2002-06-03 01:57:47

by Linus Torvalds

[permalink] [raw]
Subject: Linux 2.5.20


ACPI merge, merges from Dave Jones, IDE updates, stuff from Andrew, PPC64
update, e100[0] driver updates, the works..

And no, I still haven't upgraded my changelog scripts, kill me.

Linus

---
Summary of changes from v2.5.19 to v2.5.20
============================================

<[email protected]>
o airo wireless net driver updates:

<[email protected]>
o more file renames
o rename ACPI files to remove acpi_ prefix. Why did we ever name them that way?
o Clean up code based on things flagged by lint
o Properly (?) handle the multiple people who can find PCI root bridges
o ACPI PCI IRQ Improvements:
o ACPI Ancillary files update
o move arch-dependent macros from drivers/acpi/include/platform/acenv.h
o Code cleanups

Andrew Morton <[email protected]>
o direct-to-BIO writeback for writeback-mode ext3
o remove PageSkip() macros
o list_head debugging
o rename block_symlink() to page_symlink()
o remove inode.i_wait
o buffer_boundary() for ext3
o speed up writes
o fix swapcache packing in the radix tree
o dirsync support for minixfs, sysvfs and ufs
o give swapper_space a set_page_dirty a_op
o fix race between writeback and unlink
o swapcache bugfixes
o put in-memory filesystem dirty pages on the correct list
o tmpfs bugfixes
o rename flushpage to invalidatepage

<[email protected]>
o Renames struct bus_type to struct de4x5_bus_type in de4x5 net driver,

<[email protected]>
o pSeries HVC console: add hvc initalisation
o pSeries HVC console: add missing function prototype
o ppc64 signal cleanup: remove old debug and sync with ppc32 signal code
o pSeries HVC console: Disable interrupts in spinlock regions, fix from
o ppc64: signal formatting cleanups
o ppc64: SIGURG fix from Chris Yeoh
o ppc64: cleanup 32 bit signal code
o ppc64: SIGURG fix from Chris Yeoh
o ppc64: update config.in
o ppc64: fixes for 2.5.14
o ppc64: fix compile error caused by machine type changes
o ppc64: Add PREEMPT_ACTIVE and fix HMT macro typo
o ppc64: missed this during Naca -> naca merge
o ppc64: provide default_idle, we shouldnt ever actually use this but
o ppc64: Add TIOCSTOP translation
o ppc64: dont allow tlbiel on large pages.
o add subsys_initcall for pcibios_init
o ppc64: remove old code for stacking signals, its not used any more
o ppc64: reduce differences to the ppc32 signal code.
o ppc64: Take page_table_lock in flush_tlb_mm
o ppc64: Be sure to zero the fpscr in a signal handler, otherwise
o ppc64: Fix a number of problems with our exception reporting, in
o ppc64: use common die() function in bad_page_fault, from ppc32
o ppc64: Add Ingo's irq affinity stuff, from x86
o ppc64: prevsp is not used any more
o ppc64: Paul Mackerras' optimized power4 copy routines
o ppc64: use generic debugger hooks instead of hardwiring xmon
o ppc64: Add get/setaffinity syscalls, from sparc64
o ppc64: dont print "xmon called", it garbles the output when multiple
o ppc64: Up the gcc inline limited, needed for gcc 3.1
o ppc64: No need to handle address space destruction in flush_tlb_mm,
o ppc64: Provide a rough cache_decay_ticks.
o ppc64 defconfig update
o ppc64: Remove last_syscall, we can work the syscall out easily from
o ppc64 segment table rework. We preload segments for both segment
o ppc64: missed during segment handler rework
o ppc64: Recent firmware removes the compatible property on pci bridges.
o ppc64: Fix 32 bit execve to mirror recent generic changes
o ppc64: kill MAP_NR, dont mark free_initmem as __init
o ppc64: mask top 4 bytes of si_code
o remove bogus panic in ppc32_select
o ppc64: quota updates
o ppc64: signal32 updates from Stephen Rothwell - comment changes
o ppc64: more signal32 updates from Stephen Rothwell
o ppc64: Add CONFIG_CMDLINE, from ppc32
o ppc64: more signal32 updates from Stephen Rothwell - replace some
o ppc64: last of the signal32 updates from Stephen Rothwell. Fantastic
o ppc64: Fix clear_user, from ppc32

<anton@superego.(none)>
o add pSeries hypervisor console

Jens Axboe <[email protected]>
o misc generic block tag fixes
o documentation and tq_disk removals
o Re: ufs compile error in 2.5.19]
o update to the update

Martin Dalecki <[email protected]>
o 2.5.19 IDE 76
o 2.5.19 IDE 77
o [PATCH} 2.5.19 IDE 79
o 2.5.19 IDE 78
o 2.5.19 IDE 82
o 2.5.19 IDE 81
o 2.5.19 IDE 80
o 2.5.19 blk.h and more about the ugly kids.

<[email protected]>
o dumb cpqarray init microoptimisation.
o i386 mmx copying bug.
o check misc_register result in efirtc
o ps2esdi resource cleanups
o region handling cleanups for gscd driver
o i386 smp tweaks.
o recognise 2 extra devices for xd.c
o h8 janitor work
o epca janitor work
o dltk driver check_region -> request_region
o ib700wdt janitor work
o elsa check_region() -> request_region()
o mixcomwd janitor work
o esp janitor work
o aztech CD driver janitor work
o ite_gpio region handling cleanups
o istallion janitor work
o better sizing of queue_nr_requests
o forward ioctls on raw devices to underlying devices
o rtc max_user_freq sysctl
o isicom check_region() -> request_region()
o niccy region handling cleanups
o teles3 region handling cleanups
o Some includes that aren't needed.
o Deliver SIGIO to FIFO and pipe devices
o missing binfmt check
o Fix deadlock in nbd
o gazel region handling cleanups
o Conversion of uidhash to use list_t
o hd.c compilation fix.
o avm_a1 check_region -> request_region cleanup
o egcs no longer supported.
o fill in empty hisax_fcpcipnp debug statement
o add spinlocking to w83877f_wdt driver
o struct super_block cleanup - adfs
o missing GPL tags
o Fix up agpgart.

<[email protected]>
o ehci remove warning if no CONFIG_USB_DEBUG

<[email protected]>
o PATCH: USB Scanner Driver 0.4.8 and new maintainer

<[email protected]>
o trivial keyboard driver patch
o pass "page" pointer to clear_user_page()/copy_user_page()
o time-offset patch
o agp support for i460 and zx1 cleanup

<[email protected]>
o dl2k gige net driver updates:

<[email protected]>
o 2.5.19 : drivers/mtd/nftlcore.c

<[email protected]>
o Fix pcnet32 net driver workaround for xSeries250.

<[email protected]>
o USB OHCI driver: Added SA1111 support
o USB kernel-api documentation fix

<[email protected]>
o kbuild: Add (internal) prepare target
o kbuild: Don't rebuild if vmlinux if nothing changed - fix
o kbuild: clean up generation of modversions.h
o kbuild: Clarify the CONFIG_MODVERSIONS logic
o kbuild: Use the real instead of a phony target if we have one
o kbuild: Group targets which need / don't need .config
o kbuild: Get rid of -DMODVERSIONS, further cleanup

<[email protected]>
o USB storage: Dead code, more abort cleanups, and detached device fix

<[email protected]>
o PCI: Make sure id_table is passed to probe callback
o PCI Update:
o Device Model: Add helpers bus_for_each_dev and bus_for_each_drv
o Device Model: Implement centralized device/driver binding
o PCI: Put pci_match_device back for the people that are still using it.
o USB: define usb_bus_type and register on startup
o driverfs update:
o USB: Move URB request code from usb.c to urb.c
o USB:
o USB: Move synchronous message passing code from usb.c to message.c
o USB: Move configuration parsing code from usb.c to config.c
o driverfs: Remove default 'status' file: it had no useful read information, the commands it supported were minimal and probably broken and the comments were wrong.
o device model: remove flags parameter from struct device_driver::remove and fix all users
o device model: Use driver_for_each_dev to unbind drivers from its devices (now that it's implemented)
o devicemode: Implement driver_for_each_dev

<[email protected]>
o suspend-to-ram: clean up according to Andy
o eepro100 net driver trivial cleanup:

<[email protected]>
o Janitor: Add __devinit markers to two net drivers, epic100 and sundance

<[email protected]>
o de4x5 does not compile in 2.5.19 due to bus_type conflict
o missing argument to clear_user_page in v4l

<[email protected]>
o [ARM] Fix makefiles for drivers/acorn/{block,char}/
o [ARM] 2.5.18 Update ARM for TLB shootdown changes
o [ARM] Remove redundant instruction cache code from decompressor.
o [ARM] Tidy up context switch save area initialisation for fork
o [ARM] Remove victor machine type
o [ARM] cpufreq_init takes low and high frequency limits.
o [ARM] Remove an extraneous load from atomic ops
o [ARM] Context switch improvements
o [ARM] Convert for() delay loops to udelay()
o [ARM] Remove hard coded per-architecture memory, ramdisk and initrd

<[email protected]>
o drivers/net/wan/dscc4.c - gross overflow

<[email protected]>
o softirq.c per_cpu fix
o AUDIT 2.5.19: Continuing copy_to/from_user & clear_user

<[email protected]>
o Add ETHTOOL_PHYS_ID ethtool command to linux/ethtool.h.
o e1000 net driver updates 2/4:
o e100 net driver update:
o e1000 net driver update 1/4:
o e1000 net driver update 3/4:
o e1000 net driver update 4/4:

<[email protected]>
o APM patch for idle_period handling
o missing bit from signal patches

<[email protected]>
o Fix free-space leak truncating files in JFS.
o JFS: cleanup dbAlloc
o JFS: misc stuff for 2.5
o JFS: metapage changes
o JFS: support for kNFSD

<[email protected]>
o Fix up ACPI makefile that got broken by the merge.
o Fix PCI irq routing to always look up the bridge swizzling
o Make qla1280 driver print out irq information along with bus location.
o Allow <linux/list.h> to be used even without NULL defined yet.
o Simplify uidhash table allocation - no need to make it dynamic,
o idescsi initialization is done with module_init(), not
o Proper usage of isupper/tolower for build scripts.
o Kernel version 2.5.20
o Felipe W Damasio: add KERN_* to 3c501 driver printk's
o Fix missing piece of uidhash list conversion
o Simplify tlb_flush_mmu() for exit case: makes it easier on the ia64

<[email protected]>
o Fix RAMDISK config problem
o Missing include in drivers/base/bus.c and drivers/pci/pci-driver.c


2002-06-03 03:08:52

by Miles Lane

[permalink] [raw]
Subject: 2.5.20 -- suspend.c still breaks the build (originally reported for 2.5.18)

suspend.c: In function `freeze_processes':
suspend.c:234: warning: implicit declaration of function `signal_wake_up'
suspend.c: In function `fill_suspend_header':
suspend.c:286: warning: comparison between pointer and integer
suspend.c:305:2: #error this is broken, FIXME
suspend.c: In function `do_suspend_sync':
suspend.c:306: `tq_disk' undeclared (first use in this function)
suspend.c:306: (Each undeclared identifier is reported only once
suspend.c:306: for each function it appears in.)
suspend.c: In function `write_suspend_image':
suspend.c:431: warning: passing arg 3 of `get_swaphandle_info' from incompatible pointer type
suspend.c:430: warning: unused variable `dummy2'
suspend.c: In function `count_and_copy_data_pages':
suspend.c:536: warning: passing arg 1 of `mmx_copy_page' makes pointer from integer without a cast
suspend.c:536: warning: passing arg 2 of `mmx_copy_page' makes pointer from integer without a cast
suspend.c: In function `suspend_save_image':
suspend.c:724: warning: assignment makes integer from pointer without a cast
suspend.c: In function `resume_try_to_read':
suspend.c:1059: warning: passing arg 1 of `name_to_kdev_t' discards qualifiers from pointer target type
suspend.c:1067: warning: unsigned int format, kdev_t arg (arg 2)
suspend.c:1057: warning: unused variable `blksize'
suspend.c: At top level:
suspend.c:1221: warning: static declaration for `resume_setup' follows non-static
make[1]: *** [suspend.o] Error 1
make[1]: Leaving directory `/usr/src/linux/kernel'


2002-06-03 03:20:16

by Brad Hards

[permalink] [raw]
Subject: [patch] i386 "General Options" - begone [take 2]

This patch (a minor update on one that I accidently left lkml out of the To:)
removes the "General Options" top level config menu from the i386 build for
2.5.20. It didn't describe what it was doing, and it contained a broad
collection of mostly unrelated configuration options.
To replace it, you now get:
"Power management options (ACPI, APM)", which also includes software suspend.
"Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
"Executable file formats"

While moving software suspend, I also took the chance to tweak the Config.help
entry.

To all those who don't like the expansion in top level directories - I agree,
and have the genesis of a plan to build a more logical grouping (eg getting
the various mass storage options together, getting the various networking
options together, etc). One step at a time though, especially since that
would affect multiple architectures.

Brad

--
http://conf.linux.org.au. 22-25Jan2003. Perth, Australia. Birds in Black.


Attachments:
(No filename) (973.00 B)
config.in-03062002.patch (5.50 kB)
Download all attachments

2002-06-03 14:32:55

by Martin Dalecki

[permalink] [raw]
Subject: Oops Linux 2.5.20

The folowing happens during module load time:

<6>note: modprobe[251] exited with preempt_count 1
kernel BUG at /usr/src/linux/include/linux/device.h:115!
invalid operand: 0000
CPU: 0
EIP: 0010:[<c01924d7>] Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010246
eax: 00000000 ebx: cafaa000 ecx: cd074f50 edx: cd074f48
esi: 00000000 edi: 00000000 ebp: bfffeba8 esp: cafabf30
ds: 0018 es: 0018 ss: 0018
Stack: 00000010 00000246 c0125450 cafaa000 cd074f48 00000000 bfffeba8 c01911fb
cd074f48 cd074f48 c0191170 c0192628 cd074f48 c025abe8 00000000 00000000
cd0715b9 cd074f48 cd06d000 fffffff0 c0119763 cd06d000 cd06d000 fffffff0
Call Trace: [<c0125450>] [<cd074f48>] [<c01911fb>] [<cd074f48>] [<cd074f48>]
[<c0191170>] [<c0192628>] [<cd074f48>] [<cd0715b9>] [<cd074f48>] [<c0119763>]

[<c011894c>] [<c010740f>]
Code: 0f 0b 73 00 c0 73 23 c0 e9 26 ff ff ff 8d b6 00 00 00 00 8d

>>EIP; c01924d7 <driver_for_each_dev+e7/130> <=====
Trace; c0125450 <exec_usermodehelper+190/240>
Trace; cd074f48 <[parport].bss.end+9369/b421>
Trace; c01911fb <pci_assign_resource+35b/360>
Trace; cd074f48 <[parport].bss.end+9369/b421>
Trace; cd074f48 <[parport].bss.end+9369/b421>
Trace; c0191170 <pci_assign_resource+2d0/360>
Trace; c0192628 <put_driver+68/c80>
Trace; cd074f48 <[parport].bss.end+9369/b421>
Trace; cd0715b9 <[parport].bss.end+59da/b421>
Trace; cd074f48 <[parport].bss.end+9369/b421>
Trace; c0119763 <try_inc_mod_count+f53/1860>
Trace; c011894c <try_inc_mod_count+13c/1860>
Trace; c010740f <__up_wakeup+1243/2874>
Code; c01924d7 <driver_for_each_dev+e7/130>
00000000 <_EIP>:
Code; c01924d7 <driver_for_each_dev+e7/130> <=====
0: 0f 0b ud2a <=====
Code; c01924d9 <driver_for_each_dev+e9/130>
2: 73 00 jae 4 <_EIP+0x4> c01924db <driver_for_each_
dev+eb/130>
Code; c01924db <driver_for_each_dev+eb/130>
4: c0 (bad)
Code; c01924dc <driver_for_each_dev+ec/130>
5: 73 23 jae 2a <_EIP+0x2a> c0192501 <driver_for_eac
h_dev+111/130>
Code; c01924de <driver_for_each_dev+ee/130>
7: c0 e9 26 shr $0x26,%cl
Code; c01924e1 <driver_for_each_dev+f1/130>
a: ff (bad)
Code; c01924e2 <driver_for_each_dev+f2/130>
b: ff (bad)
Code; c01924e3 <driver_for_each_dev+f3/130>
c: ff 8d b6 00 00 00 decl 0xb6(%ebp)
Code; c01924e9 <driver_for_each_dev+f9/130>
12: 00 8d 00 00 00 00 add %cl,0x0(%ebp)


The module in question is apparently:

IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 1024 buckets, 8Kbytes
TCP: Hash tables configured (established 16384 bind 32768)
NET4: Unix domain sockets 1.0/SMP 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: 240k freed
usb.c: registered new driver usbfs
usb.c: registered new driver hub
EXT3 FS 2.4-0.9.16, 02 Dec 2001 on ide0(3,5), internal journal
kjournald starting. Commit interval 5 seconds
EXT3 FS 2.4-0.9.16, 02 Dec 2001 on ide0(3,1), internal journal
EXT3-fs: mounted filesystem with ordered data mode.
Adding Swap: 400640k swap-space (priority -1)
isapnp: Scanning for PnP cards...
isapnp: No Plug & Play device found
Serial driver version 5.05c (2001-07-08) with MANY_PORTS SHARE_IRQ SERIAL_PCI IS
APNP enabled
ttyS01 at 0x02f8 (irq = 3) is a 16550A
PCI: Found IRQ 5 for device 00:00.2
PCI: Sharing IRQ 5 with 00:06.0
PCI: Sharing IRQ 5 with 00:0c.1
register_serial(): autoconfig failed
kernel BUG at /usr/src/linux/include/linux/device.h:115!
invalid operand: 0000
CPU: 0
EIP: 0010:[<c01924d7>] Not tainted
EFLAGS: 00010246
eax: 00000000 ebx: cafaa000 ecx: cd074f50 edx: cd074f48
esi: 00000000 edi: 00000000 ebp: bfffeba8 esp: cafabf30
ds: 0018 es: 0018 ss: 0018
Process modprobe (pid: 251, threadinfo=cafaa000 task=cbc0e080)
Stack: 00000010 00000246 c0125450 cafaa000 cd074f48 00000000 bfffeba8 c01911fb
cd074f48 cd074f48 c0191170 c0192628 cd074f48 c025abe8 00000000 00000000
cd0715b9 cd074f48 cd06d000 fffffff0 c0119763 cd06d000 cd06d000 fffffff0
Call Trace: [<c0125450>] [<cd074f48>] [<c01911fb>] [<cd074f48>] [<cd074f48>]
[<c0191170>] [<c0192628>] [<cd074f48>] [<cd0715b9>] [<cd074f48>] [<c0119763>]

[<c011894c>] [<c010740f>]

Code: 0f 0b 73 00 c0 73 23 c0 e9 26 ff ff ff 8d b6 00 00 00 00 8d
<6>note: modprobe[251] exited with preempt_count 1
8139too Fast Ethernet driver 0.9.24
PCI: Found IRQ 11 for device 00:09.0
eth0: RealTek RTL8139 Fast Ethernet at 0xcd081000, 00:e0:18:19:6b:77, IRQ 11
eth0: Identified 8139 chip type 'RTL-8139C'
eth0: Setting 100mbps half-duplex based on auto-negotiated partner ability 40a1.
Linux Kernel Card Services 3.1.22
options: [pci] [cardbus] [pm]
PCI: Found IRQ 11 for device 00:0c.0
PCI: Sharing IRQ 11 with 00:02.0
PCI: Found IRQ 5 for device 00:0c.1
PCI: Sharing IRQ 5 with 00:00.2
PCI: Sharing IRQ 5 with 00:06.0

This corresponds to the following BUG_ON

static inline struct device_driver * get_driver(struct device_driver * drv)
{
BUG_ON(!atomic_read(&drv->refcount));
atomic_inc(&drv->refcount);
return drv;
}

So apparently the module initialization there is
broken in the case of a box without a serial port at all on it.

2002-06-03 15:04:41

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.20 airo wireless - "I can't get no, compilation..."

diff -urN linux-2.5.20/drivers/net/wireless/airo.c linux/drivers/net/wireless/airo.c
--- linux-2.5.20/drivers/net/wireless/airo.c 2002-06-03 03:44:41.000000000 +0200
+++ linux/drivers/net/wireless/airo.c 2002-06-03 09:55:16.000000000 +0200
@@ -191,12 +191,6 @@
#ifndef RUN_AT
#define RUN_AT(x) (jiffies+(x))
#endif
-#ifndef PDE
-static inline struct proc_dir_entry *PDE(const struct inode *inode)
-{
- return inode->u.generic_ip;
-}
-#endif


/* These variables are for insmod, since it seems that the rates
@@ -723,7 +717,7 @@

/* Leave gap of 40 commands after AIROGSTATSD32 for future */

-#define AIROPCAP AIROGSTATSD32 + 40
+#define AIROPCAP AIROGSTATSD32 + 40
#define AIROPVLIST AIROPCAP + 1
#define AIROPSLIST AIROPVLIST + 1
#define AIROPCFG AIROPSLIST + 1
@@ -845,7 +839,7 @@
struct proc_dir_entry *proc_entry;
struct airo_info *next;
spinlock_t aux_lock;
- int flags;
+ unsigned long flags;
#define FLAG_PROMISC IFF_PROMISC
#define FLAG_RADIO_OFF 0x02
#define FLAG_LOCKED 2
@@ -866,7 +860,7 @@
#ifdef WIRELESS_EXT
struct iw_statistics wstats; // wireless stats
unsigned long scan_timestamp; /* Time started to scan */
- struct tq_struct event_task;
+ struct tq_struct event_task;
#ifdef WIRELESS_SPY
int spy_number;
u_char spy_address[IW_MAX_SPY][6];


Attachments:
ario-2.5.20.diff (1.33 kB)

2002-06-03 15:08:11

by Martin Dalecki

[permalink] [raw]
Subject: ]PATCH] 2.5.20 IDE 83

diff -urN linux-2.5.20/arch/i386/pci/fixup.c linux/arch/i386/pci/fixup.c
--- linux-2.5.20/arch/i386/pci/fixup.c 2002-06-03 03:44:42.000000000 +0200
+++ linux/arch/i386/pci/fixup.c 2002-06-03 16:45:45.000000000 +0200
@@ -99,6 +99,17 @@
d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
}

+static void __devinit pci_fixup_ide_exbar(struct pci_dev *d)
+{
+ /*
+ * Some new Intel IDE controllers have an EXBAR register for
+ * MMIO instead of PIO. It's unused, undocumented (though maybe
+ * functional). BIOSes often assign conflicting memory address
+ * to this. Just kill it.
+ */
+ d->resource[5].start = d->resource[5].end = d->resource[5].flags = 0;
+}
+
static void __devinit pci_fixup_latency(struct pci_dev *d)
{
/*
@@ -174,6 +185,9 @@
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci_fixup_piix4_acpi },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_exbar },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_exbar },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_exbar },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_northbridge_bug },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug },
diff -urN linux-2.5.20/drivers/ide/Config.help linux/drivers/ide/Config.help
--- linux-2.5.20/drivers/ide/Config.help 2002-06-03 03:44:52.000000000 +0200
+++ linux/drivers/ide/Config.help 2002-06-03 14:43:45.000000000 +0200
@@ -409,13 +409,14 @@
the chip to optimum performance.

CONFIG_BLK_DEV_PIIX_TRY133
- The ICH2, ICH2-M, ICH3, ICH3-M, ICH3-S and CICH chips can support
- UDMA133 in hardware, even though the specifications of the chips
- say otherwise. By enabling this option, you allow the driver to
- enable the UDMA133 mode on these chips.
+ The ICH2, ICH2-M, ICH3, ICH3-M, ICH3-S, ICH-4 and CICH chips can
+ support UDMA133 in hardware, even though the specifications of
+ the chips say otherwise. By enabling this option, you allow the
+ driver to enable the UDMA133 mode on these chips. Note that if
+ it doesn't work, your data gets lost, you're on your own, don't
+ expect any help.

- If you want to stay on the safe side, say N here.
- If you prefer maximum performance, say Y here.
+ Say N here, unless you really know what are you doing.

CONFIG_BLK_DEV_PDC202XX
Promise Ultra33 or PDC20246
diff -urN linux-2.5.20/drivers/ide/Config.in linux/drivers/ide/Config.in
--- linux-2.5.20/drivers/ide/Config.in 2002-06-03 03:44:53.000000000 +0200
+++ linux/drivers/ide/Config.in 2002-06-03 14:43:45.000000000 +0200
@@ -53,7 +53,7 @@
dep_bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' Intel and Efar (SMsC) chipset support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI
if [ "$CONFIG_BLK_DEV_PIIX" = "y" ]; then
- dep_bool ' Use UDMA133 even on ICH2, ICH3 and CICH chips (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TRY133 $CONFIG_EXPERIMENTAL
+ dep_bool ' Allow undocumented UDMA133 on ICH chips (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TRY133 $CONFIG_EXPERIMENTAL
fi
if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then
dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI
diff -urN linux-2.5.20/drivers/ide/device.c linux/drivers/ide/device.c
--- linux-2.5.20/drivers/ide/device.c 2002-06-03 03:44:46.000000000 +0200
+++ linux/drivers/ide/device.c 2002-06-03 14:51:18.000000000 +0200
@@ -159,4 +159,18 @@
OUT_BYTE(rf->high_cylinder, ch->io_ports[IDE_HCYL_OFFSET]);
}

+/*
+ * Output a complete register file.
+ */
+void ata_in_regfile(struct ata_device *drive, struct hd_drive_task_hdr *rf)
+{
+ struct ata_channel *ch = drive->channel;
+
+ rf->sector_count = IN_BYTE(ch->io_ports[IDE_NSECTOR_OFFSET]);
+ rf->sector_number = IN_BYTE(ch->io_ports[IDE_SECTOR_OFFSET]);
+ rf->low_cylinder = IN_BYTE(ch->io_ports[IDE_LCYL_OFFSET]);
+ rf->high_cylinder = IN_BYTE(ch->io_ports[IDE_HCYL_OFFSET]);
+}
+
+
MODULE_LICENSE("GPL");
diff -urN linux-2.5.20/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- linux-2.5.20/drivers/ide/hpt34x.c 2002-06-03 03:44:41.000000000 +0200
+++ linux/drivers/ide/hpt34x.c 2002-06-03 12:35:54.000000000 +0200
@@ -253,7 +253,7 @@
unsigned int count;
u8 cmd;

- if (!(count = udma_new_table(ch, rq)))
+ if (!(count = udma_new_table(drive, rq)))
return 1; /* try PIO instead of DMA */

if (rq_data_dir(rq) == READ)
diff -urN linux-2.5.20/drivers/ide/icside.c linux/drivers/ide/icside.c
--- linux-2.5.20/drivers/ide/icside.c 2002-06-03 03:44:41.000000000 +0200
+++ linux/drivers/ide/icside.c 2002-06-03 12:35:54.000000000 +0200
@@ -275,8 +275,9 @@
#define NR_ENTRIES 256
#define TABLE_SIZE (NR_ENTRIES * 8)

-static int ide_build_sglist(struct ata_channel *ch, struct request *rq)
+static int ide_build_sglist(struct ata_device *drive, struct request *rq)
{
+ struct ata_channel *ch = drive->channel;
struct scatterlist *sg = ch->sg_table;
int nents;

@@ -294,7 +295,7 @@
sg->length = rq->nr_sectors * SECTOR_SIZE;
nents = 1;
} else {
- nents = blk_rq_map_sg(rq->q, rq, sg);
+ nents = blk_rq_map_sg(&drive->queue, rq, sg);

if (rq->q && nents > rq->nr_phys_segments)
printk("icside: received %d segments, build %d\n",
@@ -586,7 +587,7 @@
{
printk(KERN_ERR "ATA: %s: UDMA timeout occured:", drive->name);
ata_status(drive, 0, 0);
- ide_dump_status(drive, NULL, "UDMA timeout", drive->status);
+ ata_dump(drive, NULL, "UDMA timeout");
}

static void icside_irq_lost(struct ata_device *drive)
diff -urN linux-2.5.20/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.20/drivers/ide/ide.c 2002-06-03 03:44:48.000000000 +0200
+++ linux/drivers/ide/ide.c 2002-06-03 14:52:20.000000000 +0200
@@ -405,10 +405,7 @@
rq->errors = !ata_status(drive, READY_STAT, BAD_STAT);
if (ar) {
ar->taskfile.feature = IN_BYTE(IDE_ERROR_REG);
- ar->taskfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
- ar->taskfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
- ar->taskfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
- ar->taskfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
+ ata_in_regfile(drive, &ar->taskfile);
ar->taskfile.device_head = IN_BYTE(IDE_SELECT_REG);
if ((drive->id->command_set_2 & 0x0400) &&
(drive->id->cfs_enable_2 & 0x0400) &&
@@ -416,10 +413,7 @@
/* The following command goes to the hob file! */
OUT_BYTE(0x80, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
ar->hobfile.feature = IN_BYTE(IDE_FEATURE_REG);
- ar->hobfile.sector_count = IN_BYTE(IDE_NSECTOR_REG);
- ar->hobfile.sector_number = IN_BYTE(IDE_SECTOR_REG);
- ar->hobfile.low_cylinder = IN_BYTE(IDE_LCYL_REG);
- ar->hobfile.high_cylinder = IN_BYTE(IDE_HCYL_REG);
+ ata_in_regfile(drive, &ar->hobfile);
}
}
}
@@ -437,46 +431,46 @@
};

static struct ata_bit_messages ata_status_msgs[] = {
- { BUSY_STAT, BUSY_STAT, "Busy" },
- { READY_STAT, READY_STAT, "DriveReady" },
- { WRERR_STAT, WRERR_STAT, "DeviceFault" },
- { SEEK_STAT, SEEK_STAT, "SeekComplete" },
- { DRQ_STAT, DRQ_STAT, "DataRequest" },
- { ECC_STAT, ECC_STAT, "CorrectedError" },
- { INDEX_STAT, INDEX_STAT, "Index" },
- { ERR_STAT, ERR_STAT, "Error" }
+ { BUSY_STAT, BUSY_STAT, "busy" },
+ { READY_STAT, READY_STAT, "drive ready" },
+ { WRERR_STAT, WRERR_STAT, "device fault" },
+ { SEEK_STAT, SEEK_STAT, "seek complete" },
+ { DRQ_STAT, DRQ_STAT, "data request" },
+ { ECC_STAT, ECC_STAT, "corrected error" },
+ { INDEX_STAT, INDEX_STAT, "index" },
+ { ERR_STAT, ERR_STAT, "error" }
};

static struct ata_bit_messages ata_error_msgs[] = {
- { ICRC_ERR|ABRT_ERR, ABRT_ERR, "DriveStatusError" },
- { ICRC_ERR|ABRT_ERR, ICRC_ERR, "BadSector" },
- { ICRC_ERR|ABRT_ERR, ICRC_ERR|ABRT_ERR, "BadCRC" },
- { ECC_ERR, ECC_ERR, "UncorrectableError" },
- { ID_ERR, ID_ERR, "SectorIdNotFound" },
- { TRK0_ERR, TRK0_ERR, "TrackZeroNotFound" },
- { MARK_ERR, MARK_ERR, "AddrMarkNotFound" }
+ { ICRC_ERR|ABRT_ERR, ABRT_ERR, "drive status error" },
+ { ICRC_ERR|ABRT_ERR, ICRC_ERR, "bad sectorr" },
+ { ICRC_ERR|ABRT_ERR, ICRC_ERR|ABRT_ERR, "invalid checksum" },
+ { ECC_ERR, ECC_ERR, "uncorrectable error" },
+ { ID_ERR, ID_ERR, "sector id not found" },
+ { TRK0_ERR, TRK0_ERR, "track zero not found" },
+ { MARK_ERR, MARK_ERR, "addr mark not found" }
};

-static void ata_dump_bits(struct ata_bit_messages *msgs, int nr, byte bits)
+static void dump_bits(struct ata_bit_messages *msgs, int nr, byte bits)
{
int i;

- printk(" { ");
+ printk(" [ ");

for (i = 0; i < nr; i++, msgs++)
if ((bits & msgs->mask) == msgs->match)
printk("%s ", msgs->msg);

- printk("} ");
+ printk("] ");
}
#else
-# define ata_dump_bits(msgs,nr,bits) do { } while (0)
+# define dump_bits(msgs,nr,bits) do { } while (0)
#endif

/*
* Error reporting, in human readable form (luxurious, but a memory hog).
*/
-u8 ide_dump_status(struct ata_device *drive, struct request * rq, const char *msg, u8 stat)
+u8 ata_dump(struct ata_device *drive, struct request * rq, const char *msg)
{
unsigned long flags;
u8 err = 0;
@@ -484,16 +478,16 @@
__save_flags (flags); /* local CPU only */
ide__sti(); /* local CPU only */

- printk("%s: %s: status=0x%02x", drive->name, msg, stat);
- ata_dump_bits(ata_status_msgs, ARRAY_SIZE(ata_status_msgs), stat);
+ printk("%s: %s: status=0x%02x", drive->name, msg, drive->status);
+ dump_bits(ata_status_msgs, ARRAY_SIZE(ata_status_msgs), drive->status);
printk("\n");

- if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
+ if ((drive->status & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
err = GET_ERR();
printk("%s: %s: error=0x%02x", drive->name, msg, err);
#if FANCY_STATUS_DUMPS
if (drive->type == ATA_DISK) {
- ata_dump_bits(ata_error_msgs, ARRAY_SIZE(ata_error_msgs), err);
+ dump_bits(ata_error_msgs, ARRAY_SIZE(ata_error_msgs), err);

if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR || (err & (ECC_ERR|ID_ERR|MARK_ERR))) {
if ((drive->id->command_set_2 & 0x0400) &&
@@ -592,7 +586,7 @@
u8 err;
u8 stat = drive->status;

- err = ide_dump_status(drive, rq, msg, stat);
+ err = ata_dump(drive, rq, msg);
if (!drive || !rq)
return ide_stopped;

@@ -1476,7 +1470,7 @@
EXPORT_SYMBOL(do_ide_request);

EXPORT_SYMBOL(ide_set_handler);
-EXPORT_SYMBOL(ide_dump_status);
+EXPORT_SYMBOL(ata_dump);
EXPORT_SYMBOL(ata_error);

EXPORT_SYMBOL(ide_wait_stat);
diff -urN linux-2.5.20/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c
--- linux-2.5.20/drivers/ide/ide-cd.c 2002-06-03 03:44:48.000000000 +0200
+++ linux/drivers/ide/ide-cd.c 2002-06-03 10:46:58.000000000 +0200
@@ -614,7 +614,7 @@
return 0;
} else if (!pc->quiet) {
/* Otherwise, print an error. */
- ide_dump_status(drive, rq, "packet command error", drive->status);
+ ata_dump(drive, rq, "packet command error");
}

/* Set the error flag and complete the request.
@@ -662,13 +662,13 @@
sense_key == DATA_PROTECT) {
/* No point in retrying after an illegal
request or data protect error.*/
- ide_dump_status(drive, rq, "command error", drive->status);
+ ata_dump(drive, rq, "command error");
cdrom_end_request(drive, rq, 0);
} else if (sense_key == MEDIUM_ERROR) {
/* No point in re-trying a zillion times on a bad
* sector. The error is not correctable at all.
*/
- ide_dump_status(drive, rq, "media error (bad sector)", drive->status);
+ ata_dump(drive, rq, "media error (bad sector)");
cdrom_end_request(drive, rq, 0);
} else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler
diff -urN linux-2.5.20/drivers/ide/pcidma.c linux/drivers/ide/pcidma.c
--- linux-2.5.20/drivers/ide/pcidma.c 2002-06-03 03:44:43.000000000 +0200
+++ linux/drivers/ide/pcidma.c 2002-06-03 12:35:54.000000000 +0200
@@ -58,8 +58,9 @@
* FIXME: taskfiles should be a map of pages, not a long virt address... /jens
* FIXME: I agree with Jens --mdcki!
*/
-static int build_sglist(struct ata_channel *ch, struct request *rq)
+static int build_sglist(struct ata_device *drive, struct request *rq)
{
+ struct ata_channel *ch = drive->channel;
struct scatterlist *sg = ch->sg_table;
int nents = 0;

@@ -69,7 +70,7 @@
unsigned char *virt_addr = rq->buffer;
int sector_count = rq->nr_sectors;
#else
- nents = blk_rq_map_sg(rq->q, rq, ch->sg_table);
+ nents = blk_rq_map_sg(&drive->queue, rq, ch->sg_table);

if (nents > rq->nr_segments)
printk("ide-dma: received %d segments, build %d\n", rq->nr_segments, nents);
@@ -99,7 +100,7 @@
sg[nents].length = sector_count * SECTOR_SIZE;
++nents;
} else {
- nents = blk_rq_map_sg(rq->q, rq, ch->sg_table);
+ nents = blk_rq_map_sg(&drive->queue, rq, ch->sg_table);

if (rq->q && nents > rq->nr_phys_segments)
printk("ide-dma: received %d phys segments, build %d\n", rq->nr_phys_segments, nents);
@@ -150,7 +151,7 @@
reading = 1 << 3;

/* try PIO instead of DMA */
- if (!udma_new_table(ch, rq))
+ if (!udma_new_table(drive, rq))
return 1;

outl(ch->dmatable_dma, dma_base + 4); /* PRD table */
@@ -306,8 +307,9 @@
* This prepares a dma request. Returns 0 if all went okay, returns 1
* otherwise. May also be invoked from trm290.c
*/
-int udma_new_table(struct ata_channel *ch, struct request *rq)
+int udma_new_table(struct ata_device *drive, struct request *rq)
{
+ struct ata_channel *ch = drive->channel;
unsigned int *table = ch->dmatable_cpu;
#ifdef CONFIG_BLK_DEV_TRM290
unsigned int is_trm290_chipset = (ch->chipset == ide_trm290);
@@ -318,7 +320,7 @@
int i;
struct scatterlist *sg;

- ch->sg_nents = i = build_sglist(ch, rq);
+ ch->sg_nents = i = build_sglist(drive, rq);
if (!i)
return 0;

diff -urN linux-2.5.20/drivers/ide/piix.c linux/drivers/ide/piix.c
--- linux-2.5.20/drivers/ide/piix.c 2002-06-03 03:44:47.000000000 +0200
+++ linux/drivers/ide/piix.c 2002-06-03 14:43:45.000000000 +0200
@@ -1,6 +1,5 @@
-/**** vi:set ts=8 sts=8 sw=8:************************************************
- *
- * $Id: piix.c,v 1.3 2002/03/29 16:06:06 vojtech Exp $
+/*
+ * piix.c, v1.5 2002/05/03
*
* Copyright (c) 2000-2002 Vojtech Pavlik
*
@@ -9,6 +8,7 @@
* Andre Hedrick
*
* Thanks to Daniela Egbert for advice on PIIX bugs.
+ * Thanks to Ulf Axelsson for noticing that ICH4 only documents UDMA100.
*/

/*
@@ -85,20 +85,20 @@
unsigned short id;
unsigned char flags;
} piix_ide_chips[] = {
- { PCI_DEVICE_ID_INTEL_82801DB_9, PIIX_UDMA_133 | PIIX_PINGPONG }, /* Intel 82801DB ICH4 */
- { PCI_DEVICE_ID_INTEL_82801CA_11, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801CA ICH3/ICH3-S */
- { PCI_DEVICE_ID_INTEL_82801CA_10, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801CAM ICH3-M */
- { PCI_DEVICE_ID_INTEL_82801E_9, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801E C-ICH */
- { PCI_DEVICE_ID_INTEL_82801BA_9, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801BA ICH2 */
- { PCI_DEVICE_ID_INTEL_82801BA_8, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801BAM ICH2-M */
- { PCI_DEVICE_ID_INTEL_82801AB_1, PIIX_UDMA_33 | PIIX_PINGPONG }, /* Intel 82801AB ICH0 */
- { PCI_DEVICE_ID_INTEL_82801AA_1, PIIX_UDMA_66 | PIIX_PINGPONG }, /* Intel 82801AA ICH */
- { PCI_DEVICE_ID_INTEL_82372FB_1, PIIX_UDMA_66 }, /* Intel 82372FB PIIX5 */
- { PCI_DEVICE_ID_INTEL_82443MX_1, PIIX_UDMA_33 }, /* Intel 82443MX MPIIX4 */
- { PCI_DEVICE_ID_INTEL_82371AB, PIIX_UDMA_33 }, /* Intel 82371AB/EB PIIX4/PIIX4E */
- { PCI_DEVICE_ID_INTEL_82371SB_1, PIIX_UDMA_NONE }, /* Intel 82371SB PIIX3 */
- { PCI_DEVICE_ID_INTEL_82371FB_1, PIIX_UDMA_NONE | PIIX_NO_SITRE | PIIX_CHECK_REV }, /* Intel 82371FB PIIX */
- { PCI_DEVICE_ID_EFAR_SLC90E66_1, PIIX_UDMA_66 | PIIX_VICTORY }, /* Efar Victory66 */
+ { PCI_DEVICE_ID_INTEL_82801DB_9, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801DB ICH4 */
+ { PCI_DEVICE_ID_INTEL_82801CA_11, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801CA ICH3/ICH3-S */
+ { PCI_DEVICE_ID_INTEL_82801CA_10, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801CAM ICH3-M */
+ { PCI_DEVICE_ID_INTEL_82801E_9, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801E C-ICH */
+ { PCI_DEVICE_ID_INTEL_82801BA_9, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801BA ICH2 */
+ { PCI_DEVICE_ID_INTEL_82801BA_8, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801BAM ICH2-M */
+ { PCI_DEVICE_ID_INTEL_82801AB_1, PIIX_UDMA_33 | PIIX_PINGPONG}, /* Intel 82801AB ICH0 */
+ { PCI_DEVICE_ID_INTEL_82801AA_1, PIIX_UDMA_66 | PIIX_PINGPONG }, /* Intel 82801AA ICH */
+ { PCI_DEVICE_ID_INTEL_82372FB_1, PIIX_UDMA_66 }, /* Intel 82372FB PIIX5 */
+ { PCI_DEVICE_ID_INTEL_82443MX_1, PIIX_UDMA_33 }, /* Intel 82443MX MPIIX4 */
+ { PCI_DEVICE_ID_INTEL_82371AB, PIIX_UDMA_33 }, /* Intel 82371AB/EB PIIX4/PIIX4E */
+ { PCI_DEVICE_ID_INTEL_82371SB_1, PIIX_UDMA_NONE }, /* Intel 82371SB PIIX3 */
+ { PCI_DEVICE_ID_INTEL_82371FB_1, PIIX_UDMA_NONE | PIIX_NO_SITRE | PIIX_CHECK_REV }, /* Intel 82371FB PIIX */
+ { PCI_DEVICE_ID_EFAR_SLC90E66_1, PIIX_UDMA_66 | PIIX_VICTORY }, /* Efar Victory66 */
{ 0 }
};

@@ -122,7 +122,7 @@

switch (dn & 1) {

- case 1:
+ case 1:
if (timing->cycle > 9) {
t &= ~0x30;
break;
@@ -177,7 +177,7 @@
&& ~piix_config->flags & PIIX_VICTORY) {

pci_read_config_dword(dev, PIIX_IDECFG, &c);
-
+
if ((piix_config->flags & PIIX_UDMA) > PIIX_UDMA_66)
c &= ~(1 << (dn + 12));
c &= ~(1 << dn);
@@ -214,7 +214,7 @@
umul = 2;
if (speed > XFER_UDMA_4 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100)
umul = 4;
-
+
T = 1000000000 / system_bus_speed;
UT = T / umul;

@@ -280,6 +280,7 @@
*/
static unsigned int __init piix_init_chipset(struct pci_dev *dev)
{
+ struct pci_dev *orion = NULL;
unsigned int u;
unsigned short w;
unsigned char t;
@@ -293,55 +294,24 @@
if (dev->device == piix_config->id)
break;

- if (!piix_config->id) {
- printk(KERN_WARNING "PIIX: Unknown PIIX/ICH chip %#x, contact Vojtech Pavlik <[email protected]>\n", dev->device);
- return -ENODEV;
- }
-
/*
* Check for possibly broken DMA configs.
*/

- {
- struct pci_dev *orion = NULL;
-
- if (piix_config->flags & PIIX_CHECK_REV) {
- pci_read_config_byte(dev, PCI_REVISION_ID, &t);
- if (t < 2) {
- printk(KERN_INFO "PIIX: Found buggy old PIIX rev %#x, disabling DMA\n", t);
- piix_config->flags |= PIIX_NODMA;
- }
- }
-
- if ((orion = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, NULL))) {
- pci_read_config_byte(orion, PCI_REVISION_ID, &t);
- if (t < 4) {
- printk(KERN_INFO "PIIX: Found buggy 82454GX Orion bridge rev %#x, disabling DMA\n", t);
- piix_config->flags |= PIIX_NODMA;
- }
+ if (piix_config->flags & PIIX_CHECK_REV) {
+ pci_read_config_byte(dev, PCI_REVISION_ID, &t);
+ if (t < 2) {
+ printk(KERN_INFO "PIIX: Found buggy old PIIX rev %#x, disabling DMA\n", t);
+ piix_config->flags |= PIIX_NODMA;
}
}

-/*
- * Check 80-wire cable presence.
- */
-
- switch (piix_config->flags & PIIX_UDMA) {
-
- case PIIX_UDMA_66:
- if (piix_config->flags && PIIX_VICTORY) {
- pci_read_config_byte(dev, PIIX_IDESTAT, &t);
- piix_80w = ((t & 2) ? 1 : 0) | ((t & 1) ? 2 : 0);
- break;
- }
-
-#ifndef CONFIG_BLK_DEV_PIIX_TRY133
- case PIIX_UDMA_100:
-#endif
- case PIIX_UDMA_133:
- pci_read_config_dword(dev, PIIX_IDECFG, &u);
- piix_80w = ((u & 0x30) ? 1 : 0) | ((u & 0xc0) ? 2 : 0);
- break;
+ if ((orion = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, NULL))) {
+ pci_read_config_byte(orion, PCI_REVISION_ID, &t);
+ if (t < 4) {
+ printk(KERN_INFO "PIIX: Found buggy 82454GX Orion bridge rev %#x, disabling DMA\n", t);
+ piix_config->flags |= PIIX_NODMA;
+ }
}

/*
@@ -377,32 +347,44 @@
return 0;
}

-static unsigned int __init piix_ata66_check(struct ata_channel *hwif)
+static unsigned int __init piix_ata66_check(struct ata_channel *ch)
{
- return ((piix_enabled & piix_80w) >> hwif->unit) & 1;
+ unsigned char t;
+ unsigned int u;
+
+ if ((piix_config->flags & PIIX_UDMA) < PIIX_UDMA_66)
+ return 0;
+
+ if (piix_config->flags & PIIX_VICTORY) {
+ pci_read_config_byte(ch->pci_dev, PIIX_IDESTAT, &t);
+ return ch->unit ? (t & 1) : !!(t & 2);
+ }
+
+ pci_read_config_dword(ch->pci_dev, PIIX_IDECFG, &u);
+ return ch->unit ? !!(u & 0xc0) : !!(u & 0x30);
}

-static void __init piix_init_channel(struct ata_channel *hwif)
+static void __init piix_init_channel(struct ata_channel *ch)
{
int i;

- hwif->tuneproc = &piix_tune_drive;
- hwif->speedproc = &piix_set_drive;
- hwif->autodma = 0;
- hwif->io_32bit = 1;
- hwif->unmask = 1;
+ ch->tuneproc = &piix_tune_drive;
+ ch->speedproc = &piix_set_drive;
+ ch->autodma = 0;
+ ch->io_32bit = 1;
+ ch->unmask = 1;
for (i = 0; i < 2; i++) {
- hwif->drives[i].autotune = 1;
- hwif->drives[i].dn = hwif->unit * 2 + i;
+ ch->drives[i].autotune = 1;
+ ch->drives[i].dn = ch->unit * 2 + i;
}

#ifdef CONFIG_BLK_DEV_IDEDMA
- if (hwif->dma_base) {
- hwif->highmem = 1;
- hwif->udma_setup = piix_udma_setup;
+ if (ch->dma_base) {
+ ch->highmem = 1;
+ ch->udma_setup = piix_udma_setup;
# ifdef CONFIG_IDEDMA_AUTO
if (!noautodma)
- hwif->autodma = 1;
+ ch->autodma = 1;
# endif
}
#endif
@@ -412,11 +394,11 @@
* We allow the BM-DMA driver only work on enabled interfaces,
* and only if DMA is safe with the chip and bridge.
*/
-static void __init piix_init_dma(struct ata_channel *hwif, unsigned long dmabase)
+static void __init piix_init_dma(struct ata_channel *ch, unsigned long dmabase)
{
- if (((piix_enabled >> hwif->unit) & 1)
+ if (((piix_enabled >> ch->unit) & 1)
&& !(piix_config->flags & PIIX_NODMA))
- ata_init_dma(hwif, dmabase);
+ ata_init_dma(ch, dmabase);
}


diff -urN linux-2.5.20/drivers/ide/probe.c linux/drivers/ide/probe.c
--- linux-2.5.20/drivers/ide/probe.c 2002-06-03 03:44:37.000000000 +0200
+++ linux/drivers/ide/probe.c 2002-06-03 10:45:51.000000000 +0200
@@ -385,7 +385,7 @@
enable_irq(ch->irq);

if (error) {
- ide_dump_status(drive, NULL, "set_drive_speed_status", drive->status);
+ ata_dump(drive, NULL, "set drive speed");
return error;
}

diff -urN linux-2.5.20/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.20/drivers/ide/tcq.c 2002-06-03 03:44:52.000000000 +0200
+++ linux/drivers/ide/tcq.c 2002-06-03 10:51:31.000000000 +0200
@@ -247,8 +247,7 @@
OUT_BYTE(WIN_QUEUED_SERVICE, IDE_COMMAND_REG);

if (wait_altstat(drive, &stat, BUSY_STAT)) {
- printk(KERN_ERR"%s: BUSY clear took too long\n", __FUNCTION__);
- ide_dump_status(drive, rq, __FUNCTION__, stat);
+ ata_dump(drive, rq, "BUSY clear took too long");
tcq_invalidate_queue(drive);

return ide_stopped;
@@ -262,7 +261,7 @@
* FIXME, invalidate queue
*/
if (stat & ERR_STAT) {
- ide_dump_status(drive, rq, __FUNCTION__, stat);
+ ata_dump(drive, rq, "ERR condition");
tcq_invalidate_queue(drive);

return ide_stopped;
@@ -328,8 +327,7 @@
* must be end of I/O, check status and complete as necessary
*/
if (!ata_status(drive, READY_STAT, drive->bad_wstat | DRQ_STAT)) {
- printk(KERN_ERR "%s: %s: error status %x\n", __FUNCTION__, drive->name, drive->status);
- ide_dump_status(drive, rq, __FUNCTION__, drive->status);
+ ata_dump(drive, rq, __FUNCTION__);
tcq_invalidate_queue(drive);

return ide_stopped;
@@ -557,7 +555,7 @@
OUT_BYTE(args->cmd, IDE_COMMAND_REG);

if (wait_altstat(drive, &stat, BUSY_STAT)) {
- ide_dump_status(drive, rq, "queued start", stat);
+ ata_dump(drive, rq, "queued start");
tcq_invalidate_queue(drive);
return ide_stopped;
}
@@ -567,7 +565,7 @@
#endif

if (stat & ERR_STAT) {
- ide_dump_status(drive, rq, "tcq_start", stat);
+ ata_dump(drive, rq, "tcq_start");
return ide_stopped;
}

diff -urN linux-2.5.20/drivers/ide/trm290.c linux/drivers/ide/trm290.c
--- linux-2.5.20/drivers/ide/trm290.c 2002-06-03 03:44:43.000000000 +0200
+++ linux/drivers/ide/trm290.c 2002-06-03 12:35:54.000000000 +0200
@@ -217,7 +217,7 @@
writing = 0;
}

- if (!(count = udma_new_table(ch, rq))) {
+ if (!(count = udma_new_table(drive, rq))) {
trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1; /* try PIO instead of DMA */
}
diff -urN linux-2.5.20/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- linux-2.5.20/drivers/scsi/ide-scsi.c 2002-06-03 03:44:39.000000000 +0200
+++ linux/drivers/scsi/ide-scsi.c 2002-06-03 12:37:26.000000000 +0200
@@ -229,10 +229,15 @@
printk("]\n");
}

+static inline idescsi_scsi_t *idescsi_private(struct Scsi_Host *host)
+{
+ return (idescsi_scsi_t*) &host[1];
+}
+
static int idescsi_end_request(struct ata_device *drive, struct request *rq, int uptodate)
{
struct Scsi_Host *host = drive->driver_data;
- idescsi_scsi_t *scsi = (idescsi_scsi_t *) host->hostdata[0];
+ idescsi_scsi_t *scsi = idescsi_private(host);
struct atapi_packet_command *pc = (struct atapi_packet_command *) rq->special;
int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
u8 *scsi_buf;
@@ -289,7 +294,7 @@
static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request *rq)
{
struct Scsi_Host *host = drive->driver_data;
- idescsi_scsi_t *scsi = (idescsi_scsi_t *) host->hostdata[0];
+ idescsi_scsi_t *scsi = idescsi_private(host);
u8 ireason;
int bcount;
struct atapi_packet_command *pc=scsi->pc;
@@ -372,7 +377,7 @@
static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct request *rq)
{
struct Scsi_Host *host = drive->driver_data;
- idescsi_scsi_t *scsi = (idescsi_scsi_t *) host->hostdata[0];
+ idescsi_scsi_t *scsi = idescsi_private(host);
struct atapi_packet_command *pc = scsi->pc;
byte ireason;
ide_startstop_t startstop;
@@ -398,7 +403,7 @@
struct atapi_packet_command *pc)
{
struct Scsi_Host *host = drive->driver_data;
- idescsi_scsi_t *scsi = (idescsi_scsi_t *) host->hostdata[0];
+ idescsi_scsi_t *scsi = idescsi_private(host);
int bcount;
int dma_ok = 0;

@@ -473,7 +478,6 @@
if (ide_unregister_subdriver (drive)) {
return 1;
}
- kfree((idescsi_scsi_t *) host->hostdata[0]);
scsi_unregister(host);

return 0;
@@ -515,7 +519,7 @@

static int idescsi_ioctl(Scsi_Device *dev, int cmd, void *arg)
{
- idescsi_scsi_t *scsi = (idescsi_scsi_t *) dev->host->hostdata[0];
+ idescsi_scsi_t *scsi = idescsi_private(dev->host);

if (cmd == SG_SET_TRANSFORM) {
if (arg)
@@ -612,7 +616,7 @@
static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd)
{
struct Scsi_Host *host = drive->driver_data;
- idescsi_scsi_t *scsi = (idescsi_scsi_t *) host->hostdata[0];
+ idescsi_scsi_t *scsi = idescsi_private(host);

if (major(cmd->request.rq_dev) == SCSI_GENERIC_MAJOR)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
@@ -621,7 +625,7 @@

static int idescsi_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
{
- idescsi_scsi_t *scsi = (idescsi_scsi_t *) cmd->host->hostdata[0];
+ idescsi_scsi_t *scsi = idescsi_private(cmd->host);
struct ata_device *drive = scsi->drive;
struct request *rq = NULL;
struct atapi_packet_command *pc = NULL;
@@ -691,7 +695,7 @@

static int idescsi_bios(Disk *disk, kdev_t dev, int *parm)
{
- idescsi_scsi_t *scsi = (idescsi_scsi_t *) disk->device->host->hostdata[0];
+ idescsi_scsi_t *scsi = idescsi_private(disk->device->host);
struct ata_device *drive = scsi->drive;

if (drive->bios_cyl && drive->bios_head && drive->bios_sect) {
@@ -758,8 +762,7 @@
drive->driver_data = host;
drive->ready_stat = 0;

- scsi = kmalloc(sizeof(*scsi), GFP_ATOMIC);
- host->hostdata[0] = (unsigned long) scsi;
+ scsi = idescsi_private(host);
memset(scsi,0, sizeof (*scsi));
scsi->drive = drive;

diff -urN linux-2.5.20/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.20/include/linux/ide.h 2002-06-03 03:44:43.000000000 +0200
+++ linux/include/linux/ide.h 2002-06-03 14:52:03.000000000 +0200
@@ -610,11 +610,7 @@
extern void ide_set_handler(struct ata_device *drive, ata_handler_t handler,
unsigned long timeout, ata_expiry_t expiry);

-/*
- * Error reporting, in human readable form (luxurious, but a memory hog).
- */
-extern u8 ide_dump_status(struct ata_device *, struct request *rq, const char *, u8);
-
+extern u8 ata_dump(struct ata_device *, struct request *, const char *);
extern ide_startstop_t ata_error(struct ata_device *, struct request *rq, const char *);

extern void ide_fixstring(char *s, const int bytecount, const int byteswap);
@@ -799,7 +795,7 @@
extern void udma_pci_irq_lost(struct ata_device *);
extern int udma_pci_setup(struct ata_device *);

-extern int udma_new_table(struct ata_channel *, struct request *);
+extern int udma_new_table(struct ata_device *, struct request *);
extern void udma_destroy_table(struct ata_channel *);
extern void udma_print(struct ata_device *);

@@ -834,5 +830,6 @@
extern int ata_irq_enable(struct ata_device *, int);
extern void ata_reset(struct ata_channel *);
extern void ata_out_regfile(struct ata_device *, struct hd_drive_task_hdr *);
+extern void ata_in_regfile(struct ata_device *, struct hd_drive_task_hdr *);

#endif


Attachments:
ide-clean-83.diff (29.19 kB)

2002-06-03 22:39:01

by Rusty Russell

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

In message <[email protected]> you write:
> While moving software suspend, I also took the chance to tweak the Config.help
> entry.

For trivial at least, please split the patches. It makes it easy for
me and/or Linus to accept only one.

Also, please mention clearly if you obsolete a previous trivial patch...

> diff -Naur -X dontdiff linux-2.5.20-clean/arch/i386/Config.help linux-2.5.20-
config-munging/arch/i386/Config.help
> --- linux-2.5.20-clean/arch/i386/Config.help Thu May 30 04:42:46 2002
> +++ linux-2.5.20-config-munging/arch/i386/Config.help Mon Jun 3 12:39:48 200
2
> @@ -641,7 +641,8 @@
> off or put into a power conserving "sleep" mode if they are not
> being used. There are two competing standards for doing this: APM
> and ACPI. If you want to use either one, say Y here and then also
> - to the requisite support below.
> + to the requisite support below. This option is also required for
> + "software suspend", see below.
>
> Power Management is most important for battery powered laptop
> computers; if you have a laptop, check out the Linux Laptop home

Like code, descriptions develop scar tissue when you do the "minimally
invasive" change. Consider this classic trap-for-skimmers from the
glibc "snprintf" man page, and learn:

Return value
These functions return the number of characters printed
(not including the trailing `\0' used to end output to
strings). snprintf and vsnprintf do not write more than
size bytes (including the trailing '\0'), and return -1 if
the output was truncated due to this limit. (Thus until
glibc 2.0.6. Since glibc 2.1 these functions follow the
C99 standard and return the number of characters (exclud?
ing the trailing '\0') which would have been written to
the final string if enough space had been available.)

Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

2002-06-04 12:07:23

by Jens Axboe

[permalink] [raw]
Subject: Re: ]PATCH] 2.5.20 IDE 83

On Mon, Jun 03 2002, Martin Dalecki wrote:
> - Patch for DVD read through ide-scsi. There is the possibility that we can
> get
> request structures passed down, which don't have the queue field set.
> At lest on the BIO code path this seems to be something worth further
> investigation. Found by Adam J. Richter. (Jens?)

It's because of the scsi mid layer queueing private requests which have
rq->q cleared. The fix looks correct.

--
Jens Axboe

2002-06-04 16:29:43

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.20 IDE 84

diff -urN linux-2.5.20/arch/i386/pci/fixup.c linux/arch/i386/pci/fixup.c
--- linux-2.5.20/arch/i386/pci/fixup.c 2002-06-04 14:06:59.000000000 +0200
+++ linux/arch/i386/pci/fixup.c 2002-06-04 10:21:43.000000000 +0200
@@ -99,17 +99,6 @@
d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
}

-static void __devinit pci_fixup_ide_exbar(struct pci_dev *d)
-{
- /*
- * Some new Intel IDE controllers have an EXBAR register for
- * MMIO instead of PIO. It's unused, undocumented (though maybe
- * functional). BIOSes often assign conflicting memory address
- * to this. Just kill it.
- */
- d->resource[5].start = d->resource[5].end = d->resource[5].flags = 0;
-}
-
static void __devinit pci_fixup_latency(struct pci_dev *d)
{
/*
@@ -185,9 +174,9 @@
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, pci_fixup_latency },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5598, pci_fixup_latency },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci_fixup_piix4_acpi },
- { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_exbar },
- { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_exbar },
- { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_exbar },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_trash },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_trash },
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_trash },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_northbridge_bug },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug },
diff -urN linux-2.5.20/drivers/ide/ali14xx.c linux/drivers/ide/ali14xx.c
--- linux-2.5.20/drivers/ide/ali14xx.c 2002-06-03 03:44:48.000000000 +0200
+++ linux/drivers/ide/ali14xx.c 2002-06-04 10:28:53.000000000 +0200
@@ -13,7 +13,7 @@
* I think the code should be pretty understandable,
* but I'll be happy to (try to) answer questions.
*
- * The critical part is in the setupDrive function. The initRegisters
+ * The critical part is in the ali14xx_tune_drive function. The init_registers
* function doesn't seem to be necessary, but the DOS driver does it, so
* I threw it in.
*
@@ -37,12 +37,6 @@

#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/init.h>

@@ -52,12 +46,14 @@

/* port addresses for auto-detection */
#define ALI_NUM_PORTS 4
-static int ports[ALI_NUM_PORTS] __initdata = {0x074, 0x0f4, 0x034, 0x0e4};
+static int ports[ALI_NUM_PORTS] __initdata = { 0x074, 0x0f4, 0x034, 0x0e4 };

/* register initialization data */
-typedef struct { byte reg, data; } RegInitializer;
+struct reg_initializer {
+ u8 reg, data;
+};

-static RegInitializer initData[] __initdata = {
+static struct reg_initializer init_data[] __initdata = {
{0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00},
{0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f},
{0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00},
@@ -68,37 +64,37 @@
};

/* timing parameter registers for each drive */
-static struct { byte reg1, reg2, reg3, reg4; } regTab[4] = {
- {0x03, 0x26, 0x04, 0x27}, /* drive 0 */
- {0x05, 0x28, 0x06, 0x29}, /* drive 1 */
- {0x2b, 0x30, 0x2c, 0x31}, /* drive 2 */
- {0x2d, 0x32, 0x2e, 0x33}, /* drive 3 */
+static struct {
+ u8 reg1, reg2, reg3, reg4;
+} reg_tab[4] = {
+ { 0x03, 0x26, 0x04, 0x27 }, /* drive 0 */
+ { 0x05, 0x28, 0x06, 0x29 }, /* drive 1 */
+ { 0x2b, 0x30, 0x2c, 0x31 }, /* drive 2 */
+ { 0x2d, 0x32, 0x2e, 0x33 }, /* drive 3 */
};

-static int basePort; /* base port address */
-static int regPort; /* port for register number */
-static int dataPort; /* port for register data */
-static byte regOn; /* output to base port to access registers */
-static byte regOff; /* output to base port to close registers */
-
-/*------------------------------------------------------------------------*/
+static int base_port; /* base port address */
+static int reg_port; /* port for register number */
+static int data_port; /* port for register data */
+static u8 reg_on; /* output to base port to access registers */
+static u8 reg_off; /* output to base port to close registers */

/*
* Read a controller register.
*/
-static inline byte inReg (byte reg)
+static inline u8 in_reg(u8 reg)
{
- outb_p(reg, regPort);
- return inb(dataPort);
+ outb_p(reg, reg_port);
+ return inb(data_port);
}

/*
* Write a controller register.
*/
-static void outReg (byte data, byte reg)
+static inline void out_reg(u8 data, u8 reg)
{
- outb_p(reg, regPort);
- outb_p(data, dataPort);
+ outb_p(reg, reg_port);
+ outb_p(data, data_port);
}

/*
@@ -108,7 +104,7 @@
*/
static void ali14xx_tune_drive(struct ata_device *drive, u8 pio)
{
- int driveNum;
+ int drive_num;
int time1, time2;
u8 param1, param2, param3, param4;
unsigned long flags;
@@ -117,7 +113,7 @@
if (pio == 255)
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO);
else
- pio = XFER_PIO_0 + min_t(byte, pio, 4);
+ pio = XFER_PIO_0 + min_t(u8, pio, 4);

t = ata_timing_data(pio);

@@ -130,50 +126,50 @@
param3 += 8;
param4 += 8;
}
- printk("%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n",
+ printk(KERN_DEBUG "%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n",
drive->name, pio - XFER_PIO_0, time1, time2, param1, param2, param3, param4);

/* stuff timing parameters into controller registers */
- driveNum = (drive->channel->index << 1) + drive->select.b.unit;
+ drive_num = (drive->channel->index << 1) + drive->select.b.unit;
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
- outb_p(regOn, basePort);
- outReg(param1, regTab[driveNum].reg1);
- outReg(param2, regTab[driveNum].reg2);
- outReg(param3, regTab[driveNum].reg3);
- outReg(param4, regTab[driveNum].reg4);
- outb_p(regOff, basePort);
+ outb_p(reg_on, base_port);
+ out_reg(param1, reg_tab[drive_num].reg1);
+ out_reg(param2, reg_tab[drive_num].reg2);
+ out_reg(param3, reg_tab[drive_num].reg3);
+ out_reg(param4, reg_tab[drive_num].reg4);
+ outb_p(reg_off, base_port);
restore_flags(flags); /* all CPUs */
}

/*
* Auto-detect the IDE controller port.
*/
-static int __init findPort (void)
+static int __init find_port(void)
{
int i;
- byte t;
unsigned long flags;

__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
- for (i = 0; i < ALI_NUM_PORTS; ++i) {
- basePort = ports[i];
- regOff = inb(basePort);
- for (regOn = 0x30; regOn <= 0x33; ++regOn) {
- outb_p(regOn, basePort);
- if (inb(basePort) == regOn) {
- regPort = basePort + 4;
- dataPort = basePort + 8;
- t = inReg(0) & 0xf0;
- outb_p(regOff, basePort);
+ for (i = 0; i < ALI_NUM_PORTS; i++) {
+ base_port = ports[i];
+ reg_off = inb(base_port);
+ for (reg_on = 0x30; reg_on <= 0x33; reg_on++) {
+ outb_p(reg_on, base_port);
+ if (inb(base_port) == reg_on) {
+ u8 t;
+ reg_port = base_port + 4;
+ data_port = base_port + 8;
+ t = in_reg(0) & 0xf0;
+ outb_p(reg_off, base_port);
__restore_flags(flags); /* local CPU only */
if (t != 0x50)
return 0;
- return 1; /* success */
+ return 1; /* success */
}
}
- outb_p(regOff, basePort);
+ outb_p(reg_off, base_port);
}
__restore_flags(flags); /* local CPU only */
return 0;
@@ -182,32 +178,34 @@
/*
* Initialize controller registers with default values.
*/
-static int __init initRegisters (void) {
- RegInitializer *p;
- byte t;
+static int __init init_registers(void)
+{
+ struct reg_initializer *p;
unsigned long flags;
+ u8 t;

__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
- outb_p(regOn, basePort);
- for (p = initData; p->reg != 0; ++p)
- outReg(p->data, p->reg);
- outb_p(0x01, regPort);
- t = inb(regPort) & 0x01;
- outb_p(regOff, basePort);
+ outb_p(reg_on, base_port);
+ for (p = init_data; p->reg != 0; ++p)
+ out_reg(p->data, p->reg);
+ outb_p(0x01, reg_port);
+ t = inb(reg_port) & 0x01;
+ outb_p(reg_off, base_port);
__restore_flags(flags); /* local CPU only */
return t;
}

-void __init init_ali14xx (void)
+void __init init_ali14xx(void)
{
/* auto-detect IDE controller port */
- if (!findPort()) {
- printk("\nali14xx: not found");
+ if (!find_port()) {
+ printk(KERN_ERR "ali14xx: not found\n");
return;
}

- printk("\nali14xx: base= 0x%03x, regOn = 0x%02x", basePort, regOn);
+ printk(KERN_DEBUG "ali14xx: base=%#03x, reg_on=%#02x\n",
+ base_port, reg_on);
ide_hwifs[0].chipset = ide_ali14xx;
ide_hwifs[1].chipset = ide_ali14xx;
ide_hwifs[0].tuneproc = &ali14xx_tune_drive;
@@ -216,8 +214,8 @@
ide_hwifs[1].unit = ATA_SECONDARY;

/* initialize controller registers */
- if (!initRegisters()) {
- printk("\nali14xx: Chip initialization failed");
+ if (!init_registers()) {
+ printk(KERN_ERR "ali14xx: Chip initialization failed\n");
return;
}
}
diff -urN linux-2.5.20/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.20/drivers/ide/ide.c 2002-06-04 14:06:59.000000000 +0200
+++ linux/drivers/ide/ide.c 2002-06-04 12:31:58.000000000 +0200
@@ -67,9 +67,6 @@
#include "pcihost.h"
#include "ioctl.h"

-/* default maximum number of failures */
-#define IDE_DEFAULT_MAX_FAILURES 1
-
/*
* CompactFlash cards and their relatives pretend to be removable hard disks, except:
* (1) they never have a slave unit, and
@@ -555,6 +552,19 @@
#endif

/*
+ * This is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
+ *
+ * FIXME: Why can't be just use task_no_data_intr here?
+ */
+static ide_startstop_t recal_intr(struct ata_device *drive, struct request *rq)
+{
+ if (!ata_status(drive, READY_STAT, BAD_STAT))
+ return ata_error(drive, rq, __FUNCTION__);
+
+ return ide_stopped;
+}
+
+/*
* We are still on the old request path here so issuing the recalibrate command
* directly should just work.
*/
@@ -572,6 +582,7 @@
args.taskfile.sector_count = drive->sect;
args.cmd = WIN_RESTORE;
args.handler = recal_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;
ata_taskfile(drive, &args, NULL);
}

diff -urN linux-2.5.20/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.20/drivers/ide/ide-disk.c 2002-06-03 03:44:38.000000000 +0200
+++ linux/drivers/ide/ide-disk.c 2002-06-04 12:21:17.000000000 +0200
@@ -90,7 +90,224 @@
return 0; /* lba_capacity value may be bad */
}

-static u8 get_command(struct ata_device *drive, int cmd)
+/*
+ * Handler for command with PIO data-in phase
+ */
+static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
+{
+ char *buf = NULL;
+ unsigned long flags;
+
+ if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
+ if (drive->status & (ERR_STAT|DRQ_STAT))
+ return ata_error(drive, rq, __FUNCTION__);
+
+ if (!(drive->status & BUSY_STAT)) {
+#if 0
+ printk("task_in_intr to Soon wait for next interrupt\n");
+#endif
+ ide_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
+
+ return ide_started;
+ }
+ }
+ buf = ide_map_rq(rq, &flags);
+#if 0
+ printk("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
+#endif
+
+ ata_read(drive, buf, SECTOR_WORDS);
+ ide_unmap_rq(rq, buf, &flags);
+
+ /* First segment of the request is complete. note that this does not
+ * necessarily mean that the entire request is done!! this is only true
+ * if ide_end_request() returns 0.
+ */
+
+ if (--rq->current_nr_sectors <= 0) {
+#if 0
+ printk("Request Ended stat: %02x\n", drive->status);
+#endif
+ if (!ide_end_request(drive, rq, 1))
+ return ide_stopped;
+ }
+
+ /* still data left to transfer */
+ ide_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
+
+ return ide_started;
+}
+
+/*
+ * Handler for command with PIO data-out phase
+ */
+static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
+{
+ char *buf = NULL;
+ unsigned long flags;
+
+ if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
+ return ata_error(drive, rq, __FUNCTION__);
+
+ if (!rq->current_nr_sectors)
+ if (!ide_end_request(drive, rq, 1))
+ return ide_stopped;
+
+ if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
+ buf = ide_map_rq(rq, &flags);
+#if 0
+ printk("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
+#endif
+
+ ata_write(drive, buf, SECTOR_WORDS);
+ ide_unmap_rq(rq, buf, &flags);
+ rq->errors = 0;
+ rq->current_nr_sectors--;
+ }
+
+ ide_set_handler(drive, task_out_intr, WAIT_CMD, NULL);
+
+ return ide_started;
+}
+
+/*
+ * Handler for command with Read Multiple
+ */
+static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
+{
+ char *buf = NULL;
+ unsigned int msect, nsect;
+ unsigned long flags;
+
+ if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
+ if (drive->status & (ERR_STAT|DRQ_STAT))
+ return ata_error(drive, rq, __FUNCTION__);
+
+ /* no data yet, so wait for another interrupt */
+ ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
+ return ide_started;
+ }
+
+ /* (ks/hs): Fixed Multi-Sector transfer */
+ msect = drive->mult_count;
+
+ do {
+ nsect = rq->current_nr_sectors;
+ if (nsect > msect)
+ nsect = msect;
+
+ buf = ide_map_rq(rq, &flags);
+
+#if 0
+ printk("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
+ buf, nsect, rq->current_nr_sectors);
+#endif
+ ata_read(drive, buf, nsect * SECTOR_WORDS);
+ ide_unmap_rq(rq, buf, &flags);
+ rq->errors = 0;
+ rq->current_nr_sectors -= nsect;
+ msect -= nsect;
+ if (!rq->current_nr_sectors) {
+ if (!ide_end_request(drive, rq, 1))
+ return ide_stopped;
+ }
+ } while (msect);
+
+
+ /*
+ * more data left
+ */
+ ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
+
+ return ide_started;
+}
+
+static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq)
+{
+ int ok;
+ int mcount = drive->mult_count;
+ ide_startstop_t startstop;
+
+
+ /*
+ * FIXME: the drive->status checks here seem to be messy.
+ *
+ * (ks/hs): Handle last IRQ on multi-sector transfer,
+ * occurs after all data was sent in this chunk
+ */
+
+ ok = ata_status(drive, DATA_READY, BAD_R_STAT);
+
+ if (!ok || !rq->nr_sectors) {
+ if (drive->status & (ERR_STAT | DRQ_STAT)) {
+ startstop = ata_error(drive, rq, __FUNCTION__);
+
+ return startstop;
+ }
+ }
+
+ if (!rq->nr_sectors) {
+ __ide_end_request(drive, rq, 1, rq->hard_nr_sectors);
+ rq->bio = NULL;
+
+ return ide_stopped;
+ }
+
+ if (!ok) {
+ /* no data yet, so wait for another interrupt */
+ if (!drive->channel->handler)
+ ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
+
+ return ide_started;
+ }
+
+ do {
+ char *buffer;
+ int nsect = rq->current_nr_sectors;
+ unsigned long flags;
+
+ if (nsect > mcount)
+ nsect = mcount;
+ mcount -= nsect;
+
+ buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
+ rq->sector += nsect;
+ rq->nr_sectors -= nsect;
+ rq->current_nr_sectors -= nsect;
+
+ /* Do we move to the next bio after this? */
+ if (!rq->current_nr_sectors) {
+ /* remember to fix this up /jens */
+ struct bio *bio = rq->bio->bi_next;
+
+ /* end early if we ran out of requests */
+ if (!bio) {
+ mcount = 0;
+ } else {
+ rq->bio = bio;
+ rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
+ }
+ }
+
+ /*
+ * Ok, we're all setup for the interrupt re-entering us on the
+ * last transfer.
+ */
+ ata_write(drive, buffer, nsect * SECTOR_WORDS);
+ bio_kunmap_irq(buffer, &flags);
+ } while (mcount);
+
+ rq->errors = 0;
+ if (!drive->channel->handler)
+ ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
+
+ return ide_started;
+}
+
+/*
+ * Decode with physical ATA command to use and setup associated data.
+ */
+static u8 get_command(struct ata_device *drive, struct ata_taskfile *ar, int cmd)
{
int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;

@@ -100,45 +317,64 @@

if (lba48bit) {
if (cmd == READ) {
- if (drive->using_tcq)
+ ar->command_type = IDE_DRIVE_TASK_IN;
+ if (drive->using_tcq) {
return WIN_READDMA_QUEUED_EXT;
- if (drive->using_dma)
+ } else if (drive->using_dma) {
return WIN_READDMA_EXT;
- else if (drive->mult_count)
+ } else if (drive->mult_count) {
+ ar->handler = task_mulin_intr;
return WIN_MULTREAD_EXT;
- else
+ } else {
+ ar->handler = task_in_intr;
return WIN_READ_EXT;
+ }
} else if (cmd == WRITE) {
- if (drive->using_tcq)
+ ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
+ if (drive->using_tcq) {
return WIN_WRITEDMA_QUEUED_EXT;
- if (drive->using_dma)
+ } else if (drive->using_dma) {
return WIN_WRITEDMA_EXT;
- else if (drive->mult_count)
+ } else if (drive->mult_count) {
+ ar->handler = task_mulout_intr;
return WIN_MULTWRITE_EXT;
- else
+ } else {
+ ar->handler = task_out_intr;
return WIN_WRITE_EXT;
+ }
}
} else {
if (cmd == READ) {
- if (drive->using_tcq)
+ ar->command_type = IDE_DRIVE_TASK_IN;
+ if (drive->using_tcq) {
return WIN_READDMA_QUEUED;
- if (drive->using_dma)
+ } else if (drive->using_dma) {
return WIN_READDMA;
- else if (drive->mult_count)
+ } else if (drive->mult_count) {
+ ar->handler = task_in_intr;
return WIN_MULTREAD;
- else
+ } else {
+ ar->handler = task_in_intr;
return WIN_READ;
+ }
} else if (cmd == WRITE) {
- if (drive->using_tcq)
+ ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
+ if (drive->using_tcq) {
return WIN_WRITEDMA_QUEUED;
- if (drive->using_dma)
+ } else if (drive->using_dma) {
return WIN_WRITEDMA;
- else if (drive->mult_count)
+ } else if (drive->mult_count) {
+ ar->handler = task_mulout_intr;
return WIN_MULTWRITE;
- else
+ } else {
+ ar->handler = task_out_intr;
return WIN_WRITE;
+ }
}
}
+ ar->handler = task_no_data_intr;
+ ar->command_type = IDE_DRIVE_TASK_NO_DATA;
+
return WIN_NOP;
}

@@ -170,7 +406,7 @@

args.taskfile.device_head = head;
args.taskfile.device_head |= drive->select.all;
- args.cmd = get_command(drive, rq_data_dir(rq));
+ args.cmd = get_command(drive, &args, rq_data_dir(rq));

#ifdef DEBUG
printk("%s: %sing: ", drive->name,
@@ -181,7 +417,6 @@
printk("buffer=%p\n", rq->buffer);
#endif

- ide_cmd_type_parser(&args);
rq->special = &args;

return ata_taskfile(drive, &args, rq);
@@ -211,7 +446,7 @@

args.taskfile.device_head = ((block >> 8) & 0x0f);
args.taskfile.device_head |= drive->select.all;
- args.cmd = get_command(drive, rq_data_dir(rq));
+ args.cmd = get_command(drive, &args, rq_data_dir(rq));

#ifdef DEBUG
printk("%s: %sing: ", drive->name,
@@ -222,7 +457,6 @@
printk("buffer=%p\n", rq->buffer);
#endif

- ide_cmd_type_parser(&args);
rq->special = &args;

return ata_taskfile(drive, &args, rq);
@@ -264,7 +498,7 @@
args.hobfile.high_cylinder = (block >>= 8); /* hi lba */
args.hobfile.device_head = drive->select.all;

- args.cmd = get_command(drive, rq_data_dir(rq));
+ args.cmd = get_command(drive, &args, rq_data_dir(rq));

#ifdef DEBUG
printk("%s: %sing: ", drive->name,
@@ -275,7 +509,6 @@
printk("buffer=%p\n",rq->buffer);
#endif

- ide_cmd_type_parser(&args);
rq->special = &args;

return ata_taskfile(drive, &args, rq);
@@ -354,9 +587,9 @@
check_disk_change(inode->i_rdev);

memset(&args, 0, sizeof(args));
-
args.cmd = WIN_DOORLOCK;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

/*
* Ignore the return code from door_lock, since the open() has
@@ -381,7 +614,8 @@
else
args.cmd = WIN_FLUSH_CACHE;

- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

return ide_raw_taskfile(drive, &args);
}
@@ -396,7 +630,8 @@

memset(&args, 0, sizeof(args));
args.cmd = WIN_DOORUNLOCK;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

if (drive->doorlocking &&
ide_raw_taskfile(drive, &args))
@@ -445,7 +680,8 @@
memset(&args, 0, sizeof(args));
args.taskfile.sector_count = arg;
args.cmd = WIN_SETMULT;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

if (!ide_raw_taskfile(drive, &args)) {
/* all went well track this setting as valid */
@@ -476,7 +712,9 @@
memset(&args, 0, sizeof(args));
args.taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
args.cmd = WIN_SETFEATURES;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;
+
ide_raw_taskfile(drive, &args);

drive->wcache = arg;
@@ -490,7 +728,8 @@

memset(&args, 0, sizeof(args));
args.cmd = WIN_STANDBYNOW1;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

return ide_raw_taskfile(drive, &args);
}
@@ -503,7 +742,9 @@
args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
args.taskfile.sector_count = arg;
args.cmd = WIN_SETFEATURES;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;
+
ide_raw_taskfile(drive, &args);

drive->acoustic = arg;
diff -urN linux-2.5.20/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.20/drivers/ide/ide-taskfile.c 2002-06-03 03:44:50.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c 2002-06-04 12:43:06.000000000 +0200
@@ -42,24 +42,6 @@
#endif

/*
- * for now, taskfile requests are special :/
- */
-static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
-{
- if (rq->bio)
- return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
- else
- return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE;
-}
-
-static inline void ide_unmap_rq(struct request *rq, char *to,
- unsigned long *flags)
-{
- if (rq->bio)
- bio_kunmap_irq(to, flags);
-}
-
-/*
* Data transfer functions for polled IO.
*/

@@ -195,119 +177,24 @@
}

/*
- * Polling wait until the drive is ready.
- *
- * Stuff the first sector(s) by implicitly calling the handler driectly
- * therafter.
+ * Handler for commands without a data phase
*/
-void ata_poll_drive_ready(struct ata_device *drive)
-{
- int i;
-
- if (drive_is_ready(drive))
- return;
-
- /* FIXME: Replace hard-coded 100, what about error handling?
- */
- for (i = 0; i < 100; ++i) {
- if (drive_is_ready(drive))
- break;
- }
-}
-
-static ide_startstop_t pre_task_mulout_intr(struct ata_device *drive, struct request *rq)
-{
- struct ata_taskfile *args = rq->special;
- ide_startstop_t startstop;
-
- if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ))
- return startstop;
-
- ata_poll_drive_ready(drive);
-
- return args->handler(drive, rq);
-}
-
-static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq)
+ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq)
{
- int ok;
- int mcount = drive->mult_count;
- ide_startstop_t startstop;
-
-
- /*
- * FIXME: the drive->status checks here seem to be messy.
- *
- * (ks/hs): Handle last IRQ on multi-sector transfer,
- * occurs after all data was sent in this chunk
- */
-
- ok = ata_status(drive, DATA_READY, BAD_R_STAT);
-
- if (!ok || !rq->nr_sectors) {
- if (drive->status & (ERR_STAT | DRQ_STAT)) {
- startstop = ata_error(drive, rq, __FUNCTION__);
-
- return startstop;
- }
- }
-
- if (!rq->nr_sectors) {
- __ide_end_request(drive, rq, 1, rq->hard_nr_sectors);
- rq->bio = NULL;
-
- return ide_stopped;
- }
+ struct ata_taskfile *ar = rq->special;

- if (!ok) {
- /* no data yet, so wait for another interrupt */
- if (!drive->channel->handler)
- ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
+ ide__sti(); /* local CPU only */

- return ide_started;
+ if (!ata_status(drive, READY_STAT, BAD_STAT)) {
+ /* Keep quiet for NOP because it is expected to fail. */
+ if (ar && ar->cmd != WIN_NOP)
+ return ata_error(drive, rq, __FUNCTION__);
}

- do {
- char *buffer;
- int nsect = rq->current_nr_sectors;
- unsigned long flags;
-
- if (nsect > mcount)
- nsect = mcount;
- mcount -= nsect;
-
- buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
- rq->sector += nsect;
- rq->nr_sectors -= nsect;
- rq->current_nr_sectors -= nsect;
-
- /* Do we move to the next bio after this? */
- if (!rq->current_nr_sectors) {
- /* remember to fix this up /jens */
- struct bio *bio = rq->bio->bi_next;
-
- /* end early if we ran out of requests */
- if (!bio) {
- mcount = 0;
- } else {
- rq->bio = bio;
- rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
- }
- }
-
- /*
- * Ok, we're all setup for the interrupt re-entering us on the
- * last transfer.
- */
- ata_write(drive, buffer, nsect * SECTOR_WORDS);
- bio_kunmap_irq(buffer, &flags);
- } while (mcount);
-
- rq->errors = 0;
- if (!drive->channel->handler)
- ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);
+ if (ar)
+ ide_end_drive_cmd(drive, rq);

- return ide_started;
+ return ide_stopped;
}

ide_startstop_t ata_taskfile(struct ata_device *drive,
@@ -315,8 +202,11 @@
{
struct hd_driveid *id = drive->id;

- /* (ks/hs): Moved to start, do not use for multiple out commands */
- if (ar->handler != task_mulout_intr) {
+ /* (ks/hs): Moved to start, do not use for multiple out commands.
+ * FIXME: why not?! */
+ if (!(ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
+ ar->cmd == WIN_MULTWRITE ||
+ ar->cmd == WIN_MULTWRITE_EXT)) {
ata_irq_enable(drive, 1);
ata_mask(drive);
}
@@ -324,14 +214,12 @@
if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1))
ata_out_regfile(drive, &ar->hobfile);
-
ata_out_regfile(drive, &ar->taskfile);

- {
- u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
- OUT_BYTE((ar->taskfile.device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
- }
- if (ar->handler != NULL) {
+ OUT_BYTE((ar->taskfile.device_head & (drive->addressing ? 0xE0 : 0xEF)) | drive->select.all,
+ IDE_SELECT_REG);
+
+ if (ar->handler) {

/* This is apparently supposed to reset the wait timeout for
* the interrupt to accur.
@@ -340,34 +228,90 @@
ide_set_handler(drive, ar->handler, WAIT_CMD, NULL);
OUT_BYTE(ar->cmd, IDE_COMMAND_REG);

- /*
- * Warning check for race between handler and prehandler for
- * writing first block of data. however since we are well
+ /* FIXME: Warning check for race between handler and prehandler
+ * for writing first block of data. however since we are well
* inside the boundaries of the seek, we should be okay.
+ *
+ * FIXME: Replace the switch by using a proper command_type.
*/

- if (ar->prehandler != NULL)
- return ar->prehandler(drive, rq);
+ if (ar->cmd == CFA_WRITE_SECT_WO_ERASE ||
+ ar->cmd == WIN_WRITE ||
+ ar->cmd == WIN_WRITE_EXT ||
+ ar->cmd == WIN_WRITE_VERIFY ||
+ ar->cmd == WIN_WRITE_BUFFER ||
+ ar->cmd == WIN_DOWNLOAD_MICROCODE ||
+ ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
+ ar->cmd == WIN_MULTWRITE ||
+ ar->cmd == WIN_MULTWRITE_EXT) {
+ ide_startstop_t startstop;
+
+ if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+ printk(KERN_ERR "%s: no DRQ after issuing %s\n",
+ drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
+ return startstop;
+ }
+
+ /* FIXME: This doesn't make the slightest sense.
+ * (ks/hs): Fixed Multi Write
+ */
+ if (!(ar->cmd == CFA_WRITE_MULTI_WO_ERASE ||
+ ar->cmd == WIN_MULTWRITE ||
+ ar->cmd == WIN_MULTWRITE_EXT)) {
+ unsigned long flags;
+ char *buf = ide_map_rq(rq, &flags);
+
+ /* For Write_sectors we need to stuff the first sector */
+ ata_write(drive, buf, SECTOR_WORDS);
+
+ rq->current_nr_sectors--;
+ ide_unmap_rq(rq, buf, &flags);
+
+ return ide_started;
+ } else {
+ int i;
+
+ /* Polling wait until the drive is ready.
+ *
+ * Stuff the first sector(s) by calling the
+ * handler driectly therafter.
+ *
+ * FIXME: Replace hard-coded 100, what about
+ * error handling?
+ */
+
+ for (i = 0; i < 100; ++i) {
+ if (drive_is_ready(drive))
+ break;
+ }
+ if (!drive_is_ready(drive)) {
+ printk(KERN_ERR "DISASTER WAITING TO HAPPEN!\n");
+ }
+ return ar->handler(drive, rq);
+ }
+ }
} else {
/*
* FIXME: This is a gross hack, need to unify tcq dma proc and
* regular dma proc. It should now be easier.
+ *
+ * FIXME: Handle the alternateives by a command type.
*/

if (!drive->using_dma)
return ide_started;

/* for dma commands we don't set the handler */
- if (ar->cmd == WIN_WRITEDMA
- || ar->cmd == WIN_WRITEDMA_EXT
- || ar->cmd == WIN_READDMA
- || ar->cmd == WIN_READDMA_EXT)
+ if (ar->cmd == WIN_WRITEDMA ||
+ ar->cmd == WIN_WRITEDMA_EXT ||
+ ar->cmd == WIN_READDMA ||
+ ar->cmd == WIN_READDMA_EXT)
return !udma_init(drive, rq);
#ifdef CONFIG_BLK_DEV_IDE_TCQ
- else if (ar->cmd == WIN_WRITEDMA_QUEUED
- || ar->cmd == WIN_WRITEDMA_QUEUED_EXT
- || ar->cmd == WIN_READDMA_QUEUED
- || ar->cmd == WIN_READDMA_QUEUED_EXT)
+ else if (ar->cmd == WIN_WRITEDMA_QUEUED ||
+ ar->cmd == WIN_WRITEDMA_QUEUED_EXT ||
+ ar->cmd == WIN_READDMA_QUEUED ||
+ ar->cmd == WIN_READDMA_QUEUED_EXT)
return udma_tcq_taskfile(drive, rq);
#endif
else {
@@ -380,363 +324,6 @@
}

/*
- * This is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
- */
-ide_startstop_t recal_intr(struct ata_device *drive, struct request *rq)
-{
- if (!ata_status(drive, READY_STAT, BAD_STAT))
- return ata_error(drive, rq, __FUNCTION__);
-
- return ide_stopped;
-}
-
-/*
- * Handler for commands without a data phase
- */
-ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq)
-{
- struct ata_taskfile *ar = rq->special;
-
- ide__sti(); /* local CPU only */
-
- if (!ata_status(drive, READY_STAT, BAD_STAT)) {
- /* Keep quiet for NOP because it is expected to fail. */
- if (ar && ar->cmd != WIN_NOP)
- return ata_error(drive, rq, __FUNCTION__);
- }
-
- if (ar)
- ide_end_drive_cmd(drive, rq);
-
- return ide_stopped;
-}
-
-/*
- * Handler for command with PIO data-in phase
- */
-static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
-{
- char *buf = NULL;
- unsigned long flags;
-
- if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
- if (drive->status & (ERR_STAT|DRQ_STAT))
- return ata_error(drive, rq, __FUNCTION__);
-
- if (!(drive->status & BUSY_STAT)) {
- DTF("task_in_intr to Soon wait for next interrupt\n");
- ide_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
-
- return ide_started;
- }
- }
- DTF("stat: %02x\n", drive->status);
- buf = ide_map_rq(rq, &flags);
- DTF("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
-
- ata_read(drive, buf, SECTOR_WORDS);
- ide_unmap_rq(rq, buf, &flags);
-
- /* First segment of the request is complete. note that this does not
- * necessarily mean that the entire request is done!! this is only true
- * if ide_end_request() returns 0.
- */
-
- if (--rq->current_nr_sectors <= 0) {
- DTF("Request Ended stat: %02x\n", drive->status);
- if (!ide_end_request(drive, rq, 1))
- return ide_stopped;
- }
-
- /* still data left to transfer */
- ide_set_handler(drive, task_in_intr, WAIT_CMD, NULL);
-
- return ide_started;
-}
-
-static ide_startstop_t pre_task_out_intr(struct ata_device *drive, struct request *rq)
-{
- struct ata_taskfile *args = rq->special;
- ide_startstop_t startstop;
-
- if (ide_wait_stat(&startstop, drive, rq, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
- printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
- return startstop;
- }
-
- /* (ks/hs): Fixed Multi Write */
- if ((args->cmd != WIN_MULTWRITE) &&
- (args->cmd != WIN_MULTWRITE_EXT)) {
- unsigned long flags;
- char *buf = ide_map_rq(rq, &flags);
- /* For Write_sectors we need to stuff the first sector */
- ata_write(drive, buf, SECTOR_WORDS);
- rq->current_nr_sectors--;
- ide_unmap_rq(rq, buf, &flags);
- } else {
- ata_poll_drive_ready(drive);
- return args->handler(drive, rq);
- }
- return ide_started;
-}
-
-/*
- * Handler for command with PIO data-out phase
- */
-static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
-{
- char *buf = NULL;
- unsigned long flags;
-
- if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
- return ata_error(drive, rq, __FUNCTION__);
-
- if (!rq->current_nr_sectors)
- if (!ide_end_request(drive, rq, 1))
- return ide_stopped;
-
- if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
- buf = ide_map_rq(rq, &flags);
- DTF("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
-
- ata_write(drive, buf, SECTOR_WORDS);
- ide_unmap_rq(rq, buf, &flags);
- rq->errors = 0;
- rq->current_nr_sectors--;
- }
-
- ide_set_handler(drive, task_out_intr, WAIT_CMD, NULL);
-
- return ide_started;
-}
-
-/*
- * Handler for command with Read Multiple
- */
-static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
-{
- char *buf = NULL;
- unsigned int msect, nsect;
- unsigned long flags;
-
- if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
- if (drive->status & (ERR_STAT|DRQ_STAT))
- return ata_error(drive, rq, __FUNCTION__);
-
- /* no data yet, so wait for another interrupt */
- ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
- return ide_started;
- }
-
- /* (ks/hs): Fixed Multi-Sector transfer */
- msect = drive->mult_count;
-
- do {
- nsect = rq->current_nr_sectors;
- if (nsect > msect)
- nsect = msect;
-
- buf = ide_map_rq(rq, &flags);
-
- DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
- buf, nsect, rq->current_nr_sectors);
- ata_read(drive, buf, nsect * SECTOR_WORDS);
- ide_unmap_rq(rq, buf, &flags);
- rq->errors = 0;
- rq->current_nr_sectors -= nsect;
- msect -= nsect;
- if (!rq->current_nr_sectors) {
- if (!ide_end_request(drive, rq, 1))
- return ide_stopped;
- }
- } while (msect);
-
-
- /*
- * more data left
- */
- ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
-
- return ide_started;
-}
-
-/* Called to figure out the type of command being called.
- */
-void ide_cmd_type_parser(struct ata_taskfile *ar)
-{
- struct hd_drive_task_hdr *taskfile = &ar->taskfile;
-
- ar->prehandler = NULL;
- ar->handler = NULL;
-
- switch (ar->cmd) {
- case WIN_IDENTIFY:
- case WIN_PIDENTIFY:
- case CFA_TRANSLATE_SECTOR:
- case WIN_READ:
- case WIN_READ_EXT:
- case WIN_READ_BUFFER:
- ar->handler = task_in_intr;
- ar->command_type = IDE_DRIVE_TASK_IN;
- return;
-
- case CFA_WRITE_SECT_WO_ERASE:
- case WIN_WRITE:
- case WIN_WRITE_EXT:
- case WIN_WRITE_VERIFY:
- case WIN_WRITE_BUFFER:
- case WIN_DOWNLOAD_MICROCODE:
- ar->prehandler = pre_task_out_intr;
- ar->handler = task_out_intr;
- ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
- return;
-
- case WIN_MULTREAD:
- case WIN_MULTREAD_EXT:
- ar->handler = task_mulin_intr;
- ar->command_type = IDE_DRIVE_TASK_IN;
- return;
-
- case CFA_WRITE_MULTI_WO_ERASE:
- case WIN_MULTWRITE:
- case WIN_MULTWRITE_EXT:
- ar->prehandler = pre_task_mulout_intr;
- ar->handler = task_mulout_intr;
- ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
- return;
-
- case WIN_SECURITY_DISABLE:
- case WIN_SECURITY_ERASE_UNIT:
- case WIN_SECURITY_SET_PASS:
- case WIN_SECURITY_UNLOCK:
- ar->handler = task_out_intr;
- ar->command_type = IDE_DRIVE_TASK_OUT;
- return;
-
- case WIN_SMART:
- if (taskfile->feature == SMART_WRITE_LOG_SECTOR)
- ar->prehandler = pre_task_out_intr;
-
- ar->taskfile.low_cylinder = SMART_LCYL_PASS;
- ar->taskfile.high_cylinder = SMART_HCYL_PASS;
-
- switch(ar->taskfile.feature) {
- case SMART_READ_VALUES:
- case SMART_READ_THRESHOLDS:
- case SMART_READ_LOG_SECTOR:
- ar->handler = task_in_intr;
- ar->command_type = IDE_DRIVE_TASK_IN;
- return;
-
- case SMART_WRITE_LOG_SECTOR:
- ar->handler = task_out_intr;
- ar->command_type = IDE_DRIVE_TASK_OUT;
- return;
-
- default:
- ar->handler = task_no_data_intr;
- ar->command_type = IDE_DRIVE_TASK_NO_DATA;
- return;
-
- }
-#ifdef CONFIG_BLK_DEV_IDEDMA
- case WIN_READDMA:
- case WIN_IDENTIFY_DMA:
- case WIN_READDMA_QUEUED:
- case WIN_READDMA_EXT:
- case WIN_READDMA_QUEUED_EXT:
- ar->command_type = IDE_DRIVE_TASK_IN;
- return;
-
- case WIN_WRITEDMA:
- case WIN_WRITEDMA_QUEUED:
- case WIN_WRITEDMA_EXT:
- case WIN_WRITEDMA_QUEUED_EXT:
- ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
- return;
-
-#endif
- case WIN_SETFEATURES:
- ar->handler = task_no_data_intr;
- switch (ar->taskfile.feature) {
- case SETFEATURES_XFER:
- ar->command_type = IDE_DRIVE_TASK_SET_XFER;
- return;
- case SETFEATURES_DIS_DEFECT:
- case SETFEATURES_EN_APM:
- case SETFEATURES_DIS_MSN:
- case SETFEATURES_EN_RI:
- case SETFEATURES_EN_SI:
- case SETFEATURES_DIS_RPOD:
- case SETFEATURES_DIS_WCACHE:
- case SETFEATURES_EN_DEFECT:
- case SETFEATURES_DIS_APM:
- case SETFEATURES_EN_MSN:
- case SETFEATURES_EN_RLA:
- case SETFEATURES_PREFETCH:
- case SETFEATURES_EN_RPOD:
- case SETFEATURES_DIS_RI:
- case SETFEATURES_DIS_SI:
- default:
- ar->command_type = IDE_DRIVE_TASK_NO_DATA;
- return;
- }
-
- case WIN_SPECIFY:
- ar->handler = task_no_data_intr;
- ar->command_type = IDE_DRIVE_TASK_NO_DATA;
- return;
-
- case WIN_RESTORE:
- ar->handler = recal_intr;
- ar->command_type = IDE_DRIVE_TASK_NO_DATA;
- return;
-
- case WIN_DIAGNOSE:
- case WIN_FLUSH_CACHE:
- case WIN_FLUSH_CACHE_EXT:
- case WIN_STANDBYNOW1:
- case WIN_STANDBYNOW2:
- case WIN_SLEEPNOW1:
- case WIN_SLEEPNOW2:
- case WIN_SETIDLE1:
- case WIN_CHECKPOWERMODE1:
- case WIN_CHECKPOWERMODE2:
- case WIN_GETMEDIASTATUS:
- case WIN_MEDIAEJECT:
- case CFA_REQ_EXT_ERROR_CODE:
- case CFA_ERASE_SECTORS:
- case WIN_VERIFY:
- case WIN_VERIFY_EXT:
- case WIN_SEEK:
- case WIN_READ_NATIVE_MAX:
- case WIN_SET_MAX:
- case WIN_READ_NATIVE_MAX_EXT:
- case WIN_SET_MAX_EXT:
- case WIN_SECURITY_ERASE_PREPARE:
- case WIN_SECURITY_FREEZE_LOCK:
- case WIN_DOORLOCK:
- case WIN_DOORUNLOCK:
- case DISABLE_SEAGATE:
- case EXABYTE_ENABLE_NEST:
- case WIN_SETMULT:
- case WIN_NOP:
- ar->handler = task_no_data_intr;
- ar->command_type = IDE_DRIVE_TASK_NO_DATA;
- return;
-
- case WIN_FORMAT:
- case WIN_INIT:
- case WIN_DEVICE_RESET:
- case WIN_QUEUED_SERVICE:
- case WIN_PACKETCMD:
- default:
- ar->command_type = IDE_DRIVE_TASK_INVALID;
- return;
- }
-}
-
-/*
* This function issues a special IDE device request onto the request queue.
*
* If action is ide_wait, then the rq is queued at the end of the request
@@ -813,8 +400,6 @@
EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write);
EXPORT_SYMBOL(ata_taskfile);
-EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(task_no_data_intr);
EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ide_raw_taskfile);
-EXPORT_SYMBOL(ide_cmd_type_parser);
diff -urN linux-2.5.20/drivers/ide/ioctl.c linux/drivers/ide/ioctl.c
--- linux-2.5.20/drivers/ide/ioctl.c 2002-06-03 03:44:45.000000000 +0200
+++ linux/drivers/ide/ioctl.c 2002-06-04 10:27:36.000000000 +0200
@@ -150,19 +150,22 @@
* configuration.
*/

- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
-
switch (cmd) {
case HDIO_GET_32BIT: {
unsigned long val = drive->channel->io_32bit;

+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (put_user(val, (unsigned long *) arg))
return -EFAULT;
return 0;
}

case HDIO_SET_32BIT:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (arg < 0 || arg > 1)
return -EINVAL;

@@ -178,6 +181,9 @@
return 0;

case HDIO_SET_PIO_MODE:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (arg < 0 || arg > 255)
return -EINVAL;

@@ -198,6 +204,9 @@
case HDIO_GET_UNMASKINTR: {
unsigned long val = drive->channel->unmask;

+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (put_user(val, (unsigned long *) arg))
return -EFAULT;

@@ -205,6 +214,9 @@
}

case HDIO_SET_UNMASKINTR:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (arg < 0 || arg > 1)
return -EINVAL;

@@ -222,6 +234,9 @@
case HDIO_GET_DMA: {
unsigned long val = drive->using_dma;

+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (put_user(val, (unsigned long *) arg))
return -EFAULT;

@@ -229,6 +244,9 @@
}

case HDIO_SET_DMA:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (arg < 0 || arg > 1)
return -EINVAL;

@@ -250,6 +268,9 @@
struct hd_geometry *loc = (struct hd_geometry *) arg;
unsigned short bios_cyl = drive->bios_cyl; /* truncate */

+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY))
return -EINVAL;

@@ -272,6 +293,9 @@
case HDIO_GETGEO_BIG_RAW: {
struct hd_big_geometry *loc = (struct hd_big_geometry *) arg;

+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (!loc || (drive->type != ATA_DISK && drive->type != ATA_FLOPPY))
return -EINVAL;

@@ -292,6 +316,9 @@
}

case HDIO_GET_IDENTITY:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (minor(inode->i_rdev) & PARTN_MASK)
return -EINVAL;

@@ -304,11 +331,17 @@
return 0;

case HDIO_GET_NICE:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
return put_user(drive->dsc_overlap << IDE_NICE_DSC_OVERLAP |
drive->atapi_overlap << IDE_NICE_ATAPI_OVERLAP,
(long *) arg);

case HDIO_SET_NICE:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP))))
return -EPERM;

@@ -322,18 +355,27 @@
return 0;

case HDIO_GET_BUSSTATE:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (put_user(drive->channel->bus_state, (long *)arg))
return -EFAULT;

return 0;

case HDIO_SET_BUSSTATE:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (drive->channel->busproc)
drive->channel->busproc(drive, (int)arg);

return 0;

case HDIO_DRIVE_CMD:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
if (!arg) {
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
diff -urN linux-2.5.20/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.20/drivers/ide/tcq.c 2002-06-04 14:06:59.000000000 +0200
+++ linux/drivers/ide/tcq.c 2002-06-04 11:10:59.000000000 +0200
@@ -406,7 +406,8 @@

args.taskfile.feature = 0x01;
args.cmd = WIN_NOP;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

/*
* do taskfile and check ABRT bit -- intelligent adapters will not
@@ -441,7 +442,8 @@
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_WCACHE;
args.cmd = WIN_SETFEATURES;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

if (ide_raw_taskfile(drive, &args)) {
printk("%s: failed to enable write cache\n", drive->name);
@@ -455,7 +457,8 @@
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_DIS_RI;
args.cmd = WIN_SETFEATURES;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

if (ide_raw_taskfile(drive, &args)) {
printk("%s: disabling release interrupt fail\n", drive->name);
@@ -469,7 +472,8 @@
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_SI;
args.cmd = WIN_SETFEATURES;
- ide_cmd_type_parser(&args);
+ args.handler = task_no_data_intr;
+ args.command_type = IDE_DRIVE_TASK_NO_DATA;

if (ide_raw_taskfile(drive, &args)) {
printk("%s: enabling service interrupt fail\n", drive->name);
diff -urN linux-2.5.20/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.20/include/linux/ide.h 2002-06-04 14:07:00.000000000 +0200
+++ linux/include/linux/ide.h 2002-06-04 12:31:54.000000000 +0200
@@ -664,7 +664,6 @@
struct hd_drive_task_hdr hobfile;
u8 cmd; /* actual ATA command */
int command_type;
- ide_startstop_t (*prehandler)(struct ata_device *, struct request *);
ide_startstop_t (*handler)(struct ata_device *, struct request *);
};

@@ -678,17 +677,31 @@
* Special Flagged Register Validation Caller
*/

-extern ide_startstop_t recal_intr(struct ata_device *, struct request *);
-extern ide_startstop_t task_no_data_intr(struct ata_device *, struct request *);
+/*
+ * for now, taskfile requests are special :/
+ */
+static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
+{
+ if (rq->bio)
+ return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
+ else
+ return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE;
+}

-extern void ide_cmd_type_parser(struct ata_taskfile *args);
+static inline void ide_unmap_rq(struct request *rq, char *to,
+ unsigned long *flags)
+{
+ if (rq->bio)
+ bio_kunmap_irq(to, flags);
+}
+
+extern ide_startstop_t task_no_data_intr(struct ata_device *, struct request *);
extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *);

extern void ide_fix_driveid(struct hd_driveid *id);
extern int ide_config_drive_speed(struct ata_device *, byte);
extern byte eighty_ninty_three(struct ata_device *);

-
extern void ide_stall_queue(struct ata_device *, unsigned long);

extern int system_bus_speed;


Attachments:
ide-clean-84.diff (45.11 kB)

2002-06-04 19:50:47

by Pavel Machek

[permalink] [raw]
Subject: Re: 2.5.20 -- suspend.c still breaks the build (originally reported for 2.5.18)

Hi!

> suspend.c: In function signal_wake_up'
> suspend.c: In function do_suspend_sync':
> suspend.c:306:

2002-06-04 19:57:13

by Pavel Machek

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

Hi!

> This patch (a minor update on one that I accidently left lkml out of the To:)
> removes the "General Options" top level config menu from the i386 build for
> 2.5.20. It didn't describe what it was doing, and it contained a broad
> collection of mostly unrelated configuration options.
> To replace it, you now get:
> "Power management options (ACPI, APM)", which also includes software suspend.
> "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
> "Executable file formats"

Good.

> While moving software suspend, I also took the chance to tweak the Config.help
> entry.

Please don't tell people about sysrq-D, I'm going to kill that. OTOH convient
way is echo 4 > /proc/acpi/sleep -- that is if you have ACPI enabled.

Swsusp is required for suspend-to-ram, too. I plan to fix that somehow,
however.
Pavel
--
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.

2002-06-04 20:59:25

by Andrew Grover

[permalink] [raw]
Subject: RE: [patch] i386 "General Options" - begone [take 2]

> > "Power management options (ACPI, APM)", which also includes
> software suspend.
> > "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
> > "Executable file formats"

Brad,

This is a tough one because ACPI *is* power management but it is also
configuration. It is equivalent to such things as MPS table parsing, $PIR
parsing, PNPBIOS, as well as APM. The first two don't have CONFIG_ options
at the moment but they should at some point.

The only thing I can think of is a "Platform interface options" menu and
just throw all of the above in that. Any other ideas?

Regards -- Andy

2002-06-04 21:20:07

by Dave Jones

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

On Tue, Jun 04, 2002 at 01:59:11PM -0700, Grover, Andrew wrote:

> This is a tough one because ACPI *is* power management but it is also
> configuration. It is equivalent to such things as MPS table parsing, $PIR
> parsing, PNPBIOS, as well as APM. The first two don't have CONFIG_ options
> at the moment but they should at some point.
> The only thing I can think of is a "Platform interface options" menu and
> just throw all of the above in that. Any other ideas?

You seem to be halfway down the road of splitting ACPI in two already,
with the introduction of CONFIG_ACPI_HT_ONLY recently. Why not bundle
such options under a CONFIG_ACPI_INITIALISATION or the likes, and
put the rest under the power management menu as Brad suggested ?

Dave.

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

2002-06-04 21:58:49

by Andrew Grover

[permalink] [raw]
Subject: RE: [patch] i386 "General Options" - begone [take 2]

> From: Dave Jones [mailto:[email protected]]
> > This is a tough one because ACPI *is* power management but
> it is also
> > configuration. It is equivalent to such things as MPS
> table parsing, $PIR
> > parsing, PNPBIOS, as well as APM. The first two don't have
> CONFIG_ options
> > at the moment but they should at some point.
> > The only thing I can think of is a "Platform interface
> options" menu and
> > just throw all of the above in that. Any other ideas?
>
> You seem to be halfway down the road of splitting ACPI in two already,
> with the introduction of CONFIG_ACPI_HT_ONLY recently. Why not bundle
> such options under a CONFIG_ACPI_INITIALISATION or the likes, and
> put the rest under the power management menu as Brad suggested ?

CONFIG_ACPI_HT_ONLY was a concession to the fact that using ACPI for
processor discovery only was possible already, but in general an
all-or-nothing approach to ACPI is IMHO the safest bet.

So, let's assume in the very near future it becomes possible to compile a
kernel without MPS or $PIR support. Where should those config options go?
These, in addition to pnpbios, are also unneeded with ACPI. That is why I
was advocating the more general "Platform interface options" menu, so we
could have *one* place to config these and ACPI in or out, instead of having
the many different platform interface options in different logical areas.

My 2c -- Regards -- Andy

2002-06-04 22:09:05

by Dave Jones

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

<trivial patchbot removed from Cc:>

On Tue, Jun 04, 2002 at 02:58:35PM -0700, Grover, Andrew wrote:

> So, let's assume in the very near future it becomes possible to compile a
> kernel without MPS or $PIR support. Where should those config options go?

Why do they need to be options ? They should be implied if CONFIG_ACPI=n
Otherwise we could build a kernel without any PCI IRQ routing, MPS
discovery etc.. I can't see the benefit of making this stuff compile
time optional other than to save a few bytes (and there are much better
places to start attacking to save space than this).

> These, in addition to pnpbios, are also unneeded with ACPI.

As long as the target box has working ACPI tables and we don't have
to fall back to legacy tables.

> That is why I
> was advocating the more general "Platform interface options" menu, so we
> could have *one* place to config these and ACPI in or out, instead of having
> the many different platform interface options in different logical areas.

Can you confirm that you're not advocating a "ACPI or Legacy" approach ?
I think you're aware of the dragons that lie that way, but I want to be
sure my suspicions are unfounded.

Dave.

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

2002-06-04 22:12:41

by Alan

[permalink] [raw]
Subject: RE: [patch] i386 "General Options" - begone [take 2]

On Tue, 2002-06-04 at 22:58, Grover, Andrew wrote:
> So, let's assume in the very near future it becomes possible to compile a
> kernel without MPS or $PIR support. Where should those config options go?
> These, in addition to pnpbios, are also unneeded with ACPI. That is why I
> was advocating the more general "Platform interface options" menu, so we
> could have *one* place to config these and ACPI in or out, instead of having
> the many different platform interface options in different logical areas.

Hardware Discovery using
PnpBIOS
ISAPnP
MCA
PCI
ACPI

IRQ Routing using
PCI BIOS
$PIR
MP 1.x
ACPI

Power Management using
CPU idling instructions
APM
Direct power management
ACPI


There are all sorts of combinations that make sense, and trying to make
them all map around ACPI makes no sense, especially once you hit non x86
platforms where the mentality is quite different about what is
associated


2002-06-04 23:10:46

by Andrew Grover

[permalink] [raw]
Subject: RE: [patch] i386 "General Options" - begone [take 2]

> From: Dave Jones [mailto:[email protected]]

> On Tue, Jun 04, 2002 at 02:58:35PM -0700, Grover, Andrew wrote:
> > So, let's assume in the very near future it becomes
> possible to compile a
> > kernel without MPS or $PIR support. Where should those
> config options go?
> Why do they need to be options ? They should be implied if
> CONFIG_ACPI=n
> Otherwise we could build a kernel without any PCI IRQ routing, MPS
> discovery etc.. I can't see the benefit of making this stuff compile
> time optional other than to save a few bytes (and there are
> much better
> places to start attacking to save space than this).

One reason is for code cleanliness. Linux's internal data structures for irq
routing and MPS stuff on i386 were not designed to handle the possibility of
multiple ways of getting this info. ACPI init gets in there and does its
thing, but it could be better architected. Making the legacy config options
removable is one way to ensure the kernel has things properly modularized
wrt this, and yes, I think someday (maybe not soon) someone *will* want to
leave out MPS support.

> Can you confirm that you're not advocating a "ACPI or Legacy"
> approach ?
> I think you're aware of the dragons that lie that way, but I
> want to be
> sure my suspicions are unfounded.

All I can say is using just *part* of ACPI will cause some machine,
somewhere, to not work. I want to avoid scenarios where that happens. If
there are issues with that, can we discuss them asap, perhaps now?

Regards -- Andy

2002-06-04 23:25:31

by Dave Jones

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

On Tue, Jun 04, 2002 at 04:09:48PM -0700, Grover, Andrew wrote:

> > Can you confirm that you're not advocating a "ACPI or Legacy"
> > approach ?
> > I think you're aware of the dragons that lie that way, but I
> > want to be sure my suspicions are unfounded.
> All I can say is using just *part* of ACPI will cause some machine,
> somewhere, to not work. I want to avoid scenarios where that happens. If
> there are issues with that, can we discuss them asap, perhaps now?

Think vendor kernel. There we want to run on ancient pre-ACPI boxes,
and super duper new box with borken/non-existant legacy tables.
So just keep in mind that compiling both into the kernel is a must have
requirement.

Dave.

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

2002-06-04 23:54:30

by Alan

[permalink] [raw]
Subject: RE: [patch] i386 "General Options" - begone [take 2]

On Wed, 2002-06-05 at 00:09, Grover, Andrew wrote:
> All I can say is using just *part* of ACPI will cause some machine,
> somewhere, to not work.

We've established that pretty comprehensively. Any bit of ACPI causes
some machines somewhere to not work 8)

> I want to avoid scenarios where that happens. If
> there are issues with that, can we discuss them asap, perhaps now?

It may be that the IRQ routing and other bits of ACPI logic need to know
that their are dependancies. We handle that already for other legacy
stuff. If you don't have an MCA bus we don't do MCA bus enumerating. If
you don't have a PCI BIOS32 irq router we don't consider that option and
so forth. Having ACPI IRQ/Enumeration code that says if(!acpi) return
NULL isnt that demanding

2002-06-05 00:19:39

by Andrew Grover

[permalink] [raw]
Subject: RE: [patch] i386 "General Options" - begone [take 2]

> From: Dave Jones [mailto:[email protected]]
> > > Can you confirm that you're not advocating a "ACPI or Legacy"
> > > approach ?
> > > I think you're aware of the dragons that lie that way, but I
> > > want to be sure my suspicions are unfounded.
> > All I can say is using just *part* of ACPI will cause some machine,
> > somewhere, to not work. I want to avoid scenarios where
> that happens. If
> > there are issues with that, can we discuss them asap, perhaps now?
>
> Think vendor kernel. There we want to run on ancient pre-ACPI boxes,
> and super duper new box with borken/non-existant legacy tables.
> So just keep in mind that compiling both into the kernel is a
> must have
> requirement.

Oh. OK. Yes. No disagreement there.

-- Andy

2002-06-05 07:38:19

by Brad Hards

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

On Wed, 5 Jun 2002 00:09, Pavel Machek wrote:
> Please don't tell people about sysrq-D, I'm going to kill that. OTOH
> convient way is echo 4 > /proc/acpi/sleep -- that is if you have ACPI
> enabled.
Extract from the patch:
- You may suspend your machine by either pressing Sysrq-d or with
<snip>
+ require APM. You may suspend your machine by either pressing
+ Sysrq-d or with 'swsusp' or 'shutdown -z <time>' (patch for

So it is in the original. When you kill the functionality, update the doco.

Brad
--
http://conf.linux.org.au. 22-25Jan2003. Perth, Australia. Birds in Black.

2002-06-05 07:40:09

by Brad Hards

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

On Wed, 5 Jun 2002 06:59, Grover, Andrew wrote:
> > > "Power management options (ACPI, APM)", which also includes
> >
> > software suspend.
> >
> > > "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
> > > "Executable file formats"
>
> Brad,
>
> This is a tough one because ACPI *is* power management but it is also
> configuration. It is equivalent to such things as MPS table parsing, $PIR
> parsing, PNPBIOS, as well as APM. The first two don't have CONFIG_ options
> at the moment but they should at some point.
>
> The only thing I can think of is a "Platform interface options" menu and
> just throw all of the above in that. Any other ideas?
"Platform interface" is fairly true, but so was "general options". Neither of
them is an obvious description of the functionality.

One idea that comes to mind is putting the power management config options in
a "Power Management" section, then PNPBIOS in with the other PnP stuff, and
so on (read: don't know were to put MPS yet, and don't know what $PIR is :) I
understand that this means breaking up the ACPI config file, but that
shouldn't be too hard.

The general concept is that [c,C]onfig.in should be functionality based, not
implementation based. ACPI parsing isn't a function, it supports a whole
range of functions, which are quite different to the user.

Brad
--
http://conf.linux.org.au. 22-25Jan2003. Perth, Australia. Birds in Black.

2002-06-05 10:29:41

by Dave Jones

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

On Wed, Jun 05, 2002 at 11:34:23AM +1000, Brad Hards wrote:

> One idea that comes to mind is putting the power management config options in
> a "Power Management" section

*nod* sounds sensible 8)

> then PNPBIOS in with the other PnP stuff, and
> so on (read: don't know were to put MPS yet, and don't know what $PIR is :)

It's an interrupt routing table.

MPS and interrupt routing are both CPU related features, so the best
place we currently have is under the CPU menu imho.

Dave

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

2002-06-05 14:02:03

by Martin Dalecki

[permalink] [raw]
Subject: [PATCH] 2.5.20 IDE 85

diff -urN linux-2.5.20/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux-2.5.20/drivers/block/ll_rw_blk.c 2002-06-03 03:44:41.000000000 +0200
+++ linux/drivers/block/ll_rw_blk.c 2002-06-05 02:37:13.000000000 +0200
@@ -507,7 +507,6 @@
"REQ_STARTED",
"REQ_DONTPREP",
"REQ_QUEUED",
- "REQ_DRIVE_ACB",
"REQ_PC",
"REQ_BLOCK_PC",
"REQ_SENSE",
diff -urN linux-2.5.20/drivers/ide/icside.c linux/drivers/ide/icside.c
--- linux-2.5.20/drivers/ide/icside.c 2002-06-05 13:06:33.000000000 +0200
+++ linux/drivers/ide/icside.c 2002-06-05 11:56:14.000000000 +0200
@@ -281,7 +281,7 @@
struct scatterlist *sg = ch->sg_table;
int nents;

- if (rq->flags & REQ_DRIVE_ACB) {
+ if (rq->flags & REQ_SPECIAL) {
struct ata_taskfile *args = rq->special;

if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
@@ -391,7 +391,7 @@
udma_tcq_enable(drive, 0);
#endif
}
-
+
/*
* We don't need any bouncing. Yes, this looks the
* wrong way around, but it is correct.
@@ -492,7 +492,7 @@
*/
BUG_ON(dma_channel_active(ch->hw.dma));

- count = ch->sg_nents = ide_build_sglist(ch, rq);
+ count = ch->sg_nents = ide_build_sglist(drive, rq);
if (!count)
return 1;

@@ -518,33 +518,6 @@
return 0;
}

-static int icside_dma_read(struct ata_device *drive, struct request *rq)
-{
- struct ata_channel *ch = drive->channel;
- unsigned int cmd;
-
- if (icside_dma_common(drive, rq, DMA_MODE_READ))
- return 1;
-
- if (drive->type != ATA_DISK)
- return 0;
-
- ide_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);
-
- if ((rq->flags & REQ_DRIVE_ACB) && drive->addressing == 1) {
- struct ata_taskfile *args = rq->special;
- cmd = args->taskfile.command;
- } else if (drive->addressing) {
- cmd = WIN_READDMA_EXT;
- } else {
- cmd = WIN_READDMA;
- }
-
- OUT_BYTE(cmd, IDE_COMMAND_REG);
- enable_dma(ch->hw.dma);
- return 0;
-}
-
static int icside_dma_init(struct ata_device *drive, struct request *rq)
{
struct ata_channel *ch = drive->channel;
@@ -558,13 +531,13 @@

ide_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);

- if ((rq->flags & REQ_DRIVE_ACB) && drive->addressing == 1) {
+ if ((rq->flags & REQ_SPECIAL) && drive->addressing == 1) {
struct ata_taskfile *args = rq->special;
- cmd = args->taskfile.command;
+ cmd = args->cmd;
} else if (drive->addressing) {
- cmd = WIN_WRITEDMA_EXT;
+ cmd = rq_data_dir(rq) == WRITE ? WIN_WRITEDMA_EXT : WIN_READDMA_EXT;
} else {
- cmd = WIN_WRITEDMA;
+ cmd = rq_data_dir(rq) == WRITE ? WIN_WRITEDMA : WIN_READDMA;
}
OUT_BYTE(cmd, IDE_COMMAND_REG);

diff -urN linux-2.5.20/drivers/ide/ide.c linux/drivers/ide/ide.c
--- linux-2.5.20/drivers/ide/ide.c 2002-06-05 13:06:36.000000000 +0200
+++ linux/drivers/ide/ide.c 2002-06-05 02:37:13.000000000 +0200
@@ -389,37 +389,6 @@
IN_BYTE(IDE_SECTOR_REG);
}

-/*
- * Clean up after success/failure of an explicit drive cmd
- *
- * Should be called under lock held.
- */
-void ide_end_drive_cmd(struct ata_device *drive, struct request *rq)
-{
- if (rq->flags & REQ_DRIVE_ACB) {
- struct ata_taskfile *ar = rq->special;
-
- rq->errors = !ata_status(drive, READY_STAT, BAD_STAT);
- if (ar) {
- ar->taskfile.feature = IN_BYTE(IDE_ERROR_REG);
- ata_in_regfile(drive, &ar->taskfile);
- ar->taskfile.device_head = IN_BYTE(IDE_SELECT_REG);
- if ((drive->id->command_set_2 & 0x0400) &&
- (drive->id->cfs_enable_2 & 0x0400) &&
- (drive->addressing == 1)) {
- /* The following command goes to the hob file! */
- OUT_BYTE(0x80, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
- ar->hobfile.feature = IN_BYTE(IDE_FEATURE_REG);
- ata_in_regfile(drive, &ar->hobfile);
- }
- }
- }
-
- blkdev_dequeue_request(rq);
- drive->rq = NULL;
- end_that_request_last(rq);
-}
-
#if FANCY_STATUS_DUMPS
struct ata_bit_messages {
u8 mask;
@@ -552,25 +521,11 @@
#endif

/*
- * This is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
- *
- * FIXME: Why can't be just use task_no_data_intr here?
- */
-static ide_startstop_t recal_intr(struct ata_device *drive, struct request *rq)
-{
- if (!ata_status(drive, READY_STAT, BAD_STAT))
- return ata_error(drive, rq, __FUNCTION__);
-
- return ide_stopped;
-}
-
-/*
* We are still on the old request path here so issuing the recalibrate command
* directly should just work.
*/
static int do_recalibrate(struct ata_device *drive)
{
- printk(KERN_INFO "%s: recalibrating!\n", drive->name);

if (drive->type != ATA_DISK)
return ide_stopped;
@@ -578,12 +533,12 @@
if (!IS_PDC4030_DRIVE) {
struct ata_taskfile args;

+ printk(KERN_INFO "%s: recalibrating...\n", drive->name);
memset(&args, 0, sizeof(args));
args.taskfile.sector_count = drive->sect;
args.cmd = WIN_RESTORE;
- args.handler = recal_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
- ata_taskfile(drive, &args, NULL);
+ ide_raw_taskfile(drive, &args);
+ printk(KERN_INFO "%s: done!\n", drive->name);
}

return IS_PDC4030_DRIVE ? ide_stopped : ide_started;
@@ -604,7 +559,6 @@
/* retry only "normal" I/O: */
if (!(rq->flags & REQ_CMD)) {
rq->errors = 1;
- ide_end_drive_cmd(drive, rq);

return ide_stopped;
}
@@ -633,6 +587,7 @@
OUT_BYTE(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); /* force an abort */

if (rq->errors >= ERROR_MAX) {
+ printk(KERN_ERR "%s: max number of retries exceeded!\n", drive->name);
if (ata_ops(drive) && ata_ops(drive)->end_request)
ata_ops(drive)->end_request(drive, rq, 0);
else
@@ -729,10 +684,10 @@

/* Strange disk manager remap.
*/
- if ((rq->flags & REQ_CMD) &&
- (drive->type == ATA_DISK || drive->type == ATA_FLOPPY)) {
- block += drive->sect0;
- }
+ if (rq->flags & REQ_CMD)
+ if (drive->type == ATA_DISK || drive->type == ATA_FLOPPY)
+ block += drive->sect0;
+

/* Yecch - this will shift the entire interval, possibly killing some
* innocent following sector.
@@ -753,14 +708,8 @@

/* This issues a special drive command.
*/
- if (rq->flags & REQ_DRIVE_ACB) {
- struct ata_taskfile *ar = rq->special;
-
- if (!(ar))
- goto args_error;
-
- return ata_taskfile(drive, ar, NULL);
- }
+ if (rq->flags & REQ_SPECIAL)
+ return ata_taskfile(drive, rq->special, NULL);

/* The normal way of execution is to pass and execute the request
* handler down to the device type driver.
@@ -789,19 +738,6 @@
ide_end_request(drive, rq, 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, rq);
-
- return ide_stopped;
}

ide_startstop_t restart_request(struct ata_device *drive)
@@ -1485,8 +1421,8 @@
EXPORT_SYMBOL(ata_error);

EXPORT_SYMBOL(ide_wait_stat);
+/* FIXME: this is a trully bad name */
EXPORT_SYMBOL(restart_request);
-EXPORT_SYMBOL(ide_end_drive_cmd);
EXPORT_SYMBOL(__ide_end_request);
EXPORT_SYMBOL(ide_end_request);
EXPORT_SYMBOL(ide_stall_queue);
diff -urN linux-2.5.20/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
--- linux-2.5.20/drivers/ide/ide-disk.c 2002-06-05 13:06:36.000000000 +0200
+++ linux/drivers/ide/ide-disk.c 2002-06-05 02:37:13.000000000 +0200
@@ -372,9 +372,8 @@
}
}
}
- ar->handler = task_no_data_intr;
- ar->command_type = IDE_DRIVE_TASK_NO_DATA;

+ /* not reached! */
return WIN_NOP;
}

@@ -582,23 +581,21 @@
{
MOD_INC_USE_COUNT;
if (drive->removable && drive->usage == 1) {
- struct ata_taskfile args;
-
check_disk_change(inode->i_rdev);

- memset(&args, 0, sizeof(args));
- args.cmd = WIN_DOORLOCK;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
/*
* Ignore the return code from door_lock, since the open() has
* already succeeded once, and the door_lock is irrelevant at this
* time.
*/
+ if (drive->doorlocking) {
+ struct ata_taskfile args;

- if (drive->doorlocking && ide_raw_taskfile(drive, &args))
- drive->doorlocking = 0;
+ memset(&args, 0, sizeof(args));
+ args.cmd = WIN_DOORLOCK;
+ if (ide_raw_taskfile(drive, &args))
+ drive->doorlocking = 0;
+ }
}
return 0;
}
@@ -613,29 +610,23 @@
args.cmd = WIN_FLUSH_CACHE_EXT;
else
args.cmd = WIN_FLUSH_CACHE;
-
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
return ide_raw_taskfile(drive, &args);
}

static void idedisk_release(struct inode *inode, struct file *filp, struct ata_device *drive)
{
if (drive->removable && !drive->usage) {
- struct ata_taskfile args;
-
/* XXX I don't think this is up to the lowlevel drivers.. --hch */
invalidate_bdev(inode->i_bdev, 0);

- memset(&args, 0, sizeof(args));
- args.cmd = WIN_DOORUNLOCK;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
- if (drive->doorlocking &&
- ide_raw_taskfile(drive, &args))
- drive->doorlocking = 0;
+ if (drive->doorlocking) {
+ struct ata_taskfile args;
+
+ memset(&args, 0, sizeof(args));
+ args.cmd = WIN_DOORUNLOCK;
+ if (ide_raw_taskfile(drive, &args))
+ drive->doorlocking = 0;
+ }
}
if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
if (idedisk_flushcache(drive))
@@ -680,9 +671,6 @@
memset(&args, 0, sizeof(args));
args.taskfile.sector_count = arg;
args.cmd = WIN_SETMULT;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
if (!ide_raw_taskfile(drive, &args)) {
/* all went well track this setting as valid */
drive->mult_count = arg;
@@ -712,9 +700,6 @@
memset(&args, 0, sizeof(args));
args.taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
args.cmd = WIN_SETFEATURES;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
ide_raw_taskfile(drive, &args);

drive->wcache = arg;
@@ -728,9 +713,6 @@

memset(&args, 0, sizeof(args));
args.cmd = WIN_STANDBYNOW1;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
return ide_raw_taskfile(drive, &args);
}

@@ -742,9 +724,6 @@
args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
args.taskfile.sector_count = arg;
args.cmd = WIN_SETFEATURES;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
ide_raw_taskfile(drive, &args);

drive->acoustic = arg;
@@ -864,9 +843,6 @@
memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40;
args.cmd = WIN_READ_NATIVE_MAX;
- args.handler = task_no_data_intr;
-
- /* submit command request */
ide_raw_taskfile(drive, &args);

/* if OK, compute maximum address value */
@@ -892,9 +868,6 @@

args.taskfile.device_head = 0x40;
args.cmd = WIN_READ_NATIVE_MAX_EXT;
- args.handler = task_no_data_intr;
-
- /* submit command request */
ide_raw_taskfile(drive, &args);

/* if OK, compute maximum address value */
@@ -933,9 +906,8 @@

args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
args.cmd = WIN_SET_MAX;
- args.handler = task_no_data_intr;
- /* submit command request */
ide_raw_taskfile(drive, &args);
+
/* if OK, read new maximum address value */
if (!(drive->status & ERR_STAT)) {
addr_set = ((args.taskfile.device_head & 0x0f) << 24)
@@ -965,12 +937,10 @@
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.handler = task_no_data_intr;
- /* submit command request */
ide_raw_taskfile(drive, &args);
+
/* if OK, compute maximum address value */
if (!(drive->status & ERR_STAT)) {
u32 high = (args.hobfile.high_cylinder << 16) |
diff -urN linux-2.5.20/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c
--- linux-2.5.20/drivers/ide/ide-floppy.c 2002-06-03 03:44:44.000000000 +0200
+++ linux/drivers/ide/ide-floppy.c 2002-06-05 02:37:13.000000000 +0200
@@ -308,8 +308,6 @@
#define IDEFLOPPY_IOCTL_FORMAT_START 0x4602
#define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603

-#define IDEFLOPPY_RQ (REQ_SPECIAL)
-
/*
* Error codes which are returned in rq->errors to the higher part
* of the driver.
@@ -633,7 +631,7 @@
if (!rq)
return 0;

- if (!(rq->flags & IDEFLOPPY_RQ)) {
+ if (!(rq->flags & REQ_SPECIAL)) {
ide_end_request(drive, rq, uptodate);
return 0;
}
@@ -717,7 +715,7 @@
struct atapi_packet_command *pc, struct request *rq)
{
memset(rq, 0, sizeof(*rq));
- rq->flags = IDEFLOPPY_RQ;
+ rq->flags = REQ_SPECIAL;
/* FIXME: --mdcki */
rq->buffer = (char *) pc;
(void) ide_do_drive_cmd (drive, rq, ide_preempt);
@@ -1251,7 +1249,7 @@
}
pc = idefloppy_next_pc_storage(drive);
idefloppy_create_rw_cmd (floppy, pc, rq, block);
- } else if (rq->flags & IDEFLOPPY_RQ) {
+ } else if (rq->flags & REQ_SPECIAL) {
/* FIXME: --mdcki */
pc = (struct atapi_packet_command *) rq->buffer;
} else {
@@ -1274,7 +1272,7 @@
memset(&rq, 0, sizeof(rq));
/* FIXME: --mdcki */
rq.buffer = (char *) pc;
- rq.flags = IDEFLOPPY_RQ;
+ rq.flags = REQ_SPECIAL;

return ide_do_drive_cmd(drive, &rq, ide_wait);
}
diff -urN linux-2.5.20/drivers/ide/ide-pmac.c linux/drivers/ide/ide-pmac.c
--- linux-2.5.20/drivers/ide/ide-pmac.c 2002-06-03 03:44:51.000000000 +0200
+++ linux/drivers/ide/ide-pmac.c 2002-06-05 11:50:35.000000000 +0200
@@ -1126,7 +1126,7 @@
udelay(1);

/* Build sglist */
- if (rq->flags & REQ_DRIVE_ACB) {
+ if (rq->flags & REQ_SPECIAL) {
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);
@@ -1437,10 +1437,11 @@
if (drive->type != ATA_DISK)
return 0;
ide_set_handler(drive, ide_dma_intr, WAIT_CMD, NULL);
- if ((rq->flags & REQ_DRIVE_ACB) &&
+ if ((rq->flags & REQ_SPECIAL) &&
(drive->addressing == 1)) {
struct ata_taskfile *args = rq->special;
- OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
+ /* FIXME: this is never reached */
+ OUT_BYTE(args->cmd, IDE_COMMAND_REG);
} else if (drive->addressing) {
OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
} else {
diff -urN linux-2.5.20/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c
--- linux-2.5.20/drivers/ide/ide-taskfile.c 2002-06-05 13:06:36.000000000 +0200
+++ linux/drivers/ide/ide-taskfile.c 2002-06-05 02:37:13.000000000 +0200
@@ -176,27 +176,6 @@
return 1; /* drive ready: *might* be interrupting */
}

-/*
- * Handler for commands without a data phase
- */
-ide_startstop_t task_no_data_intr(struct ata_device *drive, struct request *rq)
-{
- struct ata_taskfile *ar = rq->special;
-
- ide__sti(); /* local CPU only */
-
- if (!ata_status(drive, READY_STAT, BAD_STAT)) {
- /* Keep quiet for NOP because it is expected to fail. */
- if (ar && ar->cmd != WIN_NOP)
- return ata_error(drive, rq, __FUNCTION__);
- }
-
- if (ar)
- ide_end_drive_cmd(drive, rq);
-
- return ide_stopped;
-}
-
ide_startstop_t ata_taskfile(struct ata_device *drive,
struct ata_taskfile *ar, struct request *rq)
{
@@ -385,21 +364,72 @@

}

-int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *args)
+
+/*
+ * Invoked on completion of a special REQ_SPECIAL command.
+ */
+ide_startstop_t ata_special_intr(struct ata_device *drive, struct
+ request *rq) {
+
+ struct ata_taskfile *ar = rq->special;
+ ide_startstop_t ret = ide_stopped;
+
+ ide__sti(); /* local CPU only */
+ if (rq->buffer && ar->taskfile.sector_number) {
+ if (!ata_status(drive, 0, DRQ_STAT) && ar->taskfile.sector_number) {
+ int retries = 10;
+
+ ata_read(drive, rq->buffer, ar->taskfile.sector_number * SECTOR_WORDS);
+
+ while (!ata_status(drive, 0, BUSY_STAT) && retries--)
+ udelay(100);
+ }
+ }
+
+ if (!ata_status(drive, READY_STAT, BAD_STAT)) {
+ /* Keep quiet for NOP because it is expected to fail. */
+ if (ar->cmd != WIN_NOP)
+ ret = ata_error(drive, rq, __FUNCTION__);
+ rq->errors = 1;
+ }
+
+ ar->taskfile.feature = IN_BYTE(IDE_ERROR_REG);
+ ata_in_regfile(drive, &ar->taskfile);
+ ar->taskfile.device_head = IN_BYTE(IDE_SELECT_REG);
+ if ((drive->id->command_set_2 & 0x0400) &&
+ (drive->id->cfs_enable_2 & 0x0400) &&
+ (drive->addressing == 1)) {
+ /* The following command goes to the hob file! */
+ OUT_BYTE(0x80, drive->channel->io_ports[IDE_CONTROL_OFFSET]);
+ ar->hobfile.feature = IN_BYTE(IDE_FEATURE_REG);
+ ata_in_regfile(drive, &ar->hobfile);
+ }
+
+ blkdev_dequeue_request(rq);
+ drive->rq = NULL;
+ end_that_request_last(rq);
+
+ return ret;
+}
+
+int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar)
{
- struct request rq;
+ struct request req;
+
+ ar->command_type = IDE_DRIVE_TASK_NO_DATA;
+ ar->handler = ata_special_intr;

- memset(&rq, 0, sizeof(rq));
- rq.flags = REQ_DRIVE_ACB;
- rq.special = args;
+ memset(&req, 0, sizeof(req));
+ req.flags = REQ_SPECIAL;
+ req.special = ar;

- return ide_do_drive_cmd(drive, &rq, ide_wait);
+ return ide_do_drive_cmd(drive, &req, ide_wait);
}

EXPORT_SYMBOL(drive_is_ready);
+EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write);
EXPORT_SYMBOL(ata_taskfile);
-EXPORT_SYMBOL(task_no_data_intr);
-EXPORT_SYMBOL(ide_do_drive_cmd);
+EXPORT_SYMBOL(ata_special_intr);
EXPORT_SYMBOL(ide_raw_taskfile);
diff -urN linux-2.5.20/drivers/ide/ioctl.c linux/drivers/ide/ioctl.c
--- linux-2.5.20/drivers/ide/ioctl.c 2002-06-05 13:06:36.000000000 +0200
+++ linux/drivers/ide/ioctl.c 2002-06-05 02:37:13.000000000 +0200
@@ -34,30 +34,6 @@
#include "ioctl.h"

/*
- * Invoked on completion of a special DRIVE_CMD.
- */
-static ide_startstop_t drive_cmd_intr(struct ata_device *drive, struct request *rq)
-{
- struct ata_taskfile *ar = rq->special;
-
- ide__sti(); /* local CPU only */
- if (!ata_status(drive, 0, DRQ_STAT) && ar->taskfile.sector_number) {
- int retries = 10;
-
- ata_read(drive, rq->buffer, ar->taskfile.sector_number * SECTOR_WORDS);
-
- while (!ata_status(drive, 0, BUSY_STAT) && retries--)
- udelay(100);
- }
-
- if (!ata_status(drive, READY_STAT, BAD_STAT))
- return ata_error(drive, rq, __FUNCTION__); /* already calls ide_end_drive_cmd */
- ide_end_drive_cmd(drive, rq);
-
- return ide_stopped;
-}
-
-/*
* Implement generic ioctls invoked from userspace to imlpement specific
* functionality.
*
@@ -79,7 +55,7 @@
return -EFAULT;

memset(&rq, 0, sizeof(rq));
- rq.flags = REQ_DRIVE_ACB;
+ rq.flags = REQ_SPECIAL;

memset(&args, 0, sizeof(args));

@@ -107,7 +83,7 @@

/* Issue ATA command and wait for completion.
*/
- args.handler = drive_cmd_intr;
+ args.handler = ata_special_intr;

rq.buffer = argbuf + 4;
rq.special = &args;
diff -urN linux-2.5.20/drivers/ide/pcidma.c linux/drivers/ide/pcidma.c
--- linux-2.5.20/drivers/ide/pcidma.c 2002-06-05 13:06:33.000000000 +0200
+++ linux/drivers/ide/pcidma.c 2002-06-05 02:37:13.000000000 +0200
@@ -64,7 +64,7 @@
struct scatterlist *sg = ch->sg_table;
int nents = 0;

- if (rq->flags & REQ_DRIVE_ACB) {
+ if (rq->flags & REQ_SPECIAL) {
struct ata_taskfile *args = rq->special;
#if 1
unsigned char *virt_addr = rq->buffer;
@@ -525,6 +525,7 @@
if (ata_start_dma(drive, rq))
return 1;

+ /* No DMA transfers on ATAPI devices. */
if (drive->type != ATA_DISK)
return 0;

@@ -533,13 +534,8 @@
else
cmd = 0x00;

- ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */
- if ((rq->flags & REQ_DRIVE_ACB) && (drive->addressing == 1)) {
- /* FIXME: this should never happen */
- struct ata_taskfile *args = rq->special;
-
- outb(args->cmd, IDE_COMMAND_REG);
- } else if (drive->addressing)
+ ide_set_handler(drive, ide_dma_intr, WAIT_CMD, dma_timer_expiry);
+ if (drive->addressing)
outb(cmd ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
else
outb(cmd ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
diff -urN linux-2.5.20/drivers/ide/tcq.c linux/drivers/ide/tcq.c
--- linux-2.5.20/drivers/ide/tcq.c 2002-06-05 13:06:36.000000000 +0200
+++ linux/drivers/ide/tcq.c 2002-06-05 02:37:13.000000000 +0200
@@ -60,7 +60,9 @@
struct ata_taskfile *args = rq->special;

ide__sti();
- ide_end_drive_cmd(drive, rq);
+ blkdev_dequeue_request(rq);
+ drive->rq = NULL;
+ end_that_request_last(rq);
kfree(args);

return ide_stopped;
@@ -402,18 +404,14 @@
if (drives <= 1)
return 0;

- memset(&args, 0, sizeof(args));
-
- args.taskfile.feature = 0x01;
- args.cmd = WIN_NOP;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
/*
* do taskfile and check ABRT bit -- intelligent adapters will not
* pass NOP with sub-code 0x01 to device, so the command will not
* fail there
*/
+ memset(&args, 0, sizeof(args));
+ args.taskfile.feature = 0x01;
+ args.cmd = WIN_NOP;
ide_raw_taskfile(drive, &args);
if (args.taskfile.feature & ABRT_ERR)
return 1;
@@ -442,9 +440,6 @@
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_WCACHE;
args.cmd = WIN_SETFEATURES;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
if (ide_raw_taskfile(drive, &args)) {
printk("%s: failed to enable write cache\n", drive->name);
return 1;
@@ -457,9 +452,6 @@
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_DIS_RI;
args.cmd = WIN_SETFEATURES;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
if (ide_raw_taskfile(drive, &args)) {
printk("%s: disabling release interrupt fail\n", drive->name);
return 1;
@@ -472,9 +464,6 @@
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_SI;
args.cmd = WIN_SETFEATURES;
- args.handler = task_no_data_intr;
- args.command_type = IDE_DRIVE_TASK_NO_DATA;
-
if (ide_raw_taskfile(drive, &args)) {
printk("%s: enabling service interrupt fail\n", drive->name);
return 1;
diff -urN linux-2.5.20/include/linux/blkdev.h linux/include/linux/blkdev.h
--- linux-2.5.20/include/linux/blkdev.h 2002-06-03 03:44:44.000000000 +0200
+++ linux/include/linux/blkdev.h 2002-06-05 02:39:00.000000000 +0200
@@ -81,13 +81,11 @@
/*
* for ATA/ATAPI devices
*/
- __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 (currently reset) */
+ __REQ_SPECIAL, /* driver suplied command */

__REQ_NR_BITS, /* stops here */
};
@@ -100,7 +98,6 @@
#define REQ_STARTED (1 << __REQ_STARTED)
#define REQ_DONTPREP (1 << __REQ_DONTPREP)
#define REQ_QUEUED (1 << __REQ_QUEUED)
-#define REQ_DRIVE_ACB (1 << __REQ_DRIVE_ACB)
#define REQ_PC (1 << __REQ_PC)
#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC)
#define REQ_SENSE (1 << __REQ_SENSE)
diff -urN linux-2.5.20/include/linux/ide.h linux/include/linux/ide.h
--- linux-2.5.20/include/linux/ide.h 2002-06-05 13:06:36.000000000 +0200
+++ linux/include/linux/ide.h 2002-06-05 02:40:26.000000000 +0200
@@ -654,11 +654,6 @@

extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t);

-/*
- * Clean up after success/failure of an explicit drive cmd.
- */
-extern void ide_end_drive_cmd(struct ata_device *, struct request *);
-
struct ata_taskfile {
struct hd_drive_task_hdr taskfile;
struct hd_drive_task_hdr hobfile;
@@ -695,7 +690,7 @@
bio_kunmap_irq(to, flags);
}

-extern ide_startstop_t task_no_data_intr(struct ata_device *, struct request *);
+extern ide_startstop_t ata_special_intr(struct ata_device *, struct request *);
extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *);

extern void ide_fix_driveid(struct hd_driveid *id);


Attachments:
ide-clean-85.diff (23.07 kB)

2002-06-05 14:17:41

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

On Wed, Jun 05 2002, Martin Dalecki wrote:

AFAICS, you just introduced some nasty list races in the interrupt
handlers. You must hold the queue locks when calling
blkdev_dequeue_request() and end_that_request_last(), for instance.

--
Jens Axboe

2002-06-05 14:58:53

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

Jens Axboe wrote:
> On Wed, Jun 05 2002, Martin Dalecki wrote:
>
> AFAICS, you just introduced some nasty list races in the interrupt
> handlers. You must hold the queue locks when calling
> blkdev_dequeue_request() and end_that_request_last(), for instance.
>

No. Please be more accurate. Becouse:

1. If anything I have made existing races only "obvious".

2. It is called in the context of do_ide_request or ide_raw_taskfile
where we already have the lock.


2002-06-05 15:49:13

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

On Wed, Jun 05 2002, Martin Dalecki wrote:
> Jens Axboe wrote:
> >On Wed, Jun 05 2002, Martin Dalecki wrote:
> >
> >AFAICS, you just introduced some nasty list races in the interrupt
> >handlers. You must hold the queue locks when calling
> >blkdev_dequeue_request() and end_that_request_last(), for instance.
> >
>
> No. Please be more accurate. Becouse:
>
> 1. If anything I have made existing races only "obvious".

If anything, you've made a race you introduced earlier more obvious.

> 2. It is called in the context of do_ide_request or ide_raw_taskfile
> where we already have the lock.

?? Both tcq and ata_special_intr look like interrupt handlers to me.

--
Jens Axboe

2002-06-05 15:52:56

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

On Wed, Jun 05 2002, Jens Axboe wrote:
> On Wed, Jun 05 2002, Martin Dalecki wrote:
> > Jens Axboe wrote:
> > >On Wed, Jun 05 2002, Martin Dalecki wrote:
> > >
> > >AFAICS, you just introduced some nasty list races in the interrupt
> > >handlers. You must hold the queue locks when calling
> > >blkdev_dequeue_request() and end_that_request_last(), for instance.
> > >
> >
> > No. Please be more accurate. Becouse:
> >
> > 1. If anything I have made existing races only "obvious".
>
> If anything, you've made a race you introduced earlier more obvious.
>
> > 2. It is called in the context of do_ide_request or ide_raw_taskfile
> > where we already have the lock.
>
> ?? Both tcq and ata_special_intr look like interrupt handlers to me.

BTW, I wanted to look at the code (and not just read the patch), but
it's not clear from the patch what it is against. Where do you keep
older patches so I can get them? Maybe the ide code could do with a bit
of peer review :-)

--
Jens Axboe

2002-06-05 16:09:29

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

Jens Axboe wrote:
> On Wed, Jun 05 2002, Jens Axboe wrote:
>
>>On Wed, Jun 05 2002, Martin Dalecki wrote:
>>
>>>Jens Axboe wrote:
>>>
>>>>On Wed, Jun 05 2002, Martin Dalecki wrote:
>>>>
>>>>AFAICS, you just introduced some nasty list races in the interrupt
>>>>handlers. You must hold the queue locks when calling
>>>>blkdev_dequeue_request() and end_that_request_last(), for instance.
>>>>
>>>
>>>No. Please be more accurate. Becouse:
>>>
>>>1. If anything I have made existing races only "obvious".
>>
>>If anything, you've made a race you introduced earlier more obvious.
>>
>>
>>>2. It is called in the context of do_ide_request or ide_raw_taskfile
>>> where we already have the lock.
>>
>>?? Both tcq and ata_special_intr look like interrupt handlers to me.
>
>
> BTW, I wanted to look at the code (and not just read the patch), but
> it's not clear from the patch what it is against. Where do you keep
> older patches so I can get them? Maybe the ide code could do with a bit
> of peer review :-)
>

Well IDE 83 and 84 are already inside the bk repository at linux.bkbits.com.
No as far as of now I don't have any public FTP or whatever area for
the patches (Well send you everything in one go.)
And I of course agree that the code needs a peer review in this area.
Adding the locking isn't difficult.
However I wonder a bit whatever we couldn't just blkdev_dequeue_request()
once at request handling start? We drag drive->rq around anyway...


2002-06-05 16:14:42

by Jens Axboe

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

On Wed, Jun 05 2002, Martin Dalecki wrote:
> Jens Axboe wrote:
> >On Wed, Jun 05 2002, Jens Axboe wrote:
> >
> >>On Wed, Jun 05 2002, Martin Dalecki wrote:
> >>
> >>>Jens Axboe wrote:
> >>>
> >>>>On Wed, Jun 05 2002, Martin Dalecki wrote:
> >>>>
> >>>>AFAICS, you just introduced some nasty list races in the interrupt
> >>>>handlers. You must hold the queue locks when calling
> >>>>blkdev_dequeue_request() and end_that_request_last(), for instance.
> >>>>
> >>>
> >>>No. Please be more accurate. Becouse:
> >>>
> >>>1. If anything I have made existing races only "obvious".
> >>
> >>If anything, you've made a race you introduced earlier more obvious.
> >>
> >>
> >>>2. It is called in the context of do_ide_request or ide_raw_taskfile
> >>> where we already have the lock.
> >>
> >>?? Both tcq and ata_special_intr look like interrupt handlers to me.
> >
> >
> >BTW, I wanted to look at the code (and not just read the patch), but
> >it's not clear from the patch what it is against. Where do you keep
> >older patches so I can get them? Maybe the ide code could do with a bit
> >of peer review :-)
> >
>
> Well IDE 83 and 84 are already inside the bk repository at linux.bkbits.com.
> No as far as of now I don't have any public FTP or whatever area for
> the patches (Well send you everything in one go.)

Thanks. Just ask hpa for a kernel.org dir, if you don't have anywhere
else to keep it.

> And I of course agree that the code needs a peer review in this area.
> Adding the locking isn't difficult.

Of course not, discovering the missing locking is most of the work. And
of course acknowedging that there's a problem :-)

> However I wonder a bit whatever we couldn't just blkdev_dequeue_request()
> once at request handling start? We drag drive->rq around anyway...

I did that once a long time ago, but it was very broken because the IDE
code would end up in ide_do_request() several times at times before a
request was started. I think there are advantages both ways: leaving the
request on the queue until it is done allows the i/o scheduler to know
what the disk is currently working on. Removing it is potentially a bit
cleaner, however most of the reason for that has long been reworked in
2.5 (the plugging and head active stuff).

--
Jens Axboe

2002-06-05 16:25:09

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

Jens Axboe wrote:
> On Wed, Jun 05 2002, Martin Dalecki wrote:
>
>>Jens Axboe wrote:
>>
>>>On Wed, Jun 05 2002, Jens Axboe wrote:
>>>
>>>
>>>>On Wed, Jun 05 2002, Martin Dalecki wrote:
>>>>
>>>>
>>>>>Jens Axboe wrote:
>>>>>
>>>>>
>>>>>>On Wed, Jun 05 2002, Martin Dalecki wrote:
>>>>>>
>>>>>>AFAICS, you just introduced some nasty list races in the interrupt
>>>>>>handlers. You must hold the queue locks when calling
>>>>>>blkdev_dequeue_request() and end_that_request_last(), for instance.
>>>>>>
>>>>>
>>>>>No. Please be more accurate. Becouse:
>>>>>
>>>>>1. If anything I have made existing races only "obvious".
>>>>
>>>>If anything, you've made a race you introduced earlier more obvious.
>>>>
>>>>
>>>>
>>>>>2. It is called in the context of do_ide_request or ide_raw_taskfile
>>>>> where we already have the lock.
>>>>
>>>>?? Both tcq and ata_special_intr look like interrupt handlers to me.
>>>
>>>
>>>BTW, I wanted to look at the code (and not just read the patch), but
>>>it's not clear from the patch what it is against. Where do you keep
>>>older patches so I can get them? Maybe the ide code could do with a bit
>>>of peer review :-)
>>>
>>
>>Well IDE 83 and 84 are already inside the bk repository at linux.bkbits.com.
>>No as far as of now I don't have any public FTP or whatever area for
>>the patches (Well send you everything in one go.)
>
>
> Thanks. Just ask hpa for a kernel.org dir, if you don't have anywhere
> else to keep it.
>
>
>>And I of course agree that the code needs a peer review in this area.
>>Adding the locking isn't difficult.
>
>
> Of course not, discovering the missing locking is most of the work. And
> of course acknowedging that there's a problem :-)

Just to make sure that we understand each other. I admitt that
you are right there have to be locks there. As well as around any host chip
access. Thanks for the reminder.
And well please note that the last patches in esp. are trying
hard to reducde the number of possible code flow branch cases.

>>However I wonder a bit whatever we couldn't just blkdev_dequeue_request()
>>once at request handling start? We drag drive->rq around anyway...
>
>
> I did that once a long time ago, but it was very broken because the IDE
> code would end up in ide_do_request() several times at times before a
> request was started. I think there are advantages both ways: leaving the
> request on the queue until it is done allows the i/o scheduler to know
> what the disk is currently working on. Removing it is potentially a bit
> cleaner, however most of the reason for that has long been reworked in
> 2.5 (the plugging and head active stuff).

Yes I remember - the IDE/SCSI queue head differencies. Making
them to behave entierly equal would have some charm too...
However the multi ide_do_request entry problems should
have got *much* better due to the reduction of the multiple
submitted/injected artifical request (REQ_ and friends) types.
The remaining one is now only ide_raw_taskfile
and the regular onces. Well ide-tape and packet command handling aside...
but whom I'm telling this ... I'm sure you already know...



2002-06-05 16:36:31

by Tom Rini

[permalink] [raw]
Subject: [PATCH] Cleanup i386 <linux/init.h> abuses

The following patch cleans up the i386 usage of <linux/init.h>.
This remove <linux/init.h> from <asm-i386/system.h> which did not need
it, <asm-i386/highmem.h> which only had it due to an extern using
__init, which is not needed.
This adds <linux/init.h> to <asm-i386/bugs.h> which actually has
numerous __init functions and adds <linux/init.h> to 9 files inside of
arch/i386 which were indirectly including <linux/init.h> previously.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

===== arch/i386/kernel/setup-visws.c 1.1 vs edited =====
--- 1.1/arch/i386/kernel/setup-visws.c Tue Feb 5 16:59:42 2002
+++ edited/arch/i386/kernel/setup-visws.c Wed Jun 5 09:15:52 2002
@@ -3,6 +3,8 @@
* Split out from setup.c by [email protected]
*/

+#include <linux/init.h>
+
char visws_board_type = -1;
char visws_board_rev = -1;

===== arch/i386/mm/ioremap.c 1.8 vs edited =====
--- 1.8/arch/i386/mm/ioremap.c Fri May 3 05:26:39 2002
+++ edited/arch/i386/mm/ioremap.c Wed Jun 5 09:02:02 2002
@@ -9,6 +9,7 @@
*/

#include <linux/vmalloc.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#include <asm/fixmap.h>
===== arch/i386/pci/acpi.c 1.7 vs edited =====
--- 1.7/arch/i386/pci/acpi.c Wed May 29 15:54:35 2002
+++ edited/arch/i386/pci/acpi.c Wed Jun 5 09:11:10 2002
@@ -1,5 +1,6 @@
#include <linux/pci.h>
#include <linux/acpi.h>
+#include <linux/init.h>
#include "pci.h"

static int __init pci_acpi_init(void)
===== arch/i386/pci/common.c 1.31 vs edited =====
--- 1.31/arch/i386/pci/common.c Wed May 29 15:54:35 2002
+++ edited/arch/i386/pci/common.c Wed Jun 5 09:11:18 2002
@@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/ioport.h>
+#include <linux/init.h>

#include <asm/segment.h>
#include <asm/io.h>
===== arch/i386/pci/direct.c 1.6 vs edited =====
--- 1.6/arch/i386/pci/direct.c Tue May 7 10:27:29 2002
+++ edited/arch/i386/pci/direct.c Wed Jun 5 09:08:16 2002
@@ -3,6 +3,7 @@
*/

#include <linux/pci.h>
+#include <linux/init.h>
#include "pci.h"

/*
===== arch/i386/pci/fixup.c 1.9 vs edited =====
--- 1.9/arch/i386/pci/fixup.c Tue Jun 4 01:21:43 2002
+++ edited/arch/i386/pci/fixup.c Wed Jun 5 09:11:20 2002
@@ -3,6 +3,7 @@
*/

#include <linux/pci.h>
+#include <linux/init.h>
#include "pci.h"


===== arch/i386/pci/legacy.c 1.6 vs edited =====
--- 1.6/arch/i386/pci/legacy.c Wed May 29 15:54:35 2002
+++ edited/arch/i386/pci/legacy.c Wed Jun 5 09:11:22 2002
@@ -1,6 +1,7 @@
/*
* legacy.c - traditional, old school PCI bus probing
*/
+#include <linux/init.h>
#include <linux/pci.h>
#include "pci.h"

===== arch/i386/pci/numa.c 1.7 vs edited =====
--- 1.7/arch/i386/pci/numa.c Wed May 29 15:54:35 2002
+++ edited/arch/i386/pci/numa.c Wed Jun 5 09:11:28 2002
@@ -2,6 +2,7 @@
* numa.c - Low-level PCI access for NUMA-Q machines
*/
#include <linux/pci.h>
+#include <linux/init.h>

#include "pci.h"

===== arch/i386/pci/pcbios.c 1.6 vs edited =====
--- 1.6/arch/i386/pci/pcbios.c Tue May 7 10:27:29 2002
+++ edited/arch/i386/pci/pcbios.c Wed Jun 5 09:07:11 2002
@@ -3,6 +3,7 @@
*/

#include <linux/pci.h>
+#include <linux/init.h>
#include "pci.h"


===== include/asm-i386/bugs.h 1.6 vs edited =====
--- 1.6/include/asm-i386/bugs.h Mon May 20 16:07:18 2002
+++ edited/include/asm-i386/bugs.h Wed Jun 5 08:48:57 2002
@@ -21,6 +21,7 @@
*/

#include <linux/config.h>
+#include <linux/init.h>
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/msr.h>
===== include/asm-i386/highmem.h 1.6 vs edited =====
--- 1.6/include/asm-i386/highmem.h Thu Apr 4 21:51:47 2002
+++ edited/include/asm-i386/highmem.h Wed Jun 5 08:48:57 2002
@@ -21,7 +21,6 @@
#ifdef __KERNEL__

#include <linux/config.h>
-#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/kmap_types.h>
#include <asm/tlbflush.h>
@@ -33,7 +32,7 @@
extern pgprot_t kmap_prot;
extern pte_t *pkmap_page_table;

-extern void kmap_init(void) __init;
+extern void kmap_init(void);

/*
* Right now we initialize only a single pte table. It can be extended
===== include/asm-i386/system.h 1.11 vs edited =====
--- 1.11/include/asm-i386/system.h Tue Feb 12 09:53:18 2002
+++ edited/include/asm-i386/system.h Wed Jun 5 08:48:57 2002
@@ -3,7 +3,6 @@

#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/init.h>
#include <asm/segment.h>
#include <linux/bitops.h> /* for LOCK_PREFIX */

2002-06-05 18:04:31

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

Jens Axboe wrote:

>On Wed, Jun 05 2002, Martin Dalecki wrote:
>
>
>>
>>
>>Well IDE 83 and 84 are already inside the bk repository at linux.bkbits.com.
>>No as far as of now I don't have any public FTP or whatever area for
>>the patches (Well send you everything in one go.)
>>
>>
>
>Thanks. Just ask hpa for a kernel.org dir, if you don't have anywhere
>else to keep it.
>
>


Make that [email protected] :)

Jeff




2002-06-05 23:13:11

by Brad Hards

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

On Wed, 5 Jun 2002 20:29, Dave Jones wrote:
> On Wed, Jun 05, 2002 at 11:34:23AM +1000, Brad Hards wrote:
> > One idea that comes to mind is putting the power management config
> > options in a "Power Management" section
>
> *nod* sounds sensible 8)
>
> > then PNPBIOS in with the other PnP stuff, and
> > so on (read: don't know were to put MPS yet, and don't know what $PIR is
> > :)
>
> It's an interrupt routing table.
>
> MPS and interrupt routing are both CPU related features, so the best
> place we currently have is under the CPU menu imho.
Is it fundamentally different _functionality_ to the stuff that is in "Plug
and Play configuration" (which makes devices automatically get the right
itnerrupts)? [ Ignore implementation for a second - we can always solve this
with another layer of abstraction. :-]

Of course, putting all this into the CPU menu (which is obviously a per-arch
config.in change) would make drivers/arch/acpi/Config.in look a lot cleaner.

I'll try to work with Andy Grover off-list with this, and come up with an
agreed position.

Rusty: This is starting to get a little non-trivial. Please drop the two
patches I've sent. I'll get back to you later.

Brad
--
http://conf.linux.org.au. 22-25Jan2003. Perth, Australia. Birds in Black.

2002-06-05 23:23:15

by Tom Rini

[permalink] [raw]
Subject: [PATCH] Add <linux/kdev_t.h> to <linux/bio.h>

The following add <linux/kdev_t.h> to <linux/bio.h>.

This is needed since bio_ioctl takes a kdev_t for its first argument.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

===== include/linux/bio.h 1.13 vs edited =====
--- 1.13/include/linux/bio.h Wed Apr 24 13:00:40 2002
+++ edited/include/linux/bio.h Wed Jun 5 16:20:06 2002
@@ -20,6 +20,7 @@
#ifndef __LINUX_BIO_H
#define __LINUX_BIO_H

+#include <linux/kdev_t.h>
/* Platforms may set this to teach the BIO layer about IOMMU hardware. */
#include <asm/io.h>
#ifndef BIO_VMERGE_BOUNDARY

2002-06-05 23:34:27

by Russell King

[permalink] [raw]
Subject: Re: [PATCH] Add <linux/kdev_t.h> to <linux/bio.h>

On Wed, Jun 05, 2002 at 04:22:20PM -0700, Tom Rini wrote:
> The following add <linux/kdev_t.h> to <linux/bio.h>.
>
> This is needed since bio_ioctl takes a kdev_t for its first argument.

This should be fixed by a patch I submitted earlier today (you're getting
a build error in fs/mpage.c, right?)

hch asked the very pertinent question though - why isn't kdev_t defined
by linux/types.h ?

--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html

2002-06-05 23:42:25

by Tom Rini

[permalink] [raw]
Subject: Re: [PATCH] Add <linux/kdev_t.h> to <linux/bio.h>

On Thu, Jun 06, 2002 at 12:34:20AM +0100, Russell King wrote:
> On Wed, Jun 05, 2002 at 04:22:20PM -0700, Tom Rini wrote:
> > The following add <linux/kdev_t.h> to <linux/bio.h>.
> >
> > This is needed since bio_ioctl takes a kdev_t for its first argument.
>
> This should be fixed by a patch I submitted earlier today (you're getting
> a build error in fs/mpage.c, right?)

Nope. This was with that applied. I'm breaking up mm.h, slightly,
right now and hit that.

> hch asked the very pertinent question though - why isn't kdev_t defined
> by linux/types.h ?

That is a good question... Possibly because of the other stuff
associated with it.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

2002-06-06 08:16:09

by Martin Dalecki

[permalink] [raw]
Subject: Re: [PATCH] 2.5.20 IDE 85

> BTW, I wanted to look at the code (and not just read the patch), but
> it's not clear from the patch what it is against. Where do you keep
> older patches so I can get them? Maybe the ide code could do with a bit
> of peer review :-)

After having looked at the issue yearstoday, well I have a rather
trivial question: Can someone recommend me a good call graph generator
for the kernel code? It would be actually helpfull. (No please no
trash in perl or therelike...) Is there already any public
analyzed for the parse tree dumps which can be generated by
GCC 3.xx out there maybe?

2002-06-06 18:37:20

by Tom Rini

[permalink] [raw]
Subject: [PATCH] Move vmalloc wrappers out of include/linux/vmalloc.h

This moves the vmalloc wrappers from <linux/vmalloc.h> into mm/vmalloc.c.

Doing this will later allow us to remove <linux/mm.h> from <linux/vmalloc.h>,
along with some other #include fixups.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

===== include/linux/vmalloc.h 1.2 vs edited =====
--- 1.2/include/linux/vmalloc.h Fri Feb 8 20:10:55 2002
+++ edited/include/linux/vmalloc.h Thu Jun 6 09:54:55 2002
@@ -24,33 +24,13 @@
extern void vmfree_area_pages(unsigned long address, unsigned long size);
extern int vmalloc_area_pages(unsigned long address, unsigned long size,
int gfp_mask, pgprot_t prot);
-
-/*
- * Allocate any pages
- */
-
-static inline void * vmalloc (unsigned long size)
-{
- return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
/*
- * Allocate ISA addressable pages for broke crap
+ * Various ways to allocate pages.
*/

-static inline void * vmalloc_dma (unsigned long size)
-{
- return __vmalloc(size, GFP_KERNEL|GFP_DMA, PAGE_KERNEL);
-}
-
-/*
- * vmalloc 32bit PA addressable pages - eg for PCI 32bit devices
- */
-
-static inline void * vmalloc_32(unsigned long size)
-{
- return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
-}
+extern void * vmalloc(unsigned long size);
+extern void * vmalloc_dma(unsigned long size);
+extern void * vmalloc_32(unsigned long size);

/*
* vmlist_lock is a read-write spinlock that protects vmlist
===== mm/vmalloc.c 1.14 vs edited =====
--- 1.14/mm/vmalloc.c Fri May 3 04:27:09 2002
+++ edited/mm/vmalloc.c Thu Jun 6 09:50:13 2002
@@ -232,6 +232,33 @@
printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr);
}

+/*
+ * Allocate any pages
+ */
+
+void * vmalloc (unsigned long size)
+{
+ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
+}
+
+/*
+ * Allocate ISA addressable pages for broke crap
+ */
+
+void * vmalloc_dma (unsigned long size)
+{
+ return __vmalloc(size, GFP_KERNEL|GFP_DMA, PAGE_KERNEL);
+}
+
+/*
+ * vmalloc 32bit PA addressable pages - eg for PCI 32bit devices
+ */
+
+void * vmalloc_32(unsigned long size)
+{
+ return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
+}
+
void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot)
{
void * addr;

2002-06-06 18:31:11

by Pavel Machek

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

Hi!
> > Please don't tell people about sysrq-D, I'm going to kill that. OTOH
> > convient way is echo 4 > /proc/acpi/sleep -- that is if you have ACPI
> > enabled.
> Extract from the patch:
> - You may suspend your machine by either pressing Sysrq-d or with
> <snip>
> + require APM. You may suspend your machine by either pressing
> + Sysrq-d or with 'swsusp' or 'shutdown -z <time>' (patch for
>
> So it is in the original. When you kill the functionality, update the doco.

Yep, I should do that.

--
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.

2002-06-06 19:45:14

by Tom Rini

[permalink] [raw]
Subject: [PATCH] Remove <linux/mm.h> from <linux/vmalloc.h>

This removes <linux/mm.h> from <linux/vmalloc.h>.

This then goes and fixes all of the files (x86 and PPC) which relied on
implicit includes which don't happen anymore. This also takes
<linux/kdev_t.h> out of fs/mpage.c and puts it into include/linux/bio.h
where it belongs since <linux/bio.h> references 'kdev_t' directly.

A quick summary of the of the added includes:
arch/i386/kernel/microcode.c: needs extern for num_physpages, in linux/mm.h
include/linux/spinlock.h: local_irq* is defined in <asm/system.h> but
this was never directly included.

This depends on the patch to move the vmalloc wrappers out of
<linux/vmalloc.h>

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

===== arch/i386/kernel/microcode.c 1.10 vs edited =====
--- 1.10/arch/i386/kernel/microcode.c Thu May 23 09:06:16 2002
+++ edited/arch/i386/kernel/microcode.c Thu Jun 6 11:01:38 2002
@@ -67,6 +67,7 @@
#include <linux/miscdevice.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/spinlock.h>
+#include <linux/mm.h>

#include <asm/msr.h>
#include <asm/uaccess.h>
===== fs/mpage.c 1.4 vs edited =====
--- 1.4/fs/mpage.c Wed May 29 17:34:44 2002
+++ edited/fs/mpage.c Thu Jun 6 10:45:42 2002
@@ -12,7 +12,6 @@

#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/kdev_t.h>
#include <linux/bio.h>
#include <linux/fs.h>
#include <linux/buffer_head.h>
===== include/asm-i386/pci.h 1.13 vs edited =====
--- 1.13/include/asm-i386/pci.h Thu Mar 14 03:11:25 2002
+++ edited/include/asm-i386/pci.h Thu Jun 6 10:23:38 2002
@@ -4,6 +4,7 @@
#include <linux/config.h>

#ifdef __KERNEL__
+#include <linux/mm.h> /* for struct page */

/* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
===== include/asm-i386/pgalloc.h 1.15 vs edited =====
--- 1.15/include/asm-i386/pgalloc.h Wed May 15 23:17:13 2002
+++ edited/include/asm-i386/pgalloc.h Thu Jun 6 10:19:21 2002
@@ -5,6 +5,7 @@
#include <asm/processor.h>
#include <asm/fixmap.h>
#include <linux/threads.h>
+#include <linux/mm.h> /* for struct page */

#define pmd_populate_kernel(mm, pmd, pte) \
set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
===== include/linux/bio.h 1.13 vs edited =====
--- 1.13/include/linux/bio.h Wed Apr 24 13:00:40 2002
+++ edited/include/linux/bio.h Thu Jun 6 11:23:50 2002
@@ -20,6 +20,7 @@
#ifndef __LINUX_BIO_H
#define __LINUX_BIO_H

+#include <linux/kdev_t.h>
/* Platforms may set this to teach the BIO layer about IOMMU hardware. */
#include <asm/io.h>
#ifndef BIO_VMERGE_BOUNDARY
===== include/linux/spinlock.h 1.9 vs edited =====
--- 1.9/include/linux/spinlock.h Wed Apr 3 11:46:00 2002
+++ edited/include/linux/spinlock.h Thu Jun 6 11:23:50 2002
@@ -7,6 +7,8 @@
#include <linux/thread_info.h>
#include <linux/kernel.h>

+#include <asm/system.h>
+
/*
* These are the generic versions of the spinlocks and read-write
* locks..
===== include/linux/vmalloc.h 1.3 vs edited =====
--- 1.3/include/linux/vmalloc.h Thu Jun 6 10:15:09 2002
+++ edited/include/linux/vmalloc.h Thu Jun 6 10:19:16 2002
@@ -1,7 +1,6 @@
#ifndef __LINUX_VMALLOC_H
#define __LINUX_VMALLOC_H

-#include <linux/mm.h>
#include <linux/spinlock.h>

#include <asm/pgtable.h>

2002-06-06 21:03:53

by Tom Rini

[permalink] [raw]
Subject: [PATCH] More work on removing <linux/mm.h> from <linux/vmalloc.h>

On Thu, Jun 06, 2002 at 12:44:54PM -0700, Tom Rini wrote:
> This removes <linux/mm.h> from <linux/vmalloc.h>.
>
> This then goes and fixes all of the files (x86 and PPC) which relied on
> implicit includes which don't happen anymore. This also takes
> <linux/kdev_t.h> out of fs/mpage.c and puts it into include/linux/bio.h
> where it belongs since <linux/bio.h> references 'kdev_t' directly.
>
> A quick summary of the of the added includes:
> arch/i386/kernel/microcode.c: needs extern for num_physpages, in linux/mm.h
> include/linux/spinlock.h: local_irq* is defined in <asm/system.h> but
> this was never directly included.
>
> This depends on the patch to move the vmalloc wrappers out of
> <linux/vmalloc.h>

And the following is in addition to that patch for stuff that's in the
current linux-2.5 tree but wasn't when I tested the inital patch.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

===== arch/i386/kernel/cpu/amd.c 1.1 vs edited =====
--- 1.1/arch/i386/kernel/cpu/amd.c Wed May 8 08:11:31 2002
+++ edited/arch/i386/kernel/cpu/amd.c Thu Jun 6 13:51:10 2002
@@ -1,5 +1,6 @@
#include <linux/init.h>
#include <linux/bitops.h>
+#include <linux/mm.h>
#include <asm/io.h>
#include <asm/processor.h>

===== include/asm-i386/desc.h 1.4 vs edited =====
--- 1.4/include/asm-i386/desc.h Sat Apr 27 10:47:46 2002
+++ edited/include/asm-i386/desc.h Thu Jun 6 13:45:09 2002
@@ -49,6 +49,9 @@
#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY)

#ifndef __ASSEMBLY__
+
+#include <asm/mmu.h>
+
struct desc_struct {
unsigned long a,b;
};

2002-06-06 21:21:47

by Tom Rini

[permalink] [raw]
Subject: [PATCH] Include <linux/gfp.h> directly instead of via <linux/mm.h>

Change to including <linux/gfp.h> directly when possible.

These files used <linux/mm.h> to just get at <linux/gfp.h>, so include
it directly. This is part of what's needed to remove it from
<linux/mm.h>.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/


===== include/linux/pagemap.h 1.20 vs edited =====
--- 1.20/include/linux/pagemap.h Mon May 6 09:21:54 2002
+++ edited/include/linux/pagemap.h Thu Jun 6 14:05:07 2002
@@ -4,7 +4,7 @@
/*
* Copyright 1995 Linus Torvalds
*/
-#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/highmem.h>
===== kernel/futex.c 1.6 vs edited =====
--- 1.6/kernel/futex.c Thu Jun 6 10:13:05 2002
+++ edited/kernel/futex.c Thu Jun 6 14:05:07 2002
@@ -26,7 +26,7 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
-#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/hash.h>
#include <linux/init.h>
#include <linux/fs.h>
===== kernel/ptrace.c 1.11 vs edited =====
--- 1.11/kernel/ptrace.c Sat Mar 23 15:57:49 2002
+++ edited/kernel/ptrace.c Thu Jun 6 14:05:07 2002
@@ -9,7 +9,7 @@

#include <linux/sched.h>
#include <linux/errno.h>
-#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/highmem.h>
#include <linux/smp_lock.h>

2002-06-06 21:24:40

by Tom Rini

[permalink] [raw]
Subject: [PATCH] Remove numerous includes from <linux/mm.h>

Remove 4 #includes from <linux/mm.h> and fix up implicit includes.

This remove linux/gfp.h, linux/string.h, linux/mmzone.h and
linux/rbtree.h from <linux/mm.h> and fixes the callers which relied on
<linux/mm.h> to provide <linux/gfp.h>

This relies on all of the previously sent patches to work.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

===== fs/isofs/namei.c 1.9 vs edited =====
--- 1.9/fs/isofs/namei.c Thu May 23 06:18:50 2002
+++ edited/fs/isofs/namei.c Thu Jun 6 12:33:14 2002
@@ -13,6 +13,7 @@
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/errno.h>
#include <linux/config.h> /* Joliet? */
#include <linux/smp_lock.h>
===== include/asm-i386/pgalloc.h 1.16 vs edited =====
--- 1.16/include/asm-i386/pgalloc.h Thu Jun 6 11:35:04 2002
+++ edited/include/asm-i386/pgalloc.h Thu Jun 6 12:15:09 2002
@@ -6,6 +6,7 @@
#include <asm/fixmap.h>
#include <linux/threads.h>
#include <linux/mm.h> /* for struct page */
+#include <linux/gfp.h>

#define pmd_populate_kernel(mm, pmd, pte) \
set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
===== include/linux/mm.h 1.55 vs edited =====
--- 1.55/include/linux/mm.h Sat May 25 16:25:47 2002
+++ edited/include/linux/mm.h Thu Jun 6 12:15:09 2002
@@ -7,12 +7,8 @@
#ifdef __KERNEL__

#include <linux/config.h>
-#include <linux/gfp.h>
-#include <linux/string.h>
#include <linux/list.h>
-#include <linux/mmzone.h>
#include <linux/swap.h>
-#include <linux/rbtree.h>
#include <linux/fs.h>

extern unsigned long max_mapnr;
===== mm/bootmem.c 1.9 vs edited =====
--- 1.9/mm/bootmem.c Mon Jun 3 08:24:55 2002
+++ edited/mm/bootmem.c Thu Jun 6 12:28:37 2002
@@ -10,6 +10,7 @@
*/

#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/kernel_stat.h>
#include <linux/swap.h>
#include <linux/swapctl.h>
===== mm/numa.c 1.5 vs edited =====
--- 1.5/mm/numa.c Sat May 25 16:25:47 2002
+++ edited/mm/numa.c Thu Jun 6 12:28:35 2002
@@ -4,6 +4,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/mmzone.h>

2002-06-07 17:37:04

by fchabaud

[permalink] [raw]
Subject: Re: [patch] i386 "General Options" - begone [take 2]

Le 5 Jui, Alan Cox a ?crit :
>
> Power Management using
> CPU idling instructions
> APM
> Direct power management
> ACPI

I agree with you that direct power management should be made possible,
because there's nothing preventing a very old i386 without any APM nor
ACPI feature in BIOS to suspend correctly on disk. By the way, in such a
case APM or APCI just disable themselves aren't they ? So IMHO swsusp
should have its own /proc way to activate but that may raise conflict
issues with ACPI states.

--
Florent Chabaud

2002-06-07 19:11:57

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH] Cleanup i386 <linux/init.h> abuses

Hi!

> The following patch cleans up the i386 usage of <linux/init.h>.
> This remove <linux/init.h> from <asm-i386/system.h> which did not need
> it, <asm-i386/highmem.h> which only had it due to an extern using
> __init, which is not needed.
> This adds <linux/init.h> to <asm-i386/bugs.h> which actually has
> numerous __init functions and adds <linux/init.h> to 9 files inside of
> arch/i386 which were indirectly including <linux/init.h> previously.


@@ -33,7 +32,7 @@
extern pgprot_t kmap_prot;
extern pte_t *pkmap_page_table;

-extern void kmap_init(void) __init;
+extern void kmap_init(void);

/*
* Right now we initialize only a single pte table. It can be
extended


__init is usefull as a documentation... Perhaps adding /* This is
__init function */ would be good.
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-06-07 19:20:03

by Thunder from the hill

[permalink] [raw]
Subject: Re: [PATCH] Cleanup i386 <linux/init.h> abuses

Hi,

On Fri, 7 Jun 2002, Pavel Machek wrote:

> Hi!
>
> +extern void kmap_init(void);
>
> __init is usefull as a documentation... Perhaps adding /* This is
> __init function */ would be good.

I suppose that's why it's called kmap_init(). That jumps right on me,
biting my nose and saying "I am an init function".

Regards,
Thunder
--
ship is leaving right on time | Thunder from the hill at ngforever
empty harbour, wave goodbye |
evacuation of the isle | free inhabitant not directly
caveman's paintings drowning | belonging anywhere

2002-06-07 19:27:04

by Tom Rini

[permalink] [raw]
Subject: Re: [PATCH] Cleanup i386 <linux/init.h> abuses

On Fri, Jun 07, 2002 at 01:01:45PM +0200, Pavel Machek wrote:
> Hi!
>
> > The following patch cleans up the i386 usage of <linux/init.h>.
> > This remove <linux/init.h> from <asm-i386/system.h> which did not need
> > it, <asm-i386/highmem.h> which only had it due to an extern using
> > __init, which is not needed.
> > This adds <linux/init.h> to <asm-i386/bugs.h> which actually has
> > numerous __init functions and adds <linux/init.h> to 9 files inside of
> > arch/i386 which were indirectly including <linux/init.h> previously.
>
>
> @@ -33,7 +32,7 @@
> extern pgprot_t kmap_prot;
> extern pte_t *pkmap_page_table;
>
> -extern void kmap_init(void) __init;
> +extern void kmap_init(void);
>
> /*
> * Right now we initialize only a single pte table. It can be
> extended
>
>
> __init is usefull as a documentation... Perhaps adding /* This is
> __init function */ would be good.

The use of __init in externs is done very infrequently right now, and is
probably causing <linux/init.h> to be included in a few more headers
that probably don't need it and thus masking the bugs in some .c files.

I also think it makes very poor documentation right now since it's done
a total of 24 times, and should probably be removed for consistency. Or
left alone since <linux/init.h> mentions you can do it.

But personally, I'm against doing it.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/