# 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.1401 
#	drivers/net/8139too.c	1.74    -> 1.75   
#	arch/sparc64/kernel/entry.S	1.29    -> 1.30   
#	include/asm-x86_64/irq.h	1.3     -> 1.4    
#	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    
#	    net/llc/af_llc.c	1.51    -> 1.58   
#	include/asm-sparc64/pgtable.h	1.31    -> 1.32   
#	drivers/pci/quirks.c	1.36    -> 1.37   
#	include/linux/libata.h	1.1     -> 1.3    
#	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   
#	net/ipv6/ip6_output.c	1.44    -> 1.46   
#	  net/llc/llc_conn.c	1.38    -> 1.39   
#	include/asm-sparc/unistd.h	1.26    -> 1.27   
#	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.174  
#	 drivers/net/Space.c	1.42    -> 1.43   
#	drivers/block/ll_rw_blk.c	1.219   -> 1.220  
#	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   
#	net/ipv4/netfilter/ip_nat_core.c	1.34    -> 1.35   
#	arch/x86_64/kernel/x8664_ksyms.c	1.18    -> 1.20   
#	      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/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.35   
#	 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    
#	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   
#	      net/ipv4/tcp.c	1.49    -> 1.50   
#	net/ipv6/netfilter/ip6_queue.c	1.12    -> 1.13   
#	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   
#	fs/jbd/transaction.c	1.76    -> 1.77   
#	  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.76   
#	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.14   
#	    fs/binfmt_misc.c	1.22    -> 1.23   
#	net/core/sysctl_net_core.c	1.7     -> 1.8    
#	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/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/sparc64/lib/rwlock.S	1.1     -> 1.2    
#	      fs/fat/inode.c	1.80    -> 1.81   
#	 include/linux/llc.h	1.3     -> 1.4    
#	drivers/usb/serial/digi_acceleport.c	1.40    -> 1.41   
#	arch/sparc/kernel/entry.S	1.16    -> 1.17   
#	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   
#	 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/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/3c527.c	1.16    -> 1.17   
#	      fs/direct-io.c	1.34    -> 1.35   
#	drivers/char/sonypi.h	1.18    -> 1.19   
#	drivers/net/arm/ether1.c	1.15    -> 1.16   
#	         MAINTAINERS	1.176   -> 1.178  
#	drivers/scsi/sata_svw.c	1.1     -> 1.2    
#	drivers/pcmcia/yenta_socket.c	1.49    -> 1.50   
#	        net/compat.c	1.11    -> 1.12   
#	drivers/net/tokenring/ibmtr.c	1.18    -> 1.19   
#	drivers/net/pcmcia/fmvj18x_cs.c	1.26    -> 1.27   
#	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.9    
#	include/asm-sparc64/hardirq.h	1.16    -> 1.17   
#	drivers/scsi/constants.c	1.13    -> 1.14   
#	     kernel/module.c	1.94    -> 1.95   
#	   net/core/skbuff.c	1.31    -> 1.32   
#	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   
#	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    
#	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   
#	   net/llc/llc_sap.c	1.30    -> 1.31   
#	include/linux/socket.h	1.9     -> 1.10   
#	      kernel/sched.c	1.222   -> 1.223  
#	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   
#	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   
#	       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.31   
#	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   
#	arch/ia64/kernel/perfmon.c	1.65    -> 1.67   
#	 net/ipv6/addrconf.c	1.71    -> 1.74   
#	include/linux/netdevice.h	1.64    -> 1.66   
#	        crypto/api.c	1.30    -> 1.31   
#	include/net/if_inet6.h	1.9     -> 1.10   
#	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/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    
#	net/ipv4/netfilter/ip_queue.c	1.14    -> 1.15   
#
# 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
# --------------------------------------------
#
diff -Nru a/Documentation/networking/irda.txt b/Documentation/networking/irda.txt
--- a/Documentation/networking/irda.txt	Tue Nov  4 21:58:43 2003
+++ b/Documentation/networking/irda.txt	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/Documentation/video4linux/meye.txt	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/MAINTAINERS	Tue Nov  4 21:58:43 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
diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
--- a/arch/alpha/kernel/setup.c	Tue Nov  4 21:58:43 2003
+++ b/arch/alpha/kernel/setup.c	Tue Nov  4 21:58:43 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/h8300/kernel/time.c b/arch/h8300/kernel/time.c
--- a/arch/h8300/kernel/time.c	Tue Nov  4 21:58:43 2003
+++ b/arch/h8300/kernel/time.c	Tue Nov  4 21:58:43 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/vm86.c b/arch/i386/kernel/vm86.c
--- a/arch/i386/kernel/vm86.c	Tue Nov  4 21:58:43 2003
+++ b/arch/i386/kernel/vm86.c	Tue Nov  4 21:58:43 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/mm/ioremap.c b/arch/i386/mm/ioremap.c
--- a/arch/i386/mm/ioremap.c	Tue Nov  4 21:58:43 2003
+++ b/arch/i386/mm/ioremap.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/arch/i386/pci/irq.c	Tue Nov  4 21:58:44 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/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c	Tue Nov  4 21:58:44 2003
+++ b/arch/ia64/kernel/perfmon.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/arch/ia64/kernel/perfmon_mckinley.h	Tue Nov  4 21:58:44 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/mm/tlb.c b/arch/ia64/mm/tlb.c
--- a/arch/ia64/mm/tlb.c	Tue Nov  4 21:58:44 2003
+++ b/arch/ia64/mm/tlb.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/arch/ia64/sn/io/machvec/pci_dma.c	Tue Nov  4 21:58:43 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/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
--- a/arch/sparc/kernel/entry.S	Tue Nov  4 21:58:43 2003
+++ b/arch/sparc/kernel/entry.S	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/arch/sparc/kernel/systbls.S	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/arch/sparc64/Kconfig	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/arch/sparc64/kernel/entry.S	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/arch/sparc64/kernel/rtrap.S	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/arch/sparc64/kernel/sparc64_ksyms.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/arch/sparc64/kernel/systbls.S	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/arch/sparc64/lib/dec_and_lock.S	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/arch/sparc64/lib/rwlock.S	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/arch/x86_64/kernel/acpi/boot.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/arch/x86_64/kernel/entry.S	Tue Nov  4 21:58:43 2003
@@ -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	Tue Nov  4 21:58:43 2003
+++ b/arch/x86_64/kernel/io_apic.c	Tue Nov  4 21:58:43 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/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c	Tue Nov  4 21:58:43 2003
+++ b/arch/x86_64/kernel/setup64.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/arch/x86_64/kernel/smp.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/arch/x86_64/kernel/time.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/arch/x86_64/kernel/x8664_ksyms.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/arch/x86_64/mm/extable.c	Tue Nov  4 21:58:44 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/k8topology.c b/arch/x86_64/mm/k8topology.c
--- a/arch/x86_64/mm/k8topology.c	Tue Nov  4 21:58:44 2003
+++ b/arch/x86_64/mm/k8topology.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/arch/x86_64/mm/numa.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/crypto/api.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/acpi/dispatcher/dsopcode.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/acpi/ec.c	Tue Nov  4 21:58:43 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/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Tue Nov  4 21:58:43 2003
+++ b/drivers/block/ll_rw_blk.c	Tue Nov  4 21:58:43 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)
diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
--- a/drivers/char/agp/sis-agp.c	Tue Nov  4 21:58:43 2003
+++ b/drivers/char/agp/sis-agp.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/char/sonypi.h	Tue Nov  4 21:58:43 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/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	Tue Nov  4 21:58:43 2003
+++ b/drivers/ide/ide-tape.c	Tue Nov  4 21:58:43 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/amd74xx.c b/drivers/ide/pci/amd74xx.c
--- a/drivers/ide/pci/amd74xx.c	Tue Nov  4 21:58:44 2003
+++ b/drivers/ide/pci/amd74xx.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/ide/pci/amd74xx.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/input/keyboard/atkbd.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/input/mouse/psmouse-base.c	Tue Nov  4 21:58:43 2003
@@ -40,7 +40,7 @@
 
 static int psmouse_noext;
 int psmouse_resolution;
-unsigned int psmouse_rate = 60;
+unsigned int psmouse_rate;
 int psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL;
 unsigned int psmouse_resetafter;
 
@@ -471,13 +471,16 @@
  * We set the mouse report rate.
  */
 
-	psmouse_set_rate(psmouse);
+	if (psmouse_rate)
+		psmouse_set_rate(psmouse);
 
 /*
  * We also set the resolution and scaling.
  */
 
-	psmouse_set_resolution(psmouse);
+	if (psmouse_resolution)
+		psmouse_set_resolution(psmouse);
+
 	psmouse_command(psmouse,  NULL, PSMOUSE_CMD_SETSCALE11);
 
 /*
@@ -651,10 +654,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	Tue Nov  4 21:58:44 2003
+++ b/drivers/md/dm-table.c	Tue Nov  4 21:58:44 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/media/video/bt832.c b/drivers/media/video/bt832.c
--- a/drivers/media/video/bt832.c	Tue Nov  4 21:58:44 2003
+++ b/drivers/media/video/bt832.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/media/video/bttv-cards.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/media/video/bttv-if.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/media/video/meye.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/media/video/saa5249.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/media/video/tuner-3036.c	Tue Nov  4 21:58:43 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/3c527.c b/drivers/net/3c527.c
--- a/drivers/net/3c527.c	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/3c527.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/8139cp.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/8139too.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/Space.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/arm/ether1.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/net/arm/ether3.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/net/arm/etherh.c	Tue Nov  4 21:58:44 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/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c	Tue Nov  4 21:58:44 2003
+++ b/drivers/net/bonding/bond_main.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/ethertap.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/net/pcmcia/fmvj18x_cs.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/pcmcia/ibmtr_cs.c	Tue Nov  4 21:58:43 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/r8169.c b/drivers/net/r8169.c
--- a/drivers/net/r8169.c	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/r8169.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/sis900.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/starfire.c	Tue Nov  4 21:58:43 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/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
--- a/drivers/net/tokenring/ibmtr.c	Tue Nov  4 21:58:44 2003
+++ b/drivers/net/tokenring/ibmtr.c	Tue Nov  4 21:58:44 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/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Tue Nov  4 21:58:43 2003
+++ b/drivers/net/wireless/airo.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/pci/quirks.c	Tue Nov  4 21:58:43 2003
@@ -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	Tue Nov  4 21:58:44 2003
+++ b/drivers/pci/setup-bus.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/pci/setup-res.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/pcmcia/yenta_socket.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/scsi/Kconfig	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/scsi/ata_piix.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/scsi/constants.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/scsi/libata-core.c	Tue Nov  4 21:58:43 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/osst_options.h b/drivers/scsi/osst_options.h
--- a/drivers/scsi/osst_options.h	Tue Nov  4 21:58:44 2003
+++ b/drivers/scsi/osst_options.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/drivers/scsi/sata_promise.c	Tue Nov  4 21:58:44 2003
@@ -32,22 +32,46 @@
 #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.84"
 
 
 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_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 +80,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 +99,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 +136,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 +208,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 +230,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 +333,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 +376,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 +391,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 +415,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 +443,461 @@
 	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 *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);
+	/*
+	 * 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);
+	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));
+
+	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);
+#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);
+		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;
+
+	VPRINTK("ENTER\n");
+
+	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));
+#ifdef DIRECT_HDMA
+			pdc20621_push_hdma(qc);
+#else
+			writel(port_ofs + PDC_DIMM_HOST_PKT,
+			       mmio + PDC_HDMA_PKT_SUBMIT);
+#endif
+		}
+		handled = 1;
+		break;
 
-	/* clear DMA start/stop bit (bit 7) */
-	val = readl(dmactl);
-	writel(val & ~(1 << 7), dmactl);
+	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));
+			writel(port_ofs + PDC_DIMM_ATA_PKT,
+			       (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;
+        }
 
-	/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
-	ata_altstatus(ap);              /* dummy read */
+        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 &= 0xf;		/* 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 +921,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 +982,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,21 +994,8 @@
 
 	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");
@@ -520,56 +1032,35 @@
 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));
 
-	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);
+}
 
-	/* 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 +1077,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 +1146,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 +1188,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,8 +1207,10 @@
        	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;
@@ -712,15 +1241,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 +1252,8 @@
 
 	return 0;
 
+err_out_iounmap:
+	iounmap(mmio_base);
 err_out_free_ent:
 	kfree(probe_ent);
 err_out_regions:
@@ -736,7 +1262,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	Tue Nov  4 21:58:43 2003
+++ b/drivers/scsi/sata_sil.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/scsi/sata_svw.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/scsi/sata_via.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/serial/serial_core.c	Tue Nov  4 21:58:43 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/serial/Kconfig b/drivers/usb/serial/Kconfig
--- a/drivers/usb/serial/Kconfig	Tue Nov  4 21:58:44 2003
+++ b/drivers/usb/serial/Kconfig	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/drivers/usb/serial/digi_acceleport.c	Tue Nov  4 21:58:43 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/fs/binfmt_misc.c b/fs/binfmt_misc.c
--- a/fs/binfmt_misc.c	Tue Nov  4 21:58:43 2003
+++ b/fs/binfmt_misc.c	Tue Nov  4 21:58:43 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/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c	Tue Nov  4 21:58:43 2003
+++ b/fs/direct-io.c	Tue Nov  4 21:58:43 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/fat/inode.c b/fs/fat/inode.c
--- a/fs/fat/inode.c	Tue Nov  4 21:58:43 2003
+++ b/fs/fat/inode.c	Tue Nov  4 21:58:43 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/transaction.c b/fs/jbd/transaction.c
--- a/fs/jbd/transaction.c	Tue Nov  4 21:58:43 2003
+++ b/fs/jbd/transaction.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/fs/jfs/jfs_metapage.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/fs/jfs/namei.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/fs/minix/inode.c	Tue Nov  4 21:58:43 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/include/asm-h8300/smplock.h b/include/asm-h8300/smplock.h
--- a/include/asm-h8300/smplock.h	Tue Nov  4 21:58:44 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-sparc/bitext.h b/include/asm-sparc/bitext.h
--- a/include/asm-sparc/bitext.h	Tue Nov  4 21:58:44 2003
+++ b/include/asm-sparc/bitext.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/include/asm-sparc/ioctl.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-sparc/namei.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-sparc/pcic.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-sparc/unistd.h	Tue Nov  4 21:58:43 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/hardirq.h b/include/asm-sparc64/hardirq.h
--- a/include/asm-sparc64/hardirq.h	Tue Nov  4 21:58:44 2003
+++ b/include/asm-sparc64/hardirq.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/include/asm-sparc64/ioctl.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-sparc64/namei.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-sparc64/pgtable.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-sparc64/spinlock.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-sparc64/unistd.h	Tue Nov  4 21:58:43 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/hw_irq.h b/include/asm-x86_64/hw_irq.h
--- a/include/asm-x86_64/hw_irq.h	Tue Nov  4 21:58:44 2003
+++ b/include/asm-x86_64/hw_irq.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-x86_64/irq.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-x86_64/pci.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/include/asm-x86_64/processor.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/asm-x86_64/smp.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/include/asm-x86_64/topology.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/linux/blkdev.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/include/linux/in.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/linux/ip.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/include/linux/ipv6.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/linux/libata.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/linux/llc.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/include/linux/netdevice.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/linux/pci_ids.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/linux/preempt.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/include/linux/sched.h	Tue Nov  4 21:58:43 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 */
diff -Nru a/include/linux/serial.h b/include/linux/serial.h
--- a/include/linux/serial.h	Tue Nov  4 21:58:43 2003
+++ b/include/linux/serial.h	Tue Nov  4 21:58:43 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/socket.h b/include/linux/socket.h
--- a/include/linux/socket.h	Tue Nov  4 21:58:44 2003
+++ b/include/linux/socket.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/linux/sysctl.h	Tue Nov  4 21:58:43 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/udp.h b/include/linux/udp.h
--- a/include/linux/udp.h	Tue Nov  4 21:58:43 2003
+++ b/include/linux/udp.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/include/net/if_inet6.h	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/include/net/tcp.h	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/kernel/exit.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/kernel/module.c	Tue Nov  4 21:58:44 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/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Tue Nov  4 21:58:44 2003
+++ b/kernel/sched.c	Tue Nov  4 21:58:44 2003
@@ -742,7 +742,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 +757,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);
 }
 
diff -Nru a/lib/div64.c b/lib/div64.c
--- a/lib/div64.c	Tue Nov  4 21:58:43 2003
+++ b/lib/div64.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/mm/filemap.c	Tue Nov  4 21:58:43 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/net/Kconfig b/net/Kconfig
--- a/net/Kconfig	Tue Nov  4 21:58:43 2003
+++ b/net/Kconfig	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/appletalk/ddp.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/bridge/netfilter/ebt_limit.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/compat.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/core/dev.c	Tue Nov  4 21:58:43 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/skbuff.c b/net/core/skbuff.c
--- a/net/core/skbuff.c	Tue Nov  4 21:58:44 2003
+++ b/net/core/skbuff.c	Tue Nov  4 21:58:44 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_off = head_copy_len - newheadroom;
+		head_copy_len = newheadroom;
+	}
+
+	/* 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	Tue Nov  4 21:58:44 2003
+++ b/net/core/sock.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/core/sysctl_net_core.c	Tue Nov  4 21:58:43 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/ipv4/ah4.c b/net/ipv4/ah4.c
--- a/net/ipv4/ah4.c	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/ah4.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/arp.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/ip_gre.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/ipcomp.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/ipv4/ipmr.c	Tue Nov  4 21:58:43 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/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
--- a/net/ipv4/netfilter/Kconfig	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/netfilter/Kconfig	Tue Nov  4 21:58:44 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/ip_fw_compat_masq.c b/net/ipv4/netfilter/ip_fw_compat_masq.c
--- a/net/ipv4/netfilter/ip_fw_compat_masq.c	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/netfilter/ip_fw_compat_masq.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/ipv4/netfilter/ip_nat_core.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/netfilter/ip_queue.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c	Tue Nov  4 21:58:43 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/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	Tue Nov  4 21:58:43 2003
+++ b/net/ipv4/tcp.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/tcp_input.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/ipv4/tcp_ipv4.c	Tue Nov  4 21:58:43 2003
@@ -178,12 +178,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 +187,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)) {
diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c	Tue Nov  4 21:58:44 2003
+++ b/net/ipv4/tcp_minisocks.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/ipv4/udp.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/ipv6/addrconf.c	Tue Nov  4 21:58:44 2003
@@ -970,36 +970,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 +1106,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 +1131,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>:
diff -Nru a/net/ipv6/ah6.c b/net/ipv6/ah6.c
--- a/net/ipv6/ah6.c	Tue Nov  4 21:58:44 2003
+++ b/net/ipv6/ah6.c	Tue Nov  4 21:58:44 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/ip6_output.c b/net/ipv6/ip6_output.c
--- a/net/ipv6/ip6_output.c	Tue Nov  4 21:58:43 2003
+++ b/net/ipv6/ip6_output.c	Tue Nov  4 21:58:43 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/ipcomp6.c b/net/ipv6/ipcomp6.c
--- a/net/ipv6/ipcomp6.c	Tue Nov  4 21:58:43 2003
+++ b/net/ipv6/ipcomp6.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/ipv6/mcast.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/ipv6/netfilter/ip6_queue.c	Tue Nov  4 21:58:43 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/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	Tue Nov  4 21:58:44 2003
+++ b/net/ipv6/udp.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/ipv6/xfrm6_policy.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/net/ipx/af_ipx.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/net/irda/af_irda.c	Tue Nov  4 21:58:43 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/irlmp.c b/net/irda/irlmp.c
--- a/net/irda/irlmp.c	Tue Nov  4 21:58:44 2003
+++ b/net/irda/irlmp.c	Tue Nov  4 21:58:44 2003
@@ -1812,6 +1812,7 @@
 	void *v;
 	loff_t off = *pos;
 
+	iter->hashbin = NULL;
 	if (off-- == 0)
 		return LSAP_START_TOKEN;
 
@@ -1950,7 +1951,6 @@
 
 	seq	     = file->private_data;
 	seq->private = s;
-	memset(s, 0, sizeof(*s));
 out:
 	return rc;
 out_kfree:
diff -Nru a/net/llc/af_llc.c b/net/llc/af_llc.c
--- a/net/llc/af_llc.c	Tue Nov  4 21:58:43 2003
+++ b/net/llc/af_llc.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/net/llc/llc_conn.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/llc/llc_input.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/llc/llc_proc.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/llc/llc_sap.c	Tue Nov  4 21:58:44 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	Tue Nov  4 21:58:43 2003
+++ b/net/netlink/af_netlink.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/net/socket.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:43 2003
+++ b/net/xfrm/xfrm_policy.c	Tue Nov  4 21:58:43 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	Tue Nov  4 21:58:44 2003
+++ b/net/xfrm/xfrm_state.c	Tue Nov  4 21:58:44 2003
@@ -831,6 +831,7 @@
 
 	if (err >= 0) {
 		xfrm_sk_policy_insert(sk, err, pol);
+		xfrm_pol_put(pol);
 		err = 0;
 	}
 
