# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	v2.6.0-test9 -> 1.1437 
#	drivers/net/8139too.c	1.74    -> 1.75   
#	arch/sparc64/kernel/entry.S	1.29    -> 1.30   
#	net/core/link_watch.c	1.6     -> 1.7    
#	include/asm-x86_64/irq.h	1.3     -> 1.4    
#	net/irda/ircomm/ircomm_core.c	1.13    -> 1.14   
#	include/asm-x86_64/smp.h	1.12    -> 1.13   
#	drivers/scsi/sata_sil.c	1.1     -> 1.2    
#	drivers/scsi/libata-core.c	1.1     -> 1.6    
#	drivers/block/as-iosched.c	1.27    -> 1.28   
#	    net/llc/af_llc.c	1.51    -> 1.58   
#	arch/x86_64/mm/fault.c	1.15    -> 1.16   
#	include/asm-sparc64/pgtable.h	1.31    -> 1.32   
#	arch/arm/kernel/signal.c	1.24    -> 1.25   
#	drivers/pci/quirks.c	1.36    -> 1.38   
#	drivers/net/tulip/de4x5.c	1.32    -> 1.33   
#	include/linux/libata.h	1.1     -> 1.3    
#	     net/core/flow.c	1.15    -> 1.16   
#	 drivers/net/3c509.c	1.43    -> 1.44   
#	   fs/cramfs/inode.c	1.33    -> 1.34   
#	drivers/char/agp/sis-agp.c	1.32    -> 1.33   
#	Documentation/networking/irda.txt	1.1     -> 1.2    
#	drivers/ide/pci/amd74xx.h	1.8     -> 1.10   
#	         net/Kconfig	1.26    -> 1.28   
#	arch/i386/mach-visws/visws_apic.c	1.9     -> 1.10   
#	net/ipv6/ip6_output.c	1.44    -> 1.46   
#	  net/llc/llc_conn.c	1.38    -> 1.39   
#	net/ipv6/ip6_tunnel.c	1.12    -> 1.14   
#	include/linux/times.h	1.4     -> 1.5    
#	include/asm-sparc/unistd.h	1.26    -> 1.27   
#	net/ipv6/sysctl_net_ipv6.c	1.7     -> 1.8    
#	include/asm-sparc/namei.h	1.1     -> 1.2    
#	  net/llc/llc_proc.c	1.18    -> 1.21   
#	include/linux/sched.h	1.173   -> 1.175  
#	 drivers/net/Space.c	1.42    -> 1.43   
#	drivers/block/ll_rw_blk.c	1.219   -> 1.221  
#	arch/i386/kernel/vm86.c	1.26    -> 1.27   
#	drivers/net/wireless/airo.c	1.77    -> 1.79   
#	drivers/media/video/bttv-if.c	1.16    -> 1.17   
#	   include/net/tcp.h	1.51    -> 1.52   
#	  drivers/net/tlan.c	1.29    -> 1.30   
#	net/ipv4/netfilter/ip_nat_core.c	1.34    -> 1.35   
#	arch/x86_64/kernel/x8664_ksyms.c	1.18    -> 1.20   
#	    fs/jbd/journal.c	1.67    -> 1.68   
#	      net/ipv4/udp.c	1.53    -> 1.55   
#	    net/ipx/af_ipx.c	1.44    -> 1.45   
#	include/asm-sparc64/unistd.h	1.25    -> 1.26   
#	drivers/scsi/sata_via.c	1.1     -> 1.2    
#	arch/alpha/kernel/setup.c	1.38    -> 1.39   
#	include/linux/signal.h	1.13    -> 1.14   
#	drivers/scsi/libata.h	1.1     -> 1.2    
#	include/asm-ia64/sn/nodepda.h	1.10    -> 1.11   
#	include/asm-sparc64/spinlock.h	1.7     -> 1.8    
#	include/linux/serial.h	1.9     -> 1.10   
#	arch/x86_64/kernel/acpi/boot.c	1.6     -> 1.7    
#	net/ipv6/xfrm6_policy.c	1.13    -> 1.14   
#	include/linux/blkdev.h	1.127   -> 1.128  
#	drivers/input/mouse/psmouse-base.c	1.34    -> 1.36   
#	 include/linux/udp.h	1.7     -> 1.8    
#	drivers/serial/serial_core.c	1.72    -> 1.74   
#	drivers/net/ethertap.c	1.10    -> 1.11   
#	include/asm-sparc64/namei.h	1.1     -> 1.2    
#	net/irda/discovery.c	1.6     -> 1.7    
#	drivers/net/starfire.c	1.31    -> 1.33   
#	arch/x86_64/kernel/smp.c	1.17    -> 1.18   
#	include/linux/preempt.h	1.6     -> 1.7    
#	fs/jfs/jfs_metapage.c	1.24    -> 1.25   
#	arch/i386/mm/ioremap.c	1.19    -> 1.20   
#	drivers/usb/storage/usb.c	1.77    -> 1.78   
#	drivers/acpi/pci_root.c	1.16    -> 1.17   
#	      net/ipv4/tcp.c	1.49    -> 1.50   
#	drivers/net/pcnet32.c	1.42    -> 1.43   
#	net/ipv6/netfilter/ip6_queue.c	1.12    -> 1.13   
#	    net/irda/iriap.c	1.17    -> 1.18   
#	arch/x86_64/kernel/setup64.c	1.17    -> 1.18   
#	arch/ia64/sn/io/machvec/pci_dma.c	1.16    -> 1.17   
#	  include/linux/ip.h	1.10    -> 1.11   
#	     net/ipv6/icmp.c	1.43    -> 1.45   
#	include/asm-ia64/pgtable.h	1.30    -> 1.32   
#	fs/jbd/transaction.c	1.76    -> 1.77   
#	net/irda/ircomm/ircomm_tty.c	1.28    -> 1.29   
#	  net/irda/af_irda.c	1.46    -> 1.47   
#	arch/h8300/kernel/time.c	1.3     -> 1.4    
#	 net/ipv4/tcp_ipv4.c	1.72    -> 1.77   
#	       fs/char_dev.c	1.26    -> 1.27   
#	drivers/ide/ide-tape.c	1.29    -> 1.31   
#	net/ipv4/netfilter/ipt_REDIRECT.c	1.6     -> 1.7    
#	        mm/filemap.c	1.211   -> 1.212  
#	        net/socket.c	1.69    -> 1.70   
#	arch/x86_64/kernel/entry.S	1.13    -> 1.15   
#	drivers/ide/pci/alim15x3.c	1.15    -> 1.18   
#	    fs/binfmt_misc.c	1.22    -> 1.23   
#	net/core/sysctl_net_core.c	1.7     -> 1.8    
#	arch/i386/mach-voyager/voyager_smp.c	1.16    -> 1.17   
#	    fs/ext2/balloc.c	1.29    -> 1.30   
#	       fs/nfsd/vfs.c	1.70    -> 1.71   
#	     kernel/signal.c	1.98    -> 1.100  
#	include/asm-sparc/pcic.h	1.1     -> 1.2    
#	include/linux/pci_ids.h	1.123   -> 1.126  
#	include/asm-x86_64/pci.h	1.11    -> 1.12   
#	         lib/div64.c	1.2     -> 1.3    
#	   drivers/net/b44.c	1.13    -> 1.14   
#	drivers/media/video/tuner-3036.c	1.10    -> 1.11   
#	arch/sparc64/kernel/systbls.S	1.48    -> 1.49   
#	drivers/net/sis900.c	1.46    -> 1.47   
#	arch/x86_64/kernel/pci-gart.c	1.22    -> 1.23   
#	arch/sparc64/lib/rwlock.S	1.1     -> 1.2    
#	      fs/fat/inode.c	1.80    -> 1.81   
#	         mm/memory.c	1.140   -> 1.141  
#	 include/linux/llc.h	1.3     -> 1.4    
#	arch/i386/kernel/signal.c	1.32    -> 1.33   
#	            fs/aio.c	1.37    -> 1.38   
#	drivers/usb/serial/digi_acceleport.c	1.40    -> 1.41   
#	arch/sparc/kernel/entry.S	1.16    -> 1.17   
#	 drivers/ide/Kconfig	1.30    -> 1.31   
#	drivers/net/8139cp.c	1.57    -> 1.58   
#	arch/sparc64/kernel/rtrap.S	1.16    -> 1.17   
#	drivers/media/video/bttv-cards.c	1.22    -> 1.23   
#	drivers/scsi/ata_piix.c	1.1     -> 1.2    
#	     net/ipv4/ipmr.c	1.32    -> 1.34   
#	arch/sparc64/lib/dec_and_lock.S	1.4     -> 1.5    
#	net/netlink/af_netlink.c	1.36    -> 1.37   
#	arch/sparc/kernel/systbls.S	1.24    -> 1.25   
#	  net/ipv6/ipcomp6.c	1.7     -> 1.8    
#	      net/core/dev.c	1.120   -> 1.124  
#	arch/x86_64/kernel/io_apic.c	1.16    -> 1.17   
#	net/xfrm/xfrm_policy.c	1.41    -> 1.43   
#	kernel/posix-timers.c	1.21    -> 1.23   
#	 drivers/net/r8169.c	1.15    -> 1.16   
#	    fs/minix/inode.c	1.38    -> 1.39   
#	drivers/net/pcmcia/ibmtr_cs.c	1.19    -> 1.20   
#	net/bridge/netfilter/ebt_limit.c	1.1     -> 1.2    
#	drivers/media/video/meye.h	1.10    -> 1.11   
#	drivers/usb/net/usbnet.c	1.76    -> 1.77   
#	  drivers/md/raid1.c	1.72    -> 1.73   
#	   drivers/acpi/ec.c	1.26    -> 1.27   
#	drivers/pnp/isapnp/core.c	1.43    -> 1.45   
#	include/linux/sysctl.h	1.52    -> 1.53   
#	   drivers/net/tg3.c	1.108   -> 1.111  
#	 net/ipv6/tcp_ipv6.c	1.74    -> 1.75   
#	 drivers/net/3c527.c	1.16    -> 1.17   
#	      fs/direct-io.c	1.34    -> 1.35   
#	arch/ia64/kernel/signal.c	1.35    -> 1.36   
#	drivers/char/sonypi.h	1.18    -> 1.19   
#	drivers/net/arm/ether1.c	1.15    -> 1.16   
#	         MAINTAINERS	1.176   -> 1.179  
#	drivers/scsi/sata_svw.c	1.1     -> 1.2    
#	    net/irda/irttp.c	1.19    -> 1.21   
#	drivers/pcmcia/yenta_socket.c	1.49    -> 1.50   
#	        net/compat.c	1.11    -> 1.12   
#	fs/partitions/msdos.c	1.20    -> 1.21   
#	drivers/net/tokenring/ibmtr.c	1.18    -> 1.19   
#	drivers/usb/host/ehci-hcd.c	1.60    -> 1.61   
#	drivers/net/pcmcia/fmvj18x_cs.c	1.26    -> 1.27   
#	          fs/dquot.c	1.67    -> 1.68   
#	arch/x86_64/kernel/time.c	1.25    -> 1.26   
#	      net/ipv6/ah6.c	1.24    -> 1.25   
#	include/asm-x86_64/topology.h	1.5     -> 1.6    
#	include/linux/ipv6.h	1.12    -> 1.14   
#	  arch/ia64/mm/tlb.c	1.19    -> 1.20   
#	drivers/scsi/sata_promise.c	1.1     -> 1.12   
#	include/asm-sparc64/hardirq.h	1.16    -> 1.17   
#	drivers/scsi/constants.c	1.13    -> 1.14   
#	include/asm-x86_64/checksum.h	1.4     -> 1.5    
#	net/ipv4/netfilter/arpt_mangle.c	1.2     -> 1.3    
#	drivers/usb/net/kaweth.c	1.51    -> 1.52   
#	     kernel/module.c	1.94    -> 1.95   
#	   net/core/skbuff.c	1.31    -> 1.33   
#	net/xfrm/xfrm_state.c	1.35    -> 1.36   
#	drivers/usb/serial/Kconfig	1.10    -> 1.11   
#	arch/ia64/kernel/perfmon_mckinley.h	1.9     -> 1.10   
#	     net/core/sock.c	1.28    -> 1.29   
#	net/irda/irnet/irnet_ppp.c	1.14    -> 1.15   
#	drivers/media/video/bt832.c	1.3     -> 1.4    
#	include/asm-sparc/bitext.h	1.1     -> 1.2    
#	   net/ipv4/ip_gre.c	1.33    -> 1.34   
#	net/ipv4/tcp_input.c	1.46    -> 1.47   
#	Documentation/video4linux/meye.txt	1.7     -> 1.8    
#	    net/ipv6/route.c	1.58    -> 1.60   
#	drivers/media/video/saa5249.c	1.19    -> 1.20   
#	net/ipv4/tcp_minisocks.c	1.42    -> 1.43   
#	include/asm-sparc/ioctl.h	1.2     -> 1.3    
#	      fs/jfs/namei.c	1.34    -> 1.35   
#	include/asm-i386/checksum.h	1.8     -> 1.9    
#	   net/llc/llc_sap.c	1.30    -> 1.31   
#	include/linux/socket.h	1.9     -> 1.10   
#	      kernel/sched.c	1.222   -> 1.224  
#	 sound/oss/ali5455.c	1.7     -> 1.8    
#	net/ipv4/netfilter/ip_fw_compat_masq.c	1.11    -> 1.12   
#	drivers/input/keyboard/atkbd.c	1.38    -> 1.39   
#	 net/llc/llc_input.c	1.33    -> 1.34   
#	      net/ipv6/udp.c	1.50    -> 1.53   
#	net/ipv4/netfilter/Kconfig	1.16    -> 1.17   
#	arch/x86_64/mm/numa.c	1.6     -> 1.7    
#	arch/sparc64/kernel/sparc64_ksyms.c	1.59    -> 1.60   
#	drivers/acpi/dispatcher/dsopcode.c	1.21    -> 1.22   
#	      kernel/timer.c	1.72    -> 1.73   
#	include/asm-sparc64/ioctl.h	1.2     -> 1.3    
#	    net/ipv6/mcast.c	1.39    -> 1.40   
#	      net/ipv4/arp.c	1.33    -> 1.34   
#	   net/ipv4/ipcomp.c	1.16    -> 1.17   
#	drivers/pci/setup-res.c	1.21    -> 1.22   
#	drivers/net/arm/etherh.c	1.17    -> 1.18   
#	arch/sparc64/Kconfig	1.38    -> 1.39   
#	arch/ia64/kernel/irq.c	1.30    -> 1.31   
#	       kernel/exit.c	1.117   -> 1.119  
#	      net/ipv4/ah4.c	1.27    -> 1.28   
#	drivers/scsi/Kconfig	1.42    -> 1.43   
#	    net/irda/irlmp.c	1.30    -> 1.33   
#	net/ipv4/ipvs/ip_vs_conn.c	1.11    -> 1.12   
#	include/asm-h8300/smplock.h	1.1     ->         (deleted)      
#	arch/x86_64/mm/extable.c	1.5     -> 1.6    
#	drivers/net/bonding/bond_main.c	1.46    -> 1.47   
#	    net/irda/irlap.c	1.27    -> 1.28   
#	arch/ia64/kernel/perfmon.c	1.65    -> 1.67   
#	 net/ipv6/addrconf.c	1.71    -> 1.76   
#	include/linux/netdevice.h	1.64    -> 1.66   
#	net/decnet/dn_route.c	1.18    -> 1.19   
#	        crypto/api.c	1.30    -> 1.31   
#	net/ipv4/ipvs/ip_vs_xmit.c	1.4     -> 1.5    
#	include/net/if_inet6.h	1.9     -> 1.10   
#	drivers/video/radeonfb.c	1.30    -> 1.31   
#	include/asm-x86_64/hw_irq.h	1.6     -> 1.7    
#	drivers/pci/setup-bus.c	1.22    -> 1.23   
#	include/asm-x86_64/processor.h	1.24    -> 1.25   
#	drivers/net/arm/ether3.c	1.18    -> 1.19   
#	drivers/md/dm-table.c	1.24    -> 1.25   
#	arch/x86_64/mm/k8topology.c	1.5     -> 1.6    
#	    net/ipv4/route.c	1.73    -> 1.75   
#	drivers/base/class.c	1.41    -> 1.42   
#	include/asm-sparc64/floppy.h	1.9     -> 1.10   
#	 net/appletalk/ddp.c	1.37    -> 1.40   
#	 arch/i386/pci/irq.c	1.29    -> 1.30   
#	drivers/ide/pci/amd74xx.c	1.21    -> 1.23   
#	  include/linux/in.h	1.7     -> 1.8    
#	drivers/scsi/osst_options.h	1.2     -> 1.3    
#	include/asm-x86_64/desc.h	1.12    -> 1.13   
#	net/ipv4/netfilter/ip_queue.c	1.14    -> 1.15   
#	arch/ppc/kernel/vmlinux.lds.S	1.24    -> 1.25   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/10/25	torvalds@home.osdl.org	1.1350.1.2
# Linux 2.6.0-test9
# --------------------------------------------
# 03/10/26	Andries.Brouwer@cwi.nl	1.1350.1.3
# [PATCH] atkbd: 0xfa is ACK
# 
# The 0xfa code can be a key scancode or it can be a protocol scancode.
# 
# Only few keyboards use it as a key scancode, and if we always interpret
# it as a protocol scancode then these rare keyboards will have a dead
# key.  If we interpret it as a key scancode then we have a dead keyboard
# in case it was protocol.
# 
# Clearly it is safer to prefer to interpret it as a protocol scancode.
# 
# This moves the test for ACK and NAK up, so that they are always seen as
# protocol.
# 
# This is just a minimal patch.  What I did in 1.1.54 was to keep track of
# commands sent with a flag reply_expected, so that 0xfa could be taken as
# ACK when a reply is expected and as key scancode otherwise.  That is the
# better solution, but requires larger surgery.
# --------------------------------------------
# 03/10/26	Andries.Brouwer@cwi.nl	1.1350.1.4
# [PATCH] Relax FATFS validity tests
# 
# The first FAT entry should have the media byte (0xf0,0xf8,...,0xff)
# extended with all 1 bits in the first FAT entry.
# 
# Checking this is a good idea, it prevents us from mounting garbage
# as FAT - there is no good magic for FAT.
# 
# Unfortunately, Windows does not enforce this, and 2.4 doesn't either.
# It turns out that there are filesystems around (two reports so far) that
# have a zero first FAT entry, and work under Windows and 2.4 but fail to
# mount under 2.6.
# 
# So, this weakens the test.
# --------------------------------------------
# 03/10/26	stelian@popies.net	1.1350.1.5
# [PATCH] sonypi: fix Zoom/Thumbphrase button events
# 
# This corrects the Zoom and Thumbphrase button events.
# --------------------------------------------
# 03/10/26	stelian@popies.net	1.1350.1.6
# [PATCH] meye: documentation
# 
# This documents the existence of a forth 'motioneye' camera plugged into
# the USB bus, of course unsupported by the meye driver.
# --------------------------------------------
# 03/10/26	ak@muc.de	1.1350.1.7
# [PATCH] Essential x86-64 updates
# 
# The most important part is that it makes x86-64 compile again.
# Without that 2.6 users won't be very happy.
# 
# It also works around a bug that allowed every user program to reboot the
# system on B stepping K8.
# 
# Also update to match some recent i386 fixes.
# 
# Full ChangeLog:
#  - Add acpi_pic_set_level_irq to make ACPI compile again
#  - Work around compat mode K8 bug in IRET exception handling
#  - Increase exception stack. The old 1k stack was too easy
#    to overflow (from Jim Paradis, changed by me)
#  - Replace safe_smp_processor_id with cpuid (needed for above)
#  - When there is only one node always enable fake_node mode
#  - Merge with i386 (NTP gettimeofday monoticity fix, irq nr_vectors change)
#  - Fix compile problem for UP kernels in time/cpufreq
#  - Set all nodes online at bootup
#  - Define node_to_cpumask correctly
# --------------------------------------------
# 03/10/26	ysato@users.sourceforge.jp	1.1350.1.8
# [PATCH] fix h8/300 support
# 
#  - add 'sched_clock'
#  - delete smplock.h
# --------------------------------------------
# 03/10/26	tausq@debian.org	1.1350.1.9
# [PATCH] fix __div64_32 to do division properly
# 
# This fixes the generic __div64_32() to correctly handle divisions by
# large 32-bit values (as used by nanosleep() and friends, for example).
# 
# It's a simple bit-at-a-time implementation with a reduction of the high
# 32-bits handled manually.  Architectures that can do 64/32-bit divisions
# in hardware should implement their own more efficient versions.
# --------------------------------------------
# 03/10/26	torvalds@home.osdl.org	1.1350.1.10
# Add a sticky "PF_DEAD" task flag to keep track of dead processes.
# 
# Use this to simplify 'finish_task_switch', but perhaps more
# importantly we can use this to track down why some processes
# seem to sometimes not die properly even after having been
# marked as ZOMBIE. The "task->state" flags are too fluid to 
# allow that well.
# --------------------------------------------
# 03/10/27	matthias.andree@gmx.de	1.1350.2.1
# Properly terminate /proc/tty/driver/serial output lines of known UARTS
# when the caller has no CAP_SYS_ADMIN capability.
# --------------------------------------------
# 03/10/26	davem@nuts.ninka.net	1.1353
# Merge nuts.ninka.net:/disk1/davem/BK/network-2.5
# into nuts.ninka.net:/disk1/davem/BK/net-2.5
# --------------------------------------------
# 03/10/26	davem@nuts.ninka.net	1.1350.1.11
# Merge nuts.ninka.net:/disk1/davem/BK/sparcwork-2.5
# into nuts.ninka.net:/disk1/davem/BK/sparc-2.5
# --------------------------------------------
# 03/10/26	levon@movementarian.org	1.1354
# [NETFILTER]: Fix modular iptables build.
# --------------------------------------------
# 03/10/26	ak@muc.de	1.1355
# [NET]: Fix oops in ethertap_rx().
# --------------------------------------------
# 03/10/26	yoshfuji@linux-ipv6.org	1.1356
# [IPV6]: Typo in address comparison.
# --------------------------------------------
# 03/10/26	yoshfuji@linux-ipv6.org	1.1357
# [IPV6]: Use real storage for cork'd packets, else MSG_MORE corrupts UDP packets.
# --------------------------------------------
# 03/10/26	yoshfuji@linux-ipv6.org	1.1358
# [IPV4,6]: Use common storage for cork'd flow, needed to handle mapped-ipv4 ipv6 addresses properly.
# --------------------------------------------
# 03/10/27	yoshfuji@linux-ipv6.org	1.1359
# [IPV6]: Process ipv4-mapped addresses properly on UDPv6 sockets.
# --------------------------------------------
# 03/10/27	rusty@rustcorp.com.au	1.1360
# [NETFILTER]: Fix ipchains oops in NAT
# 
# We updated ip_nat_setup_info to set the initialized flag and call
# place_in_hashes, but *didn't* change the call in ip_fw_compat_masq.c
# which also calls place_in_hashes() itself (again!).  Result: corrupt
# list, and next thing which lands in the same hash bucket goes boom.
# 
# Thanks to Andy Polyakov for chasing this down.
# --------------------------------------------
# 03/10/27	yoshfuji@linux-ipv6.org	1.1361
# [IPV6]: Fix bogus semicolon typo in mcast.c
# --------------------------------------------
# 03/10/27	bdschuym@pandora.be	1.1362
# [NETFILTER]: Fix potential OOPS in ipt_REDIRECT.
# --------------------------------------------
# 03/10/27	davem@nuts.ninka.net	1.1363
# Revert signal handling changes in tcp.c - they break SIGURG.
# 
# Cset exclude: kuznet@ms2.inr.ac.ru|ChangeSet|20031021052951|52463
# --------------------------------------------
# 03/10/27	davem@nuts.ninka.net	1.1364
# Revert "Zero initial timestamps are valid" changeset.
# 
# I am still not sure that this change all by itself is enough
# to make us accept zero initial timestamps properly. 
# 
# Cset exclude: davem@nuts.ninka.net|ChangeSet|20031025060257|60993
# --------------------------------------------
# 03/10/27	davem@nuts.ninka.net	1.1365
# [IPV6]: Do not virt_to_page() on stack addresses, fixes OOPS.
# --------------------------------------------
# 03/10/27	herbert@gondor.apana.org.au	1.1366
# [IPSEC]: Fix accidental too many ref drops on policies.
# --------------------------------------------
# 03/10/27	matthias.andree@gmx.de	1.1350.3.1
# Merge bk://linux.bkbits.net/linux-2.5/
# into gmx.de:/suse/kernel/BK/linux-2.5
# --------------------------------------------
# 03/10/27	torvalds@home.osdl.org	1.1350.4.1
# Put the compiler barrier() on the right side of the preemption
# enable on UP-PREEMPT.
# 
# Without this, the enable could "migrate" up into the critical
# region (on SMP, the actual spinlock would act as an additional
# barrier and PREEMPT was ok).
# --------------------------------------------
# 03/10/27	kevcorry@us.ibm.com	1.1350.4.2
# [PATCH] Fix DM on top of raid
# 
# Force Device-Mapper to use PAGE_SIZE or smaller I/O when the underlying
# device has a bvec_merge_fn routine registered.  This will fix the
# situation of Device-Mapper submitting I/Os to RAID-0 that span the
# RAID-0 chunk boundaries.
# 
# Joe is working on a better solution that actually honors the MD
# merge_bvec_fn routine.  But this minimal change will fix the problem for
# the time being.
# --------------------------------------------
# 03/10/27	torvalds@home.osdl.org	1.1367
# Merge bk://kernel.bkbits.net/davem/net-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/27	torvalds@home.osdl.org	1.1368
# Merge bk://kernel.bkbits.net/davem/sparc-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/27	eranian@hpl.hp.com	1.1337.43.18
# [PATCH] ia64: fix perfmon UP breakage
# 
# --------------------------------------------
# 03/10/27	davidm@tiger.hpl.hp.com	1.1350.5.1
# Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.6.0-test9
# into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5
# --------------------------------------------
# 03/10/27	torvalds@home.osdl.org	1.1369
# Fix ZOMBIE race with self-reaping threads.
# 
# exit_notify() used to leave a window open when a thread
# died that made the thread visible as a ZOMBIE even though
# the thread reaped itself. This closes that window by marking
# the thread DEAD within the tasklist_lock.
# --------------------------------------------
# 03/10/27	torvalds@home.osdl.org	1.1370
# Don't force PS/2 mouse rate or resolution by default.
# 
# Only set the rate/resolution if the user actually asked
# for it. Some mice and KVM switches don't like to have
# their rate forced.
# --------------------------------------------
# 03/10/27	akpm@osdl.org	1.1371
# [PATCH] Fix binfmt_misc locking
# 
# This fixes a sleep-in-spinlock bug for binfmt_misc registration.
# 
# That lock is purely for the list, not for the dentry.
# --------------------------------------------
# 03/10/27	rmk@flint.arm.linux.org.uk	1.1350.6.1
# [PCMCIA] Fix card detection.
# 
# Idea from David Hinds.
# 
# Some PCMCIA/Cardbus controllers seem to get upset when we ask
# them to re-do card interrogation - they miss the next insertion
# event.
# 
# We therefore avoid forcing needless card interrogations if a
# card has already been succesfully detected and interrogated.
# --------------------------------------------
# 03/10/27	eranian@hpl.hp.com	1.1350.5.2
# [PATCH] ia64: fix 2 more perfmon2 bugs
# 
# Here is the minimal patch that fixes things that do not work and that
# can be noticed fairly easily:
# 
#         - remove a typo in pfm_check_task_state() which causes
#           PFM_READ_PMDS to fail when context is in  PFM_MASKED state.
# 
#         - fix a typo in perfmon_mcklinley.h when checking the value
#           combinations for when writing to PMC14. This could reject a
#           valid request to program PMC14.
# --------------------------------------------
# 03/10/28	acme@conectiva.com.br	1.1372
# [LLC]: Fix array indexing in llc_add_pack().
# --------------------------------------------
# 03/10/28	acme@conectiva.com.br	1.1373
# [LLC]: In llc_ui_connect(), return error properly when device not found.
# --------------------------------------------
# 03/10/28	pee@erkkila.org	1.1374
# [IPV4]: Make sure ipgre_tunnel_init() gets the correct ioctl settings.
# --------------------------------------------
# 03/10/28	andrew@com.rmk.(none)	1.1350.7.1
# [SERIAL PATCH] 1672/1: Restore sizeof(struct serial_struct)
# 
# Patch from SAN People
# 
# Patch 2.4.21-rmk1 added a "iomap_base" field to the serial_struct
# structure (include/linux/serial.h).
# 
# Since that structure is exported to user-space it should be
# consistent between revisions of the stable 2.4 kernels.
# 
# This patch removes 4 bytes (were "reserved") to restore the size
# of the structure.
# 
# Without this patch, ioctl(TIOCGSERIAL) will copy_to_user() 4
# bytes more than expected and possibly corrupt the application's
# stack/heap.
# --------------------------------------------
# 03/10/28	davem@nuts.ninka.net	1.1371.1.1
# [SPARC]: Add AIO syscalls, 32-bit compat handling will come later.
# --------------------------------------------
# 03/10/28	davem@nuts.ninka.net	1.1371.1.2
# [SPARC64]: Fix preempt handling in dec_and_lock.S
# --------------------------------------------
# 03/10/28	yoshfuji@linux-ipv6.org	1.1375
# [IPV6]: Fix inappropriate usage of inet{,6}_sk().
# --------------------------------------------
# 03/10/28	yoshfuji@linux-ipv6.org	1.1376
# [IPV4]: Remove out-of-date info CONFIG_INET help text.
# --------------------------------------------
# 03/10/28	matthias.andree@gmx.de	1.1371.2.1
# Merge bk://linux.bkbits.net/linux-2.5/
# into gmx.de:/suse/kernel/BK/linux-2.5
# --------------------------------------------
# 03/10/28	wrlk@riede.org	1.1371.3.1
# [PATCH] osst buglet
# 
# Fixes a "Bad page state at destroy_compound_page" error.
# --------------------------------------------
# 03/10/28	Andries.Brouwer@cwi.nl	1.1371.3.2
# [PATCH] Strange SCSI messages
# 
# In SCSI messages, sdsdd should have been sdd.
# That is, these days error printing is a bit broken.
# --------------------------------------------
# 03/10/28	yoshfuji@linux-ipv6.org	1.1377
# [IPV6]: Fix outdated and inaccurate information in Kconfig help.
# --------------------------------------------
# 03/10/28	jgarzik@redhat.com	1.1337.1.34
# [libata] Add paranoia checks/settings suggested by Promise
# --------------------------------------------
# 03/10/28	davem@nuts.ninka.net	1.1371.1.3
# [SPARC64]: Get preempt building and working again.
# 
# - HAVE_DEC_LOCK depends on SMP
# - Trap return preemption check needs interrupt disabled check
# - Implement write_trylock
# - Fix in_atomic() definition when PREEMPT enabled
# --------------------------------------------
# 03/10/28	kml@patheticgeek.net	1.1378
# [TCP]: When SYN is set, the window is not scaled.
# --------------------------------------------
# 03/10/28	Jay.Estabrook@hp.com	1.1371.4.1
# [PATCH] Fix alpha "white box" boot
# 
# Here's a show-stopper patch for Alpha; missing it prevents several of
# our platforms ("white box" 3000 and 5000 series) from booting.
# --------------------------------------------
# 03/10/28	len.brown@intel.com	1.1371.5.1
# [ACPI] REVERT acpi_ec_gpe_query(ec) fix that crashed non-T40 boxes
# http://bugme.osdl.org/show_bug.cgi?id=1171
# --------------------------------------------
# 03/10/29	matthias.andree@gmx.de	1.1371.2.2
# Merge bk://linux.bkbits.net/linux-2.5/
# into gmx.de:/suse/kernel/BK/linux-2.5
# --------------------------------------------
# 03/10/28	len.brown@intel.com	1.1371.5.2
# [ACPI] REVERT ACPICA-20030918 CONFIG_ACPI_DEBUG printk that caused crash
# http://bugzilla.kernel.org/show_bug.cgi?id=1341
# --------------------------------------------
# 03/10/28	torvalds@home.osdl.org	1.1371.1.4
# Merge bk://kernel.bkbits.net/davem/sparc-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/28	torvalds@home.osdl.org	1.1379
# Merge bk://kernel.bkbits.net/davem/net-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/28	torvalds@home.osdl.org	1.1380
# Merge http://lia64.bkbits.net/to-linus-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/28	davem@nuts.ninka.net	1.1381
# [NET/COMPAT]: Fix copying of ipt_entry objects in do_netfilter_replace().
# 
# As noted by Georg Chini, ipt_entry object are of variable size
# so just copying individual struct ipt_entry slots around does
# not work.
# --------------------------------------------
# 03/10/28	janitor@sternwelten.at	1.1382
# [NETFILTER]: Add IPCHAINS to MAINTAINERS entry.
# --------------------------------------------
# 03/10/28	acme@conectiva.com.br	1.1383
# [LLC]: Fix oops in procf handling.
# --------------------------------------------
# 03/10/29	rmk@flint.arm.linux.org.uk	1.1380.1.1
# Merge flint.arm.linux.org.uk:/usr/src/bk/linux-2.6
# into flint.arm.linux.org.uk:/usr/src/bk/linux-2.6-serial
# --------------------------------------------
# 03/10/29	rmk@flint.arm.linux.org.uk	1.1380.1.2
# Merge bk://129.217.163.1/linux-2.5/
# into flint.arm.linux.org.uk:/usr/src/bk/linux-2.6-serial
# --------------------------------------------
# 03/10/29	phillim2@comcast.net	1.1380.2.1
# [PATCH] ibmtr_cs/ibmtr - get working again
# 
# Patch to get ibmtr_cs / ibmtr working again.  A change went in a while back
# I missed that killed it.  Also fixed the timer to eliminate the
# uninitialized timer error on close.
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.2
# [PATCH] digi_accelport warning fix
# 
# Use the correct type for the workqueue callback.
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.3
# [PATCH] JBD: use-after-free fix
# 
# The wait_event() in there can touch the memory at *transaction after
# kjournald has freed it.
# 
# Rework the code to not wait until the transaction enters T_FLUSH state: just
# loop back and try against after the wakeup.
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.4
# [PATCH] WinTV-D patch to make tuner functional
# 
# From: "Brad House" <brad_mssw@gentoo.org>
# 
# Quick patch to enable the Philips tuner on the WinTV-D boards.  Tested and
# works fine.  (acked by Gerd)
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.5
# [PATCH] bttv jiffies warning fix
# 
# Use unsigned long for time_after(), not an int.
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.6
# [PATCH] Export some symbols on x86-64
# 
# From: Andi Kleen <ak@muc.de>
# 
# Export two symbols on x86-64.  This is needed for the sk98lin driver and ipv6.
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.7
# [PATCH] /proc/tty/driver/serial formatting fix
# 
# From: Matthias Andree <matthias.andree@gmx.de>
# 
# Properly terminate /proc/tty/driver/serial output lines of known UARTS
# when the caller has no CAP_SYS_ADMIN capability.
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.8
# [PATCH] direct-io typo fix
# 
# From: Klaas de Waal <klaas.de.waal@hccnet.nl>
# 
# Bug in parameter of ZERO_PAGE macro in line 679 of fb/direct-io.c Parameter
# dio->cur_user_address has to be dio->curr_user_address.  This bug shows
# when compling for MIPS little endian as target, not when compiling for X86.
# --------------------------------------------
# 03/10/29	torvalds@home.osdl.org	1.1380.2.9
# Merge http://linux-acpi.bkbits.net/linux-acpi-release-2.6.0
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.10
# [PATCH] sis900 skb free fix
# 
# This driver is freeing skb's from timer context, with local irq's disabled.
# 
# It generates warnings from local_bh_enable() because local_bh_enable()
# reenables interrupts, exposing the machine to deadlocks.
# 
# So use the deferred dev_kfree_skb_irq() instead.
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.11
# [PATCH] initcall ordering fix for PNP NICs
# 
# From: "M.H.VanLeeuwen" <vanl@megsinet.net>
# 
# The level of isapnp_init was moved to after apci sometime ago.  Since it is
# now after net_dev_init, ISA PNP NICs fail to initialized at boot.  This is
# particularily problematic for NFS root filesystems like mine, or none
# modular systems.
# 
# This fix allows ISA PNP NIC cards to work during net_dev_init, and still
# leaves isapnp_init after apci_init.
# --------------------------------------------
# 03/10/29	acme@conectiva.com.br	1.1384
# [LLC]: llc_lookup_listener has to consider the 'any' mac address
# --------------------------------------------
# 03/10/29	acme@conectiva.com.br	1.1385
# [LLC]: fix net_device refcounting bug
# --------------------------------------------
# 03/10/29	acme@conectiva.com.br	1.1386
# [LLC]: fix bug that prevented fcntl(O_NONBLOCK) from working with PF_LLC sockets
# --------------------------------------------
# 03/10/29	arjanv@redhat.com	1.1380.2.12
# [PATCH] r8169 module license tag
# --------------------------------------------
# 03/10/29	acme@conectiva.com.br	1.1387
# [LLC]: set local mac addr at connect time when userland left it as zeroes
# --------------------------------------------
# 03/10/29	tsk@ibakou.com	1.1380.2.13
# [netdrvr 8139too] add pci id
# --------------------------------------------
# 03/10/29	riel@surriel.com	1.1380.2.14
# [netdrvr starfire] include asm/io.h
# 
# Fixes build on some platforms.
# --------------------------------------------
# 03/10/29	achirica@telefonica.net	1.1380.2.15
# [PATCH] Fix compatibily issue with some APs
# --------------------------------------------
# 03/10/29	rmk@arm.linux.org.uk	1.1380.2.16
# [PATCH] 2.6.0-test8: fix ARM ether driver naming
# 
# Ensure that arm ether drivers print the correct ether device name rather
# than "eth%d".
# --------------------------------------------
# 03/10/29	komujun@nifty.com	1.1380.2.17
# [pcmcia fmvj18x_cs] share interrupts properly for TDK multifunction cards.
# --------------------------------------------
# 03/10/29	amir.noam@intel.com	1.1380.2.18
# [netdrvr bonding] fix monitoring functions
# 
# This fix got missed in the bonding patchset applied a while ago.
# --------------------------------------------
# 03/10/29	kolya@mit.edu	1.1388
# [NET]: Allow SOMAXCONN to be adjusted via sysctl.
# --------------------------------------------
# 03/10/29	acme@conectiva.com.br	1.1389
# [NET]: Introduce dev_getbyfirsthwtype.
# --------------------------------------------
# 03/10/29	acme@conectiva.com.br	1.1390
# [LLC]: when the user doesn't specifies a local address to connect, do an autobind
# 
# Other protocols do this as soon as they discover over what interface the
# packet will be routed, but LLC isn't routable, so, to provide similar
# semantics to the other protocols, I'm just binding it to the first interface
# of the type specified, perhaps we'll need a tunable for this or some sort of
# routing table done manually by the admin, later we'll see, for now this
# allows an application like openssh, with patched getaddrinfo/getnameinfo to
# use PF_LLC sockets with a very small patch.
# --------------------------------------------
# 03/10/29	ebrower@usa.net	1.1380.3.1
# [SPARC]: Fix _IOC_SIZE() macro when direction is _IOC_NONE.
# --------------------------------------------
# 03/10/29	arjanv@redhat.com	1.1380.2.19
# [PATCH] fix starfire 64-bit b0rkage
# 
# (x >> 32) is undefined on a 32 bit integral variable in C; In contrast
# (x >>16 >> 16) is fine (and gets optimized out to 0, while (x >> 32)
# gets optimized out to a nop). 
# 
# Fix for starfire below
# --------------------------------------------
# 03/10/29	achirica@telefonica.net	1.1380.2.20
# [PATCH] Fix wireless stats locking
# --------------------------------------------
# 03/10/29	akpm@osdl.org	1.1380.2.21
# [netdrvr 3c527] add MODULE_LICENSE tag
# --------------------------------------------
# 03/10/29	torvalds@home.osdl.org	1.1380.2.22
# Merge bk://bk.arm.linux.org.uk/linux-2.6-pcmcia
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/29	torvalds@home.osdl.org	1.1380.1.3
# Merge bk://bk.arm.linux.org.uk/linux-2.6-serial
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/29	shaggy@shaggy.austin.ibm.com	1.1380.4.1
# JFS: remove racy, redundant call to block_invalidatepage
# 
# __invalidate_metapages references mp->page after after releasing the
# meta_lock spinlock, without increasing the use count.  This is racy and
# unnecessary since setting the META_discard flag is sufficient.
# block_invalidatepage() will be called when the metapage is released.
# --------------------------------------------
# 03/10/29	davem@nuts.ninka.net	1.1391
# [NET]: Make skb_copy_expand() copy header area too.
# --------------------------------------------
# 03/10/29	torvalds@home.osdl.org	1.1380.1.4
# Merge http://jfs.bkbits.net/linux-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/29	ink@jurassic.park.msu.ru	1.1380.5.1
# [PATCH] PCI: fix bug in pci_setup_bridge()
# 
# This bug prevents Alphas with older firmware from booting if there
# is a card with PCI-PCI bridge that supports 32-bit IO.
# This has happened on AS2100 with a quad-tulip card, for example:
#  - initially, the I/O window of 21152 bridge was 0x10000-0x10fff,
#    as set up by firmware;
#  - pci_setup_bridge() is going to change this, say, to 0xa000-0xafff:
#    first, it updates PCI_IO_BASE_UPPER16 and PCI_IO_LIMIT_UPPER16
#    registers, so that IO window temporarily is at 0x0000-0x0fff,
#    which effectively blocks up all legacy IO ports in the lower
#    4K range, such as serial, floppy, RTC an so on;
#    does debugging printk - machine dies here with recursive
#    machine checks as the serial console has gone.
# 
# Moving (or disabling) the debugging printk is not a solution -
# there is possibility that timer interrupt (which might access RTC
# ports) occurs between writes to lower and upper parts of the
# base/limit registers.
# 
# The patch temporarily disables the IO window of the bridge by
# setting PCI_IO_BASE_UPPER16 > PCI_IO_LIMIT_UPPER16 before doing
# an update. It's safe, as we don't have any active IO behind
# the bridge at this point. Also, it's a NOP for bridges with
# 16-bit-only IO.
# Similar (but simpler, as we always clear upper 32 bits) fix
# for 64-bit prefetchable MMIO range.
# --------------------------------------------
# 03/10/29	greg@kroah.com	1.1380.5.2
# [PATCH] I2C: remove some MOD_INC and MOD_DEC usages that are not needed anymore.
# --------------------------------------------
# 03/10/29	greg@kroah.com	1.1380.5.3
# [PATCH] USB: don't build the whiteheat driver if on SMP as the locking is all messed up.
# --------------------------------------------
# 03/10/29	torvalds@home.osdl.org	1.1380.1.5
# Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.6
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/29	rusty@rustcorp.com.au	1.1380.1.6
# [PATCH] Fix for module initialization failure
# 
# Bug reported by Paul Mackerras: if a module parameter fails, we didn't
# call module_arch_cleanup().
# 
# On x86 this was harmless (module_arch_cleanup() is a no-op), but on
# other architectures like PPC this causes inconsistent data structures
# and subsequent oopses.
# --------------------------------------------
# 03/10/30	shaggy@shaggy.austin.ibm.com	1.1380.4.2
# JFS: Fix race between link() and unlink()
# 
# JFS isn't happy it thinks a file has been removed, and link() increases
# its nlink count back from zero.  In 2.4, i_zombie prevented this race
# condition.
# 
# http://bugzilla.kernel.org/show_bug.cgi?id=866
# --------------------------------------------
# 03/10/30	torvalds@home.osdl.org	1.1380.1.7
# Merge http://jfs.bkbits.net/linux-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/30	yoshfuji@linux-ipv6.org	1.1392
# [CRYPTO]: crypto_alg_lookup() should fail when passed a NULL name.
# --------------------------------------------
# 03/10/30	herbert@gondor.apana.org.au	1.1393
# [IPSEC]: Missing NULL algorithm checks in AH and IPCOMP init.
# --------------------------------------------
# 03/10/30	acme@conectiva.com.br	1.1394
# [LLC]: Fix sockaddr, only need to provide one MAC address not three.
# --------------------------------------------
# 03/10/30	davem@kernel.bkbits.net	1.1380.6.1
# Merge davem@nuts.ninka.net:/disk1/davem/BK/sparc-2.5
# into kernel.bkbits.net:/home/davem/sparc-2.5
# --------------------------------------------
# 03/10/30	davem@nuts.ninka.net	1.1395
# Merge nuts.ninka.net:/disk1/davem/BK/network-2.5
# into nuts.ninka.net:/disk1/davem/BK/net-2.5
# --------------------------------------------
# 03/10/30	torvalds@home.osdl.org	1.1380.1.8
# Merge bk://kernel.bkbits.net/davem/sparc-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/30	torvalds@home.osdl.org	1.1380.1.9
# Stop SIS 96x chips from lying about themselves.
# 
# Some machines with the SIS 96x southbridge have it set up
# to claim it is a SIS 503 chip. That breaks irq routing logic
# among other things. Fix it properly by making everybody aware
# of the duplicity.
# --------------------------------------------
# 03/10/30	torvalds@home.osdl.org	1.1396
# Merge bk://kernel.bkbits.net/davem/net-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/30	zaitcev@redhat.com	1.1380.3.2
# [SPARC]: Eliminate references to linux/smp_lock.h, from willy.
# --------------------------------------------
# 03/10/30	davem@nuts.ninka.net	1.1397
# Merge nuts.ninka.net:/disk1/davem/BK/sparcwork-2.5
# into nuts.ninka.net:/disk1/davem/BK/sparc-2.5
# --------------------------------------------
# 03/10/30	shemminger@osdl.org	1.1396.1.1
# [IPX]: Fix OOPS when ipxcfg_auto_create_interfaces is on.
# --------------------------------------------
# 03/10/30	jejb@raven.il.steeleye.com	1.1371.3.3
# Buslogic is MCA capable as well as PCI and ISA
# --------------------------------------------
# 03/10/30	acme@conectiva.com.br	1.1396.1.2
# [IPX]: Memset newly allocated atalk private area.
# --------------------------------------------
# 03/10/30	davem@nuts.ninka.net	1.1396.1.3
# [IPX]: Fix checksum computation.
# --------------------------------------------
# 03/10/30	acme@conectiva.com.br	1.1396.1.4
# [IPX]: Missing memset()'s in route and interface creation.
# --------------------------------------------
# 03/10/31	philipc@snapgear.com	1.1396.2.1
# [netdrvr 8139cp] fix NAPI race
# 
# Cures reported lockups.
# --------------------------------------------
# 03/10/31	jgarzik@redhat.com	1.1337.1.35
# [libata] fix bugs in SATA reset code path
# --------------------------------------------
# 03/10/31	jgarzik@redhat.com	1.1337.1.36
# [libata] add Promise SATA pci id
# --------------------------------------------
# 03/10/31	torvalds@home.osdl.org	1.1396.2.2
# Merge bk://kernel.bkbits.net/jgarzik/libata-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/31	torvalds@home.osdl.org	1.1396.2.3
# Merge bk://linux-scsi.bkbits.net/scsi-bugfixes-2.6
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/31	torvalds@home.osdl.org	1.1396.1.5
# Merge bk://kernel.bkbits.net/davem/net-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/10/31	acme@conectiva.com.br	1.1396.1.6
# [APPLETALK]: Mark me as the maintainer.
# --------------------------------------------
# 03/11/01	B.Zolnierkiewicz@elka.pw.edu.pl	1.1396.3.1
# [PATCH] add support for new nForce IDE controllers
# 
# Original 2.4.23-pre4 patch by Allen Martin <AMartin@nvidia.com>.
# 
# This does not add any new code, it only adds new PCI ID's and related
# info to the existing driver.
# --------------------------------------------
# 03/11/01	B.Zolnierkiewicz@elka.pw.edu.pl	1.1396.3.2
# [PATCH] AMD/nForce driver update
# 
# From Vojtech Pavlik <vojtech@suse.cz>.
# 
# Change AMD8111 and nForce2 max speed to UDMA133.
# 
# Add workaround for Serenade mainboards which only handle UDMA100.
# 
# Fix printing of chipset name.
# 
# Fix some whitspace issues.
# --------------------------------------------
# 03/11/01	torvalds@home.osdl.org	1.1396.3.3
# Forward-port PIRQ table updates from 2.4.x
# 
# This separates out the PIRQ table parsing to vendor-specific
# code, which allows us to handle specific vendor quirks. In
# particular, SiS has a really funky notion of what PCI device
# ID's are meant to be.
# 
# Some hardware designers seem to be hitting the recreational
# drugs a bit too heavily. Tssk, tssk.
# 
# The Sis96x irq routing update is confirmed to fix at least
# one laptop.
# --------------------------------------------
# 03/11/01	davem@nuts.ninka.net	1.1396.1.7
# Merge nuts.ninka.net:/disk1/davem/BK/network-2.5
# into nuts.ninka.net:/disk1/davem/BK/net-2.5
# --------------------------------------------
# 03/11/01	davem@nuts.ninka.net	1.1396.1.8
# Cset exclude: akpm@osdl.org|ChangeSet|20031029192849|64746
# --------------------------------------------
# 03/11/01	yoshfuji@linux-ipv6.org	1.1396.1.9
# [IPV4/IPV6]: Fix one more inappropriate use of inet6_sk()->ipv6only
# --------------------------------------------
# 03/11/01	acme@conectiva.com.br	1.1396.1.10
# [LLC]: fix procfs reading when there are saps without sockets
# --------------------------------------------
# 03/11/01	acme@conectiva.com.br	1.1396.1.11
# [LLC]: fix client side after sockaddr_llc fixup
# --------------------------------------------
# 03/11/02	thomas@winischhofer.net	1.1396.3.4
# [PATCH] More SiS AGP ids
# 
# This extends the agppart table with three new SiS chipsets that must be
# handled as the other ones.  No actual code changes.
# --------------------------------------------
# 03/11/02	torvalds@home.osdl.org	1.1396.3.5
# Avoid user space access with interrupts disabled in vm86 support.
# 
# Getting a signal while in vm86 caused warnings because we still had
# interrupts disabled - for no good reason. Enable interrupts before
# accessing user space.
# --------------------------------------------
# 03/11/03	torvalds@home.osdl.org	1.1396.3.6
# Only truncate file types that can be truncated on minixfs.
# 
# Only regular files, directories and symbolic links can have any
# blocks allocated to them - other types of files have different
# metadata in their inodes and should not get to the truncation
# paths. Enforce this in fs/minix/inode.c.
# 
# Without this, deleting a block or character device can cause
# minix filesystem corruption. Noted by Konstantin Boldyshev.
# --------------------------------------------
# 03/11/03	davem@nuts.ninka.net	1.1396.1.12
# Merge nuts.ninka.net:/disk1/davem/BK/network-2.5
# into nuts.ninka.net:/disk1/davem/BK/net-2.5
# --------------------------------------------
# 03/11/03	ajm@sgi.com	1.1350.5.3
# [PATCH] ia64: fix bug in SN2 sn_pci_map_sg that causes MCA
# 
# If sg->dma_address is set, we try to do a __pa() on a dma_address,
# then, later, create a dma_addresss from a munged dma_address.  When
# this bogus dma_address is used by the card, it results in MCAs.
# --------------------------------------------
# 03/11/03	ralf@linux-mips.org	1.1396.1.13
# [PATCH] drivers/pci DEBUG build fix
# 
# Trivial build fix for the debug code in drivers PCI.  Seems like nobody
# has had to use this code in a long time.
# --------------------------------------------
# 03/11/03	davem@nuts.ninka.net	1.1398
# Merge nuts.ninka.net:/disk1/davem/BK/sparcwork-2.5
# into nuts.ninka.net:/disk1/davem/BK/sparc-2.5
# --------------------------------------------
# 03/11/03	kochi@hpc.bs1.fc.nec.co.jp	1.1350.5.4
# [PATCH] ia64: don't access per-CPU data of off-line CPUs
# 
# This patch prevents a crash that happens when per-CPU data is allocated
# only for CPUs that are online.
# --------------------------------------------
# 03/11/03	ambx1@neo.rr.com	1.1396.1.14
# [PATCH] Fix ISAPNP netdev initialization
# 
# Moving isapnp further down in the bus initialization obviously sparked
# some new problems.
# 
# Instead, remove the legacy netdev probing function from dev.c and give
# it its own initcall later in the cycle.
# --------------------------------------------
# 03/11/04	torvalds@home.osdl.org	1.1396.1.15
# Merge http://lia64.bkbits.net/to-linus-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/04	B.Zolnierkiewicz@elka.pw.edu.pl	1.1396.1.16
# [PATCH] fix ide-tape oops
# 
# Set filp->private_data in idetape_chrdev_open() to point to a opened drive,
# otherwise driver oopses during future access to tape character device.
# 
# Thanks to Stef van der Made <svdmade@planet.nl> for testing ide-tape fixes.
# --------------------------------------------
# 03/11/04	B.Zolnierkiewicz@elka.pw.edu.pl	1.1396.1.17
# [PATCH] fix rq->flags use in ide-tape.c
# 
# Noticed by Stuart_Hayes@Dell.com:
# 
# I've noticed that, in the 2.6 (test 9) kernel, the "cmd" field (of type int)
# in struct request has been removed, and it looks like all of the code in
# ide-tape has just had a find & replace run on it to replace any instance of
# rq.cmd or rq->cmd with rq.flags or rq->flags.
# 
# The values being put into "cmd" in 2.4 (now "flags", in 2.6) by ide-tape are
# 8-bit numbers, like 90, 91, etc... and the actual flags that are being used
# in "flags" cover the low 23 bits.  So, not only do the flags get wiped out
# when, say, ide-tape assigns, say, 90 to "flags", but also the 90 gets wiped
# out when one of the flags is modified.
# 
# I noticed this, because ide-tape checks this value, and spews error codes
# when it isn't correct--continuously--as soon as you load the module, because
# ide-tape is calling ide_do_drive_cmd with an action of ide_preempt, which
# causes ide_do_drive_cmd to set the REQ_PREEMPT flag, so "flags" isn't the
# same when it gets back to idetape_do_request.
# --------------------------------------------
# 03/11/04	tommy@home.tig-grr.com	1.1396.1.18
# [EBTABLES]: Fix ebt_limit for HZ=1000
# --------------------------------------------
# 03/11/04	rusty@rustcorp.com.au	1.1396.1.19
# [NETFILTER]: get_unique_tuple doesn't always return unique tuple.
# 
# get_unique_tuple doesn't check that the tuple is unique if it finds
# a hash_by_src match.
# --------------------------------------------
# 03/11/04	laforge@netfilter.org	1.1396.1.20
# [NETFILTER]: Fix ip_queue_maxlen sysctl.
# --------------------------------------------
# 03/11/04	davem@nuts.ninka.net	1.1396.1.21
# [NETLINK]: Initialize nl_pad in getname and recvmsg, noticed by Uli Drepper.
# --------------------------------------------
# 03/11/04	shemminger@osdl.org	1.1396.1.22
# [IRDA]: Fix irlmp seqfile, initialize the iterator in start.
# --------------------------------------------
# 03/11/04	davem@nuts.ninka.net	1.1396.1.23
# [IPV4]: Initialize ARP seqfile state in start() method.
# --------------------------------------------
# 03/11/04	jt@bougret.hpl.hp.com	1.1396.1.24
# [IRDA]: Fix SKB leaks in af_irda.c, from Arnaldo Carvalho de Melo.
# --------------------------------------------
# 03/11/04	rddunlap@osdl.org	1.1396.4.1
# [PATCH] Fix crash-on-boot in init_l440gx SMP
# 
# ioremap_nocache() doesn't need to check for physical address
# wraps because __ioremap() has already done that;
# fix calculation of npages to handle non-aligned phys_addr;
# --------------------------------------------
# 03/11/04	davem@nuts.ninka.net	1.1399
# [SPARC64]: Preserve cache/side-effect PTE bits in pte_modify().
# 
# Bug noticed by Russell King.
# --------------------------------------------
# 03/11/04	davem@kernel.bkbits.net	1.1400
# Merge davem@nuts.ninka.net:/disk1/davem/BK/sparc-2.5
# into kernel.bkbits.net:/home/davem/sparc-2.5
# --------------------------------------------
# 03/11/04	davem@kernel.bkbits.net	1.1396.1.25
# Merge davem@nuts.ninka.net:/disk1/davem/BK/net-2.5
# into kernel.bkbits.net:/home/davem/net-2.5
# --------------------------------------------
# 03/11/04	torvalds@home.osdl.org	1.1401
# Merge bk://kernel.bkbits.net/davem/net-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/05	willy@debian.org	1.1402
# [PATCH] Fix panic-at-boot
# 
# This fixes a panic-at-boot when ACPI Hotplug PCI is compiled in, but
# ACPI is disabled.  It just makes sure that the list is properly
# initialized statically instead of depending on runtime initialization
# that may or may not happen.
# --------------------------------------------
# 03/11/05	yoshfuji@linux-ipv6.org	1.1403
# [IPV6]: Fix OOPS on NETDEV_CHANGENAME events.
# --------------------------------------------
# 03/11/05	jt@bougret.hpl.hp.com	1.1404
# [IRDA]: Fix two OOPSers in IrCOMM
# - Do not do copy_from_user() under spinlock
# - Always access self->skb under spinlock
# 
# Original patch from Martin Diehl.
# --------------------------------------------
# 03/11/05	jt@bougret.hpl.hp.com	1.1405
# [IRDA]: Fix races between IRNET and PPP.
# - Prevent sending status event to dead/kfree sockets
# - Disable PPP access before deregistration
#   PPP deregistration might sleep -> race condition
# --------------------------------------------
# 03/11/05	jt@bougret.hpl.hp.com	1.1406
# [IRDA]: Fix IrLMP open leak.
# - Prevent 'self' leak on error in irlmp_open.
#   ASSERT is compiled in only with DEBUG option => risk = 0.
# 
# Original patch from Chris Wright.
# --------------------------------------------
# 03/11/05	shep@alum.mit.edu	1.1407
# [IPV6]: Fix /proc/sys/net/ipv6/icmp permissions.
# --------------------------------------------
# 03/11/05	vnuorval@tcs.hut.fi	1.1408
# [IPV6]: In ip6ip6 tunnel, set skb->h.raw after obtaining private copy.
# --------------------------------------------
# 03/11/05	vnuorval@tcs.hut.fi	1.1409
# [IPV6]: In ip6ip6 tunnel, user provides flowlabel in network byte order.
# --------------------------------------------
# 03/11/05	davem@nuts.ninka.net	1.1410
# [IRDA]: Fix IRQ save/restore handling in seq file handlers.
# 
# IRDA was restoring IRQ flags in a different function from which they
# were saved which explodes on certain platforms.  It did not need to
# use _irq{save,restore}() anyways since the seqfile layer always invokes
# these routines from user context with interrupts enabled, so using
# plain spin_{lock,unlock}_irq() works just fine.
# --------------------------------------------
# 03/11/05	davem@nuts.ninka.net	1.1402.1.1
# [TG3]: Fix bugs in ETHTOOL_SSET introduced by ethtool_ops conversion.
# - Missing spin_lock*() calls before tp->link_config twiddling.
# - Missing assignment to tp->link_config.autoneg
# --------------------------------------------
# 03/11/05	davem@nuts.ninka.net	1.1402.1.2
# [TG3]: Bump driver version and release date.
# --------------------------------------------
# 03/11/05	torvalds@home.osdl.org	1.1411
# Merge bk://kernel.bkbits.net/davem/tg3-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/06	torvalds@home.osdl.org	1.1412
# Fix cut-and-paste error in radeonfb.c
# 
# From Ronald Lembcke.
# --------------------------------------------
# 03/11/06	pazke@donpac.ru	1.1413
# [PATCH] fix visws irq breakage
# 
# This fixes visws subarch which was broken by asm-i386/hw_irq.h changes
# --------------------------------------------
# 03/11/06	axboe@suse.de	1.1414
# [PATCH] fix segment accounting with bounced pages
# 
# There's a problem with bio segment accounting for pages that reside
# above the bounce limit of a queue. When submitted, they may be
# considered part of another segment. A condition that changes when the
# page gets bounced. This can cause us to send bio's that have too many
# segments to a driver.
# 
# The best fix is to always consider pages above q->bounce_pfn as seperate
# segments. That's the conservative approach and the easy fix.
# 
# Problem identified and fixed by Herbert Xu.
# --------------------------------------------
# 03/11/06	jgarzik@redhat.com	1.1415
# [libata] fix ugly Promise interrupt masking bug
# --------------------------------------------
# 03/11/06	jgarzik@redhat.com	1.1416
# [libata] bump libata version
# --------------------------------------------
# 03/11/06	jack@suse.cz	1.1414.1.1
# [PATCH] Drop spin lock when calling request_module in quota code
# 
# From Herbert Xu
# --------------------------------------------
# 03/11/06	kaber@trash.net	1.1414.1.2
# [NET]: Fix skb_copy_expand offset calculation.
# --------------------------------------------
# 03/11/06	krkumar@us.ibm.com	1.1414.1.3
# [NET]: Do not run netdev todo work from linkwatch code.
# --------------------------------------------
# 03/11/07	viro@parcelfarce.linux.theplanet.co.uk	1.1414.1.4
# [PATCH] Fix cramfs metadata races
# 
# There's a few places that use incorrect exclusion for the cramfs raw
# data access buffers.  The proper lock is "read_mutex" (and BKL does
# nothing).
# 
#  - fix mount-time read and block number initialization without the mutex
#    held. 
#  - cramfs_readdir() needs to copy the name and inode information into a
#    separate buffer since it can't hold the semaphore over the
#    (potentially blocking) user mode access
#  - cramfs_lookup() needs to hold the access lock over the whole
#    function, not just the read itself
#  - use generic_file_llseek on directories to get i_sem exclusion on
#    readdir/lseek
# --------------------------------------------
# 03/11/07	michael@metaparadigm.com	1.1414.2.1
# [PATCH] PCI: Fix oops in quirk_via_bridge
# 
# I have a VIA cardbus 1394 controller which oops on insertion
# after an APM suspend/resume cycle (without card inserted):
# 
# bounds: 0000 [#1]
# CPU:    0
# EIP:    0060:[<c0300060>]    Tainted: PF
# EFLAGS: 00010206
# EIP is at quirk_via_bridge+0x4/0x1c
# eax: 0000ffff   ebx: c02982e0   ecx: d1958000   edx: 000c0010
# esi: d1958000   edi: 00000001   ebp: 00000000   esp: da401ee8
# ds: 007b   es: 007b   ss: 0068
# Process pccardd (pid: 1093, threadinfo=da400000 task=da4c8780)
# Stack: c019fb85 d1958000 00000001 d1958000 00000000 c019fbc2 d1958000 00000001
#          c02980a0 d1958000 dfdebf14 c019d828 00000001 d1958000 00000000 dec2802c
#          dfdebf00 dfdebf14 00000000 e3dfe7c7 dfdebf00 00000000 dec2802c da401f48
# Call Trace:
#    [<c019fb85>] pci_do_fixups+0x52/0x54
#    [<c019fbc2>] pci_fixup_device+0x3b/0x49
#    [<c019d828>] pci_scan_slot+0x46/0x8f
#    [<e3dfe7c7>] cb_alloc+0x29/0xf7 [pcmcia_core]
#    [<e3dfb9aa>] socket_insert+0x90/0x102 [pcmcia_core]
#    [<e3dfbc0d>] socket_detect_change+0x54/0x7e [pcmcia_core]
#    [<e3dfbdbc>] pccardd+0x185/0x1f9 [pcmcia_core]
# 
# quirk_via_bridge (which is marked device PCI_ANY_ID) triggers on
# my 1394 controller which vendor=VIA but is not a bridge.
# 
# Making the quirk __devinit solves the problem.
# --------------------------------------------
# 03/11/07	mdharm-usb@one-eyed-alien.net	1.1414.2.2
# [PATCH] USB: fix a thread-exit problem at module unload
# 
# This patch fixes a thread-exit problem when the usb-storage module is
# unloaded with a preemptable kernel.  Please refer to the comments in the
# code for more detail.
# --------------------------------------------
# 03/11/07	david-b@pacbell.net	1.1414.2.3
# [PATCH] USB: usb ignores 64bit dma
# 
# The dma hooks whereby EHCI can pass 64bit DMA support
# up the driver stack (to avoid buffer copies) turn out
# to broken on most architectures(*).  This patch just
# disables them all, since it looks like those mechanisms
# won't get fixed before 2.6.0-final.  For now it'd only
# matter on a few big Intel boxes anyway.
# 
# Please merge.
# 
# - Dave
# 
# (*) On x86, mips, and arm dma_supported() doesn't
#      even compare with the device's mask.  On several
#      other architectures (reported on ppc, alpha,
#      and sparc64), asking that question for non-PCI
#      devices will just BUG() -- even though all info
#      needed to answer the question is right at hand.
# --------------------------------------------
# 03/11/07	torvalds@home.osdl.org	1.1414.1.5
# Merge bk://linuxusb.bkbits.net/gregkh-2.6
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/07	jgarzik@redhat.com	1.1417
# [libata] fix Promise PCI posting bugs
# --------------------------------------------
# 03/11/07	ak@muc.de	1.1414.1.6
# [PATCH] Fix IP checksum for SuSE 9.0 compiler
# 
# The hammer branch based gcc 3.3 in SuSE 9.0 has a more aggressive
# optimizer. ip_send_check has this code:
# 
# 	iph->check = 0;
# 	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
# 
# The new gcc optimizes the first store away because it doesn't know
# that ip_fast_csum reads its input memory. This leads to occassionally
# packets with wrong IP header checksum getting sent; this happens especially
# with NFS. Fixing it in the constraints would have been ugly and probably
# not future proof, so this patch just adds a memory clobber to ip_fast_csum.
# 
# For some reason the issue only hits in 2.6, we haven't seen it in 2.4.
# Problem occurs on both i386 and x86-64.
# 
# Credit goes to Olaf Kirch for tracking this down.
# --------------------------------------------
# 03/11/07	greg@kroah.com	1.1414.1.7
# [PATCH] fix reference count bug with class devices
# 
# When a kobject is associated with a kset, the kset MUST be set before
# the kobject is initialized (by either a call to kobject_register() or
# kobject_init()).  This patch fixes the class code which improperly set
# the kset after the kobject was initialized, which would cause improper
# reference counts on the kset.
# 
# Thanks to Mike Anderson for locating the source of this bug.
# --------------------------------------------
# 03/11/08	pp@ee.oulu.fi	1.1414.3.1
# [netdrvr b44] Fix irq enable/disable; fix oops due to lack of SET_NETDEV_DEV() call
# 
# Also, add suspend/resume functions.
# --------------------------------------------
# 03/11/08	ralf@linux-mips.org	1.1414.3.2
# [netdrvr pcnet32] add missing pci_dma_sync_single
# 
# a patch for the pcnet32.c driver which adds a missing call to
# pci_dma_sync_single.  If a received packet is smaller than rx_copybreak
# the pcnet driver will recycle the receive buffer which requires calling
# pci_dma_sync_single.  Patch is against 2.6 but I it's also needed in 2.4.
# 
# Without that call the processor might still have old stale data in
# the data cache when the processor accesses the recycled buffer.
# 
# --------------------------------------------
# 03/11/08	torvalds@home.osdl.org	1.1414.1.8
# Don't fold nanosleep() into clock_nanosleep().
# 
# The latter has buggy restart functionality and is a lot
# more complicated anyway.
# --------------------------------------------
# 03/11/08	ak@muc.de	1.1414.1.9
# [PATCH] Fix TSS limit on x86-64
# 
# The limit of the TSS segment was incorrectly set to a too big value
# on x86-64. This lead to the CPU reading random memory behind the main
# TSS when iopl was >0, but there was no ioperm bitmap set. This caused
# random failures in port accesses in this state.
# 
# Set the correct limit.
# --------------------------------------------
# 03/11/08	ak@muc.de	1.1414.1.10
# [PATCH] Fix oops in x86-64 strace path
# 
# Fix a nasty typo found by Albert Cahalan.
# 
# This lead to an oops when a invalid syscall was called under strace in 2.6.
# --------------------------------------------
# 03/11/08	mingo@elte.hu	1.1414.1.11
# [PATCH] SMP signal latency fix
# 
# The code that sends a signal needs to "kick" the target process if it
# runs on another CPU and wasn't woken up by the signal to let it know
# that it has a new event.
# 
# Otherwise it might take a long time until the target actually notices
# and acts on the signal.
# --------------------------------------------
# 03/11/08	davem@nuts.ninka.net	1.1414.4.1
# [TCP]: Normalize jiffies values reported to userspace.
# --------------------------------------------
# 03/11/08	herbert@gondor.apana.org.au	1.1414.4.2
# [NET]: Use cpumask_t for cpumap in flow cache.
# --------------------------------------------
# 03/11/08	krkumar@us.ibm.com	1.1414.4.3
# [IPV6]: Fix hangs during interface down caused by ipv6_del_addr().
# 
# While using PRIVACY extensions, I sometimes get a hang when I remove the
# interface. But I can reproduce this every time using the test script at
# the end of the mail (hang depends on the order of address deletion).
# 
# The bug is in ipv6_del_addr() where if a temp address is being deleted, it
# does an __in6_ifa_put() of the main address from which it was derived
# (basically the autoconf prefix address). So if the main address was
# deleted first, it's ifp ref count would be 1 and it would 'wait' to be
# freed till it's temp address was freed first. When the temp address is
# deleted, the __put() routine drops the main address's ifp ref count to 0,
# but not free it. unregister_netdevice() hangs giving message that ref
# count is 1. Fix tested overnight.
# 
# Also, the code at the top of the routine is unnecessary, the same is being
# done when the address is found a little later in that routine.
# --------------------------------------------
# 03/11/08	davem@hera.kernel.org	1.1414.1.12
# Merge davem@nuts.ninka.net:/disk1/davem/BK/net-2.5
# into hera.kernel.org:/home/davem/BK/net-2.5
# --------------------------------------------
# 03/11/09	ak@muc.de	1.1414.1.13
# [PATCH] Fix critical issue in x86-64 IOMMU code
# 
# The K8 IOMMU code had some broken BUG_ON()s that hit with <4K aligned IO
# through the IOMMU.
# 
# This patch fixes this. Without this database raw IO is often broken.
# --------------------------------------------
# 03/11/09	vojtech@suse.cz	1.1414.1.14
# [PATCH] input: Always reset PS/2 mouse resolution and update speed to
# default values after probing
# 
# This sets the mouse to 100 samples/second, 200 dpi, 1:1 mapping, which
# is a standard setting, as close to 2.4 XFree86 behavior as possible, and
# a good performance setting, too. 
# 
# It also in the case of 'psmouse_noext' doesn't probe and set anything
# all, though it still issues the RESET command. This is as safe as one
# can get.
# 
# The only real problem remaining is that the report rate and resolution
# cannot be set from XFree86 config and only is available as a
# kernel/module parameter. The fix is, howewer not 2.6.0 material.
# --------------------------------------------
# 03/11/09	ak@muc.de	1.1414.1.15
# [PATCH] Work around K8 errata on x86-64
# 
# K8 has an erratum (#100) that essentially causes some compat mode processes
# to fault occassionally. The issue can be worked around in the OS. It only
# applies to x86-64, in 32bit it is fine.
# 
# This adds a check to the page fault handler that checks for addresses >4GB
# from compat mode. If they happen just return; the CPU will reexecute
# the instruction and the condition that caused the problem is gone.
# 
# More details in Opteron/Athlon64 specification update on the AMD website.
# 
# Also I removed a left over debugging printk in the prefetch handling code.
# --------------------------------------------
# 03/11/09	rmk@flint.arm.linux.org.uk	1.1414.5.1
# [ARM] Fix ARM signal handling.
# 
# If we are unable to deliver a signal to the process (eg, due to stack
# pointer corruption) block the signal so other fatal signals can kill
# off the process.
# --------------------------------------------
# 03/11/09	torvalds@home.osdl.org	1.1414.1.16
# Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/09	bdschuym@pandora.be	1.1414.4.4
# [NET]: Bart wrote arpt_mangle not DaveM. :-)
# --------------------------------------------
# 03/11/09	yoshfuji@linux-ipv6.org	1.1414.4.5
# [JIFFIES]: linux/times.h needs asm/param.h (for USER_HZ)
# --------------------------------------------
# 03/11/09	yoshfuji@linux-ipv6.org	1.1414.4.6
# [IPV4/IPV6]: Normalize jiffies reported to userspace in routing code.
# --------------------------------------------
# 03/11/09	davem@nuts.ninka.net	1.1414.1.17
# Merge nuts.ninka.net:/disk1/davem/BK/network-2.5
# into nuts.ninka.net:/disk1/davem/BK/net-2.5
# --------------------------------------------
# 03/11/09	paulus@samba.org	1.1414.6.1
# [PATCH] PPC32: Fix alignment problem with __ex_table and __bug_table.
# 
# The __start___ex_table and __start___bug_table symbols could end up
# pointing a few bytes before the actual __ex_table and __bug_table
# sections, if the preceding section had an odd length.  This led to
# oopses in some situations.  Patch from Sam Ravnborg.
# --------------------------------------------
# 03/11/09	neilb@cse.unsw.edu.au	1.1414.6.2
# [PATCH] Fix nfsd extra dput()
# 
# An extra dput was introduced in nfsd_rename 20 months ago....
# 
# time to remove it.
# --------------------------------------------
# 03/11/09	davem@hera.kernel.org	1.1414.1.18
# Merge davem@nuts.ninka.net:/disk1/davem/BK/net-2.5
# into hera.kernel.org:/home/davem/BK/net-2.5
# --------------------------------------------
# 03/11/10	akpm@osdl.org	1.1414.1.19
# [PATCH] AS: handle non-block requests
# 
# From: Nick Piggin <piggin@cyberone.com.au>
# 
# as_completed_request() can be called for requests which were not generated by
# the generic block layer.  Handle these, to avoid a subsequent WARN_ON (at
# least).
# 
# Also kill a separate WARN_ON which is bogusly triggering.
# --------------------------------------------
# 03/11/10	akpm@osdl.org	1.1414.1.20
# [PATCH] 3c509 MCA compile fix
# 
# Only include mca.h if CONFIG_MCA: only ia32 and ia64 have <asm/mca.h>
# --------------------------------------------
# 03/11/10	akpm@osdl.org	1.1414.1.21
# [PATCH] ext2 block allocation race fix
# 
# If this CPU decides that an ext2 block group has a free block it will then go
# in and try to acquire it.  No locks are held, so another CPU can come in and
# steal the last block.
# 
# In this case we will bogusly report a corrupted filessytem.
# 
# Fix it by just restarting the scan - this will choose a different blockgroup
# or will generate -ENOSPC.
# --------------------------------------------
# 03/11/10	akpm@osdl.org	1.1414.1.22
# [PATCH] Disable IDE Tagged Command Queueing
# 
# It's not ready for prime time yet, so hide it until the additional work has
# been done.
# --------------------------------------------
# 03/11/10	akpm@osdl.org	1.1414.1.23
# [PATCH] char dev request_module fix
# 
# From: Rusty Russell <rusty@rustcorp.com.au>
# 
# Module aliases are all of form "char-major-<major>-<minor>".  char_dev.c
# calls request_module with "char-major-<major>".
# --------------------------------------------
# 03/11/10	akpm@osdl.org	1.1414.1.24
# [PATCH] Fix RAID1 recovery
# 
# From: Mike Tran <mhtran@us.ibm.com>
# 
# This fixes the RAID1 recovery problems; it seems to be a simple thinko:
# sync_request_write() is passing "ok=0" into md_done_sync().  Clearly, `ok'
# should be true here.
# 
# (acked by neilb)
# --------------------------------------------
# 03/11/10	akpm@osdl.org	1.1414.1.25
# [PATCH] JBD: fix assertion failure
# 
# This fixes a JBD assertion failure (goes BUG) in __journal_remove_journal_head().
# 
# When the journal had aborted due to earlier internal consistency errors (or
# I/O errors) it is possible that we free journal_heads which still have
# attached copyout buffers.  So just free them up.
# --------------------------------------------
# 03/11/10	akpm@osdl.org	1.1414.1.26
# [PATCH] compile fix for voyager with gcc-3.3
# 
# From: James Bottomley <James.Bottomley@SteelEye.com>
# 
# The cpu_callout_map differs from the prototype in asm-i386/smp.h by a
# volatile.  gcc-3.3 now treats this as an error, so voyager support will
# only compile with older gcc's.  The fix is to remove the spurious volatile.
# --------------------------------------------
# 03/11/10	jgarzik@redhat.com	1.1418
# [libata promise] fixes suggested by Promise
# 
# * flush host FIFO after sending data to DIMM window
# * don't set SCR addresses, as the hardware doesn't have SCRs
#   (cosmetic)
# --------------------------------------------
# 03/11/10	torvalds@home.osdl.org	1.1419
# Merge bk://gkernel.bkbits.net/libata-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/10	torvalds@home.osdl.org	1.1420
# Merge bk://gkernel.bkbits.net/net-drivers-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/10	Andries.Brouwer@cwi.nl	1.1421
# [PATCH] Warn about old EZD and DM disk remappers
# 
# Since 2.6.x by default does not remap the disk partitions any more, it
# would be a good idea to warn when we see EZD or DM signatures.  That
# informs the user to fix his setup (or pass in "hdx=remap" on the kernel
# command line).
# --------------------------------------------
# 03/11/10	davidm@tiger.hpl.hp.com	1.1350.5.5
# Fix pte_modify() bug which allowed mprotect() to change too many bits.
# Found by Russell King.
# --------------------------------------------
# 03/11/10	torvalds@home.osdl.org	1.1422
# Merge http://lia64.bkbits.net/to-linus-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/10	pj@sgi.com	1.1350.5.6
# [PATCH] ia64: fix bug in prof_cpu_mask_read_proc()
# 
# Display of cpumask for /proc/irq/prof_cpu_mask has a botch in the print
# loop - should consume 2 bytes per loop.
# --------------------------------------------
# 03/11/10	davidm@tiger.hpl.hp.com	1.1350.5.7
# ia64: Fix _PAGE_CHG_MASK so PROT_NONE works again.  Caught by Linus.
# --------------------------------------------
# 03/11/10	torvalds@home.osdl.org	1.1423
# Merge http://lia64.bkbits.net/to-linus-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/10	yoshfuji@linux-ipv6.org	1.1422.1.1
# [DECNET]: Normalize jiffies reported to userspace.
# --------------------------------------------
# 03/11/10	yoshfuji@linux-ipv6.org	1.1422.1.2
# [IPV4/IPV6]: More userland jiffies reporting fixes for routing.
# --------------------------------------------
# 03/11/11	davem@nuts.ninka.net	1.1422.2.1
# [SPARC64]: Fix PCI floppy IRQ enable/disable handling.
# - Delete fd_{enable,disable}_irq() interfaces, never used.
# - Move ebus_dma_irq_enable() calls into sun_pci_fd_{request,free}_irq().
# --------------------------------------------
# 03/11/11	torvalds@home.osdl.org	1.1424
# Fix double unlock of page_table_lock in do_wp_page().
# 
# Noticed by Petr Vandrovec.
# 
# In the out-of-memory case, do_wp_page() would unlock page_table_lock
# twice - once before allocating, and once in the exit path.
# 
# Rewrite the exit paths to be more readable, and don't try to share
# the code between all the exit cases, since they are very different. 
# --------------------------------------------
# 03/11/11	daniel@osdl.org	1.1425
# [PATCH] Fix AIO reference counts
# 
# This makes the AIO submit path holds an extra reference until just
# before returning.  This fixes the referencing a free kiocb. 
# 
# Without this patch the kernel will oops if the AIO completes early.
# --------------------------------------------
# 03/11/11	torvalds@home.osdl.org	1.1426
# Avoid racy optimization in signal sending.
# 
# The bug is probably impossible to trigger on x86, due to its
# fairly strong coherency model (the SMP-safe bitops end up being
# memory barriers etc), but other architectures - notably ppc64 -
# can apparently trigger a race whereby the signal sender doesn't
# wake up the target because it doesn't notice that it has gone to
# sleep.
# 
# The optimization also optimizes only what appears to be the
# uncommon case, where the signal happens for an already-running
# process.
# --------------------------------------------
# 03/11/11	torvalds@home.osdl.org	1.1427
# Merge master.kernel.org:/home/davem/BK/net-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/11	torvalds@home.osdl.org	1.1428
# Merge master.kernel.org:/home/davem/BK/sparc-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/11	steiner@sgi.com	1.1350.5.8
# [PATCH] ia64: fix is_headless_node() for SN
# 
# Without this patch, SN machines which have nodes that contain memory only (no
# CPUs will hang.
# --------------------------------------------
# 03/11/11	george@mvista.com	1.1429
# [PATCH] Fix clock_nanosleep() signal restart issues
# 
# The problem with clock_nanosleep() restarting was that the address of
# the users return timespec was being saved at the wrong place.  In needs
# to be saved in the sys call interface code rather than the
# do_clock_nanosleep().  My original tests were a bit weak as they only
# did one signal rather than two or more which were required to break it. 
# 
# The attached patch fixes the problem.
# 
# I also added a few comments about how restart works, and added my name
# to the MAINTAINERS list.
# --------------------------------------------
# 03/11/11	ja@ssi.bg	1.1428.1.1
# [IPVS]: avoid NULL ptr deref for dest in __ip_vs_get_out_rt
# --------------------------------------------
# 03/11/11	akpm@osdl.org	1.1428.1.2
# [NET]: Remove __devinitdata from board_info[] in tlan.c driver.
# --------------------------------------------
# 03/11/11	ja@ssi.bg	1.1428.1.3
# [IPVS]: make sure timer expires on one cpu
# --------------------------------------------
# 03/11/11	torvalds@home.osdl.org	1.1430
# Fix ALI 15x3 IDE driver oops
# 
# It would oops on any machines that had an ALI northbridge but
# didn't have the exact ISA bridge we expected.
# --------------------------------------------
# 03/11/11	torvalds@home.osdl.org	1.1431
# Always disable system call restart when invoking a signal handler.
# 
# Otherwise, a restarted system call that gets interrupted before
# the restart has taken effect by _another_ signal will potentially
# restart the wrong system call.
# --------------------------------------------
# 03/11/11	davidm@wailua.hpl.hp.com	1.1350.5.9
# ia64: From Linus: Always disable system call restart when invoking a
# 	signal handler.  Otherwise, a restarted system call that gets
# 	interrupted before the restart has taken effect by _another_
# 	signal will potentially restart the wrong system call.
# --------------------------------------------
# 03/11/12	davem@nuts.ninka.net	1.1428.1.4
# [IPV6]: Fix packet quoting in icmpv6_send().
# - Mucking with the original skb pointers with push/pull around
#   the packet quoting was wrong, muching with these pointers could
#   cause problems with others using the SKB.
# 
#   It was also buggy, it only handled the case where skb->nh.raw was
#   ahead of or equal to skb->data
# 
# - The fix is to record skb->nh.raw - skb->data and use this as
#   a base offset in calls to skb_copy_and_csum_bits().  This is
#   what the pre-IPSEC code did.
# 
# This fixes IPV6 oopses and packet corruption on 64-bit platforms
# when sending UDP port unreachable ICMP messages.
# 
# Reported and analyzed by Jan Oravec (jan.oravec@6com.sk)
# --------------------------------------------
# 03/11/12	torvalds@home.osdl.org	1.1432
# Re-instate the ALI northbridge checks in ALI IDE driver
# 
# This leaves just the minimal oops protection in place, and
# maintains the logic that "if we have a non-ALI northbridge,
# we shouldn't touch any of the GPIOs because we don't know
# what they might be connected to".
# --------------------------------------------
# 03/11/12	torvalds@home.osdl.org	1.1433
# Merge http://lia64.bkbits.net/to-linus-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/11/12	wei_ni@ali.com.tw	1.1434
# [PATCH] Legacy ALi5455 Audio Driver update
# 
# We've resolved some bugs in legacy ALi5455 audio driver.
# --------------------------------------------
# 03/11/12	ink@jurassic.park.msu.ru	1.1435
# [PATCH] ALI IDE forward port from 2.4.x
# 
# This forward-ports some more of the ALI IDE sanity checks from the 2.4.x
# tree. 
# 
# In particular, we only do the enable bits for revisions < 0xC5
# --------------------------------------------
# 03/11/12	jan.oravec@6com.sk	1.1428.1.5
# [IPV6]: Fix len calculation after icmp changes.
# --------------------------------------------
# 03/11/12	davem@hera.kernel.org	1.1436
# Merge davem@nuts.ninka.net:/disk1/davem/BK/net-2.5
# into hera.kernel.org:/home/davem/BK/net-2.5
# --------------------------------------------
# 03/11/12	herbert@gondor.apana.org.au	1.1414.3.3
# [netdrvr tg3] initialize workqueue correctly
# 
# (fixes crash)
# --------------------------------------------
# 03/11/12	shemminger@osdl.org	1.1414.3.4
# [netdrvr de4x5] NE54-de4x5 - fix missing free on error path - found by viro
# --------------------------------------------
# 03/11/12	jgarzik@redhat.com	1.1435.1.1
# Merge redhat.com:/spare/repo/linux-2.5
# into redhat.com:/spare/repo/net-drivers-2.5
# --------------------------------------------
# 03/11/12	torvalds@home.osdl.org	1.1437
# Merge bk://gkernel.bkbits.net/net-drivers-2.5
# into home.osdl.org:/home/torvalds/v2.5/linux
# --------------------------------------------
#
diff -Nru a/Documentation/networking/irda.txt b/Documentation/networking/irda.txt
--- a/Documentation/networking/irda.txt	Wed Nov 12 21:06:45 2003
+++ b/Documentation/networking/irda.txt	Wed Nov 12 21:06:45 2003
@@ -3,12 +3,12 @@
 programs can be found on http://irda.sourceforge.net/
 
 For more information about how to use the IrDA protocol stack, see the
-IR-HOWTO (http://www.mobilix.org/Infrared-HOWTO/Infrared-HOWTO.html) written by Werner Heuser
-<wehe@mobilix.org>
+Linux Infared HOWTO (http://www.tuxmobil.org/Infrared-HOWTO/Infrared-HOWTO.html)
+by Werner Heuser <wehe@tuxmobil.org>
 
 There is an active mailing list for discussing Linux-IrDA matters called
-linux-irda. To subscribe to it, visit:
+    irda-users@lists.sourceforge.net
+
+
 
-	http://www.pasta.cs.uit.no/mailman/listinfo/linux-irda
 
-Dag Brattli <dagb@cs.uit.no>
diff -Nru a/Documentation/video4linux/meye.txt b/Documentation/video4linux/meye.txt
--- a/Documentation/video4linux/meye.txt	Wed Nov 12 21:06:47 2003
+++ b/Documentation/video4linux/meye.txt	Wed Nov 12 21:06:47 2003
@@ -33,6 +33,11 @@
 driver however), but things are not moving very fast (see
 http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011).
 
+There is a forth model connected on the USB bus in TR1* Vaio laptops.
+This camera is not supported at all by the current driver, in fact
+little information if any is available for this camera
+(USB vendor/device is 0x054c/0x0107).
+
 Driver options:
 ---------------
 
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Wed Nov 12 21:06:47 2003
+++ b/MAINTAINERS	Wed Nov 12 21:06:47 2003
@@ -234,9 +234,8 @@
 S:	Supported
 
 APPLETALK NETWORK LAYER
-P:	Jay Schulist
-M:	jschlst@samba.org
-L:	linux-atalk@lists.netspace.org
+P:	Arnaldo Carvalho de Melo
+M:	acme@conectiva.com.br
 S:	Maintained
 
 ARM26 ARCHITECTURE
@@ -1356,7 +1355,7 @@
 L:	linux-scsi@vger.kernel.org
 S:	Maintained
 
-NETFILTER/IPTABLES
+NETFILTER/IPTABLES/IPCHAINS
 P:	Rusty Russell
 P:	Marc Boucher
 P:	James Morris
@@ -1568,6 +1567,12 @@
 M:	tsbogend@alpha.franken.de
 L:	linux-net@vger.kernel.org
 S:	Maintained
+
+POSIX CLOCKS and TIMERS
+P:	George Anzinger
+M:	george@mvista.com
+L:	linux-net@vger.kernel.org
+S:	Supported
 
 PNP SUPPORT
 P:	Adam Belay
diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
--- a/arch/alpha/kernel/setup.c	Wed Nov 12 21:06:46 2003
+++ b/arch/alpha/kernel/setup.c	Wed Nov 12 21:06:46 2003
@@ -486,6 +486,21 @@
 	hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
 	boot_cpuid = hard_smp_processor_id();
 
+        /*
+	 * Pre-process the system type to make sure it will be valid.
+	 *
+	 * This may restore real CABRIO and EB66+ family names, ie
+	 * EB64+ and EB66.
+	 *
+	 * Oh, and "white box" AS800 (aka DIGITAL Server 3000 series)
+	 * and AS1200 (DIGITAL Server 5000 series) have the type as
+	 * the negative of the real one.
+	 */
+        if ((long)hwrpb->sys_type < 0) {
+		hwrpb->sys_type = -((long)hwrpb->sys_type);
+		hwrpb_update_checksum(hwrpb);
+	}
+
 	/* Register a call for panic conditions. */
 	notifier_chain_register(&panic_notifier_list, &alpha_panic_block);
 
diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
--- a/arch/arm/kernel/signal.c	Wed Nov 12 21:06:45 2003
+++ b/arch/arm/kernel/signal.c	Wed Nov 12 21:06:45 2003
@@ -497,18 +497,21 @@
 	 */
 	ret |= !valid_user_regs(regs);
 
+	/*
+	 * Block the signal if we were unsuccessful.
+	 */
+	if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&tsk->sighand->siglock);
+		sigorsets(&tsk->blocked, &tsk->blocked,
+			  &ka->sa.sa_mask);
+		sigaddset(&tsk->blocked, sig);
+		recalc_sigpending();
+		spin_unlock_irq(&tsk->sighand->siglock);
+	}
+
 	if (ret == 0) {
 		if (ka->sa.sa_flags & SA_ONESHOT)
 			ka->sa.sa_handler = SIG_DFL;
-
-		if (!(ka->sa.sa_flags & SA_NODEFER)) {
-			spin_lock_irq(&tsk->sighand->siglock);
-			sigorsets(&tsk->blocked, &tsk->blocked,
-				  &ka->sa.sa_mask);
-			sigaddset(&tsk->blocked, sig);
-			recalc_sigpending();
-			spin_unlock_irq(&tsk->sighand->siglock);
-		}
 		return;
 	}
 
diff -Nru a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
--- a/arch/h8300/kernel/time.c	Wed Nov 12 21:06:46 2003
+++ b/arch/h8300/kernel/time.c	Wed Nov 12 21:06:46 2003
@@ -143,3 +143,9 @@
 }
 
 EXPORT_SYMBOL(do_settimeofday);
+
+unsigned long long sched_clock(void)
+{
+	return (unsigned long long)jiffies * (1000000000 / HZ);
+
+}
diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
--- a/arch/i386/kernel/signal.c	Wed Nov 12 21:06:46 2003
+++ b/arch/i386/kernel/signal.c	Wed Nov 12 21:06:46 2003
@@ -504,12 +504,14 @@
 {
 	struct k_sigaction *ka = &current->sighand->action[sig-1];
 
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
 	/* Are we from a system call? */
 	if (regs->orig_eax >= 0) {
 		/* If so, check system call restarting.. */
 		switch (regs->eax) {
 		        case -ERESTART_RESTARTBLOCK:
-				current_thread_info()->restart_block.fn = do_no_restart_syscall;
 			case -ERESTARTNOHAND:
 				regs->eax = -EINTR;
 				break;
diff -Nru a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
--- a/arch/i386/kernel/vm86.c	Wed Nov 12 21:06:46 2003
+++ b/arch/i386/kernel/vm86.c	Wed Nov 12 21:06:46 2003
@@ -101,6 +101,13 @@
 	struct pt_regs *ret;
 	unsigned long tmp;
 
+	/*
+	 * This gets called from entry.S with interrupts disabled, but
+	 * from process context. Enable interrupts here, before trying
+	 * to access user space.
+	 */
+	local_irq_enable();
+
 	if (!current->thread.vm86_info) {
 		printk("no vm86_info: BAD\n");
 		do_exit(SIGSEGV);
diff -Nru a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
--- a/arch/i386/mach-visws/visws_apic.c	Wed Nov 12 21:06:45 2003
+++ b/arch/i386/mach-visws/visws_apic.c	Wed Nov 12 21:06:45 2003
@@ -31,9 +31,6 @@
 #include "irq_vectors.h"
 
 
-int irq_vector[NR_IRQS] = { FIRST_EXTERNAL_VECTOR, 0 };
-
-
 static spinlock_t cobalt_lock = SPIN_LOCK_UNLOCKED;
 
 /*
@@ -42,7 +39,7 @@
  */
 static inline void co_apic_set(int entry, int irq)
 {
-	co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | irq_vector[irq]);
+	co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (irq + FIRST_EXTERNAL_VECTOR));
 	co_apic_write(CO_APIC_HI(entry), 0);
 }
 
@@ -299,7 +296,6 @@
 		else if (IS_CO_APIC(i)) {
 			irq_desc[i].handler = &cobalt_irq_type;
 		}
-		irq_vector[i] = i + FIRST_EXTERNAL_VECTOR;
 	}
 
 	setup_irq(CO_IRQ_8259, &master_action);
diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
--- a/arch/i386/mach-voyager/voyager_smp.c	Wed Nov 12 21:06:46 2003
+++ b/arch/i386/mach-voyager/voyager_smp.c	Wed Nov 12 21:06:46 2003
@@ -245,8 +245,8 @@
 static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
 
 /* This is for the new dynamic CPU boot code */
-volatile cpumask_t cpu_callin_map = CPU_MASK_NONE;
-volatile cpumask_t cpu_callout_map = CPU_MASK_NONE;
+cpumask_t cpu_callin_map = CPU_MASK_NONE;
+cpumask_t cpu_callout_map = CPU_MASK_NONE;
 
 /* The per processor IRQ masks (these are usually kept in sync) */
 static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
diff -Nru a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
--- a/arch/i386/mm/ioremap.c	Wed Nov 12 21:06:46 2003
+++ b/arch/i386/mm/ioremap.c	Wed Nov 12 21:06:46 2003
@@ -190,23 +190,34 @@
 
 void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
 {
+	unsigned long last_addr;
 	void *p = __ioremap(phys_addr, size, _PAGE_PCD);
 	if (!p) 
 		return p; 
 
-	if (phys_addr + size < virt_to_phys(high_memory)) { 
+	/* Guaranteed to be > phys_addr, as per __ioremap() */
+	last_addr = phys_addr + size - 1;
+
+	if (last_addr < virt_to_phys(high_memory)) { 
 		struct page *ppage = virt_to_page(__va(phys_addr));		
-		unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+		unsigned long npages;
+
+		phys_addr &= PAGE_MASK;
+
+		/* This might overflow and become zero.. */
+		last_addr = PAGE_ALIGN(last_addr);
 
-		BUG_ON(phys_addr+size > (unsigned long)high_memory);
-		BUG_ON(phys_addr + size < phys_addr);
+		/* .. but that's ok, because modulo-2**n arithmetic will make
+	 	* the page-aligned "last - first" come out right.
+	 	*/
+		npages = (last_addr - phys_addr) >> PAGE_SHIFT;
 
 		if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) { 
 			iounmap(p); 
 			p = NULL;
 		}
 		global_flush_tlb();
-	} 
+	}
 
 	return p;					
 }
diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c	Wed Nov 12 21:06:48 2003
+++ b/arch/i386/pci/irq.c	Wed Nov 12 21:06:48 2003
@@ -44,6 +44,11 @@
 	int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
 };
 
+struct irq_router_handler {
+	u16 vendor;
+	int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
+};
+
 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
 
 /*
@@ -258,111 +263,220 @@
 }
 
 /*
- *	PIRQ routing for SiS 85C503 router used in several SiS chipsets
- *	According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
- *	the related registers work as follows:
- *	
- *	general: one byte per re-routable IRQ,
+ *	PIRQ routing for SiS 85C503 router used in several SiS chipsets.
+ *	We have to deal with the following issues here:
+ *	- vendors have different ideas about the meaning of link values
+ *	- some onboard devices (integrated in the chipset) have special
+ *	  links and are thus routed differently (i.e. not via PCI INTA-INTD)
+ *	- different revision of the router have a different layout for
+ *	  the routing registers, particularly for the onchip devices
+ *
+ *	For all routing registers the common thing is we have one byte
+ *	per routeable link which is defined as:
  *		 bit 7      IRQ mapping enabled (0) or disabled (1)
- *		 bits [6:4] reserved
+ *		 bits [6:4] reserved (sometimes used for onchip devices)
  *		 bits [3:0] IRQ to map to
  *		     allowed: 3-7, 9-12, 14-15
  *		     reserved: 0, 1, 2, 8, 13
  *
- *	individual registers in device config space:
+ *	The config-space registers located at 0x41/0x42/0x43/0x44 are
+ *	always used to route the normal PCI INT A/B/C/D respectively.
+ *	Apparently there are systems implementing PCI routing table using
+ *	link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D.
+ *	We try our best to handle both link mappings.
+ *	
+ *	Currently (2003-05-21) it appears most SiS chipsets follow the
+ *	definition of routing registers from the SiS-5595 southbridge.
+ *	According to the SiS 5595 datasheets the revision id's of the
+ *	router (ISA-bridge) should be 0x01 or 0xb0.
  *
- *	0x41/0x42/0x43/0x44:	PCI INT A/B/C/D - bits as in general case
+ *	Furthermore we've also seen lspci dumps with revision 0x00 and 0xb1.
+ *	Looks like these are used in a number of SiS 5xx/6xx/7xx chipsets.
+ *	They seem to work with the current routing code. However there is
+ *	some concern because of the two USB-OHCI HCs (original SiS 5595
+ *	had only one). YMMV.
  *
- *	0x61:			IDEIRQ: bits as in general case - but:
- *				bits [6:5] must be written 01
- *				bit 4 channel-select primary (0), secondary (1)
+ *	Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1:
  *
- *	0x62:			USBIRQ: bits as in general case - but:
- *				bit 4 OHCI function disabled (0), enabled (1)
+ *	0x61:	IDEIRQ:
+ *		bits [6:5] must be written 01
+ *		bit 4 channel-select primary (0), secondary (1)
+ *
+ *	0x62:	USBIRQ:
+ *		bit 6 OHCI function disabled (0), enabled (1)
  *	
- *	0x6a:			ACPI/SCI IRQ - bits as in general case
+ *	0x6a:	ACPI/SCI IRQ: bits 4-6 reserved
+ *
+ *	0x7e:	Data Acq. Module IRQ - bits 4-6 reserved
+ *
+ *	We support USBIRQ (in addition to INTA-INTD) and keep the
+ *	IDE, ACPI and DAQ routing untouched as set by the BIOS.
+ *
+ *	Currently the only reported exception is the new SiS 65x chipset
+ *	which includes the SiS 69x southbridge. Here we have the 85C503
+ *	router revision 0x04 and there are changes in the register layout
+ *	mostly related to the different USB HCs with USB 2.0 support.
  *
- *	0x7e:			Data Acq. Module IRQ - bits as in general case
+ *	Onchip routing for router rev-id 0x04 (try-and-error observation)
  *
- *	Apparently there are systems implementing PCI routing table using both
- *	link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets
- *	like 0x62 as link values for USBIRQ e.g. So there is no simple
- *	"register = offset + pirq" relation.
- *	Currently we support PCI INTA..D and USBIRQ and try our best to handle
- *	both link mappings.
- *	IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS).
+ *	0x60/0x61/0x62/0x63:	1xEHCI and 3xOHCI (companion) USB-HCs
+ *				bit 6-4 are probably unused, not like 5595
  */
 
-static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+#define PIRQ_SIS_IRQ_MASK	0x0f
+#define PIRQ_SIS_IRQ_DISABLE	0x80
+#define PIRQ_SIS_USB_ENABLE	0x40
+
+/* return value:
+ * -1 on error
+ * 0 for PCI INTA-INTD
+ * 0 or enable bit mask to check or set for onchip functions
+ */
+static inline int pirq_sis5595_onchip(int pirq, int *reg)
 {
-	u8 x;
-	int reg = pirq;
+	int ret = -1;
 
+	*reg = pirq;
 	switch(pirq) {
-		case 0x01:
-		case 0x02:
-		case 0x03:
-		case 0x04:
-			reg += 0x40;
-		case 0x41:
-		case 0x42:
-		case 0x43:
-		case 0x44:
-		case 0x62:
-			pci_read_config_byte(router, reg, &x);
-			if (reg != 0x62)
-				break;
-			if (!(x & 0x40))
-				return 0;
-			break;
-		case 0x61:
-		case 0x6a:
-		case 0x7e:
-			printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
-			return 0;
-		default:			
-			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
-			return 0;
+	case 0x01:
+	case 0x02:
+	case 0x03:
+	case 0x04:
+		*reg += 0x40;
+	case 0x41:
+	case 0x42:
+	case 0x43:
+	case 0x44:
+		ret = 0;
+		break;
+
+	case 0x62:
+		ret = PIRQ_SIS_USB_ENABLE;	/* documented for 5595 */
+		break;
+
+	case 0x61:
+	case 0x6a:
+	case 0x7e:
+		printk(KERN_INFO "SiS pirq: IDE/ACPI/DAQ mapping not implemented: (%u)\n",
+		       (unsigned) pirq);
+		/* fall thru */
+	default:
+		printk(KERN_INFO "SiS router unknown request: (%u)\n",
+		       (unsigned) pirq);
+		break;
+	}
+	return ret;
+}		
+
+/* return value:
+ * -1 on error
+ * 0 for PCI INTA-INTD
+ * 0 or enable bit mask to check or set for onchip functions
+ */
+static inline int pirq_sis96x_onchip(int pirq, int *reg)
+{
+	int ret = -1;
+
+	*reg = pirq;
+	switch(pirq) {
+	case 0x01:
+	case 0x02:
+	case 0x03:
+	case 0x04:
+		*reg += 0x40;
+	case 0x41:
+	case 0x42:
+	case 0x43:
+	case 0x44:
+	case 0x60:
+	case 0x61:
+	case 0x62:
+	case 0x63:
+		ret = 0;
+		break;
+
+	default:
+		printk(KERN_INFO "SiS router unknown request: (%u)\n",
+		       (unsigned) pirq);
+		break;
 	}
-	return (x & 0x80) ? 0 : (x & 0x0f);
+	return ret;
+}		
+
+
+static int pirq_sis5595_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	u8 x;
+	int reg, check;
+
+	check = pirq_sis5595_onchip(pirq, &reg);
+	if (check < 0)
+		return 0;
+
+	pci_read_config_byte(router, reg, &x);
+	if (check != 0  &&  !(x & check))
+		return 0;
+
+	return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK);
 }
 
-static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+static int pirq_sis96x_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 {
 	u8 x;
-	int reg = pirq;
+	int reg, check;
+
+	check = pirq_sis96x_onchip(pirq, &reg);
+	if (check < 0)
+		return 0;
+
+	pci_read_config_byte(router, reg, &x);
+	if (check != 0  &&  !(x & check))
+		return 0;
+
+	return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK);
+}
+
+static int pirq_sis5595_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	u8 x;
+	int reg, set;
+
+	set = pirq_sis5595_onchip(pirq, &reg);
+	if (set < 0)
+		return 0;
+
+	x = (irq & PIRQ_SIS_IRQ_MASK);
+	if (x == 0)
+		x = PIRQ_SIS_IRQ_DISABLE;
+	else
+		x |= set;
+
+	pci_write_config_byte(router, reg, x);
+
+	return 1;
+}
+
+static int pirq_sis96x_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	u8 x;
+	int reg, set;
+
+	set = pirq_sis96x_onchip(pirq, &reg);
+	if (set < 0)
+		return 0;
+
+	x = (irq & PIRQ_SIS_IRQ_MASK);
+	if (x == 0)
+		x = PIRQ_SIS_IRQ_DISABLE;
+	else
+		x |= set;
 
-	switch(pirq) {
-		case 0x01:
-		case 0x02:
-		case 0x03:
-		case 0x04:
-			reg += 0x40;
-		case 0x41:
-		case 0x42:
-		case 0x43:
-		case 0x44:
-		case 0x62:
-			x = (irq&0x0f) ? (irq&0x0f) : 0x80;
-			if (reg != 0x62)
-				break;
-			/* always mark OHCI enabled, as nothing else knows about this */
-			x |= 0x40;
-			break;
-		case 0x61:
-		case 0x6a:
-		case 0x7e:
-			printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n");
-			return 0;
-		default:			
-			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
-			return 0;
-	}
 	pci_write_config_byte(router, reg, x);
 
 	return 1;
 }
 
+
 /*
  * VLSI: nibble offset 0x74 - educated guess due to routing table and
  *       config space of VLSI 82C534 PCI-bridge/router (1004:0102)
@@ -455,96 +569,252 @@
 	return pcibios_set_irq_routing(bridge, pin, irq);
 }
 
-static struct irq_router pirq_bios_router =
-	{ "BIOS", 0, 0, NULL, pirq_bios_set };
+#endif
+
 
+static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+#if 0 /* Let's see what chip this is supposed to be ... */
+	/* We must not touch 440GX even if we have tables. 440GX has
+	   different IRQ routing weirdness */
+	if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82440GX, NULL))
+		return 0;
 #endif
 
-static struct irq_router pirq_routers[] = {
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, pirq_piix_get, pirq_piix_set },
-	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_0, pirq_piix_get, pirq_piix_set },
-
-	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
-
-	{ "ITE", PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8330G_0, pirq_ite_get, pirq_ite_set },
-
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, pirq_via_get, pirq_via_set },
-
-	{ "OPTI", PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C700, pirq_opti_get, pirq_opti_set },
-
-	{ "NatSemi", PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, pirq_cyrix_get, pirq_cyrix_set },
-	{ "SIS", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, pirq_sis_get, pirq_sis_set },
-	{ "VLSI 82C534", PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C534, pirq_vlsi_get, pirq_vlsi_set },
-	{ "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4,
-	  pirq_serverworks_get, pirq_serverworks_set },
-	{ "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5,
-	  pirq_serverworks_get, pirq_serverworks_set },
-	{ "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B,
-		pirq_amd756_get, pirq_amd756_set },
-	{ "AMD766", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413,
-		pirq_amd756_get, pirq_amd756_set },
-	{ "AMD768", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443,
-		pirq_amd756_get, pirq_amd756_set },
+	switch(device)
+	{
+		case PCI_DEVICE_ID_INTEL_82371FB_0:
+		case PCI_DEVICE_ID_INTEL_82371SB_0:
+		case PCI_DEVICE_ID_INTEL_82371AB_0:
+		case PCI_DEVICE_ID_INTEL_82371MX:
+		case PCI_DEVICE_ID_INTEL_82443MX_0:
+		case PCI_DEVICE_ID_INTEL_82801AA_0:
+		case PCI_DEVICE_ID_INTEL_82801AB_0:
+		case PCI_DEVICE_ID_INTEL_82801BA_0:
+		case PCI_DEVICE_ID_INTEL_82801BA_10:
+		case PCI_DEVICE_ID_INTEL_82801CA_0:
+		case PCI_DEVICE_ID_INTEL_82801CA_12:
+		case PCI_DEVICE_ID_INTEL_82801DB_0:
+		case PCI_DEVICE_ID_INTEL_82801E_0:
+		case PCI_DEVICE_ID_INTEL_82801EB_0:
+		case PCI_DEVICE_ID_INTEL_ESB_0:
+			r->name = "PIIX/ICH";
+			r->get = pirq_piix_get;
+			r->set = pirq_piix_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	/* FIXME: We should move some of the quirk fixup stuff here */
+	switch(device)
+	{
+		case PCI_DEVICE_ID_VIA_82C586_0:
+		case PCI_DEVICE_ID_VIA_82C596:
+		case PCI_DEVICE_ID_VIA_82C686:
+		case PCI_DEVICE_ID_VIA_8231:
+		/* FIXME: add new ones for 8233/5 */
+			r->name = "VIA";
+			r->get = pirq_via_get;
+			r->set = pirq_via_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_VLSI_82C534:
+			r->name = "VLSI 82C534";
+			r->get = pirq_vlsi_get;
+			r->set = pirq_vlsi_set;
+			return 1;
+	}
+	return 0;
+}
 
-	{ "default", 0, 0, NULL, NULL }
-};
 
-static struct irq_router *pirq_router;
+static __init int serverworks_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_SERVERWORKS_OSB4:
+		case PCI_DEVICE_ID_SERVERWORKS_CSB5:
+			r->name = "ServerWorks";
+			r->get = pirq_serverworks_get;
+			r->set = pirq_serverworks_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	if (device != PCI_DEVICE_ID_SI_503)
+		return 0;
+		
+	/*
+	 * In case of SiS south bridge, we need to detect the two
+	 * kinds of routing tables we have seen so far (5595 and 96x). 
+	 *
+	 * The 96x tends to still come with routing tables that claim
+	 * to be 503's.. Silly thing. Check the actual router chip.
+	 */
+	if ((router->device & 0xfff0) == 0x0960) {
+		r->name = "SIS96x";
+		r->get = pirq_sis96x_get;
+		r->set = pirq_sis96x_set;
+		DBG("PCI: Detecting SiS router at %02x:%02x : SiS096x detected\n",
+		    rt->rtr_bus, rt->rtr_devfn);
+	} else {
+		r->name = "SIS5595";
+		r->get = pirq_sis5595_get;
+		r->set = pirq_sis5595_set;
+		DBG("PCI: Detecting SiS router at %02x:%02x : SiS5595 detected\n",
+		    rt->rtr_bus, rt->rtr_devfn);
+	}
+	return 1;
+}
+
+static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_CYRIX_5520:
+			r->name = "NatSemi";
+			r->get = pirq_cyrix_get;
+			r->set = pirq_cyrix_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_OPTI_82C700:
+			r->name = "OPTI";
+			r->get = pirq_opti_get;
+			r->set = pirq_opti_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_ITE_IT8330G_0:
+			r->name = "ITE";
+			r->get = pirq_ite_get;
+			r->set = pirq_ite_set;
+			return 1;
+	}
+	return 0;
+}
+
+static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_AL_M1533:
+			r->name = "ALI";
+			r->get = pirq_ali_get;
+			r->set = pirq_ali_set;
+			return 1;
+		/* Should add 156x some day */
+	}
+	return 0;
+}
+
+static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
+{
+	switch(device)
+	{
+		case PCI_DEVICE_ID_AMD_VIPER_740B:
+			r->name = "AMD756";
+			break;
+		case PCI_DEVICE_ID_AMD_VIPER_7413:
+			r->name = "AMD766";
+			break;
+		case PCI_DEVICE_ID_AMD_VIPER_7443:
+			r->name = "AMD768";
+			break;
+		default:
+			return 0;
+	}
+	r->get = pirq_amd756_get;
+	r->set = pirq_amd756_set;
+	return 1;
+}
+		
+static __initdata struct irq_router_handler pirq_routers[] = {
+	{ PCI_VENDOR_ID_INTEL, intel_router_probe },
+	{ PCI_VENDOR_ID_AL, ali_router_probe },
+	{ PCI_VENDOR_ID_ITE, ite_router_probe },
+	{ PCI_VENDOR_ID_VIA, via_router_probe },
+	{ PCI_VENDOR_ID_OPTI, opti_router_probe },
+	{ PCI_VENDOR_ID_SI, sis_router_probe },
+	{ PCI_VENDOR_ID_CYRIX, cyrix_router_probe },
+	{ PCI_VENDOR_ID_VLSI, vlsi_router_probe },
+	{ PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe },
+	{ PCI_VENDOR_ID_AMD, amd_router_probe },
+	/* Someone with docs needs to add the ATI Radeon IGP */
+	{ 0, NULL }
+};
+static struct irq_router pirq_router;
 static struct pci_dev *pirq_router_dev;
 
-static void __init pirq_find_router(void)
+
+/*
+ *	FIXME: should we have an option to say "generic for
+ *	chipset" ?
+ */
+ 
+static void __init pirq_find_router(struct irq_router *r)
 {
 	struct irq_routing_table *rt = pirq_table;
-	struct irq_router *r;
+	struct irq_router_handler *h;
 
 #ifdef CONFIG_PCI_BIOS
 	if (!rt->signature) {
 		printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n");
-		pirq_router = &pirq_bios_router;
+		r->set = pirq_bios_set;
+		r->name = "BIOS";
 		return;
 	}
 #endif
 
+	/* Default unless a driver reloads it */
+	r->name = "default";
+	r->get = NULL;
+	r->set = NULL;
+	
 	DBG("PCI: Attempting to find IRQ router for %04x:%04x\n",
 	    rt->rtr_vendor, rt->rtr_device);
 
-	/* fall back to default router if nothing else found */
-	pirq_router = &pirq_routers[ARRAY_SIZE(pirq_routers) - 1];
-
 	pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
 	if (!pirq_router_dev) {
 		DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
 		return;
 	}
 
-	for(r=pirq_routers; r->vendor; r++) {
-		/* Exact match against router table entry? Use it! */
-		if (r->vendor == rt->rtr_vendor && r->device == rt->rtr_device) {
-			pirq_router = r;
+	for( h = pirq_routers; h->vendor; h++) {
+		/* First look for a router match */
+		if (rt->rtr_vendor == h->vendor && h->probe(r, pirq_router_dev, rt->rtr_device))
+			break;
+		/* Fall back to a device match */
+		if (pirq_router_dev->vendor == h->vendor && h->probe(r, pirq_router_dev, pirq_router_dev->device))
 			break;
-		}
-		/* Match against router device entry? Use it as a fallback */
-		if (r->vendor == pirq_router_dev->vendor && r->device == pirq_router_dev->device) {
-			pirq_router = r;
-		}
 	}
 	printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
-		pirq_router->name,
+		pirq_router.name,
 		pirq_router_dev->vendor,
 		pirq_router_dev->device,
 		pci_name(pirq_router_dev));
@@ -574,7 +844,7 @@
 	int i, pirq, newirq;
 	int irq = 0;
 	u32 mask;
-	struct irq_router *r = pirq_router;
+	struct irq_router *r = &pirq_router;
 	struct pci_dev *dev2 = NULL;
 	char *msg = NULL;
 
@@ -775,7 +1045,7 @@
 #endif
 	if (pirq_table) {
 		pirq_peer_trick();
-		pirq_find_router();
+		pirq_find_router(&pirq_router);
 		if (pirq_table->exclusive_irqs) {
 			int i;
 			for (i=0; i<16; i++)
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c	Wed Nov 12 21:06:47 2003
+++ b/arch/ia64/kernel/irq.c	Wed Nov 12 21:06:47 2003
@@ -1039,7 +1039,7 @@
 	if (count < HEX_DIGITS+1)
 		return -EINVAL;
 
-	for (k = 0; k < sizeof(cpumask_t)/sizeof(unsigned long); ++k) {
+	for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
 		int j = sprintf(page, "%04hx", (u16)cpus_coerce(*mask));
 		len += j;
 		page += j;
diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c	Wed Nov 12 21:06:47 2003
+++ b/arch/ia64/kernel/perfmon.c	Wed Nov 12 21:06:47 2003
@@ -4717,7 +4717,7 @@
 	/*
 	 * context is UNLOADED, MASKED, TERMINATED we are safe to go
 	 */
-	if (state != PFM_CTX_LOADED == 0) return 0;
+	if (state != PFM_CTX_LOADED) return 0;
 
 	if (state == PFM_CTX_ZOMBIE) return -EINVAL;
 
@@ -5787,7 +5787,7 @@
 	 */
 	psr = pfm_get_psr();
 
-	BUG_ON(foo & (IA64_PSR_I));
+	BUG_ON(psr & (IA64_PSR_I));
 
 	/*
 	 * stop monitoring:
diff -Nru a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h
--- a/arch/ia64/kernel/perfmon_mckinley.h	Wed Nov 12 21:06:47 2003
+++ b/arch/ia64/kernel/perfmon_mckinley.h	Wed Nov 12 21:06:47 2003
@@ -167,7 +167,7 @@
 			 val14 = ctx->ctx_pmcs[14];
 			 check_case1 = 1;
 			 break;
-		case 14: val8  = ctx->ctx_pmcs[13];
+		case 14: val8  = ctx->ctx_pmcs[8];
 			 val13 = ctx->ctx_pmcs[13];
 			 val14 = *val;
 			 check_case1 = 1;
diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
--- a/arch/ia64/kernel/signal.c	Wed Nov 12 21:06:47 2003
+++ b/arch/ia64/kernel/signal.c	Wed Nov 12 21:06:47 2003
@@ -559,10 +559,12 @@
 
 		ka = &current->sighand->action[signr - 1];
 
+		/* Always make any pending restarted system calls return -EINTR */
+		current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
 		if (restart) {
 			switch (errno) {
 			      case ERESTART_RESTARTBLOCK:
-				current_thread_info()->restart_block.fn = do_no_restart_syscall;
 			      case ERESTARTNOHAND:
 				scr->pt.r8 = ERR_CODE(EINTR);
 				/* note: scr->pt.r10 is already -1 */
diff -Nru a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
--- a/arch/ia64/mm/tlb.c	Wed Nov 12 21:06:47 2003
+++ b/arch/ia64/mm/tlb.c	Wed Nov 12 21:06:47 2003
@@ -77,7 +77,7 @@
 	{
 		int cpu = get_cpu(); /* prevent preemption/migration */
 		for (i = 0; i < NR_CPUS; ++i)
-			if (i != cpu)
+			if (cpu_online(i) && (i != cpu))
 				per_cpu(ia64_need_tlb_flush, i) = 1;
 		put_cpu();
 	}
diff -Nru a/arch/ia64/sn/io/machvec/pci_dma.c b/arch/ia64/sn/io/machvec/pci_dma.c
--- a/arch/ia64/sn/io/machvec/pci_dma.c	Wed Nov 12 21:06:46 2003
+++ b/arch/ia64/sn/io/machvec/pci_dma.c	Wed Nov 12 21:06:46 2003
@@ -279,8 +279,7 @@
 	 * scatterlist.
 	 */
 	for (i = 0; i < nents; i++, sg++) {
-		phys_addr = __pa(sg->dma_address ? sg->dma_address :
-			(unsigned long)page_address(sg->page) + sg->offset);
+		phys_addr = __pa((unsigned long)page_address(sg->page) + sg->offset);
 
 		/*
 		 * Handle the most common case: 64 bit cards.  This
diff -Nru a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
--- a/arch/ppc/kernel/vmlinux.lds.S	Wed Nov 12 21:06:48 2003
+++ b/arch/ppc/kernel/vmlinux.lds.S	Wed Nov 12 21:06:48 2003
@@ -47,13 +47,17 @@
 
   .fixup   : { *(.fixup) }
 
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
+	__ex_table : {
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+	}
 
-  __start___bug_table = .;
-  __bug_table : { *(__bug_table) }
-  __stop___bug_table = .;
+	__bug_table : {
+		__start___bug_table = .;
+		*(__bug_table)
+		__stop___bug_table = .;
+	}
 
   /* Read-write section, merged into data segment: */
   . = ALIGN(4096);
diff -Nru a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
--- a/arch/sparc/kernel/entry.S	Wed Nov 12 21:06:46 2003
+++ b/arch/sparc/kernel/entry.S	Wed Nov 12 21:06:46 2003
@@ -38,7 +38,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 268      /* Each OS is different... */
+#define NR_SYSCALLS 272      /* Each OS is different... */
 
 /* These are just handy. */
 #define _SV	save	%sp, -STACKFRAME_SZ, %sp
diff -Nru a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
--- a/arch/sparc/kernel/systbls.S	Wed Nov 12 21:06:46 2003
+++ b/arch/sparc/kernel/systbls.S	Wed Nov 12 21:06:46 2003
@@ -72,7 +72,8 @@
 /*250*/	.long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
 /*255*/	.long sys_nis_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
 /*260*/	.long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
-/*265*/	.long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_nis_syscall
+/*265*/	.long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
+/*270*/	.long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_nis_syscall
 
 #ifdef CONFIG_SUNOS_EMUL
 	/* Now the SunOS syscall table. */
@@ -172,5 +173,8 @@
 /*260*/	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys
+/*270*/	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys
 
 #endif
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Wed Nov 12 21:06:47 2003
+++ b/arch/sparc64/Kconfig	Wed Nov 12 21:06:47 2003
@@ -813,7 +813,7 @@
 # the generic version in that case.
 config HAVE_DEC_LOCK
 	bool
-	depends on !DEBUG_SPINLOCK
+	depends on SMP && !DEBUG_SPINLOCK
 	default y
 
 config DEBUG_SPINLOCK_SLEEP
diff -Nru a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
--- a/arch/sparc64/kernel/entry.S	Wed Nov 12 21:06:45 2003
+++ b/arch/sparc64/kernel/entry.S	Wed Nov 12 21:06:45 2003
@@ -26,7 +26,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 268      /* Each OS is different... */
+#define NR_SYSCALLS 272      /* Each OS is different... */
 
 	.text
 	.align		32
diff -Nru a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
--- a/arch/sparc64/kernel/rtrap.S	Wed Nov 12 21:06:46 2003
+++ b/arch/sparc64/kernel/rtrap.S	Wed Nov 12 21:06:46 2003
@@ -270,9 +270,14 @@
 #ifdef CONFIG_PREEMPT
 		ldsw			[%g6 + TI_PRE_COUNT], %l5
 		brnz			%l5, kern_fpucheck
+		 ldx			[%g6 + TI_FLAGS], %l5
+		andcc			%l5, _TIF_NEED_RESCHED, %g0
+		be,pt			%xcc, kern_fpucheck
+		 srl			%l4, 20, %l5
+		cmp			%l5, 0
+		bne,pn			%xcc, kern_fpucheck
 		 sethi			%hi(PREEMPT_ACTIVE), %l6
 		stw			%l6, [%g6 + TI_PRE_COUNT]
-		wrpr			0, %pil
 		call			schedule
 		 nop
 		ba,pt			%xcc, rtrap
diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c	Wed Nov 12 21:06:47 2003
+++ b/arch/sparc64/kernel/sparc64_ksyms.c	Wed Nov 12 21:06:47 2003
@@ -136,6 +136,7 @@
 EXPORT_SYMBOL(__read_unlock);
 EXPORT_SYMBOL(__write_lock);
 EXPORT_SYMBOL(__write_unlock);
+EXPORT_SYMBOL(__write_trylock);
 #endif
 
 /* Hard IRQ locking */
diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
--- a/arch/sparc64/kernel/systbls.S	Wed Nov 12 21:06:46 2003
+++ b/arch/sparc64/kernel/systbls.S	Wed Nov 12 21:06:46 2003
@@ -72,7 +72,8 @@
 /*250*/	.word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
 	.word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep
 /*260*/	.word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun
-	.word sys_timer_delete, sys32_timer_create, sys_ni_syscall, sys_ni_syscall
+	.word sys_timer_delete, sys32_timer_create, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
+/*270*/	.word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
 
 	/* Now the 64-bit native Linux syscall table. */
 
@@ -133,7 +134,8 @@
 /*250*/	.word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
 	.word sys_ni_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
 /*260*/	.word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
-	.word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_ni_syscall
+	.word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
+/*270*/	.word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_ni_syscall
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -233,6 +235,7 @@
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
-	.word sunos_nosys
+	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys, sunos_nosys, sunos_nosys
 
 #endif
diff -Nru a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S
--- a/arch/sparc64/lib/dec_and_lock.S	Wed Nov 12 21:06:46 2003
+++ b/arch/sparc64/lib/dec_and_lock.S	Wed Nov 12 21:06:46 2003
@@ -29,7 +29,7 @@
 atomic_dec_and_lock:	/* %o0 = counter, %o1 = lock */
 loop1:	lduw	[%o0], %g5
 	subcc	%g5, 1, %g7
-	be,pn	%icc, to_zero
+	be,pn	%icc, start_to_zero
 	 nop
 nzero:	cas	[%o0], %g5, %g7
 	cmp	%g5, %g7
@@ -40,6 +40,7 @@
 	membar	#StoreLoad | #StoreStore
 	retl
 	 mov	%g1, %o0
+start_to_zero:
 #ifdef CONFIG_PREEMPT
 	ldsw	[%g6 + TI_PRE_COUNT], %g3
 	add	%g3, 1, %g3
diff -Nru a/arch/sparc64/lib/rwlock.S b/arch/sparc64/lib/rwlock.S
--- a/arch/sparc64/lib/rwlock.S	Wed Nov 12 21:06:46 2003
+++ b/arch/sparc64/lib/rwlock.S	Wed Nov 12 21:06:46 2003
@@ -63,5 +63,27 @@
 	be,pt		%icc, 99b
 	 membar		#StoreLoad | #StoreStore
 	ba,a,pt		%xcc, 1b
+
+	.globl		__write_trylock
+__write_trylock: /* %o0 = lock_ptr */
+	sethi		%hi(0x80000000), %g2
+1:	lduw		[%o0], %g5
+	brnz,pn		%g5, __write_trylock_fail
+4:	 or		%g5, %g2, %g7
+
+	cas		[%o0], %g5, %g7
+	cmp		%g5, %g7
+	be,pt		%icc, __write_trylock_succeed
+	 membar		#StoreLoad | #StoreStore
+
+	ba,pt		%xcc, 1b
+	 nop
+__write_trylock_succeed:
+	retl
+	 mov		1, %o0
+
+__write_trylock_fail:
+	retl
+	 mov		0, %o0
 rwlock_impl_end:
 
diff -Nru a/arch/x86_64/kernel/acpi/boot.c b/arch/x86_64/kernel/acpi/boot.c
--- a/arch/x86_64/kernel/acpi/boot.c	Wed Nov 12 21:06:46 2003
+++ b/arch/x86_64/kernel/acpi/boot.c	Wed Nov 12 21:06:46 2003
@@ -251,6 +251,33 @@
 } 
 #endif
 
+#ifdef CONFIG_ACPI_BUS
+/*
+ * Set specified PIC IRQ to level triggered mode.
+ *
+ * Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
+ * for the 8259 PIC.  bit[n] = 1 means irq[n] is Level, otherwise Edge.
+ * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0)
+ * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
+ *
+ * As the BIOS should have done this for us,
+ * print a warning if the IRQ wasn't already set to level.
+ */
+
+void acpi_pic_set_level_irq(unsigned int irq)
+{
+	unsigned char mask = 1 << (irq & 7);
+	unsigned int port = 0x4d0 + (irq >> 3);
+	unsigned char val = inb(port);
+
+	if (!(val & mask)) {
+		printk(KERN_WARNING PREFIX "IRQ %d was Edge Triggered, "
+			"setting to Level Triggerd\n", irq);
+		outb(val | mask, port);
+	}
+}
+#endif /* CONFIG_ACPI_BUS */
+
 static unsigned long __init
 acpi_scan_rsdp (
 	unsigned long		start,
diff -Nru a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S	Wed Nov 12 21:06:46 2003
+++ b/arch/x86_64/kernel/entry.S	Wed Nov 12 21:06:46 2003
@@ -219,8 +219,8 @@
 	movq %r10,%rcx	/* fixup for C */
 	call *sys_call_table(,%rax,8)
 	movq %rax,RAX-ARGOFFSET(%rsp)
-	SAVE_REST
-1:	movq %rsp,%rdi
+1:	SAVE_REST
+	movq %rsp,%rdi
 	call syscall_trace
 	RESTORE_TOP_OF_STACK %rbx
 	RESTORE_REST
@@ -566,8 +566,14 @@
 	incl %ebx
        /* There are two places in the kernel that can potentially fault with
           usergs. Handle them here. The exception handlers after
-	  iret run with kernel gs again, so don't set the user space flag. */
-	cmpq $iret_label,RIP(%rsp) 
+	   iret run with kernel gs again, so don't set the user space flag.
+	   B stepping K8s sometimes report an truncated RIP for IRET 
+	   exceptions returning to compat mode. Check for these here too. */
+	leaq iret_label(%rip),%rbp
+	cmpq %rbp,RIP(%rsp) 
+	je   error_swapgs
+	movl %ebp,%ebp	/* zero extend */
+	cmpq %rbp,RIP(%rsp) 
 	je   error_swapgs
 	cmpq $gs_change,RIP(%rsp)
         je   error_swapgs
diff -Nru a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
--- a/arch/x86_64/kernel/io_apic.c	Wed Nov 12 21:06:46 2003
+++ b/arch/x86_64/kernel/io_apic.c	Wed Nov 12 21:06:46 2003
@@ -622,11 +622,13 @@
 	return 0;
 }
 
-int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 };
+/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
+u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
 
 static int __init assign_irq_vector(int irq)
 {
 	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
+	BUG_ON(irq >= NR_IRQ_VECTORS);
 	if (IO_APIC_VECTOR(irq) > 0)
 		return IO_APIC_VECTOR(irq);
 next:
diff -Nru a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
--- a/arch/x86_64/kernel/pci-gart.c	Wed Nov 12 21:06:46 2003
+++ b/arch/x86_64/kernel/pci-gart.c	Wed Nov 12 21:06:46 2003
@@ -395,7 +395,7 @@
 	for (i = start; i < stopat; i++) {
 		struct scatterlist *s = &sg[i];
 		unsigned long start_addr = s->dma_address;
-		BUG_ON(i > 0 && s->offset);
+		BUG_ON(i > start && s->offset);
 		if (i == start) {
 			*sout = *s; 
 			sout->dma_address = iommu_bus_base;
@@ -410,7 +410,6 @@
 			addr += PAGE_SIZE;
 			iommu_page++;
 	} 
-		BUG_ON(i > 0 && addr % PAGE_SIZE); 
 	} 
 	BUG_ON(iommu_page - iommu_start != pages);	
 	return 0;
diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c	Wed Nov 12 21:06:46 2003
+++ b/arch/x86_64/kernel/setup64.c	Wed Nov 12 21:06:46 2003
@@ -189,8 +189,7 @@
 	pda->irqstackptr += IRQSTACKSIZE-64;
 } 
 
-#define EXCEPTION_STK_ORDER 0 /* >= N_EXCEPTION_STACKS*EXCEPTION_STKSZ */
-char boot_exception_stacks[N_EXCEPTION_STACKS*EXCEPTION_STKSZ];
+char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ];
 
 void syscall_init(void)
 {
@@ -226,15 +225,12 @@
 #endif
 	struct tss_struct * t = &init_tss[cpu];
 	unsigned long v, efer; 
-	char *estacks; 
+	char *estacks = NULL; 
 	struct task_struct *me;
 
 	/* CPU 0 is initialised in head64.c */
 	if (cpu != 0) {
 		pda_init(cpu);
-		estacks = (char *)__get_free_pages(GFP_ATOMIC, 0); 
-		if (!estacks)
-			panic("Can't allocate exception stacks for CPU %d\n",cpu);
 	} else 
 		estacks = boot_exception_stacks; 
 
@@ -282,10 +278,15 @@
 	/*
 	 * set up and load the per-CPU TSS
 	 */
-	estacks += EXCEPTION_STKSZ;
 	for (v = 0; v < N_EXCEPTION_STACKS; v++) {
-		t->ist[v] = (unsigned long)estacks;
+		if (cpu) {
+			estacks = (char *)__get_free_pages(GFP_ATOMIC, 0);
+			if (!estacks)
+				panic("Cannot allocate exception stack %ld %d\n",
+				      v, cpu); 
+		}
 		estacks += EXCEPTION_STKSZ;
+		t->ist[v] = (unsigned long)estacks;
 	}
 
 	t->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c	Wed Nov 12 21:06:46 2003
+++ b/arch/x86_64/kernel/smp.c	Wed Nov 12 21:06:46 2003
@@ -487,25 +487,3 @@
 		atomic_inc(&call_data->finished);
 	}
 }
-
-/* Slow. Should be only used for debugging. */
-int slow_smp_processor_id(void)
-{ 
-	int stack_location;
-	unsigned long sp = (unsigned long)&stack_location; 
-	int offset = 0, cpu;
-
-	for (offset = 0; next_cpu(offset, cpu_online_map) < NR_CPUS; offset = cpu + 1) {
-		cpu = next_cpu(offset, cpu_online_map);
-
-		if (sp >= (u64)cpu_pda[cpu].irqstackptr - IRQSTACKSIZE && 
-		    sp <= (u64)cpu_pda[cpu].irqstackptr)
-			return cpu;
-
-		unsigned long estack = init_tss[cpu].ist[0] - EXCEPTION_STKSZ;
-		if (sp >= estack && sp <= estack+(1<<(PAGE_SHIFT+EXCEPTION_STK_ORDER)))
-			return cpu;			
-	}
-
-	return stack_smp_processor_id();
-} 
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c	Wed Nov 12 21:06:47 2003
+++ b/arch/x86_64/kernel/time.c	Wed Nov 12 21:06:47 2003
@@ -111,6 +111,14 @@
 		sec = xtime.tv_sec;
 		usec = xtime.tv_nsec / 1000;
 
+		/*
+		 * If time_adjust is negative then NTP is slowing the clock
+		 * so make sure not to go into next possible interval.
+		 * Better to lose some accuracy than have time go backwards..
+		 */
+		if (unlikely(time_adjust < 0) && usec > tickadj)
+			usec = tickadj;
+
 		t = (jiffies - wall_jiffies) * (1000000L / HZ) +
 			do_gettimeoffset();
 		usec += t;
@@ -477,22 +485,28 @@
 static unsigned int  ref_freq = 0;
 static unsigned long loops_per_jiffy_ref = 0;
 
-//static unsigned long fast_gettimeoffset_ref = 0;
 static unsigned long cpu_khz_ref = 0;
 
 static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
 				 void *data)
 {
         struct cpufreq_freqs *freq = data;
+	unsigned long *lpj;
+
+#ifdef CONFIG_SMP
+	lpj = &cpu_data[freq->cpu].loops_per_jiffy;
+#else
+	lpj = &boot_cpu_data.loops_per_jiffy;
+#endif
 
 	if (!ref_freq) {
 		ref_freq = freq->old;
-		loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
+		loops_per_jiffy_ref = *lpj;
 		cpu_khz_ref = cpu_khz;
 	}
         if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
             (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
-                cpu_data[freq->cpu].loops_per_jiffy =
+                *lpj =
 		cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
 
 		cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
diff -Nru a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
--- a/arch/x86_64/kernel/x8664_ksyms.c	Wed Nov 12 21:06:46 2003
+++ b/arch/x86_64/kernel/x8664_ksyms.c	Wed Nov 12 21:06:46 2003
@@ -71,6 +71,7 @@
 EXPORT_SYMBOL_NOVERS(__up_wakeup);
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_partial_copy_nocheck);
+EXPORT_SYMBOL(ip_compute_csum);
 /* Delay loops */
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__ndelay);
@@ -113,6 +114,7 @@
 EXPORT_SYMBOL(mmx_copy_page);
 #endif
 
+EXPORT_SYMBOL(cpu_pda);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(cpu_data);
 EXPORT_SYMBOL(cpu_online_map);
@@ -153,7 +155,7 @@
 
 extern void * memset(void *,int,__kernel_size_t);
 extern size_t strlen(const char *);
-extern char * bcopy(const char * src, char * dest, int count);
+extern void bcopy(const char * src, char * dest, int count);
 extern void * memmove(void * dest,const void *src,size_t count);
 extern char * strcpy(char * dest,const char *src);
 extern int strcmp(const char * cs,const char * ct);
diff -Nru a/arch/x86_64/mm/extable.c b/arch/x86_64/mm/extable.c
--- a/arch/x86_64/mm/extable.c	Wed Nov 12 21:06:47 2003
+++ b/arch/x86_64/mm/extable.c	Wed Nov 12 21:06:47 2003
@@ -14,6 +14,10 @@
 	       const struct exception_table_entry *last,
 	       unsigned long value)
 {
+	/* Work around a B stepping K8 bug */
+	if ((value >> 32) == 0)
+		value |= 0xffffffffUL << 32; 
+
         while (first <= last) {
 		const struct exception_table_entry *mid;
 		long diff;
diff -Nru a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
--- a/arch/x86_64/mm/fault.c	Wed Nov 12 21:06:45 2003
+++ b/arch/x86_64/mm/fault.c	Wed Nov 12 21:06:45 2003
@@ -126,12 +126,6 @@
 			break;
 		} 
 	}
-
-#if 1
-	if (prefetch)
-		printk("%s: prefetch caused page fault at %lx/%lx\n", current->comm,
-		       regs->rip, addr);
-#endif
 	return prefetch;
 }
 
@@ -240,6 +234,15 @@
 	 */
 	if (unlikely(in_atomic() || !mm))
 		goto bad_area_nosemaphore;
+
+	/* Work around K8 erratum #100
+	   K8 in compat mode occasionally jumps to illegal addresses >4GB.
+	   We catch this here in the page fault handler because these
+	   addresses are not reachable. Just detect this case and return.
+	   Any code segment in LDT is compatibility mode. */
+	if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
+		(address >> 32))
+		return;
 
  again:
 	down_read(&mm->mmap_sem);
diff -Nru a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
--- a/arch/x86_64/mm/k8topology.c	Wed Nov 12 21:06:48 2003
+++ b/arch/x86_64/mm/k8topology.c	Wed Nov 12 21:06:48 2003
@@ -164,5 +164,8 @@
 		rr++; 
 	}
 
+	if (found == 1) 
+		fake_node = 1;
+
 	return 0;
 } 
diff -Nru a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
--- a/arch/x86_64/mm/numa.c	Wed Nov 12 21:06:47 2003
+++ b/arch/x86_64/mm/numa.c	Wed Nov 12 21:06:47 2003
@@ -104,6 +104,7 @@
 	if (nodeid + 1 > numnodes)
 		numnodes = nodeid + 1;
 	nodes_present |= (1UL << nodeid); 
+	node_set_online(nodeid);
 } 
 
 /* Initialize final allocator for a zone */
diff -Nru a/crypto/api.c b/crypto/api.c
--- a/crypto/api.c	Wed Nov 12 21:06:47 2003
+++ b/crypto/api.c	Wed Nov 12 21:06:47 2003
@@ -36,6 +36,9 @@
 struct crypto_alg *crypto_alg_lookup(const char *name)
 {
 	struct crypto_alg *q, *alg = NULL;
+
+	if (!name)
+		return NULL;
 	
 	down_read(&crypto_alg_sem);
 	
diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
--- a/drivers/acpi/dispatcher/dsopcode.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/acpi/dispatcher/dsopcode.c	Wed Nov 12 21:06:47 2003
@@ -514,16 +514,14 @@
 		goto cleanup;
 	}
 
+
 	/* Entire field must fit within the current length of the buffer */
 
 	if ((bit_offset + bit_count) >
 		(8 * (u32) buffer_desc->buffer.length)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
-			((struct acpi_namespace_node *) result_desc)->name.ascii,
-			 bit_offset + bit_count,
-			 buffer_desc->buffer.node->name.ascii,
-			 8 * (u32) buffer_desc->buffer.length));
+			"Field size %d exceeds Buffer size %d (bits)\n",
+			 bit_offset + bit_count, 8 * (u32) buffer_desc->buffer.length));
 		status = AE_AML_BUFFER_LIMIT;
 		goto cleanup;
 	}
diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/acpi/ec.c	Wed Nov 12 21:06:46 2003
@@ -94,13 +94,6 @@
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
 
-/*
- * We use kernel thread to handle ec's gpe query, so the query may defer.
- * The query need a context, which can be freed when we replace ec_ecdt
- * with EC device. So defered query may have a wrong context.
- * We use an indication to avoid it
- */
-static int ec_device_init = 0;
 /* --------------------------------------------------------------------------
                              Transaction Management
    -------------------------------------------------------------------------- */
@@ -400,11 +393,8 @@
 
 	acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
 
-	if (!ec_device_init)
-		acpi_ec_gpe_query(ec); /* directly query when device didn't init */
-	else
-		status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
-			acpi_ec_gpe_query, ec);
+	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+		acpi_ec_gpe_query, ec);
 }
 
 /* --------------------------------------------------------------------------
@@ -599,8 +589,6 @@
 	   we now have the *real* EC info, so kill the makeshift one.*/
 	acpi_evaluate_integer(ec->handle, "_UID", NULL, &uid);
 	if (ec_ecdt && ec_ecdt->uid == uid) {
-		acpi_disable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
-		ec_device_init = 1;
 		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
 	
diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
--- a/drivers/acpi/pci_root.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/acpi/pci_root.c	Wed Nov 12 21:06:46 2003
@@ -66,7 +66,7 @@
 	u64			io_tra;
 };
 
-struct list_head		acpi_pci_roots;
+static LIST_HEAD(acpi_pci_roots);
 
 static struct acpi_pci_driver *sub_driver;
 
@@ -374,8 +374,6 @@
 	acpi_dbg_layer = ACPI_PCI_COMPONENT;
 	acpi_dbg_level = 0xFFFFFFFF;
 	 */
-
- 	INIT_LIST_HEAD(&acpi_pci_roots);
 
 	if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
 		return_VALUE(-ENODEV);
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c	Wed Nov 12 21:06:48 2003
+++ b/drivers/base/class.c	Wed Nov 12 21:06:48 2003
@@ -255,6 +255,7 @@
 
 void class_device_initialize(struct class_device *class_dev)
 {
+	kobj_set_kset_s(class_dev, class_obj_subsys);
 	kobject_init(&class_dev->kobj);
 	INIT_LIST_HEAD(&class_dev->node);
 }
@@ -277,7 +278,6 @@
 
 	/* first, register with generic layer. */
 	kobject_set_name(&class_dev->kobj, class_dev->class_id);
-	kobj_set_kset_s(class_dev, class_obj_subsys);
 	if (parent)
 		class_dev->kobj.parent = &parent->subsys.kset.kobj;
 
diff -Nru a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
--- a/drivers/block/as-iosched.c	Wed Nov 12 21:06:45 2003
+++ b/drivers/block/as-iosched.c	Wed Nov 12 21:06:45 2003
@@ -915,9 +915,10 @@
 	if (unlikely(arq->state != AS_RQ_DISPATCHED))
 		return;
 
-	if (ad->changed_batch && ad->nr_dispatched == 1) {
-		WARN_ON(ad->batch_data_dir == arq->is_sync);
+	if (!blk_fs_request(rq))
+		return;
 
+	if (ad->changed_batch && ad->nr_dispatched == 1) {
 		kblockd_schedule_work(&ad->antic_work);
 		ad->changed_batch = 0;
 
@@ -933,7 +934,6 @@
 	 * and writeback caches
 	 */
 	if (ad->new_batch && ad->batch_data_dir == arq->is_sync) {
-		WARN_ON(ad->batch_data_dir != REQ_SYNC);
 		update_write_batch(ad);
 		ad->current_batch_expires = jiffies +
 				ad->batch_expire[REQ_SYNC];
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/block/ll_rw_blk.c	Wed Nov 12 21:06:46 2003
@@ -780,6 +780,11 @@
 	"REQ_PM_SUSPEND",
 	"REQ_PM_RESUME",
 	"REQ_PM_SHUTDOWN",
+	"REQ_IDETAPE_PC1",
+	"REQ_IDETAPE_PC2",
+	"REQ_IDETAPE_READ",
+	"REQ_IDETAPE_WRITE",
+	"REQ_IDETAPE_READ_BUFFER",
 };
 
 void blk_dump_rq_flags(struct request *rq, char *msg)
@@ -814,6 +819,7 @@
 {
 	struct bio_vec *bv, *bvprv = NULL;
 	int i, nr_phys_segs, nr_hw_segs, seg_size, cluster;
+	int high, highprv = 1;
 
 	if (unlikely(!bio->bi_io_vec))
 		return;
@@ -821,7 +827,15 @@
 	cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER);
 	seg_size = nr_phys_segs = nr_hw_segs = 0;
 	bio_for_each_segment(bv, bio, i) {
-		if (bvprv && cluster) {
+		/*
+		 * the trick here is making sure that a high page is never
+		 * considered part of another segment, since that might
+		 * change with the bounce page.
+		 */
+		high = page_to_pfn(bv->bv_page) >= q->bounce_pfn;
+		if (high || highprv)
+			goto new_hw_segment;
+		if (cluster) {
 			if (seg_size + bv->bv_len > q->max_segment_size)
 				goto new_segment;
 			if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
@@ -834,12 +848,14 @@
 			continue;
 		}
 new_segment:
-		if (!bvprv || !BIOVEC_VIRT_MERGEABLE(bvprv, bv))
+		if (!BIOVEC_VIRT_MERGEABLE(bvprv, bv))
+new_hw_segment:
 			nr_hw_segs++;
 
 		nr_phys_segs++;
 		bvprv = bv;
 		seg_size = bv->bv_len;
+		highprv = high;
 	}
 
 	bio->bi_phys_segments = nr_phys_segs;
diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
--- a/drivers/char/agp/sis-agp.c	Wed Nov 12 21:06:45 2003
+++ b/drivers/char/agp/sis-agp.c	Wed Nov 12 21:06:45 2003
@@ -142,6 +142,10 @@
 		.chipset_name	= "655",
 	},
 	{
+		.device_id	= PCI_DEVICE_ID_SI_661,
+		.chipset_name	= "661",
+	},
+	{
 		.device_id	= PCI_DEVICE_ID_SI_730,
 		.chipset_name	= "730",
 	},
@@ -154,12 +158,20 @@
 		.chipset_name	= "740",
 	},
 	{
+		.device_id	= PCI_DEVICE_ID_SI_741,
+		.chipset_name	= "741",
+	},
+	{
 		.device_id	= PCI_DEVICE_ID_SI_745,
 		.chipset_name	= "745",
 	},
 	{
 		.device_id	= PCI_DEVICE_ID_SI_746,
 		.chipset_name	= "746",
+	},
+	{
+		.device_id	= PCI_DEVICE_ID_SI_760,
+		.chipset_name	= "760",
 	},
 	{ }, /* dummy final entry, always present */
 };
diff -Nru a/drivers/char/sonypi.h b/drivers/char/sonypi.h
--- a/drivers/char/sonypi.h	Wed Nov 12 21:06:47 2003
+++ b/drivers/char/sonypi.h	Wed Nov 12 21:06:47 2003
@@ -37,7 +37,7 @@
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION	 1
-#define SONYPI_DRIVER_MINORVERSION	20
+#define SONYPI_DRIVER_MINORVERSION	21
 
 #define SONYPI_DEVICE_MODEL_TYPE1	1
 #define SONYPI_DEVICE_MODEL_TYPE2	2
@@ -329,8 +329,8 @@
 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_HELP_MASK, sonypi_helpev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_ZOOM_MASK, sonypi_zoomev },
-	{ SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
+	{ SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
 	{ SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
 
diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig
--- a/drivers/ide/Kconfig	Wed Nov 12 21:06:46 2003
+++ b/drivers/ide/Kconfig	Wed Nov 12 21:06:46 2003
@@ -428,9 +428,10 @@
 
 if BLK_DEV_IDEDMA_PCI
 
+# TCQ is disabled for now
 config BLK_DEV_IDE_TCQ
 	bool "ATA tagged command queueing (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	depends on EXPERIMENTAL && n
 	help
 	  Support for tagged command queueing on ATA disk drives. This enables
 	  the IDE layer to have multiple in-flight requests on hardware that
diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/ide/ide-tape.c	Wed Nov 12 21:06:46 2003
@@ -1210,34 +1210,11 @@
  *	In order to service a character device command, we add special
  *	requests to the tail of our block device request queue and wait
  *	for their completion.
- *
- */
-#define IDETAPE_FIRST_RQ		90
-
-/*
- * 	IDETAPE_PC_RQ is used to queue a packet command in the request queue.
- */
-#define IDETAPE_PC_RQ1			90
-#define IDETAPE_PC_RQ2			91
-
-/*
- *	IDETAPE_READ_RQ and IDETAPE_WRITE_RQ are used by our
- *	character device interface to request read/write operations from
- *	our block device interface.
  */
-#define IDETAPE_READ_RQ			92
-#define IDETAPE_WRITE_RQ		93
-#define IDETAPE_ABORTED_WRITE_RQ	94
-#define IDETAPE_ABORTED_READ_RQ		95
-#define IDETAPE_READ_BUFFER_RQ		96
-
-#define IDETAPE_LAST_RQ			96
-
-/*
- *	A macro which can be used to check if a we support a given
- *	request command.
- */
-#define IDETAPE_RQ_CMD(cmd) 		((cmd >= IDETAPE_FIRST_RQ) && (cmd <= IDETAPE_LAST_RQ))
+#define idetape_request(rq) \
+	((rq)->flags & (REQ_IDETAPE_PC1 | REQ_IDETAPE_PC2 | \
+			REQ_IDETAPE_READ | REQ_IDETAPE_WRITE | \
+			REQ_IDETAPE_READ_BUFFER))
 
 /*
  *	Error codes which are returned in rq->errors to the higher part
@@ -1891,7 +1868,7 @@
 		tape->active_stage = NULL;
 		tape->active_data_request = NULL;
 		tape->nr_pending_stages--;
-		if (rq->flags == IDETAPE_WRITE_RQ) {
+		if (rq->flags & REQ_IDETAPE_WRITE) {
 #if ONSTREAM_DEBUG
 			if (tape->debug_level >= 2) {
 				if (tape->onstream) {
@@ -1937,7 +1914,7 @@
 					}
 				}
 			}
-		} else if (rq->flags == IDETAPE_READ_RQ) {
+		} else if (rq->flags & REQ_IDETAPE_READ) {
 			if (error == IDETAPE_ERROR_EOD) {
 				set_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
 				idetape_abort_pipeline(drive, active_stage);
@@ -2016,9 +1993,9 @@
  */
 static void idetape_queue_pc_head (ide_drive_t *drive, idetape_pc_t *pc,struct request *rq)
 {
-	ide_init_drive_cmd(rq);
+	memset(rq, 0, sizeof(*rq));
+	rq->flags = REQ_IDETAPE_PC1;
 	rq->buffer = (char *) pc;
-	rq->flags = IDETAPE_PC_RQ1;
 	(void) ide_do_drive_cmd(drive, rq, ide_preempt);
 }
 
@@ -2711,7 +2688,7 @@
 					  struct request *rq, sector_t block)
 {
 	idetape_tape_t *tape = drive->driver_data;
-	idetape_pc_t *pc;
+	idetape_pc_t *pc = NULL;
 	struct request *postponed_rq = tape->postponed_rq;
 	atapi_status_t status;
 
@@ -2728,7 +2705,7 @@
 			rq->sector, rq->nr_sectors, rq->current_nr_sectors);
 #endif /* IDETAPE_DEBUG_LOG */
 
-	if (!IDETAPE_RQ_CMD(rq->flags)) {
+	if (!idetape_request(rq)) {
 		/*
 		 * We do not support buffer cache originated requests.
 		 */
@@ -2769,7 +2746,7 @@
 	 */
 	if (tape->onstream)
 		status.b.dsc = 1;
-	if (!drive->dsc_overlap && rq->flags != IDETAPE_PC_RQ2)
+	if (!drive->dsc_overlap && !(rq->flags & REQ_IDETAPE_PC2))
 		set_bit(IDETAPE_IGNORE_DSC, &tape->flags);
 
 	/*
@@ -2783,7 +2760,7 @@
 	if (tape->tape_still_time > 100 && tape->tape_still_time < 200)
 		tape->measure_insert_time = 1;
 	if (tape->req_buffer_fill &&
-	    (rq->flags == IDETAPE_WRITE_RQ || rq->flags == IDETAPE_READ_RQ)) {
+	    (rq->flags & (REQ_IDETAPE_WRITE | REQ_IDETAPE_READ))) {
 		tape->req_buffer_fill = 0;
 		tape->writes_since_buffer_fill = 0;
 		tape->reads_since_buffer_fill = 0;
@@ -2797,12 +2774,12 @@
 		tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time);
 	calculate_speeds(drive);
 	if (tape->onstream && tape->max_frames &&
-	    ((rq->flags == IDETAPE_WRITE_RQ &&
+	    (((rq->flags & REQ_IDETAPE_WRITE) &&
               ( tape->cur_frames == tape->max_frames ||
                 ( tape->speed_control && tape->cur_frames > 5 &&
                        (tape->insert_speed > tape->max_insert_speed ||
                         (0 /* tape->cur_frames > 30 && tape->tape_still_time > 200 */) ) ) ) ) ||
-	     (rq->flags == IDETAPE_READ_RQ &&
+	     ((rq->flags & REQ_IDETAPE_READ) &&
 	      ( tape->cur_frames == 0 ||
 		( tape->speed_control && (tape->cur_frames < tape->max_frames - 5) &&
 			tape->insert_speed > tape->max_insert_speed ) ) && rq->nr_sectors) ) ) {
@@ -2831,7 +2808,7 @@
 		} else if ((signed long) (jiffies - tape->dsc_timeout) > 0) {
 			printk(KERN_ERR "ide-tape: %s: DSC timeout\n",
 				tape->name);
-			if (rq->flags == IDETAPE_PC_RQ2) {
+			if (rq->flags & REQ_IDETAPE_PC2) {
 				idetape_media_access_finished(drive);
 				return ide_stopped;
 			} else {
@@ -2842,69 +2819,59 @@
 		idetape_postpone_request(drive);
 		return ide_stopped;
 	}
-	switch (rq->flags) {
-		case IDETAPE_READ_RQ:
-			tape->buffer_head++;
+	if (rq->flags & REQ_IDETAPE_READ) {
+		tape->buffer_head++;
 #if USE_IOTRACE
-			IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor);
+		IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor);
 #endif
-			tape->postpone_cnt = 0;
-			tape->reads_since_buffer_fill++;
-			if (tape->onstream) {
-				if (tape->cur_frames - tape->reads_since_buffer_fill <= 0)
-					tape->req_buffer_fill = 1;
-				if (time_after(jiffies, tape->last_buffer_fill + 5 * HZ / 100))
-					tape->req_buffer_fill = 1;
-			}
-			pc = idetape_next_pc_storage(drive);
-			idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
-			break;
-		case IDETAPE_WRITE_RQ:
-			tape->buffer_head++;
+		tape->postpone_cnt = 0;
+		tape->reads_since_buffer_fill++;
+		if (tape->onstream) {
+			if (tape->cur_frames - tape->reads_since_buffer_fill <= 0)
+				tape->req_buffer_fill = 1;
+			if (time_after(jiffies, tape->last_buffer_fill + 5 * HZ / 100))
+				tape->req_buffer_fill = 1;
+		}
+		pc = idetape_next_pc_storage(drive);
+		idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
+		goto out;
+	}
+	if (rq->flags & REQ_IDETAPE_WRITE) {
+		tape->buffer_head++;
 #if USE_IOTRACE
-			IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor);
-#endif
-			tape->postpone_cnt = 0;
-			tape->writes_since_buffer_fill++;
-			if (tape->onstream) {
-				if (tape->cur_frames + tape->writes_since_buffer_fill >= tape->max_frames)
-					tape->req_buffer_fill = 1;
-				if (time_after(jiffies, tape->last_buffer_fill + 5 * HZ / 100))
-					tape->req_buffer_fill = 1;
-				calculate_speeds(drive);
-			}
-			pc = idetape_next_pc_storage(drive);
-			idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
-			break;
-		case IDETAPE_READ_BUFFER_RQ:
-			tape->postpone_cnt = 0;
-			pc = idetape_next_pc_storage(drive);
-			idetape_create_read_buffer_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
-			break;
-		case IDETAPE_ABORTED_WRITE_RQ:
-			rq->flags = IDETAPE_WRITE_RQ;
-			idetape_end_request(drive, IDETAPE_ERROR_EOD, 0);
-			return ide_stopped;
-		case IDETAPE_ABORTED_READ_RQ:
-#if IDETAPE_DEBUG_LOG
-			if (tape->debug_level >= 2)
-				printk(KERN_INFO "ide-tape: %s: detected aborted read rq\n", tape->name);
+		IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor);
 #endif
-			rq->flags = IDETAPE_READ_RQ;
-			idetape_end_request(drive, IDETAPE_ERROR_EOD, 0);
-			return ide_stopped;
-		case IDETAPE_PC_RQ1:
-			pc = (idetape_pc_t *) rq->buffer;
-			rq->flags = IDETAPE_PC_RQ2;
-			break;
-		case IDETAPE_PC_RQ2:
-			idetape_media_access_finished(drive);
-			return ide_stopped;
-		default:
-			printk(KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n");
-			idetape_end_request(drive, 0, 0);
-			return ide_stopped;
+		tape->postpone_cnt = 0;
+		tape->writes_since_buffer_fill++;
+		if (tape->onstream) {
+			if (tape->cur_frames + tape->writes_since_buffer_fill >= tape->max_frames)
+				tape->req_buffer_fill = 1;
+			if (time_after(jiffies, tape->last_buffer_fill + 5 * HZ / 100))
+				tape->req_buffer_fill = 1;
+			calculate_speeds(drive);
+		}
+		pc = idetape_next_pc_storage(drive);
+		idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
+		goto out;
+	}
+	if (rq->flags & REQ_IDETAPE_READ_BUFFER) {
+		tape->postpone_cnt = 0;
+		pc = idetape_next_pc_storage(drive);
+		idetape_create_read_buffer_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special);
+		goto out;
+	}
+	if (rq->flags & REQ_IDETAPE_PC1) {
+		pc = (idetape_pc_t *) rq->buffer;
+		rq->flags &= ~(REQ_IDETAPE_PC1);
+		rq->flags |= REQ_IDETAPE_PC2;
+		goto out;
 	}
+	if (rq->flags & REQ_IDETAPE_PC2) {
+		idetape_media_access_finished(drive);
+		return ide_stopped;
+	}
+	BUG();
+out:
 	return idetape_issue_packet_command(drive, pc);
 }
 
@@ -3196,7 +3163,7 @@
 	idetape_tape_t *tape = drive->driver_data;
 
 #if IDETAPE_DEBUG_BUGS
-	if (rq == NULL || !IDETAPE_RQ_CMD(rq->flags)) {
+	if (rq == NULL || !idetape_request(rq)) {
 		printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid request\n");
 		return;
 	}
@@ -3302,9 +3269,9 @@
 {
 	struct request rq;
 
-	ide_init_drive_cmd(&rq);
+	memset(&rq, 0, sizeof(rq));
+	rq.flags = REQ_IDETAPE_PC1;
 	rq.buffer = (char *) pc;
-	rq.flags = IDETAPE_PC_RQ1;
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
@@ -3579,16 +3546,16 @@
 	}
 #endif /* IDETAPE_DEBUG_BUGS */	
 
-	ide_init_drive_cmd(&rq);
-	rq.special = (void *)bh;
+	memset(&rq, 0, sizeof(rq));
 	rq.flags = cmd;
+	rq.special = (void *)bh;
 	rq.sector = tape->first_frame_position;
 	rq.nr_sectors = rq.current_nr_sectors = blocks;
 	if (tape->onstream)
 		tape->postpone_cnt = 600;
 	(void) ide_do_drive_cmd(drive, &rq, ide_wait);
 
-	if (cmd != IDETAPE_READ_RQ && cmd != IDETAPE_WRITE_RQ)
+	if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0)
 		return 0;
 
 	if (tape->merge_stage)
@@ -3623,14 +3590,14 @@
 			first = stage;
 		aux = stage->aux;
 		p = stage->bh->b_data;
-		idetape_queue_rw_tail(drive, IDETAPE_READ_BUFFER_RQ, tape->capabilities.ctl, stage->bh);
+		idetape_queue_rw_tail(drive, REQ_IDETAPE_READ_BUFFER, tape->capabilities.ctl, stage->bh);
 #if ONSTREAM_DEBUG
 		if (tape->debug_level >= 2)
 			printk(KERN_INFO "ide-tape: %s: read back logical block %d, data %x %x %x %x\n", tape->name, logical_blk_num, *p++, *p++, *p++, *p++);
 #endif
 		rq = &stage->rq;
-		ide_init_drive_cmd(rq);
-		rq->flags = IDETAPE_WRITE_RQ;
+		memset(rq, 0, sizeof(*rq));
+		rq->flags = REQ_IDETAPE_WRITE;
 		rq->sector = tape->first_frame_position;
 		rq->nr_sectors = rq->current_nr_sectors = tape->capabilities.ctl;
 		idetape_init_stage(drive, stage, OS_FRAME_TYPE_DATA, logical_blk_num++);
@@ -3900,12 +3867,12 @@
 			 *	Linux is short on memory. Fallback to
 			 *	non-pipelined operation mode for this request.
 			 */
-			return idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, blocks, tape->merge_stage->bh);
+			return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, tape->merge_stage->bh);
 		}
 	}
 	rq = &new_stage->rq;
-	ide_init_drive_cmd(rq);
-	rq->flags = IDETAPE_WRITE_RQ;
+	memset(rq, 0, sizeof(*rq));
+	rq->flags = REQ_IDETAPE_WRITE;
 	/* Doesn't actually matter - We always assume sequential access */
 	rq->sector = tape->first_frame_position;
 	rq->nr_sectors = rq->current_nr_sectors = blocks;
@@ -4093,7 +4060,7 @@
 		 *	is switched from completion mode to buffer available
 		 *	mode.
 		 */
-		bytes_read = idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 0, tape->merge_stage->bh);
+		bytes_read = idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 0, tape->merge_stage->bh);
 		if (bytes_read < 0) {
 			__idetape_kfree_stage(tape->merge_stage);
 			tape->merge_stage = NULL;
@@ -4103,8 +4070,8 @@
 	}
 	if (tape->restart_speed_control_req)
 		idetape_restart_speed_control(drive);
-	ide_init_drive_cmd(&rq);
-	rq.flags = IDETAPE_READ_RQ;
+	memset(&rq, 0, sizeof(rq));
+	rq.flags = REQ_IDETAPE_READ;
 	rq.sector = tape->first_frame_position;
 	rq.nr_sectors = rq.current_nr_sectors = blocks;
 	if (!test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags) &&
@@ -4242,7 +4209,7 @@
 		}
 		if (test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags))
 		 	return 0;
-		return idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, blocks, tape->merge_stage->bh);
+		return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, tape->merge_stage->bh);
 	}
 	rq_ptr = &tape->first_stage->rq;
 	bytes_read = tape->tape_block_size * (rq_ptr->nr_sectors - rq_ptr->current_nr_sectors);
@@ -4308,7 +4275,7 @@
 			count -= atomic_read(&bh->b_count);
 			bh = bh->b_reqnext;
 		}
-		idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, blocks, tape->merge_stage->bh);
+		idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, tape->merge_stage->bh);
 	}
 }
 
@@ -4788,7 +4755,7 @@
 			"tape block %d\n", tape->last_frame_position);
 #endif
 	idetape_position_tape(drive, last_mark_addr, 0, 0);
-	if (!idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 1, stage->bh)) {
+	if (!idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 1, stage->bh)) {
 		printk(KERN_INFO "ide-tape: %s: couldn't read last marker\n",
 			tape->name);
 		__idetape_kfree_stage(stage);
@@ -4809,7 +4776,7 @@
 #endif
 	aux->next_mark_addr = htonl(next_mark_addr);
 	idetape_position_tape(drive, last_mark_addr, 0, 0);
-	if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bh)) {
+	if (!idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 1, stage->bh)) {
 		printk(KERN_INFO "ide-tape: %s: couldn't write back marker "
 			"frame at %d\n", tape->name, last_mark_addr);
 		__idetape_kfree_stage(stage);
@@ -4845,7 +4812,7 @@
 
 	strcpy(stage->bh->b_data, "Filler");
 	while (cnt--) {
-		if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bh)) {
+		if (!idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 1, stage->bh)) {
 			printk(KERN_INFO "ide-tape: %s: write_filler: "
 				"couldn't write header frame\n", tape->name);
 			__idetape_kfree_stage(stage);
@@ -4880,7 +4847,7 @@
 	header.partition.eod_frame_addr = htonl(tape->eod_frame_addr);
 	memcpy(stage->bh->b_data, &header, sizeof(header));
 	while (cnt--) {
-		if (!idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 1, stage->bh)) {
+		if (!idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 1, stage->bh)) {
 			printk(KERN_INFO "ide-tape: %s: couldn't write "
 				"header frame\n", tape->name);
 			__idetape_kfree_stage(stage);
@@ -5013,7 +4980,7 @@
 		 *	is switched from completion mode to buffer available
 		 *	mode.
 		 */
-		retval = idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 0, tape->merge_stage->bh);
+		retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_stage->bh);
 		if (retval < 0) {
 			__idetape_kfree_stage(tape->merge_stage);
 			tape->merge_stage = NULL;
@@ -5487,7 +5454,7 @@
 		printk(KERN_INFO "ide-tape: %s: reading header\n", tape->name);
 #endif
 	idetape_position_tape(drive, block, 0, 0);
-	if (!idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 1, stage->bh)) {
+	if (!idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 1, stage->bh)) {
 		printk(KERN_INFO "ide-tape: %s: couldn't read header frame\n",
 			tape->name);
 		__idetape_kfree_stage(stage);
@@ -5581,6 +5548,7 @@
 		return -ENXIO;
 	drive = idetape_chrdevs[i].drive;
 	tape = drive->driver_data;
+	filp->private_data = drive;
 
 	if (test_and_set_bit(IDETAPE_BUSY, &tape->flags))
 		return -EBUSY;
diff -Nru a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
--- a/drivers/ide/pci/alim15x3.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/ide/pci/alim15x3.c	Wed Nov 12 21:06:46 2003
@@ -634,23 +634,25 @@
 	        return 0;
 	}
 
-	/*
-	 * set south-bridge's enable bit, m1533, 0x79
-	 */
-
-	pci_read_config_byte(isa_dev, 0x79, &tmpbyte);
-	if (m5229_revision == 0xC2) {
-		/*
-		 * 1543C-B0 (m1533, 0x79, bit 2)
-		 */
-		pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04);
-	} else if (m5229_revision >= 0xC3) {
+	if (m5229_revision < 0xC5 && isa_dev)
+	{	
 		/*
-		 * 1553/1535 (m1533, 0x79, bit 1)
+		 * set south-bridge's enable bit, m1533, 0x79
 		 */
-		pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
-	}
 
+		pci_read_config_byte(isa_dev, 0x79, &tmpbyte);
+		if (m5229_revision == 0xC2) {
+			/*
+			 * 1543C-B0 (m1533, 0x79, bit 2)
+			 */
+			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04);
+		} else if (m5229_revision >= 0xC3) {
+			/*
+			 * 1553/1535 (m1533, 0x79, bit 1)
+			 */
+			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
+		}
+	}
 	local_irq_restore(flags);
 	return 0;
 }
diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
--- a/drivers/ide/pci/amd74xx.c	Wed Nov 12 21:06:48 2003
+++ b/drivers/ide/pci/amd74xx.c	Wed Nov 12 21:06:48 2003
@@ -1,7 +1,7 @@
 /*
- * Version 2.11
+ * Version 2.13
  *
- * AMD 755/756/766/8111 and nVidia nForce IDE driver for Linux.
+ * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s IDE driver for Linux.
  *
  * Copyright (c) 2000-2002 Vojtech Pavlik
  *
@@ -40,9 +40,11 @@
 #define AMD_UDMA_33		0x01
 #define AMD_UDMA_66		0x02
 #define AMD_UDMA_100		0x03
+#define AMD_UDMA_133		0x04
 #define AMD_CHECK_SWDMA		0x08
 #define AMD_BAD_SWDMA		0x10
 #define AMD_BAD_FIFO		0x20
+#define AMD_CHECK_SERENADE	0x40
 
 /*
  * AMD SouthBridge chips.
@@ -50,27 +52,33 @@
 
 static struct amd_ide_chip {
 	unsigned short id;
-	unsigned char rev;
 	unsigned long base;
 	unsigned char flags;
 } amd_ide_chips[] = {
-	{ PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA },	/* AMD-755 Cobra */
-	{ PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA },	/* AMD-756 Viper */
-	{ PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO },	/* AMD-766 Viper */
-	{ PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 },			/* AMD-768 Opus */
-	{ PCI_DEVICE_ID_AMD_8111_IDE,  0x00, 0x40, AMD_UDMA_100 },			/* AMD-8111 */
-        { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x00, 0x50, AMD_UDMA_100 },                  /* nVidia nForce */
-	{ PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x00, 0x50, AMD_UDMA_100 },			/* nVidia nForce 2 */
+	{ PCI_DEVICE_ID_AMD_COBRA_7401,		0x40, AMD_UDMA_33 | AMD_BAD_SWDMA },
+	{ PCI_DEVICE_ID_AMD_VIPER_7409,		0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA },
+	{ PCI_DEVICE_ID_AMD_VIPER_7411,		0x40, AMD_UDMA_100 | AMD_BAD_FIFO },
+	{ PCI_DEVICE_ID_AMD_OPUS_7441,		0x40, AMD_UDMA_100 },
+	{ PCI_DEVICE_ID_AMD_8111_IDE,		0x40, AMD_UDMA_133 | AMD_CHECK_SERENADE },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,	0x50, AMD_UDMA_100 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,	0x50, AMD_UDMA_133 },
 	{ 0 }
 };
 
 static struct amd_ide_chip *amd_config;
+static ide_pci_device_t *amd_chipset;
 static unsigned int amd_80w;
 static unsigned int amd_clock;
 
-static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3 };
-static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 1 };
-static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100" };
+static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 };
+static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 15 };
+static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
 
 /*
  * AMD /proc entry.
@@ -102,7 +110,7 @@
 
 	amd_print("----------AMD BusMastering IDE Configuration----------------");
 
-	amd_print("Driver Version:                     2.11");
+	amd_print("Driver Version:                     2.13");
 	amd_print("South Bridge:                       %s", pci_name(bmide_dev));
 
 	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
@@ -153,6 +161,12 @@
 			continue;
 		}
 
+		if (den[i] && uen[i] && udma[i] == 15) {
+			speed[i] = amd_clock * 4;
+			cycle[i] = 500000 / amd_clock;
+			continue;
+		}
+
 		speed[i] = 4 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2);
 		cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2;
 	}
@@ -198,6 +212,7 @@
 		case AMD_UDMA_33:  t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
 		case AMD_UDMA_66:  t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break;
 		case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break;
+		case AMD_UDMA_133: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break;
 		default: return;
 	}
 
@@ -232,6 +247,7 @@
 	}
 
 	if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1;
+	if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15;
 
 	amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
 
@@ -271,7 +287,8 @@
 		XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA |
 		((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
 		(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
-		(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0));
+		(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0) |
+		(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_133 ? XFER_UDMA_133 : 0));
 
 	amd_set_drive(drive, speed);
 
@@ -307,13 +324,15 @@
 
 	switch (amd_config->flags & AMD_UDMA) {
 
+		case AMD_UDMA_133:
 		case AMD_UDMA_100:
 			pci_read_config_byte(dev, AMD_CABLE_DETECT, &t);
 			pci_read_config_dword(dev, AMD_UDMA_TIMING, &u);
 			amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0);
 			for (i = 24; i >= 0; i -= 8)
 				if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) {
-					printk(KERN_WARNING "AMD_IDE: Bios didn't set cable bits correctly. Enabling workaround.\n");
+					printk(KERN_WARNING "%s: BIOS didn't set cable bits correctly. Enabling workaround.\n",
+						amd_chipset->name);
 					amd_80w |= (1 << (1 - (i >> 4)));
 				}
 			break;
@@ -335,6 +354,15 @@
 		(amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0));
 
 /*
+ * Take care of incorrectly wired Serenade mainboards.
+ */
+
+	if ((amd_config->flags & AMD_CHECK_SERENADE) &&
+		dev->subsystem_vendor == PCI_VENDOR_ID_AMD &&
+		dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE)
+			amd_config->flags = AMD_UDMA_100;
+
+/*
  * Determine the system bus clock.
  */
 
@@ -347,8 +375,10 @@
 	}
 
 	if (amd_clock < 20000 || amd_clock > 50000) {
-		printk(KERN_WARNING "AMD_IDE: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", amd_clock);
-		printk(KERN_WARNING "AMD_IDE: Use ide0=ata66 if you want to assume 80-wire cable\n");
+		printk(KERN_WARNING "%s: User given PCI clock speed impossible (%d), using 33 MHz instead.\n",
+			amd_chipset->name, amd_clock);
+		printk(KERN_WARNING "%s: Use ide0=ata66 if you want to assume 80-wire cable\n",
+			amd_chipset->name);
 		amd_clock = 33333;
 	}
 
@@ -357,8 +387,8 @@
  */
 
 	pci_read_config_byte(dev, PCI_REVISION_ID, &t);
-	printk(KERN_INFO "AMD_IDE: %s (rev %02x) %s controller on pci%s\n",
-		pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA], pci_name(dev));
+	printk(KERN_INFO "%s: %s (rev %02x) %s controller\n",
+		amd_chipset->name, pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA]);
 
 /*
  * Register /proc/ide/amd74xx entry
@@ -373,8 +403,7 @@
         }
 #endif /* DISPLAY_AMD_TIMINGS && CONFIG_PROC_FS */
 
-
-	return 0;
+	return dev->irq;
 }
 
 static void __init init_hwif_amd74xx(ide_hwif_t *hwif)
@@ -414,23 +443,29 @@
 
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	ide_pci_device_t *d = amd74xx_chipsets + id->driver_data;
+	amd_chipset = amd74xx_chipsets + id->driver_data;
 	amd_config = amd_ide_chips + id->driver_data;
-	if (dev->device != d->device) BUG();
+	if (dev->device != amd_chipset->device) BUG();
 	if (dev->device != amd_config->id) BUG();
-	ide_setup_pci_device(dev, d);
+	ide_setup_pci_device(dev, amd_chipset);
 	MOD_INC_USE_COUNT;
 	return 0;
 }
 
 static struct pci_device_id amd74xx_pci_tbl[] = {
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
-	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, 	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_COBRA_7401,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  0 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7409,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  1 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7411,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  2 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_OPUS_7441,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  3 },
+	{ PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8111_IDE,		PCI_ANY_ID, PCI_ANY_ID, 0, 0,  4 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  5 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  6 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  7 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  8 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0,  9 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
 	{ 0, },
 };
 
diff -Nru a/drivers/ide/pci/amd74xx.h b/drivers/ide/pci/amd74xx.h
--- a/drivers/ide/pci/amd74xx.h	Wed Nov 12 21:06:45 2003
+++ b/drivers/ide/pci/amd74xx.h	Wed Nov 12 21:06:45 2003
@@ -109,6 +109,72 @@
 		.bootable	= ON_BOARD,
 		.extra		= 0,
 	},
+	{	/* 7 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE,
+		.name		= "NFORCE2S",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 8 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
+		.name		= "NFORCE2S-SATA",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 9 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE,
+		.name		= "NFORCE3",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 10 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE,
+		.name		= "NFORCE3S",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 11 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
+		.name		= "NFORCE3S-SATA",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
+	{	/* 12 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,
+		.name		= "NFORCE3S-SATA2",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_hwif	= init_hwif_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x02,0x02}, {0x50,0x01,0x01}},
+		.bootable	= ON_BOARD,
+	},
 	{
 		.vendor		= 0,
 		.device		= 0,
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/input/keyboard/atkbd.c	Wed Nov 12 21:06:47 2003
@@ -184,11 +184,19 @@
 		atkbd->resend = 0;
 #endif
 
+	switch (code) {
+		case ATKBD_RET_ACK:
+			atkbd->ack = 1;
+			goto out;
+		case ATKBD_RET_NAK:
+			atkbd->ack = -1;
+			goto out;
+	}
+
 	if (atkbd->translated) do {
 
 		if (atkbd->emul != 1) {
-			if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 ||
-			    code == ATKBD_RET_ACK || code == ATKBD_RET_NAK)
+			if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1)
 				break;
 			if (code == ATKBD_RET_BAT) {
 				if (!atkbd->bat_xl)
@@ -211,15 +219,6 @@
 		atkbd->release = 1;
 
 	} while (0);
-
-	switch (code) {
-		case ATKBD_RET_ACK:
-			atkbd->ack = 1;
-			goto out;
-		case ATKBD_RET_NAK:
-			atkbd->ack = -1;
-			goto out;
-	}
 
 	if (atkbd->cmdcnt) {
 		atkbd->cmdbuf[--atkbd->cmdcnt] = code;
diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/input/mouse/psmouse-base.c	Wed Nov 12 21:06:46 2003
@@ -36,12 +36,10 @@
 MODULE_PARM_DESC(psmouse_resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never).");
 MODULE_LICENSE("GPL");
 
-#define PSMOUSE_LOGITECH_SMARTSCROLL	1
-
 static int psmouse_noext;
-int psmouse_resolution;
-unsigned int psmouse_rate = 60;
-int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL;
+int psmouse_resolution = 200;
+unsigned int psmouse_rate = 100;
+int psmouse_smartscroll = 1;
 unsigned int psmouse_resetafter;
 
 static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
@@ -466,19 +464,15 @@
 {
 	unsigned char param[2];
 	
-
-/*
- * We set the mouse report rate.
- */
-
-	psmouse_set_rate(psmouse);
-
 /*
- * We also set the resolution and scaling.
+ * We set the mouse report rate, resolution and scaling.
  */
 
-	psmouse_set_resolution(psmouse);
-	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+	if (!psmouse_noext) {
+		psmouse_set_rate(psmouse);
+		psmouse_set_resolution(psmouse);
+		psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
+	}
 
 /*
  * We set the mouse into streaming mode.
@@ -651,10 +645,17 @@
 	return 1;
 }
 
+static int __init psmouse_rate_setup(char *str)
+{
+	get_option(&str, &psmouse_rate);
+	return 1;
+}
+
 __setup("psmouse_noext", psmouse_noext_setup);
 __setup("psmouse_resolution=", psmouse_resolution_setup);
 __setup("psmouse_smartscroll=", psmouse_smartscroll_setup);
 __setup("psmouse_resetafter=", psmouse_resetafter_setup);
+__setup("psmouse_rate=", psmouse_rate_setup);
 
 #endif
 
diff -Nru a/drivers/md/dm-table.c b/drivers/md/dm-table.c
--- a/drivers/md/dm-table.c	Wed Nov 12 21:06:48 2003
+++ b/drivers/md/dm-table.c	Wed Nov 12 21:06:48 2003
@@ -489,6 +489,18 @@
 		rs->max_sectors =
 			min_not_zero(rs->max_sectors, q->max_sectors);
 
+		/* FIXME: Device-Mapper on top of RAID-0 breaks because DM
+		 *        currently doesn't honor MD's merge_bvec_fn routine.
+		 *        In this case, we'll force DM to use PAGE_SIZE or
+		 *        smaller I/O, just to be safe. A better fix is in the
+		 *        works, but add this for the time being so it will at
+		 *        least operate correctly.
+		 */
+		if (q->merge_bvec_fn)
+			rs->max_sectors =
+				min_not_zero(rs->max_sectors,
+					     (unsigned short)(PAGE_SIZE >> 9));
+
 		rs->max_phys_segments =
 			min_not_zero(rs->max_phys_segments,
 				     q->max_phys_segments);
diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c
--- a/drivers/md/raid1.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/md/raid1.c	Wed Nov 12 21:06:46 2003
@@ -841,7 +841,7 @@
 	}
 
 	if (atomic_dec_and_test(&r1_bio->remaining)) {
-		md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 0);
+		md_done_sync(mddev, r1_bio->master_bio->bi_size >> 9, 1);
 		put_buf(r1_bio);
 	}
 }
diff -Nru a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
--- a/drivers/media/video/bt832.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/media/video/bt832.c	Wed Nov 12 21:06:47 2003
@@ -187,7 +187,6 @@
         t->client.data = t;
         i2c_attach_client(&t->client);
 
-	MOD_INC_USE_COUNT;
 	if(! bt832_init(&t->client)) {
 		bt832_detach(&t->client);
 		return -1;
@@ -210,7 +209,6 @@
 	printk("bt832: detach.\n");
 	i2c_detach_client(client);
 	kfree(t);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
--- a/drivers/media/video/bttv-cards.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/media/video/bttv-cards.c	Wed Nov 12 21:06:46 2003
@@ -2439,8 +2439,8 @@
         { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
         { TUNER_PHILIPS_FQ1216ME,   "Philips FQ1216 ME" },
         { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
-        { TUNER_ABSENT,        "Philips TD1536" },
-        { TUNER_ABSENT,        "Philips TD1536D" },
+        { TUNER_PHILIPS_NTSC,        "Philips TD1536" },
+        { TUNER_PHILIPS_NTSC,        "Philips TD1536D" },
 	{ TUNER_PHILIPS_NTSC,  "Philips FMR1236" }, /* mono radio */
         { TUNER_ABSENT,        "Philips FI1256MP" },
         { TUNER_ABSENT,        "Samsung TCPQ9091P" },
diff -Nru a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
--- a/drivers/media/video/bttv-if.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/media/video/bttv-if.c	Wed Nov 12 21:06:46 2003
@@ -247,7 +247,7 @@
 bttv_i2c_wait_done(struct bttv *btv)
 {
 	u32 stat;
-	int timeout;
+	unsigned long timeout;
 
 	timeout = jiffies + HZ/100 + 1; /* 10ms */
 	for (;;) {
diff -Nru a/drivers/media/video/meye.h b/drivers/media/video/meye.h
--- a/drivers/media/video/meye.h	Wed Nov 12 21:06:46 2003
+++ b/drivers/media/video/meye.h	Wed Nov 12 21:06:46 2003
@@ -31,7 +31,7 @@
 #define _MEYE_PRIV_H_
 
 #define MEYE_DRIVER_MAJORVERSION	1
-#define MEYE_DRIVER_MINORVERSION	7
+#define MEYE_DRIVER_MINORVERSION	8
 
 #include <linux/config.h>
 #include <linux/types.h>
diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
--- a/drivers/media/video/saa5249.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/media/video/saa5249.c	Wed Nov 12 21:06:47 2003
@@ -214,7 +214,6 @@
 	}
 	t->client = client;
 	i2c_attach_client(client);
-	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -237,7 +236,6 @@
 	kfree(vd->priv);
 	kfree(vd);
 	kfree(client);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
diff -Nru a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
--- a/drivers/media/video/tuner-3036.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/media/video/tuner-3036.c	Wed Nov 12 21:06:46 2003
@@ -134,7 +134,6 @@
 	printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client));
 
         i2c_attach_client(client);
-	MOD_INC_USE_COUNT;
 
 	if (i2c_master_send(client, buffer, 2) != 2)
 		printk("tuner: i2c i/o error 1\n");
@@ -148,7 +147,6 @@
 static int 
 tuner_detach(struct i2c_client *c)
 {
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	Wed Nov 12 21:06:45 2003
+++ b/drivers/net/3c509.c	Wed Nov 12 21:06:45 2003
@@ -74,7 +74,9 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#ifdef CONFIG_MCA
 #include <linux/mca.h>
+#endif
 #include <linux/isapnp.h>
 #include <linux/string.h>
 #include <linux/interrupt.h>
diff -Nru a/drivers/net/3c527.c b/drivers/net/3c527.c
--- a/drivers/net/3c527.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/net/3c527.c	Wed Nov 12 21:06:47 2003
@@ -109,6 +109,8 @@
 
 #include "3c527.h"
 
+MODULE_LICENSE("GPL");
+
 /*
  * The name of the card. Is used for messages and in the requests for
  * io regions, irqs and dma channels
diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c
--- a/drivers/net/8139cp.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/8139cp.c	Wed Nov 12 21:06:46 2003
@@ -615,8 +615,8 @@
 		if (cpr16(IntrStatus) & cp_rx_intr_mask)
 			goto rx_status_loop;
 
-		cpw16_f(IntrMask, cp_intr_mask);
 		netif_rx_complete(dev);
+		cpw16_f(IntrMask, cp_intr_mask);
 
 		return 0;	/* done */
 	}
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Wed Nov 12 21:06:45 2003
+++ b/drivers/net/8139too.c	Wed Nov 12 21:06:45 2003
@@ -245,6 +245,7 @@
 	{0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x1259, 0xa11e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/Space.c	Wed Nov 12 21:06:46 2003
@@ -422,7 +422,7 @@
 extern int loopback_init(void);
 
 /*  Statically configured drivers -- order matters here. */
-void __init probe_old_netdevs(void)
+static int __init net_olddevs_init(void)
 {
 	int num;
 
@@ -450,7 +450,11 @@
 #ifdef CONFIG_LTPC
 	ltpc_probe();
 #endif
+
+	return 0;
 }
+
+device_initcall(net_olddevs_init);
 
 /*
  * The @dev_base list is protected by @dev_base_lock and the rtln
diff -Nru a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
--- a/drivers/net/arm/ether1.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/net/arm/ether1.c	Wed Nov 12 21:06:47 2003
@@ -1036,13 +1036,8 @@
 		goto release;
 	}
 
-	printk(KERN_INFO "%s: ether1 in slot %d, ",
-		dev->name, ec->slot_no);
-    
-	for (i = 0; i < 6; i++) {
+	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = inb(IDPROM_ADDRESS + i);
-		printk ("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
-	}
 
 	if (ether1_init_2(dev)) {
 		ret = -ENODEV;
@@ -1060,6 +1055,12 @@
 	ret = register_netdev(dev);
 	if (ret)
 		goto release;
+
+	printk(KERN_INFO "%s: ether1 in slot %d, ",
+		dev->name, ec->slot_no);
+    
+	for (i = 0; i < 6; i++)
+		printk ("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
 
 	ecard_set_drvdata(ec, dev);
 	return 0;
diff -Nru a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
--- a/drivers/net/arm/ether3.c	Wed Nov 12 21:06:48 2003
+++ b/drivers/net/arm/ether3.c	Wed Nov 12 21:06:48 2003
@@ -881,10 +881,6 @@
 		break;
 	}
 
-	printk("%s: %s in slot %d, ", dev->name, name, ec->slot_no);
-	for (i = 0; i < 6; i++)
-		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
-
 	if (ether3_init_2(dev)) {
 		ret = -ENODEV;
 		goto failed;
@@ -901,6 +897,10 @@
 	ret = register_netdev(dev);
 	if (ret)
 		goto failed;
+
+	printk("%s: %s in slot %d, ", dev->name, name, ec->slot_no);
+	for (i = 0; i < 6; i++)
+		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
 
 	ecard_set_drvdata(ec, dev);
 	return 0;
diff -Nru a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
--- a/drivers/net/arm/etherh.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/net/arm/etherh.c	Wed Nov 12 21:06:47 2003
@@ -665,12 +665,6 @@
 		break;
 	}
 
-	printk(KERN_INFO "%s: %s in slot %d, ",
-		dev->name, dev_type, ec->slot_no);
-
-	for (i = 0; i < 6; i++)
-		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
-
 	ei_local = (struct ei_device *) dev->priv;
 	if (ec->cid.product == PROD_ANT_ETHERM) {
 		ei_local->tx_start_page = ETHERM_TX_START_PAGE;
@@ -697,6 +691,12 @@
 	ret = register_netdev(dev);
 	if (ret)
 		goto release;
+
+	printk(KERN_INFO "%s: %s in slot %d, ",
+		dev->name, dev_type, ec->slot_no);
+
+	for (i = 0; i < 6; i++)
+		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
 
 	ecard_set_drvdata(ec, dev);
 
diff -Nru a/drivers/net/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/b44.c	Wed Nov 12 21:06:46 2003
@@ -25,8 +25,8 @@
 
 #define DRV_MODULE_NAME		"b44"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.91"
-#define DRV_MODULE_RELDATE	"Oct 3, 2003"
+#define DRV_MODULE_VERSION	"0.92"
+#define DRV_MODULE_RELDATE	"Nov 4, 2003"
 
 #define B44_DEF_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
@@ -942,6 +942,8 @@
 	b44_init_hw(bp);
 	spin_unlock_irq(&bp->lock);
 
+	b44_enable_ints(bp);
+	
 	return 0;
 }
 
@@ -1558,6 +1560,8 @@
 		netif_wake_queue(bp->dev);
 		spin_unlock_irq(&bp->lock);
 
+		b44_enable_ints(bp);
+		
 		return 0;
 	}
 	case ETHTOOL_GPAUSEPARAM: {
@@ -1601,6 +1605,8 @@
 		}
 		spin_unlock_irq(&bp->lock);
 
+		b44_enable_ints(bp);
+		
 		return 0;
 	}
 	};
@@ -1752,6 +1758,7 @@
 	}
 
 	SET_MODULE_OWNER(dev);
+	SET_NETDEV_DEV(dev,&pdev->dev);
 
 	/* No interesting netdevice features in this card... */
 	dev->features |= 0;
@@ -1852,11 +1859,56 @@
 	}
 }
 
+static int b44_suspend(struct pci_dev *pdev, u32 state)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct b44 *bp = dev->priv;
+
+        if (!netif_running(dev))
+                 return 0;
+
+	del_timer_sync(&bp->timer);
+
+	spin_lock_irq(&bp->lock); 
+
+	b44_halt(bp);
+	netif_carrier_off(bp->dev); 
+	netif_device_detach(bp->dev);
+	b44_free_rings(bp);
+
+	spin_unlock_irq(&bp->lock);
+	return 0;
+}
+
+static int b44_resume(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct b44 *bp = dev->priv;
+
+	if (!netif_running(dev))
+		return 0;
+
+	spin_lock_irq(&bp->lock);
+
+	b44_init_rings(bp);
+	b44_init_hw(bp);
+	netif_device_attach(bp->dev);
+	spin_unlock_irq(&bp->lock);
+
+	bp->timer.expires = jiffies + HZ;
+	add_timer(&bp->timer);
+
+	b44_enable_ints(bp);
+	return 0;
+}
+
 static struct pci_driver b44_driver = {
 	.name		= DRV_MODULE_NAME,
 	.id_table	= b44_pci_tbl,
 	.probe		= b44_init_one,
 	.remove		= __devexit_p(b44_remove_one),
+        .suspend        = b44_suspend,
+        .resume         = b44_resume,
 };
 
 static int __init b44_init(void)
diff -Nru a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/net/bonding/bond_main.c	Wed Nov 12 21:06:47 2003
@@ -2238,8 +2238,9 @@
 static void bond_mii_monitor(struct net_device *master)
 {
 	bonding_t *bond = (struct bonding *) master->priv;
-	slave_t *slave, *bestslave, *oldcurrent;
+	slave_t *slave, *oldcurrent;
 	int slave_died = 0;
+	int do_failover = 0;
 
 	read_lock(&bond->lock);
 
@@ -2249,7 +2250,6 @@
 	 * program could monitor the link itself if needed.
 	 */
 
-	bestslave = NULL;
 	slave = (slave_t *)bond;
 
 	read_lock(&bond->ptrlock);
@@ -2257,8 +2257,6 @@
 	read_unlock(&bond->ptrlock);
 
 	while ((slave = slave->prev) != (slave_t *)bond) {
-		/* use updelay+1 to match an UP slave even when updelay is 0 */
-		int mindelay = updelay + 1;
 		struct net_device *dev = slave->dev;
 		int link_state;
 		u16 old_speed = slave->speed;
@@ -2269,14 +2267,7 @@
 		switch (slave->link) {
 		case BOND_LINK_UP:	/* the link was up */
 			if (link_state == BMSR_LSTATUS) {
-				/* link stays up, tell that this one
-				   is immediately available */
-				if (IS_UP(dev) && (mindelay > -2)) {
-					/* -2 is the best case :
-					   this slave was already up */
-					mindelay = -2;
-					bestslave = slave;
-				}
+				/* link stays up, nothing more to do */
 				break;
 			}
 			else { /* link going down */
@@ -2316,6 +2307,7 @@
 					    (bond_mode == BOND_MODE_8023AD)) {
 						bond_set_slave_inactive_flags(slave);
 					}
+
 					printk(KERN_INFO
 						"%s: link status definitely down "
 						"for interface %s, disabling it",
@@ -2332,12 +2324,10 @@
 						bond_alb_handle_link_change(bond, slave, BOND_LINK_DOWN);
 					}
 
-					write_lock(&bond->ptrlock);
-					if (slave == bond->current_slave) {
-						/* find a new interface and be verbose */
-						reselect_active_interface(bond);
+					if (slave == oldcurrent) {
+						do_failover = 1;
 					}
-					write_unlock(&bond->ptrlock);
+
 					slave_died = 1;
 				} else {
 					slave->delay--;
@@ -2352,13 +2342,6 @@
 					master->name,
 					(downdelay - slave->delay) * miimon,
 					dev->name);
-
-				if (IS_UP(dev) && (mindelay > -1)) {
-					/* -1 is a good case : this slave went
-					   down only for a short time */
-					mindelay = -1;
-					bestslave = slave;
-				}
 			}
 			break;
 		case BOND_LINK_DOWN:	/* the link was down */
@@ -2428,26 +2411,12 @@
 						bond_alb_handle_link_change(bond, slave, BOND_LINK_UP);
 					}
 
-					write_lock(&bond->ptrlock);
-					if ( (bond->primary_slave != NULL)
-					  && (slave == bond->primary_slave) )
-						reselect_active_interface(bond); 
-					write_unlock(&bond->ptrlock);
-				}
-				else
+					if ((oldcurrent == NULL) ||
+					    (slave == bond->primary_slave)) {
+						do_failover = 1;
+					}
+				} else {
 					slave->delay--;
-
-				/* we'll also look for the mostly eligible slave */
-				if (bond->primary_slave == NULL)  {
-				    if (IS_UP(dev) && (slave->delay < mindelay)) {
-					mindelay = slave->delay;
-					bestslave = slave;
-				    } 
-				} else if ( (IS_UP(bond->primary_slave->dev))  || 
-				          ( (!IS_UP(bond->primary_slave->dev))  && 
-				          (IS_UP(dev) && (slave->delay < mindelay)) ) ) {
-					mindelay = slave->delay;
-					bestslave = slave;
 				}
 			}
 			break;
@@ -2466,26 +2435,17 @@
 
 	} /* end of while */
 
-	/* 
-	 * if there's no active interface and we discovered that one
-	 * of the slaves could be activated earlier, so we do it.
-	 */
-	read_lock(&bond->ptrlock);
-	oldcurrent = bond->current_slave;
-	read_unlock(&bond->ptrlock);
+	if (do_failover) {
+		write_lock(&bond->ptrlock);
 
-	/* no active interface at the moment or need to bring up the primary */
-	if (oldcurrent == NULL)  { /* no active interface at the moment */
-		if (bestslave != NULL) { /* last chance to find one ? */
-			write_lock(&bond->ptrlock);
-			change_active_interface(bond, bestslave);
-			write_unlock(&bond->ptrlock);
-		} else if (slave_died) {
-			/* print this message only once a slave has just died */
+		reselect_active_interface(bond);
+		if (oldcurrent && !bond->current_slave) {
 			printk(KERN_INFO
 				"%s: now running without any active interface !\n",
 				master->name);
 		}
+
+		write_unlock(&bond->ptrlock);
 	}
 
 	read_unlock(&bond->lock);
@@ -2503,9 +2463,10 @@
 static void loadbalance_arp_monitor(struct net_device *master)
 {
 	bonding_t *bond;
-	slave_t *slave;
+	slave_t *slave, *oldcurrent;
 	int the_delta_in_ticks =  arp_interval * HZ / 1000;
 	int next_timer = jiffies + (arp_interval * HZ / 1000);
+	int do_failover = 0;
 
 	bond = (struct bonding *) master->priv; 
 	if (master->priv == NULL) {
@@ -2529,6 +2490,10 @@
 
 	read_lock(&bond->lock);
 
+	read_lock(&bond->ptrlock);
+	oldcurrent = bond->current_slave;
+	read_unlock(&bond->ptrlock);
+
 	/* see if any of the previous devices are up now (i.e. they have
 	 * xmt and rcv traffic). the current_slave does not come into
 	 * the picture unless it is null. also, slave->jiffies is not needed
@@ -2555,21 +2520,19 @@
 				 * current_slave being null after enslaving
 				 * is closed.
 				 */
-				write_lock(&bond->ptrlock);
-				if (bond->current_slave == NULL) {
+				if (oldcurrent == NULL) {
 					printk(KERN_INFO
 						"%s: link status definitely up "
 						"for interface %s, ",
 						master->name,
 						slave->dev->name);
-					reselect_active_interface(bond); 
+					do_failover = 1;
 				} else {
 					printk(KERN_INFO
 						"%s: interface %s is now up\n",
 						master->name,
 						slave->dev->name);
 				}
-				write_unlock(&bond->ptrlock);
 			} 
 		} else {
 			/* slave->link == BOND_LINK_UP */
@@ -2592,11 +2555,9 @@
 				       master->name,
 				       slave->dev->name);
 
-				write_lock(&bond->ptrlock);
-				if (slave == bond->current_slave) {
-					reselect_active_interface(bond);
+				if (slave == oldcurrent) {
+					do_failover = 1;
 				}
-				write_unlock(&bond->ptrlock);
 			}
 		} 
 
@@ -2610,6 +2571,19 @@
 		if (IS_UP(slave->dev)) {
 			arp_send_all(slave);
 		}
+	}
+
+	if (do_failover) {
+		write_lock(&bond->ptrlock);
+
+		reselect_active_interface(bond);
+		if (oldcurrent && !bond->current_slave) {
+			printk(KERN_INFO
+				"%s: now running without any active interface !\n",
+				master->name);
+		}
+
+		write_unlock(&bond->ptrlock);
 	}
 
 	read_unlock(&bond->lock);
diff -Nru a/drivers/net/ethertap.c b/drivers/net/ethertap.c
--- a/drivers/net/ethertap.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/ethertap.c	Wed Nov 12 21:06:46 2003
@@ -302,11 +302,12 @@
 
 static void ethertap_rx(struct sock *sk, int len)
 {
-	struct net_device *dev = tap_map[sk->sk_protocol];
+	unsigned unit = sk->sk_protocol - NETLINK_TAPBASE; 
+	struct net_device *dev;
 	struct sk_buff *skb;
 
-	if (dev==NULL) {
-		printk(KERN_CRIT "ethertap: bad unit!\n");
+	if (unit >= max_taps || (dev = tap_map[unit]) == NULL) { 
+		printk(KERN_CRIT "ethertap: bad unit %u!\n", unit);
 		skb_queue_purge(&sk->sk_receive_queue);
 		return;
 	}
diff -Nru a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
--- a/drivers/net/pcmcia/fmvj18x_cs.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/net/pcmcia/fmvj18x_cs.c	Wed Nov 12 21:06:47 2003
@@ -502,6 +502,8 @@
     }
 
     if (link->io.NumPorts2 != 0) {
+    	link->irq.Attributes =
+		IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
 	ret = mfc_try_io_port(link);
 	if (ret != CS_SUCCESS) goto cs_failed;
     } else if (cardtype == UNGERMANN) {
diff -Nru a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
--- a/drivers/net/pcmcia/ibmtr_cs.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/pcmcia/ibmtr_cs.c	Wed Nov 12 21:06:46 2003
@@ -136,7 +136,7 @@
     struct net_device	*dev;
     dev_node_t          node;
     window_handle_t     sram_win_handle;
-    struct tok_info	ti;
+    struct tok_info	*ti;
 } ibmtr_dev_t;
 
 static void netdev_get_drvinfo(struct net_device *dev,
@@ -168,13 +168,18 @@
     DEBUG(0, "ibmtr_attach()\n");
 
     /* Create new token-ring device */
-    dev = alloc_trdev(sizeof(*info));
-    if (!dev)
-	    return NULL;
-    info = dev->priv;
+    info = kmalloc(sizeof(*info), GFP_KERNEL); 
+    if (!info) return NULL;
+    memset(info,0,sizeof(*info));
+    dev = alloc_trdev(sizeof(struct tok_info));
+    if (!dev) { 
+	kfree(info); 
+	return NULL;
+    } 
 
     link = &info->link;
     link->priv = info;
+    info->ti = dev->priv; 
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts1 = 4;
@@ -265,6 +270,7 @@
     *linkp = link->next;
     unregister_netdev(dev);
     free_netdev(dev);
+    kfree(info); 
 } /* ibmtr_detach */
 
 /*======================================================================
diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
--- a/drivers/net/pcnet32.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/pcnet32.c	Wed Nov 12 21:06:46 2003
@@ -1376,6 +1376,10 @@
 		if (!rx_in_place) {
 		    skb_reserve(skb,2); /* 16 byte align */
 		    skb_put(skb,pkt_len);	/* Make room */
+		    pci_dma_sync_single(lp->pci_dev,
+		                        lp->rx_dma_addr[entry],
+		                        PKT_BUF_SZ,
+		                        PCI_DMA_FROMDEVICE);
 		    eth_copy_and_sum(skb,
 				     (unsigned char *)(lp->rx_skbuff[entry]->tail),
 				     pkt_len,0);
diff -Nru a/drivers/net/r8169.c b/drivers/net/r8169.c
--- a/drivers/net/r8169.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/r8169.c	Wed Nov 12 21:06:46 2003
@@ -292,6 +292,7 @@
 MODULE_AUTHOR("Realtek");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
 MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_LICENSE("GPL");
 
 static int rtl8169_open(struct net_device *dev);
 static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/sis900.c	Wed Nov 12 21:06:46 2003
@@ -1438,7 +1438,7 @@
 			pci_unmap_single(sis_priv->pci_dev, 
 				sis_priv->tx_ring[i].bufptr, skb->len,
 				PCI_DMA_TODEVICE);
-			dev_kfree_skb(skb);
+			dev_kfree_skb_irq(skb);
 			sis_priv->tx_skbuff[i] = 0;
 			sis_priv->tx_ring[i].cmdsts = 0;
 			sis_priv->tx_ring[i].bufptr = 0;
diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c
--- a/drivers/net/starfire.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/starfire.c	Wed Nov 12 21:06:46 2003
@@ -139,6 +139,7 @@
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
+#include <asm/io.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -1174,15 +1175,9 @@
 	       TX_DESC_SPACING | TX_DESC_TYPE,
 	       ioaddr + TxDescCtrl);
 
-#if defined(ADDR_64BITS)
-	writel(np->queue_mem_dma >> 32, ioaddr + RxDescQHiAddr);
-	writel(np->queue_mem_dma >> 32, ioaddr + TxRingHiAddr);
-	writel(np->queue_mem_dma >> 32, ioaddr + CompletionHiAddr);
-#else
-	writel(0, ioaddr + RxDescQHiAddr);
-	writel(0, ioaddr + TxRingHiAddr);
-	writel(0, ioaddr + CompletionHiAddr);
-#endif
+	writel( (np->queue_mem_dma >> 16) >> 16, ioaddr + RxDescQHiAddr);
+	writel( (np->queue_mem_dma >> 16) >> 16, ioaddr + TxRingHiAddr);
+	writel( (np->queue_mem_dma >> 16) >> 16, ioaddr + CompletionHiAddr);
 	writel(np->rx_ring_dma, ioaddr + RxDescQAddr);
 	writel(np->tx_ring_dma, ioaddr + TxRingPtr);
 
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/net/tg3.c	Wed Nov 12 21:06:47 2003
@@ -56,8 +56,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"2.2"
-#define DRV_MODULE_RELDATE	"August 24, 2003"
+#define DRV_MODULE_VERSION	"2.3"
+#define DRV_MODULE_RELDATE	"November 5, 2003"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -5935,6 +5935,10 @@
 					tp->link_config.phy_is_low_power)
 		return -EAGAIN;
 
+	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
+
+	tp->link_config.autoneg = cmd->autoneg;
 	if (cmd->autoneg == AUTONEG_ENABLE) {
 		tp->link_config.advertising = cmd->advertising;
 		tp->link_config.speed = SPEED_INVALID;
@@ -7601,7 +7605,7 @@
 	spin_lock_init(&tp->lock);
 	spin_lock_init(&tp->tx_lock);
 	spin_lock_init(&tp->indirect_lock);
-	PREPARE_WORK(&tp->reset_task, tg3_reset_task, tp);
+	INIT_WORK(&tp->reset_task, tg3_reset_task, tp);
 
 	tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
 	if (tp->regs == 0UL) {
diff -Nru a/drivers/net/tlan.c b/drivers/net/tlan.c
--- a/drivers/net/tlan.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/tlan.c	Wed Nov 12 21:06:46 2003
@@ -234,7 +234,7 @@
 	const char	*deviceLabel;
 	u32	   	flags;
 	u16	   	addrOfs;
-} board_info[] __devinitdata = {
+} board_info[] = {
 	{ "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
 	{ "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
 	{ "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
diff -Nru a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
--- a/drivers/net/tokenring/ibmtr.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/net/tokenring/ibmtr.c	Wed Nov 12 21:06:47 2003
@@ -152,7 +152,7 @@
 
 /* this allows displaying full adapter information */
 
-char *channel_def[] __initdata = { "ISA", "MCA", "ISA P&P" };
+char *channel_def[] __devinitdata = { "ISA", "MCA", "ISA P&P" };
 
 static char pcchannelid[] __devinitdata = {
 	0x05, 0x00, 0x04, 0x09,
@@ -864,7 +864,8 @@
 	ti->sram_virt &= ~1; /* to reverse what we do in tok_close */
 	/* init the spinlock */
 	ti->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
-
+	init_timer(&ti->tr_timer);
+	
 	i = tok_init_card(dev);
 	if (i) return i;
 
@@ -1033,7 +1034,7 @@
 
 	/* Important for PCMCIA hot unplug, otherwise, we'll pull the card, */
 	/* unloading the module from memory, and then if a timer pops, ouch */
-	del_timer(&ti->tr_timer);
+	del_timer_sync(&ti->tr_timer);
 	outb(0, dev->base_addr + ADAPTRESET);
 	ti->sram_virt |= 1;
 	ti->open_status = CLOSED;
diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
--- a/drivers/net/tulip/de4x5.c	Wed Nov 12 21:06:45 2003
+++ b/drivers/net/tulip/de4x5.c	Wed Nov 12 21:06:45 2003
@@ -1237,6 +1237,8 @@
 	if (lp->useSROM) {
 	    lp->state = INITIALISED;
 	    if (srom_infoleaf_info(dev)) {
+	        dma_free_coherent (gendev, lp->dma_size,
+			       lp->rx_ring, lp->dma_rings);
 		return -ENXIO;
 	    }
 	    srom_init(dev);
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/net/wireless/airo.c	Wed Nov 12 21:06:46 2003
@@ -982,6 +982,7 @@
 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 #ifdef WIRELESS_EXT
 struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
+static void airo_read_wireless_stats (struct airo_info *local);
 #endif /* WIRELESS_EXT */
 #ifdef CISCO_EXT
 static int readrids(struct net_device *dev, aironet_ioctl *comp);
@@ -1027,7 +1028,7 @@
 #define FLAG_PENDING_XMIT 9
 #define FLAG_PENDING_XMIT11 10
 #define FLAG_PCI	11
-#define JOB_MASK	0xff0000
+#define JOB_MASK	0x1ff0000
 #define JOB_DIE		16
 #define JOB_XMIT	17
 #define JOB_XMIT11	18
@@ -1036,6 +1037,7 @@
 #define JOB_MIC		21
 #define JOB_EVENT	22
 #define JOB_AUTOWEP	23
+#define JOB_WSTATS	24
 	int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
 			int whichbap);
 	unsigned short *flash;
@@ -1692,8 +1694,8 @@
 
 	return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
 }
-static int readStatusRid(struct airo_info*ai, StatusRid *statr) {
-	int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), 1);
+static int readStatusRid(struct airo_info*ai, StatusRid *statr, int lock) {
+	int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
 	u16 *s;
 
 	statr->len = le16_to_cpu(statr->len);
@@ -2415,6 +2417,8 @@
 			airo_end_xmit11(dev);
 		else if (test_bit(JOB_STATS, &ai->flags))
 			airo_read_stats(ai);
+		else if (test_bit(JOB_WSTATS, &ai->flags))
+			airo_read_wireless_stats(ai);
 		else if (test_bit(JOB_PROMISC, &ai->flags))
 			airo_set_promisc(ai);
 #ifdef MICSUPPORT
@@ -2944,7 +2948,6 @@
 		ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
 		ai->config.authType = AUTH_OPEN;
 		ai->config.modulation = MOD_CCK;
-		ai->config._reserved1a[0] = 2; /* ??? */
 
 #ifdef MICSUPPORT
 		if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) &&
@@ -3723,7 +3726,7 @@
 		return -ENOMEM;
 	}
 
-	readStatusRid(apriv, &status_rid);
+	readStatusRid(apriv, &status_rid, 1);
 	readCapabilityRid(apriv, &cap_rid);
 
         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
@@ -4767,7 +4770,7 @@
 	if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
 		status_rid.channel = local->config.channelSet;
 	else
-		readStatusRid(local, &status_rid);
+		readStatusRid(local, &status_rid, 1);
 
 #ifdef WEXT_USECHANNELS
 	fwrq->m = ((int)status_rid.channel) + 1;
@@ -4842,7 +4845,7 @@
 	struct airo_info *local = dev->priv;
 	StatusRid status_rid;		/* Card status info */
 
-	readStatusRid(local, &status_rid);
+	readStatusRid(local, &status_rid, 1);
 
 	/* Note : if dwrq->flags != 0, we should
 	 * get the relevant SSID from the SSID list... */
@@ -4906,7 +4909,7 @@
 	struct airo_info *local = dev->priv;
 	StatusRid status_rid;		/* Card status info */
 
-	readStatusRid(local, &status_rid);
+	readStatusRid(local, &status_rid, 1);
 
 	/* Tentative. This seems to work, wow, I'm lucky !!! */
 	memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
@@ -5039,7 +5042,7 @@
 	struct airo_info *local = dev->priv;
 	StatusRid status_rid;		/* Card status info */
 
-	readStatusRid(local, &status_rid);
+	readStatusRid(local, &status_rid, 1);
 
 	vwrq->value = status_rid.currentXmitRate * 500000;
 	/* If more than one rate, set auto */
@@ -5755,7 +5758,7 @@
 	}
 	if (!i) {
 		StatusRid status_rid;		/* Card status info */
-		readStatusRid(local, &status_rid);
+		readStatusRid(local, &status_rid, 1);
 		for (i = 0;
 		     i < min(IW_MAX_AP, 4) &&
 			     (status_rid.bssid[i][0]
@@ -6562,16 +6565,17 @@
  *
  * Jean
  */
-struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
+static void airo_read_wireless_stats(struct airo_info *local)
 {
-	struct airo_info *local = dev->priv;
 	StatusRid status_rid;
 	StatsRid stats_rid;
 	u32 *vals = stats_rid.vals;
 
 	/* Get stats out of the card */
-	readStatusRid(local, &status_rid);
-	readStatsRid(local, &stats_rid, RID_STATS, 1);
+	clear_bit(JOB_WSTATS, &local->flags);
+	readStatusRid(local, &status_rid, 0);
+	readStatsRid(local, &stats_rid, RID_STATS, 0);
+	up(&local->sem);
 
 	/* The status */
 	local->wstats.status = status_rid.mode;
@@ -6598,6 +6602,19 @@
 	local->wstats.discard.retries = vals[10];
 	local->wstats.discard.misc = vals[1] + vals[32];
 	local->wstats.miss.beacon = vals[34];
+}
+
+struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
+{
+	struct airo_info *local =  dev->priv;
+
+	/* Get stats out of the card if available */
+	if (down_trylock(&local->sem) != 0) {
+		set_bit(JOB_WSTATS, &local->flags);
+		wake_up_interruptible(&local->thr_wait);
+	} else
+		airo_read_wireless_stats(local);
+
 	return &local->wstats;
 }
 #endif /* WIRELESS_EXT */
diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c	Wed Nov 12 21:06:45 2003
+++ b/drivers/pci/quirks.c	Wed Nov 12 21:06:45 2003
@@ -646,7 +646,7 @@
  
 int interrupt_line_quirk;
 
-static void __init quirk_via_bridge(struct pci_dev *pdev)
+static void __devinit quirk_via_bridge(struct pci_dev *pdev)
 {
 	if(pdev->devfn == 0)
 		interrupt_line_quirk = 1;
@@ -750,13 +750,35 @@
  * bridges pretend to be 85C503/5513 instead.  In that case see if we
  * spotted a compatible north bridge to make sure.
  * (pci_find_device doesn't work yet)
+ *
+ * We can also enable the sis96x bit in the discovery register..
  */
 static int __devinitdata sis_96x_compatible = 0;
 
+#define SIS_DETECT_REGISTER 0x40
+
 static void __init quirk_sis_503_smbus(struct pci_dev *dev)
 {
-	if (sis_96x_compatible)
-		quirk_sis_96x_smbus(dev);
+	u8 reg;
+	u16 devid;
+
+	pci_read_config_byte(dev, SIS_DETECT_REGISTER, &reg);
+	pci_write_config_byte(dev, SIS_DETECT_REGISTER, reg | (1 << 6));
+	pci_read_config_word(dev, PCI_DEVICE_ID, &devid);
+	if ((devid & 0xfff0) != 0x0960) {
+		pci_write_config_byte(dev, SIS_DETECT_REGISTER, reg);
+		return;
+	}
+
+	/* Make people aware that we changed the config.. */
+	printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible);
+
+	/*
+	 * Ok, it now shows up as a 96x.. The 96x quirks are after
+	 * the 503 quirk in the quirk table, so they'll automatically
+	 * run and enable things like the SMBus device
+	 */
+	dev->device = devid;
 }
 
 static void __init quirk_sis_96x_compatible(struct pci_dev *dev)
diff -Nru a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
--- a/drivers/pci/setup-bus.c	Wed Nov 12 21:06:48 2003
+++ b/drivers/pci/setup-bus.c	Wed Nov 12 21:06:48 2003
@@ -132,13 +132,19 @@
    PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
    requires that if there is no I/O ports or memory behind the
    bridge, corresponding range must be turned off by writing base
-   value greater than limit to the bridge's base/limit registers.  */
+   value greater than limit to the bridge's base/limit registers.
+
+   Note: care must be taken when updating I/O base/limit registers
+   of bridges which support 32-bit I/O. This update requires two
+   config space writes, so it's quite possible that an I/O window of
+   the bridge will have some undesirable address (e.g. 0) after the
+   first write. Ditto 64-bit prefetchable MMIO.  */
 static void __devinit
 pci_setup_bridge(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
 	struct pci_bus_region region;
-	u32 l;
+	u32 l, io_upper16;
 
 	DBGC((KERN_INFO "PCI: Bus %d, bridge: %s\n",
 			bus->number, pci_name(bridge)));
@@ -151,20 +157,22 @@
 		l |= (region.start >> 8) & 0x00f0;
 		l |= region.end & 0xf000;
 		/* Set up upper 16 bits of I/O base/limit. */
-		pci_write_config_word(bridge, PCI_IO_BASE_UPPER16,
-				      region.start >> 16);
-		pci_write_config_word(bridge, PCI_IO_LIMIT_UPPER16,
-				      region.end >> 16);
+		io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
 		DBGC((KERN_INFO "  IO window: %04lx-%04lx\n",
 				region.start, region.end));
 	}
 	else {
 		/* Clear upper 16 bits of I/O base/limit. */
-		pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0);
+		io_upper16 = 0;
 		l = 0x00f0;
 		DBGC((KERN_INFO "  IO window: disabled.\n"));
 	}
+	/* Temporarily disable the I/O range before updating PCI_IO_BASE. */
+	pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff);
+	/* Update lower 16 bits of I/O base/limit. */
 	pci_write_config_dword(bridge, PCI_IO_BASE, l);
+	/* Update upper 16 bits of I/O base/limit. */
+	pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16);
 
 	/* Set up the top and bottom of the PCI Memory segment
 	   for this bus. */
@@ -181,8 +189,9 @@
 	}
 	pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
 
-	/* Clear out the upper 32 bits of PREF base/limit. */
-	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
+	/* Clear out the upper 32 bits of PREF limit.
+	   If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily
+	   disables PREF range, which is ok. */
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
 
 	/* Set up PREF base/limit. */
@@ -198,6 +207,9 @@
 		DBGC((KERN_INFO "  PREFETCH window: disabled.\n"));
 	}
 	pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
+
+	/* Clear out the upper 32 bits of PREF base. */
+	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
 
 	/* Check if we have VGA behind the bridge.
 	   Enable ISA in either case (FIXME!). */
diff -Nru a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/pci/setup-res.c	Wed Nov 12 21:06:47 2003
@@ -45,7 +45,7 @@
 	DBGC((KERN_ERR "  got res [%lx:%lx] bus [%lx:%lx] flags %lx for "
 	      "BAR %d of %s\n", res->start, res->end,
 	      region.start, region.end, res->flags,
-	      resno, dev->dev.name));
+	      resno, pci_name(dev)));
 
 	new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
 	if (res->flags & IORESOURCE_IO)
diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
--- a/drivers/pcmcia/yenta_socket.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/pcmcia/yenta_socket.c	Wed Nov 12 21:06:47 2003
@@ -461,6 +461,7 @@
 static int yenta_sock_init(struct pcmcia_socket *sock)
 {
 	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	u32 state;
 	u16 bridge;
 
 	bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
@@ -472,7 +473,10 @@
 	exca_writeb(socket, I365_GENCTL, 0x00);
 
 	/* Redo card voltage interrogation */
-	cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+	state = cb_readl(socket, CB_SOCKET_STATE);
+	if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD |
+	               CB_3VCARD | CB_XVCARD | CB_YVCARD)))
+		cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
 
 	yenta_clear_maps(socket);
 
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	Wed Nov 12 21:06:47 2003
+++ b/drivers/scsi/Kconfig	Wed Nov 12 21:06:47 2003
@@ -457,7 +457,7 @@
 
 config SCSI_BUSLOGIC
 	tristate "BusLogic SCSI support"
-	depends on (PCI || ISA) && SCSI
+	depends on (PCI || ISA || MCA) && SCSI
 	---help---
 	  This is support for BusLogic MultiMaster and FlashPoint SCSI Host
 	  Adapters. Consult the SCSI-HOWTO, available from
diff -Nru a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
--- a/drivers/scsi/ata_piix.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/scsi/ata_piix.c	Wed Nov 12 21:06:46 2003
@@ -117,6 +117,9 @@
 	.eng_timeout		= ata_eng_timeout,
 
 	.irq_handler		= ata_interrupt,
+
+	.port_start		= ata_port_start,
+	.port_stop		= ata_port_stop,
 };
 
 static struct ata_port_operations piix_sata_ops = {
@@ -137,6 +140,9 @@
 	.eng_timeout		= ata_eng_timeout,
 
 	.irq_handler		= ata_interrupt,
+
+	.port_start		= ata_port_start,
+	.port_stop		= ata_port_stop,
 };
 
 static struct ata_port_info piix_port_info[] = {
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/scsi/constants.c	Wed Nov 12 21:06:47 2003
@@ -915,15 +915,15 @@
 
 /* Print sense information */
 static void
-print_sense_internal(const char * devclass, 
-		     const unsigned char * sense_buffer,
+print_sense_internal(const char *devclass, 
+		     const unsigned char *sense_buffer,
 		     struct request *req)
 {
 	int s, sense_class, valid, code, info;
-	const char * error = NULL;
+	const char *error = NULL;
 	unsigned char asc, ascq;
 	const char *sense_txt;
-	char *name = req->rq_disk ? req->rq_disk->disk_name : "?";
+	const char *name = req->rq_disk ? req->rq_disk->disk_name : devclass;
     
 	sense_class = (sense_buffer[0] >> 4) & 0x07;
 	code = sense_buffer[0] & 0xf;
@@ -966,11 +966,9 @@
 
 		sense_txt = scsi_sense_key_string(sense_buffer[2]);
 		if (sense_txt)
-			printk("%s%s: sense key %s\n",
-			       devclass, name, sense_txt);
+			printk("%s: sense key %s\n", name, sense_txt);
 		else
-			printk("%s%s: sense = %2x %2x\n",
-			       devclass, name,
+			printk("%s: sense = %2x %2x\n", name,
 			       sense_buffer[0], sense_buffer[2]);
 
 		asc = ascq = 0;
@@ -993,11 +991,9 @@
 
 		sense_txt = scsi_sense_key_string(sense_buffer[0]);
 		if (sense_txt)
-			printk("%s%s: old sense key %s\n",
-			       devclass, name, sense_txt);
+			printk("%s: old sense key %s\n", name, sense_txt);
 		else
-			printk("%s%s: sense = %2x %2x\n",
-			       devclass, name,
+			printk("%s: sense = %2x %2x\n", name,
 			       sense_buffer[0], sense_buffer[2]);
 
 		printk("Non-extended sense class %d code 0x%0x\n",
diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c	Wed Nov 12 21:06:45 2003
+++ b/drivers/scsi/libata-core.c	Wed Nov 12 21:06:45 2003
@@ -1058,10 +1058,12 @@
 	u32 sstatus;
 	unsigned long timeout = jiffies + (HZ * 5);
 
-	scr_write(ap, SCR_CONTROL, 0x301);	/* issue phy wake/reset */
-	scr_read(ap, SCR_CONTROL);		/* dummy read; flush */
-	udelay(400);				/* FIXME: a guess */
-	scr_write(ap, SCR_CONTROL, 0x300);	/* issue phy wake/reset */
+	if (ap->flags & ATA_FLAG_SATA_RESET) {
+		scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */
+		scr_read(ap, SCR_STATUS);	/* dummy read; flush */
+		udelay(400);			/* FIXME: a guess */
+	}
+	scr_write(ap, SCR_CONTROL, 0x300);	/* issue phy wake/clear reset */
 
 	/* wait for phy to become ready, if necessary */
 	do {
@@ -1084,6 +1086,11 @@
 	if (ap->flags & ATA_FLAG_PORT_DISABLED)
 		return;
 
+	if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+		ata_port_disable(ap);
+		return;
+	}
+
 	ata_bus_reset(ap);
 }
 
@@ -1337,9 +1344,13 @@
 		outb(ap->ctl, ioaddr->ctl_addr);
 
 	/* determine if device 0/1 are present */
-	dev0 = ata_dev_devchk(ap, 0);
-	if (slave_possible)
-		dev1 = ata_dev_devchk(ap, 1);
+	if (ap->flags & ATA_FLAG_SATA_RESET)
+		dev0 = 1;
+	else {
+		dev0 = ata_dev_devchk(ap, 0);
+		if (slave_possible)
+			dev1 = ata_dev_devchk(ap, 1);
+	}
 
 	if (dev0)
 		devmask |= (1 << 0);
@@ -2569,7 +2580,8 @@
 
 	printk(KERN_DEBUG "ata%u: thread exiting\n", ap->id);
 	ap->thr_pid = -1;
-        complete_and_exit (&ap->thr_exited, 0);
+	del_timer_sync(&ap->thr_timer);
+	complete_and_exit (&ap->thr_exited, 0);
 }
 
 /**
@@ -2664,6 +2676,26 @@
 	goto out;
 }
 
+int ata_port_start (struct ata_port *ap)
+{
+	struct pci_dev *pdev = ap->host_set->pdev;
+
+	ap->prd = pci_alloc_consistent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma);
+	if (!ap->prd)
+		return -ENOMEM;
+	
+	DPRINTK("prd alloc, virt %p, dma %x\n", ap->prd, ap->prd_dma);
+
+	return 0;
+}
+
+void ata_port_stop (struct ata_port *ap)
+{
+	struct pci_dev *pdev = ap->host_set->pdev;
+
+	pci_free_consistent(pdev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+}
+
 /**
  *	ata_host_remove -
  *	@ap:
@@ -2683,7 +2715,7 @@
 
 	ata_thread_kill(ap);	/* FIXME: check return val */
 
-	pci_free_consistent(ap->host_set->pdev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+	ap->ops->port_stop(ap);
 }
 
 /**
@@ -2764,9 +2796,9 @@
 				      struct ata_host_set *host_set,
 				      unsigned int port_no)
 {
-	struct pci_dev *pdev = ent->pdev;
 	struct Scsi_Host *host;
 	struct ata_port *ap;
+	int rc;
 
 	DPRINTK("ENTER\n");
 	host = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
@@ -2777,10 +2809,9 @@
 
 	ata_host_init(ap, host, host_set, ent, port_no);
 
-	ap->prd = pci_alloc_consistent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma);
-	if (!ap->prd)
+	rc = ap->ops->port_start(ap);
+	if (rc)
 		goto err_out;
-	DPRINTK("prd alloc, virt %p, dma %x\n", ap->prd, ap->prd_dma);
 
 	ap->thr_pid = kernel_thread(ata_thread, ap, CLONE_FS | CLONE_FILES);
 	if (ap->thr_pid < 0) {
@@ -2792,7 +2823,7 @@
 	return ap;
 
 err_out_free:
-	pci_free_consistent(ap->host_set->pdev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+	ap->ops->port_stop(ap);
 
 err_out:
 	scsi_host_put(host);
@@ -2828,6 +2859,7 @@
 	host_set->n_ports = ent->n_ports;
 	host_set->irq = ent->irq;
 	host_set->mmio_base = ent->mmio_base;
+	host_set->private_data = ent->private_data;
 
 	/* register each port bound to this device */
 	for (i = 0; i < ent->n_ports; i++) {
@@ -3170,6 +3202,8 @@
 	free_irq(host_set->irq, host_set);
 	if (host_set->mmio_base)
 		iounmap(host_set->mmio_base);
+	if (host_set->ports[0]->ops->host_stop)
+		host_set->ports[0]->ops->host_stop(host_set);
 
 	for (i = 0; i < host_set->n_ports; i++) {
 		Scsi_Host_Template *sht;
@@ -3274,6 +3308,8 @@
 EXPORT_SYMBOL_GPL(ata_check_status_mmio);
 EXPORT_SYMBOL_GPL(ata_exec_command_pio);
 EXPORT_SYMBOL_GPL(ata_exec_command_mmio);
+EXPORT_SYMBOL_GPL(ata_port_start);
+EXPORT_SYMBOL_GPL(ata_port_stop);
 EXPORT_SYMBOL_GPL(ata_interrupt);
 EXPORT_SYMBOL_GPL(ata_fill_sg);
 EXPORT_SYMBOL_GPL(ata_bmdma_start_pio);
diff -Nru a/drivers/scsi/libata.h b/drivers/scsi/libata.h
--- a/drivers/scsi/libata.h	Wed Nov 12 21:06:46 2003
+++ b/drivers/scsi/libata.h	Wed Nov 12 21:06:46 2003
@@ -26,7 +26,7 @@
 #define __LIBATA_H__
 
 #define DRV_NAME	"libata"
-#define DRV_VERSION	"0.75"	/* must be exactly four chars */
+#define DRV_VERSION	"0.80"	/* must be exactly four chars */
 
 struct ata_scsi_args {
 	struct ata_port		*ap;
diff -Nru a/drivers/scsi/osst_options.h b/drivers/scsi/osst_options.h
--- a/drivers/scsi/osst_options.h	Wed Nov 12 21:06:48 2003
+++ b/drivers/scsi/osst_options.h	Wed Nov 12 21:06:48 2003
@@ -57,7 +57,7 @@
 /* The size of the first scatter/gather segments (determines the maximum block
    size for SCSI adapters not supporting scatter/gather). The default is set
    to try to allocate the buffer as one chunk. */
-#define OSST_FIRST_ORDER  5
+#define OSST_FIRST_ORDER  (15-PAGE_SHIFT)
 
 
 /* The following lines define defaults for properties that can be set
diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
--- a/drivers/scsi/sata_promise.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/scsi/sata_promise.c	Wed Nov 12 21:06:47 2003
@@ -32,22 +32,47 @@
 #include "scsi.h"
 #include "hosts.h"
 #include <linux/libata.h>
+#include <asm/io.h>
+
+#undef DIRECT_HDMA
 
 #define DRV_NAME	"sata_promise"
-#define DRV_VERSION	"0.83"
+#define DRV_VERSION	"0.86"
 
 
 enum {
 	PDC_PRD_TBL		= 0x44,	/* Direct command DMA table addr */
 
+	PDC_PKT_SUBMIT		= 0x40, /* Command packet pointer addr */
+	PDC_HDMA_PKT_SUBMIT	= 0x100, /* Host DMA packet pointer addr */
 	PDC_INT_SEQMASK		= 0x40,	/* Mask of asserted SEQ INTs */
 	PDC_TBG_MODE		= 0x41,	/* TBG mode */
 	PDC_FLASH_CTL		= 0x44, /* Flash control register */
 	PDC_CTLSTAT		= 0x60,	/* IDE control and status register */
 	PDC_SATA_PLUG_CSR	= 0x6C, /* SATA Plug control/status reg */
 	PDC_SLEW_CTL		= 0x470, /* slew rate control reg */
+	PDC_HDMA_CTLSTAT	= 0x12C, /* Host DMA control / status */
 	PDC_20621_SEQCTL	= 0x400,
 	PDC_20621_SEQMASK	= 0x480,
+	PDC_20621_GENERAL_CTL	= 0x484,
+	PDC_20621_PAGE_SIZE	= (32 * 1024),
+
+	/* chosen, not constant, values; we design our own DIMM mem map */
+	PDC_20621_DIMM_WINDOW	= 0x0C,	/* page# for 32K DIMM window */
+	PDC_20621_DIMM_BASE	= 0x00200000,
+	PDC_20621_DIMM_DATA	= (64 * 1024),
+	PDC_DIMM_DATA_STEP	= (256 * 1024),
+	PDC_DIMM_WINDOW_STEP	= (8 * 1024),
+	PDC_DIMM_HOST_PRD	= (6 * 1024),
+	PDC_DIMM_HOST_PKT	= (128 * 0),
+	PDC_DIMM_HPKT_PRD	= (128 * 1),
+	PDC_DIMM_ATA_PKT	= (128 * 2),
+	PDC_DIMM_APKT_PRD	= (128 * 3),
+	PDC_DIMM_HEADER_SZ	= PDC_DIMM_APKT_PRD + 128,
+	PDC_PAGE_WINDOW		= 0x40,
+	PDC_PAGE_DATA		= PDC_PAGE_WINDOW +
+				  (PDC_20621_DIMM_DATA / PDC_20621_PAGE_SIZE),
+	PDC_PAGE_SET		= PDC_DIMM_DATA_STEP / PDC_20621_PAGE_SIZE,
 
 	PDC_CHIP0_OFS		= 0xC0000, /* offset of chip #0 */
 
@@ -56,6 +81,14 @@
 	board_20621		= 2,	/* FastTrak S150 SX4 */
 
 	PDC_FLAG_20621		= (1 << 30), /* we have a 20621 */
+	PDC_HDMA_RESET		= (1 << 11), /* HDMA reset */
+};
+
+
+struct pdc_port_priv {
+	u8			dimm_buf[(ATA_PRD_SZ * ATA_MAX_PRD) + 512];
+	u8			*pkt;
+	dma_addr_t		pkt_dma;
 };
 
 
@@ -67,9 +100,20 @@
 			      unsigned int udma);
 static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static void pdc_dma_start(struct ata_queued_cmd *qc);
+static void pdc20621_dma_start(struct ata_queued_cmd *qc);
 static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
 static void pdc_eng_timeout(struct ata_port *ap);
 static void pdc_20621_phy_reset (struct ata_port *ap);
+static int pdc_port_start(struct ata_port *ap);
+static void pdc_port_stop(struct ata_port *ap);
+static void pdc_fill_sg(struct ata_queued_cmd *qc);
+static void pdc20621_fill_sg(struct ata_queued_cmd *qc);
+static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+static void pdc20621_host_stop(struct ata_host_set *host_set);
+static inline void pdc_dma_complete (struct ata_port *ap,
+                                     struct ata_queued_cmd *qc);
 
 
 static Scsi_Host_Template pdc_sata_sht = {
@@ -93,34 +137,39 @@
 	.port_disable		= ata_port_disable,
 	.set_piomode		= pdc_sata_set_piomode,
 	.set_udmamode		= pdc_sata_set_udmamode,
-	.tf_load		= ata_tf_load_mmio,
+	.tf_load		= pdc_tf_load_mmio,
 	.tf_read		= ata_tf_read_mmio,
 	.check_status		= ata_check_status_mmio,
-	.exec_command		= ata_exec_command_mmio,
+	.exec_command		= pdc_exec_command_mmio,
 	.phy_reset		= sata_phy_reset,
 	.phy_config		= pata_phy_config,	/* not a typo */
 	.bmdma_start            = pdc_dma_start,
-	.fill_sg		= ata_fill_sg,
+	.fill_sg		= pdc_fill_sg,
 	.eng_timeout		= pdc_eng_timeout,
 	.irq_handler		= pdc_interrupt,
 	.scr_read		= pdc_sata_scr_read,
 	.scr_write		= pdc_sata_scr_write,
+	.port_start		= pdc_port_start,
+	.port_stop		= pdc_port_stop,
 };
 
 static struct ata_port_operations pdc_20621_ops = {
 	.port_disable		= ata_port_disable,
 	.set_piomode		= pdc_sata_set_piomode,
 	.set_udmamode		= pdc_sata_set_udmamode,
-	.tf_load		= ata_tf_load_mmio,
+	.tf_load		= pdc_tf_load_mmio,
 	.tf_read		= ata_tf_read_mmio,
 	.check_status		= ata_check_status_mmio,
-	.exec_command		= ata_exec_command_mmio,
+	.exec_command		= pdc_exec_command_mmio,
 	.phy_reset		= pdc_20621_phy_reset,
 	.phy_config		= pata_phy_config,	/* not a typo */
-	.bmdma_start            = pdc_dma_start,
-	.fill_sg		= ata_fill_sg,
+	.bmdma_start            = pdc20621_dma_start,
+	.fill_sg		= pdc20621_fill_sg,
 	.eng_timeout		= pdc_eng_timeout,
-	.irq_handler		= pdc_interrupt,
+	.irq_handler		= pdc20621_interrupt,
+	.port_start		= pdc_port_start,
+	.port_stop		= pdc_port_stop,
+	.host_stop		= pdc20621_host_stop,
 };
 
 static struct ata_port_info pdc_port_info[] = {
@@ -160,16 +209,16 @@
 static struct pci_device_id pdc_sata_pci_tbl[] = {
 	{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_2037x },
+	{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_2037x },
 	{ PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_2037x },
 	{ PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_20319 },
 	{ PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_20319 },
-#if 0 /* broken currently */
 	{ PCI_VENDOR_ID_PROMISE, 0x6622, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_20621 },
-#endif
 	{ }	/* terminate list */
 };
 
@@ -182,6 +231,60 @@
 };
 
 
+static void pdc20621_host_stop(struct ata_host_set *host_set)
+{
+	void *mmio = host_set->private_data;
+
+	assert(mmio != NULL);
+	iounmap(mmio);
+}
+
+static int pdc_port_start(struct ata_port *ap)
+{
+	struct pci_dev *pdev = ap->host_set->pdev;
+	struct pdc_port_priv *pp;
+	int rc;
+
+	rc = ata_port_start(ap);
+	if (rc)
+		return rc;
+
+	pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+	if (!pp) {
+		rc = -ENOMEM;
+		goto err_out;
+	}
+
+	pp->pkt = pci_alloc_consistent(pdev, 128, &pp->pkt_dma);
+	if (!pp->pkt) {
+		rc = -ENOMEM;
+		goto err_out_kfree;
+	}
+
+	ap->private_data = pp;
+
+	return 0;
+
+err_out_kfree:
+	kfree(pp);
+err_out:
+	ata_port_stop(ap);
+	return rc;
+}
+
+
+static void pdc_port_stop(struct ata_port *ap)
+{
+	struct pci_dev *pdev = ap->host_set->pdev;
+	struct pdc_port_priv *pp = ap->private_data;
+
+	ap->private_data = NULL;
+	pci_free_consistent(pdev, 128, pp->pkt, pp->pkt_dma);
+	kfree(pp);
+	ata_port_stop(ap);
+}
+
+
 static void pdc_20621_phy_reset (struct ata_port *ap)
 {
 	VPRINTK("ENTER\n");
@@ -231,8 +334,9 @@
 	PDC_REG_DEVCTL		= (1 << 3) | (1 << 2) | (1 << 1),
 };
 
-static inline void pdc_pkt_header(struct ata_taskfile *tf, dma_addr_t sg_table,
-				  unsigned int devno, u8 *buf)
+static inline unsigned int pdc_pkt_header(struct ata_taskfile *tf,
+					  dma_addr_t sg_table,
+					  unsigned int devno, u8 *buf)
 {
 	u8 dev_reg;
 	u32 *buf32 = (u32 *) buf;
@@ -273,9 +377,11 @@
 	/* device control register */
 	buf[14] = (1 << 5) | PDC_REG_DEVCTL;
 	buf[15] = tf->ctl;
+
+	return 16; 	/* offset of next byte */
 }
 
-static inline void pdc_pkt_footer(struct ata_taskfile *tf, u8 *buf,
+static inline unsigned int pdc_pkt_footer(struct ata_taskfile *tf, u8 *buf,
 				  unsigned int i)
 {
 	if (tf->flags & ATA_TFLAG_DEVICE) {
@@ -286,19 +392,14 @@
 	/* and finally the command itself; also includes end-of-pkt marker */
 	buf[i++] = (1 << 5) | PDC_LAST_REG | ATA_REG_CMD;
 	buf[i++] = tf->command;
+
+	return i;
 }
 
-static void pdc_prep_lba28(struct ata_taskfile *tf, dma_addr_t sg_table,
-			   unsigned int devno, u8 *buf)
+static inline unsigned int pdc_prep_lba28(struct ata_taskfile *tf, u8 *buf, unsigned int i)
 {
-	unsigned int i;
-
-	pdc_pkt_header(tf, sg_table, devno, buf);
-
 	/* the "(1 << 5)" should be read "(count << 5)" */
 
-	i = 16;
-
 	/* ATA command block registers */
 	buf[i++] = (1 << 5) | ATA_REG_FEATURE;
 	buf[i++] = tf->feature;
@@ -315,20 +416,13 @@
 	buf[i++] = (1 << 5) | ATA_REG_LBAH;
 	buf[i++] = tf->lbah;
 
-	pdc_pkt_footer(tf, buf, i);
+	return i;
 }
 
-static void pdc_prep_lba48(struct ata_taskfile *tf, dma_addr_t sg_table,
-			   unsigned int devno, u8 *buf)
+static inline unsigned int pdc_prep_lba48(struct ata_taskfile *tf, u8 *buf, unsigned int i)
 {
-	unsigned int i;
-
-	pdc_pkt_header(tf, sg_table, devno, buf);
-
 	/* the "(2 << 5)" should be read "(count << 5)" */
 
-	i = 16;
-
 	/* ATA command block registers */
 	buf[i++] = (2 << 5) | ATA_REG_FEATURE;
 	buf[i++] = tf->hob_feature;
@@ -350,28 +444,479 @@
 	buf[i++] = tf->hob_lbah;
 	buf[i++] = tf->lbah;
 
-	pdc_pkt_footer(tf, buf, i);
+	return i;
+}
+
+static inline void pdc20621_ata_sg(struct ata_taskfile *tf, u8 *buf,
+				    	   unsigned int portno,
+					   unsigned int total_len)
+{
+	u32 addr;
+	unsigned int dw = PDC_DIMM_APKT_PRD >> 2;
+	u32 *buf32 = (u32 *) buf;
+
+	/* output ATA packet S/G table */
+	addr = PDC_20621_DIMM_BASE + PDC_20621_DIMM_DATA +
+	       (PDC_DIMM_DATA_STEP * portno);
+	VPRINTK("ATA sg addr 0x%x, %d\n", addr, addr);
+	buf32[dw] = cpu_to_le32(addr);
+	buf32[dw + 1] = cpu_to_le32(total_len | ATA_PRD_EOT);
+
+	VPRINTK("ATA PSG @ %x == (0x%x, 0x%x)\n",
+		PDC_20621_DIMM_BASE +
+		       (PDC_DIMM_WINDOW_STEP * portno) +
+		       PDC_DIMM_APKT_PRD,
+		buf32[dw], buf32[dw + 1]);
+}
+
+static inline void pdc20621_host_sg(struct ata_taskfile *tf, u8 *buf,
+				    	    unsigned int portno,
+					    unsigned int total_len)
+{
+	u32 addr;
+	unsigned int dw = PDC_DIMM_HPKT_PRD >> 2;
+	u32 *buf32 = (u32 *) buf;
+
+	/* output Host DMA packet S/G table */
+	addr = PDC_20621_DIMM_BASE + PDC_20621_DIMM_DATA +
+	       (PDC_DIMM_DATA_STEP * portno);
+
+	buf32[dw] = cpu_to_le32(addr);
+	buf32[dw + 1] = cpu_to_le32(total_len | ATA_PRD_EOT);
+
+	VPRINTK("HOST PSG @ %x == (0x%x, 0x%x)\n",
+		PDC_20621_DIMM_BASE +
+		       (PDC_DIMM_WINDOW_STEP * portno) +
+		       PDC_DIMM_HPKT_PRD,
+		buf32[dw], buf32[dw + 1]);
+}
+
+static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf,
+					    unsigned int devno, u8 *buf,
+					    unsigned int portno)
+{
+	unsigned int i, dw;
+	u32 *buf32 = (u32 *) buf;
+	u8 dev_reg;
+
+	unsigned int dimm_sg = PDC_20621_DIMM_BASE +
+			       (PDC_DIMM_WINDOW_STEP * portno) +
+			       PDC_DIMM_APKT_PRD;
+	VPRINTK("ENTER, dimm_sg == 0x%x, %d\n", dimm_sg, dimm_sg);
+
+	i = PDC_DIMM_ATA_PKT;
+
+	/*
+	 * Set up ATA packet
+	 */
+	if (tf->protocol == ATA_PROT_DMA_READ)
+		buf[i++] = PDC_PKT_READ;
+	else if (tf->protocol == ATA_PROT_NODATA)
+		buf[i++] = PDC_PKT_NODATA;
+	else
+		buf[i++] = 0;
+	buf[i++] = 0;			/* reserved */
+	buf[i++] = portno + 1;		/* seq. id */
+	buf[i++] = 0xff;		/* delay seq. id */
+
+	/* dimm dma S/G, and next-pkt */
+	dw = i >> 2;
+	buf32[dw] = cpu_to_le32(dimm_sg);
+	buf32[dw + 1] = 0;
+	i += 8;
+
+	if (devno == 0)
+		dev_reg = ATA_DEVICE_OBS;
+	else
+		dev_reg = ATA_DEVICE_OBS | ATA_DEV1;
+
+	/* select device */
+	buf[i++] = (1 << 5) | PDC_PKT_CLEAR_BSY | ATA_REG_DEVICE;
+	buf[i++] = dev_reg;
+
+	/* device control register */
+	buf[i++] = (1 << 5) | PDC_REG_DEVCTL;
+	buf[i++] = tf->ctl;
+
+	return i;
+}
+
+static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf,
+				     unsigned int portno)
+{
+	unsigned int dw;
+	u32 tmp, *buf32 = (u32 *) buf;
+
+	unsigned int host_sg = PDC_20621_DIMM_BASE +
+			       (PDC_DIMM_WINDOW_STEP * portno) +
+			       PDC_DIMM_HOST_PRD;
+	unsigned int dimm_sg = PDC_20621_DIMM_BASE +
+			       (PDC_DIMM_WINDOW_STEP * portno) +
+			       PDC_DIMM_HPKT_PRD;
+	VPRINTK("ENTER, dimm_sg == 0x%x, %d\n", dimm_sg, dimm_sg);
+	VPRINTK("host_sg == 0x%x, %d\n", host_sg, host_sg);
+
+	dw = PDC_DIMM_HOST_PKT >> 2;
+
+	/*
+	 * Set up Host DMA packet
+	 */
+	if (tf->protocol == ATA_PROT_DMA_READ)
+		tmp = PDC_PKT_READ;
+	else
+		tmp = 0;
+	tmp |= ((portno + 1 + 4) << 16);	/* seq. id */
+	tmp |= (0xff << 24);			/* delay seq. id */
+	buf32[dw + 0] = cpu_to_le32(tmp);
+	buf32[dw + 1] = cpu_to_le32(host_sg);
+	buf32[dw + 2] = cpu_to_le32(dimm_sg);
+	buf32[dw + 3] = 0;
+
+	VPRINTK("HOST PKT @ %x == (0x%x 0x%x 0x%x 0x%x)\n",
+		PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * portno) +
+			PDC_DIMM_HOST_PKT,
+		buf32[dw + 0],
+		buf32[dw + 1],
+		buf32[dw + 2],
+		buf32[dw + 3]);
+}
+
+static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
+{
+	struct scatterlist *sg = qc->sg;
+	struct ata_port *ap = qc->ap;
+	struct pdc_port_priv *pp = ap->private_data;
+	void *mmio = ap->host_set->mmio_base;
+	void *dimm_mmio = ap->host_set->private_data;
+	unsigned int portno = ap->port_no;
+	unsigned int i, last, idx, total_len = 0, sgt_len;
+	u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
+
+	VPRINTK("ata%u: ENTER\n", ap->id);
+
+	/* hard-code chip #0 */
+	mmio += PDC_CHIP0_OFS;
+
+	/*
+	 * Build S/G table
+	 */
+	last = qc->n_elem;
+	idx = 0;
+	for (i = 0; i < last; i++) {
+		buf[idx++] = cpu_to_le32(sg[i].dma_address);
+		buf[idx++] = cpu_to_le32(sg[i].length);
+		total_len += sg[i].length;
+	}
+	buf[idx - 1] |= cpu_to_le32(ATA_PRD_EOT);
+	sgt_len = idx * 4;
+
+	/*
+	 * Build ATA, host DMA packets
+	 */
+	pdc20621_host_sg(&qc->tf, &pp->dimm_buf[0], portno, total_len);
+	pdc20621_host_pkt(&qc->tf, &pp->dimm_buf[0], portno);
+
+	pdc20621_ata_sg(&qc->tf, &pp->dimm_buf[0], portno, total_len);
+	i = pdc20621_ata_pkt(&qc->tf, qc->dev->devno, &pp->dimm_buf[0], portno);
+
+	if (qc->tf.flags & ATA_TFLAG_LBA48)
+		i = pdc_prep_lba48(&qc->tf, &pp->dimm_buf[0], i);
+	else
+		i = pdc_prep_lba28(&qc->tf, &pp->dimm_buf[0], i);
+
+	pdc_pkt_footer(&qc->tf, &pp->dimm_buf[0], i);
+
+	/* copy three S/G tables and two packets to DIMM MMIO window */
+	memcpy_toio(dimm_mmio + (portno * PDC_DIMM_WINDOW_STEP),
+		    &pp->dimm_buf, PDC_DIMM_HEADER_SZ);
+	memcpy_toio(dimm_mmio + (portno * PDC_DIMM_WINDOW_STEP) +
+		    PDC_DIMM_HOST_PRD,
+		    &pp->dimm_buf[PDC_DIMM_HEADER_SZ], sgt_len);
+
+	/* force host FIFO dump */
+	writel(0x00000001, mmio + PDC_20621_GENERAL_CTL);
+
+	readl(dimm_mmio);	/* MMIO PCI posting flush */
+
+	VPRINTK("ata pkt buf ofs %u, prd size %u, mmio copied\n", i, sgt_len);
+}
+
+#ifdef DIRECT_HDMA
+static void pdc20621_push_hdma(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct ata_host_set *host_set = ap->host_set;
+	unsigned int port_no = ap->port_no;
+	void *mmio = host_set->mmio_base;
+	unsigned int rw = (qc->flags & ATA_QCFLAG_WRITE);
+	u32 tmp;
+
+	unsigned int host_sg = PDC_20621_DIMM_BASE +
+			       (PDC_DIMM_WINDOW_STEP * port_no) +
+			       PDC_DIMM_HOST_PRD;
+	unsigned int dimm_sg = PDC_20621_DIMM_BASE +
+			       (PDC_DIMM_WINDOW_STEP * port_no) +
+			       PDC_DIMM_HPKT_PRD;
+
+	/* hard-code chip #0 */
+	mmio += PDC_CHIP0_OFS;
+
+	tmp = readl(mmio + PDC_HDMA_CTLSTAT) & 0xffffff00;
+	tmp |= port_no + 1 + 4;		/* seq. ID */
+	if (!rw)
+		tmp |= (1 << 6);	/* hdma data direction */
+	writel(tmp, mmio + PDC_HDMA_CTLSTAT); /* note: stops DMA, if active */
+	readl(mmio + PDC_HDMA_CTLSTAT);	/* flush */
+
+	writel(host_sg, mmio + 0x108);
+	writel(dimm_sg, mmio + 0x10C);
+	writel(0, mmio + 0x128);
+
+	tmp |= (1 << 7);
+	writel(tmp, mmio + PDC_HDMA_CTLSTAT);
+	readl(mmio + PDC_HDMA_CTLSTAT);	/* flush */
+}
+#endif
+
+#ifdef ATA_VERBOSE_DEBUG
+static void pdc20621_dump_hdma(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	unsigned int port_no = ap->port_no;
+	void *dimm_mmio = ap->host_set->private_data;
+
+	dimm_mmio += (port_no * PDC_DIMM_WINDOW_STEP);
+	dimm_mmio += PDC_DIMM_HOST_PKT;
+
+	printk(KERN_ERR "HDMA[0] == 0x%08X\n", readl(dimm_mmio));
+	printk(KERN_ERR "HDMA[1] == 0x%08X\n", readl(dimm_mmio + 4));
+	printk(KERN_ERR "HDMA[2] == 0x%08X\n", readl(dimm_mmio + 8));
+	printk(KERN_ERR "HDMA[3] == 0x%08X\n", readl(dimm_mmio + 12));
+}
+#else
+static inline void pdc20621_dump_hdma(struct ata_queued_cmd *qc) { }
+#endif /* ATA_VERBOSE_DEBUG */
+
+static void pdc20621_dma_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct ata_host_set *host_set = ap->host_set;
+	unsigned int port_no = ap->port_no;
+	void *mmio = host_set->mmio_base;
+	unsigned int rw = (qc->flags & ATA_QCFLAG_WRITE);
+	u8 seq = (u8) (port_no + 1);
+	unsigned int doing_hdma = 0, port_ofs;
+
+	/* hard-code chip #0 */
+	mmio += PDC_CHIP0_OFS;
+
+	VPRINTK("ata%u: ENTER\n", ap->id);
+
+	port_ofs = PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * port_no);
+
+	/* if writing, we (1) DMA to DIMM, then (2) do ATA command */
+	if (rw) {
+		doing_hdma = 1;
+		seq += 4;
+	}
+
+	wmb();			/* flush PRD, pkt writes */
+
+	writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
+	readl(mmio + PDC_20621_SEQCTL + (seq * 4));	/* flush */
+
+	if (doing_hdma) {
+		pdc20621_dump_hdma(qc);
+#ifdef DIRECT_HDMA
+		pdc20621_push_hdma(qc);
+#else
+		writel(port_ofs + PDC_DIMM_HOST_PKT,
+		       mmio + PDC_HDMA_PKT_SUBMIT);
+		readl(mmio + PDC_HDMA_PKT_SUBMIT);	/* flush */
+#endif
+		VPRINTK("submitted ofs 0x%x (%u), seq %u\n",
+		port_ofs + PDC_DIMM_HOST_PKT,
+		port_ofs + PDC_DIMM_HOST_PKT,
+		seq);
+	} else {
+		writel(port_ofs + PDC_DIMM_ATA_PKT,
+		       (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+		readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+		VPRINTK("submitted ofs 0x%x (%u), seq %u\n",
+			port_ofs + PDC_DIMM_ATA_PKT,
+			port_ofs + PDC_DIMM_ATA_PKT,
+			seq);
+	}
 }
 
-static inline void __pdc_dma_complete (struct ata_port *ap,
-                                       struct ata_queued_cmd *qc)
+static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
+                                          struct ata_queued_cmd *qc,
+					  unsigned int doing_hdma,
+					  void *mmio)
 {
-	void *dmactl = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT;
-	u32 val;
+	unsigned int port_no = ap->port_no;
+	unsigned int port_ofs =
+		PDC_20621_DIMM_BASE + (PDC_DIMM_WINDOW_STEP * port_no);
+	u8 status;
+	unsigned int handled = 0;
 
-	/* clear DMA start/stop bit (bit 7) */
-	val = readl(dmactl);
-	writel(val & ~(1 << 7), dmactl);
+	VPRINTK("ENTER\n");
 
-	/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-	ata_altstatus(ap);              /* dummy read */
+	switch (qc->tf.protocol) {
+	case ATA_PROT_DMA_READ:
+		/* step two - DMA from DIMM to host */
+		if (doing_hdma) {
+			VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
+				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
+			pdc_dma_complete(ap, qc);
+		}
+
+		/* step one - exec ATA command */
+		else {
+			u8 seq = (u8) (port_no + 1 + 4);
+			VPRINTK("ata%u: read ata, 0x%x 0x%x\n", ap->id,
+				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
+
+			/* submit hdma pkt */
+			pdc20621_dump_hdma(qc);
+			writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
+			readl(mmio + PDC_20621_SEQCTL + (seq * 4));
+#ifdef DIRECT_HDMA
+			pdc20621_push_hdma(qc);
+#else
+			writel(port_ofs + PDC_DIMM_HOST_PKT,
+			       mmio + PDC_HDMA_PKT_SUBMIT);
+			readl(mmio + PDC_HDMA_PKT_SUBMIT);
+#endif
+		}
+		handled = 1;
+		break;
+
+	case ATA_PROT_DMA_WRITE:
+		/* step one - DMA from host to DIMM */
+		if (doing_hdma) {
+			u8 seq = (u8) (port_no + 1);
+			VPRINTK("ata%u: write hdma, 0x%x 0x%x\n", ap->id,
+				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
+
+			/* submit ata pkt */
+			writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
+			readl(mmio + PDC_20621_SEQCTL + (seq * 4));
+			writel(port_ofs + PDC_DIMM_ATA_PKT,
+			       (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+			readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+		}
+
+		/* step two - execute ATA command */
+		else {
+			VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
+				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
+			pdc_dma_complete(ap, qc);
+		}
+		handled = 1;
+		break;
+
+	case ATA_PROT_NODATA:   /* command completion, but no data xfer */
+		status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+		DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
+		ata_qc_complete(qc, status, 0);
+		handled = 1;
+		break;
+
+        default:
+                ap->stats.idle_irq++;
+                break;
+        }
+
+        return handled;
+}
+
+static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct ata_host_set *host_set = dev_instance;
+	struct ata_port *ap;
+	u32 mask = 0;
+	unsigned int i, tmp, port_no;
+	unsigned int handled = 0;
+	void *mmio_base;
+
+	VPRINTK("ENTER\n");
+
+	if (!host_set || !host_set->mmio_base) {
+		VPRINTK("QUICK EXIT\n");
+		return IRQ_NONE;
+	}
+
+	mmio_base = host_set->mmio_base;
+
+	/* reading should also clear interrupts */
+	mmio_base += PDC_CHIP0_OFS;
+	mask = readl(mmio_base + PDC_20621_SEQMASK);
+	VPRINTK("mask == 0x%x\n", mask);
+
+	if (mask == 0xffffffff) {
+		VPRINTK("QUICK EXIT 2\n");
+		return IRQ_NONE;
+	}
+	mask &= 0xffff;		/* only 16 tags possible */
+	if (!mask) {
+		VPRINTK("QUICK EXIT 3\n");
+		return IRQ_NONE;
+	}
+
+        spin_lock_irq(&host_set->lock);
+
+        for (i = 1; i < 9; i++) {
+		port_no = i - 1;
+		if (port_no > 3)
+			port_no -= 4;
+		if (port_no >= host_set->n_ports)
+			ap = NULL;
+		else
+			ap = host_set->ports[port_no];
+		tmp = mask & (1 << i);
+		VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp);
+		if (tmp && ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) {
+			struct ata_queued_cmd *qc;
+
+			qc = ata_qc_from_tag(ap, ap->active_tag);
+			if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0))
+				handled += pdc20621_host_intr(ap, qc, (i > 4),
+							      mmio_base);
+		}
+	}
+
+        spin_unlock_irq(&host_set->lock);
+
+	VPRINTK("mask == 0x%x\n", mask);
+
+	VPRINTK("EXIT\n");
+
+	return IRQ_RETVAL(handled);
+}
+
+static void pdc_fill_sg(struct ata_queued_cmd *qc)
+{
+	struct pdc_port_priv *pp = qc->ap->private_data;
+	unsigned int i;
+
+	VPRINTK("ENTER\n");
+
+	ata_fill_sg(qc);
+
+	i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma,  qc->dev->devno, pp->pkt);
+
+	if (qc->tf.flags & ATA_TFLAG_LBA48)
+		i = pdc_prep_lba48(&qc->tf, pp->pkt, i);
+	else
+		i = pdc_prep_lba28(&qc->tf, pp->pkt, i);
+
+	pdc_pkt_footer(&qc->tf, pp->pkt, i);
 }
 
 static inline void pdc_dma_complete (struct ata_port *ap,
                                      struct ata_queued_cmd *qc)
 {
-	__pdc_dma_complete(ap, qc);
-
 	/* get drive status; clear intr; complete txn */
 	ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag),
 			ata_wait_idle(ap), 0);
@@ -395,7 +940,6 @@
 	case ATA_PROT_DMA_READ:
 	case ATA_PROT_DMA_WRITE:
 		printk(KERN_ERR "ata%u: DMA timeout\n", ap->id);
-		__pdc_dma_complete(ap, qc);
 		ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag),
 			        ata_wait_idle(ap) | ATA_ERR, 0);
 		break;
@@ -457,7 +1001,7 @@
 	struct ata_port *ap;
 	u32 mask = 0;
 	unsigned int i, tmp;
-	unsigned int handled = 0, have_20621 = 0;
+	unsigned int handled = 0;
 	void *mmio_base;
 
 	VPRINTK("ENTER\n");
@@ -469,27 +1013,14 @@
 
 	mmio_base = host_set->mmio_base;
 
-	for (i = 0; i < host_set->n_ports; i++) {
-		ap = host_set->ports[i];
-		if (ap && (ap->flags & PDC_FLAG_20621)) {
-			have_20621 = 1;
-			break;
-		}
-	}
-
 	/* reading should also clear interrupts */
-	if (have_20621) {
-		mmio_base += PDC_CHIP0_OFS;
-		mask = readl(mmio_base + PDC_20621_SEQMASK);
-	} else {
-		mask = readl(mmio_base + PDC_INT_SEQMASK);
-	}
+	mask = readl(mmio_base + PDC_INT_SEQMASK);
 
 	if (mask == 0xffffffff) {
 		VPRINTK("QUICK EXIT 2\n");
 		return IRQ_NONE;
 	}
-	mask &= 0xf;		/* only 16 tags possible */
+	mask &= 0xffff;		/* only 16 tags possible */
 	if (!mask) {
 		VPRINTK("QUICK EXIT 3\n");
 		return IRQ_NONE;
@@ -520,56 +1051,37 @@
 static void pdc_dma_start(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
-	struct ata_host_set *host_set = ap->host_set;
+	struct pdc_port_priv *pp = ap->private_data;
 	unsigned int port_no = ap->port_no;
-	void *mmio = host_set->mmio_base;
-	void *dmactl = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT;
-	unsigned int rw = (qc->flags & ATA_QCFLAG_WRITE);
-	u32 val;
 	u8 seq = (u8) (port_no + 1);
 
-	wmb();	/* flush writes made to PRD table in DMA memory */
+	VPRINTK("ENTER, ap %p\n", ap);
 
-	if (ap->flags & PDC_FLAG_20621)
-		mmio += PDC_CHIP0_OFS;
+	writel(0x00000001, ap->host_set->mmio_base + (seq * 4));
+	readl(ap->host_set->mmio_base + (seq * 4));	/* flush */
 
-	VPRINTK("ENTER, ap %p, mmio %p\n", ap, mmio);
+	pp->pkt[2] = seq;
+	wmb();			/* flush PRD, pkt writes */
+	writel(pp->pkt_dma, (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+	readl((void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
+}
 
-	/* indicate where our S/G table is to chip */
-	writel(ap->prd_dma, (void *) ap->ioaddr.cmd_addr + PDC_PRD_TBL);
+static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	if ((tf->protocol != ATA_PROT_DMA_READ) &&
+	    (tf->protocol != ATA_PROT_DMA_WRITE))
+		ata_tf_load_mmio(ap, tf);
+}
 
-	/* clear dma start bit (paranoia), clear intr seq id (paranoia),
-	 * set DMA direction (bit 6 == from chip -> drive)
-	 */
-	val = readl(dmactl);
-	VPRINTK("val == %x\n", val);
-	val &= ~(1 << 7);	/* clear dma start/stop bit */
-	if (rw)			/* set/clear dma direction bit */
-		val |= (1 << 6);
-	else
-		val &= ~(1 << 6);
-	if (qc->tf.ctl & ATA_NIEN) /* set/clear irq-mask bit */
-		val |= (1 << 10);
-	else
-		val &= ~(1 << 10);
-	writel(val, dmactl);
-	val = readl(dmactl);
-	VPRINTK("val == %x\n", val);
-
-	/* FIXME: clear any intr status bits here? */
-
-	ata_exec_command_mmio(ap, &qc->tf);
-
-	VPRINTK("FIVE\n");
-	if (ap->flags & PDC_FLAG_20621)
-		writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
-	else
-		writel(0x00000001, mmio + (seq * 4));
 
-	/* start host DMA transaction */
-	writel(val | seq | (1 << 7), dmactl);
+static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	if ((tf->protocol != ATA_PROT_DMA_READ) &&
+	    (tf->protocol != ATA_PROT_DMA_WRITE))
+		ata_exec_command_mmio(ap, tf);
 }
 
+
 static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
 {
 	port->cmd_addr		= base;
@@ -586,6 +1098,32 @@
 
 static void pdc_20621_init(struct ata_probe_ent *pe)
 {
+	u32 tmp;
+	void *mmio = pe->mmio_base;
+
+	mmio += PDC_CHIP0_OFS;
+
+	/*
+	 * Select page 0x40 for our 32k DIMM window
+	 */
+	tmp = readl(mmio + PDC_20621_DIMM_WINDOW) & 0xffff0000;
+	tmp |= PDC_PAGE_WINDOW;	/* page 40h; arbitrarily selected */
+	writel(tmp, mmio + PDC_20621_DIMM_WINDOW);
+
+	/*
+	 * Reset Host DMA
+	 */
+	tmp = readl(mmio + PDC_HDMA_CTLSTAT);
+	tmp |= PDC_HDMA_RESET;
+	writel(tmp, mmio + PDC_HDMA_CTLSTAT);
+	readl(mmio + PDC_HDMA_CTLSTAT);		/* flush */
+
+	udelay(10);
+
+	tmp = readl(mmio + PDC_HDMA_CTLSTAT);
+	tmp &= ~PDC_HDMA_RESET;
+	writel(tmp, mmio + PDC_HDMA_CTLSTAT);
+	readl(mmio + PDC_HDMA_CTLSTAT);		/* flush */
 }
 
 static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
@@ -629,8 +1167,9 @@
 	static int printed_version;
 	struct ata_probe_ent *probe_ent = NULL;
 	unsigned long base;
-	void *mmio_base;
+	void *mmio_base, *dimm_mmio = NULL;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
+	unsigned int have_20621 = (board_idx == board_20621);
 	int rc;
 
 	if (!printed_version++)
@@ -670,6 +1209,15 @@
 	}
 	base = (unsigned long) mmio_base;
 
+	if (have_20621) {
+		dimm_mmio = ioremap(pci_resource_start(pdev, 4),
+				    pci_resource_len(pdev, 4));
+		if (!dimm_mmio) {
+			rc = -ENOMEM;
+			goto err_out_iounmap;
+		}
+	}
+
 	probe_ent->sht		= pdc_port_info[board_idx].sht;
 	probe_ent->host_flags	= pdc_port_info[board_idx].host_flags;
 	probe_ent->pio_mask	= pdc_port_info[board_idx].pio_mask;
@@ -680,14 +1228,18 @@
        	probe_ent->irq_flags = SA_SHIRQ;
 	probe_ent->mmio_base = mmio_base;
 
-	if (board_idx == board_20621)
+	if (have_20621) {
+		probe_ent->private_data = dimm_mmio;
 		base += PDC_CHIP0_OFS;
+	}
 
 	pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
-	probe_ent->port[0].scr_addr = base + 0x400;
-
 	pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
-	probe_ent->port[1].scr_addr = base + 0x500;
+
+	if (!have_20621) {
+		probe_ent->port[0].scr_addr = base + 0x400;
+		probe_ent->port[1].scr_addr = base + 0x500;
+	}
 
 	/* notice 4-port boards */
 	switch (board_idx) {
@@ -696,10 +1248,12 @@
        		probe_ent->n_ports = 4;
 
 		pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
-		probe_ent->port[2].scr_addr = base + 0x600;
-
 		pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
-		probe_ent->port[3].scr_addr = base + 0x700;
+
+		if (!have_20621) {
+			probe_ent->port[2].scr_addr = base + 0x600;
+			probe_ent->port[3].scr_addr = base + 0x700;
+		}
 		break;
 	case board_2037x:
        		probe_ent->n_ports = 2;
@@ -712,15 +1266,10 @@
 	pci_set_master(pdev);
 
 	/* initialize adapter */
-	switch (board_idx) {
-	case board_20621:
+	if (have_20621)
 		pdc_20621_init(probe_ent);
-		break;
-
-	default:
+	else
 		pdc_host_init(board_idx, probe_ent);
-		break;
-	}
 
 	/* FIXME: check ata_device_add return value */
 	ata_device_add(probe_ent);
@@ -728,6 +1277,8 @@
 
 	return 0;
 
+err_out_iounmap:
+	iounmap(mmio_base);
 err_out_free_ent:
 	kfree(probe_ent);
 err_out_regions:
@@ -736,7 +1287,6 @@
 	pci_disable_device(pdev);
 	return rc;
 }
-
 
 
 static int __init pdc_sata_init(void)
diff -Nru a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
--- a/drivers/scsi/sata_sil.c	Wed Nov 12 21:06:45 2003
+++ b/drivers/scsi/sata_sil.c	Wed Nov 12 21:06:45 2003
@@ -106,6 +106,8 @@
 	.irq_handler		= ata_interrupt,
 	.scr_read		= sil_scr_read,
 	.scr_write		= sil_scr_write,
+	.port_start		= ata_port_start,
+	.port_stop		= ata_port_stop,
 };
 
 static struct ata_port_info sil_port_info[] = {
diff -Nru a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
--- a/drivers/scsi/sata_svw.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/scsi/sata_svw.c	Wed Nov 12 21:06:47 2003
@@ -235,6 +235,8 @@
 	.irq_handler		= ata_interrupt,
 	.scr_read		= k2_sata_scr_read,
 	.scr_write		= k2_sata_scr_write,
+	.port_start		= ata_port_start,
+	.port_stop		= ata_port_stop,
 };
 
 
diff -Nru a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
--- a/drivers/scsi/sata_via.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/scsi/sata_via.c	Wed Nov 12 21:06:46 2003
@@ -98,6 +98,9 @@
 	.eng_timeout		= ata_eng_timeout,
 
 	.irq_handler		= ata_interrupt,
+
+	.port_start		= ata_port_start,
+	.port_stop		= ata_port_stop,
 };
 
 static struct ata_port_info svia_port_info[] = {
diff -Nru a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
--- a/drivers/serial/serial_core.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/serial/serial_core.c	Wed Nov 12 21:06:46 2003
@@ -1707,6 +1707,9 @@
 		strcat(stat_buf, "\n");
 	
 		ret += sprintf(buf + ret, stat_buf);
+	} else {
+		strcat(buf, "\n");
+		ret++;
 	}
 #undef STATBIT
 #undef INFOBIT
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/usb/host/ehci-hcd.c	Wed Nov 12 21:06:47 2003
@@ -426,8 +426,11 @@
 	 */
 	if (HCC_64BIT_ADDR (hcc_params)) {
 		writel (0, &ehci->regs->segment);
+#if 0
+// this is deeply broken on almost all architectures
 		if (!pci_set_dma_mask (ehci->hcd.pdev, 0xffffffffffffffffULL))
 			ehci_info (ehci, "enabled 64bit PCI DMA\n");
+#endif
 	}
 
 	/* help hc dma work well with cachelines */
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c	Wed Nov 12 21:06:47 2003
+++ b/drivers/usb/net/kaweth.c	Wed Nov 12 21:06:47 2003
@@ -1120,8 +1120,11 @@
 
 	usb_set_intfdata(intf, kaweth);
 
+#if 0
+// dma_supported() is deeply broken on almost all architectures
 	if (dma_supported (&intf->dev, 0xffffffffffffffffULL))
 		kaweth->net->features |= NETIF_F_HIGHDMA;
+#endif
 
 	SET_NETDEV_DEV(netdev, &intf->dev);
 	if (register_netdev(netdev) != 0) {
diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
--- a/drivers/usb/net/usbnet.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/usb/net/usbnet.c	Wed Nov 12 21:06:46 2003
@@ -2972,9 +2972,12 @@
 	strcpy (net->name, "usb%d");
 	memcpy (net->dev_addr, node_id, sizeof node_id);
 
+#if 0
+// dma_supported() is deeply broken on almost all architectures
 	// possible with some EHCI controllers
 	if (dma_supported (&udev->dev, 0xffffffffffffffffULL))
 		net->features |= NETIF_F_HIGHDMA;
+#endif
 
 	net->change_mtu = usbnet_change_mtu;
 	net->get_stats = usbnet_get_stats;
diff -Nru a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig	Wed Nov 12 21:06:47 2003
+++ b/drivers/usb/serial/Kconfig	Wed Nov 12 21:06:47 2003
@@ -73,7 +73,7 @@
 
 config USB_SERIAL_WHITEHEAT
 	tristate "USB ConnectTech WhiteHEAT Serial Driver"
-	depends on USB_SERIAL
+	depends on USB_SERIAL && BROKEN_ON_SMP
 	help
 	  Say Y here if you want to use a ConnectTech WhiteHEAT 4 port
 	  USB to serial converter device.
diff -Nru a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
--- a/drivers/usb/serial/digi_acceleport.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/usb/serial/digi_acceleport.c	Wed Nov 12 21:06:46 2003
@@ -444,7 +444,7 @@
 /* Local Function Declarations */
 
 static void digi_wakeup_write( struct usb_serial_port *port );
-static void digi_wakeup_write_lock( struct usb_serial_port *port );
+static void digi_wakeup_write_lock(void *);
 static int digi_write_oob_command( struct usb_serial_port *port,
 	unsigned char *buf, int count, int interruptible );
 static int digi_write_inb_command( struct usb_serial_port *port,
@@ -608,9 +608,9 @@
 *  on writes.
 */
 
-static void digi_wakeup_write_lock( struct usb_serial_port *port )
+static void digi_wakeup_write_lock(void *arg)
 {
-
+	struct usb_serial_port *port = arg;
 	unsigned long flags;
 	struct digi_port *priv = usb_get_serial_port_data(port);
 
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c	Wed Nov 12 21:06:46 2003
+++ b/drivers/usb/storage/usb.c	Wed Nov 12 21:06:46 2003
@@ -417,10 +417,21 @@
 		scsi_unlock(host);
 	} /* for (;;) */
 
-	/* notify the exit routine that we're actually exiting now */
-	complete(&(us->notify));
-
-	return 0;
+	/* notify the exit routine that we're actually exiting now 
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	complete_and_exit(&(us->notify), 0);
 }	
 
 /***********************************************************************
diff -Nru a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
--- a/drivers/video/radeonfb.c	Wed Nov 12 21:06:48 2003
+++ b/drivers/video/radeonfb.c	Wed Nov 12 21:06:48 2003
@@ -1432,7 +1432,7 @@
 			den = 1;
 			v.red.offset = 10;
 			v.green.offset = 5;
-			v.red.offset = 0;
+			v.blue.offset = 0;
 			v.red.length = v.green.length = v.blue.length = 5;
 			v.transp.offset = v.transp.length = 0;
 			break;
diff -Nru a/fs/aio.c b/fs/aio.c
--- a/fs/aio.c	Wed Nov 12 21:06:46 2003
+++ b/fs/aio.c	Wed Nov 12 21:06:46 2003
@@ -376,6 +376,11 @@
  *	Allocate a slot for an aio request.  Increments the users count
  * of the kioctx so that the kioctx stays around until all requests are
  * complete.  Returns NULL if no requests are free.
+ *
+ * Returns with kiocb->users set to 2.  The io submit code path holds
+ * an extra reference while submitting the i/o.
+ * This prevents races between the aio code path referencing the
+ * req (after submitting it) and aio_complete() freeing the req.
  */
 static struct kiocb *FASTCALL(__aio_get_req(struct kioctx *ctx));
 static struct kiocb *__aio_get_req(struct kioctx *ctx)
@@ -389,7 +394,7 @@
 		return NULL;
 
 	req->ki_flags = 1 << KIF_LOCKED;
-	req->ki_users = 1;
+	req->ki_users = 2;
 	req->ki_key = 0;
 	req->ki_ctx = ctx;
 	req->ki_cancel = NULL;
@@ -1009,7 +1014,7 @@
 	if (unlikely(!file))
 		return -EBADF;
 
-	req = aio_get_req(ctx);
+	req = aio_get_req(ctx);		/* returns with 2 references to req */
 	if (unlikely(!req)) {
 		fput(file);
 		return -EAGAIN;
@@ -1069,13 +1074,15 @@
 		ret = -EINVAL;
 	}
 
+	aio_put_req(req);	/* drop extra ref to req */
 	if (likely(-EIOCBQUEUED == ret))
 		return 0;
-	aio_complete(req, ret, 0);
+	aio_complete(req, ret, 0);	/* will drop i/o ref to req */
 	return 0;
 
 out_put_req:
-	aio_put_req(req);
+	aio_put_req(req);	/* drop extra ref to req */
+	aio_put_req(req);	/* drop i/o ref to req */
 	return ret;
 }
 
diff -Nru a/fs/binfmt_misc.c b/fs/binfmt_misc.c
--- a/fs/binfmt_misc.c	Wed Nov 12 21:06:46 2003
+++ b/fs/binfmt_misc.c	Wed Nov 12 21:06:46 2003
@@ -529,8 +529,8 @@
 	inode->u.generic_ip = e;
 	inode->i_fop = &bm_entry_operations;
 
-	write_lock(&entries_lock);
 	d_instantiate(dentry, inode);
+	write_lock(&entries_lock);
 	list_add(&e->list, &entries);
 	write_unlock(&entries_lock);
 
diff -Nru a/fs/char_dev.c b/fs/char_dev.c
--- a/fs/char_dev.c	Wed Nov 12 21:06:46 2003
+++ b/fs/char_dev.c	Wed Nov 12 21:06:46 2003
@@ -434,7 +434,7 @@
 
 static struct kobject *base_probe(dev_t dev, int *part, void *data)
 {
-	request_module("char-major-%d", MAJOR(dev));
+	request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev));
 	return NULL;
 }
 
diff -Nru a/fs/cramfs/inode.c b/fs/cramfs/inode.c
--- a/fs/cramfs/inode.c	Wed Nov 12 21:06:45 2003
+++ b/fs/cramfs/inode.c	Wed Nov 12 21:06:45 2003
@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/blkdev.h>
 #include <linux/cramfs_fs.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/cramfs_fs_sb.h>
 #include <linux/buffer_head.h>
@@ -206,10 +205,10 @@
 	sb_set_blocksize(sb, PAGE_CACHE_SIZE);
 
 	/* Invalidate the read buffers on mount: think disk change.. */
+	down(&read_mutex);
 	for (i = 0; i < READ_BUFFERS; i++)
 		buffer_blocknr[i] = -1;
 
-	down(&read_mutex);
 	/* Read the first block and get the superblock from it */
 	memcpy(&super, cramfs_read(sb, 0, sizeof(super)), sizeof(super));
 	up(&read_mutex);
@@ -217,7 +216,9 @@
 	/* Do sanity checks on the superblock */
 	if (super.magic != CRAMFS_MAGIC) {
 		/* check at 512 byte offset */
+		down(&read_mutex);
 		memcpy(&super, cramfs_read(sb, 512, sizeof(super)), sizeof(super));
+		up(&read_mutex);
 		if (super.magic != CRAMFS_MAGIC) {
 			if (!silent)
 				printk(KERN_ERR "cramfs: wrong magic\n");
@@ -288,6 +289,7 @@
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct super_block *sb = inode->i_sb;
+	char *buf;
 	unsigned int offset;
 	int copied;
 
@@ -299,18 +301,21 @@
 	if (offset & 3)
 		return -EINVAL;
 
-	lock_kernel();
+	buf = kmalloc(256, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	copied = 0;
 	while (offset < inode->i_size) {
 		struct cramfs_inode *de;
 		unsigned long nextoffset;
 		char *name;
+		ino_t ino;
+		mode_t mode;
 		int namelen, error;
 
 		down(&read_mutex);
 		de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256);
-		up(&read_mutex);
 		name = (char *)(de+1);
 
 		/*
@@ -319,17 +324,21 @@
 		 * with zeroes.
 		 */
 		namelen = de->namelen << 2;
+		memcpy(buf, name, namelen);
+		ino = CRAMINO(de);
+		mode = de->mode;
+		up(&read_mutex);
 		nextoffset = offset + sizeof(*de) + namelen;
 		for (;;) {
 			if (!namelen) {
-				unlock_kernel();
+				kfree(buf);
 				return -EIO;
 			}
-			if (name[namelen-1])
+			if (buf[namelen-1])
 				break;
 			namelen--;
 		}
-		error = filldir(dirent, name, namelen, offset, CRAMINO(de), de->mode >> 12);
+		error = filldir(dirent, buf, namelen, offset, ino, mode >> 12);
 		if (error)
 			break;
 
@@ -337,7 +346,7 @@
 		filp->f_pos = offset;
 		copied++;
 	}
-	unlock_kernel();
+	kfree(buf);
 	return 0;
 }
 
@@ -349,16 +358,14 @@
 	unsigned int offset = 0;
 	int sorted;
 
-	lock_kernel();
+	down(&read_mutex);
 	sorted = CRAMFS_SB(dir->i_sb)->flags & CRAMFS_FLAG_SORTED_DIRS;
 	while (offset < dir->i_size) {
 		struct cramfs_inode *de;
 		char *name;
 		int namelen, retval;
 
-		down(&read_mutex);
 		de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256);
-		up(&read_mutex);
 		name = (char *)(de+1);
 
 		/* Try to take advantage of sorted directories */
@@ -374,7 +381,7 @@
 
 		for (;;) {
 			if (!namelen) {
-				unlock_kernel();
+				up(&read_mutex);
 				return ERR_PTR(-EIO);
 			}
 			if (name[namelen-1])
@@ -387,15 +394,16 @@
 		if (retval > 0)
 			continue;
 		if (!retval) {
-			d_add(dentry, get_cramfs_inode(dir->i_sb, de));
-			unlock_kernel();
+			struct cramfs_inode entry = *de;
+			up(&read_mutex);
+			d_add(dentry, get_cramfs_inode(dir->i_sb, &entry));
 			return NULL;
 		}
 		/* else (retval < 0) */
 		if (sorted)
 			break;
 	}
-	unlock_kernel();
+	up(&read_mutex);
 	d_add(dentry, NULL);
 	return NULL;
 }
@@ -452,6 +460,7 @@
  * A directory can only readdir
  */
 static struct file_operations cramfs_directory_operations = {
+	.llseek		= generic_file_llseek,
 	.read		= generic_read_dir,
 	.readdir	= cramfs_readdir,
 };
diff -Nru a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c	Wed Nov 12 21:06:47 2003
+++ b/fs/direct-io.c	Wed Nov 12 21:06:47 2003
@@ -677,7 +677,7 @@
 
 	this_chunk_bytes = this_chunk_blocks << dio->blkbits;
 
-	page = ZERO_PAGE(dio->cur_user_address);
+	page = ZERO_PAGE(dio->curr_user_address);
 	if (submit_page_section(dio, page, 0, this_chunk_bytes, 
 				dio->next_block_for_io))
 		return;
diff -Nru a/fs/dquot.c b/fs/dquot.c
--- a/fs/dquot.c	Wed Nov 12 21:06:47 2003
+++ b/fs/dquot.c	Wed Nov 12 21:06:47 2003
@@ -128,16 +128,17 @@
 	if (!actqf || !try_module_get(actqf->qf_owner)) {
 		int qm;
 
+		spin_unlock(&dq_list_lock);
+		
 		for (qm = 0; module_names[qm].qm_fmt_id && module_names[qm].qm_fmt_id != id; qm++);
-		if (!module_names[qm].qm_fmt_id || request_module(module_names[qm].qm_mod_name)) {
-			actqf = NULL;
-			goto out;
-		}
+		if (!module_names[qm].qm_fmt_id || request_module(module_names[qm].qm_mod_name))
+			return NULL;
+
+		spin_lock(&dq_list_lock);
 		for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
 		if (actqf && !try_module_get(actqf->qf_owner))
 			actqf = NULL;
 	}
-out:
 	spin_unlock(&dq_list_lock);
 	return actqf;
 }
diff -Nru a/fs/ext2/balloc.c b/fs/ext2/balloc.c
--- a/fs/ext2/balloc.c	Wed Nov 12 21:06:46 2003
+++ b/fs/ext2/balloc.c	Wed Nov 12 21:06:46 2003
@@ -402,6 +402,7 @@
 	 * Now search the rest of the groups.  We assume that 
 	 * i and desc correctly point to the last group visited.
 	 */
+retry:
 	for (bit = 0; !group_alloc &&
 			bit < sbi->s_groups_count; bit++) {
 		group_no++;
@@ -425,11 +426,12 @@
 	ret_block = grab_block(sb_bgl_lock(sbi, group_no), bitmap_bh->b_data,
 				group_size, 0);
 	if (ret_block < 0) {
-		ext2_error (sb, "ext2_new_block",
-			"Free blocks count corrupted for block group %d",
-				group_no);
+		/*
+		 * Someone else grabbed the last free block in this blockgroup
+		 * before us.  Retry the scan.
+		 */
 		group_alloc = 0;
-		goto io_error;
+		goto retry;
 	}
 
 got_block:
diff -Nru a/fs/fat/inode.c b/fs/fat/inode.c
--- a/fs/fat/inode.c	Wed Nov 12 21:06:46 2003
+++ b/fs/fat/inode.c	Wed Nov 12 21:06:46 2003
@@ -964,13 +964,17 @@
 		error = first;
 		goto out_fail;
 	}
-	if (FAT_FIRST_ENT(sb, media) != first
-	    && (media != 0xf8 || FAT_FIRST_ENT(sb, 0xfe) != first)) {
-		if (!silent) {
+	if (FAT_FIRST_ENT(sb, media) == first) {
+		/* all is as it should be */
+	} else if (media == 0xf8 && FAT_FIRST_ENT(sb, 0xfe) == first) {
+		/* bad, reported on pc9800 */
+	} else if (first == 0) {
+		/* bad, reported with a SmartMedia card */
+	} else {
+		if (!silent)
 			printk(KERN_ERR "FAT: invalid first entry of FAT "
 			       "(0x%x != 0x%x)\n",
 			       FAT_FIRST_ENT(sb, media), first);
-		}
 		goto out_invalid;
 	}
 
diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c
--- a/fs/jbd/journal.c	Wed Nov 12 21:06:46 2003
+++ b/fs/jbd/journal.c	Wed Nov 12 21:06:46 2003
@@ -1729,8 +1729,18 @@
 			J_ASSERT_BH(bh, buffer_jbd(bh));
 			J_ASSERT_BH(bh, jh2bh(jh) == bh);
 			BUFFER_TRACE(bh, "remove journal_head");
-			J_ASSERT_BH(bh, !jh->b_frozen_data);
-			J_ASSERT_BH(bh, !jh->b_committed_data);
+			if (jh->b_frozen_data) {
+				printk(KERN_WARNING "%s: freeing "
+						"b_frozen_data\n",
+						__FUNCTION__);
+				kfree(jh->b_frozen_data);
+			}
+			if (jh->b_committed_data) {
+				printk(KERN_WARNING "%s: freeing "
+						"b_committed_data\n",
+						__FUNCTION__);
+				kfree(jh->b_committed_data);
+			}
 			bh->b_private = NULL;
 			jh->b_bh = NULL;	/* debug, really */
 			clear_buffer_jbd(bh);
diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c
--- a/fs/jbd/transaction.c	Wed Nov 12 21:06:46 2003
+++ b/fs/jbd/transaction.c	Wed Nov 12 21:06:46 2003
@@ -147,10 +147,13 @@
 	 * lock to be released.
 	 */
 	if (transaction->t_state == T_LOCKED) {
+		DEFINE_WAIT(wait);
+
+		prepare_to_wait(&journal->j_wait_transaction_locked,
+					&wait, TASK_UNINTERRUPTIBLE);
 		spin_unlock(&journal->j_state_lock);
-		jbd_debug(3, "Handle %p stalling...\n", handle);
-		wait_event(journal->j_wait_transaction_locked,
-				transaction->t_state != T_LOCKED);
+		schedule();
+		finish_wait(&journal->j_wait_transaction_locked, &wait);
 		goto repeat;
 	}
 
diff -Nru a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
--- a/fs/jfs/jfs_metapage.c	Wed Nov 12 21:06:46 2003
+++ b/fs/jfs/jfs_metapage.c	Wed Nov 12 21:06:46 2003
@@ -511,9 +511,6 @@
 		if (mp) {
 			set_bit(META_discard, &mp->flag);
 			spin_unlock(&meta_lock);
-			lock_page(mp->page);
-			block_invalidatepage(mp->page, 0);
-			unlock_page(mp->page);
 		} else {
 			spin_unlock(&meta_lock);
 			page = find_lock_page(mapping, lblock>>l2BlocksPerPage);
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	Wed Nov 12 21:06:47 2003
+++ b/fs/jfs/namei.c	Wed Nov 12 21:06:47 2003
@@ -772,15 +772,16 @@
 	jfs_info("jfs_link: %s %s", old_dentry->d_name.name,
 		 dentry->d_name.name);
 
+	if (ip->i_nlink == JFS_LINK_MAX)
+		return -EMLINK;
+
+	if (ip->i_nlink == 0)
+		return -ENOENT;
+
 	tid = txBegin(ip->i_sb, 0);
 
 	down(&JFS_IP(dir)->commit_sem);
 	down(&JFS_IP(ip)->commit_sem);
-
-	if (ip->i_nlink == JFS_LINK_MAX) {
-		rc = -EMLINK;
-		goto out;
-	}
 
 	/*
 	 * scan parent directory for entry/freespace
diff -Nru a/fs/minix/inode.c b/fs/minix/inode.c
--- a/fs/minix/inode.c	Wed Nov 12 21:06:46 2003
+++ b/fs/minix/inode.c	Wed Nov 12 21:06:46 2003
@@ -547,6 +547,8 @@
  */
 void minix_truncate(struct inode * inode)
 {
+	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
+		return;
 	if (INODE_VERSION(inode) == MINIX_V1)
 		V1_minix_truncate(inode);
 	else
diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
--- a/fs/nfsd/vfs.c	Wed Nov 12 21:06:46 2003
+++ b/fs/nfsd/vfs.c	Wed Nov 12 21:06:46 2003
@@ -1368,7 +1368,6 @@
 		nfsd_sync_dir(tdentry);
 		nfsd_sync_dir(fdentry);
 	}
-	dput(ndentry);
 
  out_dput_new:
 	dput(ndentry);
diff -Nru a/fs/partitions/msdos.c b/fs/partitions/msdos.c
--- a/fs/partitions/msdos.c	Wed Nov 12 21:06:47 2003
+++ b/fs/partitions/msdos.c	Wed Nov 12 21:06:47 2003
@@ -425,6 +425,10 @@
 		put_partition(state, slot, start, size);
 		if (SYS_IND(p) == LINUX_RAID_PARTITION)
 			state->parts[slot].flags = 1;
+		if (SYS_IND(p) == DM6_PARTITION)
+			printk("[DM]");
+		if (SYS_IND(p) == EZD_PARTITION)
+			printk("[EZD]");
 	}
 
 	printk("\n");
diff -Nru a/include/asm-h8300/smplock.h b/include/asm-h8300/smplock.h
--- a/include/asm-h8300/smplock.h	Wed Nov 12 21:06:47 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,51 +0,0 @@
-/*
- * <asm/smplock.h>
- *
- * Default SMP lock implementation
- */
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-
-extern spinlock_t kernel_flag;
-
-#define kernel_locked()		spin_is_locked(&kernel_flag)
-
-/*
- * Release global kernel lock and global interrupt lock
- */
-#define release_kernel_lock(task, cpu) \
-do { \
-	if (task->lock_depth >= 0) \
-		spin_unlock(&kernel_flag); \
-	release_irqlock(cpu); \
-	__sti(); \
-} while (0)
-
-/*
- * Re-acquire the kernel lock
- */
-#define reacquire_kernel_lock(task) \
-do { \
-	if (task->lock_depth >= 0) \
-		spin_lock(&kernel_flag); \
-} while (0)
-
-
-/*
- * Getting the big kernel lock.
- *
- * This cannot happen asynchronously,
- * so we only need to worry about other
- * CPU's.
- */
-extern __inline__ void lock_kernel(void)
-{
-	if (!++current->lock_depth)
-		spin_lock(&kernel_flag);
-}
-
-extern __inline__ void unlock_kernel(void)
-{
-	if (--current->lock_depth < 0)
-		spin_unlock(&kernel_flag);
-}
diff -Nru a/include/asm-i386/checksum.h b/include/asm-i386/checksum.h
--- a/include/asm-i386/checksum.h	Wed Nov 12 21:06:47 2003
+++ b/include/asm-i386/checksum.h	Wed Nov 12 21:06:47 2003
@@ -83,7 +83,8 @@
 	   are modified, we must also specify them as outputs, or gcc
 	   will assume they contain their original values. */
 	: "=r" (sum), "=r" (iph), "=r" (ihl)
-	: "1" (iph), "2" (ihl));
+	: "1" (iph), "2" (ihl)
+	: "memory");
 	return(sum);
 }
 
diff -Nru a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
--- a/include/asm-ia64/pgtable.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-ia64/pgtable.h	Wed Nov 12 21:06:46 2003
@@ -63,7 +63,8 @@
 #define _PAGE_FILE		(1 << 1)		/* see swap & file pte remarks below */
 
 #define _PFN_MASK		_PAGE_PPN_MASK
-#define _PAGE_CHG_MASK		(_PFN_MASK | _PAGE_A | _PAGE_D)
+/* Mask of bits which may be changed by pte_modify(); the odd bits are there for _PAGE_PROTNONE */
+#define _PAGE_CHG_MASK	(_PAGE_P | _PAGE_PROTNONE | _PAGE_PL_MASK | _PAGE_AR_MASK | _PAGE_ED)
 
 #define _PAGE_SIZE_4K	12
 #define _PAGE_SIZE_8K	13
@@ -230,7 +231,7 @@
 #define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
 
 #define pte_modify(_pte, newprot) \
-	(__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
+	(__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
 
 #define page_pte_prot(page,prot)	mk_pte(page, prot)
 #define page_pte(page)			page_pte_prot(page, __pgprot(0))
diff -Nru a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h
--- a/include/asm-ia64/sn/nodepda.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-ia64/sn/nodepda.h	Wed Nov 12 21:06:46 2003
@@ -128,7 +128,7 @@
  * Check if given a compact node id the corresponding node has all the
  * cpus disabled. 
  */
-#define is_headless_node(cnode)		(!node_to_cpu_mask[cnode])
+#define is_headless_node(cnode)		(nr_cpus_node(cnode) == 0)
 
 /*
  * Check if given a node vertex handle the corresponding node has all the
diff -Nru a/include/asm-sparc/bitext.h b/include/asm-sparc/bitext.h
--- a/include/asm-sparc/bitext.h	Wed Nov 12 21:06:47 2003
+++ b/include/asm-sparc/bitext.h	Wed Nov 12 21:06:47 2003
@@ -7,7 +7,7 @@
 #ifndef _SPARC_BITEXT_H
 #define _SPARC_BITEXT_H
 
-#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
 
 struct bit_map {
 	spinlock_t lock;
diff -Nru a/include/asm-sparc/ioctl.h b/include/asm-sparc/ioctl.h
--- a/include/asm-sparc/ioctl.h	Wed Nov 12 21:06:47 2003
+++ b/include/asm-sparc/ioctl.h	Wed Nov 12 21:06:47 2003
@@ -54,7 +54,9 @@
                             (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) )
 #define _IOC_TYPE(nr)       (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
 #define _IOC_NR(nr)         (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_XSIZEMASK)
+#define _IOC_SIZE(nr)   \
+ ((((((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) & (_IOC_WRITE|_IOC_READ)) == 0)?    \
+                         0: (((nr) >> _IOC_SIZESHIFT) & _IOC_XSIZEMASK))
 
 /* ...and for the PCMCIA and sound. */
 #define IOC_IN          (_IOC_WRITE << _IOC_DIRSHIFT)
diff -Nru a/include/asm-sparc/namei.h b/include/asm-sparc/namei.h
--- a/include/asm-sparc/namei.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-sparc/namei.h	Wed Nov 12 21:06:46 2003
@@ -8,8 +8,8 @@
 #ifndef __SPARC_NAMEI_H
 #define __SPARC_NAMEI_H
 
-#define SPARC_BSD_EMUL "usr/gnemul/sunos/"
-#define SPARC_SOL_EMUL "usr/gnemul/solaris/"
+#define SPARC_BSD_EMUL "/usr/gnemul/sunos/"
+#define SPARC_SOL_EMUL "/usr/gnemul/solaris/"
 
 static inline char * __emul_prefix(void)
 {
diff -Nru a/include/asm-sparc/pcic.h b/include/asm-sparc/pcic.h
--- a/include/asm-sparc/pcic.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-sparc/pcic.h	Wed Nov 12 21:06:46 2003
@@ -11,7 +11,6 @@
 
 #include <linux/types.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
 #include <asm/pbm.h>
diff -Nru a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
--- a/include/asm-sparc/unistd.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-sparc/unistd.h	Wed Nov 12 21:06:46 2003
@@ -284,10 +284,15 @@
 #define __NR_timer_delete	265
 #define __NR_timer_create	266
 /* #define __NR_vserver		267 Reserved for VSERVER */
-/* WARNING: You MAY NOT add syscall numbers larger than 267, since
+#define __NR_io_setup		268
+#define __NR_io_destroy		268
+#define __NR_io_submit		269
+#define __NR_io_cancel		270
+#define __NR_io_getevents	271
+/* WARNING: You MAY NOT add syscall numbers larger than 271, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 267 entries (starting at zero).  Therefore
- *          find a free slot in the 0-266 range.
+ *          sized to have 272 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-271 range.
  */
 
 #define _syscall0(type,name) \
diff -Nru a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h
--- a/include/asm-sparc64/floppy.h	Wed Nov 12 21:06:48 2003
+++ b/include/asm-sparc64/floppy.h	Wed Nov 12 21:06:48 2003
@@ -62,8 +62,6 @@
 	void		(*fd_set_dma_addr) (char *);
 	void		(*fd_set_dma_count) (int);
 	unsigned int	(*get_dma_residue) (void);
-	void		(*fd_enable_irq) (void);
-	void		(*fd_disable_irq) (void);
 	int		(*fd_request_irq) (void);
 	void		(*fd_free_irq) (void);
 	int		(*fd_eject) (int);
@@ -82,8 +80,6 @@
 #define fd_set_dma_addr(addr)     sun_fdops.fd_set_dma_addr(addr)
 #define fd_set_dma_count(count)   sun_fdops.fd_set_dma_count(count)
 #define get_dma_residue(x)        sun_fdops.get_dma_residue()
-#define fd_enable_irq()           sun_fdops.fd_enable_irq()
-#define fd_disable_irq()          sun_fdops.fd_disable_irq()
 #define fd_cacheflush(addr, size) /* nothing... */
 #define fd_request_irq()          sun_fdops.fd_request_irq()
 #define fd_free_irq()             sun_fdops.fd_free_irq()
@@ -232,14 +228,6 @@
 	return 0;
 }
 
-static void sun_fd_enable_irq(void)
-{
-}
-
-static void sun_fd_disable_irq(void)
-{
-}
-
 static void sun_fd_free_irq(void)
 {
 }
@@ -391,25 +379,14 @@
 	return ebus_dma_residue(&sun_pci_fd_ebus_dma);
 }
 
-static void sun_pci_fd_enable_irq(void)
-{
-	ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
-}
-
-static void sun_pci_fd_disable_irq(void)
-{
-	ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
-}
-
 static int sun_pci_fd_request_irq(void)
 {
-	/* Done by enable/disable irq */
-	return 0;
+	return ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 1);
 }
 
 static void sun_pci_fd_free_irq(void)
 {
-	/* Done by enable/disable irq */
+	ebus_dma_irq_enable(&sun_pci_fd_ebus_dma, 0);
 }
 
 static int sun_pci_fd_eject(int drive)
@@ -587,8 +564,6 @@
 	sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
 	sun_fdops.get_dma_residue = sun_get_dma_residue;
 
-	sun_fdops.fd_enable_irq = sun_fd_enable_irq;
-	sun_fdops.fd_disable_irq = sun_fd_disable_irq;
 	sun_fdops.fd_request_irq = sun_fd_request_irq;
 	sun_fdops.fd_free_irq = sun_fd_free_irq;
 
@@ -694,8 +669,6 @@
 		sun_fdops.fd_set_dma_count = sun_pci_fd_set_dma_count;
 		sun_fdops.get_dma_residue = sun_pci_get_dma_residue;
 
-		sun_fdops.fd_enable_irq = sun_pci_fd_enable_irq;
-		sun_fdops.fd_disable_irq = sun_pci_fd_disable_irq;
 		sun_fdops.fd_request_irq = sun_pci_fd_request_irq;
 		sun_fdops.fd_free_irq = sun_pci_fd_free_irq;
 
@@ -810,8 +783,6 @@
 	sun_fdops.fd_set_dma_count = sun_fd_set_dma_count;
 	sun_fdops.get_dma_residue = sun_get_dma_residue;
 
-	sun_fdops.fd_enable_irq = sun_fd_enable_irq;
-	sun_fdops.fd_disable_irq = sun_fd_disable_irq;
 	sun_fdops.fd_request_irq = sun_fd_request_irq;
 	sun_fdops.fd_free_irq = sun_fd_free_irq;
 
diff -Nru a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h
--- a/include/asm-sparc64/hardirq.h	Wed Nov 12 21:06:47 2003
+++ b/include/asm-sparc64/hardirq.h	Wed Nov 12 21:06:47 2003
@@ -79,7 +79,8 @@
 #define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
 
 #ifdef CONFIG_PREEMPT
-# define in_atomic()	(preempt_count() != kernel_locked())
+# include <linux/smp_lock.h>
+# define in_atomic()	((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
 # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
 # define in_atomic()	(preempt_count() != 0)
diff -Nru a/include/asm-sparc64/ioctl.h b/include/asm-sparc64/ioctl.h
--- a/include/asm-sparc64/ioctl.h	Wed Nov 12 21:06:47 2003
+++ b/include/asm-sparc64/ioctl.h	Wed Nov 12 21:06:47 2003
@@ -54,7 +54,9 @@
                             (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) )
 #define _IOC_TYPE(nr)       (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
 #define _IOC_NR(nr)         (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)       (((nr) >> _IOC_SIZESHIFT) & _IOC_XSIZEMASK)
+#define _IOC_SIZE(nr)   \
+ ((((((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) & (_IOC_WRITE|_IOC_READ)) == 0)?    \
+                         0: (((nr) >> _IOC_SIZESHIFT) & _IOC_XSIZEMASK))
 
 /* ...and for the PCMCIA and sound. */
 #define IOC_IN          (_IOC_WRITE << _IOC_DIRSHIFT)
diff -Nru a/include/asm-sparc64/namei.h b/include/asm-sparc64/namei.h
--- a/include/asm-sparc64/namei.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-sparc64/namei.h	Wed Nov 12 21:06:46 2003
@@ -8,8 +8,8 @@
 #ifndef __SPARC64_NAMEI_H
 #define __SPARC64_NAMEI_H
 
-#define SPARC_BSD_EMUL "usr/gnemul/sunos/"
-#define SPARC_SOL_EMUL "usr/gnemul/solaris/"
+#define SPARC_BSD_EMUL "/usr/gnemul/sunos/"
+#define SPARC_SOL_EMUL "/usr/gnemul/solaris/"
 
 static inline char * __emul_prefix(void)
 {
diff -Nru a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
--- a/include/asm-sparc64/pgtable.h	Wed Nov 12 21:06:45 2003
+++ b/include/asm-sparc64/pgtable.h	Wed Nov 12 21:06:45 2003
@@ -156,7 +156,7 @@
 #define __ACCESS_BITS	(_PAGE_ACCESSED | _PAGE_READ | _PAGE_R)
 #define __PRIV_BITS	_PAGE_P
 
-#define PAGE_NONE	__pgprot (_PAGE_PRESENT | _PAGE_ACCESSED)
+#define PAGE_NONE	__pgprot (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_CACHE)
 
 /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
 #define PAGE_SHARED	__pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
@@ -171,12 +171,8 @@
 #define PAGE_KERNEL	__pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
 				  __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS)
 
-#define PAGE_INVALID	__pgprot (0)
-
 #define _PFN_MASK	_PAGE_PADDR
 
-#define _PAGE_CHG_MASK	(_PFN_MASK | _PAGE_MODIFIED | _PAGE_ACCESSED | _PAGE_PRESENT | _PAGE_SZBITS)
-
 #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
 
 #define __P000	PAGE_NONE
@@ -224,9 +220,13 @@
 static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
 {
 	pte_t __pte;
+	const unsigned long preserve_mask = (_PFN_MASK |
+					     _PAGE_MODIFIED | _PAGE_ACCESSED |
+					     _PAGE_CACHE | _PAGE_E |
+					     _PAGE_PRESENT | _PAGE_SZBITS);
 
-	pte_val(__pte) = (pte_val(orig_pte) & _PAGE_CHG_MASK) |
-		pgprot_val(new_prot);
+	pte_val(__pte) = (pte_val(orig_pte) & preserve_mask) |
+		(pgprot_val(new_prot) & ~preserve_mask);
 
 	return __pte;
 }
diff -Nru a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
--- a/include/asm-sparc64/spinlock.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-sparc64/spinlock.h	Wed Nov 12 21:06:46 2003
@@ -118,11 +118,13 @@
 extern void __read_unlock(rwlock_t *);
 extern void __write_lock(rwlock_t *);
 extern void __write_unlock(rwlock_t *);
+extern int __write_trylock(rwlock_t *);
 
 #define _raw_read_lock(p)	__read_lock(p)
 #define _raw_read_unlock(p)	__read_unlock(p)
 #define _raw_write_lock(p)	__write_lock(p)
 #define _raw_write_unlock(p)	__write_unlock(p)
+#define _raw_write_trylock(p)	__write_trylock(p)
 
 #else /* !(CONFIG_DEBUG_SPINLOCK) */
 
diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
--- a/include/asm-sparc64/unistd.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-sparc64/unistd.h	Wed Nov 12 21:06:46 2003
@@ -286,10 +286,15 @@
 #define __NR_timer_delete	265
 #define __NR_timer_create	266
 /* #define __NR_vserver		267 Reserved for VSERVER */
-/* WARNING: You MAY NOT add syscall numbers larger than 267, since
+#define __NR_io_setup		268
+#define __NR_io_destroy		268
+#define __NR_io_submit		269
+#define __NR_io_cancel		270
+#define __NR_io_getevents	271
+/* WARNING: You MAY NOT add syscall numbers larger than 271, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 267 entries (starting at zero).  Therefore
- *          find a free slot in the 0-266 range.
+ *          sized to have 272 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-271 range.
  */
 
 #define _syscall0(type,name) \
diff -Nru a/include/asm-x86_64/checksum.h b/include/asm-x86_64/checksum.h
--- a/include/asm-x86_64/checksum.h	Wed Nov 12 21:06:47 2003
+++ b/include/asm-x86_64/checksum.h	Wed Nov 12 21:06:47 2003
@@ -68,7 +68,8 @@
 	   are modified, we must also specify them as outputs, or gcc
 	   will assume they contain their original values. */
 	: "=r" (sum), "=r" (iph), "=r" (ihl)
-	: "1" (iph), "2" (ihl));
+	: "1" (iph), "2" (ihl)
+	: "memory");
 	return(sum);
 }
 
diff -Nru a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
--- a/include/asm-x86_64/desc.h	Wed Nov 12 21:06:48 2003
+++ b/include/asm-x86_64/desc.h	Wed Nov 12 21:06:48 2003
@@ -118,7 +118,7 @@
 	d.base1 = PTR_MIDDLE(tss) & 0xFF; 
 	d.type = type;
 	d.p = 1; 
-	d.limit1 = 0xF;
+	d.limit1 = (size >> 16) & 0xF;
 	d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; 
 	d.base3 = PTR_HIGH(tss); 
 	memcpy(ptr, &d, 16); 
diff -Nru a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
--- a/include/asm-x86_64/hw_irq.h	Wed Nov 12 21:06:48 2003
+++ b/include/asm-x86_64/hw_irq.h	Wed Nov 12 21:06:48 2003
@@ -76,8 +76,8 @@
 
 
 #ifndef __ASSEMBLY__
-extern int irq_vector[NR_IRQS];
-#define IO_APIC_VECTOR(irq)	irq_vector[irq]
+extern u8 irq_vector[NR_IRQ_VECTORS];
+#define IO_APIC_VECTOR(irq)	((int)irq_vector[irq])
 
 /*
  * Various low-level irq details needed by irq.c, process.c,
diff -Nru a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h
--- a/include/asm-x86_64/irq.h	Wed Nov 12 21:06:45 2003
+++ b/include/asm-x86_64/irq.h	Wed Nov 12 21:06:45 2003
@@ -22,6 +22,7 @@
  * the usable vector space is 0x20-0xff (224 vectors)
  */
 #define NR_IRQS 224
+#define NR_IRQ_VECTORS NR_IRQS
 
 static __inline__ int irq_canonicalize(int irq)
 {
diff -Nru a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
--- a/include/asm-x86_64/pci.h	Wed Nov 12 21:06:46 2003
+++ b/include/asm-x86_64/pci.h	Wed Nov 12 21:06:46 2003
@@ -24,6 +24,8 @@
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		(pci_mem_start)
 
+#define PCIBIOS_MIN_CARDBUS_IO	0x4000
+
 void pcibios_config_init(void);
 struct pci_bus * pcibios_scan_root(int bus);
 extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
diff -Nru a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
--- a/include/asm-x86_64/processor.h	Wed Nov 12 21:06:48 2003
+++ b/include/asm-x86_64/processor.h	Wed Nov 12 21:06:48 2003
@@ -263,8 +263,8 @@
 #define DOUBLEFAULT_STACK 2 
 #define NMI_STACK 3 
 #define N_EXCEPTION_STACKS 3  /* hw limit: 7 */
-#define EXCEPTION_STKSZ 1024
-#define EXCEPTION_STK_ORDER 0
+#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
+#define EXCEPTION_STACK_ORDER 0 
 
 #define start_thread(regs,new_rip,new_rsp) do { \
 	asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));	 \
diff -Nru a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
--- a/include/asm-x86_64/smp.h	Wed Nov 12 21:06:45 2003
+++ b/include/asm-x86_64/smp.h	Wed Nov 12 21:06:45 2003
@@ -74,15 +74,7 @@
 	return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID));
 }
 
-extern int slow_smp_processor_id(void);
-
-extern inline int safe_smp_processor_id(void)
-{ 
-	if (disable_apic)
-		return slow_smp_processor_id(); 
-	else
-		return hard_smp_processor_id();
-} 
+#define safe_smp_processor_id() (cpuid_ebx(1) >> 24) 
 
 #define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
 #endif /* !ASSEMBLY */
diff -Nru a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
--- a/include/asm-x86_64/topology.h	Wed Nov 12 21:06:47 2003
+++ b/include/asm-x86_64/topology.h	Wed Nov 12 21:06:47 2003
@@ -10,13 +10,15 @@
 /* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */
 
 extern int fake_node;
+/* This is actually a cpumask_t, but doesn't matter because we don't have
+   >BITS_PER_LONG CPUs */
 extern unsigned long cpu_online_map;
 
 #define cpu_to_node(cpu)		(fake_node ? 0 : (cpu))
 #define memblk_to_node(memblk) 	(fake_node ? 0 : (memblk))
 #define parent_node(node)		(node)
 #define node_to_first_cpu(node) 	(fake_node ? 0 : (node))
-#define node_to_cpu_mask(node)	(fake_node ? cpu_online_map : (1UL << (node)))
+#define node_to_cpumask(node)	(fake_node ? cpu_online_map : (1UL << (node)))
 #define node_to_memblk(node)		(node)
 
 static inline unsigned long pcibus_to_cpumask(int bus)
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/blkdev.h	Wed Nov 12 21:06:46 2003
@@ -193,6 +193,11 @@
 	__REQ_PM_SUSPEND,	/* suspend request */
 	__REQ_PM_RESUME,	/* resume request */
 	__REQ_PM_SHUTDOWN,	/* shutdown request */
+	__REQ_IDETAPE_PC1,	/* packet command (first stage) */
+	__REQ_IDETAPE_PC2,	/* packet command (second stage) */
+	__REQ_IDETAPE_READ,
+	__REQ_IDETAPE_WRITE,
+	__REQ_IDETAPE_READ_BUFFER,
 	__REQ_NR_BITS,		/* stops here */
 };
 
@@ -218,6 +223,11 @@
 #define REQ_PM_SUSPEND	(1 << __REQ_PM_SUSPEND)
 #define REQ_PM_RESUME	(1 << __REQ_PM_RESUME)
 #define REQ_PM_SHUTDOWN	(1 << __REQ_PM_SHUTDOWN)
+#define REQ_IDETAPE_PC1 (1 << __REQ_IDETAPE_PC1)
+#define REQ_IDETAPE_PC2 (1 << __REQ_IDETAPE_PC2)
+#define REQ_IDETAPE_READ	(1 << __REQ_IDETAPE_READ)
+#define REQ_IDETAPE_WRITE	(1 << __REQ_IDETAPE_WRITE)
+#define REQ_IDETAPE_READ_BUFFER	(1 << __REQ_IDETAPE_READ_BUFFER)
 
 /*
  * State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME
diff -Nru a/include/linux/in.h b/include/linux/in.h
--- a/include/linux/in.h	Wed Nov 12 21:06:48 2003
+++ b/include/linux/in.h	Wed Nov 12 21:06:48 2003
@@ -140,29 +140,29 @@
 
 struct group_req
 {
-	__u32			gr_interface;	/* interface index */
-	struct sockaddr_storage	gr_group;	/* group address */
+	__u32				 gr_interface;	/* interface index */
+	struct __kernel_sockaddr_storage gr_group;	/* group address */
 };
 
 struct group_source_req
 {
-	__u32			gsr_interface;	/* interface index */
-	struct sockaddr_storage	gsr_group;	/* group address */
-	struct sockaddr_storage	gsr_source;	/* source address */
+	__u32				 gsr_interface;	/* interface index */
+	struct __kernel_sockaddr_storage gsr_group;	/* group address */
+	struct __kernel_sockaddr_storage gsr_source;	/* source address */
 };
 
 struct group_filter
 {
-	__u32			gf_interface;	/* interface index */
-	struct sockaddr_storage	gf_group;	/* multicast address */
-	__u32			gf_fmode;	/* filter mode */
-	__u32			gf_numsrc;	/* number of sources */
-	struct sockaddr_storage	gf_slist[1];	/* interface index */
+	__u32				 gf_interface;	/* interface index */
+	struct __kernel_sockaddr_storage gf_group;	/* multicast address */
+	__u32				 gf_fmode;	/* filter mode */
+	__u32				 gf_numsrc;	/* number of sources */
+	struct __kernel_sockaddr_storage gf_slist[1];	/* interface index */
 };
 
 #define GROUP_FILTER_SIZE(numsrc) \
-	(sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \
-	+ (numsrc) * sizeof(struct sockaddr_storage))
+	(sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
+	+ (numsrc) * sizeof(struct __kernel_sockaddr_storage))
 
 struct in_pktinfo
 {
diff -Nru a/include/linux/ip.h b/include/linux/ip.h
--- a/include/linux/ip.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/ip.h	Wed Nov 12 21:06:46 2003
@@ -83,6 +83,7 @@
 #include <linux/types.h>
 #include <net/sock.h>
 #include <linux/igmp.h>
+#include <net/flow.h>
 
 struct ip_options {
   __u32		faddr;				/* Saved first hop address */
@@ -141,6 +142,7 @@
 		struct rtable		*rt;
 		int			length; /* Total length of all frames */
 		u32			addr;
+		struct flowi		fl;
 	} cork;
 };
 
diff -Nru a/include/linux/ipv6.h b/include/linux/ipv6.h
--- a/include/linux/ipv6.h	Wed Nov 12 21:06:47 2003
+++ b/include/linux/ipv6.h	Wed Nov 12 21:06:47 2003
@@ -234,7 +234,6 @@
 	struct {
 		struct ipv6_txoptions *opt;
 		struct rt6_info	*rt;
-		struct flowi *fl;
 		int hop_limit;
 	} cork;
 };
diff -Nru a/include/linux/libata.h b/include/linux/libata.h
--- a/include/linux/libata.h	Wed Nov 12 21:06:45 2003
+++ b/include/linux/libata.h	Wed Nov 12 21:06:45 2003
@@ -207,6 +207,7 @@
 	unsigned int		irq_flags;
 	unsigned long		host_flags;
 	void			*mmio_base;
+	void			*private_data;
 };
 
 struct ata_host_set {
@@ -215,6 +216,7 @@
 	unsigned long		irq;
 	void			*mmio_base;
 	unsigned int		n_ports;
+	void			*private_data;
 	struct ata_port *	ports[0];
 };
 
@@ -264,6 +266,8 @@
 	ata_qc_cb_t		callback;
 
 	struct semaphore	sem;
+
+	void			*private_data;
 };
 
 struct ata_host_stats {
@@ -333,6 +337,8 @@
 	struct semaphore	thr_sem;
 	struct timer_list	thr_timer;
 	unsigned long		thr_timeout;
+
+	void			*private_data;
 };
 
 struct ata_port_operations {
@@ -363,6 +369,11 @@
 	u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
 	void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
 			   u32 val);
+
+	int (*port_start) (struct ata_port *ap);
+	void (*port_stop) (struct ata_port *ap);
+
+	void (*host_stop) (struct ata_host_set *host_set);
 };
 
 struct ata_port_info {
@@ -406,6 +417,8 @@
 extern u8 ata_check_status_mmio(struct ata_port *ap);
 extern void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf);
 extern void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
+extern int ata_port_start (struct ata_port *ap);
+extern void ata_port_stop (struct ata_port *ap);
 extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
 extern void ata_fill_sg(struct ata_queued_cmd *qc);
 extern void ata_bmdma_start_mmio (struct ata_queued_cmd *qc);
diff -Nru a/include/linux/llc.h b/include/linux/llc.h
--- a/include/linux/llc.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/llc.h	Wed Nov 12 21:06:46 2003
@@ -12,20 +12,17 @@
  *
  * See the GNU General Public License for more details.
  */
-#define __LLC_SOCK_SIZE__ 28	/* sizeof(sockaddr_llc), word align. */
+#define __LLC_SOCK_SIZE__ 16	/* sizeof(sockaddr_llc), word align. */
 struct sockaddr_llc {
 	sa_family_t     sllc_family;	/* AF_LLC */
 	sa_family_t	sllc_arphrd;	/* ARPHRD_ETHER */
 	unsigned char   sllc_test;
 	unsigned char   sllc_xid;
 	unsigned char	sllc_ua;	/* UA data, only for SOCK_STREAM. */
-	unsigned char   sllc_dsap;
-	unsigned char   sllc_ssap;
-	unsigned char   sllc_dmac[IFHWADDRLEN];
-	unsigned char   sllc_smac[IFHWADDRLEN];
-	unsigned char   sllc_mmac[IFHWADDRLEN];
+	unsigned char   sllc_sap;
+	unsigned char   sllc_mac[IFHWADDRLEN];
 	unsigned char   __pad[__LLC_SOCK_SIZE__ - sizeof(sa_family_t) * 2 -
-			      sizeof(unsigned char) * 5 - IFHWADDRLEN * 3];
+			      sizeof(unsigned char) * 4 - IFHWADDRLEN];
 };
 
 /* sockopt definitions. */
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	Wed Nov 12 21:06:47 2003
+++ b/include/linux/netdevice.h	Wed Nov 12 21:06:47 2003
@@ -494,10 +494,11 @@
 extern struct net_device		*dev_base;		/* All devices */
 extern rwlock_t				dev_base_lock;		/* Device list lock */
 
-extern void		probe_old_netdevs(void);
 extern int			netdev_boot_setup_add(char *name, struct ifmap *map);
 extern int 			netdev_boot_setup_check(struct net_device *dev);
 extern struct net_device    *dev_getbyhwaddr(unsigned short type, char *hwaddr);
+extern struct net_device *__dev_getfirstbyhwtype(unsigned short type);
+extern struct net_device *dev_getfirstbyhwtype(unsigned short type);
 extern void		dev_add_pack(struct packet_type *pt);
 extern void		dev_remove_pack(struct packet_type *pt);
 extern void		__dev_remove_pack(struct packet_type *pt);
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/pci_ids.h	Wed Nov 12 21:06:46 2003
@@ -440,6 +440,7 @@
 #define PCI_DEVICE_ID_AMD_LANCE		0x2000
 #define PCI_DEVICE_ID_AMD_LANCE_HOME	0x2001
 #define PCI_DEVICE_ID_AMD_SCSI		0x2020
+#define PCI_DEVICE_ID_AMD_SERENADE	0x36c0
 #define PCI_DEVICE_ID_AMD_FE_GATE_7006	0x7006
 #define PCI_DEVICE_ID_AMD_FE_GATE_7007	0x7007
 #define PCI_DEVICE_ID_AMD_FE_GATE_700C	0x700C
@@ -581,12 +582,14 @@
 #define PCI_DEVICE_ID_SI_651		0x0651
 #define PCI_DEVICE_ID_SI_652		0x0652
 #define PCI_DEVICE_ID_SI_655		0x0655
+#define PCI_DEVICE_ID_SI_661		0x0661
 #define PCI_DEVICE_ID_SI_730		0x0730
 #define PCI_DEVICE_ID_SI_733		0x0733
 #define PCI_DEVICE_ID_SI_630_VGA	0x6300
 #define PCI_DEVICE_ID_SI_730_VGA	0x7300
 #define PCI_DEVICE_ID_SI_735		0x0735
 #define PCI_DEVICE_ID_SI_740		0x0740
+#define PCI_DEVICE_ID_SI_741		0x0741
 #define PCI_DEVICE_ID_SI_745		0x0745
 #define PCI_DEVICE_ID_SI_746		0x0746
 #define PCI_DEVICE_ID_SI_748		0x0748
@@ -594,6 +597,7 @@
 #define PCI_DEVICE_ID_SI_751		0x0751
 #define PCI_DEVICE_ID_SI_752		0x0752
 #define PCI_DEVICE_ID_SI_755		0x0755
+#define PCI_DEVICE_ID_SI_760		0x0760
 #define PCI_DEVICE_ID_SI_900		0x0900
 #define PCI_DEVICE_ID_SI_961		0x0961
 #define PCI_DEVICE_ID_SI_962		0x0962
@@ -1023,7 +1027,13 @@
 #define PCI_DEVICE_ID_NVIDIA_VTNT2		0x002C
 #define PCI_DEVICE_ID_NVIDIA_UVTNT2		0x002D
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE	0x0065
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE	0x0085
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA	0x008e
 #define PCI_DEVICE_ID_NVIDIA_ITNT2		0x00A0
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE	0x00d5
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA	0x00e3
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE	0x00e5
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2	0x00ee
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR	0x0100
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR	0x0101
 #define PCI_DEVICE_ID_NVIDIA_QUADRO		0x0103
diff -Nru a/include/linux/preempt.h b/include/linux/preempt.h
--- a/include/linux/preempt.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/preempt.h	Wed Nov 12 21:06:46 2003
@@ -32,8 +32,8 @@
 
 #define preempt_enable_no_resched() \
 do { \
-	dec_preempt_count(); \
 	barrier(); \
+	dec_preempt_count(); \
 } while (0)
 
 #define preempt_check_resched() \
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/sched.h	Wed Nov 12 21:06:46 2003
@@ -483,6 +483,7 @@
 					/* Not implemented yet, only for 486*/
 #define PF_STARTING	0x00000002	/* being created */
 #define PF_EXITING	0x00000004	/* getting shut down */
+#define PF_DEAD		0x00000008	/* Dead */
 #define PF_FORKNOEXEC	0x00000040	/* forked but didn't exec */
 #define PF_SUPERPRIV	0x00000100	/* used super-user privileges */
 #define PF_DUMPCORE	0x00000200	/* dumped core */
@@ -573,7 +574,11 @@
 
 extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state));
 extern int FASTCALL(wake_up_process(struct task_struct * tsk));
-extern int FASTCALL(wake_up_process_kick(struct task_struct * tsk));
+#ifdef CONFIG_SMP
+ extern void FASTCALL(kick_process(struct task_struct * tsk));
+#else
+ static inline void kick_process(struct task_struct *tsk) { }
+#endif
 extern void FASTCALL(wake_up_forked_process(struct task_struct * tsk));
 extern void FASTCALL(sched_exit(task_t * p));
 
diff -Nru a/include/linux/serial.h b/include/linux/serial.h
--- a/include/linux/serial.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/serial.h	Wed Nov 12 21:06:46 2003
@@ -49,7 +49,6 @@
 	unsigned short	iomem_reg_shift;
 	unsigned int	port_high;
 	unsigned long	iomap_base;	/* cookie passed into ioremap */
-	int	reserved[1];
 };
 
 /*
diff -Nru a/include/linux/signal.h b/include/linux/signal.h
--- a/include/linux/signal.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/signal.h	Wed Nov 12 21:06:46 2003
@@ -214,7 +214,7 @@
 struct pt_regs;
 extern int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs, void *cookie);
 #endif
-#define FOLD_NANO_SLEEP_INTO_CLOCK_NANO_SLEEP
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_SIGNAL_H */
diff -Nru a/include/linux/socket.h b/include/linux/socket.h
--- a/include/linux/socket.h	Wed Nov 12 21:06:47 2003
+++ b/include/linux/socket.h	Wed Nov 12 21:06:47 2003
@@ -1,6 +1,21 @@
 #ifndef _LINUX_SOCKET_H
 #define _LINUX_SOCKET_H
 
+/*
+ * Desired design of maximum size and alignment (see RFC2553)
+ */
+#define _K_SS_MAXSIZE	128	/* Implementation specific max size */
+#define _K_SS_ALIGNSIZE	(__alignof__ (struct sockaddr *))
+				/* Implementation specific desired alignment */
+
+struct __kernel_sockaddr_storage {
+	unsigned short	ss_family;		/* address family */
+	/* Following field(s) are implementation specific */
+	char		__data[_K_SS_MAXSIZE - sizeof(unsigned short)];
+				/* space to achieve desired size, */
+				/* _SS_MAXSIZE value minus size of ss_family */
+} __attribute__ ((aligned(_K_SS_ALIGNSIZE)));	/* force desired alignment */
+
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #include <linux/config.h>		/* for CONFIG_COMPAT */
@@ -27,20 +42,7 @@
 	int		l_linger;	/* How long to linger for	*/
 };
 
-/*
- * Desired design of maximum size and alignment (see RFC2553)
- */
-#define _SS_MAXSIZE	128	/* Implementation specific max size */
-#define _SS_ALIGNSIZE	(__alignof__ (struct sockaddr *))
-				/* Implementation specific desired alignment */
-
-struct sockaddr_storage {
-	sa_family_t	ss_family;		/* address family */
-	/* Following field(s) are implementation specific */
-	char		__data[_SS_MAXSIZE - sizeof(sa_family_t)];
-				/* space to achieve desired size, */
-				/* _SS_MAXSIZE value minus size of ss_family */
-} __attribute__ ((aligned(_SS_ALIGNSIZE)));	/* force desired alignment */
+#define sockaddr_storage __kernel_sockaddr_storage
 
 /*
  *	As we do 4.4BSD message passing we use a 4.4BSD message passing
diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/sysctl.h	Wed Nov 12 21:06:46 2003
@@ -217,7 +217,8 @@
 	NET_CORE_NO_CONG=14,
 	NET_CORE_LO_CONG=15,
 	NET_CORE_MOD_CONG=16,
-	NET_CORE_DEV_WEIGHT=17
+	NET_CORE_DEV_WEIGHT=17,
+	NET_CORE_SOMAXCONN=18,
 };
 
 /* /proc/sys/net/ethernet */
diff -Nru a/include/linux/times.h b/include/linux/times.h
--- a/include/linux/times.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/times.h	Wed Nov 12 21:06:46 2003
@@ -4,6 +4,7 @@
 #ifdef __KERNEL__
 #include <asm/div64.h>
 #include <asm/types.h>
+#include <asm/param.h>
 
 #if (HZ % USER_HZ)==0
 # define jiffies_to_clock_t(x) ((x) / (HZ / USER_HZ))
diff -Nru a/include/linux/udp.h b/include/linux/udp.h
--- a/include/linux/udp.h	Wed Nov 12 21:06:46 2003
+++ b/include/linux/udp.h	Wed Nov 12 21:06:46 2003
@@ -44,13 +44,9 @@
 	unsigned int	corkflag;	/* Cork is required */
   	__u16		encap_type;	/* Is this an Encapsulation socket? */
 	/*
-	 * Following members retains the infomation to create a UDP header
+	 * Following member retains the infomation to create a UDP header
 	 * when the socket is uncorked.
 	 */
-	u32		saddr;		/* source address */
-	u32		daddr;		/* destination address */
-	__u16		sport;		/* source port */
-	__u16		dport;		/* destination port */
 	__u16		len;		/* total length of pending frames */
 };
 
diff -Nru a/include/net/if_inet6.h b/include/net/if_inet6.h
--- a/include/net/if_inet6.h	Wed Nov 12 21:06:47 2003
+++ b/include/net/if_inet6.h	Wed Nov 12 21:06:47 2003
@@ -175,6 +175,8 @@
 	u8			entropy[8];
 	struct timer_list	regen_timer;
 	struct inet6_ifaddr	*tempaddr_list;
+	__u8			work_eui64[8];
+	__u8			work_digest[16];
 #endif
 
 	struct neigh_parms	*nd_parms;
diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h	Wed Nov 12 21:06:46 2003
+++ b/include/net/tcp.h	Wed Nov 12 21:06:46 2003
@@ -219,6 +219,7 @@
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct in6_addr		tw_v6_daddr;
 	struct in6_addr		tw_v6_rcv_saddr;
+	int			tw_v6_ipv6only;
 #endif
 };
 
@@ -266,6 +267,38 @@
 	hlist_for_each_entry_safe(tw, node, safe, jail, tw_death_node)
 
 #define tcptw_sk(__sk)	((struct tcp_tw_bucket *)(__sk))
+
+static inline const u32 tcp_v4_rcv_saddr(const struct sock *sk)
+{
+	return likely(sk->sk_state != TCP_TIME_WAIT) ?
+		inet_sk(sk)->rcv_saddr : tcptw_sk(sk)->tw_rcv_saddr;
+}
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static inline const struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
+{
+	return likely(sk->sk_state != TCP_TIME_WAIT) ?
+		&inet6_sk(sk)->rcv_saddr : &tcptw_sk(sk)->tw_v6_rcv_saddr;
+}
+
+static inline const struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
+{
+	return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL;
+}
+
+#define tcptw_sk_ipv6only(__sk)	(tcptw_sk(__sk)->tw_v6_ipv6only)
+
+static inline int tcp_v6_ipv6only(const struct sock *sk)
+{
+	return likely(sk->sk_state != TCP_TIME_WAIT) ?
+		ipv6_only_sock(sk) : tcptw_sk_ipv6only(sk);
+}
+#else
+# define __tcp_v6_rcv_saddr(__sk)	NULL
+# define tcp_v6_rcv_saddr(__sk)		NULL
+# define tcptw_sk_ipv6only(__sk)	0
+# define tcp_v6_ipv6only(__sk)		0
+#endif
 
 extern kmem_cache_t *tcp_timewait_cachep;
 
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Wed Nov 12 21:06:47 2003
+++ b/kernel/exit.c	Wed Nov 12 21:06:47 2003
@@ -594,6 +594,7 @@
  */
 static void exit_notify(struct task_struct *tsk)
 {
+	int state;
 	struct task_struct *t;
 
 	if (signal_pending(tsk) && !tsk->signal->group_exit
@@ -687,7 +688,12 @@
 		do_notify_parent(tsk, SIGCHLD);
 	}
 
-	tsk->state = TASK_ZOMBIE;
+	state = TASK_ZOMBIE;
+	if (tsk->exit_signal == -1 && tsk->ptrace == 0)
+		state = TASK_DEAD;
+	tsk->state = state;
+	tsk->flags |= PF_DEAD;
+
 	/*
 	 * In the preemption case it must be impossible for the task
 	 * to get runnable again, so use "_raw_" unlock to keep
@@ -702,6 +708,11 @@
 	 */
 	_raw_write_unlock(&tasklist_lock);
 	local_irq_enable();
+
+	/* If the process is dead, release it - nobody will wait for it */
+	if (state == TASK_DEAD)
+		release_task(tsk);
+
 }
 
 NORET_TYPE void do_exit(long code)
@@ -750,10 +761,6 @@
 
 	tsk->exit_code = code;
 	exit_notify(tsk);
-
-	if (tsk->exit_signal == -1 && tsk->ptrace == 0)
-		release_task(tsk);
-
 	schedule();
 	BUG();
 	/* Avoid "noreturn function does return".  */
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	Wed Nov 12 21:06:47 2003
+++ b/kernel/module.c	Wed Nov 12 21:06:47 2003
@@ -1658,7 +1658,7 @@
 				 NULL);
 	}
 	if (err < 0)
-		goto cleanup;
+		goto arch_cleanup;
 
 	/* Get rid of temporary copy */
 	vfree(hdr);
@@ -1666,6 +1666,8 @@
 	/* Done! */
 	return mod;
 
+ arch_cleanup:
+	module_arch_cleanup(mod);
  cleanup:
 	module_unload_free(mod);
 	module_free(mod, mod->module_init);
diff -Nru a/kernel/posix-timers.c b/kernel/posix-timers.c
--- a/kernel/posix-timers.c	Wed Nov 12 21:06:46 2003
+++ b/kernel/posix-timers.c	Wed Nov 12 21:06:46 2003
@@ -1104,35 +1104,14 @@
 extern long do_clock_nanosleep(clockid_t which_clock, int flags,
 			       struct timespec *t);
 
-#ifdef FOLD_NANO_SLEEP_INTO_CLOCK_NANO_SLEEP
-
-asmlinkage long
-sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp)
-{
-	struct timespec t;
-	long ret;
-
-	if (copy_from_user(&t, rqtp, sizeof (t)))
-		return -EFAULT;
-
-	if ((unsigned) t.tv_nsec >= NSEC_PER_SEC || t.tv_sec < 0)
-		return -EINVAL;
-
-	ret = do_clock_nanosleep(CLOCK_REALTIME, 0, &t);
-
-	if (ret == -ERESTART_RESTARTBLOCK && rmtp &&
-					copy_to_user(rmtp, &t, sizeof (t)))
-		return -EFAULT;
-	return ret;
-}
-#endif				// ! FOLD_NANO_SLEEP_INTO_CLOCK_NANO_SLEEP
-
 asmlinkage long
 sys_clock_nanosleep(clockid_t which_clock, int flags,
 		    const struct timespec __user *rqtp,
 		    struct timespec __user *rmtp)
 {
 	struct timespec t;
+	struct restart_block *restart_block =
+	    &(current_thread_info()->restart_block);
 	int ret;
 
 	if ((unsigned) which_clock >= MAX_CLOCKS ||
@@ -1146,6 +1125,10 @@
 		return -EINVAL;
 
 	ret = do_clock_nanosleep(which_clock, flags, &t);
+	/*
+	 * Do this here as do_clock_nanosleep does not have the real address
+	 */
+	restart_block->arg1 = (unsigned long)rmtp;
 
 	if ((ret == -ERESTART_RESTARTBLOCK) && rmtp &&
 					copy_to_user(rmtp, &t, sizeof (t)))
@@ -1175,7 +1158,7 @@
 	if (restart_block->fn == clock_nanosleep_restart) {
 		/*
 		 * Interrupted by a non-delivered signal, pick up remaining
-		 * time and continue.
+		 * time and continue.  Remaining time is in arg2 & 3.
 		 */
 		restart_block->fn = do_no_restart_syscall;
 
@@ -1232,9 +1215,20 @@
 		tsave->tv_sec = div_long_long_rem(left, 
 						  NSEC_PER_SEC, 
 						  &tsave->tv_nsec);
+		/*
+		 * Restart works by saving the time remaing in 
+		 * arg2 & 3 (it is 64-bits of jiffies).  The other
+		 * info we need is the clock_id (saved in arg0). 
+		 * The sys_call interface needs the users 
+		 * timespec return address which _it_ saves in arg1.
+		 * Since we have cast the nanosleep call to a clock_nanosleep
+		 * both can be restarted with the same code.
+		 */
 		restart_block->fn = clock_nanosleep_restart;
 		restart_block->arg0 = which_clock;
-		restart_block->arg1 = (unsigned long)tsave;
+		/*
+		 * Caller sets arg1
+		 */
 		restart_block->arg2 = rq_time & 0xffffffffLL;
 		restart_block->arg3 = rq_time >> 32;
 
@@ -1244,7 +1238,7 @@
 	return 0;
 }
 /*
- * This will restart either clock_nanosleep or clock_nanosleep
+ * This will restart clock_nanosleep.
  */
 long
 clock_nanosleep_restart(struct restart_block *restart_block)
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Wed Nov 12 21:06:47 2003
+++ b/kernel/sched.c	Wed Nov 12 21:06:47 2003
@@ -530,6 +530,15 @@
 #endif
 }
 
+/**
+ * task_curr - is this task currently executing on a CPU?
+ * @p: the task in question.
+ */
+inline int task_curr(task_t *p)
+{
+	return cpu_curr(task_cpu(p)) == p;
+}
+
 #ifdef CONFIG_SMP
 
 /*
@@ -568,6 +577,27 @@
 	task_rq_unlock(rq, &flags);
 	preempt_enable();
 }
+
+/***
+ * kick_process - kick a running thread to enter/exit the kernel
+ * @p: the to-be-kicked thread
+ *
+ * Cause a process which is running on another CPU to enter
+ * kernel-mode, without any delay. (to get signals handled.)
+ */
+void kick_process(task_t *p)
+{
+	int cpu;
+
+	preempt_disable();
+	cpu = task_cpu(p);
+	if ((cpu != smp_processor_id()) && task_curr(p))
+		smp_send_reschedule(cpu);
+	preempt_enable();
+}
+
+EXPORT_SYMBOL_GPL(kick_process);
+
 #endif
 
 /***
@@ -575,7 +605,6 @@
  * @p: the to-be-woken-up thread
  * @state: the mask of task states that can be woken
  * @sync: do a synchronous wakeup?
- * @kick: kick the CPU if the task is already running?
  *
  * Put it on the run-queue if it's not already there. The "current"
  * thread is always on the run-queue (except when the actual
@@ -585,7 +614,7 @@
  *
  * returns failure only if the task is already active.
  */
-static int try_to_wake_up(task_t * p, unsigned int state, int sync, int kick)
+static int try_to_wake_up(task_t * p, unsigned int state, int sync)
 {
 	unsigned long flags;
 	int success = 0;
@@ -626,33 +655,22 @@
 			}
 			success = 1;
 		}
-#ifdef CONFIG_SMP
-	       	else
-			if (unlikely(kick) && task_running(rq, p) && (task_cpu(p) != smp_processor_id()))
-				smp_send_reschedule(task_cpu(p));
-#endif
 		p->state = TASK_RUNNING;
 	}
 	task_rq_unlock(rq, &flags);
 
 	return success;
 }
-
 int wake_up_process(task_t * p)
 {
-	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0, 0);
+	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0);
 }
 
 EXPORT_SYMBOL(wake_up_process);
 
-int wake_up_process_kick(task_t * p)
-{
-	return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0, 1);
-}
-
 int wake_up_state(task_t *p, unsigned int state)
 {
-	return try_to_wake_up(p, state, 0, 0);
+	return try_to_wake_up(p, state, 0);
 }
 
 /*
@@ -742,7 +760,7 @@
 {
 	runqueue_t *rq = this_rq();
 	struct mm_struct *mm = rq->prev_mm;
-	int drop_task_ref;
+	unsigned long prev_task_flags;
 
 	rq->prev_mm = NULL;
 
@@ -757,14 +775,11 @@
 	 * be dropped twice.
 	 * 		Manfred Spraul <manfred@colorfullife.com>
 	 */
-	drop_task_ref = 0;
-	if (unlikely(prev->state & (TASK_DEAD | TASK_ZOMBIE)))
-		drop_task_ref = 1;
-
+	prev_task_flags = prev->flags;
 	finish_arch_switch(rq, prev);
 	if (mm)
 		mmdrop(mm);
-	if (drop_task_ref)
+	if (unlikely(prev_task_flags & PF_DEAD))
 		put_task_struct(prev);
 }
 
@@ -1624,7 +1639,7 @@
 int default_wake_function(wait_queue_t *curr, unsigned mode, int sync)
 {
 	task_t *p = curr->task;
-	return try_to_wake_up(p, mode, sync, 0);
+	return try_to_wake_up(p, mode, sync);
 }
 
 EXPORT_SYMBOL(default_wake_function);
@@ -1943,15 +1958,6 @@
 }
 
 EXPORT_SYMBOL(task_nice);
-
-/**
- * task_curr - is this task currently executing on a CPU?
- * @p: the task in question.
- */
-int task_curr(task_t *p)
-{
-	return cpu_curr(task_cpu(p)) == p;
-}
 
 /**
  * idle_cpu - is a given cpu idle currently?
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	Wed Nov 12 21:06:46 2003
+++ b/kernel/signal.c	Wed Nov 12 21:06:46 2003
@@ -539,7 +539,7 @@
 {
 	unsigned int mask;
 
-	set_tsk_thread_flag(t,TIF_SIGPENDING);
+	set_tsk_thread_flag(t, TIF_SIGPENDING);
 
 	/*
 	 * If resume is set, we want to wake it up in the TASK_STOPPED case.
@@ -551,10 +551,8 @@
 	mask = TASK_INTERRUPTIBLE;
 	if (resume)
 		mask |= TASK_STOPPED;
-	if (t->state & mask) {
-		wake_up_process_kick(t);
-		return;
-	}
+	if (!wake_up_state(t, mask))
+		kick_process(t);
 }
 
 /*
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Wed Nov 12 21:06:47 2003
+++ b/kernel/timer.c	Wed Nov 12 21:06:47 2003
@@ -1059,7 +1059,6 @@
 {
 	return current->pid;
 }
-#ifndef FOLD_NANO_SLEEP_INTO_CLOCK_NANO_SLEEP
 
 static long nanosleep_restart(struct restart_block *restart)
 {
@@ -1118,7 +1117,6 @@
 	}
 	return ret;
 }
-#endif // ! FOLD_NANO_SLEEP_INTO_CLOCK_NANO_SLEEP
 
 /*
  * sys_sysinfo - fill in sysinfo struct
diff -Nru a/lib/div64.c b/lib/div64.c
--- a/lib/div64.c	Wed Nov 12 21:06:46 2003
+++ b/lib/div64.c	Wed Nov 12 21:06:46 2003
@@ -25,25 +25,34 @@
 
 uint32_t __div64_32(uint64_t *n, uint32_t base)
 {
-	uint32_t low, low2, high, rem;
+	uint64_t rem = *n;
+	uint64_t b = base;
+	uint64_t res, d = 1;
+	uint32_t high = rem >> 32;
 
-	low   = *n   & 0xffffffff;
-	high  = *n  >> 32;
-	rem   = high % (uint32_t)base;
-	high  = high / (uint32_t)base;
-	low2  = low >> 16;
-	low2 += rem << 16;
-	rem   = low2 % (uint32_t)base;
-	low2  = low2 / (uint32_t)base;
-	low   = low  & 0xffff;
-	low  += rem << 16;
-	rem   = low  % (uint32_t)base;
-	low   = low  / (uint32_t)base;
+	/* Reduce the thing a bit first */
+	res = 0;
+	if (high >= base) {
+		high /= base;
+		res = (uint64_t) high << 32;
+		rem -= (uint64_t) (high*base) << 32;
+	}
 
-	*n = low +
-		((uint64_t)low2 << 16) +
-		((uint64_t)high << 32);
+	while ((int64_t)b > 0 && b < rem) {
+		b = b+b;
+		d = d+d;
+	}
 
+	do {
+		if (rem >= b) {
+			rem -= b;
+			res += d;
+		}
+		b >>= 1;
+		d >>= 1;
+	} while (d);
+
+	*n = res;
 	return rem;
 }
 
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Wed Nov 12 21:06:46 2003
+++ b/mm/filemap.c	Wed Nov 12 21:06:46 2003
@@ -82,6 +82,9 @@
  *    ->private_lock		(try_to_unmap_one)
  *    ->page_lock		(try_to_unmap_one)
  *    ->zone.lru_lock		(follow_page->mark_page_accessed)
+ *
+ *  ->task->proc_lock
+ *    ->dcache_lock		(proc_pid_lookup)
  */
 
 /*
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Wed Nov 12 21:06:46 2003
+++ b/mm/memory.c	Wed Nov 12 21:06:46 2003
@@ -1001,8 +1001,7 @@
 {
 	struct page *old_page, *new_page;
 	unsigned long pfn = pte_pfn(pte);
-	struct pte_chain *pte_chain = NULL;
-	int ret;
+	struct pte_chain *pte_chain;
 
 	if (unlikely(!pfn_valid(pfn))) {
 		/*
@@ -1013,7 +1012,8 @@
 		pte_unmap(page_table);
 		printk(KERN_ERR "do_wp_page: bogus page at address %08lx\n",
 				address);
-		goto oom;
+		spin_unlock(&mm->page_table_lock);
+		return VM_FAULT_OOM;
 	}
 	old_page = pfn_to_page(pfn);
 
@@ -1025,8 +1025,8 @@
 			establish_pte(vma, address, page_table,
 				pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
 			pte_unmap(page_table);
-			ret = VM_FAULT_MINOR;
-			goto out;
+			spin_unlock(&mm->page_table_lock);
+			return VM_FAULT_MINOR;
 		}
 	}
 	pte_unmap(page_table);
@@ -1039,10 +1039,10 @@
 
 	pte_chain = pte_chain_alloc(GFP_KERNEL);
 	if (!pte_chain)
-		goto no_mem;
+		goto no_pte_chain;
 	new_page = alloc_page(GFP_HIGHUSER);
 	if (!new_page)
-		goto no_mem;
+		goto no_new_page;
 	copy_cow_page(old_page,new_page,address);
 
 	/*
@@ -1064,17 +1064,15 @@
 	pte_unmap(page_table);
 	page_cache_release(new_page);
 	page_cache_release(old_page);
-	ret = VM_FAULT_MINOR;
-	goto out;
-
-no_mem:
-	page_cache_release(old_page);
-oom:
-	ret = VM_FAULT_OOM;
-out:
 	spin_unlock(&mm->page_table_lock);
 	pte_chain_free(pte_chain);
-	return ret;
+	return VM_FAULT_MINOR;
+
+no_new_page:
+	pte_chain_free(pte_chain);
+no_pte_chain:
+	page_cache_release(old_page);
+	return VM_FAULT_OOM;
 }
 
 /*
diff -Nru a/net/Kconfig b/net/Kconfig
--- a/net/Kconfig	Wed Nov 12 21:06:45 2003
+++ b/net/Kconfig	Wed Nov 12 21:06:45 2003
@@ -96,15 +96,9 @@
 	  allows you to ping yourself (great fun, that!).
 
 	  For an excellent introduction to Linux networking, please read the
-	  NET-3-HOWTO, available from
+	  Linux Networking HOWTO, available from
 	  <http://www.tldp.org/docs.html#howto>.
 
-	  This option is also necessary if you want to use the full power of
-	  term (term is a program which gives you almost full Internet
-	  connectivity if you have a regular dial up shell account on some
-	  Internet connected Unix computer; for more information, read
-	  <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>).
-
 	  If you say Y here and also to "/proc file system support" and
 	  "Sysctl support" below, you can change various aspects of the
 	  behavior of the TCP/IP code by writing to the (virtual) files in
@@ -120,8 +114,10 @@
 	tristate "The IPv6 protocol (EXPERIMENTAL)"
 	depends on INET && EXPERIMENTAL
 	---help---
-	  This is experimental support for the next version of the Internet
-	  Protocol: IP version 6 (also called IPng "IP next generation").
+	  This is experimental support for the IP version 6 (formerly called
+	  IPng "IP next generation").  You will still be able to do
+	  regular IPv4 networking as well.
+
 	  Features of this new protocol include: expanded address space,
 	  authentication and privacy, and seamless interoperability with the
 	  current version of IP (IP version 4). For general information about
@@ -130,12 +126,10 @@
 	  <http://www.bieringer.de/linux/IPv6/> and the file net/ipv6/README
 	  in the kernel source.
 
-	  If you want to use IPv6, please upgrade to the newest net-tools as
-	  given in <file:Documentation/Changes>. You will still be able to do
-	  regular IPv4 networking as well.
-
-	  To compile this protocol support as a module, choose M here: the
-	  module will be called ipv6.
+	  To compile this protocol support as a module, choose M here: the 
+	  module will be called ipv6.  If you try building this as a module 
+	  and you have said Y to "Kernel module loader support" above, 
+	  be sure to add 'alias net-pf-10 ipv6' to your /etc/modules.conf file.
 
 	  It is safe to say N here for now.
 
diff -Nru a/net/appletalk/ddp.c b/net/appletalk/ddp.c
--- a/net/appletalk/ddp.c	Wed Nov 12 21:06:48 2003
+++ b/net/appletalk/ddp.c	Wed Nov 12 21:06:48 2003
@@ -249,6 +249,7 @@
 	if (!iface)
 		goto out;
 
+	memset(iface, 0, sizeof(*iface));
 	dev_hold(dev);
 	iface->dev = dev;
 	dev->atalk_ptr = iface;
@@ -580,6 +581,7 @@
 		retval = -ENOBUFS;
 		if (!rt)
 			goto out;
+		memset(rt, 0, sizeof(*rt));
 
 		rt->next = atalk_routes;
 		atalk_routes = rt;
@@ -937,9 +939,13 @@
 {
 	/* This ought to be unwrapped neatly. I'll trust gcc for now */
 	while (len--) {
-		sum += *data++;
+		sum += *data;
 		sum <<= 1;
-		sum = ((sum >> 16) + sum) & 0xFFFF;
+		if (sum & 0x10000) {
+			sum++;
+			sum &= 0xffff;
+		}
+		data++;
 	}
 	return sum;
 }
@@ -1048,6 +1054,7 @@
 	at = at_sk(sk) = kmalloc(sizeof(*at), GFP_KERNEL);
 	if (!at)
 		goto outsk;
+	memset(at, 0, sizeof(*at));
 	rc = 0;
 	sock->ops = &atalk_dgram_ops;
 	sock_init_data(sock, sk);
diff -Nru a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
--- a/net/bridge/netfilter/ebt_limit.c	Wed Nov 12 21:06:46 2003
+++ b/net/bridge/netfilter/ebt_limit.c	Wed Nov 12 21:06:46 2003
@@ -20,7 +20,16 @@
 
 static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED;
 
-#define CREDITS_PER_JIFFY 128
+#define MAX_CPJ (0xFFFFFFFF / (HZ*60*60*24))
+
+#define _POW2_BELOW2(x) ((x)|((x)>>1))
+#define _POW2_BELOW4(x) (_POW2_BELOW2(x)|_POW2_BELOW2((x)>>2))
+#define _POW2_BELOW8(x) (_POW2_BELOW4(x)|_POW2_BELOW4((x)>>4))
+#define _POW2_BELOW16(x) (_POW2_BELOW8(x)|_POW2_BELOW8((x)>>8))
+#define _POW2_BELOW32(x) (_POW2_BELOW16(x)|_POW2_BELOW16((x)>>16))
+#define POW2_BELOW32(x) ((_POW2_BELOW32(x)>>1) + 1)
+
+#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
 
 static int ebt_limit_match(const struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
@@ -68,7 +77,7 @@
 	/* Check for overflow. */
 	if (info->burst == 0 ||
 	    user2credits(info->avg * info->burst) < user2credits(info->avg)) {
-		printk("Overflow in ebt_limit: %u/%u\n",
+		printk("Overflow in ebt_limit, try lower: %u/%u\n",
 			info->avg, info->burst);
 		return -EINVAL;
 	}
diff -Nru a/net/compat.c b/net/compat.c
--- a/net/compat.c	Wed Nov 12 21:06:47 2003
+++ b/net/compat.c	Wed Nov 12 21:06:47 2003
@@ -322,7 +322,7 @@
 	u32 origsize, tmp32, num_counters;
 	unsigned int repl_nat_size;
 	int ret;
-	int i, num_ents;
+	int i;
 	compat_uptr_t ucntrs;
 
 	if (get_user(origsize, &urepl->size))
@@ -366,15 +366,10 @@
 	    __put_user(compat_ptr(ucntrs), &repl_nat->counters))
 		goto out;
 
-	num_ents = origsize / sizeof(struct ipt_entry);
-
-	for (i = 0; i < num_ents; i++) {
-		struct ipt_entry ent;
-
-		if (__copy_from_user(&ent, &urepl->entries[i], sizeof(ent)) ||
-		    __copy_to_user(&repl_nat->entries[i], &ent, sizeof(ent)))
-			goto out;
-	}
+	if (__copy_in_user(&repl_nat->entries[0],
+			   &urepl->entries[0],
+			   origsize))
+		goto out;
 
 	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
 		if (__get_user(tmp32, &urepl->hook_entry[i]) ||
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Wed Nov 12 21:06:46 2003
+++ b/net/core/dev.c	Wed Nov 12 21:06:46 2003
@@ -550,6 +550,32 @@
 	return dev;
 }
 
+struct net_device *__dev_getfirstbyhwtype(unsigned short type)
+{
+	struct net_device *dev;
+
+	for (dev = dev_base; dev; dev = dev->next)
+		if (dev->type == type)
+			break;
+	return dev;
+}
+
+EXPORT_SYMBOL(__dev_getfirstbyhwtype);
+
+struct net_device *dev_getfirstbyhwtype(unsigned short type)
+{
+	struct net_device *dev;
+
+	rtnl_lock();
+	dev = __dev_getfirstbyhwtype(type);
+	if (dev)
+		dev_hold(dev);
+	rtnl_unlock();
+	return dev;
+}
+
+EXPORT_SYMBOL(dev_getfirstbyhwtype);
+
 /**
  *	dev_get_by_flags - find any device with given flags
  *	@if_flags: IFF_* values
@@ -3006,8 +3032,6 @@
 #endif
 
 	dev_boot_phase = 0;
-
-	probe_old_netdevs();
 
 	open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
 	open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);
diff -Nru a/net/core/flow.c b/net/core/flow.c
--- a/net/core/flow.c	Wed Nov 12 21:06:45 2003
+++ b/net/core/flow.c	Wed Nov 12 21:06:45 2003
@@ -19,6 +19,7 @@
 #include <linux/bitops.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
+#include <linux/cpumask.h>
 #include <net/flow.h>
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
@@ -65,7 +66,7 @@
 
 struct flow_flush_info {
 	atomic_t cpuleft;
-	unsigned long cpumap;
+	cpumask_t cpumap;
 	struct completion completion;
 };
 static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
@@ -73,7 +74,7 @@
 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
 
 static DECLARE_MUTEX(flow_cache_cpu_sem);
-static unsigned long flow_cache_cpu_map;
+static cpumask_t flow_cache_cpu_map;
 static unsigned int flow_cache_cpu_count;
 
 static void flow_cache_new_hashrnd(unsigned long arg)
@@ -81,7 +82,7 @@
 	int i;
 
 	for (i = 0; i < NR_CPUS; i++)
-		if (test_bit(i, &flow_cache_cpu_map))
+		if (cpu_isset(i, flow_cache_cpu_map))
 			flow_hash_rnd_recalc(i) = 1;
 
 	flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD;
@@ -178,7 +179,7 @@
 	cpu = smp_processor_id();
 
 	fle = NULL;
-	if (!test_bit(cpu, &flow_cache_cpu_map))
+	if (!cpu_isset(cpu, flow_cache_cpu_map))
 		goto nocache;
 
 	if (flow_hash_rnd_recalc(cpu))
@@ -277,7 +278,7 @@
 	struct tasklet_struct *tasklet;
 
 	cpu = smp_processor_id();
-	if (!test_bit(cpu, &info->cpumap))
+	if (!cpu_isset(cpu, info->cpumap))
 		return;
 
 	tasklet = flow_flush_tasklet(cpu);
@@ -301,7 +302,7 @@
 
 	local_bh_disable();
 	smp_call_function(flow_cache_flush_per_cpu, &info, 1, 0);
-	if (test_bit(smp_processor_id(), &info.cpumap))
+	if (cpu_isset(smp_processor_id(), info.cpumap))
 		flow_cache_flush_tasklet((unsigned long)&info);
 	local_bh_enable();
 
@@ -341,7 +342,7 @@
 static int __devinit flow_cache_cpu_online(int cpu)
 {
 	down(&flow_cache_cpu_sem);
-	set_bit(cpu, &flow_cache_cpu_map);
+	cpu_set(cpu, flow_cache_cpu_map);
 	flow_cache_cpu_count++;
 	up(&flow_cache_cpu_sem);
 
diff -Nru a/net/core/link_watch.c b/net/core/link_watch.c
--- a/net/core/link_watch.c	Wed Nov 12 21:06:45 2003
+++ b/net/core/link_watch.c	Wed Nov 12 21:06:45 2003
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/if.h>
+#include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/jiffies.h>
 #include <linux/spinlock.h>
@@ -91,9 +92,11 @@
 	linkwatch_nextevent = jiffies + HZ;
 	clear_bit(LW_RUNNING, &linkwatch_flags);
 
-	rtnl_lock();
+	rtnl_shlock();
+	rtnl_exlock();
 	linkwatch_run_queue();
-	rtnl_unlock();
+	rtnl_exunlock();
+	rtnl_shunlock();
 }
 
 
diff -Nru a/net/core/skbuff.c b/net/core/skbuff.c
--- a/net/core/skbuff.c	Wed Nov 12 21:06:47 2003
+++ b/net/core/skbuff.c	Wed Nov 12 21:06:47 2003
@@ -583,6 +583,8 @@
 	 */
 	struct sk_buff *n = alloc_skb(newheadroom + skb->len + newtailroom,
 				      gfp_mask);
+	int head_copy_len, head_copy_off;
+
 	if (!n)
 		return NULL;
 
@@ -591,8 +593,16 @@
 	/* Set the tail pointer and length */
 	skb_put(n, skb->len);
 
-	/* Copy the data only. */
-	if (skb_copy_bits(skb, 0, n->data, skb->len))
+	head_copy_len = skb_headroom(skb);
+	head_copy_off = 0;
+	if (newheadroom <= head_copy_len)
+		head_copy_len = newheadroom;
+	else
+		head_copy_off = newheadroom - head_copy_len;
+
+	/* Copy the linear header and data. */
+	if (skb_copy_bits(skb, -head_copy_len, n->head + head_copy_off,
+			  skb->len + head_copy_len))
 		BUG();
 
 	copy_skb_header(n, skb);
diff -Nru a/net/core/sock.c b/net/core/sock.c
--- a/net/core/sock.c	Wed Nov 12 21:06:47 2003
+++ b/net/core/sock.c	Wed Nov 12 21:06:47 2003
@@ -154,8 +154,14 @@
 
 static void sock_warn_obsolete_bsdism(const char *name)
 {
-	printk(KERN_WARNING "process `%s' is using obsolete "
-	       "%s SO_BSDCOMPAT\n", current->comm, name);
+	static int warned;
+	static char warncomm[16];
+	if (strcmp(warncomm, current->comm) && warned < 5) { 
+		strcpy(warncomm,  current->comm); 
+		printk(KERN_WARNING "process `%s' is using obsolete "
+		       "%s SO_BSDCOMPAT\n", warncomm, name);
+		warned++;
+	}
 }
 
 /*
diff -Nru a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
--- a/net/core/sysctl_net_core.c	Wed Nov 12 21:06:46 2003
+++ b/net/core/sysctl_net_core.c	Wed Nov 12 21:06:46 2003
@@ -29,6 +29,7 @@
 
 extern int sysctl_core_destroy_delay;
 extern int sysctl_optmem_max;
+extern int sysctl_somaxconn;
 
 #ifdef CONFIG_NET_DIVERT
 extern char sysctl_divert_version[];
@@ -174,6 +175,14 @@
 	},
 #endif /* CONFIG_NET_DIVERT */
 #endif /* CONFIG_NET */
+	{
+		.ctl_name	= NET_CORE_SOMAXCONN,
+		.procname	= "somaxconn",
+		.data		= &sysctl_somaxconn,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 	{ .ctl_name = 0 }
 };
 
diff -Nru a/net/decnet/dn_route.c b/net/decnet/dn_route.c
--- a/net/decnet/dn_route.c	Wed Nov 12 21:06:47 2003
+++ b/net/decnet/dn_route.c	Wed Nov 12 21:06:47 2003
@@ -77,6 +77,7 @@
 #include <linux/string.h>
 #include <linux/netfilter_decnet.h>
 #include <linux/rcupdate.h>
+#include <linux/times.h>
 #include <asm/errno.h>
 #include <net/neighbour.h>
 #include <net/dst.h>
@@ -1508,11 +1509,11 @@
 		RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway);
 	if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
 		goto rtattr_failure;
-	ci.rta_lastuse = jiffies - rt->u.dst.lastuse;
+	ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
 	ci.rta_used     = rt->u.dst.__use;
 	ci.rta_clntref  = atomic_read(&rt->u.dst.__refcnt);
 	if (rt->u.dst.expires)
-		ci.rta_expires = rt->u.dst.expires - jiffies;
+		ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies);
 	else
 		ci.rta_expires = 0;
 	ci.rta_error    = rt->u.dst.error;
diff -Nru a/net/ipv4/ah4.c b/net/ipv4/ah4.c
--- a/net/ipv4/ah4.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/ah4.c	Wed Nov 12 21:06:47 2003
@@ -245,6 +245,9 @@
 	struct ah_data *ahp = NULL;
 	struct xfrm_algo_desc *aalg_desc;
 
+	if (!x->aalg)
+		goto error;
+
 	/* null auth can use a zero length key */
 	if (x->aalg->alg_key_len > 512)
 		goto error;
diff -Nru a/net/ipv4/arp.c b/net/ipv4/arp.c
--- a/net/ipv4/arp.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/arp.c	Wed Nov 12 21:06:47 2003
@@ -1276,6 +1276,10 @@
 
 static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
 {
+	struct arp_iter_state* state = seq->private;
+
+	state->is_pneigh = 0;
+	state->bucket = 0;
 	return *pos ? arp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
 
@@ -1399,7 +1403,6 @@
 
 	seq	     = file->private_data;
 	seq->private = s;
-	memset(s, 0, sizeof(*s));
 out:
 	return rc;
 out_kfree:
diff -Nru a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
--- a/net/ipv4/ip_gre.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/ip_gre.c	Wed Nov 12 21:06:47 2003
@@ -276,6 +276,8 @@
 	  return NULL;
 
 	dev->init = ipgre_tunnel_init;
+	nt = dev->priv;
+	nt->parms = *parms;
 
 	if (register_netdevice(dev) < 0) {
 		kfree(dev);
diff -Nru a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
--- a/net/ipv4/ipcomp.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/ipcomp.c	Wed Nov 12 21:06:47 2003
@@ -344,10 +344,15 @@
 
 static int ipcomp_init_state(struct xfrm_state *x, void *args)
 {
-	int err = -ENOMEM;
+	int err;
 	struct ipcomp_data *ipcd;
 	struct xfrm_algo_desc *calg_desc;
 
+	err = -EINVAL;
+	if (!x->calg)
+		goto out;
+
+	err = -ENOMEM;
 	ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
 	if (!ipcd)
 		goto error;
diff -Nru a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
--- a/net/ipv4/ipmr.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv4/ipmr.c	Wed Nov 12 21:06:46 2003
@@ -1124,18 +1124,16 @@
  *	Processing handlers for ipmr_forward
  */
 
-static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c,
-			   int vifi, int last)
+static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
 {
 	struct iphdr *iph = skb->nh.iph;
 	struct vif_device *vif = &vif_table[vifi];
 	struct net_device *dev;
 	struct rtable *rt;
 	int    encap = 0;
-	struct sk_buff *skb2;
 
 	if (vif->dev == NULL)
-		return;
+		goto out_free;
 
 #ifdef CONFIG_IP_PIMSM
 	if (vif->flags & VIFF_REGISTER) {
@@ -1144,6 +1142,7 @@
 		((struct net_device_stats*)vif->dev->priv)->tx_bytes += skb->len;
 		((struct net_device_stats*)vif->dev->priv)->tx_packets++;
 		ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT);
+		kfree_skb(skb);
 		return;
 	}
 #endif
@@ -1156,7 +1155,7 @@
 						.tos = RT_TOS(iph->tos) } },
 				    .proto = IPPROTO_IPIP };
 		if (ip_route_output_key(&rt, &fl))
-			return;
+			goto out_free;
 		encap = sizeof(struct iphdr);
 	} else {
 		struct flowi fl = { .oif = vif->link,
@@ -1165,7 +1164,7 @@
 						.tos = RT_TOS(iph->tos) } },
 				    .proto = IPPROTO_IPIP };
 		if (ip_route_output_key(&rt, &fl))
-			return;
+			goto out_free;
 	}
 
 	dev = rt->u.dst.dev;
@@ -1178,43 +1177,34 @@
 
 		IP_INC_STATS_BH(IpFragFails);
 		ip_rt_put(rt);
-		return;
+		goto out_free;
 	}
 
-	encap += LL_RESERVED_SPACE(dev);
+	encap += LL_RESERVED_SPACE(dev) + rt->u.dst.header_len;
 
-	if (skb_headroom(skb) < encap || skb_cloned(skb) || !last)
-		skb2 = skb_realloc_headroom(skb, (encap + 15)&~15);
-	else if (atomic_read(&skb->users) != 1)
-		skb2 = skb_clone(skb, GFP_ATOMIC);
-	else {
-		atomic_inc(&skb->users);
-		skb2 = skb;
-	}
-
-	if (skb2 == NULL) {
-		ip_rt_put(rt);
-		return;
+	if (skb_cow(skb, encap)) {
+ 		ip_rt_put(rt);
+		goto out_free;
 	}
 
 	vif->pkt_out++;
 	vif->bytes_out+=skb->len;
 
-	dst_release(skb2->dst);
-	skb2->dst = &rt->u.dst;
-	iph = skb2->nh.iph;
+	dst_release(skb->dst);
+	skb->dst = &rt->u.dst;
+	iph = skb->nh.iph;
 	ip_decrease_ttl(iph);
 
 	/* FIXME: forward and output firewalls used to be called here.
 	 * What do we do with netfilter? -- RR */
 	if (vif->flags & VIFF_TUNNEL) {
-		ip_encap(skb2, vif->local, vif->remote);
+		ip_encap(skb, vif->local, vif->remote);
 		/* FIXME: extra output firewall step used to be here. --RR */
 		((struct ip_tunnel *)vif->dev->priv)->stat.tx_packets++;
-		((struct ip_tunnel *)vif->dev->priv)->stat.tx_bytes+=skb2->len;
+		((struct ip_tunnel *)vif->dev->priv)->stat.tx_bytes+=skb->len;
 	}
 
-	IPCB(skb2)->flags |= IPSKB_FORWARDED;
+	IPCB(skb)->flags |= IPSKB_FORWARDED;
 
 	/*
 	 * RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
@@ -1227,8 +1217,13 @@
 	 * not mrouter) cannot join to more than one interface - it will
 	 * result in receiving multiple packets.
 	 */
-	NF_HOOK(PF_INET, NF_IP_FORWARD, skb2, skb->dev, dev, 
+	NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev, 
 		ipmr_forward_finish);
+	return;
+
+out_free:
+	kfree_skb(skb);
+	return;
 }
 
 static int ipmr_find_vif(struct net_device *dev)
@@ -1299,13 +1294,24 @@
 	 */
 	for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) {
 		if (skb->nh.iph->ttl > cache->mfc_un.res.ttls[ct]) {
-			if (psend != -1)
-				ipmr_queue_xmit(skb, cache, psend, 0);
+			if (psend != -1) {
+				struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+				if (skb2)
+					ipmr_queue_xmit(skb2, cache, psend);
+			}
 			psend=ct;
 		}
 	}
-	if (psend != -1)
-		ipmr_queue_xmit(skb, cache, psend, !local);
+	if (psend != -1) {
+		if (local) {
+			struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
+			if (skb2)
+				ipmr_queue_xmit(skb2, cache, psend);
+		} else {
+			ipmr_queue_xmit(skb, cache, psend);
+			return 0;
+		}
+	}
 
 dont_forward:
 	if (!local)
diff -Nru a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
--- a/net/ipv4/ipvs/ip_vs_conn.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/ipvs/ip_vs_conn.c	Wed Nov 12 21:06:47 2003
@@ -535,8 +535,8 @@
 
 void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
 {
-	cp->timeout = 0;
-	mod_timer(&cp->timer, jiffies);
+	if (del_timer(&cp->timer))
+		mod_timer(&cp->timer, jiffies);
 	__ip_vs_conn_put(cp);
 }
 
diff -Nru a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
--- a/net/ipv4/ipvs/ip_vs_xmit.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/ipvs/ip_vs_xmit.c	Wed Nov 12 21:06:47 2003
@@ -98,7 +98,7 @@
 			.oif = 0,
 			.nl_u = {
 				.ip4_u = {
-					.daddr = dest->addr,
+					.daddr = cp->daddr,
 					.saddr = 0,
 					.tos = rtos, } },
 		};
diff -Nru a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
--- a/net/ipv4/netfilter/Kconfig	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/netfilter/Kconfig	Wed Nov 12 21:06:47 2003
@@ -267,7 +267,7 @@
 
 config IP_NF_MATCH_PHYSDEV
 	tristate "Physdev match support"
-	depends on IP_NF_IPTABLES!=n && BRIDGE_NETFILTER
+	depends on IP_NF_IPTABLES && BRIDGE_NETFILTER
 	help
 	  Physdev packet matching matches against the physical bridge ports
 	  the IP packet arrived on or will leave by.
diff -Nru a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
--- a/net/ipv4/netfilter/arpt_mangle.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/netfilter/arpt_mangle.c	Wed Nov 12 21:06:47 2003
@@ -4,8 +4,8 @@
 #include <net/sock.h>
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
-MODULE_DESCRIPTION("arptables mangle table");
+MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
+MODULE_DESCRIPTION("arptables arp payload mangle target");
 
 static unsigned int
 target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in,
diff -Nru a/net/ipv4/netfilter/ip_fw_compat_masq.c b/net/ipv4/netfilter/ip_fw_compat_masq.c
--- a/net/ipv4/netfilter/ip_fw_compat_masq.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/netfilter/ip_fw_compat_masq.c	Wed Nov 12 21:06:47 2003
@@ -91,9 +91,6 @@
 			WRITE_UNLOCK(&ip_nat_lock);
 			return ret;
 		}
-
-		place_in_hashes(ct, info);
-		info->initialized = 1;
 	} else
 		DEBUGP("Masquerading already done on this conn.\n");
 	WRITE_UNLOCK(&ip_nat_lock);
diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
--- a/net/ipv4/netfilter/ip_nat_core.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv4/netfilter/ip_nat_core.c	Wed Nov 12 21:06:46 2003
@@ -421,7 +421,8 @@
 			*tuple = ((struct ip_conntrack_tuple)
 				  { *manip, orig_tuple->dst });
 			DEBUGP("get_unique_tuple: Found current src map\n");
-			return 1;
+			if (!ip_nat_used_tuple(tuple, conntrack))
+				return 1;
 		}
 	}
 
diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c	Wed Nov 12 21:06:48 2003
+++ b/net/ipv4/netfilter/ip_queue.c	Wed Nov 12 21:06:48 2003
@@ -581,15 +581,14 @@
 	.notifier_call	= ipq_rcv_nl_event,
 };
 
-static int sysctl_maxlen = IPQ_QMAX_DEFAULT;
 static struct ctl_table_header *ipq_sysctl_header;
 
 static ctl_table ipq_table[] = {
 	{
 		.ctl_name	= NET_IPQ_QMAX,
 		.procname	= NET_IPQ_QMAX_NAME,
-		.data		= &sysctl_maxlen,
-		.maxlen		= sizeof(sysctl_maxlen),
+		.data		= &queue_maxlen,
+		.maxlen		= sizeof(queue_maxlen),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
diff -Nru a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
--- a/net/ipv4/netfilter/ipt_REDIRECT.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c	Wed Nov 12 21:06:46 2003
@@ -83,7 +83,7 @@
 
 		/* Device might not have an associated in_device. */
 		indev = (struct in_device *)(*pskb)->dev->ip_ptr;
-		if (indev == NULL)
+		if (indev == NULL || indev->ifa_list == NULL)
 			return NF_DROP;
 
 		/* Grab first address on interface. */
diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
--- a/net/ipv4/route.c	Wed Nov 12 21:06:48 2003
+++ b/net/ipv4/route.c	Wed Nov 12 21:06:48 2003
@@ -89,6 +89,7 @@
 #include <linux/random.h>
 #include <linux/jhash.h>
 #include <linux/rcupdate.h>
+#include <linux/times.h>
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/route.h>
@@ -2305,11 +2306,11 @@
 		RTA_PUT(skb, RTA_GATEWAY, 4, &rt->rt_gateway);
 	if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
 		goto rtattr_failure;
-	ci.rta_lastuse	= jiffies - rt->u.dst.lastuse;
+	ci.rta_lastuse	= jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
 	ci.rta_used	= rt->u.dst.__use;
 	ci.rta_clntref	= atomic_read(&rt->u.dst.__refcnt);
 	if (rt->u.dst.expires)
-		ci.rta_expires = rt->u.dst.expires - jiffies;
+		ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies);
 	else
 		ci.rta_expires = 0;
 	ci.rta_error	= rt->u.dst.error;
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv4/tcp.c	Wed Nov 12 21:06:46 2003
@@ -1540,6 +1540,17 @@
 		if (copied && tp->urg_data && tp->urg_seq == *seq)
 			break;
 
+		/* We need to check signals first, to get correct SIGURG
+		 * handling. FIXME: Need to check this doesn't impact 1003.1g
+		 * and move it down to the bottom of the loop
+		 */
+		if (signal_pending(current)) {
+			if (copied)
+				break;
+			copied = timeo ? sock_intr_errno(timeo) : -EAGAIN;
+			break;
+		}
+
 		/* Next get a buffer. */
 
 		skb = skb_peek(&sk->sk_receive_queue);
@@ -1576,7 +1587,6 @@
 			    sk->sk_state == TCP_CLOSE ||
 			    (sk->sk_shutdown & RCV_SHUTDOWN) ||
 			    !timeo ||
-			    signal_pending(current) ||
 			    (flags & MSG_PEEK))
 				break;
 		} else {
@@ -1604,11 +1614,6 @@
 
 			if (!timeo) {
 				copied = -EAGAIN;
-				break;
-			}
-
-			if (signal_pending(current)) {
-				copied = sock_intr_errno(timeo);
 				break;
 			}
 		}
diff -Nru a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
--- a/net/ipv4/tcp_input.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/tcp_input.c	Wed Nov 12 21:06:47 2003
@@ -1967,7 +1967,10 @@
 				 struct sk_buff *skb, u32 ack, u32 ack_seq)
 {
 	int flag = 0;
-	u32 nwin = ntohs(skb->h.th->window) << tp->snd_wscale;
+	u32 nwin = ntohs(skb->h.th->window);
+
+	if (likely(!skb->h.th->syn))
+		nwin <<= tp->snd_wscale;
 
 	if (tcp_may_update_window(tp, ack, ack_seq, nwin)) {
 		flag |= FLAG_WIN_UPDATE;
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv4/tcp_ipv4.c	Wed Nov 12 21:06:46 2003
@@ -61,6 +61,7 @@
 #include <linux/cache.h>
 #include <linux/jhash.h>
 #include <linux/init.h>
+#include <linux/times.h>
 
 #include <net/icmp.h>
 #include <net/tcp.h>
@@ -178,12 +179,6 @@
 	tcp_sk(sk)->bind_hash = tb;
 }
 
-static inline const u32 tcp_v4_rcv_saddr(const struct sock *sk)
-{
-	return likely(sk->sk_state != TCP_TIME_WAIT) ?
-		inet_sk(sk)->rcv_saddr : tcptw_sk(sk)->tw_rcv_saddr;
-}
-
 static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
 {
 	const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk);
@@ -193,7 +188,7 @@
 
 	sk_for_each_bound(sk2, node, &tb->owners) {
 		if (sk != sk2 &&
-		    !ipv6_only_sock(sk2) &&
+		    !tcp_v6_ipv6only(sk2) &&
 		    (!sk->sk_bound_dev_if ||
 		     !sk2->sk_bound_dev_if ||
 		     sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
@@ -2496,7 +2491,7 @@
 		TCP_SYN_RECV,
 		0, 0, /* could print option size, but that is af dependent. */
 		1,    /* timers active (only the expire timer) */
-		ttd,
+		jiffies_to_clock_t(ttd),
 		req->retrans,
 		uid,
 		0,  /* non standard timer */
@@ -2534,7 +2529,8 @@
 			"%08X %5d %8d %lu %d %p %u %u %u %u %d",
 		i, src, srcp, dest, destp, sp->sk_state,
 		tp->write_seq - tp->snd_una, tp->rcv_nxt - tp->copied_seq,
-		timer_active, timer_expires - jiffies,
+		timer_active,
+		jiffies_to_clock_t(timer_expires - jiffies),
 		tp->retransmits,
 		sock_i_uid(sp),
 		tp->probes_out,
@@ -2562,7 +2558,7 @@
 	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
 		" %02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p",
 		i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
-		3, ttd, 0, 0, 0, 0,
+		3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
 		atomic_read(&tw->tw_refcnt), tw);
 }
 
diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv4/tcp_minisocks.c	Wed Nov 12 21:06:47 2003
@@ -368,6 +368,11 @@
 
 			ipv6_addr_copy(&tw->tw_v6_daddr, &np->daddr);
 			ipv6_addr_copy(&tw->tw_v6_rcv_saddr, &np->rcv_saddr);
+			tw->tw_v6_ipv6only = np->ipv6only;
+		} else {
+			memset(&tw->tw_v6_daddr, 0, sizeof(tw->tw_v6_daddr));
+			memset(&tw->tw_v6_rcv_saddr, 0, sizeof(tw->tw_v6_rcv_saddr));
+			tw->tw_v6_ipv6only = 0;
 		}
 #endif
 		/* Linkage updates. */
diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv4/udp.c	Wed Nov 12 21:06:46 2003
@@ -398,6 +398,8 @@
  */
 static int udp_push_pending_frames(struct sock *sk, struct udp_opt *up)
 {
+	struct inet_opt *inet = inet_sk(sk);
+	struct flowi *fl = &inet->cork.fl;
 	struct sk_buff *skb;
 	struct udphdr *uh;
 	int err = 0;
@@ -410,8 +412,8 @@
 	 * Create a UDP header
 	 */
 	uh = skb->h.uh;
-	uh->source = up->sport;
-	uh->dest = up->dport;
+	uh->source = fl->fl_ip_sport;
+	uh->dest = fl->fl_ip_dport;
 	uh->len = htons(up->len);
 	uh->check = 0;
 
@@ -426,12 +428,12 @@
 		 */
 		if (skb->ip_summed == CHECKSUM_HW) {
 			skb->csum = offsetof(struct udphdr, check);
-			uh->check = ~csum_tcpudp_magic(up->saddr, up->daddr,
+			uh->check = ~csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
 					up->len, IPPROTO_UDP, 0);
 		} else {
 			skb->csum = csum_partial((char *)uh,
 					sizeof(struct udphdr), skb->csum);
-			uh->check = csum_tcpudp_magic(up->saddr, up->daddr,
+			uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
 					up->len, IPPROTO_UDP, skb->csum);
 			if (uh->check == 0)
 				uh->check = -1;
@@ -456,7 +458,7 @@
 		skb_queue_walk(&sk->sk_write_queue, skb) {
 			csum = csum_add(csum, skb->csum);
 		}
-		uh->check = csum_tcpudp_magic(up->saddr, up->daddr,
+		uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
 				up->len, IPPROTO_UDP, csum);
 		if (uh->check == 0)
 			uh->check = -1;
@@ -520,8 +522,13 @@
 	 	 * The socket lock must be held while it's corked.
 		 */
 		lock_sock(sk);
-		if (likely(up->pending))
+		if (likely(up->pending)) {
+			if (unlikely(up->pending != AF_INET)) {
+				release_sock(sk);
+				return -EINVAL;
+			}
  			goto do_append_data;
+		}
 		release_sock(sk);
 	}
 	ulen += sizeof(struct udphdr);
@@ -636,11 +643,11 @@
 	/*
 	 *	Now cork the socket to pend data.
 	 */
-	up->daddr = daddr;
-	up->dport = dport;
-	up->saddr = saddr;
-	up->sport = inet->sport;
-	up->pending = 1;
+	inet->cork.fl.fl4_dst = daddr;
+	inet->cork.fl.fl_ip_dport = dport;
+	inet->cork.fl.fl4_src = saddr;
+	inet->cork.fl.fl_ip_sport = inet->sport;
+	up->pending = AF_INET;
 
 do_append_data:
 	up->len += ulen;
diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv6/addrconf.c	Wed Nov 12 21:06:47 2003
@@ -571,15 +571,6 @@
 
 	ifp->dead = 1;
 
-#ifdef CONFIG_IPV6_PRIVACY
-	spin_lock_bh(&ifp->lock);
-	if (ifp->ifpub) {
-		__in6_ifa_put(ifp->ifpub);
-		ifp->ifpub = NULL;
-	}
-	spin_unlock_bh(&ifp->lock);
-#endif
-
 	write_lock_bh(&addrconf_hash_lock);
 	for (ifap = &inet6_addr_lst[hash]; (ifa=*ifap) != NULL;
 	     ifap = &ifa->lst_next) {
@@ -600,7 +591,7 @@
 			if (ifa == ifp) {
 				*ifap = ifa->tmp_next;
 				if (ifp->ifpub) {
-					__in6_ifa_put(ifp->ifpub);
+					in6_ifa_put(ifp->ifpub);
 					ifp->ifpub = NULL;
 				}
 				__in6_ifa_put(ifp);
@@ -970,36 +961,33 @@
 
 int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
 {
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	int addr_type = ipv6_addr_type(&np->rcv_saddr);
+	const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
+	const struct in6_addr *sk2_rcv_saddr6 = tcp_v6_rcv_saddr(sk2);
+	u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
+	u32 sk2_rcv_saddr = tcp_v4_rcv_saddr(sk2);
+	int sk_ipv6only = ipv6_only_sock(sk);
+	int sk2_ipv6only = tcp_v6_ipv6only(sk2);
+	int addr_type = ipv6_addr_type(sk_rcv_saddr6);
+	int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED;
 
-	if (!inet_sk(sk2)->rcv_saddr && !ipv6_only_sock(sk))
+	if (!sk2_rcv_saddr && !sk_ipv6only)
 		return 1;
 
-	if (sk2->sk_family == AF_INET6 &&
-	    ipv6_addr_any(&inet6_sk(sk2)->rcv_saddr) &&
-	    !(ipv6_only_sock(sk2) && addr_type == IPV6_ADDR_MAPPED))
+	if (addr_type2 == IPV6_ADDR_ANY &&
+	    !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED))
 		return 1;
 
 	if (addr_type == IPV6_ADDR_ANY &&
-	    (!ipv6_only_sock(sk) ||
-	     !(sk2->sk_family == AF_INET6 ?
-	       (ipv6_addr_type(&inet6_sk(sk2)->rcv_saddr) == IPV6_ADDR_MAPPED) :
-	        1)))
+	    !(sk_ipv6only && addr_type2 == IPV6_ADDR_MAPPED))
 		return 1;
 
-	if (sk2->sk_family == AF_INET6 &&
-	    !ipv6_addr_cmp(&np->rcv_saddr,
-			   (sk2->sk_state != TCP_TIME_WAIT ?
-			    &inet6_sk(sk2)->rcv_saddr :
-			    &tcptw_sk(sk)->tw_v6_rcv_saddr)))
+	if (sk2_rcv_saddr6 &&
+	    !ipv6_addr_cmp(sk_rcv_saddr6, sk2_rcv_saddr6))
 		return 1;
 
 	if (addr_type == IPV6_ADDR_MAPPED &&
-	    !ipv6_only_sock(sk2) &&
-	    (!inet_sk(sk2)->rcv_saddr ||
-	     !inet_sk(sk)->rcv_saddr ||
-	     inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr))
+	    !sk2_ipv6only &&
+	    (!sk2_rcv_saddr || !sk_rcv_saddr || sk_rcv_saddr == sk2_rcv_saddr))
 		return 1;
 
 	return 0;
@@ -1109,24 +1097,22 @@
 static int __ipv6_regen_rndid(struct inet6_dev *idev)
 {
 	struct net_device *dev;
-	u8 eui64[8];
-	u8 digest[16];
 	struct scatterlist sg[2];
 
 	sg[0].page = virt_to_page(idev->entropy);
 	sg[0].offset = offset_in_page(idev->entropy);
 	sg[0].length = 8;
-	sg[1].page = virt_to_page(eui64);
-	sg[1].offset = offset_in_page(eui64);
+	sg[1].page = virt_to_page(idev->work_eui64);
+	sg[1].offset = offset_in_page(idev->work_eui64);
 	sg[1].length = 8;
 
 	dev = idev->dev;
 
-	if (ipv6_generate_eui64(eui64, dev)) {
+	if (ipv6_generate_eui64(idev->work_eui64, dev)) {
 		printk(KERN_INFO
 			"__ipv6_regen_rndid(idev=%p): cannot get EUI64 identifier; use random bytes.\n",
 			idev);
-		get_random_bytes(eui64, sizeof(eui64));
+		get_random_bytes(idev->work_eui64, sizeof(idev->work_eui64));
 	}
 regen:
 	spin_lock(&md5_tfm_lock);
@@ -1136,12 +1122,12 @@
 	}
 	crypto_digest_init(md5_tfm);
 	crypto_digest_update(md5_tfm, sg, 2);
-	crypto_digest_final(md5_tfm, digest);
+	crypto_digest_final(md5_tfm, idev->work_digest);
 	spin_unlock(&md5_tfm_lock);
 
-	memcpy(idev->rndid, &digest[0], 8);
+	memcpy(idev->rndid, &idev->work_digest[0], 8);
 	idev->rndid[0] &= ~0x02;
-	memcpy(idev->entropy, &digest[8], 8);
+	memcpy(idev->entropy, &idev->work_digest[8], 8);
 
 	/*
 	 * <draft-ietf-ipngwg-temp-addresses-v2-00.txt>:
@@ -1882,10 +1868,12 @@
 		break;
 	case NETDEV_CHANGENAME:
 #ifdef CONFIG_SYSCTL
-		addrconf_sysctl_unregister(&idev->cnf);
-		neigh_sysctl_unregister(idev->nd_parms);
-		neigh_sysctl_register(dev, idev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6");
-		addrconf_sysctl_register(idev, &idev->cnf);
+		if (idev) {
+			addrconf_sysctl_unregister(&idev->cnf);
+			neigh_sysctl_unregister(idev->nd_parms);
+			neigh_sysctl_register(dev, idev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6");
+			addrconf_sysctl_register(idev, &idev->cnf);
+		}
 #endif
 		break;
 	};
diff -Nru a/net/ipv6/ah6.c b/net/ipv6/ah6.c
--- a/net/ipv6/ah6.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv6/ah6.c	Wed Nov 12 21:06:47 2003
@@ -380,6 +380,9 @@
 	struct ah_data *ahp = NULL;
 	struct xfrm_algo_desc *aalg_desc;
 
+	if (!x->aalg)
+		goto error;
+
 	/* null auth can use a zero length key */
 	if (x->aalg->alg_key_len > 512)
 		goto error;
diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c
--- a/net/ipv6/icmp.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv6/icmp.c	Wed Nov 12 21:06:46 2003
@@ -86,15 +86,6 @@
 	.flags		=	INET6_PROTO_FINAL,
 };
 
-struct icmpv6_msg {
-	struct icmp6hdr		icmph;
-	struct sk_buff		*skb;
-	int			offset;
-	struct in6_addr		*daddr;
-	int			len;
-	__u32			csum;
-};
-
 static __inline__ int icmpv6_xmit_lock(void)
 {
 	local_bh_disable();
@@ -258,11 +249,19 @@
 	return err;
 }
 
+struct icmpv6_msg {
+	struct sk_buff	*skb;
+	int		offset;
+};
+
 static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb)
 {
-	struct sk_buff *org_skb = (struct sk_buff *)from;
+	struct icmpv6_msg *msg = (struct icmpv6_msg *) from;
+	struct sk_buff *org_skb = msg->skb;
 	__u32 csum = 0;
-	csum = skb_copy_and_csum_bits(org_skb, offset, to, len, csum);
+
+	csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
+				      to, len, csum);
 	skb->csum = csum_block_add(skb->csum, csum, odd);
 	return 0;
 }
@@ -281,9 +280,10 @@
 	struct dst_entry *dst;
 	struct icmp6hdr tmp_hdr;
 	struct flowi fl;
+	struct icmpv6_msg msg;
 	int iif = 0;
 	int addr_type = 0;
-	int len, plen;
+	int len;
 	int hlimit = -1;
 	int err = 0;
 
@@ -379,27 +379,29 @@
 			hlimit = dst_metric(dst, RTAX_HOPLIMIT);
 	}
 
-	plen = skb->nh.raw - skb->data;
-	__skb_pull(skb, plen);
-	len = skb->len;
+	msg.skb = skb;
+	msg.offset = skb->nh.raw - skb->data;
+
+	len = skb->len - msg.offset;
 	len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr));
 	if (len < 0) {
 		if (net_ratelimit())
 			printk(KERN_DEBUG "icmp: len problem\n");
-		__skb_push(skb, plen);
 		goto out_dst_release;
 	}
 
 	idev = in6_dev_get(skb->dev);
 
-	err = ip6_append_data(sk, icmpv6_getfrag, skb, len + sizeof(struct icmp6hdr), sizeof(struct icmp6hdr),
-				hlimit, NULL, &fl, (struct rt6_info*)dst, MSG_DONTWAIT);
+	err = ip6_append_data(sk, icmpv6_getfrag, &msg,
+			      len + sizeof(struct icmp6hdr),
+			      sizeof(struct icmp6hdr),
+			      hlimit, NULL, &fl, (struct rt6_info*)dst,
+			      MSG_DONTWAIT);
 	if (err) {
 		ip6_flush_pending_frames(sk);
 		goto out_put;
 	}
 	err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
-	__skb_push(skb, plen);
 
 	if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
 		ICMP6_INC_STATS_OFFSET_BH(idev, Icmp6OutDestUnreachs, type - ICMPV6_DEST_UNREACH);
@@ -423,6 +425,7 @@
 	struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
 	struct icmp6hdr tmp_hdr;
 	struct flowi fl;
+	struct icmpv6_msg msg;
 	struct dst_entry *dst;
 	int err = 0;
 	int hlimit = -1;
@@ -464,7 +467,10 @@
 
 	idev = in6_dev_get(skb->dev);
 
-	err = ip6_append_data(sk, icmpv6_getfrag, skb, skb->len + sizeof(struct icmp6hdr),
+	msg.skb = skb;
+	msg.offset = 0;
+
+	err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
 				sizeof(struct icmp6hdr), hlimit, NULL, &fl,
 				(struct rt6_info*)dst, MSG_DONTWAIT);
 
diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
--- a/net/ipv6/ip6_output.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv6/ip6_output.c	Wed Nov 12 21:06:46 2003
@@ -1239,7 +1239,7 @@
 		}
 		dst_hold(&rt->u.dst);
 		np->cork.rt = rt;
-		np->cork.fl = fl;
+		inet->cork.fl = *fl;
 		np->cork.hop_limit = hlimit;
 		inet->cork.fragsize = mtu = dst_pmtu(&rt->u.dst);
 		inet->cork.length = 0;
@@ -1250,6 +1250,7 @@
 		transhdrlen += exthdrlen;
 	} else {
 		rt = np->cork.rt;
+		fl = &inet->cork.fl;
 		if (inet->cork.flags & IPCORK_OPT)
 			opt = np->cork.opt;
 		transhdrlen = 0;
@@ -1423,7 +1424,7 @@
 	struct ipv6hdr *hdr;
 	struct ipv6_txoptions *opt = np->cork.opt;
 	struct rt6_info *rt = np->cork.rt;
-	struct flowi *fl = np->cork.fl;
+	struct flowi *fl = &inet->cork.fl;
 	unsigned char proto = fl->proto;
 	int err = 0;
 
@@ -1487,9 +1488,7 @@
 		dst_release(&np->cork.rt->u.dst);
 		np->cork.rt = NULL;
 	}
-	if (np->cork.fl) {
-		np->cork.fl = NULL;
-	}
+	memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
 	return err;
 error:
 	goto out;
@@ -1514,7 +1513,5 @@
 		dst_release(&np->cork.rt->u.dst);
 		np->cork.rt = NULL;
 	}
-	if (np->cork.fl) {
-		np->cork.fl = NULL;
-	}
+	memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
 }
diff -Nru a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
--- a/net/ipv6/ip6_tunnel.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv6/ip6_tunnel.c	Wed Nov 12 21:06:46 2003
@@ -681,7 +681,6 @@
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
 		goto tx_err_dst_release;
 	}
-	skb->h.raw = skb->nh.raw;
 
 	/*
 	 * Okay, now see if we can stuff it in the buffer as-is.
@@ -703,6 +702,8 @@
 	dst_release(skb->dst);
 	skb->dst = dst_clone(dst);
 
+	skb->h.raw = skb->nh.raw;
+
 	if (opt)
 		ipv6_push_nfrag_opts(skb, opt, &proto, NULL);
 
@@ -809,9 +810,9 @@
 	fl->fl6_flowlabel = 0;
 
 	if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
-		fl->fl6_flowlabel |= IPV6_TCLASS_MASK & htonl(p->flowinfo);
+		fl->fl6_flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
 	if (!(p->flags&IP6_TNL_F_USE_ORIG_FLOWLABEL))
-		fl->fl6_flowlabel |= IPV6_FLOWLABEL_MASK & htonl(p->flowinfo);
+		fl->fl6_flowlabel |= IPV6_FLOWLABEL_MASK & p->flowinfo;
 
 	ip6_tnl_set_cap(t);
 
diff -Nru a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
--- a/net/ipv6/ipcomp6.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv6/ipcomp6.c	Wed Nov 12 21:06:46 2003
@@ -276,10 +276,15 @@
 
 static int ipcomp6_init_state(struct xfrm_state *x, void *args)
 {
-	int err = -ENOMEM;
+	int err;
 	struct ipcomp_data *ipcd;
 	struct xfrm_algo_desc *calg_desc;
 
+	err = -EINVAL;
+	if (!x->calg)
+		goto out;
+
+	err = -ENOMEM;
 	ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
 	if (!ipcd)
 		goto error;
diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c
--- a/net/ipv6/mcast.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv6/mcast.c	Wed Nov 12 21:06:47 2003
@@ -604,9 +604,9 @@
 			if (ipv6_addr_cmp(&psl->sl_addr[i], src_addr) == 0)
 				break;
 		}
-		if (mc->sfmode == MCAST_INCLUDE && i >= psl->sl_count);
+		if (mc->sfmode == MCAST_INCLUDE && i >= psl->sl_count)
 			rv = 0;
-		if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count);
+		if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count)
 			rv = 0;
 	}
 	read_unlock(&ipv6_sk_mc_lock);
diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
--- a/net/ipv6/netfilter/ip6_queue.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv6/netfilter/ip6_queue.c	Wed Nov 12 21:06:46 2003
@@ -584,15 +584,14 @@
 	.notifier_call	= ipq_rcv_nl_event,
 };
 
-static int sysctl_maxlen = IPQ_QMAX_DEFAULT;
 static struct ctl_table_header *ipq_sysctl_header;
 
 static ctl_table ipq_table[] = {
 	{
 		.ctl_name	= NET_IPQ_QMAX,
 		.procname	= NET_IPQ_QMAX_NAME,
-		.data		= &sysctl_maxlen,
-		.maxlen		= sizeof(sysctl_maxlen),
+		.data		= &queue_maxlen,
+		.maxlen		= sizeof(queue_maxlen),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec
 	},
diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c
--- a/net/ipv6/route.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv6/route.c	Wed Nov 12 21:06:47 2003
@@ -27,6 +27,7 @@
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <linux/times.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
@@ -717,7 +718,7 @@
 		return -ENOMEM;
 
 	rt->u.dst.obsolete = -1;
-	rt->rt6i_expires = rtmsg->rtmsg_info;
+	rt->rt6i_expires = clock_t_to_jiffies(rtmsg->rtmsg_info);
 	if (nlh && (r = NLMSG_DATA(nlh))) {
 		rt->rt6i_protocol = r->rtm_protocol;
 	} else {
@@ -1533,9 +1534,9 @@
 	if (rt->u.dst.dev)
 		RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->rt6i_dev->ifindex);
 	RTA_PUT(skb, RTA_PRIORITY, 4, &rt->rt6i_metric);
-	ci.rta_lastuse = jiffies - rt->u.dst.lastuse;
+	ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
 	if (rt->rt6i_expires)
-		ci.rta_expires = rt->rt6i_expires - jiffies;
+		ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies);
 	else
 		ci.rta_expires = 0;
 	ci.rta_used = rt->u.dst.__use;
diff -Nru a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
--- a/net/ipv6/sysctl_net_ipv6.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv6/sysctl_net_ipv6.c	Wed Nov 12 21:06:46 2003
@@ -31,7 +31,7 @@
 		.ctl_name	= NET_IPV6_ICMP,
 		.procname	= "icmp",
 		.maxlen		= 0,
-		.mode		= 0500,
+		.mode		= 0555,
 		.child		= ipv6_icmp_table
 	},
 	{
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv6/tcp_ipv6.c	Wed Nov 12 21:06:47 2003
@@ -39,6 +39,7 @@
 #include <linux/init.h>
 #include <linux/jhash.h>
 #include <linux/ipsec.h>
+#include <linux/times.h>
 
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
@@ -1941,7 +1942,7 @@
 		   TCP_SYN_RECV,
 		   0,0, /* could print option size, but that is af dependent. */
 		   1,   /* timers active (only the expire timer) */  
-		   ttd, 
+		   jiffies_to_clock_t(ttd), 
 		   req->retrans,
 		   uid,
 		   0,  /* non standard timer */  
@@ -1987,7 +1988,8 @@
 		   dest->s6_addr32[2], dest->s6_addr32[3], destp,
 		   sp->sk_state, 
 		   tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq,
-		   timer_active, timer_expires-jiffies,
+		   timer_active,
+		   jiffies_to_clock_t(timer_expires - jiffies),
 		   tp->retransmits,
 		   sock_i_uid(sp),
 		   tp->probes_out,
@@ -2022,7 +2024,7 @@
 		   dest->s6_addr32[0], dest->s6_addr32[1],
 		   dest->s6_addr32[2], dest->s6_addr32[3], destp,
 		   tw->tw_substate, 0, 0,
-		   3, ttd, 0, 0, 0, 0,
+		   3, jiffies_to_clock_t(ttd), 0, 0, 0, 0,
 		   atomic_read(&tw->tw_refcnt), tw);
 }
 
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	Wed Nov 12 21:06:47 2003
+++ b/net/ipv6/udp.c	Wed Nov 12 21:06:47 2003
@@ -720,8 +720,8 @@
 {
 	struct sk_buff *skb;
 	struct udphdr *uh;
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct flowi *fl = np->cork.fl;
+	struct inet_opt *inet = inet_sk(sk);
+	struct flowi *fl = &inet->cork.fl;
 	int err = 0;
 
 	/* Grab the skbuff where UDP header space exists. */
@@ -783,15 +783,60 @@
 	struct in6_addr *daddr;
 	struct ipv6_txoptions *opt = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
-	struct flowi fl;
+	struct flowi *fl = &inet->cork.fl;
 	struct dst_entry *dst;
 	int addr_len = msg->msg_namelen;
 	int ulen = len;
-	int addr_type;
 	int hlimit = -1;
 	int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
 	int err;
-	
+
+	/* destination address check */
+	if (sin6) {
+		if (addr_len < offsetof(struct sockaddr, sa_data))
+			return -EINVAL;
+
+		switch (sin6->sin6_family) {
+		case AF_INET6:
+			if (addr_len < SIN6_LEN_RFC2133)
+				return -EINVAL;
+			daddr = &sin6->sin6_addr;
+			break;
+		case AF_INET:
+			goto do_udp_sendmsg;
+		case AF_UNSPEC:
+			msg->msg_name = sin6 = NULL;
+			msg->msg_namelen = addr_len = 0;
+			daddr = NULL;
+			break;
+		default:
+			return -EINVAL;
+		}
+	} else if (!up->pending) {
+		if (sk->sk_state != TCP_ESTABLISHED)
+			return -EDESTADDRREQ;
+		daddr = &np->daddr;
+	} else 
+		daddr = NULL;
+
+	if (daddr) {
+		if (ipv6_addr_type(daddr) == IPV6_ADDR_MAPPED) {
+			struct sockaddr_in sin;
+			sin.sin_family = AF_INET;
+			sin.sin_port = sin6 ? sin6->sin6_port : inet->dport;
+			sin.sin_addr.s_addr = daddr->s6_addr[3];
+			msg->msg_name = &sin;
+			msg->msg_namelen = sizeof(sin);
+do_udp_sendmsg:
+			if (__ipv6_only_sock(sk))
+				return -ENETUNREACH;
+			return udp_sendmsg(iocb, sk, msg, len);
+		}
+	}
+
+	if (up->pending == AF_INET)
+		return udp_sendmsg(iocb, sk, msg, len);
+
 	/* Rough check on arithmetic overflow,
 	   better check is made in ip6_build_xmit
 	   */
@@ -805,6 +850,10 @@
 		 */
 		lock_sock(sk);
 		if (likely(up->pending)) {
+			if (unlikely(up->pending != AF_INET6)) {
+				release_sock(sk);
+				return -EINVAL;
+			}
 			dst = NULL;
 			goto do_append_data;
 		}
@@ -812,31 +861,19 @@
 	}
 	ulen += sizeof(struct udphdr);
 
-	memset(&fl, 0, sizeof(fl));
+	memset(fl, 0, sizeof(*fl));
 
 	if (sin6) {
-		if (sin6->sin6_family == AF_INET) {
-			if (__ipv6_only_sock(sk))
-				return -ENETUNREACH;
-			return udp_sendmsg(iocb, sk, msg, len);
-		}
-
-		if (addr_len < SIN6_LEN_RFC2133)
-			return -EINVAL;
-
-		if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
-			return -EINVAL;
-
 		if (sin6->sin6_port == 0)
 			return -EINVAL;
 
-		up->dport = sin6->sin6_port;
+		fl->fl_ip_dport = sin6->sin6_port;
 		daddr = &sin6->sin6_addr;
 
 		if (np->sndflow) {
-			fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
-			if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
-				flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+			fl->fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+			if (fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+				flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
 				if (flowlabel == NULL)
 					return -EINVAL;
 				daddr = &flowlabel->dst;
@@ -854,48 +891,30 @@
 		if (addr_len >= sizeof(struct sockaddr_in6) &&
 		    sin6->sin6_scope_id &&
 		    ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
-			fl.oif = sin6->sin6_scope_id;
+			fl->oif = sin6->sin6_scope_id;
 	} else {
 		if (sk->sk_state != TCP_ESTABLISHED)
 			return -EDESTADDRREQ;
 
-		up->dport = inet->dport;
+		fl->fl_ip_dport = inet->dport;
 		daddr = &np->daddr;
-		fl.fl6_flowlabel = np->flow_label;
-	}
-
-	addr_type = ipv6_addr_type(daddr);
-
-	if (addr_type == IPV6_ADDR_MAPPED) {
-		struct sockaddr_in sin;
-
-		if (__ipv6_only_sock(sk))
-			return -ENETUNREACH;
-
-		sin.sin_family = AF_INET;
-		sin.sin_addr.s_addr = daddr->s6_addr32[3];
-		sin.sin_port = up->dport;
-		msg->msg_name = (struct sockaddr *)(&sin);
-		msg->msg_namelen = sizeof(sin);
-		fl6_sock_release(flowlabel);
-
-		return udp_sendmsg(iocb, sk, msg, len);
+		fl->fl6_flowlabel = np->flow_label;
 	}
 
-	if (!fl.oif)
-		fl.oif = sk->sk_bound_dev_if;
+	if (!fl->oif)
+		fl->oif = sk->sk_bound_dev_if;
 
 	if (msg->msg_controllen) {
 		opt = &opt_space;
 		memset(opt, 0, sizeof(struct ipv6_txoptions));
 
-		err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+		err = datagram_send_ctl(msg, fl, opt, &hlimit);
 		if (err < 0) {
 			fl6_sock_release(flowlabel);
 			return err;
 		}
-		if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
-			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+		if ((fl->fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
+			flowlabel = fl6_sock_lookup(sk, fl->fl6_flowlabel);
 			if (flowlabel == NULL)
 				return -EINVAL;
 		}
@@ -907,28 +926,27 @@
 	if (flowlabel)
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 
-	fl.proto = IPPROTO_UDP;
-	ipv6_addr_copy(&fl.fl6_dst, daddr);
-	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
-		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
-	fl.fl_ip_dport = up->dport;
-	fl.fl_ip_sport = inet->sport;
+	fl->proto = IPPROTO_UDP;
+	ipv6_addr_copy(&fl->fl6_dst, daddr);
+	if (ipv6_addr_any(&fl->fl6_src) && !ipv6_addr_any(&np->saddr))
+		ipv6_addr_copy(&fl->fl6_src, &np->saddr);
+	fl->fl_ip_sport = inet->sport;
 	
 	/* merge ip6_build_xmit from ip6_output */
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
 	}
 
-	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
-		fl.oif = np->mcast_oif;
+	if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst))
+		fl->oif = np->mcast_oif;
 
-	err = ip6_dst_lookup(sk, &dst, &fl);
+	err = ip6_dst_lookup(sk, &dst, fl);
 	if (err)
 		goto out;
 
 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(&fl.fl6_dst))
+		if (ipv6_addr_is_multicast(&fl->fl6_dst))
 			hlimit = np->mcast_hops;
 		else
 			hlimit = np->hop_limit;
@@ -951,12 +969,12 @@
 		goto out;
 	}
 
-	up->pending = 1;
+	up->pending = AF_INET6;
 
 do_append_data:
 	up->len += ulen;
 	err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr),
-			      hlimit, opt, &fl, (struct rt6_info*)dst,
+			      hlimit, opt, fl, (struct rt6_info*)dst,
 			      corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
 	if (err)
 		udp_v6_flush_pending_frames(sk);
@@ -965,7 +983,7 @@
 
 	if (dst)
 		ip6_dst_store(sk, dst,
-			      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+			      !ipv6_addr_cmp(&fl->fl6_dst, &np->daddr) ?
 			      &np->daddr : NULL);
 	if (err > 0)
 		err = np->recverr ? net_xmit_errno(err) : 0;
diff -Nru a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
--- a/net/ipv6/xfrm6_policy.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipv6/xfrm6_policy.c	Wed Nov 12 21:06:46 2003
@@ -169,7 +169,7 @@
 		dst_prev->output	= dst_prev->xfrm->type->output;
 		/* Sheit... I remember I did this right. Apparently,
 		 * it was magically lost, so this code needs audit */
-		x->u.rt6.rt6i_flags    = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
+		x->u.rt6.rt6i_flags    = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL|RTF_NDISC);
 		x->u.rt6.rt6i_metric   = rt0->rt6i_metric;
 		x->u.rt6.rt6i_node     = rt0->rt6i_node;
 		x->u.rt6.rt6i_gateway  = rt0->rt6i_gateway;
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c	Wed Nov 12 21:06:46 2003
+++ b/net/ipx/af_ipx.c	Wed Nov 12 21:06:46 2003
@@ -326,7 +326,6 @@
 	if (intrfc->if_dev)
 		dev_put(intrfc->if_dev);
 	kfree(intrfc);
-	module_put(THIS_MODULE);
 }
 
 void ipxitf_down(struct ipx_interface *intrfc)
@@ -358,6 +357,17 @@
 	return NOTIFY_DONE;
 }
 
+
+static __exit void ipxitf_cleanup(void)
+{
+	struct ipx_interface *i, *tmp;
+
+	spin_lock_bh(&ipx_interfaces_lock);
+	list_for_each_entry_safe(i, tmp, &ipx_interfaces, node) 
+		__ipxitf_put(i);
+	spin_unlock_bh(&ipx_interfaces_lock);
+}
+
 static void ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb)
 {
 	if (sock_queue_rcv_skb(sock, skb) < 0)
@@ -888,7 +898,6 @@
 		INIT_HLIST_HEAD(&intrfc->if_sklist);
 		atomic_set(&intrfc->refcnt, 1);
 		spin_lock_init(&intrfc->if_sklist_lock);
-		__module_get(THIS_MODULE);
 	}
 
 	return intrfc;
@@ -1979,20 +1988,12 @@
 
 static void __exit ipx_proto_finito(void)
 {
-	/*
-	 * No need to worry about having anything on the ipx_interfaces list,
-	 * when a interface is created we increment the module usage count, so
-	 * the module will only be unloaded when there are no more interfaces
-	 */
-	if (unlikely(!list_empty(&ipx_interfaces)))
-		BUG();
-	if (unlikely(!list_empty(&ipx_routes)))
-		BUG();
-
 	ipx_proc_exit();
 	ipx_unregister_sysctl();
 
 	unregister_netdevice_notifier(&ipx_dev_notifier);
+
+	ipxitf_cleanup();
 
 	unregister_snap_client(pSNAP_datalink);
 	pSNAP_datalink = NULL;
diff -Nru a/net/irda/af_irda.c b/net/irda/af_irda.c
--- a/net/irda/af_irda.c	Wed Nov 12 21:06:46 2003
+++ b/net/irda/af_irda.c	Wed Nov 12 21:06:46 2003
@@ -188,8 +188,10 @@
 	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	sk = self->sk;
-	if (sk == NULL)
+	if (sk == NULL) {
+		dev_kfree_skb(skb);
 		return;
+	}
 
 	dev_kfree_skb(skb);
 	// Should be ??? skb_queue_tail(&sk->sk_receive_queue, skb);
@@ -248,8 +250,10 @@
 	IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
 
 	sk = self->sk;
-	if (sk == NULL)
+	if (sk == NULL) {
+		dev_kfree_skb(skb);
 		return;
+	}
 
 	/* How much header space do we need to reserve */
 	self->max_header_size = max_header_size;
diff -Nru a/net/irda/discovery.c b/net/irda/discovery.c
--- a/net/irda/discovery.c	Wed Nov 12 21:06:46 2003
+++ b/net/irda/discovery.c	Wed Nov 12 21:06:46 2003
@@ -351,10 +351,6 @@
 }
 
 #ifdef CONFIG_PROC_FS
-struct discovery_iter_state {
-	unsigned long flags;
-};
-
 static inline discovery_t *discovery_seq_idx(loff_t pos)
 
 {
@@ -372,9 +368,7 @@
 
 static void *discovery_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	struct discovery_iter_state *iter = seq->private;
-
-	spin_lock_irqsave(&irlmp->cachelog->hb_spinlock, iter->flags);
+	spin_lock_irq(&irlmp->cachelog->hb_spinlock);
         return *pos ? discovery_seq_idx(*pos - 1) : SEQ_START_TOKEN;
 }
 
@@ -388,8 +382,7 @@
 
 static void discovery_seq_stop(struct seq_file *seq, void *v)
 {
-	struct discovery_iter_state *iter = seq->private;
-	spin_unlock_irqrestore(&irlmp->cachelog->hb_spinlock, iter->flags);
+	spin_unlock_irq(&irlmp->cachelog->hb_spinlock);
 }
 
 static int discovery_seq_show(struct seq_file *seq, void *v)
@@ -446,28 +439,9 @@
 
 static int discovery_seq_open(struct inode *inode, struct file *file)
 {
-	struct seq_file *seq;
-	int rc = -ENOMEM;
-	struct discovery_iter_state *s;
-       
 	ASSERT(irlmp != NULL, return -EINVAL;);
 
-	s = kmalloc(sizeof(*s), GFP_KERNEL);
-	if (!s)
-		goto out;
-
-	rc = seq_open(file, &discovery_seq_ops);
-	if (rc)
-		goto out_kfree;
-
-	seq	     = file->private_data;
-	seq->private = s;
-	memset(s, 0, sizeof(*s));
-out:
-	return rc;
-out_kfree:
-	kfree(s);
-	goto out;
+	return seq_open(file, &discovery_seq_ops);
 }
 
 struct file_operations discovery_seq_fops = {
diff -Nru a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
--- a/net/irda/ircomm/ircomm_core.c	Wed Nov 12 21:06:45 2003
+++ b/net/irda/ircomm/ircomm_core.c	Wed Nov 12 21:06:45 2003
@@ -508,17 +508,12 @@
 EXPORT_SYMBOL(ircomm_flow_request);
 
 #ifdef CONFIG_PROC_FS
-struct ircomm_iter_state {
-	unsigned long flags;
-};
-
 static void *ircomm_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	struct ircomm_iter_state *iter = seq->private;
 	struct ircomm_cb *self;
 	loff_t off = 0;
 
-	spin_lock_irqsave(&ircomm->hb_spinlock, iter->flags);
+	spin_lock_irq(&ircomm->hb_spinlock);
 
 	for (self = (struct ircomm_cb *) hashbin_get_first(ircomm);
 	     self != NULL;
@@ -539,8 +534,7 @@
 
 static void ircomm_seq_stop(struct seq_file *seq, void *v)
 {
-	struct ircomm_iter_state *iter = seq->private;
-	spin_unlock_irqrestore(&ircomm->hb_spinlock, iter->flags);
+	spin_unlock_irq(&ircomm->hb_spinlock);
 }
 
 static int ircomm_seq_show(struct seq_file *seq, void *v)
@@ -581,25 +575,7 @@
 
 static int ircomm_seq_open(struct inode *inode, struct file *file)
 {
-	struct seq_file *seq;
-	int rc = -ENOMEM;
-	struct ircomm_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL);
-       
-	if (!s)
-		goto out;
-
-	rc = seq_open(file, &ircomm_seq_ops);
-	if (rc)
-		goto out_kfree;
-
-	seq	     = file->private_data;
-	seq->private = s;
-	memset(s, 0, sizeof(*s));
-out:
-	return rc;
-out_kfree:
-	kfree(s);
-	goto out;
+	return seq_open(file, &ircomm_seq_ops);
 }
 #endif /* CONFIG_PROC_FS */
 
diff -Nru a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
--- a/net/irda/ircomm/ircomm_tty.c	Wed Nov 12 21:06:46 2003
+++ b/net/irda/ircomm/ircomm_tty.c	Wed Nov 12 21:06:46 2003
@@ -663,9 +663,10 @@
  *    accepted for writing. This routine is mandatory.
  */
 static int ircomm_tty_write(struct tty_struct *tty, int from_user,
-			    const unsigned char *buf, int count)
+			    const unsigned char *ubuf, int count)
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
+	unsigned char *kbuf;		/* Buffer in kernel space */
 	unsigned long flags;
 	struct sk_buff *skb;
 	int tailroom = 0;
@@ -702,6 +703,24 @@
 #endif
 	}
 
+	if (count < 1)
+		return 0;
+
+	/* Additional copy to avoid copy_from_user() under spinlock.
+	 * We tradeoff this extra copy to allow to pack more the
+	 * IrCOMM frames. This is advantageous because the IrDA link
+	 * is the bottleneck. */
+	if (from_user) {
+		kbuf = kmalloc(count, GFP_KERNEL);
+		if (kbuf == NULL)
+			return -ENOMEM;
+		if (copy_from_user(kbuf, ubuf, count))
+			return -EFAULT;
+	} else
+		/* The buffer is already in kernel space */
+		kbuf = (unsigned char *) ubuf;
+
+	/* Protect our manipulation of self->tx_skb and related */
 	spin_lock_irqsave(&self->spinlock, flags);
 
 	/* Fetch current transmit buffer */
@@ -761,19 +780,19 @@
 			 * change later on - Jean II */
 			self->tx_data_size = self->max_data_size;
 		}
-		
+
 		/* Copy data */
-		if (from_user)
-			copy_from_user(skb_put(skb,size), buf+len, size);
-		else
-			memcpy(skb_put(skb,size), buf+len, size);
-		
+		memcpy(skb_put(skb,size), kbuf + len, size);
+
 		count -= size;
 		len += size;
 	}
 
 	spin_unlock_irqrestore(&self->spinlock, flags);
 
+	if (from_user)
+		kfree(kbuf);
+
 	/*     
 	 * Schedule a new thread which will transmit the frame as soon
 	 * as possible, but at a safe point in time. We do this so the
@@ -837,6 +856,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	unsigned long orig_jiffies, poll_time;
+	unsigned long flags;
 	
 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
 
@@ -848,14 +868,18 @@
 	/* Set poll time to 200 ms */
 	poll_time = IRDA_MIN(timeout, MSECS_TO_JIFFIES(200));
 
+	spin_lock_irqsave(&self->spinlock, flags);
 	while (self->tx_skb && self->tx_skb->len) {
+		spin_unlock_irqrestore(&self->spinlock, flags);
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(poll_time);
+		spin_lock_irqsave(&self->spinlock, flags);
 		if (signal_pending(current))
 			break;
 		if (timeout && time_after(jiffies, orig_jiffies + timeout))
 			break;
 	}
+	spin_unlock_irqrestore(&self->spinlock, flags);
 	current->state = TASK_RUNNING;
 }
 
diff -Nru a/net/irda/iriap.c b/net/irda/iriap.c
--- a/net/irda/iriap.c	Wed Nov 12 21:06:46 2003
+++ b/net/irda/iriap.c	Wed Nov 12 21:06:46 2003
@@ -978,10 +978,6 @@
 	"IAS_STRING"
 };
 
-struct irias_iter_state {
-	unsigned long flags;
-};
-
 static inline struct ias_object *irias_seq_idx(loff_t pos) 
 {
 	struct ias_object *obj;
@@ -997,9 +993,7 @@
 
 static void *irias_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	struct irias_iter_state *iter = seq->private;
-
-	spin_lock_irqsave(&irias_objects->hb_spinlock, iter->flags);
+	spin_lock_irq(&irias_objects->hb_spinlock);
 
 	return *pos ? irias_seq_idx(*pos - 1) : SEQ_START_TOKEN;
 }
@@ -1015,9 +1009,7 @@
 
 static void irias_seq_stop(struct seq_file *seq, void *v)
 {
-	struct irias_iter_state *iter = seq->private;
-
-	spin_unlock_irqrestore(&irias_objects->hb_spinlock, iter->flags);
+	spin_unlock_irq(&irias_objects->hb_spinlock);
 }
 
 static int irias_seq_show(struct seq_file *seq, void *v)
@@ -1088,26 +1080,9 @@
 
 static int irias_seq_open(struct inode *inode, struct file *file)
 {
-	struct seq_file *seq;
-	int rc = -ENOMEM;
-	struct irias_iter_state *s;
-
 	ASSERT( irias_objects != NULL, return -EINVAL;);
-	s = kmalloc(sizeof(*s), GFP_KERNEL);
-	if (!s)
-		goto out;
-
-	rc = seq_open(file, &irias_seq_ops);
-	if (rc)
-		goto out_kfree;
-	seq	     = file->private_data;
-	seq->private = s;
-	memset(s, 0, sizeof(*s));
-out:
-	return rc;
-out_kfree:
-	kfree(s);
-	goto out;
+
+	return seq_open(file, &irias_seq_ops);
 }
 
 struct file_operations irias_seq_fops = {
diff -Nru a/net/irda/irlap.c b/net/irda/irlap.c
--- a/net/irda/irlap.c	Wed Nov 12 21:06:47 2003
+++ b/net/irda/irlap.c	Wed Nov 12 21:06:47 2003
@@ -1094,7 +1094,6 @@
 #ifdef CONFIG_PROC_FS
 struct irlap_iter_state {
 	int id;
-	unsigned long flags;
 };
 
 static void *irlap_seq_start(struct seq_file *seq, loff_t *pos)
@@ -1103,7 +1102,7 @@
 	struct irlap_cb *self;
 
 	/* Protect our access to the tsap list */
-	spin_lock_irqsave(&irlap->hb_spinlock, iter->flags);
+	spin_lock_irq(&irlap->hb_spinlock);
 	iter->id = 0;
 
 	for (self = (struct irlap_cb *) hashbin_get_first(irlap); 
@@ -1127,8 +1126,7 @@
 
 static void irlap_seq_stop(struct seq_file *seq, void *v)
 {
-	struct irlap_iter_state *iter = seq->private;
-	spin_unlock_irqrestore(&irlap->hb_spinlock, iter->flags);
+	spin_unlock_irq(&irlap->hb_spinlock);
 }
 
 static int irlap_seq_show(struct seq_file *seq, void *v)
diff -Nru a/net/irda/irlmp.c b/net/irda/irlmp.c
--- a/net/irda/irlmp.c	Wed Nov 12 21:06:47 2003
+++ b/net/irda/irlmp.c	Wed Nov 12 21:06:47 2003
@@ -146,6 +146,7 @@
 	ASSERT(notify != NULL, return NULL;);
 	ASSERT(irlmp != NULL, return NULL;);
 	ASSERT(irlmp->magic == LMP_MAGIC, return NULL;);
+	ASSERT(notify->instance != NULL, return NULL;);
 
 	/*  Does the client care which Source LSAP selector it gets?  */
 	if (slsap_sel == LSAP_ANY) {
@@ -178,7 +179,6 @@
 
 	init_timer(&self->watchdog_timer);
 
-	ASSERT(notify->instance != NULL, return NULL;);
 	self->notify = *notify;
 
 	self->lsap_state = LSAP_DISCONNECTED;
@@ -1780,7 +1780,6 @@
 #ifdef CONFIG_PROC_FS
 
 struct irlmp_iter_state {
-	unsigned long flags;
 	hashbin_t *hashbin;
 };
 
@@ -1791,7 +1790,7 @@
 {
 	void *element;
 
-	spin_lock_irqsave(&iter->hashbin->hb_spinlock, iter->flags);
+	spin_lock_irq(&iter->hashbin->hb_spinlock);
 	for (element = hashbin_get_first(iter->hashbin);
 	     element != NULL; 
 	     element = hashbin_get_next(iter->hashbin)) {
@@ -1800,7 +1799,7 @@
 			return element;
 		}
 	}
-	spin_unlock_irqrestore(&iter->hashbin->hb_spinlock, iter->flags);
+	spin_unlock_irq(&iter->hashbin->hb_spinlock);
 	iter->hashbin = NULL;
 	return NULL;
 }
@@ -1812,6 +1811,7 @@
 	void *v;
 	loff_t off = *pos;
 
+	iter->hashbin = NULL;
 	if (off-- == 0)
 		return LSAP_START_TOKEN;
 
@@ -1847,8 +1847,7 @@
 	v = hashbin_get_next(iter->hashbin);
 
 	if (v == NULL) {			/* no more in this hash bin */
-		spin_unlock_irqrestore(&iter->hashbin->hb_spinlock, 
-				       iter->flags);
+		spin_unlock_irq(&iter->hashbin->hb_spinlock);
 
 		if (iter->hashbin == irlmp->unconnected_lsaps) 
 			v =  LINK_START_TOKEN;
@@ -1861,10 +1860,9 @@
 static void irlmp_seq_stop(struct seq_file *seq, void *v)
 {
 	struct irlmp_iter_state *iter = seq->private;
-	
+
 	if (iter->hashbin)
-		spin_unlock_irqrestore(&iter->hashbin->hb_spinlock, iter->flags);
-		
+		spin_unlock_irq(&iter->hashbin->hb_spinlock);
 }
 
 static int irlmp_seq_show(struct seq_file *seq, void *v)
@@ -1950,7 +1948,6 @@
 
 	seq	     = file->private_data;
 	seq->private = s;
-	memset(s, 0, sizeof(*s));
 out:
 	return rc;
 out_kfree:
diff -Nru a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
--- a/net/irda/irnet/irnet_ppp.c	Wed Nov 12 21:06:47 2003
+++ b/net/irda/irnet/irnet_ppp.c	Wed Nov 12 21:06:47 2003
@@ -512,8 +512,8 @@
   if(ap->ppp_open)
     {
       DERROR(FS_ERROR, "Channel still registered - deregistering !\n");
-      ppp_unregister_channel(&ap->chan);
       ap->ppp_open = 0;
+      ppp_unregister_channel(&ap->chan);
     }
 
   kfree(ap);
@@ -651,10 +651,12 @@
 	  DEBUG(FS_INFO, "Exiting PPP discipline.\n");
 	  /* Disconnect from the generic PPP layer */
 	  if(ap->ppp_open)
-	    ppp_unregister_channel(&ap->chan);
+	    {
+	      ap->ppp_open = 0;
+	      ppp_unregister_channel(&ap->chan);
+	    }
 	  else
 	    DERROR(FS_ERROR, "Channel not registered !\n");
-	  ap->ppp_open = 0;
 	  err = 0;
 	}
       break;
diff -Nru a/net/irda/irttp.c b/net/irda/irttp.c
--- a/net/irda/irttp.c	Wed Nov 12 21:06:47 2003
+++ b/net/irda/irttp.c	Wed Nov 12 21:06:47 2003
@@ -968,6 +968,10 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == TTP_TSAP_MAGIC, return;);
 
+	/* Check if client has already closed the TSAP and gone away */
+	if (self->close_pend)
+		return;
+
 	/*
 	 *  Inform service user if he has requested it
 	 */
@@ -1603,7 +1607,7 @@
 {
 	int err;
 
-	/* Check if client has already tried to close the TSAP */
+	/* Check if client has already closed the TSAP and gone away */
 	if (self->close_pend) {
 		dev_kfree_skb(skb);
 		return;
@@ -1770,7 +1774,6 @@
 #ifdef CONFIG_PROC_FS
 struct irttp_iter_state {
 	int id;
-	unsigned long flags;
 };
 
 static void *irttp_seq_start(struct seq_file *seq, loff_t *pos)
@@ -1779,7 +1782,7 @@
 	struct tsap_cb *self;
 
 	/* Protect our access to the tsap list */
-	spin_lock_irqsave(&irttp->tsaps->hb_spinlock, iter->flags);
+	spin_lock_irq(&irttp->tsaps->hb_spinlock);
 	iter->id = 0;
 
 	for (self = (struct tsap_cb *) hashbin_get_first(irttp->tsaps); 
@@ -1804,8 +1807,7 @@
 
 static void irttp_seq_stop(struct seq_file *seq, void *v)
 {
-	struct irttp_iter_state *iter = seq->private;
-	spin_unlock_irqrestore(&irttp->tsaps->hb_spinlock, iter->flags);
+	spin_unlock_irq(&irttp->tsaps->hb_spinlock);
 }
 
 static int irttp_seq_show(struct seq_file *seq, void *v)
diff -Nru a/net/llc/af_llc.c b/net/llc/af_llc.c
--- a/net/llc/af_llc.c	Wed Nov 12 21:06:45 2003
+++ b/net/llc/af_llc.c	Wed Nov 12 21:06:45 2003
@@ -187,6 +187,8 @@
 		llc_release_sockets(llc->sap);
 		llc_sap_close(llc->sap);
 	}
+	if (llc->dev)
+		dev_put(llc->dev);
 	sock_put(sk);
 	llc_sk_free(sk);
 out:
@@ -244,64 +246,23 @@
 	struct sock *sk = sock->sk;
 	struct llc_opt *llc = llc_sk(sk);
 	struct llc_sap *sap;
-	struct net_device *dev = NULL;
 	int rc = -EINVAL;
 
 	if (!sk->sk_zapped)
 		goto out;
-	/* bind to a specific mac, optional. */
-	if (!llc_mac_null(addr->sllc_smac)) {
-		rtnl_lock();
-		dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac);
-		rtnl_unlock();
-		rc = -ENETUNREACH;
-		if (!dev)
-			goto out;
-		llc->dev = dev;
-	}
-	/* bind to a specific sap, optional. */
-	if (!addr->sllc_ssap) {
-		rc = -EUSERS;
-		addr->sllc_ssap = llc_ui_autoport();
-		if (!addr->sllc_ssap)
-			goto out;
-	}
-	sap = llc_sap_find(addr->sllc_ssap);
-	if (!sap) {
-		sap = llc_sap_open(addr->sllc_ssap, NULL);
-		rc = -EBUSY; /* some other network layer is using the sap */
-		if (!sap)
-			goto out;
-	} else {
-		struct llc_addr laddr, daddr;
-		struct sock *ask;
-
-		rc = -EUSERS; /* can't get exclusive use of sap */
-		if (!dev && llc_mac_null(addr->sllc_mmac))
-			goto out;
-		memset(&laddr, 0, sizeof(laddr));
-		memset(&daddr, 0, sizeof(daddr));
-		if (!llc_mac_null(addr->sllc_mmac)) {
-			if (sk->sk_type != SOCK_DGRAM) {
-				rc = -EOPNOTSUPP;
-				goto out;
-			}
-			memcpy(laddr.mac, addr->sllc_mmac, IFHWADDRLEN);
-		} else
-			memcpy(laddr.mac, addr->sllc_smac, IFHWADDRLEN);
-		laddr.lsap = addr->sllc_ssap;
-		rc = -EADDRINUSE; /* mac + sap clash. */
-		ask = llc_lookup_established(sap, &daddr, &laddr);
-		if (ask) {
-			sock_put(ask);
-			goto out;
-		}
-	}
-	llc->laddr.lsap = addr->sllc_ssap;
-	if (llc->dev)
-		memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
-	llc->daddr.lsap = addr->sllc_dsap;
-	memcpy(llc->daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
+	rc = -ENODEV;
+	llc->dev = dev_getfirstbyhwtype(addr->sllc_arphrd);
+	if (!llc->dev)
+		goto out;
+	rc = -EUSERS;
+	llc->laddr.lsap = llc_ui_autoport();
+	if (!llc->laddr.lsap)
+		goto out;
+	rc = -EBUSY; /* some other network layer is using the sap */
+	sap = llc_sap_open(llc->laddr.lsap, NULL);
+	if (!sap)
+		goto out;
+	memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
 	memcpy(&llc->addr, addr, sizeof(llc->addr));
 	/* assign new connection to its SAP */
 	llc_sap_add_socket(sap, sk);
@@ -332,16 +293,53 @@
 {
 	struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
 	struct sock *sk = sock->sk;
+	struct llc_opt *llc = llc_sk(sk);
+	struct llc_sap *sap;
 	int rc = -EINVAL;
 
-	dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_ssap);
+	dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap);
 	if (!sk->sk_zapped || addrlen != sizeof(*addr))
 		goto out;
 	rc = -EAFNOSUPPORT;
 	if (addr->sllc_family != AF_LLC)
 		goto out;
-	/* use autobind, to avoid code replication. */
-	rc = llc_ui_autobind(sock, addr);
+	if (!addr->sllc_sap) {
+		rc = -EUSERS;
+		addr->sllc_sap = llc_ui_autoport();
+		if (!addr->sllc_sap)
+			goto out;
+	}
+	sap = llc_sap_find(addr->sllc_sap);
+	if (!sap) {
+		sap = llc_sap_open(addr->sllc_sap, NULL);
+		rc = -EBUSY; /* some other network layer is using the sap */
+		if (!sap)
+			goto out;
+	} else {
+		struct llc_addr laddr, daddr;
+		struct sock *ask;
+
+		memset(&laddr, 0, sizeof(laddr));
+		memset(&daddr, 0, sizeof(daddr));
+		/*
+		 * FIXME: check if the the address is multicast,
+		 * 	  only SOCK_DGRAM can do this.
+		 */
+		memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN);
+		laddr.lsap = addr->sllc_sap;
+		rc = -EADDRINUSE; /* mac + sap clash. */
+		ask = llc_lookup_established(sap, &daddr, &laddr);
+		if (ask) {
+			sock_put(ask);
+			goto out;
+		}
+	}
+	llc->laddr.lsap = addr->sllc_sap;
+	memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN);
+	memcpy(&llc->addr, addr, sizeof(llc->addr));
+	/* assign new connection to its SAP */
+	llc_sap_add_socket(sap, sk);
+	rc = sk->sk_zapped = 0;
 out:
 	return rc;
 }
@@ -386,9 +384,9 @@
  *	@flags: Operational flags specified by the user.
  *
  *	Connect to a remote llc2 mac + sap. The caller must specify the
- *	destination mac and address to connect to. If the user previously
- *	called bind(2) with a smac the user does not need to specify the source
- *	address and mac.
+ *	destination mac and address to connect to. If the user hasn't previously
+ *	called bind(2) with a smac the address of the first interface of the
+ *	specified arp type will be used.
  *	This function will autobind if user did not previously call bind.
  *	Returns: 0 upon success, negative otherwise.
  */
@@ -413,16 +411,10 @@
 		rc = llc_ui_autobind(sock, addr);
 		if (rc)
 			goto out;
+		llc->daddr.lsap = addr->sllc_sap;
+		memcpy(llc->daddr.mac, addr->sllc_mac, IFHWADDRLEN);
 	}
-	if (!llc->dev) {
-		rtnl_lock();
-		dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac);
-		rtnl_unlock();
-		if (!dev)
-			goto out;
-		llc->dev = dev;
-	} else
-		dev = llc->dev;
+	dev = llc->dev;
 	if (sk->sk_type != SOCK_STREAM)
 		goto out;
 	rc = -EALREADY;
@@ -432,7 +424,7 @@
 	sk->sk_state   = TCP_SYN_SENT;
 	llc->link   = llc_ui_next_link_no(llc->sap->laddr.lsap);
 	rc = llc_establish_connection(sk, dev->dev_addr,
-				      addr->sllc_dmac, addr->sllc_dsap);
+				      addr->sllc_mac, addr->sllc_sap);
 	if (rc) {
 		dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__);
 		sock->state  = SS_UNCONNECTED;
@@ -491,12 +483,6 @@
 	add_wait_queue_exclusive(sk->sk_sleep, &wait);
 	for (;;) {
 		__set_current_state(TASK_INTERRUPTIBLE);
-		rc = -ERESTARTSYS;
-		if (signal_pending(current))
-			break;
-		rc = -EAGAIN;
-		if (!timeout)
-			break;
 		rc = 0;
 		if (sk->sk_state != TCP_CLOSE) {
 			release_sock(sk);
@@ -504,6 +490,12 @@
 			lock_sock(sk);
 		} else
 			break;
+		rc = -ERESTARTSYS;
+		if (signal_pending(current))
+			break;
+		rc = -EAGAIN;
+		if (!timeout)
+			break;
 	}
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(sk->sk_sleep, &wait);
@@ -521,12 +513,6 @@
 		rc = -EAGAIN;
 		if (sk->sk_state == TCP_CLOSE)
 			break;
-		rc = -ERESTARTSYS;
-		if (signal_pending(current))
-			break;
-		rc = -EAGAIN;
-		if (!timeout)
-			break;
 		rc = 0;
 		if (sk->sk_state != TCP_ESTABLISHED) {
 			release_sock(sk);
@@ -534,6 +520,12 @@
 			lock_sock(sk);
 		} else
 			break;
+		rc = -ERESTARTSYS;
+		if (signal_pending(current))
+			break;
+		rc = -EAGAIN;
+		if (!timeout)
+			break;
 	}
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(sk->sk_sleep, &wait);
@@ -550,12 +542,6 @@
 		__set_current_state(TASK_INTERRUPTIBLE);
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
 			break;
-		rc = -ERESTARTSYS;
-		if (signal_pending(current))
-			break;
-		rc = -EAGAIN;
-		if (!timeout)
-			break;
 		/*
 		 * Well, if we have backlog, try to process it now.
 		 */
@@ -570,6 +556,12 @@
 			lock_sock(sk);
 		} else
 			break;
+		rc = -ERESTARTSYS;
+		if (signal_pending(current))
+			break;
+		rc = -EAGAIN;
+		if (!timeout)
+			break;
 	}
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(sk->sk_sleep, &wait);
@@ -589,12 +581,6 @@
 		rc = -ENOTCONN;
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
 			break;
-		rc = -ERESTARTSYS;
-		if (signal_pending(current))
-			break;
-		rc = -EAGAIN;
-		if (!timeout)
-			break;
 		rc = 0;
 		if (llc_data_accept_state(llc->state) || llc->p_flag) {
 			release_sock(sk);
@@ -602,6 +588,12 @@
 			lock_sock(sk);
 		} else
 			break;
+		rc = -ERESTARTSYS;
+		if (signal_pending(current))
+			break;
+		rc = -EAGAIN;
+		if (!timeout)
+			break;
 	}
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(sk->sk_sleep, &wait);
@@ -625,7 +617,7 @@
 	int rc = -EOPNOTSUPP;
 
 	dprintk("%s: accepting on %02X\n", __FUNCTION__,
-	        llc_sk(sk)->addr.sllc_ssap);
+	        llc_sk(sk)->laddr.lsap);
 	lock_sock(sk);
 	if (sk->sk_type != SOCK_STREAM)
 		goto out;
@@ -637,7 +629,7 @@
 	if (rc)
 		goto out;
 	dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
-	        llc_sk(sk)->addr.sllc_ssap);
+	        llc_sk(sk)->laddr.lsap);
 	skb = skb_dequeue(&sk->sk_receive_queue);
 	rc = -EINVAL;
 	if (!skb->sk)
@@ -653,8 +645,6 @@
 	llc			= llc_sk(sk);
 	newllc			= llc_sk(newsk);
 	memcpy(&newllc->addr, &llc->addr, sizeof(newllc->addr));
-	memcpy(newllc->addr.sllc_dmac, newllc->daddr.mac, IFHWADDRLEN);
-	newllc->addr.sllc_dsap = newllc->daddr.lsap;
 	newllc->link = llc_ui_next_link_no(newllc->laddr.lsap);
 
 	/* put original socket back into a clean listen state. */
@@ -662,7 +652,7 @@
 	sk->sk_ack_backlog--;
 	skb->sk = NULL;
 	dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
-		llc_sk(sk)->addr.sllc_ssap, newllc->addr.sllc_dsap);
+		llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
 frees:
 	kfree_skb(skb);
 out:
@@ -764,15 +754,7 @@
 		if (rc)
 			goto release;
 	}
-	if (!llc->dev) {
-		rtnl_lock();
-		dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac);
-		rtnl_unlock();
-		rc = -ENETUNREACH;
-		if (!dev)
-			goto release;
-	} else
-		dev = llc->dev;
+	dev = llc->dev;
 	hdrlen = dev->hard_header_len + llc_ui_header_len(sk, addr);
 	size = hdrlen + len;
 	if (size > dev->mtu)
@@ -791,18 +773,18 @@
 	if (rc)
 		goto out;
 	if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
-		llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_dmac,
-					  addr->sllc_dsap);
+		llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac,
+					  addr->sllc_sap);
 		goto out;
 	}
 	if (addr->sllc_test) {
-		llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_dmac,
-					    addr->sllc_dsap);
+		llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac,
+					    addr->sllc_sap);
 		goto out;
 	}
 	if (addr->sllc_xid) {
-		llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_dmac,
-					   addr->sllc_dsap);
+		llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac,
+					   addr->sllc_sap);
 		goto out;
 	}
 	rc = -ENOPROTOOPT;
@@ -850,17 +832,17 @@
 			goto out;
 		if(llc->dev)
 			sllc.sllc_arphrd = llc->dev->type;
-		sllc.sllc_dsap = llc->daddr.lsap;
-		memcpy(&sllc.sllc_dmac, &llc->daddr.mac, IFHWADDRLEN);
+		sllc.sllc_sap = llc->daddr.lsap;
+		memcpy(&sllc.sllc_mac, &llc->daddr.mac, IFHWADDRLEN);
 	} else {
 		rc = -EINVAL;
 		if (!llc->sap)
 			goto out;
-		sllc.sllc_ssap = llc->sap->laddr.lsap;
+		sllc.sllc_sap = llc->sap->laddr.lsap;
 
 		if (llc->dev) {
 			sllc.sllc_arphrd = llc->dev->type;
-			memcpy(&sllc.sllc_smac, &llc->dev->dev_addr,
+			memcpy(&sllc.sllc_mac, &llc->dev->dev_addr,
 			       IFHWADDRLEN);
 		}
 	}
diff -Nru a/net/llc/llc_conn.c b/net/llc/llc_conn.c
--- a/net/llc/llc_conn.c	Wed Nov 12 21:06:46 2003
+++ b/net/llc/llc_conn.c	Wed Nov 12 21:06:46 2003
@@ -514,7 +514,8 @@
 
 		if (rc->sk_type == SOCK_STREAM && rc->sk_state == TCP_LISTEN &&
 		    llc->laddr.lsap == laddr->lsap &&
-		    llc_mac_match(llc->laddr.mac, laddr->mac)) {
+		    (llc_mac_match(llc->laddr.mac, laddr->mac) ||
+		     llc_mac_null(llc->laddr.mac))) {
 			sock_hold(rc);
 			goto found;
 		}
diff -Nru a/net/llc/llc_input.c b/net/llc/llc_input.c
--- a/net/llc/llc_input.c	Wed Nov 12 21:06:47 2003
+++ b/net/llc/llc_input.c	Wed Nov 12 21:06:47 2003
@@ -40,13 +40,13 @@
 					    struct sk_buff *skb))
 {
 	if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
-		llc_type_handlers[type] = handler;
+		llc_type_handlers[type - 1] = handler;
 }
 
 void llc_remove_pack(int type)
 {
 	if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
-		llc_type_handlers[type] = NULL;
+		llc_type_handlers[type - 1] = NULL;
 }
 
 void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
diff -Nru a/net/llc/llc_proc.c b/net/llc/llc_proc.c
--- a/net/llc/llc_proc.c	Wed Nov 12 21:06:46 2003
+++ b/net/llc/llc_proc.c	Wed Nov 12 21:06:46 2003
@@ -44,15 +44,10 @@
 		read_lock_bh(&sap->sk_list.lock);
 		sk_for_each(sk, node, &sap->sk_list.list) {
 			if (!pos)
-				break;
+				goto found;
 			--pos;
 		}
 		read_unlock_bh(&sap->sk_list.lock);
-		if (!pos) {
-			if (node)
-				goto found;
-			break;
-		}
 	}
 	sk = NULL;
 found:
@@ -105,7 +100,7 @@
 
 static void llc_seq_stop(struct seq_file *seq, void *v)
 {
-	if (v) {
+	if (v && v != SEQ_START_TOKEN) {
 		struct sock *sk = v;
 		struct llc_opt *llc = llc_sk(sk);
 		struct llc_sap *sap = llc->sap;
@@ -128,18 +123,16 @@
 	sk = v;
 	llc = llc_sk(sk);
 
-	seq_printf(seq, "%2X  %2X ", sk->sk_type,
-		   !llc_mac_null(llc->addr.sllc_mmac));
+	/* FIXME: check if the address is multicast */
+	seq_printf(seq, "%2X  %2X ", sk->sk_type, 0);
 
-	if (llc->dev && llc_mac_null(llc->addr.sllc_mmac))
+	if (llc->dev)
 		llc_ui_format_mac(seq, llc->dev->dev_addr);
-	else if (!llc_mac_null(llc->addr.sllc_mmac))
-		llc_ui_format_mac(seq, llc->addr.sllc_mmac);
 	else
 		seq_printf(seq, "00:00:00:00:00:00");
 	seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
-	llc_ui_format_mac(seq, llc->addr.sllc_dmac);
-	seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->addr.sllc_dsap,
+	llc_ui_format_mac(seq, llc->daddr.mac);
+	seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
 		   atomic_read(&sk->sk_wmem_alloc),
 		   atomic_read(&sk->sk_rmem_alloc),
 		   sk->sk_state,
diff -Nru a/net/llc/llc_sap.c b/net/llc/llc_sap.c
--- a/net/llc/llc_sap.c	Wed Nov 12 21:06:47 2003
+++ b/net/llc/llc_sap.c	Wed Nov 12 21:06:47 2003
@@ -54,10 +54,8 @@
 	addr->sllc_test   = prim == LLC_TEST_PRIM;
 	addr->sllc_xid    = prim == LLC_XID_PRIM;
 	addr->sllc_ua     = prim == LLC_DATAUNIT_PRIM;
-	llc_pdu_decode_sa(skb, addr->sllc_smac);
-	llc_pdu_decode_da(skb, addr->sllc_dmac);
-	llc_pdu_decode_dsap(skb, &addr->sllc_dsap);
-	llc_pdu_decode_ssap(skb, &addr->sllc_ssap);
+	llc_pdu_decode_sa(skb, addr->sllc_mac);
+	llc_pdu_decode_ssap(skb, &addr->sllc_sap);
 }
 
 /**
diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c	Wed Nov 12 21:06:46 2003
+++ b/net/netlink/af_netlink.c	Wed Nov 12 21:06:46 2003
@@ -394,6 +394,7 @@
 	struct sockaddr_nl *nladdr=(struct sockaddr_nl *)addr;
 	
 	nladdr->nl_family = AF_NETLINK;
+	nladdr->nl_pad = 0;
 	*addr_len = sizeof(*nladdr);
 
 	if (peer) {
@@ -717,6 +718,7 @@
 	if (msg->msg_name) {
 		struct sockaddr_nl *addr = (struct sockaddr_nl*)msg->msg_name;
 		addr->nl_family = AF_NETLINK;
+		addr->nl_pad    = 0;
 		addr->nl_pid	= NETLINK_CB(skb).pid;
 		addr->nl_groups	= NETLINK_CB(skb).dst_groups;
 		msg->msg_namelen = sizeof(*addr);
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Wed Nov 12 21:06:46 2003
+++ b/net/socket.c	Wed Nov 12 21:06:46 2003
@@ -1206,14 +1206,16 @@
  *	ready for listening.
  */
 
+int sysctl_somaxconn = SOMAXCONN;
+
 asmlinkage long sys_listen(int fd, int backlog)
 {
 	struct socket *sock;
 	int err;
 	
 	if ((sock = sockfd_lookup(fd, &err)) != NULL) {
-		if ((unsigned) backlog > SOMAXCONN)
-			backlog = SOMAXCONN;
+		if ((unsigned) backlog > sysctl_somaxconn)
+			backlog = sysctl_somaxconn;
 
 		err = security_socket_listen(sock, backlog);
 		if (err) {
diff -Nru a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
--- a/net/xfrm/xfrm_policy.c	Wed Nov 12 21:06:46 2003
+++ b/net/xfrm/xfrm_policy.c	Wed Nov 12 21:06:46 2003
@@ -519,7 +519,6 @@
 	     *polp != NULL; polp = &(*polp)->next) {
 		if (*polp == pol) {
 			*polp = pol->next;
-			atomic_dec(&pol->refcnt);
 			return pol;
 		}
 	}
@@ -574,6 +573,7 @@
 		write_lock_bh(&xfrm_policy_lock);
 		__xfrm_policy_link(newp, XFRM_POLICY_MAX+dir);
 		write_unlock_bh(&xfrm_policy_lock);
+		xfrm_pol_put(newp);
 	}
 	return newp;
 }
@@ -853,6 +853,8 @@
 xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, 
 	      unsigned short family)
 {
+	if (xfrm_state_kern(x))
+		return tmpl->optional && !xfrm_state_addr_cmp(tmpl, x, family);
 	return	x->id.proto == tmpl->id.proto &&
 		(x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
 		(x->props.reqid == tmpl->reqid || !tmpl->reqid) &&
@@ -862,14 +864,23 @@
 }
 
 static inline int
-xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int idx,
+xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start,
 	       unsigned short family)
 {
+	int idx = start;
+
+	if (tmpl->optional) {
+		if (!tmpl->mode)
+			return start;
+	} else
+		start = -1;
 	for (; idx < sp->len; idx++) {
 		if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family))
 			return ++idx;
+		if (sp->x[idx].xvec->props.mode)
+			break;
 	}
-	return -1;
+	return start;
 }
 
 static int
@@ -922,32 +933,35 @@
 					xfrm_policy_lookup);
 
 	if (!pol)
-		return 1;
+		return !skb->sp;
 
 	pol->curlft.use_time = (unsigned long)xtime.tv_sec;
 
 	if (pol->action == XFRM_POLICY_ALLOW) {
-		if (pol->xfrm_nr != 0) {
-			struct sec_path *sp;
-			static struct sec_path dummy;
-			int i, k;
-
-			if ((sp = skb->sp) == NULL)
-				sp = &dummy;
-
-			/* For each tmpl search corresponding xfrm.
-			 * Order is _important_. Later we will implement
-			 * some barriers, but at the moment barriers
-			 * are implied between each two transformations.
-			 */
-			for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
-				if (pol->xfrm_vec[i].optional)
-					continue;
-				k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
-				if (k < 0)
-					goto reject;
-			}
+		struct sec_path *sp;
+		static struct sec_path dummy;
+		int i, k;
+
+		if ((sp = skb->sp) == NULL)
+			sp = &dummy;
+
+		/* For each tunnel xfrm, find the first matching tmpl.
+		 * For each tmpl before that, find corresponding xfrm.
+		 * Order is _important_. Later we will implement
+		 * some barriers, but at the moment barriers
+		 * are implied between each two transformations.
+		 */
+		for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
+			k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
+			if (k < 0)
+				goto reject;
+		}
+
+		for (; k < sp->len; k++) {
+			if (sp->x[k].xvec->props.mode)
+				goto reject;
 		}
+
 		xfrm_pol_put(pol);
 		return 1;
 	}
diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
--- a/net/xfrm/xfrm_state.c	Wed Nov 12 21:06:47 2003
+++ b/net/xfrm/xfrm_state.c	Wed Nov 12 21:06:47 2003
@@ -831,6 +831,7 @@
 
 	if (err >= 0) {
 		xfrm_sk_policy_insert(sk, err, pol);
+		xfrm_pol_put(pol);
 		err = 0;
 	}
 
diff -Nru a/sound/oss/ali5455.c b/sound/oss/ali5455.c
--- a/sound/oss/ali5455.c	Wed Nov 12 21:06:47 2003
+++ b/sound/oss/ali5455.c	Wed Nov 12 21:06:47 2003
@@ -1253,17 +1253,16 @@
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
 	int free;
-	ali_update_ptr(state);
-	// catch underruns during playback
+
 	if (dmabuf->count < 0) {
 		dmabuf->count = 0;
 		dmabuf->swptr = dmabuf->hwptr;
 	}
-	free = dmabuf->dmasize - dmabuf->count;
-	free -= (dmabuf->hwptr % dmabuf->fragsize);
-	if (free < 0)
-		return (0);
-	return (free);
+	free = dmabuf->dmasize - dmabuf->swptr;
+	if ((dmabuf->count + free) > dmabuf->dmasize){
+		free = dmabuf->dmasize - dmabuf->count;
+	}
+	return free;
 }
 
 static inline int ali_get_available_read_data(struct
@@ -1860,6 +1859,7 @@
 			   NOTHING we can do to prevent it. */
 			   
 			/* FIXME - do timeout handling here !! */
+			schedule_timeout(tmo >= 2 ? tmo : 2);
 
 			if (signal_pending(current)) {
 				if (!ret)