http://linux.bkbits.net/linux-2.5
torvalds@ppc970.osdl.org|ChangeSet|20050119173008|18199 torvalds
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/01/19 09:30:08-08:00 torvalds@ppc970.osdl.org 
#   Fix x87 fnsave Tag Word emulation when using FXSR (SSE)
#   
#   From: Roland McGrath <roland@redhat.com>
#   
#   The fxsave instruction does not save the x87 tag word (only the
#   empty bits), and we re-created the old-style x87 tags incorrectly.
#   The registers are saved in "stack order" in the save area, but the
#   tag word bits are in "hardware order", and we need to get the right
#   register state.
#   
#   Both x86 and x86-64 needed this fix.
#   
#   Signed-off-by: Roland McGrath <roland@redhat.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/x86_64/ia32/fpu32.c
#   2005/01/19 09:30:00-08:00 torvalds@ppc970.osdl.org +3 -2
#   Fix x87 fnsave Tag Word emulation when using FXSR (SSE)
# 
# arch/i386/kernel/i387.c
#   2005/01/19 09:30:00-08:00 torvalds@ppc970.osdl.org +3 -2
#   Fix x87 fnsave Tag Word emulation when using FXSR (SSE)
# 
# ChangeSet
#   2005/01/18 13:23:59+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2416/1: S3C2410 - default configuration update
#   
#   Patch from Ben Dooks
#   
#   Update default configuraiton, configure support for the
#   common flash chips seen on 2410 board.
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# arch/arm/configs/s3c2410_defconfig
#   2005/01/18 11:37:19+00:00 ben-linux@org.rmk.(none) +39 -6
#   [PATCH] 2416/1: S3C2410 - default configuration update
# 
# ChangeSet
#   2005/01/18 13:17:26+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2415/1: VR1000 - add platform device for flash
#   
#   Patch from Ben Dooks
#   
#   Add platform device for the onboard site for NOR flash,
#   similar to the Simtec BAST (EB2410ITX)
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# arch/arm/mach-s3c2410/mach-vr1000.c
#   2005/01/18 10:45:30+00:00 ben-linux@org.rmk.(none) +19 -0
#   [PATCH] 2415/1: VR1000 - add platform device for flash
# 
# ChangeSet
#   2005/01/18 13:10:37+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2414/1: VR1000 - add serial platform device
#   
#   Patch from Ben Dooks
#   
#   Serial platfrom device to add ttyS0..ttyS4 to the
#   system.
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# arch/arm/mach-s3c2410/mach-vr1000.c
#   2005/01/18 01:14:04+00:00 ben-linux@org.rmk.(none) +70 -1
#   [PATCH] 2414/1: VR1000 - add serial platform device
# 
# ChangeSet
#   2005/01/18 13:03:07+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2413/1: VR1000 - add serial ports to vr1000-map.h
#   
#   Patch from Ben Dooks
#   
#   Add definition of the extra serial port area to the
#   file include/asm-arm/arch-s3c2410/vr1000-map.h
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# include/asm-arm/arch-s3c2410/vr1000-map.h
#   2005/01/17 12:32:23+00:00 ben-linux@org.rmk.(none) +6 -2
#   [PATCH] 2413/1: VR1000 - add serial ports to vr1000-map.h
# 
# ChangeSet
#   2005/01/18 12:55:04+00:00 dsaxena@net.rmk.(none) 
#   [ARM PATCH] 2412/1: Fix IXP2000 gettimeofday() implementation (again)
#   
#   Patch from Deepak Saxena
#   
#   Previous fixed showed negative time flow every few hours during
#   extensive testing. This new version is much simpler and has been
#   tested w/o any failures.
#   
#   Signed-off-by: Deepak Saxena
#   Signed-off-by: Russell King
# 
# arch/arm/mach-ixp2000/core.c
#   2005/01/18 06:46:41+00:00 dsaxena@net.rmk.(none) +1 -14
#   [PATCH] 2412/1: Fix IXP2000 gettimeofday() implementation (again)
# 
# ChangeSet
#   2005/01/18 00:49:06-05:00 jgarzik@pobox.com 
#   Merge pobox.com:/garz/repo/netdev-2.6/mc-filter
#   into pobox.com:/garz/repo/net-drivers-2.6
# 
# drivers/net/tulip/winbond-840.c
#   2005/01/18 00:49:02-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# drivers/net/tulip/tulip_core.c
#   2005/01/18 00:49:02-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# drivers/net/atp.c
#   2005/01/18 00:49:02-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/18 00:46:36-05:00 jgarzik@pobox.com 
#   Manual merge of s2io.
# 
# drivers/net/s2io.h
#   2005/01/18 00:46:30-05:00 jgarzik@pobox.com +0 -2
#   Manual merge of s2io.
# 
# ChangeSet
#   2005/01/18 00:43:47-05:00 jgarzik@pobox.com 
#   Merge pobox.com:/garz/repo/netdev-2.6/tuntap
#   into pobox.com:/garz/repo/net-drivers-2.6
# 
# drivers/net/tun.c
#   2005/01/18 00:43:41-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# drivers/net/Kconfig
#   2005/01/18 00:43:41-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# drivers/net/s2io.c
#   2005/01/18 00:43:26-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# drivers/net/hamachi.c
#   2005/01/18 00:43:26-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/17 12:31:40-08:00 greg@kroah.com 
#   Merge kroah.com:/home/greg/linux/BK/bleed-2.6
#   into kroah.com:/home/greg/linux/BK/i2c-2.6
# 
# ChangeSet
#   2005/01/17 12:31:30-08:00 greg@kroah.com 
#   Merge kroah.com:/home/greg/linux/BK/bleed-2.6
#   into kroah.com:/home/greg/linux/BK/pci-2.6
# 
# include/linux/pci_ids.h
#   2005/01/17 12:30:42-08:00 greg@kroah.com +0 -0
#   Auto merged
# 
# drivers/i2c/busses/Kconfig
#   2005/01/17 12:30:41-08:00 greg@kroah.com +0 -0
#   Auto merged
# 
# arch/i386/Kconfig
#   2005/01/17 12:30:41-08:00 greg@kroah.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/17 12:20:12-08:00 greg@kroah.com 
#   Merge kroah.com:/home/greg/linux/BK/bleed-2.6
#   into kroah.com:/home/greg/linux/BK/usb-2.6
# 
# drivers/usb/misc/Kconfig
#   2005/01/17 12:20:05-08:00 greg@kroah.com +0 -0
#   Auto merged
# 
# drivers/usb/core/hub.c
#   2005/01/17 12:20:05-08:00 greg@kroah.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/17 12:12:22-08:00 greg@kroah.com 
#   Merge kroah.com:/home/greg/linux/BK/bleed-2.6
#   into kroah.com:/home/greg/linux/BK/w1-2.6
# 
# drivers/w1/w1.c
#   2005/01/17 12:12:15-08:00 greg@kroah.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/17 20:11:25+00:00 rpurdie@net.rmk.(none) 
#   [ARM PATCH] 2406/1: PXA Corgi - Add MMC Support
#   
#   Patch from Richard Purdie
#   
#   Add MMC support to enable the MMC device on the corgi machines
#   (Sharp SL-C7xx). This is a standard PXA implementation except the
#   interrupt needs to be delayed to see card removals.
#   Applies after 2405/1.
#   
#   Signed-off-by: Richard Purdie
#   Signed-off-by: Russell King
# 
# arch/arm/mach-pxa/corgi.c
#   2005/01/17 00:00:00+00:00 rpurdie@net.rmk.(none) +80 -0
#   [PATCH] 2406/1: PXA Corgi - Add MMC Support
# 
# ChangeSet
#   2005/01/17 19:52:39+00:00 rpurdie@net.rmk.(none) 
#   [ARM PATCH] 2405/1: PXA Corgi - Add w100fb device definition
#   
#   Patch from Richard Purdie
#   
#   Add w100fb device definition to enable the framebuffer device on
#   the corgi machines (Sharp SL-C7xx).
#   
#   Signed-off-by: Richard Purdie
#   Signed-off-by: Russell King
# 
# arch/arm/mach-pxa/corgi.c
#   2005/01/17 00:00:00+00:00 rpurdie@net.rmk.(none) +64 -7
#   [PATCH] 2405/1: PXA Corgi - Add w100fb device definition
# 
# ChangeSet
#   2005/01/17 10:06:44-08:00 greg@kroah.com 
#   PCI: move pcie build into the drivers/pci/ subdirectory
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/Makefile
#   2005/01/17 10:06:18-08:00 greg@kroah.com +2 -0
#   PCI: move pcie build into the drivers/pci/ subdirectory
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/Makefile
#   2005/01/17 10:06:18-08:00 greg@kroah.com +0 -1
#   PCI: move pcie build into the drivers/pci/ subdirectory
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2005/01/17 15:04:42+00:00 giorgio@org.rmk.(none) 
#   [ARM PATCH] 2410/1: pxa-regs.h: Complete/fix I2S GPIO modes definitions
#   
#   Patch from Giorgio Padrin
#   
#   Completes/fixes I2S GPIO modes definitions in file pxa-regs.h .
#   Needed by sound drivers using I2S interface; based onofficial microprocessor documentation.
#   
#   Signed-off-by: Giorgio Padrin
#   Signed-off-by: Russell King
# 
# include/asm-arm/arch-pxa/pxa-regs.h
#   2005/01/16 20:56:11+00:00 giorgio@org.rmk.(none) +5 -2
#   [PATCH] 2410/1: pxa-regs.h: Complete/fix I2S GPIO modes definitions
# 
# ChangeSet
#   2005/01/17 14:55:28+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2409/2: BAST - nand slot description
#   
#   Patch from Ben Dooks
#   
#   Add platform device data for the NAND slot and chips
#   on the Simtec BAST (EB2410ITX) for the 3 chips
#   and SmartMedia slot.
#   Note, this does not yet support hot-plug for the
#   SmartMedia slot.
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# arch/arm/mach-s3c2410/mach-bast.c
#   2005/01/17 14:19:02+00:00 ben-linux@org.rmk.(none) +106 -2
#   [PATCH] 2409/2: BAST - nand slot description
# 
# ChangeSet
#   2005/01/17 14:00:59+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2408/1: S3C2410 - dma get position call
#   
#   Patch from Ben Dooks
#   
#   Add call to find out the current source and destination
#   of the given dma channel
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# include/asm-arm/arch-s3c2410/dma.h
#   2005/01/17 00:55:08+00:00 ben-linux@org.rmk.(none) +8 -0
#   [PATCH] 2408/1: S3C2410 - dma get position call
# 
# arch/arm/mach-s3c2410/dma.c
#   2005/01/17 00:55:08+00:00 ben-linux@org.rmk.(none) +23 -0
#   [PATCH] 2408/1: S3C2410 - dma get position call
# 
# ChangeSet
#   2005/01/17 13:54:18+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2407/1: S3C2410 - remove fixed base from IIS registers
#   
#   Patch from Ben Dooks
#   
#   Remove the fixed base address from the IIS registers, and
#   add missing defines for the IISPSR register
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# include/asm-arm/arch-s3c2410/regs-iis.h
#   2005/01/17 00:54:58+00:00 ben-linux@org.rmk.(none) +9 -5
#   [PATCH] 2407/1: S3C2410 - remove fixed base from IIS registers
# 
# ChangeSet
#   2005/01/16 19:54:12-08:00 trond.myklebust@fys.uio.no 
#   [PATCH] RPC: fix crrefresh() operations for AUTH_NULL and AUTH_SYS
#   
#   Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# net/sunrpc/auth_unix.c
#   2005/01/16 16:00:00-08:00 trond.myklebust@fys.uio.no +1 -1
#   RPC: fix crrefresh() operations for AUTH_NULL and AUTH_SYS
# 
# net/sunrpc/auth_null.c
#   2005/01/16 16:00:00-08:00 trond.myklebust@fys.uio.no +2 -1
#   RPC: fix crrefresh() operations for AUTH_NULL and AUTH_SYS
# 
# ChangeSet
#   2005/01/16 19:54:00-08:00 trond.myklebust@fys.uio.no 
#   [PATCH] RPCSEC_GSS: Fix a refcount leak
#   
#   RPC: Fix a module refcount leak in RPCSEC_GSS
#   
#   Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# net/sunrpc/auth_gss/gss_mech_switch.c
#   2005/01/16 16:00:00-08:00 trond.myklebust@fys.uio.no +4 -6
#   RPCSEC_GSS: Fix a refcount leak
# 
# net/sunrpc/auth_gss/auth_gss.c
#   2005/01/16 16:00:00-08:00 trond.myklebust@fys.uio.no +4 -1
#   RPCSEC_GSS: Fix a refcount leak
# 
# ChangeSet
#   2005/01/16 19:53:47-08:00 trond.myklebust@fys.uio.no 
#   [PATCH] Fix an Oopsable condition in the NFS locking
#   
#   Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/nfs/file.c
#   2005/01/16 16:00:00-08:00 trond.myklebust@fys.uio.no +8 -4
#   Fix an Oopsable condition in the NFS locking
# 
# ChangeSet
#   2005/01/16 19:53:34-08:00 trond.myklebust@fys.uio.no 
#   [PATCH] Fix a BKL imbalance in the NFS locking code.
#   
#   Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/nfs/file.c
#   2005/01/16 16:00:00-08:00 trond.myklebust@fys.uio.no +1 -0
#   Fix a BKL imbalance in the NFS locking code.
# 
# ChangeSet
#   2005/01/16 19:32:46+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Fix profile_pc() for SMP
#   
#   profile_pc() used thread_saved_fp() with the current task.  However,
#   thread_saved_fp() only returns sane values when called for threads
#   which are presently sleeping, so this caused an oops.  Instead, use
#   regs->ARM_fp, which correspond with the frame pointer.
# 
# arch/arm/kernel/time.c
#   2005/01/16 19:28:31+00:00 rmk@flint.arm.linux.org.uk +1 -1
#   thread_saved_fp() is not valid for the current thread; use
#   regs->ARM_fp instead.
# 
# ChangeSet
#   2005/01/16 11:21:00-08:00 pluto@pld-linux.org 
#   [PATCH] final csum_and_copy_from_user gcc4 warning fixes
#   
#   The build is clean now.
# 
# include/asm-i386/checksum.h
#   2005/01/16 03:58:42-08:00 pluto@pld-linux.org +2 -2
#   final csum_and_copy_from_user gcc4 warning fixes
# 
# ChangeSet
#   2005/01/16 10:09:59-08:00 roland@redhat.com 
#   [PATCH] x86_64: fix crash on get_user_pages of ia32 vsyscall page before it's faulted in
#   
#   God invented symbolic names to help you.  Repeating magic constants by hand
#   is begging to lose, especially when you get them wrong.  Don't be a loser.
#   
#   [ Editor's hint: 0xfffe000 vs 0xffffe000 ]
#   
#   Signed-off-by: Roland McGrath <roland@redhat.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/x86_64/mm/init.c
#   2005/01/15 16:00:00-08:00 roland@redhat.com +1 -1
#   x86_64: fix crash on get_user_pages of ia32 vsyscall page before it's faulted in
# 
# arch/x86_64/mm/fault.c
#   2005/01/15 16:00:00-08:00 roland@redhat.com +1 -1
#   x86_64: fix crash on get_user_pages of ia32 vsyscall page before it's faulted in
# 
# ChangeSet
#   2005/01/16 09:45:25-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: Remove unused file
#   
#   Remove unreferenced file
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Grant Grundler <grundler@parisc-linux.org>
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# BitKeeper/deleted/.del-bootdata.h~3876cf5254aef18e
#   2005/01/16 09:45:18-08:00 matthew@wil.cx +0 -0
#   Delete: include/asm-parisc/bootdata.h
# 
# ChangeSet
#   2005/01/16 09:45:12-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: Sort out io accessors
#   
#    - sparse annotations for ioremap/iounmap (Randolph Chung)
#    - Turn gsc_readb, __raw_readb and readb functions into static inline
#      functions (Matthew Wilcox)
#    - Document the difference between the gsc_readb, __raw_readb and readb
#      families of functions (Matthew Wilcox)
#    - Add a debugging option to determine when they are being used incorrectly
#      (Matthew Wilcox)
#    - Make memcpy_fromio's second argument const (Matthew Wilcox)
#   
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# lib/Kconfig.debug
#   2005/01/12 12:10:42-08:00 matthew@wil.cx +13 -0
#   PA-RISC: Sort out io accessors
# 
# include/asm-parisc/io.h
#   2005/01/12 12:03:32-08:00 matthew@wil.cx +187 -92
#   PA-RISC: Sort out io accessors
# 
# arch/parisc/mm/ioremap.c
#   2005/01/12 11:59:26-08:00 matthew@wil.cx +34 -5
#   PA-RISC: Sort out io accessors
# 
# arch/parisc/lib/io.c
#   2005/01/12 11:59:26-08:00 matthew@wil.cx +29 -29
#   PA-RISC: Sort out io accessors
# 
# arch/parisc/kernel/parisc_ksyms.c
#   2005/01/12 11:59:23-08:00 matthew@wil.cx +3 -3
#   PA-RISC: Sort out io accessors
# 
# ChangeSet
#   2005/01/16 09:44:57-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: Fix _syscallN wrappers
#   
#   Fix _syscallN wrappers (Mike Frysinger)
#   
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-parisc/unistd.h
#   2005/01/12 12:03:35-08:00 matthew@wil.cx +1 -1
#   PA-RISC: Fix _syscallN wrappers
# 
# ChangeSet
#   2005/01/16 09:44:44-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: ptrace fix
#   
#   Fix ptrace(SINGLESTEP) through system call
#   
#   Signed-off-by: Randolph Chung <tausq@parisc-linux.org>
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-parisc/ptrace.h
#   2005/01/12 12:03:34-08:00 matthew@wil.cx +1 -1
#   PA-RISC: ptrace fix
# 
# arch/parisc/kernel/ptrace.c
#   2005/01/12 11:59:24-08:00 matthew@wil.cx +23 -22
#   PA-RISC: ptrace fix
# 
# ChangeSet
#   2005/01/16 09:44:30-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: Remove unused serial definitions
#   
#   Remove some unused definitions
#   
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-parisc/serial.h
#   2005/01/12 12:03:35-08:00 matthew@wil.cx +0 -15
#   PA-RISC: Remove unused serial definitions
# 
# ChangeSet
#   2005/01/16 09:44:17-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: More PDC procedures
#   
#   Add PDC Stable Storage wrappers (Thibaut Varene)
#   Rewrite PDC Initiator (Matthew Wilcox)
#   
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-parisc/pdc.h
#   2005/01/12 12:03:34-08:00 matthew@wil.cx +14 -1
#   PA-RISC: More PDC procedures
# 
# arch/parisc/kernel/firmware.c
#   2005/01/12 11:59:22-08:00 matthew@wil.cx +133 -35
#   PA-RISC: More PDC procedures
# 
# ChangeSet
#   2005/01/16 09:44:03-08:00 matthew@wil.cx 
#   [PATCH] iomap for PA-RISC
#   
#   Implement the iomap interfaces on PA-RISC
#   
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-parisc/io.h
#   2005/01/12 12:03:32-08:00 matthew@wil.cx +2 -0
#   iomap for PA-RISC
# 
# arch/parisc/lib/iomap.c
#   2005/01/10 06:00:46-08:00 matthew@wil.cx +422 -0
#   iomap for PA-RISC
# 
# arch/parisc/lib/Makefile
#   2005/01/12 11:59:25-08:00 matthew@wil.cx +2 -0
#   iomap for PA-RISC
# 
# arch/parisc/lib/iomap.c
#   2005/01/10 06:00:46-08:00 matthew@wil.cx +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/arch/parisc/lib/iomap.c
# 
# ChangeSet
#   2005/01/16 09:43:50-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: Misc HPUX emulation cleanups
#   
#    - Remove declaration of sys_setpgid
#    - __user annotations
#    - Rewrite hpux_statfs
#    - Add hpux_fstatfs
#   
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/parisc/hpux/sys_hpux.c
#   2005/01/12 11:59:22-08:00 matthew@wil.cx +57 -32
#   PA-RISC: Misc HPUX emulation cleanups
# 
# arch/parisc/hpux/entry_hpux.S
#   2005/01/12 11:59:22-08:00 matthew@wil.cx +1 -1
#   PA-RISC: Misc HPUX emulation cleanups
# 
# ChangeSet
#   2005/01/16 09:43:36-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: Misc Dino fixes
#   
#    - Removes the hardware path from /proc/interrupts for Dino to make
#      it consistant with the rest of /proc/interrupts
#   Signed-off-by: Ryan Bradetich
#   
#    - Remove iomem related warnings from dino.c
#   Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
#   
#    - Convert SPIN_LOCK_UNLOCKED to spin_lock_init (Thomas Gleixner)
#   Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#   Acked-by: Ingo Molnar <mingo@elte.hu>
#   
#   Signed-off-by: Matthew Wilcox
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/parisc/dino.c
#   2005/01/12 12:01:48-08:00 matthew@wil.cx +51 -60
#   PA-RISC: Misc Dino fixes
# 
# ChangeSet
#   2005/01/16 09:43:23-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC defconfig updates
#   
#   Defconfig updates from Grant Grundler and Paul Bame
#   
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/parisc/configs/n4000_defconfig
#   2005/01/12 11:59:22-08:00 matthew@wil.cx +96 -73
#   PA-RISC defconfig updates
# 
# arch/parisc/configs/c3000_defconfig
#   2005/01/12 11:59:22-08:00 matthew@wil.cx +115 -71
#   PA-RISC defconfig updates
# 
# arch/parisc/configs/b180_defconfig
#   2005/01/12 11:59:21-08:00 matthew@wil.cx +62 -15
#   PA-RISC defconfig updates
# 
# arch/parisc/configs/a500_defconfig
#   2005/01/12 11:59:21-08:00 matthew@wil.cx +101 -45
#   PA-RISC defconfig updates
# 
# arch/parisc/configs/712_defconfig
#   2005/01/12 11:59:21-08:00 matthew@wil.cx +421 -173
#   PA-RISC defconfig updates
# 
# ChangeSet
#   2005/01/16 09:43:10-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC: parisc_device diet
#   
#    - Remove parent/child/sibling links from parisc_device in favour of the
#      ones in the embedded struct device.
#    - Display irq and device IDs through sysfs
#    - Translate a PA-RISC firmware path into a struct device (Thibaut Varene)
#   
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-parisc/parisc-device.h
#   2005/01/12 12:03:33-08:00 matthew@wil.cx +13 -4
#   PA-RISC: parisc_device diet
# 
# include/asm-parisc/hardware.h
#   2005/01/12 12:03:32-08:00 matthew@wil.cx +2 -3
#   PA-RISC: parisc_device diet
# 
# drivers/serial/8250_gsc.c
#   2005/01/12 12:02:16-08:00 matthew@wil.cx +4 -4
#   PA-RISC: parisc_device diet
# 
# drivers/parisc/dino.c
#   2005/01/12 12:01:48-08:00 matthew@wil.cx +2 -2
#   PA-RISC: parisc_device diet
# 
# drivers/parisc/ccio-dma.c
#   2005/01/12 12:01:48-08:00 matthew@wil.cx +6 -2
#   PA-RISC: parisc_device diet
# 
# arch/parisc/kernel/inventory.c
#   2005/01/12 11:59:23-08:00 matthew@wil.cx +7 -6
#   PA-RISC: parisc_device diet
# 
# arch/parisc/kernel/drivers.c
#   2005/01/12 11:59:22-08:00 matthew@wil.cx +251 -153
#   PA-RISC: parisc_device diet
# 
# ChangeSet
#   2005/01/16 09:42:56-08:00 matthew@wil.cx 
#   [PATCH] PA-RISC Cache flush optimisation
#   
#   Cache flush optimization for UP/SMP; remove hardcoded threshold
#   for selecting whole cache vs region flush
#   
#   From: Randolph Chung <tausq@parisc-linux.org>
#   Signed-off-by: Matthew Wilcox <willy@parisc-linux.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-parisc/cacheflush.h
#   2004/12/24 15:40:22-08:00 matthew@wil.cx +4 -15
#   PA-RISC Cache flush optimisation
# 
# include/asm-parisc/cache.h
#   2004/12/24 15:40:22-08:00 matthew@wil.cx +1 -0
#   PA-RISC Cache flush optimisation
# 
# arch/parisc/kernel/setup.c
#   2005/01/09 17:06:54-08:00 matthew@wil.cx +2 -0
#   PA-RISC Cache flush optimisation
# 
# arch/parisc/kernel/cache.c
#   2004/12/24 15:39:29-08:00 matthew@wil.cx +37 -0
#   PA-RISC Cache flush optimisation
# 
# ChangeSet
#   2005/01/15 16:09:15-08:00 matthew@wil.cx 
#   [PATCH] Generic IRQ support for PA-RISC
#   
#   Make PA-RISC use the generic interrupt handling code.  We need one tiny
#   change to the generic code -- the addition of a data pointer to irq_desc.
#   This shouldn't be a problem in terms of increasing size of irq_desc for
#   other architectures as the struct is cacheline aligned.  It's now 32
#   bytes on 32-bit platforms and 44/48 bytes on 64-bit platforms (assuming
#   spinlock_t is 4 bytes on 32-bit and 4 or 8 bytes on 64-bit).
#   
#   Signed-off-by: Matthew Wilcox <matthew@wil.cx>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/irq.h
#   2005/01/12 12:03:54-08:00 matthew@wil.cx +2 -1
#   Generic IRQ support for PA-RISC
# 
# include/asm-parisc/superio.h
#   2005/01/12 12:03:35-08:00 matthew@wil.cx +0 -6
#   Generic IRQ support for PA-RISC
# 
# include/asm-parisc/irq.h
#   2005/01/12 12:03:33-08:00 matthew@wil.cx +23 -72
#   Generic IRQ support for PA-RISC
# 
# include/asm-parisc/hw_irq.h
#   2005/01/12 12:03:32-08:00 matthew@wil.cx +1 -1
#   Generic IRQ support for PA-RISC
# 
# include/asm-parisc/hardirq.h
#   2005/01/12 12:09:39-08:00 matthew@wil.cx +5 -2
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/wax.c
#   2005/01/12 12:01:50-08:00 matthew@wil.cx +23 -25
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/superio.c
#   2005/01/12 12:01:50-08:00 matthew@wil.cx +36 -71
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/lba_pci.c
#   2005/01/12 12:01:49-08:00 matthew@wil.cx +0 -2
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/lasi.c
#   2005/01/12 12:01:49-08:00 matthew@wil.cx +26 -32
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/iosapic_private.h
#   2005/01/12 12:01:49-08:00 matthew@wil.cx +8 -11
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/iosapic.c
#   2005/01/12 12:01:49-08:00 matthew@wil.cx +167 -267
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/gsc.h
#   2005/01/12 12:01:49-08:00 matthew@wil.cx +11 -10
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/gsc.c
#   2005/01/12 12:01:49-08:00 matthew@wil.cx +103 -79
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/eisa.c
#   2005/01/12 12:01:49-08:00 matthew@wil.cx +27 -51
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/dino.c
#   2005/01/12 12:01:48-08:00 matthew@wil.cx +80 -103
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/asp.c
#   2005/01/12 12:01:48-08:00 matthew@wil.cx +30 -31
#   Generic IRQ support for PA-RISC
# 
# drivers/parisc/Makefile
#   2005/01/12 12:01:48-08:00 matthew@wil.cx +1 -6
#   Generic IRQ support for PA-RISC
# 
# arch/parisc/kernel/smp.c
#   2005/01/12 11:59:24-08:00 matthew@wil.cx +2 -2
#   Generic IRQ support for PA-RISC
# 
# arch/parisc/kernel/irq.c
#   2005/01/12 11:59:23-08:00 matthew@wil.cx +98 -606
#   Generic IRQ support for PA-RISC
# 
# arch/parisc/Kconfig
#   2005/01/12 11:59:21-08:00 matthew@wil.cx +6 -0
#   Generic IRQ support for PA-RISC
# 
# ChangeSet
#   2005/01/15 15:47:14-08:00 vlobanov@speakeasy.net 
#   [PATCH] Fix typo in drivers/char/Kconfig
#   
#   Signed-off-by: Vadim Lobanov <vlobanov@speakeasy.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/char/Kconfig
#   2005/01/15 14:31:07-08:00 vlobanov@speakeasy.net +2 -2
#   Fix typo in drivers/char/Kconfig
# 
# ChangeSet
#   2005/01/15 15:46:55-08:00 gaboregry@axelero.hu 
#   [PATCH] various Kconfig fixes
#   
#   Here are some Kconfig fixes:
#   
#   - typo fixes
#   - unused token removes (empty or duplicated  'help')
#   - non ASCII characters replaces
#   - e-mail address and URL format corrections
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# sound/pci/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +3 -3
#   various Kconfig fixes
# 
# sound/oss/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +3 -3
#   various Kconfig fixes
# 
# security/selinux/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# security/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# net/irda/irnet/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# net/ipv6/netfilter/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +0 -1
#   various Kconfig fixes
# 
# net/ipv4/netfilter/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +8 -9
#   various Kconfig fixes
# 
# net/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# kernel/power/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# fs/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +6 -6
#   various Kconfig fixes
# 
# drivers/video/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +3 -3
#   various Kconfig fixes
# 
# drivers/usb/storage/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/usb/misc/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +0 -1
#   various Kconfig fixes
# 
# drivers/usb/input/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# drivers/serial/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -3
#   various Kconfig fixes
# 
# drivers/scsi/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +3 -3
#   various Kconfig fixes
# 
# drivers/s390/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/pnp/pnpbios/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/pci/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/net/wireless/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/net/wan/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# drivers/net/arcnet/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/net/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +9 -9
#   various Kconfig fixes
# 
# drivers/mtd/maps/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# drivers/misc/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/media/dvb/dibusb/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# drivers/md/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/isdn/tpam/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/isdn/i4l/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/input/mouse/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +3 -3
#   various Kconfig fixes
# 
# drivers/input/misc/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +0 -1
#   various Kconfig fixes
# 
# drivers/input/joystick/iforce/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -1
#   various Kconfig fixes
# 
# drivers/input/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/i2c/busses/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -4
#   various Kconfig fixes
# 
# drivers/firmware/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# drivers/char/ipmi/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/cdrom/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/block/paride/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# drivers/block/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# drivers/acpi/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +3 -3
#   various Kconfig fixes
# 
# crypto/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +9 -9
#   various Kconfig fixes
# 
# arch/um/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# arch/sh/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +4 -4
#   various Kconfig fixes
# 
# arch/ppc64/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# arch/ppc/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# arch/ppc/8xx_io/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# arch/m68k/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# arch/i386/kernel/cpu/cpufreq/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# arch/i386/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +0 -1
#   various Kconfig fixes
# 
# arch/cris/arch-v10/drivers/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# arch/arm26/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +0 -1
#   various Kconfig fixes
# 
# arch/arm/mm/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# arch/arm/mach-s3c2410/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +4 -4
#   various Kconfig fixes
# 
# arch/arm/mach-ixp4xx/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +6 -6
#   various Kconfig fixes
# 
# arch/arm/mach-ixp2000/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +5 -5
#   various Kconfig fixes
# 
# arch/arm/mach-footbridge/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +1 -1
#   various Kconfig fixes
# 
# arch/arm/Kconfig
#   2005/01/15 14:31:06-08:00 gaboregry@axelero.hu +2 -2
#   various Kconfig fixes
# 
# ChangeSet
#   2005/01/15 15:46:37-08:00 mpm@selenic.com 
#   [PATCH] random: add_input_randomness
#   
#   The input layer wants to send us an entropy event per input event and who are
#   we to argue?  Create add_input_randomness with an input-friendly interface and
#   kill the remaining two keyboard and mouse sources.
#   
#   This eliminates lots of duplicate entropy events while covering all the input
#   bases nicely.  We now get two events per keystroke as we should, one down and
#   one up.
#   
#   Signed-off-by: Matt Mackall <mpm@selenic.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/random.h
#   2005/01/15 14:31:06-08:00 mpm@selenic.com +2 -2
#   random: add_input_randomness
# 
# drivers/input/input.c
#   2005/01/15 14:31:06-08:00 mpm@selenic.com +1 -1
#   random: add_input_randomness
# 
# drivers/char/random.c
#   2005/01/15 14:31:06-08:00 mpm@selenic.com +17 -26
#   random: add_input_randomness
# 
# drivers/char/qtronix.c
#   2005/01/15 14:31:06-08:00 mpm@selenic.com +0 -2
#   random: add_input_randomness
# 
# drivers/char/keyboard.c
#   2005/01/15 14:31:06-08:00 mpm@selenic.com +0 -4
#   random: add_input_randomness
# 
# ChangeSet
#   2005/01/15 15:46:21-08:00 mpm@selenic.com 
#   [PATCH] random: periodicity detection fix
#   
#   The input layer is now sending us a bunch of events in a row for each actual
#   event.  This shows up weaknesses in the periodicity detector and using the
#   high clock rate from get_clock: each keystroke is getting accounted as 10
#   different maximal-entropy events.
#   
#   A brief touch on a trackpad will generate as much as 2000 maximal entropy
#   events which is more than 2k of /dev/random output.  IOW, we're WAY
#   overestimating input entropy.  Here's one keystroke:
#   
#   random 0024 0000 0000: mouse event
#   random 0035 0000 0000: added 11 entropy credits to input
#   random 0035 0000 0000: mouse event
#   random 0046 0000 0000: added 11 entropy credits to input
#   random 0046 0000 0000: mouse event
#   random 0056 0000 0000: added 10 entropy credits to input
#   random 0056 0000 0000: keyboard event
#   random 0067 0000 0000: added 11 entropy credits to input
#   random 0067 0000 0000: mouse event
#   random 0078 0000 0000: added 11 entropy credits to input
#   random 0078 0000 0000: awake
#   random 0078 0000 0000: reading 128 bits
#   random 0078 0000 0000: going to reseed blocking with 128 bits (128 of 0 requested)
#   random 0078 0000 0000: trying to extract 128 bits from input
#   random 0006 0000 0000: debiting 72 entropy credits from input
#   random 0006 0072 0000: added 72 entropy credits to blocking
#   random 0006 0072 0000: trying to extract 128 bits from blocking
#   random 0006 0000 0000: debiting 72 entropy credits from blocking
#   random 0006 0000 0000: read got 72 bits (56 still needed)
#   random 0006 0000 0000: reading 56 bits
#   random 0006 0000 0000: going to reseed blocking with 64 bits (56 of 0 requested
#   random 0006 0000 0000: trying to extract 64 bits from input
#   random 0006 0000 0000: debiting 0 entropy credits from input
#   random 0006 0000 0000: trying to extract 56 bits from blocking
#   random 0006 0000 0000: debiting 0 entropy credits from blocking
#   random 0006 0000 0000: read got 0 bits (56 still needed)
#   random 0006 0000 0000: sleeping
#   random 0006 0000 0000: mouse event
#   random 0017 0000 0000: added 11 entropy credits to input
#   random 0017 0000 0000: mouse event
#   random 0028 0000 0000: added 11 entropy credits to input
#   random 0028 0000 0000: mouse event
#   random 0038 0000 0000: added 10 entropy credits to input
#   random 0038 0000 0000: keyboard event
#   random 0049 0000 0000: added 11 entropy credits to input
#   random 0049 0000 0000: mouse event
#   random 0060 0000 0000: added 11 entropy credits to input
#   
#   The first step to fixing this is to check periodicity and estimate entropy
#   against a slow clock like jiffies.  We continue to mix in get_clock() rather
#   than jiffies where available.
#   
#   This throws away most of the duplicate events and gives us more sensible
#   entropy estimates, but we still duplicates from input.c and keyboard.c.
#   
#   Signed-off-by: Matt Mackall <mpm@selenic.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/char/random.c
#   2005/01/15 14:47:07-08:00 mpm@selenic.com +16 -13
#   random: periodicity detection fix
# 
# ChangeSet
#   2005/01/15 15:46:04-08:00 mpm@selenic.com 
#   [PATCH] random: run-time configurable debugging
#   
#   Add run-time switchable entropy debugging.  Entire debug infrastructure
#   remains compiled out by default.
#   
#   Signed-off-by: Matt Mackall <mpm@selenic.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/char/random.c
#   2005/01/15 14:47:07-08:00 mpm@selenic.com +5 -2
#   random: run-time configurable debugging
# 
# ChangeSet
#   2005/01/15 15:45:47-08:00 mpm@selenic.com 
#   [PATCH] random: entropy debugging improvements
#   
#   Print pool entropy counts in all entropy debugging messages
#   
#   Signed-off-by: Matt Mackall <mpm@selenic.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/char/random.c
#   2005/01/15 14:47:07-08:00 mpm@selenic.com +18 -34
#   random: entropy debugging improvements
# 
# ChangeSet
#   2005/01/15 15:45:30-08:00 mpm@selenic.com 
#   [PATCH] random: whitespace doh
#   
#   Someone actually spotted this already.
#   
#   Signed-off-by: Matt Mackall <mpm@selenic.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/char/random.c
#   2005/01/15 14:47:07-08:00 mpm@selenic.com +1 -1
#   random: whitespace doh
# 
# ChangeSet
#   2005/01/15 15:45:11-08:00 vlobanov@speakeasy.net 
#   [PATCH] Fix typo in arch/i386/Kconfig
#   
#   Signed-off-by: Vadim Lobanov <vlobanov@speakeasy.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/i386/Kconfig
#   2005/01/15 14:47:06-08:00 vlobanov@speakeasy.net +1 -1
#   Fix typo in arch/i386/Kconfig
# 
# ChangeSet
#   2005/01/15 15:44:54-08:00 adaplas@hotpop.com 
#   [PATCH] fbdev: Add w100 framebuffer driver
#   
#   Add a framebuffer driver for the ATI w100 as found on several Sharp PDAs
#   
#   Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/video/w100fb.h
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +21 -0
#   fbdev: Add w100 framebuffer driver
# 
# drivers/video/w100fb.h
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +615 -0
#   fbdev: Add w100 framebuffer driver
# 
# include/video/w100fb.h
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/include/video/w100fb.h
# 
# drivers/video/w100fb.h
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/video/w100fb.h
# 
# drivers/video/w100fb.c
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +1864 -0
#   fbdev: Add w100 framebuffer driver
# 
# drivers/video/Makefile
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +1 -0
#   fbdev: Add w100 framebuffer driver
# 
# drivers/video/Kconfig
#   2005/01/15 14:47:06-08:00 adaplas@hotpop.com +13 -0
#   fbdev: Add w100 framebuffer driver
# 
# drivers/video/w100fb.c
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/video/w100fb.c
# 
# ChangeSet
#   2005/01/15 15:44:37-08:00 adaplas@hotpop.com 
#   [PATCH] backlight: Add Backlight/LCD device basic support
#   
#   From: Andrew Zabolotny
#   
#   Here's a patch that adds basic support for controlling backlight lamps and lcd
#   panels.  The drivers can be controlled via sysfs, which makes it easy to use
#   both from scripts and programs.
#   
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/lcd.h
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +56 -0
#   backlight: Add Backlight/LCD device basic support
# 
# include/linux/backlight.h
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +57 -0
#   backlight: Add Backlight/LCD device basic support
# 
# drivers/video/backlight/lcd.c
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +263 -0
#   backlight: Add Backlight/LCD device basic support
# 
# drivers/video/backlight/Makefile
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +4 -0
#   backlight: Add Backlight/LCD device basic support
# 
# drivers/video/backlight/Kconfig
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +41 -0
#   backlight: Add Backlight/LCD device basic support
# 
# include/linux/lcd.h
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/include/linux/lcd.h
# 
# include/linux/backlight.h
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/include/linux/backlight.h
# 
# drivers/video/backlight/lcd.c
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/video/backlight/lcd.c
# 
# drivers/video/backlight/backlight.c
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +264 -0
#   backlight: Add Backlight/LCD device basic support
# 
# drivers/video/backlight/Makefile
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/video/backlight/Makefile
# 
# drivers/video/backlight/Kconfig
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/video/backlight/Kconfig
# 
# drivers/video/Makefile
#   2005/01/15 14:47:08-08:00 adaplas@hotpop.com +1 -0
#   backlight: Add Backlight/LCD device basic support
# 
# drivers/video/Kconfig
#   2005/01/15 14:47:08-08:00 adaplas@hotpop.com +4 -0
#   backlight: Add Backlight/LCD device basic support
# 
# drivers/video/backlight/backlight.c
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/video/backlight/backlight.c
# 
# ChangeSet
#   2005/01/15 15:44:21-08:00 adaplas@hotpop.com 
#   [PATCH] sa1100fb: Reorder add_wait_queue() and set_current_state()
#   
#   Reorder add_wait_queue() and set_current_state() as a signal could be lost in
#   between the two functions.
#   
#   Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/sa1100fb.c
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +1 -1
#   sa1100fb: Reorder add_wait_queue() and set_current_state()
# 
# ChangeSet
#   2005/01/15 15:44:05-08:00 adaplas@hotpop.com 
#   [PATCH] pxafb: Reorder add_wait_queue() and set_current_state()
#   
#   Reorder set_current_state() and add_wait_queue().  There is a chance that a
#   signal could be missed in between the two functions currently.
#   
#   Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/pxafb.c
#   2005/01/15 14:31:05-08:00 adaplas@hotpop.com +1 -1
#   pxafb: Reorder add_wait_queue() and set_current_state()
# 
# ChangeSet
#   2005/01/15 15:43:47-08:00 adaplas@hotpop.com 
#   [PATCH] radeonfb: Fix init/exit section usage
#   
#     Fix 3 instances of calling exit section function from text or init:
#     Error: ./drivers/video/aty/radeon_base.o .text refers to 000029e5
#     R_386_PC32        .exit.text
#     Error: ./drivers/video/aty/radeon_base.o .text refers to 00002a60
#     R_386_PC32        .exit.text
#     Error: ./drivers/video/aty/radeon_base.o .init.text refers to 00000192
#     R_386_PC32        .exit.text
#   
#   Signed-off-by: Randy Dunlap <rddunlap@osdl.org>
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/aty/radeon_base.c
#   2005/01/15 14:31:04-08:00 adaplas@hotpop.com +1 -1
#   radeonfb: Fix init/exit section usage
# 
# ChangeSet
#   2005/01/15 15:43:30-08:00 adaplas@hotpop.com 
#   [PATCH] atyfb: Fix module parameter descriptions
#   
#   This patch syncs up the module parameter descriptions in aty128fb for module
#   parameters "mode_option" and "nomtrr".  Without the patch bad parameter names
#   are used with MODULE_PARM_DESC().
#   
#   Signed-off-by: Magnus Damm <damm@opensource.se>
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/aty/aty128fb.c
#   2005/01/15 14:31:04-08:00 adaplas@hotpop.com +2 -2
#   atyfb: Fix module parameter descriptions
# 
# ChangeSet
#   2005/01/15 15:43:13-08:00 adaplas@hotpop.com 
#   [PATCH] i810fb: Module param fix
#   
#   Last parameter is file permition in sysfs, not default value.  (If 0, file is
#   not accessible trough sysfs, and that's what i did.)
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/i810/i810_main.c
#   2005/01/15 14:31:04-08:00 adaplas@hotpop.com +5 -5
#   i810fb: Module param fix
# 
# ChangeSet
#   2005/01/15 15:42:55-08:00 adaplas@hotpop.com 
#   [PATCH] fbdev: Fbmon cleanup
#   
#   While browsing the video/fbcon.c source file (Linux 2.6.10-rc3) I found some
#   possible cleanups.  Patch follows, feel free to apply all or parts of it if it
#   looks OK to you.
#   
#   Remove unnecessary bit operations.
#   
#   Signed-off-by: Jean Delvare <khali@linux-fr.org>
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/fbmon.c
#   2005/01/15 14:31:04-08:00 adaplas@hotpop.com +2 -5
#   fbdev: Fbmon cleanup
# 
# ChangeSet
#   2005/01/15 15:42:40-08:00 adaplas@hotpop.com 
#   [PATCH] fbcon: Fix compile error
#   
#   Fix missing symbol (fb_con)
#   
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/console/fbcon.h
#   2005/01/15 14:31:04-08:00 adaplas@hotpop.com +3 -0
#   fbcon: Fix compile error
# 
# ChangeSet
#   2005/01/15 15:42:22-08:00 adaplas@hotpop.com 
#   [PATCH] fbcon: Catch blank events on both device and console level
#   
#   Call fb_blank() instead of info->fbops->fb_blank() to capture events on both
#   device and console level.
#   
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/console/fbcon.c
#   2005/01/15 14:31:04-08:00 adaplas@hotpop.com +8 -11
#   fbcon: Catch blank events on both device and console level
# 
# ChangeSet
#   2005/01/15 15:42:05-08:00 adaplas@hotpop.com 
#   [PATCH] fbdev: Cleanup broken edid fixup code
#   
#   Check first if EDID block came from a broken display before fixing.
#   
#   Signed-off-by: Antonino Daplas <adaplas@pol.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/fbmon.c
#   2005/01/15 14:47:09-08:00 adaplas@hotpop.com +46 -23
#   fbdev: Cleanup broken edid fixup code
# 
# ChangeSet
#   2005/01/15 15:41:49-08:00 mgreer@mvista.com 
#   [PATCH] serial: MPSC driver
#   
#   Patch for the Marvell MultiProtocol Serial Controller (MPSC).  This ctlr is
#   on a series of host bridges (and other things) for PPC and MIPS processors.
#   
#   The ctlr operates similar to a typical network controller with send and
#   receive rings.  Unfortunately there are many errata so you will see some
#   "unusual" things in the code.  For example: a) An erratum prevents the
#   reading of several registers on the ctlr (writing is okay).  To work around
#   that, a local copy of what the registers are is kept and special macros are
#   used to access those mirrored values.  b) Another erratum says that the
#   MPSC cannot be used to access cache coherent memory (and many of the
#   systems I use are cache coherent).  However, it seems to work okay as long
#   as there are no snoop hits so there are macros in the code to manually
#   manage the caches to prevent snoop hits.  Each macro checks a flag to see
#   if the manual cache mgmt is necessary as not all versions have the erratum.
#   
#   The driver seems to work well but more testing is needed and it is lacking
#   KGDB support.  I will get to both of those in time.
#   
#   Signed-off-by: Mark A. Greer <mgreer@mvista.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/serial/mpsc_defs.h
#   2005/01/15 14:31:04-08:00 mgreer@mvista.com +146 -0
#   serial: MPSC driver
# 
# drivers/serial/mpsc.h
#   2005/01/15 14:31:04-08:00 mgreer@mvista.com +289 -0
#   serial: MPSC driver
# 
# include/linux/serial_core.h
#   2005/01/15 14:31:04-08:00 mgreer@mvista.com +3 -0
#   serial: MPSC driver
# 
# drivers/serial/mpsc_defs.h
#   2005/01/15 14:31:04-08:00 mgreer@mvista.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/serial/mpsc_defs.h
# 
# drivers/serial/mpsc.h
#   2005/01/15 14:31:04-08:00 mgreer@mvista.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/serial/mpsc.h
# 
# drivers/serial/mpsc.c
#   2005/01/15 14:31:04-08:00 mgreer@mvista.com +1674 -0
#   serial: MPSC driver
# 
# drivers/serial/Makefile
#   2005/01/15 14:31:04-08:00 mgreer@mvista.com +2 -1
#   serial: MPSC driver
# 
# drivers/serial/Kconfig
#   2005/01/15 14:47:06-08:00 mgreer@mvista.com +14 -0
#   serial: MPSC driver
# 
# drivers/serial/mpsc.c
#   2005/01/15 14:31:04-08:00 mgreer@mvista.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/serial/mpsc.c
# 
# ChangeSet
#   2005/01/15 15:41:33-08:00 linux@dominikbrodowski.de 
#   [PATCH] pcmcia: remove #includes in rsrc_mgr which aren't necessary any longer
#   
#   Remove #includes in rsrc_mgr which are no longer needed.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/pcmcia/rsrc_mgr.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +1 -14
#   pcmcia: remove #includes in rsrc_mgr which aren't necessary any longer
# 
# ChangeSet
#   2005/01/15 15:41:18-08:00 linux@dominikbrodowski.de 
#   [PATCH] pcmcia: modify irq_mask via sysfs
#   
#   Allow to modify the per-socket irq_mask via sysfs.  Note that you can only
#   clear bits from the mask, but not re-add bits.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/pcmcia/socket_sysfs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +28 -0
#   pcmcia: modify irq_mask via sysfs
# 
# ChangeSet
#   2005/01/15 15:41:01-08:00 linux@dominikbrodowski.de 
#   [PATCH] pcmcia: remove racy try_irq()
#   
#   Remove the racy try_irq/check_irq/undo_irq interface, and try to register the
#   correct handler directly in pcmcia_request_irq().  Also, simplify the IRQ
#   usage database, but avoid using the same IRQ twice.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/pcmcia/rsrc_mgr.c
#   2005/01/15 14:47:10-08:00 linux@dominikbrodowski.de +1 -117
#   pcmcia: remove racy try_irq()
# 
# drivers/pcmcia/cs_internal.h
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +0 -2
#   pcmcia: remove racy try_irq()
# 
# drivers/pcmcia/cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +83 -48
#   pcmcia: remove racy try_irq()
# 
# ChangeSet
#   2005/01/15 15:40:43-08:00 linux@dominikbrodowski.de 
#   [PATCH] pcmcia: use irq_mask to mark IRQs as (un)usable
#   
#   Unset bits in the per-socket irq_mask to mark IRQs as unusable, if asked to do
#   so by the user in /etc/pcmcia/config.opts
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/pcmcia/rsrc_mgr.c
#   2005/01/15 14:47:10-08:00 linux@dominikbrodowski.de +35 -49
#   pcmcia: use irq_mask to mark IRQs as (un)usable
# 
# ChangeSet
#   2005/01/15 15:40:28-08:00 linux@dominikbrodowski.de 
#   [PATCH] pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
#   
#   Remove the now useless irq_mask and irq_list parameters from PCMCIA drivers.
#   Users should use either the socket driver's irq_mask / irq_list parameter or
#   use /sys/class/pcmcia_socket/pcmcia_socket%n/card_irq_mask which will be added
#   in a subsequent patch.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# sound/pcmcia/vx/vxpocket.h
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +0 -2
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# sound/pcmcia/vx/vxpocket.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +0 -8
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# sound/pcmcia/vx/vx_entry.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +1 -6
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# sound/pcmcia/pdaudiocf/pdaudiocf.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +1 -13
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/serial/serial_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -14
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/scsi/pcmcia/sym53c500_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -20
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/scsi/pcmcia/qlogic_stub.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -18
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/scsi/pcmcia/nsp_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -17
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/scsi/pcmcia/fdomain_stub.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -13
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/scsi/pcmcia/aha152x_stub.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -13
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/parport/parport_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -12
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/wireless/wl3501_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -14
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/wireless/wavelan_cs.p.h
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +0 -7
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/wireless/wavelan_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -7
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/wireless/ray_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +1 -6
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/wireless/orinoco_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +3 -24
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/wireless/netwave_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -14
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/wireless/atmel_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -17
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/wireless/airo_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -17
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/xirc2ps_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -17
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/smc91c92_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -12
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/pcnet_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -12
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/nmclan_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -12
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/ibmtr_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -13
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/fmvj18x_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -13
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/com20020_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -13
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/axnet_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +3 -13
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/3c589_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -12
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/net/pcmcia/3c574_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -12
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/isdn/hisax/teles_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -17
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/isdn/hisax/sedlbauer_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +3 -17
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/isdn/hisax/elsa_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -17
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/isdn/hisax/avma1_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +3 -13
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/isdn/hardware/avm/avm_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -19
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/ide/legacy/ide-cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -12
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/char/pcmcia/synclink_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +1 -16
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/bluetooth/dtl1_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -15
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/bluetooth/btuart_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -15
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/bluetooth/bt3c_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -15
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# drivers/bluetooth/bluecard_cs.c
#   2005/01/15 14:31:03-08:00 linux@dominikbrodowski.de +2 -15
#   pcmcia: remove irq_mask and irq_list parameters from PCMCIA drivers
# 
# ChangeSet
#   2005/01/15 15:40:10-08:00 linux@dominikbrodowski.de 
#   [PATCH] pcmcia: ignore driver IRQ mask
#   
#   As its just one pin which can be used for IRQs on PCMCIA/CardBus cards, and
#   only the _socket drivers_ care with which IRQ this pin is connected, only the
#   socket drivers (assisted by the PCCARD core) should care about which IRQ to
#   use.  Therefore, ignore the information passed to pcmcia_request_irq() in
#   IRQInfo2.  In additional patches, all in-kernel users of IRQInfo2 will be
#   removed; users wishing to influence the usage of IRQs can do so by modifying
#   several driver's irq_mask parameter and/or by adding "exclude irq 3" to
#   /etc/pcmcia/config.opts.  Note that a new sysfs-based interface to do so will
#   be added in subsequent patches.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/pcmcia/cs.h
#   2005/01/15 14:31:02-08:00 linux@dominikbrodowski.de +1 -1
#   pcmcia: ignore driver IRQ mask
# 
# drivers/pcmcia/cs.c
#   2005/01/15 14:47:10-08:00 linux@dominikbrodowski.de +15 -22
#   pcmcia: ignore driver IRQ mask
# 
# ChangeSet
#   2005/01/15 15:39:56-08:00 linux@dominikbrodowski.de 
#   [PATCH] pcmcia: remove IRQ_TYPE_TIME
#   
#   IRQ_TYPE_TIME is unused in the whole kernel, so remove it.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/pcmcia/rsrc_mgr.c
#   2005/01/15 14:47:11-08:00 linux@dominikbrodowski.de +0 -26
#   pcmcia: remove IRQ_TYPE_TIME
# 
# ChangeSet
#   2005/01/15 15:39:40-08:00 roland@redhat.com 
#   [PATCH] clear false pending signal indication in core dump
#   
#   When kill is used to force a core dump, __group_complete_signal uses the
#   group_stop_count machinery to stop other threads from doing anything more
#   before the signal-taking thread starts the coredump synchronization.  This
#   intentionally results in group_stop_count always still being > 0 when the
#   signal-taking thread gets into do_coredump.  However, that has the
#   unintended effect that signal_pending can return true when called from the
#   filesystem code while writing the core dump file.  For NFS mounts using the
#   "intr" option, this results in NFS operations bailing out before they even
#   try, so core files never get successfully dumped on such a filesystem when
#   the crash was induced by an asynchronous process-wide signal.
#   
#   This patch fixes the problem by clearing group_stop_count after the
#   coredump synchronization is complete.
#   
#   The locking I threw in is not directly related, but always should have been
#   there and may avoid some potential races with kill.
#   
#   Signed-off-by: Roland McGrath <roland@redhat.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/exec.c
#   2005/01/15 14:31:02-08:00 roland@redhat.com +9 -0
#   clear false pending signal indication in core dump
# 
# ChangeSet
#   2005/01/15 15:39:26-08:00 pmeda@akamai.com 
#   [PATCH] ptrace: unlocked access to last_siginfo (resending)
#   
#   Since Roland changed now to wakeup tracee with kill, I guess this needs to be fixed.
#   http://linus.bkbits.net:8080/linux-2.5/gnupatch@41e3fe5fIRH-W3aDnXZgfQ-qIvuXYg
#   
#   ptrace_setsiginfo/ptrace_getsiginfo need to do locked access to
#   last_siginfo.  ptrace_notify()/ptrace_stop() sets the current->last_siginfo
#   and sleeps on schedule().  It can be waked up by kill signal from
#   signal_wake_up before debugger wakes it up.  On return from schedule(), the
#   current->last_siginfo is reset.
#   
#   Signed-off-by: Prasanna Meda <pmeda@akamai.com>
#   Acked-by: Roland McGrath <roland@redhat.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/ptrace.c
#   2005/01/15 14:31:02-08:00 pmeda@akamai.com +22 -7
#   ptrace: unlocked access to last_siginfo (resending)
# 
# ChangeSet
#   2005/01/15 15:39:11-08:00 roland@redhat.com 
#   [PATCH] fix exec deadlock when ptrace used inside the thread group
#   
#   If one thread uses ptrace on another thread in the same thread group, there
#   can be a deadlock when calling exec.  The ptrace_stop change ensures that
#   no tracing stop can be entered for a queued signal, or exit tracing, if the
#   tracer is part of the same dying group.  The exit_notify change prevents a
#   ptrace zombie from sticking around if its tracer is in the midst of a group
#   exit (which an exec fakes), so these zombies don't hold up de_thread's
#   synchronization.  The de_thread change ensures the new thread group leader
#   doesn't wind up ptracing itself, which would produce its own deadlocks.
#   
#   Signed-off-by: Roland McGrath <roland@redhat.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/signal.c
#   2005/01/15 14:31:02-08:00 roland@redhat.com +3 -1
#   fix exec deadlock when ptrace used inside the thread group
# 
# kernel/exit.c
#   2005/01/15 14:31:02-08:00 roland@redhat.com +3 -1
#   fix exec deadlock when ptrace used inside the thread group
# 
# fs/exec.c
#   2005/01/15 14:47:13-08:00 roland@redhat.com +8 -0
#   fix exec deadlock when ptrace used inside the thread group
# 
# ChangeSet
#   2005/01/15 15:38:53-08:00 roland@redhat.com 
#   [PATCH] fix race between core dumping and exec with shared mm
#   
#   When threads are sharing mm via CLONE_VM (linuxthreads, vfork), there is a
#   race condition where one thread doing a core dump and synchronizing all
#   mm-sharing threads for it can deadlock waiting for another thread that just
#   did an exec and will never synchronize.  This patch makes the exec_mmap
#   check for a pending core dump and punt the exec to synchronize with that,
#   as if the core dump had struck before entering the execve system call at
#   all.
#   
#   Signed-off-by: Roland McGrath <roland@redhat.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/exec.c
#   2005/01/15 14:47:13-08:00 roland@redhat.com +16 -0
#   fix race between core dumping and exec with shared mm
# 
# ChangeSet
#   2005/01/15 15:38:36-08:00 roland@redhat.com 
#   [PATCH] fix coredump_wait deadlock with ptracer & tracee on shared mm
#   
#   In the oddball situation where one thread is using ptrace on another thread
#   sharing the same mm, and then someone sharing that mm causes a coredump,
#   there is a deadlock possible if the traced thread is in TASK_TRACED state. 
#   It leaves all the threads sharing that mm wedged and permanently
#   unkillable.  This patch checks for that situation and brings a thread out
#   of TASK_TRACED if its tracer is part of the same coredump (i.e.  shares the
#   same mm).  It's not pretty, but it does the job.
#   
#   Signed-off-by: Roland McGrath <roland@redhat.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/exec.c
#   2005/01/15 14:47:13-08:00 roland@redhat.com +21 -0
#   fix coredump_wait deadlock with ptracer & tracee on shared mm
# 
# ChangeSet
#   2005/01/15 15:38:19-08:00 mst@mellanox.co.il 
#   [PATCH] macros to detect existance of unlocked_ioctl and ioctl_compat
#   
#   To make life bearable for out-of kernel modules, the following patch adds 2
#   macros so that existance of unlocked_ioctl and ioctl_compat can be easily
#   detected.
#   
#   Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/fs.h
#   2005/01/15 14:31:01-08:00 mst@mellanox.co.il +6 -0
#   macros to detect existance of unlocked_ioctl and ioctl_compat
# 
# ChangeSet
#   2005/01/15 15:38:01-08:00 hch@infradead.org 
#   [PATCH] ioctl rework #2
#   
#   - add ->unlocked_ioctl method and a do_ioctl wrapper in ioctl.c so all
#     places calling ->ioctl get it.  THis provides us a patch to migrate away
#     from holding bkl across ioctl implementations.
#   
#   - add ->compat_ioctl method and call it in compat_sys_ioctl before doing
#     the hash lookup for registered handlers.
#   
#   - streamline compat_sys_ioctl and move the complex error reporting into a
#     function of its own
#   
#   From: "Michael S. Tsirkin" <mst@mellanox.co.il>
#   
#   Handle generic ioctl commands by falling back on static conversion
#   functions in fs/compat_ioctl.c on -ENOIOCTLCMD code.
#   
#   From: "Michael S. Tsirkin" <mst@mellanox.co.il>
#   
#   With new unlocked_ioctl and ioctl_compat, ioctls can now be as fast as
#   read/write.  So lets use fget_light/fput_light there, to get some speedup
#   in common case on SMP.
#   
#   Signed-off-by: Michael s. Tsirkin <mst@mellanox.co.il>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/fs.h
#   2005/01/15 14:47:14-08:00 hch@infradead.org +4 -2
#   ioctl rework #2
# 
# fs/ioctl.c
#   2005/01/15 14:31:01-08:00 hch@infradead.org +45 -19
#   ioctl rework #2
# 
# fs/compat.c
#   2005/01/15 14:31:01-08:00 hch@infradead.org +70 -57
#   ioctl rework #2
# 
# Documentation/filesystems/Locking
#   2005/01/15 14:31:01-08:00 hch@infradead.org +7 -0
#   ioctl rework #2
# 
# ChangeSet
#   2005/01/15 15:37:44-08:00 agruen@suse.de 
#   [PATCH] ext3/EA: In-inode extended attributes for ext3
#   
#   This started of as a patch by Alex Tomas <alex@clusterfs.com> and got an
#   overhaul by me.  The on-disk structure used is the same as in Alex's
#   original patch.
#   
#   Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/ext3_fs_i.h
#   2005/01/15 14:31:01-08:00 agruen@suse.de +3 -0
#   ext3/EA: In-inode extended attributes for ext3
# 
# include/linux/ext3_fs.h
#   2005/01/15 14:31:01-08:00 agruen@suse.de +3 -1
#   ext3/EA: In-inode extended attributes for ext3
# 
# fs/ext3/xattr.h
#   2005/01/15 14:31:01-08:00 agruen@suse.de +4 -0
#   ext3/EA: In-inode extended attributes for ext3
# 
# fs/ext3/xattr.c
#   2005/01/15 14:31:01-08:00 agruen@suse.de +419 -172
#   ext3/EA: In-inode extended attributes for ext3
# 
# fs/ext3/inode.c
#   2005/01/15 14:31:01-08:00 agruen@suse.de +16 -1
#   ext3/EA: In-inode extended attributes for ext3
# 
# fs/ext3/ialloc.c
#   2005/01/15 14:31:01-08:00 agruen@suse.de +3 -0
#   ext3/EA: In-inode extended attributes for ext3
# 
# ChangeSet
#   2005/01/15 15:37:26-08:00 agruen@suse.de 
#   [PATCH] ext3/EA: Hide ext3_get_inode_loc in_mem option
#   
#   The in_mem optimization in ext3_get_inode_loc avoids a disk read when only
#   the requested inode in the block group is allocated: In that case
#   ext3_get_inode_loc assumes that it can recreate the inode from the
#   in-memory inode.  This is incorrect with in-inode extended attributes,
#   which don't have a shadow copy in memory.  Hide the in_mem option and
#   clarify comments; the subsequent ea-in-inode changes the in_mem check as
#   required.
#   
#   Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/ext3_fs.h
#   2005/01/15 14:47:14-08:00 agruen@suse.de +1 -0
#   ext3/EA: Hide ext3_get_inode_loc in_mem option
# 
# fs/ext3/inode.c
#   2005/01/15 14:47:14-08:00 agruen@suse.de +21 -15
#   ext3/EA: Hide ext3_get_inode_loc in_mem option
# 
# ChangeSet
#   2005/01/15 15:37:09-08:00 agruen@suse.de 
#   [PATCH] ext3/EA: Cleanup and prepare ext3 for in-inode xattrs
#   
#   Clean up several things in the xattr code, and prepare it for
#   in-inode attributes:
#   
#   * Add the ext3_xattr_check_names, ext3_xattr_check_block, and
#     ext3_xattr_check_entry functions for checking xattr data
#     structures.
#   * Add the ext3_xattr_find_entry, ext3_xattr_list_entries, and
#     ext3_xattr_set_entry functions for manipulating xattr entries.
#     Switch to using these functions in ext3_xattr_get,
#     ext3_xattr_list, and ext3_xattr_set_handle.
#   * Merge ext3_xattr_set_handle and ext3_xattr_set_handle2.
#   * Rename the HDR and FIRST_ENTRY macros.
#   * We have no way to deal with a ext3_xattr_cache_insert failure,
#     so make it return void.
#   * Make the debug messages more useful.
#   
#   Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/ext3/xattr.c
#   2005/01/15 14:47:14-08:00 agruen@suse.de +353 -362
#   ext3/EA: Cleanup and prepare ext3 for in-inode xattrs
# 
# fs/ext2/xattr.c
#   2005/01/15 14:31:01-08:00 agruen@suse.de +1 -1
#   ext3/EA: Cleanup and prepare ext3 for in-inode xattrs
# 
# ChangeSet
#   2005/01/15 15:36:51-08:00 agruen@suse.de 
#   [PATCH] ext3/EA: Ext[23]: no spare xattr handler slots needed
#   
#   The ext3_xattr_set_handle2 and ext3_xattr_delete_inode functions contain
#   duplicate code to decrease the reference count of an xattr block.  Move
#   this to a separate function.
#   
#   Also we know we have exclusive access to the inode in
#   ext3_xattr_delete_inode; there is no need to grab the xattr_sem lock.
#   
#   Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/ext3/xattr.h
#   2005/01/15 14:47:14-08:00 agruen@suse.de +0 -1
#   ext3/EA: Ext[23]: no spare xattr handler slots needed
# 
# fs/ext3/xattr.c
#   2005/01/15 14:47:14-08:00 agruen@suse.de +2 -2
#   ext3/EA: Ext[23]: no spare xattr handler slots needed
# 
# fs/ext2/xattr.h
#   2005/01/15 14:31:01-08:00 agruen@suse.de +0 -1
#   ext3/EA: Ext[23]: no spare xattr handler slots needed
# 
# fs/ext2/xattr.c
#   2005/01/15 14:47:14-08:00 agruen@suse.de +2 -2
#   ext3/EA: Ext[23]: no spare xattr handler slots needed
# 
# ChangeSet
#   2005/01/15 15:36:33-08:00 agruen@suse.de 
#   [PATCH] ext3/EA: Ext3: factor our common xattr code; unnecessary lock
#   
#   The ext3_xattr_set_handle2 and ext3_xattr_delete_inode functions contain
#   duplicate code to decrease the reference count of an xattr block.  Move
#   this to a separate function.
#   
#   Also we know we have exclusive access to the inode in
#   ext3_xattr_delete_inode; there is no need to grab the xattr_sem lock.
#   
#   Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/ext3/xattr.c
#   2005/01/15 14:47:15-08:00 agruen@suse.de +40 -57
#   ext3/EA: Ext3: factor our common xattr code; unnecessary lock
# 
# ChangeSet
#   2005/01/15 15:36:16-08:00 agruen@suse.de 
#   [PATCH] ext3/EA: Ext3: do not use journal_release_buffer
#   
#   The use of journal_release_buffer is unsafe; it can overflow the journal:
#   When a buffer is stolen from a transaction and later removed from that
#   transaction with journal_release_buffer, the buffer is not accounted to the
#   transaction that now "owns" the buffer, and one extra credit appears to be
#   available.  Don't use journal_release_buffer:
#   
#   We did rely on the buffer lock to synchronize xattr block accesses, and get
#   write access to the buffer first to get atomicity.  Return the
#   mb_cache_entry from ext3_xattr_cache_find instead, and do the check/update
#   under its lock.  Only get write access when we know we will use the buffer.
#   
#   Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/ext3/xattr.c
#   2005/01/15 14:47:15-08:00 agruen@suse.de +67 -75
#   ext3/EA: Ext3: do not use journal_release_buffer
# 
# ChangeSet
#   2005/01/15 15:35:57-08:00 agruen@suse.de 
#   [PATCH] ext3/EA: Race in ext[23] xattr sharing code
#   
#   Andrew Tridgell and Stephen C.  Tweedie have reported two different Oopses
#   caused by a race condition in the mbcache, which is responsible for
#   extended attribute sharing in ext2 and ext3.  Stephen tracked down the bug;
#   I did the fix.
#   
#   Explanation:
#   
#   The mbcache caches the locations and content hashes of xattr blocks.  There
#   are two access strategies: [1] xattr block disposal via
#   mb_cache_entry_get(), [2] xattr block reuse (sharing) via
#   mb_cache_entry_find_{first,next}().  There is no locking between the two
#   methods, so between one mb_cache_entry_find_x and the next, a
#   mb_cache_entry_get might come in, unhash the cache entry, and change the
#   journaling state of the xattr buffer.  Subsequently, two things can happen:
#   [a] the next mb_cache_entry_find_x may try to follow the mbcache hash chain
#   starting from the entry that has become unhashed, which now is a stale
#   pointer, [b] the block may have become deallocated, and then we try to
#   reuse it.
#   
#   Fix this by converting the mbcache into a readers-writer style lock, and
#   protect all block accesses in ext2/ext3 by the mbcache entry lock.  This
#   ensures that destroying blocks is an exclusive operation that may not
#   overlap xattr block reuse, while allowing multiple "re-users".  Write
#   access to the xattr block's buffer is protected by the buffer lock.  
#   
#   Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/mbcache.h
#   2005/01/15 14:31:00-08:00 agruen@suse.de +2 -1
#   ext3/EA: Race in ext[23] xattr sharing code
# 
# fs/mbcache.c
#   2005/01/15 14:31:00-08:00 agruen@suse.de +62 -7
#   ext3/EA: Race in ext[23] xattr sharing code
# 
# fs/ext3/xattr.c
#   2005/01/15 14:47:15-08:00 agruen@suse.de +29 -25
#   ext3/EA: Race in ext[23] xattr sharing code
# 
# fs/ext2/xattr.c
#   2005/01/15 14:47:15-08:00 agruen@suse.de +31 -24
#   ext3/EA: Race in ext[23] xattr sharing code
# 
# ChangeSet
#   2005/01/15 15:35:39-08:00 agruen@suse.de 
#   [PATCH] ext3/EA: mbcache cleanup
#   
#   There is no need to export struct mb_cache outside mbcache.c.  Move struct
#   mb_cache to fs/mbcache.c and remove the superfluous struct
#   mb_cache_entry_index declaration.
#   
#   Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/mbcache.h
#   2005/01/15 14:47:15-08:00 agruen@suse.de +8 -27
#   ext3/EA: mbcache cleanup
# 
# fs/mbcache.c
#   2005/01/15 14:47:15-08:00 agruen@suse.de +15 -1
#   ext3/EA: mbcache cleanup
# 
# fs/ext3/xattr.c
#   2005/01/15 14:47:15-08:00 agruen@suse.de +1 -1
#   ext3/EA: mbcache cleanup
# 
# fs/ext2/xattr.c
#   2005/01/15 14:47:15-08:00 agruen@suse.de +1 -1
#   ext3/EA: mbcache cleanup
# 
# ChangeSet
#   2005/01/15 15:35:23-08:00 agruen@suse.de 
#   [PATCH] ext3/ea: revert old ea-in-inode patch
#   
#   Revert the recently-added (post-2.6.10) ea-in-inode speedup patch.  We have a
#   new one.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/ext3_fs_i.h
#   2005/01/15 14:47:14-08:00 agruen@suse.de +0 -3
#   ext3/ea: revert old ea-in-inode patch
# 
# include/linux/ext3_fs.h
#   2005/01/15 14:47:14-08:00 agruen@suse.de +0 -3
#   ext3/ea: revert old ea-in-inode patch
# 
# fs/ext3/xattr.h
#   2005/01/15 14:47:15-08:00 agruen@suse.de +8 -1
#   ext3/ea: revert old ea-in-inode patch
# 
# fs/ext3/xattr.c
#   2005/01/15 14:47:15-08:00 agruen@suse.de +58 -625
#   ext3/ea: revert old ea-in-inode patch
# 
# fs/ext3/inode.c
#   2005/01/15 14:47:14-08:00 agruen@suse.de +1 -9
#   ext3/ea: revert old ea-in-inode patch
# 
# fs/ext3/ialloc.c
#   2005/01/15 14:47:14-08:00 agruen@suse.de +0 -5
#   ext3/ea: revert old ea-in-inode patch
# 
# ChangeSet
#   2005/01/15 15:35:06-08:00 Markus.Lidel@shadowconnect.com 
#   [PATCH] I2O: printk cleanup and unnecessary code removal
#   
#   - removed commented part in header which is not used anymore
#   - added wrappers for printk to make code more readable
#   - cleaned up logging output and removed unneccessary output
#   
#   Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/i2o.h
#   2005/01/15 14:30:50-08:00 Markus.Lidel@shadowconnect.com +19 -9
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/pci.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +25 -21
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/iop.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +46 -34
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/i2o_scsi.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +55 -64
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/i2o_proc.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +14 -10
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/i2o_config.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +24 -31
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/i2o_block.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +41 -46
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/exec-osm.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +8 -5
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/driver.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +12 -10
#   I2O: printk cleanup and unnecessary code removal
# 
# drivers/message/i2o/device.c
#   2005/01/15 14:01:59-08:00 Markus.Lidel@shadowconnect.com +10 -8
#   I2O: printk cleanup and unnecessary code removal
# 
# ChangeSet
#   2005/01/15 15:34:52-08:00 Markus.Lidel@shadowconnect.com 
#   [PATCH] I2O: fix possible race condition and minor improvements
#   
#   - I2O Block OSM contained a possible race condition (by Wolfram Joost)
#   - In pci.c the memory area which will be synced was wrong (original from
#      Wolfram Joost)
#   - number of OSM's which could be loaded is increased from 4 to 8
#   
#   Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/i2o.h
#   2005/01/15 14:47:16-08:00 Markus.Lidel@shadowconnect.com +1 -1
#   I2O: fix possible race condition and minor improvements
# 
# drivers/message/i2o/pci.c
#   2005/01/15 14:47:16-08:00 Markus.Lidel@shadowconnect.com +1 -1
#   I2O: fix possible race condition and minor improvements
# 
# drivers/message/i2o/i2o_block.c
#   2005/01/15 14:47:16-08:00 Markus.Lidel@shadowconnect.com +2 -2
#   I2O: fix possible race condition and minor improvements
# 
# ChangeSet
#   2005/01/15 15:34:34-08:00 rddunlap@osdl.org 
#   [PATCH] swiotlb: fix gcc printk warning
#   
#   swiotlb: Fix gcc printk format warning on x86_64, OK for ia64:
#   arch/ia64/lib/swiotlb.c:351: warning: long unsigned int format, long long
#   unsigned int arg (arg 2)
#   
#   Signed-off-by: Randy Dunlap <rddunlap@osdl.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/ia64/lib/swiotlb.c
#   2005/01/15 14:01:59-08:00 rddunlap@osdl.org +2 -2
#   swiotlb: fix gcc printk warning
# 
# ChangeSet
#   2005/01/15 15:34:20-08:00 joern@wohnheim.fh-wedel.de 
#   [PATCH] fixups for block2mtd
#   
#   Fixes to block2mtd.c - the previous driver was only compile-tested:
#   o Corrected copyright statements and some comments.
#   o Renamed blockmtd to block2mtd.
#   o Fixed the newline handling, it oopsed the kernel if no erase size
#     was passed.
#   o Replaced some printk() by INFO().
#   o Tried (but failed) to replace the readahead code.
#   
#   Signed-off-by: Jörn Engel <joern@wohnheim.fh-wedel.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/mtd/devices/block2mtd.c
#   2005/01/15 14:01:58-08:00 joern@wohnheim.fh-wedel.de +57 -66
#   fixups for block2mtd
# 
# ChangeSet
#   2005/01/15 15:34:03-08:00 alan@lxorguk.ukuu.org.uk 
#   [PATCH] smbfs fixes
#   
#   Fixes for various smbfs data leak bugs from Alan, Chuck Ebbert and various
#   people on various mailing lists.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/smbfs/request.c
#   2005/01/15 14:01:58-08:00 alan@lxorguk.ukuu.org.uk +33 -19
#   smbfs fixes
# 
# fs/smbfs/proc.c
#   2005/01/15 14:01:58-08:00 alan@lxorguk.ukuu.org.uk +3 -3
#   smbfs fixes
# 
# ChangeSet
#   2005/01/15 15:33:46-08:00 pluto@pld-linux.org 
#   [PATCH] csum_and_copy_from_user gcc4 warning fixes
#   
#   This patch kills tons of gcc4 warnings:
#   
#   pointer targets in passing argument 2 of 'csum_and_copy_from_user' differ in signedness		 
#   
#   From: Hirokazu Takata <takata@linux-m32r.org>
#   
#   * include/asm-m32r/checksum.h: build fix
#   
#   * arch/m32r/lib/csum_partial_copy.c:
#     - update comment
#     - cosmetic changes: change indentation
#   
#   Signed-off-by: Hirokazu Takata <takata@linux-m32r.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/net/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +2 -2
#   csum_and_copy_from_user gcc4 warning fixes
# 
# include/asm-x86_64/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +4 -4
#   csum_and_copy_from_user gcc4 warning fixes
# 
# include/asm-sparc64/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +7 -5
#   csum_and_copy_from_user gcc4 warning fixes
# 
# include/asm-sparc/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +4 -4
#   csum_and_copy_from_user gcc4 warning fixes
# 
# include/asm-sh/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +6 -6
#   csum_and_copy_from_user gcc4 warning fixes
# 
# include/asm-parisc/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +6 -4
#   csum_and_copy_from_user gcc4 warning fixes
# 
# include/asm-mips/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +5 -5
#   csum_and_copy_from_user gcc4 warning fixes
# 
# include/asm-m32r/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +6 -4
#   csum_and_copy_from_user gcc4 warning fixes
# 
# include/asm-i386/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +6 -6
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/x86_64/lib/csum-wrappers.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +3 -3
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/v850/lib/checksum.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +2 -2
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/um/kernel/checksum.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +6 -6
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/um/include/sysdep-i386/checksum.h
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +10 -10
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/sh64/lib/c-checksum.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +4 -4
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/parisc/lib/checksum.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +2 -2
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/m68knommu/lib/checksum.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +3 -2
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/m68k/lib/checksum.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +3 -3
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/m32r/lib/csum_partial_copy.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +15 -13
#   csum_and_copy_from_user gcc4 warning fixes
# 
# arch/ia64/lib/csum_partial_copy.c
#   2005/01/15 14:01:58-08:00 pluto@pld-linux.org +6 -5
#   csum_and_copy_from_user gcc4 warning fixes
# 
# ChangeSet
#   2005/01/15 15:33:30-08:00 shbader@de.ibm.com 
#   [PATCH] s390: use nonseekable_open in z/VM log reader
#   
#   Disable seek on z/VM log reader misc device by using nonseekable_open().
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/s390/char/vmlogrdr.c
#   2005/01/15 14:01:58-08:00 shbader@de.ibm.com +1 -1
#   s390: use nonseekable_open in z/VM log reader
# 
# ChangeSet
#   2005/01/15 15:33:16-08:00 cotte@de.ibm.com 
#   [PATCH] s390: vol1 partition recognition
#   
#   Make the ECKD compatible disk layout labling detection conditional to run only
#   on ECKD compatible disk layout volumes, do a fall back into the default
#   LNX/unlabled case otherwise.
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/partitions/ibm.c
#   2005/01/15 14:01:58-08:00 cotte@de.ibm.com +2 -1
#   s390: vol1 partition recognition
# 
# ChangeSet
#   2005/01/15 15:33:00-08:00 horst.hummel@de.ibm.com 
#   [PATCH] s390: dasd driver debug log
#   
#   dasd driver changes:
#    - Fix debug feature usage. The sprinf event/exception functions write a
#      pointer to a format string (%s) to the log. These strings must be valid
#      at the time the DBF-log is read.
#    - Some coding style reformatting.
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/s390/block/dasd_proc.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +2 -2
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_ioctl.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +3 -2
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_int.h
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +15 -2
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_fba.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +106 -14
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_erp.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +1 -8
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_eckd.h
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +6 -6
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_eckd.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +127 -68
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_diag.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +23 -32
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_devmap.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +3 -3
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd_3990_erp.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +21 -21
#   s390: dasd driver debug log
# 
# drivers/s390/block/dasd.c
#   2005/01/15 14:01:58-08:00 horst.hummel@de.ibm.com +22 -30
#   s390: dasd driver debug log
# 
# ChangeSet
#   2005/01/15 15:32:44-08:00 braunu@de.ibm.com 
#   [PATCH] s390: remove irq_exit from iucv
#   
#   Remove the irq_exit call on error path in iucv_irq_handler.  irq_exit is done
#   in do_extint().
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/s390/net/iucv.c
#   2005/01/15 14:01:57-08:00 braunu@de.ibm.com +3 -4
#   s390: remove irq_exit from iucv
# 
# ChangeSet
#   2005/01/15 15:32:26-08:00 schwidefsky@de.ibm.com 
#   [PATCH] s390: 3270 console
#   
#   3270 console changes:
#    - Initialize timer element before first use.
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/s390/char/tty3270.c
#   2005/01/15 14:01:57-08:00 schwidefsky@de.ibm.com +1 -0
#   s390: 3270 console
# 
# ChangeSet
#   2005/01/15 15:32:09-08:00 thoss@de.ibm.com 
#   [PATCH] s390: Common I/O layer changes
#   
#   Common I/O layer changes:
#    - Check if AIF is available on hardware before enabling
#      the AIF time delay disablement facility.
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/s390/cio/qdio.c
#   2005/01/15 14:01:57-08:00 thoss@de.ibm.com +7 -2
#   s390: Common I/O layer changes
# 
# ChangeSet
#   2005/01/15 15:31:54-08:00 heiko.carstens@de.ibm.com 
#   [PATCH] s390: cmm interface
#   
#   Collaborative memory management inferface changes:
#    - Allow cmmthread to run on every cpu.
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/s390/mm/cmm.c
#   2005/01/15 14:01:57-08:00 heiko.carstens@de.ibm.com +0 -11
#   s390: cmm interface
# 
# ChangeSet
#   2005/01/15 15:31:39-08:00 heiko.carstens@de.ibm.com 
#   [PATCH] s390: Core changes
#   
#   s390 core changes:
#    - Fix mm_struct leak on cpu hotplug.
#    - Improved cpu detection logic to avoid long delay at system start.
#    - Call cpu_relax() in cpu hotplug wait loop.
#    - Remove #define of account_system_vtime for CONFIG_VIRT_CPU_ACCOUNTING=n.
#    - Regenerate default configuration.
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-s390/system.h
#   2005/01/15 14:01:57-08:00 heiko.carstens@de.ibm.com +0 -2
#   s390: Core changes
# 
# arch/s390/kernel/smp.c
#   2005/01/15 14:01:57-08:00 heiko.carstens@de.ibm.com +26 -34
#   s390: Core changes
# 
# arch/s390/kernel/setup.c
#   2005/01/15 14:01:57-08:00 heiko.carstens@de.ibm.com +2 -0
#   s390: Core changes
# 
# arch/s390/defconfig
#   2005/01/15 14:01:57-08:00 heiko.carstens@de.ibm.com +6 -2
#   s390: Core changes
# 
# ChangeSet
#   2005/01/15 15:31:21-08:00 cborntra@de.ibm.com 
#   [PATCH] reintroduce task_nice export for binfmt_elf32
#   
#   S/390 needs this for its binfmt_elf32 module.
#   
#   Signed-off-by: Christian Borntraeger <cborntra@de.ibm.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/sched.c
#   2005/01/15 14:01:57-08:00 cborntra@de.ibm.com +9 -0
#   reintroduce task_nice export for binfmt_elf32
# 
# ChangeSet
#   2005/01/15 15:31:04-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: update ld scripts to newer binutils
#   
#   It seems that linker script for userspace software are quite
#   toolchain-depending, at least because what we use is a merge between builtin
#   LD scripts (see strings /usr/bin/ld) and normal kernel linking scripts.
#   
#   Plus, a number of people are having toolchain-related troubles building UML
#   (even assertion failures on linking, with Gentoo and Fedora 2).
#   
#   So, let's try to make UML nicer for binutils.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/kernel/uml.lds.S
#   2005/01/15 14:01:56-08:00 blaisorblade_spam@yahoo.it +9 -1
#   uml: update ld scripts to newer binutils
# 
# arch/um/kernel/dyn.lds.S
#   2005/01/15 14:01:56-08:00 blaisorblade_spam@yahoo.it +3 -0
#   uml: update ld scripts to newer binutils
# 
# ChangeSet
#   2005/01/15 15:30:49-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: add stack addresses to dumps
#   
#   From: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
#   
#   Add stack addresses to print of symbols from stack trace.
#   For stack analysis it's important to have this information.
#   
#   Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
#   
#   For UML, we should also copy the CONFIG_FRAME_POINTER stack walking from i386,
#   and move the result to sys-i386.
#   
#   Another note: this should be done for i386 also, if ksymoops does not have
#   problems.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/kernel/sysrq.c
#   2005/01/15 14:01:56-08:00 blaisorblade_spam@yahoo.it +3 -2
#   uml: add stack addresses to dumps
# 
# ChangeSet
#   2005/01/15 15:30:35-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: add stack content to dumps
#   
#   Copy some code from i386 to print the stack content.  Rough form yet, should
#   work although.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/kernel/sysrq.c
#   2005/01/15 14:47:21-08:00 blaisorblade_spam@yahoo.it +35 -5
#   uml: add stack content to dumps
# 
# ChangeSet
#   2005/01/15 15:30:20-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: fix and cleanup code in ubd_kern.c coming from ubd_user.c
#   
#   * Fix the use of errno: it refers to the __errno_location glibc definition
#     when in ubd_user.c, and hence works; but in ubd_kern.c it refers to
#     kernel_errno, which is different. So use the return value of os_* functions,
#     as we should always have done.
#   * Remove {read,write}_ubd_fs(), which are just silly.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/drivers/ubd_kern.c
#   2005/01/15 14:01:56-08:00 blaisorblade_spam@yahoo.it +4 -17
#   uml: fix and cleanup code in ubd_kern.c coming from ubd_user.c
# 
# ChangeSet
#   2005/01/15 15:30:06-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: move code from ubd_user to ubd_kern
#   
#   Most code of ubd_user.c already uses the os_* functions, so it can be moved to
#   ubd_kern.c.  This patch simply moves the code without any hidden changes.
#   
#   The only change is inside io_thread(): since it calls signal(), I created a
#   little function in ubd_user.c which just calls signal() with the right
#   parameters.
#   
#   In a later patch (send together) I'll do some changes, to fix the usage of
#   errno (which makes this code break when moved in a kernelspace file) and for
#   some other little cleanups.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/include/ubd_user.h
#   2005/01/15 14:01:56-08:00 blaisorblade_spam@yahoo.it +3 -56
#   uml: move code from ubd_user to ubd_kern
# 
# arch/um/drivers/ubd_user.c
#   2005/01/15 14:01:56-08:00 blaisorblade_spam@yahoo.it +1 -303
#   uml: move code from ubd_user to ubd_kern
# 
# arch/um/drivers/ubd_kern.c
#   2005/01/15 14:47:21-08:00 blaisorblade_spam@yahoo.it +365 -0
#   uml: move code from ubd_user to ubd_kern
# 
# ChangeSet
#   2005/01/15 15:29:50-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: allow free ubd flag ordering
#   
#   When parsing the <flags> section in ubd<n><flags>=file[,file2], instead of
#   requiring that the flags are specified in a certain order, just make the code
#   smarter.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/drivers/ubd_kern.c
#   2005/01/15 14:47:21-08:00 blaisorblade_spam@yahoo.it +29 -19
#   uml: allow free ubd flag ordering
# 
# ChangeSet
#   2005/01/15 15:29:34-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: for ubd cmdline param use colon as delimiter
#   
#   Currently we can use this syntax ubd<n>[<flags>]=file1,file2. However, writing
#   things as
#   	ubd0=~/Uml/file1,~/Uml/file2
#   does not work; in fact, the shell won't expand the second '~', since it's not
#   at a path beginning; possibly even other shell expansions don't work here. So
#   simply allow using, instead of the ',' separator, the ':' separator.
#   
#   The ',' separator can still be used to preserve backward compatibility.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/drivers/ubd_kern.c
#   2005/01/15 14:47:21-08:00 blaisorblade_spam@yahoo.it +17 -3
#   uml: for ubd cmdline param use colon as delimiter
# 
# ChangeSet
#   2005/01/15 15:29:19-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: refuse to run without skas if no tt mode in
#   
#   Return an early error message when no TT support is compiled in and no SKAS
#   support is detected.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/kernel/um_arch.c
#   2005/01/15 14:01:55-08:00 blaisorblade_spam@yahoo.it +9 -1
#   uml: refuse to run without skas if no tt mode in
# 
# arch/um/kernel/process.c
#   2005/01/15 14:01:55-08:00 blaisorblade_spam@yahoo.it +26 -9
#   uml: refuse to run without skas if no tt mode in
# 
# ChangeSet
#   2005/01/15 15:29:02-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: fix some UML own initcall macros
#   
#   UML has his own initcall mechanism to handle his special userspace
#   initialization (they are called in different moments, so they are indeed
#   
#   It must also duplicate some definition for the benefit of userspace code - but
#   those definition weren't in sync with the main code.  Also, the UML own macros
#   missed __attribute_used__.  Both problems are fixed by this patch.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/include/init.h
#   2005/01/15 14:01:55-08:00 blaisorblade_spam@yahoo.it +17 -8
#   uml: fix some UML own initcall macros
# 
# ChangeSet
#   2005/01/15 15:28:47-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: Makefile simplification and correction.
#   
#   Cleanup: simplify a lot of strange constructs and whatever present in
#   arch/um/Makefile.
#   
#   Also, get rid of redundant cleaning code introduced in
#   "uml-fix-make-clean.patch" from 2.6.10-mm3 - when it was written it made
#   sense, but I fixed most problems it addressed in a more elegant way.
#   
#   Also about that, don't remove $(ARCH_SYMLINKS) in make clean, but rather in
#   make mrproper as we already do, like for include/asm-um and other symlinks.
#   
#   Finally, remove one wrong thing (almost a bug) introduced in that - the usage
#   of the clean-dirs construct:
#   
#   clean-dirs := sys-$(SUBARCH)
#   
#   which is intended to delete one whole folder, rather than to descend to clean
#   it, when used in normal Makefiles (not in the arch Makefile where is used,
#   with no effect).  It's also not needed because that folder is cleaned because
#   is listed in either $(core-y) or $(libs-y).
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Cc: Chris Wright <chrisw@osdl.org>
#   Cc: Jeff Dike <jdike@addtoit.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/Makefile
#   2005/01/15 14:01:55-08:00 blaisorblade_spam@yahoo.it +39 -58
#   uml: Makefile simplification and correction.
# 
# arch/um/Makefile-tt
#   2005/01/15 14:01:55-08:00 blaisorblade_spam@yahoo.it +0 -1
#   uml: Makefile simplification and correction.
# 
# arch/um/Makefile-skas
#   2005/01/15 14:01:55-08:00 blaisorblade_spam@yahoo.it +0 -5
#   uml: Makefile simplification and correction.
# 
# arch/um/Makefile-os-Linux
#   2005/01/15 14:01:55-08:00 blaisorblade_spam@yahoo.it +3 -1
#   uml: Makefile simplification and correction.
# 
# arch/um/Kconfig
#   2005/01/15 14:47:06-08:00 blaisorblade_spam@yahoo.it +10 -0
#   uml: Makefile simplification and correction.
# 
# ChangeSet
#   2005/01/15 15:28:32-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: depend on !USERMODE in drivers/block/Kconfig and drop arch/um/Kconfig_block
#   
#   Finally, we end with this the need to update arch/um/Kconfig_block with
#   changes in drivers/block/Kconfig - we include directly that; UML-specific
#   entries were moved into it (they are very few).
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/block/Kconfig
#   2005/01/15 14:47:06-08:00 blaisorblade_spam@yahoo.it +55 -2
#   uml: depend on !USERMODE in drivers/block/Kconfig and drop arch/um/Kconfig_block
# 
# arch/um/Kconfig
#   2005/01/15 14:47:22-08:00 blaisorblade_spam@yahoo.it +1 -1
#   uml: depend on !USERMODE in drivers/block/Kconfig and drop arch/um/Kconfig_block
# 
# BitKeeper/deleted/.del-Kconfig_block~859c1cca9b497ea8
#   2005/01/15 15:28:24-08:00 blaisorblade_spam@yahoo.it +0 -0
#   Delete: arch/um/Kconfig_block
# 
# ChangeSet
#   2005/01/15 15:28:16-08:00 cw@f00f.org 
#   [PATCH] uml: fail xterm_open when we have no $DISPLAY
#   
#   If UML wants to open an xterm channel and the xterm does not run properly (eg.
#    terminates soon after starting) we will get a hang (a comment added in the
#   patch explains why).
#   
#   This avoids the most common cause for this and adds a comment (which long term
#   will go away with a rewrite of that code); the complete fix would be to catch
#   the xterm process dying, up(&data->sem), and -EIO all requests from that point
#   onwards.
#   
#   That applies for some of the other channels too, so part of the code should
#   probably be abstracted a little and generalized.
#   
#   Signed-off-by: Chris Wedgwood <cw@f00f.org>
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/drivers/xterm_kern.c
#   2005/01/15 14:01:55-08:00 cw@f00f.org +8 -1
#   uml: fail xterm_open when we have no $DISPLAY
# 
# arch/um/drivers/xterm.c
#   2005/01/15 14:01:55-08:00 cw@f00f.org +7 -0
#   uml: fail xterm_open when we have no $DISPLAY
# 
# ChangeSet
#   2005/01/15 15:28:02-08:00 jdike@addtoit.com 
#   [PATCH] uml: commentary about SIGWINCH handling for consoles
#   
#   Explain what happens inside the SIGWINCH handler - it's non-obvious enough
#   that the correct code seemed me to need a cleanup (which was indeed buggy).
#   More info in the comments themselves.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/drivers/chan_user.c
#   2005/01/15 14:01:55-08:00 jdike@addtoit.com +29 -0
#   uml: commentary about SIGWINCH handling for consoles
# 
# ChangeSet
#   2005/01/15 15:27:45-08:00 domen@coderock.org 
#   [PATCH] uml: delete unused header umn.h
#   
#   Remove nowhere referenced header. (egrep "filename\." didn't find anything)
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Cc: UML-devel <user-mode-linux-devel@lists.sourceforge.net>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# BitKeeper/deleted/.del-umn.h~f04b88384ae2cdb0
#   2005/01/15 15:27:38-08:00 domen@coderock.org +0 -0
#   Delete: arch/um/include/umn.h
# 
# ChangeSet
#   2005/01/15 15:27:30-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: drop unused buffer_head.h header from hostfs
#   
#   Drop that header inclusion - I discovered this header was unused while
#   checking whether I can use the __set_page_dirty_nobuffers speedup suggested by
#   Andrew Morton.
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/hostfs/hostfs_kern.c
#   2005/01/15 14:01:55-08:00 blaisorblade_spam@yahoo.it +0 -1
#   uml: drop unused buffer_head.h header from hostfs
# 
# ChangeSet
#   2005/01/15 15:27:15-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: Commentary addition to recent SYSEMU fix.
#   
#   Add some comments about the "uml-sysemu-fixes" patch of 2.6.10-mm1 (merged in
#   2.6.11-rc1).
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/kernel/tt/tracer.c
#   2005/01/15 14:01:54-08:00 blaisorblade_spam@yahoo.it +14 -0
#   uml: Commentary addition to recent SYSEMU fix.
# 
# ChangeSet
#   2005/01/15 15:27:00-08:00 blaisorblade_spam@yahoo.it 
#   [PATCH] uml: readd CONFIG_MAGIC_SYSRQ for UML
#   
#   This config option was lost during the creation of lib/Kconfig.debug, due to a
#   bad expressed dependency; I also moved the option back to its original place
#   for UML (it is near CONFIG_MCONSOLE since it depends on that).
#   
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# lib/Kconfig.debug
#   2005/01/15 14:01:54-08:00 blaisorblade_spam@yahoo.it +0 -1
#   uml: readd CONFIG_MAGIC_SYSRQ for UML
# 
# arch/um/Kconfig
#   2005/01/15 14:47:22-08:00 blaisorblade_spam@yahoo.it +19 -0
#   uml: readd CONFIG_MAGIC_SYSRQ for UML
# 
# ChangeSet
#   2005/01/15 15:26:45-08:00 frank@tuxrocks.com 
#   [PATCH] uml: avoid NULL dereference in line.c
#   
#   This patch reorders two lines to check a variable for NULL before using 
#   the variable.
#   
#   Signed-off-by: Frank Sorenson <frank@tuxrocks.com>
#   Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/um/drivers/line.c
#   2005/01/15 14:01:54-08:00 frank@tuxrocks.com +1 -1
#   uml: avoid NULL dereference in line.c
# 
# ChangeSet
#   2005/01/15 15:26:28-08:00 pavel@ucw.cz 
#   [PATCH] swsusp: refrigerator cleanups
#   
#   This patch is from Nigel's swsusp2, it kills ugly #include <suspend.h> from
#   all over the tree, and makes code slightly nicer.  I only left those parts
#   that do not change any code.
#   
#   From: Nigel Cunningham <ncunningham@linuxmail.org>
#   Signed-off-by: Pavel Machek <pavel@suse.cz>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# net/sunrpc/svcsock.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# net/sunrpc/sched.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +0 -1
#   swsusp: refrigerator cleanups
# 
# mm/vmscan.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +0 -1
#   swsusp: refrigerator cleanups
# 
# mm/pdflush.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# include/linux/sched.h
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -1
#   swsusp: refrigerator cleanups
# 
# fs/xfs/linux-2.6/xfs_super.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# fs/xfs/linux-2.6/xfs_buf.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -4
#   swsusp: refrigerator cleanups
# 
# fs/reiserfs/journal.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +0 -1
#   swsusp: refrigerator cleanups
# 
# fs/jffs2/background.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -6
#   swsusp: refrigerator cleanups
# 
# drivers/w1/w1.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +2 -5
#   swsusp: refrigerator cleanups
# 
# drivers/usb/core/hub.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# drivers/pcmcia/socket_sysfs.c
#   2005/01/15 14:47:10-08:00 pavel@ucw.cz +0 -1
#   swsusp: refrigerator cleanups
# 
# drivers/pcmcia/cs.c
#   2005/01/15 14:47:12-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# drivers/net/wireless/airo.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# drivers/net/irda/stir4200.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +0 -1
#   swsusp: refrigerator cleanups
# 
# drivers/net/irda/sir_kthread.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +0 -1
#   swsusp: refrigerator cleanups
# 
# drivers/net/8139too.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# drivers/input/serio/serio.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# drivers/ieee1394/nodemgr.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -4
#   swsusp: refrigerator cleanups
# 
# arch/x86_64/kernel/signal.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -4
#   swsusp: refrigerator cleanups
# 
# arch/sh64/kernel/signal.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# arch/sh/kernel/signal.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -4
#   swsusp: refrigerator cleanups
# 
# arch/mips/kernel/signal32.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -3
#   swsusp: refrigerator cleanups
# 
# arch/mips/kernel/signal.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -4
#   swsusp: refrigerator cleanups
# 
# arch/mips/kernel/irixsig.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -4
#   swsusp: refrigerator cleanups
# 
# arch/arm/kernel/signal.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -4
#   swsusp: refrigerator cleanups
# 
# ChangeSet
#   2005/01/15 15:26:09-08:00 pavel@ucw.cz 
#   [PATCH] make suspend work with ioapic
#   
#   IRQ balancing daemon needs try_to_freeze().
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/i386/kernel/io_apic.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -0
#   make suspend work with ioapic
# 
# ChangeSet
#   2005/01/15 15:25:55-08:00 pavel@ucw.cz 
#   [PATCH] acpi: comment/whitespace updates
#   
#   This cleans few comments/formatting.
#   
#   Signed-off-by: Pavel Machek <pavel@ucw.cz>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/acpi/events/evgpeblk.c
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +1 -1
#   acpi: comment/whitespace updates
# 
# arch/i386/kernel/acpi/wakeup.S
#   2005/01/15 14:01:54-08:00 pavel@ucw.cz +2 -2
#   acpi: comment/whitespace updates
# 
# ChangeSet
#   2005/01/15 15:25:38-08:00 pavel@ucw.cz 
#   [PATCH] swsusp: update docs
#   
#   This updates swsusp documentation.
#   
#   Signed-off-by: Pavel Machek <pavel@ucw.cz>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# Documentation/power/swsusp.txt
#   2005/01/15 14:01:53-08:00 pavel@ucw.cz +50 -0
#   swsusp: update docs
# 
# ChangeSet
#   2005/01/15 15:25:21-08:00 pavel@ucw.cz 
#   [PATCH] swsusp/dm: Use right levels for device_suspend()
#   
#   This almost changes no code (constant is still "3"), but at least it uses
#   right constants for device_suspend() and fixes types at few points.  Also
#   puts explanation of constants to the Documentation.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/power/swsusp.c
#   2005/01/15 14:01:53-08:00 pavel@ucw.cz +2 -2
#   swsusp/dm: Use right levels for device_suspend()
# 
# kernel/power/main.c
#   2005/01/15 14:01:53-08:00 pavel@ucw.cz +4 -3
#   swsusp/dm: Use right levels for device_suspend()
# 
# kernel/power/disk.c
#   2005/01/15 14:01:53-08:00 pavel@ucw.cz +4 -2
#   swsusp/dm: Use right levels for device_suspend()
# 
# drivers/acpi/sleep/main.c
#   2005/01/15 14:01:53-08:00 pavel@ucw.cz +1 -1
#   swsusp/dm: Use right levels for device_suspend()
# 
# arch/i386/kernel/apm.c
#   2005/01/15 14:01:53-08:00 pavel@ucw.cz +3 -3
#   swsusp/dm: Use right levels for device_suspend()
# 
# Documentation/power/devices.txt
#   2005/01/15 14:01:53-08:00 pavel@ucw.cz +88 -0
#   swsusp/dm: Use right levels for device_suspend()
# 
# ChangeSet
#   2005/01/15 15:25:06-08:00 pavel@ucw.cz 
#   [PATCH] swsusp: more small fixes
#   
#   This adds few missing statics to swsusp.c, prints errors even when
#   non-debugging and fixes last "pmdisk: " message. Fixed few comments. 
#   
#   Signed-off-by: Pavel Machek <pavel@suse.cz>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/power/swsusp.c
#   2005/01/15 14:47:25-08:00 pavel@ucw.cz +7 -7
#   swsusp: more small fixes
# 
# kernel/power/main.c
#   2005/01/15 14:47:25-08:00 pavel@ucw.cz +1 -1
#   swsusp: more small fixes
# 
# kernel/power/disk.c
#   2005/01/15 14:47:25-08:00 pavel@ucw.cz +4 -4
#   swsusp: more small fixes
# 
# ChangeSet
#   2005/01/15 15:24:52-08:00 suresh.b.siddha@intel.com 
#   [PATCH] x86_64: use cpumask_t instead of unsigned long
#   
#   Another cpumask_t related fix: use cpumask_t instead of unsigned long.
#   
#   Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
#   Cc: Andi Kleen <ak@muc.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-x86_64/proto.h
#   2005/01/15 14:01:53-08:00 suresh.b.siddha@intel.com +1 -1
#   x86_64: use cpumask_t instead of unsigned long
# 
# arch/x86_64/kernel/setup64.c
#   2005/01/15 14:01:53-08:00 suresh.b.siddha@intel.com +2 -2
#   x86_64: use cpumask_t instead of unsigned long
# 
# arch/x86_64/kernel/mce.c
#   2005/01/15 14:01:53-08:00 suresh.b.siddha@intel.com +2 -2
#   x86_64: use cpumask_t instead of unsigned long
# 
# ChangeSet
#   2005/01/15 15:24:36-08:00 prasanna@in.ibm.com 
#   [PATCH] x68: consolidate code segment base calculation
#   
#   Calculating the base address of the segment is tricky and is used in
#   several places as well.  This patch moves this tricky part in a common
#   place as suggested by Andi Kleen.
#   
#   Signed-of-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-i386/desc.h
#   2005/01/15 14:01:53-08:00 prasanna@in.ibm.com +9 -0
#   x68: consolidate code segment base calculation
# 
# arch/i386/mm/fault.c
#   2005/01/15 14:01:53-08:00 prasanna@in.ibm.com +1 -3
#   x68: consolidate code segment base calculation
# 
# arch/i386/kernel/kprobes.c
#   2005/01/15 14:01:53-08:00 prasanna@in.ibm.com +3 -4
#   x68: consolidate code segment base calculation
# 
# ChangeSet
#   2005/01/15 15:24:20-08:00 rjw@sisk.pl 
#   [PATCH] Fix a bug in timer_suspend() on x86_64
#   
#   This patch is intended to fix a bug in timer_suspend() on x86_64 that
#   causes hard lockups on suspend with swsusp and provide some optimizations. 
#   It is based on the Nigel Cunningham's patches to to reduce delay in
#   arch/kernel/time.c.
#   
#   Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
#   Acked-by: Pavel Machek <pavel@suse.cz>
#   Acked-by: Nigel Cunningham <ncunningham@linuxmail.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/x86_64/kernel/time.c
#   2005/01/15 14:01:53-08:00 rjw@sisk.pl +9 -5
#   Fix a bug in timer_suspend() on x86_64
# 
# ChangeSet
#   2005/01/15 15:24:04-08:00 ak@suse.de 
#   [PATCH] x86_64: Optimize nodemask operations slightly
#   
#   Optimize first/node_node
#   
#   Optimize nodemask_t slightly.  The x86-64 find_first/next_bit uses
#   __builtin_constant_p on the size argument to special cases small single
#   long word searches.  But most gccs don't make __builtin_constant_p true
#   when an argument is passed through an inline function.  Move the constant
#   into the inline function to avoid this.  This generates a lot better code
#   for node searches on x86-64.
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/nodemask.h
#   2005/01/15 14:01:52-08:00 ak@suse.de +9 -6
#   x86_64: Optimize nodemask operations slightly
# 
# ChangeSet
#   2005/01/15 15:23:47-08:00 ak@suse.de 
#   [PATCH] x86_64: Disable uselib when possible
#   
#   Disable sys_uselib for 64bit processes and only enable for 32bit processes
#   when a.out support is compiled in.
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-x86_64/unistd.h
#   2005/01/15 14:01:52-08:00 ak@suse.de +2 -1
#   x86_64: Disable uselib when possible
# 
# arch/x86_64/ia32/ia32entry.S
#   2005/01/15 14:01:52-08:00 ak@suse.de +4 -0
#   x86_64: Disable uselib when possible
# 
# ChangeSet
#   2005/01/15 15:23:30-08:00 ak@suse.de 
#   [PATCH] x86_64: Move early CPU detection earlier
#   
#   Move early CPU detection earlier.  Needed for some followup patches and
#   makes sense in general.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/x86_64/kernel/setup64.c
#   2005/01/15 14:47:26-08:00 ak@suse.de +0 -3
#   x86_64: Move early CPU detection earlier
# 
# arch/x86_64/kernel/setup.c
#   2005/01/15 14:01:52-08:00 ak@suse.de +2 -0
#   x86_64: Move early CPU detection earlier
# 
# ChangeSet
#   2005/01/15 15:23:16-08:00 ak@suse.de 
#   [PATCH] x86_64: Add brackets to bitops
#   
#   Add missing argument brackets in bitop macros
#   
#   Makes these macros somewhat safer to use.
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-x86_64/bitops.h
#   2005/01/15 14:01:52-08:00 ak@suse.de +4 -4
#   x86_64: Add brackets to bitops
# 
# ChangeSet
#   2005/01/15 15:23:00-08:00 ak@suse.de 
#   [PATCH] x86_64/i386: increase command line size
#   
#   Enlarge i386/x86-64 kernel command line to 2k
#   
#   This is useful when the kernel command line is used to pass other
#   information to initrds or installers.
#   
#   On i386 it was duplicated for unknown reasons.
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-x86_64/setup.h
#   2005/01/15 14:01:52-08:00 ak@suse.de +1 -1
#   x86_64/i386: increase command line size
# 
# include/asm-i386/setup.h
#   2005/01/15 14:01:52-08:00 ak@suse.de +1 -1
#   x86_64/i386: increase command line size
# 
# include/asm-i386/param.h
#   2005/01/15 14:01:52-08:00 ak@suse.de +1 -1
#   x86_64/i386: increase command line size
# 
# ChangeSet
#   2005/01/15 15:22:46-08:00 dhowells@redhat.com 
#   [PATCH] FRV: Excess whitespace cleanup
#   
#   The attached patch cleans up some excess whitespace from the FRV entry.S.
#   
#   Signed-Off-By: David Howells <dhowells@redhat.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/frv/kernel/entry.S
#   2005/01/15 14:01:52-08:00 dhowells@redhat.com +1 -1
#   FRV: Excess whitespace cleanup
# 
# ChangeSet
#   2005/01/15 15:22:31-08:00 dhowells@redhat.com 
#   [PATCH] FRV: Remove mandatory single-step debugging diversion
#   
#   The attached patch removes the mandatory single-step diversion code from
#   the FRV syscall handler that was put there for debugging purposes now that
#   it's no longer needed.
#   
#   Signed-Off-By: David Howells <dhowells@redhat.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/frv/kernel/entry.S
#   2005/01/15 14:47:27-08:00 dhowells@redhat.com +0 -2
#   FRV: Remove mandatory single-step debugging diversion
# 
# ChangeSet
#   2005/01/15 15:22:15-08:00 anton@samba.org 
#   [PATCH] ppc64: lacks definition of MM_VM_SIZE()
#   
#   With David Woodhouse <dwmw2@infradead.org>
#   
#   We don't set MM_VM_SIZE() on ppc64, so it defaults to TASK_SIZE.  Which
#   means a 32-bit process ending up in exit_mmap() to kill a 64-bit mm may
#   call tlb_finish_mmu() with an incorrect 'end' argument.
#   
#   Signed-off-by: Anton Blanchard <anton@samba.org>
#   Signed-off-by: David Woodhouse <dwmw2@infradead.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-ppc64/processor.h
#   2005/01/15 14:01:52-08:00 anton@samba.org +4 -0
#   ppc64: lacks definition of MM_VM_SIZE()
# 
# ChangeSet
#   2005/01/15 15:21:58-08:00 olof@austin.ibm.com 
#   [PATCH] ppc64: iommu: avoid ISA io space on POWER3
#   
#   On some systems, the first PCI bus has a ISA I/O hole at the first 16MB.
#   We can't use this space for DMA addresses on the bus.
#   
#   On Python-based machines, we'll skip the first 256MB on buses that have the
#   hole, just as we do on later systems.  This means that the first bus will
#   have 768MB of DMA space shared between the devices on it.
#   
#   Signed-off-by: Olof Johansson <olof@austin.ibm.com>
#   Acked-by: Paul Mackerras <paulus@samba.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/ppc64/kernel/pSeries_iommu.c
#   2005/01/15 14:01:51-08:00 olof@austin.ibm.com +16 -3
#   ppc64: iommu: avoid ISA io space on POWER3
# 
# ChangeSet
#   2005/01/15 15:21:42-08:00 michael@ellerman.id.au 
#   [PATCH] ppc64: make iseries_veth call flush_scheduled_work()
#   
#   When the iseries_veth driver module is unloaded there is the potential for an
#   oops and also some memory leakage.
#   
#   Because the HvLpEvent_unregisterHandler() function did no synchronisation,
#   it was possible for the handler that was being unregistered to be running
#   on another CPU *after* HvLpEvent_unregisterHandler() had returned.  This
#   could cause the iseries_veth driver to leave work in the events work queue
#   after the module had been unloaded.  When that work was eventually executed
#   we got an oops.
#   
#   In addition some of the data structures in the iseries_veth driver were not
#   being correctly freed when the module was unloaded.
#   
#   This is the second patch, we make iseries_veth call flush_scheduled_work()
#   after we are sure the handler is no longer running, and also fix the memory
#   leaks.
#   
#   Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/net/iseries_veth.c
#   2005/01/15 14:01:51-08:00 michael@ellerman.id.au +22 -4
#   ppc64: make iseries_veth call flush_scheduled_work()
# 
# ChangeSet
#   2005/01/15 15:21:27-08:00 michael@ellerman.id.au 
#   [PATCH] ppc64: make HvLpEvent_unregisterHandler() work
#   
#   When the iseries_veth driver module is unloaded there is the potential for
#   an oops and also some memory leakage.
#   
#   Because the HvLpEvent_unregisterHandler() function did no synchronisation,
#   it was possible for the handler that was being unregistered to be running
#   on another CPU *after* HvLpEvent_unregisterHandler() had returned.  This
#   could cause the iseries_veth driver to leave work in the events work queue
#   after the module had been unloaded.  When that work was eventually executed
#   we got an oops.
#   
#   In addition some of the data structures in the iseries_veth driver were not
#   being correctly freed when the module was unloaded.
#   
#   This is the first patch, which makes HvLpEvent_unregisterHandler() work.
#   
#   Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-ppc64/iSeries/HvLpEvent.h
#   2005/01/15 14:01:51-08:00 michael@ellerman.id.au +3 -0
#   ppc64: make HvLpEvent_unregisterHandler() work
# 
# arch/ppc64/kernel/HvLpEvent.c
#   2005/01/15 14:01:51-08:00 michael@ellerman.id.au +8 -0
#   ppc64: make HvLpEvent_unregisterHandler() work
# 
# ChangeSet
#   2005/01/15 15:21:13-08:00 mporter@kernel.crashing.org 
#   [PATCH] ppc32: fix PPC44x build
#   
#   Fix PPC44x build broken from a latent bug.
#   
#   Signed-off-by: Matt Porter <mporter@kernel.crashing.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-ppc/pgtable.h
#   2005/01/15 14:01:51-08:00 mporter@kernel.crashing.org +1 -0
#   ppc32: fix PPC44x build
# 
# ChangeSet
#   2005/01/15 15:20:58-08:00 trini@kernel.crashing.org 
#   [PATCH] ppc32: Add Freescale PQ2FADS support
#   
#   The following adds support for Freescale's PQ2FADS board to the kernel.
#   
#   (The 'real' changes required for the board are in the ethernet driver,
#   which needs a massive sync-up with mainline as I've been holding out for a
#   better, rewritten one from the Freescale folks, who're waiting for the PHY
#   lib patch sent to the net-dev list to get ack'd)
#   
#   Signed-off-by: Tom Rini <trini@kernel.crashing.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-ppc/mpc8260.h
#   2005/01/15 14:01:51-08:00 trini@kernel.crashing.org +1 -1
#   ppc32: Add Freescale PQ2FADS support
# 
# arch/ppc/platforms/pq2ads.h
#   2005/01/15 14:01:51-08:00 trini@kernel.crashing.org +2 -0
#   ppc32: Add Freescale PQ2FADS support
# 
# arch/ppc/Kconfig
#   2005/01/15 14:47:06-08:00 trini@kernel.crashing.org +7 -1
#   ppc32: Add Freescale PQ2FADS support
# 
# ChangeSet
#   2005/01/15 15:20:43-08:00 trini@kernel.crashing.org 
#   [PATCH] ppc32: Fix mpc8272ads
#   
#   When I reworked the m82xx init functions, I inadvertantly broke the callout
#   we had from ppc_md.setup_arch() that boards can use to poke & prod things,
#   once mappings are set.  The following adds in a callback and updates the
#   one m82xx board that needs it.
#   
#   Signed-off-by: Tom Rini <trini@kernel.crashing.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/ppc/syslib/m8260_setup.c
#   2005/01/15 14:01:51-08:00 trini@kernel.crashing.org +8 -1
#   ppc32: Fix mpc8272ads
# 
# arch/ppc/platforms/pq2ads.c
#   2005/01/15 14:01:51-08:00 trini@kernel.crashing.org +2 -2
#   ppc32: Fix mpc8272ads
# 
# ChangeSet
#   2005/01/15 15:20:28-08:00 miquels@cistron.nl 
#   [PATCH] mark-page-accessed in filemap.c not quite right
#   
#   I just discovered there's a thinko in the mark-page-accessed change in
#   do_generic_mapping_read() in 2.6.11-rc1.  ra.prev_page is compared to index
#   to see if we read from this page before - except that prev_page is actually
#   set to the recent page or even a page in front of the current page.
#   
#   So we should store ra.prev_page in a seperate variable at the start of
#   do_generic_mapping_read().
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# mm/filemap.c
#   2005/01/15 14:01:51-08:00 miquels@cistron.nl +4 -1
#   mark-page-accessed in filemap.c not quite right
# 
# ChangeSet
#   2005/01/15 15:20:14-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: rename handle_outgoing_smp
#   
#   Change routine name from handle_outgoing_smp to handle_outgoing_dr_smp.
#   
#   Signed-off-by: Hal Rosenstock <halr@voltaire.com>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/core/mad.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +5 -4
#   InfiniBand/core: rename handle_outgoing_smp
# 
# ChangeSet
#   2005/01/15 15:19:59-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/ipoib: move structs from stack to device private struct
#   
#   Move the gather list and work request used for posting sends from the stack in
#   ipoib_send() to the private structure.  This reduces the stack usage for the
#   data path function ipoib_send() and may speed things up slightly because we
#   don't need to initialize constant members of the structures.
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/ulp/ipoib/ipoib_verbs.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +9 -2
#   InfiniBand/ipoib: move structs from stack to device private struct
# 
# drivers/infiniband/ulp/ipoib/ipoib_multicast.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +4 -2
#   InfiniBand/ipoib: move structs from stack to device private struct
# 
# drivers/infiniband/ulp/ipoib/ipoib_ib.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +9 -21
#   InfiniBand/ipoib: move structs from stack to device private struct
# 
# drivers/infiniband/ulp/ipoib/ipoib.h
#   2005/01/15 14:01:50-08:00 roland@topspin.com +6 -4
#   InfiniBand/ipoib: move structs from stack to device private struct
# 
# ChangeSet
#   2005/01/15 15:19:44-08:00 roland@topspin.com 
#   [PATCH] InfiniBand: update copyrights for new year
#   
#   Update copyright line (files were modified in 2005).
#   
#   Signed-off-by: Hal Rosenstock <halr@voltaire.com>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/hw/mthca/mthca_provider.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +1 -1
#   InfiniBand: update copyrights for new year
# 
# drivers/infiniband/core/sysfs.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +1 -1
#   InfiniBand: update copyrights for new year
# 
# drivers/infiniband/core/mad_priv.h
#   2005/01/15 14:01:50-08:00 roland@topspin.com +1 -1
#   InfiniBand: update copyrights for new year
# 
# drivers/infiniband/core/mad.c
#   2005/01/15 14:47:30-08:00 roland@topspin.com +1 -1
#   InfiniBand: update copyrights for new year
# 
# ChangeSet
#   2005/01/15 15:19:30-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: add ib_find_cached_gid function
#   
#   Add a new function to find a port on a device given a GID by searching the
#   cached GID tables.  Document all cache functions in ib_cache.h.  Rename
#   existing functions to better match format of verb routines.
#   
#   Signed-off by: Sean Hefty <sean.hefty@intel.com>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/ulp/ipoib/ipoib_verbs.c
#   2005/01/15 14:47:30-08:00 roland@topspin.com +2 -2
#   InfiniBand/core: add ib_find_cached_gid function
# 
# drivers/infiniband/ulp/ipoib/ipoib_ib.c
#   2005/01/15 14:47:30-08:00 roland@topspin.com +1 -1
#   InfiniBand/core: add ib_find_cached_gid function
# 
# drivers/infiniband/include/ib_cache.h
#   2005/01/15 14:01:50-08:00 roland@topspin.com +56 -6
#   InfiniBand/core: add ib_find_cached_gid function
# 
# drivers/infiniband/hw/mthca/mthca_qp.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +2 -2
#   InfiniBand/core: add ib_find_cached_gid function
# 
# drivers/infiniband/hw/mthca/mthca_av.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +1 -1
#   InfiniBand/core: add ib_find_cached_gid function
# 
# drivers/infiniband/core/cache.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +50 -15
#   InfiniBand/core: add ib_find_cached_gid function
# 
# ChangeSet
#   2005/01/15 15:19:12-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: add qp_type to struct ib_qp
#   
#   Add qp_type to struct ib_qp.
#   
#   Signed-off by: Sean Hefty <sean.hefty@intel.com>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/include/ib_verbs.h
#   2005/01/15 14:01:50-08:00 roland@topspin.com +1 -0
#   InfiniBand/core: add qp_type to struct ib_qp
# 
# drivers/infiniband/core/verbs.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +1 -0
#   InfiniBand/core: add qp_type to struct ib_qp
# 
# ChangeSet
#   2005/01/15 15:18:57-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: add more parameters to process_mad
#   
#   Add parameters to process_mad device method to support full Mellanox firmware
#   capabilities (pass sufficient information for baseboard management trap
#   generation, etc).
#   
#   Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/include/ib_verbs.h
#   2005/01/15 14:47:31-08:00 roland@topspin.com +6 -2
#   InfiniBand/core: add more parameters to process_mad
# 
# drivers/infiniband/hw/mthca/mthca_mad.c
#   2005/01/15 14:01:50-08:00 roland@topspin.com +3 -1
#   InfiniBand/core: add more parameters to process_mad
# 
# drivers/infiniband/hw/mthca/mthca_dev.h
#   2005/01/15 14:01:50-08:00 roland@topspin.com +2 -1
#   InfiniBand/core: add more parameters to process_mad
# 
# drivers/infiniband/core/sysfs.c
#   2005/01/15 14:47:30-08:00 roland@topspin.com +2 -2
#   InfiniBand/core: add more parameters to process_mad
# 
# drivers/infiniband/core/mad.c
#   2005/01/15 14:47:30-08:00 roland@topspin.com +29 -15
#   InfiniBand/core: add more parameters to process_mad
# 
# ChangeSet
#   2005/01/15 15:18:41-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: fix handling of 0-hop directed route MADs
#   
#   Handle outgoing DR 0 hop SMPs properly when provider returns just SUCCESS to
#   process_mad.
#   
#   Signed-off-by: Hal Rosenstock <halr@voltaire.com>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/core/mad_priv.h
#   2005/01/15 14:47:30-08:00 roland@topspin.com +1 -0
#   InfiniBand/core: fix handling of 0-hop directed route MADs
# 
# drivers/infiniband/core/mad.c
#   2005/01/15 14:47:31-08:00 roland@topspin.com +52 -12
#   InfiniBand/core: fix handling of 0-hop directed route MADs
# 
# ChangeSet
#   2005/01/15 15:18:25-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/mthca: clean up computation of HCA memory map
#   
#   Clean up the computation of the HCA context memory map.  This serves two
#   purposes:
#   
#    - make it easier to change the HCA "profile" (eg add more QPs)
#    - make it easier to implement mem-free Arbel support
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/hw/mthca/mthca_profile.h
#   2005/01/15 14:01:49-08:00 roland@topspin.com +11 -15
#   InfiniBand/mthca: clean up computation of HCA memory map
# 
# drivers/infiniband/hw/mthca/mthca_profile.c
#   2005/01/15 14:01:49-08:00 roland@topspin.com +58 -33
#   InfiniBand/mthca: clean up computation of HCA memory map
# 
# drivers/infiniband/hw/mthca/mthca_main.c
#   2005/01/15 14:01:49-08:00 roland@topspin.com +20 -1
#   InfiniBand/mthca: clean up computation of HCA memory map
# 
# drivers/infiniband/hw/mthca/mthca_dev.h
#   2005/01/15 14:47:31-08:00 roland@topspin.com +5 -2
#   InfiniBand/mthca: clean up computation of HCA memory map
# 
# drivers/infiniband/hw/mthca/mthca_cmd.h
#   2005/01/15 14:01:49-08:00 roland@topspin.com +3 -3
#   InfiniBand/mthca: clean up computation of HCA memory map
# 
# drivers/infiniband/hw/mthca/mthca_cmd.c
#   2005/01/15 14:01:49-08:00 roland@topspin.com +5 -3
#   InfiniBand/mthca: clean up computation of HCA memory map
# 
# ChangeSet
#   2005/01/15 15:18:11-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: add node_type and phys_state sysfs attrs
#   
#   Add per-device "node_type" and per-port "phys_state" sysfs attributes for
#   InfiniBand devices.
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/include/ib_verbs.h
#   2005/01/15 14:47:31-08:00 roland@topspin.com +1 -0
#   InfiniBand/core: add node_type and phys_state sysfs attrs
# 
# drivers/infiniband/hw/mthca/mthca_provider.c
#   2005/01/15 14:47:30-08:00 roland@topspin.com +1 -0
#   InfiniBand/core: add node_type and phys_state sysfs attrs
# 
# drivers/infiniband/core/sysfs.c
#   2005/01/15 14:47:31-08:00 roland@topspin.com +39 -0
#   InfiniBand/core: add node_type and phys_state sysfs attrs
# 
# Documentation/infiniband/sysfs.txt
#   2005/01/15 14:01:49-08:00 roland@topspin.com +2 -0
#   InfiniBand/core: add node_type and phys_state sysfs attrs
# 
# ChangeSet
#   2005/01/15 15:17:56-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: add QP number to work completion struct
#   
#   InfiniBand spec rev 1.2 compliance: add local qp number to work completion
#   structure.
#   
#   Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/include/ib_verbs.h
#   2005/01/15 14:47:34-08:00 roland@topspin.com +1 -0
#   InfiniBand/core: add QP number to work completion struct
# 
# drivers/infiniband/hw/mthca/mthca_cq.c
#   2005/01/15 14:01:49-08:00 roland@topspin.com +2 -0
#   InfiniBand/core: add QP number to work completion struct
# 
# drivers/infiniband/core/mad.c
#   2005/01/15 14:47:32-08:00 roland@topspin.com +1 -0
#   InfiniBand/core: add QP number to work completion struct
# 
# ChangeSet
#   2005/01/15 15:17:42-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: set byte_cnt correctly in MAD completion
#   
#   Integrate Michael Tsirkin's patch to local_completion to set the WC byte_cnt
#   according to the IBA 1.1 spec (include the GRH size regardless of whether it
#   is present or not).
#   
#   Signed-off-by: Hal Rosenstock <halr@voltaire.com>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/core/mad.c
#   2005/01/15 14:47:34-08:00 roland@topspin.com +3 -2
#   InfiniBand/core: set byte_cnt correctly in MAD completion
# 
# ChangeSet
#   2005/01/15 15:17:25-08:00 roland@topspin.com 
#   [PATCH] InfiniBand: make more code static
#   
#   Make needlessly global code static.
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/ulp/ipoib/ipoib_multicast.c
#   2005/01/15 14:47:30-08:00 roland@topspin.com +2 -2
#   InfiniBand: make more code static
# 
# drivers/infiniband/ulp/ipoib/ipoib_main.c
#   2005/01/15 14:01:48-08:00 roland@topspin.com +1 -1
#   InfiniBand: make more code static
# 
# drivers/infiniband/ulp/ipoib/ipoib_ib.c
#   2005/01/15 14:47:31-08:00 roland@topspin.com +1 -1
#   InfiniBand: make more code static
# 
# drivers/infiniband/core/cache.c
#   2005/01/15 14:47:31-08:00 roland@topspin.com +3 -3
#   InfiniBand: make more code static
# 
# ChangeSet
#   2005/01/15 15:17:11-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/core: remove debug printk
#   
#   Remove debug printk accidentally included.
#   
#   Signed-off-by: Tom Duffy <tduffy@sun.com>
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/core/sysfs.c
#   2005/01/15 14:47:34-08:00 roland@topspin.com +0 -2
#   InfiniBand/core: remove debug printk
# 
# ChangeSet
#   2005/01/15 15:16:54-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/mthca: add needed rmb() in event queue poll
#   
#   Add an rmb() between checking the ownership bit of an event queue entry and
#   reading the contents of the EQE.  Without this barrier, the CPU could read
#   stale contents of the EQE before HW writes the EQE but have the read of the
#   ownership bit reordered until after HW finishes writing, which leads to the
#   driver processing an incorrect event.  This was actually observed to happen
#   when multiple completion queues are in heavy use on an IBM JS20 PowerPC 970
#   system.
#   
#   Also explain the existing rmb() in completion queue poll (there for the same
#   reason) and slightly improve debugging output.
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/hw/mthca/mthca_eq.c
#   2005/01/15 14:01:47-08:00 roland@topspin.com +7 -1
#   InfiniBand/mthca: add needed rmb() in event queue poll
# 
# drivers/infiniband/hw/mthca/mthca_cq.c
#   2005/01/15 14:47:34-08:00 roland@topspin.com +7 -2
#   InfiniBand/mthca: add needed rmb() in event queue poll
# 
# ChangeSet
#   2005/01/15 15:16:40-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/mthca: clean up allocation mapping of HCA context memory
#   
#   Clean up the way we allocate and map memory for use as ICM ("InfiniHost
#   Context Memory") when running in Arbel MemFree mode.  This slightly improves
#   the code for mapping the firmware area and will make future progress towards
#   full MemFree support much easier.
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/hw/mthca/mthca_memfree.h
#   2005/01/15 14:01:47-08:00 roland@topspin.com +107 -0
#   InfiniBand/mthca: clean up allocation mapping of HCA context memory
# 
# drivers/infiniband/hw/mthca/mthca_memfree.c
#   2005/01/15 14:01:47-08:00 roland@topspin.com +133 -0
#   InfiniBand/mthca: clean up allocation mapping of HCA context memory
# 
# drivers/infiniband/hw/mthca/mthca_memfree.h
#   2005/01/15 14:01:47-08:00 roland@topspin.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/infiniband/hw/mthca/mthca_memfree.h
# 
# drivers/infiniband/hw/mthca/mthca_memfree.c
#   2005/01/15 14:01:47-08:00 roland@topspin.com +0 -0
#   BitKeeper file /home/torvalds/v2.6/linux/drivers/infiniband/hw/mthca/mthca_memfree.c
# 
# drivers/infiniband/hw/mthca/mthca_main.c
#   2005/01/15 14:47:33-08:00 roland@topspin.com +15 -75
#   InfiniBand/mthca: clean up allocation mapping of HCA context memory
# 
# drivers/infiniband/hw/mthca/mthca_dev.h
#   2005/01/15 14:47:33-08:00 roland@topspin.com +1 -2
#   InfiniBand/mthca: clean up allocation mapping of HCA context memory
# 
# drivers/infiniband/hw/mthca/mthca_cmd.h
#   2005/01/15 14:47:33-08:00 roland@topspin.com +1 -2
#   InfiniBand/mthca: clean up allocation mapping of HCA context memory
# 
# drivers/infiniband/hw/mthca/mthca_cmd.c
#   2005/01/15 14:47:33-08:00 roland@topspin.com +12 -11
#   InfiniBand/mthca: clean up allocation mapping of HCA context memory
# 
# drivers/infiniband/hw/mthca/Makefile
#   2005/01/15 14:01:47-08:00 roland@topspin.com +1 -1
#   InfiniBand/mthca: clean up allocation mapping of HCA context memory
# 
# ChangeSet
#   2005/01/15 15:16:23-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/mthca: support RDMA/atomic attributes in QP modify
#   
#   Implement setting of RDMA/atomic enable bits, initiator resources and
#   responder resources for modify QP in low-level Mellanox HCA driver (should
#   complete RDMA/atomic implementation).
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/hw/mthca/mthca_qp.c
#   2005/01/15 14:47:31-08:00 roland@topspin.com +81 -4
#   InfiniBand/mthca: support RDMA/atomic attributes in QP modify
# 
# drivers/infiniband/hw/mthca/mthca_provider.h
#   2005/01/15 14:01:45-08:00 roland@topspin.com +5 -2
#   InfiniBand/mthca: support RDMA/atomic attributes in QP modify
# 
# drivers/infiniband/hw/mthca/mthca_profile.c
#   2005/01/15 14:47:33-08:00 roland@topspin.com +7 -3
#   InfiniBand/mthca: support RDMA/atomic attributes in QP modify
# 
# drivers/infiniband/hw/mthca/mthca_dev.h
#   2005/01/15 14:47:35-08:00 roland@topspin.com +3 -1
#   InfiniBand/mthca: support RDMA/atomic attributes in QP modify
# 
# ChangeSet
#   2005/01/15 15:16:11-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/mthca: trivial formatting fix
#   
#   Trivial formatting fix for empty for loops.
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/hw/mthca/mthca_mr.c
#   2005/01/15 14:01:45-08:00 roland@topspin.com +2 -2
#   InfiniBand/mthca: trivial formatting fix
# 
# ChangeSet
#   2005/01/15 15:15:55-08:00 roland@topspin.com 
#   [PATCH] InfiniBand/IPoIB: use correct static rate in IpoIB
#   
#   Calculate static rate for IPoIB address handles based on local width/speed and
#   path rate.
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/infiniband/ulp/ipoib/ipoib_multicast.c
#   2005/01/15 14:47:34-08:00 roland@topspin.com +20 -18
#   InfiniBand/IPoIB: use correct static rate in IpoIB
# 
# drivers/infiniband/ulp/ipoib/ipoib_main.c
#   2005/01/15 14:47:34-08:00 roland@topspin.com +9 -9
#   InfiniBand/IPoIB: use correct static rate in IpoIB
# 
# drivers/infiniband/ulp/ipoib/ipoib.h
#   2005/01/15 14:47:30-08:00 roland@topspin.com +1 -0
#   InfiniBand/IPoIB: use correct static rate in IpoIB
# 
# drivers/infiniband/include/ib_sa.h
#   2005/01/15 14:01:45-08:00 roland@topspin.com +28 -0
#   InfiniBand/IPoIB: use correct static rate in IpoIB
# 
# ChangeSet
#   2005/01/15 15:15:41-08:00 James.Bottomley@SteelEye.com 
#   [PATCH] generic irq code missing export of probe_irq_mask()
#   
#   Matthew Wilcox just converted parisc over to doing the generic irq code and
#   we ran across the symbol probe_irq_mask being undefined (and thus
#   preventing yenta_socket from loading).
#   
#   It looks like the EXPORT_SYMBOL() was accidentally missed from
#   kernel/irq/autoprobe.c and no-one noticed on x86 because it's still in
#   i386_ksyms.c
#   
#   This patch corrects the problem so that the generic irq code now works
#   completely on parisc.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/irq/autoprobe.c
#   2005/01/15 14:01:45-08:00 James.Bottomley@SteelEye.com +1 -0
#   generic irq code missing export of probe_irq_mask()
# 
# arch/i386/kernel/i386_ksyms.c
#   2005/01/15 14:01:45-08:00 James.Bottomley@SteelEye.com +0 -1
#   generic irq code missing export of probe_irq_mask()
# 
# ChangeSet
#   2005/01/15 15:15:25-08:00 sds@epoch.ncsc.mil 
#   [PATCH] SELinux: fix setting of loaded policy version
#   
#   This patch fixes a different bug in the code for SELinux policy loading.
#   It ensures that the loaded policy version number is not updated until the
#   new policy is successfully committed.  It also fixes the type on the loaded
#   policy version.
#   
#   Signed-off-by: Stephen Smalley <sds@epoch.ncsc.mil>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# security/selinux/ss/services.c
#   2005/01/15 14:01:45-08:00 sds@epoch.ncsc.mil +3 -2
#   SELinux: fix setting of loaded policy version
# 
# security/selinux/ss/policydb.h
#   2005/01/15 14:01:45-08:00 sds@epoch.ncsc.mil +2 -0
#   SELinux: fix setting of loaded policy version
# 
# security/selinux/ss/policydb.c
#   2005/01/15 14:01:45-08:00 sds@epoch.ncsc.mil +7 -10
#   SELinux: fix setting of loaded policy version
# 
# security/selinux/hooks.c
#   2005/01/15 14:01:45-08:00 sds@epoch.ncsc.mil +1 -1
#   SELinux: fix setting of loaded policy version
# 
# ChangeSet
#   2005/01/15 15:15:09-08:00 sds@epoch.ncsc.mil 
#   [PATCH] SELinux: fix error handling code for policy load
#   
#   This patch fixes several bugs in the error handling code for SELinux policy
#   loading that were introduced by my earlier patch to eliminate unaligned
#   accesses by that code.
#   
#   Signed-off-by:  Stephen Smalley <sds@epoch.ncsc.mil>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# security/selinux/ss/policydb.c
#   2005/01/15 14:47:36-08:00 sds@epoch.ncsc.mil +7 -2
#   SELinux: fix error handling code for policy load
# 
# security/selinux/ss/ebitmap.c
#   2005/01/15 14:01:45-08:00 sds@epoch.ncsc.mil +4 -2
#   SELinux: fix error handling code for policy load
# 
# security/selinux/ss/avtab.c
#   2005/01/15 14:01:45-08:00 sds@epoch.ncsc.mil +3 -1
#   SELinux: fix error handling code for policy load
# 
# ChangeSet
#   2005/01/15 15:14:53-08:00 uweigand@de.ibm.com 
#   [PATCH] cputime: s/390: fix account_steal_time.
#   
#   account_steal_time called for idle doesn't work correctly:
#   1) steal time while idle needs to be added to the system time of idle
#      to get correct uptime numbers
#   3) if there is an i/o request outstanding the steal time should be
#      added to iowait, even if the hypervisor scheduled another virtual
#      cpu since we are still waiting for i/o.
#   2) steal time while idle without an i/o request outstanding has to
#      be added to cpustat->idle and not to cpustat->system.
#   
#   Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
#   Acked-by: Ingo Molnar <mingo@elte.hu>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/sched.c
#   2005/01/15 14:47:20-08:00 uweigand@de.ibm.com +9 -5
#   cputime: s/390: fix account_steal_time.
# 
# ChangeSet
#   2005/01/15 12:21:18-08:00 torvalds@ppc970.osdl.org 
#   Merge bk://linux-sam.bkbits.net/kconfig
#   into ppc970.osdl.org:/home/torvalds/v2.6/linux
# 
# mm/memory.c
#   2005/01/15 12:21:13-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# include/linux/mm.h
#   2005/01/15 12:21:13-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# include/asm-x86_64/page.h
#   2005/01/15 12:21:13-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# arch/x86_64/mm/init.c
#   2005/01/15 12:21:13-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/15 12:01:24-08:00 torvalds@ppc970.osdl.org 
#   Make pipe buffer handling more generic.
#   
#   Use a "pipe_buf_operations" structure to describe the ops that
#   can be done on a pipe buffer, so that pipe buffers from different
#   sources can have their own rules.
#   
#   Right now the rules are just about how you map the buffers into
#   kernel virtual memory space, and how to release them (and whether
#   you can append new data to the end of an existing buffer).
# 
# include/linux/pipe_fs_i.h
#   2005/01/15 12:01:16-08:00 torvalds@ppc970.osdl.org +9 -1
#   Make pipe buffer handling more generic.
#   
#   Use a "pipe_buf_operations" structure to describe the ops that
#   can be done on a pipe buffer, so that pipe buffers from different
#   sources can have their own rules.
#   
#   Right now the rules are just about how you map the buffers into
#   kernel virtual memory space, and how to release them (and whether
#   you can append new data to the end of an existing buffer).
# 
# fs/pipe.c
#   2005/01/15 12:01:16-08:00 torvalds@ppc970.osdl.org +34 -12
#   Make pipe buffer handling more generic.
#   
#   Use a "pipe_buf_operations" structure to describe the ops that
#   can be done on a pipe buffer, so that pipe buffers from different
#   sources can have their own rules.
#   
#   Right now the rules are just about how you map the buffers into
#   kernel virtual memory space, and how to release them (and whether
#   you can append new data to the end of an existing buffer).
# 
# ChangeSet
#   2005/01/15 10:07:46-08:00 torvalds@ppc970.osdl.org 
#   Merge bk://linux-dj.bkbits.net/cpufreq
#   into ppc970.osdl.org:/home/torvalds/v2.6/linux
# 
# MAINTAINERS
#   2005/01/15 10:07:42-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/15 10:07:05-08:00 matthew@wil.cx 
#   [PATCH] Make compat_rt_sigtimedwait conform
#   
#   Compat syscalls need to start compat_sys_ otherwise PA-RISC's compat
#   syscall wrappers don't work.  Not that the individual involved bothered
#   to patch PA-RISC ...
#   
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/compat.c
#   2005/01/14 11:56:08-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# arch/x86_64/ia32/ia32entry.S
#   2005/01/14 11:56:05-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# arch/sparc64/kernel/systbls.S
#   2005/01/14 11:56:05-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# arch/s390/kernel/syscalls.S
#   2005/01/14 11:56:05-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# arch/s390/kernel/compat_wrapper.S
#   2005/01/14 11:56:05-08:00 matthew@wil.cx +3 -3
#   Make compat_rt_sigtimedwait conform
# 
# arch/ppc64/kernel/misc.S
#   2005/01/14 11:56:04-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# arch/parisc/kernel/syscall_table.S
#   2005/01/14 11:56:04-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# arch/mips/kernel/scall64-o32.S
#   2005/01/14 11:56:04-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# arch/mips/kernel/scall64-n32.S
#   2005/01/14 11:56:04-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# arch/ia64/ia32/ia32_entry.S
#   2005/01/14 11:56:04-08:00 matthew@wil.cx +1 -1
#   Make compat_rt_sigtimedwait conform
# 
# ChangeSet
#   2005/01/15 09:40:45-08:00 mingo@elte.hu 
#   [PATCH] Don't busy-lock-loop in preemptable spinlocks
#   
#   Paul Mackerras points out that doing the _raw_spin_trylock each time
#   through the loop will generate tons of unnecessary bus traffic.
#   Instead, after we fail to get the lock we should poll it with simple
#   loads until we see that it is clear and then retry the atomic op. 
#   Assuming a reasonable cache design, the loads won't generate any bus
#   traffic until another cpu writes to the cacheline containing the lock.
#   
#   Agreed.
#   
#   Signed-off-by: Ingo Molnar <mingo@elte.hu>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# kernel/spinlock.c
#   2005/01/14 16:00:00-08:00 mingo@elte.hu +8 -6
#   Don't busy-lock-loop in preemptable spinlocks
# 
# ChangeSet
#   2005/01/15 11:51:45+00:00 rmk@flint.arm.linux.org.uk 
#   [SERIAL] Clarify documentation for set_termios and pm methods.
#   
#   Signed-off-by: Russell King <rmk@arm.linux.org.uk>
# 
# Documentation/serial/driver
#   2005/01/15 11:46:51+00:00 rmk@flint.arm.linux.org.uk +9 -2
#   Clarify set_termios and pm methods.
# 
# ChangeSet
#   2005/01/15 11:42:19+00:00 rmk@flint.arm.linux.org.uk 
#   [SERIAL] Fix serial console resume
#   
#   Don't use uart_change_speed() when trying to restore the serial
#   console settings - the port may not have a tty associated with
#   it.
#   
#   Signed-off-by: Russell King <rmk@arm.linux.org.uk>
# 
# drivers/serial/serial_core.c
#   2005/01/15 11:37:07+00:00 rmk@flint.arm.linux.org.uk +15 -1
#   Don't use uart_change_speed() when trying to restore the serial
#   console settings - the port may not have a tty associated with
#   it.
# 
# ChangeSet
#   2005/01/15 10:44:40+00:00 rmk@flint.arm.linux.org.uk 
#   [MMC] Add comment about GENHD_FL_REMOVABLE to mmc_block
#   
#   We don't set GENHD_FL_REMOVABLE because this flag indicates that
#   the media may be removed while the block device persists.  Since
#   MMC destroys the block device when the card (media + on-board
#   controller) is removed, the block device will never exist without
#   media present.  Therefore, setting GENHD_FL_REMOVABLE would be
#   misleading.
#   
#   Signed-off-by: Russell King <rmk@arm.linux.org.uk>
# 
# drivers/mmc/mmc_block.c
#   2005/01/15 10:39:22+00:00 rmk@flint.arm.linux.org.uk +12 -0
#   Add comment about GENHD_FL_REMOVABLE
# 
# ChangeSet
#   2005/01/14 20:41:55-08:00 herbert@gondor.apana.org.au 
#   [IPV6]: Fix locking in ip6_dst_lookup().
#   
#   The caller does not necessarily have the socket locked
#   (udpv6sendmsg() is one such case) so we have to use
#   sk_dst_check() instead of __sk_dst_check().
#   
#   Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv6/ip6_output.c
#   2005/01/14 20:41:34-08:00 herbert@gondor.apana.org.au +3 -3
#   [IPV6]: Fix locking in ip6_dst_lookup().
#   
#   The caller does not necessarily have the socket locked
#   (udpv6sendmsg() is one such case) so we have to use
#   sk_dst_check() instead of __sk_dst_check().
#   
#   Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/14 20:38:32-08:00 davem@nuts.davemloft.net 
#   [TCP]: Do not underflow sk_forward_alloc in sendpage().
#   
#   We need to do the proper checks before we try to
#   pull space out of it, just like sendmsg() does.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/tcp.c
#   2005/01/14 20:37:59-08:00 davem@nuts.davemloft.net +12 -6
#   [TCP]: Do not underflow sk_forward_alloc in sendpage().
# 
# ChangeSet
#   2005/01/15 03:30:53+01:00 bzolnier@trik.(none) 
#   [ide] kill default_{attach,cleanup}()
#   
#   Device drivers are supposed to provide their own ->attach and ->cleanup.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# drivers/ide/ide.c
#   2005/01/15 03:30:40+01:00 bzolnier@trik.(none) +2 -20
#   [ide] kill default_{attach,cleanup}()
# 
# drivers/ide/ide-default.c
#   2005/01/15 03:30:40+01:00 bzolnier@trik.(none) +1 -0
#   [ide] kill default_{attach,cleanup}()
# 
# ChangeSet
#   2005/01/15 03:21:57+01:00 bzolnier@trik.(none) 
#   [ide] ide-v10: use ide_dma_intr()
#   
#   Use now available ide_dma_intr() in etrax_dma_intr().
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# drivers/ide/cris/ide-v10.c
#   2005/01/09 21:15:06+01:00 bzolnier@trik.(none) +1 -18
#   [ide] ide-v10: use ide_dma_intr()
# 
# ChangeSet
#   2005/01/15 03:18:16+01:00 bzolnier@trik.(none) 
#   [ide] icside: use ide_dma_intr()
#   
#   Make ide_dma_intr() always available if CONFIG_BLK_DEV_IDEDMA=y
#   and use it instead of icside_dmaintr().  Acked by Russell.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# include/linux/ide.h
#   2005/01/09 21:06:39+01:00 bzolnier@trik.(none) +1 -1
#   [ide] icside: use ide_dma_intr()
# 
# drivers/ide/ide-dma.c
#   2005/01/09 21:06:39+01:00 bzolnier@trik.(none) +1 -1
#   [ide] icside: use ide_dma_intr()
# 
# drivers/ide/arm/icside.c
#   2005/01/09 21:06:39+01:00 bzolnier@trik.(none) +1 -30
#   [ide] icside: use ide_dma_intr()
# 
# ChangeSet
#   2005/01/15 03:11:30+01:00 bzolnier@trik.(none) 
#   [ide] kill ide_drive_t->suspend_reset
#   
#   This cruft pre-dates benh's PowerManagement code.
#   Moreover ->suspend_reset is always equal to zero.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# include/linux/ide.h
#   2005/01/09 20:54:36+01:00 bzolnier@trik.(none) +0 -1
#   [ide] kill ide_drive_t->suspend_reset
# 
# drivers/ide/ide.c
#   2005/01/09 20:54:36+01:00 bzolnier@trik.(none) +1 -13
#   [ide] kill ide_drive_t->suspend_reset
# 
# drivers/ide/ide-io.c
#   2005/01/09 20:54:36+01:00 bzolnier@trik.(none) +0 -7
#   [ide] kill ide_drive_t->suspend_reset
# 
# ChangeSet
#   2005/01/15 03:09:12+01:00 bzolnier@trik.(none) 
#   [ide] atiixp: add IXP400 support
#   
#   From: Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
#   
#   add IXP400 ID
#   
#   From: Frederick Li <fli@ati.com>
#   
#   update PCI IDs
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# include/linux/pci_ids.h
#   2005/01/15 03:09:01+01:00 bzolnier@trik.(none) +3 -2
#   [ide] atiixp: add IXP400 support
# 
# drivers/ide/pci/atiixp.c
#   2005/01/15 03:09:01+01:00 bzolnier@trik.(none) +3 -2
#   [ide] atiixp: add IXP400 support
# 
# ChangeSet
#   2005/01/15 02:49:16+01:00 bzolnier@trik.(none) 
#   [ide] piix: add Intel 82801DBL IDE Controller support
#   
#   From: Zhongjun, Wang <wangzhongjun@ccoss.com.cn>
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# include/linux/pci_ids.h
#   2005/01/15 02:49:03+01:00 bzolnier@trik.(none) +1 -0
#   [ide] piix: add Intel 82801DBL IDE Controller support
# 
# drivers/pci/pci.ids
#   2005/01/15 02:49:03+01:00 bzolnier@trik.(none) +1 -0
#   [ide] piix: add Intel 82801DBL IDE Controller support
# 
# drivers/ide/pci/piix.h
#   2005/01/15 02:49:03+01:00 bzolnier@trik.(none) +1 -0
#   [ide] piix: add Intel 82801DBL IDE Controller support
# 
# drivers/ide/pci/piix.c
#   2005/01/15 02:49:03+01:00 bzolnier@trik.(none) +3 -0
#   [ide] piix: add Intel 82801DBL IDE Controller support
# 
# ChangeSet
#   2005/01/15 02:31:51+01:00 bzolnier@trik.(none) 
#   [ide] suppress output of error messages for non-existant interfaces
#   
#   From: Prarit Bhargava <prarit@sgi.com>
#   
#   Suppress output of "Wait for ready failed before probe !" messages for 
#   non-existant interfaces.
#   
#   Please see 
#   http://marc.theaimsgroup.com/?l=linux-ide&m=110553792013649&w=2 for 
#   further context on this patch.
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# drivers/ide/ide-probe.c
#   2005/01/12 15:01:25+01:00 bzolnier@trik.(none) +1 -1
#   [ide] suppress output of error messages for non-existant interfaces
# 
# ChangeSet
#   2005/01/15 02:16:30+01:00 bzolnier@trik.(none) 
#   [ide] make try_to_flush_leftover_data() static
#   
#   Hi,
#   
#   now that you cleaned up the ide-io.c code to be all in the right file,
#   try_to_flush_leftover_data can become static since all users are in this
#   file now.
#   
#   bart: also remove declaration from <linux/ide.h>
#   
#   Signed-off-by: Arjan van de Ven <arjan@infradead.org>
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# include/linux/ide.h
#   2005/01/15 02:16:18+01:00 bzolnier@trik.(none) +0 -2
#   [ide] make try_to_flush_leftover_data() static
# 
# drivers/ide/ide-io.c
#   2005/01/15 02:16:18+01:00 bzolnier@trik.(none) +1 -3
#   [ide] make try_to_flush_leftover_data() static
# 
# ChangeSet
#   2005/01/15 02:06:28+01:00 bzolnier@trik.(none) 
#   [ide] ide_dump_atapi_status() printk readability fix
#   
#   From: Gunther Mayer <gunther.mayer@gmx.net>
#   
#   this improves logic and readability:
#   - remove blank from: AbortedCommand (as other flags)
#   - add blank and {} to error= line
#   - clean up: remove 2 lines and extra printk
#   
#   before:
#     hdd: status error: status=0x7f { DriveReady DeviceFault SeekComplete 
#   DataRequest CorrectedError Index Error }
#     hdd: status error: error=0x7fIllegalLengthIndication EndOfMedia 
#   Aborted Command MediaChangeRequested LastFailedSense 0x07
#   
#   after:
#     hdd: status error: status=0x7f { DriveReady DeviceFault SeekComplete 
#   DataRequest CorrectedError Index Error }
#     hdd: status error: error=0x7f { IllegalLengthIndication EndOfMedia 
#   AbortedCommand MediaChangeRequested LastFailedSense=0x07 }
#   
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# drivers/ide/ide-lib.c
#   2005/01/09 01:04:36+01:00 bzolnier@trik.(none) +6 -8
#   [ide] ide_dump_atapi_status() printk readability fix
# 
# ChangeSet
#   2005/01/15 01:56:21+01:00 bzolnier@trik.(none) 
#   [ide] ide-cd: use ssleep() instead of schedule_timeout()
#   
#   Description: Uses ssleep() in place of cdrom_sleep() to guarantee the task
#   delays as expected. Remove cdrom_sleep() definition, as this is the only place
#   where it is called.
#   
#   Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
#   Acked-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
# 
# drivers/ide/ide-cd.c
#   2005/01/05 23:23:05+01:00 bzolnier@trik.(none) +1 -14
#   [ide] ide-cd: use ssleep() instead of schedule_timeout()
# 
# ChangeSet
#   2005/01/14 16:27:59-08:00 greg@kroah.com 
#   [PATCH] USB: give the idmouse the 132 minor number
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/misc/idmouse.c
#   2005/01/14 16:00:51-08:00 greg@kroah.com +1 -1
#   USB: give the idmouse the 132 minor number
# 
# Documentation/devices.txt
#   2005/01/14 16:00:51-08:00 greg@kroah.com +1 -0
#   USB: give the idmouse the 132 minor number
# 
# ChangeSet
#   2005/01/14 16:27:34-08:00 arekm@pld-linux.org 
#   [PATCH] USB: add Ever UPS vendor/product id to ftdi_sio driver
#   
#   This patch allows to use ftdi_sio driver with Ever ECO Pro CDS UPS.
#   Patch was tested on pre-2.6.10 kernel.
#   
#   Signed-Off: Arkadiusz Miskiewicz <arekm@pld-linux.org>
# 
# drivers/usb/serial/ftdi_sio.h
#   2005/01/14 16:00:58-08:00 arekm@pld-linux.org +6 -0
#   USB: add Ever UPS vendor/product id to ftdi_sio driver
# 
# drivers/usb/serial/ftdi_sio.c
#   2005/01/14 16:00:58-08:00 arekm@pld-linux.org +3 -0
#   USB: add Ever UPS vendor/product id to ftdi_sio driver
# 
# ChangeSet
#   2005/01/14 16:26:59-08:00 greg@kroah.com 
#   [PATCH] USB: fix sparse warnings in the idmouse.c driver
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/misc/idmouse.c
#   2005/01/14 16:01:06-08:00 greg@kroah.com +3 -3
#   USB: fix sparse warnings in the idmouse.c driver
# 
# ChangeSet
#   2005/01/14 16:26:22-08:00 echtler@fs.tum.de 
#   [PATCH] USB: add driver for the Siemens ID Mouse fingerprint sensor
#   
#   This patch adds a new usb-misc driver for the fingerprint sensor that
#   can be found in the Siemens ID Mouse USB. "cat /dev/usb/idmouseX"
#   yields a 225x288 greyscale PNM with the fingerprint information.
#   
#   It's now in version 0.5, which uses memcpy() instead of snprintf()
#   and allows interruption of the image acquisition process, in case
#   it should get stuck.
#   
#   It may be considered controversial that it outputs a PNM instead
#   of raw data, but I hold the opinion that the 15 bytes of header,
#   "P5 225 288 256 ", do not do any harm and allow the device to be
#   used in shell scripts or similar, too.
#   
#   The setup packets are not described further, simply because I don"t
#   know anything about them myself. We captured them under Windows
#   using SnoopyPro.
#   
#   Please include this into the main USB kernel tree - I think it has
#   by now been scrutinized and tested quite thoroughly.
#   
#   Signed-off-by: Florian Echtler  <echtler@fs.tum.de>
#   Signed-off-by: Andreas Deresch <aderesch@fs.tum.de>
# 
# drivers/usb/misc/idmouse.c
#   2005/01/14 16:01:13-08:00 echtler@fs.tum.de +442 -0
#   USB: add driver for the Siemens ID Mouse fingerprint sensor
# 
# drivers/usb/misc/idmouse.c
#   2005/01/14 16:01:13-08:00 echtler@fs.tum.de +0 -0
#   BitKeeper file /home/greg/linux/BK/usb-2.6/drivers/usb/misc/idmouse.c
# 
# drivers/usb/misc/Makefile
#   2005/01/14 16:01:13-08:00 echtler@fs.tum.de +1 -0
#   USB: add driver for the Siemens ID Mouse fingerprint sensor
# 
# drivers/usb/misc/Kconfig
#   2005/01/14 16:01:13-08:00 echtler@fs.tum.de +14 -0
#   USB: add driver for the Siemens ID Mouse fingerprint sensor
# 
# drivers/usb/Makefile
#   2005/01/14 16:01:13-08:00 echtler@fs.tum.de +1 -0
#   USB: add driver for the Siemens ID Mouse fingerprint sensor
# 
# ChangeSet
#   2005/01/14 16:25:53-08:00 stern@rowland.harvard.edu 
#   [PATCH] USB: correct and clarify error-code documentation
#   
#   This patch corrects some misconceptions that have persisted in the USB
#   error-code documentation for quite some time.
#   
#   Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# Documentation/usb/error-codes.txt
#   2005/01/14 16:01:20-08:00 stern@rowland.harvard.edu +13 -4
#   USB: correct and clarify error-code documentation
# 
# ChangeSet
#   2005/01/14 16:25:32-08:00 petkan@nucleusys.com 
#   [PATCH] pegasus 2.6.10 cset
#   
#   Various fixes to the 'pegasus' driver, notably fixing OSDL bugid #3978
#   so this can be used with bridges again (or for that matter, other
#   normal usage).
#   
#       * Bugfixes in the status urb completion handler:
#   
#           - Never use garbage that happens to be sitting in the URB
#             data buffer to change the carrier status.
#   
#   
#           - There are two bits which claim to report parts of carrier
#             detect bit.  This switches to the one that works sometimes;
#             monitoring through MII might be the best solution.
#   
#           - Stop log spamming ... at least some of these chips seem
#             to get confused about data toggle, no point in warning
#             about each packet error as it's detected.
#   
#       * Report the normal Ethernet MTU.
#   
#       * Better ethtool support:
#   
#           - Save the message level set by userspace
#           - Basic WOL support
#   
#       * Add USB suspend() and resume() methods, to go with WOL.
#         Modeled on what stir4200 does.
#   
#   Also, some of the messages are converted to the more conventional
#   style:  "ethN: message text", or driver model style before the
#   device is registered.
#   
#   	* removed redundant MII code since CONFIG_MII is always set by Kconfig;
#     	* updated the version string;
#   
#   Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
#   Signed-off-by: Petko Manolov <petkan@nucleusys.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/net/pegasus.h
#   2005/01/14 16:01:29-08:00 petkan@nucleusys.com +3 -0
#   pegasus 2.6.10 cset
# 
# drivers/usb/net/pegasus.c
#   2005/01/14 16:01:29-08:00 petkan@nucleusys.com +114 -90
#   pegasus 2.6.10 cset
# 
# ChangeSet
#   2005/01/14 16:25:08-08:00 luca.risolia@studio.unibo.it 
#   [PATCH] USB: SN9C10x driver updates
#   
#   SN9C10x driver updates.
#   
#   Changes:
#   
#   @ Fix the sysfs interface
#   @ Fix allocated minor number after device detection
#   + Add "force_munmap" module parameter
#   + Documentation updates
#   + Add support for old VIDIOC_S_PARM_OLD and VIDIOC_S_CTRL_OLD ioctl's
#   
#   Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/media/sn9c102_tas5130d1b.c
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +1 -1
#   USB: SN9C10x driver updates
# 
# drivers/usb/media/sn9c102_tas5110c1b.c
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +1 -1
#   USB: SN9C10x driver updates
# 
# drivers/usb/media/sn9c102_sensor.h
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +1 -1
#   USB: SN9C10x driver updates
# 
# drivers/usb/media/sn9c102_pas106b.c
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +1 -1
#   USB: SN9C10x driver updates
# 
# drivers/usb/media/sn9c102_mi0343.c
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +1 -1
#   USB: SN9C10x driver updates
# 
# drivers/usb/media/sn9c102_hv7131d.c
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +1 -1
#   USB: SN9C10x driver updates
# 
# drivers/usb/media/sn9c102_core.c
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +67 -29
#   USB: SN9C10x driver updates
# 
# drivers/usb/media/sn9c102.h
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +10 -3
#   USB: SN9C10x driver updates
# 
# Documentation/usb/sn9c102.txt
#   2005/01/14 16:01:37-08:00 luca.risolia@studio.unibo.it +17 -6
#   USB: SN9C10x driver updates
# 
# ChangeSet
#   2005/01/14 16:24:46-08:00 tglx@linutronix.de 
#   [PATCH] USB: Lock initializer cleanup - batch 4
#   
#   Use the new lock initializers DEFINE_SPIN_LOCK and DEFINE_RW_LOCK
#   
#   Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/core/hub.c
#   2005/01/14 16:01:44-08:00 tglx@linutronix.de +2 -2
#   USB: Lock initializer cleanup - batch 4
# 
# drivers/usb/core/hcd.c
#   2005/01/14 16:01:44-08:00 tglx@linutronix.de +1 -1
#   USB: Lock initializer cleanup - batch 4
# 
# drivers/usb/core/file.c
#   2005/01/14 16:01:44-08:00 tglx@linutronix.de +1 -1
#   USB: Lock initializer cleanup - batch 4
# 
# ChangeSet
#   2005/01/14 16:24:23-08:00 david-b@pacbell.net 
#   [PATCH] USB: usbnet:  Olympus R1000 PDA, and blacklisting if CDC && !ZAURUS
#   
#   Add support for the Zaurus-compatible configuration of the
#   Olympus R1000 PDA.  (IDs from Todd Blumer, todd@sdgsystems.com)
#   
#   Resolve a FIXME:  all the Zaurus support morphs into blacklist
#   entries when CDC Ethernet is enabled and Zaurus isn't (since the
#   Zaurus firmware falsely advertises itself as CDC conformant).
#   
#   Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/net/usbnet.c
#   2005/01/14 16:01:50-08:00 david-b@pacbell.net +56 -36
#   USB: usbnet:  Olympus R1000 PDA, and blacklisting if CDC && !ZAURUS
# 
# ChangeSet
#   2005/01/14 16:24:01-08:00 adobriyan@mail.ru 
#   [PATCH] USB: drivers/usb/*: s/0/NULL/ in pointer context
#   
#   Signed-off-by: Alexey Dobriyan <adobriyan@mail.ru>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/serial/keyspan.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +3 -3
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/serial/garmin_gps.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +4 -4
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/net/usbnet.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +5 -4
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/misc/usbtest.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +2 -2
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/input/hid-core.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +1 -1
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/image/mdc800.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +2 -2
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/host/sl811-hcd.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +1 -1
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/host/ehci-sched.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +13 -13
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/host/ehci-q.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +7 -7
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/host/ehci-mem.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +4 -4
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/host/ehci-hcd.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +1 -1
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/core/message.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +2 -2
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/core/hub.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +3 -3
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/core/hcd.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +1 -1
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/core/devio.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +3 -3
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# drivers/usb/class/usblp.c
#   2005/01/14 16:01:56-08:00 adobriyan@mail.ru +1 -1
#   USB: drivers/usb/*: s/0/NULL/ in pointer context
# 
# ChangeSet
#   2005/01/14 16:23:35-08:00 stern@rowland.harvard.edu 
#   [PATCH] USB UHCI: protect DMA-able fields with barriers
#   
#   This is a revised patch to fix a problem in the UHCI driver, in which the
#   compiler incorrectly optimizes certain accesses to DMA-able memory
#   addresses.  The patch reorganizes the code to use special accessor
#   routines including a compiler optimization barrier, and stores the results
#   in local variables to help prevent repeated accesses.  No use is made of
#   the "volatile" keyword.  :-)
#   
#   Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/host/uhci-hcd.h
#   2005/01/14 16:02:02-08:00 stern@rowland.harvard.edu +23 -1
#   USB UHCI: protect DMA-able fields with barriers
# 
# drivers/usb/host/uhci-hcd.c
#   2005/01/14 16:02:02-08:00 stern@rowland.harvard.edu +27 -17
#   USB UHCI: protect DMA-able fields with barriers
# 
# drivers/usb/host/uhci-debug.c
#   2005/01/14 16:02:02-08:00 stern@rowland.harvard.edu +8 -7
#   USB UHCI: protect DMA-able fields with barriers
# 
# ChangeSet
#   2005/01/14 16:23:14-08:00 zaitcev@redhat.com 
#   [PATCH] USB: Patch to fix ub looping with a tag mismatch
#   
#   If a command times out, we resubmit a retry. Some devices, however, buffer
#   everything we send and then eventually reply to a command we have timed out
#   already. We receive a bad tag, send a new command, device replies to the
#   one sent before, and so on without end.
#   
#   The fix is to flush pending replies if tags mismatch (by reading them).
#   
#   Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/block/ub.c
#   2005/01/14 16:02:07-08:00 zaitcev@redhat.com +44 -42
#   USB: Patch to fix ub looping with a tag mismatch
# 
# ChangeSet
#   2005/01/14 16:22:51-08:00 phil@ipom.com 
#   [PATCH] USB unusual_devs addition: Ignore residue for ours-tech disk
#   
#   This "Ours Technology" device incorrectly reports 100% residue on transferred data.
#   Patch originally sent by Daniel Drake <dsd@gentoo.org>, with slight modification by me.
#   
#   Signed-off-by: Daniel Drake <dsd@gentoo.org>
#   Signed-off-by: Phil Dibowitz <phil@ipom.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/storage/unusual_devs.h
#   2005/01/14 16:02:13-08:00 phil@ipom.com +8 -0
#   USB unusual_devs addition: Ignore residue for ours-tech disk
# 
# ChangeSet
#   2005/01/14 16:22:30-08:00 lmendez19@austin.rr.com 
#   [PATCH] USB cypress_m8: line setting bugfix, circular write buffer added, misc. fixes
#   
#   This patch brings up to date the driver with the current stable development
#   source.  A bug with RTS not raising upon first open was fixed, Al Borcher's
#   circular write buffer from the pl2303 driver was implemented, and various
#   fixes/cleanups were made.
#   
#   Signed-off-by: Lonnie Mendez <lmendez19@austin.rr.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/serial/cypress_m8.c
#   2005/01/14 16:02:19-08:00 lmendez19@austin.rr.com +465 -149
#   USB cypress_m8: line setting bugfix, circular write buffer added, misc. fixes
# 
# ChangeSet
#   2005/01/14 16:22:09-08:00 oliver@neukum.org 
#   [PATCH] USB: CDC ACM module and Zoom 2985 modem
#   
#   there's a bug in the acm driver's work arounds. This fixes it.
#   
#   Signed-Off-By: Oliver Neukum <oliver@neukum.name>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/class/cdc-acm.c
#   2005/01/14 16:02:24-08:00 oliver@neukum.org +13 -10
#   USB: CDC ACM module and Zoom 2985 modem
# 
# ChangeSet
#   2005/01/14 16:21:39-08:00 greg@kroah.com 
#   [PATCH] USB: remove some unneeded exported symbols.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/usb/core/usb.c
#   2005/01/14 16:02:30-08:00 greg@kroah.com +1 -2
#   USB: remove some unneeded exported symbols.
# 
# drivers/usb/core/hub.c
#   2005/01/14 16:02:30-08:00 greg@kroah.com +0 -1
#   USB: remove some unneeded exported symbols.
# 
# drivers/usb/core/hcd.c
#   2005/01/14 16:02:30-08:00 greg@kroah.com +0 -3
#   USB: remove some unneeded exported symbols.
# 
# ChangeSet
#   2005/01/14 15:59:20-08:00 johnrose@austin.ibm.com 
#   [PATCH] PCI: fix release_pcibus_dev() crash
#   
#   During the course of a hotplug removal of a PCI bus, release_pcibus_dev()
#   attempts to remove attribute files from a kobject directory that no longer
#   exists.  This patch moves these calls to pci_remove_bus(), where they can work
#   as intended.
#   
#   Signed-off-by: John Rose <johnrose@austin.ibm.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/remove.c
#   2005/01/14 15:06:55-08:00 johnrose@austin.ibm.com +8 -5
#   PCI: fix release_pcibus_dev() crash
# 
# drivers/pci/probe.c
#   2005/01/14 15:06:55-08:00 johnrose@austin.ibm.com +3 -7
#   PCI: fix release_pcibus_dev() crash
# 
# drivers/pci/pci.h
#   2005/01/14 15:06:55-08:00 johnrose@austin.ibm.com +2 -0
#   PCI: fix release_pcibus_dev() crash
# 
# ChangeSet
#   2005/01/14 15:58:57-08:00 tglx@linutronix.de 
#   [PATCH] PCI: Lock initializer cleanup - batch 4
#   
#   Use the new lock initializers DEFINE_SPIN_LOCK and DEFINE_RW_LOCK
#   
#   Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/search.c
#   2005/01/14 15:07:00-08:00 tglx@linutronix.de +1 -1
#   PCI: Lock initializer cleanup - batch 4
# 
# drivers/pci/msi.c
#   2005/01/14 15:07:00-08:00 tglx@linutronix.de +1 -1
#   PCI: Lock initializer cleanup - batch 4
# 
# drivers/pci/access.c
#   2005/01/14 15:07:00-08:00 tglx@linutronix.de +1 -1
#   PCI: Lock initializer cleanup - batch 4
# 
# ChangeSet
#   2005/01/14 15:58:36-08:00 dhowells@redhat.com 
#   [PATCH] PCI: Downgrade printk that complains about unsupported PCI PM caps
#   
#   The attached patch downgrades to KERN_DEBUG level the printk that issues a
#   notification that an unsupported version of the PCI power management registers
#   has been encountered by pci_set_power_state().
#   
#   Signed-Off-By: David Howells <dhowells@redhat.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/pci.c
#   2005/01/14 15:07:06-08:00 dhowells@redhat.com +1 -1
#   PCI: Downgrade printk that complains about unsupported PCI PM caps
# 
# ChangeSet
#   2005/01/14 15:58:13-08:00 jbarnes@sgi.com 
#   [PATCH] PCI: rom.c cleanups
#   
#   Greg, here's some whitespace and long line cleanup I wanted to do last time I
#   touched rom.c, but forgot.  Does it look ok to you, Jon?
#   
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/rom.c
#   2005/01/14 15:07:12-08:00 jbarnes@sgi.com +41 -39
#   PCI: rom.c cleanups
# 
# ChangeSet
#   2005/01/14 15:57:49-08:00 roland@topspin.com 
#   [PATCH] PCI: Clean up printks in msi.c
#   
#   Add "PCI:" prefixes and fix up the formatting and grammar of printks
#   in drivers/pci/msi.c.  The main motivation was to fix the shouting
#   "MSI INIT SUCCESS" message printed when an MSI-using driver is first
#   started, but while we're at it we might as well tidy up all the messages.
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/pci/msi.c
#   2005/01/14 15:07:17-08:00 roland@topspin.com +20 -17
#   PCI: Clean up printks in msi.c
# 
# ChangeSet
#   2005/01/14 15:57:26-08:00 jason.d.gaston@intel.com 
#   [PATCH] PCI: pci_ids.h correction for Intel ICH7 - 2.6.10-bk13
#   
#   This patch corrects the ICH7 LPC controller DID in pci_ids.h from x27B0
#   to x27B8.  This patch was build against 2.6.10-bk13.
#   
#   Signed-off-by: Jason Gaston <Jason.d.gaston@intel.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pci_ids.h
#   2005/01/14 15:07:23-08:00 jason.d.gaston@intel.com +1 -1
#   PCI: pci_ids.h correction for Intel ICH7 - 2.6.10-bk13
# 
# ChangeSet
#   2005/01/14 15:56:59-08:00 bjorn.helgaas@hp.com 
#   [PATCH] PCI: use modern format for PCI addresses
#   
#   Use pci_name() rather than "%02x:%02x" when printing PCI
#   address information.
#   
#   Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# arch/i386/pci/pcbios.c
#   2005/01/14 15:07:29-08:00 bjorn.helgaas@hp.com +2 -2
#   PCI: use modern format for PCI addresses
# 
# ChangeSet
#   2005/01/14 15:56:18-08:00 tlnguyen@snoqualmie.dp.intel.com 
#   [PATCH] PCI: add PCI Express Port Bus Driver subsystem
#   
#   Signed-off-by: T. Long Nguyen <tom.l.nguyen@intel.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/pcieport_if.h
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +74 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/pcie/portdrv_pci.c
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +138 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/pcie/portdrv_core.c
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +453 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/pcie/portdrv_bus.c
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +88 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/pcie/portdrv.h
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +42 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/pcie/Makefile
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +7 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/pcie/Kconfig
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +38 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# include/linux/pcieport_if.h
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/include/linux/pcieport_if.h
# 
# drivers/pci/pcie/portdrv_pci.c
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/drivers/pci/pcie/portdrv_pci.c
# 
# drivers/pci/pcie/portdrv_core.c
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/drivers/pci/pcie/portdrv_core.c
# 
# drivers/pci/pcie/portdrv_bus.c
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/drivers/pci/pcie/portdrv_bus.c
# 
# drivers/pci/pcie/portdrv.h
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/drivers/pci/pcie/portdrv.h
# 
# drivers/pci/pcie/Makefile
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/drivers/pci/pcie/Makefile
# 
# drivers/pci/pcie/Kconfig
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/drivers/pci/pcie/Kconfig
# 
# drivers/pci/hotplug/pciehp_hpc.c
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +6 -15
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/hotplug/pciehp_core.c
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +55 -28
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/hotplug/pciehp.h
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +2 -1
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/pci/hotplug/Kconfig
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -21
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# drivers/Makefile
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +1 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# arch/i386/Kconfig
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +2 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# Documentation/PCIEBUS-HOWTO.txt
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +217 -0
#   PCI: add PCI Express Port Bus Driver subsystem
# 
# Documentation/PCIEBUS-HOWTO.txt
#   2005/01/14 15:07:35-08:00 tlnguyen@snoqualmie.dp.intel.com +0 -0
#   BitKeeper file /home/greg/linux/BK/pci-2.6/Documentation/PCIEBUS-HOWTO.txt
# 
# ChangeSet
#   2005/01/14 15:01:17-08:00 johnpol@2ka.mipt.ru 
#   [PATCH] w1: add ->search() method.
#   
#   Patch allows w1_search() to be overwritten by bus_master drivers.
#   It is very usefull for several devices, like found in iPaq w1 bus master,
#   which does not support bit operations but has hardware implemented
#   search algorithm.
#   
#   Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/w1/w1_io.h
#   2005/01/14 14:17:56-08:00 johnpol@2ka.mipt.ru +1 -0
#   w1: add ->search() method.
# 
# drivers/w1/w1_io.c
#   2005/01/14 14:17:56-08:00 johnpol@2ka.mipt.ru +10 -0
#   w1: add ->search() method.
# 
# drivers/w1/w1.h
#   2005/01/14 14:17:56-08:00 johnpol@2ka.mipt.ru +5 -0
#   w1: add ->search() method.
# 
# drivers/w1/w1.c
#   2005/01/14 14:17:56-08:00 johnpol@2ka.mipt.ru +69 -36
#   w1: add ->search() method.
# 
# ChangeSet
#   2005/01/14 14:45:49-08:00 galak@somerset.sps.mot.com 
#   [PATCH] I2C-MPC: Convert to platform_device driver
#   
#   Converted the driver to work as either a OCP or platform_device driver.
#   The intent in the future (once we convert all PPC sub-archs from OCP to
#   platform_device) is to remove the OCP code.
#   
#   Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/busses/i2c-mpc.c
#   2005/01/14 14:17:16-08:00 galak@somerset.sps.mot.com +122 -13
#   I2C-MPC: Convert to platform_device driver
# 
# drivers/i2c/busses/Kconfig
#   2005/01/14 14:17:16-08:00 galak@somerset.sps.mot.com +1 -1
#   I2C-MPC: Convert to platform_device driver
# 
# ChangeSet
#   2005/01/14 14:44:42-08:00 galak@somerset.sps.mot.com 
#   [PATCH] I2C-MPC: use wait_event_interruptible_timeout between transactions
#   
#   Use wait_event_interruptible_timeout so we dont waste time waiting between
#   transactions like we use to.  Also, we use the adapters timeout so the
#   ioctl cmd I2C_TIMEOUT will now work.
#   
#   Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/busses/i2c-mpc.c
#   2005/01/14 14:17:22-08:00 galak@somerset.sps.mot.com +15 -21
#   I2C-MPC: use wait_event_interruptible_timeout between transactions
# 
# ChangeSet
#   2005/01/14 14:44:10-08:00 khali@linux-fr.org 
#   [PATCH] I2C: Improve it87 super-i/o detection
#   
#   This patch improves the detection of Super-I/O it87 chips (IT8712F,
#   IT8705F).
#   
#   * Find the IT8712F and IT8705F address through Super-I/O (as opposed to
#     IT8712F only so far).
#   
#   * Verify that the device is activated. Print info lines if a
#     disactivated or unconfigured chip is found.
#   
#   * Print an info line when finding either chip, with device name,
#     address and revision.
#   
#   * Rearrange code in it87_find() (error path).
#   
#   * (bonus) Get rid of the useless i2c_client id.
#   
#   Successfully tested on two IT8712F and one IT8705F, thanks to Jonas
#   Munsin, Rudolf Marek and Karine Proot.
#   
#   Signed-off-by: Jean Delvare <khali@linux-fr.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/chips/it87.c
#   2005/01/14 14:17:28-08:00 khali@linux-fr.org +33 -20
#   I2C: Improve it87 super-i/o detection
# 
# ChangeSet
#   2005/01/14 14:43:50-08:00 rafael.espindola@gmail.com 
#   [PATCH] I2C: add EMC6D100 support in lm85 driver
#   
#   I have ported the support for the EMC6D100 sensor from kernel 2.4 to kernel
#   2.6. In the process I received some comments from Jean Delvare.
#   
#   Signed-off-by: Rafael Ãvila de EspÃ­ndola <rafael.espindola@gmail.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/chips/lm85.c
#   2005/01/14 14:17:33-08:00 rafael.espindola@gmail.com +62 -14
#   I2C: add EMC6D100 support in lm85 driver
# 
# ChangeSet
#   2005/01/14 14:43:30-08:00 jmunsin@iki.fi 
#   [PATCH] I2C: fix it87 sensor driver stops CPU fan
#   
#   > 2* I would then add a check to the it87 driver, which completely disables
#   > the fan speed control interface if the initial configuration looks weird
#   > (all fans supposedly stopped and polarity set to "active low"). This
#   > should protect users of the driver who have a faulty BIOS.
#   >
#   > When a bogus configuration is detected, we would of course complain in
#   > the logs and invite the user to complain to his/her motherboard maker
#   > too.
#   
#   Here is it87.c_2.6.10-jm4-detect_broken_bios_20050112.diff implementing
#   this. It goes on top of the previous patch.
#   
#   - detects broken bioses, disables the pwm for them and prints a message
#   - fixes an unrelated minor bug in set_fan_div()
#   
#   Signed-off-by: Jean Delvare <khali@linux-fr.org>
#   Signed-off-by: Jonas Munsin <jmunsin@iki.fi>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/chips/it87.c
#   2005/01/14 14:17:39-08:00 jmunsin@iki.fi +22 -7
#   I2C: fix it87 sensor driver stops CPU fan
# 
# ChangeSet
#   2005/01/14 14:43:10-08:00 khali@linux-fr.org 
#   [PATCH] I2C: Cleanups to the eeprom driver
#   
#   Here comes a cleanup patch to the i2c eeprom client driver:
#   
#   * Get rid of the unused i2c_client client_id.
#   * Get rid of the redundant non-ISA bus check.
#   * Fix the adapter capability check. We were previously using
#     capabilities without checking if they were supported. Document
#     which capabilities are required and which are optional.
#   * Reorder things a bit. In particular, wait to have a valid client
#     before we bother checking if this is a Vaio EEPROM.
#   * Use strlcpy instead of strncpy, because I Heard It Was Better (TM) and
#     all other chip drivers use it.
#   * Take benefit of the auto-increment feature of EEPROMs to speed up the
#     Vaio check.
#   * Display an information message when a Vaio EEPROM is detected.
#   
#   Tested successfully on my laptop, which happens to be a Vaio.
#   
#   Signed-off-by: Jean Delvare <khali@linux-fr.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/chips/eeprom.c
#   2005/01/14 14:17:45-08:00 khali@linux-fr.org +22 -25
#   I2C: Cleanups to the eeprom driver
# 
# ChangeSet
#   2005/01/14 14:42:49-08:00 khali@linux-fr.org 
#   [PATCH] I2C: Fix bogus bitmask in lm63 debug message
#   
#   There is a bitmask error in one debug message of my lm63 chip driver.
#   Nothing critical but still worth fixing, hence comes a patch.
#   
#   Credits go to Mohan Mistry for finding the error.
#   
#   Signed-off-by: Jean Delvare <khali@linux-fr.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/chips/lm63.c
#   2005/01/14 14:17:50-08:00 khali@linux-fr.org +2 -2
#   I2C: Fix bogus bitmask in lm63 debug message
# 
# ChangeSet
#   2005/01/14 14:42:28-08:00 jthiessen@penguincomputing.com 
#   [PATCH] I2C: adm1026.c fixes
#   
#   Ok, take 3 on the adm1026 patch.
#   
#   In this patch:
#   
#   (1) Code has been added which ensures that the fan divisor registers are
#       properly read into the data structure before fan minimum speeds are
#       determined.  This prevents a possible divide by zero error.  The line
#       which reads the hardware default fan divisor values has been reformatted
#       as suggested by Andreas Dilger to make the intent of the statement clearer.
#   
#   (2) In a similar spirit, an unecessary carriage return from a "dev_dbg"
#       statement in the adm1026_print_gpio() function has been elminated,
#       shortening the statement to a single line and making the code easier
#       to read.
#   
#   Signed-off-by: Justin Thiessen <jthiessen@penguincomputing.com
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/chips/adm1026.c
#   2005/01/14 14:18:02-08:00 jthiessen@penguincomputing.com +9 -2
#   I2C: adm1026.c fixes
# 
# ChangeSet
#   2005/01/14 14:42:04-08:00 jmunsin@iki.fi 
#   [PATCH] I2C: it87 fan update
#   
#   On Tue, Jan 11, 2005 at 10:26:22AM +0100, Jean Delvare wrote:
#   > 1* Jonas, please send a modified version of your original patch to Greg.
#   > The only difference would be that you wouldn't force on/off mode to be
#   > on at driver load time. Instead, disabling PWM for one fan control
#   > output (echo 0 > pwmN_enable) would both set on/off mode to on for that
#   > output (new) and turn that output to on/off mode (same as before).
#   
#   Ok, thanks for doing the thinking ;), here is the modified patch
#   (it87.c_2.6.10-jm3-corrected_manual_pwm_20050111.diff). In addition to
#   the above change, it also refreshes fan_main_ctrl in the update routine,
#   as suggested by Jean on IRC.
#   
#    - adds manual PWM
#    - removes buggy "reset" module parameter
#    - fixes some whitespaces
#   
#   Signed-off-by: Jonas Munsin <jmunsin@iki.fi>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/chips/it87.c
#   2005/01/14 14:18:07-08:00 jmunsin@iki.fi +131 -17
#   I2C: it87 fan update
# 
# ChangeSet
#   2005/01/14 14:41:41-08:00 jason.d.gaston@intel.com 
#   [PATCH] I2C support for Intel ICH7 - 2.6.10 - resubmit
#   
#   This patch adds the Intel ICH7 DID to the i2c-i801.c driver and adds an
#   entry to Kconfig for I2C(SMBus) support.  Note: This patch relies on the
#   already submitted and accepted PATA patch to pci_ids.h containing all
#   ICH7 DID's.
#   
#   
#   Signed-off-by: Jason Gaston <Jason.d.gaston@intel.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/busses/i2c-i801.c
#   2005/01/14 14:18:13-08:00 jason.d.gaston@intel.com +2 -0
#   I2C support for Intel ICH7 - 2.6.10 - resubmit
# 
# drivers/i2c/busses/Kconfig
#   2005/01/14 14:18:13-08:00 jason.d.gaston@intel.com +1 -0
#   I2C support for Intel ICH7 - 2.6.10 - resubmit
# 
# ChangeSet
#   2005/01/14 14:41:19-08:00 greg@kroah.com 
#   [PATCH] I2C: add MODULE_DEVICE_TABLE to via686a.c driver
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/i2c/chips/via686a.c
#   2005/01/14 14:18:19-08:00 greg@kroah.com +3 -6
#   I2C: add MODULE_DEVICE_TABLE to via686a.c driver
# 
# ChangeSet
#   2005/01/14 13:43:17-08:00 davem@nuts.davemloft.net 
#   Merge bk://kernel.bkbits.net/acme/connection_sock-2.6
#   into nuts.davemloft.net:/disk1/BK/net-2.6
# 
# net/ipv4/raw.c
#   2005/01/14 13:43:06-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/14 13:31:38-08:00 bunk@stusta.de 
#   [IPV6]: Misc cleanups.
#   
#   - make some needlessly global code static
#   - remove the following unused functions:
#     - exthdrs.c: ipv6_build_rthdr
#     - exthdrs.c: ipv6_build_exthdr
#     - exthdrs.c: ipv6_build_nfrag_opts
#     - exthdrs.c: ipv6_build_frag_opts
#   - remove the following write-only global variables:
#     - addrconf.c: inet6_dev_count
#     - addrconf.c: inet6_ifa_count
#   - #if 0 the following unused global variable:
#     - addrconf.c: in6addr_any
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - ipv6_syms.c: in6addr_any
#     - ipv6_syms.c: in6addr_loopback
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv6/sysctl_net_ipv6.c
#   2005/01/14 13:30:08-08:00 bunk@stusta.de +1 -1
#   [IPV6]: Misc cleanups.
# 
# net/ipv6/route.c
#   2005/01/14 13:30:08-08:00 bunk@stusta.de +2 -2
#   [IPV6]: Misc cleanups.
# 
# net/ipv6/mcast.c
#   2005/01/14 13:30:08-08:00 bunk@stusta.de +18 -14
#   [IPV6]: Misc cleanups.
# 
# net/ipv6/ipv6_syms.c
#   2005/01/14 13:30:08-08:00 bunk@stusta.de +0 -2
#   [IPV6]: Misc cleanups.
# 
# net/ipv6/ip6_output.c
#   2005/01/14 13:30:07-08:00 bunk@stusta.de +1 -1
#   [IPV6]: Misc cleanups.
# 
# net/ipv6/icmp.c
#   2005/01/14 13:30:07-08:00 bunk@stusta.de +1 -1
#   [IPV6]: Misc cleanups.
# 
# net/ipv6/exthdrs.c
#   2005/01/14 13:30:07-08:00 bunk@stusta.de +0 -77
#   [IPV6]: Misc cleanups.
# 
# net/ipv6/anycast.c
#   2005/01/14 13:30:07-08:00 bunk@stusta.de +3 -1
#   [IPV6]: Misc cleanups.
# 
# net/ipv6/addrconf.c
#   2005/01/14 13:30:07-08:00 bunk@stusta.de +2 -7
#   [IPV6]: Misc cleanups.
# 
# include/net/ipv6.h
#   2005/01/14 13:30:07-08:00 bunk@stusta.de +0 -2
#   [IPV6]: Misc cleanups.
# 
# include/net/addrconf.h
#   2005/01/14 13:30:07-08:00 bunk@stusta.de +0 -1
#   [IPV6]: Misc cleanups.
# 
# include/linux/in6.h
#   2005/01/14 13:30:07-08:00 bunk@stusta.de +2 -0
#   [IPV6]: Misc cleanups.
# 
# ChangeSet
#   2005/01/14 13:26:23-08:00 buytenh@wantstofly.org 
#   [NET]: Tone down the verbosity of diverter messages.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/dv.c
#   2005/01/14 13:26:02-08:00 buytenh@wantstofly.org +9 -16
#   [NET]: Tone down the verbosity of diverter messages.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/14 16:24:29-05:00 davej@redhat.com 
#   [CPUFREQ] Remove reference to obsolete cpufreq bits.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# Documentation/feature-removal-schedule.txt
#   2005/01/14 16:22:44-05:00 davej@redhat.com +0 -17
#   [CPUFREQ] Remove reference to obsolete cpufreq bits.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/14 13:21:31-08:00 davem@nuts.davemloft.net 
#   Merge bk://kernel.bkbits.net/acme/connection_sock-2.6
#   into nuts.davemloft.net:/disk1/BK/net-2.6
# 
# net/ipv4/udp.c
#   2005/01/14 13:21:20-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/14 16:17:42-05:00 davej@delerium.kernelslacker.org 
#   Merge delerium.kernelslacker.org:/mnt/data/src/bk/bk-linus
#   into delerium.kernelslacker.org:/mnt/data/src/bk/cpufreq
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2005/01/14 16:17:35-05:00 davej@delerium.kernelslacker.org +0 -0
#   Auto merged
# 
# MAINTAINERS
#   2005/01/14 16:17:35-05:00 davej@delerium.kernelslacker.org +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/14 16:09:21-05:00 davej@redhat.com 
#   [CPUFREQ] Fix structure name usage in powernow-k8
#   With 2.6.10-mm2 (or even with -mm1) some structures in struct psb_s have been
#   renamed in powernow-k8.h, but the renaming has not been done properly for all
#   occurences in powernow-k8.c.
#   This prevents cpufreq from accepting the BIOS PST-tables.
#   
#   The following patch corrects this by renaming the incorrectly named variable
#   in powernow-k8.c, following the definition in the powernow-k8.h header file.
#   
#   Signed-off-by: Hans-Frieder Vogt <hfvogt@arcor.de>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2005/01/14 16:09:07-05:00 davej@redhat.com +2 -2
#   [CPUFREQ] Fix structure name usage in powernow-k8
#   With 2.6.10-mm2 (or even with -mm1) some structures in struct psb_s have been
#   renamed in powernow-k8.h, but the renaming has not been done properly for all
#   occurences in powernow-k8.c.
#   This prevents cpufreq from accepting the BIOS PST-tables.
#   
#   The following patch corrects this by renaming the incorrectly named variable
#   in powernow-k8.c, following the definition in the powernow-k8.h header file.
#   
#   Signed-off-by: Hans-Frieder Vogt <hfvogt@arcor.de>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/14 16:07:58-05:00 davej@redhat.com 
#   [CPUFREQ] gx-suspmod: fix gx_suspmod_get
#   
#   Fix to return a proper cpu speed. it is caused by mistaking the meaning
#   of on and off.
#   
#   Signed-Off-by: Hiroshi Miura <miura@da-cha.org>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
#   2005/01/14 16:07:49-05:00 davej@redhat.com +1 -1
#   [CPUFREQ] gx-suspmod: fix gx_suspmod_get
#   
#   Fix to return a proper cpu speed. it is caused by mistaking the meaning
#   of on and off.
#   
#   Signed-Off-by: Hiroshi Miura <miura@da-cha.org>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/14 16:07:22-05:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: don't loop on transient MSR
#   
#   From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
#   
#   The transient MSR values are for very short duration and so I feel reading
#   out the last set frequency is better than looping until reading something
#   expected.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2005/01/14 16:07:13-05:00 davej@redhat.com +4 -17
#   [CPUFREQ] speedstep-centrino: don't loop on transient MSR
#   
#   From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
#   
#   The transient MSR values are for very short duration and so I feel reading
#   out the last set frequency is better than looping until reading something
#   expected.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/14 16:06:37-05:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino and acpi-cpufreq: P4 TSC rate is constant
#   
#   From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
#   
#   In P4, CPU tsc rate won't change with CPU frequency change while using Enhanced
#   Speedstep Technology. Tested with both speedstep-centrino and acpi-cpufreq on
#   both i386 and x86-64.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h
#   2005/01/14 16:06:27-05:00 davej@redhat.com +25 -0
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h
#   2005/01/14 16:06:27-05:00 davej@redhat.com +0 -0
#   BitKeeper file /mnt/data/src/bk/cpufreq/arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2005/01/14 16:06:27-05:00 davej@redhat.com +8 -0
#   [CPUFREQ] speedstep-centrino and acpi-cpufreq: P4 TSC rate is constant
#   
#   From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
#   
#   In P4, CPU tsc rate won't change with CPU frequency change while using Enhanced
#   Speedstep Technology. Tested with both speedstep-centrino and acpi-cpufreq on
#   both i386 and x86-64.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
#   2005/01/14 16:06:27-05:00 davej@redhat.com +7 -0
#   [CPUFREQ] speedstep-centrino and acpi-cpufreq: P4 TSC rate is constant
#   
#   From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
#   
#   In P4, CPU tsc rate won't change with CPU frequency change while using Enhanced
#   Speedstep Technology. Tested with both speedstep-centrino and acpi-cpufreq on
#   both i386 and x86-64.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/14 16:05:45-05:00 davej@redhat.com 
#   [CPUFREQ] p4-clockmod: Dothan is 13 not 0x13
#   
#   Dothan is stepping 13  == 0x0D instead of 0x13 == 19
#   
#   This bug crept bag in the shadows caused by the debug overhauling patch.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
#   2005/01/14 16:05:36-05:00 davej@redhat.com +1 -1
#   [CPUFREQ] p4-clockmod: Dothan is 13 not 0x13
#   
#   Dothan is stepping 13  == 0x0D instead of 0x13 == 19
#   
#   This bug crept bag in the shadows caused by the debug overhauling patch.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/14 16:05:03-05:00 davej@redhat.com 
#   [CPUFREQ] ondemand: don't increase to full speed at startup (Bruno Ducrot)
#   
#   From: Bruno Ducrot <ducrot@poupinou.org>
#   
#   dbs_timer_init() will schedule_work(&dbs_work) so that do_dbs_timer()
#   is likely called very early at same time slice scheduler, and
#   for each cpu, dbs_check_cpu(cpu) will be called, likely at the same time
#   slice than dbs_timer_init().
#   So far, we will get total_idle_ticks == idle_ticks == 0 unconditonaly,
#   and the processor will be put at full speed even though it's not needed
#   at startup.
#   
#   
#   Ack'ed by Venkatesh Pallipadi.
#   
#   Signed-off-by: Bruno Ducrot <ducrot@poupinou.org>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq_ondemand.c
#   2005/01/14 16:04:54-05:00 davej@redhat.com +2 -1
#   [CPUFREQ] ondemand: don't increase to full speed at startup (Bruno Ducrot)
#   
#   From: Bruno Ducrot <ducrot@poupinou.org>
#   
#   dbs_timer_init() will schedule_work(&dbs_work) so that do_dbs_timer()
#   is likely called very early at same time slice scheduler, and
#   for each cpu, dbs_check_cpu(cpu) will be called, likely at the same time
#   slice than dbs_timer_init().
#   So far, we will get total_idle_ticks == idle_ticks == 0 unconditonaly,
#   and the processor will be put at full speed even though it's not needed
#   at startup.
#   
#   
#   Ack'ed by Venkatesh Pallipadi.
#   
#   Signed-off-by: Bruno Ducrot <ducrot@poupinou.org>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/14 12:09:10-08:00 ecashin@coraid.com 
#   [PATCH] aoe: fix __init calling __exit
#   
#   Russell King <rmk+lkml@arm.linux.org.uk> writes:
#   
#   > static void __exit
#   > aoe_exit(void)
#   > {
#   > ...
#   > }
#   >
#   > static int __init
#   > aoe_init(void)
#   > {
#   > ...
#   >                         aoe_exit();
#   > ...
#   > }
#   
#   Thanks for catching that.  I cleaned up the error handling, too.
#   
#   Don't call __exit functions from __init functions.
#   
#   Signed-off-by: Ed L. Cashin <ecashin@coraid.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/block/aoe/aoenet.c
#   2005/01/14 11:21:11-08:00 ecashin@coraid.com +1 -1
#   aoe: fix __init calling __exit
# 
# drivers/block/aoe/aoemain.c
#   2005/01/14 11:21:11-08:00 ecashin@coraid.com +31 -13
#   aoe: fix __init calling __exit
# 
# drivers/block/aoe/aoedev.c
#   2005/01/14 11:21:11-08:00 ecashin@coraid.com +1 -1
#   aoe: fix __init calling __exit
# 
# drivers/block/aoe/aoechr.c
#   2005/01/14 11:21:11-08:00 ecashin@coraid.com +1 -1
#   aoe: fix __init calling __exit
# 
# ChangeSet
#   2005/01/14 12:03:48-08:00 ecashin@coraid.com 
#   [PATCH] aoe: don't sleep with interrupts on
#   
#   Changes:
#   
#     * get rid of sleeping with interrupts off
#       (I had to re-add the (struct aoedev *)->nopen member because I
#       can't get to bdev->bd_openers without sleeping.)
#   
#     * Scott Feldman suggestions:
#       don't do needless assignment of skb->dev in aoenet_rcv.
#       use skb_push instead of just adding to skb->len.
#       also trivial: make data in struct frame unsigned char array.
#   
#     * Alan Cox suggestion: use net_ratelimit to avoid flooding syslog
#   
#     * documentation updates and corrections
#   
#     * support one-partition per device for compatibility with systems
#       having poor support for large minor device numbers
#   
#   
#   Don't sleep with interrupts on; support no-partition devices.
#   
#   Signed-off-by: Ed L. Cashin <ecashin@coraid.com>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/block/aoe/aoenet.c
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +8 -11
#   aoe: don't sleep with interrupts on
# 
# drivers/block/aoe/aoemain.c
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +2 -1
#   aoe: don't sleep with interrupts on
# 
# drivers/block/aoe/aoedev.c
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +4 -18
#   aoe: don't sleep with interrupts on
# 
# drivers/block/aoe/aoeblk.c
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +38 -10
#   aoe: don't sleep with interrupts on
# 
# drivers/block/aoe/aoe.h
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +6 -2
#   aoe: don't sleep with interrupts on
# 
# Documentation/aoe/status.sh
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +17 -4
#   aoe: don't sleep with interrupts on
# 
# Documentation/aoe/mkshelf.sh
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +5 -3
#   aoe: don't sleep with interrupts on
# 
# Documentation/aoe/mkdevs.sh
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +6 -3
#   aoe: don't sleep with interrupts on
# 
# Documentation/aoe/aoe.txt
#   2005/01/14 11:21:17-08:00 ecashin@coraid.com +25 -16
#   aoe: don't sleep with interrupts on
# 
# ChangeSet
#   2005/01/14 11:57:48-08:00 greg@kroah.com 
#   [PATCH] Block: move struct disk_attribute to genhd.h
#   
#   This allows other block devices to add attributes to their sysfs
#   entries.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/genhd.h
#   2005/01/14 11:21:23-08:00 greg@kroah.com +6 -0
#   Block: move struct disk_attribute to genhd.h
# 
# drivers/block/genhd.c
#   2005/01/14 11:21:23-08:00 greg@kroah.com +0 -6
#   Block: move struct disk_attribute to genhd.h
# 
# drivers/block/aoe/aoeblk.c
#   2005/01/14 11:21:23-08:00 greg@kroah.com +1 -8
#   Block: move struct disk_attribute to genhd.h
# 
# ChangeSet
#   2005/01/14 19:54:18+00:00 catalin.marinas@com.rmk.(none) 
#   [ARM PATCH] 2404/1: BTAC/BTB flushing added in cpu_v6_switch_mm
#   
#   Patch from Catalin Marinas
#   
#   This is needed since ARMv6 branch prediction tagging is done by the
#   virtual address and the ASIDs aren't taken into account.
#   
#   Signed-off-by: Catalin Marinas
#   Signed-off-by: Russell King
# 
# ChangeSet
#   2005/01/14 11:50:41-08:00 greg@kroah.com 
#   [PATCH] Block: Remove block_subsys.rwsem usage
#   
#   A new, local semaphore is used, and the major_names_lock spinlock is
#   dropped, as it is no longer needed with this patch.  The goal is to
#   remove the subsys.rwsem entirely in the future, hence the need for this
#   change.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# drivers/block/genhd.c
#   2005/01/14 11:21:28-08:00 greg@kroah.com +12 -19
#   Block: Remove block_subsys.rwsem usage
# 
# arch/arm/mm/proc-v6.S
#   2005/01/14 00:00:00+00:00 catalin.marinas@com.rmk.(none) +1 -0
#   [PATCH] 2404/1: BTAC/BTB flushing added in cpu_v6_switch_mm
# 
# ChangeSet
#   2005/01/14 19:42:46+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2403/1: S3C2410 - clock initialsation tidy
#   
#   Patch from Ben Dooks
#   
#   Update to the s3c2410/s3c2440 clock code to use
#   the naming conventions now used throughout the
#   arch/arm/mach-s3c2410/ directory, as well as
#   a re-organisation of the initialisation of the
#   clocks.
#   The previous method was to initialise the clocks
#   as part of the function that initialised the
#   statically mapped IO regions, which was called
#   from the machine initialisation. This proves
#   a problem if the machine initialisation needs
#   to use these IO areas to determine the frequency
#   of PLL crystal fitted.
#   This patch makes the following changes:
#    - s3c2410_init_clocks renamed s3c24xx_setup_clocks
#    - s3c2410_clkcon_enable renamed s3c24xx_clk_enable
#    - s3c2410_register_clock renamed s3c24xx_register_clock
#    - cpu specific init_clocks to be called from cpu.c
#    - add s3c24xx_init_clocks for machine init to call
#    - split the cpu specific clock code from xxx_map_io
#    - update all machine initialisation methods
#   and the following changes as cleanup which should
#   have been caught by previous patches:
#    - remove s3c2440_hdiv (unused)
#    - remove s3c2440_clock_tick_rate (unused)
#   This patch has been generated from a request by
#   Dimitry Andric.
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# arch/arm/mach-s3c2410/s3c2440.h
#   2005/01/14 12:58:15+00:00 ben-linux@org.rmk.(none) +4 -0
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/s3c2440.c
#   2005/01/14 13:08:57+00:00 ben-linux@org.rmk.(none) +18 -17
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/s3c2410.h
#   2005/01/14 12:44:53+00:00 ben-linux@org.rmk.(none) +4 -0
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/s3c2410.c
#   2005/01/14 13:10:26+00:00 ben-linux@org.rmk.(none) +6 -6
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/mach-vr1000.c
#   2005/01/14 13:13:06+00:00 ben-linux@org.rmk.(none) +2 -0
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/mach-smdk2410.c
#   2005/01/14 13:13:38+00:00 ben-linux@org.rmk.(none) +1 -0
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/mach-rx3715.c
#   2005/01/14 13:12:31+00:00 ben-linux@org.rmk.(none) +2 -2
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/mach-h1940.c
#   2005/01/14 13:11:55+00:00 ben-linux@org.rmk.(none) +2 -0
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/mach-bast.c
#   2005/01/14 12:40:14+00:00 ben-linux@org.rmk.(none) +1 -0
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/cpu.h
#   2005/01/14 12:45:33+00:00 ben-linux@org.rmk.(none) +3 -0
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/cpu.c
#   2005/01/14 13:11:04+00:00 ben-linux@org.rmk.(none) +30 -1
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/clock.h
#   2005/01/14 13:01:50+00:00 ben-linux@org.rmk.(none) +3 -3
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# arch/arm/mach-s3c2410/clock.c
#   2005/01/14 13:03:13+00:00 ben-linux@org.rmk.(none) +30 -30
#   [PATCH] 2403/1: S3C2410 - clock initialsation tidy
# 
# ChangeSet
#   2005/01/14 19:32:28+00:00 catalin.marinas@com.rmk.(none) 
#   [ARM PATCH] 2401/1: asm/thread_info.h removed from arch/arm/vfp/entry.S
#   
#   Patch from Catalin Marinas
#   
#   This file no longer needs to be included in arch/arm/vfp/entry.S
#   because of the inclusion of asm/constants.h.
#   
#   Signed-off-by: Catalin Marinas
#   Signed-off-by: Russell King
# 
# arch/arm/vfp/entry.S
#   2005/01/14 00:00:00+00:00 catalin.marinas@com.rmk.(none) +0 -1
#   [PATCH] 2401/1: asm/thread_info.h removed from arch/arm/vfp/entry.S
# 
# ChangeSet
#   2005/01/14 10:26:02-08:00 axboe@suse.de 
#   [PATCH] noop-iosched: fix insertion point
#   
#   noop doesn't follow the instructions on where to insert a request,
#   because it uses q->queue_head instead of the *insert assigned. Clean it
#   up so it's easier to read.
#   
#   Signed-off-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/block/noop-iosched.c
#   2005/01/14 08:35:40-08:00 axboe@suse.de +3 -5
#   noop-iosched: fix insertion point
# 
# ChangeSet
#   2005/01/14 10:25:47-08:00 axboe@suse.de 
#   [PATCH] bio clone memory corruption
#   
#   Doing some raid testing threw a bug in the scsi mid layer, because the
#   segment counts wasn't correct.  Initially I worried that we still had
#   problems in this area, but it turns out that is due to the raid usage of
#   bio clones.  Currently you have to hold on to the original bio as well,
#   since the clone only maintains a pointer to the bio_vec inside the
#   original bio.  If the original bio is freed first, the clone will have
#   garbage in its bio->bi_io_vec as soon as that memory is scribbled.
#   
#   I think the best fix is to maintain flexibility and duplicate the io_vec
#   inside the clone as well. Attached patch does this.
#   
#   Signed-off-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/bio.c
#   2005/01/14 00:09:45-08:00 axboe@suse.de +7 -22
#   bio clone memory corruption
# 
# ChangeSet
#   2005/01/13 21:22:44-08:00 davem@nuts.davemloft.net 
#   [SPARC64]: Need some more SPARC32 ifdeffing in here.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# drivers/sbus/sbus.c
#   2005/01/13 21:22:09-08:00 davem@nuts.davemloft.net +5 -3
#   [SPARC64]: Need some more SPARC32 ifdeffing in here.
# 
# ChangeSet
#   2005/01/13 21:19:16-08:00 grundler@parisc-linux.org 
#   [SPARC64]: Fix brainfart in pci_psycho.c
#   
#   Signed-off-by: Grant Grundler <grundler@parisc-linux.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# arch/sparc64/kernel/pci_psycho.c
#   2005/01/13 21:18:51-08:00 grundler@parisc-linux.org +3 -3
#   [SPARC64]: Fix brainfart in pci_psycho.c
#   
#   Signed-off-by: Grant Grundler <grundler@parisc-linux.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/13 21:11:12-08:00 akpm@osdl.org 
#   [SPARC64]: Make first arg to find_next_zero_bit() const.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/asm-sparc64/bitops.h
#   2005/01/13 21:10:46-08:00 akpm@osdl.org +2 -1
#   [SPARC64]: Make first arg to find_next_zero_bit() const.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# arch/sparc64/lib/find_bit.c
#   2005/01/13 21:10:46-08:00 akpm@osdl.org +3 -2
#   [SPARC64]: Make first arg to find_next_zero_bit() const.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/13 21:07:14-08:00 okir@suse.de 
#   [NET]: Check for SOL_SOCKET in compat_sys_getsockopt
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/compat.c
#   2005/01/13 21:06:52-08:00 okir@suse.de +2 -1
#   [NET]: Check for SOL_SOCKET in compat_sys_getsockopt
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/13 21:05:27-08:00 nhorman@gmail.com 
#   [ATALK]: Add ioctls to allow ifx txqueuelen sets/gets
#   
#   Signed-off-by: Neil Horman <nhorman@gmail.com>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/appletalk/ddp.c
#   2005/01/13 21:05:06-08:00 nhorman@gmail.com +3 -0
#   [ATALK]: Add ioctls to allow ifx txqueuelen sets/gets
#   
#   Signed-off-by: Neil Horman <nhorman@gmail.com>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/13 21:03:55-08:00 bunk@stusta.de 
#   [DECNET]: Misc cleanups
#   
#   - make needlessly global code static
#   - dn_fib.c: remove the write-only global variable dn_fib_info_cnt
#   - dn_fib.c: remove the unused global function dn_fib_rt_message
#   - dn_neigh.c: remove the unused global function dn_neigh_pointopoint_notify
#   - dn_timer.c: remove the fast timer code that isn't used
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/decnet/dn_timer.c
#   2005/01/13 21:03:01-08:00 bunk@stusta.de +0 -47
#   [DECNET]: Misc cleanups
# 
# net/decnet/dn_route.c
#   2005/01/13 21:03:01-08:00 bunk@stusta.de +3 -3
#   [DECNET]: Misc cleanups
# 
# net/decnet/dn_neigh.c
#   2005/01/13 21:03:01-08:00 bunk@stusta.de +0 -8
#   [DECNET]: Misc cleanups
# 
# net/decnet/dn_fib.c
#   2005/01/13 21:03:01-08:00 bunk@stusta.de +0 -15
#   [DECNET]: Misc cleanups
# 
# net/decnet/af_decnet.c
#   2005/01/13 21:03:01-08:00 bunk@stusta.de +2 -4
#   [DECNET]: Misc cleanups
# 
# include/net/dn_fib.h
#   2005/01/13 21:03:01-08:00 bunk@stusta.de +0 -1
#   [DECNET]: Misc cleanups
# 
# include/net/dn.h
#   2005/01/13 21:03:01-08:00 bunk@stusta.de +0 -2
#   [DECNET]: Misc cleanups
# 
# ChangeSet
#   2005/01/13 20:48:54-08:00 davem@nuts.davemloft.net 
#   Merge bk://212.42.230.204/nf-2.6
#   into nuts.davemloft.net:/disk1/BK/net-2.6
# 
# net/ipv6/netfilter/ip6t_LOG.c
#   2005/01/13 20:48:42-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# net/ipv4/netfilter/ipt_LOG.c
#   2005/01/13 20:48:42-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/13 20:42:19-08:00 tglx@linutronix.de 
#   [NET]: Lock initializer cleanup.
#   
#   Use the new lock initializers DEFINE_SPIN_LOCk and DEFINE_RW_LOCK
#   
#   Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/xfrm/xfrm_state.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +5 -5
#   [NET]: Lock initializer cleanup.
# 
# net/xfrm/xfrm_policy.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/x25/x25_route.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/x25/x25_link.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/x25/af_x25.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/wanrouter/af_wanpipe.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/unix/af_unix.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sunrpc/svcauth.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sunrpc/sched.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sunrpc/pmap_clnt.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sunrpc/cache.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/sunrpc/auth_gss/gss_mech_switch.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sunrpc/auth_gss/auth_gss.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sunrpc/auth.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/socket.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sctp/protocol.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/sch_generic.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/sch_api.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/police.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/pedit.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/mirred.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/ipt.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/gact.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/estimator.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/cls_api.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/sched/act_api.c
#   2005/01/13 20:41:07-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/rxrpc/transport.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/rxrpc/krxtimod.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/rxrpc/krxsecd.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/rxrpc/krxiod.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/rose/rose_route.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/rose/af_rose.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/packet/af_packet.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/netrom/nr_route.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/netrom/af_netrom.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/netlink/af_netlink.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/llc/llc_core.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/lapb/lapb_iface.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/key/af_key.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/ipx/ipx_route.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipx/af_ipx.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/xfrm6_tunnel.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/sit.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/route.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/reassembly.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/raw.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/protocol.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/netfilter/ip6t_limit.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/netfilter/ip6t_LOG.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/netfilter/ip6_queue.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/mcast.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/ipv6_sockglue.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/ip6_tunnel.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/ip6_output.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/ip6_flowlabel.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/ip6_fib.c
#   2005/01/13 20:41:06-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/anycast.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/af_inet6.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv6/addrconf.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +4 -4
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/udp.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/tcp_minisocks.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/route.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/raw.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/protocol.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/netfilter/ipt_recent.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/netfilter/ipt_limit.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/netfilter/ipt_LOG.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/netfilter/ip_queue.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/netfilter/ip_nat_snmp_basic.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipvs/ip_vs_sync.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipvs/ip_vs_sched.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipvs/ip_vs_proto_udp.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipvs/ip_vs_proto_tcp.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipvs/ip_vs_est.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipvs/ip_vs_ctl.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +5 -5
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipmr.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipip.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ipconfig.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ip_sockglue.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ip_gre.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/ip_fragment.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/inetpeer.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/fib_semantics.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/fib_rules.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/fib_hash.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ipv4/af_inet.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/econet/af_econet.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/decnet/dn_table.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/decnet/dn_rules.c
#   2005/01/13 20:41:05-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/decnet/dn_route.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/decnet/dn_fib.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +2 -2
#   [NET]: Lock initializer cleanup.
# 
# net/decnet/dn_dev.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/decnet/af_decnet.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/core/netpoll.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/core/netfilter.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/core/neighbour.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/core/link_watch.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/core/gen_estimator.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/core/dst.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/core/dev.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/bridge/netfilter/ebt_ulog.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/bridge/netfilter/ebt_log.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/bridge/netfilter/ebt_limit.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ax25/ax25_uid.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ax25/ax25_route.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ax25/ax25_out.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ax25/ax25_iface.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/ax25/ax25_dev.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/ax25/af_ax25.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/atm/resources.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/atm/common.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/atm/br2684.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/appletalk/ddp.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +3 -3
#   [NET]: Lock initializer cleanup.
# 
# net/appletalk/aarp.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/802/tr.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# net/802/psnap.c
#   2005/01/13 20:41:04-08:00 davem@nuts.davemloft.net +1 -1
#   [NET]: Lock initializer cleanup.
# 
# ChangeSet
#   2005/01/14 02:39:01-02:00 acme@conectiva.com.br 
#   [RAW] merge raw_sock with raw_opt
#   
#   No need for two structs, follow the new inet_sock layout
#   style.
#   
#   Signed-off-by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/raw.c
#   2005/01/14 02:38:29-02:00 acme@conectiva.com.br +6 -5
#   [RAW] merge raw_sock with raw_opt
#   
#   No need for two structs, follow the new inet_sock layout
#   style.
#   
#   Signed-off-by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/icmp.h
#   2005/01/14 02:38:29-02:00 acme@conectiva.com.br +7 -8
#   [RAW] merge raw_sock with raw_opt
#   
#   No need for two structs, follow the new inet_sock layout
#   style.
#   
#   Signed-off-by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/13 20:34:08-08:00 yoshfuji@linux-ipv6.org 
#   [IPV6]: Fix tunnel list locking in sit.c
#   
#   Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv6/sit.c
#   2005/01/13 20:33:48-08:00 yoshfuji@linux-ipv6.org +2 -2
#   [IPV6]: Fix tunnel list locking in sit.c
#   
#   Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/13 20:19:03-08:00 davem@nuts.davemloft.net 
#   [TUN]: Make type explicit in min() usage.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# drivers/net/tun.c
#   2005/01/13 20:18:30-08:00 davem@nuts.davemloft.net +2 -1
#   [TUN]: Make type explicit in min() usage.
# 
# ChangeSet
#   2005/01/13 20:17:43-08:00 davem@nuts.davemloft.net 
#   [NETLINK]: netlink_kernel[] no longer used.
#   
#   The netlink_post stuff Arjan removed was the only
#   user of this array.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/netlink/af_netlink.c
#   2005/01/13 20:16:35-08:00 davem@nuts.davemloft.net +0 -4
#   [NETLINK]: netlink_kernel[] no longer used.
# 
# ChangeSet
#   2005/01/13 20:11:08-08:00 davem@nuts.davemloft.net 
#   [EBTABLES]: Use correct printf format for size_t.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/bridge/netfilter/ebt_ulog.c
#   2005/01/13 20:10:21-08:00 davem@nuts.davemloft.net +1 -1
#   [EBTABLES]: Use correct printf format for size_t.
# 
# ChangeSet
#   2005/01/13 20:02:46-08:00 davem@nuts.davemloft.net 
#   [TCP]: Fix sk_forward_alloc assertion failures with TSO.
#   
#   do_tcp_sendpages() needs to do skb->truesize et al.
#   accounting just like tcp_sendmsg() does.
#   
#   tcp_sendmsg() works by gradually adjusting these
#   accounting knobs as user data is copied into the
#   packet.
#   
#   do_tcp_sendpages() works differently, when it allocates
#   a new SKB it optimistically adds in tp->mss_cache to
#   these values and then makes no adjustments at all as
#   pages are tacked onto the packet.
#   
#   This does not work at all if tcp_sendmsg() queues a
#   packet onto the send queue, and then do_tcp_sendpages()
#   attaches pages onto the end of that SKB.  We are left
#   with a very inaccurate skb->truesize in that case.
#   
#   Consequently, if we were building a TSO frame and it
#   gets partially ACK'd, then since skb->truesize is too
#   small tcp_trim_skb() will potentially underflow it's
#   value and all the accounting becomes corrupted.
#   
#   This is usually seen as sk->sk_forward_alloc being
#   negative at socket destroy time, which triggers an
#   assertion check.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/tcp.c
#   2005/01/13 19:57:57-08:00 davem@nuts.davemloft.net +4 -1
#   [TCP]: Fix sk_forward_alloc assertion failures with TSO.
# 
# ChangeSet
#   2005/01/13 17:49:50-05:00 davej@redhat.com 
#   [CPUFREQ] Fix up more instances of the old cpufreq list URLs.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# Documentation/cpu-freq/index.txt
#   2005/01/13 17:49:41-05:00 davej@redhat.com +4 -4
#   [CPUFREQ] Fix up more instances of the old cpufreq list URLs.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/13 22:49:21+00:00 catalin.marinas@com.rmk.(none) 
#   [ARM PATCH] 2399/1: asm/constants.h included in arch/arm/vfp/entry.S
#   
#   Patch from Catalin Marinas
#   
#   The TI_VFPSTATE is otherwise undefined and gas-2.15.90 (and probably
#   earlier versions) assumes 0. Gas-2.15.92 reports an error.
#   
#   Signed-off-by: Catalin Marinas
#   Signed-off-by: Russell King
# 
# arch/arm/vfp/entry.S
#   2005/01/13 00:00:00+00:00 catalin.marinas@com.rmk.(none) +1 -0
#   [PATCH] 2399/1: asm/constants.h included in arch/arm/vfp/entry.S
# 
# ChangeSet
#   2005/01/13 22:43:31+00:00 LW@de.rmk.(none) 
#   [ARM PATCH] 2395/1: __ioremap() miscalculates mapping size under certain conditions
#   
#   Patch from Lothar Wassmann
#   
#   Hi,
#   ioremapping a memory range that ends on the first byte of a page
#   (e.g. mapping PAGE_SIZE + 1 bytes on a page boundary) results in a
#   mapping that is one page too short. In particular trying to create a 1
#   byte mapping at the start of a page results in a BUG_ON() assertion in
#   remap_area_pages() because the calculated mapping size is zero.
#   This bug has been reported on Bugzilla on 2004-02-25:
#   http://bugzilla.kernel.org/show_bug.cgi?id=2188
#   
#   Signed-off-by: Lothar Wassmann
#   Signed-off-by: Russell King
# 
# arch/arm/mm/ioremap.c
#   2005/01/13 00:00:00+00:00 LW@de.rmk.(none) +1 -1
#   [PATCH] 2395/1: __ioremap() miscalculates mapping size under certain conditions
# 
# ChangeSet
#   2005/01/13 22:37:36+00:00 elf@com.rmk.(none) 
#   [ARM PATCH] 2394/1: Re: accepting responsibility for Sharp LH ports
#   
#   Patch from Marc Singer
#   
#   Admitting that I'm the maintainer for the Sharp LH ports.
#   
#   Signed-off-by: Marc Singer
#   Signed-off-by: Russell King
# 
# MAINTAINERS
#   2005/01/13 00:51:19+00:00 elf@com.rmk.(none) +7 -0
#   [PATCH] 2394/1: Re: accepting responsibility for Sharp LH ports
# 
# ChangeSet
#   2005/01/13 22:31:41+00:00 rpurdie@net.rmk.(none) 
#   [ARM PATCH] 2392/1: Add PCMCIA/CF support code for Sharp SL-C7xx Series
#   
#   Patch from Richard Purdie
#   
#   Add support code to enable the Compact Flash socket on the Sharp
#   SL-C7xx series of PDAs. The socket is controlled via the Sharp
#   SCOOP interface.
#   
#   Signed-off-by: Richard Purdie
#   Signed-off-by: Russell King
# 
# drivers/pcmcia/Makefile
#   2005/01/13 00:00:00+00:00 rpurdie@net.rmk.(none) +1 -0
#   [PATCH] 2392/1: Add PCMCIA/CF support code for Sharp SL-C7xx Series
# 
# drivers/pcmcia/pxa2xx_sharpsl.c
#   2005/01/13 00:00:00+00:00 rpurdie@net.rmk.(none) +264 -0
#   [PATCH] 2392/1: Add PCMCIA/CF support code for Sharp SL-C7xx Series
# 
# drivers/pcmcia/pxa2xx_sharpsl.c
#   2005/01/13 00:00:00+00:00 rpurdie@net.rmk.(none) +0 -0
#   BitKeeper file /usr/src/bk/linux-2.6-rmk/drivers/pcmcia/pxa2xx_sharpsl.c
# 
# ChangeSet
#   2005/01/13 16:22:32-05:00 davej@redhat.com 
#   [CPUFREQ] cpufreq mailing list changed its DNS entry.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# MAINTAINERS
#   2005/01/13 16:22:23-05:00 davej@redhat.com +1 -1
#   [CPUFREQ] cpufreq mailing list changed its DNS entry.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2005/01/13 09:01:51-08:00 paulus@samba.org 
#   [PATCH] PPC64 Move thread_info flags to its own cache line
#   
#   This patch fixes a problem I have been seeing since all the preempt
#   changes went in, which is that ppc64 SMP systems would livelock
#   randomly if preempt was enabled.
#   
#   It turns out that what was happening was that one cpu was spinning in
#   spin_lock_irq (the version at line 215 of kernel/spinlock.c) madly
#   doing preempt_enable() and preempt_disable() calls.  The other cpu had
#   the lock and was trying to set the TIF_NEED_RESCHED flag for the task
#   running on the first cpu.  That is an atomic operation which has to be
#   retried if another cpu writes to the same cacheline between the load
#   and the store, which the other cpu was doing every time it did
#   preempt_enable() or preempt_disable().
#   
#   I decided to move the thread_info flags field into the next cache
#   line, since it is the only field that would regularly be modified by
#   cpus other than the one running the task that owns the thread_info.
#   (OK possibly the `cpu' field would be on a rebalance; I don't know the
#   rebalancing code, but that should be pretty infrequent.)  Thus, moving
#   the flags field seems like a good idea generally as well as solving the
#   immediate problem.
#   
#   For the record I am pretty unhappy with the code we use for spin_lock
#   et al. with preemption turned on (the BUILD_LOCK_OPS stuff in
#   spinlock.c).  For a start we do the atomic op (_raw_spin_trylock) each
#   time around the loop.  That is going to be generating a lot of
#   unnecessary bus (or fabric) traffic.  Instead, after we fail to get
#   the lock we should poll it with simple loads until we see that it is
#   clear and then retry the atomic op.  Assuming a reasonable cache
#   design, the loads won't generate any bus traffic until another cpu
#   writes to the cacheline containing the lock.
#   
#   Secondly we have lost the __spin_yield call that we had on ppc64,
#   which is an important optimization when we are running under the
#   hypervisor.  I can't just put that in cpu_relax because I need to know
#   which (virtual) cpu is holding the lock, so that I can tell the
#   hypervisor which virtual cpu to give my time slice to.  That
#   information is stored in the lock variable, which is why __spin_yield
#   needs the address of the lock.
#   
#   Signed-off-by: Paul Mackerras <paulus@samba.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-ppc64/thread_info.h
#   2005/01/12 23:36:24-08:00 paulus@samba.org +4 -2
#   PPC64 Move thread_info flags to its own cache line
# 
# ChangeSet
#   2005/01/13 09:01:37-08:00 paulus@samba.org 
#   [PATCH] PPC64 Add PREEMPT_BKL option
#   
#   This patch adds the PREEMPT_BKL config option for PPC64, shamelessly
#   stolen from the i386 version.  I have this turned on in the kernel on
#   my desktop G5 and it seems to be just fine.
#   
#   Signed-off-by: Paul Mackerras <paulus@samba.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/ppc64/Kconfig
#   2005/01/12 01:25:17-08:00 paulus@samba.org +11 -0
#   PPC64 Add PREEMPT_BKL option
# 
# ChangeSet
#   2005/01/13 09:01:24-08:00 paulus@samba.org 
#   [PATCH] PPC64 can do preempt debug too
#   
#   This patch enables the DEBUG_PREEMPT config option for PPC64.  I have
#   this turned on on my desktop G5 and it isn't finding any problems.
#   (It did find one problem, in flush_tlb_pending(), that I have just
#   sent a patch for.)
#   
#   BTW, do we really need to restrict which architectures the config
#   option is available on?
#   
#   Signed-off-by: Paul Mackerras <paulus@samba.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# lib/Kconfig.debug
#   2005/01/10 14:13:28-08:00 paulus@samba.org +1 -1
#   PPC64 can do preempt debug too
# 
# include/asm-ppc64/smp.h
#   2005/01/10 00:49:03-08:00 paulus@samba.org +1 -1
#   PPC64 can do preempt debug too
# 
# ChangeSet
#   2005/01/13 09:01:10-08:00 paulus@samba.org 
#   [PATCH] PPC64 Call preempt_schedule on exception exit
#   
#   This patch mirrors the recent changes on x86 to call preempt_schedule
#   rather than schedule in the exception exit path, in the case where the
#   preempt_count is zero and the TIF_NEED_RESCHED bit is set.
#   
#   I'm a little concerned that this means that we have a window where
#   interrupts are enabled and we are on our way into preempt_schedule,
#   but preempt_count is still zero.  Ingo's proposed preempt_schedule_irq
#   would fix this, and I think something like that should go in.
#   
#   Signed-off-by: Paul Mackerras <paulus@samba.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/ppc64/kernel/entry.S
#   2005/01/13 01:48:36-08:00 paulus@samba.org +2 -5
#   PPC64 Call preempt_schedule on exception exit
# 
# ChangeSet
#   2005/01/13 09:00:59-08:00 paulus@samba.org 
#   [PATCH] PPC64 Disable preemption in flush_tlb_pending
#   
#   The preempt debug stuff found a place where we were using
#   smp_processor_id() without having preemption disabled, in
#   flush_tlb_pending.  This patch fixes it by using get_cpu_var and
#   put_cpu_var instead of the __get_cpu_var variant.
#   
#   Signed-off-by: Paul Mackerras <paulus@samba.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-ppc64/tlbflush.h
#   2005/01/13 00:35:37-08:00 paulus@samba.org +2 -1
#   PPC64 Disable preemption in flush_tlb_pending
# 
# ChangeSet
#   2005/01/13 09:00:45-08:00 axboe@suse.de 
#   [PATCH] possible rq starvation on oom
#   
#   I stumbled across this the other day. The block layer only uses a single
#   memory pool for request allocation, so it's very possible for eg writes
#   to have allocated them all at any point in time. If that is the case and
#   the machine is low on memory, a reader attempting to allocate a request
#   and failing in blk_alloc_request() can get stuck for a long time since
#   no one is there to wake it up.
#   
#   The solution is either to add the extra mempool so both reads and writes
#   have one, or attempt to handle the situation. I chose the latter, to
#   save the extra memory required for the additional mempool with
#   BLKDEV_MIN_RQ statically allocated requests per-queue.
#   
#   If a read allocation fails and we have no readers in flight for this
#   queue, mark us rq-starved so that the next write being freed will wake
#   up the sleeping reader(s). Same situation would happen for writes as
#   well of course, it's just a lot more unlikely.
#   
#   Signed-off-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/blkdev.h
#   2005/01/13 01:16:43-08:00 axboe@suse.de +1 -0
#   possible rq starvation on oom
# 
# drivers/block/ll_rw_blk.c
#   2005/01/13 01:17:36-08:00 axboe@suse.de +40 -11
#   possible rq starvation on oom
# 
# ChangeSet
#   2005/01/13 09:00:32-08:00 axboe@suse.de 
#   [PATCH] Don't enable ata over eth by default
#   
#   "ATA over Ethernet support" should not default to 'm', it doesn't make
#   any sense for a special case driver to do so.
#   
#   Signed-off-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/block/Kconfig
#   2005/01/13 00:50:17-08:00 axboe@suse.de +0 -1
#   Don't enable ata over eth by default
# 
# ChangeSet
#   2005/01/13 11:29:26+01:00 perex@suse.cz 
#   ALSA 1.0.8
# 
# include/sound/version.h
#   2005/01/13 11:29:00+01:00 perex@suse.cz +2 -2
#   ALSA 1.0.8
# 
# ChangeSet
#   2005/01/12 20:04:56-08:00 akropel1@rochester.rr.com 
#   [PATCH] contort getdents64 to pacify gcc-2.96
#   
#   A recent trivial fixup in sys_getdents64 gives gcc-2.96 indigestion in
#   the form of an ICE.
#   
#   While upgrading to a sane gcc would be the preferred solution, rewriting
#   the change as follows eliminates the error for those who cannot do so.
#   
#   Signed-off-by: Adam Kropelin <akropel1@rochester.rr.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# fs/readdir.c
#   2005/01/12 14:16:55-08:00 akropel1@rochester.rr.com +3 -2
#   contort getdents64 to pacify gcc-2.96
# 
# ChangeSet
#   2005/01/12 20:04:43-08:00 davej@redhat.com 
#   [PATCH] matroxfb driver broken on non-x86.
#   
#   This broke since the recent MODULE_PARAM conversion on
#   architectures that don't have CONFIG_MTRR
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/video/matrox/matroxfb_base.c
#   2005/01/12 13:48:54-08:00 davej@redhat.com +2 -0
#   matroxfb driver broken on non-x86.
# 
# ChangeSet
#   2005/01/12 18:14:03-08:00 torvalds@ppc970.osdl.org 
#   Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk
#   into ppc970.osdl.org:/home/torvalds/v2.6/linux
# 
# MAINTAINERS
#   2005/01/12 18:13:58-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# CREDITS
#   2005/01/12 18:13:58-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/12 23:50:04+01:00 marcel@holtmann.org 
#   [Bluetooth] Lock initializer cleanup
#   
#   Use the new lock initializers DEFINE_SPIN_LOCK and DEFINE_RW_LOCK.
#   
#   Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# net/bluetooth/rfcomm/tty.c
#   2005/01/12 23:48:53+01:00 marcel@holtmann.org +1 -1
#   Lock initializer cleanup
# 
# net/bluetooth/hci_core.c
#   2005/01/12 23:48:50+01:00 marcel@holtmann.org +3 -3
#   Lock initializer cleanup
# 
# ChangeSet
#   2005/01/12 13:42:36-08:00 maxk@qualcomm.com 
#   [TUN] Add a missing dependency on enabling the crc32 libraries
#   
#   Patch by Steve French <smfltc@us.ibm.com>
#   
#   Signed-off-by: Max Krasnyansky <maxk@qualcomm.com>
# 
# drivers/net/Kconfig
#   2005/01/12 13:42:27-08:00 maxk@qualcomm.com +1 -0
#   [TUN] Add a missing dependency on enabling the crc32 libraries
# 
# ChangeSet
#   2005/01/12 13:24:36-08:00 maxk@qualcomm.com 
#   Merge bk://linux.bkbits.net/linux-2.5
#   into qualcomm.com:/home/kernel/tun-2.6
# 
# include/linux/if_tun.h
#   2005/01/12 13:24:29-08:00 maxk@qualcomm.com +0 -0
#   Auto merged
# 
# drivers/net/tun.c
#   2005/01/12 13:24:29-08:00 maxk@qualcomm.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/12 21:03:45+00:00 nico@org.rmk.(none) 
#   [ARM PATCH] 2204/1: bring {read|write}sw up to date with current reality
#   
#   Patch from Nicolas Pitre
#   
#   This patch adds support for all alignments to both endianness.
#   
#   Signed-off-by: Nicolas Pitre 
#   Signed-off-by: Russell King
# 
# arch/arm/lib/io-writesw-armv4.S
#   2004/11/04 20:44:47+00:00 nico@org.rmk.(none) +38 -24
#   [PATCH] 2204/1: bring {read|write}sw up to date with current reality
# 
# arch/arm/lib/io-readsw-armv4.S
#   2004/11/04 20:40:10+00:00 nico@org.rmk.(none) +59 -28
#   [PATCH] 2204/1: bring {read|write}sw up to date with current reality
# 
# ChangeSet
#   2005/01/12 20:55:37+00:00 nico@org.rmk.(none) 
#   [ARM PATCH] 2391/1: remove obsolete help text
#   
#   Patch from Nicolas Pitre
#   
#   Now that MTD XIP support is merged this part is
#   not relevant anymore.
#   
#   Signed-off-by: Nicolas Pitre
#   Signed-off-by: Russell King
# 
# arch/arm/Kconfig
#   2005/01/12 00:00:00+00:00 nico@org.rmk.(none) +0 -14
#   [PATCH] 2391/1: remove obsolete help text
# 
# ChangeSet
#   2005/01/12 19:52:49+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Add missing tlb_migrate_finish()
#   
#   Signed-off-by: Russell King
# 
# include/asm-arm/tlb.h
#   2005/01/12 19:49:31+00:00 rmk@flint.arm.linux.org.uk +2 -0
#   Add missing tlb_migrate_finish()
# 
# ChangeSet
#   2005/01/12 20:33:29+01:00 perex@suse.cz 
#   [ALSA] Add ac97_quirk option
#   
#   Documentation,ATIIXP driver
#   Added ac97_quirk option like intel and via drivers.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/atiixp.c
#   2005/01/12 04:17:48+01:00 perex@suse.cz +10 -3
#   [ALSA] Add ac97_quirk option
#   
#   D:2005/01/12 11:17:47
#   C:Documentation,ATIIXP driver
#   F:Documentation/ALSA-Configuration.txt:1.61->1.62 
#   F:pci/atiixp.c:1.29->1.30 
#   L:Added ac97_quirk option like intel and via drivers.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# Documentation/sound/alsa/ALSA-Configuration.txt
#   2005/01/12 04:17:47+01:00 perex@suse.cz +2 -0
#   [ALSA] Add ac97_quirk option
#   
#   D:2005/01/12 11:17:47
#   C:Documentation,ATIIXP driver
#   F:Documentation/ALSA-Configuration.txt:1.61->1.62 
#   F:pci/atiixp.c:1.29->1.30 
#   L:Added ac97_quirk option like intel and via drivers.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 20:31:31+01:00 perex@suse.cz 
#   [ALSA] Fix ctl_read/write ioctl wrappers
#   
#   IOCTL32 emulation
#   Fixed bugs with ctl_read/write ioctls.
#   The struct size mismatch due to alignment is fixed.
#   The code is also a bit optimized.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/ioctl32/ioctl32.c
#   2005/01/12 04:10:52+01:00 perex@suse.cz +15 -74
#   [ALSA] Fix ctl_read/write ioctl wrappers
#   
#   D:2005/01/12 11:10:52
#   C:IOCTL32 emulation
#   F:core/ioctl32/ioctl32.c:1.26->1.27 
#   L:Fixed bugs with ctl_read/write ioctls.
#   L:The struct size mismatch due to alignment is fixed.
#   L:The code is also a bit optimized.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 20:29:54+01:00 perex@suse.cz 
#   [ALSA] Fix DMA pointer read
#   
#   ATIIXP driver
#   Try to reread DMA pointer register if the value is invalid.
#   The register shows bogus values on some broken hardwares.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/atiixp.c
#   2005/01/12 03:50:24+01:00 perex@suse.cz +11 -12
#   [ALSA] Fix DMA pointer read
#   
#   D:2005/01/12 10:50:24
#   C:ATIIXP driver
#   F:pci/atiixp.c:1.28->1.29 
#   L:Try to reread DMA pointer register if the value is invalid.
#   L:The register shows bogus values on some broken hardwares.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 10:08:53-08:00 torvalds@ppc970.osdl.org 
#   Merge http://lia64.bkbits.net/linux-ia64-release-2.6.11
#   into ppc970.osdl.org:/home/torvalds/v2.6/linux
# 
# arch/ia64/pci/pci.c
#   2005/01/12 10:08:48-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/12 10:07:41-08:00 torvalds@ppc970.osdl.org 
#   Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.6
#   into ppc970.osdl.org:/home/torvalds/v2.6/linux
# 
# include/linux/pci_ids.h
#   2005/01/12 10:07:37-08:00 torvalds@ppc970.osdl.org +0 -1
#   Auto merged
# 
# drivers/scsi/gdth.c
#   2005/01/12 10:07:37-08:00 torvalds@ppc970.osdl.org +0 -0
#   Auto merged
# 
# drivers/block/cciss.c
#   2005/01/12 10:07:36-08:00 torvalds@ppc970.osdl.org +0 -7
#   Auto merged
# 
# Documentation/cciss.txt
#   2005/01/12 10:07:36-08:00 torvalds@ppc970.osdl.org +0 -1
#   Auto merged
# 
# ChangeSet
#   2005/01/12 09:14:26-08:00 davidm@hpl.hp.com 
#   [IA64] add hpzx1_swiotlb machine-vector (new files)
#   
#   This is really part of the earlier changeset from David to add the
#   new machine vector to support certain limited range DMA cards on
#   zx1.  I just forgot to run "bk new" before the commit, so the newly
#   added files weren't checked into BK.
#   
#   Signed-off-by: David Mosberger-Tang <davidm@hpl.hp.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/machvec_hpzx1_swiotlb.h
#   2005/01/12 09:10:35-08:00 davidm@hpl.hp.com +43 -0
# 
# arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c
#   2005/01/12 09:10:35-08:00 davidm@hpl.hp.com +3 -0
# 
# include/asm-ia64/machvec_hpzx1_swiotlb.h
#   2005/01/12 09:10:35-08:00 davidm@hpl.hp.com +0 -0
#   BitKeeper file /data/home/aegl/BK/linux-ia64-release-2.6.11/include/asm-ia64/machvec_hpzx1_swiotlb.h
# 
# arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c
#   2005/01/12 09:10:35-08:00 davidm@hpl.hp.com +0 -0
#   BitKeeper file /data/home/aegl/BK/linux-ia64-release-2.6.11/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c
# 
# arch/ia64/hp/common/hwsw_iommu.c
#   2005/01/12 09:10:34-08:00 davidm@hpl.hp.com +185 -0
# 
# arch/ia64/hp/common/hwsw_iommu.c
#   2005/01/12 09:10:34-08:00 davidm@hpl.hp.com +0 -0
#   BitKeeper file /data/home/aegl/BK/linux-ia64-release-2.6.11/arch/ia64/hp/common/hwsw_iommu.c
# 
# ChangeSet
#   2005/01/12 09:02:21-08:00 dwmw2@infradead.org 
#   [PATCH] ppc: fix removed MMCR0_PMXE define
#   
#   In ChangeSet 1.2370, 2005/01/11 17:41:32-08:00, tglx@linutronix.de wrote:
#   >
#   >         [PATCH] ppc: remove duplicate define
#   >        
#   >         The MMCR0_PMXE is already defined in reg.h...
#   
#   Er, no it's not. But perhaps it should be...
# 
# include/asm-ppc/reg.h
#   2005/01/12 07:21:20-08:00 dwmw2@infradead.org +1 -0
#   ppc: fix removed MMCR0_PMXE define
# 
# ChangeSet
#   2005/01/12 08:50:53-08:00 paulus@samba.org 
#   [PATCH] PPC64 had _raw_read_trylock already
#   
#   Ingo presumably didn't notice that ppc64 already had a functional
#   _raw_read_trylock when he added the #define to use the generic
#   version.  This just removes the #define so we use the ppc64-specific
#   version again.
#   
#   Signed-off-by: Paul Mackerras <paulus@samba.org>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-ppc64/spinlock.h
#   2005/01/09 14:44:16-08:00 paulus@samba.org +0 -2
#   PPC64 had _raw_read_trylock already
# 
# ChangeSet
#   2005/01/12 08:50:39-08:00 axboe@suse.de 
#   [PATCH] elevator: print default selection
#   
#   Currently we only print the default io scheduler if the kernel chooses,
#   not if the user/bootloader has specified one. This patch saves the extra
#   line in dmesg but always notified of the default choice by appending
#   (default) to that line:
#   
#   	..
#   	io scheduler noop registered
#   	io scheduler anticipatory registered
#   	io scheduler deadline registered
#   	io scheduler cfq registered (default)
#   	..
#   
#   Patch originally from Srihari Vijayaraghavan, modified by me.
#   
#   Signed-off-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/block/elevator.c
#   2005/01/12 00:03:47-08:00 axboe@suse.de +4 -3
#   elevator: print default selection
# 
# ChangeSet
#   2005/01/12 08:49:02-08:00 tony.luck@intel.com 
#   [IA64] reorder functions to define ia64_pci_get_legacy_mem() before using it
#   
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# ChangeSet
#   2005/01/12 08:49:02-08:00 axboe@suse.de 
#   [PATCH] cfq-iosched: fix scsi requeue accounting
#   
#   The accounting can go bad in the requeue hook, it must check the
#   accounted flag to make sure it was previously considered in the driver.
#   
#   Signed-off-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# drivers/block/cfq-iosched.c
#   2005/01/11 01:03:17-08:00 axboe@suse.de +4 -2
#   cfq-iosched: fix scsi requeue accounting
# 
# ChangeSet
#   2005/01/12 08:48:49-08:00 kaos@sgi.com 
#   [PATCH] ia64: export pcibios_resource_to_bus to match other architectures.
#   
#   Signed-off-by: Keith Owens <kaos@sgi.com>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/ia64/pci/pci.c
#   2005/01/11 23:04:12-08:00 kaos@sgi.com +1 -0
#   ia64: export pcibios_resource_to_bus to match other architectures.
# 
# ChangeSet
#   2005/01/12 08:48:35-08:00 ink@jurassic.park.msu.ru 
#   [PATCH] Alpha: typos in io_trivial.h
#   
#   This apparently explains some weird IO failures reported in last two months.
#   Only non-bwx (including generic) kernels were affected.
#   
#   Acked-by: Richard Henderson <rth@twiddle.net>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-alpha/io_trivial.h
#   2005/01/11 17:47:26-08:00 ink@jurassic.park.msu.ru +2 -2
#   Alpha: typos in io_trivial.h
# 
# arch/ia64/pci/pci.c
#   2005/01/12 08:47:14-08:00 tony.luck@intel.com +17 -17
#   reorder functions to define ia64_pci_get_legacy_mem() before using it
# 
# ChangeSet
#   2005/01/12 08:26:35-08:00 torvalds@ppc970.osdl.org 
#   Make mm writelock testing less intrusive.
#   
#   This enables it only for debug kernels, and also makes sure
#   that if some external module is still broken, we don't leave
#   the mmap-sem locked after warning about it.
# 
# mm/mmap.c
#   2005/01/12 08:26:28-08:00 torvalds@ppc970.osdl.org +11 -1
#   Make mm writelock testing less intrusive.
#   
#   This enables it only for debug kernels, and also makes sure
#   that if some external module is still broken, we don't leave
#   the mmap-sem locked after warning about it.
# 
# ChangeSet
#   2005/01/12 08:12:09-08:00 marcelo.tosatti@cyclades.com 
#   [PATCH] do_brk() needs mmap_sem write-locked
#   
#   It seems to be general consensus that its safer to require all do_brk() callers
#   to grab mmap_sem, and have do_brk to warn otherwise. This is what the following
#   patch does.
#   
#   Similar version has been changed to in v2.4.
#   
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# mm/mmap.c
#   2005/01/11 17:43:11-08:00 marcelo.tosatti@cyclades.com +6 -0
#   do_brk() needs mmap_sem write-locked
# 
# fs/binfmt_elf.c
#   2005/01/11 18:07:01-08:00 marcelo.tosatti@cyclades.com +11 -1
#   do_brk() needs mmap_sem write-locked
# 
# fs/binfmt_aout.c
#   2005/01/11 17:31:51-08:00 marcelo.tosatti@cyclades.com +14 -3
#   do_brk() needs mmap_sem write-locked
# 
# arch/x86_64/ia32/ia32_aout.c
#   2005/01/11 17:34:26-08:00 marcelo.tosatti@cyclades.com +11 -1
#   do_brk() needs mmap_sem write-locked
# 
# arch/sparc64/kernel/binfmt_aout32.c
#   2005/01/11 17:37:28-08:00 marcelo.tosatti@cyclades.com +12 -0
#   do_brk() needs mmap_sem write-locked
# 
# arch/mips/kernel/irixelf.c
#   2005/01/11 17:35:36-08:00 marcelo.tosatti@cyclades.com +10 -1
#   do_brk() needs mmap_sem write-locked
# 
# ChangeSet
#   2005/01/12 10:09:46-06:00 jejb@mulgrave.(none) 
#   FC Transport updates - additional fc host attributes
#   
#   From: 	James.Smart@Emulex.Com
#   
#   This patch adds 5 more FC transport host attributes in support of HBAAPI. 
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# ChangeSet
#   2005/01/12 08:09:20-08:00 torvalds@ppc970.osdl.org 
#   Handle two threads both trying to expand their stack simultaneously.
#   
#   We had all the locking right, but we didn't check whether one of the
#   threads now no longer needed to expand, so we could incorrectly _shrink_
#   the stack in the other thread instead (not only causing segfaults, but
#   since we didn't do a proper unmap, we'd possibly leak pages too).
#   
#   So re-check the need for expand after getting the lock.
#   
#   Noticed by Paul Starzetz.
# 
# mm/mmap.c
#   2005/01/12 08:09:12-08:00 torvalds@ppc970.osdl.org +25 -13
#   Handle two threads both trying to expand their stack simultaneously.
# 
# include/scsi/scsi_transport_fc.h
#   2005/01/12 10:08:53-06:00 jejb@mulgrave.(none) +22 -0
#   FC Transport updates - additional fc host attributes
# 
# drivers/scsi/scsi_transport_fc.c
#   2005/01/12 10:08:53-06:00 jejb@mulgrave.(none) +20 -0
#   FC Transport updates - additional fc host attributes
# 
# ChangeSet
#   2005/01/12 10:06:41-06:00 jejb@mulgrave.(none) 
#   SCSI: add starget_for_each_device
#   
#   From: 	James.Smart@Emulex.Com
#   
#   This patch deprecates the use of device_for_each_child() with stargets.
#   The reasoning behind this is due to issues regarding:
#         Semaphores that device_for_each_child() takes
#         Implicit assumptions that each child is an sdev device.
#   
#   The patch adds a new helper function, starget_for_each_device(), and
#   replaces all previous uses of device_for_each_child().
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/scsi/scsi_device.h
#   2005/01/12 10:05:35-06:00 jejb@mulgrave.(none) +2 -0
#   SCSI: add starget_for_each_device
# 
# drivers/scsi/scsi_transport_fc.c
#   2005/01/12 10:05:35-06:00 jejb@mulgrave.(none) +7 -9
#   SCSI: add starget_for_each_device
# 
# drivers/scsi/scsi_lib.c
#   2005/01/12 10:05:35-06:00 jejb@mulgrave.(none) +8 -10
#   SCSI: add starget_for_each_device
# 
# drivers/scsi/scsi.c
#   2005/01/12 10:05:35-06:00 jejb@mulgrave.(none) +22 -0
#   SCSI: add starget_for_each_device
# 
# ChangeSet
#   2005/01/12 15:38:50+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2390/1: Simtec Electronics MAINTAINERS file entries
#   
#   Patch from Ben Dooks
#   
#   MAINTAINERS entries for currently supported Simtec Electronics
#   development boards.
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# ChangeSet
#   2005/01/12 07:36:34-08:00 ak@suse.de 
#   [PATCH] [4/4] Fix numa=off command line parsing
#   
#   Fix a long standing bug: numa=off only worked as last argument on
#   the command line.
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/x86_64/mm/numa.c
#   2005/01/12 07:36:24-08:00 ak@suse.de +1 -1
#   [4/4] Fix numa=off command line parsing
# 
# ChangeSet
#   2005/01/12 07:36:17-08:00 ak@suse.de 
#   [PATCH] [3/4] x86_64: Fix NUMA hash setup
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/asm-x86_64/numa.h
#   2005/01/12 07:36:08-08:00 ak@suse.de +1 -1
#   [3/4] x86_64: Fix NUMA hash setup
# 
# arch/x86_64/mm/srat.c
#   2005/01/12 07:36:08-08:00 ak@suse.de +1 -1
#   [3/4] x86_64: Fix NUMA hash setup
# 
# arch/x86_64/mm/numa.c
#   2005/01/12 07:36:08-08:00 ak@suse.de +3 -5
#   [3/4] x86_64: Fix NUMA hash setup
# 
# arch/x86_64/mm/k8topology.c
#   2005/01/12 07:36:08-08:00 ak@suse.de +1 -1
#   [3/4] x86_64: Fix NUMA hash setup
# 
# ChangeSet
#   2005/01/12 07:36:02-08:00 ak@suse.de 
#   [PATCH] x86_64: Fix K8 NUMA discovery
#   
#   Fix K8 node discovery after nodemask changes.
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# arch/x86_64/mm/k8topology.c
#   2005/01/12 07:35:53-08:00 ak@suse.de +13 -8
#   x86_64: Fix K8 NUMA discovery
# 
# ChangeSet
#   2005/01/12 09:35:52-06:00 akpm@osdl.org 
#   [PATCH] use mmiowb in qla1280.c
#   
#   From: Jesse Barnes <jbarnes@engr.sgi.com>
#   
#   There are a few spots in qla1280.c that don't need a full PCI write flush
#   to the device, but rather a simple write ordering guarantee.  This patch
#   changes some of the PIO reads that cause write flushes into mmiowb calls
#   instead, which is a lighter weight way of ensuring ordering.
#   
#   Signed-off-by: Jeremy Higdon <jeremy@sgi.com>
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# ChangeSet
#   2005/01/12 07:35:48-08:00 ak@suse.de 
#   [PATCH] x86_64: Fix ACPI SRAT NUMA parsing
#   
#   Fix fallout from the recent nodemask_t changes. The node ids assigned
#   in the SRAT parser were off by one.
#   
#   I added a new first_unset_node() function to nodemask.h to allocate
#   IDs sanely.
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Linus Torvalds <torvalds@osdl.org>
# 
# include/linux/nodemask.h
#   2005/01/12 07:35:38-08:00 ak@suse.de +9 -0
#   x86_64: Fix ACPI SRAT NUMA parsing
# 
# arch/x86_64/mm/srat.c
#   2005/01/12 07:35:38-08:00 ak@suse.de +10 -7
#   x86_64: Fix ACPI SRAT NUMA parsing
# 
# drivers/scsi/qla1280.c
#   2004/10/21 23:20:31-05:00 akpm@osdl.org +18 -4
#   use mmiowb in qla1280.c
# 
# ChangeSet
#   2005/01/12 09:29:50-06:00 akpm@osdl.org 
#   [PATCH] SCSI aic7xxx: kill kernel 2.2 #ifdef's
#   
#   From: Adrian Bunk <bunk@stusta.de>
#   
#   The patch below kills kernel 2.2 #ifdef's from the SCSI aic7xxx driver.
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/aic7xxx/aic7xxx_pci.c
#   2005/01/10 00:47:25-06:00 akpm@osdl.org +2 -2
#   SCSI aic7xxx: kill kernel 2.2 #ifdef's
# 
# drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
#   2005/01/10 00:47:25-06:00 akpm@osdl.org +0 -91
#   SCSI aic7xxx: kill kernel 2.2 #ifdef's
# 
# drivers/scsi/aic7xxx/aic7xxx_osm.h
#   2005/01/10 00:47:25-06:00 akpm@osdl.org +0 -2
#   SCSI aic7xxx: kill kernel 2.2 #ifdef's
# 
# drivers/scsi/aic7xxx/aic7770_osm.c
#   2005/01/10 00:47:25-06:00 akpm@osdl.org +0 -12
#   SCSI aic7xxx: kill kernel 2.2 #ifdef's
# 
# MAINTAINERS
#   2005/01/11 16:57:33+00:00 ben-linux@org.rmk.(none) +14 -0
#   [PATCH] 2390/1: Simtec Electronics MAINTAINERS file entries
# 
# ChangeSet
#   2005/01/12 15:19:25+00:00 catalin.marinas@com.rmk.(none) 
#   [ARM PATCH] 2389/1: semaphore.c warning fixed
#   
#   Patch from Catalin Marinas
#   
#   The patch adds the "ax" attributes to the .sched.text section to
#   avoid a compiler warning.
#   
#   Signed-off-by: Catalin Marinas
#   Signed-off-by: Russell King
# 
# arch/arm/kernel/semaphore.c
#   2005/01/12 00:00:00+00:00 catalin.marinas@com.rmk.(none) +1 -1
#   [PATCH] 2389/1: semaphore.c warning fixed
# 
# ChangeSet
#   2005/01/12 15:14:51+00:00 rpurdie@net.rmk.(none) 
#   [ARM PATCH] 2388/1: Add SSP control code for Sharp SL-C7xx Series (Corgi)
#   
#   Patch from Richard Purdie
#   
#   The Sharp SL-C7xx Series (Corgi) has 3 devices connected to the SSP
#   interface each needing different configurations of the port.
#   This code provides the necessary access and locking so drivers can
#   access these components. It uses the functions provided by the PXA
#   SSP driver to access the port.
#   It also adds some machine specific GPIO definitions used by this
#   code and adds some comments to existing definitions.
#   
#   Signed-off-by: Richard Purdie
#   Signed-off-by: Russell King
# 
# include/asm-arm/arch-pxa/corgi.h
#   2005/01/12 00:00:00+00:00 rpurdie@net.rmk.(none) +12 -10
#   [PATCH] 2388/1: Add SSP control code for Sharp SL-C7xx Series (Corgi)
# 
# arch/arm/mach-pxa/corgi.c
#   2005/01/12 00:00:00+00:00 rpurdie@net.rmk.(none) +6 -0
#   [PATCH] 2388/1: Add SSP control code for Sharp SL-C7xx Series (Corgi)
# 
# arch/arm/mach-pxa/Makefile
#   2005/01/12 00:00:00+00:00 rpurdie@net.rmk.(none) +1 -1
#   [PATCH] 2388/1: Add SSP control code for Sharp SL-C7xx Series (Corgi)
# 
# arch/arm/mach-pxa/corgi_ssp.c
#   2005/01/12 00:00:00+00:00 rpurdie@net.rmk.(none) +247 -0
#   [PATCH] 2388/1: Add SSP control code for Sharp SL-C7xx Series (Corgi)
# 
# arch/arm/mach-pxa/corgi_ssp.c
#   2005/01/12 00:00:00+00:00 rpurdie@net.rmk.(none) +0 -0
#   BitKeeper file /usr/src/bk/linux-2.6-rmk/arch/arm/mach-pxa/corgi_ssp.c
# 
# ChangeSet
#   2005/01/12 14:01:58+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Remove <asm/atomic.h> include.
#   
#   asm/processor.h doesn't use atomic operations nor types, so
#   there's no need to include asm/atomic.h.
#   
#   Signed-off-by: Russell King <rmk@arm.linux.org.uk>
# 
# include/asm-arm/processor.h
#   2005/01/12 13:51:42+00:00 rmk@flint.arm.linux.org.uk +0 -1
#   Remove <asm/atomic.h> include
# 
# ChangeSet
#   2005/01/12 14:51:01+01:00 kaber@coreworks.de 
#   [PKT_SCHED]: cls_api.c: drop rtnl for loading modules
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/cls_api.c
#   2005/01/12 14:50:54+01:00 kaber@coreworks.de +16 -6
#   [PKT_SCHED]: cls_api.c: drop rtnl for loading modules
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/12 13:49:34+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Don't use __init for function prototypes.
# 
# include/asm-arm/smp.h
#   2005/01/12 13:37:31+00:00 rmk@flint.arm.linux.org.uk +1 -1
#   Don't use __init for function prototypes.
# 
# ChangeSet
#   2005/01/12 11:22:26+01:00 perex@suse.cz 
#   [ALSA] Add suspend callback
#   
#   AC97 Codec Core
#   Add suspend callback for each codec patch.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2005/01/11 10:44:52+01:00 perex@suse.cz +2 -0
#   [ALSA] Add suspend callback
#   
#   D:2005/01/11 17:44:51
#   C:AC97 Codec Core
#   F:include/ac97_codec.h:1.62->1.63 
#   F:pci/ac97/ac97_codec.c:1.167->1.168 
#   L:Add suspend callback for each codec patch.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# include/sound/ac97_codec.h
#   2005/01/11 10:44:51+01:00 perex@suse.cz +1 -0
#   [ALSA] Add suspend callback
#   
#   D:2005/01/11 17:44:51
#   C:AC97 Codec Core
#   F:include/ac97_codec.h:1.62->1.63 
#   F:pci/ac97/ac97_codec.c:1.167->1.168 
#   L:Add suspend callback for each codec patch.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:21:18+01:00 perex@suse.cz 
#   [ALSA] Remove & from function pointers
#   
#   AC97 Codec Core
#   Remove & from function pointers (it works but not common to add it...)
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_patch.c
#   2005/01/11 08:57:20+01:00 perex@suse.cz +2 -2
#   [ALSA] Remove & from function pointers
#   
#   D:2005/01/11 15:57:20
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_patch.c:1.67->1.68 
#   L:Remove & from function pointers (it works but not common to add it...)
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:20:14+01:00 perex@suse.cz 
#   [ALSA] Fixed description about ac97_quirk
#   
#   Documentation
#   Fixed the description about ac97_quirk option.
#   Now it accepts string, too.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# Documentation/sound/alsa/ALSA-Configuration.txt
#   2005/01/11 07:51:11+01:00 perex@suse.cz +15 -10
#   [ALSA] Fixed description about ac97_quirk
#   
#   D:2005/01/11 14:51:11
#   C:Documentation
#   F:Documentation/ALSA-Configuration.txt:1.60->1.61 
#   L:Fixed the description about ac97_quirk option.
#   L:Now it accepts string, too.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:19:00+01:00 perex@suse.cz 
#   [ALSA] Adapt SPDIF Input selection for Realtek ALC658
#   
#   AC97 Codec Core
#   This fixes the SPDIF Input selection for ALC658 as Realtek has
#   changed the meaning betweenALC655 and ALC658.
#   
#   Signed-off-by: Stefan Macher <Stefan.Macher@web.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_patch.c
#   2005/01/11 06:17:42+01:00 perex@suse.cz +4 -1
#   [ALSA] Adapt SPDIF Input selection for Realtek ALC658
#   
#   D:2005/01/11 13:17:42
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_patch.c:1.66->1.67 
#   L:This fixes the SPDIF Input selection for ALC658 as Realtek has
#   L:changed the meaning betweenALC655 and ALC658.
#   Signed-off-by: Stefan Macher <Stefan.Macher@web.de>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:17:53+01:00 perex@suse.cz 
#   [ALSA] Fix Oops at resume
#   
#   AC97 Codec Core
#   Fixed Oops at resume on certain codecs.
#   Set null ops when no patch exists or the patch doesn't set build_ops.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/ac97/ac97_codec.c
#   2005/01/11 06:16:55+01:00 perex@suse.cz +10 -4
#   [ALSA] Fix Oops at resume
#   
#   D:2005/01/11 13:16:55
#   C:AC97 Codec Core
#   F:pci/ac97/ac97_codec.c:1.166->1.167 
#   L:Fixed Oops at resume on certain codecs.
#   L:Set null ops when no patch exists or the patch doesn't set build_ops.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:16:40+01:00 perex@suse.cz 
#   [ALSA] remove compatibility code for 2.2.x kernels
#   
#   CA0106 driver
#   
#   
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ca0106/ca0106_proc.c
#   2005/01/10 00:33:03+01:00 perex@suse.cz +0 -1
#   [ALSA] remove compatibility code for 2.2.x kernels
#   
#   D:2005/01/10 07:33:03
#   C:CA0106 driver
#   F:pci/ca0106/ca0106_mixer.c:1.1->1.2 
#   F:pci/ca0106/ca0106_proc.c:1.1->1.2 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# sound/pci/ca0106/ca0106_mixer.c
#   2005/01/10 00:33:03+01:00 perex@suse.cz +0 -1
#   [ALSA] remove compatibility code for 2.2.x kernels
#   
#   D:2005/01/10 07:33:03
#   C:CA0106 driver
#   F:pci/ca0106/ca0106_mixer.c:1.1->1.2 
#   F:pci/ca0106/ca0106_proc.c:1.1->1.2 
#   L:
#   Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
# 
# ChangeSet
#   2005/01/12 11:15:36+01:00 perex@suse.cz 
#   [ALSA] Add quirk for HP zv5000
#   
#   Intel8x0 driver
#   Added the quirk for HP zv5000 (mute LED with EAPD).
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0.c
#   2005/01/07 11:48:43+01:00 perex@suse.cz +6 -0
#   [ALSA] Add quirk for HP zv5000
#   
#   D:2005/01/07 18:48:43
#   C:Intel8x0 driver
#   F:pci/intel8x0.c:1.187->1.188 
#   L:Added the quirk for HP zv5000 (mute LED with EAPD).
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:13:46+01:00 perex@suse.cz 
#   [ALSA] Fix float format support
#   
#   MIXART driver
#   Fixed typos in float format support.
#   
#   Signed-off-by: Markus Bollinger<bollinger@digigram.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/mixart/mixart.c
#   2005/01/07 10:40:41+01:00 perex@suse.cz +2 -2
#   [ALSA] Fix float format support
#   
#   D:2005/01/07 17:40:41
#   C:MIXART driver
#   F:pci/mixart/mixart.c:1.23->1.24 
#   L:Fixed typos in float format support.
#   Signed-off-by: Markus Bollinger<bollinger@digigram.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:12:00+01:00 perex@suse.cz 
#   [ALSA] Fix description of ALSA/OSS device mapping
#   
#   Documentation
#   Fixed the description of ALSA/OSS device mapping.  The direction
#   suffix was missing in ALSA devices.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# Documentation/sound/alsa/ALSA-Configuration.txt
#   2005/01/07 09:02:20+01:00 perex@suse.cz +14 -11
#   [ALSA] Fix description of ALSA/OSS device mapping
#   
#   D:2005/01/07 16:02:20
#   C:Documentation
#   F:Documentation/ALSA-Configuration.txt:1.59->1.60 
#   L:Fixed the description of ALSA/OSS device mapping.  The direction
#   L:suffix was missing in ALSA devices.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:10:10+01:00 perex@suse.cz 
#   [ALSA] ac97 quirk entries for HP xw6200 & xw8000
#   
#   Intel8x0 driver
#   Add AC97 quick list entries to snd-intel8x0 for HP xw6200 and xw8000.
#   
#   Signed-off-by: John W. Linville <linville@tuxdriver.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/pci/intel8x0.c
#   2005/01/07 07:10:28+01:00 perex@suse.cz +13 -1
#   [ALSA] ac97 quirk entries for HP xw6200 & xw8000
#   
#   D:2005/01/07 14:10:28
#   C:Intel8x0 driver
#   F:pci/intel8x0.c:1.186->1.187 
#   L:Add AC97 quick list entries to snd-intel8x0 for HP xw6200 and xw8000.
#   Signed-off-by: John W. Linville <linville@tuxdriver.com>
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 11:08:29+01:00 perex@suse.cz 
#   [ALSA] Fix ioctl arguments
#   
#   RawMidi Midlevel
#   Fixed the wrong pointer types passed to get_user() for
#   DROP and DRAIN ioctls.
#   
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# sound/core/rawmidi.c
#   2005/01/07 07:09:15+01:00 perex@suse.cz +2 -2
#   [ALSA] Fix ioctl arguments
#   
#   D:2005/01/07 14:09:15
#   C:RawMidi Midlevel
#   F:core/rawmidi.c:1.50->1.51 
#   L:Fixed the wrong pointer types passed to get_user() for
#   L:DROP and DRAIN ioctls.
#   Signed-off-by: Takashi Iwai <tiwai@suse.de>
# 
# ChangeSet
#   2005/01/12 00:30:07-05:00 fli@ati.com 
#   [libata sata_sil] support ATI IXP300/IXP400 SATA
# 
# drivers/scsi/sata_sil.c
#   2005/01/12 00:29:53-05:00 fli@ati.com +2 -0
#   [libata sata_sil] support ATI IXP300/IXP400 SATA
# 
# ChangeSet
#   2005/01/12 00:21:23-05:00 akpm@osdl.org 
#   [PATCH] 3c515 warning fix
#   
#   drivers/net/3c515.c: In function `__check_rx_copybreak':
#   drivers/net/3c515.c:406: warning: return discards qualifiers from pointer target type
#   drivers/net/3c515.c: At top level:
#   drivers/net/3c515.c:406: warning: initialization discards qualifiers from pointer target type
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
# 
# drivers/net/3c515.c
#   2005/01/11 01:33:57-05:00 akpm@osdl.org +1 -1
#   3c515 warning fix
# 
# ChangeSet
#   2005/01/12 00:21:09-05:00 akpm@osdl.org 
#   [PATCH] ixgb whitespace fix
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
# 
# drivers/net/ixgb/ixgb_hw.c
#   2005/01/09 02:50:35-05:00 akpm@osdl.org +4 -6
#   ixgb whitespace fix
# 
# ChangeSet
#   2005/01/12 00:20:57-05:00 akpm@osdl.org 
#   [PATCH] eepro build fix
#   
#   drivers/net/eepro.c:1799: initializer element is not constant
#   drivers/net/eepro.c:1799: (near initialization for `__param_arr_io.num')
#   drivers/net/eepro.c:1800: initializer element is not constant
#   drivers/net/eepro.c:1800: (near initialization for `__param_arr_irq.num')
#   drivers/net/eepro.c:1801: initializer element is not constant
#   drivers/net/eepro.c:1801: (near initialization for `__param_arr_mem.num')
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
# 
# drivers/net/eepro.c
#   2005/01/11 01:15:07-05:00 akpm@osdl.org +3 -3
#   eepro build fix
# 
# ChangeSet
#   2005/01/12 00:18:52-05:00 jgarzik@pobox.com 
#   Merge pobox.com:/garz/repo/linux-2.6
#   into pobox.com:/garz/repo/net-drivers-2.6
# 
# drivers/net/wireless/wl3501_cs.c
#   2005/01/12 00:18:47-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/12 00:34:00+00:00 rpurdie@net.rmk.(none) 
#   [ARM PATCH] 2386/1: Tidy up Sharp SCOOP driver coding style
#   
#   Patch from Richard Purdie
#   
#   Tidy up a couple of coding style issues in the Sharp SCOOP Driver
#   
#   Signed-off-by: Richard Purdie
#   Signed-off-by: Russell King
# 
# ChangeSet
#   2005/01/11 16:31:29-08:00 rja@sgi.com 
#   [IA64-SGI] Altix BTE error handling fix
#   
#   This patch fixes BTE off node error handling.
#   
#   Signed-off-by: Russ Anderson <rja@sgi.com>
#   Acked-by: Robin Holt <holt@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/arm/common/scoop.c
#   2005/01/12 00:00:00+00:00 rpurdie@net.rmk.(none) +4 -2
#   [PATCH] 2386/1: Tidy up Sharp SCOOP driver coding style
# 
# arch/ia64/sn/kernel/bte_error.c
#   2005/01/11 16:28:31-08:00 rja@sgi.com +10 -1
#   Altix BTE error handling fix
# 
# ChangeSet
#   2005/01/12 00:23:30+00:00 dsaxena@net.rmk.(none) 
#   [ARM PATCH] 2381/1: Add <linux/kernel.h> to IXP4xx source files
#   
#   Patch from Deepak Saxena
#   
#   We should be including <linux/kernel.h> to pick up various important
#   constants that might be needed by other include files.
#   
#   Signed-off-by: Deepak Saxena
#   Signed-off-by: Russell King
# 
# ChangeSet
#   2005/01/11 16:23:15-08:00 jbarnes@sgi.com 
#   [IA64-SGI] io_init.c: gcc4 fixes for sn2
#   
#   This patch is needed since "warning: use of cast expressions as lvalues is
#   deprecated" turned into an error in gcc4.  We can use the convenience macros
#   for read access and explicit assignments for initialization.  I thought about
#   using Alexandre's fixes, but this seemed a little simpler.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/sn/kernel/io_init.c
#   2005/01/11 16:22:08-08:00 jbarnes@sgi.com +3 -3
#   gcc4 fixes for sn2
# 
# arch/arm/mach-ixp4xx/prpmc1100-setup.c
#   2005/01/11 20:56:29+00:00 dsaxena@net.rmk.(none) +1 -0
#   [PATCH] 2381/1: Add <linux/kernel.h> to IXP4xx source files
# 
# arch/arm/mach-ixp4xx/prpmc1100-pci.c
#   2005/01/11 20:56:24+00:00 dsaxena@net.rmk.(none) +1 -0
#   [PATCH] 2381/1: Add <linux/kernel.h> to IXP4xx source files
# 
# arch/arm/mach-ixp4xx/ixdpg425-pci.c
#   2005/01/11 20:56:19+00:00 dsaxena@net.rmk.(none) +1 -0
#   [PATCH] 2381/1: Add <linux/kernel.h> to IXP4xx source files
# 
# arch/arm/mach-ixp4xx/ixdp425-setup.c
#   2005/01/11 20:56:17+00:00 dsaxena@net.rmk.(none) +1 -0
#   [PATCH] 2381/1: Add <linux/kernel.h> to IXP4xx source files
# 
# arch/arm/mach-ixp4xx/ixdp425-pci.c
#   2005/01/11 20:56:13+00:00 dsaxena@net.rmk.(none) +1 -0
#   [PATCH] 2381/1: Add <linux/kernel.h> to IXP4xx source files
# 
# arch/arm/mach-ixp4xx/coyote-setup.c
#   2005/01/11 20:56:10+00:00 dsaxena@net.rmk.(none) +1 -0
#   [PATCH] 2381/1: Add <linux/kernel.h> to IXP4xx source files
# 
# arch/arm/mach-ixp4xx/coyote-pci.c
#   2005/01/11 20:56:00+00:00 dsaxena@net.rmk.(none) +1 -0
#   [PATCH] 2381/1: Add <linux/kernel.h> to IXP4xx source files
# 
# ChangeSet
#   2005/01/11 16:19:26-08:00 jbarnes@sgi.com 
#   [IA64] pci.c: fix warning
#   
#   Fix a 'mixing code and declarations' warning in pci.c by creating a small
#   function that's a no-op if CONFIG_NUMA=n but otherwise includes the proper
#   extern. Similar patch also submitted by <matthew@wil.cx>
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
# 
# ChangeSet
#   2005/01/12 00:17:44+00:00 dsaxena@net.rmk.(none) 
#   [ARM PATCH] 2378/1: Trivial: Update my info in CREDITS file
#   
#   Patch from Deepak Saxena
#   
#   Signed-off-by: Deepak Saxena
#   Signed-off-by: Russell King
# 
# arch/ia64/pci/pci.c
#   2005/01/11 16:17:08-08:00 jbarnes@sgi.com +14 -5
#   fix warning
# 
# CREDITS
#   2005/01/11 18:51:51+00:00 dsaxena@net.rmk.(none) +3 -3
#   [PATCH] 2378/1: Trivial: Update my info in CREDITS file
# 
# ChangeSet
#   2005/01/11 16:13:38-08:00 hannal@us.ibm.com 
#   [IA64] pci.c: pci_find_device is going away
#   
#   Ok. Here is the reroll of the original patch to us for_each_pci_dev:
#    
#   Signed-off-by: Hanna Linder <hannal@us.ibm.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/pci/pci.c
#   2005/01/11 16:12:44-08:00 hannal@us.ibm.com +1 -1
#   pci_find_device is going away
# 
# ChangeSet
#   2005/01/12 00:12:19+00:00 ben-linux@org.rmk.(none) 
#   [ARM PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
#   
#   Patch from Ben Dooks
#   
#   This cleans up a few items in arch/arm/mach-s3c2410
#   with naming of functions and a build problem. Items
#   which are general to s3c2410 and s3c2440 are now
#   named s3c24xx_ instead of s3c2410_, as well as
#   moving them to the correct headers.
#   The patch also fixes a problem where at least one
#   s3c2410 target had to be selected to allow an s3c2440
#   target to build without error.
#   The following have been renamed:
#   	s3c2410_init_irq -> s3c24xx_init_irq
#   	s3c2410_timer -> s3c24xx_timer
#   
#   Signed-off-by: Ben Dooks
#   Signed-off-by: Russell King
# 
# ChangeSet
#   2005/01/11 16:11:40-08:00 hannal@us.ibm.com 
#   [IA64] sba_iommu.c: pci_find_device is going away
#   
#   Here is the reroll of the sba_iommu.c patch to use for_each_pci_dev.
#    
#   Signed-off-by: Hanna Linder <hannal@us.ibm.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/hp/common/sba_iommu.c
#   2005/01/11 16:10:37-08:00 hannal@us.ibm.com +1 -1
#   pci_find_device is going away
# 
# ChangeSet
#   2005/01/11 16:08:20-08:00 domen@coderock.org 
#   [IA64] sn_hwperf.c: vfree() checking cleanups
#   
#   Signed-off by: James Lamanna <jlamanna@gmail.com>
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/arm/mach-s3c2410/time.c
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +1 -1
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/s3c2440.h
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +16 -5
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/s3c2440-dsc.c
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +3 -2
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/s3c2410.h
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +11 -5
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/mach-vr1000.c
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +4 -4
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/mach-smdk2410.c
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +2 -3
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/mach-rx3715.c
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +3 -4
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/mach-h1940.c
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +3 -3
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/mach-bast.c
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +4 -4
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/irq.c
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +2 -2
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/arm/mach-s3c2410/cpu.h
#   2005/01/11 10:04:01+00:00 ben-linux@org.rmk.(none) +8 -18
#   [PATCH] 2376/1: S3C2410 - cleanup 2410/2440 distinctions, fix build
# 
# arch/ia64/sn/kernel/sn2/sn_hwperf.c
#   2005/01/11 16:05:23-08:00 domen@coderock.org +2 -4
#   vfree() checking cleanups
# 
# ChangeSet
#   2005/01/12 00:05:09+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Fix smp.c includes
#   
#   Remove asm/smp.h include, use linux/smp.h instead.
#   Add linux/cpu.h include.
# 
# arch/arm/kernel/smp.c
#   2005/01/12 00:01:43+00:00 rmk@flint.arm.linux.org.uk +4 -4
#   Remove asm/smp.h include, use linux/smp.h instead.
#   Add linux/cpu.h include.
# 
# ChangeSet
#   2005/01/11 16:00:07-08:00 schwab@suse.de 
#   [IA64] Fix PTRACE_GETEVENTMSG ia32 emulation
#   
#   This patch fixes PTRACE_GETEVENTMSG for the ia32 emulation.  The parameter
#   is a pointer, thus needs to be converted.
#    
#   Signed-off-by: Andreas Schwab <schwab@suse.de>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/ia32/sys_ia32.c
#   2005/01/11 15:58:41-08:00 schwab@suse.de +4 -0
#   Fix PTRACE_GETEVENTMSG ia32 emulation
# 
# ChangeSet
#   2005/01/11 15:49:52-08:00 jbarnes@sgi.com 
#   [IA64-SGI] fix bogus address dereference in sn/setup.c
#   
#   Some code in sn/setup.c was trying to dereference a physical address, which
#   usually doesn't work (esp. not with the region register init patch I posted).
#   This patch converts the function used to find the klconfig to return virtual
#   char * instead of a physical address and updates the caller to deal with it.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/sn/sn_sal.h
#   2005/01/11 15:49:02-08:00 jbarnes@sgi.com +2 -2
#   fix bogus address dereference in sn/setup.c
# 
# arch/ia64/sn/kernel/setup.c
#   2005/01/11 15:48:43-08:00 jbarnes@sgi.com +4 -4
#   fix bogus address dereference in sn/setup.c
# 
# ChangeSet
#   2005/01/11 15:47:04-08:00 jbarnes@sgi.com 
#   [IA64] clear all region registers at boot
#   
#   If we initialize *all* of the region registers to be non-identity mapped we
#   can catch a few more bugs that might be covered up by whatever their previous
#   state was.  This patch sets them all up to use VHPT (i.e. non alt-tlb)
#   address translation.  It already helped me find one bug in the sn2
#   initialization code.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/kernel/head.S
#   2005/01/11 15:45:50-08:00 jbarnes@sgi.com +22 -0
#   clear all region registers at boot
# 
# ChangeSet
#   2005/01/11 15:43:41-08:00 bjorn.helgaas@hp.com 
#   [IA64] reset console_loglevel so INIT output always goes to console
#   
#   Reset console_loglevel early in INIT handler.  Otherwise, if
#   it has been turned down (i.e., with "dmesg -n1"), the user may
#   see no effect at all from issuing an INIT.  We're never going
#   to run any more user code, so there won't be any opportunity for
#   anything to collect the output from the dmesg buffer.
#    
#   Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/kernel/mca.c
#   2005/01/11 15:42:37-08:00 bjorn.helgaas@hp.com +1 -0
#   reset console_loglevel so INIT output always goes to console
# 
# ChangeSet
#   2005/01/11 15:39:35-08:00 jbarnes@sgi.com 
#   [IA64] defconfig update
#   
#   This adds support for a few new modules (e.g. Infiniband, new ACPI stuff,
#   etc.) and also enables initrd support (required for Fedora for example--it's
#   really not that painful, I use the same initrd for most of my kernels).
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# ChangeSet
#   2005/01/11 23:37:59+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Relocate ipi_count into ipi data structures.
#   
#   This removes ipi_count from the globally visible per-cpu cpu data
#   structure.
# 
# arch/ia64/defconfig
#   2005/01/11 15:37:50-08:00 jbarnes@sgi.com +43 -8
#   update & include initrd support
# 
# include/asm-arm/cpu.h
#   2005/01/11 23:34:15+00:00 rmk@flint.arm.linux.org.uk +0 -1
#   Remove ipi_count.
# 
# arch/arm/kernel/smp.c
#   2005/01/11 23:34:15+00:00 rmk@flint.arm.linux.org.uk +6 -6
#   Move ipi_count to ipi_data structure rather than global per cpu data
#   structure.
# 
# ChangeSet
#   2005/01/11 23:26:57+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Add SMP IRQ affinity and routing support.
#   
#   Provide /proc/irq/*/smp_affinity support, and add necessary methods
#   to allow a machine to route the interrupt to the desired CPU.
# 
# include/asm-arm/mach/irq.h
#   2005/01/11 23:22:04+00:00 rmk@flint.arm.linux.org.uk +14 -0
#   Add "set_cpu" method to route interrupts to a specific CPU.
# 
# arch/arm/kernel/irq.c
#   2005/01/11 23:22:04+00:00 rmk@flint.arm.linux.org.uk +98 -3
#   Add basic SMP IRQ affinity support.
# 
# ChangeSet
#   2005/01/11 22:22:57+01:00 kaber@coreworks.de 
#   [PKT_SCHED]: act_api.c: kill some exports
#   
#   init, destroy, dump etc. should be performed through Thomas's tcf_exts,
#   don't export the act_api.c functions to modules. tcf_action_dump_1
#   will follow once tcf_dump_walker is converted to callbacks.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/act_api.c
#   2005/01/11 22:22:49+01:00 kaber@coreworks.de +0 -6
#   [PKT_SCHED]: act_api.c: kill some exports
#   
#   init, destroy, dump etc. should be performed through Thomas's tcf_exts,
#   don't export the act_api.c functions to modules. tcf_action_dump_1
#   will follow once tcf_dump_walker is converted to callbacks.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 22:12:44+01:00 kaber@coreworks.de 
#   [PKT_SCHED]: tcf_exts: rate_tlv is optional
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/cls_api.c
#   2005/01/11 22:12:34+01:00 kaber@coreworks.de +3 -3
#   [PKT_SCHED]: tcf_exts: rate_tlv is optional
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 22:10:34+01:00 kaber@coreworks.de 
#   [PKT_SCHED]: act_api.c: drop rtnl for loading modules
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/cls_api.c
#   2005/01/11 22:10:27+01:00 kaber@coreworks.de +18 -7
#   [PKT_SCHED]: act_api.c: drop rtnl for loading modules
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/act_api.c
#   2005/01/11 22:10:26+01:00 kaber@coreworks.de +19 -4
#   [PKT_SCHED]: act_api.c: drop rtnl for loading modules
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 12:24:42-08:00 domen@coderock.org 
#   [IA64] simeth.c: Remove unneeded casts of (void *) pointers.
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/hp/sim/simeth.c
#   2005/01/11 12:23:41-08:00 domen@coderock.org +4 -4
#   Remove unneeded casts of (void *) pointers.
# 
# ChangeSet
#   2005/01/11 11:58:15-08:00 jbarnes@sgi.com 
#   [IA64] update sn2_defconfig (fix initrd, add IB support)
#   Don't know what happened to initrd support, but 'make sn2_defconfig' no longer
#   enables it.  This patch should fix that, along with enabling modular IB
#   support.
#    
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# arch/ia64/configs/sn2_defconfig
#   2005/01/11 11:57:37-08:00 jbarnes@sgi.com +44 -7
#   update sn2_defconfig (fix initrd, add IB support)
# 
# ChangeSet
#   2005/01/11 20:32:35+01:00 kaber@coreworks.de 
#   [PKT_SCHED]: tc actions: disable bhs while lock is held in init path
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/police.c
#   2005/01/11 20:32:28+01:00 kaber@coreworks.de +2 -2
#   [PKT_SCHED]: tc actions: disable bhs while lock is held in init path
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/mirred.c
#   2005/01/11 20:32:28+01:00 kaber@coreworks.de +2 -2
#   [PKT_SCHED]: tc actions: disable bhs while lock is held in init path
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 20:25:26+01:00 kaber@coreworks.de 
#   [PKT_SCHED]: Fix memory leaks in cls_u32.c error path
#   
#   Also silence an unused-variable warning when CONFIG_CLS_U32_MARK is not set.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/cls_u32.c
#   2005/01/11 20:25:16+01:00 kaber@coreworks.de +11 -5
#   [PKT_SCHED]: Fix memory leaks in cls_u32.c error path
#   
#   Also silence an unused-variable warning when CONFIG_CLS_U32_MARK is not set.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 20:24:08+01:00 kaber@coreworks.de 
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/sch_tbf.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +1 -1
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/sch_red.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +1 -1
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/sch_htb.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +2 -2
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/sch_hfsc.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +1 -2
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/sch_gred.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +6 -9
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/sch_dsmark.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +1 -2
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/sch_cbq.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +2 -3
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/sch_atm.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +2 -2
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/police.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +2 -4
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/pedit.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +1 -2
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/mirred.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +1 -2
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/ipt.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +1 -2
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/gact.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +1 -2
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/sched/act_api.c
#   2005/01/11 20:24:00+01:00 kaber@coreworks.de +5 -8
#   [PKT_SCHED]: Use rtattr_parse_nested where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 17:08:03+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Add synchronize_irq() support.
# 
# arch/arm/kernel/irq.c
#   2005/01/11 17:04:30+00:00 rmk@flint.arm.linux.org.uk +25 -0
#   Add synchronize_irq() support.
# 
# ChangeSet
#   2005/01/11 16:59:26+00:00 rmk@flint.arm.linux.org.uk 
#   [ARM] Add show_ipi_list() call.
# 
# include/asm-arm/smp.h
#   2005/01/11 16:56:31+00:00 rmk@flint.arm.linux.org.uk +7 -0
#   Add show_ipi_list() prototype.
# 
# arch/arm/kernel/irq.c
#   2005/01/11 16:56:31+00:00 rmk@flint.arm.linux.org.uk +3 -0
#   Add show_ipi_list() call.
# 
# ChangeSet
#   2005/01/10 21:04:15-08:00 davem@nuts.davemloft.net 
#   Merge nuts.davemloft.net:/disk1/BK/network-2.6
#   into nuts.davemloft.net:/disk1/BK/net-2.6
# 
# drivers/net/8139too.c
#   2005/01/10 21:04:03-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# drivers/bluetooth/hci_usb.c
#   2005/01/10 21:04:03-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# drivers/bluetooth/bfusb.c
#   2005/01/10 21:04:03-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/11 00:03:27-05:00 jgarzik@pobox.com 
#   e1000/ixgb net drivers: rename global symbol to fix 'make allyesconfig'
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/11 00:03:21-05:00 jgarzik@pobox.com +2 -2
#   e1000/ixgb net drivers: rename global symbol to fix 'make allyesconfig'
# 
# drivers/net/ixgb/ixgb_ethtool.c
#   2005/01/11 00:03:21-05:00 jgarzik@pobox.com +1 -1
#   e1000/ixgb net drivers: rename global symbol to fix 'make allyesconfig'
# 
# drivers/net/e1000/e1000_main.c
#   2005/01/11 00:03:21-05:00 jgarzik@pobox.com +2 -2
#   e1000/ixgb net drivers: rename global symbol to fix 'make allyesconfig'
# 
# drivers/net/e1000/e1000_ethtool.c
#   2005/01/11 00:03:21-05:00 jgarzik@pobox.com +1 -1
#   e1000/ixgb net drivers: rename global symbol to fix 'make allyesconfig'
# 
# ChangeSet
#   2005/01/11 02:47:15-02:00 acme@conectiva.com.br 
#   [UDP] merge udp_sock with udp_opt
#   
#   No need for two structs, follow the new inet_sock layout
#   style.
#   
#   Signed-off-by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv6/udp.c
#   2005/01/11 02:46:44-02:00 acme@conectiva.com.br +5 -5
#   [UDP] merge udp_sock with udp_opt
#   
#   No need for two structs, follow the new inet_sock layout
#   style.
#   
#   Signed-off-by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/udp.c
#   2005/01/11 02:46:44-02:00 acme@conectiva.com.br +8 -8
#   [UDP] merge udp_sock with udp_opt
#   
#   No need for two structs, follow the new inet_sock layout
#   style.
#   
#   Signed-off-by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/udp.h
#   2005/01/11 02:46:44-02:00 acme@conectiva.com.br +9 -13
#   [UDP] merge udp_sock with udp_opt
#   
#   No need for two structs, follow the new inet_sock layout
#   style.
#   
#   Signed-off-by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/ipv6.h
#   2005/01/11 02:46:44-02:00 acme@conectiva.com.br +1 -2
#   [UDP] merge udp_sock with udp_opt
#   
#   No need for two structs, follow the new inet_sock layout
#   style.
#   
#   Signed-off-by: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 23:05:14-05:00 jgarzik@pobox.com 
#   Merge pobox.com:/garz/repo/netdev-2.6/orinoco
#   into pobox.com:/garz/repo/net-drivers-2.6
# 
# drivers/net/wireless/orinoco.c
#   2005/01/10 23:05:11-05:00 jgarzik@pobox.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/10 23:01:45-05:00 jgarzik@pobox.com 
#   Manual ixgb merge.
# 
# drivers/net/ixgb/ixgb_param.c
#   2005/01/10 23:01:39-05:00 jgarzik@pobox.com +0 -2
#   Manual ixgb merge.
# 
# ChangeSet
#   2005/01/10 22:58:17-05:00 hch@lst.de 
#   [PATCH] mark arcdev_setup static
#   
#   It's only used in arcnet.c, and following the model of the other
#   link layers it doesn't make sense to use it outside alloc_arcdev()
#   either.
# 
# include/linux/arcdevice.h
#   2004/10/23 10:09:24-04:00 hch@lst.de +0 -1
#   mark arcdev_setup static
# 
# drivers/net/arcnet/arcnet.c
#   2004/10/23 10:09:36-04:00 hch@lst.de +1 -2
#   mark arcdev_setup static
# 
# ChangeSet
#   2005/01/10 22:58:06-05:00 penguin@muskoka.com 
#   [PATCH] smc-ultra.c too-verbose driver
# 
# drivers/net/smc-ultra.c
#   2005/01/09 15:33:06-05:00 penguin@muskoka.com +0 -2
#   smc-ultra.c too-verbose driver
# 
# ChangeSet
#   2005/01/10 22:57:56-05:00 ak@suse.de 
#   [PATCH] Fix gcc4 compilation in s2io net driver
#   
#   Signed-off-by: Andi Kleen <ak@suse.de>
# 
# drivers/net/s2io.h
#   2005/01/10 22:57:50-05:00 ak@suse.de +2 -2
#   Fix gcc4 compilation in s2io net driver
# 
# ChangeSet
#   2005/01/10 22:57:45-05:00 rddunlap@osdl.org 
#   [PATCH] wl3501: fix module_param types/warnings
#   
#   Fix gcc warning:
#   drivers/net/wireless/wl3501_cs.c:2282: warning: return from incompatible pointer type
#   
#   module_param() isn't happy about different types for irq_mask;
#   unsigned long vs. int.  Make it uint consistently.
#   
#   Signed-off-by: Randy Dunlap <rddunlap@osdl.org>
# 
# drivers/net/wireless/wl3501_cs.c
#   2005/01/10 15:40:44-05:00 rddunlap@osdl.org +2 -2
#   wl3501: fix module_param types/warnings
# 
# ChangeSet
#   2005/01/11 03:46:01+01:00 laforge@netfilter.org 
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6table_raw.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +1 -2
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6table_mangle.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +1 -2
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6table_filter.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +1 -2
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6_tables.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +8 -7
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/iptable_raw.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +1 -2
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/iptable_mangle.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +1 -2
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/iptable_filter.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +3 -4
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_tables.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +7 -7
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_nat_rule.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +3 -4
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/arptable_filter.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +1 -2
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/arp_tables.c
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +8 -7
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# include/linux/netfilter_ipv6/ip6_tables.h
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +2 -4
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# include/linux/netfilter_ipv4/ip_tables.h
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +2 -4
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# include/linux/netfilter_arp/arp_tables.h
#   2005/01/11 03:45:54+01:00 laforge@netfilter.org +2 -4
#   [NETFILTER] re-introduce __initdata to {arp,ip,ip6}_tables
#   
#   Instead of just removing the (correct) __initdata as introduced by 
#   http://linux.bkbits.net:8080/linux-2.5/cset@1.2055.4.50                         
#   we rework the code in order to not trigger some misinterpretation by
#   static code checkers.
#   
#   Signed-off-by: Harald Welte <laforge@netfilter.org>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 03:45:03+01:00 pablo@eurodev.net 
#   [NETFILTER]: move ipt_error and ipt_standard to iptables.h
#   
#   Signed-off-by: Pablo Neira Ayuso <pablo@eurodev.net>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/iptable_raw.c
#   2005/01/11 03:44:54+01:00 pablo@eurodev.net +0 -19
#   [NETFILTER]: move ipt_error and ipt_standard to iptables.h
#   
#   Signed-off-by: Pablo Neira Ayuso <pablo@eurodev.net>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/iptable_mangle.c
#   2005/01/11 03:44:54+01:00 pablo@eurodev.net +0 -19
#   [NETFILTER]: move ipt_error and ipt_standard to iptables.h
#   
#   Signed-off-by: Pablo Neira Ayuso <pablo@eurodev.net>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/iptable_filter.c
#   2005/01/11 03:44:54+01:00 pablo@eurodev.net +0 -19
#   [NETFILTER]: move ipt_error and ipt_standard to iptables.h
#   
#   Signed-off-by: Pablo Neira Ayuso <pablo@eurodev.net>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ip_nat_rule.c
#   2005/01/11 03:44:54+01:00 pablo@eurodev.net +0 -19
#   [NETFILTER]: move ipt_error and ipt_standard to iptables.h
#   
#   Signed-off-by: Pablo Neira Ayuso <pablo@eurodev.net>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# include/linux/netfilter_ipv4/ip_tables.h
#   2005/01/11 03:44:54+01:00 pablo@eurodev.net +19 -0
#   [NETFILTER]: move ipt_error and ipt_standard to iptables.h
#   
#   Signed-off-by: Pablo Neira Ayuso <pablo@eurodev.net>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 03:44:14+01:00 kaber@coreworks.de 
#   [NETFILTER]: Fix ip6tables ESP matching with "-p all"
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6_tables.c
#   2005/01/11 03:44:07+01:00 kaber@coreworks.de +1 -1
#   [NETFILTER]: Fix ip6tables ESP matching with "-p all"
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 03:43:46+01:00 kaber@coreworks.de 
#   [NETFILTER]: Add --log-uid option to ipt_LOG/ip6t_LOG
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6t_LOG.c
#   2005/01/11 03:43:38+01:00 kaber@coreworks.de +8 -0
#   [NETFILTER]: Add --log-uid option to ipt_LOG/ip6t_LOG
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv4/netfilter/ipt_LOG.c
#   2005/01/11 03:43:38+01:00 kaber@coreworks.de +8 -0
#   [NETFILTER]: Add --log-uid option to ipt_LOG/ip6t_LOG
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# include/linux/netfilter_ipv6/ip6t_LOG.h
#   2005/01/11 03:43:38+01:00 kaber@coreworks.de +2 -1
#   [NETFILTER]: Add --log-uid option to ipt_LOG/ip6t_LOG
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# include/linux/netfilter_ipv4/ipt_LOG.h
#   2005/01/11 03:43:38+01:00 kaber@coreworks.de +2 -1
#   [NETFILTER]: Add --log-uid option to ipt_LOG/ip6t_LOG
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 03:42:12+01:00 kaber@coreworks.de 
#   [NETFILTER]: Remove skb_linearize in ip6tables
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6table_mangle.c
#   2005/01/11 03:42:05+01:00 kaber@coreworks.de +0 -4
#   [NETFILTER]: Remove skb_linearize in ip6tables
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6_tables.c
#   2005/01/11 03:42:05+01:00 kaber@coreworks.de +0 -4
#   [NETFILTER]: Remove skb_linearize in ip6tables
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/11 03:41:31+01:00 kaber@coreworks.de 
#   [NETFILTER]: Fix stack leakage in ip6tables
#   
#   ip6tables version of Rusty's iptables fix.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# net/ipv6/netfilter/ip6_tables.c
#   2005/01/11 03:41:24+01:00 kaber@coreworks.de +1 -1
#   [NETFILTER]: Fix stack leakage in ip6tables
#   
#   ip6tables version of Rusty's iptables fix.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
# 
# ChangeSet
#   2005/01/10 14:23:32-08:00 jbarnes@sgi.com 
#   [IA64] implements the features required for the HAVE_PCI_LEGACY code in sysfs
#   
#   This patch implements the features required for the HAVE_PCI_LEGACY code in
#   sysfs.  It allows userspace applications to access legacy I/O ports an memory
#   space using files in sysfs on a per-bus basis.  Tested on sn2, but it
#   *should* work on other ia64 platforms as well (though zx1 will probably need
#   machine vectors to do routing of non-base busses).
#   
#   Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/sn/sn_sal.h
#   2005/01/10 14:04:38-08:00 jbarnes@sgi.com +46 -0
#   implements the features required for the HAVE_PCI_LEGACY code in sysfs
# 
# include/asm-ia64/pci.h
#   2005/01/10 14:04:31-08:00 jbarnes@sgi.com +14 -0
#   implements the features required for the HAVE_PCI_LEGACY code in sysfs
# 
# include/asm-ia64/machvec_sn2.h
#   2005/01/10 14:04:23-08:00 jbarnes@sgi.com +6 -0
#   implements the features required for the HAVE_PCI_LEGACY code in sysfs
# 
# include/asm-ia64/machvec_init.h
#   2005/01/10 14:04:16-08:00 jbarnes@sgi.com +3 -0
#   implements the features required for the HAVE_PCI_LEGACY code in sysfs
# 
# include/asm-ia64/machvec.h
#   2005/01/10 14:04:10-08:00 jbarnes@sgi.com +24 -0
#   implements the features required for the HAVE_PCI_LEGACY code in sysfs
# 
# arch/ia64/sn/pci/pci_dma.c
#   2005/01/10 14:04:02-08:00 jbarnes@sgi.com +64 -0
#   implements the features required for the HAVE_PCI_LEGACY code in sysfs
# 
# arch/ia64/pci/pci.c
#   2005/01/10 14:03:12-08:00 jbarnes@sgi.com +113 -1
#   implements the features required for the HAVE_PCI_LEGACY code in sysfs
# 
# ChangeSet
#   2005/01/10 13:58:16-08:00 kaber@trash.net 
#   [PKT_SCHED]: act_api.c: sync multi action order processing
#   
#   Sync tcf_action_init and tca_action_gd. Rename a few variables
#   to make the code more easily understandable and rename the
#   rtattr_failure/nlmsg_failure labels. These are usually called
#   from the netlink macros, it is misleading to use them in a
#   larger function without actually using netlink macros.
#   
#   Multi action orders were processed differently before,
#   tcf_action_init skipped empty ones while tca_action_gd stopped
#   at the first empty one. This patch makes both stop at the first
#   empty one.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:57:56-08:00 kaber@trash.net +35 -51
#   [PKT_SCHED]: act_api.c: sync multi action order processing
#   
#   Sync tcf_action_init and tca_action_gd. Rename a few variables
#   to make the code more easily understandable and rename the
#   rtattr_failure/nlmsg_failure labels. These are usually called
#   from the netlink macros, it is misleading to use them in a
#   larger function without actually using netlink macros.
#   
#   Multi action orders were processed differently before,
#   tcf_action_init skipped empty ones while tca_action_gd stopped
#   at the first empty one. This patch makes both stop at the first
#   empty one.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:56:53-08:00 kaber@trash.net 
#   [PKT_SCHED]: act_api.c: push memory allocation to tcf_action_get_1
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:56:33-08:00 kaber@trash.net +30 -18
#   [PKT_SCHED]: act_api.c: push memory allocation to tcf_action_get_1
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:56:09-08:00 kaber@trash.net 
#   [PKT_SCHED]: act_api.c: remove module loading from get/delete operations
#   
#   If get/delete can't find the action we can assume there is nothing
#   to get/delete.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:55:48-08:00 kaber@trash.net +15 -79
#   [PKT_SCHED]: act_api.c: remove module loading from get/delete operations
#   
#   If get/delete can't find the action we can assume there is nothing
#   to get/delete.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:55:37-08:00 tony.luck@intel.com 
#   Merge intel.com:/data/home/aegl/BK/Linus
#   into intel.com:/data/home/aegl/BK/linux-ia64-release-2.6.11
# 
# arch/ia64/kernel/acpi.c
#   2005/01/10 13:55:30-08:00 tony.luck@intel.com +0 -0
#   Auto merged
# 
# arch/ia64/Kconfig
#   2005/01/10 13:55:30-08:00 tony.luck@intel.com +0 -0
#   Auto merged
# 
# Documentation/kernel-parameters.txt
#   2005/01/10 13:55:30-08:00 tony.luck@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/10 13:55:12-08:00 kaber@trash.net 
#   [PKT_SCHED]: ipt action: fix module refcount underflow/mem leaks in tcf_ipt_cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/ipt.c
#   2005/01/10 13:54:51-08:00 kaber@trash.net +22 -10
#   [PKT_SCHED]: ipt action: fix module refcount underflow/mem leaks in tcf_ipt_cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:54:22-08:00 kaber@trash.net 
#   [PKT_SCHED]: tc actions: remove unnecessary locking for refcnt changes
#   
#   refcnt/bindcnt are only used in user context under the rtnl, no additional
#   locking is necessary. Besides it was only done in some places, so kill it.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/police.c
#   2005/01/10 13:54:01-08:00 kaber@trash.net +0 -2
#   [PKT_SCHED]: tc actions: remove unnecessary locking for refcnt changes
#   
#   refcnt/bindcnt are only used in user context under the rtnl, no additional
#   locking is necessary. Besides it was only done in some places, so kill it.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/pkt_act.h
#   2005/01/10 13:54:01-08:00 kaber@trash.net +1 -3
#   [PKT_SCHED]: tc actions: remove unnecessary locking for refcnt changes
#   
#   refcnt/bindcnt are only used in user context under the rtnl, no additional
#   locking is necessary. Besides it was only done in some places, so kill it.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:53:10-08:00 kaber@trash.net 
#   [PKT_SCHED]: ipt action: fix missing unlock on error path
#   
#   Simply kill the pskb_expand_head, iptables targets already take care
#   of cloned packets.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/ipt.c
#   2005/01/10 13:52:50-08:00 kaber@trash.net +0 -4
#   [PKT_SCHED]: ipt action: fix missing unlock on error path
#   
#   Simply kill the pskb_expand_head, iptables targets already take care
#   of cloned packets.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:52:13-08:00 kaber@trash.net 
#   [PKT_SCHED]: police action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Some attribute sizes are not checked
#   - rta may by NULL
#   - multiple leaks
#   - possible unbalanced unlock
#   - used action is freed after if an error happens while trying to replace
#   - estimator can't be replaced
#   
#   This patch makes replacement atomic, so the old action is either
#   replaced entirely or not touched at all.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/police.c
#   2005/01/10 13:51:52-08:00 kaber@trash.net +49 -37
#   [PKT_SCHED]: police action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Some attribute sizes are not checked
#   - rta may by NULL
#   - multiple leaks
#   - possible unbalanced unlock
#   - used action is freed after if an error happens while trying to replace
#   - estimator can't be replaced
#   
#   This patch makes replacement atomic, so the old action is either
#   replaced entirely or not touched at all.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:51:00-08:00 kaber@trash.net 
#   [PKT_SCHED]: pedit action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Attribute sizes are not checked
#   - rta may by NULL
#   - The action is inserted into the hash before its parameters are set
#   - replacement happens without locking
#   - no reallocation on replacement for possibly changed numbers of keys
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/pedit.c
#   2005/01/10 13:50:39-08:00 kaber@trash.net +53 -28
#   [PKT_SCHED]: pedit action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Attribute sizes are not checked
#   - rta may by NULL
#   - The action is inserted into the hash before its parameters are set
#   - replacement happens without locking
#   - no reallocation on replacement for possibly changed numbers of keys
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/tc_act/tc_pedit.h
#   2005/01/10 13:50:39-08:00 kaber@trash.net +1 -1
#   [PKT_SCHED]: pedit action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Attribute sizes are not checked
#   - rta may by NULL
#   - The action is inserted into the hash before its parameters are set
#   - replacement happens without locking
#   - no reallocation on replacement for possibly changed numbers of keys
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:49:48-08:00 kaber@trash.net 
#   [PKT_SCHED]: mirred action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Attribute sizes are not checked
#   - rta may by NULL
#   - The action is inserted into the hash before its parameters are set
#   - action in hash is freed on error path
#   - action is modified outside of the locked section
#   
#   This patch makes replacement atomic, so the old action is either
#   replaced entirely or not touched at all.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/mirred.c
#   2005/01/10 13:49:28-08:00 kaber@trash.net +43 -45
#   [PKT_SCHED]: mirred action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Attribute sizes are not checked
#   - rta may by NULL
#   - The action is inserted into the hash before its parameters are set
#   - action in hash is freed on error path
#   - action is modified outside of the locked section
#   
#   This patch makes replacement atomic, so the old action is either
#   replaced entirely or not touched at all.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:48:39-08:00 kaber@trash.net 
#   [PKT_SCHED]: ipt action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Attribute sizes are not checked
#   - rta may be NULL
#   - Several leaks and locking errors
#   - When replacement fails the old action is freed while in use
#   
#   This patch makes replacement atomic, so the old action is either
#   replaced entirely or not touched at all.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/ipt.c
#   2005/01/10 13:48:18-08:00 kaber@trash.net +80 -122
#   [PKT_SCHED]: ipt action: fix multiple bugs in init path
#   
#   - Return proper error codes
#   - Attribute sizes are not checked
#   - rta may be NULL
#   - Several leaks and locking errors
#   - When replacement fails the old action is freed while in use
#   
#   This patch makes replacement atomic, so the old action is either
#   replaced entirely or not touched at all.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:47:32-08:00 kaber@trash.net 
#   [PKT_SCHED]: gact action: fix multiple bugs in init path
#   
#   - rta can be NULL
#   - Attribute sizes are not checked
#   - No locking when replacing an action
#   - The action is inserted into the hash before its parameters are set
#   
#   Also return proper error codes.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/gact.c
#   2005/01/10 13:47:12-08:00 kaber@trash.net +34 -32
#   [PKT_SCHED]: gact action: fix multiple bugs in init path
#   
#   - rta can be NULL
#   - Attribute sizes are not checked
#   - No locking when replacing an action
#   - The action is inserted into the hash before its parameters are set
#   
#   Also return proper error codes.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/pkt_act.h
#   2005/01/10 13:47:11-08:00 kaber@trash.net +10 -17
#   [PKT_SCHED]: gact action: fix multiple bugs in init path
#   
#   - rta can be NULL
#   - Attribute sizes are not checked
#   - No locking when replacing an action
#   - The action is inserted into the hash before its parameters are set
#   
#   Also return proper error codes.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:46:21-08:00 kaber@trash.net 
#   [PKT_SCHED]: tc actions: remove checks for impossible conditions
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/police.c
#   2005/01/10 13:46:00-08:00 kaber@trash.net +0 -17
#   [PKT_SCHED]: tc actions: remove checks for impossible conditions
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/pedit.c
#   2005/01/10 13:46:00-08:00 kaber@trash.net +1 -11
#   [PKT_SCHED]: tc actions: remove checks for impossible conditions
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/mirred.c
#   2005/01/10 13:46:00-08:00 kaber@trash.net +3 -20
#   [PKT_SCHED]: tc actions: remove checks for impossible conditions
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/ipt.c
#   2005/01/10 13:46:00-08:00 kaber@trash.net +1 -8
#   [PKT_SCHED]: tc actions: remove checks for impossible conditions
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/gact.c
#   2005/01/10 13:46:00-08:00 kaber@trash.net +1 -12
#   [PKT_SCHED]: tc actions: remove checks for impossible conditions
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:45:40-08:00 kaber@trash.net 
#   [PKT_SCHED]: tc actions: whitespace and coding style cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/police.c
#   2005/01/10 13:45:19-08:00 kaber@trash.net +49 -48
#   [PKT_SCHED]: tc actions: whitespace and coding style cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/pedit.c
#   2005/01/10 13:45:19-08:00 kaber@trash.net +36 -52
#   [PKT_SCHED]: tc actions: whitespace and coding style cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/mirred.c
#   2005/01/10 13:45:19-08:00 kaber@trash.net +48 -58
#   [PKT_SCHED]: tc actions: whitespace and coding style cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/ipt.c
#   2005/01/10 13:45:19-08:00 kaber@trash.net +28 -41
#   [PKT_SCHED]: tc actions: whitespace and coding style cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/gact.c
#   2005/01/10 13:45:19-08:00 kaber@trash.net +35 -47
#   [PKT_SCHED]: tc actions: whitespace and coding style cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:44:52-08:00 kaber@trash.net 
#   [PKT_SCHED]: act_api.c: clean up init path, propagate errors properly
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:44:31-08:00 kaber@trash.net +17 -36
#   [PKT_SCHED]: act_api.c: clean up init path, propagate errors properly
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:43:46-08:00 kaber@trash.net 
#   [RTNETLINK]: Use rtattr_strcmp where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:43:25-08:00 kaber@trash.net +1 -1
#   [RTNETLINK]: Use rtattr_strcmp where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/fib_rules.c
#   2005/01/10 13:43:25-08:00 kaber@trash.net +1 -1
#   [RTNETLINK]: Use rtattr_strcmp where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/devinet.c
#   2005/01/10 13:43:25-08:00 kaber@trash.net +1 -1
#   [RTNETLINK]: Use rtattr_strcmp where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/decnet/dn_rules.c
#   2005/01/10 13:43:25-08:00 kaber@trash.net +1 -1
#   [RTNETLINK]: Use rtattr_strcmp where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/decnet/dn_dev.c
#   2005/01/10 13:43:25-08:00 kaber@trash.net +1 -1
#   [RTNETLINK]: Use rtattr_strcmp where appropriate
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:42:43-08:00 kaber@trash.net 
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/sch_api.c
#   2005/01/10 13:42:22-08:00 kaber@trash.net +3 -2
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/cls_api.c
#   2005/01/10 13:42:22-08:00 kaber@trash.net +3 -2
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:42:22-08:00 kaber@trash.net +7 -18
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/fib_rules.c
#   2005/01/10 13:42:22-08:00 kaber@trash.net +1 -2
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/devinet.c
#   2005/01/10 13:42:22-08:00 kaber@trash.net +1 -1
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/decnet/dn_rules.c
#   2005/01/10 13:42:22-08:00 kaber@trash.net +1 -2
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/decnet/dn_dev.c
#   2005/01/10 13:42:22-08:00 kaber@trash.net +1 -1
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/rtnetlink.c
#   2005/01/10 13:42:22-08:00 kaber@trash.net +20 -14
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/pkt_cls.h
#   2005/01/10 13:42:22-08:00 kaber@trash.net +1 -7
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/rtnetlink.h
#   2005/01/10 13:42:22-08:00 kaber@trash.net +1 -0
#   [PKT_SCHED]: Add rtattr_strlcpy, use it where appropriate
#   
#   Add rtattr_strlcpy to handle unterminated strings. The destination
#   is nulled out entirely to avoid possible leaks when dumping. The
#   return value can be checked for >= size to detect truncated strings.
#   Currently strings equal to the size of the destination are accepted
#   everywhere even if not null-terminated. Sometimes they are silently
#   truncated, sometimes the unterminated string is used.
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:41:28-08:00 kaber@trash.net 
#   [PKT_SCHED]: act_api.c: remove unnecessary initializations
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:41:08-08:00 kaber@trash.net +10 -13
#   [PKT_SCHED]: act_api.c: remove unnecessary initializations
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:40:47-08:00 kaber@trash.net 
#   [PKT_SCHED]: act_api.c: remove checks for impossible conditions
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:40:27-08:00 kaber@trash.net +15 -34
#   [PKT_SCHED]: act_api.c: remove checks for impossible conditions
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:39:06-08:00 kaber@trash.net 
#   [PKT_SCHED]: act_api.c: use consistent comparison style
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:38:45-08:00 kaber@trash.net +37 -40
#   [PKT_SCHED]: act_api.c: use consistent comparison style
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:38:00-08:00 kaber@trash.net 
#   [PKT_SCHED]: act_api.c: whitespace and coding style cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/act_api.c
#   2005/01/10 13:37:39-08:00 kaber@trash.net +141 -184
#   [PKT_SCHED]: act_api.c: whitespace and coding style cleanup
#   
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:37:02-08:00 rusty@rustcorp.com.au 
#   [PKT_SCHED]: Restore net/sched/ipt.c After iptables Kmod Cleanup
#   
#   Thomas Graf points out that I broke net/sched/ipt.c when I removed
#   __ipt_find_target_lock.  In fact, those routines don't need to keep
#   the lock held, so we can simplify them, and expose an interface
#   (ipt_find_target) which does module loading correctly for
#   net/sched/ipt.c.
#   
#   Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/ipt.c
#   2005/01/10 13:36:42-08:00 rusty@rustcorp.com.au +8 -12
#   [PKT_SCHED]: Restore net/sched/ipt.c After iptables Kmod Cleanup
#   
#   Thomas Graf points out that I broke net/sched/ipt.c when I removed
#   __ipt_find_target_lock.  In fact, those routines don't need to keep
#   the lock held, so we can simplify them, and expose an interface
#   (ipt_find_target) which does module loading correctly for
#   net/sched/ipt.c.
#   
#   Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/netfilter/ip_tables.c
#   2005/01/10 13:36:42-08:00 rusty@rustcorp.com.au +32 -32
#   [PKT_SCHED]: Restore net/sched/ipt.c After iptables Kmod Cleanup
#   
#   Thomas Graf points out that I broke net/sched/ipt.c when I removed
#   __ipt_find_target_lock.  In fact, those routines don't need to keep
#   the lock held, so we can simplify them, and expose an interface
#   (ipt_find_target) which does module loading correctly for
#   net/sched/ipt.c.
#   
#   Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/netfilter_ipv4/ip_tables.h
#   2005/01/10 13:36:42-08:00 rusty@rustcorp.com.au +3 -0
#   [PKT_SCHED]: Restore net/sched/ipt.c After iptables Kmod Cleanup
#   
#   Thomas Graf points out that I broke net/sched/ipt.c when I removed
#   __ipt_find_target_lock.  In fact, those routines don't need to keep
#   the lock held, so we can simplify them, and expose an interface
#   (ipt_find_target) which does module loading correctly for
#   net/sched/ipt.c.
#   
#   Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
#   Signed-off-by: Patrick McHardy <kaber@trash.net>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:32:52-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: Actions are now available for all classifiers & Fix police Kconfig dependencies
#   
#   Removes outdated comment and make action and old compat policer
#   mutually exclusive to reflect the code. Noted by Jamal Hadi Salim.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/Kconfig
#   2005/01/10 13:32:31-08:00 tgraf@suug.ch +8 -8
#   [PKT_SCHED]: Actions are now available for all classifiers & Fix police Kconfig dependencies
#   
#   Removes outdated comment and make action and old compat policer
#   mutually exclusive to reflect the code. Noted by Jamal Hadi Salim.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:32:05-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: Remove old action/police helpers
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/pkt_cls.h
#   2005/01/10 13:31:44-08:00 tgraf@suug.ch +0 -122
#   [PKT_SCHED]: Remove old action/police helpers
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:31:20-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: rsvp: use tcf_exts API
#   
#   Transforms tcindex to use tcf_exts API and thus adds support for
#   actions. Needs more work to allow changing parameters for
#   existing filters.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/cls_rsvp.h
#   2005/01/10 13:31:00-08:00 tgraf@suug.ch +49 -53
#   [PKT_SCHED]: rsvp: use tcf_exts API
#   
#   Transforms tcindex to use tcf_exts API and thus adds support for
#   actions. Needs more work to allow changing parameters for
#   existing filters.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/pkt_cls.h
#   2005/01/10 13:31:00-08:00 tgraf@suug.ch +1 -0
#   [PKT_SCHED]: rsvp: use tcf_exts API
#   
#   Transforms tcindex to use tcf_exts API and thus adds support for
#   actions. Needs more work to allow changing parameters for
#   existing filters.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:30:34-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: tcindex: allow changing parameters for existing filters and use tcf_exts API
#   
#   Transforms tcindex to use tcf_exts API and thus adds support for
#   actions. Replaces the existing change implementation with a new one
#   supporting changes for existing filters which allows to change a
#   classifier without letting a single packet pass by unclassified.
#   
#   Fixes various cases where a error is returned but the filter was
#   changed already.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/cls_tcindex.c
#   2005/01/10 13:30:14-08:00 tgraf@suug.ch +210 -169
#   [PKT_SCHED]: tcindex: allow changing parameters for existing filters and use tcf_exts API
#   
#   Transforms tcindex to use tcf_exts API and thus adds support for
#   actions. Replaces the existing change implementation with a new one
#   supporting changes for existing filters which allows to change a
#   classifier without letting a single packet pass by unclassified.
#   
#   Fixes various cases where a error is returned but the filter was
#   changed already.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/pkt_cls.h
#   2005/01/10 13:30:14-08:00 tgraf@suug.ch +1 -0
#   [PKT_SCHED]: tcindex: allow changing parameters for existing filters and use tcf_exts API
#   
#   Transforms tcindex to use tcf_exts API and thus adds support for
#   actions. Replaces the existing change implementation with a new one
#   supporting changes for existing filters which allows to change a
#   classifier without letting a single packet pass by unclassified.
#   
#   Fixes various cases where a error is returned but the filter was
#   changed already.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:29:48-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: route: allow changing parameters for existing filters and use tcf_exts API
#   
#   Transforms route to use tcf_exts API and thus adds support for
#   actions. Replaces the existing change implementation with a new one
#   supporting changes for existing filters which allows to change a
#   classifier without letting a single packet pass by unclassified.
#   
#   Fixes various cases where a error is returned but the filter was
#   changed already.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/cls_route.c
#   2005/01/10 13:29:27-08:00 tgraf@suug.ch +189 -157
#   [PKT_SCHED]: route: allow changing parameters for existing filters and use tcf_exts API
#   
#   Transforms route to use tcf_exts API and thus adds support for
#   actions. Replaces the existing change implementation with a new one
#   supporting changes for existing filters which allows to change a
#   classifier without letting a single packet pass by unclassified.
#   
#   Fixes various cases where a error is returned but the filter was
#   changed already.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/pkt_cls.h
#   2005/01/10 13:29:27-08:00 tgraf@suug.ch +1 -0
#   [PKT_SCHED]: route: allow changing parameters for existing filters and use tcf_exts API
#   
#   Transforms route to use tcf_exts API and thus adds support for
#   actions. Replaces the existing change implementation with a new one
#   supporting changes for existing filters which allows to change a
#   classifier without letting a single packet pass by unclassified.
#   
#   Fixes various cases where a error is returned but the filter was
#   changed already.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:28:49-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: fw: make use of tcf_exts API
#   
#   Transforms fw to use tcf_exts API. Makes the fw changing
#   procedure consistent upon failures except for indev failures but
#   indev will be removed very soon.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/cls_fw.c
#   2005/01/10 13:28:28-08:00 tgraf@suug.ch +39 -98
#   [PKT_SCHED]: fw: make use of tcf_exts API
#   
#   Transforms fw to use tcf_exts API. Makes the fw changing
#   procedure consistent upon failures except for indev failures but
#   indev will be removed very soon.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:28:05-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: u32: make use of tcf_exts API
#   
#   Transforms u32 to use tcf_exts API. Makes the u32 changing
#   procedure consistent upon failures except for indev failures but
#   indev will be removed very soon.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/cls_u32.c
#   2005/01/10 13:27:44-08:00 tgraf@suug.ch +40 -84
#   [PKT_SCHED]: u32: make use of tcf_exts API
#   
#   Transforms u32 to use tcf_exts API. Makes the u32 changing
#   procedure consistent upon failures except for indev failures but
#   indev will be removed very soon.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:26:48-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: tc filter extension API
#   
#   The tcf_exts API abstracts extensions such as actions/policers
#   into a generic layer and reduces the knowledge inside classifiers
#   to the minimum required. It isolates the validation code into
#   its own function to allow classifiers to validate all input
#   data before making changes and thus avoids the need to undo changes
#   if a extension configuration request cannot be fullfilled.
#   
#   Adds missing locking when adding a action/police extension to an
#   already existing filter. Acquiring  dev->queue_lock makes sure we
#   don't change the action/police in the middle of a classification.
#   Noted by Patrick McHardy.
#   
#   As a nice side effect, using this API removes the existing
#   ifdef clutter.
#   
#   Usage:
#     The classifier holds struct tcf_exts which may be empty if no
#     extensions are compiled in. It then calls tcf_exts_validate
#     when a new change request was received and provides a temporary
#     tcf_exts copy to store the change requests. Given it succeeded
#     the classifier may change its own parameters and at the end
#     call tcf_exts_change to commit the changes and replace the
#     existing extension configuration with the new one. The classifier
#     is responsible to destroy his temporary copy if any of its own
#     validation checks fail.
#   
#     The classifier specific TLV types must be exported to the extensions
#     API via tcf_ext_map.
#   
#     Destroying the extensions is as easy as calling tcf_exts_destroy.
#   
#     The extensions are executed by the classifier by calling tcf_exts_exec
#     which must be done as the last thing after making sure the
#     filter matches. Note: A classifier might take further actions after
#     the execution to tcf_exts_exec such as correcting its own cache to
#     avoid caching results which could have been influenced by the extensions.
#   
#     tcf_exts_exec returns a negative error code if the filter must be
#     considered unmatched, 0 on normal execution or a positive classifier
#     return code (TC_ACT_*) which must be returned to the underlying layer
#     as-is.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/sched/cls_api.c
#   2005/01/10 13:26:27-08:00 tgraf@suug.ch +153 -0
#   [PKT_SCHED]: tc filter extension API
#   
#   The tcf_exts API abstracts extensions such as actions/policers
#   into a generic layer and reduces the knowledge inside classifiers
#   to the minimum required. It isolates the validation code into
#   its own function to allow classifiers to validate all input
#   data before making changes and thus avoids the need to undo changes
#   if a extension configuration request cannot be fullfilled.
#   
#   Adds missing locking when adding a action/police extension to an
#   already existing filter. Acquiring  dev->queue_lock makes sure we
#   don't change the action/police in the middle of a classification.
#   Noted by Patrick McHardy.
#   
#   As a nice side effect, using this API removes the existing
#   ifdef clutter.
#   
#   Usage:
#     The classifier holds struct tcf_exts which may be empty if no
#     extensions are compiled in. It then calls tcf_exts_validate
#     when a new change request was received and provides a temporary
#     tcf_exts copy to store the change requests. Given it succeeded
#     the classifier may change its own parameters and at the end
#     call tcf_exts_change to commit the changes and replace the
#     existing extension configuration with the new one. The classifier
#     is responsible to destroy his temporary copy if any of its own
#     validation checks fail.
#   
#     The classifier specific TLV types must be exported to the extensions
#     API via tcf_ext_map.
#   
#     Destroying the extensions is as easy as calling tcf_exts_destroy.
#   
#     The extensions are executed by the classifier by calling tcf_exts_exec
#     which must be done as the last thing after making sure the
#     filter matches. Note: A classifier might take further actions after
#     the execution to tcf_exts_exec such as correcting its own cache to
#     avoid caching results which could have been influenced by the extensions.
#   
#     tcf_exts_exec returns a negative error code if the filter must be
#     considered unmatched, 0 on normal execution or a positive classifier
#     return code (TC_ACT_*) which must be returned to the underlying layer
#     as-is.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/pkt_cls.h
#   2005/01/10 13:26:27-08:00 tgraf@suug.ch +87 -0
#   [PKT_SCHED]: tc filter extension API
#   
#   The tcf_exts API abstracts extensions such as actions/policers
#   into a generic layer and reduces the knowledge inside classifiers
#   to the minimum required. It isolates the validation code into
#   its own function to allow classifiers to validate all input
#   data before making changes and thus avoids the need to undo changes
#   if a extension configuration request cannot be fullfilled.
#   
#   Adds missing locking when adding a action/police extension to an
#   already existing filter. Acquiring  dev->queue_lock makes sure we
#   don't change the action/police in the middle of a classification.
#   Noted by Patrick McHardy.
#   
#   As a nice side effect, using this API removes the existing
#   ifdef clutter.
#   
#   Usage:
#     The classifier holds struct tcf_exts which may be empty if no
#     extensions are compiled in. It then calls tcf_exts_validate
#     when a new change request was received and provides a temporary
#     tcf_exts copy to store the change requests. Given it succeeded
#     the classifier may change its own parameters and at the end
#     call tcf_exts_change to commit the changes and replace the
#     existing extension configuration with the new one. The classifier
#     is responsible to destroy his temporary copy if any of its own
#     validation checks fail.
#   
#     The classifier specific TLV types must be exported to the extensions
#     API via tcf_ext_map.
#   
#     Destroying the extensions is as easy as calling tcf_exts_destroy.
#   
#     The extensions are executed by the classifier by calling tcf_exts_exec
#     which must be done as the last thing after making sure the
#     filter matches. Note: A classifier might take further actions after
#     the execution to tcf_exts_exec such as correcting its own cache to
#     avoid caching results which could have been influenced by the extensions.
#   
#     tcf_exts_exec returns a negative error code if the filter must be
#     considered unmatched, 0 on normal execution or a positive classifier
#     return code (TC_ACT_*) which must be returned to the underlying layer
#     as-is.
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:25:46-08:00 tgraf@suug.ch 
#   [PKT_SCHED]: rtattr_parse shortcut for nested TLVs
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/rtnetlink.h
#   2005/01/10 13:25:25-08:00 tgraf@suug.ch +3 -0
#   [PKT_SCHED]: rtattr_parse shortcut for nested TLVs
#   
#   Signed-off-by: Thomas Graf <tgraf@suug.ch>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:13:21-08:00 hch@lst.de 
#   [8139TOO]: Use rtnl_lock_interruptible()
#   
#   The 8139too thread needs to use rtnl_lock_interruptible so it can avoid
#   doing the actual work once it's been kill_proc()ed on module removal
#   time.
#   
#   Based on debugging and an earlier patch that adds a driver-private
#   semaphore from Herbert Xu.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# drivers/net/8139too.c
#   2005/01/10 13:13:00-08:00 hch@lst.de +2 -1
#   [8139TOO]: Use rtnl_lock_interruptible()
#   
#   The 8139too thread needs to use rtnl_lock_interruptible so it can avoid
#   doing the actual work once it's been kill_proc()ed on module removal
#   time.
#   
#   Based on debugging and an earlier patch that adds a driver-private
#   semaphore from Herbert Xu.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:12:18-08:00 hch@lst.de 
#   [NET]: Add rtnl_lock_interruptible()
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/rtnetlink.c
#   2005/01/10 13:11:58-08:00 hch@lst.de +6 -0
#   [NET]: Add rtnl_lock_interruptible()
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/rtnetlink.h
#   2005/01/10 13:11:58-08:00 hch@lst.de +1 -0
#   [NET]: Add rtnl_lock_interruptible()
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:11:23-08:00 domen@coderock.org 
#   [SPARC64]: Remove x86-specific help in arch/sparc64/Kconfig
#   
#   Signed-off by: James Nelson <james4765@gmail.com>
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# arch/sparc64/Kconfig
#   2005/01/10 13:11:03-08:00 domen@coderock.org +2 -8
#   [SPARC64]: Remove x86-specific help in arch/sparc64/Kconfig
#   
#   Signed-off by: James Nelson <james4765@gmail.com>
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:06:43-08:00 arjan@infradead.org 
#   [IPVS]: Kill check_for_ip_vs_out, no longer used
#   
#   Signed-off-by: Arjan van de Ven <arjan@infradead.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ipv4/ipvs/ip_vs_core.c
#   2005/01/10 13:06:22-08:00 arjan@infradead.org +0 -26
#   [IPVS]: Kill check_for_ip_vs_out, no longer used
#   
#   Signed-off-by: Arjan van de Ven <arjan@infradead.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/ip_vs.h
#   2005/01/10 13:06:22-08:00 arjan@infradead.org +0 -2
#   [IPVS]: Kill check_for_ip_vs_out, no longer used
#   
#   Signed-off-by: Arjan van de Ven <arjan@infradead.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 13:05:37-08:00 arjan@infradead.org 
#   [NETLINK]: Kill netlink_post, no longer used
#   
#   Signed-off-by: Arjan van de Ven <arjan@infradead.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/netlink/af_netlink.c
#   2005/01/10 13:05:16-08:00 arjan@infradead.org +0 -34
#   [NETLINK]: Kill netlink_post, no longer used
#   
#   Signed-off-by: Arjan van de Ven <arjan@infradead.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/netlink.h
#   2005/01/10 13:05:16-08:00 arjan@infradead.org +0 -1
#   [NETLINK]: Kill netlink_post, no longer used
#   
#   Signed-off-by: Arjan van de Ven <arjan@infradead.org>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 12:27:49-08:00 okir@suse.de 
#   [NET]: Fix CMSG_COMPAT_OK length check.
#   
#   Need to check against struct compat_cmsghdr
#   not struct cmsghdr.
#   
#   Signed-off-by: Olaf Kirch <okir@suse.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/compat.c
#   2005/01/10 12:27:28-08:00 okir@suse.de +1 -1
#   [NET]: Fix CMSG_COMPAT_OK length check.
#   
#   Need to check against struct compat_cmsghdr
#   not struct cmsghdr.
#   
#   Signed-off-by: Olaf Kirch <okir@suse.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 12:24:16-08:00 bunk@stusta.de 
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/wireless.c
#   2005/01/10 12:23:56-08:00 bunk@stusta.de +1 -1
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/sock.c
#   2005/01/10 12:23:56-08:00 bunk@stusta.de +9 -8
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/rtnetlink.c
#   2005/01/10 12:23:56-08:00 bunk@stusta.de +1 -2
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/netpoll.c
#   2005/01/10 12:23:56-08:00 bunk@stusta.de +2 -3
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/netfilter.c
#   2005/01/10 12:23:56-08:00 bunk@stusta.de +1 -1
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/iovec.c
#   2005/01/10 12:23:56-08:00 bunk@stusta.de +0 -23
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/dst.c
#   2005/01/10 12:23:56-08:00 bunk@stusta.de +1 -1
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/dev.c
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +4 -9
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/datagram.c
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +3 -16
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/sock.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -7
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/pkt_cls.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -1
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/net/iw_handler.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -3
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/socket.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -1
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/skbuff.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -5
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/rtnetlink.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -1
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/netpoll.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -1
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/netfilter.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -4
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# include/linux/netdevice.h
#   2005/01/10 12:23:55-08:00 bunk@stusta.de +0 -1
#   [NET]: misc cleanups
#   
#   The patch below contains the following cleanups:
#   - make needlessly global code static
#   - remove the following unused global functions:
#     - datagram.c: skb_copy_datagram
#     - iovec.c: memcpy_tokerneliovec
#   - remove the following unneeded EXPORT_SYMBOL's:
#     - datagram.c: skb_copy_datagram
#     - dev.c: ing_filter
#     - iovec.c: memcpy_tokerneliovec
#     - netpoll.c: netpoll_send_skb
#     - rtnetlink.c: rtnetlink_dump_ifinfo
#     - sock.c: sock_alloc_send_pskb
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 11:45:14-08:00 davem@nuts.davemloft.net 
#   Merge http://linux-lksctp.bkbits.net/lksctp-2.5.work
#   into nuts.davemloft.net:/disk1/BK/net-2.6
# 
# net/sctp/protocol.c
#   2005/01/10 11:45:03-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# net/sctp/ipv6.c
#   2005/01/10 11:45:03-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# net/sctp/input.c
#   2005/01/10 11:45:03-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# include/net/sctp/sctp.h
#   2005/01/10 11:45:02-08:00 davem@nuts.davemloft.net +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/10 11:44:01-08:00 bdschuym@pandora.be 
#   [BRIDGE-NF]: Check ipv4 vs ipv6 more reliably in ip_sabotage_out().
#   
#   Signed-off-by: Bart De Schuymer <bdschuym@telenet.be>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/bridge/br_netfilter.c
#   2005/01/10 11:43:41-08:00 bdschuym@pandora.be +18 -15
#   [BRIDGE-NF]: Check ipv4 vs ipv6 more reliably in ip_sabotage_out().
#   
#   Signed-off-by: Bart De Schuymer <bdschuym@telenet.be>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 11:40:21-08:00 davem@nuts.davemloft.net 
#   [AX25]: Put back ax25digicmp.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ax25/ax25_addr.c
#   2005/01/10 11:39:48-08:00 davem@nuts.davemloft.net +20 -0
#   [AX25]: Put back ax25digicmp.
# 
# include/net/ax25.h
#   2005/01/10 11:39:48-08:00 davem@nuts.davemloft.net +1 -0
#   [AX25]: Put back ax25digicmp.
# 
# ChangeSet
#   2005/01/10 11:32:45-08:00 Robert.Olsson@data.slu.se 
#   [NET]: pktgen update
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/core/pktgen.c
#   2005/01/10 11:32:10-08:00 Robert.Olsson@data.slu.se +2748 -1031
#   [NET]: pktgen update
# 
# Documentation/networking/pktgen.txt
#   2005/01/10 11:32:10-08:00 Robert.Olsson@data.slu.se +211 -74
#   [NET]: pktgen update
# 
# ChangeSet
#   2005/01/10 11:28:41-08:00 alan@lxorguk.ukuu.org.uk 
#   [AX25]: Revert to 2.6.9 behavior.
#   
#   I suspect given that someone made the change for a reason that there
#   should probably be a sysctl to switch between AX.25 (as 2.6.9) and "kind
#   of routed AX.25-ish" (as 2.6.10).
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# net/ax25/af_ax25.c
#   2005/01/10 11:27:45-08:00 alan@lxorguk.ukuu.org.uk +10 -2
#   [AX25]: Revert to 2.6.9 behavior.
# 
# ChangeSet
#   2005/01/10 11:26:25-08:00 roland@topspin.com 
#   [SPARC64]: Check copy_to_user() return value in sys_{sparc,sunos}32.c
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# arch/sparc64/kernel/sys_sunos32.c
#   2005/01/10 11:26:05-08:00 roland@topspin.com +4 -2
#   [SPARC64]: Check copy_to_user() return value in sys_{sparc,sunos}32.c
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# arch/sparc64/kernel/sys_sparc32.c
#   2005/01/10 11:26:05-08:00 roland@topspin.com +2 -1
#   [SPARC64]: Check copy_to_user() return value in sys_{sparc,sunos}32.c
#   
#   Signed-off-by: Roland Dreier <roland@topspin.com>
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# ChangeSet
#   2005/01/10 11:25:11-08:00 davem@nuts.davemloft.net 
#   [SPARC64]: Update defconfig.
#   
#   Signed-off-by: David S. Miller <davem@davemloft.net>
# 
# arch/sparc64/defconfig
#   2005/01/10 11:24:38-08:00 davem@nuts.davemloft.net +10 -11
#   [SPARC64]: Update defconfig.
# 
# ChangeSet
#   2005/01/10 10:56:57-06:00 mike.miller@hp.com 
#   [PATCH] cciss update to version 2.6.4
#   
#   This patch removes support for 2 controllers that were recently
#   cancelled and it adds support for the P600, a cciss based SAS
#   controller due to ship in late March/early April '05.
#   Neither of these controllers have made it to the field.
#   
#   Signed-off-by: Mike Miller <mike.miller@hp.com>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/linux/pci_ids.h
#   2005/01/07 11:54:25-06:00 mike.miller@hp.com +1 -1
#   cciss update to version 2.6.4
# 
# drivers/block/cciss.c
#   2005/01/07 11:50:43-06:00 mike.miller@hp.com +7 -10
#   cciss update to version 2.6.4
# 
# Documentation/cciss.txt
#   2005/01/07 11:51:16-06:00 mike.miller@hp.com +1 -2
#   cciss update to version 2.6.4
# 
# ChangeSet
#   2005/01/08 12:29:24-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: White space corrections
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_param.c
#   2005/01/07 11:10:54-05:00 ganesh.venkatesan@intel.com +75 -82
#   ixgb: White space corrections
# 
# drivers/net/ixgb/ixgb_osdep.h
#   2005/01/07 11:10:53-05:00 ganesh.venkatesan@intel.com +5 -5
#   ixgb: White space corrections
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +236 -215
#   ixgb: White space corrections
# 
# drivers/net/ixgb/ixgb_ids.h
#   2005/01/07 11:08:15-05:00 ganesh.venkatesan@intel.com +7 -13
#   ixgb: White space corrections
# 
# drivers/net/ixgb/ixgb_hw.h
#   2005/01/07 11:08:13-05:00 ganesh.venkatesan@intel.com +29 -19
#   ixgb: White space corrections
# 
# drivers/net/ixgb/ixgb_hw.c
#   2005/01/07 11:08:11-05:00 ganesh.venkatesan@intel.com +135 -91
#   ixgb: White space corrections
# 
# drivers/net/ixgb/ixgb_ethtool.c
#   2005/01/07 11:08:08-05:00 ganesh.venkatesan@intel.com +12 -11
#   ixgb: White space corrections
# 
# drivers/net/ixgb/ixgb_ee.c
#   2005/01/07 11:08:05-05:00 ganesh.venkatesan@intel.com +114 -78
#   ixgb: White space corrections
# 
# drivers/net/ixgb/ixgb.h
#   2005/01/07 11:08:10-05:00 ganesh.venkatesan@intel.com +1 -1
#   ixgb: White space corrections
# 
# ChangeSet
#   2005/01/08 12:28:58-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Driver version number update
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +15 -2
#   ixgb: Driver version number update
# 
# ChangeSet
#   2005/01/08 12:28:45-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Support for 2.6.x style module parameters
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_param.c
#   2005/01/07 11:10:54-05:00 ganesh.venkatesan@intel.com +80 -51
#   ixgb: Support for 2.6.x style module parameters
# 
# ChangeSet
#   2005/01/08 12:28:33-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Fix Tx cleanup logic
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +21 -29
#   ixgb: Fix Tx cleanup logic
# 
# ChangeSet
#   2005/01/08 12:28:21-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Shrink size and fix ordering of elements in ixgb_buffer
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb.h
#   2005/01/07 11:08:10-05:00 ganesh.venkatesan@intel.com +2 -2
#   ixgb: Shrink size and fix ordering of elements in ixgb_buffer
# 
# ChangeSet
#   2005/01/08 12:28:09-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: ethtool_ops support
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_param.c
#   2005/01/07 11:10:54-05:00 ganesh.venkatesan@intel.com +0 -4
#   ixgb: ethtool_ops support
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +17 -12
#   ixgb: ethtool_ops support
# 
# drivers/net/ixgb/ixgb_ethtool.c
#   2005/01/07 11:08:08-05:00 ganesh.venkatesan@intel.com +320 -175
#   ixgb: ethtool_ops support
# 
# drivers/net/ixgb/ixgb.h
#   2005/01/07 11:08:10-05:00 ganesh.venkatesan@intel.com +4 -0
#   ixgb: ethtool_ops support
# 
# ChangeSet
#   2005/01/08 12:27:56-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Replace kmalloc with vmalloc (one time alloc)
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +6 -6
#   ixgb: Replace kmalloc with vmalloc (one time alloc)
# 
# drivers/net/ixgb/ixgb.h
#   2005/01/07 11:08:10-05:00 ganesh.venkatesan@intel.com +1 -0
#   ixgb: Replace kmalloc with vmalloc (one time alloc)
# 
# ChangeSet
#   2005/01/08 12:27:45-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Remove support for RAIDC interrupt mitigation
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_param.c
#   2005/01/07 11:10:54-05:00 ganesh.venkatesan@intel.com +0 -21
#   ixgb: Remove support for RAIDC interrupt mitigation
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +4 -54
#   ixgb: Remove support for RAIDC interrupt mitigation
# 
# drivers/net/ixgb/ixgb.h
#   2005/01/07 11:08:10-05:00 ganesh.venkatesan@intel.com +0 -1
#   ixgb: Remove support for RAIDC interrupt mitigation
# 
# ChangeSet
#   2005/01/08 12:27:32-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Limit Rx Address Filter Array entries to 3
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_hw.h
#   2005/01/07 11:08:13-05:00 ganesh.venkatesan@intel.com +1 -1
#   ixgb: Limit Rx Address Filter Array entries to 3
# 
# ChangeSet
#   2005/01/08 12:27:20-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Fix infinite loop trying to re-establish link
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +0 -2
#   ixgb: Fix infinite loop trying to re-establish link
# 
# ChangeSet
#   2005/01/08 12:22:36-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Fix error in setting MFS register
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +2 -2
#   ixgb: Fix error in setting MFS register
# 
# ChangeSet
#   2005/01/08 12:22:23-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Poll Routine cleanup
#   
#   Includes fixes for
#   (a) kernel panic when the interface is shutdown when Poll is active
#   (b) include tx workdone in deciding when to quit polling mode
#   (c) fix poll quit condition (from Robert Olsson)
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +14 -7
#   ixgb: Poll Routine cleanup
# 
# ChangeSet
#   2005/01/08 12:22:11-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Fix memory leak in NAPI mode
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +6 -6
#   ixgb: Fix memory leak in NAPI mode
# 
# ChangeSet
#   2005/01/08 12:21:58-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Fix VLAN filter setup errors (while running on PPC)
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +4 -6
#   ixgb: Fix VLAN filter setup errors (while running on PPC)
# 
# ChangeSet
#   2005/01/08 12:21:47-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Add support for 10GbE LR device ID
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +6 -3
#   ixgb: Add support for 10GbE LR device ID
# 
# drivers/net/ixgb/ixgb_ids.h
#   2005/01/07 11:08:15-05:00 ganesh.venkatesan@intel.com +1 -0
#   ixgb: Add support for 10GbE LR device ID
# 
# drivers/net/ixgb/ixgb_hw.c
#   2005/01/07 11:08:11-05:00 ganesh.venkatesan@intel.com +5 -0
#   ixgb: Add support for 10GbE LR device ID
# 
# ChangeSet
#   2005/01/08 12:21:35-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Enable Message Signalled Interrupts
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_main.c
#   2005/01/07 11:10:49-05:00 ganesh.venkatesan@intel.com +26 -4
#   ixgb: Enable Message Signalled Interrupts
# 
# drivers/net/ixgb/ixgb.h
#   2005/01/07 11:08:10-05:00 ganesh.venkatesan@intel.com +3 -0
#   ixgb: Enable Message Signalled Interrupts
# 
# ChangeSet
#   2005/01/08 12:21:23-05:00 ganesh.venkatesan@intel.com 
#   [PATCH] ixgb: Limit number of Rx Descriptors to 512
#   
#   Workaround for a Si Erratum. When more that 512 Rx descriptors are used,
#   there may be Rx data corruption.
#   
#   Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
# 
# drivers/net/ixgb/ixgb_param.c
#   2005/01/07 11:10:54-05:00 ganesh.venkatesan@intel.com +0 -3
#   ixgb: Limit number of Rx Descriptors to 512
# 
# drivers/net/ixgb/ixgb.h
#   2005/01/07 11:08:10-05:00 ganesh.venkatesan@intel.com +10 -0
#   ixgb: Limit number of Rx Descriptors to 512
# 
# ChangeSet
#   2005/01/07 16:17:45-08:00 davidm@hpl.hp.com 
#   [IA64] add hpzx1_swiotlb machine-vector
#   
#   I was in need of a 3.3V/dual-voltage-capable PCI sound-card and, as
#   luck would have it, the only card of that sort in the local computer
#   store was one that _still_ has a DMA engine that cannot even DMA to
#   all 32 bits (it's limited to 28 bits).  Hard to believe, but true (the
#   card in question is a "SoundBlaster Live! 24-bit" with a CA0106 chip;
#   stay away from that one if you can...).
#   
#   Anyhow, since I don't like it when PCI cards don't work in my machine,
#   I created the attached patch which adds a new machine-vector to enable
#   support of such broken cards.
#   
#   With the patch applied, you can either configure the kernel for
#   "HP-zx1/sx1000+swiotlb" or configure for "generic" and boot with
#   option "machvec=hpzx1_swiotlb" to enable support for broken PCI
#   devices.
#   
#   The patch works as follows: the new machvec implements a I/O MMU which
#   will use the hardware I/O MMU whenever possible but fall back on the
#   software I/O TLB when encountering a device that can't be supported by
#   the hardware I/O MMU.  Fortunately, we don't have to mess with
#   MAX_DMA_ADDRESS or create a new zone: the software I/O TLB allocates
#   its memory as low as possible and early in the boot-process, so on any
#   machine with low memory, we're pretty much guaranteed that we'll get a
#   reasonable amount of low memory, which is all we need to properly support
#   broken PCI cards.
#   
#   Note that I made a small change to swiotlb.c: I added a
#   swiotlb_init_with_default_size() function to let the new I/O MMU
#   initialize the software I/O TLB with less than 64MB (which is way too
#   much for the limited uses we'll see for the broken PCI devices; for
#   example, the CA0106 chip allocates only coherent buffers of about
#   128KB).
#   
#   The patch has been tested on a zx1 machine in the generic, hpzx1, and
#   hpzx1_swiotlb configuration.
#   
#   Thanks to Alex Williamson for the suggestion of doing this via a
#   completely separate machvec.
#   
#   Signed-off-by: David Mosberger-Tang <davidm@hpl.hp.com>
#   Signed-off-by: Tony Luck <tony.luck@intel.com>
# 
# include/asm-ia64/numnodes.h
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +1 -1
#   add hpzx1_swiotlb machine-vector
# 
# include/asm-ia64/machvec.h
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +2 -0
#   add hpzx1_swiotlb machine-vector
# 
# drivers/char/agp/Kconfig
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +1 -1
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/lib/swiotlb.c
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +13 -3
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/kernel/setup.c
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +23 -2
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/kernel/acpi.c
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +2 -0
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/kernel/Makefile
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +1 -0
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/hp/zx1/Makefile
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +1 -1
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/hp/common/Makefile
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +2 -0
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/Makefile
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +2 -0
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/Kconfig
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +17 -7
#   add hpzx1_swiotlb machine-vector
# 
# arch/ia64/Kconfig.debug
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +1 -1
#   add hpzx1_swiotlb machine-vector
# 
# Documentation/kernel-parameters.txt
#   2005/01/07 16:15:52-08:00 davidm@hpl.hp.com +5 -1
#   add hpzx1_swiotlb machine-vector
# 
# ChangeSet
#   2005/01/07 16:38:51-05:00 jejb@mulgrave.(none) 
#   Fix exploitable hole in sg_scsi_ioctl
#   
#   in_len and out_len are signed quantites copied from
#   user space but are only checked to see if they're >
#   PAGE_SIZE.  The exploit would be to pass in a negative
#   quantity which would pass the check.
#   
#   Fix by making them unsigned.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/block/scsi_ioctl.c
#   2005/01/07 16:36:05-05:00 jejb@mulgrave.(none) +2 -1
#   Fix exploitable hole in sg_scsi_ioctl
# 
# ChangeSet
#   2005/01/07 13:24:14-05:00 aris@cathedrallabs.org 
#   [PATCH] eepro: fix auto-detection option
#   
#   eepro: fix auto-detection option
#   
#   Signed-off-by: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/eepro.c
#   2004/10/05 20:44:23-04:00 aris@cathedrallabs.org +8 -4
#   eepro: fix auto-detection option
# 
# ChangeSet
#   2005/01/07 13:24:03-05:00 aris@cathedrallabs.org 
#   [PATCH] eepro: fix return value in init_module()
#   
#   eepro: fix return value in init_module()
#   
#   Signed-off-by: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/eepro.c
#   2004/10/05 21:27:00-04:00 aris@cathedrallabs.org +1 -1
#   eepro: fix return value in init_module()
# 
# ChangeSet
#   2005/01/07 13:23:52-05:00 aris@cathedrallabs.org 
#   [PATCH] eepro: basic ethtool support
#   
#   eepro: basic ethtool support
#   
#   Signed-off-by: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/eepro.c
#   2005/01/07 06:04:40-05:00 aris@cathedrallabs.org +68 -7
#   eepro: basic ethtool support
# 
# ChangeSet
#   2005/01/07 13:23:39-05:00 aris@cathedrallabs.org 
#   [PATCH] eepro: use module_param macros
#   
#   eepro: use module_param macros
#   
#   Signed-off-by: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/eepro.c
#   2005/01/07 06:01:12-05:00 aris@cathedrallabs.org +5 -4
#   eepro: use module_param macros
# 
# ChangeSet
#   2005/01/07 13:23:28-05:00 aris@cathedrallabs.org 
#   [PATCH] eepro: cache EEPROM values
#   
#   eepro: cache EEPROM values
#   
#   Signed-off-by: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/eepro.c
#   2004/09/14 12:46:15-04:00 aris@cathedrallabs.org +29 -17
#   eepro: cache EEPROM values
# 
# ChangeSet
#   2005/01/06 23:04:58-05:00 hermes@gibson.dropbear.id.au 
#   [PATCH] Another trivial orinoco update
#   
#   Jeff/Andrew please apply:
#   
#   This patch alters the convention with which orinoco_lock() is invoked
#   in the orinoco driver.  This should cause no behavioural change, but
#   reduces meaningless diffs between the mainline and CVS version of the
#   driver.  Another small step towards a merge.
#   
#   Signed-off-by: David Gibson <hermes@gibson.dropbear.id.au>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/wireless/orinoco.c
#   2004/11/02 21:34:38-05:00 hermes@gibson.dropbear.id.au +77 -126
#   Another trivial orinoco update
# 
# ChangeSet
#   2005/01/06 22:53:05-05:00 raghavendra.koushik@s2io.com 
#   [PATCH] S2io: fixes in free_shared_mem function
#   
#   Hello All,
#   	As per KK's review comment received on Nov 8 about the free_shared_mem function, Iam sending the following patch.
#   
#   The change log includes:
#   
#   1. Break from the main 'for loop' if ba[i] is NULL.
#   
#   2. In the second level 'for loop', if ba[i][j] is NULL, instead of
#   continuing as was done previously, we now free the ba[i] pointer and
#   break from the main 'for loop'.
#   
#   3. In the 'while loop' inside the second tier 'for loop', if any of the
#   three pointers (ba or ba->ba_0_org or ba->ba_1_org) is found to be NULL,
#   then ba[i], ba[i][j] and the non NULL buffer pointer if any
#   (ba_0_org or ba_1_org) is freed and break from the main 'for loop'.
#   
#   Signed-off-by: Koushik <raghavendra.koushik@s2io.com>
#   Signed-off-by: Ravi <ravinandan.arakali@s2io.com>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/s2io.c
#   2004/11/18 13:07:48-05:00 raghavendra.koushik@s2io.com +18 -4
#   S2io: fixes in free_shared_mem function
# 
# ChangeSet
#   2005/01/06 22:03:59-05:00 mporter@kernel.crashing.org 
#   [PATCH] Add netpoll support
#   
#   Add netpoll support to the EMAC driver.
#   
#   Signed-off-by: Matt Porter <mporter@kernel.crashing.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/ibm_emac/ibm_emac_core.c
#   2004/12/07 12:06:23-05:00 mporter@kernel.crashing.org +12 -0
#   Add netpoll support
# 
# ChangeSet
#   2005/01/06 22:03:48-05:00 mporter@kernel.crashing.org 
#   [PATCH] allow rx of the maximum sized VLAN tagged packets
#   
#   Patch enables EMAC to receive maximum sized VLAN tagged packets.
#   
#   Signed-off-by: Eugene Surovegin <ebs@ebshome.net>
#   Signed-off-by: Matt Porter <mporter@kernel.crashing.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/ibm_emac/ibm_emac_core.c
#   2004/08/24 15:18:27-04:00 mporter@kernel.crashing.org +3 -0
#   allow rx of the maximum sized VLAN tagged packets
# 
# drivers/net/ibm_emac/ibm_emac.h
#   2004/08/24 15:19:41-04:00 mporter@kernel.crashing.org +1 -1
#   allow rx of the maximum sized VLAN tagged packets
# 
# ChangeSet
#   2005/01/06 22:02:34-05:00 viro@parcelfarce.linux.theplanet.co.uk 
#   [PATCH] s2io iomem annotations and cleanups
#   
#   	* usual iomem annotations
#   	* u64 is not an equivalent to pointer; unsigned long is
#   	* cast-as-lvalue ugliness killed.
#   	* caddr_t has no place in kernel (and these guys were iomem pointers,
#   actually).
#   
#   Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/s2io.h
#   2005/01/06 22:02:28-05:00 viro@parcelfarce.linux.theplanet.co.uk +9 -10
#   s2io iomem annotations and cleanups
# 
# drivers/net/s2io.c
#   2004/12/27 06:32:13-05:00 viro@parcelfarce.linux.theplanet.co.uk +52 -52
#   s2io iomem annotations and cleanups
# 
# ChangeSet
#   2005/01/06 22:02:23-05:00 viro@parcelfarce.linux.theplanet.co.uk 
#   [PATCH] bmac iomem annotations
#   
#   Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/bmac.c
#   2004/12/27 21:29:49-05:00 viro@parcelfarce.linux.theplanet.co.uk +33 -35
#   bmac iomem annotations
# 
# ChangeSet
#   2005/01/06 22:02:11-05:00 viro@parcelfarce.linux.theplanet.co.uk 
#   [PATCH] hamachi iomem annotations
#   
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/hamachi.c
#   2004/12/27 22:55:38-05:00 viro@parcelfarce.linux.theplanet.co.uk +43 -38
#   (21/32) hamachi iomem annotations
# 
# ChangeSet
#   2005/01/06 22:01:59-05:00 viro@parcelfarce.linux.theplanet.co.uk 
#   [PATCH] miri_sbus iomem annotations
#   
#   	missing __iomem annotations in myri_sbus
#   Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/myri_sbus.c
#   2004/12/28 11:47:31-05:00 viro@parcelfarce.linux.theplanet.co.uk +5 -5
#   miri_sbus iomem annotations
# 
# ChangeSet
#   2005/01/06 21:59:14-05:00 akpm@osdl.org 
#   [PATCH] EMAC: fix ibm_emac autonegotiation result parsing
#   
#   From: Matt Porter <mporter@kernel.crashing.org>
#   
#   Fix aneg result parsing in ibm_emac driver.
#   
#   Signed-off-by: Eugene Surovegin <ebs@ebshome.net>
#   Signed-off-by: Matt Porter <mporter@kernel.crashing.org>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/ibm_emac/ibm_emac_phy.c
#   2005/01/05 00:57:37-05:00 akpm@osdl.org +10 -9
#   EMAC: fix ibm_emac autonegotiation result parsing
# 
# ChangeSet
#   2005/01/06 19:44:33-05:00 takata@linux-m32r.org 
#   [PATCH] net: netconsole support for smc91x
#   
#   Signed-off-by: Hayato Fujiwara <fujiwara@linux-m32r.org>
#   Signed-off-by: Hirokazu Takata <takata@linux-m32r.org>
#   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
# 
# drivers/net/smc91x.c
#   2005/01/06 05:40:56-05:00 takata@linux-m32r.org +16 -0
#   net: netconsole support for smc91x
# 
# ChangeSet
#   2005/01/06 15:57:16-05:00 michaelc@cs.wisc.edu 
#   [PATCH] export print_sense_internal
#   
#   Currently, we have scsi_print_sense and scsi_print_req_sense, but the
#   linux-iscsi driver receives async messages from a target that may
#   contain SCSI sense data and these messages are not tied to any
#   specific command. So that we can use the scsi-ml sense printing
#   capabilities the attached patch exports exports print_sense_internal
#   and renames it to __scsi_print_sense.
#   
#   Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# include/scsi/scsi_dbg.h
#   2005/01/05 06:11:58-05:00 michaelc@cs.wisc.edu +3 -0
#   export print_sense_internal
# 
# drivers/scsi/constants.c
#   2005/01/05 06:25:05-05:00 michaelc@cs.wisc.edu +14 -10
#   export print_sense_internal
# 
# ChangeSet
#   2005/01/06 15:48:50-05:00 tonyb@cybernetics.com 
#   [PATCH] fix read capacity for large disks when CONFIG_LBD=n
#   
#   We shouldn't configure an device that requires LBD if the kernel
#   doesn't suppoprt it (because we won't be able to see most of it), so
#   set the capacity to zero in this case.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/sd.c
#   2005/01/04 08:03:59-05:00 tonyb@cybernetics.com +5 -2
#   fix read capacity for large disks when CONFIG_LBD=n
# 
# ChangeSet
#   2005/01/06 09:58:37-05:00 juhl-lkml@dif.dk 
#   [PATCH] clean out old cruft from FD MCS driver
#   
#    - Remove the unused macro DEBUG_DETECT
#    - Remove code inside DO_DETECT conditional that's broken
#    - Remove superfluous header
#   
#   Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/fd_mcs.c
#   2005/01/03 17:39:27-05:00 juhl-lkml@dif.dk +1 -57
#   clean out old cruft from FD MCS driver
# 
# BitKeeper/deleted/.del-fd_mcs.h~10e8a7cb2d178aa1
#   2005/01/06 09:55:11-05:00 juhl-lkml@dif.dk +0 -0
#   Delete: drivers/scsi/fd_mcs.h
# 
# ChangeSet
#   2005/01/05 20:18:21+01:00 sam@mars.ravnborg.org 
#   Merge bk://linux-sam.bkbits.net/kconfig
#   into mars.ravnborg.org:/home/sam/bk/kconfig
# 
# mm/memory.c
#   2005/01/05 20:18:12+01:00 sam@mars.ravnborg.org +0 -0
#   Auto merged
# 
# include/linux/mm.h
#   2005/01/05 20:18:11+01:00 sam@mars.ravnborg.org +0 -0
#   Auto merged
# 
# include/asm-x86_64/page.h
#   2005/01/05 20:18:11+01:00 sam@mars.ravnborg.org +0 -0
#   Auto merged
# 
# arch/x86_64/mm/init.c
#   2005/01/05 20:18:11+01:00 sam@mars.ravnborg.org +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/01/04 23:22:39+01:00 sam@mars.ravnborg.org 
#   kconfig: Fold README.Menuconfig into mconf.c
#   
#   Content of README.Menuconfig folded into mconf.c and README.Menuconfig deleted.
#   Text was slightly updated - mainly by deleting obsolete information.
#   
#   Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
# 
# scripts/kconfig/mconf.c
#   2005/01/04 23:22:18+01:00 sam@mars.ravnborg.org +136 -8
#   Fold README.Menuconfig into mconf.c
# 
# BitKeeper/deleted/.del-README.Menuconfig~f10bb8f47bedf17
#   2005/01/04 23:19:30+01:00 sam@mars.ravnborg.org +0 -0
#   Delete: scripts/README.Menuconfig
# 
# ChangeSet
#   2005/01/04 23:03:52+01:00 sam@mars.ravnborg.org 
#   kconfig: Include more info when selecting help for a symbol in menuconfig
#   
#   When selecting help on a symbol include information below help text
#   displaying relevant info that kconf has stored.
#   The info printed is the same info obtained when searching for a symbol
#   and the same methods are resued.
#   
#   Sample (help for "System V IPC"):
#   -----------------------------------------------------------------------
#   CONFIG_SYSIPC:
#   
#   Inter Process Communcation ...
#   
#   Symbol: SYSVIPC [=y]
#   Prompt: System V IPC
#     Defined at init/Kconfig:82
#     Depends on: MMU
#     Location:
#       -> General setup
#   -----------------------------------------------------------------------
#   
#   Idea-from: Cal Peake <cp@absolutedigital.net>
#   Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
# 
# scripts/kconfig/mconf.c
#   2005/01/04 23:03:31+01:00 sam@mars.ravnborg.org +45 -39
#   When selecting help on a symbol include information below help text
#   displaying relevant relations.
#   The info printed is the same info obtained when searching for a symbol
#   and the same methods are resued.
# 
# ChangeSet
#   2005/01/04 22:34:50+01:00 sam@mars.ravnborg.org 
#   kconfig: Redo and improve search support
#   
#   Based on patch from: Roman Zippel <zippel@linux-m68k.org>
#   
#   The search functionality has been improved:
#   - Restructured printout with more info
#   - Include value of relevant symbols
#   - Improved handling of corner cases
#   - Generic search support moved to backend - ready to be utilised by xconfig and gconfig
#   - Search functionality moved to fronend - not hardcoded in menubox.c
#   
#   Sample search (^$ used to limit search):
#   Search for "^USB_STORAGE$":
#   
#   Symbol: USB_STORAGE [=y]
#   Prompt: USB Mass Storage support
#     Defined at drivers/usb/storage/Kconfig:7
#     Depends on: USB
#     Location:
#       -> Device Drivers
#         -> USB Support
#     Selects: SCSI
#   
#   
#   Some symbols has loong "Depends on:" lines - for example FW_LOADER.
#   Use arrows to scroll horisontally to see full value.
#   
#   Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
# 
# scripts/lxdialog/menubox.c
#   2005/01/04 22:34:29+01:00 sam@mars.ravnborg.org +2 -9
#   Delete old support for search and just tell when '/' has been pressed
# 
# scripts/kconfig/symbol.c
#   2005/01/04 22:34:29+01:00 sam@mars.ravnborg.org +38 -0
#   Implement a method to search all symbols using regular expressions.
# 
# scripts/kconfig/mconf.c
#   2005/01/04 22:34:29+01:00 sam@mars.ravnborg.org +140 -126
#   Delete old support for searching and including new improved version.
#   - Utilises search method located in backend of kconfig
#   - Handling more cases correct with respect to corner cases - so info present to user is better
#   - Reformatted output format
#   - Included actual value of relevant symbols
#   - Added helt text
# 
# scripts/kconfig/lkc_proto.h
#   2005/01/04 22:34:29+01:00 sam@mars.ravnborg.org +1 -0
#   Prototype new generic search method
# 
# scripts/kconfig/expr.h
#   2005/01/04 22:34:29+01:00 sam@mars.ravnborg.org +2 -0
#   Prototype new print method utilising growable string
# 
# scripts/kconfig/expr.c
#   2005/01/04 22:34:29+01:00 sam@mars.ravnborg.org +10 -0
#   Add print helper utilising the growable string
# 
# ChangeSet
#   2005/01/04 18:45:42+01:00 marcel@holtmann.org 
#   [Bluetooth] Add module parameter for ignoring a device
#   
#   This patch adds a module parameter to the USB Bluetooth drivers
#   for ignoring devices from their matching list. This makes it
#   possible for alternate drivers to grab the device.
#   
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# drivers/bluetooth/hci_usb.c
#   2005/01/04 18:42:57+01:00 marcel@holtmann.org +5 -1
#   Add module parameter for ignoring a device
# 
# drivers/bluetooth/bfusb.c
#   2005/01/04 18:42:54+01:00 marcel@holtmann.org +8 -0
#   Add module parameter for ignoring a device
# 
# drivers/bluetooth/bcm203x.c
#   2005/01/04 18:42:34+01:00 marcel@holtmann.org +6 -2
#   Add module parameter for ignoring a device
# 
# ChangeSet
#   2005/01/03 15:22:39-06:00 coughlan@redhat.com 
#   [PATCH] aacraid: remove aac_handle_aif
#   
#   When aac_command_thread detects an adapter event (AifCmdDriverNotify or
#   AifCmdEventNotify) it calls aac_handle_aif. This routine sets a flag,
#   calls fib_adapter_complete, and returns. The bad news is that after the
#   return, aac_command_thread continues to process the command and calls
#   fib_adapter_complete again.
#   
#   Under some circumstances this causes the driver to take the device
#   offline. In my case, it happens with a Dell CERC SATA with a RAID 5 in
#   the "building" state:
#   
#   aacraid: Host adapter reset request. SCSI hang ?
#   aacraid: Host adapter appears dead
#   scsi: Device offlined - not ready after error recovery: host 0 channel 0
#   id 0 lun 0
#   SCSI error : <0 0 0 0> return code = 0x6000000
#   end_request: I/O error, dev sda, sector 976537592
#   
#   Mark Salyzyn says the intent is for aac_handle_aif to perform some
#   plug-n-play actions based on the adapter event, and return, leaving the
#   command completion to the caller.
#   
#   The attached patch solves the problem by removing aac_handle_aif
#   entirely, since it is wrong, and there is currently no code in the
#   driver to actually do anything with these events.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/aacraid/commsup.c
#   2005/01/02 18:00:00-06:00 coughlan@redhat.com +0 -27
#   aacraid: remove aac_handle_aif
# 
# ChangeSet
#   2005/01/03 21:17:14+01:00 sam@mars.ravnborg.org 
#   kconfig: introduce util.c
#   
#   Moved two functions from menu.c to new file util.c.
#   Introduced functions to handle growable strings - no user yet.
#   
#   Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
# 
# scripts/kconfig/util.c
#   2005/01/03 21:16:54+01:00 sam@mars.ravnborg.org +109 -0
# 
# scripts/kconfig/zconf.y
#   2005/01/03 21:16:54+01:00 sam@mars.ravnborg.org +1 -0
#   Include util.c
# 
# scripts/kconfig/zconf.tab.c_shipped
#   2005/01/03 21:16:54+01:00 sam@mars.ravnborg.org +1 -0
#   Include util.c
# 
# scripts/kconfig/util.c
#   2005/01/03 21:16:54+01:00 sam@mars.ravnborg.org +0 -0
#   BitKeeper file /home/sam/bk/kconfig/scripts/kconfig/util.c
# 
# scripts/kconfig/menu.c
#   2005/01/03 21:16:54+01:00 sam@mars.ravnborg.org +0 -40
#   Moved file_lookup() and file_write_dep() to util.c
# 
# scripts/kconfig/lkc.h
#   2005/01/03 21:16:54+01:00 sam@mars.ravnborg.org +13 -0
#   Added prototypes for util.c
# 
# ChangeSet
#   2005/01/03 19:06:13+01:00 sam@mars.ravnborg.org 
#   kconfig: pass 0, 0 to show_file() to select max size window
#   
#   From: Roman Zippel <zippel@linux-m68k.org>
#   Signed-off-by: Sam Ravbnorg <sam@ravnborg.org>
# 
# scripts/kconfig/mconf.c
#   2005/01/03 19:05:50+01:00 sam@mars.ravnborg.org +5 -5
#   pass 0, 0 to show_file to select max size
# 
# ChangeSet
#   2005/01/03 11:01:25-06:00 hch@lst.de 
#   [PATCH] gdth: cleanup compat clutter
#   
#   This patch
#   
#   - removes support for 2.2.x and 2.4.x without the full dma API
#     (<= 2.4.13 or 2.4.9rh)
#   - makes sure we don't acquire or release unessecary locks around
#     ->scsi_done - it's a small BH/softirq that doesn't care about
#     the callers lock state
#   - cleans up the 2.4 vs 2.6 compat code a little
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/gdth_proc.h
#   2005/01/03 10:49:16-06:00 hch@lst.de +1 -5
#   gdth: cleanup compat clutter
# 
# drivers/scsi/gdth_proc.c
#   2005/01/03 10:50:30-06:00 hch@lst.de +31 -123
#   gdth: cleanup compat clutter
# 
# drivers/scsi/gdth_kcompat.h
#   2005/01/03 10:49:17-06:00 hch@lst.de +21 -0
#   gdth: cleanup compat clutter
# 
# drivers/scsi/gdth.c
#   2005/01/03 10:53:29-06:00 hch@lst.de +111 -645
#   gdth: cleanup compat clutter
# 
# drivers/scsi/gdth_kcompat.h
#   2005/01/03 10:49:17-06:00 hch@lst.de +0 -0
#   BitKeeper file /home/jejb/BK/scsi-misc-2.6/drivers/scsi/gdth_kcompat.h
# 
# ChangeSet
#   2005/01/03 10:13:30-06:00 rddunlap@osdl.org 
#   [PATCH] gdth: reduce large on-stack locals
#   
#   gdth is the fourth-highest stack user (for a single function)
#   in 2.6.10-rc3-bk-recent (sizes on x86-32).
#   
#   Reduce stack usage in gdth driver:
#   reduce ioc_rescan() from 1564 to 52 bytes;
#   reduce ioc_hdrlist() from 1528 to 24 bytes;
#   reduce gdth_get_info() from 1076 to 300 bytes;
#   
#   Signed-off-by: Randy Dunlap <rddunlap@osdl.org>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/gdth_proc.c
#   2004/12/20 14:51:08-06:00 rddunlap@osdl.org +78 -67
#   gdth: reduce large on-stack locals
# 
# drivers/scsi/gdth.c
#   2004/12/20 12:15:33-06:00 rddunlap@osdl.org +111 -83
#   gdth: reduce large on-stack locals
# 
# ChangeSet
#   2005/01/03 10:07:16-06:00 axboe@suse.de 
#   [PATCH] gdth buggy page mapping
#   
#   Just tripped over a bug report for the SUSE kernel where gdth would
#   crash on a 32G opteron, turned out that the gdth_internal_copy() sg
#   handling was really buggy. After fixing this I wanted to do the same for
#   mainline, but I can see that a vain attempt was already made to fix it.
#   Unfortunately it wasn't complete, and on top of that there's room for
#   improvement.
#   
#   The current code is buggy on highmem, as page_address() will not yield a
#   valid kernel address causing a NULL pointer dereference. The current
#   code also doesn't unmap the sg list if it sees a NULL sl->page. In fact,
#   the whole sg mapping looks really strange, why on earth would you be
#   mapping the sglist for dma when you are only going to copy from it?
#   
#   This patch corrects both errors - correctly maps in the page, and kills
#   the pci_map_sg/pci_unmap_sg calls completely. If someone could test
#   this, that would be great.
#   
#   Signed-off-by: Jens Axboe <axboe@suse.de>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/gdth.c
#   2004/11/23 13:13:04-06:00 axboe@suse.de +9 -9
#   gdth buggy page mapping
# 
# ChangeSet
#   2005/01/02 14:36:23+01:00 marcel@holtmann.org 
#   [Bluetooth] Remove casts in BCSP driver
#   
#   This patch removes unneeded casts of (void *) pointers.
#   
#   Signed-off-by: Domen Puncer <domen@coderock.org>
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# drivers/bluetooth/hci_bcsp.c
#   2005/01/02 14:34:50+01:00 marcel@holtmann.org +2 -2
#   Remove casts in BCSP driver
# 
# ChangeSet
#   2005/01/01 21:07:52-06:00 jejb@mulgrave.(none) 
#   osst: add sysfs support
#   
#   From: 	Willem Riede <osst@riede.org>
#   
#   adds sysfs support to osst. This enables hotplug and udev to manage
#   the osst /dev nodes, which is a real necessity on installations that
#   use a dynamic /dev, such as Fedora Core 3.
#   
#   signed-off-by: Willem Riede <osst@riede.org>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/osst.c
#   2005/01/01 21:04:08-06:00 jejb@mulgrave.(none) +167 -7
#   osst: add sysfs support
# 
# ChangeSet
#   2005/01/01 20:51:14-06:00 jejb@mulgrave.(none) 
#   osst: error handling updates
#   
#   From: 	Willem Riede <osst@riede.org>
#   
#   important error handling improvements that I've made as the result of
#   problem reports.
#   
#   signed-off-by: Willem Riede <osst@riede.org>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/osst.h
#   2005/01/01 20:49:34-06:00 jejb@mulgrave.(none) +2 -1
#   osst: error handling updates
# 
# drivers/scsi/osst.c
#   2005/01/01 20:49:34-06:00 jejb@mulgrave.(none) +131 -53
#   osst: error handling updates
# 
# ChangeSet
#   2005/01/01 20:40:31-06:00 osst@riede.org 
#   [PATCH] osst: remove typedefs
#   
#   Make style changes that are the equivalent of recent changes to st,
#   such as using 'struct osst_tape' where we used to have 'OS_Scsi_Tape'
#   as a typedef. Osst behavior is not affected by this patch.
#   
#   signed-off-by: Willem Riede <osst@riede.org>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/osst.h
#   2005/01/01 18:05:27-06:00 osst@riede.org +6 -6
#   osst: remove typedefs
# 
# drivers/scsi/osst.c
#   2005/01/01 18:11:25-06:00 osst@riede.org +247 -246
#   osst: remove typedefs
# 
# ChangeSet
#   2004/12/31 14:54:38-06:00 sleddog@us.ibm.com 
#   [PATCH] ibmvscsi: fix abort and reset error path
#   
#   Description: Fix error paths to handle SCSI targets
#   that reject SCSI aborts and resets and subsequently
#   complete SCSI commands.  There are targets in the field
#   that currently exhibit this behaviour, particularly in
#   the case of bad media (a CD drive got stuck for a LOOONG
#   time on a read op.)  We previously ignore the status
#   on aborts and resets under the mistaken belief that
#   whether they worked or not, the command response was
#   never going to show up.
#   
#   Signed-off-by: Dave Boutcher <boutcher@us.ibm.com>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/ibmvscsi/ibmvscsi.h
#   2004/12/21 14:47:44-06:00 sleddog@us.ibm.com +1 -0
#   ibmvscsi: fix abort and reset error path
# 
# drivers/scsi/ibmvscsi/ibmvscsi.c
#   2004/12/21 14:47:43-06:00 sleddog@us.ibm.com +79 -4
#   ibmvscsi: fix abort and reset error path
# 
# ChangeSet
#   2004/12/31 13:33:47-06:00 sleddog@us.ibm.com 
#   [PATCH] ibmvscsi: fix dangling pointer reference
#   
#   This code has been problematic for a while and still contained a leg
#   where free_event_struct was called....followed by a reference to the
#   event_struct.  Restructure to make the code cleaner and fix the
#   dangling pointer reference.
#   
#   Signed-off-by: Dave Boutcher <boutcher@us.ibm.com>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/ibmvscsi/ibmvscsi.c
#   2004/12/31 09:59:46-06:00 sleddog@us.ibm.com +24 -25
#   ibmvscsi: fix dangling pointer reference
# 
# ChangeSet
#   2004/12/31 13:29:49-06:00 sleddog@us.ibm.com 
#   [PATCH] ibmvscsi: fix loop exit condition
#   
#   Fix a bug where we could fall out of our delay loop and then forget to
#   scan for drives.
#   
#   Signed-off-by: Dave Boutcher <boutcher@us.ibm.com>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/ibmvscsi/ibmvscsi.c
#   2004/12/31 09:59:39-06:00 sleddog@us.ibm.com +2 -2
#   ibmvscsi: fix loop exit condition
# 
# ChangeSet
#   2004/12/31 12:19:50-06:00 sleddog@us.ibm.com 
#   [PATCH] ibmvscsi: limit size of I/O requests, updated
#   
#   Description: Limit the size of I/O requests sent by the
#   ibmvscsi adapter.  With better I/O scheduling (and thus larger
#   requests) we were breaking some servers.
#   
#   Updated based on comments from Jens Axboe and James
#   Bottomley to not specify max I/O sectors as a module
#   parameter, and subsequently not needlessly store
#   the value as a static variable.
#   
#   Signed-off-by: Dave Boutcher <boutcher@us.ibm.com>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/ibmvscsi/ibmvscsi.c
#   2004/12/31 10:42:38-06:00 sleddog@us.ibm.com +9 -3
#   ibmvscsi: limit size of I/O requests, updated
# 
# ChangeSet
#   2004/12/31 11:35:21-06:00 James.Bottomley@steeleye.com 
#   [PATCH] fix SPI transport class to do DV for broken Western Digital drives
#   
#   There's been a problem reported where a WD Ultra3 drive reports that it
#   has an echo buffer of length 255 and then returns ILLEGAL REQUEST when
#   anyone tries to use it.  This causes DV to treat this as a retraining
#   error and eventually drop back to async.
#   
#   The attached fix makes the DV code identify the ILLEGAL REQUEST
#   condition and configure the drive using the read only DV tests instead.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/scsi_transport_spi.c
#   2004/12/30 14:55:59-06:00 James.Bottomley@steeleye.com +63 -28
#   fix SPI transport class to do DV for broken Western Digital drives
# 
# ChangeSet
#   2004/12/31 11:30:15-06:00 matthew@wil.cx 
#   [PATCH] Misc zalon fixes
#   
#   Some miscellaneous cleanups for the Zalon driver:
#   
#    - Remove unused definitions of sync_scsi_data_for_cpu and
#      sync_scsi_data_for_device
#    - Fill in dev->irq in the zalon driver
#    - Request the interrupt in the name of the driver, not the bus address
#    - Change the driver name to look better in sysfs
#    - Call ncr53c8xx_exit() in zalon7xx_exit()
#   
#   Signed-off-by: Matthew Wilcox <matthew@wil.cx>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/zalon.c
#   2004/12/24 17:40:00-06:00 matthew@wil.cx +10 -11
#   Misc zalon fixes
# 
# drivers/scsi/sym53c8xx_comm.h
#   2004/12/24 17:40:00-06:00 matthew@wil.cx +0 -2
#   Misc zalon fixes
# 
# ChangeSet
#   2004/12/31 11:26:43-06:00 matthew@wil.cx 
#   [PATCH] Remove lasi700.h
#   
#   Inline lasi700.h into lasi700.c to cut down on the size of the
#   drivers/scsi directory.
#   
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/lasi700.c
#   2004/12/24 17:39:59-06:00 matthew@wil.cx +21 -1
#   Remove lasi700.h
# 
# BitKeeper/deleted/.del-lasi700.h~7b65d6523b8b75b
#   2004/12/31 11:25:37-06:00 matthew@wil.cx +0 -0
#   Delete: drivers/scsi/lasi700.h
# 
# ChangeSet
#   2004/12/31 11:21:01-06:00 matthew@wil.cx 
#   [PATCH] sym2 version 2.1.18n
#   
#   sym2 version 2.1.18n:
#    - Prevent querying for DT clocking on a single ended bus
#    - Check the U3EN bit instead of the ULTRA3 bit
#    - Only use PPR if SDTR is incapable of negotiating the desired options or
#      speed
#    - minsync bugfix (James Bottomley)
#    - Always calculate what negotiation to perform inside sym_prepare_nego()
#    - Delete unused SYM_OPT_HANDLE_IO_TIMEOUT and SYM_CONF_TIMEOUT_ORDER_MAX
#      code (Christoph Hellwig)
#    - Use SCSI-3 message names instead of SCSI-2 names
#    - Remove private definitions of PCI IDs
#    - Reorganise DMA mask setup
#    - Fix comment tpyo
#    - Make some needlessly global code static (Adrian Bunk)
#    - Reorder some functions to eliminate predeclaration
#    - Use memset instead of bzero
#    - Consolidate and abstract SPARC's special IRQ printing
#    - Convert hcb_p to struct sym_hcb *
#    - Remove cam_ccb_p and cam_scsiio_p typedefs
#    - Treat PA-RISC firmware as if it were a type of NVRAM
#   
#   Signed-off-by: Matthew Wilcox <matthew@wil.cx>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/sym53c8xx_2/sym_nvram.h
#   2004/12/24 17:40:03-06:00 matthew@wil.cx +6 -0
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_nvram.c
#   2004/12/24 17:40:03-06:00 matthew@wil.cx +38 -1
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_misc.c
#   2004/12/24 17:40:03-06:00 matthew@wil.cx +1 -97
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_malloc.c
#   2004/12/24 17:40:03-06:00 matthew@wil.cx +1 -1
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_hipd.h
#   2004/12/24 17:40:03-06:00 matthew@wil.cx +22 -50
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_hipd.c
#   2004/12/29 13:40:39-06:00 matthew@wil.cx +193 -276
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_glue.h
#   2004/12/24 17:40:02-06:00 matthew@wil.cx +9 -25
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_glue.c
#   2004/12/24 17:40:02-06:00 matthew@wil.cx +30 -53
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_fw.c
#   2004/12/24 17:40:02-06:00 matthew@wil.cx +2 -2
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_defs.h
#   2004/12/29 13:42:34-06:00 matthew@wil.cx +7 -27
#   sym2 version 2.1.18n
# 
# drivers/scsi/sym53c8xx_2/sym_conf.h
#   2004/12/24 17:40:02-06:00 matthew@wil.cx +0 -8
#   sym2 version 2.1.18n
# 
# ChangeSet
#   2004/12/31 11:17:57-06:00 jejb@mulgrave.(none) 
#   SCSI: update ipr to use the change_queue_depth API
#   
#   Instead of doing an attribute override.
#   
#   Ack'd by: Brian King <brking@us.ibm.com>
#   Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
# 
# drivers/scsi/ipr.c
#   2004/12/31 11:16:52-06:00 jejb@mulgrave.(none) +7 -21
#   SCSI: update ipr to use the change_queue_depth API
# 
# ChangeSet
#   2004/12/30 15:50:53-08:00 sri@us.ibm.com 
#   [SCTP] Fix sctp_getladdrs() to return valid local addresses on an endpoint
#   that is bound to INADDR_ANY or inaddr6_any.
#   
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/socket.c
#   2004/12/30 15:50:38-08:00 sri@us.ibm.com +110 -10
#   [SCTP] Fix sctp_getladdrs() to return valid local addresses on an endpoint
#   that is bound to INADDR_ANY or inaddr6_any.
# 
# ChangeSet
#   2004/12/29 11:35:11-08:00 sri@us.ibm.com 
#   [SCTP] Fix misc. issues in SCTP_PEER_ADDR_PARAMS set socket option.
#   
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/transport.c
#   2004/12/29 11:35:02-08:00 sri@us.ibm.com +0 -1
#   [SCTP] Remove the redundant error_threshold from struct transport.
# 
# net/sctp/socket.c
#   2004/12/29 11:35:01-08:00 sri@us.ibm.com +8 -4
#   [SCTP] Fix misc. issues in SCTP_PEER_ADDR_PARAMS set socket option.
# 
# net/sctp/sm_sideeffect.c
#   2004/12/29 11:35:01-08:00 sri@us.ibm.com +1 -1
#   [SCTP] Remove the redundant error_threshold and use max_retrans.
# 
# net/sctp/associola.c
#   2004/12/29 11:35:01-08:00 sri@us.ibm.com +1 -2
#   [SCTP] Remove the redundant peer->error_threshold and use peer->max_retrans.
# 
# include/net/sctp/structs.h
#   2004/12/29 11:35:01-08:00 sri@us.ibm.com +0 -6
#   [SCTP] Remove the redundant error_threshold from struct transport.
# 
# ChangeSet
#   2004/12/29 03:00:38-05:00 davej@redhat.com 
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# include/linux/cpufreq.h
#   2004/12/29 03:00:17-05:00 davej@redhat.com +0 -3
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/proc_intf.c
#   2004/12/29 03:00:17-05:00 davej@redhat.com +0 -263
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/12/29 03:00:17-05:00 davej@redhat.com +1 -1
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Makefile
#   2004/12/29 03:00:17-05:00 davej@redhat.com +0 -1
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Kconfig
#   2004/12/29 03:00:17-05:00 davej@redhat.com +0 -12
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:58:59-05:00 davej@redhat.com 
#   [CPUFREQ] userspace: remove /proc/sys/cpu/ interface
#   
#   Remove the deprecated /proc/sys/cpu/ interface to cpufreq.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# include/linux/cpufreq.h
#   2004/12/29 02:58:39-05:00 davej@redhat.com +0 -56
#   [CPUFREQ] userspace: remove /proc/sys/cpu/ interface
#   
#   Remove the deprecated /proc/sys/cpu/ interface to cpufreq.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq_userspace.c
#   2004/12/29 02:58:39-05:00 davej@redhat.com +4 -396
#   [CPUFREQ] userspace: remove /proc/sys/cpu/ interface
#   
#   Remove the deprecated /proc/sys/cpu/ interface to cpufreq.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Kconfig
#   2004/12/29 02:58:39-05:00 davej@redhat.com +0 -15
#   [CPUFREQ] userspace: remove /proc/sys/cpu/ interface
#   
#   Remove the deprecated /proc/sys/cpu/ interface to cpufreq.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:57:21-05:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: quieten driver (Venkatesh Pallipadi)
#   
#   Patch to remove speedstep-centrino error messages getting printed by default.
#   Print them only when debug flags are enabled.
#   
#   The reason for this patch is -
#   With the multiple drivers model that we have now, any installation will try
#   different drivers one after the other, until one of them succeeds. So,
#   failure to add speedstep-centrino alone doesn't mean error, as some other
#   driver (say acpi.ko) can succeed later and system will still be able to use
#   speedstep. Printing the error whenever speedstep-centrino fails can confuse
#   the enduser.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/12/29 02:57:03-05:00 davej@redhat.com +6 -6
#   [CPUFREQ] speedstep-centrino: quieten driver (Venkatesh Pallipadi)
#   
#   Patch to remove speedstep-centrino error messages getting printed by default.
#   Print them only when debug flags are enabled.
#   
#   The reason for this patch is -
#   With the multiple drivers model that we have now, any installation will try
#   different drivers one after the other, until one of them succeeds. So,
#   failure to add speedstep-centrino alone doesn't mean error, as some other
#   driver (say acpi.ko) can succeed later and system will still be able to use
#   speedstep. Printing the error whenever speedstep-centrino fails can confuse
#   the enduser.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:55:56-05:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: transient MSR values (Venkatesh Pallipadi)
#   
#   On some CPUs, we can see transient MSR values (which are not present in _PSS)
#   in IA32_PERF_STATUS MSR, while CPU is doing some automatic P-state transition
#   (like TM2).
#   Current code will return frequency as 0 in such cases. Fix it by retrying the
#   get after a delay and use lowest possible frequency as the current frequency
#   in worst case.
#   
#   Thanks to Matt Domsch for identifying and root-causing this failure.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/12/29 02:55:38-05:00 davej@redhat.com +40 -8
#   [CPUFREQ] speedstep-centrino: transient MSR values (Venkatesh Pallipadi)
#   
#   On some CPUs, we can see transient MSR values (which are not present in _PSS)
#   in IA32_PERF_STATUS MSR, while CPU is doing some automatic P-state transition
#   (like TM2).
#   Current code will return frequency as 0 in such cases. Fix it by retrying the
#   get after a delay and use lowest possible frequency as the current frequency
#   in worst case.
#   
#   Thanks to Matt Domsch for identifying and root-causing this failure.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:54:41-05:00 davej@redhat.com 
#   [CPUFREQ] Check in missing file for cpufreq stats.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq_stats.c
#   2004/12/29 02:54:22-05:00 davej@redhat.com +334 -0
# 
# drivers/cpufreq/cpufreq_stats.c
#   2004/12/29 02:54:22-05:00 davej@redhat.com +0 -0
#   BitKeeper file /home/davej/bk/cpufreq/drivers/cpufreq/cpufreq_stats.c
# 
# ChangeSet
#   2004/12/29 02:53:28-05:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: fix SMP memory leak
#   
#   Venkatesh Pallipadi made me aware of a memory leak in speedstep-centrino:
#   centrino_model is allocated for all CPUs. There were two possibilities: either
#   make the centrino_model data per-CPU, or to share it across CPUs. I chose the
#   former variant, as ACPI data may be broken and/or different for multiple CPUs.
#   
#   Additionally, I made centrino_cpu per-CPU, and removed a check whether setting
#   allowed_cpus to policy->cpus resulted in smp_processor_id() == policy->cpu:
#   if policy->cpus has more than one bit set, this check will fail very often.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/12/29 02:53:13-05:00 davej@redhat.com +57 -54
#   [CPUFREQ] speedstep-centrino: fix SMP memory leak
#   
#   Venkatesh Pallipadi made me aware of a memory leak in speedstep-centrino:
#   centrino_model is allocated for all CPUs. There were two possibilities: either
#   make the centrino_model data per-CPU, or to share it across CPUs. I chose the
#   former variant, as ACPI data may be broken and/or different for multiple CPUs.
#   
#   Additionally, I made centrino_cpu per-CPU, and removed a check whether setting
#   allowed_cpus to policy->cpus resulted in smp_processor_id() == policy->cpu:
#   if policy->cpus has more than one bit set, this check will fail very often.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:51:32-05:00 davej@redhat.com 
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# include/linux/cpufreq.h
#   2004/12/29 02:51:14-05:00 davej@redhat.com +5 -0
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/freq_table.c
#   2004/12/29 02:51:14-05:00 davej@redhat.com +5 -0
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/12/29 02:51:14-05:00 davej@redhat.com +4 -2
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Makefile
#   2004/12/29 02:51:14-05:00 davej@redhat.com +2 -0
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Kconfig
#   2004/12/29 02:51:13-05:00 davej@redhat.com +16 -0
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:49:58-05:00 davej@redhat.com 
#   [CPUFREQ] powernow-k8: handle invalid initial frequency/voltage pairs correctly
#   
#   From: Paul Devriendt
#   
#   patch for powernow-k8 problem (Mobile Sempron 2800+, Acer Aspire 1362 )
#   
#   If the initial frequency/voltage pair are not valid in the frequency table,
#   the first requested transition is to make them valid. Fix the code doing so.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2004/12/29 02:49:41-05:00 davej@redhat.com +1 -1
#   [CPUFREQ] powernow-k8: handle invalid initial frequency/voltage pairs correctly
#   
#   From: Paul Devriendt
#   
#   patch for powernow-k8 problem (Mobile Sempron 2800+, Acer Aspire 1362 )
#   
#   If the initial frequency/voltage pair are not valid in the frequency table,
#   the first requested transition is to make them valid. Fix the code doing so.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:48:47-05:00 davej@redhat.com 
#   [CPUFREQ] nforce2: use unified cpufreq debug infrastructure
#   
#   Use the unified cpufreq debug infrastructure in the cpufreq-nforce2 driver.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
#   2004/12/29 02:48:24-05:00 davej@redhat.com +1 -10
#   [CPUFREQ] nforce2: use unified cpufreq debug infrastructure
#   
#   Use the unified cpufreq debug infrastructure in the cpufreq-nforce2 driver.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:47:36-05:00 davej@redhat.com 
#   [CPUFREQ] core: CPUFREQ_GOV_STOP needs to be last
#   
#   Assert that the call to the cpufreq governor with CPUFREQ_GOV_STOP is really
#   the last. Without this patch, some strange in-kernel preemption combined with
#   the scheduler disliking the "removing" task may cause the opposite.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/12/29 02:47:18-05:00 davej@redhat.com +4 -1
#   [CPUFREQ] core: CPUFREQ_GOV_STOP needs to be last
#   
#   Assert that the call to the cpufreq governor with CPUFREQ_GOV_STOP is really
#   the last. Without this patch, some strange in-kernel preemption combined with
#   the scheduler disliking the "removing" task may cause the opposite.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:46:18-05:00 davej@redhat.com 
#   [CPUFREQ] powernow-k8: small cleanups / documentation additions (Pavel Machek)
#   
#   From: Pavel Machek <pavel (AT) ucw.cz>
#   
#   These are very small cleanups / documentation additions. It avoids
#   using different names for same fields in different structures.
#   
#   Updated to latest cpufreq-bk by Dominik Brodowski, and ack'ed by Mark
#   Langsdorf, Paul Devriendt and Pavel Machek.
#   
#   Signed-off-by: Pavel Machek <pavel@suse.cz>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.h
#   2004/12/29 02:46:01-05:00 davej@redhat.com +4 -5
#   [CPUFREQ] powernow-k8: small cleanups / documentation additions (Pavel Machek)
#   
#   From: Pavel Machek <pavel (AT) ucw.cz>
#   
#   These are very small cleanups / documentation additions. It avoids
#   using different names for same fields in different structures.
#   
#   Updated to latest cpufreq-bk by Dominik Brodowski, and ack'ed by Mark
#   Langsdorf, Paul Devriendt and Pavel Machek.
#   
#   Signed-off-by: Pavel Machek <pavel@suse.cz>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2004/12/29 02:46:00-05:00 davej@redhat.com +15 -10
#   [CPUFREQ] powernow-k8: small cleanups / documentation additions (Pavel Machek)
#   
#   From: Pavel Machek <pavel (AT) ucw.cz>
#   
#   These are very small cleanups / documentation additions. It avoids
#   using different names for same fields in different structures.
#   
#   Updated to latest cpufreq-bk by Dominik Brodowski, and ack'ed by Mark
#   Langsdorf, Paul Devriendt and Pavel Machek.
#   
#   Signed-off-by: Pavel Machek <pavel@suse.cz>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:44:51-05:00 davej@redhat.com 
#   [CPUFREQ] acpi-cpufreq: force setting of P-State upon resume
#   
#   Upon resuming from sleep or swsusp, the ACPI P-States driver can't determine
#   the current CPU frequency, as the ACPI specification doesn't contain a method
#   to determine the current P-State.
#   
#   Therefore, _always_ re-set the CPU to the P-State it was before suspending,
#   and don't abort early if this is the same state as the CPU was put to
#   before (like it does make sense when using the ondemand governor, for example).
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
#   2004/12/29 02:44:34-05:00 davej@redhat.com +24 -3
#   [CPUFREQ] acpi-cpufreq: force setting of P-State upon resume
#   
#   Upon resuming from sleep or swsusp, the ACPI P-States driver can't determine
#   the current CPU frequency, as the ACPI specification doesn't contain a method
#   to determine the current P-State.
#   
#   Therefore, _always_ re-set the CPU to the P-State it was before suspending,
#   and don't abort early if this is the same state as the CPU was put to
#   before (like it does make sense when using the ondemand governor, for example).
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:42:43-05:00 davej@redhat.com 
#   [CPUFREQ] re-add call to cpufreq_driver->resume()
#   
#   (if anyone has a brown spare paper bag, feel free to send it to me:)
#   
#   The call to cpufreq_driver->resume() got lost in 2.6.6. Re-add it at the
#   proper place.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/12/29 02:42:27-05:00 davej@redhat.com +7 -0
#   [CPUFREQ] re-add call to cpufreq_driver->resume()
#   
#   (if anyone has a brown spare paper bag, feel free to send it to me:)
#   
#   The call to cpufreq_driver->resume() got lost in 2.6.6. Re-add it at the
#   proper place.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:41:40-05:00 davej@redhat.com 
#   [CPUFREQ] powernow-k8: unregister from ACPI perflib in error path
#   
#   If something fails in the per-CPU initialization in powernow-k8, it should
#   unregister itself from the ACPI performance library.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2004/12/29 02:41:24-05:00 davej@redhat.com +2 -0
#   [CPUFREQ] powernow-k8: unregister from ACPI perflib in error path
#   
#   If something fails in the per-CPU initialization in powernow-k8, it should
#   unregister itself from the ACPI performance library.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:40:22-05:00 davej@redhat.com 
#   [CPUFREQ] powernow-k7: ACPI perflib unregistration cleanup
#   
#   The unregistration of the ACPI performance library should be done in the
#   CPU exit function, and the cleanup too.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/12/29 02:40:04-05:00 davej@redhat.com +11 -8
#   [CPUFREQ] powernow-k7: ACPI perflib unregistration cleanup
#   
#   The unregistration of the ACPI performance library should be done in the
#   CPU exit function, and the cleanup too.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:39:04-05:00 davej@redhat.com 
#   [CPUFREQ] make ondemand governor aware of CPU domains
#   
#   The following patch makes ondemand governor aware of policy->cpus.
#   
#   policy->cpus mask lets multiple cpu use the same policy (useful where cpus
#   share the frequency state), a recent change in cpufreq core.
#   
#   Now ondemand governor looks at all cpus in policy->cpus and takes its
#   frequency increase/decrease decisions based on most lightly loaded cpu in
#   the group. This patch will not affect systems where policy->cpus contain
#   only one cpu.
#   
#   Signed-off-by: "Venkatesh Pallipadi" <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq_ondemand.c
#   2004/12/29 02:38:49-05:00 davej@redhat.com +64 -13
#   [CPUFREQ] make ondemand governor aware of CPU domains
#   
#   The following patch makes ondemand governor aware of policy->cpus.
#   
#   policy->cpus mask lets multiple cpu use the same policy (useful where cpus
#   share the frequency state), a recent change in cpufreq core.
#   
#   Now ondemand governor looks at all cpus in policy->cpus and takes its
#   frequency increase/decrease decisions based on most lightly loaded cpu in
#   the group. This patch will not affect systems where policy->cpus contain
#   only one cpu.
#   
#   Signed-off-by: "Venkatesh Pallipadi" <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/28 17:04:30-08:00 sri@us.ibm.com 
#   [SCTP] Fix bug in setting ephemeral port in the bind address.
#   
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/socket.c
#   2004/12/28 17:04:18-08:00 sri@us.ibm.com +2 -4
#   [SCTP] Fix bug in setting ephemeral port in the bind address.
# 
# ChangeSet
#   2004/12/28 16:22:41-08:00 sri@us.ibm.com 
#   [SCTP] Clean up the T3_rtx timer when deleting a transport.
#   
#   Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com>
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/transport.c
#   2004/12/28 16:22:31-08:00 sri@us.ibm.com +10 -0
#   [SCTP] Clean up the T3 timer when reving a transport.  There is no
#   reason to wait till timer fires, since we don't do anything with
#   chunks sitting on this transport anyway.  This also cleans up the
#   refcounts on the association and lets it go away sooner.
# 
# ChangeSet
#   2004/12/28 16:03:30-08:00 sri@us.ibm.com 
#   [SCTP] Implementation of SCTP Implementer's Guide Section 2.35.
#   This code checks that the verification tag, source port and
#   destination port in the SCTP header matches the information
#   contained in the state cookie.
#   
#   Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com>
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/sm_make_chunk.c
#   2004/12/28 16:03:19-08:00 sri@us.ibm.com +18 -0
#   [SCTP] Verify that vtag, source, and destination ports in the
#   sctp header is the same as the information contained in the
#   state cookie. Report an error and drop the packet otherwise.
# 
# net/sctp/associola.c
#   2004/12/28 16:03:18-08:00 sri@us.ibm.com +1 -0
#   [SCTP] Set the source port in the state cookie so we can easily verify it later.
# 
# include/net/sctp/structs.h
#   2004/12/28 16:03:18-08:00 sri@us.ibm.com +9 -0
#   [SCTP] Add a my_port member to the sctp_cookie.  This will hold the
#   source port for verification purposes. Also added explicit padding
#   to keep track of a memory gap in the structure.
# 
# include/net/sctp/constants.h
#   2004/12/28 16:03:18-08:00 sri@us.ibm.com +1 -0
#   [SCTP] Add an internal error code when we see a port  mismatch or an invalid port.
# 
# ChangeSet
#   2004/12/28 15:47:51-08:00 sri@us.ibm.com 
#   [SCTP] Validate and respond to invalid chunk/parameter lengths.
#   
#   Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com>
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/sm_statefuns.c
#   2004/12/28 15:47:33-08:00 sri@us.ibm.com +342 -12
#   [SCTP] Verify chunk lengths for each chunk type and report an error
#   if the chunk length is invalid.
# 
# net/sctp/sm_make_chunk.c
#   2004/12/28 15:47:33-08:00 sri@us.ibm.com +61 -1
#   [SCTP] Add a function that generates an ABORT with a PROTOCOL VIOLATION
#   error cause. Use this when a parameter length is invalid.
# 
# net/sctp/inqueue.c
#   2004/12/28 15:47:32-08:00 sri@us.ibm.com +24 -2
#   [SCTP] Add a check for partial chunks, i.e. chunks that have a length
#   that exceeds the length of the packet.
# 
# net/sctp/input.c
#   2004/12/28 15:47:32-08:00 sri@us.ibm.com +16 -3
#   [SCTP] Add sanity checks to make sure that we have enough buffer space
#   and make sure that we do not overflow.
# 
# net/sctp/endpointola.c
#   2004/12/28 15:47:32-08:00 sri@us.ibm.com +1 -1
#   [SCTP] Correct the subtype handline. (code cleanup)
# 
# net/sctp/associola.c
#   2004/12/28 15:47:32-08:00 sri@us.ibm.com +4 -3
#   [SCTP] Correct the subtype handling (code cleanup).
# 
# include/net/sctp/sm.h
#   2004/12/28 15:47:31-08:00 sri@us.ibm.com +5 -0
#   [SCTP] Add function prototype that makes an ABORT with a PROTOCOL VIOLATION error code.
# 
# include/net/sctp/sctp.h
#   2004/12/28 15:47:31-08:00 sri@us.ibm.com +5 -5
#   [SCTP] Modified the macros that walk sctp parameters and errors to not
#   exceed the length of the buffer.
# 
# include/linux/sctp.h
#   2004/12/28 15:47:31-08:00 sri@us.ibm.com +1 -1
#   [SCTP] Fix the typedef for sctp_abort_chunk_t.
# 
# ChangeSet
#   2004/12/27 14:13:06-08:00 sri@us.ibm.com 
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
#   
#   Signed-off-by: Jerome Forissier <jerome.forissier@hp.com>
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/sm_statetable.c
#   2004/12/27 14:12:53-08:00 sri@us.ibm.com +23 -0
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
# 
# net/sctp/sm_statefuns.c
#   2004/12/27 14:12:53-08:00 sri@us.ibm.com +31 -11
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
# 
# net/sctp/ipv6.c
#   2004/12/27 14:12:53-08:00 sri@us.ibm.com +6 -0
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
# 
# net/sctp/input.c
#   2004/12/27 14:12:53-08:00 sri@us.ibm.com +32 -1
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
# 
# net/sctp/debug.c
#   2004/12/27 14:12:53-08:00 sri@us.ibm.com +2 -1
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
# 
# include/net/sctp/sm.h
#   2004/12/27 14:12:53-08:00 sri@us.ibm.com +3 -0
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
# 
# include/net/sctp/sctp.h
#   2004/12/27 14:12:53-08:00 sri@us.ibm.com +4 -0
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
# 
# include/net/sctp/constants.h
#   2004/12/27 14:12:52-08:00 sri@us.ibm.com +2 -1
#   [SCTP] Treat ICMP protocol unreachable errors from non-SCTP capable hosts as
#   ABORTs.
# 
# ChangeSet
#   2004/12/27 10:51:01-08:00 sri@us.ibm.com 
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
#   
#   Signed-off-by: Adrian Bunk <bunk@stutsa.de>
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/ulpqueue.c
#   2004/12/27 10:50:49-08:00 sri@us.ibm.com +1 -20
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/ulpevent.c
#   2004/12/27 10:50:49-08:00 sri@us.ibm.com +9 -8
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/tsnmap.c
#   2004/12/27 10:50:49-08:00 sri@us.ibm.com +5 -34
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/transport.c
#   2004/12/27 10:50:49-08:00 sri@us.ibm.com +28 -28
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/ssnmap.c
#   2004/12/27 10:50:49-08:00 sri@us.ibm.com +5 -2
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/socket.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +2 -2
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/sm_statetable.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +19 -8
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/sm_statefuns.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +54 -27
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/sm_sideeffect.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +44 -22
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/sm_make_chunk.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +25 -54
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/protocol.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +17 -17
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/proc.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +1 -1
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/outqueue.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +1 -14
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/objcnt.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +1 -1
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/ipv6.c
#   2004/12/27 10:50:48-08:00 sri@us.ibm.com +11 -9
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/inqueue.c
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +0 -13
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/input.c
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +26 -21
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/endpointola.c
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +27 -27
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/debug.c
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +0 -17
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/command.c
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +0 -23
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/chunk.c
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +4 -4
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/bind_addr.c
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +0 -17
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# net/sctp/associola.c
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +26 -46
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# include/net/sctp/ulpqueue.h
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +0 -1
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# include/net/sctp/ulpevent.h
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +0 -2
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# include/net/sctp/tsnmap.h
#   2004/12/27 10:50:47-08:00 sri@us.ibm.com +0 -16
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# include/net/sctp/structs.h
#   2004/12/27 10:50:46-08:00 sri@us.ibm.com +0 -22
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# include/net/sctp/sm.h
#   2004/12/27 10:50:46-08:00 sri@us.ibm.com +0 -61
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# include/net/sctp/sctp.h
#   2004/12/27 10:50:46-08:00 sri@us.ibm.com +0 -10
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# include/net/sctp/constants.h
#   2004/12/27 10:50:46-08:00 sri@us.ibm.com +0 -4
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# include/net/sctp/command.h
#   2004/12/27 10:50:46-08:00 sri@us.ibm.com +0 -13
#   [SCTP] Code cleanup: remove unused code and make needlessly global code static
# 
# ChangeSet
#   2004/12/26 19:20:47+01:00 marcel@holtmann.org 
#   [Bluetooth] Add HIDP message parsing
#   
#   This patch introduces changes to incoming packet processing and
#   parsing structure for recieved messages.
#   
#   Signed-off-by: Matthew Grant <grantma@anathoth.gen.nz>
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# net/bluetooth/hidp/core.c
#   2004/12/26 19:19:32+01:00 marcel@holtmann.org +153 -17
#   Add HIDP message parsing
# 
# net/bluetooth/hidp/hidp.h
#   2004/12/26 19:18:59+01:00 marcel@holtmann.org +45 -0
#   Add HIDP message parsing
# 
# ChangeSet
#   2004/12/26 19:15:16+01:00 marcel@holtmann.org 
#   [Bluetooth] Update socket option handling
#   
#   This patch unifies the socket option handling across the L2CAP,
#   SCO and RFCOMM socket layers.
#   
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# net/bluetooth/rfcomm/sock.c
#   2004/12/26 19:12:43+01:00 marcel@holtmann.org +47 -3
#   Update socket option handling
# 
# net/bluetooth/sco.c
#   2004/12/26 19:12:42+01:00 marcel@holtmann.org +3 -2
#   Update socket option handling
# 
# net/bluetooth/rfcomm/core.c
#   2004/12/26 19:12:42+01:00 marcel@holtmann.org +1 -1
#   Update socket option handling
# 
# net/bluetooth/l2cap.c
#   2004/12/26 19:12:41+01:00 marcel@holtmann.org +11 -7
#   Update socket option handling
# 
# include/net/bluetooth/rfcomm.h
#   2004/12/26 19:12:40+01:00 marcel@holtmann.org +20 -3
#   Update socket option handling
# 
# include/net/bluetooth/sco.h
#   2004/12/26 19:12:39+01:00 marcel@holtmann.org +4 -3
#   Update socket option handling
# 
# include/net/bluetooth/l2cap.h
#   2004/12/26 19:12:23+01:00 marcel@holtmann.org +8 -19
#   Update socket option handling
# 
# ChangeSet
#   2004/12/26 12:17:28+01:00 marcel@holtmann.org 
#   [Bluetooth] Add module parameter for HCI_Reset
#   
#   This patch adds a module parameter to the hci_uart and hci_usb
#   drivers for forcing a HCI_Reset on initialization.
#   
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# drivers/bluetooth/hci_usb.c
#   2004/12/26 12:15:38+01:00 marcel@holtmann.org +6 -1
#   Add module parameter for HCI_Reset
# 
# drivers/bluetooth/hci_ldisc.c
#   2004/12/26 12:15:02+01:00 marcel@holtmann.org +11 -2
#   Add module parameter for HCI_Reset
# 
# ChangeSet
#   2004/12/26 12:10:57+01:00 marcel@holtmann.org 
#   [Bluetooth] Make more code static
#   
#   This patch makes more needlessly global code static.
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# net/bluetooth/rfcomm/sock.c
#   2004/12/26 12:09:39+01:00 marcel@holtmann.org +2 -2
#   Make more code static
# 
# net/bluetooth/rfcomm/core.c
#   2004/12/26 12:09:35+01:00 marcel@holtmann.org +30 -7
#   Make more code static
# 
# include/net/bluetooth/rfcomm.h
#   2004/12/26 12:08:42+01:00 marcel@holtmann.org +0 -27
#   Make more code static
# 
# ChangeSet
#   2004/12/26 12:05:31+01:00 marcel@holtmann.org 
#   [Bluetooth] Make another function static
#   
#   This patch makes a needlessly global function static.
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# net/bluetooth/cmtp/capi.c
#   2004/12/26 12:04:30+01:00 marcel@holtmann.org +13 -15
#   Make another function static
# 
# net/bluetooth/cmtp/cmtp.h
#   2004/12/26 12:03:50+01:00 marcel@holtmann.org +0 -1
#   Make another function static
# 
# ChangeSet
#   2004/12/26 12:01:12+01:00 marcel@holtmann.org 
#   [Bluetooth] Make some code of the core static
#   
#   This patch makes some needlessly global code static.
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
# 
# net/bluetooth/l2cap.c
#   2004/12/26 11:59:49+01:00 marcel@holtmann.org +1 -1
#   Make some code of the core static
# 
# net/bluetooth/hci_sock.c
#   2004/12/26 11:59:47+01:00 marcel@holtmann.org +5 -5
#   Make some code of the core static
# 
# net/bluetooth/hci_conn.c
#   2004/12/26 11:59:45+01:00 marcel@holtmann.org +1 -1
#   Make some code of the core static
# 
# net/bluetooth/hci_core.c
#   2004/12/26 11:59:42+01:00 marcel@holtmann.org +2 -2
#   Make some code of the core static
# 
# include/net/bluetooth/hci_core.h
#   2004/12/26 11:58:47+01:00 marcel@holtmann.org +0 -2
#   Make some code of the core static
# 
# ChangeSet
#   2004/12/24 22:33:13-08:00 sri@us.ibm.com 
#   [SCTP] Fix potential null pointer dereference in sctp_err_lookup().
#   
#   Signed-off-by: Vladislav Yasevich <vladislav.yasevich@hp.com>
#   Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
# 
# net/sctp/input.c
#   2004/12/24 22:33:04-08:00 sri@us.ibm.com +2 -1
#   [SCTP] Fix potential null pointer dereference in sctp_err_lookup().
# 
# ChangeSet
#   2004/12/23 17:41:18-08:00 maxk@qualcomm.com 
#   Use random_ether_addr() to generate TAP MAC address.
#   
#   Signed-off-by: Mark Smith <markzzzsmith@yahoo.com.au>
#   Signed-off-by: Max Krasnyansky <maxk@qualcomm.com>
# 
# drivers/net/tun.c
#   2004/12/23 17:41:09-08:00 maxk@qualcomm.com +4 -5
#   Use random_ether_addr() to generate TAP MAC address.
# 
# ChangeSet
#   2004/12/23 17:09:06-08:00 maxk@qualcomm.com 
#   TUN/TAP driver packet queuing fixes and improvements
#   
#   Patch from Harald Roelle <harald.roelle@nm.ifi.lmu.de>
#   
#   Fixes for the following issues
#   - "Kicking" packet behavior in case of kernel packet scheduler (! TUN_ONE_QUEUE):
#     When the netif queue is stopped because of an overrun of the driver's queue,
#     no new packets are delivered to the driver until a new packet arrives, not even
#     when in the meantime there's again space in the driver's queue (gained by a
#     reading user process). In short, whenever netif queue was stopped, one needs an
#     additional packet to "kick" packet delivery to the driver.
#     The reason for this is, that the netif queue is started but not woken up, i.e.
#     the rest of the kernel is not signaled to resume packet delivery.
#   
#   - Adjustment of tx queue length by ifconfig has only effect when TUN_ONE_QUEUE
#     is set.  Otherwise always constant TUN_READQ_SIZE queue length is used.
#   
#   - TX queue default length setting is not consistent:
#     o TAP dev + TUN_ONE_QUEUE: 1000 (by ether_setup())
#     o all other cases: 10
#   
#   - Default tx queue length is too short in many cases.
#     IMHO it should be at least twice as long as the number of fragments needed
#     for a maximum sized IP packet at a "typical" MTU size.
#     This would ensure that at least one complete IP packet can be delivered
#     to the attached user space process, even if the packet's fragments
#     are "misaligned" in the buffer and the user process is not scheduled
#     in time to read the queue.
#   
#   Additional modifications:
#   
#   - To signal that stopping of the queue has occurred, the tx fifo overrun
#     counter is increased.
#   
#   - Implemented ethtool api. Primarily added to have a standard method requesting
#     the driver version.
#   
#   Signed-off-by: Max Krasnyansky <maxk@qualcomm.com>
# 
# include/linux/if_tun.h
#   2004/12/23 17:08:57-08:00 maxk@qualcomm.com +1 -1
#   TUN/TAP driver packet queuing fixes and improvements
#   
#   Patch from Harald Roelle <harald.roelle@nm.ifi.lmu.de>
#   
#   Fixes for the following issues
#   - "Kicking" packet behavior in case of kernel packet scheduler (! TUN_ONE_QUEUE):
#     When the netif queue is stopped because of an overrun of the driver's queue,
#     no new packets are delivered to the driver until a new packet arrives, not even
#     when in the meantime there's again space in the driver's queue (gained by a
#     reading user process). In short, whenever netif queue was stopped, one needs an
#     additional packet to "kick" packet delivery to the driver.
#     The reason for this is, that the netif queue is started but not woken up, i.e.
#     the rest of the kernel is not signaled to resume packet delivery.
#   
#   - Adjustment of tx queue length by ifconfig has only effect when TUN_ONE_QUEUE
#     is set.  Otherwise always constant TUN_READQ_SIZE queue length is used.
#   
#   - TX queue default length setting is not consistent:
#     o TAP dev + TUN_ONE_QUEUE: 1000 (by ether_setup())
#     o all other cases: 10
#   
#   - Default tx queue length is too short in many cases.
#     IMHO it should be at least twice as long as the number of fragments needed
#     for a maximum sized IP packet at a "typical" MTU size.
#     This would ensure that at least one complete IP packet can be delivered
#     to the attached user space process, even if the packet's fragments
#     are "misaligned" in the buffer and the user process is not scheduled
#     in time to read the queue.
#   
#   Additional modifications:
#   
#   - To signal that stopping of the queue has occurred, the tx fifo overrun
#     counter is increased.
#   
#   - Implemented ethtool api. Primarily added to have a standard method requesting
#     the driver version.
#   
#   Signed-off-by: Max Krasnyansky <maxk@qualcomm.com>
# 
# drivers/net/tun.c
#   2004/12/23 17:08:57-08:00 maxk@qualcomm.com +122 -14
#   TUN/TAP driver packet queuing fixes and improvements
#   
#   Patch from Harald Roelle <harald.roelle@nm.ifi.lmu.de>
#   
#   Fixes for the following issues
#   - "Kicking" packet behavior in case of kernel packet scheduler (! TUN_ONE_QUEUE):
#     When the netif queue is stopped because of an overrun of the driver's queue,
#     no new packets are delivered to the driver until a new packet arrives, not even
#     when in the meantime there's again space in the driver's queue (gained by a
#     reading user process). In short, whenever netif queue was stopped, one needs an
#     additional packet to "kick" packet delivery to the driver.
#     The reason for this is, that the netif queue is started but not woken up, i.e.
#     the rest of the kernel is not signaled to resume packet delivery.
#   
#   - Adjustment of tx queue length by ifconfig has only effect when TUN_ONE_QUEUE
#     is set.  Otherwise always constant TUN_READQ_SIZE queue length is used.
#   
#   - TX queue default length setting is not consistent:
#     o TAP dev + TUN_ONE_QUEUE: 1000 (by ether_setup())
#     o all other cases: 10
#   
#   - Default tx queue length is too short in many cases.
#     IMHO it should be at least twice as long as the number of fragments needed
#     for a maximum sized IP packet at a "typical" MTU size.
#     This would ensure that at least one complete IP packet can be delivered
#     to the attached user space process, even if the packet's fragments
#     are "misaligned" in the buffer and the user process is not scheduled
#     in time to read the queue.
#   
#   Additional modifications:
#   
#   - To signal that stopping of the queue has occurred, the tx fifo overrun
#     counter is increased.
#   
#   - Implemented ethtool api. Primarily added to have a standard method requesting
#     the driver version.
#   
#   Signed-off-by: Max Krasnyansky <maxk@qualcomm.com>
# 
# ChangeSet
#   2004/09/20 15:08:23-04:00 rl@hellgate.ch 
#   [PATCH] mc_filter on big-endian arch
#   
#   On Sat, 19 Jun 2004 17:37:37 -0400, Jeff Garzik wrote:
#   > you would be kind enough to resend the non-via-rhine patches WRT mc_filter?
#   
#   Sure. Patch is for 2.6 (not rediffed, yell if it doesn't apply
#   anymore). Btw, did you pick up the mc_filter patch for 2.4 via-rhine?
#   
#   This untested patch fixes hardware mc filters for tulip_core, winbond,
#   and atp. Hopefully :-).
#   
#   Please review and test.
#   
#   Signed-off-by: Roger Luethi <rl@hellgate.ch>
# 
# drivers/net/tulip/winbond-840.c
#   2004/06/06 12:04:19-04:00 rl@hellgate.ch +1 -1
#   mc_filter on big-endian arch
# 
# drivers/net/tulip/tulip_core.c
#   2004/06/06 12:04:36-04:00 rl@hellgate.ch +1 -1
#   mc_filter on big-endian arch
# 
# drivers/net/atp.c
#   2004/06/06 12:04:55-04:00 rl@hellgate.ch +1 -1
#   mc_filter on big-endian arch
# 
diff -Nru a/CREDITS b/CREDITS
--- a/CREDITS	2005-01-19 13:44:47 -08:00
+++ b/CREDITS	2005-01-19 13:44:47 -08:00
@@ -2936,10 +2936,10 @@
 S: Finland
 
 N: Deepak Saxena
-E: deepak@csociety.purdue.edu
+E: dsaxena@plexity.net
 D: I2O kernel layer (config, block, core, pci, net). I2O disk support for LILO
-D: XScale(IOP310) porting
-S: Tempe, Arizona
+D: XScale(IOP, IXP) porting and other random ARM bits
+S: Portland, OR
 
 N: Eric Schenk
 E: Eric.Schenk@dna.lth.se
diff -Nru a/Documentation/PCIEBUS-HOWTO.txt b/Documentation/PCIEBUS-HOWTO.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/PCIEBUS-HOWTO.txt	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,217 @@
+		The PCI Express Port Bus Driver Guide HOWTO
+	Tom L Nguyen tom.l.nguyen@intel.com
+			11/03/2004
+
+1. About this guide
+
+This guide describes the basics of the PCI Express Port Bus driver
+and provides information on how to enable the service drivers to
+register/unregister with the PCI Express Port Bus Driver.
+
+2. Copyright 2004 Intel Corporation
+
+3. What is the PCI Express Port Bus Driver
+
+A PCI Express Port is a logical PCI-PCI Bridge structure. There
+are two types of PCI Express Port: the Root Port and the Switch
+Port. The Root Port originates a PCI Express link from a PCI Express
+Root Complex and the Switch Port connects PCI Express links to
+internal logical PCI buses. The Switch Port, which has its secondary
+bus representing the switch's internal routing logic, is called the
+switch's Upstream Port. The switch's Downstream Port is bridging from
+switch's internal routing bus to a bus representing the downstream
+PCI Express link from the PCI Express Switch.
+
+A PCI Express Port can provide up to four distinct functions,
+referred to in this document as services, depending on its port type.
+PCI Express Port's services include native hotplug support (HP),
+power management event support (PME), advanced error reporting
+support (AER), and virtual channel support (VC). These services may
+be handled by a single complex driver or be individually distributed
+and handled by corresponding service drivers.
+
+4. Why use the PCI Express Port Bus Driver?
+
+In existing Linux kernels, the Linux Device Driver Model allows a
+physical device to be handled by only a single driver. The PCI
+Express Port is a PCI-PCI Bridge device with multiple distinct
+services. To maintain a clean and simple solution each service
+may have its own software service driver. In this case several
+service drivers will compete for a single PCI-PCI Bridge device.
+For example, if the PCI Express Root Port native hotplug service
+driver is loaded first, it claims a PCI-PCI Bridge Root Port. The
+kernel therefore does not load other service drivers for that Root
+Port. In other words, it is impossible to have multiple service
+drivers load and run on a PCI-PCI Bridge device simultaneously
+using the current driver model.
+
+To enable multiple service drivers running simultaneously requires
+having a PCI Express Port Bus driver, which manages all populated
+PCI Express Ports and distributes all provided service requests
+to the corresponding service drivers as required. Some key
+advantages of using the PCI Express Port Bus driver are listed below:
+
+	- Allow multiple service drivers to run simultaneously on
+	  a PCI-PCI Bridge Port device.
+
+	- Allow service drivers implemented in an independent
+	  staged approach.
+	
+	- Allow one service driver to run on multiple PCI-PCI Bridge
+	  Port devices. 
+
+	- Manage and distribute resources of a PCI-PCI Bridge Port
+	  device to requested service drivers.
+
+5. Configuring the PCI Express Port Bus Driver vs. Service Drivers
+
+5.1 Including the PCI Express Port Bus Driver Support into the Kernel
+
+Including the PCI Express Port Bus driver depends on whether the PCI
+Express support is included in the kernel config. The kernel will
+automatically include the PCI Express Port Bus driver as a kernel
+driver when the PCI Express support is enabled in the kernel.
+
+5.2 Enabling Service Driver Support
+
+PCI device drivers are implemented based on Linux Device Driver Model.
+All service drivers are PCI device drivers. As discussed above, it is
+impossible to load any service driver once the kernel has loaded the
+PCI Express Port Bus Driver. To meet the PCI Express Port Bus Driver
+Model requires some minimal changes on existing service drivers that
+imposes no impact on the functionality of existing service drivers.
+
+A service driver is required to use the two APIs shown below to
+register its service with the PCI Express Port Bus driver (see 
+section 5.2.1 & 5.2.2). It is important that a service driver
+initializes the pcie_port_service_driver data structure, included in
+header file /include/linux/pcieport_if.h, before calling these APIs.
+Failure to do so will result an identity mismatch, which prevents
+the PCI Express Port Bus driver from loading a service driver.
+
+5.2.1 pcie_port_service_register
+
+int pcie_port_service_register(struct pcie_port_service_driver *new)
+
+This API replaces the Linux Driver Model's pci_module_init API. A
+service driver should always calls pcie_port_service_register at
+module init. Note that after service driver being loaded, calls
+such as pci_enable_device(dev) and pci_set_master(dev) are no longer
+necessary since these calls are executed by the PCI Port Bus driver.
+
+5.2.2 pcie_port_service_unregister
+
+void pcie_port_service_unregister(struct pcie_port_service_driver *new)
+
+pcie_port_service_unregister replaces the Linux Driver Model's
+pci_unregister_driver. It's always called by service driver when a
+module exits.
+
+5.2.3 Sample Code
+
+Below is sample service driver code to initialize the port service
+driver data structure.
+
+static struct pcie_port_service_id service_id[] = { {
+	.vendor = PCI_ANY_ID,
+	.device = PCI_ANY_ID,
+	.port_type = PCIE_RC_PORT,
+	.service_type = PCIE_PORT_SERVICE_AER,
+	}, { /* end: all zeroes */ }
+};
+
+static struct pcie_port_service_driver root_aerdrv = {
+	.name		= (char *)device_name,
+	.id_table	= &service_id[0],
+
+	.probe		= aerdrv_load,
+	.remove		= aerdrv_unload,
+
+	.suspend	= aerdrv_suspend,
+	.resume		= aerdrv_resume,
+};
+
+Below is a sample code for registering/unregistering a service
+driver.
+
+static int __init aerdrv_service_init(void)
+{
+	int retval = 0;
+	
+	retval = pcie_port_service_register(&root_aerdrv);
+	if (!retval) {
+		/*
+		 * FIX ME
+		 */
+	}
+	return retval;
+}
+
+static void __exit aerdrv_service_exit(void) 
+{
+	pcie_port_service_unregister(&root_aerdrv);
+}
+
+module_init(aerdrv_service_init);
+module_exit(aerdrv_service_exit);
+
+6. Possible Resource Conflicts
+
+Since all service drivers of a PCI-PCI Bridge Port device are
+allowed to run simultaneously, below lists a few of possible resource
+conflicts with proposed solutions.
+
+6.1 MSI Vector Resource
+
+The MSI capability structure enables a device software driver to call
+pci_enable_msi to request MSI based interrupts. Once MSI interrupts
+are enabled on a device, it stays in this mode until a device driver
+calls pci_disable_msi to disable MSI interrupts and revert back to
+INTx emulation mode. Since service drivers of the same PCI-PCI Bridge
+port share the same physical device, if an individual service driver
+calls pci_enable_msi/pci_disable_msi it may result unpredictable
+behavior. For example, two service drivers run simultaneously on the
+same physical Root Port. Both service drivers call pci_enable_msi to
+request MSI based interrupts. A service driver may not know whether
+any other service drivers have run on this Root Port. If either one
+of them calls pci_disable_msi, it puts the other service driver
+in a wrong interrupt mode. 
+
+To avoid this situation all service drivers are not permitted to
+switch interrupt mode on its device. The PCI Express Port Bus driver
+is responsible for determining the interrupt mode and this should be
+transparent to service drivers. Service drivers need to know only
+the vector IRQ assigned to the field irq of struct pcie_device, which
+is passed in when the PCI Express Port Bus driver probes each service
+driver. Service drivers should use (struct pcie_device*)dev->irq to
+call request_irq/free_irq. In addition, the interrupt mode is stored
+in the field interrupt_mode of struct pcie_device.
+
+6.2 MSI-X Vector Resources
+
+Similar to the MSI a device driver for an MSI-X capable device can
+call pci_enable_msix to request MSI-X interrupts. All service drivers
+are not permitted to switch interrupt mode on its device. The PCI
+Express Port Bus driver is responsible for determining the interrupt
+mode and this should be transparent to service drivers. Any attempt
+by service driver to call pci_enable_msix/pci_disable_msix may
+result unpredictable behavior. Service drivers should use
+(struct pcie_device*)dev->irq and call request_irq/free_irq.
+
+6.3 PCI Memory/IO Mapped Regions
+
+Service drivers for PCI Express Power Management (PME), Advanced
+Error Reporting (AER), Hot-Plug (HP) and Virtual Channel (VC) access
+PCI configuration space on the PCI Express port. In all cases the
+registers accessed are independent of each other. This patch assumes
+that all service drivers will be well behaved and not overwrite
+other service driver's configuration settings.
+
+6.4 PCI Config Registers
+
+Each service driver runs its PCI config operations on its own
+capability structure except the PCI Express capability structure, in
+which Root Control register and Device Control register are shared
+between PME and AER. This patch assumes that all service drivers
+will be well behaved and not overwrite other service driver's
+configuration settings.
diff -Nru a/Documentation/aoe/aoe.txt b/Documentation/aoe/aoe.txt
--- a/Documentation/aoe/aoe.txt	2005-01-19 13:44:46 -08:00
+++ b/Documentation/aoe/aoe.txt	2005-01-19 13:44:46 -08:00
@@ -33,6 +33,10 @@
   "echo > /dev/etherd/discover" tells the driver to find out what AoE
   devices are available.
 
+  These character devices may disappear and be replaced by sysfs
+  counterparts, so distribution maintainers are encouraged to create
+  scripts that use these devices.
+
   The block devices are named like this:
 
 	e{shelf}.{slot}
@@ -57,19 +61,24 @@
   There is a script in this directory that formats this information
   in a convenient way.
 
-  root@makki linux# sh Documentation/aoe/status.sh 
-    device                 mac       netif           state
-      e6.0        0010040010c6        eth0              up
-      e6.1        001004001067        eth0              up
-      e6.2        001004001068        eth0              up
-      e6.3        001004001065        eth0              up
-      e6.4        001004001066        eth0              up
-      e6.5        0010040010c7        eth0              up
-      e6.6        0010040010c8        eth0              up
-      e6.7        0010040010c9        eth0              up
-      e6.8        0010040010ca        eth0              up
-      e6.9        0010040010cb        eth0              up
-      e9.0        001004000020        eth1              up
-      e9.5        001004000025        eth1              up
-      e9.9        001004000029        eth1              up
-
+  root@makki root# sh Documentation/aoe/status.sh 
+     e10.0            eth3              up
+     e10.1            eth3              up
+     e10.2            eth3              up
+     e10.3            eth3              up
+     e10.4            eth3              up
+     e10.5            eth3              up
+     e10.6            eth3              up
+     e10.7            eth3              up
+     e10.8            eth3              up
+     e10.9            eth3              up
+      e4.0            eth1              up
+      e4.1            eth1              up
+      e4.2            eth1              up
+      e4.3            eth1              up
+      e4.4            eth1              up
+      e4.5            eth1              up
+      e4.6            eth1              up
+      e4.7            eth1              up
+      e4.8            eth1              up
+      e4.9            eth1              up
diff -Nru a/Documentation/aoe/mkdevs.sh b/Documentation/aoe/mkdevs.sh
--- a/Documentation/aoe/mkdevs.sh	2005-01-19 13:44:46 -08:00
+++ b/Documentation/aoe/mkdevs.sh	2005-01-19 13:44:46 -08:00
@@ -1,9 +1,10 @@
 #!/bin/sh
 
-n_shelves=10
+n_shelves=${n_shelves:-10}
+n_partitions=${n_partitions:-16}
 
 if test "$#" != "1"; then
-	echo "Usage: sh mkdevs.sh {dir}" 1>&2
+	echo "Usage: sh `basename $0` {dir}" 1>&2
 	exit 1
 fi
 dir=$1
@@ -26,8 +27,10 @@
 rm -f $dir/interfaces
 mknod -m 0200 $dir/interfaces c $MAJOR 4
 
+export n_partitions
+mkshelf=`echo $0 | sed 's!mkdevs!mkshelf!'`
 i=0
 while test $i -lt $n_shelves; do
-	sh -xc "sh `dirname $0`/mkshelf.sh $dir $i"
+	sh -xc "sh $mkshelf $dir $i"
 	i=`expr $i + 1`
 done
diff -Nru a/Documentation/aoe/mkshelf.sh b/Documentation/aoe/mkshelf.sh
--- a/Documentation/aoe/mkshelf.sh	2005-01-19 13:44:47 -08:00
+++ b/Documentation/aoe/mkshelf.sh	2005-01-19 13:44:47 -08:00
@@ -1,18 +1,20 @@
 #! /bin/sh
 
 if test "$#" != "2"; then
-	echo "Usage: sh mkshelf.sh {dir} {shelfaddress}" 1>&2
+	echo "Usage: sh `basename $0` {dir} {shelfaddress}" 1>&2
 	exit 1
 fi
+n_partitions=${n_partitions:-16}
 dir=$1
 shelf=$2
 MAJOR=152
 
 set -e
 
-minor=`echo 10 \* $shelf \* 16 | bc`
+minor=`echo 10 \* $shelf \* $n_partitions | bc`
+endp=`echo $n_partitions - 1 | bc`
 for slot in `seq 0 9`; do
-	for part in `seq 0 15`; do
+	for part in `seq 0 $endp`; do
 		name=e$shelf.$slot
 		test "$part" != "0" && name=${name}p$part
 		rm -f $dir/$name
diff -Nru a/Documentation/aoe/status.sh b/Documentation/aoe/status.sh
--- a/Documentation/aoe/status.sh	2005-01-19 13:44:46 -08:00
+++ b/Documentation/aoe/status.sh	2005-01-19 13:44:46 -08:00
@@ -1,15 +1,28 @@
+#! /bin/sh
 # collate and present sysfs information about AoE storage
 
 set -e
-format="%8s\t%12s\t%8s\t%8s\n"
+format="%8s\t%8s\t%8s\n"
+me=`basename $0`
 
-printf "$format" device mac netif state
+# printf "$format" device mac netif state
+
+test -z "`mount | grep sysfs`" && {
+	echo "$me Error: sysfs is not mounted" 1>&2
+	exit 1
+}
+test -z "`lsmod | grep '^aoe'`" && {
+	echo  "$me Error: aoe module is not loaded" 1>&2
+	exit 1
+}
+
+for d in `ls -d /sys/block/etherd* 2>/dev/null | grep -v p` end; do
+	# maybe ls comes up empty, so we use "end"
+	test $d = end && continue
 
-for d in `ls -d /sys/block/etherd* | grep -v p`; do
 	dev=`echo "$d" | sed 's/.*!//'`
 	printf "$format" \
 		"$dev" \
-		"`cat \"$d/mac\"`" \
 		"`cat \"$d/netif\"`" \
 		"`cat \"$d/state\"`"
 done | sort
diff -Nru a/Documentation/cpu-freq/index.txt b/Documentation/cpu-freq/index.txt
--- a/Documentation/cpu-freq/index.txt	2005-01-19 13:44:45 -08:00
+++ b/Documentation/cpu-freq/index.txt	2005-01-19 13:44:45 -08:00
@@ -35,10 +35,10 @@
 ------------
 There is a CPU frequency changing CVS commit and general list where
 you can report bugs, problems or submit patches. To post a message,
-send an email to cpufreq@www.linux.org.uk, to subscribe go to
-http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
+send an email to cpufreq@lists.linux.org.uk, to subscribe go to
+http://lists.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
 mailing list are available to subscribers at
-http://www.linux.org.uk/mailman/private/cpufreq/.
+http://lists.linux.org.uk/mailman/private/cpufreq/.
 
 
 Links
@@ -50,7 +50,7 @@
 * http://cvs.arm.linux.org.uk/
 
 the CPUFreq Mailing list:
-* http://www.linux.org.uk/mailman/listinfo/cpufreq
+* http://lists.linux.org.uk/mailman/listinfo/cpufreq
 
 Clock and voltage scaling for the SA-1100:
 * http://www.lart.tudelft.nl/projects/scaling
diff -Nru a/Documentation/devices.txt b/Documentation/devices.txt
--- a/Documentation/devices.txt	2005-01-19 13:44:48 -08:00
+++ b/Documentation/devices.txt	2005-01-19 13:44:48 -08:00
@@ -2563,6 +2563,7 @@
 		128 = /dev/usb/brlvgr0	First Braille Voyager device
 		    ...
 		131 = /dev/usb/brlvgr3	Fourth Braille Voyager device
+		132 = /dev/usb/idmouse	ID Mouse (fingerprint scanner) device
 		144 = /dev/usb/lcd	USB LCD device
 		160 = /dev/usb/legousbtower0	1st USB Legotower device
 		    ...
diff -Nru a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
--- a/Documentation/feature-removal-schedule.txt	2005-01-19 13:44:47 -08:00
+++ b/Documentation/feature-removal-schedule.txt	2005-01-19 13:44:47 -08:00
@@ -15,20 +15,3 @@
 	against the LSB, and can be replaced by using udev.
 Who:	Greg Kroah-Hartman <greg@kroah.com>
 
----------------------------
-
-What:	/proc/sys/cpu/*, sysctl and /proc/cpufreq interfaces to cpufreq (2.4.x interfaces)
-When:	January 2005
-Files:	drivers/cpufreq/: cpufreq_userspace.c, proc_intf.c
-Why:	/proc/sys/cpu/* has been deprecated since inclusion of cpufreq into
-	the main kernel tree. It bloats /proc/ unnecessarily and doesn't work
-	well with the "governor"-based design of cpufreq.
-	/proc/cpufreq/* has also been deprecated for a long time and was only
-	meant for usage during 2.5. until the new sysfs-based interface became
-	ready. It has an inconsistent interface which doesn't work well with
-	userspace setting the frequency. The output from /proc/cpufreq/* can
-	be emulated using "cpufreq-info --proc" (cpufrequtils).
-	Both interfaces are superseded by the cpufreq interface in
-	/sys/devices/system/cpu/cpu%n/cpufreq/.
-Who:	Dominik Brodowski <linux@brodo.de>
-
diff -Nru a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
--- a/Documentation/filesystems/Locking	2005-01-19 13:44:47 -08:00
+++ b/Documentation/filesystems/Locking	2005-01-19 13:44:47 -08:00
@@ -350,6 +350,8 @@
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	int (*ioctl) (struct inode *, struct file *, unsigned int,
 			unsigned long);
+	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
+	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
 	int (*mmap) (struct file *, struct vm_area_struct *);
 	int (*open) (struct inode *, struct file *);
 	int (*flush) (struct file *);
@@ -383,6 +385,8 @@
 readdir: 		no
 poll:			no
 ioctl:			yes	(see below)
+unlocked_ioctl:		no	(see below)
+compat_ioctl:		no
 mmap:			no
 open:			maybe	(see below)
 flush:			no
@@ -427,6 +431,9 @@
 ->ioctl() or kill the latter completely. One of the problems is that for
 anything that resembles union-mount we won't have a struct file for all
 components. And there are other reasons why the current interface is a mess...
+
+->ioctl() on regular files is superceded by the ->unlocked_ioctl() that
+doesn't take the BKL.
 
 ->read on directories probably must go away - we should just enforce -EISDIR
 in sys_read() and friends.
diff -Nru a/Documentation/infiniband/sysfs.txt b/Documentation/infiniband/sysfs.txt
--- a/Documentation/infiniband/sysfs.txt	2005-01-19 13:44:47 -08:00
+++ b/Documentation/infiniband/sysfs.txt	2005-01-19 13:44:47 -08:00
@@ -3,6 +3,7 @@
   For each InfiniBand device, the InfiniBand drivers create the
   following files under /sys/class/infiniband/<device name>:
 
+    node_type      - Node type (CA, switch or router)
     node_guid      - Node GUID
     sys_image_guid - System image GUID
 
@@ -25,6 +26,7 @@
     sm_lid         - Subnet manager LID for port's subnet
     sm_sl          - Subnet manager SL for port's subnet
     state          - Port state (DOWN, INIT, ARMED, ACTIVE or ACTIVE_DEFER)
+    phys_state     - Port physical state (Sleep, Polling, LinkUp, etc)
 
   There is also a "counters" subdirectory, with files
 
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	2005-01-19 13:44:48 -08:00
+++ b/Documentation/kernel-parameters.txt	2005-01-19 13:44:48 -08:00
@@ -673,7 +673,11 @@
 
 	mac53c9x=	[HW,SCSI]
 			Format: <num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
-	
+
+	machvec=	[IA64]
+			Force the use of a particular machine-vector (machvec) in a generic
+			kernel.  Example: machvec=hpzx1_swiotlb
+
 	mad16=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
 
diff -Nru a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt
--- a/Documentation/networking/pktgen.txt	2005-01-19 13:44:46 -08:00
+++ b/Documentation/networking/pktgen.txt	2005-01-19 13:44:46 -08:00
@@ -1,77 +1,214 @@
-How to use the Linux packet generator module.
 
-1. Enable CONFIG_NET_PKTGEN to compile and build pktgen.o, install it
-   in the place where insmod may find it.
-2. Cut script "ipg" (see below).
-3. Edit script to set preferred device and destination IP address.
-3a.  Create more scripts for different interfaces.  Up to thirty-two
-     pktgen processes can be configured and run at once by using the
-     32 /proc/net/pktgen/pg* files.
-4. Run in shell: ". ipg"
-5. After this two commands are defined:
-   A. "pg" to start generator and to get results.
-   B. "pgset" to change generator parameters. F.e.
-      pgset "clone_skb 100"   sets the number of copies of the same packet 
-                              will be sent before a new packet is allocated
-      pgset "clone_skb 0"     use multiple SKBs for packet generation
-      pgset "pkt_size 9014"   sets packet size to 9014
-      pgset "frags 5"         packet will consist of 5 fragments
-      pgset "count 200000"    sets number of packets to send, set to zero
-                              for continuous sends until explicitly
-                              stopped.
-      pgset "ipg 5000"        sets artificial gap inserted between packets
-                              to 5000 nanoseconds
-      pgset "dst 10.0.0.1"    sets IP destination address
-                              (BEWARE! This generator is very aggressive!)
-      pgset "dst_min 10.0.0.1"            Same as dst
-      pgset "dst_max 10.0.0.254"          Set the maximum destination IP.
-      pgset "src_min 10.0.0.1"            Set the minimum (or only) source IP.
-      pgset "src_max 10.0.0.254"          Set the maximum source IP.
-      pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
-      pgset "srcmac 00:00:00:00:00:00"    sets MAC source address
-      pgset "src_mac_count 1" Sets the number of MACs we'll range through.  The
-                              'minimum' MAC is what you set with srcmac.
-      pgset "dst_mac_count 1" Sets the number of MACs we'll range through.  The
-                              'minimum' MAC is what you set with dstmac.
-      pgset "flag [name]"     Set a flag to determine behaviour.  Current flags
-                              are: IPSRC_RND #IP Source is random (between min/max),
-                                   IPDST_RND, UDPSRC_RND,
-                                   UDPDST_RND, MACSRC_RND, MACDST_RND 
-      pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
-                              cycle through the port range.
-      pgset "udp_src_max 9"   set UDP source port max.
-      pgset "udp_dst_min 9"   set UDP destination port min, If < udp_dst_max, then
-                              cycle through the port range.
-      pgset "udp_dst_max 9"   set UDP destination port max.
-      pgset stop    	      aborts injection
-      
-  Also, ^C aborts generator.
-
----- cut here
-
-#! /bin/sh
-
-modprobe pktgen
-
-PGDEV=/proc/net/pktgen/pg0
-
-function pgset() {
-    local result
-
-    echo $1 > $PGDEV
-
-    result=`cat $PGDEV | fgrep "Result: OK:"`
-    if [ "$result" = "" ]; then
-         cat $PGDEV | fgrep Result:
-    fi
-}
-
-function pg() {
-    echo inject > $PGDEV
-    cat $PGDEV
-}
 
-pgset "odev eth0"
-pgset "dst 0.0.0.0"
+                  HOWTO for the linux packet generator 
+                  ------------------------------------
 
----- cut here
+Date: 041221
+
+Enable CONFIG_NET_PKTGEN to compile and build pktgen.o either in kernel
+or as module. Module is preferred. insmod pktgen if needed. Once running
+pktgen creates a thread on each CPU where each thread has affinty it's CPU.
+Monitoring and controlling is done via /proc. Easiest to select a suitable 
+a sample script and configure.
+
+On a dual CPU:
+
+ps aux | grep pkt
+root       129  0.3  0.0     0    0 ?        SW    2003 523:20 [pktgen/0]
+root       130  0.3  0.0     0    0 ?        SW    2003 509:50 [pktgen/1]
+
+
+For montoring and control pktgen creates:
+	/proc/net/pktgen/pgctrl
+	/proc/net/pktgen/kpktgend_X
+        /proc/net/pktgen/ethX
+
+
+Viewing threads
+===============
+/proc/net/pktgen/kpktgend_0 
+Name: kpktgend_0  max_before_softirq: 10000
+Running: 
+Stopped: eth1 
+Result: OK: max_before_softirq=10000
+
+Most important the devices assigend to thread. Note! A device can only belong 
+to one thread.
+
+
+Viewing devices
+===============
+
+Parm section holds configured info. Current hold running stats. 
+Result is printed after run or after interruption. Example:
+
+/proc/net/pktgen/eth1       
+
+Params: count 10000000  min_pkt_size: 60  max_pkt_size: 60
+     frags: 0  delay: 0  clone_skb: 1000000  ifname: eth1
+     flows: 0 flowlen: 0
+     dst_min: 10.10.11.2  dst_max: 
+     src_min:   src_max: 
+     src_mac: 00:00:00:00:00:00  dst_mac: 00:04:23:AC:FD:82
+     udp_src_min: 9  udp_src_max: 9  udp_dst_min: 9  udp_dst_max: 9
+     src_mac_count: 0  dst_mac_count: 0 
+     Flags: 
+Current:
+     pkts-sofar: 10000000  errors: 39664
+     started: 1103053986245187us  stopped: 1103053999346329us idle: 880401us
+     seq_num: 10000011  cur_dst_mac_offset: 0  cur_src_mac_offset: 0
+     cur_saddr: 0x10a0a0a  cur_daddr: 0x20b0a0a
+     cur_udp_dst: 9  cur_udp_src: 9
+     flows: 0
+Result: OK: 13101142(c12220741+d880401) usec, 10000000 (60byte,0frags)
+  763292pps 390Mb/sec (390805504bps) errors: 39664
+
+Confguring threads and devices
+==============================
+This is done via the /proc interface easiest done via pgset in the scripts
+
+Examples:
+
+ pgset "clone_skb 1"     sets the number of copies of the same packet
+ pgset "clone_skb 0"     use single SKB for all transmits
+ pgset "pkt_size 9014"   sets packet size to 9014
+ pgset "frags 5"         packet will consist of 5 fragments
+ pgset "count 200000"    sets number of packets to send, set to zero
+                         for continious sends untill explicitl stopped.
+
+ pgset "delay 5000"      adds delay to hard_start_xmit(). nanoseconds
+
+ pgset "dst 10.0.0.1"    sets IP destination address
+                         (BEWARE! This generator is very aggressive!)
+
+ pgset "dst_min 10.0.0.1"            Same as dst
+ pgset "dst_max 10.0.0.254"          Set the maximum destination IP.
+ pgset "src_min 10.0.0.1"            Set the minimum (or only) source IP.
+ pgset "src_max 10.0.0.254"          Set the maximum source IP.
+ pgset "dst6 fec0::1"     IPV6 destination address
+ pgset "src6 fec0::2"     IPV6 source address
+ pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
+ pgset "srcmac 00:00:00:00:00:00"    sets MAC source address
+
+ pgset "src_mac_count 1" Sets the number of MACs we'll range through.  
+                         The 'minimum' MAC is what you set with srcmac.
+
+ pgset "dst_mac_count 1" Sets the number of MACs we'll range through.
+                         The 'minimum' MAC is what you set with dstmac.
+
+ pgset "flag [name]"     Set a flag to determine behaviour.  Current flags
+                         are: IPSRC_RND #IP Source is random (between min/max),
+                              IPDST_RND, UDPSRC_RND,
+                              UDPDST_RND, MACSRC_RND, MACDST_RND 
+
+ pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
+                         cycle through the port range.
+
+ pgset "udp_src_max 9"   set UDP source port max.
+ pgset "udp_dst_min 9"   set UDP destination port min, If < udp_dst_max, then
+                         cycle through the port range.
+ pgset "udp_dst_max 9"   set UDP destination port max.
+
+ pgset stop    	          aborts injection. Also, ^C aborts generator.
+
+
+Example scripts
+===============
+
+A collection of small tutorial scripts for pktgen is in expamples dir.
+
+pktgen.conf-1-1                  # 1 CPU 1 dev 
+pktgen.conf-1-2                  # 1 CPU 2 dev
+pktgen.conf-2-1                  # 2 CPU's 1 dev 
+pktgen.conf-2-2                  # 2 CPU's 2 dev
+pktgen.conf-1-1-rdos             # 1 CPU 1 dev w. route DoS 
+pktgen.conf-1-1-ip6              # 1 CPU 1 dev ipv6
+pktgen.conf-1-1-ip6-rdos         # 1 CPU 1 dev ipv6  w. route DoS
+pktgen.conf-1-1-flows            # 1 CPU 1 dev multiple flows.
+
+Run in shell: ./pktgen.conf-X-Y It does all the setup including sending. 
+
+
+Interrupt affinity
+===================
+Note when adding devices to a specific CPU there good idea to also assign 
+/proc/irq/XX/smp_affinity so the TX-interrupts gets bound to the same CPU.
+as this reduces cache bouncing when freeing skb's.
+
+
+Current commands and configuration options
+==========================================
+
+** Pgcontrol commands:
+
+start
+stop
+
+** Thread commands:
+
+add_device
+rem_device_all
+max_before_softirq
+
+
+** Device commands:
+
+count
+clone_skb
+debug
+
+frags
+delay
+
+src_mac_count
+dst_mac_count
+
+pkt_size 
+min_pkt_size
+max_pkt_size
+
+udp_src_min
+udp_src_max
+
+udp_dst_min
+udp_dst_max
+
+flag
+  IPSRC_RND
+  TXSIZE_RND
+  IPDST_RND
+  UDPSRC_RND
+  UDPDST_RND
+  MACSRC_RND
+  MACDST_RND
+
+dst_min
+dst_max
+
+src_min
+src_max
+
+dst_mac
+src_mac
+
+clear_counters
+
+dst6
+src6
+
+flows
+flowlen
+
+References:
+ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/
+ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/examples/
+
+Paper from Linux-Kongress in Erlangen 2004.
+ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/pktgen_paper.pdf
+
+Thanks to:
+Grant Grundler for testing on IA-64 and parisc, Harald Welte,  Lennert Buytenhek
+Stephen Hemminger, Andi Kleen, Dave Miller and many others.
+
+
+Good luck with the linux net-development.
\ No newline at end of file
diff -Nru a/Documentation/power/devices.txt b/Documentation/power/devices.txt
--- a/Documentation/power/devices.txt	2005-01-19 13:44:45 -08:00
+++ b/Documentation/power/devices.txt	2005-01-19 13:44:45 -08:00
@@ -229,3 +229,91 @@
 The driver core will not call any extra functions when binding the
 device to the driver. 
 
+pm_message_t meaning
+
+pm_message_t has two fields. event ("major"), and flags.  If driver
+does not know event code, it aborts the request, returning error. Some
+drivers may need to deal with special cases based on the actual type
+of suspend operation being done at the system level. This is why
+there are flags.
+
+Event codes are:
+
+ON -- no need to do anything except special cases like broken
+HW.
+
+# NOTIFICATION -- pretty much same as ON?
+
+FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from
+scratch. That probably means stop accepting upstream requests, the
+actual policy of what to do with them being specific to a given
+driver. It's acceptable for a network driver to just drop packets
+while a block driver is expected to block the queue so no request is
+lost. (Use IDE as an example on how to do that). FREEZE requires no
+power state change, and it's expected for drivers to be able to
+quickly transition back to operating state.
+
+SUSPEND -- like FREEZE, but also put hardware into low-power state. If
+there's need to distinguish several levels of sleep, additional flag
+is probably best way to do that.
+
+Transitions are only from a resumed state to a suspended state, never
+between 2 suspended states. (ON -> FREEZE or ON -> SUSPEND can happen,
+FREEZE -> SUSPEND or SUSPEND -> FREEZE can not).
+
+All events are:
+
+[NOTE NOTE NOTE: If you are driver author, you should not care; you
+should only look at event, and ignore flags.]
+
+#Prepare for suspend -- userland is still running but we are going to
+#enter suspend state. This gives drivers chance to load firmware from
+#disk and store it in memory, or do other activities taht require
+#operating userland, ability to kmalloc GFP_KERNEL, etc... All of these
+#are forbiden once the suspend dance is started.. event = ON, flags =
+#PREPARE_TO_SUSPEND
+
+Apm standby -- prepare for APM event. Quiesce devices to make life
+easier for APM BIOS. event = FREEZE, flags = APM_STANDBY
+
+Apm suspend -- same as APM_STANDBY, but it we should probably avoid
+spinning down disks. event = FREEZE, flags = APM_SUSPEND
+
+System halt, reboot -- quiesce devices to make life easier for BIOS. event
+= FREEZE, flags = SYSTEM_HALT or SYSTEM_REBOOT
+
+System shutdown -- at least disks need to be spun down, or data may be
+lost. Quiesce devices, just to make life easier for BIOS. event =
+FREEZE, flags = SYSTEM_SHUTDOWN
+
+Kexec    -- turn off DMAs and put hardware into some state where new
+kernel can take over. event = FREEZE, flags = KEXEC
+
+Powerdown at end of swsusp -- very similar to SYSTEM_SHUTDOWN, except wake
+may need to be enabled on some devices. This actually has at least 3
+subtypes, system can reboot, enter S4 and enter S5 at the end of
+swsusp. event = FREEZE, flags = SWSUSP and one of SYSTEM_REBOOT,
+SYSTEM_SHUTDOWN, SYSTEM_S4
+
+Suspend to ram  -- put devices into low power state. event = SUSPEND,
+flags = SUSPEND_TO_RAM
+
+Freeze for swsusp snapshot -- stop DMA and interrupts. No need to put
+devices into low power mode, but you must be able to reinitialize
+device from scratch in resume method. This has two flavors, its done
+once on suspending kernel, once on resuming kernel. event = FREEZE,
+flags = DURING_SUSPEND or DURING_RESUME
+
+Device detach requested from /sys -- deinitialize device; proably same as
+SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
+= FREEZE, flags = DEV_DETACH.
+
+#These are not really events sent:
+#
+#System fully on -- device is working normally; this is probably never
+#passed to suspend() method... event = ON, flags = 0
+#
+#Ready after resume -- userland is now running, again. Time to free any
+#memory you ate during prepare to suspend... event = ON, flags =
+#READY_AFTER_RESUME
+#
diff -Nru a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
--- a/Documentation/power/swsusp.txt	2005-01-19 13:44:48 -08:00
+++ b/Documentation/power/swsusp.txt	2005-01-19 13:44:48 -08:00
@@ -15,6 +15,9 @@
  * If you change kernel command line between suspend and resume...
  *			        ...prepare for nasty fsck or worse.
  *
+ * If you change your hardware while system is suspended...
+ *			        ...well, it was not good idea.
+ *
  * (*) suspend/resume support is needed to make it safe.
 
 You need to append resume=/dev/your_swap_partition to kernel command
@@ -183,3 +186,50 @@
 
 "platform" is actually right thing to do, but "shutdown" is most
 reliable.
+
+Q: I do not understand why you have such strong objections to idea of
+selective suspend.
+
+A: Do selective suspend during runtime power managment, that's okay. But
+its useless for suspend-to-disk. (And I do not see how you could use
+it for suspend-to-ram, I hope you do not want that).
+
+Lets see, so you suggest to
+
+* SUSPEND all but swap device and parents
+* Snapshot
+* Write image to disk
+* SUSPEND swap device and parents
+* Powerdown
+
+Oh no, that does not work, if swap device or its parents uses DMA,
+you've corrupted data. You'd have to do
+
+* SUSPEND all but swap device and parents
+* FREEZE swap device and parents
+* Snapshot
+* UNFREEZE swap device and parents
+* Write
+* SUSPEND swap device and parents
+
+Which means that you still need that FREEZE state, and you get more
+complicated code. (And I have not yet introduce details like system
+devices).
+
+Q: There don't seem to be any generally useful behavioral
+distinctions between SUSPEND and FREEZE.
+
+A: Doing SUSPEND when you are asked to do FREEZE is always correct,
+but it may be unneccessarily slow. If you want USB to stay simple,
+slowness may not matter to you. It can always be fixed later.
+
+For devices like disk it does matter, you do not want to spindown for
+FREEZE.
+
+Q: After resuming, system is paging heavilly, leading to very bad interactivity.
+
+A: Try running
+
+cat `cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u` > /dev/null
+
+after resume. swapoff -a; swapon -a may also be usefull.
diff -Nru a/Documentation/serial/driver b/Documentation/serial/driver
--- a/Documentation/serial/driver	2005-01-19 13:44:46 -08:00
+++ b/Documentation/serial/driver	2005-01-19 13:44:46 -08:00
@@ -211,17 +211,24 @@
 	Yes		1	1	character received, marked as
 					TTY_PARITY
 
+	Other flags may be used (eg, xon/xoff characters) if your
+	hardware supports hardware "soft" flow control.
+
 	Locking: none.
 	Interrupts: caller dependent.
 	This call must not sleep
 
   pm(port,state,oldstate)
-	perform any power management related activities on the specified
-	port.  state indicates the new state (defined by ACPI D0-D3),
+	Perform any power management related activities on the specified
+	port.  State indicates the new state (defined by ACPI D0-D3),
 	oldstate indicates the previous state.  Essentially, D0 means
 	fully on, D3 means powered down.
 
 	This function should not be used to grab any resources.
+
+	This will be called when the port is initially opened and finally
+	closed, except when the port is also the system console.  This
+	will occur even if CONFIG_PM is not set.
 
 	Locking: none.
 	Interrupts: caller dependent.
diff -Nru a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
--- a/Documentation/sound/alsa/ALSA-Configuration.txt	2005-01-19 13:44:45 -08:00
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt	2005-01-19 13:44:45 -08:00
@@ -184,6 +184,8 @@
     Module for ATI IXP 150/200/250 AC97 controllers.
 
     ac97_clock		- AC'97 clock (defalut = 48000)
+    ac97_quirk		- AC'97 workaround for strange hardware
+			  See the description of intel8x0 module for details.
     spdif_aclink	- S/PDIF transfer over AC-link (default = 1)
 
     This module supports up to 8 cards and autoprobe.
@@ -680,16 +682,21 @@
 			* ALi m5455
 
     ac97_clock	  - AC'97 codec clock base (0 = auto-detect)
-    ac97_quirk    - AC'97 workaround for strange hardware (-1 = default)
-                    -1 = default, don't override
-                     0 = disable
-                     1 = use headphone control as master
-                     2 = swap headphone and master controls
-                     3 = for AD1985, turn on OMS bit and use headphone
-                     4 = for ALC65x, turn on the jack sense mode
-                     5 = inverted EAPD implementation
-    buggy_irq      - Enable workaround for buggy interrupts on some
-                     motherboards (default off)
+    ac97_quirk    - AC'97 workaround for strange hardware
+                    The following strings are accepted:
+                      default = don't override the default setting
+                      disable = disable the quirk
+                      hp_only = use headphone control as master
+                      swap_hp = swap headphone and master controls
+                      swap_surround = swap master and surround controls
+                      ad_shring = for AD1985, turn on OMS bit and use headphone
+                      alc_jack = for ALC65x, turn on the jack sense mode
+                      inv_eapd = inverted EAPD implementation
+                      mute_led = bind EAPD bit for turning on/off mute LED
+                    For backward compatibility, the corresponding integer
+                    value -1, 0, ... are accepted, too.
+    buggy_irq     - Enable workaround for buggy interrupts on some
+                    motherboards (default off)
 
     Module supports autoprobe and multiple bus-master chips (max 8).
 
@@ -1402,18 +1409,21 @@
 ALSA PCM devices to OSS devices mapping
 =======================================
 
-/dev/snd/pcmC0D0  -> /dev/audio0 (/dev/audio) -> minor 4
-/dev/snd/pcmC0D0  -> /dev/dsp0 (/dev/dsp)     -> minor 3
-/dev/snd/pcmC0D1  -> /dev/adsp0 (/dev/adsp)   -> minor 12
-/dev/snd/pcmC1D0  -> /dev/audio1              -> minor 4+16 = 20
-/dev/snd/pcmC1D0  -> /dev/dsp1                -> minor 3+16 = 19
-/dev/snd/pcmC1D1  -> /dev/adsp1               -> minor 12+16 = 28
-/dev/snd/pcmC2D0  -> /dev/audio2              -> minor 4+32 = 36
-/dev/snd/pcmC2D0  -> /dev/dsp2                -> minor 3+32 = 39
-/dev/snd/pcmC2D1  -> /dev/adsp2               -> minor 12+32 = 44
+/dev/snd/pcmC0D0[c|p]  -> /dev/audio0 (/dev/audio) -> minor 4
+/dev/snd/pcmC0D0[c|p]  -> /dev/dsp0 (/dev/dsp)     -> minor 3
+/dev/snd/pcmC0D1[c|p]  -> /dev/adsp0 (/dev/adsp)   -> minor 12
+/dev/snd/pcmC1D0[c|p]  -> /dev/audio1              -> minor 4+16 = 20
+/dev/snd/pcmC1D0[c|p]  -> /dev/dsp1                -> minor 3+16 = 19
+/dev/snd/pcmC1D1[c|p]  -> /dev/adsp1               -> minor 12+16 = 28
+/dev/snd/pcmC2D0[c|p]  -> /dev/audio2              -> minor 4+32 = 36
+/dev/snd/pcmC2D0[c|p]  -> /dev/dsp2                -> minor 3+32 = 39
+/dev/snd/pcmC2D1[c|p]  -> /dev/adsp2               -> minor 12+32 = 44
+
+The first number from /dev/snd/pcmC{X}D{Y}[c|p] expression means
+soundcard number and second means device number.  The ALSA devices
+have either 'c' or 'p' suffix indicating the direction, capture and
+playback, respectively.
 
-The first number from /dev/snd/pcmC{X}D{Y} expression means soundcard number
-and second means device number.
 Please note that the device mapping above may be varied via the module
 options of snd-pcm-oss module.
 
diff -Nru a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
--- a/Documentation/usb/error-codes.txt	2005-01-19 13:44:45 -08:00
+++ b/Documentation/usb/error-codes.txt	2005-01-19 13:44:45 -08:00
@@ -83,7 +83,18 @@
 			   prescribed bus turn-around time
 			c) unknown USB error 
 
--EILSEQ (*, **)		CRC mismatch
+-EILSEQ (*, **)		a) CRC mismatch
+			b) no response packet received within the
+			   prescribed bus turn-around time
+			c) unknown USB error 
+
+			In cases b) and c) either -EPROTO or -EILSEQ
+			may be returned.  Note that often the controller
+			hardware does not distinguish among cases a),
+			b), and c), so a driver cannot tell whether
+			there was a protocol error, a failure to respond
+			(often caused by device disconnect), or some
+			other fault.
 
 -EPIPE (**)		Endpoint stalled.  For non-control endpoints,
 			reset this status with usb_clear_halt().
@@ -104,8 +115,6 @@
 			specified buffer, and URB_SHORT_NOT_OK was set in
 			urb->transfer_flags.
 
--ETIMEDOUT (**)		transfer timed out, NAK
-
 -ENODEV			Device was removed.  Often preceded by a burst of
 			other errors, since the hub driver does't detect
 			device removal events immediately.
@@ -143,4 +152,4 @@
 usb_get_*/usb_set_*():
 usb_control_msg():
 usb_bulk_msg():
-			All USB errors (submit/status) can occur
+-ETIMEDOUT		timeout expired before the transfer completed
diff -Nru a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt
--- a/Documentation/usb/sn9c102.txt	2005-01-19 13:44:47 -08:00
+++ b/Documentation/usb/sn9c102.txt	2005-01-19 13:44:47 -08:00
@@ -26,7 +26,7 @@
 
 1. Copyright
 ============
-Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>
+Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>
 
 
 2. Disclaimer
@@ -165,6 +165,17 @@
                 other camera.
 Default:        -1
 -------------------------------------------------------------------------------
+Name:           force_munmap;
+Type:           bool array (min = 0, max = 64)
+Syntax:         <0|1[,...]> 
+Description:    Force the application to unmap previously mapped buffer memory
+                before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not
+                all the applications support this feature. This parameter is
+                specific for each detected camera.
+                0 = do not force memory unmapping"
+                1 = force memory unmapping (save memory)"
+Default:        0
+-------------------------------------------------------------------------------
 Name:           debug
 Type:           int
 Syntax:         <n> 
@@ -362,11 +373,11 @@
 file descriptor. Once it is selected, the application must close and reopen the
 device to switch to the other I/O method;
 
-- previously mapped buffer memory must always be unmapped before calling any
-of the "VIDIOC_S_CROP", "VIDIOC_TRY_FMT" and "VIDIOC_S_FMT" ioctl's. The same
-number of buffers as before will be allocated again to match the size of the
-new video frames, so you have to map the buffers again before any I/O attempts
-on them.
+- although it is not mandatory, previously mapped buffer memory should always
+be unmapped before calling any "VIDIOC_S_CROP" or "VIDIOC_S_FMT" ioctl's.
+The same number of buffers as before will be allocated again to match the size
+of the new video frames, so you have to map the buffers again before any I/O
+attempts on them.
 
 Consistently with the hardware limits, this driver also supports image
 downscaling with arbitrary scaling factors from 1, 2 and 4 in both directions.
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	2005-01-19 13:44:47 -08:00
+++ b/MAINTAINERS	2005-01-19 13:44:47 -08:00
@@ -575,7 +575,7 @@
 CPU FREQUENCY DRIVERS
 P:	Dave Jones
 M:	davej@codemonkey.org.uk
-L:	cpufreq@www.linux.org.uk
+L:	cpufreq@lists.linux.org.uk
 W:	http://www.codemonkey.org.uk/projects/cpufreq/
 S:	Maintained
 
@@ -1988,6 +1988,20 @@
 W:	http://linux-visws.sf.net
 S:	Maintained for 2.6.
 
+SIMTEC EB110ATX (Chalice CATS)
+P:	Ben Dooks
+P:	Vincent Sanders
+M:	support@simtec.co.uk
+W:	http://www.simtec.co.uk/products/EB110ATX/
+S:	Supported
+
+SIMTEC EB2410ITX (BAST)
+P:	Ben Dooks
+P:	Vincent Sanders
+M:	support@simtec.co.uk
+W:	http://www.simtec.co.uk/products/EB2410ITX/
+S:	Supported
+
 SIS 5513 IDE CONTROLLER DRIVER
 P:	Lionel Bouton
 M:	Lionel.Bouton@inet6.fr
@@ -2077,6 +2091,13 @@
 M:	anton@samba.org
 L:	sparclinux@vger.kernel.org
 L:	ultralinux@vger.kernel.org
+S:	Maintained
+
+SHARP LH SUPPORT (LH7952X & LH7A40X)
+P:	Marc Singer
+M:	elf@buici.com
+W:	http://projects.buici.com/arm
+L:	linux-arm-kernel@lists.arm.linux.org.uk
 S:	Maintained
 
 SPARC (sparc32):
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/Kconfig	2005-01-19 13:44:46 -08:00
@@ -131,7 +131,7 @@
 	  <http://www.linkupsys.com/>
 
 	  If you have any questions or comments about the Linux kernel port
-	  to this board, send e-mail to sjhill@cotw.com.
+	  to this board, send e-mail to <sjhill@cotw.com>.
 
 config ARCH_PXA
 	bool "PXA2xx-based"
@@ -149,7 +149,7 @@
 	bool "Samsung S3C2410"
 	help
 	  Samsung S3C2410X CPU based systems, such as the Simtec Electronics
-	  BAST (http://www.simtec.co.uk/products/EB110ITX/), the IPAQ 1940 or
+	  BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
 	  the Samsung SMDK2410 development board (and derviatives).
 
 config ARCH_SHARK
@@ -417,20 +417,6 @@
 	  This is the physical address in your flash memory the kernel will
 	  be linked for and stored to.  This address is dependent on your
 	  own flash usage.
-
-	  Please note that, if you're using MTD, you must use a flash chip
-	  that is NOT handled by MTD or the flash will be turned into non
-	  data mode for status and query purposes which will instantaneously
-	  crash the kernel.
-
-	  MTD can however be used with a XIP kernel on the same flash chip
-	  but only if the flash memory supports multiple partitions in
-	  hardware, like with the Intel K3 flash parts, and only if the
-	  kernel is not stored within the firrst hardware partition of the
-	  chip.
-
-	  In any case, make sure that MTD support is configured out for
-	  the first attempt.
 
 if (ARCH_SA1100 || ARCH_INTEGRATOR)
 
diff -Nru a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
--- a/arch/arm/common/scoop.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/common/scoop.c	2005-01-19 13:44:46 -08:00
@@ -100,11 +100,13 @@
 	struct platform_device *pdev = to_platform_device(dev);
 	struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-	if (!mem) return -EINVAL;
+	if (!mem)
+		return -EINVAL;
 
 	inf = dev->platform_data;
 	scoop_io_base = ioremap(mem->start, 0x1000);
-	if (!scoop_io_base) return -ENOMEM;
+	if (!scoop_io_base)
+		return -ENOMEM;
 
 	SCOOP_REG(SCOOP_MCR) = 0x0140;
 
diff -Nru a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
--- a/arch/arm/configs/s3c2410_defconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/configs/s3c2410_defconfig	2005-01-19 13:44:46 -08:00
@@ -1,12 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Mon Nov 15 15:29:42 2004
+# Linux kernel version: 2.6.11-rc1-bk5
+# Tue Jan 18 11:36:49 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_IOMAP=y
 
 #
@@ -123,12 +124,20 @@
 #
 # General setup
 #
-# CONFIG_ZBOOT_ROM is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 # CONFIG_XIP_KERNEL is not set
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
 # At least one math emulation must be selected
 #
 CONFIG_FPE_NWFPE=y
@@ -143,6 +152,7 @@
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 CONFIG_PM=y
 # CONFIG_PREEMPT is not set
@@ -168,6 +178,7 @@
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
 # CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -200,13 +211,15 @@
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
 CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
 CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ROM=y
 # CONFIG_MTD_ABSENT is not set
 # CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_XIP is not set
 
 #
 # Mapping drivers for chip access
@@ -226,6 +239,7 @@
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
 # CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
 
 #
 # Disk-On-Chip Device Drivers
@@ -244,6 +258,7 @@
 # CONFIG_MTD_NAND_S3C2410_DEBUG is not set
 # CONFIG_MTD_NAND_S3C2410_HWECC is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
 
 #
 # Plug and Play support
@@ -254,10 +269,12 @@
 #
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
@@ -270,6 +287,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # Multi-device support (RAID and LVM)
@@ -456,6 +474,7 @@
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PARKBD is not set
+CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 
 #
@@ -489,6 +508,7 @@
 # CONFIG_DIGI is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
@@ -583,6 +603,7 @@
 CONFIG_I2C_SENSOR=m
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 is not set
@@ -600,6 +621,7 @@
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
@@ -693,6 +715,7 @@
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 # CONFIG_JFFS2_FS_NAND is not set
+# CONFIG_JFFS2_FS_NOR_ECC is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -812,6 +835,7 @@
 # Logo configuration
 #
 # CONFIG_LOGO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -830,6 +854,10 @@
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -848,8 +876,9 @@
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
 CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_WAITQ is not set
@@ -869,6 +898,10 @@
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
 
 #
 # Library routines
diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
--- a/arch/arm/kernel/irq.c	2005-01-19 13:44:45 -08:00
+++ b/arch/arm/kernel/irq.c	2005-01-19 13:44:45 -08:00
@@ -32,6 +32,7 @@
 #include <linux/errno.h>
 #include <linux/list.h>
 #include <linux/kallsyms.h>
+#include <linux/proc_fs.h>
 
 #include <asm/irq.h>
 #include <asm/system.h>
@@ -85,6 +86,23 @@
 	.disable_depth	= 1,
 };
 
+#ifdef CONFIG_SMP
+void synchronize_irq(unsigned int irq)
+{
+	struct irqdesc *desc = irq_desc + irq;
+
+	while (desc->running)
+		barrier();
+}
+EXPORT_SYMBOL(synchronize_irq);
+
+#define smp_set_running(desc)	do { desc->running = 1; } while (0)
+#define smp_clear_running(desc)	do { desc->running = 0; } while (0)
+#else
+#define smp_set_running(desc)	do { } while (0)
+#define smp_clear_running(desc)	do { } while (0)
+#endif
+
 /**
  *	disable_irq_nosync - disable an irq without waiting
  *	@irq: Interrupt to disable
@@ -232,6 +250,9 @@
 #ifdef CONFIG_ARCH_ACORN
 		show_fiq_list(p, v);
 #endif
+#ifdef CONFIG_SMP
+		show_ipi_list(p);
+#endif
 		seq_printf(p, "Err: %10lu\n", irq_err_count);
 	}
 	return 0;
@@ -329,18 +350,22 @@
 do_simple_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 {
 	struct irqaction *action;
-	const int cpu = smp_processor_id();
+	const unsigned int cpu = smp_processor_id();
 
 	desc->triggered = 1;
 
 	kstat_cpu(cpu).irqs[irq]++;
 
+	smp_set_running(desc);
+
 	action = desc->action;
 	if (action) {
 		int ret = __do_irq(irq, action, regs);
 		if (ret != IRQ_HANDLED)
 			report_bad_irq(irq, regs, desc, ret);
 	}
+
+	smp_clear_running(desc);
 }
 
 /*
@@ -350,7 +375,7 @@
 void
 do_edge_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 {
-	const int cpu = smp_processor_id();
+	const unsigned int cpu = smp_processor_id();
 
 	desc->triggered = 1;
 
@@ -414,7 +439,7 @@
 do_level_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
 {
 	struct irqaction *action;
-	const int cpu = smp_processor_id();
+	const unsigned int cpu = smp_processor_id();
 
 	desc->triggered = 1;
 
@@ -426,6 +451,8 @@
 	if (likely(!desc->disable_depth)) {
 		kstat_cpu(cpu).irqs[irq]++;
 
+		smp_set_running(desc);
+
 		/*
 		 * Return with this interrupt masked if no action
 		 */
@@ -440,6 +467,8 @@
 				   !check_irq_lock(desc, irq, regs)))
 				desc->chip->unmask(irq);
 		}
+
+		smp_clear_running(desc);
 	}
 }
 
@@ -878,8 +907,97 @@
 
 EXPORT_SYMBOL(probe_irq_off);
 
+#ifdef CONFIG_SMP
+static void route_irq(struct irqdesc *desc, unsigned int irq, unsigned int cpu)
+{
+	pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->cpu, cpu);
+
+	spin_lock_irq(&irq_controller_lock);
+	desc->cpu = cpu;
+	desc->chip->set_cpu(desc, irq, cpu);
+	spin_unlock_irq(&irq_controller_lock);
+}
+
+#ifdef CONFIG_PROC_FS
+static int
+irq_affinity_read_proc(char *page, char **start, off_t off, int count,
+		       int *eof, void *data)
+{
+	struct irqdesc *desc = irq_desc + ((int)data);
+	int len = cpumask_scnprintf(page, count, desc->affinity);
+
+	if (count - len < 2)
+		return -EINVAL;
+	page[len++] = '\n';
+	page[len] = '\0';
+
+	return len;
+}
+
+static int
+irq_affinity_write_proc(struct file *file, const char __user *buffer,
+			unsigned long count, void *data)
+{
+	unsigned int irq = (unsigned int)data;
+	struct irqdesc *desc = irq_desc + irq;
+	cpumask_t affinity, tmp;
+	int ret = -EIO;
+
+	if (!desc->chip->set_cpu)
+		goto out;
+
+	ret = cpumask_parse(buffer, count, affinity);
+	if (ret)
+		goto out;
+
+	cpus_and(tmp, affinity, cpu_online_map);
+	if (cpus_empty(tmp)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	desc->affinity = affinity;
+	route_irq(desc, irq, first_cpu(tmp));
+	ret = count;
+
+ out:
+	return ret;
+}
+#endif
+#endif
+
 void __init init_irq_proc(void)
 {
+#if defined(CONFIG_SMP) && defined(CONFIG_PROC_FS)
+	struct proc_dir_entry *dir;
+	int irq;
+
+	dir = proc_mkdir("irq", 0);
+	if (!dir)
+		return;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		struct proc_dir_entry *entry;
+		struct irqdesc *desc;
+		char name[16];
+
+		desc = irq_desc + irq;
+		memset(name, 0, sizeof(name));
+		snprintf(name, sizeof(name) - 1, "%u", irq);
+
+		desc->procdir = proc_mkdir(name, dir);
+		if (!desc->procdir)
+			continue;
+
+		entry = create_proc_entry("smp_affinity", 0600, desc->procdir);
+		if (entry) {
+			entry->nlink = 1;
+			entry->data = (void *)irq;
+			entry->read_proc = irq_affinity_read_proc;
+			entry->write_proc = irq_affinity_write_proc;
+		}
+	}
+#endif
 }
 
 void __init init_IRQ(void)
@@ -887,6 +1005,11 @@
 	struct irqdesc *desc;
 	extern void init_dma(void);
 	int irq;
+
+#ifdef CONFIG_SMP
+	bad_irq_desc.affinity = CPU_MASK_ALL;
+	bad_irq_desc.cpu = smp_processor_id();
+#endif
 
 	for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {
 		*desc = bad_irq_desc;
diff -Nru a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
--- a/arch/arm/kernel/semaphore.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/kernel/semaphore.c	2005-01-19 13:44:46 -08:00
@@ -178,7 +178,7 @@
  * registers (r0 to r3 and lr), but not ip, as we use it as a return
  * value in some cases..
  */
-asm("	.section .sched.text			\n\
+asm("	.section .sched.text,\"ax\"		\n\
 	.align	5				\n\
 	.globl	__down_failed			\n\
 __down_failed:					\n\
diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
--- a/arch/arm/kernel/signal.c	2005-01-19 13:44:45 -08:00
+++ b/arch/arm/kernel/signal.c	2005-01-19 13:44:45 -08:00
@@ -12,7 +12,6 @@
 #include <linux/signal.h>
 #include <linux/ptrace.h>
 #include <linux/personality.h>
-#include <linux/suspend.h>
 
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
@@ -689,10 +688,8 @@
 	if (!user_mode(regs))
 		return 0;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (current->ptrace & PT_SINGLESTEP)
 		ptrace_cancel_bpt(current);
diff -Nru a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
--- a/arch/arm/kernel/smp.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/kernel/smp.c	2005-01-19 13:44:46 -08:00
@@ -17,16 +17,16 @@
 #include <linux/profile.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
 #include <linux/seq_file.h>
 
 #include <asm/atomic.h>
+#include <asm/cacheflush.h>
 #include <asm/cpu.h>
 #include <asm/processor.h>
-#include <asm/smp.h>
-#include <asm/ptrace.h>
-
-#include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
+#include <asm/ptrace.h>
 
 /*
  * bitmask of present and online CPUs.
@@ -42,6 +42,7 @@
  */
 struct ipi_data {
 	spinlock_t lock;
+	unsigned long ipi_count;
 	unsigned long bits;
 };
 
@@ -242,12 +243,12 @@
 
 void show_ipi_list(struct seq_file *p)
 {
-	int cpu;
+	unsigned int cpu;
 
-	seq_printf(p, "IPI: ");
+	seq_puts(p, "IPI:");
 
 	for_each_online_cpu(cpu)
-		seq_printf(p, "%10lu ", per_cpu(cpu_data, cpu).ipi_count);
+		seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count);
 
 	seq_putc(p, '\n');
 }
@@ -316,12 +317,11 @@
 void do_IPI(unsigned int ipimask, struct pt_regs *regs)
 {
 	unsigned int cpu = smp_processor_id();
+	struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
 
-	per_cpu(cpu_data, cpu).ipi_count++;
+	ipi->ipi_count++;
 
 	if (ipimask & (1 << 0)) {
-		struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
-
 		for (;;) {
 			unsigned long msgs;
 
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/kernel/time.c	2005-01-19 13:44:47 -08:00
@@ -63,7 +63,7 @@
 	unsigned long fp, pc = instruction_pointer(regs);
 
 	if (in_lock_functions(pc)) {
-		fp = thread_saved_fp(current);
+		fp = regs->ARM_fp;
 		pc = pc_pointer(((unsigned long *)fp)[-1]);
 	}
 
diff -Nru a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib/io-readsw-armv4.S
--- a/arch/arm/lib/io-readsw-armv4.S	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/lib/io-readsw-armv4.S	2005-01-19 13:44:47 -08:00
@@ -18,25 +18,14 @@
 #endif
 		.endm
 
-.insw_bad_alignment:
-		adr	r0, .insw_bad_align_msg
-		mov	r2, lr
-		b	panic
-.insw_bad_align_msg:
-		.asciz	"insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
-		.align
-
-.insw_align:	tst	r1, #1
-		bne	.insw_bad_alignment
-
-		ldrh	r3, [r0]
-		strh	r3, [r1], #2
-
-		subs	r2, r2, #1
-		RETINSTR(moveq, pc, lr)
+.insw_align:	movs	ip, r1, lsl #31
+		bne	.insw_noalign
+		ldrh	ip, [r0]
+		sub	r2, r2, #1
+		strh	ip, [r1], #2
 
 ENTRY(__raw_readsw)
-		teq	r2, #0		@ do we have to check for the zero len?
+		teq	r2, #0
 		moveq	pc, lr
 		tst	r1, #3
 		bne	.insw_align
@@ -62,14 +51,10 @@
 		ldrh	lr, [r0]
 		pack	ip, ip, lr
 
-		stmia	r1!, {r3 - r5, ip}
-
 		subs	r2, r2, #8
+		stmia	r1!, {r3 - r5, ip}
 		bpl	.insw_8_lp
 
-		tst	r2, #7
-		LOADREGS(eqfd, sp!, {r4, r5, pc})
-
 .no_insw_8:	tst	r2, #4
 		beq	.no_insw_4
 
@@ -83,17 +68,63 @@
 
 		stmia	r1!, {r3, r4}
 
-.no_insw_4:	tst	r2, #2
-		beq	.no_insw_2
+.no_insw_4:	movs	r2, r2, lsl #31
+		bcc	.no_insw_2
 
 		ldrh	r3, [r0]
 		ldrh	ip, [r0]
 		pack	r3, r3, ip
-
 		str	r3, [r1], #4
 
-.no_insw_2:	tst	r2, #1
-		ldrneh	r3, [r0]
+.no_insw_2:	ldrneh	r3, [r0]
 		strneh	r3, [r1]
 
-		LOADREGS(fd, sp!, {r4, r5, pc})
+		ldmfd	sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define _BE_ONLY_(code...)	code
+#define _LE_ONLY_(code...)
+#define push_hbyte0		lsr #8
+#define pull_hbyte1		lsl #24
+#else
+#define _BE_ONLY_(code...)
+#define _LE_ONLY_(code...) code
+#define push_hbyte0		lsl #24
+#define pull_hbyte1		lsr #8
+#endif
+
+.insw_noalign:	stmfd	sp!, {r4, lr}
+		ldrccb	ip, [r1, #-1]!
+		bcc	1f
+
+		ldrh	ip, [r0]
+		sub	r2, r2, #1
+   _BE_ONLY_(	mov	ip, ip, ror #8		)
+		strb	ip, [r1], #1
+   _LE_ONLY_(	mov	ip, ip, lsr #8		)
+   _BE_ONLY_(	mov	ip, ip, lsr #24		)
+
+1:		subs	r2, r2, #2
+		bmi	3f
+   _BE_ONLY_(	mov	ip, ip, lsl #24		)
+
+2:		ldrh	r3, [r0]
+		ldrh	r4, [r0]
+		subs	r2, r2, #2
+		orr	ip, ip, r3, lsl #8
+		orr	ip, ip, r4, push_hbyte0
+		str	ip, [r1], #4
+		mov	ip, r4, pull_hbyte1
+		bpl	2b
+
+   _BE_ONLY_(	mov	ip, ip, lsr #24		)
+
+3:		tst	r2, #1
+		strb	ip, [r1], #1
+		ldrneh	ip, [r0]
+   _BE_ONLY_(	movne	ip, ip, ror #8		)
+		strneb	ip, [r1], #1
+   _LE_ONLY_(	movne	ip, ip, lsr #8		)
+   _BE_ONLY_(	movne	ip, ip, lsr #24		)
+		strneb	ip, [r1]
+		ldmfd	sp!, {r4, pc}
diff -Nru a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
--- a/arch/arm/lib/io-writesw-armv4.S	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/lib/io-writesw-armv4.S	2005-01-19 13:44:47 -08:00
@@ -22,27 +22,17 @@
 #endif
 		.endm
 
-.outsw_bad_alignment:
-		adr	r0, .outsw_bad_align_msg
-		mov	r2, lr
-		b	panic
-.outsw_bad_align_msg:
-		.asciz	"outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
-		.align
-
-.outsw_align:	tst	r1, #1
-		bne	.outsw_bad_alignment
+.outsw_align:	movs	ip, r1, lsl #31
+		bne	.outsw_noalign
 
 		ldrh	r3, [r1], #2
+		sub	r2, r2, #1
 		strh	r3, [r0]
 
-		subs	r2, r2, #1
-		RETINSTR(moveq, pc, lr)
-
 ENTRY(__raw_writesw)
-		teq	r2, #0		@ do we have to check for the zero len?
+		teq	r2, #0
 		moveq	pc, lr
-		tst	r1, #3
+		ands	r3, r1, #3
 		bne	.outsw_align
 
 		stmfd	sp!, {r4, r5, lr}
@@ -51,16 +41,13 @@
 		bmi	.no_outsw_8
 
 .outsw_8_lp:	ldmia	r1!, {r3, r4, r5, ip}
+		subs	r2, r2, #8
 		outword	r3
 		outword	r4
 		outword	r5
 		outword	ip
-		subs	r2, r2, #8
 		bpl	.outsw_8_lp
 
-		tst	r2, #7
-		LOADREGS(eqfd, sp!, {r4, r5, pc})
-
 .no_outsw_8:	tst	r2, #4
 		beq	.no_outsw_4
 
@@ -68,14 +55,41 @@
 		outword	r3
 		outword	ip
 
-.no_outsw_4:	tst	r2, #2
-		beq	.no_outsw_2
+.no_outsw_4:	movs	r2, r2, lsl #31
+		bcc	.no_outsw_2
 
 		ldr	r3, [r1], #4
 		outword	r3
 
-.no_outsw_2:	tst	r2, #1
-		ldrneh	r3, [r1]
+.no_outsw_2:	ldrneh	r3, [r1]
 		strneh	r3, [r0]
 
-		LOADREGS(fd, sp!, {r4, r5, pc})
+		ldmfd	sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define pull_hbyte0	lsl #8
+#define push_hbyte1	lsr #24
+#else
+#define pull_hbyte0	lsr #24
+#define push_hbyte1	lsl #8
+#endif
+
+.outsw_noalign:	ldr	r3, [r1, -r3]!
+		subcs	r2, r2, #1
+		bcs	2f
+		subs	r2, r2, #2
+		bmi	3f
+
+1:		mov	ip, r3, lsr #8
+		strh	ip, [r0]
+2:		mov	ip, r3, pull_hbyte0
+		ldr	r3, [r1, #4]!
+		subs	r2, r2, #2
+		orr	ip, ip, r3, push_hbyte1
+		strh	ip, [r0]
+		bpl	2b
+
+3:		tst	r2, #1
+2:		movne	ip, r3, lsr #8
+		strneh	ip, [r0]
+		mov	pc, lr
diff -Nru a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
--- a/arch/arm/mach-footbridge/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mach-footbridge/Kconfig	2005-01-19 13:44:47 -08:00
@@ -26,7 +26,7 @@
 	  <http://www.crl.hpl.hp.com/projects/personalserver/>
 
 	  If you have any questions or comments about the  Compaq Personal
-	  Server, send e-mail to skiff@crl.dec.com.
+	  Server, send e-mail to <skiff@crl.dec.com>.
 
 config ARCH_EBSA285_ADDIN
 	bool "EBSA285 (addin mode)"
diff -Nru a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig
--- a/arch/arm/mach-ixp2000/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mach-ixp2000/Kconfig	2005-01-19 13:44:47 -08:00
@@ -14,21 +14,21 @@
 	help
 	  Say 'Y' here if you want your kernel to support the Radisys
 	  ENP2611 PCI network processing card. For more information on
-	  this card, see Documentation/arm/ENP2611.
+	  this card, see <file:Documentation/arm/ENP2611>.
 
 config ARCH_IXDP2400
 	bool "Support Intel IXDP2400"
 	help
 	  Say 'Y' here if you want your kernel to support the Intel
 	  IXDP2400 reference platform. For more information on
-	  this platform, see Documentation/arm/IXP2000.
+	  this platform, see <file:Documentation/arm/IXP2000>.
 
 config ARCH_IXDP2800
 	bool "Support Intel IXDP2800"
 	help
 	  Say 'Y' here if you want your kernel to support the Intel
 	  IXDP2800 reference platform. For more information on
-	  this platform, see Documentation/arm/IXP2000.
+	  this platform, see <file:Documentation/arm/IXP2000>.
 
 config ARCH_IXDP2X00
 	bool
@@ -40,14 +40,14 @@
 	help
 	  Say 'Y' here if you want your kernel to support the Intel
 	  IXDP2401 reference platform. For more information on
-	  this platform, see Documentation/arm/IXP2000.
+	  this platform, see <file:Documentation/arm/IXP2000>.
 
 config ARCH_IXDP2801
 	bool "Support Intel IXDP2801"
 	help
 	  Say 'Y' here if you want your kernel to support the Intel
 	  IXDP2801 reference platform. For more information on
-	  this platform, see Documentation/arm/IXP2000.
+	  this platform, see <file:Documentation/arm/IXP2000>.
 
 config ARCH_IXDP2X01
 	bool
diff -Nru a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
--- a/arch/arm/mach-ixp2000/core.c	2005-01-19 13:44:48 -08:00
+++ b/arch/arm/mach-ixp2000/core.c	2005-01-19 13:44:48 -08:00
@@ -171,22 +171,9 @@
 
 unsigned long ixp2000_gettimeoffset (void)
 {
- 	unsigned long elapsed1, elapsed2, pending;
  	unsigned long offset;
 
-	elapsed1 = *IXP2000_T1_CSR;
- 	pending = (*IXP2000_IRQ_STATUS & IRQ_MASK_TIMER1);
- 	elapsed2 = *IXP2000_T1_CSR;
-
- 	offset = ticks_per_jiffy - elapsed2;
-
- 	/*
- 	 * We have two cases to cover, one where we were pending
-   	 * already, and another where it overflowed while we were
-   	 * checking the timers.
-   	 */
- 	if ((elapsed2 > elapsed1) || pending)
- 		offset += ticks_per_jiffy;
+	offset = next_jiffy_time - *IXP2000_T4_CSR;
 
 	return offset / ticks_per_usec;
 }
diff -Nru a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
--- a/arch/arm/mach-ixp4xx/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-ixp4xx/Kconfig	2005-01-19 13:44:46 -08:00
@@ -13,28 +13,28 @@
 	help
 	  Say 'Y' here if you want your kernel to support the Gateworks
 	  Avila Network Platform. For more information on this platform,
-	  see Documentation/arm/IXP4xx.
+	  see <file:Documentation/arm/IXP4xx>.
 
 config ARCH_ADI_COYOTE
 	bool "Coyote"
 	help
 	  Say 'Y' here if you want your kernel to support the ADI 
 	  Engineering Coyote Gateway Reference Platform. For more
-	  information on this platform, see Documentation/arm/IXP4xx.
+	  information on this platform, see <file:Documentation/arm/IXP4xx>.
 
 config ARCH_IXDP425
 	bool "IXDP425"
 	help
 	  Say 'Y' here if you want your kernel to support Intel's 
 	  IXDP425 Development Platform (Also known as Richfield).  
-	  For more information on this platform, see Documentation/arm/IXP4xx.
+	  For more information on this platform, see <file:Documentation/arm/IXP4xx>.
 
 config MACH_IXDPG425
 	bool "IXDPG425"
 	help
 	  Say 'Y' here if you want your kernel to support Intel's
 	  IXDPG425 Development Platform (Also known as Montajade).
-	  For more information on this platform, see Documentation/arm/IXP4xx.
+	  For more information on this platform, see <file:Documentation/arm/IXP4xx>.
 
 config MACH_IXDP465
 	bool "IXDP465"
@@ -59,7 +59,7 @@
 	help
 	  Say 'Y' here if you want your kernel to support the Motorola
 	  PrPCM1100 Processor Mezanine Module. For more information on
-	  this platform, see Documentation/arm/IXP4xx.
+	  this platform, see <file:Documentation/arm/IXP4xx>.
 
 #
 # Avila and IXDP share the same source for now. Will change in future
@@ -87,7 +87,7 @@
           1) A direct mapped window from 0x48000000 to 0x4bffffff (64MB).
              To access PCI via this space, we simply ioremap() the BAR
              into the kernel and we can use the standard read[bwl]/write[bwl]
-             macros. This is the preffered method due to speed but it
+             macros. This is the preferred method due to speed but it
              limits the system to just 64MB of PCI memory. This can be 
              problamatic if using video cards and other memory-heavy devices.
           
diff -Nru a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
--- a/arch/arm/mach-ixp4xx/coyote-pci.c	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c	2005-01-19 13:44:47 -08:00
@@ -14,6 +14,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 
diff -Nru a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
--- a/arch/arm/mach-ixp4xx/coyote-setup.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c	2005-01-19 13:44:46 -08:00
@@ -8,6 +8,7 @@
  * Author: Deepak Saxena <dsaxena@plexity.net>
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial.h>
diff -Nru a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c	2005-01-19 13:44:46 -08:00
@@ -14,6 +14,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -Nru a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c	2005-01-19 13:44:46 -08:00
@@ -8,6 +8,7 @@
  * Author: Deepak Saxena <dsaxena@plexity.net>
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial.h>
diff -Nru a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
--- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c	2005-01-19 13:44:46 -08:00
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 
diff -Nru a/arch/arm/mach-ixp4xx/prpmc1100-pci.c b/arch/arm/mach-ixp4xx/prpmc1100-pci.c
--- a/arch/arm/mach-ixp4xx/prpmc1100-pci.c	2005-01-19 13:44:45 -08:00
+++ b/arch/arm/mach-ixp4xx/prpmc1100-pci.c	2005-01-19 13:44:45 -08:00
@@ -19,6 +19,7 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/pci.h>
 #include <linux/init.h>
diff -Nru a/arch/arm/mach-ixp4xx/prpmc1100-setup.c b/arch/arm/mach-ixp4xx/prpmc1100-setup.c
--- a/arch/arm/mach-ixp4xx/prpmc1100-setup.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-ixp4xx/prpmc1100-setup.c	2005-01-19 13:44:46 -08:00
@@ -8,6 +8,7 @@
  * Author: Deepak Saxena <dsaxena@plexity.net>
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/serial.h>
diff -Nru a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
--- a/arch/arm/mach-pxa/Makefile	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-pxa/Makefile	2005-01-19 13:44:46 -08:00
@@ -11,7 +11,7 @@
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-obj-$(CONFIG_PXA_SHARPSL)	+= corgi.o
+obj-$(CONFIG_PXA_SHARPSL)	+= corgi.o corgi_ssp.o ssp.o
 
 # Support for blinky lights
 led-y := leds.o
diff -Nru a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
--- a/arch/arm/mach-pxa/corgi.c	2005-01-19 13:44:45 -08:00
+++ b/arch/arm/mach-pxa/corgi.c	2005-01-19 13:44:45 -08:00
@@ -18,6 +18,7 @@
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
+#include <linux/mmc/host.h>
 
 #include <asm/setup.h>
 #include <asm/memory.h>
@@ -32,19 +33,18 @@
 
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/irq.h>
+#include <asm/arch/mmc.h>
 #include <asm/arch/corgi.h>
 
 #include <asm/hardware/scoop.h>
+#include <video/w100fb.h>
 
 #include "generic.h"
 
-extern void corgi_ssp_lcdtg_send (u8 adrs, u8 data);
-
-static void __init corgi_init_irq(void)
-{
-	pxa_init_irq();
-}
 
+/*
+ * Corgi SCOOP Device
+ */
 static struct resource corgi_scoop_resources[] = {
 	[0] = {
 		.start		= 0x10800000,
@@ -68,13 +68,139 @@
 	.resource	= corgi_scoop_resources,
 };
 
+
+/*
+ * Corgi SSP Device
+ *
+ * Set the parent as the scoop device because a lot of SSP devices
+ * also use scoop functions and this makes the power up/down order
+ * work correctly.
+ */
+extern void corgi_ssp_lcdtg_send (u8 adrs, u8 data);
+
+static struct platform_device corgissp_device = {
+	.name		= "corgi-ssp",
+	.dev		= {
+ 		.parent = &corgiscoop_device.dev,
+	},
+	.id		= -1,
+};
+
+
+/*
+ * Corgi w100 Frame Buffer Device
+ */
+static struct w100fb_mach_info corgi_fb_info = {
+	.w100fb_ssp_send 	= corgi_ssp_lcdtg_send,
+	.comadj 			= -1,
+	.phadadj 			= -1,
+};
+
+static struct resource corgi_fb_resources[] = {
+	[0] = {
+		.start		= 0x08000000,
+		.end		= 0x08ffffff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device corgifb_device = {
+	.name		= "w100fb",
+	.id		= -1,
+	.dev		= {
+ 		.platform_data	= &corgi_fb_info,
+ 		.parent = &corgissp_device.dev,
+	},
+	.num_resources	= ARRAY_SIZE(corgi_fb_resources),
+	.resource	= corgi_fb_resources,
+};
+
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by HZ/4
+ * to give the card a chance to fully insert/eject.
+ */
+static struct mmc_detect {
+	struct timer_list detect_timer;
+	void *devid;
+} mmc_detect;
+
+static void mmc_detect_callback(unsigned long data)
+{
+	mmc_detect_change(mmc_detect.devid);
+}
+
+static irqreturn_t corgi_mmc_detect_int(int irq, void *devid, struct pt_regs *regs)
+{
+	mmc_detect.devid=devid;
+	mod_timer(&mmc_detect.detect_timer, jiffies + HZ/4);
+	return IRQ_HANDLED;
+}
+
+static int corgi_mci_init(struct device *dev, irqreturn_t (*unused_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	int err;
+
+	/* setup GPIO for PXA25x MMC controller	*/
+	pxa_gpio_mode(GPIO6_MMCCLK_MD);
+	pxa_gpio_mode(GPIO8_MMCCS0_MD);
+	pxa_gpio_mode(CORGI_GPIO_nSD_DETECT | GPIO_IN);
+	pxa_gpio_mode(CORGI_GPIO_SD_PWR | GPIO_OUT);
+
+	err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_mmc_detect_int, SA_INTERRUPT,
+			     "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+		return -1;
+	}
+
+	init_timer(&mmc_detect.detect_timer);
+	mmc_detect.detect_timer.function = mmc_detect_callback;
+	mmc_detect.detect_timer.data = (unsigned long) &mmc_detect;
+
+	set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
+
+	return 0;
+}
+
+static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	if (( 1 << vdd) & p_d->ocr_mask) {
+		printk(KERN_DEBUG "%s: on\n", __FUNCTION__);
+		GPSR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
+	} else {
+		printk(KERN_DEBUG "%s: off\n", __FUNCTION__);
+		GPCR1 = GPIO_bit(CORGI_GPIO_SD_PWR);
+	}
+}
+
+static void corgi_mci_exit(struct device *dev, void *data)
+{
+	free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
+	del_timer(&mmc_detect.detect_timer);
+}
+
+static struct pxamci_platform_data corgi_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= corgi_mci_init,
+	.setpower 	= corgi_mci_setpower,
+	.exit		= corgi_mci_exit,
+};
+
+
 static struct platform_device *devices[] __initdata = {
 	&corgiscoop_device,
+	&corgissp_device,
+	&corgifb_device,
 };
 
 static struct sharpsl_flash_param_info sharpsl_flash_param;
 
-void corgi_get_param(void)
+static void corgi_get_param(void)
 {
 	sharpsl_flash_param.comadj_keyword = readl(FLASH_MEM_BASE + FLASH_COMADJ_MAGIC_ADR);
 	sharpsl_flash_param.comadj = readl(FLASH_MEM_BASE + FLASH_COMADJ_DATA_ADR);
@@ -85,6 +211,18 @@
 
 static void __init corgi_init(void)
 {
+	if (sharpsl_flash_param.comadj_keyword == FLASH_COMADJ_MAJIC)
+		corgi_fb_info.comadj=sharpsl_flash_param.comadj;
+	else
+		corgi_fb_info.comadj=-1;
+
+	if (sharpsl_flash_param.phad_keyword == FLASH_PHAD_MAJIC)
+		corgi_fb_info.phadadj=sharpsl_flash_param.phadadj;
+	else
+		corgi_fb_info.phadadj=-1;
+
+	pxa_set_mci_info(&corgi_mci_platform_data);
+
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
@@ -99,6 +237,11 @@
 		mi->bank[0].size = (32*1024*1024);
 	else
 		mi->bank[0].size = (64*1024*1024);
+}
+
+static void __init corgi_init_irq(void)
+{
+	pxa_init_irq();
 }
 
 static struct map_desc corgi_io_desc[] __initdata = {
diff -Nru a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/arm/mach-pxa/corgi_ssp.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,247 @@
+/*
+ *  SSP control code for Sharp Corgi devices
+ *
+ *  Copyright (c) 2004 Richard Purdie
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/ssp.h>
+#include <asm/arch/corgi.h>
+#include <asm/arch/pxa-regs.h>
+
+static spinlock_t corgi_ssp_lock = SPIN_LOCK_UNLOCKED;
+static struct ssp_dev corgi_ssp_dev;
+static struct ssp_state corgi_ssp_state;
+
+/*
+ * There are three devices connected to the SSP interface:
+ *   1. A touchscreen controller (TI ADS7846 compatible)
+ *   2. An LCD contoller (with some Backlight functionality)
+ *   3. A battery moinitoring IC (Maxim MAX1111)
+ *
+ * Each device uses a different speed/mode of communication.
+ *
+ * The touchscreen is very sensitive and the most frequently used
+ * so the port is left configured for this.
+ *
+ * Devices are selected using Chip Selects on GPIOs.
+ */
+
+/*
+ *  ADS7846 Routines
+ */
+unsigned long corgi_ssp_ads7846_putget(ulong data)
+{
+	unsigned long ret,flag;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+
+	ssp_write_word(&corgi_ssp_dev,data);
+	ret = ssp_read_word(&corgi_ssp_dev);
+
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	return ret;
+}
+
+/*
+ * NOTE: These functions should always be called in interrupt context
+ * and use the _lock and _unlock functions. They are very time sensitive.
+ */
+void corgi_ssp_ads7846_lock(void)
+{
+	spin_lock(&corgi_ssp_lock);
+	GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+}
+
+void corgi_ssp_ads7846_unlock(void)
+{
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	spin_unlock(&corgi_ssp_lock);
+}
+
+void corgi_ssp_ads7846_put(ulong data)
+{
+	ssp_write_word(&corgi_ssp_dev,data);
+}
+
+unsigned long corgi_ssp_ads7846_get(void)
+{
+	return ssp_read_word(&corgi_ssp_dev);
+}
+
+EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
+EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
+EXPORT_SYMBOL(corgi_ssp_ads7846_put);
+EXPORT_SYMBOL(corgi_ssp_ads7846_get);
+
+
+/*
+ *  LCD/Backlight Routines
+ */
+unsigned long corgi_ssp_dac_put(ulong data)
+{
+	unsigned long flag;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76));
+	ssp_enable(&corgi_ssp_dev);
+
+	ssp_write_word(&corgi_ssp_dev,data);
+	/* Read null data back from device to prevent SSP overflow */
+	ssp_read_word(&corgi_ssp_dev);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+	ssp_enable(&corgi_ssp_dev);
+	GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	return 0;
+}
+
+void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
+{
+	corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
+}
+
+void corgi_ssp_blduty_set(int duty)
+{
+	corgi_ssp_lcdtg_send(0x02,duty);
+}
+
+EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
+EXPORT_SYMBOL(corgi_ssp_blduty_set);
+
+/*
+ *  Max1111 Routines
+ */
+int corgi_ssp_max1111_get(ulong data)
+{
+	unsigned long flag;
+	int voltage,voltage1,voltage2;
+
+	spin_lock_irqsave(&corgi_ssp_lock, flag);
+	GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(8));
+	ssp_enable(&corgi_ssp_dev);
+
+	udelay(1);
+
+	/* TB1/RB1 */
+	ssp_write_word(&corgi_ssp_dev,data);
+	ssp_read_word(&corgi_ssp_dev); /* null read */
+
+	/* TB12/RB2 */
+	ssp_write_word(&corgi_ssp_dev,0);
+	voltage1=ssp_read_word(&corgi_ssp_dev);
+
+	/* TB13/RB3*/
+	ssp_write_word(&corgi_ssp_dev,0);
+	voltage2=ssp_read_word(&corgi_ssp_dev);
+
+	ssp_disable(&corgi_ssp_dev);
+	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+	ssp_enable(&corgi_ssp_dev);
+	GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
+
+	if (voltage1 & 0xc0 || voltage2 & 0x3f)
+		voltage = -1;
+	else
+		voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
+
+	return voltage;
+}
+
+EXPORT_SYMBOL(corgi_ssp_max1111_get);
+
+/*
+ *  Support Routines
+ */
+int __init corgi_ssp_probe(struct device *dev)
+{
+	int ret;
+
+	/* Chip Select - Disable All */
+	GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);  /* High - Disable LCD Control/Timing Gen */
+	GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);  /* High - Disable MAX1111*/
+	GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS);  /* output */
+	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);   /* High - Disable ADS7846*/
+
+	ret=ssp_init(&corgi_ssp_dev,1);
+
+	if (ret)
+		printk(KERN_ERR "Unable to register SSP handler!\n");
+	else {
+		ssp_disable(&corgi_ssp_dev);
+		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+		ssp_enable(&corgi_ssp_dev);
+	}
+
+	return ret;
+}
+
+static int corgi_ssp_remove(struct device *dev)
+{
+	ssp_exit(&corgi_ssp_dev);
+	return 0;
+}
+
+static int corgi_ssp_suspend(struct device *dev, u32 state, u32 level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+		ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
+	}
+	return 0;
+}
+
+static int corgi_ssp_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON) {
+		GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);  /* High - Disable LCD Control/Timing Gen */
+		GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/
+		GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/
+		ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
+		ssp_enable(&corgi_ssp_dev);
+	}
+	return 0;
+}
+
+static struct device_driver corgissp_driver = {
+	.name		= "corgi-ssp",
+	.bus		= &platform_bus_type,
+	.probe		= corgi_ssp_probe,
+	.remove		= corgi_ssp_remove,
+	.suspend	= corgi_ssp_suspend,
+	.resume		= corgi_ssp_resume,
+};
+
+int __init corgi_ssp_init(void)
+{
+	return driver_register(&corgissp_driver);
+}
+
+arch_initcall(corgi_ssp_init);
diff -Nru a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
--- a/arch/arm/mach-s3c2410/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/Kconfig	2005-01-19 13:44:46 -08:00
@@ -41,7 +41,7 @@
 	help
 	  Say Y here if you are using the HP iPAQ rx3715.
 
-	  See http://www.handhelds.org/projects/rx3715.html for more
+	  See <http://www.handhelds.org/projects/rx3715.html> for more
 	  information on this project
 
 endmenu
@@ -77,7 +77,7 @@
 	  to the kernel log, at priority KERN_DEBUG.
 
 	  Note, it is easy to create and fill the log buffer in a small
-	  amount of time, as well as using an significant percantage of
+	  amount of time, as well as using an significant percentage of
 	  the CPU time doing so.
 
 
@@ -115,9 +115,9 @@
 	  Choice of which UART port to use for the low-level messages,
 	  such as the `Uncompressing...` at start time. The value of
 	  this configuration should be between zero and two. The port
-	  must have been initalised by the boot-loader before use.
+	  must have been initialised by the boot-loader before use.
 
 	  Note, this does not affect the port used by the debug messages,
-	  which is a seperate configuration.
+	  which is a separate configuration.
 
 endif
diff -Nru a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
--- a/arch/arm/mach-s3c2410/clock.c	2005-01-19 13:44:45 -08:00
+++ b/arch/arm/mach-s3c2410/clock.c	2005-01-19 13:44:45 -08:00
@@ -60,7 +60,7 @@
 
 /* old functions */
 
-void inline s3c2410_clk_enable(unsigned int clocks, unsigned int enable)
+void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
 {
 	unsigned long clkcon;
 	unsigned long flags;
@@ -88,9 +88,9 @@
 	return 0;
 }
 
-int s3c2410_clkcon_enable(struct clk *clk, int enable)
+int s3c24xx_clkcon_enable(struct clk *clk, int enable)
 {
-	s3c2410_clk_enable(clk->ctrlbit, enable);
+	s3c24xx_clk_enable(clk->ctrlbit, enable);
 	return 0;
 }
 
@@ -264,90 +264,90 @@
 	{ .name    = "nand",
 	  .id	   = -1,
 	  .parent  = &clk_h,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_NAND
 	},
 	{ .name    = "lcd",
 	  .id	   = -1,
 	  .parent  = &clk_h,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_LCDC
 	},
 	{ .name    = "usb-host",
 	  .id	   = -1,
 	  .parent  = &clk_h,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_USBH
 	},
 	{ .name    = "usb-device",
 	  .id	   = -1,
 	  .parent  = &clk_h,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_USBD
 	},
 	{ .name    = "timers",
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_PWMT
 	},
 	{ .name    = "sdi",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_SDI
 	},
 	{ .name    = "uart",
 	  .id	   = 0,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_UART0
 	},
 	{ .name    = "uart",
 	  .id	   = 1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_UART1
 	},
 	{ .name    = "uart",
 	  .id	   = 2,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_UART2
 	},
 	{ .name    = "gpio",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_GPIO
 	},
 	{ .name    = "rtc",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_RTC
 	},
 	{ .name    = "adc",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_ADC
 	},
 	{ .name    = "i2c",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_IIC
 	},
 	{ .name    = "iis",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_IIS
 	},
 	{ .name    = "spi",
 	  .id	   = -1,
 	  .parent  = &clk_p,
-	  .enable  = s3c2410_clkcon_enable,
+	  .enable  = s3c24xx_clkcon_enable,
 	  .ctrlbit = S3C2410_CLKCON_SPI
 	},
 	{ .name    = "watchdog",
@@ -359,7 +359,7 @@
 
 /* initialise the clock system */
 
-int s3c2410_register_clock(struct clk *clk)
+int s3c24xx_register_clock(struct clk *clk)
 {
 	clk->owner = THIS_MODULE;
 	atomic_set(&clk->used, 0);
@@ -378,7 +378,7 @@
 
 /* initalise all the clocks */
 
-int __init s3c2410_init_clocks(void)
+int __init s3c24xx_setup_clocks(void)
 {
 	struct clk *clkp = init_clocks;
 	int ptr;
@@ -403,28 +403,28 @@
 	 * and of course, this looks neater
 	 */
 
-	s3c2410_clk_enable(S3C2410_CLKCON_NAND, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_USBH, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_USBD, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_ADC, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_IIC, 0);
-	s3c2410_clk_enable(S3C2410_CLKCON_SPI, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
+	s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);
 
 	/* assume uart clocks are correctly setup */
 
 	/* register our clocks */
 
-	if (s3c2410_register_clock(&clk_f) < 0)
+	if (s3c24xx_register_clock(&clk_f) < 0)
 		printk(KERN_ERR "failed to register cpu fclk\n");
 
-	if (s3c2410_register_clock(&clk_h) < 0)
+	if (s3c24xx_register_clock(&clk_h) < 0)
 		printk(KERN_ERR "failed to register cpu hclk\n");
 
-	if (s3c2410_register_clock(&clk_p) < 0)
+	if (s3c24xx_register_clock(&clk_p) < 0)
 		printk(KERN_ERR "failed to register cpu pclk\n");
 
 	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
-		ret = s3c2410_register_clock(clkp);
+		ret = s3c24xx_register_clock(clkp);
 		if (ret < 0) {
 			printk(KERN_ERR "Failed to register clock %s (%d)\n",
 			       clkp->name, ret);
diff -Nru a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h
--- a/arch/arm/mach-s3c2410/clock.h	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/clock.h	2005-01-19 13:44:46 -08:00
@@ -41,7 +41,7 @@
  * Please DO NOT use these outside of arch/arm/mach-s3c2410
 */
 
-extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
-extern int s3c2410_register_clock(struct clk *clk);
-extern int s3c2410_init_clocks(void);
+extern int s3c24xx_clkcon_enable(struct clk *clk, int enable);
+extern int s3c24xx_register_clock(struct clk *clk);
 
+extern int s3c24xx_setup_clocks(void);
diff -Nru a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
--- a/arch/arm/mach-s3c2410/cpu.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/cpu.c	2005-01-19 13:44:46 -08:00
@@ -47,6 +47,7 @@
 	unsigned long	idmask;
 	void		(*map_io)(struct map_desc *mach_desc, int size);
 	void		(*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
+	void		(*init_clocks)(int xtal);
 	int		(*init)(void);
 	const char	*name;
 };
@@ -63,6 +64,7 @@
 		.idcode		= 0x32410000,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2410_map_io,
+		.init_clocks	= s3c2410_init_clocks,
 		.init_uarts	= s3c2410_init_uarts,
 		.init		= s3c2410_init,
 		.name		= name_s3c2410
@@ -71,6 +73,7 @@
 		.idcode		= 0x32410002,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2410_map_io,
+		.init_clocks	= s3c2410_init_clocks,
 		.init_uarts	= s3c2410_init_uarts,
 		.init		= s3c2410_init,
 		.name		= name_s3c2410a
@@ -79,6 +82,7 @@
 		.idcode		= 0x32440000,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2440_map_io,
+		.init_clocks	= s3c2440_init_clocks,
 		.init_uarts	= s3c2440_init_uarts,
 		.init		= s3c2440_init,
 		.name		= name_s3c2440
@@ -87,6 +91,7 @@
 		.idcode		= 0x32440001,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2440_map_io,
+		.init_clocks	= s3c2440_init_clocks,
 		.init_uarts	= s3c2440_init_uarts,
 		.init		= s3c2440_init,
 		.name		= name_s3c2440a
@@ -132,7 +137,7 @@
 		struct clk **ptr = b->clocks;;
 
 		for (i = b->clocks_count; i > 0; i--, ptr++)
-			s3c2410_register_clock(*ptr);
+			s3c24xx_register_clock(*ptr);
 	}
 }
 
@@ -165,6 +170,29 @@
 	(cpu->map_io)(mach_desc, size);
 }
 
+/* s3c24xx_init_clocks
+ *
+ * Initialise the clock subsystem and associated information from the
+ * given master crystal value.
+ *
+ * xtal  = 0 -> use default PLL crystal value (normally 12MHz)
+ *      != 0 -> PLL crystal value in Hz
+*/
+
+void __init s3c24xx_init_clocks(int xtal)
+{
+	if (xtal != 0)
+		s3c24xx_xtal = xtal;
+
+	if (cpu == NULL)
+		panic("s3c24xx_init_clocks: no cpu setup?\n");
+
+	if (cpu->init_clocks == NULL)
+		panic("s3c24xx_init_clocks: cpu has no clock init\n");
+	else
+		(cpu->init_clocks)(xtal);
+}
+
 void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 {
 	if (cpu == NULL)
@@ -175,6 +203,7 @@
 	} else
 		(cpu->init_uarts)(cfg, no);
 }
+
 static int __init s3c_arch_init(void)
 {
 	int ret;
diff -Nru a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
--- a/arch/arm/mach-s3c2410/cpu.h	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/cpu.h	2005-01-19 13:44:46 -08:00
@@ -13,6 +13,8 @@
  *     24-Aug-2004 BJD  Start of generic S3C24XX support
  *     18-Oct-2004 BJD  Moved board struct into this file
  *     04-Jan-2005 BJD  New uart initialisation
+ *     10-Jan-2005 BJD  Moved generic init here, specific to cpu headers
+ *     14-Jan-2005 BJD  Added s3c24xx_init_clocks() call
 */
 
 #define IODESC_ENT(x) { S3C2410_VA_##x, S3C2410_PA_##x, S3C2410_SZ_##x, MT_DEVICE }
@@ -26,30 +28,16 @@
 /* forward declaration */
 struct s3c2410_uartcfg;
 
-#ifdef CONFIG_CPU_S3C2410
-extern  int s3c2410_init(void);
-extern void s3c2410_map_io(struct map_desc *mach_desc, int size);
-extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-#else
-#define s3c2410_init_uarts NULL
-#define s3c2410_map_io NULL
-#define s3c2410_init NULL
-#endif
+/* core initialisation functions */
 
-#ifdef CONFIG_CPU_S3C2440
-extern  int s3c2440_init(void);
-extern void s3c2440_map_io(struct map_desc *mach_desc, int size);
-extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-#else
-#define s3c2440_init_uarts NULL
-#define s3c2440_map_io NULL
-#define s3c2440_init NULL
-#endif
+extern void s3c24xx_init_irq(void);
 
 extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
 
 extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 
+extern void s3c24xx_init_clocks(int xtal);
+
 /* the board structure is used at first initialsation time
  * to get info such as the devices to register for this
  * board. This is done because platfrom_add_devices() cannot
@@ -65,3 +53,8 @@
 };
 
 extern void s3c24xx_set_board(struct s3c24xx_board *board);
+
+/* timer for 2410/2440 */
+
+struct sys_timer;
+extern struct sys_timer s3c24xx_timer;
diff -Nru a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
--- a/arch/arm/mach-s3c2410/dma.c	2005-01-19 13:44:48 -08:00
+++ b/arch/arm/mach-s3c2410/dma.c	2005-01-19 13:44:48 -08:00
@@ -1063,6 +1063,29 @@
 
 EXPORT_SYMBOL(s3c2410_dma_devconfig);
 
+/* s3c2410_dma_getposition
+ *
+ * returns the current transfer points for the dma source and destination
+*/
+
+int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
+{
+ 	s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];
+
+ 	check_channel(channel);
+
+	if (src != NULL)
+ 		*src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+
+ 	if (dst != NULL)
+ 		*dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
+
+ 	return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+
 /* system device class */
 
 #ifdef CONFIG_PM
diff -Nru a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
--- a/arch/arm/mach-s3c2410/irq.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/irq.c	2005-01-19 13:44:46 -08:00
@@ -628,12 +628,12 @@
 	s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
 }
 
-/* s3c2410_init_irq
+/* s3c24xx_init_irq
  *
  * Initialise S3C2410 IRQ system
 */
 
-void __init s3c2410_init_irq(void)
+void __init s3c24xx_init_irq(void)
 {
 	unsigned long pend;
 	unsigned long last;
diff -Nru a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
--- a/arch/arm/mach-s3c2410/mach-bast.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/mach-bast.c	2005-01-19 13:44:46 -08:00
@@ -20,7 +20,9 @@
  *     18-Jan-2003 BJD  Added serial port configuration
  *     05-Oct-2004 BJD  Power management code
  *     04-Nov-2004 BJD  Updated serial port clocks
- *     04-Jan-2004 BJD  New uart init call
+ *     04-Jan-2005 BJD  New uart init call
+ *     10-Jan-2005 BJD  Removed include of s3c2410.h
+ *     14-Jan-2005 BJD  Add support for muitlple NAND devices
 */
 
 #include <linux/kernel.h>
@@ -47,15 +49,20 @@
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-mem.h>
+#include <asm/arch/nand.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
 
-#include "s3c2410.h"
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
 #include "usb-simtec.h"
 #include "pm.h"
 
-#define COPYRIGHT ", (c) 2004 Simtec Electronics"
+#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
 
 /* macros for virtual address mods for the io space entries */
 #define VA_C5(item) ((item) + BAST_VAM_CS5)
@@ -220,6 +227,100 @@
 	.resource	= bast_nor_resource,
 };
 
+/* NAND Flash on BAST board */
+
+
+static int smartmedia_map[] = { 0 };
+static int chip0_map[] = { 1 };
+static int chip1_map[] = { 2 };
+static int chip2_map[] = { 3 };
+
+struct mtd_partition bast_default_nand_part[] = {
+	[0] = {
+		.name	= "Boot Agent",
+		.size	= SZ_16K,
+		.offset	= 0
+	},
+	[1] = {
+		.name	= "/boot",
+		.size	= SZ_4M - SZ_16K,
+		.offset	= SZ_16K,
+	},
+	[2] = {
+		.name	= "user",
+		.offset	= SZ_4M,
+		.size	= MTDPART_SIZ_FULL,
+	}
+};
+
+/* the bast has 4 selectable slots for nand-flash, the three
+ * on-board chip areas, as well as the external SmartMedia
+ * slot.
+ *
+ * Note, there is no current hot-plug support for the SmartMedia
+ * socket.
+*/
+
+static struct s3c2410_nand_set bast_nand_sets[] = {
+	[0] = {
+		.name		= "SmartMedia",
+		.nr_chips	= 1,
+		.nr_map		= smartmedia_map,
+		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
+		.partitions	= bast_default_nand_part
+	},
+	[1] = {
+		.name		= "chip0",
+		.nr_chips	= 1,
+		.nr_map		= chip0_map,
+		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
+		.partitions	= bast_default_nand_part
+	},
+	[2] = {
+		.name		= "chip1",
+		.nr_chips	= 1,
+		.nr_map		= chip1_map,
+		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
+		.partitions	= bast_default_nand_part
+	},
+	[3] = {
+		.name		= "chip2",
+		.nr_chips	= 1,
+		.nr_map		= chip2_map,
+		.nr_partitions	= ARRAY_SIZE(bast_default_nand_part),
+		.partitions	= bast_default_nand_part
+	}
+};
+
+static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+	unsigned int tmp;
+
+	slot = set->nr_map[slot] & 3;
+
+	pr_debug("bast_nand: selecting slot %d (set %p,%p)\n",
+		 slot, set, set->nr_map);
+
+	tmp = __raw_readb(BAST_VA_CTRL2);
+	tmp &= BAST_CPLD_CTLR2_IDERST;
+	tmp |= slot;
+	tmp |= BAST_CPLD_CTRL2_WNAND;
+
+	pr_debug("bast_nand: ctrl2 now %02x\n", tmp);
+
+	__raw_writeb(tmp, BAST_VA_CTRL2);
+}
+
+static struct s3c2410_platform_nand bast_nand_info = {
+	.tacls		= 80,
+	.twrph0		= 80,
+	.twrph1		= 80,
+	.nr_sets	= ARRAY_SIZE(bast_nand_sets),
+	.sets		= bast_nand_sets,
+	.select_chip	= bast_nand_select,
+};
+
+
 /* Standard BAST devices */
 
 static struct platform_device *bast_devices[] __initdata = {
@@ -229,6 +330,7 @@
 	&s3c_device_i2c,
 	&s3c_device_iis,
  	&s3c_device_rtc,
+	&s3c_device_nand,
 	&bast_device_nor
 };
 
@@ -262,7 +364,10 @@
 
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
+	s3c_device_nand.dev.platform_data = &bast_nand_info;
+
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
+	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
 	s3c24xx_set_board(&bast_board);
 	usb_simtec_init();
@@ -270,7 +375,7 @@
 
 void __init bast_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 }
 
 #ifdef CONFIG_PM
@@ -307,5 +412,5 @@
      MAPIO(bast_map_io)
      INITIRQ(bast_init_irq)
 	.init_machine	= bast_init_machine,
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
diff -Nru a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
--- a/arch/arm/mach-s3c2410/mach-h1940.c	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mach-s3c2410/mach-h1940.c	2005-01-19 13:44:47 -08:00
@@ -21,6 +21,8 @@
  *     18-Oct-2004 BJD  Updated new board structure name
  *     04-Nov-2004 BJD  Change for new serial clock
  *     04-Jan-2005 BJD  Updated uart init call
+ *     10-Jan-2005 BJD  Removed include of s3c2410.h
+ *     14-Jan-2005 BJD  Added clock init
 */
 
 #include <linux/kernel.h>
@@ -45,7 +47,6 @@
 
 #include <linux/serial_core.h>
 
-#include "s3c2410.h"
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
@@ -103,13 +104,14 @@
 void __init h1940_map_io(void)
 {
 	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
+	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
 	s3c24xx_set_board(&h1940_board);
 }
 
 void __init h1940_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 
 }
 
@@ -119,5 +121,5 @@
      BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
      MAPIO(h1940_map_io)
      INITIRQ(h1940_init_irq)
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
diff -Nru a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
--- a/arch/arm/mach-s3c2410/mach-rx3715.c	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c	2005-01-19 13:44:47 -08:00
@@ -12,6 +12,8 @@
  * Modifications:
  *	16-Sep-2004 BJD Copied from mach-h1940.c
  *	25-Oct-2004 BJD Updates for 2.6.10-rc1
+ *	10-Jan-2005 BJD Removed include of s3c2410.h s3c2440.h
+ *	14-Jan-2005 BJD Added new clock init
 */
 
 #include <linux/kernel.h>
@@ -38,8 +40,6 @@
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 
-#include "s3c2410.h"
-#include "s3c2440.h"
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
@@ -92,16 +92,15 @@
 
 void __init rx3715_map_io(void)
 {
-	s3c24xx_xtal = 16934000;
-
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
+	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 	s3c24xx_set_board(&rx3715_board);
 }
 
 void __init rx3715_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 }
 
 #ifdef CONFIG_PM
@@ -120,5 +119,5 @@
      MAPIO(rx3715_map_io)
      INITIRQ(rx3715_init_irq)
      INIT_MACHINE(rx3715_init_machine)
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
diff -Nru a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c	2005-01-19 13:44:48 -08:00
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c	2005-01-19 13:44:48 -08:00
@@ -46,7 +46,6 @@
 
 #include <asm/arch/regs-serial.h>
 
-#include "s3c2410.h"
 #include "devs.h"
 #include "cpu.h"
 
@@ -98,13 +97,14 @@
 void __init smdk2410_map_io(void)
 {
 	s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
+	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 	s3c24xx_set_board(&smdk2410_board);
 }
 
 void __init smdk2410_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 }
 
 MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
@@ -114,7 +114,7 @@
      BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
      MAPIO(smdk2410_map_io)
      INITIRQ(smdk2410_init_irq)
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
 
 
diff -Nru a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
--- a/arch/arm/mach-s3c2410/mach-vr1000.c	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c	2005-01-19 13:44:47 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/mach-vr1000.c
  *
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * Machine support for Thorcom VR1000 board. Designed for Thorcom by
@@ -18,7 +18,11 @@
  *     05-Apr-2004 BJD  Copied to make mach-vr1000.c
  *     18-Oct-2004 BJD  Updated board struct
  *     04-Nov-2004 BJD  Clock and serial configuration update
- *     04-Jan-2004 BJD  Updated uart init call
+ *
+ *     04-Jan-2005 BJD  Updated uart init call
+ *     10-Jan-2005 BJD  Removed include of s3c2410.h
+ *     14-Jan-2005 BJD  Added clock init
+ *     15-Jan-2005 BJD  Add serial port device definition
 */
 
 #include <linux/kernel.h>
@@ -28,12 +32,19 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
 #include <asm/arch/bast-map.h>
 #include <asm/arch/vr1000-map.h>
+#include <asm/arch/vr1000-irq.h>
+#include <asm/arch/vr1000-cpld.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -43,7 +54,6 @@
 //#include <asm/debug-ll.h>
 #include <asm/arch/regs-serial.h>
 
-#include "s3c2410.h"
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
@@ -68,6 +78,10 @@
   { S3C2410_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO),	   SZ_16M, MT_DEVICE },
   { S3C2410_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO),	   SZ_16M, MT_DEVICE },
 
+  /* serial ports */
+
+  { VR1000_VA_SERIAL,	 VR1000_PA_SERIAL,	   SZ_1M, MT_DEVICE },
+
   /* we could possibly compress the next set down into a set of smaller tables
    * pagetables, but that would mean using an L2 section, and it still means
    * we cannot actually feed the same register to an LDR due to 16K spacing
@@ -165,12 +179,87 @@
 	}
 };
 
+/* definitions for the vr1000 extra 16550 serial ports */
+
+#define VR1000_BAUDBASE (3692307)
+
+#define VR1000_SERIAL_MEMBASE(x) ((void __iomem *)VR1000_VA_SERIAL + 0x80 + ((x) << 5))
+#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	[0] = {
+		.membase	= VR1000_SERIAL_MEMBASE(0),
+		.mapbase	= VR1000_SERIAL_MAPBASE(0),
+		.irq		= IRQ_VR1000_SERIAL + 0,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= VR1000_BAUDBASE,
+	},
+	[1] = {
+		.membase	= VR1000_SERIAL_MEMBASE(1),
+		.mapbase	= VR1000_SERIAL_MAPBASE(1),
+		.irq		= IRQ_VR1000_SERIAL + 1,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= VR1000_BAUDBASE,
+	},
+	[2] = {
+		.membase	= VR1000_SERIAL_MEMBASE(2),
+		.mapbase	= VR1000_SERIAL_MAPBASE(2),
+		.irq		= IRQ_VR1000_SERIAL + 2,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= VR1000_BAUDBASE,
+	},
+	[3] = {
+		.membase	= VR1000_SERIAL_MEMBASE(3),
+		.mapbase	= VR1000_SERIAL_MAPBASE(3),
+		.irq		= IRQ_VR1000_SERIAL + 3,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= VR1000_BAUDBASE,
+	},
+	{ },
+};
+
+static struct platform_device serial_device = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= serial_platform_data,
+	},
+};
+
+/* MTD NOR Flash */
+
+static struct resource vr1000_nor_resource[] = {
+	[0] = {
+		.start	= S3C2410_CS1 + 0x4000000,
+		.end	= S3C2410_CS1 + 0x4000000 + SZ_16M - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device vr1000_nor = {
+	.name		= "bast-nor",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(vr1000_nor_resource),
+	.resource	= vr1000_nor_resource,
+};
+
+
 static struct platform_device *vr1000_devices[] __initdata = {
 	&s3c_device_usb,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c,
 	&s3c_device_iis,
+	&serial_device,
+	&vr1000_nor,
 };
 
 static struct clk *vr1000_clocks[] = {
@@ -205,6 +294,7 @@
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
+	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
 	s3c24xx_set_board(&vr1000_board);
 	usb_simtec_init();
@@ -212,7 +302,7 @@
 
 void __init vr1000_init_irq(void)
 {
-	s3c2410_init_irq();
+	s3c24xx_init_irq();
 }
 
 MACHINE_START(VR1000, "Thorcom-VR1000")
@@ -221,5 +311,5 @@
      BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
      MAPIO(vr1000_map_io)
      INITIRQ(vr1000_init_irq)
-     .timer		= &s3c2410_timer,
+	.timer		= &s3c24xx_timer,
 MACHINE_END
diff -Nru a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
--- a/arch/arm/mach-s3c2410/s3c2410.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2410.c	2005-01-19 13:44:46 -08:00
@@ -151,19 +151,19 @@
  *
  * register the standard cpu IO areas, and any passed in from the
  * machine specific initialisation.
- *
- * this function also sets the initial clock frequencies from the
- * settings passed in
 */
 
 void __init s3c2410_map_io(struct map_desc *mach_desc, int mach_size)
 {
-	unsigned long tmp;
-
 	/* register our io-tables */
 
 	iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 	iotable_init(mach_desc, mach_size);
+}
+
+void __init s3c2410_init_clocks(int xtal)
+{
+	unsigned long tmp;
 
 	/* now we've got our machine bits initialised, work out what
 	 * clocks we've got */
@@ -188,7 +188,7 @@
 	 * console to use them
 	 */
 
-	s3c2410_init_clocks();
+	s3c24xx_setup_clocks();
 }
 
 int __init s3c2410_init(void)
diff -Nru a/arch/arm/mach-s3c2410/s3c2410.h b/arch/arm/mach-s3c2410/s3c2410.h
--- a/arch/arm/mach-s3c2410/s3c2410.h	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2410.h	2005-01-19 13:44:46 -08:00
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/s3c2410.h
  *
  * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Header file for s3c2410 machine directory
  *
@@ -15,13 +15,23 @@
  *     04-Sep-2004 BJD  Added s3c2410_init_uarts() call
  *     17-Oct-2004 BJD  Moved board out to cpu
  *     04-Jan-2005 BJD  Changed uart init
+ *     10-Jan-2005 BJD  Removed timer to cpu.h, moved 2410 specific bits here
+ *     14-Jan-2005 BJD  Added s3c2410_init_clocks call
 */
 
-extern void s3c2410_map_io(struct map_desc *, int count);
+#ifdef CONFIG_CPU_S3C2410
 
-extern void s3c2410_init_irq(void);
+extern  int s3c2410_init(void);
 
-struct sys_timer;
-extern struct sys_timer s3c2410_timer;
+extern void s3c2410_map_io(struct map_desc *mach_desc, int size);
 
+extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 
+extern void s3c2410_init_clocks(int xtal);
+
+#else
+#define s3c2410_init_clocks NULL
+#define s3c2410_init_uarts NULL
+#define s3c2410_map_io NULL
+#define s3c2410_init NULL
+#endif
diff -Nru a/arch/arm/mach-s3c2410/s3c2440-dsc.c b/arch/arm/mach-s3c2410/s3c2440-dsc.c
--- a/arch/arm/mach-s3c2410/s3c2440-dsc.c	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2440-dsc.c	2005-01-19 13:44:47 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/s3c2440-dsc.c
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * Samsung S3C2440 Drive Strength Control support
@@ -12,6 +12,7 @@
  * Modifications:
  *     29-Aug-2004 BJD  Start of drive-strength control
  *     09-Nov-2004 BJD  Added symbol export
+ *     11-Jan-2005 BJD  Include fix
 */
 
 #include <linux/kernel.h>
@@ -31,8 +32,8 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-dsc.h>
 
-#include "s3c2440.h"
 #include "cpu.h"
+#include "s3c2440.h"
 
 int s3c2440_set_dsc(unsigned int pin, unsigned int value)
 {
diff -Nru a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
--- a/arch/arm/mach-s3c2410/s3c2440.c	2005-01-19 13:44:45 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2440.c	2005-01-19 13:44:45 -08:00
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/s3c2440.c
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright (c) 2004-2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * Samsung S3C2440 Mobile CPU support
@@ -16,6 +16,8 @@
  *	09-Nov-2004 BJD  Added sysdev for power management
  *	04-Nov-2004 BJD  New serial registration
  *	15-Nov-2004 BJD  Rename the i2c device for the s3c2440
+ *	14-Jan-2005 BJD  Moved clock init code into seperate function
+ *	14-Jan-2005 BJD  Removed un-used clock bits
 */
 
 #include <linux/kernel.h>
@@ -48,10 +50,6 @@
 #include "cpu.h"
 #include "pm.h"
 
-int s3c2440_clock_tick_rate = 12*1000*1000;  /* current timers at 12MHz */
-
-/* clock info */
-unsigned long s3c2440_hdiv;
 
 static struct map_desc s3c2440_iodesc[] __initdata = {
 	IODESC_ENT(USBHOST),
@@ -155,13 +153,13 @@
 
 static struct clk s3c2440_clk_cam = {
 	.name		= "camera",
-	.enable		= s3c2410_clkcon_enable,
+	.enable		= s3c24xx_clkcon_enable,
 	.ctrlbit	= S3C2440_CLKCON_CAMERA
 };
 
 static struct clk s3c2440_clk_ac97 = {
 	.name		= "ac97",
-	.enable		= s3c2410_clkcon_enable,
+	.enable		= s3c24xx_clkcon_enable,
 	.ctrlbit	= S3C2440_CLKCON_CAMERA
 };
 
@@ -204,13 +202,20 @@
 
 void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
 {
-	unsigned long clkdiv;
-	unsigned long camdiv;
-
 	/* register our io-tables */
 
 	iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
 	iotable_init(mach_desc, size);
+	/* rename any peripherals used differing from the s3c2410 */
+
+	s3c_device_i2c.name = "s3c2440-i2c";
+}
+
+void __init s3c2440_init_clocks(int xtal)
+{
+	unsigned long clkdiv;
+	unsigned long camdiv;
+	int s3c2440_hdiv = 1;
 
 	/* now we've got our machine bits initialised, work out what
 	 * clocks we've got */
@@ -254,22 +259,18 @@
 	 * console to use them, and to add new ones after the initialisation
 	 */
 
-	s3c2410_init_clocks();
+	s3c24xx_setup_clocks();
 
 	/* add s3c2440 specific clocks */
 
 	s3c2440_clk_cam.parent = clk_get(NULL, "hclk");
 	s3c2440_clk_ac97.parent = clk_get(NULL, "pclk");
 
-	s3c2410_register_clock(&s3c2440_clk_ac97);
-	s3c2410_register_clock(&s3c2440_clk_cam);
+	s3c24xx_register_clock(&s3c2440_clk_ac97);
+	s3c24xx_register_clock(&s3c2440_clk_cam);
 
 	clk_disable(&s3c2440_clk_ac97);
 	clk_disable(&s3c2440_clk_cam);
-
-	/* rename any peripherals used differing from the s3c2410 */
-
-	s3c_device_i2c.name = "s3c2440-i2c";
 }
 
 int __init s3c2440_init(void)
diff -Nru a/arch/arm/mach-s3c2410/s3c2440.h b/arch/arm/mach-s3c2410/s3c2440.h
--- a/arch/arm/mach-s3c2410/s3c2440.h	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mach-s3c2410/s3c2440.h	2005-01-19 13:44:47 -08:00
@@ -1,7 +1,7 @@
 /* arch/arm/mach-s3c2410/s3c2440.h
  *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Header file for s3c2440 cpu support
  *
@@ -12,9 +12,24 @@
  * Modifications:
  *	24-Aug-2004 BJD  Start of S3C2440 CPU support
  *	04-Nov-2004 BJD  Added s3c2440_init_uarts()
- *	04-Jan-2004 BJD  Moved uart init to cpu code
+ *	04-Jan-2005 BJD  Moved uart init to cpu code
+ *	10-Jan-2005 BJD  Moved 2440 specific init here
+ *	14-Jan-2005 BJD  Split the clock initialisation code
 */
 
-extern void s3c2440_init_irq(void);
+#ifdef CONFIG_CPU_S3C2440
 
-extern void s3c2440_init_time(void);
+extern  int s3c2440_init(void);
+
+extern void s3c2440_map_io(struct map_desc *mach_desc, int size);
+
+extern void s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2440_init_clocks(int xtal);
+
+#else
+#define s3c2440_init_clocks NULL
+#define s3c2440_init_uarts NULL
+#define s3c2440_map_io NULL
+#define s3c2440_init NULL
+#endif
diff -Nru a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c
--- a/arch/arm/mach-s3c2410/time.c	2005-01-19 13:44:46 -08:00
+++ b/arch/arm/mach-s3c2410/time.c	2005-01-19 13:44:46 -08:00
@@ -232,7 +232,7 @@
 	setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
 }
 
-struct sys_timer s3c2410_timer = {
+struct sys_timer s3c24xx_timer = {
 	.init		= s3c2410_timer_init,
 	.offset		= s3c2410_gettimeoffset,
 	.resume		= s3c2410_timer_setup
diff -Nru a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
--- a/arch/arm/mm/Kconfig	2005-01-19 13:44:48 -08:00
+++ b/arch/arm/mm/Kconfig	2005-01-19 13:44:48 -08:00
@@ -394,7 +394,7 @@
 	depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020) && !CPU_DISABLE_DCACHE
 	default y if CPU_ARM925T
 	help
-	  Say Y here to use the data cache in writethough mode. Unless you
+	  Say Y here to use the data cache in writethrough mode. Unless you
 	  specifically require this or are unsure, say N.
 
 config CPU_CACHE_ROUND_ROBIN
diff -Nru a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
--- a/arch/arm/mm/ioremap.c	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/mm/ioremap.c	2005-01-19 13:44:47 -08:00
@@ -148,7 +148,7 @@
 	 */
 	offset = phys_addr & ~PAGE_MASK;
 	phys_addr &= PAGE_MASK;
-	size = PAGE_ALIGN(last_addr) - phys_addr;
+	size = PAGE_ALIGN(last_addr + 1) - phys_addr;
 
 	/*
 	 * Ok, go for it..
diff -Nru a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
--- a/arch/arm/mm/proc-v6.S	2005-01-19 13:44:45 -08:00
+++ b/arch/arm/mm/proc-v6.S	2005-01-19 13:44:45 -08:00
@@ -105,6 +105,7 @@
 ENTRY(cpu_v6_switch_mm)
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
+	mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
 	mcr	p15, 0, r2, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c2, c0, 0		@ set TTB 0
 	mcr	p15, 0, r1, c13, c0, 1		@ set context ID
diff -Nru a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
--- a/arch/arm/vfp/entry.S	2005-01-19 13:44:47 -08:00
+++ b/arch/arm/vfp/entry.S	2005-01-19 13:44:47 -08:00
@@ -17,7 +17,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/init.h>
-#include <asm/thread_info.h>
+#include <asm/constants.h>
 #include <asm/vfpmacros.h>
 
 	.globl	do_vfp
diff -Nru a/arch/arm26/Kconfig b/arch/arm26/Kconfig
--- a/arch/arm26/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/arm26/Kconfig	2005-01-19 13:44:47 -08:00
@@ -225,4 +225,3 @@
 source "crypto/Kconfig"
 
 source "lib/Kconfig"
-
diff -Nru a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig
--- a/arch/cris/arch-v10/drivers/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/cris/arch-v10/drivers/Kconfig	2005-01-19 13:44:46 -08:00
@@ -557,7 +557,7 @@
 	select DMA_NONPCI
 	help
 	  Enable this to get support for ATA/IDE.
-	  You can't use parallell ports or SCSI ports
+	  You can't use paralell ports or SCSI ports
 	  at the same time.
 
 
diff -Nru a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
--- a/arch/frv/kernel/entry.S	2005-01-19 13:44:46 -08:00
+++ b/arch/frv/kernel/entry.S	2005-01-19 13:44:46 -08:00
@@ -821,7 +821,6 @@
 	ori		gr4,#_TIF_SYSCALL_TRACE,gr4
 	andicc		gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
 	bne		icc0,#0,__syscall_trace_entry
-	bra		__syscall_trace_entry
 
 __syscall_call:
 	slli.p		gr7,#2,gr7
@@ -858,7 +857,6 @@
 	movgs		gr23,psr
 
 	ldi		@(gr15,#TI_FLAGS),gr4
-//	ori		gr4,#_TIF_SYSCALL_TRACE,gr4		/////////////////////////////////
 	sethi.p		%hi(_TIF_ALLWORK_MASK),gr5
 	setlo		%lo(_TIF_ALLWORK_MASK),gr5
 	andcc		gr4,gr5,gr0,icc0
@@ -1075,7 +1073,7 @@
 	andicc		gr4,#_TIF_NEED_RESCHED,gr0,icc0
 	bne		icc0,#1,__entry_work_resched
 
- __entry_work_notifysig:
+__entry_work_notifysig:
 	LEDS		0x6410
 	ori.p		gr4,#0,gr8
 	call		do_notify_resume
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/i386/Kconfig	2005-01-19 13:44:46 -08:00
@@ -842,7 +842,6 @@
 	depends on ACPI
 	default n
 	---help---
-
 	This enables the the kernel to boot on EFI platforms using
 	system configuration information passed to it from the firmware.
 	This also enables the kernel to use any EFI runtime services that are
@@ -881,7 +880,7 @@
 	depends on EXPERIMENTAL
 	default n
 	help
-	Compile the kernel with -mregparm=3. This uses an different ABI
+	Compile the kernel with -mregparm=3. This uses a different ABI
 	and passes the first three arguments of a function call in registers.
 	This will probably break binary only modules.
 
@@ -1131,6 +1130,8 @@
 	depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI))
 	select ACPI_BOOT
 	default y
+
+source "drivers/pci/pcie/Kconfig"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
--- a/arch/i386/kernel/acpi/wakeup.S	2005-01-19 13:44:46 -08:00
+++ b/arch/i386/kernel/acpi/wakeup.S	2005-01-19 13:44:46 -08:00
@@ -278,7 +278,7 @@
 	movl %edi, saved_context_edi
 	pushfl ; popl saved_context_eflags
 
-	movl $ret_point,saved_eip
+	movl $ret_point, saved_eip
 	ret
 
 
@@ -295,7 +295,7 @@
 	call	save_registers
 	pushl	$3
 	call	acpi_enter_sleep_state
-	addl	$4,%esp
+	addl	$4, %esp
 	ret
 	.p2align 4,,7
 ret_point:
diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c	2005-01-19 13:44:45 -08:00
+++ b/arch/i386/kernel/apm.c	2005-01-19 13:44:45 -08:00
@@ -1201,8 +1201,8 @@
 		printk(KERN_CRIT "apm: suspend was vetoed, but suspending anyway.\n");
 	}
 
-	device_suspend(3);
-	device_power_down(3);
+	device_suspend(PMSG_SUSPEND);
+	device_power_down(PMSG_SUSPEND);
 
 	/* serialize with the timer interrupt */
 	write_seqlock_irq(&xtime_lock);
@@ -1255,7 +1255,7 @@
 {
 	int	err;
 
-	device_power_down(3);
+	device_power_down(PMSG_SUSPEND);
 	/* serialize with the timer interrupt */
 	write_seqlock_irq(&xtime_lock);
 	/* If needed, notify drivers here */
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig	2005-01-19 13:44:46 -08:00
@@ -175,7 +175,7 @@
 	depends on CPU_FREQ && EXPERIMENTAL
 	help
 	  This adds the CPUFreq driver for FSB changing on nVidia nForce2
-	  plattforms.
+	  platforms.
 
 	  For details, take a look at <file:Documentation/cpu-freq/>.
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	2005-01-19 13:44:45 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	2005-01-19 13:44:45 -08:00
@@ -38,6 +38,8 @@
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 
+#include "speedstep-est-common.h"
+
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
 
 MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
@@ -48,10 +50,12 @@
 struct cpufreq_acpi_io {
 	struct acpi_processor_performance	acpi_data;
 	struct cpufreq_frequency_table		*freq_table;
+	unsigned int				resume;
 };
 
 static struct cpufreq_acpi_io	*acpi_io_data[NR_CPUS];
 
+static struct cpufreq_driver acpi_cpufreq_driver;
 
 static int
 acpi_processor_write_port(
@@ -119,9 +123,14 @@
 	}
 	
 	if (state == data->acpi_data.state) {
-		dprintk("Already at target state (P%d)\n", state);
-		retval = 0;
-		goto migrate_end;
+		if (unlikely(data->resume)) {
+			dprintk("Called after resume, resetting to P%d\n", state);
+			data->resume = 0;
+		} else {
+			dprintk("Already at target state (P%d)\n", state);
+			retval = 0;
+			goto migrate_end;
+		}
 	}
 
 	dprintk("Transitioning from P%d to P%d\n",
@@ -368,6 +377,10 @@
 	if (result)
 		goto err_free;
 
+	if (is_const_loops_cpu(cpu)) {
+		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
+	}
+
 	/* capability check */
 	if (data->acpi_data.state_count <= 1) {
 		dprintk("No P-States\n");
@@ -462,6 +475,20 @@
 	return (0);
 }
 
+static int
+acpi_cpufreq_resume (
+	struct cpufreq_policy   *policy)
+{
+	struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
+
+
+	dprintk("acpi_cpufreq_resume\n");
+
+	data->resume = 1;
+
+	return (0);
+}
+
 
 static struct freq_attr* acpi_cpufreq_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
@@ -473,6 +500,7 @@
 	.target 	= acpi_cpufreq_target,
 	.init		= acpi_cpufreq_cpu_init,
 	.exit		= acpi_cpufreq_cpu_exit,
+	.resume		= acpi_cpufreq_resume,
 	.name		= "acpi-cpufreq",
 	.owner		= THIS_MODULE,
 	.attr           = acpi_cpufreq_attr,
diff -Nru a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
--- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c	2005-01-19 13:44:45 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c	2005-01-19 13:44:45 -08:00
@@ -55,16 +55,7 @@
 MODULE_PARM_DESC(min_fsb,
                  "Minimum FSB to use, if not defined: current FSB - 50");
 
-/* DEBUG
- *   Define it if you want verbose debug output, e.g. for bug reporting
- */
-//#define NFORCE2_DEBUG
-
-#ifdef NFORCE2_DEBUG
-#define dprintk(msg...) printk(msg)
-#else
-#define dprintk(msg...) do { } while(0)
-#endif
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg)
 
 /*
  * nforce2_calc_fsb - calculate FSB
diff -Nru a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	2005-01-19 13:44:48 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	2005-01-19 13:44:48 -08:00
@@ -209,7 +209,7 @@
 	if ((gx_params->pci_suscfg & SUSMOD) == 0) 
 		return stock_freq;
 
-	return (stock_freq * gx_params->on_duration) 
+	return (stock_freq * gx_params->off_duration) 
 		/ (gx_params->on_duration + gx_params->off_duration);
 }
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	2005-01-19 13:44:47 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	2005-01-19 13:44:47 -08:00
@@ -171,7 +171,7 @@
 		return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
 	}
 
-	if ((c->x86 == 0x06) && (c->x86_model == 0x13)) {
+	if ((c->x86 == 0x06) && (c->x86_model == 0x0D)) {
 		/* Pentium M (Dothan) */
 		printk(KERN_WARNING PFX "Warning: Pentium M detected. "
 		       "The speedstep_centrino module offers voltage scaling"
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2005-01-19 13:44:45 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2005-01-19 13:44:45 -08:00
@@ -635,6 +635,17 @@
 
 static int powernow_cpu_exit (struct cpufreq_policy *policy) {
 	cpufreq_frequency_table_put_attr(policy->cpu);
+
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+	if (acpi_processor_perf) {
+		acpi_processor_unregister_performance(acpi_processor_perf, 0);
+		kfree(acpi_processor_perf);
+	}
+#endif
+
+	if (powernow_table)
+		kfree(powernow_table);
+
 	return 0;
 }
 
@@ -664,15 +675,7 @@
 
 static void __exit powernow_exit (void)
 {
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-	if (acpi_processor_perf) {
-		acpi_processor_unregister_performance(acpi_processor_perf, 0);
-		kfree(acpi_processor_perf);
-	}
-#endif
 	cpufreq_unregister_driver(&powernow_driver);
-	if (powernow_table)
-		kfree(powernow_table);
 }
 
 module_param(acpi_force,  int, 0444);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2005-01-19 13:44:47 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2005-01-19 13:44:47 -08:00
@@ -18,6 +18,9 @@
  *  Processor information obtained from Chapter 9 (Power and Thermal Management)
  *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
  *  Opteron Processors" available for download from www.amd.com
+ *
+ *  Tables for specific CPUs can be infrerred from
+ *	http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
  */
 
 #include <linux/kernel.h>
@@ -65,7 +68,12 @@
 	return 1550-vid*25;
 }
 
-/* Return the vco fid for an input fid */
+/* Return the vco fid for an input fid
+ *
+ * Each "low" fid has corresponding "high" fid, and you can get to "low" fids
+ * only from corresponding high fids. This returns "high" fid corresponding to
+ * "low" one.
+ */
 static u32 convert_fid_to_vco_fid(u32 fid)
 {
 	if (fid < HI_FID_TABLE_BOTTOM) {
@@ -278,7 +286,7 @@
 			return 1;
 	}
 
-	while (rvosteps > 0) {
+	while ((rvosteps > 0)  && ((data->rvo + data->currvid) > reqvid)) {
 		if (data->currvid == 0) {
 			rvosteps = 0;
 		} else {
@@ -307,10 +315,7 @@
 /* Phase 2 - core frequency transition */
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 {
-	u32 vcoreqfid;
-	u32 vcocurrfid;
-	u32 vcofiddiff;
-	u32 savevid = data->currvid;
+	u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid;
 
 	if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
 		printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
@@ -498,7 +503,7 @@
 		    || (pst[j].fid & 1)
 		    || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
 			/* Only first fid is allowed to be in "low" range */
-			printk(KERN_ERR PFX "fid %d invalid : 0x%x\n", j, pst[j].fid);
+			printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
 			return -EINVAL;
 		}
 		if (pst[j].fid < lastfid)
@@ -618,7 +623,7 @@
 			return -ENODEV;
 		}
 
-		data->vstable = psb->voltagestabilizationtime;
+		data->vstable = psb->vstable;
 		dprintk("voltage stabilization time: %d(*20us)\n", data->vstable);
 
 		dprintk("flags2: 0x%x\n", psb->flags2);
@@ -632,8 +637,8 @@
 		dprintk("isochronous relief time: %d\n", data->irt);
 		dprintk("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs);
 
-		dprintk("numpst: 0x%x\n", psb->numpst);
-		cpst = psb->numpst;
+		dprintk("numpst: 0x%x\n", psb->num_tables);
+		cpst = psb->num_tables;
 		if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){
 			thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 			if ((thiscpuid == 0x00000fc0) || (thiscpuid == 0x00000fe0) ) {
@@ -651,7 +656,7 @@
 		dprintk("maxvid: 0x%x\n", psb->maxvid);
 		maxvid = psb->maxvid;
 
-		data->numps = psb->numpstates;
+		data->numps = psb->numps;
 		dprintk("numpstates: 0x%x\n", data->numps);
 		return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid);
 	}
@@ -1010,6 +1015,7 @@
 	/* min/max the cpu is capable of */
 	if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) {
 		printk(KERN_ERR PFX "invalid powernow_table\n");
+		powernow_k8_cpu_exit_acpi(data);
 		kfree(data->powernow_table);
 		kfree(data);
 		return -EINVAL;
@@ -1027,6 +1033,7 @@
 err_out:
 	set_cpus_allowed(current, oldmask);
 	schedule();
+	powernow_k8_cpu_exit_acpi(data);
 
 	kfree(data);
 	return -ENODEV;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h	2005-01-19 13:44:47 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h	2005-01-19 13:44:47 -08:00
@@ -21,8 +21,7 @@
 	u32 plllock; /* pll lock time, units 1 us */
 
 	/* keep track of the current fid / vid */
-	u32 currvid;
-	u32 currfid;
+	u32 currvid, currfid;
 
 	/* the powernow_table includes all frequency and vid/fid pairings:
 	 * fid are the lower 8 bits of the index, vid are the upper 8 bits.
@@ -152,14 +151,14 @@
 	u8 signature[10];
 	u8 tableversion;
 	u8 flags1;
-	u16 voltagestabilizationtime;
+	u16 vstable;
 	u8 flags2;
-	u8 numpst;
+	u8 num_tables;
 	u32 cpuid;
 	u8 plllocktime;
 	u8 maxfid;
 	u8 maxvid;
-	u8 numpstates;
+	u8 numps;
 };
 
 /* Pairs of fid/vid values are appended to the version 1.4 PSB table. */
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2005-01-19 13:44:46 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2005-01-19 13:44:46 -08:00
@@ -22,6 +22,8 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/compiler.h>
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
 #include <linux/acpi.h>
@@ -32,6 +34,8 @@
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
 
+#include "speedstep-est-common.h"
+
 #define PFX		"speedstep-centrino: "
 #define MAINTAINER	"Jeremy Fitzhardinge <jeremy@goop.org>"
 
@@ -71,8 +75,10 @@
 static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x);
 
 /* Operating points for current CPU */
-static struct cpu_model *centrino_model;
-static const struct cpu_id *centrino_cpu;
+static struct cpu_model *centrino_model[NR_CPUS];
+static const struct cpu_id *centrino_cpu[NR_CPUS];
+
+static struct cpufreq_driver centrino_driver;
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
 
@@ -239,7 +245,7 @@
 
 	if (model->cpu_id == NULL) {
 		/* No match at all */
-		printk(KERN_INFO PFX "no support for CPU model \"%s\": "
+		dprintk(KERN_INFO PFX "no support for CPU model \"%s\": "
 		       "send /proc/cpuinfo to " MAINTAINER "\n",
 		       cpu->x86_model_id);
 		return -ENOENT;
@@ -247,15 +253,15 @@
 
 	if (model->op_points == NULL) {
 		/* Matched a non-match */
-		printk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
+		dprintk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
 		       cpu->x86_model_id);
 #ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
-		printk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
+		dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
 #endif
 		return -ENOENT;
 	}
 
-	centrino_model = model;
+	centrino_model[policy->cpu] = model;
 
 	dprintk("found \"%s\": max frequency: %dkHz\n",
 	       model->model_name, model->max_freq);
@@ -277,7 +283,7 @@
 }
 
 /* To be called only after centrino_model is initialized */
-static unsigned extract_clock(unsigned msr)
+static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe)
 {
 	int i;
 
@@ -286,28 +292,32 @@
 	 * for centrino, as some DSDTs are buggy.
 	 * Ideally, this can be done using the acpi_data structure.
 	 */
-	if ((centrino_cpu == &cpu_ids[CPU_BANIAS]) ||
-	    (centrino_cpu == &cpu_ids[CPU_DOTHAN_A1]) ||
-	    (centrino_cpu == &cpu_ids[CPU_DOTHAN_B0])) {
+	if ((centrino_cpu[cpu] == &cpu_ids[CPU_BANIAS]) ||
+	    (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_A1]) ||
+	    (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_B0])) {
 		msr = (msr >> 8) & 0xff;
 		return msr * 100000;
 	}
 
-	if ((!centrino_model) || (!centrino_model->op_points))
+	if ((!centrino_model[cpu]) || (!centrino_model[cpu]->op_points))
 		return 0;
 
 	msr &= 0xffff;
-	for (i=0;centrino_model->op_points[i].frequency != CPUFREQ_TABLE_END; i++) {
-		if (msr == centrino_model->op_points[i].index)
-		return centrino_model->op_points[i].frequency;
-	}
-	return 0;
+	for (i=0;centrino_model[cpu]->op_points[i].frequency != CPUFREQ_TABLE_END; i++) {
+		if (msr == centrino_model[cpu]->op_points[i].index)
+			return centrino_model[cpu]->op_points[i].frequency;
+	}
+	if (failsafe)
+		return centrino_model[cpu]->op_points[i-1].frequency;
+	else
+		return 0;
 }
 
 /* Return the current CPU frequency in kHz */
 static unsigned int get_cur_freq(unsigned int cpu)
 {
 	unsigned l, h;
+	unsigned clock_freq;
 	cpumask_t saved_mask;
 
 	saved_mask = current->cpus_allowed;
@@ -316,8 +326,21 @@
 		return 0;
 
 	rdmsr(MSR_IA32_PERF_STATUS, l, h);
+	clock_freq = extract_clock(l, cpu, 0);
+
+	if (unlikely(clock_freq == 0)) {
+		/*
+		 * On some CPUs, we can see transient MSR values (which are
+		 * not present in _PSS), while CPU is doing some automatic
+		 * P-state transition (like TM2). Get the last freq set 
+		 * in PERF_CTL.
+		 */
+		rdmsr(MSR_IA32_PERF_CTL, l, h);
+		clock_freq = extract_clock(l, cpu, 1);
+	}
+
 	set_cpus_allowed(current, saved_mask);
-	return extract_clock(l);
+	return clock_freq;
 }
 
 
@@ -339,6 +362,7 @@
 	struct acpi_object_list		arg_list = {1, &arg0};
 	unsigned long			cur_freq;
 	int				result = 0, i;
+	unsigned int			cpu = policy->cpu;
 
 	/* _PDC settings */
 	arg0.buffer.length = 12;
@@ -350,8 +374,8 @@
 	p.pdc = &arg_list;
 
 	/* register with ACPI core */
-	if (acpi_processor_register_performance(&p, policy->cpu)) {
-		printk(KERN_INFO PFX "obtaining ACPI data failed\n");
+	if (acpi_processor_register_performance(&p, cpu)) {
+		dprintk(KERN_INFO PFX "obtaining ACPI data failed\n");
 		return -EIO;
 	}
 
@@ -392,49 +416,49 @@
 		}
 	}
 
-	centrino_model = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
-	if (!centrino_model) {
+	centrino_model[cpu] = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
+	if (!centrino_model[cpu]) {
 		result = -ENOMEM;
 		goto err_unreg;
 	}
-	memset(centrino_model, 0, sizeof(struct cpu_model));
+	memset(centrino_model[cpu], 0, sizeof(struct cpu_model));
 
-	centrino_model->model_name=NULL;
-	centrino_model->max_freq = p.states[0].core_frequency * 1000;
-	centrino_model->op_points =  kmalloc(sizeof(struct cpufreq_frequency_table) *
+	centrino_model[cpu]->model_name=NULL;
+	centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000;
+	centrino_model[cpu]->op_points =  kmalloc(sizeof(struct cpufreq_frequency_table) *
 					     (p.state_count + 1), GFP_KERNEL);
-        if (!centrino_model->op_points) {
+        if (!centrino_model[cpu]->op_points) {
                 result = -ENOMEM;
                 goto err_kfree;
         }
 
         for (i=0; i<p.state_count; i++) {
-		centrino_model->op_points[i].index = p.states[i].control;
-		centrino_model->op_points[i].frequency = p.states[i].core_frequency * 1000;
+		centrino_model[cpu]->op_points[i].index = p.states[i].control;
+		centrino_model[cpu]->op_points[i].frequency = p.states[i].core_frequency * 1000;
 		dprintk("adding state %i with frequency %u and control value %04x\n", 
-			i, centrino_model->op_points[i].frequency, centrino_model->op_points[i].index);
+			i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);
 	}
-	centrino_model->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
+	centrino_model[cpu]->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
 
-	cur_freq = get_cur_freq(policy->cpu);
+	cur_freq = get_cur_freq(cpu);
 
 	for (i=0; i<p.state_count; i++) {
 		if (!p.states[i].core_frequency) {
 			dprintk("skipping state %u\n", i);
-			centrino_model->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
+			centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
 			continue;
 		}
 		
-		if (extract_clock(centrino_model->op_points[i].index) !=
-		    (centrino_model->op_points[i].frequency)) {
+		if (extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0) !=
+		    (centrino_model[cpu]->op_points[i].frequency)) {
 			dprintk("Invalid encoded frequency (%u vs. %u)\n",
-				extract_clock(centrino_model->op_points[i].index),
-				centrino_model->op_points[i].frequency);
+				extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0),
+				centrino_model[cpu]->op_points[i].frequency);
 			result = -EINVAL;
 			goto err_kfree_all;
 		}
 
-		if (cur_freq == centrino_model->op_points[i].frequency)
+		if (cur_freq == centrino_model[cpu]->op_points[i].frequency)
 			p.state = i;
 	}
 
@@ -444,12 +468,12 @@
 	return 0;
 
  err_kfree_all:
-	kfree(centrino_model->op_points);
+	kfree(centrino_model[cpu]->op_points);
  err_kfree:
-	kfree(centrino_model);
+	kfree(centrino_model[cpu]);
  err_unreg:
-	acpi_processor_unregister_performance(&p, policy->cpu);
-	printk(KERN_INFO PFX "invalid ACPI data\n");
+	acpi_processor_unregister_performance(&p, cpu);
+	dprintk(KERN_INFO PFX "invalid ACPI data\n");
 	return (result);
 }
 #else
@@ -473,14 +497,18 @@
 			break;
 
 	if (i != N_IDS)
-		centrino_cpu = &cpu_ids[i];
+		centrino_cpu[policy->cpu] = &cpu_ids[i];
+
+	if (is_const_loops_cpu(policy->cpu)) {
+		centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
+	}
 
 	if (centrino_cpu_init_acpi(policy)) {
 		if (policy->cpu != 0)
 			return -ENODEV;
 
-		if (!centrino_cpu) {
-			printk(KERN_INFO PFX "found unsupported CPU with "
+		if (!centrino_cpu[policy->cpu]) {
+			dprintk(KERN_INFO PFX "found unsupported CPU with "
 			"Enhanced SpeedStep: send /proc/cpuinfo to "
 			MAINTAINER "\n");
 			return -ENODEV;
@@ -516,32 +544,34 @@
 
 	dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur);
 
-	ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
+	ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model[policy->cpu]->op_points);
 	if (ret)
 		return (ret);
 
-	cpufreq_frequency_table_get_attr(centrino_model->op_points, policy->cpu);
+	cpufreq_frequency_table_get_attr(centrino_model[policy->cpu]->op_points, policy->cpu);
 
 	return 0;
 }
 
 static int centrino_cpu_exit(struct cpufreq_policy *policy)
 {
-	if (!centrino_model)
+	unsigned int cpu = policy->cpu;
+
+	if (!centrino_model[cpu])
 		return -ENODEV;
 
-	cpufreq_frequency_table_put_attr(policy->cpu);
+	cpufreq_frequency_table_put_attr(cpu);
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
-	if (!centrino_model->model_name) {
+	if (!centrino_model[cpu]->model_name) {
 		dprintk("unregistering and freeing ACPI data\n");
-		acpi_processor_unregister_performance(&p, policy->cpu);
-		kfree(centrino_model->op_points);
-		kfree(centrino_model);
+		acpi_processor_unregister_performance(&p, cpu);
+		kfree(centrino_model[cpu]->op_points);
+		kfree(centrino_model[cpu]);
 	}
 #endif
 
-	centrino_model = NULL;
+	centrino_model[cpu] = NULL;
 
 	return 0;
 }
@@ -555,7 +585,7 @@
  */
 static int centrino_verify (struct cpufreq_policy *policy)
 {
-	return cpufreq_frequency_table_verify(policy, centrino_model->op_points);
+	return cpufreq_frequency_table_verify(policy, centrino_model[policy->cpu]->op_points);
 }
 
 /**
@@ -571,12 +601,12 @@
 			    unsigned int relation)
 {
 	unsigned int    newstate = 0;
-	unsigned int	msr, oldmsr, h;
+	unsigned int	msr, oldmsr, h, cpu = policy->cpu;
 	struct cpufreq_freqs	freqs;
 	cpumask_t		saved_mask;
 	int			retval;
 
-	if (centrino_model == NULL)
+	if (centrino_model[cpu] == NULL)
 		return -ENODEV;
 
 	/*
@@ -585,18 +615,18 @@
 	 */
 	saved_mask = current->cpus_allowed;
 	set_cpus_allowed(current, policy->cpus);
-	if (smp_processor_id() != policy->cpu) {
+	if (!cpu_isset(smp_processor_id(), policy->cpus)) {
 		dprintk("couldn't limit to CPUs in this domain\n");
 		return(-EAGAIN);
 	}
 
-	if (cpufreq_frequency_table_target(policy, centrino_model->op_points, target_freq,
+	if (cpufreq_frequency_table_target(policy, centrino_model[cpu]->op_points, target_freq,
 					   relation, &newstate)) {
 		retval = -EINVAL;
 		goto migrate_end;
 	}
 
-	msr = centrino_model->op_points[newstate].index;
+	msr = centrino_model[cpu]->op_points[newstate].index;
 	rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
 
 	if (msr == (oldmsr & 0xffff)) {
@@ -605,9 +635,9 @@
 		goto migrate_end;
 	}
 
-	freqs.cpu = policy->cpu;
-	freqs.old = extract_clock(oldmsr);
-	freqs.new = extract_clock(msr);
+	freqs.cpu = cpu;
+	freqs.old = extract_clock(oldmsr, cpu, 0);
+	freqs.new = extract_clock(msr, cpu, 0);
 
 	dprintk("target=%dkHz old=%d new=%d msr=%04x\n",
 		target_freq, freqs.old, freqs.new, msr);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h b/arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-est-common.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,25 @@
+/*
+ * Routines common for drivers handling Enhanced Speedstep Technology
+ *  Copyright (C) 2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2 -- see
+ *  COPYING for details.
+ */
+
+static inline int is_const_loops_cpu(unsigned int cpu)
+{
+	struct cpuinfo_x86 	*c = cpu_data + cpu;
+
+	if (c->x86_vendor != X86_VENDOR_INTEL || !cpu_has(c, X86_FEATURE_EST))
+		return 0;
+
+	/*
+	 * on P-4s, the TSC runs with constant frequency independent of cpu freq
+	 * when we use EST
+	 */
+	if (c->x86 == 0xf)
+		return 1;
+
+	return 0;
+}
+
diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c	2005-01-19 13:44:48 -08:00
+++ b/arch/i386/kernel/i386_ksyms.c	2005-01-19 13:44:48 -08:00
@@ -74,7 +74,6 @@
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(ioremap_nocache);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(probe_irq_mask);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(pm_idle);
 EXPORT_SYMBOL(pm_power_off);
diff -Nru a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
--- a/arch/i386/kernel/i387.c	2005-01-19 13:44:48 -08:00
+++ b/arch/i386/kernel/i387.c	2005-01-19 13:44:48 -08:00
@@ -111,16 +111,17 @@
 static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
 {
 	struct _fpxreg *st = NULL;
+	unsigned long tos = (fxsave->swd >> 11) & 7;
 	unsigned long twd = (unsigned long) fxsave->twd;
 	unsigned long tag;
 	unsigned long ret = 0xffff0000u;
 	int i;
 
-#define FPREG_ADDR(f, n)	((char *)&(f)->st_space + (n) * 16);
+#define FPREG_ADDR(f, n)	((void *)&(f)->st_space + (n) * 16);
 
 	for ( i = 0 ; i < 8 ; i++ ) {
 		if ( twd & 0x1 ) {
-			st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
+			st = FPREG_ADDR( fxsave, (i - tos) & 7 );
 
 			switch ( st->exponent & 0x7fff ) {
 			case 0x7fff:
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	2005-01-19 13:44:46 -08:00
+++ b/arch/i386/kernel/io_apic.c	2005-01-19 13:44:46 -08:00
@@ -573,6 +573,7 @@
 	for ( ; ; ) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		time_remaining = schedule_timeout(time_remaining);
+		try_to_freeze(PF_FREEZE);
 		if (time_after(jiffies,
 				prev_balance_time+balanced_irq_interval)) {
 			do_irq_balance();
diff -Nru a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
--- a/arch/i386/kernel/kprobes.c	2005-01-19 13:44:46 -08:00
+++ b/arch/i386/kernel/kprobes.c	2005-01-19 13:44:46 -08:00
@@ -31,6 +31,7 @@
 #include <linux/spinlock.h>
 #include <linux/preempt.h>
 #include <asm/kdebug.h>
+#include <asm/desc.h>
 
 /* kprobe_status settings */
 #define KPROBE_HIT_ACTIVE	0x00000001
@@ -101,10 +102,8 @@
 	if ((regs->xcs & 4) && (current->mm)) {
 		lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8)
 					+ (char *) current->mm->context.ldt);
-		addr = (kprobe_opcode_t *) ((((*lp) >> 16 &  0x0000ffff)
-				| (*(lp +1) & 0xff000000)
-				| ((*(lp +1) << 16) & 0x00ff0000))
-				+ regs->eip - sizeof(kprobe_opcode_t));
+		addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip -
+						sizeof(kprobe_opcode_t));
 	} else {
 		addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
 	}
diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
--- a/arch/i386/mm/fault.c	2005-01-19 13:44:45 -08:00
+++ b/arch/i386/mm/fault.c	2005-01-19 13:44:45 -08:00
@@ -112,9 +112,7 @@
 	}
 
 	/* Decode the code segment base from the descriptor */
-	base =   (desc[0] >> 16) |
-		((desc[1] & 0xff) << 16) |
-		 (desc[1] & 0xff000000);
+	base = get_desc_base((unsigned long *)desc);
 
 	if (seg & (1<<2)) { 
 		up(&current->mm->context.sem);
diff -Nru a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
--- a/arch/i386/pci/pcbios.c	2005-01-19 13:44:45 -08:00
+++ b/arch/i386/pci/pcbios.c	2005-01-19 13:44:45 -08:00
@@ -385,8 +385,8 @@
 			}
 		}
 		if (!found) {
-			printk(KERN_WARNING "PCI: Device %02x:%02x not found by BIOS\n",
-				dev->bus->number, dev->devfn);
+			printk(KERN_WARNING "PCI: Device %s not found by BIOS\n",
+				pci_name(dev));
 			list_del(&dev->global_list);
 			list_add_tail(&dev->global_list, &sorted_devices);
 		}
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/Kconfig	2005-01-19 13:44:47 -08:00
@@ -61,11 +61,12 @@
 	  will run on any supported IA-64 system.  However, if you configure
 	  a kernel for your specific system, it will be faster and smaller.
 
-	  generic	 For any supported IA-64 system
-	  DIG-compliant	 For DIG ("Developer's Interface Guide") compliant systems
-	  HP-zx1/sx1000	 For HP systems
-	  SGI-SN2	 For SGI Altix systems
-	  Ski-simulator  For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
+	  generic		For any supported IA-64 system
+	  DIG-compliant		For DIG ("Developer's Interface Guide") compliant systems
+	  HP-zx1/sx1000		For HP systems
+	  HP-zx1/sx1000+swiotlb	For HP systems with (broken) DMA-constrained devices.
+	  SGI-SN2		For SGI Altix systems
+	  Ski-simulator		For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
 
 	  If you don't know what to do, choose "generic".
 
@@ -78,6 +79,15 @@
 	  Build a kernel that runs on HP zx1 and sx1000 systems.  This adds
 	  support for the HP I/O MMU.
 
+config IA64_HP_ZX1_SWIOTLB
+	bool "HP-zx1/sx1000 with software I/O TLB"
+	help
+	  Build a kernel that runs on HP zx1 and sx1000 systems even when they
+	  have broken PCI devices which cannot DMA to full 32 bits.  Apart
+	  from support for the HP I/O MMU, this includes support for the software
+	  I/O TLB, which allows supporting the broken devices at the expense of
+	  wasting some kernel memory (about 2MB by default).
+
 config IA64_SGI_SN2
 	bool "SGI-SN2"
 	help
@@ -188,7 +198,7 @@
 
 config DISCONTIGMEM
 	bool "Discontiguous memory support"
-	depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1) && NUMA && VIRTUAL_MEM_MAP
+	depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP
 	default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
 	help
 	  Say Y to support efficient handling of discontiguous physical memory,
@@ -326,7 +336,7 @@
 
 config PM
 	bool "Power Management support"
-	depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
+	depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB
 	default y
 	help
 	  "Power Management" means that parts of your computer are shut
diff -Nru a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
--- a/arch/ia64/Kconfig.debug	2005-01-19 13:44:46 -08:00
+++ b/arch/ia64/Kconfig.debug	2005-01-19 13:44:46 -08:00
@@ -16,7 +16,7 @@
 
 config IA64_GRANULE_64MB
 	bool "64MB"
-	depends on !(IA64_GENERIC || IA64_HP_ZX1 || IA64_SGI_SN2)
+	depends on !(IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_SGI_SN2)
 
 endchoice
 
diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile
--- a/arch/ia64/Makefile	2005-01-19 13:44:45 -08:00
+++ b/arch/ia64/Makefile	2005-01-19 13:44:45 -08:00
@@ -57,11 +57,13 @@
 core-$(CONFIG_IA64_DIG) 	+= arch/ia64/dig/
 core-$(CONFIG_IA64_GENERIC) 	+= arch/ia64/dig/
 core-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/dig/
+core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
 core-$(CONFIG_IA64_SGI_SN2)	+= arch/ia64/sn/
 
 drivers-$(CONFIG_PCI)		+= arch/ia64/pci/
 drivers-$(CONFIG_IA64_HP_SIM)	+= arch/ia64/hp/sim/
 drivers-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/
+drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
 drivers-$(CONFIG_IA64_GENERIC)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/
 drivers-$(CONFIG_OPROFILE)	+= arch/ia64/oprofile/
 
diff -Nru a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
--- a/arch/ia64/configs/sn2_defconfig	2005-01-19 13:44:45 -08:00
+++ b/arch/ia64/configs/sn2_defconfig	2005-01-19 13:44:45 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1
-# Mon Nov  1 14:35:44 2004
+# Linux kernel version: 2.6.10
+# Mon Jan 10 13:57:35 2005
 #
 
 #
@@ -58,6 +58,7 @@
 CONFIG_64BIT=y
 CONFIG_MMU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
@@ -75,6 +76,7 @@
 CONFIG_IA64_L1_CACHE_SHIFT=7
 CONFIG_NUMA=y
 CONFIG_VIRTUAL_MEM_MAP=y
+CONFIG_HOLES_IN_ZONE=y
 CONFIG_DISCONTIGMEM=y
 # CONFIG_IA64_CYCLONE is not set
 CONFIG_IOSAPIC=y
@@ -90,6 +92,7 @@
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
@@ -110,6 +113,7 @@
 CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 # CONFIG_ACPI_BUTTON is not set
+CONFIG_ACPI_VIDEO=m
 # CONFIG_ACPI_FAN is not set
 # CONFIG_ACPI_PROCESSOR is not set
 CONFIG_ACPI_NUMA=y
@@ -119,6 +123,7 @@
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # Bus options (PCI, PCMCIA)
@@ -174,6 +179,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNP is not set
 
 #
 # Block devices
@@ -188,6 +194,7 @@
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
@@ -200,6 +207,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+CONFIG_ATA_OVER_ETH=m
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -287,6 +295,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -333,7 +342,6 @@
 CONFIG_SCSI_QLA2300=y
 CONFIG_SCSI_QLA2322=y
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -350,6 +358,7 @@
 CONFIG_MD_RAID5=y
 # CONFIG_MD_RAID6 is not set
 CONFIG_MD_MULTIPATH=y
+# CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
@@ -399,6 +408,8 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 CONFIG_IPV6=m
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_INET6_AH is not set
@@ -478,6 +489,7 @@
 # CONFIG_IXGB is not set
 CONFIG_S2IO=m
 # CONFIG_S2IO_NAPI is not set
+# CONFIG_2BUFF_MODE is not set
 
 #
 # Token Ring devices
@@ -554,6 +566,8 @@
 CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
 # CONFIG_SYNCLINK is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
@@ -664,6 +678,7 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -671,6 +686,10 @@
 # CONFIG_USB_BLUETOOTH_TTY is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 # CONFIG_USB_STORAGE is not set
 
 #
@@ -700,7 +719,6 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -712,7 +730,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -734,7 +752,6 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -754,6 +771,20 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_MTHCA=m
+# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -864,7 +895,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -958,6 +989,7 @@
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 # CONFIG_IA64_PRINT_HAZARDS is not set
@@ -994,7 +1026,12 @@
 # CONFIG_CRYPTO_TEA is not set
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff -Nru a/arch/ia64/defconfig b/arch/ia64/defconfig
--- a/arch/ia64/defconfig	2005-01-19 13:44:45 -08:00
+++ b/arch/ia64/defconfig	2005-01-19 13:44:45 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1
-# Tue Nov  2 11:47:56 2004
+# Linux kernel version: 2.6.10
+# Thu Jan  6 11:13:13 2005
 #
 
 #
@@ -59,6 +59,7 @@
 CONFIG_64BIT=y
 CONFIG_MMU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
@@ -90,6 +91,7 @@
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
@@ -111,8 +113,10 @@
 CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_VIDEO=m
 CONFIG_ACPI_FAN=m
 CONFIG_ACPI_PROCESSOR=m
+CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=m
 CONFIG_ACPI_NUMA=y
 CONFIG_ACPI_BLACKLIST_YEAR=0
@@ -121,6 +125,7 @@
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
+CONFIG_ACPI_CONTAINER=m
 
 #
 # Bus options (PCI, PCMCIA)
@@ -176,6 +181,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNP is not set
 
 #
 # Block devices
@@ -189,8 +195,10 @@
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CDROM_PKTCDVD is not set
 
@@ -288,6 +296,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -328,7 +337,6 @@
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -345,6 +353,7 @@
 CONFIG_MD_RAID5=m
 CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
@@ -395,6 +404,7 @@
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_TUNNEL is not set
 CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -573,6 +583,7 @@
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 
 #
@@ -601,6 +612,7 @@
 CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
+# CONFIG_MOXA_SMARTIO is not set
 # CONFIG_SYNCLINK is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
@@ -651,7 +663,7 @@
 CONFIG_AGP=m
 CONFIG_AGP_I460=m
 CONFIG_AGP_HP_ZX1=m
-CONFIG_DRM=y
+CONFIG_DRM=m
 CONFIG_DRM_TDFX=m
 CONFIG_DRM_R128=m
 CONFIG_DRM_RADEON=m
@@ -810,6 +822,7 @@
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -819,6 +832,10 @@
 # CONFIG_USB_MIDI is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_RW_DETECT is not set
@@ -858,7 +875,6 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -870,7 +886,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -913,6 +929,20 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_MTHCA=m
+# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1023,7 +1053,7 @@
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1158,7 +1188,12 @@
 # CONFIG_CRYPTO_TEA is not set
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff -Nru a/arch/ia64/hp/common/Makefile b/arch/ia64/hp/common/Makefile
--- a/arch/ia64/hp/common/Makefile	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/hp/common/Makefile	2005-01-19 13:44:47 -08:00
@@ -6,3 +6,5 @@
 #
 
 obj-y := sba_iommu.o
+obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += hwsw_iommu.o
+obj-$(CONFIG_IA64_GENERIC) += hwsw_iommu.o
diff -Nru a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ia64/hp/common/hwsw_iommu.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
+ *   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * This is a pseudo I/O MMU which dispatches to the hardware I/O MMU
+ * whenever possible.  We assume that the hardware I/O MMU requires
+ * full 32-bit addressability, as is the case, e.g., for HP zx1-based
+ * systems (there, the I/O MMU window is mapped at 3-4GB).  If a
+ * device doesn't provide full 32-bit addressability, we fall back on
+ * the sw I/O TLB.  This is good enough to let us support broken
+ * hardware such as soundcards which have a DMA engine that can
+ * address only 28 bits.
+ */
+
+#include <linux/device.h>
+
+#include <asm/machvec.h>
+
+/* swiotlb declarations & definitions: */
+extern void swiotlb_init_with_default_size (size_t size);
+extern ia64_mv_dma_alloc_coherent	swiotlb_alloc_coherent;
+extern ia64_mv_dma_free_coherent	swiotlb_free_coherent;
+extern ia64_mv_dma_map_single		swiotlb_map_single;
+extern ia64_mv_dma_unmap_single		swiotlb_unmap_single;
+extern ia64_mv_dma_map_sg		swiotlb_map_sg;
+extern ia64_mv_dma_unmap_sg		swiotlb_unmap_sg;
+extern ia64_mv_dma_supported		swiotlb_dma_supported;
+extern ia64_mv_dma_mapping_error	swiotlb_dma_mapping_error;
+
+/* hwiommu declarations & definitions: */
+
+extern ia64_mv_dma_alloc_coherent	sba_alloc_coherent;
+extern ia64_mv_dma_free_coherent	sba_free_coherent;
+extern ia64_mv_dma_map_single		sba_map_single;
+extern ia64_mv_dma_unmap_single		sba_unmap_single;
+extern ia64_mv_dma_map_sg		sba_map_sg;
+extern ia64_mv_dma_unmap_sg		sba_unmap_sg;
+extern ia64_mv_dma_supported		sba_dma_supported;
+extern ia64_mv_dma_mapping_error	sba_dma_mapping_error;
+
+#define hwiommu_alloc_coherent		sba_alloc_coherent
+#define hwiommu_free_coherent		sba_free_coherent
+#define hwiommu_map_single		sba_map_single
+#define hwiommu_unmap_single		sba_unmap_single
+#define hwiommu_map_sg			sba_map_sg
+#define hwiommu_unmap_sg		sba_unmap_sg
+#define hwiommu_dma_supported		sba_dma_supported
+#define hwiommu_dma_mapping_error	sba_dma_mapping_error
+#define hwiommu_sync_single_for_cpu	machvec_dma_sync_single
+#define hwiommu_sync_sg_for_cpu		machvec_dma_sync_sg
+#define hwiommu_sync_single_for_device	machvec_dma_sync_single
+#define hwiommu_sync_sg_for_device	machvec_dma_sync_sg
+
+
+/*
+ * Note: we need to make the determination of whether or not to use
+ * the sw I/O TLB based purely on the device structure.  Anything else
+ * would be unreliable or would be too intrusive.
+ */
+static inline int
+use_swiotlb (struct device *dev)
+{
+	return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask);
+}
+
+void
+hwsw_init (void)
+{
+	/* default to a smallish 2MB sw I/O TLB */
+	swiotlb_init_with_default_size (2 * (1<<20));
+}
+
+void *
+hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flags)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
+	else
+		return hwiommu_alloc_coherent(dev, size, dma_handle, flags);
+}
+
+void
+hwsw_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	if (use_swiotlb(dev))
+		swiotlb_free_coherent(dev, size, vaddr, dma_handle);
+	else
+		hwiommu_free_coherent(dev, size, vaddr, dma_handle);
+}
+
+dma_addr_t
+hwsw_map_single (struct device *dev, void *addr, size_t size, int dir)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_map_single(dev, addr, size, dir);
+	else
+		return hwiommu_map_single(dev, addr, size, dir);
+}
+
+void
+hwsw_unmap_single (struct device *dev, dma_addr_t iova, size_t size, int dir)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_unmap_single(dev, iova, size, dir);
+	else
+		return hwiommu_unmap_single(dev, iova, size, dir);
+}
+
+
+int
+hwsw_map_sg (struct device *dev, struct scatterlist *sglist, int nents, int dir)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_map_sg(dev, sglist, nents, dir);
+	else
+		return hwiommu_map_sg(dev, sglist, nents, dir);
+}
+
+void
+hwsw_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, int dir)
+{
+	if (use_swiotlb(dev))
+		return swiotlb_unmap_sg(dev, sglist, nents, dir);
+	else
+		return hwiommu_unmap_sg(dev, sglist, nents, dir);
+}
+
+void
+hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir)
+{
+	if (use_swiotlb(dev))
+		swiotlb_sync_single_for_cpu(dev, addr, size, dir);
+	else
+		hwiommu_sync_single_for_cpu(dev, addr, size, dir);
+}
+
+void
+hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, int dir)
+{
+	if (use_swiotlb(dev))
+		swiotlb_sync_sg_for_cpu(dev, sg, nelems, dir);
+	else
+		hwiommu_sync_sg_for_cpu(dev, sg, nelems, dir);
+}
+
+void
+hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, int dir)
+{
+	if (use_swiotlb(dev))
+		swiotlb_sync_single_for_device(dev, addr, size, dir);
+	else
+		hwiommu_sync_single_for_device(dev, addr, size, dir);
+}
+
+void
+hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, int dir)
+{
+	if (use_swiotlb(dev))
+		swiotlb_sync_sg_for_device(dev, sg, nelems, dir);
+	else
+		hwiommu_sync_sg_for_device(dev, sg, nelems, dir);
+}
+
+int
+hwsw_dma_supported (struct device *dev, u64 mask)
+{
+	if (hwiommu_dma_supported(dev, mask))
+		return 1;
+	return swiotlb_dma_supported(dev, mask);
+}
+
+int
+hwsw_dma_mapping_error (dma_addr_t dma_addr)
+{
+	return hwiommu_dma_mapping_error (dma_addr) || swiotlb_dma_mapping_error(dma_addr);
+}
+
+EXPORT_SYMBOL(hwsw_dma_mapping_error);
+EXPORT_SYMBOL(hwsw_map_single);
+EXPORT_SYMBOL(hwsw_unmap_single);
+EXPORT_SYMBOL(hwsw_map_sg);
+EXPORT_SYMBOL(hwsw_unmap_sg);
+EXPORT_SYMBOL(hwsw_dma_supported);
+EXPORT_SYMBOL(hwsw_alloc_coherent);
+EXPORT_SYMBOL(hwsw_free_coherent);
diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
--- a/arch/ia64/hp/common/sba_iommu.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ia64/hp/common/sba_iommu.c	2005-01-19 13:44:46 -08:00
@@ -1557,7 +1557,7 @@
 	** We program the next pdir index after we stop w/ a key for
 	** the GART code to handshake on.
 	*/
-	while ((device = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device)) != NULL)
+	for_each_pci_dev(device)	
 		agp_found |= pci_find_capability(device, PCI_CAP_ID_AGP);
 
 	if (agp_found && reserve_sba_gart) {
diff -Nru a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
--- a/arch/ia64/hp/sim/simeth.c	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/hp/sim/simeth.c	2005-01-19 13:44:47 -08:00
@@ -286,7 +286,7 @@
 static int
 simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
 {
-	struct net_device *dev = (struct net_device *)ptr;
+	struct net_device *dev = ptr;
 	struct simeth_local *local;
 	struct in_device *in_dev;
 	struct in_ifaddr **ifap = NULL;
@@ -382,7 +382,7 @@
 static int
 simeth_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct simeth_local *local = (struct simeth_local *)dev->priv;
+	struct simeth_local *local = dev->priv;
 
 #if 0
 	/* ensure we have at least ETH_ZLEN bytes (min frame size) */
@@ -446,7 +446,7 @@
 	int			len;
 	int			rcv_count = SIMETH_RECV_MAX;
 
-	local = (struct simeth_local *)dev->priv;
+	local = dev->priv;
 	/*
 	 * the loop concept has been borrowed from other drivers
 	 * looks to me like it's a throttling thing to avoid pushing to many
@@ -515,7 +515,7 @@
 static struct net_device_stats *
 simeth_get_stats(struct net_device *dev)
 {
-	struct simeth_local  *local = (struct simeth_local *) dev->priv;
+	struct simeth_local *local = dev->priv;
 
 	return &local->stats;
 }
diff -Nru a/arch/ia64/hp/zx1/Makefile b/arch/ia64/hp/zx1/Makefile
--- a/arch/ia64/hp/zx1/Makefile	2005-01-19 13:44:48 -08:00
+++ b/arch/ia64/hp/zx1/Makefile	2005-01-19 13:44:48 -08:00
@@ -5,4 +5,4 @@
 # Copyright (C) Alex Williamson (alex_williamson@hp.com)
 #
 
-obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o
+obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o hpzx1_swiotlb_machvec.o
diff -Nru a/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c b/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,3 @@
+#define MACHVEC_PLATFORM_NAME		hpzx1_swiotlb
+#define MACHVEC_PLATFORM_HEADER		<asm/machvec_hpzx1_swiotlb.h>
+#include <asm/machvec_init.h>
diff -Nru a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
--- a/arch/ia64/ia32/ia32_entry.S	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/ia32/ia32_entry.S	2005-01-19 13:44:47 -08:00
@@ -387,7 +387,7 @@
 	data8 sys32_rt_sigaction
 	data8 sys32_rt_sigprocmask /* 175 */
 	data8 sys_rt_sigpending
-	data8 compat_rt_sigtimedwait
+	data8 compat_sys_rt_sigtimedwait
 	data8 sys32_rt_sigqueueinfo
 	data8 sys32_rt_sigsuspend
 	data8 sys32_pread	  /* 180 */
diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
--- a/arch/ia64/ia32/sys_ia32.c	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/ia32/sys_ia32.c	2005-01-19 13:44:47 -08:00
@@ -1873,6 +1873,10 @@
 					    compat_ptr(data));
 		break;
 
+	      case PTRACE_GETEVENTMSG:   
+		ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));
+		break;
+
 	      case PTRACE_SYSCALL:	/* continue, stop after next syscall */
 	      case PTRACE_CONT:		/* restart after signal. */
 	      case PTRACE_KILL:
diff -Nru a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
--- a/arch/ia64/kernel/Makefile	2005-01-19 13:44:48 -08:00
+++ b/arch/ia64/kernel/Makefile	2005-01-19 13:44:48 -08:00
@@ -12,6 +12,7 @@
 obj-$(CONFIG_IA64_BRL_EMU)	+= brl_emu.o
 obj-$(CONFIG_IA64_GENERIC)	+= acpi-ext.o
 obj-$(CONFIG_IA64_HP_ZX1)	+= acpi-ext.o
+obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acpi-ext.o
 obj-$(CONFIG_IA64_PALINFO)	+= palinfo.o
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
 obj-$(CONFIG_MODULES)		+= module.o
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ia64/kernel/acpi.c	2005-01-19 13:44:46 -08:00
@@ -113,6 +113,8 @@
 	return "hpsim";
 # elif defined (CONFIG_IA64_HP_ZX1)
 	return "hpzx1";
+# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
+	return "hpzx1_swiotlb";
 # elif defined (CONFIG_IA64_SGI_SN2)
 	return "sn2";
 # elif defined (CONFIG_IA64_DIG)
diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
--- a/arch/ia64/kernel/head.S	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/kernel/head.S	2005-01-19 13:44:47 -08:00
@@ -65,10 +65,27 @@
 	;;
 	/*
 	 * Initialize kernel region registers:
+	 *	rr[0]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[1]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[2]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[3]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[4]: VHPT enabled, page size = PAGE_SHIFT
 	 *	rr[5]: VHPT enabled, page size = PAGE_SHIFT
 	 *	rr[6]: VHPT disabled, page size = IA64_GRANULE_SHIFT
 	 *	rr[7]: VHPT disabled, page size = IA64_GRANULE_SHIFT
+	 * We initialize all of them to prevent inadvertently assuming
+	 * something about the state of address translation early in boot.
 	 */
+	mov r6=((ia64_rid(IA64_REGION_ID_KERNEL, (0<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r7=(0<<61)
+	mov r8=((ia64_rid(IA64_REGION_ID_KERNEL, (1<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r9=(1<<61)
+	mov r10=((ia64_rid(IA64_REGION_ID_KERNEL, (2<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r11=(2<<61)
+	mov r12=((ia64_rid(IA64_REGION_ID_KERNEL, (3<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r13=(3<<61)
+	mov r14=((ia64_rid(IA64_REGION_ID_KERNEL, (4<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r15=(4<<61)
 	mov r16=((ia64_rid(IA64_REGION_ID_KERNEL, (5<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
 	movl r17=(5<<61)
 	mov r18=((ia64_rid(IA64_REGION_ID_KERNEL, (6<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
@@ -76,6 +93,11 @@
 	mov r20=((ia64_rid(IA64_REGION_ID_KERNEL, (7<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
 	movl r21=(7<<61)
 	;;
+	mov rr[r7]=r6
+	mov rr[r9]=r8
+	mov rr[r11]=r10
+	mov rr[r13]=r12
+	mov rr[r15]=r14
 	mov rr[r17]=r16
 	mov rr[r19]=r18
 	mov rr[r21]=r20
diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
--- a/arch/ia64/kernel/mca.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ia64/kernel/mca.c	2005-01-19 13:44:46 -08:00
@@ -1133,6 +1133,7 @@
 	pal_min_state_area_t *ms;
 
 	oops_in_progress = 1;	/* avoid deadlock in printk, but it makes recovery dodgy */
+	console_loglevel = 15;	/* make sure printks make it to console */
 
 	printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
 		ia64_sal_to_os_handoff_state.proc_state_param);
diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
--- a/arch/ia64/kernel/setup.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ia64/kernel/setup.c	2005-01-19 13:44:46 -08:00
@@ -1,7 +1,7 @@
 /*
  * Architecture-specific setup.
  *
- * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
  * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
@@ -312,7 +312,28 @@
 	io_port_init();
 
 #ifdef CONFIG_IA64_GENERIC
-	machvec_init(acpi_get_sysname());
+	{
+		const char *mvec_name = strstr (*cmdline_p, "machvec=");
+		char str[64];
+
+		if (mvec_name) {
+			const char *end;
+			size_t len;
+
+			mvec_name += 8;
+			end = strchr (mvec_name, ' ');
+			if (end)
+				len = end - mvec_name;
+			else
+				len = strlen (mvec_name);
+			len = min(len, sizeof (str) - 1);
+			strncpy (str, mvec_name, len);
+			str[len] = '\0';
+			mvec_name = str;
+		} else
+			mvec_name = acpi_get_sysname();
+		machvec_init(mvec_name);
+	}
 #endif
 
 	if (early_console_setup(*cmdline_p) == 0)
diff -Nru a/arch/ia64/lib/csum_partial_copy.c b/arch/ia64/lib/csum_partial_copy.c
--- a/arch/ia64/lib/csum_partial_copy.c	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/lib/csum_partial_copy.c	2005-01-19 13:44:47 -08:00
@@ -105,8 +105,8 @@
 extern unsigned long do_csum(const unsigned char *, long);
 
 static unsigned int
-do_csum_partial_copy_from_user (const char __user *src, char *dst, int len,
-				unsigned int psum, int *errp)
+do_csum_partial_copy_from_user (const unsigned char __user *src, unsigned char *dst,
+				int len, unsigned int psum, int *errp)
 {
 	unsigned long result;
 
@@ -129,8 +129,8 @@
 }
 
 unsigned int
-csum_partial_copy_from_user (const char __user *src, char *dst, int len,
-			     unsigned int sum, int *errp)
+csum_partial_copy_from_user (const unsigned char __user *src, unsigned char *dst,
+			     int len, unsigned int sum, int *errp)
 {
 	if (!access_ok(VERIFY_READ, src, len)) {
 		*errp = -EFAULT;
@@ -142,7 +142,8 @@
 }
 
 unsigned int
-csum_partial_copy_nocheck(const char __user *src, char *dst, int len, unsigned int sum)
+csum_partial_copy_nocheck(const unsigned char __user *src, unsigned char *dst,
+			  int len, unsigned int sum)
 {
 	return do_csum_partial_copy_from_user(src, dst, len, sum, NULL);
 }
diff -Nru a/arch/ia64/lib/swiotlb.c b/arch/ia64/lib/swiotlb.c
--- a/arch/ia64/lib/swiotlb.c	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/lib/swiotlb.c	2005-01-19 13:44:47 -08:00
@@ -61,9 +61,8 @@
 /*
  * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and
  * io_tlb_end.  This is command line adjustable via setup_io_tlb_npages.
- * Default to 64MB.
  */
-static unsigned long io_tlb_nslabs = 32768;
+static unsigned long io_tlb_nslabs;
 
 /*
  * When the IOMMU overflows we return a fallback buffer. This sets the size.
@@ -113,10 +112,15 @@
  * structures for the software IO TLB used to implement the PCI DMA API.
  */
 void
-swiotlb_init(void)
+swiotlb_init_with_default_size (size_t default_size)
 {
 	unsigned long i;
 
+	if (!io_tlb_nslabs) {
+		io_tlb_nslabs = (default_size >> PAGE_SHIFT);
+		io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
+	}
+
 	/*
 	 * Get IO TLB memory from the low pages
 	 */
@@ -145,6 +149,12 @@
 	       virt_to_phys(io_tlb_start), virt_to_phys(io_tlb_end));
 }
 
+void
+swiotlb_init (void)
+{
+	swiotlb_init_with_default_size(64 * (1<<20));	/* default to 64MB */
+}
+
 static inline int
 address_needs_mapping(struct device *hwdev, dma_addr_t addr)
 {
@@ -347,8 +357,8 @@
 
 	/* Confirm address can be DMA'd by device */
 	if (address_needs_mapping(hwdev, dev_addr)) {
-		printk("hwdev DMA mask = 0x%016lx, dev_addr = 0x%016lx\n",
-		       *hwdev->dma_mask, dev_addr);
+		printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016lx\n",
+		       (unsigned long long)*hwdev->dma_mask, dev_addr);
 		panic("swiotlb_alloc_coherent: allocated memory is out of "
 		      "range for device");
 	}
diff -Nru a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
--- a/arch/ia64/pci/pci.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ia64/pci/pci.c	2005-01-19 13:44:46 -08:00
@@ -6,6 +6,7 @@
  * Copyright (C) 2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Bjorn Helgaas <bjorn_helgaas@hp.com>
+ * Copyright (C) 2004 Silicon Graphics, Inc.
  *
  * Note: Above list of copyright holders is incomplete...
  */
@@ -131,6 +132,19 @@
 	.write = pci_write,
 };
 
+#ifdef CONFIG_NUMA
+extern acpi_status acpi_map_iosapic(acpi_handle, u32, void *, void **);
+static void acpi_map_iosapics(void)
+{
+	acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
+}
+#else
+static void acpi_map_iosapics(void)
+{
+	return;
+}
+#endif /* CONFIG_NUMA */
+
 static int __init
 pci_acpi_init (void)
 {
@@ -138,11 +152,7 @@
 
 	printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
 
-#ifdef CONFIG_NUMA
-extern acpi_status acpi_map_iosapic (acpi_handle, u32, void*, void**);
-
-	acpi_get_devices(NULL, acpi_map_iosapic, NULL, NULL);
-#endif
+	acpi_map_iosapics();
 
 	if (pci_routeirq) {
 		/*
@@ -154,7 +164,7 @@
 		printk(KERN_INFO "** was specified.  If this was required to make a driver work,\n");
 		printk(KERN_INFO "** please email the output of \"lspci\" to bjorn.helgaas@hp.com\n");
 		printk(KERN_INFO "** so I can fix the driver.\n");
-		while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+		for_each_pci_dev(dev)
 			acpi_pci_irq_enable(dev);
 	} else {
 		printk(KERN_INFO "** PCI interrupts are no longer routed automatically.  If this\n");
@@ -367,6 +377,7 @@
 	region->start = res->start - offset;
 	region->end = res->end - offset;
 }
+EXPORT_SYMBOL(pcibios_resource_to_bus);
 
 void pcibios_bus_to_resource(struct pci_dev *dev,
 		struct resource *res, struct pci_bus_region *region)
@@ -526,7 +537,7 @@
 	 * Leave vm_pgoff as-is, the PCI space address is the physical
 	 * address on this platform.
 	 */
-	vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
+	vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO);
 
 	if (write_combine)
 		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
@@ -538,6 +549,117 @@
 		return -EAGAIN;
 
 	return 0;
+}
+
+/**
+ * ia64_pci_get_legacy_mem - generic legacy mem routine
+ * @bus: bus to get legacy memory base address for
+ *
+ * Find the base of legacy memory for @bus.  This is typically the first
+ * megabyte of bus address space for @bus or is simply 0 on platforms whose
+ * chipsets support legacy I/O and memory routing.  Returns the base address
+ * or an error pointer if an error occurred.
+ *
+ * This is the ia64 generic version of this routine.  Other platforms
+ * are free to override it with a machine vector.
+ */
+char *ia64_pci_get_legacy_mem(struct pci_bus *bus)
+{
+	return (char *)__IA64_UNCACHED_OFFSET;
+}
+
+/**
+ * pci_mmap_legacy_page_range - map legacy memory space to userland
+ * @bus: bus whose legacy space we're mapping
+ * @vma: vma passed in by mmap
+ *
+ * Map legacy memory space for this device back to userspace using a machine
+ * vector to get the base address.
+ */
+int
+pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma)
+{
+	char *addr;
+
+	addr = pci_get_legacy_mem(bus);
+	if (IS_ERR(addr))
+		return PTR_ERR(addr);
+
+	vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT;
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	vma->vm_flags |= (VM_SHM | VM_RESERVED | VM_IO);
+
+	if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			    vma->vm_end - vma->vm_start, vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+/**
+ * ia64_pci_legacy_read - read from legacy I/O space
+ * @bus: bus to read
+ * @port: legacy port value
+ * @val: caller allocated storage for returned value
+ * @size: number of bytes to read
+ *
+ * Simply reads @size bytes from @port and puts the result in @val.
+ *
+ * Again, this (and the write routine) are generic versions that can be
+ * overridden by the platform.  This is necessary on platforms that don't
+ * support legacy I/O routing or that hard fail on legacy I/O timeouts.
+ */
+int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
+{
+	int ret = size;
+
+	switch (size) {
+	case 1:
+		*val = inb(port);
+		break;
+	case 2:
+		*val = inw(port);
+		break;
+	case 4:
+		*val = inl(port);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/**
+ * ia64_pci_legacy_write - perform a legacy I/O write
+ * @bus: bus pointer
+ * @port: port to write
+ * @val: value to write
+ * @size: number of bytes to write from @val
+ *
+ * Simply writes @size bytes of @val to @port.
+ */
+int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size)
+{
+	int ret = 0;
+
+	switch (size) {
+	case 1:
+		outb(val, port);
+		break;
+	case 2:
+		outw(val, port);
+		break;
+	case 4:
+		outl(val, port);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
 }
 
 /**
diff -Nru a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c
--- a/arch/ia64/sn/kernel/bte_error.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ia64/sn/kernel/bte_error.c	2005-01-19 13:44:46 -08:00
@@ -47,6 +47,7 @@
 	ii_icrb0_d_u_t icrbd;	/* II CRB Register D */
 	ii_ibcr_u_t ibcr;
 	ii_icmr_u_t icmr;
+	ii_ieclr_u_t ieclr;
 
 	BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda,
 		    smp_processor_id()));
@@ -131,6 +132,14 @@
 	imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
 	REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
 
+	/* Clear BTE0/1 error bits */
+	ieclr.ii_ieclr_regval = 0;
+	if (err_nodepda->bte_if[0].bh_error != BTE_SUCCESS)
+		ieclr.ii_ieclr_fld_s.i_e_bte_0 = 1;
+	if (err_nodepda->bte_if[1].bh_error != BTE_SUCCESS)
+		ieclr.ii_ieclr_fld_s.i_e_bte_1 = 1;
+	REMOTE_HUB_S(nasid, IIO_IECLR, ieclr.ii_ieclr_regval);
+
 	/* Reinitialize both BTE state machines. */
 	ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR);
 	ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
@@ -152,7 +161,7 @@
 		err_nodepda->bte_if[i].cleanup_active = 0;
 		BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda,
 			    smp_processor_id(), i));
-		spin_unlock(&pda->cpu_bte_if[i]->spinlock);
+		spin_unlock(&err_nodepda->bte_if[i].spinlock);
 	}
 
 	del_timer(recovery_timer);
diff -Nru a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
--- a/arch/ia64/sn/kernel/io_init.c	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/sn/kernel/io_init.c	2005-01-19 13:44:47 -08:00
@@ -202,7 +202,7 @@
 	struct pci_dev *host_pci_dev;
 	int status = 0;
 
-	SN_PCIDEV_INFO(dev) = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
+	dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
 	if (SN_PCIDEV_INFO(dev) <= 0)
 		BUG();		/* Cannot afford to run out of memory */
 	memset(SN_PCIDEV_INFO(dev), 0, sizeof(struct pcidev_info));
@@ -310,8 +310,8 @@
 	 * after this point.
 	 */
 
-	PCI_CONTROLLER(bus) = controller;
-	SN_PCIBUS_BUSSOFT(bus) = provider_soft;
+	bus->sysdata = controller;
+	PCI_CONTROLLER(bus)->platform_data = provider_soft;
 
 	nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base);
 	cnode = nasid_to_cnodeid(nasid);
diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
--- a/arch/ia64/sn/kernel/setup.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ia64/sn/kernel/setup.c	2005-01-19 13:44:46 -08:00
@@ -505,15 +505,15 @@
 
 	/* Setup ionodes with memory */
 	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
-		u64 klgraph_header;
+		char *klgraph_header;
 		cnodeid_t cnodeid;
 
 		if (physical_node_map[nasid] == -1)
 			continue;
 
-		klgraph_header = cnodeid = -1;
-		klgraph_header = ia64_sn_get_klconfig_addr(nasid);
-		if (klgraph_header <= 0) {
+		cnodeid = -1;
+		klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
+		if (!klgraph_header) {
 			if (IS_RUNNING_ON_SIMULATOR())
 				continue;
 			BUG();	/* All nodes must have klconfig tables! */
diff -Nru a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c	2005-01-19 13:44:47 -08:00
@@ -530,8 +530,7 @@
 	}
 
 error:
-	if (p)
-		vfree(p);
+	vfree(p);
 
 	lock_kernel();
 	return r;
@@ -642,7 +641,6 @@
 {
 	struct seq_file *seq = file->private_data;
 
-	if (seq->private)
-		vfree(seq->private);
+	vfree(seq->private);
 	return seq_release(inode, file);
 }
diff -Nru a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
--- a/arch/ia64/sn/pci/pci_dma.c	2005-01-19 13:44:47 -08:00
+++ b/arch/ia64/sn/pci/pci_dma.c	2005-01-19 13:44:47 -08:00
@@ -475,3 +475,67 @@
 EXPORT_SYMBOL(sn_pci_free_consistent);
 EXPORT_SYMBOL(sn_pci_dma_supported);
 EXPORT_SYMBOL(sn_dma_mapping_error);
+
+char *sn_pci_get_legacy_mem(struct pci_bus *bus)
+{
+	if (!SN_PCIBUS_BUSSOFT(bus))
+		return ERR_PTR(-ENODEV);
+
+	return (char *)(SN_PCIBUS_BUSSOFT(bus)->bs_legacy_mem | __IA64_UNCACHED_OFFSET);
+}
+
+int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
+{
+	unsigned long addr;
+	int ret;
+
+	if (!SN_PCIBUS_BUSSOFT(bus))
+		return -ENODEV;
+
+	addr = SN_PCIBUS_BUSSOFT(bus)->bs_legacy_io | __IA64_UNCACHED_OFFSET;
+	addr += port;
+
+	ret = ia64_sn_probe_mem(addr, (long)size, (void *)val);
+
+	if (ret == 2)
+		return -EINVAL;
+
+	if (ret == 1)
+		*val = -1;
+
+	return size;
+}
+
+int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
+{
+	int ret = size;
+	unsigned long paddr;
+	unsigned long *addr;
+
+	if (!SN_PCIBUS_BUSSOFT(bus)) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	/* Put the phys addr in uncached space */
+	paddr = SN_PCIBUS_BUSSOFT(bus)->bs_legacy_io | __IA64_UNCACHED_OFFSET;
+	paddr += port;
+	addr = (unsigned long *)paddr;
+
+	switch (size) {
+	case 1:
+		*(volatile u8 *)(addr) = (u8)(val);
+		break;
+	case 2:
+		*(volatile u16 *)(addr) = (u16)(val);
+		break;
+	case 4:
+		*(volatile u32 *)(addr) = (u32)(val);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+ out:
+	return ret;
+}
diff -Nru a/arch/m32r/lib/csum_partial_copy.c b/arch/m32r/lib/csum_partial_copy.c
--- a/arch/m32r/lib/csum_partial_copy.c	2005-01-19 13:44:45 -08:00
+++ b/arch/m32r/lib/csum_partial_copy.c	2005-01-19 13:44:45 -08:00
@@ -3,16 +3,16 @@
  *		operating system.  INET is implemented using the  BSD Socket
  *		interface as the means of communication with the user level.
  *
- *		MIPS specific IP/TCP/UDP checksumming routines
+ *		M32R specific IP/TCP/UDP checksumming routines
+ *		(Some code taken from MIPS architecture)
  *
- * Authors:	Ralf Baechle, <ralf@waldorf-gmbh.de>
- *		Lots of code moved from tcp.c and ip.c; see those files
- *		for more names.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
+ * Copyright (C) 1994, 1995  Waldorf Electronics GmbH
+ * Copyright (C) 1998, 1999  Ralf Baechle
+ * Copyright (C) 2001-2005  Hiroyuki Kondo, Hirokazu Takata
  *
  */
 
@@ -27,8 +27,9 @@
 /*
  * Copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy_nocheck (const char *src, char *dst,
-                                        int len, unsigned int sum)
+unsigned int
+csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst,
+                           int len, unsigned int sum)
 {
 	sum = csum_partial(src, len, sum);
 	memcpy(dst, src, len);
@@ -41,9 +42,10 @@
  * Copy from userspace and compute checksum.  If we catch an exception
  * then zero the rest of the buffer.
  */
-unsigned int csum_partial_copy_from_user (const char __user *src, char *dst,
-                                          int len, unsigned int sum,
-                                          int *err_ptr)
+unsigned int
+csum_partial_copy_from_user (const unsigned char __user *src,
+			     unsigned char *dst,
+			     int len, unsigned int sum, int *err_ptr)
 {
 	int missing;
 
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/m68k/Kconfig	2005-01-19 13:44:47 -08:00
@@ -385,8 +385,8 @@
 	bool "Support for ST-RAM as swap space"
 	depends on ATARI && BROKEN
 	---help---
-	  Some Atari 68k macines (including the 520STF and 1020STE) divide
-	  their addressible memory into ST and TT sections.  The TT section
+	  Some Atari 68k machines (including the 520STF and 1020STE) divide
+	  their addressable memory into ST and TT sections.  The TT section
 	  (up to 512MB) is the main memory; the ST section (up to 4MB) is
 	  accessible to the built-in graphics board, runs slower, and is
 	  present mainly for backward compatibility with older machines.
diff -Nru a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c
--- a/arch/m68k/lib/checksum.c	2005-01-19 13:44:48 -08:00
+++ b/arch/m68k/lib/checksum.c	2005-01-19 13:44:48 -08:00
@@ -134,8 +134,8 @@
  */
 
 unsigned int
-csum_partial_copy_from_user(const char *src, char *dst, int len,
-			    int sum, int *csum_err)
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+			    int len, int sum, int *csum_err)
 {
 	/*
 	 * GCC doesn't like more than 10 operands for the asm
@@ -326,7 +326,7 @@
  */
 
 unsigned int
-csum_partial_copy_nocheck(const char *src, char *dst, int len, int sum)
+csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, int sum)
 {
 	unsigned long tmp1, tmp2;
 	__asm__("movel %2,%4\n\t"
diff -Nru a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c
--- a/arch/m68knommu/lib/checksum.c	2005-01-19 13:44:48 -08:00
+++ b/arch/m68knommu/lib/checksum.c	2005-01-19 13:44:48 -08:00
@@ -140,7 +140,8 @@
  */
 
 unsigned int
-csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+			    int len, int sum, int *csum_err)
 {
 	if (csum_err) *csum_err = 0;
 	memcpy(dst, src, len);
@@ -152,7 +153,7 @@
  */
 
 unsigned int
-csum_partial_copy(const char *src, char *dst, int len, int sum)
+csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum)
 {
 	memcpy(dst, src, len);
 	return csum_partial(dst, len, sum);
diff -Nru a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
--- a/arch/mips/kernel/irixelf.c	2005-01-19 13:44:48 -08:00
+++ b/arch/mips/kernel/irixelf.c	2005-01-19 13:44:48 -08:00
@@ -127,7 +127,9 @@
 	end = PAGE_ALIGN(end);
 	if (end <= start)
 		return;
+	down_write(&current->mm->mmap_sem);
 	do_brk(start, end - start);
+	up_write(&current->mm->mmap_sem);
 }
 
 
@@ -375,7 +377,9 @@
 
 	/* Map the last of the bss segment */
 	if (last_bss > len) {
+		down_write(&current->mm->mmap_sem);
 		do_brk(len, (last_bss - len));
+		up_write(&current->mm->mmap_sem);
 	}
 	kfree(elf_phdata);
 
@@ -562,7 +566,9 @@
 	unsigned long v;
 	struct prda *pp;
 
+	down_write(&current->mm->mmap_sem);
 	v =  do_brk (PRDA_ADDRESS, PAGE_SIZE);
+	up_write(&current->mm->mmap_sem);
 
 	if (v < 0)
 		return;
@@ -852,8 +858,11 @@
 
 	len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
 	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
-	if (bss > len)
+	if (bss > len) {
+	  down_write(&current->mm->mmap_sem);
 	  do_brk(len, bss-len);
+	  up_write(&current->mm->mmap_sem);
+	}
 	kfree(elf_phdata);
 	return 0;
 }
diff -Nru a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
--- a/arch/mips/kernel/irixsig.c	2005-01-19 13:44:47 -08:00
+++ b/arch/mips/kernel/irixsig.c	2005-01-19 13:44:47 -08:00
@@ -13,7 +13,6 @@
 #include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/ptrace.h>
-#include <linux/suspend.h>
 
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
@@ -179,10 +178,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
--- a/arch/mips/kernel/scall64-n32.S	2005-01-19 13:44:47 -08:00
+++ b/arch/mips/kernel/scall64-n32.S	2005-01-19 13:44:47 -08:00
@@ -243,7 +243,7 @@
 	PTR	sys_capget
 	PTR	sys_capset
 	PTR	sys32_rt_sigpending		/* 6125 */
-	PTR	compat_rt_sigtimedwait
+	PTR	compat_sys_rt_sigtimedwait
 	PTR	sys32_rt_sigqueueinfo
 	PTR	sys32_rt_sigsuspend
 	PTR	sys32_sigaltstack
diff -Nru a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
--- a/arch/mips/kernel/scall64-o32.S	2005-01-19 13:44:45 -08:00
+++ b/arch/mips/kernel/scall64-o32.S	2005-01-19 13:44:45 -08:00
@@ -420,7 +420,7 @@
 	PTR	sys32_rt_sigaction
 	PTR	sys32_rt_sigprocmask 		/* 4195 */
 	PTR	sys32_rt_sigpending
-	PTR	compat_rt_sigtimedwait
+	PTR	compat_sys_rt_sigtimedwait
 	PTR	sys32_rt_sigqueueinfo
 	PTR	sys32_rt_sigsuspend
 	PTR	sys32_pread			/* 4200 */
diff -Nru a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
--- a/arch/mips/kernel/signal.c	2005-01-19 13:44:48 -08:00
+++ b/arch/mips/kernel/signal.c	2005-01-19 13:44:48 -08:00
@@ -18,7 +18,6 @@
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/ptrace.h>
-#include <linux/suspend.h>
 #include <linux/unistd.h>
 #include <linux/compiler.h>
 
@@ -577,10 +576,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
--- a/arch/mips/kernel/signal32.c	2005-01-19 13:44:46 -08:00
+++ b/arch/mips/kernel/signal32.c	2005-01-19 13:44:46 -08:00
@@ -773,10 +773,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/parisc/Kconfig	2005-01-19 13:44:47 -08:00
@@ -39,6 +39,12 @@
 config GENERIC_ISA_DMA
 	bool
 
+config GENERIC_HARDIRQS
+	def_bool y
+
+config GENERIC_IRQ_PROBE
+	def_bool y
+
 # unless you want to implement ACPI on PA-RISC ... ;-)
 config PM
 	bool
diff -Nru a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
--- a/arch/parisc/configs/712_defconfig	2005-01-19 13:44:48 -08:00
+++ b/arch/parisc/configs/712_defconfig	2005-01-19 13:44:48 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:20:32 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -9,37 +11,50 @@
 #
 # Code maturity level options
 #
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=15
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_KMOD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
 
 #
 # Processor type and features
@@ -47,10 +62,12 @@
 # CONFIG_PA7000 is not set
 CONFIG_PA7100LC=y
 # CONFIG_PA7200 is not set
+# CONFIG_PA7300LC is not set
 # CONFIG_PA8X00 is not set
 CONFIG_PA11=y
 # CONFIG_64BIT is not set
 # CONFIG_SMP is not set
+# CONFIG_DISCONTIGMEM is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_HPUX is not set
 
@@ -61,17 +78,30 @@
 # CONFIG_HPPB is not set
 # CONFIG_IOMMU_CCIO is not set
 CONFIG_GSC_LASI=y
-CONFIG_GSC_WAX=y
+# CONFIG_GSC_WAX is not set
 # CONFIG_EISA is not set
 # CONFIG_PCI is not set
-# CONFIG_CHASSIS_LCD_LED is not set
+CONFIG_CHASSIS_LCD_LED=y
 # CONFIG_PDC_CHASSIS is not set
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
+CONFIG_BINFMT_MISC=m
 
 #
 # Device Drivers
@@ -80,7 +110,10 @@
 #
 # Generic Driver Options
 #
-CONFIG_DEBUG_DRIVER=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -91,9 +124,10 @@
 # Parallel port support
 #
 CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_CML1=y
-# CONFIG_PARPORT_SERIAL is not set
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_PC_CML1=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
 CONFIG_PARPORT_GSC=y
 # CONFIG_PARPORT_OTHER is not set
 # CONFIG_PARPORT_1284 is not set
@@ -110,7 +144,20 @@
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=y
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=6144
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -137,7 +184,6 @@
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 # CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 
@@ -145,31 +191,33 @@
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_MEM_MAPPED=y
 CONFIG_53C700_LE_ON_BE=y
 # CONFIG_SCSI_ZALON is not set
-# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_DEBUG=m
 
 #
 # Multi-device support (RAID and LVM)
 #
 CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_MD_RAID5=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+# CONFIG_MD_RAID10 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_RAID6 is not set
 # CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
 
 #
@@ -197,49 +245,151 @@
 CONFIG_PACKET_MMAP=y
 CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
+CONFIG_NET_KEY=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
-# CONFIG_DECNET is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+# CONFIG_IP_NF_NAT_LOCAL is not set
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
-# CONFIG_NETFILTER is not set
 # CONFIG_VLAN_8021Q is not set
-# CONFIG_LLC2 is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+CONFIG_LLC2=m
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
 
 #
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
 #
-# CONFIG_NET_PKTGEN is not set
+CONFIG_NET_PKTGEN=m
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
 # CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+CONFIG_TUN=m
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=m
 CONFIG_LASI_82596=y
 
 #
@@ -249,14 +399,10 @@
 #
 # Ethernet (10000 Mbit)
 #
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_SLIP is not set
+
+#
+# Token Ring devices
+#
 
 #
 # Wireless LAN (non-hamradio)
@@ -267,32 +413,24 @@
 # Obsolete Wireless cards support (pre-802.11)
 #
 # CONFIG_STRIP is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_ATMEL is not set
 
 #
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
 
 #
 # ISDN subsystem
@@ -318,7 +456,7 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 
 #
@@ -327,33 +465,33 @@
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
 CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PARKBD is not set
 CONFIG_SERIO_GSCPS2=y
-# CONFIG_HP_SDC is not set
+CONFIG_HP_SDC=y
+CONFIG_HIL_MLC=y
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
+# CONFIG_KEYBOARD_ATKBD_RDI_KEYCODES is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_HIL_OLD is not set
 # CONFIG_KEYBOARD_HIL is not set
 CONFIG_INPUT_MOUSE=y
-# CONFIG_MOUSE_PS2 is not set
-# CONFIG_MOUSE_SERIAL is not set
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_SERIAL=m
 # CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_HIL is not set
+CONFIG_MOUSE_HIL=m
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_HP_SDC_RTC is not set
+# CONFIG_INPUT_MISC is not set
 
 #
 # Character devices
@@ -368,7 +506,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -380,17 +518,16 @@
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_MUX is not set
-# CONFIG_PDC_CONSOLE is not set
+CONFIG_PDC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-CONFIG_PRINTER=y
+CONFIG_LEGACY_PTY_COUNT=64
+CONFIG_PRINTER=m
 # CONFIG_LP_CONSOLE is not set
-# CONFIG_PPDEV is not set
+CONFIG_PPDEV=m
 # CONFIG_TIPAR is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -402,18 +539,17 @@
 #
 # CONFIG_WATCHDOG is not set
 CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
+CONFIG_GEN_RTC_X=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=256
 
 #
 # I2C support
@@ -421,6 +557,11 @@
 # CONFIG_I2C is not set
 
 #
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
 # Misc devices
 #
 
@@ -438,40 +579,86 @@
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
 CONFIG_FB_STI=y
 # CONFIG_FB_VIRTUAL is not set
 
 #
 # Console display driver support
 #
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_STI_CONSOLE=y
-CONFIG_DUMMY_CONSOLE_COLUMNS=160
-CONFIG_DUMMY_CONSOLE_ROWS=64
+CONFIG_DUMMY_CONSOLE_COLUMNS=128
+CONFIG_DUMMY_CONSOLE_ROWS=48
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
-# CONFIG_FONTS is not set
+CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
 
 #
 # Logo configuration
 #
 CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
-CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_PARISC_CLUT224=y
 
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_SEQUENCER=y
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# GSC devices
+#
+CONFIG_SND_HARMONY=y
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
 
 #
 # USB support
 #
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 
 #
 # USB Gadget Support
@@ -479,6 +666,11 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -488,13 +680,22 @@
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
+CONFIG_JFS_FS=m
+# CONFIG_JFS_POSIX_ACL is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_SECURITY is not set
+# CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -502,12 +703,17 @@
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_FAT_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -515,38 +721,63 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_TMPFS_SECURITY is not set
+# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
 #
 # Miscellaneous filesystems
 #
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
 # CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
-CONFIG_NFSD=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
+CONFIG_EXPORTFS=m
 CONFIG_SUNRPC=y
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
@@ -559,85 +790,102 @@
 #
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
 
 #
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_FRAME_POINTER=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 
 #
 # Security options
 #
-CONFIG_SECURITY=y
-# CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=y
-# CONFIG_SECURITY_SELINUX is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
 
 #
 # Library routines
 #
-# CONFIG_CRC32 is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff -Nru a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
--- a/arch/parisc/configs/a500_defconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/parisc/configs/a500_defconfig	2005-01-19 13:44:46 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:22:34 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -13,10 +15,12 @@
 # CONFIG_CLEAN_COMPILE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -25,6 +29,7 @@
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_EMBEDDED=y
@@ -33,11 +38,13 @@
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
 
 #
 # Loadable module support
@@ -47,6 +54,7 @@
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 
@@ -64,10 +72,10 @@
 CONFIG_64BIT=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
-# CONFIG_DISCONTIGMEM is not set
+CONFIG_DISCONTIGMEM=y
 # CONFIG_PREEMPT is not set
 CONFIG_COMPAT=y
-CONFIG_NR_CPUS=4
+CONFIG_NR_CPUS=8
 
 #
 # Bus options (PCI, PCMCIA, EISA, GSC, ISA)
@@ -84,15 +92,21 @@
 CONFIG_PDC_CHASSIS=y
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
 #
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+# CONFIG_PCMCIA_OBSOLETE is not set
 CONFIG_PCMCIA=m
-CONFIG_PCMCIA_DEBUG=y
-CONFIG_YENTA=m
 CONFIG_CARDBUS=y
-# CONFIG_PD6729 is not set
-# CONFIG_I82092 is not set
-# CONFIG_TCIC is not set
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=m
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_TCIC=m
 
 #
 # PCI Hotplug Support
@@ -113,9 +127,9 @@
 # Generic Driver Options
 #
 # CONFIG_STANDALONE is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-CONFIG_DEBUG_DRIVER=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -144,8 +158,19 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -192,7 +217,8 @@
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
@@ -216,6 +242,7 @@
 CONFIG_SCSI_QLOGIC_FC=m
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=m
+# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 # CONFIG_SCSI_QLA22XX is not set
@@ -230,9 +257,9 @@
 #
 # PCMCIA SCSI adapter support
 #
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
 
 #
 # Multi-device support (RAID and LVM)
@@ -242,9 +269,11 @@
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_MD_RAID6 is not set
 # CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
 
 #
@@ -252,7 +281,6 @@
 #
 CONFIG_FUSION=m
 CONFIG_FUSION_MAX_SGE=40
-CONFIG_FUSION_ISENSE=m
 CONFIG_FUSION_CTL=m
 
 #
@@ -293,6 +321,9 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 
 #
 # IP: Virtual Server Configuration
@@ -306,6 +337,9 @@
 # IP: Netfilter Configuration
 #
 CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
 CONFIG_IP_NF_FTP=m
 CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_TFTP=m
@@ -330,8 +364,17 @@
 CONFIG_IP_NF_MATCH_STATE=m
 CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -349,18 +392,15 @@
 CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_MARK=m
 CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 # CONFIG_IP_NF_COMPAT_IPCHAINS is not set
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=m
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -381,7 +421,6 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
@@ -434,7 +473,7 @@
 # CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
 CONFIG_PCMCIA_XIRCOM=m
-CONFIG_PCMCIA_XIRTULIP=m
+# CONFIG_PCMCIA_XIRTULIP is not set
 CONFIG_HP100=m
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
@@ -461,7 +500,6 @@
 # CONFIG_SUNDANCE is not set
 CONFIG_VIA_RHINE=m
 CONFIG_VIA_RHINE_MMIO=y
-# CONFIG_VIA_VELOCITY is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -476,6 +514,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 
 #
@@ -500,13 +539,13 @@
 # Obsolete Wireless cards support (pre-802.11)
 #
 # CONFIG_STRIP is not set
-CONFIG_PCMCIA_WAVELAN=m
+# CONFIG_PCMCIA_WAVELAN is not set
 CONFIG_PCMCIA_NETWAVE=m
 
 #
 # Wireless 802.11 Frequency Hopping cards support
 #
-# CONFIG_PCMCIA_RAYCS is not set
+CONFIG_PCMCIA_RAYCS=m
 
 #
 # Wireless 802.11b ISA/PCI cards support
@@ -522,7 +561,7 @@
 #
 CONFIG_PCMCIA_HERMES=m
 CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_PCMCIA_WL3501=m
 
 #
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
@@ -615,7 +654,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
@@ -633,7 +672,6 @@
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -695,7 +733,6 @@
 #
 # Console display driver support
 #
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_DUMMY_CONSOLE=y
@@ -709,6 +746,12 @@
 # USB support
 #
 # CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 
 #
 # USB Gadget Support
@@ -716,6 +759,11 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -729,6 +777,7 @@
 # CONFIG_JFS_POSIX_ACL is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
@@ -737,8 +786,9 @@
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -807,13 +857,14 @@
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
 CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -878,16 +929,19 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_RWLOCK is not set
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_RWLOCK is not set
 
 #
 # Security options
 #
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 # CONFIG_SECURITY is not set
 
 #
@@ -901,6 +955,7 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -908,11 +963,12 @@
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_TEST=m
 
diff -Nru a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
--- a/arch/parisc/configs/b180_defconfig	2005-01-19 13:44:48 -08:00
+++ b/arch/parisc/configs/b180_defconfig	2005-01-19 13:44:48 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:35:54 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -11,19 +13,20 @@
 #
 # CONFIG_EXPERIMENTAL is not set
 CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
@@ -31,11 +34,13 @@
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
 
 #
 # Loadable module support
@@ -43,6 +48,7 @@
 CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
 CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 
 #
@@ -91,8 +97,9 @@
 #
 # Generic Driver Options
 #
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_DEBUG_DRIVER=y
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -129,6 +136,19 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -174,12 +194,15 @@
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
@@ -190,6 +213,7 @@
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
@@ -240,6 +264,7 @@
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID5=y
 # CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
 
 #
@@ -284,6 +309,9 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -446,6 +474,7 @@
 CONFIG_SERIO_GSCPS2=y
 # CONFIG_HP_SDC is not set
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
@@ -507,7 +536,6 @@
 # CONFIG_LP_CONSOLE is not set
 # CONFIG_PPDEV is not set
 # CONFIG_TIPAR is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -527,7 +555,6 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -560,6 +587,8 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -611,6 +640,12 @@
 # USB support
 #
 # CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 
 #
 # USB Gadget Support
@@ -618,6 +653,11 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -632,8 +672,9 @@
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -658,6 +699,7 @@
 CONFIG_SYSFS=y
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
@@ -665,7 +707,6 @@
 # Miscellaneous filesystems
 #
 # CONFIG_HFSPLUS_FS is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -745,18 +786,21 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 CONFIG_SECURITY=y
 # CONFIG_SECURITY_NETWORK is not set
 CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_SECLVL is not set
 # CONFIG_SECURITY_SELINUX is not set
 
 #
@@ -770,6 +814,7 @@
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_DES is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
@@ -779,6 +824,8 @@
 # CONFIG_CRYPTO_CAST6 is not set
 # CONFIG_CRYPTO_TEA is not set
 # CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
diff -Nru a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
--- a/arch/parisc/configs/c3000_defconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/parisc/configs/c3000_defconfig	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:26:49 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -11,13 +13,13 @@
 #
 CONFIG_EXPERIMENTAL=y
 # CONFIG_CLEAN_COMPILE is not set
-# CONFIG_STANDALONE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
@@ -26,18 +28,22 @@
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
 
 #
 # Loadable module support
@@ -47,6 +53,7 @@
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
@@ -62,6 +69,7 @@
 # CONFIG_PARISC64 is not set
 # CONFIG_64BIT is not set
 # CONFIG_SMP is not set
+# CONFIG_DISCONTIGMEM is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_HPUX is not set
 
@@ -80,14 +88,13 @@
 # CONFIG_PDC_CHASSIS is not set
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
 #
-CONFIG_PCMCIA=m
-CONFIG_PCMCIA_DEBUG=y
-CONFIG_YENTA=m
-CONFIG_CARDBUS=y
-# CONFIG_I82092 is not set
-# CONFIG_TCIC is not set
 
 #
 # PCI Hotplug Support
@@ -107,8 +114,10 @@
 #
 # Generic Driver Options
 #
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_FW_LOADER=y
-CONFIG_DEBUG_DRIVER=y
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -135,8 +144,20 @@
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -147,16 +168,14 @@
 #
 # Please see Documentation/ide.txt for help/info on IDE drives
 #
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=m
 # CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_IDEDISK_STROKE=y
-# CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
 # CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
 
 #
 # IDE chipset support/bugfixes
@@ -170,7 +189,6 @@
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 # CONFIG_IDEDMA_PCI_AUTO is not set
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
@@ -217,7 +235,6 @@
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_REPORT_LUNS=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
 
@@ -231,6 +248,7 @@
 # SCSI low-level drivers
 #
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
@@ -238,14 +256,18 @@
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
 CONFIG_SCSI_SATA=y
+# CONFIG_SCSI_SATA_AHCI is not set
 # CONFIG_SCSI_SATA_SVW is not set
 CONFIG_SCSI_ATA_PIIX=m
+# CONFIG_SCSI_SATA_NV is not set
 CONFIG_SCSI_SATA_PROMISE=m
 # CONFIG_SCSI_SATA_SX4 is not set
 CONFIG_SCSI_SATA_SIL=m
 # CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
 CONFIG_SCSI_SATA_VIA=m
 # CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
@@ -270,6 +292,7 @@
 CONFIG_SCSI_QLOGIC_FC=m
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=m
+# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 # CONFIG_SCSI_QLA22XX is not set
@@ -283,15 +306,6 @@
 CONFIG_SCSI_DEBUG=m
 
 #
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-CONFIG_PCMCIA_QLOGIC=m
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
 # Multi-device support (RAID and LVM)
 #
 CONFIG_MD=y
@@ -299,18 +313,22 @@
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_MD_RAID6 is not set
 CONFIG_MD_MULTIPATH=y
+# CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=y
 # CONFIG_DM_CRYPT is not set
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
 
 #
 # Fusion MPT device support
 #
 CONFIG_FUSION=m
 CONFIG_FUSION_MAX_SGE=40
-CONFIG_FUSION_ISENSE=m
 CONFIG_FUSION_CTL=m
 
 #
@@ -351,6 +369,9 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 
 #
 # IP: Virtual Server Configuration
@@ -364,6 +385,9 @@
 # IP: Netfilter Configuration
 #
 CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
 CONFIG_IP_NF_FTP=m
 CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_TFTP=m
@@ -388,8 +412,16 @@
 CONFIG_IP_NF_MATCH_STATE=m
 CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+# CONFIG_IP_NF_MATCH_SCTP is not set
+# CONFIG_IP_NF_MATCH_COMMENT is not set
+# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -407,15 +439,12 @@
 CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_MARK=m
 CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_RAW is not set
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_COMPAT_IPFWADM=m
-# CONFIG_IP_NF_RAW is not set
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -436,12 +465,12 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -480,13 +509,11 @@
 CONFIG_DE2104X=m
 CONFIG_TULIP=y
 # CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
+CONFIG_TULIP_MMIO=y
 # CONFIG_TULIP_NAPI is not set
-CONFIG_DE4X5=m
-CONFIG_WINBOND_840=m
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
-CONFIG_PCMCIA_XIRCOM=m
-CONFIG_PCMCIA_XIRTULIP=m
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
@@ -528,6 +555,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 
 #
@@ -548,19 +576,6 @@
 # CONFIG_NET_RADIO is not set
 
 #
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
-
-#
 # Wan interfaces
 #
 # CONFIG_WAN is not set
@@ -614,6 +629,7 @@
 CONFIG_SERIO=m
 CONFIG_SERIO_SERPORT=m
 # CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
@@ -624,13 +640,10 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_HIL_OLD is not set
-# CONFIG_KEYBOARD_HIL is not set
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_HIL is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
@@ -648,7 +661,6 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_CS=m
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
@@ -667,7 +679,6 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -687,14 +698,8 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
 
@@ -704,6 +709,11 @@
 # CONFIG_I2C is not set
 
 #
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
 # Misc devices
 #
 
@@ -721,6 +731,8 @@
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -733,6 +745,7 @@
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
@@ -745,13 +758,11 @@
 #
 # Console display driver support
 #
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_STI_CONSOLE=y
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
@@ -792,6 +803,9 @@
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -799,6 +813,7 @@
 # CONFIG_USB_EHCI_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -808,8 +823,13 @@
 # CONFIG_USB_MIDI is not set
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_RW_DETECT is not set
 CONFIG_USB_STORAGE_DATAFAB=y
 CONFIG_USB_STORAGE_FREECOM=y
 # CONFIG_USB_STORAGE_ISD200 is not set
@@ -820,7 +840,7 @@
 CONFIG_USB_STORAGE_JUMPSHOT=y
 
 #
-# USB Human Interface Devices (HID)
+# USB Input Devices
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
@@ -852,7 +872,7 @@
 #
 
 #
-# USB Network adaptors
+# USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
@@ -881,15 +901,25 @@
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_TEST is not set
 
 #
+# USB ATM/DSL drivers
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -908,8 +938,9 @@
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -925,6 +956,8 @@
 CONFIG_FAT_FS=m
 CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -936,6 +969,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -974,6 +1008,7 @@
 CONFIG_EXPORTFS=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
@@ -1014,6 +1049,7 @@
 # CONFIG_NLS_ISO8859_8 is not set
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
 # CONFIG_NLS_ISO8859_1 is not set
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -1039,14 +1075,17 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -1060,6 +1099,7 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 # CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
 CONFIG_CRYPTO_DES=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -1067,7 +1107,10 @@
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
+# CONFIG_CRYPTO_TEA is not set
 # CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
@@ -1076,6 +1119,7 @@
 #
 # Library routines
 #
+CONFIG_CRC_CCITT=m
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
diff -Nru a/arch/parisc/configs/n4000_defconfig b/arch/parisc/configs/n4000_defconfig
--- a/arch/parisc/configs/n4000_defconfig	2005-01-19 13:44:48 -08:00
+++ b/arch/parisc/configs/n4000_defconfig	2005-01-19 13:44:48 -08:00
@@ -1,5 +1,7 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10-pa5
+# Wed Jan  5 13:40:36 2005
 #
 CONFIG_PARISC=y
 CONFIG_MMU=y
@@ -11,13 +13,13 @@
 #
 CONFIG_EXPERIMENTAL=y
 # CONFIG_CLEAN_COMPILE is not set
-# CONFIG_STANDALONE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
+CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -26,18 +28,22 @@
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
 
 #
 # Loadable module support
@@ -47,6 +53,7 @@
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
 #
@@ -81,14 +88,13 @@
 # CONFIG_PDC_CHASSIS is not set
 
 #
-# PCMCIA/CardBus support
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
 #
-CONFIG_PCMCIA=m
-CONFIG_PCMCIA_DEBUG=y
-CONFIG_YENTA=m
-CONFIG_CARDBUS=y
-# CONFIG_I82092 is not set
-# CONFIG_TCIC is not set
 
 #
 # PCI Hotplug Support
@@ -108,8 +114,10 @@
 #
 # Generic Driver Options
 #
-# CONFIG_FW_LOADER is not set
-CONFIG_DEBUG_DRIVER=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -136,10 +144,23 @@
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=6144
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -179,13 +200,15 @@
 # SCSI low-level drivers
 #
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
@@ -209,6 +232,7 @@
 CONFIG_SCSI_QLOGIC_FC=m
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=m
+# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 # CONFIG_SCSI_QLA22XX is not set
@@ -221,13 +245,6 @@
 CONFIG_SCSI_DEBUG=m
 
 #
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
 # Multi-device support (RAID and LVM)
 #
 CONFIG_MD=y
@@ -235,9 +252,11 @@
 CONFIG_MD_LINEAR=y
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
+# CONFIG_MD_RAID10 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_MD_RAID6 is not set
 # CONFIG_MD_MULTIPATH is not set
+# CONFIG_MD_FAULTY is not set
 # CONFIG_BLK_DEV_DM is not set
 
 #
@@ -245,7 +264,6 @@
 #
 CONFIG_FUSION=m
 CONFIG_FUSION_MAX_SGE=40
-CONFIG_FUSION_ISENSE=m
 CONFIG_FUSION_CTL=m
 
 #
@@ -286,6 +304,9 @@
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 
 #
 # IP: Virtual Server Configuration
@@ -299,6 +320,9 @@
 # IP: Netfilter Configuration
 #
 CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
 CONFIG_IP_NF_FTP=m
 CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_TFTP=m
@@ -323,8 +347,16 @@
 CONFIG_IP_NF_MATCH_STATE=m
 CONFIG_IP_NF_MATCH_CONNTRACK=m
 CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -342,16 +374,13 @@
 CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_MARK=m
 CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 # CONFIG_IP_NF_COMPAT_IPCHAINS is not set
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_RAW=m
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 
@@ -372,13 +401,12 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
 
 #
 # Network testing
@@ -424,8 +452,6 @@
 # CONFIG_DE4X5 is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
-CONFIG_PCMCIA_XIRCOM=m
-CONFIG_PCMCIA_XIRTULIP=m
 CONFIG_HP100=m
 CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
@@ -466,6 +492,7 @@
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 
 #
@@ -490,18 +517,10 @@
 # Obsolete Wireless cards support (pre-802.11)
 #
 # CONFIG_STRIP is not set
-CONFIG_PCMCIA_WAVELAN=m
-CONFIG_PCMCIA_NETWAVE=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
 
 #
 # Wireless 802.11b ISA/PCI cards support
 #
-# CONFIG_AIRO is not set
 CONFIG_HERMES=m
 CONFIG_PLX_HERMES=m
 CONFIG_TMD_HERMES=m
@@ -509,32 +528,12 @@
 # CONFIG_ATMEL is not set
 
 #
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
-
-#
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
 #
 # CONFIG_PRISM54 is not set
 CONFIG_NET_WIRELESS=y
 
 #
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-# CONFIG_PCMCIA_FMVJ18X is not set
-# CONFIG_PCMCIA_PCNET is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_PCMCIA_AXNET is not set
-
-#
 # Wan interfaces
 #
 # CONFIG_WAN is not set
@@ -606,7 +605,6 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
 CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
@@ -624,7 +622,6 @@
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -644,14 +641,8 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
 
@@ -661,6 +652,11 @@
 # CONFIG_I2C is not set
 
 #
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
 # Misc devices
 #
 
@@ -682,7 +678,6 @@
 #
 # Console display driver support
 #
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE_COLUMNS=160
 CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_DUMMY_CONSOLE=y
@@ -696,6 +691,12 @@
 # USB support
 #
 # CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 
 #
 # USB Gadget Support
@@ -703,6 +704,11 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -716,6 +722,7 @@
 # CONFIG_JFS_POSIX_ACL is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=m
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
@@ -724,8 +731,9 @@
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -734,6 +742,7 @@
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
 CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
@@ -741,6 +750,8 @@
 CONFIG_FAT_FS=m
 CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -752,6 +763,7 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
@@ -792,11 +804,14 @@
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -835,6 +850,7 @@
 # CONFIG_NLS_ISO8859_8 is not set
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_ISO8859_2=m
 CONFIG_NLS_ISO8859_3=m
@@ -860,15 +876,17 @@
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -882,6 +900,7 @@
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -889,7 +908,10 @@
 CONFIG_CRYPTO_AES=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
 # CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 CONFIG_CRYPTO_CRC32C=m
@@ -898,6 +920,7 @@
 #
 # Library routines
 #
+CONFIG_CRC_CCITT=m
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
diff -Nru a/arch/parisc/hpux/entry_hpux.S b/arch/parisc/hpux/entry_hpux.S
--- a/arch/parisc/hpux/entry_hpux.S	2005-01-19 13:44:46 -08:00
+++ b/arch/parisc/hpux/entry_hpux.S	2005-01-19 13:44:46 -08:00
@@ -227,7 +227,7 @@
 	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_unimplemented_wrapper)      /* 195 */
 	ENTRY_NAME(hpux_statfs)
-	ENTRY_NAME(hpux_unimplemented_wrapper)
+	ENTRY_NAME(hpux_fstatfs)
 	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(hpux_unimplemented_wrapper)
 	ENTRY_NAME(sys_waitpid)	/* 200 */
diff -Nru a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
--- a/arch/parisc/hpux/sys_hpux.c	2005-01-19 13:44:46 -08:00
+++ b/arch/parisc/hpux/sys_hpux.c	2005-01-19 13:44:46 -08:00
@@ -22,14 +22,16 @@
  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/file.h>
 #include <linux/fs.h>
+#include <linux/namei.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/utsname.h>
-#include <linux/vmalloc.h>
 #include <linux/vfs.h>
+#include <linux/vmalloc.h>
 
 #include <asm/errno.h>
 #include <asm/pgalloc.h>
@@ -65,7 +67,6 @@
 
 int hpux_setpgrp(void)
 {
-	extern int sys_setpgid(int, int);
 	return sys_setpgid(0,0);
 }
 
@@ -133,7 +134,7 @@
  *  aid in porting forward if and when sys_ustat() is changed from
  *  its form in kernel 2.2.5.
  */
-static int hpux_ustat(dev_t dev, struct hpux_ustat *ubuf)
+static int hpux_ustat(dev_t dev, struct hpux_ustat __user *ubuf)
 {
 	struct super_block *s;
 	struct hpux_ustat tmp;  /* Changed to hpux_ustat */
@@ -148,14 +149,13 @@
 	if (err)
 		goto out;
 
-	memset(&tmp,0,sizeof(struct hpux_ustat));  /* Changed to hpux_ustat */
+	memset(&tmp,0,sizeof(tmp));
 
 	tmp.f_tfree = (int32_t)sbuf.f_bfree;
 	tmp.f_tinode = (u_int32_t)sbuf.f_ffree;
 	tmp.f_blksize = (u_int32_t)sbuf.f_bsize;  /*  Added this line  */
 
-	/* Changed to hpux_ustat:  */
-	err = copy_to_user(ubuf,&tmp,sizeof(struct hpux_ustat)) ? -EFAULT : 0;
+	err = copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 out:
 	return err;
 }
@@ -185,37 +185,62 @@
      int16_t f_pad;
 };
 
-/* hpux statfs */
-int hpux_statfs(const char *path, struct hpux_statfs *buf)
+static int vfs_statfs_hpux(struct super_block *sb, struct hpux_statfs *buf)
 {
-	int error;
-	int len;
-	char *kpath;
-
-	len = strlen_user((char *)path); 
-
-	kpath = (char *) kmalloc(len+1, GFP_KERNEL);
-	if ( !kpath ) {
-	printk(KERN_DEBUG "failed to kmalloc kpath\n");
-	return 0;
-	}
+	struct kstatfs st;
+	int retval;
+	
+	retval = vfs_statfs(sb, &st);
+	if (retval)
+		return retval;
+
+	memset(buf, 0, sizeof(*buf));
+	buf->f_type = st.f_type;
+	buf->f_bsize = st.f_bsize;
+	buf->f_blocks = st.f_blocks;
+	buf->f_bfree = st.f_bfree;
+	buf->f_bavail = st.f_bavail;
+	buf->f_files = st.f_files;
+	buf->f_ffree = st.f_ffree;
+	buf->f_fsid[0] = st.f_fsid.val[0];
+	buf->f_fsid[1] = st.f_fsid.val[1];
 
-	if ( copy_from_user(kpath, (char *)path, len+1) ) {
-	printk(KERN_DEBUG "failed to copy_from_user kpath\n");
-	kfree(kpath);
 	return 0;
-	}
-
-	printk(KERN_DEBUG "hpux_statfs(\"%s\",-)\n", kpath);
+}
 
-	kfree(kpath);
+/* hpux statfs */
+asmlinkage long hpux_statfs(const char __user *path,
+						struct hpux_statfs __user *buf)
+{
+	struct nameidata nd;
+	int error;
 
-	/* just fake it, beginning of structures match */
-	error = sys_statfs(path, (struct statfs *) buf);
+	error = user_path_walk(path, &nd);
+	if (!error) {
+		struct hpux_statfs tmp;
+		error = vfs_statfs_hpux(nd.dentry->d_inode->i_sb, &tmp);
+		if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+			error = -EFAULT;
+		path_release(&nd);
+	}
+	return error;
+}
 
-	/* ignoring rest of statfs struct, but it should be zeros. Need to do 
-		something with f_fsid[1], which is the fstype for sysfs */
+asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf)
+{
+	struct file *file;
+	struct hpux_statfs tmp;
+	int error;
 
+	error = -EBADF;
+	file = fget(fd);
+	if (!file)
+		goto out;
+	error = vfs_statfs_hpux(file->f_dentry->d_inode->i_sb, &tmp);
+	if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
+		error = -EFAULT;
+	fput(file);
+ out:
 	return error;
 }
 
@@ -671,8 +696,8 @@
 	"setdomainname",         
 	"async_daemon",          
 	"getdirentries",          /* 195 */
-	"statfs",                
-	"fstatfs",               
+	NULL,                
+	NULL,               
 	"vfsmount",              
 	NULL,                    
 	"waitpid",                /* 200 */
diff -Nru a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
--- a/arch/parisc/kernel/cache.c	2005-01-19 13:44:46 -08:00
+++ b/arch/parisc/kernel/cache.c	2005-01-19 13:44:46 -08:00
@@ -55,6 +55,11 @@
 {
 	on_each_cpu((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
 }
+void 
+flush_instruction_cache(void)
+{
+	on_each_cpu((void (*)(void *))flush_instruction_cache_local, NULL, 1, 1);
+}
 #endif
 
 void
@@ -326,4 +331,36 @@
 	purge_tlb_start();
 	__clear_user_page_asm(page, vaddr);
 	purge_tlb_end();
+}
+
+#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
+int parisc_cache_flush_threshold = FLUSH_THRESHOLD;
+
+void parisc_setup_cache_timing(void)
+{
+	unsigned long rangetime, alltime;
+	extern char _text;	/* start of kernel code, defined by linker */
+	extern char _end;	/* end of BSS, defined by linker */
+	unsigned long size;
+
+	alltime = mfctl(16);
+	flush_data_cache();
+	alltime = mfctl(16) - alltime;
+
+	size = (unsigned long)(&_end - _text);
+	rangetime = mfctl(16);
+	flush_kernel_dcache_range((unsigned long)&_text, size);
+	rangetime = mfctl(16) - rangetime;
+
+	printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n",
+		alltime, size, rangetime);
+
+	/* Racy, but if we see an intermediate value, it's ok too... */
+	parisc_cache_flush_threshold = size * alltime / rangetime;
+
+	parisc_cache_flush_threshold = (parisc_cache_flush_threshold + L1_CACHE_BYTES - 1) &~ (L1_CACHE_BYTES - 1); 
+	if (!parisc_cache_flush_threshold)
+		parisc_cache_flush_threshold = FLUSH_THRESHOLD;
+
+	printk("Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus());
 }
diff -Nru a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
--- a/arch/parisc/kernel/drivers.c	2005-01-19 13:44:47 -08:00
+++ b/arch/parisc/kernel/drivers.c	2005-01-19 13:44:47 -08:00
@@ -10,9 +10,21 @@
  * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
  * Copyright (c) 2001 Helge Deller <deller@gmx.de>
  * Copyright (c) 2001,2002 Ryan Bradetich 
+ * Copyright (c) 2004 Thibaut VARENE <varenet@parisc-linux.org>
  * 
  * The file handles registering devices and drivers, then matching them.
  * It's the closest we get to a dating agency.
+ *
+ * If you're thinking about modifying this file, here are some gotchas to
+ * bear in mind:
+ *  - 715/Mirage device paths have a dummy device between Lasi and its children
+ *  - The EISA adapter may show up as a sibling or child of Wax
+ *  - Dino has an optionally functional serial port.  If firmware enables it,
+ *    it shows up as a child of Dino.  If firmware disables it, the buswalk
+ *    finds it and it shows up as a child of Cujo
+ *  - Dino has both parisc and pci devices as children
+ *  - parisc devices are discovered in a random order, including children
+ *    before parents in some cases.
  */
 
 #include <linux/slab.h>
@@ -30,13 +42,16 @@
 struct hppa_dma_ops *hppa_dma_ops;
 EXPORT_SYMBOL(hppa_dma_ops);
 
-static struct parisc_device root;
+static struct device root = {
+	.bus_id = "parisc",
+};
 
-#define for_each_padev(dev) \
-	for (dev = root.child; dev != NULL; dev = next_dev(dev))
+#define for_each_padev(padev) \
+	for (padev = next_dev(&root); padev != NULL; \
+			padev = next_dev(&padev->dev))
 
-#define check_dev(dev) \
-	(dev->id.hw_type != HPHW_FAULTY) ? dev : next_dev(dev)
+#define check_dev(padev) \
+	(padev->id.hw_type != HPHW_FAULTY) ? padev : next_dev(&padev->dev)
 
 /**
  * next_dev - enumerates registered devices
@@ -45,20 +60,20 @@
  * next_dev does a depth-first search of the tree, returning parents
  * before children.  Returns NULL when there are no more devices.
  */
-struct parisc_device *next_dev(struct parisc_device *dev)
+static struct parisc_device *next_dev(struct device *dev)
 {
-	if (dev->child) {
-		return check_dev(dev->child);
-	} else if (dev->sibling) {
-		return dev->sibling;
+	if (!list_empty(&dev->children)) {
+		dev = list_to_dev(dev->children.next);
+		return check_dev(to_parisc_device(dev));
 	}
 
-	/* Exhausted tree at this level, time to go up. */
-	do {
+	while (dev != &root) {
+		if (dev->node.next != &dev->parent->children) {
+			dev = list_to_dev(dev->node.next);
+			return to_parisc_device(dev);
+		}
 		dev = dev->parent;
-		if (dev && dev->sibling)
-			return dev->sibling;
-	} while (dev != &root);
+	}
 
 	return NULL;
 }
@@ -209,24 +224,58 @@
  * Walks up the device tree looking for a device of the specified type.
  * If it finds it, it returns it.  If not, it returns NULL.
  */
-const struct parisc_device *find_pa_parent_type(const struct parisc_device *dev, int type)
+const struct parisc_device *
+find_pa_parent_type(const struct parisc_device *padev, int type)
 {
+	const struct device *dev = &padev->dev;
 	while (dev != &root) {
-		if (dev->id.hw_type == type)
-			return dev;
+		struct parisc_device *candidate = to_parisc_device(dev);
+		if (candidate->id.hw_type == type)
+			return candidate;
 		dev = dev->parent;
 	}
 
 	return NULL;
 }
 
-static void
-get_node_path(struct parisc_device *dev, struct hardware_path *path)
+#ifdef CONFIG_PCI
+static inline int is_pci_dev(struct device *dev)
+{
+	return dev->bus == &pci_bus_type;
+}
+#else
+static inline int is_pci_dev(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+/*
+ * get_node_path fills in @path with the firmware path to the device.
+ * Note that if @node is a parisc device, we don't fill in the 'mod' field.
+ * This is because both callers pass the parent and fill in the mod
+ * themselves.  If @node is a PCI device, we do fill it in, even though this
+ * is inconsistent.
+ */
+static void get_node_path(struct device *dev, struct hardware_path *path)
 {
 	int i = 5;
 	memset(&path->bc, -1, 6);
+
+	if (is_pci_dev(dev)) {
+		unsigned int devfn = to_pci_dev(dev)->devfn;
+		path->mod = PCI_FUNC(devfn);
+		path->bc[i--] = PCI_SLOT(devfn);
+		dev = dev->parent;
+	}
+
 	while (dev != &root) {
-		path->bc[i--] = dev->hw_path;
+		if (is_pci_dev(dev)) {
+			unsigned int devfn = to_pci_dev(dev)->devfn;
+			path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn)<< 5);
+		} else if (dev->bus == &parisc_bus_type) {
+			path->bc[i--] = to_parisc_device(dev)->hw_path;
+		}
 		dev = dev->parent;
 	}
 }
@@ -256,7 +305,7 @@
 {
 	struct hardware_path path;
 
-	get_node_path(dev->parent, &path);
+	get_node_path(dev->dev.parent, &path);
 	path.mod = dev->hw_path;
 	return print_hwpath(&path, output);
 }
@@ -264,33 +313,17 @@
 
 #if defined(CONFIG_PCI) || defined(CONFIG_ISA)
 /**
- * get_pci_node_path - Returns hardware path for PCI devices
- * dev: The device to return the path for
- * output: Pointer to a previously-allocated array to place the path in.
+ * get_pci_node_path - Determines the hardware path for a PCI device
+ * @pdev: The device to return the path for
+ * @path: Pointer to a previously-allocated array to place the path in.
  *
  * This function fills in the hardware_path structure with the route to
  * the specified PCI device.  This structure is suitable for passing to
  * PDC calls.
  */
-void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path)
+void get_pci_node_path(struct pci_dev *pdev, struct hardware_path *path)
 {
-	struct pci_bus *bus;
-	const struct parisc_device *padev;
-	int i = 5;
-
-	memset(&path->bc, -1, 6);
-	path->mod = PCI_FUNC(dev->devfn);
-	path->bc[i--] = PCI_SLOT(dev->devfn);
-	for (bus = dev->bus; bus->parent; bus = bus->parent) {
-		unsigned int devfn = bus->self->devfn;
-		path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
-	}
-
-	padev = HBA_DATA(bus->bridge->platform_data)->dev;
-	while (padev != &root) {
-		path->bc[i--] = padev->hw_path;
-		padev = padev->parent;
-	}
+	get_node_path(&pdev->dev, path);
 }
 EXPORT_SYMBOL(get_pci_node_path);
 
@@ -314,19 +347,43 @@
 
 #endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */
 
+static void setup_bus_id(struct parisc_device *padev)
+{
+	struct hardware_path path;
+	char *output = padev->dev.bus_id;
+	int i;
+
+	get_node_path(padev->dev.parent, &path);
 
-struct parisc_device * create_tree_node(char id, struct parisc_device *parent,
-		struct parisc_device **insert)
+	for (i = 0; i < 6; i++) {
+		if (path.bc[i] == -1)
+			continue;
+		output += sprintf(output, "%u:", (unsigned char) path.bc[i]);
+	}
+	sprintf(output, "%u", (unsigned char) padev->hw_path);
+}
+
+struct parisc_device * create_tree_node(char id, struct device *parent)
 {
 	struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		return NULL;
+
 	memset(dev, 0, sizeof(*dev));
 	dev->hw_path = id;
 	dev->id.hw_type = HPHW_FAULTY;
-	dev->parent = parent;
-	dev->sibling = *insert;
-	*insert = dev;
+
+	dev->dev.parent = parent;
+	setup_bus_id(dev);
+
+	dev->dev.bus = &parisc_bus_type;
+	dev->dma_mask = 0xffffffffUL;	/* PARISC devices are 32-bit */
+
+	/* make the generic dma mask a pointer to the parisc one */
+	dev->dev.dma_mask = &dev->dma_mask;
+	dev->dev.coherent_dma_mask = dev->dma_mask;
+	device_register(&dev->dev);
+
 	return dev;
 }
 
@@ -338,36 +395,27 @@
  * Checks all the children of @parent for a matching @id.  If none
  * found, it allocates a new device and returns it.
  */
-struct parisc_device *
-alloc_tree_node(struct parisc_device *parent, char id)
+static struct parisc_device * alloc_tree_node(struct device *parent, char id)
 {
-	struct parisc_device *prev;
-	if ((!parent->child) || (parent->child->hw_path > id)) {
-		return create_tree_node(id, parent, &parent->child);
-	}
-
-	prev = parent->child;
-	if (prev->hw_path == id)
-		return prev;
+	struct device *dev;
 
-	while (prev->sibling && prev->sibling->hw_path < id) {
-		prev = prev->sibling;
+	list_for_each_entry(dev, &parent->children, node) {
+		struct parisc_device *padev = to_parisc_device(dev);
+		if (padev->hw_path == id)
+			return padev;
 	}
 
-	if ((prev->sibling) && (prev->sibling->hw_path == id))
-		return prev->sibling;
-
-	return create_tree_node(id, parent, &prev->sibling);
+	return create_tree_node(id, parent);
 }
 
-static struct parisc_device *find_parisc_device(struct hardware_path *modpath)
+static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
 {
 	int i;
-	struct parisc_device *parent = &root;
+	struct device *parent = &root;
 	for (i = 0; i < 6; i++) {
 		if (modpath->bc[i] == -1)
 			continue;
-		parent = alloc_tree_node(parent, modpath->bc[i]);
+		parent = &alloc_tree_node(parent, modpath->bc[i])->dev;
 	}
 	return alloc_tree_node(parent, modpath->mod);
 }
@@ -389,7 +437,7 @@
 	if (status != PDC_OK)
 		return NULL;
 
-	dev = find_parisc_device(mod_path);
+	dev = create_parisc_device(mod_path);
 	if (dev->id.hw_type != HPHW_FAULTY) {
 		char p[64];
 		print_pa_hwpath(dev, p);
@@ -414,12 +462,37 @@
 
 static int parisc_generic_match(struct device *dev, struct device_driver *drv)
 {
-	return  match_device(to_parisc_driver(drv), to_parisc_device(dev));
+	return match_device(to_parisc_driver(drv), to_parisc_device(dev));
 }
 
+#define pa_dev_attr(name, field, format_string)				\
+static ssize_t name##_show(struct device *dev, char *buf)		\
+{									\
+	struct parisc_device *padev = to_parisc_device(dev);		\
+	return sprintf(buf, format_string, padev->field);		\
+}
+
+#define pa_dev_attr_id(field, format) pa_dev_attr(field, id.field, format)
+
+pa_dev_attr(irq, irq, "%u\n");
+pa_dev_attr_id(hw_type, "0x%02x\n");
+pa_dev_attr(rev, id.hversion_rev, "0x%x\n");
+pa_dev_attr_id(hversion, "0x%03x\n");
+pa_dev_attr_id(sversion, "0x%05x\n");
+
+static struct device_attribute parisc_device_attrs[] = {
+	__ATTR_RO(irq),
+	__ATTR_RO(hw_type),
+	__ATTR_RO(rev),
+	__ATTR_RO(hversion),
+	__ATTR_RO(sversion),
+	__ATTR_NULL,
+};
+
 struct bus_type parisc_bus_type = {
 	.name = "parisc",
 	.match = parisc_generic_match,
+	.dev_attrs = parisc_device_attrs,
 };
 
 /**
@@ -440,6 +513,104 @@
 	return 0;
 }
 
+/**
+ * match_pci_device - Matches a pci device against a given hardware path
+ * entry.
+ * @dev: the generic device (known to be contained by a pci_dev).
+ * @index: the current BC index
+ * @modpath: the hardware path.
+ * @return: true if the device matches the hardware path.
+ */
+static int match_pci_device(struct device *dev, int index,
+		struct hardware_path *modpath)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int id;
+
+	if (index == 5) {
+		/* we are at the end of the path, and on the actual device */
+		unsigned int devfn = pdev->devfn;
+		return ((modpath->bc[5] == PCI_SLOT(devfn)) &&
+					(modpath->mod == PCI_FUNC(devfn)));
+	}
+
+	id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5);
+	return (modpath->bc[index] == id);
+}
+
+/**
+ * match_parisc_device - Matches a parisc device against a given hardware
+ * path entry.
+ * @dev: the generic device (known to be contained by a parisc_device).
+ * @index: the current BC index
+ * @modpath: the hardware path.
+ * @return: true if the device matches the hardware path.
+ */
+static int match_parisc_device(struct device *dev, int index,
+		struct hardware_path *modpath)
+{
+	struct parisc_device *curr = to_parisc_device(dev);
+	char id = (index == 6) ? modpath->mod : modpath->bc[index];
+
+	return (curr->hw_path == id);
+}
+
+/**
+ * parse_tree_node - returns a device entry in the iotree
+ * @parent: the parent node in the tree
+ * @index: the current BC index
+ * @modpath: the hardware_path struct to match a device against
+ * @return: The corresponding device if found, NULL otherwise.
+ *
+ * Checks all the children of @parent for a matching @id.  If none
+ * found, it returns NULL.
+ */
+static struct device *
+parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
+{
+	struct device *device;
+	 
+	list_for_each_entry(device, &parent->children, node) {
+		if (device->bus == &parisc_bus_type) {
+			if (match_parisc_device(device, index, modpath))
+				return device;
+		} else if (is_pci_dev(device)) {
+			if (match_pci_device(device, index, modpath))
+				return device;
+		} else if (device->bus == NULL) {
+			/* we are on a bus bridge */
+			struct device *new = parse_tree_node(device, index, modpath);
+			if (new)
+				return new;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * hwpath_to_device - Finds the generic device corresponding to a given hardware path.
+ * @modpath: the hardware path.
+ * @return: The target device, NULL if not found.
+ */
+struct device *hwpath_to_device(struct hardware_path *modpath)
+{
+	int i;
+	struct device *parent = &root;
+	for (i = 0; i < 6; i++) {
+		if (modpath->bc[i] == -1)
+			continue;
+		parent = parse_tree_node(parent, i, modpath);
+		if (!parent)
+			return NULL;
+	}
+	if (is_pci_dev(parent)) /* pci devices already parse MOD */
+		return parent;
+	else
+		return parse_tree_node(parent, 6, modpath);
+}
+EXPORT_SYMBOL(hwpath_to_device);
+
 #define BC_PORT_MASK 0x8
 #define BC_LOWER_PORT 0x8
 
@@ -447,7 +618,7 @@
         ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
 
 #define IS_LOWER_PORT(dev) \
-        ((gsc_readl(&((struct bc_module *)dev->hpa)->io_status) \
+        ((gsc_readl(dev->hpa + offsetof(struct bc_module, io_status)) \
                 & BC_PORT_MASK) == BC_LOWER_PORT)
 
 #define MAX_NATIVE_DEVICES 64
@@ -456,11 +627,11 @@
 #define FLEX_MASK 	F_EXTEND(0xfffc0000)
 #define IO_IO_LOW	offsetof(struct bc_module, io_io_low)
 #define IO_IO_HIGH	offsetof(struct bc_module, io_io_high)
-#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_LOW)
-#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_HIGH)
+#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_LOW)
+#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_HIGH)
 
 static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
-                            struct parisc_device *parent);
+                            struct device *parent);
 
 void walk_lower_bus(struct parisc_device *dev)
 {
@@ -477,7 +648,7 @@
 		io_io_high = (READ_IO_IO_HIGH(dev)+ ~FLEX_MASK) & FLEX_MASK;
 	}
 
-	walk_native_bus(io_io_low, io_io_high, dev);
+	walk_native_bus(io_io_low, io_io_high, &dev->dev);
 }
 
 /**
@@ -493,7 +664,7 @@
  * keyboard ports).  This problem is not yet solved.
  */
 static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
-                            struct parisc_device *parent)
+                            struct device *parent)
 {
 	int i, devices_found = 0;
 	unsigned long hpa = io_io_low;
@@ -535,25 +706,6 @@
 			&root);
 }
 
-void fixup_child_irqs(struct parisc_device *parent, int base,
-			int (*choose_irq)(struct parisc_device *))
-{
-	struct parisc_device *dev;
-
-	if (!parent->child)
-		return;
-
-	for (dev = check_dev(parent->child); dev; dev = dev->sibling) {
-		int irq = choose_irq(dev);
-		if (irq > 0) {
-#ifdef __LP64__
-			irq += 32;
-#endif
-			dev->irq = base + irq;
-		}
-	}
-}
-
 static void print_parisc_device(struct parisc_device *dev)
 {
 	char hw_path[64];
@@ -573,68 +725,14 @@
 	printk("\n");
 }
 
-void print_subdevices(struct parisc_device *parent)
-{
-	struct parisc_device *dev;
-	for (dev = parent->child; dev != parent->sibling; dev = next_dev(dev)) {
-		print_parisc_device(dev);
-	}
-}
-
-
-/*
- * parisc_generic_device_register_recursive() - internal function to recursively
- * 	register all parisc devices
- */
-static void parisc_generic_device_register_recursive( struct parisc_device *dev )
-{
-	char tmp1[32];
-	
-	/* has this device been registered already ? */
-	if (dev->dev.dma_mask != NULL)
-		return;
-	
-	/* register all parents recursively */
-	if (dev->parent && dev->parent!=&root)
-		parisc_generic_device_register_recursive(dev->parent);
-	
-	/* set up the generic device tree for this */
-	snprintf(tmp1, sizeof(tmp1), "%d", dev->hw_path);
-	if (dev->parent && dev->parent != &root) {
-		struct parisc_device *ndev;
-		char tmp2[32];
-
-		dev->dev.parent = &dev->parent->dev;
-		for(ndev = dev->parent; ndev != &root;
-		    ndev = ndev->parent) {
-			snprintf(tmp2, sizeof(tmp2), "%d:%s",
-				 ndev->hw_path, tmp1);
-			strlcpy(tmp1, tmp2, sizeof(tmp1));
-		}
-	}
-
-	dev->dev.bus = &parisc_bus_type;
-	snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "parisc%s",
-		 tmp1);
-	/* make the generic dma mask a pointer to the parisc one */
-	dev->dev.dma_mask = &dev->dma_mask;
-	dev->dev.coherent_dma_mask = dev->dma_mask;
-	pr_debug("device_register(%s)\n", dev->dev.bus_id);
-	device_register(&dev->dev);
-}
-
-/*
- * parisc_generic_device_register() - register all parisc devices
+/**
+ * init_parisc_bus - Some preparation to be done before inventory
  */
-void parisc_generic_device_register(void)
+void init_parisc_bus(void)
 {
-	struct parisc_device *dev;
-	
 	bus_register(&parisc_bus_type);
-
-	for_each_padev(dev) {
-		parisc_generic_device_register_recursive( dev );
-	}
+	device_register(&root);
+	get_device(&root);
 }
 
 /**
diff -Nru a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
--- a/arch/parisc/kernel/firmware.c	2005-01-19 13:44:45 -08:00
+++ b/arch/parisc/kernel/firmware.c	2005-01-19 13:44:45 -08:00
@@ -11,6 +11,7 @@
  * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy)
  * Copyright 2003 Grant Grundler <grundler parisc-linux org>
  * Copyright 2003,2004 Ryan Bradetich <rbrad@parisc-linux.org>
+ * Copyright 2004 Thibaut VARENE <varenet@parisc-linux.org>
  *
  *    This program is free software; you can redistribute it and/or modify
  *    it under the terms of the GNU General Public License as published by
@@ -573,14 +574,118 @@
 }
 EXPORT_SYMBOL(pdc_lan_station_id);
 
+/**
+ * pdc_stable_read - Read data from Stable Storage.
+ * @staddr: Stable Storage address to access.
+ * @memaddr: The memory address where Stable Storage data shall be copied.
+ * @count: number of bytes to transfert. count is multiple of 4.
+ *
+ * This PDC call reads from the Stable Storage address supplied in staddr
+ * and copies count bytes to the memory address memaddr.
+ * The call will fail if staddr+count > PDC_STABLE size.
+ */
+int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr,
+               __pa(pdc_result), count);
+       convert_to_wide(pdc_result);
+       memcpy(memaddr, pdc_result, count);
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_read);
+
+/**
+ * pdc_stable_write - Write data to Stable Storage.
+ * @staddr: Stable Storage address to access.
+ * @memaddr: The memory address where Stable Storage data shall be read from.
+ * @count: number of bytes to transfert. count is multiple of 4.
+ *
+ * This PDC call reads count bytes from the supplied memaddr address,
+ * and copies count bytes to the Stable Storage address staddr.
+ * The call will fail if staddr+count > PDC_STABLE size.
+ */
+int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       memcpy(pdc_result, memaddr, count);
+       convert_to_wide(pdc_result);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr,
+               __pa(pdc_result), count);
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_write);
+
+/**
+ * pdc_stable_get_size - Get Stable Storage size in bytes.
+ * @size: pointer where the size will be stored.
+ *
+ * This PDC call returns the number of bytes in the processor's Stable
+ * Storage, which is the number of contiguous bytes implemented in Stable
+ * Storage starting from staddr=0. size in an unsigned 64-bit integer
+ * which is a multiple of four.
+ */
+int pdc_stable_get_size(unsigned long *size)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result));
+       *size = pdc_result[0];
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_get_size);
+
+/**
+ * pdc_stable_verify_contents - Checks that Stable Storage contents are valid.
+ *
+ * This PDC call is meant to be used to check the integrity of the current
+ * contents of Stable Storage.
+ */
+int pdc_stable_verify_contents(void)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS);
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_verify_contents);
+
+/**
+ * pdc_stable_initialize - Sets Stable Storage contents to zero and initialize
+ * the validity indicator.
+ *
+ * This PDC call will erase all contents of Stable Storage. Use with care!
+ */
+int pdc_stable_initialize(void)
+{
+       int retval;
+
+       spin_lock_irq(&pdc_lock);
+       retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE);
+       spin_unlock_irq(&pdc_lock);
+
+       return retval;
+}
+EXPORT_SYMBOL(pdc_stable_initialize);
 
 /**
  * pdc_get_initiator - Get the SCSI Interface Card params (SCSI ID, SDTR, SE or LVD)
  * @hwpath: fully bc.mod style path to the device.
- * @scsi_id: what someone told firmware the ID should be.
- * @period: time in cycles 
- * @width: 8 or 16-bit wide bus
- * @mode: 0,1,2 -> SE,HVD,LVD signalling mode
+ * @initiator: the array to return the result into
  *
  * Get the SCSI operational parameters from PDC.
  * Needed since HPUX never used BIOS or symbios card NVRAM.
@@ -591,8 +696,7 @@
  *    o cable too long (ie SE scsi 10Mhz won't support 6m length),
  *    o bus width exported is less than what the interface chip supports.
  */
-int pdc_get_initiator(struct hardware_path *hwpath, unsigned char *scsi_id,
-		unsigned long *period, char *width, char *mode)
+int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator)
 {
 	int retval;
 
@@ -604,44 +708,38 @@
 
 	retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR, 
 			      __pa(pdc_result), __pa(hwpath));
-
 	if (retval < PDC_OK)
-		goto fail;
-
-	*scsi_id = (unsigned char) pdc_result[0];
+		goto out;
 
-	/* convert Bus speed in Mhz to period (in 1/10 ns) */
-	switch (pdc_result[1]) {
-		/*
-		 * case  0:   driver determines rate
-		 * case -1:   Settings are uninitialized.
-		 */
-		case  5:  *period = 2000; break;
-		case 10:  *period = 1000; break;
-		case 20:  *period = 500; break;
-		case 40:  *period = 250; break;
-		case 80:  *period = 125; break;
-		default: /* Do nothing */ break;
+	if (pdc_result[0] < 16) {
+		initiator->host_id = pdc_result[0];
+	} else {
+		initiator->host_id = -1;
 	}
 
-	/* 
-	 * pdc_result[2]	PDC suggested SCSI id
-	 * pdc_result[3]	PDC suggested SCSI rate
+	/*
+	 * Sprockets and Piranha return 20 or 40 (MT/s).  Prelude returns
+	 * 1, 2, 5 or 10 for 5, 10, 20 or 40 MT/s, respectively
 	 */
+	switch (pdc_result[1]) {
+		case  1: initiator->factor = 50; break;
+		case  2: initiator->factor = 25; break;
+		case  5: initiator->factor = 12; break;
+		case 25: initiator->factor = 10; break;
+		case 20: initiator->factor = 12; break;
+		case 40: initiator->factor = 10; break;
+		default: initiator->factor = -1; break;
+	}
 
 	if (IS_SPROCKETS()) {
-		/* 0 == 8-bit, 1 == 16-bit */
-		*width = (char) pdc_result[4];
-
-		/* ...in case someone needs it in the future.
-		 * sym53c8xx.c comments say it can't autodetect
-		 * for 825/825A/875 chips.
-		 *	0 == SE, 1 == HVD, 2 == LVD
-		 */
-		*mode = (char) pdc_result[5]; 
+		initiator->width = pdc_result[4];
+		initiator->mode = pdc_result[5];
+	} else {
+		initiator->width = -1;
+		initiator->mode = -1;
 	}
 
- fail:
+ out:
 	spin_unlock_irq(&pdc_lock);
 	return (retval >= PDC_OK);
 }
diff -Nru a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
--- a/arch/parisc/kernel/inventory.c	2005-01-19 13:44:45 -08:00
+++ b/arch/parisc/kernel/inventory.c	2005-01-19 13:44:45 -08:00
@@ -518,7 +518,7 @@
 }
 
 /**
- * do_system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
+ * system_map_inventory - Retrieve firmware devices via SYSTEM_MAP.
  *
  * This function attempts to retrieve and register all the devices firmware
  * knows about via the SYSTEM_MAP PDC call.
@@ -528,16 +528,18 @@
 	int i;
 	long status = PDC_OK;
     
-	for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
+	for (i = 0; i < 256; i++) {
 		struct parisc_device *dev;
 		struct pdc_system_map_mod_info module_result;
 		struct pdc_module_path module_path;
 
 		status = pdc_system_map_find_mods(&module_result,
 				&module_path, i);
+		if ((status == PDC_BAD_PROC) || (status == PDC_NE_MOD))
+			break;
 		if (status != PDC_OK)
 			continue;
-		
+
 		dev = alloc_pa_dev(module_result.mod_addr, &module_path.path);
 		if (!dev)
 			continue;
@@ -584,10 +586,10 @@
 
 void __init do_device_inventory(void)
 {
-	extern void parisc_generic_device_register(void);
-
 	printk(KERN_INFO "Searching for devices...\n");
 
+	init_parisc_bus();
+
 	switch (pdc_type) {
 
 	case PDC_TYPE_PAT:
@@ -605,7 +607,6 @@
 	default:
 		panic("Unknown PDC type!\n");
 	}
-	parisc_generic_device_register();
 	printk(KERN_INFO "Found devices:\n");
 	print_parisc_devices();
 }
diff -Nru a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
--- a/arch/parisc/kernel/irq.c	2005-01-19 13:44:46 -08:00
+++ b/arch/parisc/kernel/irq.c	2005-01-19 13:44:46 -08:00
@@ -54,21 +54,19 @@
 #define DBG_IRQ(irq, x)	do { } while (0)
 #endif /* DEBUG_IRQ */
 
-#define EIEM_MASK(irq)       (1UL<<(MAX_CPU_IRQ-IRQ_OFFSET(irq)))
+#define EIEM_MASK(irq)       (1UL<<(CPU_IRQ_MAX - irq))
 
 /* Bits in EIEM correlate with cpu_irq_action[].
 ** Numbered *Big Endian*! (ie bit 0 is MSB)
 */
 static volatile unsigned long cpu_eiem = 0;
 
-static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
-
 static void cpu_set_eiem(void *info)
 {
 	set_eiem((unsigned long) info);
 }
 
-static inline void disable_cpu_irq(void *unused, int irq)
+static inline void cpu_disable_irq(unsigned int irq)
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
@@ -76,7 +74,7 @@
         on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
-static void enable_cpu_irq(void *unused, int irq)
+static void cpu_enable_irq(unsigned int irq)
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
@@ -85,172 +83,56 @@
         on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
-/* mask and disable are the same at the CPU level
-** Difference is enable clears pending interrupts
-*/
-#define mask_cpu_irq	disable_cpu_irq
-
-static inline void unmask_cpu_irq(void *unused, int irq)
+static unsigned int cpu_startup_irq(unsigned int irq)
 {
-	unsigned long eirr_bit = EIEM_MASK(irq);
-	cpu_eiem |= eirr_bit;
-	/* NOTE: sending an IPI will cause do_cpu_irq_mask() to
-	** handle *any* unmasked pending interrupts.
-	** ie We don't need to check for pending interrupts here.
-	*/
-        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+	cpu_enable_irq(irq);
+	return 0;
 }
 
-/*
- * XXX cpu_irq_actions[] will become 2 dimensional for per CPU EIR support.
- * correspond changes needed in:
- * 	processor_probe()	initialize additional action arrays
- * 	request_irq()		handle CPU IRQ region specially
- * 	do_cpu_irq_mask()	index into the matching irq_action array.
- */
-struct irqaction cpu_irq_actions[IRQ_PER_REGION] = {
-	[IRQ_OFFSET(TIMER_IRQ)]	= {
-					.handler = timer_interrupt,
-					.name = "timer",
-				},
-#ifdef CONFIG_SMP
-	[IRQ_OFFSET(IPI_IRQ)]	= {
-					.handler = ipi_interrupt,
-					.name = "IPI",
-				},
-#endif
-};
+void no_ack_irq(unsigned int irq) { }
+void no_end_irq(unsigned int irq) { }
 
-
-struct irq_region cpu0_irq_region = {
-	.ops	= {
-			.disable_irq	= disable_cpu_irq,
-			.enable_irq	= enable_cpu_irq,
-			.mask_irq	= unmask_cpu_irq,
-			.unmask_irq	= unmask_cpu_irq
-	},
-	.data	= {
-			.dev		= &cpu_data[0],
-			.name		= "PARISC-CPU",
-			.irqbase 	= IRQ_FROM_REGION(CPU_IRQ_REGION),
-	},
-	.action	= cpu_irq_actions,
-};
-
-struct irq_region *irq_region[NR_IRQ_REGS] = {
-	[ 0 ]              = NULL, /* reserved for EISA, else causes data page fault (aka code 15) */
-	[ CPU_IRQ_REGION ] = &cpu0_irq_region,
+static struct hw_interrupt_type cpu_interrupt_type = {
+	.typename	= "CPU",
+	.startup	= cpu_startup_irq,
+	.shutdown	= cpu_disable_irq,
+	.enable		= cpu_enable_irq,
+	.disable	= cpu_disable_irq,
+	.ack		= no_ack_irq,
+	.end		= no_end_irq,
+//	.set_affinity	= cpu_set_affinity_irq,
 };
 
-
-/*
-** Generic interfaces that device drivers can use:
-**    mask_irq()	block IRQ
-**    unmask_irq()	re-enable IRQ and trigger if IRQ is pending
-**    disable_irq()	block IRQ
-**    enable_irq()	clear pending and re-enable IRQ
-*/
-
-void mask_irq(int irq)
-{
-	struct irq_region *region;
-
-	DBG_IRQ(irq, ("mask_irq(%d) %d+%d eiem 0x%lx\n", irq,
-				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
-	irq = irq_canonicalize(irq);
-	region = irq_region[IRQ_REGION(irq)];
-	if (region->ops.mask_irq)
-		region->ops.mask_irq(region->data.dev, IRQ_OFFSET(irq));
-}
-
-void unmask_irq(int irq)
-{
-	struct irq_region *region;
-
-	DBG_IRQ(irq, ("unmask_irq(%d) %d+%d eiem 0x%lx\n", irq,
-				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
-	irq = irq_canonicalize(irq);
-	region = irq_region[IRQ_REGION(irq)];
-	if (region->ops.unmask_irq)
-		region->ops.unmask_irq(region->data.dev, IRQ_OFFSET(irq));
-}
-
-void disable_irq(int irq)
-{
-	struct irq_region *region;
-
-	DBG_IRQ(irq, ("disable_irq(%d) %d+%d eiem 0x%lx\n", irq,
-				IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
-	irq = irq_canonicalize(irq);
-	region = irq_region[IRQ_REGION(irq)];
-	if (region->ops.disable_irq)
-		region->ops.disable_irq(region->data.dev, IRQ_OFFSET(irq));
-	else
-		BUG();
-}
-EXPORT_SYMBOL(disable_irq);
-
-void enable_irq(int irq)
-{
-	struct irq_region *region;
-
-	DBG_IRQ(irq, ("enable_irq(%d) %d+%d EIRR 0x%lx EIEM 0x%lx\n", irq,
-				IRQ_REGION(irq), IRQ_OFFSET(irq), mfctl(23), mfctl(15)));
-	irq = irq_canonicalize(irq);
-	region = irq_region[IRQ_REGION(irq)];
-
-	if (region->ops.enable_irq)
-		region->ops.enable_irq(region->data.dev, IRQ_OFFSET(irq));
-	else
-		BUG();
-}
-EXPORT_SYMBOL(enable_irq);
-
 int show_interrupts(struct seq_file *p, void *v)
 {
-#ifdef CONFIG_PROC_FS
-	unsigned int regnr = *(loff_t *) v, i = 0;
+	int i = *(loff_t *) v, j;
+	unsigned long flags;
 
-	if (regnr == 0) {
-		seq_puts(p, "     ");
-#ifdef CONFIG_SMP
-		for (i = 0; i < NR_CPUS; i++)
-			if (cpu_online(i))
-#endif
-				seq_printf(p, "      CPU%02d ", i);
+	if (i == 0) {
+		seq_puts(p, "    ");
+		for_each_online_cpu(j)
+			seq_printf(p, "       CPU%d", j);
 
 #ifdef PARISC_IRQ_CR16_COUNTS
-		seq_printf(p, "[min/avg/max] (CPU cycle counts)");
+		seq_printf(p, " [min/avg/max] (CPU cycle counts)");
 #endif
 		seq_putc(p, '\n');
 	}
 
-	/* We don't need *irqsave lock variants since this is
-	** only allowed to change while in the base context.
-	*/
-	spin_lock(&irq_lock);
-	if (regnr < NR_IRQ_REGS) {
-	    struct irq_region *region = irq_region[regnr];
-
-            if (!region || !region->action)
-		    goto skip;
-
-	    for (i = 0; i <= MAX_CPU_IRQ; i++) {
-		struct irqaction *action = &region->action[i];
-		unsigned int irq_no = IRQ_FROM_REGION(regnr) + i;
-		int j = 0;
-		if (!action->handler)
-			continue;
-
-		seq_printf(p, "%3d: ", irq_no);
+	if (i < NR_IRQS) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		struct irqaction *action = irq_desc[i].action;
+		if (!action)
+			goto skip;
+		seq_printf(p, "%3d: ", i);
 #ifdef CONFIG_SMP
-		for (; j < NR_CPUS; j++)
-			if (cpu_online(j))
+		for_each_online_cpu(j)
+			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#else
+		seq_printf(p, "%10u ", kstat_irqs(i));
 #endif
-		  seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq_no]);
 
-		seq_printf(p, " %14s",
-			    region->data.name ? region->data.name : "N/A");
+		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 #ifndef PARISC_IRQ_CR16_COUNTS
 		seq_printf(p, "  %s", action->name);
 
@@ -281,12 +163,10 @@
 #endif
 
 		seq_putc(p, '\n');
-	    }
+ skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
-  skip:
-	spin_unlock(&irq_lock);
 
-#endif	/* CONFIG_PROC_FS */
 	return 0;
 }
 
@@ -300,34 +180,42 @@
 ** Then use that to get the Transaction address and data.
 */
 
-int
-txn_alloc_irq(void)
+int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data)
 {
-	int irq;
-
-	/* never return irq 0 cause that's the interval timer */
-	for (irq = 1; irq <= MAX_CPU_IRQ; irq++) {
-		if (cpu_irq_actions[irq].handler == NULL) {
-			return (IRQ_FROM_REGION(CPU_IRQ_REGION) + irq);
-		}
+	if (irq_desc[irq].action)
+		return -EBUSY;
+	if (irq_desc[irq].handler != &cpu_interrupt_type)
+		return -EBUSY;
+
+	if (type) {
+		irq_desc[irq].handler = type;
+		irq_desc[irq].handler_data = data;
+		cpu_interrupt_type.enable(irq);
 	}
+	return 0;
+}
 
-	/* unlikely, but be prepared */
-	return -1;
+int txn_claim_irq(int irq)
+{
+	return cpu_claim_irq(irq, NULL, NULL) ? -1 : irq;
 }
 
-int
-txn_claim_irq(int irq)
+int txn_alloc_irq(void)
 {
-	if (irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)].handler ==NULL)
+	int irq;
+
+	/* never return irq 0 cause that's the interval timer */
+	for (irq = CPU_IRQ_BASE + 1; irq <= CPU_IRQ_MAX; irq++) {
+		if (cpu_claim_irq(irq, NULL, NULL) < 0)
+			continue;
 		return irq;
+	}
 
 	/* unlikely, but be prepared */
 	return -1;
 }
 
-unsigned long
-txn_alloc_addr(int virt_irq)
+unsigned long txn_alloc_addr(int virt_irq)
 {
 	static int next_cpu = -1;
 
@@ -364,68 +252,20 @@
 ** I/O subsystem supports more bits than PA2.0 has. The first
 ** case is the problem.
 */
-unsigned int
-txn_alloc_data(int virt_irq, unsigned int bits_wide)
+unsigned int txn_alloc_data(int virt_irq, unsigned int bits_wide)
 {
 	/* XXX FIXME : bits_wide indicates how wide the transaction
 	** data is allowed to be...we may need a different virt_irq
 	** if this one won't work. Another reason to index virtual
 	** irq's into a table which can manage CPU/IRQ bit separately.
 	*/
-	if (IRQ_OFFSET(virt_irq) > (1 << (bits_wide -1)))
-	{
+	if ((virt_irq - CPU_IRQ_BASE) > (1 << (bits_wide - 1))) {
 		panic("Sorry -- didn't allocate valid IRQ for this device\n");
 	}
 
-	return (IRQ_OFFSET(virt_irq));
+	return virt_irq - CPU_IRQ_BASE;
 }
 
-void do_irq(struct irqaction *action, int irq, struct pt_regs * regs)
-{
-	int cpu = smp_processor_id();
-
-	irq_enter();
-	++kstat_cpu(cpu).irqs[irq];
-
-	DBG_IRQ(irq, ("do_irq(%d) %d+%d eiem 0x%lx\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
-
-	for (; action; action = action->next) {
-#ifdef PARISC_IRQ_CR16_COUNTS
-		unsigned long cr_start = mfctl(16);
-#endif
-
-		if (action->handler == NULL) {
-			if (IRQ_REGION(irq) == EISA_IRQ_REGION && irq_region[EISA_IRQ_REGION]) {
-				/* were we called due to autodetecting (E)ISA irqs ? */
-				unsigned int *status;
-				status = &irq_region[EISA_IRQ_REGION]->data.status[IRQ_OFFSET(irq)];
-				if (*status & IRQ_AUTODETECT) {
-					*status &= ~IRQ_WAITING;
-					continue; 
-				}
-			}
-			printk(KERN_ERR "IRQ:  CPU:%d No handler for IRQ %d !\n", cpu, irq);
-			continue;
-		}
-
-		action->handler(irq, action->dev_id, regs);
-
-#ifdef PARISC_IRQ_CR16_COUNTS
-		{
-			unsigned long cr_end = mfctl(16);
-			unsigned long tmp = cr_end - cr_start;
-			/* check for roll over */
-			cr_start = (cr_end < cr_start) ?  -(tmp) : (tmp);
-		}
-		action->cr16_hist[action->cr16_idx++] = (int) cr_start;
-		action->cr16_idx &= PARISC_CR16_HIST_SIZE - 1;
-#endif
-	}
-
-	irq_exit();
-}
-
-
 /* ONLY called from entry.S:intr_extint() */
 void do_cpu_irq_mask(struct pt_regs *regs)
 {
@@ -449,9 +289,12 @@
 	 * 3) Limit the number of times we loop to make sure other
 	 *    processing can occur.
 	 */
-	while ((eirr_val = (mfctl(23) & cpu_eiem)) && --i) {
-		unsigned long bit = (1UL<<MAX_CPU_IRQ);
+	for (;;) {
+		unsigned long bit = (1UL << (BITS_PER_LONG - 1));
 		unsigned int irq;
+		eirr_val = mfctl(23) & cpu_eiem;
+		if (!eirr_val || !i--)
+			break;
 
 		mtctl(eirr_val, 23); /* reset bits we are going to process */
 
@@ -461,408 +304,52 @@
 #endif
 
 		/* Work our way from MSb to LSb...same order we alloc EIRs */
-		for (irq = 0; eirr_val && bit; bit>>=1, irq++)
-		{
+		for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
 			if (!(bit & eirr_val & cpu_eiem))
 				continue;
 
 			/* clear bit in mask - can exit loop sooner */
 			eirr_val &= ~bit;
 
-			do_irq(&cpu_irq_actions[irq], TIMER_IRQ+irq, regs);
+			__do_IRQ(irq, regs);
 		}
 	}
 	set_eiem(cpu_eiem);
 }
 
 
-/* Called from second level IRQ regions: eg dino or iosapic. */
-void do_irq_mask(unsigned long mask, struct irq_region *region, struct pt_regs *regs)
-{
-	unsigned long bit;
-	unsigned int irq;
-
-#ifdef DEBUG_IRQ
-	if (mask != (1L<<MAX_CPU_IRQ))
-	    printk(KERN_DEBUG "do_irq_mask %08lx %p %p\n", mask, region, regs);
-#endif
-
-	for (bit = (1L<<MAX_CPU_IRQ), irq = 0; mask && bit; bit>>=1, irq++) {
-		unsigned int irq_num;
-		if (!(bit&mask))
-			continue;
-
-		mask &= ~bit;	/* clear bit in mask - can exit loop sooner */
-		irq_num = region->data.irqbase + irq;
-
-		mask_irq(irq_num);
-		do_irq(&region->action[irq], irq_num, regs);
-		unmask_irq(irq_num);
-	}
-}
-
-
-static inline int find_free_region(void)
-{
-	int irqreg;
-
-	for (irqreg=1; irqreg <= (NR_IRQ_REGS); irqreg++) {
-		if (irq_region[irqreg] == NULL)
-			return irqreg;
-	}
-
-	return 0;
-}
-
-
-/*****
- * alloc_irq_region - allocate/init a new IRQ region
- * @count: number of IRQs in this region.
- * @ops: function table with request/release/mask/unmask/etc.. entries.
- * @name: name of region owner for /proc/interrupts output.
- * @dev: private data to associate with the new IRQ region.
- *
- * Every IRQ must become a MMIO write to the CPU's EIRR in
- * order to get CPU service. The IRQ region represents the
- * number of unique events the region handler can (or must)
- * identify. For PARISC CPU, that's the width of the EIR Register.
- * IRQ regions virtualize IRQs (eg EISA or PCI host bus controllers)
- * for line based devices.
- */
-struct irq_region *alloc_irq_region( int count, struct irq_region_ops *ops,
-					const char *name, void *dev)
-{
-	struct irq_region *region;
-	int index;
-
-	index = find_free_region();
-	if (index == 0) {
-		printk(KERN_ERR "Maximum number of irq regions exceeded. Increase NR_IRQ_REGS!\n");
-		return NULL;
-	}
-
-	if ((IRQ_REGION(count-1)))
-		return NULL;
-
-	if (count < IRQ_PER_REGION) {
-	    DBG_IRQ(0, ("alloc_irq_region() using minimum of %d irq lines for %s (%d)\n",
-			IRQ_PER_REGION, name, count));
-	    count = IRQ_PER_REGION;
-	}
-
-	/* if either mask *or* unmask is set, both have to be set. */
-	if((ops->mask_irq || ops->unmask_irq) &&
-		!(ops->mask_irq && ops->unmask_irq))
-			return NULL;
-
-	/* ditto for enable/disable */
-	if( (ops->disable_irq || ops->enable_irq) &&
-		!(ops->disable_irq && ops->enable_irq) )
-			return NULL;
-
-	region = kmalloc(sizeof(*region), GFP_ATOMIC);
-	if (!region)
-		return NULL;
-	memset(region, 0, sizeof(*region));
-
-	region->action = kmalloc(count * sizeof(*region->action), GFP_ATOMIC);
-	if (!region->action) {
-		kfree(region);
-		return NULL;
-	}
-	memset(region->action, 0, count * sizeof(*region->action));
-
-	region->ops = *ops;
-	region->data.irqbase = IRQ_FROM_REGION(index);
-	region->data.name = name;
-	region->data.dev = dev;
-
-	irq_region[index] = region;
-
-	return irq_region[index];
-}
-
-/* FIXME: SMP, flags, bottom halves, rest */
-
-int request_irq(unsigned int irq,
-		irqreturn_t (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags,
-		const char * devname,
-		void *dev_id)
-{
-	struct irqaction * action;
+static struct irqaction timer_action = {
+	.handler = timer_interrupt,
+	.name = "timer",
+};
 
-#if 0
-	printk(KERN_INFO "request_irq(%d, %p, 0x%lx, %s, %p)\n",irq, handler, irqflags, devname, dev_id);
+#ifdef CONFIG_SMP
+static struct irqaction ipi_action = {
+	.handler = ipi_interrupt,
+	.name = "IPI",
+};
 #endif
 
-	irq = irq_canonicalize(irq);
-	/* request_irq()/free_irq() may not be called from interrupt context. */
-	if (in_interrupt())
-		BUG();
-
-	if (!handler) {
-		printk(KERN_ERR "request_irq(%d,...): Augh! No handler for irq!\n",
-			irq);
-		return -EINVAL;
-	}
-
-	if (irq_region[IRQ_REGION(irq)] == NULL) {
-		/*
-		** Bug catcher for drivers which use "char" or u8 for
-		** the IRQ number. They lose the region number which
-		** is in pcidev->irq (an int).
-		*/
-		printk(KERN_ERR "%p (%s?) called request_irq with an invalid irq %d\n",
-			__builtin_return_address(0), devname, irq);
-		return -EINVAL;
-	}
-
-	spin_lock(&irq_lock);
-	action = &(irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)]);
-
-	/* First one is preallocated. */
-	if (action->handler) {
-		/* But it's in use...find the tail and allocate a new one */
-		while (action->next)
-			action = action->next;
-
-		action->next = kmalloc(sizeof(*action), GFP_ATOMIC);
-		memset(action->next, 0, sizeof(*action));
-
-		action = action->next;
-	}
-
-	if (!action) {
-		spin_unlock(&irq_lock);
-		printk(KERN_ERR "request_irq(): Augh! No action!\n") ;
-		return -ENOMEM;
-	}
-
-	action->handler = handler;
-	action->flags = irqflags;
-	cpus_clear(action->mask);
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-	spin_unlock(&irq_lock);
-
-	enable_irq(irq);
-	return 0;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void free_irq(unsigned int irq, void *dev_id)
+static void claim_cpu_irqs(void)
 {
-	struct irqaction *action, **p;
-
-	/* See comments in request_irq() about interrupt context */
-	irq = irq_canonicalize(irq);
-	
-	if (in_interrupt()) BUG();
-
-	spin_lock(&irq_lock);
-	action = &irq_region[IRQ_REGION(irq)]->action[IRQ_OFFSET(irq)];
-
-	if (action->dev_id == dev_id) {
-		if (action->next == NULL) {
-			action->handler = NULL;
-		} else {
-			memcpy(action, action->next, sizeof(*action));
-		}
-
-		spin_unlock(&irq_lock);
-		return;
-	}
-
-	p = &action->next;
-	action = action->next;
-
-	for (; (action = *p) != NULL; p = &action->next) {
-		if (action->dev_id != dev_id)
-			continue;
-
-		/* Found it - now free it */
-		*p = action->next;
-		kfree(action);
-
-		spin_unlock(&irq_lock);
-		return;
+	int i;
+	for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
+		irq_desc[i].handler = &cpu_interrupt_type;
 	}
 
-	spin_unlock(&irq_lock);
-	printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
-}
-
-EXPORT_SYMBOL(free_irq);
-
-
+	irq_desc[TIMER_IRQ].action = &timer_action;
+	irq_desc[TIMER_IRQ].status |= IRQ_PER_CPU;
 #ifdef CONFIG_SMP
-void synchronize_irq(unsigned int irqnum)
-{
-	while (in_irq()) ;
-}
-EXPORT_SYMBOL(synchronize_irq);
+	irq_desc[IPI_IRQ].action = &ipi_action;
+	irq_desc[IPI_IRQ].status = IRQ_PER_CPU;
 #endif
-
-
-/*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that
- * comes in on to an unassigned handler will get stuck
- * with "IRQ_WAITING" cleared and the interrupt
- * disabled.
- */
-
-static DECLARE_MUTEX(probe_sem);
-
-/**
- *	probe_irq_on	- begin an interrupt autodetect
- *
- *	Commence probing for an interrupt. The interrupts are scanned
- *	and a mask of potential interrupt lines is returned.
- *
- */
-
-/* TODO: spin_lock_irq(desc->lock -> irq_lock) */
-
-unsigned long probe_irq_on(void)
-{
-	unsigned int i;
-	unsigned long val;
-	unsigned long delay;
-	struct irq_region *region;
-
-	/* support for irq autoprobing is limited to EISA (irq region 0) */
-	region = irq_region[EISA_IRQ_REGION];
-	if (!EISA_bus || !region)
-		return 0;
-
-	down(&probe_sem);
-
-	/*
-	 * enable any unassigned irqs
-	 * (we must startup again here because if a longstanding irq
-	 * happened in the previous stage, it may have masked itself)
-	 */
-	for (i = EISA_MAX_IRQS-1; i > 0; i--) {
-		struct irqaction *action;
-		
-		spin_lock_irq(&irq_lock);
-		action = region->action + i;
-		if (!action->handler) {
-			region->data.status[i] |= IRQ_AUTODETECT | IRQ_WAITING;
-			region->ops.enable_irq(region->data.dev,i);
-		}
-		spin_unlock_irq(&irq_lock);
-	}
-
-	/*
-	 * Wait for spurious interrupts to trigger
-	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
-
-	/*
-	 * Now filter out any obviously spurious interrupts
-	 */
-	val = 0;
-	for (i = 0; i < EISA_MAX_IRQS; i++) {
-		unsigned int status;
-
-		spin_lock_irq(&irq_lock);
-		status = region->data.status[i];
-
-		if (status & IRQ_AUTODETECT) {
-			/* It triggered already - consider it spurious. */
-			if (!(status & IRQ_WAITING)) {
-				region->data.status[i] = status & ~IRQ_AUTODETECT;
-				region->ops.disable_irq(region->data.dev,i);
-			} else
-				if (i < BITS_PER_LONG)
-					val |= (1 << i);
-		}
-		spin_unlock_irq(&irq_lock);
-	}
-
-	return val;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-/*
- * Return the one interrupt that triggered (this can
- * handle any interrupt source).
- */
-
-/**
- *	probe_irq_off	- end an interrupt autodetect
- *	@val: mask of potential interrupts (unused)
- *
- *	Scans the unused interrupt lines and returns the line which
- *	appears to have triggered the interrupt. If no interrupt was
- *	found then zero is returned. If more than one interrupt is
- *	found then minus the first candidate is returned to indicate
- *	their is doubt.
- *
- *	The interrupt probe logic state is returned to its previous
- *	value.
- *
- *	BUGS: When used in a module (which arguably shouldnt happen)
- *	nothing prevents two IRQ probe callers from overlapping. The
- *	results of this are non-optimal.
- */
- 
-int probe_irq_off(unsigned long val)
-{
-        struct irq_region *region;
-	int i, irq_found, nr_irqs;
-
-        /* support for irq autoprobing is limited to EISA (irq region 0) */
-        region = irq_region[EISA_IRQ_REGION];
-        if (!EISA_bus || !region)
-		return 0;
-
-	nr_irqs = 0;
-	irq_found = 0;
-	for (i = 0; i < EISA_MAX_IRQS; i++) {
-		unsigned int status;
-		
-		spin_lock_irq(&irq_lock);
-		status = region->data.status[i];
-
-                if (status & IRQ_AUTODETECT) {
-			if (!(status & IRQ_WAITING)) {
-				if (!nr_irqs)
-					irq_found = i;
-				nr_irqs++;
-			}
-			region->ops.disable_irq(region->data.dev,i);
-			region->data.status[i] = status & ~IRQ_AUTODETECT;
-		}
-		spin_unlock_irq(&irq_lock);
-	}
-	up(&probe_sem);
-
-	if (nr_irqs > 1)
-		irq_found = -irq_found;
-	return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-unsigned int probe_irq_mask(unsigned long irqs)
-{
-	return 0;
 }
-EXPORT_SYMBOL(probe_irq_mask);
 
 void __init init_IRQ(void)
 {
 	local_irq_disable();	/* PARANOID - should already be disabled */
 	mtctl(~0UL, 23);	/* EIRR : clear all pending external intr */
+	claim_cpu_irqs();
 #ifdef CONFIG_SMP
 	if (!cpu_eiem)
 		cpu_eiem = EIEM_MASK(IPI_IRQ) | EIEM_MASK(TIMER_IRQ);
@@ -873,9 +360,14 @@
 
 }
 
-#ifdef CONFIG_PROC_FS
-/* called from kernel/sysctl.c:sysctl_init() */
-void __init init_irq_proc(void)
+void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq)
 {
+	/* XXX: Needs to be written.  We managed without it so far, but
+	 * we really ought to write it.
+	 */
+}
+
+void ack_bad_irq(unsigned int irq)
+{
+	printk("unexpected IRQ %d\n", irq);
 }
-#endif
diff -Nru a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
--- a/arch/parisc/kernel/parisc_ksyms.c	2005-01-19 13:44:48 -08:00
+++ b/arch/parisc/kernel/parisc_ksyms.c	2005-01-19 13:44:48 -08:00
@@ -87,9 +87,9 @@
 #include <asm/io.h>
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(__memcpy_toio);
-EXPORT_SYMBOL(__memcpy_fromio);
-EXPORT_SYMBOL(__memset_io);
+EXPORT_SYMBOL(memcpy_toio);
+EXPORT_SYMBOL(memcpy_fromio);
+EXPORT_SYMBOL(memset_io);
 
 #include <asm/unistd.h>
 EXPORT_SYMBOL(sys_open);
diff -Nru a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
--- a/arch/parisc/kernel/ptrace.c	2005-01-19 13:44:46 -08:00
+++ b/arch/parisc/kernel/ptrace.c	2005-01-19 13:44:46 -08:00
@@ -30,9 +30,9 @@
 #undef DEBUG_PTRACE
 
 #ifdef DEBUG_PTRACE
-#define DBG(x)	printk x
+#define DBG(x...)	printk(x)
 #else
-#define DBG(x)
+#define DBG(x...)
 #endif
 
 #ifdef __LP64__
@@ -138,9 +138,9 @@
 			if (copied != sizeof(tmp))
 				goto out_tsk;
 			ret = put_user(tmp,(unsigned int *) data);
-			DBG(("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
+			DBG("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
 				request == PTRACE_PEEKTEXT ? "TEXT" : "DATA",
-				pid, oaddr, odata, ret, tmp));
+				pid, oaddr, odata, ret, tmp);
 		}
 		else
 #endif
@@ -163,9 +163,9 @@
 #ifdef __LP64__
 		if (is_compat_task(child)) {
 			unsigned int tmp = (unsigned int)data;
-			DBG(("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
+			DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
 				request == PTRACE_POKETEXT ? "TEXT" : "DATA",
-				pid, oaddr, odata));
+				pid, oaddr, odata);
 			addr &= 0xffffffffL;
 			if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1) == sizeof(tmp))
 				goto out_tsk;
@@ -194,8 +194,8 @@
 
 			tmp = *(unsigned int *) ((char *) task_regs(child) + addr);
 			ret = put_user(tmp, (unsigned int *) data);
-			DBG(("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
-				pid, oaddr, odata, ret, addr, tmp));
+			DBG("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
+				pid, oaddr, odata, ret, addr, tmp);
 		}
 		else
 #endif
@@ -234,8 +234,8 @@
 			 * BEWARE, if you set N, and then single step, it won't
 			 * stop on the nullified instruction.
 			 */
-			DBG(("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
-				pid, oaddr, odata));
+			DBG("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
+				pid, oaddr, odata);
 			data &= USER_PSW_BITS;
 			task_regs(child)->gr[0] &= ~USER_PSW_BITS;
 			task_regs(child)->gr[0] |= data;
@@ -248,9 +248,9 @@
 				goto out_tsk;
 			if ((addr = translate_usr_offset(addr)) < 0)
 				goto out_tsk;
-			DBG(("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
-				pid, oaddr, odata, addr));
-			if (addr >= PT_FR0 && addr <= PT_FR31) {
+			DBG("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
+				pid, oaddr, odata, addr);
+			if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
 				/* Special case, fp regs are 64 bits anyway */
 				*(unsigned int *) ((char *) task_regs(child) + addr) = data;
 				ret = 0;
@@ -272,7 +272,7 @@
 				goto out_tsk;
 			if ((addr >= PT_GR1 && addr <= PT_GR31) ||
 					addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
-					(addr >= PT_FR0 && addr <= PT_FR31) ||
+					(addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
 					addr == PT_SAR) {
 				*(unsigned long *) ((char *) task_regs(child) + addr) = data;
 				ret = 0;
@@ -283,8 +283,8 @@
 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
 	case PTRACE_CONT:
 		ret = -EIO;
-		DBG(("sys_ptrace(%s)\n",
-			request == PTRACE_SYSCALL ? "SYSCALL" : "CONT"));
+		DBG("sys_ptrace(%s)\n",
+			request == PTRACE_SYSCALL ? "SYSCALL" : "CONT");
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
 		child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
@@ -302,14 +302,14 @@
 		 * sigkill.  perhaps it should be put in the status
 		 * that it wants to exit.
 		 */
-		DBG(("sys_ptrace(KILL)\n"));
+		DBG("sys_ptrace(KILL)\n");
 		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
 			goto out_tsk;
 		child->exit_code = SIGKILL;
 		goto out_wake_notrap;
 
 	case PTRACE_SINGLEBLOCK:
-		DBG(("sys_ptrace(SINGLEBLOCK)\n"));
+		DBG("sys_ptrace(SINGLEBLOCK)\n");
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
@@ -326,10 +326,11 @@
 		goto out_wake;
 
 	case PTRACE_SINGLESTEP:
-		DBG(("sys_ptrace(SINGLESTEP)\n"));
+		DBG("sys_ptrace(SINGLESTEP)\n");
 		ret = -EIO;
 		if ((unsigned long) data > _NSIG)
 			goto out_tsk;
+
 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		child->ptrace &= ~PT_BLOCKSTEP;
 		child->ptrace |= PT_SINGLESTEP;
@@ -351,7 +352,7 @@
 			/* Don't wake up the child, but let the
 			   parent know something happened. */
 			si.si_code = TRAP_TRACE;
-			si.si_addr = (void *) (task_regs(child)->iaoq[0] & ~3);
+			si.si_addr = (void __user *) (task_regs(child)->iaoq[0] & ~3);
 			si.si_signo = SIGTRAP;
 			si.si_errno = 0;
 			force_sig_info(SIGTRAP, &si, child);
@@ -397,8 +398,8 @@
 	put_task_struct(child);
 out:
 	unlock_kernel();
-	DBG(("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
-		request, pid, oaddr, odata, ret));
+	DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
+		request, pid, oaddr, odata, ret);
 	return ret;
 }
 
diff -Nru a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
--- a/arch/parisc/kernel/setup.c	2005-01-19 13:44:47 -08:00
+++ b/arch/parisc/kernel/setup.c	2005-01-19 13:44:47 -08:00
@@ -307,6 +307,8 @@
 			boot_cpu_data.cpu_hz / 1000000,
 			boot_cpu_data.cpu_hz % 1000000	);
 
+	parisc_setup_cache_timing();
+
 	/* These are in a non-obvious order, will fix when we have an iotree */
 #if defined(CONFIG_IOSAPIC)
 	iosapic_init();
diff -Nru a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
--- a/arch/parisc/kernel/smp.c	2005-01-19 13:44:48 -08:00
+++ b/arch/parisc/kernel/smp.c	2005-01-19 13:44:48 -08:00
@@ -277,7 +277,7 @@
 
 	spin_lock_irqsave(&(p->lock),flags);
 	p->pending_ipi |= 1 << op;
-	__raw_writel(IRQ_OFFSET(IPI_IRQ), cpu_data[cpu].hpa);
+	gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa);
 	spin_unlock_irqrestore(&(p->lock),flags);
 }
 
@@ -533,7 +533,7 @@
 	** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the 
 	** contents of memory are valid."
 	*/
-	__raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpuid].hpa);
+	gsc_writel(TIMER_IRQ - CPU_IRQ_BASE, cpu_data[cpuid].hpa);
 	mb();
 
 	/* 
diff -Nru a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
--- a/arch/parisc/kernel/syscall_table.S	2005-01-19 13:44:45 -08:00
+++ b/arch/parisc/kernel/syscall_table.S	2005-01-19 13:44:45 -08:00
@@ -275,7 +275,7 @@
 	ENTRY_DIFF(rt_sigaction)
 	ENTRY_DIFF(rt_sigprocmask)	/* 175 */
 	ENTRY_DIFF(rt_sigpending)
-	ENTRY_UHOH(rt_sigtimedwait)
+	ENTRY_COMP(rt_sigtimedwait)
 	/* even though the struct siginfo_t is different, it appears like
 	 * all the paths use values which should be same wide and narrow.
 	 * Also the struct is padded to 128 bytes which means we don't have
diff -Nru a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile
--- a/arch/parisc/lib/Makefile	2005-01-19 13:44:47 -08:00
+++ b/arch/parisc/lib/Makefile	2005-01-19 13:44:47 -08:00
@@ -4,4 +4,6 @@
 
 lib-y	:= lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o
 
+obj-y	:= iomap.o
+
 lib-$(CONFIG_SMP) += debuglocks.o
diff -Nru a/arch/parisc/lib/checksum.c b/arch/parisc/lib/checksum.c
--- a/arch/parisc/lib/checksum.c	2005-01-19 13:44:47 -08:00
+++ b/arch/parisc/lib/checksum.c	2005-01-19 13:44:47 -08:00
@@ -113,7 +113,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst, 
+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
 				       int len, unsigned int sum)
 {
 	/*
@@ -131,7 +131,7 @@
  * Copy from userspace and compute checksum.  If we catch an exception
  * then zero the rest of the buffer.
  */
-unsigned int csum_partial_copy_from_user (const char *src, char *dst,
+unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
                                           int len, unsigned int sum,
                                           int *err_ptr)
 {
diff -Nru a/arch/parisc/lib/io.c b/arch/parisc/lib/io.c
--- a/arch/parisc/lib/io.c	2005-01-19 13:44:45 -08:00
+++ b/arch/parisc/lib/io.c	2005-01-19 13:44:45 -08:00
@@ -15,24 +15,24 @@
  * Assumes the device can cope with 32-bit transfers.  If it can't,
  * don't use this function.
  */
-void __memcpy_toio(unsigned long dest, unsigned long src, int count)
+void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
 {
-	if ((dest & 3) != (src & 3))
+	if (((unsigned long)dst & 3) != ((unsigned long)src & 3))
 		goto bytecopy;
-	while (dest & 3) {
-		writeb(*(char *)src, dest++);
+	while ((unsigned long)dst & 3) {
+		writeb(*(char *)src, dst++);
 		src++;
 		count--;
 	}
 	while (count > 3) {
-		__raw_writel(*(u32 *)src, dest);
+		__raw_writel(*(u32 *)src, dst);
 		src += 4;
-		dest += 4;
+		dst += 4;
 		count -= 4;
 	}
  bytecopy:
 	while (count--) {
-		writeb(*(char *)src, dest++);
+		writeb(*(char *)src, dst++);
 		src++;
 	}
 }
@@ -50,51 +50,51 @@
 **      Minimize total number of transfers at cost of CPU cycles.
 **	TODO: only look at src alignment and adjust the stores to dest.
 */
-void __memcpy_fromio(unsigned long dest, unsigned long src, int count)
+void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
 {
 	/* first compare alignment of src/dst */ 
-	if ( ((dest ^ src) & 1) || (count < 2) )
+	if ( (((unsigned long)dst ^ (unsigned long)src) & 1) || (count < 2) )
 		goto bytecopy;
 
-	if ( ((dest ^ src) & 2) || (count < 4) )
+	if ( (((unsigned long)dst ^ (unsigned long)src) & 2) || (count < 4) )
 		goto shortcopy;
 
 	/* Then check for misaligned start address */
-	if (src & 1) {
-		*(u8 *)dest = readb(src);
+	if ((unsigned long)src & 1) {
+		*(u8 *)dst = readb(src);
 		src++;
-		dest++;
+		dst++;
 		count--;
 		if (count < 2) goto bytecopy;
 	}
 
-	if (src & 2) {
-		*(u16 *)dest = __raw_readw(src);
+	if ((unsigned long)src & 2) {
+		*(u16 *)dst = __raw_readw(src);
 		src += 2;
-		dest += 2;
+		dst += 2;
 		count -= 2;
 	}
 
 	while (count > 3) {
-		*(u32 *)dest = __raw_readl(src);
-		dest += 4;
+		*(u32 *)dst = __raw_readl(src);
+		dst += 4;
 		src += 4;
 		count -= 4;
 	}
 
  shortcopy:
 	while (count > 1) {
-		*(u16 *)dest = __raw_readw(src);
+		*(u16 *)dst = __raw_readw(src);
 		src += 2;
-		dest += 2;
+		dst += 2;
 		count -= 2;
 	}
 
  bytecopy:
 	while (count--) {
-		*(char *)dest = readb(src);
+		*(char *)dst = readb(src);
 		src++;
-		dest++;
+		dst++;
 	}
 }
 
@@ -102,20 +102,20 @@
  * Assumes the device can cope with 32-bit transfers.  If it can't,
  * don't use this function.
  */
-void __memset_io(unsigned long dest, char fill, int count)
+void memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
-	u32 fill32 = (fill << 24) | (fill << 16) | (fill << 8) | fill;
-	while (dest & 3) {
-		writeb(fill, dest++);
+	u32 val32 = (val << 24) | (val << 16) | (val << 8) | val;
+	while ((unsigned long)addr & 3) {
+		writeb(val, addr++);
 		count--;
 	}
 	while (count > 3) {
-		__raw_writel(fill32, dest);
-		dest += 4;
+		__raw_writel(val32, addr);
+		addr += 4;
 		count -= 4;
 	}
 	while (count--) {
-		writeb(fill, dest++);
+		writeb(val, addr++);
 	}
 }
 
diff -Nru a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/arch/parisc/lib/iomap.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,422 @@
+/*
+ * iomap.c - Implement iomap interface for PA-RISC
+ * Copyright (c) 2004 Matthew Wilcox
+ */
+
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+/*
+ * The iomap space on 32-bit PA-RISC is intended to look like this:
+ * 00000000-7fffffff virtual mapped IO
+ * 80000000-8fffffff ISA/EISA port space that can't be virtually mapped
+ * 90000000-9fffffff Dino port space
+ * a0000000-afffffff Astro port space
+ * b0000000-bfffffff PAT port space
+ * c0000000-cfffffff non-swapped memory IO
+ * f0000000-ffffffff legacy IO memory pointers
+ *
+ * For the moment, here's what it looks like:
+ * 80000000-8fffffff All ISA/EISA port space
+ * f0000000-ffffffff legacy IO memory pointers
+ *
+ * On 64-bit, everything is extended, so:
+ * 8000000000000000-8fffffffffffffff All ISA/EISA port space
+ * f000000000000000-ffffffffffffffff legacy IO memory pointers
+ */
+
+/*
+ * Technically, this should be 'if (VMALLOC_START < addr < VMALLOC_END),
+ * but that's slow and we know it'll be within the first 2GB.
+ */
+#ifdef CONFIG_64BIT
+#define INDIRECT_ADDR(addr)	(((unsigned long)(addr) & 1UL<<63) != 0)
+#define ADDR_TO_REGION(addr)    (((unsigned long)addr >> 60) & 7)
+#define IOPORT_MAP_BASE		(8UL << 60)
+#else
+#define INDIRECT_ADDR(addr)     (((unsigned long)(addr) & 1UL<<31) != 0)
+#define ADDR_TO_REGION(addr)    (((unsigned long)addr >> 28) & 7)
+#define IOPORT_MAP_BASE		(8UL << 28)
+#endif
+
+struct iomap_ops {
+	unsigned int (*read8)(void __iomem *);
+	unsigned int (*read16)(void __iomem *);
+	unsigned int (*read32)(void __iomem *);
+	void (*write8)(u8, void __iomem *);
+	void (*write16)(u16, void __iomem *);
+	void (*write32)(u32, void __iomem *);
+	void (*read8r)(void __iomem *, void *, unsigned long);
+	void (*read16r)(void __iomem *, void *, unsigned long);
+	void (*read32r)(void __iomem *, void *, unsigned long);
+	void (*write8r)(void __iomem *, const void *, unsigned long);
+	void (*write16r)(void __iomem *, const void *, unsigned long);
+	void (*write32r)(void __iomem *, const void *, unsigned long);
+};
+
+/* Generic ioport ops.  To be replaced later by specific dino/elroy/wax code */
+
+#define ADDR2PORT(addr) ((unsigned long __force)(addr) & 0xffffff)
+
+static unsigned int ioport_read8(void __iomem *addr)
+{
+	return inb(ADDR2PORT(addr));
+}
+
+static unsigned int ioport_read16(void __iomem *addr)
+{
+	return inw(ADDR2PORT(addr));
+}
+
+static unsigned int ioport_read32(void __iomem *addr)
+{
+	return inl(ADDR2PORT(addr));
+}
+
+static void ioport_write8(u8 datum, void __iomem *addr)
+{
+	outb(datum, ADDR2PORT(addr));
+}
+
+static void ioport_write16(u16 datum, void __iomem *addr)
+{
+	outw(datum, ADDR2PORT(addr));
+}
+
+static void ioport_write32(u32 datum, void __iomem *addr)
+{
+	outl(datum, ADDR2PORT(addr));
+}
+
+static void ioport_read8r(void __iomem *addr, void *dst, unsigned long count)
+{
+	insb(ADDR2PORT(addr), dst, count);
+}
+
+static void ioport_read16r(void __iomem *addr, void *dst, unsigned long count)
+{
+	insw(ADDR2PORT(addr), dst, count);
+}
+
+static void ioport_read32r(void __iomem *addr, void *dst, unsigned long count)
+{
+	insl(ADDR2PORT(addr), dst, count);
+}
+
+static void ioport_write8r(void __iomem *addr, const void *s, unsigned long n)
+{
+	outsb(ADDR2PORT(addr), s, n);
+}
+
+static void ioport_write16r(void __iomem *addr, const void *s, unsigned long n)
+{
+	outsw(ADDR2PORT(addr), s, n);
+}
+
+static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n)
+{
+	outsl(ADDR2PORT(addr), s, n);
+}
+
+static const struct iomap_ops ioport_ops = {
+	ioport_read8,
+	ioport_read16,
+	ioport_read32,
+	ioport_write8,
+	ioport_write16,
+	ioport_write32,
+	ioport_read8r,
+	ioport_read16r,
+	ioport_read32r,
+	ioport_write8r,
+	ioport_write16r,
+	ioport_write32r,
+};
+
+/* Legacy I/O memory ops */
+
+static unsigned int iomem_read8(void __iomem *addr)
+{
+	return readb(addr);
+}
+
+static unsigned int iomem_read16(void __iomem *addr)
+{
+	return readw(addr);
+}
+
+static unsigned int iomem_read32(void __iomem *addr)
+{
+	return readl(addr);
+}
+
+static void iomem_write8(u8 datum, void __iomem *addr)
+{
+	writeb(datum, addr);
+}
+
+static void iomem_write16(u16 datum, void __iomem *addr)
+{
+	writew(datum, addr);
+}
+
+static void iomem_write32(u32 datum, void __iomem *addr)
+{
+	writel(datum, addr);
+}
+
+static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count)
+{
+	while (count--) {
+		*(u8 *)dst = __raw_readb(addr);
+		dst++;
+	}
+}
+
+static void iomem_read16r(void __iomem *addr, void *dst, unsigned long count)
+{
+	while (count--) {
+		*(u16 *)dst = __raw_readw(addr);
+		dst += 2;
+	}
+}
+
+static void iomem_read32r(void __iomem *addr, void *dst, unsigned long count)
+{
+	while (count--) {
+		*(u32 *)dst = __raw_readl(addr);
+		dst += 4;
+	}
+}
+
+static void iomem_write8r(void __iomem *addr, const void *s, unsigned long n)
+{
+	while (n--) {
+		__raw_writeb(*(u8 *)s, addr);
+		s++;
+	}
+}
+
+static void iomem_write16r(void __iomem *addr, const void *s, unsigned long n)
+{
+	while (n--) {
+		__raw_writew(*(u16 *)s, addr);
+		s += 2;
+	}
+}
+
+static void iomem_write32r(void __iomem *addr, const void *s, unsigned long n)
+{
+	while (n--) {
+		__raw_writel(*(u32 *)s, addr);
+		s += 4;
+	}
+}
+
+static const struct iomap_ops iomem_ops = {
+	iomem_read8,
+	iomem_read16,
+	iomem_read32,
+	iomem_write8,
+	iomem_write16,
+	iomem_write32,
+	iomem_read8r,
+	iomem_read16r,
+	iomem_read32r,
+	iomem_write8r,
+	iomem_write16r,
+	iomem_write32r,
+};
+
+const struct iomap_ops *iomap_ops[8] = {
+	[0] = &ioport_ops,
+#ifdef CONFIG_DEBUG_IOREMAP
+	[6] = &iomem_ops,
+#else
+	[7] = &iomem_ops
+#endif
+};
+
+
+unsigned int ioread8(void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr)))
+		return iomap_ops[ADDR_TO_REGION(addr)]->read8(addr);
+	return *((u8 *)addr);
+}
+
+unsigned int ioread16(void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr)))
+		return iomap_ops[ADDR_TO_REGION(addr)]->read16(addr);
+	return le16_to_cpup((u16 *)addr);
+}
+
+unsigned int ioread32(void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr)))
+		return iomap_ops[ADDR_TO_REGION(addr)]->read32(addr);
+	return le32_to_cpup((u32 *)addr);
+}
+
+void iowrite8(u8 datum, void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write8(datum, addr);
+	} else {
+		*((u8 *)addr) = datum;
+	}
+}
+
+void iowrite16(u16 datum, void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write16(datum, addr);
+	} else {
+		*((u16 *)addr) = cpu_to_le16(datum);
+	}
+}
+
+void iowrite32(u32 datum, void __iomem *addr)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write32(datum, addr);
+	} else {
+		*((u32 *)addr) = cpu_to_le32(datum);
+	}
+}
+
+/* Repeating interfaces */
+
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->read8r(addr, dst, count);
+	} else {
+		while (count--) {
+			*(u8 *)dst = *(u8 *)addr;
+			dst++;
+		}
+	}
+}
+
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->read16r(addr, dst, count);
+	} else {
+		while (count--) {
+			*(u16 *)dst = *(u16 *)addr;
+			dst += 2;
+		}
+	}
+}
+
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->read32r(addr, dst, count);
+	} else {
+		while (count--) {
+			*(u32 *)dst = *(u32 *)addr;
+			dst += 4;
+		}
+	}
+}
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write8r(addr, src, count);
+	} else {
+		while (count--) {
+			*(u8 *)addr = *(u8 *)src;
+			src++;
+		}
+	}
+}
+
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write16r(addr, src, count);
+	} else {
+		while (count--) {
+			*(u16 *)addr = *(u16 *)src;
+			src += 2;
+		}
+	}
+}
+
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	if (unlikely(INDIRECT_ADDR(addr))) {
+		iomap_ops[ADDR_TO_REGION(addr)]->write32r(addr, src, count);
+	} else {
+		while (count--) {
+			*(u32 *)addr = *(u32 *)src;
+			src += 4;
+		}
+	}
+}
+
+/* Mapping interfaces */
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *)(IOPORT_MAP_BASE | port);
+}
+
+void ioport_unmap(void __iomem *addr)
+{
+	if (!INDIRECT_ADDR(addr)) {
+		iounmap(addr);
+	}
+}
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+	unsigned long start = pci_resource_start(dev, bar);
+	unsigned long len = pci_resource_len(dev, bar);
+	unsigned long flags = pci_resource_flags(dev, bar);
+
+	if (!len || !start)
+		return NULL;
+	if (maxlen && len > maxlen)
+		len = maxlen;
+	if (flags & IORESOURCE_IO)
+		return ioport_map(start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap(start, len);
+		return ioremap_nocache(start, len);
+	}
+	/* What? */
+	return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
+{
+	if (!INDIRECT_ADDR(addr)) {
+		iounmap(addr);
+	}
+}
+
+EXPORT_SYMBOL(ioread8);
+EXPORT_SYMBOL(ioread16);
+EXPORT_SYMBOL(ioread32);
+EXPORT_SYMBOL(iowrite8);
+EXPORT_SYMBOL(iowrite16);
+EXPORT_SYMBOL(iowrite32);
+EXPORT_SYMBOL(ioread8_rep);
+EXPORT_SYMBOL(ioread16_rep);
+EXPORT_SYMBOL(ioread32_rep);
+EXPORT_SYMBOL(iowrite8_rep);
+EXPORT_SYMBOL(iowrite16_rep);
+EXPORT_SYMBOL(iowrite32_rep);
+EXPORT_SYMBOL(ioport_map);
+EXPORT_SYMBOL(ioport_unmap);
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
diff -Nru a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
--- a/arch/parisc/mm/ioremap.c	2005-01-19 13:44:46 -08:00
+++ b/arch/parisc/mm/ioremap.c	2005-01-19 13:44:46 -08:00
@@ -11,6 +11,7 @@
 
 #include <linux/vmalloc.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/pgalloc.h>
 
@@ -94,6 +95,30 @@
 }
 #endif /* USE_HPPA_IOREMAP */
 
+#ifdef CONFIG_DEBUG_IOREMAP
+static unsigned long last = 0;
+
+void gsc_bad_addr(unsigned long addr)
+{
+	if (time_after(jiffies, last + HZ*10)) {
+		printk("gsc_foo() called with bad address 0x%lx\n", addr);
+		dump_stack();
+		last = jiffies;
+	}
+}
+EXPORT_SYMBOL(gsc_bad_addr);
+
+void __raw_bad_addr(const volatile void __iomem *addr)
+{
+	if (time_after(jiffies, last + HZ*10)) {
+		printk("__raw_foo() called with bad address 0x%p\n", addr);
+		dump_stack();
+		last = jiffies;
+	}
+}
+EXPORT_SYMBOL(__raw_bad_addr);
+#endif
+
 /*
  * Generic mapping function (not visible outside):
  */
@@ -107,7 +132,7 @@
  * have to convert them into an offset in a page-aligned mapping, but the
  * caller shouldn't need to know that small detail.
  */
-void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
 {
 #if !(USE_HPPA_IOREMAP)
 
@@ -118,7 +143,11 @@
 		phys_addr |= 0xfc000000;
 	}
 
-	return (void *)phys_addr;
+#ifdef CONFIG_DEBUG_IOREMAP
+	return (void __iomem *)(phys_addr - (0x1UL << NYBBLE_SHIFT));
+#else
+	return (void __iomem *)phys_addr;
+#endif
 
 #else
 	void * addr;
@@ -163,16 +192,16 @@
 		vfree(addr);
 		return NULL;
 	}
-	return (void *) (offset + (char *)addr);
+	return (void __iomem *) (offset + (char *)addr);
 #endif
 }
 
-void iounmap(void *addr)
+void iounmap(void __iomem *addr)
 {
 #if !(USE_HPPA_IOREMAP)
 	return;
 #else
 	if (addr > high_memory)
-		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+		return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
 #endif
 }
diff -Nru a/arch/ppc/8xx_io/Kconfig b/arch/ppc/8xx_io/Kconfig
--- a/arch/ppc/8xx_io/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/ppc/8xx_io/Kconfig	2005-01-19 13:44:47 -08:00
@@ -10,7 +10,7 @@
 	depends on NET_ETHERNET
 	help
 	  Enable Ethernet support via the Motorola MPC8xx serial
-	  commmunications controller.
+	  communications controller.
 
 choice
 	prompt "SCC used for Ethernet"
diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig	2005-01-19 13:44:48 -08:00
+++ b/arch/ppc/Kconfig	2005-01-19 13:44:48 -08:00
@@ -326,7 +326,7 @@
 
 	  HERMES:
 	  Hermes-Pro ISDN/LAN router with integrated 8 x hub
-	  Manufacturer: Multidata Gesellschaft fÃ¼r Datentechnik und Informatik
+	  Manufacturer: Multidata Gesellschaft fur Datentechnik und Informatik
 	  <http://www.multidata.de/>
 	  Date of Release: 2000 (?)
 	  End of life: -
@@ -623,6 +623,12 @@
 config ADS8272
 	bool "ADS8272"
 
+config PQ2FADS
+	bool "Freescale-PQ2FADS"
+	help
+	  Select PQ2FADS if you wish to configure for a Freescale
+	  PQ2FADS board (-VR or -ZU).
+
 config LITE5200
 	bool "Freescale LITE5200 / (IceCube)"
 	select PPC_MPC52xx
@@ -655,7 +661,7 @@
 config 8260
 	bool "CPM2 Support" if WILLOW
 	depends on 6xx
-	default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx
+	default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx || PQ2FADS
 	help
 	  The MPC8260 is a typical embedded CPU made by Motorola.  Selecting
 	  this option means that you wish to build a kernel for a machine with
diff -Nru a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
--- a/arch/ppc/platforms/pq2ads.c	2005-01-19 13:44:48 -08:00
+++ b/arch/ppc/platforms/pq2ads.c	2005-01-19 13:44:48 -08:00
@@ -19,8 +19,8 @@
 #include <asm/mpc8260.h>
 
 void __init
-m82xx_board_init(void)
+m82xx_board_setup(void)
 {
 	/* Enable the 2nd UART port */
-        *(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2;
+	*(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2;
 }
diff -Nru a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h
--- a/arch/ppc/platforms/pq2ads.h	2005-01-19 13:44:46 -08:00
+++ b/arch/ppc/platforms/pq2ads.h	2005-01-19 13:44:46 -08:00
@@ -40,6 +40,8 @@
 #define BCSR1_FETH_RST		((uint)0x04000000)	/* 0 == reset */
 #define BCSR1_RS232_EN1		((uint)0x02000000)	/* 0 == enable */
 #define BCSR1_RS232_EN2		((uint)0x01000000)	/* 0 == enable */
+#define BCSR3_FETHIEN2		((uint)0x10000000)	/* 0 == enable */
+#define BCSR3_FETH2_RST 	((uint)0x80000000)	/* 0 == reset */
 
 #define PHY_INTERRUPT	SIU_INT_IRQ7
 
diff -Nru a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
--- a/arch/ppc/syslib/m8260_setup.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ppc/syslib/m8260_setup.c	2005-01-19 13:44:46 -08:00
@@ -37,6 +37,12 @@
 extern void m8260_find_bridges(void);
 extern void idma_pci9_init(void);
 
+/* Place-holder for board-specific init */
+void __attribute__ ((weak)) __init
+m82xx_board_setup(void)
+{
+}
+
 static void __init
 m8260_setup_arch(void)
 {
@@ -56,6 +62,7 @@
 	if (initrd_start)
 		ROOT_DEV = Root_RAM0;
 #endif
+	m82xx_board_setup();
 }
 
 /* The decrementer counts at the system (internal) clock frequency
@@ -203,7 +210,7 @@
 	io_block_mapping(IO_VIRT_ADDR, IO_PHYS_ADDR, 0x10000000, _PAGE_IO);
 }
 
-/* Place-holder for board-specific init */
+/* Place-holder for board-specific ppc_md hooking */
 void __attribute__ ((weak)) __init
 m82xx_board_init(void)
 {
diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/ppc64/Kconfig	2005-01-19 13:44:46 -08:00
@@ -92,7 +92,7 @@
 	default n
 	help
           This option enables support for the Maple 970FX Evaluation Board.
-	  For more informations, refer to http://www.970eval.com
+	  For more informations, refer to <http://www.970eval.com>
 
 config PPC
 	bool
@@ -230,6 +230,17 @@
 
 	  Say Y here if you are building a kernel for a desktop, embedded
 	  or real-time system.  Say N if you are unsure.
+
+config PREEMPT_BKL
+	bool "Preempt The Big Kernel Lock"
+	depends on PREEMPT
+	default y
+	help
+	  This option reduces the latency of the kernel by making the
+	  big kernel lock preemptible.
+
+	  Say Y here if you are building a kernel for a desktop system.
+	  Say N if you are unsure.
 
 #
 # Use the generic interrupt handling code in kernel/irq/:
diff -Nru a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c
--- a/arch/ppc64/kernel/HvLpEvent.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ppc64/kernel/HvLpEvent.c	2005-01-19 13:44:46 -08:00
@@ -34,10 +34,18 @@
 int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
 {
 	int rc = 1;
+
+	might_sleep();
+
 	if ( eventType < HvLpEvent_Type_NumTypes ) {
 		if ( !lpEventHandlerPaths[eventType] ) {
 			lpEventHandler[eventType] = NULL;
 			rc = 0;
+
+			/* We now sleep until all other CPUs have scheduled. This ensures that
+			 * the deletion is seen by all other CPUs, and that the deleted handler
+			 * isn't still running on another CPU when we return. */
+			synchronize_kernel();
 		}
 	}
 	return rc;
diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
--- a/arch/ppc64/kernel/entry.S	2005-01-19 13:44:45 -08:00
+++ b/arch/ppc64/kernel/entry.S	2005-01-19 13:44:45 -08:00
@@ -574,25 +574,22 @@
 	crandc	eq,cr1*4+eq,eq
 	bne	restore
 	/* here we are preempting the current task */
-1:	lis	r0,PREEMPT_ACTIVE@h
-	stw	r0,TI_PREEMPT(r9)
+1:
 #ifdef CONFIG_PPC_ISERIES
 	li	r0,1
 	stb	r0,PACAPROCENABLED(r13)
 #endif
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10,1		/* reenable interrupts */
-	bl	.schedule
+	bl	.preempt_schedule
 	mfmsr	r10
 	clrrdi	r9,r1,THREAD_SHIFT
 	rldicl	r10,r10,48,1	/* disable interrupts again */
-	li	r0,0
 	rotldi	r10,r10,16
 	mtmsrd	r10,1
 	ld	r4,TI_FLAGS(r9)
 	andi.	r0,r4,_TIF_NEED_RESCHED
 	bne	1b
-	stw	r0,TI_PREEMPT(r9)
 	b	restore
 
 user_work:
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S	2005-01-19 13:44:47 -08:00
+++ b/arch/ppc64/kernel/misc.S	2005-01-19 13:44:47 -08:00
@@ -843,7 +843,7 @@
 	.llong .sys32_rt_sigaction
 	.llong .sys32_rt_sigprocmask
 	.llong .sys32_rt_sigpending     /* 175 */
-	.llong .compat_rt_sigtimedwait
+	.llong .compat_sys_rt_sigtimedwait
 	.llong .sys32_rt_sigqueueinfo
 	.llong .ppc32_rt_sigsuspend
 	.llong .sys32_pread64
diff -Nru a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c
--- a/arch/ppc64/kernel/pSeries_iommu.c	2005-01-19 13:44:46 -08:00
+++ b/arch/ppc64/kernel/pSeries_iommu.c	2005-01-19 13:44:46 -08:00
@@ -327,12 +327,25 @@
 		/* Root bus */
 		if (is_python(dn)) {
 			struct iommu_table *tbl;
+			unsigned int *iohole;
 
 			DBG("Python root bus %s\n", bus->name);
 
-			/* 1GB window by default */
-			dn->phb->dma_window_size = 1 << 30;
-			dn->phb->dma_window_base_cur = 0;
+			iohole = (unsigned int *)get_property(dn, "io-hole", 0);
+
+			if (iohole) {
+				/* On first bus we need to leave room for the
+				 * ISA address space. Just skip the first 256MB
+				 * alltogether. This leaves 768MB for the window.
+				 */
+				DBG("PHB has io-hole, reserving 256MB\n");
+				dn->phb->dma_window_size = 3 << 28;
+				dn->phb->dma_window_base_cur = 1 << 28;
+			} else {
+				/* 1GB window by default */
+				dn->phb->dma_window_size = 1 << 30;
+				dn->phb->dma_window_base_cur = 0;
+			}
 
 			tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
diff -Nru a/arch/s390/defconfig b/arch/s390/defconfig
--- a/arch/s390/defconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/s390/defconfig	2005-01-19 13:44:47 -08:00
@@ -1,10 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10
-# Mon Dec 27 11:03:23 2004
+# Linux kernel version: 2.6.11-rc1
+# Fri Jan 14 14:56:51 2005
 #
 CONFIG_MMU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_ARCH_S390=y
 CONFIG_UID16=y
 
@@ -142,6 +143,7 @@
 #
 # CONFIG_SCSI_SPI_ATTRS is not set
 CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -184,6 +186,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -530,6 +533,7 @@
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
 
 #
 # Security options
diff -Nru a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
--- a/arch/s390/kernel/compat_wrapper.S	2005-01-19 13:44:48 -08:00
+++ b/arch/s390/kernel/compat_wrapper.S	2005-01-19 13:44:48 -08:00
@@ -840,13 +840,13 @@
 	llgfr	%r3,%r3			# size_t
 	jg	sys32_rt_sigpending	# branch to system call
 
-	.globl  compat_rt_sigtimedwait_wrapper
-compat_rt_sigtimedwait_wrapper:
+	.globl  compat_sys_rt_sigtimedwait_wrapper
+compat_sys_rt_sigtimedwait_wrapper:
 	llgtr	%r2,%r2			# const sigset_emu31_t *
 	llgtr	%r3,%r3			# siginfo_emu31_t *
 	llgtr	%r4,%r4			# const struct compat_timespec *
 	llgfr	%r5,%r5			# size_t
-	jg	compat_rt_sigtimedwait	# branch to system call
+	jg	compat_sys_rt_sigtimedwait	# branch to system call
 
 	.globl  sys32_rt_sigqueueinfo_wrapper 
 sys32_rt_sigqueueinfo_wrapper:
diff -Nru a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
--- a/arch/s390/kernel/setup.c	2005-01-19 13:44:45 -08:00
+++ b/arch/s390/kernel/setup.c	2005-01-19 13:44:45 -08:00
@@ -98,6 +98,8 @@
         clear_thread_flag(TIF_USEDFPU);
         current->used_math = 0;
 
+	atomic_inc(&init_mm.mm_count);
+	current->active_mm = &init_mm;
         if (current->mm)
                 BUG();
         enter_lazy_tlb(&init_mm, current);
diff -Nru a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
--- a/arch/s390/kernel/smp.c	2005-01-19 13:44:48 -08:00
+++ b/arch/s390/kernel/smp.c	2005-01-19 13:44:48 -08:00
@@ -486,48 +486,38 @@
  * Lets check how many CPUs we have.
  */
 
-#ifdef CONFIG_HOTPLUG_CPU
-
 void
 __init smp_check_cpus(unsigned int max_cpus)
 {
-	int cpu;
+	int cpu, num_cpus;
+	__u16 boot_cpu_addr;
 
 	/*
 	 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu.
 	 */
-	for (cpu = 1; cpu < max_cpus; cpu++)
-		cpu_set(cpu, cpu_possible_map);
-}
 
-#else /* CONFIG_HOTPLUG_CPU */
+	boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+	__cpu_logical_map[0] = boot_cpu_addr;
+	current_thread_info()->cpu = 0;
+	num_cpus = 1;
+	for (cpu = 0; cpu <= 65535 && num_cpus < max_cpus; cpu++) {
+		if ((__u16) cpu == boot_cpu_addr)
+			continue;
+		__cpu_logical_map[num_cpus] = (__u16) cpu;
+		if (signal_processor(num_cpus, sigp_sense) ==
+		    sigp_not_operational)
+			continue;
+		cpu_set(num_cpus, cpu_present_map);
+		num_cpus++;
+	}
 
-void
-__init smp_check_cpus(unsigned int max_cpus)
-{
-        int curr_cpu, num_cpus;
-	__u16 boot_cpu_addr;
+	for (cpu = 1; cpu < max_cpus; cpu++)
+		cpu_set(cpu, cpu_possible_map);
 
-	boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
-        current_thread_info()->cpu = 0;
-        num_cpus = 1;
-        for (curr_cpu = 0;
-             curr_cpu <= 65535 && num_cpus < max_cpus; curr_cpu++) {
-                if ((__u16) curr_cpu == boot_cpu_addr)
-                        continue;
-                __cpu_logical_map[num_cpus] = (__u16) curr_cpu;
-                if (signal_processor(num_cpus, sigp_sense) ==
-                    sigp_not_operational)
-                        continue;
-		cpu_set(num_cpus, cpu_possible_map);
-                num_cpus++;
-        }
-        printk("Detected %d CPU's\n",(int) num_cpus);
-        printk("Boot cpu address %2X\n", boot_cpu_addr);
+	printk("Detected %d CPU's\n",(int) num_cpus);
+	printk("Boot cpu address %2X\n", boot_cpu_addr);
 }
 
-#endif /* CONFIG_HOTPLUG_CPU */
-
 /*
  *      Activate a secondary processor.
  */
@@ -571,8 +561,6 @@
 	p = fork_idle(cpu);
 	if (IS_ERR(p))
 		panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
-	atomic_inc(&init_mm.mm_count);
-	p->active_mm = &init_mm;
 	current_set[cpu] = p;
 }
 
@@ -681,7 +669,8 @@
 	eieio();
 	signal_processor(cpu,sigp_restart);
 
-	while (!cpu_online(cpu));
+	while (!cpu_online(cpu))
+		cpu_relax();
 	return 0;
 }
 
@@ -736,13 +725,15 @@
 __cpu_die(unsigned int cpu)
 {
 	/* Wait until target cpu is down */
-	while (!cpu_stopped(cpu));
+	while (!cpu_stopped(cpu))
+		cpu_relax();
 	printk("Processor %d spun down\n", cpu);
 }
 
 void
 cpu_die(void)
 {
+	idle_task_exit();
 	signal_processor(smp_processor_id(), sigp_stop);
 	BUG();
 	for(;;);
@@ -806,6 +797,7 @@
 
 void smp_cpus_done(unsigned int max_cpus)
 {
+	cpu_present_map = cpu_possible_map;
 }
 
 /*
diff -Nru a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
--- a/arch/s390/kernel/syscalls.S	2005-01-19 13:44:45 -08:00
+++ b/arch/s390/kernel/syscalls.S	2005-01-19 13:44:45 -08:00
@@ -185,7 +185,7 @@
 SYSCALL(sys_rt_sigaction,sys_rt_sigaction,sys32_rt_sigaction_wrapper)
 SYSCALL(sys_rt_sigprocmask,sys_rt_sigprocmask,sys32_rt_sigprocmask_wrapper)	/* 175 */
 SYSCALL(sys_rt_sigpending,sys_rt_sigpending,sys32_rt_sigpending_wrapper)
-SYSCALL(sys_rt_sigtimedwait,sys_rt_sigtimedwait,compat_rt_sigtimedwait_wrapper)
+SYSCALL(sys_rt_sigtimedwait,sys_rt_sigtimedwait,compat_sys_rt_sigtimedwait_wrapper)
 SYSCALL(sys_rt_sigqueueinfo,sys_rt_sigqueueinfo,sys32_rt_sigqueueinfo_wrapper)
 SYSCALL(sys_rt_sigsuspend_glue,sys_rt_sigsuspend_glue,sys32_rt_sigsuspend_glue)
 SYSCALL(sys_pread64,sys_pread64,sys32_pread64_wrapper)		/* 180 */
diff -Nru a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
--- a/arch/s390/mm/cmm.c	2005-01-19 13:44:47 -08:00
+++ b/arch/s390/mm/cmm.c	2005-01-19 13:44:47 -08:00
@@ -124,7 +124,6 @@
 	int rc;
 
 	daemonize("cmmthread");
-	set_cpus_allowed(current, cpumask_of_cpu(0));
 	while (1) {
 		rc = wait_event_interruptible(cmm_thread_wait,
 			(cmm_pages != cmm_pages_target ||
@@ -408,14 +407,6 @@
 static int
 cmm_init (void)
 {
-	int rc;
-
-	/* Prevent logical cpu 0 from being set offline. */
-	rc = smp_get_cpu(cpumask_of_cpu(0));
-	if (rc) {
-		printk(KERN_ERR "CMM: unable to reserve cpu 0\n");
-		return rc;
-	}
 #ifdef CONFIG_CMM_PROC
 	cmm_sysctl_header = register_sysctl_table(cmm_dir_table, 1);
 #endif
@@ -439,8 +430,6 @@
 #ifdef CONFIG_CMM_IUCV
 	smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target);
 #endif
-	/* Allow logical cpu 0 to be set offline again. */
-	smp_put_cpu(0);
 }
 
 module_init(cmm_init);
diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig
--- a/arch/sh/Kconfig	2005-01-19 13:44:48 -08:00
+++ b/arch/sh/Kconfig	2005-01-19 13:44:48 -08:00
@@ -41,25 +41,25 @@
 	bool "SolutionEngine"
 	help
 	  Select SolutionEngine if configuring for a Hitachi SH7709
-	  or SH7750 evalutation board.
+	  or SH7750 evaluation board.
 
 config SH_7751_SOLUTION_ENGINE
 	bool "SolutionEngine7751"
 	help
 	  Select 7751 SolutionEngine if configuring for a Hitachi SH7751
-	  evalutation board.
+	  evaluation board.
 
 config SH_7300_SOLUTION_ENGINE
 	bool "SolutionEngine7300"
 	help
 	  Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V)
-	  evalutation board.
+	  evaluation board.
 
 config SH_73180_SOLUTION_ENGINE
        bool "SolutionEngine73180"
        help
          Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3)
-         evalutation board.
+         evaluation board.
 
 config SH_7751_SYSTEMH
 	bool "SystemH7751R"
diff -Nru a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
--- a/arch/sh/kernel/signal.c	2005-01-19 13:44:48 -08:00
+++ b/arch/sh/kernel/signal.c	2005-01-19 13:44:48 -08:00
@@ -24,7 +24,6 @@
 #include <linux/tty.h>
 #include <linux/personality.h>
 #include <linux/binfmts.h>
-#include <linux/suspend.h>
 
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
@@ -579,10 +578,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c
--- a/arch/sh64/kernel/signal.c	2005-01-19 13:44:46 -08:00
+++ b/arch/sh64/kernel/signal.c	2005-01-19 13:44:46 -08:00
@@ -701,10 +701,8 @@
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-		}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/sh64/lib/c-checksum.c b/arch/sh64/lib/c-checksum.c
--- a/arch/sh64/lib/c-checksum.c	2005-01-19 13:44:47 -08:00
+++ b/arch/sh64/lib/c-checksum.c	2005-01-19 13:44:47 -08:00
@@ -136,7 +136,7 @@
 
 /* Copy while checksumming, otherwise like csum_partial.  */
 unsigned int
-csum_partial_copy(const char *src, char *dst, int len, unsigned int sum)
+csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, unsigned int sum)
 {
 	sum = csum_partial(src, len, sum);
 	memcpy(dst, src, len);
@@ -147,7 +147,7 @@
 /* Copy from userspace and compute checksum.  If we catch an exception
    then zero the rest of the buffer.  */
 unsigned int
-csum_partial_copy_from_user(const char *src, char *dst, int len,
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
 			    unsigned int sum, int *err_ptr)
 {
 	int missing;
@@ -168,7 +168,7 @@
 
 /* Copy to userspace and compute checksum.  */
 unsigned int
-csum_partial_copy_to_user(const char *src, char *dst, int len,
+csum_partial_copy_to_user(const unsigned char *src, unsigned char *dst, int len,
 			  unsigned int sum, int *err_ptr)
 {
 	sum = csum_partial(src, len, sum);
@@ -221,7 +221,7 @@
 
 // Post SIM:
 unsigned int
-csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum)
+csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, unsigned int sum)
 {
 	//  unsigned dummy;
 	pr_debug("csum_partial_copy_nocheck src %p dst %p len %d\n", src, dst,
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/arch/sparc64/Kconfig	2005-01-19 13:44:47 -08:00
@@ -92,8 +92,8 @@
 	bool "Symmetric multi-processing support"
 	---help---
 	  This enables support for systems with more than one CPU. If you have
-	  a system with only one CPU, like most personal computers, say N. If
-	  you have a system with more than one CPU, say Y.
+	  a system with only one CPU, say N. If you have a system with more than
+	  one CPU, say Y.
 
 	  If you say N here, the kernel will run on single and multiprocessor
 	  machines, but will use only one CPU of a multiprocessor machine. If
@@ -101,17 +101,11 @@
 	  singleprocessor machines. On a singleprocessor machine, the kernel
 	  will run faster if you say N here.
 
-	  Note that if you say Y here and choose architecture "586" or
-	  "Pentium" under "Processor family", the kernel will not work on 486
-	  architectures. Similarly, multiprocessor kernels for the "PPro"
-	  architecture may not work on all Pentium based boards.
-
 	  People using multiprocessor machines who say Y here should also say
 	  Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
 	  Management" code will be disabled if you say Y here.
 
 	  See also the <file:Documentation/smp.txt>,
-	  <file:Documentation/i386/IO-APIC.txt>,
 	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
 	  <http://www.tldp.org/docs.html#howto>.
 
diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig
--- a/arch/sparc64/defconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/sparc64/defconfig	2005-01-19 13:44:46 -08:00
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.10
-# Mon Dec 27 22:36:56 2004
+# Mon Jan 10 11:24:25 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -79,6 +79,7 @@
 CONFIG_US2E_FREQ=m
 CONFIG_SPARC64=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HUGETLB_PAGE_SIZE_4MB=y
 # CONFIG_HUGETLB_PAGE_SIZE_512K is not set
 # CONFIG_HUGETLB_PAGE_SIZE_64K is not set
@@ -336,6 +337,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
 
 #
 # SCSI low-level drivers
@@ -395,7 +397,6 @@
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
 CONFIG_SCSI_DC395x=m
 # CONFIG_SCSI_DC390T is not set
 CONFIG_SCSI_DEBUG=m
@@ -619,8 +620,6 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_COMPAT_IPFWADM=m
 
 #
 # IPv6: Netfilter Configuration
@@ -894,7 +893,6 @@
 CONFIG_FORCEDETH=m
 CONFIG_DGRS=m
 CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
 CONFIG_E100=m
 CONFIG_E100_NAPI=y
 CONFIG_FEALNX=m
@@ -1081,7 +1079,6 @@
 # XFree86 DRI support
 #
 CONFIG_DRM=y
-CONFIG_DRM_FFB=m
 CONFIG_DRM_TDFX=m
 # CONFIG_DRM_R128 is not set
 
@@ -1112,13 +1109,14 @@
 # CONFIG_GAMEPORT_EMU10K1 is not set
 # CONFIG_GAMEPORT_VORTEX is not set
 # CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461x is not set
+CONFIG_GAMEPORT_CS461X=m
 CONFIG_SERIO=y
 CONFIG_SERIO_I8042=y
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PARKBD is not set
 CONFIG_SERIO_PCIPS2=m
+CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=m
 
 #
@@ -1239,6 +1237,7 @@
 # CONFIG_REISERFS_FS is not set
 CONFIG_JFS_FS=m
 CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
 CONFIG_FS_POSIX_ACL=y
@@ -1308,7 +1307,6 @@
 CONFIG_VXFS_FS=m
 CONFIG_HPFS_FS=m
 CONFIG_QNX4FS_FS=m
-# CONFIG_QNX4FS_RW is not set
 CONFIG_SYSV_FS=m
 CONFIG_UFS_FS=m
 CONFIG_UFS_FS_WRITE=y
@@ -1579,6 +1577,8 @@
 # CONFIG_SND_CS46XX_NEW_DSP is not set
 CONFIG_SND_CS4281=m
 CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_CA0106=m
 CONFIG_SND_KORG1212=m
 CONFIG_SND_MIXART=m
 CONFIG_SND_NM256=m
@@ -1603,13 +1603,13 @@
 CONFIG_SND_INTEL8X0M=m
 CONFIG_SND_SONICVIBES=m
 # CONFIG_SND_VIA82XX is not set
+CONFIG_SND_VIA82XX_MODEM=m
 CONFIG_SND_VX222=m
 
 #
 # USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
-CONFIG_SND_USB_USX2Y=m
 
 #
 # ALSA Sparc devices
@@ -1691,7 +1691,6 @@
 #
 CONFIG_USB_MDC800=m
 CONFIG_USB_MICROTEK=m
-CONFIG_USB_HPUSBSCSI=m
 
 #
 # USB Multimedia devices
@@ -1862,7 +1861,7 @@
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_KPROBES=y
diff -Nru a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
--- a/arch/sparc64/kernel/binfmt_aout32.c	2005-01-19 13:44:46 -08:00
+++ b/arch/sparc64/kernel/binfmt_aout32.c	2005-01-19 13:44:46 -08:00
@@ -49,7 +49,9 @@
 	end = PAGE_ALIGN(end);
 	if (end <= start)
 		return;
+	down_write(&current->mm->mmap_sem);
 	do_brk(start, end - start);
+	up_write(&current->mm->mmap_sem);
 }
 
 /*
@@ -246,10 +248,14 @@
 	if (N_MAGIC(ex) == NMAGIC) {
 		loff_t pos = fd_offset;
 		/* Fuck me plenty... */
+		down_write(&current->mm->mmap_sem);	
 		error = do_brk(N_TXTADDR(ex), ex.a_text);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
 			  ex.a_text, &pos);
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(N_DATADDR(ex), ex.a_data);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex),
 			  ex.a_data, &pos);
 		goto beyond_if;
@@ -257,8 +263,10 @@
 
 	if (N_MAGIC(ex) == OMAGIC) {
 		loff_t pos = fd_offset;
+		down_write(&current->mm->mmap_sem);
 		do_brk(N_TXTADDR(ex) & PAGE_MASK,
 			ex.a_text+ex.a_data + PAGE_SIZE - 1);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
 			  ex.a_text+ex.a_data, &pos);
 	} else {
@@ -272,7 +280,9 @@
 
 		if (!bprm->file->f_op->mmap) {
 			loff_t pos = fd_offset;
+			down_write(&current->mm->mmap_sem);
 			do_brk(0, ex.a_text+ex.a_data);
+			up_write(&current->mm->mmap_sem);
 			bprm->file->f_op->read(bprm->file,
 				  (char __user *)N_TXTADDR(ex),
 				  ex.a_text+ex.a_data, &pos);
@@ -389,7 +399,9 @@
 	len = PAGE_ALIGN(ex.a_text + ex.a_data);
 	bss = ex.a_text + ex.a_data + ex.a_bss;
 	if (bss > len) {
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(start_addr + len, bss - len);
+		up_write(&current->mm->mmap_sem);
 		retval = error;
 		if (error != start_addr + len)
 			goto out;
diff -Nru a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
--- a/arch/sparc64/kernel/pci_psycho.c	2005-01-19 13:44:47 -08:00
+++ b/arch/sparc64/kernel/pci_psycho.c	2005-01-19 13:44:47 -08:00
@@ -453,9 +453,9 @@
 		tag_base = regbase + PSYCHO_STC_TAG_A;
 		line_base = regbase + PSYCHO_STC_LINE_A;
 	} else {
-		err_base = regbase + PSYCHO_STC_ERR_A;
-		tag_base = regbase + PSYCHO_STC_TAG_A;
-		line_base = regbase + PSYCHO_STC_LINE_A;
+		err_base = regbase + PSYCHO_STC_ERR_B;
+		tag_base = regbase + PSYCHO_STC_TAG_B;
+		line_base = regbase + PSYCHO_STC_LINE_B;
 	}
 
 	spin_lock(&stc_buf_lock);
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	2005-01-19 13:44:47 -08:00
+++ b/arch/sparc64/kernel/sys_sparc32.c	2005-01-19 13:44:47 -08:00
@@ -1598,7 +1598,8 @@
 			    put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp))
 				error = -EFAULT;
 		}
-		copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
+		if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
+			error = -EFAULT;
 	}
 	return error;
 #endif
diff -Nru a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
--- a/arch/sparc64/kernel/sys_sunos32.c	2005-01-19 13:44:47 -08:00
+++ b/arch/sparc64/kernel/sys_sunos32.c	2005-01-19 13:44:47 -08:00
@@ -291,7 +291,8 @@
 	put_user(ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
-	copy_to_user(dirent->d_name, name, namlen);
+	if (copy_to_user(dirent->d_name, name, namlen))
+		return -EFAULT;
 	put_user(0, dirent->d_name + namlen);
 	dirent = (void __user *) dirent + reclen;
 	buf->curr = dirent;
@@ -371,7 +372,8 @@
 	put_user(ino, &dirent->d_ino);
 	put_user(namlen, &dirent->d_namlen);
 	put_user(reclen, &dirent->d_reclen);
-	copy_to_user(dirent->d_name, name, namlen);
+	if (copy_to_user(dirent->d_name, name, namlen))
+		return -EFAULT;
 	put_user(0, dirent->d_name + namlen);
 	dirent = (void __user *) dirent + reclen;
 	buf->curr = dirent;
diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
--- a/arch/sparc64/kernel/systbls.S	2005-01-19 13:44:46 -08:00
+++ b/arch/sparc64/kernel/systbls.S	2005-01-19 13:44:46 -08:00
@@ -41,7 +41,7 @@
 /*90*/	.word sys_dup2, sys_setfsuid, compat_sys_fcntl, sys32_select, sys_setfsgid
 	.word sys_fsync, sys32_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
 /*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
-	.word compat_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
+	.word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
 /*110*/	.word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
 	.word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/	.word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
diff -Nru a/arch/sparc64/lib/find_bit.c b/arch/sparc64/lib/find_bit.c
--- a/arch/sparc64/lib/find_bit.c	2005-01-19 13:44:46 -08:00
+++ b/arch/sparc64/lib/find_bit.c	2005-01-19 13:44:46 -08:00
@@ -50,9 +50,10 @@
  * on Linus's ALPHA routines, which are pretty portable BTW.
  */
 
-unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset)
+unsigned long find_next_zero_bit(const unsigned long *addr,
+			unsigned long size, unsigned long offset)
 {
-	unsigned long *p = addr + (offset >> 6);
+	const unsigned long *p = addr + (offset >> 6);
 	unsigned long result = offset & ~63UL;
 	unsigned long tmp;
 
diff -Nru a/arch/um/Kconfig b/arch/um/Kconfig
--- a/arch/um/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/arch/um/Kconfig	2005-01-19 13:44:46 -08:00
@@ -70,6 +70,16 @@
 
 source "arch/um/Kconfig_arch"
 
+config LD_SCRIPT_STATIC
+	bool
+	default y
+	depends on MODE_TT || STATIC_LINK
+
+config LD_SCRIPT_DYN
+	bool
+	default y
+	depends on !LD_SCRIPT_STATIC
+
 config NET
 	bool "Networking support"
 	help
@@ -80,7 +90,7 @@
 	should consider updating your networking tools too because changes
 	in the kernel and the tools often go hand in hand. The tools are
 	contained in the package net-tools, the location and version number
-	of which are given in Documentation/Changes.
+	of which are given in <file:Documentation/Changes>.
 
 	For a general introduction to Linux networking, it is highly
 	recommended to read the NET-HOWTO, available from
@@ -120,7 +130,7 @@
 	by removing or changing anything in /proc which gives away the
 	identity of a UML.
 
-	See http://user-mode-linux.sf.net/hppfs.html for more information.
+	See <http://user-mode-linux.sf.net/hppfs.html> for more information.
 
 	You only need this if you are setting up a UML honeypot.  Otherwise,
 	it is safe to say 'N' here.
@@ -145,6 +155,25 @@
 
         It is safe to say 'Y' here.
 
+config MAGIC_SYSRQ
+	bool "Magic SysRq key"
+	depends on MCONSOLE
+	---help---
+	If you say Y here, you will have some control over the system even
+	if the system crashes for example during kernel debugging (e.g., you
+	will be able to flush the buffer cache to disk, reboot the system
+	immediately or dump some status information). A key for each of the
+	possible requests is provided.
+
+	This is the feature normally accomplished by pressing a key
+	while holding SysRq (Alt+PrintScreen).
+
+	On UML, this is accomplished by sending a "sysrq" command with
+	mconsole, followed by the letter for the requested command.
+
+	The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
+	unless you really know what this hack does.
+
 config HOST_2G_2G
 	bool "2G/2G host address space split"
 	default n
@@ -244,7 +273,7 @@
 
 source "arch/um/Kconfig_char"
 
-source "arch/um/Kconfig_block"
+source "drivers/block/Kconfig"
 
 config NETDEVICES
 	bool
diff -Nru a/arch/um/Kconfig_block b/arch/um/Kconfig_block
--- a/arch/um/Kconfig_block	2005-01-19 13:44:47 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,105 +0,0 @@
-
-menu "Block Devices"
-
-config BLK_DEV_UBD
-	bool "Virtual block device"
-	help
-        The User-Mode Linux port includes a driver called UBD which will let
-        you access arbitrary files on the host computer as block devices.
-        Unless you know that you do not need such virtual block devices say
-        Y here.
-
-config BLK_DEV_UBD_SYNC
-	bool "Always do synchronous disk IO for UBD"
-	depends on BLK_DEV_UBD
-	help
-        Writes to the virtual block device are not immediately written to the 
-	host's disk; this may cause problems if, for example, the 
-	User-Mode Linux 'Virtual Machine' uses a journalling filesystem and 
-	the host computer crashes.
-
-        Synchronous operation (i.e. always writing data to the host's disk
-        immediately) is configurable on a per-UBD basis by using a special
-        kernel command line option.  Alternatively, you can say Y here to
-        turn on synchronous operation by default for all block devices.
-
-        If you're running a journalling file system (like reiserfs, for
-        example) in your virtual machine, you will want to say Y here.  If
-        you care for the safety of the data in your virtual machine, Y is a
-        wise choice too.  In all other cases (for example, if you're just
-        playing around with User-Mode Linux) you can choose N.
-
-config BLK_DEV_COW_COMMON
-	bool
-	default BLK_DEV_UBD
-
-config BLK_DEV_LOOP
-	tristate "Loopback device support"
-
-config BLK_DEV_NBD
-	tristate "Network block device support"
-	depends on NET
-
-config BLK_DEV_RAM
-	tristate "RAM disk support"
-
-config BLK_DEV_RAM_COUNT
-	int "Default number of RAM disks" if BLK_DEV_RAM
-	default "16"
-
-config BLK_DEV_RAM_SIZE
-	int "Default RAM disk size"
-	depends on BLK_DEV_RAM
-	default "4096"
-
-config BLK_DEV_INITRD
-	bool "Initial RAM disk (initrd) support"
-	depends on BLK_DEV_RAM=y
-
-#Copied directly from drivers/block/Kconfig
-config INITRAMFS_SOURCE
-	string "Source directory of cpio_list"
-	default ""
-	help
-	  This can be set to either a directory containing files, etc to be
-	  included in the initramfs archive, or a file containing newline
-	  separated entries.
-
-	  If it is a file, it should be in the following format:
-	    # a comment
-	    file <name> <location> <mode> <uid> <gid>
-	    dir <name> <mode> <uid> <gid>
-	    nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>
-
-	  Where:
-	    <name>      name of the file/dir/nod in the archive
-	    <location>  location of the file in the current filesystem
-	    <mode>      mode/permissions of the file
-	    <uid>       user id (0=root)
-	    <gid>       group id (0=root)
-	    <dev_type>  device type (b=block, c=character)
-	    <maj>       major number of nod
-	    <min>       minor number of nod
-
-	  If you are not sure, leave it blank.
-
-config MMAPPER
-	tristate "Example IO memory driver"
-	depends on BROKEN
-	help
-        The User-Mode Linux port can provide support for IO Memory
-        emulation with this option.  This allows a host file to be
-        specified as an I/O region on the kernel command line. That file
-        will be mapped into UML's kernel address space where a driver can
-        locate it and do whatever it wants with the memory, including
-        providing an interface to it for UML processes to use.
-
-        For more information, see
-        <http://user-mode-linux.sourceforge.net/iomem.html>.
-
-        If you'd like to be able to provide a simulated IO port space for
-        User-Mode Linux processes, say Y.  If unsure, say N.
-
-source "drivers/block/Kconfig.iosched"
-
-endmenu
diff -Nru a/arch/um/Makefile b/arch/um/Makefile
--- a/arch/um/Makefile	2005-01-19 13:44:47 -08:00
+++ b/arch/um/Makefile	2005-01-19 13:44:47 -08:00
@@ -3,7 +3,7 @@
 # Licensed under the GPL
 #
 
-ARCH_DIR = arch/um
+ARCH_DIR := arch/um
 OS := $(shell uname -s)
 # We require bash because the vmlinux link and loader script cpp use bash
 # features.
@@ -12,34 +12,38 @@
 filechk_gen_header = $<
 
 core-y			+= $(ARCH_DIR)/kernel/		\
-			   $(ARCH_DIR)/drivers/
-
-clean-dirs := sys-$(SUBARCH)
+			   $(ARCH_DIR)/drivers/		\
+			   $(ARCH_DIR)/os-$(OS)/
 
 # Have to precede the include because the included Makefiles reference them.
-SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
+SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
 	arch-signal.h module.h vm-flags.h
 SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
 
-CLEAN_FILES += $(ARCH_SYMLINKS)
-
+# The "os" symlink is only used by arch/um/include/os.h, which includes
+# ../os/include/file.h
 ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
 	$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
 
 GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
 
-MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
-MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
+um-modes-$(CONFIG_MODE_TT) += tt
+um-modes-$(CONFIG_MODE_SKAS) += skas
+
+MODE_INCLUDE	+= $(foreach mode,$(um-modes-y),\
+		   -I$(srctree)/$(ARCH_DIR)/kernel/$(mode)/include)
 
-ifneq ($(MAKEFILE-y),)
-  include $(addprefix $(srctree)/$(ARCH_DIR)/,$(MAKEFILE-y))
+MAKEFILES-INCL	+= $(foreach mode,$(um-modes-y),\
+		   $(srctree)/$(ARCH_DIR)/Makefile-$(mode))
+
+ifneq ($(MAKEFILE-INCL),)
+  include $(MAKEFILE-INCL)
 endif
 
 ARCH_INCLUDE	:= -I$(ARCH_DIR)/include
 SYS_DIR		:= $(ARCH_DIR)/include/sysdep-$(SUBARCH)
 
 include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
-include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 
 core-y += $(SUBARCH_CORE)
 libs-y += $(SUBARCH_LIBS)
@@ -50,12 +54,16 @@
 # errnos.
 
 CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
-	-D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
-	-Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
+	$(ARCH_INCLUDE) $(MODE_INCLUDE)
 
+USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
+USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
+	$(MODE_INCLUDE)
+CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask
 CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
 
-LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+#This will adjust *FLAGS accordingly to the platform.
+include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 
 # These are needed for clean and mrproper, since in that case .config is not
 # included; the values here are meaningless
@@ -85,34 +93,16 @@
 
 $(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch)
 
-CLEAN_FILES += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h \
-	$(TOPDIR)/$(ARCH_DIR)/os
-
 prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \
 	$(ARCH_DIR)/kernel/vmlinux.lds.S
 
-# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT +
-# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case.
+LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
+LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
 
-LINK_TT = -static
-LD_SCRIPT_TT := uml.lds.S
+LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S
+LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S
 
-ifeq ($(CONFIG_STATIC_LINK),y)
-  LINK-y += $(LINK_TT)
-  LD_SCRIPT-y := $(LD_SCRIPT_TT)
-else
-ifeq ($(CONFIG_MODE_TT),y)
-  LINK-y += $(LINK_TT)
-  LD_SCRIPT-y := $(LD_SCRIPT_TT)
-else
-ifeq ($(CONFIG_MODE_SKAS),y)
-  LINK-y += $(LINK_SKAS)
-  LD_SCRIPT-y := $(LD_SCRIPT_SKAS)
-endif
-endif
-endif
-
-CPP_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
+CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
 CONFIG_KERNEL_STACK_ORDER ?= 2
 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
 
@@ -122,9 +112,12 @@
 
 CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \
 	-DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
-	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
+	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \
 	-DKERNEL_STACK_SIZE=$(STACK_SIZE))
 
+#The wrappers will select whether using "malloc" or the kernel allocator.
+LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
+
 CFLAGS_vmlinux = $(LINK-y) $(LINK_WRAPS)
 define cmd_vmlinux__
 	$(CC) $(CFLAGS_vmlinux) -o $@ \
@@ -135,39 +128,27 @@
 	FORCE ,$^) ; rm -f linux
 endef
 
-USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
-USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
-USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-	$(MODE_INCLUDE)
-USER_CFLAGS += $(ARCH_USER_CFLAGS)
-
-# To get a definition of F_SETSIG
-USER_CFLAGS += -D_GNU_SOURCE
-
 #When cleaning we don't include .config, so we don't include
 #TT or skas makefiles and don't clean skas_ptregs.h.
 CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
-	$(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h \
-	$(ARCH_DIR)/util/mk_constants $(ARCH_DIR)/util/mk_task
+	$(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h
 
 MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
 	$(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os
 
-archmrproper:
-	@:
-
 archclean:
 	$(Q)$(MAKE) $(clean)=$(ARCH_DIR)/util
 	@find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
 		-o -name '*.gcov' \) -type f -print | xargs rm -f
 
 #We need to re-preprocess this when the symlink dest changes.
-#So we touch it.
+#So we touch it when needed.
 $(ARCH_DIR)/kernel/vmlinux.lds.S: FORCE
-	@echo '  SYMLINK $@'
-	$(Q)ln -sf $(LD_SCRIPT-y) $@
-	$(Q)touch $@
+	$(Q)if [ "$(shell readlink $@)" != "$(LD_SCRIPT-y)" ]; then \
+		echo '  SYMLINK $@'; \
+		ln -sf $(LD_SCRIPT-y) $@; \
+		touch $@; \
+	fi;
 
 $(SYMLINK_HEADERS):
 	@echo '  SYMLINK $@'
diff -Nru a/arch/um/Makefile-os-Linux b/arch/um/Makefile-os-Linux
--- a/arch/um/Makefile-os-Linux	2005-01-19 13:44:48 -08:00
+++ b/arch/um/Makefile-os-Linux	2005-01-19 13:44:48 -08:00
@@ -3,4 +3,6 @@
 # Licensed under the GPL
 #
 
-core-y		+= $(ARCH_DIR)/os-$(OS)/
+# To get a definition of F_SETSIG
+USER_CFLAGS += -D_GNU_SOURCE -D_LARGEFILE64_SOURCE
+CFLAGS += -D_LARGEFILE64_SOURCE
diff -Nru a/arch/um/Makefile-skas b/arch/um/Makefile-skas
--- a/arch/um/Makefile-skas	2005-01-19 13:44:46 -08:00
+++ b/arch/um/Makefile-skas	2005-01-19 13:44:46 -08:00
@@ -9,9 +9,4 @@
 CFLAGS-$(CONFIG_GPROF) += $(PROFILE)
 LINK-$(CONFIG_GPROF) += $(PROFILE)
 
-MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/kernel/skas/include
-
-LINK_SKAS = -Wl,-rpath,/lib 
-LD_SCRIPT_SKAS = dyn.lds.S
-
 GEN_HEADERS += $(ARCH_DIR)/include/skas_ptregs.h
diff -Nru a/arch/um/Makefile-tt b/arch/um/Makefile-tt
--- a/arch/um/Makefile-tt	2005-01-19 13:44:47 -08:00
+++ b/arch/um/Makefile-tt	2005-01-19 13:44:47 -08:00
@@ -3,4 +3,3 @@
 # Licensed under the GPL
 #
 
-MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/kernel/tt/include
diff -Nru a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
--- a/arch/um/drivers/chan_user.c	2005-01-19 13:44:45 -08:00
+++ b/arch/um/drivers/chan_user.c	2005-01-19 13:44:45 -08:00
@@ -49,6 +49,24 @@
 	return(-errno);
 }
 
+/*
+ * UML SIGWINCH handling
+ *
+ * The point of this is to handle SIGWINCH on consoles which have host ttys and
+ * relay them inside UML to whatever might be running on the console and cares
+ * about the window size (since SIGWINCH notifies about terminal size changes).
+ *
+ * So, we have a separate thread for each host tty attached to a UML device
+ * (side-issue - I'm annoyed that one thread can't have multiple controlling
+ * ttys for purposed of handling SIGWINCH, but I imagine there are other reasons
+ * that doesn't make any sense).
+ *
+ * SIGWINCH can't be received synchronously, so you have to set up to receive it
+ * as a signal.  That being the case, if you are going to wait for it, it is
+ * convenient to sit in a pause() and wait for the signal to bounce you out of
+ * it (see below for how we make sure to exit only on SIGWINCH).
+ */
+
 static void winch_handler(int sig)
 {
 }
@@ -75,9 +93,14 @@
 		printk("winch_thread : failed to write synchronization "
 		       "byte, err = %d\n", -count);
 
+	/* We are not using SIG_IGN on purpose, so don't fix it as I thought to
+	 * do! If using SIG_IGN, the pause() call below would not stop on
+	 * SIGWINCH. */
+
 	signal(SIGWINCH, winch_handler);
 	sigfillset(&sigs);
 	sigdelset(&sigs, SIGWINCH);
+	/* Block anything else than SIGWINCH. */
 	if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){
 		printk("winch_thread : sigprocmask failed, errno = %d\n", 
 		       errno);
@@ -95,12 +118,18 @@
 		exit(1);
 	}
 
+	/* These are synchronization calls between various UML threads on the
+	 * host - since they are not different kernel threads, we cannot use
+	 * kernel semaphores. We don't use SysV semaphores because they are
+	 * persistant. */
 	count = os_read_file(pipe_fd, &c, sizeof(c));
 	if(count != sizeof(c))
 		printk("winch_thread : failed to read synchronization byte, "
 		       "err = %d\n", -count);
 
 	while(1){
+		/* This will be interrupted by SIGWINCH only, since other signals
+		 * are blocked.*/
 		pause();
 
 		count = os_write_file(pipe_fd, &c, sizeof(c));
diff -Nru a/arch/um/drivers/line.c b/arch/um/drivers/line.c
--- a/arch/um/drivers/line.c	2005-01-19 13:44:47 -08:00
+++ b/arch/um/drivers/line.c	2005-01-19 13:44:47 -08:00
@@ -593,8 +593,8 @@
 		}
 	}
 	tty  = winch->tty;
-	line = tty->driver_data;
 	if (tty != NULL) {
+		line = tty->driver_data;
 		chan_window_size(&line->chan_list,
 				 &tty->winsize.ws_row, 
 				 &tty->winsize.ws_col);
diff -Nru a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
--- a/arch/um/drivers/ubd_kern.c	2005-01-19 13:44:46 -08:00
+++ b/arch/um/drivers/ubd_kern.c	2005-01-19 13:44:46 -08:00
@@ -53,6 +53,60 @@
 #include "os.h"
 #include "mem.h"
 #include "mem_kern.h"
+#include "cow.h"
+
+enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
+
+struct io_thread_req {
+	enum ubd_req op;
+	int fds[2];
+	unsigned long offsets[2];
+	unsigned long long offset;
+	unsigned long length;
+	char *buffer;
+	int sectorsize;
+	unsigned long sector_mask;
+	unsigned long long cow_offset;
+	unsigned long bitmap_words[2];
+	int map_fd;
+	unsigned long long map_offset;
+	int error;
+};
+
+extern int open_ubd_file(char *file, struct openflags *openflags,
+			 char **backing_file_out, int *bitmap_offset_out,
+			 unsigned long *bitmap_len_out, int *data_offset_out,
+			 int *create_cow_out);
+extern int create_cow_file(char *cow_file, char *backing_file,
+			   struct openflags flags, int sectorsize,
+			   int alignment, int *bitmap_offset_out,
+			   unsigned long *bitmap_len_out,
+			   int *data_offset_out);
+extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
+extern void do_io(struct io_thread_req *req);
+
+static inline int ubd_test_bit(__u64 bit, unsigned char *data)
+{
+	__u64 n;
+	int bits, off;
+
+	bits = sizeof(data[0]) * 8;
+	n = bit / bits;
+	off = bit % bits;
+	return((data[n] & (1 << off)) != 0);
+}
+
+static inline void ubd_set_bit(__u64 bit, unsigned char *data)
+{
+	__u64 n;
+	int bits, off;
+
+	bits = sizeof(data[0]) * 8;
+	n = bit / bits;
+	off = bit % bits;
+	data[n] |= (1 << off);
+}
+/*End stuff from ubd_user.h*/
 
 #define DRIVER_NAME "uml-blkdev"
 
@@ -250,7 +304,7 @@
 	struct ubd *dev;
 	struct openflags flags = global_openflags;
 	char *backing_file;
-	int n, err;
+	int n, err, i;
 
 	if(index_out) *index_out = -1;
 	n = *str;
@@ -267,7 +321,7 @@
 		}
 
 		if(!strcmp(str, "sync")){
-			global_openflags.s = 1;
+			global_openflags = of_sync(global_openflags);
 			return(0);
 		}
 		major = simple_strtoul(str, &end, 0);
@@ -312,31 +366,47 @@
 	dev = &ubd_dev[n];
 	if(dev->file != NULL){
 		printk(KERN_ERR "ubd_setup : device already configured\n");
-		goto out2;
+		goto out;
 	}
 
-	if(index_out) *index_out = n;
+	if (index_out)
+		*index_out = n;
 
-	if (*str == 'r'){
-		flags.w = 0;
-		str++;
-	}
-	if (*str == 's'){
-		flags.s = 1;
-		str++;
-	}
-	if (*str == 'd'){
-		dev->no_cow = 1;
+	for (i = 0; i < 4; i++) {
+		switch (*str) {
+		case 'r':
+			flags.w = 0;
+			break;
+		case 's':
+			flags.s = 1;
+			break;
+		case 'd':
+			dev->no_cow = 1;
+			break;
+		case '=':
+			str++;
+			goto break_loop;
+		default:
+			printk(KERN_ERR "ubd_setup : Expected '=' or flag letter (r,s or d)\n");
+			goto out;
+		}
 		str++;
 	}
 
-	if(*str++ != '='){
+        if (*str == '=')
+		printk(KERN_ERR "ubd_setup : Too many flags specified\n");
+        else
 		printk(KERN_ERR "ubd_setup : Expected '='\n");
-		goto out2;
-	}
+	goto out;
 
+break_loop:
 	err = 0;
 	backing_file = strchr(str, ',');
+
+	if (!backing_file) {
+		backing_file = strchr(str, ':');
+	}
+
 	if(backing_file){
 		if(dev->no_cow)
 			printk(KERN_ERR "Can't specify both 'd' and a "
@@ -349,7 +419,7 @@
 	dev->file = str;
 	dev->cow.file = backing_file;
 	dev->boot_openflags = flags;
- out2:
+out:
 	spin_unlock(&ubd_lock);
 	return(err);
 }
@@ -362,17 +432,25 @@
 
 __setup("ubd", ubd_setup);
 __uml_help(ubd_setup,
-"ubd<n>=<filename>\n"
+"ubd<n><flags>=<filename>[(:|,)<filename2>]\n"
 "    This is used to associate a device with a file in the underlying\n"
-"    filesystem. Usually, there is a filesystem in the file, but \n"
+"    filesystem. When specifying two filenames, the first one is the\n"
+"    COW name and the second is the backing file name. As separator you can\n"
+"    use either a ':' or a ',': the first one allows writing things like;\n"
+"	ubd0=~/Uml/root_cow:~/Uml/root_backing_file\n"
+"    while with a ',' the shell would not expand the 2nd '~'.\n"
+"    When using only one filename, UML will detect whether to thread it like\n"
+"    a COW file or a backing file. To override this detection, add the 'd'\n"
+"    flag:\n"
+"	ubd0d=BackingFile\n"
+"    Usually, there is a filesystem in the file, but \n"
 "    that's not required. Swap devices containing swap files can be\n"
 "    specified like this. Also, a file which doesn't contain a\n"
 "    filesystem can have its contents read in the virtual \n"
-"    machine by running dd on the device. n must be in the range\n"
+"    machine by running 'dd' on the device. <n> must be in the range\n"
 "    0 to 7. Appending an 'r' to the number will cause that device\n"
 "    to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
-"    an 's' (has to be _after_ 'r', if there is one) will cause data\n"
-"    to be written to disk on the host immediately.\n\n"
+"    an 's' will cause data to be written to disk on the host immediately.\n\n"
 );
 
 static int fakehd_set = 0;
@@ -433,7 +511,7 @@
 
 	do_ubd = NULL;
 	intr_count++;
-	n = read_ubd_fs(thread_fd, &req, sizeof(req));
+	n = os_read_file(thread_fd, &req, sizeof(req));
 	if(n != sizeof(req)){
 		printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
 		       "err = %d\n", os_getpid(), -n);
@@ -1075,7 +1153,7 @@
 		err = prepare_request(req, &io_req);
 		if(!err){
 			do_ubd = ubd_handler;
-			n = write_ubd_fs(thread_fd, (char *) &io_req, 
+			n = os_write_file(thread_fd, (char *) &io_req,
 					 sizeof(io_req));
 			if(n != sizeof(io_req))
 				printk("write to io thread failed, "
@@ -1262,6 +1340,304 @@
 }
 
 __initcall(ubd_remapper_setup);
+
+static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+{
+	struct uml_stat buf1, buf2;
+	int err;
+
+	if(from_cmdline == NULL) return(1);
+	if(!strcmp(from_cmdline, from_cow)) return(1);
+
+	err = os_stat_file(from_cmdline, &buf1);
+	if(err < 0){
+		printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
+		return(1);
+	}
+	err = os_stat_file(from_cow, &buf2);
+	if(err < 0){
+		printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
+		return(1);
+	}
+	if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
+		return(1);
+
+	printk("Backing file mismatch - \"%s\" requested,\n"
+	       "\"%s\" specified in COW header of \"%s\"\n",
+	       from_cmdline, from_cow, cow);
+	return(0);
+}
+
+static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
+{
+	unsigned long modtime;
+	long long actual;
+	int err;
+
+	err = os_file_modtime(file, &modtime);
+	if(err < 0){
+		printk("Failed to get modification time of backing file "
+		       "\"%s\", err = %d\n", file, -err);
+		return(err);
+	}
+
+	err = os_file_size(file, &actual);
+	if(err < 0){
+		printk("Failed to get size of backing file \"%s\", "
+		       "err = %d\n", file, -err);
+		return(err);
+	}
+
+  	if(actual != size){
+		/*__u64 can be a long on AMD64 and with %lu GCC complains; so
+		 * the typecast.*/
+		printk("Size mismatch (%llu vs %llu) of COW header vs backing "
+		       "file\n", (unsigned long long) size, actual);
+		return(-EINVAL);
+	}
+	if(modtime != mtime){
+		printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
+		       "file\n", mtime, modtime);
+		return(-EINVAL);
+	}
+	return(0);
+}
+
+int read_cow_bitmap(int fd, void *buf, int offset, int len)
+{
+	int err;
+
+	err = os_seek_file(fd, offset);
+	if(err < 0)
+		return(err);
+
+	err = os_read_file(fd, buf, len);
+	if(err < 0)
+		return(err);
+
+	return(0);
+}
+
+int open_ubd_file(char *file, struct openflags *openflags,
+		  char **backing_file_out, int *bitmap_offset_out,
+		  unsigned long *bitmap_len_out, int *data_offset_out,
+		  int *create_cow_out)
+{
+	time_t mtime;
+	unsigned long long size;
+	__u32 version, align;
+	char *backing_file;
+	int fd, err, sectorsize, same, mode = 0644;
+
+	fd = os_open_file(file, *openflags, mode);
+	if(fd < 0){
+		if((fd == -ENOENT) && (create_cow_out != NULL))
+			*create_cow_out = 1;
+                if(!openflags->w ||
+                   ((fd != -EROFS) && (fd != -EACCES))) return(fd);
+		openflags->w = 0;
+		fd = os_open_file(file, *openflags, mode);
+		if(fd < 0)
+			return(fd);
+        }
+
+	err = os_lock_file(fd, openflags->w);
+	if(err < 0){
+		printk("Failed to lock '%s', err = %d\n", file, -err);
+		goto out_close;
+	}
+
+	if(backing_file_out == NULL) return(fd);
+
+	err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
+			      &size, &sectorsize, &align, bitmap_offset_out);
+	if(err && (*backing_file_out != NULL)){
+		printk("Failed to read COW header from COW file \"%s\", "
+		       "errno = %d\n", file, -err);
+		goto out_close;
+	}
+	if(err) return(fd);
+
+	if(backing_file_out == NULL) return(fd);
+
+	same = same_backing_files(*backing_file_out, backing_file, file);
+
+	if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
+		printk("Switching backing file to '%s'\n", *backing_file_out);
+		err = write_cow_header(file, fd, *backing_file_out,
+				       sectorsize, align, &size);
+		if(err){
+			printk("Switch failed, errno = %d\n", -err);
+			return(err);
+		}
+	}
+	else {
+		*backing_file_out = backing_file;
+		err = backing_file_mismatch(*backing_file_out, size, mtime);
+		if(err) goto out_close;
+	}
+
+	cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
+		  bitmap_len_out, data_offset_out);
+
+        return(fd);
+ out_close:
+	os_close_file(fd);
+	return(err);
+}
+
+int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
+		    int sectorsize, int alignment, int *bitmap_offset_out,
+		    unsigned long *bitmap_len_out, int *data_offset_out)
+{
+	int err, fd;
+
+	flags.c = 1;
+	fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
+	if(fd < 0){
+		err = fd;
+		printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
+		       -err);
+		goto out;
+	}
+
+	err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
+			    bitmap_offset_out, bitmap_len_out,
+			    data_offset_out);
+	if(!err)
+		return(fd);
+	os_close_file(fd);
+ out:
+	return(err);
+}
+
+static int update_bitmap(struct io_thread_req *req)
+{
+	int n;
+
+	if(req->cow_offset == -1)
+		return(0);
+
+	n = os_seek_file(req->fds[1], req->cow_offset);
+	if(n < 0){
+		printk("do_io - bitmap lseek failed : err = %d\n", -n);
+		return(1);
+	}
+
+	n = os_write_file(req->fds[1], &req->bitmap_words,
+		          sizeof(req->bitmap_words));
+	if(n != sizeof(req->bitmap_words)){
+		printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
+		       req->fds[1]);
+		return(1);
+	}
+
+	return(0);
+}
+
+void do_io(struct io_thread_req *req)
+{
+	char *buf;
+	unsigned long len;
+	int n, nsectors, start, end, bit;
+	int err;
+	__u64 off;
+
+	if(req->op == UBD_MMAP){
+		/* Touch the page to force the host to do any necessary IO to
+		 * get it into memory
+		 */
+		n = *((volatile int *) req->buffer);
+		req->error = update_bitmap(req);
+		return;
+	}
+
+	nsectors = req->length / req->sectorsize;
+	start = 0;
+	do {
+		bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
+		end = start;
+		while((end < nsectors) &&
+		      (ubd_test_bit(end, (unsigned char *)
+				    &req->sector_mask) == bit))
+			end++;
+
+		off = req->offset + req->offsets[bit] +
+			start * req->sectorsize;
+		len = (end - start) * req->sectorsize;
+		buf = &req->buffer[start * req->sectorsize];
+
+		err = os_seek_file(req->fds[bit], off);
+		if(err < 0){
+			printk("do_io - lseek failed : err = %d\n", -err);
+			req->error = 1;
+			return;
+		}
+		if(req->op == UBD_READ){
+			n = 0;
+			do {
+				buf = &buf[n];
+				len -= n;
+				n = os_read_file(req->fds[bit], buf, len);
+				if (n < 0) {
+					printk("do_io - read failed, err = %d "
+					       "fd = %d\n", -n, req->fds[bit]);
+					req->error = 1;
+					return;
+				}
+			} while((n < len) && (n != 0));
+			if (n < len) memset(&buf[n], 0, len - n);
+		}
+		else {
+			n = os_write_file(req->fds[bit], buf, len);
+			if(n != len){
+				printk("do_io - write failed err = %d "
+				       "fd = %d\n", -n, req->fds[bit]);
+				req->error = 1;
+				return;
+			}
+		}
+
+		start = end;
+	} while(start < nsectors);
+
+	req->error = update_bitmap(req);
+}
+
+/* Changed in start_io_thread, which is serialized by being called only
+ * from ubd_init, which is an initcall.
+ */
+int kernel_fd = -1;
+
+/* Only changed by the io thread */
+int io_count = 0;
+
+int io_thread(void *arg)
+{
+	struct io_thread_req req;
+	int n;
+
+	ignore_sigwinch_sig();
+	while(1){
+		n = os_read_file(kernel_fd, &req, sizeof(req));
+		if(n != sizeof(req)){
+			if(n < 0)
+				printk("io_thread - read failed, fd = %d, "
+				       "err = %d\n", kernel_fd, -n);
+			else {
+				printk("io_thread - short read, fd = %d, "
+				       "length = %d\n", kernel_fd, n);
+			}
+			continue;
+		}
+		io_count++;
+		do_io(&req);
+		n = os_write_file(kernel_fd, &req, sizeof(req));
+		if(n != sizeof(req))
+			printk("io_thread - write failed, fd = %d, err = %d\n",
+			       kernel_fd, -n);
+	}
+}
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
--- a/arch/um/drivers/ubd_user.c	2005-01-19 13:44:46 -08:00
+++ b/arch/um/drivers/ubd_user.c	2005-01-19 13:44:46 -08:00
@@ -26,311 +26,9 @@
 #include <endian.h>
 #include <byteswap.h>
 
-static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
+void ignore_sigwinch_sig(void)
 {
-	struct uml_stat buf1, buf2;
-	int err;
-
-	if(from_cmdline == NULL) return(1);
-	if(!strcmp(from_cmdline, from_cow)) return(1);
-
-	err = os_stat_file(from_cmdline, &buf1);
-	if(err < 0){
-		printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
-		return(1);
-	}
-	err = os_stat_file(from_cow, &buf2);
-	if(err < 0){
-		printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
-		return(1);
-	}
-	if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
-		return(1);
-
-	printk("Backing file mismatch - \"%s\" requested,\n"
-	       "\"%s\" specified in COW header of \"%s\"\n",
-	       from_cmdline, from_cow, cow);
-	return(0);
-}
-
-static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
-{
-	unsigned long modtime;
-	long long actual;
-	int err;
-
-	err = os_file_modtime(file, &modtime);
-	if(err < 0){
-		printk("Failed to get modification time of backing file "
-		       "\"%s\", err = %d\n", file, -err);
-		return(err);
-	}
-
-	err = os_file_size(file, &actual);
-	if(err < 0){
-		printk("Failed to get size of backing file \"%s\", "
-		       "err = %d\n", file, -err);
-		return(err);
-	}
-
-  	if(actual != size){
-		printk("Size mismatch (%ld vs %ld) of COW header vs backing "
-		       "file\n", size, actual);
-		return(-EINVAL);
-	}
-	if(modtime != mtime){
-		printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
-		       "file\n", mtime, modtime);
-		return(-EINVAL);
-	}
-	return(0);
-}
-
-int read_cow_bitmap(int fd, void *buf, int offset, int len)
-{
-	int err;
-
-	err = os_seek_file(fd, offset);
-	if(err < 0)
-		return(err);
-
-	err = os_read_file(fd, buf, len);
-	if(err < 0)
-		return(err);
-
-	return(0);
-}
-
-int open_ubd_file(char *file, struct openflags *openflags, 
-		  char **backing_file_out, int *bitmap_offset_out, 
-		  unsigned long *bitmap_len_out, int *data_offset_out, 
-		  int *create_cow_out)
-{
-	time_t mtime;
-	unsigned long long size;
-	__u32 version, align;
-	char *backing_file;
-	int fd, err, sectorsize, same, mode = 0644;
-
-	fd = os_open_file(file, *openflags, mode);
-	if(fd < 0){
-		if((fd == -ENOENT) && (create_cow_out != NULL))
-			*create_cow_out = 1;
-                if(!openflags->w ||
-                   ((errno != EROFS) && (errno != EACCES))) return(-errno);
-		openflags->w = 0;
-		fd = os_open_file(file, *openflags, mode);
-		if(fd < 0)
-			return(fd);
-        }
-
-	err = os_lock_file(fd, openflags->w);
-	if(err < 0){
-		printk("Failed to lock '%s', err = %d\n", file, -err);
-		goto out_close;
-	}
-
-	if(backing_file_out == NULL) return(fd);
-
-	err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
-			      &size, &sectorsize, &align, bitmap_offset_out);
-	if(err && (*backing_file_out != NULL)){
-		printk("Failed to read COW header from COW file \"%s\", "
-		       "errno = %d\n", file, -err);
-		goto out_close;
-	}
-	if(err) return(fd);
-
-	if(backing_file_out == NULL) return(fd);
-	
-	same = same_backing_files(*backing_file_out, backing_file, file);
-
-	if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
-		printk("Switching backing file to '%s'\n", *backing_file_out);
-		err = write_cow_header(file, fd, *backing_file_out,
-				       sectorsize, align, &size);
-		if(err){
-			printk("Switch failed, errno = %d\n", -err);
-			return(err);
-		}
-	}
-	else {
-		*backing_file_out = backing_file;
-		err = backing_file_mismatch(*backing_file_out, size, mtime);
-		if(err) goto out_close;
-	}
-
-	cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
-		  bitmap_len_out, data_offset_out);
-
-        return(fd);
- out_close:
-	os_close_file(fd);
-	return(err);
-}
-
-int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
-		    int sectorsize, int alignment, int *bitmap_offset_out,
-		    unsigned long *bitmap_len_out, int *data_offset_out)
-{
-	int err, fd;
-
-	flags.c = 1;
-	fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
-	if(fd < 0){
-		err = fd;
-		printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
-		       -err);
-		goto out;
-	}
-
-	err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
-			    bitmap_offset_out, bitmap_len_out,
-			    data_offset_out);
-	if(!err)
-		return(fd);
-	os_close_file(fd);
- out:
-	return(err);
-}
-
-/* XXX Just trivial wrappers around os_read_file and os_write_file */
-int read_ubd_fs(int fd, void *buffer, int len)
-{
-	return(os_read_file(fd, buffer, len));
-}
-
-int write_ubd_fs(int fd, char *buffer, int len)
-{
-	return(os_write_file(fd, buffer, len));
-}
-
-static int update_bitmap(struct io_thread_req *req)
-{
-	int n;
-
-	if(req->cow_offset == -1)
-		return(0);
-
-	n = os_seek_file(req->fds[1], req->cow_offset);
-	if(n < 0){
-		printk("do_io - bitmap lseek failed : err = %d\n", -n);
-		return(1);
-	}
-
-	n = os_write_file(req->fds[1], &req->bitmap_words,
-		          sizeof(req->bitmap_words));
-	if(n != sizeof(req->bitmap_words)){
-		printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
-		       req->fds[1]);
-		return(1);
-	}
-
-	return(0);
-}
-
-void do_io(struct io_thread_req *req)
-{
-	char *buf;
-	unsigned long len;
-	int n, nsectors, start, end, bit;
-	int err;
-	__u64 off;
-
-	if(req->op == UBD_MMAP){
-		/* Touch the page to force the host to do any necessary IO to
-		 * get it into memory
-		 */
-		n = *((volatile int *) req->buffer);
-		req->error = update_bitmap(req);
-		return;
-	}
-
-	nsectors = req->length / req->sectorsize;
-	start = 0;
-	do {
-		bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
-		end = start;
-		while((end < nsectors) && 
-		      (ubd_test_bit(end, (unsigned char *) 
-				    &req->sector_mask) == bit))
-			end++;
-
-		off = req->offset + req->offsets[bit] + 
-			start * req->sectorsize;
-		len = (end - start) * req->sectorsize;
-		buf = &req->buffer[start * req->sectorsize];
-
-		err = os_seek_file(req->fds[bit], off);
-		if(err < 0){
-			printk("do_io - lseek failed : err = %d\n", -err);
-			req->error = 1;
-			return;
-		}
-		if(req->op == UBD_READ){
-			n = 0;
-			do {
-				buf = &buf[n];
-				len -= n;
-				n = os_read_file(req->fds[bit], buf, len);
-				if (n < 0) {
-					printk("do_io - read failed, err = %d "
-					       "fd = %d\n", -n, req->fds[bit]);
-					req->error = 1;
-					return;
-				}
-			} while((n < len) && (n != 0));
-			if (n < len) memset(&buf[n], 0, len - n);
-		}
-		else {
-			n = os_write_file(req->fds[bit], buf, len);
-			if(n != len){
-				printk("do_io - write failed err = %d "
-				       "fd = %d\n", -n, req->fds[bit]);
-				req->error = 1;
-				return;
-			}
-		}
-
-		start = end;
-	} while(start < nsectors);
-
-	req->error = update_bitmap(req);
-}
-
-/* Changed in start_io_thread, which is serialized by being called only
- * from ubd_init, which is an initcall.
- */
-int kernel_fd = -1;
-
-/* Only changed by the io thread */
-int io_count = 0;
-
-int io_thread(void *arg)
-{
-	struct io_thread_req req;
-	int n;
-
 	signal(SIGWINCH, SIG_IGN);
-	while(1){
-		n = os_read_file(kernel_fd, &req, sizeof(req));
-		if(n != sizeof(req)){
-			if(n < 0)
-				printk("io_thread - read failed, fd = %d, "
-				       "err = %d\n", kernel_fd, -n);
-			else {
-				printk("io_thread - short read, fd = %d, "
-				       "length = %d\n", kernel_fd, n);
-			}
-			continue;
-		}
-		io_count++;
-		do_io(&req);
-		n = os_write_file(kernel_fd, &req, sizeof(req));
-		if(n != sizeof(req))
-			printk("io_thread - write failed, fd = %d, err = %d\n",
-			       kernel_fd, -n);
-	}
 }
 
 int start_io_thread(unsigned long sp, int *fd_out)
diff -Nru a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
--- a/arch/um/drivers/xterm.c	2005-01-19 13:44:45 -08:00
+++ b/arch/um/drivers/xterm.c	2005-01-19 13:44:45 -08:00
@@ -97,6 +97,13 @@
 	if(os_access(argv[4], OS_ACC_X_OK) < 0)
 		argv[4] = "port-helper";
 
+	/* Check that DISPLAY is set, this doesn't guarantee the xterm
+	 * will work but w/o it we can be pretty sure it won't. */
+	if (!getenv("DISPLAY")) {
+		printk("xterm_open: $DISPLAY not set.\n");
+		return -ENODEV;
+	}
+
 	fd = mkstemp(file);
 	if(fd < 0){
 		printk("xterm_open : mkstemp failed, errno = %d\n", errno);
diff -Nru a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
--- a/arch/um/drivers/xterm_kern.c	2005-01-19 13:44:47 -08:00
+++ b/arch/um/drivers/xterm_kern.c	2005-01-19 13:44:47 -08:00
@@ -46,6 +46,8 @@
 		printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n");
 		return(-ENOMEM);
 	}
+
+	/* This is a locked semaphore... */
 	*data = ((struct xterm_wait) 
 		{ .sem  	= __SEMAPHORE_INITIALIZER(data->sem, 0),
 		  .fd 		= socket,
@@ -55,12 +57,17 @@
 	err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 
 			     SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
 			     "xterm", data);
-	if(err){
+	if (err){
 		printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
 		       "err = %d\n",  err);
 		ret = err;
 		goto out;
 	}
+
+	/* ... so here we wait for an xterm interrupt.
+	 *
+	 * XXX Note, if the xterm doesn't work for some reason (eg. DISPLAY
+	 * isn't set) this will hang... */
 	down(&data->sem);
 
 	free_irq_by_irq_and_dev(XTERM_IRQ, data);
diff -Nru a/arch/um/include/init.h b/arch/um/include/init.h
--- a/arch/um/include/init.h	2005-01-19 13:44:46 -08:00
+++ b/arch/um/include/init.h	2005-01-19 13:44:46 -08:00
@@ -40,9 +40,18 @@
 typedef int (*initcall_t)(void);
 typedef void (*exitcall_t)(void);
 
-#define __init          __attribute__ ((__section__ (".text.init")))
-#define __exit          __attribute__ ((unused, __section__(".text.exit")))
-#define __initdata      __attribute__ ((__section__ (".data.init")))
+/* These are for everybody (although not all archs will actually
+   discard it in modules) */
+#define __init		__attribute__ ((__section__ (".init.text")))
+#define __initdata	__attribute__ ((__section__ (".init.data")))
+#define __exitdata	__attribute__ ((__section__(".exit.data")))
+#define __exit_call	__attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
+
+#ifdef MODULE
+#define __exit		__attribute__ ((__section__(".exit.text")))
+#else
+#define __exit		__attribute_used__ __attribute__ ((__section__(".exit.text")))
+#endif
 
 #endif
 
@@ -94,11 +103,11 @@
  * Mark functions and data as being only used at initialization
  * or exit time.
  */
-#define __uml_init_setup	__attribute__ ((unused,__section__ (".uml.setup.init")))
-#define __uml_setup_help	__attribute__ ((unused,__section__ (".uml.help.init")))
-#define __uml_init_call		__attribute__ ((unused,__section__ (".uml.initcall.init")))
-#define __uml_postsetup_call	__attribute__ ((unused,__section__ (".uml.postsetup.init")))
-#define __uml_exit_call		__attribute__ ((unused,__section__ (".uml.exitcall.exit")))
+#define __uml_init_setup	__attribute_used__ __attribute__ ((__section__ (".uml.setup.init")))
+#define __uml_setup_help	__attribute_used__ __attribute__ ((__section__ (".uml.help.init")))
+#define __uml_init_call		__attribute_used__ __attribute__ ((__section__ (".uml.initcall.init")))
+#define __uml_postsetup_call	__attribute_used__ __attribute__ ((__section__ (".uml.postsetup.init")))
+#define __uml_exit_call		__attribute_used__ __attribute__ ((__section__ (".uml.exitcall.exit")))
 
 #endif /* _LINUX_UML_INIT_H */
 
diff -Nru a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h
--- a/arch/um/include/sysdep-i386/checksum.h	2005-01-19 13:44:48 -08:00
+++ b/arch/um/include/sysdep-i386/checksum.h	2005-01-19 13:44:48 -08:00
@@ -31,10 +31,10 @@
  * better 64-bit) boundary
  */
 
-unsigned int csum_partial_copy_to(const char *src, char *dst, int len, 
-				  int sum, int *err_ptr);
-unsigned int csum_partial_copy_from(const char *src, char *dst, int len, 
-				    int sum, int *err_ptr);
+unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst,
+				  int len, int sum, int *err_ptr);
+unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst,
+				    int len, int sum, int *err_ptr);
 
 /*
  *	Note: when you get a NULL pointer exception here this means someone
@@ -45,7 +45,7 @@
  */
 
 static __inline__
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
 				       int len, int sum)
 {
 	memcpy(dst, src, len);
@@ -53,7 +53,7 @@
 }
 
 static __inline__
-unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
 					 int len, int sum, int *err_ptr)
 {
 	return csum_partial_copy_from(src, dst, len, sum, err_ptr);
@@ -67,7 +67,7 @@
  */
 
 #define csum_partial_copy_fromuser csum_partial_copy_from_user
-unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum);
 
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,
@@ -192,9 +192,9 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user(const char *src, 
-						     char *dst, int len,
-						     int sum, int *err_ptr)
+static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
+						     unsigned char *dst,
+						     int len, int sum, int *err_ptr)
 {
 	if (access_ok(VERIFY_WRITE, dst, len))
 		return(csum_partial_copy_to(src, dst, len, sum, err_ptr));
diff -Nru a/arch/um/include/ubd_user.h b/arch/um/include/ubd_user.h
--- a/arch/um/include/ubd_user.h	2005-01-19 13:44:47 -08:00
+++ b/arch/um/include/ubd_user.h	2005-01-19 13:44:47 -08:00
@@ -7,63 +7,10 @@
 #ifndef __UM_UBD_USER_H
 #define __UM_UBD_USER_H
 
-#include "os.h"
-
-enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
-
-struct io_thread_req {
-	enum ubd_req op;
-	int fds[2];
-	unsigned long offsets[2];
-	unsigned long long offset;
-	unsigned long length;
-	char *buffer;
-	int sectorsize;
-	unsigned long sector_mask;
-	unsigned long long cow_offset;
-	unsigned long bitmap_words[2];
-	int map_fd;
-	unsigned long long map_offset;
-	int error;
-};
-
-extern int open_ubd_file(char *file, struct openflags *openflags, 
-			 char **backing_file_out, int *bitmap_offset_out, 
-			 unsigned long *bitmap_len_out, int *data_offset_out,
-			 int *create_cow_out);
-extern int create_cow_file(char *cow_file, char *backing_file, 
-			   struct openflags flags, int sectorsize, 
-			   int alignment, int *bitmap_offset_out,
-			   unsigned long *bitmap_len_out,
-			   int *data_offset_out);
-extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
-extern int read_ubd_fs(int fd, void *buffer, int len);
-extern int write_ubd_fs(int fd, char *buffer, int len);
+extern void ignore_sigwinch_sig(void);
 extern int start_io_thread(unsigned long sp, int *fds_out);
-extern void do_io(struct io_thread_req *req);
-
-static inline int ubd_test_bit(__u64 bit, unsigned char *data)
-{
-	__u64 n;
-	int bits, off;
-
-	bits = sizeof(data[0]) * 8;
-	n = bit / bits;
-	off = bit % bits;
-	return((data[n] & (1 << off)) != 0);
-}
-
-static inline void ubd_set_bit(__u64 bit, unsigned char *data)
-{
-	__u64 n;
-	int bits, off;
-
-	bits = sizeof(data[0]) * 8;
-	n = bit / bits;
-	off = bit % bits;
-	data[n] |= (1 << off);
-}
-
+extern int io_thread(void *arg);
+extern int kernel_fd;
 
 #endif
 
diff -Nru a/arch/um/include/umn.h b/arch/um/include/umn.h
--- a/arch/um/include/umn.h	2005-01-19 13:44:46 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,27 +0,0 @@
-/* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __UMN_H
-#define __UMN_H
-
-extern int open_umn_tty(int *slave_out, int *slipno_out);
-extern void close_umn_tty(int master, int slave);
-extern int umn_send_packet(int fd, void *data, int len);
-extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
-extern void slip_unesc(unsigned char s);
-extern void umn_read(int fd);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff -Nru a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c
--- a/arch/um/kernel/checksum.c	2005-01-19 13:44:47 -08:00
+++ b/arch/um/kernel/checksum.c	2005-01-19 13:44:47 -08:00
@@ -2,17 +2,17 @@
 #include "linux/errno.h"
 #include "linux/module.h"
 
-unsigned int arch_csum_partial(const char *buff, int len, int sum);
+unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum);
 
-unsigned int csum_partial(char *buff, int len, int sum)
+unsigned int csum_partial(unsigned char *buff, int len, int sum)
 {
 	return arch_csum_partial(buff, len, sum);
 }
 
 EXPORT_SYMBOL(csum_partial);
 
-unsigned int csum_partial_copy_to(const char *src, char __user *dst, int len,
-				  int sum, int *err_ptr)
+unsigned int csum_partial_copy_to(const unsigned char *src, char __user *dst,
+				int len, int sum, int *err_ptr)
 {
 	if(copy_to_user(dst, src, len)){
 		*err_ptr = -EFAULT;
@@ -22,8 +22,8 @@
 	return(arch_csum_partial(src, len, sum));
 }
 
-unsigned int csum_partial_copy_from(const char __user *src, char *dst, int len,
-				    int sum, int *err_ptr)
+unsigned int csum_partial_copy_from(const unsigned char __user *src, char *dst,
+				int len, int sum, int *err_ptr)
 {
 	if(copy_from_user(dst, src, len)){
 		*err_ptr = -EFAULT;
diff -Nru a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
--- a/arch/um/kernel/dyn.lds.S	2005-01-19 13:44:46 -08:00
+++ b/arch/um/kernel/dyn.lds.S	2005-01-19 13:44:46 -08:00
@@ -7,8 +7,11 @@
 
 SECTIONS
 {
+  PROVIDE (__executable_start = START);
   . = START + SIZEOF_HEADERS;
   .interp         : { *(.interp) }
+  /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
+   * is remapped.*/
   __binary_start = .;
   . = ALIGN(4096);		/* Init code and data */
   _stext = .;
diff -Nru a/arch/um/kernel/process.c b/arch/um/kernel/process.c
--- a/arch/um/kernel/process.c	2005-01-19 13:44:47 -08:00
+++ b/arch/um/kernel/process.c	2005-01-19 13:44:47 -08:00
@@ -371,9 +371,9 @@
 		kill(target, SIGIO);
 }
 
-int can_do_skas(void)
-{
 #ifdef UML_CONFIG_MODE_SKAS
+static inline int check_skas3_ptrace_support(void)
+{
 	struct ptrace_faultinfo fi;
 	void *stack;
 	int pid, n, ret = 1;
@@ -382,29 +382,46 @@
 	pid = start_ptraced_child(&stack);
 
 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
-	if(n < 0){
+	if (n < 0) {
 		if(errno == EIO)
 			printf("not found\n");
-		else printf("No (unexpected errno - %d)\n", errno);
+		else {
+			perror("not found");
+		}
 		ret = 0;
+	} else {
+		printf("found\n");
 	}
-	else printf("found\n");
 
 	init_registers(pid);
 	stop_ptraced_child(pid, stack, 1, 1);
 
+	return(ret);
+}
+
+int can_do_skas(void)
+{
+	int ret = 1;
+
 	printf("Checking for /proc/mm...");
-	if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
+	if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
 		printf("not found\n");
 		ret = 0;
+		goto out;
+	} else {
+		printf("found\n");
 	}
-	else printf("found\n");
 
-	return(ret);
+	ret = check_skas3_ptrace_support();
+out:
+	return ret;
+}
 #else
+int can_do_skas(void)
+{
 	return(0);
-#endif
 }
+#endif
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -Nru a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
--- a/arch/um/kernel/sysrq.c	2005-01-19 13:44:46 -08:00
+++ b/arch/um/kernel/sysrq.c	2005-01-19 13:44:46 -08:00
@@ -15,26 +15,30 @@
 void show_trace(unsigned long * stack)
 {
 	/* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from
-	 * arch/i386/kernel/traps.c. */
+	 * arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/
         unsigned long addr;
 
-        if (!stack)
+        if (!stack) {
                 stack = (unsigned long*) &stack;
+		WARN_ON(1);
+	}
 
         printk("Call Trace: \n");
         while (((long) stack & (THREAD_SIZE-1)) != 0) {
-                addr = *stack++;
+                addr = *stack;
 		if (__kernel_text_address(addr)) {
-			printk(" [<%08lx>]", addr);
+			printk("%08lx:  [<%08lx>]", (unsigned long) stack, addr);
 			print_symbol(" %s", addr);
 			printk("\n");
                 }
+                stack++;
         }
         printk("\n");
 }
 
 /*
- * The architecture-independent dump_stack generator
+ * stack dumps generator - this is used by arch-independent code.
+ * And this is identical to i386 currently.
  */
 void dump_stack(void)
 {
@@ -44,7 +48,34 @@
 }
 EXPORT_SYMBOL(dump_stack);
 
-void show_stack(struct task_struct *task, unsigned long *sp)
+/*Stolen from arch/i386/kernel/traps.c */
+static int kstack_depth_to_print = 24;
+
+/* This recently started being used in arch-independent code too, as in
+ * kernel/sched.c.*/
+void show_stack(struct task_struct *task, unsigned long *esp)
 {
-	show_trace(sp);
+	unsigned long *stack;
+	int i;
+
+	if (esp == NULL) {
+		if (task != current) {
+			esp = (unsigned long *) KSTK_ESP(task);
+			/* Which one? No actual difference - just coding style.*/
+			//esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
+		} else {
+			esp = (unsigned long *) &esp;
+		}
+	}
+
+	stack = esp;
+	for(i = 0; i < kstack_depth_to_print; i++) {
+		if (kstack_end(stack))
+			break;
+		if (i && ((i % 8) == 0))
+			printk("\n       ");
+		printk("%08lx ", *stack++);
+	}
+
+	show_trace(esp);
 }
diff -Nru a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
--- a/arch/um/kernel/tt/tracer.c	2005-01-19 13:44:45 -08:00
+++ b/arch/um/kernel/tt/tracer.c	2005-01-19 13:44:45 -08:00
@@ -313,6 +313,15 @@
 				sig = 0;
 				op = do_proc_op(task, proc_id);
 				switch(op){
+				/*
+				 * This is called when entering user mode; after
+				 * this, we start intercepting syscalls.
+				 *
+				 * In fact, a process is started in kernel mode,
+				 * so with is_tracing() == 0 (and that is reset
+				 * when executing syscalls, since UML kernel has
+				 * the right to do syscalls);
+				 */
 				case OP_TRACE_ON:
 					arch_leave_kernel(task, pid);
 					tracing = 1;
@@ -347,6 +356,11 @@
 					continue;
 				}
 				tracing = 0;
+				/* local_using_sysemu has been already set
+				 * below, since if we are here, is_tracing() on
+				 * the traced task was 1, i.e. the process had
+				 * already run through one iteration of the
+				 * loop which executed a OP_TRACE_ON request.*/
 				do_syscall(task, pid, local_using_sysemu);
 				sig = SIGUSR2;
 				break;
diff -Nru a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
--- a/arch/um/kernel/um_arch.c	2005-01-19 13:44:47 -08:00
+++ b/arch/um/kernel/um_arch.c	2005-01-19 13:44:47 -08:00
@@ -198,7 +198,7 @@
 );
 #endif
 
-int force_tt = 0;
+static int force_tt = 0;
 
 #if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
 #define DEFAULT_TT 0
@@ -319,6 +319,14 @@
 	if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE);
 
 	mode_tt = force_tt ? 1 : !can_do_skas();
+#ifndef CONFIG_MODE_TT
+	if (mode_tt) {
+		/*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So,
+		 * can_do_skas() returned 0, and the message is correct. */
+		printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n");
+		exit(1);
+	}
+#endif
 	uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
 				     &host_task_size, &task_size);
 
diff -Nru a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
--- a/arch/um/kernel/uml.lds.S	2005-01-19 13:44:46 -08:00
+++ b/arch/um/kernel/uml.lds.S	2005-01-19 13:44:46 -08:00
@@ -7,8 +7,12 @@
 
 SECTIONS
 {
+  /*This must contain the right address - not quite the default ELF one.*/
+  PROVIDE (__executable_start = START);
   . = START + SIZEOF_HEADERS;
 
+  /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
+   * is remapped.*/
   __binary_start = .;
 #ifdef MODE_TT
   .thread_private : {
@@ -20,9 +24,13 @@
   }
   . = ALIGN(4096);
   .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
-#endif
+
+  /* We want it only if we are in MODE_TT. In both cases, however, when MODE_TT
+   * is off the resulting binary segfaults.*/
 
   . = ALIGN(4096);		/* Init code and data */
+#endif
+
   _stext = .;
   __init_begin = .;
   .init.text : {
diff -Nru a/arch/v850/lib/checksum.c b/arch/v850/lib/checksum.c
--- a/arch/v850/lib/checksum.c	2005-01-19 13:44:47 -08:00
+++ b/arch/v850/lib/checksum.c	2005-01-19 13:44:47 -08:00
@@ -121,7 +121,7 @@
 /*
  * copy while checksumming, otherwise like csum_partial
  */
-unsigned int csum_partial_copy(const char *src, char *dst, 
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst,
                                int len, unsigned int sum)
 {
 	/*
@@ -138,7 +138,7 @@
  * Copy from userspace and compute checksum.  If we catch an exception
  * then zero the rest of the buffer.
  */
-unsigned int csum_partial_copy_from_user (const char *src, char *dst,
+unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
                                           int len, unsigned int sum,
                                           int *err_ptr)
 {
diff -Nru a/arch/x86_64/ia32/fpu32.c b/arch/x86_64/ia32/fpu32.c
--- a/arch/x86_64/ia32/fpu32.c	2005-01-19 13:44:45 -08:00
+++ b/arch/x86_64/ia32/fpu32.c	2005-01-19 13:44:45 -08:00
@@ -28,16 +28,17 @@
 static inline unsigned long twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
 {
 	struct _fpxreg *st = NULL;
+	unsigned long tos = (fxsave->swd >> 11) & 7;
 	unsigned long twd = (unsigned long) fxsave->twd;
 	unsigned long tag;
 	unsigned long ret = 0xffff0000;
 	int i;
 
-#define FPREG_ADDR(f, n)	((char *)&(f)->st_space + (n) * 16);
+#define FPREG_ADDR(f, n)	((void *)&(f)->st_space + (n) * 16);
 
 	for (i = 0 ; i < 8 ; i++) {
 		if (twd & 0x1) {
-			st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
+			st = FPREG_ADDR( fxsave, (i - tos) & 7 );
 
 			switch (st->exponent & 0x7fff) {
 			case 0x7fff:
diff -Nru a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
--- a/arch/x86_64/ia32/ia32_aout.c	2005-01-19 13:44:48 -08:00
+++ b/arch/x86_64/ia32/ia32_aout.c	2005-01-19 13:44:48 -08:00
@@ -115,7 +115,9 @@
 	end = PAGE_ALIGN(end);
 	if (end <= start)
 		return;
+	down_write(&current->mm->mmap_sem);
 	do_brk(start, end - start);
+	up_write(&current->mm->mmap_sem);
 }
 
 #if CORE_DUMP
@@ -325,7 +327,10 @@
 		pos = 32;
 		map_size = ex.a_text+ex.a_data;
 
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(text_addr & PAGE_MASK, map_size);
+		up_write(&current->mm->mmap_sem);
+
 		if (error != (text_addr & PAGE_MASK)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
@@ -361,7 +366,9 @@
 
 		if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
 			loff_t pos = fd_offset;
+			down_write(&current->mm->mmap_sem);
 			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+			up_write(&current->mm->mmap_sem);
 			bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
 					ex.a_text+ex.a_data, &pos);
 			flush_icache_range((unsigned long) N_TXTADDR(ex),
@@ -469,8 +476,9 @@
 			error_time = jiffies;
 		}
 #endif
-
+		down_write(&current->mm->mmap_sem);
 		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+		up_write(&current->mm->mmap_sem);
 		
 		file->f_op->read(file, (char *)start_addr,
 			ex.a_text + ex.a_data, &pos);
@@ -494,7 +502,9 @@
 	len = PAGE_ALIGN(ex.a_text + ex.a_data);
 	bss = ex.a_text + ex.a_data + ex.a_bss;
 	if (bss > len) {
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(start_addr + len, bss - len);
+		up_write(&current->mm->mmap_sem);
 		retval = error;
 		if (error != start_addr + len)
 			goto out;
diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
--- a/arch/x86_64/ia32/ia32entry.S	2005-01-19 13:44:46 -08:00
+++ b/arch/x86_64/ia32/ia32entry.S	2005-01-19 13:44:46 -08:00
@@ -388,7 +388,11 @@
 	.quad sys_symlink
 	.quad sys_lstat
 	.quad sys_readlink		/* 85 */
+#ifdef CONFIG_IA32_AOUT
 	.quad sys_uselib
+#else
+	.quad quiet_ni_syscall
+#endif
 	.quad sys_swapon
 	.quad sys_reboot
 	.quad compat_sys_old_readdir
@@ -479,7 +483,7 @@
 	.quad sys32_rt_sigaction
 	.quad sys32_rt_sigprocmask	/* 175 */
 	.quad sys32_rt_sigpending
-	.quad compat_rt_sigtimedwait
+	.quad compat_sys_rt_sigtimedwait
 	.quad sys32_rt_sigqueueinfo
 	.quad stub32_rt_sigsuspend
 	.quad sys32_pread		/* 180 */
diff -Nru a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
--- a/arch/x86_64/kernel/mce.c	2005-01-19 13:44:46 -08:00
+++ b/arch/x86_64/kernel/mce.c	2005-01-19 13:44:46 -08:00
@@ -340,12 +340,12 @@
  */
 void __init mcheck_init(struct cpuinfo_x86 *c)
 {
-	static unsigned long mce_cpus __initdata = 0;
+	static cpumask_t mce_cpus __initdata = CPU_MASK_NONE;
 
 	mce_cpu_quirks(c); 
 
 	if (mce_dont_init ||
-	    test_and_set_bit(smp_processor_id(), &mce_cpus) ||
+	    cpu_test_and_set(smp_processor_id(), mce_cpus) ||
 	    !mce_available(c))
 		return;
 
diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c	2005-01-19 13:44:45 -08:00
+++ b/arch/x86_64/kernel/setup.c	2005-01-19 13:44:45 -08:00
@@ -485,6 +485,8 @@
 
 	parse_cmdline_early(cmdline_p);
 
+	early_identify_cpu(&boot_cpu_data);
+
 	/*
 	 * partially used pages are not usable - thus
 	 * we are rounding upwards:
diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c	2005-01-19 13:44:46 -08:00
+++ b/arch/x86_64/kernel/setup64.c	2005-01-19 13:44:46 -08:00
@@ -28,7 +28,7 @@
 
 char x86_boot_params[2048] __initdata = {0,};
 
-unsigned long cpu_initialized __initdata = 0;
+cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
 
 struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; 
 
@@ -187,7 +187,7 @@
 
 	me = current;
 
-	if (test_and_set_bit(cpu, &cpu_initialized))
+	if (cpu_test_and_set(cpu, cpu_initialized))
 		panic("CPU#%d already initialized!\n", cpu);
 
 	printk("Initializing CPU#%d\n", cpu);
@@ -214,9 +214,6 @@
 	 */
 
 	asm volatile("pushfq ; popq %%rax ; btr $14,%%rax ; pushq %%rax ; popfq" ::: "eax");
-
-	if (cpu == 0) 
-		early_identify_cpu(&boot_cpu_data);
 
 	syscall_init();
 
diff -Nru a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
--- a/arch/x86_64/kernel/signal.c	2005-01-19 13:44:47 -08:00
+++ b/arch/x86_64/kernel/signal.c	2005-01-19 13:44:47 -08:00
@@ -24,7 +24,6 @@
 #include <linux/stddef.h>
 #include <linux/personality.h>
 #include <linux/compiler.h>
-#include <linux/suspend.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
@@ -423,10 +422,8 @@
 		return 1;
 	} 	
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze(0))
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c	2005-01-19 13:44:47 -08:00
+++ b/arch/x86_64/kernel/time.c	2005-01-19 13:44:47 -08:00
@@ -955,16 +955,19 @@
 
 __setup("report_lost_ticks", time_setup);
 
-static long clock_cmos_diff, sleep_start;
+static long clock_cmos_diff;
+static unsigned long sleep_start;
 
 static int timer_suspend(struct sys_device *dev, u32 state)
 {
 	/*
 	 * Estimate time zone so that set_time can update the clock
 	 */
-	clock_cmos_diff = -get_cmos_time();
+	long cmos_time =  get_cmos_time();
+
+	clock_cmos_diff = -cmos_time;
 	clock_cmos_diff += get_seconds();
-	sleep_start = jiffies;
+	sleep_start = cmos_time;
 	return 0;
 }
 
@@ -973,7 +976,7 @@
 	unsigned long flags;
 	unsigned long sec;
 	unsigned long ctime = get_cmos_time();
-	unsigned long sleep_length = ctime - sleep_start;
+	unsigned long sleep_length = (ctime - sleep_start) * HZ;
 
 	if (vxtime.hpet_address)
 		hpet_reenable();
@@ -983,7 +986,8 @@
 	xtime.tv_sec = sec;
 	xtime.tv_nsec = 0;
 	write_sequnlock_irqrestore(&xtime_lock,flags);
-	jiffies += sleep_length * HZ;
+	jiffies += sleep_length;
+	wall_jiffies += sleep_length;
 	return 0;
 }
 
diff -Nru a/arch/x86_64/lib/csum-wrappers.c b/arch/x86_64/lib/csum-wrappers.c
--- a/arch/x86_64/lib/csum-wrappers.c	2005-01-19 13:44:45 -08:00
+++ b/arch/x86_64/lib/csum-wrappers.c	2005-01-19 13:44:45 -08:00
@@ -19,7 +19,7 @@
  * src and dst are best aligned to 64bits. 
  */ 
 unsigned int 
-csum_partial_copy_from_user(const char __user *src, char *dst, 
+csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst,
 			    int len, unsigned int isum, int *errp)
 { 
 	might_sleep();
@@ -67,7 +67,7 @@
  * src and dst are best aligned to 64bits.
  */ 
 unsigned int 
-csum_partial_copy_to_user(const char *src, char __user *dst, 
+csum_partial_copy_to_user(unsigned const char *src, unsigned char __user *dst,
 			  int len, unsigned int isum, int *errp)
 { 
 	might_sleep();
@@ -105,7 +105,7 @@
  * Returns an 32bit unfolded checksum of the buffer.
  */ 
 unsigned int 
-csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum)
+csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, unsigned int sum)
 { 
 	return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL);
 } 
diff -Nru a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
--- a/arch/x86_64/mm/fault.c	2005-01-19 13:44:45 -08:00
+++ b/arch/x86_64/mm/fault.c	2005-01-19 13:44:45 -08:00
@@ -462,7 +462,7 @@
 #ifdef CONFIG_IA32_EMULATION
 	/* 32bit vsyscall. map on demand. */
 	if (test_thread_flag(TIF_IA32) &&
-	    address >= 0xffffe000 && address < 0xffffe000 + PAGE_SIZE) { 
+	    address >= VSYSCALL32_BASE && address < VSYSCALL32_END) {
 		if (map_syscall32(mm, address) < 0)
 			goto out_of_memory2;
 		return;
diff -Nru a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
--- a/arch/x86_64/mm/init.c	2005-01-19 13:44:46 -08:00
+++ b/arch/x86_64/mm/init.c	2005-01-19 13:44:46 -08:00
@@ -605,7 +605,7 @@
 	if (test_tsk_thread_flag(tsk, TIF_IA32)) {
 		/* lookup code assumes the pages are present. set them up
 		   now */
-		if (__map_syscall32(tsk->mm, 0xfffe000) < 0)
+		if (__map_syscall32(tsk->mm, VSYSCALL32_BASE) < 0)
 			return NULL;
 		return &gate32_vma;
 	}
diff -Nru a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
--- a/arch/x86_64/mm/k8topology.c	2005-01-19 13:44:48 -08:00
+++ b/arch/x86_64/mm/k8topology.c	2005-01-19 13:44:48 -08:00
@@ -47,6 +47,10 @@
 	int nodeid, i, nb; 
 	int found = 0;
 	u32 reg;
+	unsigned numnodes;
+	nodemask_t nodes_parsed;
+
+	nodes_clear(nodes_parsed);
 
 	nb = find_northbridge(); 
 	if (nb < 0) 
@@ -55,10 +59,9 @@
 	printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); 
 
 	reg = read_pci_config(0, nb, 0, 0x60); 
-	for (i = 0; i <= ((reg >> 4) & 7); i++)
-		node_set_online(i);
+	numnodes = ((reg >> 4) & 7) + 1;
 
-	printk(KERN_INFO "Number of nodes %d (%x)\n", num_online_nodes(), reg);
+	printk(KERN_INFO "Number of nodes %d\n", numnodes);
 
 	memset(&nodes,0,sizeof(nodes)); 
 	prevbase = 0;
@@ -70,11 +73,11 @@
 
 		nodeid = limit & 7; 
 		if ((base & 3) == 0) { 
-			if (i < num_online_nodes())
+			if (i < numnodes)
 				printk("Skipping disabled node %d\n", i); 
 			continue;
 		} 
-		if (nodeid >= num_online_nodes()) {
+		if (nodeid >= numnodes) {
 			printk("Ignoring excess node %d (%lx:%lx)\n", nodeid,
 			       base, limit); 
 			continue;
@@ -90,7 +93,7 @@
 			       nodeid, (base>>8)&3, (limit>>8) & 3); 
 			return -1; 
 		}	
-		if (node_online(nodeid)) { 
+		if (node_isset(nodeid, nodes_parsed)) { 
 			printk(KERN_INFO "Node %d already present. Skipping\n", 
 			       nodeid);
 			continue;
@@ -138,12 +141,14 @@
 		nodes[nodeid].end = limit;
 
 		prevbase = base;
+
+		node_set(nodeid, nodes_parsed);
 	} 
 
 	if (!found)
 		return -1; 
 
-	memnode_shift = compute_hash_shift(nodes);
+	memnode_shift = compute_hash_shift(nodes, numnodes);
 	if (memnode_shift < 0) { 
 		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 
 		return -1; 
@@ -154,8 +159,8 @@
 		if (nodes[i].start != nodes[i].end) { 
 			/* assume 1:1 NODE:CPU */
 			cpu_to_node[i] = i; 
-		setup_node_bootmem(i, nodes[i].start, nodes[i].end); 
-	} 
+			setup_node_bootmem(i, nodes[i].start, nodes[i].end); 
+		} 
 	}
 
 	numa_init_array();
diff -Nru a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
--- a/arch/x86_64/mm/numa.c	2005-01-19 13:44:47 -08:00
+++ b/arch/x86_64/mm/numa.c	2005-01-19 13:44:47 -08:00
@@ -34,9 +34,7 @@
 
 int numa_off __initdata;
 
-unsigned long nodes_present; 
-
-int __init compute_hash_shift(struct node *nodes)
+int __init compute_hash_shift(struct node *nodes, int numnodes)
 {
 	int i; 
 	int shift = 24;
@@ -45,7 +43,7 @@
 	/* When in doubt use brute force. */
 	while (shift < 48) { 
 		memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); 
-		for_each_online_node(i) {
+		for (i = 0; i < numnodes; i++) {
 			if (nodes[i].start == nodes[i].end) 
 				continue;
 			for (addr = nodes[i].start; 
@@ -197,7 +195,7 @@
  		       (nodes[i].end - nodes[i].start) >> 20);
 		node_set_online(i);
  	}
- 	memnode_shift = compute_hash_shift(nodes);
+ 	memnode_shift = compute_hash_shift(nodes, numa_fake);
  	if (memnode_shift < 0) {
  		memnode_shift = 0;
  		printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n");
@@ -274,7 +272,7 @@
 /* [numa=off] */
 __init int numa_setup(char *opt) 
 { 
-	if (!strcmp(opt,"off"))
+	if (!strncmp(opt,"off",3))
 		numa_off = 1;
 #ifdef CONFIG_NUMA_EMU
 	if(!strncmp(opt, "fake=", 5)) {
diff -Nru a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
--- a/arch/x86_64/mm/srat.c	2005-01-19 13:44:46 -08:00
+++ b/arch/x86_64/mm/srat.c	2005-01-19 13:44:46 -08:00
@@ -20,17 +20,20 @@
 
 static struct acpi_table_slit *acpi_slit;
 
-static DECLARE_BITMAP(nodes_parsed, MAX_NUMNODES) __initdata;
+static nodemask_t nodes_parsed __initdata;
+static nodemask_t nodes_found __initdata;
 static struct node nodes[MAX_NUMNODES] __initdata;
 static __u8  pxm2node[256] __initdata = { [0 ... 255] = 0xff };
 
 static __init int setup_node(int pxm)
 {
-	if (pxm2node[pxm] == 0xff) {
-		if (num_online_nodes() >= MAX_NUMNODES)
+	unsigned node = pxm2node[pxm];
+	if (node == 0xff) {
+		if (nodes_weight(nodes_found) >= MAX_NUMNODES)
 			return -1;
-		pxm2node[pxm] = num_online_nodes();
-		node_set_online(num_online_nodes());
+		node = first_unset_node(nodes_found); 
+		node_set(node, nodes_found);
+		pxm2node[pxm] = node;
 	}
 	return pxm2node[pxm];
 }
@@ -140,7 +143,7 @@
 		return;
 	}
 	nd = &nodes[node];
-	if (!test_and_set_bit(node, &nodes_parsed)) {
+	if (!node_test_and_set(node, nodes_parsed)) {
 		nd->start = start;
 		nd->end = end;
 	} else {
@@ -163,7 +166,7 @@
 	int i;
 	if (acpi_numa <= 0)
 		return -1;
-	memnode_shift = compute_hash_shift(nodes);
+	memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed));
 	if (memnode_shift < 0) {
 		printk(KERN_ERR
 		     "SRAT: No NUMA node hash function found. Contact maintainer\n");
@@ -171,7 +174,7 @@
 		return -1;
 	}
 	for (i = 0; i < MAX_NUMNODES; i++) {
-		if (!test_bit(i, &nodes_parsed))
+		if (!node_isset(i, nodes_parsed))
 			continue;
 		cutoff_node(i, start, end);
 		if (nodes[i].start == nodes[i].end)
diff -Nru a/crypto/Kconfig b/crypto/Kconfig
--- a/crypto/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/crypto/Kconfig	2005-01-19 13:44:47 -08:00
@@ -77,7 +77,7 @@
 	  Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard
 
 	  See also:
-	  http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html
+	  <http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html>
 
 config CRYPTO_DES
 	tristate "DES and Triple DES EDE cipher algorithms"
@@ -102,7 +102,7 @@
 	  designed for use on "large microprocessors".
 	  
 	  See also:
-	  http://www.schneier.com/blowfish.html
+	  <http://www.schneier.com/blowfish.html>
 
 config CRYPTO_TWOFISH
 	tristate "Twofish cipher algorithm"
@@ -116,7 +116,7 @@
 	  bits.
 	  
 	  See also:
-	  http://www.schneier.com/twofish.html
+	  <http://www.schneier.com/twofish.html>
 
 config CRYPTO_SERPENT
 	tristate "Serpent cipher algorithm"
@@ -129,7 +129,7 @@
 	  variant of Serpent for compatibility with old kerneli code.
 
 	  See also:
-	  http://www.cl.cam.ac.uk/~rja14/serpent.html
+	  <http://www.cl.cam.ac.uk/~rja14/serpent.html>
 
 config CRYPTO_AES
 	tristate "AES cipher algorithms"
@@ -149,7 +149,7 @@
 
 	  The AES specifies three key sizes: 128, 192 and 256 bits	  
 
-	  See http://csrc.nist.gov/CryptoToolkit/aes/ for more information.
+	  See <http://csrc.nist.gov/CryptoToolkit/aes/> for more information.
 
 config CRYPTO_AES_586
 	tristate "AES cipher algorithms (i586)"
@@ -169,7 +169,7 @@
 
 	  The AES specifies three key sizes: 128, 192 and 256 bits	  
 
-	  See http://csrc.nist.gov/encryption/aes/ for more information.
+	  See <http://csrc.nist.gov/encryption/aes/> for more information.
 
 config CRYPTO_CAST5
 	tristate "CAST5 (CAST-128) cipher algorithm"
@@ -221,7 +221,7 @@
 	  on 32-bit processors.  Khazad uses an 128 bit key size.
 
 	  See also:
-	  http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html
+	  <http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html>
 
 config CRYPTO_ANUBIS
 	tristate "Anubis cipher algorithm"
@@ -234,8 +234,8 @@
 	  in the NESSIE competition.
 	  
 	  See also:
-	  https://www.cosic.esat.kuleuven.ac.be/nessie/reports/
-	  http://planeta.terra.com.br/informatica/paulobarreto/AnubisPage.html
+	  <https://www.cosic.esat.kuleuven.ac.be/nessie/reports/>
+	  <http://planeta.terra.com.br/informatica/paulobarreto/AnubisPage.html>
 
 
 config CRYPTO_DEFLATE
diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	2005-01-19 13:44:48 -08:00
+++ b/drivers/acpi/Kconfig	2005-01-19 13:44:48 -08:00
@@ -20,7 +20,7 @@
 	  kernel by about 70K.
 
 	  Linux ACPI provides a robust functional replacement for several 
-	  legacy configuration and power management intefaces, including 
+	  legacy configuration and power management interfaces, including
 	  the Plug-and-Play BIOS specification (PnP BIOS), the 
 	  MultiProcessor Specification (MPS), and the Advanced Power 
 	  Management (APM) specification.  If both ACPI and APM support 
@@ -209,8 +209,8 @@
 	  This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
 	  support for Fn-Fx key combinations, Bluetooth control, video
 	  output switching, ThinkLight control, UltraBay eject and more.
-	  For more information about this driver see Documentation/ibm-acpi.txt
-	  and http://ibm-acpi.sf.net/ .
+	  For more information about this driver see <file:Documentation/ibm-acpi.txt>
+	  and <http://ibm-acpi.sf.net/> .
 
 	  If you have an IBM ThinkPad laptop, say Y or M here.
 
diff -Nru a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
--- a/drivers/acpi/events/evgpeblk.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/acpi/events/evgpeblk.c	2005-01-19 13:44:46 -08:00
@@ -925,7 +925,7 @@
 
 	/*
 	 * Runtime option: Should Wake GPEs be enabled at runtime?  The default
-	 * is No,they should only be enabled just as the machine goes to sleep.
+	 * is No, they should only be enabled just as the machine goes to sleep.
 	 */
 	if (acpi_gbl_leave_wake_gpes_disabled) {
 		/*
diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
--- a/drivers/acpi/sleep/main.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/acpi/sleep/main.c	2005-01-19 13:44:45 -08:00
@@ -159,7 +159,7 @@
 
 int acpi_suspend(u32 acpi_state)
 {
-	u32 states[] = {
+	suspend_state_t states[] = {
 		[1]	= PM_SUSPEND_STANDBY,
 		[3]	= PM_SUSPEND_MEM,
 		[4]	= PM_SUSPEND_DISK,
diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig
--- a/drivers/block/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/block/Kconfig	2005-01-19 13:44:46 -08:00
@@ -6,7 +6,7 @@
 
 config BLK_DEV_FD
 	tristate "Normal floppy disk support"
-	depends on (!ARCH_S390 && !M68K && !IA64) || Q40 || (SUN3X && BROKEN)
+	depends on (!ARCH_S390 && !M68K && !IA64 && !USERMODE) || Q40 || (SUN3X && BROKEN)
 	---help---
 	  If you want to use the floppy disk drive(s) of your PC under Linux,
 	  say Y. Information about this driver, especially important for IBM
@@ -170,7 +170,7 @@
 	help
 	  When enabled (Y), this option allows SCSI tape drives and SCSI medium
 	  changers (tape robots) to be accessed via a Compaq 5xxx array 
-	  controller.  (See Documentation/cciss.txt for more details.)
+	  controller.  (See <file:Documentation/cciss.txt> for more details.)
 
 	  "SCSI support" and "SCSI tape support" must also be enabled for this 
 	  option to work.
@@ -196,7 +196,7 @@
 	---help---
 	  Saying Y here will include support for the MM5415 family of
 	  battery backed (Non-volatile) RAM cards.
-	  http://www.umem.com/
+	  <http://www.umem.com/>
 
 	  The cards appear as block devices that can be partitioned into
 	  as many as 15 partitions.
@@ -208,6 +208,56 @@
 	  one is chosen dynamically.  Use "devfs" or look in /proc/devices
 	  for the device number
 
+config BLK_DEV_UBD
+	bool "Virtual block device"
+	depends on USERMODE
+	---help---
+          The User-Mode Linux port includes a driver called UBD which will let
+          you access arbitrary files on the host computer as block devices.
+          Unless you know that you do not need such virtual block devices say
+          Y here.
+
+config BLK_DEV_UBD_SYNC
+	bool "Always do synchronous disk IO for UBD"
+	depends on BLK_DEV_UBD
+	---help---
+	  Writes to the virtual block device are not immediately written to the
+	  host's disk; this may cause problems if, for example, the User-Mode
+	  Linux 'Virtual Machine' uses a journalling filesystem and the host
+	  computer crashes.
+
+          Synchronous operation (i.e. always writing data to the host's disk
+          immediately) is configurable on a per-UBD basis by using a special
+          kernel command line option.  Alternatively, you can say Y here to
+          turn on synchronous operation by default for all block devices.
+
+          If you're running a journalling file system (like reiserfs, for
+          example) in your virtual machine, you will want to say Y here.  If
+          you care for the safety of the data in your virtual machine, Y is a
+          wise choice too.  In all other cases (for example, if you're just
+          playing around with User-Mode Linux) you can choose N.
+
+config BLK_DEV_COW_COMMON
+	bool
+	default BLK_DEV_UBD
+
+config MMAPPER
+	tristate "Example IO memory driver (BROKEN)"
+	depends on USERMODE && BROKEN
+	---help---
+          The User-Mode Linux port can provide support for IO Memory
+          emulation with this option.  This allows a host file to be
+          specified as an I/O region on the kernel command line. That file
+          will be mapped into UML's kernel address space where a driver can
+          locate it and do whatever it wants with the memory, including
+          providing an interface to it for UML processes to use.
+
+          For more information, see
+          <http://user-mode-linux.sourceforge.net/iomem.html>.
+
+          If you'd like to be able to provide a simulated IO port space for
+          User-Mode Linux processes, say Y.  If unsure, say N.
+
 config BLK_DEV_LOOP
 	tristate "Loopback device support"
 	---help---
@@ -401,9 +451,11 @@
 
 	  If you are not sure, leave it set to "0".
 
+#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
+#for instance.
 config LBD
 	bool "Support for Large Block Devices"
-	depends on X86 || MIPS32 || PPC32 || ARCH_S390_31 || SUPERH
+	depends on X86 || MIPS32 || PPC32 || ARCH_S390_31 || SUPERH || USERMODE
 	help
 	  Say Y here if you want to attach large (bigger than 2TB) discs to
 	  your machine, or if you want to have a raid or loopback device
@@ -411,6 +463,7 @@
 
 config CDROM_PKTCDVD
 	tristate "Packet writing on CD/DVD media"
+	depends on !USERMODE
 	help
 	  If you have a CDROM drive that supports packet writing, say Y to
 	  include preliminary support. It should work with any MMC/Mt Fuji
@@ -449,7 +502,6 @@
 config ATA_OVER_ETH
 	tristate "ATA over Ethernet support"
 	depends on NET
-	default m
 	help
 	This driver provides Support for ATA over Ethernet block
 	devices like the Coraid EtherDrive (R) Storage Blade.
diff -Nru a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
--- a/drivers/block/aoe/aoe.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/block/aoe/aoe.h	2005-01-19 13:44:47 -08:00
@@ -1,7 +1,10 @@
 /* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
-#define VERSION "4"
+#define VERSION "5"
 #define AOE_MAJOR 152
 #define DEVICE_NAME "aoe"
+#ifndef AOE_PARTITIONS
+#define AOE_PARTITIONS 16
+#endif
 #define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * 10 + (aoeminor))
 #define AOEMAJOR(sysminor) ((sysminor) / 10)
 #define AOEMINOR(sysminor) ((sysminor) % 10)
@@ -101,7 +104,7 @@
 	int ndata;
 
 	/* largest possible */
-	char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)];
+	unsigned char data[sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr)];
 };
 
 struct aoedev {
@@ -111,6 +114,7 @@
 	ulong sysminor;
 	ulong aoemajor;
 	ulong aoeminor;
+	ulong nopen;		/* (bd_openers isn't available without sleeping) */
 	ulong rttavg;		/* round trip average of requests/responses */
 	u16 fw_ver;		/* version of blade's firmware */
 	struct work_struct work;/* disk create work struct */
diff -Nru a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
--- a/drivers/block/aoe/aoeblk.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/block/aoe/aoeblk.c	2005-01-19 13:44:46 -08:00
@@ -12,14 +12,9 @@
 #include <linux/netdevice.h>
 #include "aoe.h"
 
-/* add attributes for our block devices in sysfs
- * (see drivers/block/genhd.c:disk_attr_show, etc.)
- */
-struct disk_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct gendisk *, char *);
-};
+static kmem_cache_t *buf_pool_cache;
 
+/* add attributes for our block devices in sysfs */
 static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
 {
 	struct aoedev *d = disk->private_data;
@@ -74,9 +69,18 @@
 aoeblk_open(struct inode *inode, struct file *filp)
 {
 	struct aoedev *d;
+	ulong flags;
 
 	d = inode->i_bdev->bd_disk->private_data;
-	return (d->flags & DEVFL_UP) ? 0 : -ENODEV;
+
+	spin_lock_irqsave(&d->lock, flags);
+	if (d->flags & DEVFL_UP) {
+		d->nopen++;
+		spin_unlock_irqrestore(&d->lock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(&d->lock, flags);
+	return -ENODEV;
 }
 
 static int
@@ -89,7 +93,7 @@
 
 	spin_lock_irqsave(&d->lock, flags);
 
-	if (inode->i_bdev->bd_openers == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
+	if (--d->nopen == 0 && (d->flags & DEVFL_CLOSEWAIT)) {
 		d->flags &= ~DEVFL_CLOSEWAIT;
 		spin_unlock_irqrestore(&d->lock, flags);
 		aoecmd_cfg(d->aoemajor, d->aoeminor);
@@ -192,23 +196,34 @@
 	struct aoedev *d = vp;
 	struct gendisk *gd;
 	ulong flags;
-	enum { NPARTITIONS = 16 };
-
-	gd = alloc_disk(NPARTITIONS);
-
-	spin_lock_irqsave(&d->lock, flags);
 
+	gd = alloc_disk(AOE_PARTITIONS);
 	if (gd == NULL) {
-		printk(KERN_CRIT "aoe: aoeblk_gdalloc: cannot allocate disk "
+		printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate disk "
 			"structure for %ld.%ld\n", d->aoemajor, d->aoeminor);
+		spin_lock_irqsave(&d->lock, flags);
 		d->flags &= ~DEVFL_WORKON;
 		spin_unlock_irqrestore(&d->lock, flags);
 		return;
 	}
 
+	d->bufpool = mempool_create(MIN_BUFS,
+				    mempool_alloc_slab, mempool_free_slab,
+				    buf_pool_cache);
+	if (d->bufpool == NULL) {
+		printk(KERN_ERR "aoe: aoeblk_gdalloc: cannot allocate bufpool "
+			"for %ld.%ld\n", d->aoemajor, d->aoeminor);
+		put_disk(gd);
+		spin_lock_irqsave(&d->lock, flags);
+		d->flags &= ~DEVFL_WORKON;
+		spin_unlock_irqrestore(&d->lock, flags);
+		return;
+	}
+
+	spin_lock_irqsave(&d->lock, flags);
 	blk_queue_make_request(&d->blkq, aoeblk_make_request);
 	gd->major = AOE_MAJOR;
-	gd->first_minor = d->sysminor * NPARTITIONS;
+	gd->first_minor = d->sysminor * AOE_PARTITIONS;
 	gd->fops = &aoe_bdops;
 	gd->private_data = d;
 	gd->capacity = d->ssize;
@@ -233,13 +248,19 @@
 void __exit
 aoeblk_exit(void)
 {
-	unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
+	kmem_cache_destroy(buf_pool_cache);
 }
 
 int __init
 aoeblk_init(void)
 {
 	int n;
+
+	buf_pool_cache = kmem_cache_create("aoe_bufs", 
+					   sizeof(struct buf),
+					   0, 0, NULL, NULL);
+	if (buf_pool_cache == NULL)
+		return -ENOMEM;
 
 	n = register_blkdev(AOE_MAJOR, DEVICE_NAME);
 	if (n < 0) {
diff -Nru a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
--- a/drivers/block/aoe/aoechr.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/block/aoe/aoechr.c	2005-01-19 13:44:48 -08:00
@@ -266,7 +266,7 @@
 	return 0;
 }
 
-void __exit
+void
 aoechr_exit(void)
 {
 	int i;
diff -Nru a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
--- a/drivers/block/aoe/aoedev.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/block/aoe/aoedev.c	2005-01-19 13:44:45 -08:00
@@ -11,7 +11,6 @@
 
 static struct aoedev *devlist;
 static spinlock_t devlist_lock;
-static kmem_cache_t *buf_pool_cache;
 
 struct aoedev *
 aoedev_bymac(unsigned char *macaddr)
@@ -53,9 +52,7 @@
 
 	spin_lock_init(&d->lock);
 	init_timer(&d->timer);
-	d->bufpool = mempool_create(MIN_BUFS,
-				    mempool_alloc_slab, mempool_free_slab,
-				    buf_pool_cache);
+	d->bufpool = NULL;	/* defer to aoeblk_gdalloc */
 	INIT_LIST_HEAD(&d->bufq);
 	d->next = devlist;
 	devlist = d;
@@ -95,15 +92,10 @@
 		bio_endio(bio, bio->bi_size, -EIO);
 	}
 
-	if (d->gd) {
-		struct block_device *bdev = bdget_disk(d->gd, 0);
-		if (bdev) {
-			if (bdev->bd_openers)
-				d->flags |= DEVFL_CLOSEWAIT;
-			bdput(bdev);
-		}
+	if (d->nopen)
+		d->flags |= DEVFL_CLOSEWAIT;
+	if (d->gd)
 		d->gd->capacity = 0;
-	}
 
 	d->flags &= ~DEVFL_UP;
 }
@@ -159,7 +151,7 @@
 	kfree(d);
 }
 
-void __exit
+void
 aoedev_exit(void)
 {
 	struct aoedev *d;
@@ -177,17 +169,11 @@
 		del_timer_sync(&d->timer);
 		aoedev_freedev(d);
 	}
-	kmem_cache_destroy(buf_pool_cache);
 }
 
 int __init
 aoedev_init(void)
 {
-	buf_pool_cache = kmem_cache_create("aoe_bufs", 
-					   sizeof(struct buf),
-					   0, 0, NULL, NULL);
-	if (buf_pool_cache == NULL)
-		return -ENOMEM;
 	spin_lock_init(&devlist_lock);
 	return 0;
 }
diff -Nru a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c
--- a/drivers/block/aoe/aoemain.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/block/aoe/aoemain.c	2005-01-19 13:44:48 -08:00
@@ -53,39 +53,58 @@
 	}
 }
 
-static void __exit
+static void
 aoe_exit(void)
 {
 	discover_timer(TKILL);
 
 	aoenet_exit();
-	aoeblk_exit();
+	unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
 	aoechr_exit();
 	aoedev_exit();
+	aoeblk_exit();		/* free cache after de-allocating bufs */
 }
 
 static int __init
 aoe_init(void)
 {
-	int n, (**p)(void);
-	int (*fns[])(void) = {
-		aoedev_init, aoechr_init, aoeblk_init, aoenet_init, NULL
-	};
+	int ret;
 
-	for (p=fns; *p != NULL; p++) {
-		n = (*p)();
-		if (n) {
-			aoe_exit();
-			printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n");
-			return n;
-		}
+	ret = aoedev_init();
+	if (ret)
+		return ret;
+	ret = aoechr_init();
+	if (ret)
+		goto chr_fail;
+	ret = aoeblk_init();
+	if (ret)
+		goto blk_fail;
+	ret = aoenet_init();
+	if (ret)
+		goto net_fail;
+	ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
+	if (ret < 0) {
+		printk(KERN_ERR "aoe: aoeblk_init: can't register major\n");
+		goto blkreg_fail;
 	}
+
 	printk(KERN_INFO
 	       "aoe: aoe_init: AoE v2.6-%s initialised.\n",
 	       VERSION);
-
 	discover_timer(TINIT);
 	return 0;
+
+ blkreg_fail:
+	aoenet_exit();
+ net_fail:
+	aoeblk_exit();
+ blk_fail:
+	aoechr_exit();
+ chr_fail:
+	aoedev_exit();
+	
+	printk(KERN_INFO "aoe: aoe_init: initialisation failure.\n");
+	return ret;
 }
 
 module_init(aoe_init);
diff -Nru a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
--- a/drivers/block/aoe/aoenet.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/block/aoe/aoenet.c	2005-01-19 13:44:46 -08:00
@@ -102,10 +102,7 @@
 }
 
 /* 
- * (1) i have no idea if this is redundant, but i can't figure why
- * the ifp is passed in if it is.
- *
- * (2) len doesn't include the header by default.  I want this. 
+ * (1) len doesn't include the header by default.  I want this. 
  */
 static int
 aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt)
@@ -117,12 +114,11 @@
 	if (!skb)
 		return 0;
 
-	skb->dev = ifp;	/* (1) */
-
 	if (!is_aoe_netif(ifp))
 		goto exit;
 
-	skb->len += ETH_HLEN;	/* (2) */
+	//skb->len += ETH_HLEN;	/* (1) */
+	skb_push(skb, ETH_HLEN);	/* (1) */
 
 	h = (struct aoe_hdr *) skb->mac.raw;
 	n = __be32_to_cpu(*((u32 *) h->tag));
@@ -133,10 +129,11 @@
 		n = h->err;
 		if (n > NECODES)
 			n = 0;
-		printk(KERN_CRIT "aoe: aoenet_rcv: error packet from %d.%d; "
-			"ecode=%d '%s'\n",
-		       __be16_to_cpu(*((u16 *) h->major)), h->minor, 
-			h->err, aoe_errlist[n]);
+		if (net_ratelimit())
+			printk(KERN_ERR "aoe: aoenet_rcv: error packet from %d.%d; "
+			       "ecode=%d '%s'\n",
+			       __be16_to_cpu(*((u16 *) h->major)), h->minor, 
+			       h->err, aoe_errlist[n]);
 		goto exit;
 	}
 
@@ -167,7 +164,7 @@
 	return 0;
 }
 
-void __exit
+void
 aoenet_exit(void)
 {
 	dev_remove_pack(&aoe_pt);
diff -Nru a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
--- a/drivers/block/cfq-iosched.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/block/cfq-iosched.c	2005-01-19 13:44:47 -08:00
@@ -622,8 +622,10 @@
 			cfq_sort_rr_list(cfqq, 0);
 		}
 
-		crq->accounted = 0;
-		cfqq->cfqd->rq_in_driver--;
+		if (crq->accounted) {
+			crq->accounted = 0;
+			cfqq->cfqd->rq_in_driver--;
+		}
 	}
 	list_add(&rq->queuelist, &q->queue_head);
 }
diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/block/elevator.c	2005-01-19 13:44:47 -08:00
@@ -170,8 +170,6 @@
 #else
 #error "You must build at least 1 IO scheduler into the kernel"
 #endif
-	printk(KERN_INFO "elevator: using %s as default io scheduler\n",
-							chosen_elevator);
 }
 
 static int __init elevator_setup(char *str)
@@ -515,7 +513,10 @@
 	list_add_tail(&e->list, &elv_list);
 	spin_unlock_irq(&elv_list_lock);
 
-	printk(KERN_INFO "io scheduler %s registered\n", e->elevator_name);
+	printk(KERN_INFO "io scheduler %s registered", e->elevator_name);
+	if (!strcmp(e->elevator_name, chosen_elevator))
+		printk(" (default)");
+	printk("\n");
 	return 0;
 }
 EXPORT_SYMBOL_GPL(elv_register);
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/block/genhd.c	2005-01-19 13:44:46 -08:00
@@ -19,10 +19,11 @@
 
 static struct subsystem block_subsys;
 
+static DECLARE_MUTEX(block_subsys_sem);
+
 /*
  * Can be deleted altogether. Later.
  *
- * Modified under both block_subsys.rwsem and major_names_lock.
  */
 static struct blk_major_name {
 	struct blk_major_name *next;
@@ -30,8 +31,6 @@
 	char name[16];
 } *major_names[MAX_PROBE_HASH];
 
-static spinlock_t major_names_lock = SPIN_LOCK_UNLOCKED;
-
 /* index in the above - for now: assume no multimajor ranges */
 static inline int major_to_index(int major)
 {
@@ -47,13 +46,13 @@
 
 	len = sprintf(p, "\nBlock devices:\n");
 
-	down_read(&block_subsys.rwsem);
+	down(&block_subsys_sem);
 	for (i = 0; i < ARRAY_SIZE(major_names); i++) {
 		for (n = major_names[i]; n; n = n->next)
 			len += sprintf(p+len, "%3d %s\n",
 				       n->major, n->name);
 	}
-	up_read(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 
 	return len;
 }
@@ -63,9 +62,8 @@
 {
 	struct blk_major_name **n, *p;
 	int index, ret = 0;
-	unsigned long flags;
 
-	down_write(&block_subsys.rwsem);
+	down(&block_subsys_sem);
 
 	/* temporary */
 	if (major == 0) {
@@ -95,7 +93,6 @@
 	p->next = NULL;
 	index = major_to_index(major);
 
-	spin_lock_irqsave(&major_names_lock, flags);
 	for (n = &major_names[index]; *n; n = &(*n)->next) {
 		if ((*n)->major == major)
 			break;
@@ -104,7 +101,6 @@
 		*n = p;
 	else
 		ret = -EBUSY;
-	spin_unlock_irqrestore(&major_names_lock, flags);
 
 	if (ret < 0) {
 		printk("register_blkdev: cannot get major %d for %s\n",
@@ -112,7 +108,7 @@
 		kfree(p);
 	}
 out:
-	up_write(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 	return ret;
 }
 
@@ -124,11 +120,9 @@
 	struct blk_major_name **n;
 	struct blk_major_name *p = NULL;
 	int index = major_to_index(major);
-	unsigned long flags;
 	int ret = 0;
 
-	down_write(&block_subsys.rwsem);
-	spin_lock_irqsave(&major_names_lock, flags);
+	down(&block_subsys_sem);
 	for (n = &major_names[index]; *n; n = &(*n)->next)
 		if ((*n)->major == major)
 			break;
@@ -138,8 +132,7 @@
 		p = *n;
 		*n = p->next;
 	}
-	spin_unlock_irqrestore(&major_names_lock, flags);
-	up_write(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 	kfree(p);
 
 	return ret;
@@ -233,7 +226,7 @@
 	struct list_head *p;
 	loff_t l = *pos;
 
-	down_read(&block_subsys.rwsem);
+	down(&block_subsys_sem);
 	list_for_each(p, &block_subsys.kset.list)
 		if (!l--)
 			return list_entry(p, struct gendisk, kobj.entry);
@@ -250,7 +243,7 @@
 
 static void part_stop(struct seq_file *part, void *v)
 {
-	up_read(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 }
 
 static int show_partition(struct seq_file *part, void *v)
@@ -322,12 +315,6 @@
 /*
  * kobject & sysfs bindings for block devices
  */
-
-struct disk_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct gendisk *, char *);
-};
-
 static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
 			      char *page)
 {
@@ -508,7 +495,7 @@
 	loff_t k = *pos;
 	struct list_head *p;
 
-	down_read(&block_subsys.rwsem);
+	down(&block_subsys_sem);
 	list_for_each(p, &block_subsys.kset.list)
 		if (!k--)
 			return list_entry(p, struct gendisk, kobj.entry);
@@ -525,7 +512,7 @@
 
 static void diskstats_stop(struct seq_file *part, void *v)
 {
-	up_read(&block_subsys.rwsem);
+	up(&block_subsys_sem);
 }
 
 static int diskstats_show(struct seq_file *s, void *v)
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/block/ll_rw_blk.c	2005-01-19 13:44:45 -08:00
@@ -1438,6 +1438,7 @@
 	struct request_list *rl = &q->rq;
 
 	rl->count[READ] = rl->count[WRITE] = 0;
+	rl->starved[READ] = rl->starved[WRITE] = 0;
 	init_waitqueue_head(&rl->wait[READ]);
 	init_waitqueue_head(&rl->wait[WRITE]);
 	init_waitqueue_head(&rl->drain);
@@ -1618,6 +1619,22 @@
 	ioc->last_waited = jiffies;
 }
 
+static void __freed_request(request_queue_t *q, int rw)
+{
+	struct request_list *rl = &q->rq;
+
+	if (rl->count[rw] < queue_congestion_off_threshold(q))
+		clear_queue_congested(q, rw);
+
+	if (rl->count[rw] + 1 <= q->nr_requests) {
+		smp_mb();
+		if (waitqueue_active(&rl->wait[rw]))
+			wake_up(&rl->wait[rw]);
+
+		blk_clear_queue_full(q, rw);
+	}
+}
+
 /*
  * A request has just been released.  Account for it, update the full and
  * congestion status, wake up any waiters.   Called under q->queue_lock.
@@ -1627,17 +1644,17 @@
 	struct request_list *rl = &q->rq;
 
 	rl->count[rw]--;
-	if (rl->count[rw] < queue_congestion_off_threshold(q))
-		clear_queue_congested(q, rw);
-	if (rl->count[rw]+1 <= q->nr_requests) {
+
+	__freed_request(q, rw);
+
+	if (unlikely(rl->starved[rw ^ 1]))
+		__freed_request(q, rw ^ 1);
+
+	if (!rl->count[READ] && !rl->count[WRITE]) {
 		smp_mb();
-		if (waitqueue_active(&rl->wait[rw]))
-			wake_up(&rl->wait[rw]);
-		blk_clear_queue_full(q, rw);
+		if (unlikely(waitqueue_active(&rl->drain)))
+			wake_up(&rl->drain);
 	}
-	if (unlikely(waitqueue_active(&rl->drain)) &&
-	    !rl->count[READ] && !rl->count[WRITE])
-		wake_up(&rl->drain);
 }
 
 #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
@@ -1669,8 +1686,7 @@
 
 	switch (elv_may_queue(q, rw)) {
 		case ELV_MQUEUE_NO:
-			spin_unlock_irq(q->queue_lock);
-			goto out;
+			goto rq_starved;
 		case ELV_MQUEUE_MAY:
 			break;
 		case ELV_MQUEUE_MUST:
@@ -1688,6 +1704,7 @@
 
 get_rq:
 	rl->count[rw]++;
+	rl->starved[rw] = 0;
 	if (rl->count[rw] >= queue_congestion_on_threshold(q))
 		set_queue_congested(q, rw);
 	spin_unlock_irq(q->queue_lock);
@@ -1703,6 +1720,18 @@
 		 */
 		spin_lock_irq(q->queue_lock);
 		freed_request(q, rw);
+
+		/*
+		 * in the very unlikely event that allocation failed and no
+		 * requests for this direction was pending, mark us starved
+		 * so that freeing of a request in the other direction will
+		 * notice us. another possible fix would be to split the
+		 * rq mempool into READ and WRITE
+		 */
+rq_starved:
+		if (unlikely(rl->count[rw] == 0))
+			rl->starved[rw] = 1;
+
 		spin_unlock_irq(q->queue_lock);
 		goto out;
 	}
diff -Nru a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
--- a/drivers/block/noop-iosched.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/block/noop-iosched.c	2005-01-19 13:44:47 -08:00
@@ -52,12 +52,10 @@
 static void elevator_noop_add_request(request_queue_t *q, struct request *rq,
 				      int where)
 {
-	struct list_head *insert = q->queue_head.prev;
-
 	if (where == ELEVATOR_INSERT_FRONT)
-		insert = &q->queue_head;
-
-	list_add_tail(&rq->queuelist, &q->queue_head);
+		list_add(&rq->queuelist, &q->queue_head);
+	else
+		list_add_tail(&rq->queuelist, &q->queue_head);
 
 	/*
 	 * new merges must not precede this barrier
diff -Nru a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
--- a/drivers/block/paride/Kconfig	2005-01-19 13:44:45 -08:00
+++ b/drivers/block/paride/Kconfig	2005-01-19 13:44:45 -08:00
@@ -119,7 +119,7 @@
 	  before 1999 were Series 5) Series 5 drives will NOT always have the
 	  Series noted on the bottom of the drive. Series 6 drivers will.
 
-	  In other words, if your BACKPACK drive dosen't say "Series 6" on the
+	  In other words, if your BACKPACK drive doesn't say "Series 6" on the
 	  bottom, enable this option.
 
 	  If you chose to build PARIDE support into your kernel, you may
diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
--- a/drivers/block/scsi_ioctl.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/block/scsi_ioctl.c	2005-01-19 13:44:48 -08:00
@@ -339,7 +339,8 @@
 			 struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic)
 {
 	struct request *rq;
-	int err, in_len, out_len, bytes, opcode, cmdlen;
+	int err;
+	unsigned int in_len, out_len, bytes, opcode, cmdlen;
 	char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
 
 	/*
diff -Nru a/drivers/block/ub.c b/drivers/block/ub.c
--- a/drivers/block/ub.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/block/ub.c	2005-01-19 13:44:48 -08:00
@@ -108,7 +108,8 @@
  */
 #define UB_URB_TIMEOUT	(HZ*2)
 #define UB_DATA_TIMEOUT	(HZ*5)	/* ZIP does spin-ups in the data phase */
-#define UB_CTRL_TIMEOUT	(HZ/2) /* 500ms ought to be enough to clear a stall */
+#define UB_STAT_TIMEOUT	(HZ*5)	/* Same spinups and eject for a dataless cmd. */
+#define UB_CTRL_TIMEOUT	(HZ/2)	/* 500ms ought to be enough to clear a stall */
 
 /*
  * An instance of a SCSI command in transit.
@@ -307,6 +308,7 @@
 static void ub_scsi_dispatch(struct ub_dev *sc);
 static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc);
+static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
@@ -894,7 +896,7 @@
 		if (urb->status == -EPIPE) {
 			/*
 			 * STALL while clearning STALL.
-			 * A STALL is illegal on a control pipe!
+			 * The control pipe clears itself - nothing to do.
 			 * XXX Might try to reset the device here and retry.
 			 */
 			printk(KERN_NOTICE "%s: "
@@ -917,7 +919,7 @@
 		if (urb->status == -EPIPE) {
 			/*
 			 * STALL while clearning STALL.
-			 * A STALL is illegal on a control pipe!
+			 * The control pipe clears itself - nothing to do.
 			 * XXX Might try to reset the device here and retry.
 			 */
 			printk(KERN_NOTICE "%s: "
@@ -941,7 +943,8 @@
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u (%d)\n",
+				    "unable to submit clear for device %u"
+				    " (code %d)\n",
 				    sc->name, sc->dev->devnum, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
@@ -1001,7 +1004,8 @@
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u (%d)\n",
+				    "unable to submit clear for device %u"
+				    " (code %d)\n",
 				    sc->name, sc->dev->devnum, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
@@ -1033,7 +1037,8 @@
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
-				    "unable to submit clear for device %u (%d)\n",
+				    "unable to submit clear for device %u"
+				    " (code %d)\n",
 				    sc->name, sc->dev->devnum, rc);
 				/*
 				 * This is typically ENOMEM or some other such shit.
@@ -1061,33 +1066,7 @@
 				    sc->name, sc->dev->devnum);
 				goto Bad_End;
 			}
-
-			/*
-			 * ub_state_stat only not dropping the count...
-			 */
-			UB_INIT_COMPLETION(sc->work_done);
-
-			sc->last_pipe = sc->recv_bulk_pipe;
-			usb_fill_bulk_urb(&sc->work_urb, sc->dev,
-			    sc->recv_bulk_pipe, &sc->work_bcs,
-			    US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
-			sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
-			sc->work_urb.actual_length = 0;
-			sc->work_urb.error_count = 0;
-			sc->work_urb.status = 0;
-
-			rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC);
-			if (rc != 0) {
-				/* XXX Clear stalls */
-				printk("%s: CSW #%d submit failed (%d)\n",
-				   sc->name, cmd->tag, rc); /* P3 */
-				ub_complete(&sc->work_done);
-				ub_state_done(sc, cmd, rc);
-				return;
-			}
-
-			sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
-			add_timer(&sc->work_timer);
+			__ub_state_stat(sc, cmd);
 			return;
 		}
 
@@ -1108,17 +1087,31 @@
 			goto Bad_End;
 		}
 
+#if 0
 		if (bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) &&
 		    bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) {
-			/* XXX Rate-limit, even for P3 tagged */
-			/* P3 */ printk("ub: signature 0x%x\n", bcs->Signature);
 			/* Windows ignores signatures, so do we. */
 		}
+#endif
 
 		if (bcs->Tag != cmd->tag) {
-			/* P3 */ printk("%s: tag orig 0x%x reply 0x%x\n",
-			    sc->name, cmd->tag, bcs->Tag);
-			goto Bad_End;
+			/*
+			 * This usually happens when we disagree with the
+			 * device's microcode about something. For instance,
+			 * a few of them throw this after timeouts. They buffer
+			 * commands and reply at commands we timed out before.
+			 * Without flushing these replies we loop forever.
+			 */
+			if (++cmd->stat_count >= 4) {
+				printk(KERN_NOTICE "%s: "
+				    "tag mismatch orig 0x%x reply 0x%x "
+				    "on device %u\n",
+				    sc->name, cmd->tag, bcs->Tag,
+				    sc->dev->devnum);
+				goto Bad_End;
+			}
+			__ub_state_stat(sc, cmd);
+			return;
 		}
 
 		switch (bcs->Status) {
@@ -1174,9 +1167,9 @@
 
 /*
  * Factorization helper for the command state machine:
- * Submit a CSW read and go to STAT state.
+ * Submit a CSW read.
  */
-static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
 	int rc;
 
@@ -1192,14 +1185,23 @@
 
 	if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
 		/* XXX Clear stalls */
-		printk("ub: CSW #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
+		printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */
 		ub_complete(&sc->work_done);
 		ub_state_done(sc, cmd, rc);
 		return;
 	}
 
-	sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
+	sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT;
 	add_timer(&sc->work_timer);
+}
+
+/*
+ * Factorization helper for the command state machine:
+ * Submit a CSW read and go to STAT state.
+ */
+static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+{
+	__ub_state_stat(sc, cmd);
 
 	cmd->stat_count = 0;
 	cmd->state = UB_CMDST_STAT;
diff -Nru a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
--- a/drivers/bluetooth/bcm203x.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/bluetooth/bcm203x.c	2005-01-19 13:44:45 -08:00
@@ -46,6 +46,8 @@
 
 #define VERSION "1.0"
 
+static int ignore = 0;
+
 static struct usb_device_id bcm203x_table[] = {
 	/* Broadcom Blutonium (BCM2033) */
 	{ USB_DEVICE(0x0a5c, 0x2033) },
@@ -55,7 +57,6 @@
 
 MODULE_DEVICE_TABLE(usb, bcm203x_table);
 
-
 #define BCM203X_ERROR		0
 #define BCM203X_RESET		1
 #define BCM203X_LOAD_MINIDRV	2
@@ -175,7 +176,7 @@
 
 	BT_DBG("intf %p id %p", intf, id);
 
-	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+	if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0))
 		return -ENODEV;
 
 	data = kmalloc(sizeof(*data), GFP_KERNEL);
@@ -303,6 +304,9 @@
 
 module_init(bcm203x_init);
 module_exit(bcm203x_exit);
+
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
 
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION);
diff -Nru a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
--- a/drivers/bluetooth/bfusb.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/bluetooth/bfusb.c	2005-01-19 13:44:47 -08:00
@@ -47,6 +47,8 @@
 
 #define VERSION "1.1"
 
+static int ignore = 0;
+
 static struct usb_driver bfusb_driver;
 
 static struct usb_device_id bfusb_table[] = {
@@ -655,6 +657,9 @@
 
 	BT_DBG("intf %p id %p", intf, id);
 
+	if (ignore)
+		return -ENODEV;
+
 	/* Check number of endpoints */
 	if (intf->cur_altsetting->desc.bNumEndpoints < 2)
 		return -EIO;
@@ -791,6 +796,9 @@
 
 module_init(bfusb_init);
 module_exit(bfusb_exit);
+
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
 
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
diff -Nru a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
--- a/drivers/bluetooth/bluecard_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/bluetooth/bluecard_cs.c	2005-01-19 13:44:46 -08:00
@@ -55,13 +55,6 @@
 /* ======================== Module parameters ======================== */
 
 
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0x86bc;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, uint, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)");
 MODULE_LICENSE("GPL");
@@ -871,7 +864,7 @@
 	bluecard_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	/* Create new info device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -885,13 +878,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
 	link->irq.Handler = bluecard_interrupt;
 	link->irq.Instance = info;
diff -Nru a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
--- a/drivers/bluetooth/bt3c_cs.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/bluetooth/bt3c_cs.c	2005-01-19 13:44:48 -08:00
@@ -63,13 +63,6 @@
 /* ======================== Module parameters ======================== */
 
 
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, uint, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
 MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
 MODULE_LICENSE("GPL");
@@ -676,7 +669,7 @@
 	bt3c_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	/* Create new info device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -690,13 +683,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
 	link->irq.Handler = bt3c_interrupt;
 	link->irq.Instance = info;
diff -Nru a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
--- a/drivers/bluetooth/btuart_cs.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/bluetooth/btuart_cs.c	2005-01-19 13:44:48 -08:00
@@ -59,13 +59,6 @@
 /* ======================== Module parameters ======================== */
 
 
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, uint, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth driver for Bluetooth PCMCIA cards with HCI UART interface");
 MODULE_LICENSE("GPL");
@@ -595,7 +588,7 @@
 	btuart_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	/* Create new info device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -609,13 +602,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
 	link->irq.Handler = btuart_interrupt;
 	link->irq.Instance = info;
diff -Nru a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
--- a/drivers/bluetooth/dtl1_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/bluetooth/dtl1_cs.c	2005-01-19 13:44:46 -08:00
@@ -59,13 +59,6 @@
 /* ======================== Module parameters ======================== */
 
 
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, uint, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth driver for Nokia Connectivity Card DTL-1");
 MODULE_LICENSE("GPL");
@@ -574,7 +567,7 @@
 	dtl1_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	/* Create new info device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -588,13 +581,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 
 	link->irq.Handler = dtl1_interrupt;
 	link->irq.Instance = info;
diff -Nru a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
--- a/drivers/bluetooth/hci_bcsp.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/bluetooth/hci_bcsp.c	2005-01-19 13:44:47 -08:00
@@ -265,7 +265,7 @@
 /* This is a rewrite of pkt_avail in ABCSP */
 static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
 {
-	struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
+	struct bcsp_struct *bcsp = hu->priv;
 	unsigned long flags;
 	struct sk_buff *skb;
 	
@@ -629,7 +629,7 @@
 static void bcsp_timed_event(unsigned long arg)
 {
 	struct hci_uart *hu = (struct hci_uart *) arg;
-	struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
+	struct bcsp_struct *bcsp = hu->priv;
 	struct sk_buff *skb;
 	unsigned long flags;
 
diff -Nru a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
--- a/drivers/bluetooth/hci_ldisc.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/bluetooth/hci_ldisc.c	2005-01-19 13:44:47 -08:00
@@ -51,6 +51,7 @@
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
+
 #include "hci_uart.h"
 
 #ifndef CONFIG_BT_HCIUART_DEBUG
@@ -60,6 +61,8 @@
 #define BT_DMP( A... )
 #endif
 
+static int reset = 0;
+
 static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
 
 int hci_uart_register_proto(struct hci_uart_proto *p)
@@ -412,7 +415,10 @@
 	hdev->destruct = hci_uart_destruct;
 
 	hdev->owner = THIS_MODULE;
-	
+
+	if (reset)
+		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+
 	if (hci_register_dev(hdev) < 0) {
 		BT_ERR("Can't register HCI device");
 		hci_free_dev(hdev);
@@ -577,7 +583,10 @@
 module_init(hci_uart_init);
 module_exit(hci_uart_exit);
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+module_param(reset, bool, 0644);
+MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
--- a/drivers/bluetooth/hci_usb.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/bluetooth/hci_usb.c	2005-01-19 13:44:47 -08:00
@@ -66,6 +66,9 @@
 #define URB_ZERO_PACKET 0
 #endif
 
+static int ignore = 0;
+static int reset = 0;
+
 #ifdef CONFIG_BT_HCIUSB_SCO
 static int isoc = 2;
 #endif
@@ -827,7 +830,7 @@
 			id = match;
 	}
 
-	if (id->driver_info & HCI_IGNORE)
+	if (ignore || id->driver_info & HCI_IGNORE)
 		return -ENODEV;
 
 	if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
@@ -963,7 +966,7 @@
 
 	hdev->owner = THIS_MODULE;
 
-	if (id->driver_info & HCI_RESET)
+	if (reset || id->driver_info & HCI_RESET)
 		set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
 
 	if (hci_register_dev(hdev) < 0) {
@@ -1035,6 +1038,12 @@
 
 module_init(hci_usb_init);
 module_exit(hci_usb_exit);
+
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
+
+module_param(reset, bool, 0644);
+MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
 
 #ifdef CONFIG_BT_HCIUSB_SCO
 module_param(isoc, int, 0644);
diff -Nru a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
--- a/drivers/cdrom/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/cdrom/Kconfig	2005-01-19 13:44:47 -08:00
@@ -18,7 +18,7 @@
 	  have, say Y and find out whether you have one of the following
 	  drives.
 
-	  For each of these drivers, a file Documentation/cdrom/{driver_name}
+	  For each of these drivers, a <file:Documentation/cdrom/{driver_name}>
 	  exists. Especially in cases where you do not know exactly which kind
 	  of drive you have you should read there. Most of these drivers use a
 	  file drivers/cdrom/{driver_name}.h where you can define your
diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
--- a/drivers/char/Kconfig	2005-01-19 13:44:45 -08:00
+++ b/drivers/char/Kconfig	2005-01-19 13:44:45 -08:00
@@ -352,7 +352,7 @@
 	bool "TX3912/PR31700 serial port support"
 	depends on SERIAL_NONSTANDARD && MIPS && BROKEN_ON_SMP
 	help
-	  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
+	  The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core;
 	  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
 	  Say Y here to enable kernel support for the on-board serial port.
 
@@ -360,7 +360,7 @@
 	bool "Console on TX3912/PR31700 serial port"
 	depends on SERIAL_TX3912
 	help
-	  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
+	  The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core;
 	  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
 	  Say Y here to direct console I/O to the on-board serial port.
 
diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
--- a/drivers/char/agp/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/char/agp/Kconfig	2005-01-19 13:44:47 -08:00
@@ -144,7 +144,7 @@
 
 config AGP_HP_ZX1
 	tristate "HP ZX1 chipset AGP support"
-	depends on AGP && (IA64_HP_ZX1 || IA64_GENERIC)
+	depends on AGP && (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC)
 	help
 	  This option gives you AGP GART support for the HP ZX1 chipset
 	  for IA64 processors.
diff -Nru a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
--- a/drivers/char/ipmi/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/char/ipmi/Kconfig	2005-01-19 13:44:47 -08:00
@@ -12,7 +12,7 @@
          IPMI is a standard for managing sensors (temperature,
          voltage, etc.) in a system.
 
-         See Documentation/IPMI.txt for more details on the driver.
+         See <file:Documentation/IPMI.txt> for more details on the driver.
 
 	 If unsure, say N.
 
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/char/keyboard.c	2005-01-19 13:44:48 -08:00
@@ -31,7 +31,6 @@
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/string.h>
-#include <linux/random.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 
@@ -1030,9 +1029,6 @@
 	unsigned char type, raw_mode;
 	struct tty_struct *tty;
 	int shift_final;
-
-	if (down != 2)
-		add_keyboard_randomness((keycode << 1) ^ down);
 
 	tty = vc->vc_tty;
 
diff -Nru a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
--- a/drivers/char/pcmcia/synclink_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/char/pcmcia/synclink_cs.c	2005-01-19 13:44:46 -08:00
@@ -464,16 +464,6 @@
 static int maxframe[MAX_DEVICE_COUNT] = {0,};
 static int dosyncppp[MAX_DEVICE_COUNT] = {1,1,1,1};
 
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 module_param(break_on_load, bool, 0);
 module_param(ttymajor, int, 0);
 module_param(debug_level, int, 0);
@@ -555,7 +545,7 @@
     MGSLPC_INFO *info;
     dev_link_t *link;
     client_reg_t client_reg;
-    int ret, i;
+    int ret;
     
     if (debug_level >= DEBUG_LEVEL_INFO)
 	    printk("mgslpc_attach\n");
@@ -592,11 +582,6 @@
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.IRQInfo1   = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	    link->irq.IRQInfo2 = irq_mask;
-    else
-	    for (i = 0; i < 4; i++)
-		    link->irq.IRQInfo2 |= 1 << irq_list[i];
     link->irq.Handler = NULL;
     
     link->conf.Attributes = 0;
diff -Nru a/drivers/char/qtronix.c b/drivers/char/qtronix.c
--- a/drivers/char/qtronix.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/char/qtronix.c	2005-01-19 13:44:48 -08:00
@@ -69,7 +69,6 @@
 #include <linux/init.h>
 #include <linux/kbd_ll.h>
 #include <linux/delay.h>
-#include <linux/random.h>
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
@@ -442,7 +441,6 @@
 		return;
 	}
 
-	add_mouse_randomness(scancode);
 	if (aux_count) {
 		int head = queue->head;
 
diff -Nru a/drivers/char/random.c b/drivers/char/random.c
--- a/drivers/char/random.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/char/random.c	2005-01-19 13:44:45 -08:00
@@ -125,15 +125,12 @@
  * The current exported interfaces for gathering environmental noise
  * from the devices are:
  *
- * 	void add_keyboard_randomness(unsigned char scancode);
- * 	void add_mouse_randomness(__u32 mouse_data);
+ * 	void add_input_randomness(unsigned int type, unsigned int code,
+ *                                unsigned int value);
  * 	void add_interrupt_randomness(int irq);
  *
- * add_keyboard_randomness() uses the inter-keypress timing, as well as the
- * scancode as random inputs into the "entropy pool".
- *
- * add_mouse_randomness() uses the mouse interrupt timing, as well as
- * the reported position of the mouse from the hardware.
+ * add_input_randomness() uses the input layer interrupt timing, as well as
+ * the event type information from the hardware.
  *
  * add_interrupt_randomness() uses the inter-interrupt timing as random
  * inputs to the entropy pool.  Note that not all interrupts are good
@@ -473,7 +470,15 @@
 #endif
 
 #if 0
-#define DEBUG_ENT(fmt, arg...) printk(KERN_DEBUG "random: " fmt, ## arg)
+static int debug = 0;
+module_param(debug, bool, 0644);
+#define DEBUG_ENT(fmt, arg...) do { if (debug) \
+	printk(KERN_DEBUG "random %04d %04d %04d: " \
+	fmt,\
+	random_state->entropy_count,\
+	sec_random_state->entropy_count,\
+	urandom_state->entropy_count,\
+	## arg); } while (0)
 #else
 #define DEBUG_ENT(fmt, arg...) do {} while (0)
 #endif
@@ -648,8 +653,8 @@
 	} else {
 		r->entropy_count += nbits;
 		if (nbits)
-			DEBUG_ENT("Added %d entropy credits to %s, now %d\n",
-				  nbits, r->name, r->entropy_count);
+			DEBUG_ENT("added %d entropy credits to %s\n",
+				  nbits, r->name);
 	}
 
 	spin_unlock_irqrestore(&r->lock, flags);
@@ -780,8 +785,7 @@
 	unsigned dont_count_entropy:1;
 };
 
-static struct timer_rand_state keyboard_timer_state;
-static struct timer_rand_state mouse_timer_state;
+static struct timer_rand_state input_timer_state;
 static struct timer_rand_state extract_timer_state;
 static struct timer_rand_state *irq_timer_state[NR_IRQS];
 
@@ -797,8 +801,8 @@
  */
 static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
 {
-	cycles_t time;
-	long delta, delta2, delta3;
+	cycles_t data;
+	long delta, delta2, delta3, time;
 	int entropy = 0;
 
 	preempt_disable();
@@ -808,20 +812,12 @@
 		goto out;
 
 	/*
-	 * Use get_cycles() if implemented, otherwise fall back to
-	 * jiffies.
-	 */
-	time = get_cycles();
-	if (time)
-		num ^= (u32)((time >> 31) >> 1);
-	else
-		time = jiffies;
-
-	/*
 	 * Calculate number of bits of randomness we probably added.
 	 * We take into account the first, second and third-order deltas
 	 * in order to make our estimate.
 	 */
+	time = jiffies;
+
 	if (!state->dont_count_entropy) {
 		delta = time - state->last_time;
 		state->last_time = time;
@@ -853,33 +849,43 @@
 
 		entropy = int_ln_12bits(delta);
 	}
-	batch_entropy_store(num, time, entropy);
+
+	/*
+	 * Use get_cycles() if implemented, otherwise fall back to
+	 * jiffies.
+	 */
+	data = get_cycles();
+	if (data)
+		num ^= (u32)((data >> 31) >> 1);
+	else
+		data = time;
+
+	batch_entropy_store(num, data, entropy);
 out:
 	preempt_enable();
 }
 
-void add_keyboard_randomness(unsigned char scancode)
+extern void add_input_randomness(unsigned int type, unsigned int code,
+				 unsigned int value)
 {
-	static unsigned char last_scancode;
-	/* ignore autorepeat (multiple key down w/o key up) */
-	if (scancode != last_scancode) {
-		last_scancode = scancode;
-		add_timer_randomness(&keyboard_timer_state, scancode);
-	}
-}
+	static unsigned char last_value;
 
-void add_mouse_randomness(__u32 mouse_data)
-{
-	add_timer_randomness(&mouse_timer_state, mouse_data);
-}
+	/* ignore autorepeat and the like */
+	if (value == last_value)
+		return;
 
-EXPORT_SYMBOL(add_mouse_randomness);
+	DEBUG_ENT("input event\n");
+	last_value = value;
+	add_timer_randomness(&input_timer_state,
+			     (type << 4) ^ code ^ (code >> 4) ^ value);
+}
 
 void add_interrupt_randomness(int irq)
 {
 	if (irq >= NR_IRQS || irq_timer_state[irq] == 0)
 		return;
 
+	DEBUG_ENT("irq event %d\n", irq);
 	add_timer_randomness(irq_timer_state[irq], 0x100 + irq);
 }
 
@@ -888,6 +894,8 @@
 	if (!disk || !disk->random)
 		return;
 	/* first major is 1, so we get >= 0x200 here */
+	DEBUG_ENT("disk event %d:%d\n", disk->major, disk->first_minor);
+
 	add_timer_randomness(disk->random,
 			     0x100 + MKDEV(disk->major, disk->first_minor));
 }
@@ -1308,10 +1316,8 @@
 		int bytes = max_t(int, random_read_wakeup_thresh / 8,
 				min_t(int, nbytes, TMP_BUF_SIZE));
 
-		DEBUG_ENT("%04d %04d : going to reseed %s with %d bits "
+		DEBUG_ENT("going to reseed %s with %d bits "
 			  "(%d of %d requested)\n",
-			  random_state->entropy_count,
-			  sec_random_state->entropy_count,
 			  r->name, bytes * 8, nbytes * 8, r->entropy_count);
 
 		bytes=extract_entropy(random_state, tmp, bytes,
@@ -1352,9 +1358,7 @@
 	/* Hold lock while accounting */
 	spin_lock_irqsave(&r->lock, cpuflags);
 
-	DEBUG_ENT("%04d %04d : trying to extract %d bits from %s\n",
-		  random_state->entropy_count,
-		  sec_random_state->entropy_count,
+	DEBUG_ENT("trying to extract %d bits from %s\n",
 		  nbytes * 8, r->name);
 
 	if (flags & EXTRACT_ENTROPY_LIMIT && nbytes >= r->entropy_count / 8)
@@ -1368,7 +1372,7 @@
 	if (r->entropy_count < random_write_wakeup_thresh)
 		wake_up_interruptible(&random_write_wait);
 
-	DEBUG_ENT("Debiting %d entropy credits from %s%s\n",
+	DEBUG_ENT("debiting %d entropy credits from %s%s\n",
 		  nbytes * 8, r->name,
 		  flags & EXTRACT_ENTROPY_LIMIT ? "" : " (unlimited)");
 
@@ -1386,15 +1390,7 @@
 				break;
 			}
 
-			DEBUG_ENT("%04d %04d : extract feeling sleepy (%d bytes left)\n",
-				  random_state->entropy_count,
-				  sec_random_state->entropy_count, nbytes);
-
 			schedule();
-
-			DEBUG_ENT("%04d %04d : extract woke up\n",
-				  random_state->entropy_count,
-				  sec_random_state->entropy_count);
 		}
 
 		/* Hash the pool to get the output */
@@ -1546,8 +1542,7 @@
 #endif
 	for (i = 0; i < NR_IRQS; i++)
 		irq_timer_state[i] = NULL;
-	memset(&keyboard_timer_state, 0, sizeof(struct timer_rand_state));
-	memset(&mouse_timer_state, 0, sizeof(struct timer_rand_state));
+	memset(&input_timer_state, 0, sizeof(struct timer_rand_state));
 	memset(&extract_timer_state, 0, sizeof(struct timer_rand_state));
 	extract_timer_state.dont_count_entropy = 1;
 	return 0;
@@ -1603,20 +1598,14 @@
 		if (n > SEC_XFER_SIZE)
 			n = SEC_XFER_SIZE;
 
-		DEBUG_ENT("%04d %04d : reading %d bits, p: %d s: %d\n",
-			  random_state->entropy_count,
-			  sec_random_state->entropy_count,
-			  n*8, random_state->entropy_count,
-			  sec_random_state->entropy_count);
+		DEBUG_ENT("reading %d bits\n", n*8);
 
 		n = extract_entropy(sec_random_state, buf, n,
 				    EXTRACT_ENTROPY_USER |
 				    EXTRACT_ENTROPY_LIMIT |
 				    EXTRACT_ENTROPY_SECONDARY);
 
-		DEBUG_ENT("%04d %04d : read got %d bits (%d still needed)\n",
-			  random_state->entropy_count,
-			  sec_random_state->entropy_count,
+		DEBUG_ENT("read got %d bits (%d still needed)\n",
 			  n*8, (nbytes-n)*8);
 
 		if (n == 0) {
@@ -1629,10 +1618,6 @@
 				break;
 			}
 
-			DEBUG_ENT("%04d %04d : sleeping?\n",
-				  random_state->entropy_count,
-				  sec_random_state->entropy_count);
-
 			set_current_state(TASK_INTERRUPTIBLE);
 			add_wait_queue(&random_read_wait, &wait);
 
@@ -1642,10 +1627,6 @@
 			set_current_state(TASK_RUNNING);
 			remove_wait_queue(&random_read_wait, &wait);
 
-			DEBUG_ENT("%04d %04d : waking up\n",
-				  random_state->entropy_count,
-				  sec_random_state->entropy_count);
-
 			continue;
 		}
 
@@ -2387,7 +2368,7 @@
 	cookie -= tmp[17] + sseq;
 	/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
 
-	diff = (count - (cookie >> COOKIEBITS)) & ((__u32) - 1 >> COOKIEBITS);
+	diff = (count - (cookie >> COOKIEBITS)) & ((__u32)-1 >> COOKIEBITS);
 	if (diff >= maxdiff)
 		return (__u32)-1;
 
diff -Nru a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
--- a/drivers/cpufreq/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/cpufreq/Kconfig	2005-01-19 13:44:47 -08:00
@@ -27,17 +27,21 @@
 	       2 to activate CPUfreq drivers debugging, and
 	       4 to activate CPUfreq governor debugging
 
-config CPU_FREQ_PROC_INTF
-	tristate "/proc/cpufreq interface (deprecated)"
-	depends on CPU_FREQ && PROC_FS
-	help
-	  This enables the /proc/cpufreq interface for controlling
-	  CPUFreq. Please note that it is recommended to use the sysfs
-	  interface instead (which is built automatically). 
-	  
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-	  
-	  If in doubt, say N.
+config CPU_FREQ_STAT
+       tristate "CPU frequency translation statistics"
+       depends on CPU_FREQ && CPU_FREQ_TABLE
+       default y
+       help
+         This driver exports CPU frequency statistics information through sysfs
+         file system
+
+config CPU_FREQ_STAT_DETAILS
+       bool "CPU frequency translation statistics details"
+       depends on CPU_FREQ && CPU_FREQ_STAT
+       default n
+       help
+         This will show detail CPU frequency translation table in sysfs file
+         system
 
 choice
 	prompt "Default CPUFreq governor"
@@ -97,21 +101,6 @@
 	  For details, take a look at <file:Documentation/cpu-freq/>.
 
 	  If in doubt, say Y.
-
-config CPU_FREQ_24_API
-	bool "/proc/sys/cpu/ interface (2.4. / OLD)"
-	depends on CPU_FREQ_GOV_USERSPACE
-	depends on SYSCTL
-	help
-	  This enables the /proc/sys/cpu/ sysctl interface for controlling
-	  the CPUFreq,"userspace" governor. This is the same interface
-	  as known from the 2.4.-kernel patches for CPUFreq, and offers
-	  the same functionality as long as "userspace" is the
-	  selected governor for the specified CPU.
-	
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
 
 config CPU_FREQ_GOV_ONDEMAND
 	tristate "'ondemand' cpufreq policy governor"
diff -Nru a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
--- a/drivers/cpufreq/Makefile	2005-01-19 13:44:48 -08:00
+++ b/drivers/cpufreq/Makefile	2005-01-19 13:44:48 -08:00
@@ -1,5 +1,7 @@
 # CPUfreq core
 obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o
+# CPUfreq stats
+obj-$(CONFIG_CPU_FREQ_STAT)             += cpufreq_stats.o
 
 # CPUfreq governors 
 obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)	+= cpufreq_performance.o
@@ -9,5 +11,4 @@
 
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
-obj-$(CONFIG_CPU_FREQ_PROC_INTF)	+= proc_intf.o
 
diff -Nru a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
--- a/drivers/cpufreq/cpufreq.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/cpufreq/cpufreq.c	2005-01-19 13:44:46 -08:00
@@ -63,7 +63,7 @@
 static LIST_HEAD(cpufreq_governor_list);
 static DECLARE_MUTEX		(cpufreq_governor_sem);
 
-static struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
+struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
 {
 	struct cpufreq_policy *data;
 	unsigned long flags;
@@ -102,12 +102,14 @@
  err_out:
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
 
-static void cpufreq_cpu_put(struct cpufreq_policy *data)
+void cpufreq_cpu_put(struct cpufreq_policy *data)
 {
 	kobject_put(&data->kobj);
 	module_put(cpufreq_driver->owner);
 }
+EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
 
 
 /*********************************************************************
@@ -285,7 +287,7 @@
 /**
  * cpufreq_parse_governor - parse a governor string
  */
-int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
+static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
 				struct cpufreq_governor **governor)
 {
 	if (!cpufreq_driver)
@@ -763,8 +765,11 @@
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 #endif
 
+	down(&data->lock);
 	if (cpufreq_driver->target)
 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
+	cpufreq_driver->target = NULL;
+	up(&data->lock);
 
 	kobject_unregister(&data->kobj);
 
@@ -893,6 +898,13 @@
 		return 0;
 	}
 
+	if (cpufreq_driver->resume) {
+		ret = cpufreq_driver->resume(cpu_policy);
+		printk(KERN_ERR "cpufreq: resume failed in ->resume step on CPU %u\n", cpu_policy->cpu);
+		cpufreq_cpu_put(cpu_policy);
+		return (ret);
+	}
+
 	if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
 		unsigned int cur_freq = 0;
 
@@ -1018,7 +1030,7 @@
 	lock_cpu_hotplug();
 	dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
 		target_freq, relation);
-	if (cpu_online(policy->cpu))
+	if (cpu_online(policy->cpu) && cpufreq_driver->target)
 		retval = cpufreq_driver->target(policy, target_freq, relation);
 	unlock_cpu_hotplug();
 	return retval;
diff -Nru a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
--- a/drivers/cpufreq/cpufreq_ondemand.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/cpufreq/cpufreq_ondemand.c	2005-01-19 13:44:47 -08:00
@@ -229,10 +229,14 @@
 	static int down_skip[NR_CPUS];
 	struct cpu_dbs_info_s *this_dbs_info;
 
+	struct cpufreq_policy *policy;
+	unsigned int j;
+
 	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 	if (!this_dbs_info->enable)
 		return;
 
+	policy = this_dbs_info->cur_policy;
 	/* 
 	 * The default safe range is 20% to 80% 
 	 * Every sampling_rate, we check
@@ -246,12 +250,33 @@
 	 * Frequency reduction happens at minimum steps of 
 	 * 5% of max_frequency 
 	 */
+
 	/* Check for frequency increase */
 	total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
 		kstat_cpu(cpu).cpustat.iowait;
 	idle_ticks = total_idle_ticks -
 		this_dbs_info->prev_cpu_idle_up;
 	this_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+	
+
+	for_each_cpu_mask(j, policy->cpus) {
+		unsigned int tmp_idle_ticks;
+		struct cpu_dbs_info_s *j_dbs_info;
+
+		if (j == cpu)
+			continue;
+
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		/* Check for frequency increase */
+		total_idle_ticks = kstat_cpu(j).cpustat.idle +
+			kstat_cpu(j).cpustat.iowait;
+		tmp_idle_ticks = total_idle_ticks -
+			j_dbs_info->prev_cpu_idle_up;
+		j_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+
+		if (tmp_idle_ticks < idle_ticks)
+			idle_ticks = tmp_idle_ticks;
+	}
 
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
@@ -259,8 +284,7 @@
 			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate);
 
 	if (idle_ticks < up_idle_ticks) {
-		__cpufreq_driver_target(this_dbs_info->cur_policy,
-			this_dbs_info->cur_policy->max, 
+		__cpufreq_driver_target(policy, policy->max, 
 			CPUFREQ_RELATION_H);
 		down_skip[cpu] = 0;
 		this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
@@ -272,12 +296,34 @@
 	if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor)
 		return;
 
+	total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
+		kstat_cpu(cpu).cpustat.iowait;
 	idle_ticks = total_idle_ticks -
 		this_dbs_info->prev_cpu_idle_down;
+	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+	for_each_cpu_mask(j, policy->cpus) {
+		unsigned int tmp_idle_ticks;
+		struct cpu_dbs_info_s *j_dbs_info;
+
+		if (j == cpu)
+			continue;
+
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		/* Check for frequency increase */
+		total_idle_ticks = kstat_cpu(j).cpustat.idle +
+			kstat_cpu(j).cpustat.iowait;
+		tmp_idle_ticks = total_idle_ticks -
+			j_dbs_info->prev_cpu_idle_down;
+		j_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+		if (tmp_idle_ticks < idle_ticks)
+			idle_ticks = tmp_idle_ticks;
+	}
+
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
 	down_skip[cpu] = 0;
-	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
 
 	freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
 		dbs_tuners_ins.sampling_down_factor;
@@ -285,14 +331,14 @@
 			sampling_rate_in_HZ(freq_down_sampling_rate);
 
 	if (idle_ticks > down_idle_ticks ) {
-		freq_down_step = (5 * this_dbs_info->cur_policy->max) / 100;
+		freq_down_step = (5 * policy->max) / 100;
 
 		/* max freq cannot be less than 100. But who knows.... */
 		if (unlikely(freq_down_step == 0))
 			freq_down_step = 5;
 
-		__cpufreq_driver_target(this_dbs_info->cur_policy,
-			this_dbs_info->cur_policy->cur - freq_down_step, 
+		__cpufreq_driver_target(policy,
+			policy->cur - freq_down_step, 
 			CPUFREQ_RELATION_H);
 		return;
 	}
@@ -313,7 +359,8 @@
 static inline void dbs_timer_init(void)
 {
 	INIT_WORK(&dbs_work, do_dbs_timer, NULL);
-	schedule_work(&dbs_work);
+	schedule_delayed_work(&dbs_work,
+			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate));
 	return;
 }
 
@@ -328,6 +375,7 @@
 {
 	unsigned int cpu = policy->cpu;
 	struct cpu_dbs_info_s *this_dbs_info;
+	unsigned int j;
 
 	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 
@@ -344,14 +392,18 @@
 			break;
 		 
 		down(&dbs_sem);
-		this_dbs_info->cur_policy = policy;
+		for_each_cpu_mask(j, policy->cpus) {
+			struct cpu_dbs_info_s *j_dbs_info;
+			j_dbs_info = &per_cpu(cpu_dbs_info, j);
+			j_dbs_info->cur_policy = policy;
 		
-		this_dbs_info->prev_cpu_idle_up = 
-				kstat_cpu(cpu).cpustat.idle +
-				kstat_cpu(cpu).cpustat.iowait;
-		this_dbs_info->prev_cpu_idle_down = 
-				kstat_cpu(cpu).cpustat.idle +
-				kstat_cpu(cpu).cpustat.iowait;
+			j_dbs_info->prev_cpu_idle_up = 
+				kstat_cpu(j).cpustat.idle +
+				kstat_cpu(j).cpustat.iowait;
+			j_dbs_info->prev_cpu_idle_down = 
+				kstat_cpu(j).cpustat.idle +
+				kstat_cpu(j).cpustat.iowait;
+		}
 		this_dbs_info->enable = 1;
 		sysfs_create_group(&policy->kobj, &dbs_attr_group);
 		dbs_enable++;
diff -Nru a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/cpufreq/cpufreq_stats.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,334 @@
+/*
+ *  drivers/cpufreq/cpufreq_stats.c
+ *
+ *  Copyright (C) 2003-2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
+ *  	      (C) 2004 Zou Nan hai <nanhai.zou@intel.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/sysfs.h>
+#include <linux/cpufreq.h>
+#include <linux/jiffies.h>
+#include <linux/percpu.h>
+#include <linux/kobject.h>
+#include <linux/spinlock.h>
+
+static spinlock_t cpufreq_stats_lock;
+
+#define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
+static struct freq_attr _attr_##_name = {\
+	.attr = {.name = __stringify(_name), .owner = THIS_MODULE, \
+		.mode = _mode, }, \
+	.show = _show,\
+};
+
+static unsigned long
+delta_time(unsigned long old, unsigned long new)
+{
+	return (old > new) ? (old - new): (new + ~old + 1);
+}
+
+struct cpufreq_stats {
+	unsigned int cpu;
+	unsigned int total_trans;
+	unsigned long long last_time;
+	unsigned int max_state;
+	unsigned int state_num;
+	unsigned int last_index;
+	unsigned long long *time_in_state;
+	unsigned int *freq_table;
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	unsigned int *trans_table;
+#endif
+};
+
+static struct cpufreq_stats *cpufreq_stats_table[NR_CPUS];
+
+struct cpufreq_stats_attribute {
+	struct attribute attr;
+	ssize_t(*show) (struct cpufreq_stats *, char *);
+};
+
+static int
+cpufreq_stats_update (unsigned int cpu)
+{
+	struct cpufreq_stats *stat;
+	spin_lock(&cpufreq_stats_lock);
+	stat = cpufreq_stats_table[cpu];
+	if (stat->time_in_state)
+		stat->time_in_state[stat->last_index] +=
+			delta_time(stat->last_time, jiffies);
+	stat->last_time = jiffies;
+	spin_unlock(&cpufreq_stats_lock);
+	return 0;
+}
+
+static ssize_t
+show_total_trans(struct cpufreq_policy *policy, char *buf)
+{
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	return sprintf(buf, "%d\n",
+			cpufreq_stats_table[stat->cpu]->total_trans);
+}
+
+static ssize_t
+show_time_in_state(struct cpufreq_policy *policy, char *buf)
+{
+	ssize_t len = 0;
+	int i;
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	cpufreq_stats_update(stat->cpu);
+	for (i = 0; i < stat->state_num; i++) {
+		len += sprintf(buf + len, "%u %llu\n",
+			stat->freq_table[i], stat->time_in_state[i]);
+	}
+	return len;
+}
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+static ssize_t
+show_trans_table(struct cpufreq_policy *policy, char *buf)
+{
+	ssize_t len = 0;
+	int i, j;
+
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	cpufreq_stats_update(stat->cpu);
+	for (i = 0; i < stat->state_num; i++) {
+		if (len >= PAGE_SIZE)
+			break;
+		len += snprintf(buf + len, PAGE_SIZE - len, "%9u:\t",
+				stat->freq_table[i]);
+
+		for (j = 0; j < stat->state_num; j++)   {
+			if (len >= PAGE_SIZE)
+				break;
+			len += snprintf(buf + len, PAGE_SIZE - len, "%u\t",
+					stat->trans_table[i*stat->max_state+j]);
+		}
+		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	}
+	return len;
+}
+CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table);
+#endif
+
+CPUFREQ_STATDEVICE_ATTR(total_trans,0444,show_total_trans);
+CPUFREQ_STATDEVICE_ATTR(time_in_state,0444,show_time_in_state);
+
+static struct attribute *default_attrs[] = {
+	&_attr_total_trans.attr,
+	&_attr_time_in_state.attr,
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	&_attr_trans_table.attr,
+#endif
+	NULL
+};
+static struct attribute_group stats_attr_group = {
+	.attrs = default_attrs,
+	.name = "stats"
+};
+
+static int
+freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
+{
+	int index;
+	for (index = 0; index < stat->max_state; index++)
+		if (stat->freq_table[index] == freq)
+			return index;
+	return -1;
+}
+
+static void
+cpufreq_stats_free_table (unsigned int cpu)
+{
+	struct cpufreq_stats *stat = cpufreq_stats_table[cpu];
+	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+	if (policy && policy->cpu == cpu)	
+		sysfs_remove_group(&policy->kobj, &stats_attr_group);
+	if (stat) {
+		kfree(stat->time_in_state);
+		kfree(stat);
+	}
+	cpufreq_stats_table[cpu] = NULL;
+	if (policy)
+		cpufreq_cpu_put(policy);
+}
+
+static int
+cpufreq_stats_create_table (struct cpufreq_policy *policy,
+		struct cpufreq_frequency_table *table)
+{
+	unsigned int i, j, count = 0, ret = 0;
+	struct cpufreq_stats *stat;
+	struct cpufreq_policy *data;
+	unsigned int alloc_size;
+	unsigned int cpu = policy->cpu;
+	if (cpufreq_stats_table[cpu])
+		return -EBUSY;
+	if ((stat = kmalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(stat, 0, sizeof (struct cpufreq_stats));
+
+	data = cpufreq_cpu_get(cpu);
+	if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group)))
+		goto error_out;
+
+	stat->cpu = cpu;
+	cpufreq_stats_table[cpu] = stat;
+
+	for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		unsigned int freq = table[i].frequency;
+		if (freq == CPUFREQ_ENTRY_INVALID)
+			continue;
+		count++;
+	}
+
+	alloc_size = count * sizeof(int) + count * sizeof(long long);
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	alloc_size += count * count * sizeof(int);
+#endif
+	stat->max_state = count;
+	stat->time_in_state = kmalloc(alloc_size, GFP_KERNEL);
+	if (!stat->time_in_state) {
+		ret = -ENOMEM;
+		goto error_out;
+	}
+	memset(stat->time_in_state, 0, alloc_size);
+	stat->freq_table = (unsigned int *)(stat->time_in_state + count);
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	stat->trans_table = stat->freq_table + count;
+#endif
+	j = 0;
+	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		unsigned int freq = table[i].frequency;
+		if (freq == CPUFREQ_ENTRY_INVALID)
+			continue;
+		if (freq_table_get_index(stat, freq) == -1)
+			stat->freq_table[j++] = freq;
+	}
+	stat->state_num = j;
+	spin_lock(&cpufreq_stats_lock);
+	stat->last_time = jiffies;
+	stat->last_index = freq_table_get_index(stat, policy->cur);
+	spin_unlock(&cpufreq_stats_lock);
+	cpufreq_cpu_put(data);
+	return 0;
+error_out:
+	cpufreq_cpu_put(data);
+	kfree(stat);
+	cpufreq_stats_table[cpu] = NULL;
+	return ret;
+}
+
+static int
+cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val,
+		void *data)
+{
+	int ret;
+	struct cpufreq_policy *policy = data;
+	struct cpufreq_frequency_table *table;
+	unsigned int cpu = policy->cpu;
+	if (val != CPUFREQ_NOTIFY)
+		return 0;
+	table = cpufreq_frequency_get_table(cpu);
+	if (!table)
+		return 0;
+	if ((ret = cpufreq_stats_create_table(policy, table)))
+		return ret;
+	return 0;
+}
+
+static int
+cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
+		void *data)
+{
+	struct cpufreq_freqs *freq = data;
+	struct cpufreq_stats *stat;
+	int old_index, new_index;
+
+	if (val != CPUFREQ_POSTCHANGE)
+		return 0;
+
+	stat = cpufreq_stats_table[freq->cpu];
+	if (!stat)
+		return 0;
+	old_index = freq_table_get_index(stat, freq->old);
+	new_index = freq_table_get_index(stat, freq->new);
+
+	cpufreq_stats_update(freq->cpu);
+	if (old_index == new_index)
+		return 0;
+
+	spin_lock(&cpufreq_stats_lock);
+	stat->last_index = new_index;
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	stat->trans_table[old_index * stat->max_state + new_index]++;
+#endif
+	stat->total_trans++;
+	spin_unlock(&cpufreq_stats_lock);
+	return 0;
+}
+
+static struct notifier_block notifier_policy_block = {
+	.notifier_call = cpufreq_stat_notifier_policy
+};
+
+static struct notifier_block notifier_trans_block = {
+	.notifier_call = cpufreq_stat_notifier_trans
+};
+
+static int
+__init cpufreq_stats_init(void)
+{
+	int ret;
+	unsigned int cpu;
+	spin_lock_init(&cpufreq_stats_lock);
+	if ((ret = cpufreq_register_notifier(&notifier_policy_block,
+				CPUFREQ_POLICY_NOTIFIER)))
+		return ret;
+
+	if ((ret = cpufreq_register_notifier(&notifier_trans_block,
+				CPUFREQ_TRANSITION_NOTIFIER))) {
+		cpufreq_unregister_notifier(&notifier_policy_block,
+				CPUFREQ_POLICY_NOTIFIER);
+		return ret;
+	}
+
+	for_each_cpu(cpu)
+		cpufreq_update_policy(cpu);
+	return 0;
+}
+static void
+__exit cpufreq_stats_exit(void)
+{
+	unsigned int cpu;
+	cpufreq_unregister_notifier(&notifier_policy_block,
+			CPUFREQ_POLICY_NOTIFIER);
+	cpufreq_unregister_notifier(&notifier_trans_block,
+			CPUFREQ_TRANSITION_NOTIFIER);
+	for_each_cpu(cpu)
+		cpufreq_stats_free_table(cpu);
+}
+
+MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
+MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats through sysfs filesystem");
+MODULE_LICENSE ("GPL");
+
+module_init(cpufreq_stats_init);
+module_exit(cpufreq_stats_exit);
diff -Nru a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
--- a/drivers/cpufreq/cpufreq_userspace.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/cpufreq/cpufreq_userspace.c	2005-01-19 13:44:46 -08:00
@@ -17,51 +17,13 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/ctype.h>
 #include <linux/cpufreq.h>
-#include <linux/sysctl.h>
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
 
 #include <asm/uaccess.h>
 
-#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MAX, \
-                .data		= &cpu_max_freq[cpunr], \
-                .procname	= "speed-max", \
-                .maxlen		= sizeof(cpu_max_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MIN, \
-                .data		= &cpu_min_freq[cpunr], \
-                .procname	= "speed-min", \
-                .maxlen		= sizeof(cpu_min_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ, \
-                .procname	= "speed", \
-                .mode		= 0644, \
-                .proc_handler	= cpufreq_procctl, \
-                .strategy	= cpufreq_sysctl, \
-                .extra1		= (void*) (cpunr), }
-
-#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
-                CTL_CPU_VARS_SPEED_MAX(cpunr), \
-                CTL_CPU_VARS_SPEED_MIN(cpunr), \
-                CTL_CPU_VARS_SPEED(cpunr),  \
-                { .ctl_name = 0, }, }
-
-/* the ctl_table entry for each CPU */
-#define CPU_ENUM(s) { \
-                .ctl_name	= (CPU_NR + s), \
-                .procname	= #s, \
-                .mode		= 0555, \
-                .child		= ctl_cpu_vars_##s }
 
 /**
  * A few values needed by the userspace governor
@@ -96,17 +58,17 @@
 
 
 /** 
- * _cpufreq_set - set the CPU frequency
+ * cpufreq_set - set the CPU frequency
  * @freq: target frequency in kHz
  * @cpu: CPU for which the frequency is to be set
  *
  * Sets the CPU frequency to freq.
  */
-static int _cpufreq_set(unsigned int freq, unsigned int cpu)
+static int cpufreq_set(unsigned int freq, unsigned int cpu)
 {
 	int ret = -EINVAL;
 
-	dprintk("_cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
+	dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
 
 	down(&userspace_sem);
 	if (!cpu_is_managed[cpu])
@@ -135,358 +97,6 @@
 }
 
 
-#ifdef CONFIG_CPU_FREQ_24_API
-
-#warning The /proc/sys/cpu/ and sysctl interface to cpufreq will be removed from the 2.6. kernel series soon after 2005-01-01
-
-static unsigned int warning_print = 0;
-
-int __deprecated cpufreq_set(unsigned int freq, unsigned int cpu)
-{
-	return _cpufreq_set(freq, cpu);
-}
-EXPORT_SYMBOL_GPL(cpufreq_set);
-
-
-/** 
- * cpufreq_setmax - set the CPU to the maximum frequency
- * @cpu - affected cpu;
- *
- * Sets the CPU frequency to the maximum frequency supported by
- * this CPU.
- */
-int __deprecated cpufreq_setmax(unsigned int cpu)
-{
-	if (!cpu_is_managed[cpu] || !cpu_online(cpu))
-		return -EINVAL;
-	return _cpufreq_set(cpu_max_freq[cpu], cpu);
-}
-EXPORT_SYMBOL_GPL(cpufreq_setmax);
-
-/*********************** cpufreq_sysctl interface ********************/
-static int
-cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
-		void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-	char buf[16], *p;
-	int cpu = (long) ctl->extra1;
-	unsigned int len, left = *lenp;
-
-	if (!left || (*ppos && !write) || !cpu_online(cpu)) {
-		*lenp = 0;
-		return 0;
-	}
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/sys/cpu/ is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	if (write) {
-		unsigned int freq;
-
-		len = left;
-		if (left > sizeof(buf))
-			left = sizeof(buf);
-		if (copy_from_user(buf, buffer, left))
-			return -EFAULT;
-		buf[sizeof(buf) - 1] = '\0';
-
-		freq = simple_strtoul(buf, &p, 0);
-		_cpufreq_set(freq, cpu);
-	} else {
-		len = sprintf(buf, "%d\n", cpufreq_get(cpu));
-		if (len > left)
-			len = left;
-		if (copy_to_user(buffer, buf, len))
-			return -EFAULT;
-	}
-
-	*lenp = len;
-	*ppos += len;
-	return 0;
-}
-
-static int
-cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
-	       void __user *oldval, size_t __user *oldlenp,
-	       void __user *newval, size_t newlen, void **context)
-{
-	int cpu = (long) table->extra1;
-
-	if (!cpu_online(cpu))
-		return -EINVAL;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/sys/cpu/ is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	if (oldval && oldlenp) {
-		size_t oldlen;
-
-		if (get_user(oldlen, oldlenp))
-			return -EFAULT;
-
-		if (oldlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (put_user(cpufreq_get(cpu), (unsigned int __user *)oldval) ||
-		    put_user(sizeof(unsigned int), oldlenp))
-			return -EFAULT;
-	}
-	if (newval && newlen) {
-		unsigned int freq;
-
-		if (newlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (get_user(freq, (unsigned int __user *)newval))
-			return -EFAULT;
-
-		_cpufreq_set(freq, cpu);
-	}
-	return 1;
-}
-
-/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-        CTL_TABLE_CPU_VARS(0);
-#if NR_CPUS > 1
-	CTL_TABLE_CPU_VARS(1);
-#endif
-#if NR_CPUS > 2
-	CTL_TABLE_CPU_VARS(2);
-#endif
-#if NR_CPUS > 3
-	CTL_TABLE_CPU_VARS(3);
-#endif
-#if NR_CPUS > 4
-	CTL_TABLE_CPU_VARS(4);
-#endif
-#if NR_CPUS > 5
-	CTL_TABLE_CPU_VARS(5);
-#endif
-#if NR_CPUS > 6
-	CTL_TABLE_CPU_VARS(6);
-#endif
-#if NR_CPUS > 7
-	CTL_TABLE_CPU_VARS(7);
-#endif
-#if NR_CPUS > 8
-	CTL_TABLE_CPU_VARS(8);
-#endif
-#if NR_CPUS > 9
-	CTL_TABLE_CPU_VARS(9);
-#endif
-#if NR_CPUS > 10
-	CTL_TABLE_CPU_VARS(10);
-#endif
-#if NR_CPUS > 11
-	CTL_TABLE_CPU_VARS(11);
-#endif
-#if NR_CPUS > 12
-	CTL_TABLE_CPU_VARS(12);
-#endif
-#if NR_CPUS > 13
-	CTL_TABLE_CPU_VARS(13);
-#endif
-#if NR_CPUS > 14
-	CTL_TABLE_CPU_VARS(14);
-#endif
-#if NR_CPUS > 15
-	CTL_TABLE_CPU_VARS(15);
-#endif
-#if NR_CPUS > 16
-	CTL_TABLE_CPU_VARS(16);
-#endif
-#if NR_CPUS > 17
-	CTL_TABLE_CPU_VARS(17);
-#endif
-#if NR_CPUS > 18
-	CTL_TABLE_CPU_VARS(18);
-#endif
-#if NR_CPUS > 19
-	CTL_TABLE_CPU_VARS(19);
-#endif
-#if NR_CPUS > 20
-	CTL_TABLE_CPU_VARS(20);
-#endif
-#if NR_CPUS > 21
-	CTL_TABLE_CPU_VARS(21);
-#endif
-#if NR_CPUS > 22
-	CTL_TABLE_CPU_VARS(22);
-#endif
-#if NR_CPUS > 23
-	CTL_TABLE_CPU_VARS(23);
-#endif
-#if NR_CPUS > 24
-	CTL_TABLE_CPU_VARS(24);
-#endif
-#if NR_CPUS > 25
-	CTL_TABLE_CPU_VARS(25);
-#endif
-#if NR_CPUS > 26
-	CTL_TABLE_CPU_VARS(26);
-#endif
-#if NR_CPUS > 27
-	CTL_TABLE_CPU_VARS(27);
-#endif
-#if NR_CPUS > 28
-	CTL_TABLE_CPU_VARS(28);
-#endif
-#if NR_CPUS > 29
-	CTL_TABLE_CPU_VARS(29);
-#endif
-#if NR_CPUS > 30
-	CTL_TABLE_CPU_VARS(30);
-#endif
-#if NR_CPUS > 31
-	CTL_TABLE_CPU_VARS(31);
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
-	CPU_ENUM(0),
-#if NR_CPUS > 1
-	CPU_ENUM(1),
-#endif
-#if NR_CPUS > 2
-	CPU_ENUM(2),
-#endif
-#if NR_CPUS > 3
-	CPU_ENUM(3),
-#endif
-#if NR_CPUS > 4
-	CPU_ENUM(4),
-#endif
-#if NR_CPUS > 5
-	CPU_ENUM(5),
-#endif
-#if NR_CPUS > 6
-	CPU_ENUM(6),
-#endif
-#if NR_CPUS > 7
-	CPU_ENUM(7),
-#endif
-#if NR_CPUS > 8
-	CPU_ENUM(8),
-#endif
-#if NR_CPUS > 9
-	CPU_ENUM(9),
-#endif
-#if NR_CPUS > 10
-	CPU_ENUM(10),
-#endif
-#if NR_CPUS > 11
-	CPU_ENUM(11),
-#endif
-#if NR_CPUS > 12
-	CPU_ENUM(12),
-#endif
-#if NR_CPUS > 13
-	CPU_ENUM(13),
-#endif
-#if NR_CPUS > 14
-	CPU_ENUM(14),
-#endif
-#if NR_CPUS > 15
-	CPU_ENUM(15),
-#endif
-#if NR_CPUS > 16
-	CPU_ENUM(16),
-#endif
-#if NR_CPUS > 17
-	CPU_ENUM(17),
-#endif
-#if NR_CPUS > 18
-	CPU_ENUM(18),
-#endif
-#if NR_CPUS > 19
-	CPU_ENUM(19),
-#endif
-#if NR_CPUS > 20
-	CPU_ENUM(20),
-#endif
-#if NR_CPUS > 21
-	CPU_ENUM(21),
-#endif
-#if NR_CPUS > 22
-	CPU_ENUM(22),
-#endif
-#if NR_CPUS > 23
-	CPU_ENUM(23),
-#endif
-#if NR_CPUS > 24
-	CPU_ENUM(24),
-#endif
-#if NR_CPUS > 25
-	CPU_ENUM(25),
-#endif
-#if NR_CPUS > 26
-	CPU_ENUM(26),
-#endif
-#if NR_CPUS > 27
-	CPU_ENUM(27),
-#endif
-#if NR_CPUS > 28
-	CPU_ENUM(28),
-#endif
-#if NR_CPUS > 29
-	CPU_ENUM(29),
-#endif
-#if NR_CPUS > 30
-	CPU_ENUM(30),
-#endif
-#if NR_CPUS > 31
-	CPU_ENUM(31),
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-	{
-		.ctl_name	= 0,
-	}
-};
-
-static ctl_table ctl_cpu[2] = {
-	{
-		.ctl_name	= CTL_CPU,
-		.procname	= "cpu",
-		.mode		= 0555,
-		.child		= ctl_cpu_table,
-	},
-	{
-		.ctl_name	= 0,
-	}
-};
-
-static struct ctl_table_header *cpufreq_sysctl_table;
-
-static inline void cpufreq_sysctl_init(void)
-{
-	cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
-}
-
-static inline void cpufreq_sysctl_exit(void)
-{
-	unregister_sysctl_table(cpufreq_sysctl_table);
-}
-
-#else
-#define cpufreq_sysctl_init() do {} while(0)
-#define cpufreq_sysctl_exit() do {} while(0)
-#endif /* CONFIG_CPU_FREQ_24API */
-
-
 /************************** sysfs interface ************************/
 static ssize_t show_speed (struct cpufreq_policy *policy, char *buf)
 {
@@ -503,7 +113,7 @@
 	if (ret != 1)
 		return -EINVAL;
 
-	_cpufreq_set(freq, policy->cpu);
+	cpufreq_set(freq, policy->cpu);
 
 	return count;
 }
@@ -577,7 +187,6 @@
 
 static int __init cpufreq_gov_userspace_init(void)
 {
-	cpufreq_sysctl_init();
 	cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 	return cpufreq_register_governor(&cpufreq_gov_userspace);
 }
@@ -587,7 +196,6 @@
 {
 	cpufreq_unregister_governor(&cpufreq_gov_userspace);
         cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-	cpufreq_sysctl_exit();
 }
 
 
diff -Nru a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
--- a/drivers/cpufreq/freq_table.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/cpufreq/freq_table.c	2005-01-19 13:44:47 -08:00
@@ -214,6 +214,11 @@
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
 
+struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
+{
+	return show_table[cpu];
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
 
 MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
diff -Nru a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c
--- a/drivers/cpufreq/proc_intf.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/cpufreq/proc_intf.c	2005-01-19 13:44:46 -08:00
@@ -1,263 +0,0 @@
-/*
- * linux/drivers/cpufreq/proc_intf.c
- *
- * Copyright (C) 2002 - 2003 Dominik Brodowski
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/ctype.h>
-#include <linux/proc_fs.h>
-#include <asm/uaccess.h>
-
-#warning This module will be removed from the 2.6. kernel series soon after 2005-01-01
-
-#define CPUFREQ_ALL_CPUS		((NR_CPUS))
-
-static unsigned int warning_print = 0;
-
-/**
- * cpufreq_parse_policy - parse a policy string
- * @input_string: the string to parse.
- * @policy: the policy written inside input_string
- *
- * This function parses a "policy string" - something the user echo'es into
- * /proc/cpufreq or gives as boot parameter - into a struct cpufreq_policy.
- * If there are invalid/missing entries, they are replaced with current
- * cpufreq policy.
- */
-static int cpufreq_parse_policy(char input_string[42], struct cpufreq_policy *policy)
-{
-	unsigned int            min = 0;
-	unsigned int            max = 0;
-	unsigned int            cpu = 0;
-	char			str_governor[16];
-	struct cpufreq_policy   current_policy;
-	unsigned int            result = -EFAULT;
-
-	if (!policy)
-		return -EINVAL;
-
-	policy->min = 0;
-	policy->max = 0;
-	policy->policy = 0;
-	policy->cpu = CPUFREQ_ALL_CPUS;
-
-	if (sscanf(input_string, "%d:%d:%d:%15s", &cpu, &min, &max, str_governor) == 4) 
-	{
-		policy->min = min;
-		policy->max = max;
-		policy->cpu = cpu;
-		result = 0;
-		goto scan_policy;
-	}
-	if (sscanf(input_string, "%d%%%d%%%d%%%15s", &cpu, &min, &max, str_governor) == 4)
-	{
-		if (!cpufreq_get_policy(&current_policy, cpu)) {
-			policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
-			policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
-			policy->cpu = cpu;
-			result = 0;
-			goto scan_policy;
-		}
-	}
-
-	if (sscanf(input_string, "%d:%d:%15s", &min, &max, str_governor) == 3) 
-	{
-		policy->min = min;
-		policy->max = max;
-		result = 0;
-		goto scan_policy;
-	}
-
-	if (sscanf(input_string, "%d%%%d%%%15s", &min, &max, str_governor) == 3)
-	{
-		if (!cpufreq_get_policy(&current_policy, cpu)) {
-			policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
-			policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
-			result = 0;
-			goto scan_policy;
-		}
-	}
-
-	return -EINVAL;
-
-scan_policy:
-	result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor);
-
-	return result;
-}
-
-/**
- * cpufreq_proc_read - read /proc/cpufreq
- *
- * This function prints out the current cpufreq policy.
- */
-static int cpufreq_proc_read (
-	char			*page,
-	char			**start,
-	off_t			off,
-	int 			count,
-	int 			*eof,
-	void			*data)
-{
-	char			*p = page;
-	int			len = 0;
-	struct cpufreq_policy   policy;
-	unsigned int            min_pctg = 0;
-	unsigned int            max_pctg = 0;
-	unsigned int            i = 0;
-
-	if (off != 0)
-		goto end;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/cpufreq is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	p += sprintf(p, "          minimum CPU frequency  -  maximum CPU frequency  -  policy\n");
-	for (i=0;i<NR_CPUS;i++) {
-		if (!cpu_online(i))
-			continue;
-
-		if (cpufreq_get_policy(&policy, i))
-			continue;
-
-		if (!policy.cpuinfo.max_freq)
-			continue;
-
-		min_pctg = (policy.min * 100) / policy.cpuinfo.max_freq;
-		max_pctg = (policy.max * 100) / policy.cpuinfo.max_freq;
-
-		p += sprintf(p, "CPU%3d    %9d kHz (%3d %%)  -  %9d kHz (%3d %%)  -  ",
-			     i , policy.min, min_pctg, policy.max, max_pctg);
-		if (policy.policy) {
-			switch (policy.policy) {
-				case CPUFREQ_POLICY_POWERSAVE:
-				p += sprintf(p, "powersave\n");
-				break;	
-			case CPUFREQ_POLICY_PERFORMANCE:
-				p += sprintf(p, "performance\n");
-				break;
-			default:
-				p += sprintf(p, "INVALID\n");
-				break;
-			} 
-		} else
-			p += scnprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
-	}
-end:
-	len = (p - page);
-	if (len <= off+count) 
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) 
-		len = count;
-	if (len<0) 
-		len = 0;
-
-	return len;
-}
-
-
-/**
- * cpufreq_proc_write - handles writing into /proc/cpufreq
- *
- * This function calls the parsing script and then sets the policy
- * accordingly.
- */
-static int cpufreq_proc_write (
-        struct file		*file,
-        const char		__user *buffer,
-        unsigned long		count,
-        void			*data)
-{
-	int                     result = 0;
-	char			proc_string[42] = {'\0'};
-	struct cpufreq_policy   policy;
-	unsigned int            i = 0;
-
-
-	if ((count > sizeof(proc_string) - 1))
-		return -EINVAL;
-	
-	if (copy_from_user(proc_string, buffer, count))
-		return -EFAULT;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/cpufreq is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-	
-	proc_string[count] = '\0';
-
-	result = cpufreq_parse_policy(proc_string, &policy);
-	if (result)
-		return -EFAULT;
-
-	if (policy.cpu == CPUFREQ_ALL_CPUS)
-	{
-		for (i=0; i<NR_CPUS; i++) 
-		{
-			policy.cpu = i;
-			if (cpu_online(i))
-				cpufreq_set_policy(&policy);
-		}
-	} 
-	else
-		cpufreq_set_policy(&policy);
-
-	return count;
-}
-
-
-/**
- * cpufreq_proc_init - add "cpufreq" to the /proc root directory
- *
- * This function adds "cpufreq" to the /proc root directory.
- */
-static int __init cpufreq_proc_init (void)
-{
-	struct proc_dir_entry *entry = NULL;
-
-	/* are these acceptable values? */
-	entry = create_proc_entry("cpufreq", S_IFREG|S_IRUGO|S_IWUSR, 
-				  &proc_root);
-
-	if (!entry) {
-		printk(KERN_ERR "unable to create /proc/cpufreq entry\n");
-		return -EIO;
-	} else {
-		entry->read_proc = cpufreq_proc_read;
-		entry->write_proc = cpufreq_proc_write;
-	}
-
-	return 0;
-}
-
-
-/**
- * cpufreq_proc_exit - removes "cpufreq" from the /proc root directory.
- *
- * This function removes "cpufreq" from the /proc root directory.
- */
-static void __exit cpufreq_proc_exit (void)
-{
-	remove_proc_entry("cpufreq", &proc_root);
-	return;
-}
-
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("CPUfreq /proc/cpufreq interface");
-MODULE_LICENSE ("GPL");
-
-module_init(cpufreq_proc_init);
-module_exit(cpufreq_proc_exit);
diff -Nru a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
--- a/drivers/firmware/Kconfig	2005-01-19 13:44:45 -08:00
+++ b/drivers/firmware/Kconfig	2005-01-19 13:44:45 -08:00
@@ -30,10 +30,10 @@
 	  Note that using this driver in concert with efibootmgr requires
 	  at least test release version 0.5.0-test3 or later, which is
 	  available from Matt Domsch's website located at:
-	  http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz
+	  <http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz>
 
 	  Subsequent efibootmgr releases may be found at:
-	  http://linux.dell.com/efibootmgr
+	  <http://linux.dell.com/efibootmgr>
 
 config EFI_PCDP
 	bool "Console device selection via EFI PCDP or HCDP table"
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/i2c/busses/Kconfig	2005-01-19 13:44:47 -08:00
@@ -112,6 +112,7 @@
 	    82801EB
 	    6300ESB
 	    ICH6
+	    ICH7
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
@@ -208,7 +209,7 @@
 
 config I2C_MPC
 	tristate "MPC107/824x/85xx/52xx"
-	depends on I2C && FSL_OCP
+	depends on I2C && PPC
 	help
 	  If you say yes to this option, support will be included for the
 	  built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
@@ -420,7 +421,7 @@
 	  especially for certain kinds of sensor chips.
 
 	  If you do build this module, be sure to read the notes and warnings
-	  in Documentation/i2c/i2c-stub.
+	  in <file:Documentation/i2c/i2c-stub>.
 
 	  If you don't know what to do here, definitely say N.
 
@@ -429,7 +430,6 @@
 	depends on I2C && PCI && EXPERIMENTAL
 	select I2C_ALGOBIT
 	help
-
 	  If you say yes to this option, support will be included for the VIA
           82C586B I2C interface
 
@@ -440,7 +440,6 @@
 	tristate "VIA 82C596/82C686/823x"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
-
 	  If you say yes to this option, support will be included for the VIA
 	  82C596/82C686/823x I2C interfaces.  Specifically, the following 
 	  chipsets are supported:
@@ -460,7 +459,6 @@
 	depends on I2C && PCI && EXPERIMENTAL
 	select I2C_ALGOBIT
 	help
-
 	  If you say yes to this option, support will be included for the
 	  Voodoo 3 I2C interface.
 
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/i2c/busses/i2c-i801.c	2005-01-19 13:44:46 -08:00
@@ -30,6 +30,7 @@
     82801EB		24D3   (HW PEC supported, 32 byte buffer not supported)
     6300ESB		25A4
     ICH6		266A
+    ICH7		27DA
     This driver supports several versions of Intel's I/O Controller Hubs (ICH).
     For SMBus support, they are similar to the PIIX4 and are part
     of Intel's '810' and other chipsets.
@@ -556,6 +557,7 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
 	{ 0, }
 };
 
diff -Nru a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
--- a/drivers/i2c/busses/i2c-mpc.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/i2c/busses/i2c-mpc.c	2005-01-19 13:44:46 -08:00
@@ -1,12 +1,12 @@
 /*
  * (C) Copyright 2003-2004
  * Humboldt Solutions Ltd, adrian@humboldt.co.uk.
- 
+
  * This is a combined i2c adapter and algorithm driver for the
  * MPC107/Tsi107 PowerPC northbridge and processors that include
- * the same I2C unit (8240, 8245, 85xx). 
+ * the same I2C unit (8240, 8245, 85xx).
  *
- * Release 0.6
+ * Release 0.8
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2. This program is licensed "as is" without any
@@ -20,7 +20,13 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <asm/io.h>
+#ifdef CONFIG_FSL_OCP
 #include <asm/ocp.h>
+#define FSL_I2C_DEV_SEPARATE_DFSRR FS_I2C_SEPARATE_DFSRR
+#define FSL_I2C_DEV_CLOCK_5200 FS_I2C_CLOCK_5200
+#else
+#include <linux/fsl_devices.h>
+#endif
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -50,10 +56,11 @@
 
 struct mpc_i2c {
 	char *base;
-	struct ocp_def *ocpdef;
 	u32 interrupt;
 	wait_queue_head_t queue;
 	struct i2c_adapter adap;
+	int irq;
+	u32 flags;
 };
 
 static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
@@ -75,12 +82,12 @@
 
 static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
 {
-	DECLARE_WAITQUEUE(wait, current);
 	unsigned long orig_jiffies = jiffies;
 	u32 x;
 	int result = 0;
 
-	if (i2c->ocpdef->irq == OCP_IRQ_NA) {
+	if (i2c->irq == 0)
+	{
 		while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
 			schedule();
 			if (time_after(jiffies, orig_jiffies + timeout)) {
@@ -92,28 +99,22 @@
 		x = readb(i2c->base + MPC_I2C_SR);
 		writeb(0, i2c->base + MPC_I2C_SR);
 	} else {
-		set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&i2c->queue, &wait);
-		while (!(i2c->interrupt & CSR_MIF)) {
-			if (signal_pending(current)) {
-				pr_debug("I2C: Interrupted\n");
-				result = -EINTR;
-				break;
-			}
-			if (time_after(jiffies, orig_jiffies + timeout)) {
-				pr_debug("I2C: timeout\n");
-				result = -EIO;
-				break;
-			}
-			msleep_interruptible(jiffies_to_msecs(timeout));
+		/* Interrupt mode */
+		result = wait_event_interruptible_timeout(i2c->queue,
+			(i2c->interrupt & CSR_MIF), timeout * HZ);
+
+		if (unlikely(result < 0))
+			pr_debug("I2C: wait interrupted\n");
+		else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
+			pr_debug("I2C: wait timeout\n");
+			result = -ETIMEDOUT;
 		}
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&i2c->queue, &wait);
+
 		x = i2c->interrupt;
 		i2c->interrupt = 0;
 	}
 
-	if (result < -0)
+	if (result < 0)
 		return result;
 
 	if (!(x & CSR_MCF)) {
@@ -137,12 +138,11 @@
 
 static void mpc_i2c_setclock(struct mpc_i2c *i2c)
 {
-	struct ocp_fs_i2c_data *i2c_data = i2c->ocpdef->additions;
 	/* Set clock and filters */
-	if (i2c_data && (i2c_data->flags & FS_I2C_SEPARATE_DFSRR)) {
+	if (i2c->flags & FSL_I2C_DEV_SEPARATE_DFSRR) {
 		writeb(0x31, i2c->base + MPC_I2C_FDR);
 		writeb(0x10, i2c->base + MPC_I2C_DFSRR);
-	} else if (i2c_data && (i2c_data->flags & FS_I2C_CLOCK_5200))
+	} else if (i2c->flags & FSL_I2C_DEV_CLOCK_5200)
 		writeb(0x3f, i2c->base + MPC_I2C_FDR);
 	else
 		writel(0x1031, i2c->base + MPC_I2C_FDR);
@@ -165,7 +165,7 @@
 		     const u8 * data, int length, int restart)
 {
 	int i;
-	unsigned timeout = HZ;
+	unsigned timeout = i2c->adap.timeout;
 	u32 flags = restart ? CCR_RSTA : 0;
 
 	/* Start with MEN */
@@ -193,7 +193,7 @@
 static int mpc_read(struct mpc_i2c *i2c, int target,
 		    u8 * data, int length, int restart)
 {
-	unsigned timeout = HZ;
+	unsigned timeout = i2c->adap.timeout;
 	int i;
 	u32 flags = restart ? CCR_RSTA : 0;
 
@@ -294,6 +294,7 @@
 	.retries = 1
 };
 
+#ifdef CONFIG_FSL_OCP
 static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
 {
 	int result = 0;
@@ -302,7 +303,10 @@
 	if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
 		return -ENOMEM;
 	}
-	i2c->ocpdef = ocp->def;
+	memset(i2c, 0, sizeof(*i2c));
+
+	i2c->irq = ocp->def->irq;
+	i2c->flags = ((struct ocp_fs_i2c_data *)ocp->def->additions)->flags;
 	init_waitqueue_head(&i2c->queue);
 
 	if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) {
@@ -318,16 +322,20 @@
 		goto fail_map;
 	}
 
-	if (ocp->def->irq != OCP_IRQ_NA)
+	if (i2c->irq != OCP_IRQ_NA)
+	{
 		if ((result = request_irq(ocp->def->irq, mpc_i2c_isr,
 					  0, "i2c-mpc", i2c)) < 0) {
 			printk(KERN_ERR
 			       "i2c-mpc - failed to attach interrupt\n");
 			goto fail_irq;
 		}
+	} else
+		i2c->irq = 0;
 
 	i2c->adap = mpc_ops;
 	i2c_set_adapdata(&i2c->adap, i2c);
+
 	if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
 		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
 		goto fail_add;
@@ -354,9 +362,9 @@
 	i2c_del_adapter(&i2c->adap);
 
 	if (ocp->def->irq != OCP_IRQ_NA)
-		free_irq(i2c->ocpdef->irq, i2c);
+		free_irq(i2c->irq, i2c);
 	iounmap(i2c->base);
-	release_mem_region(i2c->ocpdef->paddr, MPC_I2C_REGION);
+	release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
 	kfree(i2c);
 }
 
@@ -386,6 +394,101 @@
 
 module_init(iic_init);
 module_exit(iic_exit);
+#else
+static int fsl_i2c_probe(struct device *device)
+{
+	int result = 0;
+	struct mpc_i2c *i2c;
+	struct platform_device *pdev = to_platform_device(device);
+	struct fsl_i2c_platform_data *pdata;
+	struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
+
+	if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
+		return -ENOMEM;
+	}
+	memset(i2c, 0, sizeof(*i2c));
+
+	i2c->irq = platform_get_irq(pdev, 0);
+	i2c->flags = pdata->device_flags;
+	init_waitqueue_head(&i2c->queue);
+
+	i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
+
+	if (!i2c->base) {
+		printk(KERN_ERR "i2c-mpc - failed to map controller\n");
+		result = -ENOMEM;
+		goto fail_map;
+	}
+
+	if (i2c->irq != 0)
+		if ((result = request_irq(i2c->irq, mpc_i2c_isr,
+					  0, "fsl-i2c", i2c)) < 0) {
+			printk(KERN_ERR
+			       "i2c-mpc - failed to attach interrupt\n");
+			goto fail_irq;
+		}
+
+	i2c->adap = mpc_ops;
+	i2c_set_adapdata(&i2c->adap, i2c);
+	i2c->adap.dev.parent = &pdev->dev;
+	if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
+		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
+		goto fail_add;
+	}
+
+	mpc_i2c_setclock(i2c);
+	dev_set_drvdata(device, i2c);
+	return result;
+
+      fail_add:
+	if (i2c->irq != 0)
+		free_irq(i2c->irq, 0);
+      fail_irq:
+	iounmap(i2c->base);
+      fail_map:
+	kfree(i2c);
+	return result;
+};
+
+static int fsl_i2c_remove(struct device *device)
+{
+	struct mpc_i2c *i2c = dev_get_drvdata(device);
+
+	dev_set_drvdata(device, NULL);
+	i2c_del_adapter(&i2c->adap);
+
+	if (i2c->irq != 0)
+		free_irq(i2c->irq, i2c);
+
+	iounmap(i2c->base);
+	kfree(i2c);
+	return 0;
+};
+
+/* Structure for a device driver */
+static struct device_driver fsl_i2c_driver = {
+	.name = "fsl-i2c",
+	.bus = &platform_bus_type,
+	.probe = fsl_i2c_probe,
+	.remove = fsl_i2c_remove,
+};
+
+static int __init fsl_i2c_init(void)
+{
+	return driver_register(&fsl_i2c_driver);
+}
+
+static void __exit fsl_i2c_exit(void)
+{
+	driver_unregister(&fsl_i2c_driver);
+}
+
+module_init(fsl_i2c_init);
+module_exit(fsl_i2c_exit);
+
+#endif /* CONFIG_FSL_OCP */
 
 MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
 MODULE_DESCRIPTION
diff -Nru a/drivers/i2c/chips/adm1026.c b/drivers/i2c/chips/adm1026.c
--- a/drivers/i2c/chips/adm1026.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/i2c/chips/adm1026.c	2005-01-19 13:44:46 -08:00
@@ -452,6 +452,14 @@
 		client->id, value);
 	data->config1 = value;
 	adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
+
+	/* initialize fan_div[] to hardware defaults */
+	value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
+		(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
+	for (i = 0;i <= 7;++i) {
+		data->fan_div[i] = DIV_FROM_REG(value & 0x03);
+		value >>= 2;
+	}
 }
 
 void adm1026_print_gpio(struct i2c_client *client)
@@ -459,8 +467,7 @@
 	struct adm1026_data *data = i2c_get_clientdata(client);
 	int  i;
 
-	dev_dbg(&client->dev, "(%d): GPIO config is:",
-			    client->id);
+	dev_dbg(&client->dev, "(%d): GPIO config is:", client->id);
 	for (i = 0;i <= 7;++i) {
 		if (data->config2 & (1 << i)) {
 			dev_dbg(&client->dev, "\t(%d): %sGP%s%d\n", client->id,
diff -Nru a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
--- a/drivers/i2c/chips/eeprom.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/i2c/chips/eeprom.c	2005-01-19 13:44:46 -08:00
@@ -78,8 +78,6 @@
 	.detach_client	= eeprom_detach_client,
 };
 
-static int eeprom_id;
-
 static void eeprom_update_client(struct i2c_client *client, u8 slice)
 {
 	struct eeprom_data *data = i2c_get_clientdata(client);
@@ -165,16 +163,14 @@
 	struct eeprom_data *data;
 	int err = 0;
 
-	/* Make sure we aren't probing the ISA bus!! This is just a safety check
-	   at this moment; i2c_detect really won't call us. */
-#ifdef DEBUG
-	if (i2c_is_isa_adapter(adapter)) {
-		dev_dbg(&adapter->dev, " eeprom_detect called for an ISA bus adapter?!?\n");
-		return 0;
-	}
-#endif
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+	/* There are three ways we can read the EEPROM data:
+	   (1) I2C block reads (faster, but unsupported by most adapters)
+	   (2) Consecutive byte reads (100% overhead)
+	   (3) Regular byte data reads (200% overhead)
+	   The third method is not implemented by this driver because all
+	   known adapters support at least the second. */
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA
+					    | I2C_FUNC_SMBUS_BYTE))
 		goto exit;
 
 	/* OK. For now, we presume we have a valid client. We now create the
@@ -197,26 +193,27 @@
 	/* prevent 24RF08 corruption */
 	i2c_smbus_write_quick(new_client, 0);
 
-	data->nature = UNKNOWN;
-	/* Detect the Vaio nature of EEPROMs.
-	   We use the "PCG-" prefix as the signature. */
-	if (address == 0x57) {
-		if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P' && 
-		    i2c_smbus_read_byte_data(new_client, 0x81) == 'C' && 
-		    i2c_smbus_read_byte_data(new_client, 0x82) == 'G' &&
-		    i2c_smbus_read_byte_data(new_client, 0x83) == '-')
-			data->nature = VAIO;
-	}
-
 	/* Fill in the remaining client fields */
-	strncpy(new_client->name, "eeprom", I2C_NAME_SIZE);
-	new_client->id = eeprom_id++;
+	strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
 	data->valid = 0;
 	init_MUTEX(&data->update_lock);
+	data->nature = UNKNOWN;
 
 	/* Tell the I2C layer a new client has arrived */
 	if ((err = i2c_attach_client(new_client)))
 		goto exit_kfree;
+
+	/* Detect the Vaio nature of EEPROMs.
+	   We use the "PCG-" prefix as the signature. */
+	if (address == 0x57) {
+		if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
+		 && i2c_smbus_read_byte(new_client) == 'C'
+		 && i2c_smbus_read_byte(new_client) == 'G'
+		 && i2c_smbus_read_byte(new_client) == '-')
+			dev_info(&new_client->dev, "Vaio EEPROM detected, "
+				"enabling password protection\n");
+			data->nature = VAIO;
+	}
 
 	/* create the sysfs eeprom file */
 	sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/i2c/chips/it87.c	2005-01-19 13:44:47 -08:00
@@ -56,6 +56,7 @@
 #define	VAL	0x2f	/* The value to read/write */
 #define PME	0x04	/* The device with the fan registers in it */
 #define	DEVID	0x20	/* Register: Device ID */
+#define	DEVREV	0x22	/* Register: Device Revision */
 
 static inline int
 superio_inb(int reg)
@@ -64,6 +65,16 @@
 	return inb(VAL);
 }
 
+static int superio_inw(int reg)
+{
+	int val;
+	outb(reg++, REG);
+	val = inb(VAL) << 8;
+	outb(reg, REG);
+	val |= inb(VAL);
+	return val;
+}
+
 static inline void
 superio_select(void)
 {
@@ -87,18 +98,14 @@
 	outb(0x02, VAL);
 }
 
-/* just IT8712F for now - this should be extended to support the other
-   chips as well */
 #define IT8712F_DEVID 0x8712
+#define IT8705F_DEVID 0x8705
 #define IT87_ACT_REG  0x30
 #define IT87_BASE_REG 0x60
 
 /* Update battery voltage after every reading if true */
 static int update_vbat;
 
-/* Reset the registers on init if true */
-static int reset;
-
 /* Chip Type */
 
 static u16 chip_type;
@@ -128,6 +135,8 @@
 #define IT87_REG_FAN(nr)       (0x0d + (nr))
 #define IT87_REG_FAN_MIN(nr)   (0x10 + (nr))
 #define IT87_REG_FAN_MAIN_CTRL 0x13
+#define IT87_REG_FAN_CTL       0x14
+#define IT87_REG_PWM(nr)       (0x15 + (nr))
 
 #define IT87_REG_VIN(nr)       (0x20 + (nr))
 #define IT87_REG_TEMP(nr)      (0x29 + (nr))
@@ -164,6 +173,9 @@
 
 #define ALARMS_FROM_REG(val) (val)
 
+#define PWM_TO_REG(val)   ((val) >> 1)
+#define PWM_FROM_REG(val) (((val)&0x7f) << 1)
+
 static int DIV_TO_REG(int val)
 {
 	int answer = 0;
@@ -200,6 +212,8 @@
 	u8 vid;			/* Register encoding, combined */
 	int vrm;
 	u32 alarms;		/* Register encoding, combined */
+	u8 fan_main_ctrl;	/* Register value */
+	u8 manual_pwm_ctl[3];   /* manual PWM value set by user */
 };
 
 
@@ -224,8 +238,6 @@
 	.detach_client	= it87_detach_client,
 };
 
-static int it87_id;
-
 static ssize_t show_in(struct device *dev, char *buf, int nr)
 {
 	struct it87_data *data = it87_update_device(dev);
@@ -440,18 +452,28 @@
 {
 	struct it87_data *data = it87_update_device(dev);
 	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr], 
-				DIV_FROM_REG(data->fan_div[nr])) );
+				DIV_FROM_REG(data->fan_div[nr])));
 }
 static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
 {
 	struct it87_data *data = it87_update_device(dev);
 	return sprintf(buf,"%d\n",
-		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
+		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])));
 }
 static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
 {
 	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
+}
+static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr)
+{
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf,"%d\n", (data->fan_main_ctrl & (1 << nr)) ? 1 : 0);
+}
+static ssize_t show_pwm(struct device *dev, char *buf, int nr)
+{
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]);
 }
 static ssize_t set_fan_min(struct device *dev, const char *buf, 
 		size_t count, int nr)
@@ -486,7 +508,7 @@
 		else
 			data->fan_div[nr] = 3;
 	}
-	val = old & 0x100;
+	val = old & 0x80;
 	val |= (data->fan_div[0] & 0x07);
 	val |= (data->fan_div[1] & 0x07) << 3;
 	if (data->fan_div[2] == 3)
@@ -499,6 +521,48 @@
 	}
 	return count;
 }
+static ssize_t set_pwm_enable(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	if (val == 0) {
+		int tmp;
+		/* make sure the fan is on when in on/off mode */
+		tmp = it87_read_value(client, IT87_REG_FAN_CTL);
+		it87_write_value(client, IT87_REG_FAN_CTL, tmp | (1 << nr));
+		/* set on/off mode */
+		data->fan_main_ctrl &= ~(1 << nr);
+		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
+	} else if (val == 1) {
+		/* set SmartGuardian mode */
+		data->fan_main_ctrl |= (1 << nr);
+		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
+		/* set saved pwm value, clear FAN_CTLX PWM mode bit */
+		it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
+	} else
+		return -EINVAL;
+
+	return count;
+}
+static ssize_t set_pwm(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	if (val < 0 || val > 255)
+		return -EINVAL;
+
+	data->manual_pwm_ctl[nr] = val;
+	if (data->fan_main_ctrl & (1 << nr))
+		it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
+
+	return count;
+}
 
 #define show_fan_offset(offset)						\
 static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
@@ -533,6 +597,36 @@
 show_fan_offset(2);
 show_fan_offset(3);
 
+#define show_pwm_offset(offset)						\
+static ssize_t show_pwm##offset##_enable (struct device *dev,		\
+	char *buf)							\
+{									\
+	return show_pwm_enable(dev, buf, offset - 1);			\
+}									\
+static ssize_t show_pwm##offset (struct device *dev, char *buf)		\
+{									\
+	return show_pwm(dev, buf, offset - 1);				\
+}									\
+static ssize_t set_pwm##offset##_enable (struct device *dev,		\
+		const char *buf, size_t count)				\
+{									\
+	return set_pwm_enable(dev, buf, count, offset - 1);		\
+}									\
+static ssize_t set_pwm##offset (struct device *dev,			\
+		const char *buf, size_t count)				\
+{									\
+	return set_pwm(dev, buf, count, offset - 1);			\
+}									\
+static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,		\
+		show_pwm##offset##_enable,				\
+		set_pwm##offset##_enable);				\
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,			\
+		show_pwm##offset , set_pwm##offset );
+
+show_pwm_offset(1);
+show_pwm_offset(2);
+show_pwm_offset(3);
+
 /* Alarms */
 static ssize_t show_alarms(struct device *dev, char *buf)
 {
@@ -587,25 +681,33 @@
 /* SuperIO detection - will change normal_isa[0] if a chip is found */
 static int it87_find(int *address)
 {
-	u16 val;
+	int err = -ENODEV;
 
 	superio_enter();
-	chip_type = (superio_inb(DEVID) << 8) |
-	       superio_inb(DEVID + 1);
-	if (chip_type != IT8712F_DEVID) {
-		superio_exit();
-		return -ENODEV;
-	}
+	chip_type = superio_inw(DEVID);
+	if (chip_type != IT8712F_DEVID
+	 && chip_type != IT8705F_DEVID)
+	 	goto exit;
 
 	superio_select();
-	val = (superio_inb(IT87_BASE_REG) << 8) |
-	       superio_inb(IT87_BASE_REG + 1);
-	superio_exit();
-	*address = val & ~(IT87_EXTENT - 1);
+	if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
+		pr_info("it87: Device not activated, skipping\n");
+		goto exit;
+	}
+
+	*address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1);
 	if (*address == 0) {
-		return -ENODEV;
+		pr_info("it87: Base address not set, skipping\n");
+		goto exit;
 	}
-	return 0;
+
+	err = 0;
+	pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
+		chip_type, *address, superio_inb(DEVREV) & 0x0f);
+
+exit:
+	superio_exit();
+	return err;
 }
 
 /* This function is called by i2c_detect */
@@ -617,6 +719,8 @@
 	int err = 0;
 	const char *name = "";
 	int is_isa = i2c_is_isa_adapter(adapter);
+	int enable_pwm_interface;
+	int tmp;
 
 	if (!is_isa && 
 	    !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -712,10 +816,7 @@
 
 	/* Fill in the remaining client fields and put it into the global list */
 	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-
 	data->type = kind;
-
-	new_client->id = it87_id++;
 	data->valid = 0;
 	init_MUTEX(&data->update_lock);
 
@@ -726,6 +827,17 @@
 	/* Initialize the IT87 chip */
 	it87_init_client(new_client, data);
 
+	/* Some BIOSes fail to correctly configure the IT87 fans. All fans off
+	 * and polarity set to active low is sign that this is the case so we
+	 * disable pwm control to protect the user. */
+	enable_pwm_interface = 1;
+	tmp = it87_read_value(new_client, IT87_REG_FAN_CTL);
+	if ((tmp & 0x87) == 0) {
+		enable_pwm_interface = 0;
+		dev_info(&new_client->dev,
+			"detected broken BIOS defaults, disabling pwm interface");
+	}
+
 	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_in0_input);
 	device_create_file(&new_client->dev, &dev_attr_in1_input);
@@ -774,6 +886,14 @@
 	device_create_file(&new_client->dev, &dev_attr_fan2_div);
 	device_create_file(&new_client->dev, &dev_attr_fan3_div);
 	device_create_file(&new_client->dev, &dev_attr_alarms);
+	if (enable_pwm_interface) {
+		device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
+		device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
+		device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
+		device_create_file(&new_client->dev, &dev_attr_pwm1);
+		device_create_file(&new_client->dev, &dev_attr_pwm2);
+		device_create_file(&new_client->dev, &dev_attr_pwm3);
+	}
 
 	if (data->type == it8712) {
 		device_create_file_vrm(new_client);
@@ -851,12 +971,17 @@
 /* Called when we have found a new IT87. */
 static void it87_init_client(struct i2c_client *client, struct it87_data *data)
 {
-	int tmp;
+	int tmp, i;
 
-	if (reset) {
-		/* Reset all except Watchdog values and last conversion values
-		   This sets fan-divs to 2, among others */
-		it87_write_value(client, IT87_REG_CONFIG, 0x80);
+	/* initialize to sane defaults:
+	 * - if the chip is in manual pwm mode, this will be overwritten with
+	 *   the actual settings on the chip (so in this case, initialization
+	 *   is not needed)
+	 * - if in automatic or on/off mode, we could switch to manual mode,
+	 *   read the registers and set manual_pwm_ctl accordingly, but currently
+	 *   this is not implemented, so we initialize to something sane */
+	for (i = 0; i < 3; i++) {
+		data->manual_pwm_ctl[i] = 0xff;
 	}
 
 	/* Check if temperature channnels are reset manually or by some reason */
@@ -876,13 +1001,31 @@
 	}
 
 	/* Check if tachometers are reset manually or by some reason */
-	tmp = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
-	if ((tmp & 0x70) == 0) {
+	data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
+	if ((data->fan_main_ctrl & 0x70) == 0) {
 		/* Enable all fan tachometers */
-		tmp = (tmp & 0x8f) | 0x70;
-		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, tmp);
+		data->fan_main_ctrl |= 0x70;
+		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
 	}
 
+	/* Set current fan mode registers and the default settings for the
+	 * other mode registers */
+	for (i = 0; i < 3; i++) {
+		if (data->fan_main_ctrl & (1 << i)) {
+			/* pwm mode */
+			tmp = it87_read_value(client, IT87_REG_PWM(i));
+			if (tmp & 0x80) {
+				/* automatic pwm - not yet implemented, but
+				 * leave the settings made by the BIOS alone
+				 * until a change is requested via the sysfs
+				 * interface */
+			} else {
+				/* manual pwm */
+				data->manual_pwm_ctl[i] = PWM_FROM_REG(tmp);
+			}
+		}
+ 	}
+
 	/* Start monitoring */
 	it87_write_value(client, IT87_REG_CONFIG,
 			 (it87_read_value(client, IT87_REG_CONFIG) & 0x36)
@@ -948,6 +1091,7 @@
 			it87_read_value(client, IT87_REG_ALARM1) |
 			(it87_read_value(client, IT87_REG_ALARM2) << 8) |
 			(it87_read_value(client, IT87_REG_ALARM3) << 16);
+		data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
 
 		data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE);
 		/* The 8705 does not have VID capability */
@@ -984,8 +1128,6 @@
 MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver");
 module_param(update_vbat, bool, 0);
 MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
-module_param(reset, bool, 0);
-MODULE_PARM_DESC(reset, "Reset the chip's registers, default no");
 MODULE_LICENSE("GPL");
 
 module_init(sm_it87_init);
diff -Nru a/drivers/i2c/chips/lm63.c b/drivers/i2c/chips/lm63.c
--- a/drivers/i2c/chips/lm63.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/i2c/chips/lm63.c	2005-01-19 13:44:48 -08:00
@@ -464,8 +464,8 @@
 		(data->config & 0x04) ? "tachometer input" :
 		"alert output");
 	dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
-		(data->config_fan & 0x04) ? "1.4" : "360",
-		((data->config_fan & 0x04) ? 700 : 180000) / data->pwm1_freq);
+		(data->config_fan & 0x08) ? "1.4" : "360",
+		((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
 	dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
 		(data->config_fan & 0x10) ? "low" : "high",
 		(data->config_fan & 0x20) ? "manual" : "auto");
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/i2c/chips/lm85.c	2005-01-19 13:44:46 -08:00
@@ -36,7 +36,7 @@
 static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
 
 /* Insmod parameters */
-SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
+SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);
 
 /* The LM85 registers */
 
@@ -66,11 +66,15 @@
 #define	LM85_DEVICE_ADX			0x27
 #define	LM85_COMPANY_NATIONAL		0x01
 #define	LM85_COMPANY_ANALOG_DEV		0x41
+#define	LM85_COMPANY_SMSC      		0x5c
+#define	LM85_VERSTEP_VMASK              0xf0
 #define	LM85_VERSTEP_GENERIC		0x60
 #define	LM85_VERSTEP_LM85C		0x60
 #define	LM85_VERSTEP_LM85B		0x62
 #define	LM85_VERSTEP_ADM1027		0x60
 #define	LM85_VERSTEP_ADT7463		0x62
+#define	LM85_VERSTEP_EMC6D100_A0        0x60
+#define	LM85_VERSTEP_EMC6D100_A1        0x61
 
 #define	LM85_REG_CONFIG			0x40
 
@@ -105,6 +109,12 @@
 #define	ADT7463_REG_THERM		0x79
 #define	ADT7463_REG_THERM_LIMIT		0x7A
 
+#define EMC6D100_REG_ALARM3             0x7d
+/* IN5, IN6 and IN7 */
+#define EMC6D100_REG_IN(nr)             (0x70 + ((nr)-5))
+#define EMC6D100_REG_IN_MIN(nr)         (0x73 + ((nr)-5) * 2)
+#define EMC6D100_REG_IN_MAX(nr)         (0x74 + ((nr)-5) * 2)
+
 #define	LM85_ALARM_IN0			0x0001
 #define	LM85_ALARM_IN1			0x0002
 #define	LM85_ALARM_IN2			0x0004
@@ -135,7 +145,8 @@
 
 /* IN are scaled acording to built-in resistors */
 static int lm85_scaling[] = {  /* .001 Volts */
-		2500, 2250, 3300, 5000, 12000
+		2500, 2250, 3300, 5000, 12000,
+		3300, 1500, 1800 /*EMC6D100*/
 	};
 #define SCALE(val,from,to)		(((val)*(to) + ((from)/2))/(from))
 #define INS_TO_REG(n,val)		(SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255))
@@ -331,9 +342,9 @@
 	unsigned long last_reading;	/* In jiffies */
 	unsigned long last_config;	/* In jiffies */
 
-	u8 in[5];		/* Register value */
-	u8 in_max[5];		/* Register value */
-	u8 in_min[5];		/* Register value */
+	u8 in[8];		/* Register value */
+	u8 in_max[8];		/* Register value */
+	u8 in_min[8];		/* Register value */
 	s8 temp[3];		/* Register value */
 	s8 temp_min[3];		/* Register value */
 	s8 temp_max[3];		/* Register value */
@@ -353,7 +364,7 @@
 	u16 tmin_ctl;		/* Register value */
 	unsigned long therm_total; /* Cummulative therm count */
 	u8 therm_limit;		/* Register value */
-	u16 alarms;		/* Register encoding, combined */
+	u32 alarms;		/* Register encoding, combined */
 	struct lm85_autofan autofan[3];
 	struct lm85_zone zone[3];
 };
@@ -1072,7 +1083,7 @@
 		    && verstep == LM85_VERSTEP_LM85B ) {
 			kind = lm85b ;
 		} else if( company == LM85_COMPANY_NATIONAL
-		    && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
 			dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
 				" Defaulting to LM85.\n", verstep);
 			kind = any_chip ;
@@ -1083,17 +1094,34 @@
 		    && verstep == LM85_VERSTEP_ADT7463 ) {
 			kind = adt7463 ;
 		} else if( company == LM85_COMPANY_ANALOG_DEV
-		    && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
 			dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
-				" Defaulting to ADM1027.\n", verstep);
-			kind = adm1027 ;
-		} else if( kind == 0 && (verstep & 0xf0) == 0x60) {
+				" Defaulting to Generic LM85.\n", verstep );
+			kind = any_chip ;
+		} else if( company == LM85_COMPANY_SMSC
+		    && (verstep == LM85_VERSTEP_EMC6D100_A0
+			 || verstep == LM85_VERSTEP_EMC6D100_A1) ) {
+			/* Unfortunately, we can't tell a '100 from a '101
+			 * from the registers.  Since a '101 is a '100
+			 * in a package with fewer pins and therefore no
+			 * 3.3V, 1.5V or 1.8V inputs, perhaps if those
+			 * inputs read 0, then it's a '101.
+			 */
+			kind = emc6d100 ;
+		} else if( company == LM85_COMPANY_SMSC
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
+			dev_err(&adapter->dev, "lm85: Detected SMSC chip\n");
+			dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x"
+			    " Defaulting to Generic LM85.\n", verstep );
+			kind = any_chip ;
+		} else if( kind == any_chip
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
 			dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n");
 			/* Leave kind as "any_chip" */
 		} else {
 			dev_dbg(&adapter->dev, "Autodetection failed\n");
 			/* Not an LM85 ... */
-			if( kind == 0 ) {  /* User used force=x,y */
+			if( kind == any_chip ) {  /* User used force=x,y */
 				dev_err(&adapter->dev, "Generic LM85 Version 6 not"
 					" found at %d,0x%02x. Try force_lm85c.\n",
 					i2c_adapter_id(adapter), address );
@@ -1114,6 +1142,8 @@
 		type_name = "adm1027";
 	} else if ( kind == adt7463 ) {
 		type_name = "adt7463";
+	} else if ( kind == emc6d100){
+		type_name = "emc6d100";
 	}
 	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
 
@@ -1365,15 +1395,24 @@
 			    lm85_read_value(client, LM85_REG_PWM(i));
 		}
 
+		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
+
 		if ( data->type == adt7463 ) {
 			if( data->therm_total < ULONG_MAX - 256 ) {
 			    data->therm_total +=
 				lm85_read_value(client, ADT7463_REG_THERM );
 			}
+		} else if ( data->type == emc6d100 ) {
+			/* Three more voltage sensors */
+			for (i = 5; i <= 7; ++i) {
+				data->in[i] =
+					lm85_read_value(client, EMC6D100_REG_IN(i));
+			}
+			/* More alarm bits */
+			data->alarms |=
+				lm85_read_value(client, EMC6D100_REG_ALARM3) << 16;
 		}
 
-		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
-
 		data->last_reading = jiffies ;
 	};  /* last_reading */
 
@@ -1387,6 +1426,15 @@
 			    lm85_read_value(client, LM85_REG_IN_MIN(i));
 			data->in_max[i] =
 			    lm85_read_value(client, LM85_REG_IN_MAX(i));
+		}
+
+		if ( data->type == emc6d100 ) {
+			for (i = 5; i <= 7; ++i) {
+				data->in_min[i] =
+					lm85_read_value(client, EMC6D100_REG_IN_MIN(i));
+				data->in_max[i] =
+					lm85_read_value(client, EMC6D100_REG_IN_MAX(i));
+			}
 		}
 
 		for (i = 0; i <= 3; ++i) {
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/i2c/chips/via686a.c	2005-01-19 13:44:46 -08:00
@@ -786,14 +786,11 @@
 }
 
 static struct pci_device_id via686a_pci_ids[] = {
-       {
-	       .vendor 		= PCI_VENDOR_ID_VIA, 
-	       .device 		= PCI_DEVICE_ID_VIA_82C686_4, 
-	       .subvendor	= PCI_ANY_ID, 
-	       .subdevice	= PCI_ANY_ID, 
-       },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
        { 0, }
 };
+
+MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
 
 static int __devinit via686a_pci_probe(struct pci_dev *dev,
                                       const struct pci_device_id *id)
diff -Nru a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
--- a/drivers/ide/arm/icside.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/ide/arm/icside.c	2005-01-19 13:44:46 -08:00
@@ -397,35 +397,6 @@
 	enable_dma(hwif->hw.dma);
 }
 
-/*
- * dma_intr() is the handler for disk read/write DMA interrupts
- */
-static ide_startstop_t icside_dmaintr(ide_drive_t *drive)
-{
-	unsigned int stat;
-	int dma_stat;
-
-	dma_stat = icside_dma_end(drive);
-	stat = HWIF(drive)->INB(IDE_STATUS_REG);
-	if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
-		if (!dma_stat) {
-			struct request *rq = HWGROUP(drive)->rq;
-			int i;
-
-			for (i = rq->nr_sectors; i > 0; ) {
-				i -= rq->current_nr_sectors;
-				DRIVER(drive)->end_request(drive, 1, rq->nr_sectors);
-			}
-
-			return ide_stopped;
-		}
-		printk(KERN_ERR "%s: bad DMA status (dma_stat=%x)\n",
-		       drive->name, dma_stat);
-	}
-
-	return ide_error(drive, __FUNCTION__, stat);
-}
-
 static int icside_dma_setup(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
@@ -474,7 +445,7 @@
 static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
 {
 	/* issue cmd to drive */
-	ide_execute_command(drive, cmd, icside_dmaintr, 2*WAIT_CMD, NULL);
+	ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL);
 }
 
 static int icside_dma_test_irq(ide_drive_t *drive)
diff -Nru a/drivers/ide/cris/ide-v10.c b/drivers/ide/cris/ide-v10.c
--- a/drivers/ide/cris/ide-v10.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/ide/cris/ide-v10.c	2005-01-19 13:44:46 -08:00
@@ -753,27 +753,10 @@
  */
 static ide_startstop_t etrax_dma_intr (ide_drive_t *drive)
 {
-	int i, dma_stat;
-	byte stat;
-
 	LED_DISK_READ(0);
 	LED_DISK_WRITE(0);
 
-	dma_stat = HWIF(drive)->ide_dma_end(drive);
-	stat = HWIF(drive)->INB(IDE_STATUS_REG);		/* get drive status */
-	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
-		if (!dma_stat) {
-			struct request *rq;
-			rq = HWGROUP(drive)->rq;
-			for (i = rq->nr_sectors; i > 0;) {
-				i -= rq->current_nr_sectors;
-				DRIVER(drive)->end_request(drive, 1, rq->nr_sectors);
-			}
-			return ide_stopped;
-		}
-		printk("%s: bad DMA status\n", drive->name);
-	}
-	return ide_error(drive, "dma_intr", stat);
+	return ide_dma_intr(drive);
 }
 
 /*
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/ide/ide-cd.c	2005-01-19 13:44:46 -08:00
@@ -1464,19 +1464,6 @@
 }
 
 
-/* Sleep for TIME jiffies.
-   Not to be called from an interrupt handler. */
-static
-void cdrom_sleep (int time)
-{
-	int sleep = time;
-
-	do {
-		set_current_state(TASK_INTERRUPTIBLE);
-		sleep = schedule_timeout(sleep);
-	} while (sleep);
-}
-
 static
 int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
 {
@@ -1511,7 +1498,7 @@
 				/* The drive is in the process of loading
 				   a disk.  Retry, but wait a little to give
 				   the drive time to complete the load. */
-				cdrom_sleep(2 * HZ);
+				ssleep(2);
 			} else {
 				/* Otherwise, don't retry. */
 				retries = 0;
diff -Nru a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c
--- a/drivers/ide/ide-default.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/ide/ide-default.c	2005-01-19 13:44:48 -08:00
@@ -46,6 +46,7 @@
 	.name		=	"ide-default",
 	.version	=	IDEDEFAULT_VERSION,
 	.attach		=	idedefault_attach,
+	.cleanup	=	ide_unregister_subdriver,
 	.drives		=	LIST_HEAD_INIT(idedefault_driver.drives)
 };
 
diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
--- a/drivers/ide/ide-dma.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/ide/ide-dma.c	2005-01-19 13:44:46 -08:00
@@ -158,7 +158,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *	ide_dma_intr	-	IDE DMA interrupt handler
  *	@drive: the drive the interrupt is for
@@ -188,6 +187,7 @@
 
 EXPORT_SYMBOL_GPL(ide_dma_intr);
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *	ide_build_sglist	-	map IDE scatter gather for DMA I/O
  *	@drive: the drive to build the DMA table for
diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
--- a/drivers/ide/ide-io.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/ide/ide-io.c	2005-01-19 13:44:47 -08:00
@@ -437,7 +437,7 @@
  *	by read a sector's worth of data from the drive.  Of course,
  *	this may not help if the drive is *waiting* for data from *us*.
  */
-void try_to_flush_leftover_data (ide_drive_t *drive)
+static void try_to_flush_leftover_data (ide_drive_t *drive)
 {
 	int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
 
@@ -452,8 +452,6 @@
 	}
 }
 
-EXPORT_SYMBOL(try_to_flush_leftover_data);
-
 static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
 {
 	ide_hwif_t *hwif = drive->hwif;
@@ -853,13 +851,6 @@
 	if (drive->max_failures && (drive->failures > drive->max_failures)) {
 		goto kill_rq;
 	}
-
-	/*
-	 * bail early if we've sent a device to sleep, however how to wake
-	 * this needs to be a masked flag.  FIXME for proper operations.
-	 */
-	if (drive->suspend_reset)
-		goto kill_rq;
 
 	block    = rq->sector;
 	if (blk_fs_request(rq) &&
diff -Nru a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
--- a/drivers/ide/ide-lib.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/ide/ide-lib.c	2005-01-19 13:44:47 -08:00
@@ -571,8 +571,7 @@
 
 	status.all = stat;
 	local_irq_set(flags);
-	printk("%s: %s: status=0x%02x", drive->name, msg, stat);
-	printk(" { ");
+	printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
 	if (status.b.bsy)
 		printk("Busy ");
 	else {
@@ -584,18 +583,17 @@
 		if (status.b.idx)	printk("Index ");
 		if (status.b.check)	printk("Error ");
 	}
-	printk("}");
-	printk("\n");
+	printk("}\n");
 	if ((status.all & (status.b.bsy|status.b.check)) == status.b.check) {
 		error.all = HWIF(drive)->INB(IDE_ERROR_REG);
-		printk("%s: %s: error=0x%02x", drive->name, msg, error.all);
+		printk("%s: %s: error=0x%02x { ", drive->name, msg, error.all);
 		if (error.b.ili)	printk("IllegalLengthIndication ");
 		if (error.b.eom)	printk("EndOfMedia ");
-		if (error.b.abrt)	printk("Aborted Command ");
+		if (error.b.abrt)	printk("AbortedCommand ");
 		if (error.b.mcr)	printk("MediaChangeRequested ");
-		if (error.b.sense_key)	printk("LastFailedSense 0x%02x ",
+		if (error.b.sense_key)	printk("LastFailedSense=0x%02x ",
 						error.b.sense_key);
-		printk("\n");
+		printk("}\n");
 	}
 	ide_dump_opcode(drive);
 	local_irq_restore(flags);
diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
--- a/drivers/ide/ide-probe.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/ide/ide-probe.c	2005-01-19 13:44:47 -08:00
@@ -749,7 +749,7 @@
 	 *  
 	 *  BenH.
 	 */
-	if (wait_hwif_ready(hwif))
+	if (wait_hwif_ready(hwif) == -EBUSY)
 		printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
 
 	/*
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/ide/ide.c	2005-01-19 13:44:46 -08:00
@@ -1554,18 +1554,7 @@
 			HWGROUP(drive)->busy = 1;
 			spin_unlock_irqrestore(&ide_lock, flags);
 			(void) ide_do_reset(drive);
-			if (drive->suspend_reset) {
-/*
- *				APM WAKE UP todo !!
- *				int nogoodpower = 1;
- *				while(nogoodpower) {
- *					check_power1() or check_power2()
- *					nogoodpower = 0;
- *				} 
- *				HWIF(drive)->multiproc(drive);
- */
-				return ioctl_by_bdev(bdev, BLKRRPART, 0);
-			}
+
 			return 0;
 		}
 
@@ -2029,16 +2018,6 @@
 #endif
 }
 
-/*
- *	Actually unregister the subdriver. Called with the
- *	request lock dropped.
- */
- 
-static int default_cleanup (ide_drive_t *drive)
-{
-	return ide_unregister_subdriver(drive);
-}
-
 static ide_startstop_t default_do_request (ide_drive_t *drive, struct request *rq, sector_t block)
 {
 	ide_end_request(drive, 0, 0);
@@ -2074,14 +2053,6 @@
 	return ide_stopped;
 }
 
-static int default_attach (ide_drive_t *drive)
-{
-	printk(KERN_ERR "%s: does not support hotswap of device class !\n",
-		drive->name);
-
-	return 0;
-}
-
 static ide_startstop_t default_abort(ide_drive_t *drive, struct request *rq)
 {
 	return __ide_abort(drive, rq);
@@ -2096,7 +2067,8 @@
 
 static void setup_driver_defaults (ide_driver_t *d)
 {
-	if (d->cleanup == NULL)		d->cleanup = default_cleanup;
+	BUG_ON(d->attach == NULL || d->cleanup == NULL);
+
 	if (d->do_request == NULL)	d->do_request = default_do_request;
 	if (d->end_request == NULL)	d->end_request = default_end_request;
 	if (d->error == NULL)		d->error = default_error;
@@ -2104,7 +2076,6 @@
 	if (d->pre_reset == NULL)	d->pre_reset = default_pre_reset;
 	if (d->capacity == NULL)	d->capacity = default_capacity;
 	if (d->special == NULL)		d->special = default_special;
-	if (d->attach == NULL)		d->attach = default_attach;
 	if (d->start_power_step == NULL)
 		d->start_power_step = default_start_power_step;
 }
@@ -2133,7 +2104,6 @@
 		drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap);
 		drive->nice1 = 1;
 	}
-	drive->suspend_reset = 0;
 #ifdef CONFIG_PROC_FS
 	if (drive->driver != &idedefault_driver) {
 		ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
diff -Nru a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
--- a/drivers/ide/legacy/ide-cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/ide/legacy/ide-cs.c	2005-01-19 13:44:47 -08:00
@@ -64,11 +64,6 @@
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
@@ -116,7 +111,7 @@
     ide_info_t *info;
     dev_link_t *link;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "ide_attach()\n");
 
@@ -130,12 +125,7 @@
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.IOAddrLines = 3;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
diff -Nru a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
--- a/drivers/ide/pci/atiixp.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/ide/pci/atiixp.c	2005-01-19 13:44:46 -08:00
@@ -345,8 +345,9 @@
 }
 
 static struct pci_device_id atiixp_pci_tbl[] = {
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff -Nru a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
--- a/drivers/ide/pci/piix.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/ide/pci/piix.c	2005-01-19 13:44:45 -08:00
@@ -129,6 +129,7 @@
 		case PCI_DEVICE_ID_INTEL_82801CA_10:
 		case PCI_DEVICE_ID_INTEL_82801CA_11:
 		case PCI_DEVICE_ID_INTEL_82801E_11:
+		case PCI_DEVICE_ID_INTEL_82801DB_1:
 		case PCI_DEVICE_ID_INTEL_82801DB_10:
 		case PCI_DEVICE_ID_INTEL_82801DB_11:
 		case PCI_DEVICE_ID_INTEL_82801EB_11:
@@ -440,6 +441,7 @@
 		case PCI_DEVICE_ID_INTEL_82801BA_9:
 		case PCI_DEVICE_ID_INTEL_82801CA_10:
 		case PCI_DEVICE_ID_INTEL_82801CA_11:
+		case PCI_DEVICE_ID_INTEL_82801DB_1:
 		case PCI_DEVICE_ID_INTEL_82801DB_10:
 		case PCI_DEVICE_ID_INTEL_82801DB_11:
 		case PCI_DEVICE_ID_INTEL_82801EB_11:
@@ -614,6 +616,7 @@
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20},
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21},
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
diff -Nru a/drivers/ide/pci/piix.h b/drivers/ide/pci/piix.h
--- a/drivers/ide/pci/piix.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/ide/pci/piix.h	2005-01-19 13:44:46 -08:00
@@ -59,6 +59,7 @@
 	/* 19 */ DECLARE_PIIX_DEV("ICH5"),
 	/* 20 */ DECLARE_PIIX_DEV("ICH6"),
 	/* 21 */ DECLARE_PIIX_DEV("ICH7"),
+	/* 22 */ DECLARE_PIIX_DEV("ICH4"),
 };
 
 #endif /* PIIX_H */
diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
--- a/drivers/ieee1394/nodemgr.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/ieee1394/nodemgr.c	2005-01-19 13:44:47 -08:00
@@ -19,7 +19,6 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/moduleparam.h>
-#include <linux/suspend.h>
 #include <asm/atomic.h>
 
 #include "ieee1394_types.h"
@@ -1480,10 +1479,8 @@
 
 		if (down_interruptible(&hi->reset_sem) ||
 		    down_interruptible(&nodemgr_serialize)) {
-			if (current->flags & PF_FREEZE) {
-				refrigerator(0);
+			if (try_to_freeze(PF_FREEZE))
 				continue;
-			}
 			printk("NodeMgr: received unexpected signal?!\n" );
 			break;
 		}
diff -Nru a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
--- a/drivers/infiniband/core/cache.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/core/cache.c	2005-01-19 13:44:46 -08:00
@@ -65,8 +65,8 @@
 	return device->node_type == IB_NODE_SWITCH ? 0 : device->phys_port_cnt;
 }
 
-int ib_cached_gid_get(struct ib_device *device,
-		      u8                port,
+int ib_get_cached_gid(struct ib_device *device,
+		      u8                port_num,
 		      int               index,
 		      union ib_gid     *gid)
 {
@@ -74,12 +74,12 @@
 	unsigned long flags;
 	int ret = 0;
 
-	if (port < start_port(device) || port > end_port(device))
+	if (port_num < start_port(device) || port_num > end_port(device))
 		return -EINVAL;
 
 	read_lock_irqsave(&device->cache.lock, flags);
 
-	cache = device->cache.gid_cache[port - start_port(device)];
+	cache = device->cache.gid_cache[port_num - start_port(device)];
 
 	if (index < 0 || index >= cache->table_len)
 		ret = -EINVAL;
@@ -90,10 +90,45 @@
 
 	return ret;
 }
-EXPORT_SYMBOL(ib_cached_gid_get);
+EXPORT_SYMBOL(ib_get_cached_gid);
 
-int ib_cached_pkey_get(struct ib_device *device,
-		       u8                port,
+int ib_find_cached_gid(struct ib_device *device,
+		       union ib_gid	*gid,
+		       u8               *port_num,
+		       u16              *index)
+{
+	struct ib_gid_cache *cache;
+	unsigned long flags;
+	int p, i;
+	int ret = -ENOENT;
+
+	*port_num = -1;
+	if (index)
+		*index = -1;
+
+	read_lock_irqsave(&device->cache.lock, flags);
+
+	for (p = 0; p <= end_port(device) - start_port(device); ++p) {
+		cache = device->cache.gid_cache[p];
+		for (i = 0; i < cache->table_len; ++i) {
+			if (!memcmp(gid, &cache->table[i], sizeof *gid)) {
+				*port_num = p;
+				if (index)
+					*index = i;
+				ret = 0;
+				goto found;
+			}
+		}
+	}
+found:
+	read_unlock_irqrestore(&device->cache.lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_find_cached_gid);
+
+int ib_get_cached_pkey(struct ib_device *device,
+		       u8                port_num,
 		       int               index,
 		       u16              *pkey)
 {
@@ -101,12 +136,12 @@
 	unsigned long flags;
 	int ret = 0;
 
-	if (port < start_port(device) || port > end_port(device))
+	if (port_num < start_port(device) || port_num > end_port(device))
 		return -EINVAL;
 
 	read_lock_irqsave(&device->cache.lock, flags);
 
-	cache = device->cache.pkey_cache[port - start_port(device)];
+	cache = device->cache.pkey_cache[port_num - start_port(device)];
 
 	if (index < 0 || index >= cache->table_len)
 		ret = -EINVAL;
@@ -117,10 +152,10 @@
 
 	return ret;
 }
-EXPORT_SYMBOL(ib_cached_pkey_get);
+EXPORT_SYMBOL(ib_get_cached_pkey);
 
-int ib_cached_pkey_find(struct ib_device *device,
-			u8                port,
+int ib_find_cached_pkey(struct ib_device *device,
+			u8                port_num,
 			u16               pkey,
 			u16              *index)
 {
@@ -129,12 +164,12 @@
 	int i;
 	int ret = -ENOENT;
 
-	if (port < start_port(device) || port > end_port(device))
+	if (port_num < start_port(device) || port_num > end_port(device))
 		return -EINVAL;
 
 	read_lock_irqsave(&device->cache.lock, flags);
 
-	cache = device->cache.pkey_cache[port - start_port(device)];
+	cache = device->cache.pkey_cache[port_num - start_port(device)];
 
 	*index = -1;
 
@@ -149,7 +184,7 @@
 
 	return ret;
 }
-EXPORT_SYMBOL(ib_cached_pkey_find);
+EXPORT_SYMBOL(ib_find_cached_pkey);
 
 static void ib_cache_update(struct ib_device *device,
 			    u8                port)
@@ -252,7 +287,7 @@
 	}
 }
 
-void ib_cache_setup_one(struct ib_device *device)
+static void ib_cache_setup_one(struct ib_device *device)
 {
 	int p;
 
@@ -295,7 +330,7 @@
 	kfree(device->cache.gid_cache);
 }
 
-void ib_cache_cleanup_one(struct ib_device *device)
+static void ib_cache_cleanup_one(struct ib_device *device)
 {
 	int p;
 
@@ -311,7 +346,7 @@
 	kfree(device->cache.gid_cache);
 }
 
-struct ib_client cache_client = {
+static struct ib_client cache_client = {
 	.name   = "cache",
 	.add    = ib_cache_setup_one,
 	.remove = ib_cache_cleanup_one
diff -Nru a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
--- a/drivers/infiniband/core/mad.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/core/mad.c	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -60,6 +60,9 @@
 static int method_in_use(struct ib_mad_mgmt_method_table **method,
 			 struct ib_mad_reg_req *mad_reg_req);
 static void remove_mad_reg_req(struct ib_mad_agent_private *priv);
+static struct ib_mad_agent_private *find_mad_agent(
+					struct ib_mad_port_private *port_priv,
+					struct ib_mad *mad, int solicited);
 static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
 				    struct ib_mad_private *mad);
 static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv);
@@ -614,21 +617,41 @@
 	spin_unlock_irqrestore(&qp_info->snoop_lock, flags);
 }
 
+static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num,
+			 struct ib_wc *wc)
+{
+	memset(wc, 0, sizeof *wc);
+	wc->wr_id = wr_id;
+	wc->status = IB_WC_SUCCESS;
+	wc->opcode = IB_WC_RECV;
+	wc->pkey_index = pkey_index;
+	wc->byte_len = sizeof(struct ib_mad) + sizeof(struct ib_grh);
+	wc->src_qp = IB_QP0;
+	wc->qp_num = IB_QP0;
+	wc->slid = slid;
+	wc->sl = 0;
+	wc->dlid_path_bits = 0;
+	wc->port_num = port_num;
+}
+
 /*
  * Return 0 if SMP is to be sent
  * Return 1 if SMP was consumed locally (whether or not solicited)
  * Return < 0 if error
  */
-static int handle_outgoing_smp(struct ib_mad_agent_private *mad_agent_priv,
-			       struct ib_smp *smp,
-			       struct ib_send_wr *send_wr)
+static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
+				  struct ib_smp *smp,
+				  struct ib_send_wr *send_wr)
 {
-	int ret, alloc_flags;
+	int ret, alloc_flags, solicited;
 	unsigned long flags;
 	struct ib_mad_local_private *local;
 	struct ib_mad_private *mad_priv;
+	struct ib_mad_port_private *port_priv;
+	struct ib_mad_agent_private *recv_mad_agent = NULL;
 	struct ib_device *device = mad_agent_priv->agent.device;
 	u8 port_num = mad_agent_priv->agent.port_num;
+	struct ib_wc mad_wc;
 
 	if (!smi_handle_dr_smp_send(smp, device->node_type, port_num)) {
 		ret = -EINVAL;
@@ -651,6 +674,7 @@
 		goto out;
 	}
 	local->mad_priv = NULL;
+	local->recv_mad_agent = NULL;
 	mad_priv = kmem_cache_alloc(ib_mad_cache, alloc_flags);
 	if (!mad_priv) {
 		ret = -ENOMEM;
@@ -658,7 +682,12 @@
 		kfree(local);
 		goto out;
 	}
-	ret = device->process_mad(device, 0, port_num, smp->dr_slid,
+
+	build_smp_wc(send_wr->wr_id, smp->dr_slid, send_wr->wr.ud.pkey_index,
+		     send_wr->wr.ud.port_num, &mad_wc);
+
+	/* No GRH for DR SMP */
+	ret = device->process_mad(device, 0, port_num, &mad_wc, NULL,
 				  (struct ib_mad *)smp,
 				  (struct ib_mad *)&mad_priv->mad);
 	switch (ret)
@@ -669,19 +698,41 @@
 		 * there is a recv handler
 		 */
 		if (solicited_mad(&mad_priv->mad.mad) &&
-		    mad_agent_priv->agent.recv_handler)
+		    mad_agent_priv->agent.recv_handler) {
 			local->mad_priv = mad_priv;
-		else
+			local->recv_mad_agent = mad_agent_priv;
+			/*
+			 * Reference MAD agent until receive
+			 * side of local completion handled
+			 */
+			atomic_inc(&mad_agent_priv->refcount);
+		} else
 			kmem_cache_free(ib_mad_cache, mad_priv);
 		break;
 	case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
 		kmem_cache_free(ib_mad_cache, mad_priv);
 		break;
 	case IB_MAD_RESULT_SUCCESS:
-		kmem_cache_free(ib_mad_cache, mad_priv);
-		kfree(local);
-		ret = 0;
-		goto out;
+		/* Treat like an incoming receive MAD */
+		solicited = solicited_mad(&mad_priv->mad.mad);
+		port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
+					    mad_agent_priv->agent.port_num);
+		if (port_priv) {
+			mad_priv->mad.mad.mad_hdr.tid =
+				((struct ib_mad *)smp)->mad_hdr.tid;
+			recv_mad_agent = find_mad_agent(port_priv,
+						       &mad_priv->mad.mad,
+							solicited);
+		}
+		if (!port_priv || !recv_mad_agent) {
+			kmem_cache_free(ib_mad_cache, mad_priv);
+			kfree(local);
+			ret = 0;
+			goto out;
+		}
+		local->mad_priv = mad_priv;
+		local->recv_mad_agent = recv_mad_agent;
+		break;
 	default:
 		kmem_cache_free(ib_mad_cache, mad_priv);
 		kfree(local);
@@ -696,7 +747,7 @@
 	local->send_wr.next = NULL;
 	local->tid = send_wr->wr.ud.mad_hdr->tid;
 	local->wr_id = send_wr->wr_id;
-	/* Reference MAD agent until local completion handled */
+	/* Reference MAD agent until send side of local completion handled */
 	atomic_inc(&mad_agent_priv->refcount);
 	/* Queue local completion to local list */
 	spin_lock_irqsave(&mad_agent_priv->lock, flags);
@@ -797,7 +848,8 @@
 
 		smp = (struct ib_smp *)send_wr->wr.ud.mad_hdr;
 		if (smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
-			ret = handle_outgoing_smp(mad_agent_priv, smp, send_wr);
+			ret = handle_outgoing_dr_smp(mad_agent_priv, smp,
+						     send_wr);
 			if (ret < 0)		/* error */
 				goto error2;
 			else if (ret == 1)	/* locally consumed */
@@ -1593,7 +1645,7 @@
 
 		ret = port_priv->device->process_mad(port_priv->device, 0,
 						     port_priv->port_num,
-						     wc->slid,
+						     wc, &recv->grh,
 						     &recv->mad.mad,
 						     &response->mad.mad);
 		if (ret & IB_MAD_RESULT_SUCCESS) {
@@ -1996,6 +2048,7 @@
 {
 	struct ib_mad_agent_private *mad_agent_priv;
 	struct ib_mad_local_private *local;
+	struct ib_mad_agent_private *recv_mad_agent;
 	unsigned long flags;
 	struct ib_wc wc;
 	struct ib_mad_send_wc mad_send_wc;
@@ -2009,21 +2062,21 @@
 				   completion_list);
 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 		if (local->mad_priv) {
+			recv_mad_agent = local->recv_mad_agent;
+			if (!recv_mad_agent) {
+				printk(KERN_ERR PFX "No receive MAD agent for local completion\n");
+				kmem_cache_free(ib_mad_cache, local->mad_priv);
+				goto local_send_completion;
+			}
+
 			/*
 			 * Defined behavior is to complete response
 			 * before request
 			 */
-			wc.wr_id = local->wr_id;
-			wc.status = IB_WC_SUCCESS;
-			wc.opcode = IB_WC_RECV;
-			wc.vendor_err = 0;
-			wc.byte_len = sizeof(struct ib_mad);
-			wc.src_qp = IB_QP0;
-			wc.wc_flags = 0;
-			wc.pkey_index = 0;
-			wc.slid = IB_LID_PERMISSIVE;
-			wc.sl = 0;
-			wc.dlid_path_bits = 0;
+			build_smp_wc(local->wr_id, IB_LID_PERMISSIVE,
+				     0 /* pkey index */,
+				     recv_mad_agent->agent.port_num, &wc);
+
 			local->mad_priv->header.recv_wc.wc = &wc;
 			local->mad_priv->header.recv_wc.mad_len =
 						sizeof(struct ib_mad);
@@ -2031,15 +2084,19 @@
 			local->mad_priv->header.recv_wc.recv_buf.grh = NULL;
 			local->mad_priv->header.recv_wc.recv_buf.mad =
 						&local->mad_priv->mad.mad;
-			if (atomic_read(&mad_agent_priv->qp_info->snoop_count))
-				snoop_recv(mad_agent_priv->qp_info,
+			if (atomic_read(&recv_mad_agent->qp_info->snoop_count))
+				snoop_recv(recv_mad_agent->qp_info,
 					  &local->mad_priv->header.recv_wc,
 					   IB_MAD_SNOOP_RECVS);
-			mad_agent_priv->agent.recv_handler(
-						&mad_agent_priv->agent,
+			recv_mad_agent->agent.recv_handler(
+						&recv_mad_agent->agent,
 						&local->mad_priv->header.recv_wc);
+			spin_lock_irqsave(&recv_mad_agent->lock, flags);
+			atomic_dec(&recv_mad_agent->refcount);
+			spin_unlock_irqrestore(&recv_mad_agent->lock, flags);
 		}
 
+local_send_completion:
 		/* Complete send */
 		mad_send_wc.status = IB_WC_SUCCESS;
 		mad_send_wc.vendor_err = 0;
diff -Nru a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
--- a/drivers/infiniband/core/mad_priv.h	2005-01-19 13:44:48 -08:00
+++ b/drivers/infiniband/core/mad_priv.h	2005-01-19 13:44:48 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2004, 2005, Voltaire, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -127,6 +127,7 @@
 struct ib_mad_local_private {
 	struct list_head completion_list;
 	struct ib_mad_private *mad_priv;
+	struct ib_mad_agent_private *recv_mad_agent;
 	struct ib_send_wr send_wr;
 	struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
 	u64 wr_id;			/* client WR ID */
diff -Nru a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
--- a/drivers/infiniband/core/sysfs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/core/sysfs.c	2005-01-19 13:44:46 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -188,8 +188,6 @@
 	case 4: speed = " QDR"; break;
 	}
 
-	printk(KERN_ERR "width %d speed %d\n", attr.active_width, attr.active_speed);
-
 	rate = 25 * ib_width_enum_to_int(attr.active_width) * attr.active_speed;
 	if (rate < 0)
 		return -EINVAL;
@@ -199,6 +197,29 @@
 		       ib_width_enum_to_int(attr.active_width), speed);
 }
 
+static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
+			       char *buf)
+{
+	struct ib_port_attr attr;
+
+	ssize_t ret;
+
+	ret = ib_query_port(p->ibdev, p->port_num, &attr);
+	if (ret)
+		return ret;
+
+	switch (attr.phys_state) {
+	case 1:  return sprintf(buf, "1: Sleep\n");
+	case 2:  return sprintf(buf, "2: Polling\n");
+	case 3:  return sprintf(buf, "3: Disabled\n");
+	case 4:  return sprintf(buf, "4: PortConfigurationTraining\n");
+	case 5:  return sprintf(buf, "5: LinkUp\n");
+	case 6:  return sprintf(buf, "6: LinkErrorRecovery\n");
+	case 7:  return sprintf(buf, "7: Phy Test\n");
+	default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state);
+	}
+}
+
 static PORT_ATTR_RO(state);
 static PORT_ATTR_RO(lid);
 static PORT_ATTR_RO(lid_mask_count);
@@ -206,6 +227,7 @@
 static PORT_ATTR_RO(sm_sl);
 static PORT_ATTR_RO(cap_mask);
 static PORT_ATTR_RO(rate);
+static PORT_ATTR_RO(phys_state);
 
 static struct attribute *port_default_attrs[] = {
 	&port_attr_state.attr,
@@ -215,6 +237,7 @@
 	&port_attr_sm_sl.attr,
 	&port_attr_cap_mask.attr,
 	&port_attr_rate.attr,
+	&port_attr_phys_state.attr,
 	NULL
 };
 
@@ -292,8 +315,8 @@
 
 	in_mad->data[41] = p->port_num;	/* PortSelect field */
 
-	if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY, p->port_num, 0xffff,
-				   in_mad, out_mad) &
+	if ((p->ibdev->process_mad(p->ibdev, IB_MAD_IGNORE_MKEY,
+		 p->port_num, NULL, NULL, in_mad, out_mad) &
 	     (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) !=
 	    (IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY)) {
 		ret = -EINVAL;
@@ -574,6 +597,18 @@
 	return ret;
 }
 
+static ssize_t show_node_type(struct class_device *cdev, char *buf)
+{
+	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
+
+	switch (dev->node_type) {
+	case IB_NODE_CA:     return sprintf(buf, "%d: CA\n", dev->node_type);
+	case IB_NODE_SWITCH: return sprintf(buf, "%d: switch\n", dev->node_type);
+	case IB_NODE_ROUTER: return sprintf(buf, "%d: router\n", dev->node_type);
+	default:             return sprintf(buf, "%d: <unknown>\n", dev->node_type);
+	}
+}
+
 static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
 {
 	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
@@ -608,10 +643,12 @@
 		       be16_to_cpu(((u16 *) &attr.node_guid)[3]));
 }
 
+static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
 static CLASS_DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
 static CLASS_DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
 
 static struct class_device_attribute *ib_class_attributes[] = {
+	&class_device_attr_node_type,
 	&class_device_attr_sys_image_guid,
 	&class_device_attr_node_guid
 };
diff -Nru a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
--- a/drivers/infiniband/core/verbs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/core/verbs.c	2005-01-19 13:44:47 -08:00
@@ -132,6 +132,7 @@
 		qp->srq	       	  = qp_init_attr->srq;
 		qp->event_handler = qp_init_attr->event_handler;
 		qp->qp_context    = qp_init_attr->qp_context;
+		qp->qp_type	  = qp_init_attr->qp_type;
 		atomic_inc(&pd->usecnt);
 		atomic_inc(&qp_init_attr->send_cq->usecnt);
 		atomic_inc(&qp_init_attr->recv_cq->usecnt);
diff -Nru a/drivers/infiniband/hw/mthca/Makefile b/drivers/infiniband/hw/mthca/Makefile
--- a/drivers/infiniband/hw/mthca/Makefile	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/hw/mthca/Makefile	2005-01-19 13:44:47 -08:00
@@ -9,4 +9,4 @@
 ib_mthca-y :=	mthca_main.o mthca_cmd.o mthca_profile.o mthca_reset.o \
 		mthca_allocator.o mthca_eq.o mthca_pd.o mthca_cq.o \
 		mthca_mr.o mthca_qp.o mthca_av.o mthca_mcg.o mthca_mad.o \
-		mthca_provider.o
+		mthca_provider.o mthca_memfree.o
diff -Nru a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
--- a/drivers/infiniband/hw/mthca/mthca_av.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_av.c	2005-01-19 13:44:47 -08:00
@@ -159,7 +159,7 @@
 			(be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff;
 		header->grh.flow_label    =
 			ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff);
-		ib_cached_gid_get(&dev->ib_dev,
+		ib_get_cached_gid(&dev->ib_dev,
 				  be32_to_cpu(ah->av->port_pd) >> 24,
 				  ah->av->gid_index,
 				  &header->grh.source_gid);
diff -Nru a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -40,6 +40,7 @@
 #include "mthca_dev.h"
 #include "mthca_config_reg.h"
 #include "mthca_cmd.h"
+#include "mthca_memfree.h"
 
 #define CMD_POLL_TOKEN 0xffff
 
@@ -508,38 +509,38 @@
 	return mthca_cmd(dev, 0, 0, 0, CMD_SYS_DIS, HZ, status);
 }
 
-int mthca_MAP_FA(struct mthca_dev *dev, int count,
-		 struct scatterlist *sglist, u8 *status)
+int mthca_MAP_FA(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status)
 {
 	u32 *inbox;
 	dma_addr_t indma;
+	struct mthca_icm_iter iter;
 	int lg;
 	int nent = 0;
-	int i, j;
+	int i;
 	int err = 0;
 	int ts = 0;
 
 	inbox = pci_alloc_consistent(dev->pdev, PAGE_SIZE, &indma);
 	memset(inbox, 0, PAGE_SIZE);
 
-	for (i = 0; i < count; ++i) {
+	for (mthca_icm_first(icm, &iter); !mthca_icm_last(&iter); mthca_icm_next(&iter)) {
 		/*
 		 * We have to pass pages that are aligned to their
 		 * size, so find the least significant 1 in the
 		 * address or size and use that as our log2 size.
 		 */
-		lg = ffs(sg_dma_address(sglist + i) | sg_dma_len(sglist + i)) - 1;
+		lg = ffs(mthca_icm_addr(&iter) | mthca_icm_size(&iter)) - 1;
 		if (lg < 12) {
-			mthca_warn(dev, "Got FW area not aligned to 4K (%llx/%x).\n",
-				   (unsigned long long) sg_dma_address(sglist + i),
-				   sg_dma_len(sglist + i));
+			mthca_warn(dev, "Got FW area not aligned to 4K (%llx/%lx).\n",
+				   (unsigned long long) mthca_icm_addr(&iter),
+				   mthca_icm_size(&iter));
 			err = -EINVAL;
 			goto out;
 		}
-		for (j = 0; j < sg_dma_len(sglist + i) / (1 << lg); ++j, ++nent) {
+		for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) {
 			*((__be64 *) (inbox + nent * 4 + 2)) =
-				cpu_to_be64((sg_dma_address(sglist + i) +
-					     (j << lg)) |
+				cpu_to_be64((mthca_icm_addr(&iter) +
+					     (i << lg)) |
 					    (lg - 12));
 			ts += 1 << (lg - 10);
 			if (nent == PAGE_SIZE / 16) {
@@ -958,9 +959,9 @@
 		MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET);
 		dev_lim->hca.arbel.resize_srq = field & 1;
 		MTHCA_GET(size, outbox, QUERY_DEV_LIM_MTT_ENTRY_SZ_OFFSET);
-		dev_lim->hca.arbel.mtt_entry_sz = size;
+		dev_lim->mtt_seg_sz = size;
 		MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
-		dev_lim->hca.arbel.mpt_entry_sz = size;
+		dev_lim->mpt_entry_sz = size;
 		MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
 		dev_lim->hca.arbel.max_pbl_sz = 1 << (field & 0x3f);
 		MTHCA_GET(dev_lim->hca.arbel.bmme_flags, outbox,
@@ -986,6 +987,8 @@
 	} else {
 		MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET);
 		dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f);
+		dev_lim->mtt_seg_sz   = MTHCA_MTT_SEG_SIZE;
+		dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE;
 	}
 
 out:
diff -Nru a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
--- a/drivers/infiniband/hw/mthca/mthca_cmd.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h	2005-01-19 13:44:46 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -148,14 +148,14 @@
 	int cqc_entry_sz;
 	int srq_entry_sz;
 	int uar_scratch_entry_sz;
+	int mtt_seg_sz;
+	int mpt_entry_sz;
 	union {
 		struct {
 			int max_avs;
 		} tavor;
 		struct {
 			int resize_srq;
-			int mtt_entry_sz;
-			int mpt_entry_sz;
 			int max_pbl_sz;
 			u8  bmme_flags;
 			u32 reserved_lkey;
@@ -219,8 +219,7 @@
 
 int mthca_SYS_EN(struct mthca_dev *dev, u8 *status);
 int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status);
-int mthca_MAP_FA(struct mthca_dev *dev, int count,
-		 struct scatterlist *sglist, u8 *status);
+int mthca_MAP_FA(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status);
 int mthca_UNMAP_FA(struct mthca_dev *dev, u8 *status);
 int mthca_RUN_FW(struct mthca_dev *dev, u8 *status);
 int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status);
diff -Nru a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
--- a/drivers/infiniband/hw/mthca/mthca_cq.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c	2005-01-19 13:44:46 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -391,6 +391,10 @@
 	if (!next_cqe_sw(cq))
 		return -EAGAIN;
 
+	/*
+	 * Make sure we read CQ entry contents after we've checked the
+	 * ownership bit.
+	 */
 	rmb();
 
 	cqe = get_cqe(cq, cq->cons_index);
@@ -440,6 +444,8 @@
 		spin_lock(&(*cur_qp)->lock);
 	}
 
+	entry->qp_num = (*cur_qp)->qpn;
+
 	if (is_send) {
 		wq = &(*cur_qp)->sq;
 		wqe_index = ((be32_to_cpu(cqe->wqe) - (*cur_qp)->send_wqe_offset)
@@ -768,7 +774,8 @@
 		u32 *ctx = MAILBOX_ALIGN(mailbox);
 		int j;
 
-		printk(KERN_ERR "context for CQN %x\n", cq->cqn);
+		printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n",
+		       cq->cqn, cq->cons_index, next_cqe_sw(cq));
 		for (j = 0; j < 16; ++j)
 			printk(KERN_ERR "[%2x] %08x\n", j * 4, be32_to_cpu(ctx[j]));
 	}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
--- a/drivers/infiniband/hw/mthca/mthca_dev.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h	2005-01-19 13:44:46 -08:00
@@ -40,7 +40,6 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <asm/semaphore.h>
-#include <asm/scatterlist.h>
 
 #include "mthca_provider.h"
 #include "mthca_doorbell.h"
@@ -71,12 +70,16 @@
 };
 
 enum {
-	MTHCA_MPT_ENTRY_SIZE  =  0x40,
 	MTHCA_EQ_CONTEXT_SIZE =  0x40,
 	MTHCA_CQ_CONTEXT_SIZE =  0x40,
 	MTHCA_QP_CONTEXT_SIZE = 0x200,
+	MTHCA_RDB_ENTRY_SIZE  =  0x20,
 	MTHCA_AV_SIZE         =  0x20,
-	MTHCA_MGM_ENTRY_SIZE  =  0x40
+	MTHCA_MGM_ENTRY_SIZE  =  0x40,
+
+	/* Arbel FW gives us these, but we need them for Tavor */
+	MTHCA_MPT_ENTRY_SIZE  =  0x40,
+	MTHCA_MTT_SEG_SIZE    =  0x40,
 };
 
 enum {
@@ -121,7 +124,6 @@
 	int      mtt_seg_size;
 	int      reserved_mtts;
 	int      reserved_mrws;
-	int      num_rdbs;
 	int      reserved_uars;
 	int      num_mgms;
 	int      num_amgms;
@@ -174,6 +176,8 @@
 
 struct mthca_qp_table {
 	struct mthca_alloc alloc;
+	u32                rdb_base;
+	int                rdb_shift;
 	int                sqp_start;
 	spinlock_t         lock;
 	struct mthca_array qp;
@@ -212,7 +216,7 @@
 			u64 clr_int_base;
 			u64 eq_arm_base;
 			u64 eq_set_ci_base;
-			struct scatterlist *mem;
+			struct mthca_icm *icm;
 			u16 fw_pages;
 		}        arbel;
 	}                fw;
@@ -377,7 +381,8 @@
 int mthca_process_mad(struct ib_device *ibdev,
 		      int mad_flags,
 		      u8 port_num,
-		      u16 slid,
+		      struct ib_wc *in_wc,
+		      struct ib_grh *in_grh,
 		      struct ib_mad *in_mad,
 		      struct ib_mad *out_mad);
 int mthca_create_agents(struct mthca_dev *dev);
diff -Nru a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
--- a/drivers/infiniband/hw/mthca/mthca_eq.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -239,6 +239,12 @@
 	while (next_eqe_sw(eq)) {
 		int set_ci = 0;
 		eqe = get_eqe(eq, eq->cons_index);
+
+		/*
+		 * Make sure we read EQ entry contents after we've
+		 * checked the ownership bit.
+		 */
+		rmb();
 
 		switch (eqe->type) {
 		case MTHCA_EVENT_TYPE_COMP:
diff -Nru a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
--- a/drivers/infiniband/hw/mthca/mthca_mad.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c	2005-01-19 13:44:48 -08:00
@@ -185,12 +185,14 @@
 int mthca_process_mad(struct ib_device *ibdev,
 		      int mad_flags,
 		      u8 port_num,
-		      u16 slid,
+		      struct ib_wc *in_wc,
+		      struct ib_grh *in_grh,
 		      struct ib_mad *in_mad,
 		      struct ib_mad *out_mad)
 {
 	int err;
 	u8 status;
+	u16 slid = in_wc ? in_wc->slid : IB_LID_PERMISSIVE;
 
 	/* Forward locally generated traps to the SM */
 	if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
diff -Nru a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
--- a/drivers/infiniband/hw/mthca/mthca_main.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_main.c	2005-01-19 13:44:46 -08:00
@@ -48,6 +48,7 @@
 #include "mthca_config_reg.h"
 #include "mthca_cmd.h"
 #include "mthca_profile.h"
+#include "mthca_memfree.h"
 
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("Mellanox InfiniBand HCA low-level driver");
@@ -75,6 +76,20 @@
 	"ib_mthca: Mellanox InfiniBand HCA driver v"
 	DRV_VERSION " (" DRV_RELDATE ")\n";
 
+static struct mthca_profile default_profile = {
+	.num_qp     = 1 << 16,
+	.rdb_per_qp = 4,
+	.num_cq     = 1 << 16,
+	.num_mcg    = 1 << 13,
+	.num_mpt    = 1 << 17,
+	.num_mtt    = 1 << 20
+};
+
+enum {
+	MTHCA_TAVOR_NUM_UDAV  = 1 << 15,
+	MTHCA_ARBEL_UARC_SIZE = 1 << 18
+};
+
 static int __devinit mthca_tune_pci(struct mthca_dev *mdev)
 {
 	int cap;
@@ -174,6 +189,7 @@
 	u8 status;
 	int err;
 	struct mthca_dev_lim        dev_lim;
+	struct mthca_profile        profile;
 	struct mthca_init_hca_param init_hca;
 	struct mthca_adapter        adapter;
 
@@ -213,7 +229,11 @@
 
 	err = mthca_dev_lim(mdev, &dev_lim);
 
-	err = mthca_make_profile(mdev, &dev_lim, &init_hca);
+	profile = default_profile;
+	profile.num_uar  = dev_lim.uar_size / PAGE_SIZE;
+	profile.num_udav = MTHCA_TAVOR_NUM_UDAV;
+
+	err = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca);
 	if (err)
 		goto err_out_disable;
 
@@ -259,75 +279,26 @@
 {
 	u8 status;
 	int err;
-	int num_ent, num_sg, fw_pages, cur_order;
-	int i;
 
 	/* FIXME: use HCA-attached memory for FW if present */
 
-	mdev->fw.arbel.mem = kmalloc(sizeof *mdev->fw.arbel.mem *
-				     mdev->fw.arbel.fw_pages,
-				     GFP_KERNEL);
-	if (!mdev->fw.arbel.mem) {
+	mdev->fw.arbel.icm =
+		mthca_alloc_icm(mdev, mdev->fw.arbel.fw_pages,
+				GFP_HIGHUSER | __GFP_NOWARN);
+	if (!mdev->fw.arbel.icm) {
 		mthca_err(mdev, "Couldn't allocate FW area, aborting.\n");
 		return -ENOMEM;
 	}
 
-	memset(mdev->fw.arbel.mem, 0,
-	       sizeof *mdev->fw.arbel.mem * mdev->fw.arbel.fw_pages);
-
-	fw_pages = mdev->fw.arbel.fw_pages;
-	num_ent = 0;
-
-	/*
-	 * We allocate in as big chunks as we can, up to a maximum of
-	 * 256 KB per chunk.
-	 */
-	cur_order = get_order(1 << 18);
-
-	while (fw_pages > 0) {
-		while (1 << cur_order > fw_pages)
-			--cur_order;
-
-		/*
-		 * We allocate with GFP_HIGHUSER because only the
-		 * firmware is going to touch these pages, so there's
-		 * no need for a kernel virtual address.  We use
-		 * __GFP_NOWARN because we'll deal with any allocation
-		 * failures ourselves.
-		 */
-		mdev->fw.arbel.mem[num_ent].page   = alloc_pages(GFP_HIGHUSER | __GFP_NOWARN,
-								 cur_order);
-		mdev->fw.arbel.mem[num_ent].length = PAGE_SIZE << cur_order;
-		if (!mdev->fw.arbel.mem[num_ent].page) {
-			--cur_order;
-			if (cur_order < 0) {
-				mthca_err(mdev, "Couldn't allocate FW area, aborting.\n");
-				err = -ENOMEM;
-				goto err_free;
-			}
-		} else {
-			++num_ent;
-			fw_pages -= 1 << cur_order;
-		}
-	}
-
-	num_sg = pci_map_sg(mdev->pdev, mdev->fw.arbel.mem, num_ent,
-			    PCI_DMA_BIDIRECTIONAL);
-	if (num_sg <= 0) {
-		mthca_err(mdev, "Couldn't allocate FW area, aborting.\n");
-		err = -ENOMEM;
-		goto err_free;
-	}
-
-	err = mthca_MAP_FA(mdev, num_sg, mdev->fw.arbel.mem, &status);
+	err = mthca_MAP_FA(mdev, mdev->fw.arbel.icm, &status);
 	if (err) {
 		mthca_err(mdev, "MAP_FA command failed, aborting.\n");
-		goto err_unmap;
+		goto err_free;
 	}
 	if (status) {
 		mthca_err(mdev, "MAP_FA returned status 0x%02x, aborting.\n", status);
 		err = -EINVAL;
-		goto err_unmap;
+		goto err_free;
 	}
 	err = mthca_RUN_FW(mdev, &status);
 	if (err) {
@@ -345,15 +316,8 @@
 err_unmap_fa:
 	mthca_UNMAP_FA(mdev, &status);
 
-err_unmap:
-	pci_unmap_sg(mdev->pdev, mdev->fw.arbel.mem,
-		   mdev->fw.arbel.fw_pages, PCI_DMA_BIDIRECTIONAL);
 err_free:
-	for (i = 0; i < mdev->fw.arbel.fw_pages; ++i)
-		if (mdev->fw.arbel.mem[i].page)
-			__free_pages(mdev->fw.arbel.mem[i].page,
-				     get_order(mdev->fw.arbel.mem[i].length));
-	kfree(mdev->fw.arbel.mem);
+	mthca_free_icm(mdev, mdev->fw.arbel.icm);
 	return err;
 }
 
@@ -397,13 +361,17 @@
 	err = mthca_dev_lim(mdev, &dev_lim);
 	if (err) {
 		mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n");
-		goto err_out_disable;
+		goto err_out_stop_fw;
 	}
 
 	mthca_warn(mdev, "Sorry, native MT25208 mode support is not done, "
 		   "aborting.\n");
 	err = -ENODEV;
 
+err_out_stop_fw:
+	mthca_UNMAP_FA(mdev, &status);
+	mthca_free_icm(mdev, mdev->fw.arbel.icm);
+
 err_out_disable:
 	if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
 		mthca_DISABLE_LAM(mdev, &status);
@@ -610,21 +578,12 @@
 static void mthca_close_hca(struct mthca_dev *mdev)
 {
 	u8 status;
-	int i;
 
 	mthca_CLOSE_HCA(mdev, 0, &status);
 
 	if (mdev->hca_type == ARBEL_NATIVE) {
 		mthca_UNMAP_FA(mdev, &status);
-
-		pci_unmap_sg(mdev->pdev, mdev->fw.arbel.mem,
-			     mdev->fw.arbel.fw_pages, PCI_DMA_BIDIRECTIONAL);
-
-		for (i = 0; i < mdev->fw.arbel.fw_pages; ++i)
-			if (mdev->fw.arbel.mem[i].page)
-				__free_pages(mdev->fw.arbel.mem[i].page,
-					     get_order(mdev->fw.arbel.mem[i].length));
-		kfree(mdev->fw.arbel.mem);
+		mthca_free_icm(mdev, mdev->fw.arbel.icm);
 
 		if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
 			mthca_DISABLE_LAM(mdev, &status);
diff -Nru a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id$
+ */
+
+#include "mthca_memfree.h"
+#include "mthca_dev.h"
+
+void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm)
+{
+	struct mthca_icm_chunk *chunk, *tmp;
+	int i;
+
+	if (!icm)
+		return;
+
+	list_for_each_entry_safe(chunk, tmp, &icm->chunk_list, list) {
+		if (chunk->nsg > 0)
+			pci_unmap_sg(dev->pdev, chunk->mem, chunk->npages,
+				     PCI_DMA_BIDIRECTIONAL);
+
+		for (i = 0; i < chunk->npages; ++i)
+			__free_pages(chunk->mem[i].page,
+				     get_order(chunk->mem[i].length));
+
+		kfree(chunk);
+	}
+
+	kfree(icm);
+}
+
+struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
+				  unsigned int gfp_mask)
+{
+	struct mthca_icm *icm;
+	struct mthca_icm_chunk *chunk = NULL;
+	int cur_order;
+
+	icm = kmalloc(sizeof *icm, gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
+	if (!icm)
+		return icm;
+
+	INIT_LIST_HEAD(&icm->chunk_list);
+
+	/*
+	 * We allocate in as big chunks as we can, up to a maximum of
+	 * 256 KB per chunk.
+	 */
+	cur_order = get_order(1 << 18);
+
+	while (npages > 0) {
+		if (!chunk) {
+			chunk = kmalloc(sizeof *chunk,
+					gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
+			if (!chunk)
+				goto fail;
+
+			chunk->npages = 0;
+			chunk->nsg    = 0;
+			list_add_tail(&chunk->list, &icm->chunk_list);
+		}
+
+		while (1 << cur_order > npages)
+			--cur_order;
+
+		chunk->mem[chunk->npages].page = alloc_pages(gfp_mask, cur_order);
+		if (chunk->mem[chunk->npages].page) {
+			chunk->mem[chunk->npages].length = PAGE_SIZE << cur_order;
+			chunk->mem[chunk->npages].offset = 0;
+
+			if (++chunk->npages == MTHCA_ICM_CHUNK_LEN) {
+				chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
+							chunk->npages,
+							PCI_DMA_BIDIRECTIONAL);
+
+				if (chunk->nsg <= 0)
+					goto fail;
+
+				chunk = NULL;
+			}
+
+			npages -= 1 << cur_order;
+		} else {
+			--cur_order;
+			if (cur_order < 0)
+				goto fail;
+		}
+	}
+
+	if (chunk) {
+		chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
+					chunk->npages,
+					PCI_DMA_BIDIRECTIONAL);
+
+		if (chunk->nsg <= 0)
+			goto fail;
+	}
+
+	return icm;
+
+fail:
+	mthca_free_icm(dev, icm);
+	return NULL;
+}
diff -Nru a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id$
+ */
+
+#ifndef MTHCA_MEMFREE_H
+#define MTHCA_MEMFREE_H
+
+#include <linux/list.h>
+#include <linux/pci.h>
+
+#define MTHCA_ICM_CHUNK_LEN \
+	((512 - sizeof (struct list_head) - 2 * sizeof (int)) /		\
+	 (sizeof (struct scatterlist)))
+
+struct mthca_icm_chunk {
+	struct list_head   list;
+	int                npages;
+	int                nsg;
+	struct scatterlist mem[MTHCA_ICM_CHUNK_LEN];
+};
+
+struct mthca_icm {
+	struct list_head chunk_list;
+};
+
+struct mthca_icm_iter {
+	struct mthca_icm       *icm;
+	struct mthca_icm_chunk *chunk;
+	int                     page_idx;
+};
+
+struct mthca_dev;
+
+struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
+				  unsigned int gfp_mask);
+void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm);
+
+static inline void mthca_icm_first(struct mthca_icm *icm,
+				   struct mthca_icm_iter *iter)
+{
+	iter->icm      = icm;
+	iter->chunk    = list_empty(&icm->chunk_list) ?
+		NULL : list_entry(icm->chunk_list.next,
+				  struct mthca_icm_chunk, list);
+	iter->page_idx = 0;
+}
+
+static inline int mthca_icm_last(struct mthca_icm_iter *iter)
+{
+	return !iter->chunk;
+}
+
+static inline void mthca_icm_next(struct mthca_icm_iter *iter)
+{
+	if (++iter->page_idx >= iter->chunk->nsg) {
+		if (iter->chunk->list.next == &iter->icm->chunk_list) {
+			iter->chunk = NULL;
+			return;
+		}
+
+		iter->chunk = list_entry(iter->chunk->list.next,
+					 struct mthca_icm_chunk, list);
+		iter->page_idx = 0;
+	}
+}
+
+static inline dma_addr_t mthca_icm_addr(struct mthca_icm_iter *iter)
+{
+	return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
+}
+
+static inline unsigned long mthca_icm_size(struct mthca_icm_iter *iter)
+{
+	return sg_dma_len(&iter->chunk->mem[iter->page_idx]);
+}
+
+#endif /* MTHCA_MEMFREE_H */
diff -Nru a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
--- a/drivers/infiniband/hw/mthca/mthca_mr.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c	2005-01-19 13:44:48 -08:00
@@ -197,7 +197,7 @@
 	for (i = dev->limits.mtt_seg_size / 8, mr->order = 0;
 	     i < list_len;
 	     i <<= 1, ++mr->order)
-		/* nothing */ ;
+		; /* nothing */
 
 	mr->first_seg = mthca_alloc_mtt(dev, mr->order);
 	if (mr->first_seg == -1)
@@ -337,7 +337,7 @@
 	for (i = 1, dev->mr_table.max_mtt_order = 0;
 	     i < dev->limits.num_mtt_segs;
 	     i <<= 1, ++dev->mr_table.max_mtt_order)
-		/* nothing */ ;
+		; /* nothing */
 
 	dev->mr_table.mtt_buddy = kmalloc((dev->mr_table.max_mtt_order + 1) *
 					  sizeof (long *),
diff -Nru a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c
--- a/drivers/infiniband/hw/mthca/mthca_profile.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_profile.c	2005-01-19 13:44:48 -08:00
@@ -37,32 +37,34 @@
 
 #include "mthca_profile.h"
 
-static int default_profile[MTHCA_RES_NUM] = {
-	[MTHCA_RES_QP]    = 1 << 16,
-	[MTHCA_RES_EQP]   = 1 << 16,
-	[MTHCA_RES_CQ]    = 1 << 16,
-	[MTHCA_RES_EQ]    = 32,
-	[MTHCA_RES_RDB]   = 1 << 18,
-	[MTHCA_RES_MCG]   = 1 << 13,
-	[MTHCA_RES_MPT]   = 1 << 17,
-	[MTHCA_RES_MTT]   = 1 << 20,
-	[MTHCA_RES_UDAV]  = 1 << 15
-};
-
 enum {
-	MTHCA_RDB_ENTRY_SIZE = 32,
-	MTHCA_MTT_SEG_SIZE   = 64
+	MTHCA_RES_QP,
+	MTHCA_RES_EEC,
+	MTHCA_RES_SRQ,
+	MTHCA_RES_CQ,
+	MTHCA_RES_EQP,
+	MTHCA_RES_EEEC,
+	MTHCA_RES_EQ,
+	MTHCA_RES_RDB,
+	MTHCA_RES_MCG,
+	MTHCA_RES_MPT,
+	MTHCA_RES_MTT,
+	MTHCA_RES_UAR,
+	MTHCA_RES_UDAV,
+	MTHCA_RES_UARC,
+	MTHCA_RES_NUM
 };
 
 enum {
+	MTHCA_NUM_EQS = 32,
 	MTHCA_NUM_PDS = 1 << 15
 };
 
 int mthca_make_profile(struct mthca_dev *dev,
+		       struct mthca_profile *request,
 		       struct mthca_dev_lim *dev_lim,
 		       struct mthca_init_hca_param *init_hca)
 {
-	/* just use default profile for now */
 	struct mthca_resource {
 		u64 size;
 		u64 start;
@@ -71,17 +73,18 @@
 		int log_num;
 	};
 
+	u64 mem_base, mem_avail;
 	u64 total_size = 0;
 	struct mthca_resource *profile;
 	struct mthca_resource tmp;
 	int i, j;
 
-	default_profile[MTHCA_RES_UAR] = dev_lim->uar_size / PAGE_SIZE;
-
 	profile = kmalloc(MTHCA_RES_NUM * sizeof *profile, GFP_KERNEL);
 	if (!profile)
 		return -ENOMEM;
 
+	memset(profile, 0, MTHCA_RES_NUM * sizeof *profile);
+
 	profile[MTHCA_RES_QP].size   = dev_lim->qpc_entry_sz;
 	profile[MTHCA_RES_EEC].size  = dev_lim->eec_entry_sz;
 	profile[MTHCA_RES_SRQ].size  = dev_lim->srq_entry_sz;
@@ -91,16 +94,36 @@
 	profile[MTHCA_RES_EQ].size   = dev_lim->eqc_entry_sz;
 	profile[MTHCA_RES_RDB].size  = MTHCA_RDB_ENTRY_SIZE;
 	profile[MTHCA_RES_MCG].size  = MTHCA_MGM_ENTRY_SIZE;
-	profile[MTHCA_RES_MPT].size  = MTHCA_MPT_ENTRY_SIZE;
-	profile[MTHCA_RES_MTT].size  = MTHCA_MTT_SEG_SIZE;
+	profile[MTHCA_RES_MPT].size  = dev_lim->mpt_entry_sz;
+	profile[MTHCA_RES_MTT].size  = dev_lim->mtt_seg_sz;
 	profile[MTHCA_RES_UAR].size  = dev_lim->uar_scratch_entry_sz;
 	profile[MTHCA_RES_UDAV].size = MTHCA_AV_SIZE;
+	profile[MTHCA_RES_UARC].size = request->uarc_size;
+
+	profile[MTHCA_RES_QP].num    = request->num_qp;
+	profile[MTHCA_RES_EQP].num   = request->num_qp;
+	profile[MTHCA_RES_RDB].num   = request->num_qp * request->rdb_per_qp;
+	profile[MTHCA_RES_CQ].num    = request->num_cq;
+	profile[MTHCA_RES_EQ].num    = MTHCA_NUM_EQS;
+	profile[MTHCA_RES_MCG].num   = request->num_mcg;
+	profile[MTHCA_RES_MPT].num   = request->num_mpt;
+	profile[MTHCA_RES_MTT].num   = request->num_mtt;
+	profile[MTHCA_RES_UAR].num   = request->num_uar;
+	profile[MTHCA_RES_UARC].num  = request->num_uar;
+	profile[MTHCA_RES_UDAV].num  = request->num_udav;
 
 	for (i = 0; i < MTHCA_RES_NUM; ++i) {
 		profile[i].type     = i;
-		profile[i].num      = default_profile[i];
-		profile[i].log_num  = max(ffs(default_profile[i]) - 1, 0);
-		profile[i].size    *= default_profile[i];
+		profile[i].log_num  = max(ffs(profile[i].num) - 1, 0);
+		profile[i].size    *= profile[i].num;
+	}
+
+	if (dev->hca_type == ARBEL_NATIVE) {
+		mem_base  = 0;
+		mem_avail = dev_lim->hca.arbel.max_icm_sz;
+	} else {
+		mem_base  = dev->ddr_start;
+		mem_avail = dev->fw.tavor.fw_start - dev->ddr_start;
 	}
 
 	/*
@@ -120,16 +143,14 @@
 
 	for (i = 0; i < MTHCA_RES_NUM; ++i) {
 		if (profile[i].size) {
-			profile[i].start = dev->ddr_start + total_size;
+			profile[i].start = mem_base + total_size;
 			total_size      += profile[i].size;
 		}
-		if (total_size > dev->fw.tavor.fw_start - dev->ddr_start) {
+		if (total_size > mem_avail) {
 			mthca_err(dev, "Profile requires 0x%llx bytes; "
-				  "won't fit between DDR start at 0x%016llx "
-				  "and FW start at 0x%016llx.\n",
+				  "won't in 0x%llx bytes of context memory.\n",
 				  (unsigned long long) total_size,
-				  (unsigned long long) dev->ddr_start,
-				  (unsigned long long) dev->fw.tavor.fw_start);
+				  (unsigned long long) mem_avail);
 			kfree(profile);
 			return -ENOMEM;
 		}
@@ -142,10 +163,13 @@
 				  (unsigned long long) profile[i].size);
 	}
 
-	mthca_dbg(dev, "HCA memory: allocated %d KB/%d KB (%d KB free)\n",
-		  (int) (total_size >> 10),
-		  (int) ((dev->fw.tavor.fw_start - dev->ddr_start) >> 10),
-		  (int) ((dev->fw.tavor.fw_start - dev->ddr_start - total_size) >> 10));
+	if (dev->hca_type == ARBEL_NATIVE)
+		mthca_dbg(dev, "HCA context memory: reserving %d KB\n",
+			  (int) (total_size >> 10));
+	else
+		mthca_dbg(dev, "HCA memory: allocated %d KB/%d KB (%d KB free)\n",
+			  (int) (total_size >> 10), (int) (mem_avail >> 10),
+			  (int) ((mem_avail - total_size) >> 10));
 
 	for (i = 0; i < MTHCA_RES_NUM; ++i) {
 		switch (profile[i].type) {
@@ -181,8 +205,13 @@
 			init_hca->log_num_eqs = profile[i].log_num;
 			break;
 		case MTHCA_RES_RDB:
-			dev->limits.num_rdbs = profile[i].num;
-			init_hca->rdb_base   = profile[i].start;
+			for (dev->qp_table.rdb_shift = 0;
+			     profile[MTHCA_RES_QP].num << dev->qp_table.rdb_shift <
+				     profile[i].num;
+			     ++dev->qp_table.rdb_shift)
+				; /* nothing */
+			dev->qp_table.rdb_base    = (u32) profile[i].start;
+			init_hca->rdb_base        = profile[i].start;
 			break;
 		case MTHCA_RES_MCG:
 			dev->limits.num_mgms      = profile[i].num >> 1;
@@ -199,10 +228,10 @@
 			break;
 		case MTHCA_RES_MTT:
 			dev->limits.num_mtt_segs = profile[i].num;
-			dev->limits.mtt_seg_size = MTHCA_MTT_SEG_SIZE;
+			dev->limits.mtt_seg_size = dev_lim->mtt_seg_sz;
 			dev->mr_table.mtt_base   = profile[i].start;
 			init_hca->mtt_base       = profile[i].start;
-			init_hca->mtt_seg_sz     = ffs(MTHCA_MTT_SEG_SIZE) - 7;
+			init_hca->mtt_seg_sz     = ffs(dev_lim->mtt_seg_sz) - 7;
 			break;
 		case MTHCA_RES_UAR:
 			init_hca->uar_scratch_base = profile[i].start;
diff -Nru a/drivers/infiniband/hw/mthca/mthca_profile.h b/drivers/infiniband/hw/mthca/mthca_profile.h
--- a/drivers/infiniband/hw/mthca/mthca_profile.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_profile.h	2005-01-19 13:44:47 -08:00
@@ -38,24 +38,20 @@
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
 
-enum {
-	MTHCA_RES_QP,
-	MTHCA_RES_EEC,
-	MTHCA_RES_SRQ,
-	MTHCA_RES_CQ,
-	MTHCA_RES_EQP,
-	MTHCA_RES_EEEC,
-	MTHCA_RES_EQ,
-	MTHCA_RES_RDB,
-	MTHCA_RES_MCG,
-	MTHCA_RES_MPT,
-	MTHCA_RES_MTT,
-	MTHCA_RES_UAR,
-	MTHCA_RES_UDAV,
-	MTHCA_RES_NUM
+struct mthca_profile {
+	int num_qp;
+	int rdb_per_qp;
+	int num_cq;
+	int num_mcg;
+	int num_mpt;
+	int num_mtt;
+	int num_udav;
+	int num_uar;
+	int uarc_size;
 };
 
 int mthca_make_profile(struct mthca_dev *mdev,
+		       struct mthca_profile *request,
 		       struct mthca_dev_lim *dev_lim,
 		       struct mthca_init_hca_param *init_hca);
 
diff -Nru a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
--- a/drivers/infiniband/hw/mthca/mthca_provider.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -119,6 +119,7 @@
 	props->sm_lid            = be16_to_cpup((u16 *) (out_mad->data + 18));
 	props->sm_sl             = out_mad->data[36] & 0xf;
 	props->state             = out_mad->data[32] & 0xf;
+	props->phys_state        = out_mad->data[33] >> 4;
 	props->port_cap_flags    = be32_to_cpup((u32 *) (out_mad->data + 20));
 	props->gid_tbl_len       = to_mdev(ibdev)->limits.gid_table_len;
 	props->pkey_tbl_len      = to_mdev(ibdev)->limits.pkey_table_len;
diff -Nru a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
--- a/drivers/infiniband/hw/mthca/mthca_provider.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h	2005-01-19 13:44:46 -08:00
@@ -162,9 +162,12 @@
 	spinlock_t             lock;
 	atomic_t               refcount;
 	u32                    qpn;
-	int                    transport;
-	enum ib_qp_state       state;
 	int                    is_direct;
+	u8                     transport;
+	u8                     state;
+	u8                     atomic_rd_en;
+	u8                     resp_depth;
+
 	struct mthca_mr        mr;
 
 	struct mthca_wq        rq;
diff -Nru a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
--- a/drivers/infiniband/hw/mthca/mthca_qp.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c	2005-01-19 13:44:46 -08:00
@@ -146,7 +146,7 @@
 	MTHCA_QP_OPTPAR_ALT_ADDR_PATH     = 1 << 0,
 	MTHCA_QP_OPTPAR_RRE               = 1 << 1,
 	MTHCA_QP_OPTPAR_RAE               = 1 << 2,
-	MTHCA_QP_OPTPAR_REW               = 1 << 3,
+	MTHCA_QP_OPTPAR_RWE               = 1 << 3,
 	MTHCA_QP_OPTPAR_PKEY_INDEX        = 1 << 4,
 	MTHCA_QP_OPTPAR_Q_KEY             = 1 << 5,
 	MTHCA_QP_OPTPAR_RNR_TIMEOUT       = 1 << 6,
@@ -697,13 +697,86 @@
 		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RETRY_COUNT);
 	}
 
-	/* XXX initiator resources */
+	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
+		qp_context->params1 |= cpu_to_be32(min(attr->max_dest_rd_atomic ?
+						       ffs(attr->max_dest_rd_atomic) - 1 : 0,
+						       7) << 21);
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX);
+	}
 
 	if (attr_mask & IB_QP_SQ_PSN)
 		qp_context->next_send_psn = cpu_to_be32(attr->sq_psn);
 	qp_context->cqn_snd = cpu_to_be32(to_mcq(ibqp->send_cq)->cqn);
 
-	/* XXX RDMA/atomic enable, responder resources */
+	if (attr_mask & IB_QP_ACCESS_FLAGS) {
+		/*
+		 * Only enable RDMA/atomics if we have responder
+		 * resources set to a non-zero value.
+		 */
+		if (qp->resp_depth) {
+			qp_context->params2 |=
+				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
+					    MTHCA_QP_BIT_RWE : 0);
+			qp_context->params2 |=
+				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
+					    MTHCA_QP_BIT_RRE : 0);
+			qp_context->params2 |=
+				cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC ?
+					    MTHCA_QP_BIT_RAE : 0);
+		}
+
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
+							MTHCA_QP_OPTPAR_RRE |
+							MTHCA_QP_OPTPAR_RAE);
+
+		qp->atomic_rd_en = attr->qp_access_flags;
+	}
+
+	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
+		u8 rra_max;
+
+		if (qp->resp_depth && !attr->max_rd_atomic) {
+			/*
+			 * Lowering our responder resources to zero.
+			 * Turn off RDMA/atomics as responder.
+			 * (RWE/RRE/RAE in params2 already zero)
+			 */
+			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
+								MTHCA_QP_OPTPAR_RRE |
+								MTHCA_QP_OPTPAR_RAE);
+		}
+
+		if (!qp->resp_depth && attr->max_rd_atomic) {
+			/*
+			 * Increasing our responder resources from
+			 * zero.  Turn on RDMA/atomics as appropriate.
+			 */
+			qp_context->params2 |=
+				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_WRITE ?
+					    MTHCA_QP_BIT_RWE : 0);
+			qp_context->params2 |=
+				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?
+					    MTHCA_QP_BIT_RRE : 0);
+			qp_context->params2 |=
+				cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?
+					    MTHCA_QP_BIT_RAE : 0);
+
+			qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
+								MTHCA_QP_OPTPAR_RRE |
+								MTHCA_QP_OPTPAR_RAE);
+		}
+
+		for (rra_max = 0;
+		     1 << rra_max < attr->max_rd_atomic &&
+			     rra_max < dev->qp_table.rdb_shift;
+		     ++rra_max)
+			; /* nothing */
+
+		qp_context->params2      |= cpu_to_be32(rra_max << 21);
+		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX);
+
+		qp->resp_depth = attr->max_rd_atomic;
+	}
 
 	if (qp->rq.policy == IB_SIGNAL_ALL_WR)
 		qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC);
@@ -714,7 +787,9 @@
 	if (attr_mask & IB_QP_RQ_PSN)
 		qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->rq_psn);
 
-	/* XXX ra_buff_indx */
+	qp_context->ra_buff_indx = dev->qp_table.rdb_base +
+		((qp->qpn & (dev->limits.num_qps - 1)) * MTHCA_RDB_ENTRY_SIZE <<
+		 dev->qp_table.rdb_shift);
 
 	qp_context->cqn_rcv = cpu_to_be32(to_mcq(ibqp->recv_cq)->cqn);
 
@@ -910,6 +985,8 @@
 	spin_lock_init(&qp->lock);
 	atomic_set(&qp->refcount, 1);
 	qp->state    	 = IB_QPS_RESET;
+	qp->atomic_rd_en = 0;
+	qp->resp_depth   = 0;
 	qp->sq.policy    = send_policy;
 	qp->rq.policy    = recv_policy;
 	qp->rq.cur       = 0;
@@ -1113,11 +1190,11 @@
 		sqp->ud_header.lrh.source_lid = 0xffff;
 	sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED);
 	if (!sqp->qp.ibqp.qp_num)
-		ib_cached_pkey_get(&dev->ib_dev, sqp->port,
+		ib_get_cached_pkey(&dev->ib_dev, sqp->port,
 				   sqp->pkey_index,
 				   &sqp->ud_header.bth.pkey);
 	else
-		ib_cached_pkey_get(&dev->ib_dev, sqp->port,
+		ib_get_cached_pkey(&dev->ib_dev, sqp->port,
 				   wr->wr.ud.pkey_index,
 				   &sqp->ud_header.bth.pkey);
 	cpu_to_be16s(&sqp->ud_header.bth.pkey);
diff -Nru a/drivers/infiniband/include/ib_cache.h b/drivers/infiniband/include/ib_cache.h
--- a/drivers/infiniband/include/ib_cache.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/include/ib_cache.h	2005-01-19 13:44:46 -08:00
@@ -37,16 +37,66 @@
 
 #include <ib_verbs.h>
 
-int ib_cached_gid_get(struct ib_device    *device,
-		      u8                   port,
+/**
+ * ib_get_cached_gid - Returns a cached GID table entry
+ * @device: The device to query.
+ * @port_num: The port number of the device to query.
+ * @index: The index into the cached GID table to query.
+ * @gid: The GID value found at the specified index.
+ *
+ * ib_get_cached_gid() fetches the specified GID table entry stored in
+ * the local software cache.
+ */
+int ib_get_cached_gid(struct ib_device    *device,
+		      u8                   port_num,
 		      int                  index,
 		      union ib_gid        *gid);
-int ib_cached_pkey_get(struct ib_device    *device_handle,
-		       u8                   port,
+
+/**
+ * ib_find_cached_gid - Returns the port number and GID table index where
+ *   a specified GID value occurs.
+ * @device: The device to query.
+ * @gid: The GID value to search for.
+ * @port_num: The port number of the device where the GID value was found.
+ * @index: The index into the cached GID table where the GID was found.  This
+ *   parameter may be NULL.
+ *
+ * ib_find_cached_gid() searches for the specified GID value in
+ * the local software cache.
+ */
+int ib_find_cached_gid(struct ib_device *device,
+		       union ib_gid	*gid,
+		       u8               *port_num,
+		       u16              *index);
+
+/**
+ * ib_get_cached_pkey - Returns a cached PKey table entry
+ * @device: The device to query.
+ * @port_num: The port number of the device to query.
+ * @index: The index into the cached PKey table to query.
+ * @pkey: The PKey value found at the specified index.
+ *
+ * ib_get_cached_pkey() fetches the specified PKey table entry stored in
+ * the local software cache.
+ */
+int ib_get_cached_pkey(struct ib_device    *device_handle,
+		       u8                   port_num,
 		       int                  index,
 		       u16                 *pkey);
-int ib_cached_pkey_find(struct ib_device    *device,
-			u8                   port,
+
+/**
+ * ib_find_cached_pkey - Returns the PKey table index where a specified
+ *   PKey value occurs.
+ * @device: The device to query.
+ * @port_num: The port number of the device to search for the PKey.
+ * @pkey: The PKey value to search for.
+ * @index: The index into the cached PKey table where the PKey was found.
+ *
+ * ib_find_cached_pkey() searches the specified PKey table in
+ * the local software cache.
+ */
+int ib_find_cached_pkey(struct ib_device    *device,
+			u8                   port_num,
 			u16                  pkey,
 			u16                 *index);
 
diff -Nru a/drivers/infiniband/include/ib_sa.h b/drivers/infiniband/include/ib_sa.h
--- a/drivers/infiniband/include/ib_sa.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/include/ib_sa.h	2005-01-19 13:44:47 -08:00
@@ -59,6 +59,34 @@
 	IB_SA_BEST = 3
 };
 
+enum ib_sa_rate {
+	IB_SA_RATE_2_5_GBPS = 2,
+	IB_SA_RATE_5_GBPS   = 5,
+	IB_SA_RATE_10_GBPS  = 3,
+	IB_SA_RATE_20_GBPS  = 6,
+	IB_SA_RATE_30_GBPS  = 4,
+	IB_SA_RATE_40_GBPS  = 7,
+	IB_SA_RATE_60_GBPS  = 8,
+	IB_SA_RATE_80_GBPS  = 9,
+	IB_SA_RATE_120_GBPS = 10
+};
+
+static inline int ib_sa_rate_enum_to_int(enum ib_sa_rate rate)
+{
+	switch (rate) {
+	case IB_SA_RATE_2_5_GBPS: return  1;
+	case IB_SA_RATE_5_GBPS:   return  2;
+	case IB_SA_RATE_10_GBPS:  return  4;
+	case IB_SA_RATE_20_GBPS:  return  8;
+	case IB_SA_RATE_30_GBPS:  return 12;
+	case IB_SA_RATE_40_GBPS:  return 16;
+	case IB_SA_RATE_60_GBPS:  return 24;
+	case IB_SA_RATE_80_GBPS:  return 32;
+	case IB_SA_RATE_120_GBPS: return 48;
+	default: 	          return -1;
+	}
+}
+
 typedef u64 __bitwise ib_sa_comp_mask;
 
 #define IB_SA_COMP_MASK(n)	((__force ib_sa_comp_mask) cpu_to_be64(1ull << n))
diff -Nru a/drivers/infiniband/include/ib_verbs.h b/drivers/infiniband/include/ib_verbs.h
--- a/drivers/infiniband/include/ib_verbs.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/include/ib_verbs.h	2005-01-19 13:44:46 -08:00
@@ -212,6 +212,7 @@
 	u8			init_type_reply;
 	u8			active_width;
 	u8			active_speed;
+	u8                      phys_state;
 };
 
 enum ib_device_modify_flags {
@@ -352,6 +353,7 @@
 	u32			vendor_err;
 	u32			byte_len;
 	__be32			imm_data;
+	u32			qp_num;
 	u32			src_qp;
 	int			wc_flags;
 	u16			pkey_index;
@@ -657,6 +659,7 @@
 	void                  (*event_handler)(struct ib_event *, void *);
 	void		       *qp_context;
 	u32			qp_num;
+	enum ib_qp_type		qp_type;
 };
 
 struct ib_mr {
@@ -682,9 +685,12 @@
 };
 
 struct ib_mad;
+struct ib_grh;
 
 enum ib_process_mad_flags {
-	IB_MAD_IGNORE_MKEY	= 1
+	IB_MAD_IGNORE_MKEY	= 1,
+	IB_MAD_IGNORE_BKEY	= 2,
+	IB_MAD_IGNORE_ALL	= IB_MAD_IGNORE_MKEY | IB_MAD_IGNORE_BKEY
 };
 
 enum ib_mad_result {
@@ -810,7 +816,8 @@
 	int                        (*process_mad)(struct ib_device *device,
 						  int process_mad_flags,
 						  u8 port_num,
-						  u16 source_lid,
+						  struct ib_wc *in_wc,
+						  struct ib_grh *in_grh,
 						  struct ib_mad *in_mad,
 						  struct ib_mad *out_mad);
 
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
--- a/drivers/infiniband/ulp/ipoib/ipoib.h	2005-01-19 13:44:45 -08:00
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h	2005-01-19 13:44:45 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -143,16 +143,19 @@
 
 	union ib_gid local_gid;
 	u16          local_lid;
+	u8           local_rate;
 
 	unsigned int admin_mtu;
 	unsigned int mcast_mtu;
 
 	struct ipoib_buf *rx_ring;
 
-	spinlock_t tx_lock;
+	spinlock_t        tx_lock;
 	struct ipoib_buf *tx_ring;
-	unsigned tx_head;
-	unsigned tx_tail;
+	unsigned          tx_head;
+	unsigned          tx_tail;
+	struct ib_sge     tx_sge;
+	struct ib_send_wr tx_wr;
 
 	struct ib_wc ibwc[IPOIB_NUM_WC];
 
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2005-01-19 13:44:48 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -281,28 +281,16 @@
 			    struct ib_ah *address, u32 qpn,
 			    dma_addr_t addr, int len)
 {
-	struct ib_sge list = {
-		.addr    = addr,
-		.length  = len,
-		.lkey    = priv->mr->lkey,
-	};
-	struct ib_send_wr param = {
-		.wr_id = wr_id,
-		.opcode = IB_WR_SEND,
-		.sg_list = &list,
-		.num_sge = 1,
-		.wr = {
-			.ud = {
-				 .remote_qpn = qpn,
-				 .remote_qkey = priv->qkey,
-				 .ah = address
-			 },
-		},
-		.send_flags = IB_SEND_SIGNALED,
-	};
 	struct ib_send_wr *bad_wr;
 
-	return ib_post_send(priv->qp, &param, &bad_wr);
+	priv->tx_sge.addr             = addr;
+	priv->tx_sge.length           = len;
+
+	priv->tx_wr.wr_id 	      = wr_id;
+	priv->tx_wr.wr.ud.remote_qpn  = qpn;
+	priv->tx_wr.wr.ud.ah 	      = address;
+
+	return ib_post_send(priv->qp, &priv->tx_wr, &bad_wr);
 }
 
 void ipoib_send(struct net_device *dev, struct sk_buff *skb,
@@ -357,7 +345,7 @@
 	}
 }
 
-void __ipoib_reap_ah(struct net_device *dev)
+static void __ipoib_reap_ah(struct net_device *dev)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ipoib_ah *ah, *tah;
@@ -630,7 +618,7 @@
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	u16 pkey_index = 0;
 
-	if (ib_cached_pkey_find(priv->ca, priv->port, priv->pkey, &pkey_index))
+	if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index))
 		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
 	else
 		set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c	2005-01-19 13:44:46 -08:00
@@ -283,21 +283,21 @@
 	skb_queue_head_init(&skqueue);
 
 	if (!status) {
-		/*
-		 * For now we set static_rate to 0.  This is not
-		 * really correct: we should look at the rate
-		 * component of the path member record, compare it
-		 * with the rate of our local port (calculated from
-		 * the active link speed and link width) and set an
-		 * inter-packet delay appropriately.
-		 */
 		struct ib_ah_attr av = {
 			.dlid 	       = be16_to_cpu(pathrec->dlid),
 			.sl 	       = pathrec->sl,
-			.static_rate   = 0,
 			.port_num      = priv->port
 		};
 
+		if (ib_sa_rate_enum_to_int(pathrec->rate) > 0)
+			av.static_rate = (2 * priv->local_rate -
+					  ib_sa_rate_enum_to_int(pathrec->rate) - 1) /
+				(priv->local_rate ? priv->local_rate : 1);
+
+		ipoib_dbg(priv, "static_rate %d for local port %dX, path %dX\n",
+			  av.static_rate, priv->local_rate,
+			  ib_sa_rate_enum_to_int(pathrec->rate));
+
 		ah = ipoib_create_ah(dev, priv->pd, &av);
 	}
 
@@ -606,7 +606,7 @@
 	return NETDEV_TX_OK;
 }
 
-struct net_device_stats *ipoib_get_stats(struct net_device *dev)
+static struct net_device_stats *ipoib_get_stats(struct net_device *dev)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -44,7 +44,7 @@
 #include "ipoib.h"
 
 #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
-int mcast_debug_level;
+static int mcast_debug_level;
 
 module_param(mcast_debug_level, int, 0644);
 MODULE_PARM_DESC(mcast_debug_level,
@@ -213,8 +213,10 @@
 
 	/* Set the cached Q_Key before we attach if it's the broadcast group */
 	if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4,
-		    sizeof (union ib_gid)))
+		    sizeof (union ib_gid))) {
 		priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey);
+		priv->tx_wr.wr.ud.remote_qkey = priv->qkey;
+	}
 
 	if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
 		if (test_and_set_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
@@ -238,19 +240,10 @@
 	}
 
 	{
-		/*
-		 * For now we set static_rate to 0.  This is not
-		 * really correct: we should look at the rate
-		 * component of the MC member record, compare it with
-		 * the rate of our local port (calculated from the
-		 * active link speed and link width) and set an
-		 * inter-packet delay appropriately.
-		 */
 		struct ib_ah_attr av = {
 			.dlid	       = be16_to_cpu(mcast->mcmember.mlid),
 			.port_num      = priv->port,
 			.sl	       = mcast->mcmember.sl,
-			.static_rate   = 0,
 			.ah_flags      = IB_AH_GRH,
 			.grh	       = {
 				.flow_label    = be32_to_cpu(mcast->mcmember.flow_label),
@@ -262,6 +255,15 @@
 
 		av.grh.dgid = mcast->mcmember.mgid;
 
+		if (ib_sa_rate_enum_to_int(mcast->mcmember.rate) > 0)
+			av.static_rate = (2 * priv->local_rate -
+					  ib_sa_rate_enum_to_int(mcast->mcmember.rate) - 1) /
+				(priv->local_rate ? priv->local_rate : 1);
+
+		ipoib_dbg_mcast(priv, "static_rate %d for local port %dX, mcmember %dX\n",
+				av.static_rate, priv->local_rate,
+				ib_sa_rate_enum_to_int(mcast->mcmember.rate));
+
 		mcast->ah = ipoib_create_ah(dev, priv->pd, &av);
 		if (!mcast->ah) {
 			ipoib_warn(priv, "ib_address_create failed\n");
@@ -506,6 +508,17 @@
 	else
 		memcpy(priv->dev->dev_addr + 4, priv->local_gid.raw, sizeof (union ib_gid));
 
+	{
+		struct ib_port_attr attr;
+
+		if (!ib_query_port(priv->ca, priv->port, &attr)) {
+			priv->local_lid  = attr.lid;
+			priv->local_rate = attr.active_speed *
+				ib_width_enum_to_int(attr.active_width);
+		} else
+			ipoib_warn(priv, "ib_query_port failed\n");
+	}
+
 	if (!priv->broadcast) {
 		priv->broadcast = ipoib_mcast_alloc(dev, 1);
 		if (!priv->broadcast) {
@@ -554,15 +567,6 @@
 		return;
 	}
 
-	{
-		struct ib_port_attr attr;
-
-		if (!ib_query_port(priv->ca, priv->port, &attr))
-			priv->local_lid = attr.lid;
-		else
-			ipoib_warn(priv, "ib_query_port failed\n");
-	}
-
 	priv->mcast_mtu = ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu) -
 		IPOIB_ENCAP_LEN;
 	dev->mtu = min(priv->mcast_mtu, priv->admin_mtu);
@@ -621,7 +625,7 @@
 	return 0;
 }
 
-int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
+static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ib_sa_mcmember_rec rec = {
diff -Nru a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -49,7 +49,7 @@
 	if (!qp_attr)
 		goto out;
 
-	if (ib_cached_pkey_find(priv->ca, priv->port, priv->pkey, &pkey_index)) {
+	if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) {
 		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
 		ret = -ENXIO;
 		goto out;
@@ -104,7 +104,7 @@
 	 * The port has to be assigned to the respective IB partition in
 	 * advance.
 	 */
-	ret = ib_cached_pkey_find(priv->ca, priv->port, priv->pkey, &pkey_index);
+	ret = ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index);
 	if (ret) {
 		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
 		return ret;
@@ -187,7 +187,7 @@
 
 	priv->mr = ib_get_dma_mr(priv->pd, IB_ACCESS_LOCAL_WRITE);
 	if (IS_ERR(priv->mr)) {
-		printk(KERN_WARNING "%s: ib_reg_phys_mr failed\n", ca->name);
+		printk(KERN_WARNING "%s: ib_get_dma_mr failed\n", ca->name);
 		goto out_free_cq;
 	}
 
@@ -203,6 +203,13 @@
 	priv->dev->dev_addr[1] = (priv->qp->qp_num >> 16) & 0xff;
 	priv->dev->dev_addr[2] = (priv->qp->qp_num >>  8) & 0xff;
 	priv->dev->dev_addr[3] = (priv->qp->qp_num      ) & 0xff;
+
+	priv->tx_sge.lkey 	= priv->mr->lkey;
+
+	priv->tx_wr.opcode 	= IB_WR_SEND;
+	priv->tx_wr.sg_list 	= &priv->tx_sge;
+	priv->tx_wr.num_sge 	= 1;
+	priv->tx_wr.send_flags 	= IB_SEND_SIGNALED;
 
 	return 0;
 
diff -Nru a/drivers/input/Kconfig b/drivers/input/Kconfig
--- a/drivers/input/Kconfig	2005-01-19 13:44:45 -08:00
+++ b/drivers/input/Kconfig	2005-01-19 13:44:45 -08:00
@@ -32,7 +32,7 @@
 	  Say Y here if you want your mouse to be accessible as char devices
 	  13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an
 	  emulated IntelliMouse Explorer PS/2 mouse. That way, all user space
-	  programs (includung SVGAlib, GPM and X) will be able to use your
+	  programs (including SVGAlib, GPM and X) will be able to use your
 	  mouse.
 
 	  If unsure, say Y.
diff -Nru a/drivers/input/input.c b/drivers/input/input.c
--- a/drivers/input/input.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/input/input.c	2005-01-19 13:44:46 -08:00
@@ -69,7 +69,7 @@
 	if (type > EV_MAX || !test_bit(type, dev->evbit))
 		return;
 
-	add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value);
+	add_input_randomness(type, code, value);
 
 	switch (type) {
 
diff -Nru a/drivers/input/joystick/iforce/Kconfig b/drivers/input/joystick/iforce/Kconfig
--- a/drivers/input/joystick/iforce/Kconfig	2005-01-19 13:44:48 -08:00
+++ b/drivers/input/joystick/iforce/Kconfig	2005-01-19 13:44:48 -08:00
@@ -27,5 +27,6 @@
 	  connected to your serial (COM) port.
 
 	  You will need an additional utility called inputattach, see
-	  Documentation/input/joystick.txt and ff.txt.
+	  <file:Documentation/input/joystick.txt>
+	  and <file:Documentation/input/ff.txt>.
 
diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
--- a/drivers/input/misc/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/input/misc/Kconfig	2005-01-19 13:44:46 -08:00
@@ -5,7 +5,6 @@
 	bool "Misc"
 	depends on INPUT
 	help
-
 	  Say Y here, and a list of miscellaneous input drivers will be displayed.
 	  Everything that didn't fit into the other categories is here. This option
 	  doesn't affect the kernel.
diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
--- a/drivers/input/mouse/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/input/mouse/Kconfig	2005-01-19 13:44:47 -08:00
@@ -27,9 +27,9 @@
 
 	  Synaptics TouchPad users might be interested in a specialized
 	  XFree86 driver at:
-		http://w1.894.telia.com/~u89404340/touchpad/index.html
-	  and a new verion of GPM at:
-		http://www.geocities.com/dt_or/gpm/gpm.html
+		<http://w1.894.telia.com/~u89404340/touchpad/index.html>
+	  and a new version of GPM at:
+		<http://www.geocities.com/dt_or/gpm/gpm.html>
 	  to take advantage of the advanced features of the touchpad.
 
 	  If unsure, say Y.
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/input/serio/serio.c	2005-01-19 13:44:45 -08:00
@@ -34,7 +34,6 @@
 #include <linux/completion.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
-#include <linux/suspend.h>
 #include <linux/slab.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
@@ -225,8 +224,7 @@
 	do {
 		serio_handle_events();
 		wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 	} while (!signal_pending(current));
 
 	printk(KERN_DEBUG "serio: kseriod exiting\n");
diff -Nru a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
--- a/drivers/isdn/hardware/avm/avm_cs.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/isdn/hardware/avm/avm_cs.c	2005-01-19 13:44:45 -08:00
@@ -43,16 +43,6 @@
 
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
-
-/* This means pick from 15, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static int default_irq_list[10] = { 15, 12, 11, 10, 9, 7, 5, 4, 3, -1 };
-static int irq_list[10] = { -1 };
-
-MODULE_PARM(irq_list, "1-10i");
-
-/*====================================================================*/
-
 /*
    The event() function is this driver's Card Services event handler.
    It will be called by Card Services when an appropriate card status
@@ -134,7 +124,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret, i;
+    int ret;
     
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
@@ -151,14 +141,7 @@
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] != -1) {
-	    for (i = 0; i < 10 && irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << irq_list[i];
-    } else {
-	    for (i = 0; i < 10 && default_irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << default_irq_list[i];
-    }
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
diff -Nru a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
--- a/drivers/isdn/hisax/avma1_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/isdn/hisax/avma1_cs.c	2005-01-19 13:44:47 -08:00
@@ -53,11 +53,8 @@
 
 /* Parameters that can be set with 'insmod' */
 
-static int default_irq_list[11] = { 15, 13, 12, 11, 10, 9, 7, 5, 4, 3, -1 };
-static int irq_list[11] = { -1 };
 static int isdnprot = 2;
 
-module_param_array(irq_list, int, NULL, 0);
 module_param(isdnprot, int, 0);
 
 /*====================================================================*/
@@ -143,7 +140,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret, i;
+    int ret;
     
     DEBUG(0, "avma1cs_attach()\n");
 
@@ -173,15 +170,8 @@
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] != -1) {
-	    for (i = 0; i < 10 && irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << irq_list[i];
-    } else {
-	    for (i = 0; i < 10 && default_irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << default_irq_list[i];
-    }
-    
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
diff -Nru a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
--- a/drivers/isdn/hisax/elsa_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/isdn/hisax/elsa_cs.c	2005-01-19 13:44:46 -08:00
@@ -81,16 +81,6 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from, the old way */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, 3 */
-static u_long irq_mask = 0xdeb8;
-
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, ulong, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 static int protocol = 2;        /* EURO-ISDN Default */
 module_param(protocol, int, 0);
 
@@ -187,7 +177,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret, i;
+    int ret;
 
     DEBUG(0, "elsa_cs_attach()\n");
 
@@ -200,12 +190,7 @@
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID|IRQ_SHARE_ID;
-    if (irq_list[0] == -1)
-        link->irq.IRQInfo2 = irq_mask;
-    else
-        for (i = 0; i < 4; i++)
-            link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
     link->irq.Handler = NULL;
 
     /*
diff -Nru a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
--- a/drivers/isdn/hisax/sedlbauer_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/isdn/hisax/sedlbauer_cs.c	2005-01-19 13:44:46 -08:00
@@ -82,15 +82,6 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 static int protocol = 2;        /* EURO-ISDN Default */
 module_param(protocol, int, 0);
 
@@ -195,7 +186,7 @@
     local_info_t *local;
     dev_link_t *link;
     client_reg_t client_reg;
-    int ret, i;
+    int ret;
     
     DEBUG(0, "sedlbauer_attach()\n");
 
@@ -208,14 +199,9 @@
     
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = NULL;
-    
+
     /*
       General socket configuration defaults can go here.  In this
       client, we assume very little, and rely on the CIS for almost
diff -Nru a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
--- a/drivers/isdn/hisax/teles_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/isdn/hisax/teles_cs.c	2005-01-19 13:44:47 -08:00
@@ -62,16 +62,6 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from, the old way */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, 3 */
-static u_long irq_mask = 0xdeb8;
-
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, ulong, 0);
-module_param_array(irq_list, int, NULL, 0);
-
 static int protocol = 2;        /* EURO-ISDN Default */
 module_param(protocol, int, 0);
 
@@ -168,7 +158,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret, i;
+    int ret;
 
     DEBUG(0, "teles_attach()\n");
 
@@ -181,12 +171,7 @@
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID|IRQ_SHARE_ID;
-    if (irq_list[0] == -1)
-        link->irq.IRQInfo2 = irq_mask;
-    else
-        for (i = 0; i < 4; i++)
-            link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
     link->irq.Handler = NULL;
 
     /*
diff -Nru a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig
--- a/drivers/isdn/i4l/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/isdn/i4l/Kconfig	2005-01-19 13:44:46 -08:00
@@ -58,7 +58,7 @@
 	help
 	  If you say Y here, the modem-emulator will support a subset of the
 	  EIA Class 8 Voice commands. Using a getty with voice-support
-	  (mgetty+sendfax by gert@greenie.muc.de with an extension, available
+	  (mgetty+sendfax by <gert@greenie.muc.de> with an extension, available
 	  with the ISDN utility package for example), you will be able to use
 	  your Linux box as an ISDN-answering machine. Of course, this must be
 	  supported by the lowlevel driver also. Currently, the HiSax driver
diff -Nru a/drivers/isdn/tpam/Kconfig b/drivers/isdn/tpam/Kconfig
--- a/drivers/isdn/tpam/Kconfig	2005-01-19 13:44:45 -08:00
+++ b/drivers/isdn/tpam/Kconfig	2005-01-19 13:44:45 -08:00
@@ -11,5 +11,5 @@
 	  to be downloaded into the card using a utility which is distributed
 	  separately from the Auvertech's web site: <http://www.auvertech.fr/>.
 
-	  Please redirect all support questions to support@auvertech.fr.
+	  Please redirect all support questions to <support@auvertech.fr>.
 
diff -Nru a/drivers/md/Kconfig b/drivers/md/Kconfig
--- a/drivers/md/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/md/Kconfig	2005-01-19 13:44:46 -08:00
@@ -200,7 +200,7 @@
 
 	  Information on how to use dm-crypt can be found on
 
-	  http://www.saout.de/misc/dm-crypt/
+	  <http://www.saout.de/misc/dm-crypt/>
 
 	  To compile this code as a module, choose M here: the module will
 	  be called dm-crypt.
diff -Nru a/drivers/media/dvb/dibusb/Kconfig b/drivers/media/dvb/dibusb/Kconfig
--- a/drivers/media/dvb/dibusb/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/media/dvb/dibusb/Kconfig	2005-01-19 13:44:46 -08:00
@@ -6,7 +6,7 @@
 	select DVB_DIB3000MC
 	help
 	  Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
-	  DiBcom (http://www.dibcom.fr).
+	  DiBcom (<http://www.dibcom.fr>).
 
 	  Devices supported by this driver:
 
@@ -27,7 +27,7 @@
 	  These devices can be understood as budget ones, they "only" deliver
 	  (a part of) the MPEG2 transport stream.
 
-	  A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
+	  A firmware is needed to get the device working. See <file:Documentation/dvb/README.dibusb>
 	  details.
 
 	  Say Y if you own such a device and want to use it. You should build it as
diff -Nru a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
--- a/drivers/message/i2o/device.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/message/i2o/device.c	2005-01-19 13:44:47 -08:00
@@ -66,10 +66,11 @@
 
 	rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_CLAIM, I2O_CLAIM_PRIMARY);
 	if (!rc)
-		pr_debug("claim of device %d succeded\n", dev->lct_data.tid);
+		pr_debug("i2o: claim of device %d succeded\n",
+			 dev->lct_data.tid);
 	else
-		pr_debug("claim of device %d failed %d\n", dev->lct_data.tid,
-			 rc);
+		pr_debug("i2o: claim of device %d failed %d\n",
+			 dev->lct_data.tid, rc);
 
 	up(&dev->lock);
 
@@ -111,10 +112,10 @@
 	}
 
 	if (!rc)
-		pr_debug("claim release of device %d succeded\n",
+		pr_debug("i2o: claim release of device %d succeded\n",
 			 dev->lct_data.tid);
 	else
-		pr_debug("claim release of device %d failed %d\n",
+		pr_debug("i2o: claim release of device %d failed %d\n",
 			 dev->lct_data.tid, rc);
 
 	up(&dev->lock);
@@ -133,7 +134,7 @@
 {
 	struct i2o_device *i2o_dev = to_i2o_device(dev);
 
-	pr_debug("Release I2O device %s\n", dev->bus_id);
+	pr_debug("i2o: device %s released\n", dev->bus_id);
 
 	kfree(i2o_dev);
 };
@@ -241,7 +242,7 @@
 
 	i2o_driver_notify_device_add_all(dev);
 
-	pr_debug("I2O device %s added\n", dev->device.bus_id);
+	pr_debug("i2o: device %s added\n", dev->device.bus_id);
 
 	return dev;
 };
@@ -304,7 +305,8 @@
 
 	max = (lct->table_size - 3) / 9;
 
-	pr_debug("LCT has %d entries (LCT size: %d)\n", max, lct->table_size);
+	pr_debug("%s: LCT has %d entries (LCT size: %d)\n", c->name, max,
+		 lct->table_size);
 
 	/* remove devices, which are not in the LCT anymore */
 	list_for_each_entry_safe(dev, tmp, &c->devices, list) {
diff -Nru a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
--- a/drivers/message/i2o/driver.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/message/i2o/driver.c	2005-01-19 13:44:48 -08:00
@@ -76,7 +76,7 @@
 	int rc = 0;
 	unsigned long flags;
 
-	pr_debug("Register driver %s\n", drv->name);
+	pr_debug("i2o: Register driver %s\n", drv->name);
 
 	if (drv->event) {
 		drv->event_queue = create_workqueue(drv->name);
@@ -85,7 +85,8 @@
 			       "for driver %s\n", drv->name);
 			return -EFAULT;
 		}
-		pr_debug("Event queue initialized for driver %s\n", drv->name);
+		pr_debug("i2o: Event queue initialized for driver %s\n",
+			 drv->name);
 	} else
 		drv->event_queue = NULL;
 
@@ -107,7 +108,8 @@
 
 	spin_unlock_irqrestore(&i2o_drivers_lock, flags);
 
-	pr_debug("driver %s gets context id %d\n", drv->name, drv->context);
+	pr_debug("i2o: driver %s gets context id %d\n", drv->name,
+		 drv->context);
 
 	list_for_each_entry(c, &i2o_controllers, list) {
 		struct i2o_device *i2o_dev;
@@ -137,7 +139,7 @@
 	struct i2o_controller *c;
 	unsigned long flags;
 
-	pr_debug("unregister driver %s\n", drv->name);
+	pr_debug("i2o: unregister driver %s\n", drv->name);
 
 	driver_unregister(&drv->driver);
 
@@ -157,7 +159,7 @@
 	if (drv->event_queue) {
 		destroy_workqueue(drv->event_queue);
 		drv->event_queue = NULL;
-		pr_debug("event queue removed for %s\n", drv->name);
+		pr_debug("i2o: event queue removed for %s\n", drv->name);
 	}
 };
 
@@ -186,8 +188,8 @@
 		spin_unlock(&i2o_drivers_lock);
 
 		if (unlikely(!drv)) {
-			printk(KERN_WARNING "i2o: Spurious reply to unknown "
-			       "driver %d\n", context);
+			printk(KERN_WARNING "%s: Spurious reply to unknown "
+			       "driver %d\n", c->name, context);
 			return -EIO;
 		}
 
@@ -233,8 +235,8 @@
 				 " defined!\n", c->name, drv->name);
 		return -EIO;
 	} else
-		printk(KERN_WARNING "i2o: Spurious reply to unknown driver "
-		       "%d\n", readl(&msg->u.s.icntxt));
+		printk(KERN_WARNING "%s: Spurious reply to unknown driver "
+		       "%d\n", c->name, readl(&msg->u.s.icntxt));
 	return -EIO;
 }
 
@@ -336,7 +338,7 @@
 		       ">=2 and <= 64 and a power of 2\n", i2o_max_drivers);
 		i2o_max_drivers = I2O_MAX_DRIVERS;
 	}
-	printk(KERN_INFO "i2o: max_drivers=%d\n", i2o_max_drivers);
+	printk(KERN_INFO "i2o: max drivers = %d\n", i2o_max_drivers);
 
 	i2o_drivers =
 	    kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
diff -Nru a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
--- a/drivers/message/i2o/exec-osm.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/message/i2o/exec-osm.c	2005-01-19 13:44:47 -08:00
@@ -31,6 +31,8 @@
 #include <linux/i2o.h>
 #include <linux/delay.h>
 
+#define OSM_NAME "exec-osm"
+
 struct i2o_driver i2o_exec_driver;
 
 static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
@@ -236,7 +238,8 @@
 
 				dev = &c->pdev->dev;
 
-				pr_debug("timedout reply received!\n");
+				pr_debug("%s: timedout reply received!\n",
+					 c->name);
 				i2o_dma_free(dev, &wait->dma);
 				i2o_exec_wait_free(wait);
 				rc = -1;
@@ -250,7 +253,7 @@
 
 	spin_unlock(&lock);
 
-	pr_debug("i2o: Bogus reply in POST WAIT (tr-context: %08x)!\n",
+	pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
 		 context);
 
 	return -1;
@@ -378,8 +381,8 @@
  */
 static void i2o_exec_event(struct i2o_event *evt)
 {
-	printk(KERN_INFO "Event received from device: %d\n",
-	       evt->i2o_dev->lct_data.tid);
+	osm_info("Event received from device: %d\n",
+		 evt->i2o_dev->lct_data.tid);
 	kfree(evt);
 };
 
@@ -468,7 +471,7 @@
 
 /* Exec OSM driver struct */
 struct i2o_driver i2o_exec_driver = {
-	.name = "exec-osm",
+	.name = OSM_NAME,
 	.reply = i2o_exec_reply,
 	.event = i2o_exec_event,
 	.classes = i2o_exec_class_id,
diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
--- a/drivers/message/i2o/i2o_block.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/message/i2o/i2o_block.c	2005-01-19 13:44:47 -08:00
@@ -61,6 +61,10 @@
 
 #include "i2o_block.h"
 
+#define OSM_NAME	"block-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O Block Device OSM"
+
 static struct i2o_driver i2o_block_driver;
 
 /* global Block OSM request mempool */
@@ -100,8 +104,7 @@
 	struct i2o_device *i2o_dev = to_i2o_device(dev);
 	struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev);
 
-	printk(KERN_INFO "block-osm: Device removed %s\n",
-	       i2o_blk_dev->gd->disk_name);
+	osm_info("Device removed %s\n", i2o_blk_dev->gd->disk_name);
 
 	i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0);
 
@@ -137,7 +140,7 @@
 	writel(I2O_CMD_BLOCK_CFLUSH << 24 | HOST_TID << 12 | dev->lct_data.tid,
 	       &msg->u.head[1]);
 	writel(60 << 16, &msg->body[0]);
-	pr_debug("Flushing...\n");
+	osm_debug("Flushing...\n");
 
 	return i2o_msg_post_wait(dev->iop, m, 60);
 };
@@ -166,7 +169,7 @@
 	       &msg->u.head[1]);
 	writel(-1, &msg->body[0]);
 	writel(0, &msg->body[1]);
-	pr_debug("Mounting...\n");
+	osm_debug("Mounting...\n");
 
 	return i2o_msg_post_wait(dev->iop, m, 2);
 };
@@ -194,7 +197,7 @@
 	writel(I2O_CMD_BLOCK_MLOCK << 24 | HOST_TID << 12 | dev->lct_data.tid,
 	       &msg->u.head[1]);
 	writel(-1, &msg->body[0]);
-	pr_debug("Locking...\n");
+	osm_debug("Locking...\n");
 
 	return i2o_msg_post_wait(dev->iop, m, 2);
 };
@@ -222,7 +225,7 @@
 	writel(I2O_CMD_BLOCK_MUNLOCK << 24 | HOST_TID << 12 | dev->lct_data.tid,
 	       &msg->u.head[1]);
 	writel(media_id, &msg->body[0]);
-	pr_debug("Unlocking...\n");
+	osm_debug("Unlocking...\n");
 
 	return i2o_msg_post_wait(dev->iop, m, 2);
 };
@@ -252,7 +255,7 @@
 	writel(I2O_CMD_BLOCK_POWER << 24 | HOST_TID << 12 | i2o_dev->lct_data.
 	       tid, &msg->u.head[1]);
 	writel(op << 24, &msg->body[0]);
-	pr_debug("Power...\n");
+	osm_debug("Power...\n");
 
 	rc = i2o_msg_post_wait(c, m, 60);
 	if (!rc)
@@ -350,7 +353,7 @@
 
 	/* request is already processed by us, so return */
 	if (req->flags & REQ_SPECIAL) {
-		pr_debug("REQ_SPECIAL already set!\n");
+		osm_debug("REQ_SPECIAL already set!\n");
 		req->flags |= REQ_DONTPREP;
 		return BLKPREP_OK;
 	}
@@ -359,7 +362,7 @@
 	if (!req->special) {
 		ireq = i2o_block_request_alloc();
 		if (unlikely(IS_ERR(ireq))) {
-			pr_debug("unable to allocate i2o_block_request!\n");
+			osm_debug("unable to allocate i2o_block_request!\n");
 			return BLKPREP_DEFER;
 		}
 
@@ -435,7 +438,7 @@
 
 		req = i2o_cntxt_list_get(c, le32_to_cpu(pmsg->u.s.tcntxt));
 		if (unlikely(!req)) {
-			printk(KERN_ERR "block-osm: NULL reply received!\n");
+			osm_err("NULL reply received!\n");
 			return -1;
 		}
 
@@ -465,7 +468,7 @@
 
 	req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
 	if (unlikely(!req)) {
-		printk(KERN_ERR "block-osm: NULL reply received!\n");
+		osm_err("NULL reply received!\n");
 		return -1;
 	}
 
@@ -482,8 +485,7 @@
 		 * goes kaput...
 		 */
 		req->errors++;
-		printk(KERN_WARNING
-		       "I2O Block: Data transfer to deleted device!\n");
+		osm_warn("Data transfer to deleted device!\n");
 		spin_lock_irqsave(q->queue_lock, flags);
 		while (end_that_request_chunk
 		       (req, !req->errors, le32_to_cpu(msg->body[1]))) ;
@@ -537,8 +539,8 @@
 		 *      Don't stick a supertrak100 into cache aggressive modes
 		 */
 
-		printk(KERN_ERR "/dev/%s error: %s", dev->gd->disk_name,
-		       bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]);
+		osm_err("block-osm: /dev/%s error: %s", dev->gd->disk_name,
+			bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]);
 		if (le32_to_cpu(msg->body[0]) & 0x00ff0000)
 			printk(KERN_ERR " - DDM attempted %d retries",
 			       (le32_to_cpu(msg->body[0]) >> 16) & 0x00ff);
@@ -563,14 +565,14 @@
 		i2o_block_sglist_free(ireq);
 		i2o_block_request_free(ireq);
 	} else
-		printk(KERN_ERR "i2o_block: still remaining chunks\n");
+		osm_err("still remaining chunks\n");
 
 	return 1;
 };
 
 static void i2o_block_event(struct i2o_event *evt)
 {
-	printk(KERN_INFO "block-osm: event received\n");
+	osm_info("block-osm: event received\n");
 };
 
 /*
@@ -648,7 +650,7 @@
 
 	i2o_block_device_lock(dev->i2o_dev, -1);
 
-	pr_debug("Ready.\n");
+	osm_debug("Ready.\n");
 
 	return 0;
 };
@@ -877,11 +879,11 @@
 		 (unsigned long)&msg->u.head[0]) >> 2) | SGL_OFFSET_8,
 	       &msg->u.head[0]);
 
-	i2o_msg_post(c, m);
-
 	list_add_tail(&ireq->queue, &dev->open_queue);
 	dev->open_queue_depth++;
 
+	i2o_msg_post(c, m);
+
 	return 0;
 
       context_remove:
@@ -936,7 +938,7 @@
 			INIT_WORK(&dreq->work, i2o_block_delayed_request_fn,
 				  dreq);
 
-			printk(KERN_INFO "block-osm: transfer error\n");
+			osm_info("transfer error\n");
 			if (!queue_delayed_work(i2o_block_driver.event_queue,
 						&dreq->work,
 						I2O_BLOCK_RETRY_TIME))
@@ -977,8 +979,7 @@
 
 	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
-		printk(KERN_ERR "block-osm: Insufficient memory to allocate "
-		       "I2O Block disk.\n");
+		osm_err("Insufficient memory to allocate I2O Block disk.\n");
 		rc = -ENOMEM;
 		goto exit;
 	}
@@ -992,8 +993,7 @@
 	/* allocate a gendisk with 16 partitions */
 	gd = alloc_disk(16);
 	if (!gd) {
-		printk(KERN_ERR "block-osm: Insufficient memory to allocate "
-		       "gendisk.\n");
+		osm_err("Insufficient memory to allocate gendisk.\n");
 		rc = -ENOMEM;
 		goto cleanup_dev;
 	}
@@ -1001,8 +1001,7 @@
 	/* initialize the request queue */
 	queue = blk_init_queue(i2o_block_request_fn, &dev->lock);
 	if (!queue) {
-		printk(KERN_ERR "block-osm: Insufficient memory to allocate "
-		       "request queue.\n");
+		osm_err("Insufficient memory to allocate request queue.\n");
 		rc = -ENOMEM;
 		goto cleanup_queue;
 	}
@@ -1054,24 +1053,21 @@
 
 	/* skip devices which are used by IOP */
 	if (i2o_dev->lct_data.user_tid != 0xfff) {
-		pr_debug("skipping used device %03x\n", i2o_dev->lct_data.tid);
+		osm_debug("skipping used device %03x\n", i2o_dev->lct_data.tid);
 		return -ENODEV;
 	}
 
-	printk(KERN_INFO "block-osm: New device detected (TID: %03x)\n",
-	       i2o_dev->lct_data.tid);
+	osm_info("New device detected (TID: %03x)\n", i2o_dev->lct_data.tid);
 
 	if (i2o_device_claim(i2o_dev)) {
-		printk(KERN_WARNING "block-osm: Unable to claim device. "
-		       "Installation aborted\n");
+		osm_warn("Unable to claim device. Installation aborted\n");
 		rc = -EFAULT;
 		goto exit;
 	}
 
 	i2o_blk_dev = i2o_block_device_alloc();
 	if (IS_ERR(i2o_blk_dev)) {
-		printk(KERN_ERR "block-osm: could not alloc a new I2O block"
-		       "device");
+		osm_err("could not alloc a new I2O block device");
 		rc = PTR_ERR(i2o_blk_dev);
 		goto claim_release;
 	}
@@ -1106,9 +1102,9 @@
 
 	blk_queue_max_hw_segments(queue, segments);
 
-	pr_debug("max sectors:   %d\n", I2O_MAX_SECTORS);
-	pr_debug("phys segments: %d\n", I2O_MAX_SEGMENTS);
-	pr_debug("hw segments:   %d\n", segments);
+	osm_debug("max sectors = %d\n", I2O_MAX_SECTORS);
+	osm_debug("phys segments = %d\n", I2O_MAX_SEGMENTS);
+	osm_debug("hw segments = %d\n", segments);
 
 	/*
 	 *      Ask for the current media data. If that isn't supported
@@ -1119,7 +1115,7 @@
 		i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4);
 		i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8);
 	}
-	pr_debug("blocksize:     %d\n", blocksize);
+	osm_debug("blocksize = %d\n", blocksize);
 
 	if (i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2))
 		power = 0;
@@ -1145,7 +1141,7 @@
 
 /* Block OSM driver struct */
 static struct i2o_driver i2o_block_driver = {
-	.name = "block-osm",
+	.name = OSM_NAME,
 	.event = i2o_block_event,
 	.reply = i2o_block_reply,
 	.classes = i2o_block_class_id,
@@ -1168,8 +1164,7 @@
 	int rc;
 	int size;
 
-	printk(KERN_INFO "I2O Block Storage OSM v0.9\n");
-	printk(KERN_INFO "   (c) Copyright 1999-2001 Red Hat Software.\n");
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
 	/* Allocate request mempool and slab */
 	size = sizeof(struct i2o_block_request);
@@ -1177,7 +1172,7 @@
 						  SLAB_HWCACHE_ALIGN, NULL,
 						  NULL);
 	if (!i2o_blk_req_pool.slab) {
-		printk(KERN_ERR "block-osm: can't init request slab\n");
+		osm_err("can't init request slab\n");
 		rc = -ENOMEM;
 		goto exit;
 	}
@@ -1187,7 +1182,7 @@
 					       mempool_free_slab,
 					       i2o_blk_req_pool.slab);
 	if (!i2o_blk_req_pool.pool) {
-		printk(KERN_ERR "block-osm: can't init request mempool\n");
+		osm_err("can't init request mempool\n");
 		rc = -ENOMEM;
 		goto free_slab;
 	}
@@ -1195,18 +1190,17 @@
 	/* Register the block device interfaces */
 	rc = register_blkdev(I2O_MAJOR, "i2o_block");
 	if (rc) {
-		printk(KERN_ERR "block-osm: unable to register block device\n");
+		osm_err("unable to register block device\n");
 		goto free_mempool;
 	}
 #ifdef MODULE
-	printk(KERN_INFO "block-osm: registered device at major %d\n",
-	       I2O_MAJOR);
+	osm_info("registered device at major %d\n", I2O_MAJOR);
 #endif
 
 	/* Register Block OSM into I2O core */
 	rc = i2o_driver_register(&i2o_block_driver);
 	if (rc) {
-		printk(KERN_ERR "block-osm: Could not register Block driver\n");
+		osm_err("Could not register Block driver\n");
 		goto unregister_blkdev;
 	}
 
@@ -1245,8 +1239,9 @@
 };
 
 MODULE_AUTHOR("Red Hat");
-MODULE_DESCRIPTION("I2O Block Device OSM");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 module_init(i2o_block_init);
 module_exit(i2o_block_exit);
diff -Nru a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
--- a/drivers/message/i2o/i2o_config.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/message/i2o/i2o_config.c	2005-01-19 13:44:47 -08:00
@@ -48,6 +48,10 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
+#define OSM_NAME	"config-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O Configuration OSM"
+
 extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
 
 static spinlock_t i2o_config_lock;
@@ -79,7 +83,7 @@
  */
 
 static struct i2o_driver i2o_config_driver = {
-	.name = "Config-OSM"
+	.name = OSM_NAME
 };
 
 static int i2o_cfg_getiops(unsigned long arg)
@@ -296,7 +300,7 @@
 	writel(0xD0000000 | fragsize, &msg->body[3]);
 	writel(buffer.phys, &msg->body[4]);
 
-//      printk(KERN_INFO "i2o_config: swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
+	osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
 	status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
 
 	if (status != -ETIMEDOUT)
@@ -305,9 +309,7 @@
 	if (status != I2O_POST_WAIT_OK) {
 		// it fails if you try and send frags out of order
 		// and for some yet unknown reasons too
-		printk(KERN_INFO
-		       "i2o_config: swdl failed, DetailedStatus = %d\n",
-		       status);
+		osm_info("swdl failed, DetailedStatus = %d\n", status);
 		return status;
 	}
 
@@ -370,16 +372,14 @@
 	writel(0xD0000000 | fragsize, &msg->body[3]);
 	writel(buffer.phys, &msg->body[4]);
 
-//      printk(KERN_INFO "i2o_config: swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
+	osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
 	status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
 
 	if (status != I2O_POST_WAIT_OK) {
 		if (status != -ETIMEDOUT)
 			i2o_dma_free(&c->pdev->dev, &buffer);
 
-		printk(KERN_INFO
-		       "i2o_config: swul failed, DetailedStatus = %d\n",
-		       status);
+		osm_info("swul failed, DetailedStatus = %d\n", status);
 		return status;
 	}
 
@@ -432,9 +432,7 @@
 	token = i2o_msg_post_wait(c, m, 10);
 
 	if (token != I2O_POST_WAIT_OK) {
-		printk(KERN_INFO
-		       "i2o_config: swdel failed, DetailedStatus = %d\n",
-		       token);
+		osm_info("swdel failed, DetailedStatus = %d\n", token);
 		return -ETIMEDOUT;
 	}
 
@@ -466,8 +464,8 @@
 	token = i2o_msg_post_wait(c, m, 10);
 
 	if (token != I2O_POST_WAIT_OK) {
-		printk(KERN_INFO "Can't validate configuration, ErrorStatus = "
-		       "%d\n", token);
+		osm_info("Can't validate configuration, ErrorStatus = %d\n",
+			 token);
 		return -ETIMEDOUT;
 	}
 
@@ -569,7 +567,7 @@
 
 	c = i2o_find_iop(iop);
 	if (!c) {
-		pr_debug("controller %d not found\n", iop);
+		osm_debug("controller %d not found\n", iop);
 		return -ENXIO;
 	}
 
@@ -578,13 +576,13 @@
 	sb = c->status_block.virt;
 
 	if (get_user(size, &user_msg[0])) {
-		printk(KERN_WARNING "unable to get size!\n");
+		osm_warn("unable to get size!\n");
 		return -EFAULT;
 	}
 	size = size >> 16;
 
 	if (size > sb->inbound_frame_size) {
-		pr_debug("size of message > inbound_frame_size");
+		osm_warn("size of message > inbound_frame_size");
 		return -EFAULT;
 	}
 
@@ -594,7 +592,7 @@
 
 	/* Copy in the user's I2O command */
 	if (copy_from_user(msg, user_msg, size)) {
-		printk(KERN_WARNING "unable to copy user message\n");
+		osm_warn("unable to copy user message\n");
 		return -EFAULT;
 	}
 	i2o_dump_message(msg);
@@ -692,7 +690,6 @@
 		// TODO 64bit fix
 		struct sg_simple_element *sg;
 		int sg_size;
-		printk(KERN_INFO "sg_offset\n");
 
 		// re-acquire the original message to handle correctly the sg copy operation
 		memset(&msg, 0, MSG_FRAME_SIZE * 4);
@@ -737,7 +734,6 @@
 	/* Copy back the reply to user space */
 	if (reply_size) {
 		// we wrote our own values for context - now restore the user supplied ones
-		printk(KERN_INFO "reply_size\n");
 		if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) {
 			printk(KERN_WARNING
 			       "%s: Could not copy message context FROM user\n",
@@ -753,7 +749,6 @@
 
       cleanup:
 	kfree(reply);
-	printk(KERN_INFO "rcode: %d\n", rcode);
 	return rcode;
 }
 
@@ -786,7 +781,7 @@
 
 	c = i2o_find_iop(iop);
 	if (!c) {
-		pr_debug("controller %d not found\n", iop);
+		osm_warn("controller %d not found\n", iop);
 		return -ENXIO;
 	}
 
@@ -799,7 +794,7 @@
 	size = size >> 16;
 
 	if (size > sb->inbound_frame_size) {
-		pr_debug("size of message > inbound_frame_size");
+		osm_warn("size of message > inbound_frame_size");
 		return -EFAULT;
 	}
 
@@ -902,7 +897,6 @@
 		// TODO 64bit fix
 		struct sg_simple_element *sg;
 		int sg_size;
-		printk(KERN_INFO "sg_offset\n");
 
 		// re-acquire the original message to handle correctly the sg copy operation
 		memset(&msg, 0, MSG_FRAME_SIZE * 4);
@@ -947,7 +941,6 @@
 	/* Copy back the reply to user space */
 	if (reply_size) {
 		// we wrote our own values for context - now restore the user supplied ones
-		printk(KERN_INFO "reply_size\n");
 		if (copy_from_user(reply + 2, user_msg + 2, sizeof(u32) * 2)) {
 			printk(KERN_WARNING
 			       "%s: Could not copy message context FROM user\n",
@@ -1027,7 +1020,7 @@
 #endif
 
 	default:
-		pr_debug("i2o_config: unknown ioctl called!\n");
+		osm_debug("unknown ioctl called!\n");
 		ret = -EINVAL;
 	}
 
@@ -1125,20 +1118,19 @@
 
 static int __init i2o_config_init(void)
 {
-	printk(KERN_INFO "I2O configuration manager v 0.04.\n");
-	printk(KERN_INFO "  (C) Copyright 1999 Red Hat Software\n");
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
 	spin_lock_init(&i2o_config_lock);
 
 	if (misc_register(&i2o_miscdev) < 0) {
-		printk(KERN_ERR "i2o_config: can't register device.\n");
+		osm_err("can't register device.\n");
 		return -EBUSY;
 	}
 	/*
 	 *      Install our handler
 	 */
 	if (i2o_driver_register(&i2o_config_driver)) {
-		printk(KERN_ERR "i2o_config: handler register failed.\n");
+		osm_err("handler register failed.\n");
 		misc_deregister(&i2o_miscdev);
 		return -EBUSY;
 	}
@@ -1160,8 +1152,9 @@
 }
 
 MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Configuration");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 module_init(i2o_config_init);
 module_exit(i2o_config_exit);
diff -Nru a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
--- a/drivers/message/i2o/i2o_proc.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/message/i2o/i2o_proc.c	2005-01-19 13:44:47 -08:00
@@ -27,6 +27,10 @@
  *			Changes for new I2O API
  */
 
+#define OSM_NAME	"proc-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O ProcFS OSM"
+
 #define I2O_MAX_MODULES 4
 // FIXME!
 #define FMT_U64_HEX "0x%08x%08x"
@@ -60,7 +64,7 @@
 
 /* proc OSM driver struct */
 static struct i2o_driver i2o_proc_driver = {
-	.name = "proc-osm",
+	.name = OSM_NAME,
 };
 
 static int print_serial_number(struct seq_file *seq, u8 * serialno, int max_len)
@@ -1938,11 +1942,11 @@
 
 	sprintf(buff, "%03x", dev->lct_data.tid);
 
-	pr_debug("Adding device /proc/i2o/iop%d/%s\n", dev->iop->unit, buff);
+	osm_debug("adding device /proc/i2o/%s/%s\n", dev->iop->name, buff);
 
 	devdir = proc_mkdir(buff, dir);
 	if (!devdir) {
-		printk(KERN_WARNING "i2o: Could not allocate procdir!\n");
+		osm_warn("Could not allocate procdir!\n");
 		return;
 	}
 
@@ -1978,13 +1982,10 @@
 {
 	struct proc_dir_entry *iopdir;
 	struct i2o_device *dev;
-	char buff[10];
 
-	snprintf(buff, 10, "iop%d", c->unit);
+	osm_debug("adding IOP /proc/i2o/%s\n", c->name);
 
-	pr_debug("Adding IOP /proc/i2o/%s\n", buff);
-
-	iopdir = proc_mkdir(buff, dir);
+	iopdir = proc_mkdir(c->name, dir);
 	if (!iopdir)
 		return -1;
 
@@ -2018,7 +2019,7 @@
 			i2o_proc_subdir_remove(pe);
 			remove_proc_entry(pe->name, dir);
 		}
-		pr_debug("Removing IOP /proc/i2o/iop%d\n", c->unit);
+		osm_debug("removing IOP /proc/i2o/%s\n", c->name);
 		pe = tmp;
 	}
 }
@@ -2076,6 +2077,8 @@
 {
 	int rc;
 
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
+
 	rc = i2o_driver_register(&i2o_proc_driver);
 	if (rc)
 		return rc;
@@ -2101,8 +2104,9 @@
 };
 
 MODULE_AUTHOR("Deepak Saxena");
-MODULE_DESCRIPTION("I2O procfs Handler");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 module_init(i2o_proc_init);
 module_exit(i2o_proc_exit);
diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
--- a/drivers/message/i2o/i2o_scsi.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/message/i2o/i2o_scsi.c	2005-01-19 13:44:47 -08:00
@@ -65,7 +65,9 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 
-#define VERSION_STRING        "Version 0.1.2"
+#define OSM_NAME	"scsi-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O SCSI Peripheral OSM"
 
 static struct i2o_driver i2o_scsi_driver;
 
@@ -106,8 +108,7 @@
 	}
 
 	if (!max_channel) {
-		printk(KERN_WARNING "scsi-osm: no channels found on %s\n",
-		       c->name);
+		osm_warn("no channels found on %s\n", c->name);
 		return ERR_PTR(-EFAULT);
 	}
 
@@ -116,7 +117,7 @@
 
 	scsi_host = scsi_host_alloc(&i2o_scsi_host_template, size);
 	if (!scsi_host) {
-		printk(KERN_WARNING "scsi-osm: Could not allocate SCSI host\n");
+		osm_warn("Could not allocate SCSI host\n");
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -221,24 +222,23 @@
 		return -EFAULT;
 
 	if (id >= scsi_host->max_id) {
-		printk(KERN_WARNING "scsi-osm: SCSI device id (%d) >= max_id "
-		       "of I2O host (%d)", id, scsi_host->max_id);
+		osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id,
+			 scsi_host->max_id);
 		return -EFAULT;
 	}
 
 	if (i2o_parm_field_get(i2o_dev, 0, 4, &lun, 8) < 0)
 		return -EFAULT;
 	if (lun >= scsi_host->max_lun) {
-		printk(KERN_WARNING "scsi-osm: SCSI device id (%d) >= max_lun "
-		       "of I2O host (%d)", (unsigned int)lun,
-		       scsi_host->max_lun);
+		osm_warn("SCSI device id (%d) >= max_lun of I2O host (%d)",
+			 (unsigned int)lun, scsi_host->max_lun);
 		return -EFAULT;
 	}
 
 	parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
 	if (!parent) {
-		printk(KERN_WARNING "scsi-osm: can not find parent of device "
-		       "%03x\n", i2o_dev->lct_data.tid);
+		osm_warn("can not find parent of device %03x\n",
+			 i2o_dev->lct_data.tid);
 		return -EFAULT;
 	}
 
@@ -247,8 +247,8 @@
 			channel = i;
 
 	if (channel == -1) {
-		printk(KERN_WARNING "scsi-osm: can not find channel of device "
-		       "%03x\n", i2o_dev->lct_data.tid);
+		osm_warn("can not find channel of device %03x\n",
+			 i2o_dev->lct_data.tid);
 		return -EFAULT;
 	}
 
@@ -256,13 +256,13 @@
 	    __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev);
 
 	if (!scsi_dev) {
-		printk(KERN_WARNING "scsi-osm: can not add SCSI device "
-		       "%03x\n", i2o_dev->lct_data.tid);
+		osm_warn("can not add SCSI device %03x\n",
+			 i2o_dev->lct_data.tid);
 		return -EFAULT;
 	}
 
-	pr_debug("Added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n",
-		 i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
+	osm_debug("added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n",
+		  i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
 
 	return 0;
 };
@@ -307,24 +307,24 @@
 
 		pmsg = i2o_msg_in_to_virt(c, pm);
 
-		printk(KERN_ERR "IOP fail.\n");
-		printk(KERN_ERR "From %d To %d Cmd %d.\n",
-		       (msg->u.head[1] >> 12) & 0xFFF,
-		       msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24);
-		printk(KERN_ERR "Failure Code %d.\n", msg->body[0] >> 24);
+		osm_err("IOP fail.\n");
+		osm_err("From %d To %d Cmd %d.\n",
+			(msg->u.head[1] >> 12) & 0xFFF,
+			msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24);
+		osm_err("Failure Code %d.\n", msg->body[0] >> 24);
 		if (msg->body[0] & (1 << 16))
-			printk(KERN_ERR "Format error.\n");
+			osm_err("Format error.\n");
 		if (msg->body[0] & (1 << 17))
-			printk(KERN_ERR "Path error.\n");
+			osm_err("Path error.\n");
 		if (msg->body[0] & (1 << 18))
-			printk(KERN_ERR "Path State.\n");
+			osm_err("Path State.\n");
 		if (msg->body[0] & (1 << 18))
 		{
-			printk(KERN_ERR "Congestion.\n");
+			osm_err("Congestion.\n");
 			err = DID_BUS_BUSY;
 		}
 
-		printk(KERN_DEBUG "Failing message is %p.\n", pmsg);
+		osm_debug("Failing message is %p.\n", pmsg);
 
 		cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt));
 		if (!cmd)
@@ -353,13 +353,12 @@
 
 	if (!cmd) {
 		if (st)
-			printk(KERN_WARNING "SCSI abort: %08X",
-			       le32_to_cpu(msg->body[0]));
-		printk(KERN_INFO "SCSI abort completed.\n");
+			osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0]));
+		osm_info("SCSI abort completed.\n");
 		return -EFAULT;
 	}
 
-	pr_debug("Completed %ld\n", cmd->serial_number);
+	osm_debug("Completed %ld\n", cmd->serial_number);
 
 	if (st) {
 		u32 count, error;
@@ -370,13 +369,13 @@
 			count = le32_to_cpu(msg->body[1]);
 			if (count < cmd->underflow) {
 				int i;
-				printk(KERN_ERR "SCSI: underflow 0x%08X 0x%08X"
-				       "\n", count, cmd->underflow);
-				printk(KERN_DEBUG "Cmd: ");
+
+				osm_err("SCSI underflow 0x%08X 0x%08X\n", count,
+					cmd->underflow);
+				osm_debug("Cmd: ");
 				for (i = 0; i < 15; i++)
-					printk(KERN_DEBUG "%02X ",
-					       cmd->cmnd[i]);
-				printk(KERN_DEBUG ".\n");
+					pr_debug("%02X ", cmd->cmnd[i]);
+				pr_debug(".\n");
 				cmd->result = (DID_ERROR << 16);
 			}
 			break;
@@ -384,7 +383,7 @@
 		default:
 			error = le32_to_cpu(msg->body[0]);
 
-			printk(KERN_ERR "scsi-osm: SCSI error %08x\n", error);
+			osm_err("SCSI error %08x\n", error);
 
 			if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) {
 				int i;
@@ -394,8 +393,8 @@
 				memcpy(cmd->sense_buffer, (void *)&msg->body[3],
 				       len);
 				for (i = 0; i <= len; i++)
-					printk(KERN_INFO "%02x\n",
-					       cmd->sense_buffer[i]);
+					osm_info("%02x\n",
+						 cmd->sense_buffer[i]);
 				if (cmd->sense_buffer[0] == 0x70
 				    && cmd->sense_buffer[2] == DATA_PROTECT) {
 					/* This is to handle an array failed */
@@ -467,21 +466,20 @@
 
 	i2o_shost = i2o_scsi_host_alloc(c);
 	if (IS_ERR(i2o_shost)) {
-		printk(KERN_ERR "scsi-osm: Could not initialize"
-		       " SCSI host\n");
+		osm_err("Could not initialize SCSI host\n");
 		return;
 	}
 
 	rc = scsi_add_host(i2o_shost->scsi_host, &c->device);
 	if (rc) {
-		printk(KERN_ERR "scsi-osm: Could not add SCSI " "host\n");
+		osm_err("Could not add SCSI host\n");
 		scsi_host_put(i2o_shost->scsi_host);
 		return;
 	}
 
 	c->driver_data[i2o_scsi_driver.context] = i2o_shost;
 
-	pr_debug("new I2O SCSI host added\n");
+	osm_debug("new I2O SCSI host added\n");
 };
 
 /**
@@ -503,12 +501,12 @@
 
 	scsi_remove_host(i2o_shost->scsi_host);
 	scsi_host_put(i2o_shost->scsi_host);
-	pr_debug("I2O SCSI host removed\n");
+	pr_info("I2O SCSI host removed\n");
 };
 
 /* SCSI OSM driver struct */
 static struct i2o_driver i2o_scsi_driver = {
-	.name = "scsi-osm",
+	.name = OSM_NAME,
 	.reply = i2o_scsi_reply,
 	.classes = i2o_scsi_class_id,
 	.notify_controller_add = i2o_scsi_notify_controller_add,
@@ -561,7 +559,7 @@
 	SCpnt->scsi_done = done;
 
 	if (unlikely(!i2o_dev)) {
-		printk(KERN_WARNING "scsi-osm: no I2O device in request\n");
+		osm_warn("no I2O device in request\n");
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done(SCpnt);
 		return 0;
@@ -569,8 +567,8 @@
 
 	tid = i2o_dev->lct_data.tid;
 
-	pr_debug("qcmd: Tid = %03x\n", tid);
-	pr_debug("Real scsi messages.\n");
+	osm_debug("qcmd: Tid = %03x\n", tid);
+	osm_debug("Real scsi messages.\n");
 
 	/*
 	 *      Obtain an I2O message. If there are none free then
@@ -702,7 +700,7 @@
 	/* Queue the message */
 	i2o_msg_post(c, m);
 
-	pr_debug("Issued %ld\n", SCpnt->serial_number);
+	osm_debug("Issued %ld\n", SCpnt->serial_number);
 
 	return 0;
 };
@@ -727,7 +725,7 @@
 	int tid;
 	int status = FAILED;
 
-	printk(KERN_WARNING "i2o_scsi: Aborting command block.\n");
+	osm_warn("Aborting command block.\n");
 
 	i2o_dev = SCpnt->device->hostdata;
 	c = i2o_dev->iop;
@@ -777,8 +775,8 @@
 }
 
 static struct scsi_host_template i2o_scsi_host_template = {
-	.proc_name = "SCSI-OSM",
-	.name = "I2O SCSI Peripheral OSM",
+	.proc_name = OSM_NAME,
+	.name = OSM_DESCRIPTION,
 	.info = i2o_scsi_info,
 	.queuecommand = i2o_scsi_queuecommand,
 	.eh_abort_handler = i2o_scsi_abort,
@@ -789,15 +787,6 @@
 	.use_clustering = ENABLE_CLUSTERING,
 };
 
-/*
-int
-i2o_scsi_queuecommand(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
-{
-	printk(KERN_INFO "queuecommand\n");
-	return SCSI_MLQUEUE_HOST_BUSY;
-};
-*/
-
 /**
  *	i2o_scsi_init - SCSI OSM initialization function
  *
@@ -809,12 +798,12 @@
 {
 	int rc;
 
-	printk(KERN_INFO "I2O SCSI Peripheral OSM\n");
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
 	/* Register SCSI OSM into I2O core */
 	rc = i2o_driver_register(&i2o_scsi_driver);
 	if (rc) {
-		printk(KERN_ERR "scsi-osm: Could not register SCSI driver\n");
+		osm_err("Could not register SCSI driver\n");
 		return rc;
 	}
 
@@ -834,6 +823,8 @@
 
 MODULE_AUTHOR("Red Hat Software");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 module_init(i2o_scsi_init);
 module_exit(i2o_scsi_exit);
diff -Nru a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
--- a/drivers/message/i2o/iop.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/message/i2o/iop.c	2005-01-19 13:44:46 -08:00
@@ -29,6 +29,9 @@
 #include <linux/i2o.h>
 #include <linux/delay.h>
 
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O subsystem"
+
 /* global I2O controller list */
 LIST_HEAD(i2o_controllers);
 
@@ -126,12 +129,13 @@
 	unsigned long flags;
 
 	if (!ptr)
-		printk(KERN_ERR "NULL pointer found!\n");
+		printk(KERN_ERR "%s: couldn't add NULL pointer to context list!"
+		       "\n", c->name);
 
 	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
 	if (!entry) {
-		printk(KERN_ERR "i2o: Could not allocate memory for context "
-		       "list element\n");
+		printk(KERN_ERR "%s: Could not allocate memory for context "
+		       "list element\n", c->name);
 		return 0;
 	}
 
@@ -150,7 +154,7 @@
 
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
-	pr_debug("Add context to list %p -> %d\n", ptr, context);
+	pr_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context);
 
 	return entry->context;
 };
@@ -182,10 +186,11 @@
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!context)
-		printk(KERN_WARNING "i2o: Could not remove nonexistent ptr "
-		       "%p\n", ptr);
+		printk(KERN_WARNING "%s: Could not remove nonexistent ptr "
+		       "%p\n", c->name, ptr);
 
-	pr_debug("remove ptr from context list %d -> %p\n", context, ptr);
+	pr_debug("%s: remove ptr from context list %d -> %p\n", c->name,
+		 context, ptr);
 
 	return context;
 };
@@ -215,9 +220,11 @@
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!ptr)
-		printk(KERN_WARNING "i2o: context id %d not found\n", context);
+		printk(KERN_WARNING "%s: context id %d not found\n", c->name,
+		       context);
 
-	pr_debug("get ptr from context list %d -> %p\n", context, ptr);
+	pr_debug("%s: get ptr from context list %d -> %p\n", c->name, context,
+		 ptr);
 
 	return ptr;
 };
@@ -245,10 +252,11 @@
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!context)
-		printk(KERN_WARNING "i2o: Could not find nonexistent ptr "
-		       "%p\n", ptr);
+		printk(KERN_WARNING "%s: Could not find nonexistent ptr "
+		       "%p\n", c->name, ptr);
 
-	pr_debug("get context id from context list %p -> %d\n", ptr, context);
+	pr_debug("%s: get context id from context list %p -> %d\n", c->name,
+		 ptr, context);
 
 	return context;
 };
@@ -467,7 +475,7 @@
 	i2o_status_block *sb = c->status_block.virt;
 	int rc = 0;
 
-	pr_debug("Resetting controller\n");
+	pr_debug("%s: Resetting controller\n", c->name);
 
 	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
 	if (m == I2O_QUEUE_EMPTY)
@@ -494,7 +502,7 @@
 	timeout = jiffies + I2O_TIMEOUT_RESET * HZ;
 	while (!*status) {
 		if (time_after(jiffies, timeout)) {
-			printk(KERN_ERR "IOP reset timeout.\n");
+			printk(KERN_ERR "%s: IOP reset timeout.\n", c->name);
 			rc = -ETIMEDOUT;
 			goto exit;
 		}
@@ -526,7 +534,8 @@
 		m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
 		while (m == I2O_QUEUE_EMPTY) {
 			if (time_after(jiffies, timeout)) {
-				printk(KERN_ERR "IOP reset timeout.\n");
+				printk(KERN_ERR "%s: IOP reset timeout.\n",
+				       c->name);
 				rc = -ETIMEDOUT;
 				goto exit;
 			}
@@ -676,14 +685,14 @@
 
 	rc = i2o_status_get(c);
 	if (rc) {
-		printk(KERN_INFO "Unable to obtain status of %s, "
+		printk(KERN_INFO "%s: Unable to obtain status, "
 		       "attempting a reset.\n", c->name);
 		if (i2o_iop_reset(c))
 			return rc;
 	}
 
 	if (sb->i2o_version > I2OVER15) {
-		printk(KERN_ERR "%s: Not running vrs. 1.5. of the I2O "
+		printk(KERN_ERR "%s: Not running version 1.5 of the I2O "
 		       "Specification.\n", c->name);
 		return -ENODEV;
 	}
@@ -697,7 +706,7 @@
 	case ADAPTER_STATE_OPERATIONAL:
 	case ADAPTER_STATE_HOLD:
 	case ADAPTER_STATE_FAILED:
-		pr_debug("already running, trying to reset...\n");
+		pr_debug("%s: already running, trying to reset...\n", c->name);
 		if (i2o_iop_reset(c))
 			return -ENODEV;
 	}
@@ -751,15 +760,16 @@
 		       c->name);
 		root = pci_find_parent_resource(c->pdev, res);
 		if (root == NULL)
-			printk(KERN_WARNING "Can't find parent resource!\n");
+			printk(KERN_WARNING "%s: Can't find parent resource!\n",
+			       c->name);
 		if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20,	/* Unspecified, so use 1Mb and play safe */
 					      NULL, NULL) >= 0) {
 			c->mem_alloc = 1;
 			sb->current_mem_size = 1 + res->end - res->start;
 			sb->current_mem_base = res->start;
-			printk(KERN_INFO
-			       "%s: allocated %ld bytes of PCI memory at 0x%08lX.\n",
-			       c->name, 1 + res->end - res->start, res->start);
+			printk(KERN_INFO "%s: allocated %ld bytes of PCI memory"
+			       " at 0x%08lX.\n", c->name,
+			       1 + res->end - res->start, res->start);
 		}
 	}
 
@@ -773,15 +783,16 @@
 		       c->name);
 		root = pci_find_parent_resource(c->pdev, res);
 		if (root == NULL)
-			printk(KERN_WARNING "Can't find parent resource!\n");
+			printk(KERN_WARNING "%s: Can't find parent resource!\n",
+			       c->name);
 		if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20,	/* Unspecified, so use 1Mb and play safe */
 					      NULL, NULL) >= 0) {
 			c->io_alloc = 1;
 			sb->current_io_size = 1 + res->end - res->start;
 			sb->current_mem_base = res->start;
-			printk(KERN_INFO
-			       "%s: allocated %ld bytes of PCI I/O at 0x%08lX.\n",
-			       c->name, 1 + res->end - res->start, res->start);
+			printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at"
+			       " 0x%08lX.\n", c->name,
+			       1 + res->end - res->start, res->start);
 		}
 	}
 
@@ -871,7 +882,7 @@
 {
 	struct i2o_device *dev, *tmp;
 
-	pr_debug("Deleting controller %s\n", c->name);
+	pr_debug("%s: deleting controller\n", c->name);
 
 	i2o_driver_notify_controller_remove_all(c);
 
@@ -1114,7 +1125,7 @@
 
 	c = kmalloc(sizeof(*c), GFP_KERNEL);
 	if (!c) {
-		printk(KERN_ERR "i2o: Insufficient memory to allocate the "
+		printk(KERN_ERR "i2o: Insufficient memory to allocate a I2O "
 		       "controller.\n");
 		return ERR_PTR(-ENOMEM);
 	}
@@ -1162,27 +1173,27 @@
 	       "devices\n", c->name);
 
 	if ((rc = i2o_iop_activate(c))) {
-		printk(KERN_ERR "%s: controller could not activated\n",
+		printk(KERN_ERR "%s: could not activate controller\n",
 		       c->name);
 		i2o_iop_reset(c);
 		return rc;
 	}
 
-	pr_debug("building sys table %s...\n", c->name);
+	pr_debug("%s: building sys table...\n", c->name);
 
 	if ((rc = i2o_systab_build())) {
 		i2o_iop_reset(c);
 		return rc;
 	}
 
-	pr_debug("online controller %s...\n", c->name);
+	pr_debug("%s: online controller...\n", c->name);
 
 	if ((rc = i2o_iop_online(c))) {
 		i2o_iop_reset(c);
 		return rc;
 	}
 
-	pr_debug("getting LCT %s...\n", c->name);
+	pr_debug("%s: getting LCT...\n", c->name);
 
 	if ((rc = i2o_exec_lct_get(c))) {
 		i2o_iop_reset(c);
@@ -1247,7 +1258,7 @@
 {
 	int rc = 0;
 
-	printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n");
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
 	rc = i2o_device_init();
 	if (rc)
@@ -1297,8 +1308,9 @@
 module_exit(i2o_iop_exit);
 
 MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Core");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
 
 #if BITS_PER_LONG == 64
 EXPORT_SYMBOL(i2o_cntxt_list_add);
diff -Nru a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
--- a/drivers/message/i2o/pci.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/message/i2o/pci.c	2005-01-19 13:44:48 -08:00
@@ -159,34 +159,36 @@
 	}
 
 	if (i == 6) {
-		printk(KERN_ERR "i2o: I2O controller has no memory regions"
-		       " defined.\n");
+		printk(KERN_ERR "%s: I2O controller has no memory regions"
+		       " defined.\n", c->name);
 		i2o_pci_free(c);
 		return -EINVAL;
 	}
 
 	/* Map the I2O controller */
 	if (c->raptor) {
-		printk(KERN_INFO "i2o: PCI I2O controller\n");
+		printk(KERN_INFO "%s: PCI I2O controller\n", c->name);
 		printk(KERN_INFO "     BAR0 at 0x%08lX size=%ld\n",
 		       (unsigned long)c->base.phys, (unsigned long)c->base.len);
 		printk(KERN_INFO "     BAR1 at 0x%08lX size=%ld\n",
 		       (unsigned long)c->in_queue.phys,
 		       (unsigned long)c->in_queue.len);
 	} else
-		printk(KERN_INFO "i2o: PCI I2O controller at %08lX size=%ld\n",
-		       (unsigned long)c->base.phys, (unsigned long)c->base.len);
+		printk(KERN_INFO "%s: PCI I2O controller at %08lX size=%ld\n",
+		       c->name, (unsigned long)c->base.phys,
+		       (unsigned long)c->base.len);
 
 	c->base.virt = ioremap(c->base.phys, c->base.len);
 	if (!c->base.virt) {
-		printk(KERN_ERR "i2o: Unable to map controller.\n");
+		printk(KERN_ERR "%s: Unable to map controller.\n", c->name);
 		return -ENOMEM;
 	}
 
 	if (c->raptor) {
 		c->in_queue.virt = ioremap(c->in_queue.phys, c->in_queue.len);
 		if (!c->in_queue.virt) {
-			printk(KERN_ERR "i2o: Unable to map controller.\n");
+			printk(KERN_ERR "%s: Unable to map controller.\n",
+			       c->name);
 			i2o_pci_free(c);
 			return -ENOMEM;
 		}
@@ -204,10 +206,10 @@
 	c->mtrr_reg1 = -1;
 
 	if (c->mtrr_reg0 < 0)
-		printk(KERN_WARNING "i2o: could not enable write combining "
-		       "MTRR\n");
+		printk(KERN_WARNING "%s: could not enable write combining "
+		       "MTRR\n", c->name);
 	else
-		printk(KERN_INFO "i2o: using write combining MTRR\n");
+		printk(KERN_INFO "%s: using write combining MTRR\n", c->name);
 
 	/*
 	 * If it is an INTEL i960 I/O processor then set the first 64K to
@@ -216,14 +218,14 @@
 	 */
 	if ((pdev->vendor == PCI_VENDOR_ID_INTEL ||
 	     pdev->vendor == PCI_VENDOR_ID_DPT) && !c->raptor) {
-		printk(KERN_INFO "i2o: MTRR workaround for Intel i960 processor"
-		       "\n");
+		printk(KERN_INFO "%s: MTRR workaround for Intel i960 processor"
+		       "\n", c->name);
 		c->mtrr_reg1 = mtrr_add(c->base.phys, 0x10000,
 					MTRR_TYPE_UNCACHABLE, 1);
 
 		if (c->mtrr_reg1 < 0) {
-			printk(KERN_WARNING "i2o_pci: Error in setting "
-			       "MTRR_TYPE_UNCACHABLE\n");
+			printk(KERN_WARNING "%s: Error in setting "
+			       "MTRR_TYPE_UNCACHABLE\n", c->name);
 			mtrr_del(c->mtrr_reg0, c->in_queue.phys,
 				 c->in_queue.len);
 			c->mtrr_reg0 = -1;
@@ -288,7 +290,7 @@
 		if (unlikely(mv == I2O_QUEUE_EMPTY)) {
 			return IRQ_NONE;
 		} else
-			pr_debug("960 bug detected\n");
+			pr_debug("%s: 960 bug detected\n", c->name);
 	}
 
 	while (mv != I2O_QUEUE_EMPTY) {
@@ -303,7 +305,7 @@
 		 *      Ensure this message is seen coherently but cachably by
 		 *      the processor
 		 */
-		dma_sync_single_for_cpu(dev, c->out_queue.phys, MSG_FRAME_SIZE,
+		dma_sync_single_for_cpu(dev, mv, MSG_FRAME_SIZE * 4,
 					PCI_DMA_FROMDEVICE);
 
 		/* dispatch it */
@@ -425,12 +427,14 @@
 	/* Cards that fall apart if you hit them with large I/O loads... */
 	if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
 		c->short_req = 1;
-		printk(KERN_INFO "i2o: Symbios FC920 workarounds activated.\n");
+		printk(KERN_INFO "%s: Symbios FC920 workarounds activated.\n",
+		       c->name);
 	}
 
 	if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) {
 		c->promise = 1;
-		printk(KERN_INFO "i2o: Promise workarounds activated.\n");
+		printk(KERN_INFO "%s: Promise workarounds activated.\n",
+		       c->name);
 	}
 
 	/* Cards that go bananas if you quiesce them before you reset them. */
@@ -441,14 +445,14 @@
 	}
 
 	if ((rc = i2o_pci_alloc(c))) {
-		printk(KERN_ERR "i2o: DMA / IO allocation for I2O controller "
-		       " failed\n");
+		printk(KERN_ERR "%s: DMA / IO allocation for I2O controller "
+		       " failed\n", c->name);
 		goto free_controller;
 	}
 
 	if (i2o_pci_irq_enable(c)) {
-		printk(KERN_ERR "i2o: unable to enable interrupts for I2O "
-		       "controller\n");
+		printk(KERN_ERR "%s: unable to enable interrupts for I2O "
+		       "controller\n", c->name);
 		goto free_pci;
 	}
 
diff -Nru a/drivers/misc/Kconfig b/drivers/misc/Kconfig
--- a/drivers/misc/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/misc/Kconfig	2005-01-19 13:44:46 -08:00
@@ -22,7 +22,7 @@
 	  
 	  WARNING: This software may not be supported or function
 	  correctly on your IBM server. Please consult the IBM ServerProven
-	  website http://www.pc.ibm/ww/eserver/xseries/serverproven for
+	  website <http://www.pc.ibm/ww/eserver/xseries/serverproven> for
 	  information on the specific driver level and support statement
 	  for your IBM server.
 
diff -Nru a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
--- a/drivers/mmc/mmc_block.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/mmc/mmc_block.c	2005-01-19 13:44:48 -08:00
@@ -332,6 +332,18 @@
 		md->disk->queue = md->queue.queue;
 		md->disk->driverfs_dev = &card->dev;
 
+		/*
+		 * As discussed on lkml, GENHD_FL_REMOVABLE should:
+		 *
+		 * - be set for removable media with permanent block devices
+		 * - be unset for removable block devices with permanent media
+		 *
+		 * Since MMC block devices clearly fall under the second
+		 * case, we do not set GENHD_FL_REMOVABLE.  Userspace
+		 * should use the block device creation/destruction hotplug
+		 * messages to tell when the card is present.
+		 */
+
 		sprintf(md->disk->disk_name, "mmcblk%d", devidx);
 		sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
 
diff -Nru a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
--- a/drivers/mtd/devices/block2mtd.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/mtd/devices/block2mtd.c	2005-01-19 13:44:45 -08:00
@@ -1,27 +1,14 @@
 /*
  * $Id: block2mtd.c,v 1.23 2005/01/05 17:05:46 dwmw2 Exp $
  *
- * blockmtd.c - use a block device as a fake MTD
+ * block2mtd.c - create an mtd from a block device
  *
- * Author: Simon Evans <spse@secret.org.uk>
- *
- * Copyright (C) 2001,2002	Simon Evans
- * Copyright (C) 2004		
- * Copyright (C) 2004		JÃ¶rn Engel <joern@wh.fh-wedel.de>
+ * Copyright (C) 2001,2002	Simon Evans <spse@secret.org.uk>
+ * Copyright (C) 2004		Gareth Bult <Gareth@Encryptec.net>
+ * Copyright (C) 2004,2005	Jörn Engel <joern@wh.fh-wedel.de>
  *
  * Licence: GPL
- *
- * How it works:
- *	The driver uses raw/io to read/write the device and the page
- *	cache to cache access. Writes update the page cache with the
- *	new data and mark it dirty and add the page into a BIO which
- *	is then written out.
- *
- *	It can be loaded Read-Only to prevent erases and writes to the
- *	medium.
- *
  */
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/fs.h>
@@ -33,15 +20,15 @@
 #include <linux/mtd/mtd.h>
 #include <linux/buffer_head.h>
 
-#define ERROR(fmt, args...) printk(KERN_ERR "blockmtd: " fmt "\n" , ## args)
-#define INFO(fmt, args...) printk(KERN_INFO "blockmtd: " fmt "\n" , ## args)
+#define VERSION "$Revision: 1.23 $"
 
 
-/* Default erase size in K, always make it a multiple of PAGE_SIZE */
-#define VERSION "$Revision: 1.23 $"
+#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
+#define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
+
 
 /* Info for the block device */
-struct blockmtd_dev {
+struct block2mtd_dev {
 	struct list_head list;
 	struct block_device *blkdev;
 	struct mtd_info mtd;
@@ -66,7 +53,7 @@
 	loff_t isize = i_size_read(inode);
 
 	if (!isize) {
-		printk(KERN_INFO "iSize=0 in cache_readahead\n");
+		INFO("iSize=0 in cache_readahead\n");
 		return;
 	}
 
@@ -76,7 +63,7 @@
 	for (i = 0; i < PAGE_READAHEAD; i++) {
 		pagei = index + i;
 		if (pagei > end_index) {
-			printk(KERN_INFO "Overrun end of disk in cache readahead\n");
+			INFO("Overrun end of disk in cache readahead\n");
 			break;
 		}
 		page = radix_tree_lookup(&mapping->page_tree, pagei);
@@ -102,13 +89,14 @@
 static struct page* page_readahead(struct address_space *mapping, int index)
 {
 	filler_t *filler = (filler_t*)mapping->a_ops->readpage;
+	//do_page_cache_readahead(mapping, index, XXX, 64);
 	cache_readahead(mapping, index);
 	return read_cache_page(mapping, index, filler, NULL);
 }
 
 
 /* erase a specified part of the device */
-static int _blockmtd_erase(struct blockmtd_dev *dev, loff_t to, size_t len)
+static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
 {
 	struct address_space *mapping = dev->blkdev->bd_inode->i_mapping;
 	struct page *page;
@@ -140,16 +128,16 @@
 	}
 	return 0;
 }
-static int blockmtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
-	struct blockmtd_dev *dev = mtd->priv;
+	struct block2mtd_dev *dev = mtd->priv;
 	size_t from = instr->addr;
 	size_t len = instr->len;
 	int err;
 
 	instr->state = MTD_ERASING;
 	down(&dev->write_mutex);
-	err = _blockmtd_erase(dev, from, len);
+	err = _block2mtd_erase(dev, from, len);
 	up(&dev->write_mutex);
 	if (err) {
 		ERROR("erase failed err = %d", err);
@@ -163,10 +151,10 @@
 }
 
 
-static int blockmtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, u_char *buf)
 {
-	struct blockmtd_dev *dev = mtd->priv;
+	struct block2mtd_dev *dev = mtd->priv;
 	struct page *page;
 	int index = from >> PAGE_SHIFT;
 	int offset = from & (PAGE_SHIFT-1);
@@ -208,7 +196,7 @@
 
 
 /* write data to the underlying device */
-static int _blockmtd_write(struct blockmtd_dev *dev, const u_char *buf,
+static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
 		loff_t to, size_t len, size_t *retlen)
 {
 	struct page *page;
@@ -250,10 +238,10 @@
 	}
 	return 0;
 }
-static int blockmtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
 		size_t *retlen, const u_char *buf)
 {
-	struct blockmtd_dev *dev = mtd->priv;
+	struct block2mtd_dev *dev = mtd->priv;
 	int err;
 
 	if (!len)
@@ -264,7 +252,7 @@
 		len = mtd->size - to;
 
 	down(&dev->write_mutex);
-	err = _blockmtd_write(dev, buf, to, len, retlen);
+	err = _block2mtd_write(dev, buf, to, len, retlen);
 	up(&dev->write_mutex);
 	if (err > 0)
 		err = 0;
@@ -273,15 +261,15 @@
 
 
 /* sync the device - wait until the write queue is empty */
-static void blockmtd_sync(struct mtd_info *mtd)
+static void block2mtd_sync(struct mtd_info *mtd)
 {
-	struct blockmtd_dev *dev = mtd->priv;
+	struct block2mtd_dev *dev = mtd->priv;
 	sync_blockdev(dev->blkdev);
 	return;
 }
 
 
-static void blockmtd_free_device(struct blockmtd_dev *dev)
+static void block2mtd_free_device(struct block2mtd_dev *dev)
 {
 	if (!dev)
 		return;
@@ -298,15 +286,15 @@
 
 
 /* FIXME: ensure that mtd->size % erase_size == 0 */
-static struct blockmtd_dev *add_device(char *devname, int erase_size)
+static struct block2mtd_dev *add_device(char *devname, int erase_size)
 {
 	struct block_device *bdev;
-	struct blockmtd_dev *dev;
+	struct block2mtd_dev *dev;
 
 	if (!devname)
 		return NULL;
 
-	dev = kmalloc(sizeof(struct blockmtd_dev), GFP_KERNEL);
+	dev = kmalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
 	if (!dev)
 		return NULL;
 	memset(dev, 0, sizeof(*dev));
@@ -328,22 +316,22 @@
 
 	/* Setup the MTD structure */
 	/* make the name contain the block device in */
-	dev->mtd.name = kmalloc(sizeof("blockmtd: ") + strlen(devname),
+	dev->mtd.name = kmalloc(sizeof("block2mtd: ") + strlen(devname),
 			GFP_KERNEL);
 	if (!dev->mtd.name)
 		goto devinit_err;
 
-	sprintf(dev->mtd.name, "blockmtd: %s", devname);
+	sprintf(dev->mtd.name, "block2mtd: %s", devname);
 
 	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
 	dev->mtd.erasesize = erase_size;
 	dev->mtd.type = MTD_RAM;
 	dev->mtd.flags = MTD_CAP_RAM;
-	dev->mtd.erase = blockmtd_erase;
-	dev->mtd.write = blockmtd_write;
+	dev->mtd.erase = block2mtd_erase;
+	dev->mtd.write = block2mtd_write;
 	dev->mtd.writev = default_mtd_writev;
-	dev->mtd.sync = blockmtd_sync;
-	dev->mtd.read = blockmtd_read;
+	dev->mtd.sync = block2mtd_sync;
+	dev->mtd.read = block2mtd_read;
 	dev->mtd.readv = default_mtd_readv;
 	dev->mtd.priv = dev;
 	dev->mtd.owner = THIS_MODULE;
@@ -353,13 +341,13 @@
 		goto devinit_err;
 	}
 	list_add(&dev->list, &blkmtd_device_list);
-	INFO("mtd%d: [%s] erase_size = %dKiB [%ld]", dev->mtd.index,
+	INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index,
 			dev->mtd.name + strlen("blkmtd: "),
-			dev->mtd.erasesize >> 10, PAGE_SIZE);
+			dev->mtd.erasesize >> 10, dev->mtd.erasesize);
 	return dev;
 
 devinit_err:
-	blockmtd_free_device(dev);
+	block2mtd_free_device(dev);
 	return NULL;
 }
 
@@ -416,12 +404,20 @@
 }
 
 
+static inline void kill_final_newline(char *str)
+{
+	char *newline = strrchr(str, '\n');
+	if (newline && !newline[1])
+		*newline = 0;
+}
+
+
 #define parse_err(fmt, args...) do {		\
-	ERROR("blockmtd: " fmt "\n", ## args);	\
+	ERROR("block2mtd: " fmt "\n", ## args);	\
 	return 0;				\
 } while (0)
 
-static int blockmtd_setup(const char *val, struct kernel_param *kp)
+static int block2mtd_setup(const char *val, struct kernel_param *kp)
 {
 	char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */
 	char *token[2];
@@ -433,16 +429,11 @@
 		parse_err("parameter too long");
 
 	strcpy(str, val);
+	kill_final_newline(str);
 
 	for (i=0; i<2; i++)
 		token[i] = strsep(&str, ",");
 
-	{ /* people dislike typing "echo -n".  and it's simple enough */
-		char *newline = strrchr(token[1], '\n');
-		if (newline && !newline[1])
-			*newline = 0;
-	}
-
 	if (str)
 		parse_err("too many arguments");
 
@@ -469,35 +460,35 @@
 }
 
 
-module_param_call(blockmtd, blockmtd_setup, NULL, NULL, 0200);
-MODULE_PARM_DESC(blockmtd, "Device to use. \"blockmtd=<dev>[,<erasesize>]\"");
+module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
 
-static int __init blockmtd_init(void)
+static int __init block2mtd_init(void)
 {
 	INFO("version " VERSION);
 	return 0;
 }
 
 
-static void __devexit blockmtd_exit(void)
+static void __devexit block2mtd_exit(void)
 {
 	struct list_head *pos, *next;
 
 	/* Remove the MTD devices */
 	list_for_each_safe(pos, next, &blkmtd_device_list) {
-		struct blockmtd_dev *dev = list_entry(pos, typeof(*dev), list);
-		blockmtd_sync(&dev->mtd);
+		struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list);
+		block2mtd_sync(&dev->mtd);
 		del_mtd_device(&dev->mtd);
 		INFO("mtd%d: [%s] removed", dev->mtd.index,
 				dev->mtd.name + strlen("blkmtd: "));
 		list_del(&dev->list);
-		blockmtd_free_device(dev);
+		block2mtd_free_device(dev);
 	}
 }
 
 
-module_init(blockmtd_init);
-module_exit(blockmtd_exit);
+module_init(block2mtd_init);
+module_exit(block2mtd_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Simon Evans <spse@secret.org.uk> and others");
diff -Nru a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
--- a/drivers/mtd/maps/Kconfig	2005-01-19 13:44:48 -08:00
+++ b/drivers/mtd/maps/Kconfig	2005-01-19 13:44:48 -08:00
@@ -354,7 +354,7 @@
 	tristate "CFI Flash device mapping on FlagaDM"
 	depends on PPC32 && 8xx && MTD_CFI
 	help
-	  Mapping for the Flaga digital module. If you don´t have one, ignore
+	  Mapping for the Flaga digital module. If you don't have one, ignore
 	  this setting.
 
 config MTD_BEECH
@@ -417,7 +417,7 @@
 	tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"
 	depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS
 	help
-	  This provides a mapping driver for the Integrated Tecnology
+	  This provides a mapping driver for the Integrated Technology
 	  Express, Inc (ITE) QED-4N-S01B eval board and the Globespan IVR
 	  Reference Board. It provides the necessary addressing, length,
 	  buswidth, vpp code and addition setup of the flash device for
diff -Nru a/drivers/net/3c515.c b/drivers/net/3c515.c
--- a/drivers/net/3c515.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/3c515.c	2005-01-19 13:44:46 -08:00
@@ -34,7 +34,7 @@
 /* "Knobs" that adjust features and parameters. */
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1512 effectively disables this feature. */
-static const int rx_copybreak = 200;
+static int rx_copybreak = 200;
 
 /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
 static const int mtu = 1500;
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/net/8139too.c	2005-01-19 13:44:45 -08:00
@@ -108,7 +108,6 @@
 #include <linux/mii.h>
 #include <linux/completion.h>
 #include <linux/crc32.h>
-#include <linux/suspend.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
@@ -1625,8 +1624,7 @@
 		do {
 			timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
 			/* make swsusp happy with our thread */
-			if (current->flags & PF_FREEZE)
-				refrigerator(PF_FREEZE);
+			try_to_freeze(PF_FREEZE);
 		} while (!signal_pending (current) && (timeout > 0));
 
 		if (signal_pending (current)) {
@@ -1636,7 +1634,8 @@
 		if (tp->time_to_die)
 			break;
 
-		rtnl_lock ();
+		if (rtnl_lock_interruptible ())
+			break;
 		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
 		rtnl_unlock ();
 	}
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/Kconfig	2005-01-19 13:44:47 -08:00
@@ -84,6 +84,7 @@
 config TUN
 	tristate "Universal TUN/TAP device driver support"
 	depends on NETDEVICES
+	select CRC32
 	---help---
 	  TUN/TAP provides packet reception and transmission for user space
 	  programs.  It can be viewed as a simple Point-to-Point or Ethernet
@@ -1412,13 +1413,13 @@
 
 	  Use the above information and the Adapter & Driver ID Guide at:
 
-	  http://support.intel.com/support/network/adapter/pro100/21397.htm
+	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
 
           to identify the adapter.
 
 	  For the latest Intel PRO/100 network driver for Linux, see:
 
-	  http://appsr.intel.com/scripts-df/support_intel.asp
+	  <http://appsr.intel.com/scripts-df/support_intel.asp>
 
 	  More specific information on configuring the driver is in 
 	  <file:Documentation/networking/e100.txt>.
@@ -1659,7 +1660,7 @@
 	  <file:Documentation/networking/net-modules.txt>. The module
 	  will be called tlan.
 
-	  Please email feedback to  torben.mathiasen@compaq.com.
+	  Please email feedback to <torben.mathiasen@compaq.com>.
 
 config VIA_RHINE
 	tristate "VIA Rhine support"
@@ -2049,14 +2050,14 @@
 	  The dual link adapters support link-failover and dual port features.
 	  Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support 
 	  the scatter-gather functionality with sendfile(). Please refer to 
-	  Documentation/networking/sk98lin.txt for more information about
+	  <file:Documentation/networking/sk98lin.txt> for more information about
 	  optional driver parameters.
 	  Questions concerning this driver may be addressed to:
-	      linux@syskonnect.de
+	      <linux@syskonnect.de>
 	  
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read Documentation/kbuild/modules.txt. The module will
+	  say M here and read <file:Documentation/kbuild/modules.txt>. The module will
 	  be called sk98lin. This is recommended.
 
 config VIA_VELOCITY
@@ -2265,7 +2266,7 @@
 	  the driver.
 
 	  Questions concerning this driver can be addressed to:
-	  linux@syskonnect.de
+	  <linux@syskonnect.de>
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called skfp.  This is recommended.
@@ -2461,7 +2462,7 @@
 
 	  This driver requires the latest version of pppd from the CVS
 	  repository at cvs.samba.org.  Alternatively, see the 
-	  RoaringPenguin package (http://www.roaringpenguin.com/pppoe)
+	  RoaringPenguin package (<http://www.roaringpenguin.com/pppoe>)
 	  which contains instruction on how to use this driver (under 
 	  the heading "Kernel mode PPPoE").
 
@@ -2589,5 +2590,5 @@
 	depends on NETDEVICES && EXPERIMENTAL
 	---help---
 	If you want to log kernel messages over the network, enable this.
-	See Documentation/networking/netconsole.txt for details.
+	See <file:Documentation/networking/netconsole.txt> for details.
 
diff -Nru a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
--- a/drivers/net/arcnet/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/arcnet/Kconfig	2005-01-19 13:44:47 -08:00
@@ -110,7 +110,7 @@
 	  This is yet another chipset driver for the COM90xx cards, but this
 	  time only using memory-mapped mode, and no IO ports at all. This
 	  driver is completely untested, so if you have one of these cards,
-	  please mail dwmw2@infradead.org, especially if it works!
+	  please mail <dwmw2@infradead.org>, especially if it works!
 
 	  To compile this driver as a module, choose M here and read
 	  <file:Documentation/networking/net-modules.txt>.  The module will
diff -Nru a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
--- a/drivers/net/arcnet/arcnet.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/arcnet/arcnet.c	2005-01-19 13:44:47 -08:00
@@ -93,7 +93,6 @@
 EXPORT_SYMBOL(arc_proto_null);
 EXPORT_SYMBOL(arcnet_unregister_proto);
 EXPORT_SYMBOL(arcnet_debug);
-EXPORT_SYMBOL(arcdev_setup);
 EXPORT_SYMBOL(alloc_arcdev);
 EXPORT_SYMBOL(arcnet_interrupt);
 
@@ -317,7 +316,7 @@
 
 
 /* Setup a struct device for ARCnet. */
-void arcdev_setup(struct net_device *dev)
+static void arcdev_setup(struct net_device *dev)
 {
 	dev->type = ARPHRD_ARCNET;
 	dev->hard_header_len = sizeof(struct archdr);
diff -Nru a/drivers/net/atp.c b/drivers/net/atp.c
--- a/drivers/net/atp.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/atp.c	2005-01-19 13:44:48 -08:00
@@ -909,7 +909,7 @@
 			 i++, mclist = mclist->next)
 		{
 			int filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
-			mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 		}
 		new_mode = CMR2h_Normal;
 	}
diff -Nru a/drivers/net/bmac.c b/drivers/net/bmac.c
--- a/drivers/net/bmac.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/net/bmac.c	2005-01-19 13:44:45 -08:00
@@ -59,9 +59,9 @@
 struct bmac_data {
 	/* volatile struct bmac *bmac; */
 	struct sk_buff_head *queue;
-	volatile struct dbdma_regs *tx_dma;
+	volatile struct dbdma_regs __iomem *tx_dma;
 	int tx_dma_intr;
-	volatile struct dbdma_regs *rx_dma;
+	volatile struct dbdma_regs __iomem *rx_dma;
 	int rx_dma_intr;
 	volatile struct dbdma_cmd *tx_cmds;	/* xmit dma command list */
 	volatile struct dbdma_cmd *rx_cmds;	/* recv dma command list */
@@ -165,35 +165,35 @@
 #define	DBDMA_CLEAR(x)	( (x) << 16)
 
 static inline void
-dbdma_st32(volatile unsigned long *a, unsigned long x)
+dbdma_st32(volatile __u32 __iomem *a, unsigned long x)
 {
 	__asm__ volatile( "stwbrx %0,0,%1" : : "r" (x), "r" (a) : "memory");
 	return;
 }
 
 static inline unsigned long
-dbdma_ld32(volatile unsigned long *a)
+dbdma_ld32(volatile __u32 __iomem *a)
 {
-	unsigned long swap;
+	__u32 swap;
 	__asm__ volatile ("lwbrx %0,0,%1" :  "=r" (swap) : "r" (a));
 	return swap;
 }
 
 static void
-dbdma_continue(volatile struct dbdma_regs *dmap)
+dbdma_continue(volatile struct dbdma_regs __iomem *dmap)
 {
-	dbdma_st32((volatile unsigned long *)&dmap->control,
+	dbdma_st32(&dmap->control,
 		   DBDMA_SET(RUN|WAKE) | DBDMA_CLEAR(PAUSE|DEAD));
 	eieio();
 }
 
 static void
-dbdma_reset(volatile struct dbdma_regs *dmap)
+dbdma_reset(volatile struct dbdma_regs __iomem *dmap)
 {
-	dbdma_st32((volatile unsigned long *)&dmap->control,
+	dbdma_st32(&dmap->control,
 		   DBDMA_CLEAR(ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN));
 	eieio();
-	while (dbdma_ld32((volatile unsigned long *)&dmap->status) & RUN)
+	while (dbdma_ld32(&dmap->status) & RUN)
 		eieio();
 }
 
@@ -213,22 +213,22 @@
 static inline
 void bmwrite(struct net_device *dev, unsigned long reg_offset, unsigned data )
 {
-	out_le16((void *)dev->base_addr + reg_offset, data);
+	out_le16((void __iomem *)dev->base_addr + reg_offset, data);
 }
 
 
 static inline
 volatile unsigned short bmread(struct net_device *dev, unsigned long reg_offset )
 {
-	return in_le16((void *)dev->base_addr + reg_offset);
+	return in_le16((void __iomem *)dev->base_addr + reg_offset);
 }
 
 static void
 bmac_enable_and_reset_chip(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 
 	if (rd)
 		dbdma_reset(rd);
@@ -406,7 +406,7 @@
 bmac_start_chip(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	unsigned short	oldConfig;
 
 	/* enable rx dma channel */
@@ -476,8 +476,8 @@
 	bp->sleeping = 1;
 	spin_unlock_irqrestore(&bp->lock, flags);
 	if (bp->opened) {
-		volatile struct dbdma_regs *rd = bp->rx_dma;
-		volatile struct dbdma_regs *td = bp->tx_dma;
+		volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+		volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 			
 		config = bmread(dev, RXCFG);
 		bmwrite(dev, RXCFG, (config & ~RxMACEnable));
@@ -602,7 +602,7 @@
 static void
 bmac_init_tx_ring(struct bmac_data *bp)
 {
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 
 	memset((char *)bp->tx_cmds, 0, (N_TX_RING+1) * sizeof(struct dbdma_cmd));
 
@@ -623,7 +623,7 @@
 static int
 bmac_init_rx_ring(struct bmac_data *bp)
 {
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	int i;
 	struct sk_buff *skb;
 
@@ -657,7 +657,7 @@
 static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 	int i;
 
 	/* see if there's a free slot in the tx ring */
@@ -693,7 +693,7 @@
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	volatile struct dbdma_cmd *cp;
 	int i, nb, stat;
 	struct sk_buff *skb;
@@ -1331,13 +1331,11 @@
 		goto err_out_iounmap;
 
 	bp->is_bmac_plus = is_bmac_plus;
-	bp->tx_dma = (volatile struct dbdma_regs *)
-		ioremap(macio_resource_start(mdev, 1), macio_resource_len(mdev, 1));
+	bp->tx_dma = ioremap(macio_resource_start(mdev, 1), macio_resource_len(mdev, 1));
 	if (!bp->tx_dma)
 		goto err_out_iounmap;
 	bp->tx_dma_intr = macio_irq(mdev, 1);
-	bp->rx_dma = (volatile struct dbdma_regs *)
-		ioremap(macio_resource_start(mdev, 2), macio_resource_len(mdev, 2));
+	bp->rx_dma = ioremap(macio_resource_start(mdev, 2), macio_resource_len(mdev, 2));
 	if (!bp->rx_dma)
 		goto err_out_iounmap_tx;
 	bp->rx_dma_intr = macio_irq(mdev, 2);
@@ -1392,11 +1390,11 @@
 err_out_irq0:
 	free_irq(dev->irq, dev);
 err_out_iounmap_rx:
-	iounmap((void *)bp->rx_dma);
+	iounmap(bp->rx_dma);
 err_out_iounmap_tx:
-	iounmap((void *)bp->tx_dma);
+	iounmap(bp->tx_dma);
 err_out_iounmap:
-	iounmap((void *)dev->base_addr);
+	iounmap((void __iomem *)dev->base_addr);
 out_release:
 	macio_release_resources(mdev);
 out_free:
@@ -1421,8 +1419,8 @@
 static int bmac_close(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 	unsigned short config;
 	int i;
 
@@ -1505,8 +1503,8 @@
 {
 	struct net_device *dev = (struct net_device *) data;
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *td = bp->tx_dma;
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	volatile struct dbdma_cmd *cp;
 	unsigned long flags;
 	unsigned short config, oldConfig;
@@ -1638,9 +1636,9 @@
 	free_irq(bp->tx_dma_intr, dev);	
 	free_irq(bp->rx_dma_intr, dev);
 
-	iounmap((void *)dev->base_addr);
-	iounmap((void *)bp->tx_dma);
-	iounmap((void *)bp->rx_dma);
+	iounmap((void __iomem *)dev->base_addr);
+	iounmap(bp->tx_dma);
+	iounmap(bp->rx_dma);
 
 	macio_release_resources(mdev);
 
diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
--- a/drivers/net/e1000/e1000_ethtool.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/e1000/e1000_ethtool.c	2005-01-19 13:44:46 -08:00
@@ -1666,7 +1666,7 @@
 	.get_ethtool_stats      = e1000_get_ethtool_stats,
 };
 
-void set_ethtool_ops(struct net_device *netdev)
+void e1000_set_ethtool_ops(struct net_device *netdev)
 {
 	SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
 }
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/e1000/e1000_main.c	2005-01-19 13:44:48 -08:00
@@ -151,7 +151,7 @@
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 			   int cmd);
-void set_ethtool_ops(struct net_device *netdev);
+void e1000_set_ethtool_ops(struct net_device *netdev);
 static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
 static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
 static void e1000_tx_timeout(struct net_device *dev);
@@ -475,7 +475,7 @@
 	netdev->set_mac_address = &e1000_set_mac;
 	netdev->change_mtu = &e1000_change_mtu;
 	netdev->do_ioctl = &e1000_ioctl;
-	set_ethtool_ops(netdev);
+	e1000_set_ethtool_ops(netdev);
 	netdev->tx_timeout = &e1000_tx_timeout;
 	netdev->watchdog_timeo = 5 * HZ;
 #ifdef CONFIG_E1000_NAPI
diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c
--- a/drivers/net/eepro.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/eepro.c	2005-01-19 13:44:47 -08:00
@@ -23,6 +23,7 @@
 	This is a compatibility hardware problem.
 
 	Versions:
+	0.13b	basic ethtool support (aris, 09/13/2004)
 	0.13a   in memory shortage, drop packets also in board
 		(Michael Westermann <mw@microdata-pos.de>, 07/30/2002)
 	0.13    irq sharing, rewrote probe function, fixed a nasty bug in
@@ -104,7 +105,7 @@
 */
 
 static const char version[] =
-	"eepro.c: v0.13 11/08/2001 aris@cathedrallabs.org\n";
+	"eepro.c: v0.13b 09/13/2004 aris@cathedrallabs.org\n";
 
 #include <linux/module.h>
 
@@ -146,19 +147,21 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/ethtool.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 
 #define DRV_NAME "eepro"
+#define DRV_VERSION "0.13b"
 
 #define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) )
 /* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
 #define SLOW_DOWN inb(0x80)
 /* udelay(2) */
 #define compat_init_data     __initdata
-
+enum iftype { AUI=0, BNC=1, TPE=2 };
 
 /* First, a few definitions that the brave might change. */
 /* A zero-terminated list of I/O addresses to be probed. */
@@ -214,6 +217,7 @@
 	short rcv_lower_limit;
 	short rcv_upper_limit;
 	unsigned char eeprom_reg;
+	unsigned short word[8];
 };
 
 /* The station (ethernet) address prefix, used for IDing the board. */
@@ -608,16 +612,22 @@
 }
 #endif
 
-static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
+static void __init printEEPROMInfo(struct net_device *dev)
 {
+	struct eepro_local *lp = (struct eepro_local *)dev->priv;
+	int ioaddr = dev->base_addr;
 	unsigned short Word;
 	int i,j;
 
-	for (i=0, j=ee_Checksum; i<ee_SIZE; i++)
-		j+=read_eeprom(ioaddr,i,dev);
+	j = ee_Checksum;
+	for (i = 0; i < 8; i++)
+		j += lp->word[i];
+	for ( ; i < ee_SIZE; i++)
+		j += read_eeprom(ioaddr, i, dev);
+
 	printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff);
 
-	Word=read_eeprom(ioaddr, 0, dev);
+	Word = lp->word[0];
 	printk(KERN_DEBUG "Word0:\n");
 	printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
 	printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );
@@ -625,7 +635,7 @@
 	printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4);
 
 	if (net_debug>4)  {
-		Word=read_eeprom(ioaddr, 1, dev);
+		Word = lp->word[1];
 		printk(KERN_DEBUG "Word1:\n");
 		printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask);
 		printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI));
@@ -636,7 +646,7 @@
 		printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));
 	}
 
-	Word=read_eeprom(ioaddr, 5, dev);
+	Word = lp->word[5];
 	printk(KERN_DEBUG "Word5:\n");
 	printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));
 	printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));
@@ -646,12 +656,12 @@
 	if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI ");
 	printk(KERN_DEBUG "port(s) \n");
 
-	Word=read_eeprom(ioaddr, 6, dev);
+	Word = lp->word[6];
 	printk(KERN_DEBUG "Word6:\n");
 	printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask);
 	printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID);
 
-	Word=read_eeprom(ioaddr, 7, dev);
+	Word = lp->word[7];
 	printk(KERN_DEBUG "Word7:\n");
 	printk(KERN_DEBUG " INT to IRQ:\n");
 
@@ -725,7 +735,7 @@
 		printk(", %s.\n", ifmap[dev->if_port]);
 
 	if (net_debug > 3) {
-		i = read_eeprom(dev->base_addr, 5, dev);
+		i = lp->word[5];
 		if (i & 0x2000) /* bit 13 of EEPROM word 5 */
 			printk(KERN_DEBUG "%s: Concurrent Processing is "
 				"enabled but not used!\n", dev->name);
@@ -733,19 +743,20 @@
 
 	/* Check the station address for the manufacturer's code */
 	if (net_debug>3)
-		printEEPROMInfo(dev->base_addr, dev);
+		printEEPROMInfo(dev);
 }
 
+static struct ethtool_ops eepro_ethtool_ops;
+
 /* This is the real probe routine.  Linux has a history of friendly device
    probes on the ISA bus.  A good device probe avoids doing writes, and
    verifies that the correct device exists and functions.  */
 
 static int __init eepro_probe1(struct net_device *dev, int autoprobe)
 {
-	unsigned short station_addr[6], id, counter;
+	unsigned short station_addr[3], id, counter;
 	int i;
 	struct eepro_local *lp;
-	enum iftype { AUI=0, BNC=1, TPE=2 };
 	int ioaddr = dev->base_addr;
 
 	/* Grab the region so we can find another board if autoIRQ fails. */
@@ -796,11 +807,16 @@
 		lp->xmt_bar = XMT_BAR_10;
 		station_addr[0] = read_eeprom(ioaddr, 2, dev);
 	}
-	station_addr[1] = read_eeprom(ioaddr, 3, dev);
-	station_addr[2] = read_eeprom(ioaddr, 4, dev);
+
+	/* get all words at once. will be used here and for ethtool */
+	for (i = 0; i < 8; i++) {
+		lp->word[i] = read_eeprom(ioaddr, i, dev);
+	}
+	station_addr[1] = lp->word[3];
+	station_addr[2] = lp->word[4];
 
 	if (!lp->eepro) {
-		if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ)
+		if (lp->word[7] == ee_FX_INT2IRQ)
 			lp->eepro = 2;
 		else if (station_addr[2] == SA_ADDR1)
 			lp->eepro = 1;
@@ -817,15 +833,15 @@
 	/* calculate {xmt,rcv}_{lower,upper}_limit */
 	eepro_recalc(dev);
 
-	if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
+	if (GetBit(lp->word[5], ee_BNC_TPE))
 		dev->if_port = BNC;
 	else
 		dev->if_port = TPE;
 
  	if (dev->irq < 2 && lp->eepro != 0) {
  		/* Mask off INT number */
- 		int count = read_eeprom(ioaddr, 1, dev) & 7;
- 		unsigned irqMask = read_eeprom(ioaddr, 7, dev);
+ 		int count = lp->word[1] & 7;
+ 		unsigned irqMask = lp->word[7];
  
  		while (count--)
  			irqMask &= irqMask - 1;
@@ -850,6 +866,7 @@
  	dev->set_multicast_list = &set_multicast_list;
  	dev->tx_timeout		= eepro_tx_timeout;
  	dev->watchdog_timeo	= TX_TIMEOUT;
+	dev->ethtool_ops	= &eepro_ethtool_ops;
  
 	/* print boot time info */
 	eepro_print_info(dev);
@@ -941,7 +958,7 @@
 	if (net_debug > 3)
 		printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name);
 
-	irqMask = read_eeprom(ioaddr,7,dev);
+	irqMask = lp->word[7];
 
 	if (lp->eepro == LAN595FX_10ISA) {
 		if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n");
@@ -1070,8 +1087,6 @@
 		old9 = inb(ioaddr + 9);
 
 		if (irqMask==ee_FX_INT2IRQ) {
-			enum iftype { AUI=0, BNC=1, TPE=2 };
-
 			if (net_debug > 3) {
 				printk(KERN_DEBUG "IrqMask: %#x\n",irqMask);
 				printk(KERN_DEBUG "i82595FX detected!\n");
@@ -1701,12 +1716,72 @@
 	}
 }
 
+static int eepro_ethtool_get_settings(struct net_device *dev,
+					struct ethtool_cmd *cmd)
+{
+	struct eepro_local	*lp = (struct eepro_local *)dev->priv;
+
+	cmd->supported = 	SUPPORTED_10baseT_Half | 
+				SUPPORTED_10baseT_Full |
+				SUPPORTED_Autoneg;
+	cmd->advertising =	ADVERTISED_10baseT_Half |
+				ADVERTISED_10baseT_Full |
+				ADVERTISED_Autoneg;
+
+	if (GetBit(lp->word[5], ee_PortTPE)) {
+		cmd->supported |= SUPPORTED_TP;
+		cmd->advertising |= ADVERTISED_TP;
+	}
+	if (GetBit(lp->word[5], ee_PortBNC)) {
+		cmd->supported |= SUPPORTED_BNC;
+		cmd->advertising |= ADVERTISED_BNC;
+	}
+	if (GetBit(lp->word[5], ee_PortAUI)) {
+		cmd->supported |= SUPPORTED_AUI;
+		cmd->advertising |= ADVERTISED_AUI;
+	}
+
+	cmd->speed = SPEED_10;
+
+	if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
+		cmd->duplex = DUPLEX_FULL;
+	}
+	else {
+		cmd->duplex = DUPLEX_HALF;
+	}
+
+	cmd->port = dev->if_port;
+	cmd->phy_address = dev->base_addr;
+	cmd->transceiver = XCVR_INTERNAL;
+
+	if (lp->word[0] & ee_AutoNeg) {
+		cmd->autoneg = 1;
+	}
+
+	return 0;
+}
+
+static void eepro_ethtool_get_drvinfo(struct net_device *dev,
+					struct ethtool_drvinfo *drvinfo)
+{
+	strcpy(drvinfo->driver, DRV_NAME);
+	strcpy(drvinfo->version, DRV_VERSION);
+	sprintf(drvinfo->bus_info, "ISA 0x%lx", dev->base_addr);
+}
+
+static struct ethtool_ops eepro_ethtool_ops = {
+	.get_settings	= eepro_ethtool_get_settings,
+	.get_drvinfo 	= eepro_ethtool_get_drvinfo,
+};
+
 #ifdef MODULE
 
 #define MAX_EEPRO 8
 static struct net_device *dev_eepro[MAX_EEPRO];
 
-static int io[MAX_EEPRO];
+static int io[MAX_EEPRO] = {
+  [0 ... MAX_EEPRO-1] = -1
+};
 static int irq[MAX_EEPRO];
 static int mem[MAX_EEPRO] = {	/* Size of the rx buffer in KB */
   [0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024
@@ -1716,14 +1791,15 @@
 static int n_eepro;
 /* For linux 2.1.xx */
 
-MODULE_AUTHOR("Pascal Dupuis, and aris@cathedrallabs.org");
+MODULE_AUTHOR("Pascal Dupuis and others");
 MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(autodetect, "1-" __MODULE_STRING(1) "i");
+static int num_params;
+module_param_array(io, int, &num_params, 0);
+module_param_array(irq, int, &num_params, 0);
+module_param_array(mem, int, &num_params, 0);
+module_param(autodetect, int, 0);
 MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
 MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
 MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)");
@@ -1734,19 +1810,21 @@
 {
 	struct net_device *dev;
 	int i;
-	if (io[0] == 0 && autodetect == 0) {
+	if (io[0] == -1 && autodetect == 0) {
 		printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
 		printk(KERN_WARNING "eepro_init_module: Please add \"autodetect=1\" to force probe\n");
-		return 1;
+		return -ENODEV;
 	}
 	else if (autodetect) {
 		/* if autodetect is set then we must force detection */
-		io[0] = 0;
+		for (i = 0; i < MAX_EEPRO; i++) {
+			io[i] = 0;
+		}
 
 		printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n");
 	}
 
-	for (i = 0; i < MAX_EEPRO; i++) {
+	for (i = 0; io[i] != -1 && i < MAX_EEPRO; i++) {
 		dev = alloc_etherdev(sizeof(struct eepro_local));
 		if (!dev)
 			break;
diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c
--- a/drivers/net/hamachi.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/hamachi.c	2005-01-19 13:44:48 -08:00
@@ -512,6 +512,7 @@
 	u32 rx_int_var, tx_int_var;	/* interrupt control variables */
 	u32 option;							/* Hold on to a copy of the options */
 	struct pci_dev *pci_dev;
+	void __iomem *base;
 };
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>, Eric Kasten <kasten@nscl.msu.edu>, Keith Underwood <keithu@parl.clemson.edu>");
@@ -549,7 +550,7 @@
 MODULE_PARM_DESC(full_duplex, "GNIC-II full duplex setting(s) (1)");
 MODULE_PARM_DESC(force32, "GNIC-II: Bit 0: 32 bit PCI, bit 1: disable parity, bit 2: 64 bit PCI (all boards)");
                                                                         
-static int read_eeprom(long ioaddr, int location);
+static int read_eeprom(void __iomem *ioaddr, int location);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int hamachi_open(struct net_device *dev);
@@ -575,7 +576,8 @@
 	int option, i, rx_int_var, tx_int_var, boguscnt;
 	int chip_id = ent->driver_data;
 	int irq;
-	long ioaddr;
+	void __iomem *ioaddr;
+	unsigned long base;
 	static int card_idx;
 	struct net_device *dev;
 	void *ring_space;
@@ -594,9 +596,9 @@
 		goto err_out;
 	}
 
-	ioaddr = pci_resource_start(pdev, 0);
+	base = pci_resource_start(pdev, 0);
 #ifdef __alpha__				/* Really "64 bit addrs" */
-	ioaddr |= (pci_resource_start(pdev, 1) << 32);
+	base |= (pci_resource_start(pdev, 1) << 32);
 #endif
 
 	pci_set_master(pdev);
@@ -605,7 +607,7 @@
 	if (i) return i;
 
 	irq = pdev->irq;
-	ioaddr = (long) ioremap(ioaddr, 0x400);
+	ioaddr = ioremap(base, 0x400);
 	if (!ioaddr)
 		goto err_out_release;
 
@@ -678,7 +680,8 @@
 		i = readb(ioaddr + PCIClkMeas);	
 	}
 
-	dev->base_addr = ioaddr;
+	hmp->base = ioaddr;
+	dev->base_addr = (unsigned long)ioaddr;
 	dev->irq = irq;
 	pci_set_drvdata(pdev, dev);
 
@@ -741,7 +744,7 @@
 		goto err_out_unmap_rx;
 	}
 
-	printk(KERN_INFO "%s: %s type %x at 0x%lx, ",
+	printk(KERN_INFO "%s: %s type %x at %p, ",
 		   dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev),
 		   ioaddr);
 	for (i = 0; i < 5; i++)
@@ -790,14 +793,14 @@
 err_out_cleardev:
 	free_netdev (dev);
 err_out_iounmap:
-	iounmap((char *)ioaddr);
+	iounmap(ioaddr);
 err_out_release:
 	pci_release_regions(pdev);
 err_out:
 	return ret;
 }
 
-static int __devinit read_eeprom(long ioaddr, int location)
+static int __devinit read_eeprom(void __iomem *ioaddr, int location)
 {
 	int bogus_cnt = 1000;
 
@@ -819,7 +822,8 @@
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	int i;
 
 	/* We should check busy first - per docs -KDU */
@@ -836,7 +840,8 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	int i;
 
 	/* We should check busy first - per docs -KDU */
@@ -857,7 +862,7 @@
 static int hamachi_open(struct net_device *dev)
 {
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 	int i;
 	u32 rx_int_var, tx_int_var;
 	u16 fifo_info;
@@ -987,7 +992,7 @@
 	writew(0x001D, ioaddr + RxDMACtrl);
 	writew(0x001D, ioaddr + TxDMACtrl);
 #endif
-	writew(0x0001, dev->base_addr + RxCmd);
+	writew(0x0001, ioaddr + RxCmd);
 
 	if (hamachi_debug > 2) {
 		printk(KERN_DEBUG "%s: Done hamachi_open(), status: Rx %x Tx %x.\n",
@@ -1038,7 +1043,7 @@
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 	int next_tick = 10*HZ;
 
 	if (hamachi_debug > 2) {
@@ -1063,7 +1068,7 @@
 {
 	int i;
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 
 	printk(KERN_WARNING "%s: Hamachi transmit timed out, status %8.8x,"
 		   " resetting...\n", dev->name, (int)readw(ioaddr + TxStatus));
@@ -1115,7 +1120,7 @@
 	}
 
 	udelay(60); /* Sleep 60 us just for safety sake */
-	writew(0x0002, dev->base_addr + RxCmd); /* STOP Rx */
+	writew(0x0002, ioaddr + RxCmd); /* STOP Rx */
 		
 	writeb(0x01, ioaddr + ChipReset);  /* Reinit the hardware */ 
 
@@ -1157,9 +1162,9 @@
 	hmp->stats.tx_errors++;
 
 	/* Restart the chip's Tx/Rx processes . */
-	writew(0x0002, dev->base_addr + TxCmd); /* STOP Tx */
-	writew(0x0001, dev->base_addr + TxCmd); /* START Tx */
-	writew(0x0001, dev->base_addr + RxCmd); /* START Rx */
+	writew(0x0002, ioaddr + TxCmd); /* STOP Tx */
+	writew(0x0001, ioaddr + TxCmd); /* START Tx */
+	writew(0x0001, ioaddr + RxCmd); /* START Rx */
 
 	netif_wake_queue(dev);
 }
@@ -1275,9 +1280,9 @@
 
 		/* Wake the potentially-idle transmit channel. */
 		/* If we don't need to read status, DON'T -KDU */
-		status=readw(dev->base_addr + TxStatus);
+		status=readw(hmp->base + TxStatus);
 		if( !(status & 0x0001) || (status & 0x0002))
-			writew(0x0001, dev->base_addr + TxCmd);
+			writew(0x0001, hmp->base + TxCmd);
 		return 1;
 	} 
 
@@ -1343,9 +1348,9 @@
 
 	/* Wake the potentially-idle transmit channel. */
 	/* If we don't need to read status, DON'T -KDU */
-	status=readw(dev->base_addr + TxStatus);
+	status=readw(hmp->base + TxStatus);
 	if( !(status & 0x0001) || (status & 0x0002))
-		writew(0x0001, dev->base_addr + TxCmd);
+		writew(0x0001, hmp->base + TxCmd);
 
 	/* Immediately before returning, let's clear as many entries as we can. */
 	hamachi_tx(dev);
@@ -1376,8 +1381,9 @@
 static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = dev_instance;
-	struct hamachi_private *hmp;
-	long ioaddr, boguscnt = max_interrupt_work;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
+	long boguscnt = max_interrupt_work;
 	int handled = 0;
 
 #ifndef final_version			/* Can never occur. */
@@ -1387,8 +1393,6 @@
 	}
 #endif
 
-	ioaddr = dev->base_addr;
-	hmp = netdev_priv(dev);
 	spin_lock(&hmp->lock);
 
 	do {
@@ -1687,8 +1691,8 @@
 
 	/* Restart Rx engine if stopped. */
 	/* If we don't need to check status, don't. -KDU */
-	if (readw(dev->base_addr + RxStatus) & 0x0002)
-		writew(0x0001, dev->base_addr + RxCmd);
+	if (readw(hmp->base + RxStatus) & 0x0002)
+		writew(0x0001, hmp->base + RxCmd);
 
 	return 0;
 }
@@ -1697,8 +1701,8 @@
    than just errors. */
 static void hamachi_error(struct net_device *dev, int intr_status)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	if (intr_status & (LinkChange|NegotiationChange)) {
 		if (hamachi_debug > 1)
@@ -1731,8 +1735,8 @@
 
 static int hamachi_close(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	struct sk_buff *skb;
 	int i;
 
@@ -1817,8 +1821,8 @@
 
 static struct net_device_stats *hamachi_get_stats(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	/* We should lock this segment of code for SMP eventually, although
 	   the vulnerability window is very small and statistics are
@@ -1845,7 +1849,8 @@
 
 static void set_rx_mode(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		/* Unconditionally log net taps. */
@@ -1950,11 +1955,11 @@
 		 */
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		writel(d[0], dev->base_addr + TxIntrCtrl);
-		writel(d[1], dev->base_addr + RxIntrCtrl);
+		writel(d[0], np->base + TxIntrCtrl);
+		writel(d[1], np->base + RxIntrCtrl);
 		printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
-		  (u32) readl(dev->base_addr + TxIntrCtrl),
-		  (u32) readl(dev->base_addr + RxIntrCtrl));
+		  (u32) readl(np->base + TxIntrCtrl),
+		  (u32) readl(np->base + RxIntrCtrl));
 		rc = 0;
 	}
 
@@ -1980,7 +1985,7 @@
 		pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring, 
 			hmp->tx_ring_dma);
 		unregister_netdev(dev);
-		iounmap((char *)dev->base_addr);
+		iounmap(hmp->base);
 		free_netdev(dev);
 		pci_release_regions(pdev);
 		pci_set_drvdata(pdev, NULL);
diff -Nru a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
--- a/drivers/net/ibm_emac/ibm_emac.h	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/ibm_emac/ibm_emac.h	2005-01-19 13:44:48 -08:00
@@ -98,7 +98,7 @@
 #endif				/* CONFIG_IBM_EMAC4 */
 #define EMAC_M1_BASE			(EMAC_M1_TX_FIFO_2K | \
 					EMAC_M1_APP | \
-					EMAC_M1_TR)
+					EMAC_M1_TR | EMAC_M1_VLE)
 
 /* Transmit Mode Register 0 */
 #define EMAC_TMR0_GNP0			0x80000000
diff -Nru a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
--- a/drivers/net/ibm_emac/ibm_emac_core.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/net/ibm_emac/ibm_emac_core.c	2005-01-19 13:44:45 -08:00
@@ -1363,6 +1363,9 @@
 
 	/* set frame gap */
 	out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP);
+	
+	/* set VLAN Tag Protocol Identifier */
+	out_be32(&emacp->em0vtpid, 0x8100);
 
 	/* Init ring buffers */
 	emac_init_rings(fep->ndev);
@@ -1700,6 +1703,15 @@
 	.rxde = &emac_rxde_dev,
 };
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static int emac_netpoll(struct net_device *ndev)
+{
+	emac_rxeob_dev((void *)ndev, 0);
+	emac_txeob_dev((void *)ndev, 0);
+	return 0;
+}
+#endif
+
 static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
 {
 	int deferred_init = 0;
@@ -1882,6 +1894,9 @@
 	SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
 	if (emacdata->tah_idx >= 0)
 		ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	ndev->poll_controller = emac_netpoll;
+#endif
 
 	SET_MODULE_OWNER(ndev);
 
diff -Nru a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c
--- a/drivers/net/ibm_emac/ibm_emac_phy.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/ibm_emac/ibm_emac_phy.c	2005-01-19 13:44:47 -08:00
@@ -191,17 +191,18 @@
 	u16 lpa;
 
 	if (phy->autoneg) {
-		lpa = phy_read(phy, MII_LPA);
+		lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
 
-		if (lpa & (LPA_10FULL | LPA_100FULL))
-			phy->duplex = DUPLEX_FULL;
-		else
-			phy->duplex = DUPLEX_HALF;
-		if (lpa & (LPA_100FULL | LPA_100HALF))
-			phy->speed = SPEED_100;
-		else
-			phy->speed = SPEED_10;
+		phy->speed = SPEED_10;
+		phy->duplex = DUPLEX_HALF;
 		phy->pause = 0;
+
+		if (lpa & (LPA_100FULL | LPA_100HALF)) {
+			phy->speed = SPEED_100;
+			if (lpa & LPA_100FULL)
+				phy->duplex = DUPLEX_FULL;
+		} else if (lpa & LPA_10FULL)
+			phy->duplex = DUPLEX_FULL;
 	}
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	 * though magic-aneg shouldn't prevent this case from occurring
diff -Nru a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c
--- a/drivers/net/irda/sir_kthread.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/irda/sir_kthread.c	2005-01-19 13:44:48 -08:00
@@ -19,7 +19,6 @@
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
-#include <linux/suspend.h>
 
 #include <net/irda/irda.h>
 
diff -Nru a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
--- a/drivers/net/irda/stir4200.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/irda/stir4200.c	2005-01-19 13:44:46 -08:00
@@ -46,7 +46,6 @@
 #include <linux/time.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/suspend.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/usb.h>
diff -Nru a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
--- a/drivers/net/iseries_veth.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/iseries_veth.c	2005-01-19 13:44:47 -08:00
@@ -642,7 +642,7 @@
 	return 0;
 }
 
-static void veth_destroy_connection(u8 rlp)
+static void veth_stop_connection(u8 rlp)
 {
 	struct veth_lpar_connection *cnx = veth_cnx[rlp];
 
@@ -671,9 +671,18 @@
 				      HvLpEvent_Type_VirtualLan,
 				      cnx->num_ack_events,
 				      NULL, NULL);
+}
+
+static void veth_destroy_connection(u8 rlp)
+{
+	struct veth_lpar_connection *cnx = veth_cnx[rlp];
+
+	if (! cnx)
+		return;
 
-	if (cnx->msgs)
-		kfree(cnx->msgs);
+	kfree(cnx->msgs);
+	kfree(cnx);
+	veth_cnx[rlp] = NULL;
 }
 
 /*
@@ -1375,9 +1384,18 @@
 	vio_unregister_driver(&veth_driver);
 
 	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
-		veth_destroy_connection(i);
+		veth_stop_connection(i);
 
 	HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
+
+	/* Hypervisor callbacks may have scheduled more work while we
+	 * were destroying connections. Now that we've disconnected from
+	 * the hypervisor make sure everything's finished. */
+	flush_scheduled_work();
+
+	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
+		veth_destroy_connection(i);
+
 }
 module_exit(veth_module_cleanup);
 
diff -Nru a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
--- a/drivers/net/ixgb/ixgb.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/ixgb/ixgb.h	2005-01-19 13:44:46 -08:00
@@ -46,6 +46,7 @@
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/pagemap.h>
@@ -85,6 +86,20 @@
 
 #define IXGB_ERR(args...) printk(KERN_ERR "ixgb: " args)
 
+/* TX/RX descriptor defines */
+#define DEFAULT_TXD	 256
+#define MAX_TXD   	4096
+#define MIN_TXD	  64
+
+/* hardware cannot reliably support more than 512 descriptors owned by
+ * hardware descrioptor cache otherwise an unreliable ring under heavy 
+ * recieve load may result */
+/* #define DEFAULT_RXD	   1024 */
+/* #define MAX_RXD	   4096 */
+#define DEFAULT_RXD	512
+#define MAX_RXD	512
+#define MIN_RXD	 64
+
 /* Supported Rx Buffer Sizes */
 #define IXGB_RXBUFFER_2048  2048
 #define IXGB_RXBUFFER_4096  4096
@@ -105,9 +120,9 @@
 struct ixgb_buffer {
 	struct sk_buff *skb;
 	uint64_t dma;
-	unsigned long length;
 	unsigned long time_stamp;
-	unsigned int next_to_watch;
+	uint16_t length;
+	uint16_t next_to_watch;
 };
 
 struct ixgb_desc_ring {
@@ -167,7 +182,6 @@
 	uint64_t hw_csum_rx_error;
 	uint64_t hw_csum_rx_good;
 	uint32_t rx_int_delay;
-	boolean_t raidc;
 	boolean_t rx_csum;
 
 	/* OS defined structs */
@@ -178,5 +192,8 @@
 	/* structs defined in ixgb_hw.h */
 	struct ixgb_hw hw;
 	struct ixgb_hw_stats stats;
+#ifdef CONFIG_PCI_MSI
+	boolean_t have_msi;
+#endif
 };
-#endif				/* _IXGB_H_ */
+#endif /* _IXGB_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
--- a/drivers/net/ixgb/ixgb_ee.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/ixgb/ixgb_ee.c	2005-01-19 13:44:48 -08:00
@@ -32,7 +32,8 @@
 static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw);
 
 static void ixgb_shift_out_bits(struct ixgb_hw *hw,
-				uint16_t data, uint16_t count);
+				uint16_t data,
+				uint16_t count);
 static void ixgb_standby_eeprom(struct ixgb_hw *hw);
 
 static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);
@@ -45,7 +46,9 @@
  * hw - Struct containing variables accessed by shared code
  * eecd_reg - EECD's current value
  *****************************************************************************/
-static void ixgb_raise_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
+static void
+ixgb_raise_clock(struct ixgb_hw *hw,
+		  uint32_t *eecd_reg)
 {
 	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
 	 *  wait 50 microseconds.
@@ -62,7 +65,9 @@
  * hw - Struct containing variables accessed by shared code
  * eecd_reg - EECD's current value
  *****************************************************************************/
-static void ixgb_lower_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
+static void
+ixgb_lower_clock(struct ixgb_hw *hw,
+		  uint32_t *eecd_reg)
 {
 	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
 	 * wait 50 microseconds.
@@ -81,7 +86,9 @@
  * count - number of bits to shift out
  *****************************************************************************/
 static void
-ixgb_shift_out_bits(struct ixgb_hw *hw, uint16_t data, uint16_t count)
+ixgb_shift_out_bits(struct ixgb_hw *hw,
+					 uint16_t data,
+					 uint16_t count)
 {
 	uint32_t eecd_reg;
 	uint32_t mask;
@@ -101,7 +108,7 @@
 		 */
 		eecd_reg &= ~IXGB_EECD_DI;
 
-		if (data & mask)
+		if(data & mask)
 			eecd_reg |= IXGB_EECD_DI;
 
 		IXGB_WRITE_REG(hw, EECD, eecd_reg);
@@ -113,7 +120,7 @@
 
 		mask = mask >> 1;
 
-	} while (mask);
+	} while(mask);
 
 	/* We leave the "DI" bit set to "0" when we leave this routine. */
 	eecd_reg &= ~IXGB_EECD_DI;
@@ -126,7 +133,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw)
+static uint16_t
+ixgb_shift_in_bits(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 	uint32_t i;
@@ -144,14 +152,14 @@
 	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
 	data = 0;
 
-	for (i = 0; i < 16; i++) {
+	for(i = 0; i < 16; i++) {
 		data = data << 1;
 		ixgb_raise_clock(hw, &eecd_reg);
 
 		eecd_reg = IXGB_READ_REG(hw, EECD);
 
 		eecd_reg &= ~(IXGB_EECD_DI);
-		if (eecd_reg & IXGB_EECD_DO)
+		if(eecd_reg & IXGB_EECD_DO)
 			data |= 1;
 
 		ixgb_lower_clock(hw, &eecd_reg);
@@ -168,7 +176,8 @@
  * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
  * function should be called before issuing a command to the EEPROM.
  *****************************************************************************/
-static void ixgb_setup_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_setup_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -189,7 +198,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_standby_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_standby_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -222,7 +232,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_clock_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_clock_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -245,7 +256,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_cleanup_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_cleanup_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -270,7 +282,8 @@
  *      TRUE: EEPROM data pin is high before timeout.
  *      FALSE:  Time expired.
  *****************************************************************************/
-static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw)
+static boolean_t
+ixgb_wait_eeprom_command(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 	uint32_t i;
@@ -284,10 +297,10 @@
 	 * signal that the command has been completed by raising the DO signal.
 	 * If DO does not go high in 10 milliseconds, then error out.
 	 */
-	for (i = 0; i < 200; i++) {
+	for(i = 0; i < 200; i++) {
 		eecd_reg = IXGB_READ_REG(hw, EECD);
 
-		if (eecd_reg & IXGB_EECD_DO)
+		if(eecd_reg & IXGB_EECD_DO)
 			return (TRUE);
 
 		udelay(50);
@@ -309,15 +322,16 @@
  *  TRUE: Checksum is valid
  *  FALSE: Checksum is not valid.
  *****************************************************************************/
-boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)
+boolean_t
+ixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
 {
 	uint16_t checksum = 0;
 	uint16_t i;
 
-	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
+	for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
 		checksum += ixgb_read_eeprom(hw, i);
 
-	if (checksum == (uint16_t) EEPROM_SUM)
+	if(checksum == (uint16_t) EEPROM_SUM)
 		return (TRUE);
 	else
 		return (FALSE);
@@ -331,12 +345,13 @@
  * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
  * Writes the difference to word offset 63 of the EEPROM.
  *****************************************************************************/
-void ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
+void
+ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
 {
 	uint16_t checksum = 0;
 	uint16_t i;
 
-	for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
+	for(i = 0; i < EEPROM_CHECKSUM_REG; i++)
 		checksum += ixgb_read_eeprom(hw, i);
 
 	checksum = (uint16_t) EEPROM_SUM - checksum;
@@ -356,7 +371,10 @@
  * EEPROM will most likely contain an invalid checksum.
  *
  *****************************************************************************/
-void ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data)
+void
+ixgb_write_eeprom(struct ixgb_hw *hw,
+		   uint16_t offset,
+		   uint16_t data)
 {
 	/*  Prepare the EEPROM for writing  */
 	ixgb_setup_eeprom(hw);
@@ -404,7 +422,9 @@
  * Returns:
  *  The 16-bit value read from the eeprom
  *****************************************************************************/
-uint16_t ixgb_read_eeprom(struct ixgb_hw * hw, uint16_t offset)
+uint16_t
+ixgb_read_eeprom(struct ixgb_hw *hw,
+		  uint16_t offset)
 {
 	uint16_t data;
 
@@ -437,7 +457,8 @@
  *      TRUE: if eeprom read is successful
  *      FALSE: otherwise.
  *****************************************************************************/
-boolean_t ixgb_get_eeprom_data(struct ixgb_hw * hw)
+boolean_t
+ixgb_get_eeprom_data(struct ixgb_hw *hw)
 {
 	uint16_t i;
 	uint16_t checksum = 0;
@@ -448,7 +469,7 @@
 	ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
 	DEBUGOUT("ixgb_ee: Reading eeprom data\n");
-	for (i = 0; i < IXGB_EEPROM_SIZE; i++) {
+	for(i = 0; i < IXGB_EEPROM_SIZE ; i++) {
 		uint16_t ee_data;
 		ee_data = ixgb_read_eeprom(hw, i);
 		checksum += ee_data;
@@ -461,12 +482,12 @@
 	}
 
 	if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
-	    != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
+		 != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
 		DEBUGOUT("ixgb_ee: Signature invalid.\n");
-		return (FALSE);
+		return(FALSE);
 	}
 
-	return (TRUE);
+	return(TRUE);
 }
 
 /******************************************************************************
@@ -479,7 +500,8 @@
  *      TRUE: eeprom signature was good and the eeprom read was successful
  *      FALSE: otherwise.
  ******************************************************************************/
-static boolean_t ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
+static boolean_t
+ixgb_check_and_get_eeprom_data (struct ixgb_hw* hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
@@ -500,15 +522,16 @@
  * Returns:
  *          Word at indexed offset in eeprom, if valid, 0 otherwise.
  ******************************************************************************/
-uint16_t ixgb_get_eeprom_word(struct ixgb_hw * hw, uint16_t index)
+uint16_t
+ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index)
 {
 
 	if ((index < IXGB_EEPROM_SIZE) &&
-	    (ixgb_check_and_get_eeprom_data(hw) == TRUE)) {
-		return (hw->eeprom[index]);
+		(ixgb_check_and_get_eeprom_data(hw) == TRUE)) {
+	   return(hw->eeprom[index]);
 	}
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -519,7 +542,9 @@
  *
  * Returns: None.
  ******************************************************************************/
-void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr)
+void
+ixgb_get_ee_mac_addr(struct ixgb_hw *hw,
+			uint8_t *mac_addr)
 {
 	int i;
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
@@ -542,14 +567,15 @@
  * Returns:
  *          compatibility flags if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw)
+uint16_t
+ixgb_get_ee_compatibility(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->compatibility);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->compatibility);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -560,13 +586,14 @@
  * Returns:
  *          PBA number if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint32_t ixgb_get_ee_pba_number(struct ixgb_hw * hw)
+uint32_t
+ixgb_get_ee_pba_number(struct ixgb_hw *hw)
 {
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
 		return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
-			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG]) << 16));
+			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16));
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -577,14 +604,15 @@
  * Returns:
  *          Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->init_ctrl_reg_1);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->init_ctrl_reg_1);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -595,14 +623,15 @@
  * Returns:
  *          Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->init_ctrl_reg_2);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->init_ctrl_reg_2);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -613,14 +642,15 @@
  * Returns:
  *          Subsystem Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_subsystem_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->subsystem_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+	   return(ee_map->subsystem_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -631,14 +661,15 @@
  * Returns:
  *          Sub Vendor Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_subvendor_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->subvendor_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->subvendor_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -649,14 +680,15 @@
  * Returns:
  *          Device Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_device_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_device_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->device_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->device_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -667,14 +699,15 @@
  * Returns:
  *          Device Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_vendor_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->vendor_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->vendor_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -685,14 +718,15 @@
  * Returns:
  *          SDP Register if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->swdpins_reg);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->swdpins_reg);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -703,14 +737,15 @@
  * Returns:
  *          D3 Power Management Bits if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint8_t ixgb_get_ee_d3_power(struct ixgb_hw * hw)
+uint8_t
+ixgb_get_ee_d3_power(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->d3_power);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->d3_power);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -721,12 +756,13 @@
  * Returns:
  *          D0 Power Management Bits if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint8_t ixgb_get_ee_d0_power(struct ixgb_hw * hw)
+uint8_t
+ixgb_get_ee_d0_power(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->d0_power);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->d0_power);
 
-	return (0);
+	return(0);
 }
diff -Nru a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
--- a/drivers/net/ixgb/ixgb_ethtool.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/ixgb/ixgb_ethtool.c	2005-01-19 13:44:47 -08:00
@@ -37,6 +37,12 @@
 
 extern int ixgb_up(struct ixgb_adapter *adapter);
 extern void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
+extern void ixgb_reset(struct ixgb_adapter *adapter);
+extern int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
+extern int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_update_stats(struct ixgb_adapter *adapter);
 
 struct ixgb_stats {
 	char stat_string[ETH_GSTRING_LEN];
@@ -89,7 +95,7 @@
 	sizeof(ixgb_gstrings_stats) / sizeof(struct ixgb_stats)
 
 static int
-ixgb_ethtool_gset(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
@@ -97,7 +103,7 @@
 	ecmd->port = PORT_FIBRE;
 	ecmd->transceiver = XCVR_EXTERNAL;
 
-	if (netif_carrier_ok(adapter->netdev)) {
+	if(netif_carrier_ok(adapter->netdev)) {
 		ecmd->speed = SPEED_10000;
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
@@ -110,86 +116,140 @@
 }
 
 static int
-ixgb_ethtool_sset(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	if (ecmd->autoneg == AUTONEG_ENABLE ||
-	    ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
+	if(ecmd->autoneg == AUTONEG_ENABLE ||
+	   ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
 		return -EINVAL;
-	else {
+	
+	if(netif_running(adapter->netdev)) {
 		ixgb_down(adapter, TRUE);
+		ixgb_reset(adapter);
 		ixgb_up(adapter);
-	}
+	} else
+		ixgb_reset(adapter);
+
 	return 0;
 }
 
 static void
-ixgb_ethtool_gpause(struct net_device *dev,
-		    struct ethtool_pauseparam *epause)
+ixgb_get_pauseparam(struct net_device *netdev,
+			 struct ethtool_pauseparam *pause)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-
-	epause->autoneg = AUTONEG_DISABLE;
-
-	if (hw->fc.type == ixgb_fc_rx_pause)
-		epause->rx_pause = 1;
-	else if (hw->fc.type == ixgb_fc_tx_pause)
-		epause->tx_pause = 1;
-	else if (hw->fc.type == ixgb_fc_full) {
-		epause->rx_pause = 1;
-		epause->tx_pause = 1;
+	
+	pause->autoneg = AUTONEG_DISABLE;
+		
+	if(hw->fc.type == ixgb_fc_rx_pause)
+		pause->rx_pause = 1;
+	else if(hw->fc.type == ixgb_fc_tx_pause)
+		pause->tx_pause = 1;
+	else if(hw->fc.type == ixgb_fc_full) {
+		pause->rx_pause = 1;
+		pause->tx_pause = 1;
 	}
 }
 
 static int
-ixgb_ethtool_spause(struct net_device *dev,
-		    struct ethtool_pauseparam *epause)
+ixgb_set_pauseparam(struct net_device *netdev,
+			 struct ethtool_pauseparam *pause)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-
-	if (epause->autoneg == AUTONEG_ENABLE)
+	
+	if(pause->autoneg == AUTONEG_ENABLE)
 		return -EINVAL;
 
-	if (epause->rx_pause && epause->tx_pause)
+	if(pause->rx_pause && pause->tx_pause)
 		hw->fc.type = ixgb_fc_full;
-	else if (epause->rx_pause && !epause->tx_pause)
+	else if(pause->rx_pause && !pause->tx_pause)
 		hw->fc.type = ixgb_fc_rx_pause;
-	else if (!epause->rx_pause && epause->tx_pause)
+	else if(!pause->rx_pause && pause->tx_pause)
 		hw->fc.type = ixgb_fc_tx_pause;
-	else if (!epause->rx_pause && !epause->tx_pause)
+	else if(!pause->rx_pause && !pause->tx_pause)
 		hw->fc.type = ixgb_fc_none;
 
-	ixgb_down(adapter, TRUE);
-	ixgb_up(adapter);
-
+	if(netif_running(adapter->netdev)) {
+		ixgb_down(adapter, TRUE);
+		ixgb_up(adapter);
+	} else
+		ixgb_reset(adapter);
+		
 	return 0;
 }
 
-static void
-ixgb_ethtool_gdrvinfo(struct net_device *netdev,
-		      struct ethtool_drvinfo *drvinfo)
+static uint32_t
+ixgb_get_rx_csum(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	strncpy(drvinfo->driver, ixgb_driver_name, 32);
-	strncpy(drvinfo->version, ixgb_driver_version, 32);
-	strncpy(drvinfo->fw_version, "N/A", 32);
-	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	return adapter->rx_csum;
 }
 
+static int
+ixgb_set_rx_csum(struct net_device *netdev, uint32_t data)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	adapter->rx_csum = data;
+
+	if(netif_running(netdev)) {
+		ixgb_down(adapter,TRUE);
+		ixgb_up(adapter);
+	} else
+		ixgb_reset(adapter);
+	return 0;
+}
+	
+static uint32_t
+ixgb_get_tx_csum(struct net_device *netdev)
+{
+	return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+static int
+ixgb_set_tx_csum(struct net_device *netdev, uint32_t data)
+{
+	if (data)
+		netdev->features |= NETIF_F_HW_CSUM;
+	else
+		netdev->features &= ~NETIF_F_HW_CSUM;
+
+	return 0;
+}
+
+#ifdef NETIF_F_TSO
+static int
+ixgb_set_tso(struct net_device *netdev, uint32_t data)
+{
+	if(data)
+		netdev->features |= NETIF_F_TSO;
+	else
+		netdev->features &= ~NETIF_F_TSO;
+	return 0;
+} 
+#endif /* NETIF_F_TSO */
+
 #define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
+
+static int 
+ixgb_get_regs_len(struct net_device *netdev)
+{
+#define IXGB_REG_DUMP_LEN  136*sizeof(uint32_t)
+	return IXGB_REG_DUMP_LEN;
+}
+
 static void
-ixgb_ethtool_gregs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
+ixgb_get_regs(struct net_device *netdev,
+		   struct ethtool_regs *regs, void *p)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	uint32_t *reg = buf;
+	uint32_t *reg = p;
 	uint32_t *reg_start = reg;
 	uint8_t i;
 
-	regs->version =
-	    (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
+	regs->version = (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
 
 	/* General Registers */
 	*reg++ = IXGB_READ_REG(hw, CTRL0);	/*   0 */
@@ -219,8 +279,8 @@
 	*reg++ = IXGB_READ_REG(hw, RXCSUM);	/*  20 */
 
 	for (i = 0; i < IXGB_RAR_ENTRIES; i++) {
-		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1));	/*21,...,51 */
-		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1));	/*22,...,52 */
+		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
+		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
 	}
 
 	/* Transmit */
@@ -316,73 +376,222 @@
 }
 
 static int
-ixgb_ethtool_geeprom(struct net_device *dev,
-		     struct ethtool_eeprom *eeprom, u8 *data)
+ixgb_get_eeprom_len(struct net_device *netdev)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	/* return size in bytes */
+	return (IXGB_EEPROM_SIZE << 1);
+}
+
+static int
+ixgb_get_eeprom(struct net_device *netdev,
+		  struct ethtool_eeprom *eeprom, uint8_t *bytes)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
+	uint16_t *eeprom_buff;
+	int i, max_len, first_word, last_word;
+	int ret_val = 0;
+
+	if(eeprom->len == 0) {
+		ret_val = -EINVAL;
+		goto geeprom_error;
+	}
 
 	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
 
-	/* use our function to read the eeprom and update our cache */
-	ixgb_get_eeprom_data(hw);
-	memcpy(data, (char *)hw->eeprom + eeprom->offset, eeprom->len);
-	return 0;
+	max_len = ixgb_get_eeprom_len(netdev);
+
+	if(eeprom->offset > eeprom->offset + eeprom->len) {
+		ret_val = -EINVAL;
+		goto geeprom_error;
+	}
+
+	if((eeprom->offset + eeprom->len) > max_len)
+		eeprom->len = (max_len - eeprom->offset);
+
+	first_word = eeprom->offset >> 1;
+	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+
+	eeprom_buff = kmalloc(sizeof(uint16_t) *
+			(last_word - first_word + 1), GFP_KERNEL);
+	if(!eeprom_buff)
+		return -ENOMEM;
+
+	/* note the eeprom was good because the driver loaded */
+	for(i = 0; i <= (last_word - first_word); i++) {
+		eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
+	}
+
+	memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset & 1),
+			eeprom->len);
+	kfree(eeprom_buff);
+
+geeprom_error:
+	return ret_val;
 }
 
 static int
-ixgb_ethtool_seeprom(struct net_device *dev,
-		     struct ethtool_eeprom *eeprom, u8 *data)
+ixgb_set_eeprom(struct net_device *netdev,
+		  struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	/* We are under rtnl, so static is OK */
-	static uint16_t eeprom_buff[IXGB_EEPROM_SIZE];
-	int i, first_word, last_word;
-	char *ptr;
+	uint16_t *eeprom_buff;
+	void *ptr;
+	int max_len, first_word, last_word;
+	uint16_t i;
+
+	if(eeprom->len == 0)
+		return -EINVAL;
 
-	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+	if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
 		return -EFAULT;
 
+	max_len = ixgb_get_eeprom_len(netdev);
+
+	if(eeprom->offset > eeprom->offset + eeprom->len)
+		return -EINVAL;
+
+	if((eeprom->offset + eeprom->len) > max_len)
+		eeprom->len = (max_len - eeprom->offset);
+
 	first_word = eeprom->offset >> 1;
 	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
-	ptr = (char *)eeprom_buff;
+	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+	if(!eeprom_buff)
+		return -ENOMEM;
+
+	ptr = (void *)eeprom_buff;
 
-	if (eeprom->offset & 1) {
+	if(eeprom->offset & 1) {
 		/* need read/modify/write of first changed EEPROM word */
 		/* only the second byte of the word is being modified */
 		eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
 		ptr++;
 	}
-	if ((eeprom->offset + eeprom->len) & 1) {
+	if((eeprom->offset + eeprom->len) & 1) {
 		/* need read/modify/write of last changed EEPROM word */
 		/* only the first byte of the word is being modified */
-		eeprom_buff[last_word - first_word]
-		    = ixgb_read_eeprom(hw, last_word);
+		eeprom_buff[last_word - first_word] 
+			= ixgb_read_eeprom(hw, last_word);
 	}
-	memcpy(ptr, data, eeprom->len);
 
-	for (i = 0; i <= (last_word - first_word); i++)
+	memcpy(ptr, bytes, eeprom->len);
+	for(i = 0; i <= (last_word - first_word); i++)
 		ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
 
 	/* Update the checksum over the first part of the EEPROM if needed */
-	if (first_word <= EEPROM_CHECKSUM_REG)
+	if(first_word <= EEPROM_CHECKSUM_REG)
 		ixgb_update_eeprom_checksum(hw);
 
+	kfree(eeprom_buff);
 	return 0;
 }
 
+static void
+ixgb_get_drvinfo(struct net_device *netdev,
+		   struct ethtool_drvinfo *drvinfo)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+
+	strncpy(drvinfo->driver,  ixgb_driver_name, 32);
+	strncpy(drvinfo->version, ixgb_driver_version, 32);
+	strncpy(drvinfo->fw_version, "N/A", 32);
+	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	drvinfo->n_stats = IXGB_STATS_LEN;
+	drvinfo->regdump_len = ixgb_get_regs_len(netdev);
+	drvinfo->eedump_len = ixgb_get_eeprom_len(netdev);
+}
+
+static void
+ixgb_get_ringparam(struct net_device *netdev,
+		struct ethtool_ringparam *ring)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
+	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
+
+	ring->rx_max_pending = MAX_RXD; 
+	ring->tx_max_pending = MAX_TXD;
+	ring->rx_mini_max_pending = 0;
+	ring->rx_jumbo_max_pending = 0;
+	ring->rx_pending = rxdr->count;
+	ring->tx_pending = txdr->count;
+	ring->rx_mini_pending = 0;
+	ring->rx_jumbo_pending = 0;
+}
+
+static int 
+ixgb_set_ringparam(struct net_device *netdev,
+		struct ethtool_ringparam *ring)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
+	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
+	struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
+	int err;
+
+	tx_old = adapter->tx_ring;
+	rx_old = adapter->rx_ring;
+
+	if((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+		return -EINVAL;
+
+	if(netif_running(adapter->netdev))
+		ixgb_down(adapter,TRUE);
+
+	rxdr->count = max(ring->rx_pending,(uint32_t)MIN_RXD);
+	rxdr->count = min(rxdr->count,(uint32_t)MAX_RXD);
+	IXGB_ROUNDUP(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); 
+
+	txdr->count = max(ring->tx_pending,(uint32_t)MIN_TXD);
+	txdr->count = min(txdr->count,(uint32_t)MAX_TXD);
+	IXGB_ROUNDUP(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); 
+
+	if(netif_running(adapter->netdev)) {
+		/* Try to get new resources before deleting old */
+		if((err = ixgb_setup_rx_resources(adapter)))
+			goto err_setup_rx;
+		if((err = ixgb_setup_tx_resources(adapter)))
+			goto err_setup_tx;
+
+		/* save the new, restore the old in order to free it,
+		 * then restore the new back again */
+
+		rx_new = adapter->rx_ring;
+		tx_new = adapter->tx_ring;
+		adapter->rx_ring = rx_old;
+		adapter->tx_ring = tx_old;
+		ixgb_free_rx_resources(adapter);
+		ixgb_free_tx_resources(adapter);
+		adapter->rx_ring = rx_new;
+		adapter->tx_ring = tx_new;
+		if((err = ixgb_up(adapter)))
+			return err;
+	}
+
+	return 0;
+err_setup_tx:
+	ixgb_free_rx_resources(adapter);
+err_setup_rx:
+	adapter->rx_ring = rx_old;
+	adapter->tx_ring = tx_old;
+	ixgb_up(adapter);
+	return err;
+}
+
 /* toggle LED 4 times per second = 2 "blinks" per second */
 #define IXGB_ID_INTERVAL	(HZ/4)
 
 /* bit defines for adapter->led_status */
 #define IXGB_LED_ON		0
 
-static void ixgb_led_blink_callback(unsigned long data)
+static void
+ixgb_led_blink_callback(unsigned long data)
 {
 	struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
 
-	if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
+	if(test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
 		ixgb_led_off(&adapter->hw);
 	else
 		ixgb_led_on(&adapter->hw);
@@ -391,10 +600,14 @@
 }
 
 static int
-ixgb_ethtool_led_blink(struct net_device *netdev, u32 data)
+ixgb_phys_id(struct net_device *netdev, uint32_t data)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	if (!adapter->blink_timer.function) {
+
+	if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
+		data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
+
+	if(!adapter->blink_timer.function) {
 		init_timer(&adapter->blink_timer);
 		adapter->blink_timer.function = ixgb_led_blink_callback;
 		adapter->blink_timer.data = (unsigned long)adapter;
@@ -403,7 +616,7 @@
 	mod_timer(&adapter->blink_timer, jiffies);
 
 	set_current_state(TASK_INTERRUPTIBLE);
-	if (data)
+	if(data)
 		schedule_timeout(data * HZ);
 	else
 		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
@@ -415,141 +628,74 @@
 	return 0;
 }
 
-static int ixgb_nway_reset(struct net_device *netdev)
-{
-	if (netif_running(netdev)) {
-		struct ixgb_adapter *adapter = netdev->priv;
-		ixgb_down(adapter, TRUE);
-		ixgb_up(adapter);
-	}
-	return 0;
-}
-
-static int ixgb_get_stats_count(struct net_device *dev)
+static int 
+ixgb_get_stats_count(struct net_device *netdev)
 {
 	return IXGB_STATS_LEN;
 }
 
-static void ixgb_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+static void 
+ixgb_get_ethtool_stats(struct net_device *netdev, 
+		struct ethtool_stats *stats, uint64_t *data)
 {
+	struct ixgb_adapter *adapter = netdev->priv;
 	int i;
-	for (i = 0; i < IXGB_STATS_LEN; i++) {
-		memcpy(data + i * ETH_GSTRING_LEN,
-		       ixgb_gstrings_stats[i].stat_string,
-		       ETH_GSTRING_LEN);
-	}
-}
-
-static int ixgb_get_regs_len(struct net_device *dev)
-{
-	return 136*sizeof(uint32_t);
-}
 
-static int ixgb_get_eeprom_len(struct net_device *dev)
-{
-	/* return size in bytes */
-	return (IXGB_EEPROM_SIZE << 1);
+	ixgb_update_stats(adapter);
+	for(i = 0; i < IXGB_STATS_LEN; i++) {
+		char *p = (char *)adapter+ixgb_gstrings_stats[i].stat_offset;	
+		data[i] = (ixgb_gstrings_stats[i].sizeof_stat == 
+			sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
+	}
 }
 
-static void get_ethtool_stats(struct net_device *dev,
-		struct ethtool_stats *stats, u64 *data)
+static void 
+ixgb_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
 {
-	struct ixgb_adapter *adapter = dev->priv;
 	int i;
 
-	for (i = 0; i < IXGB_STATS_LEN; i++) {
-		void *p = (char *)adapter + ixgb_gstrings_stats[i].stat_offset;
-		stats->data[i] =
-		    (ixgb_gstrings_stats[i].sizeof_stat == sizeof(uint64_t))
-		    ? *(uint64_t *) p
-		    : *(uint32_t *) p;
+	switch(stringset) {
+	case ETH_SS_STATS:
+		for(i=0; i < IXGB_STATS_LEN; i++) {
+			memcpy(data + i * ETH_GSTRING_LEN, 
+			ixgb_gstrings_stats[i].stat_string,
+			ETH_GSTRING_LEN);
+		}
+		break;
 	}
 }
 
-static u32 ixgb_get_rx_csum(struct net_device *dev)
-{
-	struct ixgb_adapter *adapter = dev->priv;
-	return adapter->rx_csum;
-}
-
-static int ixgb_set_rx_csum(struct net_device *dev, u32 sum)
-{
-	struct ixgb_adapter *adapter = dev->priv;
-	adapter->rx_csum = sum;
-	ixgb_down(adapter, TRUE);
-	ixgb_up(adapter);
-	return 0;
-}
-
-static u32 ixgb_get_tx_csum(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_HW_CSUM) != 0;
-}
-
-static int ixgb_set_tx_csum(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_HW_CSUM;
-	else
-		dev->features &= ~NETIF_F_HW_CSUM;
-	return 0;
-}
-
-static u32 ixgb_get_sg(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_SG) != 0;
-}
-
-static int ixgb_set_sg(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_SG;
-	else
-		dev->features &= ~NETIF_F_SG;
-	return 0;
-}
-
-#ifdef NETIF_F_TSO
-static u32 ixgb_get_tso(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int ixgb_set_tso(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_TSO;
-	else
-		dev->features &= ~NETIF_F_TSO;
-	return 0;
-}
-#endif
-
 struct ethtool_ops ixgb_ethtool_ops = {
-	.get_settings = ixgb_ethtool_gset,
-	.set_settings = ixgb_ethtool_sset,
-	.get_drvinfo = ixgb_ethtool_gdrvinfo,
-	.nway_reset = ixgb_nway_reset,
-	.get_link = ethtool_op_get_link,
-	.phys_id = ixgb_ethtool_led_blink,
-	.get_strings = ixgb_get_strings,
-	.get_stats_count = ixgb_get_stats_count,
-	.get_regs = ixgb_ethtool_gregs,
+	.get_settings = ixgb_get_settings,
+	.set_settings = ixgb_set_settings,
+	.get_drvinfo = ixgb_get_drvinfo,
 	.get_regs_len = ixgb_get_regs_len,
+	.get_regs = ixgb_get_regs,
+	.get_link = ethtool_op_get_link,
 	.get_eeprom_len = ixgb_get_eeprom_len,
-	.get_eeprom = ixgb_ethtool_geeprom,
-	.set_eeprom = ixgb_ethtool_seeprom,
-	.get_pauseparam = ixgb_ethtool_gpause,
-	.set_pauseparam = ixgb_ethtool_spause,
-	.get_ethtool_stats = get_ethtool_stats,
+	.get_eeprom = ixgb_get_eeprom,
+	.set_eeprom = ixgb_set_eeprom,
+	.get_ringparam = ixgb_get_ringparam,
+	.set_ringparam = ixgb_set_ringparam,
+	.get_pauseparam	= ixgb_get_pauseparam,
+	.set_pauseparam	= ixgb_set_pauseparam,
 	.get_rx_csum = ixgb_get_rx_csum,
 	.set_rx_csum = ixgb_set_rx_csum,
 	.get_tx_csum = ixgb_get_tx_csum,
 	.set_tx_csum = ixgb_set_tx_csum,
-	.get_sg = ixgb_get_sg,
-	.set_sg = ixgb_set_sg,
+	.get_sg	= ethtool_op_get_sg,
+	.set_sg	= ethtool_op_set_sg,
 #ifdef NETIF_F_TSO
-	.get_tso = ixgb_get_tso,
+	.get_tso = ethtool_op_get_tso,
 	.set_tso = ixgb_set_tso,
 #endif
+	.get_strings = ixgb_get_strings,
+	.phys_id = ixgb_phys_id,
+	.get_stats_count = ixgb_get_stats_count,
+	.get_ethtool_stats = ixgb_get_ethtool_stats,
 };
+
+void ixgb_set_ethtool_ops(struct net_device *netdev)
+{
+	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
+}
diff -Nru a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
--- a/drivers/net/ixgb/ixgb_hw.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/ixgb/ixgb_hw.c	2005-01-19 13:44:47 -08:00
@@ -53,9 +53,14 @@
 {
 	uint32_t ctrl_reg;
 
-	ctrl_reg = IXGB_CTRL0_RST | IXGB_CTRL0_SDP3_DIR |	/* All pins are Output=1 */
-	    IXGB_CTRL0_SDP2_DIR | IXGB_CTRL0_SDP1_DIR | IXGB_CTRL0_SDP0_DIR | IXGB_CTRL0_SDP3 |	/* Initial value 1101   */
-	    IXGB_CTRL0_SDP2 | IXGB_CTRL0_SDP0;
+	ctrl_reg =  IXGB_CTRL0_RST |
+				IXGB_CTRL0_SDP3_DIR |   /* All pins are Output=1 */
+				IXGB_CTRL0_SDP2_DIR |
+				IXGB_CTRL0_SDP1_DIR |
+				IXGB_CTRL0_SDP0_DIR |
+				IXGB_CTRL0_SDP3	 |   /* Initial value 1101   */
+				IXGB_CTRL0_SDP2	 |
+				IXGB_CTRL0_SDP0;
 
 #ifdef HP_ZX1
 	/* Workaround for 82597EX reset errata */
@@ -84,7 +89,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-boolean_t ixgb_adapter_stop(struct ixgb_hw * hw)
+boolean_t
+ixgb_adapter_stop(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
 	uint32_t icr_reg;
@@ -94,7 +100,7 @@
 	/* If we are stopped or resetting exit gracefully and wait to be
 	 * started again before accessing the hardware.
 	 */
-	if (hw->adapter_stopped) {
+	if(hw->adapter_stopped) {
 		DEBUGOUT("Exiting because the adapter is already stopped!!!\n");
 		return FALSE;
 	}
@@ -135,6 +141,7 @@
 	return (ctrl_reg & IXGB_CTRL0_RST);
 }
 
+
 /******************************************************************************
  * Identifies the vendor of the optics module on the adapter.  The SR adapters
  * support two different types of XPAK optics, so it is necessary to determine
@@ -144,7 +151,8 @@
  *
  * Returns: the vendor of the XPAK optics module.
  *****************************************************************************/
-static ixgb_xpak_vendor ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
+static ixgb_xpak_vendor
+ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
 {
 	uint32_t i;
 	uint16_t vendor_name[5];
@@ -183,7 +191,8 @@
  *
  * Returns: the phy type of the adapter.
  *****************************************************************************/
-static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw)
+static ixgb_phy_type
+ixgb_identify_phy(struct ixgb_hw *hw)
 {
 	ixgb_phy_type phy_type;
 	ixgb_xpak_vendor xpak_vendor;
@@ -210,7 +219,10 @@
 			phy_type = ixgb_phy_type_g6005;
 		}
 		break;
-
+	case IXGB_DEVICE_ID_82597EX_LR:
+		DEBUGOUT("Identified G6104 optics\n");
+		phy_type = ixgb_phy_type_g6104;
+		break;
 	default:
 		DEBUGOUT("Unknown physical layer module\n");
 		phy_type = ixgb_phy_type_unknown;
@@ -237,7 +249,8 @@
  *      TRUE if successful,
  *      FALSE if unrecoverable problems were encountered.
  *****************************************************************************/
-boolean_t ixgb_init_hw(struct ixgb_hw * hw)
+boolean_t
+ixgb_init_hw(struct ixgb_hw *hw)
 {
 	uint32_t i;
 	uint32_t ctrl_reg;
@@ -266,7 +279,7 @@
 	msec_delay(IXGB_DELAY_AFTER_EE_RESET);
 
 	if (ixgb_get_eeprom_data(hw) == FALSE) {
-		return (FALSE);
+		return(FALSE);
 	}
 
 	/* Use the device id to determine the type of phy/transceiver. */
@@ -284,7 +297,7 @@
 	 */
 	if (!mac_addr_valid(hw->curr_mac_addr)) {
 		DEBUGOUT("MAC address invalid after ixgb_init_rx_addrs\n");
-		return (FALSE);
+		return(FALSE);
 	}
 
 	/* tell the routines in this file they can access hardware again */
@@ -295,7 +308,7 @@
 
 	/* Zero out the Multicast HASH table */
 	DEBUGOUT("Zeroing the MTA\n");
-	for (i = 0; i < IXGB_MC_TBL_SIZE; i++)
+	for(i = 0; i < IXGB_MC_TBL_SIZE; i++)
 		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
 
 	/* Zero out the VLAN Filter Table Array */
@@ -322,7 +335,8 @@
  * of the receive addresss registers. Clears the multicast table. Assumes
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
-void ixgb_init_rx_addrs(struct ixgb_hw *hw)
+void
+ixgb_init_rx_addrs(struct ixgb_hw *hw)
 {
 	uint32_t i;
 
@@ -360,7 +374,7 @@
 
 	/* Zero out the other 15 receive addresses. */
 	DEBUGOUT("Clearing RAR[1-15]\n");
-	for (i = 1; i < IXGB_RAR_ENTRIES; i++) {
+	for(i = 1; i < IXGB_RAR_ENTRIES; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
 		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
 	}
@@ -383,12 +397,13 @@
  *****************************************************************************/
 void
 ixgb_mc_addr_list_update(struct ixgb_hw *hw,
-			 uint8_t * mc_addr_list,
-			 uint32_t mc_addr_count, uint32_t pad)
+			  uint8_t *mc_addr_list,
+			  uint32_t mc_addr_count,
+			  uint32_t pad)
 {
 	uint32_t hash_value;
 	uint32_t i;
-	uint32_t rar_used_count = 1;	/* RAR[0] is used for our MAC address */
+	uint32_t rar_used_count = 1;		/* RAR[0] is used for our MAC address */
 
 	DEBUGFUNC("ixgb_mc_addr_list_update");
 
@@ -397,19 +412,19 @@
 
 	/* Clear RAR[1-15] */
 	DEBUGOUT(" Clearing RAR[1-15]\n");
-	for (i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
+	for(i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
 		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
 	}
 
 	/* Clear the MTA */
 	DEBUGOUT(" Clearing MTA\n");
-	for (i = 0; i < IXGB_MC_TBL_SIZE; i++) {
+	for(i = 0; i < IXGB_MC_TBL_SIZE; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
 	}
 
 	/* Add the new addresses */
-	for (i = 0; i < mc_addr_count; i++) {
+	for(i = 0; i < mc_addr_count; i++) {
 		DEBUGOUT(" Adding the multicast addresses:\n");
 		DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
 			  mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)],
@@ -427,7 +442,7 @@
 		/* Place this multicast address in the RAR if there is room, *
 		 * else put it in the MTA
 		 */
-		if (rar_used_count < IXGB_RAR_ENTRIES) {
+		if(rar_used_count < IXGB_RAR_ENTRIES) {
 			ixgb_rar_set(hw,
 				     mc_addr_list +
 				     (i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)),
@@ -460,7 +475,9 @@
  * Returns:
  *      The hash value
  *****************************************************************************/
-static uint32_t ixgb_hash_mc_addr(struct ixgb_hw *hw, uint8_t * mc_addr)
+static uint32_t
+ixgb_hash_mc_addr(struct ixgb_hw *hw,
+		   uint8_t *mc_addr)
 {
 	uint32_t hash_value = 0;
 
@@ -506,7 +523,9 @@
  * hw - Struct containing variables accessed by shared code
  * hash_value - Multicast address hash value
  *****************************************************************************/
-static void ixgb_mta_set(struct ixgb_hw *hw, uint32_t hash_value)
+static void
+ixgb_mta_set(struct ixgb_hw *hw,
+		  uint32_t hash_value)
 {
 	uint32_t hash_bit, hash_reg;
 	uint32_t mta_reg;
@@ -538,7 +557,10 @@
  * addr - Address to put into receive address register
  * index - Receive address register to write
  *****************************************************************************/
-void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index)
+void
+ixgb_rar_set(struct ixgb_hw *hw,
+		  uint8_t *addr,
+		  uint32_t index)
 {
 	uint32_t rar_low, rar_high;
 
@@ -548,11 +570,13 @@
 	 * from network order (big endian) to little endian
 	 */
 	rar_low = ((uint32_t) addr[0] |
-		   ((uint32_t) addr[1] << 8) |
-		   ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
+		   ((uint32_t)addr[1] << 8) |
+		   ((uint32_t)addr[2] << 16) |
+		   ((uint32_t)addr[3] << 24));
 
 	rar_high = ((uint32_t) addr[4] |
-		    ((uint32_t) addr[5] << 8) | IXGB_RAH_AV);
+			((uint32_t)addr[5] << 8) |
+			IXGB_RAH_AV);
 
 	IXGB_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
 	IXGB_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
@@ -566,7 +590,10 @@
  * offset - Offset in VLAN filer table to write
  * value - Value to write into VLAN filter table
  *****************************************************************************/
-void ixgb_write_vfta(struct ixgb_hw *hw, uint32_t offset, uint32_t value)
+void
+ixgb_write_vfta(struct ixgb_hw *hw,
+		 uint32_t offset,
+		 uint32_t value)
 {
 	IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value);
 	return;
@@ -577,11 +604,12 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_clear_vfta(struct ixgb_hw *hw)
+void
+ixgb_clear_vfta(struct ixgb_hw *hw)
 {
 	uint32_t offset;
 
-	for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
+	for(offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
 		IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
 	return;
 }
@@ -592,10 +620,11 @@
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 
-boolean_t ixgb_setup_fc(struct ixgb_hw * hw)
+boolean_t
+ixgb_setup_fc(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
-	uint32_t pap_reg = 0;	/* by default, assume no pause time */
+	uint32_t pap_reg = 0;   /* by default, assume no pause time */
 	boolean_t status = TRUE;
 
 	DEBUGFUNC("ixgb_setup_fc");
@@ -660,16 +689,16 @@
 	 * ability to transmit pause frames in not enabled, then these
 	 * registers will be set to 0.
 	 */
-	if (!(hw->fc.type & ixgb_fc_tx_pause)) {
+	if(!(hw->fc.type & ixgb_fc_tx_pause)) {
 		IXGB_WRITE_REG(hw, FCRTL, 0);
 		IXGB_WRITE_REG(hw, FCRTH, 0);
 	} else {
-		/* We need to set up the Receive Threshold high and low water
-		 * marks as well as (optionally) enabling the transmission of XON frames.
-		 */
-		if (hw->fc.send_xon) {
+	   /* We need to set up the Receive Threshold high and low water
+	    * marks as well as (optionally) enabling the transmission of XON
+	    * frames. */
+		if(hw->fc.send_xon) {
 			IXGB_WRITE_REG(hw, FCRTL,
-				       (hw->fc.low_water | IXGB_FCRTL_XONE));
+				(hw->fc.low_water | IXGB_FCRTL_XONE));
 		} else {
 			IXGB_WRITE_REG(hw, FCRTL, hw->fc.low_water);
 		}
@@ -694,9 +723,10 @@
  * read command.
  *****************************************************************************/
 uint16_t
-ixgb_read_phy_reg(struct ixgb_hw * hw,
-		  uint32_t reg_address,
-		  uint32_t phy_address, uint32_t device_type)
+ixgb_read_phy_reg(struct ixgb_hw *hw,
+		uint32_t reg_address,
+		uint32_t phy_address,
+		uint32_t device_type)
 {
 	uint32_t i;
 	uint32_t data;
@@ -721,7 +751,8 @@
     ** from the CPU Write to the Ready bit assertion.
     **************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -747,7 +778,8 @@
     ** from the CPU Write to the Ready bit assertion.
     **************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -763,7 +795,7 @@
 	 */
 	data = IXGB_READ_REG(hw, MSRWD);
 	data >>= IXGB_MSRWD_READ_DATA_SHIFT;
-	return ((uint16_t) data);
+	return((uint16_t) data);
 }
 
 /******************************************************************************
@@ -785,8 +817,10 @@
  *****************************************************************************/
 void
 ixgb_write_phy_reg(struct ixgb_hw *hw,
-		   uint32_t reg_address,
-		   uint32_t phy_address, uint32_t device_type, uint16_t data)
+			uint32_t reg_address,
+			uint32_t phy_address,
+			uint32_t device_type,
+			uint16_t data)
 {
 	uint32_t i;
 	uint32_t command = 0;
@@ -796,24 +830,25 @@
 	ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE);
 
 	/* Put the data in the MDIO Read/Write Data register */
-	IXGB_WRITE_REG(hw, MSRWD, (uint32_t) data);
+	IXGB_WRITE_REG(hw, MSRWD, (uint32_t)data);
 
 	/* Setup and write the address cycle command */
-	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
-		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
-		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
-		   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));
+	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |
+			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
+			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
+			   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));
 
 	IXGB_WRITE_REG(hw, MSCA, command);
 
-    /**************************************************************
-    ** Check every 10 usec to see if the address cycle completed
-    ** The COMMAND bit will clear when the operation is complete.
-    ** This may take as long as 64 usecs (we'll wait 100 usecs max)
-    ** from the CPU Write to the Ready bit assertion.
-    **************************************************************/
+	/**************************************************************
+	** Check every 10 usec to see if the address cycle completed
+	** The COMMAND bit will clear when the operation is complete.
+	** This may take as long as 64 usecs (we'll wait 100 usecs max)
+	** from the CPU Write to the Ready bit assertion.
+	**************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -825,21 +860,22 @@
 	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);
 
 	/* Address cycle complete, setup and write the write command */
-	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
-		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
-		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
-		   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND));
+	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |
+			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
+			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
+			   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND));
 
 	IXGB_WRITE_REG(hw, MSCA, command);
 
-    /**************************************************************
-    ** Check every 10 usec to see if the read command completed
-    ** The COMMAND bit will clear when the operation is complete.
-    ** The write may take as long as 64 usecs (we'll wait 100 usecs max)
-    ** from the CPU Write to the Ready bit assertion.
-    **************************************************************/
+	/**************************************************************
+	** Check every 10 usec to see if the read command completed
+	** The COMMAND bit will clear when the operation is complete.
+	** The write may take as long as 64 usecs (we'll wait 100 usecs max)
+	** from the CPU Write to the Ready bit assertion.
+	**************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -860,7 +896,8 @@
  *
  * Called by any function that needs to check the link status of the adapter.
  *****************************************************************************/
-void ixgb_check_for_link(struct ixgb_hw *hw)
+void
+ixgb_check_for_link(struct ixgb_hw *hw)
 {
 	uint32_t status_reg;
 	uint32_t xpcss_reg;
@@ -922,14 +959,15 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
+void
+ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
 {
 	volatile uint32_t temp_reg;
 
 	DEBUGFUNC("ixgb_clear_hw_cntrs");
 
 	/* if we are stopped or resetting exit gracefully */
-	if (hw->adapter_stopped) {
+	if(hw->adapter_stopped) {
 		DEBUGOUT("Exiting because the adapter is stopped!!!\n");
 		return;
 	}
@@ -1002,7 +1040,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_led_on(struct ixgb_hw *hw)
+void
+ixgb_led_on(struct ixgb_hw *hw)
 {
 	uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
 
@@ -1017,7 +1056,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_led_off(struct ixgb_hw *hw)
+void
+ixgb_led_off(struct ixgb_hw *hw)
 {
 	uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
 
@@ -1032,18 +1072,19 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_get_bus_info(struct ixgb_hw *hw)
+static void
+ixgb_get_bus_info(struct ixgb_hw *hw)
 {
 	uint32_t status_reg;
 
 	status_reg = IXGB_READ_REG(hw, STATUS);
 
 	hw->bus.type = (status_reg & IXGB_STATUS_PCIX_MODE) ?
-	    ixgb_bus_type_pcix : ixgb_bus_type_pci;
+		ixgb_bus_type_pcix : ixgb_bus_type_pci;
 
 	if (hw->bus.type == ixgb_bus_type_pci) {
 		hw->bus.speed = (status_reg & IXGB_STATUS_PCI_SPD) ?
-		    ixgb_bus_speed_66 : ixgb_bus_speed_33;
+			ixgb_bus_speed_66 : ixgb_bus_speed_33;
 	} else {
 		switch (status_reg & IXGB_STATUS_PCIX_SPD_MASK) {
 		case IXGB_STATUS_PCIX_SPD_66:
@@ -1062,7 +1103,7 @@
 	}
 
 	hw->bus.width = (status_reg & IXGB_STATUS_BUS64) ?
-	    ixgb_bus_width_64 : ixgb_bus_width_32;
+		ixgb_bus_width_64 : ixgb_bus_width_32;
 
 	return;
 }
@@ -1073,7 +1114,8 @@
  * mac_addr - pointer to MAC address.
  *
  *****************************************************************************/
-boolean_t mac_addr_valid(uint8_t * mac_addr)
+boolean_t
+mac_addr_valid(uint8_t *mac_addr)
 {
 	boolean_t is_valid = TRUE;
 	DEBUGFUNC("mac_addr_valid");
@@ -1090,9 +1132,11 @@
 	}
 	/* Reject the zero address */
 	else if (mac_addr[0] == 0 &&
-		 mac_addr[1] == 0 &&
-		 mac_addr[2] == 0 &&
-		 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
+			 mac_addr[1] == 0 &&
+			 mac_addr[2] == 0 &&
+			 mac_addr[3] == 0 &&
+			 mac_addr[4] == 0 &&
+			 mac_addr[5] == 0) {
 		DEBUGOUT("MAC address is all zeros\n");
 		is_valid = FALSE;
 	}
@@ -1105,7 +1149,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-boolean_t ixgb_link_reset(struct ixgb_hw * hw)
+boolean_t
+ixgb_link_reset(struct ixgb_hw *hw)
 {
 	boolean_t link_status = FALSE;
 	uint8_t wait_retries = MAX_RESET_ITERATIONS;
@@ -1135,20 +1180,22 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_optics_reset(struct ixgb_hw *hw)
+void
+ixgb_optics_reset(struct ixgb_hw *hw)
 {
 	if (hw->phy_type == ixgb_phy_type_txn17401) {
 		uint16_t mdio_reg;
 
 		ixgb_write_phy_reg(hw,
-				   MDIO_PMA_PMD_CR1,
-				   IXGB_PHY_ADDRESS,
-				   MDIO_PMA_PMD_DID, MDIO_PMA_PMD_CR1_RESET);
-
-		mdio_reg = ixgb_read_phy_reg(hw,
-					     MDIO_PMA_PMD_CR1,
-					     IXGB_PHY_ADDRESS,
-					     MDIO_PMA_PMD_DID);
+					MDIO_PMA_PMD_CR1,
+					IXGB_PHY_ADDRESS,
+					MDIO_PMA_PMD_DID,
+					MDIO_PMA_PMD_CR1_RESET);
+
+		mdio_reg = ixgb_read_phy_reg( hw,
+						MDIO_PMA_PMD_CR1,
+						IXGB_PHY_ADDRESS,
+						MDIO_PMA_PMD_DID);
 	}
 
 	return;
diff -Nru a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
--- a/drivers/net/ixgb/ixgb_hw.h	2005-01-19 13:44:45 -08:00
+++ b/drivers/net/ixgb/ixgb_hw.h	2005-01-19 13:44:45 -08:00
@@ -616,17 +616,17 @@
 #define IXGB_CONTEXT_DESC_STATUS_DD 0x01
 
 /* Filters */
-#define IXGB_RAR_ENTRIES          16	/* Number of entries in Rx Address array */
 #define IXGB_MC_TBL_SIZE          128	/* Multicast Filter Table (4096 bits) */
 #define IXGB_VLAN_FILTER_TBL_SIZE 128	/* VLAN Filter Table (4096 bits) */
+#define IXGB_RAR_ENTRIES		  3	/* Number of entries in Rx Address array */
 
 #define IXGB_MEMORY_REGISTER_BASE_ADDRESS   0
-#define ENET_HEADER_SIZE            14
-#define ENET_FCS_LENGTH             4
-#define IXGB_MAX_NUM_MULTICAST_ADDRESSES    128
-#define IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS    60
-#define IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS    1514
-#define IXGB_MAX_JUMBO_FRAME_SIZE       0x3F00
+#define ENET_HEADER_SIZE			14
+#define ENET_FCS_LENGTH			 4
+#define IXGB_MAX_NUM_MULTICAST_ADDRESSES	128
+#define IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS	60
+#define IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS	1514
+#define IXGB_MAX_JUMBO_FRAME_SIZE		0x3F00
 
 /* Phy Addresses */
 #define IXGB_OPTICAL_PHY_ADDR 0x0	/* Optical Module phy address */
@@ -789,32 +789,39 @@
 extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
 extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
 extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
-extern boolean_t mac_addr_valid(uint8_t * mac_addr);
+extern boolean_t mac_addr_valid(uint8_t *mac_addr);
 
 extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
-				  uint32_t reg_addr,
-				  uint32_t phy_addr, uint32_t device_type);
+				uint32_t reg_addr,
+				uint32_t phy_addr,
+				uint32_t device_type);
 
 extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
-			       uint32_t reg_addr,
-			       uint32_t phy_addr,
-			       uint32_t device_type, uint16_t data);
+				uint32_t reg_addr,
+				uint32_t phy_addr,
+				uint32_t device_type,
+				uint16_t data);
+
+extern void ixgb_rar_set(struct ixgb_hw *hw,
+				uint8_t *addr,
+				uint32_t index);
 
-extern void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index);
 
 /* Filters (multicast, vlan, receive) */
 extern void ixgb_mc_addr_list_update(struct ixgb_hw *hw,
-				     uint8_t * mc_addr_list,
-				     uint32_t mc_addr_count, uint32_t pad);
+				   uint8_t *mc_addr_list,
+				   uint32_t mc_addr_count,
+				   uint32_t pad);
 
 /* Vfta functions */
 extern void ixgb_write_vfta(struct ixgb_hw *hw,
-			    uint32_t offset, uint32_t value);
+				 uint32_t offset,
+				 uint32_t value);
 
 extern void ixgb_clear_vfta(struct ixgb_hw *hw);
 
 /* Access functions to eeprom data */
-void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr);
+void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr);
 uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw);
 uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
 uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw);
@@ -832,6 +839,9 @@
 /* Everything else */
 void ixgb_led_on(struct ixgb_hw *hw);
 void ixgb_led_off(struct ixgb_hw *hw);
-void ixgb_write_pci_cfg(struct ixgb_hw *hw, uint32_t reg, uint16_t * value);
+void ixgb_write_pci_cfg(struct ixgb_hw *hw,
+			 uint32_t reg,
+			 uint16_t * value);
 
-#endif				/* _IXGB_HW_H_ */
+
+#endif /* _IXGB_HW_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_ids.h b/drivers/net/ixgb/ixgb_ids.h
--- a/drivers/net/ixgb/ixgb_ids.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/ixgb/ixgb_ids.h	2005-01-19 13:44:46 -08:00
@@ -33,21 +33,16 @@
 ** The Device and Vendor IDs for 10 Gigabit MACs
 **********************************************************************/
 
-#define INTEL_VENDOR_ID         0x8086
-#define INTEL_SUBVENDOR_ID      0x8086
+#define INTEL_VENDOR_ID             0x8086
+#define INTEL_SUBVENDOR_ID          0x8086
 
-#define IXGB_DEVICE_ID_82597EX      0x1048
-#define IXGB_DEVICE_ID_82597EX_SR   0x1A48
 
-#define IXGB_SUBDEVICE_ID_A11F  0xA11F
-#define IXGB_SUBDEVICE_ID_A01F  0xA01F
+#define IXGB_DEVICE_ID_82597EX      0x1048   
+#define IXGB_DEVICE_ID_82597EX_SR   0x1A48   
+#define IXGB_DEVICE_ID_82597EX_LR   0x1B48
+#define IXGB_SUBDEVICE_ID_A11F      0xA11F   
+#define IXGB_SUBDEVICE_ID_A01F      0xA01F   
 
-#define IXGB_SUBDEVICE_ID_A15F  0xA15F
-#define IXGB_SUBDEVICE_ID_A05F  0xA05F
-
-#define IXGB_SUBDEVICE_ID_A12F  0xA12F
-#define IXGB_SUBDEVICE_ID_A02F  0xA02F
-
-#endif				/* #ifndef _IXGB_IDS_H_ */
+#endif /* #ifndef _IXGB_IDS_H_ */
 
 /* End of File */
diff -Nru a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
--- a/drivers/net/ixgb/ixgb_main.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/ixgb/ixgb_main.c	2005-01-19 13:44:48 -08:00
@@ -28,10 +28,23 @@
 
 #include "ixgb.h"
 
+/* Change Log
+ * 1.0.84 10/26/04
+ * - reset buffer_info->dma in Tx resource cleanup logic
+ * 1.0.83 10/12/04
+ * - sparse cleanup - shemminger@osdl.org
+ * - fix tx resource cleanup logic
+ */
+
 char ixgb_driver_name[] = "ixgb";
 char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
-char ixgb_driver_version[] = "1.0.66-k2";
-char ixgb_copyright[] = "Copyright (c) 2001-2004 Intel Corporation.";
+#ifndef CONFIG_IXGB_NAPI
+#define DRIVERNAPI
+#else
+#define DRIVERNAPI "-NAPI"
+#endif
+char ixgb_driver_version[] = "1.0.87-k2"DRIVERNAPI;
+char ixgb_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
 /* ixgb_pci_tbl - PCI Device ID Table
  *
@@ -46,6 +59,8 @@
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_SR,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_LR,  
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 
 	/* required last entry */
 	{0,}
@@ -55,11 +70,14 @@
 
 /* Local Function Prototypes */
 
-static inline void ixgb_irq_disable(struct ixgb_adapter *adapter);
-static inline void ixgb_irq_enable(struct ixgb_adapter *adapter);
 int ixgb_up(struct ixgb_adapter *adapter);
 void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
 void ixgb_reset(struct ixgb_adapter *adapter);
+int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
+int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
+void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
+void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
+void ixgb_update_stats(struct ixgb_adapter *adapter);
 
 static int ixgb_init_module(void);
 static void ixgb_exit_module(void);
@@ -68,27 +86,19 @@
 static int ixgb_sw_init(struct ixgb_adapter *adapter);
 static int ixgb_open(struct net_device *netdev);
 static int ixgb_close(struct net_device *netdev);
-static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
-static int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
 static void ixgb_configure_tx(struct ixgb_adapter *adapter);
 static void ixgb_configure_rx(struct ixgb_adapter *adapter);
 static void ixgb_setup_rctl(struct ixgb_adapter *adapter);
 static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter);
 static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter);
-static void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
-static void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
 static void ixgb_set_multi(struct net_device *netdev);
 static void ixgb_watchdog(unsigned long data);
 static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 static struct net_device_stats *ixgb_get_stats(struct net_device *netdev);
 static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
 static int ixgb_set_mac(struct net_device *netdev, void *p);
-static void ixgb_update_stats(struct ixgb_adapter *adapter);
 static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs);
 static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
-static inline void ixgb_rx_checksum(struct ixgb_adapter *adapter,
-				    struct ixgb_rx_desc *rx_desc,
-				    struct sk_buff *skb);
 #ifdef CONFIG_IXGB_NAPI
 static int ixgb_clean(struct net_device *netdev, int *budget);
 static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
@@ -97,6 +107,7 @@
 static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
 #endif
 static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
+void ixgb_set_ethtool_ops(struct net_device *netdev);
 static void ixgb_tx_timeout(struct net_device *dev);
 static void ixgb_tx_timeout_task(struct net_device *dev);
 static void ixgb_vlan_rx_register(struct net_device *netdev,
@@ -123,7 +134,6 @@
 /* Exported from other modules */
 
 extern void ixgb_check_options(struct ixgb_adapter *adapter);
-extern struct ethtool_ops ixgb_ethtool_ops;
 
 static struct pci_driver ixgb_driver = {
 	.name = ixgb_driver_name,
@@ -152,7 +162,8 @@
  * loaded. All it does is register with the PCI subsystem.
  **/
 
-static int __init ixgb_init_module(void)
+static int __init
+ixgb_init_module(void)
 {
 	int ret;
 	printk(KERN_INFO "%s - version %s\n",
@@ -161,7 +172,7 @@
 	printk(KERN_INFO "%s\n", ixgb_copyright);
 
 	ret = pci_module_init(&ixgb_driver);
-	if (ret >= 0) {
+	if(ret >= 0) {
 		register_reboot_notifier(&ixgb_notifier_reboot);
 	}
 	return ret;
@@ -176,7 +187,8 @@
  * from memory.
  **/
 
-static void __exit ixgb_exit_module(void)
+static void __exit
+ixgb_exit_module(void)
 {
 	unregister_reboot_notifier(&ixgb_notifier_reboot);
 	pci_unregister_driver(&ixgb_driver);
@@ -189,7 +201,8 @@
  * @adapter: board private structure
  **/
 
-static inline void ixgb_irq_disable(struct ixgb_adapter *adapter)
+static inline void
+ixgb_irq_disable(struct ixgb_adapter *adapter)
 {
 	atomic_inc(&adapter->irq_sem);
 	IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
@@ -202,17 +215,19 @@
  * @adapter: board private structure
  **/
 
-static inline void ixgb_irq_enable(struct ixgb_adapter *adapter)
+static inline void
+ixgb_irq_enable(struct ixgb_adapter *adapter)
 {
-	if (atomic_dec_and_test(&adapter->irq_sem)) {
+	if(atomic_dec_and_test(&adapter->irq_sem)) {
 		IXGB_WRITE_REG(&adapter->hw, IMS,
-			       IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
-			       IXGB_INT_RXO | IXGB_INT_LSC);
+			   IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
+			   IXGB_INT_RXO | IXGB_INT_LSC);
 		IXGB_WRITE_FLUSH(&adapter->hw);
 	}
 }
 
-int ixgb_up(struct ixgb_adapter *adapter)
+int
+ixgb_up(struct ixgb_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
 	int err;
@@ -230,27 +245,44 @@
 	ixgb_configure_rx(adapter);
 	ixgb_alloc_rx_buffers(adapter);
 
-	if ((err = request_irq(adapter->pdev->irq, &ixgb_intr,
-			       SA_SHIRQ | SA_SAMPLE_RANDOM,
-			       netdev->name, netdev)))
+#ifdef CONFIG_PCI_MSI
+	{
+	boolean_t pcix = (IXGB_READ_REG(&adapter->hw, STATUS) & 
+						  IXGB_STATUS_PCIX_MODE) ? TRUE : FALSE;
+	adapter->have_msi = TRUE;
+
+	if (!pcix)
+	   adapter->have_msi = FALSE;
+	else if((err = pci_enable_msi(adapter->pdev))) {
+		printk (KERN_ERR
+		 "Unable to allocate MSI interrupt Error: %d\n", err);
+		adapter->have_msi = FALSE;
+		/* proceed to try to request regular interrupt */
+	}
+	}
+
+#endif
+	if((err = request_irq(adapter->pdev->irq, &ixgb_intr,
+				  SA_SHIRQ | SA_SAMPLE_RANDOM,
+				  netdev->name, netdev)))
 		return err;
 
 	/* disable interrupts and get the hardware into a known state */
 	IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
 
-	if ((hw->max_frame_size != max_frame) ||
-	    (hw->max_frame_size !=
-	     (IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {
+	if((hw->max_frame_size != max_frame) ||
+		(hw->max_frame_size !=
+		(IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {
 
 		hw->max_frame_size = max_frame;
 
 		IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);
 
-		if (hw->max_frame_size >
-		    IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
+		if(hw->max_frame_size >
+		   IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
 			uint32_t ctrl0 = IXGB_READ_REG(hw, CTRL0);
 
-			if (!(ctrl0 & IXGB_CTRL0_JFE)) {
+			if(!(ctrl0 & IXGB_CTRL0_JFE)) {
 				ctrl0 |= IXGB_CTRL0_JFE;
 				IXGB_WRITE_REG(hw, CTRL0, ctrl0);
 			}
@@ -263,13 +295,19 @@
 	return 0;
 }
 
-void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
+void
+ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
 {
 	struct net_device *netdev = adapter->netdev;
 
 	ixgb_irq_disable(adapter);
 	free_irq(adapter->pdev->irq, netdev);
-	if (kill_watchdog)
+#ifdef CONFIG_PCI_MSI
+	if(adapter->have_msi == TRUE)
+		pci_disable_msi(adapter->pdev);
+
+#endif
+	if(kill_watchdog)
 		del_timer_sync(&adapter->watchdog_timer);
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
@@ -281,11 +319,12 @@
 	ixgb_clean_rx_ring(adapter);
 }
 
-void ixgb_reset(struct ixgb_adapter *adapter)
+void
+ixgb_reset(struct ixgb_adapter *adapter)
 {
 
 	ixgb_adapter_stop(&adapter->hw);
-	if (!ixgb_init_hw(&adapter->hw))
+	if(!ixgb_init_hw(&adapter->hw))
 		IXGB_DBG("ixgb_init_hw failed.\n");
 }
 
@@ -302,7 +341,8 @@
  **/
 
 static int __devinit
-ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ixgb_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
 {
 	struct net_device *netdev = NULL;
 	struct ixgb_adapter *adapter;
@@ -313,26 +353,26 @@
 	int i;
 	int err;
 
-	if ((err = pci_enable_device(pdev)))
+	if((err = pci_enable_device(pdev)))
 		return err;
 
-	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+	if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
 		pci_using_dac = 1;
 	} else {
-		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+		if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
 			IXGB_ERR("No usable DMA configuration, aborting\n");
 			return err;
 		}
 		pci_using_dac = 0;
 	}
 
-	if ((err = pci_request_regions(pdev, ixgb_driver_name)))
+	if((err = pci_request_regions(pdev, ixgb_driver_name)))
 		return err;
 
 	pci_set_master(pdev);
 
 	netdev = alloc_etherdev(sizeof(struct ixgb_adapter));
-	if (!netdev) {
+	if(!netdev) {
 		err = -ENOMEM;
 		goto err_alloc_etherdev;
 	}
@@ -350,15 +390,15 @@
 	mmio_len = pci_resource_len(pdev, BAR_0);
 
 	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
-	if (!adapter->hw.hw_addr) {
+	if(!adapter->hw.hw_addr) {
 		err = -EIO;
 		goto err_ioremap;
 	}
 
-	for (i = BAR_1; i <= BAR_5; i++) {
-		if (pci_resource_len(pdev, i) == 0)
+	for(i = BAR_1; i <= BAR_5; i++) {
+		if(pci_resource_len(pdev, i) == 0)
 			continue;
-		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+		if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
 			adapter->hw.io_base = pci_resource_start(pdev, i);
 			break;
 		}
@@ -371,9 +411,9 @@
 	netdev->set_multicast_list = &ixgb_set_multi;
 	netdev->set_mac_address = &ixgb_set_mac;
 	netdev->change_mtu = &ixgb_change_mtu;
+	ixgb_set_ethtool_ops(netdev);
 	netdev->tx_timeout = &ixgb_tx_timeout;
 	netdev->watchdog_timeo = HZ;
-	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
 #ifdef CONFIG_IXGB_NAPI
 	netdev->poll = &ixgb_clean;
 	netdev->weight = 64;
@@ -395,22 +435,24 @@
 
 	/* setup the private structure */
 
-	if ((err = ixgb_sw_init(adapter)))
+	if((err = ixgb_sw_init(adapter)))
 		goto err_sw_init;
 
 	netdev->features = NETIF_F_SG |
-	    NETIF_F_HW_CSUM |
-	    NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+			   NETIF_F_HW_CSUM |
+			   NETIF_F_HW_VLAN_TX |
+			   NETIF_F_HW_VLAN_RX |
+			   NETIF_F_HW_VLAN_FILTER;
 #ifdef NETIF_F_TSO
 	netdev->features |= NETIF_F_TSO;
 #endif
 
-	if (pci_using_dac)
+	if(pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
 	/* make sure the EEPROM is good */
 
-	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
+	if(!ixgb_validate_eeprom_checksum(&adapter->hw)) {
 		printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n");
 		err = -EIO;
 		goto err_eeprom;
@@ -418,7 +460,7 @@
 
 	ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
 
-	if (!is_valid_ether_addr(netdev->dev_addr)) {
+	if(!is_valid_ether_addr(netdev->dev_addr)) {
 		err = -EIO;
 		goto err_eeprom;
 	}
@@ -432,7 +474,7 @@
 	INIT_WORK(&adapter->tx_timeout_task,
 		  (void (*)(void *))ixgb_tx_timeout_task, netdev);
 
-	if ((err = register_netdev(netdev)))
+	if((err = register_netdev(netdev)))
 		goto err_register;
 
 	/* we're going to reset, so assume we have no link for now */
@@ -441,7 +483,7 @@
 	netif_stop_queue(netdev);
 
 	printk(KERN_INFO "%s: Intel(R) PRO/10GbE Network Connection\n",
-	       netdev->name);
+		   netdev->name);
 	ixgb_check_options(adapter);
 	/* reset the hardware with the new settings */
 
@@ -450,13 +492,13 @@
 	cards_found++;
 	return 0;
 
-      err_register:
-      err_sw_init:
-      err_eeprom:
+err_register:
+err_sw_init:
+err_eeprom:
 	iounmap(adapter->hw.hw_addr);
-      err_ioremap:
+err_ioremap:
 	free_netdev(netdev);
-      err_alloc_etherdev:
+err_alloc_etherdev:
 	pci_release_regions(pdev);
 	return err;
 }
@@ -471,7 +513,8 @@
  * memory.
  **/
 
-static void __devexit ixgb_remove(struct pci_dev *pdev)
+static void __devexit
+ixgb_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgb_adapter *adapter = netdev->priv;
@@ -493,7 +536,8 @@
  * OS network device settings (MTU size).
  **/
 
-static int __devinit ixgb_sw_init(struct ixgb_adapter *adapter)
+static int __devinit
+ixgb_sw_init(struct ixgb_adapter *adapter)
 {
 	struct ixgb_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
@@ -510,9 +554,10 @@
 
 	hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
 
-	if ((hw->device_id == IXGB_DEVICE_ID_82597EX)
-	    || (hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
-		hw->mac_type = ixgb_82597;
+	if((hw->device_id == IXGB_DEVICE_ID_82597EX)
+	   ||(hw->device_id == IXGB_DEVICE_ID_82597EX_LR)
+	   ||(hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
+			hw->mac_type = ixgb_82597;
 	else {
 		/* should never have loaded on this device */
 		printk(KERN_ERR "ixgb: unsupported device id\n");
@@ -540,31 +585,32 @@
  * and the stack is notified that the interface is ready.
  **/
 
-static int ixgb_open(struct net_device *netdev)
+static int
+ixgb_open(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	int err;
 
 	/* allocate transmit descriptors */
 
-	if ((err = ixgb_setup_tx_resources(adapter)))
+	if((err = ixgb_setup_tx_resources(adapter)))
 		goto err_setup_tx;
 
 	/* allocate receive descriptors */
 
-	if ((err = ixgb_setup_rx_resources(adapter)))
+	if((err = ixgb_setup_rx_resources(adapter)))
 		goto err_setup_rx;
 
-	if ((err = ixgb_up(adapter)))
+	if((err = ixgb_up(adapter)))
 		goto err_up;
 
 	return 0;
 
-      err_up:
+err_up:
 	ixgb_free_rx_resources(adapter);
-      err_setup_rx:
+err_setup_rx:
 	ixgb_free_tx_resources(adapter);
-      err_setup_tx:
+err_setup_tx:
 	ixgb_reset(adapter);
 
 	return err;
@@ -582,7 +628,8 @@
  * hardware, and all transmit and receive resources are freed.
  **/
 
-static int ixgb_close(struct net_device *netdev)
+static int
+ixgb_close(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -601,15 +648,16 @@
  * Return 0 on success, negative on failure
  **/
 
-static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
+int
+ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int size;
 
 	size = sizeof(struct ixgb_buffer) * txdr->count;
-	txdr->buffer_info = kmalloc(size, GFP_KERNEL);
-	if (!txdr->buffer_info) {
+	txdr->buffer_info = vmalloc(size);
+	if(!txdr->buffer_info) {
 		return -ENOMEM;
 	}
 	memset(txdr->buffer_info, 0, size);
@@ -620,8 +668,8 @@
 	IXGB_ROUNDUP(txdr->size, 4096);
 
 	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
-	if (!txdr->desc) {
-		kfree(txdr->buffer_info);
+	if(!txdr->desc) {
+		vfree(txdr->buffer_info);
 		return -ENOMEM;
 	}
 	memset(txdr->desc, 0, txdr->size);
@@ -639,7 +687,8 @@
  * Configure the Tx unit of the MAC after a reset.
  **/
 
-static void ixgb_configure_tx(struct ixgb_adapter *adapter)
+static void
+ixgb_configure_tx(struct ixgb_adapter *adapter)
 {
 	uint64_t tdba = adapter->tx_ring.dma;
 	uint32_t tdlen = adapter->tx_ring.count * sizeof(struct ixgb_tx_desc);
@@ -679,8 +728,8 @@
 
 	/* Setup Transmit Descriptor Settings for this adapter */
 	adapter->tx_cmd_type =
-	    IXGB_TX_DESC_TYPE
-	    | (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
+		IXGB_TX_DESC_TYPE 
+		| (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
 }
 
 /**
@@ -690,15 +739,16 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
+int
+ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int size;
 
 	size = sizeof(struct ixgb_buffer) * rxdr->count;
-	rxdr->buffer_info = kmalloc(size, GFP_KERNEL);
-	if (!rxdr->buffer_info) {
+	rxdr->buffer_info = vmalloc(size);
+	if(!rxdr->buffer_info) {
 		return -ENOMEM;
 	}
 	memset(rxdr->buffer_info, 0, size);
@@ -710,8 +760,8 @@
 
 	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
 
-	if (!rxdr->desc) {
-		kfree(rxdr->buffer_info);
+	if(!rxdr->desc) {
+		vfree(rxdr->buffer_info);
 		return -ENOMEM;
 	}
 	memset(rxdr->desc, 0, rxdr->size);
@@ -727,7 +777,8 @@
  * @adapter: Board private structure
  **/
 
-static void ixgb_setup_rctl(struct ixgb_adapter *adapter)
+static void
+ixgb_setup_rctl(struct ixgb_adapter *adapter)
 {
 	uint32_t rctl;
 
@@ -736,9 +787,9 @@
 	rctl &= ~(3 << IXGB_RCTL_MO_SHIFT);
 
 	rctl |=
-	    IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 |
-	    IXGB_RCTL_RXEN | IXGB_RCTL_CFF |
-	    (adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
+		IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 | 
+		IXGB_RCTL_RXEN | IXGB_RCTL_CFF | 
+		(adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
 
 	rctl |= IXGB_RCTL_SECRC;
 
@@ -768,7 +819,8 @@
  * Configure the Rx unit of the MAC after a reset.
  **/
 
-static void ixgb_configure_rx(struct ixgb_adapter *adapter)
+static void
+ixgb_configure_rx(struct ixgb_adapter *adapter)
 {
 	uint64_t rdba = adapter->rx_ring.dma;
 	uint32_t rdlen = adapter->rx_ring.count * sizeof(struct ixgb_rx_desc);
@@ -797,51 +849,14 @@
 	IXGB_WRITE_REG(hw, RDH, 0);
 	IXGB_WRITE_REG(hw, RDT, 0);
 
-	/* burst 16 or burst when RXT0 */
-	rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT
-	    | RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT
-	    | RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
+						/* burst 16 or burst when RXT0*/
+	rxdctl =  RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT 
+			| RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT 
+			| RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
 	IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
 
-	if (adapter->raidc) {
-		uint32_t raidc;
-		uint8_t poll_threshold;
-
-		/* Poll every rx_int_delay period, if RBD exists
-		 * Receive Backlog Detection is set to <threshold> 
-		 * Rx Descriptors
-		 * max is 0x3F == set to poll when 504 RxDesc left 
-		 * min is 0 */
-
-		/* polling times are 1 == 0.8192us
-		   2 == 1.6384us
-		   3 == 3.2768us etc
-		   ...
-		   511 == 418 us
-		 */
-#define IXGB_RAIDC_POLL_DEFAULT 122	/* set to poll every ~100 us under load 
-					   also known as 10000 interrupts / sec */
-
-		/* divide this by 2^3 (8) to get a register size count */
-		poll_threshold = ((adapter->rx_ring.count - 1) >> 3);
-		/* poll at half of that size */
-		poll_threshold >>= 1;
-		/* make sure its not bigger than our max */
-		poll_threshold &= 0x3F;
-
-		raidc = IXGB_RAIDC_EN |	/* turn on raidc style moderation */
-		    IXGB_RAIDC_RXT_GATE |	/* don't interrupt with rxt0 while
-						   in RBD mode (polling) */
-		    (IXGB_RAIDC_POLL_DEFAULT << IXGB_RAIDC_POLL_SHIFT) |
-		    /* this sets the regular "min interrupt delay" */
-		    (adapter->rx_int_delay << IXGB_RAIDC_DELAY_SHIFT) |
-		    poll_threshold;
-
-		IXGB_WRITE_REG(hw, RAIDC, raidc);
-	}
-
 	/* Enable Receive Checksum Offload for TCP and UDP */
-	if (adapter->rx_csum == TRUE) {
+	if(adapter->rx_csum == TRUE) {
 		rxcsum = IXGB_READ_REG(hw, RXCSUM);
 		rxcsum |= IXGB_RXCSUM_TUOFL;
 		IXGB_WRITE_REG(hw, RXCSUM, rxcsum);
@@ -859,13 +874,14 @@
  * Free all transmit software resources
  **/
 
-static void ixgb_free_tx_resources(struct ixgb_adapter *adapter)
+void
+ixgb_free_tx_resources(struct ixgb_adapter *adapter)
 {
 	struct pci_dev *pdev = adapter->pdev;
 
 	ixgb_clean_tx_ring(adapter);
 
-	kfree(adapter->tx_ring.buffer_info);
+	vfree(adapter->tx_ring.buffer_info);
 	adapter->tx_ring.buffer_info = NULL;
 
 	pci_free_consistent(pdev, adapter->tx_ring.size,
@@ -874,33 +890,42 @@
 	adapter->tx_ring.desc = NULL;
 }
 
+static inline void
+ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
+					struct ixgb_buffer *buffer_info)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	if(buffer_info->dma) {
+		pci_unmap_page(pdev,
+			   buffer_info->dma,
+			   buffer_info->length,
+			   PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
+	if(buffer_info->skb) {
+		dev_kfree_skb_any(buffer_info->skb);
+		buffer_info->skb = NULL;
+	}
+}
+
 /**
  * ixgb_clean_tx_ring - Free Tx Buffers
  * @adapter: board private structure
  **/
 
-static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
+static void
+ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct ixgb_buffer *buffer_info;
-	struct pci_dev *pdev = adapter->pdev;
 	unsigned long size;
 	unsigned int i;
 
 	/* Free all the Tx ring sk_buffs */
 
-	for (i = 0; i < tx_ring->count; i++) {
+	for(i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
-		if (buffer_info->skb) {
-
-			pci_unmap_page(pdev,
-				       buffer_info->dma,
-				       buffer_info->length, PCI_DMA_TODEVICE);
-
-			dev_kfree_skb(buffer_info->skb);
-
-			buffer_info->skb = NULL;
-		}
+		ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
 	}
 
 	size = sizeof(struct ixgb_buffer) * tx_ring->count;
@@ -924,14 +949,15 @@
  * Free all receive software resources
  **/
 
-static void ixgb_free_rx_resources(struct ixgb_adapter *adapter)
+void
+ixgb_free_rx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 
 	ixgb_clean_rx_ring(adapter);
 
-	kfree(rx_ring->buffer_info);
+	vfree(rx_ring->buffer_info);
 	rx_ring->buffer_info = NULL;
 
 	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
@@ -944,7 +970,8 @@
  * @adapter: board private structure
  **/
 
-static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
+static void
+ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct ixgb_buffer *buffer_info;
@@ -954,9 +981,9 @@
 
 	/* Free all the Rx ring sk_buffs */
 
-	for (i = 0; i < rx_ring->count; i++) {
+	for(i = 0; i < rx_ring->count; i++) {
 		buffer_info = &rx_ring->buffer_info[i];
-		if (buffer_info->skb) {
+		if(buffer_info->skb) {
 
 			pci_unmap_single(pdev,
 					 buffer_info->dma,
@@ -991,12 +1018,13 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_set_mac(struct net_device *netdev, void *p)
+static int
+ixgb_set_mac(struct net_device *netdev, void *p)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct sockaddr *addr = p;
 
-	if (!is_valid_ether_addr(addr->sa_data))
+	if(!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
@@ -1016,7 +1044,8 @@
  * promiscuous mode, and all-multi behavior.
  **/
 
-static void ixgb_set_multi(struct net_device *netdev)
+static void
+ixgb_set_multi(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
@@ -1028,16 +1057,16 @@
 
 	rctl = IXGB_READ_REG(hw, RCTL);
 
-	if (netdev->flags & IFF_PROMISC) {
+	if(netdev->flags & IFF_PROMISC) {
 		rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
-	} else if (netdev->flags & IFF_ALLMULTI) {
+	} else if(netdev->flags & IFF_ALLMULTI) {
 		rctl |= IXGB_RCTL_MPE;
 		rctl &= ~IXGB_RCTL_UPE;
 	} else {
 		rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE);
 	}
 
-	if (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
+	if(netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
 		rctl |= IXGB_RCTL_MPE;
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 	} else {
@@ -1045,10 +1074,10 @@
 
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 
-		for (i = 0, mc_ptr = netdev->mc_list; mc_ptr;
-		     i++, mc_ptr = mc_ptr->next)
+		for(i = 0, mc_ptr = netdev->mc_list; mc_ptr;
+			i++, mc_ptr = mc_ptr->next)
 			memcpy(&mta[i * IXGB_ETH_LENGTH_OF_ADDRESS],
-			       mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
+				   mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
 
 		ixgb_mc_addr_list_update(hw, mta, netdev->mc_count, 0);
 	}
@@ -1059,7 +1088,8 @@
  * @data: pointer to netdev cast into an unsigned long
  **/
 
-static void ixgb_watchdog(unsigned long data)
+static void
+ixgb_watchdog(unsigned long data)
 {
 	struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
 	struct net_device *netdev = adapter->netdev;
@@ -1073,21 +1103,22 @@
 		netif_stop_queue(netdev);
 	}
 
-	if (adapter->hw.link_up) {
-		if (!netif_carrier_ok(netdev)) {
+	if(adapter->hw.link_up) {
+		if(!netif_carrier_ok(netdev)) {
 			printk(KERN_INFO "ixgb: %s NIC Link is Up %d Mbps %s\n",
-			       netdev->name, 10000, "Full Duplex");
+				   netdev->name, 10000, "Full Duplex");
 			adapter->link_speed = 10000;
 			adapter->link_duplex = FULL_DUPLEX;
 			netif_carrier_on(netdev);
 			netif_wake_queue(netdev);
 		}
 	} else {
-		if (netif_carrier_ok(netdev)) {
+		if(netif_carrier_ok(netdev)) {
 			adapter->link_speed = 0;
 			adapter->link_duplex = 0;
 			printk(KERN_INFO
-			       "ixgb: %s NIC Link is Down\n", netdev->name);
+				   "ixgb: %s NIC Link is Down\n",
+				   netdev->name);
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
 
@@ -1096,8 +1127,8 @@
 
 	ixgb_update_stats(adapter);
 
-	if (!netif_carrier_ok(netdev)) {
-		if (IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
+	if(!netif_carrier_ok(netdev)) {
+		if(IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
 			/* We've lost link, so the controller stops DMA,
 			 * but we've got queued Tx work that's never going
 			 * to get done, so reset controller to flush Tx.
@@ -1108,9 +1139,9 @@
 
 	/* Early detection of hung controller */
 	i = txdr->next_to_clean;
-	if (txdr->buffer_info[i].dma &&
-	    time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
-	    !(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
+	if(txdr->buffer_info[i].dma &&
+	   time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
+	   !(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
 		netif_stop_queue(netdev);
 
 	/* generate an interrupt to force clean up of any stragglers */
@@ -1133,7 +1164,7 @@
 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
 	uint16_t ipcse, tucse, mss;
 
-	if (likely(skb_shinfo(skb)->tso_size)) {
+	if(likely(skb_shinfo(skb)->tso_size)) {
 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
 		mss = skb_shinfo(skb)->tso_size;
 		skb->nh.iph->tot_len = 0;
@@ -1160,22 +1191,16 @@
 		context_desc->mss = cpu_to_le16(mss);
 		context_desc->hdr_len = hdr_len;
 		context_desc->status = 0;
-		context_desc->cmd_type_len = cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
-							 |
-							 IXGB_CONTEXT_DESC_CMD_TSE
-							 |
-							 IXGB_CONTEXT_DESC_CMD_IP
-							 |
-							 IXGB_CONTEXT_DESC_CMD_TCP
-							 |
-							 IXGB_CONTEXT_DESC_CMD_RS
-							 |
-							 IXGB_CONTEXT_DESC_CMD_IDE
-							 | (skb->len -
-							    (hdr_len)));
+		context_desc->cmd_type_len = cpu_to_le32(
+						  IXGB_CONTEXT_DESC_TYPE 
+						| IXGB_CONTEXT_DESC_CMD_TSE
+						| IXGB_CONTEXT_DESC_CMD_IP
+						| IXGB_CONTEXT_DESC_CMD_TCP
+						| IXGB_CONTEXT_DESC_CMD_RS
+						| IXGB_CONTEXT_DESC_CMD_IDE
+						| (skb->len - (hdr_len)));
 
-		if (++i == adapter->tx_ring.count)
-			i = 0;
+		if(++i == adapter->tx_ring.count) i = 0;
 		adapter->tx_ring.next_to_use = i;
 
 		return TRUE;
@@ -1192,7 +1217,7 @@
 	unsigned int i;
 	uint8_t css, cso;
 
-	if (likely(skb->ip_summed == CHECKSUM_HW)) {
+	if(likely(skb->ip_summed == CHECKSUM_HW)) {
 		css = skb->h.raw - skb->data;
 		cso = (skb->h.raw + skb->csum) - skb->data;
 
@@ -1203,16 +1228,16 @@
 		context_desc->tucso = cso;
 		context_desc->tucse = 0;
 		/* zero out any previously existing data in one instruction */
-		*(uint32_t *) & (context_desc->ipcss) = 0;
+		*(uint32_t *)&(context_desc->ipcss) = 0;
 		context_desc->status = 0;
 		context_desc->hdr_len = 0;
 		context_desc->mss = 0;
 		context_desc->cmd_type_len =
-		    cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
-				| IXGB_TX_DESC_CMD_RS | IXGB_TX_DESC_CMD_IDE);
+			cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
+					| IXGB_TX_DESC_CMD_RS 
+					| IXGB_TX_DESC_CMD_IDE);
 
-		if (++i == adapter->tx_ring.count)
-			i = 0;
+		if(++i == adapter->tx_ring.count) i = 0;
 		adapter->tx_ring.next_to_use = i;
 
 		return TRUE;
@@ -1239,45 +1264,46 @@
 
 	i = tx_ring->next_to_use;
 
-	while (len) {
+	while(len) {
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
 		buffer_info->length = size;
 		buffer_info->dma =
-		    pci_map_single(adapter->pdev,
-				   skb->data + offset, size, PCI_DMA_TODEVICE);
+			pci_map_single(adapter->pdev,
+				skb->data + offset,
+				size,
+				PCI_DMA_TODEVICE);
 		buffer_info->time_stamp = jiffies;
 
 		len -= size;
 		offset += size;
 		count++;
-		if (++i == tx_ring->count)
-			i = 0;
+		if(++i == tx_ring->count) i = 0;
 	}
 
-	for (f = 0; f < nr_frags; f++) {
+	for(f = 0; f < nr_frags; f++) {
 		struct skb_frag_struct *frag;
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
 		offset = 0;
 
-		while (len) {
+		while(len) {
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
 			buffer_info->length = size;
 			buffer_info->dma =
-			    pci_map_page(adapter->pdev,
-					 frag->page,
-					 frag->page_offset + offset,
-					 size, PCI_DMA_TODEVICE);
+				pci_map_page(adapter->pdev,
+					frag->page,
+					frag->page_offset + offset,
+					size,
+					PCI_DMA_TODEVICE);
 			buffer_info->time_stamp = jiffies;
 
 			len -= size;
 			offset += size;
 			count++;
-			if (++i == tx_ring->count)
-				i = 0;
+			if(++i == tx_ring->count) i = 0;
 		}
 	}
 	i = (i == 0) ? tx_ring->count - 1 : i - 1;
@@ -1288,8 +1314,7 @@
 }
 
 static inline void
-ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
-	      int tx_flags)
+ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct ixgb_tx_desc *tx_desc = NULL;
@@ -1299,36 +1324,35 @@
 	uint8_t popts = 0;
 	unsigned int i;
 
-	if (tx_flags & IXGB_TX_FLAGS_TSO) {
+	if(tx_flags & IXGB_TX_FLAGS_TSO) {
 		cmd_type_len |= IXGB_TX_DESC_CMD_TSE;
 		popts |= (IXGB_TX_DESC_POPTS_IXSM | IXGB_TX_DESC_POPTS_TXSM);
 	}
 
-	if (tx_flags & IXGB_TX_FLAGS_CSUM)
+	if(tx_flags & IXGB_TX_FLAGS_CSUM)
 		popts |= IXGB_TX_DESC_POPTS_TXSM;
 
-	if (tx_flags & IXGB_TX_FLAGS_VLAN) {
+	if(tx_flags & IXGB_TX_FLAGS_VLAN) {
 		cmd_type_len |= IXGB_TX_DESC_CMD_VLE;
 	}
 
 	i = tx_ring->next_to_use;
 
-	while (count--) {
+	while(count--) {
 		buffer_info = &tx_ring->buffer_info[i];
 		tx_desc = IXGB_TX_DESC(*tx_ring, i);
 		tx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
 		tx_desc->cmd_type_len =
-		    cpu_to_le32(cmd_type_len | buffer_info->length);
+			cpu_to_le32(cmd_type_len | buffer_info->length);
 		tx_desc->status = status;
 		tx_desc->popts = popts;
 		tx_desc->vlan = cpu_to_le16(vlan_id);
 
-		if (++i == tx_ring->count)
-			i = 0;
+		if(++i == tx_ring->count) i = 0;
 	}
 
-	tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP
-					     | IXGB_TX_DESC_CMD_RS);
+	tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP 
+				| IXGB_TX_DESC_CMD_RS );
 
 	/* Force memory writes to complete before letting h/w
 	 * know there are new descriptors to fetch.  (Only
@@ -1346,7 +1370,8 @@
 #define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) + \
 	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
 
-static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static int
+ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	unsigned int first;
@@ -1354,33 +1379,33 @@
 	unsigned long flags;
 	int vlan_id = 0;
 
-	if (skb->len <= 0) {
+	if(skb->len <= 0) {
 		dev_kfree_skb_any(skb);
 		return 0;
 	}
 
 	spin_lock_irqsave(&adapter->tx_lock, flags);
-	if (unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
+	if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&adapter->tx_lock, flags);
 		return 1;
 	}
 	spin_unlock_irqrestore(&adapter->tx_lock, flags);
 
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
 		tx_flags |= IXGB_TX_FLAGS_VLAN;
 		vlan_id = vlan_tx_tag_get(skb);
 	}
 
 	first = adapter->tx_ring.next_to_use;
-
-	if (ixgb_tso(adapter, skb))
+	
+	if(ixgb_tso(adapter, skb))
 		tx_flags |= IXGB_TX_FLAGS_TSO;
-	else if (ixgb_tx_csum(adapter, skb))
+	else if(ixgb_tx_csum(adapter, skb))
 		tx_flags |= IXGB_TX_FLAGS_CSUM;
 
 	ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
-		      tx_flags);
+			tx_flags);
 
 	netdev->trans_start = jiffies;
 
@@ -1392,7 +1417,8 @@
  * @netdev: network interface device structure
  **/
 
-static void ixgb_tx_timeout(struct net_device *netdev)
+static void
+ixgb_tx_timeout(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -1400,14 +1426,13 @@
 	schedule_work(&adapter->tx_timeout_task);
 }
 
-static void ixgb_tx_timeout_task(struct net_device *netdev)
+static void
+ixgb_tx_timeout_task(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
-	netif_device_detach(netdev);
 	ixgb_down(adapter, TRUE);
 	ixgb_up(adapter);
-	netif_device_attach(netdev);
 }
 
 /**
@@ -1418,7 +1443,8 @@
  * The statistics are actually updated from the timer callback.
  **/
 
-static struct net_device_stats *ixgb_get_stats(struct net_device *netdev)
+static struct net_device_stats *
+ixgb_get_stats(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -1433,27 +1459,28 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_change_mtu(struct net_device *netdev, int new_mtu)
+static int
+ixgb_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	uint32_t old_mtu = adapter->rx_buffer_len;
 	int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
+	int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
+
 
-	if ((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
-	    || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
+	if((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
+	   || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
 		IXGB_ERR("Invalid MTU setting\n");
 		return -EINVAL;
 	}
 
-	if ((max_frame <=
-	     IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
-	    || (max_frame <= IXGB_RXBUFFER_2048)) {
+	if((max_frame <= IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
+	   || (max_frame <= IXGB_RXBUFFER_2048)) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_2048;
 
-	} else if (max_frame <= IXGB_RXBUFFER_4096) {
+	} else if(max_frame <= IXGB_RXBUFFER_4096) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_4096;
 
-	} else if (max_frame <= IXGB_RXBUFFER_8192) {
+	} else if(max_frame <= IXGB_RXBUFFER_8192) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_8192;
 
 	} else {
@@ -1462,7 +1489,7 @@
 
 	netdev->mtu = new_mtu;
 
-	if (old_mtu != adapter->rx_buffer_len && netif_running(netdev)) {
+	if(old_max_frame != max_frame && netif_running(netdev)) {
 
 		ixgb_down(adapter, TRUE);
 		ixgb_up(adapter);
@@ -1476,7 +1503,8 @@
  * @adapter: board private structure
  **/
 
-static void ixgb_update_stats(struct ixgb_adapter *adapter)
+void
+ixgb_update_stats(struct ixgb_adapter *adapter)
 {
 	adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL);
 	adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH);
@@ -1585,31 +1613,33 @@
  * @pt_regs: CPU registers structure
  **/
 
-static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t
+ixgb_intr(int irq, void *data, struct pt_regs *regs)
 {
 	struct net_device *netdev = data;
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	uint32_t icr = IXGB_READ_REG(&adapter->hw, ICR);
+	uint32_t icr = IXGB_READ_REG(hw, ICR);
 #ifndef CONFIG_IXGB_NAPI
 	unsigned int i;
 #endif
 
-	if (unlikely(!icr))
-		return IRQ_NONE;	/* Not our interrupt */
+	if(unlikely(!icr))
+		return IRQ_NONE;  /* Not our interrupt */
 
-	if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
+	if(unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
 		mod_timer(&adapter->watchdog_timer, jiffies);
 	}
+
 #ifdef CONFIG_IXGB_NAPI
-	if (netif_rx_schedule_prep(netdev)) {
+	if(netif_rx_schedule_prep(netdev)) {
 
 		/* Disable interrupts and register for poll. The flush 
-		   of the posted write is intentionally left out.
-		 */
+		  of the posted write is intentionally left out.
+		*/
 
 		atomic_inc(&adapter->irq_sem);
-		IXGB_WRITE_REG(hw, IMC, ~0);
+		IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
 		__netif_rx_schedule(netdev);
 	}
 #else
@@ -1621,16 +1651,7 @@
 		if(!ixgb_clean_rx_irq(adapter) &
 		   !ixgb_clean_tx_irq(adapter))
 			break;
-	/* if RAIDC:EN == 1 and ICR:RXDMT0 == 1, we need to
-	 * set IMS:RXDMT0 to 1 to restart the RBD timer (POLL)
-	 */
-	if ((icr & IXGB_INT_RXDMT0) && adapter->raidc) {
-		/* ready the timer by writing the clear reg */
-		IXGB_WRITE_REG(hw, IMC, IXGB_INT_RXDMT0);
-		/* now restart it, h/w will decide if its necessary */
-		IXGB_WRITE_REG(hw, IMS, IXGB_INT_RXDMT0);
-	}
-#endif
+#endif 
 	return IRQ_HANDLED;
 }
 
@@ -1640,25 +1661,32 @@
  * @adapter: board private structure
  **/
 
-static int ixgb_clean(struct net_device *netdev, int *budget)
+static int
+ixgb_clean(struct net_device *netdev, int *budget)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	int work_to_do = min(*budget, netdev->quota);
+	int tx_cleaned;
 	int work_done = 0;
+	
+	if (!netif_carrier_ok(netdev))
+		goto quit_polling;
 
-	ixgb_clean_tx_irq(adapter);
+	tx_cleaned = ixgb_clean_tx_irq(adapter);
 	ixgb_clean_rx_irq(adapter, &work_done, work_to_do);
 
 	*budget -= work_done;
 	netdev->quota -= work_done;
-
-	if (work_done < work_to_do || !netif_running(netdev)) {
-		netif_rx_complete(netdev);
-		/* RAIDC will be automatically restarted by irq_enable */
+	
+	/* if no Tx cleanup and not enough Rx work done, exit the polling mode */
+	if((!tx_cleaned && (work_done < work_to_do)) || 
+				!netif_running(netdev)) {
+quit_polling:	netif_rx_complete(netdev);
 		ixgb_irq_enable(adapter);
+		return 0;
 	}
 
-	return (work_done >= work_to_do);
+	return 1;
 }
 #endif
 
@@ -1667,11 +1695,11 @@
  * @adapter: board private structure
  **/
 
-static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
+static boolean_t
+ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct net_device *netdev = adapter->netdev;
-	struct pci_dev *pdev = adapter->pdev;
 	struct ixgb_tx_desc *tx_desc, *eop_desc;
 	struct ixgb_buffer *buffer_info;
 	unsigned int i, eop;
@@ -1681,9 +1709,9 @@
 	eop = tx_ring->buffer_info[i].next_to_watch;
 	eop_desc = IXGB_TX_DESC(*tx_ring, eop);
 
-	while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
+	while(eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
 
-		for (cleaned = FALSE; !cleaned;) {
+		for(cleaned = FALSE; !cleaned; ) {
 			tx_desc = IXGB_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 
@@ -1692,28 +1720,12 @@
 			       IXGB_TX_DESC_POPTS_IXSM))
 				adapter->hw_csum_tx_good++;
 
-			if (buffer_info->dma) {
-
-				pci_unmap_page(pdev,
-					       buffer_info->dma,
-					       buffer_info->length,
-					       PCI_DMA_TODEVICE);
-
-				buffer_info->dma = 0;
-			}
-
-			if (buffer_info->skb) {
-
-				dev_kfree_skb_any(buffer_info->skb);
+			ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
 
-				buffer_info->skb = NULL;
-			}
-
-			*(uint32_t *) & (tx_desc->status) = 0;
+			*(uint32_t *)&(tx_desc->status) = 0;
 
 			cleaned = (i == eop);
-			if (++i == tx_ring->count)
-				i = 0;
+			if(++i == tx_ring->count) i = 0;
 		}
 
 		eop = tx_ring->buffer_info[i].next_to_watch;
@@ -1723,8 +1735,8 @@
 	tx_ring->next_to_clean = i;
 
 	spin_lock(&adapter->tx_lock);
-	if (cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev)
-	    && (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
+	if(cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev) &&
+	   (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
 
 		netif_wake_queue(netdev);
 	}
@@ -1742,20 +1754,21 @@
 
 static inline void
 ixgb_rx_checksum(struct ixgb_adapter *adapter,
-		 struct ixgb_rx_desc *rx_desc, struct sk_buff *skb)
+		 struct ixgb_rx_desc *rx_desc,
+		 struct sk_buff *skb)
 {
 	/* Ignore Checksum bit is set OR
 	 * TCP Checksum has not been calculated
 	 */
-	if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
-	    (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
+	if((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
+	   (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
 		skb->ip_summed = CHECKSUM_NONE;
 		return;
 	}
 
 	/* At this point we know the hardware did the TCP checksum */
 	/* now look at the TCP checksum error bit */
-	if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
+	if(rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
 		/* let the stack verify checksum errors */
 		skb->ip_summed = CHECKSUM_NONE;
 		adapter->hw_csum_rx_error++;
@@ -1792,18 +1805,22 @@
 	rx_desc = IXGB_RX_DESC(*rx_ring, i);
 	buffer_info = &rx_ring->buffer_info[i];
 
-	while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
+	while(rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
 
+#ifdef CONFIG_IXGB_NAPI
+		if(*work_done >= work_to_do)
+			break;
+
+		(*work_done)++;
+#endif
 		skb = buffer_info->skb;
 		prefetch(skb->data);
 
-		if (++i == rx_ring->count)
-			i = 0;
+		if(++i == rx_ring->count) i = 0;
 		next_rxd = IXGB_RX_DESC(*rx_ring, i);
 		prefetch(next_rxd);
 
-		if ((j = i + 1) == rx_ring->count)
-			j = 0;
+		if((j = i + 1) == rx_ring->count) j = 0;
 		next2_buffer = &rx_ring->buffer_info[j];
 		prefetch(next2_buffer);
 
@@ -1811,27 +1828,22 @@
 		next_skb = next_buffer->skb;
 		prefetch(next_skb);
 
-#ifdef CONFIG_IXGB_NAPI
-		if (*work_done >= work_to_do)
-			break;
-
-		(*work_done)++;
-#endif
 
 		cleaned = TRUE;
 
 		pci_unmap_single(pdev,
 				 buffer_info->dma,
-				 buffer_info->length, PCI_DMA_FROMDEVICE);
+				 buffer_info->length,
+				 PCI_DMA_FROMDEVICE);
 
 		length = le16_to_cpu(rx_desc->length);
 
-		if (unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
+		if(unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
 
 			/* All receives must fit into a single buffer */
 
 			IXGB_DBG("Receive packet consumed multiple buffers "
-				 "length<%x>\n", length);
+					 "length<%x>\n", length);
 
 			dev_kfree_skb_irq(skb);
 			rx_desc->status = 0;
@@ -1864,26 +1876,22 @@
 
 		skb->protocol = eth_type_trans(skb, netdev);
 #ifdef CONFIG_IXGB_NAPI
-		if (adapter->vlgrp
-		    && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
+		if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-						 le16_to_cpu(rx_desc->
-							     special &
-							     IXGB_RX_DESC_SPECIAL_VLAN_MASK));
+				le16_to_cpu(rx_desc->special) &
+					IXGB_RX_DESC_SPECIAL_VLAN_MASK);
 		} else {
 			netif_receive_skb(skb);
 		}
-#else				/* CONFIG_IXGB_NAPI */
-		if (adapter->vlgrp
-		    && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
+#else /* CONFIG_IXGB_NAPI */
+		if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
-					le16_to_cpu(rx_desc->
-						    special &
-						    IXGB_RX_DESC_SPECIAL_VLAN_MASK));
+				le16_to_cpu(rx_desc->special) &
+					IXGB_RX_DESC_SPECIAL_VLAN_MASK);
 		} else {
 			netif_rx(skb);
 		}
-#endif				/* CONFIG_IXGB_NAPI */
+#endif /* CONFIG_IXGB_NAPI */
 		netdev->last_rx = jiffies;
 
 		rx_desc->status = 0;
@@ -1905,7 +1913,8 @@
  * @adapter: address of board private structure
  **/
 
-static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
+static void
+ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct net_device *netdev = adapter->netdev;
@@ -1921,19 +1930,15 @@
 	buffer_info = &rx_ring->buffer_info[i];
 	cleancount = IXGB_DESC_UNUSED(rx_ring);
 
-	/* lessen this to 4 if we're
-	 * in the midst of raidc and rbd is occuring
-	 * because we don't want to delay returning buffers when low
-	 */
-	num_group_tail_writes = adapter->raidc ? 4 : IXGB_RX_BUFFER_WRITE;
+	num_group_tail_writes = IXGB_RX_BUFFER_WRITE;
 
 	/* leave one descriptor unused */
-	while (--cleancount > 0) {
+	while(--cleancount > 0) {
 		rx_desc = IXGB_RX_DESC(*rx_ring, i);
 
 		skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
 
-		if (unlikely(!skb)) {
+		if(unlikely(!skb)) {
 			/* Better luck next round */
 			break;
 		}
@@ -1949,13 +1954,14 @@
 		buffer_info->skb = skb;
 		buffer_info->length = adapter->rx_buffer_len;
 		buffer_info->dma =
-		    pci_map_single(pdev,
+			pci_map_single(pdev,
 				   skb->data,
-				   adapter->rx_buffer_len, PCI_DMA_FROMDEVICE);
+				   adapter->rx_buffer_len,
+				   PCI_DMA_FROMDEVICE);
 
 		rx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
 
-		if ((i & ~(num_group_tail_writes - 1)) == i) {
+		if((i & ~(num_group_tail_writes- 1)) == i) {
 			/* Force memory writes to complete before letting h/w
 			 * know there are new descriptors to fetch.  (Only
 			 * applicable for weak-ordered memory model archs,
@@ -1965,8 +1971,7 @@
 			IXGB_WRITE_REG(&adapter->hw, RDT, i);
 		}
 
-		if (++i == rx_ring->count)
-			i = 0;
+		if(++i == rx_ring->count) i = 0;
 		buffer_info = &rx_ring->buffer_info[i];
 	}
 
@@ -1988,7 +1993,7 @@
 	ixgb_irq_disable(adapter);
 	adapter->vlgrp = grp;
 
-	if (grp) {
+	if(grp) {
 		/* enable VLAN tag insert/strip */
 		ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
 		ctrl |= IXGB_CTRL0_VME;
@@ -2017,7 +2022,8 @@
 	ixgb_irq_enable(adapter);
 }
 
-static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
+static void
+ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	uint32_t vfta, index;
@@ -2030,19 +2036,20 @@
 	ixgb_write_vfta(&adapter->hw, index, vfta);
 }
 
-static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
+static void
+ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	uint32_t vfta, index;
 
 	ixgb_irq_disable(adapter);
 
-	if (adapter->vlgrp)
+	if(adapter->vlgrp)
 		adapter->vlgrp->vlan_devices[vid] = NULL;
 
 	ixgb_irq_enable(adapter);
 
-	/* remove VID from filter table */
+	/* remove VID from filter table*/
 
 	index = (vid >> 5) & 0x7F;
 	vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index);
@@ -2050,14 +2057,15 @@
 	ixgb_write_vfta(&adapter->hw, index, vfta);
 }
 
-static void ixgb_restore_vlan(struct ixgb_adapter *adapter)
+static void
+ixgb_restore_vlan(struct ixgb_adapter *adapter)
 {
 	ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp);
 
-	if (adapter->vlgrp) {
+	if(adapter->vlgrp) {
 		uint16_t vid;
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
-			if (!adapter->vlgrp->vlan_devices[vid])
+		for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+			if(!adapter->vlgrp->vlan_devices[vid])
 				continue;
 			ixgb_vlan_rx_add_vid(adapter->netdev, vid);
 		}
@@ -2075,7 +2083,7 @@
 {
 	struct pci_dev *pdev = NULL;
 
-	switch (event) {
+	switch(event) {
 	case SYS_DOWN:
 	case SYS_HALT:
 	case SYS_POWER_OFF:
@@ -2092,14 +2100,15 @@
  * @param pdev pci driver structure used for passing to
  * @param state power state to enter 
  **/
-static int ixgb_suspend(struct pci_dev *pdev, uint32_t state)
+static int
+ixgb_suspend(struct pci_dev *pdev, uint32_t state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgb_adapter *adapter = netdev->priv;
 
 	netif_device_detach(netdev);
 
-	if (netif_running(netdev))
+	if(netif_running(netdev))
 		ixgb_down(adapter, TRUE);
 
 	pci_save_state(pdev);
diff -Nru a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
--- a/drivers/net/ixgb/ixgb_osdep.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/ixgb/ixgb_osdep.h	2005-01-19 13:44:47 -08:00
@@ -78,19 +78,19 @@
 #define DEBUGOUT7 DEBUGOUT3
 
 #define IXGB_WRITE_REG(a, reg, value) ( \
-    writel((value), ((a)->hw_addr + IXGB_##reg)))
+	writel((value), ((a)->hw_addr + IXGB_##reg)))
 
 #define IXGB_READ_REG(a, reg) ( \
-    readl((a)->hw_addr + IXGB_##reg))
+	readl((a)->hw_addr + IXGB_##reg))
 
 #define IXGB_WRITE_REG_ARRAY(a, reg, offset, value) ( \
-    writel((value), ((a)->hw_addr + IXGB_##reg + ((offset) << 2))))
+	writel((value), ((a)->hw_addr + IXGB_##reg + ((offset) << 2))))
 
 #define IXGB_READ_REG_ARRAY(a, reg, offset) ( \
-    readl((a)->hw_addr + IXGB_##reg + ((offset) << 2)))
+	readl((a)->hw_addr + IXGB_##reg + ((offset) << 2)))
 
 #define IXGB_WRITE_FLUSH(a) IXGB_READ_REG(a, STATUS)
 
 #define IXGB_MEMCPY memcpy
 
-#endif				/* _IXGB_OSDEP_H_ */
+#endif /* _IXGB_OSDEP_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
--- a/drivers/net/ixgb/ixgb_param.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/ixgb/ixgb_param.c	2005-01-19 13:44:48 -08:00
@@ -34,31 +34,21 @@
 
 #define IXGB_MAX_NIC 8
 
-#define OPTION_UNSET    -1
+#define OPTION_UNSET	-1
 #define OPTION_DISABLED 0
 #define OPTION_ENABLED  1
 
-/* Module Parameters are always initialized to -1, so that the driver
- * can tell the difference between no user specified value or the
- * user asking for the default value.
- * The true default values are loaded in when ixgb_check_options is called.
- *
- * This is a GCC extension to ANSI C.
- * See the item "Labeled Elements in Initializers" in the section
- * "Extensions to the C Language Family" of the GCC documentation.
- */
-
-#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
-
 /* All parameters are treated the same, as an integer array of values.
  * This macro just reduces the need to repeat the same declaration code
  * over and over (plus this helps to avoid typo bugs).
  */
 
-#define IXGB_PARAM(X, S) \
-static int __devinitdata X[IXGB_MAX_NIC + 1] = IXGB_PARAM_INIT; \
-module_param_array(X, int, NULL, 0); \
-MODULE_PARM_DESC(X, S);
+#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
+#define IXGB_PARAM(X, desc) \
+	static int __devinitdata X[IXGB_MAX_NIC+1] = IXGB_PARAM_INIT; \
+	static int num_##X = 0; \
+	module_param_array_named(X, X, int, &num_##X, 0); \
+	MODULE_PARM_DESC(X, desc);
 
 /* Transmit Descriptor Count
  *
@@ -121,15 +111,6 @@
 
 IXGB_PARAM(RxIntDelay, "Receive Interrupt Delay");
 
-/* Receive Interrupt Moderation enable (uses RxIntDelay too)
- *
- * Valid Range: 0,1
- *
- * Default Value: 1
- */
-
-IXGB_PARAM(RAIDC, "Disable or enable Receive Interrupt Moderation");
-
 /* Receive Flow control high threshold (when we send a pause frame)
  * (FCRTH)
  *
@@ -173,13 +154,6 @@
 
 IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");
 
-#define DEFAULT_TXD			    256
-#define MAX_TXD				   4096
-#define MIN_TXD				     64
-
-#define DEFAULT_RXD			   1024
-#define MAX_RXD				   4096
-#define MIN_RXD				     64
 
 #define DEFAULT_TIDV	   		     32
 #define MAX_TIDV			 0xFFFF
@@ -224,9 +198,10 @@
 	} arg;
 };
 
-static int __devinit ixgb_validate_option(int *value, struct ixgb_option *opt)
+static int __devinit
+ixgb_validate_option(int *value, struct ixgb_option *opt)
 {
-	if (*value == OPTION_UNSET) {
+	if(*value == OPTION_UNSET) {
 		*value = opt->def;
 		return 0;
 	}
@@ -243,32 +218,31 @@
 		}
 		break;
 	case range_option:
-		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+		if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
 			printk(KERN_INFO "%s set to %i\n", opt->name, *value);
 			return 0;
 		}
 		break;
-	case list_option:{
-			int i;
-			struct ixgb_opt_list *ent;
-
-			for (i = 0; i < opt->arg.l.nr; i++) {
-				ent = &opt->arg.l.p[i];
-				if (*value == ent->i) {
-					if (ent->str[0] != '\0')
-						printk(KERN_INFO "%s\n",
-						       ent->str);
-					return 0;
-				}
+	case list_option: {
+		int i;
+		struct ixgb_opt_list *ent;
+
+		for(i = 0; i < opt->arg.l.nr; i++) {
+			ent = &opt->arg.l.p[i];
+			if(*value == ent->i) {
+				if(ent->str[0] != '\0')
+					printk(KERN_INFO "%s\n", ent->str);
+				return 0;
 			}
 		}
+	}
 		break;
 	default:
 		BUG();
 	}
 
 	printk(KERN_INFO "Invalid %s specified (%i) %s\n",
-	       opt->name, *value, opt->err);
+		   opt->name, *value, opt->err);
 	*value = opt->def;
 	return -1;
 }
@@ -285,198 +259,218 @@
  * in a variable in the adapter structure.
  **/
 
-void __devinit ixgb_check_options(struct ixgb_adapter *adapter)
+void __devinit
+ixgb_check_options(struct ixgb_adapter *adapter)
 {
 	int bd = adapter->bd_number;
-	if (bd >= IXGB_MAX_NIC) {
+	if(bd >= IXGB_MAX_NIC) {
 		printk(KERN_NOTICE
-		       "Warning: no configuration for board #%i\n", bd);
+			   "Warning: no configuration for board #%i\n", bd);
 		printk(KERN_NOTICE "Using defaults for all values\n");
-		bd = IXGB_MAX_NIC;
 	}
 
-	{			/* Transmit Descriptor Count */
+	{ /* Transmit Descriptor Count */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Transmit Descriptors",
-			.err = "using default of " __MODULE_STRING(DEFAULT_TXD),
-			.def = DEFAULT_TXD,
-			.arg = {.r = {.min = MIN_TXD,
-				      .max = MAX_TXD}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TXD),
+			.def  = DEFAULT_TXD,
+			.arg  = { .r = { .min = MIN_TXD,
+					 .max = MAX_TXD}}
 		};
 		struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 
-		tx_ring->count = TxDescriptors[bd];
-		ixgb_validate_option(&tx_ring->count, &opt);
+		if(num_TxDescriptors > bd) {
+			tx_ring->count = TxDescriptors[bd];
+			ixgb_validate_option(&tx_ring->count, &opt);
+		} else {
+			tx_ring->count = opt.def;
+		}
 		IXGB_ROUNDUP(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
 	}
-	{			/* Receive Descriptor Count */
+	{ /* Receive Descriptor Count */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Receive Descriptors",
-			.err = "using default of " __MODULE_STRING(DEFAULT_RXD),
-			.def = DEFAULT_RXD,
-			.arg = {.r = {.min = MIN_RXD,
-				      .max = MAX_RXD}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RXD),
+			.def  = DEFAULT_RXD,
+			.arg  = { .r = { .min = MIN_RXD,
+					 .max = MAX_RXD}}
 		};
 		struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 
-		rx_ring->count = RxDescriptors[bd];
-		ixgb_validate_option(&rx_ring->count, &opt);
+		if(num_RxDescriptors > bd) {
+			rx_ring->count = RxDescriptors[bd];
+			ixgb_validate_option(&rx_ring->count, &opt);
+		} else {
+			rx_ring->count = opt.def;
+		}
 		IXGB_ROUNDUP(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
 	}
-	{			/* Receive Checksum Offload Enable */
+	{ /* Receive Checksum Offload Enable */
 		struct ixgb_option opt = {
 			.type = enable_option,
 			.name = "Receive Checksum Offload",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "defaulting to Enabled",
+			.def  = OPTION_ENABLED
 		};
 
-		int rx_csum = XsumRX[bd];
-		ixgb_validate_option(&rx_csum, &opt);
-		adapter->rx_csum = rx_csum;
+		if(num_XsumRX > bd) {
+			int rx_csum = XsumRX[bd];
+			ixgb_validate_option(&rx_csum, &opt);
+			adapter->rx_csum = rx_csum;
+		} else {
+			adapter->rx_csum = opt.def;
+		}
 	}
-	{			/* Flow Control */
+	{ /* Flow Control */
 
 		struct ixgb_opt_list fc_list[] =
-		    { {ixgb_fc_none, "Flow Control Disabled"},
-		{ixgb_fc_rx_pause, "Flow Control Receive Only"},
-		{ixgb_fc_tx_pause, "Flow Control Transmit Only"},
-		{ixgb_fc_full, "Flow Control Enabled"},
-		{ixgb_fc_default, "Flow Control Hardware Default"}
-		};
+			{{ ixgb_fc_none,	"Flow Control Disabled" },
+			 { ixgb_fc_rx_pause,"Flow Control Receive Only" },
+			 { ixgb_fc_tx_pause,"Flow Control Transmit Only" },
+			 { ixgb_fc_full,	"Flow Control Enabled" },
+			 { ixgb_fc_default, "Flow Control Hardware Default" }};
 
 		struct ixgb_option opt = {
 			.type = list_option,
 			.name = "Flow Control",
-			.err = "reading default settings from EEPROM",
-			.def = ixgb_fc_full,
-			.arg = {.l = {.nr = LIST_LEN(fc_list),
-				      .p = fc_list}}
+			.err  = "reading default settings from EEPROM",
+			.def  = ixgb_fc_full,
+			.arg  = { .l = { .nr = LIST_LEN(fc_list),
+					 .p = fc_list }}
 		};
 
-		int fc = FlowControl[bd];
-		ixgb_validate_option(&fc, &opt);
-		adapter->hw.fc.type = fc;
+		if(num_FlowControl > bd) {
+			int fc = FlowControl[bd];
+			ixgb_validate_option(&fc, &opt);
+			adapter->hw.fc.type = fc;
+		} else {
+			adapter->hw.fc.type = opt.def;
+		}
 	}
-	{			/* Receive Flow Control High Threshold */
+	{ /* Receive Flow Control High Threshold */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Rx Flow Control High Threshold",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_FCRTH),
-			.def = DEFAULT_FCRTH,
-			.arg = {.r = {.min = MIN_FCRTH,
-				      .max = MAX_FCRTH}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTH),
+			.def  = DEFAULT_FCRTH,
+			.arg  = { .r = { .min = MIN_FCRTH,
+					 .max = MAX_FCRTH}}
 		};
 
-		adapter->hw.fc.high_water = RxFCHighThresh[bd];
-		ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring RxFCHighThresh when no RxFC\n");
+		if(num_RxFCHighThresh > bd) {
+			adapter->hw.fc.high_water = RxFCHighThresh[bd];
+			ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
+		} else {
+			adapter->hw.fc.high_water = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring RxFCHighThresh when no RxFC\n");
 	}
-	{			/* Receive Flow Control Low Threshold */
+	{ /* Receive Flow Control Low Threshold */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Rx Flow Control Low Threshold",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_FCRTL),
-			.def = DEFAULT_FCRTL,
-			.arg = {.r = {.min = MIN_FCRTL,
-				      .max = MAX_FCRTL}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTL),
+			.def  = DEFAULT_FCRTL,
+			.arg  = { .r = { .min = MIN_FCRTL,
+					 .max = MAX_FCRTL}}
 		};
 
-		adapter->hw.fc.low_water = RxFCLowThresh[bd];
-		ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring RxFCLowThresh when no RxFC\n");
+		if(num_RxFCLowThresh > bd) {
+			adapter->hw.fc.low_water = RxFCLowThresh[bd];
+			ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
+		} else {
+			adapter->hw.fc.low_water = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring RxFCLowThresh when no RxFC\n");
 	}
-	{			/* Flow Control Pause Time Request */
+	{ /* Flow Control Pause Time Request*/
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Flow Control Pause Time Request",
-			.err =
-			    "using default of "
-			    __MODULE_STRING(DEFAULT_FCPAUSE),
-			.def = DEFAULT_FCPAUSE,
-			.arg = {.r = {.min = MIN_FCPAUSE,
-				      .max = MAX_FCPAUSE}}
+			.err  = "using default of "__MODULE_STRING(DEFAULT_FCPAUSE),
+			.def  = DEFAULT_FCPAUSE,
+			.arg = { .r = { .min = MIN_FCPAUSE,
+					.max = MAX_FCPAUSE}}
 		};
 
-		int pause_time = FCReqTimeout[bd];
-
-		ixgb_validate_option(&pause_time, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring FCReqTimeout when no RxFC\n");
-		adapter->hw.fc.pause_time = pause_time;
+		if(num_FCReqTimeout > bd) {
+			int pause_time = FCReqTimeout[bd];
+			ixgb_validate_option(&pause_time, &opt);
+			adapter->hw.fc.pause_time = pause_time;
+		} else {
+			adapter->hw.fc.pause_time = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring FCReqTimeout when no RxFC\n");
 	}
 	/* high low and spacing check for rx flow control thresholds */
 	if (adapter->hw.fc.type & ixgb_fc_rx_pause) {
 		/* high must be greater than low */
 		if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) {
 			/* set defaults */
-			printk(KERN_INFO
-			       "RxFCHighThresh must be >= (RxFCLowThresh + 8), "
-			       "Using Defaults\n");
+			printk (KERN_INFO 
+				"RxFCHighThresh must be >= (RxFCLowThresh + 8), "
+				"Using Defaults\n");
 			adapter->hw.fc.high_water = DEFAULT_FCRTH;
-			adapter->hw.fc.low_water = DEFAULT_FCRTL;
+			adapter->hw.fc.low_water  = DEFAULT_FCRTL;
 		}
 	}
-	{			/* Receive Interrupt Delay */
+	{ /* Receive Interrupt Delay */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Receive Interrupt Delay",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_RDTR),
-			.def = DEFAULT_RDTR,
-			.arg = {.r = {.min = MIN_RDTR,
-				      .max = MAX_RDTR}}
-		};
-
-		adapter->rx_int_delay = RxIntDelay[bd];
-		ixgb_validate_option(&adapter->rx_int_delay, &opt);
-	}
-	{			/* Receive Interrupt Moderation */
-		struct ixgb_option opt = {
-			.type = enable_option,
-			.name = "Advanced Receive Interrupt Moderation",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR),
+			.def  = DEFAULT_RDTR,
+			.arg  = { .r = { .min = MIN_RDTR,
+					 .max = MAX_RDTR}}
 		};
-		int raidc = RAIDC[bd];
 
-		ixgb_validate_option(&raidc, &opt);
-		adapter->raidc = raidc;
+		if(num_RxIntDelay > bd) {
+			adapter->rx_int_delay = RxIntDelay[bd];
+			ixgb_validate_option(&adapter->rx_int_delay, &opt);
+		} else {
+			adapter->rx_int_delay = opt.def;
+		}
 	}
-	{			/* Transmit Interrupt Delay */
+	{ /* Transmit Interrupt Delay */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Transmit Interrupt Delay",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_TIDV),
-			.def = DEFAULT_TIDV,
-			.arg = {.r = {.min = MIN_TIDV,
-				      .max = MAX_TIDV}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV),
+			.def  = DEFAULT_TIDV,
+			.arg  = { .r = { .min = MIN_TIDV,
+					 .max = MAX_TIDV}}
 		};
 
-		adapter->tx_int_delay = TxIntDelay[bd];
-		ixgb_validate_option(&adapter->tx_int_delay, &opt);
+		if(num_TxIntDelay > bd) {
+			adapter->tx_int_delay = TxIntDelay[bd];
+			ixgb_validate_option(&adapter->tx_int_delay, &opt);
+		} else {
+			adapter->tx_int_delay = opt.def;
+		}
 	}
 
-	{			/* Transmit Interrupt Delay Enable */
+	{ /* Transmit Interrupt Delay Enable */
 		struct ixgb_option opt = {
 			.type = enable_option,
 			.name = "Tx Interrupt Delay Enable",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "defaulting to Enabled",
+			.def  = OPTION_ENABLED
 		};
-		int ide = IntDelayEnable[bd];
 
-		ixgb_validate_option(&ide, &opt);
-		adapter->tx_int_delay_enable = ide;
+		if(num_IntDelayEnable > bd) {
+			int ide = IntDelayEnable[bd];
+			ixgb_validate_option(&ide, &opt);
+			adapter->tx_int_delay_enable = ide;
+		} else {
+			adapter->tx_int_delay_enable = opt.def;
+		}
 	}
 }
diff -Nru a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
--- a/drivers/net/myri_sbus.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/net/myri_sbus.c	2005-01-19 13:44:45 -08:00
@@ -118,7 +118,7 @@
 
 static inline void bang_the_chip(struct myri_eth *mp)
 {
-	struct myri_shmem *shmem	= mp->shmem;
+	struct myri_shmem __iomem *shmem = mp->shmem;
 	void __iomem *cregs		= mp->cregs;
 
 	sbus_writel(1, &shmem->send);
@@ -127,9 +127,9 @@
 
 static int myri_do_handshake(struct myri_eth *mp)
 {
-	struct myri_shmem *shmem	= mp->shmem;
+	struct myri_shmem __iomem *shmem = mp->shmem;
 	void __iomem *cregs = mp->cregs;
-	struct myri_channel *chan	= &shmem->channel;
+	struct myri_channel __iomem *chan = &shmem->channel;
 	int tick 			= 0;
 
 	DET(("myri_do_handshake: "));
@@ -427,7 +427,7 @@
 		u32 csum		= sbus_readl(&rxdack->csum);
 		int len			= sbus_readl(&rxdack->myri_scatters[0].len);
 		int index		= sbus_readl(&rxdack->ctx);
-		struct myri_rxd __iomem *rxd	= &rq->myri_rxd[rq->tail];
+		struct myri_rxd __iomem *rxd = &rq->myri_rxd[sbus_readl(&rq->tail)];
 		struct sk_buff *skb	= mp->rx_skbs[index];
 
 		/* Ack it. */
@@ -546,7 +546,7 @@
 	struct net_device *dev		= (struct net_device *) dev_id;
 	struct myri_eth *mp		= (struct myri_eth *) dev->priv;
 	void __iomem *lregs		= mp->lregs;
-	struct myri_channel *chan	= &mp->shmem->channel;
+	struct myri_channel __iomem *chan = &mp->shmem->channel;
 	unsigned long flags;
 	u32 status;
 	int handled = 0;
diff -Nru a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
--- a/drivers/net/pcmcia/3c574_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/pcmcia/3c574_cs.c	2005-01-19 13:44:46 -08:00
@@ -109,11 +109,6 @@
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-/* Now-standard PC card module parameters. */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 INT_MODULE_PARM(max_interrupt_work, 32);
 
@@ -275,7 +270,7 @@
 	client_reg_t client_reg;
 	dev_link_t *link;
 	struct net_device *dev;
-	int i, ret;
+	int ret;
 
 	DEBUG(0, "3c574_attach()\n");
 
@@ -291,12 +286,7 @@
 	link->io.NumPorts1 = 32;
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = &el3_interrupt;
 	link->irq.Instance = dev;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
diff -Nru a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
--- a/drivers/net/pcmcia/3c589_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/pcmcia/3c589_cs.c	2005-01-19 13:44:47 -08:00
@@ -131,11 +131,6 @@
 /* Special hook for setting if_port when module is loaded */
 INT_MODULE_PARM(if_port, 0);
 
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
@@ -188,7 +183,7 @@
     client_reg_t client_reg;
     dev_link_t *link;
     struct net_device *dev;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "3c589_attach()\n");
     
@@ -204,12 +199,7 @@
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &el3_interrupt;
     link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
diff -Nru a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
--- a/drivers/net/pcmcia/axnet_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/pcmcia/axnet_cs.c	2005-01-19 13:44:47 -08:00
@@ -73,14 +73,9 @@
 MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
+#ifdef PCMCIA_DEBUG
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask,	0xdeb8);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
-#ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
@@ -159,7 +154,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "axnet_attach()\n");
 
@@ -173,12 +168,7 @@
     link = &info->link;
     link->priv = dev;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
diff -Nru a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
--- a/drivers/net/pcmcia/com20020_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/pcmcia/com20020_cs.c	2005-01-19 13:44:46 -08:00
@@ -115,12 +115,6 @@
 module_param(clockp, int, 0);
 module_param(clockm, int, 0);
 
-/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
 MODULE_LICENSE("GPL");
 
 /*====================================================================*/
@@ -158,7 +152,7 @@
     dev_link_t *link;
     com20020_dev_t *info;
     struct net_device *dev;
-    int i, ret;
+    int ret;
     struct arcnet_local *lp;
     
     DEBUG(0, "com20020_attach()\n");
@@ -192,12 +186,7 @@
     link->io.NumPorts1 = 16;
     link->io.IOAddrLines = 16;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
diff -Nru a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
--- a/drivers/net/pcmcia/fmvj18x_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/pcmcia/fmvj18x_cs.c	2005-01-19 13:44:47 -08:00
@@ -69,12 +69,6 @@
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 /* SRAM configuration */
 /* 0:4KB*2 TX buffer   else:8KB*2 TX buffer */
 INT_MODULE_PARM(sram_config, 0);
@@ -248,7 +242,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "fmvj18x_attach()\n");
 
@@ -267,12 +261,7 @@
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &fjn_interrupt;
     link->irq.Instance = dev;
     
diff -Nru a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
--- a/drivers/net/pcmcia/ibmtr_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/pcmcia/ibmtr_cs.c	2005-01-19 13:44:46 -08:00
@@ -86,10 +86,6 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
 /* MMIO base address */
 static u_long mmiobase = 0xce000;
 
@@ -102,8 +98,6 @@
 /* Ringspeed 4,16 */
 static int ringspeed = 16;
 
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
 module_param(mmiobase, ulong, 0);
 module_param(srambase, ulong, 0);
 module_param(sramsize, ulong, 0);
@@ -162,7 +156,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "ibmtr_attach()\n");
 
@@ -184,12 +178,7 @@
     link->io.NumPorts1 = 4;
     link->io.IOAddrLines = 16;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &tok_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
diff -Nru a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
--- a/drivers/net/pcmcia/nmclan_cs.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/net/pcmcia/nmclan_cs.c	2005-01-19 13:44:45 -08:00
@@ -407,13 +407,8 @@
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 /* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
 INT_MODULE_PARM(if_port, 0);
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
 
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
@@ -461,7 +456,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "nmclan_attach()\n");
     DEBUG(1, "%s\n", rcsid);
@@ -479,12 +474,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 5;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &mace_interrupt;
     link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
diff -Nru a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
--- a/drivers/net/pcmcia/pcnet_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/pcmcia/pcnet_cs.c	2005-01-19 13:44:47 -08:00
@@ -89,11 +89,6 @@
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask,	0xdeb8);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 INT_MODULE_PARM(if_port,	1);	/* Transceiver type */
 INT_MODULE_PARM(use_big_buf,	1);	/* use 64K packet buffer? */
 INT_MODULE_PARM(mem_speed,	0);	/* shared mem speed, in ns */
@@ -256,7 +251,7 @@
     dev_link_t *link;
     struct net_device *dev;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "pcnet_attach()\n");
 
@@ -268,12 +263,7 @@
     link->priv = dev;
 
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
diff -Nru a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
--- a/drivers/net/pcmcia/smc91c92_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/pcmcia/smc91c92_cs.c	2005-01-19 13:44:47 -08:00
@@ -76,11 +76,6 @@
 */
 INT_MODULE_PARM(if_port, 0);
 
-/* Bit map of interrupts to choose from. */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 static const char *version =
@@ -320,7 +315,7 @@
     struct smc_private *smc;
     dev_link_t *link;
     struct net_device *dev;
-    int i, ret;
+    int ret;
 
     DEBUG(0, "smc91c92_attach()\n");
 
@@ -337,12 +332,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 4;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &smc_interrupt;
     link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
--- a/drivers/net/pcmcia/xirc2ps_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/pcmcia/xirc2ps_cs.c	2005-01-19 13:44:46 -08:00
@@ -257,9 +257,6 @@
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-INT_MODULE_PARM(irq_mask,	0xdeb8);
 INT_MODULE_PARM(if_port,	0);
 INT_MODULE_PARM(full_duplex,	0);
 INT_MODULE_PARM(do_sound, 	1);
@@ -921,13 +918,7 @@
     link->io.IOAddrLines =10;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
     link->irq.Attributes = IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else {
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
-    }
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     if (local->modem) {
 	int pass;
 
@@ -2025,23 +2016,17 @@
 #ifndef MODULE
 static int __init setup_xirc2ps_cs(char *str)
 {
-	/* irq, irq_mask, if_port, full_duplex, do_sound, lockup_hack
-	 * [,irq2 [,irq3 [,irq4]]]
+	/* if_port, full_duplex, do_sound, lockup_hack
 	 */
 	int ints[10] = { -1 };
 
 	str = get_options(str, 9, ints);
 
 #define MAYBE_SET(X,Y) if (ints[0] >= Y && ints[Y] != -1) { X = ints[Y]; }
-	MAYBE_SET(irq_list[0], 1);
-	MAYBE_SET(irq_mask, 2);
 	MAYBE_SET(if_port, 3);
 	MAYBE_SET(full_duplex, 4);
 	MAYBE_SET(do_sound, 5);
 	MAYBE_SET(lockup_hack, 6);
-	MAYBE_SET(irq_list[1], 7);
-	MAYBE_SET(irq_list[2], 8);
-	MAYBE_SET(irq_list[3], 9);
 #undef  MAYBE_SET
 
 	return 0;
diff -Nru a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/s2io.c	2005-01-19 13:44:47 -08:00
@@ -277,7 +277,7 @@
 	int lst_size, lst_per_page;
 	struct net_device *dev = nic->dev;
 #ifdef CONFIG_2BUFF_MODE
-	u64 tmp;
+	unsigned long tmp;
 	buffAdd_t *ba;
 #endif
 
@@ -448,22 +448,22 @@
 			while (k != MAX_RXDS_PER_BLOCK) {
 				ba = &nic->ba[i][j][k];
 
-				ba->ba_0_org = (void *) kmalloc
+				ba->ba_0_org = kmalloc
 				    (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
 				if (!ba->ba_0_org)
 					return -ENOMEM;
-				tmp = (u64) ba->ba_0_org;
+				tmp = (unsigned long) ba->ba_0_org;
 				tmp += ALIGN_SIZE;
-				tmp &= ~((u64) ALIGN_SIZE);
+				tmp &= ~((unsigned long) ALIGN_SIZE);
 				ba->ba_0 = (void *) tmp;
 
-				ba->ba_1_org = (void *) kmalloc
+				ba->ba_1_org = kmalloc
 				    (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
 				if (!ba->ba_1_org)
 					return -ENOMEM;
-				tmp = (u64) ba->ba_1_org;
+				tmp = (unsigned long) ba->ba_1_org;
 				tmp += ALIGN_SIZE;
-				tmp &= ~((u64) ALIGN_SIZE);
+				tmp &= ~((unsigned long) ALIGN_SIZE);
 				ba->ba_1 = (void *) tmp;
 				k++;
 			}
@@ -560,21 +560,35 @@
 	for (i = 0; i < config->rx_ring_num; i++) {
 		blk_cnt =
 		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
+		if (!nic->ba[i])
+			goto end_free;
 		for (j = 0; j < blk_cnt; j++) {
 			int k = 0;
-			if (!nic->ba[i][j])
-				continue;
+			if (!nic->ba[i][j]) {
+				kfree(nic->ba[i]);
+				goto end_free;
+			}
 			while (k != MAX_RXDS_PER_BLOCK) {
 				buffAdd_t *ba = &nic->ba[i][j][k];
+				if (!ba || !ba->ba_0_org || !ba->ba_1_org)
+				{
+					kfree(nic->ba[i]);
+					kfree(nic->ba[i][j]);
+					if(ba->ba_0_org)
+						kfree(ba->ba_0_org);
+					if(ba->ba_1_org)
+						kfree(ba->ba_1_org);
+					goto end_free;
+				}
 				kfree(ba->ba_0_org);
 				kfree(ba->ba_1_org);
 				k++;
 			}
 			kfree(nic->ba[i][j]);
 		}
-		if (nic->ba[i])
-			kfree(nic->ba[i]);
+		kfree(nic->ba[i]);
 	}
+end_free:
 #endif
 
 	if (mac_control->stats_mem) {
@@ -596,10 +610,10 @@
 
 static int init_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = nic->dev;
 	register u64 val64 = 0;
-	void *add;
+	void __iomem *add;
 	u32 time;
 	int i, j;
 	mac_info_t *mac_control;
@@ -688,7 +702,7 @@
 	schedule_timeout(HZ / 2);
 
 	/*  Enable Receiving broadcasts */
-	add = (void *) &bar0->mac_cfg;
+	add = &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 |= MAC_RMAC_BCAST_ENABLE;
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
@@ -989,7 +1003,7 @@
 	writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7);
 
 	/* Disable RMAC PAD STRIPPING */
-	add = (void *) &bar0->mac_cfg;
+	add = &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 &= ~(MAC_CFG_RMAC_STRIP_PAD);
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
@@ -1055,7 +1069,7 @@
 
 static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0, temp64 = 0;
 
 	/*  Top level interrupt classification */
@@ -1340,7 +1354,7 @@
 
 void fix_mac_address(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	int i = 0;
 
@@ -1365,7 +1379,7 @@
 
 static int start_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = nic->dev;
 	register u64 val64 = 0;
 	u16 interruptible, i;
@@ -1460,7 +1474,7 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 	}
 
 	/* 
@@ -1543,7 +1557,7 @@
 
 static void stop_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0;
 	u16 interruptible, i;
 	mac_info_t *mac_control;
@@ -1601,7 +1615,7 @@
 #ifdef CONFIG_2BUFF_MODE
 	RxD_t *rxdpnext;
 	int nextblk;
-	u64 tmp;
+	unsigned long tmp;
 	buffAdd_t *ba;
 	dma_addr_t rxdpphys;
 #endif
@@ -1743,7 +1757,7 @@
 #else
 		ba = &nic->ba[ring_no][block_no][off];
 		skb_reserve(skb, BUF0_LEN);
-		tmp = (u64) skb->data;
+		tmp = (unsigned long) skb->data;
 		tmp += ALIGN_SIZE;
 		tmp &= ~ALIGN_SIZE;
 		skb->data = (void *) tmp;
@@ -1886,7 +1900,7 @@
 static int s2io_poll(struct net_device *dev, int *budget)
 {
 	nic_t *nic = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	int pkts_to_process = *budget, pkt_cnt = 0;
 	register u64 val64 = 0;
 	rx_curr_get_info_t get_info, put_info;
@@ -2255,7 +2269,7 @@
 
 static void tx_intr_handler(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = (struct net_device *) nic->dev;
 	tx_curr_get_info_t get_info, put_info;
 	struct sk_buff *skb;
@@ -2362,7 +2376,7 @@
 static void alarm_intr_handler(struct s2io_nic *nic)
 {
 	struct net_device *dev = (struct net_device *) nic->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0, err_reg = 0;
 
 	/* Handling link status change error Intr */
@@ -2413,7 +2427,7 @@
 
 int wait_for_cmd_complete(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	int ret = FAILURE, cnt = 0;
 	u64 val64;
 
@@ -2444,7 +2458,7 @@
 
 void s2io_reset(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	u16 subid;
 
@@ -2480,7 +2494,7 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 	}
 
 	sp->device_enabled_once = FALSE;
@@ -2499,7 +2513,7 @@
 int s2io_set_swapper(nic_t * sp)
 {
 	struct net_device *dev = sp->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 
 	/* 
@@ -2675,14 +2689,14 @@
 	u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
 	register u64 val64;
 	TxD_t *txdp;
-	TxFIFO_element_t *tx_fifo;
+	TxFIFO_element_t __iomem *tx_fifo;
 	unsigned long flags;
 #ifdef NETIF_F_TSO
 	int mss;
 #endif
 	mac_info_t *mac_control;
 	struct config_param *config;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	mac_control = &sp->mac_control;
 	config = &sp->config;
@@ -2799,7 +2813,7 @@
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 #ifndef CONFIG_S2IO_NAPI
 	int i, ret;
 #endif
@@ -2925,11 +2939,11 @@
 	int i, j, prev_cnt;
 	struct dev_mc_list *mclist;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0, multi_mac = 0x010203040506ULL, mask =
 	    0xfeffffffffffULL;
 	u64 dis_addr = 0xffffffffffffULL, mac_addr = 0;
-	void *add;
+	void __iomem *add;
 
 	if ((dev->flags & IFF_ALLMULTI) && (!sp->m_cast_flg)) {
 		/*  Enable all Multicast addresses */
@@ -2963,7 +2977,7 @@
 
 	if ((dev->flags & IFF_PROMISC) && (!sp->promisc_flg)) {
 		/*  Put the NIC into promiscuous mode */
-		add = (void *) &bar0->mac_cfg;
+		add = &bar0->mac_cfg;
 		val64 = readq(&bar0->mac_cfg);
 		val64 |= MAC_CFG_RMAC_PROM_ENABLE;
 
@@ -2978,7 +2992,7 @@
 			  dev->name);
 	} else if (!(dev->flags & IFF_PROMISC) && (sp->promisc_flg)) {
 		/*  Remove the NIC from promiscuous mode */
-		add = (void *) &bar0->mac_cfg;
+		add = &bar0->mac_cfg;
 		val64 = readq(&bar0->mac_cfg);
 		val64 &= ~MAC_CFG_RMAC_PROM_ENABLE;
 
@@ -3068,7 +3082,7 @@
 int s2io_set_mac_addr(struct net_device *dev, u8 * addr)
 {
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	register u64 val64, mac_addr = 0;
 	int i;
 
@@ -3211,7 +3225,7 @@
 	regs->version = sp->pdev->subsystem_device;
 
 	for (i = 0; i < regs->len; i += 8) {
-		reg = readq((void *) (sp->bar0 + i));
+		reg = readq(sp->bar0 + i);
 		memcpy((reg_space + i), &reg, 8);
 	}
 }
@@ -3228,7 +3242,7 @@
 static void s2io_phy_id(unsigned long data)
 {
 	nic_t *sp = (nic_t *) data;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0;
 	u16 subid;
 
@@ -3265,7 +3279,7 @@
 {
 	u64 val64 = 0, last_gpio_ctrl_val;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u16 subid;
 
 	subid = sp->pdev->subsystem_device;
@@ -3313,7 +3327,7 @@
 {
 	u64 val64;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = readq(&bar0->rmac_pause_cfg);
 	if (val64 & RMAC_PAUSE_GEN_ENABLE)
@@ -3340,7 +3354,7 @@
 {
 	u64 val64;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = readq(&bar0->rmac_pause_cfg);
 	if (ep->tx_pause)
@@ -3377,7 +3391,7 @@
 	int ret = -1;
 	u32 exit_cnt = 0;
 	u64 val64;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
@@ -3418,7 +3432,7 @@
 {
 	int exit_cnt = 0, ret = -1;
 	u64 val64;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
@@ -3541,7 +3555,7 @@
 
 static int s2io_register_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0;
 	int fail = 0;
 
@@ -3712,7 +3726,7 @@
 
 static int s2io_link_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 
 	val64 = readq(&bar0->adapter_status);
@@ -3737,7 +3751,7 @@
 
 static int s2io_rldram_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	int cnt, iteration = 0, test_pass = 0;
 
@@ -4078,7 +4092,7 @@
 int s2io_change_mtu(struct net_device *dev, int new_mtu)
 {
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	register u64 val64;
 
 	if (netif_running(dev)) {
@@ -4155,7 +4169,7 @@
 {
 	nic_t *nic = (nic_t *) data;
 	struct net_device *dev = nic->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64;
 	u16 subid;
 
@@ -4219,7 +4233,7 @@
 static void s2io_card_down(nic_t * sp)
 {
 	int cnt = 0;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	unsigned long flags;
 	register u64 val64 = 0;
 
@@ -4597,7 +4611,7 @@
 	int dma_flag = FALSE;
 	u32 mac_up, mac_down;
 	u64 val64 = 0, tmp64 = 0;
-	XENA_dev_config_t *bar0 = NULL;
+	XENA_dev_config_t __iomem *bar0 = NULL;
 	u16 subid;
 	mac_info_t *mac_control;
 	struct config_param *config;
@@ -4727,7 +4741,7 @@
 		goto mem_alloc_failed;
 	}
 
-	sp->bar0 = (caddr_t) ioremap(pci_resource_start(pdev, 0),
+	sp->bar0 = ioremap(pci_resource_start(pdev, 0),
 				     pci_resource_len(pdev, 0));
 	if (!sp->bar0) {
 		DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem1\n",
@@ -4736,7 +4750,7 @@
 		goto bar0_remap_failed;
 	}
 
-	sp->bar1 = (caddr_t) ioremap(pci_resource_start(pdev, 2),
+	sp->bar1 = ioremap(pci_resource_start(pdev, 2),
 				     pci_resource_len(pdev, 2));
 	if (!sp->bar1) {
 		DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem2\n",
@@ -4750,7 +4764,7 @@
 
 	/* Initializing the BAR1 address as the start of the FIFO pointer. */
 	for (j = 0; j < MAX_TX_FIFOS; j++) {
-		mac_control->tx_FIFO_start[j] = (TxFIFO_element_t *)
+		mac_control->tx_FIFO_start[j] = (TxFIFO_element_t __iomem *)
 		    (sp->bar1 + (j * 0x00020000));
 	}
 
@@ -4815,7 +4829,7 @@
 	 * MAC address initialization.
 	 * For now only one mac address will be read and used.
 	 */
-	bar0 = (XENA_dev_config_t *) sp->bar0;
+	bar0 = sp->bar0;
 	val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
 	    RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET);
 	writeq(val64, &bar0->rmac_addr_cmd_mem);
@@ -4872,7 +4886,7 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (u64 *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 		val64 = readq(&bar0->gpio_control);
 	}
 
diff -Nru a/drivers/net/s2io.h b/drivers/net/s2io.h
--- a/drivers/net/s2io.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/s2io.h	2005-01-19 13:44:46 -08:00
@@ -583,7 +583,7 @@
 
 /* tx side stuff */
 	/* logical pointer of start of each Tx FIFO */
-	TxFIFO_element_t *tx_FIFO_start[MAX_TX_FIFOS];
+	TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS];
 
 /* Current offset within tx_FIFO_start, where driver would write new Tx frame*/
 	tx_curr_put_info_t tx_curr_put_info[MAX_TX_FIFOS];
@@ -623,8 +623,8 @@
 	macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED];
 
 	struct net_device_stats stats;
-	caddr_t bar0;
-	caddr_t bar1;
+	void __iomem *bar0;
+	void __iomem *bar1;
 	struct config_param config;
 	mac_info_t mac_control;
 	int high_dma_flag;
@@ -736,19 +736,18 @@
 
 /*  OS related system calls */
 #ifndef readq
-static inline u64 readq(void *addr)
+static inline u64 readq(void __iomem *addr)
 {
-	u64 ret = 0;
-	ret = readl(addr + 4);
-	(u64) ret <<= 32;
-	(u64) ret |= readl(addr);
+	u64 ret = readl(addr + 4);
+	ret <<= 32;
+	ret |= readl(addr);
 
 	return ret;
 }
 #endif
 
 #ifndef writeq
-static inline void writeq(u64 val, void *addr)
+static inline void writeq(u64 val, void __iomem *addr)
 {
 	writel((u32) (val), addr);
 	writel((u32) (val >> 32), (addr + 4));
@@ -762,7 +761,7 @@
  */
 #define UF	1
 #define LF	2
-static inline void SPECIAL_REG_WRITE(u64 val, void *addr, int order)
+static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
 {
 	if (order == LF) {
 		writel((u32) (val), addr);
diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
--- a/drivers/net/smc-ultra.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/smc-ultra.c	2005-01-19 13:44:46 -08:00
@@ -156,8 +156,6 @@
 	/* Look for any installed ISAPnP cards */
 	if (isapnp_present() && (ultra_probe_isapnp(dev) == 0))
 		return 0;
-
-	printk(KERN_NOTICE "smc-ultra.c: No ISAPnP cards found, trying standard ones...\n");
 #endif
 
 	for (i = 0; ultra_portlist[i]; i++) {
diff -Nru a/drivers/net/smc91x.c b/drivers/net/smc91x.c
--- a/drivers/net/smc91x.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/smc91x.c	2005-01-19 13:44:48 -08:00
@@ -1333,6 +1333,19 @@
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void smc_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	smc_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
 /* Our watchdog timed out. Called by the networking layer */
 static void smc_timeout(struct net_device *dev)
 {
@@ -1912,6 +1925,9 @@
 	dev->get_stats = smc_query_statistics;
 	dev->set_multicast_list = smc_set_multicast_list;
 	dev->ethtool_ops = &smc_ethtool_ops;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = smc_poll_controller;
+#endif
 
 	tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
 	INIT_WORK(&lp->phy_configure, smc_phy_configure, dev);
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/tulip/tulip_core.c	2005-01-19 13:44:47 -08:00
@@ -1051,7 +1051,7 @@
 				else
 					filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 				filterbit &= 0x3f;
-				mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+				mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 				if (tulip_debug > 2) {
 					printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:"
 						   "%2.2x:%2.2x:%2.2x  %8.8x bit %d.\n", dev->name,
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/tulip/winbond-840.c	2005-01-19 13:44:46 -08:00
@@ -1410,7 +1410,7 @@
 			 i++, mclist = mclist->next) {
 			int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F;
 			filterbit &= 0x3f;
-			mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 		}
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 	}
diff -Nru a/drivers/net/tun.c b/drivers/net/tun.c
--- a/drivers/net/tun.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/tun.c	2005-01-19 13:44:46 -08:00
@@ -16,11 +16,25 @@
  */
 
 /*
+ *  Changes:
+ *
+ *  Mark Smith <markzzzsmith@yahoo.com.au>
+ *   Use random_ether_addr() for tap MAC address.
+ *
+ *  Harald Roelle <harald.roelle@ifi.lmu.de>  2004/04/20
+ *    Fixes in packet dropping, queue length setting and queue wakeup.
+ *    Increased default tx queue length.
+ *    Added ethtool API.
+ *    Minor cleanups
+ *
  *  Daniel Podlejski <underley@underley.eu.org>
  *    Modifications for 2.3.99-pre5 kernel.
  */
 
-#define TUN_VER "1.5"
+#define DRV_NAME	"tun"
+#define DRV_VERSION	"1.6"
+#define DRV_DESCRIPTION	"Universal TUN/TAP device driver"
+#define DRV_COPYRIGHT	"(C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -31,11 +45,11 @@
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
-#include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/miscdevice.h>
+#include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
@@ -53,6 +67,7 @@
 /* Network device part of the driver */
 
 static LIST_HEAD(tun_dev_list);
+static struct ethtool_ops tun_ethtool_ops;
 
 /* Net device open. */
 static int tun_net_open(struct net_device *dev)
@@ -79,18 +94,24 @@
 	if (!tun->attached)
 		goto drop;
 
-	/* Queue packet */
-	if (!(tun->flags & TUN_ONE_QUEUE)) {
-		/* Normal queueing mode.
-		 * Packet scheduler handles dropping. */
-		if (skb_queue_len(&tun->readq) >= TUN_READQ_SIZE)
+	/* Packet dropping */
+	if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) {
+		if (!(tun->flags & TUN_ONE_QUEUE)) {
+			/* Normal queueing mode. */
+			/* Packet scheduler handles dropping of further packets. */
 			netif_stop_queue(dev);
-	} else {
-		/* Single queue mode.
-		 * Driver handles dropping itself. */
-		if (skb_queue_len(&tun->readq) >= dev->tx_queue_len)
+
+			/* We won't see all dropped packets individually, so overrun
+			 * error is more appropriate. */
+			tun->stats.tx_fifo_errors++;
+		} else {
+			/* Single queue mode.
+			 * Driver handles dropping of all packets itself. */
 			goto drop;
+		}
 	}
+
+	/* Queue packet */
 	skb_queue_tail(&tun->readq, skb);
 
 	/* Notify and wake up reader process */
@@ -164,18 +185,16 @@
 		/* Zero header length */
 		dev->type = ARPHRD_NONE; 
 		dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-		dev->tx_queue_len = 10;
+		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 
 	case TUN_TAP_DEV:
 		/* Ethernet TAP Device */
 		dev->set_multicast_list = tun_net_mclist;
 
-		/* Generate random Ethernet address.  */
-		*(u16 *)dev->dev_addr = htons(0x00FF);
-		get_random_bytes(dev->dev_addr + sizeof(u16), 4);
-
 		ether_setup(dev);
+		random_ether_addr(dev->dev_addr);
+		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 	}
 }
@@ -354,7 +373,7 @@
 			schedule();
 			continue;
 		}
-		netif_start_queue(tun->dev);
+		netif_wake_queue(tun->dev);
 
 		/** Decide whether to accept this packet. This code is designed to
 		 * behave identically to an Ethernet interface. Accept the packet if
@@ -365,7 +384,8 @@
 		 *   - we are multicast promiscous.
 		 *   - we belong to the multicast group.
 		 */
-		memcpy(addr, skb->data, min(sizeof addr, skb->len));
+		memcpy(addr, skb->data,
+		       min_t(size_t, sizeof addr, skb->len));
 		bit_nr = ether_crc(sizeof addr, addr) >> 26;
 		if ((tun->if_flags & IFF_PROMISC) ||
 				memcmp(addr, tun->dev_addr, sizeof addr) == 0 ||
@@ -417,6 +437,7 @@
 	dev->hard_start_xmit = tun_net_xmit;
 	dev->stop = tun_net_close;
 	dev->get_stats = tun_net_stats;
+	dev->ethtool_ops = &tun_ethtool_ops;
 	dev->destructor = free_netdev;
 }
 
@@ -735,12 +756,97 @@
 	.devfs_name = "net/tun",
 };
 
+/* ethtool interface */
+
+static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	cmd->supported		= 0;
+	cmd->advertising	= 0;
+	cmd->speed		= SPEED_10;
+	cmd->duplex		= DUPLEX_FULL;
+	cmd->port		= PORT_TP;
+	cmd->phy_address	= 0;
+	cmd->transceiver	= XCVR_INTERNAL;
+	cmd->autoneg		= AUTONEG_DISABLE;
+	cmd->maxtxpkt		= 0;
+	cmd->maxrxpkt		= 0;
+	return 0;
+}
+
+static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->fw_version, "N/A");
+
+	switch (tun->flags & TUN_TYPE_MASK) {
+	case TUN_TUN_DEV:
+		strcpy(info->bus_info, "tun");
+		break;
+	case TUN_TAP_DEV:
+		strcpy(info->bus_info, "tap");
+		break;
+	}
+}
+
+static u32 tun_get_msglevel(struct net_device *dev)
+{
+#ifdef TUN_DEBUG
+	struct tun_struct *tun = netdev_priv(dev);
+	return tun->debug;
+#else
+	return -EOPNOTSUPP;
+#endif
+}
+
+static void tun_set_msglevel(struct net_device *dev, u32 value)
+{
+#ifdef TUN_DEBUG
+	struct tun_struct *tun = netdev_priv(dev);
+	tun->debug = value;
+#endif
+}
+
+static u32 tun_get_link(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	return tun->attached;
+}
+
+static u32 tun_get_rx_csum(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	return (tun->flags & TUN_NOCHECKSUM) == 0;
+}
+
+static int tun_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	if (data)
+		tun->flags &= ~TUN_NOCHECKSUM;
+	else
+		tun->flags |= TUN_NOCHECKSUM;
+	return 0;
+}
+
+static struct ethtool_ops tun_ethtool_ops = {
+	.get_settings	= tun_get_settings,
+	.get_drvinfo	= tun_get_drvinfo,
+	.get_msglevel	= tun_get_msglevel,
+	.set_msglevel	= tun_set_msglevel,
+	.get_link	= tun_get_link,
+	.get_rx_csum	= tun_get_rx_csum,
+	.set_rx_csum	= tun_set_rx_csum
+};
+
 int __init tun_init(void)
 {
 	int ret = 0;
 
-	printk(KERN_INFO "Universal TUN/TAP device driver %s " 
-	       "(C)1999-2002 Maxim Krasnyansky\n", TUN_VER);
+	printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
+	printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
 
 	ret = misc_register(&tun_miscdev);
 	if (ret)
@@ -765,5 +871,7 @@
 
 module_init(tun_init);
 module_exit(tun_cleanup);
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(TUN_MINOR);
diff -Nru a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
--- a/drivers/net/wan/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/wan/Kconfig	2005-01-19 13:44:46 -08:00
@@ -109,7 +109,7 @@
 	  V.24, V.35 or V.36 interface) to your Linux box.
 
 	  - LMC 1200 with on board DSU board allows you to connect your Linux
-	  box dirrectly to a T1 or E1 circuit.
+	  box directly to a T1 or E1 circuit.
 
 	  - LMC 5200 board provides a HSSI interface capable of running up to
 	  52 Mbits per second.
@@ -459,7 +459,7 @@
 	depends on VENDOR_SANGOMA
 	help
 	  Connect a WANPIPE card to a Frame Relay network, or use Frame Felay
-	  API to develope custom applications.
+	  API to develop custom applications.
 
 	  Contains the Ethernet Bridging over Frame Relay feature, where
 	  a WANPIPE frame relay link can be directly connected to the Linux
diff -Nru a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
--- a/drivers/net/wireless/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/wireless/Kconfig	2005-01-19 13:44:46 -08:00
@@ -235,7 +235,7 @@
         one of these, you will need to provide a firmware image
         to be loaded into the card by the driver. The Atmel
         firmware package can be downloaded from
-        http://www.thekelleys.org.uk/atmel
+        <http://www.thekelleys.org.uk/atmel>
 
 config PCI_ATMEL
       tristate "Atmel at76c506 PCI cards"
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/net/wireless/airo.c	2005-01-19 13:44:46 -08:00
@@ -33,7 +33,6 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
-#include <linux/suspend.h>
 #include <linux/in.h>
 #include <linux/bitops.h>
 #include <asm/io.h>
@@ -2918,8 +2917,7 @@
 			flush_signals(current);
 
 		/* make swsusp happy with our thread */
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 
 		if (test_bit(JOB_DIE, &ai->flags))
 			break;
diff -Nru a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
--- a/drivers/net/wireless/airo_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/wireless/airo_cs.c	2005-01-19 13:44:47 -08:00
@@ -61,22 +61,12 @@
 
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
-
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
 MODULE_AUTHOR("Benjamin Reed");
 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
                    cards.  This is the module that links the PCMCIA card \
 		   with the airo module.");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
 
 /*====================================================================*/
 
@@ -178,7 +168,7 @@
 	client_reg_t client_reg;
 	dev_link_t *link;
 	local_info_t *local;
-	int ret, i;
+	int ret;
 	
 	DEBUG(0, "airo_attach()\n");
 
@@ -192,12 +182,7 @@
 	
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = NULL;
 	
 	/*
diff -Nru a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
--- a/drivers/net/wireless/atmel_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/wireless/atmel_cs.c	2005-01-19 13:44:46 -08:00
@@ -74,20 +74,10 @@
 
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
-
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
 MODULE_AUTHOR("Simon Kelley");
 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
 
 /*====================================================================*/
 
@@ -190,7 +180,7 @@
 	client_reg_t client_reg;
 	dev_link_t *link;
 	local_info_t *local;
-	int ret, i;
+	int ret;
 	
 	DEBUG(0, "atmel_attach()\n");
 
@@ -204,12 +194,7 @@
 	
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = NULL;
 	
 	/*
diff -Nru a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
--- a/drivers/net/wireless/netwave_cs.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/wireless/netwave_cs.c	2005-01-19 13:44:48 -08:00
@@ -190,16 +190,9 @@
  */
 static int mem_speed;
 
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
 module_param(domain, int, 0);
 module_param(scramble_key, int, 0);
 module_param(mem_speed, int, 0);
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
 
 /*====================================================================*/
 
@@ -438,7 +431,7 @@
     dev_link_t *link;
     struct net_device *dev;
     netwave_private *priv;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "netwave_attach()\n");
     
@@ -459,12 +452,7 @@
     
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &netwave_interrupt;
     
     /* General socket configuration */
diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/net/wireless/orinoco.c	2005-01-19 13:44:48 -08:00
@@ -617,9 +617,8 @@
 	unsigned long flags;
 	int err;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = __orinoco_up(dev);
 
@@ -671,10 +670,9 @@
 		return NULL; /* FIXME: Can we do better than this? */
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return NULL; /* FIXME: Erg, we've been signalled, how
-			      * do we propagate this back up? */
+	if (orinoco_lock(priv, &flags) != 0)
+		return NULL;  /* FIXME: Erg, we've been signalled, how
+			       * do we propagate this back up? */
 
 	if (priv->iw_mode == IW_MODE_ADHOC) {
 		memset(&wstats->qual, 0, sizeof(wstats->qual));
@@ -1819,10 +1817,8 @@
 		return 0;
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
-
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 		
 	err = hermes_disable_port(hw, 0);
 	if (err) {
@@ -1864,11 +1860,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct hermes *hw = &priv->hw;
-	int err;
+	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
+	if (orinoco_lock(priv, &flags) != 0)
 		/* When the hardware becomes available again, whatever
 		 * detects that is responsible for re-initializing
 		 * it. So no need for anything further */
@@ -2411,9 +2406,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
 			      ETH_ALEN, NULL, buf);
@@ -2433,9 +2427,8 @@
 	int len;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (strlen(priv->desired_essid) > 0) {
 		/* We read the desired SSID from the hardware rather
@@ -2486,9 +2479,8 @@
 	long freq = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
 	if (err)
@@ -2528,9 +2520,8 @@
 	int i;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
 			      sizeof(list), NULL, &list);
@@ -2568,9 +2559,8 @@
 
 	rrq->length = sizeof(range);
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	mode = priv->iw_mode;
 	orinoco_unlock(priv, &flags);
@@ -2639,9 +2629,8 @@
 	range.min_frag = 256;
 	range.max_frag = 2346;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	if (priv->has_wep) {
 		range.max_encoding_tokens = ORINOCO_MAX_KEYS;
 
@@ -2706,10 +2695,9 @@
 		if (copy_from_user(keybuf, erq->pointer, erq->length))
 			return -EFAULT;
 	}
-	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	if (erq->pointer) {
 		if (erq->length > ORINOCO_MAX_KEY_SIZE) {
@@ -2788,12 +2776,10 @@
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
 	u16 xlen = 0;
 	char keybuf[ORINOCO_MAX_KEY_SIZE];
-	int err;
 	unsigned long flags;
-	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
 		index = priv->tx_key;
@@ -2833,7 +2819,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char essidbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
 	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
@@ -2851,9 +2836,8 @@
 		essidbuf[erq->length] = '\0';
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
 
@@ -2877,9 +2861,8 @@
 		if (err)
 			return err;
 	} else {
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
 		orinoco_unlock(priv, &flags);
 	}
@@ -2899,7 +2882,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char nickbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
 	if (nrq->length > IW_ESSID_MAX_SIZE)
@@ -2912,9 +2894,8 @@
 
 	nickbuf[nrq->length] = '\0';
 	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(priv->nick, nickbuf, sizeof(priv->nick));
 
@@ -2927,12 +2908,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char nickbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
 	orinoco_unlock(priv, &flags);
@@ -2949,7 +2928,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int chan = -1;
-	int err;
 	unsigned long flags;
 
 	/* We can only use this in Ad-Hoc demo mode to set the operating
@@ -2978,9 +2956,8 @@
 	     ! (priv->channel_mask & (1 << (chan-1)) ) )
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->channel = chan;
 	orinoco_unlock(priv, &flags);
 
@@ -2998,9 +2975,8 @@
 	if (!priv->has_sensitivity)
 		return -EOPNOTSUPP;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	err = hermes_read_wordrec(hw, USER_BAP,
 				  HERMES_RID_CNFSYSTEMSCALE, &val);
 	orinoco_unlock(priv, &flags);
@@ -3018,7 +2994,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = srq->value;
-	int err;
 	unsigned long flags;
 
 	if (!priv->has_sensitivity)
@@ -3027,9 +3002,8 @@
 	if ((val < 1) || (val > 3))
 		return -EINVAL;
 	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->ap_density = val;
 	orinoco_unlock(priv, &flags);
 
@@ -3040,7 +3014,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = rrq->value;
-	int err;
 	unsigned long flags;
 
 	if (rrq->disabled)
@@ -3049,9 +3022,8 @@
 	if ( (val < 0) || (val > 2347) )
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	priv->rts_thresh = val;
 	orinoco_unlock(priv, &flags);
@@ -3065,9 +3037,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (priv->has_mwo) {
 		if (frq->disabled)
@@ -3102,9 +3073,8 @@
 	u16 val;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	if (priv->has_mwo) {
 		err = hermes_read_wordrec(hw, USER_BAP,
@@ -3166,9 +3136,8 @@
 	if (ratemode == -1)
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->bitratemode = ratemode;
 	orinoco_unlock(priv, &flags);
 
@@ -3185,9 +3154,8 @@
 	u16 val;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	ratemode = priv->bitratemode;
 
@@ -3247,9 +3215,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (prq->disabled) {
 		priv->pm_on = 0;
@@ -3302,9 +3269,8 @@
 	u16 enable, period, timeout, mcast;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
 	if (err)
@@ -3351,9 +3317,8 @@
 	u16 short_limit, long_limit, lifetime;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
 				  &short_limit);
@@ -3399,12 +3364,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = *( (int *) wrq->u.name );
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	priv->ibss_port = val ;
 
@@ -3419,12 +3382,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int *val = (int *)wrq->u.name;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	*val = priv->ibss_port;
 	orinoco_unlock(priv, &flags);
@@ -3439,9 +3400,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	switch (val) {
 	case 0: /* Try to do IEEE ad-hoc mode */
@@ -3478,12 +3438,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int *val = (int *)wrq->u.name;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	*val = priv->prefer_port3;
 	orinoco_unlock(priv, &flags);
@@ -3513,9 +3471,8 @@
 	}
 
 	/* Make sure nobody mess with the structure while we do */
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	/* orinoco_lock() doesn't disable interrupts, so make sure the
 	 * interrupt rx path don't get confused while we copy */
@@ -3546,12 +3503,10 @@
 	struct iw_quality spy_stat[IW_MAX_SPY];
 	int number;
 	int i;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	number = priv->spy_number;
 	if ((number > 0) && (srq->pointer)) {
@@ -3621,9 +3576,8 @@
 		break;
 
 	case SIOCSIWMODE:
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		switch (wrq->u.mode) {
 		case IW_MODE_ADHOC:
 			if (! (priv->has_ibss || priv->has_port3) )
@@ -3648,9 +3602,8 @@
 		break;
 
 	case SIOCGIWMODE:
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		wrq->u.mode = priv->iw_mode;
 		orinoco_unlock(priv, &flags);
 		break;
@@ -3865,9 +3818,8 @@
 		if(priv->has_preamble) {
 			int val = *( (int *) wrq->u.name );
 
-			err = orinoco_lock(priv, &flags);
-			if (err)
-				return err;
+			if (orinoco_lock(priv, &flags) != 0)
+				return -EBUSY;
 			if (val)
 				priv->preamble = 1;
 			else
@@ -3882,9 +3834,8 @@
 		if(priv->has_preamble) {
 			int *val = (int *)wrq->u.name;
 
-			err = orinoco_lock(priv, &flags);
-			if (err)
-				return err;
+			if (orinoco_lock(priv, &flags) != 0)
+				return -EBUSY;
 			*val = priv->preamble;
 			orinoco_unlock(priv, &flags);
 		} else
diff -Nru a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
--- a/drivers/net/wireless/orinoco_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/wireless/orinoco_cs.c	2005-01-19 13:44:47 -08:00
@@ -54,18 +54,10 @@
 
 /* Module parameters */
 
-/* The old way: bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static uint irq_mask = 0xdeb8;
-/* Newer, simpler way of listing specific interrupts */
-static int irq_list[4] = { -1 };
-
 /* Some D-Link cards have buggy CIS. They do work at 5v properly, but
  * don't have any CIS entry for it. This workaround it... */
 static int ignore_cis_vcc; /* = 0 */
 
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
 module_param(ignore_cis_vcc, int, 0);
 
 /********************************************************************/
@@ -161,7 +153,7 @@
 	struct orinoco_pccard *card;
 	dev_link_t *link;
 	client_reg_t client_reg;
-	int ret, i;
+	int ret;
 
 	dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
 	if (! dev)
@@ -175,12 +167,7 @@
 
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = NULL;
 
 	/* General socket configuration defaults can go here.  In this
@@ -415,16 +402,8 @@
 	 * the irq structure is initialized.
 	 */
 	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-		int i;
-
 		link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-		link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-		if (irq_list[0] == -1)
-			link->irq.IRQInfo2 = irq_mask;
-		else
-			for (i=0; i<4; i++)
-				link->irq.IRQInfo2 |= 1 << irq_list[i];
-		
+		link->irq.IRQInfo1 = IRQ_LEVEL_ID;
   		link->irq.Handler = orinoco_interrupt; 
   		link->irq.Instance = dev; 
 		
diff -Nru a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
--- a/drivers/net/wireless/ray_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/net/wireless/ray_cs.c	2005-01-19 13:44:46 -08:00
@@ -157,9 +157,6 @@
 
 /*===========================================================================*/
 /* Parameters that can be set with 'insmod' */
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static u_long irq_mask = 0xdeb8;
 
 /* ADHOC=0, Infrastructure=1 */
 static int net_type = ADHOC;
@@ -222,7 +219,6 @@
 MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
 MODULE_LICENSE("GPL");
 
-module_param(irq_mask, ulong, 0);
 module_param(net_type, int, 0);
 module_param(hop_dwell, int, 0);
 module_param(beacon_period, int, 0);
@@ -354,8 +350,7 @@
 
     /* Interrupt setup. For PCMCIA, driver takes what's given */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-    link->irq.IRQInfo2 = irq_mask;
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &ray_interrupt;
 
     /* General socket configuration */
diff -Nru a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
--- a/drivers/net/wireless/wavelan_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/wireless/wavelan_cs.c	2005-01-19 13:44:47 -08:00
@@ -4601,7 +4601,7 @@
   dev_link_t *	link;		/* Info for cardmgr */
   struct net_device *	dev;		/* Interface generic data */
   net_local *	lp;		/* Interface specific data */
-  int		i, ret;
+  int		ret;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_attach()\n");
@@ -4619,12 +4619,7 @@
 
   /* Interrupt setup */
   link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-  link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-  if (irq_list[0] == -1)
-    link->irq.IRQInfo2 = irq_mask;
-  else
-    for (i = 0; i < 4; i++)
-      link->irq.IRQInfo2 |= 1 << irq_list[i];
+  link->irq.IRQInfo1 = IRQ_LEVEL_ID;
   link->irq.Handler = wavelan_interrupt;
 
   /* General socket configuration */
diff -Nru a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
--- a/drivers/net/wireless/wavelan_cs.p.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/net/wireless/wavelan_cs.p.h	2005-01-19 13:44:47 -08:00
@@ -795,17 +795,10 @@
  * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
  */
 
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4 and 3 */
-static int	irq_mask = 0xdeb8;
-static int 	irq_list[4] = { -1 };
-
 /* Shared memory speed, in ns */
 static int	mem_speed = 0;
 
 /* New module interface */
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
 module_param(mem_speed, int, 0);
 
 #ifdef WAVELAN_ROAMING		/* Conditional compile, see above in options */
diff -Nru a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
--- a/drivers/net/wireless/wl3501_cs.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/net/wireless/wl3501_cs.c	2005-01-19 13:44:45 -08:00
@@ -97,12 +97,6 @@
 #define WL3501_RESUME	0
 #define WL3501_SUSPEND	1
 
-/* Parameters that can be set with 'insmod' */
-/* Bit map of interrupts to choose from */
-/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static unsigned long wl3501_irq_mask = 0xdeb8;
-static int wl3501_irq_list[4] = { -1 };
-
 /*
  * The event() function is this driver's Card Services event handler.  It will
  * be called by Card Services when an appropriate card status event is
@@ -1967,7 +1961,7 @@
 	client_reg_t client_reg;
 	dev_link_t *link;
 	struct net_device *dev;
-	int ret, i;
+	int ret;
 
 	/* Initialize the dev_link_t structure */
 	link = kmalloc(sizeof(*link), GFP_KERNEL);
@@ -1982,11 +1976,7 @@
 
 	/* Interrupt setup */
 	link->irq.Attributes	= IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1	= IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	link->irq.IRQInfo2	= wl3501_irq_mask;
-	if (wl3501_irq_list[0] != -1)
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << wl3501_irq_list[i];
+	link->irq.IRQInfo1	= IRQ_LEVEL_ID;
 	link->irq.Handler = wl3501_interrupt;
 
 	/* General socket configuration */
@@ -2273,8 +2263,6 @@
 module_init(wl3501_init_module);
 module_exit(wl3501_exit_module);
 
-module_param(wl3501_irq_mask, int, 0);
-module_param_array(wl3501_irq_list, int, NULL, 0);
 MODULE_AUTHOR("Fox Chen <mhchen@golf.ccl.itri.org.tw>, "
 	      "Arnaldo Carvalho de Melo <acme@conectiva.com.br>,"
 	      "Gustavo Niemeyer <niemeyer@conectiva.com>");
diff -Nru a/drivers/parisc/Makefile b/drivers/parisc/Makefile
--- a/drivers/parisc/Makefile	2005-01-19 13:44:46 -08:00
+++ b/drivers/parisc/Makefile	2005-01-19 13:44:46 -08:00
@@ -2,11 +2,6 @@
 # Makefile for most of the non-PCI devices in PA-RISC machines
 #
 
-obj-y :=
-obj-m :=
-obj-n :=
-obj-  :=
-
 # I/O SAPIC is also on IA64 platforms.
 # The two could be merged into a common source some day.
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
@@ -17,7 +12,7 @@
 # obj-$(CONFIG_IOMMU_CCIO)	+= ccio-rm-dma.o
 obj-$(CONFIG_IOMMU_CCIO)	+= ccio-dma.o
 
-obj-y				+= gsc.o
+obj-$(CONFIG_GSC)		+= gsc.o
 
 obj-$(CONFIG_HPPB)		+= hppb.o
 obj-$(CONFIG_GSC_DINO)		+= dino.o
diff -Nru a/drivers/parisc/asp.c b/drivers/parisc/asp.c
--- a/drivers/parisc/asp.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/parisc/asp.c	2005-01-19 13:44:48 -08:00
@@ -13,7 +13,7 @@
 
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -30,25 +30,27 @@
 
 #define VIPER_INT_WORD  0xFFFBF088      /* addr of viper interrupt word */
 
-static int asp_choose_irq(struct parisc_device *dev)
+static void asp_choose_irq(struct parisc_device *dev, void *ctrl)
 {
-	int irq = -1;
+	int irq;
 
 	switch (dev->id.sversion) {
-	case 0x71:	irq = 22; break; /* SCSI */
-	case 0x72:	irq = 23; break; /* LAN */
-	case 0x73:	irq = 30; break; /* HIL */
-	case 0x74:	irq = 24; break; /* Centronics */
-	case 0x75:	irq = (dev->hw_path == 4) ? 26 : 25; break; /* RS232 */
-	case 0x76:	irq = 21; break; /* EISA BA */
-	case 0x77:	irq = 20; break; /* Graphics1 */
-	case 0x7a:	irq = 18; break; /* Audio (Bushmaster) */
-	case 0x7b:	irq = 18; break; /* Audio (Scorpio) */
-	case 0x7c:	irq = 28; break; /* FW SCSI */
-	case 0x7d:	irq = 27; break; /* FDDI */
-	case 0x7f:	irq = 18; break; /* Audio (Outfield) */
+	case 0x71:	irq =  9; break; /* SCSI */
+	case 0x72:	irq =  8; break; /* LAN */
+	case 0x73:	irq =  1; break; /* HIL */
+	case 0x74:	irq =  7; break; /* Centronics */
+	case 0x75:	irq = (dev->hw_path == 4) ? 5 : 6; break; /* RS232 */
+	case 0x76:	irq = 10; break; /* EISA BA */
+	case 0x77:	irq = 11; break; /* Graphics1 */
+	case 0x7a:	irq = 13; break; /* Audio (Bushmaster) */
+	case 0x7b:	irq = 13; break; /* Audio (Scorpio) */
+	case 0x7c:	irq =  3; break; /* FW SCSI */
+	case 0x7d:	irq =  4; break; /* FDDI */
+	case 0x7f:	irq = 13; break; /* Audio (Outfield) */
+	default:	return;		 /* Unknown */
 	}
-	return irq;
+
+	gsc_asic_assign_irq(ctrl, irq, &dev->irq);
 }
 
 /* There are two register ranges we're interested in.  Interrupt /
@@ -62,11 +64,11 @@
 int __init
 asp_init_chip(struct parisc_device *dev)
 {
-	struct busdevice *asp;
+	struct gsc_asic *asp;
 	struct gsc_irq gsc_irq;
-	int irq, ret;
+	int ret;
 
-	asp = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	asp = kmalloc(sizeof(*asp), GFP_KERNEL);
 	if(!asp)
 		return -ENOMEM;
 
@@ -79,37 +81,34 @@
 
 	/* the IRQ ASP should use */
 	ret = -EBUSY;
-	irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ);
-	if (irq < 0) {
+	dev->irq = gsc_claim_irq(&gsc_irq, ASP_GSC_IRQ);
+	if (dev->irq < 0) {
 		printk(KERN_ERR "%s(): cannot get GSC irq\n", __FUNCTION__);
 		goto out;
 	}
 
-	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "asp", asp);
+	asp->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "asp", asp);
 	if (ret < 0)
 		goto out;
 
-	/* Save this for debugging later */
-	asp->parent_irq = gsc_irq.irq;
-	asp->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
-
 	/* Program VIPER to interrupt on the ASP irq */
 	gsc_writel((1 << (31 - ASP_GSC_IRQ)),VIPER_INT_WORD);
 
 	/* Done init'ing, register this driver */
-	ret = gsc_common_irqsetup(dev, asp);
+	ret = gsc_common_setup(dev, asp);
 	if (ret)
 		goto out;
 
-	fixup_child_irqs(dev, asp->busdev_region->data.irqbase, asp_choose_irq);
+	gsc_fixup_irqs(dev, asp, asp_choose_irq);
 	/* Mongoose is a sibling of Asp, not a child... */
-	fixup_child_irqs(dev->parent, asp->busdev_region->data.irqbase,
-			asp_choose_irq);
+	gsc_fixup_irqs(parisc_parent(dev), asp, asp_choose_irq);
 
 	/* initialize the chassis LEDs */ 
 #ifdef CONFIG_CHASSIS_LCD_LED	
 	register_led_driver(DISPLAY_MODEL_OLD_ASP, LED_CMD_REG_NONE, 
-		    (char *)ASP_LED_ADDR);
+		    ASP_LED_ADDR);
 #endif
 
 	return 0;
diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
--- a/drivers/parisc/ccio-dma.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/parisc/ccio-dma.c	2005-01-19 13:44:46 -08:00
@@ -1198,9 +1198,10 @@
  * to/from certain pages.  To avoid this happening, we mark these pages
  * as `used', and ensure that nothing will try to allocate from them.
  */
-void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp)
+void ccio_cujo20_fixup(struct parisc_device *cujo, u32 iovp)
 {
 	unsigned int idx;
+	struct parisc_device *dev = parisc_parent(cujo);
 	struct ioc *ioc = ccio_get_iommu(dev);
 	u8 *res_ptr;
 
@@ -1556,9 +1557,12 @@
 		create_proc_read_entry(MODULE_NAME"-bitmap", S_IRWXU,
 				       proc_runway_root, ccio_resource_map, NULL);
 	}
+
+	ioc_count++;
+
 	parisc_vmerge_boundary = IOVP_SIZE;
 	parisc_vmerge_max_size = BITS_PER_LONG * IOVP_SIZE;
-	ioc_count++;
+	parisc_has_iommu();
 	return 0;
 }
 
diff -Nru a/drivers/parisc/dino.c b/drivers/parisc/dino.c
--- a/drivers/parisc/dino.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/parisc/dino.c	2005-01-19 13:44:45 -08:00
@@ -57,7 +57,6 @@
 #include <asm/page.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/hardware.h>
 
 #include "gsc.h"
@@ -146,12 +145,10 @@
 	spinlock_t		dinosaur_pen;
 	unsigned long		txn_addr; /* EIR addr to generate interrupt */ 
 	u32			txn_data; /* EIR data assign to each dino */ 
-	int			irq;      /* Virtual IRQ dino uses */
-	struct irq_region	*dino_region;  /* region for this Dino */
-
-	u32 			imr; /* IRQ's which are enabled */ 
+	u32 			imr;	  /* IRQ's which are enabled */ 
+	int			global_irq[12]; /* map IMR bit to global irq */
 #ifdef DINO_DEBUG
-	unsigned int		dino_irr0; /* save most recent IRQ line stat */ 
+	unsigned int		dino_irr0; /* save most recent IRQ line stat */
 #endif
 };
 
@@ -178,22 +175,21 @@
 	struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
-	unsigned long base_addr = d->hba.base_addr;
+	void __iomem *base_addr = d->hba.base_addr;
 	unsigned long flags;
 
 	spin_lock_irqsave(&d->dinosaur_pen, flags);
 
 	/* tell HW which CFG address */
-	gsc_writel(v, base_addr + DINO_PCI_ADDR);
+	__raw_writel(v, base_addr + DINO_PCI_ADDR);
 
 	/* generate cfg read cycle */
 	if (size == 1) {
-		*val = gsc_readb(base_addr + DINO_CONFIG_DATA + (where & 3));
+		*val = readb(base_addr + DINO_CONFIG_DATA + (where & 3));
 	} else if (size == 2) {
-		*val = le16_to_cpu(gsc_readw(base_addr +
-					DINO_CONFIG_DATA + (where & 2)));
+		*val = readw(base_addr + DINO_CONFIG_DATA + (where & 2));
 	} else if (size == 4) {
-		*val = le32_to_cpu(gsc_readl(base_addr + DINO_CONFIG_DATA));
+		*val = readl(base_addr + DINO_CONFIG_DATA);
 	}
 
 	spin_unlock_irqrestore(&d->dinosaur_pen, flags);
@@ -212,25 +208,24 @@
 	struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->bridge));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
-	unsigned long base_addr = d->hba.base_addr;
+	void __iomem *base_addr = d->hba.base_addr;
 	unsigned long flags;
 
 	spin_lock_irqsave(&d->dinosaur_pen, flags);
 
 	/* avoid address stepping feature */
-	gsc_writel(v & 0xffffff00, base_addr + DINO_PCI_ADDR);
-	gsc_readl(base_addr + DINO_CONFIG_DATA);
+	__raw_writel(v & 0xffffff00, base_addr + DINO_PCI_ADDR);
+	__raw_readl(base_addr + DINO_CONFIG_DATA);
 
 	/* tell HW which CFG address */
-	gsc_writel(v, base_addr + DINO_PCI_ADDR);
+	__raw_writel(v, base_addr + DINO_PCI_ADDR);
 	/* generate cfg read cycle */
 	if (size == 1) {
-		gsc_writeb(val, base_addr + DINO_CONFIG_DATA + (where & 3));
+		writeb(val, base_addr + DINO_CONFIG_DATA + (where & 3));
 	} else if (size == 2) {
-		gsc_writew(cpu_to_le16(val),
-				base_addr + DINO_CONFIG_DATA + (where & 2));
+		writew(val, base_addr + DINO_CONFIG_DATA + (where & 2));
 	} else if (size == 4) {
-		gsc_writel(cpu_to_le32(val), base_addr + DINO_CONFIG_DATA);
+		writel(val, base_addr + DINO_CONFIG_DATA);
 	}
 
 	spin_unlock_irqrestore(&d->dinosaur_pen, flags);
@@ -252,9 +247,6 @@
  * I/O port instead of MMIO.
  */
 
-#define cpu_to_le8(x) (x)
-#define le8_to_cpu(x) (x)
-
 #define DINO_PORT_IN(type, size, mask) \
 static u##size dino_in##size (struct pci_hba_data *d, u16 addr) \
 { \
@@ -262,11 +254,11 @@
 	unsigned long flags; \
 	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
 	/* tell HW which IO Port address */ \
-	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
+	__raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
 	/* generate I/O PORT read cycle */ \
-	v = gsc_read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
+	v = read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
 	spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
-	return le##size##_to_cpu(v); \
+	return v; \
 }
 
 DINO_PORT_IN(b,  8, 3)
@@ -279,9 +271,9 @@
 	unsigned long flags; \
 	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
 	/* tell HW which IO port address */ \
-	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
+	__raw_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
 	/* generate cfg write cycle */ \
-	gsc_write##type(cpu_to_le##size(val), d->base_addr+DINO_IO_DATA+(addr&mask)); \
+	write##type(val, d->base_addr+DINO_IO_DATA+(addr&mask)); \
 	spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
 }
 
@@ -298,45 +290,37 @@
 	.outl	= dino_out32
 };
 
-static void
-dino_mask_irq(void *irq_dev, int irq)
+static void dino_disable_irq(unsigned int irq)
 {
-	struct dino_device *dino_dev = DINO_DEV(irq_dev);
+	struct dino_device *dino_dev = irq_desc[irq].handler_data;
+	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
 
 	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
 
-	if (NULL == irq_dev || irq > DINO_IRQS || irq < 0) {
-		printk(KERN_WARNING "%s(0x%lx, %d) - not a dino irq?\n",
-			__FUNCTION__, (long) irq_dev, irq);
-		BUG();
-	} else {
-		/*
-		** Clear the matching bit in the IMR register
-		*/
-		dino_dev->imr &= ~(DINO_MASK_IRQ(irq));
-		gsc_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
-	}
+	/* Clear the matching bit in the IMR register */
+	dino_dev->imr &= ~(DINO_MASK_IRQ(local_irq));
+	__raw_writel(dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
 }
 
-
-static void
-dino_unmask_irq(void *irq_dev, int irq)
+static void dino_enable_irq(unsigned int irq)
 {
-	struct dino_device *dino_dev = DINO_DEV(irq_dev);
+	struct dino_device *dino_dev = irq_desc[irq].handler_data;
+	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
 	u32 tmp;
 
 	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, irq_dev, irq);
 
-	if (NULL == irq_dev || irq > DINO_IRQS) {
-		printk(KERN_WARNING "%s(): %d not a dino irq?\n",
-				__FUNCTION__, irq);
-		BUG();
-		return;
-	}
+	/*
+	** clear pending IRQ bits
+	**
+	** This does NOT change ILR state!
+	** See comment below for ILR usage.
+	*/
+	__raw_readl(dino_dev->hba.base_addr+DINO_IPR);
 
 	/* set the matching bit in the IMR register */
-	dino_dev->imr |= DINO_MASK_IRQ(irq);          /* used in dino_isr() */
-	gsc_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
+	dino_dev->imr |= DINO_MASK_IRQ(local_irq);	/* used in dino_isr() */
+	__raw_writel( dino_dev->imr, dino_dev->hba.base_addr+DINO_IMR);
 
 	/* Emulate "Level Triggered" Interrupt
 	** Basically, a driver is blowing it if the IRQ line is asserted
@@ -347,38 +331,28 @@
 	** dino_isr() will read IPR and find nothing. But then catch this
 	** when it also checks ILR.
 	*/
-	tmp = gsc_readl(dino_dev->hba.base_addr+DINO_ILR);
-	if (tmp & DINO_MASK_IRQ(irq)) {
+	tmp = __raw_readl(dino_dev->hba.base_addr+DINO_ILR);
+	if (tmp & DINO_MASK_IRQ(local_irq)) {
 		DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n",
 				__FUNCTION__, tmp);
 		gsc_writel(dino_dev->txn_data, dino_dev->txn_addr);
 	}
 }
 
-
-
-static void
-dino_enable_irq(void *irq_dev, int irq)
+static unsigned int dino_startup_irq(unsigned int irq)
 {
-	struct dino_device *dino_dev = DINO_DEV(irq_dev);
-
-	/*
-	** clear pending IRQ bits
-	**
-	** This does NOT change ILR state!
-	** See comments in dino_unmask_irq() for ILR usage.
-	*/
-	gsc_readl(dino_dev->hba.base_addr+DINO_IPR);
-
-	dino_unmask_irq(irq_dev, irq);
+	dino_enable_irq(irq);
+	return 0;
 }
 
-
-static struct irq_region_ops dino_irq_ops = {
-	.disable_irq	= dino_mask_irq,	/* ??? */
-	.enable_irq	= dino_enable_irq, 
-	.mask_irq	= dino_mask_irq,
-	.unmask_irq	= dino_unmask_irq
+static struct hw_interrupt_type dino_interrupt_type = {
+	.typename	= "GSC-PCI",
+	.startup	= dino_startup_irq,
+	.shutdown	= dino_disable_irq,
+	.enable		= dino_enable_irq, 
+	.disable	= dino_disable_irq,
+	.ack		= no_ack_irq,
+	.end		= no_end_irq,
 };
 
 
@@ -391,34 +365,28 @@
 static irqreturn_t
 dino_isr(int irq, void *intr_dev, struct pt_regs *regs)
 {
-	struct dino_device *dino_dev = DINO_DEV(intr_dev);
+	struct dino_device *dino_dev = intr_dev;
 	u32 mask;
 	int ilr_loop = 100;
-	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
-
 
 	/* read and acknowledge pending interrupts */
 #ifdef DINO_DEBUG
 	dino_dev->dino_irr0 =
 #endif
-	mask = gsc_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK;
-
-ilr_again:
-	while (mask)
-	{
-		int irq;
-
-		irq = __ffs(mask);
+	mask = __raw_readl(dino_dev->hba.base_addr+DINO_IRR0) & DINO_IRR_MASK;
 
-		mask &= ~(1<<irq);
+	if (mask == 0)
+		return IRQ_NONE;
 
-		DBG(KERN_WARNING "%s(%x, %p) mask %0x\n",
+ilr_again:
+	do {
+		int local_irq = __ffs(mask);
+		int irq = dino_dev->global_irq[local_irq];
+		DBG(KERN_DEBUG "%s(%d, %p) mask 0x%x\n",
 			__FUNCTION__, irq, intr_dev, mask);
-		do_irq(&dino_dev->dino_region->action[irq],
-			dino_dev->dino_region->data.irqbase + irq,
-			regs);
-
-	}
+		__do_IRQ(irq, regs);
+		mask &= ~(1 << local_irq);
+	} while (mask);
 
 	/* Support for level triggered IRQ lines.
 	** 
@@ -427,27 +395,40 @@
 	** device drivers may assume lines are level triggered (and not
 	** edge triggered like EISA/ISA can be).
 	*/
-	mask = gsc_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr;
+	mask = __raw_readl(dino_dev->hba.base_addr+DINO_ILR) & dino_dev->imr;
 	if (mask) {
 		if (--ilr_loop > 0)
 			goto ilr_again;
-		printk(KERN_ERR "Dino %lx: stuck interrupt %d\n", dino_dev->hba.base_addr, mask);
+		printk(KERN_ERR "Dino 0x%p: stuck interrupt %d\n", 
+		       dino_dev->hba.base_addr, mask);
 		return IRQ_NONE;
 	}
 	return IRQ_HANDLED;
 }
 
-static int dino_choose_irq(struct parisc_device *dev)
+static void dino_assign_irq(struct dino_device *dino, int local_irq, int *irqp)
 {
-	int irq = -1;
+	int irq = gsc_assign_irq(&dino_interrupt_type, dino);
+	if (irq == NO_IRQ)
+		return;
+
+	*irqp = irq;
+	dino->global_irq[local_irq] = irq;
+}
+
+static void dino_choose_irq(struct parisc_device *dev, void *ctrl)
+{
+	int irq;
+	struct dino_device *dino = ctrl;
 
 	switch (dev->id.sversion) {
 		case 0x00084:	irq =  8; break; /* PS/2 */
 		case 0x0008c:	irq = 10; break; /* RS232 */
 		case 0x00096:	irq =  8; break; /* PS/2 */
+		default:	return;		 /* Unknown */
 	}
 
-	return irq;
+	dino_assign_irq(dino, irq, &dev->irq);
 }
 
 static void __init
@@ -465,7 +446,7 @@
  */
 #define _8MB 0x00800000UL
 static void __init
-dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
+dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
 {
 	int i;
 	struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
@@ -475,7 +456,8 @@
 
 	res = &dino_dev->hba.lmmio_space;
 	res->flags = IORESOURCE_MEM;
-	size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)", bus->bridge->bus_id);
+	size = scnprintf(name, sizeof(name), "Dino LMMIO (%s)", 
+			 bus->bridge->bus_id);
 	res->name = kmalloc(size+1, GFP_KERNEL);
 	if(res->name)
 		strcpy((char *)res->name, name);
@@ -510,7 +492,7 @@
 	}
 	DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %lx\n",
 	    i, res->start, base_addr + DINO_IO_ADDR_EN);
-	gsc_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
+	__raw_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
 }
 
 static void __init
@@ -531,7 +513,8 @@
 	** Set Latency Timer to 0xff (not a shared bus)
 	** Set CACHELINE_SIZE.
 	*/
-	dino_cfg_write(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4); 
+	dino_cfg_write(dev->bus, dev->devfn, 
+		       PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4); 
 
 	/*
 	** Program INT_LINE for card-mode devices.
@@ -563,8 +546,9 @@
         struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
 	int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
 
-	DBG(KERN_WARNING "%s(0x%p) bus %d sysdata 0x%p\n",
-			__FUNCTION__, bus, bus->secondary, bus->bridge->platform_data);
+	DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n",
+	    __FUNCTION__, bus, bus->secondary, 
+	    bus->bridge->platform_data);
 
 	/* Firmware doesn't set up card-mode dino, so we have to */
 	if (is_card_dino(&dino_dev->hba.dev->id)) {
@@ -589,7 +573,8 @@
 
 
 		for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
-			if((bus->self->resource[i].flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+			if((bus->self->resource[i].flags & 
+			    (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
 				continue;
 			
 			if(bus->self->resource[i].flags & IORESOURCE_MEM) {
@@ -664,11 +649,15 @@
 
 			u32 irq_pin;
 			
-			dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin);
-			dev->irq = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
-			dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq);
-			dev->irq += dino_dev->dino_region->data.irqbase;
-			printk(KERN_WARNING "Device %s has undefined IRQ, setting to %d\n", dev->slot_name, irq_pin);
+			dino_cfg_read(dev->bus, dev->devfn, 
+				      PCI_INTERRUPT_PIN, 1, &irq_pin);
+			irq_pin = (irq_pin + PCI_SLOT(dev->devfn) - 1) % 4 ;
+			printk(KERN_WARNING "Device %s has undefined IRQ, "
+					"setting to %d\n", dev->slot_name,
+					irq_pin);
+			dino_cfg_write(dev->bus, dev->devfn, 
+				       PCI_INTERRUPT_LINE, 1, irq_pin);
+			dino_assign_irq(dino_dev, irq_pin, &dev->irq);
 #else
 			dev->irq = 65535;
 			printk(KERN_WARNING "Device %s has unassigned IRQ\n", dev->slot_name);	
@@ -676,7 +665,7 @@
 		} else {
 
 			/* Adjust INT_LINE for that busses region */
-			dev->irq += dino_dev->dino_region->data.irqbase;
+			dino_assign_irq(dino_dev, dev->irq, &dev->irq);
 		}
 	}
 }
@@ -696,9 +685,9 @@
 {
 	u32 brdg_feat = 0x00784e05;
 
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK);
-	gsc_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN);
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_GMASK);
+	__raw_writel(0x00000001, dino_dev->hba.base_addr+DINO_IO_FBB_EN);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_ICR);
 
 #if 1
 /* REVISIT - should be a runtime check (eg if (CPU_IS_PCX_L) ...) */
@@ -708,34 +697,34 @@
 	*/
 	brdg_feat &= ~0x4;	/* UXQL */
 #endif
-	gsc_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT);
+	__raw_writel( brdg_feat, dino_dev->hba.base_addr+DINO_BRDG_FEAT);
 
 	/*
 	** Don't enable address decoding until we know which I/O range
 	** currently is available from the host. Only affects MMIO
 	** and not I/O port space.
 	*/
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_IO_ADDR_EN);
 
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE);
-	gsc_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR);
-	gsc_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR);
-
-	gsc_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM);
-	gsc_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL);
-	gsc_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_DAMODE);
+	__raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIROR);
+	__raw_writel(0x00222222, dino_dev->hba.base_addr+DINO_PCIWOR);
+
+	__raw_writel(0x00000040, dino_dev->hba.base_addr+DINO_MLTIM);
+	__raw_writel(0x00000080, dino_dev->hba.base_addr+DINO_IO_CONTROL);
+	__raw_writel(0x0000008c, dino_dev->hba.base_addr+DINO_TLTIM);
 
 	/* Disable PAMR before writing PAPR */
-	gsc_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR);
-	gsc_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR);
-	gsc_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR);
+	__raw_writel(0x0000007e, dino_dev->hba.base_addr+DINO_PAMR);
+	__raw_writel(0x0000007f, dino_dev->hba.base_addr+DINO_PAPR);
+	__raw_writel(0x00000000, dino_dev->hba.base_addr+DINO_PAMR);
 
 	/*
 	** Dino ERS encourages enabling FBB (0x6f).
 	** We can't until we know *all* devices below us can support it.
 	** (Something in device configuration header tells us).
 	*/
-	gsc_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD);
+	__raw_writel(0x0000004f, dino_dev->hba.base_addr+DINO_PCICMD);
 
 	/* Somewhere, the PCI spec says give devices 1 second
 	** to recover from the #RESET being de-asserted.
@@ -756,7 +745,7 @@
 	 * since PDC has already initialized this.
 	 */
 
-	io_addr = gsc_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN);
+	io_addr = __raw_readl(dino_dev->hba.base_addr + DINO_IO_ADDR_EN);
 	if (io_addr == 0) {
 		printk(KERN_WARNING "%s: No PCI devices enabled.\n", name);
 		return -ENODEV;
@@ -830,7 +819,7 @@
 	**   still only has 11 IRQ input lines - just map some of them
 	**   to a different processor.
 	*/
-	dino_dev->irq = gsc_alloc_irq(&gsc_irq);
+	dev->irq = gsc_alloc_irq(&gsc_irq);
 	dino_dev->txn_addr = gsc_irq.txn_addr;
 	dino_dev->txn_data = gsc_irq.txn_data;
 	eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
@@ -839,49 +828,36 @@
 	** Dino needs a PA "IRQ" to get a processor's attention.
 	** arch/parisc/kernel/irq.c returns an EIRR bit.
 	*/
-	if (dino_dev->irq < 0) {
+	if (dev->irq < 0) {
 		printk(KERN_WARNING "%s: gsc_alloc_irq() failed\n", name);
 		return 1;
 	}
 
-	status = request_irq(dino_dev->irq, dino_isr, 0, name, dino_dev);
+	status = request_irq(dev->irq, dino_isr, 0, name, dino_dev);
 	if (status) {
 		printk(KERN_WARNING "%s: request_irq() failed with %d\n", 
 			name, status);
 		return 1;
 	}
 
-	/*
-	** Tell generic interrupt support we have 11 bits which need
-	** be checked in the interrupt handler.
-	*/
-	dino_dev->dino_region = alloc_irq_region(DINO_IRQS, &dino_irq_ops,
-						name, dino_dev);
-
-	if (NULL == dino_dev->dino_region) {
-		printk(KERN_WARNING "%s: alloc_irq_region() failed\n", name);
-		return 1;
-	}
-
 	/* Support the serial port which is sometimes attached on built-in
 	 * Dino / Cujo chips.
 	 */
 
-	fixup_child_irqs(dev, dino_dev->dino_region->data.irqbase,
-			dino_choose_irq);
+	gsc_fixup_irqs(dev, dino_dev, dino_choose_irq);
 
 	/*
 	** This enables DINO to generate interrupts when it sees
 	** any of its inputs *change*. Just asserting an IRQ
 	** before it's enabled (ie unmasked) isn't good enough.
 	*/
-	gsc_writel(eim, dino_dev->hba.base_addr+DINO_IAR0);
+	__raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0);
 
 	/*
 	** Some platforms don't clear Dino's IRR0 register at boot time.
 	** Reading will clear it now.
 	*/
-	gsc_readl(dino_dev->hba.base_addr+DINO_IRR0);
+	__raw_readl(dino_dev->hba.base_addr+DINO_IRR0);
 
 	/* allocate I/O Port resource region */
 	res = &dino_dev->hba.io_space;
@@ -894,8 +870,9 @@
 	res->end = res->start + (HBA_PORT_SPACE_SIZE - 1);
 	res->flags = IORESOURCE_IO; /* do not mark it busy ! */
 	if (request_resource(&ioport_resource, res) < 0) {
-		printk(KERN_ERR "%s: request I/O Port region failed 0x%lx/%lx (hpa 0x%lx)\n",
-				name, res->start, res->end, dino_dev->hba.base_addr);
+		printk(KERN_ERR "%s: request I/O Port region failed "
+		       "0x%lx/%lx (hpa 0x%p)\n",
+		       name, res->start, res->end, dino_dev->hba.base_addr);
 		return 1;
 	}
 
@@ -931,20 +908,11 @@
 {
 	struct dino_device *dino_dev;	// Dino specific control struct
 	const char *version = "unknown";
-	const int name_len = 32;
-	char hw_path[64];
 	char *name;
 	int is_cujo = 0;
 	struct pci_bus *bus;
 	
-	name = kmalloc(name_len, GFP_KERNEL);
-	if(name) {
-		print_pa_hwpath(dev, hw_path);
-		snprintf(name, name_len, "Dino [%s]", hw_path);
-	} 
-	else
-		name = "Dino";
-
+	name = "Dino";
 	if (is_card_dino(&dev->id)) {
 		version = "3.x (card mode)";
 	} else {
@@ -974,9 +942,9 @@
 #ifdef CONFIG_IOMMU_CCIO
 		printk(KERN_WARNING "Enabling Cujo 2.0 bug workaround\n");
 		if (dev->hpa == (unsigned long)CUJO_RAVEN_ADDR) {
-			ccio_cujo20_fixup(dev->parent, CUJO_RAVEN_BADPAGE);
+			ccio_cujo20_fixup(dev, CUJO_RAVEN_BADPAGE);
 		} else if (dev->hpa == (unsigned long)CUJO_FIREHAWK_ADDR) {
-			ccio_cujo20_fixup(dev->parent, CUJO_FIREHAWK_BADPAGE);
+			ccio_cujo20_fixup(dev, CUJO_FIREHAWK_BADPAGE);
 		} else {
 			printk("Don't recognise Cujo at address 0x%lx, not enabling workaround\n", dev->hpa);
 		}
@@ -1003,9 +971,9 @@
 	memset(dino_dev, 0, sizeof(struct dino_device));
 
 	dino_dev->hba.dev = dev;
-	dino_dev->hba.base_addr = dev->hpa;  /* faster access */
+	dino_dev->hba.base_addr = ioremap(dev->hpa, 4096); /* faster access */
 	dino_dev->hba.lmmio_space_offset = 0;	/* CPU addrs == bus addrs */
-	dino_dev->dinosaur_pen = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&dino_dev->dinosaur_pen);
 	dino_dev->hba.iommu = ccio_get_iommu(dev);
 
 	if (is_card_dino(&dev->id)) {
diff -Nru a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
--- a/drivers/parisc/eisa.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/parisc/eisa.c	2005-01-19 13:44:45 -08:00
@@ -29,7 +29,7 @@
 
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -142,7 +142,7 @@
 
 
 /* called by free irq */
-static void eisa_disable_irq(void *irq_dev, int irq)
+static void eisa_disable_irq(unsigned int irq)
 {
 	unsigned long flags;
 
@@ -162,7 +162,7 @@
 }
 
 /* called by request irq */
-static void eisa_enable_irq(void *irq_dev, int irq)
+static void eisa_enable_irq(unsigned int irq)
 {
 	unsigned long flags;
 	EISA_DBG("enable irq %d\n", irq);
@@ -180,52 +180,24 @@
 	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
 }
 
-static void eisa_mask_irq(void *irq_dev, int irq)
+static unsigned int eisa_startup_irq(unsigned int irq)
 {
-	unsigned long flags;
-	EISA_DBG("mask irq %d\n", irq);
-	
-        /* mask irq */
-	spin_lock_irqsave(&eisa_irq_lock, flags);
-	if (irq & 8) {
-		slave_mask |= (1 << (irq&7));
-		eisa_out8(slave_mask, 0xa1);
-	} else {
-		master_mask |= (1 << (irq&7));
-		eisa_out8(master_mask, 0x21);
-	}
-	spin_unlock_irqrestore(&eisa_irq_lock, flags);
+	eisa_enable_irq(irq);
+	return 0;
 }
 
-static void eisa_unmask_irq(void *irq_dev, int irq)
-{
-	unsigned long flags;
-	EISA_DBG("unmask irq %d\n", irq);
-        
-	/* unmask */
-	spin_lock_irqsave(&eisa_irq_lock, flags);
-	if (irq & 8) {
-		slave_mask &= ~(1 << (irq&7));
-		eisa_out8(slave_mask, 0xa1);
-	} else {
-		master_mask &= ~(1 << (irq&7));
-		eisa_out8(master_mask, 0x21);
-	}
-	spin_unlock_irqrestore(&eisa_irq_lock, flags);
-}
-
-static struct irqaction action[IRQ_PER_REGION];
-
-/* EISA needs to be fixed at IRQ region #0 (EISA_IRQ_REGION) */
-static struct irq_region eisa_irq_region = {
-	.ops	= { eisa_disable_irq, eisa_enable_irq, eisa_mask_irq, eisa_unmask_irq },
-	.data	= { .name = "EISA", .irqbase = 0 },
-	.action	= action,
+static struct hw_interrupt_type eisa_interrupt_type = {
+	.typename =	"EISA",
+	.startup =	eisa_startup_irq,
+	.shutdown =	eisa_disable_irq,
+	.enable =	eisa_enable_irq,
+	.disable =	eisa_disable_irq,
+	.ack =		no_ack_irq,
+	.end =		no_end_irq,
 };
 
-static irqreturn_t eisa_irq(int _, void *intr_dev, struct pt_regs *regs)
+static irqreturn_t eisa_irq(int wax_irq, void *intr_dev, struct pt_regs *regs)
 {
-	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
 	int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */
 	unsigned long flags;
         
@@ -259,8 +231,7 @@
 	}
 	spin_unlock_irqrestore(&eisa_irq_lock, flags);
 
-   
-	do_irq(&eisa_irq_region.action[irq], EISA_IRQ_REGION + irq, regs);
+	__do_IRQ(irq, regs);
    
 	spin_lock_irqsave(&eisa_irq_lock, flags);
 	/* unmask */
@@ -281,6 +252,11 @@
 	return IRQ_HANDLED;
 }
 
+static struct irqaction irq2_action = {
+	.handler = dummy_irq2_handler,
+	.name = "cascade",
+};
+
 static void init_eisa_pic(void)
 {
 	unsigned long flags;
@@ -331,7 +307,7 @@
 
 static int __devinit eisa_probe(struct parisc_device *dev)
 {
-	int result;
+	int i, result;
 
 	char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
 
@@ -361,18 +337,18 @@
 	}
 	pcibios_register_hba(&eisa_dev.hba);
 
-	result = request_irq(dev->irq, eisa_irq, SA_SHIRQ, "EISA", NULL);
+	result = request_irq(dev->irq, eisa_irq, SA_SHIRQ, "EISA", &eisa_dev);
 	if (result) {
 		printk(KERN_ERR "EISA: request_irq failed!\n");
 		return result;
 	}
 	
 	/* Reserve IRQ2 */
-	action[2].handler = dummy_irq2_handler;
-	action[2].name = "cascade";
+	irq_desc[2].action = &irq2_action;
 	
-	eisa_irq_region.data.dev = dev;
-	irq_region[0] = &eisa_irq_region;
+	for (i = 0; i < 16; i++) {
+		irq_desc[i].handler = &eisa_interrupt_type;
+	}
 	
 	EISA_bus = 1;
 	if (dev->num_addrs) {
diff -Nru a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
--- a/drivers/parisc/gsc.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/parisc/gsc.c	2005-01-19 13:44:47 -08:00
@@ -25,15 +25,9 @@
 
 #include <asm/hardware.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 
 #include "gsc.h"
 
-/* This sets the vmerge boundary and size, it's here because it has to
- * be available on all platforms (zero means no-virtual merging) */
-unsigned long parisc_vmerge_boundary = 0;
-unsigned long parisc_vmerge_max_size = 0;
-
 #undef DEBUG
 
 #ifdef DEBUG
@@ -61,7 +55,7 @@
 {
 	int c = irq;
 
-	irq += IRQ_FROM_REGION(CPU_IRQ_REGION); /* virtualize the IRQ first */
+	irq += CPU_IRQ_BASE; /* virtualize the IRQ first */
 
 	irq = txn_claim_irq(irq);
 	if (irq < 0) {
@@ -79,116 +73,146 @@
 EXPORT_SYMBOL(gsc_alloc_irq);
 EXPORT_SYMBOL(gsc_claim_irq);
 
-/* IRQ bits must be numbered from Most Significant Bit */
-#define GSC_FIX_IRQ(x)	(31-(x))
-#define GSC_MASK_IRQ(x)	(1<<(GSC_FIX_IRQ(x)))
-
 /* Common interrupt demultiplexer used by Asp, Lasi & Wax.  */
-irqreturn_t busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs)
+irqreturn_t gsc_asic_intr(int gsc_asic_irq, void *dev, struct pt_regs *regs)
 {
-	unsigned long irq;
-	struct busdevice *busdev = (struct busdevice *) dev;
+	unsigned long irr;
+	struct gsc_asic *gsc_asic = dev;
 
-	/* 
-	    Don't need to protect OFFSET_IRR with spinlock since this is
-	    the only place it's touched.
-	    Protect busdev_region by disabling this region's interrupts,
-	    modifying the region, and then re-enabling the region.
-	*/
-
-	irq = gsc_readl(busdev->hpa+OFFSET_IRR);
-	if (irq == 0) {
-		printk(KERN_ERR "%s: barking without apparent reason.\n", busdev->name);
-	} else {
-		DEBPRINTK ("%s (0x%x) barked, mask=0x%x, irq=%d\n", 
-		    busdev->name, busdev->busdev_region->data.irqbase, 
-		    irq, GSC_FIX_IRQ(ffs(irq))+1 );
+	irr = gsc_readl(gsc_asic->hpa + OFFSET_IRR);
+	if (irr == 0)
+		return IRQ_NONE;
+
+	DEBPRINTK("%s intr, mask=0x%x\n", gsc_asic->name, irr);
+
+	do {
+		int local_irq = __ffs(irr);
+		unsigned int irq = gsc_asic->global_irq[local_irq];
+		__do_IRQ(irq, regs);
+		irr &= ~(1 << local_irq);
+	} while (irr);
 
-		do_irq_mask(irq, busdev->busdev_region, regs);
-	}
 	return IRQ_HANDLED;
 }
 
-static void
-busdev_disable_irq(void *irq_dev, int irq)
+int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit)
 {
-	/* Disable the IRQ line by clearing the bit in the IMR */
-	u32 imr = gsc_readl(BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR);
-	imr &= ~(GSC_MASK_IRQ(irq));
+	int local_irq;
 
-	DEBPRINTK( KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", 
-		    __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr);
+	for (local_irq = 0; local_irq < limit; local_irq++) {
+		if (global_irqs[local_irq] == irq)
+			return local_irq;
+	}
 
-	gsc_writel(imr, BUSDEV_DEV(irq_dev)->hpa+OFFSET_IMR);
+	return NO_IRQ;
 }
 
+static void gsc_asic_disable_irq(unsigned int irq)
+{
+	struct gsc_asic *irq_dev = irq_desc[irq].handler_data;
+	int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
+	u32 imr;
+
+	DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __FUNCTION__, irq,
+			irq_dev->name, imr);
+
+	/* Disable the IRQ line by clearing the bit in the IMR */
+	imr = gsc_readl(irq_dev->hpa + OFFSET_IMR);
+	imr &= ~(1 << local_irq);
+	gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
+}
 
-static void
-busdev_enable_irq(void *irq_dev, int irq)
+static void gsc_asic_enable_irq(unsigned int irq)
 {
+	struct gsc_asic *irq_dev = irq_desc[irq].handler_data;
+	int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
+	u32 imr;
+
+	DEBPRINTK(KERN_DEBUG "%s(%d) %s: IMR 0x%x\n", __FUNCTION__, irq,
+			irq_dev->name, imr);
+
 	/* Enable the IRQ line by setting the bit in the IMR */
-	unsigned long addr = BUSDEV_DEV(irq_dev)->hpa + OFFSET_IMR;
-	u32 imr = gsc_readl(addr);
-	imr |= GSC_MASK_IRQ(irq);
+	imr = gsc_readl(irq_dev->hpa + OFFSET_IMR);
+	imr |= 1 << local_irq;
+	gsc_writel(imr, irq_dev->hpa + OFFSET_IMR);
+	/*
+	 * FIXME: read IPR to make sure the IRQ isn't already pending.
+	 *   If so, we need to read IRR and manually call do_irq().
+	 */
+}
+
+static unsigned int gsc_asic_startup_irq(unsigned int irq)
+{
+	gsc_asic_enable_irq(irq);
+	return 0;
+}
+
+static struct hw_interrupt_type gsc_asic_interrupt_type = {
+	.typename =	"GSC-ASIC",
+	.startup =	gsc_asic_startup_irq,
+	.shutdown =	gsc_asic_disable_irq,
+	.enable =	gsc_asic_enable_irq,
+	.disable =	gsc_asic_disable_irq,
+	.ack =		no_ack_irq,
+	.end =		no_end_irq,
+};
 
-	DEBPRINTK (KERN_WARNING "%s(%p, %d) %s: IMR 0x%x\n", 
-		    __FUNCTION__, irq_dev, irq, BUSDEV_DEV(irq_dev)->name, imr);
+int gsc_assign_irq(struct hw_interrupt_type *type, void *data)
+{
+	static int irq = GSC_IRQ_BASE;
 
-	gsc_writel(imr, addr);
-//	gsc_writel(~0L, addr);
+	if (irq > GSC_IRQ_MAX)
+		return NO_IRQ;
 
-/* FIXME: read IPR to make sure the IRQ isn't already pending.
-**   If so, we need to read IRR and manually call do_irq_mask().
-**   This code should be shared with busdev_unmask_irq().
-*/
+	irq_desc[irq].handler = type;
+	irq_desc[irq].handler_data = data;
+	return irq++;
 }
 
-static void
-busdev_mask_irq(void *irq_dev, int irq)
+void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp)
 {
-/* FIXME: Clear the IMR bit in busdev for that IRQ */
+	int irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic);
+	if (irq == NO_IRQ)
+		return;
+
+	*irqp = irq;
+	asic->global_irq[local_irq] = irq;
 }
 
-static void
-busdev_unmask_irq(void *irq_dev, int irq)
+void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
+			void (*choose_irq)(struct parisc_device *, void *))
 {
-/* FIXME: Read IPR. Set the IMR bit in busdev for that IRQ.
-   call do_irq_mask() if IPR is non-zero
-*/
-}
+	struct device *dev;
 
-struct irq_region_ops busdev_irq_ops = {
-	.disable_irq =	busdev_disable_irq,
-	.enable_irq =	busdev_enable_irq,
-	.mask_irq =	busdev_mask_irq,
-	.unmask_irq =	busdev_unmask_irq
-};
+	list_for_each_entry(dev, &parent->dev.children, node) {
+		struct parisc_device *padev = to_parisc_device(dev);
 
+		/* work-around for 715/64 and others which have parent 
+		   at path [5] and children at path [5/0/x] */
+		if (padev->id.hw_type == HPHW_FAULTY)
+			return gsc_fixup_irqs(padev, ctrl, choose_irq);
+		choose_irq(padev, ctrl);
+	}
+}
 
-int gsc_common_irqsetup(struct parisc_device *parent, struct busdevice *busdev)
+int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
 {
 	struct resource *res;
 
-	busdev->gsc = parent;
-
-	/* the IRQs we simulate */
-	busdev->busdev_region = alloc_irq_region(32, &busdev_irq_ops,
-						 busdev->name, busdev);
-	if (!busdev->busdev_region)
-		return -ENOMEM;
+	gsc_asic->gsc = parent;
 
 	/* allocate resource region */
-	res = request_mem_region(busdev->hpa, 0x100000, busdev->name);
+	res = request_mem_region(gsc_asic->hpa, 0x100000, gsc_asic->name);
 	if (res) {
 		res->flags = IORESOURCE_MEM; 	/* do not mark it busy ! */
 	}
 
 #if 0
-	printk(KERN_WARNING "%s IRQ %d EIM 0x%x", busdev->name,
-			busdev->parent_irq, busdev->eim);
-	if (gsc_readl(busdev->hpa + OFFSET_IMR))
+	printk(KERN_WARNING "%s IRQ %d EIM 0x%x", gsc_asic->name,
+			parent->irq, gsc_asic->eim);
+	if (gsc_readl(gsc_asic->hpa + OFFSET_IMR))
 		printk("  IMR is non-zero! (0x%x)",
-				gsc_readl(busdev->hpa + OFFSET_IMR));
+				gsc_readl(gsc_asic->hpa + OFFSET_IMR));
 	printk("\n");
 #endif
 
diff -Nru a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h
--- a/drivers/parisc/gsc.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/parisc/gsc.h	2005-01-19 13:44:46 -08:00
@@ -25,22 +25,23 @@
 	int irq;		/* virtual IRQ */
 };
 
-struct busdevice {
+struct gsc_asic {
 	struct parisc_device *gsc;
 	unsigned long hpa;
 	char *name;
 	int version;
 	int type;
-	int parent_irq;
 	int eim;
-	struct irq_region *busdev_region;
+	int global_irq[32];
 };
 
-/* short cut to keep the compiler happy */
-#define BUSDEV_DEV(x)	((struct busdevice *) (x))
+int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic);
+int gsc_alloc_irq(struct gsc_irq *dev);			/* dev needs an irq */
+int gsc_claim_irq(struct gsc_irq *dev, int irq);	/* dev needs this irq */
+int gsc_assign_irq(struct hw_interrupt_type *type, void *data);
+int gsc_find_local_irq(unsigned int irq, int *global_irq, int limit);
+void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
+		void (*choose)(struct parisc_device *child, void *ctrl));
+void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp);
 
-int gsc_common_irqsetup(struct parisc_device *parent, struct busdevice *busdev);
-extern int gsc_alloc_irq(struct gsc_irq *dev);	/* dev needs an irq */
-extern int gsc_claim_irq(struct gsc_irq *dev, int irq);	/* dev needs this irq */
-
-irqreturn_t busdev_barked(int busdev_irq, void *dev, struct pt_regs *regs);
+irqreturn_t gsc_asic_intr(int irq, void *dev, struct pt_regs *regs);
diff -Nru a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
--- a/drivers/parisc/iosapic.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/parisc/iosapic.c	2005-01-19 13:44:48 -08:00
@@ -76,35 +76,13 @@
 ** iosapic_register().
 **
 **
-** IRQ region notes
-** ----------------
-** The data passed to iosapic_interrupt() is per IRQ line.
-** Each IRQ line will get one txn_addr/data pair. Thus each IRQ region,
-** will have several txn_addr/data pairs (up to 7 for current I/O SAPIC
-** implementations).  The IRQ region "sysdata" will NOT be directly passed
-** to the interrupt handler like GSCtoPCI (dino.c).
-**
-** iosapic interrupt handler will NOT call do_irq_mask().
-** It doesn't need to read a bit mask to determine which IRQ line was pulled
-** since it already knows based on vector_info passed to iosapic_interrupt().
-**
-** One IRQ number represents both an IRQ line and a driver ISR.
-** The I/O sapic driver can't manage shared IRQ lines because
-** additional data besides the IRQ number must be passed via
-** irq_region_ops. do_irq() and request_irq() must manage
-** a sharing a bit in the mask.
-**
-** iosapic_interrupt() replaces do_irq_mask() and calls do_irq().
-** Which IRQ line was asserted is already known since each
-** line has unique data associated with it. We could omit
-** iosapic_interrupt() from the calling path if it did NOT need
-** to write EOI. For unshared lines, it really doesn't.
-**
-** Unfortunately, can't optimize out EOI if IRQ line isn't "shared".
-** N-class console "device" and some sort of heartbeat actually share
-** one line though only one driver is registered...<sigh>...this was
-** true for HP-UX at least. May not be true for parisc-linux.
-**
+** IRQ handling notes
+** ------------------
+** The IO-SAPIC can indicate to the CPU which interrupt was asserted.
+** So, unlike the GSC-ASIC and Dino, we allocate one CPU interrupt per
+** IO-SAPIC interrupt and call the device driver's handler directly.
+** The IO-SAPIC driver hijacks the CPU interrupt handler so it can
+** issue the End Of Interrupt command to the IO-SAPIC.
 **
 ** Overview of exported iosapic functions
 ** --------------------------------------
@@ -138,11 +116,6 @@
 **   o locate vector_info (needs: isi, intr_line)
 **   o allocate processor "irq" and get txn_addr/data
 **   o request_irq(processor_irq,  iosapic_interrupt, vector_info,...)
-**   o pcidev->irq = isi->isi_region...base + intr_line;
-**
-** iosapic_interrupt:
-**   o call do_irq(vector->isi->irq_region, vector->irq_line, regs)
-**   o assume level triggered and write EOI
 **
 ** iosapic_enable_irq:
 **   o clear any pending IRQ on that line
@@ -151,8 +124,6 @@
 **
 ** iosapic_disable_irq:
 **   o disable IRdT - call disable_irq(vector[line]->processor_irq)
-**
-** FIXME: mask/unmask
 */
 
 
@@ -160,18 +131,15 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
-#include <linux/pci.h>		/* pci cfg accessor functions  */
+#include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>	/* irqaction */
-#include <linux/irq.h>		/* irq_region support */
+#include <linux/interrupt.h>
 
 #include <asm/byteorder.h>	/* get in-line asm for swab */
 #include <asm/pdc.h>
 #include <asm/pdcpat.h>
 #include <asm/page.h>
-#include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/io.h>		/* read/write functions */
 #ifdef CONFIG_SUPERIO
@@ -278,10 +246,12 @@
 #define IOSAPIC_IRDT_ID_EID_SHIFT              0x10
 
 
-static struct iosapic_info *iosapic_list;
-static spinlock_t iosapic_lock;
-static int iosapic_count;
+static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
 
+static inline void iosapic_eoi(void __iomem *addr, unsigned int data)
+{
+	__raw_writel(data, addr);
+}
 
 /*
 ** REVISIT: future platforms may have more than one IRT.
@@ -598,167 +568,34 @@
 	return irt_find_irqline(isi, intr_slot, intr_pin);
 }
 
-
-static irqreturn_t
-iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct vector_info *vi = (struct vector_info *) dev_id;
-	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
-	int irq_num = vi->iosapic->isi_region->data.irqbase + vi->irqline;
-
-	DBG("iosapic_interrupt(): irq %d line %d eoi 0x%p 0x%x\n",
-		irq, vi->irqline, vi->eoi_addr, vi->eoi_data);
-
-	/* Do NOT need to mask/unmask IRQ. processor is already masked. */
-
-	do_irq(&vi->iosapic->isi_region->action[vi->irqline], irq_num, regs);
-
-	/*
-	** PARISC only supports PCI devices below I/O SAPIC.
-	** PCI only supports level triggered in order to share IRQ lines.
-	** ergo I/O SAPIC must always issue EOI on parisc.
-	**
-	** i386/ia64 support ISA devices and have to deal with
-	** edge-triggered interrupts too.
-	*/
-	__raw_writel(vi->eoi_data, vi->eoi_addr);
-	return IRQ_HANDLED;
-}
-
-
-int
-iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
-{
-	struct iosapic_info *isi = (struct iosapic_info *)isi_obj;
-	struct irt_entry *irte = NULL;  /* only used if PAT PDC */
-	struct vector_info *vi;
-	int isi_line;	/* line used by device */
-	int tmp;
-
-	if (NULL == isi) {
-		printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
-			pci_name(pcidev));
-		return(-1);
-	}
-
-#ifdef CONFIG_SUPERIO
-	/*
-	 * HACK ALERT! (non-compliant PCI device support)
-	 *
-	 * All SuckyIO interrupts are routed through the PIC's on function 1.
-	 * But SuckyIO OHCI USB controller gets an IRT entry anyway because
-	 * it advertises INT D for INT_PIN.  Use that IRT entry to get the
-	 * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
-	 */
-	if (is_superio_device(pcidev)) {
-		/* We must call superio_fixup_irq() to register the pdev */
-		pcidev->irq = superio_fixup_irq(pcidev);
-
-		/* Don't return if need to program the IOSAPIC's IRT... */
-		if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
-			return pcidev->irq;
-	}
-#endif /* CONFIG_SUPERIO */
-
-	/* lookup IRT entry for isi/slot/pin set */
-	irte = iosapic_xlate_pin(isi, pcidev);
-	if (NULL == irte) {
-		printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
-				pci_name(pcidev));
-		return(-1);
-	}
-	DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
-		irte,
-		irte->entry_type,
-		irte->entry_length,
-		irte->polarity_trigger,
-		irte->src_bus_irq_devno,
-		irte->src_bus_id,
-		irte->src_seg_id,
-		irte->dest_iosapic_intin,
-		(u32) irte->dest_iosapic_addr);
-	isi_line = irte->dest_iosapic_intin;
-	pcidev->irq = isi->isi_region->data.irqbase + isi_line;
-
-	/* get vector info for this input line */
-	ASSERT(NULL != isi->isi_vector);
-	vi = &(isi->isi_vector[isi_line]);
-	DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
-
-	/* If this IRQ line has already been setup, skip it */
-	if (vi->irte)
-		return pcidev->irq;
-
-	vi->irte = irte;
-
-	/* Allocate processor IRQ */
-	vi->txn_irq = txn_alloc_irq();
-
-/* XXX/FIXME The txn_alloc_irq() code and related code should be moved
-** to enable_irq(). That way we only allocate processor IRQ bits
-** for devices that actually have drivers claiming them.
-** Right now we assign an IRQ to every PCI device present regardless
-** of whether it's used or not.
-*/
-	if (vi->txn_irq < 0)
-		panic("I/O sapic: couldn't get TXN IRQ\n");
-
-	/* enable_irq() will use txn_* to program IRdT */
-	vi->txn_addr = txn_alloc_addr(vi->txn_irq);
-	vi->txn_data = txn_alloc_data(vi->txn_irq, 8);
-        ASSERT(vi->txn_data < 256);  /* matches 8 above */
-
-	tmp = request_irq(vi->txn_irq, iosapic_interrupt, 0,
-						vi->name, vi);
-	ASSERT(tmp == 0);
-
-	vi->eoi_addr = (u32 *) (isi->isi_hpa + IOSAPIC_REG_EOI);
-	vi->eoi_data = cpu_to_le32(vi->txn_data);
-	ASSERT(NULL != isi->isi_region);
-
-	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
-		PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->irq),
-		pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
-
-	return pcidev->irq;
-}
-
-
-static void
-iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
+static void iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
 {
 	struct iosapic_info *isp = vi->iosapic;
 	u8 idx = vi->irqline;
 
-	*dp0 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(idx));
-	*dp1 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(idx));
+	*dp0 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY(idx));
+	*dp1 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY_HI(idx));
 }
 
 
-static void
-iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
+static void iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
 {
 	struct iosapic_info *isp = vi->iosapic;
 
-	ASSERT(NULL != isp);
-	ASSERT(0 != isp->isi_hpa);
-	DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p 0x%x 0x%x\n",
-		vi->irqline,
-		isp->isi_hpa,
-		dp0, dp1);
+	DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %lx 0x%x 0x%x\n",
+		vi->irqline, isp->isi_hpa, dp0, dp1);
 
-	iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
+	iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
 
 	/* Read the window register to flush the writes down to HW  */
-	dp0 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+	dp0 = readl(isp->addr+IOSAPIC_REG_WINDOW);
 
-	iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
+	iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
 
 	/* Read the window register to flush the writes down to HW  */
-	dp1 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+	dp1 = readl(isp->addr+IOSAPIC_REG_WINDOW);
 }
 
-
 /*
 ** set_irt prepares the data (dp0, dp1) according to the vector_info
 ** and target cpu (id_eid).  dp0/dp1 are then used to program I/O SAPIC
@@ -810,62 +647,31 @@
 }
 
 
-static void
-iosapic_disable_irq(void *irq_dev, int irq)
+static struct vector_info *iosapic_get_vector(unsigned int irq)
 {
-	ulong irqflags;
-	struct vector_info *vi = &(((struct vector_info *) irq_dev)[irq]);
-	u32 d0, d1;
-
-	ASSERT(NULL != vi);
-
-	IOSAPIC_LOCK(&iosapic_lock);
-
-#ifdef REVISIT_DESIGN_ISSUE
-/* 
-** XXX/FIXME
-
-disable_irq()/enable_irq(): drawback of using IRQ as a "handle"
-
-Current disable_irq interface only allows the irq_region support routines
-to manage sharing of "irq" objects.  The problem is the disable_irq()
-interface specifies which IRQ line needs to be disabled but does not
-identify the particular ISR which needs to be disabled.  IO sapic
-(and similar code in Dino) can only support one handler per IRQ
-since they don't further encode the meaning of the IRQ number.
-irq_region support has to hide it's implementation of "shared IRQ"
-behind a function call.
-
-Encoding the IRQ would be possible by I/O SAPIC but makes life really
-complicated for the IRQ handler and not help performance.
+	return irq_desc[irq].handler_data;
+}
 
-Need more info on how Linux supports shared IRQ lines on a PC.
-*/
-#endif /* REVISIT_DESIGN_ISSUE */
+static void iosapic_disable_irq(unsigned int irq)
+{
+	unsigned long flags;
+	struct vector_info *vi = iosapic_get_vector(irq);
+	u32 d0, d1;
 
+	spin_lock_irqsave(&iosapic_lock, flags);
 	iosapic_rd_irt_entry(vi, &d0, &d1);
 	d0 |= IOSAPIC_IRDT_ENABLE;
 	iosapic_wr_irt_entry(vi, d0, d1);
-
-	IOSAPIC_UNLOCK(&iosapic_lock);
-
-	/* disable ISR for parent */
-	disable_irq(vi->txn_irq);
+	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
 
-
-static void
-iosapic_enable_irq(void *dev, int irq)
+static void iosapic_enable_irq(unsigned int irq)
 {
-	struct vector_info *vi = &(((struct vector_info *) dev)[irq]);
+	struct vector_info *vi = iosapic_get_vector(irq);
 	u32 d0, d1;
 
-	ASSERT(NULL != vi);
-	ASSERT(NULL != vi->irte);
-
 	/* data is initialized by fixup_irq */
-	ASSERT(0 < vi->txn_irq);
-	ASSERT(0UL != vi->txn_data);
+	WARN_ON(vi->txn_irq  == 0);
 
 	iosapic_set_irt_data(vi, &d0, &d1);
 	iosapic_wr_irt_entry(vi, d0, d1);
@@ -884,7 +690,7 @@
 	struct iosapic_info *isp = vi->iosapic;
 
 	for (d0=0x10; d0<0x1e; d0++) {
-		d1 = iosapic_read(isp->isi_hpa, d0);
+		d1 = iosapic_read(isp->addr, d0);
 		printk(" %x", d1);
 	}
 }
@@ -892,35 +698,141 @@
 #endif
 
 	/*
-	** Issueing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
-	** asserted.  IRQ generally should not be asserted when a driver
-	** enables their IRQ. It can lead to "interesting" race conditions
-	** in the driver initialization sequence.
-	*/
-	__raw_writel(vi->eoi_data, vi->eoi_addr);
+	 * Issuing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
+	 * asserted.  IRQ generally should not be asserted when a driver
+	 * enables their IRQ. It can lead to "interesting" race conditions
+	 * in the driver initialization sequence.
+	 */
+	DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", irq,
+			vi->eoi_addr, vi->eoi_data);
+	iosapic_eoi(vi->eoi_addr, vi->eoi_data);
 }
 
+/*
+ * PARISC only supports PCI devices below I/O SAPIC.
+ * PCI only supports level triggered in order to share IRQ lines.
+ * ergo I/O SAPIC must always issue EOI on parisc.
+ *
+ * i386/ia64 support ISA devices and have to deal with
+ * edge-triggered interrupts too.
+ */
+static void iosapic_end_irq(unsigned int irq)
+{
+	struct vector_info *vi = iosapic_get_vector(irq);
+	DBG(KERN_DEBUG "end_irq(%d): eoi(%p, 0x%x)\n", irq,
+			vi->eoi_addr, vi->eoi_data);
+	iosapic_eoi(vi->eoi_addr, vi->eoi_data);
+}
 
-static void
-iosapic_mask_irq(void *dev, int irq)
+static unsigned int iosapic_startup_irq(unsigned int irq)
 {
-	BUG();
+	iosapic_enable_irq(irq);
+	return 0;
 }
 
+static struct hw_interrupt_type iosapic_interrupt_type = {
+	.typename =	"IO-SAPIC-level",
+	.startup =	iosapic_startup_irq,
+	.shutdown =	iosapic_disable_irq,
+	.enable =	iosapic_enable_irq,
+	.disable =	iosapic_disable_irq,
+	.ack =		no_ack_irq,
+	.end =		iosapic_end_irq,
+//	.set_affinity =	iosapic_set_affinity_irq,
+};
 
-static void
-iosapic_unmask_irq(void *dev, int irq)
+int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
 {
-	BUG();
-}
+	struct iosapic_info *isi = isi_obj;
+	struct irt_entry *irte = NULL;  /* only used if PAT PDC */
+	struct vector_info *vi;
+	int isi_line;	/* line used by device */
 
+	if (!isi) {
+		printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
+			pci_name(pcidev));
+		return -1;
+	}
 
-static struct irq_region_ops iosapic_irq_ops = {
-	.disable_irq =	iosapic_disable_irq,
-	.enable_irq =	iosapic_enable_irq,
-	.mask_irq =	iosapic_mask_irq,
-	.unmask_irq =	iosapic_unmask_irq
-};
+#ifdef CONFIG_SUPERIO
+	/*
+	 * HACK ALERT! (non-compliant PCI device support)
+	 *
+	 * All SuckyIO interrupts are routed through the PIC's on function 1.
+	 * But SuckyIO OHCI USB controller gets an IRT entry anyway because
+	 * it advertises INT D for INT_PIN.  Use that IRT entry to get the
+	 * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
+	 */
+	if (is_superio_device(pcidev)) {
+		/* We must call superio_fixup_irq() to register the pdev */
+		pcidev->irq = superio_fixup_irq(pcidev);
+
+		/* Don't return if need to program the IOSAPIC's IRT... */
+		if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
+			return pcidev->irq;
+	}
+#endif /* CONFIG_SUPERIO */
+
+	/* lookup IRT entry for isi/slot/pin set */
+	irte = iosapic_xlate_pin(isi, pcidev);
+	if (!irte) {
+		printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
+				pci_name(pcidev));
+		return -1;
+	}
+	DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
+		irte,
+		irte->entry_type,
+		irte->entry_length,
+		irte->polarity_trigger,
+		irte->src_bus_irq_devno,
+		irte->src_bus_id,
+		irte->src_seg_id,
+		irte->dest_iosapic_intin,
+		(u32) irte->dest_iosapic_addr);
+	isi_line = irte->dest_iosapic_intin;
+
+	/* get vector info for this input line */
+	vi = isi->isi_vector + isi_line;
+	DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
+
+	/* If this IRQ line has already been setup, skip it */
+	if (vi->irte)
+		goto out;
+
+	vi->irte = irte;
+
+	/* Allocate processor IRQ */
+	vi->txn_irq = txn_alloc_irq();
+
+	/*
+	 * XXX/FIXME The txn_alloc_irq() code and related code should be
+	 * moved to enable_irq(). That way we only allocate processor IRQ
+	 * bits for devices that actually have drivers claiming them.
+	 * Right now we assign an IRQ to every PCI device present,
+	 * regardless of whether it's used or not.
+	 */
+	if (vi->txn_irq < 0)
+		panic("I/O sapic: couldn't get TXN IRQ\n");
+
+	/* enable_irq() will use txn_* to program IRdT */
+	vi->txn_addr = txn_alloc_addr(vi->txn_irq);
+	vi->txn_data = txn_alloc_data(vi->txn_irq, 8);
+
+	vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
+	vi->eoi_data = cpu_to_le32(vi->txn_data);
+
+	cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
+
+ out:
+	pcidev->irq = vi->txn_irq;
+
+	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
+		PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn),
+		pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
+
+	return pcidev->irq;
+}
 
 
 /*
@@ -944,10 +856,9 @@
 **	o read iosapic version and squirrel that away
 **	o read size of IRdT.
 **	o allocate and initialize isi_vector[]
-**	o allocate isi_region (registers region handlers)
+**	o allocate irq region
 */
-void *
-iosapic_register(unsigned long hpa)
+void *iosapic_register(unsigned long hpa)
 {
 	struct iosapic_info *isi = NULL;
 	struct irt_entry *irte = irt_cell;
@@ -993,27 +904,16 @@
 
 	if (vip == NULL) {
 		IOSAPIC_FREE(isi, struct iosapic_info, 1);
-		return (NULL);
+		return NULL;
 	}
 
 	memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors);
-	sprintf(isi->isi_name, "IO-SAPIC%02d", iosapic_count++);
 
-	/*
-	** Initialize vector array
-	*/
 	for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
 		vip->irqline = (unsigned char) cnt;
 		vip->iosapic = isi;
-		sprintf(vip->name, "%s-L%d", isi->isi_name, cnt);
 	}
-
-	isi->isi_region = alloc_irq_region(isi->isi_num_vectors,
-				&iosapic_irq_ops, isi->isi_name,
-				(void *) isi->isi_vector);
-
-	ASSERT(NULL != isi->isi_region);
-	return ((void *) isi);
+	return isi;
 }
 
 
diff -Nru a/drivers/parisc/iosapic_private.h b/drivers/parisc/iosapic_private.h
--- a/drivers/parisc/iosapic_private.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/parisc/iosapic_private.h	2005-01-19 13:44:46 -08:00
@@ -136,23 +136,20 @@
 	u32	eoi_data;		/* IA64: ?       PA: swapped txn_data */
 	int	txn_irq;		/* virtual IRQ number for processor */
 	ulong	txn_addr;		/* IA64: id_eid  PA: partial HPA */
-	ulong	txn_data;		/* IA64: vector  PA: EIR bit */
+	u32	txn_data;		/* CPU interrupt bit */
 	u8	status;			/* status/flags */
 	u8	irqline;		/* INTINn(IRQ) */
-	char	name[32];		/* user visible identity */
 };
 
 
 struct iosapic_info {
-	struct iosapic_info  *isi_next;      /* list of I/O SAPIC          */
-	unsigned long	     isi_hpa;	     /* physical base address */
-	struct irq_region    *isi_region;    /* each I/O SAPIC is one region */
-	struct vector_info   *isi_vector;    /* IRdT (IRQ line) array  */
-	int                  isi_num_vectors; /* size of IRdT array */
-	int                  isi_status;     /* status/flags               */
-	unsigned int         isi_version;    /* DEBUG: data fr version reg */
-	/* round up to next cacheline */
-	char                 isi_name[20]; /* identify region for users */
+	struct iosapic_info *	isi_next;	/* list of I/O SAPIC */
+	void __iomem *		addr;		/* remapped address */
+	unsigned long		isi_hpa;	/* physical base address */
+	struct vector_info *	isi_vector;	/* IRdT (IRQ line) array */
+	int			isi_num_vectors; /* size of IRdT array */
+	int			isi_status;	/* status/flags */
+	unsigned int		isi_version;	/* DEBUG: data fr version reg */
 };
 
 
diff -Nru a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
--- a/drivers/parisc/lasi.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/parisc/lasi.c	2005-01-19 13:44:47 -08:00
@@ -16,7 +16,7 @@
 
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/pm.h>
@@ -35,33 +35,30 @@
 #define LASI_IO_CONF	0x7FFFE	/* LASI primary configuration register */
 #define LASI_IO_CONF2	0x7FFFF	/* LASI secondary configuration register */
 
-static int lasi_choose_irq(struct parisc_device *dev)
+static void lasi_choose_irq(struct parisc_device *dev, void *ctrl)
 {
 	int irq;
 
-	/*
-	** "irq" bits below are numbered relative to most significant bit.
-	*/
 	switch (dev->id.sversion) {
-		case 0x74:	irq = 24; break; /* Centronics */
-		case 0x7B:	irq = 18; break; /* Audio */
-		case 0x81:	irq = 17; break; /* Lasi itself */
-		case 0x82:	irq = 22; break; /* SCSI */
-		case 0x83:	irq = 11; break; /* Floppy */
-		case 0x84:	irq =  5; break; /* PS/2 Keyboard */
-		case 0x87:	irq = 13; break; /* ISDN */
-		case 0x8A:	irq = 23; break; /* LAN */
-		case 0x8C:	irq = 26; break; /* RS232 */
-		case 0x8D:	irq = (dev->hw_path == 13) ? 15 : 14;
-						break; /* Telephone */
-		default: 	irq = -1; break; /* unknown */
+		case 0x74:	irq =  7; break; /* Centronics */
+		case 0x7B:	irq = 13; break; /* Audio */
+		case 0x81:	irq = 14; break; /* Lasi itself */
+		case 0x82:	irq =  9; break; /* SCSI */
+		case 0x83:	irq = 20; break; /* Floppy */
+		case 0x84:	irq = 26; break; /* PS/2 Keyboard */
+		case 0x87:	irq = 18; break; /* ISDN */
+		case 0x8A:	irq =  8; break; /* LAN */
+		case 0x8C:	irq =  5; break; /* RS232 */
+		case 0x8D:	irq = (dev->hw_path == 13) ? 16 : 17; break;
+						 /* Telephone */
+		default: 	return;		 /* unknown */
 	}
 
-	return irq;
+	gsc_asic_assign_irq(ctrl, irq, &dev->irq);
 }
 
 static void __init
-lasi_init_irq(struct busdevice *this_lasi)
+lasi_init_irq(struct gsc_asic *this_lasi)
 {
 	unsigned long lasi_base = this_lasi->hpa;
 
@@ -170,11 +167,11 @@
 int __init
 lasi_init_chip(struct parisc_device *dev)
 {
-	struct busdevice *lasi;
+	struct gsc_asic *lasi;
 	struct gsc_irq gsc_irq;
-	int irq, ret;
+	int ret;
 
-	lasi = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	lasi = kmalloc(sizeof(*lasi), GFP_KERNEL);
 	if (!lasi)
 		return -ENOMEM;
 
@@ -193,36 +190,33 @@
 	lasi_init_irq(lasi);
 
 	/* the IRQ lasi should use */
-	irq = gsc_alloc_irq(&gsc_irq);
-	if (irq < 0) {
+	dev->irq = gsc_alloc_irq(&gsc_irq);
+	if (dev->irq < 0) {
 		printk(KERN_ERR "%s(): cannot get GSC irq\n",
 				__FUNCTION__);
 		kfree(lasi);
 		return -EBUSY;
 	}
 
-	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "lasi", lasi);
+	lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi);
 	if (ret < 0) {
 		kfree(lasi);
 		return ret;
 	}
 
-	/* Save this for debugging later */
-	lasi->parent_irq = gsc_irq.irq;
-	lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
-
 	/* enable IRQ's for devices below LASI */
 	gsc_writel(lasi->eim, lasi->hpa + OFFSET_IAR);
 
 	/* Done init'ing, register this driver */
-	ret = gsc_common_irqsetup(dev, lasi);
+	ret = gsc_common_setup(dev, lasi);
 	if (ret) {
 		kfree(lasi);
 		return ret;
 	}    
 
-	fixup_child_irqs(dev, lasi->busdev_region->data.irqbase,
-			lasi_choose_irq);
+	gsc_fixup_irqs(dev, lasi, lasi_choose_irq);
 
 	/* initialize the power off function */
 	/* FIXME: Record the LASI HPA for the power off function.  This should
diff -Nru a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
--- a/drivers/parisc/lba_pci.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/parisc/lba_pci.c	2005-01-19 13:44:47 -08:00
@@ -41,11 +41,9 @@
 #include <linux/smp_lock.h>
 
 #include <asm/byteorder.h>
-#include <asm/irq.h>		/* for struct irq_region support */
 #include <asm/pdc.h>
 #include <asm/pdcpat.h>
 #include <asm/page.h>
-#include <asm/segment.h>
 #include <asm/system.h>
 
 #include <asm/hardware.h>	/* for register_parisc_driver() stuff */
diff -Nru a/drivers/parisc/superio.c b/drivers/parisc/superio.c
--- a/drivers/parisc/superio.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/parisc/superio.c	2005-01-19 13:44:47 -08:00
@@ -72,7 +72,6 @@
 
 #include <asm/io.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
 #include <asm/superio.h>
 
 static struct superio_device sio_dev;
@@ -87,9 +86,8 @@
 #endif
 
 static irqreturn_t
-superio_interrupt(int irq, void *devp, struct pt_regs *regs)
+superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
 {
-	struct superio_device *sio = (struct superio_device *)devp;
 	u8 results;
 	u8 local_irq;
 
@@ -108,7 +106,7 @@
 		 * We don't know if an interrupt was/is pending and thus
 		 * just call the handler for that IRQ as if it were pending.
 		 */
-		return IRQ_HANDLED;
+		return IRQ_NONE;
 	}
 
 	/* Check to see which device is interrupting */
@@ -116,7 +114,6 @@
 
 	if (local_irq == 2 || local_irq > 7) {
 		printk(KERN_ERR "SuperIO: slave interrupted!\n");
-		BUG();
 		return IRQ_HANDLED;
 	}
 
@@ -133,9 +130,7 @@
 	}
 
 	/* Call the appropriate device's interrupt */
-	do_irq(&sio->irq_region->action[local_irq],
-		sio->irq_region->data.irqbase + local_irq,
-		regs);
+	__do_IRQ(local_irq, regs);
 
 	/* set EOI - forces a new interrupt if a lower priority device
 	 * still needs service.
@@ -280,59 +275,53 @@
 }
 
 
-static void
-superio_disable_irq(void *dev, int local_irq)
+static void superio_disable_irq(unsigned int irq)
 {
 	u8 r8;
 
-	if ((local_irq < 1) || (local_irq == 2) || (local_irq > 7)) {
-	    printk(KERN_ERR "SuperIO: Illegal irq number.\n");
-	    BUG();
-	    return;
+	if ((irq < 1) || (irq == 2) || (irq > 7)) {
+		printk(KERN_ERR "SuperIO: Illegal irq number.\n");
+		BUG();
+		return;
 	}
 
 	/* Mask interrupt */
 
 	r8 = inb(IC_PIC1+1);
-	r8 |= (1 << local_irq);
+	r8 |= (1 << irq);
 	outb (r8,IC_PIC1+1);
 }
 
-static void
-superio_enable_irq(void *dev, int local_irq)
+static void superio_enable_irq(unsigned int irq)
 {
 	u8 r8;
 
-	if ((local_irq < 1) || (local_irq == 2) || (local_irq > 7)) {
-	    printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", local_irq);
-	    BUG();
-	    return;
+	if ((irq < 1) || (irq == 2) || (irq > 7)) {
+		printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", irq);
+		BUG();
+		return;
 	}
 
 	/* Unmask interrupt */
 	r8 = inb(IC_PIC1+1);
-	r8 &= ~(1 << local_irq);
+	r8 &= ~(1 << irq);
 	outb (r8,IC_PIC1+1);
 }
 
-
-static void
-superio_mask_irq(void *dev, int local_irq)
-{
-	BUG();
-}
-
-static void
-superio_unmask_irq(void *dev, int local_irq)
+static unsigned int superio_startup_irq(unsigned int irq)
 {
-	BUG();
+	superio_enable_irq(irq);
+	return 0;
 }
 
-static struct irq_region_ops superio_irq_ops = {
-	.disable_irq =	superio_disable_irq,
-	.enable_irq =	superio_enable_irq,
-	.mask_irq =	superio_mask_irq,
-	.unmask_irq =	superio_unmask_irq
+static struct hw_interrupt_type superio_interrupt_type = {
+	.typename =	"SuperIO",
+	.startup =	superio_startup_irq,
+	.shutdown =	superio_disable_irq,
+	.enable =	superio_enable_irq,
+	.disable =	superio_disable_irq,
+	.ack =		no_ack_irq,
+	.end =		no_end_irq,
 };
 
 #ifdef DEBUG_SUPERIO_INIT
@@ -345,7 +334,7 @@
 
 int superio_fixup_irq(struct pci_dev *pcidev)
 {
-	int local_irq;
+	int local_irq, i;
 
 #ifdef DEBUG_SUPERIO_INIT
 	int fn;
@@ -362,15 +351,8 @@
 		__builtin_return_address(0));
 #endif
 
-	if (!sio_dev.irq_region) {
-		/* Allocate an irq region for SuperIO devices */
-		sio_dev.irq_region = alloc_irq_region(SUPERIO_NIRQS,
-						&superio_irq_ops,
-						"SuperIO", (void *) &sio_dev);
-		if (!sio_dev.irq_region) {
-			printk(KERN_WARNING "SuperIO: alloc_irq_region failed\n");
-			return -1;
-		}
+	for (i = 0; i < 16; i++) {
+		irq_desc[i].handler = &superio_interrupt_type;
 	}
 
 	/*
@@ -396,7 +378,7 @@
 		break;
 	}
 
-	return(sio_dev.irq_region->data.irqbase + local_irq);
+	return local_irq;
 }
 
 static struct uart_port serial[] = {
@@ -416,25 +398,13 @@
 	}
 };
 
-void __devinit
-superio_serial_init(void)
+static void __devinit superio_serial_init(void)
 {
 #ifdef CONFIG_SERIAL_8250
 	int retval;
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	extern void serial8250_console_init(void); /* drivers/serial/8250.c */
-#endif        
         
-	if (!sio_dev.irq_region)
-		return; /* superio not present */
-
-	if (!serial) {
-		printk(KERN_WARNING "SuperIO: Could not get memory for serial struct.\n");
-		return;
-	}
-
 	serial[0].iobase = sio_dev.sp1_base;
-	serial[0].irq = sio_dev.irq_region->data.irqbase + SP1_IRQ;
+	serial[0].irq = SP1_IRQ;
 
 	retval = early_serial_setup(&serial[0]);
 	if (retval < 0) {
@@ -442,12 +412,8 @@
 		return;
 	}
 
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-	serial8250_console_init();
-#endif
-        
 	serial[1].iobase = sio_dev.sp2_base;
-	serial[1].irq = sio_dev.irq_region->data.irqbase + SP2_IRQ;
+	serial[1].irq = SP2_IRQ;
 	retval = early_serial_setup(&serial[1]);
 
 	if (retval < 0)
@@ -456,13 +422,12 @@
 }
 
 
-static void __devinit
-superio_parport_init(void)
+static void __devinit superio_parport_init(void)
 {
 #ifdef CONFIG_PARPORT_PC
 	if (!parport_pc_probe_port(sio_dev.pp_base,
 			0 /*base_hi*/,
-			sio_dev.irq_region->data.irqbase + PAR_IRQ, 
+			PAR_IRQ, 
 			PARPORT_DMA_NONE /* dma */,
 			NULL /*struct pci_dev* */) )
 
@@ -471,7 +436,7 @@
 }
 
 
-void superio_fixup_pci(struct pci_dev *pdev)
+static void superio_fixup_pci(struct pci_dev *pdev)
 {
 	u8 prog;
 
diff -Nru a/drivers/parisc/wax.c b/drivers/parisc/wax.c
--- a/drivers/parisc/wax.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/parisc/wax.c	2005-01-19 13:44:47 -08:00
@@ -21,28 +21,28 @@
 
 #include <asm/io.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
 
 #include "gsc.h"
 
 #define WAX_GSC_IRQ	7	/* Hardcoded Interrupt for GSC */
 #define WAX_GSC_NMI_IRQ	29
 
-static int wax_choose_irq(struct parisc_device *dev)
+static void wax_choose_irq(struct parisc_device *dev, void *ctrl)
 {
-	int irq = -1;
+	int irq;
 
 	switch (dev->id.sversion) {
-		case 0x73:	irq = 30; break; /* HIL */
-		case 0x8c:	irq = 25; break; /* RS232 */
-		case 0x90:	irq = 21; break; /* WAX EISA BA */
+		case 0x73:	irq =  1; break; /* HIL */
+		case 0x8c:	irq =  6; break; /* RS232 */
+		case 0x90:	irq = 10; break; /* WAX EISA BA */
+		default:	return;		 /* Unknown */
 	}
 
-	return irq;
+	gsc_asic_assign_irq(ctrl, irq, &dev->irq);
 }
 
 static void __init
-wax_init_irq(struct busdevice *wax)
+wax_init_irq(struct gsc_asic *wax)
 {
 	unsigned long base = wax->hpa;
 
@@ -50,7 +50,7 @@
 	gsc_writel(0x00000000, base+OFFSET_IMR);
 
 	/* clear pending interrupts */
-	(volatile u32) gsc_readl(base+OFFSET_IRR);
+	gsc_readl(base+OFFSET_IRR);
 
 	/* We're not really convinced we want to reset the onboard
          * devices. Firmware does it for us...
@@ -69,11 +69,12 @@
 int __init
 wax_init_chip(struct parisc_device *dev)
 {
-	struct busdevice *wax;
+	struct gsc_asic *wax;
+	struct parisc_device *parent;
 	struct gsc_irq gsc_irq;
-	int irq, ret;
+	int ret;
 
-	wax = kmalloc(sizeof(struct busdevice), GFP_KERNEL);
+	wax = kmalloc(sizeof(*wax), GFP_KERNEL);
 	if (!wax)
 		return -ENOMEM;
 
@@ -87,40 +88,37 @@
 	wax_init_irq(wax);
 
 	/* the IRQ wax should use */
-	irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ);
-	if (irq < 0) {
+	dev->irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ);
+	if (dev->irq < 0) {
 		printk(KERN_ERR "%s(): cannot get GSC irq\n",
 				__FUNCTION__);
 		kfree(wax);
 		return -EBUSY;
 	}
 
-	ret = request_irq(gsc_irq.irq, busdev_barked, 0, "wax", wax);
+	wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+	ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "wax", wax);
 	if (ret < 0) {
 		kfree(wax);
 		return ret;
 	}
 
-	/* Save this for debugging later */
-	wax->parent_irq = gsc_irq.irq;
-	wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
-
 	/* enable IRQ's for devices below WAX */
 	gsc_writel(wax->eim, wax->hpa + OFFSET_IAR);
 
 	/* Done init'ing, register this driver */
-	ret = gsc_common_irqsetup(dev, wax);
+	ret = gsc_common_setup(dev, wax);
 	if (ret) {
 		kfree(wax);
 		return ret;
 	}
 
-	fixup_child_irqs(dev, wax->busdev_region->data.irqbase,
-			wax_choose_irq);
+	gsc_fixup_irqs(dev, wax, wax_choose_irq);
 	/* On 715-class machines, Wax EISA is a sibling of Wax, not a child. */
-	if (dev->parent->id.hw_type != HPHW_IOA) {
-		fixup_child_irqs(dev->parent, wax->busdev_region->data.irqbase,
-				wax_choose_irq);
+	parent = parisc_parent(dev);
+	if (parent->id.hw_type != HPHW_IOA) {
+		gsc_fixup_irqs(parent, wax, wax_choose_irq);
 	}
 
 	return ret;
diff -Nru a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
--- a/drivers/parport/parport_cs.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/parport/parport_cs.c	2005-01-19 13:44:48 -08:00
@@ -66,11 +66,6 @@
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
 
-/* Bit map of interrupts to choose from */
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 INT_MODULE_PARM(epp_mode, 1);
 
 #ifdef PCMCIA_DEBUG
@@ -116,7 +111,7 @@
     parport_info_t *info;
     dev_link_t *link;
     client_reg_t client_reg;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "parport_attach()\n");
 
@@ -129,12 +124,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
diff -Nru a/drivers/pci/Kconfig b/drivers/pci/Kconfig
--- a/drivers/pci/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/drivers/pci/Kconfig	2005-01-19 13:44:46 -08:00
@@ -25,7 +25,7 @@
 
 	  lspci can provide the same data, as well as much more. lspci is a part of
 	  the pci-utils package, which should be installed by your distribution. 
-	  See Documentation/Changes for information on where to get the latest 
+	  See <file:Documentation/Changes> for information on where to get the latest
 	  version. 
 
 	  When in doubt, say N.
diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile	2005-01-19 13:44:47 -08:00
+++ b/drivers/pci/Makefile	2005-01-19 13:44:47 -08:00
@@ -56,4 +56,6 @@
 # Files generated that shall be removed upon make clean
 clean-files := devlist.h classlist.h
 
+# Build PCI Express stuff if needed
+obj-$(CONFIG_PCIEPORTBUS) += pcie/
 
diff -Nru a/drivers/pci/access.c b/drivers/pci/access.c
--- a/drivers/pci/access.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/pci/access.c	2005-01-19 13:44:48 -08:00
@@ -7,7 +7,7 @@
  * configuration space.
  */
 
-static spinlock_t pci_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pci_lock);
 
 /*
  *  Wrappers for all PCI configuration access functions.  They just check
diff -Nru a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
--- a/drivers/pci/hotplug/Kconfig	2005-01-19 13:44:48 -08:00
+++ b/drivers/pci/hotplug/Kconfig	2005-01-19 13:44:48 -08:00
@@ -134,27 +134,6 @@
 
 	  When in doubt, say N.
 
-config HOTPLUG_PCI_PCIE
-	tristate "PCI Express Hotplug driver"
-	depends on HOTPLUG_PCI
-	help
-	  Say Y here if you have a motherboard that supports PCI Express Native
-	  Hotplug
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called pciehp.
-
-	  When in doubt, say N.
-
-config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
-	bool "Use polling mechanism for hot-plug events (for testing purpose)"
-	depends on HOTPLUG_PCI_PCIE
-	help
-	  Say Y here if you want to use the polling mechanism for hot-plug 
-	  events for early platform testing.
-	   
-	  When in doubt, say N.
-
 config HOTPLUG_PCI_SHPC
 	tristate "SHPC PCI Hotplug driver"
 	depends on HOTPLUG_PCI
diff -Nru a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
--- a/drivers/pci/hotplug/pciehp.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/pci/hotplug/pciehp.h	2005-01-19 13:44:47 -08:00
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <asm/semaphore.h>
 #include <asm/io.h>		
+#include <linux/pcieport_if.h>
 #include "pci_hotplug.h"
 
 #define MY_NAME	"pciehp"
@@ -311,7 +312,7 @@
 
 typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id);
 
-int pcie_init(struct controller *ctrl, struct pci_dev *pdev,
+int pcie_init(struct controller *ctrl, struct pcie_device *dev,
 		php_intr_callback_t attention_button_callback,
 		php_intr_callback_t switch_change_callback,
 		php_intr_callback_t presence_change_callback,
diff -Nru a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
--- a/drivers/pci/hotplug/pciehp_core.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/pci/hotplug/pciehp_core.c	2005-01-19 13:44:48 -08:00
@@ -40,6 +40,7 @@
 #include <asm/uaccess.h>
 #include "pciehp.h"
 #include "pciehprm.h"
+#include <linux/interrupt.h>
 
 /* Global variables */
 int pciehp_debug;
@@ -346,7 +347,7 @@
 	return 0;
 }
 
-static int pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
 {
 	int rc;
 	struct controller *ctrl;
@@ -354,7 +355,9 @@
 	int first_device_num = 0 ;	/* first PCI device number supported by this PCIE */  
 	int num_ctlr_slots;		/* number of slots supported by this HPC */
 	u8 value;
-
+	struct pci_dev *pdev;
+	
+	dbg("%s: Called by hp_drv\n", __FUNCTION__);
 	ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
 	if (!ctrl) {
 		err("%s : out of memory\n", __FUNCTION__);
@@ -363,8 +366,10 @@
 	memset(ctrl, 0, sizeof(struct controller));
 
 	dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
+	
+	pdev = dev->port;
 
-	rc = pcie_init(ctrl, pdev,
+	rc = pcie_init(ctrl, dev,
 		(php_intr_callback_t) pciehp_handle_attention_button,
 		(php_intr_callback_t) pciehp_handle_switch_change,
 		(php_intr_callback_t) pciehp_handle_presence_change,
@@ -562,32 +567,52 @@
 
 }
 
+int hpdriver_context = 0;
 
-static struct pci_device_id pcied_pci_tbl[] = {
-	{
-	.class =        ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
-	.class_mask =	~0,
-	.vendor =       PCI_ANY_ID,
-	.device =       PCI_ANY_ID,
-	.subvendor =    PCI_ANY_ID,
-	.subdevice =    PCI_ANY_ID,
-	},
-	
-	{ /* end: all zeroes */ }
-};
-
-MODULE_DEVICE_TABLE(pci, pcied_pci_tbl);
+static void pciehp_remove (struct pcie_device *device)
+{
+	printk("%s ENTRY\n", __FUNCTION__);	
+	printk("%s -> Call free_irq for irq = %d\n",  
+		__FUNCTION__, device->irq);
+	free_irq(device->irq, &hpdriver_context);
+}
 
+#ifdef CONFIG_PM
+static int pciehp_suspend (struct pcie_device *dev, u32 state)
+{
+	printk("%s ENTRY\n", __FUNCTION__);	
+	return 0;
+}
 
+static int pciehp_resume (struct pcie_device *dev)
+{
+	printk("%s ENTRY\n", __FUNCTION__);	
+	return 0;
+}
+#endif
 
-static struct pci_driver pcie_driver = {
-	.name		=	PCIE_MODULE_NAME,
-	.id_table	=	pcied_pci_tbl,
-	.probe		=	pcie_probe,
-	/* remove:	pcie_remove_one, */
+static struct pcie_port_service_id port_pci_ids[] = { { 
+	.vendor = PCI_ANY_ID, 
+	.device = PCI_ANY_ID,
+	.port_type = PCIE_RC_PORT, 
+	.service_type = PCIE_PORT_SERVICE_HP,
+	.driver_data =	0, 
+	}, { /* end: all zeroes */ }
 };
+static const char device_name[] = "hpdriver";
 
-
+static struct pcie_port_service_driver hpdriver_portdrv = {
+	.name		= (char *)device_name,
+	.id_table	= &port_pci_ids[0],
+
+	.probe		= pciehp_probe,
+	.remove		= pciehp_remove,
+
+#ifdef	CONFIG_PM
+	.suspend	= pciehp_suspend,
+	.resume		= pciehp_resume,
+#endif	/* PM */
+};
 
 static int __init pcied_init(void)
 {
@@ -603,9 +628,11 @@
 
 	retval = pciehprm_init(PCI);
 	if (!retval) {
-		retval = pci_register_driver(&pcie_driver);
-		dbg("pci_register_driver = %d\n", retval);
-		info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ 		retval = pcie_port_service_register(&hpdriver_portdrv);
+ 		dbg("pcie_port_service_register = %d\n", retval);
+  		info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ 		if (retval)
+ 		   dbg("%s: Failure to register service\n", __FUNCTION__);
 	}
 
 error_hpc_init:
@@ -625,8 +652,8 @@
 
 	pciehprm_cleanup();
 
-	dbg("pci_unregister_driver\n");
-	pci_unregister_driver(&pcie_driver);
+	dbg("pcie_port_service_unregister\n");
+	pcie_port_service_unregister(&hpdriver_portdrv);
 
 	info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
 }
diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
--- a/drivers/pci/hotplug/pciehp_hpc.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/pci/hotplug/pciehp_hpc.c	2005-01-19 13:44:47 -08:00
@@ -1249,7 +1249,7 @@
 };
 
 int pcie_init(struct controller * ctrl,
-	struct pci_dev *pdev,
+	struct pcie_device *dev,
 	php_intr_callback_t attention_button_callback,
 	php_intr_callback_t switch_change_callback,
 	php_intr_callback_t presence_change_callback,
@@ -1265,6 +1265,7 @@
 	u32 slot_cap;
 	int cap_base, saved_cap_base;
 	u16 slot_status, slot_ctrl;
+	struct pci_dev *pdev;
 
 	DBG_ENTER_ROUTINE
 	
@@ -1277,7 +1278,8 @@
 	}
 
 	memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
-
+	
+	pdev = dev->port;
 	php_ctlr->pci_dev = pdev;	/* save pci_dev in context */
 
 	dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__,
@@ -1338,7 +1340,7 @@
 	}
 
 	dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, 
-		PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev->irq);
+		PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
 	for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
 		if (pci_resource_len(pdev, rc) > 0)
 			dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
@@ -1355,7 +1357,7 @@
 	init_waitqueue_head(&ctrl->queue);
 
 	/* find the IRQ */
-	php_ctlr->irq = pdev->irq;
+	php_ctlr->irq = dev->irq;
 	dbg("HPC interrupt = %d\n", php_ctlr->irq);
 
 	/* Save interrupt callback info */
@@ -1407,17 +1409,6 @@
 		start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
 	} else {
 		/* Installs the interrupt handler */
-		dbg("%s: pcie_mch_quirk = %x\n", __FUNCTION__, pcie_mch_quirk);
-		if (!pcie_mch_quirk) {
-			rc = pci_enable_msi(pdev);
-			if (rc) {
-				info("Can't get msi for the hotplug controller\n");
-				info("Use INTx for the hotplug controller\n");
-				dbg("%s: rc = %x\n", __FUNCTION__, rc);
-			} else 
-				php_ctlr->irq = pdev->irq;
-		}
-
 		rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
 		dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
 		if (rc) {
diff -Nru a/drivers/pci/msi.c b/drivers/pci/msi.c
--- a/drivers/pci/msi.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/pci/msi.c	2005-01-19 13:44:47 -08:00
@@ -22,7 +22,7 @@
 
 #include "msi.h"
 
-static spinlock_t msi_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(msi_lock);
 static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
 static kmem_cache_t* msi_cachep;
 
@@ -374,19 +374,18 @@
 
 	if ((status = msi_cache_init()) < 0) {
 		pci_msi_enable = 0;
-		printk(KERN_INFO "WARNING: MSI INIT FAILURE\n");
+		printk(KERN_WARNING "PCI: MSI cache init failed\n");
 		return status;
 	}
 	last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
 	if (last_alloc_vector < 0) {
 		pci_msi_enable = 0;
-		printk(KERN_INFO "WARNING: ALL VECTORS ARE BUSY\n");
+		printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
 		status = -EBUSY;
 		return status;
 	}
 	vector_irq[last_alloc_vector] = 0;
 	nr_released_vectors++;
-	printk(KERN_INFO "MSI INIT SUCCESS\n");
 
 	return status;
 }
@@ -736,7 +735,9 @@
 	/* Check whether driver already requested for MSI-X vectors */
    	if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSIX)) > 0 &&
 		!msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
-			printk(KERN_INFO "Can't enable MSI. Device already had MSI-X vectors assigned\n");
+			printk(KERN_INFO "PCI: %s: Can't enable MSI.  "
+			       "Device already has MSI-X vectors assigned\n",
+			       pci_name(dev));
 			dev->irq = temp;
 			return -EINVAL;
 	}
@@ -774,9 +775,9 @@
 	}
 	if (entry->msi_attrib.state) {
 		spin_unlock_irqrestore(&msi_lock, flags);
-		printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n",
-		dev->bus->number, PCI_SLOT(dev->devfn),	PCI_FUNC(dev->devfn),
-		dev->irq);
+		printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without "
+		       "free_irq() on MSI vector %d\n",
+		       pci_name(dev), dev->irq);
 		BUG_ON(entry->msi_attrib.state > 0);
 	} else {
 		vector_irq[dev->irq] = 0; /* free it */
@@ -982,7 +983,9 @@
 	/* Check whether driver already requested for MSI vector */
    	if (pci_find_capability(dev, PCI_CAP_ID_MSI) > 0 &&
 		!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
-		printk(KERN_INFO "Can't enable MSI-X. Device already had MSI vector assigned\n");
+		printk(KERN_INFO "PCI: %s: Can't enable MSI-X.  "
+		       "Device already has an MSI vector assigned\n",
+		       pci_name(dev));
 		dev->irq = temp;
 		return -EINVAL;
 	}
@@ -1050,9 +1053,9 @@
 		spin_unlock_irqrestore(&msi_lock, flags);
 		if (warning) {
 			dev->irq = temp;
-			printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n",
-			dev->bus->number, PCI_SLOT(dev->devfn),
-			PCI_FUNC(dev->devfn));
+			printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without "
+			       "free_irq() on all MSI-X vectors\n",
+			       pci_name(dev));
 			BUG_ON(warning > 0);
 		} else {
 			dev->irq = temp;
@@ -1088,9 +1091,9 @@
 		state = msi_desc[dev->irq]->msi_attrib.state;
 		spin_unlock_irqrestore(&msi_lock, flags);
 		if (state) {
-			printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on vector->%d\n",
-			dev->bus->number, PCI_SLOT(dev->devfn),
-			PCI_FUNC(dev->devfn), dev->irq);
+			printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
+			       "called without free_irq() on MSI vector %d\n",
+			       pci_name(dev), dev->irq);
 			BUG_ON(state > 0);
 		} else /* Release MSI vector assigned to this device */
 			msi_free_vector(dev, dev->irq, 0);
@@ -1132,9 +1135,9 @@
 			iounmap(base);
 			release_mem_region(phys_addr, PCI_MSIX_ENTRY_SIZE *
 				multi_msix_capable(control));
-			printk(KERN_DEBUG "Driver[%d:%d:%d] unloaded wo doing free_irq on all vectors\n",
-				dev->bus->number, PCI_SLOT(dev->devfn),
-				PCI_FUNC(dev->devfn));
+			printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
+			       "called without free_irq() on all MSI-X vectors\n",
+			       pci_name(dev));
 			BUG_ON(warning > 0);
 		}
 		dev->irq = temp;		/* Restore IOAPIC IRQ */
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/pci/pci.c	2005-01-19 13:44:46 -08:00
@@ -269,7 +269,7 @@
 
 	pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
 	if ((pmc & PCI_PM_CAP_VER_MASK) != 2) {
-		printk(KERN_WARNING
+		printk(KERN_DEBUG
 		       "PCI: %s has unsupported PM cap regs version (%u)\n",
 		       dev->slot_name, pmc & PCI_PM_CAP_VER_MASK);
 		return -EIO;
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/pci/pci.h	2005-01-19 13:44:46 -08:00
@@ -59,12 +59,14 @@
 extern int pci_visit_dev(struct pci_visit *fn,
 			 struct pci_dev_wrapped *wrapped_dev,
 			 struct pci_bus_wrapped *wrapped_parent);
+extern void pci_remove_legacy_files(struct pci_bus *bus);
 
 /* Lock for read/write access to pci device and bus lists */
 extern spinlock_t pci_bus_lock;
 
 extern int pcie_mch_quirk;
 extern struct device_attribute pci_dev_attrs[];
+extern struct class_device_attribute class_device_attr_cpuaffinity;
 
 /**
  * pci_match_one_device - Tell if a PCI device structure has a matching
diff -Nru a/drivers/pci/pci.ids b/drivers/pci/pci.ids
--- a/drivers/pci/pci.ids	2005-01-19 13:44:46 -08:00
+++ b/drivers/pci/pci.ids	2005-01-19 13:44:46 -08:00
@@ -8088,6 +8088,7 @@
 	24c0  82801DB/DBL (ICH4/ICH4-L) LPC Bridge
 		1014 0267  NetVista A30p
 		1462 5800  845PE Max (MS-6580)
+	24c1  82801DBL (ICH4-L) IDE Controller
 	24c2  82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1
 		1014 0267  NetVista A30p
 		1071 8160  MIM2000
diff -Nru a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/Kconfig	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,38 @@
+#
+# PCI Express Port Bus Configuration
+#
+config PCIEPORTBUS
+	bool "PCI Express support"
+	depends on PCI_GOMMCONFIG || PCI_GOANY
+	default n
+
+	---help---
+	This automatically enables PCI Express Port Bus support. Users can
+	choose Native Hot-Plug support, Advanced Error Reporting support,
+	Power Management Event support and Virtual Channel support to run
+	on PCI Express Ports (Root or Switch).
+
+#
+# Include service Kconfig here
+#
+config HOTPLUG_PCI_PCIE
+	tristate "PCI Express Hotplug driver"
+	depends on HOTPLUG_PCI && PCIEPORTBUS
+	help
+	  Say Y here if you have a motherboard that supports PCI Express Native
+	  Hotplug
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pciehp.
+
+	  When in doubt, say N.
+
+config HOTPLUG_PCI_PCIE_POLL_EVENT_MODE
+	bool "Use polling mechanism for hot-plug events (for testing purpose)"
+	depends on HOTPLUG_PCI_PCIE
+	help
+	  Say Y here if you want to use the polling mechanism for hot-plug 
+	  events for early platform testing.
+	   
+	  When in doubt, say N.
+
diff -Nru a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/Makefile	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,7 @@
+#
+# Makefile for PCI-Express PORT Driver
+#
+
+pcieportdrv-y			:= portdrv_core.o portdrv_pci.o portdrv_bus.o
+
+obj-$(CONFIG_PCIEPORTBUS)	+= pcieportdrv.o
diff -Nru a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/portdrv.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,42 @@
+/*
+ * File:	portdrv.h
+ * Purpose:	PCI Express Port Bus Driver's Internal Data Structures
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#ifndef _PORTDRV_H_
+#define _PORTDRV_H_
+
+#if !defined(PCI_CAP_ID_PME)
+#define PCI_CAP_ID_PME			1
+#endif
+
+#if !defined(PCI_CAP_ID_EXP)
+#define PCI_CAP_ID_EXP			0x10
+#endif
+
+#define PORT_TYPE_MASK			0xf
+#define PORT_TO_SLOT_MASK		0x100
+#define SLOT_HP_CAPABLE_MASK		0x40
+#define PCIE_CAPABILITIES_REG		0x2
+#define PCIE_SLOT_CAPABILITIES_REG	0x14
+#define PCIE_PORT_DEVICE_MAXSERVICES	4
+#define PCI_CFG_SPACE_SIZE		256
+
+#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
+
+extern struct bus_type pcie_port_bus_type;
+extern struct device_driver pcieport_generic_driver;
+extern int pcie_port_device_probe(struct pci_dev *dev);
+extern int pcie_port_device_register(struct pci_dev *dev);
+#ifdef CONFIG_PM
+extern int pcie_port_device_suspend(struct pcie_device *dev, u32 state);
+extern int pcie_port_device_resume(struct pcie_device *dev);
+#endif
+extern void pcie_port_device_remove(struct pcie_device *dev);
+extern void pcie_port_bus_register(void);
+extern void pcie_port_bus_unregister(void);
+
+#endif /* _PORTDRV_H_ */
diff -Nru a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/portdrv_bus.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,88 @@
+/*
+ * File:	portdrv_bus.c
+ * Purpose:	PCI Express Port Bus Driver's Bus Overloading Functions
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+
+#include <linux/pcieport_if.h>
+
+static int generic_probe (struct device *dev) {	return 0;}
+static int generic_remove (struct device *dev) { return 0;}
+static int pcie_port_bus_match(struct device *dev, struct device_driver *drv);
+static int pcie_port_bus_suspend(struct device *dev, u32 state);
+static int pcie_port_bus_resume(struct device *dev);
+
+struct bus_type pcie_port_bus_type = {
+	.name 		= "pci_express",
+	.match 		= pcie_port_bus_match,
+	.suspend	= pcie_port_bus_suspend,
+	.resume		= pcie_port_bus_resume, 
+};
+
+struct device_driver pcieport_generic_driver = {
+	.name =	"pcieport",
+	.bus = &pcie_port_bus_type,
+	.probe = generic_probe,
+	.remove = generic_remove,
+};
+
+static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (	drv->bus != &pcie_port_bus_type || 
+		dev->bus != &pcie_port_bus_type	||
+		drv == &pcieport_generic_driver) {
+		return 0;
+	}
+	pciedev = to_pcie_device(dev);
+	driver = to_service_driver(drv);
+	if (   (driver->id_table->vendor != PCI_ANY_ID && 
+		driver->id_table->vendor != pciedev->id.vendor) ||
+	       (driver->id_table->device != PCI_ANY_ID &&
+		driver->id_table->device != pciedev->id.device) ||	
+		driver->id_table->port_type != pciedev->id.port_type ||
+		driver->id_table->service_type != pciedev->id.service_type )
+		return 0;
+
+	return 1;
+}
+
+static int pcie_port_bus_suspend(struct device *dev, u32 state)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+	if (driver && driver->suspend)
+		driver->suspend(pciedev, state);
+	return 0;
+}
+
+static int pcie_port_bus_resume(struct device *dev)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+	if (driver && driver->resume)
+		driver->resume(pciedev);
+	return 0;
+}
diff -Nru a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/portdrv_core.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,453 @@
+/*
+ * File:	portdrv_core.c
+ * Purpose:	PCI Express Port Bus Driver's Core Functions
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+#include <linux/pcieport_if.h>
+
+#include "portdrv.h"
+
+extern int pcie_mch_quirk;	/* MSI-quirk Indicator */
+
+extern struct device_driver pcieport_generic_driver;
+
+static int pcie_port_probe_service(struct device *dev)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+	int status = -ENODEV;
+
+	if (!dev || !dev->driver)
+		return status;
+
+ 	driver = to_service_driver(dev->driver);
+	if (!driver || !driver->probe)
+		return status;
+
+	pciedev = to_pcie_device(dev);
+	status = driver->probe(pciedev, driver->id_table);
+	if (!status) {
+		printk(KERN_DEBUG "Load service driver %s on pcie device %s\n",
+			driver->name, dev->bus_id);
+		get_device(dev);
+	}
+	return status;
+}
+
+static int pcie_port_remove_service(struct device *dev)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+	if (driver && driver->remove) { 
+		printk(KERN_DEBUG "Unload service driver %s on pcie device %s\n",
+			driver->name, dev->bus_id);
+		driver->remove(pciedev);
+		put_device(dev);
+	}
+	return 0;
+}
+
+static void pcie_port_shutdown_service(struct device *dev) {}
+
+static int pcie_port_suspend_service(struct device *dev, u32 state, u32 level)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+	if (driver && driver->suspend)
+		driver->suspend(pciedev, state);
+	return 0;
+}
+
+static int pcie_port_resume_service(struct device *dev, u32 state)
+{
+	struct pcie_device *pciedev;
+	struct pcie_port_service_driver *driver;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	pciedev = to_pcie_device(dev);
+ 	driver = to_service_driver(dev->driver);
+
+	if (driver && driver->resume)
+		driver->resume(pciedev);
+	return 0;
+}
+
+/*
+ * release_pcie_device
+ *	
+ *	Being invoked automatically when device is being removed 
+ *	in response to device_unregister(dev) call.
+ *	Release all resources being claimed.
+ */
+static void release_pcie_device(struct device *dev)
+{
+	kfree(to_pcie_device(dev));			
+}
+
+static int is_msi_quirked(struct pci_dev *dev)
+{
+	int port_type, quirk = 0;
+	u16 reg16;
+
+	pci_read_config_word(dev, 
+		pci_find_capability(dev, PCI_CAP_ID_EXP) + 
+		PCIE_CAPABILITIES_REG, &reg16);
+	port_type = (reg16 >> 4) & PORT_TYPE_MASK;
+	switch(port_type) {
+	case PCIE_RC_PORT:
+		if (pcie_mch_quirk == 1)
+			quirk = 1;
+		break;
+	case PCIE_SW_UPSTREAM_PORT:
+	case PCIE_SW_DOWNSTREAM_PORT:
+	default:
+		break;	
+	}
+	return quirk;
+}
+	
+static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
+{
+	int i, pos, nvec, status = -EINVAL;
+	int interrupt_mode = PCIE_PORT_INTx_MODE;
+
+	/* Set INTx as default */
+	for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+		if (mask & (1 << i)) 
+			nvec++;
+		vectors[i] = dev->irq;
+	}
+	
+	/* Check MSI quirk */
+	if (is_msi_quirked(dev))
+		return interrupt_mode;
+
+	/* Select MSI-X over MSI if supported */		
+	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+	if (pos) {
+		struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = 
+			{{0, 0}, {0, 1}, {0, 2}, {0, 3}};
+		printk("%s Found MSIX capability\n", __FUNCTION__);
+		status = pci_enable_msix(dev, msix_entries, nvec);
+		if (!status) {
+			int j = 0;
+
+			interrupt_mode = PCIE_PORT_MSIX_MODE;
+			for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+				if (mask & (1 << i)) 
+					vectors[i] = msix_entries[j++].vector;
+			}
+		}
+	} 
+	if (status) {
+		pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+		if (pos) {
+			printk("%s Found MSI capability\n", __FUNCTION__);
+			status = pci_enable_msi(dev);
+			if (!status) {
+				interrupt_mode = PCIE_PORT_MSI_MODE;
+				for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
+					vectors[i] = dev->irq;
+			}
+		}
+	} 
+	return interrupt_mode;
+}
+
+static int get_port_device_capability(struct pci_dev *dev)
+{
+	int services = 0, pos;
+	u16 reg16;
+	u32 reg32;
+
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
+	/* Hot-Plug Capable */
+	if (reg16 & PORT_TO_SLOT_MASK) {
+		pci_read_config_dword(dev, 
+			pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
+		if (reg32 & SLOT_HP_CAPABLE_MASK)
+			services |= PCIE_PORT_SERVICE_HP;
+	} 
+	/* PME Capable */
+	pos = pci_find_capability(dev, PCI_CAP_ID_PME);
+	if (pos) 
+		services |= PCIE_PORT_SERVICE_PME;
+	
+	pos = PCI_CFG_SPACE_SIZE;
+	while (pos) {
+		pci_read_config_dword(dev, pos, &reg32);
+		switch (reg32 & 0xffff) {
+		case PCI_EXT_CAP_ID_ERR:
+			services |= PCIE_PORT_SERVICE_AER;
+			pos = reg32 >> 20;
+			break;
+		case PCI_EXT_CAP_ID_VC:
+			services |= PCIE_PORT_SERVICE_VC;
+			pos = reg32 >> 20;
+			break;
+		default:
+			pos = 0;
+			break;
+		}
+	}
+
+	return services;
+}
+
+static void pcie_device_init(struct pcie_device *parent, 
+			struct pcie_device *dev, 
+			int port_type, int service_type)
+{
+	struct device *device;
+
+	if (parent) {
+		dev->id.vendor = parent->port->vendor;
+		dev->id.device = parent->port->device;
+		dev->id.port_type = port_type;
+		dev->id.service_type = (1 << service_type);
+	}
+
+	/* Initialize generic device interface */
+	device = &dev->device;
+	memset(device, 0, sizeof(struct device));
+	INIT_LIST_HEAD(&device->node);
+	INIT_LIST_HEAD(&device->children);
+	INIT_LIST_HEAD(&device->bus_list);
+	device->bus = &pcie_port_bus_type;
+	device->driver = NULL;
+	device->driver_data = NULL; 
+	device->release = release_pcie_device;	/* callback to free pcie dev */
+	sprintf(&device->bus_id[0], "%s.%02x", parent->device.bus_id, 
+			get_descriptor_id(port_type, service_type));
+	device->parent = ((parent == NULL) ? NULL : &parent->device);
+}
+
+static struct pcie_device* alloc_pcie_device(
+	struct pcie_device *parent, struct pci_dev *bridge, 
+	int port_type, int service_type, int irq, int irq_mode)
+{
+	struct pcie_device *device;
+	static int NR_PORTS = 0;
+
+	device = kmalloc(sizeof(struct pcie_device), GFP_KERNEL);
+	if (!device)
+		return NULL;
+
+	memset(device, 0, sizeof(struct pcie_device));
+	device->port = bridge;
+	device->interrupt_mode = irq_mode;
+	device->irq = irq;
+	if (!parent) {
+		pcie_device_init(NULL, device, port_type, service_type);
+		NR_PORTS++;
+		device->device.driver = &pcieport_generic_driver;
+		sprintf(&device->device.bus_id[0], "port%d", NR_PORTS); 
+	} else { 
+		pcie_device_init(parent, device, port_type, service_type);
+	}
+	printk(KERN_DEBUG "Allocate Port Device[%s]\n", device->device.bus_id);
+	return device;
+}
+
+int pcie_port_device_probe(struct pci_dev *dev)
+{
+	int pos, type;
+	u16 reg;
+
+	if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP)))
+		return -ENODEV;
+
+	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);
+	type = (reg >> 4) & PORT_TYPE_MASK;
+	if (	type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||
+		type == PCIE_SW_DOWNSTREAM_PORT )  
+		return 0;
+ 
+	return -ENODEV;
+}
+
+int pcie_port_device_register(struct pci_dev *dev)
+{
+	struct pcie_device *parent;
+	int status, type, capabilities, irq_mode, i;
+	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
+	u16 reg16;
+
+	/* Get port type */
+	pci_read_config_word(dev, 
+		pci_find_capability(dev, PCI_CAP_ID_EXP) + 
+		PCIE_CAPABILITIES_REG, &reg16);
+	type = (reg16 >> 4) & PORT_TYPE_MASK;
+
+	/* Now get port services */
+	capabilities = get_port_device_capability(dev);
+	irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
+
+	/* Allocate parent */
+	parent = alloc_pcie_device(NULL, dev, type, 0, dev->irq, irq_mode);
+	if (!parent) 
+		return -ENOMEM;
+	
+	status = device_register(&parent->device);
+	if (status) {
+		kfree(parent);
+		return status;
+	}
+	get_device(&parent->device);
+	pci_set_drvdata(dev, parent);	
+
+	/* Allocate child services if any */
+	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+		struct pcie_device *child;
+
+		if (capabilities & (1 << i)) {
+			child = alloc_pcie_device(
+				parent,		/* parent */ 
+				dev, 		/* Root/Upstream/Downstream */
+				type,		/* port type */ 
+				i,		/* service type */
+				vectors[i],	/* irq */
+				irq_mode	/* interrupt mode */);
+			if (child) { 
+				status = device_register(&child->device);
+				if (status) {
+					kfree(child);
+					continue;
+				}
+				get_device(&child->device);
+			}
+		}
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PM
+int pcie_port_device_suspend(struct pcie_device *dev, u32 state)
+{
+	struct list_head 		*head;
+	struct device 			*parent, *child;
+	struct device_driver 		*driver;
+	struct pcie_port_service_driver *service_driver;
+
+	parent = &dev->device;
+	head = &parent->children;
+	while (!list_empty(head)) {
+		child = container_of(head->next, struct device, node);
+		driver = child->driver;
+		if (!driver)
+			continue;
+		service_driver = to_service_driver(driver);
+		if (service_driver->suspend)  
+			service_driver->suspend(to_pcie_device(child), state);
+	}
+	return 0; 
+}
+
+int pcie_port_device_resume(struct pcie_device *dev) 
+{ 
+	struct list_head 		*head;
+	struct device 			*parent, *child;
+	struct device_driver 		*driver;
+	struct pcie_port_service_driver *service_driver;
+
+	parent = &dev->device;
+	head = &parent->children;
+	while (!list_empty(head)) {
+		child = container_of(head->next, struct device, node);
+		driver = child->driver;
+		if (!driver)
+			continue;
+		service_driver = to_service_driver(driver);
+		if (service_driver->resume)  
+			service_driver->resume(to_pcie_device(child));
+	}
+	return 0; 
+
+}
+#endif
+
+void pcie_port_device_remove(struct pcie_device *dev)
+{
+	struct list_head 		*head;
+	struct device 			*parent, *child;
+	struct device_driver 		*driver;
+	struct pcie_port_service_driver *service_driver;
+
+	parent = &dev->device;
+	head = &parent->children;
+	while (!list_empty(head)) {
+		child = container_of(head->next, struct device, node);
+		driver = child->driver;
+		if (driver) { 
+			service_driver = to_service_driver(driver);
+			if (service_driver->remove)  
+				service_driver->remove(to_pcie_device(child));
+		}
+		put_device(child);
+		device_unregister(child);
+	}
+
+	/* Switch to INTx by default if MSI enabled */
+	if (dev->interrupt_mode == PCIE_PORT_MSIX_MODE)
+		pci_disable_msix(dev->port);
+	else if (dev->interrupt_mode == PCIE_PORT_MSI_MODE)
+		pci_disable_msi(dev->port);
+	put_device(parent);
+	device_unregister(parent);
+}
+
+void pcie_port_bus_register(void)
+{
+	bus_register(&pcie_port_bus_type);
+	driver_register(&pcieport_generic_driver);
+}
+
+void pcie_port_bus_unregister(void)
+{
+	driver_unregister(&pcieport_generic_driver);
+	bus_unregister(&pcie_port_bus_type);
+}
+
+int pcie_port_service_register(struct pcie_port_service_driver *new)
+{
+	new->driver.name = (char *)new->name;
+	new->driver.bus = &pcie_port_bus_type;
+	new->driver.probe = pcie_port_probe_service;
+	new->driver.remove = pcie_port_remove_service;
+	new->driver.shutdown = pcie_port_shutdown_service;
+	new->driver.suspend = pcie_port_suspend_service;
+	new->driver.resume = pcie_port_resume_service;
+
+	return driver_register(&new->driver);
+} 
+
+void pcie_port_service_unregister(struct pcie_port_service_driver *new)
+{
+	driver_unregister(&new->driver);
+}
+
+EXPORT_SYMBOL(pcie_port_service_register);
+EXPORT_SYMBOL(pcie_port_service_unregister);
diff -Nru a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pci/pcie/portdrv_pci.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,138 @@
+/*
+ * File:	portdrv_pci.c
+ * Purpose:	PCI Express Port Bus Driver
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+#include <linux/pcieport_if.h>
+
+#include "portdrv.h"
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
+#define DRIVER_DESC "PCIE Port Bus Driver"
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/* global data */
+static const char device_name[] = "pcieport-driver";
+
+/*
+ * pcie_portdrv_probe - Probe PCI-Express port devices
+ * @dev: PCI-Express port device being probed
+ *
+ * If detected invokes the pcie_port_device_register() method for 
+ * this port device.
+ *
+ */
+static int __devinit pcie_portdrv_probe (struct pci_dev *dev, 
+				const struct pci_device_id *id )
+{
+	int			status;
+
+	status = pcie_port_device_probe(dev);
+	if (status)
+		return status;
+
+	if (pci_enable_device(dev) < 0) 
+		return -ENODEV;
+	
+	pci_set_master(dev);
+        if (!dev->irq) {
+		printk(KERN_WARNING 
+		"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", 
+		__FUNCTION__, dev->device, dev->vendor);
+	}
+	if (pcie_port_device_register(dev)) 
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void pcie_portdrv_remove (struct pci_dev *dev)
+{
+	struct pcie_device *pciedev;
+
+      	pciedev = (struct pcie_device *)pci_get_drvdata(dev);
+	if (pciedev) {
+		pcie_port_device_remove(pciedev);
+		pci_set_drvdata(dev, NULL); 
+	}
+}
+
+#ifdef CONFIG_PM
+static int pcie_portdrv_suspend (struct pci_dev *dev, u32 state)
+{
+	struct pcie_device *pciedev;
+	
+      	pciedev = (struct pcie_device *)pci_get_drvdata(dev);
+	if (pciedev) 
+		pcie_port_device_suspend(pciedev, state);
+	return 0;
+}
+
+static int pcie_portdrv_resume (struct pci_dev *dev)
+{
+	struct pcie_device *pciedev;
+	
+      	pciedev = (struct pcie_device *)pci_get_drvdata(dev);
+	if (pciedev) 
+		pcie_port_device_resume(pciedev);
+	return 0;
+}
+#endif
+
+/*
+ * LINUX Device Driver Model
+ */
+static const struct pci_device_id port_pci_ids[] = { {
+	/* handle any PCI-Express port */
+	PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
+	}, { /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE(pci, port_pci_ids);
+
+static struct pci_driver pcie_portdrv = {
+	.name		= (char *)device_name,
+	.id_table	= &port_pci_ids[0],
+
+	.probe		= pcie_portdrv_probe,
+	.remove		= pcie_portdrv_remove,
+
+#ifdef	CONFIG_PM
+	.suspend	= pcie_portdrv_suspend,
+	.resume		= pcie_portdrv_resume,
+#endif	/* PM */
+};
+
+static int __init pcie_portdrv_init(void)
+{
+	int retval = 0;
+
+	pcie_port_bus_register();
+	retval = pci_module_init(&pcie_portdrv);
+	if (retval)
+		pcie_port_bus_unregister();
+	return retval;
+}
+
+static void __exit pcie_portdrv_exit(void) 
+{
+	pci_unregister_driver(&pcie_portdrv);
+	pcie_port_bus_unregister();
+}
+
+module_init(pcie_portdrv_init);
+module_exit(pcie_portdrv_exit);
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/pci/probe.c	2005-01-19 13:44:47 -08:00
@@ -62,7 +62,7 @@
 	}
 }
 
-static void pci_remove_legacy_files(struct pci_bus *b)
+void pci_remove_legacy_files(struct pci_bus *b)
 {
 	class_device_remove_bin_file(&b->class_dev, b->legacy_io);
 	class_device_remove_bin_file(&b->class_dev, b->legacy_mem);
@@ -70,7 +70,7 @@
 }
 #else /* !HAVE_PCI_LEGACY */
 static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
-static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
+void pci_remove_legacy_files(struct pci_bus *bus) { return; }
 #endif /* HAVE_PCI_LEGACY */
 
 /*
@@ -86,7 +86,7 @@
 		buf[ret++] = '\n';
 	return ret;
 }
-static CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
+CLASS_DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpuaffinity, NULL);
 
 /*
  * PCI Bus Class
@@ -95,10 +95,6 @@
 {
 	struct pci_bus *pci_bus = to_pci_bus(class_dev);
 
-	pci_remove_legacy_files(pci_bus);
-	class_device_remove_file(&pci_bus->class_dev,
-				 &class_device_attr_cpuaffinity);
-	sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
 	if (pci_bus->bridge)
 		put_device(pci_bus->bridge);
 	kfree(pci_bus);
diff -Nru a/drivers/pci/remove.c b/drivers/pci/remove.c
--- a/drivers/pci/remove.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/pci/remove.c	2005-01-19 13:44:46 -08:00
@@ -61,15 +61,18 @@
 }
 EXPORT_SYMBOL(pci_remove_device_safe);
 
-void pci_remove_bus(struct pci_bus *b)
+void pci_remove_bus(struct pci_bus *pci_bus)
 {
-	pci_proc_detach_bus(b);
+	pci_proc_detach_bus(pci_bus);
 
 	spin_lock(&pci_bus_lock);
-	list_del(&b->node);
+	list_del(&pci_bus->node);
 	spin_unlock(&pci_bus_lock);
-
-	class_device_unregister(&b->class_dev);
+	pci_remove_legacy_files(pci_bus);
+	class_device_remove_file(&pci_bus->class_dev,
+		&class_device_attr_cpuaffinity);
+	sysfs_remove_link(&pci_bus->class_dev.kobj, "bridge");
+	class_device_unregister(&pci_bus->class_dev);
 }
 EXPORT_SYMBOL(pci_remove_bus);
 
diff -Nru a/drivers/pci/rom.c b/drivers/pci/rom.c
--- a/drivers/pci/rom.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/pci/rom.c	2005-01-19 13:44:46 -08:00
@@ -5,10 +5,7 @@
  * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
  *
  * PCI ROM access routines
- *
  */
-
-
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -24,11 +21,10 @@
  * between the ROM and other resources, so enabling it may disable access
  * to MMIO registers or other card memory.
  */
-static void
-pci_enable_rom(struct pci_dev *pdev)
+static void pci_enable_rom(struct pci_dev *pdev)
 {
 	u32 rom_addr;
-	
+
 	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
 	rom_addr |= PCI_ROM_ADDRESS_ENABLE;
 	pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
@@ -41,8 +37,7 @@
  * Disable ROM decoding on a PCI device by turning off the last bit in the
  * ROM BAR.
  */
-static void
-pci_disable_rom(struct pci_dev *pdev)
+static void pci_disable_rom(struct pci_dev *pdev)
 {
 	u32 rom_addr;
 	pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
@@ -57,7 +52,7 @@
  * @return: kernel virtual pointer to image of ROM
  *
  * Map a PCI ROM into kernel space. If ROM is boot video ROM,
- * the shadow BIOS copy will be returned instead of the 
+ * the shadow BIOS copy will be returned instead of the
  * actual ROM.
  */
 void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
@@ -67,10 +62,12 @@
 	void __iomem *rom;
 	void __iomem *image;
 	int last_image;
-	
-	if (res->flags & IORESOURCE_ROM_SHADOW) {	/* IORESOURCE_ROM_SHADOW only set on x86 */
-		start = (loff_t)0xC0000; 	/* primary video rom always starts here */
-		*size = 0x20000;		/* cover C000:0 through E000:0 */
+
+	/* IORESOURCE_ROM_SHADOW only set on x86 */
+	if (res->flags & IORESOURCE_ROM_SHADOW) {
+		/* primary video rom always starts here */
+		start = (loff_t)0xC0000;
+		*size = 0x20000; /* cover C000:0 through E000:0 */
 	} else {
 		if (res->flags & IORESOURCE_ROM_COPY) {
 			*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
@@ -79,28 +76,32 @@
 			/* assign the ROM an address if it doesn't have one */
 			if (res->parent == NULL)
 				pci_assign_resource(pdev, PCI_ROM_RESOURCE);
-	
+
 			start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
 			*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
 			if (*size == 0)
 				return NULL;
-			
+
 			/* Enable ROM space decodes */
 			pci_enable_rom(pdev);
 		}
 	}
-	
+
 	rom = ioremap(start, *size);
 	if (!rom) {
 		/* restore enable if ioremap fails */
-		if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | IORESOURCE_ROM_COPY)))
+		if (!(res->flags & (IORESOURCE_ROM_ENABLE |
+				    IORESOURCE_ROM_SHADOW |
+				    IORESOURCE_ROM_COPY)))
 			pci_disable_rom(pdev);
 		return NULL;
-	}		
+	}
 
-	/* Try to find the true size of the ROM since sometimes the PCI window */
-	/* size is much larger than the actual size of the ROM. */
-	/* True size is important if the ROM is going to be copied. */
+	/*
+	 * Try to find the true size of the ROM since sometimes the PCI window
+	 * size is much larger than the actual size of the ROM.
+	 * True size is important if the ROM is going to be copied.
+	 */
 	image = rom;
 	do {
 		void __iomem *pds;
@@ -136,30 +137,30 @@
  * @return: kernel virtual pointer to image of ROM
  *
  * Map a PCI ROM into kernel space. If ROM is boot video ROM,
- * the shadow BIOS copy will be returned instead of the 
+ * the shadow BIOS copy will be returned instead of the
  * actual ROM.
  */
 void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
 {
 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
 	void __iomem *rom;
-	
+
 	rom = pci_map_rom(pdev, size);
 	if (!rom)
 		return NULL;
-		
+
 	if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
 		return rom;
-		
+
 	res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
-	if (!res->start) 
+	if (!res->start)
 		return rom;
 
-	res->end = res->start + *size; 
+	res->end = res->start + *size;
 	memcpy_fromio((void*)res->start, rom, *size);
 	pci_unmap_rom(pdev, rom);
 	res->flags |= IORESOURCE_ROM_COPY;
-	
+
 	return (void __iomem *)res->start;
 }
 
@@ -170,16 +171,15 @@
  *
  * Remove a mapping of a previously mapped ROM
  */
-void 
-pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
+void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
 {
 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
 
 	if (res->flags & IORESOURCE_ROM_COPY)
 		return;
-		
+
 	iounmap(rom);
-		
+
 	/* Disable again before continuing, leave enabled if pci=rom */
 	if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
 		pci_disable_rom(pdev);
@@ -189,26 +189,28 @@
  * pci_remove_rom - disable the ROM and remove its sysfs attribute
  * @dev: pointer to pci device struct
  *
+ * Remove the rom file in sysfs and disable ROM decoding.
  */
-void 
-pci_remove_rom(struct pci_dev *pdev) 
+void pci_remove_rom(struct pci_dev *pdev)
 {
 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
-	
+
 	if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
 		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
-	if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW | IORESOURCE_ROM_COPY)))
+	if (!(res->flags & (IORESOURCE_ROM_ENABLE |
+			    IORESOURCE_ROM_SHADOW |
+			    IORESOURCE_ROM_COPY)))
 		pci_disable_rom(pdev);
 }
 
 /**
- * pci_cleanup_rom - internal routine for freeing the ROM copy created 
+ * pci_cleanup_rom - internal routine for freeing the ROM copy created
  * by pci_map_rom_copy called from remove.c
  * @dev: pointer to pci device struct
  *
+ * Free the copied ROM if we allocated one.
  */
-void 
-pci_cleanup_rom(struct pci_dev *pdev) 
+void pci_cleanup_rom(struct pci_dev *pdev)
 {
 	struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
 	if (res->flags & IORESOURCE_ROM_COPY) {
diff -Nru a/drivers/pci/search.c b/drivers/pci/search.c
--- a/drivers/pci/search.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/pci/search.c	2005-01-19 13:44:45 -08:00
@@ -13,7 +13,7 @@
 #include <linux/interrupt.h>
 #include "pci.h"
 
-spinlock_t pci_bus_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(pci_bus_lock);
 
 static struct pci_bus * __devinit
 pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
--- a/drivers/pcmcia/Makefile	2005-01-19 13:44:47 -08:00
+++ b/drivers/pcmcia/Makefile	2005-01-19 13:44:47 -08:00
@@ -48,4 +48,5 @@
 
 pxa2xx_cs-$(CONFIG_ARCH_LUBBOCK)		+= pxa2xx_lubbock.o sa1111_generic.o
 pxa2xx_cs-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o
+pxa2xx_cs-$(CONFIG_PXA_SHARPSL)			+= pxa2xx_sharpsl.o
 
diff -Nru a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
--- a/drivers/pcmcia/cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/pcmcia/cs.c	2005-01-19 13:44:46 -08:00
@@ -29,7 +29,6 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/device.h>
-#include <linux/suspend.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 
@@ -118,6 +117,11 @@
 EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
 
 
+#ifdef CONFIG_PCMCIA_PROBE
+/* mask ofIRQs already reserved by other cards, we should avoid using them */
+static u8 pcmcia_used_irq[NR_IRQS];
+#endif
+
 /*====================================================================
 
     Low-level PC Card interface drivers need to register with Card
@@ -711,8 +715,7 @@
 		}
 
 		schedule();
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 
 		if (!skt->thread)
 			break;
@@ -1297,10 +1300,9 @@
     }
 
 #ifdef CONFIG_PCMCIA_PROBE
-    if (req->AssignedIRQ != s->pci_irq)
-	undo_irq(req->Attributes, req->AssignedIRQ);
+    pcmcia_used_irq[req->AssignedIRQ]--;
 #endif
-    
+
     return CS_SUCCESS;
 } /* cs_release_irq */
 
@@ -1532,72 +1534,96 @@
     
 ======================================================================*/
 
+#ifdef CONFIG_PCMCIA_PROBE
+static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+	return IRQ_NONE;
+}
+#endif
+
 int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
 {
-    struct pcmcia_socket *s;
-    config_t *c;
-    int ret = CS_IN_USE, irq = 0;
-    struct pcmcia_device *p_dev = handle_to_pdev(handle);
-    
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-    s = SOCKET(handle);
-    if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
-    c = CONFIG(handle);
-    if (c->state & CONFIG_LOCKED)
-	return CS_CONFIGURATION_LOCKED;
-    if (c->state & CONFIG_IRQ_REQ)
-	return CS_IN_USE;
+	struct pcmcia_socket *s;
+	config_t *c;
+	int ret = CS_IN_USE, irq = 0;
+	struct pcmcia_device *p_dev = handle_to_pdev(handle);
+
+	if (CHECK_HANDLE(handle))
+		return CS_BAD_HANDLE;
+	s = SOCKET(handle);
+	if (!(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+	c = CONFIG(handle);
+	if (c->state & CONFIG_LOCKED)
+		return CS_CONFIGURATION_LOCKED;
+	if (c->state & CONFIG_IRQ_REQ)
+		return CS_IN_USE;
 
 #ifdef CONFIG_PCMCIA_PROBE
-    if (s->irq.AssignedIRQ != 0) {
-	/* If the interrupt is already assigned, it must match */
-	irq = s->irq.AssignedIRQ;
-	if (req->IRQInfo1 & IRQ_INFO2_VALID) {
-	    u_int mask = req->IRQInfo2 & s->irq_mask;
-	    ret = ((mask >> irq) & 1) ? 0 : CS_BAD_ARGS;
-	} else
-	    ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS;
-    } else {
-	if (req->IRQInfo1 & IRQ_INFO2_VALID) {
-	    u_int try, mask = req->IRQInfo2 & s->irq_mask;
-	    for (try = 0; try < 2; try++) {
-		for (irq = 0; irq < 32; irq++)
-		    if ((mask >> irq) & 1) {
-			ret = try_irq(req->Attributes, irq, try);
-			if (ret == 0) break;
-		    }
-		if (ret == 0) break;
-	    }
+	if (s->irq.AssignedIRQ != 0) {
+		/* If the interrupt is already assigned, it must be the same */
+		irq = s->irq.AssignedIRQ;
 	} else {
-	    irq = req->IRQInfo1 & IRQ_MASK;
-	    ret = try_irq(req->Attributes, irq, 1);
+		int try;
+		u32 mask = s->irq_mask;
+		void *data = NULL;
+
+		for (try = 0; try < 64; try++) {
+			irq = try % 32;
+
+			/* marked as available by driver, and not blocked by userspace? */
+			if (!((mask >> irq) & 1))
+				continue;
+
+			/* avoid an IRQ which is already used by a PCMCIA card */
+			if ((try < 32) && pcmcia_used_irq[irq])
+				continue;
+
+			/* register the correct driver, if possible, of check whether
+			 * registering a dummy handle works, i.e. if the IRQ isn't
+			 * marked as used by the kernel resource management core */
+			ret = request_irq(irq,
+					  (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
+					  ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
+					   (s->functions > 1) ||
+					   (irq == s->pci_irq)) ? SA_SHIRQ : 0,
+					  p_dev->dev.bus_id,
+					  (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
+			if (!ret) {
+				if (!(req->Attributes & IRQ_HANDLE_PRESENT))
+					free_irq(irq, data);
+				break;
+			}
+		}
 	}
-    }
 #endif
-    if (ret != 0) {
-	if (!s->pci_irq)
-	    return ret;
-	irq = s->pci_irq;
-    }
+	if (ret) {
+		if (!s->pci_irq)
+			return ret;
+		irq = s->pci_irq;
+	}
+
+	if (ret && req->Attributes & IRQ_HANDLE_PRESENT) {
+		if (request_irq(irq, req->Handler,
+				((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
+				 (s->functions > 1) ||
+				 (irq == s->pci_irq)) ? SA_SHIRQ : 0,
+				p_dev->dev.bus_id, req->Instance))
+			return CS_IN_USE;
+	}
+
+	c->irq.Attributes = req->Attributes;
+	s->irq.AssignedIRQ = req->AssignedIRQ = irq;
+	s->irq.Config++;
 
-    if (req->Attributes & IRQ_HANDLE_PRESENT) {
-	if (request_irq(irq, req->Handler,
-			    ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || 
-			     (s->functions > 1) ||
-			     (irq == s->pci_irq)) ? SA_SHIRQ : 0,
-			     p_dev->dev.bus_id, req->Instance))
-	    return CS_IN_USE;
-    }
+	c->state |= CONFIG_IRQ_REQ;
+	handle->state |= CLIENT_IRQ_REQ;
 
-    c->irq.Attributes = req->Attributes;
-    s->irq.AssignedIRQ = req->AssignedIRQ = irq;
-    s->irq.Config++;
-    
-    c->state |= CONFIG_IRQ_REQ;
-    handle->state |= CLIENT_IRQ_REQ;
-    return CS_SUCCESS;
+#ifdef CONFIG_PCMCIA_PROBE
+	pcmcia_used_irq[irq]++;
+#endif
+
+	return CS_SUCCESS;
 } /* pcmcia_request_irq */
 
 /*======================================================================
diff -Nru a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
--- a/drivers/pcmcia/cs_internal.h	2005-01-19 13:44:48 -08:00
+++ b/drivers/pcmcia/cs_internal.h	2005-01-19 13:44:48 -08:00
@@ -140,8 +140,6 @@
 		     unsigned long r_end, struct pcmcia_socket *s);
 struct resource *find_mem_region(u_long base, u_long num, u_long align,
 		    int low, struct pcmcia_socket *s);
-int try_irq(u_int Attributes, int irq, int specific);
-void undo_irq(u_int Attributes, int irq);
 int adjust_resource_info(client_handle_t handle, adjust_t *adj);
 void release_resource_db(struct pcmcia_socket *s);
 
diff -Nru a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,264 @@
+/*
+ * Sharp SL-C7xx Series PCMCIA routines
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches and pxa2xx_mainstone.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/arch/corgi.h>
+#include <asm/arch/pxa-regs.h>
+
+#include "soc_common.h"
+
+#define	NO_KEEP_VS 0x0001
+
+static unsigned char keep_vs;
+static unsigned char keep_rd;
+
+static struct pcmcia_irqs irqs[] = {
+	{ 0, CORGI_IRQ_GPIO_CF_CD, "PCMCIA0 CD"},
+};
+
+static void sharpsl_pcmcia_init_reset(void)
+{
+	reset_scoop();
+	keep_vs = NO_KEEP_VS;
+	keep_rd = 0;
+}
+
+static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	int ret;
+
+	/*
+	 * Setup default state of GPIO outputs
+	 * before we enable them as outputs.
+	 */
+	GPSR(GPIO48_nPOE) =
+		GPIO_bit(GPIO48_nPOE) |
+		GPIO_bit(GPIO49_nPWE) |
+		GPIO_bit(GPIO50_nPIOR) |
+		GPIO_bit(GPIO51_nPIOW) |
+		GPIO_bit(GPIO52_nPCE_1) |
+		GPIO_bit(GPIO53_nPCE_2);
+
+	pxa_gpio_mode(GPIO48_nPOE_MD);
+	pxa_gpio_mode(GPIO49_nPWE_MD);
+	pxa_gpio_mode(GPIO50_nPIOR_MD);
+	pxa_gpio_mode(GPIO51_nPIOW_MD);
+	pxa_gpio_mode(GPIO52_nPCE_1_MD);
+	pxa_gpio_mode(GPIO53_nPCE_2_MD);
+	pxa_gpio_mode(GPIO54_pSKTSEL_MD);
+	pxa_gpio_mode(GPIO55_nPREG_MD);
+	pxa_gpio_mode(GPIO56_nPWAIT_MD);
+	pxa_gpio_mode(GPIO57_nIOIS16_MD);
+
+	/* Register interrupts */
+	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+	if (ret) {
+		printk(KERN_ERR "Request for Compact Flash IRQ failed\n");
+		return ret;
+	}
+
+	/* Enable interrupt */
+	write_scoop_reg(SCOOP_IMR, 0x00C0);
+	write_scoop_reg(SCOOP_MCR, 0x0101);
+	keep_vs = NO_KEEP_VS;
+
+	skt->irq = CORGI_IRQ_GPIO_CF_IRQ;
+
+	return 0;
+}
+
+static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+
+	/* CF_BUS_OFF */
+	sharpsl_pcmcia_init_reset();
+}
+
+
+static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+				    struct pcmcia_state *state)
+{
+	unsigned short cpr, csr;
+
+	cpr = read_scoop_reg(SCOOP_CPR);
+
+	write_scoop_reg(SCOOP_IRM, 0x00FF);
+	write_scoop_reg(SCOOP_ISR, 0x0000);
+	write_scoop_reg(SCOOP_IRM, 0x0000);
+	csr = read_scoop_reg(SCOOP_CSR);
+	if (csr & 0x0004) {
+		/* card eject */
+		write_scoop_reg(SCOOP_CDR, 0x0000);
+		keep_vs = NO_KEEP_VS;
+	}
+	else if (!(keep_vs & NO_KEEP_VS)) {
+		/* keep vs1,vs2 */
+		write_scoop_reg(SCOOP_CDR, 0x0000);
+		csr |= keep_vs;
+	}
+	else if (cpr & 0x0003) {
+		/* power on */
+		write_scoop_reg(SCOOP_CDR, 0x0000);
+		keep_vs = (csr & 0x00C0);
+	}
+	else {
+		/* card detect */
+		write_scoop_reg(SCOOP_CDR, 0x0002);
+	}
+
+	state->detect = (csr & 0x0004) ? 0 : 1;
+	state->ready  = (csr & 0x0002) ? 1 : 0;
+	state->bvd1   = (csr & 0x0010) ? 1 : 0;
+	state->bvd2   = (csr & 0x0020) ? 1 : 0;
+	state->wrprot = (csr & 0x0008) ? 1 : 0;
+	state->vs_3v  = (csr & 0x0040) ? 0 : 1;
+	state->vs_Xv  = (csr & 0x0080) ? 0 : 1;
+
+	if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
+		printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
+	}
+
+}
+
+
+static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+				       const socket_state_t *state)
+{
+	unsigned long flags;
+
+	unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
+
+	switch (state->Vcc) {
+	case	0:  	break;
+	case 	33: 	break;
+	case	50: 	break;
+	default:
+		 printk(KERN_ERR "sharpsl_pcmcia_configure_socket(): bad Vcc %u\n", state->Vcc);
+		 return -1;
+	}
+
+	if ((state->Vpp!=state->Vcc) && (state->Vpp!=0)) {
+		printk(KERN_ERR "CF slot cannot support Vpp %u\n", state->Vpp);
+		return -1;
+	}
+
+	local_irq_save(flags);
+
+	nmcr = (mcr = read_scoop_reg(SCOOP_MCR)) & ~0x0010;
+	ncpr = (cpr = read_scoop_reg(SCOOP_CPR)) & ~0x0083;
+	nccr = (ccr = read_scoop_reg(SCOOP_CCR)) & ~0x0080;
+	nimr = (imr = read_scoop_reg(SCOOP_IMR)) & ~0x003E;
+
+	ncpr |= (state->Vcc == 33) ? 0x0001 :
+				(state->Vcc == 50) ? 0x0002 : 0;
+	nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
+	ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
+	nccr |= (state->flags&SS_RESET)? 0x0080: 0;
+	nimr |=	((skt->status&SS_DETECT) ? 0x0004 : 0)|
+			((skt->status&SS_READY)  ? 0x0002 : 0)|
+			((skt->status&SS_BATDEAD)? 0x0010 : 0)|
+			((skt->status&SS_BATWARN)? 0x0020 : 0)|
+			((skt->status&SS_STSCHG) ? 0x0010 : 0)|
+			((skt->status&SS_WRPROT) ? 0x0008 : 0);
+
+	if (!(ncpr & 0x0003)) {
+		keep_rd = 0;
+	} else if (!keep_rd) {
+		if (nccr & 0x0080)
+			keep_rd = 1;
+		else
+			nccr |= 0x0080;
+	}
+
+	if (mcr != nmcr)
+		write_scoop_reg(SCOOP_MCR, nmcr);
+	if (cpr != ncpr)
+		write_scoop_reg(SCOOP_CPR, ncpr);
+	if (ccr != nccr)
+		write_scoop_reg(SCOOP_CCR, nccr);
+	if (imr != nimr)
+		write_scoop_reg(SCOOP_IMR, nimr);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level sharpsl_pcmcia_ops = {
+	.owner				= THIS_MODULE,
+	.hw_init			= sharpsl_pcmcia_hw_init,
+	.hw_shutdown		= sharpsl_pcmcia_hw_shutdown,
+	.socket_state		= sharpsl_pcmcia_socket_state,
+	.configure_socket	= sharpsl_pcmcia_configure_socket,
+	.socket_init		= sharpsl_pcmcia_socket_init,
+	.socket_suspend		= sharpsl_pcmcia_socket_suspend,
+	.first				= 0,
+	.nr					= 1,
+};
+
+static struct platform_device *sharpsl_pcmcia_device;
+
+static int __init sharpsl_pcmcia_init(void)
+{
+	int ret;
+
+	sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
+	if (!sharpsl_pcmcia_device)
+		return -ENOMEM;
+	memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
+	sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
+	sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
+
+	ret = platform_device_register(sharpsl_pcmcia_device);
+	if (ret)
+		kfree(sharpsl_pcmcia_device);
+
+	return ret;
+}
+
+static void __exit sharpsl_pcmcia_exit(void)
+{
+	/*
+	 * This call is supposed to free our sharpsl_pcmcia_device.
+	 * Unfortunately platform_device don't have a free method, and
+	 * we can't assume it's free of any reference at this point so we
+	 * can't free it either.
+	 */
+	platform_device_unregister(sharpsl_pcmcia_device);
+}
+
+module_init(sharpsl_pcmcia_init);
+module_exit(sharpsl_pcmcia_exit);
+
+MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
--- a/drivers/pcmcia/rsrc_mgr.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/pcmcia/rsrc_mgr.c	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,5 @@
 /*
- * rsrc_mgr.c -- Resource management routines
+ * rsrc_mgr.c -- Resource management routines and/or wrappers
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,228 +14,59 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/pci.h>
-#include <asm/irq.h>
-#include <asm/io.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
-#include <pcmcia/bulkmem.h>
-#include <pcmcia/cistpl.h>
 #include "cs_internal.h"
 
-static DECLARE_MUTEX(rsrc_sem);
 
 #ifdef CONFIG_PCMCIA_PROBE
 
-typedef struct irq_info_t {
-    u_int			Attributes;
-    int				time_share, dyn_share;
-    struct pcmcia_socket	*Socket;
-} irq_info_t;
-
-/* Table of IRQ assignments */
-static irq_info_t irq_table[NR_IRQS];
+static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
+{
+	int irq;
+	u32 mask;
 
-#endif
+	irq = adj->resource.irq.IRQ;
+	if ((irq < 0) || (irq > 15))
+		return CS_BAD_IRQ;
 
+	if (adj->Action != REMOVE_MANAGED_RESOURCE)
+		return 0;
 
-/*======================================================================
+	mask = 1 << irq;
 
-    This checks to see if an interrupt is available, with support
-    for interrupt sharing.  We don't support reserving interrupts
-    yet.  If the interrupt is available, we allocate it.
-    
-======================================================================*/
+	if (!(s->irq_mask & mask))
+		return 0;
 
-#ifdef CONFIG_PCMCIA_PROBE
+	s->irq_mask &= ~mask;
 
-static irqreturn_t fake_irq(int i, void *d, struct pt_regs *r) { return IRQ_NONE; }
-static inline int check_irq(int irq)
-{
-    if (request_irq(irq, fake_irq, 0, "bogus", NULL) != 0)
-	return -1;
-    free_irq(irq, NULL);
-    return 0;
+	return 0;
 }
 
-int try_irq(u_int Attributes, int irq, int specific)
-{
-    irq_info_t *info = &irq_table[irq];
-    int ret = 0;
+#else
 
-    down(&rsrc_sem);
-    if (info->Attributes & RES_ALLOCATED) {
-	switch (Attributes & IRQ_TYPE) {
-	case IRQ_TYPE_EXCLUSIVE:
-	    ret = CS_IN_USE;
-	    break;
-	case IRQ_TYPE_TIME:
-	    if ((info->Attributes & RES_IRQ_TYPE)
-		!= RES_IRQ_TYPE_TIME) {
-		ret = CS_IN_USE;
-		break;
-	    }
-	    if (Attributes & IRQ_FIRST_SHARED) {
-		ret = CS_BAD_ATTRIBUTE;
-		break;
-	    }
-	    info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
-	    info->time_share++;
-	    break;
-	case IRQ_TYPE_DYNAMIC_SHARING:
-	    if ((info->Attributes & RES_IRQ_TYPE)
-		!= RES_IRQ_TYPE_DYNAMIC) {
-		ret = CS_IN_USE;
-		break;
-	    }
-	    if (Attributes & IRQ_FIRST_SHARED) {
-		ret = CS_BAD_ATTRIBUTE;
-		break;
-	    }
-	    info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
-	    info->dyn_share++;
-	    break;
-	}
-    } else {
-	if ((info->Attributes & RES_RESERVED) && !specific) {
-	    ret = CS_IN_USE;
-	    goto out;
-	}
-	if (check_irq(irq) != 0) {
-	    ret = CS_IN_USE;
-	    goto out;
-	}
-	switch (Attributes & IRQ_TYPE) {
-	case IRQ_TYPE_EXCLUSIVE:
-	    info->Attributes |= RES_ALLOCATED;
-	    break;
-	case IRQ_TYPE_TIME:
-	    if (!(Attributes & IRQ_FIRST_SHARED)) {
-		ret = CS_BAD_ATTRIBUTE;
-		break;
-	    }
-	    info->Attributes |= RES_IRQ_TYPE_TIME | RES_ALLOCATED;
-	    info->time_share = 1;
-	    break;
-	case IRQ_TYPE_DYNAMIC_SHARING:
-	    if (!(Attributes & IRQ_FIRST_SHARED)) {
-		ret = CS_BAD_ATTRIBUTE;
-		break;
-	    }
-	    info->Attributes |= RES_IRQ_TYPE_DYNAMIC | RES_ALLOCATED;
-	    info->dyn_share = 1;
-	    break;
-	}
-    }
- out:
-    up(&rsrc_sem);
-    return ret;
+static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
+	return CS_SUCCESS;
 }
 
 #endif
 
-/*====================================================================*/
-
-#ifdef CONFIG_PCMCIA_PROBE
-
-void undo_irq(u_int Attributes, int irq)
-{
-    irq_info_t *info;
-
-    info = &irq_table[irq];
-    down(&rsrc_sem);
-    switch (Attributes & IRQ_TYPE) {
-    case IRQ_TYPE_EXCLUSIVE:
-	info->Attributes &= RES_RESERVED;
-	break;
-    case IRQ_TYPE_TIME:
-	info->time_share--;
-	if (info->time_share == 0)
-	    info->Attributes &= RES_RESERVED;
-	break;
-    case IRQ_TYPE_DYNAMIC_SHARING:
-	info->dyn_share--;
-	if (info->dyn_share == 0)
-	    info->Attributes &= RES_RESERVED;
-	break;
-    }
-    up(&rsrc_sem);
-}
-
-#endif
-
-/*====================================================================*/
-
-static int adjust_irq(adjust_t *adj)
-{
-    int ret = CS_SUCCESS;
-#ifdef CONFIG_PCMCIA_PROBE
-    int irq;
-    irq_info_t *info;
-    
-    irq = adj->resource.irq.IRQ;
-    if ((irq < 0) || (irq > 15))
-	return CS_BAD_IRQ;
-    info = &irq_table[irq];
-
-    down(&rsrc_sem);
-    switch (adj->Action) {
-    case ADD_MANAGED_RESOURCE:
-	if (info->Attributes & RES_REMOVED)
-	    info->Attributes &= ~(RES_REMOVED|RES_ALLOCATED);
-	else
-	    if (adj->Attributes & RES_ALLOCATED) {
-		ret = CS_IN_USE;
-		break;
-	    }
-	if (adj->Attributes & RES_RESERVED)
-	    info->Attributes |= RES_RESERVED;
-	else
-	    info->Attributes &= ~RES_RESERVED;
-	break;
-    case REMOVE_MANAGED_RESOURCE:
-	if (info->Attributes & RES_REMOVED) {
-	    ret = 0;
-	    break;
-	}
-	if (info->Attributes & RES_ALLOCATED) {
-	    ret = CS_IN_USE;
-	    break;
-	}
-	info->Attributes |= RES_ALLOCATED|RES_REMOVED;
-	info->Attributes &= ~RES_RESERVED;
-	break;
-    default:
-	ret = CS_UNSUPPORTED_FUNCTION;
-	break;
-    }
-    up(&rsrc_sem);
-#endif
-    return ret;
-}
 
 int pcmcia_adjust_resource_info(adjust_t *adj)
 {
 	struct pcmcia_socket *s;
 	int ret = CS_UNSUPPORTED_FUNCTION;
 
-	if (adj->Resource == RES_IRQ)
-		return adjust_irq(adj);
-
 	down_read(&pcmcia_socket_list_rwsem);
 	list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
-		if (s->resource_ops->adjust_resource)
+
+		if (adj->Resource == RES_IRQ)
+			ret = adjust_irq(s, adj);
+
+		else if (s->resource_ops->adjust_resource)
 			ret = s->resource_ops->adjust_resource(s, adj);
 	}
 	up_read(&pcmcia_socket_list_rwsem);
diff -Nru a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
--- a/drivers/pcmcia/socket_sysfs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/pcmcia/socket_sysfs.c	2005-01-19 13:44:46 -08:00
@@ -25,7 +25,6 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/device.h>
-#include <linux/suspend.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 
@@ -122,6 +121,33 @@
 static CLASS_DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
 
 
+static ssize_t pccard_show_irq_mask(struct class_device *dev, char *buf)
+{
+	struct pcmcia_socket *s = to_socket(dev);
+	return sprintf(buf, "0x%04x\n", s->irq_mask);
+}
+
+static ssize_t pccard_store_irq_mask(struct class_device *dev, const char *buf, size_t count)
+{
+	ssize_t ret;
+	struct pcmcia_socket *s = to_socket(dev);
+	u32 mask;
+
+	if (!count)
+		return -EINVAL;
+
+	ret = sscanf (buf, "0x%x\n", &mask);
+
+	if (ret == 1) {
+		s->irq_mask &= mask;
+		ret = 0;
+	}
+
+	return ret ? ret : count;
+}
+static CLASS_DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask);
+
+
 static struct class_device_attribute *pccard_socket_attributes[] = {
 	&class_device_attr_card_type,
 	&class_device_attr_card_voltage,
@@ -129,6 +155,7 @@
 	&class_device_attr_card_vcc,
 	&class_device_attr_card_insert,
 	&class_device_attr_card_eject,
+	&class_device_attr_card_irq_mask,
 	NULL,
 };
 
diff -Nru a/drivers/pnp/pnpbios/Kconfig b/drivers/pnp/pnpbios/Kconfig
--- a/drivers/pnp/pnpbios/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/pnp/pnpbios/Kconfig	2005-01-19 13:44:47 -08:00
@@ -30,7 +30,7 @@
 	  able to directly access the PNPBIOS.  This includes resource
 	  allocation, ESCD, and other PNPBIOS services.  Using this
 	  interface is potentially dangerous because the PNPBIOS driver will
-	  not be notified of any resource changes made by writting directly.
+	  not be notified of any resource changes made by writing directly.
 	  Also some buggy systems will fault when accessing certain features
 	  in the PNPBIOS /proc interface (e.g. "boot" configs).
 
diff -Nru a/drivers/s390/Kconfig b/drivers/s390/Kconfig
--- a/drivers/s390/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/s390/Kconfig	2005-01-19 13:44:47 -08:00
@@ -162,7 +162,7 @@
 	  devices using the block device interface.  This interface is similar
 	  to CD-ROM devices on other platforms.  The tapes can only be
 	  accessed read-only when using this interface.  Have a look at
-	  Documentation/s390/TAPE for further information about creating
+	  <file:Documentation/s390/TAPE> for further information about creating
 	  volumes for and using this interface.  It is safe to say "Y" here.
 
 comment "S/390 tape hardware support"
diff -Nru a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
--- a/drivers/s390/block/dasd.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/s390/block/dasd.c	2005-01-19 13:44:46 -08:00
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.151 $
+ * $Revision: 1.154 $
  */
 
 #include <linux/config.h>
@@ -179,7 +179,7 @@
 	device->debug_area = debug_register(device->cdev->dev.bus_id, 0, 2,
 					    8 * sizeof (long));
 	debug_register_view(device->debug_area, &debug_sprintf_view);
-	debug_set_level(device->debug_area, DBF_ERR);
+	debug_set_level(device->debug_area, DBF_DEBUG);
 	DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created");
 
 	device->state = DASD_STATE_BASIC;
@@ -520,10 +520,6 @@
 	if ( magic == NULL || datasize > PAGE_SIZE ||
 	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
-	debug_text_event ( dasd_debug_area, 1, "ALLC");
-	debug_text_event ( dasd_debug_area, 1, magic);
-	debug_int_event ( dasd_debug_area, 1, cplength);
-	debug_int_event ( dasd_debug_area, 1, datasize);
 
 	cqr = kmalloc(sizeof(struct dasd_ccw_req), GFP_ATOMIC);
 	if (cqr == NULL)
@@ -570,10 +566,6 @@
 	if ( magic == NULL || datasize > PAGE_SIZE ||
 	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
-	debug_text_event ( dasd_debug_area, 1, "ALLC");
-	debug_text_event ( dasd_debug_area, 1, magic);
-	debug_int_event ( dasd_debug_area, 1, cplength);
-	debug_int_event ( dasd_debug_area, 1, datasize);
 
 	size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
 	if (cplength > 0)
@@ -623,8 +615,6 @@
 		clear_normalized_cda(ccw);
 	} while (ccw++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
 #endif
-	debug_text_event ( dasd_debug_area, 1, "FREE");
-	debug_int_event ( dasd_debug_area, 1, (long) cqr);
 	if (cqr->cpaddr != NULL)
 		kfree(cqr->cpaddr);
 	if (cqr->data != NULL)
@@ -638,8 +628,6 @@
 {
 	unsigned long flags;
 
-	debug_text_event(dasd_debug_area, 1, "FREE");
-	debug_int_event(dasd_debug_area, 1, (long) cqr);
 	spin_lock_irqsave(&device->mem_lock, flags);
 	dasd_free_chunk(&device->ccw_chunks, cqr);
 	spin_unlock_irqrestore(&device->mem_lock, flags);
@@ -696,6 +684,9 @@
 			} else
 				cqr->status = DASD_CQR_FAILED;
 			cqr->stopclk = get_clock();
+			DBF_DEV_EVENT(DBF_DEBUG, device,
+				      "terminate cqr %p successful",
+				      cqr);
 			break;
 		case -ENODEV:
 			DBF_DEV_EVENT(DBF_ERR, device, "%s",
@@ -754,6 +745,8 @@
 	switch (rc) {
 	case 0:
 		cqr->status = DASD_CQR_IN_IO;
+		DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+			      "start_IO: request %p started successful");
 		break;
 	case -EBUSY:
 		DBF_DEV_EVENT(DBF_ERR, device, "%s",
@@ -964,8 +957,8 @@
 			cdev->dev.bus_id, cqr->status);
 		return;
 	}
-	DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x",
-		      ((irb->scsw.cstat << 8) | irb->scsw.dstat));
+	DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
+		      ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr);
 
  	/* Find out the appropriate era_action. */
 	if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) 
@@ -1080,7 +1073,8 @@
 				cqr->stopclk = get_clock();
 			} else {
 				if (cqr->irb.esw.esw0.erw.cons) {
-					erp_fn = device->discipline->erp_action(cqr);
+					erp_fn = device->discipline->
+						erp_action(cqr);
 					erp_fn(cqr);
 				} else
 					dasd_default_erp_action(cqr);
@@ -1153,10 +1147,9 @@
 		req = elv_next_request(queue);
 		if (test_bit(DASD_FLAG_RO, &device->flags) &&
 		    rq_data_dir(req) == WRITE) {
-			DBF_EVENT(DBF_ERR,
-				  "(%s) Rejecting write request %p",
-				  device->cdev->dev.bus_id,
-				  req);
+			DBF_DEV_EVENT(DBF_ERR, device,
+				      "Rejecting write request %p",
+				      req);
 			blkdev_dequeue_request(req);
 			dasd_end_request(req, 0);
 			continue;
@@ -1170,10 +1163,10 @@
 		if (IS_ERR(cqr)) {
 			if (PTR_ERR(cqr) == -ENOMEM)
 				break;	/* terminate request queue loop */
-			DBF_EVENT(DBF_ERR,
-				  "(%s) CCW creation failed on request %p",
-				  device->cdev->dev.bus_id,
-				  req);
+			DBF_DEV_EVENT(DBF_ERR, device,
+				      "CCW creation failed (rc=%ld) "
+				      "on request %p",
+				      PTR_ERR(cqr), req);
 			blkdev_dequeue_request(req);
 			dasd_end_request(req, 0);
 			continue;
@@ -1678,9 +1671,8 @@
 	}
 
 	if (dasd_probeonly) {
-		MESSAGE(KERN_INFO,
-			"No access to device %s due to probeonly mode",
-			disk->disk_name);
+		DEV_MESSAGE(KERN_INFO, device, "%s",
+			    "No access to device due to probeonly mode");
 		rc = -EPERM;
 		goto out;
 	}
@@ -1970,8 +1962,8 @@
 		rc = -ENOMEM;
 		goto failed;
 	}
-	debug_register_view(dasd_debug_area, &debug_hex_ascii_view);
-	debug_set_level(dasd_debug_area, DBF_ERR);
+	debug_register_view(dasd_debug_area, &debug_sprintf_view);
+	debug_set_level(dasd_debug_area, DBF_DEBUG);
 
 	DBF_EVENT(DBF_EMERG, "%s", "debug area created");
 
diff -Nru a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
--- a/drivers/s390/block/dasd_3990_erp.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/s390/block/dasd_3990_erp.c	2005-01-19 13:44:47 -08:00
@@ -5,7 +5,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
  *
- * $Revision: 1.34 $
+ * $Revision: 1.36 $
  */
 
 #include <linux/timer.h>
@@ -20,9 +20,9 @@
 
 
 struct DCTL_data {
-	unsigned char subcommand;	/* e.g Inhibit Write, Enable Write,... */
-	unsigned char modifier;	/* Subcommand modifier		       */
-	unsigned short res;	/* reserved */
+	unsigned char subcommand;  /* e.g Inhibit Write, Enable Write,... */
+	unsigned char modifier;	   /* Subcommand modifier */
+	unsigned short res;	   /* reserved */
 } __attribute__ ((packed));
 
 /*
@@ -422,7 +422,8 @@
  *   Setup ERP to do the ERP action 4 (see Reference manual).
  *   Set the current request to PENDING to block the CQR queue for that device
  *   until the state change interrupt appears.
- *   Use a timer (20 seconds) to retry the cqr if the interrupt is still missing.
+ *   Use a timer (20 seconds) to retry the cqr if the interrupt is still
+ *   missing.
  *
  *  PARAMETER
  *   sense		sense data of the actual error
@@ -443,9 +444,8 @@
 	/* interrupt (this enables easier enqueing of the cqr)	    */
 	if (erp->function != dasd_3990_erp_action_4) {
 
-		DEV_MESSAGE(KERN_INFO, device,
-			    "dasd_3990_erp_action_4: first time retry"
-			    "%s", " ");
+		DEV_MESSAGE(KERN_INFO, device, "%s",
+			    "dasd_3990_erp_action_4: first time retry");
 
 		erp->retries = 256;
 		erp->function = dasd_3990_erp_action_4;
@@ -826,7 +826,7 @@
 		}
 		break;
 
-	case 0x50:		/* Format 5 - Data Check with displacement information */
+	case 0x50:  /* Format 5 - Data Check with displacement information */
 		switch (msg_no) {
 		case 0x00:
 			DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -871,7 +871,7 @@
 		}
 		break;
 
-	case 0x60:		/* Format 6 - Usage Statistics/Overrun Errors */
+	case 0x60:  /* Format 6 - Usage Statistics/Overrun Errors */
 		switch (msg_no) {
 		case 0x00:
 			DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -911,7 +911,7 @@
 		}
 		break;
 
-	case 0x70:		/* Format 7 - Device Connection Control Checks */
+	case 0x70:  /* Format 7 - Device Connection Control Checks */
 		switch (msg_no) {
 		case 0x00:
 			DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -988,7 +988,7 @@
 		}
 		break;
 
-	case 0x80:		/* Format 8 - Additional Device Equipment Checks */
+	case 0x80:  /* Format 8 - Additional Device Equipment Checks */
 		switch (msg_no) {
 		case 0x00:	/* No Message */
 		case 0x01:
@@ -1041,7 +1041,7 @@
 		}
 		break;
 
-	case 0x90:		/* Format 9 - Device Read, Write, and Seek Checks */
+	case 0x90:  /* Format 9 - Device Read, Write, and Seek Checks */
 		switch (msg_no) {
 		case 0x00:
 			break;	/* No Message */
@@ -2159,7 +2159,7 @@
 			erp = dasd_3990_erp_int_req(erp);
 			break;
 
-		case 0x0F:	/* length mismatch during update write command */
+		case 0x0F:  /* length mismatch during update write command */
 			DEV_MESSAGE(KERN_ERR, device, "%s",
 				    "update write command error - should not "
 				    "happen;\n"
@@ -2170,7 +2170,7 @@
 			erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
 			break;
 
-		case 0x10:	/* logging required for other channel program */
+		case 0x10:  /* logging required for other channel program */
 			erp = dasd_3990_erp_action_10_32(erp, sense);
 			break;
 
@@ -2197,8 +2197,8 @@
 
 			/* not possible to handle this situation in Linux */
 			panic
-			    ("Invalid data - No way to inform appliction about "
-			     "the possibly incorret data");
+			    ("Invalid data - No way to inform application "
+			     "about the possibly incorrect data");
 			break;
 
 		case 0x1D:	/* state-change pending */
@@ -2263,11 +2263,10 @@
 		/* inspect the 32 byte sense data */
 		erp_new = dasd_3990_erp_inspect_32(erp, sense);
 
-	}			/* end distinguish between 24 and 32 byte sense data */
+	}	/* end distinguish between 24 and 32 byte sense data */
 
 	return erp_new;
-
-}				/* END dasd_3990_erp_inspect */
+}
 
 /*
  * DASD_3990_ERP_ADD_ERP
@@ -2520,7 +2519,8 @@
 		erp = dasd_3990_erp_compound(erp, sense);
 
 	} else {
-		/* no retry left and no additional special handling necessary */
+		/* No retry left and no additional special handling */
+		/*necessary */
 		DEV_MESSAGE(KERN_ERR, device,
 			    "no retries left for erp %p - "
 			    "set status to FAILED", erp);
diff -Nru a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
--- a/drivers/s390/block/dasd_devmap.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/s390/block/dasd_devmap.c	2005-01-19 13:44:46 -08:00
@@ -11,7 +11,7 @@
  * functions may not be called from interrupt context. In particular
  * dasd_get_device is a no-no from interrupt context.
  *
- * $Revision: 1.35 $
+ * $Revision: 1.37 $
  */
 
 #include <linux/config.h>
@@ -70,7 +70,6 @@
  * strings when running as a module.
  */
 static char *dasd[256];
-
 /*
  * Single spinlock to protect devmap structures and lists.
  */
@@ -485,7 +484,8 @@
 
 	devmap = dasd_find_busid(cdev->dev.bus_id);
 	if (IS_ERR(devmap))
-		devmap = dasd_add_busid(cdev->dev.bus_id, DASD_FEATURE_DEFAULT);
+		devmap = dasd_add_busid(cdev->dev.bus_id,
+					DASD_FEATURE_DEFAULT);
 	return devmap;
 }
 
diff -Nru a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
--- a/drivers/s390/block/dasd_diag.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/s390/block/dasd_diag.c	2005-01-19 13:44:45 -08:00
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.40 $
+ * $Revision: 1.42 $
  */
 
 #include <linux/config.h>
@@ -138,7 +138,7 @@
 
 	rc = dia250(&private->iob, RW_BIO);
 	if (rc > 8) {
-		MESSAGE(KERN_WARNING, "dia250 returned CC %d", rc);
+		DEV_MESSAGE(KERN_WARNING, device, "dia250 returned CC %d", rc);
 		cqr->status = DASD_CQR_ERROR;
 	} else if (rc == 0) {
 		cqr->status = DASD_CQR_DONE;
@@ -201,8 +201,9 @@
 				if (dasd_start_diag(next) == 0)
 					expires = next->expires;
 				else
-					MESSAGE(KERN_WARNING, "%s",
-						"Interrupt fastpath failed!");
+					DEV_MESSAGE(KERN_WARNING, device, "%s",
+						    "Interrupt fastpath "
+						    "failed!");
 			}
 		}
 	} else 
@@ -231,7 +232,7 @@
 	if (private == NULL) {
 		private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
 		if (private == NULL) {
-			MESSAGE(KERN_WARNING, "%s",
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
 				"memory allocation failed for private data");
 			return -ENOMEM;
 		}
@@ -258,11 +259,11 @@
 		return -ENOTSUPP;
 	}
 
-	DBF_EVENT(DBF_INFO,
-		  "%04X: %04X on real %04X/%02X",
-		  rdc_data->dev_nr,
-		  rdc_data->vdev_type,
-		  rdc_data->rdev_type, rdc_data->rdev_model);
+	DBF_DEV_EVENT(DBF_INFO, device,
+		      "%04X: %04X on real %04X/%02X",
+		      rdc_data->dev_nr,
+		      rdc_data->vdev_type,
+		      rdc_data->rdev_type, rdc_data->rdev_model);
 
 	/* terminate all outstanding operations */
 	mdsk_term_io(device);
@@ -270,8 +271,8 @@
 	/* figure out blocksize of device */
 	label = (long *) get_zeroed_page(GFP_KERNEL);
 	if (label == NULL)  {
-		MESSAGE(KERN_WARNING, "%s",
-			"No memory to allocate initialization request");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "No memory to allocate initialization request");
 		return -ENOMEM;
 	}
 	/* try all sizes - needed for ECKD devices */
@@ -451,20 +452,8 @@
 dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
 		     struct irb *stat)
 {
-	char *page;
-
-	page = (char *) get_zeroed_page(GFP_KERNEL);
-	if (page == NULL) {
-		MESSAGE(KERN_ERR, "%s", "No memory to dump sense data");
-		return;
-	}
-	sprintf(page, KERN_WARNING PRINTK_HEADER
-		"device %s: I/O status report:\n",
-		device->cdev->dev.bus_id);
-
-	MESSAGE(KERN_ERR, "Sense data:\n%s", page);
-
-	free_page((unsigned long) page);
+	DEV_MESSAGE(KERN_ERR, device, "%s",
+		    "dump sense not available for DIAG data");
 }
 
 /*
@@ -500,9 +489,10 @@
 dasd_diag_init(void)
 {
 	if (!MACHINE_IS_VM) {
-		MESSAGE(KERN_INFO,
-			"Machine is not VM: %s discipline not initializing",
-			dasd_diag_discipline.name);
+		MESSAGE_LOG(KERN_INFO,
+			    "Machine is not VM: %s "
+			    "discipline not initializing",
+			    dasd_diag_discipline.name);
 		return -EINVAL;
 	}
 	ASCEBC(dasd_diag_discipline.ebcname, 4);
@@ -517,9 +507,10 @@
 dasd_diag_cleanup(void)
 {
 	if (!MACHINE_IS_VM) {
-		MESSAGE(KERN_INFO,
-			"Machine is not VM: %s discipline not initializing",
-			dasd_diag_discipline.name);
+		MESSAGE_LOG(KERN_INFO,
+			    "Machine is not VM: %s "
+			    "discipline not cleaned",
+			    dasd_diag_discipline.name);
 		return;
 	}
 	unregister_external_interrupt(0x2603, dasd_ext_handler);
diff -Nru a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
--- a/drivers/s390/block/dasd_eckd.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/s390/block/dasd_eckd.c	2005-01-19 13:44:45 -08:00
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.66 $
+ * $Revision: 1.68 $
  */
 
 #include <linux/config.h>
@@ -37,9 +37,12 @@
 
 #define ECKD_C0(i) (i->home_bytes)
 #define ECKD_F(i) (i->formula)
-#define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):(i->factors.f_0x02.f1))
-#define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):(i->factors.f_0x02.f2))
-#define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):(i->factors.f_0x02.f3))
+#define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):\
+		    (i->factors.f_0x02.f1))
+#define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):\
+		    (i->factors.f_0x02.f2))
+#define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):\
+		    (i->factors.f_0x02.f3))
 #define ECKD_F4(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f4):0)
 #define ECKD_F5(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f5):0)
 #define ECKD_F6(i) (i->factor6)
@@ -151,7 +154,6 @@
 		bpr = fl1 + fl2;
 		break;
 	default:
-		MESSAGE(KERN_ERR, "unknown formula%d", rdc->formula);
 		bpr = 0;
 		break;
 	}
@@ -209,8 +211,8 @@
         /* switch on System Time Stamp - needed for XRC Support */
         if (private->rdc_data.facilities.XRC_supported) {
                 
-                data->ga_extended |= 0x08;   /* switch on 'Time Stamp Valid'   */
-                data->ga_extended |= 0x02;   /* switch on 'Extended Parameter' */
+                data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid'   */
+                data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
                 
                 data->ep_sys_time = get_clock ();
                 
@@ -272,7 +274,7 @@
                 check_XRC (ccw, data, device);
 		break;
 	default:
-		MESSAGE(KERN_ERR, "unknown opcode 0x%x", cmd);
+		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
 		break;
 	}
 
@@ -318,7 +320,7 @@
 				
 	private = (struct dasd_eckd_private *) device->private;
 
-	DBF_EVENT(DBF_INFO,
+	DBF_DEV_EVENT(DBF_INFO, device,
 		  "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d",
 		  trk, rec_on_trk, no_rec, cmd, reclen);
 
@@ -400,7 +402,7 @@
 		data->operation.operation = 0x0b;
 		break;
 	default:
-		MESSAGE(KERN_ERR, "unknown opcode 0x%x", cmd);
+		DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
 	}
 	data->seek_addr.cyl = data->search_arg.cyl =
 		trk / private->rdc_data.trk_per_cyl;
@@ -458,8 +460,9 @@
 		private = kmalloc(sizeof(struct dasd_eckd_private),
 				  GFP_KERNEL | GFP_DMA);
 		if (private == NULL) {
-			MESSAGE(KERN_WARNING, "%s",
-				"memory allocation failed for private data");
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
+				    "memory allocation failed for private "
+				    "data");
 			return -ENOMEM;
 		}
 		device->private = (void *) private;
@@ -474,8 +477,9 @@
 	rdc_data = (void *) &(private->rdc_data);
 	rc = read_dev_chars(device->cdev, &rdc_data, 64);
 	if (rc) {
-		MESSAGE(KERN_WARNING,
-			"Read device characteristics returned error %d", rc);
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "Read device characteristics returned error %d",
+			    rc);
 		return rc;
 	}
 
@@ -492,19 +496,20 @@
 	/* Read Configuration Data */
 	rc = read_conf_data(device->cdev, &conf_data, &conf_len);
 	if (rc && rc != -EOPNOTSUPP) {	/* -EOPNOTSUPP is ok */
-		MESSAGE(KERN_WARNING,
-			"Read configuration data returned error %d", rc);
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "Read configuration data returned error %d", rc);
 		return rc;
 	}
 	if (conf_data == NULL) {
-		MESSAGE(KERN_WARNING, "%s", "No configuration data retrieved");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "No configuration data retrieved");
 		return 0;	/* no errror */
 	}
 	if (conf_len != sizeof (struct dasd_eckd_confdata)) {
-		MESSAGE(KERN_WARNING,
-			"sizes of configuration data mismatch"
-			"%d (read) vs %ld (expected)",
-			conf_len, sizeof (struct dasd_eckd_confdata));
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "sizes of configuration data mismatch"
+			    "%d (read) vs %ld (expected)",
+			    conf_len, sizeof (struct dasd_eckd_confdata));
 
 		kfree(conf_data); /* allocated by read_conf_data() */
 		return 0;	/* no errror */
@@ -746,8 +751,9 @@
 		return ERR_PTR(-EINVAL);
 	}
 	if (dasd_check_blocksize(fdata->blksize) != 0) {
-		MESSAGE(KERN_WARNING, "Invalid blocksize %d...terminating!",
-			fdata->blksize);
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "Invalid blocksize %d...terminating!",
+			    fdata->blksize);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -783,7 +789,8 @@
 			sizeof(struct eckd_count);
 		break;
 	default:
-		MESSAGE(KERN_WARNING, "Invalid flags 0x%x.", fdata->intensity);
+		DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
+			    fdata->intensity);
 		return ERR_PTR(-EINVAL);
 	}
 	/* Allocate the format ccw request. */
@@ -918,8 +925,8 @@
 		return dasd_9343_erp_examine(cqr, irb);
 	case 0x3880:
 	default:
-		MESSAGE(KERN_WARNING, "%s",
-			"default (unknown CU type) - RECOVERABLE return");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "default (unknown CU type) - RECOVERABLE return");
 		return dasd_era_recover;
 	}
 }
@@ -937,7 +944,6 @@
 	case 0x1750:
 		return dasd_3990_erp_action;
 	case 0x9343:
-		/* Return dasd_9343_erp_action; */
 	case 0x3880:
 	default:
 		return dasd_default_erp_action;
@@ -995,7 +1001,8 @@
 				return ERR_PTR(-EINVAL);
 			count += bv->bv_len >> (device->s2b_shift + 9);
 #if defined(CONFIG_ARCH_S390X)
-			if (idal_is_needed (page_address(bv->bv_page), bv->bv_len))
+			if (idal_is_needed (page_address(bv->bv_page),
+					    bv->bv_len))
 				cidaw += bv->bv_len >> (device->s2b_shift + 9);
 #endif
 		}
@@ -1193,8 +1200,8 @@
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		MESSAGE(KERN_WARNING, "%s",
-			"Could not allocate initialization request");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
@@ -1237,8 +1244,8 @@
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		MESSAGE(KERN_WARNING, "%s",
-			"Could not allocate initialization request");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
@@ -1280,8 +1287,8 @@
 	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
 				   1, 32, device);
 	if (IS_ERR(cqr)) {
-		MESSAGE(KERN_WARNING, "%s",
-			"Could not allocate initialization request");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
 	cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
@@ -1324,8 +1331,8 @@
 				    sizeof (struct dasd_rssd_perf_stats_t)),
 				   device);
 	if (IS_ERR(cqr)) {
-		MESSAGE(KERN_WARNING, "%s",
-			"Could not allocate initialization request");
+		DEV_MESSAGE(KERN_WARNING, device, "%s",
+			    "Could not allocate initialization request");
 		return PTR_ERR(cqr);
 	}
 	cqr->device = device;
@@ -1422,58 +1429,47 @@
 			   sizeof (struct attrib_data_t))) {
 		return -EFAULT;
 	}
-
 	private = (struct dasd_eckd_private *) device->private;
-
 	private->attrib = attrib;
 
-	DBF_DEV_EVENT(DBF_ERR, device,
-		      "cache operation mode set to "
-		      "%x (%i cylinder prestage)",
-		      private->attrib.operation, private->attrib.nr_cyl);
-	
+	DEV_MESSAGE(KERN_INFO, device,
+		    "cache operation mode set to %x (%i cylinder prestage)",
+		    private->attrib.operation, private->attrib.nr_cyl);
 	return 0;
 }
 
+/*
+ * Print sense data and related channel program.
+ * Parts are printed because printk buffer is only 1024 bytes.
+ */
 static void
 dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
 		     struct irb *irb)
 {
-
 	char *page;
-	struct ccw1 *act;
-	int len, sl, sct;
+	struct ccw1 *act, *end, *last;
+	int len, sl, sct, count;
 
 	page = (char *) get_zeroed_page(GFP_ATOMIC);
 	if (page == NULL) {
-		MESSAGE(KERN_ERR, "%s", "No memory to dump sense data");
+		DEV_MESSAGE(KERN_ERR, device, " %s",
+			    "No memory to dump sense data");
 		return;
 	}
 	len = sprintf(page, KERN_ERR PRINTK_HEADER
-		      "device %s: I/O status report:\n",
+		      " I/O status report for device %s:\n",
 		      device->cdev->dev.bus_id);
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-		       "in req: %p CS: 0x%02X DS: 0x%02X\n", req,
+		       " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
 		       irb->scsw.cstat, irb->scsw.dstat);
 	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-		       "Failing CCW: %p\n", 
+		       " device %s: Failing CCW: %p\n",
+		       device->cdev->dev.bus_id,
 		       (void *) (addr_t) irb->scsw.cpa);
-	act = req->cpaddr;
-	do {
-		DBF_EVENT(DBF_INFO,
-			  "CCW %p: %08X %08X",
-			  act, ((int *) act)[0], ((int *) act)[1]);
-		DBF_EVENT(DBF_INFO,
-			  "DAT: %08X %08X %08X %08X",
-			  ((int *) (addr_t) act->cda)[0],
-			  ((int *) (addr_t) act->cda)[1],
-			  ((int *) (addr_t) act->cda)[2],
-			  ((int *) (addr_t) act->cda)[3]);
-	} while (act++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
 	if (irb->esw.esw0.erw.cons) {
 		for (sl = 0; sl < 4; sl++) {
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-				       "Sense(hex) %2d-%2d:",
+				       " Sense(hex) %2d-%2d:",
 				       (8 * sl), ((8 * sl) + 7));
 
 			for (sct = 0; sct < 8; sct++) {
@@ -1486,23 +1482,86 @@
 		if (irb->ecw[27] & DASD_SENSE_BIT_0) {
 			/* 24 Byte Sense Data */
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-				       "24 Byte: %x MSG %x, %s MSGb to SYSOP\n",
+				       " 24 Byte: %x MSG %x, "
+				       "%s MSGb to SYSOP\n",
 				       irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
 				       irb->ecw[1] & 0x10 ? "" : "no");
 		} else {
 			/* 32 Byte Sense Data */
 			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-				       "32 Byte: Format: %x "
+				       " 32 Byte: Format: %x "
 				       "Exception class %x\n",
 				       irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
 		}
 	} else {
 	        len += sprintf(page + len, KERN_ERR PRINTK_HEADER
-			       "SORRY - NO VALID SENSE AVAILABLE\n");
+			       " SORRY - NO VALID SENSE AVAILABLE\n");
 	}
+	MESSAGE_LOG(KERN_ERR, "%s",
+		    page + sizeof(KERN_ERR PRINTK_HEADER));
 
-	MESSAGE(KERN_ERR, "Sense data:\n%s", page);
-
+	/* dump the Channel Program */
+	/* print first CCWs (maximum 8) */
+	act = req->cpaddr;
+        for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
+	end = min(act + 8, last);
+	len = sprintf(page, KERN_ERR PRINTK_HEADER
+		      " Related CP in req: %p\n", req);
+	while (act <= end) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+	MESSAGE_LOG(KERN_ERR, "%s",
+		    page + sizeof(KERN_ERR PRINTK_HEADER));
+
+	/* print failing CCW area */
+	len = 0;
+	if (act <  ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) {
+		act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
+	}
+	end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last);
+	while (act <= end) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+
+	/* print last CCWs */
+	if (act <  last - 2) {
+		act = last - 2;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
+	}
+	while (act <= last) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+	if (len > 0)
+		MESSAGE_LOG(KERN_ERR, "%s",
+			    page + sizeof(KERN_ERR PRINTK_HEADER));
 	free_page((unsigned long) page);
 }
 
diff -Nru a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
--- a/drivers/s390/block/dasd_eckd.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/s390/block/dasd_eckd.h	2005-01-19 13:44:46 -08:00
@@ -5,15 +5,15 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.8 $
+ * $Revision: 1.9 $
  */
 
 #ifndef DASD_ECKD_H
 #define DASD_ECKD_H
 
-/*******************************************************************************
+/*****************************************************************************
  * SECTION: CCW Definitions
- ******************************************************************************/
+ ****************************************************************************/
 #define DASD_ECKD_CCW_WRITE		 0x05
 #define DASD_ECKD_CCW_READ		 0x06
 #define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09
@@ -45,9 +45,9 @@
  */
 #define PSF_ORDER_PRSSD			 0x18
 
-/*******************************************************************************
+/*****************************************************************************
  * SECTION: Type Definitions
- ******************************************************************************/
+ ****************************************************************************/
 
 struct eckd_count {
 	__u16 cyl;
@@ -112,7 +112,7 @@
 	__u8 ga_extended;	/* Global Attributes Extended	*/
 	struct ch_t beg_ext;
 	struct ch_t end_ext;
-	unsigned long long ep_sys_time; /* Extended Parameter - System Time Stamp */
+	unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
 	__u8 ep_format;        /* Extended Parameter format byte       */
 	__u8 ep_prio;          /* Extended Parameter priority I/O byte */
 	__u8 ep_reserved[6];   /* Extended Parameter Reserved          */
diff -Nru a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
--- a/drivers/s390/block/dasd_erp.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/s390/block/dasd_erp.c	2005-01-19 13:44:46 -08:00
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.12 $
+ * $Revision: 1.13 $
  */
 
 #include <linux/config.h>
@@ -36,10 +36,6 @@
 	if ( magic == NULL || datasize > PAGE_SIZE ||
 	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
 		BUG();
-	debug_text_event ( dasd_debug_area, 1, "ALLC");
-	debug_text_event ( dasd_debug_area, 1, magic);
-	debug_int_event ( dasd_debug_area, 1, cplength);
-	debug_int_event ( dasd_debug_area, 1, datasize);
 
 	size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
 	if (cplength > 0)
@@ -77,8 +73,6 @@
 {
 	unsigned long flags;
 
-	debug_text_event(dasd_debug_area, 1, "FREE");
-	debug_int_event(dasd_debug_area, 1, (long) cqr);
 	spin_lock_irqsave(&device->mem_lock, flags);
 	dasd_free_chunk(&device->erp_chunks, cqr);
 	spin_unlock_irqrestore(&device->mem_lock, flags);
@@ -105,7 +99,6 @@
         } else {
                 DEV_MESSAGE (KERN_WARNING, device, "%s",
 			     "default ERP called (NO retry left)");
-		
 		cqr->status = DASD_CQR_FAILED;
 		cqr->stopclk = get_clock ();
         }
diff -Nru a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
--- a/drivers/s390/block/dasd_fba.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/s390/block/dasd_fba.c	2005-01-19 13:44:47 -08:00
@@ -4,7 +4,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.37 $
+ * $Revision: 1.39 $
  */
 
 #include <linux/config.h>
@@ -134,8 +134,9 @@
 	if (private == NULL) {
 		private = kmalloc(sizeof(struct dasd_fba_private), GFP_KERNEL);
 		if (private == NULL) {
-			MESSAGE(KERN_WARNING, "%s",
-				"memory allocation failed for private data");
+			DEV_MESSAGE(KERN_WARNING, device, "%s",
+				    "memory allocation failed for private "
+				    "data");
 			return -ENOMEM;
 		}
 		device->private = (void *) private;
@@ -144,8 +145,9 @@
 	rdc_data = (void *) &(private->rdc_data);
 	rc = read_dev_chars(device->cdev, &rdc_data, 32);
 	if (rc) {
-		MESSAGE(KERN_WARNING,
-			"Read device characteristics returned error %d", rc);
+		DEV_MESSAGE(KERN_WARNING, device,
+			    "Read device characteristics returned error %d",
+			    rc);
 		return rc;
 	}
 
@@ -227,8 +229,8 @@
 	if (cqr->function == dasd_default_erp_action)
 		return dasd_default_erp_postaction;
 
-	MESSAGE(KERN_WARNING, "unknown ERP action %p", cqr->function);
-
+	DEV_MESSAGE(KERN_WARNING, cqr->device, "unknown ERP action %p",
+		    cqr->function);
 	return NULL;
 }
 
@@ -270,7 +272,8 @@
 				return ERR_PTR(-EINVAL);
 			count += bv->bv_len >> (device->s2b_shift + 9);
 #if defined(CONFIG_ARCH_S390X)
-			if (idal_is_needed (page_address(bv->bv_page), bv->bv_len))
+			if (idal_is_needed (page_address(bv->bv_page),
+					    bv->bv_len))
 				cidaw += bv->bv_len / blksize;
 #endif
 		}
@@ -423,18 +426,107 @@
 		    struct irb *irb)
 {
 	char *page;
+	struct ccw1 *act, *end, *last;
+	int len, sl, sct, count;
 
-	page = (char *) get_zeroed_page(GFP_KERNEL);
+	page = (char *) get_zeroed_page(GFP_ATOMIC);
 	if (page == NULL) {
-		MESSAGE(KERN_ERR, "%s", "No memory to dump sense data");
+		DEV_MESSAGE(KERN_ERR, device, " %s",
+			    "No memory to dump sense data");
 		return;
 	}
-	sprintf(page, KERN_WARNING PRINTK_HEADER
-		"device %s: I/O status report:\n",
-		device->cdev->dev.bus_id);
+	len = sprintf(page, KERN_ERR PRINTK_HEADER
+		      " I/O status report for device %s:\n",
+		      device->cdev->dev.bus_id);
+	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+		       " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
+		       irb->scsw.cstat, irb->scsw.dstat);
+	len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+		       " device %s: Failing CCW: %p\n",
+		       device->cdev->dev.bus_id,
+		       (void *) (addr_t) irb->scsw.cpa);
+	if (irb->esw.esw0.erw.cons) {
+		for (sl = 0; sl < 4; sl++) {
+			len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+				       " Sense(hex) %2d-%2d:",
+				       (8 * sl), ((8 * sl) + 7));
+
+			for (sct = 0; sct < 8; sct++) {
+				len += sprintf(page + len, " %02x",
+					       irb->ecw[8 * sl + sct]);
+			}
+			len += sprintf(page + len, "\n");
+		}
+	} else {
+	        len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " SORRY - NO VALID SENSE AVAILABLE\n");
+	}
+	MESSAGE_LOG(KERN_ERR, "%s",
+		    page + sizeof(KERN_ERR PRINTK_HEADER));
+
+	/* dump the Channel Program */
+	/* print first CCWs (maximum 8) */
+	act = req->cpaddr;
+        for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
+	end = min(act + 8, last);
+	len = sprintf(page, KERN_ERR PRINTK_HEADER
+		      " Related CP in req: %p\n", req);
+	while (act <= end) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+	MESSAGE_LOG(KERN_ERR, "%s",
+		    page + sizeof(KERN_ERR PRINTK_HEADER));
 
-	MESSAGE(KERN_ERR, "Sense data:\n%s", page);
 
+	/* print failing CCW area */
+	len = 0;
+	if (act <  ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) {
+		act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
+	}
+	end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last);
+	while (act <= end) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+
+	/* print last CCWs */
+	if (act <  last - 2) {
+		act = last - 2;
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
+	}
+	while (act <= last) {
+		len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+			       " CCW %p: %08X %08X DAT:",
+			       act, ((int *) act)[0], ((int *) act)[1]);
+		for (count = 0; count < 32 && count < act->count;
+		     count += sizeof(int))
+			len += sprintf(page + len, " %08X",
+				       ((int *) (addr_t) act->cda)
+				       [(count>>2)]);
+		len += sprintf(page + len, "\n");
+		act++;
+	}
+	if (len > 0)
+		MESSAGE_LOG(KERN_ERR, "%s",
+			    page + sizeof(KERN_ERR PRINTK_HEADER));
 	free_page((unsigned long) page);
 }
 
diff -Nru a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
--- a/drivers/s390/block/dasd_int.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/s390/block/dasd_int.h	2005-01-19 13:44:47 -08:00
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.61 $
+ * $Revision: 1.63 $
  */
 
 #ifndef DASD_INT_H
@@ -150,6 +150,18 @@
 	DBF_EVENT(DBF_ALERT, d_string, d_args); \
 } while(0)
 
+/* messages to be written via klogd only */
+#define DEV_MESSAGE_LOG(d_loglevel,d_device,d_string,d_args...)\
+do { \
+	printk(d_loglevel PRINTK_HEADER " %s: " d_string "\n", \
+	       d_device->cdev->dev.bus_id, d_args); \
+} while(0)
+
+#define MESSAGE_LOG(d_loglevel,d_string,d_args...)\
+do { \
+	printk(d_loglevel PRINTK_HEADER " " d_string "\n", d_args); \
+} while(0)
+
 struct dasd_ccw_req {
 	unsigned int magic;		/* Eye catcher */
         struct list_head list;		/* list_head for request queueing. */
@@ -520,7 +532,8 @@
 /* externals in dasd_erp.c */
 struct dasd_ccw_req *dasd_default_erp_action(struct dasd_ccw_req *);
 struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *);
-struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int, struct dasd_device *);
+struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
+					    struct dasd_device *);
 void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
 void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
 void dasd_log_ccw(struct dasd_ccw_req *, int, __u32);
diff -Nru a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
--- a/drivers/s390/block/dasd_ioctl.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/s390/block/dasd_ioctl.c	2005-01-19 13:44:47 -08:00
@@ -257,8 +257,9 @@
 		      fdata->stop_unit, fdata->blksize, fdata->intensity);
 
 	/* Since dasdfmt keeps the device open after it was disabled,
-	 * there still exists an inode for this device. We must update i_blkbits,
-	 * otherwise we might get errors when enabling the device later.
+	 * there still exists an inode for this device.
+	 * We must update i_blkbits, otherwise we might get errors when
+	 * enabling the device later.
 	 */
 	if (fdata->start_unit == 0) {
 		struct block_device *bdev = bdget_disk(device->gdp, 0);
diff -Nru a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
--- a/drivers/s390/block/dasd_proc.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/s390/block/dasd_proc.c	2005-01-19 13:44:46 -08:00
@@ -9,7 +9,7 @@
  *
  * /proc interface for the dasd driver.
  *
- * $Revision: 1.29 $
+ * $Revision: 1.30 $
  */
 
 #include <linux/config.h>
@@ -250,7 +250,7 @@
 	buffer = dasd_get_user_string(user_buf, user_len);
 	if (IS_ERR(buffer))
 		return PTR_ERR(buffer);
-	MESSAGE(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer);
+	MESSAGE_LOG(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer);
 
 	/* check for valid verbs */
 	for (str = buffer; isspace(*str); str++);
diff -Nru a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
--- a/drivers/s390/char/tty3270.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/s390/char/tty3270.c	2005-01-19 13:44:46 -08:00
@@ -706,6 +706,7 @@
 	if (!tp->freemem_pages)
 		goto out_tp;
 	INIT_LIST_HEAD(&tp->freemem);
+	init_timer(&tp->timer);
 	for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) {
 		tp->freemem_pages[pages] = (void *)
 			__get_free_pages(GFP_KERNEL|GFP_DMA, 0);
diff -Nru a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
--- a/drivers/s390/char/vmlogrdr.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/s390/char/vmlogrdr.c	2005-01-19 13:44:47 -08:00
@@ -403,7 +403,7 @@
 		goto not_connected;
 	}
 
-	return 0;
+ 	return nonseekable_open(inode, filp);
 
 not_connected:
 	iucv_unregister_program(logptr->iucv_handle);
diff -Nru a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
--- a/drivers/s390/cio/qdio.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/s390/cio/qdio.c	2005-01-19 13:44:47 -08:00
@@ -56,7 +56,7 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define VERSION_QDIO_C "$Revision: 1.94 $"
+#define VERSION_QDIO_C "$Revision: 1.98 $"
 
 /****************** MODULE PARAMETER VARIABLES ********************/
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -2043,6 +2043,7 @@
 				"installed.\n");
 		return -ENOENT;
 	}
+
 	/* Check for bits 107 and 108. */
 	if (!css_chsc_characteristics.scssc ||
 	    !css_chsc_characteristics.scsscf) {
@@ -2132,7 +2133,11 @@
 	/* enables the time delay disablement facility. Don't care
 	 * whether it is really there (i.e. we haven't checked for
 	 * it) */
-	scssc_area->word_with_d_bit = 0x10000000;
+	if (css_general_characteristics.aif_tdd)
+		scssc_area->word_with_d_bit = 0x10000000;
+	else
+		QDIO_PRINT_WARN("Time delay disablement facility " \
+				"not available\n");
 
 
 
diff -Nru a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
--- a/drivers/s390/net/iucv.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/s390/net/iucv.c	2005-01-19 13:44:45 -08:00
@@ -1,5 +1,5 @@
 /* 
- * $Id: iucv.c,v 1.41 2004/08/11 14:54:14 geraldsc Exp $
+ * $Id: iucv.c,v 1.42 2005/01/07 10:49:54 braunu Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.41 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.42 $
  *
  */
 
@@ -355,7 +355,7 @@
 static void
 iucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.41 $";
+	char vbuf[] = "$Revision: 1.42 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
@@ -2285,7 +2285,6 @@
 	irqdata = kmalloc(sizeof(iucv_irqdata), GFP_ATOMIC);
 	if (!irqdata) {
 		printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
-		irq_exit();
 		return;
 	}
 
diff -Nru a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
--- a/drivers/sbus/sbus.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/sbus/sbus.c	2005-01-19 13:44:48 -08:00
@@ -231,18 +231,20 @@
 		return;
 	}
 	sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges);
+#ifdef CONFIG_SPARC32
 	if (sparc_cpu_model == sun4d) {
 		struct linux_prom_ranges iounit_ranges[PROMREG_MAX];
 		int num_iounit_ranges;
 
-	len = prom_getproperty(parent_node, "ranges",
-				(char *) iounit_ranges,
-				sizeof (iounit_ranges));
+		len = prom_getproperty(parent_node, "ranges",
+				       (char *) iounit_ranges,
+				       sizeof (iounit_ranges));
 		if (len != -1) {
 			num_iounit_ranges = (len/sizeof(struct linux_prom_ranges));
 			prom_adjust_ranges (sbus->sbus_ranges, sbus->num_sbus_ranges, iounit_ranges, num_iounit_ranges);
 		}
 	}
+#endif
 }
 
 static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/Kconfig	2005-01-19 13:44:47 -08:00
@@ -791,7 +791,7 @@
 	  See <http://www.developer.ibm.com/welcome/netfinity/serveraid.html>
 	  for more information.  If this driver does not work correctly
 	  without modification please contact the author by email at
-	  ipslinux@adaptec.com.
+	  <ipslinux@adaptec.com>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ips.
@@ -1494,7 +1494,7 @@
 	  host adapter with one dummy SCSI disk. Each dummy disk uses kernel
 	  RAM as storage (i.e. it is a ramdisk). To save space when multiple
 	  dummy disks are simulated, they share the same kernel RAM for 
-	  their storage. See http://www.torque.net/sg/sdebug.html for more
+	  their storage. See <http://www.torque.net/sg/sdebug.html> for more
 	  information. This driver is primarily of use to those testing the
 	  SCSI and block subsystems. If unsure, say N.
 
@@ -1785,7 +1785,7 @@
 
           This driver is also available as a module. This module will be
           called zfcp. If you want to compile it as a module, say M here
-          and read Documentation/modules.txt.
+          and read <file:Documentation/modules.txt>.
 
 endmenu
 
diff -Nru a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
--- a/drivers/scsi/aacraid/commsup.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/aacraid/commsup.c	2005-01-19 13:44:47 -08:00
@@ -768,28 +768,6 @@
 	memset(cp, 0,  256);
 }
 
-
-/**
- *	aac_handle_aif		-	Handle a message from the firmware
- *	@dev: Which adapter this fib is from
- *	@fibptr: Pointer to fibptr from adapter
- *
- *	This routine handles a driver notify fib from the adapter and
- *	dispatches it to the appropriate routine for handling.
- */
-
-static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
-{
-	struct hw_fib * hw_fib = fibptr->hw_fib;
-	/*
-	 * Set the status of this FIB to be Invalid parameter.
-	 *
-	 *	*(u32 *)fib->data = ST_INVAL;
-	 */
-	*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
-	fib_adapter_complete(fibptr, sizeof(u32));
-}
-
 /**
  *	aac_command_thread	-	command processing thread
  *	@dev: Adapter to monitor
@@ -859,7 +837,6 @@
 			aifcmd = (struct aac_aifcmd *) hw_fib->data;
 			if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
 				/* Handle Driver Notify Events */
-				aac_handle_aif(dev, fib);
 				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
 				fib_adapter_complete(fib, sizeof(u32));
 			} else {
@@ -869,10 +846,6 @@
 				   
 				u32 time_now, time_last;
 				unsigned long flagv;
-				
-				/* Sniff events */
-				if (aifcmd->command == cpu_to_le32(AifCmdEventNotify))
-					aac_handle_aif(dev, fib);
 				
 				time_now = jiffies/HZ;
 
diff -Nru a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c
--- a/drivers/scsi/aic7xxx/aic7770_osm.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/aic7xxx/aic7770_osm.c	2005-01-19 13:44:47 -08:00
@@ -125,14 +125,8 @@
 		uint32_t eisa_id;
 		size_t	 id_size;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-		if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0)
-			continue;
-		request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx");
-#else
 		if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0)
 			continue;
-#endif
 
 		eisa_id = 0;
 		id_size = sizeof(eisa_id);
@@ -207,14 +201,8 @@
 	/*
 	 * Lock out other contenders for our i/o space.
 	 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-	if (check_region(port, AHC_EISA_IOSIZE) != 0)
-		return (ENOMEM);
-	request_region(port, AHC_EISA_IOSIZE, "aic7xxx");
-#else
 	if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
 		return (ENOMEM);
-#endif
 	ahc->tag = BUS_SPACE_PIO;
 	ahc->bsh.ioport = port;
 	return (0);
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h	2005-01-19 13:44:46 -08:00
@@ -831,8 +831,6 @@
 
 /******************************* PCI Routines *********************************/
 #ifdef CONFIG_PCI
-void			 ahc_power_state_change(struct ahc_softc *ahc,
-						ahc_power_state new_state);
 int			 ahc_linux_pci_init(void);
 void			 ahc_linux_pci_exit(void);
 int			 ahc_pci_map_registers(struct ahc_softc *ahc);
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c	2005-01-19 13:44:46 -08:00
@@ -42,12 +42,6 @@
 #include "aic7xxx_osm.h"
 #include "aic7xxx_pci.h"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-struct pci_device_id
-{
-};
-#endif
-
 static int	ahc_linux_pci_dev_probe(struct pci_dev *pdev,
 					const struct pci_device_id *ent);
 static int	ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc,
@@ -55,7 +49,6 @@
 static int	ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
 						 u_long *bus_addr,
 						 uint8_t __iomem **maddr);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static void	ahc_linux_pci_dev_remove(struct pci_dev *pdev);
 
 /* Define the macro locally since it's different for different class of chips.
@@ -169,7 +162,6 @@
 	} else
 		ahc_list_unlock(&l);
 }
-#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */
 
 static int
 ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -219,7 +211,6 @@
 	ahc = ahc_alloc(NULL, name);
 	if (ahc == NULL)
 		return (-ENOMEM);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	if (pci_enable_device(pdev)) {
 		ahc_free(ahc);
 		return (-ENODEV);
@@ -238,14 +229,12 @@
 		}
 		ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK;
 	}
-#endif
 	ahc->dev_softc = pci;
 	error = ahc_pci_config(ahc, entry);
 	if (error != 0) {
 		ahc_free(ahc);
 		return (-error);
 	}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	pci_set_drvdata(pdev, ahc);
 	if (aic7xxx_detect_complete) {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
@@ -256,39 +245,14 @@
 		return (-ENODEV);
 #endif
 	}
-#endif
 	return (0);
 }
 
 int
 ahc_linux_pci_init(void)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	/* Translate error or zero return into zero or one */
 	return pci_module_init(&aic7xxx_pci_driver) ? 0 : 1;
-#else
-	struct pci_dev *pdev;
-	u_int class;
-	int found;
-
-	/* If we don't have a PCI bus, we can't find any adapters. */
-	if (pci_present() == 0)
-		return (0);
-
-	found = 0;
-	pdev = NULL;
-	class = PCI_CLASS_STORAGE_SCSI << 8;
-	while ((pdev = pci_find_class(class, pdev)) != NULL) {
-		ahc_dev_softc_t pci;
-		int error;
-
-		pci = pdev;
-		error = ahc_linux_pci_dev_probe(pdev, /*pci_devid*/NULL);
-		if (error == 0)
-			found++;
-	}
-	return (found);
-#endif
 }
 
 void
@@ -303,22 +267,11 @@
 	if (aic7xxx_allow_memio == 0)
 		return (ENOMEM);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
 	*base = pci_resource_start(ahc->dev_softc, 0);
-#else
-	*base = ahc_pci_read_config(ahc->dev_softc, PCIR_MAPS, 4);
-	*base &= PCI_BASE_ADDRESS_IO_MASK;
-#endif
 	if (*base == 0)
 		return (ENOMEM);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-	if (check_region(*base, 256) != 0)
-		return (ENOMEM);
-	request_region(*base, 256, "aic7xxx");
-#else
 	if (request_region(*base, 256, "aic7xxx") == 0)
 		return (ENOMEM);
-#endif
 	return (0);
 }
 
@@ -334,17 +287,13 @@
 	start = pci_resource_start(ahc->dev_softc, 1);
 	if (start != 0) {
 		*bus_addr = start;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 		if (request_mem_region(start, 0x1000, "aic7xxx") == 0)
 			error = ENOMEM;
-#endif
 		if (error == 0) {
 			*maddr = ioremap_nocache(start, 256);
 			if (*maddr == NULL) {
 				error = ENOMEM;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 				release_mem_region(start, 0x1000);
-#endif
 			}
 		}
 	} else
@@ -387,10 +336,8 @@
 			       ahc_get_pci_slot(ahc->dev_softc),
 			       ahc_get_pci_function(ahc->dev_softc));
 			iounmap(maddr);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 			release_mem_region(ahc->platform_data->mem_busaddr,
 					   0x1000);
-#endif
 			ahc->bsh.maddr = NULL;
 			maddr = NULL;
 		} else
@@ -440,41 +387,3 @@
 	return (-error);
 }
 
-void
-ahc_power_state_change(struct ahc_softc *ahc, ahc_power_state new_state)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-	pci_set_power_state(ahc->dev_softc, new_state);
-#else
-	uint32_t cap;
-	u_int cap_offset;
-
-	/*
-	 * Traverse the capability list looking for
-	 * the power management capability.
-	 */
-	cap = 0;
-	cap_offset = ahc_pci_read_config(ahc->dev_softc,
-					 PCIR_CAP_PTR, /*bytes*/1);
-	while (cap_offset != 0) {
-
-		cap = ahc_pci_read_config(ahc->dev_softc,
-					  cap_offset, /*bytes*/4);
-		if ((cap & 0xFF) == 1
-		 && ((cap >> 16) & 0x3) > 0) {
-			uint32_t pm_control;
-
-			pm_control = ahc_pci_read_config(ahc->dev_softc,
-							 cap_offset + 4,
-							 /*bytes*/4);
-			pm_control &= ~0x3;
-			pm_control |= new_state;
-			ahc_pci_write_config(ahc->dev_softc,
-					     cap_offset + 4,
-					     pm_control, /*bytes*/2);
-			break;
-		}
-		cap_offset = (cap >> 8) & 0xFF;
-	}
-#endif 
-}
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c	2005-01-19 13:44:45 -08:00
@@ -721,7 +721,7 @@
 	ahc->chip |= AHC_PCI;
 	ahc->description = entry->name;
 
-	ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
+	pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
 
 	error = ahc_pci_map_registers(ahc);
 	if (error != 0)
@@ -2016,7 +2016,7 @@
 ahc_pci_resume(struct ahc_softc *ahc)
 {
 
-	ahc_power_state_change(ahc, AHC_POWER_STATE_D0);
+	pci_set_power_state(ahc->dev_softc, AHC_POWER_STATE_D0);
 
 	/*
 	 * We assume that the OS has restored our register
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/constants.c	2005-01-19 13:44:47 -08:00
@@ -1156,17 +1156,14 @@
 }
 
 /* Print sense information */
-static void
-print_sense_internal(const char *devclass, 
-		     const unsigned char *sense_buffer,
-		     int sense_len,
-		     struct request *req)
+void
+__scsi_print_sense(const char *name, const unsigned char *sense_buffer,
+		   int sense_len)
 {
 	int k, num, res;
 	unsigned int info;
 	const char *error;
 	const char *sense_txt;
-	const char *name = req->rq_disk ? req->rq_disk->disk_name : devclass;
 	struct scsi_sense_hdr ssh;
     
 	res = scsi_normalize_sense(sense_buffer, sense_len, &ssh);
@@ -1254,18 +1251,25 @@
 		printk("\n");
 	}
 }
+EXPORT_SYMBOL(__scsi_print_sense);
 
 void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd)
 {
-	print_sense_internal(devclass, cmd->sense_buffer,
-			     SCSI_SENSE_BUFFERSIZE, cmd->request);
+	const char *name = devclass;
+
+	if (cmd->request->rq_disk)
+		name = cmd->request->rq_disk->disk_name;
+	__scsi_print_sense(name, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
 }
 EXPORT_SYMBOL(scsi_print_sense);
 
 void scsi_print_req_sense(const char *devclass, struct scsi_request *sreq)
 {
-	print_sense_internal(devclass, sreq->sr_sense_buffer,
-			     SCSI_SENSE_BUFFERSIZE, sreq->sr_request);
+	const char *name = devclass;
+
+	if (sreq->sr_request->rq_disk)
+		name = sreq->sr_request->rq_disk->disk_name;
+	__scsi_print_sense(name, sreq->sr_sense_buffer, SCSI_SENSE_BUFFERSIZE);
 }
 EXPORT_SYMBOL(scsi_print_req_sense);
 
diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/scsi/fd_mcs.c	2005-01-19 13:44:48 -08:00
@@ -96,7 +96,6 @@
 
 #include "scsi.h"
 #include <scsi/scsi_host.h>
-#include "fd_mcs.h"
 
 #define DRIVER_VERSION "v0.2 by ZP Gu<zpg@castle.net>"
 
@@ -104,14 +103,12 @@
 
 #define DEBUG            0	/* Enable debugging output */
 #define ENABLE_PARITY    1	/* Enable SCSI Parity */
-#define DO_DETECT        0	/* Do device detection here (see scsi.c) */
 
 /* END OF USER DEFINABLE OPTIONS */
 
 #if DEBUG
 #define EVERY_ACCESS     0	/* Write a line on every scsi access */
 #define ERRORS_ONLY      1	/* Only write a line if there is an error */
-#define DEBUG_DETECT     1	/* Debug fd_mcs_detect() */
 #define DEBUG_MESSAGES   1	/* Debug MESSAGE IN phase */
 #define DEBUG_ABORT      1	/* Debug abort() routine */
 #define DEBUG_RESET      1	/* Debug reset() routine */
@@ -119,7 +116,6 @@
 #else
 #define EVERY_ACCESS     0	/* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
 #define ERRORS_ONLY      0
-#define DEBUG_DETECT     0
 #define DEBUG_MESSAGES   0
 #define DEBUG_ABORT      0
 #define DEBUG_RESET      0
@@ -432,6 +428,7 @@
 				FIFO_COUNT = user_fifo_count ? user_fifo_count : fd_mcs_adapters[loop].fifo_count;
 				FIFO_Size = user_fifo_size ? user_fifo_size : fd_mcs_adapters[loop].fifo_size;
 
+/* FIXME: Do we need to keep this bit of code inside NOT_USED around at all? */
 #ifdef NOT_USED
 				/* *************************************************** */
 				/* Try to toggle 32-bit mode.  This only
@@ -510,59 +507,6 @@
 				outb(0, SCSI_Mode_Cntl_port);
 				outb(PARITY_MASK, TMC_Cntl_port);
 				/* done reset */
-
-#if DO_DETECT
-				/* scan devices attached */
-				{
-					const int buflen = 255;
-					int i, j, retcode;
-					Scsi_Cmnd SCinit;
-					unsigned char do_inquiry[] = { INQUIRY, 0, 0, 0, buflen, 0 };
-					unsigned char do_request_sense[] = { REQUEST_SENSE,
-						0, 0, 0, buflen, 0
-					};
-					unsigned char do_read_capacity[] = { READ_CAPACITY,
-						0, 0, 0, 0, 0, 0, 0, 0, 0
-					};
-					unsigned char buf[buflen];
-
-					SCinit.request_buffer = SCinit.buffer = buf;
-					SCinit.request_bufflen = SCinit.bufflen = sizeof(buf) - 1;
-					SCinit.use_sg = 0;
-					SCinit.lun = 0;
-					SCinit.host = shpnt;
-
-					printk("fd_mcs: detection routine scanning for devices:\n");
-					for (i = 0; i < 8; i++) {
-						if (i == shpnt->this_id)	/* Skip host adapter */
-							continue;
-						SCinit.target = i;
-						memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
-						retcode = fd_mcs_command(&SCinit);
-						if (!retcode) {
-							memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
-							retcode = fd_mcs_command(&SCinit);
-							if (!retcode) {
-								printk("     SCSI ID %d: ", i);
-								for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
-									printk("%c", buf[j] >= 20 ? buf[j] : ' ');
-								memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
-								retcode = fd_mcs_command(&SCinit);
-								if (!retcode) {
-									unsigned long blocks, size, capacity;
-
-									blocks = (buf[0] << 24) | (buf[1] << 16)
-									    | (buf[2] << 8) | buf[3];
-									size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
-									capacity = +(+(blocks / 1024L) * +(size * 10L)) / 1024L;
-
-									printk("%lu MB (%lu byte blocks)\n", ((capacity + 5L) / 10L), size);
-								}
-							}
-						}
-					}
-				}
-#endif
 			}
 		}
 
diff -Nru a/drivers/scsi/fd_mcs.h b/drivers/scsi/fd_mcs.h
--- a/drivers/scsi/fd_mcs.h	2005-01-19 13:44:46 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,37 +0,0 @@
-/* fd_mcs.h -- Header for Future Domain MCS 600/700 (or IBM OEM) driver
- * 
- * fd_mcs.h v0.2 03/11/1998 ZP Gu (zpg@castle.net)
- *
-
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
-
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
-#ifndef _FD_MCS_H
-#define _FD_MCS_H
-
-static int fd_mcs_detect(Scsi_Host_Template *);
-static int fd_mcs_release(struct Scsi_Host *);
-static int fd_mcs_command(Scsi_Cmnd *);
-static int fd_mcs_abort(Scsi_Cmnd *);
-static int fd_mcs_bus_reset(Scsi_Cmnd *);
-static int fd_mcs_device_reset(Scsi_Cmnd *);
-static int fd_mcs_host_reset(Scsi_Cmnd *);
-static int fd_mcs_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
-static int fd_mcs_biosparam(struct scsi_device *, struct block_device *,
-			    sector_t, int *);
-static const char *fd_mcs_info(struct Scsi_Host *);
-
-#endif				/* _FD_MCS_H */
diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
--- a/drivers/scsi/gdth.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/gdth.c	2005-01-19 13:44:47 -08:00
@@ -397,11 +397,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #include <linux/spinlock.h>
-#else
-#include <asm/spinlock.h>
-#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 #include <linux/blkdev.h>
 #else
@@ -412,14 +408,11 @@
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include "gdth.h"
+#include "gdth_kcompat.h"
 
 static void gdth_delay(int milliseconds);
 static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 static irqreturn_t gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-#else
-static void gdth_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-#endif
 static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp);
 static int gdth_async_event(int hanum);
 static void gdth_log_event(gdth_evt_data *dvr, char *buffer);
@@ -617,32 +610,6 @@
     DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN
 };
 
-/* __initfunc, __initdata macros */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-#define GDTH_INITFUNC(type, func)       type __init func 
-#include <linux/init.h>
-#else
-#define GDTH_INITFUNC(type, func)       __initfunc(type func)
-#include <linux/init.h>
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-#define GDTH_INIT_LOCK_HA(ha)           spin_lock_init(&(ha)->smp_lock)
-#define GDTH_LOCK_HA(ha,flags)          spin_lock_irqsave(&(ha)->smp_lock,flags)
-#define GDTH_UNLOCK_HA(ha,flags)        spin_unlock_irqrestore(&(ha)->smp_lock,flags)
-
-#define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags)
-#define GDTH_UNLOCK_SCSI_DONE(dev, flags) spin_unlock_irqrestore(dev->host_lock,flags)
-
-#else
-#define GDTH_INIT_LOCK_HA(ha)           spin_lock_init(&(ha)->smp_lock)
-#define GDTH_LOCK_HA(ha,flags)          spin_lock_irqsave(&(ha)->smp_lock,flags)
-#define GDTH_UNLOCK_HA(ha,flags)        spin_unlock_irqrestore(&(ha)->smp_lock,flags)
-
-#define GDTH_LOCK_SCSI_DONE(flags)      spin_lock_irqsave(&io_request_lock,flags)
-#define GDTH_UNLOCK_SCSI_DONE(flags)    spin_unlock_irqrestore(&io_request_lock,flags)
-#endif
-
 /* LILO and modprobe/insmod parameters */
 /* IRQ list for GDT3000/3020 EISA controllers */
 static int irq[MAXHA] __initdata = 
@@ -674,7 +641,6 @@
 /* 64 bit DMA mode, support for drives > 2 TB, if force_dma32 = 0 */
 static int force_dma32 = 0;
 
-#ifdef MODULE
 /* parameters for modprobe/insmod */
 module_param(irq, int, 0);
 module_param(disable, int, 0);
@@ -689,33 +655,15 @@
 module_param(probe_eisa_isa, int, 0);
 module_param(force_dma32, int, 0);
 MODULE_AUTHOR("Achim Leubner");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,11)
 MODULE_LICENSE("GPL");
-#endif
-#endif
 
 /* ioctl interface */
 static struct file_operations gdth_fops = {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     .ioctl   = gdth_ioctl,
     .open    = gdth_open,
     .release = gdth_close,
-#else
-    ioctl:gdth_ioctl,
-    open:gdth_open,
-    release:gdth_close,
-#endif
 };
 
-/* /proc support */
-#include <linux/stat.h> 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-struct proc_dir_entry proc_scsi_gdth = {
-    PROC_SCSI_GDTH, 4, "gdth",
-    S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-#endif
-
 #include "gdth_proc.h"
 #include "gdth_proc.c"
 
@@ -755,7 +703,7 @@
 
 /* controller search and initialization functions */
 
-GDTH_INITFUNC(static int, gdth_search_eisa(ushort eisa_adr))
+static int __init gdth_search_eisa(ushort eisa_adr)
 {
     ulong32 id;
     
@@ -773,7 +721,7 @@
 }
 
 
-GDTH_INITFUNC(static int, gdth_search_isa(ulong32 bios_adr))
+static int __init gdth_search_isa(ulong32 bios_adr)
 {
     void __iomem *addr;
     ulong32 id;
@@ -789,7 +737,7 @@
 }
 
 
-GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
+static int __init gdth_search_pci(gdth_pci_str *pcistr)
 {
     ushort device, cnt;
     
@@ -812,21 +760,19 @@
     return cnt;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 /* Vortex only makes RAID controllers.
  * We do not really want to specify all 550 ids here, so wildcard match.
  */
-static struct pci_device_id gdthtable[] __devinitdata = {
+static struct pci_device_id gdthtable[] __attribute_used__ = {
     {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
     {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, 
     {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, 
     {0}
 };
 MODULE_DEVICE_TABLE(pci,gdthtable);
-#endif
 
-GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
-                                           ushort vendor, ushort device))
+static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
+                                           ushort vendor, ushort device)
 {
     ulong base0, base1, base2;
     struct pci_dev *pdev;
@@ -834,7 +780,6 @@
     TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
           *cnt, vendor, device));
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     pdev = NULL;
     while ((pdev = pci_find_device(vendor, device, pdev)) 
            != NULL) {
@@ -872,52 +817,10 @@
                 pcistr[*cnt].irq, pcistr[*cnt].dpmem));
         (*cnt)++;
     }       
-#else
-    pdev = NULL;
-    while ((pdev = pci_find_device(vendor, device, pdev)) 
-           != NULL) {
-        if (*cnt >= MAXHA)
-            return;
-        /* GDT PCI controller found, resources are already in pdev */
-        pcistr[*cnt].pdev = pdev;
-        pcistr[*cnt].vendor_id = vendor;
-        pcistr[*cnt].device_id = device;
-        pcistr[*cnt].bus = pdev->bus->number;
-        pcistr[*cnt].device_fn = pdev->devfn;
-        pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn,
-                                 PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id);
-        pcistr[*cnt].irq = pdev->irq;
-        base0 = pdev->base_address[0];
-        base1 = pdev->base_address[1];
-        base2 = pdev->base_address[2];
-        if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
-            device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
-            if ((base0 & PCI_BASE_ADDRESS_SPACE) != 
-                PCI_BASE_ADDRESS_SPACE_MEMORY)
-                continue;
-            pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-        } else {                                  /* GDT6110, GDT6120, .. */
-            if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
-                PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                (base2 & PCI_BASE_ADDRESS_SPACE) !=
-                PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                (base1 & PCI_BASE_ADDRESS_SPACE) !=
-                PCI_BASE_ADDRESS_SPACE_IO)
-                continue;
-            pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
-            pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-            pcistr[*cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
-        }
-        TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
-                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
-        (*cnt)++;
-    }       
-#endif
 }   
 
 
-GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt))
+static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt)
 {    
     gdth_pci_str temp;
     int i, changed;
@@ -955,7 +858,7 @@
 }
 
 
-GDTH_INITFUNC(static int, gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha))
+static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)
 {
     ulong32 retries,id;
     unchar prot_ver,eisacf,i,irq_found;
@@ -1048,7 +951,7 @@
 }
 
        
-GDTH_INITFUNC(static int, gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha))
+static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)
 {
     register gdt2_dpram_str __iomem *dp2_ptr;
     int i;
@@ -1148,7 +1051,7 @@
 }
 
 
-GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha))
+static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
 {
     register gdt6_dpram_str __iomem *dp6_ptr;
     register gdt6c_dpram_str __iomem *dp6c_ptr;
@@ -1168,9 +1071,7 @@
     ha->stype = (ulong32)pcistr->device_id;
     ha->subdevice_id = pcistr->subdevice_id;
     ha->irq = pcistr->irq;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     ha->pdev = pcistr->pdev;
-#endif
     
     if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) {  /* GDT6000/B */
         TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
@@ -1401,7 +1302,6 @@
         }
 
         /* manipulate config. space to enable DPMEM, start RP controller */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
         pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
         command |= 6;
         pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
@@ -1412,18 +1312,6 @@
         gdth_delay(1);
         pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
                                pci_resource_start(pcistr->pdev, 8));
-#else
-        pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
-        command |= 6;
-        pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
-        if (pcistr->pdev->rom_address == 1UL)
-            pcistr->pdev->rom_address = 0UL;
-        i = 0xFEFF0001UL;
-        pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i);
-        gdth_delay(1);
-        pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
-                               pcistr->pdev->rom_address);
-#endif
         
         dp6m_ptr = ha->brd;
 
@@ -1550,7 +1438,7 @@
 
 /* controller protocol functions */
 
-GDTH_INITFUNC(static void, gdth_enable_int(int hanum))
+static void __init gdth_enable_int(int hanum)
 {
     gdth_ha_str *ha;
     ulong flags;
@@ -1560,7 +1448,7 @@
 
     TRACE(("gdth_enable_int() hanum %d\n",hanum));
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     if (ha->type == GDT_EISA) {
         outb(0xff, ha->bmic + EDOORREG);
@@ -1585,7 +1473,7 @@
         gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4,
                     &dp6m_ptr->i960r.edoor_en_reg);
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 
@@ -1897,7 +1785,7 @@
 
 /* search for devices */
 
-GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
+static int __init gdth_search_drives(int hanum)
 {
     register gdth_ha_str *ha;
     ushort cdev_cnt, i;
@@ -2357,16 +2245,11 @@
 
     TRACE(("gdth_putq() priority %d\n",priority));
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     scp->SCp.this_residual = (int)priority;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
     t = scp->device->id;
-#else
-    b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-    t = scp->target;
-#endif
     if (priority >= DEFAULT_PRI) {
         if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
             (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) {
@@ -2389,7 +2272,7 @@
         pscp->SCp.ptr = (char *)scp;
         scp->SCp.ptr  = (char *)nscp;
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 
 #ifdef GDTH_STATISTICS
     flags = 0;
@@ -2415,7 +2298,7 @@
     TRACE(("gdth_next() hanum %d\n",hanum));
     ha = HADATA(gdth_ctr_tab[hanum]);
     if (!gdth_polling) 
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
 
     ha->cmd_cnt = ha->cmd_offs_dpmem = 0;
     this_cmd = firsttime = TRUE;
@@ -2425,15 +2308,9 @@
     for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) {
         if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr)
             pscp = (Scsi_Cmnd *)pscp->SCp.ptr;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         b = virt_ctr ? NUMDATA(nscp->device->host)->busnum : nscp->device->channel;
         t = nscp->device->id;
         l = nscp->device->lun;
-#else
-        b = virt_ctr ? NUMDATA(nscp->host)->busnum : nscp->channel;
-        t = nscp->target;
-        l = nscp->lun;
-#endif
         if (nscp->SCp.this_residual >= DEFAULT_PRI) {
             if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
                 (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) 
@@ -2444,7 +2321,7 @@
             if (gdth_test_busy(hanum)) {        /* controller busy ? */
                 TRACE(("gdth_next() controller %d busy !\n",hanum));
                 if (!gdth_polling) {
-                    GDTH_UNLOCK_HA(ha, flags);
+                    spin_unlock_irqrestore(&ha->smp_lock, flags);
                     return;
                 }
                 while (gdth_test_busy(hanum))
@@ -2513,14 +2390,8 @@
                 nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
                 if (!nscp->SCp.have_data_in)
                     nscp->SCp.have_data_in++;
-                else {
-                    if (!gdth_polling) 
-                        GDTH_UNLOCK_HA(ha,flags);
-                    /* io_request_lock already active ! */
+                else
                     nscp->scsi_done(nscp);
-                    if (!gdth_polling) 
-                        GDTH_LOCK_HA(ha,flags);
-                }
             }
         } else if (nscp->done == gdth_scsi_done && nscp->cmnd[0] == 0xff) {
             if (!(cmd_index=gdth_special_cmd(hanum,nscp)))
@@ -2538,14 +2409,8 @@
             nscp->result = DID_BAD_TARGET << 16;
             if (!nscp->SCp.have_data_in)
                 nscp->SCp.have_data_in++;
-            else {
-                if (!gdth_polling) 
-                    GDTH_UNLOCK_HA(ha,flags);
-                /* io_request_lock already active ! */      
+            else
                 nscp->scsi_done(nscp);
-                if (!gdth_polling) 
-                    GDTH_LOCK_HA(ha,flags);
-            }
         } else {
             switch (nscp->cmnd[0]) {
               case TEST_UNIT_READY:
@@ -2555,9 +2420,7 @@
               case VERIFY:
               case START_STOP:
               case MODE_SENSE:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
               case SERVICE_ACTION_IN:
-#endif
                 TRACE(("cache cmd %x/%x/%x/%x/%x/%x\n",nscp->cmnd[0],
                        nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3],
                        nscp->cmnd[4],nscp->cmnd[5]));
@@ -2572,22 +2435,10 @@
                     nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
-                    else {
-                        if (!gdth_polling) 
-                            GDTH_UNLOCK_HA(ha,flags);
-                        /* io_request_lock already active ! */      
+                    else
                         nscp->scsi_done(nscp);
-                        if (!gdth_polling) 
-                            GDTH_LOCK_HA(ha,flags);
-                    }
-                } else if (gdth_internal_cache_cmd(hanum,nscp)) {
-                    if (!gdth_polling) 
-                        GDTH_UNLOCK_HA(ha,flags);
-                    /* io_request_lock already active ! */      
+                } else if (gdth_internal_cache_cmd(hanum,nscp))
                     nscp->scsi_done(nscp);
-                    if (!gdth_polling) 
-                        GDTH_LOCK_HA(ha,flags);
-                }
                 break;
 
               case ALLOW_MEDIUM_REMOVAL:
@@ -2600,14 +2451,8 @@
                     nscp->sense_buffer[0] = 0;
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
-                    else {
-                        if (!gdth_polling) 
-                            GDTH_UNLOCK_HA(ha,flags);
-                        /* io_request_lock already active ! */      
+                    else
                         nscp->scsi_done(nscp);
-                        if (!gdth_polling) 
-                            GDTH_LOCK_HA(ha,flags);
-                    }
                 } else {
                     nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0;
                     TRACE(("Prevent/allow r. %d rem. drive %d\n",
@@ -2629,10 +2474,8 @@
               case WRITE_6:
               case READ_10:
               case WRITE_10:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
               case READ_16:
               case WRITE_16:
-#endif
                 if (ha->hdr[t].media_changed) {
                     /* return UNIT_ATTENTION */
                     TRACE2(("cmd 0x%x target %d: UNIT_ATTENTION\n",
@@ -2644,14 +2487,8 @@
                     nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
                     if (!nscp->SCp.have_data_in)
                         nscp->SCp.have_data_in++;
-                    else {
-                        if (!gdth_polling) 
-                            GDTH_UNLOCK_HA(ha,flags);
-                        /* io_request_lock already active ! */      
+                    else
                         nscp->scsi_done(nscp);
-                        if (!gdth_polling) 
-                            GDTH_LOCK_HA(ha,flags);
-                    }
                 } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t)))
                     this_cmd = FALSE;
                 break;
@@ -2665,14 +2502,8 @@
                 nscp->result = DID_ABORT << 16;
                 if (!nscp->SCp.have_data_in)
                     nscp->SCp.have_data_in++;
-                else {
-                    if (!gdth_polling) 
-                        GDTH_UNLOCK_HA(ha,flags);
-                    /* io_request_lock already active ! */  
+                else
                     nscp->scsi_done(nscp);
-                    if (!gdth_polling) 
-                        GDTH_LOCK_HA(ha,flags);
-                }
                 break;
             }
         }
@@ -2692,7 +2523,7 @@
     }
 
     if (!gdth_polling) 
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
 
     if (gdth_polling && ha->cmd_cnt > 0) {
         if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT))
@@ -2708,7 +2539,6 @@
     ushort cpsum,cpnow;
     struct scatterlist *sl;
     gdth_ha_str *ha;
-    int sgcnt;
     char *address;
 
     cpcount = count<=(ushort)scp->bufflen ? count:(ushort)scp->bufflen;
@@ -2716,10 +2546,9 @@
 
     if (scp->use_sg) {
         sl = (struct scatterlist *)scp->request_buffer;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
-        sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,PCI_DMA_FROMDEVICE);
-        for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
-            cpnow = (ushort)sg_dma_len(sl);
+        for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) {
+	    unsigned long flags;
+            cpnow = (ushort)sl->length;
             TRACE(("copy_internal() now %d sum %d count %d %d\n",
                           cpnow,cpsum,cpcount,(ushort)scp->bufflen));
             if (cpsum+cpnow > cpcount) 
@@ -2730,30 +2559,16 @@
                        hanum);
                 return;
             }
-            address = (char *)(page_address(sl->page) + sl->offset);
-            memcpy(address,buffer,cpnow);
-            if (cpsum == cpcount)
-                break;
-            buffer += cpnow;
-        }
-        pci_unmap_sg(ha->pdev,scp->request_buffer,
-                     scp->use_sg,PCI_DMA_FROMDEVICE);
-#else
-        sgcnt = scp->use_sg;
-        for (i=0,cpsum=0; i<sgcnt; ++i,++sl) {
-            cpnow = (ushort)sl->length;
-            TRACE(("copy_internal() now %d sum %d count %d %d\n",
-                          cpnow,cpsum,cpcount,(ushort)scp->bufflen));
-            if (cpsum+cpnow > cpcount) 
-               cpnow = cpcount - cpsum;
-            cpsum += cpnow;
-            address = (char *)sl->address;
+	    local_irq_save(flags);
+	    address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
             memcpy(address,buffer,cpnow);
+	    flush_dcache_page(sl->page);
+	    kunmap_atomic(address, KM_BIO_SRC_IRQ);
+	    local_irq_restore(flags);
             if (cpsum == cpcount)
                 break;
             buffer += cpnow;
         }
-#endif
     } else {
         TRACE(("copy_internal() count %d\n",cpcount));
         memcpy((char*)scp->request_buffer,buffer,cpcount);
@@ -2770,11 +2585,7 @@
     gdth_modep_data mpd;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     t  = scp->device->id;
-#else
-    t  = scp->target;
-#endif
     TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n",
            scp->cmnd[0],t));
 
@@ -2839,7 +2650,6 @@
         gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data));
         break;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
       case SERVICE_ACTION_IN:
         if ((scp->cmnd[1] & 0x1f) == SAI_READ_CAPACITY_16 &&
             (ha->cache_feat & GDT_64BIT)) {
@@ -2853,7 +2663,6 @@
             scp->result = DID_ABORT << 16;
         }
         break;
-#endif
 
       default:
         TRACE2(("Internal cache cmd 0x%x unknown\n",scp->cmnd[0]));
@@ -2877,10 +2686,8 @@
     ulong64 no, blockno;
     dma_addr_t phys_addr;
     int i, cmd_index, read_write, sgcnt, mode64;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
     struct page *page;
     ulong offset;
-#endif
 
     ha = HADATA(gdth_ctr_tab[hanum]);
     cmdp = ha->pccb;
@@ -2922,10 +2729,7 @@
         else
             cmdp->OpCode = GDT_FLUSH;
     } else if (scp->cmnd[0] == WRITE_6 || scp->cmnd[0] == WRITE_10 ||
-               scp->cmnd[0] == WRITE_12 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-               || scp->cmnd[0] == WRITE_16
-#endif
+               scp->cmnd[0] == WRITE_12 || scp->cmnd[0] == WRITE_16
     ) {
         read_write = 1;
         if (gdth_write_through || ((ha->hdr[hdrive].rw_attribs & 1) && 
@@ -2976,7 +2780,6 @@
         if (scp->use_sg) {
             sl = (struct scatterlist *)scp->request_buffer;
             sgcnt = scp->use_sg;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
             scp->SCp.Status = GDTH_MAP_SG;
             scp->SCp.Message = (read_write == 1 ? 
                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);   
@@ -3005,23 +2808,6 @@
                     cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl);
                 }
             }
-#else
-            if (mode64) {
-                cmdp->u.cache64.DestAddr= (ulong64)-1;
-                cmdp->u.cache64.sg_canz = sgcnt;
-                for (i=0; i<sgcnt; ++i,++sl) {
-                    cmdp->u.cache64.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
-                    cmdp->u.cache64.sg_lst[i].sg_len = (ulong32)sl->length;
-                }
-            } else {
-                cmdp->u.cache.DestAddr= 0xffffffff;
-                cmdp->u.cache.sg_canz = sgcnt;
-                for (i=0; i<sgcnt; ++i,++sl) {
-                    cmdp->u.cache.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
-                    cmdp->u.cache.sg_lst[i].sg_len = (ulong32)sl->length;
-                }
-            }
-#endif
 
 #ifdef GDTH_STATISTICS
             if (max_sg < (ulong32)sgcnt) {
@@ -3031,7 +2817,6 @@
 #endif
 
         } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
             scp->SCp.Status = GDTH_MAP_SINGLE;
             scp->SCp.Message = (read_write == 1 ? 
                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
@@ -3040,9 +2825,6 @@
             phys_addr = pci_map_page(ha->pdev,page,offset,
                                      scp->request_bufflen,scp->SCp.Message);
             scp->SCp.dma_handle = phys_addr;
-#else
-            phys_addr = virt_to_bus(scp->request_buffer);
-#endif
             if (mode64) {
                 if (ha->cache_feat & SCATTER_GATHER) {
                     cmdp->u.cache64.DestAddr = (ulong64)-1;
@@ -3114,19 +2896,12 @@
     dma_addr_t phys_addr, sense_paddr;
     int cmd_index, sgcnt, mode64;
     unchar t,l;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
     struct page *page;
     ulong offset;
-#endif
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     t = scp->device->id;
     l = scp->device->lun;
-#else
-    t = scp->target;
-    l = scp->lun;
-#endif
     cmdp = ha->pccb;
     TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n",
            scp->cmnd[0],b,t,l));
@@ -3166,7 +2941,6 @@
         }
 
     } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
         page = virt_to_page(scp->sense_buffer);
         offset = (ulong)scp->sense_buffer & ~PAGE_MASK;
         sense_paddr = pci_map_page(ha->pdev,page,offset,
@@ -3174,9 +2948,6 @@
         scp->SCp.buffer = (struct scatterlist *)((ulong32)sense_paddr);
         /* high part, if 64bit */
         scp->host_scribble = (char *)(ulong32)((ulong64)sense_paddr >> 32);
-#else
-        sense_paddr = virt_to_bus(scp->sense_buffer);
-#endif
         cmdp->OpCode           = GDT_WRITE;             /* always */
         cmdp->BoardNode        = LOCALBOARD;
         if (mode64) { 
@@ -3215,7 +2986,6 @@
         if (scp->use_sg) {
             sl = (struct scatterlist *)scp->request_buffer;
             sgcnt = scp->use_sg;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
             scp->SCp.Status = GDTH_MAP_SG;
             scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; 
             sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message);
@@ -3243,23 +3013,6 @@
                     cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl);
                 }
             }
-#else
-            if (mode64) {
-                cmdp->u.raw64.sdata = (ulong64)-1;
-                cmdp->u.raw64.sg_ranz = sgcnt;
-                for (i=0; i<sgcnt; ++i,++sl) {
-                    cmdp->u.raw64.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
-                    cmdp->u.raw64.sg_lst[i].sg_len = (ulong32)sl->length;
-                }
-            } else {
-                cmdp->u.raw.sdata = 0xffffffff;
-                cmdp->u.raw.sg_ranz = sgcnt;
-                for (i=0; i<sgcnt; ++i,++sl) {
-                    cmdp->u.raw.sg_lst[i].sg_ptr = virt_to_bus(sl->address);
-                    cmdp->u.raw.sg_lst[i].sg_len = (ulong32)sl->length;
-                }
-            }
-#endif
 
 #ifdef GDTH_STATISTICS
             if (max_sg < sgcnt) {
@@ -3269,7 +3022,6 @@
 #endif
 
         } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
             scp->SCp.Status = GDTH_MAP_SINGLE;
             scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; 
             page = virt_to_page(scp->request_buffer);
@@ -3277,9 +3029,7 @@
             phys_addr = pci_map_page(ha->pdev,page,offset,
                                      scp->request_bufflen,scp->SCp.Message);
             scp->SCp.dma_handle = phys_addr;
-#else
-            phys_addr = virt_to_bus(scp->request_buffer);
-#endif
+
             if (mode64) {
                 if (ha->raw_feat & SCATTER_GATHER) {
                     cmdp->u.raw64.sdata  = (ulong64)-1;
@@ -3461,7 +3211,7 @@
     ulong flags;
 
     TRACE2(("gdth_read_event() handle %d\n", handle));
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
     if (handle == -1)
         eindex = eoldidx;
     else
@@ -3469,7 +3219,7 @@
     estr->event_source = 0;
 
     if (eindex >= MAX_EVENTS) {
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
         return eindex;
     }
     e = &ebuffer[eindex];
@@ -3482,7 +3232,7 @@
         }
         memcpy(estr, e, sizeof(gdth_evt_str));
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
     return eindex;
 }
 
@@ -3495,7 +3245,7 @@
     unchar found = FALSE;
 
     TRACE2(("gdth_readapp_event() app. %d\n", application));
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
     eindex = eoldidx;
     for (;;) {
         e = &ebuffer[eindex];
@@ -3515,7 +3265,7 @@
         memcpy(estr, e, sizeof(gdth_evt_str));
     else
         estr->event_source = 0;
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 static void gdth_clear_events(void)
@@ -3529,12 +3279,9 @@
 
 /* SCSI interface functions */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 static irqreturn_t gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs)
-#else
-static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs)
-#endif
 {
+    gdth_ha_str *ha2 = (gdth_ha_str *)dev_id;
     register gdth_ha_str *ha;
     gdt6m_dpram_str __iomem *dp6m_ptr = NULL;
     gdt6_dpram_str __iomem *dp6_ptr;
@@ -3556,28 +3303,20 @@
     /* if polling and not from gdth_wait() -> return */
     if (gdth_polling) {
         if (!gdth_from_wait) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
     }
 
     if (!gdth_polling)
-        GDTH_LOCK_HA((gdth_ha_str *)dev_id,flags);
+	spin_lock_irqsave(&ha2->smp_lock, flags);
     wait_index = 0;
 
     /* search controller */
     if ((hanum = gdth_get_status(&IStatus,irq)) == -1) {
         /* spurious interrupt */
         if (!gdth_polling)
-            GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+            spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
     }
     ha = HADATA(gdth_ctr_tab[hanum]);
 
@@ -3711,12 +3450,8 @@
         } else {
             TRACE2(("gdth_interrupt() unknown controller type\n"));
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
 
         TRACE(("gdth_interrupt() index %d stat %d info %d\n",
@@ -3731,13 +3466,9 @@
             TRACE2(("gdth_interrupt() async. event\n"));
             gdth_async_event(hanum);
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             gdth_next(hanum);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         } 
 
         if (IStatus == SPEZINDEX) {
@@ -3746,12 +3477,8 @@
             ha->dvr.eu.driver.ionode = hanum;
             gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr);
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
         scp     = ha->cmd_tab[IStatus-2].cmnd;
         Service = ha->cmd_tab[IStatus-2].service;
@@ -3763,40 +3490,24 @@
             ha->dvr.eu.driver.index = IStatus;
             gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr);
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
         if (scp == INTERNAL_CMND) {
             TRACE(("gdth_interrupt() answer to internal command\n"));
             if (!gdth_polling)
-                GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+                spin_unlock_irqrestore(&ha2->smp_lock, flags);
             return IRQ_HANDLED;
-#else
-            return;             
-#endif
         }
 
         TRACE(("gdth_interrupt() sync. status\n"));
         rval = gdth_sync_event(hanum,Service,IStatus,scp);
         if (!gdth_polling)
-            GDTH_UNLOCK_HA((gdth_ha_str *)dev_id,flags);
+            spin_unlock_irqrestore(&ha2->smp_lock, flags);
         if (rval == 2) {
             gdth_putq(hanum,scp,scp->SCp.this_residual);
         } else if (rval == 1) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
-            scp->scsi_done(scp);
-            GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
-#else
-            GDTH_LOCK_SCSI_DONE(flags);
             scp->scsi_done(scp);
-            GDTH_UNLOCK_SCSI_DONE(flags);
-#endif
         }
 
 #ifdef INT_COAL
@@ -3825,9 +3536,7 @@
 #endif
 
     gdth_next(hanum);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     return IRQ_HANDLED;
-#endif
 }
 
 static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
@@ -3911,13 +3620,8 @@
         printk("\n");
 
     } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         t = scp->device->id;
-#else
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        t = scp->target;
-#endif
         if (scp->SCp.sent_command == -1 && b != ha->virt_bus) {
             ha->raw[BUS_L2P(ha,b)].io_cnt[t]--;
         }
@@ -3929,7 +3633,6 @@
             /* retry */
             return 2;
         }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,13)
         if (scp->SCp.Status == GDTH_MAP_SG) 
             pci_unmap_sg(ha->pdev,scp->request_buffer,
                          scp->use_sg,scp->SCp.Message);
@@ -3943,7 +3646,7 @@
                 addr += (dma_addr_t)((ulong64)(ulong32)scp->host_scribble << 32);               
             pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE);
         }
-#endif
+
         if (ha->status == S_OK) {
             scp->SCp.Status = S_OK;
             scp->SCp.Message = ha->info;
@@ -4340,7 +4043,7 @@
     int hanum = 0;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) 
         if (ha->cmd_tab[i].cmnd != UNUSED_CMND)
@@ -4355,11 +4058,11 @@
 
     gdth_timer.expires = jiffies + 30 * HZ;
     add_timer(&gdth_timer);
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 #endif
 
-GDTH_INITFUNC(void, internal_setup(char *str,int *ints))
+void __init internal_setup(char *str,int *ints)
 {
     int i, argc;
     char *cur_str, *argv;
@@ -4432,7 +4135,7 @@
     }
 }
 
-GDTH_INITFUNC(int, option_setup(char *str))
+int __init option_setup(char *str)
 {
     int ints[MAXHA];
     char *cur = str;
@@ -4450,7 +4153,7 @@
     return 1;
 }
 
-GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
+int __init gdth_detect(Scsi_Host_Template *shtp)
 {
     struct Scsi_Host *shp;
     gdth_pci_str pcistr[MAXHA];
@@ -4540,7 +4243,6 @@
 
                 ha->pccb = CMDDATA(shp);
                 ha->ccb_phys = 0L;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
                 ha->pdev = NULL;
                 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
                                                     &scratch_dma_handle);
@@ -4554,21 +4256,7 @@
                         MAXOFFSETS, &scratch_dma_handle);
                 ha->coal_stat_phys = scratch_dma_handle;
 #endif
-#else
-                ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
-                if (ha->pscratch)
-                    ha->scratch_phys = virt_to_bus(ha->pscratch);
-                ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA);
-                if (ha->pmsg)
-                    ha->msg_phys = virt_to_bus(ha->pmsg);
-#ifdef INT_COAL
-                ha->coal_stat = 
-                    scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, 
-                                     GFP_ATOMIC | GFP_DMA);
-                if (ha->coal_stat)
-                    ha->coal_stat_phys = virt_to_bus(ha->coal_stat);
-#endif
-#endif
+
                 ha->scratch_busy = FALSE;
                 ha->req_first = NULL;
                 ha->tid_cnt = MAX_HDRIVES;
@@ -4583,7 +4271,7 @@
                     printk("GDT-ISA: Error during device scan\n");
                     --gdth_ctr_count;
                     --gdth_ctr_vcount;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+
 #ifdef INT_COAL
                     if (ha->coal_stat)
                         pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
@@ -4596,17 +4284,7 @@
                     if (ha->pmsg)
                         pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 
                                             ha->pmsg, ha->msg_phys);
-#else
-#ifdef INT_COAL
-                    if (ha->coal_stat)
-                        scsi_init_free((void *)ha->coal_stat, 
-                                       sizeof(gdth_coal_status) * MAXOFFSETS);
-#endif
-                    if (ha->pscratch)
-                        scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
-                    if (ha->pmsg)
-                        scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str));
-#endif
+
                     free_irq(ha->irq,ha);
                     scsi_unregister(shp);
                     continue;
@@ -4615,14 +4293,13 @@
                     hdr_channel = ha->bus_cnt;
                 ha->virt_bus = hdr_channel;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \
     LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
                 shp->highmem_io  = 0;
 #endif
                 if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) 
                     shp->max_cmd_len = 16;
-#endif
+
                 shp->max_id      = ha->tid_cnt;
                 shp->max_lun     = MAXLUN;
                 shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
@@ -4640,7 +4317,7 @@
                     }
                 }  
 
-                GDTH_INIT_LOCK_HA(ha);
+                spin_lock_init(&ha->smp_lock);
                 gdth_enable_int(hanum);
 #endif /* !__ia64__ */
             }
@@ -4686,7 +4363,7 @@
 
                 ha->pccb = CMDDATA(shp);
                 ha->ccb_phys = 0L; 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+
                 ha->pdev = NULL;
                 ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
                                                     &scratch_dma_handle);
@@ -4703,22 +4380,6 @@
                 ha->ccb_phys = 
                     pci_map_single(ha->pdev,ha->pccb,
                                    sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
-#else
-                ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
-                if (ha->pscratch)
-                    ha->scratch_phys = virt_to_bus(ha->pscratch);
-                ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA);
-                if (ha->pmsg)
-                    ha->msg_phys = virt_to_bus(ha->pmsg);
-#ifdef INT_COAL
-                ha->coal_stat = 
-                    scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, 
-                                     GFP_ATOMIC | GFP_DMA);
-                if (ha->coal_stat)
-                    ha->coal_stat_phys = virt_to_bus(ha->coal_stat);
-#endif
-                ha->ccb_phys = virt_to_bus(ha->pccb);
-#endif
                 ha->scratch_busy = FALSE;
                 ha->req_first = NULL;
                 ha->tid_cnt = MAX_HDRIVES;
@@ -4733,7 +4394,6 @@
                     printk("GDT-EISA: Error during device scan\n");
                     --gdth_ctr_count;
                     --gdth_ctr_vcount;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #ifdef INT_COAL
                     if (ha->coal_stat)
                         pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
@@ -4749,17 +4409,6 @@
                     if (ha->ccb_phys)
                         pci_unmap_single(ha->pdev,ha->ccb_phys,
                                         sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
-#else
-#ifdef INT_COAL
-                    if (ha->coal_stat)
-                        scsi_init_free((void *)ha->coal_stat, 
-                                       sizeof(gdth_coal_status) * MAXOFFSETS);
-#endif
-                    if (ha->pscratch)
-                        scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
-                    if (ha->pmsg)
-                        scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str));
-#endif
                     free_irq(ha->irq,ha);
                     scsi_unregister(shp);
                     continue;
@@ -4768,14 +4417,13 @@
                     hdr_channel = ha->bus_cnt;
                 ha->virt_bus = hdr_channel;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \
     LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
                 shp->highmem_io  = 0;
 #endif
                 if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) 
                     shp->max_cmd_len = 16;
-#endif
+
                 shp->max_id      = ha->tid_cnt;
                 shp->max_lun     = MAXLUN;
                 shp->max_channel = virt_ctr ? 0 : ha->bus_cnt;
@@ -4793,7 +4441,7 @@
                     }
                 }  
 
-                GDTH_INIT_LOCK_HA(ha);
+                spin_lock_init(&ha->smp_lock);
                 gdth_enable_int(hanum);
             }
         }
@@ -4841,7 +4489,7 @@
 
         ha->pccb = CMDDATA(shp);
         ha->ccb_phys = 0L;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+
         ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, 
                                             &scratch_dma_handle);
         ha->scratch_phys = scratch_dma_handle;
@@ -4854,21 +4502,6 @@
                                  MAXOFFSETS, &scratch_dma_handle);
         ha->coal_stat_phys = scratch_dma_handle;
 #endif
-#else
-        ha->pscratch = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
-        if (ha->pscratch)
-            ha->scratch_phys = virt_to_bus(ha->pscratch);
-        ha->pmsg = scsi_init_malloc(sizeof(gdth_msg_str), GFP_ATOMIC | GFP_DMA);
-        if (ha->pmsg)
-            ha->msg_phys = virt_to_bus(ha->pmsg);
-#ifdef INT_COAL
-        ha->coal_stat = 
-            scsi_init_malloc(sizeof(gdth_coal_status) * MAXOFFSETS, 
-                             GFP_ATOMIC | GFP_DMA);
-        if (ha->coal_stat)
-            ha->coal_stat_phys = virt_to_bus(ha->coal_stat);
-#endif
-#endif
         ha->scratch_busy = FALSE;
         ha->req_first = NULL;
         ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES;
@@ -4887,7 +4520,7 @@
                 hdr_channel = ha->bus_cnt;
             ha->virt_bus = hdr_channel;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
             scsi_set_device(shp, &pcistr[ctr].pdev->dev);
 #else
@@ -4909,14 +4542,12 @@
                     err = TRUE;
                 }
             }
-#endif
         }
 
         if (err) {
             printk("GDT-PCI %d: Error during device scan\n", hanum);
             --gdth_ctr_count;
             --gdth_ctr_vcount;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #ifdef INT_COAL
             if (ha->coal_stat)
                 pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
@@ -4929,17 +4560,6 @@
             if (ha->pmsg)
                 pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), 
                                     ha->pmsg, ha->msg_phys);
-#else
-#ifdef INT_COAL
-            if (ha->coal_stat)
-                scsi_init_free((void *)ha->coal_stat, 
-                               sizeof(gdth_coal_status) * MAXOFFSETS);
-#endif
-            if (ha->pscratch)
-                scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
-            if (ha->pmsg)
-                scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str));
-#endif
             free_irq(ha->irq,ha);
             scsi_unregister(shp);
             continue;
@@ -4962,8 +4582,7 @@
             }
         }  
 
-
-        GDTH_INIT_LOCK_HA(ha);
+        spin_lock_init(&ha->smp_lock);
         gdth_enable_int(hanum);
     }
     
@@ -4994,12 +4613,10 @@
     if (NUMDATA(shp)->busnum == 0) {
         hanum = NUMDATA(shp)->hanum;
         ha    = HADATA(gdth_ctr_tab[hanum]);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
         if (ha->sdev) {
             scsi_free_host_dev(ha->sdev);
             ha->sdev = NULL;
         }
-#endif
         gdth_flush(hanum);
 
         if (shp->irq) {
@@ -5010,7 +4627,6 @@
             free_dma(shp->dma_channel);
         }
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #ifdef INT_COAL
         if (ha->coal_stat)
             pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
@@ -5025,17 +4641,6 @@
         if (ha->ccb_phys)
             pci_unmap_single(ha->pdev,ha->ccb_phys,
                              sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
-#else
-#ifdef INT_COAL
-        if (ha->coal_stat)
-            scsi_init_free((void *)ha->coal_stat, 
-                           sizeof(gdth_coal_status) * MAXOFFSETS);
-#endif
-        if (ha->pscratch)
-            scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
-        if (ha->pmsg)
-            scsi_init_free((void *)ha->pmsg, sizeof(gdth_msg_str));
-#endif
         gdth_ctr_released++;
         TRACE2(("gdth_release(): HA %d of %d\n", 
                 gdth_ctr_released, gdth_ctr_count));
@@ -5098,21 +4703,6 @@
     return ((const char *)ha->binfo.type_string);
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-/* old error handling */
-int gdth_abort(Scsi_Cmnd *scp)
-{
-    TRACE2(("gdth_abort() reason %d\n",scp->abort_reason));
-    return SCSI_ABORT_SNOOZE;
-}
-
-int gdth_reset(Scsi_Cmnd *scp, unsigned int reset_flags)
-{
-    TRACE2(("gdth_reset()\n"));
-    return SCSI_RESET_PUNT;
-}
-#endif
-
 /* new error handling */
 int gdth_eh_abort(Scsi_Cmnd *scp)
 {
@@ -5135,33 +4725,25 @@
     unchar b;
 
     TRACE2(("gdth_eh_bus_reset()\n"));
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
     hanum = NUMDATA(scp->device->host)->hanum;
     b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
-#else
-    hanum = NUMDATA(scp->host)->hanum;
-    b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-#endif
     ha    = HADATA(gdth_ctr_tab[hanum]);
 
     /* clear command tab */
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
     for (i = 0; i < GDTH_MAXCMDS; ++i) {
         cmnd = ha->cmd_tab[i].cmnd;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         if (!SPECIAL_SCP(cmnd) && cmnd->device->channel == b)
-#else
-        if (!SPECIAL_SCP(cmnd) && cmnd->channel == b)
-#endif
             ha->cmd_tab[i].cmnd = UNUSED_CMND;
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 
     if (b == ha->virt_bus) {
         /* host drives */
         for (i = 0; i < MAX_HDRIVES; ++i) {
             if (ha->hdr[i].present) {
-                GDTH_LOCK_HA(ha, flags);
+                spin_lock_irqsave(&ha->smp_lock, flags);
                 gdth_polling = TRUE;
                 while (gdth_test_busy(hanum))
                     gdth_delay(0);
@@ -5169,12 +4751,12 @@
                                       GDT_CLUST_RESET, i, 0, 0))
                     ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED;
                 gdth_polling = FALSE;
-                GDTH_UNLOCK_HA(ha, flags);
+                spin_unlock_irqrestore(&ha->smp_lock, flags);
             }
         }
     } else {
         /* raw devices */
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         for (i = 0; i < MAXID; ++i)
             ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0;
         gdth_polling = TRUE;
@@ -5183,7 +4765,7 @@
         gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS,
                           BUS_L2P(ha,b), 0, 0);
         gdth_polling = FALSE;
-        GDTH_UNLOCK_HA(ha, flags);
+	spin_unlock_irqrestore(&ha->smp_lock, flags);
     }
     return SUCCESS;
 }
@@ -5249,11 +4831,8 @@
     scp->SCp.sent_command = -1;
     scp->SCp.Status = GDTH_MAP_NONE;
     scp->SCp.buffer = (struct scatterlist *)NULL;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
     hanum = NUMDATA(scp->device->host)->hanum;
-#else
-    hanum = NUMDATA(scp->host)->hanum;
-#endif
 #ifdef GDTH_STATISTICS
     ++act_ios;
 #endif
@@ -5270,7 +4849,6 @@
 
 static int gdth_open(struct inode *inode, struct file *filep)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     gdth_ha_str *ha;
     int i;
 
@@ -5279,7 +4857,6 @@
         if (!ha->sdev)
             ha->sdev = scsi_get_host_dev(gdth_ctr_tab[i]);
     }
-#endif
 
     TRACE(("gdth_open()\n"));
     return 0;
@@ -5311,10 +4888,10 @@
             evt.event.event_data.size=sizeof(evt.event.event_data.eu.sync); 
         else
             evt.event.event_data.size=sizeof(evt.event.event_data.eu.async);
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         gdth_store_event(ha, evt.event.event_source, evt.event.event_idx,
                          &evt.event.event_data);
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
     } else if (evt.erase == 0xfe) {
         gdth_clear_events();
     } else if (evt.erase == 0) {
@@ -5344,15 +4921,15 @@
         if (j >= MAX_HDRIVES || !ha->hdr[j].present)
             continue;
         if (ldrv.lock) {
-            GDTH_LOCK_HA(ha, flags);
+            spin_lock_irqsave(&ha->smp_lock, flags);
             ha->hdr[j].lock = 1;
-            GDTH_UNLOCK_HA(ha, flags);
+            spin_unlock_irqrestore(&ha->smp_lock, flags);
             gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); 
             gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); 
         } else {
-            GDTH_LOCK_HA(ha, flags);
+            spin_lock_irqsave(&ha->smp_lock, flags);
             ha->hdr[j].lock = 0;
-            GDTH_UNLOCK_HA(ha, flags);
+            spin_unlock_irqrestore(&ha->smp_lock, flags);
             gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); 
             gdth_next(ldrv.ionode); 
         }
@@ -5367,11 +4944,9 @@
     int hanum;
     gdth_ha_str *ha;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        Scsi_Request *srp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        Scsi_Cmnd *scp;
+    Scsi_Request *srp;
 #else
-        Scsi_Cmnd scp;
+    Scsi_Cmnd *scp;
 #endif
 
     if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) ||
@@ -5398,7 +4973,7 @@
     gdth_do_req(srp, &cmd, cmnd, 30);
     res.status = (ushort)srp->sr_command->SCp.Status;
     scsi_release_request(srp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
     if (!scp)
         return -ENOMEM;
@@ -5407,15 +4982,8 @@
     gdth_do_cmd(scp, &cmd, cmnd, 30);
     res.status = (ushort)scp->SCp.Status;
     scsi_release_command(scp);
-#else
-    memset(&ha->sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-    ha->sdev.id = scp.target = ha->sdev.host->this_id;
-    scp.device = &ha->sdev;
-    gdth_do_cmd(&scp, &cmd, cmnd, 30);
-    res.status = (ushort)scp.SCp.Status;
 #endif
+
     if (copy_to_user(arg, &res, sizeof(gdth_ioctl_reset)))
         return -EFAULT;
     return 0;
@@ -5430,10 +4998,8 @@
         gdth_ha_str *ha; 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         Scsi_Request *srp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        Scsi_Cmnd *scp;
 #else
-        Scsi_Cmnd scp;
+        Scsi_Cmnd *scp;
 #endif
         
     if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) ||
@@ -5536,7 +5102,7 @@
     gen.status = srp->sr_command->SCp.Status;
     gen.info = srp->sr_command->SCp.Message;
     scsi_release_request(srp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
     if (!scp)
         return -ENOMEM;
@@ -5546,15 +5112,6 @@
     gen.status = scp->SCp.Status;
     gen.info = scp->SCp.Message;
     scsi_release_command(scp);
-#else
-    memset(&ha->sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-    ha->sdev.id = scp.target = ha->sdev.host->this_id;
-    scp.device = &ha->sdev;
-    gdth_do_cmd(&scp, &gen.command, cmnd, gen.timeout);
-    gen.status = scp.SCp.Status;
-    gen.info = scp.SCp.Message;
 #endif
 
     if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, 
@@ -5573,185 +5130,183 @@
  
 static int ioc_hdrlist(void __user *arg, char *cmnd)
 {
-    gdth_ioctl_rescan rsc;
-    gdth_cmd_str cmd;
+    gdth_ioctl_rescan *rsc;
+    gdth_cmd_str *cmd;
     gdth_ha_str *ha;
     unchar i;
-    int hanum;
+    int hanum, rc = -ENOMEM;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request *srp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    Scsi_Cmnd *scp;
 #else
-    Scsi_Cmnd scp;
+    Scsi_Cmnd *scp;
 #endif
         
-    if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) ||
-        rsc.ionode >= gdth_ctr_count)
-        return -EFAULT;
-    hanum = rsc.ionode;
+    rsc = kmalloc(sizeof(*rsc), GFP_KERNEL);
+    cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+    if (!rsc || !cmd)
+	goto free_fail;
+
+    if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) ||
+        rsc->ionode >= gdth_ctr_count) {
+        rc = -EFAULT;
+	goto free_fail;
+    }
+    hanum = rsc->ionode;
     ha = HADATA(gdth_ctr_tab[hanum]);
-    memset(&cmd, 0, sizeof(gdth_cmd_str));
+    memset(cmd, 0, sizeof(gdth_cmd_str));
    
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     srp  = scsi_allocate_request(ha->sdev, GFP_KERNEL);
     if (!srp)
-        return -ENOMEM;
+        goto free_fail;
     srp->sr_cmd_len = 12;
     srp->sr_use_sg = 0;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
     if (!scp)
-        return -ENOMEM;
+        goto free_fail;
     scp->cmd_len = 12;
     scp->use_sg = 0;
-#else
-    memset(&ha->sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-    ha->sdev.id = scp.target = ha->sdev.host->this_id;
-    scp.device = &ha->sdev;
 #endif
 
     for (i = 0; i < MAX_HDRIVES; ++i) { 
         if (!ha->hdr[i].present) {
-            rsc.hdr_list[i].bus = 0xff; 
+            rsc->hdr_list[i].bus = 0xff; 
             continue;
         } 
-        rsc.hdr_list[i].bus = ha->virt_bus;
-        rsc.hdr_list[i].target = i;
-        rsc.hdr_list[i].lun = 0;
-        rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
+        rsc->hdr_list[i].bus = ha->virt_bus;
+        rsc->hdr_list[i].target = i;
+        rsc->hdr_list[i].lun = 0;
+        rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
         if (ha->hdr[i].cluster_type & CLUSTER_DRIVE) { 
-            cmd.Service = CACHESERVICE;
-            cmd.OpCode = GDT_CLUST_INFO;
+            cmd->Service = CACHESERVICE;
+            cmd->OpCode = GDT_CLUST_INFO;
             if (ha->cache_feat & GDT_64BIT)
-                cmd.u.cache64.DeviceNo = i;
+                cmd->u.cache64.DeviceNo = i;
             else
-                cmd.u.cache.DeviceNo = i;
+                cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            gdth_do_req(srp, &cmd, cmnd, 30);
+            gdth_do_req(srp, cmd, cmnd, 30);
             if (srp->sr_command->SCp.Status == S_OK)
-                rsc.hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &cmd, cmnd, 30);
-            if (scp->SCp.Status == S_OK)
-                rsc.hdr_list[i].cluster_type = scp->SCp.Message;
+                rsc->hdr_list[i].cluster_type = srp->sr_command->SCp.Message;
 #else
-            gdth_do_cmd(&scp, &cmd, cmnd, 30);
-            if (scp.SCp.Status == S_OK)
-                rsc.hdr_list[i].cluster_type = scp.SCp.Message;
+            gdth_do_cmd(scp, cmd, cmnd, 30);
+            if (scp->SCp.Status == S_OK)
+                rsc->hdr_list[i].cluster_type = scp->SCp.Message;
 #endif
         }
     } 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(srp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
 #endif       
  
-    if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan)))
-        return -EFAULT;
-    return 0;
+    if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan)))
+        rc = -EFAULT;
+    else
+	rc = 0;
+
+free_fail:
+    kfree(rsc);
+    kfree(cmd);
+    return rc;
 }
 
 static int ioc_rescan(void __user *arg, char *cmnd)
 {
-    gdth_ioctl_rescan rsc;
-    gdth_cmd_str cmd;
+    gdth_ioctl_rescan *rsc;
+    gdth_cmd_str *cmd;
     ushort i, status, hdr_cnt;
     ulong32 info;
     int hanum, cyls, hds, secs;
+    int rc = -ENOMEM;
     ulong flags;
     gdth_ha_str *ha; 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request *srp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    Scsi_Cmnd *scp;
 #else
-    Scsi_Cmnd scp;
+    Scsi_Cmnd *scp;
 #endif
-        
-    if (copy_from_user(&rsc, arg, sizeof(gdth_ioctl_rescan)) ||
-        rsc.ionode >= gdth_ctr_count)
-        return -EFAULT;
-    hanum = rsc.ionode;
+
+    rsc = kmalloc(sizeof(*rsc), GFP_KERNEL);
+    cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+    if (!cmd || !rsc)
+	goto free_fail;
+
+    if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) ||
+        rsc->ionode >= gdth_ctr_count) {
+	rc = -EFAULT;
+	goto free_fail;
+    }
+    hanum = rsc->ionode;
     ha = HADATA(gdth_ctr_tab[hanum]);
-    memset(&cmd, 0, sizeof(gdth_cmd_str));
+    memset(cmd, 0, sizeof(gdth_cmd_str));
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     srp  = scsi_allocate_request(ha->sdev, GFP_KERNEL);
     if (!srp)
-        return -ENOMEM;
+        goto free_fail;
     srp->sr_cmd_len = 12;
     srp->sr_use_sg = 0;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
     if (!scp)
-        return -ENOMEM;
+        goto free_fail;
     scp->cmd_len = 12;
     scp->use_sg = 0;
-#else
-    memset(&ha->sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-    ha->sdev.id = scp.target = ha->sdev.host->this_id;
-    scp.device = &ha->sdev;
 #endif
      
-    if (rsc.flag == 0) {
+    if (rsc->flag == 0) {
         /* old method: re-init. cache service */
-        cmd.Service = CACHESERVICE;
+        cmd->Service = CACHESERVICE;
         if (ha->cache_feat & GDT_64BIT) {
-            cmd.OpCode = GDT_X_INIT_HOST;
-            cmd.u.cache64.DeviceNo = LINUX_OS;
+            cmd->OpCode = GDT_X_INIT_HOST;
+            cmd->u.cache64.DeviceNo = LINUX_OS;
         } else {
-            cmd.OpCode = GDT_INIT;
-            cmd.u.cache.DeviceNo = LINUX_OS;
+            cmd->OpCode = GDT_INIT;
+            cmd->u.cache.DeviceNo = LINUX_OS;
         }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
 #else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
+        gdth_do_cmd(&scp, cmd, cmnd, 30);
         status = (ushort)scp.SCp.Status;
         info = (ulong32)scp.SCp.Message;
 #endif
         i = 0;
         hdr_cnt = (status == S_OK ? (ushort)info : 0);
     } else {
-        i = rsc.hdr_no;
+        i = rsc->hdr_no;
         hdr_cnt = i + 1;
     }
+
     for (; i < hdr_cnt && i < MAX_HDRIVES; ++i) {
-        cmd.Service = CACHESERVICE;
-        cmd.OpCode = GDT_INFO;
+        cmd->Service = CACHESERVICE;
+        cmd->OpCode = GDT_INFO;
         if (ha->cache_feat & GDT_64BIT) 
-            cmd.u.cache64.DeviceNo = i;
+            cmd->u.cache64.DeviceNo = i;
         else 
-            cmd.u.cache.DeviceNo = i;
+            cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+#else
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
-#else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
-        status = (ushort)scp.SCp.Status;
-        info = (ulong32)scp.SCp.Message;
 #endif
-        GDTH_LOCK_HA(ha, flags);
-        rsc.hdr_list[i].bus = ha->virt_bus;
-        rsc.hdr_list[i].target = i;
-        rsc.hdr_list[i].lun = 0;
+        spin_lock_irqsave(&ha->smp_lock, flags);
+        rsc->hdr_list[i].bus = ha->virt_bus;
+        rsc->hdr_list[i].target = i;
+        rsc->hdr_list[i].lun = 0;
         if (status != S_OK) {
             ha->hdr[i].present = FALSE;
         } else {
@@ -5765,7 +5320,7 @@
             /* round size */
             ha->hdr[i].size = cyls * hds * secs;
         }
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
         if (status != S_OK)
             continue; 
         
@@ -5773,99 +5328,87 @@
         /* but we need ha->info2, not yet stored in scp->SCp */
 
         /* devtype, cluster info, R/W attribs */
-        cmd.Service = CACHESERVICE;
-        cmd.OpCode = GDT_DEVTYPE;
+        cmd->Service = CACHESERVICE;
+        cmd->OpCode = GDT_DEVTYPE;
         if (ha->cache_feat & GDT_64BIT) 
-            cmd.u.cache64.DeviceNo = i;
+            cmd->u.cache64.DeviceNo = i;
         else
-            cmd.u.cache.DeviceNo = i;
+            cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+#else
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
-#else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
-        status = (ushort)scp.SCp.Status;
-        info = (ulong32)scp.SCp.Message;
 #endif
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         ha->hdr[i].devtype = (status == S_OK ? (ushort)info : 0);
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
 
-        cmd.Service = CACHESERVICE;
-        cmd.OpCode = GDT_CLUST_INFO;
+        cmd->Service = CACHESERVICE;
+        cmd->OpCode = GDT_CLUST_INFO;
         if (ha->cache_feat & GDT_64BIT) 
-            cmd.u.cache64.DeviceNo = i;
+            cmd->u.cache64.DeviceNo = i;
         else
-            cmd.u.cache.DeviceNo = i;
+            cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+#else
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
-#else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
-        status = (ushort)scp.SCp.Status;
-        info = (ulong32)scp.SCp.Message;
 #endif
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         ha->hdr[i].cluster_type = 
             ((status == S_OK && !shared_access) ? (ushort)info : 0);
-        GDTH_UNLOCK_HA(ha, flags);
-        rsc.hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
+        rsc->hdr_list[i].cluster_type = ha->hdr[i].cluster_type;
 
-        cmd.Service = CACHESERVICE;
-        cmd.OpCode = GDT_RW_ATTRIBS;
+        cmd->Service = CACHESERVICE;
+        cmd->OpCode = GDT_RW_ATTRIBS;
         if (ha->cache_feat & GDT_64BIT) 
-            cmd.u.cache64.DeviceNo = i;
+            cmd->u.cache64.DeviceNo = i;
         else
-            cmd.u.cache.DeviceNo = i;
+            cmd->u.cache.DeviceNo = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-        gdth_do_req(srp, &cmd, cmnd, 30);
+        gdth_do_req(srp, cmd, cmnd, 30);
         status = (ushort)srp->sr_command->SCp.Status;
         info = (ulong32)srp->sr_command->SCp.Message;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &cmd, cmnd, 30);
+#else
+        gdth_do_cmd(scp, cmd, cmnd, 30);
         status = (ushort)scp->SCp.Status;
         info = (ulong32)scp->SCp.Message;
-#else
-        gdth_do_cmd(&scp, &cmd, cmnd, 30);
-        status = (ushort)scp.SCp.Status;
-        info = (ulong32)scp.SCp.Message;
 #endif
-        GDTH_LOCK_HA(ha, flags);
+        spin_lock_irqsave(&ha->smp_lock, flags);
         ha->hdr[i].rw_attribs = (status == S_OK ? (ushort)info : 0);
-        GDTH_UNLOCK_HA(ha, flags);
+        spin_unlock_irqrestore(&ha->smp_lock, flags);
     }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(srp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
 #endif       
  
-    if (copy_to_user(arg, &rsc, sizeof(gdth_ioctl_rescan)))
-        return -EFAULT;
-    return 0;
+    if (copy_to_user(arg, rsc, sizeof(gdth_ioctl_rescan)))
+        rc = -EFAULT;
+    else
+	rc = 0;
+
+free_fail:
+    kfree(rsc);
+    kfree(cmd);
+    return rc;
 }
   
 static int gdth_ioctl(struct inode *inode, struct file *filep,
                       unsigned int cmd, unsigned long arg)
 {
     gdth_ha_str *ha; 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-    Scsi_Cmnd *scp;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     Scsi_Cmnd *scp;
-#else
-    Scsi_Cmnd scp;
-#endif
     ulong flags;
     char cmnd[MAX_COMMAND_SIZE];   
     void __user *argp = (void __user *)arg;
@@ -5956,17 +5499,17 @@
         i = lchn.channel;
         if (i < ha->bus_cnt) {
             if (lchn.lock) {
-                GDTH_LOCK_HA(ha, flags);
+                spin_lock_irqsave(&ha->smp_lock, flags);
                 ha->raw[i].lock = 1;
-                GDTH_UNLOCK_HA(ha, flags);
+                spin_unlock_irqrestore(&ha->smp_lock, flags);
                 for (j = 0; j < ha->tid_cnt; ++j) {
                     gdth_wait_completion(lchn.ionode, i, j); 
                     gdth_stop_timeout(lchn.ionode, i, j); 
                 }
             } else {
-                GDTH_LOCK_HA(ha, flags);
+                spin_lock_irqsave(&ha->smp_lock, flags);
                 ha->raw[i].lock = 0;
-                GDTH_UNLOCK_HA(ha, flags);
+                spin_unlock_irqrestore(&ha->smp_lock, flags);
                 for (j = 0; j < ha->tid_cnt; ++j) {
                     gdth_start_timeout(lchn.ionode, i, j); 
                     gdth_next(lchn.ionode); 
@@ -6004,7 +5547,7 @@
         rval = gdth_eh_bus_reset(scp);
         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
         scsi_put_command(scp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
         scp  = scsi_allocate_device(ha->sdev, 1, FALSE);
         if (!scp)
             return -ENOMEM;
@@ -6014,15 +5557,6 @@
         rval = gdth_eh_bus_reset(scp);
         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
         scsi_release_command(scp);
-#else 
-        memset(&ha->sdev,0,sizeof(Scsi_Device));
-        memset(&scp, 0,sizeof(Scsi_Cmnd));
-        ha->sdev.host = scp.host = gdth_ctr_tab[hanum];
-        ha->sdev.id = scp.target = ha->sdev.host->this_id;
-        scp.device = &ha->sdev;
-        scp.channel = virt_ctr ? 0 : res.number;
-        rval = gdth_eh_bus_reset(&scp);
-        res.status = (rval == SUCCESS ? S_OK : S_GENERR);
 #endif
         if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset)))
             return -EFAULT;
@@ -6047,14 +5581,10 @@
     gdth_cmd_str    gdtcmd;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request    *srp;
-    Scsi_Device     *sdev;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    Scsi_Cmnd       *scp;
-    Scsi_Device     *sdev;
 #else
-    Scsi_Cmnd       scp;
-    Scsi_Device     sdev;
+    Scsi_Cmnd       *scp;
 #endif
+    Scsi_Device     *sdev;
     char            cmnd[MAX_COMMAND_SIZE];   
     memset(cmnd, 0xff, MAX_COMMAND_SIZE);
 
@@ -6068,19 +5598,13 @@
         return;
     srp->sr_cmd_len = 12;
     srp->sr_use_sg = 0;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
         return;
     scp->cmd_len = 12;
     scp->use_sg = 0;
-#else
-    memset(&sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    sdev.host = scp.host = gdth_ctr_tab[hanum];
-    sdev.id = scp.target = sdev.host->this_id;
-    scp.device = &sdev;
 #endif
 
     for (i = 0; i < MAX_HDRIVES; ++i) {
@@ -6100,17 +5624,15 @@
             TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i));
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
             gdth_do_req(srp, &gdtcmd, cmnd, 30);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
-            gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
+            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #endif
         }
     }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(srp);
     scsi_free_host_dev(sdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
@@ -6125,12 +5647,9 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request    *srp;
     Scsi_Device     *sdev;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     Scsi_Cmnd       *scp;
     Scsi_Device     *sdev;
-#else
-    Scsi_Cmnd       scp;
-    Scsi_Device     sdev;
 #endif
     char            cmnd[MAX_COMMAND_SIZE];   
 #endif
@@ -6162,7 +5681,7 @@
         gdth_do_req(srp, &gdtcmd, cmnd, 10);
         scsi_release_request(srp);
         scsi_free_host_dev(sdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
         sdev = scsi_get_host_dev(gdth_ctr_tab[hanum]);
         scp  = scsi_allocate_device(sdev, 1, FALSE);
         if (!scp) {
@@ -6174,13 +5693,6 @@
         gdth_do_cmd(scp, &gdtcmd, cmnd, 10);
         scsi_release_command(scp);
         scsi_free_host_dev(sdev);
-#else
-        memset(&sdev,0,sizeof(Scsi_Device));
-        memset(&scp, 0,sizeof(Scsi_Cmnd));
-        sdev.host = scp.host = gdth_ctr_tab[hanum];
-        sdev.id = scp.target = sdev.host->this_id;
-        scp.device = &sdev;
-        gdth_do_cmd(&scp, &gdtcmd, cmnd, 10);
 #endif
 #endif
     }
@@ -6193,19 +5705,6 @@
     return NOTIFY_OK;
 }
 
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) && !defined(MODULE)
-
-GDTH_INITFUNC(void, gdth_setup(char *str,int *ints)) 
-{    
-    TRACE2(("gdth_setup() str %s ints[0] %d\n", 
-            str ? str:"NULL", ints ? ints[0]:0));
-    internal_setup(str, ints);
-}
-
-#else
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 static Scsi_Host_Template driver_template = {
         .proc_name              = "gdth", 
         .proc_info              = gdth_proc_info,
@@ -6232,13 +5731,8 @@
 #endif
 #endif
 };
-#else
-static Scsi_Host_Template driver_template = GDTH;
-#endif
 
 #include "scsi_module.c"
 #ifndef MODULE
 __setup("gdth=", option_setup);
-#endif
-
 #endif
diff -Nru a/drivers/scsi/gdth_kcompat.h b/drivers/scsi/gdth_kcompat.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/scsi/gdth_kcompat.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,21 @@
+
+
+#ifndef IRQ_HANDLED
+typedef void irqreturn_t;
+#define IRQ_NONE
+#define IRQ_HANDLED
+#endif
+
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(x)
+#endif
+
+#ifndef SERVICE_ACTION_IN
+#define SERVICE_ACTION_IN	0x9e
+#endif
+#ifndef READ_16
+#define READ_16			0x88
+#endif
+#ifndef WRITE_16
+#define WRITE_16		0x8a
+#endif
diff -Nru a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
--- a/drivers/scsi/gdth_proc.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/gdth_proc.c	2005-01-19 13:44:46 -08:00
@@ -2,9 +2,7 @@
  * $Id: gdth_proc.c,v 1.42 2004/03/05 15:50:20 achim Exp $
  */
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
 #include <linux/completion.h>
-#endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length,   
@@ -57,12 +55,9 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request    *scp;
     Scsi_Device     *sdev;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     Scsi_Cmnd       *scp;
     Scsi_Device     *sdev;
-#else
-    Scsi_Cmnd       scp;
-    Scsi_Device     sdev;
 #endif
     TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum));
 
@@ -73,19 +68,13 @@
         return -ENOMEM;
     scp->sr_cmd_len = 12;
     scp->sr_use_sg = 0;
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     sdev = scsi_get_host_dev(host);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
         return -ENOMEM;
     scp->cmd_len = 12;
     scp->use_sg = 0;
-#else
-    memset(&sdev,0,sizeof(Scsi_Device));
-    memset(&scp, 0,sizeof(Scsi_Cmnd));
-    sdev.host = scp.host = host;
-    sdev.id = scp.target = sdev.host->this_id;
-    scp.device = &sdev;
 #endif
 
     if (length >= 4) {
@@ -98,7 +87,7 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(scp);
     scsi_free_host_dev(sdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
@@ -107,10 +96,8 @@
          
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp)
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
 #else
-static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
+static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp)
 #endif
 {
     int             orig_length, drive, wb_mode;
@@ -161,10 +148,8 @@
                 }
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
                 gdth_do_req(scp, &gdtcmd, cmnd, 30);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-                gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
-                gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
+                gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #endif
             }
         }
@@ -219,10 +204,8 @@
         pcpar->write_back = wb_mode==1 ? 0:1;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         gdth_do_req(scp, &gdtcmd, cmnd, 30);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-        gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #else
-        gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
+        gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
 #endif
         gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr);
         printk("Done.\n");
@@ -243,18 +226,16 @@
     int no_mdrv = 0, drv_no, is_mirr;
     ulong32 cnt;
     ulong64 paddr;
+    int rc = -ENOMEM;
 
-    gdth_cmd_str gdtcmd;
-    gdth_evt_str estr;
+    gdth_cmd_str *gdtcmd;
+    gdth_evt_str *estr;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     Scsi_Request *scp;
     Scsi_Device *sdev; 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     Scsi_Cmnd *scp;
     Scsi_Device *sdev;
-#else
-    Scsi_Cmnd scp;
-    Scsi_Device sdev;
 #endif
     char hrec[161];
     struct timeval tv;
@@ -266,10 +247,15 @@
     gdth_defcnt_str *pdef;
     gdth_cdrinfo_str *pcdi;
     gdth_hget_str *phg;
-
     char cmnd[MAX_COMMAND_SIZE];
+
+    gdtcmd = kmalloc(sizeof(*gdtcmd), GFP_KERNEL);
+    estr = kmalloc(sizeof(*estr), GFP_KERNEL);
+    if (!gdtcmd || !estr)
+	goto free_fail;
+
     memset(cmnd, 0xff, 12);
-    memset(&gdtcmd, 0, sizeof(gdth_cmd_str));
+    memset(gdtcmd, 0, sizeof(gdth_cmd_str));
 
     TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum));
     ha = HADATA(gdth_ctr_tab[hanum]);
@@ -278,14 +264,14 @@
     sdev = scsi_get_host_dev(host);
     scp  = scsi_allocate_request(sdev, GFP_KERNEL);
     if (!scp)
-        return -ENOMEM;
+        goto free_fail;
     scp->sr_cmd_len = 12;
     scp->sr_use_sg = 0;
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
     sdev = scsi_get_host_dev(host);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
-        return -ENOMEM;
+        goto free_fail;
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -387,12 +373,12 @@
             /* 2.a statistics (and retries/reassigns) */
             TRACE2(("pdr_statistics() chn %d\n",i));                
             pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
-            gdtcmd.Service = CACHESERVICE;
-            gdtcmd.OpCode = GDT_IOCTL;
-            gdtcmd.u.ioctl.p_param = paddr + GDTH_SCRATCH/4;
-            gdtcmd.u.ioctl.param_size = 3*GDTH_SCRATCH/4;
-            gdtcmd.u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN;
-            gdtcmd.u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL;
+            gdtcmd->Service = CACHESERVICE;
+            gdtcmd->OpCode = GDT_IOCTL;
+            gdtcmd->u.ioctl.p_param = paddr + GDTH_SCRATCH/4;
+            gdtcmd->u.ioctl.param_size = 3*GDTH_SCRATCH/4;
+            gdtcmd->u.ioctl.subfunc = DSK_STATISTICS | L_CTRL_PATTERN;
+            gdtcmd->u.ioctl.channel = ha->raw[i].address | INVALID_CHANNEL;
             pds->bid = ha->raw[i].local_no;
             pds->first = 0;
             pds->entries = ha->raw[i].pdev_cnt;
@@ -401,14 +387,11 @@
             if (pds->entries > cnt)
                 pds->entries = cnt;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            gdth_do_req(scp, gdtcmd, cmnd, 30);
             if (scp->sr_command->SCp.Status != S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-            if (scp->SCp.Status != S_OK) 
 #else
-            gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-            if (scp.SCp.Status != S_OK) 
+            gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+            if (scp->SCp.Status != S_OK) 
 #endif
             { 
                 pds->count = 0;
@@ -420,22 +403,19 @@
                 TRACE2(("scsi_drv_info() chn %d dev %d\n",
                     i, ha->raw[i].id_list[j]));             
                 pdi = (gdth_diskinfo_str *)buf;
-                gdtcmd.Service = CACHESERVICE;
-                gdtcmd.OpCode = GDT_IOCTL;
-                gdtcmd.u.ioctl.p_param = paddr;
-                gdtcmd.u.ioctl.param_size = sizeof(gdth_diskinfo_str);
-                gdtcmd.u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
-                gdtcmd.u.ioctl.channel = 
+                gdtcmd->Service = CACHESERVICE;
+                gdtcmd->OpCode = GDT_IOCTL;
+                gdtcmd->u.ioctl.p_param = paddr;
+                gdtcmd->u.ioctl.param_size = sizeof(gdth_diskinfo_str);
+                gdtcmd->u.ioctl.subfunc = SCSI_DR_INFO | L_CTRL_PATTERN;
+                gdtcmd->u.ioctl.channel = 
                     ha->raw[i].address | ha->raw[i].id_list[j];
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-                gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                gdth_do_req(scp, gdtcmd, cmnd, 30);
                 if (scp->sr_command->SCp.Status == S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-                gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-                if (scp->SCp.Status == S_OK) 
 #else
-                gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-                if (scp.SCp.Status == S_OK) 
+                gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+                if (scp->SCp.Status == S_OK) 
 #endif
                 {
                     strncpy(hrec,pdi->vendor,8);
@@ -478,23 +458,20 @@
                     TRACE2(("scsi_drv_defcnt() chn %d dev %d\n",
                             i, ha->raw[i].id_list[j]));             
                     pdef = (gdth_defcnt_str *)buf;
-                    gdtcmd.Service = CACHESERVICE;
-                    gdtcmd.OpCode = GDT_IOCTL;
-                    gdtcmd.u.ioctl.p_param = paddr;
-                    gdtcmd.u.ioctl.param_size = sizeof(gdth_defcnt_str);
-                    gdtcmd.u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN;
-                    gdtcmd.u.ioctl.channel = 
+                    gdtcmd->Service = CACHESERVICE;
+                    gdtcmd->OpCode = GDT_IOCTL;
+                    gdtcmd->u.ioctl.p_param = paddr;
+                    gdtcmd->u.ioctl.param_size = sizeof(gdth_defcnt_str);
+                    gdtcmd->u.ioctl.subfunc = SCSI_DEF_CNT | L_CTRL_PATTERN;
+                    gdtcmd->u.ioctl.channel = 
                         ha->raw[i].address | ha->raw[i].id_list[j];
                     pdef->sddc_type = 0x08;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-                    gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                    gdth_do_req(scp, gdtcmd, cmnd, 30);
                     if (scp->sr_command->SCp.Status == S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-                    gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-                    if (scp->SCp.Status == S_OK) 
 #else
-                    gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-                    if (scp.SCp.Status == S_OK) 
+                    gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+                    if (scp->SCp.Status == S_OK) 
 #endif
                     {
                         size = sprintf(buffer+len,
@@ -536,21 +513,18 @@
                 /* 3.a log. drive info */
                 TRACE2(("cache_drv_info() drive no %d\n",drv_no));
                 pcdi = (gdth_cdrinfo_str *)buf;
-                gdtcmd.Service = CACHESERVICE;
-                gdtcmd.OpCode = GDT_IOCTL;
-                gdtcmd.u.ioctl.p_param = paddr;
-                gdtcmd.u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
-                gdtcmd.u.ioctl.subfunc = CACHE_DRV_INFO;
-                gdtcmd.u.ioctl.channel = drv_no;
+                gdtcmd->Service = CACHESERVICE;
+                gdtcmd->OpCode = GDT_IOCTL;
+                gdtcmd->u.ioctl.p_param = paddr;
+                gdtcmd->u.ioctl.param_size = sizeof(gdth_cdrinfo_str);
+                gdtcmd->u.ioctl.subfunc = CACHE_DRV_INFO;
+                gdtcmd->u.ioctl.channel = drv_no;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-                gdth_do_req(scp, &gdtcmd, cmnd, 30);
+                gdth_do_req(scp, gdtcmd, cmnd, 30);
                 if (scp->sr_command->SCp.Status != S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-                gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-                if (scp->SCp.Status != S_OK)
 #else
-                gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-                if (scp.SCp.Status != S_OK)
+                gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+                if (scp->SCp.Status != S_OK)
 #endif
                 {
                     break;
@@ -649,21 +623,18 @@
             /* 4.a array drive info */
             TRACE2(("array_info() drive no %d\n",i));
             pai = (gdth_arrayinf_str *)buf;
-            gdtcmd.Service = CACHESERVICE;
-            gdtcmd.OpCode = GDT_IOCTL;
-            gdtcmd.u.ioctl.p_param = paddr;
-            gdtcmd.u.ioctl.param_size = sizeof(gdth_arrayinf_str);
-            gdtcmd.u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
-            gdtcmd.u.ioctl.channel = i;
+            gdtcmd->Service = CACHESERVICE;
+            gdtcmd->OpCode = GDT_IOCTL;
+            gdtcmd->u.ioctl.p_param = paddr;
+            gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str);
+            gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;
+            gdtcmd->u.ioctl.channel = i;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            gdth_do_req(scp, gdtcmd, cmnd, 30);
             if (scp->sr_command->SCp.Status == S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-            if (scp->SCp.Status == S_OK) 
 #else
-            gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-            if (scp.SCp.Status == S_OK) 
+            gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+            if (scp->SCp.Status == S_OK) 
 #endif
             {
                 if (pai->ai_state == 0)
@@ -731,23 +702,20 @@
             /* 5.a get host drive list */
             TRACE2(("host_get() drv_no %d\n",i));           
             phg = (gdth_hget_str *)buf;
-            gdtcmd.Service = CACHESERVICE;
-            gdtcmd.OpCode = GDT_IOCTL;
-            gdtcmd.u.ioctl.p_param = paddr;
-            gdtcmd.u.ioctl.param_size = sizeof(gdth_hget_str);
-            gdtcmd.u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;
-            gdtcmd.u.ioctl.channel = i;
+            gdtcmd->Service = CACHESERVICE;
+            gdtcmd->OpCode = GDT_IOCTL;
+            gdtcmd->u.ioctl.p_param = paddr;
+            gdtcmd->u.ioctl.param_size = sizeof(gdth_hget_str);
+            gdtcmd->u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;
+            gdtcmd->u.ioctl.channel = i;
             phg->entries = MAX_HDRIVES;
             phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]); 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            gdth_do_req(scp, &gdtcmd, cmnd, 30);
+            gdth_do_req(scp, gdtcmd, cmnd, 30);
             if (scp->sr_command->SCp.Status != S_OK) 
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-            gdth_do_cmd(scp, &gdtcmd, cmnd, 30);
-            if (scp->SCp.Status != S_OK) 
 #else
-            gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
-            if (scp.SCp.Status != S_OK) 
+            gdth_do_cmd(scp, gdtcmd, cmnd, 30);
+            if (scp->SCp.Status != S_OK) 
 #endif
             {
                 ha->hdr[i].ldr_no = i;
@@ -799,14 +767,14 @@
     len += size;  pos = begin + len;
 
     for (id = -1;;) {
-        id = gdth_read_event(ha, id, &estr);
-        if (estr.event_source == 0)
+        id = gdth_read_event(ha, id, estr);
+        if (estr->event_source == 0)
             break;
-        if (estr.event_data.eu.driver.ionode == hanum &&
-            estr.event_source == ES_ASYNC) { 
-            gdth_log_event(&estr.event_data, hrec);
+        if (estr->event_data.eu.driver.ionode == hanum &&
+            estr->event_source == ES_ASYNC) { 
+            gdth_log_event(&estr->event_data, hrec);
             do_gettimeofday(&tv);
-            sec = (int)(tv.tv_sec - estr.first_stamp);
+            sec = (int)(tv.tv_sec - estr->first_stamp);
             if (sec < 0) sec = 0;
             size = sprintf(buffer+len," date- %02d:%02d:%02d\t%s\n",
                            sec/3600, sec%3600/60, sec%60, hrec);
@@ -826,7 +794,7 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     scsi_release_request(scp);
     scsi_free_host_dev(sdev);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
     scsi_release_command(scp);
     scsi_free_host_dev(sdev);
 #endif
@@ -836,7 +804,12 @@
         len = length;
     TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n",
             len,(int)pos,(int)begin,(int)offset,length,size));
-    return(len);
+    rc = len;
+
+free_fail:
+    kfree(gdtcmd);
+    kfree(estr);
+    return rc;
 }
 
 
@@ -864,13 +837,7 @@
                         char *cmnd, int timeout)
 {
     unsigned bufflen;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
     DECLARE_COMPLETION(wait);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    DECLARE_MUTEX_LOCKED(sem);
-#else
-    struct semaphore sem = MUTEX_LOCKED;
-#endif
 
     TRACE2(("gdth_do_cmd()\n"));
     if (gdtcmd != NULL) { 
@@ -880,22 +847,11 @@
         scp->SCp.this_residual = DEFAULT_PRI;
         bufflen = 0;
     }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
+
     scp->request.rq_status = RQ_SCSI_BUSY;
     scp->request.waiting = &wait;
     scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
     wait_for_completion(&wait);
-#else
-    scp->request.sem = &sem;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-    scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
-#else
-    spin_lock_irq(&io_request_lock);
-    scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
-    spin_unlock_irq(&io_request_lock);
-#endif
-    down(&sem);
-#endif
 }
 #endif
 
@@ -907,14 +863,10 @@
     scp->request->rq_status = RQ_SCSI_DONE;
     if (scp->request->waiting != NULL)
         complete(scp->request->waiting);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
+#else
     scp->request.rq_status = RQ_SCSI_DONE;
     if (scp->request.waiting != NULL)
         complete(scp->request.waiting);
-#else
-    scp->request.rq_status = RQ_SCSI_DONE;
-    if (scp->request.sem != NULL)
-        up(scp->request.sem);
 #endif
 }
 
@@ -929,7 +881,7 @@
         return NULL;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     if (!ha->scratch_busy && size <= GDTH_SCRATCH) {
         ha->scratch_busy = TRUE;
@@ -938,19 +890,13 @@
     } else if (scratch) {
         ret_val = NULL;
     } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
         dma_addr_t dma_addr;
 
         ret_val = pci_alloc_consistent(ha->pdev, size, &dma_addr);
         *paddr = dma_addr;
-#else
-        ret_val = scsi_init_malloc(size, GFP_ATOMIC | GFP_DMA);
-        if (ret_val)
-            *paddr = virt_to_bus(ret_val);
-#endif
     }
 
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
     return ret_val;
 }
 
@@ -960,19 +906,15 @@
     ulong flags;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     if (buf == ha->pscratch) {
         ha->scratch_busy = FALSE;
     } else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
         pci_free_consistent(ha->pdev, size, buf, paddr);
-#else
-        scsi_init_free((void *)buf, size);
-#endif
     }
 
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 #ifdef GDTH_IOCTL_PROC
@@ -983,14 +925,14 @@
     int ret_val;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     ret_val = FALSE;
     if (ha->scratch_busy) {
         if (((gdth_iord_str *)ha->pscratch)->size == (ulong32)size)
             ret_val = TRUE;
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
     return ret_val;
 }
 #endif
@@ -1004,36 +946,23 @@
     unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     for (i = 0; i < GDTH_MAXCMDS; ++i) {
         scp = ha->cmd_tab[i].cmnd;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         t = scp->device->id;
-#else
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        t = scp->target;
-#endif
         if (!SPECIAL_SCP(scp) && t == (unchar)id && 
             b == (unchar)busnum) {
             scp->SCp.have_data_in = 0;
-            GDTH_UNLOCK_HA(ha, flags);
+            spin_unlock_irqrestore(&ha->smp_lock, flags);
             while (!scp->SCp.have_data_in)
                 barrier();
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            GDTH_LOCK_SCSI_DONE(scp->device->host, flags);
-            scp->scsi_done(scp);
-            GDTH_UNLOCK_SCSI_DONE(scp->device->host, flags);
-#else
-            GDTH_LOCK_SCSI_DONE(flags);
-            scp->scsi_done(scp);
-            GDTH_UNLOCK_SCSI_DONE(flags);
-#endif
-        GDTH_LOCK_HA(ha, flags);
+            spin_lock_irqsave(&ha->smp_lock, flags);
         }
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 static void gdth_stop_timeout(int hanum, int busnum, int id)
@@ -1044,22 +973,17 @@
     unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         t = scp->device->id;
-#else
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        t = scp->target;
-#endif
         if (t == (unchar)id && b == (unchar)busnum) {
             TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
             scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);
         }
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 static void gdth_start_timeout(int hanum, int busnum, int id)
@@ -1070,22 +994,17 @@
     unchar b, t;
 
     ha = HADATA(gdth_ctr_tab[hanum]);
-    GDTH_LOCK_HA(ha, flags);
+    spin_lock_irqsave(&ha->smp_lock, flags);
 
     for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
         b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel;
         t = scp->device->id;
-#else
-        b = virt_ctr ? NUMDATA(scp->host)->busnum : scp->channel;
-        t = scp->target;
-#endif
         if (t == (unchar)id && b == (unchar)busnum) {
             TRACE2(("gdth_start_timeout(): update_timeout()\n"));
             gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);
         }
     }
-    GDTH_UNLOCK_HA(ha, flags);
+    spin_unlock_irqrestore(&ha->smp_lock, flags);
 }
 
 static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout)
diff -Nru a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h
--- a/drivers/scsi/gdth_proc.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/gdth_proc.h	2005-01-19 13:44:47 -08:00
@@ -14,14 +14,10 @@
 static void gdth_do_req(Scsi_Request *srp, gdth_cmd_str *cmd, 
                         char *cmnd, int timeout);
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Request *scp);
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#else
 static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
                         char *cmnd, int timeout);
 static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd *scp);
-#else 
-static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
-                        char *cmnd, int timeout);
-static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
 #endif
 
 static char *gdth_ioctl_alloc(int hanum, int size, int scratch,
diff -Nru a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c	2005-01-19 13:44:46 -08:00
@@ -87,7 +87,7 @@
 static int init_timeout = 5;
 static int max_requests = 50;
 
-#define IBMVSCSI_VERSION "1.5.1"
+#define IBMVSCSI_VERSION "1.5.5"
 
 MODULE_DESCRIPTION("IBM Virtual SCSI");
 MODULE_AUTHOR("Dave Boutcher");
@@ -256,6 +256,7 @@
 {
 	evt_struct->cmnd = NULL;
 	evt_struct->cmnd_done = NULL;
+	evt_struct->sync_srp = NULL;
 	evt_struct->crq.format = format;
 	evt_struct->crq.timeout = timeout;
 	evt_struct->done = done;
@@ -467,7 +468,7 @@
 static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
 				   struct ibmvscsi_host_data *hostdata)
 {
-	struct scsi_cmnd *cmnd = evt_struct->cmnd;
+	struct scsi_cmnd *cmnd;
 	u64 *crq_as_u64 = (u64 *) &evt_struct->crq;
 	int rc;
 
@@ -479,22 +480,15 @@
 	if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) &&
 	    (atomic_dec_if_positive(&hostdata->request_limit) < 0)) {
 		/* See if the adapter is disabled */
-		if (atomic_read(&hostdata->request_limit) < 0) {
-			if (cmnd)
-				cmnd->result = DID_ERROR << 16;
-			if (evt_struct->cmnd_done)
-				evt_struct->cmnd_done(cmnd);
-			unmap_cmd_data(&evt_struct->iu.srp.cmd,
-				       hostdata->dev);
-			free_event_struct(&hostdata->pool, evt_struct);
-			return 0;
-		} else {
-			printk("ibmvscsi: Warning, request_limit exceeded\n");
-			unmap_cmd_data(&evt_struct->iu.srp.cmd,
-				       hostdata->dev);
-			free_event_struct(&hostdata->pool, evt_struct);
-			return SCSI_MLQUEUE_HOST_BUSY;
-		}
+		if (atomic_read(&hostdata->request_limit) < 0)
+			goto send_error;
+	
+		printk(KERN_WARNING 
+		       "ibmvscsi: Warning, request_limit exceeded\n");
+		unmap_cmd_data(&evt_struct->iu.srp.cmd,
+			       hostdata->dev);
+		free_event_struct(&hostdata->pool, evt_struct);
+		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	/* Copy the IU into the transfer area */
@@ -511,18 +505,24 @@
 	     ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) {
 		list_del(&evt_struct->list);
 
-		cmnd = evt_struct->cmnd;
 		printk(KERN_ERR "ibmvscsi: failed to send event struct rc %d\n",
 		       rc);
-		unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev);
-		free_event_struct(&hostdata->pool, evt_struct);
-		if (cmnd)
-			cmnd->result = DID_ERROR << 16;
-		if (evt_struct->cmnd_done)
-			evt_struct->cmnd_done(cmnd);
+		goto send_error;
 	}
 
 	return 0;
+
+ send_error:
+	unmap_cmd_data(&evt_struct->iu.srp.cmd, hostdata->dev);
+
+	if ((cmnd = evt_struct->cmnd) != NULL) {
+		cmnd->result = DID_ERROR << 16;
+		evt_struct->cmnd_done(cmnd);
+	} else if (evt_struct->done)
+		evt_struct->done(evt_struct);
+	
+	free_event_struct(&hostdata->pool, evt_struct);
+	return 0;
 }
 
 /**
@@ -537,6 +537,13 @@
 	struct srp_rsp *rsp = &evt_struct->xfer_iu->srp.rsp;
 	struct scsi_cmnd *cmnd = evt_struct->cmnd;
 
+	if (unlikely(rsp->type != SRP_RSP_TYPE)) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+			       "ibmvscsi: bad SRP RSP type %d\n",
+			       rsp->type);
+	}
+	
 	if (cmnd) {
 		cmnd->result = rsp->status;
 		if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION)
@@ -641,11 +648,16 @@
 		       evt_struct->xfer_iu->mad.adapter_info.common.status);
 	} else {
 		printk("ibmvscsi: host srp version: %s, "
-		       "host partition %s (%d), OS %d\n",
+		       "host partition %s (%d), OS %d, max io %u\n",
 		       hostdata->madapter_info.srp_version,
 		       hostdata->madapter_info.partition_name,
 		       hostdata->madapter_info.partition_number,
-		       hostdata->madapter_info.os_type);
+		       hostdata->madapter_info.os_type,
+		       hostdata->madapter_info.port_max_txu[0]);
+		
+		if (hostdata->madapter_info.port_max_txu[0]) 
+			hostdata->host->max_sectors = 
+				hostdata->madapter_info.port_max_txu[0] >> 9;
 	}
 }
 
@@ -796,6 +808,10 @@
  */
 static void sync_completion(struct srp_event_struct *evt_struct)
 {
+	/* copy the response back */
+	if (evt_struct->sync_srp)
+		*evt_struct->sync_srp = *evt_struct->xfer_iu;
+	
 	complete(&evt_struct->comp);
 }
 
@@ -810,6 +826,8 @@
 	struct srp_tsk_mgmt *tsk_mgmt;
 	struct srp_event_struct *evt;
 	struct srp_event_struct *tmp_evt, *found_evt;
+	union viosrp_iu srp_rsp;
+	int rsp_rc;
 	u16 lun = lun_from_dev(cmd->device);
 
 	/* First, find this command in our sent list so we can figure
@@ -849,6 +867,7 @@
 	printk(KERN_INFO "ibmvscsi: aborting command. lun 0x%lx, tag 0x%lx\n",
 	       tsk_mgmt->lun, tsk_mgmt->managed_task_tag);
 
+	evt->sync_srp = &srp_rsp;
 	init_completion(&evt->comp);
 	if (ibmvscsi_send_srp_event(evt, hostdata) != 0) {
 		printk(KERN_ERR "ibmvscsi: failed to send abort() event\n");
@@ -859,6 +878,29 @@
 	wait_for_completion(&evt->comp);
 	spin_lock_irq(hostdata->host->host_lock);
 
+	/* make sure we got a good response */
+	if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+			       "ibmvscsi: abort bad SRP RSP type %d\n",
+			       srp_rsp.srp.generic.type);
+		return FAILED;
+	}
+
+	if (srp_rsp.srp.rsp.rspvalid)
+		rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data);
+	else
+		rsp_rc = srp_rsp.srp.rsp.status;
+
+	if (rsp_rc) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+		       "ibmvscsi: abort code %d for task tag 0x%lx\n",
+			       rsp_rc,
+			       tsk_mgmt->managed_task_tag);
+		return FAILED;
+	}
+
 	/* Because we dropped the spinlock above, it's possible
 	 * The event is no longer in our list.  Make sure it didn't
 	 * complete while we were aborting
@@ -871,13 +913,17 @@
 		}
 	}
 
+	if (found_evt == NULL) {
+		printk(KERN_INFO
+		       "ibmvscsi: aborted task tag 0x%lx completed\n",
+		       tsk_mgmt->managed_task_tag);
+		return SUCCESS;
+	}
+
 	printk(KERN_INFO
 	       "ibmvscsi: successfully aborted task tag 0x%lx\n",
 	       tsk_mgmt->managed_task_tag);
 
-	if (found_evt == NULL)
-		return SUCCESS;
-
 	cmd->result = (DID_ABORT << 16);
 	list_del(&found_evt->list);
 	unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt->hostdata->dev);
@@ -899,6 +945,8 @@
 	struct srp_tsk_mgmt *tsk_mgmt;
 	struct srp_event_struct *evt;
 	struct srp_event_struct *tmp_evt, *pos;
+	union viosrp_iu srp_rsp;
+	int rsp_rc;
 	u16 lun = lun_from_dev(cmd->device);
 
 	evt = get_event_struct(&hostdata->pool);
@@ -923,6 +971,7 @@
 	printk(KERN_INFO "ibmvscsi: resetting device. lun 0x%lx\n",
 	       tsk_mgmt->lun);
 
+	evt->sync_srp = &srp_rsp;
 	init_completion(&evt->comp);
 	if (ibmvscsi_send_srp_event(evt, hostdata) != 0) {
 		printk(KERN_ERR "ibmvscsi: failed to send reset event\n");
@@ -933,6 +982,29 @@
 	wait_for_completion(&evt->comp);
 	spin_lock_irq(hostdata->host->host_lock);
 
+	/* make sure we got a good response */
+	if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+			       "ibmvscsi: reset bad SRP RSP type %d\n",
+			       srp_rsp.srp.generic.type);
+		return FAILED;
+	}
+
+	if (srp_rsp.srp.rsp.rspvalid)
+		rsp_rc = *((int *)srp_rsp.srp.rsp.sense_and_response_data);
+	else
+		rsp_rc = srp_rsp.srp.rsp.status;
+
+	if (rsp_rc) {
+		if (printk_ratelimit())
+			printk(KERN_WARNING 
+			       "ibmvscsi: reset code %d for task tag 0x%lx\n",
+		       rsp_rc,
+			       tsk_mgmt->managed_task_tag);
+		return FAILED;
+	}
+
 	/* We need to find all commands for this LUN that have not yet been
 	 * responded to, and fail them with DID_RESET
 	 */
@@ -1048,6 +1120,13 @@
 		return;
 	}
 
+	if (atomic_read(&evt_struct->free)) {
+		printk(KERN_ERR
+		       "ibmvscsi: received duplicate  correlation_token 0x%p!\n",
+		       (void *)crq->IU_data_ptr);
+		return;
+	}
+
 	if (crq->format == VIOSRP_SRP_FORMAT)
 		atomic_add(evt_struct->xfer_iu->srp.rsp.request_limit_delta,
 			   &hostdata->request_limit);
@@ -1295,6 +1374,7 @@
 	hostdata->host = host;
 	hostdata->dev = dev;
 	atomic_set(&hostdata->request_limit, -1);
+	hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */
 
 	if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata,
 				    max_requests) != 0) {
@@ -1326,7 +1406,7 @@
 		 */
 		for (wait_switch = jiffies + (init_timeout * HZ);
 		     time_before(jiffies, wait_switch) &&
-		     atomic_read(&hostdata->request_limit) < 0;) {
+		     atomic_read(&hostdata->request_limit) < 2;) {
 
 			msleep(10);
 		}
diff -Nru a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h	2005-01-19 13:44:47 -08:00
@@ -67,6 +67,7 @@
 	union viosrp_iu iu;
 	void (*cmnd_done) (struct scsi_cmnd *);
 	struct completion comp;
+	union viosrp_iu *sync_srp;
 };
 
 /* a pool of event structs for use */
diff -Nru a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
--- a/drivers/scsi/ipr.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/scsi/ipr.c	2005-01-19 13:44:48 -08:00
@@ -2610,23 +2610,19 @@
 #endif
 
 /**
- * ipr_store_queue_depth - Change the device's queue depth
- * @dev:	device struct
- * @buf:	buffer
+ * ipr_change_queue_depth - Change the device's queue depth
+ * @sdev:	scsi device struct
+ * @qdepth:	depth to set
  *
  * Return value:
- * 	number of bytes printed to buffer
+ * 	actual depth set
  **/
-static ssize_t ipr_store_queue_depth(struct device *dev,
-				    const char *buf, size_t count)
+static int ipr_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
-	struct scsi_device *sdev = to_scsi_device(dev);
 	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
 	struct ipr_resource_entry *res;
-	int qdepth = simple_strtoul(buf, NULL, 10);
 	int tagged = 0;
 	unsigned long lock_flags = 0;
-	ssize_t len = -ENXIO;
 
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 	res = (struct ipr_resource_entry *)sdev->hostdata;
@@ -2635,23 +2631,13 @@
 
 		if (ipr_is_gscsi(res) && res->tcq_active)
 			tagged = MSG_ORDERED_TAG;
-
-		len = strlen(buf);
 	}
 
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 	scsi_adjust_queue_depth(sdev, tagged, qdepth);
-	return len;
+	return qdepth;
 }
 
-static struct device_attribute ipr_queue_depth_attr = {
-	.attr = {
-		.name = 	"queue_depth",
-		.mode =		S_IRUSR | S_IWUSR,
-	},
-	.store = ipr_store_queue_depth
-};
-
 /**
  * ipr_show_tcq_enable - Show if the device is enabled for tcqing
  * @dev:	device struct
@@ -2760,7 +2746,6 @@
 };
 
 static struct device_attribute *ipr_dev_attrs[] = {
-	&ipr_queue_depth_attr,
 	&ipr_tcqing_attr,
 	&ipr_adapter_handle_attr,
 	NULL,
@@ -3961,6 +3946,7 @@
 	.slave_alloc = ipr_slave_alloc,
 	.slave_configure = ipr_slave_configure,
 	.slave_destroy = ipr_slave_destroy,
+	.change_queue_depth = ipr_change_queue_depth,
 	.bios_param = ipr_biosparam,
 	.can_queue = IPR_MAX_COMMANDS,
 	.this_id = -1,
diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
--- a/drivers/scsi/lasi700.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/scsi/lasi700.c	2005-01-19 13:44:45 -08:00
@@ -54,12 +54,32 @@
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_spi.h>
 
-#include "lasi700.h"
 #include "53c700.h"
 
 MODULE_AUTHOR("James Bottomley");
 MODULE_DESCRIPTION("lasi700 SCSI Driver");
 MODULE_LICENSE("GPL");
+
+#define LASI_700_SVERSION 0x00071
+#define LASI_710_SVERSION 0x00082
+
+#define LASI700_ID_TABLE {			\
+	.hw_type	= HPHW_FIO,		\
+	.sversion	= LASI_700_SVERSION,	\
+	.hversion	= HVERSION_ANY_ID,	\
+	.hversion_rev	= HVERSION_REV_ANY_ID,	\
+}
+
+#define LASI710_ID_TABLE {			\
+	.hw_type	= HPHW_FIO,		\
+	.sversion	= LASI_710_SVERSION,	\
+	.hversion	= HVERSION_ANY_ID,	\
+	.hversion_rev	= HVERSION_REV_ANY_ID,	\
+}
+
+#define LASI700_CLOCK	25
+#define LASI710_CLOCK	40
+#define LASI_SCSI_CORE_OFFSET 0x100
 
 static struct parisc_device_id lasi700_ids[] = {
 	LASI700_ID_TABLE,
diff -Nru a/drivers/scsi/lasi700.h b/drivers/scsi/lasi700.h
--- a/drivers/scsi/lasi700.h	2005-01-19 13:44:48 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,49 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8 -*- */
-
-/* PARISC LASI driver for the 53c700 chip
- *
- * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
-**-----------------------------------------------------------------------------
-**  
-**  This program is free software; you can redistribute it and/or modify
-**  it under the terms of the GNU General Public License as published by
-**  the Free Software Foundation; either version 2 of the License, or
-**  (at your option) any later version.
-**
-**  This program is distributed in the hope that it will be useful,
-**  but WITHOUT ANY WARRANTY; without even the implied warranty of
-**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-**  GNU General Public License for more details.
-**
-**  You should have received a copy of the GNU General Public License
-**  along with this program; if not, write to the Free Software
-**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-**-----------------------------------------------------------------------------
- */
-
-#ifndef _LASI700_H
-#define _LASI700_H
-
-#define LASI_710_SVERSION	0x082
-#define LASI_700_SVERSION	0x071
-
-#define LASI700_ID_TABLE {			\
-	.hw_type	= HPHW_FIO,		\
-	.sversion	= LASI_700_SVERSION,	\
-	.hversion	= HVERSION_ANY_ID,	\
-	.hversion_rev	= HVERSION_REV_ANY_ID,	\
-}
-
-#define LASI710_ID_TABLE {			\
-	.hw_type	= HPHW_FIO,		\
-	.sversion	= LASI_710_SVERSION,	\
-	.hversion	= HVERSION_ANY_ID,	\
-	.hversion_rev	= HVERSION_REV_ANY_ID,	\
-}
-
-#define LASI700_CLOCK	25
-#define LASI710_CLOCK	40
-#define LASI_SCSI_CORE_OFFSET 0x100
-
-#endif
diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c
--- a/drivers/scsi/osst.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/osst.c	2005-01-19 13:44:46 -08:00
@@ -13,18 +13,18 @@
   order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
   Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
 
-  Copyright 1992 - 2002 Kai Makisara / Willem Riede
-	 email Kai.Makisara@metla.fi / osst@riede.org
+  Copyright 1992 - 2002 Kai Makisara / 2000 - 2004 Willem Riede
+	 email osst@riede.org
 
-  $Header: /cvsroot/osst/Driver/osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $
+  $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
 
   Microscopic alterations - Rik Ling, 2000/12/21
   Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara
   Some small formal changes - aeb, 950809
 */
 
-static const char * cvsid = "$Id: osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $";
-const char * osst_version = "0.99.1";
+static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $";
+const char * osst_version = "0.99.3";
 
 /* The "failure to reconnect" firmware bug */
 #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/
@@ -36,6 +36,7 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/proc_fs.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/string.h>
@@ -46,6 +47,7 @@
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 #include <linux/blkdev.h>
+#include <linux/moduleparam.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
@@ -82,13 +84,13 @@
 MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver");
 MODULE_LICENSE("GPL");
 
-module_param(max_dev, int, 0);
+module_param(max_dev, int, 0444);
 MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)");
 
-module_param(write_threshold_kbs, int, 0);
+module_param(write_threshold_kbs, int, 0644);
 MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)");
 
-module_param(max_sg_segs, int, 0);
+module_param(max_sg_segs, int, 0644);
 MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)");
 #else
 static struct osst_dev_parm {
@@ -119,10 +121,10 @@
 // #define OSST_INJECT_ERRORS 1 
 #endif
 
-#define MAX_RETRIES 2
-#define MAX_READ_RETRIES 0
-#define MAX_WRITE_RETRIES 0
-#define MAX_READY_RETRIES 0
+/* Do not retry! The drive firmware already retries when appropriate,
+   and when it tries to tell us something, we had better listen... */
+#define MAX_RETRIES 0
+
 #define NO_TAPE  NOT_READY
 
 #define OSST_WAIT_POSITION_COMPLETE   (HZ > 200 ? HZ / 200 : 1)
@@ -147,19 +149,19 @@
 static int osst_max_dev           = OSST_MAX_TAPES;
 static int osst_nr_dev;
 
-static OS_Scsi_Tape **os_scsi_tapes = NULL;
-static rwlock_t  os_scsi_tapes_lock = RW_LOCK_UNLOCKED;
+static struct osst_tape **os_scsi_tapes = NULL;
+static rwlock_t os_scsi_tapes_lock = RW_LOCK_UNLOCKED;
 
 static int modes_defined = FALSE;
 
-static OSST_buffer *new_tape_buffer(int, int, int);
-static int enlarge_buffer(OSST_buffer *, int);
-static void normalize_buffer(OSST_buffer *);
-static int append_to_buffer(const char __user *, OSST_buffer *, int);
-static int from_buffer(OSST_buffer *, char __user *, int);
-static int osst_zero_buffer_tail(OSST_buffer *);
-static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
-static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
+static struct osst_buffer *new_tape_buffer(int, int, int);
+static int enlarge_buffer(struct osst_buffer *, int);
+static void normalize_buffer(struct osst_buffer *);
+static int append_to_buffer(const char __user *, struct osst_buffer *, int);
+static int from_buffer(struct osst_buffer *, char __user *, int);
+static int osst_zero_buffer_tail(struct osst_buffer *);
+static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *);
+static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *);
 
 static int osst_probe(struct device *);
 static int osst_remove(struct device *);
@@ -173,17 +175,18 @@
 	}
 };
 
-static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg);
+static int osst_int_ioctl(struct osst_tape *STp, struct scsi_request ** aSRpnt,
+			    unsigned int cmd_in, unsigned long arg);
 
-static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int frame, int skip);
+static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int frame, int skip);
 
-static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
+static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt);
 
-static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt);
+static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt);
 
-static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending);
+static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending);
 
-static inline char *tape_name(OS_Scsi_Tape *tape)
+static inline char *tape_name(struct osst_tape *tape)
 {
 	return tape->drive->disk_name;
 }
@@ -191,7 +194,7 @@
 /* Routines that handle the interaction with mid-layer SCSI routines */
 
 /* Convert the result to success code */
-static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
+static int osst_chk_result(struct osst_tape * STp, struct scsi_request * SRpnt)
 {
 	char *name = tape_name(STp);
 	int result = SRpnt->sr_result;
@@ -222,7 +225,7 @@
 		if (driver_byte(result) & DRIVER_SENSE)
 			print_req_sense("osst ", SRpnt);
 	}
-//	else
+	else
 #endif
 	if (!(driver_byte(result) & DRIVER_SENSE) ||
 		((sense[0] & 0x70) == 0x70 &&
@@ -234,7 +237,7 @@
 		 SRpnt->sr_cmnd[0] != MODE_SENSE &&
 		 SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */
 		if (driver_byte(result) & DRIVER_SENSE) {
-			printk(KERN_WARNING "%s:W: Command with sense data: ", name);
+			printk(KERN_WARNING "%s:W: Command with sense data:\n", name);
 			print_req_sense("osst:", SRpnt);
 		}
 		else {
@@ -281,7 +284,7 @@
 /* Wakeup from interrupt */
 static void osst_sleep_done (Scsi_Cmnd * SCpnt)
 {
-	OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data, OS_Scsi_Tape, driver);
+	struct osst_tape * STp = container_of(SCpnt->request->rq_disk->private_data, struct osst_tape, driver);
 
 	if ((STp->buffer)->writing &&
 	    (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
@@ -307,7 +310,7 @@
 /* Do the scsi command. Waits until command performed if do_wait is true.
    Otherwise osst_write_behind_check() is used to check that the command
    has finished. */
-static	Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, 
+static	struct scsi_request * osst_do_scsi(struct scsi_request *SRpnt, struct osst_tape *STp, 
 	unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait)
 {
 	unsigned char *bp;
@@ -366,9 +369,9 @@
 
 
 /* Handle the write-behind checking (downs the semaphore) */
-static void osst_write_behind_check(OS_Scsi_Tape *STp)
+static void osst_write_behind_check(struct osst_tape *STp)
 {
-	OSST_buffer * STbuffer;
+	struct osst_buffer * STbuffer;
 
 	STbuffer = STp->buffer;
 
@@ -406,7 +409,7 @@
 /*
  * Initialize the OnStream AUX
  */
-static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_number,
+static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number,
 					 int logical_blk_num, int blk_sz, int blk_cnt)
 {
 	os_aux_t       *aux = STp->buffer->aux;
@@ -468,13 +471,13 @@
 /*
  * Verify that we have the correct tape frame
  */
-static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet)
+static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet)
 {
-	char           * name = tape_name(STp);
-	os_aux_t       * aux  = STp->buffer->aux;
-	os_partition_t * par  = &(aux->partition);
-	struct st_partstat    * STps = &(STp->ps[STp->partition]);
-	int		 blk_cnt, blk_sz, i;
+	char               * name = tape_name(STp);
+	os_aux_t           * aux  = STp->buffer->aux;
+	os_partition_t     * par  = &(aux->partition);
+	struct st_partstat * STps = &(STp->ps[STp->partition]);
+	int		     blk_cnt, blk_sz, i;
 
 	if (STp->raw) {
 		if (STp->buffer->syscall_result) {
@@ -602,14 +605,15 @@
 /*
  * Wait for the unit to become Ready
  */
-static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay)
+static int osst_wait_ready(struct osst_tape * STp, struct scsi_request ** aSRpnt,
+				 unsigned timeout, int initial_delay)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	unsigned long	startwait = jiffies;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	unsigned long		startwait = jiffies;
 #if DEBUG
-	int		dbg  = debugging;
-	char          * name = tape_name(STp);
+	int			dbg  = debugging;
+	char    	      * name = tape_name(STp);
 
 	printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name);
 #endif
@@ -620,7 +624,7 @@
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 
@@ -641,7 +645,7 @@
 	    memset(cmd, 0, MAX_COMMAND_SIZE);
 	    cmd[0] = TEST_UNIT_READY;
 
-	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 	}
 	*aSRpnt = SRpnt;
 #if DEBUG
@@ -666,14 +670,14 @@
 /*
  * Wait for a tape to be inserted in the unit
  */
-static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout)
+static int osst_wait_for_medium(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	unsigned long	startwait = jiffies;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	unsigned long		startwait = jiffies;
 #if DEBUG
-	int		dbg = debugging;
-	char          * name = tape_name(STp);
+	int			dbg = debugging;
+	char    	      * name = tape_name(STp);
 
 	printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name);
 #endif
@@ -681,7 +685,7 @@
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 
@@ -700,7 +704,7 @@
 	    memset(cmd, 0, MAX_COMMAND_SIZE);
 	    cmd[0] = TEST_UNIT_READY;
 
-	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 	}
 	*aSRpnt = SRpnt;
 #if DEBUG
@@ -722,7 +726,7 @@
 	return 1;
 }
 
-static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame)
+static int osst_position_tape_and_confirm(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame)
 {
 	int	retval;
 
@@ -736,15 +740,14 @@
 /*
  * Wait for write(s) to complete
  */
-static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_flush_drive_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-
-	int             result = 0;
-	int		delay  = OSST_WAIT_WRITE_COMPLETE;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	int			result = 0;
+	int			delay  = OSST_WAIT_WRITE_COMPLETE;
 #if DEBUG
-	char          * name = tape_name(STp);
+	char		      * name = tape_name(STp);
 
 	printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name);
 #endif
@@ -753,7 +756,7 @@
 	cmd[0] = WRITE_FILEMARKS;
 	cmd[1] = 1;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 	if (STp->buffer->syscall_result) {
@@ -771,12 +774,12 @@
 }
 
 #define OSST_POLL_PER_SEC 10
-static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, int minlast, int to)
+static int osst_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int curr, int minlast, int to)
 {
-	unsigned long	startwait     = jiffies;
-	char	      * name          = tape_name(STp);
+	unsigned long	startwait = jiffies;
+	char	      * name      = tape_name(STp);
 #if DEBUG
-	char	notyetprinted = 1;
+	char	   notyetprinted  = 1;
 #endif
 	if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING)
 		printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name);
@@ -784,7 +787,7 @@
 	while (time_before (jiffies, startwait + to*HZ))
 	{ 
 		int result;
-		result = osst_get_frame_position (STp, aSRpnt);
+		result = osst_get_frame_position(STp, aSRpnt);
 		if (result == -EIO)
 			if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0)
 				return 0;	/* successful recovery leaves drive ready for frame */
@@ -826,23 +829,79 @@
 	return -EBUSY;
 }
 
+static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int writing)
+{
+	struct scsi_request   * SRpnt;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	unsigned long   	startwait = jiffies;
+	int			retval    = 1;
+        char		      * name      = tape_name(STp);
+                                                                                                                                
+	if (writing) {
+		char	mybuf[24];
+		char  * olddata = STp->buffer->b_data;
+		int	oldsize = STp->buffer->buffer_size;
+
+		/* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */
+
+		memset(cmd, 0, MAX_COMMAND_SIZE);
+		cmd[0] = WRITE_FILEMARKS;
+		cmd[1] = 1;
+		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout,
+								MAX_RETRIES, TRUE);
+
+		while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
+
+			if (STp->buffer->syscall_result && (SRpnt->sr_sense_buffer[2] & 0x0f) != 2) {
+
+				/* some failure - not just not-ready */
+				retval = osst_write_error_recovery(STp, aSRpnt, 0);
+				break;
+			}
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout (HZ / OSST_POLL_PER_SEC);
+
+			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
+			memset(cmd, 0, MAX_COMMAND_SIZE);
+			cmd[0] = READ_POSITION;
+
+			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, SCSI_DATA_READ, STp->timeout,
+										MAX_RETRIES, TRUE);
+
+			retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
+			STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
+		}
+		if (retval)
+			printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name);
+	} else
+		/* TODO - figure out which error conditions can be handled */
+		if (STp->buffer->syscall_result)
+			printk(KERN_WARNING
+				"%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name,
+					(*aSRpnt)->sr_sense_buffer[ 2] & 0x0f,
+					(*aSRpnt)->sr_sense_buffer[12],
+					(*aSRpnt)->sr_sense_buffer[13]);
+
+	return retval;
+}
+
 /*
  * Read the next OnStream tape frame at the current location
  */
-static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout)
+static int osst_read_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int timeout)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	int		retval = 0;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	int			retval = 0;
 #if DEBUG
-	os_aux_t      * aux    = STp->buffer->aux;
-	char          * name = tape_name(STp);
+	os_aux_t	      * aux    = STp->buffer->aux;
+	char		      * name   = tape_name(STp);
 #endif
 
-	/* TODO: Error handling */
 	if (STp->poll)
-		retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout);
-	
+		if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout))
+			retval = osst_recover_wait_frame(STp, aSRpnt, 0);
+
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = READ_6;
 	cmd[1] = 1;
@@ -850,13 +909,13 @@
 
 #if DEBUG
 	if (debugging)
-	    printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
+		printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
 #endif
 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
-				      STp->timeout, MAX_READ_RETRIES, TRUE);
+				      STp->timeout, MAX_RETRIES, TRUE);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
-	    return (-EBUSY);
+		return (-EBUSY);
 
 	if ((STp->buffer)->syscall_result) {
 	    retval = 1;
@@ -900,15 +959,13 @@
 	return (retval);
 }
 
-static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_initiate_read(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
-	struct st_partstat   * STps   = &(STp->ps[STp->partition]);
-	Scsi_Request  * SRpnt  ;
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	int		retval = 0;
-#if DEBUG
-	char          * name = tape_name(STp);
-#endif
+	struct st_partstat    * STps   = &(STp->ps[STp->partition]);
+	struct scsi_request   * SRpnt  ;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	int			retval = 0;
+	char		      * name   = tape_name(STp);
 
 	if (STps->rw != ST_READING) {         /* Initialize read operation */
 		if (STps->rw == ST_WRITING || STp->dirty) {
@@ -930,23 +987,25 @@
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
 #endif
-		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE);
+		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 		*aSRpnt = SRpnt;
-		retval  = STp->buffer->syscall_result;
+		if ((retval = STp->buffer->syscall_result))
+			printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
 	}
 
 	return retval;
 }
 
-static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet)
+static int osst_get_logical_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt,
+						int frame_seq_number, int quiet)
 {
 	struct st_partstat * STps  = &(STp->ps[STp->partition]);
-	char        * name  = tape_name(STp);
-	int           cnt   = 0,
-		      bad   = 0,
-		      past  = 0,
-		      x,
-		      position;
+	char		   * name  = tape_name(STp);
+	int		     cnt   = 0,
+			     bad   = 0,
+			     past  = 0,
+			     x,
+			     position;
 
 	/*
 	 * If we want just any frame (-1) and there is a frame in the buffer, return it
@@ -971,6 +1030,7 @@
 						    name, STp->read_error_frame);
 #endif
 				STp->read_error_frame = 0;
+				STp->abort_count++;
 			}
 			return (-EIO);
 		}
@@ -988,10 +1048,11 @@
 				position = 0xbb8;
 			else if (position > STp->eod_frame_ppos || ++bad == 10) {
 				position = STp->read_error_frame - 1;
+				bad = 0;
 			}
 			else {
-				position += 39;
-				cnt += 20;
+				position += 29;
+				cnt      += 19;
 			}
 #if DEBUG
 			printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n",
@@ -1064,10 +1125,10 @@
 	return (STps->eof);
 }
 
-static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num)
+static int osst_seek_logical_blk(struct osst_tape * STp, struct scsi_request ** aSRpnt, int logical_blk_num)
 {
         struct st_partstat * STps = &(STp->ps[STp->partition]);
-	char        * name = tape_name(STp);
+	char		   * name = tape_name(STp);
 	int	retries    = 0;
 	int	frame_seq_estimate, ppos_estimate, move;
 	
@@ -1173,7 +1234,7 @@
 #define OSST_SECTOR_SHIFT 9
 #define OSST_SECTOR_MASK  0x03F
 
-static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_get_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	sector;
 #if DEBUG
@@ -1203,12 +1264,12 @@
 	return sector;
 }
 
-static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sector)
+static int osst_seek_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt, int sector)
 {
-        struct st_partstat   * STps   = &(STp->ps[STp->partition]);
-	int		frame  = sector >> OSST_FRAME_SHIFT,
-			offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
-			r;
+        struct st_partstat * STps   = &(STp->ps[STp->partition]);
+	int		     frame  = sector >> OSST_FRAME_SHIFT,
+			     offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, 
+			     r;
 #if DEBUG
 	char          * name = tape_name(STp);
 
@@ -1266,23 +1327,23 @@
  * Precondition for this function to work: all frames in the
  * drive's buffer must be of one type (DATA, MARK or EOD)!
  */
-static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
-					unsigned int frame, unsigned int skip, int pending)
+static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt,
+						unsigned int frame, unsigned int skip, int pending)
 {
-	Scsi_Request  * SRpnt = * aSRpnt;
-	unsigned char * buffer, * p;
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	int		flag, new_frame, i;
-	int		nframes          = STp->cur_frames;
-	int		blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
-	int		frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
+	struct scsi_request   * SRpnt = * aSRpnt;
+	unsigned char	      * buffer, * p;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	int			flag, new_frame, i;
+	int			nframes          = STp->cur_frames;
+	int			blks_per_frame   = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt);
+	int			frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num)
 						- (nframes + pending - 1);
-	int		logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
+	int			logical_blk_num  = ntohl(STp->buffer->aux->logical_blk_num) 
 						- (nframes + pending - 1) * blks_per_frame;
-	char	      * name             = tape_name(STp);
-	unsigned long	startwait        = jiffies;
+	char		      * name             = tape_name(STp);
+	unsigned long		startwait        = jiffies;
 #if DEBUG
-	int		dbg              = debugging;
+	int			dbg              = debugging;
 #endif
 
 	if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL)
@@ -1308,7 +1369,7 @@
 		cmd[8] = 32768 & 0xff;
 
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ,
-					    STp->timeout, MAX_READ_RETRIES, TRUE);
+					    STp->timeout, MAX_RETRIES, TRUE);
 	
 		if ((STp->buffer)->syscall_result || !SRpnt) {
 			printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
@@ -1357,8 +1418,8 @@
 				vfree((void *)buffer);
 				return (-EIO);
 			}
-			flag = 0;
 			if ( i >= nframes + pending ) break;
+			flag = 0;
 		}
 		osst_copy_to_buffer(STp->buffer, p);
 		/*
@@ -1380,7 +1441,7 @@
 				p[0], p[1], p[2], p[3]);
 #endif
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
-					    STp->timeout, MAX_WRITE_RETRIES, TRUE);
+					    STp->timeout, MAX_RETRIES, TRUE);
 
 		if (STp->buffer->syscall_result)
 			flag = 1;
@@ -1396,7 +1457,7 @@
 				cmd[0] = WRITE_FILEMARKS;
 				cmd[1] = 1;
 				SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
-							    STp->timeout, MAX_WRITE_RETRIES, TRUE);
+							    STp->timeout, MAX_RETRIES, TRUE);
 #if DEBUG
 				if (debugging) {
 					printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
@@ -1411,7 +1472,7 @@
 					cmd[0] = TEST_UNIT_READY;
 
 					SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout,
-									 MAX_READY_RETRIES, TRUE);
+												MAX_RETRIES, TRUE);
 
 					if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 &&
 					    (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) {
@@ -1448,29 +1509,34 @@
 #endif
 			osst_get_frame_position(STp, aSRpnt);
 #if DEBUG
-			printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n",
-					  name, STp->first_frame_position, STp->last_frame_position);
+			printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n",
+					  name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
 #endif
 		}
-	}    
+	}
+	if (flag) {
+		/* error recovery did not successfully complete */
+		printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name,
+				STp->write_type == OS_WRITE_HEADER?"header":"body");
+	}
 	if (!pending)
 		osst_copy_to_buffer(STp->buffer, p);	/* so buffer content == at entry in all cases */
 	vfree((void *)buffer);
 	return 0;
 }
 
-static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
+static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request ** aSRpnt,
 					unsigned int frame, unsigned int skip, int pending)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	char	      * name      = tape_name(STp);
-	int		expected  = 0;
-	int		attempts  = 1000 / skip;
-	int		flag      = 1;
-	unsigned long	startwait = jiffies;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	char		      * name      = tape_name(STp);
+	int			expected  = 0;
+	int			attempts  = 1000 / skip;
+	int			flag      = 1;
+	unsigned long		startwait = jiffies;
 #if DEBUG
-	int		dbg       = debugging;
+	int			dbg       = debugging;
 #endif
 
 	while (attempts && time_before(jiffies, startwait + 60*HZ)) {
@@ -1512,7 +1578,7 @@
 					  name, STp->frame_seq_number-1, STp->first_frame_position);
 #endif
 			SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE,
-						      STp->timeout, MAX_WRITE_RETRIES, TRUE);
+						      STp->timeout, MAX_RETRIES, TRUE);
 			*aSRpnt = SRpnt;
 
 			if (STp->buffer->syscall_result) {		/* additional write error */
@@ -1550,6 +1616,7 @@
 			debugging = 0;
 		}
 #endif
+		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(HZ / 10);
 	}
 	printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
@@ -1563,14 +1630,14 @@
  * Error recovery algorithm for the OnStream tape.
  */
 
-static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending)
+static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending)
 {
-	Scsi_Request * SRpnt  = * aSRpnt;
+	struct scsi_request * SRpnt  = * aSRpnt;
 	struct st_partstat  * STps   = & STp->ps[STp->partition];
-	char         * name   = tape_name(STp);
-	int            retval = 0;
-	int            rw_state;
-	unsigned int  frame, skip;
+	char		    * name   = tape_name(STp);
+	int		      retval = 0;
+	int		      rw_state;
+	unsigned int	      frame, skip;
 
 	rw_state = STps->rw;
 
@@ -1635,12 +1702,14 @@
 	if (retval == 0) {
 		STp->recover_count++;
 		STp->recover_erreg++;
-	}
+	} else
+		STp->abort_count++;
+
 	STps->rw = rw_state;
 	return retval;
 }
 
-static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
+static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct scsi_request ** aSRpnt,
 								 int mt_op, int mt_count)
 {
 	char  * name = tape_name(STp);
@@ -1739,7 +1808,7 @@
  *
  * Just scans for the filemark sequentially.
  */
-static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
+static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct scsi_request ** aSRpnt,
 								     int mt_op, int mt_count)
 {
 	int	cnt = 0;
@@ -1793,7 +1862,7 @@
 /*
  * Fast linux specific version of OnStream FSF
  */
-static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt,
+static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct scsi_request ** aSRpnt,
 								     int mt_op, int mt_count)
 {
 	char  * name = tape_name(STp);
@@ -1944,11 +2013,11 @@
  * to test the error recovery mechanism.
  */
 #if DEBUG
-static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int retries)
+static void osst_set_retries(struct osst_tape * STp, struct scsi_request ** aSRpnt, int retries)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt  = * aSRpnt;
-	char          * name   = tape_name(STp);
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt  = * aSRpnt;
+	char		      * name   = tape_name(STp);
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SELECT;
@@ -1976,7 +2045,7 @@
 #endif
 
 
-static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_write_filemark(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	result;
 	int	this_mark_ppos = STp->first_frame_position;
@@ -2004,7 +2073,7 @@
 	return result;
 }
 
-static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_write_eod(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	result;
 #if DEBUG
@@ -2027,7 +2096,7 @@
 	return result;
 }
 
-static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
+static int osst_write_filler(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
 {
 	char * name = tape_name(STp);
 
@@ -2052,7 +2121,7 @@
 	return osst_flush_drive_buffer(STp, aSRpnt);
 }
 
-static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count)
+static int __osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count)
 {
 	char * name = tape_name(STp);
 	int     result;
@@ -2079,7 +2148,7 @@
 	return result;
 }
 
-static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int locate_eod)
+static int osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int locate_eod)
 {
 	os_header_t * header;
 	int	      result;
@@ -2153,7 +2222,7 @@
 	return result;
 }
 
-static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_reset_header(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	if (STp->header_cache != NULL)
 		memset(STp->header_cache, 0, sizeof(os_header_t));
@@ -2166,7 +2235,7 @@
 	return osst_write_header(STp, aSRpnt, 1);
 }
 
-static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ppos)
+static int __osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt, int ppos)
 {
 	char        * name = tape_name(STp);
 	os_header_t * header;
@@ -2343,7 +2412,7 @@
 	return 1;
 }
 
-static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	position, ppos;
 	int	first, last;
@@ -2398,7 +2467,7 @@
 	return 1;
 }
 
-static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt)
+static int osst_verify_position(struct osst_tape * STp, struct scsi_request ** aSRpnt)
 {
 	int	frame_position  = STp->first_frame_position;
 	int	frame_seq_numbr = STp->frame_seq_number;
@@ -2474,11 +2543,11 @@
 /*
  * Configure the OnStream SCII tape drive for default operation
  */
-static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
+static int osst_configure_onstream(struct osst_tape *STp, struct scsi_request ** aSRpnt)
 {
 	unsigned char                  cmd[MAX_COMMAND_SIZE];
 	char                         * name = tape_name(STp);
-	Scsi_Request                 * SRpnt = * aSRpnt;
+	struct scsi_request                 * SRpnt = * aSRpnt;
 	osst_mode_parameter_header_t * header;
 	osst_block_size_page_t       * bs;
 	osst_capabilities_page_t     * cp;
@@ -2645,7 +2714,7 @@
 
 /* Step over EOF if it has been inadvertently crossed (ioctl not used because
    it messes up the block number). */
-static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward)
+static int cross_eof(struct osst_tape *STp, struct scsi_request ** aSRpnt, int forward)
 {
 	int	result;
 	char  * name = tape_name(STp);
@@ -2674,18 +2743,18 @@
 
 /* Get the tape position. */
 
-static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
+static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt)
 {
-	unsigned char	scmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	int		result = 0;
+	unsigned char		scmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	int			result = 0;
+	char    	      * name   = tape_name(STp);
 
 	/* KG: We want to be able to use it for checking Write Buffer availability
 	 *  and thus don't want to risk to overwrite anything. Exchange buffers ... */
 	char		mybuf[24];
 	char	      * olddata = STp->buffer->b_data;
 	int		oldsize = STp->buffer->buffer_size;
-	char          * name    = tape_name(STp);
 
 	if (STp->ready != ST_READY) return (-EIO);
 
@@ -2702,13 +2771,12 @@
 	*aSRpnt = SRpnt;
 
 	if (STp->buffer->syscall_result)
-		result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL;
+		result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL;	/* 3: Write Error */
 
 	if (result == -EINVAL)
 		printk(KERN_ERR "%s:E: Can't read tape position.\n", name);
 	else {
-
-		if (result == -EIO) {	/* re-read position */
+		if (result == -EIO) {	/* re-read position - this needs to preserve media errors */
 			unsigned char mysense[16];
 			memcpy (mysense, SRpnt->sr_sense_buffer, 16);
 			memset (scmd, 0, MAX_COMMAND_SIZE);
@@ -2716,8 +2784,15 @@
 			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 			SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ,
 						    STp->timeout, MAX_RETRIES, TRUE);
+#if DEBUG
+			printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
+					name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
+					SRpnt->sr_sense_buffer[2],SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]);
+#endif
 			if (!STp->buffer->syscall_result)
 				memcpy (SRpnt->sr_sense_buffer, mysense, 16);
+			else
+				printk(KERN_WARNING "%s:W: Double error in get position\n", name);
 		}
 		STp->first_frame_position = ((STp->buffer)->b_data[4] << 24)
 					  + ((STp->buffer)->b_data[5] << 16)
@@ -2739,7 +2814,7 @@
 #endif
 		if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) {
 #if DEBUG
-			printk(KERN_WARNING "%s:D: Correcting read position %d, %d, %d\n", name,
+			printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name,
 					STp->first_frame_position, STp->last_frame_position, STp->cur_frames);
 #endif
 			STp->first_frame_position = STp->last_frame_position;
@@ -2752,14 +2827,14 @@
 
 
 /* Set the tape block */
-static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int ppos, int skip)
+static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int ppos, int skip)
 {
-	unsigned char	scmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	struct st_partstat   * STps;
-	int		result = 0;
-	int		pp     = (ppos == 3000 && !skip)? 0 : ppos;
-	char          * name   = tape_name(STp);
+	unsigned char		scmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	struct st_partstat    * STps;
+	int			result = 0;
+	int			pp     = (ppos == 3000 && !skip)? 0 : ppos;
+	char		      * name   = tape_name(STp);
 
 	if (STp->ready != ST_READY) return (-EIO);
 
@@ -2810,7 +2885,7 @@
 	return result;
 }
 
-static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT)
+static int osst_write_trailer(struct osst_tape *STp, struct scsi_request ** aSRpnt, int leave_at_EOT)
 {
 	struct st_partstat * STps = &(STp->ps[STp->partition]);
 	int result = 0;
@@ -2837,26 +2912,26 @@
 /* osst versions of st functions - augmented and stripped to suit OnStream only */
 
 /* Flush the write buffer (never need to write if variable blocksize). */
-static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt)
+static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt)
 {
-	int            offset, transfer, blks = 0;
-	int            result = 0;
-	unsigned char  cmd[MAX_COMMAND_SIZE];
-	Scsi_Request * SRpnt = *aSRpnt;
-	struct st_partstat  * STps;
-	char         * name = tape_name(STp);
+	int			offset, transfer, blks = 0;
+	int			result = 0;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt = *aSRpnt;
+	struct st_partstat    * STps;
+	char		      * name = tape_name(STp);
 
 	if ((STp->buffer)->writing) {
 		if (SRpnt == (STp->buffer)->last_SRpnt)
 #if DEBUG
 			{ printk(OSST_DEB_MSG
-	 "%s:D: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", name);
+	 "%s:D: aSRpnt points to scsi_request that write_behind_check will release -- cleared\n", name);
 #endif
 			*aSRpnt = SRpnt = NULL;
 #if DEBUG
 			} else if (SRpnt)
 				printk(OSST_DEB_MSG
-	 "%s:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", name);
+	 "%s:D: aSRpnt does not point to scsi_request that write_behind_check will release -- strange\n", name);
 #endif	
 		osst_write_behind_check(STp);
 		if ((STp->buffer)->syscall_result) {
@@ -2884,9 +2959,9 @@
 		if (offset < OS_DATA_SIZE)
 			osst_zero_buffer_tail(STp->buffer);
 
-		/* TODO: Error handling! */
 		if (STp->poll)
-			result = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120);
+			if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120))
+				result = osst_recover_wait_frame(STp, aSRpnt, 1);
 
 		memset(cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = WRITE_6;
@@ -2925,7 +3000,7 @@
 #endif
 
 		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, SCSI_DATA_WRITE,
-					  STp->timeout, MAX_WRITE_RETRIES, TRUE);
+					      STp->timeout, MAX_RETRIES, TRUE);
 		*aSRpnt = SRpnt;
 		if (!SRpnt)
 			return (-EBUSY);
@@ -2967,12 +3042,12 @@
 
 /* Flush the tape buffer. The tape will be positioned correctly unless
    seek_next is true. */
-static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int seek_next)
+static int osst_flush_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt, int seek_next)
 {
 	struct st_partstat * STps;
-	int           backspace = 0, result = 0;
+	int    backspace = 0, result = 0;
 #if DEBUG
-	char        * name = tape_name(STp);
+	char * name = tape_name(STp);
 #endif
 
 	/*
@@ -3029,13 +3104,13 @@
 	return result;
 }
 
-static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int synchronous)
+static int osst_write_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int synchronous)
 {
-	unsigned char	cmd[MAX_COMMAND_SIZE];
-	Scsi_Request  * SRpnt;
-	int		blks;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt;
+	int			blks;
 #if DEBUG
-	char          * name = tape_name(STp);
+	char		      * name = tape_name(STp);
 #endif
 
 	if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */
@@ -3055,8 +3130,9 @@
 	}
 
 	if (STp->poll)
-		osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 60);
-	/* TODO: Check for an error ! */
+		if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120))
+			if (osst_recover_wait_frame(STp, aSRpnt, 1))
+				return (-EIO);
 
 //	osst_build_stats(STp, &SRpnt);
 
@@ -3081,7 +3157,7 @@
 		STp->write_pending = 1;
 #endif
 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, STp->timeout,
-							MAX_WRITE_RETRIES, synchronous);
+									MAX_RETRIES, synchronous);
 	if (!SRpnt)
 		return (-EBUSY);
 	*aSRpnt = SRpnt;
@@ -3111,8 +3187,8 @@
 	return 0;
 }
 
-/* Lock or unlock the drive door. Don't use when Scsi_Request allocated. */
-static int do_door_lock(OS_Scsi_Tape * STp, int do_lock)
+/* Lock or unlock the drive door. Don't use when struct scsi_request allocated. */
+static int do_door_lock(struct osst_tape * STp, int do_lock)
 {
 	int retval, cmd;
 
@@ -3131,7 +3207,7 @@
 }
 
 /* Set the internal state after reset */
-static void reset_state(OS_Scsi_Tape *STp)
+static void reset_state(struct osst_tape *STp)
 {
 	int i;
 	struct st_partstat *STps;
@@ -3154,16 +3230,16 @@
 /* Write command */
 static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos)
 {
-	ssize_t        total, retval = 0;
-	ssize_t        i, do_count, blks, transfer;
-	int            write_threshold;
-	int            doing_write = 0;
+	ssize_t		      total, retval = 0;
+	ssize_t		      i, do_count, blks, transfer;
+	int		      write_threshold;
+	int		      doing_write = 0;
 	const char   __user * b_point;
-	Scsi_Request * SRpnt = NULL;
+	struct scsi_request * SRpnt = NULL;
 	struct st_modedef   * STm;
 	struct st_partstat  * STps;
-	OS_Scsi_Tape * STp  = filp->private_data;
-	char         * name = tape_name(STp);
+	struct osst_tape    * STp  = filp->private_data;
+	char		    * name = tape_name(STp);
 
 
 	if (down_interruptible(&STp->lock))
@@ -3477,14 +3553,14 @@
 /* Read command */
 static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos)
 {
-	ssize_t        total, retval = 0;
-	ssize_t        i, transfer;
-	int            special;
-	struct st_modedef      * STm;
+	ssize_t		      total, retval = 0;
+	ssize_t		      i, transfer;
+	int		      special;
+	struct st_modedef   * STm;
 	struct st_partstat  * STps;
-	Scsi_Request * SRpnt = NULL;
-	OS_Scsi_Tape * STp   = filp->private_data;
-	char         * name  = tape_name(STp);
+	struct scsi_request * SRpnt = NULL;
+	struct osst_tape    * STp   = filp->private_data;
+	char		    * name  = tape_name(STp);
 
 
 	if (down_interruptible(&STp->lock))
@@ -3660,8 +3736,7 @@
 
 
 /* Set the driver options */
-static void osst_log_options(OS_Scsi_Tape *STp, struct st_modedef *STm,
-			     char *name)
+static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name)
 {
   printk(KERN_INFO
 "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n",
@@ -3684,12 +3759,12 @@
 }
 
 
-static int osst_set_options(OS_Scsi_Tape *STp, long options)
+static int osst_set_options(struct osst_tape *STp, long options)
 {
-	int       value;
-	long      code;
+	int		    value;
+	long		    code;
 	struct st_modedef * STm;
-	char    * name = tape_name(STp);
+	char		  * name = tape_name(STp);
 
 	STm = &(STp->modes[STp->current_mode]);
 	if (!STm->defined) {
@@ -3840,18 +3915,19 @@
 
 
 /* Internal ioctl function */
-static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned int cmd_in, unsigned long arg)
+static int osst_int_ioctl(struct osst_tape * STp, struct scsi_request ** aSRpnt,
+			     unsigned int cmd_in, unsigned long arg)
 {
-	int            timeout;
-	long           ltmp;
-	int            i, ioctl_result;
-	int            chg_eof = TRUE;
-	unsigned char  cmd[MAX_COMMAND_SIZE];
-	Scsi_Request * SRpnt = * aSRpnt;
-	struct st_partstat  * STps;
-	int            fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
-	int            datalen = 0, direction = SCSI_DATA_NONE;
-	char         * name = tape_name(STp);
+	int			timeout;
+	long			ltmp;
+	int			i, ioctl_result;
+	int			chg_eof = TRUE;
+	unsigned char		cmd[MAX_COMMAND_SIZE];
+	struct scsi_request   * SRpnt = * aSRpnt;
+	struct st_partstat    * STps;
+	int			fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num;
+	int			datalen = 0, direction = SCSI_DATA_NONE;
+	char		      * name = tape_name(STp);
 
 	if (STp->ready != ST_READY && cmd_in != MTLOAD) {
 		if (STp->ready == ST_NO_TAPE)
@@ -4227,16 +4303,16 @@
 /* Open the device */
 static int os_scsi_tape_open(struct inode * inode, struct file * filp)
 {
-	unsigned short flags;
-	int            i, b_size, new_session = FALSE, retval = 0;
-	unsigned char  cmd[MAX_COMMAND_SIZE];
-	Scsi_Request * SRpnt = NULL;
-	OS_Scsi_Tape * STp;
-	struct st_modedef      * STm;
+	unsigned short	      flags;
+	int		      i, b_size, new_session = FALSE, retval = 0;
+	unsigned char	      cmd[MAX_COMMAND_SIZE];
+	struct scsi_request * SRpnt = NULL;
+	struct osst_tape    * STp;
+	struct st_modedef   * STm;
 	struct st_partstat  * STps;
-	char         * name;
-	int            dev  = TAPE_NR(inode);
-	int            mode = TAPE_MODE(inode);
+	char		    * name;
+	int		      dev  = TAPE_NR(inode);
+	int		      mode = TAPE_MODE(inode);
 
 	nonseekable_open(inode, filp);
 	write_lock(&os_scsi_tapes_lock);
@@ -4327,9 +4403,9 @@
 	memset (cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE);
+	SRpnt = osst_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_RETRIES, TRUE);
 	if (!SRpnt) {
-		retval = (STp->buffer)->syscall_result;
+		retval = (STp->buffer)->syscall_result;		/* FIXME - valid? */
 		goto err_out;
 	}
 	if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70      &&
@@ -4348,7 +4424,7 @@
 			cmd[1] = 1;
 			cmd[4] = 1;
 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
-					     STp->timeout, MAX_READY_RETRIES, TRUE);
+					     STp->timeout, MAX_RETRIES, TRUE);
 		}
 		osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0);
 	}
@@ -4365,7 +4441,7 @@
 			cmd[0] = TEST_UNIT_READY;
 
 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
-					     STp->timeout, MAX_READY_RETRIES, TRUE);
+					     STp->timeout, MAX_RETRIES, TRUE);
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
 			    (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION)
 				break;
@@ -4386,6 +4462,7 @@
 		}
 		new_session = TRUE;
 		STp->recover_count = 0;
+		STp->abort_count = 0;
 	}
 	/*
 	 * if we have valid headers from before, and the drive/tape seem untouched,
@@ -4473,7 +4550,7 @@
 			cmd[0] = TEST_UNIT_READY;
 
 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE,
-					     STp->timeout, MAX_READY_RETRIES, TRUE);
+						    STp->timeout, MAX_RETRIES, TRUE);
 			if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 ||
 			    (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY)
 			break;
@@ -4588,12 +4665,12 @@
 /* Flush the tape buffer before close */
 static int os_scsi_tape_flush(struct file * filp)
 {
-	int            result = 0, result2;
-	OS_Scsi_Tape * STp  = filp->private_data;
-	struct st_modedef      * STm  = &(STp->modes[STp->current_mode]);
-	struct st_partstat  * STps = &(STp->ps[STp->partition]);
-	Scsi_Request * SRpnt = NULL;
-	char         * name = tape_name(STp);
+	int		      result = 0, result2;
+	struct osst_tape    * STp    = filp->private_data;
+	struct st_modedef   * STm    = &(STp->modes[STp->current_mode]);
+	struct st_partstat  * STps   = &(STp->ps[STp->partition]);
+	struct scsi_request * SRpnt  = NULL;
+	char		    * name   = tape_name(STp);
 
 	if (file_count(filp) > 1)
 		return 0;
@@ -4657,14 +4734,19 @@
 	}
 	if (SRpnt) scsi_release_request(SRpnt);
 
-	if (STp->recover_count) {
-		printk(KERN_INFO "%s:I: %d recovered errors in", name, STp->recover_count);
+	if (STp->abort_count || STp->recover_count) {
+		printk(KERN_INFO "%s:I:", name);
+		if (STp->abort_count)
+			printk(" %d unrecovered errors", STp->abort_count);
+		if (STp->recover_count)
+			printk(" %d recovered errors", STp->recover_count);
 		if (STp->write_count)
-			printk(" %d frames written", STp->write_count);
+			printk(" in %d frames written", STp->write_count);
 		if (STp->read_count)
-			printk(" %d frames read", STp->read_count);
+			printk(" in %d frames read", STp->read_count);
 		printk("\n");
 		STp->recover_count = 0;
+		STp->abort_count   = 0;
 	}
 	STp->write_count = 0;
 	STp->read_count  = 0;
@@ -4676,9 +4758,9 @@
 /* Close the device and release it */
 static int os_scsi_tape_close(struct inode * inode, struct file * filp)
 {
-	int result = 0;
-	OS_Scsi_Tape * STp = filp->private_data;
-	Scsi_Request * SRpnt = NULL;
+	int		      result = 0;
+	struct osst_tape    * STp    = filp->private_data;
+	struct scsi_request * SRpnt  = NULL;
 
 	if (SRpnt) scsi_release_request(SRpnt);
 
@@ -4703,14 +4785,14 @@
 static int osst_ioctl(struct inode * inode,struct file * file,
 	 unsigned int cmd_in, unsigned long arg)
 {
-	int            i, cmd_nr, cmd_type, retval = 0;
-	unsigned int   blk;
-	struct st_modedef      * STm;
+	int		      i, cmd_nr, cmd_type, retval = 0;
+	unsigned int	      blk;
+	struct st_modedef   * STm;
 	struct st_partstat  * STps;
-	Scsi_Request * SRpnt = NULL;
-	OS_Scsi_Tape * STp   = file->private_data;
-	char         * name  = tape_name(STp);
-	void __user *p = (void __user *)arg;
+	struct scsi_request * SRpnt = NULL;
+	struct osst_tape    * STp   = file->private_data;
+	char		    * name  = tape_name(STp);
+	void	    __user  * p     = (void __user *)arg;
 
 	if (down_interruptible(&STp->lock))
 		return -ERESTARTSYS;
@@ -5039,18 +5121,18 @@
 /* Memory handling routines */
 
 /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */
-static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
+static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg )
 {
 	int i, priority;
-	OSST_buffer *tb;
+	struct osst_buffer *tb;
 
 	if (from_initialization)
 		priority = GFP_ATOMIC;
 	else
 		priority = GFP_KERNEL;
 
-	i = sizeof(OSST_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
-	tb = (OSST_buffer *)kmalloc(i, priority);
+	i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
+	tb = (struct osst_buffer *)kmalloc(i, priority);
 	if (!tb) {
 		printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
 		return NULL;
@@ -5071,7 +5153,7 @@
 }
 
 /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */
-static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma)
+static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 {
 	int segs, nbr, max_segs, b_size, priority, order, got;
 
@@ -5087,12 +5169,10 @@
 	if (nbr <= 2)
 		return FALSE;
 
-	priority = GFP_KERNEL;
+	priority = GFP_KERNEL /* | __GFP_NOWARN */;
 	if (need_dma)
 		priority |= GFP_DMA;
 
-	priority |= __GFP_NOWARN;
-
 	/* Try to allocate the first segment up to OS_DATA_SIZE and the others
 	   big enough to reach the goal (code assumes no segments in place) */
 	for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
@@ -5150,7 +5230,7 @@
 
 
 /* Release the segments */
-static void normalize_buffer(OSST_buffer *STbuffer)
+static void normalize_buffer(struct osst_buffer *STbuffer)
 {
   int i, order, b_size;
 
@@ -5174,7 +5254,7 @@
 
 /* Move data from the user buffer to the tape buffer. Returns zero (success) or
    negative error code. */
-static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_count)
+static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count)
 {
 	int i, cnt, res, offset;
 
@@ -5207,7 +5287,7 @@
 
 /* Move data from the tape buffer to the user buffer. Returns zero (success) or
    negative error code. */
-static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count)
+static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count)
 {
 	int i, cnt, res, offset;
 
@@ -5239,7 +5319,7 @@
 
 /* Sets the tail of the buffer after fill point to zero.
    Returns zero (success) or negative error code.        */
-static int osst_zero_buffer_tail(OSST_buffer *st_bp)
+static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
 {
 	int	i, offset, do_count, cnt;
 
@@ -5267,7 +5347,7 @@
 
 /* Copy a osst 32K chunk of memory into the buffer.
    Returns zero (success) or negative error code.  */
-static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr)
+static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 {
 	int	i, cnt, do_count = OS_DATA_SIZE;
 
@@ -5288,7 +5368,7 @@
 
 /* Copy a osst 32K chunk of memory from the buffer.
    Returns zero (success) or negative error code.  */
-static int osst_copy_from_buffer(OSST_buffer *st_bp, unsigned char *ptr)
+static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
 {
 	int	i, cnt, do_count = OS_DATA_SIZE;
 
@@ -5406,18 +5486,163 @@
 }
 
 /*
+ * sysfs support for osst driver parameter information
+ */
+
+static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", osst_version);
+}
+
+static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
+
+static void osst_create_driverfs_files(struct device_driver *driverfs)
+{
+	driver_create_file(driverfs, &driver_attr_version);
+}
+
+static void osst_remove_driverfs_files(struct device_driver *driverfs)
+{
+	driver_remove_file(driverfs, &driver_attr_version);
+}
+
+/*
+ * sysfs support for accessing ADR header information
+ */
+
+static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL);
+
+static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL);
+
+static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL);
+
+static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL);
+
+static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL);
+
+static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf)
+{
+	struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev);
+	ssize_t l = 0;
+
+	if (STp && STp->header_ok && STp->linux_media)
+		l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt);
+	return l;
+}
+
+CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
+
+static struct class_simple * osst_sysfs_class;
+
+static int osst_sysfs_valid = 0;
+
+static void osst_sysfs_init(void)
+{
+	osst_sysfs_class = class_simple_create(THIS_MODULE, "onstream_tape");
+	if ( IS_ERR(osst_sysfs_class) )
+		printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
+	else
+		osst_sysfs_valid = TRUE;
+}
+
+static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
+{
+	struct class_device *osst_class_member;
+
+	if (!osst_sysfs_valid) return;
+
+	osst_class_member = class_simple_device_add(osst_sysfs_class, dev, device, "%s", name);
+	if (IS_ERR(osst_class_member)) {
+		printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
+		return;
+	}
+	class_set_devdata(osst_class_member, STp);
+	class_device_create_file(osst_class_member, &class_device_attr_ADR_rev);
+	class_device_create_file(osst_class_member, &class_device_attr_media_version);
+	class_device_create_file(osst_class_member, &class_device_attr_capacity);
+	class_device_create_file(osst_class_member, &class_device_attr_BOT_frame);
+	class_device_create_file(osst_class_member, &class_device_attr_EOD_frame);
+	class_device_create_file(osst_class_member, &class_device_attr_file_count);
+}
+
+static void osst_sysfs_destroy(dev_t dev)
+{
+	if (!osst_sysfs_valid) return; 
+
+	class_simple_device_remove(dev);
+}
+
+static void osst_sysfs_cleanup(void)
+{
+	if (osst_sysfs_valid) {
+		class_simple_destroy(osst_sysfs_class);
+		osst_sysfs_valid = 0;
+	}
+}
+
+/*
  * osst startup / cleanup code
  */
 
 static int osst_probe(struct device *dev)
 {
-	Scsi_Device    * SDp = to_scsi_device(dev);
-	OS_Scsi_Tape   * tpnt;
-	struct st_modedef        * STm;
-	struct st_partstat    * STps;
-	OSST_buffer    * buffer;
-	struct gendisk * drive;
-	int              i, mode, dev_num;
+	Scsi_Device	   * SDp = to_scsi_device(dev);
+	struct osst_tape   * tpnt;
+	struct st_modedef  * STm;
+	struct st_partstat * STps;
+	struct osst_buffer * buffer;
+	struct gendisk	   * drive;
+	int		     i, mode, dev_num;
 
 	if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
 		return -ENODEV;
@@ -5432,7 +5657,7 @@
 	write_lock(&os_scsi_tapes_lock);
 	if (os_scsi_tapes == NULL) {
 		os_scsi_tapes =
-			(OS_Scsi_Tape **)kmalloc(osst_max_dev * sizeof(OS_Scsi_Tape *),
+			(struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *),
 				   GFP_ATOMIC);
 		if (os_scsi_tapes == NULL) {
 			write_unlock(&os_scsi_tapes_lock);
@@ -5453,14 +5678,14 @@
 	if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)");
 	dev_num = i;
 
-	/* allocate a OS_Scsi_Tape for this device */
-	tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC);
+	/* allocate a struct osst_tape for this device */
+	tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC);
 	if (tpnt == NULL) {
 		write_unlock(&os_scsi_tapes_lock);
 		printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n");
 		goto out_put_disk;
 	}
-	memset(tpnt, 0, sizeof(OS_Scsi_Tape));
+	memset(tpnt, 0, sizeof(struct osst_tape));
 
 	/* allocate a buffer for this device */
 	i = SDp->host->sg_tablesize;
@@ -5545,7 +5770,14 @@
 	init_MUTEX(&tpnt->lock);
 	osst_nr_dev++;
 	write_unlock(&os_scsi_tapes_lock);
-
+	{
+		char name[8];
+		/*  Rewind entry  */
+		osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
+		/*  No-rewind entry  */
+		snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
+		osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
+	}
 	for (mode = 0; mode < ST_NBR_MODES; ++mode) {
 		/*  Rewind entry  */
 		devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)),
@@ -5572,8 +5804,8 @@
 
 static int osst_remove(struct device *dev)
 {
-	Scsi_Device  * SDp = to_scsi_device(dev);
-	OS_Scsi_Tape * tpnt;
+	Scsi_Device	 * SDp = to_scsi_device(dev);
+	struct osst_tape * tpnt;
 	int i, mode;
 
 	if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
@@ -5582,6 +5814,8 @@
 	write_lock(&os_scsi_tapes_lock);
 	for(i=0; i < osst_max_dev; i++) {
 		if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) {
+			osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
+			osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
 			tpnt->device = NULL;
 			for (mode = 0; mode < ST_NBR_MODES; ++mode) {
 				devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
@@ -5610,11 +5844,14 @@
 	printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
 
 	validate_options();
-	
+	osst_sysfs_init();
+
 	if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
 		printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
+		osst_sysfs_cleanup();
 		return 1;
 	}
+	osst_create_driverfs_files(&osst_template.gendrv);
 
 	return 0;
 }
@@ -5622,10 +5859,12 @@
 static void __exit exit_osst (void)
 {
 	int i;
-	OS_Scsi_Tape * STp;
+	struct osst_tape * STp;
 
+	osst_remove_driverfs_files(&osst_template.gendrv);
 	scsi_unregister_driver(&osst_template.gendrv);
 	unregister_chrdev(OSST_MAJOR, "osst");
+	osst_sysfs_cleanup();
 
 	if (os_scsi_tapes) {
 		for (i=0; i < osst_max_dev; ++i) {
diff -Nru a/drivers/scsi/osst.h b/drivers/scsi/osst.h
--- a/drivers/scsi/osst.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/osst.h	2005-01-19 13:44:47 -08:00
@@ -1,5 +1,5 @@
 /*
- *	$Header: /cvsroot/osst/Driver/osst.h,v 1.14 2003/12/14 14:34:38 wriede Exp $
+ *	$Header: /cvsroot/osst/Driver/osst.h,v 1.16 2005/01/01 21:13:35 wriede Exp $
  */
 
 #include <asm/byteorder.h>
@@ -70,7 +70,7 @@
 #define BLOCK_SIZE_PAGE_LENGTH     4
 
 #define BUFFER_FILLING_PAGE        0x33
-#define BUFFER_FILLING_PAGE_LENGTH 
+#define BUFFER_FILLING_PAGE_LENGTH 4
 
 #define VENDOR_IDENT_PAGE          0x36
 #define VENDOR_IDENT_PAGE_LENGTH   8
@@ -508,7 +508,7 @@
 //#define OSST_MAX_SG      2
 
 /* The OnStream tape buffer descriptor. */
-typedef struct {
+struct osst_buffer {
   unsigned char in_use;
   unsigned char dma;	/* DMA-able buffer */
   int buffer_size;
@@ -525,16 +525,16 @@
   unsigned short sg_segs;      /* number of segments in s/g list                  */
   unsigned short orig_sg_segs; /* number of segments allocated at first try       */
   struct scatterlist sg[1];    /* MUST BE last item                               */
-} OSST_buffer;
+} ;
 
 /* The OnStream tape drive descriptor */
-typedef struct {
+struct osst_tape {
   struct scsi_driver *driver;
   unsigned capacity;
   Scsi_Device* device;
   struct semaphore lock;       /* for serialization */
   struct completion wait;      /* for SCSI commands */
-  OSST_buffer * buffer;
+  struct osst_buffer * buffer;
 
   /* Drive characteristics */
   unsigned char omit_blklims;
@@ -577,6 +577,7 @@
   int min_block;
   int max_block;
   int recover_count;            /* from tape opening */
+  int abort_count;
   int write_count;
   int read_count;
   int recover_erreg;            /* from last status call */
@@ -623,7 +624,7 @@
   unsigned char last_sense[16];
 #endif
   struct gendisk *drive;
-} OS_Scsi_Tape;
+} ;
 
 /* Values of write_type */
 #define OS_WRITE_DATA      0
diff -Nru a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
--- a/drivers/scsi/pcmcia/aha152x_stub.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/pcmcia/aha152x_stub.c	2005-01-19 13:44:47 -08:00
@@ -70,10 +70,6 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
 /* SCSI bus setup options */
 static int host_id = 7;
 static int reconnect = 1;
@@ -82,8 +78,6 @@
 static int reset_delay = 100;
 static int ext_trans = 0;
 
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
 module_param(host_id, int, 0);
 module_param(reconnect, int, 0);
 module_param(parity, int, 0);
@@ -116,7 +110,7 @@
     scsi_info_t *info;
     client_reg_t client_reg;
     dev_link_t *link;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "aha152x_attach()\n");
 
@@ -130,12 +124,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 10;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
--- a/drivers/scsi/pcmcia/fdomain_stub.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/pcmcia/fdomain_stub.c	2005-01-19 13:44:47 -08:00
@@ -61,12 +61,6 @@
 MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-/* Bit map of interrupts to choose from */
-static int irq_mask = 0xdeb8;
-module_param(irq_mask, int, 0);
-static int irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-
 #ifdef PCMCIA_DEBUG
 static int pc_debug = PCMCIA_DEBUG;
 module_param(pc_debug, int, 0);
@@ -103,7 +97,7 @@
     scsi_info_t *info;
     client_reg_t client_reg;
     dev_link_t *link;
-    int i, ret;
+    int ret;
     
     DEBUG(0, "fdomain_attach()\n");
 
@@ -116,12 +110,7 @@
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 10;
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] == -1)
-	link->irq.IRQInfo2 = irq_mask;
-    else
-	for (i = 0; i < 4; i++)
-	    link->irq.IRQInfo2 |= 1 << irq_list[i];
+    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/scsi/pcmcia/nsp_cs.c	2005-01-19 13:44:48 -08:00
@@ -72,14 +72,6 @@
 /*====================================================================*/
 /* Parameters that can be set with 'insmod' */
 
-static unsigned int irq_mask = 0xffff;
-module_param(irq_mask, int, 0);
-MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xffff)");
-
-static int       irq_list[4] = { -1 };
-module_param_array(irq_list, int, NULL, 0);
-MODULE_PARM_DESC(irq_list, "Use specified IRQ number. (default: auto select)");
-
 static int       nsp_burst_mode = BURST_MEM32;
 module_param(nsp_burst_mode, int, 0);
 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
@@ -1625,7 +1617,7 @@
 	scsi_info_t  *info;
 	client_reg_t  client_reg;
 	dev_link_t   *link;
-	int	      ret, i;
+	int	      ret;
 	nsp_hw_data  *data = &nsp_data_base;
 
 	nsp_dbg(NSP_DEBUG_INIT, "in");
@@ -1647,14 +1639,7 @@
 
 	/* Interrupt setup */
 	link->irq.Attributes	 = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	link->irq.IRQInfo1	 = IRQ_INFO2_VALID    | IRQ_LEVEL_ID;
-	if (irq_list[0] == -1) {
-		link->irq.IRQInfo2 = irq_mask;
-	} else {
-		for (i = 0; i < 4; i++) {
-			link->irq.IRQInfo2 |= BIT(irq_list[i]);
-		}
-	}
+	link->irq.IRQInfo1	 = IRQ_LEVEL_ID;
 
 	/* Interrupt handler */
 	link->irq.Handler	 = &nspintr;
diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
--- a/drivers/scsi/pcmcia/qlogic_stub.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/pcmcia/qlogic_stub.c	2005-01-19 13:44:46 -08:00
@@ -93,17 +93,6 @@
 
 /*====================================================================*/
 
-/* Parameters that can be set with 'insmod' */
-
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xdeb8;
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, int, 0);
-module_param_array(irq_list, int, NULL, 0);
-
-/*====================================================================*/
-
 typedef struct scsi_info_t {
 	dev_link_t link;
 	dev_node_t node;
@@ -182,7 +171,7 @@
 	scsi_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	DEBUG(0, "qlogic_attach()\n");
 
@@ -197,12 +186,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 	link->io.IOAddrLines = 10;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
diff -Nru a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
--- a/drivers/scsi/pcmcia/sym53c500_cs.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c	2005-01-19 13:44:47 -08:00
@@ -92,19 +92,6 @@
 
 /* ================================================================== */
 
-/* Parameters that can be set with 'insmod' */
-
-/* Bit map of interrupts to choose from */
-static unsigned int irq_mask = 0xdeb8;	/* 3-5, 7, 9-12, 14, 15 */
-static int irq_list[4] = { -1 };
-
-module_param(irq_mask, int, 0);
-MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xdeb8)");
-module_param_array(irq_list, int, NULL, 0);
-MODULE_PARM_DESC(irq_list, "Comma-separated list of up to 4 IRQs to try (default: auto select).");
-
-/* ================================================================== */
-
 #define SYNC_MODE 0 		/* Synchronous transfer mode */
 
 /* Default configuration */
@@ -965,7 +952,7 @@
 	struct scsi_info_t *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	DEBUG(0, "SYM53C500_attach()\n");
 
@@ -980,12 +967,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 	link->io.IOAddrLines = 10;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
--- a/drivers/scsi/qla1280.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/scsi/qla1280.c	2005-01-19 13:44:48 -08:00
@@ -3400,7 +3400,8 @@
 	sp->flags |= SRB_SENT;
 	ha->actthreads++;
 	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-	(void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+	/* Enforce mmio write ordering; see comment in qla1280_isp_cmd(). */
+	mmiowb();
 
  out:
 	if (status)
@@ -3668,7 +3669,8 @@
 	sp->flags |= SRB_SENT;
 	ha->actthreads++;
 	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-	(void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+	/* Enforce mmio write ordering; see comment in qla1280_isp_cmd(). */
+	mmiowb();
 
 out:
 	if (status)
@@ -3778,9 +3780,21 @@
 	} else
 		ha->request_ring_ptr++;
 
-	/* Set chip new ring index. */
+	/*
+	 * Update request index to mailbox4 (Request Queue In).
+	 * The mmiowb() ensures that this write is ordered with writes by other
+	 * CPUs.  Without the mmiowb(), it is possible for the following:
+	 *    CPUA posts write of index 5 to mailbox4
+	 *    CPUA releases host lock
+	 *    CPUB acquires host lock
+	 *    CPUB posts write of index 6 to mailbox4
+	 *    On PCI bus, order reverses and write of 6 posts, then index 5,
+	 *       causing chip to issue full queue of stale commands
+	 * The mmiowb() prevents future writes from crossing the barrier.
+	 * See Documentation/DocBook/deviceiobook.tmpl for more information.
+	 */
 	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-	(void) RD_REG_WORD(&reg->mailbox4); /* PCI posted write flush */
+	mmiowb();
 
 	LEAVE("qla1280_isp_cmd");
 }
diff -Nru a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
--- a/drivers/scsi/sata_sil.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/scsi/sata_sil.c	2005-01-19 13:44:45 -08:00
@@ -71,6 +71,8 @@
 	{ 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
 	{ 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
 	{ 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
+	{ 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+	{ 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
 	{ }	/* terminate list */
 };
 
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/scsi.c	2005-01-19 13:44:46 -08:00
@@ -1083,6 +1083,28 @@
 EXPORT_SYMBOL(__scsi_iterate_devices);
 
 /**
+ * starget_for_each_device  -  helper to walk all devices of a target
+ * @starget:	target whose devices we want to iterate over.
+ *
+ * This traverses over each devices of @shost.  The devices have
+ * a reference that must be released by scsi_host_put when breaking
+ * out of the loop.
+ */
+void starget_for_each_device(struct scsi_target *starget, void * data,
+		     void (*fn)(struct scsi_device *, void *))
+{
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct scsi_device *sdev;
+
+	shost_for_each_device(sdev, shost) {
+		if ((sdev->channel == starget->channel) &&
+		    (sdev->id == starget->id))
+			fn(sdev, data);
+	}
+}
+EXPORT_SYMBOL(starget_for_each_device);
+
+/**
  * scsi_device_lookup - find a device given the host (UNLOCKED)
  * @shost:	SCSI host pointer
  * @channel:	SCSI channel (zero if only one channel)
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/scsi_lib.c	2005-01-19 13:44:46 -08:00
@@ -1782,31 +1782,29 @@
 }
 EXPORT_SYMBOL(scsi_device_resume);
 
-static int
-device_quiesce_fn(struct device *dev, void *data)
+static void
+device_quiesce_fn(struct scsi_device *sdev, void *data)
 {
-	scsi_device_quiesce(to_scsi_device(dev));
-	return 0;
+	scsi_device_quiesce(sdev);
 }
 
 void
 scsi_target_quiesce(struct scsi_target *starget)
 {
-	device_for_each_child(&starget->dev, NULL, device_quiesce_fn);
+	starget_for_each_device(starget, NULL, device_quiesce_fn);
 }
 EXPORT_SYMBOL(scsi_target_quiesce);
 
-static int
-device_resume_fn(struct device *dev, void *data)
+static void
+device_resume_fn(struct scsi_device *sdev, void *data)
 {
-	scsi_device_resume(to_scsi_device(dev));
-	return 0;
+	scsi_device_resume(sdev);
 }
 
 void
 scsi_target_resume(struct scsi_target *starget)
 {
-	device_for_each_child(&starget->dev, NULL, device_resume_fn);
+	starget_for_each_device(starget, NULL, device_resume_fn);
 }
 EXPORT_SYMBOL(scsi_target_resume);
 
diff -Nru a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
--- a/drivers/scsi/scsi_transport_fc.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/scsi/scsi_transport_fc.c	2005-01-19 13:44:45 -08:00
@@ -270,6 +270,16 @@
 		sizeof(fc_host_symbolic_name(shost)));
 	fc_host_supported_speeds(shost) = FC_PORTSPEED_UNKNOWN;
 	fc_host_maxframe_size(shost) = -1;
+	memset(fc_host_hardware_version(shost), 0,
+		sizeof(fc_host_hardware_version(shost)));
+	memset(fc_host_firmware_version(shost), 0,
+		sizeof(fc_host_firmware_version(shost)));
+	memset(fc_host_serial_number(shost), 0,
+		sizeof(fc_host_serial_number(shost)));
+	memset(fc_host_opt_rom_version(shost), 0,
+		sizeof(fc_host_opt_rom_version(shost)));
+	memset(fc_host_driver_version(shost), 0,
+		sizeof(fc_host_driver_version(shost)));
 
 	fc_host_port_id(shost) = -1;
 	fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
@@ -536,6 +546,11 @@
 fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
 fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1));
 fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
+fc_private_host_rd_attr(hardware_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
+fc_private_host_rd_attr(firmware_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
+fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
+fc_private_host_rd_attr(opt_rom_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
+fc_private_host_rd_attr(driver_version, "%s\n", (FC_VERSION_STRING_SIZE +1));
 
 
 /* Dynamic Host Attributes */
@@ -772,6 +787,11 @@
 	SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
 	SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
 	SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
+	SETUP_HOST_ATTRIBUTE_RD(hardware_version);
+	SETUP_HOST_ATTRIBUTE_RD(firmware_version);
+	SETUP_HOST_ATTRIBUTE_RD(serial_number);
+	SETUP_HOST_ATTRIBUTE_RD(opt_rom_version);
+	SETUP_HOST_ATTRIBUTE_RD(driver_version);
 
 	SETUP_HOST_ATTRIBUTE_RD(port_id);
 	SETUP_HOST_ATTRIBUTE_RD(port_type);
@@ -808,10 +828,9 @@
  * @dev:	scsi device
  * @data:	unused
  **/
-static int fc_device_block(struct device *dev, void *data)
+static void fc_device_block(struct scsi_device *sdev, void *data)
 {
-	scsi_internal_device_block(to_scsi_device(dev));
-	return 0;
+	scsi_internal_device_block(sdev);
 }
 
 /**
@@ -819,10 +838,9 @@
  * @dev:	scsi device
  * @data:	unused
  **/
-static int fc_device_unblock(struct device *dev, void *data)
+static void fc_device_unblock(struct scsi_device *sdev, void *data)
 {
-	scsi_internal_device_unblock(to_scsi_device(dev));
-	return 0;
+	scsi_internal_device_unblock(sdev);
 }
 
 /**
@@ -842,7 +860,7 @@
 	 * unblock this device, then IO errors will probably
 	 * result if the host still isn't ready.
 	 */
-	device_for_each_child(&starget->dev, NULL, fc_device_unblock);
+	starget_for_each_device(starget, NULL, fc_device_unblock);
 }
 
 /**
@@ -870,7 +888,7 @@
 	if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
 		return -EINVAL;
 
-	device_for_each_child(&starget->dev, NULL, fc_device_block);
+	starget_for_each_device(starget, NULL, fc_device_block);
 
 	/* The scsi lld blocks this target for the timeout period only. */
 	schedule_delayed_work(work, timeout * HZ);
@@ -901,7 +919,7 @@
 	if (cancel_delayed_work(&fc_starget_dev_loss_work(starget)))
 		flush_scheduled_work();
 
-	device_for_each_child(&starget->dev, NULL, fc_device_unblock);
+	starget_for_each_device(starget, NULL, fc_device_unblock);
 }
 EXPORT_SYMBOL(fc_target_unblock);
 
diff -Nru a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
--- a/drivers/scsi/scsi_transport_spi.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/scsi_transport_spi.c	2005-01-19 13:44:46 -08:00
@@ -31,6 +31,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_request.h>
+#include <scsi/scsi_eh.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_spi.h>
 
@@ -378,10 +379,16 @@
 #define DV_RETRIES	3	/* should only need at most 
 				 * two cc/ua clears */
 
+enum spi_compare_returns {
+	SPI_COMPARE_SUCCESS,
+	SPI_COMPARE_FAILURE,
+	SPI_COMPARE_SKIP_TEST,
+};
+
 
 /* This is for read/write Domain Validation:  If the device supports
  * an echo buffer, we do read/write tests to it */
-static int
+static enum spi_compare_returns
 spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer,
 			  u8 *ptr, const int retries)
 {
@@ -438,9 +445,23 @@
 		scsi_wait_req(sreq, spi_write_buffer, buffer, len,
 			      DV_TIMEOUT, DV_RETRIES);
 		if(sreq->sr_result || !scsi_device_online(sdev)) {
+			struct scsi_sense_hdr sshdr;
+
 			scsi_device_set_state(sdev, SDEV_QUIESCE);
+			if (scsi_request_normalize_sense(sreq, &sshdr)
+			    && sshdr.sense_key == ILLEGAL_REQUEST
+			    /* INVALID FIELD IN CDB */
+			    && sshdr.asc == 0x24 && sshdr.ascq == 0x00)
+				/* This would mean that the drive lied
+				 * to us about supporting an echo
+				 * buffer (unfortunately some Western
+				 * Digital drives do precisely this)
+				 */
+				return SPI_COMPARE_SKIP_TEST;
+
+
 			SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Write Buffer failure %x\n", sreq->sr_result);
-			return 0;
+			return SPI_COMPARE_FAILURE;
 		}
 
 		memset(ptr, 0, len);
@@ -451,14 +472,14 @@
 		scsi_device_set_state(sdev, SDEV_QUIESCE);
 
 		if (memcmp(buffer, ptr, len) != 0)
-			return 0;
+			return SPI_COMPARE_FAILURE;
 	}
-	return 1;
+	return SPI_COMPARE_SUCCESS;
 }
 
 /* This is for the simplest form of Domain Validation: a read test
  * on the inquiry data from the device */
-static int
+static enum spi_compare_returns
 spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer,
 			      u8 *ptr, const int retries)
 {
@@ -480,7 +501,7 @@
 		
 		if(sreq->sr_result || !scsi_device_online(sdev)) {
 			scsi_device_set_state(sdev, SDEV_QUIESCE);
-			return 0;
+			return SPI_COMPARE_FAILURE;
 		}
 
 		/* If we don't have the inquiry data already, the
@@ -493,24 +514,28 @@
 
 		if (memcmp(buffer, ptr, len) != 0)
 			/* failure */
-			return 0;
+			return SPI_COMPARE_FAILURE;
 	}
-	return 1;
+	return SPI_COMPARE_SUCCESS;
 }
 
-static int
+static enum spi_compare_returns
 spi_dv_retrain(struct scsi_request *sreq, u8 *buffer, u8 *ptr,
-	       int (*compare_fn)(struct scsi_request *, u8 *, u8 *, int))
+	       enum spi_compare_returns 
+	       (*compare_fn)(struct scsi_request *, u8 *, u8 *, int))
 {
 	struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt);
 	struct scsi_device *sdev = sreq->sr_device;
 	int period = 0, prevperiod = 0; 
+	enum spi_compare_returns retval;
 
 
 	for (;;) {
 		int newperiod;
-		if (compare_fn(sreq, buffer, ptr, DV_LOOPS))
-			/* Successful DV */
+		retval = compare_fn(sreq, buffer, ptr, DV_LOOPS);
+
+		if (retval == SPI_COMPARE_SUCCESS
+		    || retval == SPI_COMPARE_SKIP_TEST)
 			break;
 
 		/* OK, retrain, fallback */
@@ -527,13 +552,13 @@
 			/* Total failure; set to async and return */
 			SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n");
 			DV_SET(offset, 0);
-			return 0;
+			return SPI_COMPARE_FAILURE;
 		}
 		SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation detected failure, dropping back\n");
 		DV_SET(period, period);
 		prevperiod = period;
 	}
-	return 1;
+	return retval;
 }
 
 static int
@@ -599,7 +624,8 @@
 	DV_SET(offset, 0);
 	DV_SET(width, 0);
 	
-	if (!spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS)) {
+	if (spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS)
+	    != SPI_COMPARE_SUCCESS) {
 		SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Initial Inquiry Failed\n");
 		/* FIXME: should probably offline the device here? */
 		return;
@@ -609,9 +635,10 @@
 	if (i->f->set_width && sdev->wdtr) {
 		i->f->set_width(sdev->sdev_target, 1);
 
-		if (!spi_dv_device_compare_inquiry(sreq, buffer,
+		if (spi_dv_device_compare_inquiry(sreq, buffer,
 						   buffer + len,
-						   DV_LOOPS)) {
+						   DV_LOOPS)
+		    != SPI_COMPARE_SUCCESS) {
 			SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Wide Transfers Fail\n");
 			i->f->set_width(sdev->sdev_target, 0);
 		}
@@ -624,31 +651,39 @@
 	if(!sdev->ppr && !sdev->sdtr)
 		return;
 
-	/* now set up to the maximum */
-	DV_SET(offset, 255);
-	DV_SET(period, 1);
-	if (!spi_dv_retrain(sreq, buffer, buffer + len,
-			    spi_dv_device_compare_inquiry))
-		return;
-
-	/* OK, now we have our initial speed set by the read only inquiry
-	 * test, now try an echo buffer test (if the device allows it) */
+	/* see if the device has an echo buffer.  If it does we can
+	 * do the SPI pattern write tests */
 
 	len = 0;
 	if (sdev->ppr)
 		len = spi_dv_device_get_echo_buffer(sreq, buffer);
 
+ retry:
+
+	/* now set up to the maximum */
+	DV_SET(offset, 255);
+	DV_SET(period, 1);
+
 	if (len == 0) {
 		SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n");
+		spi_dv_retrain(sreq, buffer, buffer + len,
+			       spi_dv_device_compare_inquiry);
 		return;
 	}
+
 	if (len > SPI_MAX_ECHO_BUFFER_SIZE) {
 		SPI_PRINTK(sdev->sdev_target, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE);
 		len = SPI_MAX_ECHO_BUFFER_SIZE;
 	}
 
-	spi_dv_retrain(sreq, buffer, buffer + len,
-		       spi_dv_device_echo_buffer);
+	if (spi_dv_retrain(sreq, buffer, buffer + len,
+			   spi_dv_device_echo_buffer)
+	    == SPI_COMPARE_SKIP_TEST) {
+		/* OK, the stupid drive can't do a write echo buffer
+		 * test after all, fall back to the read tests */
+		len = 0;
+		goto retry;
+	}
 }
 
 
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/sd.c	2005-01-19 13:44:47 -08:00
@@ -1082,9 +1082,12 @@
 				       " READ CAPACITY(16).\n", diskname);
 				longrc = 1;
 				goto repeat;
-			} else {
-				printk(KERN_ERR "%s: too big for kernel.  Assuming maximum 2Tb\n", diskname);
 			}
+			printk(KERN_ERR "%s: too big for this kernel.  Use a "
+			       "kernel compiled with support for large block "
+			       "devices.\n", diskname);
+			sdkp->capacity = 0;
+			goto got_data;
 		}
 		sdkp->capacity = 1 + (((sector_t)buffer[0] << 24) |
 			(buffer[1] << 16) |
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_conf.h b/drivers/scsi/sym53c8xx_2/sym_conf.h
--- a/drivers/scsi/sym53c8xx_2/sym_conf.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_conf.h	2005-01-19 13:44:47 -08:00
@@ -79,14 +79,6 @@
 /* #define SYM_CONF_IARB_SUPPORT */
 
 /*
- *  Number of lists for the optimization of the IO timeout handling.
- *  Not used under FreeBSD and Linux.
- */
-#ifndef SYM_CONF_TIMEOUT_ORDER_MAX
-#define SYM_CONF_TIMEOUT_ORDER_MAX	(8)
-#endif
-
-/*
  *  Only relevant if IARB support configured.
  *  - Max number of successive settings of IARB hints.
  *  - Set IARB on arbitration lost.
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h
--- a/drivers/scsi/sym53c8xx_2/sym_defs.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_defs.h	2005-01-19 13:44:46 -08:00
@@ -40,30 +40,10 @@
 #ifndef SYM_DEFS_H
 #define SYM_DEFS_H
 
-#define SYM_VERSION "2.1.18m"
+#define SYM_VERSION "2.1.18n"
 #define SYM_DRIVER_NAME	"sym-" SYM_VERSION
 
 /*
- *  PCI device identifier of SYMBIOS chips.
- */
-#define PCI_ID_SYM53C810	PCI_DEVICE_ID_NCR_53C810
-#define PCI_ID_SYM53C810AP	PCI_DEVICE_ID_LSI_53C810AP
-#define PCI_ID_SYM53C815	PCI_DEVICE_ID_NCR_53C815
-#define PCI_ID_SYM53C820	PCI_DEVICE_ID_NCR_53C820
-#define PCI_ID_SYM53C825	PCI_DEVICE_ID_NCR_53C825
-#define PCI_ID_SYM53C860	PCI_DEVICE_ID_NCR_53C860
-#define PCI_ID_SYM53C875	PCI_DEVICE_ID_NCR_53C875
-#define PCI_ID_SYM53C875_2	PCI_DEVICE_ID_NCR_53C875J
-#define PCI_ID_SYM53C885	PCI_DEVICE_ID_NCR_53C885
-#define PCI_ID_SYM53C895	PCI_DEVICE_ID_NCR_53C895
-#define PCI_ID_SYM53C896	PCI_DEVICE_ID_NCR_53C896
-#define PCI_ID_SYM53C895A	PCI_DEVICE_ID_LSI_53C895A
-#define PCI_ID_SYM53C875A	PCI_DEVICE_ID_LSI_53C875A
-#define PCI_ID_LSI53C1010_33	PCI_DEVICE_ID_LSI_53C1010_33
-#define PCI_ID_LSI53C1010_66	PCI_DEVICE_ID_LSI_53C1010_66
-#define PCI_ID_LSI53C1510D	PCI_DEVICE_ID_LSI_53C1510
-
-/*
  *	SYM53C8XX device features descriptor.
  */
 struct sym_pci_chip {
@@ -764,27 +744,27 @@
 #define	M_RESTORE_DP	RESTORE_POINTERS
 #define	M_DISCONNECT	DISCONNECT
 #define	M_ID_ERROR	INITIATOR_ERROR
-#define	M_ABORT		ABORT
+#define	M_ABORT		ABORT_TASK_SET
 #define	M_REJECT	MESSAGE_REJECT
 #define	M_NOOP		NOP
 #define	M_PARITY	MSG_PARITY_ERROR
 #define	M_LCOMPLETE	LINKED_CMD_COMPLETE
 #define	M_FCOMPLETE	LINKED_FLG_CMD_COMPLETE
-#define	M_RESET		BUS_DEVICE_RESET
-#define	M_ABORT_TAG	(0x0d)
-#define	M_CLEAR_QUEUE	(0x0e)
+#define	M_RESET		TARGET_RESET
+#define	M_ABORT_TAG	ABORT_TASK
+#define	M_CLEAR_QUEUE	CLEAR_TASK_SET
 #define	M_INIT_REC	INITIATE_RECOVERY
 #define	M_REL_REC	RELEASE_RECOVERY
 #define	M_TERMINATE	(0x11)
 #define	M_SIMPLE_TAG	SIMPLE_QUEUE_TAG
 #define	M_HEAD_TAG	HEAD_OF_QUEUE_TAG
 #define	M_ORDERED_TAG	ORDERED_QUEUE_TAG
-#define	M_IGN_RESIDUE	(0x23)
+#define	M_IGN_RESIDUE	IGNORE_WIDE_RESIDUE
 
 #define	M_X_MODIFY_DP	EXTENDED_MODIFY_DATA_POINTER
 #define	M_X_SYNC_REQ	EXTENDED_SDTR
 #define	M_X_WIDE_REQ	EXTENDED_WDTR
-#define	M_X_PPR_REQ	(0x04)
+#define	M_X_PPR_REQ	EXTENDED_PPR
 
 /*
  *	PPR protocol options
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c
--- a/drivers/scsi/sym53c8xx_2/sym_fw.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_fw.c	2005-01-19 13:44:48 -08:00
@@ -223,13 +223,13 @@
 	 *  Remove a couple of work-arounds specific to C1010 if 
 	 *  they are not desirable. See `sym_fw2.h' for more details.
 	 */
-	if (!(np->device_id == PCI_ID_LSI53C1010_66 &&
+	if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_66 &&
 	      np->revision_id < 0x1 &&
 	      np->pciclk_khz < 60000)) {
 		scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
 		scripta0->datao_phase[1] = cpu_to_scr(0);
 	}
-	if (!(np->device_id == PCI_ID_LSI53C1010_33 &&
+	if (!(np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
 	      /* np->revision_id < 0xff */ 1)) {
 		scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
 		scripta0->sel_done[1] = cpu_to_scr(0);
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c	2005-01-19 13:44:48 -08:00
@@ -55,6 +55,15 @@
 #define NAME53C		"sym53c"
 #define NAME53C8XX	"sym53c8xx"
 
+/* SPARC just has to be different ... */
+#ifdef __sparc__
+#define IRQ_FMT "%s"
+#define IRQ_PRM(x) __irq_itoa(x)
+#else
+#define IRQ_FMT "%d"
+#define IRQ_PRM(x) (x)
+#endif
+
 struct sym_driver_setup sym_driver_setup = SYM_LINUX_DRIVER_SETUP;
 unsigned int sym_debug_flags = 0;
 
@@ -147,7 +156,7 @@
 }
 
 /* This lock protects only the memory allocation/free.  */
-spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
 
 static struct scsi_transport_template *sym2_transport_template = NULL;
 
@@ -285,7 +294,7 @@
 	ccb->scsi_done(ccb);
 }
 
-void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *ccb, int cam_status)
+static void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *ccb, int cam_status)
 {
 	sym_set_cam_status(ccb, cam_status);
 	sym_xpt_done(np, ccb);
@@ -379,7 +388,7 @@
 			/*
 			 *  Bounce back the sense data to user.
 			 */
-			bzero(&csio->sense_buffer, sizeof(csio->sense_buffer));
+			memset(&csio->sense_buffer, 0, sizeof(csio->sense_buffer));
 			memcpy(csio->sense_buffer, cp->sns_bbuf,
 			      min(sizeof(csio->sense_buffer),
 				  (size_t)SYM_SNS_BBUF_LEN));
@@ -513,7 +522,7 @@
 	}
 
 	/*
-	 *  Retreive the target descriptor.
+	 *  Retrieve the target descriptor.
 	 */
 	tp = &np->target[ccb->device->id];
 
@@ -1277,7 +1286,7 @@
 	int		arg_len;
 	u_long 		target;
 
-	bzero(uc, sizeof(*uc));
+	memset(uc, 0, sizeof(*uc));
 
 	if (len > 0 && ptr[len-1] == '\n')
 		--len;
@@ -1467,18 +1476,8 @@
 	copy_info(&info, "Chip " NAME53C "%s, device id 0x%x, "
 			 "revision id 0x%x\n",
 			 np->s.chip_name, np->device_id, np->revision_id);
-	copy_info(&info, "At PCI address %s, "
-#ifdef __sparc__
-		"IRQ %s\n",
-#else
-		"IRQ %d\n",
-#endif
-		pci_name(np->s.device),
-#ifdef __sparc__
-		__irq_itoa(np->s.irq));
-#else
-		(int) np->s.irq);
-#endif
+	copy_info(&info, "At PCI address %s, IRQ " IRQ_FMT "\n",
+		pci_name(np->s.device), IRQ_PRM(np->s.irq));
 	copy_info(&info, "Min. period factor %d, %s SCSI BUS%s\n",
 			 (int) (np->minsync_dt ? np->minsync_dt : np->minsync),
 			 np->maxwide ? "Wide" : "Narrow",
@@ -1558,32 +1557,23 @@
  */
 static int sym_setup_bus_dma_mask(struct sym_hcb *np)
 {
-#if   SYM_CONF_DMA_ADDRESSING_MODE == 0
-	if (pci_set_dma_mask(np->s.device, 0xffffffffUL))
-		goto out_err32;
-#else
+#if SYM_CONF_DMA_ADDRESSING_MODE > 0
 #if   SYM_CONF_DMA_ADDRESSING_MODE == 1
-#define	PciDmaMask	0xffffffffffULL
+#define	DMA_DAC_MASK	0x000000ffffffffffULL /* 40-bit */
 #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
-#define	PciDmaMask	0xffffffffffffffffULL
+#define	DMA_DAC_MASK	DMA_64BIT_MASK
 #endif
-	if (np->features & FE_DAC) {
-		if (!pci_set_dma_mask(np->s.device, PciDmaMask)) {
-			np->use_dac = 1;
-			printf_info("%s: using 64 bit DMA addressing\n",
-					sym_name(np));
-		} else {
-			if (pci_set_dma_mask(np->s.device, 0xffffffffUL))
-				goto out_err32;
-		}
+	if ((np->features & FE_DAC) &&
+			!pci_set_dma_mask(np->s.device, DMA_DAC_MASK)) {
+		np->use_dac = 1;
+		return 0;
 	}
-#undef	PciDmaMask
 #endif
-	return 0;
 
-out_err32:
-	printf_warning("%s: 32 BIT DMA ADDRESSING NOT SUPPORTED\n",
-			sym_name(np));
+	if (!pci_set_dma_mask(np->s.device, DMA_32BIT_MASK))
+		return 0;
+
+	printf_warning("%s: No suitable DMA available\n", sym_name(np));
 	return -1;
 }
 
@@ -1606,19 +1596,9 @@
 	struct sym_fw *fw;
 
 	printk(KERN_INFO
-		"sym%d: <%s> rev 0x%x at pci %s "
-#ifdef __sparc__
-		"irq %s\n",
-#else
-		"irq %d\n",
-#endif
+		"sym%d: <%s> rev 0x%x at pci %s irq " IRQ_FMT "\n",
 		unit, dev->chip.name, dev->chip.revision_id,
-		pci_name(dev->pdev),
-#ifdef __sparc__
-		__irq_itoa(dev->s.irq));
-#else
-		dev->s.irq);
-#endif
+		pci_name(dev->pdev), IRQ_PRM(dev->s.irq));
 
 	/*
 	 *  Get the firmware for this chip.
@@ -1672,9 +1652,6 @@
 	strlcpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name));
 	sprintf(np->s.inst_name, "sym%d", np->s.unit);
 
-	/*
-	 *  Ask/tell the system about DMA addressing.
-	 */
 	if (sym_setup_bus_dma_mask(np))
 		goto attach_failed;
 
@@ -2010,7 +1987,7 @@
  * the preset SCSI ID (which may be zero) must be read in from
  * a special configuration space register of the 875.
  */
-void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev)
+static void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev)
 {
 	int slot;
 	u8 tmp;
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h	2005-01-19 13:44:48 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h	2005-01-19 13:44:48 -08:00
@@ -58,13 +58,6 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 
-#ifndef bzero
-#define bzero(d, n)	memset((d), 0, (n))
-#endif
-
-/*
- *  General driver includes.
- */
 #include "sym_conf.h"
 #include "sym_defs.h"
 #include "sym_misc.h"
@@ -123,14 +116,6 @@
 typedef struct sym_tcb *tcb_p;
 typedef struct sym_lcb *lcb_p;
 typedef struct sym_ccb *ccb_p;
-typedef struct sym_hcb *hcb_p;
-
-/*
- *  Define a reference to the O/S dependent IO request.
- */
-typedef struct scsi_cmnd *cam_ccb_p;	/* Generic */
-typedef struct scsi_cmnd *cam_scsiio_p;/* SCSI I/O */
-
 
 /*
  *  IO functions definition for big/little endian CPU support.
@@ -525,7 +510,7 @@
 /*
  *  Async handler for negotiations.
  */
-void sym_xpt_async_nego_wide(hcb_p np, int target);
+void sym_xpt_async_nego_wide(struct sym_hcb *np, int target);
 #define sym_xpt_async_nego_sync(np, target)	\
 	sym_announce_transfer_rate(np, target)
 #define sym_xpt_async_nego_ppr(np, target)	\
@@ -534,14 +519,14 @@
 /*
  *  Build CAM result for a successful IO and for a failed IO.
  */
-static __inline void sym_set_cam_result_ok(hcb_p np, ccb_p cp, int resid)
+static __inline void sym_set_cam_result_ok(struct sym_hcb *np, ccb_p cp, int resid)
 {
 	struct scsi_cmnd *cmd = cp->cam_ccb;
 
 	cmd->resid = resid;
 	cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f));
 }
-void sym_set_cam_result_error(hcb_p np, ccb_p cp, int resid);
+void sym_set_cam_result_error(struct sym_hcb *np, ccb_p cp, int resid);
 
 /*
  *  Other O/S specific methods.
@@ -549,13 +534,12 @@
 #define sym_cam_target_id(ccb)	(ccb)->target
 #define sym_cam_target_lun(ccb)	(ccb)->lun
 #define	sym_freeze_cam_ccb(ccb)	do { ; } while (0)
-void sym_xpt_done(hcb_p np, cam_ccb_p ccb);
-void sym_xpt_done2(hcb_p np, cam_ccb_p ccb, int cam_status);
+void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb);
 void sym_print_addr (ccb_p cp);
-void sym_xpt_async_bus_reset(hcb_p np);
-void sym_xpt_async_sent_bdr(hcb_p np, int target);
-int  sym_setup_data_and_start (hcb_p np, cam_scsiio_p csio, ccb_p cp);
-void sym_log_bus_error(hcb_p np);
-void sym_sniff_inquiry(hcb_p np, struct scsi_cmnd *cmd, int resid);
+void sym_xpt_async_bus_reset(struct sym_hcb *np);
+void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target);
+int  sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp);
+void sym_log_bus_error(struct sym_hcb *np);
+void sym_sniff_inquiry(struct sym_hcb *np, struct scsi_cmnd *cmd, int resid);
 
 #endif /* SYM_GLUE_H */
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c	2005-01-19 13:44:45 -08:00
@@ -47,14 +47,14 @@
 /*
  *  Needed function prototypes.
  */
-static void sym_int_ma (hcb_p np);
-static void sym_int_sir (hcb_p np);
-static ccb_p sym_alloc_ccb(hcb_p np);
-static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa);
-static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln);
-static void sym_complete_error (hcb_p np, ccb_p cp);
-static void sym_complete_ok (hcb_p np, ccb_p cp);
-static int sym_compute_residual(hcb_p np, ccb_p cp);
+static void sym_int_ma (struct sym_hcb *np);
+static void sym_int_sir (struct sym_hcb *np);
+static ccb_p sym_alloc_ccb(struct sym_hcb *np);
+static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa);
+static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln);
+static void sym_complete_error (struct sym_hcb *np, ccb_p cp);
+static void sym_complete_ok (struct sym_hcb *np, ccb_p cp);
+static int sym_compute_residual(struct sym_hcb *np, ccb_p cp);
 
 /*
  *  Returns the name of this driver.
@@ -86,12 +86,12 @@
  *  Print something which allows to retrieve the controler type, 
  *  unit, target, lun concerned by a kernel message.
  */
-static void sym_print_target (hcb_p np, int target)
+static void sym_print_target (struct sym_hcb *np, int target)
 {
 	printf ("%s:%d:", sym_name(np), target);
 }
 
-static void sym_print_lun(hcb_p np, int target, int lun)
+static void sym_print_lun(struct sym_hcb *np, int target, int lun)
 {
 	printf ("%s:%d:%d:", sym_name(np), target, lun);
 }
@@ -126,7 +126,7 @@
 	printf (".\n");
 }
 
-static void sym_print_nego_msg (hcb_p np, int target, char *label, u_char *msg)
+static void sym_print_nego_msg (struct sym_hcb *np, int target, char *label, u_char *msg)
 {
 	PRINT_TARGET(np, target);
 	if (label)
@@ -184,7 +184,7 @@
  *  On the other hand, LVD devices need some delay 
  *  to settle and report actual BUS mode in STEST4.
  */
-static void sym_chip_reset (hcb_p np)
+static void sym_chip_reset (struct sym_hcb *np)
 {
 	OUTB (nc_istat, SRST);
 	UDELAY (10);
@@ -201,7 +201,7 @@
  *  So, we need to abort the current operation prior to 
  *  soft resetting the chip.
  */
-static void sym_soft_reset (hcb_p np)
+static void sym_soft_reset (struct sym_hcb *np)
 {
 	u_char istat = 0;
 	int i;
@@ -234,12 +234,12 @@
  *
  *  The interrupt handler will reinitialize the chip.
  */
-static void sym_start_reset(hcb_p np)
+static void sym_start_reset(struct sym_hcb *np)
 {
 	(void) sym_reset_scsi_bus(np, 1);
 }
  
-int sym_reset_scsi_bus(hcb_p np, int enab_int)
+int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int)
 {
 	u32 term;
 	int retv = 0;
@@ -293,7 +293,7 @@
 /*
  *  Select SCSI clock frequency
  */
-static void sym_selectclock(hcb_p np, u_char scntl3)
+static void sym_selectclock(struct sym_hcb *np, u_char scntl3)
 {
 	/*
 	 *  If multiplier not present or not selected, leave here.
@@ -348,7 +348,7 @@
 /*
  *  calculate SCSI clock frequency (in KHz)
  */
-static unsigned getfreq (hcb_p np, int gen)
+static unsigned getfreq (struct sym_hcb *np, int gen)
 {
 	unsigned int ms = 0;
 	unsigned int f;
@@ -420,7 +420,7 @@
 	return f;
 }
 
-static unsigned sym_getfreq (hcb_p np)
+static unsigned sym_getfreq (struct sym_hcb *np)
 {
 	u_int f1, f2;
 	int gen = 8;
@@ -435,7 +435,7 @@
 /*
  *  Get/probe chip SCSI clock frequency
  */
-static void sym_getclock (hcb_p np, int mult)
+static void sym_getclock (struct sym_hcb *np, int mult)
 {
 	unsigned char scntl3 = np->sv_scntl3;
 	unsigned char stest1 = np->sv_stest1;
@@ -492,7 +492,7 @@
 /*
  *  Get/probe PCI clock frequency
  */
-static int sym_getpciclock (hcb_p np)
+static int sym_getpciclock (struct sym_hcb *np)
 {
 	int f = 0;
 
@@ -528,7 +528,7 @@
  *  synchronous factor period.
  */
 static int 
-sym_getsync(hcb_p np, u_char dt, u_char sfac, u_char *divp, u_char *fakp)
+sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fakp)
 {
 	u32	clk = np->clock_khz;	/* SCSI clock frequency in kHz	*/
 	int	div = np->clock_divn;	/* Number of divisors supported	*/
@@ -648,7 +648,7 @@
 /*
  *  Set initial io register bits from burst code.
  */
-static __inline void sym_init_burst(hcb_p np, u_char bc)
+static __inline void sym_init_burst(struct sym_hcb *np, u_char bc)
 {
 	np->rv_ctest4	&= ~0x80;
 	np->rv_dmode	&= ~(0x3 << 6);
@@ -668,7 +668,7 @@
 /*
  * Print out the list of targets that have some flag disabled by user.
  */
-static void sym_print_targets_flag(hcb_p np, int mask, char *msg)
+static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg)
 {
 	int cnt;
 	int i;
@@ -696,7 +696,7 @@
  *  is not safe on paper, but it seems to work quite 
  *  well. :)
  */
-static void sym_save_initial_setting (hcb_p np)
+static void sym_save_initial_setting (struct sym_hcb *np)
 {
 	np->sv_scntl0	= INB(nc_scntl0) & 0x0a;
 	np->sv_scntl3	= INB(nc_scntl3) & 0x07;
@@ -716,44 +716,11 @@
 		np->sv_ctest5	= INB(nc_ctest5) & 0x24;
 }
 
-#ifdef CONFIG_PARISC
-static u32 parisc_setup_hcb(hcb_p np, u32 period)
-{
-	unsigned long pdc_period;
-	char scsi_mode;
-	struct hardware_path hwpath;
-
-	/* Host firmware (PDC) keeps a table for crippling SCSI capabilities.
-	 * Many newer machines export one channel of 53c896 chip
-	 * as SE, 50-pin HD.  Also used for Multi-initiator SCSI clusters
-	 * to set the SCSI Initiator ID.
-	 */
-	get_pci_node_path(np->s.device, &hwpath);
-	if (!pdc_get_initiator(&hwpath, &np->myaddr, &pdc_period,
-				&np->maxwide, &scsi_mode))
-		return period;
-
-	if (scsi_mode >= 0) {
-		/* C3000 PDC reports period/mode */
-		SYM_SETUP_SCSI_DIFF = 0;
-		switch(scsi_mode) {
-		case 0:	np->scsi_mode = SMODE_SE; break;
-		case 1:	np->scsi_mode = SMODE_HVD; break;
-		case 2:	np->scsi_mode = SMODE_LVD; break;
-		default:	break;
-		}
-	}
-
-	return (u32) pdc_period;
-}
-#else
-static inline int parisc_setup_hcb(hcb_p np, u32 period) { return period; }
-#endif
 /*
  *  Prepare io register values used by sym_start_up() 
  *  according to selected and supported features.
  */
-static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
+static int sym_prepare_setting(struct sym_hcb *np, struct sym_nvram *nvram)
 {
 	u_char	burst_max;
 	u32	period;
@@ -816,8 +783,6 @@
 	 */
 	period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz;
 
-	period = parisc_setup_hcb(np, period);
-
 	if	(period <= 250)		np->minsync = 10;
 	else if	(period <= 303)		np->minsync = 11;
 	else if	(period <= 500)		np->minsync = 12;
@@ -880,7 +845,7 @@
 	 *  In dual channel mode, contention occurs if internal cycles
 	 *  are used. Disable internal cycles.
 	 */
-	if (np->device_id == PCI_ID_LSI53C1010_33 &&
+	if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
 	    np->revision_id < 0x1)
 		np->rv_ccntl0	|=  DILS;
 
@@ -904,9 +869,9 @@
 	 *  this driver. The generic ncr driver that does not use 
 	 *  LOAD/STORE instructions does not need this work-around.
 	 */
-	if ((np->device_id == PCI_ID_SYM53C810 &&
+	if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 &&
 	     np->revision_id >= 0x10 && np->revision_id <= 0x11) ||
-	    (np->device_id == PCI_ID_SYM53C860 &&
+	    (np->device_id == PCI_DEVICE_ID_NCR_53C860 &&
 	     np->revision_id <= 0x1))
 		np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP);
 
@@ -1000,7 +965,7 @@
 	if ((SYM_SETUP_SCSI_LED || 
 	     (nvram->type == SYM_SYMBIOS_NVRAM ||
 	      (nvram->type == SYM_TEKRAM_NVRAM &&
-	       np->device_id == PCI_ID_SYM53C895))) &&
+	       np->device_id == PCI_DEVICE_ID_NCR_53C895))) &&
 	    !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01))
 		np->features |= FE_LED0;
 
@@ -1091,7 +1056,7 @@
  *  Has to be called with interrupts disabled.
  */
 #ifndef SYM_CONF_IOMAPPED
-static int sym_regtest (hcb_p np)
+static int sym_regtest (struct sym_hcb *np)
 {
 	register volatile u32 data;
 	/*
@@ -1115,7 +1080,7 @@
 }
 #endif
 
-static int sym_snooptest (hcb_p np)
+static int sym_snooptest (struct sym_hcb *np)
 {
 	u32	sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;
 	int	i, err=0;
@@ -1241,7 +1206,7 @@
  *  First 24 register of the chip:
  *  	r0..rf
  */
-static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat)
+static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat)
 {
 	u32	dsp;
 	int	script_ofs;
@@ -1299,85 +1264,85 @@
 }
 
 static struct sym_pci_chip sym_pci_dev_table[] = {
- {PCI_ID_SYM53C810, 0x0f, "810", 4, 8, 4, 64,
+ {PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, 64,
  FE_ERL}
  ,
 #ifdef SYM_DEBUG_GENERIC_SUPPORT
- {PCI_ID_SYM53C810, 0xff, "810a", 4,  8, 4, 1,
+ {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4,  8, 4, 1,
  FE_BOF}
  ,
 #else
- {PCI_ID_SYM53C810, 0xff, "810a", 4,  8, 4, 1,
+ {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4,  8, 4, 1,
  FE_CACHE_SET|FE_LDSTR|FE_PFEN|FE_BOF}
  ,
 #endif
- {PCI_ID_SYM53C815, 0xff, "815", 4,  8, 4, 64,
+ {PCI_DEVICE_ID_NCR_53C815, 0xff, "815", 4,  8, 4, 64,
  FE_BOF|FE_ERL}
  ,
- {PCI_ID_SYM53C825, 0x0f, "825", 6,  8, 4, 64,
+ {PCI_DEVICE_ID_NCR_53C825, 0x0f, "825", 6,  8, 4, 64,
  FE_WIDE|FE_BOF|FE_ERL|FE_DIFF}
  ,
- {PCI_ID_SYM53C825, 0xff, "825a", 6,  8, 4, 2,
+ {PCI_DEVICE_ID_NCR_53C825, 0xff, "825a", 6,  8, 4, 2,
  FE_WIDE|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|FE_DIFF}
  ,
- {PCI_ID_SYM53C860, 0xff, "860", 4,  8, 5, 1,
+ {PCI_DEVICE_ID_NCR_53C860, 0xff, "860", 4,  8, 5, 1,
  FE_ULTRA|FE_CACHE_SET|FE_BOF|FE_LDSTR|FE_PFEN}
  ,
- {PCI_ID_SYM53C875, 0x01, "875", 6, 16, 5, 2,
+ {PCI_DEVICE_ID_NCR_53C875, 0x01, "875", 6, 16, 5, 2,
  FE_WIDE|FE_ULTRA|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DIFF|FE_VARCLK}
  ,
- {PCI_ID_SYM53C875, 0xff, "875", 6, 16, 5, 2,
+ {PCI_DEVICE_ID_NCR_53C875, 0xff, "875", 6, 16, 5, 2,
  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DIFF|FE_VARCLK}
  ,
- {PCI_ID_SYM53C875_2, 0xff, "875", 6, 16, 5, 2,
+ {PCI_DEVICE_ID_NCR_53C875J, 0xff, "875J", 6, 16, 5, 2,
  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DIFF|FE_VARCLK}
  ,
- {PCI_ID_SYM53C885, 0xff, "885", 6, 16, 5, 2,
+ {PCI_DEVICE_ID_NCR_53C885, 0xff, "885", 6, 16, 5, 2,
  FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DIFF|FE_VARCLK}
  ,
 #ifdef SYM_DEBUG_GENERIC_SUPPORT
- {PCI_ID_SYM53C895, 0xff, "895", 6, 31, 7, 2,
+ {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|
  FE_RAM|FE_LCKFRQ}
  ,
 #else
- {PCI_ID_SYM53C895, 0xff, "895", 6, 31, 7, 2,
+ {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_LCKFRQ}
  ,
 #endif
- {PCI_ID_SYM53C896, 0xff, "896", 6, 31, 7, 4,
+ {PCI_DEVICE_ID_NCR_53C896, 0xff, "896", 6, 31, 7, 4,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
  ,
- {PCI_ID_SYM53C895A, 0xff, "895a", 6, 31, 7, 4,
+ {PCI_DEVICE_ID_LSI_53C895A, 0xff, "895a", 6, 31, 7, 4,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
  ,
- {PCI_ID_SYM53C875A, 0xff, "875a", 6, 31, 7, 4,
+ {PCI_DEVICE_ID_LSI_53C875A, 0xff, "875a", 6, 31, 7, 4,
  FE_WIDE|FE_ULTRA|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
  ,
- {PCI_ID_LSI53C1010_33, 0x00, "1010-33", 6, 31, 7, 8,
+ {PCI_DEVICE_ID_LSI_53C1010_33, 0x00, "1010-33", 6, 31, 7, 8,
  FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
  FE_C10}
  ,
- {PCI_ID_LSI53C1010_33, 0xff, "1010-33", 6, 31, 7, 8,
+ {PCI_DEVICE_ID_LSI_53C1010_33, 0xff, "1010-33", 6, 31, 7, 8,
  FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
  FE_C10|FE_U3EN}
  ,
- {PCI_ID_LSI53C1010_66, 0xff, "1010-66", 6, 31, 7, 8,
+ {PCI_DEVICE_ID_LSI_53C1010_66, 0xff, "1010-66", 6, 31, 7, 8,
  FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_66MHZ|FE_CRC|
  FE_C10|FE_U3EN}
  ,
- {PCI_ID_LSI53C1510D, 0xff, "1510d", 6, 31, 7, 4,
+ {PCI_DEVICE_ID_LSI_53C1510, 0xff, "1510d", 6, 31, 7, 4,
  FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
  FE_RAM|FE_IO256|FE_LEDC}
 };
@@ -1415,7 +1380,7 @@
  *  This is only used if the direct mapping 
  *  has been unsuccessful.
  */
-int sym_lookup_dmap(hcb_p np, u32 h, int s)
+int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s)
 {
 	int i;
 
@@ -1448,7 +1413,7 @@
  *  Update IO registers scratch C..R so they will be 
  *  in sync. with queued CCB expectations.
  */
-static void sym_update_dmap_regs(hcb_p np)
+static void sym_update_dmap_regs(struct sym_hcb *np)
 {
 	int o, i;
 
@@ -1463,13 +1428,12 @@
 }
 #endif
 
+/* Enforce all the fiddly SPI rules and the chip limitations */
 static void sym_check_goals(struct scsi_device *sdev)
 {
 	struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb;
 	struct sym_trans *st = &np->target[sdev->id].tinfo.goal;
 
-	/* here we enforce all the fiddly SPI rules */
-
 	if (!scsi_device_wide(sdev))
 		st->width = 0;
 
@@ -1479,7 +1443,7 @@
 		st->offset = 0;
 		return;
 	}
-		
+
 	if (scsi_device_dt(sdev)) {
 		if (scsi_device_dt_only(sdev))
 			st->options |= PPR_OPT_DT;
@@ -1490,7 +1454,8 @@
 		st->options &= ~PPR_OPT_DT;
 	}
 
-	if (!(np->features & FE_ULTRA3))
+	/* Some targets fail to properly negotiate DT in SE mode */
+	if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN))
 		st->options &= ~PPR_OPT_DT;
 
 	if (st->options & PPR_OPT_DT) {
@@ -1520,38 +1485,31 @@
  *  negotiation and the nego_status field of the CCB.
  *  Returns the size of the message in bytes.
  */
-static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr)
+static int sym_prepare_nego(struct sym_hcb *np, ccb_p cp, u_char *msgptr)
 {
 	tcb_p tp = &np->target[cp->target];
-	int msglen = 0;
 	struct scsi_device *sdev = tp->sdev;
+	struct sym_trans *goal = &tp->tinfo.goal;
+	struct sym_trans *curr = &tp->tinfo.curr;
+	int msglen = 0;
+	int nego;
 
 	if (likely(sdev))
 		sym_check_goals(sdev);
 
 	/*
-	 *  Early C1010 chips need a work-around for DT 
-	 *  data transfer to work.
+	 * Many devices implement PPR in a buggy way, so only use it if we
+	 * really want to.
 	 */
-	if (!(np->features & FE_U3EN))
-		tp->tinfo.goal.options = 0;
-	/*
-	 *  negotiate using PPR ?
-	 */
-	if (scsi_device_dt(sdev)) {
+	if ((goal->options & PPR_OPT_MASK) || (goal->period < 0xa)) {
 		nego = NS_PPR;
+	} else if (curr->width != goal->width) {
+		nego = NS_WIDE;
+	} else if (curr->period != goal->period ||
+		   curr->offset != goal->offset) {
+		nego = NS_SYNC;
 	} else {
-		/*
-		 *  negotiate wide transfers ?
-		 */
-		if (tp->tinfo.curr.width != tp->tinfo.goal.width)
-			nego = NS_WIDE;
-		/*
-		 *  negotiate synchronous transfers?
-		 */
-		else if (tp->tinfo.curr.period != tp->tinfo.goal.period ||
-			 tp->tinfo.curr.offset != tp->tinfo.goal.offset)
-			nego = NS_SYNC;
+		nego = 0;
 	}
 
 	switch (nego) {
@@ -1559,24 +1517,24 @@
 		msgptr[msglen++] = M_EXTENDED;
 		msgptr[msglen++] = 3;
 		msgptr[msglen++] = M_X_SYNC_REQ;
-		msgptr[msglen++] = tp->tinfo.goal.period;
-		msgptr[msglen++] = tp->tinfo.goal.offset;
+		msgptr[msglen++] = goal->period;
+		msgptr[msglen++] = goal->offset;
 		break;
 	case NS_WIDE:
 		msgptr[msglen++] = M_EXTENDED;
 		msgptr[msglen++] = 2;
 		msgptr[msglen++] = M_X_WIDE_REQ;
-		msgptr[msglen++] = tp->tinfo.goal.width;
+		msgptr[msglen++] = goal->width;
 		break;
 	case NS_PPR:
 		msgptr[msglen++] = M_EXTENDED;
 		msgptr[msglen++] = 6;
 		msgptr[msglen++] = M_X_PPR_REQ;
-		msgptr[msglen++] = tp->tinfo.goal.period;
+		msgptr[msglen++] = goal->period;
 		msgptr[msglen++] = 0;
-		msgptr[msglen++] = tp->tinfo.goal.offset;
-		msgptr[msglen++] = tp->tinfo.goal.width;
-		msgptr[msglen++] = tp->tinfo.goal.options & PPR_OPT_MASK;
+		msgptr[msglen++] = goal->offset;
+		msgptr[msglen++] = goal->width;
+		msgptr[msglen++] = goal->options & PPR_OPT_MASK;
 		break;
 	};
 
@@ -1598,7 +1556,7 @@
 /*
  *  Insert a job into the start queue.
  */
-void sym_put_start_queue(hcb_p np, ccb_p cp)
+void sym_put_start_queue(struct sym_hcb *np, ccb_p cp)
 {
 	u_short	qidx;
 
@@ -1630,13 +1588,6 @@
 #endif
 
 	/*
-	 *  Optionnaly, set the IO timeout condition.
-	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	sym_timeout_ccb(np, cp, sym_cam_timeout(cp->cam_ccb));
-#endif
-
-	/*
 	 *  Insert first the idle task and then our job.
 	 *  The MBs should ensure proper ordering.
 	 */
@@ -1664,7 +1615,7 @@
 /*
  *  Start next ready-to-start CCBs.
  */
-void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn)
+void sym_start_next_ccbs(struct sym_hcb *np, lcb_p lp, int maxn)
 {
 	SYM_QUEHEAD *qp;
 	ccb_p cp;
@@ -1718,7 +1669,7 @@
  *  prevent out of order LOADs by the CPU from having 
  *  prefetched stale data prior to DMA having occurred.
  */
-static int sym_wakeup_done (hcb_p np)
+static int sym_wakeup_done (struct sym_hcb *np)
 {
 	ccb_p cp;
 	int i, n;
@@ -1752,10 +1703,64 @@
 }
 
 /*
+ *  Complete all CCBs queued to the COMP queue.
+ *
+ *  These CCBs are assumed:
+ *  - Not to be referenced either by devices or 
+ *    SCRIPTS-related queues and datas.
+ *  - To have to be completed with an error condition 
+ *    or requeued.
+ *
+ *  The device queue freeze count is incremented 
+ *  for each CCB that does not prevent this.
+ *  This function is called when all CCBs involved 
+ *  in error handling/recovery have been reaped.
+ */
+static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status)
+{
+	SYM_QUEHEAD *qp;
+	ccb_p cp;
+
+	while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) {
+		struct scsi_cmnd *ccb;
+		cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+		sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
+		/* Leave quiet CCBs waiting for resources */
+		if (cp->host_status == HS_WAIT)
+			continue;
+		ccb = cp->cam_ccb;
+		if (cam_status)
+			sym_set_cam_status(ccb, cam_status);
+#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+		if (sym_get_cam_status(ccb) == CAM_REQUEUE_REQ) {
+			tcb_p tp = &np->target[cp->target];
+			lcb_p lp = sym_lp(np, tp, cp->lun);
+			if (lp) {
+				sym_remque(&cp->link2_ccbq);
+				sym_insque_tail(&cp->link2_ccbq,
+				                &lp->waiting_ccbq);
+				if (cp->started) {
+					if (cp->tag != NO_TAG)
+						--lp->started_tags;
+					else
+						--lp->started_no_tag;
+				}
+			}
+			cp->started = 0;
+			continue;
+		}
+#endif
+		sym_free_ccb(np, cp);
+		sym_freeze_cam_ccb(ccb);
+		sym_xpt_done(np, ccb);
+	}
+}
+
+/*
  *  Complete all active CCBs with error.
  *  Used on CHIP/SCSI RESET.
  */
-static void sym_flush_busy_queue (hcb_p np, int cam_status)
+static void sym_flush_busy_queue (struct sym_hcb *np, int cam_status)
 {
 	/*
 	 *  Move all active CCBs to the COMP queue 
@@ -1774,7 +1779,7 @@
  *     1: SCSI BUS RESET delivered or received.
  *     2: SCSI BUS MODE changed.
  */
-void sym_start_up (hcb_p np, int reason)
+void sym_start_up (struct sym_hcb *np, int reason)
 {
  	int	i;
 	u32	phys;
@@ -1865,7 +1870,7 @@
 	/*
 	 *  For now, disable AIP generation on C1010-66.
 	 */
-	if (np->device_id == PCI_ID_LSI53C1010_66)
+	if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)
 		OUTB (nc_aipcntl1, DISAIP);
 
 	/*
@@ -1875,7 +1880,7 @@
 	 *  that from SCRIPTS for each selection/reselection, but 
 	 *  I just don't want. :)
 	 */
-	if (np->device_id == PCI_ID_LSI53C1010_33 &&
+	if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
 	    np->revision_id < 1)
 		OUTB (nc_stest1, INB(nc_stest1) | 0x30);
 
@@ -1884,9 +1889,9 @@
 	 *  Disable overlapped arbitration for some dual function devices, 
 	 *  regardless revision id (kind of post-chip-design feature. ;-))
 	 */
-	if (np->device_id == PCI_ID_SYM53C875)
+	if (np->device_id == PCI_DEVICE_ID_NCR_53C875)
 		OUTB (nc_ctest0, (1<<5));
-	else if (np->device_id == PCI_ID_SYM53C896)
+	else if (np->device_id == PCI_DEVICE_ID_NCR_53C896)
 		np->rv_ccntl0 |= DPR;
 
 	/*
@@ -2010,7 +2015,7 @@
 /*
  *  Switch trans mode for current job and it's target.
  */
-static void sym_settrans(hcb_p np, int target, u_char opts, u_char ofs,
+static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs,
 			 u_char per, u_char wide, u_char div, u_char fak)
 {
 	SYM_QUEHEAD *qp;
@@ -2119,7 +2124,7 @@
  *  We received a WDTR.
  *  Let everything be aware of the changes.
  */
-static void sym_setwide(hcb_p np, int target, u_char wide)
+static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
 {
 	tcb_p tp = &np->target[target];
 
@@ -2138,7 +2143,7 @@
  *  Let everything be aware of the changes.
  */
 static void
-sym_setsync(hcb_p np, int target,
+sym_setsync(struct sym_hcb *np, int target,
             u_char ofs, u_char per, u_char div, u_char fak)
 {
 	tcb_p tp = &np->target[target];
@@ -2164,7 +2169,7 @@
  *  Let everything be aware of the changes.
  */
 static void 
-sym_setpprot(hcb_p np, int target, u_char opts, u_char ofs,
+sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs,
              u_char per, u_char wide, u_char div, u_char fak)
 {
 	tcb_p tp = &np->target[target];
@@ -2205,7 +2210,7 @@
  *  pushes a DSA into a queue, we can trust it when it 
  *  points to a CCB.
  */
-static void sym_recover_scsi_int (hcb_p np, u_char hsts)
+static void sym_recover_scsi_int (struct sym_hcb *np, u_char hsts)
 {
 	u32	dsp	= INL (nc_dsp);
 	u32	dsa	= INL (nc_dsa);
@@ -2256,7 +2261,7 @@
 /*
  *  chip exception handler for selection timeout
  */
-static void sym_int_sto (hcb_p np)
+static void sym_int_sto (struct sym_hcb *np)
 {
 	u32 dsp	= INL (nc_dsp);
 
@@ -2271,7 +2276,7 @@
 /*
  *  chip exception handler for unexpected disconnect
  */
-static void sym_int_udc (hcb_p np)
+static void sym_int_udc (struct sym_hcb *np)
 {
 	printf ("%s: unexpected disconnect\n", sym_name(np));
 	sym_recover_scsi_int(np, HS_UNEXPECTED);
@@ -2287,7 +2292,7 @@
  *  mode to eight bit asynchronous, etc...
  *  So, just reinitializing all except chip should be enough.
  */
-static void sym_int_sbmc (hcb_p np)
+static void sym_int_sbmc (struct sym_hcb *np)
 {
 	u_char scsi_mode = INB (nc_stest4) & SMODE;
 
@@ -2328,7 +2333,7 @@
  *    The chip will load the DSP with the phase mismatch 
  *    JUMP address and interrupt the host processor.
  */
-static void sym_int_par (hcb_p np, u_short sist)
+static void sym_int_par (struct sym_hcb *np, u_short sist)
 {
 	u_char	hsts	= INB (HS_PRT);
 	u32	dsp	= INL (nc_dsp);
@@ -2416,7 +2421,7 @@
  *  We have to construct a new transfer descriptor,
  *  to transfer the rest of the current block.
  */
-static void sym_int_ma (hcb_p np)
+static void sym_int_ma (struct sym_hcb *np)
 {
 	u32	dbc;
 	u32	rest;
@@ -2826,7 +2831,7 @@
  *  Use at your own decision and risk.
  */
 
-void sym_interrupt (hcb_p np)
+void sym_interrupt (struct sym_hcb *np)
 {
 	u_char	istat, istatc;
 	u_char	dstat;
@@ -2981,7 +2986,7 @@
  *  It is called with SCRIPTS not running.
  */
 static int 
-sym_dequeue_from_squeue(hcb_p np, int i, int target, int lun, int task)
+sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task)
 {
 	int j;
 	ccb_p cp;
@@ -3025,60 +3030,6 @@
 }
 
 /*
- *  Complete all CCBs queued to the COMP queue.
- *
- *  These CCBs are assumed:
- *  - Not to be referenced either by devices or 
- *    SCRIPTS-related queues and datas.
- *  - To have to be completed with an error condition 
- *    or requeued.
- *
- *  The device queue freeze count is incremented 
- *  for each CCB that does not prevent this.
- *  This function is called when all CCBs involved 
- *  in error handling/recovery have been reaped.
- */
-void sym_flush_comp_queue(hcb_p np, int cam_status)
-{
-	SYM_QUEHEAD *qp;
-	ccb_p cp;
-
-	while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) {
-		cam_ccb_p ccb;
-		cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
-		sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
-		/* Leave quiet CCBs waiting for resources */
-		if (cp->host_status == HS_WAIT)
-			continue;
-		ccb = cp->cam_ccb;
-		if (cam_status)
-			sym_set_cam_status(ccb, cam_status);
-#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
-		if (sym_get_cam_status(ccb) == CAM_REQUEUE_REQ) {
-			tcb_p tp = &np->target[cp->target];
-			lcb_p lp = sym_lp(np, tp, cp->lun);
-			if (lp) {
-				sym_remque(&cp->link2_ccbq);
-				sym_insque_tail(&cp->link2_ccbq,
-				                &lp->waiting_ccbq);
-				if (cp->started) {
-					if (cp->tag != NO_TAG)
-						--lp->started_tags;
-					else
-						--lp->started_no_tag;
-				}
-			}
-			cp->started = 0;
-			continue;
-		}
-#endif
-		sym_free_ccb(np, cp);
-		sym_freeze_cam_ccb(ccb);
-		sym_xpt_done(np, ccb);
-	}
-}
-
-/*
  *  chip handler for bad SCSI status condition
  *
  *  In case of bad SCSI status, we unqueue all the tasks 
@@ -3096,14 +3047,13 @@
  *  SCRATCHA is assumed to have been loaded with STARTPOS 
  *  before the SCRIPTS called the C code.
  */
-static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp)
+static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, ccb_p cp)
 {
 	tcb_p tp	= &np->target[cp->target];
 	u32		startp;
 	u_char		s_status = cp->ssss_status;
 	u_char		h_flags  = cp->host_flags;
 	int		msglen;
-	int		nego;
 	int		i;
 
 	/*
@@ -3178,16 +3128,7 @@
 		 *  cp->nego_status is filled by sym_prepare_nego().
 		 */
 		cp->nego_status = 0;
-		nego = 0;
-		if	(tp->tinfo.curr.options & PPR_OPT_MASK)
-			nego = NS_PPR;
-		else if	(tp->tinfo.curr.width != BUS_8_BIT)
-			nego = NS_WIDE;
-		else if (tp->tinfo.curr.offset != 0)
-			nego = NS_SYNC;
-		if (nego)
-			msglen +=
-			sym_prepare_nego (np,cp, nego, &cp->scsi_smsg2[msglen]);
+		msglen += sym_prepare_nego(np, cp, &cp->scsi_smsg2[msglen]);
 		/*
 		 *  Message table indirect structure.
 		 */
@@ -3213,7 +3154,7 @@
 		/*
 		 *  sense data
 		 */
-		bzero(cp->sns_bbuf, SYM_SNS_BBUF_LEN);
+		memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
 		cp->phys.sense.addr	= cpu_to_scr(vtobus(cp->sns_bbuf));
 		cp->phys.sense.size	= cpu_to_scr(SYM_SNS_BBUF_LEN);
 
@@ -3263,7 +3204,7 @@
  *  - lun=-1  means any logical UNIT otherwise a given one.
  *  - task=-1 means any task, otherwise a given one.
  */
-int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task)
+int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task)
 {
 	SYM_QUEHEAD qtmp, *qp;
 	int i = 0;
@@ -3282,7 +3223,7 @@
 	 *  the BUSY queue.
 	 */
 	while ((qp = sym_remque_head(&qtmp)) != 0) {
-		cam_ccb_p ccb;
+		struct scsi_cmnd *ccb;
 		cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
 		ccb = cp->cam_ccb;
 		if (cp->host_status != HS_DISCONNECT ||
@@ -3346,7 +3287,7 @@
  *  all the CCBs that should have been aborted by the 
  *  target according to our message.
  */
-static void sym_sir_task_recovery(hcb_p np, int num)
+static void sym_sir_task_recovery(struct sym_hcb *np, int num)
 {
 	SYM_QUEHEAD *qp;
 	ccb_p cp;
@@ -3698,7 +3639,7 @@
  *  the corresponding values of dp_sg and dp_ofs.
  */
 
-static int sym_evaluate_dp(hcb_p np, ccb_p cp, u32 scr, int *ofs)
+static int sym_evaluate_dp(struct sym_hcb *np, ccb_p cp, u32 scr, int *ofs)
 {
 	u32	dp_scr;
 	int	dp_ofs, dp_sg, dp_sgmin;
@@ -3816,7 +3757,7 @@
  *  is equivalent to a MODIFY DATA POINTER (offset=-1).
  */
 
-static void sym_modify_dp(hcb_p np, tcb_p tp, ccb_p cp, int ofs)
+static void sym_modify_dp(struct sym_hcb *np, tcb_p tp, ccb_p cp, int ofs)
 {
 	int dp_ofs	= ofs;
 	u32	dp_scr	= sym_get_script_dp (np, cp);
@@ -3915,7 +3856,7 @@
  *  a relevant information. :)
  */
 
-int sym_compute_residual(hcb_p np, ccb_p cp)
+int sym_compute_residual(struct sym_hcb *np, ccb_p cp)
 {
 	int dp_sg, dp_sgmin, resid = 0;
 	int dp_ofs = 0;
@@ -4015,7 +3956,7 @@
  *  chip handler for SYNCHRONOUS DATA TRANSFER REQUEST (SDTR) message.
  */
 static int  
-sym_sync_nego_check(hcb_p np, int req, int target)
+sym_sync_nego_check(struct sym_hcb *np, int req, int target)
 {
 	u_char	chg, ofs, per, fak, div;
 
@@ -4096,7 +4037,7 @@
 	return -1;
 }
 
-static void sym_sync_nego(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_sync_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	int req = 1;
 	int result;
@@ -4133,7 +4074,7 @@
  *  chip handler for PARALLEL PROTOCOL REQUEST (PPR) message.
  */
 static int 
-sym_ppr_nego_check(hcb_p np, int req, int target)
+sym_ppr_nego_check(struct sym_hcb *np, int req, int target)
 {
 	tcb_p tp = &np->target[target];
 	unsigned char fak, div;
@@ -4176,7 +4117,7 @@
 
 	if (ofs) {
 		unsigned char minsync = dt ? np->minsync_dt : np->minsync;
-		if (per < np->minsync_dt) {
+		if (per < minsync) {
 			chg = 1;
 			per = minsync;
 		}
@@ -4242,7 +4183,7 @@
 	return -1;
 }
 
-static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_ppr_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	int req = 1;
 	int result;
@@ -4279,7 +4220,7 @@
  *  chip handler for WIDE DATA TRANSFER REQUEST (WDTR) message.
  */
 static int  
-sym_wide_nego_check(hcb_p np, int req, int target)
+sym_wide_nego_check(struct sym_hcb *np, int req, int target)
 {
 	u_char	chg, wide;
 
@@ -4344,7 +4285,7 @@
 	return -1;
 }
 
-static void sym_wide_nego(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_wide_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	int req = 1;
 	int result;
@@ -4413,7 +4354,7 @@
  *  So, if a PPR makes problems, we may just want to 
  *  try a legacy negotiation later.
  */
-static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_nego_default(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	switch (cp->nego_status) {
 	case NS_PPR:
@@ -4443,7 +4384,7 @@
  *  chip handler for MESSAGE REJECT received in response to 
  *  PPR, WIDE or SYNCHRONOUS negotiation.
  */
-static void sym_nego_rejected(hcb_p np, tcb_p tp, ccb_p cp)
+static void sym_nego_rejected(struct sym_hcb *np, tcb_p tp, ccb_p cp)
 {
 	sym_nego_default(np, tp, cp);
 	OUTB (HS_PRT, HS_BUSY);
@@ -4452,7 +4393,7 @@
 /*
  *  chip exception handler for programmed interrupts.
  */
-static void sym_int_sir (hcb_p np)
+static void sym_int_sir (struct sym_hcb *np)
 {
 	u_char	num	= INB (nc_dsps);
 	u32	dsa	= INL (nc_dsa);
@@ -4726,7 +4667,7 @@
 /*
  *  Acquire a control block
  */
-ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order)
+ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order)
 {
 	tcb_p tp = &np->target[tn];
 	lcb_p lp = sym_lp(np, tp, ln);
@@ -4875,7 +4816,7 @@
 /*
  *  Release one control block
  */
-void sym_free_ccb (hcb_p np, ccb_p cp)
+void sym_free_ccb (struct sym_hcb *np, ccb_p cp)
 {
 	tcb_p tp = &np->target[cp->target];
 	lcb_p lp = sym_lp(np, tp, cp->lun);
@@ -4960,13 +4901,6 @@
 	sym_remque(&cp->link_ccbq);
 	sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
 
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	/*
-	 *  Cancel any pending timeout condition.
-	 */
-	sym_untimeout_ccb(np, cp);
-#endif
-
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	if (lp) {
 		sym_remque(&cp->link2_ccbq);
@@ -4985,7 +4919,7 @@
 /*
  *  Allocate a CCB from memory and initialize its fixed part.
  */
-static ccb_p sym_alloc_ccb(hcb_p np)
+static ccb_p sym_alloc_ccb(struct sym_hcb *np)
 {
 	ccb_p cp = NULL;
 	int hcode;
@@ -5053,9 +4987,6 @@
 	/*
 	 *  Chain into optionnal lists.
 	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq);
-#endif
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	sym_insque_head(&cp->link2_ccbq, &np->dummy_ccbq);
 #endif
@@ -5072,7 +5003,7 @@
 /*
  *  Look up a CCB from a DSA value.
  */
-static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa)
+static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa)
 {
 	int hcode;
 	ccb_p cp;
@@ -5092,7 +5023,7 @@
  *  Target control block initialisation.
  *  Nothing important to do at the moment.
  */
-static void sym_init_tcb (hcb_p np, u_char tn)
+static void sym_init_tcb (struct sym_hcb *np, u_char tn)
 {
 #if 0	/*  Hmmm... this checking looks paranoid. */
 	/*
@@ -5108,7 +5039,7 @@
 /*
  *  Lun control block allocation and initialization.
  */
-lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln)
+lcb_p sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
 {
 	tcb_p tp = &np->target[tn];
 	lcb_p lp = sym_lp(np, tp, ln);
@@ -5210,7 +5141,7 @@
 /*
  *  Allocate LCB resources for tagged command queuing.
  */
-static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln)
+static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
 {
 	tcb_p tp = &np->target[tn];
 	lcb_p lp = sym_lp(np, tp, ln);
@@ -5262,7 +5193,7 @@
 /*
  *  Queue a SCSI IO to the controller.
  */
-int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp)
+int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp)
 {
 	tcb_p	tp;
 	lcb_p	lp;
@@ -5273,7 +5204,7 @@
 	/*
 	 *  Keep track of the IO in our CCB.
 	 */
-	cp->cam_ccb = (cam_ccb_p) csio;
+	cp->cam_ccb = csio;
 
 	/*
 	 *  Retrieve the target descriptor.
@@ -5351,7 +5282,7 @@
 	    tp->tinfo.curr.offset  != tp->tinfo.goal.offset ||
 	    tp->tinfo.curr.options != tp->tinfo.goal.options) {
 		if (!tp->nego_cp && lp)
-			msglen += sym_prepare_nego(np, cp, 0, msgptr + msglen);
+			msglen += sym_prepare_nego(np, cp, msgptr + msglen);
 	}
 
 	/*
@@ -5401,7 +5332,7 @@
 /*
  *  Reset a SCSI target (all LUNs of this target).
  */
-int sym_reset_scsi_target(hcb_p np, int target)
+int sym_reset_scsi_target(struct sym_hcb *np, int target)
 {
 	tcb_p tp;
 
@@ -5420,7 +5351,7 @@
 /*
  *  Abort a SCSI IO.
  */
-int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out)
+int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out)
 {
 	/*
 	 *  Check that the IO is active.
@@ -5450,7 +5381,7 @@
 	return 0;
 }
 
-int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out)
+int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out)
 {
 	ccb_p cp;
 	SYM_QUEHEAD *qp;
@@ -5480,7 +5411,7 @@
  *  SCRATCHA is assumed to have been loaded with STARTPOS 
  *  before the SCRIPTS called the C code.
  */
-void sym_complete_error (hcb_p np, ccb_p cp)
+void sym_complete_error (struct sym_hcb *np, ccb_p cp)
 {
 	tcb_p tp;
 	lcb_p lp;
@@ -5614,11 +5545,11 @@
  *  The SCRIPTS processor is running while we are 
  *  completing successful commands.
  */
-void sym_complete_ok (hcb_p np, ccb_p cp)
+void sym_complete_ok (struct sym_hcb *np, ccb_p cp)
 {
 	tcb_p tp;
 	lcb_p lp;
-	cam_ccb_p ccb;
+	struct scsi_cmnd *ccb;
 	int resid;
 
 	/*
@@ -5724,7 +5655,7 @@
 /*
  *  Soft-attach the controller.
  */
-int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram)
+int sym_hcb_attach(struct sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram)
 {
 	int i;
 
@@ -5815,17 +5746,9 @@
 	sym_que_init(&np->comp_ccbq);
 
 	/*
-	 *  Initializations for optional handling 
-	 *  of IO timeouts and device queueing.
+	 *  Initialization for optional handling 
+	 *  of device queueing.
 	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	sym_que_init(&np->tmo0_ccbq);
-	np->tmo_ccbq =
-		sym_calloc(2*SYM_CONF_TIMEOUT_ORDER_MAX*sizeof(SYM_QUEHEAD),
-			   "TMO_CCBQ");
-	for (i = 0 ; i < 2*SYM_CONF_TIMEOUT_ORDER_MAX ; i++)
-		sym_que_init(&np->tmo_ccbq[i]);
-#endif
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	sym_que_init(&np->dummy_ccbq);
 #endif
@@ -5957,7 +5880,7 @@
 /*
  *  Free everything that has been allocated for this device.
  */
-void sym_hcb_free(hcb_p np)
+void sym_hcb_free(struct sym_hcb *np)
 {
 	SYM_QUEHEAD *qp;
 	ccb_p cp;
@@ -5971,12 +5894,6 @@
 		sym_mfree_dma(np->scriptb0, np->scriptb_sz, "SCRIPTB0");
 	if (np->scripta0)
 		sym_mfree_dma(np->scripta0, np->scripta_sz, "SCRIPTA0");
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	if (np->tmo_ccbq)
-		sym_mfree(np->tmo_ccbq,
-			  2*SYM_CONF_TIMEOUT_ORDER_MAX*sizeof(SYM_QUEHEAD),
-			  "TMO_CCBQ");
-#endif
 	if (np->squeue)
 		sym_mfree_dma(np->squeue, sizeof(u32)*(MAX_QUEUE*2), "SQUEUE");
 	if (np->dqueue)
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h	2005-01-19 13:44:46 -08:00
@@ -749,7 +749,7 @@
 	/*
 	 *  Pointer to CAM ccb and related stuff.
 	 */
-	cam_ccb_p cam_ccb;	/* CAM scsiio ccb		*/
+	struct scsi_cmnd *cam_ccb;	/* CAM scsiio ccb		*/
 	u8	cdb_buf[16];	/* Copy of CDB			*/
 	u8	*sns_bbuf;	/* Bounce buffer for sense data	*/
 #ifndef	SYM_SNS_BBUF_LEN
@@ -796,10 +796,6 @@
 	/*
 	 *  Other fields.
 	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	SYM_QUEHEAD tmo_linkq;	/* Optional timeout handling	*/
-	u_int	tmo_clock;	/* (link and dealine value)	*/
-#endif
 	u32	ccb_ba;		/* BUS address of this CCB	*/
 	u_short	tag;		/* Tag for this transfer	*/
 				/*  NO_TAG means no tag		*/
@@ -946,8 +942,8 @@
 	struct sym_fwa_ba fwa_bas;	/* Useful SCRIPTA bus addresses	*/
 	struct sym_fwb_ba fwb_bas;	/* Useful SCRIPTB bus addresses	*/
 	struct sym_fwz_ba fwz_bas;	/* Useful SCRIPTZ bus addresses	*/
-	void		(*fw_setup)(hcb_p np, struct sym_fw *fw);
-	void		(*fw_patch)(hcb_p np);
+	void		(*fw_setup)(struct sym_hcb *np, struct sym_fw *fw);
+	void		(*fw_patch)(struct sym_hcb *np);
 	char		*fw_name;
 
 	/*
@@ -1025,15 +1021,6 @@
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	SYM_QUEHEAD	dummy_ccbq;
 #endif
-	/*
-	 *  Optional handling of IO timeouts.
-	 */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-	SYM_QUEHEAD tmo0_ccbq;
-	SYM_QUEHEAD *tmo_ccbq;	/* [2*SYM_TIMEOUT_ORDER_MAX] */
-	u_int	tmo_clock;
-	u_int	tmo_actq;
-#endif
 
 	/*
 	 *  IMMEDIATE ARBITRATION (IARB) control.
@@ -1082,54 +1069,39 @@
  *  FIRMWARES (sym_fw.c)
  */
 struct sym_fw * sym_find_firmware(struct sym_pci_chip *chip);
-void sym_fw_bind_script (hcb_p np, u32 *start, int len);
+void sym_fw_bind_script (struct sym_hcb *np, u32 *start, int len);
 
 /*
  *  Driver methods called from O/S specific code.
  */
 char *sym_driver_name(void);
 void sym_print_xerr(ccb_p cp, int x_status);
-int sym_reset_scsi_bus(hcb_p np, int enab_int);
+int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
 struct sym_pci_chip *
 sym_lookup_pci_chip_table (u_short device_id, u_char revision);
-void sym_put_start_queue(hcb_p np, ccb_p cp);
+void sym_put_start_queue(struct sym_hcb *np, ccb_p cp);
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
-void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn);
+void sym_start_next_ccbs(struct sym_hcb *np, lcb_p lp, int maxn);
 #endif
-void sym_start_up (hcb_p np, int reason);
-void sym_interrupt (hcb_p np);
-void sym_flush_comp_queue(hcb_p np, int cam_status);
-int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task);
-ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order);
-void sym_free_ccb (hcb_p np, ccb_p cp);
-lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln);
-int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp);
-int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out);
-int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out);
-int sym_reset_scsi_target(hcb_p np, int target);
-void sym_hcb_free(hcb_p np);
-int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram);
-
-/*
- *  Optionnaly, the driver may handle IO timeouts.
- */
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out);
-void sym_timeout_ccb(hcb_p np, ccb_p cp, u_int ticks);
-static void __inline sym_untimeout_ccb(hcb_p np, ccb_p cp)
-{
-	sym_remque(&cp->tmo_linkq);
-	sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq);
-}
-void sym_clock(hcb_p np);
-#endif	/* SYM_OPT_HANDLE_IO_TIMEOUT */
+void sym_start_up (struct sym_hcb *np, int reason);
+void sym_interrupt (struct sym_hcb *np);
+int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task);
+ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order);
+void sym_free_ccb (struct sym_hcb *np, ccb_p cp);
+lcb_p sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln);
+int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp);
+int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out);
+int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out);
+int sym_reset_scsi_target(struct sym_hcb *np, int target);
+void sym_hcb_free(struct sym_hcb *np);
+int sym_hcb_attach(struct sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram);
 
 /*
  *  Optionnaly, the driver may provide a function
  *  to announce transfer rate changes.
  */
 #ifdef	SYM_OPT_ANNOUNCE_TRANSFER_RATE
-void sym_announce_transfer_rate(hcb_p np, int target);
+void sym_announce_transfer_rate(struct sym_hcb *np, int target);
 #endif
 
 /*
@@ -1153,9 +1125,9 @@
 	(data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len);	\
 } while (0)
 #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
-int sym_lookup_dmap(hcb_p np, u32 h, int s);
+int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s);
 static __inline void 
-sym_build_sge(hcb_p np, struct sym_tblmove *data, u64 badd, int len)
+sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len)
 {
 	u32 h = (badd>>32);
 	int s = (h&SYM_DMAP_MASK);
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c
--- a/drivers/scsi/sym53c8xx_2/sym_malloc.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c	2005-01-19 13:44:47 -08:00
@@ -170,7 +170,7 @@
 	}
 
 	if (p)
-		bzero(p, size);
+		memset(p, 0, size);
 	else if (uflags & SYM_MEM_WARN)
 		printf ("__sym_calloc2: failed to allocate %s[%d]\n", name, size);
 	return p;
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_misc.c b/drivers/scsi/sym53c8xx_2/sym_misc.c
--- a/drivers/scsi/sym53c8xx_2/sym_misc.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_misc.c	2005-01-19 13:44:47 -08:00
@@ -37,109 +37,13 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifdef __FreeBSD__
-#include <dev/sym/sym_glue.h>
-#else
 #include "sym_glue.h"
-#endif
-
-#ifdef	SYM_OPT_HANDLE_IO_TIMEOUT
-/*
- *  Optional CCB timeout handling.
- *
- *  This code is useful for O/Ses that allow or expect 
- *  SIMs (low-level drivers) to handle SCSI IO timeouts.
- *  It uses a power-of-two based algorithm of my own:) 
- *  that avoids scanning of lists, provided that:
- *
- *  - The IO does complete in less than half the associated
- *    timeout value.
- *  - The greatest delay between the queuing of the IO and 
- *    its completion is less than 
- *          (1<<(SYM_CONF_TIMEOUT_ORDER_MAX-1))/2 ticks.
- *
- *  For example, if tick is 1 second and the max order is 8,
- *  any IO that is completed within less than 64 seconds will 
- *  just be put into some list at queuing and be removed 
- *  at completion without any additionnal overhead.
- */
-
-/*
- *  Set a timeout condition on a CCB.
- */ 
-void sym_timeout_ccb(hcb_p np, ccb_p cp, u_int ticks)
-{
-	sym_remque(&cp->tmo_linkq);
-	cp->tmo_clock = np->tmo_clock + ticks;
-	if (!ticks) {
-		sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq);
-	}
-	else {
-		int i = SYM_CONF_TIMEOUT_ORDER_MAX - 1;
-		while (i > 0) {
-			if (ticks >= (1<<(i+1)))
-				break;
-			--i;
-		}
-		if (!(np->tmo_actq & (1<<i)))
-			i += SYM_CONF_TIMEOUT_ORDER_MAX;
-		sym_insque_head(&cp->tmo_linkq, &np->tmo_ccbq[i]);
-	}
-}
-
-/*
- *  Walk a list of CCB and handle timeout conditions.
- *  Should never be called in normal situations.
- */
-static void sym_walk_ccb_tmo_list(hcb_p np, SYM_QUEHEAD *tmoq)
-{
-	SYM_QUEHEAD qtmp, *qp;
-	ccb_p cp;
-
-	sym_que_move(tmoq, &qtmp);
-	while ((qp = sym_remque_head(&qtmp)) != 0) {
-		sym_insque_head(qp, &np->tmo0_ccbq);
-		cp = sym_que_entry(qp, struct sym_ccb, tmo_linkq);
-		if (cp->tmo_clock     != np->tmo_clock &&
-		    cp->tmo_clock + 1 != np->tmo_clock)
-			sym_timeout_ccb(np, cp, cp->tmo_clock - np->tmo_clock);
-		else
-			sym_abort_ccb(np, cp, 1);
-	}
-}
-
-/*
- * Our clock handler called from the O/S specific side.
- */
-void sym_clock(hcb_p np)
-{
-	int i, j;
-	u_int tmp;
-
-	tmp = np->tmo_clock;
-	tmp ^= (++np->tmo_clock);
-
-	for (i = 0; i < SYM_CONF_TIMEOUT_ORDER_MAX; i++, tmp >>= 1) {
-		if (!(tmp & 1))
-			continue;
-		j = i;
-		if (np->tmo_actq & (1<<i))
-			j += SYM_CONF_TIMEOUT_ORDER_MAX;
-
-		if (!sym_que_empty(&np->tmo_ccbq[j])) {
-			sym_walk_ccb_tmo_list(np, &np->tmo_ccbq[j]);
-		}
-		np->tmo_actq ^= (1<<i);
-	}
-}
-#endif	/* SYM_OPT_HANDLE_IO_TIMEOUT */
-
 
 #ifdef	SYM_OPT_ANNOUNCE_TRANSFER_RATE
 /*
  *  Announce transfer rate if anything changed since last announcement.
  */
-void sym_announce_transfer_rate(hcb_p np, int target)
+void sym_announce_transfer_rate(struct sym_hcb *np, int target)
 {
 	tcb_p tp = &np->target[target];
 
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_nvram.c b/drivers/scsi/sym53c8xx_2/sym_nvram.c
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.c	2005-01-19 13:44:47 -08:00
@@ -68,6 +68,21 @@
 	case SYM_TEKRAM_NVRAM:
 		np->myaddr = nvram->data.Tekram.host_id & 0x0f;
 		break;
+#ifdef CONFIG_PARISC
+	case SYM_PARISC_PDC:
+		if (nvram->data.parisc.host_id != -1)
+			np->myaddr = nvram->data.parisc.host_id;
+		if (nvram->data.parisc.factor != -1)
+			np->minsync = nvram->data.parisc.factor;
+		if (nvram->data.parisc.width != -1)
+			np->maxwide = nvram->data.parisc.width;
+		switch (nvram->data.parisc.mode) {
+			case 0: np->scsi_mode = SMODE_SE; break;
+			case 1: np->scsi_mode = SMODE_HVD; break;
+			case 2: np->scsi_mode = SMODE_LVD; break;
+			default: break;
+		}
+#endif
 	default:
 		break;
 	}
@@ -702,6 +717,28 @@
 	return 0;
 }
 
+#ifdef CONFIG_PARISC
+/*
+ * Host firmware (PDC) keeps a table for altering SCSI capabilities.
+ * Many newer machines export one channel of 53c896 chip as SE, 50-pin HD.
+ * Also used for Multi-initiator SCSI clusters to set the SCSI Initiator ID.
+ */
+static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *pdc)
+{
+	struct hardware_path hwpath;
+	get_pci_node_path(np->pdev, &hwpath);
+	if (!pdc_get_initiator(&hwpath, pdc))
+		return 0;
+
+	return SYM_PARISC_PDC;
+}
+#else
+static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *x)
+{
+	return 0;
+}
+#endif
+
 /*
  *  Try reading Symbios or Tekram NVRAM
  */
@@ -714,7 +751,7 @@
 		nvp->type = SYM_TEKRAM_NVRAM;
 		sym_display_Tekram_nvram(np, &nvp->data.Tekram);
 	} else {
-		nvp->type = 0;
+		nvp->type = sym_read_parisc_pdc(np, &nvp->data.parisc);
 	}
 	return nvp->type;
 }
diff -Nru a/drivers/scsi/sym53c8xx_2/sym_nvram.h b/drivers/scsi/sym53c8xx_2/sym_nvram.h
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.h	2005-01-19 13:44:47 -08:00
@@ -171,6 +171,10 @@
 typedef struct Tekram_nvram	Tekram_nvram;
 typedef struct Tekram_target	Tekram_target;
 
+#ifndef CONFIG_PARISC
+struct pdc_initiator { int dummy; };
+#endif
+
 /*
  *  Union of supported NVRAM formats.
  */
@@ -178,10 +182,12 @@
 	int type;
 #define	SYM_SYMBIOS_NVRAM	(1)
 #define	SYM_TEKRAM_NVRAM	(2)
+#define SYM_PARISC_PDC		(3)
 #if SYM_CONF_NVRAM_SUPPORT
 	union {
 		Symbios_nvram Symbios;
 		Tekram_nvram Tekram;
+		struct pdc_initiator parisc;
 	} data;
 #endif
 };
diff -Nru a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h
--- a/drivers/scsi/sym53c8xx_comm.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/sym53c8xx_comm.h	2005-01-19 13:44:47 -08:00
@@ -505,8 +505,6 @@
 #define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->dev, cmd)
 #define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->dev, cmd)
 #define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->dev, cmd)
-#define sync_scsi_data_for_cpu(np, cmd)	__sync_scsi_data_for_cpu(np->dev, cmd)
-#define sync_scsi_data_for_device(np, cmd) __sync_scsi_data_for_device(np->dev, cmd)
 
 /*==========================================================
 **
diff -Nru a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
--- a/drivers/scsi/zalon.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/scsi/zalon.c	2005-01-19 13:44:47 -08:00
@@ -87,7 +87,7 @@
 {
 	struct gsc_irq gsc_irq;
 	u32 zalon_vers;
-	int irq, error = -ENODEV;
+	int error = -ENODEV;
 	unsigned long zalon = dev->hpa;
 	unsigned long io_port = zalon + GSC_SCSI_ZALON_OFFSET;
 	static int unit = 0;
@@ -107,10 +107,10 @@
 	/* Setup the interrupts first.
 	** Later on request_irq() will register the handler.
 	*/
-	irq = gsc_alloc_irq(&gsc_irq);
+	dev->irq = gsc_alloc_irq(&gsc_irq);
 
 	printk("%s: Zalon vers field is 0x%x, IRQ %d\n", __FUNCTION__,
-		zalon_vers, irq);
+		zalon_vers, dev->irq);
 
 	__raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, dev->hpa + IO_MODULE_EIM);
 
@@ -130,16 +130,16 @@
 	device.dev		= &dev->dev;
 	device.slot.base	= (u_long)io_port;
 	device.slot.base_c	= (u_long)io_port;
-	device.slot.irq		= irq;
+	device.slot.irq		= dev->irq;
 	device.differential	= 2;
 
 	host = ncr_attach(&zalon7xx_template, unit, &device);
 	if (!host)
 		goto fail;
 
-	if (request_irq(irq, ncr53c8xx_intr, SA_SHIRQ, dev->dev.bus_id, host)) {
+	if (request_irq(dev->irq, ncr53c8xx_intr, SA_SHIRQ, "zalon", host)) {
 		printk(KERN_ERR "%s: irq problem with %d, detaching\n ",
-			dev->dev.bus_id, irq);
+			dev->dev.bus_id, dev->irq);
 		goto fail;
 	}
 
@@ -155,7 +155,7 @@
 	return 0;
 
  fail_free_irq:
-	free_irq(irq, host);
+	free_irq(dev->irq, host);
  fail:
 	ncr53c8xx_release(host);
 	return error;
@@ -171,18 +171,16 @@
 static int __exit zalon_remove(struct parisc_device *dev)
 {
 	struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
-	int irq = host->irq;
 
 	scsi_remove_host(host);
 	ncr53c8xx_release(host);
-	free_irq(irq, host);
+	free_irq(dev->irq, host);
 
 	return 0;
 }
-	
 
 static struct parisc_driver zalon_driver = {
-	.name =		"GSC SCSI (Zalon)",
+	.name =		"zalon",
 	.id_table =	zalon_tbl,
 	.probe =	zalon_probe,
 	.remove =	__devexit_p(zalon_remove),
@@ -201,6 +199,7 @@
 static void __exit zalon7xx_exit(void)
 {
 	unregister_parisc_driver(&zalon_driver);
+	ncr53c8xx_exit();
 }
 
 module_init(zalon7xx_init);
diff -Nru a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
--- a/drivers/serial/8250_gsc.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/serial/8250_gsc.c	2005-01-19 13:44:47 -08:00
@@ -40,7 +40,7 @@
 		 * what we have here is a missing parent device, so tell
 		 * the user what they're missing.
 		 */
-		if (dev->parent->id.hw_type != HPHW_IOA) {
+		if (parisc_parent(dev)->id.hw_type != HPHW_IOA) {
 			printk(KERN_INFO "Serial: device 0x%lx not configured.\n"
 				"Enable support for Wax, Lasi, Asp or Dino.\n", dev->hpa);
 		}
@@ -65,7 +65,7 @@
 		printk(KERN_WARNING "serial8250_register_port returned error %d\n", err);
 		return err;
 	}
-
+        
 	return 0;
 }
 
@@ -99,13 +99,13 @@
 MODULE_DEVICE_TABLE(parisc, serial_tbl);
 
 static struct parisc_driver lasi_driver = {
-	.name		= "Lasi RS232",
+	.name		= "serial_1",
 	.id_table	= lasi_tbl,
 	.probe		= serial_init_chip,
 };
 
 static struct parisc_driver serial_driver = {
-	.name		= "Serial RS232",
+	.name		= "serial",
 	.id_table	= serial_tbl,
 	.probe		= serial_init_chip,
 };
diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig
--- a/drivers/serial/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/serial/Kconfig	2005-01-19 13:44:47 -08:00
@@ -321,7 +321,7 @@
 	select SERIAL_CORE
 	help
 	  Say Y here if you want to use the hard logic uart on Excalibur. This
-	  driver also supports soft logic implentations of this uart core.
+	  driver also supports soft logic implementations of this uart core.
 
 config SERIAL_UART00_CONSOLE
 	bool "Support for console on Excalibur serial port"
@@ -338,6 +338,20 @@
 	  your boot loader (lilo or loadlin) about how to pass options to the
 	  kernel at boot time.)
 
+config SERIAL_MPSC
+	bool "Marvell MPSC serial port support"
+	depends on PPC32 && MV64X60
+	select SERIAL_CORE
+	help
+	  Say Y here if you want to use the Marvell MPSC serial controller.
+
+config SERIAL_MPSC_CONSOLE
+	bool "Support for console on Marvell MPSC serial port"
+	depends on SERIAL_MPSC
+	select SERIAL_CORE_CONSOLE
+	help
+	  Say Y here if you want to support a serial console on a Marvell MPSC.
+
 config SERIAL_PXA
 	bool "PXA serial port support"
 	depends on ARM && ARCH_PXA
@@ -515,7 +529,6 @@
 	bool "Console on IP22 Zilog8530 serial port"
 	depends on SERIAL_IP22_ZILOG=y
 	select SERIAL_CORE_CONSOLE
-	help
 
 config V850E_UART
 	bool "NEC V850E on-chip UART support"
@@ -627,7 +640,7 @@
 	  Sharp LH7A40X series CPUs.  Choose Y or M.
 
 config SERIAL_LH7A40X_CONSOLE
-	bool "Support for connsole on Sharp LH7A40X serial port"
+	bool "Support for console on Sharp LH7A40X serial port"
 	depends on SERIAL_LH7A40X=y
 	select SERIAL_CORE_CONSOLE
 	help
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile	2005-01-19 13:44:46 -08:00
+++ b/drivers/serial/Makefile	2005-01-19 13:44:46 -08:00
@@ -46,4 +46,5 @@
 obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o
 obj-$(CONFIG_SERIAL_ICOM) += icom.o
 obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o
-obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
\ No newline at end of file
+obj-$(CONFIG_SERIAL_MPSC) += mpsc.o
+obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
diff -Nru a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/serial/mpsc.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,1674 @@
+/*
+ * drivers/serial/mpsc.c
+ *
+ * Generic driver for the MPSC (UART mode) on Marvell parts (e.g., GT64240,
+ * GT64260, MV64340, MV64360, GT96100, ... ).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * Based on an old MPSC driver that was in the linuxppc tree.  It appears to
+ * have been created by Chris Zankel (formerly of MontaVista) but there
+ * is no proper Copyright so I'm not sure.  Apparently, parts were also
+ * taken from PPCBoot (now U-Boot).  Also based on drivers/serial/8250.c
+ * by Russell King.
+ *
+ * 2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+/*
+ * The MPSC interface is much like a typical network controller's interface.
+ * That is, you set up separate rings of descriptors for transmitting and
+ * receiving data.  There is also a pool of buffers with (one buffer per
+ * descriptor) that incoming data are dma'd into or outgoing data are dma'd
+ * out of.
+ *
+ * The MPSC requires two other controllers to be able to work.  The Baud Rate
+ * Generator (BRG) provides a clock at programmable frequencies which determines
+ * the baud rate.  The Serial DMA Controller (SDMA) takes incoming data from the
+ * MPSC and DMA's it into memory or DMA's outgoing data and passes it to the
+ * MPSC.  It is actually the SDMA interrupt that the driver uses to keep the
+ * transmit and receive "engines" going (i.e., indicate data has been
+ * transmitted or received).
+ *
+ * NOTES:
+ *
+ * 1) Some chips have an erratum where several regs cannot be
+ * read.  To work around that, we keep a local copy of those regs in
+ * 'mpsc_port_info' and use the *_M or *_S macros when accessing those regs.
+ *
+ * 2) Some chips have an erratum where the ctlr will hang when the SDMA ctlr
+ * accesses system mem in a cache coherent region.  This *should* be a
+ * show-stopper when coherency is turned on but it seems to work okay as
+ * long as there are no snoop hits.  Therefore, the ring buffer entries and
+ * the buffers themselves are allocated via 'dma_alloc_noncoherent()' and
+ * 'dma_cache_sync()' is used.  Also, since most PPC platforms are coherent
+ * which makes 'dma_cache_sync()' a no-op, explicit cache management macros
+ * have been added ensuring there are no snoop hits when coherency is on.
+ *
+ * 3) There is an erratum (on PPC) where you can't use the instruction to do
+ * a DMA_TO_DEVICE/cache clean so DMA_BIDIRECTIONAL/flushes are used in places
+ * where a DMA_TO_DEVICE/clean would have [otherwise] sufficed.
+ *
+ * 4) AFAICT, hardware flow control isn't supported by the controller --MAG.
+ */
+
+#include <linux/mv64xxx.h>
+#include "mpsc.h"
+
+/*
+ * Define how this driver is known to the outside (we've been assigned a
+ * range on the "Low-density serial ports" major).
+ */
+#define MPSC_MAJOR		204
+#define MPSC_MINOR_START	44
+#define	MPSC_DRIVER_NAME	"MPSC"
+#define	MPSC_DEVFS_NAME		"ttymm/"
+#define	MPSC_DEV_NAME		"ttyMM"
+#define	MPSC_VERSION		"1.00"
+
+static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS];
+static struct mpsc_shared_regs mpsc_shared_regs;
+
+/*
+ ******************************************************************************
+ *
+ * Baud Rate Generator Routines (BRG)
+ *
+ ******************************************************************************
+ */
+static void
+mpsc_brg_init(struct mpsc_port_info *pi, u32 clk_src)
+{
+	if (pi->brg_can_tune)
+		MPSC_MOD_FIELD_M(pi, brg, BRG_BCR, 1, 25, 0);
+
+	MPSC_MOD_FIELD_M(pi, brg, BRG_BCR, 4, 18, clk_src);
+	MPSC_MOD_FIELD(pi, brg, BRG_BTR, 16, 0, 0);
+	return;
+}
+
+static void
+mpsc_brg_enable(struct mpsc_port_info *pi)
+{
+	MPSC_MOD_FIELD_M(pi, brg, BRG_BCR, 1, 16, 1);
+	return;
+}
+
+static void
+mpsc_brg_disable(struct mpsc_port_info *pi)
+{
+	MPSC_MOD_FIELD_M(pi, brg, BRG_BCR, 1, 16, 0);
+	return;
+}
+
+static inline void
+mpsc_set_baudrate(struct mpsc_port_info *pi, u32 baud)
+{
+	/*
+	 * To set the baud, we adjust the CDV field in the BRG_BCR reg.
+	 * From manual: Baud = clk / ((CDV+1)*2) ==> CDV = (clk / (baud*2)) - 1.
+	 * However, the input clock is divided by 16 in the MPSC b/c of how
+	 * 'MPSC_MMCRH' was set up so we have to divide the 'clk' used in our
+	 * calculation by 16 to account for that.  So the real calculation
+	 * that accounts for the way the mpsc is set up is:
+	 * CDV = (clk / (baud*2*16)) - 1 ==> CDV = (clk / (baud << 5)) - 1.
+	 */
+	u32 cdv = (pi->port.uartclk / (baud << 5)) - 1;
+
+	mpsc_brg_disable(pi);
+	MPSC_MOD_FIELD_M(pi, brg, BRG_BCR, 16, 0, cdv);
+	mpsc_brg_enable(pi);
+
+	return;
+}
+
+/*
+ ******************************************************************************
+ *
+ * Serial DMA Routines (SDMA)
+ *
+ ******************************************************************************
+ */
+
+static void
+mpsc_sdma_burstsize(struct mpsc_port_info *pi, u32 burst_size)
+{
+	u32 v;
+
+	pr_debug("mpsc_sdma_burstsize[%d]: burst_size: %d\n",
+	    pi->port.line, burst_size);
+
+	burst_size >>= 3; /* Divide by 8 b/c reg values are 8-byte chunks */
+
+	if (burst_size < 2)
+		v = 0x0;	/* 1 64-bit word */
+	else if (burst_size < 4)
+		v = 0x1;	/* 2 64-bit words */
+	else if (burst_size < 8)
+		v = 0x2;	/* 4 64-bit words */
+	else
+		v = 0x3;	/* 8 64-bit words */
+
+	MPSC_MOD_FIELD(pi, sdma, SDMA_SDC, 2, 12, v);
+	return;
+}
+
+static void
+mpsc_sdma_init(struct mpsc_port_info *pi, u32 burst_size)
+{
+	pr_debug("mpsc_sdma_init[%d]: burst_size: %d\n", pi->port.line,
+		burst_size);
+
+	MPSC_MOD_FIELD(pi, sdma, SDMA_SDC, 10, 0, 0x03f);
+	mpsc_sdma_burstsize(pi, burst_size);
+	return;
+}
+
+static inline u32
+mpsc_sdma_intr_mask(struct mpsc_port_info *pi, u32 mask)
+{
+	u32 old, v;
+
+	pr_debug("mpsc_sdma_intr_mask[%d]: mask: 0x%x\n", pi->port.line, mask);
+
+	old = v = MPSC_READ_S(pi, sdma_intr, SDMA_INTR_MASK);
+	mask &= 0xf;
+	if (pi->port.line)
+		mask <<= 8;
+	v &= ~mask;
+	MPSC_WRITE_S(pi, sdma_intr, SDMA_INTR_MASK, v);
+
+	if (pi->port.line)
+		old >>= 8;
+	return old & 0xf;
+}
+
+static inline void
+mpsc_sdma_intr_unmask(struct mpsc_port_info *pi, u32 mask)
+{
+	u32 v;
+
+	pr_debug("mpsc_sdma_intr_unmask[%d]: mask: 0x%x\n", pi->port.line,mask);
+
+	v = MPSC_READ_S(pi, sdma_intr, SDMA_INTR_MASK);
+	mask &= 0xf;
+	if (pi->port.line)
+		mask <<= 8;
+	v |= mask;
+	MPSC_WRITE_S(pi, sdma_intr, SDMA_INTR_MASK, v);
+	return;
+}
+
+static inline void
+mpsc_sdma_intr_ack(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_sdma_intr_ack[%d]: Acknowledging IRQ\n", pi->port.line);
+	MPSC_WRITE_S(pi, sdma_intr, SDMA_INTR_CAUSE, 0);
+	return;
+}
+
+static inline void
+mpsc_sdma_set_rx_ring(struct mpsc_port_info *pi, struct mpsc_rx_desc *rxre_p)
+{
+	pr_debug("mpsc_sdma_set_rx_ring[%d]: rxre_p: 0x%x\n",
+		pi->port.line, (u32) rxre_p);
+
+	MPSC_WRITE(pi, sdma, SDMA_SCRDP, (u32) rxre_p);
+	return;
+}
+
+static inline void
+mpsc_sdma_set_tx_ring(struct mpsc_port_info *pi, struct mpsc_tx_desc *txre_p)
+{
+	MPSC_WRITE(pi, sdma, SDMA_SFTDP, (u32) txre_p);
+	MPSC_WRITE(pi, sdma, SDMA_SCTDP, (u32) txre_p);
+	return;
+}
+
+static inline void
+mpsc_sdma_cmd(struct mpsc_port_info *pi, u32 val)
+{
+	u32 v;
+
+	v = MPSC_READ(pi, sdma, SDMA_SDCM);
+	if (val)
+		v |= val;
+	else
+		v = 0;
+	wmb();
+	MPSC_WRITE(pi, sdma, SDMA_SDCM, v);
+	wmb();
+	return;
+}
+
+static inline uint
+mpsc_sdma_tx_active(struct mpsc_port_info *pi)
+{
+	return MPSC_READ(pi, sdma, SDMA_SDCM) & SDMA_SDCM_TXD;
+}
+
+static inline void
+mpsc_sdma_start_tx(struct mpsc_port_info *pi)
+{
+	struct mpsc_tx_desc *txre, *txre_p;
+
+	/* If tx isn't running & there's a desc ready to go, start it */
+	if (!mpsc_sdma_tx_active(pi)) {
+		txre = (struct mpsc_tx_desc *)(pi->txr +
+			(pi->txr_tail * MPSC_TXRE_SIZE));
+		dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
+		MPSC_CACHE_INVALIDATE(pi, (u32)txre, (u32)txre+MPSC_TXRE_SIZE);
+
+		if (be32_to_cpu(txre->cmdstat) & SDMA_DESC_CMDSTAT_O) {
+			txre_p = (struct mpsc_tx_desc *)(pi->txr_p +
+							 (pi->txr_tail *
+							  MPSC_TXRE_SIZE));
+
+			mpsc_sdma_set_tx_ring(pi, txre_p);
+			mpsc_sdma_cmd(pi, SDMA_SDCM_STD | SDMA_SDCM_TXD);
+		}
+	}
+
+	return;
+}
+
+static inline void
+mpsc_sdma_stop(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_sdma_stop[%d]: Stopping SDMA\n", pi->port.line);
+
+	/* Abort any SDMA transfers */
+	mpsc_sdma_cmd(pi, 0);
+	mpsc_sdma_cmd(pi, SDMA_SDCM_AR | SDMA_SDCM_AT);
+
+	/* Clear the SDMA current and first TX and RX pointers */
+	mpsc_sdma_set_tx_ring(pi, 0);
+	mpsc_sdma_set_rx_ring(pi, 0);
+
+	/* Disable interrupts */
+	mpsc_sdma_intr_mask(pi, 0xf);
+	mpsc_sdma_intr_ack(pi);
+
+	return;
+}
+
+/*
+ ******************************************************************************
+ *
+ * Multi-Protocol Serial Controller Routines (MPSC)
+ *
+ ******************************************************************************
+ */
+
+static void
+mpsc_hw_init(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_hw_init[%d]: Initializing hardware\n", pi->port.line);
+
+	/* Set up clock routing */
+	MPSC_MOD_FIELD_S(pi, mpsc_routing, MPSC_MRR, 3, 0, 0);
+	MPSC_MOD_FIELD_S(pi, mpsc_routing, MPSC_MRR, 3, 6, 0);
+	MPSC_MOD_FIELD_S(pi, mpsc_routing, MPSC_RCRR, 4, 0, 0);
+	MPSC_MOD_FIELD_S(pi, mpsc_routing, MPSC_RCRR, 4, 8, 1);
+	MPSC_MOD_FIELD_S(pi, mpsc_routing, MPSC_TCRR, 4, 0, 0);
+	MPSC_MOD_FIELD_S(pi, mpsc_routing, MPSC_TCRR, 4, 8, 1);
+
+	/* Put MPSC in UART mode & enabel Tx/Rx egines */
+	MPSC_WRITE(pi, mpsc, MPSC_MMCRL, 0x000004c4);
+
+	/* No preamble, 16x divider, low-latency,  */
+	MPSC_WRITE(pi, mpsc, MPSC_MMCRH, 0x04400400);
+
+	MPSC_WRITE_M(pi, mpsc, MPSC_CHR_1, 0);
+	MPSC_WRITE_M(pi, mpsc, MPSC_CHR_2, 0);
+	MPSC_WRITE(pi, mpsc, MPSC_CHR_3, pi->mpsc_max_idle);
+	MPSC_WRITE(pi, mpsc, MPSC_CHR_4, 0);
+	MPSC_WRITE(pi, mpsc, MPSC_CHR_5, 0);
+	MPSC_WRITE(pi, mpsc, MPSC_CHR_6, 0);
+	MPSC_WRITE(pi, mpsc, MPSC_CHR_7, 0);
+	MPSC_WRITE(pi, mpsc, MPSC_CHR_8, 0);
+	MPSC_WRITE(pi, mpsc, MPSC_CHR_9, 0);
+	MPSC_WRITE(pi, mpsc, MPSC_CHR_10, 0);
+
+	return;
+}
+
+static inline void
+mpsc_enter_hunt(struct mpsc_port_info *pi)
+{
+	u32 v;
+
+	pr_debug("mpsc_enter_hunt[%d]: Hunting...\n", pi->port.line);
+
+	MPSC_MOD_FIELD_M(pi, mpsc, MPSC_CHR_2, 1, 31, 1);
+
+	/* If erratum prevents reading CHR_2, just delay for a while */
+	if (pi->mirror_regs)
+		udelay(100);
+	else
+		do {
+			v = MPSC_READ_M(pi, mpsc, MPSC_CHR_2);
+		} while (v & MPSC_CHR_2_EH);
+
+	return;
+}
+
+static inline void
+mpsc_freeze(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_freeze[%d]: Freezing\n", pi->port.line);
+
+	MPSC_MOD_FIELD_M(pi, mpsc, MPSC_MPCR, 1, 9, 1);
+	return;
+}
+
+static inline void
+mpsc_unfreeze(struct mpsc_port_info *pi)
+{
+	MPSC_MOD_FIELD_M(pi, mpsc, MPSC_MPCR, 1, 9, 0);
+
+	pr_debug("mpsc_unfreeze[%d]: Unfrozen\n", pi->port.line);
+	return;
+}
+
+static inline void
+mpsc_set_char_length(struct mpsc_port_info *pi, u32 len)
+{
+	pr_debug("mpsc_set_char_length[%d]: char len: %d\n", pi->port.line,len);
+
+	MPSC_MOD_FIELD_M(pi, mpsc, MPSC_MPCR, 2, 12, len);
+	return;
+}
+
+static inline void
+mpsc_set_stop_bit_length(struct mpsc_port_info *pi, u32 len)
+{
+	pr_debug("mpsc_set_stop_bit_length[%d]: stop bits: %d\n",
+		pi->port.line, len);
+
+	MPSC_MOD_FIELD_M(pi, mpsc, MPSC_MPCR, 1, 14, len);
+	return;
+}
+
+static inline void
+mpsc_set_parity(struct mpsc_port_info *pi, u32 p)
+{
+	pr_debug("mpsc_set_parity[%d]: parity bits: 0x%x\n", pi->port.line, p);
+
+	MPSC_MOD_FIELD_M(pi, mpsc, MPSC_CHR_2, 2, 2, p);	/* TPM */
+	MPSC_MOD_FIELD_M(pi, mpsc, MPSC_CHR_2, 2, 18, p);	/* RPM */
+	return;
+}
+
+/*
+ ******************************************************************************
+ *
+ * Driver Init Routines
+ *
+ ******************************************************************************
+ */
+
+static void
+mpsc_init_hw(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_init_hw[%d]: Initializing\n", pi->port.line);
+
+	mpsc_brg_init(pi, pi->brg_clk_src);
+	mpsc_brg_enable(pi);
+	mpsc_sdma_init(pi, dma_get_cache_alignment());	/* burst a cacheline */
+	mpsc_sdma_stop(pi);
+	mpsc_hw_init(pi);
+
+	return;
+}
+
+static int
+mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
+{
+	int rc = 0;
+	static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
+
+	pr_debug("mpsc_alloc_ring_mem[%d]: Allocating ring mem\n",
+		pi->port.line);
+
+	if (!pi->dma_region) {
+		if (!dma_supported(pi->port.dev, 0xffffffff)) {
+			printk(KERN_ERR "MPSC: Inadequate DMA support\n");
+			rc = -ENXIO;
+		}
+		else if ((pi->dma_region = dma_alloc_noncoherent(pi->port.dev,
+			MPSC_DMA_ALLOC_SIZE, &pi->dma_region_p, GFP_KERNEL))
+			== NULL) {
+
+			printk(KERN_ERR "MPSC: Can't alloc Desc region\n");
+			rc = -ENOMEM;
+		}
+	}
+
+	return rc;
+}
+
+static void
+mpsc_free_ring_mem(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_free_ring_mem[%d]: Freeing ring mem\n", pi->port.line);
+
+	if (pi->dma_region) {
+		dma_free_noncoherent(pi->port.dev, MPSC_DMA_ALLOC_SIZE,
+			  pi->dma_region, pi->dma_region_p);
+		pi->dma_region = NULL;
+		pi->dma_region_p = (dma_addr_t) NULL;
+	}
+
+	return;
+}
+
+static void
+mpsc_init_rings(struct mpsc_port_info *pi)
+{
+	struct mpsc_rx_desc *rxre;
+	struct mpsc_tx_desc *txre;
+	dma_addr_t dp, dp_p;
+	u8 *bp, *bp_p;
+	int i;
+
+	pr_debug("mpsc_init_rings[%d]: Initializing rings\n", pi->port.line);
+
+	BUG_ON(pi->dma_region == NULL);
+
+	memset(pi->dma_region, 0, MPSC_DMA_ALLOC_SIZE);
+
+	/*
+	 * Descriptors & buffers are multiples of cacheline size and must be
+	 * cacheline aligned.
+	 */
+	dp = ALIGN((u32) pi->dma_region, dma_get_cache_alignment());
+	dp_p = ALIGN((u32) pi->dma_region_p, dma_get_cache_alignment());
+
+	/*
+	 * Partition dma region into rx ring descriptor, rx buffers,
+	 * tx ring descriptors, and tx buffers.
+	 */
+	pi->rxr = dp;
+	pi->rxr_p = dp_p;
+	dp += MPSC_RXR_SIZE;
+	dp_p += MPSC_RXR_SIZE;
+
+	pi->rxb = (u8 *) dp;
+	pi->rxb_p = (u8 *) dp_p;
+	dp += MPSC_RXB_SIZE;
+	dp_p += MPSC_RXB_SIZE;
+
+	pi->rxr_posn = 0;
+
+	pi->txr = dp;
+	pi->txr_p = dp_p;
+	dp += MPSC_TXR_SIZE;
+	dp_p += MPSC_TXR_SIZE;
+
+	pi->txb = (u8 *) dp;
+	pi->txb_p = (u8 *) dp_p;
+
+	pi->txr_head = 0;
+	pi->txr_tail = 0;
+
+	/* Init rx ring descriptors */
+	dp = pi->rxr;
+	dp_p = pi->rxr_p;
+	bp = pi->rxb;
+	bp_p = pi->rxb_p;
+
+	for (i = 0; i < MPSC_RXR_ENTRIES; i++) {
+		rxre = (struct mpsc_rx_desc *)dp;
+
+		rxre->bufsize = cpu_to_be16(MPSC_RXBE_SIZE);
+		rxre->bytecnt = cpu_to_be16(0);
+		rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
+					    SDMA_DESC_CMDSTAT_EI |
+					    SDMA_DESC_CMDSTAT_F |
+					    SDMA_DESC_CMDSTAT_L);
+		rxre->link = cpu_to_be32(dp_p + MPSC_RXRE_SIZE);
+		rxre->buf_ptr = cpu_to_be32(bp_p);
+
+		dp += MPSC_RXRE_SIZE;
+		dp_p += MPSC_RXRE_SIZE;
+		bp += MPSC_RXBE_SIZE;
+		bp_p += MPSC_RXBE_SIZE;
+	}
+	rxre->link = cpu_to_be32(pi->rxr_p);	/* Wrap last back to first */
+
+	/* Init tx ring descriptors */
+	dp = pi->txr;
+	dp_p = pi->txr_p;
+	bp = pi->txb;
+	bp_p = pi->txb_p;
+
+	for (i = 0; i < MPSC_TXR_ENTRIES; i++) {
+		txre = (struct mpsc_tx_desc *)dp;
+
+		txre->link = cpu_to_be32(dp_p + MPSC_TXRE_SIZE);
+		txre->buf_ptr = cpu_to_be32(bp_p);
+
+		dp += MPSC_TXRE_SIZE;
+		dp_p += MPSC_TXRE_SIZE;
+		bp += MPSC_TXBE_SIZE;
+		bp_p += MPSC_TXBE_SIZE;
+	}
+	txre->link = cpu_to_be32(pi->txr_p);	/* Wrap last back to first */
+
+	dma_cache_sync((void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE,
+		DMA_BIDIRECTIONAL);
+	MPSC_CACHE_FLUSH(pi, pi->dma_region,
+		pi->dma_region + MPSC_DMA_ALLOC_SIZE);
+
+	return;
+}
+
+static void
+mpsc_uninit_rings(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_uninit_rings[%d]: Uninitializing rings\n",pi->port.line);
+
+	BUG_ON(pi->dma_region == NULL);
+
+	pi->rxr = 0;
+	pi->rxr_p = 0;
+	pi->rxb = NULL;
+	pi->rxb_p = NULL;
+	pi->rxr_posn = 0;
+
+	pi->txr = 0;
+	pi->txr_p = 0;
+	pi->txb = NULL;
+	pi->txb_p = NULL;
+	pi->txr_head = 0;
+	pi->txr_tail = 0;
+
+	return;
+}
+
+static int
+mpsc_make_ready(struct mpsc_port_info *pi)
+{
+	int rc;
+
+	pr_debug("mpsc_make_ready[%d]: Making cltr ready\n", pi->port.line);
+
+	if (!pi->ready) {
+		mpsc_init_hw(pi);
+		if ((rc = mpsc_alloc_ring_mem(pi)))
+			return rc;
+		mpsc_init_rings(pi);
+		pi->ready = 1;
+	}
+
+	return 0;
+}
+
+/*
+ ******************************************************************************
+ *
+ * Interrupt Handling Routines
+ *
+ ******************************************************************************
+ */
+
+static inline int
+mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs)
+{
+	struct mpsc_rx_desc *rxre;
+	struct tty_struct *tty = pi->port.info->tty;
+	u32	cmdstat, bytes_in, i;
+	int	rc = 0;
+	u8	*bp;
+	char	flag = TTY_NORMAL;
+	static void mpsc_start_rx(struct mpsc_port_info *pi);
+
+	pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
+
+	rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE));
+
+	dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+	MPSC_CACHE_INVALIDATE(pi, (u32) rxre, (u32) rxre + MPSC_RXRE_SIZE);
+
+	/*
+	 * Loop through Rx descriptors handling ones that have been completed.
+	 */
+	while (!((cmdstat = be32_to_cpu(rxre->cmdstat)) & SDMA_DESC_CMDSTAT_O)){
+		bytes_in = be16_to_cpu(rxre->bytecnt);
+
+		/* Following use of tty struct directly is deprecated */
+		if (unlikely((tty->flip.count + bytes_in) >= TTY_FLIPBUF_SIZE)){
+			if (tty->low_latency)
+				tty_flip_buffer_push(tty);
+			/*
+			 * If this failed then we will throw awa the bytes
+			 * but mst do so to clear interrupts.
+			 */
+		}
+
+		bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
+		dma_cache_sync((void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
+		MPSC_CACHE_INVALIDATE(pi, bp, bp + MPSC_RXBE_SIZE);
+
+		/*
+		 * Other than for parity error, the manual provides little
+		 * info on what data will be in a frame flagged by any of
+		 * these errors.  For parity error, it is the last byte in
+		 * the buffer that had the error.  As for the rest, I guess
+		 * we'll assume there is no data in the buffer.
+		 * If there is...it gets lost.
+		 */
+		if (unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
+			SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) {
+
+			pi->port.icount.rx++;
+
+			if (cmdstat & SDMA_DESC_CMDSTAT_BR) {	/* Break */
+				pi->port.icount.brk++;
+
+				if (uart_handle_break(&pi->port))
+					goto next_frame;
+			}
+			else if (cmdstat & SDMA_DESC_CMDSTAT_FR)/* Framing */
+				pi->port.icount.frame++;
+			else if (cmdstat & SDMA_DESC_CMDSTAT_OR) /* Overrun */
+				pi->port.icount.overrun++;
+
+			cmdstat &= pi->port.read_status_mask;
+
+			if (cmdstat & SDMA_DESC_CMDSTAT_BR)
+				flag = TTY_BREAK;
+			else if (cmdstat & SDMA_DESC_CMDSTAT_FR)
+				flag = TTY_FRAME;
+			else if (cmdstat & SDMA_DESC_CMDSTAT_OR)
+				flag = TTY_OVERRUN;
+			else if (cmdstat & SDMA_DESC_CMDSTAT_PE)
+				flag = TTY_PARITY;
+		}
+
+		if (uart_handle_sysrq_char(&pi->port, *bp, regs)) {
+			bp++;
+			bytes_in--;
+			goto next_frame;
+		}
+
+		if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
+			SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
+			!(cmdstat & pi->port.ignore_status_mask))
+
+			tty_insert_flip_char(tty, *bp, flag);
+		else {
+			for (i=0; i<bytes_in; i++)
+				tty_insert_flip_char(tty, *bp++, TTY_NORMAL);
+
+			pi->port.icount.rx += bytes_in;
+		}
+
+next_frame:
+		rxre->bytecnt = cpu_to_be16(0);
+		wmb();
+		rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
+					    SDMA_DESC_CMDSTAT_EI |
+					    SDMA_DESC_CMDSTAT_F |
+					    SDMA_DESC_CMDSTAT_L);
+		wmb();
+		dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
+		MPSC_CACHE_FLUSH(pi, (u32) rxre, (u32) rxre + MPSC_RXRE_SIZE);
+
+		/* Advance to next descriptor */
+		pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1);
+		rxre = (struct mpsc_rx_desc *)(pi->rxr +
+			(pi->rxr_posn * MPSC_RXRE_SIZE));
+		dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
+		MPSC_CACHE_INVALIDATE(pi, (u32)rxre, (u32)rxre+MPSC_RXRE_SIZE);
+
+		rc = 1;
+	}
+
+	/* Restart rx engine, if its stopped */
+	if ((MPSC_READ(pi, sdma, SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
+		mpsc_start_rx(pi);
+
+	tty_flip_buffer_push(tty);
+	return rc;
+}
+
+static inline void
+mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
+{
+	struct mpsc_tx_desc *txre;
+
+	txre = (struct mpsc_tx_desc *)(pi->txr +
+		(pi->txr_head * MPSC_TXRE_SIZE));
+
+	txre->bytecnt = cpu_to_be16(count);
+	txre->shadow = txre->bytecnt;
+	wmb();			/* ensure cmdstat is last field updated */
+	txre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O | SDMA_DESC_CMDSTAT_F |
+				    SDMA_DESC_CMDSTAT_L | ((intr) ?
+							   SDMA_DESC_CMDSTAT_EI
+							   : 0));
+	wmb();
+	dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL);
+	MPSC_CACHE_FLUSH(pi, (u32) txre, (u32) txre + MPSC_TXRE_SIZE);
+
+	return;
+}
+
+static inline void
+mpsc_copy_tx_data(struct mpsc_port_info *pi)
+{
+	struct circ_buf *xmit = &pi->port.info->xmit;
+	u8 *bp;
+	u32 i;
+
+	/* Make sure the desc ring isn't full */
+	while (CIRC_CNT(pi->txr_head, pi->txr_tail, MPSC_TXR_ENTRIES) <
+	       (MPSC_TXR_ENTRIES - 1)) {
+		if (pi->port.x_char) {
+			/*
+			 * Ideally, we should use the TCS field in
+			 * CHR_1 to put the x_char out immediately but
+			 * errata prevents us from being able to read
+			 * CHR_2 to know that its safe to write to
+			 * CHR_1.  Instead, just put it in-band with
+			 * all the other Tx data.
+			 */
+			bp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
+			*bp = pi->port.x_char;
+			pi->port.x_char = 0;
+			i = 1;
+		}
+		else if (!uart_circ_empty(xmit) && !uart_tx_stopped(&pi->port)){
+			i = min((u32) MPSC_TXBE_SIZE,
+				(u32) uart_circ_chars_pending(xmit));
+			i = min(i, (u32) CIRC_CNT_TO_END(xmit->head, xmit->tail,
+				UART_XMIT_SIZE));
+			bp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
+			memcpy(bp, &xmit->buf[xmit->tail], i);
+			xmit->tail = (xmit->tail + i) & (UART_XMIT_SIZE - 1);
+
+			if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+				uart_write_wakeup(&pi->port);
+		}
+		else /* All tx data copied into ring bufs */
+			return;
+
+		dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
+		MPSC_CACHE_FLUSH(pi, bp, bp + MPSC_TXBE_SIZE);
+		mpsc_setup_tx_desc(pi, i, 1);
+
+		/* Advance to next descriptor */
+		pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
+	}
+
+	return;
+}
+
+static inline int
+mpsc_tx_intr(struct mpsc_port_info *pi)
+{
+	struct mpsc_tx_desc *txre;
+	int rc = 0;
+
+	if (!mpsc_sdma_tx_active(pi)) {
+		txre = (struct mpsc_tx_desc *)(pi->txr +
+			(pi->txr_tail * MPSC_TXRE_SIZE));
+
+		dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
+		MPSC_CACHE_INVALIDATE(pi, (u32) txre, (u32)txre+MPSC_TXRE_SIZE);
+
+		while (!(be32_to_cpu(txre->cmdstat) & SDMA_DESC_CMDSTAT_O)) {
+			rc = 1;
+			pi->port.icount.tx += be16_to_cpu(txre->bytecnt);
+			pi->txr_tail = (pi->txr_tail+1) & (MPSC_TXR_ENTRIES-1);
+
+			/* If no more data to tx, fall out of loop */
+			if (pi->txr_head == pi->txr_tail)
+				break;
+
+			txre = (struct mpsc_tx_desc *)(pi->txr +
+				(pi->txr_tail * MPSC_TXRE_SIZE));
+			dma_cache_sync((void *) txre, MPSC_TXRE_SIZE,
+				DMA_FROM_DEVICE);
+			MPSC_CACHE_INVALIDATE(pi, (u32) txre,
+			      (u32) txre + MPSC_TXRE_SIZE);
+		}
+
+		mpsc_copy_tx_data(pi);
+		mpsc_sdma_start_tx(pi);	/* start next desc if ready */
+	}
+
+	return rc;
+}
+
+/*
+ * This is the driver's interrupt handler.  To avoid a race, we first clear
+ * the interrupt, then handle any completed Rx/Tx descriptors.  When done
+ * handling those descriptors, we restart the Rx/Tx engines if they're stopped.
+ */
+static irqreturn_t
+mpsc_sdma_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct mpsc_port_info *pi = dev_id;
+	ulong iflags;
+	int rc = IRQ_NONE;
+
+	pr_debug("mpsc_sdma_intr[%d]: SDMA Interrupt Received\n",pi->port.line);
+
+	spin_lock_irqsave(&pi->port.lock, iflags);
+	mpsc_sdma_intr_ack(pi);
+	if (mpsc_rx_intr(pi, regs))
+		rc = IRQ_HANDLED;
+	if (mpsc_tx_intr(pi))
+		rc = IRQ_HANDLED;
+	spin_unlock_irqrestore(&pi->port.lock, iflags);
+
+	pr_debug("mpsc_sdma_intr[%d]: SDMA Interrupt Handled\n", pi->port.line);
+	return rc;
+}
+
+/*
+ ******************************************************************************
+ *
+ * serial_core.c Interface routines
+ *
+ ******************************************************************************
+ */
+static uint
+mpsc_tx_empty(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	ulong iflags;
+	uint rc;
+
+	spin_lock_irqsave(&pi->port.lock, iflags);
+	rc = mpsc_sdma_tx_active(pi) ? 0 : TIOCSER_TEMT;
+	spin_unlock_irqrestore(&pi->port.lock, iflags);
+
+	return rc;
+}
+
+static void
+mpsc_set_mctrl(struct uart_port *port, uint mctrl)
+{
+	/* Have no way to set modem control lines AFAICT */
+	return;
+}
+
+static uint
+mpsc_get_mctrl(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	u32 mflags, status;
+	ulong iflags;
+
+	spin_lock_irqsave(&pi->port.lock, iflags);
+	status = MPSC_READ_M(pi, mpsc, MPSC_CHR_10);
+	spin_unlock_irqrestore(&pi->port.lock, iflags);
+
+	mflags = 0;
+	if (status & 0x1)
+		mflags |= TIOCM_CTS;
+	if (status & 0x2)
+		mflags |= TIOCM_CAR;
+
+	return mflags | TIOCM_DSR;	/* No way to tell if DSR asserted */
+}
+
+static void
+mpsc_stop_tx(struct uart_port *port, uint tty_start)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	pr_debug("mpsc_stop_tx[%d]: tty_start: %d\n", port->line, tty_start);
+
+	mpsc_freeze(pi);
+	return;
+}
+
+static void
+mpsc_start_tx(struct uart_port *port, uint tty_start)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	mpsc_unfreeze(pi);
+	mpsc_copy_tx_data(pi);
+	mpsc_sdma_start_tx(pi);
+
+	pr_debug("mpsc_start_tx[%d]: tty_start: %d\n", port->line, tty_start);
+	return;
+}
+
+static void
+mpsc_start_rx(struct mpsc_port_info *pi)
+{
+	pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
+
+	if (pi->rcv_data) {
+		mpsc_enter_hunt(pi);
+		mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
+	}
+	return;
+}
+
+static void
+mpsc_stop_rx(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	pr_debug("mpsc_stop_rx[%d]: Stopping...\n", port->line);
+
+	mpsc_sdma_cmd(pi, SDMA_SDCM_AR);
+	return;
+}
+
+static void
+mpsc_enable_ms(struct uart_port *port)
+{
+	return;			/* Not supported */
+}
+
+static void
+mpsc_break_ctl(struct uart_port *port, int ctl)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	ulong flags;
+
+	spin_lock_irqsave(&pi->port.lock, flags);
+	if (ctl) /* Send as many BRK chars as we can */
+		MPSC_WRITE_M(pi, mpsc, MPSC_CHR_1, 0x00ff0000);
+	else /* Stop sending BRK chars */
+		MPSC_WRITE_M(pi, mpsc, MPSC_CHR_1, 0);
+	spin_unlock_irqrestore(&pi->port.lock, flags);
+
+	return;
+}
+
+static int
+mpsc_startup(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	u32 flag = 0;
+	int rc;
+
+	pr_debug("mpsc_startup[%d]: Starting up MPSC, irq: %d\n",
+		port->line, pi->port.irq);
+
+	if ((rc = mpsc_make_ready(pi)) == 0) {
+		/* Setup IRQ handler */
+		mpsc_sdma_intr_ack(pi);
+
+		/* If irq's are shared, need to set flag */
+		if (mpsc_ports[0].port.irq == mpsc_ports[1].port.irq)
+			flag = SA_SHIRQ;
+
+		if (request_irq(pi->port.irq, mpsc_sdma_intr, flag,
+				"mpsc/sdma", pi))
+			printk(KERN_ERR "MPSC: Can't get SDMA IRQ %d\n",
+			       pi->port.irq);
+
+		mpsc_sdma_intr_unmask(pi, 0xf);
+		mpsc_sdma_set_rx_ring(pi, (struct mpsc_rx_desc *)(pi->rxr_p +
+			(pi->rxr_posn * MPSC_RXRE_SIZE)));
+	}
+
+	return rc;
+}
+
+static void
+mpsc_shutdown(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	static void mpsc_release_port(struct uart_port *port);
+
+	pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line);
+
+	mpsc_sdma_stop(pi);
+	free_irq(pi->port.irq, pi);
+	return;
+}
+
+static void
+mpsc_set_termios(struct uart_port *port, struct termios *termios,
+		 struct termios *old)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	u32 baud;
+	ulong flags;
+	u32 chr_bits, stop_bits, par;
+
+	pi->c_iflag = termios->c_iflag;
+	pi->c_cflag = termios->c_cflag;
+
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		chr_bits = MPSC_MPCR_CL_5;
+		break;
+	case CS6:
+		chr_bits = MPSC_MPCR_CL_6;
+		break;
+	case CS7:
+		chr_bits = MPSC_MPCR_CL_7;
+		break;
+	case CS8:
+	default:
+		chr_bits = MPSC_MPCR_CL_8;
+		break;
+	}
+
+	if (termios->c_cflag & CSTOPB)
+		stop_bits = MPSC_MPCR_SBL_2;
+	else
+		stop_bits = MPSC_MPCR_SBL_1;
+
+	par = MPSC_CHR_2_PAR_EVEN;
+	if (termios->c_cflag & PARENB)
+		if (termios->c_cflag & PARODD)
+			par = MPSC_CHR_2_PAR_ODD;
+#ifdef	CMSPAR
+		if (termios->c_cflag & CMSPAR) {
+			if (termios->c_cflag & PARODD)
+				par = MPSC_CHR_2_PAR_MARK;
+			else
+				par = MPSC_CHR_2_PAR_SPACE;
+		}
+#endif
+
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk);
+
+	spin_lock_irqsave(&pi->port.lock, flags);
+
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	mpsc_set_char_length(pi, chr_bits);
+	mpsc_set_stop_bit_length(pi, stop_bits);
+	mpsc_set_parity(pi, par);
+	mpsc_set_baudrate(pi, baud);
+
+	/* Characters/events to read */
+	pi->rcv_data = 1;
+	pi->port.read_status_mask = SDMA_DESC_CMDSTAT_OR;
+
+	if (termios->c_iflag & INPCK)
+		pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_PE |
+		    SDMA_DESC_CMDSTAT_FR;
+
+	if (termios->c_iflag & (BRKINT | PARMRK))
+		pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_BR;
+
+	/* Characters/events to ignore */
+	pi->port.ignore_status_mask = 0;
+
+	if (termios->c_iflag & IGNPAR)
+		pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_PE |
+		    SDMA_DESC_CMDSTAT_FR;
+
+	if (termios->c_iflag & IGNBRK) {
+		pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_BR;
+
+		if (termios->c_iflag & IGNPAR)
+			pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_OR;
+	}
+
+	/* Ignore all chars if CREAD not set */
+	if (!(termios->c_cflag & CREAD))
+		pi->rcv_data = 0;
+	else
+		mpsc_start_rx(pi);
+
+	spin_unlock_irqrestore(&pi->port.lock, flags);
+	return;
+}
+
+static const char *
+mpsc_type(struct uart_port *port)
+{
+	pr_debug("mpsc_type[%d]: port type: %s\n", port->line,MPSC_DRIVER_NAME);
+	return MPSC_DRIVER_NAME;
+}
+
+static int
+mpsc_request_port(struct uart_port *port)
+{
+	/* Should make chip/platform specific call */
+	return 0;
+}
+
+static void
+mpsc_release_port(struct uart_port *port)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	if (pi->ready) {
+		mpsc_uninit_rings(pi);
+		mpsc_free_ring_mem(pi);
+		pi->ready = 0;
+	}
+
+	return;
+}
+
+static void
+mpsc_config_port(struct uart_port *port, int flags)
+{
+	return;
+}
+
+static int
+mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+	int rc = 0;
+
+	pr_debug("mpsc_verify_port[%d]: Verifying port data\n", pi->port.line);
+
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_MPSC)
+		rc = -EINVAL;
+	else if (pi->port.irq != ser->irq)
+		rc = -EINVAL;
+	else if (ser->io_type != SERIAL_IO_MEM)
+		rc = -EINVAL;
+	else if (pi->port.uartclk / 16 != ser->baud_base) /* Not sure */
+		rc = -EINVAL;
+	else if ((void *)pi->port.mapbase != ser->iomem_base)
+		rc = -EINVAL;
+	else if (pi->port.iobase != ser->port)
+		rc = -EINVAL;
+	else if (ser->hub6 != 0)
+		rc = -EINVAL;
+
+	return rc;
+}
+
+static struct uart_ops mpsc_pops = {
+	.tx_empty     = mpsc_tx_empty,
+	.set_mctrl    = mpsc_set_mctrl,
+	.get_mctrl    = mpsc_get_mctrl,
+	.stop_tx      = mpsc_stop_tx,
+	.start_tx     = mpsc_start_tx,
+	.stop_rx      = mpsc_stop_rx,
+	.enable_ms    = mpsc_enable_ms,
+	.break_ctl    = mpsc_break_ctl,
+	.startup      = mpsc_startup,
+	.shutdown     = mpsc_shutdown,
+	.set_termios  = mpsc_set_termios,
+	.type         = mpsc_type,
+	.release_port = mpsc_release_port,
+	.request_port = mpsc_request_port,
+	.config_port  = mpsc_config_port,
+	.verify_port  = mpsc_verify_port,
+};
+
+/*
+ ******************************************************************************
+ *
+ * Console Interface Routines
+ *
+ ******************************************************************************
+ */
+
+#ifdef CONFIG_SERIAL_MPSC_CONSOLE
+static void
+mpsc_console_write(struct console *co, const char *s, uint count)
+{
+	struct mpsc_port_info *pi = &mpsc_ports[co->index];
+	u8 *bp, *dp, add_cr = 0;
+	int i;
+
+	while (mpsc_sdma_tx_active(pi))
+		udelay(100);
+
+	while (count > 0) {
+		bp = dp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
+
+		for (i = 0; i < MPSC_TXBE_SIZE; i++) {
+			if (count == 0)
+				break;
+
+			if (add_cr) {
+				*(dp++) = '\r';
+				add_cr = 0;
+			}
+			else {
+				*(dp++) = *s;
+
+				if (*(s++) == '\n') { /* add '\r' after '\n' */
+					add_cr = 1;
+					count++;
+				}
+			}
+
+			count--;
+		}
+
+		dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL);
+		MPSC_CACHE_FLUSH(pi, bp, bp + MPSC_TXBE_SIZE);
+		mpsc_setup_tx_desc(pi, i, 0);
+		pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
+		mpsc_sdma_start_tx(pi);
+
+		while (mpsc_sdma_tx_active(pi))
+			udelay(100);
+
+		pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1);
+	}
+
+	return;
+}
+
+static int __init
+mpsc_console_setup(struct console *co, char *options)
+{
+	struct mpsc_port_info *pi;
+	int baud, bits, parity, flow;
+
+	pr_debug("mpsc_console_setup[%d]: options: %s\n", co->index, options);
+
+	if (co->index >= MPSC_NUM_CTLRS)
+		co->index = 0;
+
+	pi = &mpsc_ports[co->index];
+
+	baud = pi->default_baud;
+	bits = pi->default_bits;
+	parity = pi->default_parity;
+	flow = pi->default_flow;
+
+	if (!pi->port.ops)
+		return -ENODEV;
+
+	spin_lock_init(&pi->port.lock);	/* Temporary fix--copied from 8250.c */
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(&pi->port, co, baud, parity, bits, flow);
+}
+
+extern struct uart_driver mpsc_reg;
+static struct console mpsc_console = {
+	.name   = MPSC_DEV_NAME,
+	.write  = mpsc_console_write,
+	.device = uart_console_device,
+	.setup  = mpsc_console_setup,
+	.flags  = CON_PRINTBUFFER,
+	.index  = -1,
+	.data   = &mpsc_reg,
+};
+
+static int __init
+mpsc_late_console_init(void)
+{
+	pr_debug("mpsc_late_console_init: Enter\n");
+
+	if (!(mpsc_console.flags & CON_ENABLED))
+		register_console(&mpsc_console);
+	return 0;
+}
+
+late_initcall(mpsc_late_console_init);
+
+#define MPSC_CONSOLE	&mpsc_console
+#else
+#define MPSC_CONSOLE	NULL
+#endif
+/*
+ ******************************************************************************
+ *
+ * Dummy Platform Driver to extract & map shared register regions
+ *
+ ******************************************************************************
+ */
+static void
+mpsc_resource_err(char *s)
+{
+	printk(KERN_WARNING "MPSC: Platform device resource error in %s\n", s);
+	return;
+}
+
+static int
+mpsc_shared_map_regs(struct platform_device *pd)
+{
+	struct resource	*r;
+
+	if ((r = platform_get_resource(pd, IORESOURCE_MEM,
+		MPSC_ROUTING_BASE_ORDER)) && request_mem_region(r->start,
+		MPSC_ROUTING_REG_BLOCK_SIZE, "mpsc_routing_regs")) {
+
+		mpsc_shared_regs.mpsc_routing_base = (u32) ioremap(r->start,
+			MPSC_ROUTING_REG_BLOCK_SIZE);
+		mpsc_shared_regs.mpsc_routing_base_p = r->start;
+	}
+	else {
+		mpsc_resource_err("MPSC routing base");
+		return -ENOMEM;
+	}
+
+	if ((r = platform_get_resource(pd, IORESOURCE_MEM,
+		MPSC_SDMA_INTR_BASE_ORDER)) && request_mem_region(r->start,
+		MPSC_SDMA_INTR_REG_BLOCK_SIZE, "sdma_intr_regs")) {
+
+		mpsc_shared_regs.sdma_intr_base = (u32) ioremap(r->start,
+			MPSC_SDMA_INTR_REG_BLOCK_SIZE);
+		mpsc_shared_regs.sdma_intr_base_p = r->start;
+	}
+	else {
+		iounmap((void *)mpsc_shared_regs.mpsc_routing_base);
+		release_mem_region(mpsc_shared_regs.mpsc_routing_base_p,
+			MPSC_ROUTING_REG_BLOCK_SIZE);
+		mpsc_resource_err("SDMA intr base");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void
+mpsc_shared_unmap_regs(void)
+{
+	if (!mpsc_shared_regs.mpsc_routing_base) {
+		iounmap((void *)mpsc_shared_regs.mpsc_routing_base);
+		release_mem_region(mpsc_shared_regs.mpsc_routing_base_p,
+			MPSC_ROUTING_REG_BLOCK_SIZE);
+	}
+	if (!mpsc_shared_regs.sdma_intr_base) {
+		iounmap((void *)mpsc_shared_regs.sdma_intr_base);
+		release_mem_region(mpsc_shared_regs.sdma_intr_base_p,
+			MPSC_SDMA_INTR_REG_BLOCK_SIZE);
+	}
+
+	mpsc_shared_regs.mpsc_routing_base = 0;
+	mpsc_shared_regs.sdma_intr_base = 0;
+
+	mpsc_shared_regs.mpsc_routing_base_p = 0;
+	mpsc_shared_regs.sdma_intr_base_p = 0;
+
+	return;
+}
+
+static int
+mpsc_shared_drv_probe(struct device *dev)
+{
+	struct platform_device		*pd = to_platform_device(dev);
+	struct mpsc_shared_pd_dd	*dd;
+	int				 rc = -ENODEV;
+
+	if (pd->id == 0) {
+		if (!(rc = mpsc_shared_map_regs(pd)))  {
+			dd = (struct mpsc_shared_pd_dd *)
+				dev_get_drvdata(dev);
+
+			mpsc_shared_regs.MPSC_MRR_m = dd->mrr_val;
+			mpsc_shared_regs.MPSC_RCRR_m= dd->rcrr_val;
+			mpsc_shared_regs.MPSC_TCRR_m= dd->tcrr_val;
+			mpsc_shared_regs.SDMA_INTR_CAUSE_m =
+				dd->intr_cause_val;
+			mpsc_shared_regs.SDMA_INTR_MASK_m =
+				dd->intr_mask_val;
+
+			rc = 0;
+		}
+	}
+
+	return rc;
+}
+
+static int
+mpsc_shared_drv_remove(struct device *dev)
+{
+	struct platform_device	*pd = to_platform_device(dev);
+	int	rc = -ENODEV;
+
+	if (pd->id == 0) {
+		mpsc_shared_unmap_regs();
+		mpsc_shared_regs.MPSC_MRR_m = 0;
+		mpsc_shared_regs.MPSC_RCRR_m = 0;
+		mpsc_shared_regs.MPSC_TCRR_m = 0;
+		mpsc_shared_regs.SDMA_INTR_CAUSE_m = 0;
+		mpsc_shared_regs.SDMA_INTR_MASK_m = 0;
+		rc = 0;
+	}
+
+	return rc;
+}
+
+static struct device_driver mpsc_shared_driver = {
+	.name	= MPSC_SHARED_NAME,
+	.bus	= &platform_bus_type,
+	.probe	= mpsc_shared_drv_probe,
+	.remove	= mpsc_shared_drv_remove,
+};
+
+/*
+ ******************************************************************************
+ *
+ * Driver Interface Routines
+ *
+ ******************************************************************************
+ */
+static struct uart_driver mpsc_reg = {
+	.owner       = THIS_MODULE,
+	.driver_name = MPSC_DRIVER_NAME,
+	.devfs_name  = MPSC_DEVFS_NAME,
+	.dev_name    = MPSC_DEV_NAME,
+	.major       = MPSC_MAJOR,
+	.minor       = MPSC_MINOR_START,
+	.nr          = MPSC_NUM_CTLRS,
+	.cons        = MPSC_CONSOLE,
+};
+
+static int
+mpsc_drv_map_regs(struct mpsc_port_info *pi, struct platform_device *pd)
+{
+	struct resource	*r;
+
+	if ((r = platform_get_resource(pd, IORESOURCE_MEM, MPSC_BASE_ORDER)) &&
+		request_mem_region(r->start, MPSC_REG_BLOCK_SIZE, "mpsc_regs")){
+
+		pi->mpsc_base = (u32) ioremap(r->start, MPSC_REG_BLOCK_SIZE);
+		pi->mpsc_base_p = r->start;
+	}
+	else {
+		mpsc_resource_err("MPSC base");
+		return -ENOMEM;
+	}
+
+	if ((r = platform_get_resource(pd, IORESOURCE_MEM,
+		MPSC_SDMA_BASE_ORDER)) && request_mem_region(r->start,
+		MPSC_SDMA_REG_BLOCK_SIZE, "sdma_regs")) {
+
+		pi->sdma_base = (u32)ioremap(r->start,MPSC_SDMA_REG_BLOCK_SIZE);
+		pi->sdma_base_p = r->start;
+	}
+	else {
+		mpsc_resource_err("SDMA base");
+		return -ENOMEM;
+	}
+
+	if ((r = platform_get_resource(pd,IORESOURCE_MEM,MPSC_BRG_BASE_ORDER))
+		&& request_mem_region(r->start, MPSC_BRG_REG_BLOCK_SIZE,
+		"brg_regs")) {
+
+		pi->brg_base = (u32) ioremap(r->start, MPSC_BRG_REG_BLOCK_SIZE);
+		pi->brg_base_p = r->start;
+	}
+	else {
+		mpsc_resource_err("BRG base");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void
+mpsc_drv_unmap_regs(struct mpsc_port_info *pi)
+{
+	if (!pi->mpsc_base) {
+		iounmap((void *)pi->mpsc_base);
+		release_mem_region(pi->mpsc_base_p, MPSC_REG_BLOCK_SIZE);
+	}
+	if (!pi->sdma_base) {
+		iounmap((void *)pi->sdma_base);
+		release_mem_region(pi->sdma_base_p, MPSC_SDMA_REG_BLOCK_SIZE);
+	}
+	if (!pi->brg_base) {
+		iounmap((void *)pi->brg_base);
+		release_mem_region(pi->brg_base_p, MPSC_BRG_REG_BLOCK_SIZE);
+	}
+
+	pi->mpsc_base = 0;
+	pi->sdma_base = 0;
+	pi->brg_base = 0;
+
+	pi->mpsc_base_p = 0;
+	pi->sdma_base_p = 0;
+	pi->brg_base_p = 0;
+
+	return;
+}
+
+static void
+mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
+	struct platform_device *pd, int num)
+{
+	struct mpsc_pd_dd	*dd;
+
+	dd = (struct mpsc_pd_dd *)dev_get_drvdata(&pd->dev);
+
+	pi->port.uartclk = dd->brg_clk_freq;
+	pi->port.iotype = UPIO_MEM;
+	pi->port.line = num;
+	pi->port.type = PORT_MPSC;
+	pi->port.fifosize = MPSC_TXBE_SIZE;
+	pi->port.membase = (char *)pi->mpsc_base;
+	pi->port.mapbase = (ulong) pi->mpsc_base;
+	pi->port.ops = &mpsc_pops;
+
+	pi->mirror_regs = dd->mirror_regs;
+	pi->cache_mgmt = dd->cache_mgmt;
+	pi->brg_can_tune = dd->brg_can_tune;
+	pi->brg_clk_src = dd->brg_clk_src;
+	pi->mpsc_max_idle = dd->max_idle;
+	pi->default_baud = dd->default_baud;
+	pi->default_bits = dd->default_bits;
+	pi->default_parity = dd->default_parity;
+	pi->default_flow = dd->default_flow;
+
+	/* Initial values of mirrored regs */
+	pi->MPSC_CHR_1_m = dd->chr_1_val;
+	pi->MPSC_CHR_2_m = dd->chr_2_val;
+	pi->MPSC_CHR_10_m = dd->chr_10_val;
+	pi->MPSC_MPCR_m = dd->mpcr_val;
+	pi->BRG_BCR_m = dd->bcr_val;
+
+	pi->shared_regs = &mpsc_shared_regs;
+
+	pi->port.irq = platform_get_irq(pd, 0);
+
+	return;
+}
+
+static int
+mpsc_drv_probe(struct device *dev)
+{
+	struct platform_device	*pd = to_platform_device(dev);
+	struct mpsc_port_info	*pi;
+	int			rc = -ENODEV;
+
+	pr_debug("mpsc_drv_probe: Adding MPSC %d\n", pd->id);
+
+	if (pd->id < MPSC_NUM_CTLRS) {
+		pi = &mpsc_ports[pd->id];
+
+		if (!(rc = mpsc_drv_map_regs(pi, pd))) {
+			mpsc_drv_get_platform_data(pi, pd, pd->id);
+
+			if (!(rc = mpsc_make_ready(pi)))
+				if (!(rc = uart_add_one_port(&mpsc_reg,
+					&pi->port)))
+					rc = 0;
+				else {
+					mpsc_release_port(
+						(struct uart_port *)pi);
+					mpsc_drv_unmap_regs(pi);
+				}
+			else
+				mpsc_drv_unmap_regs(pi);
+		}
+	}
+
+	return rc;
+}
+
+static int
+mpsc_drv_remove(struct device *dev)
+{
+	struct platform_device	*pd = to_platform_device(dev);
+
+	pr_debug("mpsc_drv_exit: Removing MPSC %d\n", pd->id);
+
+	if (pd->id < MPSC_NUM_CTLRS) {
+		uart_remove_one_port(&mpsc_reg, &mpsc_ports[pd->id].port);
+		mpsc_release_port((struct uart_port *)&mpsc_ports[pd->id].port);
+		mpsc_drv_unmap_regs(&mpsc_ports[pd->id]);
+		return 0;
+	}
+	else
+		return -ENODEV;
+}
+
+static struct device_driver mpsc_driver = {
+	.name	= MPSC_CTLR_NAME,
+	.bus	= &platform_bus_type,
+	.probe	= mpsc_drv_probe,
+	.remove	= mpsc_drv_remove,
+};
+
+static int __init
+mpsc_drv_init(void)
+{
+	int	rc;
+
+	printk(KERN_INFO "Serial: MPSC driver $Revision: 1.00 $\n");
+
+	memset(mpsc_ports, 0, sizeof(mpsc_ports));
+	memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
+
+	if (!(rc = uart_register_driver(&mpsc_reg))) {
+		if (!(rc = driver_register(&mpsc_shared_driver))) {
+			if ((rc = driver_register(&mpsc_driver))) {
+				driver_unregister(&mpsc_shared_driver);
+				uart_unregister_driver(&mpsc_reg);
+			}
+		}
+		else
+			uart_unregister_driver(&mpsc_reg);
+	}
+
+	return rc;
+
+}
+
+static void __exit
+mpsc_drv_exit(void)
+{
+	driver_unregister(&mpsc_driver);
+	driver_unregister(&mpsc_shared_driver);
+	uart_unregister_driver(&mpsc_reg);
+	memset(mpsc_ports, 0, sizeof(mpsc_ports));
+	memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
+	return;
+}
+
+module_init(mpsc_drv_init);
+module_exit(mpsc_drv_exit);
+
+MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
+MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver $Revision: 1.00 $");
+MODULE_VERSION(MPSC_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(MPSC_MAJOR);
diff -Nru a/drivers/serial/mpsc.h b/drivers/serial/mpsc.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/serial/mpsc.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,289 @@
+/*
+ * drivers/serial/mpsc.h
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef	__MPSC_H__
+#define	__MPSC_H__
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/serial.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#if defined(CONFIG_SERIAL_MPSC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+#include "mpsc_defs.h"
+
+/*
+ * Descriptors and buffers must be cache line aligned.
+ * Buffers lengths must be multiple of cache line size.
+ * Number of Tx & Rx descriptors must be powers of 2.
+ */
+#define	MPSC_RXR_ENTRIES	32
+#define	MPSC_RXRE_SIZE		dma_get_cache_alignment()
+#define	MPSC_RXR_SIZE		(MPSC_RXR_ENTRIES * MPSC_RXRE_SIZE)
+#define	MPSC_RXBE_SIZE		dma_get_cache_alignment()
+#define	MPSC_RXB_SIZE		(MPSC_RXR_ENTRIES * MPSC_RXBE_SIZE)
+
+#define	MPSC_TXR_ENTRIES	32
+#define	MPSC_TXRE_SIZE		dma_get_cache_alignment()
+#define	MPSC_TXR_SIZE		(MPSC_TXR_ENTRIES * MPSC_TXRE_SIZE)
+#define	MPSC_TXBE_SIZE		dma_get_cache_alignment()
+#define	MPSC_TXB_SIZE		(MPSC_TXR_ENTRIES * MPSC_TXBE_SIZE)
+
+#define	MPSC_DMA_ALLOC_SIZE	(MPSC_RXR_SIZE + MPSC_RXB_SIZE +	\
+				MPSC_TXR_SIZE + MPSC_TXB_SIZE +		\
+				dma_get_cache_alignment() /* for alignment */)
+
+/* Rx and Tx Ring entry descriptors -- assume entry size is <= cacheline size */
+struct mpsc_rx_desc {
+	u16 bufsize;
+	u16 bytecnt;
+	u32 cmdstat;
+	u32 link;
+	u32 buf_ptr;
+} __attribute((packed));
+
+struct mpsc_tx_desc {
+	u16 bytecnt;
+	u16 shadow;
+	u32 cmdstat;
+	u32 link;
+	u32 buf_ptr;
+} __attribute((packed));
+
+/*
+ * Some regs that have the erratum that you can't read them are are shared
+ * between the two MPSC controllers.  This struct contains those shared regs.
+ */
+struct mpsc_shared_regs {
+	u32 mpsc_routing_base_p;
+	u32 sdma_intr_base_p;
+
+	u32 mpsc_routing_base;
+	u32 sdma_intr_base;
+
+	u32 MPSC_MRR_m;
+	u32 MPSC_RCRR_m;
+	u32 MPSC_TCRR_m;
+	u32 SDMA_INTR_CAUSE_m;
+	u32 SDMA_INTR_MASK_m;
+};
+
+/* The main driver data structure */
+struct mpsc_port_info {
+	struct uart_port port;	/* Overlay uart_port structure */
+
+	/* Internal driver state for this ctlr */
+	u8 ready;
+	u8 rcv_data;
+	tcflag_t c_iflag;	/* save termios->c_iflag */
+	tcflag_t c_cflag;	/* save termios->c_cflag */
+
+	/* Info passed in from platform */
+	u8 mirror_regs;		/* Need to mirror regs? */
+	u8 cache_mgmt;		/* Need manual cache mgmt? */
+	u8 brg_can_tune;	/* BRG has baud tuning? */
+	u32 brg_clk_src;
+	u16 mpsc_max_idle;
+	int default_baud;
+	int default_bits;
+	int default_parity;
+	int default_flow;
+
+	/* Physical addresses of various blocks of registers (from platform) */
+	u32 mpsc_base_p;
+	u32 sdma_base_p;
+	u32 brg_base_p;
+
+	/* Virtual addresses of various blocks of registers (from platform) */
+	u32 mpsc_base;
+	u32 sdma_base;
+	u32 brg_base;
+
+	/* Descriptor ring and buffer allocations */
+	void *dma_region;
+	dma_addr_t dma_region_p;
+
+	dma_addr_t rxr;		/* Rx descriptor ring */
+	dma_addr_t rxr_p;	/* Phys addr of rxr */
+	u8 *rxb;		/* Rx Ring I/O buf */
+	u8 *rxb_p;		/* Phys addr of rxb */
+	u32 rxr_posn;		/* First desc w/ Rx data */
+
+	dma_addr_t txr;		/* Tx descriptor ring */
+	dma_addr_t txr_p;	/* Phys addr of txr */
+	u8 *txb;		/* Tx Ring I/O buf */
+	u8 *txb_p;		/* Phys addr of txb */
+	int txr_head;		/* Where new data goes */
+	int txr_tail;		/* Where sent data comes off */
+
+	/* Mirrored values of regs we can't read (if 'mirror_regs' set) */
+	u32 MPSC_MPCR_m;
+	u32 MPSC_CHR_1_m;
+	u32 MPSC_CHR_2_m;
+	u32 MPSC_CHR_10_m;
+	u32 BRG_BCR_m;
+	struct mpsc_shared_regs *shared_regs;
+};
+
+#if defined(CONFIG_PPC32)
+
+#if defined(CONFIG_NOT_COHERENT_CACHE)
+/* No-ops when coherency is off b/c dma_cache_sync() does that work */
+#define	MPSC_CACHE_INVALIDATE(pi, s, e)
+#define	MPSC_CACHE_FLUSH(pi, s, e)
+#else /* defined(CONFIG_NOT_COHERENT_CACHE) */
+/* Coherency is on so dma_cache_sync() is no-op so must do manually */
+#define	MPSC_CACHE_INVALIDATE(pi, s, e) {			\
+	if (pi->cache_mgmt) {					\
+		invalidate_dcache_range((ulong)s, (ulong)e);	\
+	}							\
+}
+
+#define	MPSC_CACHE_FLUSH(pi, s, e) {			\
+	if (pi->cache_mgmt) {				\
+		flush_dcache_range((ulong)s, (ulong)e);	\
+	}						\
+}
+#endif /* defined(CONFIG_NOT_COHERENT_CACHE) */
+
+#else /* defined(CONFIG_PPC32) */
+/* Other architectures need to fill this in */
+#define	MPSC_CACHE_INVALIDATE(pi, s, e)	BUG()
+#define	MPSC_CACHE_FLUSH(pi, s, e)	BUG()
+#endif /* defined(CONFIG_PPC32) */
+
+/*
+ * 'MASK_INSERT' takes the low-order 'n' bits of 'i', shifts it 'b' bits to
+ * the left, and inserts it into the target 't'.  The corresponding bits in
+ * 't' will have been cleared before the bits in 'i' are inserted.
+ */
+#ifdef CONFIG_PPC32
+#define MASK_INSERT(t, i, n, b) ({				\
+	u32	rval = (t);					\
+        __asm__ __volatile__(					\
+		"rlwimi %0,%2,%4,32-(%3+%4),31-%4\n"		\
+		: "=r" (rval)					\
+		: "0" (rval), "r" (i), "i" (n), "i" (b));	\
+	rval;							\
+})
+#else
+/* These macros are really just examples.  Feel free to change them --MAG */
+#define GEN_MASK(n, b)			\
+({					\
+	u32	m, sl, sr;		\
+	sl = 32 - (n);			\
+	sr = sl - (b);			\
+	m = (0xffffffff << sl) >> sr;	\
+})
+
+#define MASK_INSERT(t, i, n, b)		\
+({					\
+	u32	m, rval = (t);		\
+	m = GEN_MASK((n), (b));		\
+	rval &= ~m;			\
+	rval |= (((i) << (b)) & m);	\
+})
+#endif
+
+/* I/O macros for regs that you can read */
+#define	MPSC_READ(pi, unit, offset)					\
+	readl((volatile void *)((pi)->unit##_base + (offset)))
+
+#define	MPSC_WRITE(pi, unit, offset, v)					\
+	writel(v, (volatile void *)((pi)->unit##_base + (offset)))
+
+#define	MPSC_MOD_FIELD(pi, unit, offset, num_bits, shift, val)		\
+{									\
+	u32	v;							\
+	v = readl((volatile void *)((pi)->unit##_base + (offset)));	\
+	writel(MASK_INSERT(v,val,num_bits,shift),			\
+		(volatile void *)((pi)->unit##_base+(offset)));		\
+}
+
+/* Macros for regs with erratum that are not shared between MPSC ctlrs */
+#define	MPSC_READ_M(pi, unit, offset)					\
+({									\
+	u32	v;							\
+	if ((pi)->mirror_regs) v = (pi)->offset##_m;			\
+	else v = readl((volatile void *)((pi)->unit##_base + (offset)));\
+	v;								\
+})
+
+#define	MPSC_WRITE_M(pi, unit, offset, v)				\
+({									\
+	if ((pi)->mirror_regs) (pi)->offset##_m = v;			\
+	writel(v, (volatile void *)((pi)->unit##_base + (offset)));	\
+})
+
+#define	MPSC_MOD_FIELD_M(pi, unit, offset, num_bits, shift, val)	\
+({									\
+	u32	v;							\
+	if ((pi)->mirror_regs) v = (pi)->offset##_m;			\
+	else v = readl((volatile void *)((pi)->unit##_base + (offset)));\
+	v = MASK_INSERT(v, val, num_bits, shift);			\
+	if ((pi)->mirror_regs) (pi)->offset##_m = v;			\
+	writel(v, (volatile void *)((pi)->unit##_base + (offset)));	\
+})
+
+/* Macros for regs with erratum that are shared between MPSC ctlrs */
+#define	MPSC_READ_S(pi, unit, offset)					\
+({									\
+	u32	v;							\
+	if ((pi)->mirror_regs) v = (pi)->shared_regs->offset##_m;	\
+	else v = readl((volatile void *)((pi)->shared_regs->unit##_base + \
+		(offset)));						\
+	v;								\
+})
+
+#define	MPSC_WRITE_S(pi, unit, offset, v)				\
+({									\
+	if ((pi)->mirror_regs) (pi)->shared_regs->offset##_m = v;	\
+	writel(v, (volatile void *)((pi)->shared_regs->unit##_base +	\
+		(offset)));						\
+})
+
+#define	MPSC_MOD_FIELD_S(pi, unit, offset, num_bits, shift, val)	\
+({									\
+	u32	v;							\
+	if ((pi)->mirror_regs) v = (pi)->shared_regs->offset##_m;	\
+	else v = readl((volatile void *)((pi)->shared_regs->unit##_base + \
+		(offset)));						\
+	v = MASK_INSERT(v, val, num_bits, shift);			\
+	if ((pi)->mirror_regs) (pi)->shared_regs->offset##_m = v;	\
+	writel(v, (volatile void *)((pi)->shared_regs->unit##_base +	\
+		(offset)));						\
+})
+
+/* Hooks to platform-specific code */
+int mpsc_platform_register_driver(void);
+void mpsc_platform_unregister_driver(void);
+
+/* Hooks back in to mpsc common to be called by platform-specific code */
+struct mpsc_port_info *mpsc_device_probe(int index);
+struct mpsc_port_info *mpsc_device_remove(int index);
+
+#endif				/* __MPSC_H__ */
diff -Nru a/drivers/serial/mpsc_defs.h b/drivers/serial/mpsc_defs.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/serial/mpsc_defs.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,146 @@
+/*
+ * drivers/serial/mpsc_defs.h
+ *
+ * Register definitions for the Marvell Multi-Protocol Serial Controller (MPSC),
+ * Serial DMA Controller (SDMA), and Baud Rate Generator (BRG).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef	__MPSC_DEFS_H__
+#define	__MPSC_DEFS_H__
+
+#define	MPSC_NUM_CTLRS		2
+
+/*
+ *****************************************************************************
+ *
+ *	Multi-Protocol Serial Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* Main Configuratino Register Offsets */
+#define	MPSC_MMCRL			0x0000
+#define	MPSC_MMCRH			0x0004
+#define	MPSC_MPCR			0x0008
+#define	MPSC_CHR_1			0x000c
+#define	MPSC_CHR_2			0x0010
+#define	MPSC_CHR_3			0x0014
+#define	MPSC_CHR_4			0x0018
+#define	MPSC_CHR_5			0x001c
+#define	MPSC_CHR_6			0x0020
+#define	MPSC_CHR_7			0x0024
+#define	MPSC_CHR_8			0x0028
+#define	MPSC_CHR_9			0x002c
+#define	MPSC_CHR_10			0x0030
+#define	MPSC_CHR_11			0x0034
+
+#define	MPSC_MPCR_CL_5			0
+#define	MPSC_MPCR_CL_6			1
+#define	MPSC_MPCR_CL_7			2
+#define	MPSC_MPCR_CL_8			3
+#define	MPSC_MPCR_SBL_1			0
+#define	MPSC_MPCR_SBL_2			3
+
+#define	MPSC_CHR_2_TEV			(1<<1)
+#define	MPSC_CHR_2_TA			(1<<7)
+#define	MPSC_CHR_2_TTCS			(1<<9)
+#define	MPSC_CHR_2_REV			(1<<17)
+#define	MPSC_CHR_2_RA			(1<<23)
+#define	MPSC_CHR_2_CRD			(1<<25)
+#define	MPSC_CHR_2_EH			(1<<31)
+#define	MPSC_CHR_2_PAR_ODD		0
+#define	MPSC_CHR_2_PAR_SPACE		1
+#define	MPSC_CHR_2_PAR_EVEN		2
+#define	MPSC_CHR_2_PAR_MARK		3
+
+/* MPSC Signal Routing */
+#define	MPSC_MRR			0x0000
+#define	MPSC_RCRR			0x0004
+#define	MPSC_TCRR			0x0008
+
+/*
+ *****************************************************************************
+ *
+ *	Serial DMA Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	SDMA_SDC			0x0000
+#define	SDMA_SDCM			0x0008
+#define	SDMA_RX_DESC			0x0800
+#define	SDMA_RX_BUF_PTR			0x0808
+#define	SDMA_SCRDP			0x0810
+#define	SDMA_TX_DESC			0x0c00
+#define	SDMA_SCTDP			0x0c10
+#define	SDMA_SFTDP			0x0c14
+
+#define	SDMA_DESC_CMDSTAT_PE		(1<<0)
+#define	SDMA_DESC_CMDSTAT_CDL		(1<<1)
+#define	SDMA_DESC_CMDSTAT_FR		(1<<3)
+#define	SDMA_DESC_CMDSTAT_OR		(1<<6)
+#define	SDMA_DESC_CMDSTAT_BR		(1<<9)
+#define	SDMA_DESC_CMDSTAT_MI		(1<<10)
+#define	SDMA_DESC_CMDSTAT_A		(1<<11)
+#define	SDMA_DESC_CMDSTAT_AM		(1<<12)
+#define	SDMA_DESC_CMDSTAT_CT		(1<<13)
+#define	SDMA_DESC_CMDSTAT_C		(1<<14)
+#define	SDMA_DESC_CMDSTAT_ES		(1<<15)
+#define	SDMA_DESC_CMDSTAT_L		(1<<16)
+#define	SDMA_DESC_CMDSTAT_F		(1<<17)
+#define	SDMA_DESC_CMDSTAT_P		(1<<18)
+#define	SDMA_DESC_CMDSTAT_EI		(1<<23)
+#define	SDMA_DESC_CMDSTAT_O		(1<<31)
+
+#define SDMA_DESC_DFLT			(SDMA_DESC_CMDSTAT_O |	\
+					SDMA_DESC_CMDSTAT_EI)
+
+#define	SDMA_SDC_RFT			(1<<0)
+#define	SDMA_SDC_SFM			(1<<1)
+#define	SDMA_SDC_BLMR			(1<<6)
+#define	SDMA_SDC_BLMT			(1<<7)
+#define	SDMA_SDC_POVR			(1<<8)
+#define	SDMA_SDC_RIFB			(1<<9)
+
+#define	SDMA_SDCM_ERD			(1<<7)
+#define	SDMA_SDCM_AR			(1<<15)
+#define	SDMA_SDCM_STD			(1<<16)
+#define	SDMA_SDCM_TXD			(1<<23)
+#define	SDMA_SDCM_AT			(1<<31)
+
+#define	SDMA_0_CAUSE_RXBUF		(1<<0)
+#define	SDMA_0_CAUSE_RXERR		(1<<1)
+#define	SDMA_0_CAUSE_TXBUF		(1<<2)
+#define	SDMA_0_CAUSE_TXEND		(1<<3)
+#define	SDMA_1_CAUSE_RXBUF		(1<<8)
+#define	SDMA_1_CAUSE_RXERR		(1<<9)
+#define	SDMA_1_CAUSE_TXBUF		(1<<10)
+#define	SDMA_1_CAUSE_TXEND		(1<<11)
+
+#define	SDMA_CAUSE_RX_MASK	(SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \
+	SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR)
+#define	SDMA_CAUSE_TX_MASK	(SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \
+	SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND)
+
+/* SDMA Interrupt registers */
+#define	SDMA_INTR_CAUSE			0x0000
+#define	SDMA_INTR_MASK			0x0080
+
+/*
+ *****************************************************************************
+ *
+ *	Baud Rate Generator Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	BRG_BCR				0x0000
+#define	BRG_BTR				0x0004
+
+#endif /*__MPSC_DEFS_H__ */
diff -Nru a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
--- a/drivers/serial/serial_core.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/serial/serial_core.c	2005-01-19 13:44:46 -08:00
@@ -1877,7 +1877,21 @@
 	 * Re-enable the console device after suspending.
 	 */
 	if (uart_console(port)) {
-		uart_change_speed(state, NULL);
+		struct termios termios;
+
+		/*
+		 * First try to use the console cflag setting.
+		 */
+		memset(&termios, 0, sizeof(struct termios));
+		termios.c_cflag = port->cons->cflag;
+
+		/*
+		 * If that's unset, use the tty termios setting.
+		 */
+		if (state->info && state->info->tty && termios.c_cflag == 0)
+			termios = *state->info->tty->termios;
+
+		port->ops->set_termios(port, &termios, NULL);
 		console_start(port->cons);
 	}
 
diff -Nru a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
--- a/drivers/serial/serial_cs.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/serial/serial_cs.c	2005-01-19 13:44:46 -08:00
@@ -68,18 +68,11 @@
 
 /* Parameters that can be set with 'insmod' */
 
-/* Bit map of interrupts to choose from */
-static u_int irq_mask = 0xdeb8;
-static int irq_list[4];
-static unsigned int irq_list_count;
-
 /* Enable the speaker? */
 static int do_sound = 1;
 /* Skip strict UART tests? */
 static int buggy_uart;
 
-module_param(irq_mask, uint, 0444);
-module_param_array(irq_list, int, &irq_list_count, 0444);
 module_param(do_sound, int, 0444);
 module_param(buggy_uart, int, 0444);
 
@@ -205,7 +198,7 @@
 	struct serial_info *info;
 	client_reg_t client_reg;
 	dev_link_t *link;
-	int i, ret;
+	int ret;
 
 	DEBUG(0, "serial_attach()\n");
 
@@ -220,12 +213,7 @@
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.NumPorts1 = 8;
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (irq_list_count == 0)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < irq_list_count; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
 	if (do_sound) {
 		link->conf.Attributes |= CONF_ENABLE_SPKR;
diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile
--- a/drivers/usb/Makefile	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/Makefile	2005-01-19 13:44:47 -08:00
@@ -59,6 +59,7 @@
 obj-$(CONFIG_USB_CYTHERM)	+= misc/
 obj-$(CONFIG_USB_EMI26)		+= misc/
 obj-$(CONFIG_USB_EMI62)		+= misc/
+obj-$(CONFIG_USB_IDMOUSE)	+= misc/
 obj-$(CONFIG_USB_LCD)		+= misc/
 obj-$(CONFIG_USB_LED)		+= misc/
 obj-$(CONFIG_USB_LEGOTOWER)	+= misc/
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/class/cdc-acm.c	2005-01-19 13:44:47 -08:00
@@ -544,24 +544,24 @@
 	
 	/* normal probing*/
 	if (!buffer) {
-		err("Wierd descriptor references");
+		err("Wierd descriptor references\n");
 		return -EINVAL;
 	}
 
 	if (!buflen) {
 		if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
-			dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint");
+			dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
 			buflen = intf->cur_altsetting->endpoint->extralen;
 			buffer = intf->cur_altsetting->endpoint->extra;
 		} else {
-			err("Zero length descriptor references");
+			err("Zero length descriptor references\n");
 			return -EINVAL;
 		}
 	}
 
 	while (buflen > 0) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
-			err("skipping garbage");
+			err("skipping garbage\n");
 			goto next_desc;
 		}
 
@@ -614,14 +614,10 @@
 		}
 	}
 	
-		if (data_interface_num != call_interface_num)
-			dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.");
+	if (data_interface_num != call_interface_num)
+		dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n");
 
 skip_normal_probe:
-	if (usb_interface_claimed(data_interface)) { /* valid in this context */
-		dev_dbg(&intf->dev,"The data interface isn't available\n");
-		return -EBUSY;
-	}
 
 	/*workaround for switched interfaces */
 	if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
@@ -636,6 +632,13 @@
 			return -EINVAL;
 		}
 	}
+	
+	if (usb_interface_claimed(data_interface)) { /* valid in this context */
+		dev_dbg(&intf->dev,"The data interface isn't available\n");
+		return -EBUSY;
+	}
+
+
 	if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
 		return -EINVAL;
 
diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/class/usblp.c	2005-01-19 13:44:46 -08:00
@@ -1096,7 +1096,7 @@
 		usblp->writebuf, 0,
 		usblp_bulk_write, usblp);
 
-	usblp->bidir = (usblp->protocol[protocol].epread != 0);
+	usblp->bidir = (usblp->protocol[protocol].epread != NULL);
 	if (usblp->bidir)
 		usb_fill_bulk_urb(usblp->readurb, usblp->dev,
 			usb_rcvbulkpipe(usblp->dev,
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/core/devio.c	2005-01-19 13:44:46 -08:00
@@ -1127,7 +1127,7 @@
 	if (copy_from_user(&ctrl, arg, sizeof (ctrl)))
 		return -EFAULT;
 	if ((size = _IOC_SIZE (ctrl.ioctl_code)) > 0) {
-		if ((buf = kmalloc (size, GFP_KERNEL)) == 0)
+		if ((buf = kmalloc (size, GFP_KERNEL)) == NULL)
 			return -ENOMEM;
 		if ((_IOC_DIR(ctrl.ioctl_code) & _IOC_WRITE)) {
 			if (copy_from_user (buf, ctrl.data, size)) {
@@ -1187,7 +1187,7 @@
 		down_read(&usb_bus_type.subsys.rwsem);
 		if (intf->dev.driver)
 			driver = to_usb_driver(intf->dev.driver);
-		if (driver == 0 || driver->ioctl == 0) {
+		if (driver == NULL || driver->ioctl == NULL) {
 			retval = -ENOTTY;
 		} else {
 			retval = driver->ioctl (intf, ctrl.ioctl_code, buf);
@@ -1203,7 +1203,7 @@
 			&& size > 0
 			&& copy_to_user (ctrl.data, buf, size) != 0)
 		retval = -EFAULT;
-	if (buf != 0)
+	if (buf != NULL)
 		kfree (buf);
 	return retval;
 }
diff -Nru a/drivers/usb/core/file.c b/drivers/usb/core/file.c
--- a/drivers/usb/core/file.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/usb/core/file.c	2005-01-19 13:44:48 -08:00
@@ -30,7 +30,7 @@
 
 #define MAX_USB_MINORS	256
 static struct file_operations *usb_minors[MAX_USB_MINORS];
-static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(minor_lock);
 
 static int usb_open(struct inode * inode, struct file * file)
 {
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/core/hcd.c	2005-01-19 13:44:47 -08:00
@@ -86,7 +86,6 @@
 
 /* host controllers we manage */
 LIST_HEAD (usb_bus_list);
-EXPORT_SYMBOL_GPL (usb_bus_list);
 
 /* used when allocating bus numbers */
 #define USB_MAXBUS		64
@@ -97,10 +96,9 @@
 
 /* used when updating list of hcds */
 DECLARE_MUTEX (usb_bus_list_lock);	/* exported only for usbfs */
-EXPORT_SYMBOL_GPL (usb_bus_list_lock);
 
 /* used when updating hcd data */
-static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hcd_data_lock);
 
 /* wait queue for synchronous unlinks */
 DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue);
@@ -526,7 +524,7 @@
 	/* do nothing if the urb's been unlinked */
 	if (!urb->dev
 			|| urb->status != -EINPROGRESS
-			|| (hcd = urb->dev->bus->hcpriv) == 0) {
+			|| (hcd = urb->dev->bus->hcpriv) == NULL) {
 		spin_unlock (&urb->lock);
 		local_irq_restore (flags);
 		return;
@@ -1542,7 +1540,6 @@
 	usb_set_device_state(hcd->self.root_hub, USB_STATE_NOTATTACHED);
 	mod_timer(&hcd->rh_timer, jiffies);
 }
-EXPORT_SYMBOL (usb_hc_died);
 
 /*-------------------------------------------------------------------------*/
 
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/core/hub.c	2005-01-19 13:44:46 -08:00
@@ -26,7 +26,6 @@
 #include <linux/ioctl.h>
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
-#include <linux/suspend.h>
 
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
@@ -39,10 +38,10 @@
 /* Protect struct usb_device->state and ->children members
  * Note: Both are also protected by ->serialize, except that ->state can
  * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
-static spinlock_t device_state_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(device_state_lock);
 
 /* khubd's worklist and its lock */
-static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(hub_event_lock);
 static LIST_HEAD(hub_event_list);	/* List of hubs needing servicing */
 
 /* Wakes up khubd */
@@ -405,7 +404,7 @@
 	 * since each TT has "at least two" buffers that can need it (and
 	 * there can be many TTs per hub).  even if they're uncommon.
 	 */
-	if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == 0) {
+	if ((clear = kmalloc (sizeof *clear, SLAB_ATOMIC)) == NULL) {
 		dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
 		/* FIXME recover somehow ... RESET_TT? */
 		return;
@@ -1618,7 +1617,6 @@
 		udev->dev.power.power_state = state;
 	return status;
 }
-EXPORT_SYMBOL(__usb_suspend_device);
 
 /**
  * usb_suspend_device - suspend a usb device
@@ -2300,7 +2298,7 @@
 	int				status;
 
 	qual = kmalloc (sizeof *qual, SLAB_KERNEL);
-	if (qual == 0)
+	if (qual == NULL)
 		return;
 
 	status = usb_get_descriptor (udev, USB_DT_DEVICE_QUALIFIER, 0,
@@ -2748,8 +2746,7 @@
 	do {
 		hub_events();
 		wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 	} while (!signal_pending(current));
 
 	pr_debug ("%s: khubd exiting\n", usbcore_name);
@@ -2832,7 +2829,7 @@
 			len = le16_to_cpu(udev->config[index].desc.wTotalLength);
 	}
 	buf = kmalloc (len, SLAB_KERNEL);
-	if (buf == 0) {
+	if (buf == NULL) {
 		dev_err(&udev->dev, "no mem to re-read configs after reset\n");
 		/* assume the worst */
 		return 1;
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/core/message.c	2005-01-19 13:44:46 -08:00
@@ -209,7 +209,7 @@
 		kfree (io->urbs);
 		io->urbs = NULL;
 	}
-	if (io->dev->dev.dma_mask != 0)
+	if (io->dev->dev.dma_mask != NULL)
 		usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
 	io->dev = NULL;
 }
@@ -334,7 +334,7 @@
 	/* not all host controllers use DMA (like the mainstream pci ones);
 	 * they can use PIO (sl811) or be software over another transport.
 	 */
-	dma = (dev->dev.dma_mask != 0);
+	dma = (dev->dev.dma_mask != NULL);
 	if (dma)
 		io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
 	else
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/core/usb.c	2005-01-19 13:44:46 -08:00
@@ -63,8 +63,7 @@
 int nousb;		/* Disable USB when built into kernel image */
 			/* Not honored on modular build */
 
-DECLARE_RWSEM(usb_all_devices_rwsem);
-EXPORT_SYMBOL(usb_all_devices_rwsem);
+static DECLARE_RWSEM(usb_all_devices_rwsem);
 
 
 static int generic_probe (struct device *dev)
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/host/ehci-hcd.c	2005-01-19 13:44:47 -08:00
@@ -796,7 +796,7 @@
 	 * such lossage has been observed on both VT6202 and VT8235. 
 	 */
 	if (HCD_IS_RUNNING (ehci_to_hcd(ehci)->state) &&
-			(ehci->async->qh_next.ptr != 0 ||
+			(ehci->async->qh_next.ptr != NULL ||
 			 ehci->periodic_sched != 0))
 		timer_action (ehci, TIMER_IO_WATCHDOG);
 }
diff -Nru a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
--- a/drivers/usb/host/ehci-mem.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/host/ehci-mem.c	2005-01-19 13:44:47 -08:00
@@ -51,7 +51,7 @@
 	dma_addr_t		dma;
 
 	qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
-	if (qtd != 0) {
+	if (qtd != NULL) {
 		ehci_qtd_init (qtd, dma);
 	}
 	return qtd;
@@ -98,7 +98,7 @@
 
 	/* dummy td enables safe urb queuing */
 	qh->dummy = ehci_qtd_alloc (ehci, flags);
-	if (qh->dummy == 0) {
+	if (qh->dummy == NULL) {
 		ehci_dbg (ehci, "no dummy td\n");
 		dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
 		qh = NULL;
@@ -215,7 +215,7 @@
 		dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller,
 			ehci->periodic_size * sizeof(__le32),
 			&ehci->periodic_dma, 0);
-	if (ehci->periodic == 0) {
+	if (ehci->periodic == NULL) {
 		goto fail;
 	}
 	for (i = 0; i < ehci->periodic_size; i++)
@@ -223,7 +223,7 @@
 
 	/* software shadow of hardware table */
 	ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags);
-	if (ehci->pshadow == 0) {
+	if (ehci->pshadow == NULL) {
 		goto fail;
 	}
 	memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *));
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/host/ehci-q.c	2005-01-19 13:44:47 -08:00
@@ -218,7 +218,7 @@
 __releases(ehci->lock)
 __acquires(ehci->lock)
 {
-	if (likely (urb->hcpriv != 0)) {
+	if (likely (urb->hcpriv != NULL)) {
 		struct ehci_qh	*qh = (struct ehci_qh *) urb->hcpriv;
 
 		/* S-mask in a QH means it's an interrupt urb */
@@ -404,7 +404,7 @@
 	}
 
 	/* last urb's completion might still need calling */
-	if (likely (last != 0)) {
+	if (likely (last != NULL)) {
 		ehci_urb_done (ehci, last->urb, regs);
 		count++;
 		ehci_qtd_free (ehci, last);
@@ -846,7 +846,7 @@
 		/* just one way to queue requests: swap with the dummy qtd.
 		 * only hc or qh_refresh() ever modify the overlay.
 		 */
-		if (likely (qtd != 0)) {
+		if (likely (qtd != NULL)) {
 			struct ehci_qtd		*dummy;
 			dma_addr_t		dma;
 			__le32			token;
@@ -921,12 +921,12 @@
 	/* Control/bulk operations through TTs don't need scheduling,
 	 * the HC and TT handle it when the TT has a buffer ready.
 	 */
-	if (likely (qh != 0)) {
+	if (likely (qh != NULL)) {
 		if (likely (qh->qh_state == QH_STATE_IDLE))
 			qh_link_async (ehci, qh_get (qh));
 	}
 	spin_unlock_irqrestore (&ehci->lock, flags);
-	if (unlikely (qh == 0)) {
+	if (unlikely (qh == NULL)) {
 		qtd_list_free (ehci, urb, qtd_list);
 		return -ENOMEM;
 	}
@@ -967,7 +967,7 @@
 		 * active but idle for a while once it empties.
 		 */
 		if (HCD_IS_RUNNING (ehci_to_hcd(ehci)->state)
-				&& ehci->async->qh_next.qh == 0)
+				&& ehci->async->qh_next.qh == NULL)
 			timer_action (ehci, TIMER_ASYNC_OFF);
 	}
 
@@ -1048,7 +1048,7 @@
 	timer_action_done (ehci, TIMER_ASYNC_SHRINK);
 rescan:
 	qh = ehci->async->qh_next.qh;
-	if (likely (qh != 0)) {
+	if (likely (qh != NULL)) {
 		do {
 			/* clean any finished work for this qh */
 			if (!list_empty (&qh->qtd_list)
diff -Nru a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/host/ehci-sched.c	2005-01-19 13:44:46 -08:00
@@ -604,7 +604,7 @@
 	/* get qh and force any scheduling errors */
 	INIT_LIST_HEAD (&empty);
 	qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv);
-	if (qh == 0) {
+	if (qh == NULL) {
 		status = -ENOMEM;
 		goto done;
 	}
@@ -615,7 +615,7 @@
 
 	/* then queue the urb's tds to the qh */
 	qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
-	BUG_ON (qh == 0);
+	BUG_ON (qh == NULL);
 
 	/* ... update usbfs periodic stats */
 	ehci_to_hcd(ehci)->self.bandwidth_int_reqs++;
@@ -638,7 +638,7 @@
 	struct ehci_iso_stream *stream;
 
 	stream = kmalloc(sizeof *stream, mem_flags);
-	if (likely (stream != 0)) {
+	if (likely (stream != NULL)) {
 		memset (stream, 0, sizeof(*stream));
 		INIT_LIST_HEAD(&stream->td_list);
 		INIT_LIST_HEAD(&stream->free_list);
@@ -791,7 +791,7 @@
 static inline struct ehci_iso_stream *
 iso_stream_get (struct ehci_iso_stream *stream)
 {
-	if (likely (stream != 0))
+	if (likely (stream != NULL))
 		stream->refcount++;
 	return stream;
 }
@@ -813,9 +813,9 @@
 	spin_lock_irqsave (&ehci->lock, flags);
 	stream = ep->hcpriv;
 
-	if (unlikely (stream == 0)) {
+	if (unlikely (stream == NULL)) {
 		stream = iso_stream_alloc(GFP_ATOMIC);
-		if (likely (stream != 0)) {
+		if (likely (stream != NULL)) {
 			/* dev->ep owns the initial refcount */
 			ep->hcpriv = stream;
 			stream->ep = ep;
@@ -850,7 +850,7 @@
 
 	size += packets * sizeof (struct ehci_iso_packet);
 	iso_sched = kmalloc (size, mem_flags);
-	if (likely (iso_sched != 0)) {
+	if (likely (iso_sched != NULL)) {
 		memset(iso_sched, 0, size);
 		INIT_LIST_HEAD (&iso_sched->td_list);
 	}
@@ -927,7 +927,7 @@
 	unsigned long		flags;
 
 	sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
-	if (unlikely (sched == 0))
+	if (unlikely (sched == NULL))
 		return -ENOMEM;
 
 	itd_sched_init (sched, stream, urb);
@@ -961,7 +961,7 @@
 			spin_lock_irqsave (&ehci->lock, flags);
 		}
 
-		if (unlikely (0 == itd)) {
+		if (unlikely (NULL == itd)) {
 			iso_sched_free (stream, sched);
 			spin_unlock_irqrestore (&ehci->lock, flags);
 			return -ENOMEM;
@@ -1416,7 +1416,7 @@
 
 	/* Get iso_stream head */
 	stream = iso_stream_find (ehci, urb);
-	if (unlikely (stream == 0)) {
+	if (unlikely (stream == NULL)) {
 		ehci_dbg (ehci, "can't get iso stream\n");
 		return -ENOMEM;
 	}
@@ -1530,7 +1530,7 @@
 	unsigned long		flags;
 
 	iso_sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
-	if (iso_sched == 0)
+	if (iso_sched == NULL)
 		return -ENOMEM;
 
 	sitd_sched_init (iso_sched, stream, urb);
@@ -1784,7 +1784,7 @@
 
 	/* Get iso_stream head */
 	stream = iso_stream_find (ehci, urb);
-	if (stream == 0) {
+	if (stream == NULL) {
 		ehci_dbg (ehci, "can't get iso stream\n");
 		return -ENOMEM;
 	}
@@ -1889,7 +1889,7 @@
 		type = Q_NEXT_TYPE (*hw_p);
 		modified = 0;
 
-		while (q.ptr != 0) {
+		while (q.ptr != NULL) {
 			unsigned		uf;
 			union ehci_shadow	temp;
 			int			live;
diff -Nru a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
--- a/drivers/usb/host/sl811-hcd.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/host/sl811-hcd.c	2005-01-19 13:44:46 -08:00
@@ -1042,7 +1042,7 @@
 
 	usb_put_dev(ep->udev);
 	kfree(ep);
-	hep->hcpriv = 0;
+	hep->hcpriv = NULL;
 }
 
 static int
diff -Nru a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
--- a/drivers/usb/host/uhci-debug.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/host/uhci-debug.c	2005-01-19 13:44:46 -08:00
@@ -95,24 +95,25 @@
 	struct list_head *head, *tmp;
 	struct uhci_td *td;
 	int i = 0, checked = 0, prevactive = 0;
+	__le32 element = qh_element(qh);
 
 	/* Try to make sure there's enough memory */
 	if (len < 80 * 6)
 		return 0;
 
 	out += sprintf(out, "%*s[%p] link (%08x) element (%08x)\n", space, "",
-			qh, le32_to_cpu(qh->link), le32_to_cpu(qh->element));
+			qh, le32_to_cpu(qh->link), le32_to_cpu(element));
 
-	if (qh->element & UHCI_PTR_QH)
+	if (element & UHCI_PTR_QH)
 		out += sprintf(out, "%*s  Element points to QH (bug?)\n", space, "");
 
-	if (qh->element & UHCI_PTR_DEPTH)
+	if (element & UHCI_PTR_DEPTH)
 		out += sprintf(out, "%*s  Depth traverse\n", space, "");
 
-	if (qh->element & cpu_to_le32(8))
+	if (element & cpu_to_le32(8))
 		out += sprintf(out, "%*s  Bit 3 set (bug?)\n", space, "");
 
-	if (!(qh->element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH)))
+	if (!(element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH)))
 		out += sprintf(out, "%*s  Element is NULL (bug?)\n", space, "");
 
 	if (!qh->urbp) {
@@ -127,7 +128,7 @@
 
 	td = list_entry(tmp, struct uhci_td, list);
 
-	if (cpu_to_le32(td->dma_handle) != (qh->element & ~UHCI_PTR_BITS))
+	if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS))
 		out += sprintf(out, "%*s Element != First TD\n", space, "");
 
 	while (tmp != head) {
@@ -447,7 +448,7 @@
 			if (qh->link != UHCI_PTR_TERM)
 				out += sprintf(out, "    bandwidth reclamation on!\n");
 
-			if (qh->element != cpu_to_le32(uhci->term_td->dma_handle))
+			if (qh_element(qh) != cpu_to_le32(uhci->term_td->dma_handle))
 				out += sprintf(out, "    skel_term_qh element is not set to term_td!\n");
 
 			continue;
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/host/uhci-hcd.c	2005-01-19 13:44:47 -08:00
@@ -236,7 +236,7 @@
 {
 	struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
 	struct uhci_td *td;
-	u32 *plink;
+	__le32 *plink;
 
 	/* Ordering isn't important here yet since the QH hasn't been */
 	/* inserted into the schedule yet */
@@ -637,8 +637,9 @@
 /*
  * Map status to standard result codes
  *
- * <status> is (td->status & 0xF60000) [a.k.a. uhci_status_bits(td->status)]
- * Note: status does not include the TD_CTRL_NAK bit.
+ * <status> is (td_status(td) & 0xF60000), a.k.a.
+ * uhci_status_bits(td_status(td)).
+ * Note: <status> does not include the TD_CTRL_NAK bit.
  * <dir_out> is True for output TDs and False for input TDs.
  */
 static int uhci_map_status(int status, int dir_out)
@@ -843,21 +844,24 @@
 	/* The rest of the TD's (but the last) are data */
 	tmp = tmp->next;
 	while (tmp != head && tmp->next != head) {
-		td = list_entry(tmp, struct uhci_td, list);
+		unsigned int ctrlstat;
 
+		td = list_entry(tmp, struct uhci_td, list);
 		tmp = tmp->next;
 
-		status = uhci_status_bits(td_status(td));
+		ctrlstat = td_status(td);
+		status = uhci_status_bits(ctrlstat);
 		if (status & TD_CTRL_ACTIVE)
 			return -EINPROGRESS;
 
-		urb->actual_length += uhci_actual_length(td_status(td));
+		urb->actual_length += uhci_actual_length(ctrlstat);
 
 		if (status)
 			goto td_error;
 
 		/* Check to see if we received a short packet */
-		if (uhci_actual_length(td_status(td)) < uhci_expected_length(td_token(td))) {
+		if (uhci_actual_length(ctrlstat) <
+				uhci_expected_length(td_token(td))) {
 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
 				ret = -EREMOTEIO;
 				goto err;
@@ -1031,16 +1035,19 @@
 	urb->actual_length = 0;
 
 	list_for_each_entry(td, &urbp->td_list, list) {
-		status = uhci_status_bits(td_status(td));
+		unsigned int ctrlstat = td_status(td);
+
+		status = uhci_status_bits(ctrlstat);
 		if (status & TD_CTRL_ACTIVE)
 			return -EINPROGRESS;
 
-		urb->actual_length += uhci_actual_length(td_status(td));
+		urb->actual_length += uhci_actual_length(ctrlstat);
 
 		if (status)
 			goto td_error;
 
-		if (uhci_actual_length(td_status(td)) < uhci_expected_length(td_token(td))) {
+		if (uhci_actual_length(ctrlstat) <
+				uhci_expected_length(td_token(td))) {
 			if (urb->transfer_flags & URB_SHORT_NOT_OK) {
 				ret = -EREMOTEIO;
 				goto err;
@@ -1209,15 +1216,16 @@
 	i = 0;
 	list_for_each_entry(td, &urbp->td_list, list) {
 		int actlength;
+		unsigned int ctrlstat = td_status(td);
 
-		if (td_status(td) & TD_CTRL_ACTIVE)
+		if (ctrlstat & TD_CTRL_ACTIVE)
 			return -EINPROGRESS;
 
-		actlength = uhci_actual_length(td_status(td));
+		actlength = uhci_actual_length(ctrlstat);
 		urb->iso_frame_desc[i].actual_length = actlength;
 		urb->actual_length += actlength;
 
-		status = uhci_map_status(uhci_status_bits(td_status(td)),
+		status = uhci_map_status(uhci_status_bits(ctrlstat),
 				usb_pipeout(urb->pipe));
 		urb->iso_frame_desc[i].status = status;
 		if (status) {
@@ -1423,19 +1431,21 @@
 	 */
 	head = &urbp->td_list;
 	list_for_each_entry(td, head, list) {
-		if (!(td_status(td) & TD_CTRL_ACTIVE) &&
-				(uhci_actual_length(td_status(td)) <
+		unsigned int ctrlstat = td_status(td);
+
+		if (!(ctrlstat & TD_CTRL_ACTIVE) &&
+				(uhci_actual_length(ctrlstat) <
 				 uhci_expected_length(td_token(td)) ||
 				td->list.next == head))
 			usb_settoggle(urb->dev, uhci_endpoint(td_token(td)),
 				uhci_packetout(td_token(td)),
 				uhci_toggle(td_token(td)) ^ 1);
-		else if ((td_status(td) & TD_CTRL_ACTIVE) && !prevactive)
+		else if ((ctrlstat & TD_CTRL_ACTIVE) && !prevactive)
 			usb_settoggle(urb->dev, uhci_endpoint(td_token(td)),
 				uhci_packetout(td_token(td)),
 				uhci_toggle(td_token(td)));
 
-		prevactive = td_status(td) & TD_CTRL_ACTIVE;
+		prevactive = ctrlstat & TD_CTRL_ACTIVE;
 	}
 
 	uhci_delete_queued_urb(uhci, urb);
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/host/uhci-hcd.h	2005-01-19 13:44:47 -08:00
@@ -119,9 +119,19 @@
 } __attribute__((aligned(16)));
 
 /*
+ * We need a special accessor for the element pointer because it is
+ * subject to asynchronous updates by the controller
+ */
+static __le32 inline qh_element(struct uhci_qh *qh) {
+	__le32 element = qh->element;
+
+	barrier();
+	return element;
+}
+
+/*
  * for TD <status>:
  */
-#define td_status(td)		le32_to_cpu((td)->status)
 #define TD_CTRL_SPD		(1 << 29)	/* Short Packet Detect */
 #define TD_CTRL_C_ERR_MASK	(3 << 27)	/* Error Counter bits */
 #define TD_CTRL_C_ERR_SHIFT	27
@@ -202,6 +212,18 @@
 	int frame;			/* for iso: what frame? */
 	struct list_head fl_list;	/* P: uhci->frame_list_lock */
 } __attribute__((aligned(16)));
+
+/*
+ * We need a special accessor for the control/status word because it is
+ * subject to asynchronous updates by the controller
+ */
+static u32 inline td_status(struct uhci_td *td) {
+	__le32 status = td->status;
+
+	barrier();
+	return le32_to_cpu(status);
+}
+
 
 /*
  * The UHCI driver places Interrupt, Control and Bulk into QH's both
diff -Nru a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
--- a/drivers/usb/image/mdc800.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/image/mdc800.c	2005-01-19 13:44:46 -08:00
@@ -456,7 +456,7 @@
 	dbg ("(mdc800_usb_probe) called.");
 
 
-	if (mdc800->dev != 0)
+	if (mdc800->dev != NULL)
 	{
 		warn ("only one Mustek MDC800 is supported.");
 		return -ENODEV;
@@ -1045,7 +1045,7 @@
 
 cleanup_on_fail:
 
-	if (mdc800 != 0)
+	if (mdc800 != NULL)
 	{
 		err ("can't alloc memory!");
 
diff -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
--- a/drivers/usb/input/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/input/Kconfig	2005-01-19 13:44:47 -08:00
@@ -200,7 +200,7 @@
 	  The driver has been tested on a Xenarc 700TSV monitor
 	  with eGalax touchscreen.
 
-	  Have a look at http://linux.chapter7.ch/touchkit/ for
+	  Have a look at <http://linux.chapter7.ch/touchkit/> for
 	  a usage description and the required user-space stuff.
 
 	  To compile this driver as a module, choose M here: the
@@ -228,7 +228,7 @@
 	  These are RF remotes with USB receivers. 
 	  The ATI remote comes with many of ATI's All-In-Wonder video cards.
 	  The X10 "Lola" remote is available at:
-	     http://www.x10.com/products/lola_sg1.htm
+	     <http://www.x10.com/products/lola_sg1.htm>
 	  This driver provides mouse pointer, left and right mouse buttons, 
 	  and maps all the other remote buttons to keypress events.
 	  
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/input/hid-core.c	2005-01-19 13:44:47 -08:00
@@ -676,7 +676,7 @@
 	parser->device = device;
 
 	end = start + size;
-	while ((start = fetch_item(start, end, &item)) != 0) {
+	while ((start = fetch_item(start, end, &item)) != NULL) {
 
 		if (item.format != HID_ITEM_FORMAT_SHORT) {
 			dbg("unexpected long global item");
diff -Nru a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
--- a/drivers/usb/media/sn9c102.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/media/sn9c102.h	2005-01-19 13:44:46 -08:00
@@ -1,7 +1,7 @@
 /***************************************************************************
  * V4L2 driver for SN9C10x PC Camera Controllers                           *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -42,6 +42,7 @@
 #define SN9C102_DEBUG_LEVEL       2
 #define SN9C102_MAX_DEVICES       64
 #define SN9C102_PRESERVE_IMGSCALE 0
+#define SN9C102_FORCE_MUNMAP      0
 #define SN9C102_MAX_FRAMES        32
 #define SN9C102_URBS              2
 #define SN9C102_ISO_PACKETS       7
@@ -55,8 +56,8 @@
 #define SN9C102_MODULE_AUTHOR   "(C) 2004 Luca Risolia"
 #define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
 #define SN9C102_MODULE_LICENSE  "GPL"
-#define SN9C102_MODULE_VERSION  "1:1.20"
-#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 20)
+#define SN9C102_MODULE_VERSION  "1:1.22"
+#define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 22)
 
 enum sn9c102_bridge {
 	BRIDGE_SN9C101 = 0x01,
@@ -109,6 +110,10 @@
 	sn9c102_sof_header_t frame_header;
 };
 
+struct sn9c102_module_param {
+	u8 force_munmap;
+};
+
 static DECLARE_MUTEX(sn9c102_sysfs_lock);
 static DECLARE_RWSEM(sn9c102_disconnect);
 
@@ -137,6 +142,8 @@
 	struct sn9c102_sysfs_attr sysfs;
 	sn9c102_sof_header_t sof_header;
 	u16 reg[32];
+
+	struct sn9c102_module_param module_param;
 
 	enum sn9c102_dev_state state;
 	u8 users;
diff -Nru a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
--- a/drivers/usb/media/sn9c102_core.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/usb/media/sn9c102_core.c	2005-01-19 13:44:45 -08:00
@@ -1,7 +1,7 @@
 /***************************************************************************
  * V4L2 driver for SN9C10x PC Camera Controllers                           *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/page-flags.h>
+#include <linux/byteorder/generic.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
@@ -65,6 +66,20 @@
                  "\none and for every other camera."
                  "\n");
 
+static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] = 
+                               SN9C102_FORCE_MUNMAP};
+module_param_array(force_munmap, bool, NULL, 0444);
+MODULE_PARM_DESC(force_munmap,
+                 "\n<0|1[,...]> Force the application to unmap previously "
+                 "\nmapped buffer memory before calling any VIDIOC_S_CROP or "
+                 "\nVIDIOC_S_FMT ioctl's. Not all the applications support "
+                 "\nthis feature. This parameter is specific for each "
+                 "\ndetected camera."
+                 "\n 0 = do not force memory unmapping"
+                 "\n 1 = force memory unmapping (save memory)"
+                 "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
+                 "\n");
+
 #ifdef SN9C102_DEBUG
 static unsigned short debug = SN9C102_DEBUG_LEVEL;
 module_param(debug, ushort, 0644);
@@ -141,10 +156,16 @@
 }
 
 
-static u32 sn9c102_request_buffers(struct sn9c102_device* cam, u32 count)
+static u32 
+sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, 
+                        enum sn9c102_io_method io)
 {
 	struct v4l2_pix_format* p = &(cam->sensor->pix_format);
-	const size_t imagesize = (p->width * p->height * p->priv)/8;
+	struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
+	const size_t imagesize = cam->module_param.force_munmap ||
+	                         io == IO_READ ?
+	                         (p->width * p->height * p->priv)/8 :
+	                         (r->width * r->height * p->priv)/8;
 	void* buff = NULL;
 	u32 i;
 
@@ -911,11 +932,6 @@
 		return -ENODEV;
 	}
 
-	if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
-		up(&sn9c102_sysfs_lock);
-		return -ENOSYS;
-	}
-
 	value = sn9c102_strtou8(buf, len, &count);
 	if (!count) {
 		up(&sn9c102_sysfs_lock);
@@ -1047,6 +1063,11 @@
 		return -ENODEV;
 	}
 
+	if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
+		up(&sn9c102_sysfs_lock);
+		return -ENOSYS;
+	}
+
 	value = sn9c102_strtou8(buf, len, &count);
 	if (!count) {
 		up(&sn9c102_sysfs_lock);
@@ -1514,7 +1535,7 @@
 	}
 
 	if (cam->io == IO_NONE) {
-		if (!sn9c102_request_buffers(cam, cam->nreadbuffers)) {
+		if (!sn9c102_request_buffers(cam,cam->nreadbuffers, IO_READ)) {
 			DBG(1, "read() failed, not enough memory")
 			up(&cam->fileop_sem);
 			return -ENOMEM;
@@ -1594,7 +1615,7 @@
 	}
 
 	if (cam->io == IO_NONE) {
-		if (!sn9c102_request_buffers(cam, 2)) {
+		if (!sn9c102_request_buffers(cam, 2, IO_READ)) {
 			DBG(1, "poll() failed, not enough memory")
 			goto error;
 		}
@@ -1811,6 +1832,7 @@
 		return err;
 	}
 
+	case VIDIOC_S_CTRL_OLD:
 	case VIDIOC_S_CTRL:
 	{
 		struct sn9c102_sensor* s = cam->sensor;
@@ -1895,12 +1917,13 @@
 		if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 			return -EINVAL;
 
-		for (i = 0; i < cam->nbuffers; i++)
-			if (cam->frame[i].vma_use_count) {
-				DBG(3, "VIDIOC_S_CROP failed. "
-				       "Unmap the buffers first.")
-				return -EINVAL;
-			}
+		if (cam->module_param.force_munmap)
+			for (i = 0; i < cam->nbuffers; i++)
+				if (cam->frame[i].vma_use_count) {
+					DBG(3, "VIDIOC_S_CROP failed. "
+					       "Unmap the buffers first.")
+					return -EINVAL;
+				}
 
 		/* Preserve R,G or B origin */
 		rect->left = (s->_rect.left & 1L) ?
@@ -1947,7 +1970,8 @@
 			return -EFAULT;
 		}
 
-		sn9c102_release_buffers(cam);
+		if (cam->module_param.force_munmap)
+			sn9c102_release_buffers(cam);
 
 		err = sn9c102_set_crop(cam, rect);
 		if (s->set_crop)
@@ -1966,7 +1990,9 @@
 		s->pix_format.height = rect->height/scale;
 		memcpy(&(s->_rect), rect, sizeof(*rect));
 
-		if (nbuffers != sn9c102_request_buffers(cam, nbuffers)) {
+		if (cam->module_param.force_munmap &&
+		    nbuffers != sn9c102_request_buffers(cam, nbuffers,
+		                                        cam->io)) {
 			cam->state |= DEV_MISCONFIGURED;
 			DBG(1, "VIDIOC_S_CROP failed because of not enough "
 			       "memory. To use the camera, close and open "
@@ -2103,12 +2129,13 @@
 			return 0;
 		}
 
-		for (i = 0; i < cam->nbuffers; i++)
-			if (cam->frame[i].vma_use_count) {
-				DBG(3, "VIDIOC_S_FMT failed. "
-				       "Unmap the buffers first.")
-				return -EINVAL;
-			}
+		if (cam->module_param.force_munmap)
+			for (i = 0; i < cam->nbuffers; i++)
+				if (cam->frame[i].vma_use_count) {
+					DBG(3, "VIDIOC_S_FMT failed. "
+					       "Unmap the buffers first.")
+					return -EINVAL;
+				}
 
 		if (cam->stream == STREAM_ON)
 			if ((err = sn9c102_stream_interrupt(cam)))
@@ -2119,7 +2146,8 @@
 			return -EFAULT;
 		}
 
-		sn9c102_release_buffers(cam);
+		if (cam->module_param.force_munmap)
+			sn9c102_release_buffers(cam);
 
 		err += sn9c102_set_pix_format(cam, pix);
 		err += sn9c102_set_crop(cam, &rect);
@@ -2140,7 +2168,9 @@
 		memcpy(pfmt, pix, sizeof(*pix));
 		memcpy(&(s->_rect), &rect, sizeof(rect));
 
-		if (nbuffers != sn9c102_request_buffers(cam, nbuffers)) {
+		if (cam->module_param.force_munmap &&
+		    nbuffers != sn9c102_request_buffers(cam, nbuffers,
+		                                        cam->io)) {
 			cam->state |= DEV_MISCONFIGURED;
 			DBG(1, "VIDIOC_S_FMT failed because of not enough "
 			       "memory. To use the camera, close and open "
@@ -2228,7 +2258,8 @@
 
 		sn9c102_release_buffers(cam);
 		if (rb.count)
-			rb.count = sn9c102_request_buffers(cam, rb.count);
+			rb.count = sn9c102_request_buffers(cam, rb.count,
+			                                   IO_MMAP);
 
 		if (copy_to_user(arg, &rb, sizeof(rb))) {
 			sn9c102_release_buffers(cam);
@@ -2402,6 +2433,7 @@
 		return 0;
 	}
 
+	case VIDIOC_S_PARM_OLD:
 	case VIDIOC_S_PARM:
 	{
 		struct v4l2_streamparm sp;
@@ -2496,8 +2528,10 @@
 
 	n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]);
 	for (i = 0; i < n-1; i++)
-		if (le16_to_cpu(udev->descriptor.idVendor) == sn9c102_id_table[i].idVendor &&
-		    le16_to_cpu(udev->descriptor.idProduct) == sn9c102_id_table[i].idProduct)
+		if (le16_to_cpu(udev->descriptor.idVendor) == 
+		    sn9c102_id_table[i].idVendor &&
+		    le16_to_cpu(udev->descriptor.idProduct) ==
+		    sn9c102_id_table[i].idProduct)
 			break;
 	if (i == n-1)
 		return -ENODEV;
@@ -2595,6 +2629,10 @@
 	}
 
 	DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor)
+
+	cam->module_param.force_munmap = force_munmap[dev_nr];
+
+	dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
 
 	sn9c102_create_sysfs(cam);
 	DBG(2, "Optional device control through 'sysfs' interface ready")
diff -Nru a/drivers/usb/media/sn9c102_hv7131d.c b/drivers/usb/media/sn9c102_hv7131d.c
--- a/drivers/usb/media/sn9c102_hv7131d.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/usb/media/sn9c102_hv7131d.c	2005-01-19 13:44:48 -08:00
@@ -2,7 +2,7 @@
  * Plug-in for HV7131D image sensor connected to the SN9C10x PC Camera     *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff -Nru a/drivers/usb/media/sn9c102_mi0343.c b/drivers/usb/media/sn9c102_mi0343.c
--- a/drivers/usb/media/sn9c102_mi0343.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/media/sn9c102_mi0343.c	2005-01-19 13:44:47 -08:00
@@ -2,7 +2,7 @@
  * Plug-in for MI-0343 image sensor connected to the SN9C10x PC Camera     *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff -Nru a/drivers/usb/media/sn9c102_pas106b.c b/drivers/usb/media/sn9c102_pas106b.c
--- a/drivers/usb/media/sn9c102_pas106b.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/usb/media/sn9c102_pas106b.c	2005-01-19 13:44:45 -08:00
@@ -2,7 +2,7 @@
  * Plug-in for PAS106B image sensor connected to the SN9C10x PC Camera     *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff -Nru a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
--- a/drivers/usb/media/sn9c102_sensor.h	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/media/sn9c102_sensor.h	2005-01-19 13:44:46 -08:00
@@ -1,7 +1,7 @@
 /***************************************************************************
  * API for image sensors connected to the SN9C10x PC Camera Controllers    *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff -Nru a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
--- a/drivers/usb/media/sn9c102_tas5110c1b.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c	2005-01-19 13:44:45 -08:00
@@ -2,7 +2,7 @@
  * Plug-in for TAS5110C1B image sensor connected to the SN9C10x PC Camera  *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff -Nru a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
--- a/drivers/usb/media/sn9c102_tas5130d1b.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c	2005-01-19 13:44:47 -08:00
@@ -2,7 +2,7 @@
  * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera  *
  * Controllers                                                             *
  *                                                                         *
- * Copyright (C) 2004 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff -Nru a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
--- a/drivers/usb/misc/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/misc/Kconfig	2005-01-19 13:44:47 -08:00
@@ -123,11 +123,24 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called phidgetservo.
 
+config USB_IDMOUSE
+	tristate "Siemens ID USB Mouse Fingerprint sensor support"
+	depends on USB
+	help
+	  Say Y here if you want to use the fingerprint sensor on
+	  the Siemens ID Mouse. There is also a Siemens ID Mouse
+	  _Professional_, which has not been tested with this driver,
+	  but uses the same sensor and may therefore work.
+
+	  This driver creates an entry "/dev/idmouseX" or "/dev/usb/idmouseX",
+	  which can be used by, e.g.,"cat /dev/idmouse0 > fingerprint.pnm".
+
+	  See also <http://www.fs.tum.de/~echtler/idmouse/>.
+
 config USB_TEST
 	tristate "USB testing driver (DEVELOPMENT)"
 	depends on USB && USB_DEVICEFS && EXPERIMENTAL
 	help
-
 	  This driver is for testing host controller software.  It is used
 	  with specialized device firmware for regression and stress testing,
 	  to help prevent problems from cropping up with "real" drivers.
diff -Nru a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
--- a/drivers/usb/misc/Makefile	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/misc/Makefile	2005-01-19 13:44:46 -08:00
@@ -7,6 +7,7 @@
 obj-$(CONFIG_USB_CYTHERM)	+= cytherm.o
 obj-$(CONFIG_USB_EMI26)		+= emi26.o
 obj-$(CONFIG_USB_EMI62)		+= emi62.o
+obj-$(CONFIG_USB_IDMOUSE)	+= idmouse.o
 obj-$(CONFIG_USB_LCD)		+= usblcd.o
 obj-$(CONFIG_USB_LED)		+= usbled.o
 obj-$(CONFIG_USB_LEGOTOWER)	+= legousbtower.o
diff -Nru a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/usb/misc/idmouse.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,442 @@
+/* Siemens ID Mouse driver v0.5
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 2 of
+  the License, or (at your option) any later version.
+
+  Copyright (C) 2004-5 by Florian 'Floe' Echtler  <echtler@fs.tum.de>
+                      and Andreas  'ad'  Deresch <aderesch@fs.tum.de>
+
+  Derived from the USB Skeleton driver 1.1,
+  Copyright (C) 2003 Greg Kroah-Hartman (greg@kroah.com)
+
+*/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/completion.h>
+#include <asm/uaccess.h>
+#include <linux/usb.h>
+
+#define WIDTH 225
+#define HEIGHT 288
+#define HEADER "P5 225 288 255 "
+#define IMGSIZE ((WIDTH * HEIGHT) + sizeof(HEADER)-1)
+
+/* Version Information */
+#define DRIVER_VERSION "0.5"
+#define DRIVER_SHORT   "idmouse"
+#define DRIVER_AUTHOR  "Florian 'Floe' Echtler <echtler@fs.tum.de>"
+#define DRIVER_DESC    "Siemens ID Mouse FingerTIP Sensor Driver"
+
+/* Siemens ID Mouse */
+#define USB_IDMOUSE_VENDOR_ID  0x0681
+#define USB_IDMOUSE_PRODUCT_ID 0x0005
+
+/* we still need a minor number */
+#define USB_IDMOUSE_MINOR_BASE 132
+
+static struct usb_device_id idmouse_table[] = {
+	{USB_DEVICE(USB_IDMOUSE_VENDOR_ID, USB_IDMOUSE_PRODUCT_ID)},
+	{} /* null entry at the end */
+};
+
+MODULE_DEVICE_TABLE(usb, idmouse_table);
+
+/* structure to hold all of our device specific stuff */
+struct usb_idmouse {
+
+	struct usb_device *udev; /* save off the usb device pointer */
+	struct usb_interface *interface; /* the interface for this device */
+
+	unsigned char *bulk_in_buffer; /* the buffer to receive data */
+	size_t bulk_in_size; /* the size of the receive buffer */
+	__u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
+
+	int open; /* if the port is open or not */
+	int present; /* if the device is not disconnected */
+	struct semaphore sem; /* locks this structure */
+
+};
+
+/* local function prototypes */
+static ssize_t idmouse_read(struct file *file, char __user *buffer,
+				size_t count, loff_t * ppos);
+
+static int idmouse_open(struct inode *inode, struct file *file);
+static int idmouse_release(struct inode *inode, struct file *file);
+
+static int idmouse_probe(struct usb_interface *interface,
+				const struct usb_device_id *id);
+
+static void idmouse_disconnect(struct usb_interface *interface);
+
+/* file operation pointers */
+static struct file_operations idmouse_fops = {
+	.owner = THIS_MODULE,
+	.read = idmouse_read,
+	.open = idmouse_open,
+	.release = idmouse_release,
+};
+
+/* class driver information for devfs */
+static struct usb_class_driver idmouse_class = {
+	.name = "usb/idmouse%d",
+	.fops = &idmouse_fops,
+	.mode = S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH, /* filemode (char, 444) */
+	.minor_base = USB_IDMOUSE_MINOR_BASE,
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver idmouse_driver = {
+	.owner = THIS_MODULE,
+	.name = DRIVER_SHORT,
+	.probe = idmouse_probe,
+	.disconnect = idmouse_disconnect,
+	.id_table = idmouse_table,
+};
+
+// prevent races between open() and disconnect()
+static DECLARE_MUTEX(disconnect_sem);
+
+static int idmouse_create_image(struct usb_idmouse *dev)
+{
+	int bytes_read = 0;
+	int bulk_read = 0;
+	int result = 0;
+
+	if (dev->bulk_in_size < sizeof(HEADER))
+		return -ENOMEM;
+
+	memcpy(dev->bulk_in_buffer,HEADER,sizeof(HEADER)-1);
+	bytes_read += sizeof(HEADER)-1;
+
+	/* Dump the setup packets. Yes, they are uncommented, simply 
+	   because they were sniffed under Windows using SnoopyPro.
+	   I _guess_ that 0x22 is a kind of reset command and 0x21 
+	   means init..
+	*/
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x21, 0x42, 0x0001, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x20, 0x42, 0x0001, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x22, 0x42, 0x0000, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x21, 0x42, 0x0001, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x20, 0x42, 0x0001, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x20, 0x42, 0x0000, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+
+	/* loop over a blocking bulk read to get data from the device */
+	while (bytes_read < IMGSIZE) {
+		result = usb_bulk_msg (dev->udev,
+				usb_rcvbulkpipe (dev->udev, dev->bulk_in_endpointAddr),
+				dev->bulk_in_buffer + bytes_read,
+				dev->bulk_in_size, &bulk_read, HZ * 5);
+		if (result < 0)
+			return result;
+		if (signal_pending(current))
+			return -EINTR;
+		bytes_read += bulk_read;
+	}
+
+	/* reset the device */
+	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
+				0x22, 0x42, 0x0000, 0x0002, NULL, 0, HZ);
+	if (result < 0)
+		return result;
+
+	/* should be IMGSIZE == 64815 */
+	dbg("read %d bytes fingerprint data", bytes_read);
+	return 0;
+}
+
+static inline void idmouse_delete(struct usb_idmouse *dev)
+{
+	kfree(dev->bulk_in_buffer);
+	kfree(dev);
+}
+
+static int idmouse_open(struct inode *inode, struct file *file)
+{
+	struct usb_idmouse *dev = NULL;
+	struct usb_interface *interface;
+	int result = 0;
+
+	/* prevent disconnects */
+	down(&disconnect_sem);
+
+	/* get the interface from minor number and driver information */
+	interface = usb_find_interface (&idmouse_driver, iminor (inode));
+	if (!interface) {
+		up(&disconnect_sem);
+		return -ENODEV;
+	}
+	/* get the device information block from the interface */
+	dev = usb_get_intfdata(interface);
+	if (!dev) {
+		up(&disconnect_sem);
+		return -ENODEV;
+	}
+
+	/* lock this device */
+	down(&dev->sem);
+
+	/* check if already open */
+	if (dev->open) {
+
+		/* already open, so fail */
+		result = -EBUSY;
+
+	} else {
+
+		/* create a new image and check for success */
+		result = idmouse_create_image (dev);
+		if (result)
+			goto error;
+
+		/* increment our usage count for the driver */
+		++dev->open;
+
+		/* save our object in the file's private structure */
+		file->private_data = dev;
+
+	} 
+
+error:
+
+	/* unlock this device */
+	up(&dev->sem);
+
+	/* unlock the disconnect semaphore */
+	up(&disconnect_sem);
+	return result;
+}
+
+static int idmouse_release(struct inode *inode, struct file *file)
+{
+	struct usb_idmouse *dev;
+
+	/* prevent a race condition with open() */
+	down(&disconnect_sem);
+
+	dev = (struct usb_idmouse *) file->private_data;
+
+	if (dev == NULL) {
+		up(&disconnect_sem);
+		return -ENODEV;
+	}
+
+	/* lock our device */
+	down(&dev->sem);
+
+	/* are we really open? */
+	if (dev->open <= 0) {
+		up(&dev->sem);
+		up(&disconnect_sem);
+		return -ENODEV;
+	}
+
+	--dev->open;
+
+	if (!dev->present) {
+		/* the device was unplugged before the file was released */
+		up(&dev->sem);
+		idmouse_delete(dev);
+		up(&disconnect_sem);
+		return 0;
+	}
+
+	up(&dev->sem);
+	up(&disconnect_sem);
+	return 0;
+}
+
+static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count,
+				loff_t * ppos)
+{
+	struct usb_idmouse *dev;
+	int result = 0;
+
+	dev = (struct usb_idmouse *) file->private_data;
+
+	// lock this object
+	down (&dev->sem);
+
+	// verify that the device wasn't unplugged
+	if (!dev->present) {
+		up (&dev->sem);
+		return -ENODEV;
+	}
+
+	if (*ppos >= IMGSIZE) {
+		up (&dev->sem);
+		return 0;
+	}
+
+	count = min ((loff_t)count, IMGSIZE - (*ppos));
+
+	if (copy_to_user (buffer, dev->bulk_in_buffer + *ppos, count)) {
+		result = -EFAULT;
+	} else {
+		result = count;
+		*ppos += count;
+	}
+
+	// unlock the device 
+	up(&dev->sem);
+	return result;
+}
+
+static int idmouse_probe(struct usb_interface *interface,
+				const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(interface);
+	struct usb_idmouse *dev = NULL;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	size_t buffer_size;
+	int result;
+
+	/* check if we have gotten the data or the hid interface */
+	iface_desc = &interface->altsetting[0];
+	if (iface_desc->desc.bInterfaceClass != 0x0A)
+		return -ENODEV;
+
+	/* allocate memory for our device state and initialize it */
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL)
+		return -ENOMEM;
+	memset(dev, 0x00, sizeof(*dev));
+
+	init_MUTEX(&dev->sem);
+	dev->udev = udev;
+	dev->interface = interface;
+
+	/* set up the endpoint information - use only the first bulk-in endpoint */
+	endpoint = &iface_desc->endpoint[0].desc;
+	if (!dev->bulk_in_endpointAddr
+		&& (endpoint->bEndpointAddress & USB_DIR_IN)
+		&& ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+		USB_ENDPOINT_XFER_BULK)) {
+
+		/* we found a bulk in endpoint */
+		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+		dev->bulk_in_size = buffer_size;
+		dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+		dev->bulk_in_buffer =
+			kmalloc(IMGSIZE + buffer_size, GFP_KERNEL);
+
+		if (!dev->bulk_in_buffer) {
+			err("Unable to allocate input buffer.");
+			idmouse_delete(dev);
+			return -ENOMEM;
+		}
+	}
+
+	if (!(dev->bulk_in_endpointAddr)) {
+		err("Unable to find bulk-in endpoint.");
+		idmouse_delete(dev);
+		return -ENODEV;
+	}
+	/* allow device read, write and ioctl */
+	dev->present = 1;
+
+	/* we can register the device now, as it is ready */
+	usb_set_intfdata(interface, dev);
+	result = usb_register_dev(interface, &idmouse_class);
+	if (result) {
+		/* something prevented us from registering this device */
+		err("Unble to allocate minor number.");
+		usb_set_intfdata(interface, NULL);
+		idmouse_delete(dev);
+		return result;
+	}
+
+	/* be noisy */
+	dev_info(&interface->dev,"%s now attached\n",DRIVER_DESC);
+
+	return 0;
+}
+
+static void idmouse_disconnect(struct usb_interface *interface)
+{
+	struct usb_idmouse *dev;
+
+	/* prevent races with open() */
+	down(&disconnect_sem);
+
+	/* get device structure */
+	dev = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	/* lock it */
+	down(&dev->sem);
+
+	/* give back our minor */
+	usb_deregister_dev(interface, &idmouse_class);
+
+	/* prevent device read, write and ioctl */
+	dev->present = 0;
+
+	/* unlock */
+	up(&dev->sem);
+
+	/* if the device is opened, idmouse_release will clean this up */
+	if (!dev->open)
+		idmouse_delete(dev);
+
+	up(&disconnect_sem);
+
+	info("%s disconnected", DRIVER_DESC);
+}
+
+static int __init usb_idmouse_init(void)
+{
+	int result;
+
+	info(DRIVER_DESC " " DRIVER_VERSION);
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&idmouse_driver);
+	if (result)
+		err("Unable to register device (error %d).", result);
+
+	return result;
+}
+
+static void __exit usb_idmouse_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&idmouse_driver);
+}
+
+module_init(usb_idmouse_init);
+module_exit(usb_idmouse_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/misc/usbtest.c	2005-01-19 13:44:47 -08:00
@@ -1204,7 +1204,7 @@
 	struct urb	*urb;
 
 	urb = simple_alloc_urb (testdev_to_usbdev (dev), 0, 512);
-	if (urb == 0)
+	if (urb == NULL)
 		return -ENOMEM;
 
 	if (dev->in_pipe) {
@@ -1862,7 +1862,7 @@
 	dev->intf = intf;
 
 	/* cacheline-aligned scratch for i/o */
-	if ((dev->buf = kmalloc (TBUF_SIZE, SLAB_KERNEL)) == 0) {
+	if ((dev->buf = kmalloc (TBUF_SIZE, SLAB_KERNEL)) == NULL) {
 		kfree (dev);
 		return -ENOMEM;
 	}
diff -Nru a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
--- a/drivers/usb/net/pegasus.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/usb/net/pegasus.c	2005-01-19 13:44:48 -08:00
@@ -28,6 +28,8 @@
  * 			is out of the interrupt routine.
  */
 
+#undef	DEBUG
+
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -45,7 +47,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.5.12 (2003/06/06)"
+#define DRIVER_VERSION "v0.5.12 (2005/01/13)"
 #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -712,11 +714,11 @@
 {
 	pegasus_t *pegasus = urb->context;
 	struct net_device *net;
-	__u8 *d;
 	int status;
 
 	if (!pegasus)
 		return;
+	net = pegasus->net;
 
 	switch (urb->status) {
 	case 0:
@@ -726,36 +728,50 @@
 	case -ESHUTDOWN:
 		return;
 	default:
-		info("intr status %d", urb->status);
+		/* some Pegasus-I products report LOTS of data
+		 * toggle errors... avoid log spamming
+		 */
+		pr_debug("%s: intr status %d\n", net->name, urb->status);
 	}
 
-	d = urb->transfer_buffer;
-	net = pegasus->net;
-	if (d[0] & 0xfc) {
-		pegasus->stats.tx_errors++;
-		if (d[0] & TX_UNDERRUN)
-			pegasus->stats.tx_fifo_errors++;
-		if (d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT))
-			pegasus->stats.tx_aborted_errors++;
-		if (d[0] & LATE_COL)
-			pegasus->stats.tx_window_errors++;
-		if (d[5] & LINK_STATUS) {
-			netif_carrier_on(net);
-		} else {
-			pegasus->stats.tx_carrier_errors++;
-			netif_carrier_off(net);	
+	if (urb->actual_length >= 6) {
+		u8	* d = urb->transfer_buffer;
+
+		/* byte 0 == tx_status1, reg 2B */
+		if (d[0] & (TX_UNDERRUN|EXCESSIVE_COL
+					|LATE_COL|JABBER_TIMEOUT)) {
+			pegasus->stats.tx_errors++;
+			if (d[0] & TX_UNDERRUN)
+				pegasus->stats.tx_fifo_errors++;
+			if (d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT))
+				pegasus->stats.tx_aborted_errors++;
+			if (d[0] & LATE_COL)
+				pegasus->stats.tx_window_errors++;
 		}
+
+		/* d[5].LINK_STATUS lies on some adapters.
+		 * d[0].NO_CARRIER kicks in only with failed TX.
+		 * ... so monitoring with MII may be safest.
+		 */
+		if (d[0] & NO_CARRIER)
+			netif_carrier_off(net);	
+		else
+			netif_carrier_on(net);
+
+		/* bytes 3-4 == rx_lostpkt, reg 2E/2F */
+		pegasus->stats.rx_missed_errors += ((d[3] & 0x7f) << 8) | d[4];
 	}
 
 	status = usb_submit_urb(urb, SLAB_ATOMIC);
 	if (status)
-		err("%s: can't resubmit interrupt urb, %d", net->name, status);
+		printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n",
+				net->name, status);
 }
 
 static void pegasus_tx_timeout(struct net_device *net)
 {
 	pegasus_t *pegasus = netdev_priv(net);
-	warn("%s: Tx timed out.", net->name);
+	printk(KERN_WARNING "%s: tx timeout\n", net->name);
 	pegasus->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
 	usb_unlink_urb(pegasus->tx_urb);
 	pegasus->stats.tx_errors++;
@@ -948,14 +964,57 @@
 	usb_make_path(pegasus->usb, info->bus_info, sizeof (info->bus_info));
 }
 
-#ifdef	CONFIG_MII
-static int pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+/* also handles three patterns of some kind in hardware */
+#define	WOL_SUPPORTED	(WAKE_MAGIC|WAKE_PHY)
+
+static void
+pegasus_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	pegasus_t	*pegasus = netdev_priv(dev);
+
+	wol->supported = WAKE_MAGIC | WAKE_PHY;
+	wol->wolopts = pegasus->wolopts;
+}
+
+static int
+pegasus_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	pegasus_t	*pegasus = netdev_priv(dev);
+	u8		reg78 = 0x04;
+	
+	if (wol->wolopts & ~WOL_SUPPORTED)
+		return -EINVAL;
+
+	if (wol->wolopts & WAKE_MAGIC)
+		reg78 |= 0x80;
+	if (wol->wolopts & WAKE_PHY)
+		reg78 |= 0x40;
+	if (wol->wolopts)
+		pegasus->eth_regs[0] |= 0x10;
+	else
+		pegasus->eth_regs[0] &= ~0x10;
+	pegasus->wolopts = wol->wolopts;
+	return set_register(pegasus, WakeupControl, reg78);
+}
+
+static inline void
+pegasus_reset_wol(struct net_device *dev)
+{
+	struct ethtool_wolinfo wol;
+	
+	memset(&wol, 0, sizeof wol);
+	(void) pegasus_set_wol(dev, &wol);
+}
+
+static int
+pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	pegasus_t *pegasus = netdev_priv(dev);
 	mii_ethtool_gset(&pegasus->mii, ecmd);
 	return 0;
 }
-static int pegasus_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+static int
+pegasus_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	pegasus_t *pegasus = netdev_priv(dev);
 	return mii_ethtool_sset(&pegasus->mii, ecmd);
@@ -975,19 +1034,14 @@
 
 static u32 pegasus_get_msglevel(struct net_device *dev)
 {
-	/*
-	 * pegasus_t *pegasus = netdev_priv(dev);
-	 * return pegasus->msg_enable; FIXME
-	 */
-	return 0;
+	pegasus_t *pegasus = netdev_priv(dev);
+	return pegasus->msg_level;
 }
 
 static void pegasus_set_msglevel(struct net_device *dev, u32 v)
 {
-	/*
-	 * pegasus_t *pegasus = netdev_priv(dev);
-	 * pegasus->msg_enable = edata.data; FIXME
-	 */
+	pegasus_t *pegasus = netdev_priv(dev);
+	pegasus->msg_level = v;
 }
 
 static struct ethtool_ops ops = {
@@ -998,58 +1052,10 @@
 	.get_link = pegasus_get_link,
 	.get_msglevel = pegasus_get_msglevel,
 	.set_msglevel = pegasus_set_msglevel,
+	.get_wol = pegasus_get_wol,
+	.set_wol = pegasus_set_wol,
 };
 
-#else
-
-static int pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-	pegasus_t *pegasus = netdev_priv(dev);
-	short lpa, bmcr;
-	u8 port;
-
-	ecmd->supported = (SUPPORTED_10baseT_Half |
-			  SUPPORTED_10baseT_Full |
-			  SUPPORTED_100baseT_Half |
-			  SUPPORTED_100baseT_Full |
-			  SUPPORTED_Autoneg |
-			  SUPPORTED_TP | SUPPORTED_MII);
-	get_registers(pegasus, Reg7b, 1, &port);
-	if (port == 0)
-		ecmd->port = PORT_MII;
-	else
-		ecmd->port = PORT_TP;
-	ecmd->transceiver = XCVR_INTERNAL;
-	ecmd->phy_address = pegasus->phy;
-	read_mii_word(pegasus, pegasus->phy, MII_BMCR, &bmcr);
-	read_mii_word(pegasus, pegasus->phy, MII_LPA, &lpa);
-	if (bmcr & BMCR_ANENABLE) {
-		ecmd->autoneg = AUTONEG_ENABLE;
-		ecmd->speed = lpa & (LPA_100HALF | LPA_100FULL) ?
-		    SPEED_100 : SPEED_10;
-		if (ecmd->speed == SPEED_100)
-			ecmd->duplex = lpa & LPA_100FULL ?
-			    DUPLEX_FULL : DUPLEX_HALF;
-		else
-			ecmd->duplex = lpa & LPA_10FULL ?
-			    DUPLEX_FULL : DUPLEX_HALF;
-	} else {
-		ecmd->autoneg = AUTONEG_DISABLE;
-		ecmd->speed = bmcr & BMCR_SPEED100 ?
-		    SPEED_100 : SPEED_10;
-		ecmd->duplex = bmcr & BMCR_FULLDPLX ?
-		    DUPLEX_FULL : DUPLEX_HALF;
-	}
-	return 0;
-}
-
-static struct ethtool_ops ops = {
-	.get_drvinfo = pegasus_get_drvinfo,
-	.get_settings = pegasus_get_settings,
-	.get_link = ethtool_op_get_link,
-};
-#endif
-
 static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 {
 	__u16 *data = (__u16 *) & rq->ifr_ifru;
@@ -1081,12 +1087,12 @@
 
 	if (net->flags & IFF_PROMISC) {
 		pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
-		info("%s: Promiscuous mode enabled", net->name);
+		pr_info("%s: Promiscuous mode enabled.\n", net->name);
 	} else if ((net->mc_count > multicast_filter_limit) ||
 		   (net->flags & IFF_ALLMULTI)) {
 		pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
-		info("%s set allmulti", net->name);
+		pr_info("%s: set allmulti\n", net->name);
 	} else {
 		pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
@@ -1180,7 +1186,6 @@
 	net->hard_start_xmit = pegasus_start_xmit;
 	net->set_multicast_list = pegasus_set_multicast;
 	net->get_stats = pegasus_netdev_stats;
-	net->mtu = PEGASUS_MTU;
 	SET_ETHTOOL_OPS(net, &ops);
 	pegasus->mii.dev = net;
 	pegasus->mii.mdio_read = mdio_read;
@@ -1192,27 +1197,28 @@
 	pegasus->features = usb_dev_id[dev_index].private;
 	get_interrupt_interval(pegasus);
 	if (reset_mac(pegasus)) {
-		err("can't reset MAC");
+		dev_err(&intf->dev, "can't reset MAC\n");
 		res = -EIO;
 		goto out2;
 	}
 	set_ethernet_addr(pegasus);
 	fill_skb_pool(pegasus);
 	if (pegasus->features & PEGASUS_II) {
-		info("setup Pegasus II specific registers");
+		dev_info(&intf->dev, "setup Pegasus II specific registers\n");
 		setup_pegasus_II(pegasus);
 	}
 	pegasus->phy = mii_phy_probe(pegasus);
 	if (pegasus->phy == 0xff) {
-		warn("can't locate MII phy, using default");
+		dev_warn(&intf->dev, "can't locate MII phy, using default\n");
 		pegasus->phy = 1;
 	}
 	usb_set_intfdata(intf, pegasus);
 	SET_NETDEV_DEV(net, &intf->dev);
+	pegasus_reset_wol(net);
 	res = register_netdev(net);
 	if (res)
 		goto out3;
-	printk("%s: %s\n", net->name, usb_dev_id[dev_index].name);
+	pr_info("%s: %s\n", net->name, usb_dev_id[dev_index].name);
 	return 0;
 
 out3:
@@ -1247,16 +1253,34 @@
 	free_netdev(pegasus->net);
 }
 
+static int pegasus_suspend (struct usb_interface *intf, u32 state)
+{
+	struct pegasus *pegasus = usb_get_intfdata(intf);
+	
+	netif_device_detach (pegasus->net);
+	return 0;
+}
+
+static int pegasus_resume (struct usb_interface *intf)
+{
+	struct pegasus *pegasus = usb_get_intfdata(intf);
+
+	netif_device_attach (pegasus->net);
+	return 0;
+}
+
 static struct usb_driver pegasus_driver = {
 	.name = driver_name,
 	.probe = pegasus_probe,
 	.disconnect = pegasus_disconnect,
 	.id_table = pegasus_ids,
+	.suspend = pegasus_suspend,
+	.resume = pegasus_resume,
 };
 
 static int __init pegasus_init(void)
 {
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION);
 	return usb_register(&pegasus_driver);
 }
 
diff -Nru a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
--- a/drivers/usb/net/pegasus.h	2005-01-19 13:44:48 -08:00
+++ b/drivers/usb/net/pegasus.h	2005-01-19 13:44:48 -08:00
@@ -76,6 +76,7 @@
 	EthTxStat0 = 0x2b,
 	EthTxStat1 = 0x2c,
 	EthRxStat = 0x2d,
+	WakeupControl = 0x78,
 	Reg7b = 0x7b,
 	Gpio0 = 0x7e,
 	Gpio1 = 0x7f,
@@ -90,6 +91,8 @@
 	struct mii_if_info	mii;
 	unsigned		flags;
 	unsigned		features;
+	u32			msg_level;
+	u32			wolopts;
 	int			dev_index;
 	int			intr_interval;
 	struct tasklet_struct	rx_tl;
diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
--- a/drivers/usb/net/usbnet.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/net/usbnet.c	2005-01-19 13:44:46 -08:00
@@ -745,7 +745,7 @@
 	dev->out = usb_sndbulkpipe(dev->udev, 2);
 
 	// allocate irq urb
-	if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
+	if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == NULL) {
 		dbg ("%s: cannot allocate interrupt URB",
 			dev->net->name);
 		return -ENOMEM;
@@ -2265,14 +2265,34 @@
 	.unbind =	cdc_unbind,
 	.tx_fixup = 	zaurus_tx_fixup,
 };
+#define	ZAURUS_STRONGARM_INFO	((unsigned long)&zaurus_sl5x00_info)
+
 static const struct driver_info	zaurus_pxa_info = {
 	.description =	"Sharp Zaurus, PXA-2xx based",
 	.flags =	FLAG_FRAMING_Z,
 	.check_connect = always_connected,
+	.bind =		generic_cdc_bind,
+	.unbind =	cdc_unbind,
 	.tx_fixup = 	zaurus_tx_fixup,
+};
+#define	ZAURUS_PXA_INFO		((unsigned long)&zaurus_pxa_info)
 
-	.in = 1, .out = 2,
+static const struct driver_info	olympus_mxl_info = {
+	.description =	"Olympus R1000",
+	.flags =	FLAG_FRAMING_Z,
+	.check_connect = always_connected,
+	.bind =		generic_cdc_bind,
+	.unbind =	cdc_unbind,
+	.tx_fixup = 	zaurus_tx_fixup,
 };
+#define	OLYMPUS_MXL_INFO	((unsigned long)&olympus_mxl_info)
+
+#else
+
+/* blacklist all those devices */
+#define	ZAURUS_STRONGARM_INFO	0
+#define	ZAURUS_PXA_INFO		0
+#define	OLYMPUS_MXL_INFO	0
 
 #endif
 
@@ -2384,7 +2404,7 @@
 #endif
 		size = (sizeof (struct ethhdr) + dev->net->mtu);
 
-	if ((skb = alloc_skb (size, flags)) == 0) {
+	if ((skb = alloc_skb (size, flags)) == NULL) {
 		devdbg (dev, "no rx skb");
 		defer_kevent (dev, EVENT_RX_MEMORY);
 		usb_free_urb (urb);
@@ -2741,7 +2761,7 @@
 	if (test_bit (EVENT_TX_HALT, &dev->flags)) {
 		unlink_urbs (dev, &dev->txq);
 		status = usb_clear_halt (dev->udev, dev->out);
-		if (status < 0)
+		if (status < 0 && status != -EPIPE)
 			deverr (dev, "can't clear tx halt, status %d",
 				status);
 		else {
@@ -2752,7 +2772,7 @@
 	if (test_bit (EVENT_RX_HALT, &dev->flags)) {
 		unlink_urbs (dev, &dev->rxq);
 		status = usb_clear_halt (dev->udev, dev->in);
-		if (status < 0)
+		if (status < 0 && status != -EPIPE)
 			deverr (dev, "can't clear rx halt, status %d",
 				status);
 		else {
@@ -2769,7 +2789,7 @@
 			urb = usb_alloc_urb (0, GFP_KERNEL);
 		else
 			clear_bit (EVENT_RX_MEMORY, &dev->flags);
-		if (urb != 0) {
+		if (urb != NULL) {
 			clear_bit (EVENT_RX_MEMORY, &dev->flags);
 			rx_submit (dev, urb, GFP_KERNEL);
 			tasklet_schedule (&dev->bh);
@@ -2996,7 +3016,8 @@
 
 			// don't refill the queue all at once
 			for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) {
-				if ((urb = usb_alloc_urb (0, GFP_ATOMIC)) != 0)
+				urb = usb_alloc_urb (0, GFP_ATOMIC);
+				if (urb != NULL)
 					rx_submit (dev, urb, GFP_ATOMIC);
 			}
 			if (temp != dev->rxq.qlen)
@@ -3354,12 +3375,15 @@
 }, 
 #endif
 
-#ifdef	CONFIG_USB_ZAURUS
+#if	defined(CONFIG_USB_ZAURUS) || defined(CONFIG_USB_CDCETHER)
 /*
  * SA-1100 based Sharp Zaurus ("collie"), or compatible.
  * Same idea as above, but different framing.
  *
  * PXA-2xx based models are also lying-about-cdc.
+ *
+ * NOTE:  These entries do double-duty, serving as blacklist entries
+ * whenever Zaurus support isn't enabled, but CDC Ethernet is.
  */
 {
 	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
@@ -3370,82 +3394,79 @@
 	.bInterfaceClass	= USB_CLASS_COMM,
 	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol	= 0,
-	.driver_info =  (unsigned long) &zaurus_sl5x00_info,
+	.driver_info = ZAURUS_STRONGARM_INFO,
 }, {
 	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
 			  | USB_DEVICE_ID_MATCH_DEVICE, 
 	.idVendor		= 0x04DD,
 	.idProduct		= 0x8005,	/* A-300 */
-	.bInterfaceClass	= 0x02,
-	.bInterfaceSubClass	= 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol	= 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
 			  | USB_DEVICE_ID_MATCH_DEVICE, 
 	.idVendor		= 0x04DD,
 	.idProduct		= 0x8006,	/* B-500/SL-5600 */
-	.bInterfaceClass	= 0x02,
-	.bInterfaceSubClass	= 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol	= 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 	          | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor		= 0x04DD,
 	.idProduct		= 0x8007,	/* C-700 */
-	.bInterfaceClass    = 0x02,
-	.bInterfaceSubClass = 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol = 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
 	.idProduct              = 0x9031,	/* C-750 C-760 */
-	.bInterfaceClass        = 0x02,
-	.bInterfaceSubClass     = 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol     = 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
 	.idProduct              = 0x9032,	/* SL-6000 */
-	.bInterfaceClass        = 0x02,
-	.bInterfaceSubClass     = 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol     = 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 }, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
 	.idProduct              = 0x9050,	/* C-860 */
-	.bInterfaceClass        = 0x02,
-	.bInterfaceSubClass     = 0x0a,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= 6 /* Ethernet model */,
 	.bInterfaceProtocol     = 0x00,
-	.driver_info =  (unsigned long) &zaurus_pxa_info,
+	.driver_info = ZAURUS_PXA_INFO,
 },
-#endif
 
-#ifdef	CONFIG_USB_CDCETHER
-
-#ifndef	CONFIG_USB_ZAURUS
-	/* if we couldn't whitelist Zaurus, we must blacklist it */
+/* Olympus has some models with a Zaurus-compatible option.
+ * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
+ */
 {
-	.match_flags	=   USB_DEVICE_ID_MATCH_INT_INFO
-			  | USB_DEVICE_ID_MATCH_DEVICE, 
-	.idVendor		= 0x04DD,
-	.idProduct		= 0x8004,
-	/* match the master interface */
+	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
+		 | USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor               = 0x07B4,
+	.idProduct              = 0x0F02,	/* R-1000 */
 	.bInterfaceClass	= USB_CLASS_COMM,
 	.bInterfaceSubClass	= 6 /* Ethernet model */,
-	.bInterfaceProtocol	= 0,
-	.driver_info 		= 0, /* BLACKLIST */
+	.bInterfaceProtocol     = 0x00,
+	.driver_info = OLYMPUS_MXL_INFO,
 },
-	// FIXME blacklist the other Zaurus models too, sigh
 #endif
 
+#ifdef	CONFIG_USB_CDCETHER
 {
 	/* CDC Ether uses two interfaces, not necessarily consecutive.
 	 * We match the main interface, ignoring the optional device
diff -Nru a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
--- a/drivers/usb/serial/cypress_m8.c	2005-01-19 13:44:45 -08:00
+++ b/drivers/usb/serial/cypress_m8.c	2005-01-19 13:44:45 -08:00
@@ -18,6 +18,12 @@
  *
  *
  *  Lonnie Mendez <dignome@gmail.com>
+ *  12-15-2004
+ *	Incorporated write buffering from pl2303 driver.  Fixed bug with line
+ *	handling so both lines are raised in cypress_open. (was dropping rts)
+ *      Various code cleanups made as well along with other misc bug fixes.
+ *
+ *  Lonnie Mendez <dignome@gmail.com>
  *  04-10-2004
  *	Driver modified to support dynamic line settings.  Various improvments
  *      and features.
@@ -30,9 +36,11 @@
  * Long Term TODO:
  *	Improve transfer speeds - both read/write are somewhat slow
  *   at this point.
+ *      Improve debugging.  Show modem line status with debug output and
+ *   implement filtering for certain data as a module parameter.
  */
 
-/* Neil Whelchel wrote the cypress m8 implementation */
+/* Thanks to Neil Whelchel for writing the first cypress m8 implementation for linux. */
 /* Thanks to cypress for providing references for the hid reports. */
 /* Thanks to Jiang Zhang for providing links and for general help. */
 /* Code originates and was built up from ftdi_sio, belkin, pl2303 and others. */
@@ -53,24 +61,28 @@
 #include <linux/usb.h>
 #include <linux/serial.h>
 
+#include "usb-serial.h"
+#include "cypress_m8.h"
+
+
 #ifdef CONFIG_USB_SERIAL_DEBUG
 	static int debug = 1;
 #else
 	static int debug;
 #endif
-
 static int stats;
 
-#include "usb-serial.h"
-#include "cypress_m8.h"
-
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.06"
+#define DRIVER_VERSION "v1.08"
 #define DRIVER_AUTHOR "Lonnie Mendez <dignome@gmail.com>, Neil Whelchel <koyama@firstlight.net>"
 #define DRIVER_DESC "Cypress USB to Serial Driver"
 
+/* write buffer size defines */
+#define CYPRESS_BUF_SIZE	1024
+#define CYPRESS_CLOSING_WAIT	(30*HZ)
+
 static struct usb_device_id id_table_earthmate [] = {
 	{ USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) },
 	{ }						/* Terminating entry */
@@ -103,6 +115,8 @@
 	int bytes_out;			   /* used for statistics */
 	int cmd_count;			   /* used for statistics */
 	int cmd_ctrl;			   /* always set this to 1 before issuing a command */
+	struct cypress_buf *buf;	   /* write buffer */
+	int write_urb_in_use;		   /* write urb in use indicator */
 	int termios_initialized;
 	__u8 line_control;	   	   /* holds dtr / rts value */
 	__u8 current_status;	   	   /* received from last read - info on dsr,cts,cd,ri,etc */
@@ -115,8 +129,15 @@
 	char prev_status, diff_status;	   /* used for TIOCMIWAIT */
 	/* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
 	struct termios tmp_termios; 	   /* stores the old termios settings */
-	int write_interval;		   /* interrupt out write interval, as obtained from interrupt_out_urb */
-	int writepipe;			   /* used for clear halt, if necessary */
+	char calledfromopen;		   /* used when issuing lines on open - fixes rts drop bug */
+};
+
+/* write buffer structure */
+struct cypress_buf {
+	unsigned int	buf_size;
+	char		*buf_buf;
+	char		*buf_get;
+	char		*buf_put;
 };
 
 /* function prototypes for the Cypress USB to serial device */
@@ -126,6 +147,7 @@
 static int  cypress_open		(struct usb_serial_port *port, struct file *filp);
 static void cypress_close		(struct usb_serial_port *port, struct file *filp);
 static int  cypress_write		(struct usb_serial_port *port, const unsigned char *buf, int count);
+static void cypress_send		(struct usb_serial_port *port);
 static int  cypress_write_room		(struct usb_serial_port *port);
 static int  cypress_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
 static void cypress_set_termios		(struct usb_serial_port *port, struct termios * old);
@@ -136,8 +158,20 @@
 static void cypress_unthrottle		(struct usb_serial_port *port);
 static void cypress_read_int_callback	(struct urb *urb, struct pt_regs *regs);
 static void cypress_write_int_callback	(struct urb *urb, struct pt_regs *regs);
-static int  mask_to_rate		(unsigned mask);
-static unsigned rate_to_mask		(int rate);
+/* baud helper functions */
+static int	 mask_to_rate		(unsigned mask);
+static unsigned  rate_to_mask		(int rate);
+/* write buffer functions */
+static struct cypress_buf *cypress_buf_alloc(unsigned int size);
+static void 		  cypress_buf_free(struct cypress_buf *cb);
+static void		  cypress_buf_clear(struct cypress_buf *cb);
+static unsigned int	  cypress_buf_data_avail(struct cypress_buf *cb);
+static unsigned int	  cypress_buf_space_avail(struct cypress_buf *cb);
+static unsigned int	  cypress_buf_put(struct cypress_buf *cb, const char *buf,
+					  unsigned int count);
+static unsigned int	  cypress_buf_get(struct cypress_buf *cb, char *buf,
+					  unsigned int count);
+
 
 static struct usb_serial_device_type cypress_earthmate_device = {
 	.owner =			THIS_MODULE,
@@ -394,25 +428,19 @@
 
 	memset(priv, 0x00, sizeof (struct cypress_private));
 	spin_lock_init(&priv->lock);
+	priv->buf = cypress_buf_alloc(CYPRESS_BUF_SIZE);
+	if (priv->buf == NULL) {
+		kfree(priv);
+		return -ENOMEM;
+	}
 	init_waitqueue_head(&priv->delta_msr_wait);
-	priv->writepipe = serial->port[0]->interrupt_out_urb->pipe;
 	
-	/* free up interrupt_out buffer / urb allocated by usbserial
- 	 * for this port as we use our own urbs for writing */
-	if (serial->port[0]->interrupt_out_buffer) {
-		kfree(serial->port[0]->interrupt_out_buffer);
-		serial->port[0]->interrupt_out_buffer = NULL;
-	}
-	if (serial->port[0]->interrupt_out_urb) {
-		priv->write_interval = serial->port[0]->interrupt_out_urb->interval;
-		usb_free_urb(serial->port[0]->interrupt_out_urb);
-		serial->port[0]->interrupt_out_urb = NULL;
-	} else /* still need a write interval */
-		priv->write_interval = 10;
-
+	usb_reset_configuration (serial->dev);
+	
 	priv->cmd_ctrl = 0;
 	priv->line_control = 0;
 	priv->termios_initialized = 0;
+	priv->calledfromopen = 0;
 	priv->rx_flags = 0;
 	usb_set_serial_port_data(serial->port[0], priv);
 	
@@ -467,6 +495,7 @@
 	priv = usb_get_serial_port_data(serial->port[0]);
 
 	if (priv) {
+		cypress_buf_free(priv->buf);
 		kfree(priv);
 		usb_set_serial_port_data(serial->port[0], NULL);
 	}
@@ -482,37 +511,39 @@
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	/* clear halts before open */
+	usb_clear_halt(serial->dev, 0x00);
+	usb_clear_halt(serial->dev, 0x81);
+	usb_clear_halt(serial->dev, 0x02);
+
 	spin_lock_irqsave(&priv->lock, flags);
 	/* reset read/write statistics */
 	priv->bytes_in = 0;
 	priv->bytes_out = 0;
 	priv->cmd_count = 0;
-
-	/* turn on dtr / rts since we are not flow controlling by default */
-	priv->line_control = CONTROL_DTR | CONTROL_RTS; /* sent in status byte */
+	priv->rx_flags = 0;
 	spin_unlock_irqrestore(&priv->lock, flags);
-	priv->cmd_ctrl = 1;
-	result = cypress_write(port, NULL, 0);
-	
+
+	/* setting to zero could cause data loss */
 	port->tty->low_latency = 1;
 
-	/* termios defaults are set by usb_serial_init */
-	
-	cypress_set_termios(port, &priv->tmp_termios);
+	/* raise both lines and set termios */
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->line_control = CONTROL_DTR | CONTROL_RTS;
+	priv->calledfromopen = 1;
+	priv->cmd_ctrl = 1;
+	spin_unlock_irqrestore(&priv->lock, flags);
+	result = cypress_write(port, NULL, 0);
 
 	if (result) {
 		dev_err(&port->dev, "%s - failed setting the control lines - error %d\n", __FUNCTION__, result);
 		return result;
 	} else
-		dbg("%s - success setting the control lines", __FUNCTION__);
+		dbg("%s - success setting the control lines", __FUNCTION__);	
 
-	/* throttling off */
-	spin_lock_irqsave(&priv->lock, flags);
-	priv->rx_flags = 0;
-	spin_unlock_irqrestore(&priv->lock, flags);
+	cypress_set_termios(port, &priv->tmp_termios);
 
-	/* setup the port and
-	 * start reading from the device */
+	/* setup the port and start reading from the device */
 	if(!port->interrupt_in_urb){
 		err("%s - interrupt_in_urb is empty!", __FUNCTION__);
 		return(-1);
@@ -537,9 +568,46 @@
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	unsigned int c_cflag;
 	unsigned long flags;
+	int bps;
+	long timeout;
+	wait_queue_t wait;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	/* wait for data to drain from buffer */
+	spin_lock_irqsave(&priv->lock, flags);
+	timeout = CYPRESS_CLOSING_WAIT;
+	init_waitqueue_entry(&wait, current);
+	add_wait_queue(&port->tty->write_wait, &wait);
+	for (;;) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (cypress_buf_data_avail(priv->buf) == 0
+		|| timeout == 0 || signal_pending(current)
+		|| !usb_get_intfdata(port->serial->interface))
+			break;
+		spin_unlock_irqrestore(&priv->lock, flags);
+		timeout = schedule_timeout(timeout);
+		spin_lock_irqsave(&priv->lock, flags);
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&port->tty->write_wait, &wait);
+	/* clear out any remaining data in the buffer */
+	cypress_buf_clear(priv->buf);
+	spin_unlock_irqrestore(&priv->lock, flags);
+	
+	/* wait for characters to drain from device */
+	bps = tty_get_baud_rate(port->tty);
+	if (bps > 1200)
+		timeout = max((HZ*2560)/bps,HZ/10);
+	else
+		timeout = 2*HZ;
+	set_current_state(TASK_INTERRUPTIBLE);
+	schedule_timeout(timeout);
+
+	dbg("%s - stopping urbs", __FUNCTION__);
+	usb_kill_urb (port->interrupt_in_urb);
+	usb_kill_urb (port->interrupt_out_urb);
+
 	if (port->tty) {
 		c_cflag = port->tty->termios->c_cflag;
 		if (c_cflag & HUPCL) {
@@ -553,11 +621,6 @@
 		}
 	}
 
-	if (port->interrupt_in_urb) {
-		dbg("%s - stopping read urb", __FUNCTION__);
-		usb_kill_urb (port->interrupt_in_urb);
-	}
-
 	if (stats)
 		dev_info (&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",
 		          priv->bytes_in, priv->bytes_out, priv->cmd_count);
@@ -568,116 +631,145 @@
 {
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
-	struct urb *urb;
-	int status, s_pos = 0;
-	__u8 transfer_size = 0;
-	__u8 *buffer;
-
-	dbg("%s - port %d", __FUNCTION__, port->number);
+	
+	dbg("%s - port %d, %d bytes", __FUNCTION__, port->number, count);
 
-	spin_lock_irqsave(&priv->lock, flags);
-	if (count == 0 && !priv->cmd_ctrl) {
-		spin_unlock_irqrestore(&priv->lock, flags);
-		dbg("%s - write request of 0 bytes", __FUNCTION__);
-		return 0;
+	/* line control commands, which need to be executed immediately,
+	   are not put into the buffer for obvious reasons.
+	 */
+	if (priv->cmd_ctrl) {
+		count = 0;
+		goto finish;
 	}
-
-	if (priv->cmd_ctrl)
-		++priv->cmd_count;
-	priv->cmd_ctrl = 0;
+	
+	if (!count)
+		return count;
+	
+	spin_lock_irqsave(&priv->lock, flags);
+	count = cypress_buf_put(priv->buf, buf, count);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size);
-	dbg("%s - count is %d", __FUNCTION__, count);
+finish:
+	cypress_send(port);
 
-	/* Allocate buffer and urb */
-	buffer = kmalloc (port->interrupt_out_size, GFP_ATOMIC);
-	if (!buffer) {
-		dev_err(&port->dev, "ran out of memory for buffer\n");
-		return -ENOMEM;
-	}
+	return count;
+} /* cypress_write */
 
-	urb = usb_alloc_urb (0, GFP_ATOMIC);
-	if (!urb) {
-		dev_err(&port->dev, "failed allocating write urb\n");
-		kfree (buffer);
-		return -ENOMEM;
+
+static void cypress_send(struct usb_serial_port *port)
+{
+	int count = 0, result, offset, actual_size;
+	struct cypress_private *priv = usb_get_serial_port_data(port);
+	unsigned long flags;
+	
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	dbg("%s - interrupt out size is %d", __FUNCTION__, port->interrupt_out_size);
+	
+	spin_lock_irqsave(&priv->lock, flags);
+	if (priv->write_urb_in_use) {
+		dbg("%s - can't write, urb in use", __FUNCTION__);
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return;
 	}
+	spin_unlock_irqrestore(&priv->lock, flags);
 
-	memset(buffer, 0, port->interrupt_out_size); // test if this is needed... probably not since loop removed
+	/* clear buffer */
+	memset(port->interrupt_out_urb->transfer_buffer, 0, port->interrupt_out_size);
 
 	spin_lock_irqsave(&priv->lock, flags);
 	switch (port->interrupt_out_size) {
 		case 32:
 			// this is for the CY7C64013...
-			transfer_size = min (count, 30);
-			buffer[0] = priv->line_control;
-			buffer[1] = transfer_size;
-			s_pos = 2;
+			offset = 2;
+			port->interrupt_out_buffer[0] = priv->line_control;
 			break;
 		case 8:
 			// this is for the CY7C63743...
-			transfer_size = min (count, 7);
-			buffer[0] = priv->line_control | transfer_size;
-			s_pos = 1;
+			offset = 1;
+			port->interrupt_out_buffer[0] = priv->line_control;
 			break;
 		default:
 			dbg("%s - wrong packet size", __FUNCTION__);
 			spin_unlock_irqrestore(&priv->lock, flags);
-			kfree (buffer);
-			usb_free_urb (urb);
-			return -1;
+			return;
 	}
 
 	if (priv->line_control & CONTROL_RESET)
 		priv->line_control &= ~CONTROL_RESET;
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	/* copy data to offset position in urb transfer buffer */
-	memcpy (&buffer[s_pos], buf, transfer_size);
 
-	usb_serial_debug_data (debug, &port->dev, __FUNCTION__, port->interrupt_out_size, buffer);
+	if (priv->cmd_ctrl) {
+		priv->cmd_count++;
+		dbg("%s - line control command being issued", __FUNCTION__);
+		spin_unlock_irqrestore(&priv->lock, flags);
+		goto send;
+	} else
+		spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* build up the urb */
-	usb_fill_int_urb (urb, port->serial->dev,
-			  usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress),
-			  buffer, port->interrupt_out_size,
-			  cypress_write_int_callback, port, priv->write_interval);
+	count = cypress_buf_get(priv->buf, &port->interrupt_out_buffer[offset],
+				port->interrupt_out_size-offset);
 
-	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (count == 0) {
+		return;
+	}
 
-	if (status) {
-		dev_err(&port->dev, "%s - usb_submit_urb (write interrupt) failed with status %d\n",
-			__FUNCTION__, status);
-		transfer_size = status;
-		kfree (buffer);
-		goto exit;
+	switch (port->interrupt_out_size) {
+		case 32:
+			port->interrupt_out_buffer[1] = count;
+			break;
+		case 8:
+			port->interrupt_out_buffer[0] |= count;
 	}
 
+	dbg("%s - count is %d", __FUNCTION__, count);
+
+send:
 	spin_lock_irqsave(&priv->lock, flags);
-	priv->bytes_out += transfer_size;
+	priv->write_urb_in_use = 1;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-exit:
-	/* buffer free'd in callback */
-	usb_free_urb (urb);
+	if (priv->cmd_ctrl)
+		actual_size = 1;
+	else
+		actual_size = count + (port->interrupt_out_size == 32 ? 2 : 1);
+	
+	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, port->interrupt_out_size,
+			      port->interrupt_out_urb->transfer_buffer);
 
-	return transfer_size;
+	port->interrupt_out_urb->transfer_buffer_length = actual_size;
+	port->interrupt_out_urb->dev = port->serial->dev;
+	result = usb_submit_urb (port->interrupt_out_urb, GFP_ATOMIC);
+	if (result) {
+		dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__,
+			result);
+		priv->write_urb_in_use = 0;
+	}
 
-} /* cypress_write */
+	spin_lock_irqsave(&priv->lock, flags);
+	if (priv->cmd_ctrl) {
+		priv->cmd_ctrl = 0;
+	}
+	priv->bytes_out += count; /* do not count the line control and size bytes */
+	spin_unlock_irqrestore(&priv->lock, flags);
 
+	schedule_work(&port->work);
+} /* cypress_send */
 
+
+/* returns how much space is available in the soft buffer */
 static int cypress_write_room(struct usb_serial_port *port)
 {
+	struct cypress_private *priv = usb_get_serial_port_data(port);
+	int room = 0;
+	unsigned long flags;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
-	/*
-	 * We really can take anything the user throw at us
-	 * but let's pick a nice big number to tell the tty
-	 * layer that we have lots of free space
-	 */	
+	spin_lock_irqsave(&priv->lock, flags);
+	room = cypress_buf_space_avail(priv->buf);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return 2048;
+	dbg("%s - returns %d", __FUNCTION__, room);
+	return room;
 }
 
 
@@ -816,6 +908,8 @@
 	int data_bits, stop_bits, parity_type, parity_enable;
 	unsigned cflag, iflag, baud_mask;
 	unsigned long flags;
+	__u8 oldlines;
+	int linechange;
 	
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -880,6 +974,7 @@
 		data_bits = 3;
 
 	spin_lock_irqsave(&priv->lock, flags);
+	oldlines = priv->line_control;
 	if ((cflag & CBAUD) == B0) {
 		/* drop dtr and rts */
 		dbg("%s - dropping the lines, baud rate 0bps", __FUNCTION__);
@@ -902,11 +997,13 @@
 		}
 		priv->line_control |= CONTROL_DTR;
 		
-		/* this is probably not what I think it is... check into it */
-		if (cflag & CRTSCTS)
-			priv->line_control |= CONTROL_RTS;
-		else
-			priv->line_control &= ~CONTROL_RTS;
+		/* toggle CRTSCTS? - don't do this if being called from cypress_open */
+		if (!priv->calledfromopen) {
+			if (cflag & CRTSCTS)
+				priv->line_control |= CONTROL_RTS;
+			else
+				priv->line_control &= ~CONTROL_RTS;
+		}
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 	
@@ -925,7 +1022,7 @@
 
 	/* Here we can define custom tty settings for devices
          *
-         * the main tty base comes from empeg.c
+         * the main tty termios flag base comes from empeg.c
          */
 
 	spin_lock_irqsave(&priv->lock, flags);	
@@ -959,33 +1056,37 @@
 
 		// Software app handling it for device...	
 
-	} else {
-		
-		/* do something here */
-
 	}
+	linechange = (priv->line_control != oldlines);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* set lines */
-	priv->cmd_ctrl = 1;
-	cypress_write(port, NULL, 0);
+	/* if necessary, set lines */
+	if (!priv->calledfromopen && linechange) {
+		priv->cmd_ctrl = 1;
+		cypress_write(port, NULL, 0);
+	}
+
+	if (priv->calledfromopen)
+		priv->calledfromopen = 0;
 	
-	return;
 } /* cypress_set_termios */
 
-
+ 
+/* returns amount of data still left in soft buffer */
 static int cypress_chars_in_buffer(struct usb_serial_port *port)
 {
-	dbg("%s - port %d", __FUNCTION__, port->number);
+	struct cypress_private *priv = usb_get_serial_port_data(port);
+	int chars = 0;
+	unsigned long flags;
 
-	/*
-	 * We can't really account for how much data we
-	 * have sent out, but hasn't made it through to the
-	 * device, so just tell the tty layer that everything
-	 * is flushed.
-	 */
+	dbg("%s - port %d", __FUNCTION__, port->number);
+	
+	spin_lock_irqsave(&priv->lock, flags);
+	chars = cypress_buf_data_avail(priv->buf);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return 0;
+	dbg("%s - returns %d", __FUNCTION__, chars);
+	return chars;
 }
 
 
@@ -1032,10 +1133,11 @@
 	struct tty_struct *tty;
 	unsigned char *data = urb->transfer_buffer;
 	unsigned long flags;
-	char tty_flag = TTY_NORMAL;
-	int bytes=0;
+	char tty_flag = TTY_NORMAL;	
+	int havedata = 0;
+	int bytes = 0;
 	int result;
-	int i=0;
+	int i = 0;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -1046,6 +1148,7 @@
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->rx_flags & THROTTLED) {
+		dbg("%s - now throttling", __FUNCTION__);
 		priv->rx_flags |= ACTUALLY_THROTTLED;
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return;
@@ -1058,8 +1161,6 @@
 		return;
 	}
 
-	usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data);
-	
 	spin_lock_irqsave(&priv->lock, flags);
 	switch(urb->actual_length) {
 		case 32:
@@ -1067,12 +1168,16 @@
 			priv->current_status = data[0] & 0xF8;
 			bytes = data[1]+2;
 			i=2;
+			if (bytes > 2)
+				havedata = 1;
 			break;
 		case 8:
 			// This is for the CY7C63743...
 			priv->current_status = data[0] & 0xF8;
 			bytes = (data[0] & 0x07)+1;
 			i=1;
+			if (bytes > 1)
+				havedata = 1;
 			break;
 		default:
 			dbg("%s - wrong packet size - received %d bytes", __FUNCTION__, urb->actual_length);
@@ -1081,6 +1186,8 @@
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
+	usb_serial_debug_data (debug, &port->dev, __FUNCTION__, urb->actual_length, data);
+
 	spin_lock_irqsave(&priv->lock, flags);
 	/* check to see if status has changed */
 	if (priv != NULL) {
@@ -1115,7 +1222,7 @@
 	/* process read if there is data other than line status */
 	if (tty && (bytes > i)) {
 		for (; i < bytes ; ++i) {
-			dbg("pushing byte number %d - %d",i,data[i]);
+			dbg("pushing byte number %d - %d - %c",i,data[i],data[i]);
 			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
 				tty_flip_buffer_push(tty);
 			}
@@ -1151,21 +1258,229 @@
 static void cypress_write_int_callback(struct urb *urb, struct pt_regs *regs)
 {
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-
-	/* free up the transfer buffer, as usb_free_urb() does not do this */
-	kfree (urb->transfer_buffer);
+	struct cypress_private *priv = usb_get_serial_port_data(port);
+	int result;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 	
-	if (urb->status) {
-		dbg("%s - nonzero write status received: %d", __FUNCTION__, urb->status);
-		return;
+	switch (urb->status) {
+		case 0:
+			/* success */
+			break;
+		case -ECONNRESET:
+		case -ENOENT:
+		case -ESHUTDOWN:
+			/* this urb is terminated, clean up */
+			dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+			priv->write_urb_in_use = 0;
+			return;
+		default:
+			/* error in the urb, so we have to resubmit it */
+			dbg("%s - Overflow in write", __FUNCTION__);
+			dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+			port->interrupt_out_urb->transfer_buffer_length = 1;
+			port->interrupt_out_urb->dev = port->serial->dev;
+			result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
+			if (result)
+				dev_err(&urb->dev->dev, "%s - failed resubmitting write urb, error %d\n",
+					__FUNCTION__, result);
+			else
+				return;
 	}
+	
+	priv->write_urb_in_use = 0;
+	
+	/* send any buffered data */
+	cypress_send(port);
+}
+
+
+/*****************************************************************************
+ * Write buffer functions - buffering code from pl2303 used
+ *****************************************************************************/
+
+/*
+ * cypress_buf_alloc
+ *
+ * Allocate a circular buffer and all associated memory.
+ */
+
+static struct cypress_buf *cypress_buf_alloc(unsigned int size)
+{
+
+	struct cypress_buf *cb;
+
+
+	if (size == 0)
+		return NULL;
+
+	cb = (struct cypress_buf *)kmalloc(sizeof(struct cypress_buf), GFP_KERNEL);
+	if (cb == NULL)
+		return NULL;
+
+	cb->buf_buf = kmalloc(size, GFP_KERNEL);
+	if (cb->buf_buf == NULL) {
+		kfree(cb);
+		return NULL;
+	}
+
+	cb->buf_size = size;
+	cb->buf_get = cb->buf_put = cb->buf_buf;
+
+	return cb;
 
-	schedule_work(&port->work);
 }
 
 
+/*
+ * cypress_buf_free
+ *
+ * Free the buffer and all associated memory.
+ */
+
+static void cypress_buf_free(struct cypress_buf *cb)
+{
+	if (cb != NULL) {
+		if (cb->buf_buf != NULL)
+			kfree(cb->buf_buf);
+		kfree(cb);
+	}
+}
+
+
+/*
+ * cypress_buf_clear
+ *
+ * Clear out all data in the circular buffer.
+ */
+
+static void cypress_buf_clear(struct cypress_buf *cb)
+{
+	if (cb != NULL)
+		cb->buf_get = cb->buf_put;
+		/* equivalent to a get of all data available */
+}
+
+
+/*
+ * cypress_buf_data_avail
+ *
+ * Return the number of bytes of data available in the circular
+ * buffer.
+ */
+
+static unsigned int cypress_buf_data_avail(struct cypress_buf *cb)
+{
+	if (cb != NULL)
+		return ((cb->buf_size + cb->buf_put - cb->buf_get) % cb->buf_size);
+	else
+		return 0;
+}
+
+
+/*
+ * cypress_buf_space_avail
+ *
+ * Return the number of bytes of space available in the circular
+ * buffer.
+ */
+
+static unsigned int cypress_buf_space_avail(struct cypress_buf *cb)
+{
+	if (cb != NULL)
+		return ((cb->buf_size + cb->buf_get - cb->buf_put - 1) % cb->buf_size);
+	else
+		return 0;
+}
+
+
+/*
+ * cypress_buf_put
+ *
+ * Copy data data from a user buffer and put it into the circular buffer.
+ * Restrict to the amount of space available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static unsigned int cypress_buf_put(struct cypress_buf *cb, const char *buf,
+	unsigned int count)
+{
+
+	unsigned int len;
+
+
+	if (cb == NULL)
+		return 0;
+
+	len  = cypress_buf_space_avail(cb);
+	if (count > len)
+		count = len;
+
+	if (count == 0)
+		return 0;
+
+	len = cb->buf_buf + cb->buf_size - cb->buf_put;
+	if (count > len) {
+		memcpy(cb->buf_put, buf, len);
+		memcpy(cb->buf_buf, buf+len, count - len);
+		cb->buf_put = cb->buf_buf + count - len;
+	} else {
+		memcpy(cb->buf_put, buf, count);
+		if (count < len)
+			cb->buf_put += count;
+		else /* count == len */
+			cb->buf_put = cb->buf_buf;
+	}
+
+	return count;
+
+}
+
+
+/*
+ * cypress_buf_get
+ *
+ * Get data from the circular buffer and copy to the given buffer.
+ * Restrict to the amount of data available.
+ *
+ * Return the number of bytes copied.
+ */
+
+static unsigned int cypress_buf_get(struct cypress_buf *cb, char *buf,
+	unsigned int count)
+{
+
+	unsigned int len;
+
+
+	if (cb == NULL)
+		return 0;
+
+	len = cypress_buf_data_avail(cb);
+	if (count > len)
+		count = len;
+
+	if (count == 0)
+		return 0;
+
+	len = cb->buf_buf + cb->buf_size - cb->buf_get;
+	if (count > len) {
+		memcpy(buf, cb->buf_get, len);
+		memcpy(buf+len, cb->buf_buf, count - len);
+		cb->buf_get = cb->buf_buf + count - len;
+	} else {
+		memcpy(buf, cb->buf_get, count);
+		if (count < len)
+			cb->buf_get += count;
+		else /* count == len */
+			cb->buf_get = cb->buf_buf;
+	}
+
+	return count;
+
+}
+
 /*****************************************************************************
  * Module functions
  *****************************************************************************/
@@ -1214,6 +1529,7 @@
 
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_VERSION( DRIVER_VERSION );
 MODULE_LICENSE("GPL");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
diff -Nru a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/serial/ftdi_sio.c	2005-01-19 13:44:47 -08:00
@@ -372,6 +372,7 @@
 	{ USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0, 0x3ff) },
 	{ }						/* Terminating entry */
 };
 
@@ -486,6 +487,7 @@
 	{ USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0x400, 0xffff) },
 	{ }						/* Terminating entry */
 };
 
@@ -608,6 +610,7 @@
 	{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
+	{ USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) },
 	{ }						/* Terminating entry */
 };
 
diff -Nru a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
--- a/drivers/usb/serial/ftdi_sio.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/serial/ftdi_sio.h	2005-01-19 13:44:47 -08:00
@@ -240,6 +240,12 @@
 #define FTDI_RM_VID		0x0403	/* Vendor  Id */
 #define FTDI_RMCANVIEW_PID	0xfd60	/* Product Id */
 
+/*
+ * EVER Eco Pro UPS (http://www.ever.com.pl/)
+ */
+
+#define	EVER_ECO_PRO_CDS	0xe520	/* RS-232 converter */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
diff -Nru a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
--- a/drivers/usb/serial/garmin_gps.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/serial/garmin_gps.c	2005-01-19 13:44:47 -08:00
@@ -316,7 +316,7 @@
 		garmin_data_p->flags |= FLAGS_QUEUING;
 		pkt = kmalloc(sizeof(struct garmin_packet)+data_length,
 		              GFP_ATOMIC);
-		if (pkt == 0) {
+		if (pkt == NULL) {
 			dev_err(&garmin_data_p->port->dev, "out of memory\n");
 			return 0;
 		}
@@ -739,7 +739,7 @@
 {
 	struct garmin_packet *pkt = NULL;
 
-	while ((pkt = pkt_pop(garmin_data_p)) != 0) {
+	while ((pkt = pkt_pop(garmin_data_p)) != NULL) {
 		dbg("%s - next pkt: %d", __FUNCTION__, pkt->seq);
 		if (gsp_send(garmin_data_p, pkt->data, pkt->size) > 0) {
 			kfree(pkt);
@@ -877,7 +877,7 @@
 
 	struct usb_serial_port *port = garmin_data_p->port;
 
-	if (port != 0 && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) {
+	if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) {
 		/* send a terminate command */
 		status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
 		                           sizeof(GARMIN_STOP_TRANSFER_REQ));
@@ -1366,7 +1366,7 @@
 
 	if ((garmin_data_p->flags & FLAGS_THROTTLED) == 0) {
 		pkt = pkt_pop(garmin_data_p);
-		if (pkt != 0) {
+		if (pkt != NULL) {
 
 			send_to_tty(garmin_data_p->port, pkt->data, pkt->size);
 			kfree(pkt);
diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/usb/serial/keyspan.c	2005-01-19 13:44:46 -08:00
@@ -374,7 +374,7 @@
 		flip = p_priv->out_flip;
 	
 		/* Check we have a valid urb/endpoint before we use it... */
-		if ((this_urb = p_priv->out_urbs[flip]) == 0) {
+		if ((this_urb = p_priv->out_urbs[flip]) == NULL) {
 			/* no bulk out, so return 0 bytes written */
 			dbg("%s - no output urb :(", __FUNCTION__);
 			return count;
@@ -1020,11 +1020,11 @@
 	flip = p_priv->out_flip;
 
 	/* Check both endpoints to see if any are available. */
-	if ((this_urb = p_priv->out_urbs[flip]) != 0) {
+	if ((this_urb = p_priv->out_urbs[flip]) != NULL) {
 		if (this_urb->status != -EINPROGRESS)
 			return (data_len);
 		flip = (flip + 1) & d_details->outdat_endp_flip;        
-		if ((this_urb = p_priv->out_urbs[flip]) != 0) 
+		if ((this_urb = p_priv->out_urbs[flip]) != NULL) 
 			if (this_urb->status != -EINPROGRESS)
 				return (data_len);
 	}
diff -Nru a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
--- a/drivers/usb/storage/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/storage/Kconfig	2005-01-19 13:44:47 -08:00
@@ -47,7 +47,7 @@
 
 	  Saying Y here allows these commands to be sent to a USB device.
 	  If you find a device this doesn't work for, switch to N and let
-	  us know at usb-storage@lists.one-eyed-alien.net
+	  us know at <usb-storage@lists.one-eyed-alien.net>
 
 	  If you say N here, the kernel will assume that all disk-like USB
 	  devices are write-enabled.
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/usb/storage/unusual_devs.h	2005-01-19 13:44:47 -08:00
@@ -865,6 +865,14 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
+/* Submitted by Daniel Drake <dsd@gentoo.org>
+ * Reported by dayul on the Gentoo Forums */
+UNUSUAL_DEV(  0x0ea0, 0x2168, 0x0110, 0x0110,
+		"Ours Technology",
+		"Flash Disk",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /* Reported by Rastislav Stanik <rs_kernel@yahoo.com> */
 UNUSUAL_DEV(  0x0ea0, 0x6828, 0x0110, 0x0110,
 		"USB",
diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	2005-01-19 13:44:45 -08:00
+++ b/drivers/video/Kconfig	2005-01-19 13:44:45 -08:00
@@ -836,7 +836,7 @@
 	depends on FB && PCI
 	help
 	  This is the frame buffer device driver for the SiS 300, 315 and
-	  330 series VGA chipsets. Specs available at http://www.sis.com
+	  330 series VGA chipsets. Specs available at <http://www.sis.com>
 
 	  To compile this driver as a module, choose M here; the module
 	  will be called sisfb.
@@ -905,7 +905,7 @@
 
 	  WARNING: Do not use any application that uses the 3D engine
 	  (namely glide) while using this driver.
-	  Please read the file Documentation/fb/README-sstfb.txt for supported
+	  Please read the <file:Documentation/fb/README-sstfb.txt> for supported
 	  options and other important info  support.
 
 config FB_TRIDENT
@@ -1052,6 +1052,19 @@
 
 	  If unsure, say N.
 
+config FB_W100
+	tristate "W100 frame buffer support"
+	depends on FB && PXA_SHARPSL
+	---help---
+	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called vfb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
+
 config FB_PXA_PARAMETERS
 	bool "PXA LCD command line parameters"
 	default n
@@ -1067,7 +1080,7 @@
 	  single model of flatpanel then you can safely leave this
 	  option disabled.
 
-	  Documentation/fb/pxafb.txt describes the available parameters.
+	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
 
 config FB_VIRTUAL
 	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
@@ -1092,6 +1105,10 @@
 
 if FB || SGI_NEWPORT_CONSOLE
 	source "drivers/video/logo/Kconfig"
+endif
+
+if SYSFS
+	source "drivers/video/backlight/Kconfig"
 endif
 
 endmenu
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	2005-01-19 13:44:46 -08:00
+++ b/drivers/video/Makefile	2005-01-19 13:44:46 -08:00
@@ -6,6 +6,7 @@
 
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
+obj-$(CONFIG_SYSFS)		  += backlight/
 
 obj-$(CONFIG_FB)                  += fbmem.o fbmon.o fbcmap.o fbsysfs.o modedb.o softcursor.o
 # Only include macmodes.o if we have FB support and are PPC
@@ -94,6 +95,7 @@
 obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
 obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PXA)		  += pxafb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
+obj-$(CONFIG_FB_W100)		   += w100fb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
 
 # Platform or fallback drivers go here
 obj-$(CONFIG_FB_VESA)             += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
diff -Nru a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
--- a/drivers/video/aty/aty128fb.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/video/aty/aty128fb.c	2005-01-19 13:44:46 -08:00
@@ -2430,10 +2430,10 @@
 MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
 MODULE_LICENSE("GPL");
 module_param(mode_option, charp, 0);
-MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
+MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
 #ifdef CONFIG_MTRR
 module_param_named(nomtrr, mtrr, invbool, 0);
-MODULE_PARM_DESC(mtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");
+MODULE_PARM_DESC(nomtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");
 #endif
 #endif
 
diff -Nru a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
--- a/drivers/video/aty/radeon_base.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/video/aty/radeon_base.c	2005-01-19 13:44:46 -08:00
@@ -261,7 +261,7 @@
 
 #endif /* CONFIG_PPC_OF */
 
-static void __devexit radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
+static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
 {
 	if (!rinfo->bios_seg)
 		return;
diff -Nru a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/Kconfig	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,41 @@
+#
+# Backlight & LCD drivers configuration
+#
+
+menuconfig BACKLIGHT_LCD_SUPPORT
+	bool "Backlight & LCD device support"
+	help
+	  Enable this to be able to choose the drivers for controlling the
+	  backlight and the LCD panel on some platforms, for example on PDAs.
+
+config BACKLIGHT_CLASS_DEVICE
+        tristate "Lowlevel Backlight controls"
+	depends on BACKLIGHT_LCD_SUPPORT
+	help
+	  This framework adds support for low-level control of the LCD
+          backlight. This includes support for brightness and power.
+
+	  To have support for your specific LCD panel you will have to
+	  select the proper drivers which depend on this option.
+
+config BACKLIGHT_DEVICE
+	bool
+	depends on BACKLIGHT_CLASS_DEVICE
+	default y
+
+config LCD_CLASS_DEVICE
+        tristate "Lowlevel LCD controls"
+	depends on BACKLIGHT_LCD_SUPPORT
+	help
+	  This framework adds support for low-level control of LCD.
+	  Some framebuffer devices connect to platform-specific LCD modules
+	  in order to have a platform-specific way to control the flat panel
+	  (contrast and applying power to the LCD (not to the backlight!)).
+
+	  To have support for your specific LCD panel you will have to
+	  select the proper drivers which depend on this option.
+
+config LCD_DEVICE
+	bool
+	depends on LCD_CLASS_DEVICE
+	default y
diff -Nru a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/Makefile	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,4 @@
+# Backlight & LCD drivers
+
+obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
+obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
diff -Nru a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/backlight.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,264 @@
+/*
+ * Backlight Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/backlight.h>
+#include <linux/notifier.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <asm/bug.h>
+
+static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->get_power))
+		rc = sprintf(buf, "%d\n", bd->props->get_power(bd));
+	else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
+{
+	int rc, power;
+	char *endp;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	power = simple_strtoul(buf, &endp, 0);
+	if (*endp && !isspace(*endp))
+		return -EINVAL;
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->set_power)) {
+		pr_debug("backlight: set power to %d\n", power);
+		bd->props->set_power(bd, power);
+		rc = count;
+	} else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->get_brightness))
+		rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd));
+	else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
+{
+	int rc, brightness;
+	char *endp;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	brightness = simple_strtoul(buf, &endp, 0);
+	if (*endp && !isspace(*endp))
+		return -EINVAL;
+
+	down(&bd->sem);
+	if (likely(bd->props && bd->props->set_brightness)) {
+		pr_debug("backlight: set brightness to %d\n", brightness);
+		bd->props->set_brightness(bd, brightness);
+		rc = count;
+	} else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct backlight_device *bd = to_backlight_device(cdev);
+
+	down(&bd->sem);
+	if (likely(bd->props))
+		rc = sprintf(buf, "%d\n", bd->props->max_brightness);
+	else
+		rc = -ENXIO;
+	up(&bd->sem);
+
+	return rc;
+}
+
+static void backlight_class_release(struct class_device *dev)
+{
+	struct backlight_device *bd = to_backlight_device(dev);
+	kfree(bd);
+}
+
+struct class backlight_class = {
+	.name = "backlight",
+	.release = backlight_class_release,
+};
+
+#define DECLARE_ATTR(_name,_mode,_show,_store)			\
+{							 	\
+	.attr	= { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
+	.show	= _show,					\
+	.store	= _store,					\
+}
+
+static struct class_device_attribute bl_class_device_attributes[] = {
+	DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
+	DECLARE_ATTR(brightness, 0644, backlight_show_brightness, backlight_store_brightness),
+	DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
+};
+
+/* This callback gets called when something important happens inside a
+ * framebuffer driver. We're looking if that important event is blanking,
+ * and if it is, we're switching backlight power as well ...
+ */
+static int fb_notifier_callback(struct notifier_block *self,
+				unsigned long event, void *data)
+{
+	struct backlight_device *bd;
+	struct fb_event *evdata =(struct fb_event *)data;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK)
+		return 0;
+
+	bd = container_of(self, struct backlight_device, fb_notif);
+	down(&bd->sem);
+	if (bd->props)
+		if (!bd->props->check_fb || bd->props->check_fb(evdata->info))
+			bd->props->set_power(bd, *(int *)evdata->data);
+	up(&bd->sem);
+	return 0;
+}
+
+/**
+ * backlight_device_register - create and register a new object of
+ *   backlight_device class.
+ * @name: the name of the new object(must be the same as the name of the
+ *   respective framebuffer device).
+ * @devdata: an optional pointer to be stored in the class_device. The
+ *   methods may retrieve it by using class_get_devdata(&bd->class_dev).
+ * @bp: the backlight properties structure.
+ *
+ * Creates and registers new backlight class_device. Returns either an
+ * ERR_PTR() or a pointer to the newly allocated device.
+ */
+struct backlight_device *backlight_device_register(const char *name, void *devdata,
+						   struct backlight_properties *bp)
+{
+	int i, rc;
+	struct backlight_device *new_bd;
+
+	pr_debug("backlight_device_alloc: name=%s\n", name);
+
+	new_bd = kmalloc(sizeof(struct backlight_device), GFP_KERNEL);
+	if (unlikely(!new_bd))
+		return ERR_PTR(ENOMEM);
+
+	init_MUTEX(&new_bd->sem);
+	new_bd->props = bp;
+	memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev));
+	new_bd->class_dev.class = &backlight_class;
+	strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN);
+	class_set_devdata(&new_bd->class_dev, devdata);
+
+	rc = class_device_register(&new_bd->class_dev);
+	if (unlikely(rc)) {
+error:		kfree(new_bd);
+		return ERR_PTR(rc);
+	}
+
+	memset(&new_bd->fb_notif, 0, sizeof(new_bd->fb_notif));
+	new_bd->fb_notif.notifier_call = fb_notifier_callback;
+
+	rc = fb_register_client(&new_bd->fb_notif);
+	if (unlikely(rc))
+		goto error;
+
+	for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) {
+		rc = class_device_create_file(&new_bd->class_dev,
+					      &bl_class_device_attributes[i]);
+		if (unlikely(rc)) {
+			while (--i >= 0)
+				class_device_remove_file(&new_bd->class_dev,
+							 &bl_class_device_attributes[i]);
+			class_device_unregister(&new_bd->class_dev);
+			/* No need to kfree(new_bd) since release() method was called */
+			return ERR_PTR(rc);
+		}
+	}
+
+	return new_bd;
+}
+EXPORT_SYMBOL(backlight_device_register);
+
+/**
+ * backlight_device_unregister - unregisters a backlight device object.
+ * @bd: the backlight device object to be unregistered and freed.
+ *
+ * Unregisters a previously registered via backlight_device_register object.
+ */
+void backlight_device_unregister(struct backlight_device *bd)
+{
+	int i;
+
+	if (!bd)
+		return;
+
+	pr_debug("backlight_device_unregister: name=%s\n", bd->class_dev.class_id);
+
+	for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++)
+		class_device_remove_file(&bd->class_dev,
+					 &bl_class_device_attributes[i]);
+
+	down(&bd->sem);
+	bd->props = NULL;
+	up(&bd->sem);
+
+	fb_unregister_client(&bd->fb_notif);
+
+	class_device_unregister(&bd->class_dev);
+}
+EXPORT_SYMBOL(backlight_device_unregister);
+
+static void __exit backlight_class_exit(void)
+{
+	class_unregister(&backlight_class);
+}
+
+static int __init backlight_class_init(void)
+{
+	return class_register(&backlight_class);
+}
+
+/*
+ * if this is compiled into the kernel, we need to ensure that the
+ * class is registered before users of the class try to register lcd's
+ */
+postcore_initcall(backlight_class_init);
+module_exit(backlight_class_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>");
+MODULE_DESCRIPTION("Backlight Lowlevel Control Abstraction");
diff -Nru a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/backlight/lcd.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,263 @@
+/*
+ * LCD Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/lcd.h>
+#include <linux/notifier.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <asm/bug.h>
+
+static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	down(&ld->sem);
+	if (likely(ld->props && ld->props->get_power))
+		rc = sprintf(buf, "%d\n", ld->props->get_power(ld));
+	else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_t count)
+{
+	int rc, power;
+	char *endp;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	power = simple_strtoul(buf, &endp, 0);
+	if (*endp && !isspace(*endp))
+		return -EINVAL;
+
+	down(&ld->sem);
+	if (likely(ld->props && ld->props->set_power)) {
+		pr_debug("lcd: set power to %d\n", power);
+		ld->props->set_power(ld, power);
+		rc = count;
+	} else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	down(&ld->sem);
+	if (likely(ld->props && ld->props->get_contrast))
+		rc = sprintf(buf, "%d\n", ld->props->get_contrast(ld));
+	else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, size_t count)
+{
+	int rc, contrast;
+	char *endp;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	contrast = simple_strtoul(buf, &endp, 0);
+	if (*endp && !isspace(*endp))
+		return -EINVAL;
+
+	down(&ld->sem);
+	if (likely(ld->props && ld->props->set_contrast)) {
+		pr_debug("lcd: set contrast to %d\n", contrast);
+		ld->props->set_contrast(ld, contrast);
+		rc = count;
+	} else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf)
+{
+	int rc;
+	struct lcd_device *ld = to_lcd_device(cdev);
+
+	down(&ld->sem);
+	if (likely(ld->props))
+		rc = sprintf(buf, "%d\n", ld->props->max_contrast);
+	else
+		rc = -ENXIO;
+	up(&ld->sem);
+
+	return rc;
+}
+
+static void lcd_class_release(struct class_device *dev)
+{
+	struct lcd_device *ld = to_lcd_device(dev);
+	kfree(ld);
+}
+
+struct class lcd_class = {
+	.name = "lcd",
+	.release = lcd_class_release,
+};
+
+#define DECLARE_ATTR(_name,_mode,_show,_store)			\
+{							 	\
+	.attr	= { .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },	\
+	.show	= _show,					\
+	.store	= _store,					\
+}
+
+static struct class_device_attribute lcd_class_device_attributes[] = {
+	DECLARE_ATTR(power, 0644, lcd_show_power, lcd_store_power),
+	DECLARE_ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
+	DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
+};
+
+/* This callback gets called when something important happens inside a
+ * framebuffer driver. We're looking if that important event is blanking,
+ * and if it is, we're switching lcd power as well ...
+ */
+static int fb_notifier_callback(struct notifier_block *self,
+				 unsigned long event, void *data)
+{
+	struct lcd_device *ld;
+	struct fb_event *evdata =(struct fb_event *)data;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK)
+		return 0;
+
+	ld = container_of(self, struct lcd_device, fb_notif);
+	down(&ld->sem);
+	if (ld->props)
+		if (!ld->props->check_fb || ld->props->check_fb(evdata->info))
+			ld->props->set_power(ld, *(int *)evdata->data);
+	up(&ld->sem);
+	return 0;
+}
+
+/**
+ * lcd_device_register - register a new object of lcd_device class.
+ * @name: the name of the new object(must be the same as the name of the
+ *   respective framebuffer device).
+ * @devdata: an optional pointer to be stored in the class_device. The
+ *   methods may retrieve it by using class_get_devdata(ld->class_dev).
+ * @lp: the lcd properties structure.
+ *
+ * Creates and registers a new lcd class_device. Returns either an ERR_PTR()
+ * or a pointer to the newly allocated device.
+ */
+struct lcd_device *lcd_device_register(const char *name, void *devdata,
+				       struct lcd_properties *lp)
+{
+	int i, rc;
+	struct lcd_device *new_ld;
+
+	pr_debug("lcd_device_register: name=%s\n", name);
+
+	new_ld = kmalloc(sizeof(struct lcd_device), GFP_KERNEL);
+	if (unlikely(!new_ld))
+		return ERR_PTR(ENOMEM);
+
+	init_MUTEX(&new_ld->sem);
+	new_ld->props = lp;
+	memset(&new_ld->class_dev, 0, sizeof(new_ld->class_dev));
+	new_ld->class_dev.class = &lcd_class;
+	strlcpy(new_ld->class_dev.class_id, name, KOBJ_NAME_LEN);
+	class_set_devdata(&new_ld->class_dev, devdata);
+
+	rc = class_device_register(&new_ld->class_dev);
+	if (unlikely(rc)) {
+error:		kfree(new_ld);
+		return ERR_PTR(rc);
+	}
+
+	memset(&new_ld->fb_notif, 0, sizeof(new_ld->fb_notif));
+	new_ld->fb_notif.notifier_call = fb_notifier_callback;
+
+	rc = fb_register_client(&new_ld->fb_notif);
+	if (unlikely(rc))
+		goto error;
+
+	for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++) {
+		rc = class_device_create_file(&new_ld->class_dev,
+					      &lcd_class_device_attributes[i]);
+		if (unlikely(rc)) {
+			while (--i >= 0)
+				class_device_remove_file(&new_ld->class_dev,
+							 &lcd_class_device_attributes[i]);
+			class_device_unregister(&new_ld->class_dev);
+			/* No need to kfree(new_ld) since release() method was called */
+			return ERR_PTR(rc);
+		}
+	}
+
+	return new_ld;
+}
+EXPORT_SYMBOL(lcd_device_register);
+
+/**
+ * lcd_device_unregister - unregisters a object of lcd_device class.
+ * @ld: the lcd device object to be unregistered and freed.
+ *
+ * Unregisters a previously registered via lcd_device_register object.
+ */
+void lcd_device_unregister(struct lcd_device *ld)
+{
+	int i;
+
+	if (!ld)
+		return;
+
+	pr_debug("lcd_device_unregister: name=%s\n", ld->class_dev.class_id);
+
+	for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++)
+		class_device_remove_file(&ld->class_dev,
+					 &lcd_class_device_attributes[i]);
+
+	down(&ld->sem);
+	ld->props = NULL;
+	up(&ld->sem);
+
+	fb_unregister_client(&ld->fb_notif);
+
+	class_device_unregister(&ld->class_dev);
+}
+EXPORT_SYMBOL(lcd_device_unregister);
+
+static void __exit lcd_class_exit(void)
+{
+	class_unregister(&lcd_class);
+}
+
+static int __init lcd_class_init(void)
+{
+	return class_register(&lcd_class);
+}
+
+/*
+ * if this is compiled into the kernel, we need to ensure that the
+ * class is registered before users of the class try to register lcd's
+ */
+postcore_initcall(lcd_class_init);
+module_exit(lcd_class_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamey Hicks <jamey.hicks@hp.com>, Andrew Zabolotny <zap@homelink.ru>");
+MODULE_DESCRIPTION("LCD Lowlevel Control Abstraction");
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- a/drivers/video/console/fbcon.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/video/console/fbcon.c	2005-01-19 13:44:47 -08:00
@@ -2014,6 +2014,7 @@
 static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
 {
 	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
 	int active = !fbcon_is_inactive(vc, info);
 
 	if (mode_switch) {
@@ -2037,18 +2038,14 @@
 	}
 
  	if (active) {
-		struct fbcon_ops *ops = info->fbcon_par;
+		if (ops->blank_state != blank) {
+			ops->blank_state = blank;
+			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
+			ops->cursor_flash = (!blank);
 
- 		fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
- 		ops->cursor_flash = (!blank);
-
- 		if (ops->blank_state != blank) {
- 			if (info->fbops->fb_blank &&
- 			    info->fbops->fb_blank(blank, info))
- 				fbcon_generic_blank(vc, info, blank);
-
- 			ops->blank_state = blank;
- 		}
+			if (fb_blank(info, blank))
+				fbcon_generic_blank(vc, info, blank);
+		}
 
  		if (!blank)
  			update_screen(vc->vc_num);
diff -Nru a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
--- a/drivers/video/console/fbcon.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/video/console/fbcon.h	2005-01-19 13:44:47 -08:00
@@ -162,4 +162,7 @@
 			      struct display *p, struct fbcon_ops *ops);
 #endif
 extern void fbcon_set_bitops(struct fbcon_ops *ops);
+
+extern const struct consw fb_con;
+
 #endif /* _VIDEO_FBCON_H */
diff -Nru a/drivers/video/fbmon.c b/drivers/video/fbmon.c
--- a/drivers/video/fbmon.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/video/fbmon.c	2005-01-19 13:44:47 -08:00
@@ -89,11 +89,12 @@
   while (i-- && (*--s == 0x20)) *s = 0;
 }
 
-static void fix_edid(unsigned char *edid)
+static int check_edid(unsigned char *edid)
 {
 	unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
 	unsigned char *b;
-	u32 model, i;
+	u32 model;
+	int i, fix = 0, ret = 0;
 
 	manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@';
 	manufacturer[1] = ((block[0] & 0x03) << 3) +
@@ -105,36 +106,57 @@
 	for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
 		if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
 			brokendb[i].model == model) {
-
 			printk("fbmon: The EDID Block of "
 			       "Manufacturer: %s Model: 0x%x is known to "
 			       "be broken,\n",  manufacturer, model);
-			switch (brokendb[i].fix) {
-			case FBMON_FIX_HEADER:
-				printk("fbmon: trying a header "
-				       "reconstruct\n");
-				memcpy(edid, edid_v1_header, 8);
-				break;
-			case FBMON_FIX_INPUT:
-				printk("fbmon: trying to fix input type\n");
-				b = edid + EDID_STRUCT_DISPLAY;
-				/* Only if display is GTF capable will
-				   the input type be reset to analog */
-				if (b[4] & 0x01) {
-					b[0] &= ~0x80;
-					edid[127] += 0x80;
-				}
-			}
+ 			fix = brokendb[i].fix;
+ 			break;
+		}
+	}
+
+	switch (fix) {
+	case FBMON_FIX_HEADER:
+		for (i = 0; i < 8; i++) {
+			if (edid[i] != edid_v1_header[i])
+				ret = fix;
 		}
+		break;
+	case FBMON_FIX_INPUT:
+		b = edid + EDID_STRUCT_DISPLAY;
+		/* Only if display is GTF capable will
+		   the input type be reset to analog */
+		if (b[4] & 0x01 && b[0] & 0x80)
+			ret = fix;
+		break;
+	}
+
+	return ret;
+}
+
+static void fix_edid(unsigned char *edid, int fix)
+{
+	unsigned char *b;
+
+	switch (fix) {
+	case FBMON_FIX_HEADER:
+		printk("fbmon: trying a header reconstruct\n");
+		memcpy(edid, edid_v1_header, 8);
+		break;
+	case FBMON_FIX_INPUT:
+		printk("fbmon: trying to fix input type\n");
+		b = edid + EDID_STRUCT_DISPLAY;
+		b[0] &= ~0x80;
+		edid[127] += 0x80;
 	}
 }
 
 static int edid_checksum(unsigned char *edid)
 {
 	unsigned char i, csum = 0, all_null = 0;
-	int err = 0;
+	int err = 0, fix = check_edid(edid);
 
-	fix_edid(edid);
+	if (fix)
+		fix_edid(edid, fix);
 
 	for (i = 0; i < EDID_LENGTH; i++) {
 		csum += edid[i];
@@ -151,9 +173,10 @@
 
 static int edid_check_header(unsigned char *edid)
 {
-	int i, err = 1;
+	int i, err = 1, fix = check_edid(edid);
 
-	fix_edid(edid);
+	if (fix)
+		fix_edid(edid, fix);
 
 	for (i = 0; i < 8; i++) {
 		if (edid[i] != edid_v1_header[i])
@@ -639,7 +662,7 @@
 
 	fb_get_monitor_limits(edid, specs);
 
-	c = (block[0] & 0x80) >> 7;
+	c = block[0] & 0x80;
 	specs->input = 0;
 	if (c) {
 		specs->input |= FB_DISP_DDI;
@@ -663,13 +686,10 @@
 			DPRINTK("0.700V/0.000V");
 			specs->input |= FB_DISP_ANA_700_000;
 			break;
-		default:
-			DPRINTK("unknown");
-			specs->input |= FB_DISP_UNKNOWN;
 		}
 	}
 	DPRINTK("\n      Sync: ");
-	c = (block[0] & 0x10) >> 4;
+	c = block[0] & 0x10;
 	if (c)
 		DPRINTK("      Configurable signal level\n");
 	c = block[0] & 0x0f;
diff -Nru a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
--- a/drivers/video/i810/i810_main.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/video/i810/i810_main.c	2005-01-19 13:44:46 -08:00
@@ -2002,20 +2002,20 @@
 	return pci_register_driver(&i810fb_driver);
 }
 
-module_param(vram, int, 4);
+module_param(vram, int, 0);
 MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB" 
 		 " (default=4)");
 module_param(voffset, int, 0);
 MODULE_PARM_DESC(voffset, "at what offset to place start of framebuffer "
                  "memory (0 to maximum aperture size), in MiB (default = 48)");
-module_param(bpp, int, 8);
+module_param(bpp, int, 0);
 MODULE_PARM_DESC(bpp, "Color depth for display in bits per pixel"
 		 " (default = 8)");
-module_param(xres, int, 640);
+module_param(xres, int, 0);
 MODULE_PARM_DESC(xres, "Horizontal resolution in pixels (default = 640)");
-module_param(yres, int, 480);
+module_param(yres, int, 0);
 MODULE_PARM_DESC(yres, "Vertical resolution in scanlines (default = 480)");
-module_param(vyres,int, 480);
+module_param(vyres,int, 0);
 MODULE_PARM_DESC(vyres, "Virtual vertical resolution in scanlines"
 		 " (default = 480)");
 module_param(hsync1, int, 0);
diff -Nru a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
--- a/drivers/video/matrox/matroxfb_base.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/video/matrox/matroxfb_base.c	2005-01-19 13:44:47 -08:00
@@ -2477,8 +2477,10 @@
 MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization (0 or 1=do not initialize) (default=0)");
 module_param(memtype, int, 0);
 MODULE_PARM_DESC(memtype, "Memory type for G200/G400 (see Documentation/fb/matroxfb.txt for explanation) (default=3 for G200, 0 for G400)");
+#ifdef CONFIG_MTRR
 module_param(mtrr, int, 0);
 MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
+#endif
 module_param(sgram, int, 0);
 MODULE_PARM_DESC(sgram, "Indicates that G100/G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
 module_param(inv24, int, 0);
diff -Nru a/drivers/video/pxafb.c b/drivers/video/pxafb.c
--- a/drivers/video/pxafb.c	2005-01-19 13:44:48 -08:00
+++ b/drivers/video/pxafb.c	2005-01-19 13:44:48 -08:00
@@ -740,8 +740,8 @@
 
 	DPRINTK("Disabling LCD controller\n");
 
-	add_wait_queue(&fbi->ctrlr_wait, &wait);
 	set_current_state(TASK_UNINTERRUPTIBLE);
+	add_wait_queue(&fbi->ctrlr_wait, &wait);
 
 	LCSR = 0xffffffff;	/* Clear LCD Status Register */
 	LCCR0 &= ~LCCR0_LDM;	/* Enable LCD Disable Done Interrupt */
diff -Nru a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
--- a/drivers/video/sa1100fb.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/video/sa1100fb.c	2005-01-19 13:44:46 -08:00
@@ -1072,8 +1072,8 @@
 		GPCR |= SHANNON_GPIO_DISP_EN;
 	}	
 
-	add_wait_queue(&fbi->ctrlr_wait, &wait);
 	set_current_state(TASK_UNINTERRUPTIBLE);
+	add_wait_queue(&fbi->ctrlr_wait, &wait);
 
 	LCSR = 0xffffffff;	/* Clear LCD Status Register */
 	LCCR0 &= ~LCCR0_LDM;	/* Enable LCD Disable Done Interrupt */
diff -Nru a/drivers/video/w100fb.c b/drivers/video/w100fb.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/w100fb.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,1864 @@
+/*
+ * linux/drivers/video/w100fb.c
+ *
+ * Frame Buffer Device for ATI Imageon w100 (Wallaby)
+ *
+ * Copyright (C) 2002, ATI Corp.
+ * Copyright (C) 2004-2005 Richard Purdie
+ *
+ * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <video/w100fb.h>
+#include "w100fb.h"
+
+/*
+ * Prototypes
+ */
+static void w100fb_save_buffer(void);
+static void w100fb_clear_buffer(void);
+static void w100fb_restore_buffer(void);
+static void w100fb_clear_screen(u32 mode, long int offset);
+static void w100_resume(void);
+static void w100_suspend(u32 mode);
+static void w100_init_qvga_rotation(u16 deg);
+static void w100_init_vga_rotation(u16 deg);
+static void w100_vsync(void);
+static void w100_init_sharp_lcd(u32 mode);
+static void w100_pwm_setup(void);
+static void w100_InitExtMem(u32 mode);
+static void w100_hw_init(void);
+static u16 w100_set_fastsysclk(u16 Freq);
+
+static void lcdtg_hw_init(u32 mode);
+static void lcdtg_lcd_change(u32 mode);
+static void lcdtg_resume(void);
+static void lcdtg_suspend(void);
+
+
+/* Register offsets & lengths */
+#define REMAPPED_FB_LEN   0x15ffff
+
+#define BITS_PER_PIXEL    16
+
+/* Pseudo palette size */
+#define MAX_PALETTES      16
+
+/* for resolution change */
+#define LCD_MODE_INIT (-1)
+#define LCD_MODE_480    0
+#define LCD_MODE_320    1
+#define LCD_MODE_240    2
+#define LCD_MODE_640    3
+
+#define LCD_SHARP_QVGA 0
+#define LCD_SHARP_VGA  1
+
+#define LCD_MODE_PORTRAIT	0
+#define LCD_MODE_LANDSCAPE	1
+
+#define W100_SUSPEND_EXTMEM 0
+#define W100_SUSPEND_ALL    1
+
+/* General frame buffer data structures */
+struct w100fb_par {
+	u32 xres;
+	u32 yres;
+	int fastsysclk_mode;
+	int lcdMode;
+	int rotation_flag;
+	int blanking_flag;
+	int comadj;
+	int phadadj;
+};
+
+static struct w100fb_par *current_par;
+
+static u16 *gSaveImagePtr = NULL;
+
+/* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */
+static void *remapped_base;
+static void *remapped_regs;
+static void *remapped_fbuf;
+
+/* External Function */
+static void(*w100fb_ssp_send)(u8 adrs, u8 data);
+
+/*
+ * Sysfs functions
+ */
+
+static ssize_t rotation_show(struct device *dev, char *buf)
+{
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+
+	return sprintf(buf, "%d\n",par->rotation_flag);
+}
+
+static ssize_t rotation_store(struct device *dev, const char *buf, size_t count)
+{
+	unsigned int rotate;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+
+	rotate = simple_strtoul(buf, NULL, 10);
+
+	if (rotate > 0) par->rotation_flag = 1;
+	else par->rotation_flag = 0;
+
+	if (par->lcdMode == LCD_MODE_320)
+		w100_init_qvga_rotation(par->rotation_flag ? 270 : 90);
+	else if (par->lcdMode == LCD_MODE_240)
+		w100_init_qvga_rotation(par->rotation_flag ? 180 : 0);
+	else if (par->lcdMode == LCD_MODE_640)
+		w100_init_vga_rotation(par->rotation_flag ? 270 : 90);
+	else if (par->lcdMode == LCD_MODE_480)
+		w100_init_vga_rotation(par->rotation_flag ? 180 : 0);
+
+	return count;
+}
+
+static DEVICE_ATTR(rotation, 0644, rotation_show, rotation_store);
+
+static ssize_t w100fb_reg_read(struct device *dev, const char *buf, size_t count)
+{
+	unsigned long param;
+	unsigned long regs;
+	regs = simple_strtoul(buf, NULL, 16);
+	param = readl(remapped_regs + regs);
+	printk("Read Register 0x%08lX: 0x%08lX\n", regs, param);
+	return count;
+}
+
+static DEVICE_ATTR(reg_read, 0200, NULL, w100fb_reg_read);
+
+static ssize_t w100fb_reg_write(struct device *dev, const char *buf, size_t count)
+{
+	unsigned long regs;
+	unsigned long param;
+	sscanf(buf, "%lx %lx", &regs, &param);
+
+	if (regs <= 0x2000) {
+		printk("Write Register 0x%08lX: 0x%08lX\n", regs, param);
+		writel(param, remapped_regs + regs);
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write);
+
+
+static ssize_t fastsysclk_show(struct device *dev, char *buf)
+{
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+
+	return sprintf(buf, "%d\n",par->fastsysclk_mode);
+}
+
+static ssize_t fastsysclk_store(struct device *dev, const char *buf, size_t count)
+{
+	int param;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+
+	param = simple_strtoul(buf, NULL, 10);
+
+	if (param == 75) {
+		printk("Set fastsysclk %d\n", param);
+		par->fastsysclk_mode = param;
+		w100_set_fastsysclk(par->fastsysclk_mode);
+	} else if (param == 100) {
+		printk("Set fastsysclk %d\n", param);
+		par->fastsysclk_mode = param;
+		w100_set_fastsysclk(par->fastsysclk_mode);
+	}
+	return count;
+}
+
+static DEVICE_ATTR(fastsysclk, 0644, fastsysclk_show, fastsysclk_store);
+
+/*
+ * The touchscreen on this device needs certain information
+ * from the video driver to function correctly. We export it here.
+ */
+int w100fb_get_xres(void) {
+	return current_par->xres;
+}
+
+int w100fb_get_blanking(void) {
+	return current_par->blanking_flag;
+}
+
+int w100fb_get_fastsysclk(void) {
+	return current_par->fastsysclk_mode;
+}
+EXPORT_SYMBOL(w100fb_get_xres);
+EXPORT_SYMBOL(w100fb_get_blanking);
+EXPORT_SYMBOL(w100fb_get_fastsysclk);
+
+
+/*
+ * Set a palette value from rgb components
+ */
+static int w100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			     u_int trans, struct fb_info *info)
+{
+	unsigned int val;
+	int ret = 1;
+
+	/*
+	 * If greyscale is true, then we convert the RGB value
+	 * to greyscale no matter what visual we are using.
+	 */
+	if (info->var.grayscale)
+		red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16;
+
+	/*
+	 * 16-bit True Colour.  We encode the RGB value
+	 * according to the RGB bitfield information.
+	 */
+	if (regno < MAX_PALETTES) {
+
+		u32 *pal = info->pseudo_palette;
+
+		val = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+		pal[regno] = val;
+		ret = 0;
+	}
+	return ret;
+}
+
+
+/*
+ * Blank the display based on value in blank_mode
+ */
+static int w100fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct w100fb_par *par;
+	par=info->par;
+
+	switch(blank_mode) {
+
+ 	case FB_BLANK_NORMAL: /* Normal blanking */
+	case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
+	case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
+ 	case FB_BLANK_POWERDOWN: /* Poweroff */
+  		if (par->blanking_flag == 0) {
+			w100fb_save_buffer();
+			lcdtg_suspend();
+			par->blanking_flag = 1;
+  		}
+  		break;
+
+ 	case FB_BLANK_UNBLANK: /* Unblanking */
+  		if (par->blanking_flag != 0) {
+			w100fb_restore_buffer();
+			lcdtg_resume();
+			par->blanking_flag = 0;
+  		}
+  		break;
+ 	}
+	return 0;
+}
+
+/*
+ *  Change the resolution by calling the appropriate hardware functions
+ */
+static void w100fb_changeres(int rotate_mode, u32 mode)
+{
+	u16 rotation=0;
+
+	switch(rotate_mode) {
+	case LCD_MODE_LANDSCAPE:
+		rotation=(current_par->rotation_flag ? 270 : 90);
+		break;
+	case LCD_MODE_PORTRAIT:
+		rotation=(current_par->rotation_flag ? 180 : 0);
+		break;
+	}
+
+	w100_pwm_setup();
+	switch(mode) {
+	case LCD_SHARP_QVGA:
+		w100_vsync();
+		w100_suspend(W100_SUSPEND_EXTMEM);
+		w100_init_sharp_lcd(LCD_SHARP_QVGA);
+		w100_init_qvga_rotation(rotation);
+		w100_InitExtMem(LCD_SHARP_QVGA);
+		w100fb_clear_screen(LCD_SHARP_QVGA, 0);
+		lcdtg_lcd_change(LCD_SHARP_QVGA);
+		break;
+	case LCD_SHARP_VGA:
+		w100fb_clear_screen(LCD_SHARP_QVGA, 0);
+		writel(0xBFFFA000, remapped_regs + mmMC_EXT_MEM_LOCATION);
+		w100_InitExtMem(LCD_SHARP_VGA);
+		w100fb_clear_screen(LCD_SHARP_VGA, 0x200000);
+		w100_vsync();
+		w100_init_sharp_lcd(LCD_SHARP_VGA);
+		if (rotation != 0)
+			w100_init_vga_rotation(rotation);
+		lcdtg_lcd_change(LCD_SHARP_VGA);
+		break;
+	}
+}
+
+/*
+ * Set up the display for the fb subsystem
+ */
+static void w100fb_activate_var(struct fb_info *info)
+{
+	u32 temp32;
+	struct w100fb_par *par=info->par;
+	struct fb_var_screeninfo *var = &info->var;
+
+	/* Set the hardware to 565 */
+	temp32 = readl(remapped_regs + mmDISP_DEBUG2);
+	temp32 &= 0xff7fffff;
+	temp32 |= 0x00800000;
+	writel(temp32, remapped_regs + mmDISP_DEBUG2);
+
+	if (par->lcdMode == LCD_MODE_INIT) {
+		w100_init_sharp_lcd(LCD_SHARP_VGA);
+		w100_init_vga_rotation(par->rotation_flag ? 270 : 90);
+		par->lcdMode = LCD_MODE_640;
+		lcdtg_hw_init(LCD_SHARP_VGA);
+	} else if (var->xres == 320 && var->yres == 240) {
+		if (par->lcdMode != LCD_MODE_320) {
+			w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_QVGA);
+			par->lcdMode = LCD_MODE_320;
+		}
+	} else if (var->xres == 240 && var->yres == 320) {
+		if (par->lcdMode != LCD_MODE_240) {
+			w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_QVGA);
+			par->lcdMode = LCD_MODE_240;
+		}
+	} else if (var->xres == 640 && var->yres == 480) {
+		if (par->lcdMode != LCD_MODE_640) {
+			w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_VGA);
+			par->lcdMode = LCD_MODE_640;
+		}
+	} else if (var->xres == 480 && var->yres == 640) {
+		if (par->lcdMode != LCD_MODE_480) {
+			w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_VGA);
+			par->lcdMode = LCD_MODE_480;
+		}
+	} else printk(KERN_ERR "W100FB: Resolution error!\n");
+}
+
+
+/*
+ *  w100fb_check_var():
+ *  Get the video params out of 'var'. If a value doesn't fit, round it up,
+ *  if it's too big, return -EINVAL.
+ *
+ */
+static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	if (var->xres < var->yres) { /* Portrait mode */
+		if ((var->xres > 480) || (var->yres > 640)) {
+			return -EINVAL;
+		} else if ((var->xres > 240) || (var->yres > 320)) {
+			var->xres = 480;
+			var->yres = 640;
+		} else {
+			var->xres = 240;
+			var->yres = 320;
+		}
+	} else { /* Landscape mode */
+		if ((var->xres > 640) || (var->yres > 480)) {
+			return -EINVAL;
+		} else if ((var->xres > 320) || (var->yres > 240)) {
+			var->xres = 640;
+			var->yres = 480;
+		} else {
+			var->xres = 320;
+			var->yres = 240;
+		}
+	}
+
+	var->xres_virtual = max(var->xres_virtual, var->xres);
+	var->yres_virtual = max(var->yres_virtual, var->yres);
+
+	if (var->bits_per_pixel > BITS_PER_PIXEL)
+		return -EINVAL;
+	else
+		var->bits_per_pixel = BITS_PER_PIXEL;
+
+	var->red.offset = 11;
+	var->red.length = 5;
+	var->green.offset = 5;
+	var->green.length = 6;
+	var->blue.offset = 0;
+	var->blue.length = 5;
+	var->transp.offset = var->transp.length = 0;
+
+	var->nonstd = 0;
+
+	var->height = -1;
+	var->width = -1;
+	var->vmode = FB_VMODE_NONINTERLACED;
+
+	var->sync = 0;
+	var->pixclock = 0x04;	/* 171521; */
+
+	return 0;
+}
+
+
+/*
+ * w100fb_set_par():
+ *	Set the user defined part of the display for the specified console
+ *  by looking at the values in info.var
+ */
+static int w100fb_set_par(struct fb_info *info)
+{
+	struct w100fb_par *par=info->par;
+
+	par->xres = info->var.xres;
+	par->yres = info->var.yres;
+
+	info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	info->fix.ypanstep = 0;
+	info->fix.ywrapstep = 0;
+
+	if (par->blanking_flag)
+		w100fb_clear_buffer();
+
+	w100fb_activate_var(info);
+
+	if (par->lcdMode == LCD_MODE_480) {
+		info->fix.line_length = (480 * BITS_PER_PIXEL) / 8;
+		info->fix.smem_len = 0x200000;
+	} else if (par->lcdMode == LCD_MODE_320) {
+		info->fix.line_length = (320 * BITS_PER_PIXEL) / 8;
+		info->fix.smem_len = 0x60000;
+	} else if (par->lcdMode == LCD_MODE_240) {
+		info->fix.line_length = (240 * BITS_PER_PIXEL) / 8;
+		info->fix.smem_len = 0x60000;
+	} else if (par->lcdMode == LCD_MODE_INIT || par->lcdMode == LCD_MODE_640) {
+		info->fix.line_length = (640 * BITS_PER_PIXEL) / 8;
+		info->fix.smem_len = 0x200000;
+	}
+
+	return 0;
+}
+
+
+/*
+ *      Frame buffer operations
+ */
+static struct fb_ops w100fb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = w100fb_check_var,
+	.fb_set_par = w100fb_set_par,
+	.fb_setcolreg = w100fb_setcolreg,
+	.fb_blank = w100fb_blank,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_cursor = soft_cursor,
+};
+
+
+static void w100fb_clear_screen(u32 mode, long int offset)
+{
+	int i, numPix = 0;
+
+	if (mode == LCD_SHARP_VGA)
+		numPix = 640 * 480;
+	else if (mode == LCD_SHARP_QVGA)
+		numPix = 320 * 240;
+
+	for (i = 0; i < numPix; i++)
+		writew(0xffff, remapped_fbuf + offset + (2*i));
+}
+
+
+static void w100fb_save_buffer(void)
+{
+	int i;
+
+	if (gSaveImagePtr != NULL) {
+		vfree(gSaveImagePtr);
+		gSaveImagePtr = NULL;
+	}
+	gSaveImagePtr = vmalloc(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8);
+	if (gSaveImagePtr != NULL) {
+		for (i = 0; i < (current_par->xres * current_par->yres); i++)
+			*(gSaveImagePtr + i) = readw(remapped_fbuf + (2*i));
+	} else {
+		printk(KERN_WARNING "can't alloc pre-off image buffer\n");
+	}
+}
+
+
+static void w100fb_restore_buffer(void)
+{
+	int i;
+
+	if (gSaveImagePtr != NULL) {
+		for (i = 0; i < (current_par->xres * current_par->yres); i++) {
+				writew(*(gSaveImagePtr + i),remapped_fbuf + (2*i));
+			}
+		vfree(gSaveImagePtr);
+		gSaveImagePtr = NULL;
+	}
+}
+
+static void w100fb_clear_buffer(void)
+{
+	if (gSaveImagePtr != NULL) {
+		vfree(gSaveImagePtr);
+		gSaveImagePtr = NULL;
+	}
+}
+
+
+#ifdef CONFIG_PM
+static int w100fb_suspend(struct device *dev, u32 state, u32 level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+		struct fb_info *info = dev_get_drvdata(dev);
+		struct w100fb_par *par=info->par;
+
+		w100fb_save_buffer();
+		lcdtg_suspend();
+		w100_suspend(W100_SUSPEND_ALL);
+		par->blanking_flag = 1;
+	}
+	return 0;
+}
+
+static int w100fb_resume(struct device *dev, u32 level)
+{
+	if (level == RESUME_POWER_ON) {
+		struct fb_info *info = dev_get_drvdata(dev);
+		struct w100fb_par *par=info->par;
+
+		w100_resume();
+		w100fb_restore_buffer();
+		lcdtg_resume();
+		par->blanking_flag = 0;
+	}
+	return 0;
+}
+#else
+#define w100fb_suspend	NULL
+#define w100fb_resume	NULL
+#endif
+
+
+int __init w100fb_probe(struct device *dev)
+{
+	struct w100fb_mach_info *inf;
+	struct fb_info *info;
+	struct w100fb_par *par;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!mem)
+		return -EINVAL;
+
+	/* remap the areas we're going to use */
+	remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN);
+	if (remapped_base == NULL)
+		return -EIO;
+
+	remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN);
+	if (remapped_regs == NULL) {
+		iounmap(remapped_base);
+		return -EIO;
+	}
+
+	remapped_fbuf = ioremap_nocache(mem->start+MEM_EXT_BASE_VALUE, REMAPPED_FB_LEN);
+	if (remapped_fbuf == NULL) {
+		iounmap(remapped_base);
+		iounmap(remapped_regs);
+		return -EIO;
+	}
+
+	info=framebuffer_alloc(sizeof(struct w100fb_par), dev);
+	if (!info) {
+		iounmap(remapped_base);
+		iounmap(remapped_regs);
+		iounmap(remapped_fbuf);
+		return -ENOMEM;
+	}
+
+	info->device=dev;
+	par = info->par;
+	current_par=info->par;
+	dev_set_drvdata(dev, info);
+
+	inf = dev->platform_data;
+	par->phadadj = inf->phadadj;
+	par->comadj = inf->comadj;
+	par->fastsysclk_mode = 75;
+	par->lcdMode = LCD_MODE_INIT;
+	par->rotation_flag=0;
+	par->blanking_flag=0;
+	w100fb_ssp_send = inf->w100fb_ssp_send;
+
+	w100_hw_init();
+	w100_pwm_setup();
+
+	info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL);
+	if (!info->pseudo_palette) {
+		iounmap(remapped_base);
+		iounmap(remapped_regs);
+		iounmap(remapped_fbuf);
+		return -ENOMEM;
+	}
+
+	info->fbops = &w100fb_ops;
+	info->flags = FBINFO_DEFAULT;
+	info->node = -1;
+	info->screen_base = remapped_fbuf;
+	info->screen_size = REMAPPED_FB_LEN;
+
+	info->var.xres = 640;
+	info->var.xres_virtual = info->var.xres;
+	info->var.yres = 480;
+	info->var.yres_virtual = info->var.yres;
+	info->var.pixclock = 0x04;	/* 171521; */
+	info->var.sync = 0;
+	info->var.grayscale = 0;
+	info->var.xoffset = info->var.yoffset = 0;
+	info->var.accel_flags = 0;
+	info->var.activate = FB_ACTIVATE_NOW;
+
+	strcpy(info->fix.id, "w100fb");
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.type_aux = 0;
+	info->fix.accel = FB_ACCEL_NONE;
+	info->fix.smem_start = mem->start+MEM_EXT_BASE_VALUE;
+	info->fix.mmio_start = mem->start+W100_REG_BASE;
+	info->fix.mmio_len = W100_REG_LEN;
+
+	w100fb_check_var(&info->var, info);
+	w100fb_set_par(info);
+
+	if (register_framebuffer(info) < 0) {
+		kfree(info->pseudo_palette);
+		iounmap(remapped_base);
+		iounmap(remapped_regs);
+		iounmap(remapped_fbuf);
+		return -EINVAL;
+	}
+
+	device_create_file(dev, &dev_attr_fastsysclk);
+	device_create_file(dev, &dev_attr_reg_read);
+	device_create_file(dev, &dev_attr_reg_write);
+	device_create_file(dev, &dev_attr_rotation);
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
+	return 0;
+}
+
+
+static int w100fb_remove(struct device *dev)
+{
+	struct fb_info *info = dev_get_drvdata(dev);
+
+	device_remove_file(dev, &dev_attr_fastsysclk);
+	device_remove_file(dev, &dev_attr_reg_read);
+	device_remove_file(dev, &dev_attr_reg_write);
+	device_remove_file(dev, &dev_attr_rotation);
+
+	unregister_framebuffer(info);
+
+	w100fb_clear_buffer();
+	kfree(info->pseudo_palette);
+
+	iounmap(remapped_base);
+	iounmap(remapped_regs);
+	iounmap(remapped_fbuf);
+
+	framebuffer_release(info);
+
+	return 0;
+}
+
+
+/* ------------------- chipset specific functions -------------------------- */
+
+
+static void w100_soft_reset(void)
+{
+	u16 val = readw((u16 *) remapped_base + cfgSTATUS);
+	writew(val | 0x08, (u16 *) remapped_base + cfgSTATUS);
+	udelay(100);
+	writew(0x00, (u16 *) remapped_base + cfgSTATUS);
+	udelay(100);
+}
+
+/*
+ * Initialization of critical w100 hardware
+ */
+static void w100_hw_init(void)
+{
+	u32 temp32;
+	union cif_cntl_u cif_cntl;
+	union intf_cntl_u intf_cntl;
+	union cfgreg_base_u cfgreg_base;
+	union wrap_top_dir_u wrap_top_dir;
+	union cif_read_dbg_u cif_read_dbg;
+	union cpu_defaults_u cpu_default;
+	union cif_write_dbg_u cif_write_dbg;
+	union wrap_start_dir_u wrap_start_dir;
+	union mc_ext_mem_location_u mc_ext_mem_loc;
+	union cif_io_u cif_io;
+
+	w100_soft_reset();
+
+	/* This is what the fpga_init code does on reset. May be wrong
+	   but there is little info available */
+	writel(0x31, remapped_regs + mmSCRATCH_UMSK);
+	for (temp32 = 0; temp32 < 10000; temp32++)
+		readl(remapped_regs + mmSCRATCH_UMSK);
+	writel(0x30, remapped_regs + mmSCRATCH_UMSK);
+
+	/* Set up CIF */
+	cif_io.val = defCIF_IO;
+	writel((u32)(cif_io.val), remapped_regs + mmCIF_IO);
+
+	cif_write_dbg.val = readl(remapped_regs + mmCIF_WRITE_DBG);
+	cif_write_dbg.f.dis_packer_ful_during_rbbm_timeout = 0;
+	cif_write_dbg.f.en_dword_split_to_rbbm = 1;
+	cif_write_dbg.f.dis_timeout_during_rbbm = 1;
+	writel((u32) (cif_write_dbg.val), remapped_regs + mmCIF_WRITE_DBG);
+
+	cif_read_dbg.val = readl(remapped_regs + mmCIF_READ_DBG);
+	cif_read_dbg.f.dis_rd_same_byte_to_trig_fetch = 1;
+	writel((u32) (cif_read_dbg.val), remapped_regs + mmCIF_READ_DBG);
+
+	cif_cntl.val = readl(remapped_regs + mmCIF_CNTL);
+	cif_cntl.f.dis_system_bits = 1;
+	cif_cntl.f.dis_mr = 1;
+	cif_cntl.f.en_wait_to_compensate_dq_prop_dly = 0;
+	cif_cntl.f.intb_oe = 1;
+	cif_cntl.f.interrupt_active_high = 1;
+	writel((u32) (cif_cntl.val), remapped_regs + mmCIF_CNTL);
+
+	/* Setup cfgINTF_CNTL and cfgCPU defaults */
+	intf_cntl.val = defINTF_CNTL;
+	intf_cntl.f.ad_inc_a = 1;
+	intf_cntl.f.ad_inc_b = 1;
+	intf_cntl.f.rd_data_rdy_a = 0;
+	intf_cntl.f.rd_data_rdy_b = 0;
+	writeb((u8) (intf_cntl.val), remapped_base + cfgINTF_CNTL);
+
+	cpu_default.val = defCPU_DEFAULTS;
+	cpu_default.f.access_ind_addr_a = 1;
+	cpu_default.f.access_ind_addr_b = 1;
+	cpu_default.f.access_scratch_reg = 1;
+	cpu_default.f.transition_size = 0;
+	writeb((u8) (cpu_default.val), remapped_base + cfgCPU_DEFAULTS);
+
+	/* set up the apertures */
+	writeb((u8) (W100_REG_BASE >> 16), remapped_base + cfgREG_BASE);
+
+	cfgreg_base.val = defCFGREG_BASE;
+	cfgreg_base.f.cfgreg_base = W100_CFG_BASE;
+	writel((u32) (cfgreg_base.val), remapped_regs + mmCFGREG_BASE);
+
+	/* This location is relative to internal w100 addresses */
+	writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION);
+
+	mc_ext_mem_loc.val = defMC_EXT_MEM_LOCATION;
+	mc_ext_mem_loc.f.mc_ext_mem_start = MEM_EXT_BASE_VALUE >> 8;
+	mc_ext_mem_loc.f.mc_ext_mem_top = MEM_EXT_TOP_VALUE >> 8;
+	writel((u32) (mc_ext_mem_loc.val), remapped_regs + mmMC_EXT_MEM_LOCATION);
+
+	if ((current_par->lcdMode == LCD_MODE_240) || (current_par->lcdMode == LCD_MODE_320))
+		w100_InitExtMem(LCD_SHARP_QVGA);
+	else
+		w100_InitExtMem(LCD_SHARP_VGA);
+
+	wrap_start_dir.val = defWRAP_START_DIR;
+	wrap_start_dir.f.start_addr = WRAP_BUF_BASE_VALUE >> 1;
+	writel((u32) (wrap_start_dir.val), remapped_regs + mmWRAP_START_DIR);
+
+	wrap_top_dir.val = defWRAP_TOP_DIR;
+	wrap_top_dir.f.top_addr = WRAP_BUF_TOP_VALUE >> 1;
+	writel((u32) (wrap_top_dir.val), remapped_regs + mmWRAP_TOP_DIR);
+
+	writel((u32) 0x2440, remapped_regs + mmRBBM_CNTL);
+}
+
+
+/*
+ * Types
+ */
+
+struct pll_parm {
+	u16 freq;		/* desired Fout for PLL */
+	u8 M;
+	u8 N_int;
+	u8 N_fac;
+	u8 tfgoal;
+	u8 lock_time;
+};
+
+struct power_state {
+	union clk_pin_cntl_u clk_pin_cntl;
+	union pll_ref_fb_div_u pll_ref_fb_div;
+	union pll_cntl_u pll_cntl;
+	union sclk_cntl_u sclk_cntl;
+	union pclk_cntl_u pclk_cntl;
+	union clk_test_cntl_u clk_test_cntl;
+	union pwrmgt_cntl_u pwrmgt_cntl;
+	u32 freq;		/* Fout for PLL calibration */
+	u8 tf100;		/* for pll calibration */
+	u8 tf80;		/* for pll calibration */
+	u8 tf20;		/* for pll calibration */
+	u8 M;			/* for pll calibration */
+	u8 N_int;		/* for pll calibration */
+	u8 N_fac;		/* for pll calibration */
+	u8 lock_time;	/* for pll calibration */
+	u8 tfgoal;		/* for pll calibration */
+	u8 auto_mode;	/* hardware auto switch? */
+	u8 pwm_mode;		/* 0 fast, 1 normal/slow */
+	u16 fast_sclk;	/* fast clk freq */
+	u16 norm_sclk;	/* slow clk freq */
+};
+
+
+/*
+ * Global state variables
+ */
+
+static struct power_state w100_pwr_state;
+
+/* This table is specific for 12.5MHz ref crystal.  */
+static struct pll_parm gPLLTable[] = {
+    /*freq     M   N_int    N_fac  tfgoal  lock_time */
+    { 50,      0,   1,       0,     0xE0,        56}, /*  50.00 MHz */
+    { 75,      0,   5,       0,     0xDE,	     37}, /*  75.00 MHz */
+    {100,      0,   7,       0,     0xE0,        28}, /* 100.00 MHz */
+    {125,      0,   9,       0,     0xE0,        22}, /* 125.00 MHz */
+    {150,      0,   11,      0,     0xE0,        17}, /* 150.00 MHz */
+    {  0,      0,   0,       0,        0,         0}  /* Terminator */
+};
+
+
+static u8 w100_pll_get_testcount(u8 testclk_sel)
+{
+	udelay(5);
+
+	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
+	w100_pwr_state.clk_test_cntl.f.testclk_sel = testclk_sel;
+	w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x1;	/*reset test count */
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+	w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x1;
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	udelay(20);
+
+	w100_pwr_state.clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL);
+	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	return w100_pwr_state.clk_test_cntl.f.test_count;
+}
+
+
+static u8 w100_pll_adjust(void)
+{
+	do {
+		/* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V
+		 * therefore, commented out the following lines
+		 * tf80 meant tf100
+		 * set VCO input = 0.8 * VDD
+		 */
+		w100_pwr_state.pll_cntl.f.pll_dactal = 0xd;
+		writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+		w100_pwr_state.tf80 = w100_pll_get_testcount(0x1);	/* PLLCLK */
+		if (w100_pwr_state.tf80 >= (w100_pwr_state.tfgoal)) {
+			/* set VCO input = 0.2 * VDD */
+			w100_pwr_state.pll_cntl.f.pll_dactal = 0x7;
+			writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+			w100_pwr_state.tf20 = w100_pll_get_testcount(0x1);	/* PLLCLK */
+			if (w100_pwr_state.tf20 <= (w100_pwr_state.tfgoal))
+				return 1; // Success
+
+			if ((w100_pwr_state.pll_cntl.f.pll_vcofr == 0x0) &&
+			    ((w100_pwr_state.pll_cntl.f.pll_pvg == 0x7) ||
+			     (w100_pwr_state.pll_cntl.f.pll_ioffset == 0x0))) {
+				/* slow VCO config */
+				w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1;
+				w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
+				w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
+				writel((u32) (w100_pwr_state.pll_cntl.val),
+					remapped_regs + mmPLL_CNTL);
+				continue;
+			}
+		}
+		if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) {
+			w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1;
+			writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+			continue;
+		}
+		if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) {
+			w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
+			w100_pwr_state.pll_cntl.f.pll_pvg += 0x1;
+			writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+			continue;
+		}
+		return 0; // error
+	} while(1);
+}
+
+
+/*
+ * w100_pll_calibration
+ *                freq = target frequency of the PLL
+ *                (note: crystal = 14.3MHz)
+ */
+static u8 w100_pll_calibration(u32 freq)
+{
+	u8 status;
+
+	/* initial setting */
+	w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0;		/* power down */
+	w100_pwr_state.pll_cntl.f.pll_reset = 0x0;		/* not reset */
+	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1;	/* Hi-Z */
+	w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;		/* VCO gain = 0 */
+	w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;		/* VCO frequency range control = off */
+	w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;	/* current offset inside VCO = 0 */
+	w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	/* check for (tf80 >= tfgoal) && (tf20 =< tfgoal) */
+	if ((w100_pwr_state.tf80 < w100_pwr_state.tfgoal) || (w100_pwr_state.tf20 > w100_pwr_state.tfgoal)) {
+		status=w100_pll_adjust();
+	}
+	/* PLL Reset And Lock */
+
+	/* set VCO input = 0.5 * VDD */
+	w100_pwr_state.pll_cntl.f.pll_dactal = 0xa;
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	/* reset time */
+	udelay(1);
+
+	/* enable charge pump */
+	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0;	/* normal */
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	/* set VCO input = Hi-Z */
+	/* disable DAC */
+	w100_pwr_state.pll_cntl.f.pll_dactal = 0x0;
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	/* lock time */
+	udelay(400);	/* delay 400 us */
+
+	/* PLL locked */
+
+	w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x1;	/* PLL clock */
+	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+
+	w100_pwr_state.tf100 = w100_pll_get_testcount(0x1);	/* PLLCLK */
+
+	return status;
+}
+
+
+static u8 w100_pll_set_clk(void)
+{
+	u8 status;
+
+	if (w100_pwr_state.auto_mode == 1)	/* auto mode */
+	{
+		w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0;	/* disable fast to normal */
+		w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0;	/* disable normal to fast */
+		writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+	}
+
+	w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0;	/* crystal clock */
+	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+
+	w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = w100_pwr_state.M;
+	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = w100_pwr_state.N_int;
+	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = w100_pwr_state.N_fac;
+	w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = w100_pwr_state.lock_time;
+	writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);
+
+	w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0;
+	writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+
+	status = w100_pll_calibration (w100_pwr_state.freq);
+
+	if (w100_pwr_state.auto_mode == 1)	/* auto mode */
+	{
+		w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x1;	/* reenable fast to normal */
+		w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x1;	/* reenable normal to fast  */
+		writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+	}
+	return status;
+}
+
+
+/* assume reference crystal clk is 12.5MHz,
+ * and that doubling is not enabled.
+ *
+ * Freq = 12 == 12.5MHz.
+ */
+static u16 w100_set_slowsysclk(u16 freq)
+{
+	if (w100_pwr_state.norm_sclk == freq)
+		return freq;
+
+	if (w100_pwr_state.auto_mode == 1)	/* auto mode */
+		return 0;
+
+	if (freq == 12) {
+		w100_pwr_state.norm_sclk = freq;
+		w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0;	/* Pslow = 1 */
+		w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0;	/* crystal src */
+
+		writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+
+		w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x1;
+		writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
+
+		w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x1;
+		w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1;
+		writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+		w100_pwr_state.pwm_mode = 1;	/* normal mode */
+		return freq;
+	} else
+		return 0;
+}
+
+
+static u16 w100_set_fastsysclk(u16 freq)
+{
+	u16 pll_freq;
+	int i;
+
+	while(1) {
+		pll_freq = (u16) (freq * (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast + 1));
+		i = 0;
+		do {
+			if (pll_freq == gPLLTable[i].freq) {
+				w100_pwr_state.freq = gPLLTable[i].freq * 1000000;
+				w100_pwr_state.M = gPLLTable[i].M;
+				w100_pwr_state.N_int = gPLLTable[i].N_int;
+				w100_pwr_state.N_fac = gPLLTable[i].N_fac;
+				w100_pwr_state.tfgoal = gPLLTable[i].tfgoal;
+				w100_pwr_state.lock_time = gPLLTable[i].lock_time;
+				w100_pwr_state.tf20 = 0xff;	/* set highest */
+				w100_pwr_state.tf80 = 0x00;	/* set lowest */
+
+				w100_pll_set_clk();
+				w100_pwr_state.pwm_mode = 0;	/* fast mode */
+				w100_pwr_state.fast_sclk = freq;
+				return freq;
+			}
+			i++;
+		} while(gPLLTable[i].freq);
+
+		if (w100_pwr_state.auto_mode == 1)
+			break;
+
+		if (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast == 0)
+			break;
+
+		w100_pwr_state.sclk_cntl.f.sclk_post_div_fast -= 1;
+		writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+	}
+	return 0;
+}
+
+
+/* Set up an initial state.  Some values/fields set
+   here will be overwritten. */
+static void w100_pwm_setup(void)
+{
+	w100_pwr_state.clk_pin_cntl.f.osc_en = 0x1;
+	w100_pwr_state.clk_pin_cntl.f.osc_gain = 0x1f;
+	w100_pwr_state.clk_pin_cntl.f.dont_use_xtalin = 0x0;
+	w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x0;
+	w100_pwr_state.clk_pin_cntl.f.xtalin_dbl_en = 0x0;	/* no freq doubling */
+	w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0;
+	writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
+
+	w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0;	/* Crystal Clk */
+	w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0;	/* Pfast = 1 */
+	w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3;
+	w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0;	/* Pslow = 1 */
+	w100_pwr_state.sclk_cntl.f.disp_cg_ok2switch_en = 0x0;
+	w100_pwr_state.sclk_cntl.f.sclk_force_reg = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_disp = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_mc = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_extmc = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_cp = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_e2 = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_e3 = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_idct = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.sclk_force_bist = 0x0;	/* Dynamic */
+	w100_pwr_state.sclk_cntl.f.busy_extend_cp = 0x0;
+	w100_pwr_state.sclk_cntl.f.busy_extend_e2 = 0x0;
+	w100_pwr_state.sclk_cntl.f.busy_extend_e3 = 0x0;
+	w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0;
+	writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
+
+	w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x0;	/* Crystal Clk */
+	w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1;	/* P = 2 */
+	w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0;	/* Dynamic */
+	writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
+
+	w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = 0x0;	/* M = 1 */
+	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = 0x0;	/* N = 1.0 */
+	w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = 0x0;
+	w100_pwr_state.pll_ref_fb_div.f.pll_reset_time = 0x5;
+	w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = 0xff;
+	writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV);
+
+	w100_pwr_state.pll_cntl.f.pll_pwdn = 0x1;
+	w100_pwr_state.pll_cntl.f.pll_reset = 0x1;
+	w100_pwr_state.pll_cntl.f.pll_pm_en = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_mode = 0x0;	/* uses VCO clock */
+	w100_pwr_state.pll_cntl.f.pll_refclk_sel = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_fbclk_sel = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_pcp = 0x4;
+	w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_pecc_mode = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_pecc_scon = 0x0;
+	w100_pwr_state.pll_cntl.f.pll_dactal = 0x0;	/* Hi-Z */
+	w100_pwr_state.pll_cntl.f.pll_cp_clip = 0x3;
+	w100_pwr_state.pll_cntl.f.pll_conf = 0x2;
+	w100_pwr_state.pll_cntl.f.pll_mbctrl = 0x2;
+	w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
+	writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
+
+	w100_pwr_state.clk_test_cntl.f.testclk_sel = 0x1;	/* PLLCLK (for testing) */
+	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
+	w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
+	writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x0;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1;	/* normal mode (0, 1, 3) */
+	w100_pwr_state.pwrmgt_cntl.f.pwm_wakeup_cond = 0x0;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_cond = 0x1;	/* PM4,ENG */
+	w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_cond = 0x1;	/* PM4,ENG */
+	w100_pwr_state.pwrmgt_cntl.f.pwm_idle_timer = 0xFF;
+	w100_pwr_state.pwrmgt_cntl.f.pwm_busy_timer = 0xFF;
+	writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL);
+
+	w100_pwr_state.auto_mode = 0;	/* manual mode */
+	w100_pwr_state.pwm_mode = 1;	/* normal mode (0, 1, 2) */
+	w100_pwr_state.freq = 50000000;	/* 50 MHz */
+	w100_pwr_state.M = 3;	/* M = 4 */
+	w100_pwr_state.N_int = 6;	/* N = 7.0 */
+	w100_pwr_state.N_fac = 0;
+	w100_pwr_state.tfgoal = 0xE0;
+	w100_pwr_state.lock_time = 56;
+	w100_pwr_state.tf20 = 0xff;	/* set highest */
+	w100_pwr_state.tf80 = 0x00;	/* set lowest */
+	w100_pwr_state.tf100 = 0x00;	/* set lowest */
+	w100_pwr_state.fast_sclk = 50;	/* 50.0 MHz */
+	w100_pwr_state.norm_sclk = 12;	/* 12.5 MHz */
+}
+
+
+static void w100_init_sharp_lcd(u32 mode)
+{
+	u32 temp32;
+	union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl;
+
+	/* Prevent display updates */
+	disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;
+	disp_db_buf_wr_cntl.f.update_db_buf = 0;
+	disp_db_buf_wr_cntl.f.en_db_buf = 0;
+	writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);
+
+	switch(mode) {
+	case LCD_SHARP_QVGA:
+		w100_set_slowsysclk(12);	/* use crystal -- 12.5MHz */
+		/* not use PLL */
+
+		writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
+		writel(0x85FF8000, remapped_regs + mmMC_FB_LOCATION);
+		writel(0x00000003, remapped_regs + mmLCD_FORMAT);
+		writel(0x00CF1C06, remapped_regs + mmGRAPHIC_CTRL);
+		writel(0x01410145, remapped_regs + mmCRTC_TOTAL);
+		writel(0x01170027, remapped_regs + mmACTIVE_H_DISP);
+		writel(0x01410001, remapped_regs + mmACTIVE_V_DISP);
+		writel(0x01170027, remapped_regs + mmGRAPHIC_H_DISP);
+		writel(0x01410001, remapped_regs + mmGRAPHIC_V_DISP);
+		writel(0x81170027, remapped_regs + mmCRTC_SS);
+		writel(0xA0140000, remapped_regs + mmCRTC_LS);
+		writel(0x00400008, remapped_regs + mmCRTC_REV);
+		writel(0xA0000000, remapped_regs + mmCRTC_DCLK);
+		writel(0xC0140014, remapped_regs + mmCRTC_GS);
+		writel(0x00010141, remapped_regs + mmCRTC_VPOS_GS);
+		writel(0x8015010F, remapped_regs + mmCRTC_GCLK);
+		writel(0x80100110, remapped_regs + mmCRTC_GOE);
+		writel(0x00000000, remapped_regs + mmCRTC_FRAME);
+		writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);
+		writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1);
+		writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2);
+		writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1);
+		writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2);
+		writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);
+		writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);
+		writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3);
+		writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET);
+		writel(0x000001e0, remapped_regs + mmGRAPHIC_PITCH);
+		writel(0x000000bf, remapped_regs + mmGPIO_DATA);
+		writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2);
+		writel(0x00000000, remapped_regs + mmGPIO_CNTL1);
+		writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE);
+		break;
+	case LCD_SHARP_VGA:
+		w100_set_slowsysclk(12);	/* use crystal -- 12.5MHz */
+		w100_set_fastsysclk(current_par->fastsysclk_mode);	/* use PLL -- 75.0MHz */
+		w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1;
+		w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x2;
+		writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
+		writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION);
+		writel(0x9FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
+		writel(0x00000003, remapped_regs + mmLCD_FORMAT);
+		writel(0x00DE1D66, remapped_regs + mmGRAPHIC_CTRL);
+
+		writel(0x0283028B, remapped_regs + mmCRTC_TOTAL);
+		writel(0x02360056, remapped_regs + mmACTIVE_H_DISP);
+		writel(0x02830003, remapped_regs + mmACTIVE_V_DISP);
+		writel(0x02360056, remapped_regs + mmGRAPHIC_H_DISP);
+		writel(0x02830003, remapped_regs + mmGRAPHIC_V_DISP);
+		writel(0x82360056, remapped_regs + mmCRTC_SS);
+		writel(0xA0280000, remapped_regs + mmCRTC_LS);
+		writel(0x00400008, remapped_regs + mmCRTC_REV);
+		writel(0xA0000000, remapped_regs + mmCRTC_DCLK);
+		writel(0x80280028, remapped_regs + mmCRTC_GS);
+		writel(0x02830002, remapped_regs + mmCRTC_VPOS_GS);
+		writel(0x8015010F, remapped_regs + mmCRTC_GCLK);
+		writel(0x80100110, remapped_regs + mmCRTC_GOE);
+		writel(0x00000000, remapped_regs + mmCRTC_FRAME);
+		writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS);
+		writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1);
+		writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2);
+		writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1);
+		writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2);
+		writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT);
+		writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR);
+		writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3);
+		writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET);
+		writel(0x000003C0, remapped_regs + mmGRAPHIC_PITCH);
+		writel(0x000000bf, remapped_regs + mmGPIO_DATA);
+		writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2);
+		writel(0x00000000, remapped_regs + mmGPIO_CNTL1);
+		writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE);
+		break;
+	default:
+		break;
+	}
+
+	/* Hack for overlay in ext memory */
+	temp32 = readl(remapped_regs + mmDISP_DEBUG2);
+	temp32 |= 0xc0000000;
+	writel(temp32, remapped_regs + mmDISP_DEBUG2);
+
+	/* Re-enable display updates */
+	disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e;
+	disp_db_buf_wr_cntl.f.update_db_buf = 1;
+	disp_db_buf_wr_cntl.f.en_db_buf = 1;
+	writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL);
+}
+
+
+static void w100_set_vga_rotation_regs(u16 divider, unsigned long ctrl, unsigned long offset, unsigned long pitch)
+{
+	w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1;
+	w100_pwr_state.pclk_cntl.f.pclk_post_div = divider;
+	writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
+
+	writel(ctrl, remapped_regs + mmGRAPHIC_CTRL);
+	writel(offset, remapped_regs + mmGRAPHIC_OFFSET);
+	writel(pitch, remapped_regs + mmGRAPHIC_PITCH);
+
+	/* Re-enable display updates */
+	writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL);
+}
+
+
+static void w100_init_vga_rotation(u16 deg)
+{
+	switch(deg) {
+	case 0:
+		w100_set_vga_rotation_regs(0x02, 0x00DE1D66, 0x00800000, 0x000003c0);
+		break;
+	case 90:
+		w100_set_vga_rotation_regs(0x06, 0x00DE1D0e, 0x00895b00, 0x00000500);
+		break;
+	case 180:
+		w100_set_vga_rotation_regs(0x02, 0x00DE1D7e, 0x00895ffc, 0x000003c0);
+		break;
+	case 270:
+		w100_set_vga_rotation_regs(0x06, 0x00DE1D16, 0x008004fc, 0x00000500);
+		break;
+	default:
+		/* not-support */
+		break;
+	}
+}
+
+
+static void w100_set_qvga_rotation_regs(unsigned long ctrl, unsigned long offset, unsigned long pitch)
+{
+	writel(ctrl, remapped_regs + mmGRAPHIC_CTRL);
+	writel(offset, remapped_regs + mmGRAPHIC_OFFSET);
+	writel(pitch, remapped_regs + mmGRAPHIC_PITCH);
+
+	/* Re-enable display updates */
+	writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL);
+}
+
+
+static void w100_init_qvga_rotation(u16 deg)
+{
+	switch(deg) {
+	case 0:
+		w100_set_qvga_rotation_regs(0x00d41c06, 0x00800000, 0x000001e0);
+		break;
+	case 90:
+		w100_set_qvga_rotation_regs(0x00d41c0E, 0x00825580, 0x00000280);
+		break;
+	case 180:
+		w100_set_qvga_rotation_regs(0x00d41c1e, 0x008257fc, 0x000001e0);
+		break;
+	case 270:
+		w100_set_qvga_rotation_regs(0x00d41c16, 0x0080027c, 0x00000280);
+		break;
+	default:
+		/* not-support */
+		break;
+	}
+}
+
+
+static void w100_suspend(u32 mode)
+{
+	u32 val;
+
+	writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION);
+	writel(0x00FF0000, remapped_regs + mmMC_PERF_MON_CNTL);
+
+	val = readl(remapped_regs + mmMEM_EXT_TIMING_CNTL);
+	val &= ~(0x00100000);	/* bit20=0 */
+	val |= 0xFF000000;	/* bit31:24=0xff */
+	writel(val, remapped_regs + mmMEM_EXT_TIMING_CNTL);
+
+	val = readl(remapped_regs + mmMEM_EXT_CNTL);
+	val &= ~(0x00040000);	/* bit18=0 */
+	val |= 0x00080000;	/* bit19=1 */
+	writel(val, remapped_regs + mmMEM_EXT_CNTL);
+
+	udelay(1);		/* wait 1us */
+
+	if (mode == W100_SUSPEND_EXTMEM) {
+
+		/* CKE: Tri-State */
+		val = readl(remapped_regs + mmMEM_EXT_CNTL);
+		val |= 0x40000000;	/* bit30=1 */
+		writel(val, remapped_regs + mmMEM_EXT_CNTL);
+
+		/* CLK: Stop */
+		val = readl(remapped_regs + mmMEM_EXT_CNTL);
+		val &= ~(0x00000001);	/* bit0=0 */
+		writel(val, remapped_regs + mmMEM_EXT_CNTL);
+	} else {
+
+		writel(0x00000000, remapped_regs + mmSCLK_CNTL);
+		writel(0x000000BF, remapped_regs + mmCLK_PIN_CNTL);
+		writel(0x00000015, remapped_regs + mmPWRMGT_CNTL);
+
+		udelay(5);
+
+		val = readl(remapped_regs + mmPLL_CNTL);
+		val |= 0x00000004;	/* bit2=1 */
+		writel(val, remapped_regs + mmPLL_CNTL);
+		writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL);
+	}
+}
+
+
+static void w100_resume(void)
+{
+	u32 temp32;
+
+	w100_hw_init();
+	w100_pwm_setup();
+
+	temp32 = readl(remapped_regs + mmDISP_DEBUG2);
+	temp32 &= 0xff7fffff;
+	temp32 |= 0x00800000;
+	writel(temp32, remapped_regs + mmDISP_DEBUG2);
+
+	if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) {
+		w100_init_sharp_lcd(LCD_SHARP_VGA);
+		if (current_par->lcdMode == LCD_MODE_640) {
+			w100_init_vga_rotation(current_par->rotation_flag ? 270 : 90);
+		}
+	} else {
+		w100_init_sharp_lcd(LCD_SHARP_QVGA);
+		if (current_par->lcdMode == LCD_MODE_320) {
+			w100_init_qvga_rotation(current_par->rotation_flag ? 270 : 90);
+		}
+	}
+}
+
+
+static void w100_vsync(void)
+{
+	u32 tmp;
+	int timeout = 30000; /* VSync timeout = 30[ms] > 16.8[ms] */
+
+	tmp = readl(remapped_regs + mmACTIVE_V_DISP);
+
+	/* set vline pos  */
+	writel((tmp >> 16) & 0x3ff, remapped_regs + mmDISP_INT_CNTL);
+
+	/* disable vline irq */
+	tmp = readl(remapped_regs + mmGEN_INT_CNTL);
+
+	tmp &= ~0x00000002;
+	writel(tmp, remapped_regs + mmGEN_INT_CNTL);
+
+	/* clear vline irq status */
+	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
+
+	/* enable vline irq */
+	writel((tmp | 0x00000002), remapped_regs + mmGEN_INT_CNTL);
+
+	/* clear vline irq status */
+	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
+
+	while(timeout > 0) {
+		if (readl(remapped_regs + mmGEN_INT_STATUS) & 0x00000002)
+			break;
+		udelay(1);
+		timeout--;
+	}
+
+	/* disable vline irq */
+	writel(tmp, remapped_regs + mmGEN_INT_CNTL);
+
+	/* clear vline irq status */
+	writel(0x00000002, remapped_regs + mmGEN_INT_STATUS);
+}
+
+
+static void w100_InitExtMem(u32 mode)
+{
+	switch(mode) {
+	case LCD_SHARP_QVGA:
+		/* QVGA doesn't use external memory
+		   nothing to do, really. */
+		break;
+	case LCD_SHARP_VGA:
+		writel(0x00007800, remapped_regs + mmMC_BIST_CTRL);
+		writel(0x00040003, remapped_regs + mmMEM_EXT_CNTL);
+		writel(0x00200021, remapped_regs + mmMEM_SDRAM_MODE_REG);
+		udelay(100);
+		writel(0x80200021, remapped_regs + mmMEM_SDRAM_MODE_REG);
+		udelay(100);
+		writel(0x00650021, remapped_regs + mmMEM_SDRAM_MODE_REG);
+		udelay(100);
+		writel(0x10002a4a, remapped_regs + mmMEM_EXT_TIMING_CNTL);
+		writel(0x7ff87012, remapped_regs + mmMEM_IO_CNTL);
+		break;
+	default:
+		break;
+	}
+}
+
+
+#define RESCTL_ADRS     0x00
+#define PHACTRL_ADRS	0x01
+#define DUTYCTRL_ADRS	0x02
+#define POWERREG0_ADRS	0x03
+#define POWERREG1_ADRS	0x04
+#define GPOR3_ADRS		0x05
+#define PICTRL_ADRS     0x06
+#define POLCTRL_ADRS    0x07
+
+#define RESCTL_QVGA     0x01
+#define RESCTL_VGA      0x00
+
+#define POWER1_VW_ON	0x01	/* VW Supply FET ON */
+#define POWER1_GVSS_ON	0x02	/* GVSS(-8V) Power Supply ON */
+#define POWER1_VDD_ON	0x04	/* VDD(8V),SVSS(-4V) Power Supply ON */
+
+#define POWER1_VW_OFF	0x00	/* VW Supply FET OFF */
+#define POWER1_GVSS_OFF	0x00	/* GVSS(-8V) Power Supply OFF */
+#define POWER1_VDD_OFF	0x00	/* VDD(8V),SVSS(-4V) Power Supply OFF */
+
+#define POWER0_COM_DCLK	0x01	/* COM Voltage DC Bias DAC Serial Data Clock */
+#define POWER0_COM_DOUT	0x02	/* COM Voltage DC Bias DAC Serial Data Out */
+#define POWER0_DAC_ON	0x04	/* DAC Power Supply ON */
+#define POWER0_COM_ON	0x08	/* COM Powewr Supply ON */
+#define POWER0_VCC5_ON	0x10	/* VCC5 Power Supply ON */
+
+#define POWER0_DAC_OFF	0x00	/* DAC Power Supply OFF */
+#define POWER0_COM_OFF	0x00	/* COM Powewr Supply OFF */
+#define POWER0_VCC5_OFF	0x00	/* VCC5 Power Supply OFF */
+
+#define PICTRL_INIT_STATE	0x01
+#define PICTRL_INIOFF		0x02
+#define PICTRL_POWER_DOWN	0x04
+#define PICTRL_COM_SIGNAL_OFF	0x08
+#define PICTRL_DAC_SIGNAL_OFF	0x10
+
+#define PICTRL_POWER_ACTIVE	(0)
+
+#define POLCTRL_SYNC_POL_FALL	0x01
+#define POLCTRL_EN_POL_FALL	0x02
+#define POLCTRL_DATA_POL_FALL	0x04
+#define POLCTRL_SYNC_ACT_H	0x08
+#define POLCTRL_EN_ACT_L	0x10
+
+#define POLCTRL_SYNC_POL_RISE	0x00
+#define POLCTRL_EN_POL_RISE	0x00
+#define POLCTRL_DATA_POL_RISE	0x00
+#define POLCTRL_SYNC_ACT_L	0x00
+#define POLCTRL_EN_ACT_H	0x00
+
+#define PHACTRL_PHASE_MANUAL	0x01
+
+#define PHAD_QVGA_DEFAULT_VAL (9)
+#define COMADJ_DEFAULT        (125)
+
+static void lcdtg_ssp_send(u8 adrs, u8 data)
+{
+	w100fb_ssp_send(adrs,data);
+}
+
+/*
+ * This is only a psuedo I2C interface. We can't use the standard kernel
+ * routines as the interface is write only. We just assume the data is acked...
+ */
+static void lcdtg_ssp_i2c_send(u8 data)
+{
+	lcdtg_ssp_send(POWERREG0_ADRS, data);
+	udelay(10);
+}
+
+static void lcdtg_i2c_send_bit(u8 data)
+{
+	lcdtg_ssp_i2c_send(data);
+	lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(data);
+}
+
+static void lcdtg_i2c_send_start(u8 base)
+{
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(base);
+}
+
+static void lcdtg_i2c_send_stop(u8 base)
+{
+	lcdtg_ssp_i2c_send(base);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
+	lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
+}
+
+static void lcdtg_i2c_send_byte(u8 base, u8 data)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		if (data & 0x80)
+			lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
+		else
+			lcdtg_i2c_send_bit(base);
+		data <<= 1;
+	}
+}
+
+static void lcdtg_i2c_wait_ack(u8 base)
+{
+	lcdtg_i2c_send_bit(base);
+}
+
+static void lcdtg_set_common_voltage(u8 base_data, u8 data)
+{
+	/* Set Common Voltage to M62332FP via I2C */
+	lcdtg_i2c_send_start(base_data);
+	lcdtg_i2c_send_byte(base_data, 0x9c);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_byte(base_data, 0x00);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_byte(base_data, data);
+	lcdtg_i2c_wait_ack(base_data);
+	lcdtg_i2c_send_stop(base_data);
+}
+
+static struct lcdtg_register_setting {
+	u8 adrs;
+	u8 data;
+	u32 wait;
+} lcdtg_power_on_table[] = {
+
+    /* Initialize Internal Logic & Port */
+    { PICTRL_ADRS,
+      PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE |
+      PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF,
+      0 },
+
+    { POWERREG0_ADRS,
+      POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF | POWER0_COM_OFF |
+      POWER0_VCC5_OFF,
+      0 },
+
+    { POWERREG1_ADRS,
+      POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF,
+      0 },
+
+    /* VDD(+8V),SVSS(-4V) ON */
+    { POWERREG1_ADRS,
+      POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON /* VDD ON */,
+      3000 },
+
+    /* DAC ON */
+    { POWERREG0_ADRS,
+      POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
+      POWER0_COM_OFF | POWER0_VCC5_OFF,
+      0 },
+
+    /* INIB = H, INI = L  */
+    { PICTRL_ADRS,
+      /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
+      PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF,
+      0 },
+
+    /* Set Common Voltage */
+    { 0xfe, 0, 0 },
+
+    /* VCC5 ON */
+    { POWERREG0_ADRS,
+      POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
+      POWER0_COM_OFF | POWER0_VCC5_ON /* VCC5 ON */,
+      0 },
+
+    /* GVSS(-8V) ON */
+    { POWERREG1_ADRS,
+      POWER1_VW_OFF | POWER1_GVSS_ON /* GVSS ON */ |
+      POWER1_VDD_ON /* VDD ON */,
+      2000 },
+
+    /* COM SIGNAL ON (PICTL[3] = L) */
+    { PICTRL_ADRS,
+      PICTRL_INIT_STATE,
+      0 },
+
+    /* COM ON */
+    { POWERREG0_ADRS,
+      POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ |
+      POWER0_COM_ON /* COM ON */ | POWER0_VCC5_ON /* VCC5_ON */,
+      0 },
+
+    /* VW ON */
+    { POWERREG1_ADRS,
+      POWER1_VW_ON /* VW ON */ | POWER1_GVSS_ON /* GVSS ON */ |
+      POWER1_VDD_ON /* VDD ON */,
+      0 /* Wait 100ms */ },
+
+    /* Signals output enable */
+    { PICTRL_ADRS,
+      0 /* Signals output enable */,
+      0 },
+
+    { PHACTRL_ADRS,
+      PHACTRL_PHASE_MANUAL,
+      0 },
+
+    /* Initialize for Input Signals from ATI */
+    { POLCTRL_ADRS,
+      POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE | POLCTRL_DATA_POL_RISE |
+      POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H,
+      1000 /*100000*/ /* Wait 100ms */ },
+
+    /* end mark */
+    { 0xff, 0, 0 }
+};
+
+static void lcdtg_resume(void)
+{
+	if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) {
+		lcdtg_hw_init(LCD_SHARP_VGA);
+	} else {
+		lcdtg_hw_init(LCD_SHARP_QVGA);
+	}
+}
+
+static void lcdtg_suspend(void)
+{
+	int i;
+
+	for (i = 0; i < (current_par->xres * current_par->yres); i++) {
+		writew(0xffff, remapped_fbuf + (2*i));
+	}
+
+	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
+	mdelay(34);
+
+	/* (1)VW OFF */
+	lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
+
+	/* (2)COM OFF */
+	lcdtg_ssp_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
+	lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
+
+	/* (3)Set Common Voltage Bias 0V */
+	lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
+
+	/* (4)GVSS OFF */
+	lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
+
+	/* (5)VCC5 OFF */
+	lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (6)Set PDWN, INIOFF, DACOFF */
+	lcdtg_ssp_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
+			PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
+
+	/* (7)DAC OFF */
+	lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
+
+	/* (8)VDD OFF */
+	lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
+
+}
+
+static void lcdtg_set_phadadj(u32 mode)
+{
+	int adj;
+
+	if (mode == LCD_SHARP_VGA) {
+		/* Setting for VGA */
+		adj = current_par->phadadj;
+		if (adj < 0) {
+			adj = PHACTRL_PHASE_MANUAL;
+		} else {
+			adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
+		}
+	} else {
+		/* Setting for QVGA */
+		adj = (PHAD_QVGA_DEFAULT_VAL << 1) | PHACTRL_PHASE_MANUAL;
+	}
+	lcdtg_ssp_send(PHACTRL_ADRS, adj);
+}
+
+static void lcdtg_hw_init(u32 mode)
+{
+	int i;
+	int comadj;
+
+	i = 0;
+	while(lcdtg_power_on_table[i].adrs != 0xff) {
+		if (lcdtg_power_on_table[i].adrs == 0xfe) {
+			/* Set Common Voltage */
+			comadj = current_par->comadj;
+			if (comadj < 0) {
+				comadj = COMADJ_DEFAULT;
+			}
+			lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
+		} else if (lcdtg_power_on_table[i].adrs == PHACTRL_ADRS) {
+			/* Set Phase Adjuct */
+			lcdtg_set_phadadj(mode);
+		} else {
+			/* Other */
+			lcdtg_ssp_send(lcdtg_power_on_table[i].adrs, lcdtg_power_on_table[i].data);
+		}
+		if (lcdtg_power_on_table[i].wait != 0)
+			udelay(lcdtg_power_on_table[i].wait);
+		i++;
+	}
+
+	switch(mode) {
+	case LCD_SHARP_QVGA:
+		/* Set Lcd Resolution (QVGA) */
+		lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA);
+		break;
+	case LCD_SHARP_VGA:
+		/* Set Lcd Resolution (VGA) */
+		lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA);
+		break;
+	default:
+		break;
+	}
+}
+
+static void lcdtg_lcd_change(u32 mode)
+{
+	/* Set Phase Adjuct */
+	lcdtg_set_phadadj(mode);
+
+	if (mode == LCD_SHARP_VGA)
+		/* Set Lcd Resolution (VGA) */
+		lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA);
+	else if (mode == LCD_SHARP_QVGA)
+		/* Set Lcd Resolution (QVGA) */
+		lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA);
+}
+
+
+static struct device_driver w100fb_driver = {
+	.name		= "w100fb",
+	.bus		= &platform_bus_type,
+	.probe		= w100fb_probe,
+	.remove		= w100fb_remove,
+	.suspend	= w100fb_suspend,
+	.resume		= w100fb_resume,
+};
+
+int __devinit w100fb_init(void)
+{
+	return driver_register(&w100fb_driver);
+}
+
+void __exit w100fb_cleanup(void)
+{
+ 	driver_unregister(&w100fb_driver);
+}
+
+module_init(w100fb_init);
+module_exit(w100fb_cleanup);
+
+MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver");
+MODULE_LICENSE("GPLv2");
diff -Nru a/drivers/video/w100fb.h b/drivers/video/w100fb.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/video/w100fb.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,615 @@
+/*
+ * linux/drivers/video/w100fb.h
+ *
+ * Frame Buffer Device for ATI w100 (Wallaby)
+ *
+ * Copyright (C) 2002, ATI Corp.
+ * Copyright (C) 2004-2005 Richard Purdie
+ *
+ * Modified to work with 2.6 by Richard Purdie <rpurdie@rpsys.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#if !defined (_W100FB_H)
+#define _W100FB_H
+
+/* Block CIF Start: */
+#define mmCHIP_ID           0x0000
+#define mmREVISION_ID		0x0004
+#define mmWRAP_BUF_A        0x0008
+#define mmWRAP_BUF_B        0x000C
+#define mmWRAP_TOP_DIR      0x0010
+#define mmWRAP_START_DIR    0x0014
+#define mmCIF_CNTL          0x0018
+#define mmCFGREG_BASE       0x001C
+#define mmCIF_IO            0x0020
+#define mmCIF_READ_DBG      0x0024
+#define mmCIF_WRITE_DBG     0x0028
+#define cfgIND_ADDR_A_0     0x0000
+#define cfgIND_ADDR_A_1     0x0001
+#define cfgIND_ADDR_A_2     0x0002
+#define cfgIND_DATA_A       0x0003
+#define cfgREG_BASE         0x0004
+#define cfgINTF_CNTL        0x0005
+#define cfgSTATUS           0x0006
+#define cfgCPU_DEFAULTS     0x0007
+#define cfgIND_ADDR_B_0     0x0008
+#define cfgIND_ADDR_B_1     0x0009
+#define cfgIND_ADDR_B_2     0x000A
+#define cfgIND_DATA_B       0x000B
+#define cfgPM4_RPTR         0x000C
+#define cfgSCRATCH          0x000D
+#define cfgPM4_WRPTR_0      0x000E
+#define cfgPM4_WRPTR_1      0x000F
+/* Block CIF End: */
+
+/* Block CP Start: */
+#define mmSCRATCH_UMSK      0x0280
+#define mmSCRATCH_ADDR      0x0284
+#define mmGEN_INT_CNTL      0x0200
+#define mmGEN_INT_STATUS    0x0204
+/* Block CP End: */
+
+/* Block DISPLAY Start: */
+#define mmLCD_FORMAT        0x0410
+#define mmGRAPHIC_CTRL      0x0414
+#define mmGRAPHIC_OFFSET    0x0418
+#define mmGRAPHIC_PITCH     0x041C
+#define mmCRTC_TOTAL        0x0420
+#define mmACTIVE_H_DISP     0x0424
+#define mmACTIVE_V_DISP     0x0428
+#define mmGRAPHIC_H_DISP    0x042C
+#define mmGRAPHIC_V_DISP    0x0430
+#define mmVIDEO_CTRL        0x0434
+#define mmGRAPHIC_KEY       0x0438
+#define mmBRIGHTNESS_CNTL   0x045C
+#define mmDISP_INT_CNTL     0x0488
+#define mmCRTC_SS           0x048C
+#define mmCRTC_LS           0x0490
+#define mmCRTC_REV          0x0494
+#define mmCRTC_DCLK         0x049C
+#define mmCRTC_GS           0x04A0
+#define mmCRTC_VPOS_GS      0x04A4
+#define mmCRTC_GCLK         0x04A8
+#define mmCRTC_GOE          0x04AC
+#define mmCRTC_FRAME        0x04B0
+#define mmCRTC_FRAME_VPOS   0x04B4
+#define mmGPIO_DATA         0x04B8
+#define mmGPIO_CNTL1        0x04BC
+#define mmGPIO_CNTL2        0x04C0
+#define mmLCDD_CNTL1        0x04C4
+#define mmLCDD_CNTL2        0x04C8
+#define mmGENLCD_CNTL1      0x04CC
+#define mmGENLCD_CNTL2      0x04D0
+#define mmDISP_DEBUG        0x04D4
+#define mmDISP_DB_BUF_CNTL  0x04D8
+#define mmDISP_CRC_SIG      0x04DC
+#define mmCRTC_DEFAULT_COUNT 	0x04E0
+#define mmLCD_BACKGROUND_COLOR  0x04E4
+#define mmCRTC_PS2          0x04E8
+#define mmCRTC_PS2_VPOS     0x04EC
+#define mmCRTC_PS1_ACTIVE   0x04F0
+#define mmCRTC_PS1_NACTIVE  0x04F4
+#define mmCRTC_GCLK_EXT     0x04F8
+#define mmCRTC_ALW          0x04FC
+#define mmCRTC_ALW_VPOS     0x0500
+#define mmCRTC_PSK          0x0504
+#define mmCRTC_PSK_HPOS     0x0508
+#define mmCRTC_CV4_START    0x050C
+#define mmCRTC_CV4_END      0x0510
+#define mmCRTC_CV4_HPOS     0x0514
+#define mmCRTC_ECK          0x051C
+#define mmREFRESH_CNTL      0x0520
+#define mmGENLCD_CNTL3      0x0524
+#define mmGPIO_DATA2        0x0528
+#define mmGPIO_CNTL3        0x052C
+#define mmGPIO_CNTL4        0x0530
+#define mmCHIP_STRAP        0x0534
+#define mmDISP_DEBUG2       0x0538
+#define mmDEBUG_BUS_CNTL    0x053C
+#define mmGAMMA_VALUE1      0x0540
+#define mmGAMMA_VALUE2      0x0544
+#define mmGAMMA_SLOPE       0x0548
+#define mmGEN_STATUS        0x054C
+#define mmHW_INT            0x0550
+/* Block DISPLAY End: */
+
+/* Block GFX Start: */
+#define mmBRUSH_OFFSET      0x108C
+#define mmBRUSH_Y_X         0x1074
+#define mmDEFAULT_PITCH_OFFSET		0x10A0
+#define mmDEFAULT_SC_BOTTOM_RIGHT	0x10A8
+#define mmDEFAULT2_SC_BOTTOM_RIGHT	0x10AC
+#define mmGLOBAL_ALPHA      0x1210
+#define mmFILTER_COEF       0x1214
+#define mmMVC_CNTL_START    0x11E0
+#define mmE2_ARITHMETIC_CNTL	0x1220
+#define mmENG_CNTL          0x13E8
+#define mmENG_PERF_CNT      0x13F0
+/* Block GFX End: */
+
+/* Block IDCT Start: */
+#define mmIDCT_RUNS         0x0C00
+#define mmIDCT_LEVELS       0x0C04
+#define mmIDCT_CONTROL      0x0C3C
+#define mmIDCT_AUTH_CONTROL 0x0C08
+#define mmIDCT_AUTH         0x0C0C
+/* Block IDCT End: */
+
+/* Block MC Start: */
+#define mmMEM_CNTL          0x0180
+#define mmMEM_ARB           0x0184
+#define mmMC_FB_LOCATION    0x0188
+#define mmMEM_EXT_CNTL      0x018C
+#define mmMC_EXT_MEM_LOCATION   0x0190
+#define mmMEM_EXT_TIMING_CNTL   0x0194
+#define mmMEM_SDRAM_MODE_REG	0x0198
+#define mmMEM_IO_CNTL       0x019C
+#define mmMC_DEBUG          0x01A0
+#define mmMC_BIST_CTRL      0x01A4
+#define mmMC_BIST_COLLAR_READ  	0x01A8
+#define mmTC_MISMATCH       0x01AC
+#define mmMC_PERF_MON_CNTL  0x01B0
+#define mmMC_PERF_COUNTERS  0x01B4
+/* Block MC End: */
+
+/* Block RBBM Start: */
+#define mmWAIT_UNTIL        0x1400
+#define mmISYNC_CNTL        0x1404
+#define mmRBBM_CNTL         0x0144
+#define mmNQWAIT_UNTIL      0x0150
+/* Block RBBM End: */
+
+/* Block CG Start: */
+#define mmCLK_PIN_CNTL      0x0080
+#define mmPLL_REF_FB_DIV    0x0084
+#define mmPLL_CNTL          0x0088
+#define mmSCLK_CNTL         0x008C
+#define mmPCLK_CNTL         0x0090
+#define mmCLK_TEST_CNTL     0x0094
+#define mmPWRMGT_CNTL       0x0098
+#define mmPWRMGT_STATUS     0x009C
+/* Block CG End: */
+
+/* default value definitions */
+#define defWRAP_TOP_DIR     0x00000000
+#define defWRAP_START_DIR	0x00000000
+#define defCFGREG_BASE      0x00000000
+#define defCIF_IO           0x000C0902
+#define defINTF_CNTL        0x00000011
+#define defCPU_DEFAULTS     0x00000006
+#define defHW_INT           0x00000000
+#define defMC_EXT_MEM_LOCATION            0x07ff0000
+#define defTC_MISMATCH      0x00000000
+
+#define W100_CFG_BASE          0x0
+#define W100_CFG_LEN           0x10
+#define W100_REG_BASE          0x10000
+#define W100_REG_LEN           0x2000
+#define MEM_INT_BASE_VALUE     0x100000
+#define MEM_INT_TOP_VALUE_W100 0x15ffff
+#define MEM_EXT_BASE_VALUE     0x800000
+#define MEM_EXT_TOP_VALUE      0x9fffff
+#define WRAP_BUF_BASE_VALUE    0x80000
+#define WRAP_BUF_TOP_VALUE     0xbffff
+
+
+/* data structure definitions */
+
+struct wrap_top_dir_t {
+     unsigned long top_addr         : 23;
+     unsigned long    				: 9;
+} __attribute__((packed));
+
+union wrap_top_dir_u {
+     unsigned long val : 32;
+     struct wrap_top_dir_t f;
+} __attribute__((packed));
+
+struct wrap_start_dir_t {
+     unsigned long start_addr       : 23;
+     unsigned long    				: 9;
+} __attribute__((packed));
+
+union wrap_start_dir_u {
+     unsigned long val : 32;
+     struct wrap_start_dir_t f;
+} __attribute__((packed));
+
+struct cif_cntl_t {
+     unsigned long swap_reg         		: 2;
+     unsigned long swap_fbuf_1      		: 2;
+     unsigned long swap_fbuf_2      		: 2;
+     unsigned long swap_fbuf_3      		: 2;
+     unsigned long pmi_int_disable  		: 1;
+     unsigned long pmi_schmen_disable       : 1;
+     unsigned long intb_oe          		: 1;
+     unsigned long en_wait_to_compensate_dq_prop_dly : 1;
+     unsigned long compensate_wait_rd_size  : 2;
+     unsigned long wait_asserted_timeout_val      : 2;
+     unsigned long wait_masked_val  		: 2;
+     unsigned long en_wait_timeout  		: 1;
+     unsigned long en_one_clk_setup_before_wait   : 1;
+     unsigned long interrupt_active_high    : 1;
+     unsigned long en_overwrite_straps      : 1;
+     unsigned long strap_wait_active_hi     : 1;
+     unsigned long lat_busy_count   		: 2;
+     unsigned long lat_rd_pm4_sclk_busy     : 1;
+     unsigned long dis_system_bits  		: 1;
+     unsigned long dis_mr           		: 1;
+     unsigned long cif_spare_1      		: 4;
+} __attribute__((packed));
+
+union cif_cntl_u {
+     unsigned long val : 32;
+     struct cif_cntl_t f;
+} __attribute__((packed));
+
+struct cfgreg_base_t {
+     unsigned long cfgreg_base      : 24;
+     unsigned long    				: 8;
+} __attribute__((packed));
+
+union cfgreg_base_u {
+     unsigned long val : 32;
+     struct cfgreg_base_t f;
+} __attribute__((packed));
+
+struct cif_io_t {
+     unsigned long dq_srp           : 1;
+     unsigned long dq_srn           : 1;
+     unsigned long dq_sp            : 4;
+     unsigned long dq_sn            : 4;
+     unsigned long waitb_srp        : 1;
+     unsigned long waitb_srn        : 1;
+     unsigned long waitb_sp         : 4;
+     unsigned long waitb_sn         : 4;
+     unsigned long intb_srp         : 1;
+     unsigned long intb_srn         : 1;
+     unsigned long intb_sp          : 4;
+     unsigned long intb_sn          : 4;
+     unsigned long    				: 2;
+} __attribute__((packed));
+
+union cif_io_u {
+     unsigned long val : 32;
+     struct cif_io_t f;
+} __attribute__((packed));
+
+struct cif_read_dbg_t {
+     unsigned long unpacker_pre_fetch_trig_gen  : 2;
+     unsigned long dly_second_rd_fetch_trig     : 1;
+     unsigned long rst_rd_burst_id  			: 1;
+     unsigned long dis_rd_burst_id  			: 1;
+     unsigned long en_block_rd_when_packer_is_not_emp : 1;
+     unsigned long dis_pre_fetch_cntl_sm        : 1;
+     unsigned long rbbm_chrncy_dis  			: 1;
+     unsigned long rbbm_rd_after_wr_lat         : 2;
+     unsigned long dis_be_during_rd 			: 1;
+     unsigned long one_clk_invalidate_pulse     : 1;
+     unsigned long dis_chnl_priority			: 1;
+     unsigned long rst_read_path_a_pls          : 1;
+     unsigned long rst_read_path_b_pls          : 1;
+     unsigned long dis_reg_rd_fetch_trig        : 1;
+     unsigned long dis_rd_fetch_trig_from_ind_addr : 1;
+     unsigned long dis_rd_same_byte_to_trig_fetch : 1;
+     unsigned long dis_dir_wrap     			: 1;
+     unsigned long dis_ring_buf_to_force_dec    : 1;
+     unsigned long dis_addr_comp_in_16bit       : 1;
+     unsigned long clr_w            			: 1;
+     unsigned long err_rd_tag_is_3  			: 1;
+     unsigned long err_load_when_ful_a          : 1;
+     unsigned long err_load_when_ful_b          : 1;
+     unsigned long    							: 7;
+} __attribute__((packed));
+
+union cif_read_dbg_u {
+     unsigned long val : 32;
+     struct cif_read_dbg_t f;
+} __attribute__((packed));
+
+struct cif_write_dbg_t {
+     unsigned long packer_timeout_count           : 2;
+     unsigned long en_upper_load_cond             : 1;
+     unsigned long en_chnl_change_cond            : 1;
+     unsigned long dis_addr_comp_cond             : 1;
+     unsigned long dis_load_same_byte_addr_cond   : 1;
+     unsigned long dis_timeout_cond 			  : 1;
+     unsigned long dis_timeout_during_rbbm        : 1;
+     unsigned long dis_packer_ful_during_rbbm_timeout : 1;
+     unsigned long en_dword_split_to_rbbm         : 1;
+     unsigned long en_dummy_val     			  : 1;
+     unsigned long dummy_val_sel    			  : 1;
+     unsigned long mask_pm4_wrptr_dec             : 1;
+     unsigned long dis_mc_clean_cond			  : 1;
+     unsigned long err_two_reqi_during_ful        : 1;
+     unsigned long err_reqi_during_idle_clk       : 1;
+     unsigned long err_global       			  : 1;
+     unsigned long en_wr_buf_dbg_load             : 1;
+     unsigned long en_wr_buf_dbg_path             : 1;
+     unsigned long sel_wr_buf_byte  			  : 3;
+     unsigned long dis_rd_flush_wr  			  : 1;
+     unsigned long dis_packer_ful_cond            : 1;
+     unsigned long dis_invalidate_by_ops_chnl     : 1;
+     unsigned long en_halt_when_reqi_err          : 1;
+     unsigned long cif_spare_2      			  : 5;
+     unsigned long    							  : 1;
+} __attribute__((packed));
+
+union cif_write_dbg_u {
+     unsigned long val : 32;
+     struct cif_write_dbg_t f;
+} __attribute__((packed));
+
+
+struct intf_cntl_t {
+     unsigned char ad_inc_a            : 1;
+     unsigned char ring_buf_a          : 1;
+     unsigned char rd_fetch_trigger_a  : 1;
+     unsigned char rd_data_rdy_a       : 1;
+     unsigned char ad_inc_b            : 1;
+     unsigned char ring_buf_b          : 1;
+     unsigned char rd_fetch_trigger_b  : 1;
+     unsigned char rd_data_rdy_b       : 1;
+} __attribute__((packed));
+
+union intf_cntl_u {
+     unsigned char val : 8;
+     struct intf_cntl_t f;
+} __attribute__((packed));
+
+struct cpu_defaults_t {
+     unsigned char unpack_rd_data   : 1;
+     unsigned char access_ind_addr_a: 1;
+     unsigned char access_ind_addr_b: 1;
+     unsigned char access_scratch_reg             : 1;
+     unsigned char pack_wr_data     : 1;
+     unsigned char transition_size  : 1;
+     unsigned char en_read_buf_mode : 1;
+     unsigned char rd_fetch_scratch : 1;
+} __attribute__((packed));
+
+union cpu_defaults_u {
+     unsigned char val : 8;
+     struct cpu_defaults_t f;
+} __attribute__((packed));
+
+struct video_ctrl_t {
+     unsigned long video_mode       : 1;
+     unsigned long keyer_en         : 1;
+     unsigned long en_video_req     : 1;
+     unsigned long en_graphic_req_video           : 1;
+     unsigned long en_video_crtc    : 1;
+     unsigned long video_hor_exp    : 2;
+     unsigned long video_ver_exp    : 2;
+     unsigned long uv_combine       : 1;
+     unsigned long total_req_video  : 9;
+     unsigned long video_ch_sel     : 1;
+     unsigned long video_portrait   : 2;
+     unsigned long yuv2rgb_en       : 1;
+     unsigned long yuv2rgb_option   : 1;
+     unsigned long video_inv_hor    : 1;
+     unsigned long video_inv_ver    : 1;
+     unsigned long gamma_sel        : 2;
+     unsigned long dis_limit        : 1;
+     unsigned long en_uv_hblend     : 1;
+     unsigned long rgb_gamma_sel    : 2;
+} __attribute__((packed));
+
+union video_ctrl_u {
+     unsigned long val : 32;
+     struct video_ctrl_t f;
+} __attribute__((packed));
+
+struct disp_db_buf_cntl_rd_t {
+     unsigned long en_db_buf        	: 1;
+     unsigned long update_db_buf_done   : 1;
+     unsigned long db_buf_cntl      	: 6;
+     unsigned long    					: 24;
+} __attribute__((packed));
+
+union disp_db_buf_cntl_rd_u {
+     unsigned long val : 32;
+     struct disp_db_buf_cntl_rd_t f;
+} __attribute__((packed));
+
+struct disp_db_buf_cntl_wr_t {
+     unsigned long en_db_buf        : 1;
+     unsigned long update_db_buf    : 1;
+     unsigned long db_buf_cntl      : 6;
+     unsigned long    : 24;
+} __attribute__((packed));
+
+union disp_db_buf_cntl_wr_u {
+     unsigned long val : 32;
+     struct disp_db_buf_cntl_wr_t f;
+} __attribute__((packed));
+
+struct gamma_value1_t {
+     unsigned long gamma1           : 8;
+     unsigned long gamma2           : 8;
+     unsigned long gamma3           : 8;
+     unsigned long gamma4           : 8;
+} __attribute__((packed));
+
+union gamma_value1_u {
+     unsigned long val : 32;
+     struct gamma_value1_t f;
+} __attribute__((packed));
+
+struct gamma_value2_t {
+     unsigned long gamma5           : 8;
+     unsigned long gamma6           : 8;
+     unsigned long gamma7           : 8;
+     unsigned long gamma8           : 8;
+} __attribute__((packed));
+
+union gamma_value2_u {
+     unsigned long val : 32;
+     struct gamma_value2_t f;
+} __attribute__((packed));
+
+struct gamma_slope_t {
+     unsigned long slope1           : 3;
+     unsigned long slope2           : 3;
+     unsigned long slope3           : 3;
+     unsigned long slope4           : 3;
+     unsigned long slope5           : 3;
+     unsigned long slope6           : 3;
+     unsigned long slope7           : 3;
+     unsigned long slope8           : 3;
+     unsigned long    				: 8;
+} __attribute__((packed));
+
+union gamma_slope_u {
+     unsigned long val : 32;
+     struct gamma_slope_t f;
+} __attribute__((packed));
+
+struct mc_ext_mem_location_t {
+     unsigned long mc_ext_mem_start : 16;
+     unsigned long mc_ext_mem_top   : 16;
+} __attribute__((packed));
+
+union mc_ext_mem_location_u {
+     unsigned long val : 32;
+     struct mc_ext_mem_location_t f;
+} __attribute__((packed));
+
+struct clk_pin_cntl_t {
+     unsigned long osc_en           : 1;
+     unsigned long osc_gain         : 5;
+     unsigned long dont_use_xtalin  : 1;
+     unsigned long xtalin_pm_en     : 1;
+     unsigned long xtalin_dbl_en    : 1;
+     unsigned long    				: 7;
+     unsigned long cg_debug         : 16;
+} __attribute__((packed));
+
+union clk_pin_cntl_u {
+     unsigned long val : 32;
+     struct clk_pin_cntl_t f;
+} __attribute__((packed));
+
+struct pll_ref_fb_div_t {
+     unsigned long pll_ref_div      : 4;
+     unsigned long    				: 4;
+     unsigned long pll_fb_div_int   : 6;
+     unsigned long    				: 2;
+     unsigned long pll_fb_div_frac  : 3;
+     unsigned long    				: 1;
+     unsigned long pll_reset_time   : 4;
+     unsigned long pll_lock_time    : 8;
+} __attribute__((packed));
+
+union pll_ref_fb_div_u {
+     unsigned long val : 32;
+     struct pll_ref_fb_div_t f;
+} __attribute__((packed));
+
+struct pll_cntl_t {
+     unsigned long pll_pwdn         : 1;
+     unsigned long pll_reset        : 1;
+     unsigned long pll_pm_en        : 1;
+     unsigned long pll_mode         : 1;
+     unsigned long pll_refclk_sel   : 1;
+     unsigned long pll_fbclk_sel    : 1;
+     unsigned long pll_tcpoff       : 1;
+     unsigned long pll_pcp          : 3;
+     unsigned long pll_pvg          : 3;
+     unsigned long pll_vcofr        : 1;
+     unsigned long pll_ioffset      : 2;
+     unsigned long pll_pecc_mode    : 2;
+     unsigned long pll_pecc_scon    : 2;
+     unsigned long pll_dactal       : 4;
+     unsigned long pll_cp_clip      : 2;
+     unsigned long pll_conf         : 3;
+     unsigned long pll_mbctrl       : 2;
+     unsigned long pll_ring_off     : 1;
+} __attribute__((packed));
+
+union pll_cntl_u {
+     unsigned long val : 32;
+     struct pll_cntl_t f;
+} __attribute__((packed));
+
+struct sclk_cntl_t {
+     unsigned long sclk_src_sel     	: 2;
+     unsigned long    					: 2;
+     unsigned long sclk_post_div_fast   : 4;
+     unsigned long sclk_clkon_hys   	: 3;
+     unsigned long sclk_post_div_slow   : 4;
+     unsigned long disp_cg_ok2switch_en : 1;
+     unsigned long sclk_force_reg   	: 1;
+     unsigned long sclk_force_disp  	: 1;
+     unsigned long sclk_force_mc    	: 1;
+     unsigned long sclk_force_extmc 	: 1;
+     unsigned long sclk_force_cp    	: 1;
+     unsigned long sclk_force_e2    	: 1;
+     unsigned long sclk_force_e3    	: 1;
+     unsigned long sclk_force_idct  	: 1;
+     unsigned long sclk_force_bist  	: 1;
+     unsigned long busy_extend_cp   	: 1;
+     unsigned long busy_extend_e2   	: 1;
+     unsigned long busy_extend_e3   	: 1;
+     unsigned long busy_extend_idct 	: 1;
+     unsigned long    					: 3;
+} __attribute__((packed));
+
+union sclk_cntl_u {
+     unsigned long val : 32;
+     struct sclk_cntl_t f;
+} __attribute__((packed));
+
+struct pclk_cntl_t {
+     unsigned long pclk_src_sel     : 2;
+     unsigned long    				: 2;
+     unsigned long pclk_post_div    : 4;
+     unsigned long    				: 8;
+     unsigned long pclk_force_disp  : 1;
+     unsigned long    				: 15;
+} __attribute__((packed));
+
+union pclk_cntl_u {
+     unsigned long val : 32;
+     struct pclk_cntl_t f;
+} __attribute__((packed));
+
+struct clk_test_cntl_t {
+     unsigned long testclk_sel      : 4;
+     unsigned long    				: 3;
+     unsigned long start_check_freq : 1;
+     unsigned long tstcount_rst     : 1;
+     unsigned long    				: 15;
+     unsigned long test_count       : 8;
+} __attribute__((packed));
+
+union clk_test_cntl_u {
+     unsigned long val : 32;
+     struct clk_test_cntl_t f;
+} __attribute__((packed));
+
+struct pwrmgt_cntl_t {
+     unsigned long pwm_enable       	: 1;
+     unsigned long    					: 1;
+     unsigned long pwm_mode_req         : 2;
+     unsigned long pwm_wakeup_cond      : 2;
+     unsigned long pwm_fast_noml_hw_en  : 1;
+     unsigned long pwm_noml_fast_hw_en  : 1;
+     unsigned long pwm_fast_noml_cond   : 4;
+     unsigned long pwm_noml_fast_cond   : 4;
+     unsigned long pwm_idle_timer   	: 8;
+     unsigned long pwm_busy_timer   	: 8;
+} __attribute__((packed));
+
+union pwrmgt_cntl_u {
+     unsigned long val : 32;
+     struct pwrmgt_cntl_t f;
+} __attribute__((packed));
+
+#endif
+
diff -Nru a/drivers/w1/w1.c b/drivers/w1/w1.c
--- a/drivers/w1/w1.c	2005-01-19 13:44:46 -08:00
+++ b/drivers/w1/w1.c	2005-01-19 13:44:46 -08:00
@@ -32,7 +32,6 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
-#include <linux/suspend.h>
 
 #include "w1.h"
 #include "w1_io.h"
@@ -468,17 +467,75 @@
 	w1_netlink_send(sl->master, &msg);
 }
 
-static void w1_search(struct w1_master *dev)
+static struct w1_master *w1_search_master(unsigned long data)
 {
-	u64 last, rn, tmp;
-	int i, count = 0, slave_count;
-	int last_family_desc, last_zero, last_device;
-	int search_bit, id_bit, comp_bit, desc_bit;
-	struct list_head *ent;
+	struct w1_master *dev;
+	int found = 0;
+	
+	spin_lock_irq(&w1_mlock);
+	list_for_each_entry(dev, &w1_masters, w1_master_entry) {
+		if (dev->bus_master->data == data) {
+			found = 1;
+			atomic_inc(&dev->refcnt);
+			break;
+		}
+	}
+	spin_unlock_irq(&w1_mlock);
+
+	return (found)?dev:NULL;
+}
+
+void w1_slave_found(unsigned long data, u64 rn)
+{
+	int slave_count;
 	struct w1_slave *sl;
+	struct list_head *ent;
+	struct w1_reg_num *tmp;
 	int family_found = 0;
+	struct w1_master *dev;
+
+	dev = w1_search_master(data);
+	if (!dev) {
+		printk(KERN_ERR "Failed to find w1 master device for data %08lx, it is impossible.\n",
+				data);
+		return;
+	}
+	
+	tmp = (struct w1_reg_num *) &rn;
+
+	slave_count = 0;
+	list_for_each(ent, &dev->slist) {
+
+		sl = list_entry(ent, struct w1_slave, w1_slave_entry);
+
+		if (sl->reg_num.family == tmp->family &&
+		    sl->reg_num.id == tmp->id &&
+		    sl->reg_num.crc == tmp->crc) {
+			set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
+			break;
+		}
+		else if (sl->reg_num.family == tmp->family) {
+			family_found = 1;
+			break;
+		}
 
-	dev->attempts++;
+		slave_count++;
+	}
+
+	if (slave_count == dev->slave_count &&
+		rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
+		w1_attach_slave_device(dev, (struct w1_reg_num *) &rn);
+	}
+			
+	atomic_dec(&dev->refcnt);
+}
+
+void w1_search(struct w1_master *dev)
+{
+	u64 last, rn, tmp;
+	int i, count = 0;
+	int last_family_desc, last_zero, last_device;
+	int search_bit, id_bit, comp_bit, desc_bit;
 
 	search_bit = id_bit = comp_bit = 0;
 	rn = tmp = last = 0;
@@ -556,33 +613,8 @@
 			last_device = 1;
 
 		desc_bit = last_zero;
-
-		slave_count = 0;
-		list_for_each(ent, &dev->slist) {
-			struct w1_reg_num *tmp;
-
-			tmp = (struct w1_reg_num *) &rn;
-
-			sl = list_entry(ent, struct w1_slave, w1_slave_entry);
-
-			if (sl->reg_num.family == tmp->family &&
-			    sl->reg_num.id == tmp->id &&
-			    sl->reg_num.crc == tmp->crc) {
-				set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
-				break;
-			}
-			else if (sl->reg_num.family == tmp->family) {
-				family_found = 1;
-				break;
-			}
-
-			slave_count++;
-		}
-
-		if (slave_count == dev->slave_count &&
-			rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
-			w1_attach_slave_device(dev, (struct w1_reg_num *) &rn);
-		}
+	
+		w1_slave_found(dev->bus_master->data, rn);
 	}
 }
 
@@ -628,8 +660,7 @@
 		timeout = w1_timeout*HZ;
 		do {
 			timeout = interruptible_sleep_on_timeout(&w1_control_wait, timeout);
-			if (current->flags & PF_FREEZE)
-				refrigerator(PF_FREEZE);
+			try_to_freeze(PF_FREEZE);
 		} while (!signal_pending(current) && (timeout > 0));
 
 		if (signal_pending(current))
@@ -701,8 +732,7 @@
 		timeout = w1_timeout*HZ;
 		do {
 			timeout = interruptible_sleep_on_timeout(&dev->kwait, timeout);
-			if (current->flags & PF_FREEZE)
-				refrigerator(PF_FREEZE);
+			try_to_freeze(PF_FREEZE);
 		} while (!signal_pending(current) && (timeout > 0));
 
 		if (signal_pending(current))
@@ -724,8 +754,8 @@
 				clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
 		}
 		
-      		w1_search(dev);
-		
+		w1_search_devices(dev, w1_slave_found);
+
 		list_for_each_safe(ent, n, &dev->slist) {
 			sl = list_entry(ent, struct w1_slave, w1_slave_entry);
 
diff -Nru a/drivers/w1/w1.h b/drivers/w1/w1.h
--- a/drivers/w1/w1.h	2005-01-19 13:44:48 -08:00
+++ b/drivers/w1/w1.h	2005-01-19 13:44:48 -08:00
@@ -74,6 +74,8 @@
 	struct device_attribute	attr_name, attr_val;
 };
 
+typedef void (* w1_slave_found_callback)(unsigned long, u64);
+
 struct w1_bus_master
 {
 	unsigned long		data;
@@ -90,6 +92,8 @@
   	u8			(*touch_bit)(unsigned long, u8);
   
   	u8			(*reset_bus)(unsigned long);
+
+	void			(*search)(unsigned long, w1_slave_found_callback);
 };
 
 struct w1_master
@@ -127,6 +131,7 @@
 
 int w1_create_master_attributes(struct w1_master *);
 void w1_destroy_master_attributes(struct w1_master *);
+void w1_search(struct w1_master *dev);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
--- a/drivers/w1/w1_io.c	2005-01-19 13:44:47 -08:00
+++ b/drivers/w1/w1_io.c	2005-01-19 13:44:47 -08:00
@@ -174,6 +174,15 @@
 	return crc;
 }
 
+void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb)
+{
+	dev->attempts++;
+	if (dev->bus_master->search)
+		dev->bus_master->search(dev->bus_master->data, cb);
+	else
+		w1_search(dev);
+}
+
 EXPORT_SYMBOL(w1_write_bit);
 EXPORT_SYMBOL(w1_write_8);
 EXPORT_SYMBOL(w1_read_bit);
@@ -183,3 +192,4 @@
 EXPORT_SYMBOL(w1_delay);
 EXPORT_SYMBOL(w1_read_block);
 EXPORT_SYMBOL(w1_write_block);
+EXPORT_SYMBOL(w1_search_devices);
diff -Nru a/drivers/w1/w1_io.h b/drivers/w1/w1_io.h
--- a/drivers/w1/w1_io.h	2005-01-19 13:44:47 -08:00
+++ b/drivers/w1/w1_io.h	2005-01-19 13:44:47 -08:00
@@ -34,5 +34,6 @@
 u8 w1_calc_crc8(u8 *, int);
 void w1_write_block(struct w1_master *, u8 *, int);
 u8 w1_read_block(struct w1_master *, u8 *, int);
+void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);
 
 #endif /* __W1_IO_H */
diff -Nru a/fs/Kconfig b/fs/Kconfig
--- a/fs/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/fs/Kconfig	2005-01-19 13:44:47 -08:00
@@ -250,7 +250,7 @@
 	select NLS
 	help
 	  This is a port of IBM's Journaled Filesystem .  More information is
-	  available in the file Documentation/filesystems/jfs.txt.
+	  available in the file <file:Documentation/filesystems/jfs.txt>.
 
 	  If you do not intend to use the JFS filesystem, say N.
 
@@ -1027,10 +1027,10 @@
 	help
 	  The BeOS File System (BeFS) is the native file system of Be, Inc's
 	  BeOS. Notable features include support for arbitrary attributes
-	  on files and directories, and database-like indices on selected
+	  on files and directories, and database-like indeces on selected
 	  attributes. (Also note that this driver doesn't make those features
 	  available at this time). It is a 64 bit filesystem, so it supports
-	  extreemly large volumes and files.
+	  extremly large volumes and files.
 
 	  If you use this filesystem, you should also say Y to at least one
 	  of the NLS (native language support) options below.
@@ -1180,7 +1180,7 @@
         help
           Zlib is designed to be a free, general-purpose, legally unencumbered,
           lossless data-compression library for use on virtually any computer 
-          hardware and operating system. See http://www.gzip.org/zlib/ for
+          hardware and operating system. See <http://www.gzip.org/zlib/> for
           further information.
           
           Say 'Y' if unsure.
@@ -1205,7 +1205,7 @@
         depends on JFFS2_FS
         help
           You can set here the default compression mode of JFFS2 from 
-          the avaiable compression modes. Don't touch if unsure.
+          the available compression modes. Don't touch if unsure.
 
 config JFFS2_CMODE_NONE
         bool "no compression"
@@ -1782,7 +1782,7 @@
 	  If you say Y here, you will get an experimental Andrew File System
 	  driver. It currently only supports unsecured read-only AFS access.
 
-	  See Documentation/filesystems/afs.txt for more intormation.
+	  See <file:Documentation/filesystems/afs.txt> for more intormation.
 
 	  If unsure, say N.
 
diff -Nru a/fs/binfmt_aout.c b/fs/binfmt_aout.c
--- a/fs/binfmt_aout.c	2005-01-19 13:44:48 -08:00
+++ b/fs/binfmt_aout.c	2005-01-19 13:44:48 -08:00
@@ -50,7 +50,10 @@
 	start = PAGE_ALIGN(start);
 	end = PAGE_ALIGN(end);
 	if (end > start) {
-		unsigned long addr = do_brk(start, end - start);
+		unsigned long addr;
+		down_write(&current->mm->mmap_sem);
+		addr = do_brk(start, end - start);
+		up_write(&current->mm->mmap_sem);
 		if (BAD_ADDR(addr))
 			return addr;
 	}
@@ -323,10 +326,14 @@
 		loff_t pos = fd_offset;
 		/* Fuck me plenty... */
 		/* <AOL></AOL> */
+		down_write(&current->mm->mmap_sem);	
 		error = do_brk(N_TXTADDR(ex), ex.a_text);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex),
 			  ex.a_text, &pos);
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(N_DATADDR(ex), ex.a_data);
+		up_write(&current->mm->mmap_sem);
 		bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex),
 			  ex.a_data, &pos);
 		goto beyond_if;
@@ -346,8 +353,9 @@
 		pos = 32;
 		map_size = ex.a_text+ex.a_data;
 #endif
-
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(text_addr & PAGE_MASK, map_size);
+		up_write(&current->mm->mmap_sem);
 		if (error != (text_addr & PAGE_MASK)) {
 			send_sig(SIGKILL, current, 0);
 			return error;
@@ -382,7 +390,9 @@
 
 		if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
 			loff_t pos = fd_offset;
+			down_write(&current->mm->mmap_sem);
 			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+			up_write(&current->mm->mmap_sem);
 			bprm->file->f_op->read(bprm->file,
 					(char __user *)N_TXTADDR(ex),
 					ex.a_text+ex.a_data, &pos);
@@ -487,8 +497,9 @@
 			       file->f_dentry->d_name.name);
 			error_time = jiffies;
 		}
-
+		down_write(&current->mm->mmap_sem);
 		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+		up_write(&current->mm->mmap_sem);
 		
 		file->f_op->read(file, (char __user *)start_addr,
 			ex.a_text + ex.a_data, &pos);
diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c
--- a/fs/binfmt_elf.c	2005-01-19 13:44:46 -08:00
+++ b/fs/binfmt_elf.c	2005-01-19 13:44:46 -08:00
@@ -88,7 +88,10 @@
 	start = ELF_PAGEALIGN(start);
 	end = ELF_PAGEALIGN(end);
 	if (end > start) {
-		unsigned long addr = do_brk(start, end - start);
+		unsigned long addr;
+		down_write(&current->mm->mmap_sem);
+		addr = do_brk(start, end - start);
+		up_write(&current->mm->mmap_sem);
 		if (BAD_ADDR(addr))
 			return addr;
 	}
@@ -409,7 +412,9 @@
 
 	/* Map the last of the bss segment */
 	if (last_bss > elf_bss) {
+		down_write(&current->mm->mmap_sem);
 		error = do_brk(elf_bss, last_bss - elf_bss);
+		up_write(&current->mm->mmap_sem);
 		if (BAD_ADDR(error))
 			goto out_close;
 	}
@@ -449,7 +454,9 @@
 		goto out;
 	}
 
+	down_write(&current->mm->mmap_sem);	
 	do_brk(0, text_data);
+	up_write(&current->mm->mmap_sem);
 	if (!interpreter->f_op || !interpreter->f_op->read)
 		goto out;
 	if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
@@ -457,8 +464,11 @@
 	flush_icache_range((unsigned long)addr,
 	                   (unsigned long)addr + text_data);
 
+
+	down_write(&current->mm->mmap_sem);	
 	do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
 		interp_ex->a_bss);
+	up_write(&current->mm->mmap_sem);
 	elf_entry = interp_ex->a_entry;
 
 out:
diff -Nru a/fs/bio.c b/fs/bio.c
--- a/fs/bio.c	2005-01-19 13:44:47 -08:00
+++ b/fs/bio.c	2005-01-19 13:44:47 -08:00
@@ -98,12 +98,7 @@
 
 	BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
 
-	/*
-	 * cloned bio doesn't own the veclist
-	 */
-	if (!bio_flagged(bio, BIO_CLONED))
-		mempool_free(bio->bi_io_vec, bp->pool);
-
+	mempool_free(bio->bi_io_vec, bp->pool);
 	mempool_free(bio, bio_pool);
 }
 
@@ -210,7 +205,9 @@
  */
 inline void __bio_clone(struct bio *bio, struct bio *bio_src)
 {
-	bio->bi_io_vec = bio_src->bi_io_vec;
+	request_queue_t *q = bdev_get_queue(bio_src->bi_bdev);
+
+	memcpy(bio->bi_io_vec, bio_src->bi_io_vec, bio_src->bi_max_vecs * sizeof(struct bio_vec));
 
 	bio->bi_sector = bio_src->bi_sector;
 	bio->bi_bdev = bio_src->bi_bdev;
@@ -222,21 +219,9 @@
 	 * for the clone
 	 */
 	bio->bi_vcnt = bio_src->bi_vcnt;
-	bio->bi_idx = bio_src->bi_idx;
-	if (bio_flagged(bio, BIO_SEG_VALID)) {
-		bio->bi_phys_segments = bio_src->bi_phys_segments;
-		bio->bi_hw_segments = bio_src->bi_hw_segments;
-		bio->bi_flags |= (1 << BIO_SEG_VALID);
-	}
 	bio->bi_size = bio_src->bi_size;
-
-	/*
-	 * cloned bio does not own the bio_vec, so users cannot fiddle with
-	 * it. clear bi_max_vecs and clear the BIO_POOL_BITS to make this
-	 * apparent
-	 */
-	bio->bi_max_vecs = 0;
-	bio->bi_flags &= (BIO_POOL_MASK - 1);
+	bio_phys_segments(q, bio);
+	bio_hw_segments(q, bio);
 }
 
 /**
@@ -248,7 +233,7 @@
  */
 struct bio *bio_clone(struct bio *bio, int gfp_mask)
 {
-	struct bio *b = bio_alloc(gfp_mask, 0);
+	struct bio *b = bio_alloc(gfp_mask, bio->bi_max_vecs);
 
 	if (b)
 		__bio_clone(b, bio);
diff -Nru a/fs/compat.c b/fs/compat.c
--- a/fs/compat.c	2005-01-19 13:44:46 -08:00
+++ b/fs/compat.c	2005-01-19 13:44:46 -08:00
@@ -397,77 +397,90 @@
 }
 EXPORT_SYMBOL(unregister_ioctl32_conversion); 
 
+static void compat_ioctl_error(struct file *filp, unsigned int fd,
+		unsigned int cmd, unsigned long arg)
+{
+	char buf[10];
+	char *fn = "?";
+	char *path;
+
+	/* find the name of the device. */
+	path = (char *)__get_free_page(GFP_KERNEL);
+	if (path) {
+		fn = d_path(filp->f_dentry, filp->f_vfsmnt, path, PAGE_SIZE);
+		if (IS_ERR(fn))
+			fn = "?";
+	}
+
+	sprintf(buf,"'%c'", (cmd>>24) & 0x3f);
+	if (!isprint(buf[1]))
+		sprintf(buf, "%02x", buf[1]);
+	printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
+			"cmd(%08x){%s} arg(%08x) on %s\n",
+			current->comm, current->pid,
+			(int)fd, (unsigned int)cmd, buf,
+			(unsigned int)arg, fn);
+
+	if (path)
+		free_page((unsigned long)path);
+}
+
 asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
 				unsigned long arg)
 {
-	struct file * filp;
+	struct file *filp;
 	int error = -EBADF;
 	struct ioctl_trans *t;
+	int fput_needed;
 
-	filp = fget(fd);
-	if(!filp)
-		goto out2;
-
-	if (!filp->f_op || !filp->f_op->ioctl) {
-		error = sys_ioctl (fd, cmd, arg);
+	filp = fget_light(fd, &fput_needed);
+	if (!filp)
 		goto out;
+
+	if (filp->f_op && filp->f_op->compat_ioctl) {
+		error = filp->f_op->compat_ioctl(filp, cmd, arg);
+		if (error != -ENOIOCTLCMD)
+			goto out_fput;
 	}
 
-	down_read(&ioctl32_sem);
+	if (!filp->f_op ||
+	    (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl))
+		goto do_ioctl;
 
-	t = ioctl32_hash_table[ioctl32_hash (cmd)];
+	down_read(&ioctl32_sem);
+	for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
+		if (t->cmd == cmd)
+			goto found_handler;
+	}
+	up_read(&ioctl32_sem);
 
-	while (t && t->cmd != cmd)
-		t = t->next;
-	if (t) {
-		if (t->handler) { 
-			lock_kernel();
-			error = t->handler(fd, cmd, arg, filp);
-			unlock_kernel();
-			up_read(&ioctl32_sem);
-		} else {
-			up_read(&ioctl32_sem);
-			error = sys_ioctl(fd, cmd, arg);
-		}
+	if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
+		error = siocdevprivate_ioctl(fd, cmd, arg);
 	} else {
+		static int count;
+
+		if (++count <= 50)
+			compat_ioctl_error(filp, fd, cmd, arg);
+		error = -EINVAL;
+	}
+
+	goto out_fput;
+
+ found_handler:
+	if (t->handler) {
+		lock_kernel();
+		error = t->handler(fd, cmd, arg, filp);
+		unlock_kernel();
 		up_read(&ioctl32_sem);
-		if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
-			error = siocdevprivate_ioctl(fd, cmd, arg);
-		} else {
-			static int count;
-			if (++count <= 50) {
-				char buf[10];
-				char *fn = "?";
-				char *path;
-
-				path = (char *)__get_free_page(GFP_KERNEL);
-
-				/* find the name of the device. */
-				if (path) {
-			       		fn = d_path(filp->f_dentry,
-						filp->f_vfsmnt, path,
-						PAGE_SIZE);
-					if (IS_ERR(fn))
-						fn = "?";
-				}
-
-				sprintf(buf,"'%c'", (cmd>>24) & 0x3f);
-				if (!isprint(buf[1]))
-				    sprintf(buf, "%02x", buf[1]);
-				printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
-					"cmd(%08x){%s} arg(%08x) on %s\n",
-					current->comm, current->pid,
-					(int)fd, (unsigned int)cmd, buf,
-					(unsigned int)arg, fn);
-				if (path)
-					free_page((unsigned long)path);
-			}
-			error = -EINVAL;
-		}
+		goto out_fput;
 	}
-out:
-	fput(filp);
-out2:
+
+	up_read(&ioctl32_sem);
+ do_ioctl:
+	error = sys_ioctl(fd, cmd, arg);
+ out_fput:
+	fput_light(filp, fput_needed);
+ out:
 	return error;
 }
 
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	2005-01-19 13:44:46 -08:00
+++ b/fs/exec.c	2005-01-19 13:44:46 -08:00
@@ -550,6 +550,21 @@
 	old_mm = current->mm;
 	mm_release(tsk, old_mm);
 
+	if (old_mm) {
+		/*
+		 * Make sure that if there is a core dump in progress
+		 * for the old mm, we get out and die instead of going
+		 * through with the exec.  We must hold mmap_sem around
+		 * checking core_waiters and changing tsk->mm.  The
+		 * core-inducing thread will increment core_waiters for
+		 * each thread whose ->mm == old_mm.
+		 */
+		down_read(&old_mm->mmap_sem);
+		if (unlikely(old_mm->core_waiters)) {
+			up_read(&old_mm->mmap_sem);
+			return -EINTR;
+		}
+	}
 	task_lock(tsk);
 	active_mm = tsk->active_mm;
 	tsk->mm = mm;
@@ -558,6 +573,7 @@
 	task_unlock(tsk);
 	arch_pick_mmap_layout(mm);
 	if (old_mm) {
+		up_read(&old_mm->mmap_sem);
 		if (active_mm != old_mm) BUG();
 		mmput(old_mm);
 		return 0;
@@ -669,6 +685,14 @@
 		 */
 		ptrace = leader->ptrace;
 		parent = leader->parent;
+		if (unlikely(ptrace) && unlikely(parent == current)) {
+			/*
+			 * Joker was ptracing his own group leader,
+			 * and now he wants to be his own parent!
+			 * We can't have that.
+			 */
+			ptrace = 0;
+		}
 
 		ptrace_unlink(current);
 		ptrace_unlink(leader);
@@ -1338,6 +1362,7 @@
 	struct task_struct *g, *p;
 	struct task_struct *tsk = current;
 	struct completion *vfork_done = tsk->vfork_done;
+	int traced = 0;
 
 	/*
 	 * Make sure nobody is waiting for us to release the VM,
@@ -1353,10 +1378,30 @@
 		if (mm == p->mm && p != tsk) {
 			force_sig_specific(SIGKILL, p);
 			mm->core_waiters++;
+			if (unlikely(p->ptrace) &&
+			    unlikely(p->parent->mm == mm))
+				traced = 1;
 		}
 	while_each_thread(g,p);
 
 	read_unlock(&tasklist_lock);
+
+	if (unlikely(traced)) {
+		/*
+		 * We are zapping a thread and the thread it ptraces.
+		 * If the tracee went into a ptrace stop for exit tracing,
+		 * we could deadlock since the tracer is waiting for this
+		 * coredump to finish.  Detach them so they can both die.
+		 */
+		write_lock_irq(&tasklist_lock);
+		do_each_thread(g,p) {
+			if (mm == p->mm && p != tsk &&
+			    p->ptrace && p->parent->mm == mm) {
+				__ptrace_unlink(p);
+			}
+		} while_each_thread(g,p);
+		write_unlock_irq(&tasklist_lock);
+	}
 }
 
 static void coredump_wait(struct mm_struct *mm)
@@ -1397,9 +1442,18 @@
 	}
 	mm->dumpable = 0;
 	init_completion(&mm->core_done);
+	spin_lock_irq(&current->sighand->siglock);
 	current->signal->flags = SIGNAL_GROUP_EXIT;
 	current->signal->group_exit_code = exit_code;
+	spin_unlock_irq(&current->sighand->siglock);
 	coredump_wait(mm);
+
+	/*
+	 * Clear any false indication of pending signals that might
+	 * be seen by the filesystem code called to write the core file.
+	 */
+	current->signal->group_stop_count = 0;
+	clear_thread_flag(TIF_SIGPENDING);
 
 	if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
 		goto fail_unlock;
diff -Nru a/fs/ext2/xattr.c b/fs/ext2/xattr.c
--- a/fs/ext2/xattr.c	2005-01-19 13:44:47 -08:00
+++ b/fs/ext2/xattr.c	2005-01-19 13:44:47 -08:00
@@ -24,7 +24,7 @@
  *
  *   +------------------+
  *   | header           |
- *   ¦ entry 1          | |
+ *   | entry 1          | |
  *   | entry 2          | | growing downwards
  *   | entry 3          | v
  *   | four null bytes  |
@@ -95,13 +95,12 @@
 static int ext2_xattr_cache_insert(struct buffer_head *);
 static struct buffer_head *ext2_xattr_cache_find(struct inode *,
 						 struct ext2_xattr_header *);
-static void ext2_xattr_cache_remove(struct buffer_head *);
 static void ext2_xattr_rehash(struct ext2_xattr_header *,
 			      struct ext2_xattr_entry *);
 
 static struct mb_cache *ext2_xattr_cache;
 
-static struct xattr_handler *ext2_xattr_handler_map[EXT2_XATTR_INDEX_MAX] = {
+static struct xattr_handler *ext2_xattr_handler_map[] = {
 	[EXT2_XATTR_INDEX_USER]		     = &ext2_xattr_user_handler,
 #ifdef CONFIG_EXT2_FS_POSIX_ACL
 	[EXT2_XATTR_INDEX_POSIX_ACL_ACCESS]  = &ext2_xattr_acl_access_handler,
@@ -131,7 +130,7 @@
 {
 	struct xattr_handler *handler = NULL;
 
-	if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX)
+	if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map))
 		handler = ext2_xattr_handler_map[name_index];
 	return handler;
 }
@@ -494,15 +493,22 @@
 	/* Here we know that we can set the new attribute. */
 
 	if (header) {
+		struct mb_cache_entry *ce;
+
 		/* assert(header == HDR(bh)); */
+		ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev,
+					bh->b_blocknr);
 		lock_buffer(bh);
 		if (header->h_refcount == cpu_to_le32(1)) {
 			ea_bdebug(bh, "modifying in-place");
-			ext2_xattr_cache_remove(bh);
+			if (ce)
+				mb_cache_entry_free(ce);
 			/* keep the buffer locked while modifying it. */
 		} else {
 			int offset;
 
+			if (ce)
+				mb_cache_entry_release(ce);
 			unlock_buffer(bh);
 			ea_bdebug(bh, "cloning");
 			header = kmalloc(bh->b_size, GFP_KERNEL);
@@ -707,13 +713,19 @@
 
 	error = 0;
 	if (old_bh && old_bh != new_bh) {
+		struct mb_cache_entry *ce;
+
 		/*
 		 * If there was an old block and we are no longer using it,
 		 * release the old block.
 		 */
+		ce = mb_cache_entry_get(ext2_xattr_cache, old_bh->b_bdev,
+					old_bh->b_blocknr);
 		lock_buffer(old_bh);
 		if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) {
 			/* Free the old block. */
+			if (ce)
+				mb_cache_entry_free(ce);
 			ea_bdebug(old_bh, "freeing");
 			ext2_free_blocks(inode, old_bh->b_blocknr, 1);
 			/* We let our caller release old_bh, so we
@@ -724,6 +736,8 @@
 			/* Decrement the refcount only. */
 			HDR(old_bh)->h_refcount = cpu_to_le32(
 				le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
+			if (ce)
+				mb_cache_entry_release(ce);
 			DQUOT_FREE_BLOCK(inode, 1);
 			mark_buffer_dirty(old_bh);
 			ea_bdebug(old_bh, "refcount now=%d",
@@ -748,6 +762,7 @@
 ext2_xattr_delete_inode(struct inode *inode)
 {
 	struct buffer_head *bh = NULL;
+	struct mb_cache_entry *ce;
 
 	down_write(&EXT2_I(inode)->xattr_sem);
 	if (!EXT2_I(inode)->i_file_acl)
@@ -767,15 +782,19 @@
 			EXT2_I(inode)->i_file_acl);
 		goto cleanup;
 	}
+	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev, bh->b_blocknr);
 	lock_buffer(bh);
 	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-		ext2_xattr_cache_remove(bh);
+		if (ce)
+			mb_cache_entry_free(ce);
 		ext2_free_blocks(inode, EXT2_I(inode)->i_file_acl, 1);
 		get_bh(bh);
 		bforget(bh);
 	} else {
 		HDR(bh)->h_refcount = cpu_to_le32(
 			le32_to_cpu(HDR(bh)->h_refcount) - 1);
+		if (ce)
+			mb_cache_entry_release(ce);
 		mark_buffer_dirty(bh);
 		if (IS_SYNC(inode))
 			sync_dirty_buffer(bh);
@@ -892,11 +911,19 @@
 	if (!header->h_hash)
 		return NULL;  /* never share */
 	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
+again:
 	ce = mb_cache_entry_find_first(ext2_xattr_cache, 0,
 				       inode->i_sb->s_bdev, hash);
 	while (ce) {
-		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
+		struct buffer_head *bh;
 
+		if (IS_ERR(ce)) {
+			if (PTR_ERR(ce) == -EAGAIN)
+				goto again;
+			break;
+		}
+
+		bh = sb_bread(inode->i_sb, ce->e_block);
 		if (!bh) {
 			ext2_error(inode->i_sb, "ext2_xattr_cache_find",
 				"inode %ld: block %ld read error",
@@ -923,26 +950,6 @@
 	return NULL;
 }
 
-/*
- * ext2_xattr_cache_remove()
- *
- * Remove the cache entry of a block from the cache. Called when a
- * block becomes invalid.
- */
-static void
-ext2_xattr_cache_remove(struct buffer_head *bh)
-{
-	struct mb_cache_entry *ce;
-
-	ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_bdev, bh->b_blocknr);
-	if (ce) {
-		ea_bdebug(bh, "removing (%d cache entries remaining)",
-			  atomic_read(&ext2_xattr_cache->c_entry_count)-1);
-		mb_cache_entry_free(ce);
-	} else 
-		ea_bdebug(bh, "no cache entry");
-}
-
 #define NAME_HASH_SHIFT 5
 #define VALUE_HASH_SHIFT 16
 
@@ -1016,7 +1023,7 @@
 {
 	ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL,
 		sizeof(struct mb_cache_entry) +
-		sizeof(struct mb_cache_entry_index), 1, 6);
+		sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6);
 	if (!ext2_xattr_cache)
 		return -ENOMEM;
 	return 0;
diff -Nru a/fs/ext2/xattr.h b/fs/ext2/xattr.h
--- a/fs/ext2/xattr.h	2005-01-19 13:44:47 -08:00
+++ b/fs/ext2/xattr.h	2005-01-19 13:44:47 -08:00
@@ -17,7 +17,6 @@
 #define EXT2_XATTR_REFCOUNT_MAX		1024
 
 /* Name indexes */
-#define EXT2_XATTR_INDEX_MAX			10
 #define EXT2_XATTR_INDEX_USER			1
 #define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS	2
 #define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT	3
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
--- a/fs/ext3/ialloc.c	2005-01-19 13:44:46 -08:00
+++ b/fs/ext3/ialloc.c	2005-01-19 13:44:46 -08:00
@@ -596,11 +596,9 @@
 	spin_unlock(&sbi->s_next_gen_lock);
 
 	ei->i_state = EXT3_STATE_NEW;
-	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) {
-		ei->i_extra_isize = sizeof(__u16)	/* i_extra_isize */
-				+ sizeof(__u16);	/* i_pad1 */
-	} else
-		ei->i_extra_isize = 0;
+	ei->i_extra_isize =
+		(EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
+		sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
 
 	ret = inode;
 	if(DQUOT_ALLOC_INODE(inode)) {
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	2005-01-19 13:44:47 -08:00
+++ b/fs/ext3/inode.c	2005-01-19 13:44:47 -08:00
@@ -2271,13 +2271,13 @@
 	return block;
 }
 
-/* 
+/*
  * ext3_get_inode_loc returns with an extra refcount against the inode's
- * underlying buffer_head on success.  If `in_mem' is false then we're purely
- * trying to determine the inode's location on-disk and no read need be
- * performed.
+ * underlying buffer_head on success. If 'in_mem' is true, we have all
+ * data in memory that is needed to recreate the on-disk version of this
+ * inode.
  */
-int ext3_get_inode_loc(struct inode *inode,
+static int __ext3_get_inode_loc(struct inode *inode,
 				struct ext3_iloc *iloc, int in_mem)
 {
 	unsigned long block;
@@ -2302,7 +2302,11 @@
 			goto has_buffer;
 		}
 
-		/* we can't skip I/O if inode is on a disk only */
+		/*
+		 * If we have all information of the inode in memory and this
+		 * is the only valid inode in the block, we need not read the
+		 * block.
+		 */
 		if (in_mem) {
 			struct buffer_head *bitmap_bh;
 			struct ext3_group_desc *desc;
@@ -2311,10 +2315,6 @@
 			int block_group;
 			int start;
 
-			/*
-			 * If this is the only valid inode in the block we
-			 * need not read the block.
-			 */
 			block_group = (inode->i_ino - 1) /
 					EXT3_INODES_PER_GROUP(inode->i_sb);
 			inodes_per_buffer = bh->b_size /
@@ -2361,8 +2361,9 @@
 
 make_io:
 		/*
-		 * There are another valid inodes in the buffer so we must
-		 * read the block from disk
+		 * There are other valid inodes in the buffer, this inode
+		 * has in-inode xattrs, or we don't have this inode in memory.
+		 * Read the block from disk.
 		 */
 		get_bh(bh);
 		bh->b_end_io = end_buffer_read_sync;
@@ -2382,6 +2383,13 @@
 	return 0;
 }
 
+int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)
+{
+	/* We have all inode data except xattrs in memory here. */
+	return __ext3_get_inode_loc(inode, iloc,
+		!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR));
+}
+
 void ext3_set_inode_flags(struct inode *inode)
 {
 	unsigned int flags = EXT3_I(inode)->i_flags;
@@ -2413,7 +2421,7 @@
 #endif
 	ei->i_rsv_window.rsv_end = EXT3_RESERVE_WINDOW_NOT_ALLOCATED;
 
-	if (ext3_get_inode_loc(inode, &iloc, 0))
+	if (__ext3_get_inode_loc(inode, &iloc, 0))
 		goto bad_inode;
 	bh = iloc.bh;
 	raw_inode = ext3_raw_inode(&iloc);
@@ -2485,10 +2493,15 @@
 		ei->i_data[block] = raw_inode->i_block[block];
 	INIT_LIST_HEAD(&ei->i_orphan);
 
-	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
-		ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize);
-	else
-		ei->i_extra_isize = 0;
+	ei->i_extra_isize =
+		(EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
+		le16_to_cpu(raw_inode->i_extra_isize) : 0;
+	if (ei->i_extra_isize) {
+		__le32 *magic = (void *)raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
+				ei->i_extra_isize;
+		if (le32_to_cpu(*magic))
+			 ei->i_state |= EXT3_STATE_XATTR;
+	}
 
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext3_file_inode_operations;
@@ -2858,7 +2871,7 @@
 {
 	int err = 0;
 	if (handle) {
-		err = ext3_get_inode_loc(inode, iloc, 1);
+		err = ext3_get_inode_loc(inode, iloc);
 		if (!err) {
 			BUFFER_TRACE(iloc->bh, "get_write_access");
 			err = ext3_journal_get_write_access(handle, iloc->bh);
@@ -2957,7 +2970,7 @@
 
 	int err = 0;
 	if (handle) {
-		err = ext3_get_inode_loc(inode, &iloc, 1);
+		err = ext3_get_inode_loc(inode, &iloc);
 		if (!err) {
 			BUFFER_TRACE(iloc.bh, "get_write_access");
 			err = journal_get_write_access(handle, iloc.bh);
diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
--- a/fs/ext3/xattr.c	2005-01-19 13:44:47 -08:00
+++ b/fs/ext3/xattr.c	2005-01-19 13:44:47 -08:00
@@ -10,22 +10,24 @@
  * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
  *  Red Hat Inc.
  * ea-in-inode support by Alex Tomas <alex@clusterfs.com> aka bzzz
+ *  and Andreas Gruenbacher <agruen@suse.de>.
  */
 
 /*
- * Extended attributes are stored on disk blocks allocated outside of
- * any inode. The i_file_acl field is then made to point to this allocated
- * block. If all extended attributes of an inode are identical, these
- * inodes may share the same extended attribute block. Such situations
- * are automatically detected by keeping a cache of recent attribute block
- * numbers and hashes over the block's contents in memory.
+ * Extended attributes are stored directly in inodes (on file systems with
+ * inodes bigger than 128 bytes) and on additional disk blocks. The i_file_acl
+ * field contains the block number if an inode uses an additional block. All
+ * attributes must fit in the inode and one additional block. Blocks that
+ * contain the identical set of attributes may be shared among several inodes.
+ * Identical blocks are detected by keeping a cache of blocks that have
+ * recently been accessed.
  *
- *
- * Extended attribute block layout:
+ * The attributes in inodes and on blocks have a different header; the entries
+ * are stored in the same format:
  *
  *   +------------------+
  *   | header           |
- *   ¦ entry 1          | |
+ *   | entry 1          | |
  *   | entry 2          | | growing downwards
  *   | entry 3          | v
  *   | four null bytes  |
@@ -35,23 +37,17 @@
  *   | value 2          | |
  *   +------------------+
  *
- * The block header is followed by multiple entry descriptors. These entry
- * descriptors are variable in size, and alligned to EXT3_XATTR_PAD
- * byte boundaries. The entry descriptors are sorted by attribute name,
- * so that two extended attribute blocks can be compared efficiently.
- *
- * Attribute values are aligned to the end of the block, stored in
- * no specific order. They are also padded to EXT3_XATTR_PAD byte
- * boundaries. No additional gaps are left between them.
+ * The header is followed by multiple entry descriptors. Descriptors are
+ * kept sorted. The attribute values are aligned to the end of the block
+ * in no specific order.
  *
  * Locking strategy
  * ----------------
  * EXT3_I(inode)->i_file_acl is protected by EXT3_I(inode)->xattr_sem.
  * EA blocks are only changed if they are exclusive to an inode, so
  * holding xattr_sem also means that nothing but the EA block's reference
- * count will change. Multiple writers to an EA block are synchronized
- * by the bh lock. No more than a single bh lock is held at any time
- * to avoid deadlocks.
+ * count can change. Multiple writers to the same block are synchronized
+ * by the buffer lock.
  */
 
 #include <linux/init.h>
@@ -65,11 +61,18 @@
 #include "xattr.h"
 #include "acl.h"
 
-#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
+#define BHDR(bh) ((struct ext3_xattr_header *)((bh)->b_data))
 #define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr))
-#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1)
+#define BFIRST(bh) ENTRY(BHDR(bh)+1)
 #define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
 
+#define IHDR(inode, raw_inode) \
+	((struct ext3_xattr_ibody_header *) \
+		((void *)raw_inode + \
+		 EXT3_GOOD_OLD_INODE_SIZE + \
+		 EXT3_I(inode)->i_extra_isize))
+#define IFIRST(hdr) ((struct ext3_xattr_entry *)((hdr)+1))
+
 #ifdef EXT3_XATTR_DEBUG
 # define ea_idebug(inode, f...) do { \
 		printk(KERN_DEBUG "inode %s:%ld: ", \
@@ -90,20 +93,16 @@
 # define ea_bdebug(f...)
 #endif
 
-static int ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
-				       struct buffer_head *old_bh,
-				       struct ext3_xattr_header *header);
-static int ext3_xattr_cache_insert(struct buffer_head *);
-static struct buffer_head *ext3_xattr_cache_find(handle_t *, struct inode *,
+static void ext3_xattr_cache_insert(struct buffer_head *);
+static struct buffer_head *ext3_xattr_cache_find(struct inode *,
 						 struct ext3_xattr_header *,
-						 int *);
-static void ext3_xattr_cache_remove(struct buffer_head *);
+						 struct mb_cache_entry **);
 static void ext3_xattr_rehash(struct ext3_xattr_header *,
 			      struct ext3_xattr_entry *);
 
 static struct mb_cache *ext3_xattr_cache;
 
-static struct xattr_handler *ext3_xattr_handler_map[EXT3_XATTR_INDEX_MAX] = {
+static struct xattr_handler *ext3_xattr_handler_map[] = {
 	[EXT3_XATTR_INDEX_USER]		     = &ext3_xattr_user_handler,
 #ifdef CONFIG_EXT3_FS_POSIX_ACL
 	[EXT3_XATTR_INDEX_POSIX_ACL_ACCESS]  = &ext3_xattr_acl_access_handler,
@@ -133,178 +132,176 @@
 {
 	struct xattr_handler *handler = NULL;
 
-	if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
+	if (name_index > 0 && name_index < ARRAY_SIZE(ext3_xattr_handler_map))
 		handler = ext3_xattr_handler_map[name_index];
 	return handler;
 }
 
 /*
- * ext3_xattr_block_get()
+ * Inode operation listxattr()
  *
- * routine looks for attribute in EA block and returns it's value and size
+ * dentry->d_inode->i_sem: don't care
  */
+ssize_t
+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	return ext3_xattr_list(dentry->d_inode, buffer, size);
+}
+
 static int
+ext3_xattr_check_names(struct ext3_xattr_entry *entry, void *end)
+{
+	while (!IS_LAST_ENTRY(entry)) {
+		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(entry);
+		if ((void *)next >= end)
+			return -EIO;
+		entry = next;
+	}
+	return 0;
+}
+
+static inline int
+ext3_xattr_check_block(struct buffer_head *bh)
+{
+	int error;
+
+	if (BHDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
+	    BHDR(bh)->h_blocks != cpu_to_le32(1))
+		return -EIO;
+	error = ext3_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
+	return error;
+}
+
+static inline int
+ext3_xattr_check_entry(struct ext3_xattr_entry *entry, size_t size)
+{
+	size_t value_size = le32_to_cpu(entry->e_value_size);
+
+	if (entry->e_value_block != 0 || value_size > size ||
+	    le16_to_cpu(entry->e_value_offs) + value_size > size)
+		return -EIO;
+	return 0;
+}
+
+static int
+ext3_xattr_find_entry(struct ext3_xattr_entry **pentry, int name_index,
+		      const char *name, size_t size, int sorted)
+{
+	struct ext3_xattr_entry *entry;
+	size_t name_len;
+	int cmp = 1;
+
+	if (name == NULL)
+		return -EINVAL;
+	name_len = strlen(name);
+	entry = *pentry;
+	for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) {
+		cmp = name_index - entry->e_name_index;
+		if (!cmp)
+			cmp = name_len - entry->e_name_len;
+		if (!cmp)
+			cmp = memcmp(name, entry->e_name, name_len);
+		if (cmp <= 0 && (sorted || cmp == 0))
+			break;
+	}
+	*pentry = entry;
+	if (!cmp && ext3_xattr_check_entry(entry, size))
+			return -EIO;
+	return cmp ? -ENODATA : 0;
+}
+
+int
 ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
-	       void *buffer, size_t buffer_size)
+		     void *buffer, size_t buffer_size)
 {
 	struct buffer_head *bh = NULL;
 	struct ext3_xattr_entry *entry;
-	size_t name_len, size;
-	char *end;
+	size_t size;
 	int error;
 
 	ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
 		  name_index, name, buffer, (long)buffer_size);
 
-	if (name == NULL)
-		return -EINVAL;
 	error = -ENODATA;
 	if (!EXT3_I(inode)->i_file_acl)
 		goto cleanup;
 	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
 	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
-	error = -EIO;
 	if (!bh)
 		goto cleanup;
 	ea_bdebug(bh, "b_count=%d, refcount=%d",
-		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-	end = bh->b_data + bh->b_size;
-	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
-bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
-			"inode %ld: bad block %d", inode->i_ino,
-			EXT3_I(inode)->i_file_acl);
+		atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
+	if (ext3_xattr_check_block(bh)) {
+bad_block:	ext3_error(inode->i_sb, __FUNCTION__,
+			   "inode %ld: bad block %d", inode->i_ino,
+			   EXT3_I(inode)->i_file_acl);
 		error = -EIO;
 		goto cleanup;
 	}
-	/* find named attribute */
-	name_len = strlen(name);
-
-	error = -ERANGE;
-	if (name_len > 255)
-		goto cleanup;
-	entry = FIRST_ENTRY(bh);
-	while (!IS_LAST_ENTRY(entry)) {
-		struct ext3_xattr_entry *next =
-			EXT3_XATTR_NEXT(entry);
-		if ((char *)next >= end)
-			goto bad_block;
-		if (name_index == entry->e_name_index &&
-		    name_len == entry->e_name_len &&
-		    memcmp(name, entry->e_name, name_len) == 0)
-			goto found;
-		entry = next;
-	}
-	/* Check the remaining name entries */
-	while (!IS_LAST_ENTRY(entry)) {
-		struct ext3_xattr_entry *next =
-			EXT3_XATTR_NEXT(entry);
-		if ((char *)next >= end)
-			goto bad_block;
-		entry = next;
-	}
-	if (ext3_xattr_cache_insert(bh))
-		ea_idebug(inode, "cache insert failed");
-	error = -ENODATA;
-	goto cleanup;
-found:
-	/* check the buffer size */
-	if (entry->e_value_block != 0)
+	ext3_xattr_cache_insert(bh);
+	entry = BFIRST(bh);
+	error = ext3_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
+	if (error == -EIO)
 		goto bad_block;
+	if (error)
+		goto cleanup;
 	size = le32_to_cpu(entry->e_value_size);
-	if (size > inode->i_sb->s_blocksize ||
-	    le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize)
-		goto bad_block;
-
-	if (ext3_xattr_cache_insert(bh))
-		ea_idebug(inode, "cache insert failed");
 	if (buffer) {
 		error = -ERANGE;
 		if (size > buffer_size)
 			goto cleanup;
-		/* return value of attribute */
 		memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
-			size);
+		       size);
 	}
 	error = size;
 
 cleanup:
 	brelse(bh);
-
 	return error;
 }
 
-/*
- * ext3_xattr_ibody_get()
- *
- * routine looks for attribute in inode body and returns it's value and size
- */
 static int
 ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
-	       void *buffer, size_t buffer_size)
+		     void *buffer, size_t buffer_size)
 {
-	int size, name_len = strlen(name), storage_size;
-	struct ext3_xattr_entry *last;
+	struct ext3_xattr_ibody_header *header;
+	struct ext3_xattr_entry *entry;
 	struct ext3_inode *raw_inode;
 	struct ext3_iloc iloc;
-	char *start, *end;
-	int ret = -ENOENT;
-
-	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
-		return -ENOENT;
+	size_t size;
+	void *end;
+	int error;
 
-	ret = ext3_get_inode_loc(inode, &iloc, 1);
-	if (ret)
-		return ret;
+	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE ||
+	    !(EXT3_I(inode)->i_state & EXT3_STATE_XATTR))
+		return -ENODATA;
+	error = ext3_get_inode_loc(inode, &iloc);
+	if (error)
+		return error;
 	raw_inode = ext3_raw_inode(&iloc);
-
-	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
-				EXT3_GOOD_OLD_INODE_SIZE -
-				EXT3_I(inode)->i_extra_isize -
-				sizeof(__u32);
-	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
-			EXT3_I(inode)->i_extra_isize;
-	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
-		brelse(iloc.bh);
-		return -ENOENT;
-	}
-	start += sizeof(__u32);
-	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
-
-	last = (struct ext3_xattr_entry *) start;
-	while (!IS_LAST_ENTRY(last)) {
-		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-		if (le32_to_cpu(last->e_value_size) > storage_size ||
-				(char *) next >= end) {
-			ext3_error(inode->i_sb, "ext3_xattr_ibody_get",
-				"inode %ld", inode->i_ino);
-			brelse(iloc.bh);
-			return -EIO;
-		}
-		if (name_index == last->e_name_index &&
-		    name_len == last->e_name_len &&
-		    !memcmp(name, last->e_name, name_len))
-			goto found;
-		last = next;
+	header = IHDR(inode, raw_inode);
+	entry = IFIRST(header);
+	end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
+	error = ext3_xattr_check_names(entry, end);
+	if (error)
+		goto cleanup;
+	error = ext3_xattr_find_entry(&entry, name_index, name,
+				      end - (void *)entry, 0);
+	if (error)
+		goto cleanup;
+	size = le32_to_cpu(entry->e_value_size);
+	if (buffer) {
+		error = -ERANGE;
+		if (size > buffer_size)
+			goto cleanup;
+		memcpy(buffer, (void *)IFIRST(header) +
+		       le16_to_cpu(entry->e_value_offs), size);
 	}
+	error = size;
 
-	/* can't find EA */
-	brelse(iloc.bh);
-	return -ENOENT;
-
-found:
-	size = le32_to_cpu(last->e_value_size);
-	if (buffer) {
-		ret = -ERANGE;
-		if (buffer_size >= size) {
-			memcpy(buffer, start + le16_to_cpu(last->e_value_offs),
-				size);
-			ret = size;
-		}
-	} else
-		ret = size;
+cleanup:
 	brelse(iloc.bh);
-	return ret;
+	return error;
 }
 
 /*
@@ -321,33 +318,47 @@
 ext3_xattr_get(struct inode *inode, int name_index, const char *name,
 	       void *buffer, size_t buffer_size)
 {
-	int err;
+	int error;
 
 	down_read(&EXT3_I(inode)->xattr_sem);
-
-	/* try to find attribute in inode body */
-	err = ext3_xattr_ibody_get(inode, name_index, name,
-					buffer, buffer_size);
-	if (err < 0)
-		/* search was unsuccessful, try to find EA in dedicated block */
-		err = ext3_xattr_block_get(inode, name_index, name,
-				buffer, buffer_size);
+	error = ext3_xattr_ibody_get(inode, name_index, name, buffer,
+				     buffer_size);
+	if (error == -ENODATA)
+		error = ext3_xattr_block_get(inode, name_index, name, buffer,
+					     buffer_size);
 	up_read(&EXT3_I(inode)->xattr_sem);
-
-	return err;
+	return error;
 }
 
-/* ext3_xattr_block_list()
- *
- * generate list of attributes stored in EA block
- */
 static int
+ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry,
+			char *buffer, size_t buffer_size)
+{
+	size_t rest = buffer_size;
+
+	for (; !IS_LAST_ENTRY(entry); entry = EXT3_XATTR_NEXT(entry)) {
+		struct xattr_handler *handler =
+			ext3_xattr_handler(entry->e_name_index);
+
+		if (handler) {
+			size_t size = handler->list(inode, buffer, rest,
+						    entry->e_name,
+						    entry->e_name_len);
+			if (buffer) {
+				if (size > rest)
+					return -ERANGE;
+				buffer += size;
+			}
+			rest -= size;
+		}
+	}
+	return buffer_size - rest;
+}
+
+int
 ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
 	struct buffer_head *bh = NULL;
-	struct ext3_xattr_entry *entry;
-	char *end;
-	size_t rest = buffer_size;
 	int error;
 
 	ea_idebug(inode, "buffer=%p, buffer_size=%ld",
@@ -362,50 +373,16 @@
 	if (!bh)
 		goto cleanup;
 	ea_bdebug(bh, "b_count=%d, refcount=%d",
-		(int) atomic_read(&(bh->b_count)), (int) le32_to_cpu(HDR(bh)->h_refcount));
-	end = bh->b_data + bh->b_size;
-	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
-bad_block:	ext3_error(inode->i_sb, "ext3_xattr_list",
-			"inode %ld: bad block %d", inode->i_ino,
-			EXT3_I(inode)->i_file_acl);
+		atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
+	if (ext3_xattr_check_block(bh)) {
+		ext3_error(inode->i_sb, __FUNCTION__,
+			   "inode %ld: bad block %d", inode->i_ino,
+			   EXT3_I(inode)->i_file_acl);
 		error = -EIO;
 		goto cleanup;
 	}
-
-	/* check the on-disk data structure */
-	entry = FIRST_ENTRY(bh);
-	while (!IS_LAST_ENTRY(entry)) {
-		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(entry);
-
-		if ((char *)next >= end)
-			goto bad_block;
-		entry = next;
-	}
-	if (ext3_xattr_cache_insert(bh))
-		ea_idebug(inode, "cache insert failed");
-
-	/* list the attribute names */
-	for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry);
-	     entry = EXT3_XATTR_NEXT(entry)) {
-		struct xattr_handler *handler =
-			ext3_xattr_handler(entry->e_name_index);
-
-		if (handler) {
-			size_t size = handler->list(inode, buffer, rest,
-						    entry->e_name,
-						    entry->e_name_len);
-			if (buffer) {
-				if (size > rest) {
-					error = -ERANGE;
-					goto cleanup;
-				}
-				buffer += size;
-			}
-			rest -= size;
-		}
-	}
-	error = buffer_size - rest;  /* total size */
+	ext3_xattr_cache_insert(bh);
+	error = ext3_xattr_list_entries(inode, BFIRST(bh), buffer, buffer_size);
 
 cleanup:
 	brelse(bh);
@@ -413,77 +390,33 @@
 	return error;
 }
 
-/* ext3_xattr_ibody_list()
- *
- * generate list of attributes stored in inode body
- */
 static int
 ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
-	struct ext3_xattr_entry *last;
+	struct ext3_xattr_ibody_header *header;
 	struct ext3_inode *raw_inode;
-	size_t rest = buffer_size;
 	struct ext3_iloc iloc;
-	char *start, *end;
-	int storage_size;
-	int size = 0;
-	int ret;
+	void *end;
+	int error;
 
-	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
+	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE ||
+	    !(EXT3_I(inode)->i_state & EXT3_STATE_XATTR))
 		return 0;
-
-	ret = ext3_get_inode_loc(inode, &iloc, 1);
-	if (ret)
-		return ret;
+	error = ext3_get_inode_loc(inode, &iloc);
+	if (error)
+		return error;
 	raw_inode = ext3_raw_inode(&iloc);
-
-	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
-				EXT3_GOOD_OLD_INODE_SIZE -
-				EXT3_I(inode)->i_extra_isize -
-				sizeof(__u32);
-	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
-			EXT3_I(inode)->i_extra_isize;
-	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC)
+	header = IHDR(inode, raw_inode);
+	end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
+	error = ext3_xattr_check_names(IFIRST(header), end);
+	if (error)
 		goto cleanup;
-	start += sizeof(__u32);
-	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
-
-	last = (struct ext3_xattr_entry *) start;
-	while (!IS_LAST_ENTRY(last)) {
-		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-		if ((char *) next >= end) {
-			ext3_error(inode->i_sb, "ext3_xattr_ibody_list",
-					"inode %ld", inode->i_ino);
-			ret = -EIO;
-			goto cleanup;
-		}
-		last = next;
-	}
-
-	last = (struct ext3_xattr_entry *) start;
-	for (; !IS_LAST_ENTRY(last); last = EXT3_XATTR_NEXT(last)) {
-		struct xattr_handler *handler =
-			ext3_xattr_handler(last->e_name_index);
-
-		if (!handler)
-			continue;
-
-		size += handler->list(inode, buffer, rest, last->e_name,
-					last->e_name_len);
-		if (buffer) {
-			if (size > rest) {
-				ret = -ERANGE;
-				goto cleanup;
-			}
-			buffer += size;
-		}
-		rest -= size;
-	}
-	ret = buffer_size - rest; /* total size */
+	error = ext3_xattr_list_entries(inode, IFIRST(header),
+					buffer, buffer_size);
 
 cleanup:
 	brelse(iloc.bh);
-	return ret;
+	return error;
 }
 
 /*
@@ -496,53 +429,26 @@
  * Returns a negative error number on failure, or the number of bytes
  * used / required on success.
  */
-static int
+int
 ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
-	int size = buffer_size;
-	int error;
+	int i_error, b_error;
 
 	down_read(&EXT3_I(inode)->xattr_sem);
-
-	/* get list of attributes stored in inode body */
-	error = ext3_xattr_ibody_list(inode, buffer, buffer_size);
-	if (error < 0) {
-		/* some error occured while collecting
-		 * attributes in inode body */
-		size = 0;
-		goto cleanup;
-	}
-	size = error;
-
-	/* get list of attributes stored in dedicated block */
-	if (buffer) {
-		buffer_size -= error;
-		if (buffer_size <= 0) {
-			buffer = NULL;
-			buffer_size = 0;
-		} else
-			buffer += error;
+	i_error = ext3_xattr_ibody_list(inode, buffer, buffer_size);
+	if (i_error < 0) {
+		b_error = 0;
+	} else {
+		if (buffer) {
+			buffer += i_error;
+			buffer_size -= i_error;
+		}
+		b_error = ext3_xattr_block_list(inode, buffer, buffer_size);
+		if (b_error < 0)
+			i_error = 0;
 	}
-
-	error = ext3_xattr_block_list(inode, buffer, buffer_size);
-	/* listing was successful, so we return len */
-	if (error < 0)
-		size = 0;
-
-cleanup:
 	up_read(&EXT3_I(inode)->xattr_sem);
-	return error + size;
-}
-
-/*
- * Inode operation listxattr()
- *
- * dentry->d_inode->i_sem: don't care
- */
-ssize_t
-ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-{
-	return ext3_xattr_list(dentry->d_inode, buffer, size);
+	return i_error + b_error;
 }
 
 /*
@@ -566,687 +472,326 @@
 }
 
 /*
- * ext3_xattr_ibody_find()
- *
- * search attribute and calculate free space in inode body
- * NOTE: free space includes space our attribute hold
+ * Release the xattr block BH: If the reference count is > 1, decrement
+ * it; otherwise free the block.
  */
-static int
-ext3_xattr_ibody_find(struct inode *inode, int name_index,
-			const char *name, int *free)
+static void
+ext3_xattr_release_block(handle_t *handle, struct inode *inode,
+			 struct buffer_head *bh)
 {
-	struct ext3_xattr_entry *last;
-	struct ext3_inode *raw_inode;
-	int name_len = strlen(name);
-	int err, storage_size;
-	struct ext3_iloc iloc;
-	char *start, *end;
-	int ret = -ENOENT;
-
-	*free = 0;
-	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
-		return ret;
+	struct mb_cache_entry *ce = NULL;
 
-	err = ext3_get_inode_loc(inode, &iloc, 1);
-	if (err)
-		return -EIO;
-	raw_inode = ext3_raw_inode(&iloc);
-
-	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
-				EXT3_GOOD_OLD_INODE_SIZE -
-				EXT3_I(inode)->i_extra_isize -
-				sizeof(__u32);
-	*free = storage_size - sizeof(__u32);
-	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
-			EXT3_I(inode)->i_extra_isize;
-	if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) {
-		brelse(iloc.bh);
-		return -ENOENT;
-	}
-	start += sizeof(__u32);
-	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
-
-	last = (struct ext3_xattr_entry *) start;
-	while (!IS_LAST_ENTRY(last)) {
-		struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-		if (le32_to_cpu(last->e_value_size) > storage_size ||
-				(char *) next >= end) {
-			ext3_error(inode->i_sb, "ext3_xattr_ibody_find",
-				"inode %ld", inode->i_ino);
-			brelse(iloc.bh);
-			return -EIO;
-		}
-
-		if (name_index == last->e_name_index &&
-		    name_len == last->e_name_len &&
-		    !memcmp(name, last->e_name, name_len)) {
-			ret = 0;
-		} else {
-			*free -= EXT3_XATTR_LEN(last->e_name_len);
-			*free -= le32_to_cpu(last->e_value_size);
+	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, bh->b_blocknr);
+	if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
+		ea_bdebug(bh, "refcount now=0; freeing");
+		if (ce)
+			mb_cache_entry_free(ce);
+		ext3_free_blocks(handle, inode, bh->b_blocknr, 1);
+		get_bh(bh);
+		ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
+	} else {
+		if (ext3_journal_get_write_access(handle, bh) == 0) {
+			lock_buffer(bh);
+			BHDR(bh)->h_refcount = cpu_to_le32(
+				le32_to_cpu(BHDR(bh)->h_refcount) - 1);
+			ext3_journal_dirty_metadata(handle, bh);
+			if (IS_SYNC(inode))
+				handle->h_sync = 1;
+			DQUOT_FREE_BLOCK(inode, 1);
+			unlock_buffer(bh);
+			ea_bdebug(bh, "refcount now=%d; releasing",
+				  le32_to_cpu(BHDR(bh)->h_refcount));
 		}
-		last = next;
+		if (ce)
+			mb_cache_entry_release(ce);
 	}
-
-	brelse(iloc.bh);
-	return ret;
 }
 
-/*
- * ext3_xattr_block_find()
- *
- * search attribute and calculate free space in EA block (if it allocated)
- * NOTE: free space includes space our attribute hold
- */
-static int
-ext3_xattr_block_find(struct inode *inode, int name_index,
-			const char *name, int *free)
-{
-	struct buffer_head *bh = NULL;
-	struct ext3_xattr_entry *entry;
-	char *end;
-	int name_len, error = -ENOENT;
-
-	if (!EXT3_I(inode)->i_file_acl) {
-		*free = inode->i_sb->s_blocksize -
-			sizeof(struct ext3_xattr_header) -
-			sizeof(__u32);
-		return -ENOENT;
-	}
-	ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl);
-	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
-	if (!bh)
-		return -EIO;
-	ea_bdebug(bh, "b_count=%d, refcount=%d",
-		atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount));
-	end = bh->b_data + bh->b_size;
-	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
-bad_block:	ext3_error(inode->i_sb, "ext3_xattr_get",
-			"inode %ld: bad block %d", inode->i_ino,
-			EXT3_I(inode)->i_file_acl);
-		brelse(bh);
-		return -EIO;
-	}
-	/* find named attribute */
-	name_len = strlen(name);
-	*free = bh->b_size - sizeof(__u32);
-
-	entry = FIRST_ENTRY(bh);
-	while (!IS_LAST_ENTRY(entry)) {
-		struct ext3_xattr_entry *next =
-			EXT3_XATTR_NEXT(entry);
-		if ((char *)next >= end)
-			goto bad_block;
-		if (name_index == entry->e_name_index &&
-		    name_len == entry->e_name_len &&
-		    memcmp(name, entry->e_name, name_len) == 0) {
-			error = 0;
-		} else {
-			*free -= EXT3_XATTR_LEN(entry->e_name_len);
-			*free -= le32_to_cpu(entry->e_value_size);
-		}
-		entry = next;
-	}
-	brelse(bh);
+struct ext3_xattr_info {
+	int name_index;
+	const char *name;
+	const void *value;
+	size_t value_len;
+};
 
-	return error;
-}
+struct ext3_xattr_search {
+	struct ext3_xattr_entry *first;
+	void *base;
+	void *end;
+	struct ext3_xattr_entry *here;
+	int not_found;
+};
 
-/*
- * ext3_xattr_ibody_set()
- *
- * this routine add/remove/replace attribute in inode body
- */
 static int
-ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index,
-		      const char *name, const void *value, size_t value_len,
-		      int flags)
+ext3_xattr_set_entry(struct ext3_xattr_info *i, struct ext3_xattr_search *s)
 {
-	struct ext3_xattr_entry *last, *next, *here = NULL;
-	struct ext3_inode *raw_inode;
-	int name_len = strlen(name);
-	int esize = EXT3_XATTR_LEN(name_len);
-	struct buffer_head *bh;
-	int err, storage_size;
-	struct ext3_iloc iloc;
-	int free, min_offs;
-	char *start, *end;
-
-	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
-		return -ENOSPC;
-
-	err = ext3_get_inode_loc(inode, &iloc, 1);
-	if (err)
-		return err;
-	raw_inode = ext3_raw_inode(&iloc);
-	bh = iloc.bh;
-
-	storage_size = EXT3_SB(inode->i_sb)->s_inode_size -
-				EXT3_GOOD_OLD_INODE_SIZE -
-				EXT3_I(inode)->i_extra_isize -
-				sizeof(__u32);
-	start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE +
-			EXT3_I(inode)->i_extra_isize;
-	if ((*(__u32*) start) != EXT3_XATTR_MAGIC) {
-		/* inode had no attributes before */
-		*((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC);
-	}
-	start += sizeof(__u32);
-	end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
-	min_offs = storage_size;
-	free = storage_size - sizeof(__u32);
-
-	last = (struct ext3_xattr_entry *) start;
-	while (!IS_LAST_ENTRY(last)) {
-		next = EXT3_XATTR_NEXT(last);
-		if (le32_to_cpu(last->e_value_size) > storage_size ||
-				(char *) next >= end) {
-			ext3_error(inode->i_sb, "ext3_xattr_ibody_set",
-				"inode %ld", inode->i_ino);
-			brelse(bh);
-			return -EIO;
-		}
+	struct ext3_xattr_entry *last;
+	size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
 
-		if (last->e_value_size) {
-			int offs = le16_to_cpu(last->e_value_offs);
+	/* Compute min_offs and last. */
+	last = s->first;
+	for (; !IS_LAST_ENTRY(last); last = EXT3_XATTR_NEXT(last)) {
+		if (!last->e_value_block && last->e_value_size) {
+			size_t offs = le16_to_cpu(last->e_value_offs);
 			if (offs < min_offs)
 				min_offs = offs;
 		}
-		if (name_index == last->e_name_index &&
-			name_len == last->e_name_len &&
-			!memcmp(name, last->e_name, name_len))
-			here = last;
-		else {
-			/* we calculate all but our attribute
-			 * because it will be removed before changing */
-			free -= EXT3_XATTR_LEN(last->e_name_len);
-			free -= le32_to_cpu(last->e_value_size);
-		}
-		last = next;
-	}
-
-	if (value && (esize + value_len > free)) {
-		brelse(bh);
-		return -ENOSPC;
-	}
-
-	err = ext3_reserve_inode_write(handle, inode, &iloc);
-	if (err) {
-		brelse(bh);
-		return err;
-	}
-
-	/* optimization: can we simple replace old value ? */
-	if (here && value_len == le32_to_cpu(here->e_value_size)) {
-		int offs = le16_to_cpu(here->e_value_offs);
-		memcpy(start + offs, value, value_len);
-		goto done;
-	}
-
-	if (here) {
-		/* time to remove old value */
-		struct ext3_xattr_entry *e;
-		int size = le32_to_cpu(here->e_value_size);
-		int border = le16_to_cpu(here->e_value_offs);
-		char *src;
-
-		/* move tail */
-		memmove(start + min_offs + size, start + min_offs,
-				border - min_offs);
-
-		/* recalculate offsets */
-		e = (struct ext3_xattr_entry *) start;
-		while (!IS_LAST_ENTRY(e)) {
-			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e);
-			int offs = le16_to_cpu(e->e_value_offs);
-			if (offs < border)
-				e->e_value_offs =
-					cpu_to_le16(offs + size);
-			e = next;
-		}
-		min_offs += size;
-
-		/* remove entry */
-		border = EXT3_XATTR_LEN(here->e_name_len);
-		src = (char *) here + EXT3_XATTR_LEN(here->e_name_len);
-		size = (char *) last - src;
-		if ((char *) here + size > end)
-			printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n",
-					__FILE__, __LINE__, here, size, end);
-		memmove(here, src, size);
-		last = (struct ext3_xattr_entry *) ((char *) last - border);
-		*((__u32 *) last) = 0;
-	}
-
-	if (value) {
-		int offs = min_offs - value_len;
-		/* use last to create new entry */
-		last->e_name_len = strlen(name);
-		last->e_name_index = name_index;
-		last->e_value_offs = cpu_to_le16(offs);
-		last->e_value_size = cpu_to_le32(value_len);
-		last->e_hash = last->e_value_block = 0;
-		memset(last->e_name, 0, esize);
-		memcpy(last->e_name, name, last->e_name_len);
-		if (start + offs + value_len > end)
-			printk("ALERT at %s:%d: 0x%p + %d + %zd > 0x%p\n",
-					__FILE__, __LINE__, start, offs,
-					value_len, end);
-		memcpy(start + offs, value, value_len);
-		last = EXT3_XATTR_NEXT(last);
-		*((__u32 *) last) = 0;
 	}
-
-done:
-	ext3_mark_iloc_dirty(handle, inode, &iloc);
-	brelse(bh);
-
-	return 0;
-}
-
-/*
- * ext3_xattr_block_set()
- *
- * this routine add/remove/replace attribute in EA block
- */
-static int
-ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index,
-		      const char *name, const void *value, size_t value_len,
-		      int flags)
-{
-	struct super_block *sb = inode->i_sb;
-	struct buffer_head *bh = NULL;
-	struct ext3_xattr_header *header = NULL;
-	struct ext3_xattr_entry *here, *last;
-	size_t name_len, free, min_offs = sb->s_blocksize;
-	int not_found = 1, error;
-	char *end;
-
-	/*
-	 * header -- Points either into bh, or to a temporarily
-	 *           allocated buffer.
-	 * here -- The named entry found, or the place for inserting, within
-	 *         the block pointed to by header.
-	 * last -- Points right after the last named entry within the block
-	 *         pointed to by header.
-	 * min_offs -- The offset of the first value (values are aligned
-	 *             towards the end of the block).
-	 * end -- Points right after the block pointed to by header.
-	 */
-	name_len = strlen(name);
-	if (EXT3_I(inode)->i_file_acl) {
-		/* The inode already has an extended attribute block. */
-		bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
-		error = -EIO;
-		if (!bh)
-			goto cleanup;
-		ea_bdebug(bh, "b_count=%d, refcount=%d",
-			atomic_read(&(bh->b_count)),
-			le32_to_cpu(HDR(bh)->h_refcount));
-		header = HDR(bh);
-		end = bh->b_data + bh->b_size;
-		if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-		    header->h_blocks != cpu_to_le32(1)) {
-bad_block:		ext3_error(sb, "ext3_xattr_set",
-				"inode %ld: bad block %d", inode->i_ino,
-				EXT3_I(inode)->i_file_acl);
-			error = -EIO;
-			goto cleanup;
-		}
-		/* Find the named attribute. */
-		here = FIRST_ENTRY(bh);
-		while (!IS_LAST_ENTRY(here)) {
-			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here);
-			if ((char *)next >= end)
-				goto bad_block;
-			if (!here->e_value_block && here->e_value_size) {
-				size_t offs = le16_to_cpu(here->e_value_offs);
-				if (offs < min_offs)
-					min_offs = offs;
-			}
-			not_found = name_index - here->e_name_index;
-			if (!not_found)
-				not_found = name_len - here->e_name_len;
-			if (!not_found)
-				not_found = memcmp(name, here->e_name,name_len);
-			if (not_found <= 0)
-				break;
-			here = next;
-		}
-		last = here;
-		/* We still need to compute min_offs and last. */
-		while (!IS_LAST_ENTRY(last)) {
-			struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last);
-			if ((char *)next >= end)
-				goto bad_block;
-			if (!last->e_value_block && last->e_value_size) {
-				size_t offs = le16_to_cpu(last->e_value_offs);
-				if (offs < min_offs)
-					min_offs = offs;
-			}
-			last = next;
-		}
-
-		/* Check whether we have enough space left. */
-		free = min_offs - ((char*)last - (char*)header) - sizeof(__u32);
-	} else {
-		/* We will use a new extended attribute block. */
-		free = sb->s_blocksize -
-			sizeof(struct ext3_xattr_header) - sizeof(__u32);
-		here = last = NULL;  /* avoid gcc uninitialized warning. */
-	}
-
-	if (not_found) {
-		/* Request to remove a nonexistent attribute? */
-		error = -ENODATA;
-		if (flags & XATTR_REPLACE)
-			goto cleanup;
-		error = 0;
-		if (value == NULL)
-			goto cleanup;
-	} else {
-		/* Request to create an existing attribute? */
-		error = -EEXIST;
-		if (flags & XATTR_CREATE)
-			goto cleanup;
-		if (!here->e_value_block && here->e_value_size) {
-			size_t size = le32_to_cpu(here->e_value_size);
-
-			if (le16_to_cpu(here->e_value_offs) + size > 
-			    sb->s_blocksize || size > sb->s_blocksize)
-				goto bad_block;
+	free = min_offs - ((void *)last - s->base) - sizeof(__u32);
+	if (!s->not_found) {
+		if (!s->here->e_value_block && s->here->e_value_size) {
+			size_t size = le32_to_cpu(s->here->e_value_size);
 			free += EXT3_XATTR_SIZE(size);
 		}
 		free += EXT3_XATTR_LEN(name_len);
 	}
-	error = -ENOSPC;
-	if (free < EXT3_XATTR_LEN(name_len) + EXT3_XATTR_SIZE(value_len))
-		goto cleanup;
-
-	/* Here we know that we can set the new attribute. */
-
-	if (header) {
-		int credits = 0;
-
-		/* assert(header == HDR(bh)); */
-		if (header->h_refcount != cpu_to_le32(1))
-			goto skip_get_write_access;
-		/* ext3_journal_get_write_access() requires an unlocked bh,
-		   which complicates things here. */
-		error = ext3_journal_get_write_access_credits(handle, bh,
-							      &credits);
-		if (error)
-			goto cleanup;
-		lock_buffer(bh);
-		if (header->h_refcount == cpu_to_le32(1)) {
-			ea_bdebug(bh, "modifying in-place");
-			ext3_xattr_cache_remove(bh);
-			/* keep the buffer locked while modifying it. */
-		} else {
-			int offset;
-
-			unlock_buffer(bh);
-			journal_release_buffer(handle, bh, credits);
-		skip_get_write_access:
-			ea_bdebug(bh, "cloning");
-			header = kmalloc(bh->b_size, GFP_KERNEL);
-			error = -ENOMEM;
-			if (header == NULL)
-				goto cleanup;
-			memcpy(header, HDR(bh), bh->b_size);
-			header->h_refcount = cpu_to_le32(1);
-			offset = (char *)here - bh->b_data;
-			here = ENTRY((char *)header + offset);
-			offset = (char *)last - bh->b_data;
-			last = ENTRY((char *)header + offset);
-		}
-	} else {
-		/* Allocate a buffer where we construct the new block. */
-		header = kmalloc(sb->s_blocksize, GFP_KERNEL);
-		error = -ENOMEM;
-		if (header == NULL)
-			goto cleanup;
-		memset(header, 0, sb->s_blocksize);
-		end = (char *)header + sb->s_blocksize;
-		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
-		header->h_blocks = header->h_refcount = cpu_to_le32(1);
-		last = here = ENTRY(header+1);
+	if (i->value) {
+		if (free < EXT3_XATTR_SIZE(i->value_len) ||
+		    free < EXT3_XATTR_LEN(name_len) +
+			   EXT3_XATTR_SIZE(i->value_len))
+			return -ENOSPC;
 	}
 
-	/* Iff we are modifying the block in-place, bh is locked here. */
-
-	if (not_found) {
+	if (i->value && s->not_found) {
 		/* Insert the new name. */
 		size_t size = EXT3_XATTR_LEN(name_len);
-		size_t rest = (char *)last - (char *)here;
-		memmove((char *)here + size, here, rest);
-		memset(here, 0, size);
-		here->e_name_index = name_index;
-		here->e_name_len = name_len;
-		memcpy(here->e_name, name, name_len);
+		size_t rest = (void *)last - (void *)s->here + sizeof(__u32);
+		memmove((void *)s->here + size, s->here, rest);
+		memset(s->here, 0, size);
+		s->here->e_name_index = i->name_index;
+		s->here->e_name_len = name_len;
+		memcpy(s->here->e_name, i->name, name_len);
 	} else {
-		if (!here->e_value_block && here->e_value_size) {
-			char *first_val = (char *)header + min_offs;
-			size_t offs = le16_to_cpu(here->e_value_offs);
-			char *val = (char *)header + offs;
+		if (!s->here->e_value_block && s->here->e_value_size) {
+			void *first_val = s->base + min_offs;
+			size_t offs = le16_to_cpu(s->here->e_value_offs);
+			void *val = s->base + offs;
 			size_t size = EXT3_XATTR_SIZE(
-				le32_to_cpu(here->e_value_size));
+				le32_to_cpu(s->here->e_value_size));
 
-			if (size == EXT3_XATTR_SIZE(value_len)) {
+			if (i->value && size == EXT3_XATTR_SIZE(i->value_len)) {
 				/* The old and the new value have the same
 				   size. Just replace. */
-				here->e_value_size = cpu_to_le32(value_len);
+				s->here->e_value_size =
+					cpu_to_le32(i->value_len);
 				memset(val + size - EXT3_XATTR_PAD, 0,
 				       EXT3_XATTR_PAD); /* Clear pad bytes. */
-				memcpy(val, value, value_len);
-				goto skip_replace;
+				memcpy(val, i->value, i->value_len);
+				return 0;
 			}
 
 			/* Remove the old value. */
 			memmove(first_val + size, first_val, val - first_val);
 			memset(first_val, 0, size);
-			here->e_value_offs = 0;
+			s->here->e_value_size = 0;
+			s->here->e_value_offs = 0;
 			min_offs += size;
 
 			/* Adjust all value offsets. */
-			last = ENTRY(header+1);
+			last = s->first;
 			while (!IS_LAST_ENTRY(last)) {
 				size_t o = le16_to_cpu(last->e_value_offs);
-				if (!last->e_value_block && o < offs)
+				if (!last->e_value_block &&
+				    last->e_value_size && o < offs)
 					last->e_value_offs =
 						cpu_to_le16(o + size);
 				last = EXT3_XATTR_NEXT(last);
 			}
 		}
-		if (value == NULL) {
+		if (!i->value) {
 			/* Remove the old name. */
 			size_t size = EXT3_XATTR_LEN(name_len);
-			last = ENTRY((char *)last - size);
-			memmove(here, (char*)here + size,
-				(char*)last - (char*)here);
+			last = ENTRY((void *)last - size);
+			memmove(s->here, (void *)s->here + size,
+				(void *)last - (void *)s->here + sizeof(__u32));
 			memset(last, 0, size);
 		}
 	}
 
-	if (value != NULL) {
+	if (i->value) {
 		/* Insert the new value. */
-		here->e_value_size = cpu_to_le32(value_len);
-		if (value_len) {
-			size_t size = EXT3_XATTR_SIZE(value_len);
-			char *val = (char *)header + min_offs - size;
-			here->e_value_offs =
-				cpu_to_le16((char *)val - (char *)header);
+		s->here->e_value_size = cpu_to_le32(i->value_len);
+		if (i->value_len) {
+			size_t size = EXT3_XATTR_SIZE(i->value_len);
+			void *val = s->base + min_offs - size;
+			s->here->e_value_offs = cpu_to_le16(min_offs - size);
 			memset(val + size - EXT3_XATTR_PAD, 0,
 			       EXT3_XATTR_PAD); /* Clear the pad bytes. */
-			memcpy(val, value, value_len);
+			memcpy(val, i->value, i->value_len);
 		}
 	}
-
-skip_replace:
-	if (IS_LAST_ENTRY(ENTRY(header+1))) {
-		/* This block is now empty. */
-		if (bh && header == HDR(bh))
-			unlock_buffer(bh);  /* we were modifying in-place. */
-		error = ext3_xattr_set_handle2(handle, inode, bh, NULL);
-	} else {
-		ext3_xattr_rehash(header, here);
-		if (bh && header == HDR(bh))
-			unlock_buffer(bh);  /* we were modifying in-place. */
-		error = ext3_xattr_set_handle2(handle, inode, bh, header);
-	}
-
-cleanup:
-	brelse(bh);
-	if (!(bh && header == HDR(bh)))
-		kfree(header);
-
-	return error;
+	return 0;
 }
 
-/*
- * ext3_xattr_set_handle()
- *
- * Create, replace or remove an extended attribute for this inode. Buffer
- * is NULL to remove an existing extended attribute, and non-NULL to
- * either replace an existing extended attribute, or create a new extended
- * attribute. The flags XATTR_REPLACE and XATTR_CREATE
- * specify that an extended attribute must exist and must not exist
- * previous to the call, respectively.
- *
- * Returns 0, or a negative error number on failure.
- */
+struct ext3_xattr_block_find {
+	struct ext3_xattr_search s;
+	struct buffer_head *bh;
+};
+
 int
-ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
-		const char *name, const void *value, size_t value_len,
-		int flags)
+ext3_xattr_block_find(struct inode *inode, struct ext3_xattr_info *i,
+		      struct ext3_xattr_block_find *bs)
 {
-	int free1 = -1, free2 = -1;
-	int err, where = 0, total;
-	int name_len;
+	struct super_block *sb = inode->i_sb;
+	int error;
 
 	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-		  name_index, name, value, (long)value_len);
+		  i->name_index, i->name, i->value, (long)i->value_len);
 
-	if (IS_RDONLY(inode))
-		return -EROFS;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
-	if (value == NULL)
-		value_len = 0;
-	if (name == NULL)
-		return -EINVAL;
-	name_len = strlen(name);
-	if (name_len > 255 || value_len > inode->i_sb->s_blocksize)
-		return -ERANGE;
-	down_write(&EXT3_I(inode)->xattr_sem);
-
-#define EX_FOUND_IN_IBODY	1
-#define EX_FOUND_IN_BLOCK	2
-
-	/* try to find attribute in inode body */
-	err = ext3_xattr_ibody_find(inode, name_index, name, &free1);
-	if (err == 0) {
-		/* found EA in inode */
-		where = EX_FOUND_IN_IBODY;
-	} else if (err == -ENOENT) {
-		/* there is no such attribute in inode body */
-		/* try to find attribute in dedicated block */
-		err = ext3_xattr_block_find(inode, name_index, name, &free2);
-		if (err != 0 && err != -ENOENT) {
-			/* not found EA in block */
-			goto finish;
-		} else if (err == 0) {
-			/* found EA in block */
-			where = EX_FOUND_IN_BLOCK;
+	if (EXT3_I(inode)->i_file_acl) {
+		/* The inode already has an extended attribute block. */
+		bs->bh = sb_bread(sb, EXT3_I(inode)->i_file_acl);
+		error = -EIO;
+		if (!bs->bh)
+			goto cleanup;
+		ea_bdebug(bs->bh, "b_count=%d, refcount=%d",
+			atomic_read(&(bs->bh->b_count)),
+			le32_to_cpu(BHDR(bs->bh)->h_refcount));
+		if (ext3_xattr_check_block(bs->bh)) {
+			ext3_error(sb, __FUNCTION__,
+				"inode %ld: bad block %d", inode->i_ino,
+				EXT3_I(inode)->i_file_acl);
+			error = -EIO;
+			goto cleanup;
 		}
-	} else
-		goto finish;
-
-	/* check flags: may replace? may create ? */
-	if (where && (flags & XATTR_CREATE)) {
-		err = -EEXIST;
-		goto finish;
-	} else if (!where && (flags & XATTR_REPLACE)) {
-		err = -ENODATA;
-		goto finish;
-	}
-
-	/* check if we have enough space to store attribute */
-	total = EXT3_XATTR_LEN(strlen(name)) + value_len;
-	if (total > free1 && free2 > 0 && total > free2) {
-		/* have no enough space */
-		err = -ENOSPC;
-		goto finish;
-	}
-
-	/* there are two cases when we want to remove EA from original storage:
-	 * a) EA is stored in the inode, but new value doesn't fit
-	 * b) EA is stored in the block, but new value fit in inode
-	 */
-	if (where == EX_FOUND_IN_IBODY && total > free1)
-		ext3_xattr_ibody_set(handle, inode, name_index, name,
-					NULL, 0, flags);
-	else if (where == EX_FOUND_IN_BLOCK && total <= free1)
-		ext3_xattr_block_set(handle, inode, name_index,
-					name, NULL, 0, flags);
-
-	/* try to store EA in inode body */
-	err = ext3_xattr_ibody_set(handle, inode, name_index, name,
-					value, value_len, flags);
-	if (err) {
-		/* can't store EA in inode body: try to store in block */
-		err = ext3_xattr_block_set(handle, inode, name_index, name,
-						value, value_len, flags);
+		/* Find the named attribute. */
+		bs->s.base = BHDR(bs->bh);
+		bs->s.first = BFIRST(bs->bh);
+		bs->s.end = bs->bh->b_data + bs->bh->b_size;
+		bs->s.here = bs->s.first;
+		error = ext3_xattr_find_entry(&bs->s.here, i->name_index,
+					      i->name, bs->bh->b_size, 1);
+		if (error && error != -ENODATA)
+			goto cleanup;
+		bs->s.not_found = error;
 	}
+	error = 0;
 
-finish:
-	up_write(&EXT3_I(inode)->xattr_sem);
-	return err;
+cleanup:
+	return error;
 }
 
-/*
- * Second half of ext3_xattr_set_handle(): Update the file system.
- */
 static int
-ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
-		       struct buffer_head *old_bh,
-		       struct ext3_xattr_header *header)
+ext3_xattr_block_set(handle_t *handle, struct inode *inode,
+		     struct ext3_xattr_info *i,
+		     struct ext3_xattr_block_find *bs)
 {
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *new_bh = NULL;
-	int credits = 0, error;
+	struct ext3_xattr_search *s = &bs->s;
+	struct mb_cache_entry *ce = NULL;
+	int error;
+
+#define header(x) ((struct ext3_xattr_header *)(x))
+
+	if (i->value && i->value_len > sb->s_blocksize)
+		return -ENOSPC;
+	if (s->base) {
+		ce = mb_cache_entry_get(ext3_xattr_cache, bs->bh->b_bdev,
+					bs->bh->b_blocknr);
+		if (header(s->base)->h_refcount == cpu_to_le32(1)) {
+			if (ce) {
+				mb_cache_entry_free(ce);
+				ce = NULL;
+			}
+			ea_bdebug(bs->bh, "modifying in-place");
+			error = ext3_journal_get_write_access(handle, bs->bh);
+			if (error)
+				goto cleanup;
+			lock_buffer(bs->bh);
+			error = ext3_xattr_set_entry(i, s);
+			if (!error) {
+				if (!IS_LAST_ENTRY(s->first))
+					ext3_xattr_rehash(header(s->base),
+							  s->here);
+				ext3_xattr_cache_insert(bs->bh);
+			}
+			unlock_buffer(bs->bh);
+			if (error == -EIO)
+				goto bad_block;
+			if (!error)
+				error = ext3_journal_dirty_metadata(handle,
+								    bs->bh);
+			if (error)
+				goto cleanup;
+			goto inserted;
+		} else {
+			int offset = (char *)s->here - bs->bh->b_data;
+
+			if (ce) {
+				mb_cache_entry_release(ce);
+				ce = NULL;
+			}
+			ea_bdebug(bs->bh, "cloning");
+			s->base = kmalloc(bs->bh->b_size, GFP_KERNEL);
+			error = -ENOMEM;
+			if (s->base == NULL)
+				goto cleanup;
+			memcpy(s->base, BHDR(bs->bh), bs->bh->b_size);
+			s->first = ENTRY(header(s->base)+1);
+			header(s->base)->h_refcount = cpu_to_le32(1);
+			s->here = ENTRY(s->base + offset);
+			s->end = s->base + bs->bh->b_size;
+		}
+	} else {
+		/* Allocate a buffer where we construct the new block. */
+		s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+		/* assert(header == s->base) */
+		error = -ENOMEM;
+		if (s->base == NULL)
+			goto cleanup;
+		memset(s->base, 0, sb->s_blocksize);
+		header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
+		header(s->base)->h_blocks = cpu_to_le32(1);
+		header(s->base)->h_refcount = cpu_to_le32(1);
+		s->first = ENTRY(header(s->base)+1);
+		s->here = ENTRY(header(s->base)+1);
+		s->end = s->base + sb->s_blocksize;
+	}
 
-	if (header) {
-		new_bh = ext3_xattr_cache_find(handle, inode, header, &credits);
+	error = ext3_xattr_set_entry(i, s);
+	if (error == -EIO)
+		goto bad_block;
+	if (error)
+		goto cleanup;
+	if (!IS_LAST_ENTRY(s->first))
+		ext3_xattr_rehash(header(s->base), s->here);
+
+inserted:
+	if (!IS_LAST_ENTRY(s->first)) {
+		new_bh = ext3_xattr_cache_find(inode, header(s->base), &ce);
 		if (new_bh) {
 			/* We found an identical block in the cache. */
-			if (new_bh == old_bh)
-				ea_bdebug(new_bh, "keeping this block");
+			if (new_bh == bs->bh)
+				ea_bdebug(new_bh, "keeping");
 			else {
 				/* The old block is released after updating
 				   the inode. */
-				ea_bdebug(new_bh, "reusing block");
-
 				error = -EDQUOT;
-				if (DQUOT_ALLOC_BLOCK(inode, 1)) {
-					unlock_buffer(new_bh);
-					journal_release_buffer(handle, new_bh,
-							       credits);
+				if (DQUOT_ALLOC_BLOCK(inode, 1))
+					goto cleanup;
+				error = ext3_journal_get_write_access(handle,
+								      new_bh);
+				if (error)
+					goto cleanup;
+				lock_buffer(new_bh);
+				BHDR(new_bh)->h_refcount = cpu_to_le32(1 +
+					le32_to_cpu(BHDR(new_bh)->h_refcount));
+				ea_bdebug(new_bh, "reusing; refcount now=%d",
+					le32_to_cpu(BHDR(new_bh)->h_refcount));
+				unlock_buffer(new_bh);
+				error = ext3_journal_dirty_metadata(handle,
+								    new_bh);
+				if (error)
 					goto cleanup;
-				}
-				HDR(new_bh)->h_refcount = cpu_to_le32(1 +
-					le32_to_cpu(HDR(new_bh)->h_refcount));
-				ea_bdebug(new_bh, "refcount now=%d",
-					le32_to_cpu(HDR(new_bh)->h_refcount));
 			}
-			unlock_buffer(new_bh);
-		} else if (old_bh && header == HDR(old_bh)) {
-			/* Keep this block. No need to lock the block as we
-			 * don't need to change the reference count. */
-			new_bh = old_bh;
+			mb_cache_entry_release(ce);
+			ce = NULL;
+		} else if (bs->bh && s->base == bs->bh->b_data) {
+			/* We were modifying this block in-place. */
+			ea_bdebug(bs->bh, "keeping this block");
+			new_bh = bs->bh;
 			get_bh(new_bh);
-			ext3_xattr_cache_insert(new_bh);
 		} else {
 			/* We need to allocate a new block */
 			int goal = le32_to_cpu(
@@ -1271,60 +816,206 @@
 				unlock_buffer(new_bh);
 				goto getblk_failed;
 			}
-			memcpy(new_bh->b_data, header, new_bh->b_size);
+			memcpy(new_bh->b_data, s->base, new_bh->b_size);
 			set_buffer_uptodate(new_bh);
 			unlock_buffer(new_bh);
 			ext3_xattr_cache_insert(new_bh);
-
+			error = ext3_journal_dirty_metadata(handle, new_bh);
+			if (error)
+				goto cleanup;
 			ext3_xattr_update_super_block(handle, sb);
 		}
-		error = ext3_journal_dirty_metadata(handle, new_bh);
-		if (error)
-			goto cleanup;
 	}
 
 	/* Update the inode. */
 	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-	inode->i_ctime = CURRENT_TIME_SEC;
-	ext3_mark_inode_dirty(handle, inode);
-	if (IS_SYNC(inode))
-		handle->h_sync = 1;
 
+	/* Drop the previous xattr block. */
+	if (bs->bh && bs->bh != new_bh)
+		ext3_xattr_release_block(handle, inode, bs->bh);
 	error = 0;
-	if (old_bh && old_bh != new_bh) {
-		/*
-		 * If there was an old block, and we are no longer using it,
-		 * release the old block.
-		*/
-		error = ext3_journal_get_write_access(handle, old_bh);
+
+cleanup:
+	if (ce)
+		mb_cache_entry_release(ce);
+	brelse(new_bh);
+	if (!(bs->bh && s->base == bs->bh->b_data))
+		kfree(s->base);
+
+	return error;
+
+bad_block:
+	ext3_error(inode->i_sb, __FUNCTION__,
+		   "inode %ld: bad block %d", inode->i_ino,
+		   EXT3_I(inode)->i_file_acl);
+	goto cleanup;
+
+#undef header
+}
+
+struct ext3_xattr_ibody_find {
+	struct ext3_xattr_search s;
+	struct ext3_iloc iloc;
+};
+
+int
+ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i,
+		      struct ext3_xattr_ibody_find *is)
+{
+	struct ext3_xattr_ibody_header *header;
+	struct ext3_inode *raw_inode;
+	int error;
+
+	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
+		return 0;
+	raw_inode = ext3_raw_inode(&is->iloc);
+	header = IHDR(inode, raw_inode);
+	is->s.base = is->s.first = IFIRST(header);
+	is->s.here = is->s.first;
+	is->s.end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size;
+	if (EXT3_I(inode)->i_state & EXT3_STATE_XATTR) {
+		error = ext3_xattr_check_names(IFIRST(header), is->s.end);
 		if (error)
+			return error;
+		/* Find the named attribute. */
+		error = ext3_xattr_find_entry(&is->s.here, i->name_index,
+					      i->name, is->s.end -
+					      (void *)is->s.base, 0);
+		if (error && error != -ENODATA)
+			return error;
+		is->s.not_found = error;
+	}
+	return 0;
+}
+
+static int
+ext3_xattr_ibody_set(handle_t *handle, struct inode *inode,
+		     struct ext3_xattr_info *i,
+		     struct ext3_xattr_ibody_find *is)
+{
+	struct ext3_xattr_ibody_header *header;
+	struct ext3_xattr_search *s = &is->s;
+	int error;
+
+	if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE)
+		return -ENOSPC;
+	error = ext3_xattr_set_entry(i, s);
+	if (error)
+		return error;
+	header = IHDR(inode, ext3_raw_inode(&is->iloc));
+	if (!IS_LAST_ENTRY(s->first)) {
+		header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
+		EXT3_I(inode)->i_state |= EXT3_STATE_XATTR;
+	} else {
+		header->h_magic = cpu_to_le32(0);
+		EXT3_I(inode)->i_state &= ~EXT3_STATE_XATTR;
+	}
+	return 0;
+}
+
+/*
+ * ext3_xattr_set_handle()
+ *
+ * Create, replace or remove an extended attribute for this inode. Buffer
+ * is NULL to remove an existing extended attribute, and non-NULL to
+ * either replace an existing extended attribute, or create a new extended
+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
+ * specify that an extended attribute must exist and must not exist
+ * previous to the call, respectively.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+int
+ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+		      const char *name, const void *value, size_t value_len,
+		      int flags)
+{
+	struct ext3_xattr_info i = {
+		.name_index = name_index,
+		.name = name,
+		.value = value,
+		.value_len = value_len,
+
+	};
+	struct ext3_xattr_ibody_find is = {
+		.s = { .not_found = -ENODATA, },
+	};
+	struct ext3_xattr_block_find bs = {
+		.s = { .not_found = -ENODATA, },
+	};
+	int error;
+
+	if (IS_RDONLY(inode))
+		return -EROFS;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+	if (!name)
+		return -EINVAL;
+	if (strlen(name) > 255)
+		return -ERANGE;
+	down_write(&EXT3_I(inode)->xattr_sem);
+	error = ext3_get_inode_loc(inode, &is.iloc);
+	if (error)
+		goto cleanup;
+	error = ext3_xattr_ibody_find(inode, &i, &is);
+	if (error)
+		goto cleanup;
+	if (is.s.not_found)
+		error = ext3_xattr_block_find(inode, &i, &bs);
+	if (error)
+		goto cleanup;
+	if (is.s.not_found && bs.s.not_found) {
+		error = -ENODATA;
+		if (flags & XATTR_REPLACE)
 			goto cleanup;
-		lock_buffer(old_bh);
-		if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) {
-			/* Free the old block. */
-			ea_bdebug(old_bh, "freeing");
-			ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1);
-
-			/* ext3_forget() calls bforget() for us, but we
-			   let our caller release old_bh, so we need to
-			   duplicate the handle before. */
-			get_bh(old_bh);
-			ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
-		} else {
-			/* Decrement the refcount only. */
-			HDR(old_bh)->h_refcount = cpu_to_le32(
-				le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
-			DQUOT_FREE_BLOCK(inode, 1);
-			ext3_journal_dirty_metadata(handle, old_bh);
-			ea_bdebug(old_bh, "refcount now=%d",
-				le32_to_cpu(HDR(old_bh)->h_refcount));
+		error = 0;
+		if (!value)
+			goto cleanup;
+	} else {
+		error = -EEXIST;
+		if (flags & XATTR_CREATE)
+			goto cleanup;
+	}
+	error = ext3_journal_get_write_access(handle, is.iloc.bh);
+	if (error)
+		goto cleanup;
+	if (!value) {
+		if (!is.s.not_found)
+			error = ext3_xattr_ibody_set(handle, inode, &i, &is);
+		else if (!bs.s.not_found)
+			error = ext3_xattr_block_set(handle, inode, &i, &bs);
+	} else {
+		error = ext3_xattr_ibody_set(handle, inode, &i, &is);
+		if (!error && !bs.s.not_found) {
+			i.value = NULL;
+			error = ext3_xattr_block_set(handle, inode, &i, &bs);
+		} else if (error == -ENOSPC) {
+			error = ext3_xattr_block_set(handle, inode, &i, &bs);
+			if (error)
+				goto cleanup;
+			if (!is.s.not_found) {
+				i.value = NULL;
+				error = ext3_xattr_ibody_set(handle, inode, &i,
+							     &is);
+			}
 		}
-		unlock_buffer(old_bh);
+	}
+	if (!error) {
+		inode->i_ctime = CURRENT_TIME_SEC;
+		error = ext3_mark_iloc_dirty(handle, inode, &is.iloc);
+		/*
+		 * The bh is consumed by ext3_mark_iloc_dirty, even with
+		 * error != 0.
+		 */
+		is.iloc.bh = NULL;
+		if (IS_SYNC(inode))
+			handle->h_sync = 1;
 	}
 
 cleanup:
-	brelse(new_bh);
-
+	brelse(is.iloc.bh);
+	brelse(bs.bh);
+	up_write(&EXT3_I(inode)->xattr_sem);
 	return error;
 }
 
@@ -1367,7 +1058,8 @@
  * ext3_xattr_delete_inode()
  *
  * Free extended attribute resources associated with this inode. This
- * is called immediately before an inode is freed.
+ * is called immediately before an inode is freed. We have exclusive
+ * access to the inode.
  */
 void
 ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
@@ -1379,36 +1071,19 @@
 		goto cleanup;
 	bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl);
 	if (!bh) {
-		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
+		ext3_error(inode->i_sb, __FUNCTION__,
 			"inode %ld: block %d read error", inode->i_ino,
 			EXT3_I(inode)->i_file_acl);
 		goto cleanup;
 	}
-	if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
-	    HDR(bh)->h_blocks != cpu_to_le32(1)) {
-		ext3_error(inode->i_sb, "ext3_xattr_delete_inode",
+	if (BHDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) ||
+	    BHDR(bh)->h_blocks != cpu_to_le32(1)) {
+		ext3_error(inode->i_sb, __FUNCTION__,
 			"inode %ld: bad block %d", inode->i_ino,
 			EXT3_I(inode)->i_file_acl);
 		goto cleanup;
 	}
-	if (ext3_journal_get_write_access(handle, bh) != 0)
-		goto cleanup;
-	lock_buffer(bh);
-	if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
-		ext3_xattr_cache_remove(bh);
-		ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1);
-		get_bh(bh);
-		ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl);
-	} else {
-		HDR(bh)->h_refcount = cpu_to_le32(
-			le32_to_cpu(HDR(bh)->h_refcount) - 1);
-		ext3_journal_dirty_metadata(handle, bh);
-		if (IS_SYNC(inode))
-			handle->h_sync = 1;
-		DQUOT_FREE_BLOCK(inode, 1);
-	}
-	ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
-	unlock_buffer(bh);
+	ext3_xattr_release_block(handle, inode, bh);
 	EXT3_I(inode)->i_file_acl = 0;
 
 cleanup:
@@ -1435,30 +1110,29 @@
  *
  * Returns 0, or a negative error number on failure.
  */
-static int
+static void
 ext3_xattr_cache_insert(struct buffer_head *bh)
 {
-	__u32 hash = le32_to_cpu(HDR(bh)->h_hash);
+	__u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
 	struct mb_cache_entry *ce;
 	int error;
 
 	ce = mb_cache_entry_alloc(ext3_xattr_cache);
-	if (!ce)
-		return -ENOMEM;
+	if (!ce) {
+		ea_bdebug(bh, "out of memory");
+		return;
+	}
 	error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash);
 	if (error) {
 		mb_cache_entry_free(ce);
 		if (error == -EBUSY) {
-			ea_bdebug(bh, "already in cache (%d cache entries)",
-				atomic_read(&ext3_xattr_cache->c_entry_count));
+			ea_bdebug(bh, "already in cache");
 			error = 0;
 		}
 	} else {
-		ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash,
-			  atomic_read(&ext3_xattr_cache->c_entry_count));
+		ea_bdebug(bh, "inserting [%x]", (int)hash);
 		mb_cache_entry_release(ce);
 	}
-	return error;
 }
 
 /*
@@ -1509,8 +1183,8 @@
  * not found or an error occurred.
  */
 static struct buffer_head *
-ext3_xattr_cache_find(handle_t *handle, struct inode *inode,
-		      struct ext3_xattr_header *header, int *credits)
+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header,
+		      struct mb_cache_entry **pce)
 {
 	__u32 hash = le32_to_cpu(header->h_hash);
 	struct mb_cache_entry *ce;
@@ -1518,62 +1192,38 @@
 	if (!header->h_hash)
 		return NULL;  /* never share */
 	ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
+again:
 	ce = mb_cache_entry_find_first(ext3_xattr_cache, 0,
 				       inode->i_sb->s_bdev, hash);
 	while (ce) {
-		struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block);
+		struct buffer_head *bh;
 
+		if (IS_ERR(ce)) {
+			if (PTR_ERR(ce) == -EAGAIN)
+				goto again;
+			break;
+		}
+		bh = sb_bread(inode->i_sb, ce->e_block);
 		if (!bh) {
-			ext3_error(inode->i_sb, "ext3_xattr_cache_find",
+			ext3_error(inode->i_sb, __FUNCTION__,
 				"inode %ld: block %ld read error",
 				inode->i_ino, (unsigned long) ce->e_block);
-		} else if (ext3_journal_get_write_access_credits(
-				handle, bh, credits) == 0) {
-			/* ext3_journal_get_write_access() requires an unlocked
-			 * bh, which complicates things here. */
-			lock_buffer(bh);
-			if (le32_to_cpu(HDR(bh)->h_refcount) >
-				   EXT3_XATTR_REFCOUNT_MAX) {
-				ea_idebug(inode, "block %ld refcount %d>%d",
-					  (unsigned long) ce->e_block,
-					  le32_to_cpu(HDR(bh)->h_refcount),
+		} else if (le32_to_cpu(BHDR(bh)->h_refcount) >=
+				EXT3_XATTR_REFCOUNT_MAX) {
+			ea_idebug(inode, "block %ld refcount %d>=%d",
+				  (unsigned long) ce->e_block,
+				  le32_to_cpu(BHDR(bh)->h_refcount),
 					  EXT3_XATTR_REFCOUNT_MAX);
-			} else if (!ext3_xattr_cmp(header, HDR(bh))) {
-				mb_cache_entry_release(ce);
-				/* buffer will be unlocked by caller */
-				return bh;
-			}
-			unlock_buffer(bh);
-			journal_release_buffer(handle, bh, *credits);
-			*credits = 0;
-			brelse(bh);
+		} else if (ext3_xattr_cmp(header, BHDR(bh)) == 0) {
+			*pce = ce;
+			return bh;
 		}
+		brelse(bh);
 		ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash);
 	}
 	return NULL;
 }
 
-/*
- * ext3_xattr_cache_remove()
- *
- * Remove the cache entry of a block from the cache. Called when a
- * block becomes invalid.
- */
-static void
-ext3_xattr_cache_remove(struct buffer_head *bh)
-{
-	struct mb_cache_entry *ce;
-
-	ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev,
-				bh->b_blocknr);
-	if (ce) {
-		ea_bdebug(bh, "removing (%d cache entries remaining)",
-			  atomic_read(&ext3_xattr_cache->c_entry_count)-1);
-		mb_cache_entry_free(ce);
-	} else 
-		ea_bdebug(bh, "no cache entry");
-}
-
 #define NAME_HASH_SHIFT 5
 #define VALUE_HASH_SHIFT 16
 
@@ -1647,7 +1297,7 @@
 {
 	ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL,
 		sizeof(struct mb_cache_entry) +
-		sizeof(struct mb_cache_entry_index), 1, 6);
+		sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6);
 	if (!ext3_xattr_cache)
 		return -ENOMEM;
 	return 0;
diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h
--- a/fs/ext3/xattr.h	2005-01-19 13:44:47 -08:00
+++ b/fs/ext3/xattr.h	2005-01-19 13:44:47 -08:00
@@ -16,7 +16,6 @@
 #define EXT3_XATTR_REFCOUNT_MAX		1024
 
 /* Name indexes */
-#define EXT3_XATTR_INDEX_MAX			10
 #define EXT3_XATTR_INDEX_USER			1
 #define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS	2
 #define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT	3
@@ -32,6 +31,10 @@
 	__u32	h_reserved[4];	/* zero right now */
 };
 
+struct ext3_xattr_ibody_header {
+	__le32	h_magic;	/* magic number for identification */
+};
+
 struct ext3_xattr_entry {
 	__u8	e_name_len;	/* length of name */
 	__u8	e_name_index;	/* attribute name index */
@@ -65,8 +68,9 @@
 extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
 
 extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
+extern int ext3_xattr_list(struct inode *, char *, size_t);
 extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
-extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *,const void *,size_t,int);
+extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
 
 extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
 extern void ext3_xattr_put_super(struct super_block *);
@@ -81,6 +85,12 @@
 static inline int
 ext3_xattr_get(struct inode *inode, int name_index, const char *name,
 	       void *buffer, size_t size, int flags)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
 {
 	return -EOPNOTSUPP;
 }
diff -Nru a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
--- a/fs/hostfs/hostfs_kern.c	2005-01-19 13:44:46 -08:00
+++ b/fs/hostfs/hostfs_kern.c	2005-01-19 13:44:46 -08:00
@@ -15,7 +15,6 @@
 #include <linux/pagemap.h>
 #include <linux/blkdev.h>
 #include <linux/list.h>
-#include <linux/buffer_head.h>
 #include <linux/root_dev.h>
 #include <linux/statfs.h>
 #include <linux/kdev_t.h>
diff -Nru a/fs/ioctl.c b/fs/ioctl.c
--- a/fs/ioctl.c	2005-01-19 13:44:46 -08:00
+++ b/fs/ioctl.c	2005-01-19 13:44:46 -08:00
@@ -16,7 +16,32 @@
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
-static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
+static long do_ioctl(struct file *filp, unsigned int cmd,
+		unsigned long arg)
+{
+	int error = -ENOTTY;
+
+	if (!filp->f_op)
+		goto out;
+
+	if (filp->f_op->unlocked_ioctl) {
+		error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
+		if (error == -ENOIOCTLCMD)
+			error = -EINVAL;
+		goto out;
+	} else if (filp->f_op->ioctl) {
+		lock_kernel();
+		error = filp->f_op->ioctl(filp->f_dentry->d_inode,
+					  filp, cmd, arg);
+		unlock_kernel();
+	}
+
+ out:
+	return error;
+}
+
+static int file_ioctl(struct file *filp, unsigned int cmd,
+		unsigned long arg)
 {
 	int error;
 	int block;
@@ -36,7 +61,9 @@
 			if ((error = get_user(block, p)) != 0)
 				return error;
 
+			lock_kernel();
 			res = mapping->a_ops->bmap(mapping, block);
+			unlock_kernel();
 			return put_user(res, p);
 		}
 		case FIGETBSZ:
@@ -46,29 +73,26 @@
 		case FIONREAD:
 			return put_user(i_size_read(inode) - filp->f_pos, p);
 	}
-	if (filp->f_op && filp->f_op->ioctl)
-		return filp->f_op->ioctl(inode, filp, cmd, arg);
-	return -ENOTTY;
+
+	return do_ioctl(filp, cmd, arg);
 }
 
 
 asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{	
+{
 	struct file * filp;
 	unsigned int flag;
 	int on, error = -EBADF;
+	int fput_needed;
 
-	filp = fget(fd);
+	filp = fget_light(fd, &fput_needed);
 	if (!filp)
 		goto out;
 
 	error = security_file_ioctl(filp, cmd, arg);
-	if (error) {
-                fput(filp);
-                goto out;
-        }
+	if (error)
+		goto out_fput;
 
-	lock_kernel();
 	switch (cmd) {
 		case FIOCLEX:
 			set_close_on_exec(fd, 1);
@@ -100,8 +124,11 @@
 
 			/* Did FASYNC state change ? */
 			if ((flag ^ filp->f_flags) & FASYNC) {
-				if (filp->f_op && filp->f_op->fasync)
+				if (filp->f_op && filp->f_op->fasync) {
+					lock_kernel();
 					error = filp->f_op->fasync(fd, filp, on);
+					unlock_kernel();
+				}
 				else error = -ENOTTY;
 			}
 			if (error != 0)
@@ -124,16 +151,15 @@
 				error = -ENOTTY;
 			break;
 		default:
-			error = -ENOTTY;
 			if (S_ISREG(filp->f_dentry->d_inode->i_mode))
 				error = file_ioctl(filp, cmd, arg);
-			else if (filp->f_op && filp->f_op->ioctl)
-				error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+			else
+				error = do_ioctl(filp, cmd, arg);
+			break;
 	}
-	unlock_kernel();
-	fput(filp);
-
-out:
+ out_fput:
+	fput_light(filp, fput_needed);
+ out:
 	return error;
 }
 
diff -Nru a/fs/jffs2/background.c b/fs/jffs2/background.c
--- a/fs/jffs2/background.c	2005-01-19 13:44:45 -08:00
+++ b/fs/jffs2/background.c	2005-01-19 13:44:45 -08:00
@@ -15,7 +15,6 @@
 #include <linux/jffs2.h>
 #include <linux/mtd/mtd.h>
 #include <linux/completion.h>
-#include <linux/suspend.h>
 #include "nodelist.h"
 
 
@@ -93,12 +92,8 @@
 			schedule();
 		}
 
-		if (current->flags & PF_FREEZE) {
-			refrigerator(0);
-			/* refrigerator() should recalc sigpending for us
-			   but doesn't. No matter - allow_signal() will. */
+		if (try_to_freeze(0))
 			continue;
-		}
 
 		cond_resched();
 
diff -Nru a/fs/mbcache.c b/fs/mbcache.c
--- a/fs/mbcache.c	2005-01-19 13:44:48 -08:00
+++ b/fs/mbcache.c	2005-01-19 13:44:48 -08:00
@@ -54,6 +54,10 @@
 		printk(KERN_ERR f); \
 		printk("\n"); \
 	} while(0)
+
+#define MB_CACHE_WRITER ((unsigned short)~0U >> 1)
+
+DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue);
 		
 MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
 MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
@@ -72,6 +76,20 @@
 EXPORT_SYMBOL(mb_cache_entry_find_next);
 #endif
 
+struct mb_cache {
+	struct list_head		c_cache_list;
+	const char			*c_name;
+	struct mb_cache_op		c_op;
+	atomic_t			c_entry_count;
+	int				c_bucket_bits;
+#ifndef MB_CACHE_INDEXES_COUNT
+	int				c_indexes_count;
+#endif
+	kmem_cache_t			*c_entry_cache;
+	struct list_head		*c_block_hash;
+	struct list_head		*c_indexes_hash[0];
+};
+
 
 /*
  * Global data: list of all mbcache's, lru list, and a spinlock for
@@ -126,7 +144,7 @@
 {
 	struct mb_cache *cache = ce->e_cache;
 
-	mb_assert(atomic_read(&ce->e_used) == 0);
+	mb_assert(!(ce->e_used || ce->e_queued));
 	if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) {
 		/* free failed -- put back on the lru list
 		   for freeing later. */
@@ -143,9 +161,16 @@
 static inline void
 __mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
 {
-	if (atomic_dec_and_test(&ce->e_used)) {
+	/* Wake up all processes queuing for this cache entry. */
+	if (ce->e_queued)
+		wake_up_all(&mb_cache_queue);
+	if (ce->e_used >= MB_CACHE_WRITER)
+		ce->e_used -= MB_CACHE_WRITER;
+	ce->e_used--;
+	if (!(ce->e_used || ce->e_queued)) {
 		if (!__mb_cache_entry_is_hashed(ce))
 			goto forget;
+		mb_assert(list_empty(&ce->e_lru_list));
 		list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
 	}
 	spin_unlock(&mb_cache_spinlock);
@@ -229,7 +254,7 @@
 	struct mb_cache *cache = NULL;
 
 	if(entry_size < sizeof(struct mb_cache_entry) +
-	   indexes_count * sizeof(struct mb_cache_entry_index))
+	   indexes_count * sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]))
 		return NULL;
 
 	cache = kmalloc(sizeof(struct mb_cache) +
@@ -382,7 +407,8 @@
 		INIT_LIST_HEAD(&ce->e_lru_list);
 		INIT_LIST_HEAD(&ce->e_block_list);
 		ce->e_cache = cache;
-		atomic_set(&ce->e_used, 1);
+		ce->e_used = 1 + MB_CACHE_WRITER;
+		ce->e_queued = 0;
 	}
 	return ce;
 }
@@ -474,7 +500,8 @@
  *
  * Get a cache entry  by device / block number. (There can only be one entry
  * in the cache per device and block.) Returns NULL if no such cache entry
- * exists.
+ * exists. The returned cache entry is locked for exclusive access ("single
+ * writer").
  */
 struct mb_cache_entry *
 mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev,
@@ -490,9 +517,27 @@
 	list_for_each(l, &cache->c_block_hash[bucket]) {
 		ce = list_entry(l, struct mb_cache_entry, e_block_list);
 		if (ce->e_bdev == bdev && ce->e_block == block) {
+			DEFINE_WAIT(wait);
+
 			if (!list_empty(&ce->e_lru_list))
 				list_del_init(&ce->e_lru_list);
-			atomic_inc(&ce->e_used);
+
+			while (ce->e_used > 0) {
+				ce->e_queued++;
+				prepare_to_wait(&mb_cache_queue, &wait,
+						TASK_UNINTERRUPTIBLE);
+				spin_unlock(&mb_cache_spinlock);
+				schedule();
+				spin_lock(&mb_cache_spinlock);
+				ce->e_queued--;
+			}
+			finish_wait(&mb_cache_queue, &wait);
+			ce->e_used += 1 + MB_CACHE_WRITER;
+
+			if (!__mb_cache_entry_is_hashed(ce)) {
+				__mb_cache_entry_release_unlock(ce);
+				return NULL;
+			}
 			goto cleanup;
 		}
 	}
@@ -509,14 +554,37 @@
 __mb_cache_entry_find(struct list_head *l, struct list_head *head,
 		      int index, struct block_device *bdev, unsigned int key)
 {
+	DEFINE_WAIT(wait);
+
 	while (l != head) {
 		struct mb_cache_entry *ce =
 			list_entry(l, struct mb_cache_entry,
 			           e_indexes[index].o_list);
 		if (ce->e_bdev == bdev && ce->e_indexes[index].o_key == key) {
+			DEFINE_WAIT(wait);
+
 			if (!list_empty(&ce->e_lru_list))
 				list_del_init(&ce->e_lru_list);
-			atomic_inc(&ce->e_used);
+
+			/* Incrementing before holding the lock gives readers
+			   priority over writers. */
+			ce->e_used++;
+			while (ce->e_used >= MB_CACHE_WRITER) {
+				ce->e_queued++;
+				prepare_to_wait(&mb_cache_queue, &wait,
+						TASK_UNINTERRUPTIBLE);
+				spin_unlock(&mb_cache_spinlock);
+				schedule();
+				spin_lock(&mb_cache_spinlock);
+				ce->e_queued--;
+			}
+			finish_wait(&mb_cache_queue, &wait);
+
+			if (!__mb_cache_entry_is_hashed(ce)) {
+				__mb_cache_entry_release_unlock(ce);
+				spin_lock(&mb_cache_spinlock);
+				return ERR_PTR(-EAGAIN);
+			}
 			return ce;
 		}
 		l = l->next;
@@ -530,7 +598,8 @@
  *
  * Find the first cache entry on a given device with a certain key in
  * an additional index. Additonal matches can be found with
- * mb_cache_entry_find_next(). Returns NULL if no match was found.
+ * mb_cache_entry_find_next(). Returns NULL if no match was found. The
+ * returned cache entry is locked for shared access ("multiple readers").
  *
  * @cache: the cache to search
  * @index: the number of the additonal index to search (0<=index<indexes_count)
diff -Nru a/fs/nfs/file.c b/fs/nfs/file.c
--- a/fs/nfs/file.c	2005-01-19 13:44:47 -08:00
+++ b/fs/nfs/file.c	2005-01-19 13:44:47 -08:00
@@ -339,6 +339,7 @@
 		status = NFS_PROTO(inode)->lock(filp, cmd, fl);
 	else
 		status = posix_lock_file_wait(filp, fl);
+	unlock_kernel();
 	rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset);
 	return status;
 }
@@ -346,8 +347,10 @@
 static int do_setlk(struct file *filp, int cmd, struct file_lock *fl)
 {
 	struct inode *inode = filp->f_mapping->host;
+	sigset_t oldset;
 	int status;
 
+	rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset);
 	/*
 	 * Flush all pending writes before doing anything
 	 * with locks..
@@ -361,7 +364,7 @@
 			status = filemap_fdatawait(filp->f_mapping);
 	}
 	if (status < 0)
-		return status;
+		goto out;
 
 	lock_kernel();
 	/* Use local locking if mounted with "-onolock" */
@@ -374,12 +377,12 @@
 		 * the process exits.
 		 */
 		if (status == -EINTR || status == -ERESTARTSYS)
-			posix_lock_file(filp, fl);
+			posix_lock_file_wait(filp, fl);
 	} else
 		status = posix_lock_file_wait(filp, fl);
 	unlock_kernel();
 	if (status < 0)
-		return status;
+		goto out;
 	/*
 	 * Make sure we clear the cache whenever we try to get the lock.
 	 * This makes locking act as a cache coherency point.
@@ -390,7 +393,9 @@
 	up(&inode->i_sem);
 	filemap_fdatawait(filp->f_mapping);
 	nfs_zap_caches(inode);
-	return 0;
+out:
+	rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset);
+	return status;
 }
 
 /*
diff -Nru a/fs/partitions/ibm.c b/fs/partitions/ibm.c
--- a/fs/partitions/ibm.c	2005-01-19 13:44:48 -08:00
+++ b/fs/partitions/ibm.c	2005-01-19 13:44:48 -08:00
@@ -114,7 +114,8 @@
 		}
 		put_partition(state, 1, offset*(blocksize >> 9),
 				 size-offset*(blocksize >> 9));
-	} else if (strncmp(type, "VOL1", 4) == 0) {
+	} else if ((strncmp(type, "VOL1", 4) == 0) &&
+		(!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) {
 		/*
 		 * New style VOL1 labeled disk
 		 */
diff -Nru a/fs/pipe.c b/fs/pipe.c
--- a/fs/pipe.c	2005-01-19 13:44:46 -08:00
+++ b/fs/pipe.c	2005-01-19 13:44:46 -08:00
@@ -86,7 +86,7 @@
 	return 0;
 }
 
-static void release_pipe_buf(struct pipe_inode_info *info, struct pipe_buffer *buf)
+static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buffer *buf)
 {
 	struct page *page = buf->page;
 
@@ -97,6 +97,23 @@
 	info->tmp_page = page;
 }
 
+static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *info, struct pipe_buffer *buf)
+{
+	return kmap(buf->page);
+}
+
+static void anon_pipe_buf_unmap(struct pipe_inode_info *info, struct pipe_buffer *buf)
+{
+	kunmap(buf->page);
+}
+
+static struct pipe_buf_operations anon_pipe_buf_ops = {
+	.can_merge = 1,
+	.map = anon_pipe_buf_map,
+	.unmap = anon_pipe_buf_unmap,
+	.release = anon_pipe_buf_release,
+};
+
 static ssize_t
 pipe_readv(struct file *filp, const struct iovec *_iov,
 	   unsigned long nr_segs, loff_t *ppos)
@@ -122,14 +139,17 @@
 		if (bufs) {
 			int curbuf = info->curbuf;
 			struct pipe_buffer *buf = info->bufs + curbuf;
+			struct pipe_buf_operations *ops = buf->ops;
+			void *addr;
 			size_t chars = buf->len;
 			int error;
 
 			if (chars > total_len)
 				chars = total_len;
 
-			error = pipe_iov_copy_to_user(iov, kmap(buf->page) + buf->offset, chars);
-			kunmap(buf->page);
+			addr = ops->map(filp, info, buf);
+			error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
+			ops->unmap(info, buf);
 			if (unlikely(error)) {
 				if (!ret) ret = -EFAULT;
 				break;
@@ -138,8 +158,8 @@
 			buf->offset += chars;
 			buf->len -= chars;
 			if (!buf->len) {
-				release_pipe_buf(info, buf);
-				buf->page = NULL;
+				buf->ops = NULL;
+				ops->release(info, buf);
 				curbuf = (curbuf + 1) & (PIPE_BUFFERS-1);
 				info->curbuf = curbuf;
 				info->nrbufs = --bufs;
@@ -219,11 +239,12 @@
 	if (info->nrbufs && total_len < PAGE_SIZE) {
 		int lastbuf = (info->curbuf + info->nrbufs - 1) & (PIPE_BUFFERS-1);
 		struct pipe_buffer *buf = info->bufs + lastbuf;
+		struct pipe_buf_operations *ops = buf->ops;
 		int offset = buf->offset + buf->len;
-		if (offset + total_len <= PAGE_SIZE) {
-			struct page *page = buf->page;
-			int error = pipe_iov_copy_from_user(offset + kmap(page), iov, total_len);
-			kunmap(page);
+		if (ops->can_merge && offset + total_len <= PAGE_SIZE) {
+			void *addr = ops->map(filp, info, buf);
+			int error = pipe_iov_copy_from_user(offset + addr, iov, total_len);
+			ops->unmap(info, buf);
 			ret = error;
 			do_wakeup = 1;
 			if (error)
@@ -251,7 +272,7 @@
 			int error;
 
 			if (!page) {
-				page = alloc_page(GFP_KERNEL);
+				page = alloc_page(GFP_HIGHUSER);
 				if (unlikely(!page)) {
 					ret = ret ? : -ENOMEM;
 					break;
@@ -278,6 +299,7 @@
 
 			/* Insert it into the buffer array */
 			buf->page = page;
+			buf->ops = &anon_pipe_buf_ops;
 			buf->offset = 0;
 			buf->len = chars;
 			info->nrbufs = ++bufs;
@@ -612,8 +634,8 @@
 		__free_page(info->tmp_page);
 	for (i = 0; i < PIPE_BUFFERS; i++) {
 		struct pipe_buffer *buf = info->bufs + i;
-		if (buf->page)
-			release_pipe_buf(info, buf);
+		if (buf->ops)
+			buf->ops->release(info, buf);
 	}
 	kfree(info);
 }
diff -Nru a/fs/readdir.c b/fs/readdir.c
--- a/fs/readdir.c	2005-01-19 13:44:46 -08:00
+++ b/fs/readdir.c	2005-01-19 13:44:46 -08:00
@@ -287,9 +287,10 @@
 	lastdirent = buf.previous;
 	if (lastdirent) {
 		typeof(lastdirent->d_off) d_off = file->f_pos;
-		error = count - buf.count;
+		error = -EFAULT;
 		if (__put_user(d_off, &lastdirent->d_off))
-			error = -EFAULT;
+			goto out_putf;
+		error = count - buf.count;
 	}
 
 out_putf:
diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
--- a/fs/reiserfs/journal.c	2005-01-19 13:44:47 -08:00
+++ b/fs/reiserfs/journal.c	2005-01-19 13:44:47 -08:00
@@ -50,7 +50,6 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/smp_lock.h>
-#include <linux/suspend.h>
 #include <linux/buffer_head.h>
 #include <linux/workqueue.h>
 #include <linux/writeback.h>
diff -Nru a/fs/smbfs/proc.c b/fs/smbfs/proc.c
--- a/fs/smbfs/proc.c	2005-01-19 13:44:46 -08:00
+++ b/fs/smbfs/proc.c	2005-01-19 13:44:46 -08:00
@@ -1427,9 +1427,9 @@
 	 * So we must first calculate the amount of padding used by the server.
 	 */
 	data_off -= hdrlen;
-	if (data_off > SMB_READX_MAX_PAD) {
-		PARANOIA("offset is larger than max pad!\n");
-		PARANOIA("%d > %d\n", data_off, SMB_READX_MAX_PAD);
+	if (data_off > SMB_READX_MAX_PAD || data_off < 0) {
+		PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n");
+		PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off);
 		req->rq_rlen = req->rq_bufsize + 1;
 		return;
 	}
diff -Nru a/fs/smbfs/request.c b/fs/smbfs/request.c
--- a/fs/smbfs/request.c	2005-01-19 13:44:48 -08:00
+++ b/fs/smbfs/request.c	2005-01-19 13:44:48 -08:00
@@ -590,8 +590,18 @@
 	data_count  = WVAL(inbuf, smb_drcnt);
 
 	/* Modify offset for the split header/buffer we use */
-	data_offset -= hdrlen;
-	parm_offset -= hdrlen;
+	if (data_count || data_offset) {
+		if (unlikely(data_offset < hdrlen))
+			goto out_bad_data;
+		else
+			data_offset -= hdrlen;
+	}
+	if (parm_count || parm_offset) {
+		if (unlikely(parm_offset < hdrlen))
+			goto out_bad_parm;
+		else
+			parm_offset -= hdrlen;
+	}
 
 	if (parm_count == parm_tot && data_count == data_tot) {
 		/*
@@ -602,18 +612,22 @@
 		 * response that fits.
 		 */
 		VERBOSE("single trans2 response  "
-			"dcnt=%d, pcnt=%d, doff=%d, poff=%d\n",
+			"dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
 			data_count, parm_count,
 			data_offset, parm_offset);
 		req->rq_ldata = data_count;
 		req->rq_lparm = parm_count;
 		req->rq_data = req->rq_buffer + data_offset;
 		req->rq_parm = req->rq_buffer + parm_offset;
+		if (unlikely(parm_offset + parm_count > req->rq_rlen))
+			goto out_bad_parm;
+		if (unlikely(data_offset + data_count > req->rq_rlen))
+			goto out_bad_data;
 		return 0;
 	}
 
 	VERBOSE("multi trans2 response  "
-		"frag=%d, dcnt=%d, pcnt=%d, doff=%d, poff=%d\n",
+		"frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
 		req->rq_fragment,
 		data_count, parm_count,
 		data_offset, parm_offset);
@@ -640,13 +654,15 @@
 
 		req->rq_parm = req->rq_trans2buffer;
 		req->rq_data = req->rq_trans2buffer + parm_tot;
-	} else if (req->rq_total_data < data_tot ||
-		   req->rq_total_parm < parm_tot)
+	} else if (unlikely(req->rq_total_data < data_tot ||
+			    req->rq_total_parm < parm_tot))
 		goto out_data_grew;
 
-	if (parm_disp + parm_count > req->rq_total_parm)
+	if (unlikely(parm_disp + parm_count > req->rq_total_parm ||
+		     parm_offset + parm_count > req->rq_rlen))
 		goto out_bad_parm;
-	if (data_disp + data_count > req->rq_total_data)
+	if (unlikely(data_disp + data_count > req->rq_total_data ||
+		     data_offset + data_count > req->rq_rlen))
 		goto out_bad_data;
 
 	inbuf = req->rq_buffer;
@@ -668,10 +684,9 @@
 	return 1;
 
 out_too_long:
-	printk(KERN_ERR "smb_trans2: data/param too long, data=%d, parm=%d\n",
+	printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n",
 		data_tot, parm_tot);
-	req->rq_errno = -EIO;
-	goto out;
+	goto out_EIO;
 out_no_mem:
 	printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n",
 	       req->rq_trans2bufsize);
@@ -679,16 +694,15 @@
 	goto out;
 out_data_grew:
 	printk(KERN_ERR "smb_trans2: data/params grew!\n");
-	req->rq_errno = -EIO;
-	goto out;
+	goto out_EIO;
 out_bad_parm:
-	printk(KERN_ERR "smb_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
-	       parm_disp, parm_count, parm_tot);
-	req->rq_errno = -EIO;
-	goto out;
+	printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
+	       parm_disp, parm_count, parm_tot, parm_offset);
+	goto out_EIO;
 out_bad_data:
-	printk(KERN_ERR "smb_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
-	       data_disp, data_count, data_tot);
+	printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
+	       data_disp, data_count, data_tot, data_offset);
+out_EIO:
 	req->rq_errno = -EIO;
 out:
 	return req->rq_errno;
diff -Nru a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
--- a/fs/xfs/linux-2.6/xfs_buf.c	2005-01-19 13:44:45 -08:00
+++ b/fs/xfs/linux-2.6/xfs_buf.c	2005-01-19 13:44:45 -08:00
@@ -51,7 +51,6 @@
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <linux/workqueue.h>
-#include <linux/suspend.h>
 #include <linux/percpu.h>
 #include <linux/blkdev.h>
 
@@ -1685,9 +1684,7 @@
 
 	INIT_LIST_HEAD(&tmp);
 	do {
-		/* swsusp */
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100);
diff -Nru a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
--- a/fs/xfs/linux-2.6/xfs_super.c	2005-01-19 13:44:47 -08:00
+++ b/fs/xfs/linux-2.6/xfs_super.c	2005-01-19 13:44:47 -08:00
@@ -71,7 +71,6 @@
 #include <linux/namei.h>
 #include <linux/init.h>
 #include <linux/mount.h>
-#include <linux/suspend.h>
 #include <linux/writeback.h>
 
 STATIC struct quotactl_ops linvfs_qops;
@@ -489,8 +488,7 @@
 		set_current_state(TASK_INTERRUPTIBLE);
 		timeleft = schedule_timeout(timeleft);
 		/* swsusp */
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 		if (vfsp->vfs_flag & VFS_UMOUNT)
 			break;
 
diff -Nru a/include/asm-alpha/io_trivial.h b/include/asm-alpha/io_trivial.h
--- a/include/asm-alpha/io_trivial.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-alpha/io_trivial.h	2005-01-19 13:44:46 -08:00
@@ -26,7 +26,7 @@
 __EXTERN_INLINE void
 IO_CONCAT(__IO_PREFIX,iowrite16)(u16 b, void __iomem *a)
 {
-	__kernel_stb(b, *(volatile u16 __force *)a);
+	__kernel_stw(b, *(volatile u16 __force *)a);
 }
 #endif
 
@@ -66,7 +66,7 @@
 __EXTERN_INLINE void
 IO_CONCAT(__IO_PREFIX,writew)(u16 b, volatile void __iomem *a)
 {
-	__kernel_stb(b, *(volatile u16 __force *)a);
+	__kernel_stw(b, *(volatile u16 __force *)a);
 }
 #elif IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 2
 __EXTERN_INLINE u8
diff -Nru a/include/asm-arm/arch-pxa/corgi.h b/include/asm-arm/arch-pxa/corgi.h
--- a/include/asm-arm/arch-pxa/corgi.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-arm/arch-pxa/corgi.h	2005-01-19 13:44:45 -08:00
@@ -15,29 +15,31 @@
 
 
 /*
- * Corgi GPIO definitions
+ * Corgi (Non Standard) GPIO Definitions
  */
-#define CORGI_GPIO_KEY_INT			(0)	/* key interrupt */
+#define CORGI_GPIO_KEY_INT			(0)	/* Keyboard Interrupt */
 #define CORGI_GPIO_AC_IN			(1)
 #define CORGI_GPIO_WAKEUP			(3)
-#define CORGI_GPIO_AK_INT			(4)	// Remote Controller
-#define CORGI_GPIO_TP_INT			(5)	/* Touch Panel interrupt */
-#define CORGI_GPIO_nSD_CLK			(6)
+#define CORGI_GPIO_AK_INT			(4)	/* IR Controller Interrupt */
+#define CORGI_GPIO_TP_INT			(5)	/* Touch Panel Interrupt */
 #define CORGI_GPIO_nSD_WP			(7)
-#define CORGI_GPIO_nSD_DETECT		(9)
+#define CORGI_GPIO_nSD_DETECT		(9) /* MMC/SD Card Detect */
 #define CORGI_GPIO_nSD_INT			(10)
 #define CORGI_GPIO_MAIN_BAT_LOW		(11)
 #define CORGI_GPIO_BAT_COVER		(11)
 #define CORGI_GPIO_LED_ORANGE		(13)
-#define CORGI_GPIO_CF_CD			(14)
+#define CORGI_GPIO_CF_CD			(14) /* Compact Flash Card Detect */
 #define CORGI_GPIO_CHRG_FULL		(16)
-#define CORGI_GPIO_CF_IRQ			(17)
+#define CORGI_GPIO_CF_IRQ			(17) /* Compact Flash Interrupt */
+#define CORGI_GPIO_LCDCON_CS		(19) /* LCD Control Chip Select */
+#define CORGI_GPIO_MAX1111_CS		(20) /* MAX111 Chip Select */
 #define CORGI_GPIO_ADC_TEMP_ON		(21)
 #define CORGI_GPIO_IR_ON			(22)
-#define CORGI_GPIO_SD_PWR			(33)
+#define CORGI_GPIO_ADS7846_CS		(24) /* ADS7846 Chip Select */
+#define CORGI_GPIO_SD_PWR			(33) /* MMC/SD Power */
 #define CORGI_GPIO_CHRG_ON			(38)
 #define CORGI_GPIO_DISCHARGE_ON		(42)
-#define CORGI_GPIO_HSYNC			(44)
+#define CORGI_GPIO_HSYNC			(44) /* LCD HSync Pulse */
 #define CORGI_GPIO_USB_PULLUP		(45)
 
 
diff -Nru a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
--- a/include/asm-arm/arch-pxa/pxa-regs.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-arm/arch-pxa/pxa-regs.h	2005-01-19 13:44:47 -08:00
@@ -1210,6 +1210,7 @@
 #define GPIO30_SDATA_OUT	30	/* AC97/I2S Sdata_out */
 #define GPIO31_SYNC		31	/* AC97/I2S sync */
 #define GPIO32_SDATA_IN1	32	/* AC97 Sdata_in1 */
+#define GPIO32_SYSCLK		32	/* I2S System Clock */
 #define GPIO32_MMCCLK		32	/* MMC Clock (PXA270) */
 #define GPIO33_nCS_5		33	/* chip select 5 */
 #define GPIO34_FFRXD		34	/* FFUART receive */
@@ -1327,14 +1328,16 @@
 #define GPIO26_SRXD_MD		(26 | GPIO_ALT_FN_1_IN)
 #define GPIO27_SEXTCLK_MD	(27 | GPIO_ALT_FN_1_IN)
 #define GPIO28_BITCLK_AC97_MD	(28 | GPIO_ALT_FN_1_IN)
-#define GPIO28_BITCLK_I2S_MD	(28 | GPIO_ALT_FN_2_IN)
+#define GPIO28_BITCLK_IN_I2S_MD	(28 | GPIO_ALT_FN_2_IN)
+#define GPIO28_BITCLK_OUT_I2S_MD	(28 | GPIO_ALT_FN_1_OUT)
 #define GPIO29_SDATA_IN_AC97_MD	(29 | GPIO_ALT_FN_1_IN)
 #define GPIO29_SDATA_IN_I2S_MD	(29 | GPIO_ALT_FN_2_IN)
 #define GPIO30_SDATA_OUT_AC97_MD	(30 | GPIO_ALT_FN_2_OUT)
 #define GPIO30_SDATA_OUT_I2S_MD	(30 | GPIO_ALT_FN_1_OUT)
-#define GPIO31_SYNC_AC97_MD	(31 | GPIO_ALT_FN_2_OUT)
 #define GPIO31_SYNC_I2S_MD	(31 | GPIO_ALT_FN_1_OUT)
+#define GPIO31_SYNC_AC97_MD	(31 | GPIO_ALT_FN_2_OUT)
 #define GPIO32_SDATA_IN1_AC97_MD	(32 | GPIO_ALT_FN_1_IN)
+#define GPIO32_SYSCLK_I2S_MD	(32 | GPIO_ALT_FN_1_OUT)
 #define GPIO32_MMCCLK_MD		( 32 | GPIO_ALT_FN_2_OUT)
 #define GPIO33_nCS_5_MD		(33 | GPIO_ALT_FN_2_OUT)
 #define GPIO34_FFRXD_MD		(34 | GPIO_ALT_FN_1_IN)
diff -Nru a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h
--- a/include/asm-arm/arch-s3c2410/dma.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-arm/arch-s3c2410/dma.h	2005-01-19 13:44:46 -08:00
@@ -285,6 +285,14 @@
 extern int s3c2410_dma_devconfig(int channel, s3c2410_dmasrc_t source,
 				 int hwcfg, unsigned long devaddr);
 
+/* s3c2410_dma_getposition
+ *
+ * get the position that the dma transfer is currently at
+*/
+
+extern int s3c2410_dma_getposition(dmach_t channel,
+				   dma_addr_t *src, dma_addr_t *dest);
+
 extern int s3c2410_dma_set_opfn(dmach_t, s3c2410_dma_opfn_t rtn);
 extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
 
diff -Nru a/include/asm-arm/arch-s3c2410/regs-iis.h b/include/asm-arm/arch-s3c2410/regs-iis.h
--- a/include/asm-arm/arch-s3c2410/regs-iis.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-arm/arch-s3c2410/regs-iis.h	2005-01-19 13:44:46 -08:00
@@ -18,7 +18,7 @@
 #ifndef __ASM_ARCH_REGS_IIS_H
 #define __ASM_ARCH_REGS_IIS_H
 
-#define S3C2410_IISCON	 (S3C2410_VA_IIS + 0x00)
+#define S3C2410_IISCON	 (0x00)
 
 #define S3C2410_IISCON_LRINDEX	  (1<<8)
 #define S3C2410_IISCON_TXFIFORDY  (1<<7)
@@ -29,7 +29,7 @@
 #define S3C2410_IISCON_RXIDLE	  (1<<2)
 #define S3C2410_IISCON_IISEN	  (1<<0)
 
-#define S3C2410_IISMOD	 (S3C2410_VA_IIS + 0x04)
+#define S3C2410_IISMOD	 (0x04)
 
 #define S3C2410_IISMOD_SLAVE	  (1<<8)
 #define S3C2410_IISMOD_NOXFER	  (0<<6)
@@ -48,16 +48,20 @@
 #define S3C2410_IISMOD_32FS	  (1<<0)
 #define S3C2410_IISMOD_48FS	  (2<<0)
 
-#define S3C2410_IISPSR	 (S3C2410_VA_IIS + 0x08)
+#define S3C2410_IISPSR		(0x08)
+#define S3C2410_IISPSR_INTMASK	(31<<5)
+#define S3C2410_IISPSR_INTSHFIT	(5)
+#define S3C2410_IISPSR_EXTMASK	(31<<0)
+#define S3C2410_IISPSR_EXTSHFIT	(0)
 
-#define S3C2410_IISFCON  (S3C2410_VA_IIS + 0x0c)
+#define S3C2410_IISFCON  (0x0c)
 
 #define S3C2410_IISFCON_TXDMA	  (1<<15)
 #define S3C2410_IISFCON_RXDMA	  (1<<14)
 #define S3C2410_IISFCON_TXENABLE  (1<<13)
 #define S3C2410_IISFCON_RXENABLE  (1<<12)
 
-#define S3C2410_IISFIFO  (S3C2410_VA_IIS + 0x10)
+#define S3C2410_IISFIFO  (0x10)
 
 #endif /* __ASM_ARCH_REGS_IIS_H */
 
diff -Nru a/include/asm-arm/arch-s3c2410/vr1000-map.h b/include/asm-arm/arch-s3c2410/vr1000-map.h
--- a/include/asm-arm/arch-s3c2410/vr1000-map.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-arm/arch-s3c2410/vr1000-map.h	2005-01-19 13:44:47 -08:00
@@ -1,6 +1,6 @@
 /* linux/include/asm-arm/arch-s3c2410/vr1000-map.h
  *
- * (c) 2003,2004 Simtec Electronics
+ * (c) 2003-2005 Simtec Electronics
  *  Ben Dooks <ben@simtec.co.uk>
  *
  * Machine VR1000 - Memory map definitions
@@ -13,6 +13,7 @@
  *  06-Jan-2003 BJD  Linux 2.6.0 version, split specifics from arch/map.h
  *  12-Mar-2004 BJD  Fixed header include protection
  *  19-Mar-2004 BJD  Copied to VR1000 machine headers.
+ *  19-Jan-2005 BJD  Updated map definitions
 */
 
 /* needs arch/map.h including with this */
@@ -94,7 +95,6 @@
 #define VR1000_VA_DM9000	   (VR1000_VA_MULTISPACE + 0x02500000)
 #define VR1000_VA_SUPERIO	   (VR1000_VA_MULTISPACE + 0x02600000)
 
-
 /* physical offset addresses for the peripherals */
 
 #define VR1000_PA_IDEPRI	   (0x02000000)
@@ -104,6 +104,10 @@
 #define VR1000_PA_DM9000	   (0x05000000)
 
 #define VR1000_PA_SERIAL	   (0x11800000)
+#define VR1000_VA_SERIAL	   (VR1000_IOADDR(0x00700000))
+
+/* VR1000 ram is in CS1, with A26..A24 = 2_101 */
+#define VR1000_PA_SRAM		   (S3C2410_CS1 | 0x05000000)
 
 /* some configurations for the peripherals */
 
diff -Nru a/include/asm-arm/cpu.h b/include/asm-arm/cpu.h
--- a/include/asm-arm/cpu.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-arm/cpu.h	2005-01-19 13:44:48 -08:00
@@ -17,7 +17,6 @@
 	struct cpu	cpu;
 #ifdef CONFIG_SMP
 	unsigned int	loops_per_jiffy;
-	unsigned long	ipi_count;
 #endif
 };
 
diff -Nru a/include/asm-arm/mach/irq.h b/include/asm-arm/mach/irq.h
--- a/include/asm-arm/mach/irq.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-arm/mach/irq.h	2005-01-19 13:44:46 -08:00
@@ -47,6 +47,13 @@
 	 * Set wakeup-enable on the selected IRQ
 	 */
 	int (*wake)(unsigned int, unsigned int);
+
+#ifdef CONFIG_SMP
+	/*
+	 * Route an interrupt to a CPU
+	 */
+	void (*set_cpu)(struct irqdesc *desc, unsigned int irq, unsigned int cpu);
+#endif
 };
 
 struct irqdesc {
@@ -66,6 +73,13 @@
 	unsigned int	valid    : 1;		/* IRQ claimable	      */
 	unsigned int	noautoenable : 1;	/* don't automatically enable IRQ */
 	unsigned int	unused   :25;
+
+	struct proc_dir_entry *procdir;
+
+#ifdef CONFIG_SMP
+	cpumask_t	affinity;
+	unsigned int	cpu;
+#endif
 
 	/*
 	 * IRQ lock detection
diff -Nru a/include/asm-arm/processor.h b/include/asm-arm/processor.h
--- a/include/asm-arm/processor.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-arm/processor.h	2005-01-19 13:44:48 -08:00
@@ -19,7 +19,6 @@
 
 #ifdef __KERNEL__
 
-#include <asm/atomic.h>
 #include <asm/ptrace.h>
 #include <asm/procinfo.h>
 #include <asm/types.h>
diff -Nru a/include/asm-arm/smp.h b/include/asm-arm/smp.h
--- a/include/asm-arm/smp.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-arm/smp.h	2005-01-19 13:44:48 -08:00
@@ -32,6 +32,13 @@
  */
 #define PROC_CHANGE_PENALTY		15
 
+struct seq_file;
+
+/*
+ * generate IPI list text
+ */
+extern void show_ipi_list(struct seq_file *p);
+
 /*
  * Move global data into per-processor storage.
  */
@@ -46,6 +53,6 @@
  * Boot a secondary CPU, and assign it the specified idle task.
  * This also gives us the initial stack to use for this CPU.
  */
-extern int __init boot_secondary(unsigned int cpu, struct task_struct *);
+extern int boot_secondary(unsigned int cpu, struct task_struct *);
 
 #endif /* ifndef __ASM_ARM_SMP_H */
diff -Nru a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h
--- a/include/asm-arm/tlb.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-arm/tlb.h	2005-01-19 13:44:45 -08:00
@@ -91,4 +91,6 @@
 #define pte_free_tlb(tlb,ptep)		pte_free(ptep)
 #define pmd_free_tlb(tlb,pmdp)		pmd_free(pmdp)
 
+#define tlb_migrate_finish(mm)		do { } while (0)
+
 #endif
diff -Nru a/include/asm-i386/checksum.h b/include/asm-i386/checksum.h
--- a/include/asm-i386/checksum.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-i386/checksum.h	2005-01-19 13:44:48 -08:00
@@ -25,8 +25,8 @@
  * better 64-bit) boundary
  */
 
-asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
-						   int *src_err_ptr, int *dst_err_ptr);
+asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned char *dst,
+						  int len, int sum, int *src_err_ptr, int *dst_err_ptr);
 
 /*
  *	Note: when you get a NULL pointer exception here this means someone
@@ -36,18 +36,18 @@
  *	verify_area().
  */
 static __inline__
-unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+unsigned int csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst,
 					int len, int sum)
 {
 	return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
 }
 
 static __inline__
-unsigned int csum_partial_copy_from_user(const char __user *src, char *dst,
+unsigned int csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst,
 						int len, int sum, int *err_ptr)
 {
 	might_sleep();
-	return csum_partial_copy_generic((__force char *)src, dst,
+	return csum_partial_copy_generic((__force unsigned char *)src, dst,
 					len, sum, err_ptr, NULL);
 }
 
@@ -174,14 +174,14 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user(const char *src, 
-						     char __user *dst,
+static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
+						     unsigned char __user *dst,
 						     int len, int sum, 
 						     int *err_ptr)
 {
 	might_sleep();
 	if (access_ok(VERIFY_WRITE, dst, len))
-		return csum_partial_copy_generic(src, (__force char *)dst, len, sum, NULL, err_ptr);
+		return csum_partial_copy_generic(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
 
 	if (len)
 		*err_ptr = -EFAULT;
diff -Nru a/include/asm-i386/desc.h b/include/asm-i386/desc.h
--- a/include/asm-i386/desc.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-i386/desc.h	2005-01-19 13:44:45 -08:00
@@ -126,6 +126,15 @@
 	put_cpu();
 }
 
+static inline unsigned long get_desc_base(unsigned long *desc)
+{
+	unsigned long base;
+	base = ((desc[0] >> 16)  & 0x0000ffff) |
+		((desc[1] << 16) & 0x00ff0000) |
+		(desc[1] & 0xff000000);
+	return base;
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif
diff -Nru a/include/asm-i386/param.h b/include/asm-i386/param.h
--- a/include/asm-i386/param.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-i386/param.h	2005-01-19 13:44:46 -08:00
@@ -18,6 +18,6 @@
 #endif
 
 #define MAXHOSTNAMELEN	64	/* max length of hostname */
-#define COMMAND_LINE_SIZE 256
+#define COMMAND_LINE_SIZE 2048
 
 #endif
diff -Nru a/include/asm-i386/setup.h b/include/asm-i386/setup.h
--- a/include/asm-i386/setup.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-i386/setup.h	2005-01-19 13:44:47 -08:00
@@ -17,7 +17,7 @@
 #define MAX_NONPAE_PFN	(1 << 20)
 
 #define PARAM_SIZE 2048
-#define COMMAND_LINE_SIZE 256
+#define COMMAND_LINE_SIZE 2048
 
 #define OLD_CL_MAGIC_ADDR	0x90020
 #define OLD_CL_MAGIC		0xA33F
diff -Nru a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
--- a/include/asm-ia64/machvec.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-ia64/machvec.h	2005-01-19 13:44:46 -08:00
@@ -20,6 +20,7 @@
 struct irq_desc;
 struct page;
 struct mm_struct;
+struct pci_bus;
 
 typedef void ia64_mv_setup_t (char **);
 typedef void ia64_mv_cpu_init_t (void);
@@ -31,6 +32,11 @@
 typedef struct irq_desc *ia64_mv_irq_desc (unsigned int);
 typedef u8 ia64_mv_irq_to_vector (unsigned int);
 typedef unsigned int ia64_mv_local_vector_to_irq (u8);
+typedef char *ia64_mv_pci_get_legacy_mem_t (struct pci_bus *);
+typedef int ia64_mv_pci_legacy_read_t (struct pci_bus *, u16 port, u32 *val,
+				       u8 size);
+typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val,
+					u8 size);
 
 /* DMA-mapping interface: */
 typedef void ia64_mv_dma_init (void);
@@ -94,6 +100,8 @@
 #  include <asm/machvec_dig.h>
 # elif defined (CONFIG_IA64_HP_ZX1)
 #  include <asm/machvec_hpzx1.h>
+# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
+#  include <asm/machvec_hpzx1_swiotlb.h>
 # elif defined (CONFIG_IA64_SGI_SN2)
 #  include <asm/machvec_sn2.h>
 # elif defined (CONFIG_IA64_GENERIC)
@@ -125,6 +133,9 @@
 #  define platform_irq_desc		ia64_mv.irq_desc
 #  define platform_irq_to_vector	ia64_mv.irq_to_vector
 #  define platform_local_vector_to_irq	ia64_mv.local_vector_to_irq
+#  define platform_pci_get_legacy_mem	ia64_mv.pci_get_legacy_mem
+#  define platform_pci_legacy_read	ia64_mv.pci_legacy_read
+#  define platform_pci_legacy_write	ia64_mv.pci_legacy_write
 #  define platform_inb		ia64_mv.inb
 #  define platform_inw		ia64_mv.inw
 #  define platform_inl		ia64_mv.inl
@@ -172,6 +183,9 @@
 	ia64_mv_irq_desc *irq_desc;
 	ia64_mv_irq_to_vector *irq_to_vector;
 	ia64_mv_local_vector_to_irq *local_vector_to_irq;
+	ia64_mv_pci_get_legacy_mem_t *pci_get_legacy_mem;
+	ia64_mv_pci_legacy_read_t *pci_legacy_read;
+	ia64_mv_pci_legacy_write_t *pci_legacy_write;
 	ia64_mv_inb_t *inb;
 	ia64_mv_inw_t *inw;
 	ia64_mv_inl_t *inl;
@@ -215,6 +229,9 @@
 	platform_irq_desc,			\
 	platform_irq_to_vector,			\
 	platform_local_vector_to_irq,		\
+	platform_pci_get_legacy_mem,		\
+	platform_pci_legacy_read,		\
+	platform_pci_legacy_write,		\
 	platform_inb,				\
 	platform_inw,				\
 	platform_inl,				\
@@ -329,6 +346,15 @@
 #endif
 #ifndef platform_local_vector_to_irq
 # define platform_local_vector_to_irq	__ia64_local_vector_to_irq
+#endif
+#ifndef platform_pci_get_legacy_mem
+# define platform_pci_get_legacy_mem	ia64_pci_get_legacy_mem
+#endif
+#ifndef platform_pci_legacy_read
+# define platform_pci_legacy_read	ia64_pci_legacy_read
+#endif
+#ifndef platform_pci_legacy_write
+# define platform_pci_legacy_write	ia64_pci_legacy_write
 #endif
 #ifndef platform_inb
 # define platform_inb		__ia64_inb
diff -Nru a/include/asm-ia64/machvec_hpzx1_swiotlb.h b/include/asm-ia64/machvec_hpzx1_swiotlb.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/asm-ia64/machvec_hpzx1_swiotlb.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,43 @@
+#ifndef _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
+#define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
+
+extern ia64_mv_setup_t				dig_setup;
+extern ia64_mv_dma_init				hwsw_init;
+extern ia64_mv_dma_alloc_coherent		hwsw_alloc_coherent;
+extern ia64_mv_dma_free_coherent		hwsw_free_coherent;
+extern ia64_mv_dma_map_single			hwsw_map_single;
+extern ia64_mv_dma_unmap_single			hwsw_unmap_single;
+extern ia64_mv_dma_map_sg			hwsw_map_sg;
+extern ia64_mv_dma_unmap_sg			hwsw_unmap_sg;
+extern ia64_mv_dma_supported			hwsw_dma_supported;
+extern ia64_mv_dma_mapping_error		hwsw_dma_mapping_error;
+extern ia64_mv_dma_sync_single_for_cpu		hwsw_sync_single_for_cpu;
+extern ia64_mv_dma_sync_sg_for_cpu		hwsw_sync_sg_for_cpu;
+extern ia64_mv_dma_sync_single_for_device	hwsw_sync_single_for_device;
+extern ia64_mv_dma_sync_sg_for_device		hwsw_sync_sg_for_device;
+
+/*
+ * This stuff has dual use!
+ *
+ * For a generic kernel, the macros are used to initialize the
+ * platform's machvec structure.  When compiling a non-generic kernel,
+ * the macros are used directly.
+ */
+#define platform_name				"hpzx1_swiotlb"
+
+#define platform_setup				dig_setup
+#define platform_dma_init			hwsw_init
+#define platform_dma_alloc_coherent		hwsw_alloc_coherent
+#define platform_dma_free_coherent		hwsw_free_coherent
+#define platform_dma_map_single			hwsw_map_single
+#define platform_dma_unmap_single		hwsw_unmap_single
+#define platform_dma_map_sg			hwsw_map_sg
+#define platform_dma_unmap_sg			hwsw_unmap_sg
+#define platform_dma_supported			hwsw_dma_supported
+#define platform_dma_mapping_error		hwsw_dma_mapping_error
+#define platform_dma_sync_single_for_cpu	hwsw_sync_single_for_cpu
+#define platform_dma_sync_sg_for_cpu		hwsw_sync_sg_for_cpu
+#define platform_dma_sync_single_for_device	hwsw_sync_single_for_device
+#define platform_dma_sync_sg_for_device		hwsw_sync_sg_for_device
+
+#endif /* _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h */
diff -Nru a/include/asm-ia64/machvec_init.h b/include/asm-ia64/machvec_init.h
--- a/include/asm-ia64/machvec_init.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-ia64/machvec_init.h	2005-01-19 13:44:48 -08:00
@@ -5,6 +5,9 @@
 extern ia64_mv_irq_desc __ia64_irq_desc;
 extern ia64_mv_irq_to_vector __ia64_irq_to_vector;
 extern ia64_mv_local_vector_to_irq __ia64_local_vector_to_irq;
+extern ia64_mv_pci_get_legacy_mem_t ia64_pci_get_legacy_mem;
+extern ia64_mv_pci_legacy_read_t ia64_pci_legacy_read;
+extern ia64_mv_pci_legacy_write_t ia64_pci_legacy_write;
 
 extern ia64_mv_inb_t __ia64_inb;
 extern ia64_mv_inw_t __ia64_inw;
diff -Nru a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h
--- a/include/asm-ia64/machvec_sn2.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-ia64/machvec_sn2.h	2005-01-19 13:44:46 -08:00
@@ -43,6 +43,9 @@
 extern ia64_mv_irq_desc sn_irq_desc;
 extern ia64_mv_irq_to_vector sn_irq_to_vector;
 extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq;
+extern ia64_mv_pci_get_legacy_mem_t sn_pci_get_legacy_mem;
+extern ia64_mv_pci_legacy_read_t sn_pci_legacy_read;
+extern ia64_mv_pci_legacy_write_t sn_pci_legacy_write;
 extern ia64_mv_inb_t __sn_inb;
 extern ia64_mv_inw_t __sn_inw;
 extern ia64_mv_inl_t __sn_inl;
@@ -105,6 +108,9 @@
 #define platform_irq_desc		sn_irq_desc
 #define platform_irq_to_vector		sn_irq_to_vector
 #define platform_local_vector_to_irq	sn_local_vector_to_irq
+#define platform_pci_get_legacy_mem	sn_pci_get_legacy_mem
+#define platform_pci_legacy_read	sn_pci_legacy_read
+#define platform_pci_legacy_write	sn_pci_legacy_write
 #define platform_dma_init		machvec_noop
 #define platform_dma_alloc_coherent	sn_dma_alloc_coherent
 #define platform_dma_free_coherent	sn_dma_free_coherent
diff -Nru a/include/asm-ia64/numnodes.h b/include/asm-ia64/numnodes.h
--- a/include/asm-ia64/numnodes.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-ia64/numnodes.h	2005-01-19 13:44:48 -08:00
@@ -4,7 +4,7 @@
 #ifdef CONFIG_IA64_DIG
 /* Max 8 Nodes */
 #define NODES_SHIFT	3
-#elif defined(CONFIG_IA64_HP_ZX1)
+#elif defined(CONFIG_IA64_HP_ZX1) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
 /* Max 32 Nodes */
 #define NODES_SHIFT	5
 #elif defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
diff -Nru a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
--- a/include/asm-ia64/pci.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-ia64/pci.h	2005-01-19 13:44:47 -08:00
@@ -85,6 +85,20 @@
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
 				enum pci_mmap_state mmap_state, int write_combine);
+#define HAVE_PCI_LEGACY
+extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
+				      struct vm_area_struct *vma);
+extern ssize_t pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off,
+				  size_t count);
+extern ssize_t pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off,
+				   size_t count);
+extern int pci_mmap_legacy_mem(struct kobject *kobj,
+			       struct bin_attribute *attr,
+			       struct vm_area_struct *vma);
+
+#define pci_get_legacy_mem platform_pci_get_legacy_mem
+#define pci_legacy_read platform_pci_legacy_read
+#define pci_legacy_write platform_pci_legacy_write
 
 struct pci_window {
 	struct resource resource;
diff -Nru a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
--- a/include/asm-ia64/sn/sn_sal.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-ia64/sn/sn_sal.h	2005-01-19 13:44:48 -08:00
@@ -203,7 +203,7 @@
 	return ret_stuff.v0;
 }
 
-static inline u64
+static inline char *
 ia64_sn_get_klconfig_addr(nasid_t nasid)
 {
 	struct ia64_sal_retval ret_stuff;
@@ -223,7 +223,7 @@
 	if (ret_stuff.status != 0) {
 		panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status);
 	}
-	return(ret_stuff.v0);
+	return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL;
 }
 
 /*
@@ -472,6 +472,52 @@
 	if (isrv.status)
 		return 0;
 	return isrv.v0;
+}
+
+/**
+ * ia64_sn_probe_mem - read from memory safely
+ * @addr: address to probe
+ * @size: number bytes to read (1,2,4,8)
+ * @data_ptr: address to store value read by probe (-1 returned if probe fails)
+ *
+ * Call into the SAL to do a memory read.  If the read generates a machine
+ * check, this routine will recover gracefully and return -1 to the caller.
+ * @addr is usually a kernel virtual address in uncached space (i.e. the
+ * address starts with 0xc), but if called in physical mode, @addr should
+ * be a physical address.
+ *
+ * Return values:
+ *  0 - probe successful
+ *  1 - probe failed (generated MCA)
+ *  2 - Bad arg
+ * <0 - PAL error
+ */
+static inline u64
+ia64_sn_probe_mem(long addr, long size, void *data_ptr)
+{
+	struct ia64_sal_retval isrv;
+
+	SAL_CALL(isrv, SN_SAL_PROBE, addr, size, 0, 0, 0, 0, 0);
+
+	if (data_ptr) {
+		switch (size) {
+		case 1:
+			*((u8*)data_ptr) = (u8)isrv.v0;
+			break;
+		case 2:
+			*((u16*)data_ptr) = (u16)isrv.v0;
+			break;
+		case 4:
+			*((u32*)data_ptr) = (u32)isrv.v0;
+			break;
+		case 8:
+			*((u64*)data_ptr) = (u64)isrv.v0;
+			break;
+		default:
+			isrv.status = 2;
+		}
+	}
+	return isrv.status;
 }
 
 /*
diff -Nru a/include/asm-m32r/checksum.h b/include/asm-m32r/checksum.h
--- a/include/asm-m32r/checksum.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-m32r/checksum.h	2005-01-19 13:44:45 -08:00
@@ -31,7 +31,8 @@
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-asmlinkage unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum);
+asmlinkage unsigned int csum_partial(const unsigned char *buff,
+				     int len, unsigned int sum);
 
 /*
  * The same as csum_partial, but copies from src while it checksums.
@@ -39,15 +40,16 @@
  * Here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+extern unsigned int csum_partial_copy_nocheck(const unsigned char *src,
+					      unsigned char *dst,
                                               int len, unsigned int sum);
 
 /*
  * This is a new version of the above that records errors it finds in *errp,
  * but continues and zeros thre rest of the buffer.
  */
-extern unsigned int csum_partial_copy_from_user(const char __user *src,
-                                                char *dst,
+extern unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
+                                                unsigned char *dst,
                                                 int len, unsigned int sum,
                                                 int *err_ptr);
 
diff -Nru a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h
--- a/include/asm-mips/checksum.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-mips/checksum.h	2005-01-19 13:44:45 -08:00
@@ -34,15 +34,15 @@
  * this is a new version of the above that records errors it finds in *errp,
  * but continues and zeros the rest of the buffer.
  */
-unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len,
+unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
                                          unsigned int sum, int *errp);
 
 /*
  * Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static inline unsigned int csum_and_copy_to_user (const char *src, 
-						  char __user *dst,
+static inline unsigned int csum_and_copy_to_user (const unsigned char *src,
+						  unsigned char __user *dst,
 						  int len, int sum,
 						  int *err_ptr)
 {
@@ -61,8 +61,8 @@
  * the same as csum_partial, but copies from user space (but on MIPS
  * we have just one address space, so this is identical to the above)
  */
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len,
-				       unsigned int sum);
+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
+				       int len, unsigned int sum);
 
 /*
  *	Fold a partial checksum without adding pseudo headers
diff -Nru a/include/asm-parisc/bootdata.h b/include/asm-parisc/bootdata.h
--- a/include/asm-parisc/bootdata.h	2005-01-19 13:44:48 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,16 +0,0 @@
-#ifndef _PARISC_BOOTDATA_H
-#define _PARISC_BOOTDATA_H
-
-/* structure given from bootloader... */
-typedef struct {
-    unsigned 	data_valid_signature,
-		initrd_start,
-		initrd_end;
-    char	commandline[1024];
-} bootdata_t;
-
-#define BOOTDATA_DATA_VALID_SIGNATURE 0xC0400000
-
-#define BOOTDATA_PTR ((bootdata_t*) 0xC0400000)
-
-#endif 
diff -Nru a/include/asm-parisc/cache.h b/include/asm-parisc/cache.h
--- a/include/asm-parisc/cache.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-parisc/cache.h	2005-01-19 13:44:48 -08:00
@@ -34,6 +34,7 @@
 extern void flush_instruction_cache_local(void); /* flushes local code-cache only */
 #ifdef CONFIG_SMP
 extern void flush_data_cache(void); /* flushes data-cache only (all processors) */
+extern void flush_instruction_cache(void); /* flushes i-cache only (all processors) */
 #else
 #define flush_data_cache flush_data_cache_local
 #define flush_instruction_cache flush_instruction_cache_local
diff -Nru a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
--- a/include/asm-parisc/cacheflush.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-parisc/cacheflush.h	2005-01-19 13:44:48 -08:00
@@ -33,36 +33,25 @@
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
 
-/* The following value needs to be tuned and probably scaled with the
- * cache size.
- */
-
-#define FLUSH_THRESHOLD 0x80000
+extern int parisc_cache_flush_threshold;
+void parisc_setup_cache_timing(void);
 
 static inline void
 flush_user_dcache_range(unsigned long start, unsigned long end)
 {
-#ifdef CONFIG_SMP
-	flush_user_dcache_range_asm(start,end);
-#else
-	if ((end - start) < FLUSH_THRESHOLD)
+	if ((end - start) < parisc_cache_flush_threshold)
 		flush_user_dcache_range_asm(start,end);
 	else
 		flush_data_cache();
-#endif
 }
 
 static inline void
 flush_user_icache_range(unsigned long start, unsigned long end)
 {
-#ifdef CONFIG_SMP
-	flush_user_icache_range_asm(start,end);
-#else
-	if ((end - start) < FLUSH_THRESHOLD)
+	if ((end - start) < parisc_cache_flush_threshold)
 		flush_user_icache_range_asm(start,end);
 	else
 		flush_instruction_cache();
-#endif
 }
 
 extern void flush_dcache_page(struct page *page);
diff -Nru a/include/asm-parisc/checksum.h b/include/asm-parisc/checksum.h
--- a/include/asm-parisc/checksum.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-parisc/checksum.h	2005-01-19 13:44:46 -08:00
@@ -23,13 +23,15 @@
  * Here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern unsigned int csum_partial_copy_nocheck(const char *, char *, int, unsigned int);
+extern unsigned int csum_partial_copy_nocheck(const unsigned char *, unsigned char *,
+					      int, unsigned int);
 
 /*
  * this is a new version of the above that records errors it finds in *errp,
  * but continues and zeros the rest of the buffer.
  */
-extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *errp);
+extern unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+						int len, unsigned int sum, int *errp);
 
 /*
  *	Optimized for IP headers, which always checksum on 4 octet boundaries.
@@ -191,8 +193,8 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, 
-						      char __user *dst,
+static __inline__ unsigned int csum_and_copy_to_user (const unsigned char *src,
+						      unsigned char __user *dst,
 						      int len, int sum, 
 						      int *err_ptr)
 {
diff -Nru a/include/asm-parisc/hardirq.h b/include/asm-parisc/hardirq.h
--- a/include/asm-parisc/hardirq.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-parisc/hardirq.h	2005-01-19 13:44:47 -08:00
@@ -18,6 +18,7 @@
 #include <linux/config.h>
 #include <linux/threads.h>
 #include <linux/cache.h>
+#include <linux/irq.h>
 
 typedef struct {
 	unsigned long __softirq_pending; /* set_bit is used on this */
@@ -28,11 +29,13 @@
 #define HARDIRQ_BITS	16
 
 /*
- * The hardirq mask has to be large enough to have space for potentially all IRQ sources
- * in the system nesting on a single CPU:
+ * The hardirq mask has to be large enough to have space for potentially all
+ * IRQ sources in the system nesting on a single CPU:
  */
 #if (1 << HARDIRQ_BITS) < NR_IRQS
 # error HARDIRQ_BITS is too low!
 #endif
+
+void ack_bad_irq(unsigned int irq);
 
 #endif /* _PARISC_HARDIRQ_H */
diff -Nru a/include/asm-parisc/hardware.h b/include/asm-parisc/hardware.h
--- a/include/asm-parisc/hardware.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-parisc/hardware.h	2005-01-19 13:44:47 -08:00
@@ -115,14 +115,13 @@
 extern int count_parisc_driver(struct parisc_driver *driver);
 extern int unregister_parisc_driver(struct parisc_driver *driver);
 extern void walk_central_bus(void);
-extern void fixup_child_irqs(struct parisc_device *parent, int irqbase,
-		int (*choose)(struct parisc_device *parent));
-extern void print_subdevices(struct parisc_device *dev);
 extern const struct parisc_device *find_pa_parent_type(const struct parisc_device *, int);
 extern void print_parisc_devices(void);
 extern char *print_pa_hwpath(struct parisc_device *dev, char *path);
 extern char *print_pci_hwpath(struct pci_dev *dev, char *path);
 extern void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path);
+extern void init_parisc_bus(void);
+extern struct device *hwpath_to_device(struct hardware_path *modpath);
 
 
 /* inventory.c: */
diff -Nru a/include/asm-parisc/hw_irq.h b/include/asm-parisc/hw_irq.h
--- a/include/asm-parisc/hw_irq.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-parisc/hw_irq.h	2005-01-19 13:44:46 -08:00
@@ -12,6 +12,6 @@
  *	<tomsoft@informatik.tu-chemnitz.de>
  */
 
-#include <asm/irq.h>
+extern void hw_resend_irq(struct hw_interrupt_type *, unsigned int);
 
 #endif
diff -Nru a/include/asm-parisc/io.h b/include/asm-parisc/io.h
--- a/include/asm-parisc/io.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-parisc/io.h	2005-01-19 13:44:46 -08:00
@@ -1,14 +1,6 @@
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
-/* USE_HPPA_IOREMAP IS THE MAGIC FLAG TO ENABLE OR DISABLE REAL IOREMAP() FUNCTIONALITY */
-/* FOR 712 or 715 MACHINES THIS SHOULD BE ENABLED, 
-   NEWER MACHINES STILL HAVE SOME ISSUES IN THE SCSI AND/OR NETWORK DRIVERS AND 
-   BECAUSE OF THAT I WILL LEAVE IT DISABLED FOR NOW <deller@gmx.de> */
-/* WHEN THOSE ISSUES ARE SOLVED, USE_HPPA_IOREMAP WILL GO AWAY */
-#define USE_HPPA_IOREMAP 0
-
-
 #include <linux/config.h>
 #include <linux/types.h>
 #include <asm/pgtable.h>
@@ -24,38 +16,44 @@
 #define virt_to_bus virt_to_phys
 #define bus_to_virt phys_to_virt
 
-/* Memory mapped IO */
-
-extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
-
-extern inline void * ioremap(unsigned long offset, unsigned long size)
-{
-	return __ioremap(offset, size, 0);
-}
-
 /*
- * This one maps high address device memory and turns off caching for that area.
- * it's useful if some control registers are in such an area and write combining
- * or read caching is not desirable:
+ * Memory mapped I/O
+ *
+ * readX()/writeX() do byteswapping and take an ioremapped address
+ * __raw_readX()/__raw_writeX() don't byteswap and take an ioremapped address.
+ * gsc_*() don't byteswap and operate on physical addresses;
+ *   eg dev->hpa or 0xfee00000.
  */
-extern inline void * ioremap_nocache(unsigned long offset, unsigned long size)
-{
-        return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */);
-}
 
-extern void iounmap(void *addr);
+#ifdef CONFIG_DEBUG_IOREMAP
+#ifdef CONFIG_64BIT
+#define NYBBLE_SHIFT 60
+#else
+#define NYBBLE_SHIFT 28
+#endif
+extern void gsc_bad_addr(unsigned long addr);
+extern void __raw_bad_addr(const volatile void __iomem *addr);
+#define gsc_check_addr(addr)					\
+	if ((addr >> NYBBLE_SHIFT) != 0xf) {			\
+		gsc_bad_addr(addr);				\
+		addr |= 0xfUL << NYBBLE_SHIFT;			\
+	}
+#define __raw_check_addr(addr)					\
+	if (((unsigned long)addr >> NYBBLE_SHIFT) != 0xe)	\
+		__raw_bad_addr(addr);			\
+	addr = (void *)((unsigned long)addr | (0xfUL << NYBBLE_SHIFT));
+#else
+#define gsc_check_addr(addr)
+#define __raw_check_addr(addr)
+#endif
 
-/*
- * __raw_ variants have no defined meaning.  on hppa, it means `i was
- * too lazy to ioremap first'.  kind of like isa_, except that there's
- * no additional base address to add on.
- */
-#define __raw_readb(a) ___raw_readb((unsigned long)(a))
-extern __inline__ unsigned char ___raw_readb(unsigned long addr)
+static inline unsigned char gsc_readb(unsigned long addr)
 {
 	long flags;
 	unsigned char ret;
 
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	rsm	2,%0\n"
 	"	ldbx	0(%2),%1\n"
@@ -65,12 +63,13 @@
 	return ret;
 }
 
-#define __raw_readw(a) ___raw_readw((unsigned long)(a))
-extern __inline__ unsigned short ___raw_readw(unsigned long addr)
+static inline unsigned short gsc_readw(unsigned long addr)
 {
 	long flags;
 	unsigned short ret;
 
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	rsm	2,%0\n"
 	"	ldhx	0(%2),%1\n"
@@ -80,11 +79,12 @@
 	return ret;
 }
 
-#define __raw_readl(a) ___raw_readl((unsigned long)(a))
-extern __inline__ unsigned int ___raw_readl(unsigned long addr)
+static inline unsigned int gsc_readl(unsigned long addr)
 {
 	u32 ret;
 
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	ldwax	0(%1),%0\n"
 	: "=r" (ret) : "r" (addr) );
@@ -92,26 +92,28 @@
 	return ret;
 }
 
-#define __raw_readq(a) ___raw_readq((unsigned long)(a))
-extern __inline__ unsigned long long ___raw_readq(unsigned long addr)
+static inline unsigned long long gsc_readq(unsigned long addr)
 {
 	unsigned long long ret;
+	gsc_check_addr(addr);
+
 #ifdef __LP64__
 	__asm__ __volatile__(
 	"	ldda	0(%1),%0\n"
 	:  "=r" (ret) : "r" (addr) );
 #else
 	/* two reads may have side effects.. */
-	ret = ((u64) __raw_readl(addr)) << 32;
-	ret |= __raw_readl(addr+4);
+	ret = ((u64) gsc_readl(addr)) << 32;
+	ret |= gsc_readl(addr+4);
 #endif
 	return ret;
 }
 
-#define __raw_writeb(a,b) ___raw_writeb(a, (unsigned long)(b))
-extern __inline__ void ___raw_writeb(unsigned char val, unsigned long addr)
+static inline void gsc_writeb(unsigned char val, unsigned long addr)
 {
 	long flags;
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	rsm	2,%0\n"
 	"	stbs	%1,0(%2)\n"
@@ -119,10 +121,11 @@
 	: "=&r" (flags) :  "r" (val), "r" (addr) );
 }
 
-#define __raw_writew(a,b) ___raw_writew(a, (unsigned long)(b))
-extern __inline__ void ___raw_writew(unsigned short val, unsigned long addr)
+static inline void gsc_writew(unsigned short val, unsigned long addr)
 {
 	long flags;
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	rsm	2,%0\n"
 	"	sths	%1,0(%2)\n"
@@ -130,88 +133,180 @@
 	: "=&r" (flags) :  "r" (val), "r" (addr) );
 }
 
-#define __raw_writel(a,b) ___raw_writel(a, (unsigned long)(b))
-extern __inline__ void ___raw_writel(unsigned int val, unsigned long addr)
+static inline void gsc_writel(unsigned int val, unsigned long addr)
 {
+	gsc_check_addr(addr);
+
 	__asm__ __volatile__(
 	"	stwas	%0,0(%1)\n"
 	: :  "r" (val), "r" (addr) );
 }
 
-#define __raw_writeq(a,b) ___raw_writeq(a, (unsigned long)(b))
-extern __inline__ void ___raw_writeq(unsigned long long val, unsigned long addr)
+static inline void gsc_writeq(unsigned long long val, unsigned long addr)
 {
+	gsc_check_addr(addr);
+
 #ifdef __LP64__
 	__asm__ __volatile__(
 	"	stda	%0,0(%1)\n"
 	: :  "r" (val), "r" (addr) );
 #else
 	/* two writes may have side effects.. */
-	__raw_writel(val >> 32, addr);
-	__raw_writel(val, addr+4);
+	gsc_writel(val >> 32, addr);
+	gsc_writel(val, addr+4);
 #endif
 }
 
+/*
+ * The standard PCI ioremap interfaces
+ */
+
+extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+extern inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+
+/*
+ * This one maps high address device memory and turns off caching for that area.
+ * it's useful if some control registers are in such an area and write combining
+ * or read caching is not desirable:
+ */
+extern inline void * ioremap_nocache(unsigned long offset, unsigned long size)
+{
+        return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */);
+}
+
+extern void iounmap(void __iomem *addr);
+
+/*
+ * USE_HPPA_IOREMAP is the magic flag to enable or disable real ioremap()
+ * functionality.  It's currently disabled because it may not work on some
+ * machines.
+ */
+#define USE_HPPA_IOREMAP 0
+
 #if USE_HPPA_IOREMAP
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
-#define readq(addr) (*(volatile u64 *) (addr))
-#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
-#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
-#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
-#define writeq(b,addr) (*(volatile u64 *) (addr) = (b))
+static inline unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+	return (*(volatile unsigned char __force *) (addr));
+}
+static inline unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned short __force *) addr;
+}
+static inline unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned int __force *) addr;
+}
+static inline unsigned long long __raw_readq(const volatile void __iomem *addr)
+{
+	return *(volatile unsigned long long __force *) addr;
+}
+
+static inline void __raw_writeb(unsigned char b, volatile void __iomem *addr)
+{
+	*(volatile unsigned char __force *) addr = b;
+}
+static inline void __raw_writew(unsigned short b, volatile void __iomem *addr)
+{
+	*(volatile unsigned short __force *) addr = b;
+}
+static inline void __raw_writel(unsigned int b, volatile void __iomem *addr)
+{
+	*(volatile unsigned int __force *) addr = b;
+}
+static inline void __raw_writeq(unsigned long long b, volatile void __iomem *addr)
+{
+	*(volatile unsigned long long __force *) addr = b;
+}
 #else /* !USE_HPPA_IOREMAP */
+static inline unsigned char __raw_readb(const volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	return gsc_readb((unsigned long) addr);
+}
+static inline unsigned short __raw_readw(const volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	return gsc_readw((unsigned long) addr);
+}
+static inline unsigned int __raw_readl(const volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	return gsc_readl((unsigned long) addr);
+}
+static inline unsigned long long __raw_readq(const volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	return gsc_readq((unsigned long) addr);
+}
+
+static inline void __raw_writeb(unsigned char b, volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	gsc_writeb(b, (unsigned long) addr);
+}
+static inline void __raw_writew(unsigned short b, volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	gsc_writew(b, (unsigned long) addr);
+}
+static inline void __raw_writel(unsigned int b, volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	gsc_writel(b, (unsigned long) addr);
+}
+static inline void __raw_writeq(unsigned long long b, volatile void __iomem *addr)
+{
+	__raw_check_addr(addr);
+
+	gsc_writeq(b, (unsigned long) addr);
+}
+#endif /* !USE_HPPA_IOREMAP */
+
 #define readb(addr) __raw_readb(addr)
 #define readw(addr) le16_to_cpu(__raw_readw(addr))
 #define readl(addr) le32_to_cpu(__raw_readl(addr))
 #define readq(addr) le64_to_cpu(__raw_readq(addr))
-#define writeb(b,addr) __raw_writeb(b,addr)
-#define writew(b,addr) __raw_writew(cpu_to_le16(b),addr)
-#define writel(b,addr) __raw_writel(cpu_to_le32(b),addr)
-#define writeq(b,addr) __raw_writeq(cpu_to_le64(b),addr)
-#endif /* !USE_HPPA_IOREMAP */
+#define writeb(b, addr) __raw_writeb(b, addr)
+#define writew(b, addr) __raw_writew(cpu_to_le16(b), addr)
+#define writel(b, addr) __raw_writel(cpu_to_le32(b), addr)
+#define writeq(b, addr) __raw_writeq(cpu_to_le64(b), addr)
 
 #define readb_relaxed(addr) readb(addr)
 #define readw_relaxed(addr) readw(addr)
 #define readl_relaxed(addr) readl(addr)
 #define readq_relaxed(addr) readq(addr)
 
-#define mmiowb()
+#define mmiowb() do { } while (0)
 
-extern void __memcpy_fromio(unsigned long dest, unsigned long src, int count);
-extern void __memcpy_toio(unsigned long dest, unsigned long src, int count);
-extern void __memset_io(unsigned long dest, char fill, int count);
-
-#define memcpy_fromio(a,b,c) __memcpy_fromio((unsigned long)(a), (unsigned long)(b), (c))
-#define memcpy_toio(a,b,c)   __memcpy_toio((unsigned long)(a), (unsigned long)(b), (c))
-#define memset_io(a,b,c)     __memset_io((unsigned long)(a), (b), (c))
+void memset_io(volatile void __iomem *addr, unsigned char val, int count);
+void memcpy_fromio(void *dst, const volatile void __iomem *src, int count);
+void memcpy_toio(volatile void __iomem *dst, const void *src, int count);
 
 /* Support old drivers which don't ioremap.
  * NB this interface is scheduled to disappear in 2.5
  */
 
-#define EISA_BASE 0xfffffffffc000000UL
-#define isa_readb(a) readb(EISA_BASE | (a))
-#define isa_readw(a) readw(EISA_BASE | (a))
-#define isa_readl(a) readl(EISA_BASE | (a))
-#define isa_writeb(b,a) writeb((b), EISA_BASE | (a))
-#define isa_writew(b,a) writew((b), EISA_BASE | (a))
-#define isa_writel(b,a) writel((b), EISA_BASE | (a))
-#define isa_memset_io(a,b,c) memset_io(EISA_BASE | (a), (b), (c))
-#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), EISA_BASE | (b), (c))
-#define isa_memcpy_toio(a,b,c) memcpy_toio(EISA_BASE | (a), (b), (c))
-
-/* 
- * These functions support PA-RISC drivers which don't yet call ioremap().
- * They will disappear once the last of these drivers is gone.
- */
-#define gsc_readb(x) __raw_readb(x)
-#define gsc_readw(x) __raw_readw(x)
-#define gsc_readl(x) __raw_readl(x)
-#define gsc_writeb(x, y) __raw_writeb(x, y)
-#define gsc_writew(x, y) __raw_writew(x, y)
-#define gsc_writel(x, y) __raw_writel(x, y)
+#define __isa_addr(x) (void __iomem *)(F_EXTEND(0xfc000000) | (x))
+#define isa_readb(a) readb(__isa_addr(a))
+#define isa_readw(a) readw(__isa_addr(a))
+#define isa_readl(a) readl(__isa_addr(a))
+#define isa_writeb(b,a) writeb((b), __isa_addr(a))
+#define isa_writew(b,a) writew((b), __isa_addr(a))
+#define isa_writel(b,a) writel((b), __isa_addr(a))
+#define isa_memset_io(a,b,c) memset_io(__isa_addr(a), (b), (c))
+#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), __isa_addr(b), (c))
+#define isa_memcpy_toio(a,b,c) memcpy_toio(__isa_addr(a), (b), (c))
 
 
 /*
@@ -305,5 +400,7 @@
  * bit I/O address (still with the leading f) and outputs the correct
  * value for either 32 or 64 bit mode */
 #define F_EXTEND(x) ((unsigned long)((x) | (0xffffffff00000000ULL)))
+
+#include <asm-generic/iomap.h>
 
 #endif
diff -Nru a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h
--- a/include/asm-parisc/irq.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-parisc/irq.h	2005-01-19 13:44:46 -08:00
@@ -1,102 +1,53 @@
 /*
- *	linux/include/asm-parisc/irq.h
+ * include/asm-parisc/irq.h
  *
- *	(C) 1992, 1993 Linus Torvalds, (C) 1997 Ingo Molnar,
- *		Copyright 1999 SuSE GmbH
- *
- *	IRQ/IPI changes taken from work by Thomas Radke
- *	<tomsoft@informatik.tu-chemnitz.de>
+ * Copyright 2005 Matthew Wilcox <matthew@wil.cx>
  */
 
 #ifndef _ASM_PARISC_IRQ_H
 #define _ASM_PARISC_IRQ_H
 
-#include <asm/ptrace.h>
-#include <asm/types.h>
-#include <asm/errno.h>
-
-#include <linux/string.h>
-#include <linux/interrupt.h>
 #include <linux/config.h>
+#include <asm/types.h>
 
+#define NO_IRQ		(-1)
 
-#define CPU_IRQ_REGION		1
-#define TIMER_IRQ		(IRQ_FROM_REGION(CPU_IRQ_REGION) | 0)
-#define	IPI_IRQ			(IRQ_FROM_REGION(CPU_IRQ_REGION) | 1)
-
-/* This should be 31 for PA1.1 binaries and 63 for PA-2.0 wide mode */
-#define MAX_CPU_IRQ		(BITS_PER_LONG - 1)
-
-#if BITS_PER_LONG == 32
-#  define IRQ_REGION_SHIFT 	5
+#ifdef CONFIG_GSC
+#define GSC_IRQ_BASE	16
+#define GSC_IRQ_MAX	63
+#define CPU_IRQ_BASE	64
 #else
-#  define IRQ_REGION_SHIFT 	6
+#define CPU_IRQ_BASE	16
 #endif
 
-#define IRQ_PER_REGION		(1 << IRQ_REGION_SHIFT)
-#define NR_IRQ_REGS		16
-#define NR_IRQS			(NR_IRQ_REGS * IRQ_PER_REGION)
-
-#define IRQ_REGION(irq) 	((irq) >> IRQ_REGION_SHIFT)
-#define IRQ_OFFSET(irq)		((irq) & ((1<<IRQ_REGION_SHIFT)-1))
-#define	IRQ_FROM_REGION(reg)	((reg) << IRQ_REGION_SHIFT)
-
-#define EISA_IRQ_REGION		0 /* region 0 needs to be reserved for EISA */
-#define EISA_MAX_IRQS		16 /* max. (E)ISA irq line */
-
-struct irq_region_ops {
-	void (*disable_irq)(void *dev, int irq);
-	void (* enable_irq)(void *dev, int irq);
-	void (*   mask_irq)(void *dev, int irq);
-	void (* unmask_irq)(void *dev, int irq);
-};
-
-struct irq_region_data {
-	void *dev;
-	const char *name;
-	int irqbase;
-	unsigned int status[IRQ_PER_REGION]; /* IRQ status */
-};
-
-struct irq_region {
-	struct irq_region_ops ops;
-	struct irq_region_data data;
+#define TIMER_IRQ	(CPU_IRQ_BASE + 0)
+#define	IPI_IRQ		(CPU_IRQ_BASE + 1)
+#define CPU_IRQ_MAX	(CPU_IRQ_BASE + (BITS_PER_LONG - 1))
 
-	struct irqaction *action;
-};
-
-extern struct irq_region *irq_region[NR_IRQ_REGS];
+#define NR_IRQS		(CPU_IRQ_MAX + 1)
 
 static __inline__ int irq_canonicalize(int irq)
 {
-#ifdef CONFIG_EISA
-	return (irq == (IRQ_FROM_REGION(EISA_IRQ_REGION)+2) 
-		? (IRQ_FROM_REGION(EISA_IRQ_REGION)+9) : irq);
-#else
-	return irq;
-#endif
+	return (irq == 2) ? 9 : irq;
 }
 
-extern void disable_irq(int);
-#define disable_irq_nosync(i) disable_irq(i)
-extern void enable_irq(int);
-
-extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
-extern void do_irq_mask(unsigned long mask, struct irq_region *region,
-	struct pt_regs *regs);
+struct hw_interrupt_type;
 
-extern struct irq_region *alloc_irq_region(int count, struct irq_region_ops *ops,
-	const char *name, void *dev);
+/*
+ * Some useful "we don't have to do anything here" handlers.  Should
+ * probably be provided by the generic code.
+ */
+void no_ack_irq(unsigned int irq);
+void no_end_irq(unsigned int irq);
 
 extern int txn_alloc_irq(void);
 extern int txn_claim_irq(int);
 extern unsigned int txn_alloc_data(int, unsigned int);
 extern unsigned long txn_alloc_addr(int);
 
+extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
+
 /* soft power switch support (power.c) */
 extern struct tasklet_struct power_tasklet;
-
-struct irqaction;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
 
 #endif	/* _ASM_PARISC_IRQ_H */
diff -Nru a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
--- a/include/asm-parisc/parisc-device.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-parisc/parisc-device.h	2005-01-19 13:44:46 -08:00
@@ -3,11 +3,7 @@
 struct parisc_device {
 	unsigned long   hpa;		/* Hard Physical Address */
 	struct parisc_device_id id;
-	struct parisc_device *parent;
-	struct parisc_device *sibling;
-	struct parisc_device *child;
 	struct parisc_driver *driver;	/* Driver for this device */
-	void		*sysdata;	/* Driver instance private data */
 	char		name[80];	/* The hardware description */
 	int		irq;
 
@@ -40,5 +36,18 @@
 
 #define to_parisc_device(d)	container_of(d, struct parisc_device, dev)
 #define to_parisc_driver(d)	container_of(d, struct parisc_driver, drv)
+#define parisc_parent(d)	to_parisc_device(d->dev.parent)
+
+static inline void
+parisc_set_drvdata(struct parisc_device *d, void *p)
+{
+	dev_set_drvdata(&d->dev, p);
+}
+
+static inline void *
+parisc_get_drvdata(struct parisc_device *d)
+{
+	return dev_get_drvdata(&d->dev);
+}
 
 extern struct bus_type parisc_bus_type;
diff -Nru a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h
--- a/include/asm-parisc/pdc.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-parisc/pdc.h	2005-01-19 13:44:45 -08:00
@@ -471,6 +471,13 @@
 	unsigned long mod_pgs;
 };
 
+struct pdc_initiator { /* PDC_INITIATOR */
+	int host_id;
+	int factor;
+	int width;
+	int mode;
+};
+
 struct hardware_path {
 	char  flags;	/* see bit definitions below */
 	char  bc[6];	/* Bus Converter routing info to a specific */
@@ -732,10 +739,16 @@
 #endif /* !CONFIG_PA20 */
 int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
 
+int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);
+int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count);
+int pdc_stable_get_size(unsigned long *size);
+int pdc_stable_verify_contents(void);
+int pdc_stable_initialize(void);
+
 int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa);
 int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl);
 
-int pdc_get_initiator(struct hardware_path *hwpath, unsigned char *scsi_id, unsigned long *period, char *width, char *mode);
+int pdc_get_initiator(struct hardware_path *, struct pdc_initiator *);
 int pdc_tod_read(struct pdc_tod *tod);
 int pdc_tod_set(unsigned long sec, unsigned long usec);
 
diff -Nru a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h
--- a/include/asm-parisc/ptrace.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-parisc/ptrace.h	2005-01-19 13:44:46 -08:00
@@ -47,7 +47,7 @@
 
 /* XXX should we use iaoq[1] or iaoq[0] ? */
 #define user_mode(regs)			(((regs)->iaoq[0] & 3) ? 1 : 0)
-#define user_space(regs)		(((regs)->iasq[0] != 0) ? 1 : 0)
+#define user_space(regs)		(((regs)->iasq[1] != 0) ? 1 : 0)
 #define instruction_pointer(regs)	((regs)->iaoq[0] & ~3)
 #define profile_pc(regs) instruction_pointer(regs)
 extern void show_regs(struct pt_regs *);
diff -Nru a/include/asm-parisc/serial.h b/include/asm-parisc/serial.h
--- a/include/asm-parisc/serial.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-parisc/serial.h	2005-01-19 13:44:48 -08:00
@@ -13,21 +13,6 @@
 #define LASI_BASE_BAUD ( 7272727 / 16 )
 #define BASE_BAUD  LASI_BASE_BAUD
 
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#endif
-	
 /*
  * We don't use the ISA probing code, so these entries are just to reserve
  * space.  Some example (maximal) configurations:
diff -Nru a/include/asm-parisc/superio.h b/include/asm-parisc/superio.h
--- a/include/asm-parisc/superio.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-parisc/superio.h	2005-01-19 13:44:46 -08:00
@@ -56,7 +56,6 @@
 	u32 pp_base;
 	u32 acpi_base;
 	int suckyio_irq_enabled;
-	struct irq_region *irq_region;
 	struct pci_dev *lio_pdev;       /* pci device for legacy IO (fn 1) */
 	struct pci_dev *usb_pdev;       /* pci device for USB (fn 2) */
 };
@@ -81,11 +80,6 @@
 	|| ((x)->device == PCI_DEVICE_ID_NS_87560_LIO) \
 	|| ((x)->device == PCI_DEVICE_ID_NS_87560_USB) ) )
 
-struct hwif_s;
-
-extern void superio_inform_irq(int irq);
-extern void superio_serial_init(void);		/* called by rs_init() */
 extern int superio_fixup_irq(struct pci_dev *pcidev); /* called by iosapic */
-extern void superio_fixup_pci(struct pci_dev *pdev);
 
 #endif /* _PARISC_SUPERIO_H */
diff -Nru a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
--- a/include/asm-parisc/unistd.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-parisc/unistd.h	2005-01-19 13:44:45 -08:00
@@ -822,7 +822,7 @@
 		__sys_res = (long)__res;				\
 	}								\
 	if ( (unsigned long)__sys_res >= (unsigned long)-4095 ){	\
-		errno = -__sys_res);		        		\
+		errno = -__sys_res;		        		\
 		__sys_res = -1;						\
 	}								\
 	__sys_res;							\
diff -Nru a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
--- a/include/asm-ppc/mpc8260.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-ppc/mpc8260.h	2005-01-19 13:44:45 -08:00
@@ -36,7 +36,7 @@
 #include <platforms/tqm8260.h>
 #endif
 
-#ifdef CONFIG_PQ2ADS
+#if defined(CONFIG_PQ2ADS) || defined (CONFIG_PQ2FADS)
 #include <platforms/pq2ads.h>
 #endif
 
diff -Nru a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
--- a/include/asm-ppc/pgtable.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-ppc/pgtable.h	2005-01-19 13:44:48 -08:00
@@ -127,6 +127,7 @@
  */
 #define VMALLOC_OFFSET (0x1000000) /* 16M */
 #ifdef CONFIG_44x
+#include <asm/ibm44x.h>
 #define VMALLOC_START (((_ALIGN((long)high_memory, PPC44x_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
 #else
 #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
diff -Nru a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h
--- a/include/asm-ppc/reg.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-ppc/reg.h	2005-01-19 13:44:48 -08:00
@@ -329,6 +329,7 @@
 #define MMCR0_PMC2_CYCLES	0x1
 #define MMCR0_PMC2_ITLB		0x7
 #define MMCR0_PMC2_LOADMISSTIME	0x5
+#define MMCR0_PMXE		(1 << 26)
 
 /* Short-hand versions for a number of the above SPRNs */
 #define CTR	SPRN_CTR	/* Counter Register */
diff -Nru a/include/asm-ppc64/iSeries/HvLpEvent.h b/include/asm-ppc64/iSeries/HvLpEvent.h
--- a/include/asm-ppc64/iSeries/HvLpEvent.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-ppc64/iSeries/HvLpEvent.h	2005-01-19 13:44:47 -08:00
@@ -75,6 +75,9 @@
 extern int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler hdlr);
 
 // Unregister a handler for an event type
+//  This call will sleep until the handler being removed is guaranteed to
+//  be no longer executing on any CPU. Do not call with locks held.
+//
 //  returns 0 on success
 //  Unregister will fail if there are any paths open for the type
 extern int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType );
diff -Nru a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
--- a/include/asm-ppc64/processor.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-ppc64/processor.h	2005-01-19 13:44:45 -08:00
@@ -537,6 +537,10 @@
 #define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
 		TASK_SIZE_USER32 : TASK_SIZE_USER64)
 
+/* We can't actually tell the TASK_SIZE given just the mm, but default
+ * to the 64-bit case to make sure that enough gets cleaned up. */
+#define MM_VM_SIZE(mm)	TASK_SIZE_USER64
+
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
diff -Nru a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
--- a/include/asm-ppc64/smp.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-ppc64/smp.h	2005-01-19 13:44:45 -08:00
@@ -38,7 +38,7 @@
 extern void smp_message_recv(int, struct pt_regs *);
 
 
-#define smp_processor_id() (get_paca()->paca_index)
+#define __smp_processor_id() (get_paca()->paca_index)
 #define hard_smp_processor_id() (get_paca()->hw_cpu_id)
 
 extern cpumask_t cpu_sibling_map[NR_CPUS];
diff -Nru a/include/asm-ppc64/spinlock.h b/include/asm-ppc64/spinlock.h
--- a/include/asm-ppc64/spinlock.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-ppc64/spinlock.h	2005-01-19 13:44:48 -08:00
@@ -222,8 +222,6 @@
 	: "cr0", "memory");
 }
 
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
-
 /*
  * This returns the old value in the lock,
  * so we got the write lock if the return value is 0.
diff -Nru a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
--- a/include/asm-ppc64/thread_info.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-ppc64/thread_info.h	2005-01-19 13:44:46 -08:00
@@ -12,6 +12,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/config.h>
+#include <linux/cache.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <linux/stringify.h>
@@ -22,12 +23,13 @@
 struct thread_info {
 	struct task_struct *task;		/* main task structure */
 	struct exec_domain *exec_domain;	/* execution domain */
-	unsigned long	flags;			/* low level flags */
 	int		cpu;			/* cpu we're on */
 	int		preempt_count;
 	struct restart_block restart_block;
 	/* set by force_successful_syscall_return */
 	unsigned char	syscall_noerror;
+	/* low level flags - has atomic operations done on it */
+	unsigned long	flags ____cacheline_aligned_in_smp;
 };
 
 /*
@@ -39,12 +41,12 @@
 {						\
 	.task =		&tsk,			\
 	.exec_domain =	&default_exec_domain,	\
-	.flags =	0,			\
 	.cpu =		0,			\
 	.preempt_count = 1,			\
 	.restart_block = {			\
 		.fn = do_no_restart_syscall,	\
 	},					\
+	.flags =	0,			\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff -Nru a/include/asm-ppc64/tlbflush.h b/include/asm-ppc64/tlbflush.h
--- a/include/asm-ppc64/tlbflush.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-ppc64/tlbflush.h	2005-01-19 13:44:45 -08:00
@@ -32,10 +32,11 @@
 
 static inline void flush_tlb_pending(void)
 {
-	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
+	struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
 
 	if (batch->index)
 		__flush_tlb_pending(batch);
+	put_cpu_var(ppc64_tlb_batch);
 }
 
 #define flush_tlb_mm(mm)			flush_tlb_pending()
diff -Nru a/include/asm-s390/system.h b/include/asm-s390/system.h
--- a/include/asm-s390/system.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-s390/system.h	2005-01-19 13:44:48 -08:00
@@ -119,8 +119,6 @@
 
 #else
 
-#define account_system_vtime(prev)
-
 #define finish_arch_switch(rq, prev) do {				     \
 	set_fs(current->thread.mm_segment);				     \
 	spin_unlock_irq(&(rq)->lock);					     \
diff -Nru a/include/asm-sh/checksum.h b/include/asm-sh/checksum.h
--- a/include/asm-sh/checksum.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-sh/checksum.h	2005-01-19 13:44:46 -08:00
@@ -34,8 +34,8 @@
  * better 64-bit) boundary
  */
 
-asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
-						   int *src_err_ptr, int *dst_err_ptr);
+asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned char *dst,
+						  int len, int sum, int *src_err_ptr, int *dst_err_ptr);
 
 /*
  *	Note: when you get a NULL pointer exception here this means someone
@@ -45,14 +45,14 @@
  *	verify_area().
  */
 static __inline__
-unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+unsigned int csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst,
 					int len, int sum)
 {
 	return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
 }
 
 static __inline__
-unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
 						int len, int sum, int *err_ptr)
 {
 	return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
@@ -200,8 +200,8 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static __inline__ unsigned int csum_and_copy_to_user (const char *src, 
-						      char __user *dst,
+static __inline__ unsigned int csum_and_copy_to_user (const unsigned char *src,
+						      unsigned char __user *dst,
 						      int len, int sum,
 						      int *err_ptr)
 {
diff -Nru a/include/asm-sparc/checksum.h b/include/asm-sparc/checksum.h
--- a/include/asm-sparc/checksum.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-sparc/checksum.h	2005-01-19 13:44:45 -08:00
@@ -39,10 +39,10 @@
  * better 64-bit) boundary
  */
 
-extern unsigned int __csum_partial_copy_sparc_generic (const char *, char *);
+extern unsigned int __csum_partial_copy_sparc_generic (const unsigned char *, unsigned char *);
 
 static inline unsigned int 
-csum_partial_copy_nocheck (const char *src, char *dst, int len, 
+csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, int len,
 			   unsigned int sum)
 {
 	register unsigned int ret asm("o0") = (unsigned int)src;
@@ -61,7 +61,7 @@
 }
 
 static inline unsigned int 
-csum_partial_copy_from_user(const char *src, char *dst, int len, 
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
 			    unsigned int sum, int *err)
   {
 	if (!access_ok (VERIFY_READ, src, len)) {
@@ -91,7 +91,7 @@
   }
   
 static inline unsigned int 
-csum_partial_copy_to_user(const char *src, char __user *dst, int len, 
+csum_partial_copy_to_user(const unsigned char *src, unsigned char __user *dst, int len,
 			  unsigned int sum, int *err)
 {
 	if (!access_ok (VERIFY_WRITE, dst, len)) {
diff -Nru a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
--- a/include/asm-sparc64/bitops.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-sparc64/bitops.h	2005-01-19 13:44:46 -08:00
@@ -223,7 +223,8 @@
  * on Linus's ALPHA routines, which are pretty portable BTW.
  */
 
-extern unsigned long find_next_zero_bit(unsigned long *, unsigned long, unsigned long);
+extern unsigned long find_next_zero_bit(const unsigned long *,
+					unsigned long, unsigned long);
 
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
diff -Nru a/include/asm-sparc64/checksum.h b/include/asm-sparc64/checksum.h
--- a/include/asm-sparc64/checksum.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-sparc64/checksum.h	2005-01-19 13:44:46 -08:00
@@ -38,10 +38,11 @@
  * here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern unsigned int csum_partial_copy_sparc64(const char *src, char *dst, int len, unsigned int sum);
+extern unsigned int csum_partial_copy_sparc64(const unsigned char *src, unsigned char *dst,
+					      int len, unsigned int sum);
 			
 static inline unsigned int 
-csum_partial_copy_nocheck (const char *src, char *dst, int len, 
+csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, int len,
 			   unsigned int sum)
 {
 	int ret;
@@ -53,7 +54,7 @@
 }
 
 static inline unsigned int 
-csum_partial_copy_from_user(const char __user *src, char *dst, int len, 
+csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, int len,
 			    unsigned int sum, int *err)
 {
 	__asm__ __volatile__ ("stx	%0, [%%sp + 0x7ff + 128]"
@@ -66,10 +67,11 @@
  *	Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-extern unsigned int csum_partial_copy_user_sparc64(const char *src, char __user *dst, int len, unsigned int sum);
+extern unsigned int csum_partial_copy_user_sparc64(const unsigned char *src, unsigned char __user *dst,
+						   int len, unsigned int sum);
 
 static inline unsigned int 
-csum_and_copy_to_user(const char *src, char __user *dst, int len, 
+csum_and_copy_to_user(const unsigned char *src, unsigned char __user *dst, int len,
 		      unsigned int sum, int *err)
 {
 	__asm__ __volatile__ ("stx	%0, [%%sp + 0x7ff + 128]"
diff -Nru a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
--- a/include/asm-x86_64/bitops.h	2005-01-19 13:44:46 -08:00
+++ b/include/asm-x86_64/bitops.h	2005-01-19 13:44:46 -08:00
@@ -267,22 +267,22 @@
 }
 
 #define find_first_bit(addr,size) \
-((__builtin_constant_p(size) && size <= BITS_PER_LONG ? \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
   (__scanbit(*(unsigned long *)addr,(size))) : \
   find_first_bit(addr,size)))
 
 #define find_next_bit(addr,size,off) \
-((__builtin_constant_p(size) && size <= BITS_PER_LONG ? 	  \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? 	  \
   ((off) + (__scanbit((*(unsigned long *)addr) >> (off),(size)-(off)))) : \
 	find_next_bit(addr,size,off)))
 
 #define find_first_zero_bit(addr,size) \
-((__builtin_constant_p(size) && size <= BITS_PER_LONG ? \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \
   (__scanbit(~*(unsigned long *)addr,(size))) : \
   	find_first_zero_bit(addr,size)))
 	
 #define find_next_zero_bit(addr,size,off) \
-((__builtin_constant_p(size) && size <= BITS_PER_LONG ? 	  \
+((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? 	  \
   ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off)),(size)-(off)))) : \
 	find_next_zero_bit(addr,size,off)))
 
diff -Nru a/include/asm-x86_64/checksum.h b/include/asm-x86_64/checksum.h
--- a/include/asm-x86_64/checksum.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-x86_64/checksum.h	2005-01-19 13:44:47 -08:00
@@ -133,17 +133,17 @@
 
 
 /* Do not call this directly. Use the wrappers below */
-extern unsigned long csum_partial_copy_generic(const char *src, const char *dst, 
+extern unsigned long csum_partial_copy_generic(const unsigned char *src, const unsigned char *dst,
 					       unsigned len,
 					       unsigned sum, 
 					       int *src_err_ptr, int *dst_err_ptr);
 
 
-extern unsigned int csum_partial_copy_from_user(const char __user *src, char *dst, 
+extern unsigned int csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst,
 				       int len, unsigned int isum, int *errp);
-extern unsigned int csum_partial_copy_to_user(const char *src, char __user *dst, 
+extern unsigned int csum_partial_copy_to_user(const unsigned char *src, unsigned char __user *dst,
 				      int len, unsigned int isum, int *errp);
-extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, 
+extern unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len,
 					      unsigned int sum);
 
 /* Old names. To be removed. */
diff -Nru a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h
--- a/include/asm-x86_64/numa.h	2005-01-19 13:44:45 -08:00
+++ b/include/asm-x86_64/numa.h	2005-01-19 13:44:45 -08:00
@@ -8,7 +8,7 @@
 	u64 start,end; 
 };
 
-extern int compute_hash_shift(struct node *nodes);
+extern int compute_hash_shift(struct node *nodes, int numnodes);
 
 #define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
 
diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
--- a/include/asm-x86_64/proto.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-x86_64/proto.h	2005-01-19 13:44:47 -08:00
@@ -52,7 +52,7 @@
 
 extern unsigned long end_pfn_map; 
 
-extern unsigned long cpu_initialized;
+extern cpumask_t cpu_initialized;
 
 extern void show_trace(unsigned long * rsp);
 extern void show_registers(struct pt_regs *regs);
diff -Nru a/include/asm-x86_64/setup.h b/include/asm-x86_64/setup.h
--- a/include/asm-x86_64/setup.h	2005-01-19 13:44:48 -08:00
+++ b/include/asm-x86_64/setup.h	2005-01-19 13:44:48 -08:00
@@ -1,6 +1,6 @@
 #ifndef _x8664_SETUP_H
 #define _x8664_SETUP_H
 
-#define COMMAND_LINE_SIZE	256
+#define COMMAND_LINE_SIZE	2048
 
 #endif
diff -Nru a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
--- a/include/asm-x86_64/unistd.h	2005-01-19 13:44:47 -08:00
+++ b/include/asm-x86_64/unistd.h	2005-01-19 13:44:47 -08:00
@@ -298,8 +298,9 @@
 #define __NR_mknod                             133
 __SYSCALL(__NR_mknod, sys_mknod)
 
+/* Only needed for a.out */
 #define __NR_uselib                            134
-__SYSCALL(__NR_uselib, sys_uselib)
+__SYSCALL(__NR_uselib, sys_ni_syscall)
 #define __NR_personality                       135
 __SYSCALL(__NR_personality, sys_personality)
 
diff -Nru a/include/linux/arcdevice.h b/include/linux/arcdevice.h
--- a/include/linux/arcdevice.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/arcdevice.h	2005-01-19 13:44:46 -08:00
@@ -343,7 +343,6 @@
 
 void arcnet_unregister_proto(struct ArcProto *proto);
 irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-void arcdev_setup(struct net_device *dev);
 struct net_device *alloc_arcdev(char *name);
 void arcnet_rx(struct net_device *dev, int bufnum);
 
diff -Nru a/include/linux/backlight.h b/include/linux/backlight.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/backlight.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,57 @@
+/*
+ * Backlight Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#ifndef _LINUX_BACKLIGHT_H
+#define _LINUX_BACKLIGHT_H
+
+#include <linux/device.h>
+#include <linux/notifier.h>
+
+struct backlight_device;
+struct fb_info;
+
+/* This structure defines all the properties of a backlight
+   (usually attached to a LCD). */
+struct backlight_properties {
+	/* Owner module */
+	struct module *owner;
+	/* Get the backlight power status (0: full on, 1..3: power saving
+	   modes; 4: full off), see FB_BLANK_XXX */
+	int (*get_power)(struct backlight_device *);
+	/* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */
+	int (*set_power)(struct backlight_device *, int power);
+	/* Maximal value for brightness (read-only) */
+	int max_brightness;
+	/* Get current backlight brightness */
+	int (*get_brightness)(struct backlight_device *);
+	/* Set backlight brightness (0..max_brightness) */
+	int (*set_brightness)(struct backlight_device *, int brightness);
+	/* Check if given framebuffer device is the one bound to this backlight;
+	   return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
+	int (*check_fb)(struct fb_info *);
+};
+
+struct backlight_device {
+	/* This protects the 'props' field. If 'props' is NULL, the driver that
+	   registered this device has been unloaded, and if class_get_devdata()
+	   points to something in the body of that driver, it is also invalid. */
+	struct semaphore sem;
+	/* If this is NULL, the backing module is unloaded */
+	struct backlight_properties *props;
+	/* The framebuffer notifier block */
+	struct notifier_block fb_notif;
+	/* The class device structure */
+	struct class_device class_dev;
+};
+
+extern struct backlight_device *backlight_device_register(const char *name,
+	void *devdata, struct backlight_properties *bp);
+extern void backlight_device_unregister(struct backlight_device *bd);
+
+#define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev)
+
+#endif
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/blkdev.h	2005-01-19 13:44:46 -08:00
@@ -95,6 +95,7 @@
 
 struct request_list {
 	int count[2];
+	int starved[2];
 	mempool_t *rq_pool;
 	wait_queue_head_t wait[2];
 	wait_queue_head_t drain;
diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/cpufreq.h	2005-01-19 13:44:47 -08:00
@@ -252,65 +252,6 @@
 /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
 unsigned int cpufreq_get(unsigned int cpu);
 
-/* the proc_intf.c needs this */
-int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
-
-
-/*********************************************************************
- *                      CPUFREQ USERSPACE GOVERNOR                   *
- *********************************************************************/
-#ifdef CONFIG_CPU_FREQ_24_API
-
-int __deprecated cpufreq_setmax(unsigned int cpu);
-int __deprecated cpufreq_set(unsigned int kHz, unsigned int cpu);
-
-
-/* /proc/sys/cpu */
-enum {
-	CPU_NR   = 1,           /* compatibilty reasons */
-	CPU_NR_0 = 1,
-	CPU_NR_1 = 2,
-	CPU_NR_2 = 3,
-	CPU_NR_3 = 4,
-	CPU_NR_4 = 5,
-	CPU_NR_5 = 6,
-	CPU_NR_6 = 7,
-	CPU_NR_7 = 8,
-	CPU_NR_8 = 9,
-	CPU_NR_9 = 10,
-	CPU_NR_10 = 11,
-	CPU_NR_11 = 12,
-	CPU_NR_12 = 13,
-	CPU_NR_13 = 14,
-	CPU_NR_14 = 15,
-	CPU_NR_15 = 16,
-	CPU_NR_16 = 17,
-	CPU_NR_17 = 18,
-	CPU_NR_18 = 19,
-	CPU_NR_19 = 20,
-	CPU_NR_20 = 21,
-	CPU_NR_21 = 22,
-	CPU_NR_22 = 23,
-	CPU_NR_23 = 24,
-	CPU_NR_24 = 25,
-	CPU_NR_25 = 26,
-	CPU_NR_26 = 27,
-	CPU_NR_27 = 28,
-	CPU_NR_28 = 29,
-	CPU_NR_29 = 30,
-	CPU_NR_30 = 31,
-	CPU_NR_31 = 32,
-};
-
-/* /proc/sys/cpu/{0,1,...,(NR_CPUS-1)} */
-enum {
-	CPU_NR_FREQ_MAX = 1,
-	CPU_NR_FREQ_MIN = 2,
-	CPU_NR_FREQ = 3,
-};
-
-#endif /* CONFIG_CPU_FREQ_24_API */
-
 
 /*********************************************************************
  *                       CPUFREQ DEFAULT GOVERNOR                    *
@@ -350,6 +291,11 @@
 				   unsigned int target_freq,
 				   unsigned int relation,
 				   unsigned int *index);
+
+/* the following 3 funtions are for cpufreq core use only */
+struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
+struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu);
+void   cpufreq_cpu_put (struct cpufreq_policy *data);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/ext3_fs.h	2005-01-19 13:44:47 -08:00
@@ -195,7 +195,7 @@
  */
 #define EXT3_STATE_JDATA		0x00000001 /* journaled data exists */
 #define EXT3_STATE_NEW			0x00000002 /* inode is newly created */
-
+#define EXT3_STATE_XATTR		0x00000004 /* has in-inode xattrs */
 
 /* Used to pass group descriptor data when online resize is done */
 struct ext3_new_group_input {
@@ -293,8 +293,8 @@
 			__u32	m_i_reserved2[2];
 		} masix2;
 	} osd2;				/* OS dependent 2 */
-	__u16	i_extra_isize;
-	__u16	i_pad1;
+	__le16	i_extra_isize;
+	__le16	i_pad1;
 };
 
 #define i_size_high	i_dir_acl
@@ -757,7 +757,6 @@
 extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
 extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
 
-extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *, int);
 extern void ext3_read_inode (struct inode *);
 extern int  ext3_write_inode (struct inode *, int);
 extern int  ext3_setattr (struct dentry *, struct iattr *);
@@ -766,6 +765,7 @@
 extern void ext3_discard_reservation (struct inode *);
 extern void ext3_dirty_inode(struct inode *);
 extern int ext3_change_inode_journal_flag(struct inode *, int);
+extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *);
 extern void ext3_truncate (struct inode *);
 extern void ext3_set_inode_flags(struct inode *);
 extern void ext3_set_aops(struct inode *inode);
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/fs.h	2005-01-19 13:44:46 -08:00
@@ -905,10 +905,16 @@
 
 typedef int (*read_actor_t)(read_descriptor_t *, struct page *, unsigned long, unsigned long);
 
+/* These macros are for out of kernel modules to test that
+ * the kernel supports the unlocked_ioctl and compat_ioctl
+ * fields in struct file_operations. */
+#define HAVE_COMPAT_IOCTL 1
+#define HAVE_UNLOCKED_IOCTL 1
+
 /*
  * NOTE:
- * read, write, poll, fsync, readv, writev can be called
- *   without the big kernel lock held in all filesystems.
+ * read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
+ * can be called without the big kernel lock held in all filesystems.
  */
 struct file_operations {
 	struct module *owner;
@@ -920,6 +926,8 @@
 	int (*readdir) (struct file *, void *, filldir_t);
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
+	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
+	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
 	int (*mmap) (struct file *, struct vm_area_struct *);
 	int (*open) (struct inode *, struct file *);
 	int (*flush) (struct file *);
diff -Nru a/include/linux/genhd.h b/include/linux/genhd.h
--- a/include/linux/genhd.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/genhd.h	2005-01-19 13:44:46 -08:00
@@ -128,6 +128,12 @@
 #endif
 };
 
+/* Structure for sysfs attributes on block devices */
+struct disk_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct gendisk *, char *);
+};
+
 /* 
  * Macros to operate on percpu disk statistics:
  *
diff -Nru a/include/linux/i2o.h b/include/linux/i2o.h
--- a/include/linux/i2o.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/i2o.h	2005-01-19 13:44:46 -08:00
@@ -23,7 +23,7 @@
 #include <linux/i2o-dev.h>
 
 /* How many different OSM's are we allowing */
-#define I2O_MAX_DRIVERS		4
+#define I2O_MAX_DRIVERS		8
 
 #include <asm/io.h>
 #include <asm/semaphore.h>	/* Needed for MUTEX init macros */
@@ -631,15 +631,25 @@
 extern int i2o_parm_field_get(struct i2o_device *, int, int, void *, int);
 extern int i2o_parm_table_get(struct i2o_device *, int, int, int, void *, int,
 			      void *, int);
-/* FIXME: remove
-extern int i2o_query_table(int, struct i2o_controller *, int, int, int,
-			   void *, int, void *, int);
-extern int i2o_clear_table(struct i2o_controller *, int, int);
-extern int i2o_row_add_table(struct i2o_controller *, int, int, int,
-			     void *, int);
-extern int i2o_issue_params(int, struct i2o_controller *, int, void *, int,
-			    void *, int);
-*/
+
+/* debugging and troubleshooting/diagnostic helpers. */
+#define osm_printk(level, format, arg...)  \
+	printk(level "%s: " format, OSM_NAME , ## arg)
+
+#ifdef DEBUG
+#define osm_debug(format, arg...) \
+	osm_printk(KERN_DEBUG, format , ## arg)
+#else
+#define osm_debug(format, arg...) \
+        do { } while (0)
+#endif
+
+#define osm_err(format, arg...)		\
+	osm_printk(KERN_ERR, format , ## arg)
+#define osm_info(format, arg...)		\
+	osm_printk(KERN_INFO, format , ## arg)
+#define osm_warn(format, arg...)		\
+	osm_printk(KERN_WARNING, format , ## arg)
 
 /* debugging functions */
 extern void i2o_report_status(const char *, const char *, struct i2o_message *);
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/ide.h	2005-01-19 13:44:46 -08:00
@@ -723,7 +723,6 @@
 	unsigned scsi		: 1;	/* 0=default, 1=ide-scsi emulation */
 
         u8	quirk_list;	/* considered quirky, set for a specific host */
-        u8	suspend_reset;	/* drive suspend mode flag, soft-reset recovers */
         u8	init_speed;	/* transfer rate set at boot */
         u8	pio_speed;      /* unused by core, used by some drivers for fallback from DMA */
         u8	current_speed;	/* current transfer rate set */
@@ -1250,8 +1249,6 @@
  */
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
 
-extern void try_to_flush_leftover_data(ide_drive_t *);
-
 /*
  * Issue ATA command and wait for completion.
  * Use for implementing commands in kernel
@@ -1444,12 +1441,12 @@
 int ide_use_dma(ide_drive_t *);
 int __ide_dma_off(ide_drive_t *);
 void ide_dma_verbose(ide_drive_t *);
+ide_startstop_t ide_dma_intr(ide_drive_t *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 extern int ide_build_sglist(ide_drive_t *, struct request *);
 extern int ide_build_dmatable(ide_drive_t *, struct request *);
 extern void ide_destroy_dmatable(ide_drive_t *);
-extern ide_startstop_t ide_dma_intr(ide_drive_t *);
 extern int ide_release_dma(ide_hwif_t *);
 extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
 
diff -Nru a/include/linux/if_tun.h b/include/linux/if_tun.h
--- a/include/linux/if_tun.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/if_tun.h	2005-01-19 13:44:46 -08:00
@@ -58,7 +58,7 @@
 #endif /* __KERNEL__ */
 
 /* Read queue size */
-#define TUN_READQ_SIZE	10
+#define TUN_READQ_SIZE	500
 
 /* TUN device flags */
 #define TUN_TUN_DEV 	0x0001	
diff -Nru a/include/linux/in6.h b/include/linux/in6.h
--- a/include/linux/in6.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/in6.h	2005-01-19 13:44:47 -08:00
@@ -44,8 +44,10 @@
  * NOTE: Be aware the IN6ADDR_* constants and in6addr_* externals are defined
  * in network byte order, not in host byte order as are the IPv4 equivalents
  */
+#if 0
 extern const struct in6_addr in6addr_any;
 #define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#endif
 extern const struct in6_addr in6addr_loopback;
 #define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
 
diff -Nru a/include/linux/ipv6.h b/include/linux/ipv6.h
--- a/include/linux/ipv6.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/ipv6.h	2005-01-19 13:44:47 -08:00
@@ -262,8 +262,7 @@
 };
 
 struct udp6_sock {
-	struct inet_sock  inet;
-	struct udp_opt	  udp;
+	struct udp_sock	  udp;
 	struct ipv6_pinfo inet6;
 };
 
diff -Nru a/include/linux/irq.h b/include/linux/irq.h
--- a/include/linux/irq.h	2005-01-19 13:44:48 -08:00
+++ b/include/linux/irq.h	2005-01-19 13:44:48 -08:00
@@ -59,9 +59,10 @@
  * Pad this out to 32 bytes for cache and indexing reasons.
  */
 typedef struct irq_desc {
-	unsigned int status;		/* IRQ status */
 	hw_irq_controller *handler;
+	void *handler_data;
 	struct irqaction *action;	/* IRQ action list */
+	unsigned int status;		/* IRQ status */
 	unsigned int depth;		/* nested irq disables */
 	unsigned int irq_count;		/* For detecting broken interrupts */
 	unsigned int irqs_unhandled;
diff -Nru a/include/linux/lcd.h b/include/linux/lcd.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/lcd.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,56 @@
+/*
+ * LCD Lowlevel Control Abstraction
+ *
+ * Copyright (C) 2003,2004 Hewlett-Packard Company
+ *
+ */
+
+#ifndef _LINUX_LCD_H
+#define _LINUX_LCD_H
+
+#include <linux/device.h>
+#include <linux/notifier.h>
+
+struct lcd_device;
+struct fb_info;
+
+/* This structure defines all the properties of a LCD flat panel. */
+struct lcd_properties {
+	/* Owner module */
+	struct module *owner;
+	/* Get the LCD panel power status (0: full on, 1..3: controller
+	   power on, flat panel power off, 4: full off), see FB_BLANK_XXX */
+	int (*get_power)(struct lcd_device *);
+	/* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */
+	int (*set_power)(struct lcd_device *, int power);
+	/* The maximum value for contrast (read-only) */
+	int max_contrast;
+	/* Get the current contrast setting (0-max_contrast) */
+	int (*get_contrast)(struct lcd_device *);
+	/* Set LCD panel contrast */
+        int (*set_contrast)(struct lcd_device *, int contrast);
+	/* Check if given framebuffer device is the one LCD is bound to;
+	   return 0 if not, !=0 if it is. If NULL, lcd always matches the fb. */
+	int (*check_fb)(struct fb_info *);
+};
+
+struct lcd_device {
+	/* This protects the 'props' field. If 'props' is NULL, the driver that
+	   registered this device has been unloaded, and if class_get_devdata()
+	   points to something in the body of that driver, it is also invalid. */
+	struct semaphore sem;
+	/* If this is NULL, the backing module is unloaded */
+	struct lcd_properties *props;
+	/* The framebuffer notifier block */
+	struct notifier_block fb_notif;
+	/* The class device structure */
+	struct class_device class_dev;
+};
+
+extern struct lcd_device *lcd_device_register(const char *name,
+	void *devdata, struct lcd_properties *lp);
+extern void lcd_device_unregister(struct lcd_device *ld);
+
+#define to_lcd_device(obj) container_of(obj, struct lcd_device, class_dev)
+
+#endif
diff -Nru a/include/linux/mbcache.h b/include/linux/mbcache.h
--- a/include/linux/mbcache.h	2005-01-19 13:44:48 -08:00
+++ b/include/linux/mbcache.h	2005-01-19 13:44:48 -08:00
@@ -7,39 +7,22 @@
 /* Hardwire the number of additional indexes */
 #define MB_CACHE_INDEXES_COUNT 1
 
-struct mb_cache_entry;
-
-struct mb_cache_op {
-	int (*free)(struct mb_cache_entry *, int);
-};
-
-struct mb_cache {
-	struct list_head		c_cache_list;
-	const char			*c_name;
-	struct mb_cache_op		c_op;
-	atomic_t			c_entry_count;
-	int				c_bucket_bits;
-#ifndef MB_CACHE_INDEXES_COUNT
-	int				c_indexes_count;
-#endif
-	kmem_cache_t			*c_entry_cache;
-	struct list_head		*c_block_hash;
-	struct list_head		*c_indexes_hash[0];
-};
-
-struct mb_cache_entry_index {
-	struct list_head		o_list;
-	unsigned int			o_key;
-};
-
 struct mb_cache_entry {
 	struct list_head		e_lru_list;
 	struct mb_cache			*e_cache;
-	atomic_t			e_used;
+	unsigned short			e_used;
+	unsigned short			e_queued;
 	struct block_device		*e_bdev;
 	sector_t			e_block;
 	struct list_head		e_block_list;
-	struct mb_cache_entry_index	e_indexes[0];
+	struct {
+		struct list_head	o_list;
+		unsigned int		o_key;
+	} e_indexes[0];
+};
+
+struct mb_cache_op {
+	int (*free)(struct mb_cache_entry *, int);
 };
 
 /* Functions on caches */
@@ -54,7 +37,6 @@
 struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
 int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *,
 			  sector_t, unsigned int[]);
-void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]);
 void mb_cache_entry_release(struct mb_cache_entry *);
 void mb_cache_entry_free(struct mb_cache_entry *);
 struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *,
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/netdevice.h	2005-01-19 13:44:47 -08:00
@@ -522,7 +522,6 @@
 extern struct net_device		*dev_base;		/* All devices */
 extern rwlock_t				dev_base_lock;		/* Device list lock */
 
-extern int			netdev_boot_setup_add(char *name, struct ifmap *map);
 extern int 			netdev_boot_setup_check(struct net_device *dev);
 extern unsigned long		netdev_boot_base(const char *prefix, int unit);
 extern struct net_device    *dev_getbyhwaddr(unsigned short type, char *hwaddr);
diff -Nru a/include/linux/netfilter.h b/include/linux/netfilter.h
--- a/include/linux/netfilter.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/netfilter.h	2005-01-19 13:44:46 -08:00
@@ -175,10 +175,6 @@
 extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
 extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
 
-#ifdef CONFIG_NETFILTER_DEBUG
-extern void nf_dump_skb(int pf, struct sk_buff *skb);
-#endif
-
 /* FIXME: Before cache is ever used, this must be implemented for real. */
 extern void nf_invalidate_cache(int pf);
 
diff -Nru a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
--- a/include/linux/netfilter_arp/arp_tables.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/netfilter_arp/arp_tables.h	2005-01-19 13:44:46 -08:00
@@ -312,9 +312,6 @@
 	/* A unique name... */
 	char name[ARPT_TABLE_MAXNAMELEN];
 
-	/* Seed table: copied in register_table */
-	struct arpt_replace *table;
-
 	/* What hooks you will enter on */
 	unsigned int valid_hooks;
 
@@ -328,7 +325,8 @@
 	struct module *me;
 };
 
-extern int arpt_register_table(struct arpt_table *table);
+extern int arpt_register_table(struct arpt_table *table,
+			       const struct arpt_replace *repl);
 extern void arpt_unregister_table(struct arpt_table *table);
 extern unsigned int arpt_do_table(struct sk_buff **pskb,
 				  unsigned int hook,
diff -Nru a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
--- a/include/linux/netfilter_ipv4/ip_tables.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/netfilter_ipv4/ip_tables.h	2005-01-19 13:44:46 -08:00
@@ -440,9 +440,6 @@
 	/* A unique name... */
 	char name[IPT_TABLE_MAXNAMELEN];
 
-	/* Seed table: copied in register_table */
-	struct ipt_replace *table;
-
 	/* What hooks you will enter on */
 	unsigned int valid_hooks;
 
@@ -456,7 +453,30 @@
 	struct module *me;
 };
 
-extern int ipt_register_table(struct ipt_table *table);
+/* net/sched/ipt.c: Gimme access to your targets!  Gets target->me. */
+extern struct ipt_target *ipt_find_target(const char *name, u8 revision);
+
+/* Standard entry. */
+struct ipt_standard
+{
+	struct ipt_entry entry;
+	struct ipt_standard_target target;
+};
+
+struct ipt_error_target
+{
+	struct ipt_entry_target target;
+	char errorname[IPT_FUNCTION_MAXNAMELEN];
+};
+
+struct ipt_error
+{
+	struct ipt_entry entry;
+	struct ipt_error_target target;
+};
+
+extern int ipt_register_table(struct ipt_table *table,
+			      const struct ipt_replace *repl);
 extern void ipt_unregister_table(struct ipt_table *table);
 extern unsigned int ipt_do_table(struct sk_buff **pskb,
 				 unsigned int hook,
diff -Nru a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/linux/netfilter_ipv4/ipt_LOG.h
--- a/include/linux/netfilter_ipv4/ipt_LOG.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/netfilter_ipv4/ipt_LOG.h	2005-01-19 13:44:47 -08:00
@@ -4,7 +4,8 @@
 #define IPT_LOG_TCPSEQ		0x01	/* Log TCP sequence numbers */
 #define IPT_LOG_TCPOPT		0x02	/* Log TCP options */
 #define IPT_LOG_IPOPT		0x04	/* Log IP options */
-#define IPT_LOG_MASK		0x07
+#define IPT_LOG_UID		0x08	/* Log UID owning local socket */
+#define IPT_LOG_MASK		0x0f
 
 struct ipt_log_info {
 	unsigned char level;
diff -Nru a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
--- a/include/linux/netfilter_ipv6/ip6_tables.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/netfilter_ipv6/ip6_tables.h	2005-01-19 13:44:47 -08:00
@@ -429,9 +429,6 @@
 	/* A unique name... */
 	char name[IP6T_TABLE_MAXNAMELEN];
 
-	/* Seed table: copied in register_table */
-	struct ip6t_replace *table;
-
 	/* What hooks you will enter on */
 	unsigned int valid_hooks;
 
@@ -445,7 +442,8 @@
 	struct module *me;
 };
 
-extern int ip6t_register_table(struct ip6t_table *table);
+extern int ip6t_register_table(struct ip6t_table *table,
+			       const struct ip6t_replace *repl);
 extern void ip6t_unregister_table(struct ip6t_table *table);
 extern unsigned int ip6t_do_table(struct sk_buff **pskb,
 				  unsigned int hook,
diff -Nru a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/linux/netfilter_ipv6/ip6t_LOG.h
--- a/include/linux/netfilter_ipv6/ip6t_LOG.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/netfilter_ipv6/ip6t_LOG.h	2005-01-19 13:44:47 -08:00
@@ -4,7 +4,8 @@
 #define IP6T_LOG_TCPSEQ		0x01	/* Log TCP sequence numbers */
 #define IP6T_LOG_TCPOPT		0x02	/* Log TCP options */
 #define IP6T_LOG_IPOPT		0x04	/* Log IP options */
-#define IP6T_LOG_MASK		0x07
+#define IP6T_LOG_UID		0x08	/* Log UID owning local socket */
+#define IP6T_LOG_MASK		0x0f
 
 struct ip6t_log_info {
 	unsigned char level;
diff -Nru a/include/linux/netlink.h b/include/linux/netlink.h
--- a/include/linux/netlink.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/netlink.h	2005-01-19 13:44:47 -08:00
@@ -116,7 +116,6 @@
 #define NETLINK_CREDS(skb)	(&NETLINK_CB((skb)).creds)
 
 
-extern int netlink_post(int unit, struct sk_buff *skb);
 extern struct sock *netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len));
 extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
 extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
diff -Nru a/include/linux/netpoll.h b/include/linux/netpoll.h
--- a/include/linux/netpoll.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/netpoll.h	2005-01-19 13:44:46 -08:00
@@ -24,7 +24,6 @@
 };
 
 void netpoll_poll(struct netpoll *np);
-void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb);
 void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
 int netpoll_parse_options(struct netpoll *np, char *opt);
 int netpoll_setup(struct netpoll *np);
diff -Nru a/include/linux/nodemask.h b/include/linux/nodemask.h
--- a/include/linux/nodemask.h	2005-01-19 13:44:45 -08:00
+++ b/include/linux/nodemask.h	2005-01-19 13:44:45 -08:00
@@ -38,6 +38,8 @@
  *
  * int first_node(mask)			Number lowest set bit, or MAX_NUMNODES
  * int next_node(node, mask)		Next node past 'node', or MAX_NUMNODES
+ * int first_unset_node(mask)		First node not set in mask, or 
+ *					MAX_NUMNODES.
  *
  * nodemask_t nodemask_of_node(node)	Return nodemask with bit 'node' set
  * NODE_MASK_ALL			Initializer - all bits set
@@ -211,16 +213,19 @@
 	bitmap_shift_left(dstp->bits, srcp->bits, n, nbits);
 }
 
-#define first_node(src) __first_node(&(src), MAX_NUMNODES)
-static inline int __first_node(const nodemask_t *srcp, int nbits)
+/* FIXME: better would be to fix all architectures to never return
+          > MAX_NUMNODES, then the silly min_ts could be dropped. */
+
+#define first_node(src) __first_node(&(src))
+static inline int __first_node(const nodemask_t *srcp)
 {
-	return min_t(int, nbits, find_first_bit(srcp->bits, nbits));
+	return min_t(int, MAX_NUMNODES, find_first_bit(srcp->bits, MAX_NUMNODES));
 }
 
-#define next_node(n, src) __next_node((n), &(src), MAX_NUMNODES)
-static inline int __next_node(int n, const nodemask_t *srcp, int nbits)
+#define next_node(n, src) __next_node((n), &(src))
+static inline int __next_node(int n, const nodemask_t *srcp)
 {
-	return min_t(int, nbits, find_next_bit(srcp->bits, nbits, n+1));
+	return min_t(int,MAX_NUMNODES,find_next_bit(srcp->bits, MAX_NUMNODES, n+1));
 }
 
 #define nodemask_of_node(node)						\
@@ -234,6 +239,13 @@
 	}								\
 	m;								\
 })
+
+#define first_unset_node(mask) __first_unset_node(&(mask))
+static inline int __first_unset_node(const nodemask_t *maskp)
+{
+	return min_t(int,MAX_NUMNODES,
+			find_first_zero_bit(maskp->bits, MAX_NUMNODES));
+}
 
 #define NODE_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(MAX_NUMNODES)
 
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	2005-01-19 13:44:48 -08:00
+++ b/include/linux/pci_ids.h	2005-01-19 13:44:48 -08:00
@@ -353,8 +353,9 @@
 #define PCI_DEVICE_ID_ATI_RS300_166	0x5832
 #define PCI_DEVICE_ID_ATI_RS300_200	0x5833
 /* ATI IXP Chipset */
-#define PCI_DEVICE_ID_ATI_IXP_IDE	0x4349
-#define PCI_DEVICE_ID_ATI_IXP2_IDE	0x4369	/* True name not yet sure */
+#define PCI_DEVICE_ID_ATI_IXP200_IDE	0x4349
+#define PCI_DEVICE_ID_ATI_IXP300_IDE	0x4369
+#define PCI_DEVICE_ID_ATI_IXP400_IDE	0x4376
 
 #define PCI_VENDOR_ID_VLSI		0x1004
 #define PCI_DEVICE_ID_VLSI_82C592	0x0005
@@ -2178,6 +2179,7 @@
 #define PCI_DEVICE_ID_INTEL_82801CA_11	0x248b
 #define PCI_DEVICE_ID_INTEL_82801CA_12	0x248c
 #define PCI_DEVICE_ID_INTEL_82801DB_0	0x24c0
+#define PCI_DEVICE_ID_INTEL_82801DB_1	0x24c1
 #define PCI_DEVICE_ID_INTEL_82801DB_2	0x24c2
 #define PCI_DEVICE_ID_INTEL_82801DB_3	0x24c3
 #define PCI_DEVICE_ID_INTEL_82801DB_4	0x24c4
@@ -2244,7 +2246,7 @@
 #define PCI_DEVICE_ID_INTEL_ICH6_17	0x266d
 #define PCI_DEVICE_ID_INTEL_ICH6_18	0x266e
 #define PCI_DEVICE_ID_INTEL_ICH6_19	0x266f
-#define PCI_DEVICE_ID_INTEL_ICH7_0	0x27b0
+#define PCI_DEVICE_ID_INTEL_ICH7_0	0x27b8
 #define PCI_DEVICE_ID_INTEL_ICH7_1	0x27b1
 #define PCI_DEVICE_ID_INTEL_ICH7_2	0x27c0
 #define PCI_DEVICE_ID_INTEL_ICH7_3	0x27c1
diff -Nru a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/linux/pcieport_if.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,74 @@
+/*
+ * File:	pcieport_if.h
+ * Purpose:	PCI Express Port Bus Driver's IF Data Structure
+ *
+ * Copyright (C) 2004 Intel
+ * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ */
+
+#ifndef _PCIEPORT_IF_H_
+#define _PCIEPORT_IF_H_
+
+/* Port Type */
+#define PCIE_RC_PORT			4	/* Root port of RC */
+#define PCIE_SW_UPSTREAM_PORT		5	/* Upstream port of Switch */
+#define PCIE_SW_DOWNSTREAM_PORT		6	/* Downstream port of Switch */
+#define PCIE_ANY_PORT			7
+
+/* Service Type */
+#define PCIE_PORT_SERVICE_PME		1	/* Power Management Event */
+#define PCIE_PORT_SERVICE_AER		2	/* Advanced Error Reporting */
+#define PCIE_PORT_SERVICE_HP		4	/* Native Hotplug */
+#define PCIE_PORT_SERVICE_VC		8	/* Virtual Channel */
+
+/* Root/Upstream/Downstream Port's Interrupt Mode */
+#define PCIE_PORT_INTx_MODE		0
+#define PCIE_PORT_MSI_MODE		1
+#define PCIE_PORT_MSIX_MODE		2
+
+struct pcie_port_service_id {
+	__u32 vendor, device;		/* Vendor and device ID or PCI_ANY_ID*/
+	__u32 subvendor, subdevice;	/* Subsystem ID's or PCI_ANY_ID */
+	__u32 class, class_mask;	/* (class,subclass,prog-if) triplet */
+	__u32 port_type, service_type;	/* Port Entity */
+	kernel_ulong_t driver_data;
+};
+
+struct pcie_device {
+	int 		irq;	    /* Service IRQ/MSI/MSI-X Vector */
+	int 		interrupt_mode;	/* [0:INTx | 1:MSI | 2:MSI-X] */	
+	struct pcie_port_service_id id;	/* Service ID */
+	struct pci_dev	*port;	    /* Root/Upstream/Downstream Port */
+	void		*priv_data; /* Service Private Data */
+	struct device	device;     /* Generic Device Interface */
+};
+#define to_pcie_device(d) container_of(d, struct pcie_device, device)
+
+static inline void set_service_data(struct pcie_device *dev, void *data)
+{
+	dev->priv_data = data;
+}
+
+static inline void* get_service_data(struct pcie_device *dev)
+{
+	return dev->priv_data;
+}
+
+struct pcie_port_service_driver {
+	const char *name;
+	int (*probe) (struct pcie_device *dev, 
+		const struct pcie_port_service_id *id);
+	void (*remove) (struct pcie_device *dev);
+	int (*suspend) (struct pcie_device *dev, u32 state);
+	int (*resume) (struct pcie_device *dev);
+
+	const struct pcie_port_service_id *id_table;
+	struct device_driver driver;
+};
+#define to_service_driver(d) \
+	container_of(d, struct pcie_port_service_driver, driver)
+
+extern int pcie_port_service_register(struct pcie_port_service_driver *new);
+extern void pcie_port_service_unregister(struct pcie_port_service_driver *new);
+
+#endif /* _PCIEPORT_IF_H_ */
diff -Nru a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
--- a/include/linux/pipe_fs_i.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/pipe_fs_i.h	2005-01-19 13:44:47 -08:00
@@ -7,7 +7,15 @@
 
 struct pipe_buffer {
 	struct page *page;
-	unsigned short offset, len;
+	unsigned int offset, len;
+	struct pipe_buf_operations *ops;
+};
+
+struct pipe_buf_operations {
+	int can_merge;
+	void * (*map)(struct file *, struct pipe_inode_info *, struct pipe_buffer *);
+	void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *);
+	void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
 };
 
 struct pipe_inode_info {
diff -Nru a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
--- a/include/linux/pkt_cls.h	2005-01-19 13:44:45 -08:00
+++ b/include/linux/pkt_cls.h	2005-01-19 13:44:45 -08:00
@@ -249,6 +249,7 @@
 	TCA_RSVP_SRC,
 	TCA_RSVP_PINFO,
 	TCA_RSVP_POLICE,
+	TCA_RSVP_ACT,
 	__TCA_RSVP_MAX
 };
 
@@ -280,6 +281,7 @@
 	TCA_ROUTE4_FROM,
 	TCA_ROUTE4_IIF,
 	TCA_ROUTE4_POLICE,
+	TCA_ROUTE4_ACT,
 	__TCA_ROUTE4_MAX
 };
 
@@ -311,6 +313,7 @@
 	TCA_TCINDEX_FALL_THROUGH,
 	TCA_TCINDEX_CLASSID,
 	TCA_TCINDEX_POLICE,
+	TCA_TCINDEX_ACT,
 	__TCA_TCINDEX_MAX
 };
 
diff -Nru a/include/linux/random.h b/include/linux/random.h
--- a/include/linux/random.h	2005-01-19 13:44:48 -08:00
+++ b/include/linux/random.h	2005-01-19 13:44:48 -08:00
@@ -44,8 +44,8 @@
 
 extern void rand_initialize_irq(int irq);
 
-extern void add_keyboard_randomness(unsigned char scancode);
-extern void add_mouse_randomness(__u32 mouse_data);
+extern void add_input_randomness(unsigned int type, unsigned int code,
+				 unsigned int value);
 extern void add_interrupt_randomness(int irq);
 
 extern void get_random_bytes(void *buf, int nbytes);
diff -Nru a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
--- a/include/linux/rtnetlink.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/rtnetlink.h	2005-01-19 13:44:47 -08:00
@@ -748,6 +748,7 @@
 
 #include <linux/config.h>
 
+extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size);
 static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
 {
 	int len = strlen(str) + 1;
@@ -756,6 +757,9 @@
 
 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
 
+#define rtattr_parse_nested(tb, max, rta) \
+	rtattr_parse((tb), (max), RTA_DATA((rta)), RTA_PAYLOAD((rta)))
+
 extern struct sock *rtnl;
 
 struct rtnetlink_link
@@ -765,7 +769,6 @@
 };
 
 extern struct rtnetlink_link * rtnetlink_links[NPROTO];
-extern int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb);
 extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
 extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
 
@@ -806,6 +809,7 @@
 		        } while(0)
 
 extern void rtnl_lock(void);
+extern int rtnl_lock_interruptible(void);
 extern void rtnl_unlock(void);
 extern void rtnetlink_init(void);
 
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	2005-01-19 13:44:45 -08:00
+++ b/include/linux/sched.h	2005-01-19 13:44:45 -08:00
@@ -727,7 +727,7 @@
 #define PF_MEMDIE	0x00001000	/* Killed for out-of-memory */
 #define PF_FLUSHER	0x00002000	/* responsible for disk writeback */
 
-#define PF_FREEZE	0x00004000	/* this task should be frozen for suspend */
+#define PF_FREEZE	0x00004000	/* this task is being frozen for suspend now */
 #define PF_NOFREEZE	0x00008000	/* this thread should not be frozen */
 #define PF_FROZEN	0x00010000	/* frozen for system suspend */
 #define PF_FSTRANS	0x00020000	/* inside a filesystem transaction */
diff -Nru a/include/linux/sctp.h b/include/linux/sctp.h
--- a/include/linux/sctp.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/sctp.h	2005-01-19 13:44:47 -08:00
@@ -364,7 +364,7 @@
  */
 typedef struct sctp_abort_chunk {
         sctp_chunkhdr_t uh;
-} __attribute__((packed)) sctp_abort_chunkt_t;
+} __attribute__((packed)) sctp_abort_chunk_t;
 
 
 /* For the graceful shutdown we must carry the tag (in common header)
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/serial_core.h	2005-01-19 13:44:46 -08:00
@@ -100,6 +100,9 @@
 /* Motorola i.MX SoC */
 #define PORT_IMX	62
 
+/* Marvell MPSC */
+#define PORT_MPSC	63
+
 #ifdef __KERNEL__
 
 #include <linux/config.h>
diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h
--- a/include/linux/skbuff.h	2005-01-19 13:44:48 -08:00
+++ b/include/linux/skbuff.h	2005-01-19 13:44:48 -08:00
@@ -1086,14 +1086,9 @@
 					 int noblock, int *err);
 extern unsigned int    datagram_poll(struct file *file, struct socket *sock,
 				     struct poll_table_struct *wait);
-extern int	       skb_copy_datagram(const struct sk_buff *from,
-					 int offset, char __user *to, int size);
 extern int	       skb_copy_datagram_iovec(const struct sk_buff *from,
 					       int offset, struct iovec *to,
 					       int size);
-extern int	       skb_copy_and_csum_datagram(const struct sk_buff *skb,
-						  int offset, u8 __user *to,
-						  int len, unsigned int *csump);
 extern int	       skb_copy_and_csum_datagram_iovec(const
 							struct sk_buff *skb,
 							int hlen,
diff -Nru a/include/linux/socket.h b/include/linux/socket.h
--- a/include/linux/socket.h	2005-01-19 13:44:47 -08:00
+++ b/include/linux/socket.h	2005-01-19 13:44:47 -08:00
@@ -286,7 +286,6 @@
 
 extern int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode);
 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
-extern void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len);
 extern int move_addr_to_user(void *kaddr, int klen, void __user *uaddr, int __user *ulen);
 extern int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr);
 extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
diff -Nru a/include/linux/udp.h b/include/linux/udp.h
--- a/include/linux/udp.h	2005-01-19 13:44:46 -08:00
+++ b/include/linux/udp.h	2005-01-19 13:44:46 -08:00
@@ -40,26 +40,22 @@
 #include <net/sock.h>
 #include <linux/ip.h>
 
-struct udp_opt {
-	int		pending;	/* Any pending frames ? */
-	unsigned int	corkflag;	/* Cork is required */
-  	__u16		encap_type;	/* Is this an Encapsulation socket? */
+struct udp_sock {
+	/* inet_sock has to be the first member */
+	struct inet_sock inet;
+	int		 pending;	/* Any pending frames ? */
+	unsigned int	 corkflag;	/* Cork is required */
+  	__u16		 encap_type;	/* Is this an Encapsulation socket? */
 	/*
 	 * Following member retains the infomation to create a UDP header
 	 * when the socket is uncorked.
 	 */
-	__u16		len;		/* total length of pending frames */
-};
-
-/* WARNING: don't change the layout of the members in udp_sock! */
-struct udp_sock {
-	struct inet_sock  inet;
-	struct udp_opt	  udp;
+	__u16		 len;		/* total length of pending frames */
 };
 
-static inline struct udp_opt * udp_sk(const struct sock *__sk)
+static inline struct udp_sock *udp_sk(const struct sock *sk)
 {
-	return &((struct udp_sock *)__sk)->udp;
+	return (struct udp_sock *)sk;
 }
 
 #endif
diff -Nru a/include/net/addrconf.h b/include/net/addrconf.h
--- a/include/net/addrconf.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/addrconf.h	2005-01-19 13:44:47 -08:00
@@ -112,7 +112,6 @@
 
 extern int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr);
 extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr);
-extern int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
 extern int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr);
 
 
diff -Nru a/include/net/ax25.h b/include/net/ax25.h
--- a/include/net/ax25.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/ax25.h	2005-01-19 13:44:47 -08:00
@@ -238,6 +238,7 @@
 extern char *ax2asc(ax25_address *);
 extern ax25_address *asc2ax(char *);
 extern int  ax25cmp(ax25_address *, ax25_address *);
+extern int  ax25digicmp(ax25_digi *, ax25_digi *);
 extern unsigned char *ax25_addr_parse(unsigned char *, int, ax25_address *, ax25_address *, ax25_digi *, int *, int *);
 extern int  ax25_addr_build(unsigned char *, ax25_address *, ax25_address *, ax25_digi *, int, int);
 extern int  ax25_addr_size(ax25_digi *);
diff -Nru a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
--- a/include/net/bluetooth/hci_core.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/bluetooth/hci_core.h	2005-01-19 13:44:46 -08:00
@@ -277,7 +277,6 @@
 	return NULL;
 }
 
-void hci_acl_connect(struct hci_conn *conn);
 void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
 void hci_add_sco(struct hci_conn *conn, __u16 handle);
 
@@ -589,6 +588,5 @@
 #define hci_req_unlock(d)	up(&d->req_lock)
 
 void hci_req_complete(struct hci_dev *hdev, int result);
-void hci_req_cancel(struct hci_dev *hdev, int err);
 
 #endif /* __HCI_CORE_H */
diff -Nru a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
--- a/include/net/bluetooth/l2cap.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/bluetooth/l2cap.h	2005-01-19 13:44:46 -08:00
@@ -38,17 +38,19 @@
 	bdaddr_t	l2_bdaddr;
 };
 
-/* Socket options */
+/* L2CAP socket options */
 #define L2CAP_OPTIONS	0x01
 struct l2cap_options {
 	__u16 omtu;
 	__u16 imtu;
 	__u16 flush_to;
+	__u8  mode;
 };
 
-#define L2CAP_CONNINFO  0x02
+#define L2CAP_CONNINFO	0x02
 struct l2cap_conninfo {
 	__u16 hci_handle;
+	__u8  dev_class[3];
 };
 
 #define L2CAP_LM	0x03
@@ -59,20 +61,6 @@
 #define L2CAP_LM_RELIABLE	0x0010
 #define L2CAP_LM_SECURE		0x0020
 
-#define L2CAP_QOS	0x04
-struct l2cap_qos {
-	__u16 service_type;
-	__u32 token_rate;
-	__u32 token_bucket_size;
-	__u32 peak_bandwidth;
-	__u32 latency;
-	__u32 delay_variation;
-};
-
-#define L2CAP_SERV_NO_TRAFFIC	0x00
-#define L2CAP_SERV_BEST_EFFORT	0x01
-#define L2CAP_SERV_GUARANTEED	0x02
-
 /* L2CAP command codes */
 #define L2CAP_COMMAND_REJ 0x01
 #define L2CAP_CONN_REQ    0x02
@@ -154,6 +142,7 @@
 #define L2CAP_CONF_MTU		0x01
 #define L2CAP_CONF_FLUSH_TO	0x02
 #define L2CAP_CONF_QOS		0x03
+#define L2CAP_CONF_RFC		0x04
 
 #define L2CAP_CONF_MAX_SIZE	22
 
@@ -198,11 +187,11 @@
 
 	bdaddr_t	*dst;
 	bdaddr_t	*src;
-	
+
 	unsigned int	mtu;
 
 	spinlock_t	lock;
-	
+
 	struct sk_buff *rx_skb;
 	__u32		rx_len;
 	__u8		rx_ident;
@@ -222,7 +211,7 @@
 	__u16		imtu;
 	__u16		omtu;
 	__u16		flush_to;
-	
+
 	__u32		link_mode;
 
 	__u8		conf_state;
diff -Nru a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
--- a/include/net/bluetooth/rfcomm.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/bluetooth/rfcomm.h	2005-01-19 13:44:47 -08:00
@@ -181,6 +181,8 @@
 	u8            v24_sig;
 	u8            mscex;
 
+	u32           link_mode;
+
 	uint          mtu;
 	uint          cfc;
 	uint          rx_credits;
@@ -216,22 +218,6 @@
 #define RFCOMM_CFC_DISABLED 0
 #define RFCOMM_CFC_ENABLED  RFCOMM_MAX_CREDITS
 
-extern struct task_struct *rfcomm_thread;
-extern unsigned long rfcomm_event;
-
-static inline void rfcomm_schedule(uint event)
-{
-	if (!rfcomm_thread)
-		return;
-	//set_bit(event, &rfcomm_event);
-	set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-	wake_up_process(rfcomm_thread);
-}
-
-extern struct semaphore rfcomm_sem;
-#define rfcomm_lock()	down(&rfcomm_sem);
-#define rfcomm_unlock()	up(&rfcomm_sem);
-
 /* ---- RFCOMM DLCs (channels) ---- */
 struct rfcomm_dlc *rfcomm_dlc_alloc(int prio);
 void rfcomm_dlc_free(struct rfcomm_dlc *d);
@@ -271,11 +257,6 @@
 }
 
 /* ---- RFCOMM sessions ---- */
-struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
-struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
-struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
-void   rfcomm_session_del(struct rfcomm_session *s);
-void   rfcomm_session_close(struct rfcomm_session *s, int err);
 void   rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
 
 static inline void rfcomm_session_hold(struct rfcomm_session *s)
@@ -283,27 +264,36 @@
 	atomic_inc(&s->refcnt);
 }
 
-static inline void rfcomm_session_put(struct rfcomm_session *s)
-{
-	if (atomic_dec_and_test(&s->refcnt))
-		rfcomm_session_del(s);
-}
-
 /* ---- RFCOMM chechsum ---- */
 extern u8 rfcomm_crc_table[];
 
 /* ---- RFCOMM sockets ---- */
 struct sockaddr_rc {
-	sa_family_t rc_family;
-	bdaddr_t    rc_bdaddr;
-	u8          rc_channel;
+	sa_family_t	rc_family;
+	bdaddr_t	rc_bdaddr;
+	u8		rc_channel;
 };
 
+#define RFCOMM_CONNINFO	0x02
+struct rfcomm_conninfo {
+	__u16 hci_handle;
+	__u8  dev_class[3];
+};
+
+#define RFCOMM_LM	0x03
+#define RFCOMM_LM_MASTER	0x0001
+#define RFCOMM_LM_AUTH		0x0002
+#define RFCOMM_LM_ENCRYPT	0x0004
+#define RFCOMM_LM_TRUSTED	0x0008
+#define RFCOMM_LM_RELIABLE	0x0010
+#define RFCOMM_LM_SECURE	0x0020
+
 #define rfcomm_pi(sk)   ((struct rfcomm_pinfo *)sk->sk_protinfo)
 
 struct rfcomm_pinfo {
 	struct rfcomm_dlc   *dlc;
 	u8     channel;
+	u32    link_mode;
 };
 
 int  rfcomm_init_sockets(void);
diff -Nru a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h
--- a/include/net/bluetooth/sco.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/bluetooth/sco.h	2005-01-19 13:44:46 -08:00
@@ -39,15 +39,16 @@
 	bdaddr_t	sco_bdaddr;
 };
 
-/* set/get sockopt defines */
-#define SCO_OPTIONS  0x01
+/* SCO socket options */
+#define SCO_OPTIONS	0x01
 struct sco_options {
 	__u16 mtu;
 };
 
-#define SCO_CONNINFO  0x02
+#define SCO_CONNINFO	0x02
 struct sco_conninfo {
 	__u16 hci_handle;
+	__u8  dev_class[3];
 };
 
 /* ---- SCO connections ---- */
diff -Nru a/include/net/checksum.h b/include/net/checksum.h
--- a/include/net/checksum.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/checksum.h	2005-01-19 13:44:46 -08:00
@@ -27,7 +27,7 @@
 
 #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
 static inline
-unsigned int csum_and_copy_from_user (const char __user *src, char *dst,
+unsigned int csum_and_copy_from_user (const unsigned char __user *src, unsigned char *dst,
 				      int len, int sum, int *err_ptr)
 {
 	if (verify_area(VERIFY_READ, src, len) == 0)
@@ -42,7 +42,7 @@
 
 #ifndef HAVE_CSUM_COPY_USER
 static __inline__ unsigned int csum_and_copy_to_user
-(const char *src, char __user *dst, int len, unsigned int sum, int *err_ptr)
+(const unsigned char *src, unsigned char __user *dst, int len, unsigned int sum, int *err_ptr)
 {
 	sum = csum_partial(src, len, sum);
 
diff -Nru a/include/net/dn.h b/include/net/dn.h
--- a/include/net/dn.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/dn.h	2005-01-19 13:44:47 -08:00
@@ -220,8 +220,6 @@
 
 extern void dn_start_slow_timer(struct sock *sk);
 extern void dn_stop_slow_timer(struct sock *sk);
-extern void dn_start_fast_timer(struct sock *sk);
-extern void dn_stop_fast_timer(struct sock *sk);
 
 extern dn_address decnet_address;
 extern int decnet_debug_level;
diff -Nru a/include/net/dn_fib.h b/include/net/dn_fib.h
--- a/include/net/dn_fib.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/dn_fib.h	2005-01-19 13:44:46 -08:00
@@ -117,7 +117,6 @@
 extern void dn_fib_init(void);
 extern void dn_fib_cleanup(void);
 
-extern int dn_fib_rt_message(struct sk_buff *skb);
 extern int dn_fib_ioctl(struct socket *sock, unsigned int cmd, 
 			unsigned long arg);
 extern struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, 
diff -Nru a/include/net/icmp.h b/include/net/icmp.h
--- a/include/net/icmp.h	2005-01-19 13:44:48 -08:00
+++ b/include/net/icmp.h	2005-01-19 13:44:48 -08:00
@@ -46,16 +46,15 @@
 /* Move into dst.h ? */
 extern int 	xrlim_allow(struct dst_entry *dst, int timeout);
 
-struct raw_opt {
-	struct icmp_filter filter;
-};
-
-/* WARNING: don't change the layout of the members in raw_sock! */
 struct raw_sock {
-	struct inet_sock  inet;
-	struct raw_opt	  raw4;
+	/* inet_sock has to be the first member */
+	struct inet_sock   inet;
+	struct icmp_filter filter;
 };
 
-#define raw4_sk(__sk) (&((struct raw_sock *)__sk)->raw4)
+static inline struct raw_sock *raw_sk(const struct sock *sk)
+{
+	return (struct raw_sock *)sk;
+}
 
 #endif	/* _ICMP_H */
diff -Nru a/include/net/ip_vs.h b/include/net/ip_vs.h
--- a/include/net/ip_vs.h	2005-01-19 13:44:45 -08:00
+++ b/include/net/ip_vs.h	2005-01-19 13:44:45 -08:00
@@ -701,8 +701,6 @@
  *      (from ip_vs_core.c)
  */
 extern const char *ip_vs_proto_name(unsigned proto);
-extern unsigned int check_for_ip_vs_out(struct sk_buff **skb_p,
-					int (*okfn)(struct sk_buff *));
 extern void ip_vs_init_hash_table(struct list_head *table, int rows);
 #define IP_VS_INIT_HASH_TABLE(t) ip_vs_init_hash_table(t, sizeof(t)/sizeof(t[0]))
 
diff -Nru a/include/net/ipv6.h b/include/net/ipv6.h
--- a/include/net/ipv6.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/ipv6.h	2005-01-19 13:44:47 -08:00
@@ -229,8 +229,6 @@
 					       void (*destructor)(struct sock *));
 
 
-extern int			ip6_call_ra_chain(struct sk_buff *skb, int sel);
-
 extern int			ipv6_parse_hopopts(struct sk_buff *skb, int);
 
 extern struct ipv6_txoptions *  ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
diff -Nru a/include/net/iw_handler.h b/include/net/iw_handler.h
--- a/include/net/iw_handler.h	2005-01-19 13:44:48 -08:00
+++ b/include/net/iw_handler.h	2005-01-19 13:44:48 -08:00
@@ -418,9 +418,6 @@
  * Those may be called only within the kernel.
  */
 
-/* Data needed by fs/compat_ioctl.c for 32->64 bit conversion */
-extern const char iw_priv_type_size[];
-
 /* First : function strictly used inside the kernel */
 
 /* Handle /proc/net/wireless, called in net/code/dev.c */
diff -Nru a/include/net/pkt_act.h b/include/net/pkt_act.h
--- a/include/net/pkt_act.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/pkt_act.h	2005-01-19 13:44:47 -08:00
@@ -218,25 +218,22 @@
 
 #ifdef CONFIG_NET_ACT_INIT
 static inline struct tcf_st *
-tcf_hash_check(struct tc_st *parm, struct tc_action *a, int ovr, int bind)
+tcf_hash_check(u32 index, struct tc_action *a, int ovr, int bind)
 {
 	struct tcf_st *p = NULL;
-	if (parm->index && (p = tcf_hash_lookup(parm->index)) != NULL) {
-		spin_lock(&p->lock);
+	if (index && (p = tcf_hash_lookup(index)) != NULL) {
 		if (bind) {
 			p->bindcnt++;
 			p->refcnt++;
 		}
-		spin_unlock(&p->lock);
-		a->priv = (void *) p;
+		a->priv = p;
 	}
 	return p;
 }
 
 static inline struct tcf_st *
-tcf_hash_create(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind)
+tcf_hash_create(u32 index, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind)
 {
-	unsigned h;
 	struct tcf_st *p = NULL;
 
 	p = kmalloc(size, GFP_KERNEL);
@@ -252,31 +249,25 @@
 
 	spin_lock_init(&p->lock);
 	p->stats_lock = &p->lock;
-	p->index = parm->index ? : tcf_hash_new_index();
+	p->index = index ? : tcf_hash_new_index();
 	p->tm.install = jiffies;
 	p->tm.lastuse = jiffies;
 #ifdef CONFIG_NET_ESTIMATOR
 	if (est)
 		gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
 #endif
-	h = tcf_hash(p->index);
-	write_lock_bh(&tcf_t_lock);
-	p->next = tcf_ht[h];
-	tcf_ht[h] = p;
-	write_unlock_bh(&tcf_t_lock);
-
 	a->priv = (void *) p;
 	return p;
 }
 
-static inline struct tcf_st *
-tcf_hash_init(struct tc_st *parm, struct rtattr *est, struct tc_action *a, int size, int ovr, int bind)
+static inline void tcf_hash_insert(struct tcf_st *p)
 {
-	struct tcf_st *p = tcf_hash_check (parm,a,ovr,bind);
+	unsigned h = tcf_hash(p->index);
 
-	if (!p)
-		p = tcf_hash_create(parm, est, a, size, ovr, bind);
-	return p;
+	write_lock_bh(&tcf_t_lock);
+	p->next = tcf_ht[h];
+	tcf_ht[h] = p;
+	write_unlock_bh(&tcf_t_lock);
 }
 
 #endif
diff -Nru a/include/net/pkt_cls.h b/include/net/pkt_cls.h
--- a/include/net/pkt_cls.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/pkt_cls.h	2005-01-19 13:44:47 -08:00
@@ -17,7 +17,6 @@
 
 extern int register_tcf_proto_ops(struct tcf_proto_ops *ops);
 extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
-extern int ing_filter(struct sk_buff *skb);
 
 static inline unsigned long
 __cls_set_class(unsigned long *clp, unsigned long cl)
@@ -62,100 +61,99 @@
 		tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
 }
 
+struct tcf_exts
+{
 #ifdef CONFIG_NET_CLS_ACT
+	struct tc_action *action;
+#elif defined CONFIG_NET_CLS_POLICE
+	struct tcf_police *police;
+#endif
+};
+
+/* Map to export classifier specific extension TLV types to the
+ * generic extensions API. Unsupported extensions must be set to 0.
+ */
+struct tcf_ext_map
+{
+	int action;
+	int police;
+};
+
+/**
+ * tcf_exts_is_predicative - check if a predicative extension is present
+ * @exts: tc filter extensions handle
+ *
+ * Returns 1 if a predicative extension is present, i.e. an extension which
+ * might cause further actions and thus overrule the regular tcf_result.
+ */
 static inline int
-tcf_change_act_police(struct tcf_proto *tp, struct tc_action **action,
-	struct rtattr *act_police_tlv, struct rtattr *rate_tlv)
+tcf_exts_is_predicative(struct tcf_exts *exts)
 {
-	int ret;
-	struct tc_action *act;
-
-	act = tcf_action_init_1(act_police_tlv, rate_tlv, "police",
-	                        TCA_ACT_NOREPLACE, TCA_ACT_BIND, &ret);
-	if (act == NULL)
-		return ret;
-
-	act->type = TCA_OLD_COMPAT;
-
-	if (*action) {
-		tcf_tree_lock(tp);
-		act = xchg(action, act);
-		tcf_tree_unlock(tp);
-
-		tcf_action_destroy(act, TCA_ACT_UNBIND);
-	} else
-		*action = act;
-
-	return 0;
-}
-
+#ifdef CONFIG_NET_CLS_ACT
+	return !!exts->action;
+#elif defined CONFIG_NET_CLS_POLICE
+	return !!exts->police;
+#else
+	return 0;
+#endif
+}
+
+/**
+ * tcf_exts_is_available - check if at least one extension is present
+ * @exts: tc filter extensions handle
+ *
+ * Returns 1 if at least one extension is present.
+ */
+static inline int
+tcf_exts_is_available(struct tcf_exts *exts)
+{
+	/* All non-predicative extensions must be added here. */
+	return tcf_exts_is_predicative(exts);
+}
+
+/**
+ * tcf_exts_exec - execute tc filter extensions
+ * @skb: socket buffer
+ * @exts: tc filter extensions handle
+ * @res: desired result
+ *
+ * Executes all configured extensions. Returns 0 on a normal execution,
+ * a negative number if the filter must be considered unmatched or
+ * a positive action code (TC_ACT_*) which must be returned to the
+ * underlying layer.
+ */
 static inline int
-tcf_change_act(struct tcf_proto *tp, struct tc_action **action,
-	struct rtattr *act_tlv, struct rtattr *rate_tlv)
+tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
+	       struct tcf_result *res)
 {
-	int ret;
-	struct tc_action *act;
-
-	act = tcf_action_init(act_tlv, rate_tlv, NULL,
-	                      TCA_ACT_NOREPLACE, TCA_ACT_BIND, &ret);
-	if (act == NULL)
-		return ret;
-
-	if (*action) {
-		tcf_tree_lock(tp);
-		act = xchg(action, act);
-		tcf_tree_unlock(tp);
-
-		tcf_action_destroy(act, TCA_ACT_UNBIND);
-	} else
-		*action = act;
+#ifdef CONFIG_NET_CLS_ACT
+	if (exts->action)
+		return tcf_action_exec(skb, exts->action, res);
+#elif defined CONFIG_NET_CLS_POLICE
+	if (exts->police)
+		return tcf_police(skb, exts->police);
+#endif
 
 	return 0;
 }
 
-static inline int
-tcf_dump_act(struct sk_buff *skb, struct tc_action *action,
-	int act_type, int compat_type)
-{
-	/*
-	 * again for backward compatible mode - we want
-	 * to work with both old and new modes of entering
-	 * tc data even if iproute2  was newer - jhs
-	 */
-	if (action) {
-		struct rtattr * p_rta = (struct rtattr*) skb->tail;
-
-		if (action->type != TCA_OLD_COMPAT) {
-			RTA_PUT(skb, act_type, 0, NULL);
-			if (tcf_action_dump(skb, action, 0, 0) < 0)
-				goto rtattr_failure;
-		} else {
-			RTA_PUT(skb, compat_type, 0, NULL);
-			if (tcf_action_dump_old(skb, action, 0, 0) < 0)
-				goto rtattr_failure;
-		}
-		
-		p_rta->rta_len = skb->tail - (u8*)p_rta;
-	}
-	return 0;
-
-rtattr_failure:
-	return -1;
-}
-#endif /* CONFIG_NET_CLS_ACT */
+extern int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
+	                     struct rtattr *rate_tlv, struct tcf_exts *exts,
+	                     struct tcf_ext_map *map);
+extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
+extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
+	                     struct tcf_exts *src);
+extern int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
+	                 struct tcf_ext_map *map);
+extern int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
+	                       struct tcf_ext_map *map);
 
 #ifdef CONFIG_NET_CLS_IND
 static inline int
 tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
 {
-	if (RTA_PAYLOAD(indev_tlv) >= IFNAMSIZ) {
-		printk("cls: bad indev name %s\n", (char *) RTA_DATA(indev_tlv));
+	if (rtattr_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
 		return -EINVAL;
-	}
-
-	memset(indev, 0, IFNAMSIZ);
-	sprintf(indev, "%s", (char *) RTA_DATA(indev_tlv));
-
 	return 0;
 }
 
@@ -172,45 +170,5 @@
 	return 1;
 }
 #endif /* CONFIG_NET_CLS_IND */
-
-#ifdef CONFIG_NET_CLS_POLICE
-static inline int
-tcf_change_police(struct tcf_proto *tp, struct tcf_police **police,
-	struct rtattr *police_tlv, struct rtattr *rate_tlv)
-{
-	struct tcf_police *p = tcf_police_locate(police_tlv, rate_tlv);
-
-	if (*police) {
-		tcf_tree_lock(tp);
-		p = xchg(police, p);
-		tcf_tree_unlock(tp);
-
-		tcf_police_release(p, TCA_ACT_UNBIND);
-	} else
-		*police = p;
-
-	return 0;
-}
-
-static inline int
-tcf_dump_police(struct sk_buff *skb, struct tcf_police *police,
-	int police_type)
-{
-	if (police) {
-		struct rtattr * p_rta = (struct rtattr*) skb->tail;
-
-		RTA_PUT(skb, police_type, 0, NULL);
-
-		if (tcf_police_dump(skb, police) < 0)
-			goto rtattr_failure;
-
-		p_rta->rta_len = skb->tail - (u8*)p_rta;
-	}
-	return 0;
-
-rtattr_failure:
-	return -1;
-}
-#endif /* CONFIG_NET_CLS_POLICE */
 
 #endif
diff -Nru a/include/net/sctp/command.h b/include/net/sctp/command.h
--- a/include/net/sctp/command.h	2005-01-19 13:44:48 -08:00
+++ b/include/net/sctp/command.h	2005-01-19 13:44:48 -08:00
@@ -189,11 +189,6 @@
 } sctp_cmd_seq_t;
 
 
-/* Create a new sctp_command_sequence.
- * Return NULL if creating a new sequence fails.
- */
-sctp_cmd_seq_t *sctp_new_cmd_seq(int gfp);
-
 /* Initialize a block of memory as a command sequence.
  * Return 0 if the initialization fails.
  */
@@ -207,18 +202,10 @@
  */
 int sctp_add_cmd(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj);
 
-/* Rewind an sctp_cmd_seq_t to iterate from the start.
- * Return 0 if the rewind fails.
- */
-int sctp_rewind_sequence(sctp_cmd_seq_t *seq);
-
 /* Return the next command structure in an sctp_cmd_seq.
  * Return NULL at the end of the sequence.
  */
 sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq);
-
-/* Dispose of a command sequence.  */
-void sctp_free_cmd_seq(sctp_cmd_seq_t *seq);
 
 #endif /* __net_sctp_command_h__ */
 
diff -Nru a/include/net/sctp/constants.h b/include/net/sctp/constants.h
--- a/include/net/sctp/constants.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/sctp/constants.h	2005-01-19 13:44:46 -08:00
@@ -105,9 +105,10 @@
 
 typedef enum {
 	SCTP_EVENT_NO_PENDING_TSN = 0,
+	SCTP_EVENT_ICMP_PROTO_UNREACH,
 } sctp_event_other_t;
 
-#define SCTP_EVENT_OTHER_MAX		SCTP_EVENT_NO_PENDING_TSN
+#define SCTP_EVENT_OTHER_MAX		SCTP_EVENT_ICMP_PROTO_UNREACH
 #define SCTP_NUM_OTHER_TYPES		(SCTP_EVENT_OTHER_MAX + 1)
 
 /* These are primitive requests from the ULP.  */
@@ -155,10 +156,6 @@
 		       		- (unsigned long)(c->chunk_hdr)\
 				- sizeof(sctp_data_chunk_t)))
 
-/* This is a table of printable names of sctp_param_t's.  */
-extern const char *sctp_param_tbl[];
-
-
 #define SCTP_MAX_ERROR_CAUSE  SCTP_ERROR_NONEXIST_IP
 #define SCTP_NUM_ERROR_CAUSE  10
 
@@ -179,6 +176,7 @@
 	SCTP_IERROR_IGNORE_TSN,
 	SCTP_IERROR_NO_DATA,
 	SCTP_IERROR_BAD_STREAM,
+	SCTP_IERROR_BAD_PORTS,
 
 } sctp_ierror_t;
 
diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/sctp/sctp.h	2005-01-19 13:44:46 -08:00
@@ -162,17 +162,9 @@
 int sctp_rcv(struct sk_buff *skb);
 void sctp_v4_err(struct sk_buff *skb, u32 info);
 void sctp_hash_established(struct sctp_association *);
-void __sctp_hash_established(struct sctp_association *);
 void sctp_unhash_established(struct sctp_association *);
-void __sctp_unhash_established(struct sctp_association *);
 void sctp_hash_endpoint(struct sctp_endpoint *);
-void __sctp_hash_endpoint(struct sctp_endpoint *);
 void sctp_unhash_endpoint(struct sctp_endpoint *);
-void __sctp_unhash_endpoint(struct sctp_endpoint *);
-struct sctp_association *__sctp_lookup_association(
-	const union sctp_addr *,
-	const union sctp_addr *,
-	struct sctp_transport **);
 struct sock *sctp_err_lookup(int family, struct sk_buff *,
 			     struct sctphdr *, struct sctp_endpoint **,
 			     struct sctp_association **,
@@ -181,6 +173,10 @@
 			    struct sctp_association *);
 void sctp_icmp_frag_needed(struct sock *, struct sctp_association *,
 			   struct sctp_transport *t, __u32 pmtu);
+void sctp_icmp_proto_unreachable(struct sock *sk,
+				 struct sctp_endpoint *ep,
+				 struct sctp_association *asoc,
+				 struct sctp_transport *t);
 
 /*
  *  Section:  Macros, externs, and inlines
@@ -310,8 +306,6 @@
 
 int sctp_v6_init(void);
 void sctp_v6_exit(void);
-void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-			int type, int code, int offset, __u32 info);
 
 #else /* #ifdef defined(CONFIG_IPV6) */
 
@@ -455,7 +449,8 @@
 #define _sctp_walk_params(pos, chunk, end, member)\
 for (pos.v = chunk->member;\
      pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
-     pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)); \
+     pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\
+     ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
      pos.v += WORD_ROUND(ntohs(pos.p->length)))
 
 #define sctp_walk_errors(err, chunk_hdr)\
@@ -465,10 +460,9 @@
 for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
 	    sizeof(sctp_chunkhdr_t));\
      (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
-     (void *)err <= (void *)chunk_hdr + end - \
-		    WORD_ROUND(ntohs(err->length));\
-     err = (sctp_errhdr_t *)((void *)err + \
-	    WORD_ROUND(ntohs(err->length))))
+     (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\
+     ntohs(err->length) >= sizeof(sctp_errhdr_t); \
+     err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
 
 #define sctp_walk_fwdtsn(pos, chunk)\
 _sctp_walk_fwdtsn((pos), (chunk), ntohs((chunk)->chunk_hdr->length) - sizeof(struct sctp_fwdtsn_chunk))
diff -Nru a/include/net/sctp/sm.h b/include/net/sctp/sm.h
--- a/include/net/sctp/sm.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/sctp/sm.h	2005-01-19 13:44:46 -08:00
@@ -128,9 +128,9 @@
 sctp_state_fn_t sctp_sf_do_ecn_cwr;
 sctp_state_fn_t sctp_sf_do_ecne;
 sctp_state_fn_t sctp_sf_ootb;
-sctp_state_fn_t sctp_sf_shut_8_4_5;
 sctp_state_fn_t sctp_sf_pdiscard;
 sctp_state_fn_t sctp_sf_violation;
+sctp_state_fn_t sctp_sf_violation_chunklen;
 sctp_state_fn_t sctp_sf_discard_chunk;
 sctp_state_fn_t sctp_sf_do_5_2_1_siminit;
 sctp_state_fn_t sctp_sf_do_5_2_2_dupinit;
@@ -138,7 +138,6 @@
 sctp_state_fn_t sctp_sf_unk_chunk;
 sctp_state_fn_t sctp_sf_do_8_5_1_E_sa;
 sctp_state_fn_t sctp_sf_cookie_echoed_err;
-sctp_state_fn_t sctp_sf_do_5_2_6_stale;
 sctp_state_fn_t sctp_sf_do_asconf;
 sctp_state_fn_t sctp_sf_do_asconf_ack;
 sctp_state_fn_t sctp_sf_do_9_2_reshutack;
@@ -167,6 +166,7 @@
 sctp_state_fn_t sctp_sf_do_9_2_start_shutdown;
 sctp_state_fn_t sctp_sf_do_9_2_shutdown_ack;
 sctp_state_fn_t sctp_sf_ignore_other;
+sctp_state_fn_t sctp_sf_cookie_wait_icmp_abort;
 
 /* Prototypes for timeout event state functions.  */
 sctp_state_fn_t sctp_sf_do_6_3_3_rtx;
@@ -200,19 +200,10 @@
 struct sctp_chunk *sctp_make_cwr(const struct sctp_association *,
 				 const __u32 lowest_tsn,
 				 const struct sctp_chunk *);
-struct sctp_chunk *sctp_make_datafrag(struct sctp_association *,
-				 const struct sctp_sndrcvinfo *sinfo,
-				 int len, const __u8 *data,
-				 __u8 flags, __u16 ssn);
 struct sctp_chunk * sctp_make_datafrag_empty(struct sctp_association *,
 					const struct sctp_sndrcvinfo *sinfo,
 					int len, const __u8 flags,
 					__u16 ssn);
-struct sctp_chunk *sctp_make_data(struct sctp_association *,
-			     const struct sctp_sndrcvinfo *sinfo,
-			     int len, const __u8 *data);
-struct sctp_chunk *sctp_make_data_empty(struct sctp_association *,
-				   const struct sctp_sndrcvinfo *, int len);
 struct sctp_chunk *sctp_make_ecne(const struct sctp_association *,
 				  const __u32);
 struct sctp_chunk *sctp_make_sack(const struct sctp_association *);
@@ -232,6 +223,10 @@
 struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *,
 				   const struct sctp_chunk *,
 				   const struct msghdr *);
+struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
+				   const struct sctp_chunk *,
+				   const __u8 *,
+				   const size_t );
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
 				  const struct sctp_transport *,
 				  const void *payload,
@@ -246,17 +241,12 @@
 				 const void *payload,
 				 size_t paylen);
 
-struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
-				    union sctp_addr *addr,
-				    int vparam_len);
 struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
 					      union sctp_addr *,
 					      struct sockaddr *,
 					      int, __u16);
 struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
 					     union sctp_addr *addr);
-struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
-					__u32 serial, int vparam_len);
 struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
 				       struct sctp_chunk *asconf);
 int sctp_process_asconf_ack(struct sctp_association *asoc,
@@ -268,6 +258,8 @@
 void sctp_chunk_assign_tsn(struct sctp_chunk *);
 void sctp_chunk_assign_ssn(struct sctp_chunk *);
 
+void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error);
+
 /* Prototypes for statetable processing. */
 
 int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
@@ -277,70 +269,25 @@
                void *event_arg,
                int gfp);
 
-int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
-		      sctp_state_t state,
-                      struct sctp_endpoint *,
-                      struct sctp_association *asoc,
-                      void *event_arg,
-                      sctp_disposition_t status,
-		      sctp_cmd_seq_t *commands,
-                      int gfp);
-
 /* 2nd level prototypes */
-int sctp_cmd_interpreter(sctp_event_t, sctp_subtype_t, sctp_state_t,
-			 struct sctp_endpoint *, struct sctp_association *,
-			 void *event_arg, sctp_disposition_t,
-			 sctp_cmd_seq_t *retval, int gfp);
-
-
-int sctp_gen_sack(struct sctp_association *, int force, sctp_cmd_seq_t *);
 void sctp_generate_t3_rtx_event(unsigned long peer);
 void sctp_generate_heartbeat_event(unsigned long peer);
 
-sctp_sackhdr_t *sctp_sm_pull_sack(struct sctp_chunk *);
-struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *,
-				       const struct sctp_association *,
-				       struct sctp_chunk *chunk,
-				       const void *payload,
-				       size_t paylen);
-struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *,
-				      const struct sctp_chunk *);
 void sctp_ootb_pkt_free(struct sctp_packet *);
 
-struct sctp_cookie_param *
-sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *,
-		 const struct sctp_chunk *, int *cookie_len,
-		 const __u8 *, int addrs_len);
 struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *,
 				       const struct sctp_association *,
 				       struct sctp_chunk *, int gfp, int *err,
 				       struct sctp_chunk **err_chk_p);
 int sctp_addip_addr_config(struct sctp_association *, sctp_param_t,
 			   struct sockaddr_storage*, int);
-void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
-				const struct sctp_association *asoc,
-				const struct sctp_chunk *chunk,
-				sctp_cmd_seq_t *commands,
-				struct sctp_chunk *err_chunk);
-int sctp_eat_data(const struct sctp_association *asoc,
-		  struct sctp_chunk *chunk,
-		  sctp_cmd_seq_t *commands);
 
 /* 3rd level prototypes */
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
 /* Extern declarations for major data structures.  */
-const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t);
-extern const sctp_sm_table_entry_t
-primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
-extern const sctp_sm_table_entry_t
-other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
-extern const sctp_sm_table_entry_t
-timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
 extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES];
-
-/* These are some handy utility macros... */
 
 
 /* Get the size of a DATA chunk payload. */
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h	2005-01-19 13:44:48 -08:00
+++ b/include/net/sctp/structs.h	2005-01-19 13:44:48 -08:00
@@ -322,10 +322,19 @@
 	/* This holds the originating address of the INIT packet.  */
 	union sctp_addr peer_addr;
 
+	/* IG Section 2.35.3 
+	 * Include the source port of the INIT-ACK
+	 */
+	__u16		my_port;
+
 	__u8 prsctp_capable;
 
+	/* Padding for future use */
+	__u8 padding;  		
+
 	__u32 adaption_ind;	
 
+
 	/* This is a shim for my peer's INIT packet, followed by
 	 * a copy of the raw address list of the association.
 	 * The length of the raw address list is saved in the
@@ -406,7 +415,6 @@
 	int malloced;
 };
 
-struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *, __u16, __u16);
 struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp);
 void sctp_ssnmap_free(struct sctp_ssnmap *map);
 void sctp_ssnmap_clear(struct sctp_ssnmap *map);
@@ -538,12 +546,9 @@
 struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
 					    struct sctp_sndrcvinfo *,
 					    struct msghdr *, int len);
-struct sctp_datamsg *sctp_datamsg_new(int gfp);
 void sctp_datamsg_put(struct sctp_datamsg *);
-void sctp_datamsg_hold(struct sctp_datamsg *);
 void sctp_datamsg_free(struct sctp_datamsg *);
 void sctp_datamsg_track(struct sctp_chunk *);
-void sctp_datamsg_assign(struct sctp_datamsg *, struct sctp_chunk *);
 void sctp_chunk_fail(struct sctp_chunk *, int error);
 int sctp_chunk_abandoned(struct sctp_chunk *);
 
@@ -651,8 +656,6 @@
 void sctp_chunk_put(struct sctp_chunk *);
 int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len,
 			  struct iovec *data);
-struct sctp_chunk *sctp_make_chunk(const struct sctp_association *, __u8 type,
-				   __u8 flags, int size);
 void sctp_chunk_free(struct sctp_chunk *);
 void  *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
 struct sctp_chunk *sctp_chunkify(struct sk_buff *,
@@ -853,12 +856,6 @@
 	/* Error count : The current error count for this destination.	*/
 	unsigned short error_count;
 
-	/* Error       : Current error threshold for this destination
-	 * Threshold   : i.e. what value marks the destination down if
-	 *	       : errorCount reaches this value.
-	 */
-	unsigned short error_threshold;
-
 	/* This is the max_retrans value for the transport and will
 	 * be initialized to proto.max_retrans.path.  This can be changed
 	 * using SCTP_SET_PEER_ADDR_PARAMS socket option.
@@ -922,15 +919,12 @@
 };
 
 struct sctp_transport *sctp_transport_new(const union sctp_addr *, int);
-struct sctp_transport *sctp_transport_init(struct sctp_transport *,
-					   const union sctp_addr *, int);
 void sctp_transport_set_owner(struct sctp_transport *,
 			      struct sctp_association *);
 void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
 			  struct sctp_opt *);
 void sctp_transport_pmtu(struct sctp_transport *);
 void sctp_transport_free(struct sctp_transport *);
-void sctp_transport_destroy(struct sctp_transport *);
 void sctp_transport_reset_timers(struct sctp_transport *);
 void sctp_transport_hold(struct sctp_transport *);
 void sctp_transport_put(struct sctp_transport *);
@@ -961,7 +955,6 @@
 	int malloced;	     /* Is this structure kfree()able?	*/
 };
 
-struct sctp_inq *sctp_inq_new(void);
 void sctp_inq_init(struct sctp_inq *);
 void sctp_inq_free(struct sctp_inq *);
 void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet);
@@ -1029,7 +1022,6 @@
 	char malloced;
 };
 
-struct sctp_outq *sctp_outq_new(struct sctp_association *);
 void sctp_outq_init(struct sctp_association *, struct sctp_outq *);
 void sctp_outq_teardown(struct sctp_outq *);
 void sctp_outq_free(struct sctp_outq*);
@@ -1070,7 +1062,6 @@
 	int malloced;	     /* Are we kfree()able?  */
 };
 
-struct sctp_bind_addr *sctp_bind_addr_new(int gfp_mask);
 void sctp_bind_addr_init(struct sctp_bind_addr *, __u16 port);
 void sctp_bind_addr_free(struct sctp_bind_addr *);
 int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
@@ -1220,8 +1211,6 @@
 
 /* These are function signatures for manipulating endpoints.  */
 struct sctp_endpoint *sctp_endpoint_new(struct sock *, int);
-struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *,
-					 struct sock *, int gfp);
 void sctp_endpoint_free(struct sctp_endpoint *);
 void sctp_endpoint_put(struct sctp_endpoint *);
 void sctp_endpoint_hold(struct sctp_endpoint *);
@@ -1243,8 +1232,6 @@
 int sctp_process_init(struct sctp_association *, sctp_cid_t cid,
 		      const union sctp_addr *peer,
 		      sctp_init_chunk_t *init, int gfp);
-int sctp_process_param(struct sctp_association *, union sctp_params param,
-		       const union sctp_addr *from, int gfp);
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
@@ -1690,10 +1677,6 @@
 struct sctp_association *
 sctp_association_new(const struct sctp_endpoint *, const struct sock *,
 		     sctp_scope_t scope, int gfp);
-struct sctp_association *
-sctp_association_init(struct sctp_association *, const struct sctp_endpoint *,
-		      const struct sock *, sctp_scope_t scope,
-		      int gfp);
 void sctp_association_free(struct sctp_association *);
 void sctp_association_put(struct sctp_association *);
 void sctp_association_hold(struct sctp_association *);
@@ -1722,7 +1705,6 @@
 		       struct sctp_association *new);
 
 __u32 sctp_association_get_next_tsn(struct sctp_association *);
-__u32 sctp_association_get_tsn_block(struct sctp_association *, int);
 
 void sctp_assoc_sync_pmtu(struct sctp_association *);
 void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
@@ -1736,7 +1718,6 @@
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
 			const union sctp_addr *ss2);
 struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc);
-struct sctp_chunk *sctp_get_no_prepend(struct sctp_association *asoc);
 
 /* A convenience structure to parse out SCTP specific CMSGs. */
 typedef struct sctp_cmsgs {
diff -Nru a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h
--- a/include/net/sctp/tsnmap.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/sctp/tsnmap.h	2005-01-19 13:44:47 -08:00
@@ -120,12 +120,6 @@
 	__u32 start;
 };
 
-/* Create a new tsnmap.  */
-struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 init_tsn, int gfp);
-
-/* Dispose of a tsnmap.  */
-void sctp_tsnmap_free(struct sctp_tsnmap *);
-
 /* This macro assists in creation of external storage for variable length
  * internal buffers.  We double allocate so the overflow map works.
  */
@@ -209,15 +203,5 @@
 
 /* Is there a gap in the TSN map? */
 int sctp_tsnmap_has_gap(const struct sctp_tsnmap *);
-
-/* Initialize a gap ack block interator from user-provided memory.  */
-void sctp_tsnmap_iter_init(const struct sctp_tsnmap *,
-			   struct sctp_tsnmap_iter *);
-
-/* Get the next gap ack blocks.  We return 0 if there are no more
- * gap ack blocks.
- */
-int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *,
-	struct sctp_tsnmap_iter *,__u16 *start, __u16 *end);
 
 #endif /* __sctp_tsnmap_h__ */
diff -Nru a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
--- a/include/net/sctp/ulpevent.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/sctp/ulpevent.h	2005-01-19 13:44:46 -08:00
@@ -77,8 +77,6 @@
 	return (struct sctp_ulpevent *)skb->cb;
 }
 
-struct sctp_ulpevent *sctp_ulpevent_new(int size, int flags, int gfp);
-void sctp_ulpevent_init(struct sctp_ulpevent *, int flags);
 void sctp_ulpevent_free(struct sctp_ulpevent *);
 int sctp_ulpevent_is_notification(const struct sctp_ulpevent *);
 void sctp_queue_purge_ulpevents(struct sk_buff_head *list);
diff -Nru a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
--- a/include/net/sctp/ulpqueue.h	2005-01-19 13:44:46 -08:00
+++ b/include/net/sctp/ulpqueue.h	2005-01-19 13:44:46 -08:00
@@ -57,7 +57,6 @@
 };
 
 /* Prototypes. */
-struct sctp_ulpq *sctp_ulpq_new(struct sctp_association *asoc, int gfp);
 struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *,
 				 struct sctp_association *);
 void sctp_ulpq_free(struct sctp_ulpq *);
diff -Nru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/sock.h	2005-01-19 13:44:47 -08:00
@@ -733,11 +733,6 @@
 						     unsigned long size,
 						     int noblock,
 						     int *errcode);
-extern struct sk_buff 		*sock_alloc_send_pskb(struct sock *sk,
-						      unsigned long header_len,
-						      unsigned long data_len,
-						      int noblock,
-						      int *errcode);
 extern void *sock_kmalloc(struct sock *sk, int size, int priority);
 extern void sock_kfree_s(struct sock *sk, void *mem, int size);
 extern void sk_send_sigurg(struct sock *sk);
@@ -795,8 +790,6 @@
  *	Default socket callbacks and setup code
  */
  
-extern void sock_def_destruct(struct sock *);
-
 /* Initialise core socket variables */
 extern void sock_init_data(struct socket *sock, struct sock *sk);
 
diff -Nru a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h
--- a/include/net/tc_act/tc_pedit.h	2005-01-19 13:44:47 -08:00
+++ b/include/net/tc_act/tc_pedit.h	2005-01-19 13:44:47 -08:00
@@ -8,7 +8,7 @@
 	tca_gen(pedit);
 	unsigned char           nkeys;
 	unsigned char           flags;
-	struct tc_pedit_key     keys[0];
+	struct tc_pedit_key     *keys;
 };
 
 #endif
diff -Nru a/include/pcmcia/cs.h b/include/pcmcia/cs.h
--- a/include/pcmcia/cs.h	2005-01-19 13:44:45 -08:00
+++ b/include/pcmcia/cs.h	2005-01-19 13:44:45 -08:00
@@ -191,7 +191,7 @@
 typedef struct irq_req_t {
     u_int	Attributes;
     u_int	AssignedIRQ;
-    u_int	IRQInfo1, IRQInfo2;
+    u_int	IRQInfo1, IRQInfo2; /* IRQInfo2 is ignored */
     void	*Handler;
     void	*Instance;
 } irq_req_t;
diff -Nru a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
--- a/include/scsi/scsi_dbg.h	2005-01-19 13:44:48 -08:00
+++ b/include/scsi/scsi_dbg.h	2005-01-19 13:44:48 -08:00
@@ -8,6 +8,9 @@
 extern void __scsi_print_command(unsigned char *);
 extern void scsi_print_sense(const char *, struct scsi_cmnd *);
 extern void scsi_print_req_sense(const char *, struct scsi_request *);
+extern void __scsi_print_sense(const char *name,
+			       const unsigned char *sense_buffer,
+			       int sense_len);
 extern void scsi_print_driverbyte(int);
 extern void scsi_print_hostbyte(int);
 extern void scsi_print_status(unsigned char);
diff -Nru a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
--- a/include/scsi/scsi_device.h	2005-01-19 13:44:45 -08:00
+++ b/include/scsi/scsi_device.h	2005-01-19 13:44:45 -08:00
@@ -172,6 +172,8 @@
 					      uint, uint, uint);
 extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *,
 						uint, uint, uint);
+extern void starget_for_each_device(struct scsi_target *, void *,
+		     void (*fn)(struct scsi_device *, void *));
 
 /* only exposed to implement shost_for_each_device */
 extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
diff -Nru a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
--- a/include/scsi/scsi_transport_fc.h	2005-01-19 13:44:46 -08:00
+++ b/include/scsi/scsi_transport_fc.h	2005-01-19 13:44:46 -08:00
@@ -185,6 +185,8 @@
 
 #define FC_FC4_LIST_SIZE		32
 #define FC_SYMBOLIC_NAME_SIZE		256
+#define FC_VERSION_STRING_SIZE		64
+#define FC_SERIAL_NUMBER_SIZE		80
 
 struct fc_host_attrs {
 	/* Fixed Attributes */
@@ -195,6 +197,11 @@
 	char symbolic_name[FC_SYMBOLIC_NAME_SIZE];
 	u32 supported_speeds;
 	u32 maxframe_size;
+	char hardware_version[FC_VERSION_STRING_SIZE];
+	char firmware_version[FC_VERSION_STRING_SIZE];
+	char serial_number[FC_SERIAL_NUMBER_SIZE];
+	char opt_rom_version[FC_VERSION_STRING_SIZE];
+	char driver_version[FC_VERSION_STRING_SIZE];
 
 	/* Dynamic Attributes */
 	u32 port_id;
@@ -226,6 +233,16 @@
 	(((struct fc_host_attrs *)(x)->shost_data)->supported_speeds)
 #define fc_host_maxframe_size(x)	\
 	(((struct fc_host_attrs *)(x)->shost_data)->maxframe_size)
+#define fc_host_hardware_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->hardware_version)
+#define fc_host_firmware_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->firmware_version)
+#define fc_host_serial_number(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->serial_number)
+#define fc_host_opt_rom_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->opt_rom_version)
+#define fc_host_driver_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->driver_version)
 #define fc_host_port_id(x)	\
 	(((struct fc_host_attrs *)(x)->shost_data)->port_id)
 #define fc_host_port_type(x)	\
@@ -285,6 +302,11 @@
 	unsigned long	show_host_symbolic_name:1;
 	unsigned long	show_host_supported_speeds:1;
 	unsigned long	show_host_maxframe_size:1;
+	unsigned long	show_host_hardware_version:1;
+	unsigned long	show_host_firmware_version:1;
+	unsigned long	show_host_serial_number:1;
+	unsigned long	show_host_opt_rom_version:1;
+	unsigned long	show_host_driver_version:1;
 	/* host dynamic attributes */
 	unsigned long	show_host_port_id:1;
 	unsigned long	show_host_port_type:1;
diff -Nru a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h	2005-01-19 13:44:46 -08:00
+++ b/include/sound/ac97_codec.h	2005-01-19 13:44:46 -08:00
@@ -426,6 +426,7 @@
 	int (*build_spdif) (ac97_t *ac97);
 	int (*build_post_spdif) (ac97_t *ac97);
 #ifdef CONFIG_PM
+	void (*suspend) (ac97_t *ac97);
 	void (*resume) (ac97_t *ac97);
 #endif
 };
diff -Nru a/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h	2005-01-19 13:44:48 -08:00
+++ b/include/sound/version.h	2005-01-19 13:44:48 -08:00
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.8rc2"
-#define CONFIG_SND_DATE " (Wed Jan 05 06:44:40 2005 UTC)"
+#define CONFIG_SND_VERSION "1.0.8"
+#define CONFIG_SND_DATE " (Thu Jan 13 09:39:32 2005 UTC)"
diff -Nru a/include/video/w100fb.h b/include/video/w100fb.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/include/video/w100fb.h	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,21 @@
+/*
+ *  Support for the w100 frame buffer.
+ *
+ *  Copyright (c) 2004 Richard Purdie
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+/*
+ * This structure describes the machine which we are running on.
+ * It is set by machine specific code and used in the probe routine
+ * of drivers/video/w100fb.c
+ */
+
+struct w100fb_mach_info {
+	void (*w100fb_ssp_send)(u8 adrs, u8 data);
+	int comadj;
+	int phadadj;
+};
diff -Nru a/kernel/compat.c b/kernel/compat.c
--- a/kernel/compat.c	2005-01-19 13:44:46 -08:00
+++ b/kernel/compat.c	2005-01-19 13:44:46 -08:00
@@ -701,7 +701,7 @@
 }
 
 asmlinkage long
-compat_rt_sigtimedwait (compat_sigset_t __user *uthese,
+compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
 		struct compat_siginfo __user *uinfo,
 		struct compat_timespec __user *uts, compat_size_t sigsetsize)
 {
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	2005-01-19 13:44:47 -08:00
+++ b/kernel/exit.c	2005-01-19 13:44:47 -08:00
@@ -747,7 +747,9 @@
 	}
 
 	state = EXIT_ZOMBIE;
-	if (tsk->exit_signal == -1 && tsk->ptrace == 0)
+	if (tsk->exit_signal == -1 &&
+	    (likely(tsk->ptrace == 0) ||
+	     unlikely(tsk->parent->signal->flags & SIGNAL_GROUP_EXIT)))
 		state = EXIT_DEAD;
 	tsk->exit_state = state;
 
diff -Nru a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
--- a/kernel/irq/autoprobe.c	2005-01-19 13:44:46 -08:00
+++ b/kernel/irq/autoprobe.c	2005-01-19 13:44:46 -08:00
@@ -137,6 +137,7 @@
 
 	return mask & val;
 }
+EXPORT_SYMBOL(probe_irq_mask);
 
 /**
  *	probe_irq_off	- end an interrupt autodetect
diff -Nru a/kernel/power/Kconfig b/kernel/power/Kconfig
--- a/kernel/power/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/kernel/power/Kconfig	2005-01-19 13:44:47 -08:00
@@ -48,7 +48,7 @@
 	  involved in suspending. Also in this case there is a risk that buffers
 	  on disk won't match with saved ones.
 
-	  For more information take a look at Documentation/power/swsusp.txt.
+	  For more information take a look at <file:Documentation/power/swsusp.txt>.
 
 config PM_STD_PARTITION
 	string "Default resume partition"
diff -Nru a/kernel/power/disk.c b/kernel/power/disk.c
--- a/kernel/power/disk.c	2005-01-19 13:44:45 -08:00
+++ b/kernel/power/disk.c	2005-01-19 13:44:45 -08:00
@@ -51,7 +51,7 @@
 	local_irq_save(flags);
 	switch(mode) {
 	case PM_DISK_PLATFORM:
-		device_power_down(PM_SUSPEND_DISK);
+ 		device_power_down(PMSG_SUSPEND);
 		error = pm_ops->enter(PM_SUSPEND_DISK);
 		break;
 	case PM_DISK_SHUTDOWN:
@@ -144,8 +144,10 @@
 	free_some_memory();
 
 	disable_nonboot_cpus();
-	if ((error = device_suspend(PM_SUSPEND_DISK)))
+	if ((error = device_suspend(PMSG_FREEZE))) {
+		printk("Some devices failed to suspend\n");
 		goto Finish;
+	}
 
 	return 0;
  Finish:
@@ -163,7 +165,7 @@
  *
  *	If we're going through the firmware, then get it over with quickly.
  *
- *	If not, then call swsusp to do it's thing, then figure out how
+ *	If not, then call swsusp to do its thing, then figure out how
  *	to power down the system.
  */
 
@@ -201,7 +203,7 @@
  *	software_resume - Resume from a saved image.
  *
  *	Called as a late_initcall (so all devices are discovered and
- *	initialized), we call pmdisk to see if we have a saved image or not.
+ *	initialized), we call swsusp to see if we have a saved image or not.
  *	If so, we quiesce devices, the restore the saved image. We will
  *	return above (in pm_suspend_disk() ) if everything goes well.
  *	Otherwise, we fail gracefully and return to the normally
@@ -221,7 +223,7 @@
 		return 0;
 	}
 
-	pr_debug("PM: Reading pmdisk image.\n");
+	pr_debug("PM: Reading swsusp image.\n");
 
 	if ((error = swsusp_read()))
 		goto Done;
@@ -284,7 +286,7 @@
 
 static ssize_t disk_show(struct subsystem * subsys, char * buf)
 {
-	return sprintf(buf,"%s\n",pm_disk_modes[pm_disk_mode]);
+	return sprintf(buf, "%s\n", pm_disk_modes[pm_disk_mode]);
 }
 
 
diff -Nru a/kernel/power/main.c b/kernel/power/main.c
--- a/kernel/power/main.c	2005-01-19 13:44:46 -08:00
+++ b/kernel/power/main.c	2005-01-19 13:44:46 -08:00
@@ -65,7 +65,7 @@
 			goto Thaw;
 	}
 
-	if ((error = device_suspend(state)))
+	if ((error = device_suspend(PMSG_SUSPEND)))
 		goto Finish;
 	return 0;
  Finish:
@@ -78,13 +78,14 @@
 }
 
 
-static int suspend_enter(u32 state)
+static int suspend_enter(suspend_state_t state)
 {
 	int error = 0;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	if ((error = device_power_down(state)))
+
+	if ((error = device_power_down(PMSG_SUSPEND)))
 		goto Done;
 	error = pm_ops->enter(state);
 	device_power_up();
@@ -99,7 +100,7 @@
  *	@state:		State we're coming out of.
  *
  *	Call platform code to clean up, restart processes, and free the 
- *	console that we've allocated.
+ *	console that we've allocated. This is not called for suspend-to-disk.
  */
 
 static void suspend_finish(suspend_state_t state)
diff -Nru a/kernel/power/swsusp.c b/kernel/power/swsusp.c
--- a/kernel/power/swsusp.c	2005-01-19 13:44:46 -08:00
+++ b/kernel/power/swsusp.c	2005-01-19 13:44:46 -08:00
@@ -420,7 +420,7 @@
 	struct highmem_page *next;
 };
 
-struct highmem_page *highmem_copy = NULL;
+static struct highmem_page *highmem_copy;
 
 static int save_highmem_zone(struct zone *zone)
 {
@@ -753,11 +753,11 @@
 		return -ENOSPC;
 
 	if ((error = alloc_pagedir())) {
-		pr_debug("suspend: Allocating pagedir failed.\n");
+		printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
 		return error;
 	}
 	if ((error = alloc_image_pages())) {
-		pr_debug("suspend: Allocating image pages failed.\n");
+		printk(KERN_ERR "suspend: Allocating image pages failed.\n");
 		swsusp_free();
 		return error;
 	}
@@ -767,7 +767,7 @@
 	return 0;
 }
 
-int suspend_prepare_image(void)
+static int suspend_prepare_image(void)
 {
 	int error;
 
@@ -849,7 +849,7 @@
 	 * become desynchronized with the actual state of the hardware
 	 * at resume time, and evil weirdness ensues.
 	 */
-	if ((error = device_power_down(PM_SUSPEND_DISK))) {
+	if ((error = device_power_down(PMSG_FREEZE))) {
 		local_irq_enable();
 		return error;
 	}
@@ -878,7 +878,7 @@
 {
 	int error;
 	local_irq_disable();
-	device_power_down(PM_SUSPEND_DISK);
+	device_power_down(PMSG_FREEZE);
 	/* We'll ignore saved state, but this gets preempt count (etc) right */
 	save_processor_state();
 	error = swsusp_arch_resume();
@@ -1050,12 +1050,12 @@
 	return error;
 }
 
-int bio_read_page(pgoff_t page_off, void * page)
+static int bio_read_page(pgoff_t page_off, void * page)
 {
 	return submit(READ, page_off, page);
 }
 
-int bio_write_page(pgoff_t page_off, void * page)
+static int bio_write_page(pgoff_t page_off, void * page)
 {
 	return submit(WRITE, page_off, page);
 }
@@ -1172,7 +1172,7 @@
 		return -ENOMEM;
 	pagedir_nosave = (struct pbe *)addr;
 
-	pr_debug("pmdisk: Reading pagedir (%d Pages)\n",n);
+	pr_debug("swsusp: Reading pagedir (%d Pages)\n",n);
 
 	for (i = 0; i < n && !error; i++, addr += PAGE_SIZE) {
 		unsigned long offset = swp_offset(swsusp_info.pagedir[i]);
diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c
--- a/kernel/ptrace.c	2005-01-19 13:44:48 -08:00
+++ b/kernel/ptrace.c	2005-01-19 13:44:48 -08:00
@@ -319,18 +319,33 @@
 
 static int ptrace_getsiginfo(struct task_struct *child, siginfo_t __user * data)
 {
-	if (child->last_siginfo == NULL)
-		return -EINVAL;
-	return copy_siginfo_to_user(data, child->last_siginfo);
+	siginfo_t lastinfo;
+
+	spin_lock_irq(&child->sighand->siglock);
+	if (likely(child->last_siginfo != NULL)) {
+		memcpy(&lastinfo, child->last_siginfo, sizeof (siginfo_t));
+		spin_unlock_irq(&child->sighand->siglock);
+		return copy_siginfo_to_user(data, &lastinfo);
+	}
+	spin_unlock_irq(&child->sighand->siglock);
+	return -EINVAL;
 }
 
 static int ptrace_setsiginfo(struct task_struct *child, siginfo_t __user * data)
 {
-	if (child->last_siginfo == NULL)
-		return -EINVAL;
-	if (copy_from_user(child->last_siginfo, data, sizeof (siginfo_t)) != 0)
+	siginfo_t newinfo;
+
+	if (copy_from_user(&newinfo, data, sizeof (siginfo_t)) != 0)
 		return -EFAULT;
-	return 0;
+
+	spin_lock_irq(&child->sighand->siglock);
+	if (likely(child->last_siginfo != NULL)) {
+		memcpy(child->last_siginfo, &newinfo, sizeof (siginfo_t));
+		spin_unlock_irq(&child->sighand->siglock);
+		return 0;
+	}
+	spin_unlock_irq(&child->sighand->siglock);
+	return -EINVAL;
 }
 
 int ptrace_request(struct task_struct *child, long request,
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	2005-01-19 13:44:47 -08:00
+++ b/kernel/sched.c	2005-01-19 13:44:47 -08:00
@@ -2383,13 +2383,17 @@
 void account_steal_time(struct task_struct *p, cputime_t steal)
 {
 	struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
-	cputime64_t steal64 = cputime_to_cputime64(steal);
+	cputime64_t tmp = cputime_to_cputime64(steal);
 	runqueue_t *rq = this_rq();
 
-	if (p == rq->idle)
-		cpustat->system = cputime64_add(cpustat->system, steal64);
-	else
-		cpustat->steal = cputime64_add(cpustat->steal, steal64);
+	if (p == rq->idle) {
+		p->stime = cputime_add(p->stime, steal);
+		if (atomic_read(&rq->nr_iowait) > 0)
+			cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
+		else
+			cpustat->idle = cputime64_add(cpustat->idle, tmp);
+	} else
+		cpustat->steal = cputime64_add(cpustat->steal, tmp);
 }
 
 /*
@@ -3186,6 +3190,15 @@
 {
 	return TASK_NICE(p);
 }
+
+/*
+ * The only users of task_nice are binfmt_elf and binfmt_elf32.
+ * binfmt_elf is no longer modular, but binfmt_elf32 still is.
+ * Therefore, task_nice is needed if there is a compat_mode.
+ */
+#ifdef CONFIG_COMPAT
+EXPORT_SYMBOL_GPL(task_nice);
+#endif
 
 /**
  * idle_cpu - is a given cpu idle currently?
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	2005-01-19 13:44:46 -08:00
+++ b/kernel/signal.c	2005-01-19 13:44:46 -08:00
@@ -1588,7 +1588,9 @@
 	read_lock(&tasklist_lock);
 	if (likely(current->ptrace & PT_PTRACED) &&
 	    likely(current->parent != current->real_parent ||
-		   !(current->ptrace & PT_ATTACHED))) {
+		   !(current->ptrace & PT_ATTACHED)) &&
+	    (likely(current->parent->signal != current->signal) ||
+	     !unlikely(current->signal->flags & SIGNAL_GROUP_EXIT))) {
 		do_notify_parent_cldstop(current, current->parent,
 					 CLD_TRAPPED);
 		read_unlock(&tasklist_lock);
diff -Nru a/kernel/spinlock.c b/kernel/spinlock.c
--- a/kernel/spinlock.c	2005-01-19 13:44:45 -08:00
+++ b/kernel/spinlock.c	2005-01-19 13:44:45 -08:00
@@ -173,7 +173,7 @@
  * (We do this in a function because inlining it would be excessive.)
  */
 
-#define BUILD_LOCK_OPS(op, locktype)					\
+#define BUILD_LOCK_OPS(op, locktype, is_locked_fn)			\
 void __lockfunc _##op##_lock(locktype *lock)				\
 {									\
 	preempt_disable();						\
@@ -183,7 +183,8 @@
 		preempt_enable();					\
 		if (!(lock)->break_lock)				\
 			(lock)->break_lock = 1;				\
-		cpu_relax();						\
+		while (is_locked_fn(lock) && (lock)->break_lock)	\
+			cpu_relax();					\
 		preempt_disable();					\
 	}								\
 }									\
@@ -204,7 +205,8 @@
 		preempt_enable();					\
 		if (!(lock)->break_lock)				\
 			(lock)->break_lock = 1;				\
-		cpu_relax();						\
+		while (is_locked_fn(lock) && (lock)->break_lock)	\
+			cpu_relax();					\
 		preempt_disable();					\
 	}								\
 	return flags;							\
@@ -244,9 +246,9 @@
  *         _[spin|read|write]_lock_irqsave()
  *         _[spin|read|write]_lock_bh()
  */
-BUILD_LOCK_OPS(spin, spinlock_t);
-BUILD_LOCK_OPS(read, rwlock_t);
-BUILD_LOCK_OPS(write, rwlock_t);
+BUILD_LOCK_OPS(spin, spinlock_t, spin_is_locked);
+BUILD_LOCK_OPS(read, rwlock_t, rwlock_is_locked);
+BUILD_LOCK_OPS(write, rwlock_t, spin_is_locked);
 
 #endif /* CONFIG_PREEMPT */
 
diff -Nru a/lib/Kconfig.debug b/lib/Kconfig.debug
--- a/lib/Kconfig.debug	2005-01-19 13:44:47 -08:00
+++ b/lib/Kconfig.debug	2005-01-19 13:44:47 -08:00
@@ -23,7 +23,6 @@
 config MAGIC_SYSRQ
 	bool "Magic SysRq key"
 	depends on DEBUG_KERNEL && (H8300 || M68KNOMMU || V850)
-	depends (USERMODE && MCONSOLE)
 	help
 	  Enables console device to interpret special characters as
 	  commands to dump state information.
@@ -50,7 +49,7 @@
 
 config DEBUG_PREEMPT
 	bool "Debug preemptible kernel"
-	depends on PREEMPT && X86
+	depends on PREEMPT && (X86 || PPC64)
 	default y
 	help
 	  If you say Y here then the kernel will use a debug variant of the
@@ -117,6 +116,19 @@
 
         If you're truly short on disk space or don't expect to report any
         bugs back to the UML developers, say N, otherwise say Y.
+
+config DEBUG_IOREMAP
+	bool "Enable ioremap() debugging"
+	depends on DEBUG_KERNEL && PARISC
+	help
+	  Enabling this option will cause the kernel to distinguish between
+	  ioremapped and physical addresses.  It will print a backtrace (at
+	  most one every 10 seconds), hopefully allowing you to see which
+	  drivers need work.  Fixing all these problems is a prerequisite
+	  for turning on USE_HPPA_IOREMAP.  The warnings are harmless;
+	  the kernel has enough information to fix the broken drivers
+	  automatically, but we'd like to make it more efficient by not
+	  having to do that.
 
 config DEBUG_FS
 	bool "Debug Filesystem"
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	2005-01-19 13:44:48 -08:00
+++ b/mm/filemap.c	2005-01-19 13:44:48 -08:00
@@ -693,6 +693,7 @@
 	unsigned long offset;
 	unsigned long req_size;
 	unsigned long next_index;
+	unsigned long prev_index;
 	loff_t isize;
 	struct page *cached_page;
 	int error;
@@ -701,6 +702,7 @@
 	cached_page = NULL;
 	index = *ppos >> PAGE_CACHE_SHIFT;
 	next_index = index;
+	prev_index = ra.prev_page;
 	req_size = (desc->count + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	offset = *ppos & ~PAGE_CACHE_MASK;
 
@@ -754,8 +756,9 @@
 		 * When (part of) the same page is read multiple times
 		 * in succession, only mark it as accessed the first time.
 		 */
-		if (ra.prev_page != index)
+		if (prev_index != index)
 			mark_page_accessed(page);
+		prev_index = index;
 
 		/*
 		 * Ok, we have the page, and it's up-to-date, so
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	2005-01-19 13:44:47 -08:00
+++ b/mm/mmap.c	2005-01-19 13:44:47 -08:00
@@ -1475,7 +1475,6 @@
 int expand_stack(struct vm_area_struct * vma, unsigned long address)
 {
 	int error;
-	unsigned long size, grow;
 
 	if (!(vma->vm_flags & VM_GROWSUP))
 		return -EFAULT;
@@ -1495,12 +1494,19 @@
 	 */
 	address += 4 + PAGE_SIZE - 1;
 	address &= PAGE_MASK;
-	size = address - vma->vm_start;
-	grow = (address - vma->vm_end) >> PAGE_SHIFT;
+	error = 0;
 
-	error = acct_stack_growth(vma, size, grow);
-	if (!error)
-		vma->vm_end = address;
+	/* Somebody else might have raced and expanded it already */
+	if (address > vma->vm_end) {
+		unsigned long size, grow;
+
+		size = address - vma->vm_start;
+		grow = (address - vma->vm_end) >> PAGE_SHIFT;
+
+		error = acct_stack_growth(vma, size, grow);
+		if (!error)
+			vma->vm_end = address;
+	}
 	anon_vma_unlock(vma);
 	return error;
 }
@@ -1528,7 +1534,6 @@
 int expand_stack(struct vm_area_struct *vma, unsigned long address)
 {
 	int error;
-	unsigned long size, grow;
 
 	/*
 	 * We must make sure the anon_vma is allocated
@@ -1544,13 +1549,20 @@
 	 * anon_vma lock to serialize against concurrent expand_stacks.
 	 */
 	address &= PAGE_MASK;
-	size = vma->vm_end - address;
-	grow = (vma->vm_start - address) >> PAGE_SHIFT;
+	error = 0;
 
-	error = acct_stack_growth(vma, size, grow);
-	if (!error) {
-		vma->vm_start = address;
-		vma->vm_pgoff -= grow;
+	/* Somebody else might have raced and expanded it already */
+	if (address < vma->vm_start) {
+		unsigned long size, grow;
+
+		size = vma->vm_end - address;
+		grow = (vma->vm_start - address) >> PAGE_SHIFT;
+
+		error = acct_stack_growth(vma, size, grow);
+		if (!error) {
+			vma->vm_start = address;
+			vma->vm_pgoff -= grow;
+		}
 	}
 	anon_vma_unlock(vma);
 	return error;
@@ -1858,6 +1870,16 @@
 	return ret;
 }
 
+static inline void verify_mm_writelocked(struct mm_struct *mm)
+{
+#ifdef CONFIG_DEBUG_KERNEL
+	if (unlikely(down_read_trylock(&mm->mmap_sem))) {
+		WARN_ON(1);
+		up_read(&mm->mmap_sem);
+	}
+#endif
+}
+
 /*
  *  this is really a simplified "do_mmap".  it only handles
  *  anonymous maps.  eventually we may be able to do some
@@ -1889,6 +1911,12 @@
 		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
 			return -EAGAIN;
 	}
+
+	/*
+	 * mm->mmap_sem is required to protect against another thread
+	 * changing the mappings in case we sleep.
+	 */
+	verify_mm_writelocked(mm);
 
 	/*
 	 * Clear old maps.  this also does some error checking for us
diff -Nru a/mm/pdflush.c b/mm/pdflush.c
--- a/mm/pdflush.c	2005-01-19 13:44:48 -08:00
+++ b/mm/pdflush.c	2005-01-19 13:44:48 -08:00
@@ -17,7 +17,6 @@
 #include <linux/gfp.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/suspend.h>
 #include <linux/fs.h>		// Needed by writeback.h
 #include <linux/writeback.h>	// Prototypes pdflush_operation()
 #include <linux/kthread.h>
@@ -106,8 +105,7 @@
 		spin_unlock_irq(&pdflush_lock);
 
 		schedule();
-		if (current->flags & PF_FREEZE) {
-			refrigerator(PF_FREEZE);
+		if (try_to_freeze(PF_FREEZE)) {
 			spin_lock_irq(&pdflush_lock);
 			continue;
 		}
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	2005-01-19 13:44:46 -08:00
+++ b/mm/vmscan.c	2005-01-19 13:44:46 -08:00
@@ -21,7 +21,6 @@
 #include <linux/highmem.h>
 #include <linux/file.h>
 #include <linux/writeback.h>
-#include <linux/suspend.h>
 #include <linux/blkdev.h>
 #include <linux/buffer_head.h>	/* for try_to_release_page(),
 					buffer_heads_over_limit */
diff -Nru a/net/802/psnap.c b/net/802/psnap.c
--- a/net/802/psnap.c	2005-01-19 13:44:48 -08:00
+++ b/net/802/psnap.c	2005-01-19 13:44:48 -08:00
@@ -22,7 +22,7 @@
 #include <linux/init.h>
 
 static LIST_HEAD(snap_list);
-static spinlock_t snap_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(snap_lock);
 static struct llc_sap *snap_sap;
 
 /*
diff -Nru a/net/802/tr.c b/net/802/tr.c
--- a/net/802/tr.c	2005-01-19 13:44:45 -08:00
+++ b/net/802/tr.c	2005-01-19 13:44:45 -08:00
@@ -66,7 +66,7 @@
  
 static struct rif_cache_s *rif_table[RIF_TABLE_SIZE];
 
-static spinlock_t rif_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rif_lock);
 
 
 /*
diff -Nru a/net/Kconfig b/net/Kconfig
--- a/net/Kconfig	2005-01-19 13:44:45 -08:00
+++ b/net/Kconfig	2005-01-19 13:44:45 -08:00
@@ -621,7 +621,7 @@
 	  stress testing and performance analysis.  If you don't understand
 	  what was just said, you don't need it: say N.
 
-	  Documentation on how to use the packet generaor can be found
+	  Documentation on how to use the packet generator can be found
 	  at <file:Documentation/networking/pktgen.txt>.
 
 	  To compile this code as a module, choose M here: the
diff -Nru a/net/appletalk/aarp.c b/net/appletalk/aarp.c
--- a/net/appletalk/aarp.c	2005-01-19 13:44:47 -08:00
+++ b/net/appletalk/aarp.c	2005-01-19 13:44:47 -08:00
@@ -77,7 +77,7 @@
 static int unresolved_count;
 
 /* One lock protects it all. */
-static rwlock_t aarp_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(aarp_lock);
 
 /* Used to walk the list and purge/kick entries.  */
 static struct timer_list aarp_timer;
diff -Nru a/net/appletalk/ddp.c b/net/appletalk/ddp.c
--- a/net/appletalk/ddp.c	2005-01-19 13:44:48 -08:00
+++ b/net/appletalk/ddp.c	2005-01-19 13:44:48 -08:00
@@ -9,6 +9,7 @@
  *		Wesley Craig <netatalk@umich.edu>
  *
  *	Fixes:
+ *		Neil Horman		:	Added missing device ioctls
  *		Michael Callahan	:	Made routing work
  *		Wesley Craig		:	Fix probing to listen to a
  *						passed node id.
@@ -71,7 +72,7 @@
 \**************************************************************************/
 
 HLIST_HEAD(atalk_sockets);
-rwlock_t atalk_sockets_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(atalk_sockets_lock);
 
 static inline void __atalk_insert_socket(struct sock *sk)
 {
@@ -193,10 +194,10 @@
 
 /* Anti-deadlock ordering is atalk_routes_lock --> iface_lock -DaveM */
 struct atalk_route *atalk_routes;
-rwlock_t atalk_routes_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(atalk_routes_lock);
 
 struct atalk_iface *atalk_interfaces;
-rwlock_t atalk_interfaces_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(atalk_interfaces_lock);
 
 /* For probing devices or in a routerless network */
 struct atalk_route atrtr_default;
@@ -1806,6 +1807,8 @@
 		case SIOCSIFHWADDR:
 		case SIOCGIFFLAGS:
 		case SIOCSIFFLAGS:
+		case SIOCGIFTXQLEN:
+		case SIOCSIFTXQLEN:
 		case SIOCGIFMTU:
 		case SIOCGIFCONF:
 		case SIOCADDMULTI:
diff -Nru a/net/atm/br2684.c b/net/atm/br2684.c
--- a/net/atm/br2684.c	2005-01-19 13:44:48 -08:00
+++ b/net/atm/br2684.c	2005-01-19 13:44:48 -08:00
@@ -97,7 +97,7 @@
  * do read-locking under interrupt context, so write locking must block
  * the current CPU's interrupts
  */
-static rwlock_t devs_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(devs_lock);
 
 static LIST_HEAD(br2684_devs);
 
diff -Nru a/net/atm/common.c b/net/atm/common.c
--- a/net/atm/common.c	2005-01-19 13:44:48 -08:00
+++ b/net/atm/common.c	2005-01-19 13:44:48 -08:00
@@ -39,7 +39,7 @@
 #endif
 
 struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
-rwlock_t vcc_sklist_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(vcc_sklist_lock);
 
 void __vcc_insert_socket(struct sock *sk)
 {
diff -Nru a/net/atm/resources.c b/net/atm/resources.c
--- a/net/atm/resources.c	2005-01-19 13:44:47 -08:00
+++ b/net/atm/resources.c	2005-01-19 13:44:47 -08:00
@@ -24,7 +24,7 @@
 
 
 LIST_HEAD(atm_devs);
-spinlock_t atm_dev_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(atm_dev_lock);
 
 static struct atm_dev *__alloc_atm_dev(const char *type)
 {
diff -Nru a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
--- a/net/ax25/af_ax25.c	2005-01-19 13:44:47 -08:00
+++ b/net/ax25/af_ax25.c	2005-01-19 13:44:47 -08:00
@@ -52,7 +52,7 @@
 
 
 HLIST_HEAD(ax25_list);
-spinlock_t ax25_list_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ax25_list_lock);
 
 static struct proto_ops ax25_proto_ops;
 
@@ -207,8 +207,16 @@
 			continue;
 		if (s->ax25_dev == NULL)
 			continue;
-		if (ax25cmp(&s->source_addr, src_addr) == 0 &&
-		    ax25cmp(&s->dest_addr, dest_addr) == 0) {
+		if (ax25cmp(&s->source_addr, src_addr) == 0 && ax25cmp(&s->dest_addr, dest_addr) == 0 && s->ax25_dev->dev == dev) {
+			if (digi != NULL && digi->ndigi != 0) {
+				if (s->digipeat == NULL)
+					continue;
+				if (ax25digicmp(s->digipeat, digi) != 0)
+					continue;
+			} else {
+				if (s->digipeat != NULL && s->digipeat->ndigi != 0)
+					continue;
+			}
 			ax25_cb_hold(s);
 			spin_unlock_bh(&ax25_list_lock);
 
diff -Nru a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
--- a/net/ax25/ax25_addr.c	2005-01-19 13:44:48 -08:00
+++ b/net/ax25/ax25_addr.c	2005-01-19 13:44:48 -08:00
@@ -121,6 +121,26 @@
 }
 
 /*
+ *	Compare two AX.25 digipeater paths.
+ */
+int ax25digicmp(ax25_digi *digi1, ax25_digi *digi2)
+{
+	int i;
+
+	if (digi1->ndigi != digi2->ndigi)
+		return 1;
+
+	if (digi1->lastrepeat != digi2->lastrepeat)
+		return 1;
+
+	for (i = 0; i < digi1->ndigi; i++)
+		if (ax25cmp(&digi1->calls[i], &digi2->calls[i]) != 0)
+			return 1;
+
+	return 0;
+}
+
+/*
  *	Given an AX.25 address pull of to, from, digi list, command/response and the start of data
  *
  */
diff -Nru a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c
--- a/net/ax25/ax25_dev.c	2005-01-19 13:44:46 -08:00
+++ b/net/ax25/ax25_dev.c	2005-01-19 13:44:46 -08:00
@@ -32,7 +32,7 @@
 #include <linux/init.h>
 
 ax25_dev *ax25_dev_list;
-spinlock_t ax25_dev_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ax25_dev_lock);
 
 ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
 {
diff -Nru a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
--- a/net/ax25/ax25_iface.c	2005-01-19 13:44:48 -08:00
+++ b/net/ax25/ax25_iface.c	2005-01-19 13:44:48 -08:00
@@ -34,20 +34,20 @@
 	unsigned int pid;
 	int (*func)(struct sk_buff *, ax25_cb *);
 } *protocol_list = NULL;
-static rwlock_t protocol_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(protocol_list_lock);
 
 static struct linkfail_struct {
 	struct linkfail_struct *next;
 	void (*func)(ax25_cb *, int);
 } *linkfail_list = NULL;
-static spinlock_t linkfail_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(linkfail_lock);
 
 static struct listen_struct {
 	struct listen_struct *next;
 	ax25_address  callsign;
 	struct net_device *dev;
 } *listen_list = NULL;
-static spinlock_t listen_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(listen_lock);
 
 int ax25_protocol_register(unsigned int pid,
 	int (*func)(struct sk_buff *, ax25_cb *))
diff -Nru a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
--- a/net/ax25/ax25_out.c	2005-01-19 13:44:47 -08:00
+++ b/net/ax25/ax25_out.c	2005-01-19 13:44:47 -08:00
@@ -32,7 +32,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 
-static spinlock_t ax25_frag_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ax25_frag_lock);
 
 ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax25_address *dest, ax25_digi *digi, struct net_device *dev)
 {
diff -Nru a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
--- a/net/ax25/ax25_route.c	2005-01-19 13:44:47 -08:00
+++ b/net/ax25/ax25_route.c	2005-01-19 13:44:47 -08:00
@@ -37,7 +37,7 @@
 #include <linux/seq_file.h>
 
 static ax25_route *ax25_route_list;
-static rwlock_t ax25_route_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ax25_route_lock);
 
 static ax25_route *ax25_get_route(ax25_address *, struct net_device *);
 
diff -Nru a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
--- a/net/ax25/ax25_uid.c	2005-01-19 13:44:46 -08:00
+++ b/net/ax25/ax25_uid.c	2005-01-19 13:44:46 -08:00
@@ -42,7 +42,7 @@
  */
 
 static ax25_uid_assoc *ax25_uid_list;
-static rwlock_t ax25_uid_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ax25_uid_lock);
 
 int ax25_uid_policy = 0;
 
diff -Nru a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
--- a/net/bluetooth/cmtp/capi.c	2005-01-19 13:44:47 -08:00
+++ b/net/bluetooth/cmtp/capi.c	2005-01-19 13:44:47 -08:00
@@ -139,6 +139,19 @@
 	return session->msgnum;
 }
 
+static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
+{
+	struct cmtp_scb *scb = (void *) skb->cb;
+
+	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
+
+	scb->id = -1;
+	scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
+
+	skb_queue_tail(&session->transmit, skb);
+
+	cmtp_schedule(session);
+}
 
 static void cmtp_send_interopmsg(struct cmtp_session *session,
 					__u8 subcmd, __u16 appl, __u16 msgnum,
@@ -336,21 +349,6 @@
 
 	capi_ctr_handle_message(ctrl, appl, skb);
 }
-
-void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-{
-	struct cmtp_scb *scb = (void *) skb->cb;
-
-	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-
-	scb->id = -1;
-	scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
-
-	skb_queue_tail(&session->transmit, skb);
-
-	cmtp_schedule(session);
-}
-
 
 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 {
diff -Nru a/net/bluetooth/cmtp/cmtp.h b/net/bluetooth/cmtp/cmtp.h
--- a/net/bluetooth/cmtp/cmtp.h	2005-01-19 13:44:47 -08:00
+++ b/net/bluetooth/cmtp/cmtp.h	2005-01-19 13:44:47 -08:00
@@ -120,7 +120,6 @@
 void cmtp_detach_device(struct cmtp_session *session);
 
 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
 
 static inline void cmtp_schedule(struct cmtp_session *session)
 {
diff -Nru a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
--- a/net/bluetooth/hci_conn.c	2005-01-19 13:44:48 -08:00
+++ b/net/bluetooth/hci_conn.c	2005-01-19 13:44:48 -08:00
@@ -53,7 +53,7 @@
 #define BT_DBG(D...)
 #endif
 
-void hci_acl_connect(struct hci_conn *conn)
+static void hci_acl_connect(struct hci_conn *conn)
 {
 	struct hci_dev *hdev = conn->hdev;
 	struct inquiry_entry *ie;
diff -Nru a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
--- a/net/bluetooth/hci_core.c	2005-01-19 13:44:46 -08:00
+++ b/net/bluetooth/hci_core.c	2005-01-19 13:44:46 -08:00
@@ -59,15 +59,15 @@
 static void hci_tx_task(unsigned long arg);
 static void hci_notify(struct hci_dev *hdev, int event);
 
-rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(hci_task_lock);
 
 /* HCI device list */
 LIST_HEAD(hci_dev_list);
-rwlock_t hci_dev_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(hci_dev_list_lock);
 
 /* HCI callback list */
 LIST_HEAD(hci_cb_list);
-rwlock_t hci_cb_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(hci_cb_list_lock);
 
 /* HCI protocols */
 #define HCI_MAX_PROTO	2
@@ -106,7 +106,7 @@
 	}
 }
 
-void hci_req_cancel(struct hci_dev *hdev, int err)
+static void hci_req_cancel(struct hci_dev *hdev, int err)
 {
 	BT_DBG("%s err 0x%2.2x", hdev->name, err);
 
diff -Nru a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
--- a/net/bluetooth/hci_sock.c	2005-01-19 13:44:47 -08:00
+++ b/net/bluetooth/hci_sock.c	2005-01-19 13:44:47 -08:00
@@ -447,7 +447,7 @@
 	goto done;
 }
 
-int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
+static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
 {
 	struct hci_ufilter uf = { .opcode = 0 };
 	struct sock *sk = sock->sk;
@@ -514,7 +514,7 @@
 	return err;
 }
 
-int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
+static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
 {
 	struct hci_ufilter uf;
 	struct sock *sk = sock->sk;
@@ -567,7 +567,7 @@
 	return 0;
 }
 
-struct proto_ops hci_sock_ops = {
+static struct proto_ops hci_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= hci_sock_release,
@@ -647,13 +647,13 @@
 	return NOTIFY_DONE;
 }
 
-struct net_proto_family hci_sock_family_ops = {
+static struct net_proto_family hci_sock_family_ops = {
 	.family	= PF_BLUETOOTH,
 	.owner	= THIS_MODULE,
 	.create	= hci_sock_create,
 };
 
-struct notifier_block hci_sock_nblock = {
+static struct notifier_block hci_sock_nblock = {
 	.notifier_call = hci_sock_dev_event
 };
 
diff -Nru a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
--- a/net/bluetooth/hidp/core.c	2005-01-19 13:44:47 -08:00
+++ b/net/bluetooth/hidp/core.c	2005-01-19 13:44:47 -08:00
@@ -50,7 +50,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "1.0"
+#define VERSION "1.1"
 
 static DECLARE_RWSEM(hidp_session_sem);
 static LIST_HEAD(hidp_session_list);
@@ -130,7 +130,7 @@
 	struct sk_buff *skb;
 	unsigned char newleds;
 
-	BT_DBG("session %p hid %p data %p size %d", session, device, data, size);
+	BT_DBG("input %p type %d code %d value %d", dev, type, code, value);
 
 	if (type != EV_LED)
 		return -1;
@@ -151,7 +151,7 @@
 		return -ENOMEM;
 	}
 
-	*skb_put(skb, 1) = 0xa2;
+	*skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
 	*skb_put(skb, 1) = 0x01;
 	*skb_put(skb, 1) = newleds;
 
@@ -232,36 +232,171 @@
 		del_timer(&session->timer);
 }
 
-static inline void hidp_send_message(struct hidp_session *session, unsigned char hdr)
+static int __hidp_send_ctrl_message(struct hidp_session *session,
+			unsigned char hdr, unsigned char *data, int size)
 {
 	struct sk_buff *skb;
 
-	BT_DBG("session %p", session);
+	BT_DBG("session %p data %p size %d", session, data, size);
 
-	if (!(skb = alloc_skb(1, GFP_ATOMIC))) {
-		BT_ERR("Can't allocate memory for message");
-		return;
+	if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
+		BT_ERR("Can't allocate memory for new frame");
+		return -ENOMEM;
 	}
 
 	*skb_put(skb, 1) = hdr;
+	if (data && size > 0)
+		memcpy(skb_put(skb, size), data, size);
 
 	skb_queue_tail(&session->ctrl_transmit, skb);
 
+	return 0;
+}
+
+static int inline hidp_send_ctrl_message(struct hidp_session *session,
+			unsigned char hdr, unsigned char *data, int size)
+{
+	int err;
+
+	err = __hidp_send_ctrl_message(session, hdr, data, size);
+
 	hidp_schedule(session);
+
+	return err;
+}
+
+static inline void hidp_process_handshake(struct hidp_session *session, unsigned char param)
+{
+	BT_DBG("session %p param 0x%02x", session, param);
+
+	switch (param) {
+	case HIDP_HSHK_SUCCESSFUL:
+		/* FIXME: Call into SET_ GET_ handlers here */
+		break;
+
+	case HIDP_HSHK_NOT_READY:
+	case HIDP_HSHK_ERR_INVALID_REPORT_ID:
+	case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
+	case HIDP_HSHK_ERR_INVALID_PARAMETER:
+		/* FIXME: Call into SET_ GET_ handlers here */
+		break;
+
+	case HIDP_HSHK_ERR_UNKNOWN:
+		break;
+
+	case HIDP_HSHK_ERR_FATAL:
+		/* Device requests a reboot, as this is the only way this error
+ 		 * can be recovered. */
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
+		break;
+
+	default:
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
+		break;
+	}
+}
+
+static inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param)
+{
+	BT_DBG("session %p param 0x%02x", session, param);
+
+	switch (param) {
+	case HIDP_CTRL_NOP:
+		break;
+
+	case HIDP_CTRL_VIRTUAL_CABLE_UNPLUG:
+		/* Flush the transmit queues */
+		skb_queue_purge(&session->ctrl_transmit);
+		skb_queue_purge(&session->intr_transmit);
+
+		/* Kill session thread */
+		atomic_inc(&session->terminate);
+		break;
+
+	case HIDP_CTRL_HARD_RESET:
+	case HIDP_CTRL_SOFT_RESET:
+	case HIDP_CTRL_SUSPEND:
+	case HIDP_CTRL_EXIT_SUSPEND:
+		/* FIXME: We have to parse these and return no error */
+		break;
+
+	default:
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
+		break;
+	}
 }
 
-static inline int hidp_recv_frame(struct hidp_session *session, struct sk_buff *skb)
+static inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param)
 {
-	__u8 hdr;
+	BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
+
+	switch (param) {
+	case HIDP_DATA_RTYPE_INPUT:
+		hidp_set_timer(session);
+
+		if (session->input)
+			hidp_input_report(session, skb);
+		break;
+
+	case HIDP_DATA_RTYPE_OTHER:
+	case HIDP_DATA_RTYPE_OUPUT:
+	case HIDP_DATA_RTYPE_FEATURE:
+		break;
+
+	default:
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
+	}
+}
+
+static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb)
+{
+	unsigned char hdr, type, param;
 
 	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
 
 	hdr = skb->data[0];
 	skb_pull(skb, 1);
 
-	if (hdr == 0xa1) {
-		hidp_set_timer(session);
+	type = hdr & HIDP_HEADER_TRANS_MASK;
+	param = hdr & HIDP_HEADER_PARAM_MASK;
+
+	switch (type) {
+	case HIDP_TRANS_HANDSHAKE:
+		hidp_process_handshake(session, param);
+		break;
 
+	case HIDP_TRANS_HID_CONTROL:
+		hidp_process_hid_control(session, param);
+		break;
+
+	case HIDP_TRANS_DATA:
+		hidp_process_data(session, skb, param);
+		break;
+
+	default:
+		__hidp_send_ctrl_message(session,
+			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
+		break;
+	}
+
+	kfree_skb(skb);
+}
+
+static inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb)
+{
+	unsigned char hdr;
+
+	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
+
+	hdr = skb->data[0];
+	skb_pull(skb, 1);
+
+	if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) {
+		hidp_set_timer(session);
 		if (session->input)
 			hidp_input_report(session, skb);
 	} else {
@@ -269,7 +404,6 @@
 	}
 
 	kfree_skb(skb);
-	return 0;
 }
 
 static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
@@ -350,12 +484,12 @@
 
 		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
 			skb_orphan(skb);
-			hidp_recv_frame(session, skb);
+			hidp_recv_ctrl_frame(session, skb);
 		}
 
 		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
 			skb_orphan(skb);
-			hidp_recv_frame(session, skb);
+			hidp_recv_intr_frame(session, skb);
 		}
 
 		hidp_process_transmit(session);
@@ -514,7 +648,8 @@
 		goto unlink;
 
 	if (session->input) {
-		hidp_send_message(session, 0x70);
+		hidp_send_ctrl_message(session,
+			HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0);
 		session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
 
 		session->leds = 0xff;
@@ -554,7 +689,8 @@
 	session = __hidp_get_session(&req->bdaddr);
 	if (session) {
 		if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
-			hidp_send_message(session, 0x15);
+			hidp_send_ctrl_message(session,
+				HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0);
 		} else {
 			/* Flush the transmit queues */
 			skb_queue_purge(&session->ctrl_transmit);
diff -Nru a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
--- a/net/bluetooth/hidp/hidp.h	2005-01-19 13:44:46 -08:00
+++ b/net/bluetooth/hidp/hidp.h	2005-01-19 13:44:46 -08:00
@@ -26,6 +26,51 @@
 #include <linux/types.h>
 #include <net/bluetooth/bluetooth.h>
 
+/* HIDP header masks */
+#define HIDP_HEADER_TRANS_MASK			0xf0
+#define HIDP_HEADER_PARAM_MASK			0x0f
+
+/* HIDP transaction types */
+#define HIDP_TRANS_HANDSHAKE			0x00
+#define HIDP_TRANS_HID_CONTROL			0x10
+#define HIDP_TRANS_GET_REPORT			0x40
+#define HIDP_TRANS_SET_REPORT			0x50
+#define HIDP_TRANS_GET_PROTOCOL			0x60
+#define HIDP_TRANS_SET_PROTOCOL			0x70
+#define HIDP_TRANS_GET_IDLE			0x80
+#define HIDP_TRANS_SET_IDLE			0x90
+#define HIDP_TRANS_DATA				0xa0
+#define HIDP_TRANS_DATC				0xb0
+
+/* HIDP handshake results */
+#define HIDP_HSHK_SUCCESSFUL			0x00
+#define HIDP_HSHK_NOT_READY			0x01
+#define HIDP_HSHK_ERR_INVALID_REPORT_ID		0x02
+#define HIDP_HSHK_ERR_UNSUPPORTED_REQUEST	0x03
+#define HIDP_HSHK_ERR_INVALID_PARAMETER		0x04
+#define HIDP_HSHK_ERR_UNKNOWN			0x0e
+#define HIDP_HSHK_ERR_FATAL			0x0f
+
+/* HIDP control operation parameters */
+#define HIDP_CTRL_NOP				0x00
+#define HIDP_CTRL_HARD_RESET			0x01
+#define HIDP_CTRL_SOFT_RESET			0x02
+#define HIDP_CTRL_SUSPEND			0x03
+#define HIDP_CTRL_EXIT_SUSPEND			0x04
+#define HIDP_CTRL_VIRTUAL_CABLE_UNPLUG		0x05
+
+/* HIDP data transaction headers */
+#define HIDP_DATA_RTYPE_MASK			0x03
+#define HIDP_DATA_RSRVD_MASK			0x0c
+#define HIDP_DATA_RTYPE_OTHER			0x00
+#define HIDP_DATA_RTYPE_INPUT			0x01
+#define HIDP_DATA_RTYPE_OUPUT			0x02
+#define HIDP_DATA_RTYPE_FEATURE			0x03
+
+/* HIDP protocol header parameters */
+#define HIDP_PROTO_BOOT				0x00
+#define HIDP_PROTO_REPORT			0x01
+
 /* HIDP ioctl defines */
 #define HIDPCONNADD	_IOW('H', 200, int)
 #define HIDPCONNDEL	_IOW('H', 201, int)
diff -Nru a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
--- a/net/bluetooth/l2cap.c	2005-01-19 13:44:47 -08:00
+++ b/net/bluetooth/l2cap.c	2005-01-19 13:44:47 -08:00
@@ -57,11 +57,11 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "2.6"
+#define VERSION "2.7"
 
 static struct proto_ops l2cap_sock_ops;
 
-struct bt_sock_list l2cap_sk_list = {
+static struct bt_sock_list l2cap_sk_list = {
 	.lock = RW_LOCK_UNLOCKED
 };
 
@@ -798,7 +798,7 @@
 	switch (optname) {
 	case L2CAP_OPTIONS:
 		len = min_t(unsigned int, sizeof(opts), optlen);
-		if (copy_from_user((char *)&opts, optval, len)) {
+		if (copy_from_user((char *) &opts, optval, len)) {
 			err = -EFAULT;
 			break;
 		}
@@ -807,7 +807,7 @@
 		break;
 
 	case L2CAP_LM:
-		if (get_user(opt, (u32 __user *)optval)) {
+		if (get_user(opt, (u32 __user *) optval)) {
 			err = -EFAULT;
 			break;
 		}
@@ -829,7 +829,9 @@
 	struct sock *sk = sock->sk;
 	struct l2cap_options opts;
 	struct l2cap_conninfo cinfo;
-	int len, err = 0; 
+	int len, err = 0;
+
+	BT_DBG("sk %p", sk);
 
 	if (get_user(len, optlen))
 		return -EFAULT;
@@ -841,15 +843,16 @@
 		opts.imtu     = l2cap_pi(sk)->imtu;
 		opts.omtu     = l2cap_pi(sk)->omtu;
 		opts.flush_to = l2cap_pi(sk)->flush_to;
+		opts.mode     = 0x00;
 
 		len = min_t(unsigned int, len, sizeof(opts));
-		if (copy_to_user(optval, (char *)&opts, len))
+		if (copy_to_user(optval, (char *) &opts, len))
 			err = -EFAULT;
 
 		break;
 
 	case L2CAP_LM:
-		if (put_user(l2cap_pi(sk)->link_mode, (u32 __user *)optval))
+		if (put_user(l2cap_pi(sk)->link_mode, (u32 __user *) optval))
 			err = -EFAULT;
 		break;
 
@@ -860,9 +863,10 @@
 		}
 
 		cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
+		memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3);
 
 		len = min_t(unsigned int, len, sizeof(cinfo));
-		if (copy_to_user(optval, (char *)&cinfo, len))
+		if (copy_to_user(optval, (char *) &cinfo, len))
 			err = -EFAULT;
 
 		break;
diff -Nru a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
--- a/net/bluetooth/rfcomm/core.c	2005-01-19 13:44:45 -08:00
+++ b/net/bluetooth/rfcomm/core.c	2005-01-19 13:44:45 -08:00
@@ -50,7 +50,7 @@
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/rfcomm.h>
 
-#define VERSION "1.3"
+#define VERSION "1.4"
 
 #ifndef CONFIG_BT_RFCOMM_DEBUG
 #undef  BT_DBG
@@ -61,8 +61,12 @@
 struct proc_dir_entry *proc_bt_rfcomm;
 #endif
 
-struct task_struct *rfcomm_thread;
-DECLARE_MUTEX(rfcomm_sem);
+static struct task_struct *rfcomm_thread;
+
+static DECLARE_MUTEX(rfcomm_sem);
+#define rfcomm_lock()	down(&rfcomm_sem);
+#define rfcomm_unlock()	up(&rfcomm_sem);
+
 unsigned long rfcomm_event;
 
 static LIST_HEAD(session_list);
@@ -81,6 +85,10 @@
 
 static void rfcomm_process_connect(struct rfcomm_session *s);
 
+static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
+static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
+static void rfcomm_session_del(struct rfcomm_session *s);
+
 /* ---- RFCOMM frame parsing macros ---- */
 #define __get_dlci(b)     ((b & 0xfc) >> 2)
 #define __get_channel(b)  ((b & 0xf8) >> 3)
@@ -111,6 +119,21 @@
 #define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
 #define __get_rpn_parity(line)    (((line) >> 3) & 0x3)
 
+static inline void rfcomm_schedule(uint event)
+{
+	if (!rfcomm_thread)
+		return;
+	//set_bit(event, &rfcomm_event);
+	set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
+	wake_up_process(rfcomm_thread);
+}
+
+static inline void rfcomm_session_put(struct rfcomm_session *s)
+{
+	if (atomic_dec_and_test(&s->refcnt))
+		rfcomm_session_del(s);
+}
+
 /* ---- RFCOMM FCS computation ---- */
 
 /* CRC on 2 bytes */
@@ -458,7 +481,7 @@
 }
 
 /* ---- RFCOMM sessions ---- */
-struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
+static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
 {
 	struct rfcomm_session *s = kmalloc(sizeof(*s), GFP_KERNEL);
 	if (!s)
@@ -487,7 +510,7 @@
 	return s;
 }
 
-void rfcomm_session_del(struct rfcomm_session *s)
+static void rfcomm_session_del(struct rfcomm_session *s)
 {
 	int state = s->state;
 
@@ -505,7 +528,7 @@
 		module_put(THIS_MODULE);
 }
 
-struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
+static struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
 {
 	struct rfcomm_session *s;
 	struct list_head *p, *n;
@@ -521,7 +544,7 @@
 	return NULL;
 }
 
-void rfcomm_session_close(struct rfcomm_session *s, int err)
+static void rfcomm_session_close(struct rfcomm_session *s, int err)
 {
 	struct rfcomm_dlc *d;
 	struct list_head *p, *n;
@@ -542,7 +565,7 @@
 	rfcomm_session_put(s);
 }
 
-struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
+static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
 {
 	struct rfcomm_session *s = NULL;
 	struct sockaddr_l2 addr;
diff -Nru a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
--- a/net/bluetooth/rfcomm/sock.c	2005-01-19 13:44:47 -08:00
+++ b/net/bluetooth/rfcomm/sock.c	2005-01-19 13:44:47 -08:00
@@ -51,6 +51,8 @@
 #include <asm/uaccess.h>
 
 #include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/rfcomm.h>
 
 #ifndef CONFIG_BT_RFCOMM_DEBUG
@@ -261,10 +263,18 @@
 
 static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
 {
+	struct rfcomm_pinfo *pi = rfcomm_pi(sk);
+
 	BT_DBG("sk %p", sk);
 
-	if (parent) 
+	if (parent) {
 		sk->sk_type = parent->sk_type;
+		pi->link_mode = rfcomm_pi(parent)->link_mode;
+	} else {
+		pi->link_mode = 0;
+	}
+
+	pi->dlc->link_mode = pi->link_mode;
 }
 
 static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
@@ -393,7 +403,7 @@
 	return err;
 }
 
-int rfcomm_sock_listen(struct socket *sock, int backlog)
+static int rfcomm_sock_listen(struct socket *sock, int backlog)
 {
 	struct sock *sk = sock->sk;
 	int err = 0;
@@ -437,7 +447,7 @@
 	return err;
 }
 
-int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
+static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct sock *sk = sock->sk, *nsk;
@@ -671,12 +681,22 @@
 {
 	struct sock *sk = sock->sk;
 	int err = 0;
+	u32 opt;
 
 	BT_DBG("sk %p", sk);
 
 	lock_sock(sk);
 
 	switch (optname) {
+	case RFCOMM_LM:
+		if (get_user(opt, (u32 __user *) optval)) {
+			err = -EFAULT;
+			break;
+		}
+
+		rfcomm_pi(sk)->link_mode = opt;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -689,7 +709,9 @@
 static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen)
 {
 	struct sock *sk = sock->sk;
-	int len, err = 0; 
+	struct sock *l2cap_sk;
+	struct rfcomm_conninfo cinfo;
+	int len, err = 0;
 
 	BT_DBG("sk %p", sk);
 
@@ -699,10 +721,32 @@
 	lock_sock(sk);
 
 	switch (optname) {
+	case RFCOMM_LM:
+		if (put_user(rfcomm_pi(sk)->link_mode, (u32 __user *) optval))
+			err = -EFAULT;
+		break;
+
+	case RFCOMM_CONNINFO:
+		if (sk->sk_state != BT_CONNECTED) {
+			err = -ENOTCONN;
+			break;
+		}
+
+		l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
+
+		cinfo.hci_handle = l2cap_pi(l2cap_sk)->conn->hcon->handle;
+		memcpy(cinfo.dev_class, l2cap_pi(l2cap_sk)->conn->hcon->dev_class, 3);
+
+		len = min_t(unsigned int, len, sizeof(cinfo));
+		if (copy_to_user(optval, (char *) &cinfo, len))
+			err = -EFAULT;
+
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
-	};
+	}
 
 	release_sock(sk);
 	return err;
diff -Nru a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
--- a/net/bluetooth/rfcomm/tty.c	2005-01-19 13:44:46 -08:00
+++ b/net/bluetooth/rfcomm/tty.c	2005-01-19 13:44:46 -08:00
@@ -77,7 +77,7 @@
 };
 
 static LIST_HEAD(rfcomm_dev_list);
-static rwlock_t rfcomm_dev_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(rfcomm_dev_lock);
 
 static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
 static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
diff -Nru a/net/bluetooth/sco.c b/net/bluetooth/sco.c
--- a/net/bluetooth/sco.c	2005-01-19 13:44:46 -08:00
+++ b/net/bluetooth/sco.c	2005-01-19 13:44:46 -08:00
@@ -56,7 +56,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "0.3"
+#define VERSION "0.4"
 
 static struct proto_ops sco_sock_ops;
 
@@ -705,6 +705,7 @@
 		}
 
 		cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
+		memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3);
 
 		len = min_t(unsigned int, len, sizeof(cinfo));
 		if (copy_to_user(optval, (char *)&cinfo, len))
@@ -1045,7 +1046,7 @@
 module_init(sco_init);
 module_exit(sco_exit);
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
diff -Nru a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
--- a/net/bridge/br_netfilter.c	2005-01-19 13:44:47 -08:00
+++ b/net/bridge/br_netfilter.c	2005-01-19 13:44:47 -08:00
@@ -845,19 +845,6 @@
 {
 	struct sk_buff *skb = *pskb;
 
-#ifdef CONFIG_SYSCTL
-	if (!skb->nf_bridge) {
-		struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
-
-		if (skb->protocol == __constant_htons(ETH_P_IP) ||
-		    IS_VLAN_IP) {
-			if (!brnf_call_iptables)
-				return NF_ACCEPT;
-		} else if (!brnf_call_ip6tables)
-			return NF_ACCEPT;
-	}
-#endif
-
 	if ((out->hard_start_xmit == br_dev_xmit &&
 	    okfn != br_nf_forward_finish &&
 	    okfn != br_nf_local_out_finish &&
@@ -869,8 +856,24 @@
 	    ) {
 		struct nf_bridge_info *nf_bridge;
 
-		if (!skb->nf_bridge && !nf_bridge_alloc(skb))
-			return NF_DROP;
+		if (!skb->nf_bridge) {
+#ifdef CONFIG_SYSCTL
+			/* This code is executed while in the IP(v6) stack,
+			   the version should be 4 or 6. We can't use
+			   skb->protocol because that isn't set on
+			   PF_INET(6)/LOCAL_OUT. */
+			struct iphdr *ip = skb->nh.iph;
+
+			if (ip->version == 4 && !brnf_call_iptables)
+				return NF_ACCEPT;
+			else if (ip->version == 6 && !brnf_call_ip6tables)
+				return NF_ACCEPT;
+#endif
+			if (hook == NF_IP_POST_ROUTING)
+				return NF_ACCEPT;
+			if (!nf_bridge_alloc(skb))
+				return NF_DROP;
+		}
 
 		nf_bridge = skb->nf_bridge;
 
diff -Nru a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
--- a/net/bridge/netfilter/ebt_limit.c	2005-01-19 13:44:46 -08:00
+++ b/net/bridge/netfilter/ebt_limit.c	2005-01-19 13:44:46 -08:00
@@ -18,7 +18,7 @@
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
 
-static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(limit_lock);
 
 #define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
 
diff -Nru a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
--- a/net/bridge/netfilter/ebt_log.c	2005-01-19 13:44:47 -08:00
+++ b/net/bridge/netfilter/ebt_log.c	2005-01-19 13:44:47 -08:00
@@ -15,7 +15,7 @@
 #include <linux/if_arp.h>
 #include <linux/spinlock.h>
 
-static spinlock_t ebt_log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ebt_log_lock);
 
 static int ebt_log_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
diff -Nru a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
--- a/net/bridge/netfilter/ebt_ulog.c	2005-01-19 13:44:47 -08:00
+++ b/net/bridge/netfilter/ebt_ulog.c	2005-01-19 13:44:47 -08:00
@@ -135,7 +135,7 @@
 
 	size = NLMSG_SPACE(sizeof(*pm) + copy_len);
 	if (size > nlbufsiz) {
-		PRINTR("ebt_ulog: Size %d needed, but nlbufsiz=%d\n",
+		PRINTR("ebt_ulog: Size %Zd needed, but nlbufsiz=%d\n",
 		       size, nlbufsiz);
 		return;
 	}
@@ -255,7 +255,7 @@
 		init_timer(&ulog_buffers[i].timer);
 		ulog_buffers[i].timer.function = ulog_timer;
 		ulog_buffers[i].timer.data = i;
-		ulog_buffers[i].lock = SPIN_LOCK_UNLOCKED;
+		spin_lock_init(&ulog_buffers[i].lock);
 	}
 
 	ebtulognl = netlink_kernel_create(NETLINK_NFLOG, NULL);
diff -Nru a/net/compat.c b/net/compat.c
--- a/net/compat.c	2005-01-19 13:44:47 -08:00
+++ b/net/compat.c	2005-01-19 13:44:47 -08:00
@@ -125,7 +125,7 @@
 	 (struct compat_cmsghdr __user *)NULL)
 
 #define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
-	((ucmlen) >= sizeof(struct cmsghdr) && \
+	((ucmlen) >= sizeof(struct compat_cmsghdr) && \
 	 (ucmlen) <= (unsigned long) \
 	 ((mhdr)->msg_controllen - \
 	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
@@ -507,7 +507,8 @@
 asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
 				char __user *optval, int __user *optlen)
 {
-	if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
+	if (level == SOL_SOCKET &&
+	    (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
 		return do_get_sock_timeout(fd, level, optname, optval, optlen);
 	return sys_getsockopt(fd, level, optname, optval, optlen);
 }
diff -Nru a/net/core/datagram.c b/net/core/datagram.c
--- a/net/core/datagram.c	2005-01-19 13:44:47 -08:00
+++ b/net/core/datagram.c	2005-01-19 13:44:47 -08:00
@@ -199,19 +199,6 @@
 	kfree_skb(skb);
 }
 
-/*
- *	Copy a datagram to a linear buffer.
- */
-int skb_copy_datagram(const struct sk_buff *skb, int offset, char __user *to, int size)
-{
-	struct iovec iov = {
-		.iov_base = to,
-		.iov_len =size,
-	};
-
-	return skb_copy_datagram_iovec(skb, offset, &iov, size);
-}
-
 /**
  *	skb_copy_datagram_iovec - Copy a datagram to an iovec.
  *	@skb - buffer to copy
@@ -296,8 +283,9 @@
 	return -EFAULT;
 }
 
-int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
-			       u8 __user *to, int len, unsigned int *csump)
+static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
+				      u8 __user *to, int len,
+				      unsigned int *csump)
 {
 	int start = skb_headlen(skb);
 	int pos = 0;
@@ -489,7 +477,6 @@
 
 EXPORT_SYMBOL(datagram_poll);
 EXPORT_SYMBOL(skb_copy_and_csum_datagram_iovec);
-EXPORT_SYMBOL(skb_copy_datagram);
 EXPORT_SYMBOL(skb_copy_datagram_iovec);
 EXPORT_SYMBOL(skb_free_datagram);
 EXPORT_SYMBOL(skb_recv_datagram);
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	2005-01-19 13:44:46 -08:00
+++ b/net/core/dev.c	2005-01-19 13:44:46 -08:00
@@ -154,7 +154,7 @@
  *		86DD	IPv6
  */
 
-static spinlock_t ptype_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ptype_lock);
 static struct list_head ptype_base[16];	/* 16 way hashed list */
 static struct list_head ptype_all;		/* Taps */
 
@@ -183,8 +183,8 @@
  * semaphore held.
  */
 struct net_device *dev_base;
-struct net_device **dev_tail = &dev_base;
-rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
+static struct net_device **dev_tail = &dev_base;
+DEFINE_RWLOCK(dev_base_lock);
 
 EXPORT_SYMBOL(dev_base);
 EXPORT_SYMBOL(dev_base_lock);
@@ -361,7 +361,7 @@
  *	returns 0 on error and 1 on success.  This is a generic routine to
  *	all netdevices.
  */
-int netdev_boot_setup_add(char *name, struct ifmap *map)
+static int netdev_boot_setup_add(char *name, struct ifmap *map)
 {
 	struct netdev_boot_setup *s;
 	int i;
@@ -644,7 +644,7 @@
  *	Network device names need to be valid file names to
  *	to allow sysfs to work
  */
-int dev_valid_name(const char *name)
+static int dev_valid_name(const char *name)
 {
 	return !(*name == '\0' 
 		 || !strcmp(name, ".")
@@ -1590,7 +1590,7 @@
  * the ingress scheduler, you just cant add policies on ingress.
  *
  */
-int ing_filter(struct sk_buff *skb) 
+static int ing_filter(struct sk_buff *skb) 
 {
 	struct Qdisc *q;
 	struct net_device *dev = skb->dev;
@@ -2674,7 +2674,7 @@
 static int dev_boot_phase = 1;
 
 /* Delayed registration/unregisteration */
-static spinlock_t net_todo_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(net_todo_list_lock);
 static struct list_head net_todo_list = LIST_HEAD_INIT(net_todo_list);
 
 static inline void net_set_todo(struct net_device *dev)
@@ -3345,10 +3345,5 @@
 #ifdef CONFIG_KMOD
 EXPORT_SYMBOL(dev_load);
 #endif
-
-#ifdef CONFIG_NET_CLS_ACT
-EXPORT_SYMBOL(ing_filter);
-#endif
-
 
 EXPORT_PER_CPU_SYMBOL(softnet_data);
diff -Nru a/net/core/dst.c b/net/core/dst.c
--- a/net/core/dst.c	2005-01-19 13:44:47 -08:00
+++ b/net/core/dst.c	2005-01-19 13:44:47 -08:00
@@ -32,7 +32,7 @@
 #if RT_CACHE_DEBUG >= 2 
 static atomic_t			 dst_total = ATOMIC_INIT(0);
 #endif
-static spinlock_t		 dst_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dst_lock);
 
 static unsigned long dst_gc_timer_expires;
 static unsigned long dst_gc_timer_inc = DST_GC_MAX;
@@ -264,7 +264,7 @@
 	return NOTIFY_DONE;
 }
 
-struct notifier_block dst_dev_notifier = {
+static struct notifier_block dst_dev_notifier = {
 	.notifier_call	= dst_dev_event,
 };
 
diff -Nru a/net/core/dv.c b/net/core/dv.c
--- a/net/core/dv.c	2005-01-19 13:44:46 -08:00
+++ b/net/core/dv.c	2005-01-19 13:44:46 -08:00
@@ -52,26 +52,20 @@
 {
 	int alloc_size = (sizeof(struct divert_blk) + 3) & ~3;
 
+	dev->divert = NULL;
 	if (dev->type == ARPHRD_ETHER) {
-		printk(KERN_DEBUG "divert: allocating divert_blk for %s\n",
-		       dev->name);
-
 		dev->divert = (struct divert_blk *)
 			kmalloc(alloc_size, GFP_KERNEL);
 		if (dev->divert == NULL) {
-			printk(KERN_DEBUG "divert: unable to allocate divert_blk for %s\n",
+			printk(KERN_INFO "divert: unable to allocate divert_blk for %s\n",
 			       dev->name);
 			return -ENOMEM;
-		} else {
-			memset(dev->divert, 0, sizeof(struct divert_blk));
 		}
-		dev_hold(dev);
-	} else {
-		printk(KERN_DEBUG "divert: not allocating divert_blk for non-ethernet device %s\n",
-		       dev->name);
 
-		dev->divert = NULL;
+		memset(dev->divert, 0, sizeof(struct divert_blk));
+		dev_hold(dev);
 	}
+
 	return 0;
 } 
 
@@ -85,11 +79,6 @@
 		kfree(dev->divert);
 		dev->divert=NULL;
 		dev_put(dev);
-		printk(KERN_DEBUG "divert: freeing divert_blk for %s\n",
-		       dev->name);
-	} else {
-		printk(KERN_DEBUG "divert: no divert_blk to free, %s not ethernet\n",
-		       dev->name);
 	}
 }
 
@@ -192,8 +181,12 @@
 /*
  * control function of the diverter
  */
+#if 0
 #define	DVDBG(a)	\
 	printk(KERN_DEBUG "divert_ioctl() line %d %s\n", __LINE__, (a))
+#else
+#define	DVDBG(a)
+#endif
 
 int divert_ioctl(unsigned int cmd, struct divert_cf __user *arg)
 {
diff -Nru a/net/core/gen_estimator.c b/net/core/gen_estimator.c
--- a/net/core/gen_estimator.c	2005-01-19 13:44:47 -08:00
+++ b/net/core/gen_estimator.c	2005-01-19 13:44:47 -08:00
@@ -100,7 +100,7 @@
 static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
 
 /* Estimator array lock */
-static rwlock_t est_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(est_lock);
 
 static void est_timer(unsigned long arg)
 {
diff -Nru a/net/core/iovec.c b/net/core/iovec.c
--- a/net/core/iovec.c	2005-01-19 13:44:48 -08:00
+++ b/net/core/iovec.c	2005-01-19 13:44:48 -08:00
@@ -99,28 +99,6 @@
 }
 
 /*
- *	In kernel copy to iovec. Returns -EFAULT on error.
- *
- *	Note: this modifies the original iovec.
- */
- 
-void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len)
-{
-	while (len > 0) {
-		if (iov->iov_len) {
-			int copy = min_t(unsigned int, iov->iov_len, len);
-			memcpy(iov->iov_base, kdata, copy);
-			kdata += copy;
-			len -= copy;
-			iov->iov_len -= copy;
-			iov->iov_base += copy;
-		}
-		iov++;
-	}
-}
-
-
-/*
  *	Copy iovec to kernel. Returns -EFAULT on error.
  *
  *	Note: this modifies the original iovec.
@@ -259,4 +237,3 @@
 EXPORT_SYMBOL(memcpy_fromiovec);
 EXPORT_SYMBOL(memcpy_fromiovecend);
 EXPORT_SYMBOL(memcpy_toiovec);
-EXPORT_SYMBOL(memcpy_tokerneliovec);
diff -Nru a/net/core/link_watch.c b/net/core/link_watch.c
--- a/net/core/link_watch.c	2005-01-19 13:44:45 -08:00
+++ b/net/core/link_watch.c	2005-01-19 13:44:45 -08:00
@@ -38,7 +38,7 @@
 static DECLARE_WORK(linkwatch_work, linkwatch_event, NULL);
 
 static LIST_HEAD(lweventlist);
-static spinlock_t lweventlist_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(lweventlist_lock);
 
 struct lw_event {
 	struct list_head list;
diff -Nru a/net/core/neighbour.c b/net/core/neighbour.c
--- a/net/core/neighbour.c	2005-01-19 13:44:45 -08:00
+++ b/net/core/neighbour.c	2005-01-19 13:44:45 -08:00
@@ -93,7 +93,7 @@
    list of neighbour tables. This list is used only in process context,
  */
 
-static rwlock_t neigh_tbl_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(neigh_tbl_lock);
 
 static int neigh_blackhole(struct sk_buff *skb)
 {
diff -Nru a/net/core/netfilter.c b/net/core/netfilter.c
--- a/net/core/netfilter.c	2005-01-19 13:44:46 -08:00
+++ b/net/core/netfilter.c	2005-01-19 13:44:46 -08:00
@@ -47,7 +47,7 @@
 
 struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
 static LIST_HEAD(nf_sockopts);
-static spinlock_t nf_hook_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nf_hook_lock);
 
 /* 
  * A queue handler may be registered for each protocol.  Each is protected by
@@ -58,7 +58,7 @@
 	nf_queue_outfn_t outfn;
 	void *data;
 } queue_handler[NPROTO];
-static rwlock_t queue_handler_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(queue_handler_lock);
 
 int nf_register_hook(struct nf_hook_ops *reg)
 {
@@ -173,7 +173,7 @@
 	printk("\n");
 }
 
-void nf_dump_skb(int pf, struct sk_buff *skb)
+static void nf_dump_skb(int pf, struct sk_buff *skb)
 {
 	printk("skb: pf=%i %s dev=%s len=%u\n", 
 	       pf,
@@ -744,7 +744,7 @@
 
 static nf_logfn *nf_logging[NPROTO]; /* = NULL */
 static int reported = 0;
-static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nf_log_lock);
 
 int nf_log_register(int pf, nf_logfn *logfn)
 {
diff -Nru a/net/core/netpoll.c b/net/core/netpoll.c
--- a/net/core/netpoll.c	2005-01-19 13:44:48 -08:00
+++ b/net/core/netpoll.c	2005-01-19 13:44:48 -08:00
@@ -31,15 +31,15 @@
 #define MAX_SKBS 32
 #define MAX_UDP_CHUNK 1460
 
-static spinlock_t skb_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(skb_list_lock);
 static int nr_skbs;
 static struct sk_buff *skbs;
 
-static spinlock_t rx_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rx_list_lock);
 static LIST_HEAD(rx_list);
 
 static atomic_t trapped;
-spinlock_t netpoll_poll_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(netpoll_poll_lock);
 
 #define NETPOLL_RX_ENABLED  1
 #define NETPOLL_RX_DROP     2
@@ -178,7 +178,7 @@
 	return skb;
 }
 
-void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
+static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
 {
 	int status;
 
@@ -676,6 +676,5 @@
 EXPORT_SYMBOL(netpoll_parse_options);
 EXPORT_SYMBOL(netpoll_setup);
 EXPORT_SYMBOL(netpoll_cleanup);
-EXPORT_SYMBOL(netpoll_send_skb);
 EXPORT_SYMBOL(netpoll_send_udp);
 EXPORT_SYMBOL(netpoll_poll);
diff -Nru a/net/core/pktgen.c b/net/core/pktgen.c
--- a/net/core/pktgen.c	2005-01-19 13:44:47 -08:00
+++ b/net/core/pktgen.c	2005-01-19 13:44:47 -08:00
@@ -1,13 +1,22 @@
-/* -*-linux-c-*-
- * $Id: pktgen.c,v 1.8 2002/07/15 19:30:17 robert Exp $
- * pktgen.c: Packet Generator for performance evaluation.
- *
+/*
+ * Authors:
  * Copyright 2001, 2002 by Robert Olsson <robert.olsson@its.uu.se>
- *				 Uppsala University, Sweden
+ *                             Uppsala University and
+ *                             Swedish University of Agricultural Sciences
+ *
+ * Alexey Kuznetsov  <kuznet@ms2.inr.ac.ru>
+ * Ben Greear <greearb@candelatech.com>
+ * Jens Låås <jens.laas@data.slu.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
  *
  * A tool for loading the network with preconfigurated packets.
  * The tool is implemented as a linux module.  Parameters are output 
- * device, IPG (interpacket gap), number of packets, and whether
+ * device, delay (to hard_xmit), number of packets, and whether
  * to use multiple SKBs or just the same one.
  * pktgen uses the installed interface's output routine.
  *
@@ -21,866 +30,702 @@
  * Added multiskb option 020301 --DaveM
  * Scaling of results. 020417--sigurdur@linpro.no
  * Significant re-work of the module:
- *   *  Updated to support generation over multiple interfaces at once
- *       by creating 32 /proc/net/pg* files.  Each file can be manipulated
- *       individually.
+ *   *  Convert to threaded model to more efficiently be able to transmit
+ *       and receive on multiple interfaces at once.
  *   *  Converted many counters to __u64 to allow longer runs.
  *   *  Allow configuration of ranges, like min/max IP address, MACs,
  *       and UDP-ports, for both source and destination, and can
  *       set to use a random distribution or sequentially walk the range.
- *   *  Can now change some values after starting.
+ *   *  Can now change most values after starting.
  *   *  Place 12-byte packet in UDP payload with magic number,
- *       sequence number, and timestamp.  Will write receiver next.
- *   *  The new changes seem to have a performance impact of around 1%,
- *       as far as I can tell.
+ *       sequence number, and timestamp.
+ *   *  Add receiver code that detects dropped pkts, re-ordered pkts, and
+ *       latencies (with micro-second) precision.
+ *   *  Add IOCTL interface to easily get counters & configuration.
  *   --Ben Greear <greearb@candelatech.com>
- * Integrated to 2.5.x 021029 --Lucio Maciel (luciomaciel@zipmail.com.br)
  *
  * Renamed multiskb to clone_skb and cleaned up sending core for two distinct 
  * skb modes. A clone_skb=0 mode for Ben "ranges" work and a clone_skb != 0 
  * as a "fastpath" with a configurable number of clones after alloc's.
- *
  * clone_skb=0 means all packets are allocated this also means ranges time 
  * stamps etc can be used. clone_skb=100 means 1 malloc is followed by 100 
  * clones.
  *
  * Also moved to /proc/net/pktgen/ 
- * --ro 
+ * --ro
+ *
+ * Sept 10:  Fixed threading/locking.  Lots of bone-headed and more clever
+ *    mistakes.  Also merged in DaveM's patch in the -pre6 patch.
+ * --Ben Greear <greearb@candelatech.com>
+ *
+ * Integrated to 2.5.x 021029 --Lucio Maciel (luciomaciel@zipmail.com.br)
+ *
+ * 
+ * 021124 Finished major redesign and rewrite for new functionality.
+ * See Documentation/networking/pktgen.txt for how to use this.
+ *
+ * The new operation:
+ * For each CPU one thread/process is created at start. This process checks 
+ * for running devices in the if_list and sends packets until count is 0 it 
+ * also the thread checks the thread->control which is used for inter-process 
+ * communication. controlling process "posts" operations to the threads this 
+ * way. The if_lock should be possible to remove when add/rem_device is merged
+ * into this too.
+ *
+ * By design there should only be *one* "controlling" process. In practice 
+ * multiple write accesses gives unpredictable result. Understood by "write" 
+ * to /proc gives result code thats should be read be the "writer".
+ * For pratical use this should be no problem.
+ *
+ * Note when adding devices to a specific CPU there good idea to also assign 
+ * /proc/irq/XX/smp_affinity so TX-interrupts gets bound to the same CPU. 
+ * --ro
  *
  * Fix refcount off by one if first packet fails, potential null deref, 
  * memleak 030710- KJP
  *
+ * First "ranges" functionality for ipv6 030726 --ro
+ *
+ * Included flow support. 030802 ANK.
+ *
  * Fixed unaligned access on IA-64 Grant Grundler <grundler@parisc-linux.org>
+ * 
+ * Remove if fix from added Harald Welte <laforge@netfilter.org> 040419
+ * ia64 compilation fix from  Aron Griffis <aron@hp.com> 040604
  *
  * New xmit() return, do_div and misc clean up by Stephen Hemminger 
  * <shemminger@osdl.org> 040923
  *
- * See Documentation/networking/pktgen.txt for how to use this.
+ * Rany Dunlap fixed u64 printk compiler waring 
+ *
+ * Remove FCS from BW calculation.  Lennert Buytenhek <buytenh@wantstofly.org>
+ * New time handling. Lennert Buytenhek <buytenh@wantstofly.org> 041213
+ *
+ * Corrections from Nikolai Malykh (nmalykh@bilim.com) 
+ * Removed unused flags F_SET_SRCMAC & F_SET_SRCIP 041230
+ *
  */
-
+#include <linux/sys.h>
+#include <linux/types.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+#include <linux/smp_lock.h>
 #include <linux/sched.h>
-#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/sched.h>
+#include <linux/unistd.h>
 #include <linux/string.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/inet.h>
-#include <linux/rcupdate.h>
-#include <linux/bitops.h>
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/inet.h>
 #include <linux/inetdevice.h>
 #include <linux/rtnetlink.h>
-#include <linux/proc_fs.h>
 #include <linux/if_arp.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/udp.h>
+#include <linux/proc_fs.h>
 #include <net/checksum.h>
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#include <asm/byteorder.h>
+#include <linux/rcupdate.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+#include <asm/div64.h> /* do_div */
 #include <asm/timex.h>
 
-#define cycles()	((u32)get_cycles())
-
-
-#define VERSION "pktgen version 1.32"
-static char version[] __initdata = 
-  "pktgen.c: v1.4: Packet Generator for packet performance testing.\n";
-
-/* Used to help with determining the pkts on receive */
-
-#define PKTGEN_MAGIC 0xbe9be955
 
+#define VERSION  "pktgen v2.54: Packet Generator for packet performance testing.\n"
 
-/* Keep information per interface */
-struct pktgen_info {
-	/* Parameters */
+/* #define PG_DEBUG(a) a */
+#define PG_DEBUG(a) 
 
-	/* If min != max, then we will either do a linear iteration, or
-	 * we will do a random selection from within the range.
-	 */
-	__u32 flags;     
+/* The buckets are exponential in 'width' */
+#define LAT_BUCKETS_MAX 32
+#define IP_NAME_SZ 32
 
+/* Device flag bits */
 #define F_IPSRC_RND   (1<<0)  /* IP-Src Random  */
 #define F_IPDST_RND   (1<<1)  /* IP-Dst Random  */
 #define F_UDPSRC_RND  (1<<2)  /* UDP-Src Random */
 #define F_UDPDST_RND  (1<<3)  /* UDP-Dst Random */
 #define F_MACSRC_RND  (1<<4)  /* MAC-Src Random */
 #define F_MACDST_RND  (1<<5)  /* MAC-Dst Random */
-#define F_SET_SRCMAC  (1<<6)  /* Specify-Src-Mac 
-				 (default is to use Interface's MAC Addr) */
-#define F_SET_SRCIP   (1<<7)  /*  Specify-Src-IP
-				  (default is to use Interface's IP Addr) */ 
+#define F_TXSIZE_RND  (1<<6)  /* Transmit size is random */
+#define F_IPV6        (1<<7)  /* Interface in IPV6 Mode */
 
-	
-	int pkt_size;    /* = ETH_ZLEN; */
-	int nfrags;
-	__u32 ipg;       /* Default Interpacket gap in nsec */
-	__u64 count;     /* Default No packets to send */
-	__u64 sofar;     /* How many pkts we've sent so far */
-	__u64 errors;    /* Errors when trying to transmit, pkts will be re-sent */
-	struct timeval started_at;
-	struct timeval stopped_at;
-	__u64 idle_acc;
-	__u32 seq_num;
-	
-	int clone_skb;   /* Use multiple SKBs during packet gen.  If this number
-			  * is greater than 1, then that many coppies of the same
-			  * packet will be sent before a new packet is allocated.
-			  * For instance, if you want to send 1024 identical packets
-			  * before creating a new packet, set clone_skb to 1024.
-			  */
-	int busy;
-	int do_run_run;   /* if this changes to false, the test will stop */
-	
-	char outdev[32];
-	char dst_min[32];
-	char dst_max[32];
-	char src_min[32];
-	char src_max[32];
+#define L_PUSH(t, i)              {i->next = t; t=i;}
+#define L_POP(t, i)               {i=t; if(i) t = i->next;}
+
+/* Thread control flag bits */
+#define T_TERMINATE   (1<<0)  
+#define T_STOP        (1<<1)  /* Stop run */
+#define T_RUN         (1<<2)  /* Start run */
+#define T_REMDEV      (1<<3)  /* Remove all devs */
+
+/* Locks */
+#define   thread_lock()        spin_lock(&_thread_lock)
+#define   thread_unlock()      spin_unlock(&_thread_lock)
+
+/* If lock -- can be removed after some work */
+#define   if_lock(t)           spin_lock(&(t->if_lock));
+#define   if_unlock(t)           spin_unlock(&(t->if_lock));
+
+/* Used to help with determining the pkts on receive */
+#define PKTGEN_MAGIC 0xbe9be955
+#define PG_PROC_DIR "pktgen"
+
+#define MAX_CFLOWS  65536
+
+struct flow_state
+{
+	__u32		cur_daddr;
+	int		count;
+};
+
+struct pktgen_dev {
 
-	/* If we're doing ranges, random or incremental, then this
-	 * defines the min/max for those ranges.
+	/*
+	 * Try to keep frequent/infrequent used vars. separated.
 	 */
-	__u32 saddr_min; /* inclusive, source IP address */
-	__u32 saddr_max; /* exclusive, source IP address */
-	__u32 daddr_min; /* inclusive, dest IP address */
-	__u32 daddr_max; /* exclusive, dest IP address */
-
-	__u16 udp_src_min; /* inclusive, source UDP port */
-	__u16 udp_src_max; /* exclusive, source UDP port */
-	__u16 udp_dst_min; /* inclusive, dest UDP port */
-	__u16 udp_dst_max; /* exclusive, dest UDP port */
 
-	__u32 src_mac_count; /* How many MACs to iterate through */
-	__u32 dst_mac_count; /* How many MACs to iterate through */
-	
-	unsigned char dst_mac[6];
-	unsigned char src_mac[6];
-	
-	__u32 cur_dst_mac_offset;
-	__u32 cur_src_mac_offset;
-	__u32 cur_saddr;
-	__u32 cur_daddr;
-	__u16 cur_udp_dst;
-	__u16 cur_udp_src;
-	
-	__u8 hh[14];
-	/* = { 
-	   0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB, 
-	   
-	   We fill in SRC address later
-	   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	   0x08, 0x00
-	   };
-	*/
-	__u16 pad; /* pad out the hh struct to an even 16 bytes */
-	char result[512];
-
-	/* proc file names */
-	char fname[80];
-	char busy_fname[80];
-	
-	struct proc_dir_entry *proc_ent;
-	struct proc_dir_entry *busy_proc_ent;
+        char ifname[32];
+        struct proc_dir_entry *proc_ent;
+        char result[512];
+        /* proc file names */
+        char fname[80];
+
+        struct pktgen_thread* pg_thread; /* the owner */
+        struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
+
+        int running;  /* if this changes to false, the test will stop */
+        
+        /* If min != max, then we will either do a linear iteration, or
+         * we will do a random selection from within the range.
+         */
+        __u32 flags;     
+
+        int min_pkt_size;    /* = ETH_ZLEN; */
+        int max_pkt_size;    /* = ETH_ZLEN; */
+        int nfrags;
+        __u32 delay_us;    /* Default delay */
+        __u32 delay_ns;
+        __u64 count;  /* Default No packets to send */
+        __u64 sofar;  /* How many pkts we've sent so far */
+        __u64 tx_bytes; /* How many bytes we've transmitted */
+        __u64 errors;    /* Errors when trying to transmit, pkts will be re-sent */
+
+        /* runtime counters relating to clone_skb */
+        __u64 next_tx_us;          /* timestamp of when to tx next */
+        __u32 next_tx_ns;
+        
+        __u64 allocated_skbs;
+        __u32 clone_count;
+	int last_ok;           /* Was last skb sent? 
+	                        * Or a failed transmit of some sort?  This will keep
+                                * sequence numbers in order, for example.
+				*/
+        __u64 started_at; /* micro-seconds */
+        __u64 stopped_at; /* micro-seconds */
+        __u64 idle_acc; /* micro-seconds */
+        __u32 seq_num;
+        
+        int clone_skb; /* Use multiple SKBs during packet gen.  If this number
+                          * is greater than 1, then that many coppies of the same
+                          * packet will be sent before a new packet is allocated.
+                          * For instance, if you want to send 1024 identical packets
+                          * before creating a new packet, set clone_skb to 1024.
+                          */
+        
+        char dst_min[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */
+        char dst_max[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */
+        char src_min[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */
+        char src_max[IP_NAME_SZ]; /* IP, ie 1.2.3.4 */
+
+	struct in6_addr  in6_saddr;
+	struct in6_addr  in6_daddr;
+	struct in6_addr  cur_in6_daddr;
+	struct in6_addr  cur_in6_saddr;
+	/* For ranges */
+	struct in6_addr  min_in6_daddr;
+	struct in6_addr  max_in6_daddr;
+	struct in6_addr  min_in6_saddr;
+	struct in6_addr  max_in6_saddr;
+
+        /* If we're doing ranges, random or incremental, then this
+         * defines the min/max for those ranges.
+         */
+        __u32 saddr_min; /* inclusive, source IP address */
+        __u32 saddr_max; /* exclusive, source IP address */
+        __u32 daddr_min; /* inclusive, dest IP address */
+        __u32 daddr_max; /* exclusive, dest IP address */
+
+        __u16 udp_src_min; /* inclusive, source UDP port */
+        __u16 udp_src_max; /* exclusive, source UDP port */
+        __u16 udp_dst_min; /* inclusive, dest UDP port */
+        __u16 udp_dst_max; /* exclusive, dest UDP port */
+
+        __u32 src_mac_count; /* How many MACs to iterate through */
+        __u32 dst_mac_count; /* How many MACs to iterate through */
+        
+        unsigned char dst_mac[6];
+        unsigned char src_mac[6];
+        
+        __u32 cur_dst_mac_offset;
+        __u32 cur_src_mac_offset;
+        __u32 cur_saddr;
+        __u32 cur_daddr;
+        __u16 cur_udp_dst;
+        __u16 cur_udp_src;
+        __u32 cur_pkt_size;
+        
+        __u8 hh[14];
+        /* = { 
+           0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB, 
+           
+           We fill in SRC address later
+           0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+           0x08, 0x00
+           };
+        */
+        __u16 pad; /* pad out the hh struct to an even 16 bytes */
+
+        struct sk_buff* skb; /* skb we are to transmit next, mainly used for when we
+                              * are transmitting the same one multiple times
+                              */
+        struct net_device* odev; /* The out-going device.  Note that the device should
+                                  * have it's pg_info pointer pointing back to this
+                                  * device.  This will be set when the user specifies
+                                  * the out-going device name (not when the inject is
+                                  * started as it used to do.)
+                                  */
+	struct flow_state *flows;
+	unsigned cflows;         /* Concurrent flows (config) */
+	unsigned lflow;          /* Flow length  (config) */
+	unsigned nflows;         /* accumulated flows (stats) */
 };
 
 struct pktgen_hdr {
-	__u32 pgh_magic;
-	__u32 seq_num;
+        __u32 pgh_magic;
+        __u32 seq_num;
 	__u32 tv_sec;
 	__u32 tv_usec;
 };
 
-static int cpu_speed;
-static int debug;
+struct pktgen_thread {
+        spinlock_t if_lock;
+        struct pktgen_dev *if_list;           /* All device here */
+        struct pktgen_thread* next;
+        char name[32];
+        char fname[128]; /* name of proc file */
+        struct proc_dir_entry *proc_ent;
+        char result[512];
+        u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
+        
+	/* Field for thread to receive "posted" events terminate, stop ifs etc.*/
+
+        u32 control;
+	int pid;
+	int cpu;
 
-/* Module parameters, defaults. */
-static int count_d = 100000;
-static int ipg_d;
-static int clone_skb_d;
+        wait_queue_head_t queue;
+};
 
+#define REMOVE 1
+#define FIND   0
 
-#define MAX_PKTGEN 8
-static struct pktgen_info pginfos[MAX_PKTGEN];
+/*  This code works around the fact that do_div cannot handle two 64-bit
+    numbers, and regular 64-bit division doesn't work on x86 kernels.
+    --Ben
+*/
 
+#define PG_DIV 0
 
-/** Convert to miliseconds */
-static inline __u64 tv_to_ms(const struct timeval* tv) {
-	__u64 ms = tv->tv_usec / 1000;
-	ms += (__u64)tv->tv_sec * (__u64)1000;
-	return ms;
-}
-
-static inline __u64 getCurMs(void) {
-	struct timeval tv;
-	do_gettimeofday(&tv);
-	return tv_to_ms(&tv);
+/* This was emailed to LMKL by: Chris Caputo <ccaputo@alt.net>
+ * Function copied/adapted/optimized from:
+ *
+ *  nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
+ *
+ * Copyright 1994, University of Cambridge Computer Laboratory
+ * All Rights Reserved.
+ *
+ */
+inline static s64 divremdi3(s64 x, s64 y, int type) 
+{
+        u64 a = (x < 0) ? -x : x;
+        u64 b = (y < 0) ? -y : y;
+        u64 res = 0, d = 1;
+
+        if (b > 0) {
+                while (b < a) {
+                        b <<= 1;
+                        d <<= 1;
+                }
+        }
+        
+        do {
+                if ( a >= b ) {
+                        a -= b;
+                        res += d;
+                }
+                b >>= 1;
+                d >>= 1;
+        }
+        while (d);
+
+        if (PG_DIV == type) {
+                return (((x ^ y) & (1ll<<63)) == 0) ? res : -(s64)res;
+        }
+        else {
+                return ((x & (1ll<<63)) == 0) ? a : -(s64)a;
+        }
 }
 
-#define PG_PROC_DIR "pktgen"
-static struct proc_dir_entry *proc_dir;
+/* End of hacks to deal with 64-bit math on x86 */
 
-static struct net_device *setup_inject(struct pktgen_info* info)
+/** Convert to miliseconds */
+static inline __u64 tv_to_ms(const struct timeval* tv) 
 {
-	struct net_device *odev;
-
-	odev = dev_get_by_name(info->outdev);
-	if (!odev) {
-		sprintf(info->result, "No such netdevice: \"%s\"", info->outdev);
-		goto out;
-	}
-
-	if (odev->type != ARPHRD_ETHER) {
-		sprintf(info->result, "Not ethernet device: \"%s\"", info->outdev);
-		goto out_put;
-	}
-
-	if (!netif_running(odev)) {
-		sprintf(info->result, "Device is down: \"%s\"", info->outdev);
-		goto out_put;
-	}
-
-	/* Default to the interface's mac if not explicitly set. */
-	if (!(info->flags & F_SET_SRCMAC)) {
-		memcpy(&(info->hh[6]), odev->dev_addr, 6);
-	}
-	else {
-		memcpy(&(info->hh[6]), info->src_mac, 6);
-	}
-
-	/* Set up Dest MAC */
-	memcpy(&(info->hh[0]), info->dst_mac, 6);
-	
-	info->saddr_min = 0;
-	info->saddr_max = 0;
-	if (strlen(info->src_min) == 0) {
-		struct in_device *in_dev;
-
-		rcu_read_lock();
-		in_dev = __in_dev_get(odev);
-		if (in_dev) {
-			if (in_dev->ifa_list) {
-				info->saddr_min = in_dev->ifa_list->ifa_address;
-				info->saddr_max = info->saddr_min;
-			}
-		}
-		rcu_read_unlock();
-	}
-	else {
-		info->saddr_min = in_aton(info->src_min);
-		info->saddr_max = in_aton(info->src_max);
-	}
+        __u64 ms = tv->tv_usec / 1000;
+        ms += (__u64)tv->tv_sec * (__u64)1000;
+        return ms;
+}
 
-	info->daddr_min = in_aton(info->dst_min);
-	info->daddr_max = in_aton(info->dst_max);
 
-	/* Initialize current values. */
-	info->cur_dst_mac_offset = 0;
-	info->cur_src_mac_offset = 0;
-	info->cur_saddr = info->saddr_min;
-	info->cur_daddr = info->daddr_min;
-	info->cur_udp_dst = info->udp_dst_min;
-	info->cur_udp_src = info->udp_src_min;
-	
-	return odev;
+/** Convert to micro-seconds */
+static inline __u64 tv_to_us(const struct timeval* tv) 
+{
+        __u64 us = tv->tv_usec;
+        us += (__u64)tv->tv_sec * (__u64)1000000;
+        return us;
+}
 
-out_put:
-	dev_put(odev);
-out:
-	return NULL;
+static inline __u64 pg_div(__u64 n, __u32 base) {
+        __u64 tmp = n;
+        do_div(tmp, base);
+        /* printk("pktgen: pg_div, n: %llu  base: %d  rv: %llu\n",
+                  n, base, tmp); */
+        return tmp;
 }
 
-static void nanospin(int ipg, struct pktgen_info* info)
+static inline __u64 pg_div64(__u64 n, __u64 base) 
 {
-	u32 idle_start, idle;
-
-	idle_start = cycles();
+        __u64 tmp = n;
+/*
+ * How do we know if the architectrure we are running on
+ * supports division with 64 bit base?
+ * 
+ */
+#if defined(__sparc_v9__) || defined(__powerpc64__) || defined(__alpha__) || defined(__x86_64__) || defined(__ia64__) 
 
-	for (;;) {
-		barrier();
-		idle = cycles() - idle_start;
-		if (idle * 1000 >= ipg * cpu_speed)
-			break;
-	}
-	info->idle_acc += idle;
+		do_div(tmp, base);
+#else
+		tmp = divremdi3(n, base, PG_DIV);
+#endif
+        return tmp;
 }
 
-static int calc_mhz(void)
+static inline u32 pktgen_random(void)
 {
-	struct timeval start, stop;
-	u32 start_s, elapsed;
+#if 0
+	__u32 n;
+	get_random_bytes(&n, 4);
+	return n;
+#else
+	return net_random();
+#endif
+}
 
-	do_gettimeofday(&start);
-	start_s = cycles();
-	do {
-		barrier();
-		elapsed = cycles() - start_s;
-		if (elapsed == 0)
-			return 0;
-	} while (elapsed < 1000 * 50000);
-	do_gettimeofday(&stop);
-	return elapsed/(stop.tv_usec-start.tv_usec+1000000*(stop.tv_sec-start.tv_sec));
+static inline __u64 getCurMs(void) 
+{
+        struct timeval tv;
+        do_gettimeofday(&tv);
+        return tv_to_ms(&tv);
 }
 
-static void cycles_calibrate(void)
+static inline __u64 getCurUs(void) 
 {
-	int i;
+        struct timeval tv;
+        do_gettimeofday(&tv);
+        return tv_to_us(&tv);
+}
 
-	for (i = 0; i < 3; i++) {
-		int res = calc_mhz();
-		if (res > cpu_speed)
-			cpu_speed = res;
-	}
+static inline __u64 tv_diff(const struct timeval* a, const struct timeval* b) 
+{
+        return tv_to_us(a) - tv_to_us(b);
 }
 
 
-/* Increment/randomize headers according to flags and current values
- * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
- */
-static void mod_cur_headers(struct pktgen_info* info) {	
-	__u32 imn;
-	__u32 imx;
-	
-	/*  Deal with source MAC */
-	if (info->src_mac_count > 1) {
-		__u32 mc;
-		__u32 tmp;
-		if (info->flags & F_MACSRC_RND) {
-			mc = net_random() % (info->src_mac_count);
-		}
-		else {
-			mc = info->cur_src_mac_offset++;
-			if (info->cur_src_mac_offset > info->src_mac_count) {
-				info->cur_src_mac_offset = 0;
-			}
-		}
+/* old include end */
 
-		tmp = info->src_mac[5] + (mc & 0xFF);
-		info->hh[11] = tmp;
-		tmp = (info->src_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
-		info->hh[10] = tmp;
-		tmp = (info->src_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
-		info->hh[9] = tmp;
-		tmp = (info->src_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
-		info->hh[8] = tmp;
-		tmp = (info->src_mac[1] + (tmp >> 8));
-		info->hh[7] = tmp;	
-	}
-
-	/*  Deal with Destination MAC */
-	if (info->dst_mac_count > 1) {
-		__u32 mc;
-		__u32 tmp;
-		if (info->flags & F_MACDST_RND) {
-			mc = net_random() % (info->dst_mac_count);
-		}
-		else {
-			mc = info->cur_dst_mac_offset++;
-			if (info->cur_dst_mac_offset > info->dst_mac_count) {
-				info->cur_dst_mac_offset = 0;
-			}
-		}
+static char version[] __initdata = VERSION;
 
-		tmp = info->dst_mac[5] + (mc & 0xFF);
-		info->hh[5] = tmp;
-		tmp = (info->dst_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
-		info->hh[4] = tmp;
-		tmp = (info->dst_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
-		info->hh[3] = tmp;
-		tmp = (info->dst_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
-		info->hh[2] = tmp;
-		tmp = (info->dst_mac[1] + (tmp >> 8));
-		info->hh[1] = tmp;	
-	}
-
-	if (info->udp_src_min < info->udp_src_max) {
-		if (info->flags & F_UDPSRC_RND) {
-			info->cur_udp_src = ((net_random() % (info->udp_src_max - info->udp_src_min))
-					     + info->udp_src_min);
-		}
-		else {
-		     info->cur_udp_src++;
-		     if (info->cur_udp_src >= info->udp_src_max) {
-			     info->cur_udp_src = info->udp_src_min;
-		     }
-		}
-	}
-
-	if (info->udp_dst_min < info->udp_dst_max) {
-		if (info->flags & F_UDPDST_RND) {
-			info->cur_udp_dst = ((net_random() % (info->udp_dst_max - info->udp_dst_min))
-					     + info->udp_dst_min);
-		}
-		else {
-		     info->cur_udp_dst++;
-		     if (info->cur_udp_dst >= info->udp_dst_max) {
-			     info->cur_udp_dst = info->udp_dst_min;
-		     }
-		}
-	}
+static ssize_t proc_pgctrl_read(struct file* file, char * buf, size_t count, loff_t *ppos);
+static ssize_t proc_pgctrl_write(struct file* file, const char * buf, size_t count, loff_t *ppos);
+static int proc_if_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
+
+static int proc_thread_read(char *buf , char **start, off_t offset, int len, int *eof, void *data);
+static int proc_if_write(struct file *file, const char *user_buffer, unsigned long count, void *data);
+static int proc_thread_write(struct file *file, const char *user_buffer, unsigned long count, void *data);
+static int create_proc_dir(void);
+static int remove_proc_dir(void);
+
+static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
+static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
+static struct pktgen_thread* pktgen_find_thread(const char* name);
+static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread* t, const char* ifname);
+static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
+static void pktgen_run_all_threads(void);
+static void pktgen_stop_all_threads_ifs(void);
+static int pktgen_stop_device(struct pktgen_dev *pkt_dev);
+static void pktgen_stop(struct pktgen_thread* t);
+static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
+static struct pktgen_dev *pktgen_NN_threads(const char* dev_name, int remove);
+static unsigned int scan_ip6(const char *s,char ip[16]);
+static unsigned int fmt_ip6(char *s,const char ip[16]);
 
-	if ((imn = ntohl(info->saddr_min)) < (imx = ntohl(info->saddr_max))) {
-		__u32 t;
-		if (info->flags & F_IPSRC_RND) {
-			t = ((net_random() % (imx - imn)) + imn);
-		}
-		else {
-		     t = ntohl(info->cur_saddr);
-		     t++;
-		     if (t >= imx) {
-			     t = imn;
-		     }
-		}
-		info->cur_saddr = htonl(t);
-	}
+/* Module parameters, defaults. */
+static int pg_count_d = 1000; /* 1000 pkts by default */
+static int pg_delay_d = 0;
+static int pg_clone_skb_d = 0;
+static int debug = 0;
 
-	if ((imn = ntohl(info->daddr_min)) < (imx = ntohl(info->daddr_max))) {
-		__u32 t;
-		if (info->flags & F_IPDST_RND) {
-			t = ((net_random() % (imx - imn)) + imn);
-		}
-		else {
-		     t = ntohl(info->cur_daddr);
-		     t++;
-		     if (t >= imx) {
-			     t = imn;
-		     }
-		}
-		info->cur_daddr = htonl(t);
-	}
-}/* mod_cur_headers */
+static spinlock_t _thread_lock = SPIN_LOCK_UNLOCKED;
+static struct pktgen_thread *pktgen_threads = NULL;
 
+static char module_fname[128];
+static struct proc_dir_entry *module_proc_ent = NULL;
 
-static struct sk_buff *fill_packet(struct net_device *odev, struct pktgen_info* info)
-{
-	struct sk_buff *skb = NULL;
-	__u8 *eth;
-	struct udphdr *udph;
-	int datalen, iplen;
-	struct iphdr *iph;
-	struct pktgen_hdr *pgh = NULL;
-	
-	skb = alloc_skb(info->pkt_size + 64 + 16, GFP_ATOMIC);
-	if (!skb) {
-		sprintf(info->result, "No memory");
-		return NULL;
-	}
+static struct notifier_block pktgen_notifier_block = {
+	notifier_call: pktgen_device_event,
+};
 
-	skb_reserve(skb, 16);
+static struct file_operations pktgen_fops = {
+        .read     = proc_pgctrl_read,
+        .write    = proc_pgctrl_write,
+	/*  .ioctl    = pktgen_ioctl, later maybe */
+};
 
-	/*  Reserve for ethernet and IP header  */
-	eth = (__u8 *) skb_push(skb, 14);
-	iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
-	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
+/*
+ * /proc handling functions 
+ *
+ */
 
-	/* Update any of the values, used when we're incrementing various
-	 * fields.
-	 */
-	mod_cur_headers(info);
+static struct proc_dir_entry *pg_proc_dir = NULL;
+static int proc_pgctrl_read_eof=0;
 
-	memcpy(eth, info->hh, 14);
-	
-	datalen = info->pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */
-	if (datalen < sizeof(struct pktgen_hdr)) {
-		datalen = sizeof(struct pktgen_hdr);
+static ssize_t proc_pgctrl_read(struct file* file, char * buf,
+                                 size_t count, loff_t *ppos)
+{ 
+	char data[200];
+	int len = 0;
+
+	if(proc_pgctrl_read_eof) {
+		proc_pgctrl_read_eof=0;
+		len = 0;
+		goto out;
 	}
-	
-	udph->source = htons(info->cur_udp_src);
-	udph->dest = htons(info->cur_udp_dst);
-	udph->len = htons(datalen + 8); /* DATA + udphdr */
-	udph->check = 0;  /* No checksum */
 
-	iph->ihl = 5;
-	iph->version = 4;
-	iph->ttl = 3;
-	iph->tos = 0;
-	iph->protocol = IPPROTO_UDP; /* UDP */
-	iph->saddr = info->cur_saddr;
-	iph->daddr = info->cur_daddr;
-	iph->frag_off = 0;
-	iplen = 20 + 8 + datalen;
-	iph->tot_len = htons(iplen);
-	iph->check = 0;
-	iph->check = ip_fast_csum((void *) iph, iph->ihl);
-	skb->protocol = __constant_htons(ETH_P_IP);
-	skb->mac.raw = ((u8 *)iph) - 14;
-	skb->dev = odev;
-	skb->pkt_type = PACKET_HOST;
+	sprintf(data, "%s", VERSION); 
 
-	if (info->nfrags <= 0) {
-		pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
-	} else {
-		int frags = info->nfrags;
-		int i;
+	len = strlen(data);
 
-		/* TODO: Verify this is OK...it sure is ugly. --Ben */
-		pgh = (struct pktgen_hdr*)(((char*)(udph)) + 8);
-		
-		if (frags > MAX_SKB_FRAGS)
-			frags = MAX_SKB_FRAGS;
-		if (datalen > frags*PAGE_SIZE) {
-			skb_put(skb, datalen-frags*PAGE_SIZE);
-			datalen = frags*PAGE_SIZE;
-		}
-
-		i = 0;
-		while (datalen > 0) {
-			struct page *page = alloc_pages(GFP_KERNEL, 0);
-			skb_shinfo(skb)->frags[i].page = page;
-			skb_shinfo(skb)->frags[i].page_offset = 0;
-			skb_shinfo(skb)->frags[i].size =
-				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
-			datalen -= skb_shinfo(skb)->frags[i].size;
-			skb->len += skb_shinfo(skb)->frags[i].size;
-			skb->data_len += skb_shinfo(skb)->frags[i].size;
-			i++;
-			skb_shinfo(skb)->nr_frags = i;
-		}
-
-		while (i < frags) {
-			int rem;
-
-			if (i == 0)
-				break;
-
-			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
-			if (rem == 0)
-				break;
-
-			skb_shinfo(skb)->frags[i - 1].size -= rem;
+	if(len > count) {
+		len =-EFAULT;
+		goto out;
+	}  	
 
-			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];
-			get_page(skb_shinfo(skb)->frags[i].page);
-			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;
-			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;
-			skb_shinfo(skb)->frags[i].size = rem;
-			i++;
-			skb_shinfo(skb)->nr_frags = i;
-		}
-	}
+	if (copy_to_user(buf, data, len)) {
+		len =-EFAULT;
+		goto out;
+	}  
 
-	/* Stamp the time, and sequence number, convert them to network byte order */
-	if (pgh) {
-		struct timeval timestamp;
+	*ppos += len;
+	proc_pgctrl_read_eof=1; /* EOF next call */
 
-		pgh->pgh_magic = htonl(PKTGEN_MAGIC);
-		pgh->seq_num   = htonl(info->seq_num);
-		
-		do_gettimeofday(&timestamp);
-		pgh->tv_sec    = htonl(timestamp.tv_sec);
-		pgh->tv_usec   = htonl(timestamp.tv_usec);
-	}
-	
-	return skb;
+ out:
+	return len;
 }
 
-static void show_results(struct pktgen_info* info, int nr_frags)
+static ssize_t proc_pgctrl_write(struct file* file,const char * buf,
+				 size_t count, loff_t *ppos)
 {
-	__u64 total, bps, mbps, pps;
-	unsigned long idle;
-	int size = info->pkt_size + 4; /* incl 32bit ethernet CRC */
-	char *p = info->result;
+	char *data = NULL;
+	int err = 0;
 
-	total = (info->stopped_at.tv_sec - info->started_at.tv_sec) * 1000000ull
-		+ info->stopped_at.tv_usec - info->started_at.tv_usec;
-
-	BUG_ON(cpu_speed == 0);
-
-	idle = info->idle_acc;
-	do_div(idle, cpu_speed);
+        if (!capable(CAP_NET_ADMIN)){
+                err = -EPERM;
+		goto out;
+        }
 
-	p += sprintf(p, "OK: %llu(c%llu+d%lu) usec, %llu (%dbyte,%dfrags)\n",
-		     (unsigned long long) total,
-		     (unsigned long long) (total - idle), idle,
-		     (unsigned long long) info->sofar,
-		     size, nr_frags);
+	data = (void*)vmalloc ((unsigned int)count);
 
-	pps = info->sofar * USEC_PER_SEC;
-	
-	while ((total >> 32) != 0) {
-		pps >>= 1;
-		total >>= 1;
+	if(!data) {
+		err = -ENOMEM;
+		goto out;
 	}
-
-	do_div(pps, total);
-	
-	bps = pps * 8 * size;
-
-	mbps = bps;
-	do_div(mbps, 1000000);
-	p += sprintf(p, "  %llupps %lluMb/sec (%llubps) errors: %llu",
-		     (unsigned long long) pps,
-		     (unsigned long long) mbps,
-		     (unsigned long long) bps,
-		     (unsigned long long) info->errors);
+	if (copy_from_user(data, buf, count)) {
+		err =-EFAULT;
+		goto out_free;
+	}  
+	data[count-1] = 0; /* Make string */
+
+	if (!strcmp(data, "stop")) 
+		pktgen_stop_all_threads_ifs();
+
+        else if (!strcmp(data, "start")) 
+		pktgen_run_all_threads();
+
+	else 
+		printk("pktgen: Unknown command: %s\n", data);
+
+	err = count;
+
+ out_free:
+	vfree (data);
+ out:
+        return err;
 }
 
-static void inject(struct pktgen_info* info)
+static int proc_if_read(char *buf , char **start, off_t offset,
+                           int len, int *eof, void *data)
 {
-	struct net_device *odev;
-	struct sk_buff *skb = NULL;
-	__u64 lcount = 0;
-	int ret;
-	int last_ok = 1;	   /* Was last skb sent? 
-				    * Or a failed transmit of some sort?  This will keep
-				    * sequence numbers in order, for example.
-				    */
-	__u64 fp = 0;
-	__u32 fp_tmp = 0;
-
-	odev = setup_inject(info);
-	if (!odev)
-		return;
-
-	info->do_run_run = 1; /* Cranke yeself! */
-	info->idle_acc = 0;
-	info->sofar = 0;
-	info->errors = 0;
-	lcount = info->count;
-
-
-	/* Build our initial pkt and place it as a re-try pkt. */
-	skb = fill_packet(odev, info);
-	if (skb == NULL) goto out_reldev;
-
-	do_gettimeofday(&(info->started_at));
-
-	while(info->do_run_run) {
-
-		/* Set a time-stamp, so build a new pkt each time */
-
-		if (last_ok) {
-			if (++fp_tmp >= info->clone_skb ) {
-				kfree_skb(skb);
-				skb = fill_packet(odev, info);
-				if (skb == NULL) {
-					goto out_reldev;
-				}
-				fp++;
-				fp_tmp = 0; /* reset counter */
-			}
-		}
-
-		if (!(odev->features & NETIF_F_LLTX))
-			spin_lock_bh(&odev->xmit_lock);
-		if (!netif_queue_stopped(odev)) {
-
-			atomic_inc(&skb->users);
-
-		retry:
-			ret = odev->hard_start_xmit(skb, odev);
-			if (likely(ret == NETDEV_TX_OK)) {
-				last_ok = 1;	
-				info->sofar++;
-				info->seq_num++;
-			} else if (ret == NETDEV_TX_LOCKED 
-				   && (odev->features & NETIF_F_LLTX)) {
-				cpu_relax();
-				goto retry;
-			} else {
-				atomic_dec(&skb->users);
-				if (debug && net_ratelimit()) {
-				   printk(KERN_INFO "Hard xmit error\n");
-				}
-				info->errors++;
-				last_ok = 0;
-			}
-		}
-		else {
-			/* Re-try it next time */
-			last_ok = 0;
-		}
-		
-		if (!(odev->features & NETIF_F_LLTX))
-			spin_unlock_bh(&odev->xmit_lock);
-
-		if (info->ipg) {
-			/* Try not to busy-spin if we have larger sleep times.
-			 * TODO:  Investigate better ways to do this.
-			 */
-			if (info->ipg < 10000) { /* 10 usecs or less */
-				nanospin(info->ipg, info);
-			}
-			else if (info->ipg < 10000000) { /* 10ms or less */
-				udelay(info->ipg / 1000);
-			}
-			else {
-				mdelay(info->ipg / 1000000);
-			}
-		}
-		
-		if (signal_pending(current)) {
-			break;
-		}
-
-		/* If lcount is zero, then run forever */
-		if ((lcount != 0) && (--lcount == 0)) {
-			if (atomic_read(&skb->users) != 1) {
-				u32 idle_start, idle;
-
-				idle_start = cycles();
-				while (atomic_read(&skb->users) != 1) {
-					if (signal_pending(current)) {
-						break;
-					}
-					schedule();
-				}
-				idle = cycles() - idle_start;
-				info->idle_acc += idle;
-			}
-			break;
-		}
-
-		if (netif_queue_stopped(odev) || need_resched()) {
-			u32 idle_start, idle;
-
-			idle_start = cycles();
-			do {
-				if (signal_pending(current)) {
-					info->do_run_run = 0;
-					break;
-				}
-				if (!netif_running(odev)) {
-					info->do_run_run = 0;
-					break;
-				}
-				if (need_resched())
-					schedule();
-				else
-					do_softirq();
-			} while (netif_queue_stopped(odev));
-			idle = cycles() - idle_start;
-			info->idle_acc += idle;
-		}
-	}/* while we should be running */
-
-	do_gettimeofday(&(info->stopped_at));
-
-	show_results(info, skb_shinfo(skb)->nr_frags);
-
-	kfree_skb(skb);
+	char *p;
+	int i;
+        struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
+        __u64 sa;
+        __u64 stopped;
+        __u64 now = getCurUs();
+        
+	p = buf;
+	p += sprintf(p, "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
+		     (unsigned long long) pkt_dev->count,
+		     pkt_dev->min_pkt_size, pkt_dev->max_pkt_size);
+
+	p += sprintf(p, "     frags: %d  delay: %u  clone_skb: %d  ifname: %s\n",
+                     pkt_dev->nfrags, 1000*pkt_dev->delay_us+pkt_dev->delay_ns, pkt_dev->clone_skb, pkt_dev->ifname);
+
+	p += sprintf(p, "     flows: %u flowlen: %u\n", pkt_dev->cflows, pkt_dev->lflow);
+
+
+	if(pkt_dev->flags & F_IPV6) {
+		char b1[128], b2[128], b3[128];
+		fmt_ip6(b1,  pkt_dev->in6_saddr.s6_addr);
+		fmt_ip6(b2,  pkt_dev->min_in6_saddr.s6_addr);
+		fmt_ip6(b3,  pkt_dev->max_in6_saddr.s6_addr);
+		p += sprintf(p, "     saddr: %s  min_saddr: %s  max_saddr: %s\n", b1, b2, b3);
+
+		fmt_ip6(b1,  pkt_dev->in6_daddr.s6_addr);
+		fmt_ip6(b2,  pkt_dev->min_in6_daddr.s6_addr);
+		fmt_ip6(b3,  pkt_dev->max_in6_daddr.s6_addr);
+		p += sprintf(p, "     daddr: %s  min_daddr: %s  max_daddr: %s\n", b1, b2, b3);
+
+	} 
+	else 
+		p += sprintf(p, "     dst_min: %s  dst_max: %s\n     src_min: %s  src_max: %s\n",
+                     pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min, pkt_dev->src_max);
+
+        p += sprintf(p, "     src_mac: ");
+
+	if ((pkt_dev->src_mac[0] == 0) && 
+	    (pkt_dev->src_mac[1] == 0) && 
+	    (pkt_dev->src_mac[2] == 0) && 
+	    (pkt_dev->src_mac[3] == 0) && 
+	    (pkt_dev->src_mac[4] == 0) && 
+	    (pkt_dev->src_mac[5] == 0)) 
+
+		for (i = 0; i < 6; i++) 
+			p += sprintf(p, "%02X%s", pkt_dev->odev->dev_addr[i], i == 5 ? "  " : ":");
+
+	else 
+		for (i = 0; i < 6; i++) 
+			p += sprintf(p, "%02X%s", pkt_dev->src_mac[i], i == 5 ? "  " : ":");
+
+        p += sprintf(p, "dst_mac: ");
+	for (i = 0; i < 6; i++) 
+		p += sprintf(p, "%02X%s", pkt_dev->dst_mac[i], i == 5 ? "\n" : ":");
+
+        p += sprintf(p, "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
+                     pkt_dev->udp_src_min, pkt_dev->udp_src_max, pkt_dev->udp_dst_min,
+                     pkt_dev->udp_dst_max);
+
+        p += sprintf(p, "     src_mac_count: %d  dst_mac_count: %d \n     Flags: ",
+                     pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
+
+
+        if (pkt_dev->flags &  F_IPV6) 
+                p += sprintf(p, "IPV6  ");
+
+        if (pkt_dev->flags &  F_IPSRC_RND) 
+                p += sprintf(p, "IPSRC_RND  ");
+
+        if (pkt_dev->flags & F_IPDST_RND) 
+                p += sprintf(p, "IPDST_RND  ");
+        
+        if (pkt_dev->flags & F_TXSIZE_RND) 
+                p += sprintf(p, "TXSIZE_RND  ");
+        
+        if (pkt_dev->flags & F_UDPSRC_RND) 
+                p += sprintf(p, "UDPSRC_RND  ");
+        
+        if (pkt_dev->flags & F_UDPDST_RND) 
+                p += sprintf(p, "UDPDST_RND  ");
+        
+        if (pkt_dev->flags & F_MACSRC_RND) 
+                p += sprintf(p, "MACSRC_RND  ");
+        
+        if (pkt_dev->flags & F_MACDST_RND) 
+                p += sprintf(p, "MACDST_RND  ");
+
+        
+        p += sprintf(p, "\n");
+        
+        sa = pkt_dev->started_at;
+        stopped = pkt_dev->stopped_at;
+        if (pkt_dev->running) 
+                stopped = now; /* not really stopped, more like last-running-at */
+        
+        p += sprintf(p, "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %lluus  stopped: %lluus idle: %lluus\n",
+		     (unsigned long long) pkt_dev->sofar,
+		     (unsigned long long) pkt_dev->errors,
+		     (unsigned long long) sa,
+		     (unsigned long long) stopped, 
+		     (unsigned long long) pkt_dev->idle_acc);
 
-out_reldev:
-	if (odev) {
-		dev_put(odev);
-		odev = NULL;
-	}
+        p += sprintf(p, "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
+                     pkt_dev->seq_num, pkt_dev->cur_dst_mac_offset, pkt_dev->cur_src_mac_offset);
 
-	return;
+	if(pkt_dev->flags & F_IPV6) {
+		char b1[128], b2[128];
+		fmt_ip6(b1,  pkt_dev->cur_in6_daddr.s6_addr);
+		fmt_ip6(b2,  pkt_dev->cur_in6_saddr.s6_addr);
+		p += sprintf(p, "     cur_saddr: %s  cur_daddr: %s\n", b2, b1);
+	} 
+	else 
+		p += sprintf(p, "     cur_saddr: 0x%x  cur_daddr: 0x%x\n",
+                     pkt_dev->cur_saddr, pkt_dev->cur_daddr);
 
-}
 
-/* proc/net/pktgen/pg */
+	p += sprintf(p, "     cur_udp_dst: %d  cur_udp_src: %d\n",
+                     pkt_dev->cur_udp_dst, pkt_dev->cur_udp_src);
 
-static int proc_busy_read(char *buf , char **start, off_t offset,
-			     int len, int *eof, void *data)
-{
-	char *p;
-	int idx = (int)(long)(data);
-	struct pktgen_info* info = NULL;
-	
-	if ((idx < 0) || (idx >= MAX_PKTGEN)) {
-		printk("ERROR: idx: %i is out of range in proc_write\n", idx);
-		return -EINVAL;
-	}
-	info = &(pginfos[idx]);
-  
-	p = buf;
-	p += sprintf(p, "%d\n", info->busy);
-	*eof = 1;
-  
-	return p-buf;
-}
+	p += sprintf(p, "     flows: %u\n", pkt_dev->nflows);
 
-static int proc_read(char *buf , char **start, off_t offset,
-			int len, int *eof, void *data)
-{
-	char *p;
-	int i;
-	int idx = (int)(long)(data);
-	struct pktgen_info* info = NULL;
-	__u64 sa;
-	__u64 stopped;
-	__u64 now = getCurMs();
-	
-	if ((idx < 0) || (idx >= MAX_PKTGEN)) {
-		printk("ERROR: idx: %i is out of range in proc_write\n", idx);
-		return -EINVAL;
-	}
-	info = &(pginfos[idx]);
-  
-	p = buf;
-	p += sprintf(p, "%s\n", VERSION); /* Help with parsing compatibility */
-	p += sprintf(p, "Params: count %llu  pkt_size: %u  frags: %d  ipg: %u  clone_skb: %d odev \"%s\"\n",
-		     (unsigned long long) info->count,
-		     info->pkt_size, info->nfrags, info->ipg,
-		     info->clone_skb, info->outdev);
-	p += sprintf(p, "     dst_min: %s  dst_max: %s  src_min: %s  src_max: %s\n",
-		     info->dst_min, info->dst_max, info->src_min, info->src_max);
-	p += sprintf(p, "     src_mac: ");
-	for (i = 0; i < 6; i++) {
-		p += sprintf(p, "%02X%s", info->src_mac[i], i == 5 ? "  " : ":");
-	}
-	p += sprintf(p, "dst_mac: ");
-	for (i = 0; i < 6; i++) {
-		p += sprintf(p, "%02X%s", info->dst_mac[i], i == 5 ? "\n" : ":");
-	}
-	p += sprintf(p, "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
-		     info->udp_src_min, info->udp_src_max, info->udp_dst_min,
-		     info->udp_dst_max);
-	p += sprintf(p, "     src_mac_count: %d  dst_mac_count: %d\n     Flags: ",
-		     info->src_mac_count, info->dst_mac_count);
-	if (info->flags &  F_IPSRC_RND) {
-		p += sprintf(p, "IPSRC_RND  ");
-	}
-	if (info->flags & F_IPDST_RND) {
-		p += sprintf(p, "IPDST_RND  ");
-	}
-	if (info->flags & F_UDPSRC_RND) {
-		p += sprintf(p, "UDPSRC_RND  ");
-	}
-	if (info->flags & F_UDPDST_RND) {
-		p += sprintf(p, "UDPDST_RND  ");
-	}
-	if (info->flags & F_MACSRC_RND) {
-		p += sprintf(p, "MACSRC_RND  ");
-	}
-	if (info->flags & F_MACDST_RND) {
-		p += sprintf(p, "MACDST_RND  ");
-	}
-	p += sprintf(p, "\n");
-	
-	sa = tv_to_ms(&(info->started_at));
-	stopped = tv_to_ms(&(info->stopped_at));
-	if (info->do_run_run) {
-		stopped = now; /* not really stopped, more like last-running-at */
-	}
-	p += sprintf(p, "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %llums  stopped: %llums  now: %llums  idle: %lluns\n",
-		     (unsigned long long) info->sofar,
-		     (unsigned long long) info->errors,
-		     (unsigned long long) sa,
-		     (unsigned long long) stopped,
-		     (unsigned long long) now,
-		     (unsigned long long) info->idle_acc);
-	p += sprintf(p, "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
-		     info->seq_num, info->cur_dst_mac_offset, info->cur_src_mac_offset);
-	p += sprintf(p, "     cur_saddr: 0x%x  cur_daddr: 0x%x  cur_udp_dst: %d  cur_udp_src: %d\n",
-		     info->cur_saddr, info->cur_daddr, info->cur_udp_dst, info->cur_udp_src);
-	
-	if (info->result[0])
-		p += sprintf(p, "Result: %s\n", info->result);
+	if (pkt_dev->result[0])
+		p += sprintf(p, "Result: %s\n", pkt_dev->result);
 	else
 		p += sprintf(p, "Result: Idle\n");
 	*eof = 1;
@@ -888,16 +733,16 @@
 	return p - buf;
 }
 
-static int count_trail_chars(const char __user *user_buffer, unsigned int maxlen)
+
+static int count_trail_chars(const char *user_buffer, unsigned int maxlen)
 {
 	int i;
 
 	for (i = 0; i < maxlen; i++) {
-		char c;
-
-		if (get_user(c, &user_buffer[i]))
-			return -EFAULT;
-		switch (c) {
+                char c;
+                if (get_user(c, &user_buffer[i]))
+                        return -EFAULT;
+                switch (c) {
 		case '\"':
 		case '\n':
 		case '\r':
@@ -913,19 +758,17 @@
 	return i;
 }
 
-static unsigned long num_arg(const char __user *user_buffer, unsigned long maxlen,
+static unsigned long num_arg(const char *user_buffer, unsigned long maxlen, 
 			     unsigned long *num)
 {
 	int i = 0;
-
 	*num = 0;
   
 	for(; i < maxlen; i++) {
-		char c;
-
-		if (get_user(c, &user_buffer[i]))
-			return -EFAULT;
-		if ((c >= '0') && (c <= '9')) {
+                char c;
+                if (get_user(c, &user_buffer[i]))
+                        return -EFAULT;
+                if ((c >= '0') && (c <= '9')) {
 			*num *= 10;
 			*num += c -'0';
 		} else
@@ -934,321 +777,485 @@
 	return i;
 }
 
-static int strn_len(const char __user *user_buffer, unsigned int maxlen)
+static int strn_len(const char *user_buffer, unsigned int maxlen)
 {
 	int i = 0;
 
 	for(; i < maxlen; i++) {
-		char c;
-
-		if (get_user(c, &user_buffer[i]))
-			return -EFAULT;
-		switch (c) {
+                char c;
+                if (get_user(c, &user_buffer[i]))
+                        return -EFAULT;
+                switch (c) {
 		case '\"':
 		case '\n':
 		case '\r':
 		case '\t':
 		case ' ':
 			goto done_str;
+			break;
 		default:
 			break;
 		};
 	}
 done_str:
+
 	return i;
 }
 
-static int proc_write(struct file *file, const char __user *user_buffer,
-			 unsigned long count, void *data)
+static int proc_if_write(struct file *file, const char *user_buffer,
+                            unsigned long count, void *data)
 {
 	int i = 0, max, len;
 	char name[16], valstr[32];
 	unsigned long value = 0;
-	int idx = (int)(long)(data);
-	struct pktgen_info* info = NULL;
-	char* result = NULL;
-	int tmp;
-	
-	if ((idx < 0) || (idx >= MAX_PKTGEN)) {
-		printk("ERROR: idx: %i is out of range in proc_write\n", idx);
-		return -EINVAL;
-	}
-	info = &(pginfos[idx]);
-	result = &(info->result[0]);
-	
+        struct pktgen_dev *pkt_dev = (struct pktgen_dev*)(data);
+        char* pg_result = NULL;
+        int tmp = 0;
+        
+        pg_result = &(pkt_dev->result[0]);
+        
 	if (count < 1) {
-		sprintf(result, "Wrong command format");
+		printk("pktgen: wrong command format\n");
 		return -EINVAL;
 	}
   
 	max = count - i;
 	tmp = count_trail_chars(&user_buffer[i], max);
-	if (tmp < 0)
-		return tmp;
-	i += tmp;
-  
+        if (tmp < 0) { 
+		printk("pktgen: illegal format\n");
+		return tmp; 
+	}
+        i += tmp;
+        
 	/* Read variable name */
 
 	len = strn_len(&user_buffer[i], sizeof(name) - 1);
-	if (len < 0)
-		return len;
+        if (len < 0) { return len; }
 	memset(name, 0, sizeof(name));
-	if (copy_from_user(name, &user_buffer[i], len))
+	if (copy_from_user(name, &user_buffer[i], len) )
 		return -EFAULT;
 	i += len;
   
 	max = count -i;
 	len = count_trail_chars(&user_buffer[i], max);
-	if (len < 0)
-		return len;
+        if (len < 0) 
+                return len;
+        
 	i += len;
 
-	if (debug)
-		printk("pg: %s,%lu\n", name, count);
+	if (debug) {
+                char tb[count + 1];
+                if (copy_from_user(tb, user_buffer, count))
+			return -EFAULT;
+                tb[count] = 0;
+		printk("pktgen: %s,%lu  buffer -:%s:-\n", name, count, tb);
+        }
 
-	if (!strcmp(name, "stop")) {
-		if (info->do_run_run) {
-			strcpy(result, "Stopping");
-		}
-		else {
-			strcpy(result, "Already stopped...\n");
-		}
-		info->do_run_run = 0;
+	if (!strcmp(name, "min_pkt_size")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
+		i += len;
+		if (value < 14+20+8)
+			value = 14+20+8;
+                if (value != pkt_dev->min_pkt_size) {
+                        pkt_dev->min_pkt_size = value;
+                        pkt_dev->cur_pkt_size = value;
+                }
+		sprintf(pg_result, "OK: min_pkt_size=%u", pkt_dev->min_pkt_size);
 		return count;
 	}
 
+        if (!strcmp(name, "max_pkt_size")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
+		i += len;
+		if (value < 14+20+8)
+			value = 14+20+8;
+                if (value != pkt_dev->max_pkt_size) {
+                        pkt_dev->max_pkt_size = value;
+                        pkt_dev->cur_pkt_size = value;
+                }
+		sprintf(pg_result, "OK: max_pkt_size=%u", pkt_dev->max_pkt_size);
+		return count;
+	}
+
+        /* Shortcut for min = max */
+
 	if (!strcmp(name, "pkt_size")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
 		if (value < 14+20+8)
 			value = 14+20+8;
-		info->pkt_size = value;
-		sprintf(result, "OK: pkt_size=%u", info->pkt_size);
+                if (value != pkt_dev->min_pkt_size) {
+                        pkt_dev->min_pkt_size = value;
+                        pkt_dev->max_pkt_size = value;
+                        pkt_dev->cur_pkt_size = value;
+                }
+		sprintf(pg_result, "OK: pkt_size=%u", pkt_dev->min_pkt_size);
 		return count;
 	}
-	if (!strcmp(name, "frags")) {
+
+        if (!strcmp(name, "debug")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-		info->nfrags = value;
-		sprintf(result, "OK: frags=%u", info->nfrags);
+                debug = value;
+		sprintf(pg_result, "OK: debug=%u", debug);
 		return count;
 	}
-	if (!strcmp(name, "ipg")) {
+
+        if (!strcmp(name, "frags")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
+		i += len;
+		pkt_dev->nfrags = value;
+		sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags);
+		return count;
+	}
+	if (!strcmp(name, "delay")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
 		i += len;
-		info->ipg = value;
-		sprintf(result, "OK: ipg=%u", info->ipg);
+		if (value == 0x7FFFFFFF) {
+			pkt_dev->delay_us = 0x7FFFFFFF;
+			pkt_dev->delay_ns = 0;
+		} else {
+			pkt_dev->delay_us = value / 1000;
+			pkt_dev->delay_ns = value % 1000;
+		}
+		sprintf(pg_result, "OK: delay=%u", 1000*pkt_dev->delay_us+pkt_dev->delay_ns);
 		return count;
 	}
  	if (!strcmp(name, "udp_src_min")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-	 	info->udp_src_min = value;
-		sprintf(result, "OK: udp_src_min=%u", info->udp_src_min);
+                if (value != pkt_dev->udp_src_min) {
+                        pkt_dev->udp_src_min = value;
+                        pkt_dev->cur_udp_src = value;
+                }       
+		sprintf(pg_result, "OK: udp_src_min=%u", pkt_dev->udp_src_min);
 		return count;
 	}
  	if (!strcmp(name, "udp_dst_min")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-	 	info->udp_dst_min = value;
-		sprintf(result, "OK: udp_dst_min=%u", info->udp_dst_min);
+                if (value != pkt_dev->udp_dst_min) {
+                        pkt_dev->udp_dst_min = value;
+                        pkt_dev->cur_udp_dst = value;
+                }
+		sprintf(pg_result, "OK: udp_dst_min=%u", pkt_dev->udp_dst_min);
 		return count;
 	}
  	if (!strcmp(name, "udp_src_max")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-	 	info->udp_src_max = value;
-		sprintf(result, "OK: udp_src_max=%u", info->udp_src_max);
+                if (value != pkt_dev->udp_src_max) {
+                        pkt_dev->udp_src_max = value;
+                        pkt_dev->cur_udp_src = value;
+                }
+		sprintf(pg_result, "OK: udp_src_max=%u", pkt_dev->udp_src_max);
 		return count;
 	}
  	if (!strcmp(name, "udp_dst_max")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-	 	info->udp_dst_max = value;
-		sprintf(result, "OK: udp_dst_max=%u", info->udp_dst_max);
+                if (value != pkt_dev->udp_dst_max) {
+                        pkt_dev->udp_dst_max = value;
+                        pkt_dev->cur_udp_dst = value;
+                }
+		sprintf(pg_result, "OK: udp_dst_max=%u", pkt_dev->udp_dst_max);
 		return count;
 	}
 	if (!strcmp(name, "clone_skb")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-		info->clone_skb = value;
+                pkt_dev->clone_skb = value;
 	
-		sprintf(result, "OK: clone_skb=%d", info->clone_skb);
+		sprintf(pg_result, "OK: clone_skb=%d", pkt_dev->clone_skb);
 		return count;
 	}
 	if (!strcmp(name, "count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-		info->count = value;
-		sprintf(result, "OK: count=%llu", (unsigned long long) info->count);
+		pkt_dev->count = value;
+		sprintf(pg_result, "OK: count=%llu",
+			(unsigned long long) pkt_dev->count);
 		return count;
 	}
 	if (!strcmp(name, "src_mac_count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		i += len;
-		info->src_mac_count = value;
-		sprintf(result, "OK: src_mac_count=%d", info->src_mac_count);
+		if (pkt_dev->src_mac_count != value) {
+                        pkt_dev->src_mac_count = value;
+                        pkt_dev->cur_src_mac_offset = 0;
+                }
+		sprintf(pg_result, "OK: src_mac_count=%d", pkt_dev->src_mac_count);
 		return count;
 	}
 	if (!strcmp(name, "dst_mac_count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0)
-			return len;
-		i += len;
-		info->dst_mac_count = value;
-		sprintf(result, "OK: dst_mac_count=%d", info->dst_mac_count);
-		return count;
-	}
-	if (!strcmp(name, "odev")) {
-		len = strn_len(&user_buffer[i], sizeof(info->outdev) - 1);
-		if (len < 0)
-			return len;
-		memset(info->outdev, 0, sizeof(info->outdev));
-		if (copy_from_user(info->outdev, &user_buffer[i], len))
-			return -EFAULT;
+                if (len < 0) { return len; }
 		i += len;
-		sprintf(result, "OK: odev=%s", info->outdev);
+		if (pkt_dev->dst_mac_count != value) {
+                        pkt_dev->dst_mac_count = value;
+                        pkt_dev->cur_dst_mac_offset = 0;
+                }
+		sprintf(pg_result, "OK: dst_mac_count=%d", pkt_dev->dst_mac_count);
 		return count;
 	}
 	if (!strcmp(name, "flag")) {
-		char f[32];
+                char f[32];
+                memset(f, 0, 32);
 		len = strn_len(&user_buffer[i], sizeof(f) - 1);
-		if (len < 0)
-			return len;
-		memset(f, 0, 32);
+                if (len < 0) { return len; }
 		if (copy_from_user(f, &user_buffer[i], len))
 			return -EFAULT;
 		i += len;
-		if (strcmp(f, "IPSRC_RND") == 0) {
-			info->flags |= F_IPSRC_RND;
-		}
-		else if (strcmp(f, "!IPSRC_RND") == 0) {
-			info->flags &= ~F_IPSRC_RND;
-		}
-		else if (strcmp(f, "IPDST_RND") == 0) {
-			info->flags |= F_IPDST_RND;
-		}
-		else if (strcmp(f, "!IPDST_RND") == 0) {
-			info->flags &= ~F_IPDST_RND;
-		}
-		else if (strcmp(f, "UDPSRC_RND") == 0) {
-			info->flags |= F_UDPSRC_RND;
-		}
-		else if (strcmp(f, "!UDPSRC_RND") == 0) {
-			info->flags &= ~F_UDPSRC_RND;
-		}
-		else if (strcmp(f, "UDPDST_RND") == 0) {
-			info->flags |= F_UDPDST_RND;
-		}
-		else if (strcmp(f, "!UDPDST_RND") == 0) {
-			info->flags &= ~F_UDPDST_RND;
-		}
-		else if (strcmp(f, "MACSRC_RND") == 0) {
-			info->flags |= F_MACSRC_RND;
-		}
-		else if (strcmp(f, "!MACSRC_RND") == 0) {
-			info->flags &= ~F_MACSRC_RND;
-		}
-		else if (strcmp(f, "MACDST_RND") == 0) {
-			info->flags |= F_MACDST_RND;
-		}
-		else if (strcmp(f, "!MACDST_RND") == 0) {
-			info->flags &= ~F_MACDST_RND;
-		}
-		else {
-			sprintf(result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
-				f,
-				"IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n");
-			return count;
-		}
-		sprintf(result, "OK: flags=0x%x", info->flags);
+                if (strcmp(f, "IPSRC_RND") == 0) 
+                        pkt_dev->flags |= F_IPSRC_RND;
+                
+                else if (strcmp(f, "!IPSRC_RND") == 0) 
+                        pkt_dev->flags &= ~F_IPSRC_RND;
+                
+                else if (strcmp(f, "TXSIZE_RND") == 0) 
+                        pkt_dev->flags |= F_TXSIZE_RND;
+                
+                else if (strcmp(f, "!TXSIZE_RND") == 0) 
+                        pkt_dev->flags &= ~F_TXSIZE_RND;
+                
+                else if (strcmp(f, "IPDST_RND") == 0) 
+                        pkt_dev->flags |= F_IPDST_RND;
+                
+                else if (strcmp(f, "!IPDST_RND") == 0) 
+                        pkt_dev->flags &= ~F_IPDST_RND;
+                
+                else if (strcmp(f, "UDPSRC_RND") == 0) 
+                        pkt_dev->flags |= F_UDPSRC_RND;
+                
+                else if (strcmp(f, "!UDPSRC_RND") == 0) 
+                        pkt_dev->flags &= ~F_UDPSRC_RND;
+                
+                else if (strcmp(f, "UDPDST_RND") == 0) 
+                        pkt_dev->flags |= F_UDPDST_RND;
+                
+                else if (strcmp(f, "!UDPDST_RND") == 0) 
+                        pkt_dev->flags &= ~F_UDPDST_RND;
+                
+                else if (strcmp(f, "MACSRC_RND") == 0) 
+                        pkt_dev->flags |= F_MACSRC_RND;
+                
+                else if (strcmp(f, "!MACSRC_RND") == 0) 
+                        pkt_dev->flags &= ~F_MACSRC_RND;
+                
+                else if (strcmp(f, "MACDST_RND") == 0) 
+                        pkt_dev->flags |= F_MACDST_RND;
+                
+                else if (strcmp(f, "!MACDST_RND") == 0) 
+                        pkt_dev->flags &= ~F_MACDST_RND;
+                
+                else {
+                        sprintf(pg_result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
+                                f,
+                                "IPSRC_RND, IPDST_RND, TXSIZE_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND\n");
+                        return count;
+                }
+		sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
 		return count;
 	}
 	if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) {
-		len = strn_len(&user_buffer[i], sizeof(info->dst_min) - 1);
-		if (len < 0)
-			return len;
-		memset(info->dst_min, 0, sizeof(info->dst_min));
-		if (copy_from_user(info->dst_min, &user_buffer[i], len))
+                char buf[IP_NAME_SZ];
+		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1);
+                if (len < 0) { return len; }
+
+                if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
-		if(debug)
-			printk("pg: dst_min set to: %s\n", info->dst_min);
-		i += len;
-		sprintf(result, "OK: dst_min=%s", info->dst_min);
+                buf[len] = 0;
+                if (strcmp(buf, pkt_dev->dst_min) != 0) {
+                        memset(pkt_dev->dst_min, 0, sizeof(pkt_dev->dst_min));
+                        strncpy(pkt_dev->dst_min, buf, len);
+                        pkt_dev->daddr_min = in_aton(pkt_dev->dst_min);
+                        pkt_dev->cur_daddr = pkt_dev->daddr_min;
+                }
+                if(debug)
+                        printk("pktgen: dst_min set to: %s\n", pkt_dev->dst_min);
+                i += len;
+		sprintf(pg_result, "OK: dst_min=%s", pkt_dev->dst_min);
 		return count;
 	}
 	if (!strcmp(name, "dst_max")) {
-		len = strn_len(&user_buffer[i], sizeof(info->dst_max) - 1);
-		if (len < 0)
-			return len;
-		memset(info->dst_max, 0, sizeof(info->dst_max));
-		if (copy_from_user(info->dst_max, &user_buffer[i], len))
+                char buf[IP_NAME_SZ];
+		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1);
+                if (len < 0) { return len; }
+
+                if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
+
+                buf[len] = 0;
+                if (strcmp(buf, pkt_dev->dst_max) != 0) {
+                        memset(pkt_dev->dst_max, 0, sizeof(pkt_dev->dst_max));
+                        strncpy(pkt_dev->dst_max, buf, len);
+                        pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
+                        pkt_dev->cur_daddr = pkt_dev->daddr_max;
+                }
 		if(debug)
-			printk("pg: dst_max set to: %s\n", info->dst_max);
+			printk("pktgen: dst_max set to: %s\n", pkt_dev->dst_max);
 		i += len;
-		sprintf(result, "OK: dst_max=%s", info->dst_max);
+		sprintf(pg_result, "OK: dst_max=%s", pkt_dev->dst_max);
+		return count;
+	}
+	if (!strcmp(name, "dst6")) {
+                char buf[128];
+
+		len = strn_len(&user_buffer[i], 128 - 1);
+                if (len < 0) return len; 
+
+		pkt_dev->flags |= F_IPV6;
+
+                if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+                buf[len] = 0;
+
+		scan_ip6(buf, pkt_dev->in6_daddr.s6_addr);
+		fmt_ip6(buf,  pkt_dev->in6_daddr.s6_addr);
+
+		ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->in6_daddr);
+
+                if(debug) 
+			printk("pktgen: dst6 set to: %s\n", buf);
+
+                i += len;
+		sprintf(pg_result, "OK: dst6=%s", buf);
+		return count;
+	}
+	if (!strcmp(name, "dst6_min")) {
+                char buf[128];
+
+		len = strn_len(&user_buffer[i], 128 - 1);
+                if (len < 0) return len; 
+
+		pkt_dev->flags |= F_IPV6;
+
+                if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+                buf[len] = 0;
+
+		scan_ip6(buf, pkt_dev->min_in6_daddr.s6_addr);
+		fmt_ip6(buf,  pkt_dev->min_in6_daddr.s6_addr);
+
+		ipv6_addr_copy(&pkt_dev->cur_in6_daddr, &pkt_dev->min_in6_daddr);
+                if(debug) 
+			printk("pktgen: dst6_min set to: %s\n", buf);
+
+                i += len;
+		sprintf(pg_result, "OK: dst6_min=%s", buf);
+		return count;
+	}
+	if (!strcmp(name, "dst6_max")) {
+                char buf[128];
+
+		len = strn_len(&user_buffer[i], 128 - 1);
+                if (len < 0) return len; 
+
+		pkt_dev->flags |= F_IPV6;
+
+                if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+                buf[len] = 0;
+
+		scan_ip6(buf, pkt_dev->max_in6_daddr.s6_addr);
+		fmt_ip6(buf,  pkt_dev->max_in6_daddr.s6_addr);
+
+                if(debug) 
+			printk("pktgen: dst6_max set to: %s\n", buf);
+
+                i += len;
+		sprintf(pg_result, "OK: dst6_max=%s", buf);
+		return count;
+	}
+	if (!strcmp(name, "src6")) {
+                char buf[128];
+
+		len = strn_len(&user_buffer[i], 128 - 1);
+                if (len < 0) return len; 
+
+		pkt_dev->flags |= F_IPV6;
+
+                if (copy_from_user(buf, &user_buffer[i], len))
+			return -EFAULT;
+                buf[len] = 0;
+
+		scan_ip6(buf, pkt_dev->in6_saddr.s6_addr);
+		fmt_ip6(buf,  pkt_dev->in6_saddr.s6_addr);
+
+		ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &pkt_dev->in6_saddr);
+
+                if(debug) 
+			printk("pktgen: src6 set to: %s\n", buf);
+		
+                i += len;
+		sprintf(pg_result, "OK: src6=%s", buf);
 		return count;
 	}
 	if (!strcmp(name, "src_min")) {
-		len = strn_len(&user_buffer[i], sizeof(info->src_min) - 1);
-		if (len < 0)
-			return len;
-		memset(info->src_min, 0, sizeof(info->src_min));
-		if (copy_from_user(info->src_min, &user_buffer[i], len))
+                char buf[IP_NAME_SZ];
+		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1);
+                if (len < 0) { return len; }
+                if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
+                buf[len] = 0;
+                if (strcmp(buf, pkt_dev->src_min) != 0) {
+                        memset(pkt_dev->src_min, 0, sizeof(pkt_dev->src_min));
+                        strncpy(pkt_dev->src_min, buf, len);
+                        pkt_dev->saddr_min = in_aton(pkt_dev->src_min);
+                        pkt_dev->cur_saddr = pkt_dev->saddr_min;
+                }
 		if(debug)
-			printk("pg: src_min set to: %s\n", info->src_min);
+			printk("pktgen: src_min set to: %s\n", pkt_dev->src_min);
 		i += len;
-		sprintf(result, "OK: src_min=%s", info->src_min);
+		sprintf(pg_result, "OK: src_min=%s", pkt_dev->src_min);
 		return count;
 	}
 	if (!strcmp(name, "src_max")) {
-		len = strn_len(&user_buffer[i], sizeof(info->src_max) - 1);
-		if (len < 0)
-			return len;
-		memset(info->src_max, 0, sizeof(info->src_max));
-		if (copy_from_user(info->src_max, &user_buffer[i], len))
+                char buf[IP_NAME_SZ];
+		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1);
+                if (len < 0) { return len; }
+                if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
+                buf[len] = 0;
+                if (strcmp(buf, pkt_dev->src_max) != 0) {
+                        memset(pkt_dev->src_max, 0, sizeof(pkt_dev->src_max));
+                        strncpy(pkt_dev->src_max, buf, len);
+                        pkt_dev->saddr_max = in_aton(pkt_dev->src_max);
+                        pkt_dev->cur_saddr = pkt_dev->saddr_max;
+                }
 		if(debug)
-			printk("pg: src_max set to: %s\n", info->src_max);
+			printk("pktgen: src_max set to: %s\n", pkt_dev->src_max);
 		i += len;
-		sprintf(result, "OK: src_max=%s", info->src_max);
+		sprintf(pg_result, "OK: src_max=%s", pkt_dev->src_max);
 		return count;
 	}
-	if (!strcmp(name, "dstmac")) {
+	if (!strcmp(name, "dst_mac")) {
 		char *v = valstr;
-		unsigned char *m = info->dst_mac;
-
+                unsigned char old_dmac[6];
+		unsigned char *m = pkt_dev->dst_mac;
+                memcpy(old_dmac, pkt_dev->dst_mac, 6);
+                
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		memset(valstr, 0, sizeof(valstr));
-		if (copy_from_user(valstr, &user_buffer[i], len))
+		if( copy_from_user(valstr, &user_buffer[i], len))
 			return -EFAULT;
 		i += len;
 
-		for(*m = 0;*v && m < info->dst_mac + 6; v++) {
+		for(*m = 0;*v && m < pkt_dev->dst_mac + 6; v++) {
 			if (*v >= '0' && *v <= '9') {
 				*m *= 16;
 				*m += *v - '0';
@@ -1265,23 +1272,27 @@
 				m++;
 				*m = 0;
 			}
-		}	  
-		sprintf(result, "OK: dstmac");
+		}
+
+		/* Set up Dest MAC */
+                if (memcmp(old_dmac, pkt_dev->dst_mac, 6) != 0) 
+                        memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
+                
+		sprintf(pg_result, "OK: dstmac");
 		return count;
 	}
-	if (!strcmp(name, "srcmac")) {
+	if (!strcmp(name, "src_mac")) {
 		char *v = valstr;
-		unsigned char *m = info->src_mac;
+		unsigned char *m = pkt_dev->src_mac;
 
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
-		if (len < 0)
-			return len;
+                if (len < 0) { return len; }
 		memset(valstr, 0, sizeof(valstr));
-		if (copy_from_user(valstr, &user_buffer[i], len))
+		if( copy_from_user(valstr, &user_buffer[i], len)) 
 			return -EFAULT;
 		i += len;
 
-		for(*m = 0;*v && m < info->src_mac + 6; v++) {
+		for(*m = 0;*v && m < pkt_dev->src_mac + 6; v++) {
 			if (*v >= '0' && *v <= '9') {
 				*m *= 16;
 				*m += *v - '0';
@@ -1299,135 +1310,1841 @@
 				*m = 0;
 			}
 		}	  
-		sprintf(result, "OK: srcmac");
+
+                sprintf(pg_result, "OK: srcmac");
 		return count;
 	}
 
-	if (!strcmp(name, "inject") || !strcmp(name, "start")) {
-		if (info->busy) {
-			strcpy(info->result, "Already running...\n");
-		}
-		else {
-			info->busy = 1;
-			strcpy(info->result, "Starting");
-			inject(info);
-			info->busy = 0;
-		}
+        if (!strcmp(name, "clear_counters")) {
+                pktgen_clear_counters(pkt_dev);
+                sprintf(pg_result, "OK: Clearing counters.\n");
+                return count;
+        }
+
+	if (!strcmp(name, "flows")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
+		i += len;
+		if (value > MAX_CFLOWS)
+			value = MAX_CFLOWS;
+
+		pkt_dev->cflows = value;
+		sprintf(pg_result, "OK: flows=%u", pkt_dev->cflows);
 		return count;
 	}
 
-	sprintf(info->result, "No such parameter \"%s\"", name);
+	if (!strcmp(name, "flowlen")) {
+		len = num_arg(&user_buffer[i], 10, &value);
+                if (len < 0) { return len; }
+		i += len;
+		pkt_dev->lflow = value;
+		sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow);
+		return count;
+	}
+        
+	sprintf(pkt_dev->result, "No such parameter \"%s\"", name);
 	return -EINVAL;
 }
 
+static int proc_thread_read(char *buf , char **start, off_t offset,
+                               int len, int *eof, void *data)
+{
+	char *p;
+        struct pktgen_thread *t = (struct pktgen_thread*)(data);
+        struct pktgen_dev *pkt_dev = NULL;
+
+
+        if (!t) {
+                printk("pktgen: ERROR: could not find thread in proc_thread_read\n");
+                return -EINVAL;
+        }
+
+	p = buf;
+	p += sprintf(p, "Name: %s  max_before_softirq: %d\n",
+                     t->name, t->max_before_softirq);
+
+        p += sprintf(p, "Running: ");
+        
+        if_lock(t);
+        pkt_dev = t->if_list;
+        while (pkt_dev && pkt_dev->running) {
+                p += sprintf(p, "%s ", pkt_dev->ifname);
+                pkt_dev = pkt_dev->next;
+        }
+        p += sprintf(p, "\nStopped: ");
+
+        pkt_dev = t->if_list;
+        while (pkt_dev && !pkt_dev->running) {
+                p += sprintf(p, "%s ", pkt_dev->ifname);
+                pkt_dev = pkt_dev->next;
+        }
+
+
+	if (t->result[0])
+		p += sprintf(p, "\nResult: %s\n", t->result);
+	else
+		p += sprintf(p, "\nResult: NA\n");
+
+	*eof = 1;
+
+        if_unlock(t);
+
+	return p - buf;
+}
+
+static int proc_thread_write(struct file *file, const char *user_buffer,
+                                unsigned long count, void *data)
+{
+	int i = 0, max, len, ret;
+	char name[40];
+        struct pktgen_thread *t;
+        char *pg_result;
+        unsigned long value = 0;
+        
+	if (count < 1) {
+		//	sprintf(pg_result, "Wrong command format");
+		return -EINVAL;
+	}
+  
+	max = count - i;
+        len = count_trail_chars(&user_buffer[i], max);
+        if (len < 0) 
+		return len; 
+     
+	i += len;
+  
+	/* Read variable name */
+
+	len = strn_len(&user_buffer[i], sizeof(name) - 1);
+        if (len < 0)  
+		return len; 
+	
+	memset(name, 0, sizeof(name));
+	if (copy_from_user(name, &user_buffer[i], len))
+		return -EFAULT;
+	i += len;
+  
+	max = count -i;
+	len = count_trail_chars(&user_buffer[i], max);
+        if (len < 0)  
+		return len; 
+	
+	i += len;
+
+	if (debug) 
+		printk("pktgen: t=%s, count=%lu\n", name, count);
+        
+	thread_lock();
+
+        t = (struct pktgen_thread*)(data);
+	if(!t) {
+		printk("pktgen: ERROR: No thread\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	pg_result = &(t->result[0]);
+
+        if (!strcmp(name, "add_device")) {
+                char f[32];
+                memset(f, 0, 32);
+		len = strn_len(&user_buffer[i], sizeof(f) - 1);
+                if (len < 0) { 
+			ret = len; 
+			goto out;
+		}
+		if( copy_from_user(f, &user_buffer[i], len) )
+			return -EFAULT;
+		i += len;
+                pktgen_add_device(t, f);
+                ret = count;
+                sprintf(pg_result, "OK: add_device=%s", f);
+		goto out;
+	}
+
+        if (!strcmp(name, "rem_device_all")) {
+		t->control |= T_REMDEV;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(HZ/8);  /* Propagate thread->control  */
+		ret = count;
+                sprintf(pg_result, "OK: rem_device_all");
+		goto out;
+	}
+
+
+        if (!strcmp(name, "max_before_softirq")) {
+                len = num_arg(&user_buffer[i], 10, &value);
+                t->max_before_softirq = value;
+                ret = count;
+                sprintf(pg_result, "OK: max_before_softirq=%lu", value);
+		goto out;
+	}
+
+	ret = -EINVAL;
+ out:
+	thread_unlock();
+
+	return ret;
+}
 
 static int create_proc_dir(void)
 {
-	int     len;
-	/*  does proc_dir already exists */
-	len = strlen(PG_PROC_DIR);
-
-	for (proc_dir = proc_net->subdir; proc_dir;
-	     proc_dir=proc_dir->next) {
-		if ((proc_dir->namelen == len) &&
-		    (! memcmp(proc_dir->name, PG_PROC_DIR, len)))
+        int     len;
+        /*  does proc_dir already exists */
+        len = strlen(PG_PROC_DIR);
+
+        for (pg_proc_dir = proc_net->subdir; pg_proc_dir; pg_proc_dir=pg_proc_dir->next) {
+                if ((pg_proc_dir->namelen == len) &&
+		    (! memcmp(pg_proc_dir->name, PG_PROC_DIR, len))) 
+                        break;
+        }
+        
+        if (!pg_proc_dir) 
+                pg_proc_dir = create_proc_entry(PG_PROC_DIR, S_IFDIR, proc_net);
+        
+        if (!pg_proc_dir) 
+                return -ENODEV;
+        
+        return 0;
+}
+
+static int remove_proc_dir(void)
+{
+        remove_proc_entry(PG_PROC_DIR, proc_net);
+        return 0;
+}
+
+/* Think find or remove for NN */
+static struct pktgen_dev *__pktgen_NN_threads(const char* ifname, int remove) 
+{
+	struct pktgen_thread *t;
+	struct pktgen_dev *pkt_dev = NULL;
+
+        t = pktgen_threads;
+                
+	while (t) {
+		pkt_dev = pktgen_find_dev(t, ifname);
+		if (pkt_dev) {
+		                if(remove) { 
+				        if_lock(t);
+				        pktgen_remove_device(t, pkt_dev);
+				        if_unlock(t);
+				}
 			break;
+		}
+		t = t->next;
 	}
-	if (!proc_dir)
-		proc_dir = create_proc_entry(PG_PROC_DIR, S_IFDIR, proc_net);
-	if (!proc_dir) return -ENODEV;
-	return 1;
+        return pkt_dev;
 }
 
-static int remove_proc_dir(void)
+static struct pktgen_dev *pktgen_NN_threads(const char* ifname, int remove) 
 {
-	remove_proc_entry(PG_PROC_DIR, proc_net);
-	return 1;
+	struct pktgen_dev *pkt_dev = NULL;
+	thread_lock();
+	pkt_dev = __pktgen_NN_threads(ifname, remove);
+        thread_unlock();
+	return pkt_dev;
 }
 
-static int __init init(void)
+static int pktgen_device_event(struct notifier_block *unused, unsigned long event, void *ptr) 
 {
-	int i;
-	printk(version);
-	cycles_calibrate();
-	if (cpu_speed == 0) {
-		printk("pktgen: Error: your machine does not have working cycle counter.\n");
-		return -EINVAL;
+	struct net_device *dev = (struct net_device *)(ptr);
+
+	/* It is OK that we do not hold the group lock right now,
+	 * as we run under the RTNL lock.
+	 */
+
+	switch (event) {
+	case NETDEV_CHANGEADDR:
+	case NETDEV_GOING_DOWN:
+	case NETDEV_DOWN:
+	case NETDEV_UP:
+		/* Ignore for now */
+		break;
+		
+	case NETDEV_UNREGISTER:
+                pktgen_NN_threads(dev->name, REMOVE);
+		break;
+	};
+
+	return NOTIFY_DONE;
+}
+
+/* Associate pktgen_dev with a device. */
+
+static struct net_device* pktgen_setup_dev(struct pktgen_dev *pkt_dev) {
+	struct net_device *odev;
+
+	/* Clean old setups */
+
+	if (pkt_dev->odev) {
+		dev_put(pkt_dev->odev);
+                pkt_dev->odev = NULL;
+        }
+
+	odev = dev_get_by_name(pkt_dev->ifname);
+
+	if (!odev) {
+		printk("pktgen: no such netdevice: \"%s\"\n", pkt_dev->ifname);
+		goto out;
+	}
+	if (odev->type != ARPHRD_ETHER) {
+		printk("pktgen: not an ethernet device: \"%s\"\n", pkt_dev->ifname);
+		goto out_put;
 	}
+	if (!netif_running(odev)) {
+		printk("pktgen: device is down: \"%s\"\n", pkt_dev->ifname);
+		goto out_put;
+	}
+	pkt_dev->odev = odev;
+	
+        return pkt_dev->odev;
 
-	create_proc_dir();
+out_put:
+	dev_put(odev);
+out:
+ 	return NULL;
+
+}
+
+/* Read pkt_dev from the interface and set up internal pktgen_dev
+ * structure to have the right information to create/send packets
+ */
+static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
+{
+	/* Try once more, just in case it works now. */
+        if (!pkt_dev->odev) 
+                pktgen_setup_dev(pkt_dev);
+        
+        if (!pkt_dev->odev) {
+                printk("pktgen: ERROR: pkt_dev->odev == NULL in setup_inject.\n");
+                sprintf(pkt_dev->result, "ERROR: pkt_dev->odev == NULL in setup_inject.\n");
+                return;
+        }
+        
+        /* Default to the interface's mac if not explicitly set. */
+
+	if ((pkt_dev->src_mac[0] == 0) && 
+	    (pkt_dev->src_mac[1] == 0) && 
+	    (pkt_dev->src_mac[2] == 0) && 
+	    (pkt_dev->src_mac[3] == 0) && 
+	    (pkt_dev->src_mac[4] == 0) && 
+	    (pkt_dev->src_mac[5] == 0)) {
+
+	       memcpy(&(pkt_dev->hh[6]), pkt_dev->odev->dev_addr, 6);
+       }
+        /* Set up Dest MAC */
+        memcpy(&(pkt_dev->hh[0]), pkt_dev->dst_mac, 6);
+
+        /* Set up pkt size */
+        pkt_dev->cur_pkt_size = pkt_dev->min_pkt_size;
+	
+	if(pkt_dev->flags & F_IPV6) {
+		/*
+		 * Skip this automatic address setting until locks or functions 
+		 * gets exported
+		 */
+
+#ifdef NOTNOW
+		int i, set = 0, err=1;
+		struct inet6_dev *idev;
+
+		for(i=0; i< IN6_ADDR_HSIZE; i++)
+			if(pkt_dev->cur_in6_saddr.s6_addr[i]) {
+				set = 1;
+				break;
+			}
+
+		if(!set) {
+			
+			/*
+			 * Use linklevel address if unconfigured.
+			 *
+			 * use ipv6_get_lladdr if/when it's get exported
+			 */
+
+
+			read_lock(&addrconf_lock);
+			if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) {
+				struct inet6_ifaddr *ifp;
+
+				read_lock_bh(&idev->lock);
+				for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
+					if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
+						ipv6_addr_copy(&pkt_dev->cur_in6_saddr, &ifp->addr);
+						err = 0;
+						break;
+					}
+				}
+				read_unlock_bh(&idev->lock);
+			}
+			read_unlock(&addrconf_lock);
+			if(err)	printk("pktgen: ERROR: IPv6 link address not availble.\n");
+		}
+#endif
+	} 
+	else {
+		pkt_dev->saddr_min = 0;
+		pkt_dev->saddr_max = 0;
+		if (strlen(pkt_dev->src_min) == 0) {
+			
+			struct in_device *in_dev; 
+
+			rcu_read_lock();
+			in_dev = __in_dev_get(pkt_dev->odev);
+			if (in_dev) {
+				if (in_dev->ifa_list) {
+					pkt_dev->saddr_min = in_dev->ifa_list->ifa_address;
+					pkt_dev->saddr_max = pkt_dev->saddr_min;
+				}
+				in_dev_put(in_dev);	
+			}
+			rcu_read_unlock();
+		}
+		else {
+			pkt_dev->saddr_min = in_aton(pkt_dev->src_min);
+			pkt_dev->saddr_max = in_aton(pkt_dev->src_max);
+		}
 
-	for (i = 0; i<MAX_PKTGEN; i++) {
-		memset(&(pginfos[i]), 0, sizeof(pginfos[i]));
-		pginfos[i].pkt_size = ETH_ZLEN;
-		pginfos[i].nfrags = 0;
-		pginfos[i].clone_skb = clone_skb_d;
-		pginfos[i].ipg = ipg_d;
-		pginfos[i].count = count_d;
-		pginfos[i].sofar = 0;
-		pginfos[i].hh[12] = 0x08; /* fill in protocol.  Rest is filled in later. */
-		pginfos[i].hh[13] = 0x00;
-		pginfos[i].udp_src_min = 9; /* sink NULL */
-		pginfos[i].udp_src_max = 9;
-		pginfos[i].udp_dst_min = 9;
-		pginfos[i].udp_dst_max = 9;
+		pkt_dev->daddr_min = in_aton(pkt_dev->dst_min);
+		pkt_dev->daddr_max = in_aton(pkt_dev->dst_max);
+	}
+        /* Initialize current values. */
+        pkt_dev->cur_dst_mac_offset = 0;
+        pkt_dev->cur_src_mac_offset = 0;
+        pkt_dev->cur_saddr = pkt_dev->saddr_min;
+        pkt_dev->cur_daddr = pkt_dev->daddr_min;
+        pkt_dev->cur_udp_dst = pkt_dev->udp_dst_min;
+        pkt_dev->cur_udp_src = pkt_dev->udp_src_min;
+	pkt_dev->nflows = 0;
+}
+
+static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
+{
+	__u64 start;
+	__u64 now;
+
+	start = now = getCurUs();
+	printk(KERN_INFO "sleeping for %d\n", (int)(spin_until_us - now));
+	while (now < spin_until_us) {
+		/* TODO: optimise sleeping behavior */
+		if (spin_until_us - now > (1000000/HZ)+1) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(1);
+		} else if (spin_until_us - now > 100) {
+			do_softirq();
+			if (!pkt_dev->running)
+				return;
+			if (need_resched())
+				schedule();
+		}
+
+		now = getCurUs();
+	}
+
+	pkt_dev->idle_acc += now - start;
+}
+
+
+/* Increment/randomize headers according to flags and current values
+ * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
+ */
+static void mod_cur_headers(struct pktgen_dev *pkt_dev) {        
+        __u32 imn;
+        __u32 imx;
+	int  flow = 0;
+
+	if(pkt_dev->cflows)  {
+		flow = pktgen_random() % pkt_dev->cflows;
+		
+		if (pkt_dev->flows[flow].count > pkt_dev->lflow)
+			pkt_dev->flows[flow].count = 0;
+	}						
+
+
+	/*  Deal with source MAC */
+        if (pkt_dev->src_mac_count > 1) {
+                __u32 mc;
+                __u32 tmp;
+
+                if (pkt_dev->flags & F_MACSRC_RND) 
+                        mc = pktgen_random() % (pkt_dev->src_mac_count);
+                else {
+                        mc = pkt_dev->cur_src_mac_offset++;
+                        if (pkt_dev->cur_src_mac_offset > pkt_dev->src_mac_count) 
+                                pkt_dev->cur_src_mac_offset = 0;
+                }
+
+                tmp = pkt_dev->src_mac[5] + (mc & 0xFF);
+                pkt_dev->hh[11] = tmp;
+                tmp = (pkt_dev->src_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[10] = tmp;
+                tmp = (pkt_dev->src_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[9] = tmp;
+                tmp = (pkt_dev->src_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[8] = tmp;
+                tmp = (pkt_dev->src_mac[1] + (tmp >> 8));
+                pkt_dev->hh[7] = tmp;        
+        }
+
+        /*  Deal with Destination MAC */
+        if (pkt_dev->dst_mac_count > 1) {
+                __u32 mc;
+                __u32 tmp;
+
+                if (pkt_dev->flags & F_MACDST_RND) 
+                        mc = pktgen_random() % (pkt_dev->dst_mac_count);
+
+                else {
+                        mc = pkt_dev->cur_dst_mac_offset++;
+                        if (pkt_dev->cur_dst_mac_offset > pkt_dev->dst_mac_count) {
+                                pkt_dev->cur_dst_mac_offset = 0;
+                        }
+                }
+
+                tmp = pkt_dev->dst_mac[5] + (mc & 0xFF);
+                pkt_dev->hh[5] = tmp;
+                tmp = (pkt_dev->dst_mac[4] + ((mc >> 8) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[4] = tmp;
+                tmp = (pkt_dev->dst_mac[3] + ((mc >> 16) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[3] = tmp;
+                tmp = (pkt_dev->dst_mac[2] + ((mc >> 24) & 0xFF) + (tmp >> 8));
+                pkt_dev->hh[2] = tmp;
+                tmp = (pkt_dev->dst_mac[1] + (tmp >> 8));
+                pkt_dev->hh[1] = tmp;        
+        }
+
+        if (pkt_dev->udp_src_min < pkt_dev->udp_src_max) {
+                if (pkt_dev->flags & F_UDPSRC_RND) 
+                        pkt_dev->cur_udp_src = ((pktgen_random() % (pkt_dev->udp_src_max - pkt_dev->udp_src_min)) + pkt_dev->udp_src_min);
+
+                else {
+			pkt_dev->cur_udp_src++;
+			if (pkt_dev->cur_udp_src >= pkt_dev->udp_src_max)
+				pkt_dev->cur_udp_src = pkt_dev->udp_src_min;
+                }
+        }
+
+        if (pkt_dev->udp_dst_min < pkt_dev->udp_dst_max) {
+                if (pkt_dev->flags & F_UDPDST_RND) {
+                        pkt_dev->cur_udp_dst = ((pktgen_random() % (pkt_dev->udp_dst_max - pkt_dev->udp_dst_min)) + pkt_dev->udp_dst_min);
+                }
+                else {
+			pkt_dev->cur_udp_dst++;
+			if (pkt_dev->cur_udp_dst >= pkt_dev->udp_dst_max) 
+				pkt_dev->cur_udp_dst = pkt_dev->udp_dst_min;
+                }
+        }
+
+	if (!(pkt_dev->flags & F_IPV6)) {
+
+		if ((imn = ntohl(pkt_dev->saddr_min)) < (imx = ntohl(pkt_dev->saddr_max))) {
+			__u32 t;
+			if (pkt_dev->flags & F_IPSRC_RND) 
+				t = ((pktgen_random() % (imx - imn)) + imn);
+			else {
+				t = ntohl(pkt_dev->cur_saddr);
+				t++;
+				if (t > imx) {
+					t = imn;
+				}
+			}
+			pkt_dev->cur_saddr = htonl(t);
+		}
 		
-		sprintf(pginfos[i].fname, "net/%s/pg%i", PG_PROC_DIR, i);
-		pginfos[i].proc_ent = create_proc_entry(pginfos[i].fname, 0600, NULL);
-		if (!pginfos[i].proc_ent) {
-			printk("pktgen: Error: cannot create net/%s/pg procfs entry.\n", PG_PROC_DIR);
-			goto cleanup_mem;
-		}
-		pginfos[i].proc_ent->read_proc = proc_read;
-		pginfos[i].proc_ent->write_proc = proc_write;
-		pginfos[i].proc_ent->data = (void*)(long)(i);
-		pginfos[i].proc_ent->owner = THIS_MODULE;
-
-		sprintf(pginfos[i].busy_fname, "net/%s/pg_busy%i",  PG_PROC_DIR, i);
-		pginfos[i].busy_proc_ent = create_proc_entry(pginfos[i].busy_fname, 0, NULL);
-		if (!pginfos[i].busy_proc_ent) {
-			printk("pktgen: Error: cannot create net/%s/pg_busy procfs entry.\n", PG_PROC_DIR);
-			goto cleanup_mem;
+		if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) {
+			pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr;
+		} else {
+
+			if ((imn = ntohl(pkt_dev->daddr_min)) < (imx = ntohl(pkt_dev->daddr_max))) {
+				__u32 t;
+				if (pkt_dev->flags & F_IPDST_RND) {
+
+					t = ((pktgen_random() % (imx - imn)) + imn);
+					t = htonl(t);
+
+					while( LOOPBACK(t) || MULTICAST(t) || BADCLASS(t) || ZERONET(t) ||  LOCAL_MCAST(t) ) {
+						t = ((pktgen_random() % (imx - imn)) + imn);
+						t = htonl(t);
+					}
+					pkt_dev->cur_daddr = t;
+				}
+				
+				else {
+					t = ntohl(pkt_dev->cur_daddr);
+					t++;
+					if (t > imx) {
+						t = imn;
+					}
+					pkt_dev->cur_daddr = htonl(t);
+				}
+			}
+			if(pkt_dev->cflows) {	
+				pkt_dev->flows[flow].cur_daddr = pkt_dev->cur_daddr;
+				pkt_dev->nflows++;
+			}
 		}
-		pginfos[i].busy_proc_ent->read_proc = proc_busy_read;
-		pginfos[i].busy_proc_ent->data = (void*)(long)(i);
 	}
-	return 0;
+	else /* IPV6 * */
+	{
+		if(pkt_dev->min_in6_daddr.s6_addr32[0] == 0 &&
+		   pkt_dev->min_in6_daddr.s6_addr32[1] == 0 &&
+		   pkt_dev->min_in6_daddr.s6_addr32[2] == 0 &&
+		   pkt_dev->min_in6_daddr.s6_addr32[3] == 0);
+		else {
+			int i;
+
+			/* Only random destinations yet */
+
+			for(i=0; i < 4; i++) {
+				pkt_dev->cur_in6_daddr.s6_addr32[i] =
+					((pktgen_random() |
+					  pkt_dev->min_in6_daddr.s6_addr32[i]) &
+					 pkt_dev->max_in6_daddr.s6_addr32[i]);
+			}
+ 		}
+	}
+
+        if (pkt_dev->min_pkt_size < pkt_dev->max_pkt_size) {
+                __u32 t;
+                if (pkt_dev->flags & F_TXSIZE_RND) {
+                        t = ((pktgen_random() % (pkt_dev->max_pkt_size - pkt_dev->min_pkt_size))
+                             + pkt_dev->min_pkt_size);
+                }
+                else {
+			t = pkt_dev->cur_pkt_size + 1;
+			if (t > pkt_dev->max_pkt_size) 
+				t = pkt_dev->min_pkt_size;
+                }
+                pkt_dev->cur_pkt_size = t;
+        }
+
+	pkt_dev->flows[flow].count++;
+}
+
+
+static struct sk_buff *fill_packet_ipv4(struct net_device *odev, 
+				   struct pktgen_dev *pkt_dev)
+{
+	struct sk_buff *skb = NULL;
+	__u8 *eth;
+	struct udphdr *udph;
+	int datalen, iplen;
+	struct iphdr *iph;
+        struct pktgen_hdr *pgh = NULL;
+        
+	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
+	if (!skb) {
+		sprintf(pkt_dev->result, "No memory");
+		return NULL;
+	}
+
+	skb_reserve(skb, 16);
+
+	/*  Reserve for ethernet and IP header  */
+	eth = (__u8 *) skb_push(skb, 14);
+	iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
+	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
+
+        /* Update any of the values, used when we're incrementing various
+         * fields.
+         */
+        mod_cur_headers(pkt_dev);
+
+	memcpy(eth, pkt_dev->hh, 12);
+	*(u16*)&eth[12] = __constant_htons(ETH_P_IP);
+
+	datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8; /* Eth + IPh + UDPh */
+	if (datalen < sizeof(struct pktgen_hdr)) 
+		datalen = sizeof(struct pktgen_hdr);
+        
+	udph->source = htons(pkt_dev->cur_udp_src);
+	udph->dest = htons(pkt_dev->cur_udp_dst);
+	udph->len = htons(datalen + 8); /* DATA + udphdr */
+	udph->check = 0;  /* No checksum */
+
+	iph->ihl = 5;
+	iph->version = 4;
+	iph->ttl = 32;
+	iph->tos = 0;
+	iph->protocol = IPPROTO_UDP; /* UDP */
+	iph->saddr = pkt_dev->cur_saddr;
+	iph->daddr = pkt_dev->cur_daddr;
+	iph->frag_off = 0;
+	iplen = 20 + 8 + datalen;
+	iph->tot_len = htons(iplen);
+	iph->check = 0;
+	iph->check = ip_fast_csum((void *) iph, iph->ihl);
+	skb->protocol = __constant_htons(ETH_P_IP);
+	skb->mac.raw = ((u8 *)iph) - 14;
+	skb->dev = odev;
+	skb->pkt_type = PACKET_HOST;
+
+	if (pkt_dev->nfrags <= 0) 
+                pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
+	else {
+		int frags = pkt_dev->nfrags;
+		int i;
+
+                pgh = (struct pktgen_hdr*)(((char*)(udph)) + 8);
+                
+		if (frags > MAX_SKB_FRAGS)
+			frags = MAX_SKB_FRAGS;
+		if (datalen > frags*PAGE_SIZE) {
+			skb_put(skb, datalen-frags*PAGE_SIZE);
+			datalen = frags*PAGE_SIZE;
+		}
+
+		i = 0;
+		while (datalen > 0) {
+			struct page *page = alloc_pages(GFP_KERNEL, 0);
+			skb_shinfo(skb)->frags[i].page = page;
+			skb_shinfo(skb)->frags[i].page_offset = 0;
+			skb_shinfo(skb)->frags[i].size =
+				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+			datalen -= skb_shinfo(skb)->frags[i].size;
+			skb->len += skb_shinfo(skb)->frags[i].size;
+			skb->data_len += skb_shinfo(skb)->frags[i].size;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+
+		while (i < frags) {
+			int rem;
+
+			if (i == 0)
+				break;
+
+			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
+			if (rem == 0)
+				break;
+
+			skb_shinfo(skb)->frags[i - 1].size -= rem;
+
+			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];
+			get_page(skb_shinfo(skb)->frags[i].page);
+			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;
+			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;
+			skb_shinfo(skb)->frags[i].size = rem;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+	}
+
+        /* Stamp the time, and sequence number, convert them to network byte order */
+
+        if (pgh) {
+              struct timeval timestamp;
+	      
+	      pgh->pgh_magic = htonl(PKTGEN_MAGIC);
+	      pgh->seq_num   = htonl(pkt_dev->seq_num);
+	      
+	      do_gettimeofday(&timestamp);
+	      pgh->tv_sec    = htonl(timestamp.tv_sec);
+	      pgh->tv_usec   = htonl(timestamp.tv_usec);
+        }
+        pkt_dev->seq_num++;
+        
+	return skb;
+}
+
+/*
+ * scan_ip6, fmt_ip taken from dietlibc-0.21 
+ * Author Felix von Leitner <felix-dietlibc@fefe.de>
+ *
+ * Slightly modified for kernel. 
+ * Should be candidate for net/ipv4/utils.c
+ * --ro
+ */
+
+static unsigned int scan_ip6(const char *s,char ip[16])
+{
+	unsigned int i;
+	unsigned int len=0;
+	unsigned long u;
+	char suffix[16];
+	unsigned int prefixlen=0;
+	unsigned int suffixlen=0;
+	__u32 tmp;
+
+	for (i=0; i<16; i++) ip[i]=0;
+
+	for (;;) {
+		if (*s == ':') {
+			len++;
+			if (s[1] == ':') {        /* Found "::", skip to part 2 */
+				s+=2;
+				len++;
+				break;
+			}
+			s++;
+		}
+		{
+			char *tmp;
+			u=simple_strtoul(s,&tmp,16);
+			i=tmp-s;
+		}
+
+		if (!i) return 0;
+		if (prefixlen==12 && s[i]=='.') {
+
+			/* the last 4 bytes may be written as IPv4 address */
+
+			tmp = in_aton(s);
+			memcpy((struct in_addr*)(ip+12), &tmp, sizeof(tmp));
+			return i+len;
+		}
+		ip[prefixlen++] = (u >> 8);
+		ip[prefixlen++] = (u & 255);
+		s += i; len += i;
+		if (prefixlen==16)
+			return len;
+	}
+
+/* part 2, after "::" */
+	for (;;) {
+		if (*s == ':') {
+			if (suffixlen==0)
+				break;
+			s++;
+			len++;
+		} else if (suffixlen!=0)
+			break;
+		{
+			char *tmp;
+			u=simple_strtol(s,&tmp,16);
+			i=tmp-s;
+		}
+		if (!i) {
+			if (*s) len--;
+			break;
+		}
+		if (suffixlen+prefixlen<=12 && s[i]=='.') {
+			tmp = in_aton(s);
+			memcpy((struct in_addr*)(suffix+suffixlen), &tmp, sizeof(tmp));
+			suffixlen+=4;
+			len+=strlen(s);
+			break;
+		}
+		suffix[suffixlen++] = (u >> 8);
+		suffix[suffixlen++] = (u & 255);
+		s += i; len += i;
+		if (prefixlen+suffixlen==16)
+			break;
+	}
+	for (i=0; i<suffixlen; i++)
+		ip[16-suffixlen+i] = suffix[i];
+	return len;
+}
+
+static char tohex(char hexdigit) {
+	return hexdigit>9?hexdigit+'a'-10:hexdigit+'0';
+}
+
+static int fmt_xlong(char* s,unsigned int i) {
+	char* bak=s;
+	*s=tohex((i>>12)&0xf); if (s!=bak || *s!='0') ++s;
+	*s=tohex((i>>8)&0xf); if (s!=bak || *s!='0') ++s;
+	*s=tohex((i>>4)&0xf); if (s!=bak || *s!='0') ++s;
+	*s=tohex(i&0xf);
+	return s-bak+1;
+}
+
+static unsigned int fmt_ip6(char *s,const char ip[16]) {
+	unsigned int len;
+	unsigned int i;
+	unsigned int temp;
+	unsigned int compressing;
+	int j;
+
+	len = 0; compressing = 0;
+	for (j=0; j<16; j+=2) {
+
+#ifdef V4MAPPEDPREFIX
+		if (j==12 && !memcmp(ip,V4mappedprefix,12)) {
+			inet_ntoa_r(*(struct in_addr*)(ip+12),s);
+			temp=strlen(s);
+			return len+temp;
+		}
+#endif
+		temp = ((unsigned long) (unsigned char) ip[j] << 8) +
+			(unsigned long) (unsigned char) ip[j+1];
+		if (temp == 0) {
+			if (!compressing) {
+				compressing=1;
+				if (j==0) {
+					*s++=':'; ++len;
+				}
+			}
+		} else {
+			if (compressing) {
+				compressing=0;
+				*s++=':'; ++len;
+			}
+			i = fmt_xlong(s,temp); len += i; s += i;
+			if (j<14) {
+				*s++ = ':';
+				++len;
+			}
+		}
+	}
+	if (compressing) {
+		*s++=':'; ++len;
+	}
+	*s=0;
+	return len;
+}
+
+static struct sk_buff *fill_packet_ipv6(struct net_device *odev, 
+				   struct pktgen_dev *pkt_dev)
+{
+	struct sk_buff *skb = NULL;
+	__u8 *eth;
+	struct udphdr *udph;
+	int datalen;
+	struct ipv6hdr *iph;
+        struct pktgen_hdr *pgh = NULL;
+        
+	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
+	if (!skb) {
+		sprintf(pkt_dev->result, "No memory");
+		return NULL;
+	}
+
+	skb_reserve(skb, 16);
+
+	/*  Reserve for ethernet and IP header  */
+	eth = (__u8 *) skb_push(skb, 14);
+	iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
+	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
+
+
+        /* Update any of the values, used when we're incrementing various
+         * fields.
+         */
+	mod_cur_headers(pkt_dev);
+
+	
+	memcpy(eth, pkt_dev->hh, 12);
+	*(u16*)&eth[12] = __constant_htons(ETH_P_IPV6);
+	
+        
+	datalen = pkt_dev->cur_pkt_size-14- 
+		sizeof(struct ipv6hdr)-sizeof(struct udphdr); /* Eth + IPh + UDPh */
+
+	if (datalen < sizeof(struct pktgen_hdr)) { 
+		datalen = sizeof(struct pktgen_hdr);
+		if (net_ratelimit())
+			printk(KERN_INFO "pktgen: increased datalen to %d\n", datalen);
+	}
+
+	udph->source = htons(pkt_dev->cur_udp_src);
+	udph->dest = htons(pkt_dev->cur_udp_dst);
+	udph->len = htons(datalen + sizeof(struct udphdr)); 
+	udph->check = 0;  /* No checksum */
+
+	 *(u32*)iph = __constant_htonl(0x60000000); /* Version + flow */
+
+	iph->hop_limit = 32;
+
+	iph->payload_len = htons(sizeof(struct udphdr) + datalen);
+	iph->nexthdr = IPPROTO_UDP;
+
+	ipv6_addr_copy(&iph->daddr, &pkt_dev->cur_in6_daddr);
+	ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
+
+	skb->mac.raw = ((u8 *)iph) - 14;
+	skb->protocol = __constant_htons(ETH_P_IPV6);
+	skb->dev = odev;
+	skb->pkt_type = PACKET_HOST;
+
+	if (pkt_dev->nfrags <= 0) 
+                pgh = (struct pktgen_hdr *)skb_put(skb, datalen);
+	else {
+		int frags = pkt_dev->nfrags;
+		int i;
+
+                pgh = (struct pktgen_hdr*)(((char*)(udph)) + 8);
+                
+		if (frags > MAX_SKB_FRAGS)
+			frags = MAX_SKB_FRAGS;
+		if (datalen > frags*PAGE_SIZE) {
+			skb_put(skb, datalen-frags*PAGE_SIZE);
+			datalen = frags*PAGE_SIZE;
+		}
+
+		i = 0;
+		while (datalen > 0) {
+			struct page *page = alloc_pages(GFP_KERNEL, 0);
+			skb_shinfo(skb)->frags[i].page = page;
+			skb_shinfo(skb)->frags[i].page_offset = 0;
+			skb_shinfo(skb)->frags[i].size =
+				(datalen < PAGE_SIZE ? datalen : PAGE_SIZE);
+			datalen -= skb_shinfo(skb)->frags[i].size;
+			skb->len += skb_shinfo(skb)->frags[i].size;
+			skb->data_len += skb_shinfo(skb)->frags[i].size;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+
+		while (i < frags) {
+			int rem;
+
+			if (i == 0)
+				break;
+
+			rem = skb_shinfo(skb)->frags[i - 1].size / 2;
+			if (rem == 0)
+				break;
+
+			skb_shinfo(skb)->frags[i - 1].size -= rem;
+
+			skb_shinfo(skb)->frags[i] = skb_shinfo(skb)->frags[i - 1];
+			get_page(skb_shinfo(skb)->frags[i].page);
+			skb_shinfo(skb)->frags[i].page = skb_shinfo(skb)->frags[i - 1].page;
+			skb_shinfo(skb)->frags[i].page_offset += skb_shinfo(skb)->frags[i - 1].size;
+			skb_shinfo(skb)->frags[i].size = rem;
+			i++;
+			skb_shinfo(skb)->nr_frags = i;
+		}
+	}
+
+        /* Stamp the time, and sequence number, convert them to network byte order */
+	/* should we update cloned packets too ? */
+        if (pgh) {
+              struct timeval timestamp;
+	      
+	      pgh->pgh_magic = htonl(PKTGEN_MAGIC);
+	      pgh->seq_num   = htonl(pkt_dev->seq_num);
+	      
+	      do_gettimeofday(&timestamp);
+	      pgh->tv_sec    = htonl(timestamp.tv_sec);
+	      pgh->tv_usec   = htonl(timestamp.tv_usec);
+        }
+        pkt_dev->seq_num++;
+        
+	return skb;
+}
+
+static inline struct sk_buff *fill_packet(struct net_device *odev, 
+				   struct pktgen_dev *pkt_dev)
+{
+	if(pkt_dev->flags & F_IPV6) 
+		return fill_packet_ipv6(odev, pkt_dev);
+	else
+		return fill_packet_ipv4(odev, pkt_dev);
+}
+
+static void pktgen_clear_counters(struct pktgen_dev *pkt_dev) 
+{
+        pkt_dev->seq_num = 1;
+        pkt_dev->idle_acc = 0;
+	pkt_dev->sofar = 0;
+        pkt_dev->tx_bytes = 0;
+        pkt_dev->errors = 0;
+}
+
+/* Set up structure for sending pkts, clear counters */
+
+static void pktgen_run(struct pktgen_thread *t)
+{
+        struct pktgen_dev *pkt_dev = NULL;
+	int started = 0;
+
+	PG_DEBUG(printk("pktgen: entering pktgen_run. %p\n", t));
+
+	if_lock(t);
+        for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
+
+		/*
+		 * setup odev and create initial packet.
+		 */
+		pktgen_setup_inject(pkt_dev);
+
+		if(pkt_dev->odev) { 
+			pktgen_clear_counters(pkt_dev);
+			pkt_dev->running = 1; /* Cranke yeself! */
+			pkt_dev->skb = NULL;
+			pkt_dev->started_at = getCurUs();
+			pkt_dev->next_tx_us = getCurUs(); /* Transmit immediately */
+			pkt_dev->next_tx_ns = 0;
+			
+			strcpy(pkt_dev->result, "Starting");
+			started++;
+		}
+		else 
+			strcpy(pkt_dev->result, "Error starting");
+	}
+	if_unlock(t);
+	if(started) t->control &= ~(T_STOP);
+}
+
+static void pktgen_stop_all_threads_ifs(void)
+{
+        struct pktgen_thread *t = pktgen_threads;
+
+	PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads.\n"));
+
+	thread_lock();
+	while(t) {
+		pktgen_stop(t);
+		t = t->next;
+	}
+       thread_unlock();
+}
+
+static int running(struct pktgen_thread *t )
+{
+        struct pktgen_dev *next;
+        int res = 0;
+
+        for(next=t->if_list; next; next=next->next) { 
+		if(next->running) {
+			res = 1;
+			break;
+		}
+        }
+        return res;
+}
+
+static int pktgen_wait_thread_run(struct pktgen_thread *t )
+{
+        wait_queue_head_t queue;
+        
+        init_waitqueue_head(&queue);
+        
+        if_lock(t);
+
+        while(running(t)) {
+                if_unlock(t);
+        
+                interruptible_sleep_on_timeout(&queue, HZ/10);
+                if (signal_pending(current)) 
+                        goto signal;
+                if_lock(t);
+        }
+        if_unlock(t);
+        return 1;
+ signal:
+        return 0;
+}
+
+static int pktgen_wait_all_threads_run(void)
+{
+	struct pktgen_thread *t = pktgen_threads;
+	int sig = 1;
 	
-cleanup_mem:
-	for (i = 0; i<MAX_PKTGEN; i++) {
-		if (strlen(pginfos[i].fname)) {
-			remove_proc_entry(pginfos[i].fname, NULL);
+	while (t) {
+		sig = pktgen_wait_thread_run(t);
+		if( sig == 0 ) break;
+		thread_lock();
+		t=t->next;
+		thread_unlock();
+	}
+	if(sig == 0) {
+		thread_lock();
+		while (t) {
+			t->control |= (T_STOP);
+			t=t->next;
 		}
-		if (strlen(pginfos[i].busy_fname)) {
-			remove_proc_entry(pginfos[i].busy_fname, NULL);
+		thread_unlock();
+	}
+	return sig;
+}
+
+static void pktgen_run_all_threads(void)
+{
+        struct pktgen_thread *t = pktgen_threads;
+
+	PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n"));
+
+	thread_lock();
+
+	while(t) {
+		t->control |= (T_RUN);
+		t = t->next;
+	}
+	thread_unlock();
+
+	current->state = TASK_INTERRUPTIBLE;
+	schedule_timeout(HZ/8);  /* Propagate thread->control  */
+			
+	pktgen_wait_all_threads_run();
+}
+
+
+static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
+{
+       __u64 total_us, bps, mbps, pps, idle;
+       char *p = pkt_dev->result;
+
+       total_us = pkt_dev->stopped_at - pkt_dev->started_at;
+
+       idle = pkt_dev->idle_acc;
+
+       p += sprintf(p, "OK: %llu(c%llu+d%llu) usec, %llu (%dbyte,%dfrags)\n",
+                    (unsigned long long) total_us, 
+		    (unsigned long long)(total_us - idle), 
+		    (unsigned long long) idle,
+                    (unsigned long long) pkt_dev->sofar, 
+		    pkt_dev->cur_pkt_size, nr_frags);
+
+       pps = pkt_dev->sofar * USEC_PER_SEC;
+
+       while ((total_us >> 32) != 0) {
+               pps >>= 1;
+               total_us >>= 1;
+       }
+
+       do_div(pps, total_us);
+       
+       bps = pps * 8 * pkt_dev->cur_pkt_size;
+
+       mbps = bps;
+       do_div(mbps, 1000000);
+       p += sprintf(p, "  %llupps %lluMb/sec (%llubps) errors: %llu",
+                    (unsigned long long) pps, 
+		    (unsigned long long) mbps, 
+		    (unsigned long long) bps, 
+		    (unsigned long long) pkt_dev->errors);
+}
+ 
+
+/* Set stopped-at timer, remove from running list, do counters & statistics */
+
+static int pktgen_stop_device(struct pktgen_dev *pkt_dev) 
+{
+	
+        if (!pkt_dev->running) {
+                printk("pktgen: interface: %s is already stopped\n", pkt_dev->ifname);
+                return -EINVAL;
+        }
+
+	if (pkt_dev->skb) 
+		kfree_skb(pkt_dev->skb);
+
+        pkt_dev->stopped_at = getCurUs();
+        pkt_dev->running = 0;
+
+	show_results(pkt_dev, skb_shinfo(pkt_dev->skb)->nr_frags);
+	
+        return 0;
+}
+
+static struct pktgen_dev *next_to_run(struct pktgen_thread *t )
+{
+	struct pktgen_dev *next, *best = NULL;
+        
+	if_lock(t);
+
+	for(next=t->if_list; next ; next=next->next) {
+		if(!next->running) continue;
+		if(best == NULL) best=next;
+		else if ( next->next_tx_us < best->next_tx_us) 
+			best =  next;
+	}
+	if_unlock(t);
+        return best;
+}
+
+static void pktgen_stop(struct pktgen_thread *t) {
+        struct pktgen_dev *next = NULL;
+
+	PG_DEBUG(printk("pktgen: entering pktgen_stop.\n"));
+
+        if_lock(t);
+
+        for(next=t->if_list; next; next=next->next)
+                pktgen_stop_device(next);
+
+        if_unlock(t);
+}
+
+static void pktgen_rem_all_ifs(struct pktgen_thread *t) 
+{
+        struct pktgen_dev *cur, *next = NULL;
+        
+        /* Remove all devices, free mem */
+ 
+        if_lock(t);
+
+        for(cur=t->if_list; cur; cur=next) { 
+		next = cur->next;
+		pktgen_remove_device(t, cur);
+	}
+
+        if_unlock(t);
+}
+
+static void pktgen_rem_thread(struct pktgen_thread *t) 
+{
+        /* Remove from the thread list */
+
+	struct pktgen_thread *tmp = pktgen_threads;
+
+        if (strlen(t->fname))
+                remove_proc_entry(t->fname, NULL);
+
+       thread_lock();
+
+	if (tmp == t)
+		pktgen_threads = tmp->next;
+	else {
+		while (tmp) {
+			if (tmp->next == t) {
+				tmp->next = t->next;
+				t->next = NULL;
+				break;
+			}
+			tmp = tmp->next;
 		}
 	}
-	return -ENOMEM;
+        thread_unlock();
 }
 
+__inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
+{
+	struct net_device *odev = NULL;
+	__u64 idle_start = 0;
+	int ret;
+
+	odev = pkt_dev->odev;
+	
+	if (pkt_dev->delay_us || pkt_dev->delay_ns) {
+		u64 now;
+
+		now = getCurUs();
+		if (now < pkt_dev->next_tx_us)
+			spin(pkt_dev, pkt_dev->next_tx_us);
 
-static void __exit cleanup(void)
+		/* This is max DELAY, this has special meaning of
+		 * "never transmit"
+		 */
+		if (pkt_dev->delay_us == 0x7FFFFFFF) {
+			pkt_dev->next_tx_us = getCurUs() + pkt_dev->delay_us;
+			pkt_dev->next_tx_ns = pkt_dev->delay_ns;
+			goto out;
+		}
+	}
+	
+	if (netif_queue_stopped(odev) || need_resched()) {
+		idle_start = getCurUs();
+		
+		if (!netif_running(odev)) {
+			pktgen_stop_device(pkt_dev);
+			goto out;
+		}
+		if (need_resched()) 
+			schedule();
+		
+		pkt_dev->idle_acc += getCurUs() - idle_start;
+		
+		if (netif_queue_stopped(odev)) {
+			pkt_dev->next_tx_us = getCurUs(); /* TODO */
+			pkt_dev->next_tx_ns = 0;
+			goto out; /* Try the next interface */
+		}
+	}
+	
+	if (pkt_dev->last_ok || !pkt_dev->skb) {
+		if ((++pkt_dev->clone_count >= pkt_dev->clone_skb ) || (!pkt_dev->skb)) {
+			/* build a new pkt */
+			if (pkt_dev->skb) 
+				kfree_skb(pkt_dev->skb);
+			
+			pkt_dev->skb = fill_packet(odev, pkt_dev);
+			if (pkt_dev->skb == NULL) {
+				printk("pktgen: ERROR: couldn't allocate skb in fill_packet.\n");
+				schedule();
+				pkt_dev->clone_count--; /* back out increment, OOM */
+				goto out;
+			}
+			pkt_dev->allocated_skbs++;
+			pkt_dev->clone_count = 0; /* reset counter */
+		}
+	}
+	
+	spin_lock_bh(&odev->xmit_lock);
+	if (!netif_queue_stopped(odev)) {
+		u64 now;
+
+		atomic_inc(&(pkt_dev->skb->users));
+retry_now:
+		ret = odev->hard_start_xmit(pkt_dev->skb, odev);
+		if (likely(ret == NETDEV_TX_OK)) {
+			pkt_dev->last_ok = 1;    
+			pkt_dev->sofar++;
+			pkt_dev->seq_num++;
+			pkt_dev->tx_bytes += pkt_dev->cur_pkt_size;
+			
+		} else if (ret == NETDEV_TX_LOCKED 
+			   && (odev->features & NETIF_F_LLTX)) {
+			cpu_relax();
+			goto retry_now;
+		} else {  /* Retry it next time */
+			
+			atomic_dec(&(pkt_dev->skb->users));
+			
+			if (debug && net_ratelimit())
+				printk(KERN_INFO "pktgen: Hard xmit error\n");
+			
+			pkt_dev->errors++;
+			pkt_dev->last_ok = 0;
+			pkt_dev->next_tx_us = getCurUs(); /* TODO */
+			pkt_dev->next_tx_ns = 0;
+		}
+
+		pkt_dev->next_tx_us += pkt_dev->delay_us;
+		pkt_dev->next_tx_ns += pkt_dev->delay_ns;
+		if (pkt_dev->next_tx_ns > 1000) {
+			pkt_dev->next_tx_us++;
+			pkt_dev->next_tx_ns -= 1000;
+		}
+
+		now = getCurUs();
+		if (now > pkt_dev->next_tx_us) {
+			/* TODO: this code is slightly wonky.  */
+			pkt_dev->errors++;
+			pkt_dev->next_tx_us = now - pkt_dev->delay_us;
+			pkt_dev->next_tx_ns = 0;
+		}
+	} 
+
+	else {  /* Retry it next time */
+                pkt_dev->last_ok = 0;
+                pkt_dev->next_tx_us = getCurUs(); /* TODO */
+		pkt_dev->next_tx_ns = 0;
+        }
+
+	spin_unlock_bh(&odev->xmit_lock);
+	
+	/* If pkt_dev->count is zero, then run forever */
+	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
+		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
+			idle_start = getCurUs();
+			while (atomic_read(&(pkt_dev->skb->users)) != 1) {
+				if (signal_pending(current)) {
+					break;
+				}
+				schedule();
+			}
+			pkt_dev->idle_acc += getCurUs() - idle_start;
+		}
+                
+		/* Done with this */
+		pktgen_stop_device(pkt_dev);
+	} 
+ out:;
+ }
+
+/* 
+ * Main loop of the thread goes here
+ */
+
+static void pktgen_thread_worker(struct pktgen_thread *t) 
 {
-	int i;
-	for (i = 0; i<MAX_PKTGEN; i++) {
-		if (strlen(pginfos[i].fname)) {
-			remove_proc_entry(pginfos[i].fname, NULL);
+        struct pktgen_dev *pkt_dev = NULL;
+	int cpu = t->cpu;
+	sigset_t tmpsig;
+	u32 max_before_softirq;
+        u32 tx_since_softirq = 0;
+
+	daemonize("pktgen/%d", cpu);
+
+        /* Block all signals except SIGKILL, SIGSTOP and SIGTERM */
+
+        spin_lock_irq(&current->sighand->siglock);
+        tmpsig = current->blocked;
+        siginitsetinv(&current->blocked, 
+                      sigmask(SIGKILL) | 
+                      sigmask(SIGSTOP)| 
+                      sigmask(SIGTERM));
+
+        recalc_sigpending();
+        spin_unlock_irq(&current->sighand->siglock);
+
+	/* Migrate to the right CPU */
+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+        if (smp_processor_id() != cpu)
+                BUG();
+
+	init_waitqueue_head(&t->queue);
+
+	t->control &= ~(T_TERMINATE);
+	t->control &= ~(T_RUN);
+	t->control &= ~(T_STOP);
+	t->control &= ~(T_REMDEV);
+
+        t->pid = current->pid;        
+
+        PG_DEBUG(printk("pktgen: starting pktgen/%d:  pid=%d\n", cpu, current->pid));
+
+	max_before_softirq = t->max_before_softirq;
+        
+        __set_current_state(TASK_INTERRUPTIBLE);
+        mb();
+
+        while (1) {
+		
+		__set_current_state(TASK_RUNNING);
+
+		/*
+		 * Get next dev to xmit -- if any.
+		 */
+
+                pkt_dev = next_to_run(t);
+                
+                if (pkt_dev) {
+
+			pktgen_xmit(pkt_dev);
+
+			/*
+			 * We like to stay RUNNING but must also give
+			 * others fair share.
+			 */
+
+			tx_since_softirq += pkt_dev->last_ok;
+
+			if (tx_since_softirq > max_before_softirq) {
+				if(softirq_pending(smp_processor_id()))  
+					do_softirq();
+				tx_since_softirq = 0;
+			}
+		}
+                else 
+                        interruptible_sleep_on_timeout(&(t->queue), HZ/10);
+
+                /* 
+		 * Back from sleep, either due to the timeout or signal.
+		 * We check if we have any "posted" work for us.
+		 */
+
+                if (t->control & T_TERMINATE || signal_pending(current)) 
+                        /* we received a request to terminate ourself */
+                        break;
+		
+
+		if(t->control & T_STOP) {
+			pktgen_stop(t);
+			t->control &= ~(T_STOP);
 		}
-		if (strlen(pginfos[i].busy_fname)) {
-			remove_proc_entry(pginfos[i].busy_fname, NULL);
+
+		if(t->control & T_RUN) {
+			pktgen_run(t);
+			t->control &= ~(T_RUN);
 		}
+
+		if(t->control & T_REMDEV) {
+			pktgen_rem_all_ifs(t);
+			t->control &= ~(T_REMDEV);
+		}
+
+		if (need_resched()) 
+			schedule();
+        } 
+
+        PG_DEBUG(printk("pktgen: %s stopping all device\n", t->name));
+        pktgen_stop(t);
+
+        PG_DEBUG(printk("pktgen: %s removing all device\n", t->name));
+        pktgen_rem_all_ifs(t);
+
+        PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name));
+        pktgen_rem_thread(t);
+}
+
+static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, const char* ifname) 
+{
+        struct pktgen_dev *pkt_dev = NULL;
+        if_lock(t);
+
+        for(pkt_dev=t->if_list; pkt_dev; pkt_dev = pkt_dev->next ) {
+                if (strcmp(pkt_dev->ifname, ifname) == 0) {
+                        goto out;
+                }
+        }
+ out:
+        if_unlock(t);
+	PG_DEBUG(printk("pktgen: find_dev(%s) returning %p\n", ifname,pkt_dev));
+        return pkt_dev;
+}
+
+/* 
+ * Adds a dev at front of if_list. 
+ */
+
+static int add_dev_to_thread(struct pktgen_thread *t, struct pktgen_dev *pkt_dev) 
+{
+	int rv = 0;
+	
+        if_lock(t);
+
+        if (pkt_dev->pg_thread) {
+                printk("pktgen: ERROR:  already assigned to a thread.\n");
+                rv = -EBUSY;
+                goto out;
+        }
+
+	L_PUSH(t->if_list, pkt_dev);
+        pkt_dev->pg_thread = t;
+	pkt_dev->running = 0;
+
+ out:
+        if_unlock(t);        
+        return rv;
+}
+
+/* Called under thread lock */
+
+static int pktgen_add_device(struct pktgen_thread *t, const char* ifname) 
+{
+        struct pktgen_dev *pkt_dev;
+	
+	/* We don't allow a device to be on several threads */
+
+	if( (pkt_dev = __pktgen_NN_threads(ifname, FIND)) == NULL) {
+						   
+		pkt_dev = kmalloc(sizeof(struct pktgen_dev), GFP_KERNEL);
+                if (!pkt_dev) 
+                        return -ENOMEM;
+
+                memset(pkt_dev, 0, sizeof(struct pktgen_dev));
+
+		pkt_dev->flows = vmalloc(MAX_CFLOWS*sizeof(struct flow_state));
+		if (pkt_dev->flows == NULL) {
+			kfree(pkt_dev);
+			return -ENOMEM;
+		}
+		memset(pkt_dev->flows, 0, MAX_CFLOWS*sizeof(struct flow_state));
+
+		pkt_dev->min_pkt_size = ETH_ZLEN;
+                pkt_dev->max_pkt_size = ETH_ZLEN;
+                pkt_dev->nfrags = 0;
+                pkt_dev->clone_skb = pg_clone_skb_d;
+                pkt_dev->delay_us = pg_delay_d / 1000;
+                pkt_dev->delay_ns = pg_delay_d % 1000;
+                pkt_dev->count = pg_count_d;
+                pkt_dev->sofar = 0;
+                pkt_dev->udp_src_min = 9; /* sink port */
+                pkt_dev->udp_src_max = 9;
+                pkt_dev->udp_dst_min = 9;
+                pkt_dev->udp_dst_max = 9;
+
+                strncpy(pkt_dev->ifname, ifname, 31);
+                sprintf(pkt_dev->fname, "net/%s/%s", PG_PROC_DIR, ifname);
+
+                if (! pktgen_setup_dev(pkt_dev)) {
+                        printk("pktgen: ERROR: pktgen_setup_dev failed.\n");
+			if (pkt_dev->flows)
+				vfree(pkt_dev->flows);
+                        kfree(pkt_dev);
+                        return -ENODEV;
+                }
+
+                pkt_dev->proc_ent = create_proc_entry(pkt_dev->fname, 0600, 0);
+                if (!pkt_dev->proc_ent) {
+                        printk("pktgen: cannot create %s procfs entry.\n", pkt_dev->fname);
+			if (pkt_dev->flows)
+				vfree(pkt_dev->flows);
+                        kfree(pkt_dev);
+                        return -EINVAL;
+                }
+                pkt_dev->proc_ent->read_proc = proc_if_read;
+                pkt_dev->proc_ent->write_proc = proc_if_write;
+                pkt_dev->proc_ent->data = (void*)(pkt_dev);
+		pkt_dev->proc_ent->owner = THIS_MODULE;
+
+                return add_dev_to_thread(t, pkt_dev);
+        }
+        else {
+                printk("pktgen: ERROR: interface already used.\n");
+                return -EBUSY;
+        }
+}
+
+static struct pktgen_thread *pktgen_find_thread(const char* name) 
+{
+        struct pktgen_thread *t = NULL;
+
+       thread_lock();
+
+        t = pktgen_threads;
+        while (t) {
+                if (strcmp(t->name, name) == 0) 
+                        break;
+
+                t = t->next;
+        }
+        thread_unlock();
+        return t;
+}
+
+static int pktgen_create_thread(const char* name, int cpu) 
+{
+        struct pktgen_thread *t = NULL;
+
+        if (strlen(name) > 31) {
+                printk("pktgen: ERROR:  Thread name cannot be more than 31 characters.\n");
+                return -EINVAL;
+        }
+        
+        if (pktgen_find_thread(name)) {
+                printk("pktgen: ERROR: thread: %s already exists\n", name);
+                return -EINVAL;
+        }
+
+        t = (struct pktgen_thread*)(kmalloc(sizeof(struct pktgen_thread), GFP_KERNEL));
+        if (!t) {
+                printk("pktgen: ERROR: out of memory, can't create new thread.\n");
+                return -ENOMEM;
+        }
+
+        memset(t, 0, sizeof(struct pktgen_thread));
+        strcpy(t->name, name);
+        spin_lock_init(&t->if_lock);
+	t->cpu = cpu;
+        
+        sprintf(t->fname, "net/%s/%s", PG_PROC_DIR, t->name);
+        t->proc_ent = create_proc_entry(t->fname, 0600, 0);
+        if (!t->proc_ent) {
+                printk("pktgen: cannot create %s procfs entry.\n", t->fname);
+                kfree(t);
+                return -EINVAL;
+        }
+        t->proc_ent->read_proc = proc_thread_read;
+        t->proc_ent->write_proc = proc_thread_write;
+        t->proc_ent->data = (void*)(t);
+        t->proc_ent->owner = THIS_MODULE;
+
+        t->next = pktgen_threads;
+        pktgen_threads = t;
+
+	if (kernel_thread((void *) pktgen_thread_worker, (void *) t, 
+			  CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
+		printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
+
+	return 0;
+}
+
+/* 
+ * Removes a device from the thread if_list. 
+ */
+static void _rem_dev_from_if_list(struct pktgen_thread *t, struct pktgen_dev *pkt_dev) 
+{
+	struct pktgen_dev *i, *prev = NULL;
+
+	i = t->if_list;
+
+	while(i) {
+		if(i == pkt_dev) {
+			if(prev) prev->next = i->next;
+			else t->if_list = NULL;
+			break;
+		}
+		prev = i;
+		i=i->next;
 	}
+}
+
+static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *pkt_dev) 
+{
+
+	PG_DEBUG(printk("pktgen: remove_device pkt_dev=%p\n", pkt_dev));
+
+        if (pkt_dev->running) { 
+                printk("pktgen:WARNING: trying to remove a running interface, stopping it now.\n");
+                pktgen_stop_device(pkt_dev);
+        }
+        
+        /* Dis-associate from the interface */
+
+	if (pkt_dev->odev) {
+		dev_put(pkt_dev->odev);
+                pkt_dev->odev = NULL;
+        }
+        
+	/* And update the thread if_list */
+
+	_rem_dev_from_if_list(t, pkt_dev);
+
+        /* Clean up proc file system */
+
+        if (strlen(pkt_dev->fname)) 
+                remove_proc_entry(pkt_dev->fname, NULL);
+
+	if (pkt_dev->flows)
+		vfree(pkt_dev->flows);
+	kfree(pkt_dev);
+        return 0;
+}
+
+static int __init pg_init(void) 
+{
+	int cpu;
+	printk(version);
+
+        module_fname[0] = 0;
+
+	create_proc_dir();
+
+        sprintf(module_fname, "net/%s/pgctrl", PG_PROC_DIR);
+        module_proc_ent = create_proc_entry(module_fname, 0600, 0);
+        if (!module_proc_ent) {
+                printk("pktgen: ERROR: cannot create %s procfs entry.\n", module_fname);
+                return -EINVAL;
+        }
+
+        module_proc_ent->proc_fops =  &pktgen_fops;
+        module_proc_ent->data = NULL;
+
+	/* Register us to receive netdevice events */
+	register_netdevice_notifier(&pktgen_notifier_block);
+        
+	for (cpu = 0; cpu < NR_CPUS ; cpu++) {
+		char buf[30];
+
+		if (!cpu_online(cpu))
+			continue;
+
+                sprintf(buf, "kpktgend_%i", cpu);
+                pktgen_create_thread(buf, cpu);
+        }
+        return 0;        
+}
+
+static void __exit pg_cleanup(void)
+{
+	wait_queue_head_t queue;
+	init_waitqueue_head(&queue);
+
+        /* Stop all interfaces & threads */        
+
+        while (pktgen_threads) {
+                struct pktgen_thread *t = pktgen_threads;
+                pktgen_threads->control |= (T_TERMINATE);
+
+                while( t == pktgen_threads) 
+                        interruptible_sleep_on_timeout(&queue, HZ);
+        }
+
+        /* Un-register us from receiving netdevice events */
+	unregister_netdevice_notifier(&pktgen_notifier_block);
+
+        /* Clean up proc file system */
+
+        remove_proc_entry(module_fname, NULL);
+        
 	remove_proc_dir();
 }
 
-module_init(init);
-module_exit(cleanup);
+
+module_init(pg_init);
+module_exit(pg_cleanup);
 
 MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se");
 MODULE_DESCRIPTION("Packet Generator tool");
 MODULE_LICENSE("GPL");
-module_param(count_d, int, 0);
-module_param(ipg_d, int, 0);
-module_param(cpu_speed, int, 0);
-module_param(clone_skb_d, int, 0);
+module_param(pg_count_d, int, 0);
+module_param(pg_delay_d, int, 0);
+module_param(pg_clone_skb_d, int, 0);
+module_param(debug, int, 0);
diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c
--- a/net/core/rtnetlink.c	2005-01-19 13:44:48 -08:00
+++ b/net/core/rtnetlink.c	2005-01-19 13:44:48 -08:00
@@ -57,6 +57,11 @@
 {
 	rtnl_shlock();
 }
+
+int rtnl_lock_interruptible(void)
+{
+	return down_interruptible(&rtnl_sem);
+}
  
 void rtnl_unlock(void)
 {
@@ -119,6 +124,21 @@
 	memcpy(RTA_DATA(rta), data, attrlen);
 }
 
+size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size)
+{
+	size_t ret = RTA_PAYLOAD(rta);
+	char *src = RTA_DATA(rta);
+
+	if (ret > 0 && src[ret - 1] == '\0')
+		ret--;
+	if (size > 0) {
+		size_t len = (ret >= size) ? size - 1 : ret;
+		memset(dest, 0, size);
+		memcpy(dest, src, len);
+	}
+	return ret;
+}
+
 int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
 {
 	int err = 0;
@@ -241,7 +261,7 @@
 	return -1;
 }
 
-int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	int idx;
 	int s_idx = cb->args[0];
@@ -272,13 +292,9 @@
 	else if (ida[IFLA_IFNAME - 1]) {
 		char ifname[IFNAMSIZ];
 
-		if (RTA_PAYLOAD(ida[IFLA_IFNAME - 1]) > RTA_ALIGN(sizeof(ifname)))
+		if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1],
+		                   IFNAMSIZ) >= IFNAMSIZ)
 			return -EINVAL;
-
-		memset(ifname, 0, sizeof(ifname));
-		memcpy(ifname, RTA_DATA(ida[IFLA_IFNAME - 1]),
-			RTA_PAYLOAD(ida[IFLA_IFNAME - 1]));
-		ifname[IFNAMSIZ - 1] = '\0';
 		dev = dev_get_by_name(ifname);
 	} else
 		return -EINVAL;
@@ -376,16 +392,10 @@
 	if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) {
 		char ifname[IFNAMSIZ];
 
-		if (RTA_PAYLOAD(ida[IFLA_IFNAME - 1]) > RTA_ALIGN(sizeof(ifname)))
+		if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1],
+		                   IFNAMSIZ) >= IFNAMSIZ)
 			goto out;
-
-		memset(ifname, 0, sizeof(ifname));
-		memcpy(ifname, RTA_DATA(ida[IFLA_IFNAME - 1]),
-			RTA_PAYLOAD(ida[IFLA_IFNAME - 1]));
-		ifname[IFNAMSIZ - 1] = '\0';
-
 		err = dev_change_name(dev, ifname);
-
 		if (err)
 			goto out;
 	}
@@ -690,11 +700,12 @@
 }
 
 EXPORT_SYMBOL(__rta_fill);
+EXPORT_SYMBOL(rtattr_strlcpy);
 EXPORT_SYMBOL(rtattr_parse);
-EXPORT_SYMBOL(rtnetlink_dump_ifinfo);
 EXPORT_SYMBOL(rtnetlink_links);
 EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl);
 EXPORT_SYMBOL(rtnl_lock);
+EXPORT_SYMBOL(rtnl_lock_interruptible);
 EXPORT_SYMBOL(rtnl_sem);
 EXPORT_SYMBOL(rtnl_unlock);
diff -Nru a/net/core/sock.c b/net/core/sock.c
--- a/net/core/sock.c	2005-01-19 13:44:47 -08:00
+++ b/net/core/sock.c	2005-01-19 13:44:47 -08:00
@@ -825,8 +825,10 @@
  *	Generic send/receive buffer handlers
  */
 
-struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
-				     unsigned long data_len, int noblock, int *errcode)
+static struct sk_buff *sock_alloc_send_pskb(struct sock *sk,
+					    unsigned long header_len,
+					    unsigned long data_len,
+					    int noblock, int *errcode)
 {
 	struct sk_buff *skb;
 	unsigned int gfp_mask;
@@ -1084,7 +1086,7 @@
  *	Default Socket Callbacks
  */
 
-void sock_def_wakeup(struct sock *sk)
+static void sock_def_wakeup(struct sock *sk)
 {
 	read_lock(&sk->sk_callback_lock);
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
@@ -1092,7 +1094,7 @@
 	read_unlock(&sk->sk_callback_lock);
 }
 
-void sock_def_error_report(struct sock *sk)
+static void sock_def_error_report(struct sock *sk)
 {
 	read_lock(&sk->sk_callback_lock);
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
@@ -1101,7 +1103,7 @@
 	read_unlock(&sk->sk_callback_lock);
 }
 
-void sock_def_readable(struct sock *sk, int len)
+static void sock_def_readable(struct sock *sk, int len)
 {
 	read_lock(&sk->sk_callback_lock);
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
@@ -1110,7 +1112,7 @@
 	read_unlock(&sk->sk_callback_lock);
 }
 
-void sock_def_write_space(struct sock *sk)
+static void sock_def_write_space(struct sock *sk)
 {
 	read_lock(&sk->sk_callback_lock);
 
@@ -1129,7 +1131,7 @@
 	read_unlock(&sk->sk_callback_lock);
 }
 
-void sock_def_destruct(struct sock *sk)
+static void sock_def_destruct(struct sock *sk)
 {
 	if (sk->sk_protinfo)
 		kfree(sk->sk_protinfo);
@@ -1368,7 +1370,6 @@
 EXPORT_SYMBOL(sk_alloc);
 EXPORT_SYMBOL(sk_free);
 EXPORT_SYMBOL(sk_send_sigurg);
-EXPORT_SYMBOL(sock_alloc_send_pskb);
 EXPORT_SYMBOL(sock_alloc_send_skb);
 EXPORT_SYMBOL(sock_init_data);
 EXPORT_SYMBOL(sock_kfree_s);
diff -Nru a/net/core/wireless.c b/net/core/wireless.c
--- a/net/core/wireless.c	2005-01-19 13:44:48 -08:00
+++ b/net/core/wireless.c	2005-01-19 13:44:48 -08:00
@@ -304,7 +304,7 @@
 				       sizeof(struct iw_ioctl_description));
 
 /* Size (in bytes) of the various private data types */
-const char iw_priv_type_size[] = {
+static const char iw_priv_type_size[] = {
 	0,				/* IW_PRIV_TYPE_NONE */
 	1,				/* IW_PRIV_TYPE_BYTE */
 	1,				/* IW_PRIV_TYPE_CHAR */
diff -Nru a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
--- a/net/decnet/af_decnet.c	2005-01-19 13:44:46 -08:00
+++ b/net/decnet/af_decnet.c	2005-01-19 13:44:46 -08:00
@@ -151,7 +151,7 @@
 
 static kmem_cache_t *dn_sk_cachep;
 static struct proto_ops dn_proto_ops;
-static rwlock_t dn_hash_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(dn_hash_lock);
 static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
 
@@ -246,7 +246,7 @@
 	write_unlock_bh(&dn_hash_lock);
 }
 
-struct hlist_head *listen_hash(struct sockaddr_dn *addr)
+static struct hlist_head *listen_hash(struct sockaddr_dn *addr)
 {
 	int i;
 	unsigned hash = addr->sdn_objnum;
@@ -447,7 +447,7 @@
 	dst_release(xchg(&sk->sk_dst_cache, NULL));
 }
 
-struct sock *dn_alloc_sock(struct socket *sock, int gfp)
+static struct sock *dn_alloc_sock(struct socket *sock, int gfp)
 {
 	struct dn_scp *scp;
 	struct sock *sk = sk_alloc(PF_DECnet, gfp, sizeof(struct dn_sock),
@@ -578,7 +578,6 @@
 	if (sk->sk_socket)
 		return 0;
 
-	dn_stop_fast_timer(sk); /* unlikely, but possible that this is runninng */
 	if ((jiffies - scp->stamp) >= (HZ * decnet_time_wait)) {
 		dn_unhash_sock(sk);
 		sock_put(sk);
@@ -631,7 +630,6 @@
 		default:
 			printk(KERN_DEBUG "DECnet: dn_destroy_sock passed socket in invalid state\n");
 		case DN_O:
-			dn_stop_fast_timer(sk);
 			dn_stop_slow_timer(sk);
 
 			dn_unhash_sock_bh(sk);
diff -Nru a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
--- a/net/decnet/dn_dev.c	2005-01-19 13:44:46 -08:00
+++ b/net/decnet/dn_dev.c	2005-01-19 13:44:46 -08:00
@@ -65,7 +65,7 @@
  */
 dn_address decnet_address = 0;
 
-static rwlock_t dndev_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(dndev_lock);
 static struct net_device *decnet_default_device;
 static struct notifier_block *dnaddr_chain;
 
@@ -662,7 +662,7 @@
 	for(ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) {
 		void *tmp = rta[IFA_LOCAL-1];
 		if ((tmp && memcmp(RTA_DATA(tmp), &ifa->ifa_local, 2)) ||
-				(rta[IFA_LABEL-1] && strcmp(RTA_DATA(rta[IFA_LABEL-1]), ifa->ifa_label)))
+		    (rta[IFA_LABEL-1] && rtattr_strcmp(rta[IFA_LABEL-1], ifa->ifa_label)))
 			continue;
 
 		dn_dev_del_ifa(dn_db, ifap, 1);
@@ -705,7 +705,7 @@
 	ifa->ifa_scope = ifm->ifa_scope;
 	ifa->ifa_dev = dn_db;
 	if (rta[IFA_LABEL-1])
-		memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL-1]), IFNAMSIZ);
+		rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL-1], IFNAMSIZ);
 	else
 		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 
diff -Nru a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
--- a/net/decnet/dn_fib.c	2005-01-19 13:44:48 -08:00
+++ b/net/decnet/dn_fib.c	2005-01-19 13:44:48 -08:00
@@ -57,10 +57,9 @@
 
 extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);
 
-static spinlock_t dn_fib_multipath_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dn_fib_multipath_lock);
 static struct dn_fib_info *dn_fib_info_list;
-static rwlock_t dn_fib_info_lock = RW_LOCK_UNLOCKED;
-int dn_fib_info_cnt;
+static DEFINE_RWLOCK(dn_fib_info_lock);
 
 static struct
 {
@@ -93,7 +92,6 @@
 			dev_put(nh->nh_dev);
 		nh->nh_dev = NULL;
 	} endfor_nexthops(fi);
-	dn_fib_info_cnt--;
 	kfree(fi);
 }
 
@@ -388,7 +386,6 @@
 	if (dn_fib_info_list)
 		dn_fib_info_list->fib_prev = fi;
 	dn_fib_info_list = fi;
-	dn_fib_info_cnt++;
 	write_unlock(&dn_fib_info_lock);
 	return fi;
 
@@ -483,18 +480,6 @@
 	} endfor_nexthops(fi);
 	res->nh_sel = 0;
 	spin_unlock_bh(&dn_fib_multipath_lock);
-}
-
-
-/*
- * Punt to user via netlink for example, but for now
- * we just drop it.
- */
-int dn_fib_rt_message(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-
-	return 0;
 }
 
 
diff -Nru a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
--- a/net/decnet/dn_neigh.c	2005-01-19 13:44:47 -08:00
+++ b/net/decnet/dn_neigh.c	2005-01-19 13:44:47 -08:00
@@ -355,14 +355,6 @@
  * basically does a neigh_lookup(), but without comparing the device
  * field. This is required for the On-Ethernet cache
  */
-/*
- * Any traffic on a pointopoint link causes the timer to be reset
- * for the entry in the neighbour table.
- */
-void dn_neigh_pointopoint_notify(struct sk_buff *skb)
-{
-	return;
-}
 
 /*
  * Pointopoint link receives a hello message
diff -Nru a/net/decnet/dn_route.c b/net/decnet/dn_route.c
--- a/net/decnet/dn_route.c	2005-01-19 13:44:47 -08:00
+++ b/net/decnet/dn_route.c	2005-01-19 13:44:47 -08:00
@@ -99,9 +99,9 @@
 
 static unsigned char dn_hiord_addr[6] = {0xAA,0x00,0x04,0x00,0x00,0x00};
 
-int dn_rt_min_delay = 2 * HZ;
-int dn_rt_max_delay = 10 * HZ;
-int dn_rt_mtu_expires = 10 * 60 * HZ;
+static const int dn_rt_min_delay = 2 * HZ;
+static const int dn_rt_max_delay = 10 * HZ;
+static const int dn_rt_mtu_expires = 10 * 60 * HZ;
 
 static unsigned long dn_rt_deadline;
 
@@ -336,7 +336,7 @@
 	}
 }
 
-static spinlock_t dn_rt_flush_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(dn_rt_flush_lock);
 
 void dn_rt_cache_flush(int delay)
 {
diff -Nru a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
--- a/net/decnet/dn_rules.c	2005-01-19 13:44:47 -08:00
+++ b/net/decnet/dn_rules.c	2005-01-19 13:44:47 -08:00
@@ -68,7 +68,7 @@
 };
 
 static struct dn_fib_rule *dn_fib_rules = &default_rule;
-static rwlock_t dn_fib_rules_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(dn_fib_rules_lock);
 
 
 int dn_fib_rtm_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
@@ -88,7 +88,7 @@
 #endif
 			(!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
 			(!rta[RTA_PRIORITY-1] || memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
-			(!rta[RTA_IIF-1] || strcmp(RTA_DATA(rta[RTA_IIF-1]), r->r_ifname) == 0) &&
+			(!rta[RTA_IIF-1] || rtattr_strcmp(rta[RTA_IIF-1], r->r_ifname) == 0) &&
 			(!rtm->rtm_table || (r && rtm->rtm_table == r->r_table))) {
 
 			err = -EPERM;
@@ -170,8 +170,7 @@
 	new_r->r_table = table_id;
 	if (rta[RTA_IIF-1]) {
 		struct net_device *dev;
-		memcpy(new_r->r_ifname, RTA_DATA(rta[RTA_IIF-1]), IFNAMSIZ);
-		new_r->r_ifname[IFNAMSIZ-1] = 0;
+		rtattr_strlcpy(new_r->r_ifname, rta[RTA_IIF-1], IFNAMSIZ);
 		new_r->r_ifindex = -1;
 		dev = dev_get_by_name(new_r->r_ifname);
 		if (dev) {
diff -Nru a/net/decnet/dn_table.c b/net/decnet/dn_table.c
--- a/net/decnet/dn_table.c	2005-01-19 13:44:46 -08:00
+++ b/net/decnet/dn_table.c	2005-01-19 13:44:46 -08:00
@@ -76,7 +76,7 @@
 
 #define RT_TABLE_MIN 1
 
-static rwlock_t dn_fib_tables_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(dn_fib_tables_lock);
 struct dn_fib_table *dn_fib_tables[RT_TABLE_MAX + 1];
 
 static kmem_cache_t *dn_hash_kmem;
diff -Nru a/net/decnet/dn_timer.c b/net/decnet/dn_timer.c
--- a/net/decnet/dn_timer.c	2005-01-19 13:44:47 -08:00
+++ b/net/decnet/dn_timer.c	2005-01-19 13:44:47 -08:00
@@ -27,11 +27,9 @@
 #include <net/dn.h>
 
 /*
- * Fast timer is for delayed acks (200mS max)
  * Slow timer is for everything else (n * 500mS)
  */
 
-#define FAST_INTERVAL (HZ/5)
 #define SLOW_INTERVAL (HZ/2)
 
 static void dn_slow_timer(unsigned long arg);
@@ -109,48 +107,3 @@
 	bh_unlock_sock(sk);
 	sock_put(sk);
 }
-
-static void dn_fast_timer(unsigned long arg)
-{
-	struct sock *sk = (struct sock *)arg;
-	struct dn_scp *scp = DN_SK(sk);
-
-	bh_lock_sock(sk);
-	if (sock_owned_by_user(sk)) {
-		scp->delack_timer.expires = jiffies + HZ / 20;
-		add_timer(&scp->delack_timer);
-		goto out;
-	}
-
-	scp->delack_pending = 0;
-
-	if (scp->delack_fxn)
-		scp->delack_fxn(sk);
-out:
-	bh_unlock_sock(sk);
-}
-
-void dn_start_fast_timer(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (!scp->delack_pending) {
-		scp->delack_pending = 1;
-		init_timer(&scp->delack_timer);
-		scp->delack_timer.expires = jiffies + FAST_INTERVAL;
-		scp->delack_timer.data = (unsigned long)sk;
-		scp->delack_timer.function = dn_fast_timer;
-		add_timer(&scp->delack_timer);
-	}
-}
-
-void dn_stop_fast_timer(struct sock *sk)
-{
-	struct dn_scp *scp = DN_SK(sk);
-
-	if (scp->delack_pending) {
-		scp->delack_pending = 0;
-		del_timer(&scp->delack_timer);
-	}
-}
-
diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c
--- a/net/econet/af_econet.c	2005-01-19 13:44:46 -08:00
+++ b/net/econet/af_econet.c	2005-01-19 13:44:46 -08:00
@@ -47,7 +47,7 @@
 
 static struct proto_ops econet_ops;
 static struct hlist_head econet_sklist;
-static rwlock_t econet_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(econet_lock);
 
 /* Since there are only 256 possible network numbers (or fewer, depends
    how you count) it makes sense to use a simple lookup table. */
diff -Nru a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
--- a/net/ipv4/af_inet.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/af_inet.c	2005-01-19 13:44:46 -08:00
@@ -125,7 +125,7 @@
  * build a new socket.
  */
 static struct list_head inetsw[SOCK_MAX];
-static spinlock_t inetsw_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inetsw_lock);
 
 /* New destruction routine */
 
diff -Nru a/net/ipv4/devinet.c b/net/ipv4/devinet.c
--- a/net/ipv4/devinet.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/devinet.c	2005-01-19 13:44:46 -08:00
@@ -399,7 +399,7 @@
 		     memcmp(RTA_DATA(rta[IFA_LOCAL - 1]),
 			    &ifa->ifa_local, 4)) ||
 		    (rta[IFA_LABEL - 1] &&
-		     strcmp(RTA_DATA(rta[IFA_LABEL - 1]), ifa->ifa_label)) ||
+		     rtattr_strcmp(rta[IFA_LABEL - 1], ifa->ifa_label)) ||
 		    (rta[IFA_ADDRESS - 1] &&
 		     (ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
 		      !inet_ifa_match(*(u32*)RTA_DATA(rta[IFA_ADDRESS - 1]),
@@ -456,7 +456,7 @@
 	in_dev_hold(in_dev);
 	ifa->ifa_dev   = in_dev;
 	if (rta[IFA_LABEL - 1])
-		memcpy(ifa->ifa_label, RTA_DATA(rta[IFA_LABEL - 1]), IFNAMSIZ);
+		rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL - 1], IFNAMSIZ);
 	else
 		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
 
diff -Nru a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
--- a/net/ipv4/fib_hash.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/fib_hash.c	2005-01-19 13:44:46 -08:00
@@ -92,7 +92,7 @@
 	return dst & FZ_MASK(fz);
 }
 
-static rwlock_t fib_hash_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(fib_hash_lock);
 
 #define FZ_MAX_DIVISOR ((PAGE_SIZE<<MAX_ORDER) / sizeof(struct hlist_head))
 
diff -Nru a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
--- a/net/ipv4/fib_rules.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/fib_rules.c	2005-01-19 13:44:47 -08:00
@@ -99,7 +99,7 @@
 };
 
 static struct fib_rule *fib_rules = &local_rule;
-static rwlock_t fib_rules_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(fib_rules_lock);
 
 int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
@@ -119,7 +119,7 @@
 #endif
 		    (!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
 		    (!rta[RTA_PRIORITY-1] || memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
-		    (!rta[RTA_IIF-1] || strcmp(RTA_DATA(rta[RTA_IIF-1]), r->r_ifname) == 0) &&
+		    (!rta[RTA_IIF-1] || rtattr_strcmp(rta[RTA_IIF-1], r->r_ifname) == 0) &&
 		    (!rtm->rtm_table || (r && rtm->rtm_table == r->r_table))) {
 			err = -EPERM;
 			if (r == &local_rule)
@@ -209,8 +209,7 @@
 	new_r->r_table = table_id;
 	if (rta[RTA_IIF-1]) {
 		struct net_device *dev;
-		memcpy(new_r->r_ifname, RTA_DATA(rta[RTA_IIF-1]), IFNAMSIZ);
-		new_r->r_ifname[IFNAMSIZ-1] = 0;
+		rtattr_strlcpy(new_r->r_ifname, rta[RTA_IIF-1], IFNAMSIZ);
 		new_r->r_ifindex = -1;
 		dev = __dev_get_by_name(new_r->r_ifname);
 		if (dev)
diff -Nru a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
--- a/net/ipv4/fib_semantics.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/fib_semantics.c	2005-01-19 13:44:46 -08:00
@@ -47,7 +47,7 @@
 
 #define FSprintk(a...)
 
-static rwlock_t fib_info_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(fib_info_lock);
 static struct hlist_head *fib_info_hash;
 static struct hlist_head *fib_info_laddrhash;
 static unsigned int fib_hash_size;
@@ -59,7 +59,7 @@
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 
-static spinlock_t fib_multipath_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(fib_multipath_lock);
 
 #define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \
 for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
diff -Nru a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
--- a/net/ipv4/inetpeer.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/inetpeer.c	2005-01-19 13:44:47 -08:00
@@ -70,7 +70,7 @@
  */
 
 /* Exported for inet_getid inline function.  */
-spinlock_t inet_peer_idlock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(inet_peer_idlock);
 
 static kmem_cache_t *peer_cachep;
 
@@ -82,7 +82,7 @@
 };
 #define peer_avl_empty (&peer_fake_node)
 static struct inet_peer *peer_root = peer_avl_empty;
-static rwlock_t peer_pool_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(peer_pool_lock);
 #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */
 
 static volatile int peer_total;
@@ -95,7 +95,7 @@
 /* Exported for inet_putpeer inline function.  */
 struct inet_peer *inet_peer_unused_head,
 		**inet_peer_unused_tailp = &inet_peer_unused_head;
-spinlock_t inet_peer_unused_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(inet_peer_unused_lock);
 #define PEER_MAX_CLEANUP_WORK 30
 
 static void peer_check_expire(unsigned long dummy);
diff -Nru a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
--- a/net/ipv4/ip_fragment.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/ip_fragment.c	2005-01-19 13:44:46 -08:00
@@ -99,7 +99,7 @@
 
 /* Per-bucket lock is easy to add now. */
 static struct ipq *ipq_hash[IPQ_HASHSZ];
-static rwlock_t ipfrag_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipfrag_lock);
 static u32 ipfrag_hash_rnd;
 static LIST_HEAD(ipq_lru_list);
 int ip_frag_nqueues = 0;
diff -Nru a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
--- a/net/ipv4/ip_gre.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv4/ip_gre.c	2005-01-19 13:44:48 -08:00
@@ -152,7 +152,7 @@
 #define tunnels_l	(tunnels[1])
 #define tunnels_wc	(tunnels[0])
 
-static rwlock_t ipgre_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipgre_lock);
 
 /* Given src, dst and key, find appropriate for input tunnel. */
 
diff -Nru a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
--- a/net/ipv4/ip_sockglue.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/ip_sockglue.c	2005-01-19 13:44:46 -08:00
@@ -186,7 +186,7 @@
    sent to multicast group to reach destination designated router.
  */
 struct ip_ra_chain *ip_ra_chain;
-rwlock_t ip_ra_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(ip_ra_lock);
 
 int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *))
 {
diff -Nru a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
--- a/net/ipv4/ipconfig.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv4/ipconfig.c	2005-01-19 13:44:45 -08:00
@@ -152,7 +152,7 @@
 static int ic_proto_have_if __initdata = 0;
 
 #ifdef IPCONFIG_DYNAMIC
-static spinlock_t ic_recv_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ic_recv_lock);
 static volatile int ic_got_reply __initdata = 0;    /* Proto(s) that replied */
 #endif
 #ifdef IPCONFIG_DHCP
diff -Nru a/net/ipv4/ipip.c b/net/ipv4/ipip.c
--- a/net/ipv4/ipip.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv4/ipip.c	2005-01-19 13:44:48 -08:00
@@ -132,7 +132,7 @@
 static struct ip_tunnel *tunnels_wc[1];
 static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l };
 
-static rwlock_t ipip_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipip_lock);
 
 static struct ip_tunnel * ipip_tunnel_lookup(u32 remote, u32 local)
 {
diff -Nru a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
--- a/net/ipv4/ipmr.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/ipmr.c	2005-01-19 13:44:46 -08:00
@@ -73,7 +73,7 @@
    Note that the changes are semaphored via rtnl_lock.
  */
 
-static rwlock_t mrt_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(mrt_lock);
 
 /*
  *	Multicast router control variables
@@ -93,7 +93,7 @@
 static atomic_t cache_resolve_queue_len;		/* Size of unresolved	*/
 
 /* Special spinlock for queue of unresolved entries */
-static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(mfc_unres_lock);
 
 /* We return to original Alan's scheme. Hash table of resolved
    entries is changed only in process context and protected
diff -Nru a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
--- a/net/ipv4/ipvs/ip_vs_core.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv4/ipvs/ip_vs_core.c	2005-01-19 13:44:45 -08:00
@@ -57,7 +57,6 @@
 #ifdef CONFIG_IP_VS_DEBUG
 EXPORT_SYMBOL(ip_vs_get_debug_level);
 #endif
-EXPORT_SYMBOL(check_for_ip_vs_out);
 EXPORT_SYMBOL(ip_vs_make_skb_writable);
 
 
@@ -833,31 +832,6 @@
 	return NF_STOLEN;
 }
 
-
-/*
- *      Check if the packet is for VS/NAT connections, then send it
- *      immediately.
- *      Called by ip_fw_compact to detect packets for VS/NAT before
- *      they are changed by ipchains masquerading code.
- */
-unsigned int
-check_for_ip_vs_out(struct sk_buff **pskb, int (*okfn)(struct sk_buff *))
-{
-	unsigned int ret;
-
-	ret = ip_vs_out(NF_IP_FORWARD, pskb, NULL, NULL, NULL);
-	if (ret != NF_ACCEPT) {
-		return ret;
-	} else {
-		/* send the packet immediately if it is already mangled
-		   by ip_vs_out */
-		if ((*pskb)->nfcache & NFC_IPVS_PROPERTY) {
-			(*okfn)(*pskb);
-			return NF_STOLEN;
-		}
-	}
-	return NF_ACCEPT;
-}
 
 /*
  *	Handle ICMP messages in the outside-to-inside direction (incoming).
diff -Nru a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
--- a/net/ipv4/ipvs/ip_vs_ctl.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/ipvs/ip_vs_ctl.c	2005-01-19 13:44:47 -08:00
@@ -45,19 +45,19 @@
 static DECLARE_MUTEX(__ip_vs_mutex);
 
 /* lock for service table */
-static rwlock_t __ip_vs_svc_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(__ip_vs_svc_lock);
 
 /* lock for table with the real services */
-static rwlock_t __ip_vs_rs_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(__ip_vs_rs_lock);
 
 /* lock for state and timeout tables */
-static rwlock_t __ip_vs_securetcp_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(__ip_vs_securetcp_lock);
 
 /* lock for drop entry handling */
-static spinlock_t __ip_vs_dropentry_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(__ip_vs_dropentry_lock);
 
 /* lock for drop packet handling */
-static spinlock_t __ip_vs_droppacket_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(__ip_vs_droppacket_lock);
 
 /* 1/rate drop and drop-entry variables */
 int ip_vs_drop_rate = 0;
diff -Nru a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c
--- a/net/ipv4/ipvs/ip_vs_est.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv4/ipvs/ip_vs_est.c	2005-01-19 13:44:45 -08:00
@@ -62,7 +62,7 @@
 
 
 static struct ip_vs_estimator *est_list = NULL;
-static rwlock_t est_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(est_lock);
 static struct timer_list est_timer;
 
 static void estimation_timer(unsigned long arg)
diff -Nru a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c	2005-01-19 13:44:46 -08:00
@@ -510,7 +510,7 @@
 #define	TCP_APP_TAB_MASK	(TCP_APP_TAB_SIZE - 1)
 
 static struct list_head tcp_apps[TCP_APP_TAB_SIZE];
-static spinlock_t tcp_app_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tcp_app_lock);
 
 static inline __u16 tcp_app_hashkey(__u16 port)
 {
diff -Nru a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c	2005-01-19 13:44:48 -08:00
@@ -277,7 +277,7 @@
 #define	UDP_APP_TAB_MASK	(UDP_APP_TAB_SIZE - 1)
 
 static struct list_head udp_apps[UDP_APP_TAB_SIZE];
-static spinlock_t udp_app_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(udp_app_lock);
 
 static inline __u16 udp_app_hashkey(__u16 port)
 {
diff -Nru a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c
--- a/net/ipv4/ipvs/ip_vs_sched.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv4/ipvs/ip_vs_sched.c	2005-01-19 13:44:45 -08:00
@@ -33,7 +33,7 @@
 static LIST_HEAD(ip_vs_schedulers);
 
 /* lock for service table */
-static rwlock_t __ip_vs_sched_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(__ip_vs_sched_lock);
 
 
 /*
diff -Nru a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
--- a/net/ipv4/ipvs/ip_vs_sync.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv4/ipvs/ip_vs_sync.c	2005-01-19 13:44:48 -08:00
@@ -119,11 +119,11 @@
 
 /* the sync_buff list head and the lock */
 static LIST_HEAD(ip_vs_sync_queue);
-static spinlock_t ip_vs_sync_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ip_vs_sync_lock);
 
 /* current sync_buff for accepting new conn entries */
 static struct ip_vs_sync_buff   *curr_sb = NULL;
-static spinlock_t curr_sb_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(curr_sb_lock);
 
 /* ipvs sync daemon state */
 volatile int ip_vs_sync_state = IP_VS_STATE_NONE;
diff -Nru a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
--- a/net/ipv4/netfilter/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/netfilter/Kconfig	2005-01-19 13:44:47 -08:00
@@ -48,7 +48,7 @@
 	  be able to do state tracking on SCTP connections.
 
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_FTP
 	tristate "FTP protocol support"
@@ -313,7 +313,7 @@
 	  eg. UNICAST, LOCAL, BROADCAST, ...
 	
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_MATCH_REALM
 	tristate  'realm match support'
@@ -321,13 +321,13 @@
 	select NET_CLS_ROUTE
 	help
 	  This option adds a `realm' match, which allows you to use the realm
-	  key from the routing subsytem inside iptables.
+	  key from the routing subsystem inside iptables.
 	
 	  This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option 
 	  in tc world.
 	
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_MATCH_SCTP
 	tristate  'SCTP protocol match support'
@@ -338,7 +338,7 @@
 	  and SCTP chunk types.
 
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_MATCH_COMMENT
 	tristate  'comment match support'
@@ -348,7 +348,7 @@
 	  comments in your iptables ruleset.
 
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  If unsure, say `N'.
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
 config IP_NF_MATCH_CONNMARK
 	tristate  'Connection mark match support'
@@ -358,7 +358,7 @@
 	  connection mark value previously set for the session by `CONNMARK'. 
 	
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  The module will be called
+	  <file:Documentation/modules.txt>.  The module will be called
 	  ipt_connmark.o.  If unsure, say `N'.
 
 config IP_NF_MATCH_HASHLIMIT
@@ -625,7 +625,7 @@
 	  affects the connection mark value rather than the packet mark value.
 	
 	  If you want to compile it as a module, say M here and read
-	  Documentation/modules.txt.  The module will be called
+	  <file:Documentation/modules.txt>.  The module will be called
 	  ipt_CONNMARK.o.  If unsure, say `N'.
 
 config IP_NF_TARGET_CLUSTERIP
@@ -649,7 +649,6 @@
 	
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
-	  help
 
 config IP_NF_TARGET_NOTRACK
 	tristate  'NOTRACK target support'
diff -Nru a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
--- a/net/ipv4/netfilter/arp_tables.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv4/netfilter/arp_tables.c	2005-01-19 13:44:48 -08:00
@@ -1150,7 +1150,8 @@
 	up(&arpt_mutex);
 }
 
-int arpt_register_table(struct arpt_table *table)
+int arpt_register_table(struct arpt_table *table,
+			const struct arpt_replace *repl)
 {
 	int ret;
 	struct arpt_table_info *newinfo;
@@ -1158,18 +1159,18 @@
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
 	newinfo = vmalloc(sizeof(struct arpt_table_info)
-			  + SMP_ALIGN(table->table->size) * NR_CPUS);
+			  + SMP_ALIGN(repl->size) * NR_CPUS);
 	if (!newinfo) {
 		ret = -ENOMEM;
 		return ret;
 	}
-	memcpy(newinfo->entries, table->table->entries, table->table->size);
+	memcpy(newinfo->entries, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, table->table->size,
-			      table->table->num_entries,
-			      table->table->hook_entry,
-			      table->table->underflow);
+			      newinfo, repl->size,
+			      repl->num_entries,
+			      repl->hook_entry,
+			      repl->underflow);
 	duprintf("arpt_register_table: translate table gives %d\n", ret);
 	if (ret != 0) {
 		vfree(newinfo);
diff -Nru a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
--- a/net/ipv4/netfilter/arptable_filter.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv4/netfilter/arptable_filter.c	2005-01-19 13:44:48 -08:00
@@ -141,7 +141,6 @@
 
 static struct arpt_table packet_filter = {
 	.name		= "filter",
-	.table		= &initial_table.repl,
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.private	= NULL,
@@ -184,7 +183,7 @@
 	int ret, i;
 
 	/* Register table */
-	ret = arpt_register_table(&packet_filter);
+	ret = arpt_register_table(&packet_filter, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
--- a/net/ipv4/netfilter/ip_nat_rule.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/netfilter/ip_nat_rule.c	2005-01-19 13:44:46 -08:00
@@ -35,32 +35,13 @@
 
 #define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT))
 
-/* Standard entry. */
-struct ipt_standard
-{
-	struct ipt_entry entry;
-	struct ipt_standard_target target;
-};
-
-struct ipt_error_target
-{
-	struct ipt_entry_target target;
-	char errorname[IPT_FUNCTION_MAXNAMELEN];
-};
-
-struct ipt_error
-{
-	struct ipt_entry entry;
-	struct ipt_error_target target;
-};
-
 static struct
 {
 	struct ipt_replace repl;
 	struct ipt_standard entries[3];
 	struct ipt_error term;
-} nat_initial_table = {
-    { "nat", NAT_VALID_HOOKS, 4,
+} nat_initial_table __initdata
+= { { "nat", NAT_VALID_HOOKS, 4,
       sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
       { [NF_IP_PRE_ROUTING] = 0,
 	[NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
@@ -110,7 +91,6 @@
 
 static struct ipt_table nat_table = {
 	.name		= "nat",
-	.table		= &nat_initial_table.repl,
 	.valid_hooks	= NAT_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE,
@@ -285,7 +265,7 @@
 {
 	int ret;
 
-	ret = ipt_register_table(&nat_table);
+	ret = ipt_register_table(&nat_table, &nat_initial_table.repl);
 	if (ret != 0)
 		return ret;
 	ret = ipt_register_target(&ipt_snat_reg);
diff -Nru a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c	2005-01-19 13:44:47 -08:00
@@ -65,7 +65,7 @@
 #define NOCT1(n) (u_int8_t )((n) & 0xff)
 
 static int debug;
-static spinlock_t snmp_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(snmp_lock);
 
 /* 
  * Application layer address mapping mimics the NAT mapping, but 
diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv4/netfilter/ip_queue.c	2005-01-19 13:44:48 -08:00
@@ -55,7 +55,7 @@
 
 static unsigned char copy_mode = IPQ_COPY_NONE;
 static unsigned int queue_maxlen = IPQ_QMAX_DEFAULT;
-static rwlock_t queue_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(queue_lock);
 static int peer_pid;
 static unsigned int copy_range;
 static unsigned int queue_total;
diff -Nru a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
--- a/net/ipv4/netfilter/ip_tables.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/netfilter/ip_tables.c	2005-01-19 13:44:46 -08:00
@@ -430,62 +430,63 @@
 	return NULL;
 }
 
-/* Find match, grabs mutex & ref.  Returns ERR_PTR() on error. */
-static inline struct ipt_match *find_match_lock(const char *name, u8 revision)
+/* Find match, grabs ref.  Returns ERR_PTR() on error. */
+static inline struct ipt_match *find_match(const char *name, u8 revision)
 {
 	struct ipt_match *m;
-	int found = 0;
+	int err = 0;
 
 	if (down_interruptible(&ipt_mutex) != 0)
 		return ERR_PTR(-EINTR);
 
 	list_for_each_entry(m, &ipt_match, list) {
 		if (strcmp(m->name, name) == 0) {
-			found = 1;
 			if (m->revision == revision) {
-				if (!try_module_get(m->me))
-					found = 0;
-				else
+				if (try_module_get(m->me)) {
+					up(&ipt_mutex);
 					return m;
-			}
+				}
+			} else
+				err = -EPROTOTYPE; /* Found something. */
 		}
 	}
 	up(&ipt_mutex);
-
-	/* Not found at all?  NULL so try_then_request_module loads module. */
-	if (!found)
-		return NULL;
-
-	return ERR_PTR(-EPROTOTYPE);
+	return ERR_PTR(err);
 }
 
-/* Find target, grabs mutex & ref.  Returns ERR_PTR() on error. */
-static inline struct ipt_target *find_target_lock(const char *name, u8 revision)
+/* Find target, grabs ref.  Returns ERR_PTR() on error. */
+static inline struct ipt_target *find_target(const char *name, u8 revision)
 {
 	struct ipt_target *t;
-	int found = 0;
+	int err = 0;
 
 	if (down_interruptible(&ipt_mutex) != 0)
 		return ERR_PTR(-EINTR);
 
 	list_for_each_entry(t, &ipt_target, list) {
 		if (strcmp(t->name, name) == 0) {
-			found = 1;
 			if (t->revision == revision) {
-				if (!try_module_get(t->me))
-					found = 0;
-				else
+				if (try_module_get(t->me)) {
+					up(&ipt_mutex);
 					return t;
-			}
+				}
+			} else
+				err = -EPROTOTYPE; /* Found something. */
 		}
 	}
 	up(&ipt_mutex);
+	return ERR_PTR(err);
+}
 
-	/* Not found at all?  NULL so try_then_request_module loads module. */
-	if (!found)
-		return NULL;
+struct ipt_target *ipt_find_target(const char *name, u8 revision)
+{
+	struct ipt_target *target;
 
-	return ERR_PTR(-EPROTOTYPE);
+	target = try_then_request_module(find_target(name, revision),
+					 "ipt_%s", name);
+	if (IS_ERR(target) || !target)
+		return NULL;
+	return target;
 }
 
 static int match_revfn(const char *name, u8 revision, int *bestp)
@@ -708,15 +709,14 @@
 {
 	struct ipt_match *match;
 
-	match = try_then_request_module(find_match_lock(m->u.user.name,
-							m->u.user.revision),
+	match = try_then_request_module(find_match(m->u.user.name,
+						   m->u.user.revision),
 					"ipt_%s", m->u.user.name);
 	if (IS_ERR(match) || !match) {
 		duprintf("check_match: `%s' not found\n", m->u.user.name);
 		return match ? PTR_ERR(match) : -ENOENT;
 	}
 	m->u.kernel.match = match;
-	up(&ipt_mutex);
 
 	if (m->u.kernel.match->checkentry
 	    && !m->u.kernel.match->checkentry(name, ip, m->data,
@@ -754,8 +754,8 @@
 		goto cleanup_matches;
 
 	t = ipt_get_target(e);
-	target = try_then_request_module(find_target_lock(t->u.user.name,
-							  t->u.user.revision),
+	target = try_then_request_module(find_target(t->u.user.name,
+						     t->u.user.revision),
 					 "ipt_%s", t->u.user.name);
 	if (IS_ERR(target) || !target) {
 		duprintf("check_entry: `%s' not found\n", t->u.user.name);
@@ -763,7 +763,6 @@
 		goto cleanup_matches;
 	}
 	t->u.kernel.target = target;
-	up(&ipt_mutex);
 
 	if (t->u.kernel.target == &ipt_standard_target) {
 		if (!standard_check(t, size)) {
@@ -1453,7 +1452,7 @@
 	up(&ipt_mutex);
 }
 
-int ipt_register_table(struct ipt_table *table)
+int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl)
 {
 	int ret;
 	struct ipt_table_info *newinfo;
@@ -1461,17 +1460,17 @@
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
 	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(table->table->size) * NR_CPUS);
+			  + SMP_ALIGN(repl->size) * NR_CPUS);
 	if (!newinfo)
 		return -ENOMEM;
 
-	memcpy(newinfo->entries, table->table->entries, table->table->size);
+	memcpy(newinfo->entries, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, table->table->size,
-			      table->table->num_entries,
-			      table->table->hook_entry,
-			      table->table->underflow);
+			      newinfo, repl->size,
+			      repl->num_entries,
+			      repl->hook_entry,
+			      repl->underflow);
 	if (ret != 0) {
 		vfree(newinfo);
 		return ret;
@@ -1959,6 +1958,7 @@
 EXPORT_SYMBOL(ipt_do_table);
 EXPORT_SYMBOL(ipt_register_target);
 EXPORT_SYMBOL(ipt_unregister_target);
+EXPORT_SYMBOL(ipt_find_target);
 
 module_init(init);
 module_exit(fini);
diff -Nru a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
--- a/net/ipv4/netfilter/ipt_LOG.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/netfilter/ipt_LOG.c	2005-01-19 13:44:47 -08:00
@@ -38,7 +38,7 @@
 #endif
 
 /* Use lock to serialize, so printks don't overlap */
-static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(log_lock);
 
 /* One level of recursion won't kill us */
 static void dump_packet(const struct ipt_log_info *info,
@@ -325,6 +325,14 @@
 	/* Max length: 10 "PROTO 255 " */
 	default:
 		printk("PROTO=%u ", ih->protocol);
+	}
+
+	/* Max length: 15 "UID=4294967295 " */
+ 	if ((info->logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
+		read_lock_bh(&skb->sk->sk_callback_lock);
+		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
+ 			printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
+		read_unlock_bh(&skb->sk->sk_callback_lock);
 	}
 
 	/* Proto    Max log string length */
diff -Nru a/net/ipv4/netfilter/ipt_limit.c b/net/ipv4/netfilter/ipt_limit.c
--- a/net/ipv4/netfilter/ipt_limit.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv4/netfilter/ipt_limit.c	2005-01-19 13:44:45 -08:00
@@ -29,7 +29,7 @@
  * see net/sched/sch_tbf.c in the linux source tree
  */
 
-static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(limit_lock);
 
 /* Rusty: This is my (non-mathematically-inclined) understanding of
    this algorithm.  The `average rate' in jiffies becomes your initial
diff -Nru a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
--- a/net/ipv4/netfilter/ipt_recent.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/netfilter/ipt_recent.c	2005-01-19 13:44:46 -08:00
@@ -90,7 +90,7 @@
 /* We protect r_list with this spinlock so two processors are not modifying
  * the list at the same time. 
  */
-static spinlock_t recent_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(recent_lock);
 
 #ifdef CONFIG_PROC_FS
 /* Our /proc/net/ipt_recent entry */
diff -Nru a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
--- a/net/ipv4/netfilter/iptable_filter.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/netfilter/iptable_filter.c	2005-01-19 13:44:46 -08:00
@@ -20,32 +20,13 @@
 
 #define FILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))
 
-/* Standard entry. */
-struct ipt_standard
-{
-	struct ipt_entry entry;
-	struct ipt_standard_target target;
-};
-
-struct ipt_error_target
-{
-	struct ipt_entry_target target;
-	char errorname[IPT_FUNCTION_MAXNAMELEN];
-};
-
-struct ipt_error
-{
-	struct ipt_entry entry;
-	struct ipt_error_target target;
-};
-
 static struct
 {
 	struct ipt_replace repl;
 	struct ipt_standard entries[3];
 	struct ipt_error term;
-} initial_table = {
-    { "filter", FILTER_VALID_HOOKS, 4,
+} initial_table __initdata 
+= { { "filter", FILTER_VALID_HOOKS, 4,
       sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
       { [NF_IP_LOCAL_IN] = 0,
 	[NF_IP_FORWARD] = sizeof(struct ipt_standard),
@@ -95,7 +76,6 @@
 
 static struct ipt_table packet_filter = {
 	.name		= "filter",
-	.table		= &initial_table.repl,
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE
@@ -171,7 +151,7 @@
 	initial_table.entries[1].target.verdict = -forward - 1;
 
 	/* Register table */
-	ret = ipt_register_table(&packet_filter);
+	ret = ipt_register_table(&packet_filter, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
--- a/net/ipv4/netfilter/iptable_mangle.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/netfilter/iptable_mangle.c	2005-01-19 13:44:47 -08:00
@@ -29,25 +29,6 @@
 			    (1 << NF_IP_LOCAL_OUT) | \
 			    (1 << NF_IP_POST_ROUTING))
 
-/* Standard entry. */
-struct ipt_standard
-{
-	struct ipt_entry entry;
-	struct ipt_standard_target target;
-};
-
-struct ipt_error_target
-{
-	struct ipt_entry_target target;
-	char errorname[IPT_FUNCTION_MAXNAMELEN];
-};
-
-struct ipt_error
-{
-	struct ipt_entry entry;
-	struct ipt_error_target target;
-};
-
 /* Ouch - five different hooks? Maybe this should be a config option..... -- BC */
 static struct
 {
@@ -125,7 +106,6 @@
 
 static struct ipt_table packet_mangler = {
 	.name		= "mangle",
-	.table		= &initial_table.repl,
 	.valid_hooks	= MANGLE_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE,
@@ -225,7 +205,7 @@
 	int ret;
 
 	/* Register table */
-	ret = ipt_register_table(&packet_mangler);
+	ret = ipt_register_table(&packet_mangler, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
--- a/net/ipv4/netfilter/iptable_raw.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/netfilter/iptable_raw.c	2005-01-19 13:44:47 -08:00
@@ -8,25 +8,6 @@
 
 #define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
 
-/* Standard entry. */
-struct ipt_standard
-{
-	struct ipt_entry entry;
-	struct ipt_standard_target target;
-};
-
-struct ipt_error_target
-{
-	struct ipt_entry_target target;
-	char errorname[IPT_FUNCTION_MAXNAMELEN];
-};
-
-struct ipt_error
-{
-	struct ipt_entry entry;
-	struct ipt_error_target target;
-};
-
 static struct
 {
 	struct ipt_replace repl;
@@ -100,7 +81,6 @@
 
 static struct ipt_table packet_raw = { 
 	.name = "raw", 
-	.table = &initial_table.repl,
 	.valid_hooks =  RAW_VALID_HOOKS, 
 	.lock = RW_LOCK_UNLOCKED, 
 	.me = THIS_MODULE
@@ -138,7 +118,7 @@
 	int ret;
 
 	/* Register table */
-	ret = ipt_register_table(&packet_raw);
+	ret = ipt_register_table(&packet_raw, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv4/protocol.c b/net/ipv4/protocol.c
--- a/net/ipv4/protocol.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/protocol.c	2005-01-19 13:44:46 -08:00
@@ -49,7 +49,7 @@
 #include <linux/igmp.h>
 
 struct net_protocol *inet_protos[MAX_INET_PROTOS];
-static spinlock_t inet_proto_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inet_proto_lock);
 
 /*
  *	Add a protocol handler to the hash tables
diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/raw.c	2005-01-19 13:44:47 -08:00
@@ -81,7 +81,7 @@
 #include <linux/netfilter_ipv4.h>
 
 struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
-rwlock_t raw_v4_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(raw_v4_lock);
 
 static void raw_v4_hash(struct sock *sk)
 {
@@ -135,7 +135,7 @@
 
 	type = skb->h.icmph->type;
 	if (type < 32) {
-		__u32 data = raw4_sk(sk)->filter.data;
+		__u32 data = raw_sk(sk)->filter.data;
 
 		return ((1 << type) & data) != 0;
 	}
@@ -615,9 +615,10 @@
 
 static int raw_init(struct sock *sk)
 {
-	struct raw_opt *tp = raw4_sk(sk);
+	struct raw_sock *rp = raw_sk(sk);
+
 	if (inet_sk(sk)->num == IPPROTO_ICMP)
-		memset(&tp->filter, 0, sizeof(tp->filter));
+		memset(&rp->filter, 0, sizeof(rp->filter));
 	return 0;
 }
 
@@ -625,7 +626,7 @@
 {
 	if (optlen > sizeof(struct icmp_filter))
 		optlen = sizeof(struct icmp_filter);
-	if (copy_from_user(&raw4_sk(sk)->filter, optval, optlen))
+	if (copy_from_user(&raw_sk(sk)->filter, optval, optlen))
 		return -EFAULT;
 	return 0;
 }
@@ -643,7 +644,7 @@
 		len = sizeof(struct icmp_filter);
 	ret = -EFAULT;
 	if (put_user(len, optlen) ||
-	    copy_to_user(optval, &raw4_sk(sk)->filter, len))
+	    copy_to_user(optval, &raw_sk(sk)->filter, len))
 		goto out;
 	ret = 0;
 out:	return ret;
diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
--- a/net/ipv4/route.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv4/route.c	2005-01-19 13:44:48 -08:00
@@ -582,7 +582,7 @@
 	}
 }
 
-static spinlock_t rt_flush_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rt_flush_lock);
 
 void rt_cache_flush(int delay)
 {
@@ -901,7 +901,7 @@
 
 void rt_bind_peer(struct rtable *rt, int create)
 {
-	static spinlock_t rt_peer_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(rt_peer_lock);
 	struct inet_peer *peer;
 
 	peer = inet_getpeer(rt->rt_dst, create);
@@ -925,7 +925,7 @@
  */
 static void ip_select_fb_ident(struct iphdr *iph)
 {
-	static spinlock_t ip_fb_id_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(ip_fb_id_lock);
 	static u32 ip_fallback_id;
 	u32 salt;
 
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/tcp.c	2005-01-19 13:44:46 -08:00
@@ -655,7 +655,7 @@
 	while (psize > 0) {
 		struct sk_buff *skb = sk->sk_write_queue.prev;
 		struct page *page = pages[poffset / PAGE_SIZE];
-		int copy, i;
+		int copy, i, can_coalesce;
 		int offset = poffset % PAGE_SIZE;
 		int size = min_t(size_t, psize, PAGE_SIZE - offset);
 
@@ -664,7 +664,7 @@
 			if (!sk_stream_memory_free(sk))
 				goto wait_for_sndbuf;
 
-			skb = sk_stream_alloc_pskb(sk, 0, tp->mss_cache,
+			skb = sk_stream_alloc_pskb(sk, 0, 0,
 						   sk->sk_allocation);
 			if (!skb)
 				goto wait_for_memory;
@@ -677,18 +677,27 @@
 			copy = size;
 
 		i = skb_shinfo(skb)->nr_frags;
-		if (skb_can_coalesce(skb, i, page, offset)) {
+		can_coalesce = skb_can_coalesce(skb, i, page, offset);
+		if (!can_coalesce && i >= MAX_SKB_FRAGS) {
+			tcp_mark_push(tp, skb);
+			goto new_segment;
+		}
+		if (sk->sk_forward_alloc < copy &&
+		    !sk_stream_mem_schedule(sk, copy, 0))
+			goto wait_for_memory;
+		
+		if (can_coalesce) {
 			skb_shinfo(skb)->frags[i - 1].size += copy;
-		} else if (i < MAX_SKB_FRAGS) {
+		} else {
 			get_page(page);
 			skb_fill_page_desc(skb, i, page, offset, copy);
-		} else {
-			tcp_mark_push(tp, skb);
-			goto new_segment;
 		}
 
 		skb->len += copy;
 		skb->data_len += copy;
+		skb->truesize += copy;
+		sk->sk_wmem_queued += copy;
+		sk->sk_forward_alloc -= copy;
 		skb->ip_summed = CHECKSUM_HW;
 		tp->write_seq += copy;
 		TCP_SKB_CB(skb)->end_seq += copy;
diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv4/tcp_minisocks.c	2005-01-19 13:44:47 -08:00
@@ -419,7 +419,7 @@
 #define TCP_TWKILL_QUOTA	100
 
 static struct hlist_head tcp_tw_death_row[TCP_TWKILL_SLOTS];
-static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(tw_death_lock);
 static struct timer_list tcp_tw_timer = TIMER_INITIALIZER(tcp_twkill, 0, 0);
 static void twkill_work(void *);
 static DECLARE_WORK(tcp_twkill_work, twkill_work, NULL);
diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv4/udp.c	2005-01-19 13:44:46 -08:00
@@ -115,7 +115,7 @@
 DEFINE_SNMP_STAT(struct udp_mib, udp_statistics);
 
 struct hlist_head udp_hash[UDP_HTABLE_SIZE];
-rwlock_t udp_hash_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(udp_hash_lock);
 
 /* Shared by v4/v6 udp. */
 int udp_port_rover;
@@ -386,7 +386,7 @@
  */
 static void udp_flush_pending_frames(struct sock *sk)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 
 	if (up->pending) {
 		up->len = 0;
@@ -398,7 +398,7 @@
 /*
  * Push out all pending data as one UDP datagram. Socket is locked.
  */
-static int udp_push_pending_frames(struct sock *sk, struct udp_opt *up)
+static int udp_push_pending_frames(struct sock *sk, struct udp_sock *up)
 {
 	struct inet_sock *inet = inet_sk(sk);
 	struct flowi *fl = &inet->cork.fl;
@@ -483,7 +483,7 @@
 		size_t len)
 {
 	struct inet_sock *inet = inet_sk(sk);
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int ulen = len;
 	struct ipcm_cookie ipc;
 	struct rtable *rt = NULL;
@@ -672,7 +672,7 @@
 static int udp_sendpage(struct sock *sk, struct page *page, int offset,
 			size_t size, int flags)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int ret;
 
 	if (!up->pending) {
@@ -902,7 +902,7 @@
 #ifndef CONFIG_XFRM
 	return 1; 
 #else
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
   	struct udphdr *uh = skb->h.uh;
 	struct iphdr *iph;
 	int iphlen, len;
@@ -988,7 +988,7 @@
  */
 static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 
 	/*
 	 *	Charge it to the socket, dropping if the queue is full.
@@ -1223,7 +1223,7 @@
 static int udp_setsockopt(struct sock *sk, int level, int optname, 
 			  char __user *optval, int optlen)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int val;
 	int err = 0;
 
@@ -1272,7 +1272,7 @@
 static int udp_getsockopt(struct sock *sk, int level, int optname, 
 			  char __user *optval, int __user *optlen)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int val, len;
 
 	if (level != SOL_UDP)
diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/addrconf.c	2005-01-19 13:44:47 -08:00
@@ -99,9 +99,6 @@
 static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
 #endif
 
-int inet6_dev_count;
-int inet6_ifa_count;
-
 #ifdef CONFIG_IPV6_PRIVACY
 static int __ipv6_regen_rndid(struct inet6_dev *idev);
 static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); 
@@ -109,7 +106,7 @@
 
 static int desync_factor = MAX_DESYNC_FACTOR * HZ;
 static struct crypto_tfm *md5_tfm;
-static spinlock_t md5_tfm_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(md5_tfm_lock);
 #endif
 
 static int ipv6_count_addresses(struct inet6_dev *idev);
@@ -118,16 +115,16 @@
  *	Configured unicast address hash table
  */
 static struct inet6_ifaddr		*inet6_addr_lst[IN6_ADDR_HSIZE];
-static rwlock_t	addrconf_hash_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(addrconf_hash_lock);
 
 /* Protects inet6 devices */
-rwlock_t addrconf_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(addrconf_lock);
 
 static void addrconf_verify(unsigned long);
 
 static struct timer_list addr_chk_timer =
 			TIMER_INITIALIZER(addrconf_verify, 0, 0);
-static spinlock_t addrconf_verify_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(addrconf_verify_lock);
 
 static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
 static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
@@ -191,7 +188,9 @@
 };
 
 /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
+#if 0
 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+#endif
 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
 
 int ipv6_addr_type(const struct in6_addr *addr)
@@ -310,7 +309,6 @@
 		return;
 	}
 	snmp6_unregister_dev(idev);
-	inet6_dev_count--;
 	kfree(idev);
 }
 
@@ -338,7 +336,6 @@
 			kfree(ndev);
 			return NULL;
 		}
-		inet6_dev_count++;
 		/* We refer to the device */
 		dev_hold(dev);
 
@@ -475,7 +472,6 @@
 	}
 	dst_release(&ifp->rt->u.dst);
 
-	inet6_ifa_count--;
 	kfree(ifp);
 }
 
@@ -530,7 +526,6 @@
 	ifa->flags = flags | IFA_F_TENTATIVE;
 	ifa->cstamp = ifa->tstamp = jiffies;
 
-	inet6_ifa_count++;
 	ifa->idev = idev;
 	in6_dev_hold(idev);
 	/* For caller */
diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
--- a/net/ipv6/af_inet6.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/af_inet6.c	2005-01-19 13:44:47 -08:00
@@ -94,7 +94,7 @@
  * build a new socket.
  */
 static struct list_head inetsw6[SOCK_MAX];
-static spinlock_t inetsw6_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inetsw6_lock);
 
 static void inet6_sock_destruct(struct sock *sk)
 {
diff -Nru a/net/ipv6/anycast.c b/net/ipv6/anycast.c
--- a/net/ipv6/anycast.c	2005-01-19 13:44:48 -08:00
+++ b/net/ipv6/anycast.c	2005-01-19 13:44:48 -08:00
@@ -43,8 +43,10 @@
 
 #include <net/checksum.h>
 
+static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
+
 /* Big ac list lock for all the sockets */
-static rwlock_t ipv6_sk_ac_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipv6_sk_ac_lock);
 
 /* XXX ip6_addr_match() and ip6_onlink() really belong in net/core.c */
 
@@ -413,7 +415,7 @@
 	return 0;
 }
 
-int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
+static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr)
 {
 	int ret;
 	struct inet6_dev *idev = in6_dev_get(dev);
diff -Nru a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
--- a/net/ipv6/exthdrs.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv6/exthdrs.c	2005-01-19 13:44:45 -08:00
@@ -501,83 +501,6 @@
  *	for headers.
  */
 
-static u8 *ipv6_build_rthdr(struct sk_buff *skb, u8 *prev_hdr,
-		     struct ipv6_rt_hdr *opt, struct in6_addr *addr)
-{
-	struct rt0_hdr *phdr, *ihdr;
-	int hops;
-
-	ihdr = (struct rt0_hdr *) opt;
-	
-	phdr = (struct rt0_hdr *) skb_put(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
-	memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
-
-	hops = ihdr->rt_hdr.hdrlen >> 1;
-
-	if (hops > 1)
-		memcpy(phdr->addr, ihdr->addr + 1,
-		       (hops - 1) * sizeof(struct in6_addr));
-
-	ipv6_addr_copy(phdr->addr + (hops - 1), addr);
-
-	phdr->rt_hdr.nexthdr = *prev_hdr;
-	*prev_hdr = NEXTHDR_ROUTING;
-	return &phdr->rt_hdr.nexthdr;
-}
-
-static u8 *ipv6_build_exthdr(struct sk_buff *skb, u8 *prev_hdr, u8 type, struct ipv6_opt_hdr *opt)
-{
-	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_put(skb, ipv6_optlen(opt));
-
-	memcpy(h, opt, ipv6_optlen(opt));
-	h->nexthdr = *prev_hdr;
-	*prev_hdr = type;
-	return &h->nexthdr;
-}
-
-u8 *ipv6_build_nfrag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt,
-			  struct in6_addr *daddr, u32 jumbolen)
-{
-	struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb->data;
-
-	if (opt && opt->hopopt)
-		prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_HOP, opt->hopopt);
-
-	if (jumbolen) {
-		u8 *jumboopt = (u8 *)skb_put(skb, 8);
-
-		if (opt && opt->hopopt) {
-			*jumboopt++ = IPV6_TLV_PADN;
-			*jumboopt++ = 0;
-			h->hdrlen++;
-		} else {
-			h = (struct ipv6_opt_hdr *)jumboopt;
-			h->nexthdr = *prev_hdr;
-			h->hdrlen = 0;
-			jumboopt += 2;
-			*prev_hdr = NEXTHDR_HOP;
-			prev_hdr = &h->nexthdr;
-		}
-		jumboopt[0] = IPV6_TLV_JUMBO;
-		jumboopt[1] = 4;
-		*(u32*)(jumboopt+2) = htonl(jumbolen);
-	}
-	if (opt) {
-		if (opt->dst0opt)
-			prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst0opt);
-		if (opt->srcrt)
-			prev_hdr = ipv6_build_rthdr(skb, prev_hdr, opt->srcrt, daddr);
-	}
-	return prev_hdr;
-}
-
-u8 *ipv6_build_frag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt)
-{
-	if (opt->dst1opt)
-		prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst1opt);
-	return prev_hdr;
-}
-
 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
 			    struct ipv6_rt_hdr *opt,
 			    struct in6_addr **addr_p)
diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c
--- a/net/ipv6/icmp.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/icmp.c	2005-01-19 13:44:46 -08:00
@@ -211,7 +211,7 @@
 	return (*op & 0xC0) == 0x80;
 }
 
-int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
+static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len)
 {
 	struct sk_buff *skb;
 	struct icmp6hdr *icmp6h;
diff -Nru a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
--- a/net/ipv6/ip6_fib.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/ip6_fib.c	2005-01-19 13:44:47 -08:00
@@ -69,7 +69,7 @@
 	void *arg;
 };
 
-rwlock_t fib6_walker_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(fib6_walker_lock);
 
 
 #ifdef CONFIG_IPV6_SUBTREES
@@ -1205,7 +1205,7 @@
 	return 0;
 }
 
-static spinlock_t fib6_gc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(fib6_gc_lock);
 
 void fib6_run_gc(unsigned long dummy)
 {
diff -Nru a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
--- a/net/ipv6/ip6_flowlabel.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/ip6_flowlabel.c	2005-01-19 13:44:46 -08:00
@@ -54,11 +54,11 @@
 
 /* FL hash table lock: it protects only of GC */
 
-static rwlock_t ip6_fl_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ip6_fl_lock);
 
 /* Big socket sock */
 
-static rwlock_t ip6_sk_fl_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ip6_sk_fl_lock);
 
 
 static __inline__ struct ip6_flowlabel * __fl_lookup(u32 label)
diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
--- a/net/ipv6/ip6_output.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv6/ip6_output.c	2005-01-19 13:44:45 -08:00
@@ -61,7 +61,7 @@
 static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
 {
 	static u32 ipv6_fragmentation_id = 1;
-	static spinlock_t ip6_id_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(ip6_id_lock);
 
 	spin_lock_bh(&ip6_id_lock);
 	fhdr->identification = htonl(ipv6_fragmentation_id);
@@ -311,7 +311,7 @@
 	return 0;
 }
 
-int ip6_call_ra_chain(struct sk_buff *skb, int sel)
+static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
 {
 	struct ip6_ra_chain *ra;
 	struct sock *last = NULL;
@@ -745,7 +745,7 @@
 	if (sk) {
 		struct ipv6_pinfo *np = inet6_sk(sk);
 	
-		*dst = __sk_dst_check(sk, np->dst_cookie);
+		*dst = sk_dst_check(sk, np->dst_cookie);
 		if (*dst) {
 			struct rt6_info *rt = (struct rt6_info*)*dst;
 	
@@ -772,9 +772,9 @@
 			     && (np->daddr_cache == NULL ||
 				 !ipv6_addr_equal(&fl->fl6_dst, np->daddr_cache)))
 			    || (fl->oif && fl->oif != (*dst)->dev->ifindex)) {
+				dst_release(*dst);
 				*dst = NULL;
-			} else
-				dst_hold(*dst);
+			}
 		}
 	}
 
diff -Nru a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
--- a/net/ipv6/ip6_tunnel.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv6/ip6_tunnel.c	2005-01-19 13:44:45 -08:00
@@ -85,7 +85,7 @@
 static struct ip6_tnl **tnls[2] = { tnls_wc, tnls_r_l };
 
 /* lock for the tunnel lists */
-static rwlock_t ip6ip6_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ip6ip6_lock);
 
 static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t)
 {
diff -Nru a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
--- a/net/ipv6/ipv6_sockglue.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv6/ipv6_sockglue.c	2005-01-19 13:44:45 -08:00
@@ -63,7 +63,7 @@
 };
 
 struct ip6_ra_chain *ip6_ra_chain;
-rwlock_t ip6_ra_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(ip6_ra_lock);
 
 int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
 {
diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
--- a/net/ipv6/ipv6_syms.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/ipv6_syms.c	2005-01-19 13:44:47 -08:00
@@ -32,8 +32,6 @@
 EXPORT_SYMBOL(inet6_ioctl);
 EXPORT_SYMBOL(ipv6_get_saddr);
 EXPORT_SYMBOL(ipv6_chk_addr);
-EXPORT_SYMBOL(in6addr_any);
-EXPORT_SYMBOL(in6addr_loopback);
 EXPORT_SYMBOL(in6_dev_finish_destroy);
 #ifdef CONFIG_XFRM
 EXPORT_SYMBOL(xfrm6_rcv);
diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c
--- a/net/ipv6/mcast.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/mcast.c	2005-01-19 13:44:47 -08:00
@@ -121,10 +121,10 @@
 	struct in6_addr srcs[0];
 };
 
-struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
+static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
 
 /* Big mc list lock for all the sockets */
-static rwlock_t ipv6_sk_mc_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipv6_sk_mc_lock);
 
 static struct socket *igmp6_socket;
 
@@ -143,12 +143,14 @@
 static int sf_setstate(struct ifmcaddr6 *pmc);
 static void sf_markstate(struct ifmcaddr6 *pmc);
 static void ip6_mc_clear_src(struct ifmcaddr6 *pmc);
-int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
-	int sfcount, struct in6_addr *psfsrc, int delta);
-int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
-	int sfcount, struct in6_addr *psfsrc, int delta);
-int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
-	struct inet6_dev *idev);
+static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca,
+			  int sfmode, int sfcount, struct in6_addr *psfsrc,
+			  int delta);
+static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca,
+			  int sfmode, int sfcount, struct in6_addr *psfsrc,
+			  int delta);
+static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
+			    struct inet6_dev *idev);
 
 
 #define IGMP6_UNSOLICITED_IVAL	(10*HZ)
@@ -272,7 +274,7 @@
 	return -ENOENT;
 }
 
-struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex)
+static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex)
 {
 	struct net_device *dev = NULL;
 	struct inet6_dev *idev = NULL;
@@ -1723,8 +1725,9 @@
 	return rv;
 }
 
-int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
-	int sfcount, struct in6_addr *psfsrc, int delta)
+static int ip6_mc_del_src(struct inet6_dev *idev, struct in6_addr *pmca,
+			  int sfmode, int sfcount, struct in6_addr *psfsrc,
+			  int delta)
 {
 	struct ifmcaddr6 *pmc;
 	int	changerec = 0;
@@ -1847,8 +1850,9 @@
 /*
  * Add multicast source filter list to the interface list
  */
-int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode,
-	int sfcount, struct in6_addr *psfsrc, int delta)
+static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca,
+			  int sfmode, int sfcount, struct in6_addr *psfsrc,
+			  int delta)
 {
 	struct ifmcaddr6 *pmc;
 	int	isexclude;
@@ -1951,8 +1955,8 @@
 	spin_unlock_bh(&ma->mca_lock);
 }
 
-int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
-	struct inet6_dev *idev)
+static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
+			    struct inet6_dev *idev)
 {
 	int err;
 
diff -Nru a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
--- a/net/ipv6/netfilter/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/netfilter/Kconfig	2005-01-19 13:44:47 -08:00
@@ -237,7 +237,6 @@
 	
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
-	  help
 
 endmenu
 
diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
--- a/net/ipv6/netfilter/ip6_queue.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/netfilter/ip6_queue.c	2005-01-19 13:44:46 -08:00
@@ -60,7 +60,7 @@
 
 static unsigned char copy_mode = IPQ_COPY_NONE;
 static unsigned int queue_maxlen = IPQ_QMAX_DEFAULT;
-static rwlock_t queue_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(queue_lock);
 static int peer_pid;
 static unsigned int copy_range;
 static unsigned int queue_total;
diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
--- a/net/ipv6/netfilter/ip6_tables.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/netfilter/ip6_tables.c	2005-01-19 13:44:47 -08:00
@@ -234,7 +234,7 @@
 			 * we will change the return 0 to 1*/
 			if ((currenthdr == IPPROTO_NONE) || 
 				(currenthdr == IPPROTO_ESP))
-				return 0;
+				break;
 
 			hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
 			BUG_ON(hp == NULL);
@@ -366,10 +366,6 @@
 	void *table_base;
 	struct ip6t_entry *e, *back;
 
-	/* FIXME: Push down to extensions --RR */
-	if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
-		return NF_DROP;
-
 	/* Initialization */
 	indev = in ? in->name : nulldevname;
 	outdev = out ? out->name : nulldevname;
@@ -1373,7 +1369,7 @@
 			       sizeof(info.underflow));
 			info.num_entries = t->private->number;
 			info.size = t->private->size;
-			strcpy(info.name, name);
+			memcpy(info.name, name, sizeof(info.name));
 
 			if (copy_to_user(user, &info, *len) != 0)
 				ret = -EFAULT;
@@ -1464,7 +1460,8 @@
 	up(&ip6t_mutex);
 }
 
-int ip6t_register_table(struct ip6t_table *table)
+int ip6t_register_table(struct ip6t_table *table,
+			const struct ip6t_replace *repl)
 {
 	int ret;
 	struct ip6t_table_info *newinfo;
@@ -1472,17 +1469,17 @@
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
 	newinfo = vmalloc(sizeof(struct ip6t_table_info)
-			  + SMP_ALIGN(table->table->size) * NR_CPUS);
+			  + SMP_ALIGN(repl->size) * NR_CPUS);
 	if (!newinfo)
 		return -ENOMEM;
 
-	memcpy(newinfo->entries, table->table->entries, table->table->size);
+	memcpy(newinfo->entries, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, table->table->size,
-			      table->table->num_entries,
-			      table->table->hook_entry,
-			      table->table->underflow);
+			      newinfo, repl->size,
+			      repl->num_entries,
+			      repl->hook_entry,
+			      repl->underflow);
 	if (ret != 0) {
 		vfree(newinfo);
 		return ret;
diff -Nru a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
--- a/net/ipv6/netfilter/ip6t_LOG.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/netfilter/ip6t_LOG.c	2005-01-19 13:44:46 -08:00
@@ -41,7 +41,7 @@
 #endif
 
 /* Use lock to serialize, so printks don't overlap */
-static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(log_lock);
 
 /* One level of recursion won't kill us */
 static void dump_packet(const struct ip6t_log_info *info,
@@ -346,6 +346,14 @@
 	/* Max length: 10 "PROTO=255 " */
 	default:
 		printk("PROTO=%u ", currenthdr);
+	}
+
+	/* Max length: 15 "UID=4294967295 " */
+	if ((info->logflags & IP6T_LOG_UID) && recurse && skb->sk) {
+		read_lock_bh(&skb->sk->sk_callback_lock);
+		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
+			printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
+		read_unlock_bh(&skb->sk->sk_callback_lock);
 	}
 }
 
diff -Nru a/net/ipv6/netfilter/ip6t_limit.c b/net/ipv6/netfilter/ip6t_limit.c
--- a/net/ipv6/netfilter/ip6t_limit.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/netfilter/ip6t_limit.c	2005-01-19 13:44:46 -08:00
@@ -29,7 +29,7 @@
  * see net/sched/sch_tbf.c in the linux source tree
  */
 
-static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(limit_lock);
 
 /* Rusty: This is my (non-mathematically-inclined) understanding of
    this algorithm.  The `average rate' in jiffies becomes your initial
diff -Nru a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
--- a/net/ipv6/netfilter/ip6table_filter.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv6/netfilter/ip6table_filter.c	2005-01-19 13:44:45 -08:00
@@ -94,7 +94,6 @@
 
 static struct ip6t_table packet_filter = {
 	.name		= "filter",
-	.table		= &initial_table.repl,
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE,
@@ -172,7 +171,7 @@
 	initial_table.entries[1].target.verdict = -forward - 1;
 
 	/* Register table */
-	ret = ip6t_register_table(&packet_filter);
+	ret = ip6t_register_table(&packet_filter, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
--- a/net/ipv6/netfilter/ip6table_mangle.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/netfilter/ip6table_mangle.c	2005-01-19 13:44:46 -08:00
@@ -124,7 +124,6 @@
 
 static struct ip6t_table packet_mangler = {
 	.name		= "mangle",
-	.table		= &initial_table.repl,
 	.valid_hooks	= MANGLE_VALID_HOOKS,
 	.lock		= RW_LOCK_UNLOCKED,
 	.me		= THIS_MODULE,
@@ -165,10 +164,6 @@
 	}
 #endif
 
-	/* FIXME: Push down to extensions --RR */
-	if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
-		return NF_DROP;
-
 	/* save source/dest address, nfmark, hoplimit, flowlabel, priority,  */
 	memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr));
 	memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr));
@@ -237,7 +232,7 @@
 	int ret;
 
 	/* Register table */
-	ret = ip6t_register_table(&packet_mangler);
+	ret = ip6t_register_table(&packet_mangler, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
--- a/net/ipv6/netfilter/ip6table_raw.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/netfilter/ip6table_raw.c	2005-01-19 13:44:47 -08:00
@@ -108,7 +108,6 @@
 
 static struct ip6t_table packet_raw = { 
 	.name = "raw", 
-	.table = &initial_table.repl,
 	.valid_hooks = RAW_VALID_HOOKS, 
 	.lock = RW_LOCK_UNLOCKED, 
 	.me = THIS_MODULE
@@ -145,7 +144,7 @@
 	int ret;
 
 	/* Register table */
-	ret = ip6t_register_table(&packet_raw);
+	ret = ip6t_register_table(&packet_raw, &initial_table.repl);
 	if (ret < 0)
 		return ret;
 
diff -Nru a/net/ipv6/protocol.c b/net/ipv6/protocol.c
--- a/net/ipv6/protocol.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/protocol.c	2005-01-19 13:44:46 -08:00
@@ -40,7 +40,7 @@
 #include <net/protocol.h>
 
 struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
-static spinlock_t inet6_proto_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(inet6_proto_lock);
 
 
 int inet6_add_protocol(struct inet6_protocol *prot, unsigned char protocol)
diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/raw.c	2005-01-19 13:44:46 -08:00
@@ -56,7 +56,7 @@
 #include <linux/seq_file.h>
 
 struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
-rwlock_t raw_v6_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(raw_v6_lock);
 
 static void raw_v6_hash(struct sock *sk)
 {
diff -Nru a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
--- a/net/ipv6/reassembly.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipv6/reassembly.c	2005-01-19 13:44:46 -08:00
@@ -103,7 +103,7 @@
 #define IP6Q_HASHSZ	64
 
 static struct frag_queue *ip6_frag_hash[IP6Q_HASHSZ];
-static rwlock_t ip6_frag_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ip6_frag_lock);
 static u32 ip6_frag_hash_rnd;
 static LIST_HEAD(ip6_frag_lru_list);
 int ip6_frag_nqueues = 0;
diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c
--- a/net/ipv6/route.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/route.c	2005-01-19 13:44:47 -08:00
@@ -133,7 +133,7 @@
 
 /* Protects all the ip6 fib */
 
-rwlock_t rt6_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(rt6_lock);
 
 
 /* allocate dst with ip6_dst_ops */
@@ -208,8 +208,8 @@
 /*
  *	pointer to the last default router chosen. BH is disabled locally.
  */
-struct rt6_info *rt6_dflt_pointer;
-spinlock_t rt6_dflt_lock = SPIN_LOCK_UNLOCKED;
+static struct rt6_info *rt6_dflt_pointer;
+static DEFINE_SPINLOCK(rt6_dflt_lock);
 
 void rt6_reset_dflt_pointer(struct rt6_info *rt)
 {
diff -Nru a/net/ipv6/sit.c b/net/ipv6/sit.c
--- a/net/ipv6/sit.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/sit.c	2005-01-19 13:44:47 -08:00
@@ -73,7 +73,7 @@
 static struct ip_tunnel *tunnels_wc[1];
 static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l };
 
-static rwlock_t ipip6_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipip6_lock);
 
 static struct ip_tunnel * ipip6_tunnel_lookup(u32 remote, u32 local)
 {
@@ -135,10 +135,10 @@
 {
 	struct ip_tunnel **tp = ipip6_bucket(t);
 
-	write_lock_bh(&ipip6_lock);
 	t->next = *tp;
-	write_unlock_bh(&ipip6_lock);
+	write_lock_bh(&ipip6_lock);
 	*tp = t;
+	write_unlock_bh(&ipip6_lock);
 }
 
 static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create)
diff -Nru a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
--- a/net/ipv6/sysctl_net_ipv6.c	2005-01-19 13:44:45 -08:00
+++ b/net/ipv6/sysctl_net_ipv6.c	2005-01-19 13:44:45 -08:00
@@ -19,7 +19,7 @@
 
 #ifdef CONFIG_SYSCTL
 
-ctl_table ipv6_table[] = {
+static ctl_table ipv6_table[] = {
 	{
 		.ctl_name	= NET_IPV6_ROUTE,
 		.procname	= "route",
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/udp.c	2005-01-19 13:44:47 -08:00
@@ -549,7 +549,7 @@
  */
 static void udp_v6_flush_pending_frames(struct sock *sk)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 
 	if (up->pending) {
 		up->len = 0;
@@ -562,7 +562,7 @@
  *	Sending
  */
 
-static int udp_v6_push_pending_frames(struct sock *sk, struct udp_opt *up)
+static int udp_v6_push_pending_frames(struct sock *sk, struct udp_sock *up)
 {
 	struct sk_buff *skb;
 	struct udphdr *uh;
@@ -623,7 +623,7 @@
 		  struct msghdr *msg, size_t len)
 {
 	struct ipv6_txoptions opt_space;
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
@@ -878,7 +878,7 @@
 static int udpv6_setsockopt(struct sock *sk, int level, int optname, 
 			  char __user *optval, int optlen)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int val;
 	int err = 0;
 
@@ -925,7 +925,7 @@
 static int udpv6_getsockopt(struct sock *sk, int level, int optname, 
 			  char __user *optval, int __user *optlen)
 {
-	struct udp_opt *up = udp_sk(sk);
+	struct udp_sock *up = udp_sk(sk);
 	int val, len;
 
 	if (level != SOL_UDP)
diff -Nru a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
--- a/net/ipv6/xfrm6_tunnel.c	2005-01-19 13:44:47 -08:00
+++ b/net/ipv6/xfrm6_tunnel.c	2005-01-19 13:44:47 -08:00
@@ -72,7 +72,7 @@
 # define XFRM6_TUNNEL_SPI_MAGIC 0xdeadbeef
 #endif
 
-static rwlock_t xfrm6_tunnel_spi_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock);
 
 static u32 xfrm6_tunnel_spi;
 
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipx/af_ipx.c	2005-01-19 13:44:46 -08:00
@@ -78,7 +78,7 @@
 static struct proto_ops ipx_dgram_ops;
 
 LIST_HEAD(ipx_interfaces);
-spinlock_t ipx_interfaces_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(ipx_interfaces_lock);
 
 struct ipx_interface *ipx_primary_net;
 struct ipx_interface *ipx_internal_net;
diff -Nru a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c
--- a/net/ipx/ipx_route.c	2005-01-19 13:44:46 -08:00
+++ b/net/ipx/ipx_route.c	2005-01-19 13:44:46 -08:00
@@ -16,7 +16,7 @@
 #include <net/sock.h>
 
 LIST_HEAD(ipx_routes);
-rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(ipx_routes_lock);
 
 extern struct ipx_interface *ipx_internal_net;
 
diff -Nru a/net/irda/irnet/Kconfig b/net/irda/irnet/Kconfig
--- a/net/irda/irnet/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/net/irda/irnet/Kconfig	2005-01-19 13:44:47 -08:00
@@ -7,7 +7,7 @@
 	  called irnet.  IrNET is a PPP driver, so you will also need a
 	  working PPP subsystem (driver, daemon and config)...
 
-	  IrNET is an alternate way to tranfer TCP/IP traffic over IrDA.  It
+	  IrNET is an alternate way to transfer TCP/IP traffic over IrDA.  It
 	  uses synchronous PPP over a set of point to point IrDA sockets.  You
 	  can use it between Linux machine or with W2k.
 
diff -Nru a/net/key/af_key.c b/net/key/af_key.c
--- a/net/key/af_key.c	2005-01-19 13:44:48 -08:00
+++ b/net/key/af_key.c	2005-01-19 13:44:48 -08:00
@@ -37,7 +37,7 @@
 /* List of all pfkey sockets. */
 static HLIST_HEAD(pfkey_table);
 static DECLARE_WAIT_QUEUE_HEAD(pfkey_table_wait);
-static rwlock_t pfkey_table_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(pfkey_table_lock);
 static atomic_t pfkey_table_users = ATOMIC_INIT(0);
 
 static atomic_t pfkey_socks_nr = ATOMIC_INIT(0);
@@ -2344,7 +2344,7 @@
 {
 	u32 res;
 	static u32 acqseq;
-	static spinlock_t acqseq_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(acqseq_lock);
 
 	spin_lock_bh(&acqseq_lock);
 	res = (++acqseq ? : ++acqseq);
diff -Nru a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
--- a/net/lapb/lapb_iface.c	2005-01-19 13:44:46 -08:00
+++ b/net/lapb/lapb_iface.c	2005-01-19 13:44:46 -08:00
@@ -40,7 +40,7 @@
 #include <net/lapb.h>
 
 static struct list_head lapb_list = LIST_HEAD_INIT(lapb_list);
-static rwlock_t lapb_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(lapb_list_lock);
 
 /*
  *	Free an allocated lapb control block. 
diff -Nru a/net/llc/llc_core.c b/net/llc/llc_core.c
--- a/net/llc/llc_core.c	2005-01-19 13:44:45 -08:00
+++ b/net/llc/llc_core.c	2005-01-19 13:44:45 -08:00
@@ -22,7 +22,7 @@
 #include <net/llc.h>
 
 LIST_HEAD(llc_sap_list);
-rwlock_t llc_sap_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(llc_sap_list_lock);
 
 unsigned char llc_station_mac_sa[ETH_ALEN];
 
diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c	2005-01-19 13:44:46 -08:00
+++ b/net/netlink/af_netlink.c	2005-01-19 13:44:46 -08:00
@@ -98,14 +98,10 @@
 static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
 static unsigned int nl_nonroot[MAX_LINKS];
 
-#ifdef NL_EMULATE_DEV
-static struct socket *netlink_kernel[MAX_LINKS];
-#endif
-
 static int netlink_dump(struct sock *sk);
 static void netlink_destroy_callback(struct netlink_callback *cb);
 
-static rwlock_t nl_table_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(nl_table_lock);
 static atomic_t nl_table_users = ATOMIC_INIT(0);
 
 static struct notifier_block *netlink_chain;
@@ -1202,37 +1198,6 @@
 }
 
 
-#ifdef NL_EMULATE_DEV
-
-static rwlock_t nl_emu_lock = RW_LOCK_UNLOCKED;
-
-/*
- *	Backward compatibility.
- */	
- 
-int netlink_post(int unit, struct sk_buff *skb)
-{
-	struct socket *sock;
-
-	read_lock(&nl_emu_lock);
-	sock = netlink_kernel[unit];
-	if (sock) {
-		struct sock *sk = sock->sk;
-		memset(skb->cb, 0, sizeof(skb->cb));
-		sock_hold(sk);
-		read_unlock(&nl_emu_lock);
-
-		netlink_broadcast(sk, skb, 0, ~0, GFP_ATOMIC);
-
-		sock_put(sk);
-		return 0;
-	}
-	read_unlock(&nl_emu_lock);
-	return -EUNATCH;
-}
-
-#endif
-
 #ifdef CONFIG_PROC_FS
 struct nl_seq_iter {
 	int link;
@@ -1497,6 +1462,3 @@
 EXPORT_SYMBOL(netlink_unicast);
 EXPORT_SYMBOL(netlink_unregister_notifier);
 
-#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
-EXPORT_SYMBOL(netlink_post);
-#endif
diff -Nru a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
--- a/net/netrom/af_netrom.c	2005-01-19 13:44:46 -08:00
+++ b/net/netrom/af_netrom.c	2005-01-19 13:44:46 -08:00
@@ -60,7 +60,7 @@
 static unsigned short circuit = 0x101;
 
 static HLIST_HEAD(nr_list);
-static spinlock_t nr_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nr_list_lock);
 
 static struct proto_ops nr_proto_ops;
 void nr_init_timers(struct sock *sk);
diff -Nru a/net/netrom/nr_route.c b/net/netrom/nr_route.c
--- a/net/netrom/nr_route.c	2005-01-19 13:44:48 -08:00
+++ b/net/netrom/nr_route.c	2005-01-19 13:44:48 -08:00
@@ -41,9 +41,9 @@
 static unsigned int nr_neigh_no = 1;
 
 static HLIST_HEAD(nr_node_list);
-static spinlock_t nr_node_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nr_node_list_lock);
 static HLIST_HEAD(nr_neigh_list);
-static spinlock_t nr_neigh_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nr_neigh_list_lock);
 
 static struct nr_node *nr_node_get(ax25_address *callsign)
 {
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c	2005-01-19 13:44:47 -08:00
+++ b/net/packet/af_packet.c	2005-01-19 13:44:47 -08:00
@@ -146,7 +146,7 @@
 
 /* List of all packet sockets. */
 static HLIST_HEAD(packet_sklist);
-static rwlock_t packet_sklist_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(packet_sklist_lock);
 
 static atomic_t packet_socks_nr;
 
diff -Nru a/net/rose/af_rose.c b/net/rose/af_rose.c
--- a/net/rose/af_rose.c	2005-01-19 13:44:46 -08:00
+++ b/net/rose/af_rose.c	2005-01-19 13:44:46 -08:00
@@ -59,7 +59,7 @@
 int sysctl_rose_window_size             = ROSE_DEFAULT_WINDOW_SIZE;
 
 static HLIST_HEAD(rose_list);
-static spinlock_t rose_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rose_list_lock);
 
 static struct proto_ops rose_proto_ops;
 
diff -Nru a/net/rose/rose_route.c b/net/rose/rose_route.c
--- a/net/rose/rose_route.c	2005-01-19 13:44:48 -08:00
+++ b/net/rose/rose_route.c	2005-01-19 13:44:48 -08:00
@@ -40,11 +40,11 @@
 static unsigned int rose_neigh_no = 1;
 
 static struct rose_node  *rose_node_list;
-static spinlock_t rose_node_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rose_node_list_lock);
 static struct rose_neigh *rose_neigh_list;
-static spinlock_t rose_neigh_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rose_neigh_list_lock);
 static struct rose_route *rose_route_list;
-static spinlock_t rose_route_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rose_route_list_lock);
 
 struct rose_neigh *rose_loopback_neigh;
 
diff -Nru a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c
--- a/net/rxrpc/krxiod.c	2005-01-19 13:44:45 -08:00
+++ b/net/rxrpc/krxiod.c	2005-01-19 13:44:45 -08:00
@@ -25,10 +25,10 @@
 static atomic_t rxrpc_krxiod_qcount = ATOMIC_INIT(0);
 
 static LIST_HEAD(rxrpc_krxiod_transportq);
-static spinlock_t rxrpc_krxiod_transportq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rxrpc_krxiod_transportq_lock);
 
 static LIST_HEAD(rxrpc_krxiod_callq);
-static spinlock_t rxrpc_krxiod_callq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rxrpc_krxiod_callq_lock);
 
 static volatile int rxrpc_krxiod_die;
 
diff -Nru a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c
--- a/net/rxrpc/krxsecd.c	2005-01-19 13:44:46 -08:00
+++ b/net/rxrpc/krxsecd.c	2005-01-19 13:44:46 -08:00
@@ -39,7 +39,7 @@
 /* queue of unprocessed inbound messages with seqno #1 and
  * RXRPC_CLIENT_INITIATED flag set */
 static LIST_HEAD(rxrpc_krxsecd_initmsgq);
-static spinlock_t rxrpc_krxsecd_initmsgq_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rxrpc_krxsecd_initmsgq_lock);
 
 static void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg);
 
diff -Nru a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
--- a/net/rxrpc/krxtimod.c	2005-01-19 13:44:46 -08:00
+++ b/net/rxrpc/krxtimod.c	2005-01-19 13:44:46 -08:00
@@ -24,7 +24,7 @@
 static int krxtimod_die;
 
 static LIST_HEAD(krxtimod_list);
-static spinlock_t krxtimod_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(krxtimod_lock);
 
 static int krxtimod(void *arg);
 
diff -Nru a/net/rxrpc/transport.c b/net/rxrpc/transport.c
--- a/net/rxrpc/transport.c	2005-01-19 13:44:47 -08:00
+++ b/net/rxrpc/transport.c	2005-01-19 13:44:47 -08:00
@@ -39,7 +39,7 @@
 	struct sockaddr_in		icmp_src;	/* ICMP packet source address */
 };
 
-static spinlock_t rxrpc_transports_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rxrpc_transports_lock);
 static struct list_head rxrpc_transports = LIST_HEAD_INIT(rxrpc_transports);
 
 __RXACCT_DECL(atomic_t rxrpc_transport_count);
diff -Nru a/net/sched/Kconfig b/net/sched/Kconfig
--- a/net/sched/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/net/sched/Kconfig	2005-01-19 13:44:47 -08:00
@@ -381,7 +381,6 @@
 	---help---
 	This option requires you have a new iproute2. It enables
 	tc extensions which can be used with tc classifiers.
-	Only the u32 and fw classifiers are supported at the moment.
 	  You MUST NOT turn this on if you dont have an update iproute2.
 
 config NET_ACT_POLICE
@@ -392,13 +391,6 @@
 	below to select a policer.
 	  You MUST NOT turn this on if you dont have an update iproute2.
 
-config NET_CLS_POLICE
-	bool "Traffic policing (needed for in/egress)"
-	depends on NET_CLS && NET_QOS && NET_ACT_POLICE!=y && NET_ACT_POLICE!=m
-	help
-	  Say Y to support traffic policing (bandwidth limits).  Needed for
-	  ingress and egress rate limiting.
-
 config NET_ACT_GACT
         tristate "generic Actions"
         depends on NET_CLS_ACT
@@ -432,3 +424,11 @@
         ---help---
         requires new iproute2
         This allows for packets to be generically edited
+
+config NET_CLS_POLICE
+	bool "Traffic policing (needed for in/egress)"
+	depends on NET_CLS && NET_QOS && NET_CLS_ACT!=y
+	help
+	  Say Y to support traffic policing (bandwidth limits).  Needed for
+	  ingress and egress rate limiting.
+
diff -Nru a/net/sched/act_api.c b/net/sched/act_api.c
--- a/net/sched/act_api.c	2005-01-19 13:44:48 -08:00
+++ b/net/sched/act_api.c	2005-01-19 13:44:48 -08:00
@@ -35,36 +35,33 @@
 #include <net/act_api.h>
 
 #if 1 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
+#define DPRINTK(format, args...) printk(KERN_DEBUG format, ##args)
 #else
-#define DPRINTK(format,args...)
+#define DPRINTK(format, args...)
 #endif
 #if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
+#define D2PRINTK(format, args...) printk(KERN_DEBUG format, ##args)
 #else
-#define D2PRINTK(format,args...)
+#define D2PRINTK(format, args...)
 #endif
 
 static struct tc_action_ops *act_base = NULL;
-static rwlock_t act_mod_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(act_mod_lock);
 
 int tcf_register_action(struct tc_action_ops *act)
 {
 	struct tc_action_ops *a, **ap;
 
 	write_lock(&act_mod_lock);
-	for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) {
+	for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) {
 		if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) {
 			write_unlock(&act_mod_lock);
 			return -EEXIST;
 		}
 	}
-
-        act->next = NULL;
+	act->next = NULL;
 	*ap = act;
-
 	write_unlock(&act_mod_lock);
-
 	return 0;
 }
 
@@ -74,10 +71,9 @@
 	int err = -ENOENT;
 
 	write_lock(&act_mod_lock);
-	for (ap = &act_base; (a=*ap)!=NULL; ap = &a->next) 
-		if(a == act)
+	for (ap = &act_base; (a = *ap) != NULL; ap = &a->next)
+		if (a == act)
 			break;
-
 	if (a) {
 		*ap = a->next;
 		a->next = NULL;
@@ -90,47 +86,42 @@
 /* lookup by name */
 static struct tc_action_ops *tc_lookup_action_n(char *kind)
 {
-
 	struct tc_action_ops *a = NULL;
 
 	if (kind) {
 		read_lock(&act_mod_lock);
 		for (a = act_base; a; a = a->next) {
-			if (strcmp(kind,a->kind) == 0) {
+			if (strcmp(kind, a->kind) == 0) {
 				if (!try_module_get(a->owner)) {
 					read_unlock(&act_mod_lock);
 					return NULL;
-				} 
+				}
 				break;
 			}
 		}
 		read_unlock(&act_mod_lock);
 	}
-
 	return a;
 }
 
 /* lookup by rtattr */
 static struct tc_action_ops *tc_lookup_action(struct rtattr *kind)
 {
-
 	struct tc_action_ops *a = NULL;
 
 	if (kind) {
 		read_lock(&act_mod_lock);
 		for (a = act_base; a; a = a->next) {
-
-			if (strcmp((char*)RTA_DATA(kind),a->kind) == 0){
+			if (rtattr_strcmp(kind, a->kind) == 0) {
 				if (!try_module_get(a->owner)) {
 					read_unlock(&act_mod_lock);
 					return NULL;
-				} 
+				}
 				break;
 			}
 		}
 		read_unlock(&act_mod_lock);
 	}
-
 	return a;
 }
 
@@ -147,55 +138,52 @@
 				if (!try_module_get(a->owner)) {
 					read_unlock(&act_mod_lock);
 					return NULL;
-				} 
+				}
 				break;
 			}
 		}
 		read_unlock(&act_mod_lock);
 	}
-
 	return a;
 }
 #endif
 
-int tcf_action_exec(struct sk_buff *skb,struct tc_action *act, struct tcf_result *res)
+int tcf_action_exec(struct sk_buff *skb, struct tc_action *act,
+                    struct tcf_result *res)
 {
-
 	struct tc_action *a;
-	int ret = -1; 
+	int ret = -1;
 
 	if (skb->tc_verd & TC_NCLS) {
 		skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
-		D2PRINTK("(%p)tcf_action_exec: cleared TC_NCLS in %s out %s\n",skb,skb->input_dev?skb->input_dev->name:"xxx",skb->dev->name);
+		D2PRINTK("(%p)tcf_action_exec: cleared TC_NCLS in %s out %s\n",
+		         skb, skb->input_dev ? skb->input_dev->name : "xxx",
+		         skb->dev->name);
 		ret = TC_ACT_OK;
 		goto exec_done;
 	}
 	while ((a = act) != NULL) {
 repeat:
 		if (a->ops && a->ops->act) {
-			ret = a->ops->act(&skb,a);
-				if (TC_MUNGED & skb->tc_verd) {
-					/* copied already, allow trampling */
-					skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
-					skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
-				}
-
+			ret = a->ops->act(&skb, a);
+			if (TC_MUNGED & skb->tc_verd) {
+				/* copied already, allow trampling */
+				skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
+				skb->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
+			}
 			if (ret != TC_ACT_PIPE)
 				goto exec_done;
 			if (ret == TC_ACT_REPEAT)
 				goto repeat;	/* we need a ttl - JHS */
-
 		}
 		act = a->next;
 	}
-
 exec_done:
 	if (skb->tc_classid > 0) {
 		res->classid = skb->tc_classid;
 		res->class = 0;
 		skb->tc_classid = 0;
 	}
-
 	return ret;
 }
 
@@ -203,56 +191,44 @@
 {
 	struct tc_action *a;
 
-	for (a = act; act; a = act) {
-		if (a && a->ops && a->ops->cleanup) {
-			DPRINTK("tcf_action_destroy destroying %p next %p\n", a,a->next?a->next:NULL);
-			act = act->next;
-			if (ACT_P_DELETED == a->ops->cleanup(a, bind)) {
+	for (a = act; a; a = act) {
+		if (a->ops && a->ops->cleanup) {
+			DPRINTK("tcf_action_destroy destroying %p next %p\n",
+			        a, a->next);
+			if (a->ops->cleanup(a, bind) == ACT_P_DELETED)
 				module_put(a->ops->owner);
-			}
-			
-			a->ops = NULL;  
+			act = act->next;
 			kfree(a);
 		} else { /*FIXME: Remove later - catch insertion bugs*/
-			printk("tcf_action_destroy: BUG? destroying NULL ops \n");
-			if (a) {
-				act = act->next;
-				kfree(a);
-			} else {
-				printk("tcf_action_destroy: BUG? destroying NULL action! \n");
-				break;
-			}
+			printk("tcf_action_destroy: BUG? destroying NULL ops\n");
+			act = act->next;
+			kfree(a);
 		}
 	}
 }
 
-int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+int
+tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	int err = -EINVAL;
 
-
-	if ( (NULL == a) || (NULL == a->ops)
-	   || (NULL == a->ops->dump) )
+	if (a->ops == NULL || a->ops->dump == NULL)
 		return err;
 	return a->ops->dump(skb, a, bind, ref);
-
 }
 
-
-int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+int
+tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	int err = -EINVAL;
-	unsigned char    *b = skb->tail;
+	unsigned char *b = skb->tail;
 	struct rtattr *r;
 
-
-	if ( (NULL == a) || (NULL == a->ops)
-	   || (NULL == a->ops->dump) || (NULL == a->ops->kind))
+	if (a->ops == NULL || a->ops->dump == NULL)
 		return err;
 
-
 	RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
-	if (tcf_action_copy_stats(skb,a))
+	if (tcf_action_copy_stats(skb, a))
 		goto rtattr_failure;
 	r = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
@@ -261,18 +237,17 @@
 		return err;
 	}
 
-
 rtattr_failure:
 	skb_trim(skb, b - skb->data);
 	return -1;
-
 }
 
-int tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
+int
+tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
 {
 	struct tc_action *a;
 	int err = -EINVAL;
-	unsigned char    *b = skb->tail;
+	unsigned char *b = skb->tail;
 	struct rtattr *r ;
 
 	while ((a = act) != NULL) {
@@ -280,9 +255,8 @@
 		act = a->next;
 		RTA_PUT(skb, a->order, 0, NULL);
 		err = tcf_action_dump_1(skb, a, bind, ref);
-		if (0 > err) 
+		if (err < 0)
 			goto rtattr_failure;
-
 		r->rta_len = skb->tail - (u8*)r;
 	}
 
@@ -291,7 +265,6 @@
 rtattr_failure:
 	skb_trim(skb, b - skb->data);
 	return -err;
-	
 }
 
 struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
@@ -299,76 +272,70 @@
 {
 	struct tc_action *a;
 	struct tc_action_ops *a_o;
-	char act_name[4 + IFNAMSIZ + 1];
+	char act_name[IFNAMSIZ];
 	struct rtattr *tb[TCA_ACT_MAX+1];
-	struct rtattr *kind = NULL;
+	struct rtattr *kind;
 
 	*err = -EINVAL;
 
-	if (NULL == name) {
-		if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0)
+	if (name == NULL) {
+		if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
 			goto err_out;
 		kind = tb[TCA_ACT_KIND-1];
-		if (NULL != kind) {
-			sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-			if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-				printk(" Action %s bad\n", (char*)RTA_DATA(kind));
-				goto err_out;
-			}
-
-		} else {
-			printk("Action bad kind\n");
+		if (kind == NULL)
+			goto err_out;
+		if (rtattr_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
 			goto err_out;
-		}
-		a_o = tc_lookup_action(kind);
 	} else {
-		sprintf(act_name, "%s", name);
-		DPRINTK("tcf_action_init_1: finding  %s\n",act_name);
-		a_o = tc_lookup_action_n(name);
+		if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
+			goto err_out;
 	}
+
+	a_o = tc_lookup_action_n(act_name);
+	if (a_o == NULL) {
 #ifdef CONFIG_KMOD
-	if (NULL == a_o) {
-		DPRINTK("tcf_action_init_1: trying to load module %s\n",act_name);
-		request_module (act_name);
+		rtnl_unlock();
+		request_module(act_name);
+		rtnl_lock();
+
 		a_o = tc_lookup_action_n(act_name);
-	}
 
+		/* We dropped the RTNL semaphore in order to
+		 * perform the module load.  So, even if we
+		 * succeeded in loading the module we have to
+		 * tell the caller to replay the request.  We
+		 * indicate this using -EAGAIN.
+		 */
+		if (a_o != NULL) {
+			*err = -EAGAIN;
+			goto err_mod;
+		}
 #endif
-	if (NULL == a_o) {
-		printk("failed to find %s\n",act_name);
 		goto err_out;
 	}
 
+	*err = -ENOMEM;
 	a = kmalloc(sizeof(*a), GFP_KERNEL);
-	if (a == NULL) {
-		*err = -ENOMEM;
+	if (a == NULL)
 		goto err_mod;
-	}
 	memset(a, 0, sizeof(*a));
 
 	/* backward compatibility for policer */
-	if (NULL == name) {
+	if (name == NULL)
 		*err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind);
-		if (*err < 0) {
-			*err = -EINVAL;
-			goto err_free;
-		}
-	} else {
+	else
 		*err = a_o->init(rta, est, a, ovr, bind);
-		if (*err < 0) {
-			*err = -EINVAL;
-			goto err_free;
-		}
-	}
+	if (*err < 0)
+		goto err_free;
 
 	/* module count goes up only when brand new policy is created
 	   if it exists and is only bound to in a_o->init() then
-           ACT_P_CREATED is not returned (a zero is).
-        */
+	   ACT_P_CREATED is not returned (a zero is).
+	*/
 	if (*err != ACT_P_CREATED)
 		module_put(a_o->owner);
 	a->ops = a_o;
-	DPRINTK("tcf_action_init_1: successfull %s \n",act_name);
+	DPRINTK("tcf_action_init_1: successfull %s\n", act_name);
 
 	*err = 0;
 	return a;
@@ -385,51 +352,41 @@
                                   char *name, int ovr, int bind, int *err)
 {
 	struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
-	struct tc_action *a = NULL, *act, *act_prev = NULL;
+	struct tc_action *head = NULL, *act, *act_prev = NULL;
 	int i;
 
-	if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta),
-	                 RTA_PAYLOAD(rta)) < 0) {
+	if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) {
 		*err = -EINVAL;
-		return a;
+		return head;
 	}
 
-	for (i=0; i < TCA_ACT_MAX_PRIO; i++) {
-		if (tb[i]) {
-			act = tcf_action_init_1(tb[i], est, name, ovr, bind, err);
-			if (act == NULL) {
-				printk("Error processing action order %d\n", i);
-				goto bad_ret;
-			}
-
-			act->order = i+1;
-			if (a == NULL)
-				a = act;
-			else
-				act_prev->next = act;
-			act_prev = act;
-		}
-
-	}
-	return a;
-
-bad_ret:
-	if (a != NULL)
-		tcf_action_destroy(a, bind);
+	for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) {
+		act = tcf_action_init_1(tb[i], est, name, ovr, bind, err);
+		if (act == NULL)
+			goto err;
+		act->order = i+1;
+
+		if (head == NULL)
+			head = act;
+		else
+			act_prev->next = act;
+		act_prev = act;
+	}
+	return head;
+
+err:
+	if (head != NULL)
+		tcf_action_destroy(head, bind);
 	return NULL;
 }
 
-int tcf_action_copy_stats (struct sk_buff *skb,struct tc_action *a)
+int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a)
 {
 	int err;
 	struct gnet_dump d;
 	struct tcf_act_hdr *h = a->priv;
 	
-#ifdef CONFIG_KMOD
-	/* place holder */
-#endif
-
-	if (NULL == h)
+	if (h == NULL)
 		goto errout;
 
 	if (a->type == TCA_OLD_COMPAT)
@@ -442,7 +399,7 @@
 	if (err < 0)
 		goto errout;
 
-	if (NULL != a->ops && NULL != a->ops->get_stats)
+	if (a->ops != NULL && a->ops->get_stats != NULL)
 		if (a->ops->get_stats(skb, a) < 0)
 			goto errout;
 
@@ -462,14 +419,13 @@
 	return -1;
 }
 
-
 static int
-tca_get_fill(struct sk_buff *skb,  struct tc_action *a,
-	      u32 pid, u32 seq, unsigned flags, int event, int bind, int ref)
+tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
+             unsigned flags, int event, int bind, int ref)
 {
 	struct tcamsg *t;
-	struct nlmsghdr  *nlh;
-	unsigned char	 *b = skb->tail;
+	struct nlmsghdr *nlh;
+	unsigned char *b = skb->tail;
 	struct rtattr *x;
 
 	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t));
@@ -480,9 +436,8 @@
 	x = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
-	if (0 > tcf_action_dump(skb, a, bind, ref)) {
+	if (tcf_action_dump(skb, a, bind, ref) < 0)
 		goto rtattr_failure;
-	}
 
 	x->rta_len = skb->tail - (u8*)x;
 	
@@ -495,160 +450,88 @@
 	return -1;
 }
 
-static int act_get_notify(u32 pid, struct nlmsghdr *n,
-			   struct tc_action *a, int event)
+static int
+act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
 {
 	struct sk_buff *skb;
-
 	int err = 0;
 
 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 	if (!skb)
 		return -ENOBUFS;
-
-	if (tca_get_fill(skb, a,  pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
+	if (tca_get_fill(skb, a, pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) {
 		kfree_skb(skb);
 		return -EINVAL;
 	}
-
-	err =  netlink_unicast(rtnl,skb, pid, MSG_DONTWAIT);
+	err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT);
 	if (err > 0)
 		err = 0;
 	return err;
 }
 
-static int tcf_action_get_1(struct rtattr *rta, struct tc_action *a, struct nlmsghdr *n, u32 pid)
+static struct tc_action *
+tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err)
 {
-	struct tc_action_ops *a_o;
-	char act_name[4 + IFNAMSIZ + 1];
 	struct rtattr *tb[TCA_ACT_MAX+1];
-	struct rtattr *kind = NULL;
+	struct tc_action *a;
 	int index;
 
-	int err = -EINVAL;
-
-	if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0)
-		goto err_out;
-
-
-	kind = tb[TCA_ACT_KIND-1];
-	if (NULL != kind) {
-		sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-		if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-			printk("tcf_action_get_1: action %s bad\n", (char*)RTA_DATA(kind));
-			goto err_out;
-		}
-
-	} else {
-		printk("tcf_action_get_1: action bad kind\n");
-		goto err_out;
-	}
-
-	if (tb[TCA_ACT_INDEX - 1]) {
-		index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]);
-	} else {
-		printk("tcf_action_get_1: index not received\n");
-		goto err_out;
-	}
+	*err = -EINVAL;
+	if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
+		return NULL;
 
-	a_o = tc_lookup_action(kind);
-#ifdef CONFIG_KMOD
-	if (NULL == a_o) {
-		request_module (act_name);
-		a_o = tc_lookup_action_n(act_name);
-	}
+	if (tb[TCA_ACT_INDEX - 1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_ACT_INDEX - 1]) < sizeof(index))
+		return NULL;
+	index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]);
 
-#endif
-	if (NULL == a_o) {
-		printk("failed to find %s\n",act_name);
-		goto err_out;
-	}
+	*err = -ENOMEM;
+	a = kmalloc(sizeof(struct tc_action), GFP_KERNEL);
+	if (a == NULL)
+		return NULL;
+	memset(a, 0, sizeof(struct tc_action));
 
-	if (NULL == a) {
+	*err = -EINVAL;
+	a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]);
+	if (a->ops == NULL)
+		goto err_free;
+	if (a->ops->lookup == NULL)
 		goto err_mod;
-	}
-
-	a->ops = a_o;
-
-	if (NULL == a_o->lookup || 0 == a_o->lookup(a, index)) {
-		a->ops = NULL;
-		err = -EINVAL;
+	*err = -ENOENT;
+	if (a->ops->lookup(a, index) == 0)
 		goto err_mod;
-	}
 
-	module_put(a_o->owner);
-	return 0;
+	module_put(a->ops->owner);
+	*err = 0;
+	return a;
 err_mod:
-	module_put(a_o->owner);
-err_out:
-	return err;
+	module_put(a->ops->owner);
+err_free:
+	kfree(a);
+	return NULL;
 }
 
-static void cleanup_a (struct tc_action *act) 
+static void cleanup_a(struct tc_action *act)
 {
 	struct tc_action *a;
 
-	for (a = act; act; a = act) {
-		if (a) {
-			act = act->next;
-			a->ops = NULL;
-			a->priv = NULL;
-			kfree(a);
-		} else {
-			printk("cleanup_a: BUG? empty action\n");
-		}
-	}
-}
-
-static struct tc_action_ops *get_ao(struct rtattr *kind, struct tc_action *a)
-{
-	char act_name[4 + IFNAMSIZ + 1];
-	struct tc_action_ops *a_o = NULL;
-
-	if (NULL != kind) {
-		sprintf(act_name, "%s", (char*)RTA_DATA(kind));
-		if (RTA_PAYLOAD(kind) >= IFNAMSIZ) {
-			printk("get_ao: action %s bad\n", (char*)RTA_DATA(kind));
-			return NULL;
-		}
-
-	} else {
-		printk("get_ao: action bad kind\n");
-		return NULL;
-	}
-
-	a_o = tc_lookup_action(kind);
-#ifdef CONFIG_KMOD
-	if (NULL == a_o) {
-		DPRINTK("get_ao: trying to load module %s\n",act_name);
-		request_module (act_name);
-		a_o = tc_lookup_action_n(act_name);
-	}
-#endif
-
-	if (NULL == a_o) {
-		printk("get_ao: failed to find %s\n",act_name);
-		return NULL;
+	for (a = act; a; a = act) {
+		act = a->next;
+		kfree(a);
 	}
-
-	a->ops = a_o;
-	return a_o;
 }
 
 static struct tc_action *create_a(int i)
 {
-	struct tc_action *act = NULL;
+	struct tc_action *act;
 
-	act = kmalloc(sizeof(*act),GFP_KERNEL);
-	if (NULL == act) { /* grrr .. */
-		printk("create_a: failed to alloc! \n");
+	act = kmalloc(sizeof(*act), GFP_KERNEL);
+	if (act == NULL) {
+		printk("create_a: failed to alloc!\n");
 		return NULL;
 	}
-
-	memset(act, 0,sizeof(*act));
-
+	memset(act, 0, sizeof(*act));
 	act->order = i;
-
 	return act;
 }
 
@@ -661,11 +544,11 @@
 	struct netlink_callback dcb;
 	struct rtattr *x;
 	struct rtattr *tb[TCA_ACT_MAX+1];
-	struct rtattr *kind = NULL;
+	struct rtattr *kind;
 	struct tc_action *a = create_a(0);
 	int err = -EINVAL;
 
-	if (NULL == a) {
+	if (a == NULL) {
 		printk("tca_action_flush: couldnt create tc_action\n");
 		return err;
 	}
@@ -679,16 +562,15 @@
 
 	b = (unsigned char *)skb->tail;
 
-	if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) {
+	if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
 		goto err_out;
-	}
 
 	kind = tb[TCA_ACT_KIND-1];
-	if (NULL == get_ao(kind, a)) {
+	a->ops = tc_lookup_action(kind);
+	if (a->ops == NULL)
 		goto err_out;
-	}
 
-	nlh = NLMSG_PUT(skb, pid,  n->nlmsg_seq, RTM_DELACTION, sizeof (*t));
+	nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
 
@@ -696,9 +578,8 @@
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
 	err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
-	if (0 > err ) {
+	if (err < 0)
 		goto rtattr_failure;
-	}
 
 	x->rta_len = skb->tail - (u8 *) x;
 
@@ -712,7 +593,6 @@
 
 	return err;
 
-
 rtattr_failure:
 	module_put(a->ops->owner);
 nlmsg_failure:
@@ -722,99 +602,73 @@
 	return err;
 }
 
-static int tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event )
+static int
+tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event)
 {
-
-	int s = 0;
 	int i, ret = 0;
-	struct tc_action *act = NULL;
 	struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
-	struct tc_action *a = NULL, *a_s = NULL;
-
-	if (event != RTM_GETACTION  && event != RTM_DELACTION)
-		ret = -EINVAL;
+	struct tc_action *head = NULL, *act, *act_prev = NULL;
 
-	if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), RTA_PAYLOAD(rta))<0) {
-		ret = -EINVAL;
-		goto nlmsg_failure;
-	}
+	if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0)
+		return -EINVAL;
 
 	if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
-		if (NULL != tb[0]  && NULL == tb[1]) {
-			return tca_action_flush(tb[0],n,pid);
-		}
+		if (tb[0] != NULL && tb[1] == NULL)
+			return tca_action_flush(tb[0], n, pid);
 	}
 
-	for (i=0; i < TCA_ACT_MAX_PRIO ; i++) {
-
-		if (NULL == tb[i])
-			break;
-
-		act = create_a(i+1);
-		if (NULL != a && a != act) {
-			a->next = act;
-			a = act;
-		} else {
-			a = act;
-		}
-
-		if (!s) {
-			s = 1;
-			a_s = a;
-		}
-
-		ret = tcf_action_get_1(tb[i],act,n,pid);
-		if (ret < 0) {
-			printk("tcf_action_get: failed to get! \n");
-			ret = -EINVAL;
-			goto rtattr_failure;
-		}
-
-	}
-
-
-	if (RTM_GETACTION == event) {
-		ret = act_get_notify(pid, n, a_s, event);
-	} else { /* delete */
-
+	for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) {
+		act = tcf_action_get_1(tb[i], n, pid, &ret);
+		if (act == NULL)
+			goto err;
+		act->order = i+1;
+
+		if (head == NULL)
+			head = act;
+		else
+			act_prev->next = act;
+		act_prev = act;
+	}
+
+	if (event == RTM_GETACTION)
+		ret = act_get_notify(pid, n, head, event);
+	else { /* delete */
 		struct sk_buff *skb;
 
 		skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 		if (!skb) {
 			ret = -ENOBUFS;
-			goto nlmsg_failure;
+			goto err;
 		}
 
-		if (tca_get_fill(skb, a_s,  pid, n->nlmsg_seq, 0, event, 0 , 1) <= 0) {
+		if (tca_get_fill(skb, head, pid, n->nlmsg_seq, 0, event,
+		                 0, 1) <= 0) {
 			kfree_skb(skb);
 			ret = -EINVAL;
-			goto nlmsg_failure;
+			goto err;
 		}
 
 		/* now do the delete */
-		tcf_action_destroy(a_s, 0);
-
-		ret = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+		tcf_action_destroy(head, 0);
+		ret = rtnetlink_send(skb, pid, RTMGRP_TC,
+		                     n->nlmsg_flags&NLM_F_ECHO);
 		if (ret > 0)
 			return 0;
 		return ret;
 	}
-rtattr_failure:
-nlmsg_failure:
-	cleanup_a(a_s);
+err:
+	cleanup_a(head);
 	return ret;
 }
 
-
-static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, unsigned flags) 
+static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
+                          unsigned flags)
 {
 	struct tcamsg *t;
-	struct nlmsghdr  *nlh;
+	struct nlmsghdr *nlh;
 	struct sk_buff *skb;
 	struct rtattr *x;
 	unsigned char *b;
-
-
 	int err = 0;
 
 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
@@ -831,9 +685,8 @@
 	x = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
-	if (0 > tcf_action_dump(skb, a, 0, 0)) {
+	if (tcf_action_dump(skb, a, 0, 0) < 0)
 		goto rtattr_failure;
-	}
 
 	x->rta_len = skb->tail - (u8*)x;
 	
@@ -843,7 +696,6 @@
 	err = rtnetlink_send(skb, pid, RTMGRP_TC, flags&NLM_F_ECHO);
 	if (err > 0)
 		err = 0;
-
 	return err;
 
 rtattr_failure:
@@ -853,11 +705,12 @@
 }
 
 	
-static int tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr ) 
+static int
+tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr)
 {
 	int ret = 0;
-	struct tc_action *act = NULL;
-	struct tc_action *a = NULL;
+	struct tc_action *act;
+	struct tc_action *a;
 	u32 seq = n->nlmsg_seq;
 
 	act = tcf_action_init(rta, NULL, NULL, ovr, 0, &ret);
@@ -867,16 +720,10 @@
 	/* dump then free all the actions after update; inserted policy
 	 * stays intact
 	 * */
-	ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); 
-	for (a = act; act; a = act) {
-		if (a) {
-			act = act->next;
-			a->ops = NULL;
-			a->priv = NULL;
-			kfree(a);
-		} else {
-			printk("tcf_action_add: BUG? empty action\n");
-		}
+	ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
+	for (a = act; a; a = act) {
+		act = a->next;
+		kfree(a);
 	}
 done:
 	return ret;
@@ -886,38 +733,38 @@
 {
 	struct rtattr **tca = arg;
 	u32 pid = skb ? NETLINK_CB(skb).pid : 0;
-
 	int ret = 0, ovr = 0;
 
-	if (NULL == tca[TCA_ACT_TAB-1]) {
-			printk("tc_ctl_action: received NO action attribs\n");
-			return -EINVAL;
+	if (tca[TCA_ACT_TAB-1] == NULL) {
+		printk("tc_ctl_action: received NO action attribs\n");
+		return -EINVAL;
 	}
 
 	/* n->nlmsg_flags&NLM_F_CREATE
 	 * */
 	switch (n->nlmsg_type) {
-	case RTM_NEWACTION:    
+	case RTM_NEWACTION:
 		/* we are going to assume all other flags
 		 * imply create only if it doesnt exist
 		 * Note that CREATE | EXCL implies that
 		 * but since we want avoid ambiguity (eg when flags
 		 * is zero) then just set this
 		 */
-		if (n->nlmsg_flags&NLM_F_REPLACE) {
+		if (n->nlmsg_flags&NLM_F_REPLACE)
 			ovr = 1;
-		}
-		ret =  tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr);
+replay:
+		ret = tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr);
+		if (ret == -EAGAIN)
+			goto replay;
 		break;
 	case RTM_DELACTION:
-		ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid,RTM_DELACTION);
+		ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_DELACTION);
 		break;
 	case RTM_GETACTION:
-		ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid,RTM_GETACTION);
+		ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_GETACTION);
 		break;
 	default:
-		printk(" Unknown cmd was detected\n");
-		break;
+		BUG();
 	}
 
 	return ret;
@@ -929,25 +776,25 @@
 	struct rtattr *tb1, *tb2[TCA_ACT_MAX+1];
 	struct rtattr *tb[TCA_ACT_MAX_PRIO + 1];
 	struct rtattr *rta[TCAA_MAX + 1];
-	struct rtattr *kind = NULL;
-	int min_len = NLMSG_LENGTH(sizeof (struct tcamsg));
-
+	struct rtattr *kind;
+	int min_len = NLMSG_LENGTH(sizeof(struct tcamsg));
 	int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len);
 	struct rtattr *attr = (void *) n + NLMSG_ALIGN(min_len);
 
 	if (rtattr_parse(rta, TCAA_MAX, attr, attrlen) < 0)
 		return NULL;
 	tb1 = rta[TCA_ACT_TAB - 1];
-	if (NULL == tb1) {
+	if (tb1 == NULL)
 		return NULL;
-	}
 
-	if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1), NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0)
+	if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1),
+	                 NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0)
 		return NULL;
-	if (NULL == tb[0]) 
+	if (tb[0] == NULL)
 		return NULL;
 
-	if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]), RTA_PAYLOAD(tb[0]))<0)
+	if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]),
+	                 RTA_PAYLOAD(tb[0])) < 0)
 		return NULL;
 	kind = tb2[TCA_ACT_KIND-1];
 
@@ -963,30 +810,30 @@
 	struct tc_action_ops *a_o;
 	struct tc_action a;
 	int ret = 0;
-
 	struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
 	char *kind = find_dump_kind(cb->nlh);
-	if (NULL == kind) {
+
+	if (kind == NULL) {
 		printk("tc_dump_action: action bad kind\n");
 		return 0;
 	}
 
 	a_o = tc_lookup_action_n(kind);
-
-	if (NULL == a_o) {
+	if (a_o == NULL) {
 		printk("failed to find %s\n", kind);
 		return 0;
 	}
 
-	memset(&a,0,sizeof(struct tc_action));
+	memset(&a, 0, sizeof(struct tc_action));
 	a.ops = a_o;
 
-	if (NULL == a_o->walk) {
-		printk("tc_dump_action: %s !capable of dumping table\n",kind);
+	if (a_o->walk == NULL) {
+		printk("tc_dump_action: %s !capable of dumping table\n", kind);
 		goto rtattr_failure;
 	}
 
-	nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid,  cb->nlh->nlmsg_seq, cb->nlh->nlmsg_type, sizeof (*t));
+	nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
+	                cb->nlh->nlmsg_type, sizeof(*t));
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
 
@@ -994,19 +841,17 @@
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
 	ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
-	if (0 > ret ) {
+	if (ret < 0)
 		goto rtattr_failure;
-	}
 
 	if (ret > 0) {
 		x->rta_len = skb->tail - (u8 *) x;
 		ret = skb->len;
-	} else {
+	} else
 		skb_trim(skb, (u8*)x - skb->data);
-	}
 
 	nlh->nlmsg_len = skb->tail - b;
-	if (NETLINK_CB(cb->skb).pid && ret) 
+	if (NETLINK_CB(cb->skb).pid && ret)
 		nlh->nlmsg_flags |= NLM_F_MULTI;
 	module_put(a_o->owner);
 	return skb->len;
@@ -1029,7 +874,8 @@
 		link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action;
 	}
 
-	printk("TC classifier action (bugs to netdev@oss.sgi.com cc hadi@cyberus.ca)\n");
+	printk("TC classifier action (bugs to netdev@oss.sgi.com cc "
+	       "hadi@cyberus.ca)\n");
 	return 0;
 }
 
@@ -1037,11 +883,5 @@
 
 EXPORT_SYMBOL(tcf_register_action);
 EXPORT_SYMBOL(tcf_unregister_action);
-EXPORT_SYMBOL(tcf_action_init_1);
-EXPORT_SYMBOL(tcf_action_init);
-EXPORT_SYMBOL(tcf_action_destroy);
 EXPORT_SYMBOL(tcf_action_exec);
-EXPORT_SYMBOL(tcf_action_copy_stats);
-EXPORT_SYMBOL(tcf_action_dump);
 EXPORT_SYMBOL(tcf_action_dump_1);
-EXPORT_SYMBOL(tcf_action_dump_old);
diff -Nru a/net/sched/cls_api.c b/net/sched/cls_api.c
--- a/net/sched/cls_api.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/cls_api.c	2005-01-19 13:44:46 -08:00
@@ -49,7 +49,7 @@
 static struct tcf_proto_ops *tcf_proto_base;
 
 /* Protects list of registered TC modules. It is pure SMP lock. */
-static rwlock_t cls_mod_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(cls_mod_lock);
 
 /* Find classifier type by string name */
 
@@ -130,22 +130,31 @@
 
 static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
-	struct rtattr **tca = arg;
-	struct tcmsg *t = NLMSG_DATA(n);
-	u32 protocol = TC_H_MIN(t->tcm_info);
-	u32 prio = TC_H_MAJ(t->tcm_info);
-	u32 nprio = prio;
-	u32 parent = t->tcm_parent;
+	struct rtattr **tca;
+	struct tcmsg *t;
+	u32 protocol;
+	u32 prio;
+	u32 nprio;
+	u32 parent;
 	struct net_device *dev;
 	struct Qdisc  *q;
 	struct tcf_proto **back, **chain;
-	struct tcf_proto *tp = NULL;
+	struct tcf_proto *tp;
 	struct tcf_proto_ops *tp_ops;
 	struct Qdisc_class_ops *cops;
-	unsigned long cl = 0;
+	unsigned long cl;
 	unsigned long fh;
 	int err;
 
+replay:
+	tca = arg;
+	t = NLMSG_DATA(n);
+	protocol = TC_H_MIN(t->tcm_info);
+	prio = TC_H_MAJ(t->tcm_info);
+	nprio = prio;
+	parent = t->tcm_parent;
+	cl = 0;
+
 	if (prio == 0) {
 		/* If no priority is given, user wants we allocated it. */
 		if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
@@ -211,19 +220,29 @@
 		err = -ENOBUFS;
 		if ((tp = kmalloc(sizeof(*tp), GFP_KERNEL)) == NULL)
 			goto errout;
+		err = -EINVAL;
 		tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
+		if (tp_ops == NULL) {
 #ifdef CONFIG_KMOD
-		if (tp_ops==NULL && tca[TCA_KIND-1] != NULL) {
 			struct rtattr *kind = tca[TCA_KIND-1];
+			char name[IFNAMSIZ];
 
-			if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
-				request_module("cls_%s", (char*)RTA_DATA(kind));
+			if (kind != NULL &&
+			    rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+				rtnl_unlock();
+				request_module("cls_%s", name);
+				rtnl_lock();
 				tp_ops = tcf_proto_lookup_ops(kind);
+				/* We dropped the RTNL semaphore in order to
+				 * perform the module load.  So, even if we
+				 * succeeded in loading the module we have to
+				 * replay the request.  We indicate this using
+				 * -EAGAIN.
+				 */
+				if (tp_ops != NULL)
+					err = -EAGAIN;
 			}
-		}
 #endif
-		if (tp_ops == NULL) {
-			err = -EINVAL;
 			kfree(tp);
 			goto errout;
 		}
@@ -293,6 +312,9 @@
 errout:
 	if (cl)
 		cops->put(q, cl);
+	if (err == -EAGAIN)
+		/* Replay the request. */
+		goto replay;
 	return err;
 }
 
@@ -439,6 +461,154 @@
 	return skb->len;
 }
 
+void
+tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (exts->action) {
+		tcf_action_destroy(exts->action, TCA_ACT_UNBIND);
+		exts->action = NULL;
+	}
+#elif defined CONFIG_NET_CLS_POLICE
+	if (exts->police) {
+		tcf_police_release(exts->police, TCA_ACT_UNBIND);
+		exts->police = NULL;
+	}
+#endif
+}
+
+
+int
+tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
+	          struct rtattr *rate_tlv, struct tcf_exts *exts,
+	          struct tcf_ext_map *map)
+{
+	memset(exts, 0, sizeof(*exts));
+	
+#ifdef CONFIG_NET_CLS_ACT
+	int err;
+	struct tc_action *act;
+
+	if (map->police && tb[map->police-1]) {
+		act = tcf_action_init_1(tb[map->police-1], rate_tlv, "police",
+			TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
+		if (act == NULL)
+			return err;
+
+		act->type = TCA_OLD_COMPAT;
+		exts->action = act;
+	} else if (map->action && tb[map->action-1]) {
+		act = tcf_action_init(tb[map->action-1], rate_tlv, NULL,
+			TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
+		if (act == NULL)
+			return err;
+
+		exts->action = act;
+	}
+#elif defined CONFIG_NET_CLS_POLICE
+	if (map->police && tb[map->police-1]) {
+		struct tcf_police *p;
+		
+		p = tcf_police_locate(tb[map->police-1], rate_tlv);
+		if (p == NULL)
+			return -EINVAL;
+
+		exts->police = p;
+	} else if (map->action && tb[map->action-1])
+		return -EOPNOTSUPP;
+#else
+	if ((map->action && tb[map->action-1]) ||
+	    (map->police && tb[map->police-1]))
+		return -EOPNOTSUPP;
+#endif
+
+	return 0;
+}
+
+void
+tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
+	        struct tcf_exts *src)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (src->action) {
+		struct tc_action *act;
+		tcf_tree_lock(tp);
+		act = xchg(&dst->action, src->action);
+		tcf_tree_unlock(tp);
+		if (act)
+			tcf_action_destroy(act, TCA_ACT_UNBIND);
+	}
+#elif defined CONFIG_NET_CLS_POLICE
+	if (src->police) {
+		struct tcf_police *p;
+		tcf_tree_lock(tp);
+		p = xchg(&dst->police, src->police);
+		tcf_tree_unlock(tp);
+		if (p)
+			tcf_police_release(p, TCA_ACT_UNBIND);
+	}
+#endif
+}
+
+int
+tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
+	      struct tcf_ext_map *map)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (map->action && exts->action) {
+		/*
+		 * again for backward compatible mode - we want
+		 * to work with both old and new modes of entering
+		 * tc data even if iproute2  was newer - jhs
+		 */
+		struct rtattr * p_rta = (struct rtattr*) skb->tail;
+
+		if (exts->action->type != TCA_OLD_COMPAT) {
+			RTA_PUT(skb, map->action, 0, NULL);
+			if (tcf_action_dump(skb, exts->action, 0, 0) < 0)
+				goto rtattr_failure;
+			p_rta->rta_len = skb->tail - (u8*)p_rta;
+		} else if (map->police) {
+			RTA_PUT(skb, map->police, 0, NULL);
+			if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0)
+				goto rtattr_failure;
+			p_rta->rta_len = skb->tail - (u8*)p_rta;
+		}
+	}
+#elif defined CONFIG_NET_CLS_POLICE
+	if (map->police && exts->police) {
+		struct rtattr * p_rta = (struct rtattr*) skb->tail;
+
+		RTA_PUT(skb, map->police, 0, NULL);
+
+		if (tcf_police_dump(skb, exts->police) < 0)
+			goto rtattr_failure;
+
+		p_rta->rta_len = skb->tail - (u8*)p_rta;
+	}
+#endif
+	return 0;
+rtattr_failure: __attribute__ ((unused))
+	return -1;
+}
+
+int
+tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
+	            struct tcf_ext_map *map)
+{
+#ifdef CONFIG_NET_CLS_ACT
+	if (exts->action)
+		if (tcf_action_copy_stats(skb, exts->action) < 0)
+			goto rtattr_failure;
+#elif defined CONFIG_NET_CLS_POLICE
+	if (exts->police)
+		if (tcf_police_dump_stats(skb, exts->police) < 0)
+			goto rtattr_failure;
+#endif
+	return 0;
+rtattr_failure: __attribute__ ((unused))
+	return -1;
+}
 
 static int __init tc_filter_init(void)
 {
@@ -461,3 +631,8 @@
 
 EXPORT_SYMBOL(register_tcf_proto_ops);
 EXPORT_SYMBOL(unregister_tcf_proto_ops);
+EXPORT_SYMBOL(tcf_exts_validate);
+EXPORT_SYMBOL(tcf_exts_destroy);
+EXPORT_SYMBOL(tcf_exts_change);
+EXPORT_SYMBOL(tcf_exts_dump);
+EXPORT_SYMBOL(tcf_exts_dump_stats);
diff -Nru a/net/sched/cls_fw.c b/net/sched/cls_fw.c
--- a/net/sched/cls_fw.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/cls_fw.c	2005-01-19 13:44:46 -08:00
@@ -59,13 +59,12 @@
 #ifdef CONFIG_NET_CLS_IND
 	char			indev[IFNAMSIZ];
 #endif /* CONFIG_NET_CLS_IND */
-#ifdef CONFIG_NET_CLS_ACT
-	struct tc_action        *action;
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-	struct tcf_police	*police;
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
+	struct tcf_exts		exts;
+};
+
+static struct tcf_ext_map fw_ext_map = {
+	.action = TCA_FW_ACT,
+	.police = TCA_FW_POLICE
 };
 
 static __inline__ int fw_hash(u32 handle)
@@ -78,6 +77,7 @@
 {
 	struct fw_head *head = (struct fw_head*)tp->root;
 	struct fw_filter *f;
+	int r;
 #ifdef CONFIG_NETFILTER
 	u32 id = skb->nfmark;
 #else
@@ -92,20 +92,11 @@
 				if (!tcf_match_indev(skb, f->indev))
 					continue;
 #endif /* CONFIG_NET_CLS_IND */
-#ifdef CONFIG_NET_CLS_ACT
-				if (f->action) {
-					int act_res = tcf_action_exec(skb, f->action, res);
-					if (act_res >= 0)
-						return act_res;
+				r = tcf_exts_exec(skb, &f->exts, res);
+				if (r < 0)
 					continue;
-				}
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-				if (f->police)
-					return tcf_police(skb, f->police);
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
-				return 0;
+
+				return r;
 			}
 		}
 	} else {
@@ -144,6 +135,14 @@
 	return 0;
 }
 
+static inline void
+fw_delete_filter(struct tcf_proto *tp, struct fw_filter *f)
+{
+	tcf_unbind_filter(tp, &f->res);
+	tcf_exts_destroy(tp, &f->exts);
+	kfree(f);
+}
+
 static void fw_destroy(struct tcf_proto *tp)
 {
 	struct fw_head *head = (struct fw_head*)xchg(&tp->root, NULL);
@@ -156,18 +155,7 @@
 	for (h=0; h<256; h++) {
 		while ((f=head->ht[h]) != NULL) {
 			head->ht[h] = f->next;
-			tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_ACT
-			if (f->action)
-				tcf_action_destroy(f->action, TCA_ACT_UNBIND);
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-			if (f->police)
-				tcf_police_release(f->police, TCA_ACT_UNBIND);
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
-
-			kfree(f);
+			fw_delete_filter(tp, f);
 		}
 	}
 	kfree(head);
@@ -187,16 +175,7 @@
 			tcf_tree_lock(tp);
 			*fp = f->next;
 			tcf_tree_unlock(tp);
-			tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_ACT
-			if (f->action)
-				tcf_action_destroy(f->action,TCA_ACT_UNBIND);
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-			tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
-			kfree(f);
+			fw_delete_filter(tp, f);
 			return 0;
 		}
 	}
@@ -208,8 +187,14 @@
 fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
 	struct rtattr **tb, struct rtattr **tca, unsigned long base)
 {
-	int err = -EINVAL;
+	struct tcf_exts e;
+	int err;
 
+	err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &fw_ext_map);
+	if (err < 0)
+		return err;
+
+	err = -EINVAL;
 	if (tb[TCA_FW_CLASSID-1]) {
 		if (RTA_PAYLOAD(tb[TCA_FW_CLASSID-1]) != sizeof(u32))
 			goto errout;
@@ -225,33 +210,11 @@
 	}
 #endif /* CONFIG_NET_CLS_IND */
 
-#ifdef CONFIG_NET_CLS_ACT
-	if (tb[TCA_FW_POLICE-1]) {
-		err = tcf_change_act_police(tp, &f->action, tb[TCA_FW_POLICE-1],
-			tca[TCA_RATE-1]);
-		if (err < 0)
-			goto errout;
-	}
-
-	if (tb[TCA_FW_ACT-1]) {
-		err = tcf_change_act(tp, &f->action, tb[TCA_FW_ACT-1],
-			tca[TCA_RATE-1]);
-		if (err < 0)
-			goto errout;
-	}
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_FW_POLICE-1]) {
-		err = tcf_change_police(tp, &f->police, tb[TCA_FW_POLICE-1],
-			tca[TCA_RATE-1]);
-		if (err < 0)
-			goto errout;
-	}
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
+	tcf_exts_change(tp, &f->exts, &e);
 
-	err = 0;
+	return 0;
 errout:
+	tcf_exts_destroy(tp, &e);
 	return err;
 }
 
@@ -269,7 +232,7 @@
 	if (!opt)
 		return handle ? -EINVAL : 0;
 
-	if (rtattr_parse(tb, TCA_FW_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
+	if (rtattr_parse_nested(tb, TCA_FW_MAX, opt) < 0)
 		return -EINVAL;
 
 	if (f != NULL) {
@@ -357,15 +320,7 @@
 
 	t->tcm_handle = f->id;
 
-	if (!f->res.classid
-#ifdef CONFIG_NET_CLS_ACT
-		&& !f->action
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-		&& !f->police
-#endif
-#endif
-		)
+	if (!f->res.classid && !tcf_exts_is_available(&f->exts))
 		return skb->len;
 
 	rta = (struct rtattr*)b;
@@ -377,29 +332,15 @@
 	if (strlen(f->indev))
 		RTA_PUT(skb, TCA_FW_INDEV, IFNAMSIZ, f->indev);
 #endif /* CONFIG_NET_CLS_IND */
-#ifdef CONFIG_NET_CLS_ACT
-	if (tcf_dump_act(skb, f->action, TCA_FW_ACT, TCA_FW_POLICE) < 0)
-		goto rtattr_failure;
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tcf_dump_police(skb, f->police, TCA_FW_POLICE) < 0)
+
+	if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0)
 		goto rtattr_failure;
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
 
 	rta->rta_len = skb->tail - b;
-#ifdef CONFIG_NET_CLS_ACT
-	if (f->action && f->action->type == TCA_OLD_COMPAT) {
-		if (tcf_action_copy_stats(skb,f->action))
-			goto rtattr_failure;
-	}
-#else /* CONFIG_NET_CLS_ACT */
-#ifdef CONFIG_NET_CLS_POLICE
-	if (f->police)
-		if (tcf_police_dump_stats(skb, f->police) < 0)
-			goto rtattr_failure;
-#endif /* CONFIG_NET_CLS_POLICE */
-#endif /* CONFIG_NET_CLS_ACT */
+
+	if (tcf_exts_dump_stats(skb, &f->exts, &fw_ext_map) < 0)
+		goto rtattr_failure;
+
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/cls_route.c b/net/sched/cls_route.c
--- a/net/sched/cls_route.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/cls_route.c	2005-01-19 13:44:46 -08:00
@@ -59,6 +59,7 @@
 
 struct route4_bucket
 {
+	/* 16 FROM buckets + 16 IIF buckets + 1 wildcard bucket */
 	struct route4_filter	*ht[16+16+1];
 };
 
@@ -69,22 +70,25 @@
 	int			iif;
 
 	struct tcf_result	res;
-#ifdef CONFIG_NET_CLS_POLICE
-	struct tcf_police	*police;
-#endif
-
+	struct tcf_exts		exts;
 	u32			handle;
 	struct route4_bucket	*bkt;
 };
 
 #define ROUTE4_FAILURE ((struct route4_filter*)(-1L))
 
+static struct tcf_ext_map route_ext_map = {
+	.police = TCA_ROUTE4_POLICE,
+	.action = TCA_ROUTE4_ACT
+};
+
 static __inline__ int route4_fastmap_hash(u32 id, int iif)
 {
 	return id&0xF;
 }
 
-static void route4_reset_fastmap(struct net_device *dev, struct route4_head *head, u32 id)
+static inline
+void route4_reset_fastmap(struct net_device *dev, struct route4_head *head, u32 id)
 {
 	spin_lock_bh(&dev->queue_lock);
 	memset(head->fastmap, 0, sizeof(head->fastmap));
@@ -121,19 +125,20 @@
 	return 32;
 }
 
-#ifdef CONFIG_NET_CLS_POLICE
-#define IF_ROUTE_POLICE \
-if (f->police) { \
-	int pol_res = tcf_police(skb, f->police); \
-	if (pol_res >= 0) return pol_res; \
-	dont_cache = 1; \
-	continue; \
-} \
-if (!dont_cache)
-#else
-#define IF_ROUTE_POLICE
-#endif
-
+#define ROUTE4_APPLY_RESULT()						\
+	do {								\
+		*res = f->res;						\
+		if (tcf_exts_is_available(&f->exts)) {			\
+			int r = tcf_exts_exec(skb, &f->exts, res);	\
+			if (r < 0) {					\
+				dont_cache = 1;				\
+				continue;				\
+			}						\
+			return r;					\
+		} else if (!dont_cache)					\
+			route4_set_fastmap(head, id, iif, f);		\
+		return 0;						\
+	} while(0)
 
 static int route4_classify(struct sk_buff *skb, struct tcf_proto *tp,
 			   struct tcf_result *res)
@@ -142,11 +147,8 @@
 	struct dst_entry *dst;
 	struct route4_bucket *b;
 	struct route4_filter *f;
-#ifdef CONFIG_NET_CLS_POLICE
-	int dont_cache = 0;
-#endif
 	u32 id, h;
-	int iif;
+	int iif, dont_cache = 0;
 
 	if ((dst = skb->dst) == NULL)
 		goto failure;
@@ -172,29 +174,16 @@
 
 restart:
 	if ((b = head->table[h]) != NULL) {
-		f = b->ht[route4_hash_from(id)];
-
-		for ( ; f; f = f->next) {
-			if (f->id == id) {
-				*res = f->res;
-				IF_ROUTE_POLICE route4_set_fastmap(head, id, iif, f);
-				return 0;
-			}
-		}
-
-		for (f = b->ht[route4_hash_iif(iif)]; f; f = f->next) {
-			if (f->iif == iif) {
-				*res = f->res;
-				IF_ROUTE_POLICE route4_set_fastmap(head, id, iif, f);
-				return 0;
-			}
-		}
+		for (f = b->ht[route4_hash_from(id)]; f; f = f->next)
+			if (f->id == id)
+				ROUTE4_APPLY_RESULT();
+
+		for (f = b->ht[route4_hash_iif(iif)]; f; f = f->next)
+			if (f->iif == iif)
+				ROUTE4_APPLY_RESULT();
 
-		for (f = b->ht[route4_hash_wild()]; f; f = f->next) {
-			*res = f->res;
-			IF_ROUTE_POLICE route4_set_fastmap(head, id, iif, f);
-			return 0;
-		}
+		for (f = b->ht[route4_hash_wild()]; f; f = f->next)
+			ROUTE4_APPLY_RESULT();
 
 	}
 	if (h < 256) {
@@ -203,9 +192,7 @@
 		goto restart;
 	}
 
-#ifdef CONFIG_NET_CLS_POLICE
 	if (!dont_cache)
-#endif
 		route4_set_fastmap(head, id, iif, ROUTE4_FAILURE);
 failure:
 	return -1;
@@ -220,7 +207,7 @@
 	return -1;
 }
 
-static u32 to_hash(u32 id)
+static inline u32 to_hash(u32 id)
 {
 	u32 h = id&0xFF;
 	if (id&0x8000)
@@ -228,7 +215,7 @@
 	return h;
 }
 
-static u32 from_hash(u32 id)
+static inline u32 from_hash(u32 id)
 {
 	id &= 0xFFFF;
 	if (id == 0xFFFF)
@@ -276,6 +263,14 @@
 	return 0;
 }
 
+static inline void
+route4_delete_filter(struct tcf_proto *tp, struct route4_filter *f)
+{
+	tcf_unbind_filter(tp, &f->res);
+	tcf_exts_destroy(tp, &f->exts);
+	kfree(f);
+}
+
 static void route4_destroy(struct tcf_proto *tp)
 {
 	struct route4_head *head = xchg(&tp->root, NULL);
@@ -293,11 +288,7 @@
 
 				while ((f = b->ht[h2]) != NULL) {
 					b->ht[h2] = f->next;
-					tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_POLICE
-					tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-					kfree(f);
+					route4_delete_filter(tp, f);
 				}
 			}
 			kfree(b);
@@ -327,11 +318,7 @@
 			tcf_tree_unlock(tp);
 
 			route4_reset_fastmap(tp->q->dev, head, f->id);
-			tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_POLICE
-			tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-			kfree(f);
+			route4_delete_filter(tp, f);
 
 			/* Strip tree */
 
@@ -351,108 +338,63 @@
 	return 0;
 }
 
-static int route4_change(struct tcf_proto *tp, unsigned long base,
-		       u32 handle,
-		       struct rtattr **tca,
-		       unsigned long *arg)
+static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
+	struct route4_filter *f, u32 handle, struct route4_head *head,
+	struct rtattr **tb, struct rtattr *est, int new)
 {
-	struct route4_head *head = tp->root;
-	struct route4_filter *f, *f1, **ins_f;
-	struct route4_bucket *b;
-	struct rtattr *opt = tca[TCA_OPTIONS-1];
-	struct rtattr *tb[TCA_ROUTE4_MAX];
-	unsigned h1, h2;
 	int err;
+	u32 id = 0, to = 0, nhandle = 0x8000;
+	struct route4_filter *fp;
+	unsigned int h1;
+	struct route4_bucket *b;
+	struct tcf_exts e;
 
-	if (opt == NULL)
-		return handle ? -EINVAL : 0;
-
-	if (rtattr_parse(tb, TCA_ROUTE4_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
-		return -EINVAL;
-
-	if ((f = (struct route4_filter*)*arg) != NULL) {
-		if (f->handle != handle && handle)
-			return -EINVAL;
-		if (tb[TCA_ROUTE4_CLASSID-1]) {
-			f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
-			tcf_bind_filter(tp, &f->res, base);
-		}
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tb[TCA_ROUTE4_POLICE-1]) {
-			err = tcf_change_police(tp, &f->police,
-				tb[TCA_ROUTE4_POLICE-1], tca[TCA_RATE-1]);
-			if (err < 0)
-				return err;
-		}
-#endif
-		return 0;
-	}
-
-	/* Now more serious part... */
-
-	if (head == NULL) {
-		head = kmalloc(sizeof(struct route4_head), GFP_KERNEL);
-		if (head == NULL)
-			return -ENOBUFS;
-		memset(head, 0, sizeof(struct route4_head));
-
-		tcf_tree_lock(tp);
-		tp->root = head;
-		tcf_tree_unlock(tp);
-	}
-
-	f = kmalloc(sizeof(struct route4_filter), GFP_KERNEL);
-	if (f == NULL)
-		return -ENOBUFS;
-
-	memset(f, 0, sizeof(*f));
+	err = tcf_exts_validate(tp, tb, est, &e, &route_ext_map);
+	if (err < 0)
+		return err;
 
 	err = -EINVAL;
-	f->handle = 0x8000;
+	if (tb[TCA_ROUTE4_CLASSID-1])
+		if (RTA_PAYLOAD(tb[TCA_ROUTE4_CLASSID-1]) < sizeof(u32))
+			goto errout;
+
 	if (tb[TCA_ROUTE4_TO-1]) {
-		if (handle&0x8000)
+		if (new && handle & 0x8000)
 			goto errout;
-		if (RTA_PAYLOAD(tb[TCA_ROUTE4_TO-1]) < 4)
+		if (RTA_PAYLOAD(tb[TCA_ROUTE4_TO-1]) < sizeof(u32))
 			goto errout;
-		f->id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_TO-1]);
-		if (f->id > 0xFF)
+		to = *(u32*)RTA_DATA(tb[TCA_ROUTE4_TO-1]);
+		if (to > 0xFF)
 			goto errout;
-		f->handle = f->id;
+		nhandle = to;
 	}
+
 	if (tb[TCA_ROUTE4_FROM-1]) {
-		u32 sid;
 		if (tb[TCA_ROUTE4_IIF-1])
 			goto errout;
-		if (RTA_PAYLOAD(tb[TCA_ROUTE4_FROM-1]) < 4)
+		if (RTA_PAYLOAD(tb[TCA_ROUTE4_FROM-1]) < sizeof(u32))
 			goto errout;
-		sid = (*(u32*)RTA_DATA(tb[TCA_ROUTE4_FROM-1]));
-		if (sid > 0xFF)
+		id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_FROM-1]);
+		if (id > 0xFF)
 			goto errout;
-		f->handle |= sid<<16;
-		f->id |= sid<<16;
+		nhandle |= id << 16;
 	} else if (tb[TCA_ROUTE4_IIF-1]) {
-		if (RTA_PAYLOAD(tb[TCA_ROUTE4_IIF-1]) < 4)
+		if (RTA_PAYLOAD(tb[TCA_ROUTE4_IIF-1]) < sizeof(u32))
 			goto errout;
-		f->iif = *(u32*)RTA_DATA(tb[TCA_ROUTE4_IIF-1]);
-		if (f->iif > 0x7FFF)
+		id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_IIF-1]);
+		if (id > 0x7FFF)
 			goto errout;
-		f->handle |= (f->iif|0x8000)<<16;
+		nhandle = (id | 0x8000) << 16;
 	} else
-		f->handle |= 0xFFFF<<16;
+		nhandle = 0xFFFF << 16;
 
-	if (handle) {
-		f->handle |= handle&0x7F00;
-		if (f->handle != handle)
+	if (handle && new) {
+		nhandle |= handle & 0x7F00;
+		if (nhandle != handle)
 			goto errout;
 	}
 
-	if (tb[TCA_ROUTE4_CLASSID-1]) {
-		if (RTA_PAYLOAD(tb[TCA_ROUTE4_CLASSID-1]) < 4)
-			goto errout;
-		f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
-	}
-
-	h1 = to_hash(f->handle);
+	h1 = to_hash(nhandle);
 	if ((b = head->table[h1]) == NULL) {
 		err = -ENOBUFS;
 		b = kmalloc(sizeof(struct route4_bucket), GFP_KERNEL);
@@ -463,27 +405,119 @@
 		tcf_tree_lock(tp);
 		head->table[h1] = b;
 		tcf_tree_unlock(tp);
+	} else {
+		unsigned int h2 = from_hash(nhandle >> 16);
+		err = -EEXIST;
+		for (fp = b->ht[h2]; fp; fp = fp->next)
+			if (fp->handle == f->handle)
+				goto errout;
 	}
+
+	tcf_tree_lock(tp);
+	if (tb[TCA_ROUTE4_TO-1])
+		f->id = to;
+
+	if (tb[TCA_ROUTE4_FROM-1])
+		f->id = to | id<<16;
+	else if (tb[TCA_ROUTE4_IIF-1])
+		f->iif = id;
+
+	f->handle = nhandle;
 	f->bkt = b;
+	tcf_tree_unlock(tp);
 
-	err = -EEXIST;
-	h2 = from_hash(f->handle>>16);
-	for (ins_f = &b->ht[h2]; (f1=*ins_f) != NULL; ins_f = &f1->next) {
-		if (f->handle < f1->handle)
-			break;
-		if (f1->handle == f->handle)
+	if (tb[TCA_ROUTE4_CLASSID-1]) {
+		f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
+		tcf_bind_filter(tp, &f->res, base);
+	}
+
+	tcf_exts_change(tp, &f->exts, &e);
+
+	return 0;
+errout:
+	tcf_exts_destroy(tp, &e);
+	return err;
+}
+
+static int route4_change(struct tcf_proto *tp, unsigned long base,
+		       u32 handle,
+		       struct rtattr **tca,
+		       unsigned long *arg)
+{
+	struct route4_head *head = tp->root;
+	struct route4_filter *f, *f1, **fp;
+	struct route4_bucket *b;
+	struct rtattr *opt = tca[TCA_OPTIONS-1];
+	struct rtattr *tb[TCA_ROUTE4_MAX];
+	unsigned int h, th;
+	u32 old_handle = 0;
+	int err;
+
+	if (opt == NULL)
+		return handle ? -EINVAL : 0;
+
+	if (rtattr_parse_nested(tb, TCA_ROUTE4_MAX, opt) < 0)
+		return -EINVAL;
+
+	if ((f = (struct route4_filter*)*arg) != NULL) {
+		if (f->handle != handle && handle)
+			return -EINVAL;
+
+		if (f->bkt)
+			old_handle = f->handle;
+
+		err = route4_set_parms(tp, base, f, handle, head, tb,
+			tca[TCA_RATE-1], 0);
+		if (err < 0)
+			return err;
+
+		goto reinsert;
+	}
+
+	err = -ENOBUFS;
+	if (head == NULL) {
+		head = kmalloc(sizeof(struct route4_head), GFP_KERNEL);
+		if (head == NULL)
 			goto errout;
+		memset(head, 0, sizeof(struct route4_head));
+
+		tcf_tree_lock(tp);
+		tp->root = head;
+		tcf_tree_unlock(tp);
 	}
 
-	tcf_bind_filter(tp, &f->res, base);
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_ROUTE4_POLICE-1])
-		tcf_change_police(tp, &f->police, tb[TCA_ROUTE4_POLICE-1], tca[TCA_RATE-1]);
-#endif
+	f = kmalloc(sizeof(struct route4_filter), GFP_KERNEL);
+	if (f == NULL)
+		goto errout;
+	memset(f, 0, sizeof(*f));
+
+	err = route4_set_parms(tp, base, f, handle, head, tb,
+		tca[TCA_RATE-1], 1);
+	if (err < 0)
+		goto errout;
+
+reinsert:
+	h = from_hash(f->handle >> 16);
+	for (fp = &f->bkt->ht[h]; (f1=*fp) != NULL; fp = &f1->next)
+		if (f->handle < f1->handle)
+			break;
 
 	f->next = f1;
 	tcf_tree_lock(tp);
-	*ins_f = f;
+	*fp = f;
+
+	if (old_handle && f->handle != old_handle) {
+		th = to_hash(old_handle);
+		h = from_hash(old_handle >> 16);
+		if ((b = head->table[th]) != NULL) {
+			for (fp = &b->ht[h]; *fp; fp = &(*fp)->next) {
+				if (*fp == f) {
+					*fp = f->next;
+					break;
+				}
+			}
+		}
+	}
 	tcf_tree_unlock(tp);
 
 	route4_reset_fastmap(tp->q->dev, head, f->id);
@@ -559,17 +593,15 @@
 	}
 	if (f->res.classid)
 		RTA_PUT(skb, TCA_ROUTE4_CLASSID, 4, &f->res.classid);
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tcf_dump_police(skb, f->police, TCA_ROUTE4_POLICE) < 0)
+
+	if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0)
 		goto rtattr_failure;
-#endif
 
 	rta->rta_len = skb->tail - b;
-#ifdef CONFIG_NET_CLS_POLICE
-	if (f->police)
-		if (tcf_police_dump_stats(skb, f->police) < 0)
-			goto rtattr_failure;
-#endif
+
+	if (tcf_exts_dump_stats(skb, &f->exts, &route_ext_map) < 0)
+		goto rtattr_failure;
+
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
--- a/net/sched/cls_rsvp.h	2005-01-19 13:44:45 -08:00
+++ b/net/sched/cls_rsvp.h	2005-01-19 13:44:45 -08:00
@@ -95,9 +95,7 @@
 	u8			tunnelhdr;
 
 	struct tcf_result	res;
-#ifdef CONFIG_NET_CLS_POLICE
-	struct tcf_police	*police;
-#endif
+	struct tcf_exts		exts;
 
 	u32			handle;
 	struct rsvp_session	*sess;
@@ -120,18 +118,20 @@
 	return h & 0xF;
 }
 
-#ifdef CONFIG_NET_CLS_POLICE
-#define RSVP_POLICE() \
-if (f->police) { \
-	int pol_res = tcf_police(skb, f->police); \
-	if (pol_res < 0) continue; \
-	if (pol_res) return pol_res; \
-}
-#else
-#define RSVP_POLICE()
-#endif
-
+static struct tcf_ext_map rsvp_ext_map = {
+	.police = TCA_RSVP_POLICE,
+	.action = TCA_RSVP_ACT
+};
 
+#define RSVP_APPLY_RESULT()					\
+	do {							\
+		int r = tcf_exts_exec(skb, &f->exts, res);	\
+		if (r < 0)					\
+			continue;				\
+		else if (r > 0)					\
+			return r;				\
+	} while(0)
+	
 static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
 			 struct tcf_result *res)
 {
@@ -189,8 +189,7 @@
 #endif
 				    ) {
 					*res = f->res;
-
-					RSVP_POLICE();
+					RSVP_APPLY_RESULT();
 
 matched:
 					if (f->tunnelhdr == 0)
@@ -205,7 +204,7 @@
 			/* And wildcard bucket... */
 			for (f = s->ht[16]; f; f = f->next) {
 				*res = f->res;
-				RSVP_POLICE();
+				RSVP_APPLY_RESULT();
 				goto matched;
 			}
 			return -1;
@@ -251,6 +250,14 @@
 	return -ENOBUFS;
 }
 
+static inline void
+rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f)
+{
+	tcf_unbind_filter(tp, &f->res);
+	tcf_exts_destroy(tp, &f->exts);
+	kfree(f);
+}
+
 static void rsvp_destroy(struct tcf_proto *tp)
 {
 	struct rsvp_head *data = xchg(&tp->root, NULL);
@@ -273,11 +280,7 @@
 
 				while ((f = s->ht[h2]) != NULL) {
 					s->ht[h2] = f->next;
-					tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_POLICE
-					tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-					kfree(f);
+					rsvp_delete_filter(tp, f);
 				}
 			}
 			kfree(s);
@@ -299,12 +302,7 @@
 			tcf_tree_lock(tp);
 			*fp = f->next;
 			tcf_tree_unlock(tp);
-			tcf_unbind_filter(tp, &f->res);
-#ifdef CONFIG_NET_CLS_POLICE
-			tcf_police_release(f->police,TCA_ACT_UNBIND);
-#endif
-
-			kfree(f);
+			rsvp_delete_filter(tp, f);
 
 			/* Strip tree */
 
@@ -412,6 +410,7 @@
 	struct tc_rsvp_pinfo *pinfo = NULL;
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct rtattr *tb[TCA_RSVP_MAX];
+	struct tcf_exts e;
 	unsigned h1, h2;
 	u32 *dst;
 	int err;
@@ -419,38 +418,38 @@
 	if (opt == NULL)
 		return handle ? -EINVAL : 0;
 
-	if (rtattr_parse(tb, TCA_RSVP_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
+	if (rtattr_parse_nested(tb, TCA_RSVP_MAX, opt) < 0)
 		return -EINVAL;
 
+	err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &rsvp_ext_map);
+	if (err < 0)
+		return err;
+
 	if ((f = (struct rsvp_filter*)*arg) != NULL) {
 		/* Node exists: adjust only classid */
 
 		if (f->handle != handle && handle)
-			return -EINVAL;
+			goto errout2;
 		if (tb[TCA_RSVP_CLASSID-1]) {
 			f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]);
 			tcf_bind_filter(tp, &f->res, base);
 		}
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tb[TCA_RSVP_POLICE-1]) {
-			err = tcf_change_police(tp, &f->police,
-				tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
-			if (err < 0)
-				return err;
-		}
-#endif
+
+		tcf_exts_change(tp, &f->exts, &e);
 		return 0;
 	}
 
 	/* Now more serious part... */
+	err = -EINVAL;
 	if (handle)
-		return -EINVAL;
+		goto errout2;
 	if (tb[TCA_RSVP_DST-1] == NULL)
-		return -EINVAL;
+		goto errout2;
 
+	err = -ENOBUFS;
 	f = kmalloc(sizeof(struct rsvp_filter), GFP_KERNEL);
 	if (f == NULL)
-		return -ENOBUFS;
+		goto errout2;
 
 	memset(f, 0, sizeof(*f));
 	h2 = 16;
@@ -516,10 +515,8 @@
 			f->sess = s;
 			if (f->tunnelhdr == 0)
 				tcf_bind_filter(tp, &f->res, base);
-#ifdef CONFIG_NET_CLS_POLICE
-			if (tb[TCA_RSVP_POLICE-1])
-				tcf_change_police(tp, &f->police, tb[TCA_RSVP_POLICE-1], tca[TCA_RATE-1]);
-#endif
+
+			tcf_exts_change(tp, &f->exts, &e);
 
 			for (fp = &s->ht[h2]; *fp; fp = &(*fp)->next)
 				if (((*fp)->spi.mask&f->spi.mask) != f->spi.mask)
@@ -560,6 +557,8 @@
 errout:
 	if (f)
 		kfree(f);
+errout2:
+	tcf_exts_destroy(tp, &e);
 	return err;
 }
 
@@ -624,17 +623,14 @@
 		RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid);
 	if (((f->handle>>8)&0xFF) != 16)
 		RTA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src);
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tcf_dump_police(skb, f->police, TCA_RSVP_POLICE) < 0)
+
+	if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0)
 		goto rtattr_failure;
-#endif
 
 	rta->rta_len = skb->tail - b;
-#ifdef CONFIG_NET_CLS_POLICE
-	if (f->police)
-		if (tcf_police_dump_stats(skb, f->police) < 0)
-			goto rtattr_failure;
-#endif
+
+	if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0)
+		goto rtattr_failure;
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
--- a/net/sched/cls_tcindex.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/cls_tcindex.c	2005-01-19 13:44:46 -08:00
@@ -49,12 +49,12 @@
 
 
 struct tcindex_filter_result {
-	struct tcf_police *police;
-	struct tcf_result res;
+	struct tcf_exts		exts;
+	struct tcf_result	res;
 };
 
 struct tcindex_filter {
-	__u16 key;
+	u16 key;
 	struct tcindex_filter_result result;
 	struct tcindex_filter *next;
 };
@@ -64,60 +64,64 @@
 	struct tcindex_filter_result *perfect; /* perfect hash; NULL if none */
 	struct tcindex_filter **h; /* imperfect hash; only used if !perfect;
 				      NULL if unused */
-	__u16 mask;		/* AND key with mask */
+	u16 mask;		/* AND key with mask */
 	int shift;		/* shift ANDed key to the right */
 	int hash;		/* hash table size; 0 if undefined */
 	int alloc_hash;		/* allocated size */
 	int fall_through;	/* 0: only classify if explicit match */
 };
 
+static struct tcf_ext_map tcindex_ext_map = {
+	.police = TCA_TCINDEX_POLICE,
+	.action = TCA_TCINDEX_ACT
+};
+
+static inline int
+tcindex_filter_is_set(struct tcindex_filter_result *r)
+{
+	return tcf_exts_is_predicative(&r->exts) || r->res.classid;
+}
 
-static struct tcindex_filter_result *lookup(struct tcindex_data *p,__u16 key)
+static struct tcindex_filter_result *
+tcindex_lookup(struct tcindex_data *p, u16 key)
 {
 	struct tcindex_filter *f;
 
 	if (p->perfect)
-		return p->perfect[key].res.class ? p->perfect+key : NULL;
-	if (!p->h)
-		return NULL;
-	for (f = p->h[key % p->hash]; f; f = f->next) {
-		if (f->key == key)
-			return &f->result;
+		return tcindex_filter_is_set(p->perfect + key) ?
+			p->perfect + key : NULL;
+	else if (p->h) {
+		for (f = p->h[key % p->hash]; f; f = f->next)
+			if (f->key == key)
+				return &f->result;
 	}
+
 	return NULL;
 }
 
 
 static int tcindex_classify(struct sk_buff *skb, struct tcf_proto *tp,
-			  struct tcf_result *res)
+			    struct tcf_result *res)
 {
 	struct tcindex_data *p = PRIV(tp);
 	struct tcindex_filter_result *f;
+	int key = (skb->tc_index & p->mask) >> p->shift;
 
 	D2PRINTK("tcindex_classify(skb %p,tp %p,res %p),p %p\n",skb,tp,res,p);
 
-	f = lookup(p,(skb->tc_index & p->mask) >> p->shift);
+	f = tcindex_lookup(p, key);
 	if (!f) {
 		if (!p->fall_through)
 			return -1;
-		res->classid = TC_H_MAKE(TC_H_MAJ(tp->q->handle),
-		    (skb->tc_index& p->mask) >> p->shift);
+		res->classid = TC_H_MAKE(TC_H_MAJ(tp->q->handle), key);
 		res->class = 0;
 		D2PRINTK("alg 0x%x\n",res->classid);
 		return 0;
 	}
 	*res = f->res;
 	D2PRINTK("map 0x%x\n",res->classid);
-#ifdef CONFIG_NET_CLS_POLICE
-	if (f->police) {
-		int result;
-
-		result = tcf_police(skb,f->police);
-		D2PRINTK("police %d\n",res);
-		return result;
-	}
-#endif
-	return 0;
+
+	return tcf_exts_exec(skb, &f->exts, res);
 }
 
 
@@ -129,8 +133,8 @@
 	DPRINTK("tcindex_get(tp %p,handle 0x%08x)\n",tp,handle);
 	if (p->perfect && handle >= p->alloc_hash)
 		return 0;
-	r = lookup(PRIV(tp),handle);
-	return r && r->res.class ? (unsigned long) r : 0;
+	r = tcindex_lookup(p, handle);
+	return r && tcindex_filter_is_set(r) ? (unsigned long) r : 0UL;
 }
 
 
@@ -149,13 +153,12 @@
 	if (!p)
 		return -ENOMEM;
 
-	tp->root = p;
-	p->perfect = NULL;
-	p->h = NULL;
-	p->hash = 0;
+	memset(p, 0, sizeof(*p));
 	p->mask = 0xffff;
-	p->shift = 0;
+	p->hash = DEFAULT_HASH_SIZE;
 	p->fall_through = 1;
+
+	tp->root = p;
 	return 0;
 }
 
@@ -190,9 +193,7 @@
 			tcf_tree_unlock(tp);
 	}
 	tcf_unbind_filter(tp, &r->res);
-#ifdef CONFIG_NET_CLS_POLICE
-	tcf_police_release(r->police, TCA_ACT_UNBIND);
-#endif
+	tcf_exts_destroy(tp, &r->exts);
 	if (f)
 		kfree(f);
 	return 0;
@@ -203,148 +204,184 @@
 	return __tcindex_delete(tp, arg, 1);
 }
 
-/*
- * There are no parameters for tcindex_init, so we overload tcindex_change
- */
+static inline int
+valid_perfect_hash(struct tcindex_data *p)
+{
+	return  p->hash > (p->mask >> p->shift);
+}
+
+static int
+tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
+		  struct tcindex_data *p, struct tcindex_filter_result *r,
+		  struct rtattr **tb, struct rtattr *est)
+{
+	int err, balloc = 0;
+	struct tcindex_filter_result new_filter_result, *old_r = r;
+	struct tcindex_filter_result cr;
+	struct tcindex_data cp;
+	struct tcindex_filter *f = NULL; /* make gcc behave */
+	struct tcf_exts e;
+
+	err = tcf_exts_validate(tp, tb, est, &e, &tcindex_ext_map);
+	if (err < 0)
+		return err;
+	
+	memcpy(&cp, p, sizeof(cp));
+	memset(&new_filter_result, 0, sizeof(new_filter_result));
+
+	if (old_r)
+		memcpy(&cr, r, sizeof(cr));
+	else
+		memset(&cr, 0, sizeof(cr));
+
+	err = -EINVAL;
+	if (tb[TCA_TCINDEX_HASH-1]) {
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH-1]) < sizeof(u32))
+			goto errout;
+		cp.hash = *(u32 *) RTA_DATA(tb[TCA_TCINDEX_HASH-1]);
+	}
+
+	if (tb[TCA_TCINDEX_MASK-1]) {
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK-1]) < sizeof(u16))
+			goto errout;
+		cp.mask = *(u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK-1]);
+	}
+
+	if (tb[TCA_TCINDEX_SHIFT-1]) {
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(u16))
+			goto errout;
+		cp.shift = *(u16 *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
+	}
+
+	err = -EBUSY;
+	/* Hash already allocated, make sure that we still meet the
+	 * requirements for the allocated hash.
+	 */
+	if (cp.perfect) {
+		if (!valid_perfect_hash(&cp) ||
+		    cp.hash > cp.alloc_hash)
+			goto errout;
+	} else if (cp.h && cp.hash != cp.alloc_hash)
+		goto errout;
+
+	err = -EINVAL;
+	if (tb[TCA_TCINDEX_FALL_THROUGH-1]) {
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH-1]) < sizeof(u32))
+			goto errout;
+		cp.fall_through =
+			*(u32 *) RTA_DATA(tb[TCA_TCINDEX_FALL_THROUGH-1]);
+	}
+
+	if (!cp.hash) {
+		/* Hash not specified, use perfect hash if the upper limit
+		 * of the hashing index is below the threshold.
+		 */
+		if ((cp.mask >> cp.shift) < PERFECT_HASH_THRESHOLD)
+			cp.hash = (cp.mask >> cp.shift)+1;
+		else
+			cp.hash = DEFAULT_HASH_SIZE;
+	}
+
+	if (!cp.perfect && !cp.h)
+		cp.alloc_hash = cp.hash;
+
+	/* Note: this could be as restrictive as if (handle & ~(mask >> shift))
+	 * but then, we'd fail handles that may become valid after some future
+	 * mask change. While this is extremely unlikely to ever matter,
+	 * the check below is safer (and also more backwards-compatible).
+	 */
+	if (cp.perfect || valid_perfect_hash(&cp))
+		if (handle >= cp.alloc_hash)
+			goto errout;
+
+
+	err = -ENOMEM;
+	if (!cp.perfect && !cp.h) {
+		if (valid_perfect_hash(&cp)) {
+			cp.perfect = kmalloc(cp.hash * sizeof(*r), GFP_KERNEL);
+			if (!cp.perfect)
+				goto errout;
+			memset(cp.perfect, 0, cp.hash * sizeof(*r));
+			balloc = 1;
+		} else {
+			cp.h = kmalloc(cp.hash * sizeof(f), GFP_KERNEL);
+			if (!cp.h)
+				goto errout;
+			memset(cp.h, 0, cp.hash * sizeof(f));
+			balloc = 2;
+		}
+	}
+
+	if (cp.perfect)
+		r = cp.perfect + handle;
+	else
+		r = tcindex_lookup(&cp, handle) ? : &new_filter_result;
+
+	if (r == &new_filter_result) {
+		f = kmalloc(sizeof(*f), GFP_KERNEL);
+		if (!f)
+			goto errout_alloc;
+		memset(f, 0, sizeof(*f));
+ 	}
+
+	if (tb[TCA_TCINDEX_CLASSID-1]) {
+		cr.res.classid = *(u32 *) RTA_DATA(tb[TCA_TCINDEX_CLASSID-1]);
+		tcf_bind_filter(tp, &cr.res, base);
+ 	}
+
+	tcf_exts_change(tp, &cr.exts, &e);
+
+	tcf_tree_lock(tp);
+	if (old_r && old_r != r)
+		memset(old_r, 0, sizeof(*old_r));
+
+	memcpy(p, &cp, sizeof(cp));
+	memcpy(r, &cr, sizeof(cr));
+
+	if (r == &new_filter_result) {
+		struct tcindex_filter **fp;
+
+		f->key = handle;
+		f->result = new_filter_result;
+		f->next = NULL;
+		for (fp = p->h+(handle % p->hash); *fp; fp = &(*fp)->next)
+			/* nothing */;
+		*fp = f;
+ 	}
+	tcf_tree_unlock(tp);
+
+	return 0;
 
+errout_alloc:
+	if (balloc == 1)
+		kfree(cp.perfect);
+	else if (balloc == 2)
+		kfree(cp.h);
+errout:
+	tcf_exts_destroy(tp, &e);
+	return err;
+}
 
-static int tcindex_change(struct tcf_proto *tp,unsigned long base,u32 handle,
-    struct rtattr **tca,unsigned long *arg)
-{
-	struct tcindex_filter_result new_filter_result = {
-		NULL,		/* no policing */
-		{ 0,0 },	/* no classification */
-	};
+static int
+tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle,
+	       struct rtattr **tca, unsigned long *arg)
+{
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct rtattr *tb[TCA_TCINDEX_MAX];
 	struct tcindex_data *p = PRIV(tp);
-	struct tcindex_filter *f;
 	struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg;
-	struct tcindex_filter **walk;
-	int hash,shift;
-	__u16 mask;
 
 	DPRINTK("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
-	    "p %p,r %p\n",tp,handle,tca,arg,opt,p,r);
-	if (arg)
-		DPRINTK("*arg = 0x%lx\n",*arg);
+	    "p %p,r %p,*arg 0x%lx\n",
+	    tp, handle, tca, arg, opt, p, r, arg ? *arg : 0L);
+
 	if (!opt)
 		return 0;
-	if (rtattr_parse(tb,TCA_TCINDEX_MAX,RTA_DATA(opt),RTA_PAYLOAD(opt)) < 0)
-		return -EINVAL;
-	if (!tb[TCA_TCINDEX_HASH-1]) {
-		hash = p->hash;
-	} else {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH-1]) < sizeof(int))
-			return -EINVAL;
-		hash = *(int *) RTA_DATA(tb[TCA_TCINDEX_HASH-1]);
-	}
-	if (!tb[TCA_TCINDEX_MASK-1]) {
-		mask = p->mask;
-	} else {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK-1]) < sizeof(__u16))
-			return -EINVAL;
-		mask = *(__u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK-1]);
-	}
-	if (!tb[TCA_TCINDEX_SHIFT-1])
-		shift = p->shift;
-	else {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(__u16))
-			return -EINVAL;
-		shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
-	}
-	if (p->perfect && hash <= (mask >> shift))
-		return -EBUSY;
-	if (p->perfect && hash > p->alloc_hash)
-		return -EBUSY;
-	if (p->h && hash != p->alloc_hash)
-		return -EBUSY;
-	p->hash = hash;
-	p->mask = mask;
-	p->shift = shift;
-	if (tb[TCA_TCINDEX_FALL_THROUGH-1]) {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH-1]) < sizeof(int))
-			return -EINVAL;
-		p->fall_through =
-		    *(int *) RTA_DATA(tb[TCA_TCINDEX_FALL_THROUGH-1]);
-	}
-	DPRINTK("classid/police %p/%p\n",tb[TCA_TCINDEX_CLASSID-1],
-	    tb[TCA_TCINDEX_POLICE-1]);
-	if (!tb[TCA_TCINDEX_CLASSID-1] && !tb[TCA_TCINDEX_POLICE-1])
-		return 0;
-	if (!hash) {
-		if ((mask >> shift) < PERFECT_HASH_THRESHOLD) {
-			p->hash = (mask >> shift)+1;
-		} else {
-			p->hash = DEFAULT_HASH_SIZE;
-		}
-	}
-	if (!p->perfect && !p->h) {
-		p->alloc_hash = p->hash;
-		DPRINTK("hash %d mask %d\n",p->hash,p->mask);
-		if (p->hash > (mask >> shift)) {
-			p->perfect = kmalloc(p->hash*
-			    sizeof(struct tcindex_filter_result),GFP_KERNEL);
-			if (!p->perfect)
-				return -ENOMEM;
-			memset(p->perfect, 0,
-			       p->hash * sizeof(struct tcindex_filter_result));
-		} else {
-			p->h = kmalloc(p->hash*sizeof(struct tcindex_filter *),
-			    GFP_KERNEL);
-			if (!p->h)
-				return -ENOMEM;
-			memset(p->h, 0, p->hash*sizeof(struct tcindex_filter *));
-		}
-	}
-	/*
-	 * Note: this could be as restrictive as
-	 * if (handle & ~(mask >> shift))
-	 * but then, we'd fail handles that may become valid after some
-	 * future mask change. While this is extremely unlikely to ever
-	 * matter, the check below is safer (and also more
-	 * backwards-compatible).
-	 */
-	if (p->perfect && handle >= p->alloc_hash)
+
+	if (rtattr_parse_nested(tb, TCA_TCINDEX_MAX, opt) < 0)
 		return -EINVAL;
-	if (p->perfect) {
-		r = p->perfect+handle;
-	} else {
-		r = lookup(p,handle);
-		DPRINTK("r=%p\n",r);
-		if (!r)
-			r = &new_filter_result;
-	}
-	DPRINTK("r=%p\n",r);
-	if (tb[TCA_TCINDEX_CLASSID-1]) {
-		r->res.classid = *(__u32 *) RTA_DATA(tb[TCA_TCINDEX_CLASSID-1]);
-		tcf_bind_filter(tp, &r->res, base);
 
-		if (!r->res.class) {
-			r->res.classid = 0;
-			return -ENOENT;
-		}
-	}
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_TCINDEX_POLICE-1]) {
-		int err = tcf_change_police(tp, &r->police, tb[TCA_TCINDEX_POLICE-1], NULL);
-		if (err < 0)
-			return err;
-	}
-#endif
-	if (r != &new_filter_result)
-		return 0;
-	f = kmalloc(sizeof(struct tcindex_filter),GFP_KERNEL);
-	if (!f)
-		return -ENOMEM;
-	f->key = handle;
-	f->result = new_filter_result;
-	f->next = NULL;
-	for (walk = p->h+(handle % p->hash); *walk; walk = &(*walk)->next)
-		/* nothing */;
-	wmb();
-	*walk = f;
-	return 0;
+	return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE-1]);
 }
 
 
@@ -434,6 +471,7 @@
 		RTA_PUT(skb,TCA_TCINDEX_SHIFT,sizeof(p->shift),&p->shift);
 		RTA_PUT(skb,TCA_TCINDEX_FALL_THROUGH,sizeof(p->fall_through),
 		    &p->fall_through);
+		rta->rta_len = skb->tail-b;
 	} else {
 		if (p->perfect) {
 			t->tcm_handle = r-p->perfect;
@@ -453,12 +491,15 @@
 		DPRINTK("handle = %d\n",t->tcm_handle);
 		if (r->res.class)
 			RTA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid);
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tcf_dump_police(skb, r->police, TCA_TCINDEX_POLICE) < 0)
+
+		if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0)
+			goto rtattr_failure;
+		rta->rta_len = skb->tail-b;
+
+		if (tcf_exts_dump_stats(skb, &r->exts, &tcindex_ext_map) < 0)
 			goto rtattr_failure;
-#endif
 	}
-	rta->rta_len = skb->tail-b;
+	
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/cls_u32.c b/net/sched/cls_u32.c
--- a/net/sched/cls_u32.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/cls_u32.c	2005-01-19 13:44:46 -08:00
@@ -61,9 +61,9 @@
 
 struct tc_u32_mark
 {
-	__u32		val;
-	__u32		mask;
-	__u32		success;
+	u32		val;
+	u32		mask;
+	u32		success;
 };
 
 struct tc_u_knode
@@ -71,13 +71,7 @@
 	struct tc_u_knode	*next;
 	u32			handle;
 	struct tc_u_hnode	*ht_up;
-#ifdef CONFIG_NET_CLS_ACT
-	struct tc_action	*action;
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	struct tcf_police	*police;
-#endif
-#endif
+	struct tcf_exts		exts;
 #ifdef CONFIG_NET_CLS_IND
 	char                     indev[IFNAMSIZ];
 #endif
@@ -112,6 +106,11 @@
 	u32			hgenerator;
 };
 
+static struct tcf_ext_map u32_ext_map = {
+	.action = TCA_U32_ACT,
+	.police = TCA_U32_POLICE
+};
+
 static struct tc_u_common *u32_list;
 
 static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
@@ -137,7 +136,7 @@
 #ifdef CONFIG_CLS_U32_PERF
 	int j;
 #endif
-	int i;
+	int i, r;
 
 next_ht:
 	n = ht->ht[sel];
@@ -185,22 +184,13 @@
 #ifdef CONFIG_CLS_U32_PERF
 				n->pf->rhit +=1;
 #endif
-#ifdef CONFIG_NET_CLS_ACT
-				if (n->action) {
-					int pol_res = tcf_action_exec(skb, n->action, res);
-					if (pol_res >= 0)
-						return pol_res;
-				} else
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-				if (n->police) {
-					int pol_res = tcf_police(skb, n->police);
-					if (pol_res >= 0)
-						return pol_res;
-				} else
-#endif
-#endif
-					return 0;
+				r = tcf_exts_exec(skb, &n->exts, res);
+				if (r < 0) {
+					n = n->next;
+					goto next_knode;
+				}
+
+				return r;
 			}
 			n = n->next;
 			goto next_knode;
@@ -359,15 +349,7 @@
 static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n)
 {
 	tcf_unbind_filter(tp, &n->res);
-#ifdef CONFIG_NET_CLS_ACT
-	if (n->action) {
-		tcf_action_destroy(n->action, TCA_ACT_UNBIND);
-	}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	tcf_police_release(n->police, TCA_ACT_UNBIND);
-#endif
-#endif
+	tcf_exts_destroy(tp, &n->exts);
 	if (n->ht_down)
 		n->ht_down->refcnt--;
 #ifdef CONFIG_CLS_U32_PERF
@@ -509,18 +491,26 @@
 			 struct tc_u_knode *n, struct rtattr **tb,
 			 struct rtattr *est)
 {
+	int err;
+	struct tcf_exts e;
+
+	err = tcf_exts_validate(tp, tb, est, &e, &u32_ext_map);
+	if (err < 0)
+		return err;
+
+	err = -EINVAL;
 	if (tb[TCA_U32_LINK-1]) {
 		u32 handle = *(u32*)RTA_DATA(tb[TCA_U32_LINK-1]);
 		struct tc_u_hnode *ht_down = NULL;
 
 		if (TC_U32_KEY(handle))
-			return -EINVAL;
+			goto errout;
 
 		if (handle) {
 			ht_down = u32_lookup_ht(ht->tp_c, handle);
 
 			if (ht_down == NULL)
-				return -EINVAL;
+				goto errout;
 			ht_down->refcnt++;
 		}
 
@@ -535,36 +525,20 @@
 		n->res.classid = *(u32*)RTA_DATA(tb[TCA_U32_CLASSID-1]);
 		tcf_bind_filter(tp, &n->res, base);
 	}
-#ifdef CONFIG_NET_CLS_ACT
-	if (tb[TCA_U32_POLICE-1]) {
-		int err = tcf_change_act_police(tp, &n->action, tb[TCA_U32_POLICE-1], est);
-		if (err < 0)
-			return err;
-	}
 
-	if (tb[TCA_U32_ACT-1]) {
-		int err = tcf_change_act(tp, &n->action, tb[TCA_U32_ACT-1], est);
-		if (err < 0)
-			return err;
-	}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_U32_POLICE-1]) {
-		int err = tcf_change_police(tp, &n->police, tb[TCA_U32_POLICE-1], est);
-		if (err < 0)
-			return err;
-	}
-#endif
-#endif
 #ifdef CONFIG_NET_CLS_IND
 	if (tb[TCA_U32_INDEV-1]) {
 		int err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]);
 		if (err < 0)
-			return err;
+			goto errout;
 	}
 #endif
+	tcf_exts_change(tp, &n->exts, &e);
 
 	return 0;
+errout:
+	tcf_exts_destroy(tp, &e);
+	return err;
 }
 
 static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
@@ -575,7 +549,6 @@
 	struct tc_u_hnode *ht;
 	struct tc_u_knode *n;
 	struct tc_u32_sel *s;
-	struct tc_u32_mark *mark;
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct rtattr *tb[TCA_U32_MAX];
 	u32 htid;
@@ -584,7 +557,7 @@
 	if (opt == NULL)
 		return handle ? -EINVAL : 0;
 
-	if (rtattr_parse(tb, TCA_U32_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
+	if (rtattr_parse_nested(tb, TCA_U32_MAX, opt) < 0)
 		return -EINVAL;
 
 	if ((n = (struct tc_u_knode*)*arg) != NULL) {
@@ -657,12 +630,12 @@
 
 	memset(n, 0, sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key));
 #ifdef CONFIG_CLS_U32_PERF
-	n->pf = kmalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(__u64), GFP_KERNEL);
+	n->pf = kmalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64), GFP_KERNEL);
 	if (n->pf == NULL) {
 		kfree(n);
 		return -ENOBUFS;
 	}
-	memset(n->pf, 0, sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(__u64));
+	memset(n->pf, 0, sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64));
 #endif
 
 	memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
@@ -680,15 +653,22 @@
 	n->fshift = i;
 }
 
-#ifdef CONFIG_CLS_U32_MARK                                                                                                                                             
+#ifdef CONFIG_CLS_U32_MARK
 	if (tb[TCA_U32_MARK-1]) {
-		if (RTA_PAYLOAD(tb[TCA_U32_MARK-1]) < sizeof(struct tc_u32_mark))
+		struct tc_u32_mark *mark;
+
+		if (RTA_PAYLOAD(tb[TCA_U32_MARK-1]) < sizeof(struct tc_u32_mark)) {
+#ifdef CONFIG_CLS_U32_PERF
+			kfree(n->pf);
+#endif
+			kfree(n);
 			return -EINVAL;
+		}
 		mark = RTA_DATA(tb[TCA_U32_MARK-1]);
 		memcpy(&n->mark, mark, sizeof(struct tc_u32_mark));
 		n->mark.success = 0;
-	}                                                                                                                                                                
-#endif                                                                                                                                                                 
+	}
+#endif
 
 	err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE-1]);
 	if (err == 0) {
@@ -783,15 +763,8 @@
 			RTA_PUT(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark);
 #endif
 
-#ifdef CONFIG_NET_CLS_ACT
-		if (tcf_dump_act(skb, n->action, TCA_U32_ACT, TCA_U32_POLICE) < 0)
+		if (tcf_exts_dump(skb, &n->exts, &u32_ext_map) < 0)
 			goto rtattr_failure;
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tcf_dump_police(skb, n->police, TCA_U32_POLICE) < 0)
-			goto rtattr_failure;
-#endif
-#endif
 
 #ifdef CONFIG_NET_CLS_IND
 		if(strlen(n->indev))
@@ -799,26 +772,15 @@
 #endif
 #ifdef CONFIG_CLS_U32_PERF
 		RTA_PUT(skb, TCA_U32_PCNT, 
-		sizeof(struct tc_u32_pcnt) + n->sel.nkeys*sizeof(__u64),
+		sizeof(struct tc_u32_pcnt) + n->sel.nkeys*sizeof(u64),
 			n->pf);
 #endif
 	}
 
 	rta->rta_len = skb->tail - b;
-#ifdef CONFIG_NET_CLS_ACT
-	if (TC_U32_KEY(n->handle) != 0) {
-		if (TC_U32_KEY(n->handle) && n->action && n->action->type == TCA_OLD_COMPAT) {
-			if (tcf_action_copy_stats(skb,n->action))
-				goto rtattr_failure;
-		}
-	}
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	if (TC_U32_KEY(n->handle) && n->police)
-		if (tcf_police_dump_stats(skb, n->police) < 0)
+	if (TC_U32_KEY(n->handle))
+		if (tcf_exts_dump_stats(skb, &n->exts, &u32_ext_map) < 0)
 			goto rtattr_failure;
-#endif
-#endif
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/estimator.c b/net/sched/estimator.c
--- a/net/sched/estimator.c	2005-01-19 13:44:45 -08:00
+++ b/net/sched/estimator.c	2005-01-19 13:44:45 -08:00
@@ -95,7 +95,7 @@
 static struct qdisc_estimator_head elist[EST_MAX_INTERVAL+1];
 
 /* Estimator array lock */
-static rwlock_t est_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(est_lock);
 
 static void est_timer(unsigned long arg)
 {
diff -Nru a/net/sched/gact.c b/net/sched/gact.c
--- a/net/sched/gact.c	2005-01-19 13:44:47 -08:00
+++ b/net/sched/gact.c	2005-01-19 13:44:47 -08:00
@@ -38,103 +38,98 @@
 /* use generic hash table */
 #define MY_TAB_SIZE	16
 #define MY_TAB_MASK	15
+
 static u32 idx_gen;
 static struct tcf_gact *tcf_gact_ht[MY_TAB_SIZE];
-static rwlock_t gact_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(gact_lock);
 
 /* ovewrride the defaults */
-#define tcf_st  tcf_gact
-#define tc_st  tc_gact
-#define tcf_t_lock   gact_lock
-#define tcf_ht tcf_gact_ht
+#define tcf_st		tcf_gact
+#define tc_st		tc_gact
+#define tcf_t_lock	gact_lock
+#define tcf_ht		tcf_gact_ht
 
 #define CONFIG_NET_ACT_INIT 1
 #include <net/pkt_act.h>
 
 #ifdef CONFIG_GACT_PROB
-typedef int (*g_rand)(struct tcf_gact *p);
-static int
-gact_net_rand(struct tcf_gact *p) {
+static int gact_net_rand(struct tcf_gact *p)
+{
 	if (net_random()%p->pval)
 		return p->action;
 	return p->paction;
 }
 
-static int
-gact_determ(struct tcf_gact *p) {
+static int gact_determ(struct tcf_gact *p)
+{
 	if (p->bstats.packets%p->pval)
 		return p->action;
 	return p->paction;
 }
 
-
-static g_rand gact_rand[MAX_RAND]= { NULL,gact_net_rand, gact_determ};
-
+typedef int (*g_rand)(struct tcf_gact *p);
+static g_rand gact_rand[MAX_RAND]= { NULL, gact_net_rand, gact_determ };
 #endif
-static int
-tcf_gact_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,int ovr,int bind)
+
+static int tcf_gact_init(struct rtattr *rta, struct rtattr *est,
+                         struct tc_action *a, int ovr, int bind)
 {
 	struct rtattr *tb[TCA_GACT_MAX];
-	struct tc_gact *parm = NULL;
-#ifdef CONFIG_GACT_PROB
-	struct tc_gact_p *p_parm = NULL;
-#endif
-	struct tcf_gact *p = NULL;
+	struct tc_gact *parm;
+	struct tcf_gact *p;
 	int ret = 0;
-	int size = sizeof (*p);
 
-	if (rtattr_parse(tb, TCA_GACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0)
-		return -1;
-
-	if (NULL == a || NULL == tb[TCA_GACT_PARMS - 1]) {
-		printk("BUG: tcf_gact_init called with NULL params\n");
-		return -1;
-	}
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_GACT_MAX, rta) < 0)
+		return -EINVAL;
 
+	if (tb[TCA_GACT_PARMS - 1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_GACT_PARMS - 1]) < sizeof(*parm))
+		return -EINVAL;
 	parm = RTA_DATA(tb[TCA_GACT_PARMS - 1]);
+
+	if (tb[TCA_GACT_PROB-1] != NULL)
 #ifdef CONFIG_GACT_PROB
-	if (NULL != tb[TCA_GACT_PROB - 1]) {
-		p_parm = RTA_DATA(tb[TCA_GACT_PROB - 1]);
-	}
+		if (RTA_PAYLOAD(tb[TCA_GACT_PROB-1]) < sizeof(struct tc_gact_p))
+			return -EINVAL;
+#else
+		return -EOPNOTSUPP;
 #endif
 
-	p = tcf_hash_check(parm, a, ovr, bind);
-
-	if (NULL == p) {
-		p = tcf_hash_create(parm,est,a,size,ovr, bind);
-
-		if (NULL == p) {
-			return -1;
-		} else {
-			p->refcnt = 1;
-			ret = 1;
-			goto override;
+	p = tcf_hash_check(parm->index, a, ovr, bind);
+	if (p == NULL) {
+		p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind);
+		if (p == NULL)
+			return -ENOMEM;
+		ret = ACT_P_CREATED;
+	} else {
+		if (!ovr) {
+			tcf_hash_release(p, bind);
+			return -EEXIST;
 		}
 	}
 
-	if (ovr) {
-override:
-		p->action = parm->action;
+	spin_lock_bh(&p->lock);
+	p->action = parm->action;
 #ifdef CONFIG_GACT_PROB
-		if (NULL != p_parm) {
-			p->paction = p_parm->paction;
-			p->pval = p_parm->pval;
-			p->ptype = p_parm->ptype;
-		} else {
-			p->paction = p->pval = p->ptype = 0;
-		}
-#endif
+	if (tb[TCA_GACT_PROB-1] != NULL) {
+		struct tc_gact_p *p_parm = RTA_DATA(tb[TCA_GACT_PROB-1]);
+		p->paction = p_parm->paction;
+		p->pval    = p_parm->pval;
+		p->ptype   = p_parm->ptype;
 	}
-
+#endif
+	spin_unlock_bh(&p->lock);
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(p);
 	return ret;
 }
 
 static int
 tcf_gact_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_gact *p;
-	p = PRIV(a,gact);
-	if (NULL != p)
+	struct tcf_gact *p = PRIV(a, gact);
+
+	if (p != NULL)
 		return tcf_hash_release(p, bind);
 	return 0;
 }
@@ -142,21 +137,13 @@
 static int
 tcf_gact(struct sk_buff **pskb, struct tc_action *a)
 {
-	struct tcf_gact *p;
+	struct tcf_gact *p = PRIV(a, gact);
 	struct sk_buff *skb = *pskb;
 	int action = TC_ACT_SHOT;
 
-	p = PRIV(a,gact);
-
-	if (NULL == p) {
-		if (net_ratelimit())
-			printk("BUG: tcf_gact called with NULL params\n");
-		return -1;
-	}
-
 	spin_lock(&p->lock);
 #ifdef CONFIG_GACT_PROB
-	if (p->ptype && NULL != gact_rand[p->ptype])
+	if (p->ptype && gact_rand[p->ptype] != NULL)
 		action = gact_rand[p->ptype](p);
 	else
 		action = p->action;
@@ -165,7 +152,7 @@
 #endif
 	p->bstats.bytes += skb->len;
 	p->bstats.packets++;
-	if (TC_ACT_SHOT == action)
+	if (action == TC_ACT_SHOT)
 		p->qstats.drops++;
 	p->tm.lastuse = jiffies;
 	spin_unlock(&p->lock);
@@ -178,35 +165,27 @@
 {
 	unsigned char *b = skb->tail;
 	struct tc_gact opt;
-#ifdef CONFIG_GACT_PROB
-	struct tc_gact_p p_opt;
-#endif
-	struct tcf_gact *p;
+	struct tcf_gact *p = PRIV(a, gact);
 	struct tcf_t t;
 
-	p = PRIV(a,gact);
-	if (NULL == p) {
-		printk("BUG: tcf_gact_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
-
 	opt.index = p->index;
 	opt.refcnt = p->refcnt - ref;
 	opt.bindcnt = p->bindcnt - bind;
 	opt.action = p->action;
-	RTA_PUT(skb, TCA_GACT_PARMS, sizeof (opt), &opt);
+	RTA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
 #ifdef CONFIG_GACT_PROB
 	if (p->ptype) {
+		struct tc_gact_p p_opt;
 		p_opt.paction = p->paction;
 		p_opt.pval = p->pval;
 		p_opt.ptype = p->ptype;
-		RTA_PUT(skb, TCA_GACT_PROB, sizeof (p_opt), &p_opt);
-	} 
+		RTA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
+	}
 #endif
 	t.install = jiffies_to_clock_t(jiffies - p->tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
 	t.expires = jiffies_to_clock_t(p->tm.expires);
-	RTA_PUT(skb, TCA_GACT_TM, sizeof (t), &t);
+	RTA_PUT(skb, TCA_GACT_TM, sizeof(t), &t);
 	return skb->len;
 
       rtattr_failure:
@@ -215,7 +194,6 @@
 }
 
 static struct tc_action_ops act_gact_ops = {
-	.next		=	NULL,
 	.kind		=	"gact",
 	.type		=	TCA_ACT_GACT,
 	.capab		=	TCA_CAP_NONE,
diff -Nru a/net/sched/ipt.c b/net/sched/ipt.c
--- a/net/sched/ipt.c	2005-01-19 13:44:45 -08:00
+++ b/net/sched/ipt.c	2005-01-19 13:44:45 -08:00
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/kmod.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <linux/tc_act/tc_ipt.h>
@@ -45,231 +46,179 @@
 static u32 idx_gen;
 static struct tcf_ipt *tcf_ipt_ht[MY_TAB_SIZE];
 /* ipt hash table lock */
-static rwlock_t ipt_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(ipt_lock);
 
 /* ovewrride the defaults */
-#define tcf_st  tcf_ipt
-#define tcf_t_lock   ipt_lock
-#define tcf_ht tcf_ipt_ht
+#define tcf_st		tcf_ipt
+#define tcf_t_lock	ipt_lock
+#define tcf_ht		tcf_ipt_ht
 
+#define CONFIG_NET_ACT_INIT
 #include <net/pkt_act.h>
 
-static inline int
-init_targ(struct tcf_ipt *p)
+static int
+ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
 {
 	struct ipt_target *target;
 	int ret = 0;
-	struct ipt_entry_target *t = p->t;
-	target = __ipt_find_target_lock(t->u.user.name, &ret);
 
-	if (!target) {
-		printk("init_targ: Failed to find %s\n", t->u.user.name);
-		return -1;
-	}
+	target = ipt_find_target(t->u.user.name, t->u.user.revision);
+	if (!target)
+		return -ENOENT;
 
-	DPRINTK("init_targ: found %s\n", target->name);
-	/* we really need proper ref counting
-	 seems to be only needed for modules?? Talk to laforge */
-/*      if (target->me)
-              __MOD_INC_USE_COUNT(target->me);
-*/
+	DPRINTK("ipt_init_target: found %s\n", target->name);
 	t->u.kernel.target = target;
 
-	__ipt_mutex_up();
-
 	if (t->u.kernel.target->checkentry
-	    && !t->u.kernel.target->checkentry(p->tname, NULL, t->data,
-					       t->u.target_size
-					       - sizeof (*t), p->hook)) {
-/*              if (t->u.kernel.target->me)
-	      __MOD_DEC_USE_COUNT(t->u.kernel.target->me);
-*/
-		DPRINTK("ip_tables: check failed for `%s'.\n",
+	    && !t->u.kernel.target->checkentry(table, NULL, t->data,
+					       t->u.target_size - sizeof(*t),
+					       hook)) {
+		DPRINTK("ipt_init_target: check failed for `%s'.\n",
 			t->u.kernel.target->name);
+		module_put(t->u.kernel.target->me);
 		ret = -EINVAL;
 	}
 
 	return ret;
 }
 
+static void
+ipt_destroy_target(struct ipt_entry_target *t)
+{
+	if (t->u.kernel.target->destroy)
+		t->u.kernel.target->destroy(t->data,
+		                            t->u.target_size - sizeof(*t));
+        module_put(t->u.kernel.target->me);
+}
+
 static int
-tcf_ipt_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, int ovr, int bind)
+tcf_ipt_release(struct tcf_ipt *p, int bind)
 {
-	struct ipt_entry_target *t;
-	unsigned h;
-	struct rtattr *tb[TCA_IPT_MAX];
-	struct tcf_ipt *p;
 	int ret = 0;
-	u32 index = 0;
-	u32 hook = 0;
-
-	if (NULL == a || NULL == rta ||
-	    (rtattr_parse(tb, TCA_IPT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) <
-	     0)) {
-		return -1;
-	}
-
-
-	if (tb[TCA_IPT_INDEX - 1]) {
-		index = *(u32 *) RTA_DATA(tb[TCA_IPT_INDEX - 1]);
-		DPRINTK("ipt index %d\n", index);
-	}
-
-	if (index && (p = tcf_hash_lookup(index)) != NULL) {
-		a->priv = (void *) p;
-		spin_lock(&p->lock);
-		if (bind) {
-			p->bindcnt += 1;
-			p->refcnt += 1;
+	if (p) {
+		if (bind)
+			p->bindcnt--;
+		p->refcnt--;
+		if (p->bindcnt <= 0 && p->refcnt <= 0) {
+			ipt_destroy_target(p->t);
+			kfree(p->tname);
+			kfree(p->t);
+			tcf_hash_destroy(p);
+			ret = ACT_P_DELETED;
 		}
-		if (ovr) {
-			goto override;
-		}
-		spin_unlock(&p->lock);
-		return ret;
 	}
+	return ret;
+}
 
-	if (NULL == tb[TCA_IPT_TARG - 1] || NULL == tb[TCA_IPT_HOOK - 1]) {
-		return -1;
-	}
+static int
+tcf_ipt_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,
+             int ovr, int bind)
+{
+	struct rtattr *tb[TCA_IPT_MAX];
+	struct tcf_ipt *p;
+	struct ipt_entry_target *td, *t;
+	char *tname;
+	int ret = 0, err;
+	u32 hook = 0;
+	u32 index = 0;
 
-	p = kmalloc(sizeof (*p), GFP_KERNEL);
-	if (p == NULL)
-		return -1;
-
-	memset(p, 0, sizeof (*p));
-	p->refcnt = 1;
-	ret = 1;
-	spin_lock_init(&p->lock);
-	p->stats_lock = &p->lock;
-	if (bind)
-		p->bindcnt = 1;
-
-override:
-	hook = *(u32 *) RTA_DATA(tb[TCA_IPT_HOOK - 1]);
-
-	t = (struct ipt_entry_target *) RTA_DATA(tb[TCA_IPT_TARG - 1]);
-
-	p->t = kmalloc(t->u.target_size, GFP_KERNEL);
-	if (p->t == NULL) {
-		if (ovr) {
-			printk("ipt policy messed up \n");
-			spin_unlock(&p->lock);
-			return -1;
-		}
-		kfree(p);
-		return -1;
-	}
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_IPT_MAX, rta) < 0)
+		return -EINVAL;
 
-	memcpy(p->t, RTA_DATA(tb[TCA_IPT_TARG - 1]), t->u.target_size);
-	DPRINTK(" target NAME %s size %d data[0] %x data[1] %x\n",
-		t->u.user.name, t->u.target_size, t->data[0], t->data[1]);
-
-	p->tname = kmalloc(IFNAMSIZ, GFP_KERNEL);
-
-	if (p->tname == NULL) {
-		if (ovr) {
-			printk("ipt policy messed up 2 \n");
-			spin_unlock(&p->lock);
-			return -1;
-		}
-		kfree(p->t);
-		kfree(p);
-		return -1;
+	if (tb[TCA_IPT_HOOK-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_IPT_HOOK-1]) < sizeof(u32))
+		return -EINVAL;
+	if (tb[TCA_IPT_TARG-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_IPT_TARG-1]) < sizeof(*t))
+		return -EINVAL;
+	td = (struct ipt_entry_target *)RTA_DATA(tb[TCA_IPT_TARG-1]);
+	if (RTA_PAYLOAD(tb[TCA_IPT_TARG-1]) < td->u.target_size)
+		return -EINVAL;
+
+	if (tb[TCA_IPT_INDEX-1] != NULL &&
+	    RTA_PAYLOAD(tb[TCA_IPT_INDEX-1]) >= sizeof(u32))
+		index = *(u32 *)RTA_DATA(tb[TCA_IPT_INDEX-1]);
+
+	p = tcf_hash_check(index, a, ovr, bind);
+	if (p == NULL) {
+		p = tcf_hash_create(index, est, a, sizeof(*p), ovr, bind);
+		if (p == NULL)
+			return -ENOMEM;
+		ret = ACT_P_CREATED;
 	} else {
-		int csize = IFNAMSIZ - 1;
-
-		memset(p->tname, 0, IFNAMSIZ);
-		if (tb[TCA_IPT_TABLE - 1]) {
-			if (strlen((char *) RTA_DATA(tb[TCA_IPT_TABLE - 1])) <
-			    csize)
-				csize = strlen(RTA_DATA(tb[TCA_IPT_TABLE - 1]));
-			strncpy(p->tname, RTA_DATA(tb[TCA_IPT_TABLE - 1]),
-				csize);
-			DPRINTK("table name %s\n", p->tname);
-		} else {
-			strncpy(p->tname, "mangle", 1 + strlen("mangle"));
+		if (!ovr) {
+			tcf_ipt_release(p, bind);
+			return -EEXIST;
 		}
 	}
 
-	if (0 > init_targ(p)) {
-		if (ovr) {
-			printk("ipt policy messed up 2 \n");
-			spin_unlock(&p->lock);
-			return -1;
-		}
+	hook = *(u32 *)RTA_DATA(tb[TCA_IPT_HOOK-1]);
+
+	err = -ENOMEM;
+	tname = kmalloc(IFNAMSIZ, GFP_KERNEL);
+	if (tname == NULL)
+		goto err1;
+	if (tb[TCA_IPT_TABLE - 1] == NULL ||
+	    rtattr_strlcpy(tname, tb[TCA_IPT_TABLE-1], IFNAMSIZ) >= IFNAMSIZ)
+		strcpy(tname, "mangle");
+
+	t = kmalloc(td->u.target_size, GFP_KERNEL);
+	if (t == NULL)
+		goto err2;
+	memcpy(t, td, td->u.target_size);
+
+	if ((err = ipt_init_target(t, tname, hook)) < 0)
+		goto err3;
+
+	spin_lock_bh(&p->lock);
+	if (ret != ACT_P_CREATED) {
+		ipt_destroy_target(p->t);
 		kfree(p->tname);
 		kfree(p->t);
-		kfree(p);
-		return -1;
-	}
-
-	if (ovr) {
-		spin_unlock(&p->lock);
-		return -1;
 	}
-
-	p->index = index ? : tcf_hash_new_index();
-
-	p->tm.lastuse = jiffies;
-	/*
-	p->tm.expires = jiffies;
-	*/
-	p->tm.install = jiffies;
-#ifdef CONFIG_NET_ESTIMATOR
-	if (est)
-		gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
-#endif
-	h = tcf_hash(p->index);
-	write_lock_bh(&ipt_lock);
-	p->next = tcf_ipt_ht[h];
-	tcf_ipt_ht[h] = p;
-	write_unlock_bh(&ipt_lock);
-	a->priv = (void *) p;
+	p->tname = tname;
+	p->t     = t;
+	p->hook  = hook;
+	spin_unlock_bh(&p->lock);
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(p);
 	return ret;
 
+err3:
+	kfree(t);
+err2:
+	kfree(tname);
+err1:
+	kfree(p);
+	return err;
 }
 
 static int
 tcf_ipt_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_ipt *p;
-	p = PRIV(a,ipt);
-	if (NULL != p)
-		return tcf_hash_release(p, bind);
-	return 0;
+	struct tcf_ipt *p = PRIV(a, ipt);
+	return tcf_ipt_release(p, bind);
 }
 
 static int
 tcf_ipt(struct sk_buff **pskb, struct tc_action *a)
 {
 	int ret = 0, result = 0;
-	struct tcf_ipt *p;
+	struct tcf_ipt *p = PRIV(a, ipt);
 	struct sk_buff *skb = *pskb;
 
-	p = PRIV(a,ipt);
-
-	if (NULL == p || NULL == skb) {
-		return -1;
-	}
-
 	spin_lock(&p->lock);
 
 	p->tm.lastuse = jiffies;
 	p->bstats.bytes += skb->len;
 	p->bstats.packets++;
 
-	if (skb_cloned(skb) ) {
-		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
-			return -1;
-		}
-	}
 	/* yes, we have to worry about both in and out dev
 	 worry later - danger - this API seems to have changed
 	 from earlier kernels */
 
 	ret = p->t->u.kernel.target->target(&skb, skb->dev, NULL,
-					    p->hook, p->t->data, (void *)NULL);
+					    p->hook, p->t->data, NULL);
 	switch (ret) {
 	case NF_ACCEPT:
 		result = TC_ACT_OK;
@@ -299,22 +248,15 @@
 	struct tcf_t tm;
 	struct tc_cnt c;
 	unsigned char *b = skb->tail;
+	struct tcf_ipt *p = PRIV(a, ipt);
 
-	struct tcf_ipt *p;
-
-	p = PRIV(a,ipt);
-	if (NULL == p) {
-		printk("BUG: tcf_ipt_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
 	/* for simple targets kernel size == user size
 	** user name = target name
 	** for foolproof you need to not assume this
 	*/
 
 	t = kmalloc(p->t->u.user.target_size, GFP_ATOMIC);
-
-	if (NULL == t)
+	if (t == NULL)
 		goto rtattr_failure;
 
 	c.bindcnt = p->bindcnt - bind;
@@ -324,10 +266,10 @@
 
 	DPRINTK("\ttcf_ipt_dump tablename %s length %d\n", p->tname,
 		strlen(p->tname));
-	DPRINTK
-	    ("\tdump target name %s size %d size user %d data[0] %x data[1] %x\n",
-	     p->t->u.kernel.target->name, p->t->u.target_size, p->t->u.user.target_size,
-	     p->t->data[0], p->t->data[1]);
+	DPRINTK("\tdump target name %s size %d size user %d "
+	        "data[0] %x data[1] %x\n", p->t->u.kernel.target->name,
+	        p->t->u.target_size, p->t->u.user.target_size,
+	        p->t->data[0], p->t->data[1]);
 	RTA_PUT(skb, TCA_IPT_TARG, p->t->u.user.target_size, t);
 	RTA_PUT(skb, TCA_IPT_INDEX, 4, &p->index);
 	RTA_PUT(skb, TCA_IPT_HOOK, 4, &p->hook);
@@ -345,7 +287,6 @@
 }
 
 static struct tc_action_ops act_ipt_ops = {
-	.next		=	NULL,
 	.kind		=	"ipt",
 	.type		=	TCA_ACT_IPT,
 	.capab		=	TCA_CAP_NONE,
diff -Nru a/net/sched/mirred.c b/net/sched/mirred.c
--- a/net/sched/mirred.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/mirred.c	2005-01-19 13:44:46 -08:00
@@ -46,13 +46,13 @@
 #define MY_TAB_MASK     (MY_TAB_SIZE - 1)
 static u32 idx_gen;
 static struct tcf_mirred *tcf_mirred_ht[MY_TAB_SIZE];
-static rwlock_t mirred_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(mirred_lock);
 
 /* ovewrride the defaults */
-#define tcf_st  tcf_mirred
-#define tc_st  tc_mirred
-#define tcf_t_lock   mirred_lock
-#define tcf_ht tcf_mirred_ht
+#define tcf_st		tcf_mirred
+#define tc_st		tc_mirred
+#define tcf_t_lock	mirred_lock
+#define tcf_ht		tcf_mirred_ht
 
 #define CONFIG_NET_ACT_INIT 1
 #include <net/pkt_act.h>
@@ -61,10 +61,8 @@
 tcf_mirred_release(struct tcf_mirred *p, int bind)
 {
 	if (p) {
-		if (bind) {
+		if (bind)
 			p->bindcnt--;
-		}
-
 		p->refcnt--;
 		if(!p->bindcnt && p->refcnt <= 0) {
 			dev_put(p->dev);
@@ -72,46 +70,32 @@
 			return 1;
 		}
 	}
-
 	return 0;
 }
 
 static int
-tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,int ovr, int bind)
+tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,
+                int ovr, int bind)
 {
 	struct rtattr *tb[TCA_MIRRED_MAX];
 	struct tc_mirred *parm;
 	struct tcf_mirred *p;
 	struct net_device *dev = NULL;
-	int size = sizeof (*p), new = 0;
+	int ret = 0;
+	int ok_push = 0;
 
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_MIRRED_MAX, rta) < 0)
+		return -EINVAL;
 
-	if (rtattr_parse(tb, TCA_MIRRED_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0) {
-		DPRINTK("tcf_mirred_init BUG in user space couldnt parse properly\n");
-		return -1;
-	}
-
-	if (NULL == a || NULL == tb[TCA_MIRRED_PARMS - 1]) {
-		DPRINTK("BUG: tcf_mirred_init called with NULL params\n");
-		return -1;
-	}
-
-	parm = RTA_DATA(tb[TCA_MIRRED_PARMS - 1]);
-
-	p = tcf_hash_check(parm, a, ovr, bind);
-	if (NULL == p) { /* new */
-		p = tcf_hash_create(parm,est,a,size,ovr,bind);
-		new = 1;
-		if (NULL == p)
-			return -1;
-	}
+	if (tb[TCA_MIRRED_PARMS-1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_MIRRED_PARMS-1]) < sizeof(*parm))
+		return -EINVAL;
+	parm = RTA_DATA(tb[TCA_MIRRED_PARMS-1]);
 
 	if (parm->ifindex) {
-		dev = dev_get_by_index(parm->ifindex);
-		if (NULL == dev) {
-			printk("BUG: tcf_mirred_init called with bad device\n");
-			return -1;
-		}
+		dev = __dev_get_by_index(parm->ifindex);
+		if (dev == NULL)
+			return -ENODEV;
 		switch (dev->type) {
 			case ARPHRD_TUNNEL:
 			case ARPHRD_TUNNEL6:
@@ -119,44 +103,56 @@
 			case ARPHRD_IPGRE:
 			case ARPHRD_VOID:
 			case ARPHRD_NONE:
-				p->ok_push = 0;
+				ok_push = 0;
 				break;
 			default:
-				p->ok_push = 1;
+				ok_push = 1;
 				break;
 		}
-	} else {
-		if (new) {
-			kfree(p);
-			return -1;
-		}	
 	}
 
-	if (new || ovr) {
-		spin_lock(&p->lock);
-		p->action = parm->action;
-		p->eaction = parm->eaction;
-		if (parm->ifindex) {
-			p->ifindex = parm->ifindex;
-			if (ovr)
-				dev_put(p->dev);
-			p->dev = dev;
+	p = tcf_hash_check(parm->index, a, ovr, bind);
+	if (p == NULL) {
+		if (!parm->ifindex)
+			return -EINVAL;
+		p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind);
+		if (p == NULL)
+			return -ENOMEM;
+		ret = ACT_P_CREATED;
+	} else {
+		if (!ovr) {
+			tcf_mirred_release(p, bind);
+			return -EEXIST;
 		}
-		spin_unlock(&p->lock);
 	}
 
-
-	DPRINTK(" tcf_mirred_init index %d action %d eaction %d device %s ifndex %d\n",parm->index,parm->action,parm->eaction,dev->name,parm->ifindex);
-	return new;
-
+	spin_lock_bh(&p->lock);
+	p->action = parm->action;
+	p->eaction = parm->eaction;
+	if (parm->ifindex) {
+		p->ifindex = parm->ifindex;
+		if (ret != ACT_P_CREATED)
+			dev_put(p->dev);
+		p->dev = dev;
+		dev_hold(dev);
+		p->ok_push = ok_push;
+	}
+	spin_unlock_bh(&p->lock);
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(p);
+
+	DPRINTK("tcf_mirred_init index %d action %d eaction %d device %s "
+	        "ifindex %d\n", parm->index, parm->action, parm->eaction,
+	        dev->name, parm->ifindex);
+	return ret;
 }
 
 static int
 tcf_mirred_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_mirred *p;
-	p = PRIV(a,mirred);
-	if (NULL != p)
+	struct tcf_mirred *p = PRIV(a, mirred);
+
+	if (p != NULL)
 		return tcf_mirred_release(p, bind);
 	return 0;
 }
@@ -164,70 +160,52 @@
 static int
 tcf_mirred(struct sk_buff **pskb, struct tc_action *a)
 {
-	struct tcf_mirred *p;
+	struct tcf_mirred *p = PRIV(a, mirred);
 	struct net_device *dev;
 	struct sk_buff *skb2 = NULL;
 	struct sk_buff *skb = *pskb;
-	__u32 at = G_TC_AT(skb->tc_verd);
-
-	if (NULL == a) {
-		if (net_ratelimit())
-			printk("BUG: tcf_mirred called with NULL action!\n");
-		return -1;
-	}
-
-	p = PRIV(a,mirred);
-
-	if (NULL == p) {
-		if (net_ratelimit())
-			printk("BUG: tcf_mirred called with NULL params\n");
-		return -1;
-	}
+	u32 at = G_TC_AT(skb->tc_verd);
 
 	spin_lock(&p->lock);
 
-       	dev = p->dev;
+	dev = p->dev;
 	p->tm.lastuse = jiffies;
 
-	if (NULL == dev || !(dev->flags&IFF_UP) ) {
+	if (!(dev->flags&IFF_UP) ) {
 		if (net_ratelimit())
 			printk("mirred to Houston: device %s is gone!\n",
-					dev?dev->name:"");
+			       dev->name);
 bad_mirred:
-		if (NULL != skb2)
+		if (skb2 != NULL)
 			kfree_skb(skb2);
 		p->qstats.overlimits++;
 		p->bstats.bytes += skb->len;
 		p->bstats.packets++;
 		spin_unlock(&p->lock);
 		/* should we be asking for packet to be dropped?
-		 * may make sense for redirect case only 
+		 * may make sense for redirect case only
 		*/
 		return TC_ACT_SHOT;
-	} 
+	}
 
 	skb2 = skb_clone(skb, GFP_ATOMIC);
-	if (skb2 == NULL) {
+	if (skb2 == NULL)
 		goto bad_mirred;
-	}
-	if (TCA_EGRESS_MIRROR != p->eaction &&
-		TCA_EGRESS_REDIR != p->eaction) {
+	if (p->eaction != TCA_EGRESS_MIRROR && p->eaction != TCA_EGRESS_REDIR) {
 		if (net_ratelimit())
-			printk("tcf_mirred unknown action %d\n",p->eaction);
+			printk("tcf_mirred unknown action %d\n", p->eaction);
 		goto bad_mirred;
 	}
 
 	p->bstats.bytes += skb2->len;
 	p->bstats.packets++;
-	if ( !(at & AT_EGRESS)) {
-		if (p->ok_push) {
+	if (!(at & AT_EGRESS))
+		if (p->ok_push)
 			skb_push(skb2, skb2->dev->hard_header_len);
-		}
-	}
 
 	/* mirror is always swallowed */
-	if (TCA_EGRESS_MIRROR != p->eaction)
-		skb2->tc_verd = SET_TC_FROM(skb2->tc_verd,at);
+	if (p->eaction != TCA_EGRESS_MIRROR)
+		skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at);
 
 	skb2->dev = dev;
 	skb2->input_dev = skb->dev;
@@ -237,31 +215,26 @@
 }
 
 static int
-tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref)
+tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	unsigned char *b = skb->tail;
 	struct tc_mirred opt;
-	struct tcf_mirred *p;
+	struct tcf_mirred *p = PRIV(a, mirred);
 	struct tcf_t t;
 
-	p = PRIV(a,mirred);
-	if (NULL == p) {
-		printk("BUG: tcf_mirred_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
-
 	opt.index = p->index;
 	opt.action = p->action;
 	opt.refcnt = p->refcnt - ref;
 	opt.bindcnt = p->bindcnt - bind;
 	opt.eaction = p->eaction;
 	opt.ifindex = p->ifindex;
-	DPRINTK(" tcf_mirred_dump index %d action %d eaction %d ifndex %d\n",p->index,p->action,p->eaction,p->ifindex);
-	RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof (opt), &opt);
+	DPRINTK("tcf_mirred_dump index %d action %d eaction %d ifindex %d\n",
+	         p->index, p->action, p->eaction, p->ifindex);
+	RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
 	t.install = jiffies_to_clock_t(jiffies - p->tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
 	t.expires = jiffies_to_clock_t(p->tm.expires);
-	RTA_PUT(skb, TCA_MIRRED_TM, sizeof (t), &t);
+	RTA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t);
 	return skb->len;
 
       rtattr_failure:
@@ -270,7 +243,6 @@
 }
 
 static struct tc_action_ops act_mirred_ops = {
-	.next		=	NULL,
 	.kind		=	"mirred",
 	.type		=	TCA_ACT_MIRRED,
 	.capab		=	TCA_CAP_NONE,
@@ -287,7 +259,6 @@
 MODULE_DESCRIPTION("Device Mirror/redirect actions");
 MODULE_LICENSE("GPL");
 
-
 static int __init
 mirred_init_module(void)
 {
@@ -303,4 +274,3 @@
 
 module_init(mirred_init_module);
 module_exit(mirred_cleanup_module);
-
diff -Nru a/net/sched/pedit.c b/net/sched/pedit.c
--- a/net/sched/pedit.c	2005-01-19 13:44:47 -08:00
+++ b/net/sched/pedit.c	2005-01-19 13:44:47 -08:00
@@ -42,92 +42,101 @@
 #define MY_TAB_MASK     15
 static u32 idx_gen;
 static struct tcf_pedit *tcf_pedit_ht[MY_TAB_SIZE];
-static rwlock_t pedit_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(pedit_lock);
 
-#define tcf_st  tcf_pedit
-#define tc_st  tc_pedit
-#define tcf_t_lock   pedit_lock
-#define tcf_ht tcf_pedit_ht
+#define tcf_st		tcf_pedit
+#define tc_st		tc_pedit
+#define tcf_t_lock	pedit_lock
+#define tcf_ht		tcf_pedit_ht
 
 #define CONFIG_NET_ACT_INIT 1
 #include <net/pkt_act.h>
 
-
 static int
-tcf_pedit_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,int ovr, int bind)
+tcf_pedit_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,
+               int ovr, int bind)
 {
 	struct rtattr *tb[TCA_PEDIT_MAX];
 	struct tc_pedit *parm;
-	int size = 0;
 	int ret = 0;
-	struct tcf_pedit *p = NULL;
-
-	if (rtattr_parse(tb, TCA_PEDIT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0)
-		return -1;
-
-	if (NULL == a || NULL == tb[TCA_PEDIT_PARMS - 1]) {
-		printk("BUG: tcf_pedit_init called with NULL params\n");
-		return -1;
-	}
-
-	parm = RTA_DATA(tb[TCA_PEDIT_PARMS - 1]);
+	struct tcf_pedit *p;
+	struct tc_pedit_key *keys = NULL;
+	int ksize;
 
-	p = tcf_hash_check(parm, a, ovr, bind);
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_PEDIT_MAX, rta) < 0)
+		return -EINVAL;
 
-	if (NULL == p) { /* new */
+	if (tb[TCA_PEDIT_PARMS - 1] == NULL ||
+	    RTA_PAYLOAD(tb[TCA_PEDIT_PARMS-1]) < sizeof(*parm))
+		return -EINVAL;
+	parm = RTA_DATA(tb[TCA_PEDIT_PARMS-1]);
+	ksize = parm->nkeys * sizeof(struct tc_pedit_key);
+	if (RTA_PAYLOAD(tb[TCA_PEDIT_PARMS-1]) < sizeof(*parm) + ksize)
+		return -EINVAL;
 
+	p = tcf_hash_check(parm->index, a, ovr, bind);
+	if (p == NULL) {
 		if (!parm->nkeys)
-			return -1;
-
-		size = sizeof (*p)+ (parm->nkeys*sizeof(struct tc_pedit_key));
-
-		p = tcf_hash_create(parm,est,a,size,ovr,bind);
-
-		if (NULL == p)
-			return -1;
-		ret = 1;
-		goto override;
-	} 
+			return -EINVAL;
+		p = tcf_hash_create(parm->index, est, a, sizeof(*p), ovr, bind);
+		if (p == NULL)
+			return -ENOMEM;
+		keys = kmalloc(ksize, GFP_KERNEL);
+		if (keys == NULL) {
+			kfree(p);
+			return -ENOMEM;
+		}
+		ret = ACT_P_CREATED;
+	} else {
+		if (!ovr) {
+			tcf_hash_release(p, bind);
+			return -EEXIST;
+		}
+		if (p->nkeys && p->nkeys != parm->nkeys) {
+			keys = kmalloc(ksize, GFP_KERNEL);
+			if (keys == NULL)
+				return -ENOMEM;
+		}
+	}
 
-	if (ovr) {
-override:
-		p->flags = parm->flags;
+	spin_lock_bh(&p->lock);
+	p->flags = parm->flags;
+	p->action = parm->action;
+	if (keys) {
+		kfree(p->keys);
+		p->keys = keys;
 		p->nkeys = parm->nkeys;
-		p->action = parm->action;
-		memcpy(p->keys,parm->keys,parm->nkeys*(sizeof(struct tc_pedit_key)));
 	}
-
+	memcpy(p->keys, parm->keys, ksize);
+	spin_unlock_bh(&p->lock);
+	if (ret == ACT_P_CREATED)
+		tcf_hash_insert(p);
 	return ret;
 }
 
 static int
 tcf_pedit_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_pedit *p;
-	p = PRIV(a,pedit);
-	if (NULL != p)
-		return	tcf_hash_release(p, bind);
+	struct tcf_pedit *p = PRIV(a, pedit);
+
+	if (p != NULL) {
+		struct tc_pedit_key *keys = p->keys;
+		if (tcf_hash_release(p, bind)) {
+			kfree(keys);
+			return 1;
+		}
+	}
 	return 0;
 }
 
-/*
-**
-*/
 static int
 tcf_pedit(struct sk_buff **pskb, struct tc_action *a)
 {
-	struct tcf_pedit *p;
+	struct tcf_pedit *p = PRIV(a, pedit);
 	struct sk_buff *skb = *pskb;
 	int i, munged = 0;
 	u8 *pptr;
 
-	p = PRIV(a,pedit);
-
-	if (NULL == p) {
-		printk("BUG: tcf_pedit called with NULL params\n");
-		return -1; /* change to something symbolic */
-	}
-
 	if (!(skb->tc_verd & TC_OK2MUNGE)) {
 		/* should we set skb->cloned? */
 		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -141,17 +150,18 @@
 
 	p->tm.lastuse = jiffies;
 
-	if (0 < p->nkeys) {
+	if (p->nkeys > 0) {
 		struct tc_pedit_key *tkey = p->keys;
 
 		for (i = p->nkeys; i > 0; i--, tkey++) {
-			u32 *ptr ;
-
+			u32 *ptr;
 			int offset = tkey->off;
+
 			if (tkey->offmask) {
 				if (skb->len > tkey->at) {
-					 char *j = pptr+tkey->at;
-					 offset +=((*j&tkey->offmask)>>tkey->shift);
+					 char *j = pptr + tkey->at;
+					 offset += ((*j & tkey->offmask) >> 
+					           tkey->shift);
 				} else {
 					goto bad;
 				}
@@ -161,14 +171,12 @@
 				printk("offset must be on 32 bit boundaries\n");
 				goto bad;
 			}
-
 			if (skb->len < 0 || (offset > 0 && offset > skb->len)) {
 				printk("offset %d cant exceed pkt length %d\n",
-						offset, skb->len);
+				       offset, skb->len);
 				goto bad;
 			}
 
-
 			ptr = (u32 *)(pptr+offset);
 			/* just do it, baby */
 			*ptr = ((*ptr & tkey->mask) ^ tkey->val);
@@ -196,29 +204,19 @@
 {
 	unsigned char *b = skb->tail;
 	struct tc_pedit *opt;
-	struct tcf_pedit *p;
+	struct tcf_pedit *p = PRIV(a, pedit);
 	struct tcf_t t;
 	int s; 
 		
+	s = sizeof(*opt) + p->nkeys * sizeof(struct tc_pedit_key);
 
-	p = PRIV(a,pedit);
-
-	if (NULL == p) {
-		printk("BUG: tcf_pedit_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
-
-	s = sizeof (*opt)+(p->nkeys*sizeof(struct tc_pedit_key));
-
-	/* netlink spinlocks held above us - must use ATOMIC
-	 * */
+	/* netlink spinlocks held above us - must use ATOMIC */
 	opt = kmalloc(s, GFP_ATOMIC);
 	if (opt == NULL)
 		return -ENOBUFS;
-
 	memset(opt, 0, s);
 
-	memcpy(opt->keys,p->keys,p->nkeys*(sizeof(struct tc_pedit_key)));
+	memcpy(opt->keys, p->keys, p->nkeys * sizeof(struct tc_pedit_key));
 	opt->index = p->index;
 	opt->nkeys = p->nkeys;
 	opt->flags = p->flags;
@@ -239,15 +237,15 @@
 			(unsigned int)key->off,
 			(unsigned int)key->val,
 			(unsigned int)key->mask);
-												}
-											}
+		}
+	}
 #endif
 
 	RTA_PUT(skb, TCA_PEDIT_PARMS, s, opt);
 	t.install = jiffies_to_clock_t(jiffies - p->tm.install);
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
 	t.expires = jiffies_to_clock_t(p->tm.expires);
-	RTA_PUT(skb, TCA_PEDIT_TM, sizeof (t), &t);
+	RTA_PUT(skb, TCA_PEDIT_TM, sizeof(t), &t);
 	return skb->len;
 
 rtattr_failure:
diff -Nru a/net/sched/police.c b/net/sched/police.c
--- a/net/sched/police.c	2005-01-19 13:44:47 -08:00
+++ b/net/sched/police.c	2005-01-19 13:44:47 -08:00
@@ -43,7 +43,7 @@
 static u32 idx_gen;
 static struct tcf_police *tcf_police_ht[MY_TAB_SIZE];
 /* Policer hash table lock */
-static rwlock_t police_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(police_lock);
 
 /* Each policer is serialized by its individual spinlock */
 
@@ -66,11 +66,12 @@
 }
 
 #ifdef CONFIG_NET_CLS_ACT
-static __inline__ int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb, int type, struct tc_action *a)
+static int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb,
+                              int type, struct tc_action *a)
 {
 	struct tcf_police *p;
-	int err =0, index =  -1,i= 0, s_i = 0, n_i = 0;
-	struct rtattr *r ;
+	int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
+	struct rtattr *r;
 
 	read_lock(&police_lock);
 
@@ -91,7 +92,7 @@
 				err = tcf_action_dump_1(skb, a, 0, 1);
 			else
 				err = tcf_action_dump_1(skb, a, 0, 0);
-			if (0 > err) {
+			if (err < 0) {
 				index--;
 				skb_trim(skb, (u8*)r - skb->data);
 				goto done;
@@ -123,11 +124,9 @@
 		return 0;
 	}
 }
-
-
 #endif
 
-static __inline__ u32 tcf_police_new_index(void)
+static inline u32 tcf_police_new_index(void)
 {
 	do {
 		if (++idx_gen == 0)
@@ -137,7 +136,6 @@
 	return idx_gen;
 }
 
-
 void tcf_police_destroy(struct tcf_police *p)
 {
 	unsigned h = tcf_police_hash(p->index);
@@ -163,49 +161,48 @@
 }
 
 #ifdef CONFIG_NET_CLS_ACT
-static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,struct tc_action *a, int ovr, int bind)
+static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
+                                 struct tc_action *a, int ovr, int bind)
 {
 	unsigned h;
-	int ret = 0;
+	int ret = 0, err;
 	struct rtattr *tb[TCA_POLICE_MAX];
 	struct tc_police *parm;
 	struct tcf_police *p;
+	struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL;
 
-	if (NULL == a) {
-		if (net_ratelimit())
-			printk("BUG: tcf_police_locate called with NULL params\n");
-		return -1;  
-	}
-
-	if (rtattr_parse(tb, TCA_POLICE_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0)
-		return -1;
+	if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0)
+		return -EINVAL;
 
 	if (tb[TCA_POLICE_TBF-1] == NULL ||
 	    RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm))
-		return -1;
-
+		return -EINVAL;
 	parm = RTA_DATA(tb[TCA_POLICE_TBF-1]);
 
+	if (tb[TCA_POLICE_RESULT-1] != NULL &&
+	    RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
+		return -EINVAL;
+	if (tb[TCA_POLICE_RESULT-1] != NULL &&
+	    RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
+		return -EINVAL;
+
 	if (parm->index && (p = tcf_police_lookup(parm->index)) != NULL) {
-		a->priv = (void *)p;
-		spin_lock(&p->lock);
+		a->priv = p;
 		if (bind) {
 			p->bindcnt += 1;
 			p->refcnt += 1;
 		}
-		if (ovr) {
+		if (ovr)
 			goto override;
-		}
-		spin_unlock(&p->lock);
-		return ret; 
+		return ret;
 	}
 
 	p = kmalloc(sizeof(*p), GFP_KERNEL);
 	if (p == NULL)
-		return -1;
-
+		return -ENOMEM;
 	memset(p, 0, sizeof(*p));
-	ret = 1;
+
+	ret = ACT_P_CREATED;
 	p->refcnt = 1;
 	spin_lock_init(&p->lock);
 	p->stats_lock = &p->lock;
@@ -213,26 +210,32 @@
 		p->bindcnt = 1;
 override:
 	if (parm->rate.rate) {
-		if ((p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1])) == NULL) {
-			goto failure;
-		}
-		if (parm->peakrate.rate &&
-		    (p->P_tab = qdisc_get_rtab(&parm->peakrate, tb[TCA_POLICE_PEAKRATE-1])) == NULL) {
+		err = -ENOMEM;
+		R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]);
+		if (R_tab == NULL)
 			goto failure;
+		if (parm->peakrate.rate) {
+			P_tab = qdisc_get_rtab(&parm->peakrate,
+					       tb[TCA_POLICE_PEAKRATE-1]);
+			if (p->P_tab == NULL) {
+				qdisc_put_rtab(R_tab);
+				goto failure;
+			}
 		}
 	}
-	if (tb[TCA_POLICE_RESULT-1]) {
-		if (RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
-			goto failure;
-		p->result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
+	/* No failure allowed after this point */
+	spin_lock_bh(&p->lock);
+	if (R_tab != NULL) {
+		qdisc_put_rtab(p->R_tab);
+		p->R_tab = R_tab;
 	}
-#ifdef CONFIG_NET_ESTIMATOR
-	if (tb[TCA_POLICE_AVRATE-1]) {
-		if (RTA_PAYLOAD(tb[TCA_POLICE_AVRATE-1]) != sizeof(u32))
-			goto failure;
-		p->ewma_rate = *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
+	if (P_tab != NULL) {
+		qdisc_put_rtab(p->P_tab);
+		p->P_tab = P_tab;
 	}
-#endif
+
+	if (tb[TCA_POLICE_RESULT-1])
+		p->result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
 	p->toks = p->burst = parm->burst;
 	p->mtu = parm->mtu;
 	if (p->mtu == 0) {
@@ -244,41 +247,40 @@
 		p->ptoks = L2T_P(p, p->mtu);
 	p->action = parm->action;
 
-	if (ovr) {
-		spin_unlock(&p->lock);
-		return ret;
-	}
-	PSCHED_GET_TIME(p->t_c);
-	p->index = parm->index ? : tcf_police_new_index();
 #ifdef CONFIG_NET_ESTIMATOR
+	if (tb[TCA_POLICE_AVRATE-1])
+		p->ewma_rate = *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
 	if (est)
-		gen_new_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
+		gen_replace_estimator(&p->bstats, &p->rate_est, p->stats_lock, est);
 #endif
+
+	spin_unlock_bh(&p->lock);
+	if (ret != ACT_P_CREATED)
+		return ret;
+
+	PSCHED_GET_TIME(p->t_c);
+	p->index = parm->index ? : tcf_police_new_index();
 	h = tcf_police_hash(p->index);
 	write_lock_bh(&police_lock);
 	p->next = tcf_police_ht[h];
 	tcf_police_ht[h] = p;
 	write_unlock_bh(&police_lock);
 
-	a->priv = (void *)p;
-	return ret;  
+	a->priv = p;
+	return ret;
 
 failure:
-	if (p->R_tab)
-		qdisc_put_rtab(p->R_tab);
-	if (ovr)
-		spin_unlock(&p->lock);
-	kfree(p);
-	return -1;
+	if (ret == ACT_P_CREATED)
+		kfree(p);
+	return err;
 }
 
 static int tcf_act_police_cleanup(struct tc_action *a, int bind)
 {
-	struct tcf_police *p;
-	p = PRIV(a);
-	if (NULL != p) 
-		return tcf_police_release(p, bind);
+	struct tcf_police *p = PRIV(a);
 
+	if (p != NULL)
+		return tcf_police_release(p, bind);
 	return 0;
 }
 
@@ -286,17 +288,10 @@
 {
 	psched_time_t now;
 	struct sk_buff *skb = *pskb;
-	struct tcf_police *p;
+	struct tcf_police *p = PRIV(a);
 	long toks;
 	long ptoks = 0;
 
-	p = PRIV(a);
-
-	if (NULL == p) {
-		printk("BUG: tcf_police called with NULL params\n");
-		return -1;  
-	}
-
 	spin_lock(&p->lock);
 
 	p->bstats.bytes += skb->len;
@@ -345,17 +340,12 @@
 	return p->action;
 }
 
-static int tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
+static int
+tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
 	unsigned char	 *b = skb->tail;
 	struct tc_police opt;
-	struct tcf_police *p;
-
-	p = PRIV(a);
-	if (NULL == p) {
-		printk("BUG: tcf_police_dump called with NULL params\n");
-		goto rtattr_failure;
-	}
+	struct tcf_police *p = PRIV(a);
 
 	opt.index = p->index;
 	opt.action = p->action;
@@ -389,12 +379,10 @@
 MODULE_DESCRIPTION("Policing actions");
 MODULE_LICENSE("GPL");
 
-
 static struct tc_action_ops act_police_ops = {
-	.next		=	NULL,
 	.kind		=	"police",
-	.type		=	TCA_ID_POLICE, 
-	.capab		=	TCA_CAP_NONE, 
+	.type		=	TCA_ID_POLICE,
+	.capab		=	TCA_CAP_NONE,
 	.owner		=	THIS_MODULE,
 	.act		=	tcf_act_police,
 	.dump		=	tcf_act_police_dump,
@@ -428,7 +416,7 @@
 	struct rtattr *tb[TCA_POLICE_MAX];
 	struct tc_police *parm;
 
-	if (rtattr_parse(tb, TCA_POLICE_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0)
+	if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0)
 		return NULL;
 
 	if (tb[TCA_POLICE_TBF-1] == NULL ||
@@ -451,11 +439,15 @@
 	spin_lock_init(&p->lock);
 	p->stats_lock = &p->lock;
 	if (parm->rate.rate) {
-		if ((p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1])) == NULL)
-			goto failure;
-		if (parm->peakrate.rate &&
-		    (p->P_tab = qdisc_get_rtab(&parm->peakrate, tb[TCA_POLICE_PEAKRATE-1])) == NULL)
+		p->R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]);
+		if (p->R_tab == NULL)
 			goto failure;
+		if (parm->peakrate.rate) {
+			p->P_tab = qdisc_get_rtab(&parm->peakrate,
+			                          tb[TCA_POLICE_PEAKRATE-1]);
+			if (p->P_tab == NULL)
+				goto failure;
+		}
 	}
 	if (tb[TCA_POLICE_RESULT-1]) {
 		if (RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c
--- a/net/sched/sch_api.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/sch_api.c	2005-01-19 13:44:46 -08:00
@@ -131,7 +131,7 @@
  */
 
 /* Protects list of registered TC modules. It is pure SMP lock. */
-static rwlock_t qdisc_mod_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(qdisc_mod_lock);
 
 
 /************************************************
@@ -407,8 +407,9 @@
 	ops = qdisc_lookup_ops(kind);
 #ifdef CONFIG_KMOD
 	if (ops==NULL && tca[TCA_KIND-1] != NULL) {
-		if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
-			request_module("sch_%s", (char*)RTA_DATA(kind));
+		char name[IFNAMSIZ];
+		if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+			request_module("sch_%s", name);
 			ops = qdisc_lookup_ops(kind);
 		}
 	}
diff -Nru a/net/sched/sch_atm.c b/net/sched/sch_atm.c
--- a/net/sched/sch_atm.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/sch_atm.c	2005-01-19 13:44:46 -08:00
@@ -255,8 +255,8 @@
 	 * later.)
 	 */
 	if (flow) return -EBUSY;
-	if (opt == NULL || rtattr_parse(tb,TCA_ATM_MAX,RTA_DATA(opt),
-	    RTA_PAYLOAD(opt))) return -EINVAL;
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_ATM_MAX, opt))
+		return -EINVAL;
 	if (!tb[TCA_ATM_FD-1] || RTA_PAYLOAD(tb[TCA_ATM_FD-1]) < sizeof(fd))
 		return -EINVAL;
 	fd = *(int *) RTA_DATA(tb[TCA_ATM_FD-1]);
diff -Nru a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
--- a/net/sched/sch_cbq.c	2005-01-19 13:44:45 -08:00
+++ b/net/sched/sch_cbq.c	2005-01-19 13:44:45 -08:00
@@ -1439,7 +1439,7 @@
 	struct rtattr *tb[TCA_CBQ_MAX];
 	struct tc_ratespec *r;
 
-	if (rtattr_parse(tb, TCA_CBQ_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0 ||
+	if (rtattr_parse_nested(tb, TCA_CBQ_MAX, opt) < 0 ||
 	    tb[TCA_CBQ_RTAB-1] == NULL || tb[TCA_CBQ_RATE-1] == NULL ||
 	    RTA_PAYLOAD(tb[TCA_CBQ_RATE-1]) < sizeof(struct tc_ratespec))
 		return -EINVAL;
@@ -1824,8 +1824,7 @@
 	struct cbq_class *parent;
 	struct qdisc_rate_table *rtab = NULL;
 
-	if (opt==NULL ||
-	    rtattr_parse(tb, TCA_CBQ_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)))
+	if (opt==NULL || rtattr_parse_nested(tb, TCA_CBQ_MAX, opt))
 		return -EINVAL;
 
 	if (tb[TCA_CBQ_OVL_STRATEGY-1] &&
diff -Nru a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
--- a/net/sched/sch_dsmark.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/sch_dsmark.c	2005-01-19 13:44:46 -08:00
@@ -125,8 +125,7 @@
 	    "arg 0x%lx\n",sch,p,classid,parent,*arg);
 	if (*arg > p->indices)
 		return -ENOENT;
-	if (!opt || rtattr_parse(tb, TCA_DSMARK_MAX, RTA_DATA(opt),
-				 RTA_PAYLOAD(opt)))
+	if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt))
 		return -EINVAL;
 	if (tb[TCA_DSMARK_MASK-1]) {
 		if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK-1]))
diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c
--- a/net/sched/sch_generic.c	2005-01-19 13:44:45 -08:00
+++ b/net/sched/sch_generic.c	2005-01-19 13:44:45 -08:00
@@ -54,7 +54,7 @@
 
    qdisc_tree_lock must be grabbed BEFORE dev->queue_lock!
  */
-rwlock_t qdisc_tree_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(qdisc_tree_lock);
 
 void qdisc_lock_tree(struct net_device *dev)
 {
diff -Nru a/net/sched/sch_gred.c b/net/sched/sch_gred.c
--- a/net/sched/sch_gred.c	2005-01-19 13:44:47 -08:00
+++ b/net/sched/sch_gred.c	2005-01-19 13:44:47 -08:00
@@ -332,13 +332,11 @@
 	struct rtattr *tb2[TCA_GRED_DPS];
 	int i;
 
-	if (opt == NULL ||
-		rtattr_parse(tb, TCA_GRED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) )
-			return -EINVAL;
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt))
+		return -EINVAL;
 
 	if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) {
-		rtattr_parse(tb2, TCA_GRED_DPS, RTA_DATA(opt),
-		    RTA_PAYLOAD(opt));
+		rtattr_parse_nested(tb2, TCA_GRED_DPS, opt);
 
 	    if (tb2[TCA_GRED_DPS-1] == 0) 
 			return -EINVAL;
@@ -475,12 +473,11 @@
 	struct rtattr *tb[TCA_GRED_STAB];
 	struct rtattr *tb2[TCA_GRED_DPS];
 
-	if (opt == NULL ||
-		rtattr_parse(tb, TCA_GRED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) )
-			return -EINVAL;
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt))
+		return -EINVAL;
 
 	if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) {
-		rtattr_parse(tb2, TCA_GRED_DPS, RTA_DATA(opt),RTA_PAYLOAD(opt));
+		rtattr_parse_nested(tb2, TCA_GRED_DPS, opt);
 
 	    if (tb2[TCA_GRED_DPS-1] == 0) 
 			return -EINVAL;
diff -Nru a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
--- a/net/sched/sch_hfsc.c	2005-01-19 13:44:46 -08:00
+++ b/net/sched/sch_hfsc.c	2005-01-19 13:44:46 -08:00
@@ -1046,8 +1046,7 @@
 	struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL;
 	u64 cur_time;
 
-	if (opt == NULL ||
-	    rtattr_parse(tb, TCA_HFSC_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)))
+	if (opt == NULL || rtattr_parse_nested(tb, TCA_HFSC_MAX, opt))
 		return -EINVAL;
 
 	if (tb[TCA_HFSC_RSC-1]) {
diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c
--- a/net/sched/sch_htb.c	2005-01-19 13:44:47 -08:00
+++ b/net/sched/sch_htb.c	2005-01-19 13:44:47 -08:00
@@ -1267,7 +1267,7 @@
 	printk(KERN_INFO "HTB init, kernel part version %d.%d\n",
 			  HTB_VER >> 16,HTB_VER & 0xffff);
 #endif
-	if (!opt || rtattr_parse(tb, TCA_HTB_INIT, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+	if (!opt || rtattr_parse_nested(tb, TCA_HTB_INIT, opt) ||
 			tb[TCA_HTB_INIT-1] == NULL ||
 			RTA_PAYLOAD(tb[TCA_HTB_INIT-1]) < sizeof(*gopt)) {
 		printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
@@ -1559,7 +1559,7 @@
 	struct tc_htb_opt *hopt;
 
 	/* extract all subattrs from opt attr */
-	if (!opt || rtattr_parse(tb, TCA_HTB_RTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+	if (!opt || rtattr_parse_nested(tb, TCA_HTB_RTAB, opt) ||
 			tb[TCA_HTB_PARMS-1] == NULL ||
 			RTA_PAYLOAD(tb[TCA_HTB_PARMS-1]) < sizeof(*hopt))
 		goto failure;
diff -Nru a/net/sched/sch_red.c b/net/sched/sch_red.c
--- a/net/sched/sch_red.c	2005-01-19 13:44:48 -08:00
+++ b/net/sched/sch_red.c	2005-01-19 13:44:48 -08:00
@@ -364,7 +364,7 @@
 	struct tc_red_qopt *ctl;
 
 	if (opt == NULL ||
-	    rtattr_parse(tb, TCA_RED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+	    rtattr_parse_nested(tb, TCA_RED_STAB, opt) ||
 	    tb[TCA_RED_PARMS-1] == 0 || tb[TCA_RED_STAB-1] == 0 ||
 	    RTA_PAYLOAD(tb[TCA_RED_PARMS-1]) < sizeof(*ctl) ||
 	    RTA_PAYLOAD(tb[TCA_RED_STAB-1]) < 256)
diff -Nru a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
--- a/net/sched/sch_tbf.c	2005-01-19 13:44:45 -08:00
+++ b/net/sched/sch_tbf.c	2005-01-19 13:44:45 -08:00
@@ -310,7 +310,7 @@
 	struct Qdisc *child = NULL;
 	int max_size,n;
 
-	if (rtattr_parse(tb, TCA_TBF_PTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+	if (rtattr_parse_nested(tb, TCA_TBF_PTAB, opt) ||
 	    tb[TCA_TBF_PARMS-1] == NULL ||
 	    RTA_PAYLOAD(tb[TCA_TBF_PARMS-1]) < sizeof(*qopt))
 		goto done;
diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c	2005-01-19 13:44:45 -08:00
+++ b/net/sctp/associola.c	2005-01-19 13:44:45 -08:00
@@ -66,33 +66,8 @@
 
 /* 1st Level Abstractions. */
 
-/* Allocate and initialize a new association */
-struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
-					 const struct sock *sk,
-					 sctp_scope_t scope, int gfp)
-{
-	struct sctp_association *asoc;
-
-	asoc = t_new(struct sctp_association, gfp);
-	if (!asoc)
-		goto fail;
-
-	if (!sctp_association_init(asoc, ep, sk, scope, gfp))
-		goto fail_init;
-
-	asoc->base.malloced = 1;
-	SCTP_DBG_OBJCNT_INC(assoc);
-
-	return asoc;
-
-fail_init:
-	kfree(asoc);
-fail:
-	return NULL;
-}
-
 /* Initialize a new association from provided memory. */
-struct sctp_association *sctp_association_init(struct sctp_association *asoc,
+static struct sctp_association *sctp_association_init(struct sctp_association *asoc,
 					  const struct sctp_endpoint *ep,
 					  const struct sock *sk,
 					  sctp_scope_t scope,
@@ -204,6 +179,7 @@
 	asoc->c.peer_vtag = 0;
 	asoc->c.my_ttag   = 0;
 	asoc->c.peer_ttag = 0;
+	asoc->c.my_port = ep->base.bind_addr.port;
 
 	asoc->c.initial_tsn = sctp_generate_tsn(ep);
 
@@ -296,6 +272,31 @@
 	return NULL;
 }
 
+/* Allocate and initialize a new association */
+struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
+					 const struct sock *sk,
+					 sctp_scope_t scope, int gfp)
+{
+	struct sctp_association *asoc;
+
+	asoc = t_new(struct sctp_association, gfp);
+	if (!asoc)
+		goto fail;
+
+	if (!sctp_association_init(asoc, ep, sk, scope, gfp))
+		goto fail_init;
+
+	asoc->base.malloced = 1;
+	SCTP_DBG_OBJCNT_INC(assoc);
+
+	return asoc;
+
+fail_init:
+	kfree(asoc);
+fail:
+	return NULL;
+}
+
 /* Free this association if possible.  There may still be users, so
  * the actual deallocation may be delayed.
  */
@@ -500,7 +501,6 @@
 
 	peer->partial_bytes_acked = 0;
 	peer->flight_size = 0;
-	peer->error_threshold = peer->max_retrans;
 
 	/* By default, enable heartbeat for peer address. */
 	peer->hb_allowed = 1;
@@ -511,7 +511,7 @@
 	peer->hb_interval = msecs_to_jiffies(sp->paddrparam.spp_hbinterval);
 
 	/* Set the path max_retrans.  */
-	peer->max_retrans = asoc->max_retrans;
+	peer->max_retrans = sp->paddrparam.spp_pathmaxrxt;
 
 	/* Set the transport's RTO.initial value */
 	peer->rto = asoc->rto_initial;
@@ -714,18 +714,6 @@
 	return retval;
 }
 
-/* Allocate 'num' TSNs by incrementing the association's TSN by num. */
-__u32 sctp_association_get_tsn_block(struct sctp_association *asoc, int num)
-{
-	__u32 retval = asoc->next_tsn;
-
-	asoc->next_tsn += num;
-	asoc->unack_data += num;
-
-	return retval;
-}
-
-
 /* Compare two addresses to see if they match.  Wildcard addresses
  * only match themselves.
  */
@@ -760,14 +748,6 @@
 	return chunk;
 }
 
-/* Use this function for the packet prepend callback when no ECNE
- * packet is desired (e.g. some packets don't like to be bundled).
- */
-struct sctp_chunk *sctp_get_no_prepend(struct sctp_association *asoc)
-{
-	return NULL;
-}
-
 /*
  * Find which transport this TSN was sent on.
  */
@@ -861,7 +841,8 @@
 	struct sctp_chunk *chunk;
 	struct sock *sk;
 	struct sctp_inq *inqueue;
-	int state, subtype;
+	int state;
+	sctp_subtype_t subtype;
 	int error = 0;
 
 	/* The association should be held so we should be safe. */
@@ -872,7 +853,7 @@
 	sctp_association_hold(asoc);
 	while (NULL != (chunk = sctp_inq_pop(inqueue))) {
 		state = asoc->state;
-		subtype = chunk->chunk_hdr->type;
+		subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
 
 		/* Remember where the last DATA chunk came from so we
 		 * know where to send the SACK.
@@ -886,7 +867,7 @@
 			chunk->transport->last_time_heard = jiffies;
 
 		/* Run through the state machine. */
-		error = sctp_do_sm(SCTP_EVENT_T_CHUNK, SCTP_ST_CHUNK(subtype),
+		error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype,
 				   state, ep, asoc, chunk, GFP_ATOMIC);
 
 		/* Check to see if the association is freed in response to
diff -Nru a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
--- a/net/sctp/bind_addr.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/bind_addr.c	2005-01-19 13:44:47 -08:00
@@ -104,23 +104,6 @@
 	return error;
 }
 
-/* Create a new SCTP_bind_addr from nothing.  */
-struct sctp_bind_addr *sctp_bind_addr_new(int gfp)
-{
-	struct sctp_bind_addr *retval;
-
-	retval = t_new(struct sctp_bind_addr, gfp);
-	if (!retval)
-		goto nomem;
-
-	sctp_bind_addr_init(retval, 0);
-	retval->malloced = 1;
-	SCTP_DBG_OBJCNT_INC(bind_addr);
-
-nomem:
-	return retval;
-}
-
 /* Initialize the SCTP_bind_addr structure for either an endpoint or
  * an association.
  */
diff -Nru a/net/sctp/chunk.c b/net/sctp/chunk.c
--- a/net/sctp/chunk.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/chunk.c	2005-01-19 13:44:47 -08:00
@@ -51,7 +51,7 @@
  */
 
 /* Initialize datamsg from memory. */
-void sctp_datamsg_init(struct sctp_datamsg *msg)
+static void sctp_datamsg_init(struct sctp_datamsg *msg)
 {
 	atomic_set(&msg->refcnt, 1);
 	msg->send_failed = 0;
@@ -62,7 +62,7 @@
 }
 
 /* Allocate and initialize datamsg. */
-struct sctp_datamsg *sctp_datamsg_new(int gfp)
+SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(int gfp)
 {
 	struct sctp_datamsg *msg;
 	msg = kmalloc(sizeof(struct sctp_datamsg), gfp);
@@ -124,7 +124,7 @@
 }
 
 /* Hold a reference. */
-void sctp_datamsg_hold(struct sctp_datamsg *msg)
+static void sctp_datamsg_hold(struct sctp_datamsg *msg)
 {
 	atomic_inc(&msg->refcnt);
 }
@@ -151,7 +151,7 @@
 }
 
 /* Assign a chunk to this datamsg. */
-void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chunk)
+static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chunk)
 {
 	sctp_datamsg_hold(msg);
 	chunk->msg = msg;
diff -Nru a/net/sctp/command.c b/net/sctp/command.c
--- a/net/sctp/command.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/command.c	2005-01-19 13:44:47 -08:00
@@ -42,17 +42,6 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-/* Create a new sctp_command_sequence.  */
-sctp_cmd_seq_t *sctp_new_cmd_seq(int gfp)
-{
-	sctp_cmd_seq_t *retval = t_new(sctp_cmd_seq_t, gfp);
-
-	if (retval)
-		sctp_init_cmd_seq(retval);
-
-	return retval;
-}
-
 /* Initialize a block of memory as a command sequence. */
 int sctp_init_cmd_seq(sctp_cmd_seq_t *seq)
 {
@@ -77,13 +66,6 @@
 	return 0;
 }
 
-/* Rewind an sctp_cmd_seq_t to iterate from the start.  */
-int sctp_rewind_sequence(sctp_cmd_seq_t *seq)
-{
-	seq->next_cmd = 0;
-	return 1;		/* We always succeed. */
-}
-
 /* Return the next command structure in a sctp_cmd_seq.
  * Returns NULL at the end of the sequence.
  */
@@ -97,8 +79,3 @@
 	return retval;
 }
 
-/* Dispose of a command sequence.  */
-void sctp_free_cmd_seq(sctp_cmd_seq_t *seq)
-{
-	kfree(seq);
-}
diff -Nru a/net/sctp/debug.c b/net/sctp/debug.c
--- a/net/sctp/debug.c	2005-01-19 13:44:46 -08:00
+++ b/net/sctp/debug.c	2005-01-19 13:44:46 -08:00
@@ -98,23 +98,6 @@
 	return "unknown chunk";
 }
 
-/* These are printable form of variable-length parameters. */
-const char *sctp_param_tbl[SCTP_PARAM_ECN_CAPABLE + 1] = {
-	"",
-	"PARAM_HEARTBEAT_INFO",
-	"",
-	"",
-	"",
-	"PARAM_IPV4_ADDRESS",
-	"PARAM_IPV6_ADDRESS",
-	"PARAM_STATE_COOKIE",
-	"PARAM_UNRECOGNIZED_PARAMETERS",
-	"PARAM_COOKIE_PRESERVATIVE",
-	"",
-	"PARAM_HOST_NAME_ADDRESS",
-	"PARAM_SUPPORTED_ADDRESS_TYPES",
-};
-
 /* These are printable forms of the states.  */
 const char *sctp_state_tbl[SCTP_STATE_NUM_STATES] = {
 	"STATE_EMPTY",
@@ -171,6 +154,7 @@
 
 static const char *sctp_other_tbl[] = {
 	"NO_PENDING_TSN",
+        "ICMP_PROTO_UNREACH",
 };
 
 /* Lookup "other" debug name. */
@@ -178,7 +162,7 @@
 {
 	if (id.other < 0)
 		return "illegal 'other' event";
-	if (id.other < SCTP_EVENT_OTHER_MAX)
+	if (id.other <= SCTP_EVENT_OTHER_MAX)
 		return sctp_other_tbl[id.other];
 	return "unknown 'other' event";
 }
diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c	2005-01-19 13:44:46 -08:00
+++ b/net/sctp/endpointola.c	2005-01-19 13:44:46 -08:00
@@ -63,34 +63,11 @@
 /* Forward declarations for internal helpers. */
 static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep);
 
-/* Create a sctp_endpoint with all that boring stuff initialized.
- * Returns NULL if there isn't enough memory.
- */
-struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, int gfp)
-{
-	struct sctp_endpoint *ep;
-
-	/* Build a local endpoint. */
-	ep = t_new(struct sctp_endpoint, gfp);
-	if (!ep)
-		goto fail;
-	if (!sctp_endpoint_init(ep, sk, gfp))
-		goto fail_init;
-	ep->base.malloced = 1;
-	SCTP_DBG_OBJCNT_INC(ep);
-	return ep;
-
-fail_init:
-	kfree(ep);
-fail:
-	return NULL;
-}
-
 /*
  * Initialize the base fields of the endpoint structure.
  */
-struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
-					 struct sock *sk, int gfp)
+static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
+						struct sock *sk, int gfp)
 {
 	struct sctp_opt *sp = sctp_sk(sk);
 	memset(ep, 0, sizeof(struct sctp_endpoint));
@@ -160,6 +137,29 @@
 	return ep;
 }
 
+/* Create a sctp_endpoint with all that boring stuff initialized.
+ * Returns NULL if there isn't enough memory.
+ */
+struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, int gfp)
+{
+	struct sctp_endpoint *ep;
+
+	/* Build a local endpoint. */
+	ep = t_new(struct sctp_endpoint, gfp);
+	if (!ep)
+		goto fail;
+	if (!sctp_endpoint_init(ep, sk, gfp))
+		goto fail_init;
+	ep->base.malloced = 1;
+	SCTP_DBG_OBJCNT_INC(ep);
+	return ep;
+
+fail_init:
+	kfree(ep);
+fail:
+	return NULL;
+}
+
 /* Add an association to an endpoint.  */
 void sctp_endpoint_add_asoc(struct sctp_endpoint *ep,
 			    struct sctp_association *asoc)
@@ -184,7 +184,7 @@
 }
 
 /* Final destructor for endpoint.  */
-void sctp_endpoint_destroy(struct sctp_endpoint *ep)
+static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
 {
 	SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return);
 
@@ -257,7 +257,7 @@
  * We do a linear search of the associations for this endpoint.
  * We return the matching transport address too.
  */
-struct sctp_association *__sctp_endpoint_lookup_assoc(
+static struct sctp_association *__sctp_endpoint_lookup_assoc(
 	const struct sctp_endpoint *ep,
 	const union sctp_addr *paddr,
 	struct sctp_transport **transport)
@@ -345,7 +345,7 @@
 	sk = ep->base.sk;
 
 	while (NULL != (chunk = sctp_inq_pop(inqueue))) {
-		subtype.chunk = chunk->chunk_hdr->type;
+		subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
 
 		/* We might have grown an association since last we
 		 * looked, so try again.
diff -Nru a/net/sctp/input.c b/net/sctp/input.c
--- a/net/sctp/input.c	2005-01-19 13:44:45 -08:00
+++ b/net/sctp/input.c	2005-01-19 13:44:45 -08:00
@@ -63,11 +63,15 @@
 
 /* Forward declarations for internal helpers. */
 static int sctp_rcv_ootb(struct sk_buff *);
-struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
+static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
 				      const union sctp_addr *laddr,
 				      const union sctp_addr *paddr,
 				      struct sctp_transport **transportp);
-struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr);
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr);
+static struct sctp_association *__sctp_lookup_association(
+					const union sctp_addr *local,
+					const union sctp_addr *peer,
+					struct sctp_transport **pt);
 
 
 /* Calculate the SCTP checksum of an SCTP packet.  */
@@ -130,6 +134,10 @@
 
 	skb_pull(skb, sizeof(struct sctphdr));
 
+	/* Make sure we at least have chunk headers worth of data left. */
+	if (skb->len < sizeof(struct sctp_chunkhdr))
+		goto discard_it;
+
 	family = ipver2af(skb->nh.iph->version);
 	af = sctp_get_af_specific(family);
 	if (unlikely(!af))
@@ -284,6 +292,31 @@
 	}
 }
 
+/*
+ * SCTP Implementer's Guide, 2.37 ICMP handling procedures
+ *
+ * ICMP8) If the ICMP code is a "Unrecognized next header type encountered"
+ *        or a "Protocol Unreachable" treat this message as an abort
+ *        with the T bit set.
+ *
+ * This function sends an event to the state machine, which will abort the
+ * association.
+ *
+ */
+void sctp_icmp_proto_unreachable(struct sock *sk,
+                           struct sctp_endpoint *ep,
+                           struct sctp_association *asoc,
+                           struct sctp_transport *t)
+{
+	SCTP_DEBUG_PRINTK("%s\n",  __FUNCTION__);
+
+	sctp_do_sm(SCTP_EVENT_T_OTHER,
+		   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
+		   asoc->state, asoc->ep, asoc, NULL,
+		   GFP_ATOMIC);
+
+}
+
 /* Common lookup code for icmp/icmpv6 error handler. */
 struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
 			     struct sctphdr *sctphdr,
@@ -326,11 +359,12 @@
 	}
 
 	if (asoc) {
+		sk = asoc->base.sk;
+
 		if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) {
 			ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
 			goto out;
 		}
-		sk = asoc->base.sk;
 	} else
 		sk = ep->base.sk;
 
@@ -432,7 +466,13 @@
 			sctp_icmp_frag_needed(sk, asoc, transport, info);
 			goto out_unlock;
 		}
-
+		else {
+			if (ICMP_PROT_UNREACH == code) {
+				sctp_icmp_proto_unreachable(sk, ep, asoc,
+							    transport);
+				goto out_unlock;
+			}
+		}
 		err = icmp_err_convert[code].errno;
 		break;
 	case ICMP_TIME_EXCEEDED:
@@ -479,10 +519,10 @@
 	sctp_errhdr_t *err;
 
 	ch = (sctp_chunkhdr_t *) skb->data;
+	ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
 
 	/* Scan through all the chunks in the packet.  */
-	do {
-		ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
+	while (ch_end > (__u8 *)ch && ch_end < skb->tail) {
 
 		/* RFC 8.4, 2) If the OOTB packet contains an ABORT chunk, the
 		 * receiver MUST silently discard the OOTB packet and take no
@@ -513,7 +553,8 @@
 		}
 
 		ch = (sctp_chunkhdr_t *) ch_end;
-	} while (ch_end < skb->tail);
+	        ch_end = ((__u8 *) ch) + WORD_ROUND(ntohs(ch->length));
+	}
 
 	return 0;
 
@@ -522,7 +563,7 @@
 }
 
 /* Insert endpoint into the hash table.  */
-void __sctp_hash_endpoint(struct sctp_endpoint *ep)
+static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
 {
 	struct sctp_ep_common **epp;
 	struct sctp_ep_common *epb;
@@ -552,7 +593,7 @@
 }
 
 /* Remove endpoint from the hash table.  */
-void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
+static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
 {
 	struct sctp_hashbucket *head;
 	struct sctp_ep_common *epb;
@@ -584,7 +625,7 @@
 }
 
 /* Look up an endpoint. */
-struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
+static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr)
 {
 	struct sctp_hashbucket *head;
 	struct sctp_ep_common *epb;
@@ -610,16 +651,8 @@
 	return ep;
 }
 
-/* Add an association to the hash. Local BH-safe. */
-void sctp_hash_established(struct sctp_association *asoc)
-{
-	sctp_local_bh_disable();
-	__sctp_hash_established(asoc);
-	sctp_local_bh_enable();
-}
-
 /* Insert association into the hash table.  */
-void __sctp_hash_established(struct sctp_association *asoc)
+static void __sctp_hash_established(struct sctp_association *asoc)
 {
 	struct sctp_ep_common **epp;
 	struct sctp_ep_common *epb;
@@ -642,16 +675,16 @@
 	sctp_write_unlock(&head->lock);
 }
 
-/* Remove association from the hash table.  Local BH-safe. */
-void sctp_unhash_established(struct sctp_association *asoc)
+/* Add an association to the hash. Local BH-safe. */
+void sctp_hash_established(struct sctp_association *asoc)
 {
 	sctp_local_bh_disable();
-	__sctp_unhash_established(asoc);
+	__sctp_hash_established(asoc);
 	sctp_local_bh_enable();
 }
 
 /* Remove association from the hash table.  */
-void __sctp_unhash_established(struct sctp_association *asoc)
+static void __sctp_unhash_established(struct sctp_association *asoc)
 {
 	struct sctp_hashbucket *head;
 	struct sctp_ep_common *epb;
@@ -675,8 +708,16 @@
 	sctp_write_unlock(&head->lock);
 }
 
+/* Remove association from the hash table.  Local BH-safe. */
+void sctp_unhash_established(struct sctp_association *asoc)
+{
+	sctp_local_bh_disable();
+	__sctp_unhash_established(asoc);
+	sctp_local_bh_enable();
+}
+
 /* Look up an association. */
-struct sctp_association *__sctp_lookup_association(
+static struct sctp_association *__sctp_lookup_association(
 					const union sctp_addr *local,
 					const union sctp_addr *peer,
 					struct sctp_transport **pt)
@@ -713,8 +754,9 @@
 }
 
 /* Look up an association. BH-safe. */
+SCTP_STATIC
 struct sctp_association *sctp_lookup_association(const union sctp_addr *laddr,
-					    const union sctp_addr *paddr,
+						 const union sctp_addr *paddr,
 					    struct sctp_transport **transportp)
 {
 	struct sctp_association *asoc;
@@ -784,6 +826,14 @@
 		return NULL;
 	}
 
+	/* The code below will attempt to walk the chunk and extract
+	 * parameter information.  Before we do that, we need to verify
+	 * that the chunk length doesn't cause overflow.  Otherwise, we'll
+	 * walk off the end.
+	 */
+	if (WORD_ROUND(ntohs(ch->length)) > skb->len)
+		return NULL;
+
 	/*
 	 * This code will NOT touch anything inside the chunk--it is
 	 * strictly READ-ONLY.
@@ -821,7 +871,7 @@
 }
 
 /* Lookup an association for an inbound skb. */
-struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
+static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
 				      const union sctp_addr *paddr,
 				      const union sctp_addr *laddr,
 				      struct sctp_transport **transportp)
diff -Nru a/net/sctp/inqueue.c b/net/sctp/inqueue.c
--- a/net/sctp/inqueue.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/inqueue.c	2005-01-19 13:44:47 -08:00
@@ -59,19 +59,6 @@
 	queue->malloced = 0;
 }
 
-/* Create an initialized sctp_inq.  */
-struct sctp_inq *sctp_inq_new(void)
-{
-	struct sctp_inq *retval;
-
-	retval = t_new(struct sctp_inq, GFP_ATOMIC);
-	if (retval) {
-		sctp_inq_init(retval);
-		retval->malloced = 1;
-	}
-        return retval;
-}
-
 /* Release the memory associated with an SCTP inqueue.  */
 void sctp_inq_free(struct sctp_inq *queue)
 {
@@ -157,14 +144,36 @@
 	}
 
         chunk->chunk_hdr = ch;
-        chunk->chunk_end = ((__u8 *) ch)
-		+ WORD_ROUND(ntohs(ch->length));
+        chunk->chunk_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
+	/* In the unlikely case of an IP reassembly, the skb could be
+	 * non-linear. If so, update chunk_end so that it doesn't go past
+	 * the skb->tail.
+	 */
+	if (unlikely(skb_is_nonlinear(chunk->skb))) {
+		if (chunk->chunk_end > chunk->skb->tail)
+			chunk->chunk_end = chunk->skb->tail;
+	}
 	skb_pull(chunk->skb, sizeof(sctp_chunkhdr_t));
 	chunk->subh.v = NULL; /* Subheader is no longer valid.  */
 
 	if (chunk->chunk_end < chunk->skb->tail) {
 		/* This is not a singleton */
 		chunk->singleton = 0;
+	} else if (chunk->chunk_end > chunk->skb->tail) {
+                /* RFC 2960, Section 6.10  Bundling
+		 *
+		 * Partial chunks MUST NOT be placed in an SCTP packet.
+		 * If the receiver detects a partial chunk, it MUST drop
+		 * the chunk.  
+		 *
+		 * Since the end of the chunk is past the end of our buffer
+		 * (which contains the whole packet, we can freely discard
+		 * the whole packet.
+		 */
+		sctp_chunk_free(chunk);
+		chunk = queue->in_progress = NULL;
+
+		return NULL;
 	} else {
 		/* We are at the end of the packet, so mark the chunk
 		 * in case we need to send a SACK.
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/ipv6.c	2005-01-19 13:44:47 -08:00
@@ -84,8 +84,8 @@
 };
 
 /* ICMP error handler. */
-void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-		 int type, int code, int offset, __u32 info)
+SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			     int type, int code, int offset, __u32 info)
 {
 	struct inet6_dev *idev;
 	struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
@@ -122,6 +122,12 @@
 	case ICMPV6_PKT_TOOBIG:
 		sctp_icmp_frag_needed(sk, asoc, transport, ntohl(info));
 		goto out_unlock;
+	case ICMPV6_PARAMPROB:
+		if (ICMPV6_UNK_NEXTHDR == code) {
+			sctp_icmp_proto_unreachable(sk, ep, asoc, transport);
+			goto out_unlock;
+		}
+		break;
 	default:
 		break;
 	}
@@ -188,9 +194,9 @@
 /* Returns the dst cache entry for the given source and destination ip
  * addresses.
  */
-struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
-				  union sctp_addr *daddr,
-				  union sctp_addr *saddr)
+static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
+					 union sctp_addr *daddr,
+					 union sctp_addr *saddr)
 {
 	struct dst_entry *dst;
 	struct flowi fl;
@@ -251,8 +257,10 @@
 /* Fills in the source address(saddr) based on the destination address(daddr)
  * and asoc's bind address list.
  */
-void sctp_v6_get_saddr(struct sctp_association *asoc, struct dst_entry *dst,
-		       union sctp_addr *daddr, union sctp_addr *saddr)
+static void sctp_v6_get_saddr(struct sctp_association *asoc,
+			      struct dst_entry *dst,
+			      union sctp_addr *daddr,
+			      union sctp_addr *saddr)
 {
 	struct sctp_bind_addr *bp;
 	rwlock_t *addr_lock;
@@ -577,8 +585,8 @@
 }
 
 /* Create and initialize a new sk for the socket to be returned by accept(). */
-struct sock *sctp_v6_create_accept_sk(struct sock *sk,
-				      struct sctp_association *asoc)
+static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
+					     struct sctp_association *asoc)
 {
 	struct inet_sock *inet = inet_sk(sk);
 	struct sock *newsk;
diff -Nru a/net/sctp/objcnt.c b/net/sctp/objcnt.c
--- a/net/sctp/objcnt.c	2005-01-19 13:44:45 -08:00
+++ b/net/sctp/objcnt.c	2005-01-19 13:44:45 -08:00
@@ -62,7 +62,7 @@
 /* An array to make it easy to pretty print the debug information
  * to the proc fs.
  */
-sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
+static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
 	SCTP_DBG_OBJCNT_ENTRY(sock),
 	SCTP_DBG_OBJCNT_ENTRY(ep),
 	SCTP_DBG_OBJCNT_ENTRY(assoc),
diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c
--- a/net/sctp/outqueue.c	2005-01-19 13:44:46 -08:00
+++ b/net/sctp/outqueue.c	2005-01-19 13:44:46 -08:00
@@ -190,19 +190,6 @@
 	return 0;
 }
 
-/* Generate a new outqueue.  */
-struct sctp_outq *sctp_outq_new(struct sctp_association *asoc)
-{
-	struct sctp_outq *q;
-
-	q = t_new(struct sctp_outq, GFP_KERNEL);
-	if (q) {
-		sctp_outq_init(asoc, q);
-		q->malloced = 1;
-	}
-	return q;
-}
-
 /* Initialize an existing sctp_outq.  This does the boring stuff.
  * You still need to define handlers if you really want to DO
  * something with this structure...
@@ -362,7 +349,7 @@
 /* Insert a chunk into the sorted list based on the TSNs.  The retransmit list
  * and the abandoned list are in ascending order.
  */
-void sctp_insert_list(struct list_head *head, struct list_head *new)
+static void sctp_insert_list(struct list_head *head, struct list_head *new)
 {
 	struct list_head *pos;
 	struct sctp_chunk *nchunk, *lchunk;
diff -Nru a/net/sctp/proc.c b/net/sctp/proc.c
--- a/net/sctp/proc.c	2005-01-19 13:44:48 -08:00
+++ b/net/sctp/proc.c	2005-01-19 13:44:48 -08:00
@@ -39,7 +39,7 @@
 #include <linux/init.h>
 #include <net/sctp/sctp.h>
 
-struct snmp_mib sctp_snmp_list[] = {
+static struct snmp_mib sctp_snmp_list[] = {
 	SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB),
 	SNMP_MIB_ITEM("SctpActiveEstabs", SCTP_MIB_ACTIVEESTABS),
 	SNMP_MIB_ITEM("SctpPassiveEstabs", SCTP_MIB_PASSIVEESTABS),
diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/protocol.c	2005-01-19 13:44:47 -08:00
@@ -65,7 +65,7 @@
 DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics);
 
 struct idr sctp_assocs_id;
-spinlock_t sctp_assocs_id_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(sctp_assocs_id_lock);
 
 /* This is the global socket data structure used for responding to
  * the Out-of-the-blue (OOTB) packets.  A control sock will be created
@@ -95,7 +95,7 @@
 }
 
 /* Set up the proc fs entry for the SCTP protocol. */
-__init int sctp_proc_init(void)
+static __init int sctp_proc_init(void)
 {
 	if (!proc_net_sctp) {
 		struct proc_dir_entry *ent;
@@ -124,7 +124,7 @@
  * Note: Do not make this __exit as it is used in the init error
  * path.
  */
-void sctp_proc_exit(void)
+static void sctp_proc_exit(void)
 {
 	sctp_snmp_proc_exit();
 	sctp_eps_proc_exit();
@@ -428,9 +428,9 @@
  * addresses. If an association is passed, trys to get a dst entry with a
  * source address that matches an address in the bind address list.
  */
-struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
-				  union sctp_addr *daddr,
-				  union sctp_addr *saddr)
+static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
+					 union sctp_addr *daddr,
+					 union sctp_addr *saddr)
 {
 	struct rtable *rt;
 	struct flowi fl;
@@ -520,10 +520,10 @@
 /* For v4, the source address is cached in the route entry(dst). So no need
  * to cache it separately and hence this is an empty routine.
  */
-void sctp_v4_get_saddr(struct sctp_association *asoc,
-		       struct dst_entry *dst,
-		       union sctp_addr *daddr,
-		       union sctp_addr *saddr)
+static void sctp_v4_get_saddr(struct sctp_association *asoc,
+			      struct dst_entry *dst,
+			      union sctp_addr *daddr,
+			      union sctp_addr *saddr)
 {
 	struct rtable *rt = (struct rtable *)dst;
 
@@ -547,8 +547,8 @@
 }
 
 /* Create and initialize a new sk for the socket returned by accept(). */
-struct sock *sctp_v4_create_accept_sk(struct sock *sk,
-				      struct sctp_association *asoc)
+static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
+					     struct sctp_association *asoc)
 {
 	struct sock *newsk;
 	struct inet_sock *inet = inet_sk(sk);
@@ -639,7 +639,7 @@
  * Initialize the control inode/socket with a control endpoint data
  * structure.  This endpoint is reserved exclusively for the OOTB processing.
  */
-int sctp_ctl_sock_init(void)
+static int sctp_ctl_sock_init(void)
 {
 	int err;
 	sa_family_t family;
@@ -808,7 +808,7 @@
 	return ip_queue_xmit(skb, ipfragok);
 }
 
-struct sctp_af sctp_ipv4_specific;
+static struct sctp_af sctp_ipv4_specific;
 
 static struct sctp_pf sctp_pf_inet = {
 	.event_msgname = sctp_inet_event_msgname,
@@ -829,7 +829,7 @@
 };
 
 /* Socket operations.  */
-struct proto_ops inet_seqpacket_ops = {
+static struct proto_ops inet_seqpacket_ops = {
 	.family      = PF_INET,
 	.owner       = THIS_MODULE,
 	.release     = inet_release,       /* Needs to be wrapped... */
@@ -878,7 +878,7 @@
 };
 
 /* IPv4 address related functions.  */
-struct sctp_af sctp_ipv4_specific = {
+static struct sctp_af sctp_ipv4_specific = {
 	.sctp_xmit      = sctp_v4_xmit,
 	.setsockopt     = ip_setsockopt,
 	.getsockopt     = ip_getsockopt,
@@ -959,7 +959,7 @@
 }
 
 /* Initialize the universe into something sensible.  */
-__init int sctp_init(void)
+SCTP_STATIC __init int sctp_init(void)
 {
 	int i;
 	int status = -EINVAL;
@@ -1196,7 +1196,7 @@
 }
 
 /* Exit handler for the SCTP protocol.  */
-__exit void sctp_exit(void)
+SCTP_STATIC __exit void sctp_exit(void)
 {
 	/* BUG.  This should probably do something useful like clean
 	 * up all the remaining associations and all that memory.
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c	2005-01-19 13:44:46 -08:00
+++ b/net/sctp/sm_make_chunk.c	2005-01-19 13:44:46 -08:00
@@ -67,6 +67,19 @@
 
 extern kmem_cache_t *sctp_chunk_cachep;
 
+SCTP_STATIC
+struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
+				   __u8 type, __u8 flags, int paylen);
+static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
+					const struct sctp_association *asoc,
+					const struct sctp_chunk *init_chunk,
+					int *cookie_len,
+					const __u8 *raw_addrs, int addrs_len);
+static int sctp_process_param(struct sctp_association *asoc,
+			      union sctp_params param,
+			      const union sctp_addr *peer_addr,
+			      int gfp);
+
 /* What was the inbound interface for this chunk? */
 int sctp_chunk_iif(const struct sctp_chunk *chunk)
 {
@@ -559,52 +572,6 @@
 	return retval;
 }
 
-/* Make a DATA chunk for the given association.  Populate the data
- * payload.
- */
-struct sctp_chunk *sctp_make_datafrag(struct sctp_association *asoc,
-				 const struct sctp_sndrcvinfo *sinfo,
-				 int data_len, const __u8 *data,
-				 __u8 flags, __u16 ssn)
-{
-	struct sctp_chunk *retval;
-
-	retval = sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, ssn);
-	if (retval)
-		sctp_addto_chunk(retval, data_len, data);
-
-	return retval;
-}
-
-/* Make a DATA chunk for the given association to ride on stream id
- * 'stream', with a payload id of 'payload', and a body of 'data'.
- */
-struct sctp_chunk *sctp_make_data(struct sctp_association *asoc,
-			     const struct sctp_sndrcvinfo *sinfo,
-			     int data_len, const __u8 *data)
-{
-	struct sctp_chunk *retval = NULL;
-
-	retval = sctp_make_data_empty(asoc, sinfo, data_len);
-	if (retval)
-		sctp_addto_chunk(retval, data_len, data);
-        return retval;
-}
-
-/* Make a DATA chunk for the given association to ride on stream id
- * 'stream', with a payload id of 'payload', and a body big enough to
- * hold 'data_len' octets of data.  We use this version when we need
- * to build the message AFTER allocating memory.
- */
-struct sctp_chunk *sctp_make_data_empty(struct sctp_association *asoc,
-				   const struct sctp_sndrcvinfo *sinfo,
-				   int data_len)
-{
-	__u8 flags = SCTP_DATA_NOT_FRAG;
-
-	return sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, 0);
-}
-
 /* Create a selective ackowledgement (SACK) for the given
  * association.  This reports on which TSN's we've seen to date,
  * including duplicates and gaps.
@@ -881,6 +848,31 @@
 	return retval;
 }
 
+/* Make an ABORT chunk with a PROTOCOL VIOLATION cause code. */ 
+struct sctp_chunk *sctp_make_abort_violation(
+	const struct sctp_association *asoc,
+	const struct sctp_chunk *chunk,
+	const __u8   *payload,
+	const size_t paylen)
+{
+	struct sctp_chunk  *retval;
+	struct sctp_paramhdr phdr;
+
+	retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen
+					+ sizeof(sctp_chunkhdr_t));
+	if (!retval)
+		goto end;
+
+	sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, payload, paylen);
+
+	phdr.type = htons(chunk->chunk_hdr->type);
+	phdr.length = chunk->chunk_hdr->length;
+	sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &phdr);
+
+end:
+	return retval;
+}
+
 /* Make a HEARTBEAT chunk.  */
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
 				  const struct sctp_transport *transport,
@@ -933,7 +925,7 @@
 /* Create an Operation Error chunk with the specified space reserved.
  * This routine can be used for containing multiple causes in the chunk.
  */
-struct sctp_chunk *sctp_make_op_error_space(
+static struct sctp_chunk *sctp_make_op_error_space(
 	const struct sctp_association *asoc,
 	const struct sctp_chunk *chunk,
 	size_t size)
@@ -1034,7 +1026,6 @@
 	SCTP_DBG_OBJCNT_INC(chunk);
 	atomic_set(&retval->refcnt, 1);
 
-
 nodata:
 	return retval;
 }
@@ -1062,6 +1053,7 @@
 /* Create a new chunk, setting the type and flags headers from the
  * arguments, reserving enough space for a 'paylen' byte payload.
  */
+SCTP_STATIC
 struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
 				   __u8 type, __u8 flags, int paylen)
 {
@@ -1261,7 +1253,7 @@
 /* Build a cookie representing asoc.
  * This INCLUDES the param header needed to put the cookie in the INIT ACK.
  */
-sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
+static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 				      const struct sctp_association *asoc,
 				      const struct sctp_chunk *init_chunk,
 				      int *cookie_len,
@@ -1409,6 +1401,24 @@
 	}
 
 no_hmac:
+	/* IG Section 2.35.2:
+	 *  3) Compare the port numbers and the verification tag contained
+	 *     within the COOKIE ECHO chunk to the actual port numbers and the
+	 *     verification tag within the SCTP common header of the received
+	 *     packet. If these values do not match the packet MUST be silently
+	 *     discarded,
+	 */
+	if (ntohl(chunk->sctp_hdr->vtag) != bear_cookie->my_vtag) {
+		*error = -SCTP_IERROR_BAD_TAG;
+		goto fail;
+	}
+
+	if (ntohs(chunk->sctp_hdr->source) != bear_cookie->peer_addr.v4.sin_port ||
+	    ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) {
+		*error = -SCTP_IERROR_BAD_PORTS;
+		goto fail;
+	}
+
 	/* Check to see if the cookie is stale.  If there is already
 	 * an association, there is no need to check cookie's expiration
 	 * for init collision case of lost COOKIE ACK.
@@ -1547,6 +1557,30 @@
 	return 0;
 }
 
+static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
+					struct sctp_paramhdr *param,
+					const struct sctp_chunk *chunk,
+					struct sctp_chunk **errp)
+{
+	char		error[] = "The following parameter had invalid length:";
+	size_t		payload_len = WORD_ROUND(sizeof(error)) + 
+						sizeof(sctp_paramhdr_t);
+
+
+	/* Create an error chunk and fill it in with our payload. */
+	if (!*errp)
+		*errp = sctp_make_op_error_space(asoc, chunk, payload_len);
+
+	if (*errp) {
+		sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION, error,
+				sizeof(error));
+		sctp_addto_chunk(*errp, sizeof(sctp_paramhdr_t), param);
+	}
+
+	return 0;
+}
+
+
 /* Do not attempt to handle the HOST_NAME parm.  However, do
  * send back an indicator to the peer.
  */
@@ -1725,6 +1759,18 @@
 
 	} /* for (loop through all parameters) */
 
+	/* There is a possibility that a parameter length was bad and
+	 * in that case we would have stoped walking the parameters.
+	 * The current param.p would point at the bad one.
+	 * Current consensus on the mailing list is to generate a PROTOCOL
+	 * VIOLATION error.  We build the ERROR chunk here and let the normal
+	 * error handling code build and send the packet.
+	 */
+	if (param.v < (void*)chunk->chunk_end - sizeof(sctp_paramhdr_t)) {
+		sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
+		return 0;
+	}
+
 	/* The only missing mandatory param possible today is
 	 * the state cookie for an INIT-ACK chunk.
 	 */
@@ -1912,8 +1958,10 @@
  * work we do.  In particular, we should not build transport
  * structures for the addresses.
  */
-int sctp_process_param(struct sctp_association *asoc, union sctp_params param,
-		       const union sctp_addr *peer_addr, int gfp)
+static int sctp_process_param(struct sctp_association *asoc,
+			      union sctp_params param,
+			      const union sctp_addr *peer_addr,
+			      int gfp)
 {
 	union sctp_addr addr;
 	int i;
@@ -2078,8 +2126,9 @@
  *
  * Address Parameter and other parameter will not be wrapped in this function 
  */
-struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
-				    union sctp_addr *addr, int vparam_len)
+static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
+					   union sctp_addr *addr,
+					   int vparam_len)
 {
 	sctp_addiphdr_t asconf;
 	struct sctp_chunk *retval;
@@ -2248,8 +2297,8 @@
  *
  * Create an ASCONF_ACK chunk with enough space for the parameter responses. 
  */
-struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
-					__u32 serial, int vparam_len)
+static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
+					       __u32 serial, int vparam_len)
 {
 	sctp_addiphdr_t		asconf;
 	struct sctp_chunk	*retval;
diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
--- a/net/sctp/sm_sideeffect.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/sm_sideeffect.c	2005-01-19 13:44:47 -08:00
@@ -55,6 +55,24 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
+static int sctp_cmd_interpreter(sctp_event_t event_type,
+				sctp_subtype_t subtype,
+				sctp_state_t state,
+				struct sctp_endpoint *ep,
+				struct sctp_association *asoc,
+				void *event_arg,
+			 	sctp_disposition_t status,
+				sctp_cmd_seq_t *commands,
+				int gfp);
+static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+			     sctp_state_t state,
+			     struct sctp_endpoint *ep,
+			     struct sctp_association *asoc,
+			     void *event_arg,
+			     sctp_disposition_t status,
+			     sctp_cmd_seq_t *commands,
+			     int gfp);
+
 /********************************************************************
  * Helper functions
  ********************************************************************/
@@ -134,8 +152,8 @@
 }
 
 /* Generate SACK if necessary.  We call this at the end of a packet.  */
-int sctp_gen_sack(struct sctp_association *asoc, int force,
-		  sctp_cmd_seq_t *commands)
+static int sctp_gen_sack(struct sctp_association *asoc, int force,
+			 sctp_cmd_seq_t *commands)
 {
 	__u32 ctsn, max_tsn_seen;
 	struct sctp_chunk *sack;
@@ -276,31 +294,31 @@
 	sctp_association_put(asoc);
 }
 
-void sctp_generate_t1_cookie_event(unsigned long data)
+static void sctp_generate_t1_cookie_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T1_COOKIE);
 }
 
-void sctp_generate_t1_init_event(unsigned long data)
+static void sctp_generate_t1_init_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T1_INIT);
 }
 
-void sctp_generate_t2_shutdown_event(unsigned long data)
+static void sctp_generate_t2_shutdown_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T2_SHUTDOWN);
 }
 
-void sctp_generate_t4_rto_event(unsigned long data)
+static void sctp_generate_t4_rto_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_T4_RTO);
 }
 
-void sctp_generate_t5_shutdown_guard_event(unsigned long data)
+static void sctp_generate_t5_shutdown_guard_event(unsigned long data)
 {
         struct sctp_association *asoc = (struct sctp_association *)data;
         sctp_generate_timeout_event(asoc,
@@ -308,7 +326,7 @@
 
 } /* sctp_generate_t5_shutdown_guard_event() */
 
-void sctp_generate_autoclose_event(unsigned long data)
+static void sctp_generate_autoclose_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_AUTOCLOSE);
@@ -353,7 +371,7 @@
 }
 
 /* Inject a SACK Timeout event into the state machine.  */
-void sctp_generate_sack_event(unsigned long data)
+static void sctp_generate_sack_event(unsigned long data)
 {
 	struct sctp_association *asoc = (struct sctp_association *) data;
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK);
@@ -397,7 +415,7 @@
 	asoc->overall_error_count++;
 
 	if (transport->active &&
-	    (transport->error_count++ >= transport->error_threshold)) {
+	    (transport->error_count++ >= transport->max_retrans)) {
 		SCTP_DEBUG_PRINTK("transport_strike: transport "
 				  "IP:%d.%d.%d.%d failed.\n",
 				  NIPQUAD(transport->ipaddr.v4.sin_addr));
@@ -857,14 +875,14 @@
 /*****************************************************************
  * This the master state function side effect processing function.
  *****************************************************************/
-int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
-		      sctp_state_t state,
-		      struct sctp_endpoint *ep,
-		      struct sctp_association *asoc,
-		      void *event_arg,
-		      sctp_disposition_t status,
-		      sctp_cmd_seq_t *commands,
-		      int gfp)
+static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+			     sctp_state_t state,
+			     struct sctp_endpoint *ep,
+			     struct sctp_association *asoc,
+			     void *event_arg,
+			     sctp_disposition_t status,
+			     sctp_cmd_seq_t *commands,
+			     int gfp)
 {
 	int error;
 
@@ -944,11 +962,15 @@
  ********************************************************************/
 
 /* This is the side-effect interpreter.  */
-int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
-			 sctp_state_t state, struct sctp_endpoint *ep,
-			 struct sctp_association *asoc, void *event_arg,
-			 sctp_disposition_t status, sctp_cmd_seq_t *commands,
-			 int gfp)
+static int sctp_cmd_interpreter(sctp_event_t event_type,
+				sctp_subtype_t subtype,
+				sctp_state_t state,
+				struct sctp_endpoint *ep,
+				struct sctp_association *asoc,
+				void *event_arg,
+			 	sctp_disposition_t status,
+				sctp_cmd_seq_t *commands,
+				int gfp)
 {
 	int error = 0;
 	int force;
diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
--- a/net/sctp/sm_statefuns.c	2005-01-19 13:44:45 -08:00
+++ b/net/sctp/sm_statefuns.c	2005-01-19 13:44:45 -08:00
@@ -65,6 +65,53 @@
 #include <net/sctp/sm.h>
 #include <net/sctp/structs.h>
 
+static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
+				  const struct sctp_association *asoc,
+				  struct sctp_chunk *chunk,
+				  const void *payload,
+				  size_t paylen);
+static int sctp_eat_data(const struct sctp_association *asoc,
+			 struct sctp_chunk *chunk,
+			 sctp_cmd_seq_t *commands);
+static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
+					     const struct sctp_chunk *chunk);
+static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
+				       const struct sctp_association *asoc,
+				       const struct sctp_chunk *chunk,
+				       sctp_cmd_seq_t *commands,
+				       struct sctp_chunk *err_chunk);
+static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
+						 const struct sctp_association *asoc,
+						 const sctp_subtype_t type,
+						 void *arg,
+						 sctp_cmd_seq_t *commands);
+static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
+					     const struct sctp_association *asoc,
+					     const sctp_subtype_t type,
+					     void *arg,
+					     sctp_cmd_seq_t *commands);
+static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
+
+
+/* Small helper function that checks if the chunk length
+ * is of the appropriate length.  The 'required_length' argument
+ * is set to be the size of a specific chunk we are testing.
+ * Return Values:  1 = Valid length
+ * 		   0 = Invalid length
+ *
+ */
+static inline int
+sctp_chunk_length_valid(struct sctp_chunk *chunk,
+			   __u16 required_length)
+{
+	__u16 chunk_length = ntohs(chunk->chunk_hdr->length);
+
+	if (unlikely(chunk_length < required_length))
+		return 0;
+
+	return 1;
+}
+
 /**********************************************************
  * These are the state functions for handling chunk events.
  **********************************************************/
@@ -199,9 +246,14 @@
 	/* 6.10 Bundling
 	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 	 * SHUTDOWN COMPLETE with any other chunks.
+	 * 
+	 * IG Section 2.11.2
+	 * Furthermore, we require that the receiver of an INIT chunk MUST
+	 * enforce these rules by silently discarding an arriving packet
+	 * with an INIT chunk that is bundled with other chunks.
 	 */
 	if (!chunk->singleton)
-		return SCTP_DISPOSITION_VIOLATION;
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
 	/* If the packet is an OOTB packet which is temporarily on the
 	 * control endpoint, respond with an ABORT.
@@ -225,6 +277,14 @@
 	if (chunk->sctp_hdr->vtag != 0)
 		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
+	/* Make sure that the INIT chunk has a valid length.
+	 * Normally, this would cause an ABORT with a Protocol Violation
+	 * error, but since we don't have an association, we'll
+	 * just discard the packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 	/* Verify the INIT chunk before processing it. */
 	err_chunk = NULL;
 	if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
@@ -376,6 +436,13 @@
 	struct sctp_packet *packet;
 	sctp_disposition_t ret;
 
+	if (!sctp_vtag_verify(chunk, asoc))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* Make sure that the INIT-ACK chunk has a valid length */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
 	/* 6.10 Bundling
 	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 	 * SHUTDOWN COMPLETE with any other chunks.
@@ -383,9 +450,6 @@
 	if (!chunk->singleton)
 		return SCTP_DISPOSITION_VIOLATION;
 
-	if (!sctp_vtag_verify(chunk, asoc))
-		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
 	/* Grab the INIT header.  */
 	chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
@@ -542,6 +606,14 @@
 	if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
 		return sctp_sf_ootb(ep, asoc, type, arg, commands);
 
+	/* Make sure that the COOKIE_ECHO chunk has a valid length.
+	 * In this case, we check that we have enough for at least a
+	 * chunk header.  More detailed verification is done
+	 * in sctp_unpack_cookie().
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 	/* "Decode" the chunk.  We have no optional parameters so we
 	 * are in good shape.
 	 */
@@ -687,6 +759,13 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Verify that the chunk length for the COOKIE-ACK is OK.
+	 * If we don't do this, any bundled chunks may be junked.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* Reset init error count upon receipt of COOKIE-ACK,
 	 * to avoid problems with the managemement of this
 	 * counter in stale cookie situations when a transition back
@@ -748,11 +827,11 @@
 }
 
 /* Generate and sendout a heartbeat packet.  */
-sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
-				     const struct sctp_association *asoc,
-				     const sctp_subtype_t type,
-				     void *arg,
-				     sctp_cmd_seq_t *commands)
+static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep,
+					    const struct sctp_association *asoc,
+					    const sctp_subtype_t type,
+					    void *arg,
+					    sctp_cmd_seq_t *commands)
 {
 	struct sctp_transport *transport = (struct sctp_transport *) arg;
 	struct sctp_chunk *reply;
@@ -859,6 +938,11 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the HEARTBEAT chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* 8.3 The receiver of the HEARTBEAT should immediately
 	 * respond with a HEARTBEAT ACK that contains the Heartbeat
 	 * Information field copied from the received HEARTBEAT chunk.
@@ -922,6 +1006,11 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the HEARTBEAT-ACK chunk has a valid length.  */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
 	from_addr = hbinfo->daddr;
 	link = sctp_assoc_lookup_paddr(asoc, &from_addr);
@@ -1165,9 +1254,14 @@
 	/* 6.10 Bundling
 	 * An endpoint MUST NOT bundle INIT, INIT ACK or
 	 * SHUTDOWN COMPLETE with any other chunks.
+	 *
+	 * IG Section 2.11.2
+	 * Furthermore, we require that the receiver of an INIT chunk MUST
+	 * enforce these rules by silently discarding an arriving packet
+	 * with an INIT chunk that is bundled with other chunks.
 	 */
 	if (!chunk->singleton)
-		return SCTP_DISPOSITION_VIOLATION;
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
 	/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
 	 * Tag. 
@@ -1175,6 +1269,13 @@
 	if (chunk->sctp_hdr->vtag != 0)
 		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
+	/* Make sure that the INIT chunk has a valid length.
+	 * In this case, we generate a protocol violation since we have
+	 * an association established.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
 	/* Grab the INIT header.  */
 	chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
 
@@ -1718,6 +1819,15 @@
 	char action;
 	struct sctp_chunk *err_chk_p;
 
+	/* Make sure that the chunk has a valid length from the protocol
+	 * perspective.  In this case check to make sure we have at least
+	 * enough for the chunk header.  Cookie length verification is
+	 * done later.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* "Decode" the chunk.  We have no optional parameters so we
 	 * are in good shape.
 	 */
@@ -1815,6 +1925,19 @@
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the ABORT chunk has a valid length.
+	 * Since this is an ABORT chunk, we have to discard it
+	 * because of the following text:
+	 * RFC 2960, Section 3.3.7
+	 *    If an endpoint receives an ABORT with a format error or for an
+	 *    association that doesn't exist, it MUST silently discard it.
+	 * Becasue the length is "invalid", we can't really discard just
+	 * as we do not know its true length.  So, to be safe, discard the
+	 * packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 	/* Stop the T5-shutdown guard timer.  */
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
@@ -1838,6 +1961,19 @@
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the ABORT chunk has a valid length.
+	 * Since this is an ABORT chunk, we have to discard it
+	 * because of the following text:
+	 * RFC 2960, Section 3.3.7
+	 *    If an endpoint receives an ABORT with a format error or for an
+	 *    association that doesn't exist, it MUST silently discard it.
+	 * Becasue the length is "invalid", we can't really discard just
+	 * as we do not know its true length.  So, to be safe, discard the
+	 * packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 	/* Stop the T2-shutdown timer. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
@@ -1890,6 +2026,16 @@
 	struct sctp_chunk *chunk = arg;
 	sctp_errhdr_t *err;
 
+	if (!sctp_vtag_verify(chunk, asoc))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* Make sure that the ERROR chunk has a valid length.
+	 * The parameter walking depends on this as well.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* Process the error here */
 	/* FUTURE FIXME:  When PR-SCTP related and other optional
 	 * parms are emitted, this will have to change to handle multiple
@@ -1900,6 +2046,12 @@
 			return sctp_sf_do_5_2_6_stale(ep, asoc, type, 
 							arg, commands);
 	}
+
+	/* It is possible to have malformed error causes, and that
+	 * will cause us to end the walk early.  However, since
+	 * we are discarding the packet, there should be no adverse
+	 * affects.
+	 */
 	return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 }
 
@@ -1928,11 +2080,11 @@
  *
  * The return value is the disposition of the chunk.
  */
-sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
-					  const struct sctp_association *asoc,
-					  const sctp_subtype_t type,
-					  void *arg,
-					  sctp_cmd_seq_t *commands)
+static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
+						 const struct sctp_association *asoc,
+						 const sctp_subtype_t type,
+						 void *arg,
+						 sctp_cmd_seq_t *commands)
 {
 	struct sctp_chunk *chunk = arg;
 	time_t stale;
@@ -2064,12 +2216,24 @@
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-	/* Check that chunk header looks valid.  */
+	/* Make sure that the ABORT chunk has a valid length.
+	 * Since this is an ABORT chunk, we have to discard it
+	 * because of the following text:
+	 * RFC 2960, Section 3.3.7
+	 *    If an endpoint receives an ABORT with a format error or for an
+	 *    association that doesn't exist, it MUST silently discard it.
+	 * Becasue the length is "invalid", we can't really discard just
+	 * as we do not know its true length.  So, to be safe, discard the
+	 * packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* See if we have an error cause code in the chunk.  */
 	len = ntohs(chunk->chunk_hdr->length);
 	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
 		error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-
  	/* ASSOC_FAILED will DELETE_TCB. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error));
 	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -2096,27 +2260,43 @@
 	if (!sctp_vtag_verify_either(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-			SCTP_STATE(SCTP_STATE_CLOSED));
-	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
-	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
-			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+	/* Make sure that the ABORT chunk has a valid length.
+	 * Since this is an ABORT chunk, we have to discard it
+	 * because of the following text:
+	 * RFC 2960, Section 3.3.7
+	 *    If an endpoint receives an ABORT with a format error or for an
+	 *    association that doesn't exist, it MUST silently discard it.
+	 * Becasue the length is "invalid", we can't really discard just
+	 * as we do not know its true length.  So, to be safe, discard the
+	 * packet.
+	 */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
-	/* Check that chunk header looks valid.  */
+	/* See if we have an error cause code in the chunk.  */
 	len = ntohs(chunk->chunk_hdr->length);
 	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
 		error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-	/* CMD_INIT_FAILED will DELETE_TCB. */
-	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, SCTP_U32(error));
-
+ 	sctp_stop_t1_and_abort(commands, error);
 	return SCTP_DISPOSITION_ABORT;
 }
 
 /*
+ * Process an incoming ICMP as an ABORT.  (COOKIE-WAIT state)
+ */
+sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep,
+					const struct sctp_association *asoc,
+					const sctp_subtype_t type,
+					void *arg,
+					sctp_cmd_seq_t *commands)
+{
+	sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR);
+ 	return SCTP_DISPOSITION_ABORT;
+}
+
+/*
  * Process an ABORT.  (COOKIE-ECHOED state)
- *
- * See sctp_sf_do_9_1_abort() above.
  */
 sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
 					       const struct sctp_association *asoc,
@@ -2131,6 +2311,23 @@
 }
 
 /*
+ * Stop T1 timer and abort association with "INIT failed".
+ *
+ * This is common code called by several sctp_sf_*_abort() functions above.
+ */
+void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error)
+{
+	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+			SCTP_STATE(SCTP_STATE_CLOSED));
+	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
+	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+	/* CMD_INIT_FAILED will DELETE_TCB. */
+	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
+			SCTP_U32(error));
+}
+
+/*
  * sctp_sf_do_9_2_shut
  *
  * Section: 9.2
@@ -2174,14 +2371,20 @@
 	sctp_disposition_t disposition;
 	struct sctp_ulpevent *ev;
 
+	if (!sctp_vtag_verify(chunk, asoc))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* Make sure that the SHUTDOWN chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk,
+				      sizeof(struct sctp_shutdown_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* Convert the elaborate header.  */
 	sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));
 	chunk->subh.shutdown_hdr = sdh;
 
-	if (!sctp_vtag_verify(chunk, asoc))
-		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
 	/* Upon the reception of the SHUTDOWN, the peer endpoint shall
 	 *  - enter the SHUTDOWN-RECEIVED state,
 	 *  - stop accepting new data from its SCTP user
@@ -2238,6 +2441,10 @@
 	struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
 	struct sctp_chunk *reply;
 
+	/* Since we are not going to really process this INIT, there
+	 * is no point in verifying chunk boundries.  Just generate
+	 * the SHUTDOWN ACK.
+	 */
 	reply = sctp_make_shutdown_ack(asoc, chunk);
 	if (NULL == reply)
 		goto nomem;
@@ -2295,6 +2502,10 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+		
 	cwr = (sctp_cwrhdr_t *) chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_cwrhdr_t));
 
@@ -2345,6 +2556,10 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_ecne_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	ecne = (sctp_ecnehdr_t *) chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_ecnehdr_t));
 
@@ -2400,6 +2615,10 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
         }
 
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	error = sctp_eat_data(asoc, chunk, commands );
 	switch (error) {
 	case SCTP_IERROR_NO_ERROR:
@@ -2517,6 +2736,10 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 	}
 
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_data_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	error = sctp_eat_data(asoc, chunk, commands );
 	switch (error) {
 	case SCTP_IERROR_NO_ERROR:
@@ -2598,6 +2821,11 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the SACK chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_sack_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* Pull the SACK chunk from the data buffer */
 	sackh = sctp_sm_pull_sack(chunk);
 	/* Was this a bogus SACK? */
@@ -2700,6 +2928,14 @@
 	struct sctp_chunk *chunk = arg;
 	struct sctp_ulpevent *ev;
 
+	if (!sctp_vtag_verify(chunk, asoc))
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+	/* Make sure that the ERROR chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_operr_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	while (chunk->chunk_end > chunk->skb->data) {
 		ev = sctp_ulpevent_make_remote_error(asoc, chunk, 0,
 						     GFP_ATOMIC);
@@ -2744,6 +2980,11 @@
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	/* 10.2 H) SHUTDOWN COMPLETE notification
 	 *
 	 * When SCTP completes the shutdown procedures (section 9.2) this
@@ -2818,11 +3059,23 @@
 
 	ch = (sctp_chunkhdr_t *) chunk->chunk_hdr;
 	do {
+		/* Break out if chunk length is less then minimal. */
+		if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
+			break;
+
 		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
 
 		if (SCTP_CID_SHUTDOWN_ACK == ch->type)
 			ootb_shut_ack = 1;
 
+		/* RFC 2960, Section 3.3.7
+		 *   Moreover, under any circumstances, an endpoint that
+		 *   receives an ABORT  MUST NOT respond to that ABORT by
+		 *   sending an ABORT of its own.
+		 */
+		if (SCTP_CID_ABORT == ch->type)
+			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+			
 		ch = (sctp_chunkhdr_t *) ch_end;
 	} while (ch_end < skb->tail);
 
@@ -2853,11 +3106,11 @@
  *
  * The return value is the disposition of the chunk.
  */
-sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
-				      const struct sctp_association *asoc,
-				      const sctp_subtype_t type,
-				      void *arg,
-				      sctp_cmd_seq_t *commands)
+static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
+					     const struct sctp_association *asoc,
+					     const sctp_subtype_t type,
+					     void *arg,
+					     sctp_cmd_seq_t *commands)
 {
 	struct sctp_packet *packet = NULL;
 	struct sctp_chunk *chunk = arg;
@@ -2885,6 +3138,12 @@
 
 		SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
 
+		/* If the chunk length is invalid, we don't want to process
+		 * the reset of the packet.
+		 */
+		if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
+			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
 		return SCTP_DISPOSITION_CONSUME;
 	}
 
@@ -2927,6 +3186,17 @@
 	sctp_addiphdr_t		*hdr;
 	__u32			serial;
 
+	if (!sctp_vtag_verify(chunk, asoc)) {
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
+				SCTP_NULL());
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+	}
+
+	/* Make sure that the ASCONF ADDIP chunk has a valid length.  */
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_addip_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	hdr = (sctp_addiphdr_t *)chunk->skb->data;
 	serial = ntohl(hdr->serial);
 
@@ -2947,7 +3217,8 @@
 		/* ADDIP 4.2 C3) If the value found in the serial number is
 		 * equal to the value stored in the 'Peer-Serial-Number'
 		 * IMPLEMENTATION NOTE: As an optimization a receiver may wish
-		 * to save the last ASCONF-ACK for some predetermined period of 		 * time and instead of re-processing the ASCONF (with the same
+		 * to save the last ASCONF-ACK for some predetermined period of
+		 * time and instead of re-processing the ASCONF (with the same
 		 * serial number) it may just re-transmit the ASCONF-ACK.
 		 */
 		if (asoc->addip_last_asconf_ack)
@@ -2986,6 +3257,17 @@
 	sctp_addiphdr_t		*addip_hdr;
 	__u32			sent_serial, rcvd_serial;
 
+	if (!sctp_vtag_verify(asconf_ack, asoc)) {
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
+				SCTP_NULL());
+		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+	}
+
+	/* Make sure that the ADDIP chunk has a valid length.  */
+	if (!sctp_chunk_length_valid(asconf_ack, sizeof(sctp_addip_chunk_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	addip_hdr = (sctp_addiphdr_t *)asconf_ack->skb->data;
 	rcvd_serial = ntohl(addip_hdr->serial);
 
@@ -3084,6 +3366,11 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 	}
 
+	/* Make sure that the FORWARD_TSN chunk has valid length.  */
+	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
 	chunk->subh.fwdtsn_hdr = fwdtsn_hdr;
 	len = ntohs(chunk->chunk_hdr->length);
@@ -3142,6 +3429,11 @@
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 	}
 
+	/* Make sure that the FORWARD_TSN chunk has a valid length.  */
+	if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	fwdtsn_hdr = (struct sctp_fwdtsn_hdr *)chunk->skb->data;
 	chunk->subh.fwdtsn_hdr = fwdtsn_hdr;
 	len = ntohs(chunk->chunk_hdr->length);
@@ -3216,6 +3508,14 @@
 	if (!sctp_vtag_verify(unk_chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* Make sure that the chunk has a valid length.
+	 * Since we don't know the chunk type, we use a general
+	 * chunkhdr structure to make a comparison.
+	 */
+	if (!sctp_chunk_length_valid(unk_chunk, sizeof(sctp_chunkhdr_t)))
+		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+						  commands);
+
 	switch (type.chunk & SCTP_CID_ACTION_MASK) {
 	case SCTP_CID_ACTION_DISCARD:
 		/* Discard the packet.  */
@@ -3338,6 +3638,66 @@
 	return SCTP_DISPOSITION_VIOLATION;
 }
 
+
+/*
+ * Handle a protocol violation when the chunk length is invalid.
+ * "Invalid" length is identified as smaller then the minimal length a
+ * given chunk can be.  For example, a SACK chunk has invalid length
+ * if it's length is set to be smaller then the size of sctp_sack_chunk_t.
+ *
+ * We inform the other end by sending an ABORT with a Protocol Violation
+ * error code. 
+ *
+ * Section: Not specified
+ * Verification Tag:  Nothing to do
+ * Inputs
+ * (endpoint, asoc, chunk)
+ *
+ * Outputs
+ * (reply_msg, msg_up, counters)
+ *
+ * Generate an  ABORT chunk and terminate the association.
+ */
+sctp_disposition_t sctp_sf_violation_chunklen(const struct sctp_endpoint *ep,
+				     const struct sctp_association *asoc,
+				     const sctp_subtype_t type,
+				     void *arg,
+				     sctp_cmd_seq_t *commands)
+{
+	struct sctp_chunk *chunk =  arg;
+	struct sctp_chunk *abort = NULL;
+	char 		   err_str[]="The following chunk had invalid length:";
+
+	/* Make the abort chunk. */
+	abort = sctp_make_abort_violation(asoc, chunk, err_str,
+					  sizeof(err_str));
+	if (!abort)
+		goto nomem;
+
+	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+	SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
+
+	if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
+		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
+				SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
+	} else {
+		sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
+				SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
+		SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
+	}
+
+	sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
+
+	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
+	
+	return SCTP_DISPOSITION_ABORT;
+
+nomem:
+	return SCTP_DISPOSITION_NOMEM;
+}
+
 /***************************************************************************
  * These are the state functions for handling primitive (Section 10) events.
  ***************************************************************************/
@@ -4050,6 +4410,23 @@
 	struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
 	struct sctp_chunk *reply;
 
+	/* There are 2 ways of getting here:
+	 *    1) called in response to a SHUTDOWN chunk
+	 *    2) called when SCTP_EVENT_NO_PENDING_TSN event is issued.
+	 *
+	 * For the case (2), the arg parameter is set to NULL.  We need
+	 * to check that we have a chunk before accessing it's fields.
+	 */
+	if (chunk) {
+		if (!sctp_vtag_verify(chunk, asoc))
+			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
+
+		/* Make sure that the SHUTDOWN chunk has a valid length. */
+		if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_shutdown_chunk_t)))
+			return sctp_sf_violation_chunklen(ep, asoc, type, arg,
+							  commands);
+	}
+
 	/* If it has no more outstanding DATA chunks, the SHUTDOWN receiver
 	 * shall send a SHUTDOWN ACK ...
 	 */
@@ -4537,7 +4914,7 @@
  ********************************************************************/
 
 /* Pull the SACK chunk based on the SACK header. */
-struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk)
+static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk)
 {
 	struct sctp_sackhdr *sack;
 	unsigned int len;
@@ -4564,7 +4941,7 @@
 /* Create an ABORT packet to be sent as a response, with the specified
  * error causes.
  */
-struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
+static struct sctp_packet *sctp_abort_pkt_new(const struct sctp_endpoint *ep,
 				  const struct sctp_association *asoc,
 				  struct sctp_chunk *chunk,
 				  const void *payload,
@@ -4600,8 +4977,8 @@
 }
 
 /* Allocate a packet for responding in the OOTB conditions.  */
-struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
-				 const struct sctp_chunk *chunk)
+static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc,
+					     const struct sctp_chunk *chunk)
 {
 	struct sctp_packet *packet;
 	struct sctp_transport *transport;
@@ -4664,11 +5041,11 @@
 }
 
 /* Send a stale cookie error when a invalid COOKIE ECHO chunk is found  */
-void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
-				const struct sctp_association *asoc,
-				const struct sctp_chunk *chunk,
-				sctp_cmd_seq_t *commands,
-				struct sctp_chunk *err_chunk)
+static void sctp_send_stale_cookie_err(const struct sctp_endpoint *ep,
+				       const struct sctp_association *asoc,
+				       const struct sctp_chunk *chunk,
+				       sctp_cmd_seq_t *commands,
+				       struct sctp_chunk *err_chunk)
 {
 	struct sctp_packet *packet;
 
@@ -4694,9 +5071,9 @@
 
 
 /* Process a data chunk */
-int sctp_eat_data(const struct sctp_association *asoc,
-		  struct sctp_chunk *chunk,
-		  sctp_cmd_seq_t *commands)
+static int sctp_eat_data(const struct sctp_association *asoc,
+			 struct sctp_chunk *chunk,
+			 sctp_cmd_seq_t *commands)
 {
 	sctp_datahdr_t *data_hdr;
 	struct sctp_chunk *err;
diff -Nru a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
--- a/net/sctp/sm_statetable.c	2005-01-19 13:44:48 -08:00
+++ b/net/sctp/sm_statetable.c	2005-01-19 13:44:48 -08:00
@@ -50,6 +50,17 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
+static const sctp_sm_table_entry_t
+primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES];
+static const sctp_sm_table_entry_t
+other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
+static const sctp_sm_table_entry_t
+timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
+
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
+							    sctp_state_t state);
+
+
 static const sctp_sm_table_entry_t bug = {
 	.fn = sctp_sf_bug,
 	.name = "sctp_sf_bug"
@@ -419,7 +430,7 @@
  *
  * For base protocol (RFC 2960).
  */
-const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_DATA,
 	TYPE_SCTP_INIT,
 	TYPE_SCTP_INIT_ACK,
@@ -482,7 +493,7 @@
 /* The primary index for this table is the chunk type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_ASCONF,
 	TYPE_SCTP_ASCONF_ACK,
 }; /*state_fn_t addip_chunk_event_table[][] */
@@ -511,7 +522,7 @@
 /* The primary index for this table is the chunk type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_FWD_TSN,
 }; /*state_fn_t prsctp_chunk_event_table[][] */
 
@@ -684,7 +695,7 @@
 /* The primary index for this table is the primitive type.
  * The secondary index for this table is the state.
  */
-const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_PRIMITIVE_ASSOCIATE,
 	TYPE_SCTP_PRIMITIVE_SHUTDOWN,
 	TYPE_SCTP_PRIMITIVE_ABORT,
@@ -716,8 +727,31 @@
 	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 }
 
-const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
+#define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH  { \
+	/* SCTP_STATE_EMPTY */ \
+	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
+	/* SCTP_STATE_CLOSED */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_COOKIE_WAIT */ \
+	{.fn = sctp_sf_cookie_wait_icmp_abort, \
+	 .name = "sctp_sf_cookie_wait_icmp_abort"}, \
+	/* SCTP_STATE_COOKIE_ECHOED */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_ESTABLISHED */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_SHUTDOWN_PENDING */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_SHUTDOWN_SENT */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
+	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
+}
+
+static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_OTHER_NO_PENDING_TSN,
+	TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH,
 };
 
 #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
@@ -931,7 +965,7 @@
 	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
-const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
+static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_EVENT_TIMEOUT_NONE,
 	TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE,
 	TYPE_SCTP_EVENT_TIMEOUT_T1_INIT,
@@ -944,8 +978,8 @@
 	TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
 };
 
-const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, 
-						     sctp_state_t state)
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, 
+							    sctp_state_t state)
 {
 	if (state > SCTP_STATE_MAX)
 		return &bug;
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c	2005-01-19 13:44:48 -08:00
+++ b/net/sctp/socket.c	2005-01-19 13:44:48 -08:00
@@ -208,7 +208,7 @@
  * id are specified, the associations matching the address and the id should be
  * the same.
  */
-struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
+static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
 					      struct sockaddr_storage *addr,
 					      sctp_assoc_t id)
 {
@@ -245,7 +245,7 @@
  *             sockaddr_in6 [RFC 2553]),
  *   addr_len - the size of the address structure.
  */
-int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
 	int retval = 0;
 
@@ -343,8 +343,8 @@
 	}
 
 	/* Refresh ephemeral port.  */
-	if (!snum)
-		snum = inet_sk(sk)->num;
+	if (!bp->port)
+		bp->port = inet_sk(sk)->num;
 
 	/* Add the address to the bind address list.  */
 	sctp_local_bh_disable();
@@ -354,8 +354,6 @@
 	addr->v4.sin_port = ntohs(addr->v4.sin_port);
 	ret = sctp_add_bind_addr(bp, addr, GFP_ATOMIC);
 	addr->v4.sin_port = htons(addr->v4.sin_port);
-	if (!ret && !bp->port)
-		bp->port = snum;
 	sctp_write_unlock(&ep->base.addr_lock);
 	sctp_local_bh_enable();
 
@@ -1713,10 +1711,13 @@
 	/* update default value for endpoint (all future associations) */
 	if (!params.spp_assoc_id && 
 	    sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-		if (params.spp_hbinterval)
+		/* Manual heartbeat on an endpoint is invalid. */
+		if (0xffffffff == params.spp_hbinterval)
+			return -EINVAL;
+		else if (params.spp_hbinterval)
 			sctp_sk(sk)->paddrparam.spp_hbinterval =
 						params.spp_hbinterval;
-		if (sctp_max_retrans_path)
+		if (params.spp_pathmaxrxt)
 			sctp_sk(sk)->paddrparam.spp_pathmaxrxt =
 						params.spp_pathmaxrxt;
 		return 0;
@@ -1758,7 +1759,8 @@
 	/* spp_pathmaxrxt contains the maximum number of retransmissions
 	 * before this address shall be considered unreachable.
 	 */
-	trans->error_threshold = params.spp_pathmaxrxt;
+	if (params.spp_pathmaxrxt)
+		trans->max_retrans = params.spp_pathmaxrxt;
 
 	return 0;
 }
@@ -2937,7 +2939,7 @@
 	/* spp_pathmaxrxt contains the maximum number of retransmissions
 	 * before this address shall be considered unreachable.
 	 */
-	params.spp_pathmaxrxt = trans->error_threshold;
+	params.spp_pathmaxrxt = trans->max_retrans;
 
 done:
 	if (copy_to_user(optval, &params, len))
@@ -3049,6 +3051,9 @@
 	struct sctp_bind_addr *bp;
 	struct sctp_association *asoc;
 	struct list_head *pos;
+	struct sctp_sockaddr_entry *addr;
+	rwlock_t *addr_lock;
+	unsigned long flags;
 	int cnt = 0;
 
 	if (len != sizeof(sctp_assoc_t))
@@ -3065,33 +3070,104 @@
 	 */
 	if (0 == id) {
 		bp = &sctp_sk(sk)->ep->base.bind_addr;
+		addr_lock = &sctp_sk(sk)->ep->base.addr_lock;
 	} else {
 		asoc = sctp_id2assoc(sk, id);
 		if (!asoc)
 			return -EINVAL;
 		bp = &asoc->base.bind_addr;
+		addr_lock = &asoc->base.addr_lock;
+	}
+
+	sctp_read_lock(addr_lock);
+
+	/* If the endpoint is bound to 0.0.0.0 or ::0, count the valid
+	 * addresses from the global local address list.
+	 */
+	if (sctp_list_single_entry(&bp->address_list)) {
+		addr = list_entry(bp->address_list.next,
+				  struct sctp_sockaddr_entry, list);
+		if (sctp_is_any(&addr->a)) {
+			sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
+			list_for_each(pos, &sctp_local_addr_list) {
+				addr = list_entry(pos,
+						  struct sctp_sockaddr_entry,
+						  list);
+				if ((PF_INET == sk->sk_family) && 
+				    (AF_INET6 == addr->a.sa.sa_family))	
+					continue;
+				cnt++;
+			}
+			sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
+						    flags);
+		} else {
+			cnt = 1;
+		}
+		goto done;
 	}
 
 	list_for_each(pos, &bp->address_list) {
 		cnt ++;
 	}
 
+done:
+	sctp_read_unlock(addr_lock);
+	return cnt;
+}
+
+/* Helper function that copies local addresses to user and returns the number
+ * of addresses copied.
+ */
+static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, int max_addrs,
+				    void __user *to)
+{
+	struct list_head *pos;
+	struct sctp_sockaddr_entry *addr;
+	unsigned long flags;
+	union sctp_addr temp;
+	int cnt = 0;
+	int addrlen;
+
+	sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
+	list_for_each(pos, &sctp_local_addr_list) {
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+		if ((PF_INET == sk->sk_family) && 
+		    (AF_INET6 == addr->a.sa.sa_family))
+			continue;
+		memcpy(&temp, &addr->a, sizeof(temp));
+		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
+								&temp);
+		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
+		temp.v4.sin_port = htons(port);
+		if (copy_to_user(to, &temp, addrlen)) {
+			sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
+						    flags);
+			return -EFAULT;
+		}
+		to += addrlen;
+		cnt ++;
+		if (cnt >= max_addrs) break;
+	}
+	sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
+
 	return cnt;
 }
 
 static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
-					char __user *optval, int __user *optlen)
+				       char __user *optval, int __user *optlen)
 {
 	struct sctp_bind_addr *bp;
 	struct sctp_association *asoc;
 	struct list_head *pos;
 	int cnt = 0;
 	struct sctp_getaddrs getaddrs;
-	struct sctp_sockaddr_entry *from;
+	struct sctp_sockaddr_entry *addr;
 	void __user *to;
 	union sctp_addr temp;
 	struct sctp_opt *sp = sctp_sk(sk);
 	int addrlen;
+	rwlock_t *addr_lock;
+	int err = 0;
 
 	if (len != sizeof(struct sctp_getaddrs))
 		return -EINVAL;
@@ -3108,33 +3184,59 @@
 	 */
 	if (0 == getaddrs.assoc_id) {
 		bp = &sctp_sk(sk)->ep->base.bind_addr;
+		addr_lock = &sctp_sk(sk)->ep->base.addr_lock;
 	} else {
 		asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
 		if (!asoc)
 			return -EINVAL;
 		bp = &asoc->base.bind_addr;
+		addr_lock = &asoc->base.addr_lock;
 	}
 
 	to = getaddrs.addrs;
+
+	sctp_read_lock(addr_lock);
+
+	/* If the endpoint is bound to 0.0.0.0 or ::0, get the valid
+	 * addresses from the global local address list.
+	 */
+	if (sctp_list_single_entry(&bp->address_list)) {
+		addr = list_entry(bp->address_list.next,
+				  struct sctp_sockaddr_entry, list);
+		if (sctp_is_any(&addr->a)) {
+			cnt = sctp_copy_laddrs_to_user(sk, bp->port,
+						       getaddrs.addr_num, to);
+			if (cnt < 0) {
+				err = cnt;
+				goto unlock;
+			}
+			goto copy_getaddrs;		
+		}
+	}
+
 	list_for_each(pos, &bp->address_list) {
-		from = list_entry(pos,
-				struct sctp_sockaddr_entry,
-				list);
-		memcpy(&temp, &from->a, sizeof(temp));
+		addr = list_entry(pos, struct sctp_sockaddr_entry, list);
+		memcpy(&temp, &addr->a, sizeof(temp));
 		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
 		addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
 		temp.v4.sin_port = htons(temp.v4.sin_port);
-		if (copy_to_user(to, &temp, addrlen))
-			return -EFAULT;
+		if (copy_to_user(to, &temp, addrlen)) {
+			err = -EFAULT;
+			goto unlock;
+		}
 		to += addrlen;
 		cnt ++;
 		if (cnt >= getaddrs.addr_num) break;
 	}
+
+copy_getaddrs:
 	getaddrs.addr_num = cnt;
 	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
-		return -EFAULT;
+		err = -EFAULT;
 
-	return 0;
+unlock:
+	sctp_read_unlock(addr_lock);
+	return err;
 }
 
 /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
diff -Nru a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
--- a/net/sctp/ssnmap.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/ssnmap.c	2005-01-19 13:44:47 -08:00
@@ -42,6 +42,9 @@
 
 #define MAX_KMALLOC_SIZE	131072
 
+static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
+					    __u16 out);
+
 /* Storage size needed for map includes 2 headers and then the
  * specific needs of in or out streams.
  */
@@ -87,8 +90,8 @@
 
 
 /* Initialize a block of memory as a ssnmap.  */
-struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
-				     __u16 out)
+static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
+					    __u16 out)
 {
 	memset(map, 0x00, sctp_ssnmap_size(in, out));
 
diff -Nru a/net/sctp/transport.c b/net/sctp/transport.c
--- a/net/sctp/transport.c	2005-01-19 13:44:48 -08:00
+++ b/net/sctp/transport.c	2005-01-19 13:44:48 -08:00
@@ -54,34 +54,10 @@
 
 /* 1st Level Abstractions.  */
 
-/* Allocate and initialize a new transport.  */
-struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, int gfp)
-{
-        struct sctp_transport *transport;
-
-        transport = t_new(struct sctp_transport, gfp);
-	if (!transport)
-		goto fail;
-
-	if (!sctp_transport_init(transport, addr, gfp))
-		goto fail_init;
-
-	transport->malloced = 1;
-	SCTP_DBG_OBJCNT_INC(transport);
-
-	return transport;
-
-fail_init:
-	kfree(transport);
-
-fail:
-	return NULL;
-}
-
 /* Initialize a new transport from provided memory.  */
-struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
-					   const union sctp_addr *addr,
-					   int gfp)
+static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
+						  const union sctp_addr *addr,
+						  int gfp)
 {
 	/* Copy in the address.  */
 	peer->ipaddr = *addr;
@@ -112,7 +88,6 @@
 
 	/* Initialize the default path max_retrans.  */
 	peer->max_retrans = sctp_max_retrans_path;
-	peer->error_threshold = 0;
 	peer->error_count = 0;
 
 	INIT_LIST_HEAD(&peer->transmitted);
@@ -144,6 +119,30 @@
 	return peer;
 }
 
+/* Allocate and initialize a new transport.  */
+struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, int gfp)
+{
+        struct sctp_transport *transport;
+
+        transport = t_new(struct sctp_transport, gfp);
+	if (!transport)
+		goto fail;
+
+	if (!sctp_transport_init(transport, addr, gfp))
+		goto fail_init;
+
+	transport->malloced = 1;
+	SCTP_DBG_OBJCNT_INC(transport);
+
+	return transport;
+
+fail_init:
+	kfree(transport);
+
+fail:
+	return NULL;
+}
+
 /* This transport is no longer needed.  Free up if possible, or
  * delay until it last reference count.
  */
@@ -155,13 +154,23 @@
 	if (del_timer(&transport->hb_timer))
 		sctp_transport_put(transport);
 
+	/* Delete the T3_rtx timer if it's active.
+	 * There is no point in not doing this now and letting
+	 * structure hang around in memory since we know
+	 * the tranport is going away.
+	 */
+	if (timer_pending(&transport->T3_rtx_timer) &&
+	    del_timer(&transport->T3_rtx_timer))
+		sctp_transport_put(transport);
+
+
 	sctp_transport_put(transport);
 }
 
 /* Destroy the transport data structure.
  * Assumes there are no more users of this structure.
  */
-void sctp_transport_destroy(struct sctp_transport *transport)
+static void sctp_transport_destroy(struct sctp_transport *transport)
 {
 	SCTP_ASSERT(transport->dead, "Transport is not dead", return);
 
diff -Nru a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
--- a/net/sctp/tsnmap.c	2005-01-19 13:44:48 -08:00
+++ b/net/sctp/tsnmap.c	2005-01-19 13:44:48 -08:00
@@ -52,29 +52,6 @@
 				     int *started, __u16 *start,
 				     int *ended, __u16 *end);
 
-/* Create a new sctp_tsnmap.
- * Allocate room to store at least 'len' contiguous TSNs.
- */
-struct sctp_tsnmap *sctp_tsnmap_new(__u16 len, __u32 initial_tsn, int gfp)
-{
-	struct sctp_tsnmap *retval;
-
-	retval = kmalloc(sizeof(struct sctp_tsnmap) +
-			 sctp_tsnmap_storage_size(len), gfp);
-	if (!retval)
-		goto fail;
-
-	if (!sctp_tsnmap_init(retval, len, initial_tsn))
-		goto fail_map;
-	retval->malloced = 1;
-	return retval;
-
-fail_map:
-	kfree(retval);
-fail:
-	return NULL;
-}
-
 /* Initialize a block of memory as a tsnmap.  */
 struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
 				     __u32 initial_tsn)
@@ -168,16 +145,9 @@
 }
 
 
-/* Dispose of a tsnmap.  */
-void sctp_tsnmap_free(struct sctp_tsnmap *map)
-{
-	if (map->malloced)
-		kfree(map);
-}
-
 /* Initialize a Gap Ack Block iterator from memory being provided.  */
-void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
-			   struct sctp_tsnmap_iter *iter)
+SCTP_STATIC void sctp_tsnmap_iter_init(const struct sctp_tsnmap *map,
+				       struct sctp_tsnmap_iter *iter)
 {
 	/* Only start looking one past the Cumulative TSN Ack Point.  */
 	iter->start = map->cumulative_tsn_ack_point + 1;
@@ -186,8 +156,9 @@
 /* Get the next Gap Ack Blocks. Returns 0 if there was not another block
  * to get.
  */
-int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
-	struct sctp_tsnmap_iter *iter, __u16 *start, __u16 *end)
+SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
+					 struct sctp_tsnmap_iter *iter,
+					 __u16 *start, __u16 *end)
 {
 	int started, ended;
 	__u16 _start, _end, offset;
diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
--- a/net/sctp/ulpevent.c	2005-01-19 13:44:46 -08:00
+++ b/net/sctp/ulpevent.c	2005-01-19 13:44:46 -08:00
@@ -65,8 +65,16 @@
  */
 }
 
+/* Initialize an ULP event from an given skb.  */
+SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
+{
+	memset(event, 0, sizeof(struct sctp_ulpevent));
+	event->msg_flags = msg_flags;
+}
+
 /* Create a new sctp_ulpevent.  */
-struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, int gfp)
+SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags,
+						    int gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sk_buff *skb;
@@ -82,13 +90,6 @@
 
 fail:
 	return NULL;
-}
-
-/* Initialize an ULP event from an given skb.  */
-void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags)
-{
-	memset(event, 0, sizeof(struct sctp_ulpevent));
-	event->msg_flags = msg_flags;
 }
 
 /* Is this a MSG_NOTIFICATION?  */
diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c	2005-01-19 13:44:47 -08:00
+++ b/net/sctp/ulpqueue.c	2005-01-19 13:44:47 -08:00
@@ -56,25 +56,6 @@
 
 /* 1st Level Abstractions */
 
-/* Create a new ULP queue.  */
-struct sctp_ulpq *sctp_ulpq_new(struct sctp_association *asoc, int gfp)
-{
-	struct sctp_ulpq *ulpq;
-
-	ulpq = kmalloc(sizeof(struct sctp_ulpq), gfp);
-	if (!ulpq)
-		goto fail;
-	if (!sctp_ulpq_init(ulpq, asoc))
-		goto fail_init;
-	ulpq->malloced = 1;
-	return ulpq;
-
-fail_init:
-	kfree(ulpq);
-fail:
-	return NULL;
-}
-
 /* Initialize a ULP queue from a block of memory.  */
 struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq,
 				 struct sctp_association *asoc)
@@ -92,7 +73,7 @@
 
 
 /* Flush the reassembly and ordering queues.  */
-void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
+static void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
 {
 	struct sk_buff *skb;
 	struct sctp_ulpevent *event;
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	2005-01-19 13:44:46 -08:00
+++ b/net/socket.c	2005-01-19 13:44:46 -08:00
@@ -144,7 +144,7 @@
 
 #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 static atomic_t net_family_lockct = ATOMIC_INIT(0);
-static spinlock_t net_family_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(net_family_lock);
 
 /* The strategy is: modifications net_family vector are short, do not
    sleep and veeery rare, but read access should be free of any exclusive
diff -Nru a/net/sunrpc/auth.c b/net/sunrpc/auth.c
--- a/net/sunrpc/auth.c	2005-01-19 13:44:46 -08:00
+++ b/net/sunrpc/auth.c	2005-01-19 13:44:46 -08:00
@@ -89,7 +89,7 @@
 	kfree(auth);
 }
 
-static spinlock_t rpc_credcache_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rpc_credcache_lock);
 
 /*
  * Initialize RPC credential cache
diff -Nru a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
--- a/net/sunrpc/auth_gss/auth_gss.c	2005-01-19 13:44:46 -08:00
+++ b/net/sunrpc/auth_gss/auth_gss.c	2005-01-19 13:44:46 -08:00
@@ -80,7 +80,7 @@
 /* dump the buffer in `emacs-hexl' style */
 #define isprint(c)      ((c > 0x1f) && (c < 0x7f))
 
-static rwlock_t gss_ctx_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(gss_ctx_lock);
 
 struct gss_auth {
 	struct rpc_auth rpc_auth;
@@ -593,9 +593,11 @@
 			gss_auth->mech->gm_name);
 	gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
 	if (IS_ERR(gss_auth->dentry))
-		goto err_free;
+		goto err_put_mech;
 
 	return auth;
+err_put_mech:
+	gss_mech_put(gss_auth->mech);
 err_free:
 	kfree(gss_auth);
 out_dec:
@@ -612,6 +614,7 @@
 
 	gss_auth = container_of(auth, struct gss_auth, rpc_auth);
 	rpc_unlink(gss_auth->path);
+	gss_mech_put(gss_auth->mech);
 
 	rpcauth_free_credcache(auth);
 }
diff -Nru a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
--- a/net/sunrpc/auth_gss/gss_mech_switch.c	2005-01-19 13:44:47 -08:00
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c	2005-01-19 13:44:47 -08:00
@@ -51,7 +51,7 @@
 #endif
 
 static LIST_HEAD(registered_mechs);
-static spinlock_t registered_mechs_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(registered_mechs_lock);
 
 static void
 gss_mech_free(struct gss_api_mech *gm)
@@ -150,9 +150,8 @@
 	spin_lock(&registered_mechs_lock);
 	list_for_each_entry(pos, &registered_mechs, gm_list) {
 		if (0 == strcmp(name, pos->gm_name)) {
-			if (!try_module_get(pos->gm_owner))
-				continue;
-			gm = pos;
+			if (try_module_get(pos->gm_owner))
+				gm = pos;
 			break;
 		}
 	}
@@ -182,13 +181,12 @@
 
 	spin_lock(&registered_mechs_lock);
 	list_for_each_entry(pos, &registered_mechs, gm_list) {
-		if (!try_module_get(pos->gm_owner))
-			continue;
 		if (!mech_supports_pseudoflavor(pos, pseudoflavor)) {
 			module_put(pos->gm_owner);
 			continue;
 		}
-		gm = pos;
+		if (try_module_get(pos->gm_owner))
+			gm = pos;
 		break;
 	}
 	spin_unlock(&registered_mechs_lock);
diff -Nru a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
--- a/net/sunrpc/auth_null.c	2005-01-19 13:44:48 -08:00
+++ b/net/sunrpc/auth_null.c	2005-01-19 13:44:48 -08:00
@@ -100,7 +100,8 @@
 static int
 nul_refresh(struct rpc_task *task)
 {
-	return task->tk_status = -EACCES;
+	task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
+	return 0;
 }
 
 static u32 *
diff -Nru a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
--- a/net/sunrpc/auth_unix.c	2005-01-19 13:44:47 -08:00
+++ b/net/sunrpc/auth_unix.c	2005-01-19 13:44:47 -08:00
@@ -187,7 +187,7 @@
 unx_refresh(struct rpc_task *task)
 {
 	task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
-	return task->tk_status = -EACCES;
+	return 0;
 }
 
 static u32 *
diff -Nru a/net/sunrpc/cache.c b/net/sunrpc/cache.c
--- a/net/sunrpc/cache.c	2005-01-19 13:44:47 -08:00
+++ b/net/sunrpc/cache.c	2005-01-19 13:44:47 -08:00
@@ -161,7 +161,7 @@
  */
 
 static LIST_HEAD(cache_list);
-static spinlock_t cache_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cache_list_lock);
 static struct cache_detail *current_detail;
 static int current_index;
 
@@ -405,7 +405,7 @@
 
 #define	DFR_MAX	300	/* ??? */
 
-static spinlock_t cache_defer_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(cache_defer_lock);
 static LIST_HEAD(cache_defer_list);
 static struct list_head cache_defer_hash[DFR_HASHSIZE];
 static int cache_defer_cnt;
@@ -533,7 +533,7 @@
  *
  */
 
-static spinlock_t queue_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(queue_lock);
 static DECLARE_MUTEX(queue_io_sem);
 
 struct cache_queue {
diff -Nru a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
--- a/net/sunrpc/pmap_clnt.c	2005-01-19 13:44:46 -08:00
+++ b/net/sunrpc/pmap_clnt.c	2005-01-19 13:44:46 -08:00
@@ -32,7 +32,7 @@
 static struct rpc_clnt *	pmap_create(char *, struct sockaddr_in *, int);
 static void			pmap_getport_done(struct rpc_task *);
 static struct rpc_program	pmap_program;
-static spinlock_t		pmap_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(pmap_lock);
 
 /*
  * Obtain the port for a given RPC service on a given host. This one can
diff -Nru a/net/sunrpc/sched.c b/net/sunrpc/sched.c
--- a/net/sunrpc/sched.c	2005-01-19 13:44:46 -08:00
+++ b/net/sunrpc/sched.c	2005-01-19 13:44:46 -08:00
@@ -18,7 +18,6 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
-#include <linux/suspend.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xprt.h>
@@ -72,7 +71,7 @@
 /*
  * Spinlock for other critical sections of code.
  */
-static spinlock_t rpc_sched_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(rpc_sched_lock);
 
 /*
  * Disable the timer for a given RPC task. Should be called with
diff -Nru a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
--- a/net/sunrpc/svcauth.c	2005-01-19 13:44:47 -08:00
+++ b/net/sunrpc/svcauth.c	2005-01-19 13:44:47 -08:00
@@ -28,7 +28,7 @@
 extern struct auth_ops svcauth_null;
 extern struct auth_ops svcauth_unix;
 
-static spinlock_t authtab_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(authtab_lock);
 static struct auth_ops	*authtab[RPC_AUTH_MAXFLAVOR] = {
 	[0] = &svcauth_null,
 	[1] = &svcauth_unix,
diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
--- a/net/sunrpc/svcsock.c	2005-01-19 13:44:45 -08:00
+++ b/net/sunrpc/svcsock.c	2005-01-19 13:44:45 -08:00
@@ -31,7 +31,6 @@
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/suspend.h>
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/ip.h>
@@ -1227,8 +1226,7 @@
 
 		schedule_timeout(timeout);
 
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze(PF_FREEZE);
 
 		spin_lock_bh(&serv->sv_lock);
 		remove_wait_queue(&rqstp->rq_wait, &wait);
diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c
--- a/net/unix/af_unix.c	2005-01-19 13:44:47 -08:00
+++ b/net/unix/af_unix.c	2005-01-19 13:44:47 -08:00
@@ -124,7 +124,7 @@
 static kmem_cache_t *unix_sk_cachep;
 
 struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-rwlock_t unix_table_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(unix_table_lock);
 static atomic_t unix_nr_socks = ATOMIC_INIT(0);
 
 #define unix_sockets_unbound	(&unix_socket_table[UNIX_HASH_SIZE])
diff -Nru a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
--- a/net/wanrouter/af_wanpipe.c	2005-01-19 13:44:48 -08:00
+++ b/net/wanrouter/af_wanpipe.c	2005-01-19 13:44:48 -08:00
@@ -158,7 +158,7 @@
 
 /* List of all wanpipe sockets. */
 HLIST_HEAD(wanpipe_sklist);
-static rwlock_t wanpipe_sklist_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(wanpipe_sklist_lock);
 
 atomic_t wanpipe_socks_nr;
 static unsigned long wanpipe_tx_critical;
diff -Nru a/net/x25/af_x25.c b/net/x25/af_x25.c
--- a/net/x25/af_x25.c	2005-01-19 13:44:47 -08:00
+++ b/net/x25/af_x25.c	2005-01-19 13:44:47 -08:00
@@ -58,7 +58,7 @@
 int sysctl_x25_ack_holdback_timeout    = X25_DEFAULT_T2;
 
 HLIST_HEAD(x25_list);
-rwlock_t x25_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(x25_list_lock);
 
 static struct proto_ops x25_proto_ops;
 
diff -Nru a/net/x25/x25_link.c b/net/x25/x25_link.c
--- a/net/x25/x25_link.c	2005-01-19 13:44:45 -08:00
+++ b/net/x25/x25_link.c	2005-01-19 13:44:45 -08:00
@@ -31,7 +31,7 @@
 #include <net/x25.h>
 
 static struct list_head x25_neigh_list = LIST_HEAD_INIT(x25_neigh_list);
-static rwlock_t x25_neigh_list_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(x25_neigh_list_lock);
 
 static void x25_t20timer_expiry(unsigned long);
 
diff -Nru a/net/x25/x25_route.c b/net/x25/x25_route.c
--- a/net/x25/x25_route.c	2005-01-19 13:44:47 -08:00
+++ b/net/x25/x25_route.c	2005-01-19 13:44:47 -08:00
@@ -23,7 +23,7 @@
 #include <net/x25.h>
 
 struct list_head x25_route_list = LIST_HEAD_INIT(x25_route_list);
-rwlock_t x25_route_list_lock = RW_LOCK_UNLOCKED;
+DEFINE_RWLOCK(x25_route_list_lock);
 
 /*
  *	Add a new route.
diff -Nru a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
--- a/net/xfrm/xfrm_policy.c	2005-01-19 13:44:46 -08:00
+++ b/net/xfrm/xfrm_policy.c	2005-01-19 13:44:46 -08:00
@@ -26,11 +26,11 @@
 
 DECLARE_MUTEX(xfrm_cfg_sem);
 
-static rwlock_t xfrm_policy_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm_policy_lock);
 
 struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2];
 
-static rwlock_t xfrm_policy_afinfo_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm_policy_afinfo_lock);
 static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO];
 
 static kmem_cache_t *xfrm_dst_cache;
@@ -38,7 +38,7 @@
 static struct work_struct xfrm_policy_gc_work;
 static struct list_head xfrm_policy_gc_list =
 	LIST_HEAD_INIT(xfrm_policy_gc_list);
-static spinlock_t xfrm_policy_gc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
 
 static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
 static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
--- a/net/xfrm/xfrm_state.c	2005-01-19 13:44:47 -08:00
+++ b/net/xfrm/xfrm_state.c	2005-01-19 13:44:47 -08:00
@@ -26,7 +26,7 @@
       destination/tunnel endpoint. (output)
  */
 
-static spinlock_t xfrm_state_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xfrm_state_lock);
 
 /* Hash table to find appropriate SA towards given target (endpoint
  * of tunnel or destination of transport mode) allowed by selector.
@@ -39,12 +39,12 @@
 
 DECLARE_WAIT_QUEUE_HEAD(km_waitq);
 
-static rwlock_t xfrm_state_afinfo_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm_state_afinfo_lock);
 static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
 
 static struct work_struct xfrm_state_gc_work;
 static struct list_head xfrm_state_gc_list = LIST_HEAD_INIT(xfrm_state_gc_list);
-static spinlock_t xfrm_state_gc_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xfrm_state_gc_lock);
 
 static void __xfrm_state_delete(struct xfrm_state *x);
 
@@ -619,7 +619,7 @@
 {
 	u32 res;
 	static u32 acqseq;
-	static spinlock_t acqseq_lock = SPIN_LOCK_UNLOCKED;
+	static DEFINE_SPINLOCK(acqseq_lock);
 
 	spin_lock_bh(&acqseq_lock);
 	res = (++acqseq ? : ++acqseq);
@@ -747,7 +747,7 @@
 }
 
 static struct list_head xfrm_km_list = LIST_HEAD_INIT(xfrm_km_list);
-static rwlock_t		xfrm_km_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(xfrm_km_lock);
 
 static void km_state_expired(struct xfrm_state *x, int hard)
 {
diff -Nru a/scripts/README.Menuconfig b/scripts/README.Menuconfig
--- a/scripts/README.Menuconfig	2005-01-19 13:44:46 -08:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,201 +0,0 @@
-Menuconfig gives the Linux kernel configuration a long needed face
-lift.  Featuring text based color menus and dialogs, it does not
-require X Windows (however, you need ncurses in order to use it).
-With this utility you can easily select a kernel option to modify
-without sifting through 100 other options.
-
-Overview
---------
-Some kernel features may be built directly into the kernel.
-Some may be made into loadable runtime modules.  Some features
-may be completely removed altogether.  There are also certain
-kernel parameters which are not really features, but must be 
-entered in as decimal or hexadecimal numbers or possibly text.
-
-Menu items beginning with [*], <M> or [ ] represent features 
-configured to be built in, modularized or removed respectively.
-Pointed brackets <> represent module capable features.
-                                                             more...
-
-To change any of these features, highlight it with the cursor 
-keys and press <Y> to build it in, <M> to make it a module or
-<N> to removed it.  You may also press the <Space Bar> to cycle
-through the available options (ie. Y->N->M->Y). 
-
-Items beginning with numbers or other text within parenthesis can 
-be changed by highlighting the item and pressing <Enter>.  Then
-enter the new parameter into the dialog box that pops up.
-
-
-Some additional keyboard hints:
-
-Menus
-----------
-o  Use the Up/Down arrow keys (cursor keys) to highlight the item 
-   you wish to change or submenu wish to select and press <Enter>.
-   Submenus are designated by "--->".
-
-   Shortcut: Press the option's highlighted letter (hotkey).
-             Pressing a hotkey more than once will sequence
-             through all visible items which use that hotkey.
-
-   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll
-   unseen options into view.
-
-o  To exit a menu use the cursor keys to highlight the <Exit> button
-   and press <ENTER>.  
-
-   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey
-             using those letters.  You may press a single <ESC>, but
-             there is a delayed response which you may find annoying.
-
-   Also, the <TAB> and cursor keys will cycle between <Select>,
-   <Exit> and <Help>
-
-o  To get help with an item, use the cursor keys to highlight <Help>
-   and Press <ENTER>.
-
-   Shortcut: Press <H> or <?>.
-
-
-Radiolists  (Choice lists)
------------
-o  Use the cursor keys to select the option you wish to set and press
-   <S> or the <SPACE BAR>.
-
-   Shortcut: Press the first letter of the option you wish to set then
-             press <S> or <SPACE BAR>.
-
-o  To see available help for the item, use the cursor keys to highlight
-   <Help> and Press <ENTER>.
-
-   Shortcut: Press <H> or <?>.
-
-   Also, the <TAB> and cursor keys will cycle between <Select> and
-   <Help>
-
-
-Data Entry
------------
-o  Enter the requested information and press <ENTER>
-   If you are entering hexadecimal values, it is not necessary to
-   add the '0x' prefix to the entry.
-
-o  For help, use the <TAB> or cursor keys to highlight the help option
-   and press <ENTER>.  You can try <TAB><H> as well.
-
-
-Text Box    (Help Window)
---------
-o  Use the cursor keys to scroll up/down/left/right.  The VI editor
-   keys h,j,k,l function here as do <SPACE BAR> and <B> for those
-   who are familiar with less and lynx.
-
-o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.
-
-
-Final Acceptance
-----------------
-With the exception of the old style sound configuration,
-YOUR CHANGES ARE NOT FINAL.  You will be given a last chance to
-confirm them prior to exiting Menuconfig.
-
-If Menuconfig quits with an error while saving your configuration,
-you may look in the file /usr/src/linux/.menuconfig.log for
-information which may help you determine the cause.
-
-Alternate Configuration Files
------------------------------
-Menuconfig supports the use of alternate configuration files for
-those who, for various reasons, find it necessary to switch 
-between different kernel configurations.
-
-At the end of the main menu you will find two options.  One is
-for saving the current configuration to a file of your choosing.
-The other option is for loading a previously saved alternate
-configuration.
-
-Even if you don't use alternate configuration files, but you 
-find during a Menuconfig session that you have completely messed
-up your settings, you may use the "Load Alternate..." option to
-restore your previously saved settings from ".config" without 
-restarting Menuconfig.
-
-Other information
------------------
-The windowing utility, lxdialog, will only be rebuilt if your kernel
-source tree is fresh, or changes are patched into it via a kernel
-patch or you do 'make mrproper'.  If changes to lxdialog are patched
-in, most likely the rebuild time will be short.  You may force a
-complete rebuild of lxdialog by changing to its directory and doing
-'make clean all'
-
-If you use Menuconfig in an XTERM window make sure you have your 
-$TERM variable set to point to a xterm definition which supports color.
-Otherwise, Menuconfig will look rather bad.  Menuconfig will not 
-display correctly in a RXVT window because rxvt displays only one
-intensity of color, bright.
-
-Menuconfig will display larger menus on screens or xterms which are
-set to display more than the standard 25 row by 80 column geometry.
-In order for this to work, the "stty size" command must be able to 
-display the screen's current row and column geometry.  I STRONGLY
-RECOMMEND that you make sure you do NOT have the shell variables
-LINES and COLUMNS exported into your environment.  Some distributions
-export those variables via /etc/profile.  Some ncurses programs can
-become confused when those variables (LINES & COLUMNS) don't reflect
-the true screen size.
-
-
-NOTICE:  lxdialog requires the ncurses libraries to compile.  If you
-         don't already have ncurses you really should get it.
-
-         The makefile for lxdialog attempts to find your ncurses
-         header file.  Although it should find the header for older
-         versions of ncurses, it is probably a good idea to get the
-         latest ncurses anyway. 
-
-         If you have upgraded your ncurses libraries, MAKE SURE you
-         remove the old ncurses header files.  If you don't you
-         will most certainly get a segmentation fault.
-
-WARNING: It is not recommended that you change any defines in
-         lxdialog's header files.  If you have a grayscale display and
-         are brave, you may tinker with color.h to tune the colors to
-         your preference.
-
-COMPATIBILITY ISSUE:
-         There have been some compatibility problems reported with
-         older versions of bash and sed.  I am trying to work these
-         out but it is preferable that you upgrade those utilities.
-
-
-******** IMPORTANT, OPTIONAL ALTERNATE PERSONALITY AVAILABLE ********
-********                                                     ********
-If you prefer to have all of the kernel options listed in a single
-menu, rather than the default multimenu hierarchy, run the menuconfig
-with MENUCONFIG_MODE environment variable set to single_menu. Example:
-
-make menuconfig MENUCONFIG_MODE=single_menu
-
-<Enter> will then unroll the appropriate category, or enfold it if it
-is already unrolled.
-
-Note that this mode can eventually be a little more CPU expensive
-(especially with a larger number of unrolled categories) than the
-default mode.
-*********************************************************************
-
-
-Propaganda
-----------
-The windowing support utility (lxdialog) is a VERY modified version of
-the dialog utility by Savio Lam <lam836@cs.cuhk.hk>.  Although lxdialog
-is significantly different from dialog, I have left Savio's copyrights
-intact.  Please DO NOT contact Savio with questions about lxdialog.
-He will not be able to assist.
-
-William Roadcap was the original author of Menuconfig.
-Michael Elizabeth Chastain <mec@shout.net> is the current maintainer.
-
-<END OF FILE>
diff -Nru a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
--- a/scripts/kconfig/expr.c	2005-01-19 13:44:46 -08:00
+++ b/scripts/kconfig/expr.c	2005-01-19 13:44:46 -08:00
@@ -1087,3 +1087,13 @@
 {
 	expr_print(e, expr_print_file_helper, out, E_NONE);
 }
+
+static void expr_print_gstr_helper(void *data, const char *str)
+{
+	str_append((struct gstr*)data, str);
+}
+
+void expr_gstr_print(struct expr *e, struct gstr *gs)
+{
+	expr_print(e, expr_print_gstr_helper, gs, E_NONE);
+}
diff -Nru a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
--- a/scripts/kconfig/expr.h	2005-01-19 13:44:47 -08:00
+++ b/scripts/kconfig/expr.h	2005-01-19 13:44:47 -08:00
@@ -174,6 +174,8 @@
 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
 
 void expr_fprint(struct expr *e, FILE *out);
+struct gstr; /* forward */
+void expr_gstr_print(struct expr *e, struct gstr *gs);
 
 static inline int expr_is_yes(struct expr *e)
 {
diff -Nru a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
--- a/scripts/kconfig/lkc.h	2005-01-19 13:44:45 -08:00
+++ b/scripts/kconfig/lkc.h	2005-01-19 13:44:45 -08:00
@@ -56,8 +56,21 @@
 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
 void menu_finalize(struct menu *parent);
 void menu_set_type(int type);
+
+/* util.c */
 struct file *file_lookup(const char *name);
 int file_write_dep(const char *name);
+
+struct gstr {
+	size_t len;
+	char  *s;
+};
+struct gstr str_new(void);
+struct gstr str_assign(const char *s);
+void str_free(struct gstr *gs);
+void str_append(struct gstr *gs, const char *s);
+void str_printf(struct gstr *gs, const char *fmt, ...);
+const char *str_get(struct gstr *gs);
 
 /* symbol.c */
 void sym_init(void);
diff -Nru a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
--- a/scripts/kconfig/lkc_proto.h	2005-01-19 13:44:46 -08:00
+++ b/scripts/kconfig/lkc_proto.h	2005-01-19 13:44:46 -08:00
@@ -18,6 +18,7 @@
 
 P(sym_lookup,struct symbol *,(const char *name, int isconst));
 P(sym_find,struct symbol *,(const char *name));
+P(sym_re_search,struct symbol **,(const char *pattern));
 P(sym_type_name,const char *,(enum symbol_type type));
 P(sym_calc_value,void,(struct symbol *sym));
 P(sym_get_type,enum symbol_type,(struct symbol *sym));
diff -Nru a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
--- a/scripts/kconfig/mconf.c	2005-01-19 13:44:46 -08:00
+++ b/scripts/kconfig/mconf.c	2005-01-19 13:44:46 -08:00
@@ -18,13 +18,146 @@
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
-#include <regex.h>
 
 #define LKC_DIRECT_LINK
 #include "lkc.h"
 
 static char menu_backtitle[128];
-static const char menu_instructions[] =
+static const char mconf_readme[] =
+"Overview\n"
+"--------\n"
+"Some kernel features may be built directly into the kernel.\n"
+"Some may be made into loadable runtime modules.  Some features\n"
+"may be completely removed altogether.  There are also certain\n"
+"kernel parameters which are not really features, but must be\n"
+"entered in as decimal or hexadecimal numbers or possibly text.\n"
+"\n"
+"Menu items beginning with [*], <M> or [ ] represent features\n"
+"configured to be built in, modularized or removed respectively.\n"
+"Pointed brackets <> represent module capable features.\n"
+"\n"
+"To change any of these features, highlight it with the cursor\n"
+"keys and press <Y> to build it in, <M> to make it a module or\n"
+"<N> to removed it.  You may also press the <Space Bar> to cycle\n"
+"through the available options (ie. Y->N->M->Y).\n"
+"\n"
+"Some additional keyboard hints:\n"
+"\n"
+"Menus\n"
+"----------\n"
+"o  Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
+"   you wish to change or submenu wish to select and press <Enter>.\n"
+"   Submenus are designated by \"--->\".\n"
+"\n"
+"   Shortcut: Press the option's highlighted letter (hotkey).\n"
+"             Pressing a hotkey more than once will sequence\n"
+"             through all visible items which use that hotkey.\n"
+"\n"
+"   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
+"   unseen options into view.\n"
+"\n"
+"o  To exit a menu use the cursor keys to highlight the <Exit> button\n"
+"   and press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
+"             using those letters.  You may press a single <ESC>, but\n"
+"             there is a delayed response which you may find annoying.\n"
+"\n"
+"   Also, the <TAB> and cursor keys will cycle between <Select>,\n"
+"   <Exit> and <Help>\n"
+"\n"
+"o  To get help with an item, use the cursor keys to highlight <Help>\n"
+"   and Press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <H> or <?>.\n"
+"\n"
+"\n"
+"Radiolists  (Choice lists)\n"
+"-----------\n"
+"o  Use the cursor keys to select the option you wish to set and press\n"
+"   <S> or the <SPACE BAR>.\n"
+"\n"
+"   Shortcut: Press the first letter of the option you wish to set then\n"
+"             press <S> or <SPACE BAR>.\n"
+"\n"
+"o  To see available help for the item, use the cursor keys to highlight\n"
+"   <Help> and Press <ENTER>.\n"
+"\n"
+"   Shortcut: Press <H> or <?>.\n"
+"\n"
+"   Also, the <TAB> and cursor keys will cycle between <Select> and\n"
+"   <Help>\n"
+"\n"
+"\n"
+"Data Entry\n"
+"-----------\n"
+"o  Enter the requested information and press <ENTER>\n"
+"   If you are entering hexadecimal values, it is not necessary to\n"
+"   add the '0x' prefix to the entry.\n"
+"\n"
+"o  For help, use the <TAB> or cursor keys to highlight the help option\n"
+"   and press <ENTER>.  You can try <TAB><H> as well.\n"
+"\n"
+"\n"
+"Text Box    (Help Window)\n"
+"--------\n"
+"o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
+"   keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
+"   who are familiar with less and lynx.\n"
+"\n"
+"o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
+"\n"
+"\n"
+"Alternate Configuration Files\n"
+"-----------------------------\n"
+"Menuconfig supports the use of alternate configuration files for\n"
+"those who, for various reasons, find it necessary to switch\n"
+"between different kernel configurations.\n"
+"\n"
+"At the end of the main menu you will find two options.  One is\n"
+"for saving the current configuration to a file of your choosing.\n"
+"The other option is for loading a previously saved alternate\n"
+"configuration.\n"
+"\n"
+"Even if you don't use alternate configuration files, but you\n"
+"find during a Menuconfig session that you have completely messed\n"
+"up your settings, you may use the \"Load Alternate...\" option to\n"
+"restore your previously saved settings from \".config\" without\n"
+"restarting Menuconfig.\n"
+"\n"
+"Other information\n"
+"-----------------\n"
+"If you use Menuconfig in an XTERM window make sure you have your\n"
+"$TERM variable set to point to a xterm definition which supports color.\n"
+"Otherwise, Menuconfig will look rather bad.  Menuconfig will not\n"
+"display correctly in a RXVT window because rxvt displays only one\n"
+"intensity of color, bright.\n"
+"\n"
+"Menuconfig will display larger menus on screens or xterms which are\n"
+"set to display more than the standard 25 row by 80 column geometry.\n"
+"In order for this to work, the \"stty size\" command must be able to\n"
+"display the screen's current row and column geometry.  I STRONGLY\n"
+"RECOMMEND that you make sure you do NOT have the shell variables\n"
+"LINES and COLUMNS exported into your environment.  Some distributions\n"
+"export those variables via /etc/profile.  Some ncurses programs can\n"
+"become confused when those variables (LINES & COLUMNS) don't reflect\n"
+"the true screen size.\n"
+"\n"
+"Optional personality available\n"
+"------------------------------\n"
+"If you prefer to have all of the kernel options listed in a single\n"
+"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
+"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
+"\n"
+"make MENUCONFIG_MODE=single_menu menuconfig\n"
+"\n"
+"<Enter> will then unroll the appropriate category, or enfold it if it\n"
+"is already unrolled.\n"
+"\n"
+"Note that this mode can eventually be a little more CPU expensive\n"
+"(especially with a larger number of unrolled categories) than the\n"
+"default mode.\n",
+menu_instructions[] =
 	"Arrow keys navigate the menu.  "
 	"<Enter> selects submenus --->.  "
 	"Highlighted letters are hotkeys.  "
@@ -79,8 +212,45 @@
 	"configuration options you have selected at that time.\n"
 	"\n"
 	"If you are uncertain what all this means then you should probably\n"
-	"leave this blank.\n"
-;
+	"leave this blank.\n",
+search_help[] =
+	"\n"
+	"Search for CONFIG_ symbols and display their relations.\n"
+	"Example: search for \"^FOO\"\n"
+	"Result:\n"
+	"-----------------------------------------------------------------\n"
+	"Symbol: FOO [=m]\n"
+	"Prompt: Foo bus is used to drive the bar HW\n"
+	"Defined at drivers/pci/Kconfig:47\n"
+	"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+	"Location:\n"
+	"  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
+	"    -> PCI support (PCI [=y])\n"
+	"      -> PCI access mode (<choice> [=y])\n"
+	"Selects: LIBCRC32\n"
+	"Selected by: BAR\n"
+	"-----------------------------------------------------------------\n"
+	"o The line 'Prompt:' shows the text used in the menu structure for\n"
+	"  this CONFIG_ symbol\n"
+	"o The 'Defined at' line tell at what file / line number the symbol\n"
+	"  is defined\n"
+	"o The 'Depends on:' line tell what symbols needs to be defined for\n"
+	"  this symbol to be visible in the menu (selectable)\n"
+	"o The 'Location:' lines tell where in the menu structure this symbol\n"
+	"  is located\n"
+	"    A location followed by a [=y] indicate that this is a selectable\n"
+	"    menu item - and current value is displayed inside brackets.\n"
+	"o The 'Selects:' line tell what symbol will be automatically\n"
+	"  selected if this symbol is selected (y or m)\n"
+	"o The 'Selected by' line tell what symbol has selected this symbol\n"
+	"\n"
+	"Only relevant lines are shown.\n"
+	"\n\n"
+	"Search examples:\n"
+	"Examples: USB	=> find all CONFIG_ symbols containing USB\n"
+	"          ^USB => find all CONFIG_ symbols starting with USB\n"
+	"          USB$ => find all CONFIG_ symbols ending with USB\n"
+	"\n";
 
 static signed char buf[4096], *bufptr = buf;
 static signed char input_buf[4096];
@@ -102,11 +272,7 @@
 static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
-static void show_readme(void);
 static void show_file(const char *filename, const char *title, int r, int c);
-static void show_expr(struct menu *menu, FILE *fp);
-static void search_conf(char *pattern);
-static int regex_match(const char *string, regex_t *re);
 
 static void cprint_init(void);
 static int cprint1(const char *fmt, ...);
@@ -196,6 +362,78 @@
 	return res;
 }
 
+static void get_prompt_str(struct gstr *r, struct property *prop)
+{
+	int i, j;
+	struct menu *submenu[8], *menu;
+
+	str_printf(r, "Prompt: %s\n", prop->text);
+	str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
+		prop->menu->lineno);
+	if (!expr_is_yes(prop->visible.expr)) {
+		str_append(r, "  Depends on: ");
+		expr_gstr_print(prop->visible.expr, r);
+		str_append(r, "\n");
+	}
+	menu = prop->menu->parent;
+	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
+		submenu[i++] = menu;
+	if (i > 0) {
+		str_printf(r, "  Location:\n");
+		for (j = 4; --i >= 0; j += 2) {
+			menu = submenu[i];
+			str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
+			if (menu->sym) {
+				str_printf(r, " (%s [=%s])", menu->sym->name ?
+					menu->sym->name : "<choice>",
+					sym_get_string_value(menu->sym));
+			}
+			str_append(r, "\n");
+		}
+	}
+}
+
+static void get_symbol_str(struct gstr *r, struct symbol *sym)
+{
+	bool hit;
+	struct property *prop;
+
+	str_printf(r, "Symbol: %s [=%s]\n", sym->name,
+	                               sym_get_string_value(sym));
+	for_all_prompts(sym, prop)
+		get_prompt_str(r, prop);
+	hit = false;
+	for_all_properties(sym, prop, P_SELECT) {
+		if (!hit) {
+			str_append(r, "  Selects: ");
+			hit = true;
+		} else
+			str_printf(r, " && ");
+		expr_gstr_print(prop->expr, r);
+	}
+	if (hit)
+		str_append(r, "\n");
+	if (sym->rev_dep.expr) {
+		str_append(r, "  Selected by: ");
+		expr_gstr_print(sym->rev_dep.expr, r);
+		str_append(r, "\n");
+	}
+	str_append(r, "\n\n");
+}
+
+static struct gstr get_relations_str(struct symbol **sym_arr)
+{
+	struct symbol *sym;
+	struct gstr res = str_new();
+	int i;
+
+	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
+		get_symbol_str(&res, sym);
+	if (!i)
+		str_append(&res, "No matches found.\n");
+	return res;
+}
+
 pid_t pid;
 
 static void winch_handler(int sig)
@@ -279,112 +517,39 @@
 	return WEXITSTATUS(stat);
 }
 
-static int regex_match(const char *string, regex_t *re)
+static void search_conf(void)
 {
-	int rc;
-
-	rc = regexec(re, string, (size_t) 0, NULL, 0);
-	if (rc)
-		return 0;
-	return 1;
-}
-
-static void show_expr(struct menu *menu, FILE *fp)
-{
-	bool hit = false;
-	fprintf(fp, "Depends:\n ");
-	if (menu->prompt->visible.expr) {
-		if (!hit)
-			hit = true;
-		expr_fprint(menu->prompt->visible.expr, fp);
-	}
-	if (!hit)
-		fprintf(fp, "None");
-	if (menu->sym) {
-		struct property *prop;
-		hit = false;
-		fprintf(fp, "\nSelects:\n ");
-		for_all_properties(menu->sym, prop, P_SELECT) {
-			if (!hit)
-				hit = true;
-			expr_fprint(prop->expr, fp);
-		}
-		if (!hit)
-			fprintf(fp, "None");
-		hit = false;
-		fprintf(fp, "\nSelected by:\n ");
-		if (menu->sym->rev_dep.expr) {
-			hit = true;
-			expr_fprint(menu->sym->rev_dep.expr, fp);
-		}
-		if (!hit)
-			fprintf(fp, "None");
-	}
-}
-
-static void search_conf(char *pattern)
-{
-	struct symbol *sym = NULL;
-	struct menu *menu[32] = { 0 };
-	struct property *prop = NULL;
-	FILE *fp = NULL;
-	bool hit = false;
-	int i, j, k, l;
-	regex_t re;
-
-	if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB))
+	struct symbol **sym_arr;
+	int stat;
+	struct gstr res;
+
+again:
+	cprint_init();
+	cprint("--title");
+	cprint("Search Configuration Parameter");
+	cprint("--inputbox");
+	cprint("Enter Keyword");
+	cprint("10");
+	cprint("75");
+	cprint("");
+	stat = exec_conf();
+	if (stat < 0)
+		goto again;
+	switch (stat) {
+	case 0:
+		break;
+	case 1:
+		show_helptext("Search Configuration", search_help);
+		goto again;
+	default:
 		return;
-
-	fp = fopen(".search.tmp", "w");
-	if (fp == NULL) {
-		perror("fopen");
-		return;
-	}
-	for_all_symbols(i, sym) {
-		if (!sym->name)
-			continue;
-		if (!regex_match(sym->name, &re))
-			continue;
-		for_all_prompts(sym, prop) {
-			struct menu *submenu = prop->menu;
-			if (!submenu)
-				continue;
-			j = 0;
-			hit = false;
-			while (submenu) {
-				menu[j++] = submenu;
-				submenu = submenu->parent;
-			}
-			if (j > 0) {
-				if (!hit)
-					hit = true;
-				fprintf(fp, "%s (%s)\n", prop->text, sym->name);
-				fprintf(fp, "Location:\n");
-			}
-			for (k = j-2, l=1; k > 0; k--, l++) {
-				const char *prompt = menu_get_prompt(menu[k]);
-				if (menu[k]->sym)
-					fprintf(fp, "%*c-> %s (%s)\n",
-								l, ' ',
-								prompt,
-								menu[k]->sym->name);
-				else
-					fprintf(fp, "%*c-> %s\n",
-								l, ' ',
-								prompt);
-			}
-			if (hit) {
-				show_expr(menu[0], fp);
-				fprintf(fp, "\n\n\n");
-			}
-		}
 	}
-	if (!hit)
-		fprintf(fp, "No matches found.");
-	regfree(&re);
-	fclose(fp);
-	show_file(".search.tmp", "Search Results", rows, cols);
-	unlink(".search.tmp");
+
+	sym_arr = sym_re_search(input_buf);
+	res = get_relations_str(sym_arr);
+	free(sym_arr);
+	show_textbox("Search Results", str_get(&res), 0, 0);
+	str_free(&res);
 }
 
 static void build_conf(struct menu *menu)
@@ -576,23 +741,6 @@
 			cprint("    Save Configuration to an Alternate File");
 		}
 		stat = exec_conf();
-		if (stat == 26) {
-			char *pattern;
-
-			if (!strlen(input_buf))
-				continue;
-			pattern = malloc(sizeof(char)*sizeof(input_buf));
-			if (pattern == NULL) {
-				perror("malloc");
-				continue;
-			}
-			for (i = 0; input_buf[i]; i++)
-				pattern[i] = toupper(input_buf[i]);
-			pattern[i] = '\0';
-			search_conf(pattern);
-			free(pattern);
-			continue;
-		}
 		if (stat < 0)
 			continue;
 
@@ -645,7 +793,7 @@
 			if (sym)
 				show_help(submenu);
 			else
-				show_readme();
+				show_helptext("README", mconf_readme);
 			break;
 		case 3:
 			if (type == 't') {
@@ -669,6 +817,9 @@
 			else if (type == 'm')
 				conf(submenu);
 			break;
+		case 7:
+			search_conf();
+			break;
 		}
 	}
 }
@@ -686,30 +837,27 @@
 
 static void show_helptext(const char *title, const char *text)
 {
-	show_textbox(title, text, rows, cols);
+	show_textbox(title, text, 0, 0);
 }
 
 static void show_help(struct menu *menu)
 {
-	const char *help;
-	char *helptext;
+	struct gstr help = str_new();
 	struct symbol *sym = menu->sym;
 
-	help = sym->help;
-	if (!help)
-		help = nohelp_text;
-	if (sym->name) {
-		helptext = malloc(strlen(sym->name) + strlen(help) + 16);
-		sprintf(helptext, "CONFIG_%s:\n\n%s", sym->name, help);
-		show_helptext(menu_get_prompt(menu), helptext);
-		free(helptext);
-	} else
-		show_helptext(menu_get_prompt(menu), help);
-}
-
-static void show_readme(void)
-{
-	show_file("scripts/README.Menuconfig", NULL, rows, cols);
+	if (sym->help)
+	{
+		if (sym->name) {
+			str_printf(&help, "CONFIG_%s:\n\n", sym->name);
+			str_append(&help, sym->help);
+			str_append(&help, "\n");
+		}
+	} else {
+		str_append(&help, nohelp_text);
+	}
+	get_symbol_str(&help, sym);
+	show_helptext(menu_get_prompt(menu), str_get(&help));
+	str_free(&help);
 }
 
 static void show_file(const char *filename, const char *title, int r, int c)
@@ -722,8 +870,8 @@
 		}
 		cprint("--textbox");
 		cprint("%s", filename);
-		cprint("%d", r);
-		cprint("%d", c);
+		cprint("%d", r ? r : rows);
+		cprint("%d", c ? c : cols);
 	} while (exec_conf() < 0);
 }
 
diff -Nru a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
--- a/scripts/kconfig/menu.c	2005-01-19 13:44:48 -08:00
+++ b/scripts/kconfig/menu.c	2005-01-19 13:44:48 -08:00
@@ -388,43 +388,3 @@
 	return menu;
 }
 
-struct file *file_lookup(const char *name)
-{
-	struct file *file;
-
-	for (file = file_list; file; file = file->next) {
-		if (!strcmp(name, file->name))
-			return file;
-	}
-
-	file = malloc(sizeof(*file));
-	memset(file, 0, sizeof(*file));
-	file->name = strdup(name);
-	file->next = file_list;
-	file_list = file;
-	return file;
-}
-
-int file_write_dep(const char *name)
-{
-	struct file *file;
-	FILE *out;
-
-	if (!name)
-		name = ".config.cmd";
-	out = fopen("..config.tmp", "w");
-	if (!out)
-		return 1;
-	fprintf(out, "deps_config := \\\n");
-	for (file = file_list; file; file = file->next) {
-		if (file->next)
-			fprintf(out, "\t%s \\\n", file->name);
-		else
-			fprintf(out, "\t%s\n", file->name);
-	}
-	fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
-	fclose(out);
-	rename("..config.tmp", name);
-	return 0;
-}
-
diff -Nru a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
--- a/scripts/kconfig/symbol.c	2005-01-19 13:44:46 -08:00
+++ b/scripts/kconfig/symbol.c	2005-01-19 13:44:46 -08:00
@@ -6,6 +6,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+#include <regex.h>
 #include <sys/utsname.h>
 
 #define LKC_DIRECT_LINK
@@ -655,6 +656,43 @@
 
 	return symbol;
 }
+
+struct symbol **sym_re_search(const char *pattern)
+{
+	struct symbol *sym, **sym_arr = NULL;
+	int i, cnt, size;
+	regex_t re;
+
+	cnt = size = 0;
+	/* Skip if empty */
+	if (strlen(pattern) == 0)
+		return NULL;
+	if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
+		return NULL;
+
+	for_all_symbols(i, sym) {
+		if (sym->flags & SYMBOL_CONST || !sym->name)
+			continue;
+		if (regexec(&re, sym->name, 0, NULL, 0))
+			continue;
+		if (cnt + 1 >= size) {
+			void *tmp = sym_arr;
+			size += 16;
+			sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
+			if (!sym_arr) {
+				free(tmp);
+				return NULL;
+			}
+		}
+		sym_arr[cnt++] = sym;
+	}
+	if (sym_arr)
+		sym_arr[cnt] = NULL;
+	regfree(&re);
+
+	return sym_arr;
+}
+
 
 struct symbol *sym_check_deps(struct symbol *sym);
 
diff -Nru a/scripts/kconfig/util.c b/scripts/kconfig/util.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/scripts/kconfig/util.c	2005-01-19 13:44:48 -08:00
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
+ * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <string.h>
+#include "lkc.h"
+
+/* file already present in list? If not add it */
+struct file *file_lookup(const char *name)
+{
+	struct file *file;
+
+	for (file = file_list; file; file = file->next) {
+		if (!strcmp(name, file->name))
+			return file;
+	}
+
+	file = malloc(sizeof(*file));
+	memset(file, 0, sizeof(*file));
+	file->name = strdup(name);
+	file->next = file_list;
+	file_list = file;
+	return file;
+}
+
+/* write a dependency file as used by kbuild to track dependencies */
+int file_write_dep(const char *name)
+{
+	struct file *file;
+	FILE *out;
+
+	if (!name)
+		name = ".config.cmd";
+	out = fopen("..config.tmp", "w");
+	if (!out)
+		return 1;
+	fprintf(out, "deps_config := \\\n");
+	for (file = file_list; file; file = file->next) {
+		if (file->next)
+			fprintf(out, "\t%s \\\n", file->name);
+		else
+			fprintf(out, "\t%s\n", file->name);
+	}
+	fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n");
+	fclose(out);
+	rename("..config.tmp", name);
+	return 0;
+}
+
+
+/* Allocate initial growable sting */
+struct gstr str_new(void)
+{
+	struct gstr gs;
+	gs.s = malloc(sizeof(char) * 64);
+	gs.len = 16;
+	strcpy(gs.s, "\0");
+	return gs;
+}
+
+/* Allocate and assign growable string */
+struct gstr str_assign(const char *s)
+{
+	struct gstr gs;
+	gs.s = strdup(s);
+	gs.len = strlen(s) + 1;
+	return gs;
+}
+
+/* Free storage for growable string */
+void str_free(struct gstr *gs)
+{
+	if (gs->s)
+		free(gs->s);
+	gs->s = NULL;
+	gs->len = 0;
+}
+
+/* Append to growable string */
+void str_append(struct gstr *gs, const char *s)
+{
+	size_t l = strlen(gs->s) + strlen(s) + 1;
+	if (l > gs->len) {
+		gs->s   = realloc(gs->s, l);
+		gs->len = l;
+	}
+	strcat(gs->s, s);
+}
+
+/* Append printf formatted string to growable string */
+void str_printf(struct gstr *gs, const char *fmt, ...)
+{
+	va_list ap;
+	char s[10000]; /* big enough... */
+	va_start(ap, fmt);
+	vsnprintf(s, sizeof(s), fmt, ap);
+	str_append(gs, s);
+	va_end(ap);
+}
+
+/* Retreive value of growable string */
+const char *str_get(struct gstr *gs)
+{
+	return gs->s;
+}
+
diff -Nru a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
--- a/scripts/kconfig/zconf.tab.c_shipped	2005-01-19 13:44:47 -08:00
+++ b/scripts/kconfig/zconf.tab.c_shipped	2005-01-19 13:44:47 -08:00
@@ -2121,6 +2121,7 @@
 }
 
 #include "lex.zconf.c"
+#include "util.c"
 #include "confdata.c"
 #include "expr.c"
 #include "symbol.c"
diff -Nru a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
--- a/scripts/kconfig/zconf.y	2005-01-19 13:44:47 -08:00
+++ b/scripts/kconfig/zconf.y	2005-01-19 13:44:47 -08:00
@@ -683,6 +683,7 @@
 }
 
 #include "lex.zconf.c"
+#include "util.c"
 #include "confdata.c"
 #include "expr.c"
 #include "symbol.c"
diff -Nru a/scripts/lxdialog/menubox.c b/scripts/lxdialog/menubox.c
--- a/scripts/lxdialog/menubox.c	2005-01-19 13:44:47 -08:00
+++ b/scripts/lxdialog/menubox.c	2005-01-19 13:44:47 -08:00
@@ -276,15 +276,6 @@
 
     while (key != ESC) {
 	key = wgetch(menu);
-	if ( key == '/' ) {
-		int ret = dialog_inputbox("Search Configuration Parameter",
-					"Enter Keyword", height, width,
-					(char *) NULL);
-		if (ret == 0) {
-			fprintf(stderr, "%s", dialog_input_result);
-			return 26;
-		}
-	}
 
 	if (key < 256 && isalpha(key)) key = tolower(key);
 
@@ -408,6 +399,7 @@
 	case 'y':
 	case 'n':
 	case 'm':
+	case '/':
 	    /* save scroll info */
 	    if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
 		fprintf(f,"%d\n",scroll);
@@ -421,6 +413,7 @@
             case 'n': return 4;
             case 'm': return 5;
             case ' ': return 6;
+            case '/': return 7;
             }
 	    return 0;
 	case 'h':
diff -Nru a/security/Kconfig b/security/Kconfig
--- a/security/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/security/Kconfig	2005-01-19 13:44:47 -08:00
@@ -80,7 +80,7 @@
 	select CRYPTO_SHA1
 	help
 	  Implements BSD Secure Levels as an LSM.  See
-	  Documentation/seclvl.txt for instructions on how to use this
+	  <file:Documentation/seclvl.txt> for instructions on how to use this
 	  module.
 
 	  If you are unsure how to answer this question, answer N.
diff -Nru a/security/selinux/Kconfig b/security/selinux/Kconfig
--- a/security/selinux/Kconfig	2005-01-19 13:44:45 -08:00
+++ b/security/selinux/Kconfig	2005-01-19 13:44:45 -08:00
@@ -34,7 +34,7 @@
 	  'selinux', which allows SELinux to be disabled at boot.  If this
 	  option is set to 0 (zero), the SELinux kernel parameter will
 	  default to 0, disabling SELinux at bootup.  If this option is
-	  set to 1 (one), the SELinux kernel paramater will default to 1,
+	  set to 1 (one), the SELinux kernel parameter will default to 1,
 	  enabling SELinux at bootup.
 
 	  If you are unsure how to answer this question, answer 1.
diff -Nru a/security/selinux/hooks.c b/security/selinux/hooks.c
--- a/security/selinux/hooks.c	2005-01-19 13:44:47 -08:00
+++ b/security/selinux/hooks.c	2005-01-19 13:44:47 -08:00
@@ -73,7 +73,7 @@
 #define XATTR_SELINUX_SUFFIX "selinux"
 #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
 
-extern int policydb_loaded_version;
+extern unsigned int policydb_loaded_version;
 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
 
 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP
diff -Nru a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
--- a/security/selinux/ss/avtab.c	2005-01-19 13:44:47 -08:00
+++ b/security/selinux/ss/avtab.c	2005-01-19 13:44:47 -08:00
@@ -386,8 +386,10 @@
 		goto bad;
 	}
 	for (i = 0; i < nel; i++) {
-		if (avtab_read_item(fp, &avdatum, &avkey))
+		if (avtab_read_item(fp, &avdatum, &avkey)) {
+			rc = -EINVAL;
 			goto bad;
+		}
 		rc = avtab_insert(a, &avkey, &avdatum);
 		if (rc) {
 			if (rc == -ENOMEM)
diff -Nru a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
--- a/security/selinux/ss/ebitmap.c	2005-01-19 13:44:47 -08:00
+++ b/security/selinux/ss/ebitmap.c	2005-01-19 13:44:47 -08:00
@@ -237,7 +237,7 @@
 
 int ebitmap_read(struct ebitmap *e, void *fp)
 {
-	int rc = -EINVAL;
+	int rc;
 	struct ebitmap_node *n, *l;
 	u32 buf[3], mapsize, count, i;
 	u64 map;
@@ -256,7 +256,7 @@
 		printk(KERN_ERR "security: ebitmap: map size %u does not "
 		       "match my size %Zd (high bit was %d)\n", mapsize,
 		       MAPSIZE, e->highbit);
-		goto out;
+		goto bad;
 	}
 	if (!e->highbit) {
 		e->node = NULL;
@@ -329,6 +329,8 @@
 bad_free:
 	kfree(n);
 bad:
+	if (!rc)
+		rc = -EINVAL;
 	ebitmap_destroy(e);
 	goto out;
 }
diff -Nru a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
--- a/security/selinux/ss/policydb.c	2005-01-19 13:44:46 -08:00
+++ b/security/selinux/ss/policydb.c	2005-01-19 13:44:46 -08:00
@@ -38,8 +38,6 @@
 };
 #endif
 
-int policydb_loaded_version;
-
 static unsigned int symtab_sizes[SYM_NUM] = {
 	2,
 	32,
@@ -832,7 +830,6 @@
 	}
 
 	lc = NULL;
-	rc = -EINVAL;
 	for (i = 0; i < ncons; i++) {
 		c = kmalloc(sizeof(*c), GFP_KERNEL);
 		if (!c) {
@@ -875,6 +872,7 @@
 			e->attr = le32_to_cpu(buf[1]);
 			e->op = le32_to_cpu(buf[2]);
 
+			rc = -EINVAL;
 			switch (e->expr_type) {
 			case CEXPR_NOT:
 				if (depth < 0)
@@ -915,6 +913,8 @@
 	rc = hashtab_insert(h, key, cladatum);
 	if (rc)
 		goto bad;
+
+	rc = 0;
 out:
 	return rc;
 bad:
@@ -1098,7 +1098,7 @@
 	struct role_trans *tr, *ltr;
 	struct ocontext *l, *c, *newc;
 	struct genfs *genfs_p, *genfs, *newgenfs;
-	int i, j, rc, r_policyvers = 0;
+	int i, j, rc;
 	u32 buf[8], len, len2, config, nprim, nel, nel2;
 	char *policydb_str;
 	struct policydb_compat_info *info;
@@ -1110,7 +1110,6 @@
 	if (rc)
 		goto out;
 
-	rc = -EINVAL;
 	/* Read the magic number and string length. */
 	rc = next_entry(buf, fp, sizeof(u32)* 2);
 	if (rc < 0)
@@ -1164,9 +1163,9 @@
 	for (i = 0; i < 4; i++)
 		buf[i] = le32_to_cpu(buf[i]);
 
-	r_policyvers = buf[0];
-	if (r_policyvers < POLICYDB_VERSION_MIN ||
-	    r_policyvers > POLICYDB_VERSION_MAX) {
+	p->policyvers = buf[0];
+	if (p->policyvers < POLICYDB_VERSION_MIN ||
+	    p->policyvers > POLICYDB_VERSION_MAX) {
 	    	printk(KERN_ERR "security:  policydb version %d does not match "
 	    	       "my version range %d-%d\n",
 	    	       buf[0], POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
@@ -1182,10 +1181,10 @@
 	}
 
 
-	info = policydb_lookup_compat(r_policyvers);
+	info = policydb_lookup_compat(p->policyvers);
 	if (!info) {
 		printk(KERN_ERR "security:  unable to find policy compat info "
-		       "for version %d\n", r_policyvers);
+		       "for version %d\n", p->policyvers);
 		goto bad;
 	}
 
@@ -1219,7 +1218,7 @@
 	if (rc)
 		goto bad;
 
-	if (r_policyvers >= POLICYDB_VERSION_BOOL) {
+	if (p->policyvers >= POLICYDB_VERSION_BOOL) {
 		rc = cond_read_list(p, fp);
 		if (rc)
 			goto bad;
@@ -1503,12 +1502,15 @@
 	rc = mls_read_trusted(p, fp);
 	if (rc)
 		goto bad;
+
+	rc = 0;
 out:
-	policydb_loaded_version = r_policyvers;
 	return rc;
 bad_newc:
 	ocontext_destroy(newc,OCON_FSUSE);
 bad:
+	if (!rc)
+		rc = -EINVAL;
 	policydb_destroy(p);
 	goto out;
 }
diff -Nru a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
--- a/security/selinux/ss/policydb.h	2005-01-19 13:44:47 -08:00
+++ b/security/selinux/ss/policydb.h	2005-01-19 13:44:47 -08:00
@@ -246,6 +246,8 @@
 	struct ebitmap trustedwriters;
 	struct ebitmap trustedobjects;
 #endif
+
+	unsigned int policyvers;
 };
 
 extern int policydb_init(struct policydb *p);
diff -Nru a/security/selinux/ss/services.c b/security/selinux/ss/services.c
--- a/security/selinux/ss/services.c	2005-01-19 13:44:47 -08:00
+++ b/security/selinux/ss/services.c	2005-01-19 13:44:47 -08:00
@@ -40,7 +40,7 @@
 #include "mls.h"
 
 extern void selnl_notify_policyload(u32 seqno);
-extern int policydb_loaded_version;
+unsigned int policydb_loaded_version;
 
 static rwlock_t policy_rwlock = RW_LOCK_UNLOCKED;
 #define POLICY_RDLOCK read_lock(&policy_rwlock)
@@ -1047,6 +1047,7 @@
 			avtab_cache_destroy();
 			return -EINVAL;
 		}
+		policydb_loaded_version = policydb.policyvers;
 		ss_initialized = 1;
 
 		LOAD_UNLOCK;
@@ -1095,7 +1096,7 @@
 	memcpy(&policydb, &newpolicydb, sizeof policydb);
 	sidtab_set(&sidtab, &newsidtab);
 	seqno = ++latest_granting;
-
+	policydb_loaded_version = policydb.policyvers;
 	POLICY_WRUNLOCK;
 	LOAD_UNLOCK;
 
diff -Nru a/sound/core/ioctl32/ioctl32.c b/sound/core/ioctl32/ioctl32.c
--- a/sound/core/ioctl32/ioctl32.c	2005-01-19 13:44:46 -08:00
+++ b/sound/core/ioctl32/ioctl32.c	2005-01-19 13:44:46 -08:00
@@ -219,25 +219,10 @@
 	struct sndrv_ctl_elem_id id;
 	unsigned int indirect;	/* bit-field causes misalignment */
         union {
-		union {
-			s32 value[128];
-			u32 value_ptr;
-		} integer;
-		union {
-			s64 value[64];
-			u32 value_ptr;
-		} integer64;
-		union {
-			u32 item[128];
-			u32 item_ptr;
-		} enumerated;
-		union {
-			unsigned char data[512];
-			u32 data_ptr;
-		} bytes;
-		struct sndrv_aes_iec958 iec958;
+		s32 integer[128];	/* integer and boolean need conversion */
+		unsigned char data[512];	/* others should be compatible */
         } value;
-        unsigned char reserved[128];
+        unsigned char reserved[128];	/* not used */
 };
 
 
@@ -269,7 +254,7 @@
 	struct sndrv_ctl_elem_value *data;
 	struct sndrv_ctl_elem_value32 __user *data32;
 	snd_ctl_file_t *ctl;
-	int err, i;
+	int err, i, indirect;
 	int type;
 
 	/* sanity check */
@@ -281,7 +266,7 @@
 		return -ENOTTY;
 
 	data32 = compat_ptr(arg);
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 
@@ -289,12 +274,12 @@
 		err = -EFAULT;
 		goto __end;
 	}
-	if (__get_user(data->indirect, &data32->indirect)) {
+	if (__get_user(indirect, &data32->indirect)) {
 		err = -EFAULT;
 		goto __end;
 	}
 	/* FIXME: indirect access is not supported */
-	if (data->indirect) {
+	if (indirect) {
 		err = -EINVAL;
 		goto __end;
 	}
@@ -309,7 +294,7 @@
 	case SNDRV_CTL_ELEM_TYPE_INTEGER:
 		for (i = 0; i < 128; i++) {
 			int val;
-			if (__get_user(val, &data32->value.integer.value[i])) {
+			if (__get_user(val, &data32->value.integer[i])) {
 				err = -EFAULT;
 				goto __end;
 			}
@@ -317,33 +302,12 @@
 		}
 		break;
 	case SNDRV_CTL_ELEM_TYPE_INTEGER64:
-		if (__copy_from_user(data->value.integer64.value,
-				     data32->value.integer64.value,
-				     sizeof(data->value.integer64.value))) {
-			err = -EFAULT;
-			goto __end;
-		}
-		break;
 	case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
-		if (__copy_from_user(data->value.enumerated.item,
-				     data32->value.enumerated.item,
-				     sizeof(data32->value.enumerated.item))) {
-			err = -EFAULT;
-			goto __end;
-		}
-		break;
 	case SNDRV_CTL_ELEM_TYPE_BYTES:
-		if (__copy_from_user(data->value.bytes.data,
-				     data32->value.bytes.data,
-				     sizeof(data32->value.bytes.data))) {
-			err = -EFAULT;
-			goto __end;
-		}
-		break;
 	case SNDRV_CTL_ELEM_TYPE_IEC958:
-		if (__copy_from_user(&data->value.iec958,
-				     &data32->value.iec958,
-				     sizeof(data32->value.iec958))) {
+		if (__copy_from_user(data->value.bytes.data,
+				     data32->value.data,
+				     sizeof(data32->value.data))) {
 			err = -EFAULT;
 			goto __end;
 		}
@@ -367,43 +331,20 @@
 		for (i = 0; i < 128; i++) {
 			int val;
 			val = data->value.integer.value[i];
-			if (__put_user(val, &data32->value.integer.value[i])) {
+			if (__put_user(val, &data32->value.integer[i])) {
 				err = -EFAULT;
 				goto __end;
 			}
 		}
 		break;
-	case SNDRV_CTL_ELEM_TYPE_INTEGER64:
-		if (__copy_to_user(data32->value.integer64.value,
-				   data->value.integer64.value,
-				   sizeof(data32->value.integer64.value))) {
-			err = -EFAULT;
-			goto __end;
-		}
-		break;
-	case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
-		if (__copy_to_user(data32->value.enumerated.item,
-				   data->value.enumerated.item,
-				   sizeof(data32->value.enumerated.item))) {
-			err = -EFAULT;
-			goto __end;
-		}
-		break;
-	case SNDRV_CTL_ELEM_TYPE_BYTES:
-		if (__copy_to_user(data32->value.bytes.data,
+	default:
+		if (__copy_to_user(data32->value.data,
 				   data->value.bytes.data,
-				   sizeof(data32->value.bytes.data))) {
+				   sizeof(data32->value.data))) {
 			err = -EFAULT;
 			goto __end;
 		}
 		break;
-	case SNDRV_CTL_ELEM_TYPE_IEC958:
-		if (__copy_to_user(&data32->value.iec958,
-				   &data->value.iec958,
-				   sizeof(data32->value.iec958))) {
-			err = -EFAULT;
-			goto __end;
-		}
 		break;
 	}
 	err = 0;
diff -Nru a/sound/core/rawmidi.c b/sound/core/rawmidi.c
--- a/sound/core/rawmidi.c	2005-01-19 13:44:46 -08:00
+++ b/sound/core/rawmidi.c	2005-01-19 13:44:46 -08:00
@@ -747,7 +747,7 @@
 	case SNDRV_RAWMIDI_IOCTL_DROP:
 	{
 		int val;
-		if (get_user(val, (long __user *) argp))
+		if (get_user(val, (int __user *) argp))
 			return -EFAULT;
 		switch (val) {
 		case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -761,7 +761,7 @@
 	case SNDRV_RAWMIDI_IOCTL_DRAIN:
 	{
 		int val;
-		if (get_user(val, (long __user *) argp))
+		if (get_user(val, (int __user *) argp))
 			return -EFAULT;
 		switch (val) {
 		case SNDRV_RAWMIDI_STREAM_OUTPUT:
diff -Nru a/sound/oss/Kconfig b/sound/oss/Kconfig
--- a/sound/oss/Kconfig	2005-01-19 13:44:47 -08:00
+++ b/sound/oss/Kconfig	2005-01-19 13:44:47 -08:00
@@ -423,7 +423,7 @@
 	depends on MSNDPIN_NONPNP
 	default "0"
 	help
-	  Iinterrupt request number for the Kurzweil daughterboard
+	  Interrupt request number for the Kurzweil daughterboard
 	  synthesizer on MultiSound Pinnacle and Fiji sound cards.
 
 config MSNDPIN_IDE_IO0
@@ -1081,8 +1081,8 @@
 	depends on SOUND_PRIME!=n && PCI
 	help
 	  Say Y or M if you have a Hammerfall or Hammerfall light
-	  multichannel card from RME. If you want to acess advanced
-	  features of the card, read Documentation/sound/oss/rme96xx.
+	  multichannel card from RME. If you want to access advanced
+	  features of the card, read <file:Documentation/sound/oss/rme96xx>.
 
 config SOUND_AD1980
 	tristate "AD1980 front/back switch plugin"
diff -Nru a/sound/pci/Kconfig b/sound/pci/Kconfig
--- a/sound/pci/Kconfig	2005-01-19 13:44:46 -08:00
+++ b/sound/pci/Kconfig	2005-01-19 13:44:46 -08:00
@@ -54,7 +54,7 @@
 
 	  Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
           3D support code is in place, but not yet useable. For more info, 
-          email the ALSA developer list, or mjander@users.sourceforge.net.
+          email the ALSA developer list, or <mjander@users.sourceforge.net>.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-au8810.
@@ -68,7 +68,7 @@
 	  Say Y here to include support for Aureal Vortex soundcards.
 
           Supported features: Hardware Mixer and SRC. For more info, email 
-          the ALSA developer list, or mjander@users.sourceforge.net.
+          the ALSA developer list, or <mjander@users.sourceforge.net>.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-au8820.
@@ -83,7 +83,7 @@
 
           Supported features: Hardware Mixer, SRC, EQ and SPDIF output.
           3D support code is in place, but not yet useable. For more info, 
-          email the ALSA developer list, or mjander@users.sourceforge.net.
+          email the ALSA developer list, or <mjander@users.sourceforge.net>.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-au8830.
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	2005-01-19 13:44:48 -08:00
+++ b/sound/pci/ac97/ac97_codec.c	2005-01-19 13:44:48 -08:00
@@ -1505,7 +1505,7 @@
 	snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, ~AC97_GP_DRSS_MASK, 0x0000);
 
 	/* build 3D controls */
-	if (ac97->build_ops && ac97->build_ops->build_3d) {
+	if (ac97->build_ops->build_3d) {
 		ac97->build_ops->build_3d(ac97);
 	} else {
 		if (snd_ac97_try_volume_mix(ac97, AC97_3D_CONTROL)) {
@@ -1528,14 +1528,14 @@
 
 	/* build S/PDIF controls */
 	if (ac97->ext_id & AC97_EI_SPDIF) {
-		if (ac97->build_ops && ac97->build_ops->build_spdif) {
+		if (ac97->build_ops->build_spdif) {
 			if ((err = ac97->build_ops->build_spdif(ac97)) < 0)
 				return err;
 		} else {
 			for (idx = 0; idx < 5; idx++)
 				if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97))) < 0)
 					return err;
-			if (ac97->build_ops && ac97->build_ops->build_post_spdif) {
+			if (ac97->build_ops->build_post_spdif) {
 				if ((err = ac97->build_ops->build_post_spdif(ac97)) < 0)
 					return err;
 			}
@@ -1548,7 +1548,7 @@
 	}
 	
 	/* build chip specific controls */
-	if (ac97->build_ops && ac97->build_ops->build_specific)
+	if (ac97->build_ops->build_specific)
 		if ((err = ac97->build_ops->build_specific(ac97)) < 0)
 			return err;
 
@@ -1811,6 +1811,9 @@
 	return 0;
 }
 
+/* build_ops to do nothing */
+static struct snd_ac97_build_ops null_build_ops;
+
 /**
  * snd_ac97_mixer - create an Codec97 component
  * @bus: the AC97 bus which codec is attached to
@@ -2050,6 +2053,9 @@
 		bus->ops->init(ac97);
 	snd_ac97_get_name(ac97, ac97->id, name, !ac97_is_audio(ac97));
 	snd_ac97_get_name(NULL, ac97->id, name, !ac97_is_audio(ac97));  // ac97->id might be changed in the special setup code
+	if (! ac97->build_ops)
+		ac97->build_ops = &null_build_ops;
+
 	if (ac97_is_audio(ac97)) {
 		char comp[16];
 		if (card->mixername[0] == '\0') {
@@ -2157,6 +2163,8 @@
  */
 void snd_ac97_suspend(ac97_t *ac97)
 {
+	if (ac97->build_ops->suspend)
+		ac97->build_ops->suspend(ac97);
 	snd_ac97_powerdown(ac97);
 }
 
diff -Nru a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
--- a/sound/pci/ac97/ac97_patch.c	2005-01-19 13:44:47 -08:00
+++ b/sound/pci/ac97/ac97_patch.c	2005-01-19 13:44:47 -08:00
@@ -910,7 +910,7 @@
 
 static struct snd_ac97_build_ops patch_ad1881_build_ops = {
 #ifdef CONFIG_PM
-	.resume = &ad18xx_resume
+	.resume = ad18xx_resume
 #endif
 };
 
@@ -993,7 +993,7 @@
 static struct snd_ac97_build_ops patch_ad1885_build_ops = {
 	.build_specific = &patch_ad1885_specific,
 #ifdef CONFIG_PM
-	.resume = &ad18xx_resume
+	.resume = ad18xx_resume
 #endif
 };
 
@@ -1605,7 +1605,10 @@
 
 	/* adjust default values */
 	val = snd_ac97_read(ac97, 0x7a); /* misc control */
-	val |= (1 << 1); /* spdif input pin */
+	if (ac97->id == 0x414c4780) /* ALC658 */
+		val &= ~(1 << 1); /* Pin 47 is spdif input pin */
+	else /* ALC655 */
+		val |= (1 << 1); /* Pin 47 is spdif input pin */
 	val &= ~(1 << 12); /* vref enable */
 	snd_ac97_write_cache(ac97, 0x7a, val);
 	/* set default: spdif-in enabled,
diff -Nru a/sound/pci/atiixp.c b/sound/pci/atiixp.c
--- a/sound/pci/atiixp.c	2005-01-19 13:44:47 -08:00
+++ b/sound/pci/atiixp.c	2005-01-19 13:44:47 -08:00
@@ -43,6 +43,7 @@
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
 static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static char *ac97_quirk[SNDRV_CARDS];
 static int spdif_aclink[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 
 module_param_array(index, int, NULL, 0444);
@@ -53,6 +54,8 @@
 MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
 module_param_array(ac97_clock, int, NULL, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
+module_param_array(ac97_quirk, charp, NULL, 0444);
+MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
 module_param_array(spdif_aclink, bool, NULL, 0444);
 MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
 
@@ -630,21 +633,20 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
 	unsigned int curptr;
+	int timeout = 1000;
 
-	spin_lock(&chip->reg_lock);
-	curptr = readl(chip->remap_addr + dma->ops->dt_cur);
-	if (curptr < dma->buf_addr) {
-		snd_printdd("curptr = %x, base = %x\n", curptr, dma->buf_addr);
-		curptr = 0;
-	} else {
+	while (timeout--) {
+		curptr = readl(chip->remap_addr + dma->ops->dt_cur);
+		if (curptr < dma->buf_addr)
+			continue;
 		curptr -= dma->buf_addr;
-		if (curptr >= dma->buf_bytes) {
-			snd_printdd("curptr = %x, size = %x\n", curptr, dma->buf_bytes);
-			curptr = 0;
-		}
+		if (curptr >= dma->buf_bytes)
+			continue;
+		return bytes_to_frames(runtime, curptr);
 	}
-	spin_unlock(&chip->reg_lock);
-	return bytes_to_frames(runtime, curptr);
+	snd_printd("atiixp: invalid DMA pointer read 0x%x (buf=%x)\n",
+		   readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
+	return 0;
 }
 
 /*
@@ -1329,7 +1331,11 @@
  * ac97 mixer section
  */
 
-static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock)
+static struct ac97_quirk ac97_quirks[] __devinitdata = {
+	{ } /* terminator */
+};
+
+static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock, const char *quirk_override)
 {
 	ac97_bus_t *pbus;
 	ac97_template_t ac97;
@@ -1376,7 +1382,7 @@
 		return -ENODEV;
 	}
 
-	/* snd_ac97_tune_hardware(chip->ac97, ac97_quirks); */
+	snd_ac97_tune_hardware(chip->ac97[0], ac97_quirks, quirk_override);
 
 	return 0;
 }
@@ -1569,7 +1575,7 @@
 
 	chip->spdif_over_aclink = spdif_aclink[dev];
 
-	if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev])) < 0)
+	if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev], ac97_quirk[dev])) < 0)
 		goto __error;
 
 	if ((err = snd_atiixp_pcm_new(chip)) < 0)
diff -Nru a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
--- a/sound/pci/ca0106/ca0106_mixer.c	2005-01-19 13:44:47 -08:00
+++ b/sound/pci/ca0106/ca0106_mixer.c	2005-01-19 13:44:47 -08:00
@@ -1,4 +1,3 @@
-#define __NO_VERSION__
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
diff -Nru a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
--- a/sound/pci/ca0106/ca0106_proc.c	2005-01-19 13:44:46 -08:00
+++ b/sound/pci/ca0106/ca0106_proc.c	2005-01-19 13:44:46 -08:00
@@ -1,4 +1,3 @@
-#define __NO_VERSION__
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	2005-01-19 13:44:47 -08:00
+++ b/sound/pci/intel8x0.c	2005-01-19 13:44:47 -08:00
@@ -1766,10 +1766,22 @@
 		.name = "Dell",	/* which model?  AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
 	},
+	{
+		.vendor = 0x103c,
+		.device = 0x006d,
+		.name = "HP zv5000",
+		.type = AC97_TUNE_MUTE_LED	/*AD1981B*/
+	},
 	{	/* FIXME: which codec? */
 		.vendor = 0x103c,
 		.device = 0x00c3,
-		.name = "Hewlett-Packard onboard",
+		.name = "HP xw6000",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x129d,
+		.name = "HP xw8000",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
@@ -1782,6 +1794,12 @@
 		.vendor = 0x103c,
 		.device = 0x12f1,
 		.name = "HP xw8200",	/* AD1981B*/
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.vendor = 0x103c,
+		.device = 0x12f2,
+		.name = "HP xw6200",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
diff -Nru a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
--- a/sound/pci/mixart/mixart.c	2005-01-19 13:44:47 -08:00
+++ b/sound/pci/mixart/mixart.c	2005-01-19 13:44:47 -08:00
@@ -526,11 +526,11 @@
 		stream_param.sample_type = ST_INTEGER_24BE;
 		stream_param.sample_size = 24;
 		break;
-	case SNDRV_PCM_FMTBIT_FLOAT_LE:
+	case SNDRV_PCM_FORMAT_FLOAT_LE:
 		stream_param.sample_type = ST_FLOATING_POINT_32LE;
 		stream_param.sample_size = 32;
 		break;
-	case  SNDRV_PCM_FMTBIT_FLOAT_BE:
+	case  SNDRV_PCM_FORMAT_FLOAT_BE:
 		stream_param.sample_type = ST_FLOATING_POINT_32BE;
 		stream_param.sample_size = 32;
 		break;
diff -Nru a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c	2005-01-19 13:44:46 -08:00
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c	2005-01-19 13:44:46 -08:00
@@ -42,8 +42,6 @@
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable switches */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
@@ -51,11 +49,6 @@
 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-module_param(irq_mask, int, 0444);
-MODULE_PARM_DESC(irq_mask, "IRQ bitmask for " CARD_NAME " soundcard.");
-module_param_array(irq_list, int, NULL, 0444);
-MODULE_PARM_DESC(irq_list, "List of Available interrupts for " CARD_NAME " soundcard.");
- 
 
 /*
  */
@@ -164,12 +157,7 @@
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT | IRQ_FORCED_PULSE;
 	// link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID /* | IRQ_LEVEL_ID */;
-	if (irq_list[0] == -1)
-		link->irq.IRQInfo2 = irq_mask;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.IRQInfo1 = 0 /* | IRQ_LEVEL_ID */;
 	link->irq.Handler = pdacf_interrupt;
 	link->irq.Instance = pdacf;
 	link->conf.Attributes = CONF_ENABLE_IRQ;
diff -Nru a/sound/pcmcia/vx/vx_entry.c b/sound/pcmcia/vx/vx_entry.c
--- a/sound/pcmcia/vx/vx_entry.c	2005-01-19 13:44:45 -08:00
+++ b/sound/pcmcia/vx/vx_entry.c	2005-01-19 13:44:45 -08:00
@@ -157,12 +157,7 @@
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 	// link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-	if (hw->irq_list[0] == -1)
-		link->irq.IRQInfo2 = *hw->irq_mask_p;
-	else
-		for (i = 0; i < 4; i++)
-			link->irq.IRQInfo2 |= 1 << hw->irq_list[i];
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = &snd_vx_irq_handler;
 	link->irq.Instance = chip;
 
diff -Nru a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
--- a/sound/pcmcia/vx/vxpocket.c	2005-01-19 13:44:46 -08:00
+++ b/sound/pcmcia/vx/vxpocket.c	2005-01-19 13:44:46 -08:00
@@ -55,8 +55,6 @@
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable switches */
-static unsigned int irq_mask = 0xffff;
-static int irq_list[4] = { -1 };
 static int ibl[SNDRV_CARDS];
 
 module_param_array(index, int, NULL, 0444);
@@ -65,10 +63,6 @@
 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
-module_param(irq_mask, int, 0444);
-MODULE_PARM_DESC(irq_mask, "IRQ bitmask for " CARD_NAME " soundcard.");
-module_param_array(irq_list, int, NULL, 0444);
-MODULE_PARM_DESC(irq_list, "List of Available interrupts for " CARD_NAME " soundcard.");
 module_param_array(ibl, int, NULL, 0444);
 MODULE_PARM_DESC(ibl, "Capture IBL size for " CARD_NAME " soundcard.");
  
@@ -123,8 +117,6 @@
 	.index_table = index,
 	.id_table = id,
 	.enable_table = enable,
-	.irq_mask_p = &irq_mask,
-	.irq_list = irq_list,
 	.ibl = ibl,
 
 	/* h/w config */
diff -Nru a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h
--- a/sound/pcmcia/vx/vxpocket.h	2005-01-19 13:44:46 -08:00
+++ b/sound/pcmcia/vx/vxpocket.h	2005-01-19 13:44:46 -08:00
@@ -35,8 +35,6 @@
 	int *index_table;
 	char **id_table;
 	int *enable_table;
-	unsigned int *irq_mask_p;
-	int *irq_list;
 	int *ibl;
 
 	/* h/w config */
