linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-23  8:18 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included) Miles Lane
@ 2002-04-23  8:00 ` Martin Dalecki
  2002-04-23  9:18   ` Jens Axboe
                     ` (2 more replies)
  0 siblings, 3 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-04-23  8:00 UTC (permalink / raw)
  To: Miles Lane; +Cc: LKML

Miles Lane wrote:
> I should probably add the /proc/ksyms snapshotting stuff to 
> get the module information for you as well.  I hope this 
> current batch of info helps, for starters.
> 
> ksymoops 2.4.4 on i686 2.4.7-10.  Options used
>      -v /usr/src/linux/vmlinux (specified)
>      -K (specified)
>      -L (specified)
>      -o /lib/modules/2.5.9/ (specified)
>      -m /boot/System.map-2.5.9 (specified)


Looks like the oops came from module code.
Which modules did you use: ide-flappy and ide-scsi are still
in need of the same medication ide-cd got.


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

* 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
@ 2002-04-23  8:18 Miles Lane
  2002-04-23  8:00 ` Martin Dalecki
  0 siblings, 1 reply; 48+ messages in thread
From: Miles Lane @ 2002-04-23  8:18 UTC (permalink / raw)
  To: LKML

I should probably add the /proc/ksyms snapshotting stuff to 
get the module information for you as well.  I hope this 
current batch of info helps, for starters.

ksymoops 2.4.4 on i686 2.4.7-10.  Options used
     -v /usr/src/linux/vmlinux (specified)
     -K (specified)
     -L (specified)
     -o /lib/modules/2.5.9/ (specified)
     -m /boot/System.map-2.5.9 (specified)

Unable to handle kernel NULL pointer dereference at virtual address 00000004
*pde = 00000000
Oops: 0002
CPU:    0
EIP:    0010:[<c01fb579>]    Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010002
eax: 00000004   ebx: cf44be24   ecx: 00000000   edx: 00000000
esi: cf44bd90   edi: c03426bc   ebp: 00000296   esp: c02ddeac
ds: 0018   es: 0018   ss: 0018
Stack: 00000001 cf44bd90 cf44be24 c03426bc 00000001 c01ff62f c03426bc 00000001 
       00000000 d98f164d c03426bc 00000001 cf44bd50 00000000 cf44bd90 cf44be24 
       cff26500 d98f227b c02ddf0c c03426bc 00000000 c02ddf10 00000000 c01fce26 
Call Trace: [<c01ff62f>] [<d98f164d>] [<d98f227b>] [<c01fce26>] [<c01fd433>] 
   [<d98f2250>] [<c0108709>] [<c01088eb>] [<c0105310>] [<c010730e>] [<c0105310>] 
   [<c0105310>] [<c0105337>] [<c01053b6>] [<c0105000>] 
Code: c7 04 90 00 00 00 00 8b 53 0c 8b 87 20 02 00 00 0f b3 10 8b 

>>EIP; c01fb579 <__ide_end_request+109/190>   <=====
Trace; c01ff62f <ide_end_request+f/20>
Trace; d98f164d <END_OF_CODE+195a2039/????>
Trace; d98f227b <END_OF_CODE+195a2c67/????>
Trace; c01fce26 <ide_do_request+36/a0>
Trace; c01fd433 <ide_intr+103/1c0>
Trace; d98f2250 <END_OF_CODE+195a2c3c/????>
Trace; c0108709 <handle_IRQ_event+39/70>
Trace; c01088eb <do_IRQ+8b/110>
Trace; c0105310 <default_idle+0/30>
Trace; c010730e <common_interrupt+22/28>
Trace; c0105310 <default_idle+0/30>
Trace; c0105310 <default_idle+0/30>
Trace; c0105337 <default_idle+27/30>
Trace; c01053b6 <cpu_idle+36/40>
Trace; c0105000 <_stext+0/0>
Code;  c01fb579 <__ide_end_request+109/190>
00000000 <_EIP>:
Code;  c01fb579 <__ide_end_request+109/190>   <=====
   0:   c7 04 90 00 00 00 00      movl   $0x0,(%eax,%edx,4)   <=====
Code;  c01fb580 <__ide_end_request+110/190>
   7:   8b 53 0c                  mov    0xc(%ebx),%edx
Code;  c01fb583 <__ide_end_request+113/190>
   a:   8b 87 20 02 00 00         mov    0x220(%edi),%eax
Code;  c01fb589 <__ide_end_request+119/190>
  10:   0f b3 10                  btr    %edx,(%eax)
Code;  c01fb58c <__ide_end_request+11c/190>
  13:   8b 00                     mov    (%eax),%eax

 <0>Kernel panic: Aiee, killing interrupt handler!

1 warning and 1 error issued.  Results may not be reliable.


Linux version 2.5.9 (root@turbulence.megapathdsl.net) (gcc version 3.0.4 (Red Hat Linux 7.2 3.0.4-1)) #4 2BIOS-provided physical RAM map:                                   
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)          
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)        
 BIOS-e820: 00000000000e0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 000000000ffe0000 (usable)
 BIOS-e820: 000000000ffe0000 - 000000000fff8000 (ACPI data)
 BIOS-e820: 000000000fff8000 - 0000000010000000 (ACPI NVS)
 BIOS-e820: 00000000fff80000 - 0000000100000000 (reserved)
255MB LOWMEM available.
On node 0 totalpages: 65504
zone(0): 4096 pages.
zone(1): 61408 pages.
zone(2): 0 pages.
ACPI: RSDP (v000 AMI                        ) @ 0x000fae70
ACPI: RSDT (v001 GATEWA 8DT-084  00529.06553) @ 0x0fff0000
ACPI: FADT (v001 GATEWA 8DT-084  00529.06553) @ 0x0fff1000
Kernel command line: ro root=/dev/hda6 hdd=ide-scsi console=ttyS0,38400 video=riva:1600x1200-16@76
ide_setup: hdd=ide-scsi
Local APIC disabled by BIOS -- reenabling.
Found and enabled local APIC!
Initializing CPU#0
Detected 848.364 MHz processor.
Console: colour VGA+ 80x25
Calibrating delay loop... 1690.82 BogoMIPS
Memory: 256916k/262016k available (1509k kernel code, 4712k reserved, 391k data, 232k init, 0k highmem)
Dentry-cache hash table entries: 32768 (order: 6, 262144 bytes)
Inode-cache hash table entries: 16384 (order: 5, 131072 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 16384 (order: 4, 65536 bytes)
CPU: L1 I Cache: 64K (64 bytes/line), D cache 64K (64 bytes/line)
CPU: L2 Cache: 512K (64 bytes/line)
CPU: AMD Athlon(tm) Processor stepping 01
Enabling fast FPU save and restore... done.
Checking 'hlt' instruction... OK.
POSIX conformance testing by UNIFIX
enabled ExtINT on CPU#0
ESR value before enabling vector: 00000000
ESR value after enabling vector: 00000000
Using local APIC timer interrupts.
calibrating APIC timer ...
..... CPU clock speed is 848.3696 MHz.
..... host bus clock speed is 199.6163 MHz.
cpu: 0, clocks: 1996163, slice: 998081
CPU0<T0:1996160,T1:998064,D:15,S:998081,C:1996163>
mtrr: v1.40 (20010327) Richard Gooch (rgooch@atnf.csiro.au)
mtrr: detected mtrr type: Intel
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
ACPI: Bus Driver revision 20020404
ACPI: Core Subsystem revision 20020403
PCI: PCI BIOS revision 2.10 entry at 0xfdad1, last bus=1
PCI: Using configuration type 1
 tbxface-0101 [03] Acpi_load_tables      : ACPI Tables successfully loaded
Parsing Methods:...................................................................................
83 Control Methods found and parsed (271 nodes total)
ACPI Namespace successfully loaded at root c03276f8
evxfevnt-0080 [04] Acpi_enable           : Transition to ACPI mode successful
Executing all Device _STA and_INI methods:............... exfldio-0100 [21] Ex_setup_region       : Field) exfldio-0110 [21] Ex_setup_region       : Field [PS2E] Base+Offset+Width 0+0+4 is beyond end of region [)  uteval-0421 [07] Ut_execute_STA        : _STA on PS2M failed AE_AML_REGION_LIMIT
...........
26 Devices found containing: 25 _STA, 2 _INI methods
Completing Region/Field/Buffer/Package initialization:..........................................
 Initialized 12/15 Regions 1/1 Fields 21/21 Buffers 8/9 Packages (271 nodes)
ACPI: Interpreter enabled
ACPI: Using PIC for interrupt routing
ACPI: System [ACPI] (supports S0 S1 S5)
ACPI: PCI Root Bridge [PCI0] (00:00:00.00)
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
      00:00:11[A] -> \_SB_.LNKA[0]
      00:00:11[B] -> \_SB_.LNKB[0]
      00:00:11[C] -> \_SB_.LNKC[0]
      00:00:11[D] -> \_SB_.LNKD[0]
      00:00:12[A] -> \_SB_.LNKB[0]
      00:00:12[B] -> \_SB_.LNKC[0]
      00:00:12[C] -> \_SB_.LNKD[0]
      00:00:12[D] -> \_SB_.LNKA[0]
      00:00:13[A] -> \_SB_.LNKC[0]
      00:00:13[B] -> \_SB_.LNKD[0]
      00:00:13[C] -> \_SB_.LNKA[0]
      00:00:13[D] -> \_SB_.LNKB[0]
      00:00:14[A] -> \_SB_.LNKB[0]
      00:00:14[B] -> \_SB_.LNKC[0]
      00:00:14[C] -> \_SB_.LNKD[0]
      00:00:14[D] -> \_SB_.LNKA[0]
      00:00:0F[A] -> \_SB_.LNKA[0]
      00:00:0F[B] -> \_SB_.LNKB[0]
      00:00:0F[C] -> \_SB_.LNKC[0]
      00:00:0F[D] -> \_SB_.LNKD[0]
      00:00:07[D] -> \_SB_.LNKD[0]
ACPI: PCI Interrupt Routing Table [\_SB_.PCI0.AGPB._PRT]
      00:01:05[A] -> \_SB_.LNKA[0]
 exfldio-0100 [21] Ex_setup_region       : Field [PS2E] access width (4 bytes) too large for region [PSRG) exfldio-0110 [21] Ex_setup_region       : Field [PS2E] Base+Offset+Width 0+0+4 is beyond end of region [)acpi_pci_link-0164 [09] acpi_pci_link_get_poss: Resource is not an IRQ entry
acpi_pci_link-0164 [09] acpi_pci_link_get_poss: Resource is not an IRQ entry
acpi_pci_link-0164 [09] acpi_pci_link_get_poss: Resource is not an IRQ entry
acpi_pci_link-0164 [09] acpi_pci_link_get_poss: Resource is not an IRQ entry
PCI: Probing PCI hardware
PCI: Using ACPI for IRQ routing
acpi_pci_link-0330 [02] acpi_pci_link_get_irq : Invalid link context
pci_root-0160 [01] acpi_prt_get_irq      : Unable to reslove IRQ
PCI: No IRQ known for interrupt pin A of device 00:14.0
acpi_pci_link-0330 [02] acpi_pci_link_get_irq : Invalid link context
pci_root-0160 [01] acpi_prt_get_irq      : Unable to reslove IRQ
PCI: No IRQ known for interrupt pin B of device 00:14.1
Starting kswapd
BIO: pool of 256 setup, 14Kb (56 bytes/bio)
biovec: init pool 0, 1 entries, 12 bytes
biovec: init pool 1, 4 entries, 48 bytes
biovec: init pool 2, 16 entries, 192 bytes
biovec: init pool 3, 64 entries, 768 bytes
biovec: init pool 4, 128 entries, 1536 bytes
biovec: init pool 5, 256 entries, 3072 bytes
Journalled Block Device driver loaded
rivafb: RIVA MTRR set to ON
Console: switching to colour frame buffer device 200x75
rivafb: PCI nVidia NV16 framebuffer ver 0.9.2a (GeForce-DDR, 32MB @ 0xE8000000)
pty: 256 Unix98 ptys configured
Serial driver version 5.05c (2001-07-08) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled
ttyS00 at 0x03f8 (irq = 4) is a 16550A
ttyS02 at 0x03e8 (irq = 0) is a 16550A
block: 256 slots per queue, batch=32
loop: loaded (max 8 devices)
acpi_pci_link-0330 [02] acpi_pci_link_get_irq : Invalid link context
pci_root-0160 [01] acpi_prt_get_irq      : Unable to reslove IRQ
PCI: No IRQ known for interrupt pin A of device 00:13.0
3c59x: Donald Becker and others. www.scyld.com/network/vortex.html
00:13.0: 3Com PCI 3c905C Tornado at 0xfc00. Vers LK1.1.17
phy=0, phyx=24, mii_status=0x782d
Linux agpgart interface v0.99 (c) Jeff Hartmann
agpgart: Maximum main memory to use for agp memory: 203M
agpgart: Detected AMD Irongate chipset
agpgart: AGP aperture is 64M @ 0xf8000000
ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393@maroon.tc.umn.edu>
ipddp0: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393@maroon.tc.umn.edu>
Uniform Multi-Platform E-IDE driver ver.:7.0.0
ide: system bus speed 33MHz
Advanced Micro Devices [AMD] AMD-756 [Viper] IDE: IDE controller on PCI slot 00:07.1
Advanced Micro Devices [AMD] AMD-756 [Viper] IDE: chipset revision 3
Advanced Micro Devices [AMD] AMD-756 [Viper] IDE: not 100% native mode: will probe irqs later
AMD_IDE: Advanced Micro Devices [AMD] AMD-756 [Viper] IDE (rev 03) UDMA66 controller on pci00:07.1
    ide0: BM-DMA at 0xcb00-0xcb07, BIOS settings: hda:DMA, hdb:pio
    ide1: BM-DMA at 0xcb08-0xcb0f, BIOS settings: hdc:DMA, hdd:DMA
hda: QUANTUM FIREBALLP LM30, ATA DISK drive
hdc: Pioneer DVD-ROM ATAPIModel DVD-114 0117, ATAPI CD/DVD-ROM drive
hdd: R/RW 4x4x24, ATAPI CD/DVD-ROM drive
ide2: ports already in use, skipping probe
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
ide: unexpected interrupt 0 14
hda: 58633344 sectors (30020 MB) w/1900KiB Cache, CHS=58168/16/63, UDMA(66)
Partition check:
 hda: [PTBL] [3649/255/63] hda1 hda2 < hda5 hda6 hda7 hda8 hda9 hda10 hda11 hda12 hda13 >
mice: PS/2 mouse device common for all mice
md: linear personality registered as nr 1
md: raid0 personality registered as nr 2
md: md driver 0.90.0 MAX_MD_DEVS=256, MD_SB_DISKS=27
md: Autodetecting RAID arrays.
 [events: 00000098]
 [events: 00000098]
md: autorun ...
md: considering hda12 ...
md:  adding hda12 ...
md:  adding hda11 ...
md: created md0
md: bind<hda11,1>
md0: WARNING: hda12 appears to be on the same physical disk as hda11. True
     protection against single-disk failure might be compromised.
md: bind<hda12,2>
md: running: <hda12><hda11>
md: hda12's event counter: 00000098
md: hda11's event counter: 00000098
md0: max total readahead window set to 512k
md0: 2 data-disks, max readahead per data-disk: 256k
raid0: looking at hda11
raid0:   comparing hda11(1028032) with hda11(1028032)
raid0:   END
raid0:   ==> UNIQUE
raid0: 1 zones
raid0: looking at hda12
raid0:   comparing hda12(1028032) with hda11(1028032)
raid0:   EQUAL
raid0: FINAL 1 zones
raid0: zone 0
raid0: checking hda11 ... contained as device 0
  (1028032) is smallest!.
raid0: checking hda12 ... contained as device 1
raid0: zone->nb_dev: 2, size: 2056064
raid0: current zone offset: 1028032
raid0: done.
raid0 : md_size is 2056064 blocks.
raid0 : conf->smallest->size is 2056064 blocks.
raid0 : nb_zone is 1.
raid0 : Allocating 8 bytes for hash.
md: updating md0 RAID superblock on device
md: hda12 [events: 00000099]<6>(write) hda12's sb offset: 1028032
md: hda11 [events: 00000099]<6>(write) hda11's sb offset: 1028032
md: ... autorun DONE.
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP, IGMP
IP: routing cache hash table of 2048 buckets, 16Kbytes
TCP: Hash tables configured (established 16384 bind 32768)
IPv4 over IPv4 tunneling driver
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
NET4: AppleTalk 0.18a for Linux NET4.0
kjournald starting.  Commit interval 5 seconds
EXT3-fs: mounted filesystem with ordered data mode.
VFS: Mounted root (ext3 filesystem) readonly.
Freeing unused kernel memory: 232k freed
INIT: version 2.78 booting
                        Welcome to Red Hat Linux
                Press 'I' to enter interactive startup.
Mounting proc filesystem:  [  OK  ]
Configuring kernel parameters:  [  OK  ]
Setting clock  (localtime): Mon Apr 22 22:15:59 PDT 2002 [  OK  ]
Activating swap partitions:  [  OK  ]
Setting hostname turbulence.megapathdsl.net:  [  OK  ]
Mounting USB filesystem:  [  OK  ]
Initializing USB controller (usb-ohci):  [  OK  ]
Initializing USB HID interface:  [  OK  ]
Initializing USB mouse:  modprobe: Can't locate module mousedev
[FAILED]
Checking root filesystem
/: clean, 313674/1921984 files, 2266435/3841535 blocks
[/sbin/fsck.ext3 (1) -- /] fsck.ext3 -a /dev/hda6 
[  OK  ]
Remounting root filesystem in read-write mode:  [  OK  ]
Finding module dependencies:  [  OK  ]
Starting up RAID devices: md0 
Checking filesystems
/boot: clean, 77/84336 files, 53660/337333 blocks
/home: clean, 13228/257024 files, 173634/514016 blocks
Logical sector size is zero.dosfsck 2.7, 14 Feb 2001, FAT32, LFN

Logical sector size is zero.dosfsck 2.7, 14 Feb 2001, FAT32, LFN

Logical sector size is zero.dosfsck 2.7, 14 Feb 2001, FAT32, LFN
dosfsck 2.7, 14 Feb 2001, FAT32, LFN
Checking all file systems.
[/sbin/fsck.ext3 (1) -- /boot] fsck.ext3 -a /dev/hda5 
[/sbin/fsck.ext3 (1) -- /home] fsck.ext3 -a /dev/md0 
[/sbin/fsck.vfat (1) -- /mnt/test1] fsck.vfat -a /dev/hda7 
[/sbin/fsck.vfat (1) -- /mnt/test2] fsck.vfat -a /dev/hda8 
[/sbin/fsck.vfat (1) -- /mnt/test3] fsck.vfat -a /dev/hda9 
[/sbin/fsck.vfat (1) -- /mnt/test4] fsck.vfat -a /dev/hda10 

Logical sector size is zero.
[PASSED]
Mounting local filesystems:  mount: wrong fs type, bad option, bad superblock on /dev/hda7,
       or too many mounted file systems
mount: wrong fs type, bad option, bad superblock on /dev/hda8,
       or too many mounted file systems
mount: wrong fs type, bad option, bad superblock on /dev/hda9,
       or too many mounted file systems
mount: mount point /mnt/test4 does not exist
[FAILED]
Enabling local filesystem quotas:  [  OK  ]
Enabling swap space:  [  OK  ]
Unable to handle kernel NULL pointer dereference at virtual address 00000004
*pde = 00000000
Oops: 0002
CPU:    0
EIP:    0010:[<c01fb579>]    Not tainted
EFLAGS: 00010002
eax: 00000004   ebx: cf44be24   ecx: 00000000   edx: 00000000
esi: cf44bd90   edi: c03426bc   ebp: 00000296   esp: c02ddeac
ds: 0018   es: 0018   ss: 0018
Process swapper (pid: 0, threadinfo=c02dc000 task=c02bf3e0)
Stack: 00000001 cf44bd90 cf44be24 c03426bc 00000001 c01ff62f c03426bc 00000001 
       00000000 d98f164d c03426bc 00000001 cf44bd50 00000000 cf44bd90 cf44be24 
       cff26500 d98f227b c02ddf0c c03426bc 00000000 c02ddf10 00000000 c01fce26 
Call Trace: [<c01ff62f>] [<d98f164d>] [<d98f227b>] [<c01fce26>] [<c01fd433>] 
   [<d98f2250>] [<c0108709>] [<c01088eb>] [<c0105310>] [<c010730e>] [<c0105310>] 
   [<c0105310>] [<c0105337>] [<c01053b6>] [<c0105000>] 

Code: c7 04 90 00 00 00 00 8b 53 0c 8b 87 20 02 00 00 0f b3 10 8b 
 <0>Kernel panic: Aiee, killing interrupt handler!
In interrupt handler - not syncing


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-23  9:18   ` Jens Axboe
@ 2002-04-23  8:43     ` Martin Dalecki
  2002-04-23  9:54       ` Jens Axboe
  0 siblings, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-04-23  8:43 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Miles Lane, LKML

> Martin,
> 
> There are several 'issues' with the ide-cd changes, in fact I think they
> are horrible. I'll take part of the blame for that, I'll explain.

Well... I refer you to my change long, where I indeed admitted directly
that it's an ugly band aid ;-).

> The ata_ar_get() doesn't belong inside the do_request() strategies, the
> reason I did that for ide-disk was to get going on the tcq stuff and not
> spend too much time rewriting the ide request handling at that point. It

Right. it belongs one level up. The request handling should
possible learn whatever it it's handling ATA or ATAPI devices.
In esp. the ide_start_dma() changes where no pretty...

> was _never_ meant to propagate into the other ide drivers, and in fact
> the code in ide-disk has several tcq specific parts that really cannot
> work in ide-cd. Such as (ide-cd.c:ide_cdrom_do_request()):
> 
> 	spin_lock...
> 
> 	ar = ata_ar_get()
> 	if (!ar) {
> 		spin_unlock;
> 		return ide_started;
> 	}
> 	...
> 
> ide-disk guarentees that if ata_ar_get() fails, it's because we have
> some pending commands on the drive. The ide_started is bogus too, in
> this context it really should be ide_didnt_start_jack, but it works for
> ide-disk because of the above assumptions.

Fortunately it can't happen becouse the other devices don't
support TCQ.

> Don't tell me you can read ide_cdrom_do_request() right now without a
> barf bag :-)

Ohhh. there are a lot of other things I'm unhappy about there as well.

> I'd suggest moving the ata_ar_get() at the ide_queue_commands() level,
> and just pass { drive, ar } to the do_request() strategies. That's also
> why ide-disk.c:idedisk_do_request() has this comment:

Yes this was my intention for the future. The only driver which will have
problems with this is ide-scsi.c - it's not obvious (at least right now)
to me how to change the do_request signature there.

> 	/*
> 	 * 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);
> 	...
> 
> I've been meaning to do this once tcq settled down, just didn't get
> around to it yet. But please don't start moving stuff like this into
> ide-cd too.

You notice that I didn't even care to change the write request code-path?
BTW.> It became obvious to me as well that even all the drivers out
there not supporting TCQ will have to get the TCQ parts of struct ata_device
initialized - with a trivial queue depth. drive->tcq should therefore be really
just a memmber of struct ata_device()..


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-23  8:00 ` Martin Dalecki
@ 2002-04-23  9:18   ` Jens Axboe
  2002-04-23  8:43     ` Martin Dalecki
  2002-04-23 17:39   ` Miles Lane
  2002-04-23 18:23   ` Melchior FRANZ
  2 siblings, 1 reply; 48+ messages in thread
From: Jens Axboe @ 2002-04-23  9:18 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Miles Lane, LKML

On Tue, Apr 23 2002, Martin Dalecki wrote:
> Miles Lane wrote:
> >I should probably add the /proc/ksyms snapshotting stuff to 
> >get the module information for you as well.  I hope this 
> >current batch of info helps, for starters.
> >
> >ksymoops 2.4.4 on i686 2.4.7-10.  Options used
> >     -v /usr/src/linux/vmlinux (specified)
> >     -K (specified)
> >     -L (specified)
> >     -o /lib/modules/2.5.9/ (specified)
> >     -m /boot/System.map-2.5.9 (specified)
> 
> 
> Looks like the oops came from module code.
> Which modules did you use: ide-flappy and ide-scsi are still
> in need of the same medication ide-cd got.

Martin,

There are several 'issues' with the ide-cd changes, in fact I think they
are horrible. I'll take part of the blame for that, I'll explain.

The ata_ar_get() doesn't belong inside the do_request() strategies, the
reason I did that for ide-disk was to get going on the tcq stuff and not
spend too much time rewriting the ide request handling at that point. It
was _never_ meant to propagate into the other ide drivers, and in fact
the code in ide-disk has several tcq specific parts that really cannot
work in ide-cd. Such as (ide-cd.c:ide_cdrom_do_request()):

	spin_lock...

	ar = ata_ar_get()
	if (!ar) {
		spin_unlock;
		return ide_started;
	}
	...

ide-disk guarentees that if ata_ar_get() fails, it's because we have
some pending commands on the drive. The ide_started is bogus too, in
this context it really should be ide_didnt_start_jack, but it works for
ide-disk because of the above assumptions.

Don't tell me you can read ide_cdrom_do_request() right now without a
barf bag :-)

I'd suggest moving the ata_ar_get() at the ide_queue_commands() level,
and just pass { drive, ar } to the do_request() strategies. That's also
why ide-disk.c:idedisk_do_request() has this comment:

	/*
	 * 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);
	...

I've been meaning to do this once tcq settled down, just didn't get
around to it yet. But please don't start moving stuff like this into
ide-cd too.

-- 
Jens Axboe


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-23  8:43     ` Martin Dalecki
@ 2002-04-23  9:54       ` Jens Axboe
  0 siblings, 0 replies; 48+ messages in thread
From: Jens Axboe @ 2002-04-23  9:54 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Miles Lane, LKML

On Tue, Apr 23 2002, Martin Dalecki wrote:
> >Martin,
> >
> >There are several 'issues' with the ide-cd changes, in fact I think they
> >are horrible. I'll take part of the blame for that, I'll explain.
> 
> Well... I refer you to my change long, where I indeed admitted directly
> that it's an ugly band aid ;-).

Didn't read that :)

> >The ata_ar_get() doesn't belong inside the do_request() strategies, the
> >reason I did that for ide-disk was to get going on the tcq stuff and not
> >spend too much time rewriting the ide request handling at that point. It
> 
> Right. it belongs one level up. The request handling should
> possible learn whatever it it's handling ATA or ATAPI devices.
> In esp. the ide_start_dma() changes where no pretty...

Why would you care what type of transport they use??

> >was _never_ meant to propagate into the other ide drivers, and in fact
> >the code in ide-disk has several tcq specific parts that really cannot
> >work in ide-cd. Such as (ide-cd.c:ide_cdrom_do_request()):
> >
> >	spin_lock...
> >
> >	ar = ata_ar_get()
> >	if (!ar) {
> >		spin_unlock;
> >		return ide_started;
> >	}
> >	...
> >
> >ide-disk guarentees that if ata_ar_get() fails, it's because we have
> >some pending commands on the drive. The ide_started is bogus too, in
> >this context it really should be ide_didnt_start_jack, but it works for
> >ide-disk because of the above assumptions.
> 
> Fortunately it can't happen becouse the other devices don't
> support TCQ.

Right, it should rather be a bug trigger in ide-cd... Doesn't matter, it
will be killed soon.

> >I'd suggest moving the ata_ar_get() at the ide_queue_commands() level,
> >and just pass { drive, ar } to the do_request() strategies. That's also
> >why ide-disk.c:idedisk_do_request() has this comment:
> 
> Yes this was my intention for the future. The only driver which will have
> problems with this is ide-scsi.c - it's not obvious (at least right now)
> to me how to change the do_request signature there.

How so? Even with pusing ar at the level discussed here, ide-xx.c does
really not need to care. Change the do_request() strategy to just take
the drive and ar, driver is free to just:

	/* something to this effect */
	struct request *rq = ar->ar_rq;
	sector_t block = ar->ar_block;

and the rest could remain unchanged. It's up to the driver how far it
wants to take this. The only "problem" is that rq->special will always
contain the pointer to the ar used, so none of them can touch it.

> >	/*
> >	 * 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);
> >	...
> >
> >I've been meaning to do this once tcq settled down, just didn't get
> >around to it yet. But please don't start moving stuff like this into
> >ide-cd too.
> 
> You notice that I didn't even care to change the write request code-path?
> BTW.> It became obvious to me as well that even all the drivers out
> there not supporting TCQ will have to get the TCQ parts of struct ata_device
> initialized - with a trivial queue depth. drive->tcq should therefore be 
> really just a memmber of struct ata_device()..

I disagree, there's no need to have a ->tcq if you don't support
queueing. The "trivial queue depth" is already done, it's called
drive->queue_depth and is 1 for non-tcq (or tcq with depth 1 :-).

-- 
Jens Axboe


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-23  8:00 ` Martin Dalecki
  2002-04-23  9:18   ` Jens Axboe
@ 2002-04-23 17:39   ` Miles Lane
  2002-04-23 17:54     ` Miles Lane
  2002-04-23 18:23   ` Melchior FRANZ
  2 siblings, 1 reply; 48+ messages in thread
From: Miles Lane @ 2002-04-23 17:39 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: LKML

On Tue, 2002-04-23 at 01:00, Martin Dalecki wrote:
> Miles Lane wrote:
> > I should probably add the /proc/ksyms snapshotting stuff to 
> > get the module information for you as well.  I hope this 
> > current batch of info helps, for starters.
> > 
> > ksymoops 2.4.4 on i686 2.4.7-10.  Options used
> >      -v /usr/src/linux/vmlinux (specified)
> >      -K (specified)
> >      -L (specified)
> >      -o /lib/modules/2.5.9/ (specified)
> >      -m /boot/System.map-2.5.9 (specified)
> 
> 
> Looks like the oops came from module code.
> Which modules did you use: ide-flappy and ide-scsi are still
> in need of the same medication ide-cd got.

CONFIG_BLK_DEV_IDESCSI=m
CONFIG_SCSI=m
CONFIG_BLK_DEV_SD=m
CONFIG_BLK_DEV_SR=m
CONFIG_CHR_DEV_SG=m




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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-23 17:39   ` Miles Lane
@ 2002-04-23 17:54     ` Miles Lane
  2002-04-24  8:06       ` Martin Dalecki
  0 siblings, 1 reply; 48+ messages in thread
From: Miles Lane @ 2002-04-23 17:54 UTC (permalink / raw)
  To: Miles Lane; +Cc: Martin Dalecki, LKML

On Tue, 2002-04-23 at 10:39, Miles Lane wrote:
> On Tue, 2002-04-23 at 01:00, Martin Dalecki wrote:
> > Miles Lane wrote:
> > > I should probably add the /proc/ksyms snapshotting stuff to 
> > > get the module information for you as well.  I hope this 
> > > current batch of info helps, for starters.
> > > 
> > > ksymoops 2.4.4 on i686 2.4.7-10.  Options used
> > >      -v /usr/src/linux/vmlinux (specified)
> > >      -K (specified)
> > >      -L (specified)
> > >      -o /lib/modules/2.5.9/ (specified)
> > >      -m /boot/System.map-2.5.9 (specified)
> > 
> > 
> > Looks like the oops came from module code.
> > Which modules did you use: ide-flappy and ide-scsi are still
> > in need of the same medication ide-cd got.
> 
> CONFIG_BLK_DEV_IDESCSI=m
> CONFIG_SCSI=m
> CONFIG_BLK_DEV_SD=m
> CONFIG_BLK_DEV_SR=m
> CONFIG_CHR_DEV_SG=m

Hmm.  You probably need this, too.  Sorry for not sending this
in the first reply.

CONFIG_IDE=y

#
# ATA and ATAPI Block devices
#
CONFIG_BLK_DEV_IDE=y
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
CONFIG_BLK_DEV_IDECD=m
CONFIG_BLK_DEV_IDESCSI=m
CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_BLK_DEV_IDEDMA=y
CONFIG_BLK_DEV_AMD74XX=y
CONFIG_IDEDMA_AUTO=y



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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-23  8:00 ` Martin Dalecki
  2002-04-23  9:18   ` Jens Axboe
  2002-04-23 17:39   ` Miles Lane
@ 2002-04-23 18:23   ` Melchior FRANZ
  2 siblings, 0 replies; 48+ messages in thread
From: Melchior FRANZ @ 2002-04-23 18:23 UTC (permalink / raw)
  To: linux-kernel

* Martin Dalecki -- Tuesday 23 April 2002 10:00:
> Looks like the oops came from module code.
> Which modules did you use: ide-flappy and ide-scsi are still
> in need of the same medication ide-cd got.

I've got the same oops, but I have ide-cd compiled into the kernel, and use
neither ide-scsi nor ide-floppy. It's obviously a ide-cd problem.
(Oops report on request.)

m.


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-23 17:54     ` Miles Lane
@ 2002-04-24  8:06       ` Martin Dalecki
  2002-04-24  9:11         ` Jens Axboe
  2002-04-24  9:29         ` 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included) Luigi Genoni
  0 siblings, 2 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-04-24  8:06 UTC (permalink / raw)
  To: Miles Lane; +Cc: LKML

Użytkownik Miles Lane napisał:
> On Tue, 2002-04-23 at 10:39, Miles Lane wrote:
> 
>>On Tue, 2002-04-23 at 01:00, Martin Dalecki wrote:
>>
>>>Miles Lane wrote:
>>>
>>>>I should probably add the /proc/ksyms snapshotting stuff to 
>>>>get the module information for you as well.  I hope this 
>>>>current batch of info helps, for starters.
>>>>
>>>>ksymoops 2.4.4 on i686 2.4.7-10.  Options used
>>>>     -v /usr/src/linux/vmlinux (specified)
>>>>     -K (specified)
>>>>     -L (specified)
>>>>     -o /lib/modules/2.5.9/ (specified)
>>>>     -m /boot/System.map-2.5.9 (specified)
>>>
>>>
>>>Looks like the oops came from module code.
>>>Which modules did you use: ide-flappy and ide-scsi are still
>>>in need of the same medication ide-cd got.
>>
>>CONFIG_BLK_DEV_IDESCSI=m
>>CONFIG_SCSI=m
>>CONFIG_BLK_DEV_SD=m
>>CONFIG_BLK_DEV_SR=m
>>CONFIG_CHR_DEV_SG=m
> 
> 
> Hmm.  You probably need this, too.  Sorry for not sending this
> in the first reply.


OK I assume that the oops happens inside the ide-scsi module.
This will be fixed in one of the forthcomming patch sets.


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-24  9:11         ` Jens Axboe
@ 2002-04-24  8:20           ` Martin Dalecki
  2002-04-25 11:07           ` Martin Dalecki
  1 sibling, 0 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-04-24  8:20 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Miles Lane, LKML

>>OK I assume that the oops happens inside the ide-scsi module.
>>This will be fixed in one of the forthcomming patch sets.
> 
> 
> Are you sure this isn't just due to ->special being set, and
> ide_end_request() assuming it's an ar? From ide-cd, that is.

Yes right. Thank you for reminding me. I will have to
redo the stuff from the "draft" patch I did send you once...


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-24  8:06       ` Martin Dalecki
@ 2002-04-24  9:11         ` Jens Axboe
  2002-04-24  8:20           ` Martin Dalecki
  2002-04-25 11:07           ` Martin Dalecki
  2002-04-24  9:29         ` 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included) Luigi Genoni
  1 sibling, 2 replies; 48+ messages in thread
From: Jens Axboe @ 2002-04-24  9:11 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Miles Lane, LKML

On Wed, Apr 24 2002, Martin Dalecki wrote:
> U?ytkownik Miles Lane napisa?:
> >On Tue, 2002-04-23 at 10:39, Miles Lane wrote:
> >
> >>On Tue, 2002-04-23 at 01:00, Martin Dalecki wrote:
> >>
> >>>Miles Lane wrote:
> >>>
> >>>>I should probably add the /proc/ksyms snapshotting stuff to 
> >>>>get the module information for you as well.  I hope this 
> >>>>current batch of info helps, for starters.
> >>>>
> >>>>ksymoops 2.4.4 on i686 2.4.7-10.  Options used
> >>>>    -v /usr/src/linux/vmlinux (specified)
> >>>>    -K (specified)
> >>>>    -L (specified)
> >>>>    -o /lib/modules/2.5.9/ (specified)
> >>>>    -m /boot/System.map-2.5.9 (specified)
> >>>
> >>>
> >>>Looks like the oops came from module code.
> >>>Which modules did you use: ide-flappy and ide-scsi are still
> >>>in need of the same medication ide-cd got.
> >>
> >>CONFIG_BLK_DEV_IDESCSI=m
> >>CONFIG_SCSI=m
> >>CONFIG_BLK_DEV_SD=m
> >>CONFIG_BLK_DEV_SR=m
> >>CONFIG_CHR_DEV_SG=m
> >
> >
> >Hmm.  You probably need this, too.  Sorry for not sending this
> >in the first reply.
> 
> 
> OK I assume that the oops happens inside the ide-scsi module.
> This will be fixed in one of the forthcomming patch sets.

Are you sure this isn't just due to ->special being set, and
ide_end_request() assuming it's an ar? From ide-cd, that is.

-- 
Jens Axboe


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-24  8:06       ` Martin Dalecki
  2002-04-24  9:11         ` Jens Axboe
@ 2002-04-24  9:29         ` Luigi Genoni
  1 sibling, 0 replies; 48+ messages in thread
From: Luigi Genoni @ 2002-04-24  9:29 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Miles Lane, LKML

I had a similar oops loading ide-cd module, without ide-scsi or similar.
EIP is the same, but since loading the module freezes the system, I do not
have a complite oops.
The system il a PentiumIII 512 MB ram,with i810 chipset.
Unfortunatelly all the other test systems I have right now are scsi based
even for the cd reader, so I cannot test on other chipset.



On Wed, 24 Apr 2002, Martin Dalecki wrote:

> U¿ytkownik Miles Lane napisa³:
> > On Tue, 2002-04-23 at 10:39, Miles Lane wrote:
> >
> >>On Tue, 2002-04-23 at 01:00, Martin Dalecki wrote:
> >>
> >>>Miles Lane wrote:
> >>>
> >>>>I should probably add the /proc/ksyms snapshotting stuff to
> >>>>get the module information for you as well.  I hope this
> >>>>current batch of info helps, for starters.
> >>>>
> >>>>ksymoops 2.4.4 on i686 2.4.7-10.  Options used
> >>>>     -v /usr/src/linux/vmlinux (specified)
> >>>>     -K (specified)
> >>>>     -L (specified)
> >>>>     -o /lib/modules/2.5.9/ (specified)
> >>>>     -m /boot/System.map-2.5.9 (specified)
> >>>
> >>>
> >>>Looks like the oops came from module code.
> >>>Which modules did you use: ide-flappy and ide-scsi are still
> >>>in need of the same medication ide-cd got.
> >>
> >>CONFIG_BLK_DEV_IDESCSI=m
> >>CONFIG_SCSI=m
> >>CONFIG_BLK_DEV_SD=m
> >>CONFIG_BLK_DEV_SR=m
> >>CONFIG_CHR_DEV_SG=m
> >
> >
> > Hmm.  You probably need this, too.  Sorry for not sending this
> > in the first reply.
>
>
> OK I assume that the oops happens inside the ide-scsi module.
> This will be fixed in one of the forthcomming patch sets.
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-24  9:11         ` Jens Axboe
  2002-04-24  8:20           ` Martin Dalecki
@ 2002-04-25 11:07           ` Martin Dalecki
  2002-04-25 17:25             ` Jens Axboe
  1 sibling, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-04-25 11:07 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Miles Lane, LKML

Uz.ytkownik Jens Axboe napisa?:
> On Wed, Apr 24 2002, Martin Dalecki wrote:

>>OK I assume that the oops happens inside the ide-scsi module.
>>This will be fixed in one of the forthcomming patch sets.
> 
> 
> Are you sure this isn't just due to ->special being set, and
> ide_end_request() assuming it's an ar? From ide-cd, that is.


Yes I know it's all the same. However unfortunately
it's *not easy* to back out the ->special use from
the drivers that do it. We have the following sutuation:

1. Generic BIO code checking for ->special and deciding whatever
it should trying to merge request or not.

2. Gneric ATA code setting ->special for ata_request passing.

3. CD-ROM ATAPI code using ->special for passing packet commands
and failed commands.

4. ide-scsi using it for the same purspose as CD-ROM

5. ide-floppy not using it at all buf abusing the ->buffer member
    for precisely the same purpose.

And unfortunately there is *no* easy solution for any of the
above circumstances without breaking far too many things.

The conclusion simply is: unless the above issues are fixed
the TCQ stuff has simply to be backed out again anbd live
separately from the main code chain. :-(.



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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-25 11:07           ` Martin Dalecki
@ 2002-04-25 17:25             ` Jens Axboe
  2002-04-25 17:34               ` Jens Axboe
  0 siblings, 1 reply; 48+ messages in thread
From: Jens Axboe @ 2002-04-25 17:25 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Miles Lane, LKML

On Thu, Apr 25 2002, Martin Dalecki wrote:
> Uz.ytkownik Jens Axboe napisa?:
> >On Wed, Apr 24 2002, Martin Dalecki wrote:
> 
> >>OK I assume that the oops happens inside the ide-scsi module.
> >>This will be fixed in one of the forthcomming patch sets.
> >
> >
> >Are you sure this isn't just due to ->special being set, and
> >ide_end_request() assuming it's an ar? From ide-cd, that is.
> 
> 
> Yes I know it's all the same. However unfortunately
> it's *not easy* to back out the ->special use from
> the drivers that do it. We have the following sutuation:
> 
> 1. Generic BIO code checking for ->special and deciding whatever
> it should trying to merge request or not.
> 
> 2. Gneric ATA code setting ->special for ata_request passing.
> 
> 3. CD-ROM ATAPI code using ->special for passing packet commands
> and failed commands.
> 
> 4. ide-scsi using it for the same purspose as CD-ROM
> 
> 5. ide-floppy not using it at all buf abusing the ->buffer member
>    for precisely the same purpose.
> 
> And unfortunately there is *no* easy solution for any of the
> above circumstances without breaking far too many things.

You don't _have_ to back out the ->special usage. As I mentioned, it was
always just a quick hack for ide-disk so I didn't have to change every
single driver out there.

There are two options, as I see it:

- Keep ata_request as an ide-disk speciality. This is pretty trivial
  even though other drivers use ->special, because the ata_ar_put()
  path simply needs to do

	struct ata_request *ar = rq->special;

	if (ar && drive->media == ide_disk)
		ata_ar_put(ar);

  and that is it.

- Make the ata_request the general means of passing down request in the
  IDE layer -- start by making hwgroup->rq into hwgroup->ar and _never_
  store ar in ->special (you don't have to, you will always just go from
  ar -> rq, which is of course ar->ar_rq). This is what I wanted to do.

> The conclusion simply is: unless the above issues are fixed
> the TCQ stuff has simply to be backed out again anbd live
> separately from the main code chain. :-(.

If you didn't persist on pushing half-done stuff to Linus all the time,
I would have had the time to implement this properly... Now you keep
doing hackish work-arounds to make things limp along. So please calm
down for a moment, sick back, and think about it. It's a heck of a lot
better than going full throttle with an axe.

-- 
Jens Axboe


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-25 17:25             ` Jens Axboe
@ 2002-04-25 17:34               ` Jens Axboe
  2002-04-25 21:02                 ` Linus Torvalds
  0 siblings, 1 reply; 48+ messages in thread
From: Jens Axboe @ 2002-04-25 17:34 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Miles Lane, LKML

On Thu, Apr 25 2002, Jens Axboe wrote:
> - Make the ata_request the general means of passing down request in the
>   IDE layer -- start by making hwgroup->rq into hwgroup->ar and _never_
>   store ar in ->special (you don't have to, you will always just go from
>   ar -> rq, which is of course ar->ar_rq). This is what I wanted to do.

I'll do this on monday, I'm away friday and through the weekend. Lets
get this fixed _properly_.

-- 
Jens Axboe


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

* Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)
  2002-04-25 17:34               ` Jens Axboe
@ 2002-04-25 21:02                 ` Linus Torvalds
  2002-04-26  7:33                   ` [PATCH] 2.5.10 UTS_VERSION Martin Dalecki
                                     ` (4 more replies)
  0 siblings, 5 replies; 48+ messages in thread
From: Linus Torvalds @ 2002-04-25 21:02 UTC (permalink / raw)
  To: linux-kernel

In article <20020425173439.GM3542@suse.de>, Jens Axboe  <axboe@suse.de> wrote:
>On Thu, Apr 25 2002, Jens Axboe wrote:
>> - Make the ata_request the general means of passing down request in the
>>   IDE layer -- start by making hwgroup->rq into hwgroup->ar and _never_
>>   store ar in ->special (you don't have to, you will always just go from
>>   ar -> rq, which is of course ar->ar_rq). This is what I wanted to do.
>
>I'll do this on monday, I'm away friday and through the weekend. Lets
>get this fixed _properly_.

The only _proper_ fix is to not abuse "special" at all. Mid-level layers
simpyl should not use it.

Please don't use "special" for mid-level things that clash like this. 
There are real reasons why Linux tries hard to avoid stupidly overloaded
"void *" things, and if IDE is to be cleaned up (which I sure hope), it
should NOT use "special" at all.

And it should _definitely_ not use it for multiple different things,
depending on what kind of disk it is.  Checking whether the target is a
disk or a CD is _absolutely_ the wrong thing to do, and will just make
the code continue the current mistake of now being able to integrate the
packet command stuff between them. 

Jens, please don't make it worse. Add a new field if you have to, with a
proper type, don't overload crap.

		Linus

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

* [PATCH] 2.5.10 UTS_VERSION
  2002-04-25 21:02                 ` Linus Torvalds
@ 2002-04-26  7:33                   ` Martin Dalecki
  2002-04-26  9:52                     ` Keith Owens
  2002-04-26  7:41                   ` [PATCH] 2.5.10 IDE 42 Martin Dalecki
                                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-04-26  7:33 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

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

Make sure UTS_VERSION is allways in "C" locale.
Without it you will get (please note the day of week):

~# export LANG=en_US
~# uname -a
Linux rosomak.prv 2.5.10 #1 pią kwi 26 09:31:52 CEST 2002 i686 unknown
~#




[-- Attachment #2: trivial-2.5.10.diff --]
[-- Type: text/plain, Size: 709 bytes --]

diff -urN linux-2.5.10/Makefile linux/Makefile
--- linux-2.5.10/Makefile	2002-04-24 12:01:52.000000000 +0200
+++ linux/Makefile	2002-04-26 02:06:38.000000000 +0200
@@ -312,8 +312,8 @@
 	@echo -n \#define UTS_VERSION \"\#`cat .version` > .ver
 	@if [ -n "$(CONFIG_SMP)" ] ; then echo -n " SMP" >> .ver; fi
 	@if [ -f .name ]; then  echo -n \-`cat .name` >> .ver; fi
-	@echo ' '`date`'"' >> .ver
-	@echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
+	@echo ' '`LANG=C date`'"' >> .ver
+	@echo \#define LINUX_COMPILE_TIME \"`LANG=C date +%T`\" >> .ver
 	@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver
 	@echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> .ver
 	@if [ -x /bin/dnsdomainname ]; then \

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

* [PATCH] 2.5.10 IDE 42
  2002-04-25 21:02                 ` Linus Torvalds
  2002-04-26  7:33                   ` [PATCH] 2.5.10 UTS_VERSION Martin Dalecki
@ 2002-04-26  7:41                   ` Martin Dalecki
  2002-04-26 16:09                     ` Pavel Machek
  2002-04-26 16:10                     ` Sebastian Droege
  2002-05-05 15:54                   ` [PATCH] 2.5.13 IDE 52 Martin Dalecki
                                     ` (2 subsequent siblings)
  4 siblings, 2 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-04-26  7:41 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

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

Thu Apr 25 21:54:03 CEST 2002 ide-clean-42

- Streamline the usage of sector_t over the strategy routines in question a
   bit. Streamline the do_request code in ide-disk.c.

- Improve the readability of start_request in ide.c.

- Remove obsolete/nowhere used stuff from hdreg.h.

- Splitup special_t into classical flag field.

- Use only a single field to determine the capacity of a drive.  Make this
   field and the code paths it follows as far as possible use the sector_t
   instead of a hard coded integer types.  This increases the chances that at
   some distant point in time we will indeed be able to use 64 bit wide sector_t
   entities. (Disks are getting huge those times now...)

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

diff -urN linux-2.5.10/arch/mips64/kernel/ioctl32.c linux/arch/mips64/kernel/ioctl32.c
--- linux-2.5.10/arch/mips64/kernel/ioctl32.c	2002-04-23 00:29:14.000000000 +0200
+++ linux/arch/mips64/kernel/ioctl32.c	2002-04-25 23:04:42.000000000 +0200
@@ -732,15 +732,12 @@
 	IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo),	/* hdreg.h ioctls  */
 	IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
 	IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
-	// HDIO_OBSOLETE_IDENTITY
 	IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
 	IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans),
 	IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans),
 	IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans),
 	IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans),
 	IOCTL32_DEFAULT(HDIO_GET_IDENTITY),
-	// HDIO_TRISTATE_HWIF				/* not implemented */
-	// HDIO_DRIVE_TASK				/* To do, need specs */
 	IOCTL32_DEFAULT(HDIO_DRIVE_CMD),
 	IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT),
 	IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR),
diff -urN linux-2.5.10/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux-2.5.10/drivers/block/ll_rw_blk.c	2002-04-23 00:27:58.000000000 +0200
+++ linux/drivers/block/ll_rw_blk.c	2002-04-25 23:27:41.000000000 +0200
@@ -334,7 +334,7 @@
 
 static char *rq_flags[] = { "REQ_RW", "REQ_RW_AHEAD", "REQ_BARRIER",
 			   "REQ_CMD", "REQ_NOMERGE", "REQ_STARTED",
-			   "REQ_DONTPREP", "REQ_DRIVE_CMD", "REQ_DRIVE_TASK",
+			   "REQ_DONTPREP", "REQ_DRIVE_CMD",
 			   "REQ_DRIVE_ACB", "REQ_PC", "REQ_BLOCK_PC",
 			   "REQ_SENSE", "REQ_SPECIAL" };
 
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-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-04-26 03:30:21.000000000 +0200
@@ -283,6 +283,7 @@
 	hwif->major = ide_major[index];
 	sprintf(hwif->name, "ide%d", index);
 	hwif->bus_state = BUSSTATE_ON;
+
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		ide_drive_t *drive = &hwif->drives[unit];
 
@@ -292,10 +293,10 @@
 		drive->ctl			= 0x08;
 		drive->ready_stat		= READY_STAT;
 		drive->bad_wstat		= BAD_W_STAT;
-		drive->special.b.recalibrate	= 1;
-		drive->special.b.set_geometry	= 1;
+		drive->special_cmd = (ATA_SPECIAL_RECALIBRATE | ATA_SPECIAL_GEOMETRY);
 		sprintf(drive->name, "hd%c", 'a' + (index * MAX_DRIVES) + unit);
 		drive->max_failures		= IDE_DEFAULT_MAX_FAILURES;
+
 		init_waitqueue_head(&drive->wqueue);
 	}
 }
@@ -455,7 +456,7 @@
  * The capacity of a drive according to its current geometry/LBA settings in
  * sectors.
  */
-unsigned long ata_capacity(ide_drive_t *drive)
+sector_t ata_capacity(struct ata_device *drive)
 {
 	if (!drive->present || !drive->driver)
 		return 0;
@@ -472,31 +473,31 @@
 
 /*
  * This is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT commands to
- * a drive.  It used to do much more, but has been scaled back.
+ * a drive.
  */
-static ide_startstop_t ata_special (ide_drive_t *drive)
+static ide_startstop_t ata_special(struct ata_device *drive)
 {
-	special_t *s = &drive->special;
+	unsigned char special_cmd = drive->special_cmd;
 
 #ifdef DEBUG
-	printk("%s: ata_special: 0x%02x\n", drive->name, s->all);
+	printk("%s: ata_special: 0x%02x\n", drive->name, special_cmd);
 #endif
-	if (s->b.set_tune) {
-		s->b.set_tune = 0;
+	if (special_cmd & ATA_SPECIAL_TUNE) {
+		drive->special_cmd &= ~ATA_SPECIAL_TUNE;
 		if (drive->channel->tuneproc != NULL)
 			drive->channel->tuneproc(drive, drive->tune_req);
 	} else if (drive->driver != NULL) {
 		if (ata_ops(drive)->special)
 			return ata_ops(drive)->special(drive);
 		else {
-			drive->special.all = 0;
+			drive->special_cmd = 0;
 			drive->mult_req = 0;
 
 			return ide_stopped;
 		}
-	} else if (s->all) {
-		printk("%s: bad special flag: 0x%02x\n", drive->name, s->all);
-		s->all = 0;
+	} else if (special_cmd) {
+		printk("%s: bad special flag: 0x%02x\n", drive->name, special_cmd);
+		drive->special_cmd = 0;
 	}
 
 	return ide_stopped;
@@ -584,27 +585,25 @@
 			drive->failures = 0;
 		} else {
 			drive->failures++;
+			char *msg = "";
 #if FANCY_STATUS_DUMPS
-			printk("master: ");
+			printk("master:");
 			switch (tmp & 0x7f) {
-				case 1: printk("passed");
+				case 1: msg = " passed";
 					break;
-				case 2: printk("formatter device error");
+				case 2: msg = " formatter device";
 					break;
-				case 3: printk("sector buffer error");
+				case 3: msg = " sector buffer";
 					break;
-				case 4: printk("ECC circuitry error");
+				case 4: msg = " ECC circuitry";
 					break;
-				case 5: printk("controlling MPU error");
+				case 5: msg = " controlling MPU error";
 					break;
-				default:printk("error (0x%02x?)", tmp);
 			}
 			if (tmp & 0x80)
-				printk("; slave: failed");
-			printk("\n");
-#else
-			printk("failed\n");
+				printk("; slave:");
 #endif
+			printk("%s error [%02x]\n", msg, tmp);
 		}
 	}
 	hwgroup->poll_timeout = 0;	/* done polling */
@@ -705,7 +704,7 @@
 /*
  * Clean up after success/failure of an explicit drive cmd
  */
-void ide_end_drive_cmd(ide_drive_t *drive, byte stat, byte err)
+void ide_end_drive_cmd(struct ata_device *drive, byte stat, byte err)
 {
 	unsigned long flags;
 	struct request *rq;
@@ -714,27 +713,16 @@
 	rq = HWGROUP(drive)->rq;
 
 	if (rq->flags & REQ_DRIVE_CMD) {
-		byte *args = (byte *) rq->buffer;
-		rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-		if (args) {
-			args[0] = stat;
-			args[1] = err;
-			args[2] = IN_BYTE(IDE_NSECTOR_REG);
-		}
-	} else if (rq->flags & REQ_DRIVE_TASK) {
-		byte *args = (byte *) rq->buffer;
-		rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
+		u8 *args = rq->buffer;
+		rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
 		if (args) {
 			args[0] = stat;
 			args[1] = err;
 			args[2] = IN_BYTE(IDE_NSECTOR_REG);
-			args[3] = IN_BYTE(IDE_SECTOR_REG);
-			args[4] = IN_BYTE(IDE_LCYL_REG);
-			args[5] = IN_BYTE(IDE_HCYL_REG);
-			args[6] = IN_BYTE(IDE_SELECT_REG);
 		}
-	} else if (rq->flags & REQ_DRIVE_TASKFILE) {
+	} else if (rq->flags & REQ_DRIVE_ACB) {
 		struct ata_taskfile *args = rq->special;
+
 		rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
 		if (args) {
 			args->taskfile.feature = err;
@@ -783,16 +771,23 @@
 	if (stat & BUSY_STAT)
 		printk("Busy ");
 	else {
-		if (stat & READY_STAT)	printk("DriveReady ");
-		if (stat & WRERR_STAT)	printk("DeviceFault ");
-		if (stat & SEEK_STAT)	printk("SeekComplete ");
-		if (stat & DRQ_STAT)	printk("DataRequest ");
-		if (stat & ECC_STAT)	printk("CorrectedError ");
-		if (stat & INDEX_STAT)	printk("Index ");
-		if (stat & ERR_STAT)	printk("Error ");
+		if (stat & READY_STAT)
+			printk("DriveReady ");
+		if (stat & WRERR_STAT)
+			printk("DeviceFault ");
+		if (stat & SEEK_STAT)
+			printk("SeekComplete ");
+		if (stat & DRQ_STAT)
+			printk("DataRequest ");
+		if (stat & ECC_STAT)
+			printk("CorrectedError ");
+		if (stat & INDEX_STAT)
+			printk("Index ");
+		if (stat & ERR_STAT)
+			printk("Error ");
 	}
 	printk("}");
-#endif	/* FANCY_STATUS_DUMPS */
+#endif
 	printk("\n");
 	if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
 		err = GET_ERR();
@@ -839,7 +834,7 @@
 					printk(", sector=%ld", HWGROUP(drive)->rq->sector);
 			}
 		}
-#endif	/* FANCY_STATUS_DUMPS */
+#endif
 		printk("\n");
 	}
 	__restore_flags (flags);	/* local CPU only */
@@ -907,7 +902,6 @@
 		OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG);	/* force an abort */
 
 	if (rq->errors >= ERROR_MAX) {
-		/* ATA-PATTERN */
 		if (ata_ops(drive) && ata_ops(drive)->end_request)
 			ata_ops(drive)->end_request(drive, 0);
 		else
@@ -918,7 +912,7 @@
 			return do_reset1(drive, 0);
 		}
 		if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
-			drive->special.b.recalibrate = 1;
+			drive->special_cmd |= ATA_SPECIAL_RECALIBRATE;
 		++rq->errors;
 	}
 	return ide_stopped;
@@ -1020,47 +1014,55 @@
  */
 static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
 {
-	ide_startstop_t startstop;
-	unsigned long block;
-	unsigned int minor = minor(rq->rq_dev), unit = minor >> PARTN_BITS;
-	struct ata_channel *hwif = drive->channel;
+	sector_t block;
+	unsigned int minor = minor(rq->rq_dev);
+	unsigned int unit = minor >> PARTN_BITS;
+	struct ata_channel *ch = drive->channel;
 
 	BUG_ON(!(rq->flags & REQ_STARTED));
 
 #ifdef DEBUG
-	printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq);
+	printk("%s: start_request: current=0x%08lx\n", ch->name, (unsigned long) rq);
 #endif
 
 	/* bail early if we've exceeded max_failures */
-	if (drive->max_failures && (drive->failures > drive->max_failures)) {
+	if (drive->max_failures && (drive->failures > drive->max_failures))
 		goto kill_rq;
-	}
 
 	if (unit >= MAX_DRIVES) {
-		printk("%s: bad device number: %s\n", hwif->name, kdevname(rq->rq_dev));
+		printk(KERN_ERR "%s: bad device number: %s\n", ch->name, kdevname(rq->rq_dev));
 		goto kill_rq;
 	}
+
 	block    = rq->sector;
 
-	/* Strange disk manager remap */
+	/* Strange disk manager remap.
+	 */
 	if ((rq->flags & REQ_CMD) &&
 	    (drive->type == ATA_DISK || drive->type == ATA_FLOPPY)) {
 		block += drive->sect0;
 	}
-	/* Yecch - this will shift the entire interval,
-	   possibly killing some innocent following sector */
+
+	/* Yecch - this will shift the entire interval, possibly killing some
+	 * innocent following sector.
+	 */
 	if (block == 0 && drive->remap_0_to_1 == 1)
 		block = 1;  /* redirect MBR access to EZ-Drive partn table */
 
 #if (DISK_RECOVERY_TIME > 0)
-	while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME);
+	while ((read_timer() - ch->last_time) < DISK_RECOVERY_TIME);
 #endif
 
-	SELECT_DRIVE(hwif, drive);
-	if (ide_wait_stat(&startstop, drive, drive->ready_stat,
-			  BUSY_STAT|DRQ_STAT, WAIT_READY)) {
-		printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
-		return startstop;
+	{
+		ide_startstop_t res;
+
+		SELECT_DRIVE(ch, drive);
+		if (ide_wait_stat(&res, drive, drive->ready_stat,
+					BUSY_STAT|DRQ_STAT, WAIT_READY)) {
+			printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
+
+			return res;
+		}
 	}
 
 	/* FIXME: We can see nicely here that all commands should be submitted
@@ -1068,110 +1070,93 @@
 	 * go as soon as possible!
 	 */
 
-	if (!drive->special.all) {
-		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 (drive->special_cmd)
+		return ata_special(drive);
 
-			if (rq->flags & REQ_DRIVE_TASKFILE) {
-				struct ata_taskfile *args = rq->special;
+	/* This issues a special drive command, usually initiated by ioctl()
+	 * from the external hdparm program.
+	 */
+	if (rq->flags & REQ_DRIVE_ACB) {
+		struct ata_taskfile *args = rq->special;
 
-				if (!(args))
-					goto args_error;
+		if (!(args))
+			goto args_error;
 
-				ata_taskfile(drive, args, NULL);
+		ata_taskfile(drive, args, NULL);
 
-				if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
+		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;
+				args->prehandler && args->handler)
+			return args->prehandler(drive, rq);
 
-				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;
+	}
 
-					return ide_started;
-				}
-				OUT_BYTE(args[2],IDE_FEATURE_REG);
-				ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
-				return ide_started;
-			}
+	if (rq->flags & REQ_DRIVE_CMD) {
+		u8 *args = rq->buffer;
 
-args_error:
-			/*
-			 * NULL is actually a valid way of waiting for all
-			 * current requests to be flushed from the queue.
-			 */
+		if (!(args))
+			goto args_error;
 #ifdef DEBUG
-			printk("%s: DRIVE_CMD (null)\n", drive->name);
-#endif
-			ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
-			return ide_stopped;
+		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);
 
-		/* The normal way of execution is to pass execute the request
-		 * handler.
-		 */
+		return ide_started;
+	}
 
-		if (ata_ops(drive)) {
-			if (ata_ops(drive)->do_request)
-				return ata_ops(drive)->do_request(drive, rq, block);
-			else {
-				ide_end_request(drive, 0);
-				return ide_stopped;
-			}
+	/* The normal way of execution is to pass and execute the request
+	 * handler down to the device type driver.
+	 */
+	if (ata_ops(drive)) {
+		if (ata_ops(drive)->do_request)
+			return ata_ops(drive)->do_request(drive, rq, block);
+		else {
+			ide_end_request(drive, 0);
+			return ide_stopped;
 		}
-		printk(KERN_WARNING "%s: device type %d not supported\n",
-		       drive->name, drive->type);
-		goto kill_rq;
 	}
-	return ata_special(drive);
+
+	/*
+	 * Error handling:
+	 */
+
+	printk(KERN_WARNING "%s: device type %d not supported\n",
+			drive->name, drive->type);
+
 kill_rq:
 	if (ata_ops(drive) && ata_ops(drive)->end_request)
 		ata_ops(drive)->end_request(drive, 0);
 	else
 		ide_end_request(drive, 0);
+
+	return ide_stopped;
+
+args_error:
+
+	/* NULL as arguemnt is used by ioctls as a 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;
 }
 
@@ -1678,7 +1663,7 @@
 /*
  * This function is intended to be used prior to invoking ide_do_drive_cmd().
  */
-void ide_init_drive_cmd (struct request *rq)
+void ide_init_drive_cmd(struct request *rq)
 {
 	memset(rq, 0, sizeof(*rq));
 	rq->flags = REQ_DRIVE_CMD;
@@ -1742,6 +1727,7 @@
 		wait_for_completion(&wait);	/* wait for it to be serviced */
 		return rq->errors ? -EIO : 0;	/* return -EIO if errors */
 	}
+
 	return 0;
 
 }
@@ -2386,18 +2372,21 @@
 	return 0;
 }
 
-static int set_pio_mode (ide_drive_t *drive, int arg)
+static int set_pio_mode(ide_drive_t *drive, int arg)
 {
 	struct request rq;
 
 	if (!drive->channel->tuneproc)
 		return -ENOSYS;
-	if (drive->special.b.set_tune)
+
+	if (drive->special_cmd & ATA_SPECIAL_TUNE)
 		return -EBUSY;
+
 	ide_init_drive_cmd(&rq);
-	drive->tune_req = (byte) arg;
-	drive->special.b.set_tune = 1;
+	drive->tune_req = (u8) arg;
+	drive->special_cmd |= ATA_SPECIAL_TUNE;
 	ide_do_drive_cmd(drive, &rq, ide_wait);
+
 	return 0;
 }
 
@@ -2433,8 +2422,7 @@
 #endif /* CONFIG_BLK_DEV_IDECS */
 }
 
-static int ide_ioctl (struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg)
+static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	int err = 0, major, minor;
 	ide_drive_t *drive;
@@ -2468,7 +2456,7 @@
 		}
 	}
 
-	ide_init_drive_cmd (&rq);
+	ide_init_drive_cmd(&rq);
 	switch (cmd) {
 		case HDIO_GETGEO:
 		{
@@ -2518,13 +2506,12 @@
 				return -EACCES;
 			return ide_revalidate_disk(inode->i_rdev);
 
-		case HDIO_OBSOLETE_IDENTITY:
 		case HDIO_GET_IDENTITY:
 			if (minor(inode->i_rdev) & PARTN_MASK)
 				return -EINVAL;
 			if (drive->id == NULL)
 				return -ENOMSG;
-			if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142))
+			if (copy_to_user((char *)arg, (char *)drive->id, sizeof(*drive->id)))
 				return -EFAULT;
 			return 0;
 
@@ -2538,11 +2525,6 @@
 				return -EACCES;
 			return ide_cmd_ioctl(drive, arg);
 
-		case HDIO_DRIVE_TASK:
-			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
-				return -EACCES;
-			return ide_task_ioctl(drive, arg);
-
 		case HDIO_SET_NICE:
 			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP))))
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-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-04-26 03:07:04.000000000 +0200
@@ -1162,11 +1162,12 @@
 	return ide_stopped;
 }
 
-static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
+static ide_startstop_t cdrom_start_seek_continuation(struct ata_device *drive)
 {
 	unsigned char cmd[CDROM_PACKET_SIZE];
 	struct request *rq = HWGROUP(drive)->rq;
-	int sector, frame, nskip;
+	sector_t sector;
+	int frame, nskip;
 
 	sector = rq->sector;
 	nskip = (sector % SECTORS_PER_FRAME);
@@ -1181,14 +1182,14 @@
 	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)
+static ide_startstop_t cdrom_start_seek(struct ata_device *drive, sector_t block)
 {
 	struct cdrom_info *info = drive->driver_data;
 
 	info->dma = 0;
 	info->cmd = 0;
 	info->start_seek = jiffies;
-	return cdrom_start_packet_command (drive, 0, cdrom_start_seek_continuation);
+	return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
 }
 
 /*
@@ -1199,7 +1200,7 @@
 static void restore_request (struct request *rq)
 {
 	if (rq->buffer != bio_data(rq->bio)) {
-		int n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
+		sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
 		rq->buffer = bio_data(rq->bio);
 		rq->nr_sectors += n;
 		rq->sector -= n;
@@ -1213,7 +1214,7 @@
 /*
  * 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, sector_t block)
 {
 	struct cdrom_info *info = drive->driver_data;
 	struct request *rq = HWGROUP(drive)->rq;
@@ -1634,8 +1635,6 @@
 	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();
@@ -1650,7 +1649,7 @@
 			CDROM_CONFIG_FLAGS(drive)->seeking = 0;
 		}
 		if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
-			action = cdrom_start_seek (drive, block);
+			action = cdrom_start_seek(drive, block);
 		else {
 			if (rq_data_dir(rq) == READ)
 				action = cdrom_start_read(drive, block);
@@ -1837,7 +1836,7 @@
 	return cdrom_queue_packet_command(drive, cmd, sense, &pc);
 }
 
-static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
+static int cdrom_read_capacity(ide_drive_t *drive, u32 *capacity,
 			       struct request_sense *sense)
 {
 	struct {
@@ -2027,7 +2026,8 @@
 	/* Now try to get the total cdrom capacity. */
 	minor = (drive->select.b.unit) << PARTN_BITS;
 	dev = mk_kdev(drive->channel->major, minor);
-	stat = cdrom_get_last_written(dev, &toc->capacity);
+	/* FIXME: This is making worng assumptions about register layout. */
+	stat = cdrom_get_last_written(dev, (unsigned long *) &toc->capacity);
 	if (stat)
 		stat = cdrom_read_capacity(drive, &toc->capacity, sense);
 	if (stat)
@@ -2686,7 +2686,7 @@
 }
 
 static
-int ide_cdrom_setup (ide_drive_t *drive)
+int ide_cdrom_setup(ide_drive_t *drive)
 {
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_device_info *cdi = &info->devinfo;
@@ -2702,7 +2702,6 @@
 
 	blk_queue_prep_rq(&drive->queue, ll_10byte_cmd_build);
 
-	drive->special.all	= 0;
 	drive->ready_stat	= 0;
 
 	CDROM_STATE_FLAGS (drive)->media_changed = 1;
@@ -2891,10 +2890,9 @@
 	set_blocksize(mk_kdev(drive->channel->major, minor), CD_FRAMESIZE);
 }
 
-static
-unsigned long ide_cdrom_capacity (ide_drive_t *drive)
+static sector_t ide_cdrom_capacity(struct ata_device *drive)
 {
-	unsigned long capacity;
+	u32 capacity;
 
 	if (cdrom_read_capacity(drive, &capacity, NULL))
 		return 0;
@@ -2934,9 +2932,7 @@
 	release:		ide_cdrom_release,
 	check_media_change:	ide_cdrom_check_media_change,
 	revalidate:		ide_cdrom_revalidate,
-	pre_reset:		NULL,
 	capacity:		ide_cdrom_capacity,
-	special:		NULL,
 	proc:			NULL
 };
 
diff -urN linux-2.5.10/drivers/ide/ide-cd.h linux/drivers/ide/ide-cd.h
--- linux-2.5.10/drivers/ide/ide-cd.h	2002-04-23 00:29:47.000000000 +0200
+++ linux/drivers/ide/ide-cd.h	2002-04-26 03:04:52.000000000 +0200
@@ -151,12 +151,11 @@
 };
 
 struct atapi_toc {
-	int    last_session_lba;
-	int    xa_flag;
-	unsigned long capacity;
+	int last_session_lba;
+	int xa_flag;
+	u32 capacity;
 	struct atapi_toc_header hdr;
-	struct atapi_toc_entry  ent[MAX_TRACKS+1];
-	  /* One extra for the leadout. */
+	struct atapi_toc_entry ent[MAX_TRACKS+1];  /* one extra for the leadout. */
 };
 
 
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-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-04-26 03:20:07.000000000 +0200
@@ -132,34 +132,31 @@
 	return WIN_NOP;
 }
 
-static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t chs_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
-	struct hd_drive_task_hdr	taskfile;
-	struct hd_drive_hob_hdr		hobfile;
-	struct ata_taskfile		args;
-	int				sectors;
+	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);
 
-	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;
+	memset(&args, 0, sizeof(args));
+
+	args.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));
+	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));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -167,40 +164,35 @@
 	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);
+	printk("buffer=%p\n", rq->buffer);
 #endif
 
-	args.taskfile = taskfile;
-	args.hobfile = hobfile;
 	ide_cmd_type_parser(&args);
 	rq->special = &args;
 
 	return ata_taskfile(drive, &args, rq);
 }
 
-static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t lba28_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
-	struct hd_drive_task_hdr	taskfile;
-	struct hd_drive_hob_hdr		hobfile;
-	struct ata_taskfile		args;
-	int				sectors;
+	struct ata_taskfile args;
+	int sectors;
 
 	sectors = rq->nr_sectors;
 	if (sectors == 256)
 		sectors = 0;
 
-	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
-	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	memset(&args, 0, sizeof(args));
 
-	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));
+	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));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -208,11 +200,9 @@
 	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);
+	printk("buffer=%p\n", rq->buffer);
 #endif
 
-	args.taskfile = taskfile;
-	args.hobfile = hobfile;
 	ide_cmd_type_parser(&args);
 	rq->special = &args;
 
@@ -225,40 +215,32 @@
  * 1073741822 == 549756 MB or 48bit addressing fake drive
  */
 
-static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block)
+static ide_startstop_t lba48_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
-	struct hd_drive_task_hdr	taskfile;
-	struct hd_drive_hob_hdr		hobfile;
-	struct ata_taskfile		args;
-	int				sectors;
-
-	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
-	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
+	struct ata_taskfile args;
+	int sectors;
 
 	sectors = rq->nr_sectors;
 	if (sectors == 65536)
 		sectors = 0;
 
-	taskfile.sector_count	= sectors;
-	hobfile.sector_count	= sectors >> 8;
+	memset(&args, 0, sizeof(args));
+
+	args.taskfile.sector_count = sectors;
+	args.hobfile.sector_count = sectors >> 8;
 
-	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));
+	args.taskfile.sector_number = block;		/* low lba */
+	args.taskfile.low_cylinder = (block >>= 8);	/* mid lba */
+	args.taskfile.high_cylinder = (block >>= 8);	/* hi  lba */
+
+	args.hobfile.sector_number = (block >>= 8);	/* low lba */
+	args.hobfile.low_cylinder = (block >>= 8);	/* mid lba */
+	args.hobfile.high_cylinder = (block >>= 8);	/* hi  lba */
+
+	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));
 
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name,
@@ -266,11 +248,9 @@
 	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);
+	printk("buffer=%p\n",rq->buffer);
 #endif
 
-	args.taskfile = taskfile;
-	args.hobfile = hobfile;
 	ide_cmd_type_parser(&args);
 	rq->special = &args;
 
@@ -282,7 +262,7 @@
  * 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)
+static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
 	/*
 	 * Wait until all request have bin finished.
@@ -290,7 +270,7 @@
 
 	while (drive->blocked) {
 		yield();
-		printk("ide: Request while drive blocked?");
+		printk(KERN_ERR "ide: Request while drive blocked?");
 	}
 
 	if (!(rq->flags & REQ_CMD)) {
@@ -300,7 +280,7 @@
 	}
 
 	if (IS_PDC4030_DRIVE) {
-		extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
+		extern ide_startstop_t promise_rw_disk(struct ata_device *, struct request *, unsigned long);
 
 		return promise_rw_disk(drive, rq, block);
 	}
@@ -386,256 +366,19 @@
 	return drive->removable;
 }
 
-/*
- * Queries for true maximum capacity of the drive.
- * Returns maximum LBA address (> 0) of the drive, 0 if failed.
- */
-static unsigned long idedisk_read_native_max_address(ide_drive_t *drive)
+static sector_t idedisk_capacity(struct ata_device *drive)
 {
-	struct ata_taskfile args;
-	unsigned long addr = 0;
-
-	if (!(drive->id->command_set_1 & 0x0400) &&
-	    !(drive->id->cfs_enable_2 & 0x0100))
-		return addr;
-
-	/* Create IDE/ATA command request structure */
-	memset(&args, 0, sizeof(args));
-	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.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;
-}
-
-static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive)
-{
-	struct ata_taskfile args;
-	unsigned long long addr = 0;
-
-	/* Create IDE/ATA command request structure */
-	memset(&args, 0, sizeof(args));
-
-	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.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;
+	return drive->capacity - drive->sect0;
 }
 
-#ifdef CONFIG_IDEDISK_STROKE
-/*
- * Sets maximum virtual LBA address of the drive.
- * Returns new maximum virtual LBA address (> 0) or 0 on failure.
- */
-static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req)
+static ide_startstop_t idedisk_special(struct ata_device *drive)
 {
-	struct ata_taskfile args;
-	unsigned long addr_set = 0;
-
-	addr_req--;
-	/* Create IDE/ATA command request structure */
-	memset(&args, 0, sizeof(args));
-
-	args.taskfile.sector_number = (addr_req >> 0);
-	args.taskfile.low_cylinder = (addr_req >> 8);
-	args.taskfile.high_cylinder = (addr_req >> 16);
+	unsigned char special_cmd = drive->special_cmd;
 
-	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.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;
-}
-
-static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsigned long long addr_req)
-{
-	struct ata_taskfile args;
-	unsigned long long addr_set = 0;
-
-	addr_req--;
-	/* Create IDE/ATA command request structure */
-	memset(&args, 0, sizeof(args));
-
-	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.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;
-}
-
-/*
- * Tests if the drive supports Host Protected Area feature.
- * Returns true if supported, false otherwise.
- */
-static inline int idedisk_supports_host_protected_area(ide_drive_t *drive)
-{
-	int flag = (drive->id->cfs_enable_1 & 0x0400) ? 1 : 0;
-	printk("%s: host protected area => %d\n", drive->name, flag);
-	return flag;
-}
-
-#endif
-
-/*
- * Compute drive->capacity, the full capacity of the drive
- * Called with drive->id != NULL.
- *
- * To compute capacity, this uses either of
- *
- *    1. CHS value set by user       (whatever user sets will be trusted)
- *    2. LBA value from target drive (require new ATA feature)
- *    3. LBA value from system BIOS  (new one is OK, old one may break)
- *    4. CHS value from system BIOS  (traditional style)
- *
- * in above order (i.e., if value of higher priority is available,
- * reset will be ignored).
- */
-static void init_idedisk_capacity (ide_drive_t  *drive)
-{
-	struct hd_driveid *id = drive->id;
-	unsigned long capacity = drive->cyl * drive->head * drive->sect;
-	unsigned long set_max = idedisk_read_native_max_address(drive);
-	unsigned long long capacity_2 = capacity;
-	unsigned long long set_max_ext;
-
-	drive->capacity48 = 0;
-	drive->select.b.lba = 0;
-
-	if (id->cfs_enable_2 & 0x0400) {
-		capacity_2 = id->lba_capacity_2;
-		drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
-		drive->head		= drive->bios_head = 255;
-		drive->sect		= drive->bios_sect = 63;
-		drive->select.b.lba	= 1;
-		set_max_ext = idedisk_read_native_max_address_ext(drive);
-		if (set_max_ext > capacity_2) {
-#ifdef CONFIG_IDEDISK_STROKE
-			set_max_ext = idedisk_read_native_max_address_ext(drive);
-			set_max_ext = idedisk_set_max_address_ext(drive, set_max_ext);
-			if (set_max_ext) {
-				drive->capacity48 = capacity_2 = set_max_ext;
-				drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect);
-				drive->select.b.lba = 1;
-				drive->id->lba_capacity_2 = capacity_2;
-                        }
-#else
-			printk("%s: setmax_ext LBA %llu, native  %llu\n",
-				drive->name, set_max_ext, capacity_2);
-#endif
-		}
-		drive->bios_cyl		= drive->cyl;
-		drive->capacity48	= capacity_2;
-		drive->capacity		= (unsigned long) capacity_2;
-		return;
-	/* Determine capacity, and use LBA if the drive properly supports it */
-	} else if ((id->capability & 2) && lba_capacity_is_ok(id)) {
-		capacity = id->lba_capacity;
-		drive->cyl = capacity / (drive->head * drive->sect);
-		drive->select.b.lba = 1;
-	}
-
-	if (set_max > capacity) {
-#ifdef CONFIG_IDEDISK_STROKE
-		set_max = idedisk_read_native_max_address(drive);
-		set_max = idedisk_set_max_address(drive, set_max);
-		if (set_max) {
-			drive->capacity = capacity = set_max;
-			drive->cyl = set_max / (drive->head * drive->sect);
-			drive->select.b.lba = 1;
-			drive->id->lba_capacity = capacity;
-		}
-#else
-		printk("%s: setmax LBA %lu, native  %lu\n",
-			drive->name, set_max, capacity);
-#endif
-	}
-
-	drive->capacity = capacity;
-
-	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
-                drive->capacity48 = id->lba_capacity_2;
-		drive->head = 255;
-		drive->sect = 63;
-		drive->cyl = (unsigned long)(drive->capacity48) / (drive->head * drive->sect);
-	}
-}
-
-static unsigned long idedisk_capacity (ide_drive_t *drive)
-{
-	if (drive->id->cfs_enable_2 & 0x0400)
-		return (drive->capacity48 - drive->sect0);
-	return (drive->capacity - drive->sect0);
-}
-
-static ide_startstop_t idedisk_special (ide_drive_t *drive)
-{
-	special_t *s = &drive->special;
-
-	if (s->b.set_geometry) {
+	if (special_cmd & ATA_SPECIAL_GEOMETRY) {
 		struct ata_taskfile args;
 
-		s->b.set_geometry	= 0;
+		drive->special_cmd &= ~ATA_SPECIAL_GEOMETRY;
 
 		memset(&args, 0, sizeof(args));
 		args.taskfile.sector_number	= drive->sect;
@@ -648,8 +391,9 @@
 			args.handler = set_geometry_intr;;
 		}
 		ata_taskfile(drive, &args, NULL);
-	} else if (s->b.recalibrate) {
-		s->b.recalibrate = 0;
+	} else if (special_cmd & ATA_SPECIAL_RECALIBRATE) {
+		drive->special_cmd &= ~ATA_SPECIAL_RECALIBRATE;
+
 		if (!IS_PDC4030_DRIVE) {
 			struct ata_taskfile args;
 
@@ -659,8 +403,8 @@
 			args.handler = recal_intr;
 			ata_taskfile(drive, &args, NULL);
 		}
-	} else if (s->b.set_multmode) {
-		s->b.set_multmode = 0;
+	} else if (special_cmd & ATA_SPECIAL_MMODE) {
+		drive->special_cmd &= ~ATA_SPECIAL_MMODE;
 		if (drive->id && drive->mult_req > drive->id->max_multsect)
 			drive->mult_req = drive->id->max_multsect;
 		if (!IS_PDC4030_DRIVE) {
@@ -673,10 +417,10 @@
 
 			ata_taskfile(drive, &args, NULL);
 		}
-	} else if (s->all) {
-		int special = s->all;
-		s->all = 0;
-		printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special);
+	} else if (special_cmd) {
+		drive->special_cmd = 0;
+
+		printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special_cmd);
 		return ide_stopped;
 	}
 	return IS_PDC4030_DRIVE ? ide_stopped : ide_started;
@@ -686,13 +430,14 @@
 {
 	int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;
 
-	drive->special.all = 0;
-	drive->special.b.set_geometry = legacy;
-	drive->special.b.recalibrate  = legacy;
+	if (legacy)
+		drive->special_cmd = (ATA_SPECIAL_GEOMETRY | ATA_SPECIAL_RECALIBRATE);
+	else
+		drive->special_cmd = 0;
 	if (OK_TO_RESET_CONTROLLER)
 		drive->mult_count = 0;
 	if (drive->mult_req != drive->mult_count)
-		drive->special.b.set_multmode = 1;
+		drive->special_cmd |= ATA_SPECIAL_MMODE;
 }
 
 #ifdef CONFIG_PROC_FS
@@ -812,19 +557,23 @@
 #endif	/* CONFIG_PROC_FS */
 
 /*
- * This is tightly woven into the driver->do_special can not touch.
+ * This is tightly woven into the driver->special can not touch.
  * DON'T do it again until a total personality rewrite is committed.
  */
 static int set_multcount(ide_drive_t *drive, int arg)
 {
-	struct request rq;
+	struct ata_taskfile args;
 
-	if (drive->special.b.set_multmode)
+	if (drive->special_cmd & ATA_SPECIAL_MMODE)
 		return -EBUSY;
-	ide_init_drive_cmd (&rq);
+
+	memset(&args, 0, sizeof(args));
+
 	drive->mult_req = arg;
-	drive->special.b.set_multmode = 1;
-	ide_do_drive_cmd (drive, &rq, ide_wait);
+	drive->special_cmd |= ATA_SPECIAL_MMODE;
+
+	ide_raw_taskfile(drive, &args, NULL);
+
 	return (drive->mult_count == arg) ? 0 : -EIO;
 }
 
@@ -835,6 +584,7 @@
 	drive->nowerr = arg;
 	drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
 	spin_unlock_irq(&ide_lock);
+
 	return 0;
 }
 
@@ -968,12 +718,153 @@
 	resume: idedisk_resume,
 };
 
-static void idedisk_setup(ide_drive_t *drive)
+/*
+ * Queries for true maximum capacity of the drive.
+ * Returns maximum LBA address (> 0) of the drive, 0 if failed.
+ */
+static unsigned long native_max_address(struct ata_device *drive)
+{
+	struct ata_taskfile args;
+	unsigned long addr = 0;
+
+	if (!(drive->id->command_set_1 & 0x0400) &&
+	    !(drive->id->cfs_enable_2 & 0x0100))
+		return addr;
+
+	/* Create IDE/ATA command request structure */
+	memset(&args, 0, sizeof(args));
+	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.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;
+}
+
+static u64 native_max_address_ext(struct ata_device *drive)
+{
+	struct ata_taskfile args;
+	u64 addr = 0;
+
+	/* Create IDE/ATA command request structure */
+	memset(&args, 0, sizeof(args));
+
+	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.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;
+}
+
+#ifdef CONFIG_IDEDISK_STROKE
+/*
+ * Sets maximum virtual LBA address of the drive.
+ * Returns new maximum virtual LBA address (> 0) or 0 on failure.
+ */
+static sector_t set_max_address(ide_drive_t *drive, sector_t addr_req)
+{
+	struct ata_taskfile args;
+	sector_t addr_set = 0;
+
+	addr_req--;
+	/* Create IDE/ATA command request structure */
+	memset(&args, 0, sizeof(args));
+
+	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.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;
+}
+
+static u64 set_max_address_ext(ide_drive_t *drive, u64 addr_req)
+{
+	struct ata_taskfile args;
+	u64 addr_set = 0;
+
+	addr_req--;
+	/* Create IDE/ATA command request structure */
+	memset(&args, 0, sizeof(args));
+
+	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.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;
+}
+
+#endif
+
+static void idedisk_setup(struct ata_device *drive)
 {
 	int i;
 
 	struct hd_driveid *id = drive->id;
-	unsigned long capacity;
+	sector_t capacity;
+	sector_t set_max;
 	int drvid = -1;
 
 	idedisk_add_settings(drive);
@@ -1024,7 +915,7 @@
 		drive->sect    = drive->bios_sect = id->sectors;
 	}
 
-	/* Handle logical geometry translation by the drive */
+	/* Handle logical geometry translation by the drive. */
 	if ((id->field_valid & 1) && id->cur_cyls &&
 	    id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) {
 		drive->cyl  = id->cur_cyls;
@@ -1032,31 +923,126 @@
 		drive->sect = id->cur_sectors;
 	}
 
-	/* Use physical geometry if what we have still makes no sense */
+	/* Use physical geometry if what we have still makes no sense. */
 	if (drive->head > 16 && id->heads && id->heads <= 16) {
 		drive->cyl  = id->cyls;
 		drive->head = id->heads;
 		drive->sect = id->sectors;
 	}
 
-	/* calculate drive capacity, and select LBA if possible */
-	init_idedisk_capacity (drive);
+	/* Calculate drive capacity, and select LBA if possible.
+	 * drive->id != NULL is spected
+	 *
+	 * To compute capacity, this uses either of
+	 *
+	 *    1. CHS value set by user       (whatever user sets will be trusted)
+	 *    2. LBA value from target drive (require new ATA feature)
+	 *    3. LBA value from system BIOS  (new one is OK, old one may break)
+	 *    4. CHS value from system BIOS  (traditional style)
+	 *
+	 * in above order (i.e., if value of higher priority is available,
+	 * reset will be ignored).
+	 */
+	capacity = drive->cyl * drive->head * drive->sect;
+	set_max = native_max_address(drive);
+
+	drive->capacity = 0;
+	drive->select.b.lba = 0;
+
+	if (id->cfs_enable_2 & 0x0400) {
+		u64 set_max_ext;
+		u64 capacity_2;
+		capacity_2 = capacity;
+		capacity_2 = id->lba_capacity_2;
+
+		drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
+		drive->head = drive->bios_head = 255;
+		drive->sect = drive->bios_sect = 63;
+
+		drive->select.b.lba = 1;
+		set_max_ext = native_max_address_ext(drive);
+		if (set_max_ext > capacity_2) {
+#ifdef CONFIG_IDEDISK_STROKE
+			set_max_ext = native_max_address_ext(drive);
+			set_max_ext = set_max_address_ext(drive, set_max_ext);
+			if (set_max_ext) {
+				drive->capacity = capacity_2 = set_max_ext;
+				drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect);
+				drive->select.b.lba = 1;
+				drive->id->lba_capacity_2 = capacity_2;
+                        }
+#else
+			printk("%s: setmax_ext LBA %llu, native  %llu\n",
+				drive->name, set_max_ext, capacity_2);
+#endif
+		}
+		drive->bios_cyl	= drive->cyl;
+		drive->capacity	= capacity_2;
+	} else {
+
+		/*
+		 * Determine capacity, and use LBA if the drive properly
+		 * supports it.
+		 */
+
+		if ((id->capability & 2) && lba_capacity_is_ok(id)) {
+			capacity = id->lba_capacity;
+			drive->cyl = capacity / (drive->head * drive->sect);
+			drive->select.b.lba = 1;
+		}
+
+		if (set_max > capacity) {
+#ifdef CONFIG_IDEDISK_STROKE
+			set_max = native_max_address(drive);
+			set_max = set_max_address(drive, set_max);
+			if (set_max) {
+				drive->capacity = capacity = set_max;
+				drive->cyl = set_max / (drive->head * drive->sect);
+				drive->select.b.lba = 1;
+				drive->id->lba_capacity = capacity;
+			}
+#else
+			printk("%s: setmax LBA %lu, native  %lu\n",
+					drive->name, set_max, capacity);
+#endif
+		}
+
+		drive->capacity = capacity;
+
+		if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
+			drive->capacity = id->lba_capacity_2;
+			drive->head = 255;
+			drive->sect = 63;
+			drive->cyl = (unsigned long)(drive->capacity) / (drive->head * drive->sect);
+		}
+	}
 
 	/*
-	 * if possible, give fdisk access to more of the drive,
+	 * If possible, give fdisk access to more of the drive,
 	 * by correcting bios_cyls:
 	 */
-	capacity = idedisk_capacity (drive);
+	capacity = idedisk_capacity(drive);
 	if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) &&
 	    (!drive->forced_geom) && drive->bios_sect && drive->bios_head)
 		drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head;
 	printk(KERN_INFO "%s: %ld sectors", drive->name, capacity);
 
-	/* Give size in megabytes (MB), not mebibytes (MiB). */
-	/* We compute the exact rounded value, avoiding overflow. */
+#if 0
+
+	/* Right now we avoid this calculation, since it can result in the
+	 * usage of not supported compiler internal functions on 32 bit hosts.
+	 * However since the calculation appears to be an interesting piece of
+	 * number theory let's preserve the formula here.
+	 */
+
+	/* Give size in megabytes (MB), not mebibytes (MiB).
+	 * We compute the exact rounded value, avoiding overflow.
+	 */
 	printk(" (%ld MB)", (capacity - capacity/625 + 974)/1950);
+#endif
 
-	/* Only print cache size when it was specified */
+	/* Only print cache size when it was specified.
+	 */
 	if (id->buf_size)
 		printk (" w/%dKiB Cache", id->buf_size/2);
 
@@ -1074,14 +1060,15 @@
 		id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0;
 		id->multsect_valid = id->multsect ? 1 : 0;
 		drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT;
-		drive->special.b.set_multmode = drive->mult_req ? 1 : 0;
+		if (drive->mult_req)
+			drive->special_cmd |= ATA_SPECIAL_MMODE;
 #else
 		/* original, pre IDE-NFG, per request of AC */
 		drive->mult_req = INITIAL_MULT_COUNT;
 		if (drive->mult_req > id->max_multsect)
 			drive->mult_req = id->max_multsect;
 		if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect))
-			drive->special.b.set_multmode = 1;
+			drive->special_cmd |= ATA_SPECIAL_MMODE;
 #endif
 	}
 
@@ -1095,6 +1082,7 @@
 
 	if (drive->id->cfs_enable_2 & 0x3000)
 		write_cache(drive, (id->cfs_enable_2 & 0x3000));
+
 	probe_lba_addressing(drive, 1);
 }
 
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-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide-dma.c	2002-04-25 23:20:20.000000000 +0200
@@ -295,7 +295,7 @@
 	int i;
 	struct scatterlist *sg;
 
-	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
+	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) {
 		hwif->sg_nents = i = raw_build_sglist(hwif, HWGROUP(drive)->rq);
 	} else {
 		hwif->sg_nents = i = ide_build_sglist(hwif, HWGROUP(drive)->rq);
@@ -590,9 +590,10 @@
 
 			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) &&
+			if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) &&
 			    (drive->addressing == 1)) {
 				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);
diff -urN linux-2.5.10/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.10/drivers/ide/ide-floppy.c	2002-04-23 00:28:19.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c	2002-04-26 00:32:21.000000000 +0200
@@ -1255,12 +1255,12 @@
 	pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;
 }
 
-static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector)
+static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, sector_t sector)
 {
 	int block = sector / floppy->bs_factor;
 	int blocks = rq->nr_sectors / floppy->bs_factor;
 	int cmd = rq_data_dir(rq);
-	
+
 #if IDEFLOPPY_DEBUG_LOG
 	printk ("create_rw1%d_cmd: block == %d, blocks == %d\n",
 		2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags), block, blocks);
@@ -1287,9 +1287,9 @@
 }
 
 /*
- *	idefloppy_do_request is our request handling function.	
+ * This is our request handling function.
  */
-static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
 	idefloppy_floppy_t *floppy = drive->driver_data;
 	idefloppy_pc_t *pc;
@@ -1297,7 +1297,7 @@
 #if IDEFLOPPY_DEBUG_LOG
 	printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors);
 	printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
-#endif /* IDEFLOPPY_DEBUG_LOG */
+#endif
 
 	if (rq->errors >= ERROR_MAX) {
 		if (floppy->failed_pc != NULL)
@@ -1314,7 +1314,7 @@
 			idefloppy_end_request(drive, 0);
 			return ide_stopped;
 		}
-		pc = idefloppy_next_pc_storage (drive);
+		pc = idefloppy_next_pc_storage(drive);
 		idefloppy_create_rw_cmd (floppy, pc, rq, block);
 	} else if (rq->flags & IDEFLOPPY_RQ) {
 		pc = (idefloppy_pc_t *) rq->buffer;
@@ -2063,9 +2063,7 @@
 	release:		idefloppy_release,
 	check_media_change:	idefloppy_check_media_change,
 	revalidate:		NULL, /* use default method */
-	pre_reset:		NULL,
 	capacity:		idefloppy_capacity,
-	special:		NULL,
 	proc:			idefloppy_proc
 };
 
diff -urN linux-2.5.10/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.10/drivers/ide/ide-pmac.c	2002-04-23 00:29:34.000000000 +0200
+++ linux/drivers/ide/ide-pmac.c	2002-04-25 23:27:08.000000000 +0200
@@ -1109,7 +1109,7 @@
 		udelay(1);
 
 	/* Build sglist */
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
+	if (rq->flags & REQ_DRIVE_ACB) {
 		pmac_ide[ix].sg_nents = i = pmac_raw_build_sglist(ix, rq);
 	} else {
 		pmac_ide[ix].sg_nents = i = pmac_ide_build_sglist(ix, rq);
@@ -1386,7 +1386,7 @@
 			return 0;
 		BUG_ON(HWGROUP(drive)->handler);
 		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
-		if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) &&
+		if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) &&
 		    (drive->addressing == 1)) {
 			struct ata_taskfile *args = HWGROUP(drive)->rq->special;
 			OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
diff -urN linux-2.5.10/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c
--- linux-2.5.10/drivers/ide/ide-proc.c	2002-04-23 00:27:49.000000000 +0200
+++ linux/drivers/ide/ide-proc.c	2002-04-26 00:09:09.000000000 +0200
@@ -160,8 +160,8 @@
 	PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
 }
 
-static int proc_ide_read_channel
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int proc_ide_read_channel(char *page, char **start,
+		off_t off, int count, int *eof, void *data)
 {
 	struct ata_channel *hwif = data;
 	int		len;
diff -urN linux-2.5.10/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.10/drivers/ide/ide-tape.c	2002-04-23 00:28:08.000000000 +0200
+++ linux/drivers/ide/ide-tape.c	2002-04-25 21:57:49.000000000 +0200
@@ -2614,9 +2614,9 @@
 }
 
 /*
- *	idetape_do_request is our request handling function.	
+ * This is our request handling function.
  */
-static ide_startstop_t idetape_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t idetape_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
 	idetape_tape_t *tape = drive->driver_data;
 	idetape_pc_t *pc;
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-26 03:38:13.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-04-26 01:44:57.000000000 +0200
@@ -476,15 +476,15 @@
 /*
  * This is invoked on completion of a WIN_SETMULT cmd.
  */
-ide_startstop_t set_multmode_intr (ide_drive_t *drive)
+ide_startstop_t set_multmode_intr(struct ata_device *drive)
 {
-	byte stat;
+	u8 stat;
 
 	if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) {
 		drive->mult_count = drive->mult_req;
 	} else {
 		drive->mult_req = drive->mult_count = 0;
-		drive->special.b.recalibrate = 1;
+		drive->special_cmd |= ATA_SPECIAL_RECALIBRATE;
 		ide_dump_status(drive, "set_multmode", stat);
 	}
 	return ide_stopped;
@@ -879,20 +879,12 @@
 	}
 }
 
-/*
- * This function is intended to be used prior to invoking ide_do_drive_cmd().
- */
-static void init_taskfile_request(struct request *rq)
-{
-	memset(rq, 0, sizeof(*rq));
-	rq->flags = REQ_DRIVE_TASKFILE;
-}
-
 int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
 {
 	struct request rq;
-	init_taskfile_request(&rq);
 
+	memset(&rq, 0, sizeof(rq));
+	rq.flags = REQ_DRIVE_ACB;
 	rq.buffer = buf;
 
 	if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
@@ -909,13 +901,8 @@
  * Implement generic ioctls invoked from userspace to imlpement specific
  * functionality.
  *
- * FIXME:
- *
- * 1. Rewrite hdparm to use the ide_task_ioctl function.
- *
- * 2. Publish it.
- *
- * 3. Kill this and HDIO_DRIVE_CMD alltogether.
+ * Unfortunately every single low level programm out there is using this
+ * interface.
  */
 
 int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
@@ -923,22 +910,19 @@
 	int err = 0;
 	u8 vals[4];
 	u8 *argbuf = vals;
-	byte xfer_rate = 0;
+	u8 xfer_rate = 0;
 	int argsize = 4;
 	struct ata_taskfile args;
 	struct request rq;
 
-	/*
-	 * First phase.
+	ide_init_drive_cmd(&rq);
+
+	/* Wait for drive ready.
 	 */
-	if (NULL == (void *) arg) {
-		struct request rq;
-		ide_init_drive_cmd(&rq);
+	if (!arg)
 		return ide_do_drive_cmd(drive, &rq, ide_wait);
-	}
 
-	/*
-	 * Second phase.
+	/* Second phase.
 	 */
 	if (copy_from_user(vals, (void *)arg, 4))
 		return -EFAULT;
@@ -960,6 +944,8 @@
 		memset(argbuf + 4, 0, argsize - 4);
 	}
 
+	/* Always make sure the transfer reate has been setup.
+	 */
 	if (set_transfer(drive, &args)) {
 		xfer_rate = vals[1];
 		if (ide_ata66_check(drive, &args))
@@ -968,7 +954,6 @@
 
 	/* Issue ATA command and wait for completion.
 	 */
-	ide_init_drive_cmd(&rq);
 	rq.buffer = argbuf;
 	err = ide_do_drive_cmd(drive, &rq, ide_wait);
 
@@ -978,44 +963,22 @@
 			drive->channel->speedproc(drive, xfer_rate);
 		ide_driveid_update(drive);
 	}
+
 abort:
 	if (copy_to_user((void *)arg, argbuf, argsize))
 		err = -EFAULT;
+
 	if (argsize > 4)
 		kfree(argbuf);
 
 	return err;
 }
 
-int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
-{
-	int err = 0;
-	u8 args[7];
-	u8 *argbuf;
-	int argsize = 7;
-	struct request rq;
-
-	argbuf = args;
-
-	if (copy_from_user(args, (void *)arg, 7))
-		return -EFAULT;
-
-	ide_init_drive_cmd(&rq);
-	rq.flags = REQ_DRIVE_TASK;
-	rq.buffer = argbuf;
-	err = ide_do_drive_cmd(drive, &rq, ide_wait);
-	if (copy_to_user((void *)arg, argbuf, argsize))
-		err = -EFAULT;
-	return err;
-}
-
 EXPORT_SYMBOL(drive_is_ready);
-
 EXPORT_SYMBOL(ata_read);
 EXPORT_SYMBOL(ata_write);
 EXPORT_SYMBOL(atapi_read);
 EXPORT_SYMBOL(atapi_write);
-
 EXPORT_SYMBOL(ata_taskfile);
 EXPORT_SYMBOL(recal_intr);
 EXPORT_SYMBOL(set_geometry_intr);
@@ -1023,6 +986,4 @@
 EXPORT_SYMBOL(task_no_data_intr);
 EXPORT_SYMBOL(ide_raw_taskfile);
 EXPORT_SYMBOL(ide_cmd_type_parser);
-
 EXPORT_SYMBOL(ide_cmd_ioctl);
-EXPORT_SYMBOL(ide_task_ioctl);
diff -urN linux-2.5.10/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.10/drivers/scsi/ide-scsi.c	2002-04-23 00:27:48.000000000 +0200
+++ linux/drivers/scsi/ide-scsi.c	2002-04-26 00:32:14.000000000 +0200
@@ -458,9 +458,9 @@
 }
 
 /*
- *	idescsi_do_request is our request handling function.
+ * This is our request handling function.
  */
-static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct request *rq, sector_t block)
 {
 #if IDESCSI_DEBUG_LOG
 	printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
@@ -468,20 +468,20 @@
 #endif /* IDESCSI_DEBUG_LOG */
 
 	if (rq->flags & REQ_SPECIAL) {
-		return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->special);
+		return idescsi_issue_pc(drive, (idescsi_pc_t *) rq->special);
 	}
 	blk_dump_rq_flags(rq, "ide-scsi: unsup command");
 	idescsi_end_request(drive, 0);
 	return ide_stopped;
 }
 
-static int idescsi_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
+static int idescsi_open(struct inode *inode, struct file *filp, struct ata_device *drive)
 {
 	MOD_INC_USE_COUNT;
 	return 0;
 }
 
-static void idescsi_ide_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
+static void idescsi_ide_release(struct inode *inode, struct file *filp, struct ata_device *drive)
 {
 	MOD_DEC_USE_COUNT;
 }
@@ -556,9 +556,7 @@
 	release:		idescsi_ide_release,
 	check_media_change:	NULL,
 	revalidate:		idescsi_revalidate,
-	pre_reset:		NULL,
 	capacity:		NULL,
-	special:		NULL,
 	proc:			NULL
 };
 
diff -urN linux-2.5.10/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux-2.5.10/include/linux/blkdev.h	2002-04-23 00:28:15.000000000 +0200
+++ linux/include/linux/blkdev.h	2002-04-25 23:28:54.000000000 +0200
@@ -76,17 +76,16 @@
 	__REQ_STARTED,	/* drive already may have started this one */
 	__REQ_DONTPREP,	/* don't call prep for this one */
 	/*
-	 * for IDE
- 	*/
+	 * for ATA/ATAPI devices
+	 */
 	__REQ_DRIVE_CMD,
-	__REQ_DRIVE_TASK,
 	__REQ_DRIVE_ACB,
 
 	__REQ_PC,	/* packet command (special) */
 	__REQ_BLOCK_PC,	/* queued down pc from block layer */
 	__REQ_SENSE,	/* sense retrival */
 
-	__REQ_SPECIAL,	/* driver special command */
+	__REQ_SPECIAL,	/* driver special command (currently reset) */
 
 	__REQ_NR_BITS,	/* stops here */
 };
@@ -99,15 +98,12 @@
 #define REQ_STARTED	(1 << __REQ_STARTED)
 #define REQ_DONTPREP	(1 << __REQ_DONTPREP)
 #define REQ_DRIVE_CMD	(1 << __REQ_DRIVE_CMD)
-#define REQ_DRIVE_TASK	(1 << __REQ_DRIVE_TASK)
 #define REQ_DRIVE_ACB	(1 << __REQ_DRIVE_ACB)
 #define REQ_PC		(1 << __REQ_PC)
-#define REQ_SENSE	(1 << __REQ_SENSE)
 #define REQ_BLOCK_PC	(1 << __REQ_BLOCK_PC)
+#define REQ_SENSE	(1 << __REQ_SENSE)
 #define REQ_SPECIAL	(1 << __REQ_SPECIAL)
 
-#define REQ_DRIVE_TASKFILE	REQ_DRIVE_ACB
-
 #include <linux/elevator.h>
 
 typedef int (merge_request_fn) (request_queue_t *, struct request *,
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-26 03:38:13.000000000 +0200
+++ linux/include/linux/hdreg.h	2002-04-25 23:05:19.000000000 +0200
@@ -3,7 +3,7 @@
 
 /*
  * This file contains some defines for the AT-hd-controller.
- * Various sources.  
+ * Various sources.
  */
 
 #define HD_IRQ 14			/* the standard disk interrupt */
@@ -51,11 +51,9 @@
 
 /*
  * Command Header sizes for IOCTL commands
- *	HDIO_DRIVE_CMD and HDIO_DRIVE_TASK
  */
 
 #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
@@ -287,7 +285,6 @@
 #define HDIO_GET_UNMASKINTR	0x0302	/* get current unmask setting */
 #define HDIO_GET_MULTCOUNT	0x0304	/* get current IDE blockmode setting */
 #define HDIO_GET_QDMA		0x0305	/* get use-qdma flag */
-#define HDIO_OBSOLETE_IDENTITY	0x0307	/* OBSOLETE, DO NOT USE: returns 142 bytes */
 #define HDIO_GET_32BIT		0x0309	/* get current io_32bit setting */
 #define HDIO_GET_NOWERR		0x030a	/* get ignore-write-error flag */
 #define HDIO_GET_DMA		0x030b	/* get use-dma flag */
@@ -298,12 +295,8 @@
 #define	HDIO_GET_ADDRESS	0x0310	/* */
 
 #define HDIO_GET_BUSSTATE	0x031a	/* get the bus state of the hwif */
-#define HDIO_TRISTATE_HWIF	0x031b	/* execute a channel tristate */
-#define HDIO_DRIVE_TASK		0x031e	/* execute task and special drive command */
 #define HDIO_DRIVE_CMD		0x031f	/* execute a special drive command */
 
-#define HDIO_DRIVE_CMD_AEB	HDIO_DRIVE_TASK
-
 /* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
 #define HDIO_SET_MULTCOUNT	0x0321	/* change IDE blockmode */
 #define HDIO_SET_UNMASKINTR	0x0322	/* permit other irqs during I/O */
@@ -521,11 +514,7 @@
 					 *  7:0	current value
 					 */
 	unsigned short	words95_99[5];	/* reserved words 95-99 */
-#if 0
-	unsigned short	words100_103[4]	;/* reserved words 100-103 */
-#else
 	unsigned long long lba_capacity_2;/* 48-bit total number of sectors */
-#endif
 	unsigned short	words104_125[22];/* reserved words 104-125 */
 	unsigned short	last_lun;	/* (word 126) */
 	unsigned short	word127;	/* (word 127) Feature Set
@@ -573,7 +562,7 @@
 					 * 15:8 Checksum
 					 *  7:0 Signature
 					 */
-};
+} __attribute__((packed));
 
 /*
  * IDE "nice" flags. These are used on a per drive basis to determine
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-26 03:38:13.000000000 +0200
+++ linux/include/linux/ide.h	2002-04-26 03:30:50.000000000 +0200
@@ -33,23 +33,26 @@
  */
 #define INITIAL_MULT_COUNT	0	/* off=0; on=2,4,8,16,32, etc.. */
 
-#ifndef SUPPORT_SLOW_DATA_PORTS		/* 1 to support slow data ports */
-#define SUPPORT_SLOW_DATA_PORTS	1	/* 0 to reduce kernel size */
+#ifndef SUPPORT_SLOW_DATA_PORTS			/* 1 to support slow data ports */
+# define SUPPORT_SLOW_DATA_PORTS	1	/* 0 to reduce kernel size */
 #endif
+
+/* Right now this is only needed by a promise controlled.
+ */
 #ifndef SUPPORT_VLB_SYNC		/* 1 to support weird 32-bit chips */
-#define SUPPORT_VLB_SYNC	1	/* 0 to reduce kernel size */
+# define SUPPORT_VLB_SYNC	1	/* 0 to reduce kernel size */
 #endif
 #ifndef DISK_RECOVERY_TIME		/* off=0; on=access_delay_time */
-#define DISK_RECOVERY_TIME	0	/*  for hardware that needs it */
+# define DISK_RECOVERY_TIME	0	/*  for hardware that needs it */
 #endif
 #ifndef OK_TO_RESET_CONTROLLER		/* 1 needed for good error recovery */
-#define OK_TO_RESET_CONTROLLER	1	/* 0 for use with AH2372A/B interface */
+# define OK_TO_RESET_CONTROLLER	1	/* 0 for use with AH2372A/B interface */
 #endif
 #ifndef FANCY_STATUS_DUMPS		/* 1 for human-readable drive errors */
-#define FANCY_STATUS_DUMPS	1	/* 0 to reduce kernel size */
+# define FANCY_STATUS_DUMPS	1	/* 0 to reduce kernel size */
 #endif
 #ifndef DISABLE_IRQ_NOSYNC
-#define DISABLE_IRQ_NOSYNC	0
+# define DISABLE_IRQ_NOSYNC	0
 #endif
 
 /*
@@ -262,17 +265,6 @@
 #define ATA_SCSI	0x21
 #define ATA_NO_LUN      0x7f
 
-typedef union {
-	unsigned all			: 8;	/* all of the bits together */
-	struct {
-		unsigned set_geometry	: 1;	/* respecify drive geometry */
-		unsigned recalibrate	: 1;	/* seek to cyl 0      */
-		unsigned set_multmode	: 1;	/* set multmode count */
-		unsigned set_tune	: 1;	/* tune interface for drive */
-		unsigned reserved	: 4;	/* unused */
-	} b;
-} special_t;
-
 struct ide_settings_s;
 /* structure describing an ATA/ATAPI device */
 typedef
@@ -300,7 +292,17 @@
 	unsigned long PADAM_service_time;	/* service time of last request */
 	unsigned long PADAM_timeout;		/* max time to wait for irq */
 
-	special_t	special;	/* special action flags */
+	/* Flags requesting/indicating one of the following special commands
+	 * executed on the request queue.
+	 */
+#define ATA_SPECIAL_GEOMETRY		0x01
+#define ATA_SPECIAL_RECALIBRATE		0x02
+#define ATA_SPECIAL_MMODE		0x04
+#define ATA_SPECIAL_TUNE		0x08
+	unsigned char special_cmd;
+	u8 mult_req;			/* requested multiple sector setting */
+	u8 tune_req;			/* requested drive tuning setting */
+
 	byte     using_dma;		/* disk is using dma for read/write */
 	byte	 retry_pio;		/* retrying dma capable host in pio */
 	byte	 state;			/* retry state */
@@ -327,8 +329,6 @@
 	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		bad_wstat;	/* used for ignoring WRERR_STAT */
 	byte		nowerr;		/* used for ignoring WRERR_STAT */
 	byte		sect0;		/* offset of first sector for DM6:DDO */
@@ -338,8 +338,7 @@
 	byte		bios_sect;	/* BIOS/fdisk/LILO sectors per track */
 	unsigned int	bios_cyl;	/* BIOS/fdisk/LILO number of cyls */
 	unsigned int	cyl;		/* "real" number of cyls */
-	unsigned long	capacity;	/* total number of sectors */
-	unsigned long long capacity48;	/* total number of sectors */
+	u64		capacity;	/* total number of sectors */
 	unsigned int	drive_data;	/* for use by tuneproc/selectproc as needed */
 
 	wait_queue_head_t wqueue;	/* used to wait for drive in open() */
@@ -462,19 +461,19 @@
 	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 */
-	unsigned	present    : 1;	/* there is a device on this interface */
-	unsigned	serialized : 1;	/* serialized operation between channels */
-	unsigned	sharing_irq: 1;	/* 1 = sharing irq with another hwif */
-	unsigned	reset      : 1;	/* reset after probe */
-	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		slow;		/* flag: slow data port */
-	unsigned no_io_32bit	   : 1;	/* disallow enabling 32bit I/O */
+	unsigned noprobe	: 1;	/* don't probe for this interface */
+	unsigned present	: 1;	/* there is a device on this interface */
+	unsigned serialized	: 1;	/* serialized operation between channels */
+	unsigned sharing_irq	: 1;	/* 1 = sharing irq with another hwif */
+	unsigned reset		: 1;	/* reset after probe */
+	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 */
+	unsigned no_io_32bit	: 1;	/* disallow enabling 32bit I/O */
+	unsigned no_unmask	: 1;	/* disallow setting unmask bit */
 	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 */
+	byte		slow;		/* flag: slow data port */
 
 #if (DISK_RECOVERY_TIME > 0)
 	unsigned long	last_time;	/* time when previous rq was done */
@@ -616,20 +615,20 @@
 
 struct ata_operations {
 	struct module *owner;
-	int (*cleanup)(ide_drive_t *);
-	int (*standby)(ide_drive_t *);
-	ide_startstop_t	(*do_request)(ide_drive_t *, struct request *, unsigned long);
-	int (*end_request)(ide_drive_t *drive, int uptodate);
-
-	int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
-	int (*open)(struct inode *, struct file *, ide_drive_t *);
-	void (*release)(struct inode *, struct file *, ide_drive_t *);
-	int (*check_media_change)(ide_drive_t *);
-	void (*revalidate)(ide_drive_t *);
-
-	void (*pre_reset)(ide_drive_t *);
-	unsigned long (*capacity)(ide_drive_t *);
-	ide_startstop_t	(*special)(ide_drive_t *);
+	int (*cleanup)(struct ata_device *);
+	int (*standby)(struct ata_device *);
+	ide_startstop_t	(*do_request)(struct ata_device *, struct request *, sector_t);
+	int (*end_request)(struct ata_device *, int);
+
+	int (*ioctl)(struct ata_device *, struct inode *, struct file *, unsigned int, unsigned long);
+	int (*open)(struct inode *, struct file *, struct ata_device *);
+	void (*release)(struct inode *, struct file *, struct ata_device *);
+	int (*check_media_change)(struct ata_device *);
+	void (*revalidate)(struct ata_device *);
+
+	void (*pre_reset)(struct ata_device *);
+	sector_t (*capacity)(struct ata_device *);
+	ide_startstop_t	(*special)(struct ata_device *);
 
 	ide_proc_entry_t *proc;
 };
@@ -646,7 +645,7 @@
 		__MOD_DEC_USE_COUNT((ata)->owner);	\
 } while(0)
 
-extern unsigned long ata_capacity(ide_drive_t *drive);
+extern sector_t ata_capacity(struct ata_device *drive);
 
 /* FIXME: Actually implement and use them as soon as possible!  to make the
  * ide_scan_devices() go away! */
@@ -733,7 +732,6 @@
  * This function is intended to be used prior to invoking ide_do_drive_cmd().
  */
 extern void ide_init_drive_cmd(struct request *rq);
-extern void init_taskfile_request(struct request *rq);
 
 /*
  * "action" parameter type for ide_do_drive_cmd() below.
@@ -787,10 +785,8 @@
 /* This is setting up all fields in args, which depend upon the command type.
  */
 extern void ide_cmd_type_parser(struct ata_taskfile *args);
-extern int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *cmd, byte *buf);
-
-extern int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg);
-extern int ide_task_ioctl(ide_drive_t *drive, unsigned long arg);
+extern int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *cmd, byte *buf);
+extern int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg);
 
 void ide_delay_50ms(void);
 
@@ -864,13 +860,13 @@
 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
 
 void __init ide_scan_pcibus(int scan_direction);
 #endif
@@ -892,4 +888,4 @@
 extern int drive_is_ready(ide_drive_t *drive);
 extern void revalidate_drives(void);
 
-#endif /* _IDE_H */
+#endif

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

* Re: [PATCH] 2.5.10 UTS_VERSION
  2002-04-26  9:52                     ` Keith Owens
@ 2002-04-26  8:58                       ` Martin Dalecki
  0 siblings, 0 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-04-26  8:58 UTC (permalink / raw)
  To: Keith Owens; +Cc: Linus Torvalds, linux-kernel

Użytkownik Keith Owens napisał:
> On Fri, 26 Apr 2002 09:33:44 +0200, 
> Martin Dalecki <dalecki@evision-ventures.com> wrote:
> 
>>Make sure UTS_VERSION is allways in "C" locale.
>>Without it you will get (please note the day of week):
>>
>>~# export LANG=en_US
>>~# uname -a
>>Linux rosomak.prv 2.5.10 #1 pi? kwi 26 09:31:52 CEST 2002 i686 unknown
>>~#
> 
> 
> Why is that a problem?  If a user wants a kernel uname in their local
> language, kbuild has no objection.  I need LC_COLLATE=C to get a
> consistent filename ordering for kbuild but everything else, including
> build messages, date and time can be local.

Please note that this is not just a compile time problem!
The UTS_STRING is hard compiled *in to* the kernel and should
be normalized for the following reasons:

1. Consistency
2. Consistency
3. Consistency
4. Giving the uname command a chance to translate it to the peculiar locale
    of the user.
5. During boot this string will be printed to the console. This is the
    time where the system doesn't know *anything* about non ASCII character sets.
    This results in the above example for me for example in printing
    of utter garbage on the screen.
6. Kernel messages are supposed to be in LOCALE="C".


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

* Re: [PATCH] 2.5.10 UTS_VERSION
  2002-04-26  7:33                   ` [PATCH] 2.5.10 UTS_VERSION Martin Dalecki
@ 2002-04-26  9:52                     ` Keith Owens
  2002-04-26  8:58                       ` Martin Dalecki
  0 siblings, 1 reply; 48+ messages in thread
From: Keith Owens @ 2002-04-26  9:52 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, linux-kernel

On Fri, 26 Apr 2002 09:33:44 +0200, 
Martin Dalecki <dalecki@evision-ventures.com> wrote:
>Make sure UTS_VERSION is allways in "C" locale.
>Without it you will get (please note the day of week):
>
>~# export LANG=en_US
>~# uname -a
>Linux rosomak.prv 2.5.10 #1 pi± kwi 26 09:31:52 CEST 2002 i686 unknown
>~#

Why is that a problem?  If a user wants a kernel uname in their local
language, kbuild has no objection.  I need LC_COLLATE=C to get a
consistent filename ordering for kbuild but everything else, including
build messages, date and time can be local.


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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26  7:41                   ` [PATCH] 2.5.10 IDE 42 Martin Dalecki
@ 2002-04-26 16:09                     ` Pavel Machek
  2002-04-26 17:31                       ` Dave Jones
                                         ` (2 more replies)
  2002-04-26 16:10                     ` Sebastian Droege
  1 sibling, 3 replies; 48+ messages in thread
From: Pavel Machek @ 2002-04-26 16:09 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, linux-kernel

Hi!

> @@ -783,16 +771,23 @@
>  	if (stat & BUSY_STAT)
>  		printk("Busy ");
>  	else {
> -		if (stat & READY_STAT)	printk("DriveReady ");
> -		if (stat & WRERR_STAT)	printk("DeviceFault ");
> -		if (stat & SEEK_STAT)	printk("SeekComplete ");
> -		if (stat & DRQ_STAT)	printk("DataRequest ");
> -		if (stat & ECC_STAT)	printk("CorrectedError ");
> -		if (stat & INDEX_STAT)	printk("Index ");
> -		if (stat & ERR_STAT)	printk("Error ");
> +		if (stat & READY_STAT)
> +			printk("DriveReady ");
> +		if (stat & WRERR_STAT)
> +			printk("DeviceFault ");
> +		if (stat & SEEK_STAT)
> +			printk("SeekComplete ");
> +		if (stat & DRQ_STAT)
> +			printk("DataRequest ");
> +		if (stat & ECC_STAT)
> +			printk("CorrectedError ");
> +		if (stat & INDEX_STAT)
> +			printk("Index ");
> +		if (stat & ERR_STAT)
> +			printk("Error ");
>  	}
>  	printk("}");
> -#endif	/* FANCY_STATUS_DUMPS */
> +#endif
>  	printk("\n");
>  	if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
>  		err = GET_ERR();

I believe this is actually making it *less* readable.

> @@ -839,7 +834,7 @@
>  					printk(", sector=%ld", HWGROUP(drive)->rq->sector);
>  			}
>  		}
> -#endif	/* FANCY_STATUS_DUMPS */
> +#endif
>  		printk("\n");
>  	}
>  	__restore_flags (flags);	/* local CPU only */

Here to. Comment after endif is good thing; you don't have to add it
but you should certainly not kill it.
									Pavel
-- 
(about SSSCA) "I don't say this lightly.  However, I really think that the U.S.
no longer is classifiable as a democracy, but rather as a plutocracy." --hpa

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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26  7:41                   ` [PATCH] 2.5.10 IDE 42 Martin Dalecki
  2002-04-26 16:09                     ` Pavel Machek
@ 2002-04-26 16:10                     ` Sebastian Droege
  2002-04-26 21:28                       ` Martin Dalecki
  1 sibling, 1 reply; 48+ messages in thread
From: Sebastian Droege @ 2002-04-26 16:10 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: torvalds, linux-kernel

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

On Fri, 26 Apr 2002 09:41:30 +0200
Martin Dalecki <dalecki@evision-ventures.com> wrote:

Hi,

@@ -584,27 +585,25 @@
 			drive->failures = 0;
 		} else {
 			drive->failures++;
+			char *msg = "";

My compiler won't compile that ;)
Declare msg after the function's beginning and it compiles fine

Bye

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 16:09                     ` Pavel Machek
@ 2002-04-26 17:31                       ` Dave Jones
  2002-04-26 17:37                       ` Linus Torvalds
  2002-04-26 21:42                       ` Martin Dalecki
  2 siblings, 0 replies; 48+ messages in thread
From: Dave Jones @ 2002-04-26 17:31 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Martin Dalecki, Linus Torvalds, linux-kernel

On Fri, Apr 26, 2002 at 06:09:11PM +0200, Pavel Machek wrote:

> 
 > > @@ -839,7 +834,7 @@
 > >  					printk(", sector=%ld", HWGROUP(drive)->rq->sector);
 > >  			}
 > >  		}
 > > -#endif	/* FANCY_STATUS_DUMPS */
 > > +#endif
 > >  		printk("\n");
 > >  	}
 > >  	__restore_flags (flags);	/* local CPU only */
 > 
 > Here to. Comment after endif is good thing; you don't have to add it
 > but you should certainly not kill it.

In cases where the #if is several pages before, or there multiple nested
#if's, I agree. But when the #if is just a few lines up with no other #if's
around, it's ugly.

We have functions elsewhere in the kernel like this..

void foo (void)
{
#if MY_MEMORY_SUCKS_BUT_LIKE_SILLY_COMMENTS
    one_line_of_code();
#endif /* MY_MEMORY_SUCKS_BUT_I_LIKE_SILLY_COMMENTS */
}

What information is this comment adding ?

-- 
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs

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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 16:09                     ` Pavel Machek
  2002-04-26 17:31                       ` Dave Jones
@ 2002-04-26 17:37                       ` Linus Torvalds
  2002-04-26 20:05                         ` Oliver Xymoron
  2002-04-26 21:32                         ` Martin Dalecki
  2002-04-26 21:42                       ` Martin Dalecki
  2 siblings, 2 replies; 48+ messages in thread
From: Linus Torvalds @ 2002-04-26 17:37 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Martin Dalecki, linux-kernel



On Fri, 26 Apr 2002, Pavel Machek wrote:
> > +		if (stat & READY_STAT)
> > +			printk("DriveReady ");
> > +		if (stat & WRERR_STAT)
> > +			printk("DeviceFault ");
> > +		if (stat & SEEK_STAT)
> > +			printk("SeekComplete ");
> > +		if (stat & DRQ_STAT)
> > +			printk("DataRequest ");
> > +		if (stat & ECC_STAT)
> > +			printk("CorrectedError ");
> > +		if (stat & INDEX_STAT)
> > +			printk("Index ");
> > +		if (stat & ERR_STAT)
> > +			printk("Error ");
>
> I believe this is actually making it *less* readable.

Somewhat agreed. Also, the above is just not the right way to do
printouts.

I'd suggest rewriting the whole big mess as something like

	#define STAT_STR(x,s) \
		((stat & x ##_STAT) ? s " " : "")

	...

	printf("IDE: %s%s%s%s%s%s..\n"
		STAT_STR(READY, "DriveReady"),
		STAT_STR(WERR, "DeviceFault"),
		...

which is pretty certain to generate much smaller code (not to mention
smaller sources).

			Linus


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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 17:37                       ` Linus Torvalds
@ 2002-04-26 20:05                         ` Oliver Xymoron
  2002-04-26 21:34                           ` Martin Dalecki
  2002-04-26 22:25                           ` Martin Dalecki
  2002-04-26 21:32                         ` Martin Dalecki
  1 sibling, 2 replies; 48+ messages in thread
From: Oliver Xymoron @ 2002-04-26 20:05 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Pavel Machek, Martin Dalecki, linux-kernel

On Fri, 26 Apr 2002, Linus Torvalds wrote:

>
>
> On Fri, 26 Apr 2002, Pavel Machek wrote:
> > > +		if (stat & READY_STAT)
> > > +			printk("DriveReady ");
> > > +		if (stat & WRERR_STAT)
> > > +			printk("DeviceFault ");
> > > +		if (stat & SEEK_STAT)
> > > +			printk("SeekComplete ");
> > > +		if (stat & DRQ_STAT)
> > > +			printk("DataRequest ");
> > > +		if (stat & ECC_STAT)
> > > +			printk("CorrectedError ");
> > > +		if (stat & INDEX_STAT)
> > > +			printk("Index ");
> > > +		if (stat & ERR_STAT)
> > > +			printk("Error ");
> >
> > I believe this is actually making it *less* readable.
>
> Somewhat agreed. Also, the above is just not the right way to do
> printouts.
>
> I'd suggest rewriting the whole big mess as something like
>
> 	#define STAT_STR(x,s) \
> 		((stat & x ##_STAT) ? s " " : "")
>
> 	...
>
> 	printf("IDE: %s%s%s%s%s%s..\n"
> 		STAT_STR(READY, "DriveReady"),
> 		STAT_STR(WERR, "DeviceFault"),
> 		...

I'd go even further and suggest that pulling the mapping from a mask or
key to string out into a table and looping through it is preferable for
this sort of thing. You win later if you decide you need the same mapping
elsewhere or if you want to format your messages differently, add bits to
it, etc. Tables are generally easier to inspect for errors than code,
although Linus' version is very nearly a table.

Maintaining tables as code is a pain and is generally only a win for
small or sparse state machines.

-- 
 "Love the dolphins," she advised him. "Write by W.A.S.T.E.."


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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 16:10                     ` Sebastian Droege
@ 2002-04-26 21:28                       ` Martin Dalecki
  2002-04-26 22:44                         ` Padraig Brady
  0 siblings, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-04-26 21:28 UTC (permalink / raw)
  To: Sebastian Droege; +Cc: torvalds, linux-kernel

Uz.ytkownik Sebastian Droege napisa?:
> On Fri, 26 Apr 2002 09:41:30 +0200
> Martin Dalecki <dalecki@evision-ventures.com> wrote:
> 
> Hi,
> 
> @@ -584,27 +585,25 @@
>  			drive->failures = 0;
>  		} else {
>  			drive->failures++;
> +			char *msg = "";
> 
> My compiler won't compile that ;)
> Declare msg after the function's beginning and it compiles fine

Well it doesn't has to be the function it sufficient to be
the beginng of a block. However this is puzzling me,
becouse the gcc-3.1 snap eats the above just like if it
where a C++ complier!!!

Thank you for pointing out.


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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 17:37                       ` Linus Torvalds
  2002-04-26 20:05                         ` Oliver Xymoron
@ 2002-04-26 21:32                         ` Martin Dalecki
  2002-04-26 23:21                           ` Rene Rebe
  1 sibling, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-04-26 21:32 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Pavel Machek, linux-kernel

Uz.ytkownik Linus Torvalds napisa?:
> 
> On Fri, 26 Apr 2002, Pavel Machek wrote:
> 
>>>+		if (stat & READY_STAT)
>>>+			printk("DriveReady ");
>>>+		if (stat & WRERR_STAT)
>>>+			printk("DeviceFault ");
>>>+		if (stat & SEEK_STAT)
>>>+			printk("SeekComplete ");
>>>+		if (stat & DRQ_STAT)
>>>+			printk("DataRequest ");
>>>+		if (stat & ECC_STAT)
>>>+			printk("CorrectedError ");
>>>+		if (stat & INDEX_STAT)
>>>+			printk("Index ");
>>>+		if (stat & ERR_STAT)
>>>+			printk("Error ");
>>
>>I believe this is actually making it *less* readable.
> 
> 
> Somewhat agreed. Also, the above is just not the right way to do
> printouts.
> 
> I'd suggest rewriting the whole big mess as something like
> 
> 	#define STAT_STR(x,s) \
> 		((stat & x ##_STAT) ? s " " : "")
> 
> 	...
> 
> 	printf("IDE: %s%s%s%s%s%s..\n"
> 		STAT_STR(READY, "DriveReady"),
> 		STAT_STR(WERR, "DeviceFault"),
> 		...
> 
> which is pretty certain to generate much smaller code (not to mention
> smaller sources).

Agreed. Making the code more compact was the only reason I was
touching those debugging sections in first place.

BTW> I'm still puzzled that gcc-3.1 eats C++ like randomly
placed variable declarations. Is there someting I did miss in C9X
papers maybe?


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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 20:05                         ` Oliver Xymoron
@ 2002-04-26 21:34                           ` Martin Dalecki
  2002-04-26 22:25                           ` Martin Dalecki
  1 sibling, 0 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-04-26 21:34 UTC (permalink / raw)
  To: Oliver Xymoron; +Cc: Linus Torvalds, Pavel Machek, linux-kernel

Uz.ytkownik Oliver Xymoron napisa?:
> On Fri, 26 Apr 2002, Linus Torvalds wrote:
> 
> 
>>
>>On Fri, 26 Apr 2002, Pavel Machek wrote:
>>
>>>>+		if (stat & READY_STAT)
>>>>+			printk("DriveReady ");
>>>>+		if (stat & WRERR_STAT)
>>>>+			printk("DeviceFault ");
>>>>+		if (stat & SEEK_STAT)
>>>>+			printk("SeekComplete ");
>>>>+		if (stat & DRQ_STAT)
>>>>+			printk("DataRequest ");
>>>>+		if (stat & ECC_STAT)
>>>>+			printk("CorrectedError ");
>>>>+		if (stat & INDEX_STAT)
>>>>+			printk("Index ");
>>>>+		if (stat & ERR_STAT)
>>>>+			printk("Error ");
>>>
>>>I believe this is actually making it *less* readable.
>>
>>Somewhat agreed. Also, the above is just not the right way to do
>>printouts.
>>
>>I'd suggest rewriting the whole big mess as something like
>>
>>	#define STAT_STR(x,s) \
>>		((stat & x ##_STAT) ? s " " : "")
>>
>>	...
>>
>>	printf("IDE: %s%s%s%s%s%s..\n"
>>		STAT_STR(READY, "DriveReady"),
>>		STAT_STR(WERR, "DeviceFault"),
>>		...
> 
> 
> I'd go even further and suggest that pulling the mapping from a mask or
> key to string out into a table and looping through it is preferable for
> this sort of thing. You win later if you decide you need the same mapping
> elsewhere or if you want to format your messages differently, add bits to
> it, etc. Tables are generally easier to inspect for errors than code,
> although Linus' version is very nearly a table.
> 
> Maintaining tables as code is a pain and is generally only a win for
> small or sparse state machines.

Yes I will use an ffz() based loop to lookup a table.


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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 16:09                     ` Pavel Machek
  2002-04-26 17:31                       ` Dave Jones
  2002-04-26 17:37                       ` Linus Torvalds
@ 2002-04-26 21:42                       ` Martin Dalecki
  2 siblings, 0 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-04-26 21:42 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Linus Torvalds, linux-kernel

Uz.ytkownik Pavel Machek napisa?:

>>+		if (stat & READY_STAT)
>>+			printk("DriveReady ");
>>+		if (stat & WRERR_STAT)
>>+			printk("DeviceFault ");
>>+		if (stat & SEEK_STAT)
>>+			printk("SeekComplete ");
>>+		if (stat & DRQ_STAT)
>>+			printk("DataRequest ");
>>+		if (stat & ECC_STAT)
>>+			printk("CorrectedError ");
>>+		if (stat & INDEX_STAT)
>>+			printk("Index ");
>>+		if (stat & ERR_STAT)
>>+			printk("Error ");
>> 	}
>> 	printk("}");
>>-#endif	/* FANCY_STATUS_DUMPS */
>>+#endif
>> 	printk("\n");
>> 	if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
>> 		err = GET_ERR();
> 
> 
> I believe this is actually making it *less* readable.

It makes the waste of stack setup code and call instructions
more obvious then the former, so the chances are better that I will
come back and compactize the actually generated code a bit ;-)

BTW> Redundant comments can only be false. Like the following:

#ifdef DEFINE

#endif /* DEFINE */

/*
  * some_function() is used for this and that
  */
some_function()
{
	for (;;)
	{
	} /* for */
} /* some_function() */




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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 20:05                         ` Oliver Xymoron
  2002-04-26 21:34                           ` Martin Dalecki
@ 2002-04-26 22:25                           ` Martin Dalecki
  1 sibling, 0 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-04-26 22:25 UTC (permalink / raw)
  To: Oliver Xymoron; +Cc: Linus Torvalds, Pavel Machek, linux-kernel

>>Somewhat agreed. Also, the above is just not the right way to do
>>printouts.
>>
>>I'd suggest rewriting the whole big mess as something like
>>
>>	#define STAT_STR(x,s) \
>>		((stat & x ##_STAT) ? s " " : "")
>>
>>	...
>>
>>	printf("IDE: %s%s%s%s%s%s..\n"
>>		STAT_STR(READY, "DriveReady"),
>>		STAT_STR(WERR, "DeviceFault"),
>>		...
> 
> 
> I'd go even further and suggest that pulling the mapping from a mask or
> key to string out into a table and looping through it is preferable for
> this sort of thing. You win later if you decide you need the same mapping
> elsewhere or if you want to format your messages differently, add bits to
> it, etc. Tables are generally easier to inspect for errors than code,
> although Linus' version is very nearly a table.
> 
> Maintaining tables as code is a pain and is generally only a win for
> small or sparse state machines.


Once could have a look at the ll_rw_blk.c file. There is
a function there, which is dissecting the differnt request
attributes, which are stored as bitfields there.


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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 21:28                       ` Martin Dalecki
@ 2002-04-26 22:44                         ` Padraig Brady
  2002-04-28  9:18                           ` Kai Henningsen
  0 siblings, 1 reply; 48+ messages in thread
From: Padraig Brady @ 2002-04-26 22:44 UTC (permalink / raw)
  To: linux-kernel

Martin Dalecki wrote:
 > Uz.ytkownik Sebastian Droege napisa?:
 >
 >> On Fri, 26 Apr 2002 09:41:30 +0200
 >> Martin Dalecki <dalecki@evision-ventures.com> wrote:
 >>
 >> Hi,
 >>
 >> @@ -584,27 +585,25 @@
 >>              drive->failures = 0;
 >>          } else {
 >>              drive->failures++;
 >> +            char *msg = "";
 >>
 >> My compiler won't compile that ;)
 >> Declare msg after the function's beginning and it compiles fine
 >
 >
 > Well it doesn't has to be the function it sufficient to be
 > the beginng of a block. However this is puzzling me,
 > becouse the gcc-3.1 snap eats the above just like if it
 > where a C++ complier!!!
 >
 > Thank you for pointing out.

Note the "mixed declarations and code" @
http://www.gnu.org/software/gcc/gcc-3.0/c99status.html

Padraig.



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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 21:32                         ` Martin Dalecki
@ 2002-04-26 23:21                           ` Rene Rebe
  0 siblings, 0 replies; 48+ messages in thread
From: Rene Rebe @ 2002-04-26 23:21 UTC (permalink / raw)
  To: dalecki; +Cc: torvalds, pavel, linux-kernel

Hi.

On: Fri, 26 Apr 2002 23:32:44 +0200,
    Martin Dalecki <dalecki@evision-ventures.com> wrote:

> BTW> I'm still puzzled that gcc-3.1 eats C++ like randomly
> placed variable declarations. Is there someting I did miss in C9X
> papers maybe?

Yes this is a C99 feature.

k33p h4ck1n6
  René

--  
René Rebe (Registered Linux user: #248718 <http://counter.li.org>)

eMail:    rene.rebe@gmx.net
          rene@rocklinux.org

Homepage: http://drocklinux.dyndns.org/rene/

Anyone sending unwanted advertising e-mail to this address will be
charged $25 for network traffic and computing time. By extracting my
address from this message or its header, you agree to these terms.

> 

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

* Re: [PATCH] 2.5.10 IDE 42
  2002-04-26 22:44                         ` Padraig Brady
@ 2002-04-28  9:18                           ` Kai Henningsen
  0 siblings, 0 replies; 48+ messages in thread
From: Kai Henningsen @ 2002-04-28  9:18 UTC (permalink / raw)
  To: linux-kernel

padraig@antefacto.com (Padraig Brady)  wrote on 26.04.02 in <3CC9D865.80104@antefacto.com>:

> Martin Dalecki wrote:
>  > Uz.ytkownik Sebastian Droege napisa?:
>  >
>  >> On Fri, 26 Apr 2002 09:41:30 +0200
>  >> Martin Dalecki <dalecki@evision-ventures.com> wrote:
>  >>
>  >> Hi,
>  >>
>  >> @@ -584,27 +585,25 @@
>  >>              drive->failures = 0;
>  >>          } else {
>  >>              drive->failures++;
>  >> +            char *msg = "";
>  >>
>  >> My compiler won't compile that ;)
>  >> Declare msg after the function's beginning and it compiles fine
>  >
>  >
>  > Well it doesn't has to be the function it sufficient to be
>  > the beginng of a block. However this is puzzling me,
>  > becouse the gcc-3.1 snap eats the above just like if it
>  > where a C++ complier!!!

> Note the "mixed declarations and code" @
> http://www.gnu.org/software/gcc/gcc-3.0/c99status.html

And see the -std= option for selecting what ou want it to conform to.

MfG Kai

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

* [PATCH] 2.5.13 IDE 52
  2002-04-25 21:02                 ` Linus Torvalds
  2002-04-26  7:33                   ` [PATCH] 2.5.10 UTS_VERSION Martin Dalecki
  2002-04-26  7:41                   ` [PATCH] 2.5.10 IDE 42 Martin Dalecki
@ 2002-05-05 15:54                   ` Martin Dalecki
  2002-05-05 17:09                     ` Jens Axboe
  2002-05-05 15:55                   ` [PATCH] 2.5.13 IDE 53 Martin Dalecki
  2002-05-05 15:56                   ` [PATCH 2.5.13 IDE 54 Martin Dalecki
  4 siblings, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-05-05 15:54 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

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

Fri May  3 17:50:22 CEST 2002 ide-clean-52

Adapted from patch Barłomiej Żołnierkiewicz:

- make straight8 a flag in ata_channel instead of byte

- don't store tables as code in drive_is_flashcard()
   and ide_xfer_verbose()

- fix init_gendisk() (due to 2.5.13 blksize_size[] change)

- compress region requesting/releasing
   in channel_probe() and ide_unregister()

- clean a bit ide_setup_ports()

Start of DMA handling tratment.

- Fix the parameters to ide_build_dmatable() to be channel and request.
   Rename it to udma_new_table(). udma will mark arch specific functions
   later.

- Let ide_start_dma() take the request directly as an arguemnt. Rename it to
   ata_start_dma(). After realizing that the usage of the func argument of it
   was bogous and that nobody is using rwproc we where able to remove both of
   them.

- Fix ide_destroy_dmatable() to take the channel as argument and rename it to
   udma_destroy_table(). This function should have possible architecture
   specific implementation as well at some point in time.

- Split up the TCQ UDMA handling stuff in to proper functions. Jens must has
   been dreaming as he introduced them ;-).


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

diff -urN linux-2.5.13/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- linux-2.5.13/arch/cris/drivers/ide.c	2002-05-03 02:22:45.000000000 +0200
+++ linux/arch/cris/drivers/ide.c	2002-05-04 04:01:08.000000000 +0200
@@ -191,7 +191,7 @@
 #define ATA_PIO0_STROBE 19
 #define ATA_PIO0_HOLD    4
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive);
+static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq);
 static void e100_ideproc (ide_ide_action_t func, ide_drive_t *drive,
 			  void *buffer, unsigned int length);
 
@@ -278,7 +278,7 @@
 
 		hwif->chipset = ide_etrax100;
 		hwif->tuneproc = &tune_e100_ide;
-		hwif->dmaproc = &e100_dmaproc;
+		hwif->udma = &e100_dmaproc;
 		hwif->ata_read = e100_ide_input_data;
 		hwif->ata_write = e100_ide_output_data;
 		hwif->atapi_read = e100_atapi_read;
@@ -564,13 +564,14 @@
 static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS];
 static unsigned int ata_tot_size;
 
+
 /*
- * e100_ide_build_dmatable() prepares a dma request.
- * Returns 0 if all went okay, returns 1 otherwise.
+ * This prepares a dma request.  Returns 0 if all went okay, returns 1
+ * otherwise.
  */
-static int e100_ide_build_dmatable (ide_drive_t *drive)
+
+static int e100_udma_new_table(struct ata_channel *ch, struct request *rq)
 {
-	struct request *rq = HWGROUP(drive)->rq;
 	struct buffer_head *bh = rq->bh;
 	unsigned long size, addr;
 	unsigned int count = 0;
@@ -602,7 +603,7 @@
 		/* did we run out of descriptors? */
 
 		if(count >= MAX_DMA_DESCRS) {
-			printk("%s: too few DMA descriptors\n", drive->name);
+			printk("%s: too few DMA descriptors\n", ch->name);
 			return 1;
 		}
 
@@ -623,7 +624,7 @@
                    size > 131072 only one split is necessary */
 
 		if(size > 65536) {
- 		        /* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
+		        /* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
                         ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
                         ata_descrs[count].ctrl = 0;
                         ata_descrs[count].buf = addr;
@@ -656,7 +657,7 @@
 		return 0;
 	}
 
-	printk("%s: empty DMA table?\n", drive->name);
+	printk("%s: empty DMA table?\n", ch->name);
 	return 1;	/* let the PIO routines handle this weirdness */
 }
 
@@ -695,7 +696,7 @@
 	LED_DISK_READ(0);
 	LED_DISK_WRITE(0);
 
-	dma_stat = drive->channel->dmaproc(ide_dma_end, drive);
+	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
 	stat = GET_STAT();			/* get drive status */
 	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
 		if (!dma_stat) {
@@ -726,7 +727,7 @@
  * the caller should revert to PIO for the current request.
  */
 
-static int e100_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+static int e100_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
         static unsigned int reading; /* static to support ide_dma_begin semantics */
 	int atapi = 0;
@@ -786,24 +787,21 @@
 
 		/* set up the Etrax DMA descriptors */
 
-		if(e100_ide_build_dmatable (drive))
+		if(e100_udma_new_table(drive->channel, rq))
 			return 1;
 
 		if(!atapi) {
 			/* set the irq handler which will finish the request when DMA is done */
-		
 			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
-			
+
 			/* issue cmd to drive */
-			
 			OUT_BYTE(WIN_READDMA, IDE_COMMAND_REG);
 		}
 
 		/* begin DMA */
-	      
 		*R_DMA_CH3_FIRST = virt_to_phys(ata_descrs);
 		*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
-		
+
 		/* initiate a multi word dma read using DMA handshaking */
 		
 		*R_ATA_TRANSFER_CNT =
@@ -820,7 +818,7 @@
 		LED_DISK_READ(1);
 
 		D(printk("dma read of %d bytes.\n", ata_tot_size));
- 
+
 	} else {
 		/* writing */
 
@@ -829,29 +827,25 @@
 
 		/* set up the Etrax DMA descriptors */
 
-		if(e100_ide_build_dmatable (drive))
+		if(e100_udma_new_table(drive->channel, rq))
 			return 1;
 
 		if(!atapi) {
 			/* set the irq handler which will finish the request when DMA is done */
-				
 			ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
-			
+
 			/* issue cmd to drive */
-			
 			OUT_BYTE(WIN_WRITEDMA, IDE_COMMAND_REG);
 		}
 
 		/* begin DMA */
-		
 		*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs);
 		*R_DMA_CH2_CMD   = IO_STATE(R_DMA_CH2_CMD, cmd, start);
-		
+
 		/* initiate a multi word dma write using DMA handshaking */
-		
 		*R_ATA_TRANSFER_CNT =
 			IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
-		
+
 		*R_ATA_CTRL_DATA =
 			IO_FIELD(R_ATA_CTRL_DATA, data,     IDE_DATA_REG) |
 			IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
@@ -878,7 +872,7 @@
  * --- Marcin Dalecki
  */
 
-void ide_release_dma(struct ata_channel *hwif)
+void ide_release_dma(struct ata_channel *ch)
 {
 	/* empty */
 }
diff -urN linux-2.5.13/drivers/ide/ata-timing.h linux/drivers/ide/ata-timing.h
--- linux-2.5.13/drivers/ide/ata-timing.h	2002-05-03 02:22:55.000000000 +0200
+++ linux/drivers/ide/ata-timing.h	2002-05-04 05:43:45.000000000 +0200
@@ -74,12 +74,12 @@
  * It's a bit elaborate due to the legacy we have to bear.
  */
 
-extern short ata_timing_mode(ide_drive_t *drive, int map);
+extern short ata_timing_mode(struct ata_device *drive, int map);
 extern void ata_timing_quantize(struct ata_timing *t, struct ata_timing *q,
 		int T, int UT);
 extern void ata_timing_merge(struct ata_timing *a, struct ata_timing *b,
 		struct ata_timing *m, unsigned int what);
 extern struct ata_timing* ata_timing_data(short speed);
-extern int ata_timing_compute(ide_drive_t *drive,
+extern int ata_timing_compute(struct ata_device *drive,
 		short speed, struct ata_timing *t, int T, int UT);
 #endif
diff -urN linux-2.5.13/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c
--- linux-2.5.13/drivers/ide/cmd64x.c	2002-05-03 02:22:49.000000000 +0200
+++ linux/drivers/ide/cmd64x.c	2002-05-04 03:59:44.000000000 +0200
@@ -208,10 +208,10 @@
  * This routine writes the prepared setup/active/recovery counts
  * for a drive into the cmd646 chipset registers to active them.
  */
-static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count)
+static void program_drive_counts(struct ata_device *drive, int setup_count, int active_count, int recovery_count)
 {
 	unsigned long flags;
-	ide_drive_t *drives = drive->channel->drives;
+	struct ata_device *drives = drive->channel->drives;
 	byte temp_b;
 	static const byte setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
 	static const byte recovery_counts[] =
@@ -277,7 +277,7 @@
  * 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
  * Called with 255 at boot time.
  */
-static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted)
+static void cmd64x_tuneproc(struct ata_device *drive, byte mode_wanted)
 {
 	int recovery_time, clock_time;
 	byte recovery_count2, cycle_count;
@@ -351,7 +351,7 @@
 	}
 }
 
-static void cmd680_tuneproc (ide_drive_t *drive, byte mode_wanted)
+static void cmd680_tuneproc(struct ata_device *drive, byte mode_wanted)
 {
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -381,7 +381,7 @@
 	pci_write_config_word(dev, drive_pci, speedt);
 }
 
-static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+static void config_cmd64x_chipset_for_pio(struct ata_device *drive, byte set_speed)
 {
 	byte speed	= 0x00;
 	byte set_pio	= ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
@@ -392,7 +392,7 @@
 		(void) ide_config_drive_speed(drive, speed);
 }
 
-static void config_cmd680_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+static void config_cmd680_chipset_for_pio(struct ata_device *drive, byte set_speed)
 {
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -418,7 +418,7 @@
 	}
 }
 
-static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+static void config_chipset_for_pio(struct ata_device *drive, byte set_speed)
 {
         if (drive->channel->pci_dev->device == PCI_DEVICE_ID_CMD_680) {
 		config_cmd680_chipset_for_pio(drive, set_speed);
@@ -427,7 +427,7 @@
 	}
 }
 
-static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
+static int cmd64x_tune_chipset(struct ata_device *drive, byte speed)
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	struct ata_channel *hwif = drive->channel;
@@ -496,7 +496,7 @@
 	return err;
 }
 
-static int cmd680_tune_chipset (ide_drive_t *drive, byte speed)
+static int cmd680_tune_chipset(struct ata_device *drive, byte speed)
 {
 	struct ata_channel *hwif = drive->channel;
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -612,7 +612,7 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_cmd64x_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
+static int config_cmd64x_chipset_for_dma(struct ata_device *drive, unsigned int rev, byte ultra_66)
 {
 	struct hd_driveid *id	= drive->id;
 	struct ata_channel *hwif = drive->channel;
@@ -697,7 +697,7 @@
 	return rval;
 }
 
-static int config_cmd680_chipset_for_dma (ide_drive_t *drive)
+static int config_cmd680_chipset_for_dma(struct ata_device *drive)
 {
 	struct hd_driveid *id	= drive->id;
 	byte udma_66		= eighty_ninty_three(drive);
@@ -739,14 +739,14 @@
 	return rval;
 }
 
-static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66)
+static int config_chipset_for_dma(struct ata_device *drive, unsigned int rev, byte ultra_66)
 {
 	if (drive->channel->pci_dev->device == PCI_DEVICE_ID_CMD_680)
 		return (config_cmd680_chipset_for_dma(drive));
 	return (config_cmd64x_chipset_for_dma(drive, rev, ultra_66));
 }
 
-static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
+static int cmd64x_config_drive_for_dma(struct ata_device *drive)
 {
 	struct hd_driveid *id	= drive->id;
 	struct ata_channel *hwif = drive->channel;
@@ -839,11 +839,12 @@
 
 static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	byte dma_stat		= 0;
-	byte dma_alt_stat	= 0;
-	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;
+	struct ata_channel *ch = drive->channel;
+	u8 dma_stat = 0;
+	u8 dma_alt_stat	= 0;
+	u8 mask	= (ch->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
+	unsigned long dma_base	= ch->dma_base;
+	struct pci_dev *dev	= ch->pci_dev;
 	byte jack_slap		= ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
 
 	switch (func) {
@@ -855,9 +856,9 @@
 			dma_stat = inb(dma_base+2);		/* get DMA status */
 			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
 			if (jack_slap) {
-				byte dma_intr	= 0;
-				byte dma_mask	= (drive->channel->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
-				byte dma_reg	= (drive->channel->unit) ? ARTTIM2 : CFR;
+				byte dma_intr = 0;
+				byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+				byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
 				(void) pci_read_config_byte(dev, dma_reg, &dma_intr);
 				/*
 				 * DAMN BMIDE is not connected to PCI space!
@@ -866,7 +867,7 @@
 				 */
 				(void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask);	/* clear the INTR bit */
 			}
-			ide_destroy_dmatable(drive);		/* purge DMA mappings */
+			udma_destroy_table(ch);	/* purge DMA mappings */
 			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
 			dma_stat = inb(dma_base+2);
@@ -891,8 +892,8 @@
  */
 static int cmd646_1_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
 	byte dma_stat;
 
 	switch (func) {
@@ -903,7 +904,7 @@
 			dma_stat = inb(dma_base+2);		/* get DMA status */
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
 			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
-			ide_destroy_dmatable(drive);		/* and free any DMA resources */
+			udma_destroy_table(ch);			/* and free any DMA resources */
 			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		default:
 			break;
@@ -914,48 +915,48 @@
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
-static int cmd680_busproc (ide_drive_t * drive, int state)
+static int cmd680_busproc(struct ata_device * drive, int state)
 {
 #if 0
-	struct ata_channel *hwif	= drive->channel;
-	u8 addr_mask		= (hwif->unit) ? 0xB0 : 0xA0;
+	struct ata_channel *ch	= drive->channel;
+	u8 addr_mask		= (ch->unit) ? 0xB0 : 0xA0;
 	u32 stat_config		= 0;
 
-        pci_read_config_dword(hwif->pci_dev, addr_mask, &stat_config);
+        pci_read_config_dword(ch->pci_dev, addr_mask, &stat_config);
 
-	if (!hwif)
+	if (!ch)
 		return -EINVAL;
 
 	switch (state) {
 		case BUSSTATE_ON:
-			hwif->drives[0].failures = 0;
-			hwif->drives[1].failures = 0;
+			ch->drives[0].failures = 0;
+			ch->drives[1].failures = 0;
 			break;
 		case BUSSTATE_OFF:
-			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
-			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+			ch->drives[0].failures = ch->drives[0].max_failures + 1;
+			ch->drives[1].failures = ch->drives[1].max_failures + 1;
 			break;
 		case BUSSTATE_TRISTATE:
-			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
-			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
+			ch->drives[0].failures = ch->drives[0].max_failures + 1;
+			ch->drives[1].failures = ch->drives[1].max_failures + 1;
 			break;
 		default:
 			return 0;
 	}
-	hwif->bus_state = state;
+	ch->bus_state = state;
 #endif
 	return 0;
 }
 
-static void cmd680_reset (ide_drive_t *drive)
+static void cmd680_reset(struct ata_device *drive)
 {
 #if 0
-	struct ata_channel *hwif = drive->channel;
-	u8 addr_mask		= (hwif->unit) ? 0xB0 : 0xA0;
-	byte reset		= 0;
+	struct ata_channel *ch = drive->channel;
+	u8 addr_mask = (ch->unit) ? 0xB0 : 0xA0;
+	u8 reset = 0;
 
-	pci_read_config_byte(hwif->pci_dev, addr_mask, &reset);
-	pci_write_config_byte(hwif->pci_dev, addr_mask, reset|0x03);
+	pci_read_config_byte(ch->pci_dev, addr_mask, &reset);
+	pci_write_config_byte(ch->pci_dev, addr_mask, reset|0x03);
 #endif
 }
 
diff -urN linux-2.5.13/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.13/drivers/ide/hpt34x.c	2002-05-04 06:07:13.000000000 +0200
+++ linux/drivers/ide/hpt34x.c	2002-05-04 03:53:29.000000000 +0200
@@ -312,10 +312,10 @@
  * by HighPoint|Triones Technologies, Inc.
  */
 
-int hpt34x_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+int hpt34x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
 	unsigned int count, reading = 0;
 	byte dma_stat;
 
@@ -325,9 +325,9 @@
 		case ide_dma_read:
 			reading = 1 << 3;
 		case ide_dma_write:
-			if (!(count = ide_build_dmatable(drive, func)))
+			if (!(count = udma_new_table(ch, rq)))
 				return 1;	/* try PIO instead of DMA */
-			outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
+			outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
 			reading |= 0x01;
 			outb(reading, dma_base);		/* specify r/w */
 			outb(inb(dma_base+2)|6, dma_base+2);	/* clear INTR & ERROR flags */
@@ -342,7 +342,7 @@
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
 			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 */
+			udma_destroy_table(ch);			/* purge DMA mappings */
 			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		default:
 			break;
diff -urN linux-2.5.13/drivers/ide/icside.c linux/drivers/ide/icside.c
--- linux-2.5.13/drivers/ide/icside.c	2002-05-03 02:22:41.000000000 +0200
+++ linux/drivers/ide/icside.c	2002-05-04 05:33:38.000000000 +0200
@@ -242,9 +242,9 @@
 }
 
 static int
-icside_build_dmatable(ide_drive_t *drive, int reading)
+icside_udma_new_table(struct ata_channel *ch, struct request *rq)
 {
-	return drive->channel->sg_nents = ide_build_sglist(drive->channel, HWGROUP(drive)->rq);
+	return ch->sg_nents = ide_build_sglist(ch, rq);
 }
 
 /* Teardown mappings after DMA has completed.  */
@@ -332,7 +332,7 @@
 	int i;
 	byte stat, dma_stat;
 
-	dma_stat = drive->channel->dmaproc(ide_dma_end, drive);
+	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
 	stat = GET_STAT();			/* get drive status */
 	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
 		if (!dma_stat) {
@@ -350,7 +350,7 @@
 
 
 static int
-icside_dma_check(ide_drive_t *drive)
+icside_dma_check(struct ata_device *drive, struct request *rq)
 {
 	struct hd_driveid *id = drive->id;
 	struct ata_channel *hwif = drive->channel;
@@ -381,14 +381,7 @@
 out:
 	func = icside_config_if(drive, xfer_mode);
 
-	return hwif->dmaproc(func, drive);
-}
-
-static int
-icside_dma_verbose(ide_drive_t *drive)
-{
-	printk(", DMA");
-	return 1;
+	return hwif->udma(func, drive, rq);
 }
 
 static int
@@ -413,12 +406,12 @@
 		return 0;
 
 	case ide_dma_check:
-		return icside_dma_check(drive);
+		return icside_dma_check(drive, rq);
 
 	case ide_dma_read:
 		reading = 1;
 	case ide_dma_write:
-		count = icside_build_dmatable(drive, reading);
+		count = icside_udma_new_table(hwif, rq);
 		if (!count)
 			return 1;
 		disable_dma(hwif->hw.dma);
@@ -458,9 +451,6 @@
 	case ide_dma_test_irq:
 		return inb((unsigned long)hwif->hw.priv) & 1;
 
-	case ide_dma_verbose:
-		return icside_dma_verbose(drive);
-
 	case ide_dma_timeout:
 	default:
 		printk("icside_dmaproc: unsupported function: %d\n", func);
diff -urN linux-2.5.13/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.13/drivers/ide/ide.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-05-04 05:31:42.000000000 +0200
@@ -226,7 +226,7 @@
  * of the kernel (such as memory allocation) to be functioning yet.
  *
  * This is too bad, as otherwise we could dynamically allocate the
- * ide_drive_t structs as needed, rather than always consuming memory
+ * ata_device structs as needed, rather than always consuming memory
  * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them.
  */
 #define MAGIC_COOKIE 0x12345678
@@ -263,24 +263,29 @@
  * At that time, we might also consider parameterizing the timeouts and retries,
  * since these are MUCH faster than mechanical drives.	-M.Lord
  */
-int drive_is_flashcard (ide_drive_t *drive)
+int drive_is_flashcard(struct ata_device *drive)
 {
 	struct hd_driveid *id = drive->id;
+	int i;
+
+	char *flashcards[] = {
+		"KODAK ATA_FLASH",
+		"Hitachi CV",
+		"SunDisk SDCFB",
+		"HAGIWARA HPC",
+		"LEXAR ATA_FLASH",
+		"ATA_FLASH"		/* Simple Tech */
+	};
 
 	if (drive->removable && id != NULL) {
 		if (id->config == 0x848a)
 			return 1;	/* CompactFlash */
-		if (!strncmp(id->model, "KODAK ATA_FLASH", 15)	/* Kodak */
-		 || !strncmp(id->model, "Hitachi CV", 10)	/* Hitachi */
-		 || !strncmp(id->model, "SunDisk SDCFB", 13)	/* SunDisk */
-		 || !strncmp(id->model, "HAGIWARA HPC", 12)	/* Hagiwara */
-		 || !strncmp(id->model, "LEXAR ATA_FLASH", 15)	/* Lexar */
-		 || !strncmp(id->model, "ATA_FLASH", 9))	/* Simple Tech */
-		{
-			return 1;	/* yes, it is a flash memory card */
-		}
+		for (i = 0; i < ARRAY_SIZE(flashcards); i++)
+			if (!strncmp(id->model, flashcards[i],
+				     strlen(flashcards[i])))
+				return 1;
 	}
-	return 0;	/* no, it is not a flash memory card */
+	return 0;
 }
 
 int __ide_end_request(struct ata_device *drive, struct request *rq, int uptodate, int nr_secs)
@@ -446,7 +451,7 @@
 	}
 }
 
-static ide_startstop_t do_reset1(ide_drive_t *, int);		/* needed below */
+static ide_startstop_t do_reset1(struct ata_device *, int); /* needed below */
 
 /*
  * Poll the interface for completion every 50ms during an ATAPI drive reset
@@ -546,7 +551,7 @@
  * for it, we set a timer to poll at 50ms intervals.
  */
 
-static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
+static ide_startstop_t do_reset1(struct ata_device *drive, int do_not_try_atapi)
 {
 	unsigned int unit;
 	unsigned long flags;
@@ -614,7 +619,7 @@
 	return ide_started;
 }
 
-static inline u32 read_24 (ide_drive_t *drive)
+static inline u32 read_24(struct ata_device *drive)
 {
 	return  (IN_BYTE(IDE_HCYL_REG)<<16) |
 		(IN_BYTE(IDE_LCYL_REG)<<8) |
@@ -678,7 +683,7 @@
 /*
  * Error reporting, in human readable form (luxurious, but a memory hog).
  */
-byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
+byte ide_dump_status(struct ata_device *drive, const char *msg, byte stat)
 {
 	unsigned long flags;
 	byte err = 0;
@@ -770,7 +775,7 @@
  * condition by reading a sector's worth of data from the drive.  Of course,
  * this may not help if the drive is *waiting* for data from *us*.
  */
-static void try_to_flush_leftover_data (ide_drive_t *drive)
+static void try_to_flush_leftover_data(struct ata_device *drive)
 {
 	int i;
 
@@ -787,7 +792,7 @@
 /*
  * Take action based on the error returned by the drive.
  */
-ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, byte stat)
+ide_startstop_t ide_error(struct ata_device *drive, const char *msg, byte stat)
 {
 	struct request *rq;
 	byte err;
@@ -844,7 +849,7 @@
 /*
  * Issue a simple drive command.  The drive must be selected beforehand.
  */
-void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ata_handler_t handler)
+void ide_cmd(struct ata_device *drive, byte cmd, byte nsect, ata_handler_t handler)
 {
 	ide_set_handler (drive, handler, WAIT_CMD, NULL);
 	if (IDE_CONTROL_REG)
@@ -889,7 +894,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, struct ata_device *drive, byte good, byte bad, unsigned long timeout) {
 	byte stat;
 	int i;
 	unsigned long flags;
@@ -933,7 +938,7 @@
 /*
  * This initiates handling of a new I/O request.
  */
-static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
+static ide_startstop_t start_request(struct ata_device *drive, struct request *rq)
 {
 	sector_t block;
 	unsigned int minor = minor(rq->rq_dev);
@@ -1081,7 +1086,7 @@
 	return ide_stopped;
 }
 
-ide_startstop_t restart_request(ide_drive_t *drive)
+ide_startstop_t restart_request(struct ata_device *drive)
 {
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 	unsigned long flags;
@@ -1100,7 +1105,7 @@
  * This is used by a drive to give excess bandwidth back to the hwgroup by
  * sleeping for timeout jiffies.
  */
-void ide_stall_queue(ide_drive_t *drive, unsigned long timeout)
+void ide_stall_queue(struct ata_device *drive, unsigned long timeout)
 {
 	if (timeout > WAIT_WORSTCASE)
 		timeout = WAIT_WORSTCASE;
@@ -1681,10 +1686,10 @@
 }
 
 /*
- * get_info_ptr() returns the (ide_drive_t *) for a given device number.
+ * get_info_ptr() returns the (struct ata_device *) for a given device number.
  * It returns NULL if the given device number does not match any present drives.
  */
-ide_drive_t *get_info_ptr(kdev_t i_rdev)
+struct ata_device *get_info_ptr(kdev_t i_rdev)
 {
 	unsigned int major = major(i_rdev);
 	int h;
@@ -2012,25 +2017,13 @@
 	if (ch->straight8) {
 		release_region(ch->io_ports[IDE_DATA_OFFSET], 8);
 	} else {
-		if (ch->io_ports[IDE_DATA_OFFSET])
-			release_region(ch->io_ports[IDE_DATA_OFFSET], 1);
-		if (ch->io_ports[IDE_ERROR_OFFSET])
-			release_region(ch->io_ports[IDE_ERROR_OFFSET], 1);
-		if (ch->io_ports[IDE_NSECTOR_OFFSET])
-			release_region(ch->io_ports[IDE_NSECTOR_OFFSET], 1);
-		if (ch->io_ports[IDE_SECTOR_OFFSET])
-			release_region(ch->io_ports[IDE_SECTOR_OFFSET], 1);
-		if (ch->io_ports[IDE_LCYL_OFFSET])
-			release_region(ch->io_ports[IDE_LCYL_OFFSET], 1);
-		if (ch->io_ports[IDE_HCYL_OFFSET])
-			release_region(ch->io_ports[IDE_HCYL_OFFSET], 1);
-		if (ch->io_ports[IDE_SELECT_OFFSET])
-			release_region(ch->io_ports[IDE_SELECT_OFFSET], 1);
-		if (ch->io_ports[IDE_STATUS_OFFSET])
-			release_region(ch->io_ports[IDE_STATUS_OFFSET], 1);
+		for (i = 0; i < 8; i++)
+			if (ch->io_ports[i])
+				release_region(ch->io_ports[i], 1);
 	}
 	if (ch->io_ports[IDE_CONTROL_OFFSET])
 		release_region(ch->io_ports[IDE_CONTROL_OFFSET], 1);
+/* FIXME: check if we can remove this ifdef */
 #if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
 	if (ch->io_ports[IDE_IRQ_OFFSET])
 		release_region(ch->io_ports[IDE_IRQ_OFFSET], 1);
@@ -2129,7 +2122,6 @@
 	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;
@@ -2172,24 +2164,18 @@
 	int i;
 
 	for (i = 0; i < IDE_NR_PORTS; i++) {
-		if (offsets[i] == -1) {
-			switch(i) {
-				case IDE_CONTROL_OFFSET:
-					hw->io_ports[i] = ctrl;
-					break;
-#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
-				case IDE_IRQ_OFFSET:
-					hw->io_ports[i] = intr;
-					break;
-#endif
-				default:
-					hw->io_ports[i] = 0;
-					break;
-			}
-		} else {
+		if (offsets[i] != -1)
 			hw->io_ports[i] = base + offsets[i];
-		}
+		else
+			hw->io_ports[i] = 0;
 	}
+	if (offsets[IDE_CONTROL_OFFSET] == -1)
+		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl;
+/* FIMXE: check if we can remove this ifdef */
+#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
+	if (offsets[IDE_IRQ_OFFSET] == -1)
+		hw->io_ports[IDE_IRQ_OFFSET] = intr;
+#endif
 	hw->irq = irq;
 	hw->dma = NO_DMA;
 	hw->ack_intr = ack_intr;
@@ -2261,7 +2247,7 @@
 	return ide_register_hw(&hw, NULL);
 }
 
-void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
+void ide_add_setting(struct ata_device *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set)
 {
 	ide_settings_t **p = &drive->settings;
 	ide_settings_t *setting = NULL;
@@ -2288,7 +2274,7 @@
 		kfree(setting);
 }
 
-void ide_remove_setting (ide_drive_t *drive, char *name)
+void ide_remove_setting(struct ata_device *drive, char *name)
 {
 	ide_settings_t **p = &drive->settings, *setting;
 
@@ -2301,7 +2287,7 @@
 	kfree(setting);
 }
 
-static void auto_remove_settings (ide_drive_t *drive)
+static void auto_remove_settings(struct ata_device *drive)
 {
 	ide_settings_t *setting;
 repeat:
@@ -2315,10 +2301,10 @@
 	}
 }
 
-int ide_read_setting (ide_drive_t *drive, ide_settings_t *setting)
+int ide_read_setting(struct ata_device *drive, ide_settings_t *setting)
 {
-	int		val = -EINVAL;
-	unsigned long	flags;
+	int val = -EINVAL;
+	unsigned long flags;
 
 	if ((setting->rw & SETTING_READ)) {
 		spin_lock_irqsave(&ide_lock, flags);
@@ -2339,7 +2325,7 @@
 	return val;
 }
 
-int ide_spin_wait_hwgroup (ide_drive_t *drive)
+int ide_spin_wait_hwgroup(struct ata_device *drive)
 {
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 	unsigned long timeout = jiffies + (3 * HZ);
@@ -2367,7 +2353,7 @@
  * to the driver to change settings, and then wait on a semaphore for completion.
  * The current scheme of polling is kludgey, though safe enough.
  */
-int ide_write_setting (ide_drive_t *drive, ide_settings_t *setting, int val)
+int ide_write_setting(struct ata_device *drive, ide_settings_t *setting, int val)
 {
 	int i;
 	u32 *p;
@@ -2412,7 +2398,7 @@
 	return 0;
 }
 
-static int set_using_dma(ide_drive_t *drive, int arg)
+static int set_using_dma(struct ata_device *drive, int arg)
 {
 	if (!drive->driver)
 		return -EPERM;
@@ -2423,7 +2409,7 @@
 	return 0;
 }
 
-static int set_pio_mode(ide_drive_t *drive, int arg)
+static int set_pio_mode(struct ata_device *drive, int arg)
 {
 	struct request rq;
 
@@ -2441,7 +2427,7 @@
 	return 0;
 }
 
-void ide_add_generic_settings (ide_drive_t *drive)
+void ide_add_generic_settings(struct ata_device *drive)
 {
 /*			drive	setting name		read/write access				read ioctl		write ioctl		data type	min	max				mul_factor	div_factor	data pointer			set function */
 	ide_add_setting(drive,	"io_32bit",		drive->channel->no_io_32bit ? SETTING_READ : SETTING_RW,	HDIO_GET_32BIT,		HDIO_SET_32BIT,		TYPE_BYTE,	0,	1 + (SUPPORT_VLB_SYNC << 1),	1,		1,		&drive->channel->io_32bit,		set_io_32bit);
@@ -2476,7 +2462,7 @@
 static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	int err = 0, major, minor;
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	struct request rq;
 	kdev_t dev;
 	ide_settings_t *setting;
@@ -2630,7 +2616,7 @@
 
 static int ide_check_media_change (kdev_t i_rdev)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	int res = 0; /* not changed */
 
 	drive = get_info_ptr(i_rdev);
@@ -2828,7 +2814,7 @@
 {
 	int i, vals[3];
 	struct ata_channel *hwif;
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	unsigned int hw, unit;
 	const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
 	const char max_hwif  = '0' + (MAX_HWIFS - 1);
@@ -3144,7 +3130,7 @@
 /*
  * 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)
+struct ata_device *ide_scan_devices(byte type, const char *name, struct ata_operations *driver, int n)
 {
 	unsigned int unit, index, i;
 
@@ -3171,7 +3157,7 @@
 /*
  * This is in fact registering a drive not a driver.
  */
-int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *driver)
+int ide_register_subdriver(struct ata_device *drive, struct ata_operations *driver)
 {
 	unsigned long flags;
 
@@ -3204,7 +3190,7 @@
 			drive->channel->udma(ide_dma_off_quietly, drive, NULL);
 			drive->channel->udma(ide_dma_check, drive, NULL);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-			drive->channel->udma(ide_dma_queued_on, drive, NULL);
+			udma_tcq_enable(drive, 1);
 #endif
 		}
 
@@ -3238,7 +3224,7 @@
  *
  * FIXME: Check whatever we maybe don't call it twice!.
  */
-int ide_unregister_subdriver(ide_drive_t *drive)
+int ide_unregister_subdriver(struct ata_device *drive)
 {
 	unsigned long flags;
 
diff -urN linux-2.5.13/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.13/drivers/ide/ide-cd.c	2002-05-03 02:22:51.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-05-04 04:27:35.000000000 +0200
@@ -2652,7 +2652,7 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (drive->using_dma)
-		(void) drive->channel->udma(ide_dma_verbose, drive, NULL);
+		udma_print(drive);
 #endif
 	printk("\n");
 
diff -urN linux-2.5.13/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.13/drivers/ide/ide-disk.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-05-04 05:54:14.000000000 +0200
@@ -89,7 +89,7 @@
 	return 0;	/* lba_capacity value may be bad */
 }
 
-static u8 get_command(ide_drive_t *drive, int cmd)
+static u8 get_command(struct ata_device *drive, int cmd)
 {
 	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
 
@@ -345,7 +345,7 @@
 	return chs_do_request(drive, rq, block);
 }
 
-static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
+static int idedisk_open (struct inode *inode, struct file *filp, struct ata_device *drive)
 {
 	MOD_INC_USE_COUNT;
 	if (drive->removable && drive->usage == 1) {
@@ -370,7 +370,7 @@
 	return 0;
 }
 
-static int idedisk_flushcache(ide_drive_t *drive)
+static int idedisk_flushcache(struct ata_device *drive)
 {
 	struct ata_taskfile args;
 
@@ -386,7 +386,7 @@
 	return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
+static void idedisk_release (struct inode *inode, struct file *filp, struct ata_device *drive)
 {
 	if (drive->removable && !drive->usage) {
 		struct ata_taskfile args;
@@ -408,7 +408,7 @@
 	MOD_DEC_USE_COUNT;
 }
 
-static int idedisk_check_media_change (ide_drive_t *drive)
+static int idedisk_check_media_change(struct ata_device *drive)
 {
 	/* if removable, always assume it was changed */
 	return drive->removable;
@@ -474,7 +474,7 @@
 	return IS_PDC4030_DRIVE ? ide_stopped : ide_started;
 }
 
-static void idedisk_pre_reset (ide_drive_t *drive)
+static void idedisk_pre_reset(struct ata_device *drive)
 {
 	int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;
 
@@ -490,7 +490,7 @@
 
 #ifdef CONFIG_PROC_FS
 
-static int smart_enable(ide_drive_t *drive)
+static int smart_enable(struct ata_device *drive)
 {
 	struct ata_taskfile args;
 
@@ -504,7 +504,7 @@
 	return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static int get_smart_values(ide_drive_t *drive, u8 *buf)
+static int get_smart_values(struct ata_device *drive, u8 *buf)
 {
 	struct ata_taskfile args;
 
@@ -521,7 +521,7 @@
 	return ide_raw_taskfile(drive, &args, buf);
 }
 
-static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
+static int get_smart_thresholds(struct ata_device *drive, u8 *buf)
 {
 	struct ata_taskfile args;
 
@@ -541,7 +541,7 @@
 static int proc_idedisk_read_cache
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
+	struct ata_device *drive = (struct ata_device *) data;
 	char		*out = page;
 	int		len;
 
@@ -555,7 +555,7 @@
 static int proc_idedisk_read_smart_thresholds
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	ide_drive_t	*drive = (ide_drive_t *)data;
+	struct ata_device *drive = (struct ata_device *)data;
 	int		len = 0, i = 0;
 
 	if (!get_smart_thresholds(drive, page)) {
@@ -574,8 +574,8 @@
 static int proc_idedisk_read_smart_values
 	(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	ide_drive_t	*drive = (ide_drive_t *)data;
-	int		len = 0, i = 0;
+	struct ata_device *drive = (struct ata_device *)data;
+	int len = 0, i = 0;
 
 	if (!get_smart_values(drive, page)) {
 		unsigned short *val = (unsigned short *) page;
@@ -594,7 +594,7 @@
 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;
+	struct ata_device *drive = (struct ata_device *) data;
 	char		*out = page;
 	int		len, cmds, i;
 	unsigned long	flags;
@@ -658,7 +658,7 @@
  * This is tightly woven into the driver->special can not touch.
  * DON'T do it again until a total personality rewrite is committed.
  */
-static int set_multcount(ide_drive_t *drive, int arg)
+static int set_multcount(struct ata_device *drive, int arg)
 {
 	struct request rq;
 
@@ -670,12 +670,12 @@
 	drive->mult_req = arg;
 	drive->special_cmd |= ATA_SPECIAL_MMODE;
 
-	ide_do_drive_cmd (drive, &rq, ide_wait);
+	ide_do_drive_cmd(drive, &rq, ide_wait);
 
 	return (drive->mult_count == arg) ? 0 : -EIO;
 }
 
-static int set_nowerr(ide_drive_t *drive, int arg)
+static int set_nowerr(struct ata_device *drive, int arg)
 {
 	if (ide_spin_wait_hwgroup(drive))
 		return -EBUSY;
@@ -686,7 +686,7 @@
 	return 0;
 }
 
-static int write_cache(ide_drive_t *drive, int arg)
+static int write_cache(struct ata_device *drive, int arg)
 {
 	struct ata_taskfile args;
 
@@ -704,7 +704,7 @@
 	return 0;
 }
 
-static int idedisk_standby(ide_drive_t *drive)
+static int idedisk_standby(struct ata_device *drive)
 {
 	struct ata_taskfile args;
 
@@ -715,7 +715,7 @@
 	return ide_raw_taskfile(drive, &args, NULL);
 }
 
-static int set_acoustic(ide_drive_t *drive, int arg)
+static int set_acoustic(struct ata_device *drive, int arg)
 {
 	struct ata_taskfile args;
 
@@ -732,7 +732,7 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDE_TCQ
-static int set_using_tcq(ide_drive_t *drive, int arg)
+static int set_using_tcq(struct ata_device *drive, int arg)
 {
 	if (!drive->driver)
 		return -EPERM;
@@ -750,14 +750,14 @@
 			drive->queue_depth = drive->id->queue_depth + 1;
 	}
 
-	if (drive->channel->udma(arg ? ide_dma_queued_on : ide_dma_queued_off, drive, NULL))
+	if (udma_tcq_enable(drive, arg))
 		return -EIO;
 
 	return 0;
 }
 #endif
 
-static int probe_lba_addressing (ide_drive_t *drive, int arg)
+static int probe_lba_addressing(struct ata_device *drive, int arg)
 {
 	drive->addressing =  0;
 
@@ -768,12 +768,12 @@
 	return 0;
 }
 
-static int set_lba_addressing (ide_drive_t *drive, int arg)
+static int set_lba_addressing(struct ata_device *drive, int arg)
 {
 	return (probe_lba_addressing(drive, arg));
 }
 
-static void idedisk_add_settings(ide_drive_t *drive)
+static void idedisk_add_settings(struct ata_device *drive)
 {
 	struct hd_driveid *id = drive->id;
 
@@ -795,7 +795,7 @@
 
 static int idedisk_suspend(struct device *dev, u32 state, u32 level)
 {
-	ide_drive_t *drive = dev->driver_data;
+	struct ata_device *drive = dev->driver_data;
 
 	/* I hope that every freeze operations from the upper levels have
 	 * already been done...
@@ -822,7 +822,7 @@
 
 static int idedisk_resume(struct device *dev, u32 level)
 {
-	ide_drive_t *drive = dev->driver_data;
+	struct ata_device *drive = dev->driver_data;
 
 	if (level != RESUME_RESTORE_STATE)
 		return 0;
@@ -916,7 +916,7 @@
  * Sets maximum virtual LBA address of the drive.
  * Returns new maximum virtual LBA address (> 0) or 0 on failure.
  */
-static sector_t set_max_address(ide_drive_t *drive, sector_t addr_req)
+static sector_t set_max_address(struct ata_device *drive, sector_t addr_req)
 {
 	struct ata_taskfile args;
 	sector_t addr_set = 0;
@@ -945,7 +945,7 @@
 	return addr_set;
 }
 
-static u64 set_max_address_ext(ide_drive_t *drive, u64 addr_req)
+static u64 set_max_address_ext(struct ata_device *drive, u64 addr_req)
 {
 	struct ata_taskfile args;
 	u64 addr_set = 0;
@@ -1177,7 +1177,7 @@
 	       drive->bios_cyl, drive->bios_head, drive->bios_sect);
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (drive->using_dma)
-		(void) drive->channel->udma(ide_dma_verbose, drive, NULL);
+		udma_print(drive);
 #endif
 	printk("\n");
 
@@ -1213,7 +1213,7 @@
 	probe_lba_addressing(drive, 1);
 }
 
-static int idedisk_cleanup(ide_drive_t *drive)
+static int idedisk_cleanup(struct ata_device *drive)
 {
 	if (!drive)
 	    return 0;
@@ -1250,7 +1250,7 @@
 
 static void __exit idedisk_exit (void)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	int failed = 0;
 
 	while ((drive = ide_scan_devices(ATA_DISK, "ide-disk", &idedisk_driver, failed)) != NULL) {
@@ -1267,9 +1267,9 @@
 	}
 }
 
-int idedisk_init (void)
+int idedisk_init(void)
 {
-	ide_drive_t *drive;
+	struct ata_device *drive;
 	int failed = 0;
 
 	MOD_INC_USE_COUNT;
diff -urN linux-2.5.13/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.13/drivers/ide/ide-dma.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide-dma.c	2002-05-04 06:00:00.000000000 +0200
@@ -1,4 +1,5 @@
-/*
+/**** vi:set ts=8 sts=8 sw=8:************************************************
+ *
  *  Copyright (c) 1999-2000  Andre Hedrick <andre@linux-ide.org>
  *  Copyright (c) 1995-1998  Mark Lord
  *
@@ -63,12 +64,12 @@
  *
  * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports.
  *
- * check_drive_lists(ide_drive_t *drive, int good_bad)
- *
  * ATA-66/100 and recovery functions, I forgot the rest......
  */
 
 #include <linux/config.h>
+#define __NO_VERSION__
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
@@ -192,11 +193,11 @@
 #endif
 
 /*
- * dma_intr() is the handler for disk read/write DMA interrupts
+ * This is the handler for disk read/write DMA interrupts.
  */
 ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
 {
-	byte stat, dma_stat;
+	u8 stat, dma_stat;
 
 	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
 	if (OK_STAT(stat = GET_STAT(),DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
@@ -204,7 +205,7 @@
 			__ide_end_request(drive, rq, 1, rq->nr_sectors);
 			return ide_stopped;
 		}
-		printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
+		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
 		       drive->name, dma_stat);
 	}
 	return ide_error(drive, "dma_intr", stat);
@@ -270,106 +271,11 @@
 }
 
 /*
- * This prepares a dma request.  Returns 0 if all went okay, returns 1
- * otherwise.  May also be invoked from trm290.c
- */
-int ide_build_dmatable(struct ata_device *drive, ide_dma_action_t func)
-{
-	struct ata_channel *ch = drive->channel;
-	unsigned int *table = ch->dmatable_cpu;
-#ifdef CONFIG_BLK_DEV_TRM290
-	unsigned int is_trm290_chipset = (ch->chipset == ide_trm290);
-#else
-	const int is_trm290_chipset = 0;
-#endif
-	unsigned int count = 0;
-	int i;
-	struct scatterlist *sg;
-
-	ch->sg_nents = i = build_sglist(ch, HWGROUP(drive)->rq);
-	if (!i)
-		return 0;
-
-	sg = ch->sg_table;
-	while (i) {
-		u32 cur_addr;
-		u32 cur_len;
-
-		cur_addr = sg_dma_address(sg);
-		cur_len = sg_dma_len(sg);
-
-		/*
-		 * Fill in the dma table, without crossing any 64kB boundaries.
-		 * Most hardware requires 16-bit alignment of all blocks,
-		 * but the trm290 requires 32-bit alignment.
-		 */
-
-		while (cur_len) {
-			u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
-
-			if (count++ >= PRD_ENTRIES) {
-				printk("ide-dma: count %d, sg_nents %d, cur_len %d, cur_addr %u\n",
-						count, ch->sg_nents, cur_len, cur_addr);
-				BUG();
-			}
-
-			if (bcount > cur_len)
-				bcount = cur_len;
-			*table++ = cpu_to_le32(cur_addr);
-			xcount = bcount & 0xffff;
-			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
-			 * the 64KB entry into two 32KB entries instead.
-			 */
-				if (count++ >= PRD_ENTRIES) {
-					pci_unmap_sg(ch->pci_dev, sg,
-						     ch->sg_nents,
-						     ch->sg_dma_direction);
-					return 0;
-				}
-
-				*table++ = cpu_to_le32(0x8000);
-				*table++ = cpu_to_le32(cur_addr + 0x8000);
-				xcount = 0x8000;
-			}
-			*table++ = cpu_to_le32(xcount);
-			cur_addr += bcount;
-			cur_len -= bcount;
-		}
-
-		sg++;
-		i--;
-	}
-
-	if (!count)
-		printk("%s: empty DMA table?\n", drive->name);
-	else if (!is_trm290_chipset)
-		*--table |= cpu_to_le32(0x80000000);
-
-	return count;
-}
-
-/* Teardown mappings after DMA has completed.  */
-void ide_destroy_dmatable (ide_drive_t *drive)
-{
-	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, sg, nents, drive->channel->sg_dma_direction);
-}
-
-/*
  *  For both Blacklisted and Whitelisted drives.
  *  This is setup to be called as an extern for future support
  *  to other special driver code.
  */
-int check_drive_lists (ide_drive_t *drive, int good_bad)
+int check_drive_lists(struct ata_device *drive, int good_bad)
 {
 	struct hd_driveid *id = drive->id;
 
@@ -407,80 +313,43 @@
 	return 0;
 }
 
-int report_drive_dmaing (ide_drive_t *drive)
-{
-	struct hd_driveid *id = drive->id;
-
-	if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
-	    (id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
-		if ((id->dma_ultra >> 15) & 1) {
-			printk(", UDMA(mode 7)");	/* UDMA BIOS-enabled! */
-		} else {
-			printk(", UDMA(133)");	/* UDMA BIOS-enabled! */
-		}
-	} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
-	  	  (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) {
-			printk(", UDMA(66)");	/* UDMA BIOS-enabled! */
-		} else {
-			printk(", UDMA(44)");	/* UDMA BIOS-enabled! */
-		}
-	} else if ((id->field_valid & 4) &&
-		   (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
-		if ((id->dma_ultra >> 10) & 1) {
-			printk(", UDMA(33)");	/* UDMA BIOS-enabled! */
-		} else if ((id->dma_ultra >> 9) & 1) {
-			printk(", UDMA(25)");	/* UDMA BIOS-enabled! */
-		} else {
-			printk(", UDMA(16)");	/* UDMA BIOS-enabled! */
-		}
-	} else if (id->field_valid & 4) {
-		printk(", (U)DMA");	/* Can be BIOS-enabled! */
-	} else {
-		printk(", DMA");
-	}
-	return 1;
-}
-
-static int config_drive_for_dma (ide_drive_t *drive)
+static int config_drive_for_dma(struct ata_device *drive)
 {
 	int config_allows_dma = 1;
 	struct hd_driveid *id = drive->id;
-	struct ata_channel *hwif = drive->channel;
+	struct ata_channel *ch = drive->channel;
 
 #ifdef CONFIG_IDEDMA_ONLYDISK
 	if (drive->type != ATA_DISK)
 		config_allows_dma = 0;
 #endif
 
-	if (id && (id->capability & 1) && hwif->autodma && config_allows_dma) {
+	if (id && (id->capability & 1) && ch->autodma && config_allows_dma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL))
-			return hwif->udma(ide_dma_off, drive, NULL);
+			return ch->udma(ide_dma_off, drive, NULL);
 
 		/* Enable DMA on any drive that has UltraDMA (mode 6/7/?) enabled */
 		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
 			if ((id->dma_ultra & (id->dma_ultra >> 14) & 2))
-				return hwif->udma(ide_dma_on, drive, NULL);
+				return ch->udma(ide_dma_on, drive, NULL);
 		/* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */
 		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
 			if ((id->dma_ultra & (id->dma_ultra >> 11) & 7))
-				return hwif->udma(ide_dma_on, drive, NULL);
+				return ch->udma(ide_dma_on, drive, NULL);
 		/* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */
 		if (id->field_valid & 4)	/* UltraDMA */
 			if ((id->dma_ultra & (id->dma_ultra >> 8) & 7))
-				return hwif->udma(ide_dma_on, drive, NULL);
+				return ch->udma(ide_dma_on, drive, NULL);
 		/* Enable DMA on any drive that has mode2 DMA (multi or single) enabled */
 		if (id->field_valid & 2)	/* regular DMA */
 			if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404)
-				return hwif->udma(ide_dma_on, drive, NULL);
+				return ch->udma(ide_dma_on, drive, NULL);
 		/* Consult the list of known "good" drives */
 		if (ide_dmaproc(ide_dma_good_drive, drive, NULL))
-			return hwif->udma(ide_dma_on, drive, NULL);
+			return ch->udma(ide_dma_on, drive, NULL);
 	}
-	return hwif->udma(ide_dma_off_quietly, drive, NULL);
+	return ch->udma(ide_dma_off_quietly, drive, NULL);
 }
 
 /*
@@ -508,7 +377,7 @@
 	return 0;
 }
 
-static void ide_toggle_bounce(ide_drive_t *drive, int on)
+static void ide_toggle_bounce(struct ata_device *drive, int on)
 {
 	u64 addr = BLK_BOUNCE_HIGH;
 
@@ -522,26 +391,20 @@
 	blk_queue_bounce_limit(&drive->queue, addr);
 }
 
-int ide_start_dma(ide_dma_action_t func, struct ata_device *drive)
+int ata_start_dma(struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
 	unsigned int reading = 0;
 
-	if (rq_data_dir(HWGROUP(drive)->rq) == READ)
+	if (rq_data_dir(rq) == READ)
 		reading = 1 << 3;
 
-	/* active tuning based on IO direction */
-	if (hwif->rwproc)
-		hwif->rwproc(drive, func);
-
-	/*
-	 * try PIO instead of DMA
-	 */
-	if (!ide_build_dmatable(drive, func))
+	/* try PIO instead of DMA */
+	if (!udma_new_table(ch, rq))
 		return 1;
 
-	outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
+	outl(ch->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;
@@ -566,11 +429,11 @@
  */
 int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
-	byte unit = (drive->select.b.unit & 0x01);
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	u8 unit = (drive->select.b.unit & 0x01);
 	unsigned int reading = 0, set_high = 1;
-	byte dma_stat;
+	u8 dma_stat;
 
 	switch (func) {
 		case ide_dma_off:
@@ -579,7 +442,7 @@
 			set_high = 0;
 			outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ
-			hwif->udma(ide_dma_queued_off, drive, rq);
+			udma_tcq_enable(drive, 0);
 #endif
 		case ide_dma_on:
 			ide_toggle_bounce(drive, set_high);
@@ -587,7 +450,7 @@
 			if (drive->using_dma) {
 				outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-				hwif->udma(ide_dma_queued_on, drive, rq);
+				udma_tcq_enable(drive, 1);
 #endif
 			}
 			return 0;
@@ -596,7 +459,7 @@
 		case ide_dma_read:
 			reading = 1 << 3;
 		case ide_dma_write:
-			if (ide_start_dma(func, drive))
+			if (ata_start_dma(drive, rq))
 				return 1;
 
 			if (drive->type != ATA_DISK)
@@ -613,14 +476,6 @@
 				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			}
 			return drive->channel->udma(ide_dma_begin, drive, NULL);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ
-		case ide_dma_queued_on:
-		case ide_dma_queued_off:
-		case ide_dma_read_queued:
-		case ide_dma_write_queued:
-		case ide_dma_queued_start:
-			return ide_tcq_dmaproc(func, drive, rq);
-#endif
 		case ide_dma_begin:
 			/* Note that this is done *after* the cmd has
 			 * been issued to the drive, as per the BM-IDE spec.
@@ -634,13 +489,13 @@
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
 			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 */
+			udma_destroy_table(ch);	/* purge DMA mappings */
 			return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
 		case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
 			dma_stat = inb(dma_base+2);
 #if 0  /* do not set unless you know what you are doing */
 			if (dma_stat & 4) {
-				byte stat = GET_STAT();
+				u8 stat = GET_STAT();
 				outb(dma_base+2, dma_stat & 0xE4);
 			}
 #endif
@@ -648,8 +503,6 @@
 		case ide_dma_bad_drive:
 		case ide_dma_good_drive:
 			return check_drive_lists(drive, (func == ide_dma_good_drive));
-		case ide_dma_verbose:
-			return report_drive_dmaing(drive);
 		case ide_dma_timeout:
 			printk(KERN_ERR "%s: DMA timeout occured!\n", __FUNCTION__);
 			return 1;
@@ -666,61 +519,61 @@
 /*
  * Needed for allowing full modular support of ide-driver
  */
-void ide_release_dma(struct ata_channel *hwif)
+void ide_release_dma(struct ata_channel *ch)
 {
-	if (!hwif->dma_base)
+	if (!ch->dma_base)
 		return;
 
-	if (hwif->dmatable_cpu) {
-		pci_free_consistent(hwif->pci_dev,
+	if (ch->dmatable_cpu) {
+		pci_free_consistent(ch->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);
-	hwif->dma_base = 0;
+				    ch->dmatable_cpu,
+				    ch->dmatable_dma);
+		ch->dmatable_cpu = NULL;
+	}
+	if (ch->sg_table) {
+		kfree(ch->sg_table);
+		ch->sg_table = NULL;
+	}
+	if ((ch->dma_extra) && (ch->unit == 0))
+		release_region((ch->dma_base + 16), ch->dma_extra);
+	release_region(ch->dma_base, 8);
+	ch->dma_base = 0;
 }
 
 /*
  * This can be called for a dynamically installed interface. Don't __init it
  */
-void ide_setup_dma(struct ata_channel *hwif, unsigned long dma_base, unsigned int num_ports)
+void ide_setup_dma(struct ata_channel *ch, unsigned long dma_base, unsigned int num_ports)
 {
-	printk("    %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, dma_base, dma_base + num_ports - 1);
+	printk("    %s: BM-DMA at 0x%04lx-0x%04lx", ch->name, dma_base, dma_base + num_ports - 1);
 	if (check_region(dma_base, num_ports)) {
 		printk(" -- ERROR, PORT ADDRESSES ALREADY IN USE\n");
 		return;
 	}
-	request_region(dma_base, num_ports, hwif->name);
-	hwif->dma_base = dma_base;
-	hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
+	request_region(dma_base, num_ports, ch->name);
+	ch->dma_base = dma_base;
+	ch->dmatable_cpu = pci_alloc_consistent(ch->pci_dev,
 						  PRD_ENTRIES * PRD_BYTES,
-						  &hwif->dmatable_dma);
-	if (hwif->dmatable_cpu == NULL)
+						  &ch->dmatable_dma);
+	if (ch->dmatable_cpu == NULL)
 		goto dma_alloc_failure;
 
-	hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
+	ch->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);
+	if (ch->sg_table == NULL) {
+		pci_free_consistent(ch->pci_dev, PRD_ENTRIES * PRD_BYTES,
+				    ch->dmatable_cpu, ch->dmatable_dma);
 		goto dma_alloc_failure;
 	}
 
-	hwif->udma = ide_dmaproc;
+	ch->udma = ide_dmaproc;
 
-	if (hwif->chipset != ide_trm290) {
-		byte dma_stat = inb(dma_base+2);
+	if (ch->chipset != ide_trm290) {
+		u8 dma_stat = inb(dma_base+2);
 		printk(", BIOS settings: %s:%s, %s:%s",
-		       hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
-		       hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
+		       ch->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio",
+		       ch->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio");
 	}
 	printk("\n");
 	return;
@@ -728,3 +581,141 @@
 dma_alloc_failure:
 	printk(" -- ERROR, UNABLE TO ALLOCATE DMA TABLES\n");
 }
+
+/****************************************************************************
+ * UDMA function which should have architecture specific counterparts where
+ * neccessary.
+ */
+
+/*
+ * This prepares a dma request.  Returns 0 if all went okay, returns 1
+ * otherwise.  May also be invoked from trm290.c
+ */
+int udma_new_table(struct ata_channel *ch, struct request *rq)
+{
+	unsigned int *table = ch->dmatable_cpu;
+#ifdef CONFIG_BLK_DEV_TRM290
+	unsigned int is_trm290_chipset = (ch->chipset == ide_trm290);
+#else
+	const int is_trm290_chipset = 0;
+#endif
+	unsigned int count = 0;
+	int i;
+	struct scatterlist *sg;
+
+	ch->sg_nents = i = build_sglist(ch, rq);
+	if (!i)
+		return 0;
+
+	sg = ch->sg_table;
+	while (i) {
+		u32 cur_addr;
+		u32 cur_len;
+
+		cur_addr = sg_dma_address(sg);
+		cur_len = sg_dma_len(sg);
+
+		/*
+		 * Fill in the dma table, without crossing any 64kB boundaries.
+		 * Most hardware requires 16-bit alignment of all blocks,
+		 * but the trm290 requires 32-bit alignment.
+		 */
+
+		while (cur_len) {
+			u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
+
+			if (count++ >= PRD_ENTRIES) {
+				printk("ide-dma: count %d, sg_nents %d, cur_len %d, cur_addr %u\n",
+						count, ch->sg_nents, cur_len, cur_addr);
+				BUG();
+			}
+
+			if (bcount > cur_len)
+				bcount = cur_len;
+			*table++ = cpu_to_le32(cur_addr);
+			xcount = bcount & 0xffff;
+			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
+			 * the 64KB entry into two 32KB entries instead.
+			 */
+				if (count++ >= PRD_ENTRIES) {
+					pci_unmap_sg(ch->pci_dev, sg,
+						     ch->sg_nents,
+						     ch->sg_dma_direction);
+					return 0;
+				}
+
+				*table++ = cpu_to_le32(0x8000);
+				*table++ = cpu_to_le32(cur_addr + 0x8000);
+				xcount = 0x8000;
+			}
+			*table++ = cpu_to_le32(xcount);
+			cur_addr += bcount;
+			cur_len -= bcount;
+		}
+
+		sg++;
+		i--;
+	}
+
+	if (!count)
+		printk(KERN_ERR "%s: empty DMA table?\n", ch->name);
+	else if (!is_trm290_chipset)
+		*--table |= cpu_to_le32(0x80000000);
+
+	return count;
+}
+
+/* Teardown mappings after DMA has completed.  */
+void udma_destroy_table(struct ata_channel *ch)
+{
+	pci_unmap_sg(ch->pci_dev, ch->sg_table, ch->sg_nents, ch->sg_dma_direction);
+}
+
+void udma_print(struct ata_device *drive)
+{
+#ifdef CONFIG_ARCH_ACORN
+	printk(", DMA");
+#else
+	struct hd_driveid *id = drive->id;
+	char *str = NULL;
+
+	if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
+	    (id->dma_ultra & (id->dma_ultra >> 14) & 3)) {
+		if ((id->dma_ultra >> 15) & 1)
+			str = ", UDMA(mode 7)";	/* UDMA BIOS-enabled! */
+		else
+			str = ", UDMA(133)";	/* UDMA BIOS-enabled! */
+	} else if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
+		  (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
+		if ((id->dma_ultra >> 13) & 1) {
+			str = ", UDMA(100)";	/* UDMA BIOS-enabled! */
+		} else if ((id->dma_ultra >> 12) & 1) {
+			str = ", UDMA(66)";	/* UDMA BIOS-enabled! */
+		} else {
+			str = ", UDMA(44)";	/* UDMA BIOS-enabled! */
+		}
+	} else if ((id->field_valid & 4) &&
+		   (id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
+		if ((id->dma_ultra >> 10) & 1) {
+			str = ", UDMA(33)";	/* UDMA BIOS-enabled! */
+		} else if ((id->dma_ultra >> 9) & 1) {
+			str = ", UDMA(25)";	/* UDMA BIOS-enabled! */
+		} else {
+			str = ", UDMA(16)";	/* UDMA BIOS-enabled! */
+		}
+	} else if (id->field_valid & 4)
+		str = ", (U)DMA";	/* Can be BIOS-enabled! */
+	else
+		str = ", DMA";
+
+	printk(str);
+#endif
+}
+
+EXPORT_SYMBOL(udma_print);
diff -urN linux-2.5.13/drivers/ide/ide-features.c linux/drivers/ide/ide-features.c
--- linux-2.5.13/drivers/ide/ide-features.c	2002-05-03 02:22:55.000000000 +0200
+++ linux/drivers/ide/ide-features.c	2002-05-03 18:03:00.000000000 +0200
@@ -44,29 +44,38 @@
  */
 char *ide_xfer_verbose (byte xfer_rate)
 {
-	switch(xfer_rate) {
-		case XFER_UDMA_7:	return("UDMA 7");
-		case XFER_UDMA_6:	return("UDMA 6");
-		case XFER_UDMA_5:	return("UDMA 5");
-		case XFER_UDMA_4:	return("UDMA 4");
-		case XFER_UDMA_3:	return("UDMA 3");
-		case XFER_UDMA_2:	return("UDMA 2");
-		case XFER_UDMA_1:	return("UDMA 1");
-		case XFER_UDMA_0:	return("UDMA 0");
-		case XFER_MW_DMA_2:	return("MW DMA 2");
-		case XFER_MW_DMA_1:	return("MW DMA 1");
-		case XFER_MW_DMA_0:	return("MW DMA 0");
-		case XFER_SW_DMA_2:	return("SW DMA 2");
-		case XFER_SW_DMA_1:	return("SW DMA 1");
-		case XFER_SW_DMA_0:	return("SW DMA 0");
-		case XFER_PIO_4:	return("PIO 4");
-		case XFER_PIO_3:	return("PIO 3");
-		case XFER_PIO_2:	return("PIO 2");
-		case XFER_PIO_1:	return("PIO 1");
-		case XFER_PIO_0:	return("PIO 0");
-		case XFER_PIO_SLOW:	return("PIO SLOW");
-		default:		return("XFER ERROR");
-	}
+	static struct ide_xfer_par {
+		byte rate;
+		char *name;
+	} xfer_verbose[] = {
+		{ XFER_UDMA_7,		"UDMA 7" },
+		{ XFER_UDMA_6,		"UDMA 6" },
+		{ XFER_UDMA_5,		"UDMA 5" },
+		{ XFER_UDMA_4,		"UDMA 4" },
+		{ XFER_UDMA_3,		"UDMA 3" },
+		{ XFER_UDMA_2,		"UDMA 2" },
+		{ XFER_UDMA_1,		"UDMA 1" },
+		{ XFER_UDMA_0,		"UDMA 0" },
+		{ XFER_MW_DMA_2,	"MW DMA 2" },
+		{ XFER_MW_DMA_1,	"MW DMA 1" },
+		{ XFER_MW_DMA_0,	"MW DMA 0" },
+		{ XFER_SW_DMA_2,	"SW DMA 2" },
+		{ XFER_SW_DMA_1,	"SW DMA 1" },
+		{ XFER_SW_DMA_0,	"SW DMA 0" },
+		{ XFER_PIO_4,		"PIO 4" },
+		{ XFER_PIO_3,		"PIO 3" },
+		{ XFER_PIO_2,		"PIO 2" },
+		{ XFER_PIO_1,		"PIO 1" },
+		{ XFER_PIO_0,		"PIO 0" },
+		{ XFER_PIO_SLOW,	"PIO SLOW" },
+	};
+
+	int i = 0;
+
+	for (; i < ARRAY_SIZE(xfer_verbose); i++)
+		if (xfer_verbose[i].rate == xfer_rate)
+			return xfer_verbose[i].name;
+	return "XFER ERROR";
 }
 
 byte ide_auto_reduce_xfer (ide_drive_t *drive)
diff -urN linux-2.5.13/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.13/drivers/ide/ide-pmac.c	2002-05-03 02:22:55.000000000 +0200
+++ linux/drivers/ide/ide-pmac.c	2002-05-04 04:59:34.000000000 +0200
@@ -1164,9 +1164,9 @@
 
 /* Teardown mappings after DMA has completed.  */
 static void
-pmac_ide_destroy_dmatable (ide_drive_t *drive, int ix)
+pmac_ide_destroy_dmatable(struct ata_channel *ch, int ix)
 {
-	struct pci_dev *dev = drive->channel->pci_dev;
+	struct pci_dev *dev = ch->pci_dev;
 	struct scatterlist *sg = pmac_ide[ix].sg_table;
 	int nents = pmac_ide[ix].sg_nents;
 
@@ -1367,10 +1367,6 @@
 		break;
 	case ide_dma_read:
 	case ide_dma_write:
-		/* this almost certainly isn't needed since we don't
-		   appear to have a rwproc */
-		if (drive->channel->rwproc)
-			drive->channel->rwproc(drive, func);
 		reading = (func == ide_dma_read);
 		if (!pmac_ide_build_dmatable(drive, rq, ix, !reading))
 			return 1;
@@ -1404,7 +1400,7 @@
 		drive->waiting_for_dma = 0;
 		dstat = in_le32(&dma->status);
 		out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
-		pmac_ide_destroy_dmatable(drive, ix);
+		pmac_ide_destroy_dmatable(drive->channel, ix);
 		/* verify good dma status */
 		return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
 	case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
@@ -1453,8 +1449,6 @@
 	case ide_dma_bad_drive:
 	case ide_dma_good_drive:
 		return check_drive_lists(drive, (func == ide_dma_good_drive));
-	case ide_dma_verbose:
-		return report_drive_dmaing(drive);
 	case ide_dma_retune:
 	case ide_dma_lostirq:
 	case ide_dma_timeout:
diff -urN linux-2.5.13/drivers/ide/ide-probe.c linux/drivers/ide/ide-probe.c
--- linux-2.5.13/drivers/ide/ide-probe.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide-probe.c	2002-05-03 18:03:00.000000000 +0200
@@ -448,7 +448,7 @@
  */
 static void channel_probe(struct ata_channel *ch)
 {
-	unsigned int unit;
+	unsigned int i;
 	unsigned long flags;
 	int error;
 
@@ -463,8 +463,8 @@
 	/*
 	 * 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];
+	for (i = 0; i < MAX_DRIVES; ++i) {
+		struct ata_device *drive = &ch->drives[i];
 
 		probe_for_drive(drive);
 
@@ -483,23 +483,8 @@
 		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);
-
+		for (i = 0; i < 8; i++)
+			error += !request_region(ch->io_ports[i], 1, ch->name);
 	}
 	if (ch->io_ports[IDE_CONTROL_OFFSET])
 		error += !request_region(ch->io_ports[IDE_CONTROL_OFFSET], 1, ch->name);
@@ -561,8 +546,8 @@
 	/*
 	 * Now setup the PIO transfer modes of the drives on this channel.
 	 */
-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		struct ata_device *drive = &ch->drives[unit];
+	for (i = 0; i < MAX_DRIVES; ++i) {
+		struct ata_device *drive = &ch->drives[i];
 
 		if (drive->present && (drive->autotune == 1)) {
 			if (drive->channel->tuneproc)
@@ -819,6 +804,16 @@
 		goto err_kmalloc_gd_part;
 	memset(gd->part, 0, ATA_MINORS * sizeof(struct hd_struct));
 
+	gd->de_arr = kmalloc (sizeof(*gd->de_arr) * MAX_DRIVES, GFP_KERNEL);
+	if (!gd->de_arr)
+		goto err_kmalloc_gd_de_arr;
+	memset(gd->de_arr, 0, sizeof(*gd->de_arr) * MAX_DRIVES);
+
+	gd->flags = kmalloc (sizeof(*gd->flags) * MAX_DRIVES, GFP_KERNEL);
+	if (!gd->flags)
+		goto err_kmalloc_gd_flags;
+	memset(gd->flags, 0, sizeof(*gd->flags) * MAX_DRIVES);
+
 	for (unit = 0; unit < MAX_DRIVES; ++unit)
 		ch->drives[unit].part = &gd->part[unit << PARTN_BITS];
 
diff -urN linux-2.5.13/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.13/drivers/ide/ide-taskfile.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-05-04 05:59:57.000000000 +0200
@@ -130,12 +130,12 @@
 }
 #endif
 
-static void ata_read_16(ide_drive_t *drive, void *buffer, unsigned int wcount)
+static void ata_read_16(struct ata_device *drive, void *buffer, unsigned int wcount)
 {
 	insw(IDE_DATA_REG, buffer, wcount<<1);
 }
 
-static void ata_write_16(ide_drive_t *drive, void *buffer, unsigned int wcount)
+static void ata_write_16(struct ata_device *drive, void *buffer, unsigned int wcount)
 {
 	outsw(IDE_DATA_REG, buffer, wcount<<1);
 }
@@ -143,7 +143,7 @@
 /*
  * This is used for most PIO data transfers *from* the device.
  */
-void ata_read(ide_drive_t *drive, void *buffer, unsigned int wcount)
+void ata_read(struct ata_device *drive, void *buffer, unsigned int wcount)
 {
 	int io_32bit;
 
@@ -178,7 +178,7 @@
 /*
  * This is used for most PIO data transfers *to* the device interface.
  */
-void ata_write(ide_drive_t *drive, void *buffer, unsigned int wcount)
+void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount)
 {
 	int io_32bit;
 
@@ -213,7 +213,7 @@
  * so if an odd bytecount is specified, be sure that there's at least one
  * extra byte allocated for the buffer.
  */
-void atapi_read(ide_drive_t *drive, void *buffer, unsigned int bytecount)
+void atapi_read(struct ata_device *drive, void *buffer, unsigned int bytecount)
 {
 	if (drive->channel->atapi_read) {
 		drive->channel->atapi_read(drive, buffer, bytecount);
@@ -233,7 +233,7 @@
 		insw(IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
 }
 
-void atapi_write(ide_drive_t *drive, void *buffer, unsigned int bytecount)
+void atapi_write(struct ata_device *drive, void *buffer, unsigned int bytecount)
 {
 	if (drive->channel->atapi_write) {
 		drive->channel->atapi_write(drive, buffer, bytecount);
@@ -256,7 +256,7 @@
 /*
  * Needed for PCI irq sharing
  */
-int drive_is_ready(ide_drive_t *drive)
+int drive_is_ready(struct ata_device *drive)
 {
 	byte stat = 0;
 	if (drive->waiting_for_dma)
@@ -290,7 +290,7 @@
  * Stuff the first sector(s) by implicitly calling the handler driectly
  * therafter.
  */
-void ata_poll_drive_ready(ide_drive_t *drive)
+void ata_poll_drive_ready(struct ata_device *drive)
 {
 	int i;
 
@@ -399,7 +399,7 @@
 	return ide_started;
 }
 
-ide_startstop_t ata_taskfile(ide_drive_t *drive,
+ide_startstop_t ata_taskfile(struct ata_device *drive,
 		struct ata_taskfile *args, struct request *rq)
 {
 	struct hd_driveid *id = drive->id;
@@ -456,39 +456,38 @@
 		if (args->prehandler != NULL)
 			return args->prehandler(drive, rq);
 	} else {
+		/*
+		 * FIXME: this is a gross hack, need to unify tcq dma proc and
+		 * regular dma proc -- basically split stuff that needs to act
+		 * on a request from things like ide_dma_check etc.
+		 */
 		ide_dma_action_t dma_act;
-		int tcq = 0;
 
 		if (!drive->using_dma)
 			return ide_started;
 
 		/* for dma commands we don't set the handler */
-		if (args->taskfile.command == WIN_WRITEDMA || args->taskfile.command == WIN_WRITEDMA_EXT)
+		if (args->taskfile.command == WIN_WRITEDMA
+		 || args->taskfile.command == WIN_WRITEDMA_EXT)
 			dma_act = ide_dma_write;
-		else if (args->taskfile.command == WIN_READDMA || args->taskfile.command == WIN_READDMA_EXT)
+		else if (args->taskfile.command == WIN_READDMA
+		      || args->taskfile.command == WIN_READDMA_EXT)
 			dma_act = ide_dma_read;
-		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT) {
-			tcq = 1;
-			dma_act = ide_dma_write_queued;
-		} else if (args->taskfile.command == WIN_READDMA_QUEUED || args->taskfile.command == WIN_READDMA_QUEUED_EXT) {
-			tcq = 1;
-			dma_act = ide_dma_read_queued;
-		} else {
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
+		      || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
+		      || args->taskfile.command == WIN_READDMA_QUEUED
+		      || args->taskfile.command == WIN_READDMA_QUEUED_EXT)
+			return udma_tcq_taskfile(drive, rq);
+#endif
+		else {
 			printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
 			return ide_stopped;
 		}
 
-		/*
-		 * FIXME: this is a gross hack, need to unify tcq dma proc and
-		 * regular dma proc -- basically split stuff that needs to act
-		 * on a request from things like ide_dma_check etc.
-		 */
-		if (tcq)
-			return drive->channel->udma(dma_act, drive, rq);
-		else {
-			if (drive->channel->udma(dma_act, drive, rq))
-				return ide_stopped;
-		}
+
+		if (drive->channel->udma(dma_act, drive, rq))
+			return ide_stopped;
 	}
 
 	return ide_started;
@@ -900,7 +899,7 @@
 	}
 }
 
-int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
+int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *args, byte *buf)
 {
 	struct request rq;
 
@@ -926,7 +925,7 @@
  * interface.
  */
 
-int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
+int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg)
 {
 	int err = 0;
 	u8 vals[4];
diff -urN linux-2.5.13/drivers/ide/Makefile linux/drivers/ide/Makefile
--- linux-2.5.13/drivers/ide/Makefile	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/Makefile	2002-05-04 06:02:26.000000000 +0200
@@ -10,7 +10,7 @@
 
 O_TARGET := idedriver.o
 
-export-objs		:= ide-taskfile.o ide.o ide-features.o ide-probe.o ataraid.o
+export-objs	:= ide-taskfile.o ide.o ide-features.o ide-probe.o ide-dma.o ataraid.o
 
 obj-y		:=
 obj-m		:=
diff -urN linux-2.5.13/drivers/ide/ns87415.c linux/drivers/ide/ns87415.c
--- linux-2.5.13/drivers/ide/ns87415.c	2002-05-03 02:22:48.000000000 +0200
+++ linux/drivers/ide/ns87415.c	2002-05-04 03:51:59.000000000 +0200
@@ -93,7 +93,7 @@
 			dma_stat = inb(hwif->dma_base+2);
 			outb(inb(hwif->dma_base)&~1, hwif->dma_base);	/* stop DMA */
 			outb(inb(hwif->dma_base)|6, hwif->dma_base);	/* from ERRATA: clear the INTR & ERROR bits */
-			ide_destroy_dmatable(drive);			/* and free any DMA resources */
+			udma_destroy_table(hwif);			/* and free any DMA resources */
 			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		case ide_dma_write:
 		case ide_dma_read:
diff -urN linux-2.5.13/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.13/drivers/ide/tcq.c	2002-05-04 06:07:15.000000000 +0200
+++ linux/drivers/ide/tcq.c	2002-05-04 05:25:59.000000000 +0200
@@ -215,6 +215,8 @@
 	return 0;
 }
 
+static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq);
+
 /*
  * 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)
@@ -296,7 +298,7 @@
 	 * interrupt to indicate end of transfer, release is not allowed
 	 */
 	TCQ_PRINTK("%s: starting command %x\n", __FUNCTION__, stat);
-	return drive->channel->udma(ide_dma_queued_start, drive, rq);
+	return udma_tcq_start(drive, rq);
 }
 
 static ide_startstop_t check_service(struct ata_device *drive)
@@ -483,11 +485,119 @@
 	return 0;
 }
 
+static int tcq_wait_dataphase(struct ata_device *drive)
+{
+	u8 stat;
+	int i;
+
+	while ((stat = GET_STAT()) & BUSY_STAT)
+		udelay(10);
+
+	if (OK_STAT(stat, READY_STAT | DRQ_STAT, drive->bad_wstat))
+		return 0;
+
+	i = 0;
+	udelay(1);
+	while (!OK_STAT(GET_STAT(), READY_STAT | DRQ_STAT, drive->bad_wstat)) {
+		if (unlikely(i++ > IDE_TCQ_WAIT))
+			return 1;
+
+		udelay(10);
+	}
+
+	return 0;
+}
+
+/****************************************************************************
+ * UDMA transfer handling functions.
+ */
+
+/*
+ * Invoked from a SERVICE interrupt, command etc already known.  Just need to
+ * start the dma engine for this tag.
+ */
+static ide_startstop_t udma_tcq_start(struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *ch = drive->channel;
+
+	TCQ_PRINTK("%s: setting up queued %d\n", __FUNCTION__, rq->tag);
+	if (!test_bit(IDE_BUSY, &ch->hwgroup->flags))
+		printk("queued_rw: IDE_BUSY not set\n");
+
+	if (tcq_wait_dataphase(drive))
+		return ide_stopped;
+
+	if (ata_start_dma(drive, rq))
+		return ide_stopped;
+
+	set_irq(drive, ide_dmaq_intr);
+	if (!ch->udma(ide_dma_begin, drive, rq))
+		return ide_started;
+
+	return ide_stopped;
+}
+
 /*
- * for now assume that command list is always as big as we need and don't
- * attempt to shrink it on tcq disable
+ * Start a queued command from scratch.
  */
-static int enable_queued(struct ata_device *drive, int on)
+ide_startstop_t udma_tcq_taskfile(struct ata_device *drive, struct request *rq)
+{
+	u8 stat;
+	u8 feat;
+
+	struct ata_taskfile *args = rq->special;
+
+	TCQ_PRINTK("%s: start tag %d\n", drive->name, rq->tag);
+
+	/*
+	 * set nIEN, tag start operation will enable again when
+	 * it is safe
+	 */
+	drive_ctl_nien(drive, 1);
+
+	OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
+
+	if (wait_altstat(drive, &stat, BUSY_STAT)) {
+		ide_dump_status(drive, "queued start", stat);
+		tcq_invalidate_queue(drive);
+		return ide_stopped;
+	}
+
+	drive_ctl_nien(drive, 0);
+
+	if (stat & ERR_STAT) {
+		ide_dump_status(drive, "tcq_start", stat);
+		return ide_stopped;
+	}
+
+	/*
+	 * drive released the bus, clear active tag and
+	 * check for service
+	 */
+	if ((feat = GET_FEAT()) & NSEC_REL) {
+		drive->immed_rel++;
+		HWGROUP(drive)->rq = NULL;
+		set_irq(drive, ide_dmaq_intr);
+
+		TCQ_PRINTK("REL in queued_start\n");
+
+		if ((stat = GET_STAT()) & SERVICE_STAT)
+			return service(drive);
+
+		return ide_released;
+	}
+
+	TCQ_PRINTK("IMMED in queued_start\n");
+	drive->immed_comp++;
+
+	return udma_tcq_start(drive, rq);
+}
+
+/*
+ * For now assume that command list is always as big as we need and don't
+ * attempt to shrink it on tcq disable.
+ */
+int udma_tcq_enable(struct ata_device *drive, int on)
 {
 	int depth = drive->using_tcq ? drive->queue_depth : 0;
 
@@ -523,120 +633,3 @@
 	drive->using_tcq = 1;
 	return 0;
 }
-
-static int tcq_wait_dataphase(struct ata_device *drive)
-{
-	u8 stat;
-	int i;
-
-	while ((stat = GET_STAT()) & BUSY_STAT)
-		udelay(10);
-
-	if (OK_STAT(stat, READY_STAT | DRQ_STAT, drive->bad_wstat))
-		return 0;
-
-	i = 0;
-	udelay(1);
-	while (!OK_STAT(GET_STAT(), READY_STAT | DRQ_STAT, drive->bad_wstat)) {
-		if (unlikely(i++ > IDE_TCQ_WAIT))
-			return 1;
-
-		udelay(10);
-	}
-
-	return 0;
-}
-
-ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
-{
-	struct ata_channel *hwif = drive->channel;
-	unsigned int enable_tcq = 1;
-	u8 stat;
-	u8 feat;
-
-	switch (func) {
-		/*
-		 * invoked from a SERVICE interrupt, command etc already known.
-		 * just need to start the dma engine for this tag
-		 */
-		case ide_dma_queued_start:
-			TCQ_PRINTK("ide_dma: setting up queued %d\n", rq->tag);
-			if (!test_bit(IDE_BUSY, &HWGROUP(drive)->flags))
-				printk("queued_rw: IDE_BUSY not set\n");
-
-			if (tcq_wait_dataphase(drive))
-				return ide_stopped;
-
-			if (ide_start_dma(func, drive))
-				return ide_stopped;
-
-			set_irq(drive, ide_dmaq_intr);
-			if (!hwif->udma(ide_dma_begin, drive, rq))
-				return ide_started;
-
-			return ide_stopped;
-
-			/*
-			 * start a queued command from scratch
-			 */
-		case ide_dma_read_queued:
-		case ide_dma_write_queued: {
-			struct ata_taskfile *args = rq->special;
-
-			TCQ_PRINTK("%s: start tag %d\n", drive->name, rq->tag);
-
-			/*
-			 * set nIEN, tag start operation will enable again when
-			 * it is safe
-			 */
-			drive_ctl_nien(drive, 1);
-
-			OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
-
-			if (wait_altstat(drive, &stat, BUSY_STAT)) {
-				ide_dump_status(drive, "queued start", stat);
-				tcq_invalidate_queue(drive);
-				return ide_stopped;
-			}
-
-			drive_ctl_nien(drive, 0);
-
-			if (stat & ERR_STAT) {
-				ide_dump_status(drive, "tcq_start", stat);
-				return ide_stopped;
-			}
-
-			/*
-			 * drive released the bus, clear active tag and
-			 * check for service
-			 */
-			if ((feat = GET_FEAT()) & NSEC_REL) {
-				drive->immed_rel++;
-				HWGROUP(drive)->rq = NULL;
-				set_irq(drive, ide_dmaq_intr);
-
-				TCQ_PRINTK("REL in queued_start\n");
-
-				if ((stat = GET_STAT()) & SERVICE_STAT)
-					return service(drive);
-
-				return ide_released;
-			}
-
-			TCQ_PRINTK("IMMED in queued_start\n");
-			drive->immed_comp++;
-			return hwif->udma(ide_dma_queued_start, drive, rq);
-			}
-
-		case ide_dma_queued_off:
-			enable_tcq = 0;
-		case ide_dma_queued_on:
-			if (enable_tcq && !drive->using_dma)
-				return 1;
-			return enable_queued(drive, enable_tcq);
-		default:
-			break;
-	}
-
-	return 1;
-}
diff -urN linux-2.5.13/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.13/drivers/ide/trm290.c	2002-05-03 02:22:44.000000000 +0200
+++ linux/drivers/ide/trm290.c	2002-05-04 03:52:43.000000000 +0200
@@ -175,7 +175,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *hwif = drive->channel;
+	struct ata_channel *ch = drive->channel;
 	unsigned int count, reading = 2, writing = 0;
 
 	switch (func) {
@@ -186,12 +186,12 @@
 			break;	/* always use PIO for writes */
 #endif
 		case ide_dma_read:
-			if (!(count = ide_build_dmatable(drive, func)))
+			if (!(count = udma_new_table(ch, rq)))
 				break;		/* try PIO instead of DMA */
 			trm290_prepare_drive(drive, 1);	/* select DMA xfer */
-			outl(hwif->dmatable_dma|reading|writing, hwif->dma_base);
+			outl(ch->dmatable_dma|reading|writing, ch->dma_base);
 			drive->waiting_for_dma = 1;
-			outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
+			outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
 			if (drive->type != ATA_DISK)
 				return 0;
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
@@ -201,10 +201,10 @@
 			return 0;
 		case ide_dma_end:
 			drive->waiting_for_dma = 0;
-			ide_destroy_dmatable(drive);		/* purge DMA mappings */
-			return (inw(hwif->dma_base+2) != 0x00ff);
+			udma_destroy_table(ch);	/* purge DMA mappings */
+			return (inw(ch->dma_base + 2) != 0x00ff);
 		case ide_dma_test_irq:
-			return (inw(hwif->dma_base+2) == 0x00ff);
+			return (inw(ch->dma_base + 2) == 0x00ff);
 		default:
 			return ide_dmaproc(func, drive, rq);
 	}
diff -urN linux-2.5.13/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.13/include/linux/ide.h	2002-05-04 06:07:15.000000000 +0200
+++ linux/include/linux/ide.h	2002-05-04 05:41:33.000000000 +0200
@@ -368,32 +368,24 @@
 	/*
 	 * tcq statistics
 	 */
-	unsigned long	immed_rel;	
+	unsigned long	immed_rel;
 	unsigned long	immed_comp;
 	int		max_last_depth;
 	int		max_depth;
 } ide_drive_t;
 
-/*
- * This initiates/aborts DMA read/write operations on a drive.
- *
- * The caller is assumed to have selected the drive and programmed the drive's
- * sector address using CHS or LBA.  All that remains is to prepare for DMA
- * and then issue the actual read/write DMA/PIO command to the drive.
- *
- * Returns 0 if all went well.
- * Returns 1 if DMA read/write could not be started, in which case the caller
- * should either try again later, or revert to PIO for the current request.
- */
-typedef enum {	ide_dma_read,	ide_dma_write,		ide_dma_begin,
-		ide_dma_end,	ide_dma_check,		ide_dma_on,
-		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,
+typedef enum {
+	ide_dma_read,	ide_dma_write,
+	ide_dma_begin,	ide_dma_end,
+	ide_dma_check,
+	ide_dma_on, ide_dma_off,
+	ide_dma_off_quietly,
+	ide_dma_test_irq,
+	ide_dma_bad_drive,
+	ide_dma_good_drive,
+	ide_dma_retune,
+	ide_dma_lostirq,
+	ide_dma_timeout
 } ide_dma_action_t;
 
 enum {
@@ -436,9 +428,6 @@
 	/* special host masking for drive selection */
 	void (*maskproc) (struct ata_device *, int);
 
-	/* adjust timing based upon rq->cmd direction */
-	void (*rwproc) (struct ata_device *, ide_dma_action_t);
-
 	/* check host's drive quirk list */
 	int (*quirkproc) (struct ata_device *);
 
@@ -472,6 +461,7 @@
 	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 */
+	unsigned straight8	: 1;	/* Alan's straight 8 check */
 	unsigned no_io_32bit	: 1;	/* disallow enabling 32bit I/O */
 	unsigned no_unmask	: 1;	/* disallow setting unmask bit */
 	unsigned auto_poll	: 1;	/* supports nop auto-poll */
@@ -482,8 +472,8 @@
 #if (DISK_RECOVERY_TIME > 0)
 	unsigned long	last_time;	/* time when previous rq was done */
 #endif
-	byte		straight8;	/* Alan's straight 8 check */
-	int (*busproc)(struct ata_device *, int);	/* driver soft-power interface */
+	/* driver soft-power interface */
+	int (*busproc)(struct ata_device *, int);
 	byte		bus_state;	/* power state of the IDE bus */
 };
 
@@ -562,7 +552,7 @@
 #define SETTING_WRITE	(1 << 1)
 #define SETTING_RW	(SETTING_READ | SETTING_WRITE)
 
-typedef int (ide_procset_t)(ide_drive_t *, int);
+typedef int (ide_procset_t)(struct ata_device *, int);
 typedef struct ide_settings_s {
 	char			*name;
 	int			rw;
@@ -579,11 +569,11 @@
 	struct ide_settings_s	*next;
 } ide_settings_t;
 
-void ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set);
-void ide_remove_setting(ide_drive_t *drive, char *name);
-int ide_read_setting(ide_drive_t *t, ide_settings_t *setting);
-int ide_write_setting(ide_drive_t *drive, ide_settings_t *setting, int val);
-void ide_add_generic_settings(ide_drive_t *drive);
+extern void ide_add_setting(struct ata_device *, const char *, int, int, int, int, int, int, int, int, void *, ide_procset_t *);
+extern void ide_remove_setting(struct ata_device *, char *);
+extern int ide_read_setting(struct ata_device *, ide_settings_t *);
+extern int ide_write_setting(struct ata_device *, ide_settings_t *, int);
+extern void ide_add_generic_settings(struct ata_device *);
 
 /*
  * /proc/ide interface
@@ -696,19 +686,19 @@
 /*
  * Error reporting, in human readable form (luxurious, but a memory hog).
  */
-byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat);
+extern byte ide_dump_status(struct ata_device *, const char *, byte);
 
 /*
  * ide_error() takes action based on the error returned by the controller.
  * The caller should return immediately after invoking this.
  */
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
+extern ide_startstop_t ide_error(struct ata_device *, const char *, byte);
 
 /*
  * Issue a simple drive command
  * The drive must be selected beforehand.
  */
-void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ata_handler_t handler);
+void ide_cmd(struct ata_device *, byte, byte, ata_handler_t);
 
 /*
  * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
@@ -726,9 +716,9 @@
  * caller should return the updated value of "startstop" in this case.
  * "startstop" is unchanged when the function returns 0;
  */
-int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout);
+extern int ide_wait_stat(ide_startstop_t *, struct ata_device *, byte, byte, unsigned long);
 
-int ide_wait_noerr(ide_drive_t *drive, byte good, byte bad, unsigned long timeout);
+extern int ide_wait_noerr(struct ata_device *, byte, byte, unsigned long);
 
 /*
  * This routine is called from the partition-table code in genhd.c
@@ -737,15 +727,15 @@
 int ide_xlate_1024(kdev_t, int, int, const char *);
 
 /*
- * Convert kdev_t structure into ide_drive_t * one.
+ * Convert kdev_t structure into struct ata_device * one.
  */
-ide_drive_t *get_info_ptr(kdev_t i_rdev);
+struct ata_device *get_info_ptr(kdev_t i_rdev);
 
 /*
  * Re-Start an operation for an IDE interface.
  * The caller should return immediately after invoking this.
  */
-ide_startstop_t restart_request(ide_drive_t *);
+ide_startstop_t restart_request(struct ata_device *);
 
 /*
  * This function is intended to be used prior to invoking ide_do_drive_cmd().
@@ -767,12 +757,12 @@
  */
 #define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
 
-extern int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action);
+extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t);
 
 /*
  * Clean up after success/failure of an explicit drive cmd.
  */
-void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err);
+extern void ide_end_drive_cmd(struct ata_device *, byte, byte);
 
 struct ata_taskfile {
 	struct hd_drive_task_hdr taskfile;
@@ -809,31 +799,20 @@
 
 void ide_delay_50ms(void);
 
-byte ide_auto_reduce_xfer (ide_drive_t *drive);
-int ide_driveid_update (ide_drive_t *drive);
-int ide_ata66_check (ide_drive_t *drive, struct ata_taskfile *args);
-int ide_config_drive_speed (ide_drive_t *drive, byte speed);
-byte eighty_ninty_three (ide_drive_t *drive);
-int set_transfer (ide_drive_t *drive, struct ata_taskfile *args);
+extern byte ide_auto_reduce_xfer(struct ata_device *);
+extern int ide_driveid_update(struct ata_device *);
+extern int ide_ata66_check(struct ata_device *, struct ata_taskfile *);
+extern int ide_config_drive_speed(struct ata_device *, byte);
+extern byte eighty_ninty_three(struct ata_device *);
+extern int set_transfer(struct ata_device *, struct ata_taskfile *);
 
 extern int system_bus_speed;
 
 /*
- * idedisk_input_data() is a wrapper around ide_input_data() which copes
- * with byte-swapping the input data if required.
- */
-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
  * to the hwgroup by sleeping for timeout jiffies.
  */
-void ide_stall_queue (ide_drive_t *drive, unsigned long timeout);
-
-/*
- * ide_get_queue() returns the queue which corresponds to a given device.
- */
-request_queue_t *ide_get_queue(kdev_t dev);
+void ide_stall_queue(struct ata_device *, unsigned long);
 
 /*
  * CompactFlash cards and their brethern pretend to be removable hard disks,
@@ -842,9 +821,9 @@
  * config bits.
  */
 
-extern int drive_is_flashcard(ide_drive_t *drive);
+extern int drive_is_flashcard(struct ata_device *);
 
-int ide_spin_wait_hwgroup (ide_drive_t *drive);
+int ide_spin_wait_hwgroup(struct ata_device *);
 void ide_timer_expiry (unsigned long data);
 extern void ata_irq_request(int irq, void *data, struct pt_regs *regs);
 void do_ide_request (request_queue_t * q);
@@ -890,15 +869,21 @@
 void __init ide_scan_pcibus(int scan_direction);
 #endif
 #ifdef CONFIG_BLK_DEV_IDEDMA
-extern int ide_build_dmatable(struct ata_device *, ide_dma_action_t);
-extern void ide_destroy_dmatable(struct ata_device *);
+
+extern int udma_new_table(struct ata_channel *, struct request *);
+extern void udma_destroy_table(struct ata_channel *);
+extern void udma_print(struct ata_device *);
+
+extern ide_startstop_t udma_tcq_taskfile(struct ata_device *, struct request *);
+extern int udma_tcq_enable(struct ata_device *, int);
+
 extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
 extern int check_drive_lists(struct ata_device *, int good_bad);
 extern int ide_dmaproc(ide_dma_action_t func, struct ata_device *, struct request *);
 extern ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t, struct ata_device *, struct request *);
 extern void ide_release_dma(struct ata_channel *);
 extern void ide_setup_dma(struct ata_channel *,	unsigned long, unsigned int) __init;
-extern int ide_start_dma(ide_dma_action_t, struct ata_device *);
+extern int ata_start_dma(struct ata_device *, struct request *rq);
 #endif
 
 extern spinlock_t ide_lock;

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

* [PATCH] 2.5.13 IDE 53
  2002-04-25 21:02                 ` Linus Torvalds
                                     ` (2 preceding siblings ...)
  2002-05-05 15:54                   ` [PATCH] 2.5.13 IDE 52 Martin Dalecki
@ 2002-05-05 15:55                   ` Martin Dalecki
  2002-05-06  9:53                     ` Russell King
  2002-05-05 15:56                   ` [PATCH 2.5.13 IDE 54 Martin Dalecki
  4 siblings, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-05-05 15:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

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

Sun May  5 16:26:37 CEST 2002 ide-clean-53

- Start splitting the functions for host chip handling in to separate entities.
   This change is quite sensitive and may cause some trouble but it's for
   certain worth it anyway, because it should for example provide a much better
   infrastructure for th handling of different architectures.


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

diff -urN linux-2.5.13/drivers/ide/aec62xx.c linux/drivers/ide/aec62xx.c
--- linux-2.5.13/drivers/ide/aec62xx.c	2002-05-03 02:22:49.000000000 +0200
+++ linux/drivers/ide/aec62xx.c	2002-05-05 06:42:36.000000000 +0200
@@ -437,7 +437,7 @@
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -459,7 +459,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+		} else if (udma_white_list(drive)) {
 			if (id->eide_dma_time > 150) {
 				goto no_dma_set;
 			}
diff -urN linux-2.5.13/drivers/ide/alim15x3.c linux/drivers/ide/alim15x3.c
--- linux-2.5.13/drivers/ide/alim15x3.c	2002-05-03 02:22:54.000000000 +0200
+++ linux/drivers/ide/alim15x3.c	2002-05-05 06:43:33.000000000 +0200
@@ -441,7 +441,7 @@
 
 	if ((id != NULL) && ((id->capability & 1) != 0) && hwif->autodma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -463,7 +463,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+		} else if (udma_white_list(drive)) {
 			if (id->eide_dma_time > 150) {
 				goto no_dma_set;
 			}
@@ -483,21 +483,25 @@
 	return hwif->udma(dma_func, drive, NULL);
 }
 
+static int ali15x3_udma_write(struct ata_device *drive, struct request *rq)
+{
+	if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
+		return 1;	/* try PIO instead of DMA */
+
+	return ata_do_udma(0, drive, rq);
+}
+
 static int ali15x3_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
 	switch(func) {
 		case ide_dma_check:
 			return ali15x3_config_drive_for_dma(drive);
-		case ide_dma_write:
-			if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
-				return 1;	/* try PIO instead of DMA */
-			break;
 		default:
 			break;
 	}
 	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 unsigned int __init pci_init_ali15x3(struct pci_dev *dev)
 {
@@ -679,6 +683,7 @@
 		/*
 		 * M1543C or newer for DMAing
 		 */
+		hwif->udma_write = ali15x3_udma_write;
 		hwif->udma = ali15x3_dmaproc;
 		hwif->autodma = 1;
 	}
diff -urN linux-2.5.13/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c
--- linux-2.5.13/drivers/ide/cmd64x.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/cmd64x.c	2002-05-05 06:44:24.000000000 +0200
@@ -783,7 +783,7 @@
 	if ((id != NULL) && ((id->capability & 1) != 0) &&
 	    hwif->autodma && (drive->type == ATA_DISK)) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -805,7 +805,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+		} else if (udma_white_list(drive)) {
 			if (id->eide_dma_time > 150) {
 				goto no_dma_set;
 			}
@@ -837,6 +837,34 @@
         return ide_dmaproc(func, drive, rq);
 }
 
+static int cmd64x_udma_stop(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+	u8 dma_stat = 0;
+	unsigned long dma_base	= ch->dma_base;
+	struct pci_dev *dev	= ch->pci_dev;
+	u8 jack_slap		= ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
+
+	drive->waiting_for_dma = 0;
+	outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+	dma_stat = inb(dma_base+2);		/* get DMA status */
+	outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
+	if (jack_slap) {
+		byte dma_intr = 0;
+		byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+		byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
+		(void) pci_read_config_byte(dev, dma_reg, &dma_intr);
+		/*
+		 * DAMN BMIDE is not connected to PCI space!
+		 * Have to manually jack-slap that bitch!
+		 * To allow the PCI side to read incoming interrupts.
+		 */
+		(void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask);	/* clear the INTR bit */
+	}
+	udma_destroy_table(ch);	/* purge DMA mappings */
+	return (dma_stat & 7) != 4;		/* verify good DMA status */
+}
+
 static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *ch = drive->channel;
@@ -845,30 +873,10 @@
 	u8 mask	= (ch->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
 	unsigned long dma_base	= ch->dma_base;
 	struct pci_dev *dev	= ch->pci_dev;
-	byte jack_slap		= ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
 
 	switch (func) {
 		case ide_dma_check:
 			return cmd64x_config_drive_for_dma(drive);
-		case ide_dma_end: /* returns 1 on error, 0 otherwise */
-			drive->waiting_for_dma = 0;
-			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
-			dma_stat = inb(dma_base+2);		/* get DMA status */
-			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
-			if (jack_slap) {
-				byte dma_intr = 0;
-				byte dma_mask = (ch->unit) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
-				byte dma_reg = (ch->unit) ? ARTTIM2 : CFR;
-				(void) pci_read_config_byte(dev, dma_reg, &dma_intr);
-				/*
-				 * DAMN BMIDE is not connected to PCI space!
-				 * Have to manually jack-slap that bitch!
-				 * To allow the PCI side to read incoming interrupts.
-				 */
-				(void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask);	/* clear the INTR bit */
-			}
-			udma_destroy_table(ch);	/* purge DMA mappings */
-			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
 			dma_stat = inb(dma_base+2);
 			(void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
@@ -886,26 +894,29 @@
 	return ide_dmaproc(func, drive, rq);
 }
 
+static int cmd646_1_udma_stop(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	u8 dma_stat;
+
+	drive->waiting_for_dma = 0;
+	dma_stat = inb(dma_base+2);		/* get DMA status */
+	outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+	outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
+	udma_destroy_table(ch);			/* and free any DMA resources */
+	return (dma_stat & 7) != 4;		/* verify good DMA status */
+}
+
 /*
  * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
  * event order for DMA transfers.
  */
 static int cmd646_1_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *ch = drive->channel;
-	unsigned long dma_base = ch->dma_base;
-	byte dma_stat;
-
 	switch (func) {
 		case ide_dma_check:
 			return cmd64x_config_drive_for_dma(drive);
-		case ide_dma_end:
-			drive->waiting_for_dma = 0;
-			dma_stat = inb(dma_base+2);		/* get DMA status */
-			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
-			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
-			udma_destroy_table(ch);			/* and free any DMA resources */
-			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		default:
 			break;
 	}
@@ -1134,19 +1145,22 @@
 		case PCI_DEVICE_ID_CMD_649:
 		case PCI_DEVICE_ID_CMD_648:
 		case PCI_DEVICE_ID_CMD_643:
-			hwif->udma	= &cmd64x_dmaproc;
-			hwif->tuneproc	= &cmd64x_tuneproc;
-			hwif->speedproc = &cmd64x_tune_chipset;
+			hwif->udma_stop	= cmd64x_udma_stop;
+			hwif->udma	= cmd64x_dmaproc;
+			hwif->tuneproc	= cmd64x_tuneproc;
+			hwif->speedproc = cmd64x_tune_chipset;
 			break;
 		case PCI_DEVICE_ID_CMD_646:
 			hwif->chipset = ide_cmd646;
 			if (class_rev == 0x01) {
+				hwif->udma_stop = &cmd646_1_udma_stop;
 				hwif->udma = &cmd646_1_dmaproc;
 			} else {
-				hwif->udma = &cmd64x_dmaproc;
+				hwif->udma_stop = cmd64x_udma_stop;
+				hwif->udma = cmd64x_dmaproc;
 			}
-			hwif->tuneproc	= &cmd64x_tuneproc;
-			hwif->speedproc	= &cmd64x_tune_chipset;
+			hwif->tuneproc	= cmd64x_tuneproc;
+			hwif->speedproc	= cmd64x_tune_chipset;
 			break;
 		default:
 			break;
diff -urN linux-2.5.13/drivers/ide/Config.in linux/drivers/ide/Config.in
--- linux-2.5.13/drivers/ide/Config.in	2002-05-05 07:04:50.000000000 +0200
+++ linux/drivers/ide/Config.in	2002-05-05 03:56:46.000000000 +0200
@@ -33,16 +33,16 @@
    dep_tristate '  Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
    dep_tristate '  SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI
 
-   comment 'IDE chipset support'
+   comment 'ATA host chipset support'
    dep_bool '  CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640 $CONFIG_X86
    dep_bool '    CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED $CONFIG_BLK_DEV_CMD640
-   dep_bool '  ISA-PNP EIDE support' CONFIG_BLK_DEV_ISAPNP $CONFIG_ISAPNP
+   dep_bool '  ISA-PNP support' CONFIG_BLK_DEV_ISAPNP $CONFIG_ISAPNP
    if [ "$CONFIG_PCI" = "y" ]; then
       dep_bool '  RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 $CONFIG_X86
-      bool '  Generic PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI
+      bool '  PCI host chipset support' CONFIG_BLK_DEV_IDEPCI
       if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then
 	 bool '    Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
-	 bool '    Sharing PCI IDE interrupts support' CONFIG_IDEPCI_SHARE_IRQ
+	 bool '    Sharing PCI ATA interrupts support' CONFIG_IDEPCI_SHARE_IRQ
 	 bool '    Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI
 	 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
@@ -82,11 +82,9 @@
 	 dep_bool '    SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
 	 dep_bool '    Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI
 	 dep_bool '    VIA chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI
+	 dep_bool '    Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 $CONFIG_BLK_DEV_IDEDMA_PCI
       fi
 
-      if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
-	 bool '    Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
-      fi
    fi
    if [ "$CONFIG_ALL_PPC" = "y" ]; then
       bool '    Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC
diff -urN linux-2.5.13/drivers/ide/cs5530.c linux/drivers/ide/cs5530.c
--- linux-2.5.13/drivers/ide/cs5530.c	2002-05-03 02:22:54.000000000 +0200
+++ linux/drivers/ide/cs5530.c	2002-05-05 06:45:29.000000000 +0200
@@ -158,7 +158,7 @@
 	 */
 	if (mate->present) {
 		struct hd_driveid *mateid = mate->id;
-		if (mateid && (mateid->capability & 1) && !hwif->udma(ide_dma_bad_drive, mate, NULL)) {
+		if (mateid && (mateid->capability & 1) && !udma_black_list(mate)) {
 			if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7))
 				udma_ok = 1;
 			else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7))
@@ -172,7 +172,7 @@
 	 * Now see what the current drive is capable of,
 	 * selecting UDMA only if the mate said it was ok.
 	 */
-	if (id && (id->capability & 1) && hwif->autodma && !hwif->udma(ide_dma_bad_drive, drive, NULL)) {
+	if (id && (id->capability & 1) && hwif->autodma && !udma_black_list(drive)) {
 		if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) {
 			if      (id->dma_ultra & 4)
 				mode = XFER_UDMA_2;
diff -urN linux-2.5.13/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.13/drivers/ide/hpt34x.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/hpt34x.c	2002-05-05 06:46:35.000000000 +0200
@@ -256,7 +256,7 @@
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, rq)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -278,7 +278,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive, rq)) {
+		} else if (udma_white_list(drive)) {
 			if (id->eide_dma_time > 150) {
 				goto no_dma_set;
 			}
@@ -304,6 +304,55 @@
 	return drive->channel->udma(dma_func, drive, rq);
 }
 
+static int hpt34x_udma_stop(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	u8 dma_stat;
+
+	drive->waiting_for_dma = 0;
+	outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+	dma_stat = inb(dma_base+2);		/* get DMA status */
+	outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
+	udma_destroy_table(ch);			/* purge DMA mappings */
+
+	return (dma_stat & 7) != 4;		/* verify good DMA status */
+}
+
+static int do_udma(unsigned int reading, struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	unsigned int count;
+
+	if (!(count = udma_new_table(ch, rq)))
+		return 1;	/* try PIO instead of DMA */
+
+	outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
+	reading |= 0x01;
+	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;
+
+	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;
+}
+
+static int hpt34x_udma_read(struct ata_device *drive, struct request *rq)
+{
+	return do_udma(1 << 3, drive, rq);
+}
+
+static int hpt34x_udma_write(struct ata_device *drive, struct request *rq)
+{
+	return do_udma(0, drive, rq);
+}
+
 /*
  * hpt34x_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
  *
@@ -311,45 +360,17 @@
  * and HPT345 UDMA bios chipset (stamped HPT363)
  * by HighPoint|Triones Technologies, Inc.
  */
-
 int hpt34x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *ch = drive->channel;
-	unsigned long dma_base = ch->dma_base;
-	unsigned int count, reading = 0;
-	byte dma_stat;
-
 	switch (func) {
 		case ide_dma_check:
 			return config_drive_xfer_rate(drive, rq);
-		case ide_dma_read:
-			reading = 1 << 3;
-		case ide_dma_write:
-			if (!(count = udma_new_table(ch, rq)))
-				return 1;	/* try PIO instead of DMA */
-			outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
-			reading |= 0x01;
-			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;
-			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;
-		case ide_dma_end:	/* returns 1 on error, 0 otherwise */
-			drive->waiting_for_dma = 0;
-			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
-			dma_stat = inb(dma_base+2);		/* get DMA status */
-			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
-			udma_destroy_table(ch);			/* purge DMA mappings */
-			return (dma_stat & 7) != 4;		/* verify good DMA status */
 		default:
 			break;
 	}
 	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * If the BIOS does not set the IO base addaress to XX00, 343 will fail.
@@ -423,7 +444,10 @@
 		else
 			hwif->autodma = 0;
 
-		hwif->udma = &hpt34x_dmaproc;
+		hwif->udma_stop = hpt34x_udma_stop;
+		hwif->udma_read = hpt34x_udma_read;
+		hwif->udma_write = hpt34x_udma_write;
+		hwif->udma = hpt34x_dmaproc;
 		hwif->highmem = 1;
 	} else {
 		hwif->drives[0].autotune = 1;
diff -urN linux-2.5.13/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- linux-2.5.13/drivers/ide/hpt366.c	2002-05-05 07:04:50.000000000 +0200
+++ linux/drivers/ide/hpt366.c	2002-05-05 06:47:24.000000000 +0200
@@ -748,7 +748,7 @@
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -769,7 +769,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+		} else if (udma_white_list(drive)) {
 			if (id->eide_dma_time > 150) {
 				goto no_dma_set;
 			}
@@ -830,6 +830,86 @@
 	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
 }
 
+static void do_udma_start(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+
+	u8 regstate = ch->unit ? 0x54 : 0x50;
+	pci_write_config_byte(ch->pci_dev, regstate, 0x37);
+	udelay(10);
+}
+
+static int hpt370_udma_start(struct ata_device *drive, struct request *__rq)
+{
+	struct ata_channel *ch = drive->channel;
+
+	do_udma_start(drive);
+
+	/* 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(ch->dma_base) | 1, ch->dma_base);	/* start DMA */
+
+	return 0;
+}
+
+static void do_timeout_irq(struct ata_device *drive)
+{
+	u8 dma_stat;
+	u8 regstate = drive->channel->unit ? 0x54 : 0x50;
+	u8 reginfo = drive->channel->unit ? 0x56 : 0x52;
+	unsigned long dma_base = drive->channel->dma_base;
+
+	pci_read_config_byte(drive->channel->pci_dev, reginfo, &dma_stat);
+	printk(KERN_INFO "%s: %d bytes in FIFO\n", drive->name, dma_stat);
+	pci_write_config_byte(drive->channel->pci_dev, regstate, 0x37);
+	udelay(10);
+	dma_stat = inb(dma_base);
+	outb(dma_stat & ~0x1, dma_base); /* stop dma */
+	dma_stat = inb(dma_base + 2);
+	outb(dma_stat | 0x6, dma_base+2); /* clear errors */
+
+}
+
+static void hpt370_udma_timeout(struct ata_device *drive)
+{
+	do_timeout_irq(drive);
+	do_udma_start(drive);
+}
+
+static void hpt370_udma_lost_irq(struct ata_device *drive)
+{
+	do_timeout_irq(drive);
+	do_udma_start(drive);
+}
+
+static int hpt370_udma_stop(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	u8 dma_stat;
+
+	dma_stat = inb(dma_base + 2);
+	if (dma_stat & 0x01) {
+		udelay(20); /* wait a little */
+		dma_stat = inb(dma_base + 2);
+	}
+	if ((dma_stat & 0x01) != 0) {
+		do_timeout_irq(drive);
+		do_udma_start(drive);
+	}
+
+	drive->waiting_for_dma = 0;
+	outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+	dma_stat = inb(dma_base+2);		/* get DMA status */
+	outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
+	udma_destroy_table(ch);			/* purge DMA mappings */
+
+	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
+}
+
 int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *hwif = drive->channel;
@@ -845,18 +925,6 @@
 			dma_stat = inb(dma_base+2);
 			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
 
-		case ide_dma_end:
-			dma_stat = inb(dma_base + 2);
-			if (dma_stat & 0x01) {
-				udelay(20); /* wait a little */
-				dma_stat = inb(dma_base + 2);
-			}
-			if ((dma_stat & 0x01) == 0) 
-				break;
-
-			func = ide_dma_timeout;
-			/* fallthrough */
-
 		case ide_dma_timeout:
 		case ide_dma_lostirq:
 			pci_read_config_byte(hwif->pci_dev, reginfo, 
@@ -871,11 +939,7 @@
 			outb(dma_stat | 0x6, dma_base+2); /* clear errors */
 			/* fallthrough */
 
-#ifdef HPT_RESET_STATE_ENGINE
-	        case ide_dma_begin:
-#endif
-			pci_write_config_byte(hwif->pci_dev, regstate, 0x37);
-			udelay(10);
+			do_udma_start(drive);
 			break;
 
 		default:
@@ -883,7 +947,7 @@
 	}
 	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * Since SUN Cobalt is attempting to do this operation, I should disclose
@@ -1183,6 +1247,8 @@
 			pci_read_config_byte(hwif->pci_dev, 0x5a, &reg5ah);
 			if (reg5ah & 0x10)	/* interrupt force enable */
 				pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10);
+			hwif->udma_start = hpt370_udma_start;
+			hwif->udma_stop = hpt370_udma_stop;
 			hwif->udma = hpt370_dmaproc;
 		} else {
 			hwif->udma = hpt366_dmaproc;
diff -urN linux-2.5.13/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.13/drivers/ide/ide.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-05-05 04:27:55.000000000 +0200
@@ -1407,7 +1407,7 @@
 	/*
 	 * end current dma transaction
 	 */
-	ch->udma(ide_dma_end, drive, rq);
+	ch->udma_stop(drive);
 
 	/*
 	 * complain a little, later we might remove some of this verbosity
@@ -2127,6 +2127,13 @@
 	ch->atapi_read = old.atapi_read;
 	ch->atapi_write = old.atapi_write;
 	ch->udma = old.udma;
+	ch->udma_start = old.udma_start;
+	ch->udma_stop = old.udma_stop;
+	ch->udma_read = old.udma_read;
+	ch->udma_write = old.udma_write;
+	ch->udma_irq_status = old.udma_irq_status;
+	ch->udma_timeout = old.udma_timeout;
+	ch->udma_lost_irq = old.udma_lost_irq;
 	ch->busproc = old.busproc;
 	ch->bus_state = old.bus_state;
 	ch->dma_base = old.dma_base;
diff -urN linux-2.5.13/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.13/drivers/ide/ide-cd.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-05-05 06:36:30.000000000 +0200
@@ -737,9 +737,9 @@
 
 	if (info->dma) {
 		if (info->cmd == READ)
-			info->dma = !drive->channel->udma(ide_dma_read, drive, rq);
+			info->dma = !udma_read(drive, rq);
 		else if (info->cmd == WRITE)
-			info->dma = !drive->channel->udma(ide_dma_write, drive, rq);
+			info->dma = !udma_write(drive, rq);
 		else
 			printk("ide-cd: DMA set, but not allowed\n");
 	}
@@ -755,7 +755,7 @@
 		OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
 
 	if (info->dma)
-		drive->channel->udma(ide_dma_begin, drive, NULL);
+		udma_start(drive, rq);
 
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
 		ide_set_handler(drive, handler, WAIT_CMD, cdrom_timer_expiry);
@@ -905,7 +905,7 @@
 	/* Check for errors. */
 	if (dma) {
 		info->dma = 0;
-		if ((dma_error = drive->channel->udma(ide_dma_end, drive, NULL)))
+		if ((dma_error = udma_stop(drive)))
 			drive->channel->udma(ide_dma_off, drive, NULL);
 	}
 
@@ -1480,7 +1480,7 @@
 	/* Check for errors. */
 	if (dma) {
 		info->dma = 0;
-		if ((dma_error = drive->channel->udma(ide_dma_end, drive, NULL))) {
+		if ((dma_error = udma_stop(drive))) {
 			printk("ide-cd: write dma error\n");
 			drive->channel->udma(ide_dma_off, drive, NULL);
 		}
diff -urN linux-2.5.13/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.13/drivers/ide/ide-dma.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/ide-dma.c	2002-05-05 06:55:44.000000000 +0200
@@ -199,7 +199,7 @@
 {
 	u8 stat, dma_stat;
 
-	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
+	dma_stat = udma_stop(drive);
 	if (OK_STAT(stat = GET_STAT(),DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
 		if (!dma_stat) {
 			__ide_end_request(drive, rq, 1, rq->nr_sectors);
@@ -288,7 +288,7 @@
 			printk("%s: Disabling (U)DMA for %s\n", drive->name, id->model);
 		return(blacklist);
 	}
-#else /* !CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */
+#else
 	const char **list;
 
 	if (good_bad) {
@@ -309,7 +309,7 @@
 			}
 		}
 	}
-#endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */
+#endif
 	return 0;
 }
 
@@ -326,7 +326,7 @@
 
 	if (id && (id->capability & 1) && ch->autodma && config_allows_dma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL))
+		if (udma_black_list(drive))
 			return ch->udma(ide_dma_off, drive, NULL);
 
 		/* Enable DMA on any drive that has UltraDMA (mode 6/7/?) enabled */
@@ -346,7 +346,7 @@
 			if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404)
 				return ch->udma(ide_dma_on, drive, NULL);
 		/* Consult the list of known "good" drives */
-		if (ide_dmaproc(ide_dma_good_drive, drive, NULL))
+		if (udma_white_list(drive))
 			return ch->udma(ide_dma_on, drive, NULL);
 	}
 	return ch->udma(ide_dma_off_quietly, drive, NULL);
@@ -420,7 +420,7 @@
  *
  * For ATAPI devices, we just prepare for DMA and return. The caller should
  * then issue the packet command to the drive and call us again with
- * ide_dma_begin afterwards.
+ * udma_start afterwards.
  *
  * Returns 0 if all went well.
  * Returns 1 if DMA read/write could not be started, in which case
@@ -432,7 +432,7 @@
 	struct ata_channel *ch = drive->channel;
 	unsigned long dma_base = ch->dma_base;
 	u8 unit = (drive->select.b.unit & 0x01);
-	unsigned int reading = 0, set_high = 1;
+	unsigned int set_high = 1;
 	u8 dma_stat;
 
 	switch (func) {
@@ -456,41 +456,6 @@
 			return 0;
 		case ide_dma_check:
 			return config_drive_for_dma (drive);
-		case ide_dma_read:
-			reading = 1 << 3;
-		case ide_dma_write:
-			if (ata_start_dma(drive, rq))
-				return 1;
-
-			if (drive->type != ATA_DISK)
-				return 0;
-
-			ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);	/* issue cmd to drive */
-			if ((rq->flags & REQ_DRIVE_ACB) && (drive->addressing == 1)) {
-				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);
-			} else {
-				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
-			}
-			return drive->channel->udma(ide_dma_begin, drive, NULL);
-		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 */
-			drive->waiting_for_dma = 0;
-			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
-			dma_stat = inb(dma_base+2);		/* get DMA status */
-			outb(dma_stat|6, dma_base+2);	/* clear the INTR & ERROR bits */
-			udma_destroy_table(ch);	/* purge DMA mappings */
-			return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
 		case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
 			dma_stat = inb(dma_base+2);
 #if 0  /* do not set unless you know what you are doing */
@@ -500,13 +465,9 @@
 			}
 #endif
 			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
-		case ide_dma_bad_drive:
-		case ide_dma_good_drive:
-			return check_drive_lists(drive, (func == ide_dma_good_drive));
 		case ide_dma_timeout:
 			printk(KERN_ERR "%s: DMA timeout occured!\n", __FUNCTION__);
 			return 1;
-		case ide_dma_retune:
 		case ide_dma_lostirq:
 			printk(KERN_ERR "%s: chipset supported func only: %d\n", __FUNCTION__,  func);
 			return 1;
@@ -585,7 +546,64 @@
 /****************************************************************************
  * UDMA function which should have architecture specific counterparts where
  * neccessary.
+ *
+ * The intention is that at some point in time we will move this whole to
+ * architecture specific kernel sections. For now I would love the architecture
+ * maintainers to just #ifdef #endif this stuff directly here. I have for now
+ * tryed to update as much as I could in the architecture specific code.  But
+ * of course I may have done mistakes, so please bear with me and update it
+ * here the proper way.
+ *
+ * Thank you a lot in advance!
+ *
+ * Sat May  4 20:29:46 CEST 2002 Marcin Dalecki.
+ */
+
+/*
+ * This is the generic part of the DMA setup used by the host chipset drivers
+ * in the corresponding DMA setup method.
+ *
+ * FIXME: there are some places where this gets used driectly for "error
+ * recovery" in the ATAPI drivers. This was just plain wrong before, in esp.
+ * not portable, and just got uncovered now.
  */
+void udma_enable(struct ata_device *drive, int on, int verbose)
+{
+	struct ata_channel *ch = drive->channel;
+	int set_high = 1;
+	u8 unit = (drive->select.b.unit & 0x01);
+	u64 addr = BLK_BOUNCE_HIGH;
+
+	if (!on) {
+		if (verbose)
+			printk("%s: DMA disabled\n", drive->name);
+		set_high = 0;
+		outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ
+		udma_tcq_enable(drive, 0);
+#endif
+	}
+
+	/* toggle bounce buffers */
+
+	if (on && drive->type == ATA_DISK && drive->channel->highmem) {
+		if (!PCI_DMA_BUS_IS_PHYS)
+			addr = BLK_BOUNCE_ANY;
+		else
+			addr = drive->channel->pci_dev->dma_mask;
+	}
+
+	blk_queue_bounce_limit(&drive->queue, addr);
+
+	drive->using_dma = on;
+
+	if (on) {
+		outb(inb(ch->dma_base + 2) | (1 << (5 + unit)), ch->dma_base + 2);
+#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
+		udma_tcq_enable(drive, 1);
+#endif
+	}
+}
 
 /*
  * This prepares a dma request.  Returns 0 if all went okay, returns 1
@@ -718,4 +736,157 @@
 #endif
 }
 
+/*
+ * Drive back/white list handling for UDMA capability:
+ */
+
+int udma_black_list(struct ata_device *drive)
+{
+	return check_drive_lists(drive, 0);
+}
+
+int udma_white_list(struct ata_device *drive)
+{
+	return check_drive_lists(drive, 1);
+}
+
+/*
+ * Generic entry points for functions provided possibly by the host chip set
+ * drivers.
+ */
+
+/*
+ * Prepare the channel for a DMA startfer. Please note that only the broken
+ * Pacific Digital host chip needs the reques to be passed there to decide
+ * about addressing modes.
+ */
+
+int udma_start(struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+
+	if (ch->udma_start)
+		return ch->udma_start(drive, rq);
+
+	/* 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;
+}
+
+int udma_stop(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	u8 dma_stat;
+
+	if (ch->udma_stop)
+		return ch->udma_stop(drive);
+
+	drive->waiting_for_dma = 0;
+	outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+	dma_stat = inb(dma_base+2);		/* get DMA status */
+	outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
+	udma_destroy_table(ch);			/* purge DMA mappings */
+
+	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
+}
+
+/*
+ * This is the default read write function.
+ *
+ * It's exported only for host chips which use it for fallback or (too) late
+ * capability checking.
+ */
+
+int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request *rq)
+{
+	if (ata_start_dma(drive, rq))
+		return 1;
+
+	if (drive->type != ATA_DISK)
+		return 0;
+
+	reading <<= 3;
+
+	ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);	/* issue cmd to drive */
+	if ((rq->flags & REQ_DRIVE_ACB) && (drive->addressing == 1)) {
+		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);
+	} else {
+		OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+	}
+
+	return udma_start(drive, rq);
+}
+
+int udma_read(struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *ch = drive->channel;
+
+	if (ch->udma_read)
+		return ch->udma_read(drive, rq);
+
+	return ata_do_udma(1, drive, rq);
+}
+
+int udma_write(struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *ch = drive->channel;
+
+	if (ch->udma_write)
+		return ch->udma_write(drive, rq);
+
+	return ata_do_udma(0, drive, rq);
+}
+
+/*
+ * FIXME: This should be attached to a channel as we can see now!
+ */
+int udma_irq_status(struct ata_device *drive)
+{
+	struct ata_channel *ch = drive->channel;
+	u8 dma_stat;
+
+	if (ch->udma_irq_status)
+		return ch->udma_irq_status(drive);
+
+	/* default action */
+	dma_stat = inb(ch->dma_base + 2);
+
+	return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
+}
+
+void udma_timeout(struct ata_device *drive)
+{
+	printk(KERN_ERR "ATA: UDMA timeout occured %s!\n", drive->name);
+
+	/* Invoke the chipset specific handler now. */
+	if (drive->channel->udma_timeout)
+		drive->channel->udma_timeout(drive);
+
+}
+
+void udma_lost_irq(struct ata_device *drive)
+{
+	if (drive->channel->udma_lost_irq)
+		drive->channel->udma_lost_irq(drive);
+}
+
+EXPORT_SYMBOL(udma_enable);
+EXPORT_SYMBOL(udma_start);
+EXPORT_SYMBOL(udma_stop);
+EXPORT_SYMBOL(udma_read);
+EXPORT_SYMBOL(udma_write);
+EXPORT_SYMBOL(ata_do_udma);
+EXPORT_SYMBOL(udma_irq_status);
 EXPORT_SYMBOL(udma_print);
+EXPORT_SYMBOL(udma_black_list);
+EXPORT_SYMBOL(udma_white_list);
diff -urN linux-2.5.13/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.13/drivers/ide/ide-floppy.c	2002-05-03 02:22:45.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c	2002-05-05 06:39:44.000000000 +0200
@@ -901,7 +901,7 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
-		if (drive->channel->udma(ide_dma_end, drive, NULL)) {
+		if (udma_stop(drive)) {
 			set_bit (PC_DMA_ERROR, &pc->flags);
 		} else {
 			pc->actually_transferred=pc->request_transfer;
@@ -1122,8 +1122,12 @@
 	if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
 		(void) drive->channel->udma(ide_dma_off, drive, NULL);
 	}
-	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-		dma_ok=!drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
+	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
+		if (test_bit (PC_WRITING, &pc->flags))
+			dma_ok = !udma_write(drive, rq);
+		else
+			dma_ok = !udma_read(drive, rq);
+	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
 	if (IDE_CONTROL_REG)
@@ -1136,7 +1140,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (dma_ok) {							/* Begin DMA, if necessary */
 		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
-		(void) drive->channel->udma(ide_dma_begin, drive, NULL);
+		udma_start(drive, rq);
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
diff -urN linux-2.5.13/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- linux-2.5.13/drivers/ide/ide-pci.c	2002-05-05 07:04:47.000000000 +0200
+++ linux/drivers/ide/ide-pci.c	2002-05-05 03:56:46.000000000 +0200
@@ -709,7 +709,7 @@
 		d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
 	}
 
-	printk("%s: chipset revision %d\n", dev->name, class_rev);
+	printk(KERN_INFO "ATA: chipset rev.: %d\n", class_rev);
 
 	/*
 	 * Can we trust the reported IRQ?
@@ -722,11 +722,11 @@
 		   to act otherwise on those. The Supertrak however we need
 		   to skip */
 		if (d->vendor == PCI_VENDOR_ID_PROMISE && d->device == PCI_DEVICE_ID_PROMISE_20265) {
-			printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n");
+			printk(KERN_INFO "ATA: Found promise 20265 in RAID mode.\n");
 			if(dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_INTEL &&
 				dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960)
 			{
-				printk(KERN_INFO "ide: Skipping Promise PDC20265 attached to I2O RAID controller.\n");
+				printk(KERN_INFO "ATA: Skipping Promise PDC20265 attached to I2O RAID controller.\n");
 				return;
 			}
 		}
@@ -734,9 +734,10 @@
 		   Suspect a fastrak and fall through */
 	}
 	if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {
-		printk("%s: not 100%% native mode: will probe irqs later\n", dev->name);
+		printk(KERN_INFO "ATA: non-legacy mode: IRQ probe delayed\n");
+
 		/*
-		 * This allows off board ide-pci cards the enable a BIOS,
+		 * This allows off board ide-pci cards to enable a BIOS,
 		 * verify interrupt settings of split-mirror pci-config
 		 * space, place chipset into init-mode, and/or preserve
 		 * an interrupt if the card is not native ide support.
@@ -746,19 +747,18 @@
 		else
 			pciirq = trust_pci_irq(d, dev);
 	} else if (tried_config) {
-		printk("%s: will probe IRQs later\n", dev->name);
+		printk(KERN_INFO "ATA: will probe IRQs later\n");
 		pciirq = 0;
 	} else if (!pciirq) {
-		printk("%s: bad IRQ (%d): will probe later\n", dev->name, pciirq);
+		printk(KERN_INFO "ATA: invalid IRQ (%d): will probe later\n", pciirq);
 		pciirq = 0;
 	} else {
 		if (d->init_chipset)
 			d->init_chipset(dev);
 #ifdef __sparc__
-		printk("%s: 100%% native mode on irq %s\n",
-		       dev->name, __irq_itoa(pciirq));
+		printk(KERN_INFO "ATA: 100%% native mode on irq\n", __irq_itoa(pciirq));
 #else
-		printk("%s: 100%% native mode on irq %d\n", dev->name, pciirq);
+		printk(KERN_INFO "ATA: 100%% native mode on irq %d\n", pciirq);
 #endif
 	}
 
@@ -889,10 +889,10 @@
 		pdc20270_device_order_fixup(dev, d);
 	else if (!(d->vendor == 0 && d->device == 0) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
 		if (d->vendor == 0 && d->device == 0)
-			printk(KERN_INFO "ATA: unknown ATA interface %s (%04x:%04x) on PCI slot %s\n",
+			printk(KERN_INFO "ATA: unknown interface: %s (%04x:%04x) on PCI slot %s\n",
 			       dev->name, vendor, device, dev->slot_name);
 		else
-			printk(KERN_INFO "ATA: interface %s on PCI slot %s\n", dev->name, dev->slot_name);
+			printk(KERN_INFO "ATA: interface: %s, on PCI slot %s\n", dev->name, dev->slot_name);
 		setup_pci_device(dev, d);
 	}
 }
diff -urN linux-2.5.13/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.13/drivers/ide/ide-pmac.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/ide-pmac.c	2002-05-05 06:55:24.000000000 +0200
@@ -1449,7 +1449,6 @@
 	case ide_dma_bad_drive:
 	case ide_dma_good_drive:
 		return check_drive_lists(drive, (func == ide_dma_good_drive));
-	case ide_dma_retune:
 	case ide_dma_lostirq:
 	case ide_dma_timeout:
 		printk(KERN_WARNING "ide_pmac_dmaproc: chipset supported func only: %d\n", func);
diff -urN linux-2.5.13/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.13/drivers/ide/ide-tape.c	2002-05-03 02:22:43.000000000 +0200
+++ linux/drivers/ide/ide-tape.c	2002-05-05 06:37:08.000000000 +0200
@@ -2058,7 +2058,7 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (test_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
-		if (drive->channel->udma(ide_dma_end, drive, NULL)) {
+		if (udma_stop(drive)) {
 			/*
 			 * A DMA error is sometimes expected. For example,
 			 * if the tape is crossing a filemark during a
@@ -2311,9 +2311,13 @@
 		printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n");
 		(void) drive->channel->udma(ide_dma_off, drive, NULL);
 	}
-	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
-		dma_ok = !drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
+		if (test_bit (PC_WRITING, &pc->flags))
+			dma_ok = !udma_write(drive, rq);
+		else
+			dma_ok = !udma_read(drive, rq);
+	}
+#endif
 
 	if (IDE_CONTROL_REG)
 		OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
@@ -2324,7 +2328,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (dma_ok) {						/* Begin DMA, if necessary */
 		set_bit (PC_DMA_IN_PROGRESS, &pc->flags);
-		(void) drive->channel->udma(ide_dma_begin, drive, NULL);
+		udma_start(drive, rq);
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 	if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
diff -urN linux-2.5.13/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.13/drivers/ide/ide-taskfile.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-05-05 06:20:42.000000000 +0200
@@ -461,7 +461,6 @@
 		 * regular dma proc -- basically split stuff that needs to act
 		 * on a request from things like ide_dma_check etc.
 		 */
-		ide_dma_action_t dma_act;
 
 		if (!drive->using_dma)
 			return ide_started;
@@ -469,10 +468,10 @@
 		/* for dma commands we don't set the handler */
 		if (args->taskfile.command == WIN_WRITEDMA
 		 || args->taskfile.command == WIN_WRITEDMA_EXT)
-			dma_act = ide_dma_write;
+			udma_write(drive, rq);
 		else if (args->taskfile.command == WIN_READDMA
 		      || args->taskfile.command == WIN_READDMA_EXT)
-			dma_act = ide_dma_read;
+			udma_read(drive, rq);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ
 		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
 		      || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
@@ -484,10 +483,6 @@
 			printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
 			return ide_stopped;
 		}
-
-
-		if (drive->channel->udma(dma_act, drive, rq))
-			return ide_stopped;
 	}
 
 	return ide_started;
diff -urN linux-2.5.13/drivers/ide/ns87415.c linux/drivers/ide/ns87415.c
--- linux-2.5.13/drivers/ide/ns87415.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/ns87415.c	2002-05-05 06:29:10.000000000 +0200
@@ -82,26 +82,50 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int ns87415_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+
+static int ns87415_udma_stop(struct ata_device *drive)
 {
-	struct ata_channel *hwif = drive->channel;
-	byte		dma_stat;
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	u8 dma_stat;
+
+	drive->waiting_for_dma = 0;
+	dma_stat = inb(ch->dma_base+2);
+	outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+	outb(inb(dma_base)|6, dma_base);	/* from ERRATA: clear the INTR & ERROR bits */
+	udma_destroy_table(ch);				/* and free any DMA resources */
+
+	return (dma_stat & 7) != 4;	/* verify good DMA status */
+
+}
+
+static int ns87415_udma_read(struct ata_device *drive, struct request *rq)
+{
+	ns87415_prepare_drive(drive, 1);	/* select DMA xfer */
+
+	if (!ata_do_udma(1, drive, rq))		/* use standard DMA stuff */
+		return 0;
+
+	ns87415_prepare_drive(drive, 0);	/* DMA failed: select PIO xfer */
+
+	return 1;
+}
 
+static int ns87415_udma_write(struct ata_device *drive, struct request *rq)
+{
+	ns87415_prepare_drive(drive, 1);	/* select DMA xfer */
+
+	if (!ata_do_udma(0, drive, rq))		/* use standard DMA stuff */
+		return 0;
+
+	ns87415_prepare_drive(drive, 0);	/* DMA failed: select PIO xfer */
+
+	return 1;
+}
+
+static int ns87415_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+{
 	switch (func) {
-		case ide_dma_end: /* returns 1 on error, 0 otherwise */
-			drive->waiting_for_dma = 0;
-			dma_stat = inb(hwif->dma_base+2);
-			outb(inb(hwif->dma_base)&~1, hwif->dma_base);	/* stop DMA */
-			outb(inb(hwif->dma_base)|6, hwif->dma_base);	/* from ERRATA: clear the INTR & ERROR bits */
-			udma_destroy_table(hwif);			/* and free any DMA resources */
-			return (dma_stat & 7) != 4;		/* verify good DMA status */
-		case ide_dma_write:
-		case ide_dma_read:
-			ns87415_prepare_drive(drive, 1);	/* select DMA xfer */
-			if (!ide_dmaproc(func, drive, rq))		/* use standard DMA stuff */
-				return 0;
-			ns87415_prepare_drive(drive, 0);	/* DMA failed: select PIO xfer */
-			return 1;
 		case ide_dma_check:
 			if (drive->type != ATA_DISK)
 				return ide_dmaproc(ide_dma_off_quietly, drive, rq);
@@ -205,8 +229,12 @@
 	}
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	if (hwif->dma_base)
+	if (hwif->dma_base) {
+		hwif->udma_stop = ns87415_udma_stop;
+		hwif->udma_read = ns87415_udma_read;
+		hwif->udma_write = ns87415_udma_write;
 		hwif->udma = ns87415_dmaproc;
+	}
 #endif
 
 	hwif->selectproc = &ns87415_selectproc;
diff -urN linux-2.5.13/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.13/drivers/ide/pdc202xx.c	2002-05-03 02:22:57.000000000 +0200
+++ linux/drivers/ide/pdc202xx.c	2002-05-05 06:51:02.000000000 +0200
@@ -916,7 +916,7 @@
 	return ((int)	((id->dma_ultra >> 14) & 3) ? ide_dma_on :
 			((id->dma_ultra >> 11) & 7) ? ide_dma_on :
 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on : 
+			((id->dma_mword >> 8) & 7) ? ide_dma_on :
 			((id->dma_1word >> 8) & 7) ? ide_dma_on :
 						     ide_dma_off_quietly);
 }
@@ -929,7 +929,7 @@
 
 	if (id && (id->capability & 1) && hwif->autodma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -951,7 +951,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+		} else if (udma_white_list(drive)) {
 			if (id->eide_dma_time > 150) {
 				goto no_dma_set;
 			}
@@ -977,20 +977,107 @@
 	return ((int) check_in_drive_lists(drive, pdc_quirk_drives));
 }
 
+static int pdc202xx_udma_start(struct ata_device *drive, struct request *rq)
+{
+	u8 clock		= 0;
+	u8 hardware48hack	= 0;
+	struct ata_channel *ch = drive->channel;
+	struct pci_dev *dev	= ch->pci_dev;
+	unsigned long high_16	= pci_resource_start(dev, 4);
+	unsigned long atapi_reg	= high_16 + (ch->unit ? 0x24 : 0x00);
+
+
+	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:
+			break;
+		case PCI_DEVICE_ID_PROMISE_20267:
+		case PCI_DEVICE_ID_PROMISE_20265:
+		case PCI_DEVICE_ID_PROMISE_20262:
+			hardware48hack = 1;
+			clock = IN_BYTE(high_16 + 0x11);
+		default:
+			break;
+	}
+
+	if ((drive->addressing) && (hardware48hack)) {
+		unsigned long word_count = 0;
+
+		outb(clock|(ch->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);
+	}
+
+	/* 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(ch->dma_base) | 1, ch->dma_base); /* start DMA */
+
+	return 0;
+}
+
+int pdc202xx_udma_stop(struct ata_device *drive)
+{
+	u8 newchip		= 0;
+	u8 clock		= 0;
+	u8 hardware48hack	= 0;
+	struct ata_channel *ch = drive->channel;
+	struct pci_dev *dev	= ch->pci_dev;
+	unsigned long high_16	= pci_resource_start(dev, 4);
+	unsigned long atapi_reg	= high_16 + (ch->unit ? 0x24 : 0x00);
+	unsigned long dma_base = ch->dma_base;
+	u8 dma_stat;
+
+	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:
+			newchip = 1;
+			break;
+		case PCI_DEVICE_ID_PROMISE_20267:
+		case PCI_DEVICE_ID_PROMISE_20265:
+		case PCI_DEVICE_ID_PROMISE_20262:
+			hardware48hack = 1;
+			clock = IN_BYTE(high_16 + 0x11);
+ 		default:
+			break;
+	}
+	if ((drive->addressing) && (hardware48hack)) {
+		outl(0, atapi_reg);	/* zero out extra */
+		clock = IN_BYTE(high_16 + 0x11);
+		OUT_BYTE(clock & ~(ch->unit ? 0x08:0x02), high_16 + 0x11);
+	}
+
+	drive->waiting_for_dma = 0;
+	outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+	dma_stat = inb(dma_base+2);		/* get DMA status */
+	outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
+	udma_destroy_table(ch);			/* purge DMA mappings */
+
+	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
+}
+
 /*
  * pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
  */
 int pdc202xx_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
-	byte dma_stat		= 0;
-	byte sc1d		= 0;
-	byte newchip		= 0;
-	byte clock		= 0;
-	byte hardware48hack	= 0;
+	u8 dma_stat	= 0;
+	u8 sc1d		= 0;
+	u8 newchip	= 0;
+	u8 clock	= 0;
+	u8 hardware48hack = 0;
 	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->unit ? 0x24 : 0x00);
 	unsigned long dma_base	= hwif->dma_base;
 
 	switch (dev->device) {
@@ -1013,29 +1100,6 @@
 	switch (func) {
 		case ide_dma_check:
 			return config_drive_xfer_rate(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.
-			 */
-			if ((drive->addressing) && (hardware48hack)) {
-				struct request *rq = HWGROUP(drive)->rq;
-				unsigned long word_count = 0;
-
-				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);
-			}
-			break;
-		case ide_dma_end:
-			if ((drive->addressing) && (hardware48hack)) {
-				outl(0, atapi_reg);	/* zero out extra */
-				clock = IN_BYTE(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 */
 			dma_stat = IN_BYTE(dma_base+2);
 			if (newchip)
@@ -1268,6 +1332,8 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
+		hwif->udma_start = pdc202xx_udma_start;
+		hwif->udma_stop = pdc202xx_udma_stop;
 		hwif->udma = pdc202xx_dmaproc;
 		hwif->highmem = 1;
 		if (!noautodma)
diff -urN linux-2.5.13/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c
--- linux-2.5.13/drivers/ide/serverworks.c	2002-05-03 02:22:54.000000000 +0200
+++ linux/drivers/ide/serverworks.c	2002-05-05 06:50:07.000000000 +0200
@@ -431,14 +431,14 @@
 						     ide_dma_off_quietly);
 }
 
-static int config_drive_xfer_rate (ide_drive_t *drive)
+static int config_drive_xfer_rate(struct ata_device *drive)
 {
 	struct hd_driveid *id = drive->id;
 	ide_dma_action_t dma_func = ide_dma_on;
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -460,7 +460,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if (ide_dmaproc(ide_dma_good_drive, drive, NULL)) {
+		} else if (udma_white_list(drive)) {
 			if (id->eide_dma_time > 150) {
 				goto no_dma_set;
 			}
@@ -480,45 +480,54 @@
 	return drive->channel->udma(dma_func, drive, NULL);
 }
 
-static int svwks_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int svwks_udma_stop(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		case ide_dma_end:
-		{
-			struct ata_channel *hwif = drive->channel;
-			unsigned long dma_base		= hwif->dma_base;
+	struct ata_channel *ch = drive->channel;
+	unsigned long dma_base = ch->dma_base;
+	u8 dma_stat;
 
-			if(inb(dma_base+0x02)&1)
-			{
+	if(inb(dma_base+0x02)&1)
+	{
 #if 0
-				int i;
-				printk(KERN_ERR "Curious - OSB4 thinks the DMA is still running.\n");
-				for(i=0;i<10;i++)
-				{
-					if(!(inb(dma_base+0x02)&1))
-					{
-						printk(KERN_ERR "OSB4 now finished.\n");
-						break;
-					}
-					udelay(5);
-				}
+		int i;
+		printk(KERN_ERR "Curious - OSB4 thinks the DMA is still running.\n");
+		for(i=0;i<10;i++)
+		{
+			if(!(inb(dma_base+0x02)&1))
+			{
+				printk(KERN_ERR "OSB4 now finished.\n");
+				break;
+			}
+			udelay(5);
+		}
 #endif
-				printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
-				printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
-				printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
+		printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n");
+		printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n");
+		printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n");
 #if 0
-				/* Panic might sys_sync -> death by corrupt disk */
-				panic("OSB4: continuing might cause disk corruption.\n");
+		/* Panic might sys_sync -> death by corrupt disk */
+		panic("OSB4: continuing might cause disk corruption.\n");
 #else
-				printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
-				while(1)
-					cpu_relax();
+		printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n");
+		while(1)
+			cpu_relax();
 #endif
-			}
-			/* and drop through */
-		}
+	}
+
+	drive->waiting_for_dma = 0;
+	outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
+	dma_stat = inb(dma_base+2);		/* get DMA status */
+	outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */
+	udma_destroy_table(ch);			/* purge DMA mappings */
+
+	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
+}
+
+static int svwks_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+{
+	switch (func) {
+		case ide_dma_check:
+			return config_drive_xfer_rate(drive);
 		default:
 			break;
 	}
@@ -645,6 +654,7 @@
 		if (!noautodma)
 			hwif->autodma = 1;
 #endif
+		hwif->udma_stop = svwks_udma_stop;
 		hwif->udma = svwks_dmaproc;
 		hwif->highmem = 1;
 	} else {
diff -urN linux-2.5.13/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c
--- linux-2.5.13/drivers/ide/sis5513.c	2002-05-03 02:22:49.000000000 +0200
+++ linux/drivers/ide/sis5513.c	2002-05-05 06:52:10.000000000 +0200
@@ -685,7 +685,7 @@
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive, NULL)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			goto fast_ata_pio;
 		}
@@ -707,7 +707,7 @@
 				if (dma_func != ide_dma_on)
 					goto no_dma_set;
 			}
-		} else if ((ide_dmaproc(ide_dma_good_drive, drive, NULL)) &&
+		} else if ((udma_white_list(drive)) &&
 			   (id->eide_dma_time > 150)) {
 			/* Consult the list of known "good" drives */
 			dma_func = config_chipset_for_dma(drive, 0);
diff -urN linux-2.5.13/drivers/ide/sl82c105.c linux/drivers/ide/sl82c105.c
--- linux-2.5.13/drivers/ide/sl82c105.c	2002-05-03 02:22:46.000000000 +0200
+++ linux/drivers/ide/sl82c105.c	2002-05-05 06:53:08.000000000 +0200
@@ -114,7 +114,7 @@
  * Check to see if the drive and
  * chipset is capable of DMA mode
  */
-static int sl82c105_check_drive(ide_drive_t *drive)
+static int sl82c105_check_drive(ide_drive_t *drive, struct request *rq)
 {
 	ide_dma_action_t dma_func = ide_dma_off_quietly;
 
@@ -129,7 +129,7 @@
 			break;
 
 		/* Consult the list of known "bad" drives */
-		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
+		if (udma_black_list(drive)) {
 			dma_func = ide_dma_off;
 			break;
 		}
@@ -140,23 +140,23 @@
 			break;
 		}
 
-		if (ide_dmaproc(ide_dma_good_drive, drive)) {
+		if (udma_white_list(drive)) {
 			dma_func = ide_dma_on;
 			break;
 		}
 	} while (0);
 
-	return drive->channel->dmaproc(dma_func, drive);
+	return drive->channel->udma(dma_func, drive, rq);
 }
 
 /*
  * Our own dmaproc, only to intercept ide_dma_check
  */
-static int sl82c105_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
+static int sl82c105_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
 {
 	switch (func) {
 	case ide_dma_check:
-		return sl82c105_check_drive(drive);
+		return sl82c105_check_drive(drive, rq);
 	case ide_dma_on:
 		if (config_for_dma(drive))
 			func = ide_dma_off;
@@ -168,7 +168,7 @@
 	default:
 		break;
 	}
-	return ide_dmaproc(func, drive);
+	return ide_dmaproc(func, drive, rq);
 }
 
 /*
@@ -183,8 +183,8 @@
 	 * We support 32-bit I/O on this interface, and it
 	 * doesn't have problems with interrupts.
 	 */
-	drive->io_32bit = 1;
-	drive->unmask = 1;
+	drive->channel->io_32bit = 1;
+	drive->channel->unmask = 1;
 }
 
 /*
@@ -252,10 +252,10 @@
 	}
 	outb(dma_state, dma_base + 2);
 
-	hwif->dmaproc = NULL;
+	hwif->udma = NULL;
 	ide_setup_dma(hwif, dma_base, 8);
-	if (hwif->dmaproc)
-		hwif->dmaproc = sl82c105_dmaproc;
+	if (hwif->udma)
+		hwif->udma = sl82c105_dmaproc;
 }
 
 /*
diff -urN linux-2.5.13/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.13/drivers/ide/tcq.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/tcq.c	2002-05-05 06:03:18.000000000 +0200
@@ -95,7 +95,7 @@
 	del_timer(&hwgroup->timer);
 
 	if (test_bit(IDE_DMA, &hwgroup->flags))
-		drive->channel->udma(ide_dma_end, drive, hwgroup->rq);
+		udma_stop(drive);
 
 	blk_queue_invalidate_tags(q);
 
@@ -328,7 +328,7 @@
 	/*
 	 * transfer was in progress, stop DMA engine
 	 */
-	dma_stat = drive->channel->udma(ide_dma_end, drive, rq);
+	dma_stat = udma_stop(drive);
 
 	/*
 	 * must be end of I/O, check status and complete as necessary
@@ -531,7 +531,7 @@
 		return ide_stopped;
 
 	set_irq(drive, ide_dmaq_intr);
-	if (!ch->udma(ide_dma_begin, drive, rq))
+	if (!udma_start(drive, rq))
 		return ide_started;
 
 	return ide_stopped;
diff -urN linux-2.5.13/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.13/drivers/ide/trm290.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/trm290.c	2002-05-05 06:32:15.000000000 +0200
@@ -173,36 +173,73 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int trm290_udma_start(struct ata_device *drive, struct request *__rq)
+{
+	/* Nothing to be done here. */
+	return 0;
+}
+
+static int trm290_udma_stop(struct ata_device *drive)
 {
 	struct ata_channel *ch = drive->channel;
-	unsigned int count, reading = 2, writing = 0;
 
-	switch (func) {
-		case ide_dma_write:
-			reading = 0;
-			writing = 1;
+	drive->waiting_for_dma = 0;
+	udma_destroy_table(ch);	/* purge DMA mappings */
+	return (inw(ch->dma_base + 2) != 0x00ff);
+}
+
+static int do_udma(unsigned int reading, struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *ch = drive->channel;
+	unsigned int count, writing;
+
+	if (!reading) {
+		reading = 0;
+		writing = 1;
 #ifdef TRM290_NO_DMA_WRITES
-			break;	/* always use PIO for writes */
+		trm290_prepare_drive(drive, 0);	/* select PIO xfer */
+
+		return 1;
 #endif
-		case ide_dma_read:
-			if (!(count = udma_new_table(ch, rq)))
-				break;		/* try PIO instead of DMA */
-			trm290_prepare_drive(drive, 1);	/* select DMA xfer */
-			outl(ch->dmatable_dma|reading|writing, ch->dma_base);
-			drive->waiting_for_dma = 1;
-			outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
-			if (drive->type != ATA_DISK)
-				return 0;
-			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
-			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
-			return 0;
-		case ide_dma_begin:
-			return 0;
-		case ide_dma_end:
-			drive->waiting_for_dma = 0;
-			udma_destroy_table(ch);	/* purge DMA mappings */
-			return (inw(ch->dma_base + 2) != 0x00ff);
+	} else {
+		reading = 2;
+		writing = 0;
+	}
+
+	if (!(count = udma_new_table(ch, rq))) {
+		trm290_prepare_drive(drive, 0);	/* select PIO xfer */
+		return 1;	/* try PIO instead of DMA */
+	}
+
+	trm290_prepare_drive(drive, 1);	/* select DMA xfer */
+	outl(ch->dmatable_dma|reading|writing, ch->dma_base);
+	drive->waiting_for_dma = 1;
+	outw((count * 2) - 1, ch->dma_base+2); /* start DMA */
+
+	if (drive->type != ATA_DISK)
+		return 0;
+
+	ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
+	OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+
+	return 0;
+}
+
+static int trm290_udma_read(struct ata_device *drive, struct request *rq)
+{
+	return do_udma(1, drive, rq);
+}
+
+static int trm290_udma_write(struct ata_device *drive, struct request *rq)
+{
+	return do_udma(0, drive, rq);
+}
+
+static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+{
+	struct ata_channel *ch = drive->channel;
+
+	switch (func) {
 		case ide_dma_test_irq:
 			return (inw(ch->dma_base + 2) == 0x00ff);
 		default:
@@ -263,6 +300,10 @@
 	ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->unit ? 0x0080 : 0x0000), 3);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+	hwif->udma_start = trm290_udma_start;
+	hwif->udma_stop = trm290_udma_stop;
+	hwif->udma_read = trm290_udma_read;
+	hwif->udma_write = trm290_udma_write;
 	hwif->udma = trm290_dmaproc;
 #endif
 
diff -urN linux-2.5.13/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.13/drivers/scsi/ide-scsi.c	2002-05-03 02:22:38.000000000 +0200
+++ linux/drivers/scsi/ide-scsi.c	2002-05-05 06:41:03.000000000 +0200
@@ -328,7 +328,7 @@
 		printk ("ide-scsi: %s: DMA complete\n", drive->name);
 #endif /* IDESCSI_DEBUG_LOG */
 		pc->actually_transferred=pc->request_transfer;
-		(void) drive->channel->udma(ide_dma_end, drive, NULL);
+		udma_stop(drive);
 	}
 
 	status = GET_STAT();						/* Clear the interrupt */
@@ -429,8 +429,12 @@
 	pc->current_position=pc->buffer;
 	bcount = min(pc->request_transfer, 63 * 1024);		/* Request to transfer the entire buffer at once */
 
-	if (drive->using_dma && rq->bio)
-		dma_ok = !drive->channel->udma(test_bit (PC_WRITING, &pc->flags) ? ide_dma_write : ide_dma_read, drive, rq);
+	if (drive->using_dma && rq->bio) {
+		if (test_bit (PC_WRITING, &pc->flags))
+			dma_ok = !udma_write(drive, rq);
+		else
+			dma_ok = !udma_read(drive, rq);
+	}
 
 	SELECT_DRIVE(drive->channel, drive);
 	if (IDE_CONTROL_REG)
@@ -441,7 +445,7 @@
 
 	if (dma_ok) {
 		set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
-		(void) drive->channel->udma(ide_dma_begin, drive, NULL);
+		udma_start(drive, rq);
 	}
 	if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
 		ide_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL);
diff -urN linux-2.5.13/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.13/include/linux/ide.h	2002-05-05 07:04:53.000000000 +0200
+++ linux/include/linux/ide.h	2002-05-05 06:54:29.000000000 +0200
@@ -375,15 +375,10 @@
 } ide_drive_t;
 
 typedef enum {
-	ide_dma_read,	ide_dma_write,
-	ide_dma_begin,	ide_dma_end,
 	ide_dma_check,
 	ide_dma_on, ide_dma_off,
 	ide_dma_off_quietly,
 	ide_dma_test_irq,
-	ide_dma_bad_drive,
-	ide_dma_good_drive,
-	ide_dma_retune,
 	ide_dma_lostirq,
 	ide_dma_timeout
 } ide_dma_action_t;
@@ -437,7 +432,19 @@
 	void (*atapi_read)(struct ata_device *, void *, unsigned int);
 	void (*atapi_write)(struct ata_device *, void *, unsigned int);
 
-	int (*udma)(ide_dma_action_t, struct ata_device *, struct request *); /* dma read/write/abort routine */
+	int (*udma)(ide_dma_action_t, struct ata_device *, struct request *);
+
+	int (*udma_start) (struct ata_device *, struct request *rq);
+	int (*udma_stop) (struct ata_device *);
+
+	int (*udma_read) (struct ata_device *, struct request *rq);
+	int (*udma_write) (struct ata_device *, struct request *rq);
+
+	int (*udma_irq_status) (struct ata_device *);
+
+	void (*udma_timeout) (struct ata_device *);
+	void (*udma_lost_irq) (struct ata_device *);
+
 	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 */
@@ -874,13 +881,25 @@
 extern void udma_destroy_table(struct ata_channel *);
 extern void udma_print(struct ata_device *);
 
+extern void udma_enable(struct ata_device *, int, int);
+extern int udma_black_list(struct ata_device *);
+extern int udma_white_list(struct ata_device *);
+extern void udma_timeout(struct ata_device *);
+extern void udma_lost_irq(struct ata_device *);
+extern int udma_start(struct ata_device *, struct request *rq);
+extern int udma_stop(struct ata_device *);
+extern int udma_read(struct ata_device *, struct request *rq);
+extern int udma_write(struct ata_device *, struct request *rq);
+extern int udma_irq_status(struct ata_device *);
+
+extern int ata_do_udma(unsigned int reading, struct ata_device *drive, struct request *rq);
+
 extern ide_startstop_t udma_tcq_taskfile(struct ata_device *, struct request *);
 extern int udma_tcq_enable(struct ata_device *, int);
 
 extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
 extern int check_drive_lists(struct ata_device *, int good_bad);
 extern int ide_dmaproc(ide_dma_action_t func, struct ata_device *, struct request *);
-extern ide_startstop_t ide_tcq_dmaproc(ide_dma_action_t, struct ata_device *, struct request *);
 extern void ide_release_dma(struct ata_channel *);
 extern void ide_setup_dma(struct ata_channel *,	unsigned long, unsigned int) __init;
 extern int ata_start_dma(struct ata_device *, struct request *rq);

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

* [PATCH 2.5.13 IDE 54
  2002-04-25 21:02                 ` Linus Torvalds
                                     ` (3 preceding siblings ...)
  2002-05-05 15:55                   ` [PATCH] 2.5.13 IDE 53 Martin Dalecki
@ 2002-05-05 15:56                   ` Martin Dalecki
  2002-05-07 12:52                     ` Paul Mackerras
  4 siblings, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-05-05 15:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

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

Sun May  5 16:32:22 CEST 2002 ide-clean-54

- Finish the changes from patch 53. ide_dma_actaion_t is gone now as well as
   whole hidden code paths associated with it. I hope I didn't mess too many
   things up with this, since the sheer size of the changes make them sensitive.
   (Tested on tree different host chip sets so it shouldn't be too bad...)

   Just still some minor cleanup remaining to be done in this area. The tags
   lefts there are intentional.

   In esp. the ide_dma_on method in cy82c693 looks suspicious.

   Using udma_enable in ide-cd.c, ide-floppy.c and ide-tape.c is suspicious as
   well. We have just uncovered it.

   In the next round we will concentrate on the fixes people did send me
   last time.

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

diff -urN linux-2.5.13/drivers/ide/aec62xx.c linux/drivers/ide/aec62xx.c
--- linux-2.5.13/drivers/ide/aec62xx.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/aec62xx.c	2002-05-05 17:56:44.000000000 +0200
@@ -310,7 +310,7 @@
 	byte speed		= -1;
 
 	if (drive->type != ATA_DISK)
-		return ide_dma_off_quietly;
+		return 0;
 
 	if (((id->dma_ultra & 0x0010) ||
 	     (id->dma_ultra & 0x0008) ||
@@ -333,17 +333,17 @@
 	} else if (id->dma_1word & 0x0001) {
 		speed = XFER_SW_DMA_0;
 	} else {
- 		return ((int) ide_dma_off_quietly);
- 	}
+		return 0;
+	}
 
 	outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
 	(void) aec6210_tune_chipset(drive, speed);
 
-	return ((int)	((id->dma_ultra >> 11) & 3) ? ide_dma_off :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	return ((int)	((id->dma_ultra >> 11) & 3) ? 0 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+			((id->dma_1word >> 8) & 7) ? 1 :
+						     0);
 }
 
 static int config_aec6260_chipset_for_dma (ide_drive_t *drive, byte ultra)
@@ -356,7 +356,7 @@
 	byte ultra66		= eighty_ninty_three(drive);
 
 	if (drive->type != ATA_DISK)
-		return ((int) ide_dma_off_quietly);
+		return 0;
 
 	if ((id->dma_ultra & 0x0010) && (ultra) && (ultra66)) {
 		speed = XFER_UDMA_4;
@@ -381,17 +381,17 @@
 	} else if (id->dma_1word & 0x0001) {
 		speed = XFER_SW_DMA_0;
 	} else {
-		return ((int) ide_dma_off_quietly);
+		return 0;
 	}
 
 	outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
 	(void) aec6260_tune_chipset(drive, speed);
 
-	return ((int)	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	return ((int)	((id->dma_ultra >> 11) & 3) ? 1 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+			((id->dma_1word >> 8) & 7) ? 1 :
+						     0);
 }
 
 static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
@@ -403,7 +403,7 @@
 		case PCI_DEVICE_ID_ARTOP_ATP860R:
 			return config_aec6260_chipset_for_dma(drive, ultra);
 		default:
-			return ((int) ide_dma_off_quietly);
+			return 0;
 	}
 }
 
@@ -433,21 +433,23 @@
 static int config_drive_xfer_rate (ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
-	ide_dma_action_t dma_func = ide_dma_on;
+	int on = 1;
+	int verbose = 1;
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			goto fast_ata_pio;
 		}
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 		if (id->field_valid & 4) {
 			if (id->dma_ultra & 0x001F) {
 				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive, 1);
+				on = config_chipset_for_dma(drive, 1);
 				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
+				    (!on))
 					goto try_dma_modes;
 			}
 		} else if (id->field_valid & 2) {
@@ -455,8 +457,8 @@
 			if ((id->dma_mword & 0x0007) ||
 			    (id->dma_1word & 0x0007)) {
 				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive, 0);
-				if (dma_func != ide_dma_on)
+				on = config_chipset_for_dma(drive, 0);
+				if (!on)
 					goto no_dma_set;
 			}
 		} else if (udma_white_list(drive)) {
@@ -464,53 +466,29 @@
 				goto no_dma_set;
 			}
 			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive, 0);
-			if (dma_func != ide_dma_on)
+			on = config_chipset_for_dma(drive, 0);
+			if (!on)
 				goto no_dma_set;
 		} else {
 			goto fast_ata_pio;
 		}
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 no_dma_set:
 		aec62xx_tune_drive(drive, 5);
 	}
-	return drive->channel->udma(dma_func, drive, NULL);
+	udma_enable(drive, on, verbose);
+	return 0;
 }
 
-/*
- * aec62xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
- */
-int aec62xx_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+int aec62xx_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		case ide_dma_lostirq:
-		case ide_dma_timeout:
-			switch(drive->channel->pci_dev->device) {
-				case PCI_DEVICE_ID_ARTOP_ATP860:
-				case PCI_DEVICE_ID_ARTOP_ATP860R:
-//					{
-//						int i = 0;
-//						byte reg49h = 0;
-//						pci_read_config_byte(drive->channel->pci_dev, 0x49, &reg49h);
-//						for (i=0;i<256;i++)
-//							pci_write_config_byte(drive->channel->pci_dev, 0x49, reg49h|0x10);
-//						pci_write_config_byte(drive->channel->pci_dev, 0x49, reg49h & ~0x10);
-//					}
-//					return 0;
-				default:
-					break;
-			}
-		default:
-			break;
-	}
-	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+	return config_drive_xfer_rate(drive);
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-#endif /* CONFIG_AEC62XX_TUNING */
+#endif
+#endif
 
 unsigned int __init pci_init_aec62xx (struct pci_dev *dev)
 {
@@ -546,7 +524,7 @@
 	hwif->speedproc = aec62xx_tune_chipset;
 # ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base)
-		hwif->udma = aec62xx_dmaproc;
+		hwif->XXX_udma = aec62xx_dmaproc;
 	hwif->highmem = 1;
 # else
 	hwif->drives[0].autotune = 1;
diff -urN linux-2.5.13/drivers/ide/alim15x3.c linux/drivers/ide/alim15x3.c
--- linux-2.5.13/drivers/ide/alim15x3.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/alim15x3.c	2002-05-05 17:58:09.000000000 +0200
@@ -297,7 +297,7 @@
 			pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0);
 		}
 	}
-	
+
 	pci_write_config_byte(dev, port, s_clc);
 	pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc);
 	__restore_flags(flags);
@@ -391,7 +391,7 @@
 	} else if (id->dma_1word & 0x0001) {
 		speed = XFER_SW_DMA_0;
 	} else {
-		return ((int) ide_dma_off_quietly);
+		return 0;
 	}
 
 	(void) ali15x3_tune_chipset(drive, speed);
@@ -399,11 +399,11 @@
 	if (!drive->init_speed)
 		drive->init_speed = speed;
 
-	rval = (int)(	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	rval = (int)(	((id->dma_ultra >> 11) & 3) ? 1:
+			((id->dma_ultra >> 8) & 7) ? 1:
+			((id->dma_mword >> 8) & 7) ? 1:
+			((id->dma_1word >> 8) & 7) ? 1:
+						     0);
 
 	return rval;
 }
@@ -433,25 +433,29 @@
 {
 	struct hd_driveid *id = drive->id;
 	struct ata_channel *hwif = drive->channel;
-	ide_dma_action_t dma_func = ide_dma_on;
+	int on = 1;
+	int verbose = 1;
 	byte can_ultra_dma = ali15x3_can_ultra(drive);
 
-	if ((m5229_revision<=0x20) && (drive->type != ATA_DISK))
-		return hwif->udma(ide_dma_off_quietly, drive, NULL);
+	if ((m5229_revision<=0x20) && (drive->type != ATA_DISK)) {
+		udma_enable(drive, 0, 0);
+		return 0;
+	}
 
 	if ((id != NULL) && ((id->capability & 1) != 0) && hwif->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			goto fast_ata_pio;
 		}
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 		if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) {
 			if (id->dma_ultra & 0x003F) {
 				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive, can_ultra_dma);
+				on = config_chipset_for_dma(drive, can_ultra_dma);
 				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
+				    (!on))
 					goto try_dma_modes;
 			}
 		} else if (id->field_valid & 2) {
@@ -459,8 +463,8 @@
 			if ((id->dma_mword & 0x0007) ||
 			    (id->dma_1word & 0x0007)) {
 				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive, can_ultra_dma);
-				if (dma_func != ide_dma_on)
+				on = config_chipset_for_dma(drive, can_ultra_dma);
+				if (!on)
 					goto no_dma_set;
 			}
 		} else if (udma_white_list(drive)) {
@@ -468,19 +472,23 @@
 				goto no_dma_set;
 			}
 			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive, can_ultra_dma);
-			if (dma_func != ide_dma_on)
+			on = config_chipset_for_dma(drive, can_ultra_dma);
+			if (!on)
 				goto no_dma_set;
 		} else {
 			goto fast_ata_pio;
 		}
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 no_dma_set:
 		config_chipset_for_pio(drive);
 	}
-	return hwif->udma(dma_func, drive, NULL);
+
+	udma_enable(drive, on, verbose);
+
+	return 0;
 }
 
 static int ali15x3_udma_write(struct ata_device *drive, struct request *rq)
@@ -491,15 +499,9 @@
 	return ata_do_udma(0, drive, rq);
 }
 
-static int ali15x3_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int ali15x3_dmaproc(struct ata_device *drive)
 {
-	switch(func) {
-		case ide_dma_check:
-			return ali15x3_config_drive_for_dma(drive);
-		default:
-			break;
-	}
-	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+	return ali15x3_config_drive_for_dma(drive);
 }
 #endif
 
@@ -684,7 +686,7 @@
 		 * M1543C or newer for DMAing
 		 */
 		hwif->udma_write = ali15x3_udma_write;
-		hwif->udma = ali15x3_dmaproc;
+		hwif->XXX_udma = ali15x3_dmaproc;
 		hwif->autodma = 1;
 	}
 
diff -urN linux-2.5.13/drivers/ide/amd74xx.c linux/drivers/ide/amd74xx.c
--- linux-2.5.13/drivers/ide/amd74xx.c	2002-05-03 02:22:54.000000000 +0200
+++ linux/drivers/ide/amd74xx.c	2002-05-05 17:59:25.000000000 +0200
@@ -275,36 +275,23 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-
-/*
- * amd74xx_dmaproc() is a callback from upper layers that can do
- * a lot, but we use it for DMA/PIO tuning only, delegating everything
- * else to the default ide_dmaproc().
- */
-
-int amd74xx_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+int amd74xx_dmaproc(struct ata_device *drive)
 {
+	short w80 = drive->channel->udma_four;
 
-	if (func == ide_dma_check) {
-
-		short w80 = drive->channel->udma_four;
-
-		short speed = ata_timing_mode(drive,
+	short speed = ata_timing_mode(drive,
 			XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA |
 			((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
 			(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
 			(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0));
 
-		amd_set_drive(drive, speed);
+	amd_set_drive(drive, speed);
 
-		func = (drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO)
-			? ide_dma_on : ide_dma_off_quietly;
-	}
+	udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
 
-	return ide_dmaproc(func, drive, rq);
+	return 0;
 }
-
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * The initialization callback. Here we determine the IDE chip type
@@ -433,7 +420,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
 		hwif->highmem = 1;
-		hwif->udma = amd74xx_dmaproc;
+		hwif->XXX_udma = amd74xx_dmaproc;
 # ifdef CONFIG_IDEDMA_AUTO
 		if (!noautodma)
 			hwif->autodma = 1;
diff -urN linux-2.5.13/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c
--- linux-2.5.13/drivers/ide/cmd64x.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/cmd64x.c	2002-05-05 18:00:56.000000000 +0200
@@ -636,7 +636,7 @@
 
 	if (drive->type != ATA_DISK) {
 		cmdprintk("CMD64X: drive is not a disk at double check, inital check failed!!\n");
-		return ((int) ide_dma_off);
+		return 0;
 	}
 
 	/* UltraDMA only supported on PCI646U and PCI646U2,
@@ -683,16 +683,16 @@
 	config_chipset_for_pio(drive, set_pio);
 
 	if (set_pio)
-		return ((int) ide_dma_off_quietly);
+		return 0;
 
 	if (cmd64x_tune_chipset(drive, speed))
-		return ((int) ide_dma_off);
+		return 0;
 
-	rval = (int)(	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	rval = (int)(	((id->dma_ultra >> 11) & 7) ? 1 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+			((id->dma_1word >> 8) & 7) ? 1 :
+						     0);
 
 	return rval;
 }
@@ -725,17 +725,17 @@
 	config_chipset_for_pio(drive, set_pio);
 
 	if (set_pio)
-		return ((int) ide_dma_off_quietly);
+		return 0;
 
 	if (cmd680_tune_chipset(drive, speed))
-		return ((int) ide_dma_off);
+		return 0;
 
-	rval = (int)(	((id->dma_ultra >> 14) & 3) ? ide_dma_on :
-			((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	rval = (int)(	((id->dma_ultra >> 14) & 3) ? 1 :
+			((id->dma_ultra >> 11) & 7) ? 1 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+			((id->dma_1word >> 8) & 7) ? 1 :
+						     0);
 	return rval;
 }
 
@@ -756,7 +756,8 @@
 	byte can_ultra_66	= 0;
 	byte can_ultra_100	= 0;
 	byte can_ultra_133	= 0;
-	ide_dma_action_t dma_func = ide_dma_on;
+	int on = 1;
+	int verbose = 1;
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
@@ -777,23 +778,26 @@
 			can_ultra_100 = 0;
 			break;
 		default:
-			return hwif->udma(ide_dma_off, drive, NULL);
+			udma_enable(drive, 0, 1);
+
+			return 0;
 	}
 
 	if ((id != NULL) && ((id->capability & 1) != 0) &&
 	    hwif->autodma && (drive->type == ATA_DISK)) {
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			goto fast_ata_pio;
 		}
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 		if ((id->field_valid & 4) && (can_ultra_33)) {
 			if (id->dma_ultra & 0x007F) {
 				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive, class_rev, can_ultra_66);
+				on = config_chipset_for_dma(drive, class_rev, can_ultra_66);
 				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
+				    (!on))
 					goto try_dma_modes;
 			}
 		} else if (id->field_valid & 2) {
@@ -801,8 +805,8 @@
 			if ((id->dma_mword & 0x0007) ||
 			    (id->dma_1word & 0x0007)) {
 				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive, class_rev, 0);
-				if (dma_func != ide_dma_on)
+				on = config_chipset_for_dma(drive, class_rev, 0);
+				if (!on)
 					goto no_dma_set;
 			}
 		} else if (udma_white_list(drive)) {
@@ -810,31 +814,28 @@
 				goto no_dma_set;
 			}
 			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive, class_rev, 0);
-			if (dma_func != ide_dma_on)
+			on = config_chipset_for_dma(drive, class_rev, 0);
+			if (!on)
 				goto no_dma_set;
 		} else {
 			goto fast_ata_pio;
 		}
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 no_dma_set:
 		config_chipset_for_pio(drive, 1);
 	}
-	return drive->channel->udma(dma_func, drive, NULL);
+
+	udma_enable(drive, on, verbose);
+
+	return 0;
 }
 
-static int cmd680_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int cmd680_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			return cmd64x_config_drive_for_dma(drive);
-		default:
-			break;
-	}
-	/* Other cases are done by generic IDE-DMA code. */
-        return ide_dmaproc(func, drive, rq);
+	return cmd64x_config_drive_for_dma(drive);
 }
 
 static int cmd64x_udma_stop(struct ata_device *drive)
@@ -865,33 +866,29 @@
 	return (dma_stat & 7) != 4;		/* verify good DMA status */
 }
 
-static int cmd64x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int cmd64x_udma_irq_status(struct ata_device *drive)
 {
 	struct ata_channel *ch = drive->channel;
 	u8 dma_stat = 0;
 	u8 dma_alt_stat	= 0;
-	u8 mask	= (ch->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
 	unsigned long dma_base	= ch->dma_base;
 	struct pci_dev *dev	= ch->pci_dev;
+	u8 mask	= (ch->unit) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
 
-	switch (func) {
-		case ide_dma_check:
-			return cmd64x_config_drive_for_dma(drive);
-		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
-			dma_stat = inb(dma_base+2);
-			(void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
+	dma_stat = inb(dma_base+2);
+	(void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
 #ifdef DEBUG
-			printk("%s: dma_stat: 0x%02x dma_alt_stat: 0x%02x mask: 0x%02x\n", drive->name, dma_stat, dma_alt_stat, mask);
+	printk("%s: dma_stat: 0x%02x dma_alt_stat: 0x%02x mask: 0x%02x\n", drive->name, dma_stat, dma_alt_stat, mask);
 #endif
-			if (!(dma_alt_stat & mask)) {
-				return 0;
-			}
-			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
-		default:
-			break;
+	if (!(dma_alt_stat & mask)) {
+		return 0;
 	}
-	/* Other cases are done by generic IDE-DMA code. */
-	return ide_dmaproc(func, drive, rq);
+	return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
+}
+
+static int cmd64x_dmaproc(struct ata_device *drive)
+{
+	return cmd64x_config_drive_for_dma(drive);
 }
 
 static int cmd646_1_udma_stop(struct ata_device *drive)
@@ -912,19 +909,11 @@
  * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
  * event order for DMA transfers.
  */
-static int cmd646_1_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int cmd646_1_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			return cmd64x_config_drive_for_dma(drive);
-		default:
-			break;
-	}
-
-	/* Other cases are done by generic IDE-DMA code. */
-	return ide_dmaproc(func, drive, rq);
+	return cmd64x_config_drive_for_dma(drive);
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 static int cmd680_busproc(struct ata_device * drive, int state)
 {
@@ -1136,28 +1125,30 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	switch(dev->device) {
 		case PCI_DEVICE_ID_CMD_680:
-			hwif->busproc	= &cmd680_busproc;
-			hwif->udma	= &cmd680_dmaproc;
-			hwif->resetproc = &cmd680_reset;
-			hwif->speedproc	= &cmd680_tune_chipset;
-			hwif->tuneproc	= &cmd680_tuneproc;
+			hwif->busproc	= cmd680_busproc;
+			hwif->XXX_udma	= cmd680_dmaproc;
+			hwif->resetproc = cmd680_reset;
+			hwif->speedproc	= cmd680_tune_chipset;
+			hwif->tuneproc	= cmd680_tuneproc;
 			break;
 		case PCI_DEVICE_ID_CMD_649:
 		case PCI_DEVICE_ID_CMD_648:
 		case PCI_DEVICE_ID_CMD_643:
 			hwif->udma_stop	= cmd64x_udma_stop;
-			hwif->udma	= cmd64x_dmaproc;
+			hwif->udma_irq_status = cmd64x_udma_irq_status;
+			hwif->XXX_udma	= cmd64x_dmaproc;
 			hwif->tuneproc	= cmd64x_tuneproc;
 			hwif->speedproc = cmd64x_tune_chipset;
 			break;
 		case PCI_DEVICE_ID_CMD_646:
 			hwif->chipset = ide_cmd646;
 			if (class_rev == 0x01) {
-				hwif->udma_stop = &cmd646_1_udma_stop;
-				hwif->udma = &cmd646_1_dmaproc;
+				hwif->udma_stop = cmd646_1_udma_stop;
+				hwif->XXX_udma = cmd646_1_dmaproc;
 			} else {
 				hwif->udma_stop = cmd64x_udma_stop;
-				hwif->udma = cmd64x_dmaproc;
+				hwif->udma_irq_status = cmd64x_udma_irq_status;
+				hwif->XXX_udma = cmd64x_dmaproc;
 			}
 			hwif->tuneproc	= cmd64x_tuneproc;
 			hwif->speedproc	= cmd64x_tune_chipset;
diff -urN linux-2.5.13/drivers/ide/cs5530.c linux/drivers/ide/cs5530.c
--- linux-2.5.13/drivers/ide/cs5530.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/cs5530.c	2002-05-05 18:01:52.000000000 +0200
@@ -144,7 +144,7 @@
 	/*
 	 * Default to DMA-off in case we run into trouble here.
 	 */
-	hwif->udma(ide_dma_off_quietly, drive, NULL);
+	udma_enable(drive, 0, 0);
 	outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */
 
 	/*
@@ -229,26 +229,16 @@
 	/*
 	 * Finally, turn DMA on in software, and exit.
 	 */
-	return hwif->udma(ide_dma_on, drive, NULL);	/* success */
+	udma_enable(drive, 1, 1);	/* success */
+
+	return 0;
 }
 
-/*
- * This is a CS5530-specific wrapper for the standard ide_dmaproc().
- * We need it for our custom "ide_dma_check" function.
- * All other requests are forwarded to the standard ide_dmaproc().
- */
-int cs5530_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+int cs5530_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			return cs5530_config_dma(drive);
-		default:
-			break;
-	}
-	/* Other cases are done by generic IDE-DMA code. */
-	return ide_dmaproc(func, drive, rq);
+	return cs5530_config_dma(drive);
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * Initialize the cs5530 bridge for reliable IDE DMA operation.
@@ -353,11 +343,11 @@
 		unsigned int basereg, d0_timings;
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	hwif->udma = cs5530_dmaproc;
+	hwif->XXX_udma = cs5530_dmaproc;
 	hwif->highmem = 1;
 #else
 	hwif->autodma = 0;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 		hwif->tuneproc = &cs5530_tuneproc;
 		basereg = CS5530_BASEREG(hwif);
diff -urN linux-2.5.13/drivers/ide/cy82c693.c linux/drivers/ide/cy82c693.c
--- linux-2.5.13/drivers/ide/cy82c693.c	2002-05-03 02:22:45.000000000 +0200
+++ linux/drivers/ide/cy82c693.c	2002-05-05 18:03:30.000000000 +0200
@@ -8,7 +8,7 @@
  *
  * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards.
  * Writting the driver was quite simple, since most of the job is
- * done by the generic pci-ide support. 
+ * done by the generic pci-ide support.
  * The hard part was finding the CY82C693's datasheet on Cypress's
  * web page :-(. But Altavista solved this problem :-).
  *
@@ -17,12 +17,12 @@
  * - I recently got a 16.8G IBM DTTA, so I was able to test it with
  *   a large and fast disk - the results look great, so I'd say the
  *   driver is working fine :-)
- *   hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA 
- * - this is my first linux driver, so there's probably a lot  of room 
+ *   hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
+ * - this is my first linux driver, so there's probably a lot  of room
  *   for optimizations and bug fixing, so feel free to do it.
  * - use idebus=xx parameter to set PCI bus speed - needed to calc
  *   timings for PIO modes (default will be 40)
- * - if using PIO mode it's a good idea to set the PIO mode and 
+ * - if using PIO mode it's a good idea to set the PIO mode and
  *   32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
  * - I had some problems with my IBM DHEA with PIO modes < 2
  *   (lost interrupts) ?????
@@ -71,7 +71,7 @@
  * note: the value for busmaster timeout is tricky and i got it by trial and error !
  *       using a to low value will cause DMA timeouts and drop IDE performance
  *       using a to high value will cause audio playback to scatter
- *       if you know a better value or how to calc it, please let me know 
+ *       if you know a better value or how to calc it, please let me know
  */
 #define BUSMASTER_TIMEOUT	0x50	/* twice the value written in cy82c693ub datasheet */
 /*
@@ -81,12 +81,12 @@
 /* here are the offset definitions for the registers */
 #define CY82_IDE_CMDREG		0x04
 #define CY82_IDE_ADDRSETUP	0x48
-#define CY82_IDE_MASTER_IOR	0x4C	
-#define CY82_IDE_MASTER_IOW	0x4D	
-#define CY82_IDE_SLAVE_IOR	0x4E	
+#define CY82_IDE_MASTER_IOR	0x4C
+#define CY82_IDE_MASTER_IOW	0x4D
+#define CY82_IDE_SLAVE_IOR	0x4E
 #define CY82_IDE_SLAVE_IOW	0x4F
-#define CY82_IDE_MASTER_8BIT	0x50	
-#define CY82_IDE_SLAVE_8BIT	0x51	
+#define CY82_IDE_MASTER_8BIT	0x50
+#define CY82_IDE_SLAVE_8BIT	0x51
 
 #define CY82_INDEX_PORT		0x22
 #define CY82_DATA_PORT		0x23
@@ -188,14 +188,14 @@
 
         if (mode>2)	/* make sure we set a valid mode */
 		mode = 2;
-			   
+
 	if (mode > drive->id->tDMA)  /* to be absolutly sure we have a valid mode */
 		mode = drive->id->tDMA;
-	
+
         index = (drive->channel->unit == 0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1;
 
 #if CY82C693_DEBUG_LOGS
-       	/* for debug let's show the previous values */
+	/* for debug let's show the previous values */
 
 	OUT_BYTE(index, CY82_INDEX_PORT);
 	data = IN_BYTE(CY82_DATA_PORT);
@@ -212,7 +212,7 @@
 	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 */
 
-	/* 
+	/*
 	 * note: below we set the value for Bus Master IDE TimeOut Register
 	 * I'm not absolutly sure what this does, but it solved my problem
 	 * with IDE DMA and sound, so I now can play sound and work with
@@ -226,45 +226,44 @@
 	OUT_BYTE(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
 	OUT_BYTE(data, CY82_DATA_PORT);
 
-#if CY82C693_DEBUG_INFO	
+#if CY82C693_DEBUG_INFO
 	printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", drive->name, data);
 #endif /* CY82C693_DEBUG_INFO */
 }
 
-/* 
+/*
  * used to set DMA mode for CY82C693 (single and multi modes)
  */
-static int cy82c693_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int cy82c693_dmaproc(struct ata_device *drive)
 {
 	/*
-	 * if the function is dma on, set dma mode for drive everything
-	 * else is done by the defaul func
+	 * Set dma mode for drive everything else is done by the defaul func.
 	 */
-	if (func == ide_dma_on) {
-		struct hd_driveid *id = drive->id;
+	struct hd_driveid *id = drive->id;
 
 #if CY82C693_DEBUG_INFO
-		printk (KERN_INFO "dma_on: %s\n", drive->name);
-#endif /* CY82C693_DEBUG_INFO */
+	printk (KERN_INFO "dma_on: %s\n", drive->name);
+#endif
 
-		if (id != NULL) {
-                       /* Enable DMA on any drive that has DMA (multi or single) enabled */
-                       if (id->field_valid & 2) {       /* regular DMA */
-			       int mmode, smode;
-
-			       mmode = id->dma_mword & (id->dma_mword >> 8);
-			       smode = id->dma_1word & (id->dma_1word >> 8);
-
-		               if (mmode != 0)
-				     cy82c693_dma_enable(drive, (mmode >> 1), 0); /* enable multi */
-			       else if (smode != 0)
-				     cy82c693_dma_enable(drive, (smode >> 1), 1); /* enable single */
-			}
+	if (id != NULL) {
+		/* Enable DMA on any drive that has DMA (multi or single) enabled */
+		if (id->field_valid & 2) {       /* regular DMA */
+			int mmode, smode;
+
+			mmode = id->dma_mword & (id->dma_mword >> 8);
+			smode = id->dma_1word & (id->dma_1word >> 8);
+
+			if (mmode != 0)
+				cy82c693_dma_enable(drive, (mmode >> 1), 0); /* enable multi */
+			else if (smode != 0)
+				cy82c693_dma_enable(drive, (smode >> 1), 1); /* enable single */
 		}
 	}
-        return ide_dmaproc(func, drive, rq);
+	udma_enable(drive, 1, 1);
+
+	return 0;
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * tune ide drive - set PIO mode
@@ -287,14 +286,14 @@
 
 #if CY82C693_DEBUG_LOGS
 	/* for debug let's show the register values */
-	
-       	if (drive->select.b.unit == 0) {
+
+	if (drive->select.b.unit == 0) {
 		/*
-		 * get master drive registers               	
+		 * get master drive registers
 		 * address setup control register
 		 * is 32 bit !!!
-		 */ 
-	  	pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);                
+		 */
+		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 		addrCtrl &= 0x0F;
 
 		/* now let's get the remaining registers */
@@ -306,7 +305,7 @@
 		 * set slave drive registers
 		 * address setup control register
 		 * is 32 bit !!!
-		 */ 
+		 */
 		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 
 		addrCtrl &= 0xF0;
@@ -336,9 +335,9 @@
 		 * set master drive
 		 * address setup control register
 		 * is 32 bit !!!
-		 */ 
+		 */
 		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
-		
+
 		addrCtrl &= (~0xF);
 		addrCtrl |= (unsigned int)pclk.address_time;
 		pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
@@ -347,14 +346,14 @@
 		pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
 		pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
 		pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
-		
+
 		addrCtrl &= 0xF;
 	} else {
 		/*
 		 * set slave drive
 		 * address setup control register
 		 * is 32 bit !!!
-		 */ 
+		 */
 		pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
 
 		addrCtrl &= (~0xF0);
@@ -368,7 +367,7 @@
 
 		addrCtrl >>= 4;
 		addrCtrl &= 0xF;
-	}	
+	}
 
 #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->unit, drive->select.b.unit, addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
@@ -388,14 +387,14 @@
 {
 #ifdef CY82C693_SETDMA_CLOCK
         byte data;
-#endif /* CY82C693_SETDMA_CLOCK */ 
+#endif /* CY82C693_SETDMA_CLOCK */
 
 	/* write info about this verion of the driver */
 	printk (KERN_INFO CY82_VERSION "\n");
 
 #ifdef CY82C693_SETDMA_CLOCK
        /* okay let's set the DMA clock speed */
-        
+
         OUT_BYTE(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT);
         data = IN_BYTE(CY82_DATA_PORT);
 
@@ -406,11 +405,11 @@
         /*
 	 * for some reason sometimes the DMA controller
 	 * speed is set to ATCLK/2 ???? - we fix this here
-	 * 
+	 *
 	 * note: i don't know what causes this strange behaviour,
 	 *       but even changing the dma speed doesn't solve it :-(
-	 *       the ide performance is still only half the normal speed 
-	 * 
+	 *       the ide performance is still only half the normal speed
+	 *
 	 *       if anybody knows what goes wrong with my machine, please
 	 *       let me know - ASK
          */
@@ -442,7 +441,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
 		hwif->highmem = 1;
-		hwif->udma = cy82c693_dmaproc;
+		hwif->XXX_udma = cy82c693_dmaproc;
 		if (!noautodma)
 			hwif->autodma = 1;
 	}
diff -urN linux-2.5.13/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.13/drivers/ide/hpt34x.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/hpt34x.c	2002-05-05 18:05:45.000000000 +0200
@@ -210,7 +210,7 @@
 	byte speed		= 0x00;
 
 	if (drive->type != ATA_DISK)
-		return ((int) ide_dma_off_quietly);
+		return 0;
 
 	hpt34x_clear_chipset(drive);
 
@@ -237,36 +237,38 @@
 	} else if (id->dma_1word & 0x0001) {
 		speed = XFER_SW_DMA_0;
         } else {
-		return ((int) ide_dma_off_quietly);
+		return 0;
 	}
 
 	(void) hpt34x_tune_chipset(drive, speed);
 
-	return ((int)	((id->dma_ultra >> 11) & 3) ? ide_dma_off :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	return ((int)	((id->dma_ultra >> 11) & 3) ? 0 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+			((id->dma_1word >> 8) & 7) ? 1 :
+						     0);
 }
 
-static int config_drive_xfer_rate(struct ata_device *drive, struct request *rq)
+static int config_drive_xfer_rate(struct ata_device *drive)
 {
 	struct hd_driveid *id = drive->id;
-	ide_dma_action_t dma_func = ide_dma_on;
+	int on = 1;
+	int verbose = 1;
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			goto fast_ata_pio;
 		}
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 		if (id->field_valid & 4) {
 			if (id->dma_ultra & 0x0007) {
 				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive, 1);
+				on = config_chipset_for_dma(drive, 1);
 				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
+				    (!on))
 					goto try_dma_modes;
 			}
 		} else if (id->field_valid & 2) {
@@ -274,8 +276,8 @@
 			if ((id->dma_mword & 0x0007) ||
 			    (id->dma_1word & 0x0007)) {
 				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive, 0);
-				if (dma_func != ide_dma_on)
+				on = config_chipset_for_dma(drive, 0);
+				if (!on)
 					goto no_dma_set;
 			}
 		} else if (udma_white_list(drive)) {
@@ -283,25 +285,27 @@
 				goto no_dma_set;
 			}
 			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive, 0);
-			if (dma_func != ide_dma_on)
+			on = config_chipset_for_dma(drive, 0);
+			if (!on)
 				goto no_dma_set;
 		} else {
 			goto fast_ata_pio;
 		}
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 no_dma_set:
 		config_chipset_for_pio(drive);
 	}
 
 #ifndef CONFIG_HPT34X_AUTODMA
-	if (dma_func == ide_dma_on)
-		dma_func = ide_dma_off;
-#endif /* CONFIG_HPT34X_AUTODMA */
+	if (on)
+		on = 0;
+#endif
+	udma_enable(drive, on, verbose);
 
-	return drive->channel->udma(dma_func, drive, rq);
+	return 0;
 }
 
 static int hpt34x_udma_stop(struct ata_device *drive)
@@ -354,21 +358,13 @@
 }
 
 /*
- * hpt34x_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
- *
  * This is specific to the HPT343 UDMA bios-less chipset
  * and HPT345 UDMA bios chipset (stamped HPT363)
  * by HighPoint|Triones Technologies, Inc.
  */
-int hpt34x_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int hpt34x_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive, rq);
-		default:
-			break;
-	}
-	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+	return config_drive_xfer_rate(drive);
 }
 #endif
 
@@ -447,7 +443,7 @@
 		hwif->udma_stop = hpt34x_udma_stop;
 		hwif->udma_read = hpt34x_udma_read;
 		hwif->udma_write = hpt34x_udma_write;
-		hwif->udma = hpt34x_dmaproc;
+		hwif->XXX_udma = hpt34x_dmaproc;
 		hwif->highmem = 1;
 	} else {
 		hwif->drives[0].autotune = 1;
diff -urN linux-2.5.13/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- linux-2.5.13/drivers/ide/hpt366.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/hpt366.c	2002-05-05 18:06:29.000000000 +0200
@@ -661,7 +661,7 @@
 	int  rval;
 
 	if ((drive->type != ATA_DISK) && (speed < XFER_SW_DMA_0))
-		return ((int) ide_dma_off_quietly);
+		return 0;
 
 	if ((id->dma_ultra & 0x0020) &&
 	    (!check_in_drive_lists(drive, bad_ata100_5)) &&
@@ -694,15 +694,15 @@
 	} else if (id->dma_mword & 0x0001) {
 		speed = XFER_MW_DMA_0;
 	} else {
-		return ((int) ide_dma_off_quietly);
+		return 0;
 	}
 
 	(void) hpt3xx_tune_chipset(drive, speed);
 
-	rval = (int)(	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	rval = (int)(	((id->dma_ultra >> 11) & 7) ? 1 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+						     0);
 	return rval;
 }
 
@@ -744,29 +744,31 @@
 static int config_drive_xfer_rate (ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
-	ide_dma_action_t dma_func = ide_dma_on;
+	int on = 1;
+	int verbose = 1;
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			goto fast_ata_pio;
 		}
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 		if (id->field_valid & 4) {
 			if (id->dma_ultra & 0x002F) {
 				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive);
+				on = config_chipset_for_dma(drive);
 				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
+				    (!on))
 					goto try_dma_modes;
 			}
 		} else if (id->field_valid & 2) {
 try_dma_modes:
 			if (id->dma_mword & 0x0007) {
 				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive);
-				if (dma_func != ide_dma_on)
+				on = config_chipset_for_dma(drive);
+				if (!on)
 					goto no_dma_set;
 			}
 		} else if (udma_white_list(drive)) {
@@ -774,60 +776,45 @@
 				goto no_dma_set;
 			}
 			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive);
-			if (dma_func != ide_dma_on)
+			on = config_chipset_for_dma(drive);
+			if (!on)
 				goto no_dma_set;
 		} else {
 			goto fast_ata_pio;
 		}
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 no_dma_set:
 
 		config_chipset_for_pio(drive);
 	}
-	return drive->channel->udma(dma_func, drive, NULL);
+	udma_enable(drive, on, verbose);
+
+	return 0;
+}
+
+static void hpt366_udma_irq_lost(struct ata_device *drive)
+{
+	u8 reg50h = 0, reg52h = 0, reg5ah = 0;
+
+	pci_read_config_byte(drive->channel->pci_dev, 0x50, &reg50h);
+	pci_read_config_byte(drive->channel->pci_dev, 0x52, &reg52h);
+	pci_read_config_byte(drive->channel->pci_dev, 0x5a, &reg5ah);
+	printk("%s: (%s)  reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n",
+			drive->name, __FUNCTION__, reg50h, reg52h, reg5ah);
+	if (reg5ah & 0x10)
+		pci_write_config_byte(drive->channel->pci_dev, 0x5a, reg5ah & ~0x10);
 }
 
 /*
- * hpt366_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
- *
  * This is specific to the HPT366 UDMA bios chipset
  * by HighPoint|Triones Technologies, Inc.
  */
-int hpt366_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int hpt366_dmaproc(struct ata_device *drive)
 {
-	byte reg50h = 0, reg52h = 0, reg5ah = 0, dma_stat = 0;
-	unsigned long dma_base = drive->channel->dma_base;
-
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
-			dma_stat = inb(dma_base+2);
-			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
-		case ide_dma_lostirq:
-			pci_read_config_byte(drive->channel->pci_dev, 0x50, &reg50h);
-			pci_read_config_byte(drive->channel->pci_dev, 0x52, &reg52h);
-			pci_read_config_byte(drive->channel->pci_dev, 0x5a, &reg5ah);
-			printk("%s: (ide_dma_lostirq)  reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n",
-				drive->name, reg50h, reg52h, reg5ah);
-			if (reg5ah & 0x10)
-				pci_write_config_byte(drive->channel->pci_dev, 0x5a, reg5ah & ~0x10);
-			/* fall through to a reset */
-#if 0
-		case ide_dma_begin:
-		case ide_dma_end:
-			/* reset the chips state over and over.. */
-			pci_write_config_byte(drive->channel->pci_dev, 0x51, 0x13);
-#endif
-			break;
-		case ide_dma_timeout:
-		default:
-			break;
-	}
-	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+	return config_drive_xfer_rate(drive);
 }
 
 static void do_udma_start(struct ata_device *drive)
@@ -879,7 +866,7 @@
 	do_udma_start(drive);
 }
 
-static void hpt370_udma_lost_irq(struct ata_device *drive)
+static void hpt370_udma_irq_lost(struct ata_device *drive)
 {
 	do_timeout_irq(drive);
 	do_udma_start(drive);
@@ -910,42 +897,10 @@
 	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
 }
 
-int hpt370_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
-{
-	struct ata_channel *hwif = drive->channel;
-	unsigned long dma_base = hwif->dma_base;
-	byte regstate = hwif->unit ? 0x54 : 0x50;
-	byte reginfo = hwif->unit ? 0x56 : 0x52;
-	byte dma_stat;
-
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
-			dma_stat = inb(dma_base+2);
-			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
-
-		case ide_dma_timeout:
-		case ide_dma_lostirq:
-			pci_read_config_byte(hwif->pci_dev, reginfo, 
-					     &dma_stat); 
-			printk("%s: %d bytes in FIFO\n", drive->name, 
-			       dma_stat);
-			pci_write_config_byte(hwif->pci_dev, regstate, 0x37);
-			udelay(10);
-			dma_stat = inb(dma_base);
-			outb(dma_stat & ~0x1, dma_base); /* stop dma */
-			dma_stat = inb(dma_base + 2); 
-			outb(dma_stat | 0x6, dma_base+2); /* clear errors */
-			/* fallthrough */
-
-			do_udma_start(drive);
-			break;
 
-		default:
-			break;
-	}
-	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+static int hpt370_dmaproc(struct ata_device *drive)
+{
+	return config_drive_xfer_rate(drive);
 }
 #endif
 
@@ -1249,9 +1204,12 @@
 				pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10);
 			hwif->udma_start = hpt370_udma_start;
 			hwif->udma_stop = hpt370_udma_stop;
-			hwif->udma = hpt370_dmaproc;
+			hwif->udma_timeout = hpt370_udma_timeout;
+			hwif->udma_irq_lost = hpt370_udma_irq_lost;
+			hwif->XXX_udma = hpt370_dmaproc;
 		} else {
-			hwif->udma = hpt366_dmaproc;
+			hwif->udma_irq_lost = hpt366_udma_irq_lost;
+			hwif->XXX_udma = hpt366_dmaproc;
 		}
 		if (!noautodma)
 			hwif->autodma = 1;
diff -urN linux-2.5.13/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.13/drivers/ide/ide.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/ide.c	2002-05-05 17:54:40.000000000 +0200
@@ -311,7 +311,7 @@
 
 	if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
 		drive->state = 0;
-		drive->channel->udma(ide_dma_on, drive, rq);
+		udma_enable(drive, 1, 1);
 	}
 
 	if (!end_that_request_first(rq, uptodate, nr_secs)) {
@@ -364,13 +364,13 @@
 
 	/* check the DMA crc count */
 	if (drive->crc_count) {
-		drive->channel->udma(ide_dma_off_quietly, drive, NULL);
+		udma_enable(drive, 0, 0);
 		if ((drive->channel->speedproc) != NULL)
 		        drive->channel->speedproc(drive, ide_auto_reduce_xfer(drive));
 		if (drive->current_speed >= XFER_SW_DMA_0)
-			drive->channel->udma(ide_dma_on, drive, NULL);
+			udma_enable(drive, 1, 1);
 	} else
-		drive->channel->udma(ide_dma_off, drive, NULL);
+		udma_enable(drive, 0, 1);
 }
 
 /*
@@ -1402,18 +1402,11 @@
  */
 static void dma_timeout_retry(struct ata_device *drive, struct request *rq)
 {
-	struct ata_channel *ch = drive->channel;
-
 	/*
 	 * end current dma transaction
 	 */
-	ch->udma_stop(drive);
-
-	/*
-	 * complain a little, later we might remove some of this verbosity
-	 */
-	printk("%s: timeout waiting for DMA\n", drive->name);
-	ch->udma(ide_dma_timeout, drive, rq);
+	udma_stop(drive);
+	udma_timeout(drive);
 
 	/*
 	 * Disable dma for now, but remember that we did so because of
@@ -1422,7 +1415,7 @@
 	 */
 	drive->retry_pio++;
 	drive->state = DMA_PIO_RETRY;
-	ch->udma(ide_dma_off_quietly, drive, rq);
+	udma_enable(drive, 0, 0);
 
 	/*
 	 * un-busy drive etc (hwgroup->busy is cleared on return) and
@@ -1510,7 +1503,7 @@
 				startstop = handler(drive, ch->hwgroup->rq);
 			} else if (drive_is_ready(drive)) {
 				if (drive->waiting_for_dma)
-					ch->udma(ide_dma_lostirq, drive, ch->hwgroup->rq);
+					udma_irq_lost(drive);
 				(void) ide_ack_intr(ch);
 				printk("%s: lost interrupt\n", drive->name);
 				startstop = handler(drive, ch->hwgroup->rq);
@@ -2126,14 +2119,14 @@
 	ch->ata_write = old.ata_write;
 	ch->atapi_read = old.atapi_read;
 	ch->atapi_write = old.atapi_write;
-	ch->udma = old.udma;
+	ch->XXX_udma = old.XXX_udma;
 	ch->udma_start = old.udma_start;
 	ch->udma_stop = old.udma_stop;
 	ch->udma_read = old.udma_read;
 	ch->udma_write = old.udma_write;
 	ch->udma_irq_status = old.udma_irq_status;
 	ch->udma_timeout = old.udma_timeout;
-	ch->udma_lost_irq = old.udma_lost_irq;
+	ch->udma_irq_lost = old.udma_irq_lost;
 	ch->busproc = old.busproc;
 	ch->bus_state = old.bus_state;
 	ch->dma_base = old.dma_base;
@@ -2409,10 +2402,11 @@
 {
 	if (!drive->driver)
 		return -EPERM;
-	if (!drive->id || !(drive->id->capability & 1) || !drive->channel->udma)
+
+	if (!drive->id || !(drive->id->capability & 1) || !drive->channel->XXX_udma)
 		return -EPERM;
-	if (drive->channel->udma(arg ? ide_dma_on : ide_dma_off, drive, NULL))
-		return -EIO;
+
+	udma_enable(drive, arg, 1);
 	return 0;
 }
 
@@ -3184,7 +3178,7 @@
 	restore_flags(flags);		/* all CPUs */
 	/* FIXME: Check what this magic number is supposed to be about? */
 	if (drive->autotune != 2) {
-		if (drive->channel->udma) {
+		if (drive->channel->XXX_udma) {
 
 			/*
 			 * Force DMAing for the beginning of the check.  Some
@@ -3194,8 +3188,8 @@
 			 *   PARANOIA!!!
 			 */
 
-			drive->channel->udma(ide_dma_off_quietly, drive, NULL);
-			drive->channel->udma(ide_dma_check, drive, NULL);
+			udma_enable(drive, 0, 0);
+			drive->channel->XXX_udma(drive);
 #ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
 			udma_tcq_enable(drive, 1);
 #endif
diff -urN linux-2.5.13/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.13/drivers/ide/ide-cd.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/ide-cd.c	2002-05-05 17:40:50.000000000 +0200
@@ -906,7 +906,7 @@
 	if (dma) {
 		info->dma = 0;
 		if ((dma_error = udma_stop(drive)))
-			drive->channel->udma(ide_dma_off, drive, NULL);
+			udma_enable(drive, 0, 1);
 	}
 
 	if (cdrom_decode_status(&startstop, drive, rq, 0, &stat))
@@ -1482,7 +1482,7 @@
 		info->dma = 0;
 		if ((dma_error = udma_stop(drive))) {
 			printk("ide-cd: write dma error\n");
-			drive->channel->udma(ide_dma_off, drive, NULL);
+			udma_enable(drive, 0, 1);
 		}
 	}
 
diff -urN linux-2.5.13/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.13/drivers/ide/ide-disk.c	2002-05-05 07:04:53.000000000 +0200
+++ linux/drivers/ide/ide-disk.c	2002-05-05 17:39:03.000000000 +0200
@@ -736,7 +736,7 @@
 {
 	if (!drive->driver)
 		return -EPERM;
-	if (!drive->channel->udma)
+	if (!drive->channel->XXX_udma)
 		return -EPERM;
 	if (arg == drive->queue_depth && drive->using_tcq)
 		return 0;
diff -urN linux-2.5.13/drivers/ide/ide-dma.c linux/drivers/ide/ide-dma.c
--- linux-2.5.13/drivers/ide/ide-dma.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/ide-dma.c	2002-05-05 18:07:13.000000000 +0200
@@ -326,30 +326,50 @@
 
 	if (id && (id->capability & 1) && ch->autodma && config_allows_dma) {
 		/* Consult the list of known "bad" drives */
-		if (udma_black_list(drive))
-			return ch->udma(ide_dma_off, drive, NULL);
+		if (udma_black_list(drive)) {
+			udma_enable(drive, 0, 1);
+
+			return 0;
+		}
 
 		/* Enable DMA on any drive that has UltraDMA (mode 6/7/?) enabled */
 		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
-			if ((id->dma_ultra & (id->dma_ultra >> 14) & 2))
-				return ch->udma(ide_dma_on, drive, NULL);
+			if ((id->dma_ultra & (id->dma_ultra >> 14) & 2)) {
+				udma_enable(drive, 1, 1);
+
+				return 0;
+			}
 		/* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */
 		if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
-			if ((id->dma_ultra & (id->dma_ultra >> 11) & 7))
-				return ch->udma(ide_dma_on, drive, NULL);
+			if ((id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
+				udma_enable(drive, 1, 1);
+
+				return 0;
+			}
 		/* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */
 		if (id->field_valid & 4)	/* UltraDMA */
-			if ((id->dma_ultra & (id->dma_ultra >> 8) & 7))
-				return ch->udma(ide_dma_on, drive, NULL);
+			if ((id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
+				udma_enable(drive, 1, 1);
+
+				return 0;
+			}
 		/* Enable DMA on any drive that has mode2 DMA (multi or single) enabled */
 		if (id->field_valid & 2)	/* regular DMA */
-			if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404)
-				return ch->udma(ide_dma_on, drive, NULL);
+			if ((id->dma_mword & 0x404) == 0x404 || (id->dma_1word & 0x404) == 0x404) {
+				udma_enable(drive, 1, 1);
+
+				return 0;
+			}
 		/* Consult the list of known "good" drives */
-		if (udma_white_list(drive))
-			return ch->udma(ide_dma_on, drive, NULL);
+		if (udma_white_list(drive)) {
+			udma_enable(drive, 1, 1);
+
+			return 0;
+		}
 	}
-	return ch->udma(ide_dma_off_quietly, drive, NULL);
+	udma_enable(drive, 0, 0);
+
+	return 0;
 }
 
 /*
@@ -377,20 +397,6 @@
 	return 0;
 }
 
-static void ide_toggle_bounce(struct ata_device *drive, int on)
-{
-	u64 addr = BLK_BOUNCE_HIGH;
-
-	if (on && drive->type == ATA_DISK && drive->channel->highmem) {
-		if (!PCI_DMA_BUS_IS_PHYS)
-			addr = BLK_BOUNCE_ANY;
-		else
-			addr = drive->channel->pci_dev->dma_mask;
-	}
-
-	blk_queue_bounce_limit(&drive->queue, addr);
-}
-
 int ata_start_dma(struct ata_device *drive, struct request *rq)
 {
 	struct ata_channel *ch = drive->channel;
@@ -427,54 +433,9 @@
  * the caller should revert to PIO for the current request.
  * May also be invoked from trm290.c
  */
-int ide_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+int XXX_ide_dmaproc(struct ata_device *drive)
 {
-	struct ata_channel *ch = drive->channel;
-	unsigned long dma_base = ch->dma_base;
-	u8 unit = (drive->select.b.unit & 0x01);
-	unsigned int set_high = 1;
-	u8 dma_stat;
-
-	switch (func) {
-		case ide_dma_off:
-			printk("%s: DMA disabled\n", drive->name);
-		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
-			udma_tcq_enable(drive, 0);
-#endif
-		case ide_dma_on:
-			ide_toggle_bounce(drive, set_high);
-			drive->using_dma = (func == ide_dma_on);
-			if (drive->using_dma) {
-				outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
-#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
-				udma_tcq_enable(drive, 1);
-#endif
-			}
-			return 0;
-		case ide_dma_check:
-			return config_drive_for_dma (drive);
-		case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
-			dma_stat = inb(dma_base+2);
-#if 0  /* do not set unless you know what you are doing */
-			if (dma_stat & 4) {
-				u8 stat = GET_STAT();
-				outb(dma_base+2, dma_stat & 0xE4);
-			}
-#endif
-			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
-		case ide_dma_timeout:
-			printk(KERN_ERR "%s: DMA timeout occured!\n", __FUNCTION__);
-			return 1;
-		case ide_dma_lostirq:
-			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);
-			return 1;
-	}
+	return config_drive_for_dma(drive);
 }
 
 /*
@@ -528,7 +489,7 @@
 		goto dma_alloc_failure;
 	}
 
-	ch->udma = ide_dmaproc;
+	ch->XXX_udma = XXX_ide_dmaproc;
 
 	if (ch->chipset != ide_trm290) {
 		u8 dma_stat = inb(dma_base+2);
@@ -874,10 +835,10 @@
 
 }
 
-void udma_lost_irq(struct ata_device *drive)
+void udma_irq_lost(struct ata_device *drive)
 {
-	if (drive->channel->udma_lost_irq)
-		drive->channel->udma_lost_irq(drive);
+	if (drive->channel->udma_irq_lost)
+		drive->channel->udma_irq_lost(drive);
 }
 
 EXPORT_SYMBOL(udma_enable);
diff -urN linux-2.5.13/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.13/drivers/ide/ide-floppy.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c	2002-05-05 17:43:37.000000000 +0200
@@ -944,10 +944,11 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
 		printk (KERN_ERR "ide-floppy: The floppy wants to issue more interrupts in DMA mode\n");
-		drive->channel->udma(ide_dma_off, drive, NULL);
+		udma_enable(drive, 0, 1);
+
 		return ide_stopped;
 	}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 	bcount.b.high=IN_BYTE (IDE_BCOUNTH_REG);			/* Get the number of bytes to transfer */
 	bcount.b.low=IN_BYTE (IDE_BCOUNTL_REG);			/* on this interrupt */
 	ireason.all=IN_BYTE (IDE_IREASON_REG);
@@ -1119,9 +1120,9 @@
 	bcount.all = min(pc->request_transfer, 63 * 1024);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
-		(void) drive->channel->udma(ide_dma_off, drive, NULL);
-	}
+	if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags))
+		udma_enable(drive, 0, 1);
+
 	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
 		if (test_bit (PC_WRITING, &pc->flags))
 			dma_ok = !udma_write(drive, rq);
diff -urN linux-2.5.13/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c
--- linux-2.5.13/drivers/ide/ide-tape.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/ide-tape.c	2002-05-05 17:41:55.000000000 +0200
@@ -2132,7 +2132,8 @@
 	if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) {
 		printk (KERN_ERR "ide-tape: The tape wants to issue more interrupts in DMA mode\n");
 		printk (KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
-		drive->channel->udma(ide_dma_off, drive, NULL);
+		udma_enable(drive, 0, 1);
+
 		return ide_stopped;
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -2309,7 +2310,7 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (test_and_clear_bit (PC_DMA_ERROR, &pc->flags)) {
 		printk (KERN_WARNING "ide-tape: DMA disabled, reverting to PIO\n");
-		(void) drive->channel->udma(ide_dma_off, drive, NULL);
+		udma_enable(drive, 0, 1);
 	}
 	if (test_bit (PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
 		if (test_bit (PC_WRITING, &pc->flags))
diff -urN linux-2.5.13/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.13/drivers/ide/ide-taskfile.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c	2002-05-05 15:08:48.000000000 +0200
@@ -260,7 +260,7 @@
 {
 	byte stat = 0;
 	if (drive->waiting_for_dma)
-		return drive->channel->udma(ide_dma_test_irq, drive, NULL);
+		return udma_irq_status(drive);
 #if 0
 	/* need to guarantee 400ns since last command was issued */
 	udelay(1);
diff -urN linux-2.5.13/drivers/ide/ns87415.c linux/drivers/ide/ns87415.c
--- linux-2.5.13/drivers/ide/ns87415.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/ns87415.c	2002-05-05 18:08:31.000000000 +0200
@@ -123,18 +123,16 @@
 	return 1;
 }
 
-static int ns87415_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int ns87415_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			if (drive->type != ATA_DISK)
-				return ide_dmaproc(ide_dma_off_quietly, drive, rq);
-			/* Fallthrough... */
-		default:
-			return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+	if (drive->type != ATA_DISK) {
+		udma_enable(drive, 0, 0);
+
+		return 0;
 	}
+	return XXX_ide_dmaproc(drive);
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 void __init ide_init_ns87415(struct ata_channel *hwif)
 {
@@ -233,7 +231,7 @@
 		hwif->udma_stop = ns87415_udma_stop;
 		hwif->udma_read = ns87415_udma_read;
 		hwif->udma_write = ns87415_udma_write;
-		hwif->udma = ns87415_dmaproc;
+		hwif->XXX_udma = ns87415_dmaproc;
 	}
 #endif
 
diff -urN linux-2.5.13/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- linux-2.5.13/drivers/ide/pdc202xx.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/pdc202xx.c	2002-05-05 18:10:02.000000000 +0200
@@ -829,7 +829,7 @@
 
 	if (jumpbit) {
 		if (drive->type != ATA_DISK)
-			return ide_dma_off_quietly;
+			return 0;
 		if (id->capability & 4) {	/* IORDY_EN & PREFETCH_EN */
 			OUT_BYTE((iordy + adj), indexreg);
 			OUT_BYTE((IN_BYTE(datareg)|0x03), datareg);
@@ -873,13 +873,13 @@
 				pci_write_config_byte(dev, (drive_pci), test2|SYNC_ERRDY_EN);
 			break;
 		default:
-			return ide_dma_off;
+			return 0;
 	}
 
 chipset_is_set:
 
 	if (drive->type != ATA_DISK)
-		return ide_dma_off_quietly;
+		return 0;
 
 	pci_read_config_byte(dev, (drive_pci), &AP);
 	if (id->capability & 4)	/* IORDY_EN */
@@ -907,39 +907,41 @@
 		/* restore original pci-config space */
 		if (!jumpbit)
 			pci_write_config_dword(dev, drive_pci, drive_conf);
-		return ide_dma_off_quietly;
+		return 0;
 	}
 
 	outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
 	(void) hwif->speedproc(drive, speed);
 
-	return ((int)	((id->dma_ultra >> 14) & 3) ? ide_dma_on :
-			((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	return ((int)	((id->dma_ultra >> 14) & 3) ? 1 :
+			((id->dma_ultra >> 11) & 7) ? 1 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+			((id->dma_1word >> 8) & 7) ? 1 :
+						     0);
 }
 
 static int config_drive_xfer_rate (ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
 	struct ata_channel *hwif = drive->channel;
-	ide_dma_action_t dma_func = ide_dma_off_quietly;
+	int on = 0;
+	int verbose = 1;
 
 	if (id && (id->capability & 1) && hwif->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			goto fast_ata_pio;
 		}
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 		if (id->field_valid & 4) {
 			if (id->dma_ultra & 0x007F) {
 				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive, 1);
+				on = config_chipset_for_dma(drive, 1);
 				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
+				    (!on))
 					goto try_dma_modes;
 			}
 		} else if (id->field_valid & 2) {
@@ -947,8 +949,8 @@
 			if ((id->dma_mword & 0x0007) ||
 			    (id->dma_1word & 0x0007)) {
 				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive, 0);
-				if (dma_func != ide_dma_on)
+				on = config_chipset_for_dma(drive, 0);
+				if (!on)
 					goto no_dma_set;
 			}
 		} else if (udma_white_list(drive)) {
@@ -956,20 +958,23 @@
 				goto no_dma_set;
 			}
 			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive, 0);
-			if (dma_func != ide_dma_on)
+			on = config_chipset_for_dma(drive, 0);
+			if (!on)
 				goto no_dma_set;
 		} else {
 			goto fast_ata_pio;
 		}
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 no_dma_set:
 		(void) config_chipset_for_pio(drive, 5);
 	}
 
-	return drive->channel->udma(dma_func, drive, NULL);
+	udma_enable(drive, on, verbose);
+
+	return 0;
 }
 
 int pdc202xx_quirkproc (ide_drive_t *drive)
@@ -1065,20 +1070,17 @@
 	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
 }
 
-/*
- * pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
- */
-int pdc202xx_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int pdc202xx_udma_irq_status(struct ata_device *drive)
 {
-	u8 dma_stat	= 0;
-	u8 sc1d		= 0;
-	u8 newchip	= 0;
-	u8 clock	= 0;
+	struct ata_channel *ch = drive->channel;
+	u8 dma_stat = 0;
+	u8 sc1d	= 0;
+	u8 newchip = 0;
+	u8 clock = 0;
 	u8 hardware48hack = 0;
-	struct ata_channel *hwif = drive->channel;
-	struct pci_dev *dev	= hwif->pci_dev;
-	unsigned long high_16	= pci_resource_start(dev, 4);
-	unsigned long dma_base	= hwif->dma_base;
+	struct pci_dev *dev = ch->pci_dev;
+	unsigned long high_16 = pci_resource_start(dev, 4);
+	unsigned long dma_base = ch->dma_base;
 
 	switch (dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20275:
@@ -1097,36 +1099,45 @@
 			break;
 	}
 
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
-			dma_stat = IN_BYTE(dma_base+2);
-			if (newchip)
-				return (dma_stat & 4) == 4;
-
-			sc1d = IN_BYTE(high_16 + 0x001d);
-			if (drive->channel->unit) {
-				if ((sc1d & 0x50) == 0x50) goto somebody_else;
-				else if ((sc1d & 0x40) == 0x40)
-					return (dma_stat & 4) == 4;
-			} else {
-				if ((sc1d & 0x05) == 0x05) goto somebody_else;
-				else if ((sc1d & 0x04) == 0x04)
-					return (dma_stat & 4) == 4;
-			}
-somebody_else:
-			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
-		case ide_dma_lostirq:
-		case ide_dma_timeout:
-			if (drive->channel->resetproc != NULL)
-				drive->channel->resetproc(drive);
-		default:
-			break;
+	dma_stat = IN_BYTE(dma_base + 2);
+	if (newchip)
+		return (dma_stat & 4) == 4;
+
+	sc1d = IN_BYTE(high_16 + 0x001d);
+	if (ch->unit) {
+		if ((sc1d & 0x50) == 0x50) goto somebody_else;
+		else if ((sc1d & 0x40) == 0x40)
+			return (dma_stat & 4) == 4;
+	} else {
+		if ((sc1d & 0x05) == 0x05) goto somebody_else;
+		else if ((sc1d & 0x04) == 0x04)
+			return (dma_stat & 4) == 4;
 	}
-	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+somebody_else:
+	return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+static void pdc202xx_udma_timeout(struct ata_device *drive)
+{
+	if (!drive->channel->resetproc)
+		return;
+	/* Assume naively that resetting the drive may help. */
+	drive->channel->resetproc(drive);
+}
+
+static void pdc202xx_udma_irq_lost(struct ata_device *drive)
+{
+	if (!drive->channel->resetproc)
+		return;
+	/* Assume naively that resetting the drive may help. */
+	drive->channel->resetproc(drive);
+}
+
+static int pdc202xx_dmaproc(struct ata_device *drive)
+{
+	return config_drive_xfer_rate(drive);
+}
+#endif
 
 void pdc202xx_new_reset (ide_drive_t *drive)
 {
@@ -1334,7 +1345,10 @@
 	if (hwif->dma_base) {
 		hwif->udma_start = pdc202xx_udma_start;
 		hwif->udma_stop = pdc202xx_udma_stop;
-		hwif->udma = pdc202xx_dmaproc;
+		hwif->udma_irq_status = pdc202xx_udma_irq_status;
+		hwif->udma_irq_lost = pdc202xx_udma_irq_lost;
+		hwif->udma_timeout = pdc202xx_udma_timeout;
+		hwif->XXX_udma = pdc202xx_dmaproc;
 		hwif->highmem = 1;
 		if (!noautodma)
 			hwif->autodma = 1;
diff -urN linux-2.5.13/drivers/ide/pdcadma.c linux/drivers/ide/pdcadma.c
--- linux-2.5.13/drivers/ide/pdcadma.c	2002-05-03 02:22:45.000000000 +0200
+++ linux/drivers/ide/pdcadma.c	2002-05-05 18:10:46.000000000 +0200
@@ -58,15 +58,11 @@
 /*
  * This initiates/aborts (U)DMA read/write operations on a drive.
  */
-int pdcadma_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int pdcadma_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			func = ide_dma_off_quietly;
-		default:
-			break;
-	}
-	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+	udma_enable(drive, 0, 0);
+
+	return 0;
 }
 #endif
 
@@ -96,7 +92,7 @@
 //	hwif->speedproc = &pdcadma_tune_chipset;
 
 //	if (hwif->dma_base) {
-//		hwif->dmaproc = &pdcadma_dmaproc;
+//		hwif->XXX_dmaproc = &pdcadma_dmaproc;
 //		hwif->autodma = 1;
 //	}
 }
diff -urN linux-2.5.13/drivers/ide/piix.c linux/drivers/ide/piix.c
--- linux-2.5.13/drivers/ide/piix.c	2002-05-03 02:22:50.000000000 +0200
+++ linux/drivers/ide/piix.c	2002-05-05 18:12:04.000000000 +0200
@@ -376,38 +376,26 @@
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 
-/*
- * piix_dmaproc() is a callback from upper layers that can do
- * a lot, but we use it for DMA/PIO tuning only, delegating everything
- * else to the default ide_dmaproc().
- */
-
-int piix_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+int piix_dmaproc(struct ata_device *drive)
 {
+	short w80 = drive->channel->udma_four;
 
-	if (func == ide_dma_check) {
-
-		short w80 = drive->channel->udma_four;
-
-		short speed = ata_timing_mode(drive,
-			XFER_PIO | XFER_EPIO | 
+	short speed = ata_timing_mode(drive,
+			XFER_PIO | XFER_EPIO |
 			(piix_config->flags & PIIX_NODMA ? 0 : (XFER_SWDMA | XFER_MWDMA |
 			(piix_config->flags & PIIX_UDMA ? XFER_UDMA : 0) |
 			(w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 ? XFER_UDMA_66 : 0) |
 			(w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 ? XFER_UDMA_100 : 0) |
 			(w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_133 ? XFER_UDMA_133 : 0))));
 
-		piix_set_drive(drive, speed);
+	piix_set_drive(drive, speed);
 
-		func = (drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO)
-			? ide_dma_on : ide_dma_off_quietly;
+	udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
 
-	}
-
-	return ide_dmaproc(func, drive, rq);
+	return 0;
 }
 
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * The initialization callback. Here we determine the IDE chip type
@@ -566,13 +554,13 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
 		hwif->highmem = 1;
-		hwif->udma = piix_dmaproc;
-#ifdef CONFIG_IDEDMA_AUTO
+		hwif->XXX_udma = piix_dmaproc;
+# ifdef CONFIG_IDEDMA_AUTO
 		if (!noautodma)
 			hwif->autodma = 1;
-#endif
+# endif
 	}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 }
 
 /*
diff -urN linux-2.5.13/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c
--- linux-2.5.13/drivers/ide/serverworks.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/serverworks.c	2002-05-05 18:09:24.000000000 +0200
@@ -424,31 +424,33 @@
 
 	(void) svwks_tune_chipset(drive, speed);
 
-	return ((int)	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	return ((int)	((id->dma_ultra >> 11) & 7) ? 1 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+			((id->dma_1word >> 8) & 7) ? 1 :
+						     0);
 }
 
 static int config_drive_xfer_rate(struct ata_device *drive)
 {
 	struct hd_driveid *id = drive->id;
-	ide_dma_action_t dma_func = ide_dma_on;
+	int on = 1;
+	int verbose = 1;
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			goto fast_ata_pio;
 		}
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 		if (id->field_valid & 4) {
 			if (id->dma_ultra & 0x003F) {
 				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive);
+				on = config_chipset_for_dma(drive);
 				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
+				    (!on))
 					goto try_dma_modes;
 			}
 		} else if (id->field_valid & 2) {
@@ -456,8 +458,8 @@
 			if ((id->dma_mword & 0x0007) ||
 			    (id->dma_1word & 0x007)) {
 				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive);
-				if (dma_func != ide_dma_on)
+				on = config_chipset_for_dma(drive);
+				if (!on)
 					goto no_dma_set;
 			}
 		} else if (udma_white_list(drive)) {
@@ -465,19 +467,23 @@
 				goto no_dma_set;
 			}
 			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive);
-			if (dma_func != ide_dma_on)
+			on = config_chipset_for_dma(drive);
+			if (!on)
 				goto no_dma_set;
 		} else {
 			goto fast_ata_pio;
 		}
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 no_dma_set:
 		config_chipset_for_pio(drive);
 	}
-	return drive->channel->udma(dma_func, drive, NULL);
+
+	udma_enable(drive, on, verbose);
+
+	return 0;
 }
 
 static int svwks_udma_stop(struct ata_device *drive)
@@ -523,18 +529,11 @@
 	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
 }
 
-static int svwks_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int svwks_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			return config_drive_xfer_rate(drive);
-		default:
-			break;
-	}
-	/* Other cases are done by generic IDE-DMA code. */
-	return ide_dmaproc(func, drive, rq);
+	return config_drive_xfer_rate(drive);
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 unsigned int __init pci_init_svwks(struct pci_dev *dev)
 {
@@ -655,7 +654,7 @@
 			hwif->autodma = 1;
 #endif
 		hwif->udma_stop = svwks_udma_stop;
-		hwif->udma = svwks_dmaproc;
+		hwif->XXX_udma = svwks_dmaproc;
 		hwif->highmem = 1;
 	} else {
 		hwif->autodma = 0;
diff -urN linux-2.5.13/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c
--- linux-2.5.13/drivers/ide/sis5513.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/sis5513.c	2002-05-05 18:12:55.000000000 +0200
@@ -556,7 +556,7 @@
 		case 1:		drive_pci = 0x42; break;
 		case 2:		drive_pci = 0x44; break;
 		case 3:		drive_pci = 0x46; break;
-		default:	return ide_dma_off;
+		default:	return 0;
 	}
 
 #ifdef BROKEN_LEVEL
@@ -663,39 +663,41 @@
 	else if (id->dma_1word & 0x0001)
 		speed = XFER_SW_DMA_0;
 	else
-		return ((int) ide_dma_off_quietly);
+		return 0;
 
 	outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
 
 	sis5513_tune_chipset(drive, speed);
 
-	return ((int)	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
-			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
-			((id->dma_mword >> 8) & 7) ? ide_dma_on :
-			((id->dma_1word >> 8) & 7) ? ide_dma_on :
-						     ide_dma_off_quietly);
+	return ((int)	((id->dma_ultra >> 11) & 7) ? 1 :
+			((id->dma_ultra >> 8) & 7) ? 1 :
+			((id->dma_mword >> 8) & 7) ? 1 :
+			((id->dma_1word >> 8) & 7) ? 1 :
+						     0);
 }
 
 static int config_drive_xfer_rate (ide_drive_t *drive)
 {
-	struct hd_driveid *id		= drive->id;
-	ide_dma_action_t dma_func	= ide_dma_off_quietly;
+	struct hd_driveid *id = drive->id;
+	int on = 0;
+	int verbose = 1;
 
 	config_chipset_for_pio(drive, 5);
 
 	if (id && (id->capability & 1) && drive->channel->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			goto fast_ata_pio;
 		}
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 		if (id->field_valid & 4) {
 			if (id->dma_ultra & 0x003F) {
 				/* Force if Capable UltraDMA */
-				dma_func = config_chipset_for_dma(drive, 1);
+				on = config_chipset_for_dma(drive, 1);
 				if ((id->field_valid & 2) &&
-				    (dma_func != ide_dma_on))
+				    (!on))
 					goto try_dma_modes;
 			}
 		} else if (id->field_valid & 2) {
@@ -703,43 +705,40 @@
 			if ((id->dma_mword & 0x0007) ||
 			    (id->dma_1word & 0x0007)) {
 				/* Force if Capable regular DMA modes */
-				dma_func = config_chipset_for_dma(drive, 0);
-				if (dma_func != ide_dma_on)
+				on = config_chipset_for_dma(drive, 0);
+				if (!on)
 					goto no_dma_set;
 			}
 		} else if ((udma_white_list(drive)) &&
 			   (id->eide_dma_time > 150)) {
 			/* Consult the list of known "good" drives */
-			dma_func = config_chipset_for_dma(drive, 0);
-			if (dma_func != ide_dma_on)
+			on = config_chipset_for_dma(drive, 0);
+			if (!on)
 				goto no_dma_set;
 		} else {
 			goto fast_ata_pio;
 		}
 	} else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-		dma_func = ide_dma_off_quietly;
+		on = 0;
+		verbose = 0;
 no_dma_set:
 		(void) config_chipset_for_pio(drive, 5);
 	}
 
-	return drive->channel->udma(dma_func, drive, NULL);
+	udma_enable(drive, on, verbose);
+
+	return 0;
 }
 
-/* initiates/aborts (U)DMA read/write operations on a drive. */
-int sis5513_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int sis5513_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-		case ide_dma_check:
-			config_drive_art_rwp(drive);
-			config_art_rwp_pio(drive, 5);
-			return config_drive_xfer_rate(drive);
-		default:
-			break;
-	}
-	return ide_dmaproc(func, drive, rq);	/* use standard DMA stuff */
+	config_drive_art_rwp(drive);
+	config_art_rwp_pio(drive, 5);
+
+	return config_drive_xfer_rate(drive);
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /* Chip detection and general config */
 unsigned int __init pci_init_sis5513(struct pci_dev *dev)
@@ -852,7 +851,7 @@
 		if (chipset_family > ATA_16) {
 			hwif->autodma = noautodma ? 0 : 1;
 			hwif->highmem = 1;
-			hwif->udma = sis5513_dmaproc;
+			hwif->XXX_udma = sis5513_dmaproc;
 		} else {
 #endif
 			hwif->autodma = 0;
diff -urN linux-2.5.13/drivers/ide/sl82c105.c linux/drivers/ide/sl82c105.c
--- linux-2.5.13/drivers/ide/sl82c105.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/sl82c105.c	2002-05-05 18:13:41.000000000 +0200
@@ -114,9 +114,9 @@
  * Check to see if the drive and
  * chipset is capable of DMA mode
  */
-static int sl82c105_check_drive(ide_drive_t *drive, struct request *rq)
+static int sl82c105_check_drive(ide_drive_t *drive)
 {
-	ide_dma_action_t dma_func = ide_dma_off_quietly;
+	int on = 0;
 
 	do {
 		struct hd_driveid *id = drive->id;
@@ -130,45 +130,38 @@
 
 		/* Consult the list of known "bad" drives */
 		if (udma_black_list(drive)) {
-			dma_func = ide_dma_off;
+			on = 0;
 			break;
 		}
 
 		if (id->field_valid & 2) {
 			if  (id->dma_mword & 7 || id->dma_1word & 7)
-				dma_func = ide_dma_on;
+				on = 1;
 			break;
 		}
 
 		if (udma_white_list(drive)) {
-			dma_func = ide_dma_on;
+			on = 1;
 			break;
 		}
 	} while (0);
+	if (on)
+		config_for_dma(drive);
+	else
+		config_for_pio(drive, 4, 0);
+
+	udma_enable(drive, on, 0);
+
 
-	return drive->channel->udma(dma_func, drive, rq);
+	return 0;
 }
 
 /*
  * Our own dmaproc, only to intercept ide_dma_check
  */
-static int sl82c105_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int sl82c105_dmaproc(struct ata_device *drive)
 {
-	switch (func) {
-	case ide_dma_check:
-		return sl82c105_check_drive(drive, rq);
-	case ide_dma_on:
-		if (config_for_dma(drive))
-			func = ide_dma_off;
-		/* fall through */
-	case ide_dma_off_quietly:
-	case ide_dma_off:
-		config_for_pio(drive, 4, 0);
-		break;
-	default:
-		break;
-	}
-	return ide_dmaproc(func, drive, rq);
+	return sl82c105_check_drive(drive);
 }
 
 /*
@@ -252,10 +245,10 @@
 	}
 	outb(dma_state, dma_base + 2);
 
-	hwif->udma = NULL;
+	hwif->XXX_udma = NULL;
 	ide_setup_dma(hwif, dma_base, 8);
-	if (hwif->udma)
-		hwif->udma = sl82c105_dmaproc;
+	if (hwif->XXX_udma)
+		hwif->XXX_udma = sl82c105_dmaproc;
 }
 
 /*
diff -urN linux-2.5.13/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.13/drivers/ide/trm290.c	2002-05-05 07:13:21.000000000 +0200
+++ linux/drivers/ide/trm290.c	2002-05-05 18:14:33.000000000 +0200
@@ -235,18 +235,14 @@
 	return do_udma(0, drive, rq);
 }
 
-static int trm290_dmaproc (ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int trm290_udma_irq_status(struct ata_device *drive)
 {
-	struct ata_channel *ch = drive->channel;
+	return (inw(drive->channel->dma_base + 2) == 0x00ff);
+}
 
-	switch (func) {
-		case ide_dma_test_irq:
-			return (inw(ch->dma_base + 2) == 0x00ff);
-		default:
-			return ide_dmaproc(func, drive, rq);
-	}
-	trm290_prepare_drive(drive, 0);	/* select PIO xfer */
-	return 1;
+static int trm290_dmaproc(struct ata_device *drive)
+{
+	return XXX_ide_dmaproc(drive);
 }
 #endif
 
@@ -304,7 +300,8 @@
 	hwif->udma_stop = trm290_udma_stop;
 	hwif->udma_read = trm290_udma_read;
 	hwif->udma_write = trm290_udma_write;
-	hwif->udma = trm290_dmaproc;
+	hwif->udma_irq_status = trm290_udma_irq_status;
+	hwif->XXX_udma = trm290_dmaproc;
 #endif
 
 	hwif->selectproc = &trm290_selectproc;
diff -urN linux-2.5.13/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c
--- linux-2.5.13/drivers/ide/via82cxxx.c	2002-05-03 02:22:47.000000000 +0200
+++ linux/drivers/ide/via82cxxx.c	2002-05-05 18:15:37.000000000 +0200
@@ -356,37 +356,24 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
-
-/*
- * via82cxxx_dmaproc() is a callback from upper layers that can do
- * a lot, but we use it for DMA/PIO tuning only, delegating everything
- * else to the default ide_dmaproc().
- */
-
-int via82cxxx_dmaproc(ide_dma_action_t func, struct ata_device *drive, struct request *rq)
+static int via82cxxx_dmaproc(struct ata_device *drive)
 {
+	short w80 = drive->channel->udma_four;
 
-	if (func == ide_dma_check) {
-
-		short w80 = drive->channel->udma_four;
-
-		short speed = ata_timing_mode(drive,
+	short speed = ata_timing_mode(drive,
 			XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
 			(via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
 			(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
 			(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
 			(w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
 
-		via_set_drive(drive, speed);
+	via_set_drive(drive, speed);
 
-		func = (drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO)
-			? ide_dma_on : ide_dma_off_quietly;
-	}
+	udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
 
-	return ide_dmaproc(func, drive, rq);
+	return 0;
 }
-
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 
 /*
  * The initialization callback. Here we determine the IDE chip type
@@ -546,13 +533,13 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
 		hwif->highmem = 1;
-		hwif->udma = &via82cxxx_dmaproc;
-#ifdef CONFIG_IDEDMA_AUTO
+		hwif->XXX_udma = &via82cxxx_dmaproc;
+# ifdef CONFIG_IDEDMA_AUTO
 		if (!noautodma)
 			hwif->autodma = 1;
-#endif
+# endif
 	}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif
 }
 
 /*
diff -urN linux-2.5.13/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.13/include/linux/ide.h	2002-05-05 07:13:21.000000000 +0200
+++ linux/include/linux/ide.h	2002-05-05 17:54:04.000000000 +0200
@@ -374,15 +374,6 @@
 	int		max_depth;
 } ide_drive_t;
 
-typedef enum {
-	ide_dma_check,
-	ide_dma_on, ide_dma_off,
-	ide_dma_off_quietly,
-	ide_dma_test_irq,
-	ide_dma_lostirq,
-	ide_dma_timeout
-} ide_dma_action_t;
-
 enum {
 	ATA_PRIMARY	= 0,
 	ATA_SECONDARY	= 1
@@ -432,7 +423,7 @@
 	void (*atapi_read)(struct ata_device *, void *, unsigned int);
 	void (*atapi_write)(struct ata_device *, void *, unsigned int);
 
-	int (*udma)(ide_dma_action_t, struct ata_device *, struct request *);
+	int (*XXX_udma)(struct ata_device *);
 
 	int (*udma_start) (struct ata_device *, struct request *rq);
 	int (*udma_stop) (struct ata_device *);
@@ -443,7 +434,7 @@
 	int (*udma_irq_status) (struct ata_device *);
 
 	void (*udma_timeout) (struct ata_device *);
-	void (*udma_lost_irq) (struct ata_device *);
+	void (*udma_irq_lost) (struct ata_device *);
 
 	unsigned int	*dmatable_cpu;	/* dma physical region descriptor table (cpu view) */
 	dma_addr_t	dmatable_dma;	/* dma physical region descriptor table (dma view) */
@@ -885,7 +876,7 @@
 extern int udma_black_list(struct ata_device *);
 extern int udma_white_list(struct ata_device *);
 extern void udma_timeout(struct ata_device *);
-extern void udma_lost_irq(struct ata_device *);
+extern void udma_irq_lost(struct ata_device *);
 extern int udma_start(struct ata_device *, struct request *rq);
 extern int udma_stop(struct ata_device *);
 extern int udma_read(struct ata_device *, struct request *rq);
@@ -899,7 +890,7 @@
 
 extern ide_startstop_t ide_dma_intr(struct ata_device *, struct request *);
 extern int check_drive_lists(struct ata_device *, int good_bad);
-extern int ide_dmaproc(ide_dma_action_t func, struct ata_device *, struct request *);
+extern int XXX_ide_dmaproc(struct ata_device *);
 extern void ide_release_dma(struct ata_channel *);
 extern void ide_setup_dma(struct ata_channel *,	unsigned long, unsigned int) __init;
 extern int ata_start_dma(struct ata_device *, struct request *rq);

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

* Re: [PATCH] 2.5.13 IDE 52
  2002-05-05 17:09                     ` Jens Axboe
@ 2002-05-05 16:16                       ` Martin Dalecki
  0 siblings, 0 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-05-05 16:16 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Linus Torvalds, linux-kernel

Uz.ytkownik Jens Axboe napisa?:
> On Sun, May 05 2002, Martin Dalecki wrote:
> 
>>- Split up the TCQ UDMA handling stuff in to proper functions. Jens must has
>>  been dreaming as he introduced them ;-).
> 
> 
> This was pending stuff, and why I wrote that the start command tcq = 1
> stuff was a gross hack.

Sure I just did it in one go with the rest of DMA handling changes.
I just wan'ted to get over with this.

>>-		int tcq = 0;
>> 
>> 		if (!drive->using_dma)
>> 			return ide_started;
>> 
>> 		/* for dma commands we don't set the handler */
>>-		if (args->taskfile.command == WIN_WRITEDMA || args->taskfile.command == WIN_WRITEDMA_EXT)
>>+		if (args->taskfile.command == WIN_WRITEDMA
>>+		 || args->taskfile.command == WIN_WRITEDMA_EXT)
>> 			dma_act = ide_dma_write;
>>-		else if (args->taskfile.command == WIN_READDMA || args->taskfile.command == WIN_READDMA_EXT)
>>+		else if (args->taskfile.command == WIN_READDMA
>>+		      || args->taskfile.command == WIN_READDMA_EXT)
>> 			dma_act = ide_dma_read;
>>-		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT) {
>>-			tcq = 1;
>>-			dma_act = ide_dma_write_queued;
>>-		} else if (args->taskfile.command == WIN_READDMA_QUEUED || args->taskfile.command == WIN_READDMA_QUEUED_EXT) {
>>-			tcq = 1;
>>-			dma_act = ide_dma_read_queued;
>>-		} else {
>>+#ifdef CONFIG_BLK_DEV_IDE_TCQ
>>+		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
>>+		      || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
>>+		      || args->taskfile.command == WIN_READDMA_QUEUED
>>+		      || args->taskfile.command == WIN_READDMA_QUEUED_EXT)
>>+			return udma_tcq_taskfile(drive, rq);
>>+#endif
>>+		else {
>> 			printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
>> 			return ide_stopped;
>> 		}
>> 
>>-		/*
>>-		 * FIXME: this is a gross hack, need to unify tcq dma proc and
>>-		 * regular dma proc -- basically split stuff that needs to act
>>-		 * on a request from things like ide_dma_check etc.
>>-		 */
>>-		if (tcq)
>>-			return drive->channel->udma(dma_act, drive, rq);
>>-		else {
>>-			if (drive->channel->udma(dma_act, drive, rq))
>>-				return ide_stopped;
>>-		}
>>+
>>+		if (drive->channel->udma(dma_act, drive, rq))
>>+			return ide_stopped;
> 
> 
> This is still ugly, IMHO. What I wanted was to split the udma->
> function into two parts, one that acts on a request (ide_dma_read,
> ide_dma_being, etc -- and then also ide_dma_read_queued) ad one that
> does the silly stuff like ide_dma_check etc. Then unify the tcq and
> non-tcq stuff so that udma_rw->(dma_act, drive, rq) always returns
> ide_started or ide_stopped (or ide_released) and kill the #ifdef above.
> 
> I don't think udma_tcq_taskfile() should be public like this, and btw I
> think the name really SUCKS! :-). ata_tcq_dma() is much better for
> instance, even though it should be a private stratey. BTW, this goes for
> all your tcq.c renaming.

Sure it sucks. The most sucks the fact that the trasnfer functions
should be folded in the generic context functions. I know.
I have choosen the udma prefix becouse ata_udma wouldn't contain much more
information and just stayed consistant with it for the tcq stuff as well.
Now one can at least understand the work flow of the DMA stuff I think
so cleaning it firther should be easier now.

Please consided it all as a step in between and after reading 54 you should
see where it's going...


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

* Re: [PATCH] 2.5.13 IDE 52
  2002-05-05 15:54                   ` [PATCH] 2.5.13 IDE 52 Martin Dalecki
@ 2002-05-05 17:09                     ` Jens Axboe
  2002-05-05 16:16                       ` Martin Dalecki
  0 siblings, 1 reply; 48+ messages in thread
From: Jens Axboe @ 2002-05-05 17:09 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, linux-kernel

On Sun, May 05 2002, Martin Dalecki wrote:
> - Split up the TCQ UDMA handling stuff in to proper functions. Jens must has
>   been dreaming as he introduced them ;-).

This was pending stuff, and why I wrote that the start command tcq = 1
stuff was a gross hack.

> -		int tcq = 0;
>  
>  		if (!drive->using_dma)
>  			return ide_started;
>  
>  		/* for dma commands we don't set the handler */
> -		if (args->taskfile.command == WIN_WRITEDMA || args->taskfile.command == WIN_WRITEDMA_EXT)
> +		if (args->taskfile.command == WIN_WRITEDMA
> +		 || args->taskfile.command == WIN_WRITEDMA_EXT)
>  			dma_act = ide_dma_write;
> -		else if (args->taskfile.command == WIN_READDMA || args->taskfile.command == WIN_READDMA_EXT)
> +		else if (args->taskfile.command == WIN_READDMA
> +		      || args->taskfile.command == WIN_READDMA_EXT)
>  			dma_act = ide_dma_read;
> -		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT) {
> -			tcq = 1;
> -			dma_act = ide_dma_write_queued;
> -		} else if (args->taskfile.command == WIN_READDMA_QUEUED || args->taskfile.command == WIN_READDMA_QUEUED_EXT) {
> -			tcq = 1;
> -			dma_act = ide_dma_read_queued;
> -		} else {
> +#ifdef CONFIG_BLK_DEV_IDE_TCQ
> +		else if (args->taskfile.command == WIN_WRITEDMA_QUEUED
> +		      || args->taskfile.command == WIN_WRITEDMA_QUEUED_EXT
> +		      || args->taskfile.command == WIN_READDMA_QUEUED
> +		      || args->taskfile.command == WIN_READDMA_QUEUED_EXT)
> +			return udma_tcq_taskfile(drive, rq);
> +#endif
> +		else {
>  			printk("ata_taskfile: unknown command %x\n", args->taskfile.command);
>  			return ide_stopped;
>  		}
>  
> -		/*
> -		 * FIXME: this is a gross hack, need to unify tcq dma proc and
> -		 * regular dma proc -- basically split stuff that needs to act
> -		 * on a request from things like ide_dma_check etc.
> -		 */
> -		if (tcq)
> -			return drive->channel->udma(dma_act, drive, rq);
> -		else {
> -			if (drive->channel->udma(dma_act, drive, rq))
> -				return ide_stopped;
> -		}
> +
> +		if (drive->channel->udma(dma_act, drive, rq))
> +			return ide_stopped;

This is still ugly, IMHO. What I wanted was to split the udma->
function into two parts, one that acts on a request (ide_dma_read,
ide_dma_being, etc -- and then also ide_dma_read_queued) ad one that
does the silly stuff like ide_dma_check etc. Then unify the tcq and
non-tcq stuff so that udma_rw->(dma_act, drive, rq) always returns
ide_started or ide_stopped (or ide_released) and kill the #ifdef above.

I don't think udma_tcq_taskfile() should be public like this, and btw I
think the name really SUCKS! :-). ata_tcq_dma() is much better for
instance, even though it should be a private stratey. BTW, this goes for
all your tcq.c renaming.

-- 
Jens Axboe


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

* Re: [PATCH] 2.5.13 IDE 53
  2002-05-06  9:53                     ` Russell King
@ 2002-05-06  8:55                       ` Martin Dalecki
  2002-05-06 23:48                         ` jw schultz
  0 siblings, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-05-06  8:55 UTC (permalink / raw)
  To: Russell King; +Cc: Linus Torvalds, linux-kernel

Uz.ytkownik Russell King napisa?:
> On Sun, May 05, 2002 at 05:55:45PM +0200, Martin Dalecki wrote:
> 
>>- Start splitting the functions for host chip handling in to separate entities.
>>   This change is quite sensitive and may cause some trouble but it's for
>>   certain worth it anyway, because it should for example provide a much better
>>   infrastructure for th handling of different architectures.
> 
> 
> Are you at some point going to add the black/white lists back into
> icside.c that you removed shortly after you took over the IDE
> maintainence?  I've been patiently waiting to see what was going to
> happen to them.

What about using the generic udma_black_list() and udma_white_list()?
Just tell so and I could prvide the code for testing.


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

* Re: [PATCH] 2.5.13 IDE 53
  2002-05-05 15:55                   ` [PATCH] 2.5.13 IDE 53 Martin Dalecki
@ 2002-05-06  9:53                     ` Russell King
  2002-05-06  8:55                       ` Martin Dalecki
  0 siblings, 1 reply; 48+ messages in thread
From: Russell King @ 2002-05-06  9:53 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Linus Torvalds, linux-kernel

On Sun, May 05, 2002 at 05:55:45PM +0200, Martin Dalecki wrote:
> - Start splitting the functions for host chip handling in to separate entities.
>    This change is quite sensitive and may cause some trouble but it's for
>    certain worth it anyway, because it should for example provide a much better
>    infrastructure for th handling of different architectures.

Are you at some point going to add the black/white lists back into
icside.c that you removed shortly after you took over the IDE
maintainence?  I've been patiently waiting to see what was going to
happen to them.

-- 
Russell King (rmk@arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html


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

* Re: [PATCH] 2.5.13 IDE 53
  2002-05-06  8:55                       ` Martin Dalecki
@ 2002-05-06 23:48                         ` jw schultz
  0 siblings, 0 replies; 48+ messages in thread
From: jw schultz @ 2002-05-06 23:48 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Russell King, Linus Torvalds, linux-kernel

On Mon, May 06, 2002 at 10:55:01AM +0200, Martin Dalecki wrote:
> Uz.ytkownik Russell King napisa?:
> > 
> > Are you at some point going to add the black/white lists back into
> > icside.c that you removed shortly after you took over the IDE
> > maintainence?  I've been patiently waiting to see what was going to
> > happen to them.
> 
> What about using the generic udma_black_list() and udma_white_list()?
> Just tell so and I could prvide the code for testing.
> 

Just a thought so i'll throw it out there.  I'm just a
spectator so far on this issue as i haven't yet been burned
by it. 

There seem to be several black|white lists floating around.
This would appear to be an ongoing task keeping up with the
new and obscure hardware to cope with capabilities and
compatibilities and often requires kernel or module rebuilds
and means ever-growing lists.

For some time i have been thinking that a common black|white
list API might be worthwhile.  Along with this would be the
ability to examine and modify, or at least add to, the lists
at runtime.  For hot-plug some of the black|white checks
might even be better handled by a daemon that can read an
external file.  That would facilitate testing and allow
people to add support for their hot-plug devices without
reboot.


-- 
________________________________________________________________
	J.W. Schultz            Pegasystems Technologies
	email address:		jw@pegasys.ws

		Remember Cernan and Schmitt

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

* Re: [PATCH 2.5.13 IDE 54
  2002-05-07 12:52                     ` Paul Mackerras
@ 2002-05-07 12:06                       ` Martin Dalecki
  2002-05-07 14:40                         ` benh
  2002-05-07 14:07                       ` Alan Cox
  1 sibling, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-05-07 12:06 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linux-kernel

Uz.ytkownik Paul Mackerras napisa?:
> Martin Dalecki writes:
> 
> 
>>Sun May  5 16:32:22 CEST 2002 ide-clean-54
>>
>>- Finish the changes from patch 53. ide_dma_actaion_t is gone now as well as
>>   whole hidden code paths associated with it. I hope I didn't mess too many
>>   things up with this, since the sheer size of the changes make them sensitive.
> 
> 
> I'm wondering how you would suggest that I change ide-pmac.c now so
> that it compiles and works again.
> 
> With this patch we have calls to udma_enable scattered throughout
> ide.c, and udma_enable assumes that it is to do its stuff by poking
> particular I/O ports.  You seem to have taken away the ability to have
> a chipset provide its own methods for setting up, enabling and
> disabling DMA.
> 
> The comment above udma_enable seems to indicate that you think it
> should be ifdef'd per-architecture.  That won't work for us (besides
> being ugly), because we can have two ATA host adaptors in the one
> machine that need to be programmed quite differently.  Consider for
> instance a powermac with the built-in IDE interface (which would use
> the ide-pmac.c code) and a plug-in PCI IDE card, for which the
> udma_enable code is presumably correct.
> 
> So we definitely need to have the DMA setup/enable/disable methods
> able to be specified per host adaptor.

OK I see I have "forced" you to take care of this.
My problem previously was the simple fact that in esp.
the pmac code was sidestepping the generic code and providing his
own mechanisms for handling chipset specific dma transfer methods.

As you can see now it's possible to have overloaded most
of the "virtuaized" udma_xxx channel methods.

Now you request me to virtualize the udma_enable stuff.
Nothing easier then this.

Now we have:

udma_enable()
{
...
     /* default method implementation */
...
}

I will do the following with it:

static do_dma_enable() // was udma_enable() before
{
    /* default method implementation */
}


udma_enable()
{
    if (ch->udma_enable)
		return ch->udma_enable();

    /* fallback to default implementation */
    do_dma_enable();
}


I think this should suite your needs and you will be
able to just overload the implementation of
udma_enable() in ide-pmac.c

by setting the udma_enable method in the
host chip initialization routine there. (Directly alonside
the the compiler will chock on ->udma so such memmber.)

> If I have missed something, please let me know.  But it looks to me
> very much as though this patch makes it impossible for me to use my
> powermac IDE interfaces.


Would the above infrastructue adjustment suit your needs?

If Yes (I think so), please just drop me an OK please.



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

* Re: [PATCH 2.5.13 IDE 54
  2002-05-05 15:56                   ` [PATCH 2.5.13 IDE 54 Martin Dalecki
@ 2002-05-07 12:52                     ` Paul Mackerras
  2002-05-07 12:06                       ` Martin Dalecki
  2002-05-07 14:07                       ` Alan Cox
  0 siblings, 2 replies; 48+ messages in thread
From: Paul Mackerras @ 2002-05-07 12:52 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: linux-kernel

Martin Dalecki writes:

> Sun May  5 16:32:22 CEST 2002 ide-clean-54
> 
> - Finish the changes from patch 53. ide_dma_actaion_t is gone now as well as
>    whole hidden code paths associated with it. I hope I didn't mess too many
>    things up with this, since the sheer size of the changes make them sensitive.

I'm wondering how you would suggest that I change ide-pmac.c now so
that it compiles and works again.

With this patch we have calls to udma_enable scattered throughout
ide.c, and udma_enable assumes that it is to do its stuff by poking
particular I/O ports.  You seem to have taken away the ability to have
a chipset provide its own methods for setting up, enabling and
disabling DMA.

The comment above udma_enable seems to indicate that you think it
should be ifdef'd per-architecture.  That won't work for us (besides
being ugly), because we can have two ATA host adaptors in the one
machine that need to be programmed quite differently.  Consider for
instance a powermac with the built-in IDE interface (which would use
the ide-pmac.c code) and a plug-in PCI IDE card, for which the
udma_enable code is presumably correct.

So we definitely need to have the DMA setup/enable/disable methods
able to be specified per host adaptor.

If I have missed something, please let me know.  But it looks to me
very much as though this patch makes it impossible for me to use my
powermac IDE interfaces.

Paul.

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

* Re: [PATCH 2.5.13 IDE 54
  2002-05-07 14:07                       ` Alan Cox
@ 2002-05-07 13:24                         ` Martin Dalecki
  0 siblings, 0 replies; 48+ messages in thread
From: Martin Dalecki @ 2002-05-07 13:24 UTC (permalink / raw)
  To: Alan Cox; +Cc: Paul Mackerras, linux-kernel

Uz.ytkownik Alan Cox napisa?:
>>The comment above udma_enable seems to indicate that you think it
>>should be ifdef'd per-architecture.  That won't work for us (besides
>>being ugly), because we can have two ATA host adaptors in the one
>>machine that need to be programmed quite differently.  Consider for
>>instance a powermac with the built-in IDE interface (which would use
>>the ide-pmac.c code) and a plug-in PCI IDE card, for which the
>>udma_enable code is presumably correct.
> 
> 
> The same will be true for the PC very soon. In fact in a few cases
> it already is


I have already virtualized this method in my tree :-).


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

* Re: [PATCH 2.5.13 IDE 54
  2002-05-07 14:40                         ` benh
@ 2002-05-07 13:40                           ` Martin Dalecki
  2002-05-07 15:18                             ` benh
  0 siblings, 1 reply; 48+ messages in thread
From: Martin Dalecki @ 2002-05-07 13:40 UTC (permalink / raw)
  To: benh; +Cc: Paul Mackerras, linux-kernel

Uz.ytkownik benh@kernel.crashing.org napisa?:
>>OK I see I have "forced" you to take care of this.
>>My problem previously was the simple fact that in esp.
>>the pmac code was sidestepping the generic code and providing his
>>own mechanisms for handling chipset specific dma transfer methods.
>>
>>As you can see now it's possible to have overloaded most
>>of the "virtuaized" udma_xxx channel methods.
>>
>>Now you request me to virtualize the udma_enable stuff.
>>Nothing easier then this.
> 
> 
> I haven't looked closely at your new stuff yet, but here's what
> we need for ide-pmac (and similarily, on a whole bunch of embedded
> IDE controllers that do not behave like a legacy controller).
> 
>  - hook on enabling/disabling DMA & setting up timing stuffs. Due to
>    some weird HW, we must be in control of the actual sending of the
>    feature setting command to the drive
>  - hook on creating/disposing the DMA related data structures (lists
>    etc...)
>  - hook on setting up the DMA SG list as PRDs are really only
>    specific to the legacy PCI controllers, we deal with all sort
>    of different DMA controllers here in the outside world ;)
>  - hook on starting the DMA transfer
>  - hook on stopping the DMA transfer
>  - hook on knowing if the DMA is done and/or letting it drain
>    completely upon reception of the last interrupt.

Alomst all of them done ;-). Please take a look at the end of
ide-dma.c

> 
> Ideally, in order to properly deal with some HW details, the hook on
> starting the DMA transfer should also be the one ultimately issuing
> the command to the taskfile register, as depending on the HW, it may
> have to be done either prior or after starting the DMA channel.
> 
> So instead of having a ton of hook, I'd rather see all of this be
> properly abstracted by default, the legacy IDE beeing only one
> of the possible set of callbacks, instead of having the default code
> in ide.c with hooks for different chipsets.

This is presisely where the "default" code from the
"virtualizations" found in ide-dma.c is going to go, after
some restabilizing of the interface.

So I think we are at least "mentally" in sync.


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

* Re: [PATCH 2.5.13 IDE 54
  2002-05-07 12:52                     ` Paul Mackerras
  2002-05-07 12:06                       ` Martin Dalecki
@ 2002-05-07 14:07                       ` Alan Cox
  2002-05-07 13:24                         ` Martin Dalecki
  1 sibling, 1 reply; 48+ messages in thread
From: Alan Cox @ 2002-05-07 14:07 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Martin Dalecki, linux-kernel

> The comment above udma_enable seems to indicate that you think it
> should be ifdef'd per-architecture.  That won't work for us (besides
> being ugly), because we can have two ATA host adaptors in the one
> machine that need to be programmed quite differently.  Consider for
> instance a powermac with the built-in IDE interface (which would use
> the ide-pmac.c code) and a plug-in PCI IDE card, for which the
> udma_enable code is presumably correct.

The same will be true for the PC very soon. In fact in a few cases
it already is

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

* Re: [PATCH 2.5.13 IDE 54
  2002-05-07 12:06                       ` Martin Dalecki
@ 2002-05-07 14:40                         ` benh
  2002-05-07 13:40                           ` Martin Dalecki
  0 siblings, 1 reply; 48+ messages in thread
From: benh @ 2002-05-07 14:40 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Paul Mackerras, linux-kernel

>OK I see I have "forced" you to take care of this.
>My problem previously was the simple fact that in esp.
>the pmac code was sidestepping the generic code and providing his
>own mechanisms for handling chipset specific dma transfer methods.
>
>As you can see now it's possible to have overloaded most
>of the "virtuaized" udma_xxx channel methods.
>
>Now you request me to virtualize the udma_enable stuff.
>Nothing easier then this.

I haven't looked closely at your new stuff yet, but here's what
we need for ide-pmac (and similarily, on a whole bunch of embedded
IDE controllers that do not behave like a legacy controller).

 - hook on enabling/disabling DMA & setting up timing stuffs. Due to
   some weird HW, we must be in control of the actual sending of the
   feature setting command to the drive
 - hook on creating/disposing the DMA related data structures (lists
   etc...)
 - hook on setting up the DMA SG list as PRDs are really only
   specific to the legacy PCI controllers, we deal with all sort
   of different DMA controllers here in the outside world ;)
 - hook on starting the DMA transfer
 - hook on stopping the DMA transfer
 - hook on knowing if the DMA is done and/or letting it drain
   completely upon reception of the last interrupt.

Ideally, in order to properly deal with some HW details, the hook on
starting the DMA transfer should also be the one ultimately issuing
the command to the taskfile register, as depending on the HW, it may
have to be done either prior or after starting the DMA channel.

So instead of having a ton of hook, I'd rather see all of this be
properly abstracted by default, the legacy IDE beeing only one
of the possible set of callbacks, instead of having the default code
in ide.c with hooks for different chipsets.

Regards,
Ben.




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

* Re: [PATCH 2.5.13 IDE 54
  2002-05-07 13:40                           ` Martin Dalecki
@ 2002-05-07 15:18                             ` benh
  0 siblings, 0 replies; 48+ messages in thread
From: benh @ 2002-05-07 15:18 UTC (permalink / raw)
  To: Martin Dalecki; +Cc: Paul Mackerras, linux-kernel

>
>This is presisely where the "default" code from the
>"virtualizations" found in ide-dma.c is going to go, after
>some restabilizing of the interface.
>
>So I think we are at least "mentally" in sync.
>

Ok, good. I just wanted to make sure you knew all we
needed ;)

I'm looking forward to your new version.

Ben.




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

end of thread, other threads:[~2002-05-07 15:20 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-04-23  8:18 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included) Miles Lane
2002-04-23  8:00 ` Martin Dalecki
2002-04-23  9:18   ` Jens Axboe
2002-04-23  8:43     ` Martin Dalecki
2002-04-23  9:54       ` Jens Axboe
2002-04-23 17:39   ` Miles Lane
2002-04-23 17:54     ` Miles Lane
2002-04-24  8:06       ` Martin Dalecki
2002-04-24  9:11         ` Jens Axboe
2002-04-24  8:20           ` Martin Dalecki
2002-04-25 11:07           ` Martin Dalecki
2002-04-25 17:25             ` Jens Axboe
2002-04-25 17:34               ` Jens Axboe
2002-04-25 21:02                 ` Linus Torvalds
2002-04-26  7:33                   ` [PATCH] 2.5.10 UTS_VERSION Martin Dalecki
2002-04-26  9:52                     ` Keith Owens
2002-04-26  8:58                       ` Martin Dalecki
2002-04-26  7:41                   ` [PATCH] 2.5.10 IDE 42 Martin Dalecki
2002-04-26 16:09                     ` Pavel Machek
2002-04-26 17:31                       ` Dave Jones
2002-04-26 17:37                       ` Linus Torvalds
2002-04-26 20:05                         ` Oliver Xymoron
2002-04-26 21:34                           ` Martin Dalecki
2002-04-26 22:25                           ` Martin Dalecki
2002-04-26 21:32                         ` Martin Dalecki
2002-04-26 23:21                           ` Rene Rebe
2002-04-26 21:42                       ` Martin Dalecki
2002-04-26 16:10                     ` Sebastian Droege
2002-04-26 21:28                       ` Martin Dalecki
2002-04-26 22:44                         ` Padraig Brady
2002-04-28  9:18                           ` Kai Henningsen
2002-05-05 15:54                   ` [PATCH] 2.5.13 IDE 52 Martin Dalecki
2002-05-05 17:09                     ` Jens Axboe
2002-05-05 16:16                       ` Martin Dalecki
2002-05-05 15:55                   ` [PATCH] 2.5.13 IDE 53 Martin Dalecki
2002-05-06  9:53                     ` Russell King
2002-05-06  8:55                       ` Martin Dalecki
2002-05-06 23:48                         ` jw schultz
2002-05-05 15:56                   ` [PATCH 2.5.13 IDE 54 Martin Dalecki
2002-05-07 12:52                     ` Paul Mackerras
2002-05-07 12:06                       ` Martin Dalecki
2002-05-07 14:40                         ` benh
2002-05-07 13:40                           ` Martin Dalecki
2002-05-07 15:18                             ` benh
2002-05-07 14:07                       ` Alan Cox
2002-05-07 13:24                         ` Martin Dalecki
2002-04-24  9:29         ` 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included) Luigi Genoni
2002-04-23 18:23   ` Melchior FRANZ

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