2002-04-23 08:19:46

by Miles Lane

[permalink] [raw]
Subject: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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 ([email protected]) (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 ([email protected])
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. http://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 <[email protected]>
ipddp0: Appletalk-IP Encap. mode by Bradford W. Johnson <[email protected]>
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


2002-04-23 09:02:46

by Martin Dalecki

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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.

2002-04-23 09:18:25

by Jens Axboe

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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

2002-04-23 09:45:45

by Martin Dalecki

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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

2002-04-23 09:55:03

by Jens Axboe

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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

2002-04-23 17:40:41

by Miles Lane

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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



2002-04-23 17:56:27

by Miles Lane

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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


2002-04-24 00:50:48

by Randy Hron

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

It sounds like Jens and Martin have a handle on this
already. Just in case this helps. No modules.

Oops on 2.5.9 at boot time.

Here is the last part of the boot message:

Uniform Multi-Platform E-IDE driver ver.:7.0.0
ide: system bus speed 33MHz
VIA Technologies, Inc. Bus Master IDE: IDE controller on PCI slot 00:07.1
VIA Technologies, Inc. Bus Master IDE: chipset revision 6
VIA Technologies, Inc. Bus Master IDE: not 100% native mode: will probe irqs later
VP_IDE: VIA vt82c586b (rev 47) IDE UDMA33 controller on pci00:07.1
ide0: BM-DMA at 0xe000-0xe007, BIOS settings: hda:DMA, hdb:DMA
ide1: BM-DMA at 0xe008-0xe00f, BIOS settings: hdc:DMA, hdd:DMA
hda: Maxtor 51536U3, ATA DISK drive
hdb: ATAPI CDROM, ATAPI CD/DVD-ROM drive
hdc: Maxtor 52049U4, ATA DISK drive
ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
ide1 at 0x170-0x177,0x376 on irq 15
ide: unexpected interrupt 0 14
hda: 30015216 sectors (15368 MB) w/2048KiB Cache, CHS=29777/16/63, UDMA(33)
ide: unexpected interrupt 1 15
hdc: 40020624 sectors (20491 MB) w/2048KiB Cache, CHS=39703/16/63, UDMA(33)
ide: unexpected interrupt 0 14
(oops here)


ksymoops output

No modules in ksyms, skipping objects
No ksyms, skipping lsmod
Unable to handle kernel NULL pointer dereference at virtual address 00000004
c01bf5f6
*pde = 00000000
Oops: 0002
CPU: 0
EIP: 0010:[<c01bf5f6>] Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010002
eax: 00000004 ebx: d7f61eb4 ecx: 00000001 edx: 00000000
esi: d7f61e30 edi: c02c8b6c ebp: 00000292 esp: c026bedc
ds: 0018 es: 0018 ss: 0018
Stack: d7f61e30 00000001 c02c8b6c 00000003 00000001 c01c2f1b c02c8b6c 00000001
00000000 c01c9a52 c02c8b6c 00000001 00000018 d7f61eb4 d7f61e30 c01ca783
c02c8b6c 00000001 00000000 c02c8b6c d7f622c0 c02c8840 c02c8f0c d7f62380
Call Trace: [<c01c2f1b>] [<c01c9a52>] [<c01ca783>] [<c01c11ba>] [<c01ca6bc>]
[<c01080fc>] [<c0108262>] [<c0105000>] [<c0106eff>] [<c0105240>] [<c0105000>]
[<c0105263>] [<c01052d4>] [<c0105019>]
Code: c7 04 02 00 00 00 00 8b 53 0c 8b 87 34 02 00 00 0f b3 10 8b


>>EIP; c01bf5f6 <__ide_end_request+fe/140> <=====

>>ebx; d7f61eb4 <END_OF_CODE+17c930f8/????>
>>esi; d7f61e30 <END_OF_CODE+17c93074/????>
>>edi; c02c8b6c <ide_hwifs+32c/3a70>
>>esp; c026bedc <init_thread_union+1edc/2000>

Trace; c01c2f1b <ide_end_request+f/14>
Trace; c01c9a52 <cdrom_end_request+42/4c>
Trace; c01ca783 <cdrom_pc_intr+c7/1d0>
Trace; c01c11ba <ide_intr+c6/13c>
Trace; c01ca6bc <cdrom_pc_intr+0/1d0>
Trace; c01080fc <handle_IRQ_event+30/5c>
Trace; c0108262 <do_IRQ+6a/a8>
Trace; c0105000 <_stext+0/0>
Trace; c0106eff <common_interrupt+1f/30>
Trace; c0105240 <default_idle+0/28>
Trace; c0105000 <_stext+0/0>
Trace; c0105263 <default_idle+23/28>
Trace; c01052d4 <cpu_idle+28/38>
Trace; c0105019 <rest_init+19/1c>

Code; c01bf5f6 <__ide_end_request+fe/140>
00000000 <_EIP>:
Code; c01bf5f6 <__ide_end_request+fe/140> <=====
0: c7 04 02 00 00 00 00 movl $0x0,(%edx,%eax,1) <=====
Code; c01bf5fd <__ide_end_request+105/140>
7: 8b 53 0c mov 0xc(%ebx),%edx
Code; c01bf600 <__ide_end_request+108/140>
a: 8b 87 34 02 00 00 mov 0x234(%edi),%eax
Code; c01bf606 <__ide_end_request+10e/140>
10: 0f b3 10 btr %edx,(%eax)
Code; c01bf609 <__ide_end_request+111/140>
13: 8b 00 mov (%eax),%eax

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

This config has been working with other kernels, including 2.5.8.

grep ^CONFIG .config
CONFIG_X86=y
CONFIG_ISA=y
CONFIG_UID16=y
CONFIG_EXPERIMENTAL=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
CONFIG_SYSCTL=y
CONFIG_MK6=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_X86_L1_CACHE_SHIFT=5
CONFIG_X86_ALIGNMENT_16=y
CONFIG_X86_TSC=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_NOHIGHMEM=y
CONFIG_MTRR=y
CONFIG_PCI=y
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_NAMES=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_BLK_DEV_FD=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_BLK_DEV_IDEDMA=y
CONFIG_BLK_DEV_VIA82CXXX=y
CONFIG_IDEDMA_AUTO=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_NET_PCI=y
CONFIG_8139TOO=y
CONFIG_SOUND_GAMEPORT=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_SERIAL=y
CONFIG_SERIAL_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=64
CONFIG_REISERFS_FS=y
CONFIG_RAMFS=y
CONFIG_ISO9660_FS=y
CONFIG_PROC_FS=y
CONFIG_DEVPTS_FS=y
CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_MSDOS_PARTITION=y
CONFIG_VGA_CONSOLE=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y

lspci
00:00.0 Host bridge: VIA Technologies, Inc. VT82C598 [Apollo MVP3] (rev 04)
00:01.0 PCI bridge: VIA Technologies, Inc. VT82C598/694x [Apollo MVP3/Pro133x AGP]
00:07.0 ISA bridge: VIA Technologies, Inc. VT82C586/A/B PCI-to-ISA [Apollo VP] (rev 47)
00:07.1 IDE interface: VIA Technologies, Inc. Bus Master IDE (rev 06)
00:07.2 USB Controller: VIA Technologies, Inc. UHCI USB (rev 02)
00:07.3 Host bridge: VIA Technologies, Inc. VT82C586B ACPI (rev 10)
00:13.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139 (rev 10)
01:00.0 VGA compatible controller: nVidia Corporation Vanta [NV6] (rev 15)

--
Randy Hron

2002-04-24 09:09:14

by Martin Dalecki

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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.

2002-04-24 09:12:08

by Jens Axboe

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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

2002-04-24 09:18:26

by Martin Dalecki

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

Uz.ytkownik [email protected] napisa?:
> It sounds like Jens and Martin have a handle on this
> already. Just in case this helps. No modules.

Yeep.

> Oops on 2.5.9 at boot time.

That is indeed a bit surprising. In esp. since the oops happens at boot time.
Maybe some goot order problem.
Could you please introduce two printk("BANG\n") printk("BOOM\n")
aroung the ata_ar_get() in ide-cd? Just to see whatever the
command queue is already up and initialized.

2002-04-24 09:23:25

by Martin Dalecki

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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

2002-04-24 09:30:13

by Luigi Genoni

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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 [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

2002-04-24 13:24:56

by Randy Hron

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

>> Oops on 2.5.9 at boot time.

> Could you please introduce two printk("BANG\n") printk("BOOM\n")
> aroung the ata_ar_get() in ide-cd? Just to see whatever the
> command queue is already up and initialized.

This may not be what you wanted:

printk("BANG\n");
ar = ata_ar_get(drive);
printk("BOOM\n");

If it is, neither BANG nor BOOM printed before oops.

I see Melchior may have narrowed down the code path in
this thread.

2.5.10 gives very similar oops to 2.5.9:

Unable to handle kernel NULL pointer dereference at virtual address 00000004
c01bf7f6
*pde = 00000000
Oops: 0002
CPU: 0
EIP: 0010:[<c01bf7f6>] Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010002
eax: 00000004 ebx: d7f61eb4 ecx: 00000001 edx: 00000000
esi: d7f61e30 edi: c02c8b6c ebp: 00000292 esp: c026bedc
ds: 0018 es: 0018 ss: 0018
Stack: d7f61e30 00000001 c02c8b6c 00000003 00000001 c01c311b c02c8b6c 00000001
00000000 c01c9c52 c02c8b6c 00000001 00000018 d7f61eb4 d7f61e30 c01ca983
c02c8b6c 00000001 00000000 c02c8b6c d7f622c0 c02c8840 c02c8f0c d7f62380
Call Trace: [<c01c311b>] [<c01c9c52>] [<c01ca983>] [<c01c13ba>] [<c01ca8bc>]
[<c01080fc>] [<c0108262>] [<c0105000>] [<c0106eff>] [<c0105240>] [<c0105000>]
[<c0105263>] [<c01052d4>] [<c0105019>]
Code: c7 04 02 00 00 00 00 8b 53 0c 8b 87 34 02 00 00 0f b3 10 8b


>>EIP; c01bf7f6 <__ide_end_request+fe/140> <=====

>>ebx; d7f61eb4 <END_OF_CODE+17c930f8/????>
>>esi; d7f61e30 <END_OF_CODE+17c93074/????>
>>edi; c02c8b6c <ide_hwifs+32c/3a70>
>>esp; c026bedc <init_thread_union+1edc/2000>

Trace; c01c311b <ide_end_request+f/14>
Trace; c01c9c52 <cdrom_end_request+42/4c>
Trace; c01ca983 <cdrom_pc_intr+c7/1d0>
Trace; c01c13ba <ide_intr+c6/13c>
Trace; c01ca8bc <cdrom_pc_intr+0/1d0>
Trace; c01080fc <handle_IRQ_event+30/5c>
Trace; c0108262 <do_IRQ+6a/a8>
Trace; c0105000 <_stext+0/0>
Trace; c0106eff <common_interrupt+1f/30>
Trace; c0105240 <default_idle+0/28>
Trace; c0105000 <_stext+0/0>
Trace; c0105263 <default_idle+23/28>
Trace; c01052d4 <cpu_idle+28/38>
Trace; c0105019 <rest_init+19/1c>

Code; c01bf7f6 <__ide_end_request+fe/140>
00000000 <_EIP>:
Code; c01bf7f6 <__ide_end_request+fe/140> <=====
0: c7 04 02 00 00 00 00 movl $0x0,(%edx,%eax,1) <=====
Code; c01bf7fd <__ide_end_request+105/140>
7: 8b 53 0c mov 0xc(%ebx),%edx
Code; c01bf800 <__ide_end_request+108/140>
a: 8b 87 34 02 00 00 mov 0x234(%edi),%eax
Code; c01bf806 <__ide_end_request+10e/140>
10: 0f b3 10 btr %edx,(%eax)
Code; c01bf809 <__ide_end_request+111/140>
13: 8b 00 mov (%eax),%eax

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


--
Randy Hron

2002-04-24 13:33:43

by Jens Axboe

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

On Wed, Apr 24 2002, [email protected] wrote:
> >> Oops on 2.5.9 at boot time.
>
> > Could you please introduce two printk("BANG\n") printk("BOOM\n")
> > aroung the ata_ar_get() in ide-cd? Just to see whatever the
> > command queue is already up and initialized.
>
> This may not be what you wanted:
>
> printk("BANG\n");
> ar = ata_ar_get(drive);
> printk("BOOM\n");
>
> If it is, neither BANG nor BOOM printed before oops.

Look, the problem is easy. Backout the changes to ide_cdrom_do_request()
and cdrom_start_read(), then re-add the

HWGROUP(drive)->rq->special = NULL;

in cdrom_end_request() before calling ide_end_request()

Something ala, completely untested (not even compiled). See the thread
about the ide-cd changes being broken.

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.558 -> 1.559
# drivers/ide/ide-cd.c 1.35 -> 1.36
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/04/24 [email protected] 1.559
# "fix" rq->special and ar usage, needs proper fixing
# --------------------------------------------
#
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c Wed Apr 24 15:32:59 2002
+++ b/drivers/ide/ide-cd.c Wed Apr 24 15:32:59 2002
@@ -558,10 +558,7 @@
if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
uptodate = 1;

-#if 0
- /* FIXME --mdcki */
HWGROUP(drive)->rq->special = NULL;
-#endif
ide_end_request(drive, uptodate);
}

@@ -1217,22 +1214,13 @@
/*
* Start a read request from the CD-ROM.
*/
-static ide_startstop_t cdrom_start_read(struct ata_device *drive, struct ata_request *ar, unsigned int block)
+static ide_startstop_t cdrom_start_read(struct ata_device *drive, unsigned int block)
{
struct cdrom_info *info = drive->driver_data;
- struct request *rq = ar->ar_rq;
-
- if (ar->ar_flags & ATA_AR_QUEUED) {
-// spin_lock_irqsave(DRIVE_LOCK(drive), flags);
- blkdev_dequeue_request(rq);
-// spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
- }
-
+ struct request *rq = HWGROUP(drive)->rq;

restore_request(rq);

- rq->special = ar;
-
/* Satisfy whatever we can of this request from our cached sector. */
if (cdrom_read_from_buffer(drive))
return ide_stopped;
@@ -1665,30 +1653,8 @@
if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
action = cdrom_start_seek (drive, block);
else {
- unsigned long flags;
- struct ata_request *ar;
-
- /*
- * get a new command (push ar further down to avoid grabbing lock here
- */
- spin_lock_irqsave(DRIVE_LOCK(drive), flags);
-
- ar = ata_ar_get(drive);
-
- /*
- * we've reached maximum queue depth, bail
- */
- if (!ar) {
- spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-
- return ide_started;
- }
-
- ar->ar_rq = rq;
- spin_unlock_irqrestore(DRIVE_LOCK(drive), flags);
-
if (rq_data_dir(rq) == READ)
- action = cdrom_start_read(drive, ar, block);
+ action = cdrom_start_read(drive, block);
else
action = cdrom_start_write(drive, rq);
}

--
Jens Axboe

2002-04-24 13:56:42

by Randy Hron

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

>> > > Oops on 2.5.9 at boot time.

> Look, the problem is easy. Backout the changes to ide_cdrom_do_request()
> and cdrom_start_read(), then re-add the
>
> HWGROUP(drive)->rq->special = NULL;
>
> in cdrom_end_request() before calling ide_end_request()
>
> Something ala, completely untested (not even compiled). See the thread
> about the ide-cd changes being broken.

That works! Applied to 2.5.10, compiled and booted.
Mounted a cdrom and that works too.

Thanks!
--
Randy Hron

2002-04-24 14:42:16

by Martin Dalecki

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

Uz.ytkownik Jens Axboe napisa?:
> On Wed, Apr 24 2002, [email protected] wrote:
>
>>>>Oops on 2.5.9 at boot time.
>>>
>>>Could you please introduce two printk("BANG\n") printk("BOOM\n")
>>>aroung the ata_ar_get() in ide-cd? Just to see whatever the
>>>command queue is already up and initialized.
>>
>>This may not be what you wanted:
>>
>> printk("BANG\n");
>> ar = ata_ar_get(drive);
>> printk("BOOM\n");
>>
>>If it is, neither BANG nor BOOM printed before oops.
>
>
> Look, the problem is easy. Backout the changes to ide_cdrom_do_request()
> and cdrom_start_read(), then re-add the
>
> HWGROUP(drive)->rq->special = NULL;
>
> in cdrom_end_request() before calling ide_end_request()
>
> Something ala, completely untested (not even compiled). See the thread
> about the ide-cd changes being broken.
>

Jens - this is *not going to work* becouse the DMA methods are
expecting an full ata_request right now.

Uunfortunately pulling the whole ata_ar_get() stuff one
level up to the ide.c file where ->do_request get's called
doesn't work right now.


2002-04-24 14:47:32

by Martin Dalecki

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

Uz.ytkownik [email protected] napisa?:
>>>>>Oops on 2.5.9 at boot time.
>>>>
>
>>Look, the problem is easy. Backout the changes to ide_cdrom_do_request()
>>and cdrom_start_read(), then re-add the
>>
>> HWGROUP(drive)->rq->special = NULL;
>>
>>in cdrom_end_request() before calling ide_end_request()
>>
>>Something ala, completely untested (not even compiled). See the thread
>>about the ide-cd changes being broken.
>
>
> That works! Applied to 2.5.10, compiled and booted.
> Mounted a cdrom and that works too.
>
> Thanks!

Yes but if you look at ide_start_dma() in ide-dma.c you will notice
that the if (!ar) path is taken, which will cause fallback from
DMA to PIO transfer:

/*
* Start DMA engine.
*/
int ide_start_dma(struct ata_channel *hwif, ide_drive_t *drive, ide_dma_action_t
func)
{
unsigned int reading = 0, count;
unsigned long dma_base = hwif->dma_base;
struct ata_request *ar = IDE_CUR_AR(drive);

/* This can happen with drivers abusing the special request field.
*/

if (!ar) {
printk(KERN_ERR "DMA without ATA request\n");

return 1;
}





--
- phone: +49 214 8656 283
- job: eVision-Ventures AG, LEV .de (MY OPINIONS ARE MY OWN!)
- langs: de_DE.ISO8859-1, en_US, pl_PL.ISO8859-2, last ressort: ru_RU.KOI8-R

2002-04-25 12:09:35

by Martin Dalecki

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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


2002-04-25 17:25:20

by Jens Axboe

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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

2002-04-25 17:34:37

by Jens Axboe

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

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

2002-04-25 21:03:01

by Linus Torvalds

[permalink] [raw]
Subject: Re: 2.5.9 -- OOPS in IDE code (symbolic dump and boot log included)

In article <[email protected]>, Jens Axboe <[email protected]> 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

2002-04-26 08:36:16

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.10 UTS_VERSION

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 \


Attachments:
trivial-2.5.10.diff (709.00 B)

2002-04-26 08:44:16

by Martin Dalecki

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

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


Attachments:
ide-clean-42.diff (71.91 kB)

2002-04-26 09:53:07

by Keith Owens

[permalink] [raw]
Subject: Re: [PATCH] 2.5.10 UTS_VERSION

On Fri, 26 Apr 2002 09:33:44 +0200,
Martin Dalecki <[email protected]> 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.

2002-04-26 10:01:21

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.10 UTS_VERSION

U?ytkownik Keith Owens napisa?:
> On Fri, 26 Apr 2002 09:33:44 +0200,
> Martin Dalecki <[email protected]> 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".

2002-04-26 16:12:39

by Sebastian Droege

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

On Fri, 26 Apr 2002 09:41:30 +0200
Martin Dalecki <[email protected]> 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


Attachments:
(No filename) (189.00 B)

2002-04-26 17:15:01

by Pavel Machek

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

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

2002-04-26 17:31:26

by Dave Jones

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

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

2002-04-26 17:37:59

by Linus Torvalds

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



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

2002-04-26 20:05:54

by Oliver Xymoron

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

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

2002-04-26 22:30:47

by Martin Dalecki

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

Uz.ytkownik Sebastian Droege napisa?:
> On Fri, 26 Apr 2002 09:41:30 +0200
> Martin Dalecki <[email protected]> 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.

2002-04-26 22:35:18

by Martin Dalecki

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

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?

2002-04-26 22:36:57

by Martin Dalecki

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

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.

2002-04-26 22:44:57

by Martin Dalecki

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

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



2002-04-26 22:45:47

by Padraig Brady

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

Martin Dalecki wrote:
> Uz.ytkownik Sebastian Droege napisa?:
>
>> On Fri, 26 Apr 2002 09:41:30 +0200
>> Martin Dalecki <[email protected]> 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.


2002-04-26 23:23:05

by Rene Rebe

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

Hi.

On: Fri, 26 Apr 2002 23:32:44 +0200,
Martin Dalecki <[email protected]> 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: [email protected]
[email protected]

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.

>

2002-04-26 23:28:23

by Martin Dalecki

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

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

2002-04-28 12:49:03

by kaih

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

[email protected] (Padraig Brady) wrote on 26.04.02 in <[email protected]>:

> Martin Dalecki wrote:
> > Uz.ytkownik Sebastian Droege napisa?:
> >
> >> On Fri, 26 Apr 2002 09:41:30 +0200
> >> Martin Dalecki <[email protected]> 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