[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] Apply patch for 2.6.18.8.



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Date 1191402044 -3600
# Node ID 3e8752eb6d9c63bbc49faf4873316aed366e07cf
# Parent  aafef975e5186fe684b466235f26194bb89609be
Apply patch for 2.6.18.8.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
 include/asm-arm26/Kbuild                           |    1 
 include/asm-um/Kbuild                              |    1 
 Documentation/dontdiff                             |    1 
 Documentation/sysctl/vm.txt                        |   27 
 Makefile                                           |   13 
 arch/alpha/Kconfig                                 |    2 
 arch/arm/kernel/calls.S                            |   13 
 arch/i386/Kconfig.cpu                              |    3 
 arch/i386/kernel/alternative.c                     |    6 
 arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c        |    3 
 arch/i386/kernel/microcode.c                       |    9 
 arch/i386/kernel/smpboot.c                         |    6 
 arch/i386/mm/boot_ioremap.c                        |    7 
 arch/i386/pci/irq.c                                |    4 
 arch/ia64/kernel/acpi.c                            |   13 
 arch/ia64/kernel/numa.c                            |   34 
 arch/ia64/kernel/topology.c                        |    4 
 arch/ia64/sn/kernel/bte.c                          |    9 
 arch/m32r/kernel/entry.S                           |   65 -
 arch/powerpc/Kconfig                               |    9 
 arch/powerpc/configs/pseries_defconfig             |    1 
 arch/powerpc/kernel/traps.c                        |   20 
 arch/ppc/kernel/traps.c                            |   20 
 arch/s390/Kconfig                                  |    4 
 arch/s390/lib/Makefile                             |    1 
 arch/s390/lib/div64.c                              |  151 +++
 arch/s390/lib/uaccess.S                            |   12 
 arch/s390/lib/uaccess64.S                          |   12 
 arch/sh/kernel/process.c                           |    1 
 arch/sparc/kernel/entry.S                          |    3 
 arch/sparc64/kernel/central.c                      |    4 
 arch/sparc64/kernel/entry.S                        |    3 
 arch/sparc64/kernel/of_device.c                    |   39 
 arch/sparc64/kernel/pci_common.c                   |   29 
 arch/sparc64/kernel/pci_iommu.c                    |    2 
 arch/sparc64/kernel/pci_sabre.c                    |   25 
 arch/sparc64/kernel/prom.c                         |   32 
 arch/sparc64/kernel/time.c                         |    2 
 arch/sparc64/mm/init.c                             |    3 
 arch/um/Kconfig                                    |    5 
 arch/um/Makefile-x86_64                            |    2 
 arch/um/include/common-offsets.h                   |    1 
 arch/um/include/kern_util.h                        |    1 
 arch/um/include/sysdep-i386/kernel-offsets.h       |    1 
 arch/um/include/sysdep-x86_64/kernel-offsets.h     |    1 
 arch/um/os-Linux/process.c                         |    4 
 arch/um/os-Linux/sys-i386/tls.c                    |    6 
 arch/um/os-Linux/tls.c                             |    9 
 arch/um/sys-x86_64/stub_segv.c                     |    1 
 arch/x86_64/ia32/ptrace32.c                        |    1 
 arch/x86_64/kernel/entry.S                         |    4 
 arch/x86_64/kernel/pci-calgary.c                   |   13 
 arch/x86_64/kernel/process.c                       |    7 
 arch/x86_64/kernel/setup.c                         |    5 
 arch/x86_64/kernel/setup64.c                       |    6 
 arch/x86_64/kernel/time.c                          |    2 
 block/elevator.c                                   |    4 
 block/ll_rw_blk.c                                  |   24 
 block/scsi_ioctl.c                                 |    5 
 drivers/block/DAC960.c                             |    2 
 drivers/block/cciss.c                              |    6 
 drivers/block/cpqarray.c                           |   19 
 drivers/char/agp/generic.c                         |    2 
 drivers/char/agp/intel-agp.c                       |    2 
 drivers/char/hw_random/intel-rng.c                 |  188 +++
 drivers/char/ipmi/ipmi_si_intf.c                   |    2 
 drivers/char/isicom.c                              |    3 
 drivers/char/mem.c                                 |   12 
 drivers/char/rtc.c                                 |    5 
 drivers/char/watchdog/sc1200wdt.c                  |    9 
 drivers/clocksource/scx200_hrt.c                   |    4 
 drivers/cpufreq/cpufreq_stats.c                    |    2 
 drivers/i2c/chips/ds1337.c                         |    8 
 drivers/ide/pci/generic.c                          |   18 
 drivers/ide/ppc/pmac.c                             |    2 
 drivers/ieee1394/ohci1394.c                        |   21 
 drivers/infiniband/core/mad.c                      |    2 
 drivers/infiniband/hw/mthca/mthca_cq.c             |    7 
 drivers/infiniband/hw/mthca/mthca_mad.c            |    2 
 drivers/infiniband/hw/mthca/mthca_qp.c             |   19 
 drivers/infiniband/hw/mthca/mthca_srq.c            |    8 
 drivers/infiniband/ulp/ipoib/ipoib_ib.c            |    4 
 drivers/infiniband/ulp/srp/ib_srp.c                |    2 
 drivers/infiniband/ulp/srp/ib_srp.h                |    2 
 drivers/input/mouse/psmouse-base.c                 |   10 
 drivers/isdn/capi/capidrv.c                        |    3 
 drivers/isdn/hisax/config.c                        |    6 
 drivers/isdn/i4l/isdn_common.c                     |    9 
 drivers/isdn/icn/icn.c                             |    3 
 drivers/isdn/isdnloop/isdnloop.c                   |    3 
 drivers/isdn/pcbit/drv.c                           |   16 
 drivers/macintosh/via-pmu-backlight.c              |    2 
 drivers/md/dm-crypt.c                              |    6 
 drivers/md/dm-snap.c                               |    1 
 drivers/md/md.c                                    |    2 
 drivers/md/multipath.c                             |    2 
 drivers/md/raid10.c                                |    2 
 drivers/media/Kconfig                              |    1 
 drivers/media/dvb/b2c2/flexcop-fe-tuner.c          |    2 
 drivers/media/dvb/dvb-core/dvb_net.c               |    4 
 drivers/media/dvb/frontends/cx24123.c              |    4 
 drivers/media/dvb/frontends/dvb-pll.c              |    3 
 drivers/media/dvb/frontends/lgdt330x.c             |    6 
 drivers/media/video/cx88/cx88-cards.c              |    2 
 drivers/media/video/cx88/cx88-dvb.c                |   14 
 drivers/media/video/ks0127.c                       |    8 
 drivers/media/video/msp3400-driver.c               |    2 
 drivers/media/video/msp3400-driver.h               |    1 
 drivers/media/video/msp3400-kthreads.c             |    5 
 drivers/media/video/pvrusb2/Kconfig                |    9 
 drivers/media/video/pvrusb2/pvrusb2-ctrl.c         |   21 
 drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h |    2 
 drivers/media/video/pvrusb2/pvrusb2-hdw.c          |   30 
 drivers/media/video/pvrusb2/pvrusb2-v4l2.c         |  101 --
 drivers/media/video/saa7134/saa7134-dvb.c          |    4 
 drivers/media/video/tuner-simple.c                 |    2 
 drivers/media/video/tuner-types.c                  |   14 
 drivers/media/video/tveeprom.c                     |    2 
 drivers/media/video/usbvideo/quickcam_messenger.h  |   14 
 drivers/media/video/video-buf.c                    |    1 
 drivers/media/video/videodev.c                     |    6 
 drivers/net/bonding/bond_main.c                    |    2 
 drivers/net/e1000/e1000_main.c                     |    7 
 drivers/net/forcedeth.c                            |    3 
 drivers/net/lp486e.c                               |    6 
 drivers/net/mv643xx_eth.c                          |    2 
 drivers/net/sky2.c                                 |   95 +-
 drivers/net/sky2.h                                 |    2 
 drivers/net/sunhme.c                               |    5 
 drivers/net/tg3.c                                  |    4 
 drivers/net/wireless/bcm43xx/bcm43xx.h             |  183 +--
 drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c     |   80 +
 drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h     |    1 
 drivers/net/wireless/bcm43xx/bcm43xx_dma.c         |  601 ++++++++----
 drivers/net/wireless/bcm43xx/bcm43xx_dma.h         |  296 ++++--
 drivers/net/wireless/bcm43xx/bcm43xx_leds.c        |   16 
 drivers/net/wireless/bcm43xx/bcm43xx_main.c        |  997 ++++++++++++---------
 drivers/net/wireless/bcm43xx/bcm43xx_main.h        |    6 
 drivers/net/wireless/bcm43xx/bcm43xx_phy.c         |   50 -
 drivers/net/wireless/bcm43xx/bcm43xx_pio.c         |    4 
 drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c       |   54 -
 drivers/net/wireless/bcm43xx/bcm43xx_wx.c          |  127 +-
 drivers/net/wireless/bcm43xx/bcm43xx_xmit.h        |   10 
 drivers/net/wireless/zd1211rw/zd_chip.c            |    2 
 drivers/pci/pci-sysfs.c                            |    3 
 drivers/pci/quirks.c                               |   27 
 drivers/pcmcia/ds.c                                |    5 
 drivers/rtc/rtc-max6902.c                          |    2 
 drivers/rtc/rtc-pcf8563.c                          |    4 
 drivers/scsi/aic7xxx/aic7xxx_osm.c                 |   23 
 drivers/scsi/sata_mv.c                             |    1 
 drivers/scsi/scsi_lib.c                            |    2 
 drivers/serial/serial_core.c                       |    9 
 drivers/serial/serial_cs.c                         |   14 
 drivers/usb/class/usblp.c                          |    1 
 drivers/usb/core/devio.c                           |   28 
 drivers/usb/core/notify.c                          |    3 
 drivers/usb/core/usb.h                             |    1 
 drivers/usb/gadget/ether.c                         |    4 
 drivers/usb/input/hid-core.c                       |    4 
 drivers/usb/input/hid-input.c                      |   17 
 drivers/usb/input/hid.h                            |    1 
 drivers/usb/input/usbtouchscreen.c                 |    2 
 drivers/video/fbmem.c                              |    3 
 drivers/video/fbsysfs.c                            |   12 
 drivers/video/nvidia/nv_hw.c                       |   12 
 drivers/video/nvidia/nv_setup.c                    |   18 
 drivers/video/nvidia/nv_type.h                     |    1 
 drivers/video/nvidia/nvidia.c                      |   24 
 fs/buffer.c                                        |   26 
 fs/cifs/CHANGES                                    |    6 
 fs/cifs/file.c                                     |    3 
 fs/cifs/inode.c                                    |   14 
 fs/compat.c                                        |    2 
 fs/ext2/super.c                                    |    4 
 fs/ext3/super.c                                    |    4 
 fs/fuse/dir.c                                      |   82 +
 fs/fuse/file.c                                     |   12 
 fs/fuse/inode.c                                    |    5 
 fs/hfs/super.c                                     |    2 
 fs/jbd/commit.c                                    |  188 ++-
 fs/jfs/jfs_imap.c                                  |    4 
 fs/nfs/dir.c                                       |   14 
 fs/nfsd/nfs2acl.c                                  |   17 
 fs/splice.c                                        |    6 
 fs/sysfs/file.c                                    |    5 
 include/Kbuild                                     |   11 
 include/asm-alpha/Kbuild                           |   10 
 include/asm-arm/elf.h                              |   18 
 include/asm-arm/page.h                             |    4 
 include/asm-arm/unistd.h                           |   13 
 include/asm-cris/Kbuild                            |    4 
 include/asm-cris/arch-v10/Kbuild                   |    2 
 include/asm-cris/arch-v32/Kbuild                   |    2 
 include/asm-cris/byteorder.h                       |    3 
 include/asm-cris/elf.h                             |    8 
 include/asm-cris/page.h                            |    8 
 include/asm-cris/posix_types.h                     |    9 
 include/asm-cris/unistd.h                          |    4 
 include/asm-generic/Kbuild                         |   15 
 include/asm-generic/Kbuild.asm                     |   38 
 include/asm-generic/audit_change_attr.h            |    4 
 include/asm-generic/audit_dir_write.h              |    4 
 include/asm-h8300/page.h                           |    7 
 include/asm-i386/Kbuild                            |    9 
 include/asm-ia64/Kbuild                            |   18 
 include/asm-ia64/numa.h                            |    6 
 include/asm-m32r/page.h                            |    3 
 include/asm-m32r/ptrace.h                          |   32 
 include/asm-m32r/sigcontext.h                      |   13 
 include/asm-m32r/signal.h                          |    1 
 include/asm-m32r/unistd.h                          |    4 
 include/asm-m32r/user.h                            |    1 
 include/asm-m68knommu/page.h                       |    7 
 include/asm-powerpc/Kbuild                         |   45 
 include/asm-powerpc/current.h                      |   12 
 include/asm-powerpc/ptrace.h                       |    4 
 include/asm-s390/Kbuild                            |   11 
 include/asm-s390/div64.h                           |   48 -
 include/asm-sh/page.h                              |    3 
 include/asm-sh/ptrace.h                            |    2 
 include/asm-sh64/page.h                            |    3 
 include/asm-sh64/shmparam.h                        |   16 
 include/asm-sh64/signal.h                          |    1 
 include/asm-sh64/user.h                            |    1 
 include/asm-sparc/Kbuild                           |   17 
 include/asm-sparc/page.h                           |    8 
 include/asm-sparc/unistd.h                         |    2 
 include/asm-sparc64/Kbuild                         |   24 
 include/asm-sparc64/futex.h                        |   18 
 include/asm-sparc64/page.h                         |    9 
 include/asm-sparc64/shmparam.h                     |    2 
 include/asm-sparc64/unistd.h                       |    2 
 include/asm-v850/page.h                            |    7 
 include/asm-v850/param.h                           |    4 
 include/asm-x86_64/Kbuild                          |   18 
 include/asm-x86_64/system.h                        |    5 
 include/linux/Kbuild                               |  400 +++++++-
 include/linux/byteorder/Kbuild                     |    9 
 include/linux/dvb/Kbuild                           |   11 
 include/linux/mmzone.h                             |   15 
 include/linux/netfilter/Kbuild                     |   47 
 include/linux/netfilter_arp/Kbuild                 |    5 
 include/linux/netfilter_bridge/Kbuild              |   21 
 include/linux/netfilter_ipv4.h                     |    2 
 include/linux/netfilter_ipv4/Kbuild                |   82 +
 include/linux/netfilter_ipv6/Kbuild                |   27 
 include/linux/nfsd/Kbuild                          |    9 
 include/linux/raid/Kbuild                          |    3 
 include/linux/scx200.h                             |    2 
 include/linux/serial_core.h                        |    1 
 include/linux/stddef.h                             |    2 
 include/linux/sunrpc/Kbuild                        |    2 
 include/linux/swap.h                               |    1 
 include/linux/sysctl.h                             |    1 
 include/linux/tc_act/Kbuild                        |    5 
 include/linux/tc_ematch/Kbuild                     |    5 
 include/linux/ufs_fs.h                             |    2 
 include/media/cx2341x.h                            |    2 
 include/mtd/Kbuild                                 |    8 
 include/rdma/Kbuild                                |    2 
 include/scsi/Kbuild                                |    4 
 include/sound/Kbuild                               |   12 
 include/video/Kbuild                               |    2 
 init/Kconfig                                       |    1 
 kernel/module.c                                    |    6 
 kernel/posix-cpu-timers.c                          |   27 
 kernel/sched.c                                     |   54 -
 kernel/softirq.c                                   |    2 
 kernel/sysctl.c                                    |   11 
 kernel/taskstats.c                                 |   15 
 lib/audit.c                                        |    2 
 mm/memory.c                                        |   41 
 mm/migrate.c                                       |    3 
 mm/mincore.c                                       |  177 +--
 mm/msync.c                                         |   68 -
 mm/page_alloc.c                                    |   25 
 mm/shmem.c                                         |    7 
 mm/slab.c                                          |    2 
 mm/truncate.c                                      |   34 
 mm/vmscan.c                                        |  125 +-
 mm/vmstat.c                                        |    2 
 net/bluetooth/cmtp/capi.c                          |   39 
 net/bluetooth/hci_sock.c                           |   11 
 net/bluetooth/rfcomm/tty.c                         |    3 
 net/bridge/br_ioctl.c                              |   11 
 net/bridge/netfilter/ebtables.c                    |   54 -
 net/core/dev.c                                     |   16 
 net/core/skbuff.c                                  |    1 
 net/core/sock.c                                    |    2 
 net/dccp/ipv6.c                                    |    2 
 net/decnet/af_decnet.c                             |    4 
 net/ieee80211/softmac/ieee80211softmac_io.c        |    2 
 net/ieee80211/softmac/ieee80211softmac_scan.c      |    2 
 net/ipv4/ipvs/ip_vs_core.c                         |   10 
 net/ipv4/netfilter.c                               |    9 
 net/ipv4/netfilter/arp_tables.c                    |   39 
 net/ipv4/netfilter/ip_conntrack_helper_h323.c      |    4 
 net/ipv4/netfilter/ip_nat_standalone.c             |   14 
 net/ipv4/netfilter/ip_tables.c                     |  116 +-
 net/ipv4/netfilter/iptable_mangle.c                |    3 
 net/ipv4/route.c                                   |    2 
 net/ipv4/tcp.c                                     |    4 
 net/ipv4/tcp_cubic.c                               |    6 
 net/ipv4/tcp_input.c                               |   18 
 net/ipv4/udp.c                                     |   19 
 net/ipv4/xfrm4_policy.c                            |    2 
 net/ipv6/ip6_flowlabel.c                           |    2 
 net/ipv6/ipv6_sockglue.c                           |    3 
 net/ipv6/netfilter/ip6_tables.c                    |   53 -
 net/ipv6/tcp_ipv6.c                                |    2 
 net/ipv6/udp.c                                     |    7 
 net/irda/irttp.c                                   |    4 
 net/netfilter/Kconfig                              |    6 
 net/sched/act_gact.c                               |    4 
 net/sched/act_police.c                             |   26 
 net/sched/cls_api.c                                |    4 
 net/sched/cls_basic.c                              |    2 
 net/sched/sch_api.c                                |   16 
 net/sched/sch_generic.c                            |   68 -
 net/sctp/input.c                                   |    3 
 net/sunrpc/svcsock.c                               |    2 
 security/seclvl.c                                  |    2 
 sound/core/control.c                               |    1 
 sound/core/hwdep.c                                 |    3 
 sound/core/info.c                                  |    5 
 sound/core/rtctimer.c                              |   17 
 sound/pci/au88x0/au88x0.c                          |    1 
 sound/pci/emu10k1/emu10k1_main.c                   |    4 
 sound/ppc/keywest.c                                |    3 
 sound/usb/usx2y/usbusx2yaudio.c                    |   18 
 sound/usb/usx2y/usx2yhwdeppcm.c                    |   17 
 332 files changed, 4573 insertions(+), 2435 deletions(-)

diff -r aafef975e518 -r 3e8752eb6d9c Documentation/dontdiff
--- a/Documentation/dontdiff    Tue Oct 02 09:52:15 2007 +0100
+++ b/Documentation/dontdiff    Wed Oct 03 10:00:44 2007 +0100
@@ -135,6 +135,7 @@ times.h*
 times.h*
 tkparse
 trix_boot.h
+utsrelease.h*
 version.h*
 vmlinux
 vmlinux-*
diff -r aafef975e518 -r 3e8752eb6d9c Documentation/sysctl/vm.txt
--- a/Documentation/sysctl/vm.txt       Tue Oct 02 09:52:15 2007 +0100
+++ b/Documentation/sysctl/vm.txt       Wed Oct 03 10:00:44 2007 +0100
@@ -29,6 +29,7 @@ Currently, these files are in /proc/sys/
 - drop-caches
 - zone_reclaim_mode
 - min_unmapped_ratio
+- min_slab_ratio
 - panic_on_oom
 
 ==============================================================
@@ -138,7 +139,6 @@ 1   = Zone reclaim on
 1      = Zone reclaim on
 2      = Zone reclaim writes dirty pages out
 4      = Zone reclaim swaps pages
-8      = Also do a global slab reclaim pass
 
 zone_reclaim_mode is set during bootup to 1 if it is determined that pages
 from remote zones will cause a measurable performance reduction. The
@@ -162,23 +162,36 @@ node unless explicitly overridden by mem
 node unless explicitly overridden by memory policies or cpuset
 configurations.
 
-It may be advisable to allow slab reclaim if the system makes heavy
-use of files and builds up large slab caches. However, the slab
-shrink operation is global, may take a long time and free slabs
-in all nodes of the system.
-
 =============================================================
 
 min_unmapped_ratio:
 
 This is available only on NUMA kernels.
 
-A percentage of the file backed pages in each zone.  Zone reclaim will only
+A percentage of the total pages in each zone.  Zone reclaim will only
 occur if more than this percentage of pages are file backed and unmapped.
 This is to insure that a minimal amount of local pages is still available for
 file I/O even if the node is overallocated.
 
 The default is 1 percent.
+
+=============================================================
+
+min_slab_ratio:
+
+This is available only on NUMA kernels.
+
+A percentage of the total pages in each zone.  On Zone reclaim
+(fallback from the local zone occurs) slabs will be reclaimed if more
+than this percentage of pages in a zone are reclaimable slab pages.
+This insures that the slab growth stays under control even in NUMA
+systems that rarely perform global reclaim.
+
+The default is 5 percent.
+
+Note that slab reclaim is triggered in a per zone / node fashion.
+The process of reclaiming slab memory is currently not node specific
+and may not be fast.
 
 =============================================================
 
diff -r aafef975e518 -r 3e8752eb6d9c Makefile
--- a/Makefile  Tue Oct 02 09:52:15 2007 +0100
+++ b/Makefile  Wed Oct 03 10:00:44 2007 +0100
@@ -1,7 +1,7 @@ VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 18
-EXTRAVERSION =
+EXTRAVERSION = .8
 NAME=Avast! A bilge rat!
 
 # *DOCUMENTATION*
@@ -894,6 +894,9 @@ export INSTALL_HDR_PATH
 
 PHONY += headers_install
 headers_install: include/linux/version.h
+       @if [ ! -r include/asm-$(ARCH)/Kbuild ]; then \
+         echo '*** Error: Headers not exportable for this architecture 
($(ARCH))'; \
+         exit 1 ; fi
        $(Q)unifdef -Ux /dev/null
        $(Q)rm -rf $(INSTALL_HDR_PATH)/include
        $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.headersinst obj=include
@@ -1076,13 +1079,17 @@ help:
        @echo  '  cscope          - Generate cscope index'
        @echo  '  kernelrelease   - Output the release version string'
        @echo  '  kernelversion   - Output the version stored in Makefile'
-       @echo  '  headers_install - Install sanitised kernel headers to 
INSTALL_HDR_PATH'
+       @if [ -r include/asm-$(ARCH)/Kbuild ]; then \
+        echo  '  headers_install - Install sanitised kernel headers to 
INSTALL_HDR_PATH'; \
+        fi
        @echo  '                    (default: $(INSTALL_HDR_PATH))'
        @echo  ''
        @echo  'Static analysers'
        @echo  '  checkstack      - Generate a list of stack hogs'
        @echo  '  namespacecheck  - Name space analysis on compiled kernel'
-       @echo  '  headers_check   - Sanity check on exported headers'
+       @if [ -r include/asm-$(ARCH)/Kbuild ]; then \
+        echo  '  headers_check   - Sanity check on exported headers'; \
+        fi
        @echo  ''
        @echo  'Kernel packaging:'
        @$(MAKE) $(build)=$(package-dir) help
diff -r aafef975e518 -r 3e8752eb6d9c arch/alpha/Kconfig
--- a/arch/alpha/Kconfig        Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/alpha/Kconfig        Wed Oct 03 10:00:44 2007 +0100
@@ -381,7 +381,7 @@ config ALPHA_EV56
 
 config ALPHA_EV56
        prompt "EV56 CPU (speed >= 333MHz)?"
-       depends on ALPHA_NORITAKE && ALPHA_PRIMO
+       depends on ALPHA_NORITAKE || ALPHA_PRIMO
 
 config ALPHA_EV56
        prompt "EV56 CPU (speed >= 400MHz)?"
diff -r aafef975e518 -r 3e8752eb6d9c arch/arm/kernel/calls.S
--- a/arch/arm/kernel/calls.S   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/arm/kernel/calls.S   Wed Oct 03 10:00:44 2007 +0100
@@ -331,6 +331,19 @@
                CALL(sys_mbind)
 /* 320 */      CALL(sys_get_mempolicy)
                CALL(sys_set_mempolicy)
+               CALL(sys_openat)
+               CALL(sys_mkdirat)
+               CALL(sys_mknodat)
+/* 325 */      CALL(sys_fchownat)
+               CALL(sys_futimesat)
+               CALL(sys_fstatat64)
+               CALL(sys_unlinkat)
+               CALL(sys_renameat)
+/* 330 */      CALL(sys_linkat)
+               CALL(sys_symlinkat)
+               CALL(sys_readlinkat)
+               CALL(sys_fchmodat)
+               CALL(sys_faccessat)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/Kconfig.cpu
--- a/arch/i386/Kconfig.cpu     Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/Kconfig.cpu     Wed Oct 03 10:00:44 2007 +0100
@@ -7,6 +7,7 @@ choice
 
 config M386
        bool "386"
+       depends on !UML
        ---help---
          This is the processor type of your CPU. This information is used for
          optimizing purposes. In order to compile a kernel that can run on
@@ -301,7 +302,7 @@ config X86_USE_PPRO_CHECKSUM
 
 config X86_USE_3DNOW
        bool
-       depends on MCYRIXIII || MK7 || MGEODE_LX
+       depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
        default y
 
 config X86_OOSTORE
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/kernel/alternative.c
--- a/arch/i386/kernel/alternative.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/kernel/alternative.c    Wed Oct 03 10:00:44 2007 +0100
@@ -344,6 +344,7 @@ void alternatives_smp_switch(int smp)
 
 void __init alternative_instructions(void)
 {
+       unsigned long flags;
        if (no_replacement) {
                printk(KERN_INFO "(SMP-)alternatives turned off\n");
                free_init_pages("SMP alternatives",
@@ -351,6 +352,8 @@ void __init alternative_instructions(voi
                                (unsigned long)__smp_alt_end);
                return;
        }
+
+       local_irq_save(flags);
        apply_alternatives(__alt_instructions, __alt_instructions_end);
 
        /* switch to patch-once-at-boottime-only mode and free the
@@ -386,4 +389,5 @@ void __init alternative_instructions(voi
                alternatives_smp_switch(0);
        }
 #endif
-}
+       local_irq_restore(flags);
+}
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c       Tue Oct 02 09:52:15 
2007 +0100
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c       Wed Oct 03 10:00:44 
2007 +0100
@@ -560,7 +560,6 @@ static struct cpufreq_driver acpi_cpufre
        .name   = "acpi-cpufreq",
        .owner  = THIS_MODULE,
        .attr   = acpi_cpufreq_attr,
-       .flags  = CPUFREQ_STICKY,
 };
 
 
@@ -571,7 +570,7 @@ acpi_cpufreq_init (void)
 
        acpi_cpufreq_early_init_acpi();
 
-       return cpufreq_register_driver(&acpi_cpufreq_driver);
+       return cpufreq_register_driver(&acpi_cpufreq_driver);
 }
 
 
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/kernel/microcode.c
--- a/arch/i386/kernel/microcode.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/kernel/microcode.c      Wed Oct 03 10:00:44 2007 +0100
@@ -250,14 +250,14 @@ static int find_matching_ucodes (void)
                }
 
                total_size = get_totalsize(&mc_header);
-               if ((cursor + total_size > user_buffer_size) || (total_size < 
DEFAULT_UCODE_TOTALSIZE)) {
+               if (cursor + total_size > user_buffer_size) {
                        printk(KERN_ERR "microcode: error! Bad data in 
microcode data file\n");
                        error = -EINVAL;
                        goto out;
                }
 
                data_size = get_datasize(&mc_header);
-               if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < 
DEFAULT_UCODE_DATASIZE)) {
+               if (data_size + MC_HEADER_SIZE > total_size) {
                        printk(KERN_ERR "microcode: error! Bad data in 
microcode data file\n");
                        error = -EINVAL;
                        goto out;
@@ -460,11 +460,6 @@ static ssize_t microcode_write (struct f
 {
        ssize_t ret;
 
-       if (len < DEFAULT_UCODE_TOTALSIZE) {
-               printk(KERN_ERR "microcode: not enough data\n"); 
-               return -EINVAL;
-       }
-
        if ((len >> PAGE_SHIFT) > num_physpages) {
                printk(KERN_ERR "microcode: too much data (max %ld pages)\n", 
num_physpages);
                return -EINVAL;
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/kernel/smpboot.c        Wed Oct 03 10:00:44 2007 +0100
@@ -642,9 +642,13 @@ static void map_cpu_to_logical_apicid(vo
 {
        int cpu = smp_processor_id();
        int apicid = logical_smp_processor_id();
+       int node = apicid_to_node(apicid);
+
+       if (!node_online(node))
+               node = first_online_node;
 
        cpu_2_logical_apicid[cpu] = apicid;
-       map_cpu_to_node(cpu, apicid_to_node(apicid));
+       map_cpu_to_node(cpu, node);
 }
 
 static void unmap_cpu_to_logical_apicid(int cpu)
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/mm/boot_ioremap.c
--- a/arch/i386/mm/boot_ioremap.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/mm/boot_ioremap.c       Wed Oct 03 10:00:44 2007 +0100
@@ -29,8 +29,11 @@
  */
 
 #define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
-#define boot_pte_index(address) \
-            (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
+
+static unsigned long boot_pte_index(unsigned long vaddr)
+{
+       return __pa(vaddr) >> PAGE_SHIFT;
+}
 
 static inline boot_pte_t* boot_vaddr_to_pte(void *address)
 {
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/pci/irq.c       Wed Oct 03 10:00:44 2007 +0100
@@ -255,13 +255,13 @@ static int pirq_via_set(struct pci_dev *
  */
 static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int 
pirq)
 {
-       static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+       static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
        return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
 }
 
 static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int 
pirq, int irq)
 {
-       static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+       static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
        write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
        return 1;
 }
diff -r aafef975e518 -r 3e8752eb6d9c arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ia64/kernel/acpi.c   Wed Oct 03 10:00:44 2007 +0100
@@ -777,16 +777,19 @@ int acpi_map_cpu2node(acpi_handle handle
 {
 #ifdef CONFIG_ACPI_NUMA
        int pxm_id;
+       int nid;
 
        pxm_id = acpi_get_pxm(handle);
-
        /*
-        * Assuming that the container driver would have set the proximity
-        * domain and would have initialized pxm_to_node(pxm_id) && pxm_flag
+        * We don't have cpu-only-node hotadd. But if the system equips
+        * SRAT table, pxm is already found and node is ready.
+        * So, just pxm_to_nid(pxm) is OK.
+        * This code here is for the system which doesn't have full SRAT
+        * table for possible cpus.
         */
-       node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_node(pxm_id);
-
+       nid = acpi_map_pxm_to_node(pxm_id);
        node_cpuid[cpu].phys_id = physid;
+       node_cpuid[cpu].nid = nid;
 #endif
        return (0);
 }
diff -r aafef975e518 -r 3e8752eb6d9c arch/ia64/kernel/numa.c
--- a/arch/ia64/kernel/numa.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ia64/kernel/numa.c   Wed Oct 03 10:00:44 2007 +0100
@@ -29,6 +29,36 @@ EXPORT_SYMBOL(cpu_to_node_map);
 
 cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
 
+void __cpuinit map_cpu_to_node(int cpu, int nid)
+{
+       int oldnid;
+       if (nid < 0) { /* just initialize by zero */
+               cpu_to_node_map[cpu] = 0;
+               return;
+       }
+       /* sanity check first */
+       oldnid = cpu_to_node_map[cpu];
+       if (cpu_isset(cpu, node_to_cpu_mask[oldnid])) {
+               return; /* nothing to do */
+       }
+       /* we don't have cpu-driven node hot add yet...
+          In usual case, node is created from SRAT at boot time. */
+       if (!node_online(nid))
+               nid = first_online_node;
+       cpu_to_node_map[cpu] = nid;
+       cpu_set(cpu, node_to_cpu_mask[nid]);
+       return;
+}
+
+void __cpuinit unmap_cpu_from_node(int cpu, int nid)
+{
+       WARN_ON(!cpu_isset(cpu, node_to_cpu_mask[nid]));
+       WARN_ON(cpu_to_node_map[cpu] != nid);
+       cpu_to_node_map[cpu] = 0;
+       cpu_clear(cpu, node_to_cpu_mask[nid]);
+}
+
+
 /**
  * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
  *
@@ -49,8 +79,6 @@ void __init build_cpu_to_node_map(void)
                                node = node_cpuid[i].nid;
                                break;
                        }
-               cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
-               if (node >= 0)
-                       cpu_set(cpu, node_to_cpu_mask[node]);
+               map_cpu_to_node(cpu, node);
        }
 }
diff -r aafef975e518 -r 3e8752eb6d9c arch/ia64/kernel/topology.c
--- a/arch/ia64/kernel/topology.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ia64/kernel/topology.c       Wed Oct 03 10:00:44 2007 +0100
@@ -36,6 +36,7 @@ int arch_register_cpu(int num)
         */
        if (!can_cpei_retarget() && is_cpu_cpei_target(num))
                sysfs_cpus[num].cpu.no_control = 1;
+       map_cpu_to_node(num, node_cpuid[num].nid);
 #endif
 
        return register_cpu(&sysfs_cpus[num].cpu, num);
@@ -45,7 +46,8 @@ int arch_register_cpu(int num)
 
 void arch_unregister_cpu(int num)
 {
-       return unregister_cpu(&sysfs_cpus[num].cpu);
+       unregister_cpu(&sysfs_cpus[num].cpu);
+       unmap_cpu_from_node(num, cpu_to_node(num));
 }
 EXPORT_SYMBOL(arch_register_cpu);
 EXPORT_SYMBOL(arch_unregister_cpu);
diff -r aafef975e518 -r 3e8752eb6d9c arch/ia64/sn/kernel/bte.c
--- a/arch/ia64/sn/kernel/bte.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ia64/sn/kernel/bte.c Wed Oct 03 10:00:44 2007 +0100
@@ -382,14 +382,13 @@ bte_result_t bte_unaligned_copy(u64 src,
                 * bcopy to the destination.
                 */
 
-               /* Add the leader from source */
-               headBteLen = len + (src & L1_CACHE_MASK);
-               /* Add the trailing bytes from footer. */
-               headBteLen += L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK);
-               headBteSource = src & ~L1_CACHE_MASK;
                headBcopySrcOffset = src & L1_CACHE_MASK;
                headBcopyDest = dest;
                headBcopyLen = len;
+
+               headBteSource = src - headBcopySrcOffset;
+               /* Add the leading and trailing bytes from source */
+               headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset);
        }
 
        if (headBcopyLen > 0) {
diff -r aafef975e518 -r 3e8752eb6d9c arch/m32r/kernel/entry.S
--- a/arch/m32r/kernel/entry.S  Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/m32r/kernel/entry.S  Wed Oct 03 10:00:44 2007 +0100
@@ -23,35 +23,35 @@
  *     updated in fork.c:copy_thread, signal.c:do_signal,
  *     ptrace.c and ptrace.h
  *
- * M32Rx/M32R2                         M32R
- *       @(sp)      - r4               ditto
- *       @(0x04,sp) - r5               ditto
- *       @(0x08,sp) - r6               ditto
- *       @(0x0c,sp) - *pt_regs         ditto
- *       @(0x10,sp) - r0               ditto
- *       @(0x14,sp) - r1               ditto
- *       @(0x18,sp) - r2               ditto
- *       @(0x1c,sp) - r3               ditto
- *       @(0x20,sp) - r7               ditto
- *       @(0x24,sp) - r8               ditto
- *       @(0x28,sp) - r9               ditto
- *       @(0x2c,sp) - r10              ditto
- *       @(0x30,sp) - r11              ditto
- *       @(0x34,sp) - r12              ditto
- *       @(0x38,sp) - syscall_nr       ditto
- *       @(0x3c,sp) - acc0h            @(0x3c,sp) - acch
- *       @(0x40,sp) - acc0l            @(0x40,sp) - accl
- *       @(0x44,sp) - acc1h            @(0x44,sp) - dummy_acc1h
- *       @(0x48,sp) - acc1l            @(0x48,sp) - dummy_acc1l
- *       @(0x4c,sp) - psw              ditto
- *       @(0x50,sp) - bpc              ditto
- *       @(0x54,sp) - bbpsw            ditto
- *       @(0x58,sp) - bbpc             ditto
- *       @(0x5c,sp) - spu (cr3)                ditto
- *       @(0x60,sp) - fp (r13)         ditto
- *       @(0x64,sp) - lr (r14)         ditto
- *       @(0x68,sp) - spi (cr2)                ditto
- *       @(0x6c,sp) - orig_r0          ditto
+ * M32R/M32Rx/M32R2
+ *       @(sp)      - r4
+ *       @(0x04,sp) - r5
+ *       @(0x08,sp) - r6
+ *       @(0x0c,sp) - *pt_regs
+ *       @(0x10,sp) - r0
+ *       @(0x14,sp) - r1
+ *       @(0x18,sp) - r2
+ *       @(0x1c,sp) - r3
+ *       @(0x20,sp) - r7
+ *       @(0x24,sp) - r8
+ *       @(0x28,sp) - r9
+ *       @(0x2c,sp) - r10
+ *       @(0x30,sp) - r11
+ *       @(0x34,sp) - r12
+ *       @(0x38,sp) - syscall_nr
+ *       @(0x3c,sp) - acc0h
+ *       @(0x40,sp) - acc0l
+ *       @(0x44,sp) - acc1h            ; ISA_DSP_LEVEL2 only
+ *       @(0x48,sp) - acc1l            ; ISA_DSP_LEVEL2 only
+ *       @(0x4c,sp) - psw
+ *       @(0x50,sp) - bpc
+ *       @(0x54,sp) - bbpsw
+ *       @(0x58,sp) - bbpc
+ *       @(0x5c,sp) - spu (cr3)
+ *       @(0x60,sp) - fp (r13)
+ *       @(0x64,sp) - lr (r14)
+ *       @(0x68,sp) - spi (cr2)
+ *       @(0x6c,sp) - orig_r0
  */
 
 #include <linux/linkage.h>
@@ -95,17 +95,10 @@
 #define R11(reg)               @(0x30,reg)
 #define R12(reg)               @(0x34,reg)
 #define SYSCALL_NR(reg)                @(0x38,reg)
-#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
 #define ACC0H(reg)             @(0x3C,reg)
 #define ACC0L(reg)             @(0x40,reg)
 #define ACC1H(reg)             @(0x44,reg)
 #define ACC1L(reg)             @(0x48,reg)
-#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
-#define ACCH(reg)              @(0x3C,reg)
-#define ACCL(reg)              @(0x40,reg)
-#else
-#error unknown isa configuration
-#endif
 #define PSW(reg)               @(0x4C,reg)
 #define BPC(reg)               @(0x50,reg)
 #define BBPSW(reg)             @(0x54,reg)
diff -r aafef975e518 -r 3e8752eb6d9c arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig      Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/powerpc/Kconfig      Wed Oct 03 10:00:44 2007 +0100
@@ -740,6 +740,15 @@ config ARCH_MEMORY_PROBE
        def_bool y
        depends on MEMORY_HOTPLUG
 
+# Some NUMA nodes have memory ranges that span
+# other nodes.  Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node.  See memmap_init_zone()
+# for details.
+config NODES_SPAN_OTHER_NODES
+       def_bool y
+       depends on NEED_MULTIPLE_NODES
+
 config PPC_64K_PAGES
        bool "64k page size"
        depends on PPC64
diff -r aafef975e518 -r 3e8752eb6d9c arch/powerpc/configs/pseries_defconfig
--- a/arch/powerpc/configs/pseries_defconfig    Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/powerpc/configs/pseries_defconfig    Wed Oct 03 10:00:44 2007 +0100
@@ -184,6 +184,7 @@ CONFIG_MIGRATION=y
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
diff -r aafef975e518 -r 3e8752eb6d9c arch/powerpc/kernel/traps.c
--- a/arch/powerpc/kernel/traps.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/powerpc/kernel/traps.c       Wed Oct 03 10:00:44 2007 +0100
@@ -818,7 +818,7 @@ void __kprobes program_check_exception(s
 
 void alignment_exception(struct pt_regs *regs)
 {
-       int fixed = 0;
+       int sig, code, fixed = 0;
 
        /* we don't implement logging of alignment exceptions */
        if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
@@ -832,14 +832,16 @@ void alignment_exception(struct pt_regs 
 
        /* Operand address was bad */
        if (fixed == -EFAULT) {
-               if (user_mode(regs))
-                       _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-               else
-                       /* Search exception table */
-                       bad_page_fault(regs, regs->dar, SIGSEGV);
-               return;
-       }
-       _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+               sig = SIGSEGV;
+               code = SEGV_ACCERR;
+       } else {
+               sig = SIGBUS;
+               code = BUS_ADRALN;
+       }
+       if (user_mode(regs))
+               _exception(sig, regs, code, regs->dar);
+       else
+               bad_page_fault(regs, regs->dar, sig);
 }
 
 void StackOverflow(struct pt_regs *regs)
diff -r aafef975e518 -r 3e8752eb6d9c arch/ppc/kernel/traps.c
--- a/arch/ppc/kernel/traps.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ppc/kernel/traps.c   Wed Oct 03 10:00:44 2007 +0100
@@ -708,7 +708,7 @@ void single_step_exception(struct pt_reg
 
 void alignment_exception(struct pt_regs *regs)
 {
-       int fixed;
+       int sig, code, fixed = 0;
 
        fixed = fix_alignment(regs);
        if (fixed == 1) {
@@ -717,14 +717,16 @@ void alignment_exception(struct pt_regs 
                return;
        }
        if (fixed == -EFAULT) {
-               /* fixed == -EFAULT means the operand address was bad */
-               if (user_mode(regs))
-                       _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-               else
-                       bad_page_fault(regs, regs->dar, SIGSEGV);
-               return;
-       }
-       _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+               sig = SIGSEGV;
+               code = SEGV_ACCERR;
+       } else {
+               sig = SIGBUS;
+               code = BUS_ADRALN;
+       }
+       if (user_mode(regs))
+               _exception(sig, regs, code, regs->dar);
+       else
+               bad_page_fault(regs, regs->dar, sig);
 }
 
 void StackOverflow(struct pt_regs *regs)
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/Kconfig
--- a/arch/s390/Kconfig Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/s390/Kconfig Wed Oct 03 10:00:44 2007 +0100
@@ -50,6 +50,10 @@ config 64BIT
        help
          Select this option if you have a 64 bit IBM zSeries machine
          and want to use the 64 bit addressing mode.
+
+config 32BIT
+       bool
+       default y if !64BIT
 
 config SMP
        bool "Symmetric multi-processing support"
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/lib/Makefile
--- a/arch/s390/lib/Makefile    Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/s390/lib/Makefile    Wed Oct 03 10:00:44 2007 +0100
@@ -7,3 +7,4 @@ lib-y += delay.o string.o
 lib-y += delay.o string.o
 lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
 lib-$(CONFIG_SMP) += spinlock.o
+lib-$(CONFIG_32BIT) += div64.o
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/lib/div64.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/s390/lib/div64.c     Wed Oct 03 10:00:44 2007 +0100
@@ -0,0 +1,151 @@
+/*
+ *  arch/s390/lib/div64.c
+ *
+ *  __div64_32 implementation for 31 bit.
+ *
+ *    Copyright (C) IBM Corp. 2006
+ *    Author(s): Martin Schwidefsky (schwidefsky@xxxxxxxxxx),
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+#ifdef CONFIG_MARCH_G5
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 31 bit integer using signed 64/32 bit division.
+ */
+static uint32_t __div64_31(uint64_t *n, uint32_t base)
+{
+       register uint32_t reg2 asm("2");
+       register uint32_t reg3 asm("3");
+       uint32_t *words = (uint32_t *) n;
+       uint32_t tmp;
+
+       /* Special case base==1, remainder = 0, quotient = n */
+       if (base == 1)
+               return 0;
+       /*
+        * Special case base==0 will cause a fixed point divide exception
+        * on the dr instruction and may not happen anyway. For the
+        * following calculation we can assume base > 1. The first
+        * signed 64 / 32 bit division with an upper half of 0 will
+        * give the correct upper half of the 64 bit quotient.
+        */
+       reg2 = 0UL;
+       reg3 = words[0];
+       asm volatile(
+               "       dr      %0,%2\n"
+               : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+       words[0] = reg3;
+       reg3 = words[1];
+       /*
+        * To get the lower half of the 64 bit quotient and the 32 bit
+        * remainder we have to use a little trick. Since we only have
+        * a signed division the quotient can get too big. To avoid this
+        * the 64 bit dividend is halved, then the signed division will
+        * work. Afterwards the quotient and the remainder are doubled.
+        * If the last bit of the dividend has been one the remainder
+        * is increased by one then checked against the base. If the
+        * remainder has overflown subtract base and increase the
+        * quotient. Simple, no ?
+        */
+       asm volatile(
+               "       nr      %2,%1\n"
+               "       srdl    %0,1\n"
+               "       dr      %0,%3\n"
+               "       alr     %0,%0\n"
+               "       alr     %1,%1\n"
+               "       alr     %0,%2\n"
+               "       clr     %0,%3\n"
+               "       jl      0f\n"
+               "       slr     %0,%3\n"
+               "       alr     %1,%2\n"
+               "0:\n"
+               : "+d" (reg2), "+d" (reg3), "=d" (tmp)
+               : "d" (base), "2" (1UL) : "cc" );
+       words[1] = reg3;
+       return reg2;
+}
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 32 bit integer using the unsigned 64/31 bit division.
+ */
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+       uint32_t r;
+
+       /*
+        * If the most significant bit of base is set, divide n by
+        * (base/2). That allows to use 64/31 bit division and gives a
+        * good approximation of the result: n = (base/2)*q + r. The
+        * result needs to be corrected with two simple transformations.
+        * If base is already < 2^31-1 __div64_31 can be used directly.
+        */
+       r = __div64_31(n, ((signed) base < 0) ? (base/2) : base);
+       if ((signed) base < 0) {
+               uint64_t q = *n;
+               /*
+                * First transformation:
+                * n = (base/2)*q + r
+                *   = ((base/2)*2)*(q/2) + ((q&1) ? (base/2) : 0) + r
+                * Since r < (base/2), r + (base/2) < base.
+                * With q1 = (q/2) and r1 = r + ((q&1) ? (base/2) : 0)
+                * n = ((base/2)*2)*q1 + r1 with r1 < base.
+                */
+               if (q & 1)
+                       r += base/2;
+               q >>= 1;
+               /*
+                * Second transformation. ((base/2)*2) could have lost the
+                * last bit.
+                * n = ((base/2)*2)*q1 + r1
+                *   = base*q1 - ((base&1) ? q1 : 0) + r1
+                */
+               if (base & 1) {
+                       int64_t rx = r - q;
+                       /*
+                        * base is >= 2^31. The worst case for the while
+                        * loop is n=2^64-1 base=2^31+1. That gives a
+                        * maximum for q=(2^64-1)/2^31 = 0x1ffffffff. Since
+                        * base >= 2^31 the loop is finished after a maximum
+                        * of three iterations.
+                        */
+                       while (rx < 0) {
+                               rx += base;
+                               q--;
+                       }
+                       r = rx;
+               }
+               *n = q;
+       }
+       return r;
+}
+
+#else /* MARCH_G5 */
+
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+       register uint32_t reg2 asm("2");
+       register uint32_t reg3 asm("3");
+       uint32_t *words = (uint32_t *) n;
+
+       reg2 = 0UL;
+       reg3 = words[0];
+       asm volatile(
+               "       dlr     %0,%2\n"
+               : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+       words[0] = reg3;
+       reg3 = words[1];
+       asm volatile(
+               "       dlr     %0,%2\n"
+               : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+       words[1] = reg3;
+       return reg2;
+}
+
+#endif /* MARCH_G5 */
+
+EXPORT_SYMBOL(__div64_32);
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/lib/uaccess.S
--- a/arch/s390/lib/uaccess.S   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/s390/lib/uaccess.S   Wed Oct 03 10:00:44 2007 +0100
@@ -40,7 +40,17 @@ 4:   lhi     %r0,-4096
        # move with the reduced length which is < 256
 5:     mvcp    0(%r5,%r2),0(%r4),%r0
        slr     %r3,%r5
-6:     lr      %r2,%r3
+       alr     %r2,%r5
+6:     lr      %r5,%r3         # copy remaining size
+       ahi     %r5,-1          # subtract 1 for xc loop
+       bras    %r4,8f
+       xc      0(1,%r2),0(%r2)
+7:     xc      0(256,%r2),0(%r2)
+       la      %r2,256(%r2)
+8:     ahi     %r5,-256
+       jnm     7b
+       ex      %r5,0(%r4)
+9:     lr      %r2,%r3
        br      %r14
         .section __ex_table,"a"
        .long   0b,4b
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/lib/uaccess64.S
--- a/arch/s390/lib/uaccess64.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/s390/lib/uaccess64.S Wed Oct 03 10:00:44 2007 +0100
@@ -40,7 +40,17 @@ 4:   lghi    %r0,-4096
        # move with the reduced length which is < 256
 5:     mvcp    0(%r5,%r2),0(%r4),%r0
        slgr    %r3,%r5
-6:     lgr     %r2,%r3
+       algr    %r2,%r5
+6:     lgr     %r5,%r3         # copy remaining size
+       aghi    %r5,-1          # subtract 1 for xc loop
+       bras    %r4,8f
+       xc      0(1,%r2),0(%r2)
+7:     xc      0(256,%r2),0(%r2)
+       la      %r2,256(%r2)
+8:     aghi    %r5,-256
+       jnm     7b
+       ex      %r5,0(%r4)
+9:     lgr     %r2,%r3
        br      %r14
         .section __ex_table,"a"
        .quad   0b,4b
diff -r aafef975e518 -r 3e8752eb6d9c arch/sh/kernel/process.c
--- a/arch/sh/kernel/process.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sh/kernel/process.c  Wed Oct 03 10:00:44 2007 +0100
@@ -26,6 +26,7 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/elf.h>
+#include <asm/ubc.h>
 
 static int hlt_counter=0;
 
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc/kernel/entry.S
--- a/arch/sparc/kernel/entry.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc/kernel/entry.S Wed Oct 03 10:00:44 2007 +0100
@@ -32,12 +32,11 @@
 #include <asm/mxcc.h>
 #include <asm/thread_info.h>
 #include <asm/param.h>
+#include <asm/unistd.h>
 
 #include <asm/asmmacro.h>
 
 #define curptr      g6
-
-#define NR_SYSCALLS 300      /* Each OS is different... */
 
 /* These are just handy. */
 #define _SV    save    %sp, -STACKFRAME_SZ, %sp
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/central.c
--- a/arch/sparc64/kernel/central.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/central.c     Wed Oct 03 10:00:44 2007 +0100
@@ -125,6 +125,10 @@ static void probe_other_fhcs(void)
                struct linux_fhc *fhc;
                int board;
                u32 tmp;
+
+               if (dp->parent &&
+                   dp->parent->parent != NULL)
+                       continue;
 
                fhc = (struct linux_fhc *)
                        central_alloc_bootmem(sizeof(struct linux_fhc));
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/entry.S
--- a/arch/sparc64/kernel/entry.S       Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/entry.S       Wed Oct 03 10:00:44 2007 +0100
@@ -22,10 +22,9 @@
 #include <asm/auxio.h>
 #include <asm/sfafsr.h>
 #include <asm/pil.h>
+#include <asm/unistd.h>
 
 #define curptr      g6
-
-#define NR_SYSCALLS 300      /* Each OS is different... */
 
        .text
        .align          32
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/of_device.c
--- a/arch/sparc64/kernel/of_device.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/of_device.c   Wed Oct 03 10:00:44 2007 +0100
@@ -398,16 +398,22 @@ static void of_bus_sbus_count_cells(stru
                *sizec = 1;
 }
 
-static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int 
pna)
-{
-       return of_bus_default_map(addr, range, na, ns, pna);
-}
-
-static unsigned int of_bus_sbus_get_flags(u32 *addr)
-{
-       return IORESOURCE_MEM;
-}
-
+/*
+ * FHC/Central bus specific translator.
+ *
+ * This is just needed to hard-code the address and size cell
+ * counts.  'fhc' and 'central' nodes lack the #address-cells and
+ * #size-cells properties, and if you walk to the root on such
+ * Enterprise boxes all you'll get is a #size-cells of 2 which is
+ * not what we want to use.
+ */
+static int of_bus_fhc_match(struct device_node *np)
+{
+       return !strcmp(np->name, "fhc") ||
+               !strcmp(np->name, "central");
+}
+
+#define of_bus_fhc_count_cells of_bus_sbus_count_cells
 
 /*
  * Array of bus specific translators
@@ -429,8 +435,17 @@ static struct of_bus of_busses[] = {
                .addr_prop_name = "reg",
                .match = of_bus_sbus_match,
                .count_cells = of_bus_sbus_count_cells,
-               .map = of_bus_sbus_map,
-               .get_flags = of_bus_sbus_get_flags,
+               .map = of_bus_default_map,
+               .get_flags = of_bus_default_get_flags,
+       },
+       /* FHC */
+       {
+               .name = "fhc",
+               .addr_prop_name = "reg",
+               .match = of_bus_fhc_match,
+               .count_cells = of_bus_fhc_count_cells,
+               .map = of_bus_default_map,
+               .get_flags = of_bus_default_get_flags,
        },
        /* Default */
        {
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/pci_common.c
--- a/arch/sparc64/kernel/pci_common.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/pci_common.c  Wed Oct 03 10:00:44 2007 +0100
@@ -328,19 +328,6 @@ __init get_device_resource(struct linux_
        };
 
        return res;
-}
-
-static int __init pdev_resource_collisions_expected(struct pci_dev *pdev)
-{
-       if (pdev->vendor != PCI_VENDOR_ID_SUN)
-               return 0;
-
-       if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS ||
-           pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 ||
-           pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
-               return 1;
-
-       return 0;
 }
 
 static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
@@ -400,19 +387,23 @@ static void __init pdev_record_assignmen
                pbm->parent->resource_adjust(pdev, res, root);
 
                if (request_resource(root, res) < 0) {
+                       int rnum;
+
                        /* OK, there is some conflict.  But this is fine
                         * since we'll reassign it in the fixup pass.
                         *
-                        * We notify the user that OBP made an error if it
-                        * is a case we don't expect.
+                        * Do not print the warning for ROM resources
+                        * as such a conflict is quite common and
+                        * harmless as the ROM bar is disabled.
                         */
-                       if (!pdev_resource_collisions_expected(pdev)) {
-                               printk(KERN_ERR "PCI: Address space collision 
on region %ld "
+                       rnum = (res - &pdev->resource[0]);
+                       if (rnum != PCI_ROM_RESOURCE)
+                               printk(KERN_ERR "PCI: Resource collision, "
+                                      "region %d "
                                       "[%016lx:%016lx] of device %s\n",
-                                      (res - &pdev->resource[0]),
+                                      rnum,
                                       res->start, res->end,
                                       pci_name(pdev));
-                       }
                }
        }
 }
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/pci_iommu.c
--- a/arch/sparc64/kernel/pci_iommu.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/pci_iommu.c   Wed Oct 03 10:00:44 2007 +0100
@@ -281,7 +281,7 @@ static void pci_4u_free_consistent(struc
 
        spin_lock_irqsave(&iommu->lock, flags);
 
-       free_npages(iommu, dvma, npages);
+       free_npages(iommu, dvma - iommu->page_table_map_base, npages);
 
        spin_unlock_irqrestore(&iommu->lock, flags);
 
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/pci_sabre.c
--- a/arch/sparc64/kernel/pci_sabre.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/pci_sabre.c   Wed Oct 03 10:00:44 2007 +0100
@@ -1196,7 +1196,7 @@ static void pbm_register_toplevel_resour
                                            &pbm->mem_space);
 }
 
-static void sabre_pbm_init(struct pci_controller_info *p, struct device_node 
*dp, u32 dma_begin)
+static void sabre_pbm_init(struct pci_controller_info *p, struct device_node 
*dp, u32 dma_start, u32 dma_end)
 {
        struct pci_pbm_info *pbm;
        struct device_node *node;
@@ -1261,6 +1261,8 @@ static void sabre_pbm_init(struct pci_co
                node = node->sibling;
        }
        if (simbas_found == 0) {
+               struct resource *rp;
+
                /* No APBs underneath, probably this is a hummingbird
                 * system.
                 */
@@ -1302,8 +1304,10 @@ static void sabre_pbm_init(struct pci_co
                pbm->io_space.end   = pbm->io_space.start + (1UL << 24) - 1UL;
                pbm->io_space.flags = IORESOURCE_IO;
 
-               pbm->mem_space.start = p->pbm_A.controller_regs + 
SABRE_MEMSPACE;
-               pbm->mem_space.end   = pbm->mem_space.start + (unsigned 
long)dma_begin - 1UL;
+               pbm->mem_space.start =
+                       (p->pbm_A.controller_regs + SABRE_MEMSPACE);
+               pbm->mem_space.end =
+                       (pbm->mem_space.start + ((1UL << 32UL) - 1UL));
                pbm->mem_space.flags = IORESOURCE_MEM;
 
                if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
@@ -1314,6 +1318,17 @@ static void sabre_pbm_init(struct pci_co
                        prom_printf("Cannot register Hummingbird's MEM 
space.\n");
                        prom_halt();
                }
+
+               rp = kmalloc(sizeof(*rp), GFP_KERNEL);
+               if (!rp) {
+                       prom_printf("Cannot allocate IOMMU resource.\n");
+                       prom_halt();
+               }
+               rp->name = "IOMMU";
+               rp->start = pbm->mem_space.start + (unsigned long) dma_start;
+               rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL;
+               rp->flags = IORESOURCE_BUSY;
+               request_resource(&pbm->mem_space, rp);
 
                pci_register_legacy_regions(&pbm->io_space,
                                            &pbm->mem_space);
@@ -1450,5 +1465,5 @@ void sabre_init(struct device_node *dp, 
        /*
         * Look for APB underneath.
         */
-       sabre_pbm_init(p, dp, vdma[0]);
-}
+       sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]);
+}
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/prom.c
--- a/arch/sparc64/kernel/prom.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/prom.c        Wed Oct 03 10:00:44 2007 +0100
@@ -1080,23 +1080,22 @@ static void sun4v_vdev_irq_trans_init(st
 
 static void irq_trans_init(struct device_node *dp)
 {
+#ifdef CONFIG_PCI
        const char *model;
-#ifdef CONFIG_PCI
        int i;
 #endif
 
+#ifdef CONFIG_PCI
        model = of_get_property(dp, "model", NULL);
        if (!model)
                model = of_get_property(dp, "compatible", NULL);
-       if (!model)
-               return;
-
-#ifdef CONFIG_PCI
-       for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
-               struct irq_trans *t = &pci_irq_trans_table[i];
-
-               if (!strcmp(model, t->name))
-                       return t->init(dp);
+       if (model) {
+               for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
+                       struct irq_trans *t = &pci_irq_trans_table[i];
+
+                       if (!strcmp(model, t->name))
+                               return t->init(dp);
+               }
        }
 #endif
 #ifdef CONFIG_SBUS
@@ -1104,8 +1103,9 @@ static void irq_trans_init(struct device
            !strcmp(dp->name, "sbi"))
                return sbus_irq_trans_init(dp);
 #endif
-       if (!strcmp(dp->name, "central"))
-               return central_irq_trans_init(dp->child);
+       if (!strcmp(dp->name, "fhc") &&
+           !strcmp(dp->parent->name, "central"))
+               return central_irq_trans_init(dp);
        if (!strcmp(dp->name, "virtual-devices"))
                return sun4v_vdev_irq_trans_init(dp);
 }
@@ -1517,7 +1517,7 @@ static char * __init get_one_property(ph
        return buf;
 }
 
-static struct device_node * __init create_node(phandle node)
+static struct device_node * __init create_node(phandle node, struct 
device_node *parent)
 {
        struct device_node *dp;
 
@@ -1526,6 +1526,7 @@ static struct device_node * __init creat
 
        dp = prom_early_alloc(sizeof(*dp));
        dp->unique_id = unique_id++;
+       dp->parent = parent;
 
        kref_init(&dp->kref);
 
@@ -1544,12 +1545,11 @@ static struct device_node * __init build
 {
        struct device_node *dp;
 
-       dp = create_node(node);
+       dp = create_node(node, parent);
        if (dp) {
                *(*nextp) = dp;
                *nextp = &dp->allnext;
 
-               dp->parent = parent;
                dp->path_component_name = build_path_component(dp);
                dp->full_name = build_full_name(dp);
 
@@ -1565,7 +1565,7 @@ void __init prom_build_devicetree(void)
 {
        struct device_node **nextp;
 
-       allnodes = create_node(prom_root_node);
+       allnodes = create_node(prom_root_node, NULL);
        allnodes->path_component_name = "";
        allnodes->full_name = "/";
 
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/time.c        Wed Oct 03 10:00:44 2007 +0100
@@ -983,7 +983,7 @@ static struct time_interpolator sparc64_
 };
 
 /* The quotient formula is taken from the IA64 port. */
-#define SPARC64_NSEC_PER_CYC_SHIFT     30UL
+#define SPARC64_NSEC_PER_CYC_SHIFT     10UL
 void __init time_init(void)
 {
        unsigned long clock = sparc64_init_timers();
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/mm/init.c
--- a/arch/sparc64/mm/init.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/mm/init.c    Wed Oct 03 10:00:44 2007 +0100
@@ -920,8 +920,7 @@ static unsigned long __init bootmem_init
        if (sparc_ramdisk_image || sparc_ramdisk_image64) {
                unsigned long ramdisk_image = sparc_ramdisk_image ?
                        sparc_ramdisk_image : sparc_ramdisk_image64;
-               if (ramdisk_image >= (unsigned long)_end - 2 * PAGE_SIZE)
-                       ramdisk_image -= KERNBASE;
+               ramdisk_image -= KERNBASE;
                initrd_start = ramdisk_image + phys_base;
                initrd_end = initrd_start + sparc_ramdisk_size;
                if (initrd_end > end_of_phys_memory) {
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/Kconfig
--- a/arch/um/Kconfig   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/Kconfig   Wed Oct 03 10:00:44 2007 +0100
@@ -1,3 +1,8 @@
+config DEFCONFIG_LIST
+       string
+       option defconfig_list
+       default "arch/$ARCH/defconfig"
+
 # UML uses the generic IRQ sugsystem
 config GENERIC_HARDIRQS
        bool
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/Makefile-x86_64
--- a/arch/um/Makefile-x86_64   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/Makefile-x86_64   Wed Oct 03 10:00:44 2007 +0100
@@ -1,7 +1,7 @@
 # Copyright 2003 - 2004 Pathscale, Inc
 # Released under the GPL
 
-core-y += arch/um/sys-x86_64/
+core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/
 START := 0x60000000
 
 #We #undef __x86_64__ for kernelspace, not for userspace where
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/include/common-offsets.h
--- a/arch/um/include/common-offsets.h  Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/include/common-offsets.h  Wed Oct 03 10:00:44 2007 +0100
@@ -15,3 +15,4 @@ DEFINE(UM_ELF_CLASS, ELF_CLASS);
 DEFINE(UM_ELF_CLASS, ELF_CLASS);
 DEFINE(UM_ELFCLASS32, ELFCLASS32);
 DEFINE(UM_ELFCLASS64, ELFCLASS64);
+DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/include/kern_util.h
--- a/arch/um/include/kern_util.h       Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/include/kern_util.h       Wed Oct 03 10:00:44 2007 +0100
@@ -6,7 +6,6 @@
 #ifndef __KERN_UTIL_H__
 #define __KERN_UTIL_H__
 
-#include "linux/threads.h"
 #include "sysdep/ptrace.h"
 #include "sysdep/faultinfo.h"
 
diff -r aafef975e518 -r 3e8752eb6d9c 
arch/um/include/sysdep-i386/kernel-offsets.h
--- a/arch/um/include/sysdep-i386/kernel-offsets.h      Tue Oct 02 09:52:15 
2007 +0100
+++ b/arch/um/include/sysdep-i386/kernel-offsets.h      Wed Oct 03 10:00:44 
2007 +0100
@@ -1,6 +1,7 @@
 #include <linux/stddef.h>
 #include <linux/sched.h>
 #include <linux/elf.h>
+#include <linux/crypto.h>
 #include <asm/mman.h>
 
 #define DEFINE(sym, val) \
diff -r aafef975e518 -r 3e8752eb6d9c 
arch/um/include/sysdep-x86_64/kernel-offsets.h
--- a/arch/um/include/sysdep-x86_64/kernel-offsets.h    Tue Oct 02 09:52:15 
2007 +0100
+++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h    Wed Oct 03 10:00:44 
2007 +0100
@@ -2,6 +2,7 @@
 #include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/elf.h>
+#include <linux/crypto.h>
 #include <asm/page.h>
 #include <asm/mman.h>
 
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/os-Linux/process.c
--- a/arch/um/os-Linux/process.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/os-Linux/process.c        Wed Oct 03 10:00:44 2007 +0100
@@ -141,11 +141,9 @@ void os_usr1_process(int pid)
  * syscalls, and also breaks with clone(), which does not unshare the TLS.
  */
 
-inline _syscall0(pid_t, getpid)
-
 int os_getpid(void)
 {
-       return(getpid());
+       return syscall(__NR_getpid);
 }
 
 int os_getpgrp(void)
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/os-Linux/sys-i386/tls.c
--- a/arch/um/os-Linux/sys-i386/tls.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/os-Linux/sys-i386/tls.c   Wed Oct 03 10:00:44 2007 +0100
@@ -1,9 +1,9 @@
 #include <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
 #include <linux/unistd.h>
 #include "sysdep/tls.h"
 #include "user_util.h"
-
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
 
 /* Checks whether host supports TLS, and sets *tls_min according to the value
  * valid on the host.
@@ -17,7 +17,7 @@ void check_host_supports_tls(int *suppor
                user_desc_t info;
                info.entry_number = val[i];
 
-               if (get_thread_area(&info) == 0) {
+               if(syscall(__NR_get_thread_area, &info) == 0){
                        *tls_min = val[i];
                        *supports_tls = 1;
                        return;
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/os-Linux/tls.c
--- a/arch/um/os-Linux/tls.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/os-Linux/tls.c    Wed Oct 03 10:00:44 2007 +0100
@@ -1,6 +1,8 @@
 #include <errno.h>
 #include <sys/ptrace.h>
+#include <sys/syscall.h>
 #include <asm/ldt.h>
+#include <unistd.h>
 #include "sysdep/tls.h"
 #include "uml-config.h"
 
@@ -48,14 +50,11 @@ int os_get_thread_area(user_desc_t *info
 #ifdef UML_CONFIG_MODE_TT
 #include "linux/unistd.h"
 
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-static _syscall1(int, set_thread_area, user_desc_t *, u_info);
-
 int do_set_thread_area_tt(user_desc_t *info)
 {
        int ret;
 
-       ret = set_thread_area(info);
+       ret = syscall(__NR_set_thread_area, info);
        if (ret < 0) {
                ret = -errno;
        }
@@ -66,7 +65,7 @@ int do_get_thread_area_tt(user_desc_t *i
 {
        int ret;
 
-       ret = get_thread_area(info);
+       ret = syscall(__NR_get_thread_area, info);
        if (ret < 0) {
                ret = -errno;
        }
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/sys-x86_64/stub_segv.c
--- a/arch/um/sys-x86_64/stub_segv.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/sys-x86_64/stub_segv.c    Wed Oct 03 10:00:44 2007 +0100
@@ -5,7 +5,6 @@
 
 #include <stddef.h>
 #include <signal.h>
-#include <linux/compiler.h>
 #include <asm/unistd.h>
 #include "uml-config.h"
 #include "sysdep/sigcontext.h"
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/ia32/ptrace32.c
--- a/arch/x86_64/ia32/ptrace32.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/ia32/ptrace32.c       Wed Oct 03 10:00:44 2007 +0100
@@ -239,6 +239,7 @@ asmlinkage long sys32_ptrace(long reques
        case PTRACE_SINGLESTEP:
        case PTRACE_DETACH:
        case PTRACE_SYSCALL:
+       case PTRACE_OLDSETOPTIONS:
        case PTRACE_SETOPTIONS:
                return sys_ptrace(request, pid, addr, data); 
 
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S        Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/entry.S        Wed Oct 03 10:00:44 2007 +0100
@@ -146,6 +146,10 @@ 1:
 /* rdi:        prev */ 
 ENTRY(ret_from_fork)
        CFI_DEFAULT_STACK
+       push kernel_eflags(%rip)
+       CFI_ADJUST_CFA_OFFSET 4
+       popf                            # reset kernel eflags
+       CFI_ADJUST_CFA_OFFSET -4
        call schedule_tail
        GET_THREAD_INFO(%rcx)
        testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx)
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/pci-calgary.c
--- a/arch/x86_64/kernel/pci-calgary.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/pci-calgary.c  Wed Oct 03 10:00:44 2007 +0100
@@ -759,7 +759,16 @@ static inline unsigned int __init locate
        int rionodeid;
        u32 address;
 
-       rionodeid = (dev->bus->number % 15 > 4) ? 3 : 2;
+       /*
+        * Each Calgary has four busses. The first four busses (first Calgary)
+        * have RIO node ID 2, then the next four (second Calgary) have RIO
+        * node ID 3, the next four (third Calgary) have node ID 2 again, etc.
+        * We use a gross hack - relying on the dev->bus->number ordering,
+        * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1,
+        * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the
+        * second (id 3), and then it repeats modulo 14.
+        */
+       rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2;
        /*
         * register space address calculation as follows:
         * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase)
@@ -767,7 +776,7 @@ static inline unsigned int __init locate
         * RioNodeId is 2 for first Calgary, 3 for second Calgary
         */
        address = START_ADDRESS -
-               (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 15)) +
+               (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) +
                (0x100000) * (rionodeid - CHASSIS_BASE);
        return address;
 }
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/process.c      Wed Oct 03 10:00:44 2007 +0100
@@ -571,6 +571,9 @@ __switch_to(struct task_struct *prev_p, 
                prev->gsindex = gsindex;
        }
 
+       /* Must be after DS reload */
+       unlazy_fpu(prev_p);
+
        /* 
         * Switch the PDA and FPU contexts.
         */
@@ -578,10 +581,6 @@ __switch_to(struct task_struct *prev_p, 
        write_pda(oldrsp, next->userrsp); 
        write_pda(pcurrent, next_p); 
 
-       /* This must be here to ensure both math_state_restore() and
-          kernel_fpu_begin() work consistently. 
-          And the AMD workaround requires it to be after DS reload. */
-       unlazy_fpu(prev_p);
        write_pda(kernelstack,
                  task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
 
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/setup.c        Wed Oct 03 10:00:44 2007 +0100
@@ -1010,7 +1010,10 @@ static void __cpuinit init_intel(struct 
        if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
            (c->x86 == 0x6 && c->x86_model >= 0x0e))
                set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
-       set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
+       if (c->x86 == 15)
+               set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
+       else
+               clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
        c->x86_max_cores = intel_num_cpu_cores(c);
 
        srat_detect_node();
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/setup64.c      Wed Oct 03 10:00:44 2007 +0100
@@ -178,6 +178,8 @@ void __cpuinit check_efer(void)
         }       
 }
 
+unsigned long kernel_eflags;
+
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
@@ -290,4 +292,6 @@ void __cpuinit cpu_init (void)
        set_debugreg(0UL, 7);
 
        fpu_init(); 
-}
+
+       raw_local_save_flags(kernel_eflags);
+}
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/time.c Wed Oct 03 10:00:44 2007 +0100
@@ -960,7 +960,7 @@ __cpuinit int unsynchronized_tsc(void)
        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
 #ifdef CONFIG_ACPI
                /* But TSC doesn't tick in C3 so don't use it there */
-               if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
+               if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000)
                        return 1;
 #endif
                return 0;
diff -r aafef975e518 -r 3e8752eb6d9c block/elevator.c
--- a/block/elevator.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/block/elevator.c  Wed Oct 03 10:00:44 2007 +0100
@@ -892,7 +892,7 @@ ssize_t elv_iosched_show(request_queue_t
        struct list_head *entry;
        int len = 0;
 
-       spin_lock_irq(q->queue_lock);
+       spin_lock_irq(&elv_list_lock);
        list_for_each(entry, &elv_list) {
                struct elevator_type *__e;
 
@@ -902,7 +902,7 @@ ssize_t elv_iosched_show(request_queue_t
                else
                        len += sprintf(name+len, "%s ", __e->elevator_name);
        }
-       spin_unlock_irq(q->queue_lock);
+       spin_unlock_irq(&elv_list_lock);
 
        len += sprintf(len+name, "\n");
        return len;
diff -r aafef975e518 -r 3e8752eb6d9c block/ll_rw_blk.c
--- a/block/ll_rw_blk.c Tue Oct 02 09:52:15 2007 +0100
+++ b/block/ll_rw_blk.c Wed Oct 03 10:00:44 2007 +0100
@@ -3021,6 +3021,7 @@ void generic_make_request(struct bio *bi
 {
        request_queue_t *q;
        sector_t maxsector;
+       sector_t old_sector;
        int ret, nr_sectors = bio_sectors(bio);
        dev_t old_dev;
 
@@ -3049,7 +3050,7 @@ void generic_make_request(struct bio *bi
         * NOTE: we don't repeat the blk_size check for each new device.
         * Stacking drivers are expected to know what they are doing.
         */
-       maxsector = -1;
+       old_sector = -1;
        old_dev = 0;
        do {
                char b[BDEVNAME_SIZE];
@@ -3083,14 +3084,29 @@ end_io:
                 */
                blk_partition_remap(bio);
 
-               if (maxsector != -1)
+               if (old_sector != -1)
                        blk_add_trace_remap(q, bio, old_dev, bio->bi_sector, 
-                                           maxsector);
+                                           old_sector);
 
                blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
 
-               maxsector = bio->bi_sector;
+               old_sector = bio->bi_sector;
                old_dev = bio->bi_bdev->bd_dev;
+
+               maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
+               if (maxsector) {
+                       sector_t sector = bio->bi_sector;
+
+                       if (maxsector < nr_sectors || maxsector - nr_sectors < 
sector) {
+                               /*
+                                * This may well happen - partitions are not 
checked
+                                * to make sure they are within the size of the
+                                * whole device.
+                                */
+                               handle_bad_sector(bio);
+                               goto end_io;
+                       }
+               }
 
                ret = q->make_request_fn(q, bio);
        } while (ret);
diff -r aafef975e518 -r 3e8752eb6d9c block/scsi_ioctl.c
--- a/block/scsi_ioctl.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/block/scsi_ioctl.c        Wed Oct 03 10:00:44 2007 +0100
@@ -246,10 +246,10 @@ static int sg_io(struct file *file, requ
                switch (hdr->dxfer_direction) {
                default:
                        return -EINVAL;
-               case SG_DXFER_TO_FROM_DEV:
                case SG_DXFER_TO_DEV:
                        writing = 1;
                        break;
+               case SG_DXFER_TO_FROM_DEV:
                case SG_DXFER_FROM_DEV:
                        break;
                }
@@ -286,9 +286,8 @@ static int sg_io(struct file *file, requ
         * fill in request structure
         */
        rq->cmd_len = hdr->cmd_len;
+       memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
        memcpy(rq->cmd, cmd, hdr->cmd_len);
-       if (sizeof(rq->cmd) != hdr->cmd_len)
-               memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - 
hdr->cmd_len);
 
        memset(sense, 0, sizeof(sense));
        rq->sense = sense;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/block/DAC960.c
--- a/drivers/block/DAC960.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/block/DAC960.c    Wed Oct 03 10:00:44 2007 +0100
@@ -7115,7 +7115,7 @@ static struct pci_device_id DAC960_id_ta
        {
                .vendor         = PCI_VENDOR_ID_MYLEX,
                .device         = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
-               .subvendor      = PCI_ANY_ID,
+               .subvendor      = PCI_VENDOR_ID_MYLEX,
                .subdevice      = PCI_ANY_ID,
                .driver_data    = (unsigned long) &DAC960_GEM_privdata,
        },
diff -r aafef975e518 -r 3e8752eb6d9c drivers/block/cciss.c
--- a/drivers/block/cciss.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/block/cciss.c     Wed Oct 03 10:00:44 2007 +0100
@@ -1301,6 +1301,12 @@ static void cciss_softirq_done(struct re
        }
 
        complete_buffers(rq->bio, rq->errors);
+
+       if (blk_fs_request(rq)) {
+               const int rw = rq_data_dir(rq);
+
+               disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
+       }
 
 #ifdef CCISS_DEBUG
        printk("Done with %p\n", rq);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/block/cpqarray.c  Wed Oct 03 10:00:44 2007 +0100
@@ -1000,6 +1000,7 @@ static inline void complete_buffers(stru
  */
 static inline void complete_command(cmdlist_t *cmd, int timeout)
 {
+       struct request *rq = cmd->rq;
        int ok=1;
        int i, ddir;
 
@@ -1031,12 +1032,18 @@ static inline void complete_command(cmdl
                 pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
                                cmd->req.sg[i].size, ddir);
 
-       complete_buffers(cmd->rq->bio, ok);
-
-       add_disk_randomness(cmd->rq->rq_disk);
-
-        DBGPX(printk("Done with %p\n", cmd->rq););
-       end_that_request_last(cmd->rq, ok ? 1 : -EIO);
+       complete_buffers(rq->bio, ok);
+
+       if (blk_fs_request(rq)) {
+               const int rw = rq_data_dir(rq);
+
+               disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
+       }
+
+       add_disk_randomness(rq->rq_disk);
+
+       DBGPX(printk("Done with %p\n", rq););
+       end_that_request_last(rq, ok ? 1 : -EIO);
 }
 
 /*
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/agp/generic.c
--- a/drivers/char/agp/generic.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/agp/generic.c        Wed Oct 03 10:00:44 2007 +0100
@@ -1020,7 +1020,7 @@ void *agp_generic_alloc_page(struct agp_
 {
        struct page * page;
 
-       page = alloc_page(GFP_KERNEL);
+       page = alloc_page(GFP_KERNEL | GFP_DMA32);
        if (page == NULL)
                return NULL;
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/agp/intel-agp.c
--- a/drivers/char/agp/intel-agp.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/agp/intel-agp.c      Wed Oct 03 10:00:44 2007 +0100
@@ -160,7 +160,7 @@ static void *i8xx_alloc_pages(void)
 {
        struct page * page;
 
-       page = alloc_pages(GFP_KERNEL, 2);
+       page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2);
        if (page == NULL)
                return NULL;
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/hw_random/intel-rng.c
--- a/drivers/char/hw_random/intel-rng.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/hw_random/intel-rng.c        Wed Oct 03 10:00:44 2007 +0100
@@ -50,6 +50,43 @@
 #define INTEL_RNG_ADDR_LEN                     3
 
 /*
+ * LPC bridge PCI config space registers
+ */
+#define FWH_DEC_EN1_REG_OLD                    0xe3
+#define FWH_DEC_EN1_REG_NEW                    0xd9 /* high byte of 16-bit 
register */
+#define FWH_F8_EN_MASK                         0x80
+
+#define BIOS_CNTL_REG_OLD                      0x4e
+#define BIOS_CNTL_REG_NEW                      0xdc
+#define BIOS_CNTL_WRITE_ENABLE_MASK            0x01
+#define BIOS_CNTL_LOCK_ENABLE_MASK             0x02
+
+/*
+ * Magic address at which Intel Firmware Hubs get accessed
+ */
+#define INTEL_FWH_ADDR                         0xffff0000
+#define INTEL_FWH_ADDR_LEN                     2
+
+/*
+ * Intel Firmware Hub command codes (write to any address inside the device)
+ */
+#define INTEL_FWH_RESET_CMD                    0xff /* aka READ_ARRAY */
+#define INTEL_FWH_READ_ID_CMD                  0x90
+
+/*
+ * Intel Firmware Hub Read ID command result addresses
+ */
+#define INTEL_FWH_MANUFACTURER_CODE_ADDRESS    0x000000
+#define INTEL_FWH_DEVICE_CODE_ADDRESS          0x000001
+
+/*
+ * Intel Firmware Hub Read ID command result values
+ */
+#define INTEL_FWH_MANUFACTURER_CODE            0x89
+#define INTEL_FWH_DEVICE_CODE_8M               0xac
+#define INTEL_FWH_DEVICE_CODE_4M               0xad
+
+/*
  * Data for PCI driver interface
  *
  * This data only exists for exporting the supported
@@ -58,12 +95,50 @@
  * want to register another driver on the same PCI id.
  */
 static const struct pci_device_id pci_tbl[] = {
-       { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+/* AA
+       { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AA */
+/* AB
+       { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AB */
+/* ??
+       { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+/* BAM, CAM, DBM, FBM, GxM
+       { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BAM */
+       { 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CAM */
+       { 0x8086, 0x24cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DBM */
+       { 0x8086, 0x2641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FBM */
+       { 0x8086, 0x27b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM */
+       { 0x8086, 0x27bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM DH */
+/* BA, CA, DB, Ex, 6300, Fx, 631x/632x, Gx
+       { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BA */
+       { 0x8086, 0x2480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CA */
+       { 0x8086, 0x24c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DB */
+       { 0x8086, 0x24d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ex */
+       { 0x8086, 0x25a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 6300 */
+       { 0x8086, 0x2640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Fx */
+       { 0x8086, 0x2670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+       { 0x8086, 0x27b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Gx */
+/* E
+       { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+       { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E  */
        { 0, }, /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, pci_tbl);
@@ -138,14 +213,107 @@ static struct hwrng intel_rng = {
 };
 
 
+#ifdef CONFIG_SMP
+static char __initdata waitflag;
+
+static void __init intel_init_wait(void *unused)
+{
+       while (waitflag)
+               cpu_relax();
+}
+#endif
+
 static int __init mod_init(void)
 {
        int err = -ENODEV;
+       unsigned i;
+       struct pci_dev *dev = NULL;
        void __iomem *mem;
-       u8 hw_status;
-
-       if (!pci_dev_present(pci_tbl))
+       unsigned long flags;
+       u8 bios_cntl_off, fwh_dec_en1_off;
+       u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
+       u8 hw_status, mfc, dvc;
+
+       for (i = 0; !dev && pci_tbl[i].vendor; ++i)
+               dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, 
NULL);
+
+       if (!dev)
                goto out; /* Device not found. */
+
+       /* Check for Intel 82802 */
+       if (dev->device < 0x2640) {
+               fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
+               bios_cntl_off = BIOS_CNTL_REG_OLD;
+       } else {
+               fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
+               bios_cntl_off = BIOS_CNTL_REG_NEW;
+       }
+
+       pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
+       pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
+
+       mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
+       if (mem == NULL) {
+               pci_dev_put(dev);
+               err = -EBUSY;
+               goto out;
+       }
+
+       /*
+        * Since the BIOS code/data is going to disappear from its normal
+        * location with the Read ID command, all activity on the system
+        * must be stopped until the state is back to normal.
+        */
+#ifdef CONFIG_SMP
+       set_mb(waitflag, 1);
+       if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
+               set_mb(waitflag, 0);
+               pci_dev_put(dev);
+               printk(KERN_ERR PFX "cannot run on all processors\n");
+               err = -EAGAIN;
+               goto err_unmap;
+       }
+#endif
+       local_irq_save(flags);
+
+       if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+               pci_write_config_byte(dev,
+                                     fwh_dec_en1_off,
+                                     fwh_dec_en1_val | FWH_F8_EN_MASK);
+       if (!(bios_cntl_val &
+             (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+               pci_write_config_byte(dev,
+                                     bios_cntl_off,
+                                     bios_cntl_val | 
BIOS_CNTL_WRITE_ENABLE_MASK);
+
+       writeb(INTEL_FWH_RESET_CMD, mem);
+       writeb(INTEL_FWH_READ_ID_CMD, mem);
+       mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
+       dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
+       writeb(INTEL_FWH_RESET_CMD, mem);
+
+       if (!(bios_cntl_val &
+             (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+               pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
+       if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+               pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
+
+       local_irq_restore(flags);
+#ifdef CONFIG_SMP
+       /* Tell other CPUs to resume. */
+       set_mb(waitflag, 0);
+#endif
+
+       iounmap(mem);
+       pci_dev_put(dev);
+
+       if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
+           (dvc != INTEL_FWH_DEVICE_CODE_8M &&
+            dvc != INTEL_FWH_DEVICE_CODE_4M)) {
+               printk(KERN_ERR PFX "FWH not detected\n");
+               err = -ENODEV;
+               goto out;
+       }
 
        err = -ENOMEM;
        mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
@@ -153,7 +321,7 @@ static int __init mod_init(void)
                goto out;
        intel_rng.priv = (unsigned long)mem;
 
-       /* Check for Intel 82802 */
+       /* Check for Random Number Generator */
        err = -ENODEV;
        hw_status = hwstatus_get(mem);
        if ((hw_status & INTEL_RNG_PRESENT) == 0)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/ipmi/ipmi_si_intf.c
--- a/drivers/char/ipmi/ipmi_si_intf.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/ipmi/ipmi_si_intf.c  Wed Oct 03 10:00:44 2007 +0100
@@ -1845,7 +1845,7 @@ static int ipmi_pci_resume(struct pci_de
 
 static struct pci_device_id ipmi_pci_devices[] = {
        { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
-       { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) }
+       { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }
 };
 MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/isicom.c
--- a/drivers/char/isicom.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/isicom.c     Wed Oct 03 10:00:44 2007 +0100
@@ -1062,11 +1062,12 @@ static void isicom_close(struct tty_stru
 static void isicom_close(struct tty_struct *tty, struct file *filp)
 {
        struct isi_port *port = tty->driver_data;
-       struct isi_board *card = port->card;
+       struct isi_board *card;
        unsigned long flags;
 
        if (!port)
                return;
+       card = port->card;
        if (isicom_paranoia_check(port, tty->name, "isicom_close"))
                return;
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/mem.c
--- a/drivers/char/mem.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/mem.c        Wed Oct 03 10:00:44 2007 +0100
@@ -618,7 +618,8 @@ static inline size_t read_zero_pagealign
                        count = size;
 
                zap_page_range(vma, addr, count, NULL);
-               zeromap_page_range(vma, addr, count, PAGE_COPY);
+               if (zeromap_page_range(vma, addr, count, PAGE_COPY))
+                       break;
 
                size -= count;
                buf += count;
@@ -685,11 +686,14 @@ out:
 
 static int mmap_zero(struct file * file, struct vm_area_struct * vma)
 {
+       int err;
+
        if (vma->vm_flags & VM_SHARED)
                return shmem_zero_setup(vma);
-       if (zeromap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, 
vma->vm_page_prot))
-               return -EAGAIN;
-       return 0;
+       err = zeromap_page_range(vma, vma->vm_start,
+                       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+       BUG_ON(err == -EEXIST);
+       return err;
 }
 #else /* CONFIG_MMU */
 static ssize_t read_zero(struct file * file, char * buf, 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/rtc.c
--- a/drivers/char/rtc.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/rtc.c        Wed Oct 03 10:00:44 2007 +0100
@@ -209,11 +209,12 @@ static const unsigned char days_in_mo[] 
  */
 static inline unsigned char rtc_is_updating(void)
 {
+       unsigned long flags;
        unsigned char uip;
 
-       spin_lock_irq(&rtc_lock);
+       spin_lock_irqsave(&rtc_lock, flags);
        uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
-       spin_unlock_irq(&rtc_lock);
+       spin_unlock_irqrestore(&rtc_lock, flags);
        return uip;
 }
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/watchdog/sc1200wdt.c
--- a/drivers/char/watchdog/sc1200wdt.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/watchdog/sc1200wdt.c Wed Oct 03 10:00:44 2007 +0100
@@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void)
        if (io == -1) {
                printk(KERN_ERR PFX "io parameter must be specified\n");
                ret = -EINVAL;
-               goto out_clean;
+               goto out_pnp;
        }
 
 #if defined CONFIG_PNP
@@ -405,7 +405,7 @@ static int __init sc1200wdt_init(void)
        if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
                printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
                ret = -EBUSY;
-               goto out_clean;
+               goto out_pnp;
        }
 
        ret = sc1200wdt_probe();
@@ -435,6 +435,11 @@ out_io:
 out_io:
        release_region(io, io_len);
 
+out_pnp:
+#if defined CONFIG_PNP
+       if (isapnp)
+               pnp_unregister_driver(&scl200wdt_pnp_driver);
+#endif
        goto out_clean;
 }
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/clocksource/scx200_hrt.c
--- a/drivers/clocksource/scx200_hrt.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/clocksource/scx200_hrt.c  Wed Oct 03 10:00:44 2007 +0100
@@ -63,7 +63,7 @@ static struct clocksource cs_hrt = {
 
 static int __init init_hrt_clocksource(void)
 {
-       /* Make sure scx200 has initializedd the configuration block */
+       /* Make sure scx200 has initialized the configuration block */
        if (!scx200_cb_present())
                return -ENODEV;
 
@@ -76,7 +76,7 @@ static int __init init_hrt_clocksource(v
        }
 
        /* write timer config */
-       outb(HR_TMEN | (mhz27) ? HR_TMCLKSEL : 0,
+       outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0),
             scx200_cb_base + SCx200_TMCNFG_OFFSET);
 
        if (mhz27) {
diff -r aafef975e518 -r 3e8752eb6d9c drivers/cpufreq/cpufreq_stats.c
--- a/drivers/cpufreq/cpufreq_stats.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/cpufreq/cpufreq_stats.c   Wed Oct 03 10:00:44 2007 +0100
@@ -350,12 +350,10 @@ __init cpufreq_stats_init(void)
        }
 
        register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
-       lock_cpu_hotplug();
        for_each_online_cpu(cpu) {
                cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, 
CPU_ONLINE,
                        (void *)(long)cpu);
        }
-       unlock_cpu_hotplug();
        return 0;
 }
 static void
diff -r aafef975e518 -r 3e8752eb6d9c drivers/i2c/chips/ds1337.c
--- a/drivers/i2c/chips/ds1337.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/i2c/chips/ds1337.c        Wed Oct 03 10:00:44 2007 +0100
@@ -347,13 +347,19 @@ static void ds1337_init_client(struct i2
 
        if ((status & 0x80) || (control & 0x80)) {
                /* RTC not running */
-               u8 buf[16];
+               u8 buf[1+16];   /* First byte is interpreted as address */
                struct i2c_msg msg[1];
 
                dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
 
                /* Initialize all, including STATUS and CONTROL to zero */
                memset(buf, 0, sizeof(buf));
+
+               /* Write valid values in the date/time registers */
+               buf[1+DS1337_REG_DAY] = 1;
+               buf[1+DS1337_REG_DATE] = 1;
+               buf[1+DS1337_REG_MONTH] = 1;
+
                msg[0].addr = client->addr;
                msg[0].flags = 0;
                msg[0].len = sizeof(buf);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/ide/pci/generic.c
--- a/drivers/ide/pci/generic.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/ide/pci/generic.c Wed Oct 03 10:00:44 2007 +0100
@@ -242,13 +242,17 @@ static int __devinit generic_init_one(st
            (!(PCI_FUNC(dev->devfn) & 1)))
                goto out;
 
-       if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1)
-               goto out;
-
-       pci_read_config_word(dev, PCI_COMMAND, &command);
-       if (!(command & PCI_COMMAND_IO)) {
-               printk(KERN_INFO "Skipping disabled %s IDE controller.\n", 
d->name);
-               goto out;
+       if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
+               if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && 
PCI_FUNC(dev->devfn) != 1)
+                       goto out;
+       }
+
+       if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+               pci_read_config_word(dev, PCI_COMMAND, &command);
+               if (!(command & PCI_COMMAND_IO)) {
+                       printk(KERN_INFO "Skipping disabled %s IDE 
controller.\n", d->name);
+                       goto out;
+               }
        }
        ret = ide_setup_pci_device(dev, d);
 out:
diff -r aafef975e518 -r 3e8752eb6d9c drivers/ide/ppc/pmac.c
--- a/drivers/ide/ppc/pmac.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/ide/ppc/pmac.c    Wed Oct 03 10:00:44 2007 +0100
@@ -1326,7 +1326,7 @@ pmac_ide_macio_attach(struct macio_dev *
        if (macio_irq_count(mdev) == 0) {
                printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n",
                        i, mdev->ofdev.node->full_name);
-               irq = 13;
+               irq = irq_create_mapping(NULL, 13);
        } else
                irq = macio_irq(mdev, 0);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/ieee1394/ohci1394.c
--- a/drivers/ieee1394/ohci1394.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/ieee1394/ohci1394.c       Wed Oct 03 10:00:44 2007 +0100
@@ -3218,6 +3218,19 @@ static int __devinit ohci1394_pci_probe(
        struct ti_ohci *ohci;   /* shortcut to currently handled device */
        resource_size_t ohci_base;
 
+#ifdef CONFIG_PPC_PMAC
+       /* Necessary on some machines if ohci1394 was loaded/ unloaded before */
+       if (machine_is(powermac)) {
+               struct device_node *of_node = pci_device_to_OF_node(dev);
+
+               if (of_node) {
+                       pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, of_node,
+                                         0, 1);
+                       pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 1);
+               }
+       }
+#endif /* CONFIG_PPC_PMAC */
+
         if (pci_enable_device(dev))
                FAIL(-ENXIO, "Failed to enable OHCI hardware");
         pci_set_master(dev);
@@ -3506,11 +3519,9 @@ static void ohci1394_pci_remove(struct p
 #endif
 
 #ifdef CONFIG_PPC_PMAC
-       /* On UniNorth, power down the cable and turn off the chip
-        * clock when the module is removed to save power on
-        * laptops. Turning it back ON is done by the arch code when
-        * pci_enable_device() is called */
-       {
+       /* On UniNorth, power down the cable and turn off the chip clock
+        * to save power on laptops */
+       if (machine_is(powermac)) {
                struct device_node* of_node;
 
                of_node = pci_device_to_OF_node(ohci->dev);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/core/mad.c
--- a/drivers/infiniband/core/mad.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/core/mad.c     Wed Oct 03 10:00:44 2007 +0100
@@ -1750,7 +1750,7 @@ ib_find_send_mad(struct ib_mad_agent_pri
                     */
                    (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) ||
                     rcv_has_same_gid(mad_agent_priv, wr, wc)))
-                       return wr;
+                       return (wr->status == IB_WC_SUCCESS) ? wr : NULL;
        }
 
        /*
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/hw/mthca/mthca_cq.c
--- a/drivers/infiniband/hw/mthca/mthca_cq.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c    Wed Oct 03 10:00:44 2007 +0100
@@ -39,6 +39,8 @@
 #include <linux/init.h>
 #include <linux/hardirq.h>
 
+#include <asm/io.h>
+
 #include <rdma/ib_pack.h>
 
 #include "mthca_dev.h"
@@ -210,6 +212,11 @@ static inline void update_cons_index(str
                mthca_write64(doorbell,
                              dev->kar + MTHCA_CQ_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+               /*
+                * Make sure doorbells don't leak out of CQ spinlock
+                * and reach the HCA out of order:
+                */
+               mmiowb();
        }
 }
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/hw/mthca/mthca_mad.c
--- a/drivers/infiniband/hw/mthca/mthca_mad.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c   Wed Oct 03 10:00:44 2007 +0100
@@ -119,7 +119,7 @@ static void smp_snoop(struct ib_device *
 
                        mthca_update_rate(to_mdev(ibdev), port_num);
                        update_sm_ah(to_mdev(ibdev), port_num,
-                                    be16_to_cpu(pinfo->lid),
+                                    be16_to_cpu(pinfo->sm_lid),
                                     pinfo->neighbormtu_mastersmsl & 0xf);
 
                        event.device           = ibdev;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/hw/mthca/mthca_qp.c
--- a/drivers/infiniband/hw/mthca/mthca_qp.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c    Wed Oct 03 10:00:44 2007 +0100
@@ -38,6 +38,8 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+
+#include <asm/io.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
@@ -1730,6 +1732,11 @@ out:
                mthca_write64(doorbell,
                              dev->kar + MTHCA_SEND_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+               /*
+                * Make sure doorbells don't leak out of SQ spinlock
+                * and reach the HCA out of order:
+                */
+               mmiowb();
        }
 
        qp->sq.next_ind = ind;
@@ -1848,6 +1855,12 @@ out:
 
        qp->rq.next_ind = ind;
        qp->rq.head    += nreq;
+
+       /*
+        * Make sure doorbells don't leak out of RQ spinlock and reach
+        * the HCA out of order:
+        */
+       mmiowb();
 
        spin_unlock_irqrestore(&qp->rq.lock, flags);
        return err;
@@ -2110,6 +2123,12 @@ out:
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
        }
 
+       /*
+        * Make sure doorbells don't leak out of SQ spinlock and reach
+        * the HCA out of order:
+        */
+       mmiowb();
+
        spin_unlock_irqrestore(&qp->sq.lock, flags);
        return err;
 }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/hw/mthca/mthca_srq.c
--- a/drivers/infiniband/hw/mthca/mthca_srq.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c   Wed Oct 03 10:00:44 2007 +0100
@@ -35,6 +35,8 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 
+#include <asm/io.h>
+
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
 #include "mthca_memfree.h"
@@ -592,6 +594,12 @@ int mthca_tavor_post_srq_recv(struct ib_
                              dev->kar + MTHCA_RECEIVE_DOORBELL,
                              MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
        }
+
+       /*
+        * Make sure doorbells don't leak out of SRQ spinlock and
+        * reach the HCA out of order:
+        */
+       mmiowb();
 
        spin_unlock_irqrestore(&srq->lock, flags);
        return err;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c   Wed Oct 03 10:00:44 2007 +0100
@@ -619,8 +619,10 @@ void ipoib_ib_dev_flush(void *_dev)
         * The device could have been brought down between the start and when
         * we get here, don't bring it back up if it's not configured up
         */
-       if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+       if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) {
                ipoib_ib_dev_up(dev);
+               ipoib_mcast_restart_task(dev);
+       }
 
        mutex_lock(&priv->vlan_mutex);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/ulp/srp/ib_srp.c
--- a/drivers/infiniband/ulp/srp/ib_srp.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/ulp/srp/ib_srp.c       Wed Oct 03 10:00:44 2007 +0100
@@ -1851,7 +1851,7 @@ static void srp_add_one(struct ib_device
         */
        srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1);
        srp_dev->fmr_page_size  = 1 << srp_dev->fmr_page_shift;
-       srp_dev->fmr_page_mask  = ~((unsigned long) srp_dev->fmr_page_size - 1);
+       srp_dev->fmr_page_mask  = ~((u64) srp_dev->fmr_page_size - 1);
 
        INIT_LIST_HEAD(&srp_dev->dev_list);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/ulp/srp/ib_srp.h
--- a/drivers/infiniband/ulp/srp/ib_srp.h       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/ulp/srp/ib_srp.h       Wed Oct 03 10:00:44 2007 +0100
@@ -87,7 +87,7 @@ struct srp_device {
        struct ib_fmr_pool     *fmr_pool;
        int                     fmr_page_shift;
        int                     fmr_page_size;
-       unsigned long           fmr_page_mask;
+       u64                     fmr_page_mask;
 };
 
 struct srp_host {
diff -r aafef975e518 -r 3e8752eb6d9c drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/input/mouse/psmouse-base.c        Wed Oct 03 10:00:44 2007 +0100
@@ -1332,19 +1332,21 @@ ssize_t psmouse_attr_set_helper(struct d
 
 static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, 
char *buf)
 {
-       unsigned long *field = (unsigned long *)((char *)psmouse + 
(size_t)offset);
-
-       return sprintf(buf, "%lu\n", *field);
+       unsigned int *field = (unsigned int *)((char *)psmouse + 
(size_t)offset);
+
+       return sprintf(buf, "%u\n", *field);
 }
 
 static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, 
const char *buf, size_t count)
 {
-       unsigned long *field = (unsigned long *)((char *)psmouse + 
(size_t)offset);
+       unsigned int *field = (unsigned int *)((char *)psmouse + 
(size_t)offset);
        unsigned long value;
        char *rest;
 
        value = simple_strtoul(buf, &rest, 10);
        if (*rest)
+               return -EINVAL;
+       if ((unsigned int)value != value)
                return -EINVAL;
 
        *field = value;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/capi/capidrv.c
--- a/drivers/isdn/capi/capidrv.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/capi/capidrv.c       Wed Oct 03 10:00:44 2007 +0100
@@ -1907,7 +1907,8 @@ static int if_readstat(u8 __user *buf, i
        }
 
        for (p=buf, count=0; count < len; p++, count++) {
-               put_user(*card->q931_read++, p);
+               if (put_user(*card->q931_read++, p))
+                       return -EFAULT;
                if (card->q931_read > card->q931_end)
                        card->q931_read = card->q931_buf;
        }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/hisax/config.c
--- a/drivers/isdn/hisax/config.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/hisax/config.c       Wed Oct 03 10:00:44 2007 +0100
@@ -631,7 +631,8 @@ static int HiSax_readstatus(u_char __use
                count = cs->status_end - cs->status_read + 1;
                if (count >= len)
                        count = len;
-               copy_to_user(p, cs->status_read, count);
+               if (copy_to_user(p, cs->status_read, count))
+                       return -EFAULT;
                cs->status_read += count;
                if (cs->status_read > cs->status_end)
                        cs->status_read = cs->status_buf;
@@ -642,7 +643,8 @@ static int HiSax_readstatus(u_char __use
                                cnt = HISAX_STATUS_BUFSIZE;
                        else
                                cnt = count;
-                       copy_to_user(p, cs->status_read, cnt);
+                       if (copy_to_user(p, cs->status_read, cnt))
+                               return -EFAULT;
                        p += cnt;
                        cs->status_read += cnt % HISAX_STATUS_BUFSIZE;
                        count -= cnt;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/i4l/isdn_common.c
--- a/drivers/isdn/i4l/isdn_common.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/i4l/isdn_common.c    Wed Oct 03 10:00:44 2007 +0100
@@ -1134,9 +1134,12 @@ isdn_read(struct file *file, char __user
                if (dev->drv[drvidx]->interface->readstat) {
                        if (count > dev->drv[drvidx]->stavail)
                                count = dev->drv[drvidx]->stavail;
-                       len = dev->drv[drvidx]->interface->
-                               readstat(buf, count, drvidx,
-                                        isdn_minor2chan(minor));
+                       len = dev->drv[drvidx]->interface->readstat(buf, count,
+                                               drvidx, isdn_minor2chan(minor));
+                       if (len < 0) {
+                               retval = len;
+                               goto out;
+                       }
                } else {
                        len = 0;
                }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/icn/icn.c
--- a/drivers/isdn/icn/icn.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/icn/icn.c    Wed Oct 03 10:00:44 2007 +0100
@@ -1010,7 +1010,8 @@ icn_readstatus(u_char __user *buf, int l
        for (p = buf, count = 0; count < len; p++, count++) {
                if (card->msg_buf_read == card->msg_buf_write)
                        return count;
-               put_user(*card->msg_buf_read++, p);
+               if (put_user(*card->msg_buf_read++, p))
+                       return -EFAULT;
                if (card->msg_buf_read > card->msg_buf_end)
                        card->msg_buf_read = card->msg_buf;
        }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/isdnloop/isdnloop.c
--- a/drivers/isdn/isdnloop/isdnloop.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/isdnloop/isdnloop.c  Wed Oct 03 10:00:44 2007 +0100
@@ -451,7 +451,8 @@ isdnloop_readstatus(u_char __user *buf, 
        for (p = buf, count = 0; count < len; p++, count++) {
                if (card->msg_buf_read == card->msg_buf_write)
                        return count;
-               put_user(*card->msg_buf_read++, p);
+               if (put_user(*card->msg_buf_read++, p))
+                       return -EFAULT;
                if (card->msg_buf_read > card->msg_buf_end)
                        card->msg_buf_read = card->msg_buf;
        }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/pcbit/drv.c
--- a/drivers/isdn/pcbit/drv.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/pcbit/drv.c  Wed Oct 03 10:00:44 2007 +0100
@@ -725,23 +725,27 @@ static int pcbit_stat(u_char __user *buf
 
        if (stat_st < stat_end)
        {
-               copy_to_user(buf, statbuf + stat_st, len);
+               if (copy_to_user(buf, statbuf + stat_st, len))
+                       return -EFAULT;
                stat_st += len;    
        }
        else
        {
                if (len > STATBUF_LEN - stat_st)
                {
-                       copy_to_user(buf, statbuf + stat_st, 
-                                      STATBUF_LEN - stat_st);
-                       copy_to_user(buf, statbuf, 
-                                      len - (STATBUF_LEN - stat_st));
+                       if (copy_to_user(buf, statbuf + stat_st,
+                                      STATBUF_LEN - stat_st))
+                               return -EFAULT;
+                       if (copy_to_user(buf, statbuf,
+                                      len - (STATBUF_LEN - stat_st)))
+                               return -EFAULT;
 
                        stat_st = len - (STATBUF_LEN - stat_st);
                }
                else
                {
-                       copy_to_user(buf, statbuf + stat_st, len);
+                       if (copy_to_user(buf, statbuf + stat_st, len))
+                               return -EFAULT;
 
                        stat_st += len;
                        
diff -r aafef975e518 -r 3e8752eb6d9c drivers/macintosh/via-pmu-backlight.c
--- a/drivers/macintosh/via-pmu-backlight.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/macintosh/via-pmu-backlight.c     Wed Oct 03 10:00:44 2007 +0100
@@ -16,7 +16,7 @@
 #define MAX_PMU_LEVEL 0xFF
 
 static struct backlight_properties pmu_backlight_data;
-static spinlock_t pmu_backlight_lock;
+static DEFINE_SPINLOCK(pmu_backlight_lock);
 static int sleeping;
 static u8 bl_curve[FB_BACKLIGHT_LEVELS];
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/dm-crypt.c
--- a/drivers/md/dm-crypt.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/dm-crypt.c     Wed Oct 03 10:00:44 2007 +0100
@@ -717,13 +717,15 @@ static int crypt_endio(struct bio *bio, 
        if (bio->bi_size)
                return 1;
 
+       if (!bio_flagged(bio, BIO_UPTODATE) && !error)
+               error = -EIO;
+
        bio_put(bio);
 
        /*
         * successful reads are decrypted by the worker thread
         */
-       if ((bio_data_dir(bio) == READ)
-           && bio_flagged(bio, BIO_UPTODATE)) {
+       if (bio_data_dir(io->bio) == READ && !error) {
                kcryptd_queue_io(io);
                return 0;
        }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/dm-snap.c
--- a/drivers/md/dm-snap.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/dm-snap.c      Wed Oct 03 10:00:44 2007 +0100
@@ -691,6 +691,7 @@ static void pending_complete(struct pend
 
                free_exception(e);
 
+               remove_exception(&pe->e);
                error_snapshot_bios(pe);
                goto out;
        }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/md.c
--- a/drivers/md/md.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/md.c   Wed Oct 03 10:00:44 2007 +0100
@@ -1994,6 +1994,7 @@ static mdk_rdev_t *md_import_device(dev_
        kobject_init(&rdev->kobj);
 
        rdev->desc_nr = -1;
+       rdev->saved_raid_disk = -1;
        rdev->flags = 0;
        rdev->data_offset = 0;
        rdev->sb_events = 0;
@@ -3867,6 +3868,7 @@ static int hot_add_disk(mddev_t * mddev,
        }
        clear_bit(In_sync, &rdev->flags);
        rdev->desc_nr = -1;
+       rdev->saved_raid_disk = -1;
        err = bind_rdev_to_array(rdev, mddev);
        if (err)
                goto abort_export;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/multipath.c
--- a/drivers/md/multipath.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/multipath.c    Wed Oct 03 10:00:44 2007 +0100
@@ -480,7 +480,7 @@ static int multipath_run (mddev_t *mddev
                        mdname(mddev));
                goto out_free_conf;
        }
-       mddev->degraded = conf->raid_disks = conf->working_disks;
+       mddev->degraded = conf->raid_disks - conf->working_disks;
 
        conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
                                                 sizeof(struct multipath_bh));
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/raid10.c
--- a/drivers/md/raid10.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/raid10.c       Wed Oct 03 10:00:44 2007 +0100
@@ -2042,7 +2042,7 @@ static int run(mddev_t *mddev)
                disk = conf->mirrors + i;
 
                if (!disk->rdev ||
-                   !test_bit(In_sync, &rdev->flags)) {
+                   !test_bit(In_sync, &disk->rdev->flags)) {
                        disk->head_position = 0;
                        mddev->degraded++;
                }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/Kconfig
--- a/drivers/media/Kconfig     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/Kconfig     Wed Oct 03 10:00:44 2007 +0100
@@ -54,6 +54,7 @@ config VIDEO_V4L1_COMPAT
 
 config VIDEO_V4L2
        bool
+       depends on VIDEO_DEV
        default y
 
 source "drivers/media/video/Kconfig"
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/b2c2/flexcop-fe-tuner.c
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c Wed Oct 03 10:00:44 2007 +0100
@@ -527,7 +527,7 @@ int flexcop_frontend_init(struct flexcop
        /* try the air atsc 2nd generation (nxt2002) */
        if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != 
NULL) {
                fc->dev_type          = FC_AIR_ATSC2;
-               dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, 
&dvb_pll_samsung_tbmv);
+               dvb_pll_attach(fc->fe, 0x61, NULL, &dvb_pll_samsung_tbmv);
                info("found the nxt2002 at i2c address: 
0x%02x",samsung_tbmv_config.demod_address);
        } else
        /* try the air atsc 3nd generation (lgdt3303) */
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/dvb-core/dvb_net.c
--- a/drivers/media/dvb/dvb-core/dvb_net.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/dvb-core/dvb_net.c      Wed Oct 03 10:00:44 2007 +0100
@@ -604,7 +604,7 @@ static void dvb_net_ule( struct net_devi
                                { &utype, sizeof utype },
                                { priv->ule_skb->data, priv->ule_skb->len - 4 }
                        };
-                       unsigned long ule_crc = ~0L, expected_crc;
+                       u32 ule_crc = ~0L, expected_crc;
                        if (priv->ule_dbit) {
                                /* Set D-bit for CRC32 verification,
                                 * if it was set originally. */
@@ -617,7 +617,7 @@ static void dvb_net_ule( struct net_devi
                                       *((u8 *)priv->ule_skb->tail - 2) << 8 |
                                       *((u8 *)priv->ule_skb->tail - 1);
                        if (ule_crc != expected_crc) {
-                               printk(KERN_WARNING "%lu: CRC32 check FAILED: 
%#lx / %#lx, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
+                               printk(KERN_WARNING "%lu: CRC32 check FAILED: 
%08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
                                       priv->ts_count, ule_crc, expected_crc, 
priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned 
short *)from_where : 0);
 
 #ifdef ULE_DEBUG
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/frontends/cx24123.c
--- a/drivers/media/dvb/frontends/cx24123.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/frontends/cx24123.c     Wed Oct 03 10:00:44 2007 +0100
@@ -549,8 +549,8 @@ static int cx24123_pll_calculate(struct 
        ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 
0x1ff;
        adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 
0x1f;
 
-       if (adiv == 0)
-               ndiv++;
+       if (adiv == 0 && ndiv > 0)
+               ndiv--;
 
        /* control bits 11, refdiv 11, charge pump polarity 1, charge pump 
current, ndiv, adiv */
        state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | 
(ndiv << 5) | adiv;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/frontends/dvb-pll.c
--- a/drivers/media/dvb/frontends/dvb-pll.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/frontends/dvb-pll.c     Wed Oct 03 10:00:44 2007 +0100
@@ -493,6 +493,9 @@ static int dvb_pll_sleep(struct dvb_fron
        int i;
        int result;
 
+       if (priv->i2c == NULL)
+               return -EINVAL;
+
        for (i = 0; i < priv->pll_desc->count; i++) {
                if (priv->pll_desc->entries[i].limit == 0)
                        break;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/frontends/lgdt330x.c
--- a/drivers/media/dvb/frontends/lgdt330x.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/frontends/lgdt330x.c    Wed Oct 03 10:00:44 2007 +0100
@@ -435,9 +435,6 @@ static int lgdt3302_read_status(struct d
                /* Test signal does not exist flag */
                /* as well as the AGC lock flag.   */
                *status |= FE_HAS_SIGNAL;
-       } else {
-               /* Without a signal all other status bits are meaningless */
-               return 0;
        }
 
        /*
@@ -500,9 +497,6 @@ static int lgdt3303_read_status(struct d
                /* Test input signal does not exist flag */
                /* as well as the AGC lock flag.   */
                *status |= FE_HAS_SIGNAL;
-       } else {
-               /* Without a signal all other status bits are meaningless */
-               return 0;
        }
 
        /* Carrier Recovery Lock Status Register */
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/cx88/cx88-cards.c
--- a/drivers/media/video/cx88/cx88-cards.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/cx88/cx88-cards.c     Wed Oct 03 10:00:44 2007 +0100
@@ -1465,7 +1465,7 @@ const unsigned int cx88_idcount = ARRAY_
 /* ----------------------------------------------------------------------- */
 /* some leadtek specific stuff                                             */
 
-static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
+static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
 {
        /* This is just for the "Winfast 2000XP Expert" board ATM; I don't have 
data on
         * any others.
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/cx88/cx88-dvb.c
--- a/drivers/media/video/cx88/cx88-dvb.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/cx88/cx88-dvb.c       Wed Oct 03 10:00:44 2007 +0100
@@ -576,7 +576,7 @@ static int dvb_register(struct cx8802_de
                                                 &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
                        dvb_pll_attach(dev->dvb.frontend, 0x60,
-                                      &dev->core->i2c_adap,
+                                      NULL,
                                       &dvb_pll_thomson_dtt7579);
                        break;
                }
@@ -587,7 +587,7 @@ static int dvb_register(struct cx8802_de
                                                   &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
                        dvb_pll_attach(dev->dvb.frontend, 0x60,
-                                      &dev->core->i2c_adap,
+                                      NULL,
                                       &dvb_pll_thomson_dtt7579);
                }
 #endif
@@ -600,7 +600,7 @@ static int dvb_register(struct cx8802_de
                                                 &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
                        dvb_pll_attach(dev->dvb.frontend, 0x61,
-                                      &dev->core->i2c_adap,
+                                      NULL,
                                       &dvb_pll_thomson_dtt7579);
                        break;
                }
@@ -611,7 +611,7 @@ static int dvb_register(struct cx8802_de
                                                   &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
                        dvb_pll_attach(dev->dvb.frontend, 0x61,
-                                      &dev->core->i2c_adap,
+                                      NULL,
                                       &dvb_pll_thomson_dtt7579);
                }
 #endif
@@ -623,7 +623,7 @@ static int dvb_register(struct cx8802_de
                                                 &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
                        dvb_pll_attach(dev->dvb.frontend, 0x61,
-                                      &dev->core->i2c_adap,
+                                      NULL,
                                       &dvb_pll_lg_z201);
                }
                break;
@@ -634,7 +634,7 @@ static int dvb_register(struct cx8802_de
                                                 &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
                        dvb_pll_attach(dev->dvb.frontend, 0x61,
-                                      &dev->core->i2c_adap,
+                                      NULL,
                                       &dvb_pll_unknown_1);
                }
                break;
@@ -757,7 +757,7 @@ static int dvb_register(struct cx8802_de
                                                 &dev->core->i2c_adap);
                if (dev->dvb.frontend != NULL) {
                        dvb_pll_attach(dev->dvb.frontend, 0x61,
-                                      &dev->core->i2c_adap,
+                                      NULL,
                                       &dvb_pll_tuv1236d);
                }
                break;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/ks0127.c
--- a/drivers/media/video/ks0127.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/ks0127.c      Wed Oct 03 10:00:44 2007 +0100
@@ -712,13 +712,13 @@ static int ks0127_command(struct i2c_cli
                *iarg = 0;
                status = ks0127_read(ks, KS_STAT);
                if (!(status & 0x20))            /* NOVID not set */
-                       *iarg = (*iarg & DECODER_STATUS_GOOD);
+                       *iarg = (*iarg | DECODER_STATUS_GOOD);
                if ((status & 0x01))                  /* CLOCK set */
-                       *iarg = (*iarg & DECODER_STATUS_COLOR);
+                       *iarg = (*iarg | DECODER_STATUS_COLOR);
                if ((status & 0x08))               /* PALDET set */
-                       *iarg = (*iarg & DECODER_STATUS_PAL);
+                       *iarg = (*iarg | DECODER_STATUS_PAL);
                else
-                       *iarg = (*iarg & DECODER_STATUS_NTSC);
+                       *iarg = (*iarg | DECODER_STATUS_NTSC);
                break;
 
        //Catch any unknown command
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/msp3400-driver.c
--- a/drivers/media/video/msp3400-driver.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/msp3400-driver.c      Wed Oct 03 10:00:44 2007 +0100
@@ -904,6 +904,8 @@ static int msp_attach(struct i2c_adapter
        state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo 
== 1;
        /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */
        state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2;
+       /* The msp343xG supports BTSC only and cannot do Automatic Standard 
Detection. */
+       state->force_btsc = msp_family == 3 && msp_revision == 'G' && 
msp_prod_hi == 3;
 
        state->opmode = opmode;
        if (state->opmode == OPMODE_AUTO) {
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/msp3400-driver.h
--- a/drivers/media/video/msp3400-driver.h      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/msp3400-driver.h      Wed Oct 03 10:00:44 2007 +0100
@@ -64,6 +64,7 @@ struct msp_state {
        u8 has_sound_processing;
        u8 has_virtual_dolby_surround;
        u8 has_dolby_pro_logic;
+       u8 force_btsc;
 
        int radio;
        int opmode;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/msp3400-kthreads.c
--- a/drivers/media/video/msp3400-kthreads.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/msp3400-kthreads.c    Wed Oct 03 10:00:44 2007 +0100
@@ -960,9 +960,10 @@ int msp34xxg_thread(void *data)
 
                /* setup the chip*/
                msp34xxg_reset(client);
-               state->std = state->radio ? 0x40 : msp_standard;
+               state->std = state->radio ? 0x40 :
+                       (state->force_btsc && msp_standard == 1) ? 32 : 
msp_standard;
+               msp_write_dem(client, 0x20, state->std);
                /* start autodetect */
-               msp_write_dem(client, 0x20, state->std);
                if (state->std != 1)
                        goto unmute;
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/pvrusb2/Kconfig
--- a/drivers/media/video/pvrusb2/Kconfig       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/pvrusb2/Kconfig       Wed Oct 03 10:00:44 2007 +0100
@@ -25,14 +25,9 @@ config VIDEO_PVRUSB2_24XXX
          form "24xxx" (leading prefix of "24" followed by 3 digits).
          To see if you may need this option, examine the white
          sticker on the underside of your device.  Enabling this
-         option will not harm support for older devices, however it
-         is a separate option because of the experimental nature of
-         this new feature.
+         option will not harm support for older devices.
 
-         If you are in doubt, say N.
-
-         Note: This feature is _very_ experimental.  You have been
-         warned.
+         If you are in doubt, say Y.
 
 config VIDEO_PVRUSB2_SYSFS
        bool "pvrusb2 sysfs support (EXPERIMENTAL)"
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/pvrusb2/pvrusb2-ctrl.c
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c        Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c        Wed Oct 03 10:00:44 
2007 +0100
@@ -43,12 +43,17 @@ int pvr2_ctrl_set_mask_value(struct pvr2
                        if (cptr->info->type == pvr2_ctl_bitmask) {
                                mask &= cptr->info->def.type_bitmask.valid_bits;
                        } else if (cptr->info->type == pvr2_ctl_int) {
-                               if (val < cptr->info->def.type_int.min_value) {
-                                       break;
+                               int lim;
+                               lim = cptr->info->def.type_int.min_value;
+                               if (cptr->info->get_min_value) {
+                                       cptr->info->get_min_value(cptr,&lim);
                                }
-                               if (val > cptr->info->def.type_int.max_value) {
-                                       break;
+                               if (val < lim) break;
+                               lim = cptr->info->def.type_int.max_value;
+                               if (cptr->info->get_max_value) {
+                                       cptr->info->get_max_value(cptr,&lim);
                                }
+                               if (val > lim) break;
                        } else if (cptr->info->type == pvr2_ctl_enum) {
                                if (val >= cptr->info->def.type_enum.count) {
                                        break;
@@ -91,7 +96,9 @@ int pvr2_ctrl_get_max(struct pvr2_ctrl *
        int ret = 0;
        if (!cptr) return 0;
        LOCK_TAKE(cptr->hdw->big_lock); do {
-               if (cptr->info->type == pvr2_ctl_int) {
+               if (cptr->info->get_max_value) {
+                       cptr->info->get_max_value(cptr,&ret);
+               } else if (cptr->info->type == pvr2_ctl_int) {
                        ret = cptr->info->def.type_int.max_value;
                }
        } while(0); LOCK_GIVE(cptr->hdw->big_lock);
@@ -105,7 +112,9 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *
        int ret = 0;
        if (!cptr) return 0;
        LOCK_TAKE(cptr->hdw->big_lock); do {
-               if (cptr->info->type == pvr2_ctl_int) {
+               if (cptr->info->get_min_value) {
+                       cptr->info->get_min_value(cptr,&ret);
+               } else if (cptr->info->type == pvr2_ctl_int) {
                        ret = cptr->info->def.type_int.min_value;
                }
        } while(0); LOCK_GIVE(cptr->hdw->big_lock);
diff -r aafef975e518 -r 3e8752eb6d9c 
drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h        Tue Oct 02 
09:52:15 2007 +0100
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h        Wed Oct 03 
10:00:44 2007 +0100
@@ -107,6 +107,8 @@ struct pvr2_ctl_info {
 
        /* Control's implementation */
        pvr2_ctlf_get_value get_value;      /* Get its value */
+       pvr2_ctlf_get_value get_min_value;  /* Get minimum allowed value */
+       pvr2_ctlf_get_value get_max_value;  /* Get maximum allowed value */
        pvr2_ctlf_set_value set_value;      /* Set its value */
        pvr2_ctlf_val_to_sym val_to_sym;    /* Custom convert value->symbol */
        pvr2_ctlf_sym_to_val sym_to_val;    /* Custom convert symbol->value */
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c Wed Oct 03 10:00:44 2007 +0100
@@ -362,6 +362,30 @@ static int ctrl_freq_set(struct pvr2_ctr
        return 0;
 }
 
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+static int ctrl_hres_max_get(struct pvr2_ctrl *cptr,int *vp)
+{
+       /* If we're dealing with a 24xxx device, force the horizontal
+          maximum to be 720 no matter what, since we can't get the device
+          to work properly with any other value.  Otherwise just return
+          the normal value. */
+       *vp = cptr->info->def.type_int.max_value;
+       if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
+       return 0;
+}
+
+static int ctrl_hres_min_get(struct pvr2_ctrl *cptr,int *vp)
+{
+       /* If we're dealing with a 24xxx device, force the horizontal
+          minimum to be 720 no matter what, since we can't get the device
+          to work properly with any other value.  Otherwise just return
+          the normal value. */
+       *vp = cptr->info->def.type_int.min_value;
+       if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
+       return 0;
+}
+#endif
+
 static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
 {
        return cptr->hdw->enc_stale != 0;
@@ -720,6 +744,12 @@ static const struct pvr2_ctl_info contro
                .default_value = 720,
                DEFREF(res_hor),
                DEFINT(320,720),
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+               /* Hook in check for clamp on horizontal resolution in
+                  order to avoid unsolved problem involving cx25840. */
+               .get_max_value = ctrl_hres_max_get,
+               .get_min_value = ctrl_hres_min_get,
+#endif
        },{
                .desc = "Vertical capture resolution",
                .name = "resolution_ver",
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/pvrusb2/pvrusb2-v4l2.c
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c        Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c        Wed Oct 03 10:00:44 
2007 +0100
@@ -22,6 +22,7 @@
 
 #include <linux/kernel.h>
 #include <linux/version.h>
+#include <linux/videodev.h>
 #include "pvrusb2-context.h"
 #include "pvrusb2-hdw.h"
 #include "pvrusb2.h"
@@ -31,25 +32,21 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 
+/* Mike Isely <isely@xxxxxxxxx> 23-Sep-2006 - This function is prototyped
+ * only for V4L1 but is implemented regardless of the V4L1 compatibility
+ * option state.  V4L2 has no replacement for this and we need it.  For now
+ * copy the prototype here so we can avoid the compiler warning. */
+extern struct video_device* video_devdata(struct file*);
+
 struct pvr2_v4l2_dev;
 struct pvr2_v4l2_fh;
 struct pvr2_v4l2;
 
-/* V4L no longer provide the ability to set / get a private context pointer
-   (i.e. video_get_drvdata / video_set_drvdata), which means we have to
-   concoct our own context locating mechanism.  Supposedly this is intended
-   to simplify driver implementation.  It's not clear to me how that can
-   possibly be true.  Our solution here is to maintain a lookup table of
-   our context instances, indexed by the minor device number of the V4L
-   device.  See pvr2_v4l2_open() for some implications of this approach. */
-static struct pvr2_v4l2_dev *devices[256];
-static DEFINE_MUTEX(device_lock);
 
 struct pvr2_v4l2_dev {
        struct pvr2_v4l2 *v4lp;
        struct video_device *vdev;
        struct pvr2_context_stream *stream;
-       int ctxt_idx;
        enum pvr2_config config;
 };
 
@@ -459,18 +456,26 @@ static int pvr2_v4l2_do_ioctl(struct ino
                ret = 0;
                switch(vf->type) {
                case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
+                       int lmin,lmax;
+                       struct pvr2_ctrl *hcp,*vcp;
                        int h = vf->fmt.pix.height;
                        int w = vf->fmt.pix.width;
-
-                       if (h < 200) {
-                               h = 200;
-                       } else if (h > 625) {
-                               h = 625;
-                       }
-                       if (w < 320) {
-                               w = 320;
-                       } else if (w > 720) {
-                               w = 720;
+                       hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES);
+                       vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES);
+
+                       lmin = pvr2_ctrl_get_min(hcp);
+                       lmax = pvr2_ctrl_get_max(hcp);
+                       if (w < lmin) {
+                               w = lmin;
+                       } else if (w > lmax) {
+                               w = lmax;
+                       }
+                       lmin = pvr2_ctrl_get_min(vcp);
+                       lmax = pvr2_ctrl_get_max(vcp);
+                       if (h < lmin) {
+                               h = lmin;
+                       } else if (h > lmax) {
+                               h = lmax;
                        }
 
                        memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
@@ -479,14 +484,8 @@ static int pvr2_v4l2_do_ioctl(struct ino
                        vf->fmt.pix.height = h;
 
                        if (cmd == VIDIOC_S_FMT) {
-                               pvr2_ctrl_set_value(
-                                       pvr2_hdw_get_ctrl_by_id(hdw,
-                                                               PVR2_CID_HRES),
-                                       vf->fmt.pix.width);
-                               pvr2_ctrl_set_value(
-                                       pvr2_hdw_get_ctrl_by_id(hdw,
-                                                               PVR2_CID_VRES),
-                                       vf->fmt.pix.height);
+                               pvr2_ctrl_set_value(hcp,vf->fmt.pix.width);
+                               pvr2_ctrl_set_value(vcp,vf->fmt.pix.height);
                        }
                } break;
                case V4L2_BUF_TYPE_VBI_CAPTURE:
@@ -703,12 +702,6 @@ static void pvr2_v4l2_dev_destroy(struct
 {
        printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n",
               dip->vdev->minor,pvr2_config_get_name(dip->config));
-       if (dip->ctxt_idx >= 0) {
-               mutex_lock(&device_lock);
-               devices[dip->ctxt_idx] = NULL;
-               dip->ctxt_idx = -1;
-               mutex_unlock(&device_lock);
-       }
        video_unregister_device(dip->vdev);
 }
 
@@ -800,33 +793,10 @@ static int pvr2_v4l2_open(struct inode *
        struct pvr2_v4l2 *vp;
        struct pvr2_hdw *hdw;
 
-       mutex_lock(&device_lock);
-       /* MCI 7-Jun-2006 Even though we're just doing what amounts to an
-          atomic read of the device mapping array here, we still need the
-          mutex.  The problem is that there is a tiny race possible when
-          we register the device.  We can't update the device mapping
-          array until after the device has been registered, owing to the
-          fact that we can't know the minor device number until after the
-          registration succeeds.  And if another thread tries to open the
-          device in the window of time after registration but before the
-          map is updated, then it will get back an erroneous null pointer
-          and the open will result in a spurious failure.  The only way to
-          prevent that is to (a) be inside the mutex here before we access
-          the array, and (b) cover the entire registration process later
-          on with this same mutex.  Thus if we get inside the mutex here,
-          then we can be assured that the registration process actually
-          completed correctly.  This is an unhappy complication from the
-          use of global data in a driver that lives in a preemptible
-          environment.  It sure would be nice if the video device itself
-          had a means for storing and retrieving a local context pointer.
-          Oh wait.  It did.  But now it's gone.  Silly me. */
-       {
-               unsigned int midx = iminor(file->f_dentry->d_inode);
-               if (midx < sizeof(devices)/sizeof(devices[0])) {
-                       dip = devices[midx];
-               }
-       }
-       mutex_unlock(&device_lock);
+       {
+               struct video_device *vdev = video_devdata(file);
+               dip = (struct pvr2_v4l2_dev *)video_get_drvdata(vdev);
+       }
 
        if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
 
@@ -1066,7 +1036,7 @@ static void pvr2_v4l2_dev_init(struct pv
 
        memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
        dip->vdev->release = video_device_release;
-       mutex_lock(&device_lock);
+       video_set_drvdata(dip->vdev,dip);
 
        mindevnum = -1;
        unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
@@ -1081,12 +1051,6 @@ static void pvr2_v4l2_dev_init(struct pv
                       dip->vdev->minor,pvr2_config_get_name(dip->config));
        }
 
-       if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
-           (devices[dip->vdev->minor] == NULL)) {
-               dip->ctxt_idx = dip->vdev->minor;
-               devices[dip->ctxt_idx] = dip;
-       }
-       mutex_unlock(&device_lock);
 
        pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
                                        dip->vdev->minor);
@@ -1100,7 +1064,6 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struc
        vp = kmalloc(sizeof(*vp),GFP_KERNEL);
        if (!vp) return vp;
        memset(vp,0,sizeof(*vp));
-       vp->video_dev.ctxt_idx = -1;
        pvr2_channel_init(&vp->channel,mnp);
        pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/saa7134/saa7134-dvb.c
--- a/drivers/media/video/saa7134/saa7134-dvb.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/saa7134/saa7134-dvb.c Wed Oct 03 10:00:44 2007 +0100
@@ -1158,13 +1158,13 @@ static int dvb_init(struct saa7134_dev *
        case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
                dev->dvb.frontend = nxt200x_attach(&avertvhda180, 
&dev->i2c_adap);
                if (dev->dvb.frontend) {
-                       dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, 
&dvb_pll_tdhu2);
+                       dvb_pll_attach(dev->dvb.frontend, 0x61, NULL, 
&dvb_pll_tdhu2);
                }
                break;
        case SAA7134_BOARD_KWORLD_ATSC110:
                dev->dvb.frontend = nxt200x_attach(&kworldatsc110, 
&dev->i2c_adap);
                if (dev->dvb.frontend) {
-                       dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap, 
&dvb_pll_tuv1236d);
+                       dvb_pll_attach(dev->dvb.frontend, 0x61, NULL, 
&dvb_pll_tuv1236d);
                }
                break;
 #endif
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/tuner-simple.c
--- a/drivers/media/video/tuner-simple.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/tuner-simple.c        Wed Oct 03 10:00:44 2007 +0100
@@ -108,6 +108,7 @@ static int tuner_stereo(struct i2c_clien
                case TUNER_PHILIPS_FM1216ME_MK3:
                case TUNER_PHILIPS_FM1236_MK3:
                case TUNER_PHILIPS_FM1256_IH3:
+               case TUNER_LG_NTSC_TAPE:
                        stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
                        break;
                default:
@@ -419,6 +420,7 @@ static void default_set_radio_freq(struc
        case TUNER_PHILIPS_FM1216ME_MK3:
        case TUNER_PHILIPS_FM1236_MK3:
        case TUNER_PHILIPS_FMD1216ME_MK3:
+       case TUNER_LG_NTSC_TAPE:
                buffer[3] = 0x19;
                break;
        case TUNER_TNF_5335MF:
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/tuner-types.c
--- a/drivers/media/video/tuner-types.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/tuner-types.c Wed Oct 03 10:00:44 2007 +0100
@@ -671,16 +671,6 @@ static struct tuner_params tuner_panason
        },
 };
 
-/* ------------ TUNER_LG_NTSC_TAPE - LGINNOTEK NTSC ------------ */
-
-static struct tuner_params tuner_lg_ntsc_tape_params[] = {
-       {
-               .type   = TUNER_PARAM_TYPE_NTSC,
-               .ranges = tuner_fm1236_mk3_ntsc_ranges,
-               .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
-       },
-};
-
 /* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */
 
 static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = {
@@ -1331,8 +1321,8 @@ struct tunertype tuners[] = {
        },
        [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
                .name   = "LG NTSC (TAPE series)",
-               .params = tuner_lg_ntsc_tape_params,
-               .count  = ARRAY_SIZE(tuner_lg_ntsc_tape_params),
+               .params = tuner_fm1236_mk3_params,
+               .count  = ARRAY_SIZE(tuner_fm1236_mk3_params),
        },
        [TUNER_TNF_8831BGFF] = { /* Philips PAL */
                .name   = "Tenna TNF 8831 BGFF)",
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/tveeprom.c
--- a/drivers/media/video/tveeprom.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/tveeprom.c    Wed Oct 03 10:00:44 2007 +0100
@@ -184,7 +184,7 @@ hauppauge_tuner[] =
        { TUNER_ABSENT,        "Thompson DTT757"},
        /* 80-89 */
        { TUNER_ABSENT,        "Philips FQ1216LME MK3"},
-       { TUNER_ABSENT,        "LG TAPC G701D"},
+       { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"},
        { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
        { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
        { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
diff -r aafef975e518 -r 3e8752eb6d9c 
drivers/media/video/usbvideo/quickcam_messenger.h
--- a/drivers/media/video/usbvideo/quickcam_messenger.h Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/media/video/usbvideo/quickcam_messenger.h Wed Oct 03 10:00:44 
2007 +0100
@@ -35,27 +35,13 @@ struct rgb {
 };
 
 struct bayL0 {
-#ifdef __BIG_ENDIAN
-       u8 r;
-       u8 g;
-#elif __LITTLE_ENDIAN
        u8 g;
        u8 r;
-#else
-#error not byte order defined
-#endif
 };
 
 struct bayL1 {
-#ifdef __BIG_ENDIAN
-       u8 g;
-       u8 b;
-#elif __LITTLE_ENDIAN
        u8 b;
        u8 g;
-#else
-#error not byte order defined
-#endif
 };
 
 struct cam_size {
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/video-buf.c
--- a/drivers/media/video/video-buf.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/video-buf.c   Wed Oct 03 10:00:44 2007 +0100
@@ -695,6 +695,7 @@ videobuf_qbuf(struct videobuf_queue *q,
                goto done;
        }
        if (buf->state == STATE_QUEUED ||
+           buf->state == STATE_PREPARED ||
            buf->state == STATE_ACTIVE) {
                dprintk(1,"qbuf: buffer is already queued or active.\n");
                goto done;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/videodev.c
--- a/drivers/media/video/videodev.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/videodev.c    Wed Oct 03 10:00:44 2007 +0100
@@ -739,13 +739,13 @@ static int __video_do_ioctl(struct inode
        case VIDIOC_DQBUF:
        {
                struct v4l2_buffer *p=arg;
-               if (!vfd->vidioc_qbuf)
+               if (!vfd->vidioc_dqbuf)
                        break;
                ret = check_fmt (vfd, p->type);
                if (ret)
                        break;
 
-               ret=vfd->vidioc_qbuf(file, fh, p);
+               ret=vfd->vidioc_dqbuf(file, fh, p);
                if (!ret)
                        dbgbuf(cmd,vfd,p);
                break;
@@ -836,7 +836,7 @@ static int __video_do_ioctl(struct inode
                        break;
                }
 
-               if (index<=0 || index >= vfd->tvnormsize) {
+               if (index < 0 || index >= vfd->tvnormsize) {
                        ret=-EINVAL;
                        break;
                }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/bonding/bond_main.c   Wed Oct 03 10:00:44 2007 +0100
@@ -3547,7 +3547,7 @@ static int bond_do_ioctl(struct net_devi
                        mii->val_out = 0;
                        read_lock_bh(&bond->lock);
                        read_lock(&bond->curr_slave_lock);
-                       if (bond->curr_active_slave) {
+                       if (netif_carrier_ok(bond->dev)) {
                                mii->val_out = BMSR_LSTATUS;
                        }
                        read_unlock(&bond->curr_slave_lock);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/e1000/e1000_main.c    Wed Oct 03 10:00:44 2007 +0100
@@ -4683,6 +4683,9 @@ e1000_suspend(struct pci_dev *pdev, pm_m
        if (adapter->hw.phy_type == e1000_phy_igp_3)
                e1000_phy_powerdown_workaround(&adapter->hw);
 
+       if (netif_running(netdev))
+               e1000_free_irq(adapter);
+
        /* Release control of h/w to f/w.  If f/w is AMT enabled, this
         * would have already happened in close and is redundant. */
        e1000_release_hw_control(adapter);
@@ -4710,6 +4713,10 @@ e1000_resume(struct pci_dev *pdev)
        pci_enable_wake(pdev, PCI_D3hot, 0);
        pci_enable_wake(pdev, PCI_D3cold, 0);
 
+       if (netif_running(netdev) && (ret_val = e1000_request_irq(adapter)))
+               return ret_val;
+
+       e1000_power_up_phy(adapter);
        e1000_reset(adapter);
        E1000_WRITE_REG(&adapter->hw, WUS, ~0);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/forcedeth.c
--- a/drivers/net/forcedeth.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/forcedeth.c   Wed Oct 03 10:00:44 2007 +0100
@@ -2692,11 +2692,13 @@ static int nv_request_irq(struct net_dev
        }
        if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
                if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
+                       pci_intx(np->pci_dev, 0);
                        np->msi_flags |= NV_MSI_ENABLED;
                        if ((!intr_test && request_irq(np->pci_dev->irq, 
&nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) ||
                            (intr_test && request_irq(np->pci_dev->irq, 
&nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) {
                                printk(KERN_INFO "forcedeth: request_irq failed 
%d\n", ret);
                                pci_disable_msi(np->pci_dev);
+                               pci_intx(np->pci_dev, 1);
                                np->msi_flags &= ~NV_MSI_ENABLED;
                                goto out_err;
                        }
@@ -2739,6 +2741,7 @@ static void nv_free_irq(struct net_devic
                free_irq(np->pci_dev->irq, dev);
                if (np->msi_flags & NV_MSI_ENABLED) {
                        pci_disable_msi(np->pci_dev);
+                       pci_intx(np->pci_dev, 1);
                        np->msi_flags &= ~NV_MSI_ENABLED;
                }
        }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/lp486e.c
--- a/drivers/net/lp486e.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/lp486e.c      Wed Oct 03 10:00:44 2007 +0100
@@ -442,16 +442,16 @@ init_rx_bufs(struct net_device *dev, int
                if (rbd) {
                        rbd->pad = 0;
                        rbd->count = 0;
-                       rbd->skb = dev_alloc_skb(RX_SKB_SIZE);
+                       rbd->skb = dev_alloc_skb(RX_SKBSIZE);
                        if (!rbd->skb) {
                                printk("dev_alloc_skb failed");
                        }
                        rbd->next = rfd->rbd;
                        if (i) {
                                rfd->rbd->prev = rbd;
-                               rbd->size = RX_SKB_SIZE;
+                               rbd->size = RX_SKBSIZE;
                        } else {
-                               rbd->size = (RX_SKB_SIZE | RBD_EL);
+                               rbd->size = (RX_SKBSIZE | RBD_EL);
                                lp->rbd_tail = rbd;
                        }
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/mv643xx_eth.c
--- a/drivers/net/mv643xx_eth.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/mv643xx_eth.c Wed Oct 03 10:00:44 2007 +0100
@@ -385,7 +385,7 @@ static int mv643xx_eth_receive_queue(str
        struct pkt_info pkt_info;
 
        while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
-               dma_unmap_single(NULL, pkt_info.buf_ptr, RX_SKB_SIZE,
+               dma_unmap_single(NULL, pkt_info.buf_ptr, ETH_RX_SKB_SIZE,
                                                        DMA_FROM_DEVICE);
                mp->rx_desc_count--;
                received_packets++;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/sky2.c
--- a/drivers/net/sky2.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/sky2.c        Wed Oct 03 10:00:44 2007 +0100
@@ -106,6 +106,7 @@ static const struct pci_device_id sky2_i
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
        { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },    /* DGE-560T */
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) },    /* DGE-550SX */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
@@ -117,10 +118,17 @@ static const struct pci_device_id sky2_i
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) },
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) },
        { 0 }
 };
 
@@ -670,7 +678,7 @@ static void sky2_mac_init(struct sky2_hw
        sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
 
        if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
-               sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
+               sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 512/8);
                sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
                if (hw->dev[port]->mtu > ETH_DATA_LEN) {
                        /* set Tx GMAC FIFO Almost Empty Threshold */
@@ -682,16 +690,10 @@ static void sky2_mac_init(struct sky2_hw
 
 }
 
-/* Assign Ram Buffer allocation.
- * start and end are in units of 4k bytes
- * ram registers are in units of 64bit words
- */
-static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
-{
-       u32 start, end;
-
-       start = startk * 4096/8;
-       end = (endk * 4096/8) - 1;
+/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end)
+{
+       pr_debug(PFX "q %d %#x %#x\n", q, start, end);
 
        sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
        sky2_write32(hw, RB_ADDR(q, RB_START), start);
@@ -700,7 +702,7 @@ static void sky2_ramset(struct sky2_hw *
        sky2_write32(hw, RB_ADDR(q, RB_RP), start);
 
        if (q == Q_R1 || q == Q_R2) {
-               u32 space = (endk - startk) * 4096/8;
+               u32 space = end - start + 1;
                u32 tp = space - space/4;
 
                /* On receive queue's set the thresholds
@@ -1082,19 +1084,16 @@ static int sky2_up(struct net_device *de
 
        sky2_mac_init(hw, port);
 
-       /* Determine available ram buffer space (in 4K blocks).
-        * Note: not sure about the FE setting below yet
-        */
-       if (hw->chip_id == CHIP_ID_YUKON_FE)
-               ramsize = 4;
+       /* Determine available ram buffer space in qwords.  */
+       ramsize = sky2_read8(hw, B2_E_0) * 4096/8;
+
+       if (ramsize > 6*1024/8)
+               rxspace = ramsize - (ramsize + 2) / 3;
        else
-               ramsize = sky2_read8(hw, B2_E_0);
-
-       /* Give transmitter one third (rounded up) */
-       rxspace = ramsize - (ramsize + 2) / 3;
-
-       sky2_ramset(hw, rxqaddr[port], 0, rxspace);
-       sky2_ramset(hw, txqaddr[port], rxspace, ramsize);
+               rxspace = ramsize / 2;
+
+       sky2_ramset(hw, rxqaddr[port], 0, rxspace-1);
+       sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1);
 
        /* Make sure SyncQ is disabled */
        sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
@@ -1421,6 +1420,11 @@ static int sky2_down(struct net_device *
        /* Stop more packets from being queued */
        netif_stop_queue(dev);
 
+       /* Disable port IRQ */
+       imask = sky2_read32(hw, B0_IMSK);
+       imask &= ~portirq_msk[port];
+       sky2_write32(hw, B0_IMSK, imask);
+
        sky2_phy_reset(hw, port);
 
        /* Stop transmitter */
@@ -1463,11 +1467,6 @@ static int sky2_down(struct net_device *
 
        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
        sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
-
-       /* Disable port IRQ */
-       imask = sky2_read32(hw, B0_IMSK);
-       imask &= ~portirq_msk[port];
-       sky2_write32(hw, B0_IMSK, imask);
 
        /* turn off LED's */
        sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
@@ -1679,12 +1678,12 @@ static void sky2_phy_intr(struct sky2_hw
        struct sky2_port *sky2 = netdev_priv(dev);
        u16 istatus, phystat;
 
+       if (!netif_running(dev))
+               return;
+
        spin_lock(&sky2->phy_lock);
        istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
        phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
-
-       if (!netif_running(dev))
-               goto out;
 
        if (netif_msg_intr(sky2))
                printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
@@ -2737,6 +2736,14 @@ static int sky2_set_mac_address(struct n
        return 0;
 }
 
+static void inline sky2_add_filter(u8 filter[8], const u8 *addr)
+{
+       u32 bit;
+
+       bit = ether_crc(ETH_ALEN, addr) & 63;
+       filter[bit >> 3] |= 1 << (bit & 7);
+}
+
 static void sky2_set_multicast(struct net_device *dev)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
@@ -2745,6 +2752,7 @@ static void sky2_set_multicast(struct ne
        struct dev_mc_list *list = dev->mc_list;
        u16 reg;
        u8 filter[8];
+       static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 
0x1 };
 
        memset(filter, 0, sizeof(filter));
 
@@ -2755,16 +2763,17 @@ static void sky2_set_multicast(struct ne
                reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
        else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16)     /* all 
multicast */
                memset(filter, 0xff, sizeof(filter));
-       else if (dev->mc_count == 0)    /* no multicast */
+       else if (dev->mc_count == 0 && !sky2->rx_pause)
                reg &= ~GM_RXCR_MCF_ENA;
        else {
                int i;
                reg |= GM_RXCR_MCF_ENA;
 
-               for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
-                       u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
-                       filter[bit / 8] |= 1 << (bit % 8);
-               }
+               if (sky2->rx_pause)
+                       sky2_add_filter(filter, pause_mc_addr);
+
+               for (i = 0; list && i < dev->mc_count; i++, list = list->next)
+                       sky2_add_filter(filter, list->dmi_addr);
        }
 
        gma_write16(hw, port, GM_MC_ADDR_H1,
@@ -3200,6 +3209,8 @@ static int __devinit sky2_test_msi(struc
        struct pci_dev *pdev = hw->pdev;
        int err;
 
+       init_waitqueue_head (&hw->msi_wait);
+
        sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
 
        err = request_irq(pdev->irq, sky2_test_intr, IRQF_SHARED, DRV_NAME, hw);
@@ -3209,18 +3220,15 @@ static int __devinit sky2_test_msi(struc
                return err;
        }
 
-       init_waitqueue_head (&hw->msi_wait);
-
        sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
-       wmb();
+       sky2_read8(hw, B0_CTST);
 
        wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10);
 
        if (!hw->msi_detected) {
                /* MSI test failed, go back to INTx mode */
-               printk(KERN_WARNING PFX "%s: No interrupt was generated using 
MSI, "
-                      "switching to INTx mode. Please report this failure to "
-                      "the PCI maintainer and include system chipset 
information.\n",
+               printk(KERN_INFO PFX "%s: No interrupt generated using MSI, "
+                      "switching to INTx mode.\n",
                       pci_name(pdev));
 
                err = -EOPNOTSUPP;
@@ -3228,6 +3236,7 @@ static int __devinit sky2_test_msi(struc
        }
 
        sky2_write32(hw, B0_IMSK, 0);
+       sky2_read32(hw, B0_IMSK);
 
        free_irq(pdev->irq, hw);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/sky2.h
--- a/drivers/net/sky2.h        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/sky2.h        Wed Oct 03 10:00:44 2007 +0100
@@ -1566,7 +1566,7 @@ enum {
 
        GMR_FS_ANY_ERR  = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
                          GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
-                         GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
+                         GMR_FS_MII_ERR | GMR_FS_GOOD_FC | GMR_FS_BAD_FC |
                          GMR_FS_UN_SIZE | GMR_FS_JABBER,
 };
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/sunhme.c
--- a/drivers/net/sunhme.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/sunhme.c      Wed Oct 03 10:00:44 2007 +0100
@@ -3012,6 +3012,11 @@ static int __devinit happy_meal_pci_prob
 #endif
 
        err = -ENODEV;
+
+       if (pci_enable_device(pdev))
+               goto err_out;
+       pci_set_master(pdev);
+
        if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
                qp = quattro_pci_find(pdev);
                if (qp == NULL)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/tg3.c
--- a/drivers/net/tg3.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/tg3.c Wed Oct 03 10:00:44 2007 +0100
@@ -6889,8 +6889,10 @@ static int tg3_open(struct net_device *d
        tg3_full_lock(tp, 0);
 
        err = tg3_set_power_state(tp, PCI_D0);
-       if (err)
+       if (err) {
+               tg3_full_unlock(tp);
                return err;
+       }
 
        tg3_disable_ints(tp);
        tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h    Wed Oct 03 10:00:44 2007 +0100
@@ -21,7 +21,7 @@
 #define PFX                            KBUILD_MODNAME ": "
 
 #define BCM43xx_SWITCH_CORE_MAX_RETRIES        50
-#define BCM43xx_IRQWAIT_MAX_RETRIES    50
+#define BCM43xx_IRQWAIT_MAX_RETRIES    100
 
 #define BCM43xx_IO_SIZE                        8192
 
@@ -33,14 +33,18 @@
 #define BCM43xx_PCICFG_ICR             0x94
 
 /* MMIO offsets */
-#define BCM43xx_MMIO_DMA1_REASON       0x20
-#define BCM43xx_MMIO_DMA1_IRQ_MASK     0x24
-#define BCM43xx_MMIO_DMA2_REASON       0x28
-#define BCM43xx_MMIO_DMA2_IRQ_MASK     0x2C
-#define BCM43xx_MMIO_DMA3_REASON       0x30
-#define BCM43xx_MMIO_DMA3_IRQ_MASK     0x34
-#define BCM43xx_MMIO_DMA4_REASON       0x38
-#define BCM43xx_MMIO_DMA4_IRQ_MASK     0x3C
+#define BCM43xx_MMIO_DMA0_REASON       0x20
+#define BCM43xx_MMIO_DMA0_IRQ_MASK     0x24
+#define BCM43xx_MMIO_DMA1_REASON       0x28
+#define BCM43xx_MMIO_DMA1_IRQ_MASK     0x2C
+#define BCM43xx_MMIO_DMA2_REASON       0x30
+#define BCM43xx_MMIO_DMA2_IRQ_MASK     0x34
+#define BCM43xx_MMIO_DMA3_REASON       0x38
+#define BCM43xx_MMIO_DMA3_IRQ_MASK     0x3C
+#define BCM43xx_MMIO_DMA4_REASON       0x40
+#define BCM43xx_MMIO_DMA4_IRQ_MASK     0x44
+#define BCM43xx_MMIO_DMA5_REASON       0x48
+#define BCM43xx_MMIO_DMA5_IRQ_MASK     0x4C
 #define BCM43xx_MMIO_STATUS_BITFIELD   0x120
 #define BCM43xx_MMIO_STATUS2_BITFIELD  0x124
 #define BCM43xx_MMIO_GEN_IRQ_REASON    0x128
@@ -56,14 +60,27 @@
 #define BCM43xx_MMIO_XMITSTAT_1                0x174
 #define BCM43xx_MMIO_REV3PLUS_TSF_LOW  0x180 /* core rev >= 3 only */
 #define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
-#define BCM43xx_MMIO_DMA1_BASE         0x200
-#define BCM43xx_MMIO_DMA2_BASE         0x220
-#define BCM43xx_MMIO_DMA3_BASE         0x240
-#define BCM43xx_MMIO_DMA4_BASE         0x260
+
+/* 32-bit DMA */
+#define BCM43xx_MMIO_DMA32_BASE0       0x200
+#define BCM43xx_MMIO_DMA32_BASE1       0x220
+#define BCM43xx_MMIO_DMA32_BASE2       0x240
+#define BCM43xx_MMIO_DMA32_BASE3       0x260
+#define BCM43xx_MMIO_DMA32_BASE4       0x280
+#define BCM43xx_MMIO_DMA32_BASE5       0x2A0
+/* 64-bit DMA */
+#define BCM43xx_MMIO_DMA64_BASE0       0x200
+#define BCM43xx_MMIO_DMA64_BASE1       0x240
+#define BCM43xx_MMIO_DMA64_BASE2       0x280
+#define BCM43xx_MMIO_DMA64_BASE3       0x2C0
+#define BCM43xx_MMIO_DMA64_BASE4       0x300
+#define BCM43xx_MMIO_DMA64_BASE5       0x340
+/* PIO */
 #define BCM43xx_MMIO_PIO1_BASE         0x300
 #define BCM43xx_MMIO_PIO2_BASE         0x310
 #define BCM43xx_MMIO_PIO3_BASE         0x320
 #define BCM43xx_MMIO_PIO4_BASE         0x330
+
 #define BCM43xx_MMIO_PHY_VER           0x3E0
 #define BCM43xx_MMIO_PHY_RADIO         0x3E2
 #define BCM43xx_MMIO_ANTENNA           0x3E8
@@ -233,8 +250,14 @@
 #define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK  0x20000
 
 /* sbtmstatehigh state flags */
-#define BCM43xx_SBTMSTATEHIGH_SERROR           0x1
-#define BCM43xx_SBTMSTATEHIGH_BUSY             0x4
+#define BCM43xx_SBTMSTATEHIGH_SERROR           0x00000001
+#define BCM43xx_SBTMSTATEHIGH_BUSY             0x00000004
+#define BCM43xx_SBTMSTATEHIGH_TIMEOUT          0x00000020
+#define BCM43xx_SBTMSTATEHIGH_COREFLAGS                0x1FFF0000
+#define BCM43xx_SBTMSTATEHIGH_DMA64BIT         0x10000000
+#define BCM43xx_SBTMSTATEHIGH_GATEDCLK         0x20000000
+#define BCM43xx_SBTMSTATEHIGH_BISTFAILED       0x40000000
+#define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE     0x80000000
 
 /* sbimstate flags */
 #define BCM43xx_SBIMSTATE_IB_ERROR             0x20000
@@ -282,6 +305,13 @@
 #define BCM43xx_SBF_NO_SSID_BCAST      0x08000000
 #define BCM43xx_SBF_TIME_UPDATE                0x10000000
 #define BCM43xx_SBF_80000000           0x80000000 /*FIXME: fix name*/
+
+/* Microcode */
+#define BCM43xx_UCODE_REVISION         0x0000
+#define BCM43xx_UCODE_PATCHLEVEL       0x0002
+#define BCM43xx_UCODE_DATE             0x0004
+#define BCM43xx_UCODE_TIME             0x0006
+#define BCM43xx_UCODE_STATUS           0x0040
 
 /* MicrocodeFlagsBitfield (addr + lo-word values?)*/
 #define BCM43xx_UCODEFLAGS_OFFSET      0x005E
@@ -504,6 +534,12 @@ struct bcm43xx_phyinfo {
         * This lock is only used by bcm43xx_phy_{un}lock()
         */
        spinlock_t lock;
+
+       /* Firmware. */
+       const struct firmware *ucode;
+       const struct firmware *pcm;
+       const struct firmware *initvals0;
+       const struct firmware *initvals1;
 };
 
 
@@ -568,8 +604,11 @@ struct bcm43xx_dma {
        struct bcm43xx_dmaring *tx_ring1;
        struct bcm43xx_dmaring *tx_ring2;
        struct bcm43xx_dmaring *tx_ring3;
+       struct bcm43xx_dmaring *tx_ring4;
+       struct bcm43xx_dmaring *tx_ring5;
+
        struct bcm43xx_dmaring *rx_ring0;
-       struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */
+       struct bcm43xx_dmaring *rx_ring3; /* only available on core.rev < 5 */
 };
 
 /* Data structures for PIO transmission, per 80211 core. */
@@ -593,12 +632,14 @@ struct bcm43xx_coreinfo {
        u8 available:1,
           enabled:1,
           initialized:1;
-       /** core_id ID number */
-       u16 id;
        /** core_rev revision number */
        u8 rev;
        /** Index number for _switch_core() */
        u8 index;
+       /** core_id ID number */
+       u16 id;
+       /** Core-specific data. */
+       void *priv;
 };
 
 /* Additional information for each 80211 core. */
@@ -647,7 +688,23 @@ enum {
        BCM43xx_STAT_RESTARTING,        /* controller_restart() called. */
 };
 #define bcm43xx_status(bcm)            atomic_read(&(bcm)->init_status)
-#define bcm43xx_set_status(bcm, stat)  atomic_set(&(bcm)->init_status, (stat))
+#define bcm43xx_set_status(bcm, stat)  do {                    \
+               atomic_set(&(bcm)->init_status, (stat));        \
+               smp_wmb();                                      \
+                                       } while (0)
+
+/*    *** THEORY OF LOCKING ***
+ *
+ * We have two different locks in the bcm43xx driver.
+ * => bcm->mutex:    General sleeping mutex. Protects struct bcm43xx_private
+ *                   and the device registers. This mutex does _not_ protect
+ *                   against concurrency from the IRQ handler.
+ * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
+ *
+ * Please note that, if you only take the irq_lock, you are not protected
+ * against concurrency from the periodic work handlers.
+ * Most times you want to take _both_ locks.
+ */
 
 struct bcm43xx_private {
        struct ieee80211_device *ieee;
@@ -659,7 +716,6 @@ struct bcm43xx_private {
 
        void __iomem *mmio_addr;
 
-       /* Locking, see "theory of locking" text below. */
        spinlock_t irq_lock;
        struct mutex mutex;
 
@@ -691,6 +747,7 @@ struct bcm43xx_private {
        struct bcm43xx_sprominfo sprom;
 #define BCM43xx_NR_LEDS                4
        struct bcm43xx_led leds[BCM43xx_NR_LEDS];
+       spinlock_t leds_lock;
 
        /* The currently active core. */
        struct bcm43xx_coreinfo *current_core;
@@ -708,10 +765,6 @@ struct bcm43xx_private {
        struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
        /* Additional information, specific to the 80211 cores. */
        struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
-       /* Index of the current 80211 core. If current_core is not
-        * an 80211 core, this is -1.
-        */
-       int current_80211_core_idx;
        /* Number of available 80211 cores. */
        int nr_80211_available;
 
@@ -719,11 +772,13 @@ struct bcm43xx_private {
 
        /* Reason code of the last interrupt. */
        u32 irq_reason;
-       u32 dma_reason[4];
+       u32 dma_reason[6];
        /* saved irq enable/disable state bitfield. */
        u32 irq_savedstate;
        /* Link Quality calculation context. */
        struct bcm43xx_noise_calculation noisecalc;
+       /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
+       int mac_suspended;
 
        /* Threshold values. */
        //TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
@@ -746,12 +801,6 @@ struct bcm43xx_private {
        struct bcm43xx_key key[54];
        u8 default_key_idx;
 
-       /* Firmware. */
-       const struct firmware *ucode;
-       const struct firmware *pcm;
-       const struct firmware *initvals0;
-       const struct firmware *initvals1;
-
        /* Random Number Generator. */
        struct hwrng rng;
        char rng_name[20 + 1];
@@ -761,55 +810,6 @@ struct bcm43xx_private {
        struct bcm43xx_dfsentry *dfsentry;
 #endif
 };
-
-
-/*    *** THEORY OF LOCKING ***
- *
- * We have two different locks in the bcm43xx driver.
- * => bcm->mutex:    General sleeping mutex. Protects struct bcm43xx_private
- *                   and the device registers.
- * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
- *
- * We have three types of helper function pairs to utilize these locks.
- *     (Always use the helper functions.)
- * 1) bcm43xx_{un}lock_noirq():
- *     Takes bcm->mutex. Does _not_ protect against IRQ concurrency,
- *     so it is almost always unsafe, if device IRQs are enabled.
- *     So only use this, if device IRQs are masked.
- *     Locking may sleep.
- *     You can sleep within the critical section.
- * 2) bcm43xx_{un}lock_irqonly():
- *     Takes bcm->irq_lock. Does _not_ protect against
- *     bcm43xx_lock_noirq() critical sections.
- *     Does only protect against the IRQ handler path and other
- *     irqonly() critical sections.
- *     Locking does not sleep.
- *     You must not sleep within the critical section.
- * 3) bcm43xx_{un}lock_irqsafe():
- *     This is the cummulative lock and takes both, mutex and irq_lock.
- *     Protects against noirq() and irqonly() critical sections (and
- *     the IRQ handler path).
- *     Locking may sleep.
- *     You must not sleep within the critical section.
- */
-
-/* Lock type 1 */
-#define bcm43xx_lock_noirq(bcm)                mutex_lock(&(bcm)->mutex)
-#define bcm43xx_unlock_noirq(bcm)      mutex_unlock(&(bcm)->mutex)
-/* Lock type 2 */
-#define bcm43xx_lock_irqonly(bcm, flags)       \
-       spin_lock_irqsave(&(bcm)->irq_lock, flags)
-#define bcm43xx_unlock_irqonly(bcm, flags)     \
-       spin_unlock_irqrestore(&(bcm)->irq_lock, flags)
-/* Lock type 3 */
-#define bcm43xx_lock_irqsafe(bcm, flags) do {  \
-       bcm43xx_lock_noirq(bcm);                \
-       bcm43xx_lock_irqonly(bcm, flags);       \
-               } while (0)
-#define bcm43xx_unlock_irqsafe(bcm, flags) do {        \
-       bcm43xx_unlock_irqonly(bcm, flags);     \
-       bcm43xx_unlock_noirq(bcm);              \
-               } while (0)
 
 
 static inline
@@ -863,34 +863,33 @@ int bcm43xx_using_pio(struct bcm43xx_pri
  * any of these functions.
  */
 static inline
+struct bcm43xx_coreinfo_80211 *
+bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
+{
+       assert(bcm->current_core->id == BCM43xx_COREID_80211);
+       return bcm->current_core->priv;
+}
+static inline
 struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
 {
        assert(bcm43xx_using_pio(bcm));
-       assert(bcm->current_80211_core_idx >= 0);
-       assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
-       return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
+       return &(bcm43xx_current_80211_priv(bcm)->pio);
 }
 static inline
 struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
 {
        assert(!bcm43xx_using_pio(bcm));
-       assert(bcm->current_80211_core_idx >= 0);
-       assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
-       return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
+       return &(bcm43xx_current_80211_priv(bcm)->dma);
 }
 static inline
 struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
 {
-       assert(bcm->current_80211_core_idx >= 0);
-       assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
-       return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
+       return &(bcm43xx_current_80211_priv(bcm)->phy);
 }
 static inline
 struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
 {
-       assert(bcm->current_80211_core_idx >= 0);
-       assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
-       return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
+       return &(bcm43xx_current_80211_priv(bcm)->radio);
 }
 
 
diff -r aafef975e518 -r 3e8752eb6d9c 
drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c    Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c    Wed Oct 03 10:00:44 
2007 +0100
@@ -77,7 +77,8 @@ static ssize_t devinfo_read_file(struct 
 
        down(&big_buffer_sem);
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
                fappend("Board not initialized.\n");
                goto out;
@@ -121,7 +122,8 @@ static ssize_t devinfo_read_file(struct 
        fappend("\n");
 
 out:
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
        res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
        up(&big_buffer_sem);
        return res;
@@ -159,7 +161,8 @@ static ssize_t spromdump_read_file(struc
        unsigned long flags;
 
        down(&big_buffer_sem);
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
                fappend("Board not initialized.\n");
                goto out;
@@ -169,7 +172,8 @@ static ssize_t spromdump_read_file(struc
        fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
 
 out:
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
        res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
        up(&big_buffer_sem);
        return res;
@@ -188,7 +192,8 @@ static ssize_t tsf_read_file(struct file
        u64 tsf;
 
        down(&big_buffer_sem);
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
                fappend("Board not initialized.\n");
                goto out;
@@ -199,7 +204,8 @@ static ssize_t tsf_read_file(struct file
                (unsigned int)(tsf & 0xFFFFFFFFULL));
 
 out:
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
        res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
        up(&big_buffer_sem);
        return res;
@@ -221,7 +227,8 @@ static ssize_t tsf_write_file(struct fil
                res = -EFAULT;
                goto out_up;
        }
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
                printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
                res = -EFAULT;
@@ -237,7 +244,8 @@ static ssize_t tsf_write_file(struct fil
        res = buf_size;
        
 out_unlock:
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 out_up:
        up(&big_buffer_sem);
        return res;
@@ -258,7 +266,8 @@ static ssize_t txstat_read_file(struct f
        int i, cnt, j = 0;
 
        down(&big_buffer_sem);
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
 
        fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
                BCM43xx_NR_LOGGED_XMITSTATUS);
@@ -294,14 +303,51 @@ static ssize_t txstat_read_file(struct f
                        i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
        }
 
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
        res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-       bcm43xx_lock_irqsafe(bcm, flags);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (*ppos == pos) {
                /* Done. Drop the copied data. */
                e->xmitstatus_printing = 0;
        }
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
+       up(&big_buffer_sem);
+       return res;
+}
+
+static ssize_t restart_write_file(struct file *file, const char __user 
*user_buf,
+                                 size_t count, loff_t *ppos)
+{
+       struct bcm43xx_private *bcm = file->private_data;
+       char *buf = really_big_buffer;
+       ssize_t buf_size;
+       ssize_t res;
+       unsigned long flags;
+
+       buf_size = min(count, sizeof (really_big_buffer) - 1);
+       down(&big_buffer_sem);
+       if (copy_from_user(buf, user_buf, buf_size)) {
+               res = -EFAULT;
+               goto out_up;
+       }
+       mutex_lock(&(bcm)->mutex);
+       spin_lock_irqsave(&(bcm)->irq_lock, flags);
+       if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
+               printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
+               res = -EFAULT;
+               goto out_unlock;
+       }
+       if (count > 0 && buf[0] == '1') {
+               bcm43xx_controller_restart(bcm, "manually restarted");
+               res = count;
+       } else
+               res = -EINVAL;
+
+out_unlock:
+       spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
+       mutex_unlock(&(bcm)->mutex);
+out_up:
        up(&big_buffer_sem);
        return res;
 }
@@ -336,6 +382,11 @@ static struct file_operations txstat_fop
 static struct file_operations txstat_fops = {
        .read = txstat_read_file,
        .write = write_file_dummy,
+       .open = open_file_generic,
+};
+
+static struct file_operations restart_fops = {
+       .write = restart_write_file,
        .open = open_file_generic,
 };
 
@@ -390,6 +441,10 @@ void bcm43xx_debugfs_add_device(struct b
                                                bcm, &txstat_fops);
        if (!e->dentry_txstat)
                printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" 
failed!\n", devdir);
+       e->dentry_restart = debugfs_create_file("restart", 0222, e->subdir,
+                                               bcm, &restart_fops);
+       if (!e->dentry_restart)
+               printk(KERN_ERR PFX "debugfs: creating \"restart\" for \"%s\" 
failed!\n", devdir);
 }
 
 void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
@@ -405,6 +460,7 @@ void bcm43xx_debugfs_remove_device(struc
        debugfs_remove(e->dentry_devinfo);
        debugfs_remove(e->dentry_tsf);
        debugfs_remove(e->dentry_txstat);
+       debugfs_remove(e->dentry_restart);
        debugfs_remove(e->subdir);
        kfree(e->xmitstatus_buffer);
        kfree(e->xmitstatus_print_buffer);
diff -r aafef975e518 -r 3e8752eb6d9c 
drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h    Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h    Wed Oct 03 10:00:44 
2007 +0100
@@ -20,6 +20,7 @@ struct bcm43xx_dfsentry {
        struct dentry *dentry_spromdump;
        struct dentry *dentry_tsf;
        struct dentry *dentry_txstat;
+       struct dentry *dentry_restart;
 
        struct bcm43xx_private *bcm;
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_dma.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c        Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c        Wed Oct 03 10:00:44 
2007 +0100
@@ -4,7 +4,7 @@
 
   DMA ringbuffer and descriptor allocation/management
 
-  Copyright (c) 2005 Michael Buesch <mbuesch@xxxxxxxxxx>
+  Copyright (c) 2005, 2006 Michael Buesch <mbuesch@xxxxxxxxxx>
 
   Some code in this file is derived from the b44.c driver
   Copyright (C) 2002 David S. Miller
@@ -107,6 +107,35 @@ void return_slot(struct bcm43xx_dmaring 
                        netif_wake_queue(ring->bcm->net_dev);
                }
        }
+}
+
+u16 bcm43xx_dmacontroller_base(int dma64bit, int controller_idx)
+{
+       static const u16 map64[] = {
+               BCM43xx_MMIO_DMA64_BASE0,
+               BCM43xx_MMIO_DMA64_BASE1,
+               BCM43xx_MMIO_DMA64_BASE2,
+               BCM43xx_MMIO_DMA64_BASE3,
+               BCM43xx_MMIO_DMA64_BASE4,
+               BCM43xx_MMIO_DMA64_BASE5,
+       };
+       static const u16 map32[] = {
+               BCM43xx_MMIO_DMA32_BASE0,
+               BCM43xx_MMIO_DMA32_BASE1,
+               BCM43xx_MMIO_DMA32_BASE2,
+               BCM43xx_MMIO_DMA32_BASE3,
+               BCM43xx_MMIO_DMA32_BASE4,
+               BCM43xx_MMIO_DMA32_BASE5,
+       };
+
+       if (dma64bit) {
+               assert(controller_idx >= 0 &&
+                      controller_idx < ARRAY_SIZE(map64));
+               return map64[controller_idx];
+       }
+       assert(controller_idx >= 0 &&
+              controller_idx < ARRAY_SIZE(map32));
+       return map32[controller_idx];
 }
 
 static inline
@@ -172,7 +201,6 @@ void sync_descbuffer_for_device(struct b
 /* Unmap and free a descriptor buffer. */
 static inline
 void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
-                           struct bcm43xx_dmadesc *desc,
                            struct bcm43xx_dmadesc_meta *meta,
                            int irq_context)
 {
@@ -188,23 +216,13 @@ static int alloc_ringmemory(struct bcm43
 {
        struct device *dev = &(ring->bcm->pci_dev->dev);
 
-       ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
-                                        &(ring->dmabase), GFP_KERNEL);
-       if (!ring->vbase) {
+       ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
+                                           &(ring->dmabase), GFP_KERNEL);
+       if (!ring->descbase) {
                printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
                return -ENOMEM;
        }
-       if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) {
-               printk(KERN_ERR PFX ">>>FATAL ERROR<<<  DMA RINGMEMORY >1G "
-                                   "(0x%llx, len: %lu)\n",
-                               (unsigned long long)ring->dmabase,
-                               BCM43xx_DMA_RINGMEMSIZE);
-               dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
-                                 ring->vbase, ring->dmabase);
-               return -ENOMEM;
-       }
-       assert(!(ring->dmabase & 0x000003FF));
-       memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE);
+       memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
 
        return 0;
 }
@@ -214,26 +232,34 @@ static void free_ringmemory(struct bcm43
        struct device *dev = &(ring->bcm->pci_dev->dev);
 
        dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
-                         ring->vbase, ring->dmabase);
+                         ring->descbase, ring->dmabase);
 }
 
 /* Reset the RX DMA channel */
 int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
-                                  u16 mmio_base)
+                                  u16 mmio_base, int dma64)
 {
        int i;
        u32 value;
-
-       bcm43xx_write32(bcm,
-                       mmio_base + BCM43xx_DMA_RX_CONTROL,
-                       0x00000000);
+       u16 offset;
+
+       offset = dma64 ? BCM43xx_DMA64_RXCTL : BCM43xx_DMA32_RXCTL;
+       bcm43xx_write32(bcm, mmio_base + offset, 0);
        for (i = 0; i < 1000; i++) {
-               value = bcm43xx_read32(bcm,
-                                      mmio_base + BCM43xx_DMA_RX_STATUS);
-               value &= BCM43xx_DMA_RXSTAT_STAT_MASK;
-               if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) {
-                       i = -1;
-                       break;
+               offset = dma64 ? BCM43xx_DMA64_RXSTATUS : 
BCM43xx_DMA32_RXSTATUS;
+               value = bcm43xx_read32(bcm, mmio_base + offset);
+               if (dma64) {
+                       value &= BCM43xx_DMA64_RXSTAT;
+                       if (value == BCM43xx_DMA64_RXSTAT_DISABLED) {
+                               i = -1;
+                               break;
+                       }
+               } else {
+                       value &= BCM43xx_DMA32_RXSTATE;
+                       if (value == BCM43xx_DMA32_RXSTAT_DISABLED) {
+                               i = -1;
+                               break;
+                       }
                }
                udelay(10);
        }
@@ -247,31 +273,47 @@ int bcm43xx_dmacontroller_rx_reset(struc
 
 /* Reset the RX DMA channel */
 int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
-                                  u16 mmio_base)
+                                  u16 mmio_base, int dma64)
 {
        int i;
        u32 value;
+       u16 offset;
 
        for (i = 0; i < 1000; i++) {
-               value = bcm43xx_read32(bcm,
-                                      mmio_base + BCM43xx_DMA_TX_STATUS);
-               value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
-               if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED ||
-                   value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT ||
-                   value == BCM43xx_DMA_TXSTAT_STAT_STOPPED)
-                       break;
+               offset = dma64 ? BCM43xx_DMA64_TXSTATUS : 
BCM43xx_DMA32_TXSTATUS;
+               value = bcm43xx_read32(bcm, mmio_base + offset);
+               if (dma64) {
+                       value &= BCM43xx_DMA64_TXSTAT;
+                       if (value == BCM43xx_DMA64_TXSTAT_DISABLED ||
+                           value == BCM43xx_DMA64_TXSTAT_IDLEWAIT ||
+                           value == BCM43xx_DMA64_TXSTAT_STOPPED)
+                               break;
+               } else {
+                       value &= BCM43xx_DMA32_TXSTATE;
+                       if (value == BCM43xx_DMA32_TXSTAT_DISABLED ||
+                           value == BCM43xx_DMA32_TXSTAT_IDLEWAIT ||
+                           value == BCM43xx_DMA32_TXSTAT_STOPPED)
+                               break;
+               }
                udelay(10);
        }
-       bcm43xx_write32(bcm,
-                       mmio_base + BCM43xx_DMA_TX_CONTROL,
-                       0x00000000);
+       offset = dma64 ? BCM43xx_DMA64_TXCTL : BCM43xx_DMA32_TXCTL;
+       bcm43xx_write32(bcm, mmio_base + offset, 0);
        for (i = 0; i < 1000; i++) {
-               value = bcm43xx_read32(bcm,
-                                      mmio_base + BCM43xx_DMA_TX_STATUS);
-               value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
-               if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) {
-                       i = -1;
-                       break;
+               offset = dma64 ? BCM43xx_DMA64_TXSTATUS : 
BCM43xx_DMA32_TXSTATUS;
+               value = bcm43xx_read32(bcm, mmio_base + offset);
+               if (dma64) {
+                       value &= BCM43xx_DMA64_TXSTAT;
+                       if (value == BCM43xx_DMA64_TXSTAT_DISABLED) {
+                               i = -1;
+                               break;
+                       }
+               } else {
+                       value &= BCM43xx_DMA32_TXSTATE;
+                       if (value == BCM43xx_DMA32_TXSTAT_DISABLED) {
+                               i = -1;
+                               break;
+                       }
                }
                udelay(10);
        }
@@ -285,47 +327,98 @@ int bcm43xx_dmacontroller_tx_reset(struc
        return 0;
 }
 
+static void fill_descriptor(struct bcm43xx_dmaring *ring,
+                           struct bcm43xx_dmadesc_generic *desc,
+                           dma_addr_t dmaaddr,
+                           u16 bufsize,
+                           int start, int end, int irq)
+{
+       int slot;
+
+       slot = bcm43xx_dma_desc2idx(ring, desc);
+       assert(slot >= 0 && slot < ring->nr_slots);
+
+       if (ring->dma64) {
+               u32 ctl0 = 0, ctl1 = 0;
+               u32 addrlo, addrhi;
+               u32 addrext;
+
+               addrlo = (u32)(dmaaddr & 0xFFFFFFFF);
+               addrhi = (((u64)dmaaddr >> 32) & ~BCM43xx_DMA64_ROUTING);
+               addrext = (((u64)dmaaddr >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
+               addrhi |= ring->routing;
+               if (slot == ring->nr_slots - 1)
+                       ctl0 |= BCM43xx_DMA64_DCTL0_DTABLEEND;
+               if (start)
+                       ctl0 |= BCM43xx_DMA64_DCTL0_FRAMESTART;
+               if (end)
+                       ctl0 |= BCM43xx_DMA64_DCTL0_FRAMEEND;
+               if (irq)
+                       ctl0 |= BCM43xx_DMA64_DCTL0_IRQ;
+               ctl1 |= (bufsize - ring->frameoffset)
+                       & BCM43xx_DMA64_DCTL1_BYTECNT;
+               ctl1 |= (addrext << BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT)
+                       & BCM43xx_DMA64_DCTL1_ADDREXT_MASK;
+
+               desc->dma64.control0 = cpu_to_le32(ctl0);
+               desc->dma64.control1 = cpu_to_le32(ctl1);
+               desc->dma64.address_low = cpu_to_le32(addrlo);
+               desc->dma64.address_high = cpu_to_le32(addrhi);
+       } else {
+               u32 ctl;
+               u32 addr;
+               u32 addrext;
+
+               addr = (u32)(dmaaddr & ~BCM43xx_DMA32_ROUTING);
+               addrext = (u32)(dmaaddr & BCM43xx_DMA32_ROUTING)
+                          >> BCM43xx_DMA32_ROUTING_SHIFT;
+               addr |= ring->routing;
+               ctl = (bufsize - ring->frameoffset)
+                     & BCM43xx_DMA32_DCTL_BYTECNT;
+               if (slot == ring->nr_slots - 1)
+                       ctl |= BCM43xx_DMA32_DCTL_DTABLEEND;
+               if (start)
+                       ctl |= BCM43xx_DMA32_DCTL_FRAMESTART;
+               if (end)
+                       ctl |= BCM43xx_DMA32_DCTL_FRAMEEND;
+               if (irq)
+                       ctl |= BCM43xx_DMA32_DCTL_IRQ;
+               ctl |= (addrext << BCM43xx_DMA32_DCTL_ADDREXT_SHIFT)
+                      & BCM43xx_DMA32_DCTL_ADDREXT_MASK;
+
+               desc->dma32.control = cpu_to_le32(ctl);
+               desc->dma32.address = cpu_to_le32(addr);
+       }
+}
+
 static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
-                              struct bcm43xx_dmadesc *desc,
+                              struct bcm43xx_dmadesc_generic *desc,
                               struct bcm43xx_dmadesc_meta *meta,
                               gfp_t gfp_flags)
 {
        struct bcm43xx_rxhdr *rxhdr;
+       struct bcm43xx_hwxmitstatus *xmitstat;
        dma_addr_t dmaaddr;
-       u32 desc_addr;
-       u32 desc_ctl;
-       const int slot = (int)(desc - ring->vbase);
        struct sk_buff *skb;
 
-       assert(slot >= 0 && slot < ring->nr_slots);
        assert(!ring->tx);
 
        skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
        if (unlikely(!skb))
                return -ENOMEM;
        dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
-       if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) {
-               unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
-               dev_kfree_skb_any(skb);
-               printk(KERN_ERR PFX ">>>FATAL ERROR<<<  DMA RX SKB >1G "
-                                   "(0x%llx, len: %u)\n",
-                       (unsigned long long)dmaaddr, ring->rx_buffersize);
-               return -ENOMEM;
-       }
        meta->skb = skb;
        meta->dmaaddr = dmaaddr;
        skb->dev = ring->bcm->net_dev;
-       desc_addr = (u32)(dmaaddr + ring->memoffset);
-       desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK &
-                   (u32)(ring->rx_buffersize - ring->frameoffset));
-       if (slot == ring->nr_slots - 1)
-               desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
-       set_desc_addr(desc, desc_addr);
-       set_desc_ctl(desc, desc_ctl);
+
+       fill_descriptor(ring, desc, dmaaddr,
+                       ring->rx_buffersize, 0, 0, 0);
 
        rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
        rxhdr->frame_length = 0;
        rxhdr->flags1 = 0;
+       xmitstat = (struct bcm43xx_hwxmitstatus *)(skb->data);
+       xmitstat->cookie = 0;
 
        return 0;
 }
@@ -336,17 +429,17 @@ static int alloc_initial_descbuffers(str
 static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
 {
        int i, err = -ENOMEM;
-       struct bcm43xx_dmadesc *desc;
+       struct bcm43xx_dmadesc_generic *desc;
        struct bcm43xx_dmadesc_meta *meta;
 
        for (i = 0; i < ring->nr_slots; i++) {
-               desc = ring->vbase + i;
-               meta = ring->meta + i;
+               desc = bcm43xx_dma_idx2desc(ring, i, &meta);
 
                err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
                if (err)
                        goto err_unwind;
        }
+       mb();
        ring->used_slots = ring->nr_slots;
        err = 0;
 out:
@@ -354,8 +447,7 @@ out:
 
 err_unwind:
        for (i--; i >= 0; i--) {
-               desc = ring->vbase + i;
-               meta = ring->meta + i;
+               desc = bcm43xx_dma_idx2desc(ring, i, &meta);
 
                unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
                dev_kfree_skb(meta->skb);
@@ -371,27 +463,67 @@ static int dmacontroller_setup(struct bc
 {
        int err = 0;
        u32 value;
+       u32 addrext;
 
        if (ring->tx) {
-               /* Set Transmit Control register to "transmit enable" */
-               bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
-                                 BCM43xx_DMA_TXCTRL_ENABLE);
-               /* Set Transmit Descriptor ring address. */
-               bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING,
-                                 ring->dmabase + ring->memoffset);
+               if (ring->dma64) {
+                       u64 ringbase = (u64)(ring->dmabase);
+
+                       addrext = ((ringbase >> 32) >> 
BCM43xx_DMA64_ROUTING_SHIFT);
+                       value = BCM43xx_DMA64_TXENABLE;
+                       value |= (addrext << BCM43xx_DMA64_TXADDREXT_SHIFT)
+                               & BCM43xx_DMA64_TXADDREXT_MASK;
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL, value);
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO,
+                                       (ringbase & 0xFFFFFFFF));
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI,
+                                       ((ringbase >> 32) & 
~BCM43xx_DMA64_ROUTING)
+                                       | ring->routing);
+               } else {
+                       u32 ringbase = (u32)(ring->dmabase);
+
+                       addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
+                       value = BCM43xx_DMA32_TXENABLE;
+                       value |= (addrext << BCM43xx_DMA32_TXADDREXT_SHIFT)
+                               & BCM43xx_DMA32_TXADDREXT_MASK;
+                       bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL, value);
+                       bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING,
+                                       (ringbase & ~BCM43xx_DMA32_ROUTING)
+                                       | ring->routing);
+               }
        } else {
                err = alloc_initial_descbuffers(ring);
                if (err)
                        goto out;
-               /* Set Receive Control "receive enable" and frame offset */
-               value = (ring->frameoffset << 
BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT);
-               value |= BCM43xx_DMA_RXCTRL_ENABLE;
-               bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value);
-               /* Set Receive Descriptor ring address. */
-               bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING,
-                                 ring->dmabase + ring->memoffset);
-               /* Init the descriptor pointer. */
-               bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200);
+               if (ring->dma64) {
+                       u64 ringbase = (u64)(ring->dmabase);
+
+                       addrext = ((ringbase >> 32) >> 
BCM43xx_DMA64_ROUTING_SHIFT);
+                       value = (ring->frameoffset << 
BCM43xx_DMA64_RXFROFF_SHIFT);
+                       value |= BCM43xx_DMA64_RXENABLE;
+                       value |= (addrext << BCM43xx_DMA64_RXADDREXT_SHIFT)
+                               & BCM43xx_DMA64_RXADDREXT_MASK;
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_RXCTL, value);
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO,
+                                       (ringbase & 0xFFFFFFFF));
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI,
+                                       ((ringbase >> 32) & 
~BCM43xx_DMA64_ROUTING)
+                                       | ring->routing);
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX, 200);
+               } else {
+                       u32 ringbase = (u32)(ring->dmabase);
+
+                       addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
+                       value = (ring->frameoffset << 
BCM43xx_DMA32_RXFROFF_SHIFT);
+                       value |= BCM43xx_DMA32_RXENABLE;
+                       value |= (addrext << BCM43xx_DMA32_RXADDREXT_SHIFT)
+                               & BCM43xx_DMA32_RXADDREXT_MASK;
+                       bcm43xx_dma_write(ring, BCM43xx_DMA32_RXCTL, value);
+                       bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING,
+                                       (ringbase & ~BCM43xx_DMA32_ROUTING)
+                                       | ring->routing);
+                       bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX, 200);
+               }
        }
 
 out:
@@ -402,27 +534,32 @@ static void dmacontroller_cleanup(struct
 static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
 {
        if (ring->tx) {
-               bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base);
-               /* Zero out Transmit Descriptor ring address. */
-               bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0);
+               bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base, 
ring->dma64);
+               if (ring->dma64) {
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO, 0);
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI, 0);
+               } else
+                       bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING, 0);
        } else {
-               bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base);
-               /* Zero out Receive Descriptor ring address. */
-               bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0);
+               bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base, 
ring->dma64);
+               if (ring->dma64) {
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO, 0);
+                       bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI, 0);
+               } else
+                       bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING, 0);
        }
 }
 
 static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
 {
-       struct bcm43xx_dmadesc *desc;
+       struct bcm43xx_dmadesc_generic *desc;
        struct bcm43xx_dmadesc_meta *meta;
        int i;
 
        if (!ring->used_slots)
                return;
        for (i = 0; i < ring->nr_slots; i++) {
-               desc = ring->vbase + i;
-               meta = ring->meta + i;
+               desc = bcm43xx_dma_idx2desc(ring, i, &meta);
 
                if (!meta->skb) {
                        assert(ring->tx);
@@ -430,62 +567,67 @@ static void free_all_descbuffers(struct 
                }
                if (ring->tx) {
                        unmap_descbuffer(ring, meta->dmaaddr,
-                                        meta->skb->len, 1);
+                                       meta->skb->len, 1);
                } else {
                        unmap_descbuffer(ring, meta->dmaaddr,
-                                        ring->rx_buffersize, 0);
-               }
-               free_descriptor_buffer(ring, desc, meta, 0);
+                                       ring->rx_buffersize, 0);
+               }
+               free_descriptor_buffer(ring, meta, 0);
        }
 }
 
 /* Main initialization function. */
 static
 struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
-                                              u16 dma_controller_base,
-                                              int nr_descriptor_slots,
-                                              int tx)
+                                              int controller_index,
+                                              int for_tx,
+                                              int dma64)
 {
        struct bcm43xx_dmaring *ring;
        int err;
+       int nr_slots;
 
        ring = kzalloc(sizeof(*ring), GFP_KERNEL);
        if (!ring)
                goto out;
 
-       ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots,
+       nr_slots = BCM43xx_RXRING_SLOTS;
+       if (for_tx)
+               nr_slots = BCM43xx_TXRING_SLOTS;
+
+       ring->meta = kcalloc(nr_slots, sizeof(struct bcm43xx_dmadesc_meta),
                             GFP_KERNEL);
        if (!ring->meta)
                goto err_kfree_ring;
 
-       ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET;
+       ring->routing = BCM43xx_DMA32_CLIENTTRANS;
+       if (dma64)
+               ring->routing = BCM43xx_DMA64_CLIENTTRANS;
 #ifdef CONFIG_BCM947XX
        if (bcm->pci_dev->bus->number == 0)
-               ring->memoffset = 0;
+               ring->routing = dma64 ? BCM43xx_DMA64_NOTRANS : 
BCM43xx_DMA32_NOTRANS;
 #endif
 
        ring->bcm = bcm;
-       ring->nr_slots = nr_descriptor_slots;
+       ring->nr_slots = nr_slots;
        ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100;
        ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100;
        assert(ring->suspend_mark < ring->resume_mark);
-       ring->mmio_base = dma_controller_base;
-       if (tx) {
+       ring->mmio_base = bcm43xx_dmacontroller_base(dma64, controller_index);
+       ring->index = controller_index;
+       ring->dma64 = !!dma64;
+       if (for_tx) {
                ring->tx = 1;
                ring->current_slot = -1;
        } else {
-               switch (dma_controller_base) {
-               case BCM43xx_MMIO_DMA1_BASE:
-                       ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE;
-                       ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET;
-                       break;
-               case BCM43xx_MMIO_DMA4_BASE:
-                       ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE;
-                       ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET;
-                       break;
-               default:
+               if (ring->index == 0) {
+                       ring->rx_buffersize = BCM43xx_DMA0_RX_BUFFERSIZE;
+                       ring->frameoffset = BCM43xx_DMA0_RX_FRAMEOFFSET;
+               } else if (ring->index == 3) {
+                       ring->rx_buffersize = BCM43xx_DMA3_RX_BUFFERSIZE;
+                       ring->frameoffset = BCM43xx_DMA3_RX_FRAMEOFFSET;
+               } else
                        assert(0);
-               }
        }
 
        err = alloc_ringmemory(ring);
@@ -514,7 +656,8 @@ static void bcm43xx_destroy_dmaring(stru
        if (!ring)
                return;
 
-       dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n",
+       dprintk(KERN_INFO PFX "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
+               (ring->dma64) ? "64" : "32",
                ring->mmio_base,
                (ring->tx) ? "TX" : "RX",
                ring->max_used_slots, ring->nr_slots);
@@ -537,10 +680,15 @@ void bcm43xx_dma_free(struct bcm43xx_pri
                return;
        dma = bcm43xx_current_dma(bcm);
 
-       bcm43xx_destroy_dmaring(dma->rx_ring1);
-       dma->rx_ring1 = NULL;
+       bcm43xx_destroy_dmaring(dma->rx_ring3);
+       dma->rx_ring3 = NULL;
        bcm43xx_destroy_dmaring(dma->rx_ring0);
        dma->rx_ring0 = NULL;
+
+       bcm43xx_destroy_dmaring(dma->tx_ring5);
+       dma->tx_ring5 = NULL;
+       bcm43xx_destroy_dmaring(dma->tx_ring4);
+       dma->tx_ring4 = NULL;
        bcm43xx_destroy_dmaring(dma->tx_ring3);
        dma->tx_ring3 = NULL;
        bcm43xx_destroy_dmaring(dma->tx_ring2);
@@ -556,48 +704,59 @@ int bcm43xx_dma_init(struct bcm43xx_priv
        struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
        struct bcm43xx_dmaring *ring;
        int err = -ENOMEM;
+       int dma64 = 0;
+       u32 sbtmstatehi;
+
+       sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
+       if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
+               dma64 = 1;
 
        /* setup TX DMA channels. */
-       ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
-                                    BCM43xx_TXRING_SLOTS, 1);
+       ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
        if (!ring)
                goto out;
        dma->tx_ring0 = ring;
 
-       ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE,
-                                    BCM43xx_TXRING_SLOTS, 1);
+       ring = bcm43xx_setup_dmaring(bcm, 1, 1, dma64);
        if (!ring)
                goto err_destroy_tx0;
        dma->tx_ring1 = ring;
 
-       ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE,
-                                    BCM43xx_TXRING_SLOTS, 1);
+       ring = bcm43xx_setup_dmaring(bcm, 2, 1, dma64);
        if (!ring)
                goto err_destroy_tx1;
        dma->tx_ring2 = ring;
 
-       ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
-                                    BCM43xx_TXRING_SLOTS, 1);
+       ring = bcm43xx_setup_dmaring(bcm, 3, 1, dma64);
        if (!ring)
                goto err_destroy_tx2;
        dma->tx_ring3 = ring;
 
-       /* setup RX DMA channels. */
-       ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
-                                    BCM43xx_RXRING_SLOTS, 0);
+       ring = bcm43xx_setup_dmaring(bcm, 4, 1, dma64);
        if (!ring)
                goto err_destroy_tx3;
+       dma->tx_ring4 = ring;
+
+       ring = bcm43xx_setup_dmaring(bcm, 5, 1, dma64);
+       if (!ring)
+               goto err_destroy_tx4;
+       dma->tx_ring5 = ring;
+
+       /* setup RX DMA channels. */
+       ring = bcm43xx_setup_dmaring(bcm, 0, 0, dma64);
+       if (!ring)
+               goto err_destroy_tx5;
        dma->rx_ring0 = ring;
 
        if (bcm->current_core->rev < 5) {
-               ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
-                                            BCM43xx_RXRING_SLOTS, 0);
+               ring = bcm43xx_setup_dmaring(bcm, 3, 0, dma64);
                if (!ring)
                        goto err_destroy_rx0;
-               dma->rx_ring1 = ring;
-       }
-
-       dprintk(KERN_INFO PFX "DMA initialized\n");
+               dma->rx_ring3 = ring;
+       }
+
+       dprintk(KERN_INFO PFX "%s DMA initialized\n",
+                       dma64 ? "64-bit" : "32-bit");
        err = 0;
 out:
        return err;
@@ -605,6 +764,12 @@ err_destroy_rx0:
 err_destroy_rx0:
        bcm43xx_destroy_dmaring(dma->rx_ring0);
        dma->rx_ring0 = NULL;
+err_destroy_tx5:
+       bcm43xx_destroy_dmaring(dma->tx_ring5);
+       dma->tx_ring5 = NULL;
+err_destroy_tx4:
+       bcm43xx_destroy_dmaring(dma->tx_ring4);
+       dma->tx_ring4 = NULL;
 err_destroy_tx3:
        bcm43xx_destroy_dmaring(dma->tx_ring3);
        dma->tx_ring3 = NULL;
@@ -624,7 +789,7 @@ static u16 generate_cookie(struct bcm43x
 static u16 generate_cookie(struct bcm43xx_dmaring *ring,
                           int slot)
 {
-       u16 cookie = 0xF000;
+       u16 cookie = 0x1000;
 
        /* Use the upper 4 bits of the cookie as
         * DMA controller ID and store the slot number
@@ -632,20 +797,24 @@ static u16 generate_cookie(struct bcm43x
         * Note that the cookie must never be 0, as this
         * is a special value used in RX path.
         */
-       switch (ring->mmio_base) {
-       default:
-               assert(0);
-       case BCM43xx_MMIO_DMA1_BASE:
+       switch (ring->index) {
+       case 0:
                cookie = 0xA000;
                break;
-       case BCM43xx_MMIO_DMA2_BASE:
+       case 1:
                cookie = 0xB000;
                break;
-       case BCM43xx_MMIO_DMA3_BASE:
+       case 2:
                cookie = 0xC000;
                break;
-       case BCM43xx_MMIO_DMA4_BASE:
+       case 3:
                cookie = 0xD000;
+               break;
+       case 4:
+               cookie = 0xE000;
+               break;
+       case 5:
+               cookie = 0xF000;
                break;
        }
        assert(((u16)slot & 0xF000) == 0x0000);
@@ -675,6 +844,12 @@ struct bcm43xx_dmaring * parse_cookie(st
        case 0xD000:
                ring = dma->tx_ring3;
                break;
+       case 0xE000:
+               ring = dma->tx_ring4;
+               break;
+       case 0xF000:
+               ring = dma->tx_ring5;
+               break;
        default:
                assert(0);
        }
@@ -687,6 +862,9 @@ static void dmacontroller_poke_tx(struct
 static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
                                  int slot)
 {
+       u16 offset;
+       int descsize;
+
        /* Everything is ready to start. Buffers are DMA mapped and
         * associated with slots.
         * "slot" is the last slot of the new frame we want to transmit.
@@ -694,25 +872,26 @@ static void dmacontroller_poke_tx(struct
         */
        wmb();
        slot = next_slot(ring, slot);
-       bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX,
-                         (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
-}
-
-static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
-                          struct sk_buff *skb,
-                          u8 cur_frag)
+       offset = (ring->dma64) ? BCM43xx_DMA64_TXINDEX : BCM43xx_DMA32_TXINDEX;
+       descsize = (ring->dma64) ? sizeof(struct bcm43xx_dmadesc64)
+               : sizeof(struct bcm43xx_dmadesc32);
+       bcm43xx_dma_write(ring, offset,
+                       (u32)(slot * descsize));
+}
+
+static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
+                           struct sk_buff *skb,
+                           u8 cur_frag)
 {
        int slot;
-       struct bcm43xx_dmadesc *desc;
+       struct bcm43xx_dmadesc_generic *desc;
        struct bcm43xx_dmadesc_meta *meta;
-       u32 desc_ctl;
-       u32 desc_addr;
+       dma_addr_t dmaaddr;
 
        assert(skb_shinfo(skb)->nr_frags == 0);
 
        slot = request_slot(ring);
-       desc = ring->vbase + slot;
-       meta = ring->meta + slot;
+       desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
 
        /* Add a device specific TX header. */
        assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr));
@@ -729,29 +908,14 @@ static int dma_tx_fragment(struct bcm43x
                               generate_cookie(ring, slot));
 
        meta->skb = skb;
-       meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
-       if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) {
-               return_slot(ring, slot);
-               printk(KERN_ERR PFX ">>>FATAL ERROR<<<  DMA TX SKB >1G "
-                                   "(0x%llx, len: %u)\n",
-                       (unsigned long long)meta->dmaaddr, skb->len);
-               return -ENOMEM;
-       }
-
-       desc_addr = (u32)(meta->dmaaddr + ring->memoffset);
-       desc_ctl = BCM43xx_DMADTOR_FRAMESTART | BCM43xx_DMADTOR_FRAMEEND;
-       desc_ctl |= BCM43xx_DMADTOR_COMPIRQ;
-       desc_ctl |= (BCM43xx_DMADTOR_BYTECNT_MASK &
-                    (u32)(meta->skb->len - ring->frameoffset));
-       if (slot == ring->nr_slots - 1)
-               desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
-
-       set_desc_ctl(desc, desc_ctl);
-       set_desc_addr(desc, desc_addr);
+       dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+       meta->dmaaddr = dmaaddr;
+
+       fill_descriptor(ring, desc, dmaaddr,
+                       skb->len, 1, 1, 1);
+
        /* Now transfer the whole frame. */
        dmacontroller_poke_tx(ring, slot);
-
-       return 0;
 }
 
 int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
@@ -781,7 +945,6 @@ int bcm43xx_dma_tx(struct bcm43xx_privat
                /* Take skb from ieee80211_txb_free */
                txb->fragments[i] = NULL;
                dma_tx_fragment(ring, skb, i);
-               //TODO: handle failure of dma_tx_fragment
        }
        ieee80211_txb_free(txb);
 
@@ -792,23 +955,28 @@ void bcm43xx_dma_handle_xmitstatus(struc
                                   struct bcm43xx_xmitstatus *status)
 {
        struct bcm43xx_dmaring *ring;
-       struct bcm43xx_dmadesc *desc;
+       struct bcm43xx_dmadesc_generic *desc;
        struct bcm43xx_dmadesc_meta *meta;
        int is_last_fragment;
        int slot;
+       u32 tmp;
 
        ring = parse_cookie(bcm, status->cookie, &slot);
        assert(ring);
        assert(ring->tx);
-       assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART);
        while (1) {
                assert(slot >= 0 && slot < ring->nr_slots);
-               desc = ring->vbase + slot;
-               meta = ring->meta + slot;
-
-               is_last_fragment = !!(get_desc_ctl(desc) & 
BCM43xx_DMADTOR_FRAMEEND);
+               desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
+
+               if (ring->dma64) {
+                       tmp = le32_to_cpu(desc->dma64.control0);
+                       is_last_fragment = !!(tmp & 
BCM43xx_DMA64_DCTL0_FRAMEEND);
+               } else {
+                       tmp = le32_to_cpu(desc->dma32.control);
+                       is_last_fragment = !!(tmp & 
BCM43xx_DMA32_DCTL_FRAMEEND);
+               }
                unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
-               free_descriptor_buffer(ring, desc, meta, 1);
+               free_descriptor_buffer(ring, meta, 1);
                /* Everything belonging to the slot is unmapped
                 * and freed, so we can return it.
                 */
@@ -824,7 +992,7 @@ static void dma_rx(struct bcm43xx_dmarin
 static void dma_rx(struct bcm43xx_dmaring *ring,
                   int *slot)
 {
-       struct bcm43xx_dmadesc *desc;
+       struct bcm43xx_dmadesc_generic *desc;
        struct bcm43xx_dmadesc_meta *meta;
        struct bcm43xx_rxhdr *rxhdr;
        struct sk_buff *skb;
@@ -832,13 +1000,12 @@ static void dma_rx(struct bcm43xx_dmarin
        int err;
        dma_addr_t dmaaddr;
 
-       desc = ring->vbase + *slot;
-       meta = ring->meta + *slot;
+       desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
 
        sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
        skb = meta->skb;
 
-       if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) {
+       if (ring->index == 3) {
                /* We received an xmit status. */
                struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus 
*)skb->data;
                struct bcm43xx_xmitstatus stat;
@@ -894,8 +1061,7 @@ static void dma_rx(struct bcm43xx_dmarin
                s32 tmp = len;
 
                while (1) {
-                       desc = ring->vbase + *slot;
-                       meta = ring->meta + *slot;
+                       desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
                        /* recycle the descriptor buffer. */
                        sync_descbuffer_for_device(ring, meta->dmaaddr,
                                                   ring->rx_buffersize);
@@ -906,8 +1072,8 @@ static void dma_rx(struct bcm43xx_dmarin
                                break;
                }
                printkl(KERN_ERR PFX "DMA RX buffer too small "
-                                    "(len: %u, buffer: %u, nr-dropped: %d)\n",
-                       len, ring->rx_buffersize, cnt);
+                       "(len: %u, buffer: %u, nr-dropped: %d)\n",
+                       len, ring->rx_buffersize, cnt);
                goto drop;
        }
        len -= IEEE80211_FCS_LEN;
@@ -945,9 +1111,15 @@ void bcm43xx_dma_rx(struct bcm43xx_dmari
 #endif
 
        assert(!ring->tx);
-       status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS);
-       descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK);
-       current_slot = descptr / sizeof(struct bcm43xx_dmadesc);
+       if (ring->dma64) {
+               status = bcm43xx_dma_read(ring, BCM43xx_DMA64_RXSTATUS);
+               descptr = (status & BCM43xx_DMA64_RXSTATDPTR);
+               current_slot = descptr / sizeof(struct bcm43xx_dmadesc64);
+       } else {
+               status = bcm43xx_dma_read(ring, BCM43xx_DMA32_RXSTATUS);
+               descptr = (status & BCM43xx_DMA32_RXDPTR);
+               current_slot = descptr / sizeof(struct bcm43xx_dmadesc32);
+       }
        assert(current_slot >= 0 && current_slot < ring->nr_slots);
 
        slot = ring->current_slot;
@@ -958,8 +1130,13 @@ void bcm43xx_dma_rx(struct bcm43xx_dmari
                        ring->max_used_slots = used_slots;
 #endif
        }
-       bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX,
-                         (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
+       if (ring->dma64) {
+               bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX,
+                               (u32)(slot * sizeof(struct bcm43xx_dmadesc64)));
+       } else {
+               bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX,
+                               (u32)(slot * sizeof(struct bcm43xx_dmadesc32)));
+       }
        ring->current_slot = slot;
 }
 
@@ -967,16 +1144,28 @@ void bcm43xx_dma_tx_suspend(struct bcm43
 {
        assert(ring->tx);
        bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1);
-       bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
-                         bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
-                         | BCM43xx_DMA_TXCTRL_SUSPEND);
+       if (ring->dma64) {
+               bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
+                               bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
+                               | BCM43xx_DMA64_TXSUSPEND);
+       } else {
+               bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
+                               bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
+                               | BCM43xx_DMA32_TXSUSPEND);
+       }
 }
 
 void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
 {
        assert(ring->tx);
-       bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
-                         bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
-                         & ~BCM43xx_DMA_TXCTRL_SUSPEND);
+       if (ring->dma64) {
+               bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
+                               bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
+                               & ~BCM43xx_DMA64_TXSUSPEND);
+       } else {
+               bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
+                               bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
+                               & ~BCM43xx_DMA32_TXSUSPEND);
+       }
        bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1);
 }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_dma.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h        Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h        Wed Oct 03 10:00:44 
2007 +0100
@@ -14,63 +14,179 @@
 #define BCM43xx_DMAIRQ_NONFATALMASK    (1 << 13)
 #define BCM43xx_DMAIRQ_RX_DONE         (1 << 16)
 
-/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
-#define BCM43xx_DMA_TX_CONTROL         0x00
-#define BCM43xx_DMA_TX_DESC_RING       0x04
-#define BCM43xx_DMA_TX_DESC_INDEX      0x08
-#define BCM43xx_DMA_TX_STATUS          0x0c
-#define BCM43xx_DMA_RX_CONTROL         0x10
-#define BCM43xx_DMA_RX_DESC_RING       0x14
-#define BCM43xx_DMA_RX_DESC_INDEX      0x18
-#define BCM43xx_DMA_RX_STATUS          0x1c
-
-/* DMA controller channel control word values. */
-#define BCM43xx_DMA_TXCTRL_ENABLE              (1 << 0)
-#define BCM43xx_DMA_TXCTRL_SUSPEND             (1 << 1)
-#define BCM43xx_DMA_TXCTRL_LOOPBACK            (1 << 2)
-#define BCM43xx_DMA_TXCTRL_FLUSH               (1 << 4)
-#define BCM43xx_DMA_RXCTRL_ENABLE              (1 << 0)
-#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK       0x000000fe
-#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT      1
-#define BCM43xx_DMA_RXCTRL_PIO                 (1 << 8)
-/* DMA controller channel status word values. */
-#define BCM43xx_DMA_TXSTAT_DPTR_MASK           0x00000fff
-#define BCM43xx_DMA_TXSTAT_STAT_MASK           0x0000f000
-#define BCM43xx_DMA_TXSTAT_STAT_DISABLED       0x00000000
-#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE         0x00001000
-#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT       0x00002000
-#define BCM43xx_DMA_TXSTAT_STAT_STOPPED                0x00003000
-#define BCM43xx_DMA_TXSTAT_STAT_SUSP           0x00004000
-#define BCM43xx_DMA_TXSTAT_ERROR_MASK          0x000f0000
-#define BCM43xx_DMA_TXSTAT_FLUSHED             (1 << 20)
-#define BCM43xx_DMA_RXSTAT_DPTR_MASK           0x00000fff
-#define BCM43xx_DMA_RXSTAT_STAT_MASK           0x0000f000
-#define BCM43xx_DMA_RXSTAT_STAT_DISABLED       0x00000000
-#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE         0x00001000
-#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT       0x00002000
-#define BCM43xx_DMA_RXSTAT_STAT_RESERVED       0x00003000
-#define BCM43xx_DMA_RXSTAT_STAT_ERRORS         0x00004000
-#define BCM43xx_DMA_RXSTAT_ERROR_MASK          0x000f0000
-
-/* DMA descriptor control field values. */
-#define BCM43xx_DMADTOR_BYTECNT_MASK           0x00001fff
-#define BCM43xx_DMADTOR_DTABLEEND              (1 << 28) /* End of descriptor 
table */
-#define BCM43xx_DMADTOR_COMPIRQ                        (1 << 29) /* IRQ on 
completion request */
-#define BCM43xx_DMADTOR_FRAMEEND               (1 << 30)
-#define BCM43xx_DMADTOR_FRAMESTART             (1 << 31)
+
+/*** 32-bit DMA Engine. ***/
+
+/* 32-bit DMA controller registers. */
+#define BCM43xx_DMA32_TXCTL                            0x00
+#define                BCM43xx_DMA32_TXENABLE                  0x00000001
+#define                BCM43xx_DMA32_TXSUSPEND                 0x00000002
+#define                BCM43xx_DMA32_TXLOOPBACK                0x00000004
+#define                BCM43xx_DMA32_TXFLUSH                   0x00000010
+#define                BCM43xx_DMA32_TXADDREXT_MASK            0x00030000
+#define                BCM43xx_DMA32_TXADDREXT_SHIFT           16
+#define BCM43xx_DMA32_TXRING                           0x04
+#define BCM43xx_DMA32_TXINDEX                          0x08
+#define BCM43xx_DMA32_TXSTATUS                         0x0C
+#define                BCM43xx_DMA32_TXDPTR                    0x00000FFF
+#define                BCM43xx_DMA32_TXSTATE                   0x0000F000
+#define                        BCM43xx_DMA32_TXSTAT_DISABLED   0x00000000
+#define                        BCM43xx_DMA32_TXSTAT_ACTIVE     0x00001000
+#define                        BCM43xx_DMA32_TXSTAT_IDLEWAIT   0x00002000
+#define                        BCM43xx_DMA32_TXSTAT_STOPPED    0x00003000
+#define                        BCM43xx_DMA32_TXSTAT_SUSP       0x00004000
+#define                BCM43xx_DMA32_TXERROR                   0x000F0000
+#define                        BCM43xx_DMA32_TXERR_NOERR       0x00000000
+#define                        BCM43xx_DMA32_TXERR_PROT        0x00010000
+#define                        BCM43xx_DMA32_TXERR_UNDERRUN    0x00020000
+#define                        BCM43xx_DMA32_TXERR_BUFREAD     0x00030000
+#define                        BCM43xx_DMA32_TXERR_DESCREAD    0x00040000
+#define                BCM43xx_DMA32_TXACTIVE                  0xFFF00000
+#define BCM43xx_DMA32_RXCTL                            0x10
+#define                BCM43xx_DMA32_RXENABLE                  0x00000001
+#define                BCM43xx_DMA32_RXFROFF_MASK              0x000000FE
+#define                BCM43xx_DMA32_RXFROFF_SHIFT             1
+#define                BCM43xx_DMA32_RXDIRECTFIFO              0x00000100
+#define                BCM43xx_DMA32_RXADDREXT_MASK            0x00030000
+#define                BCM43xx_DMA32_RXADDREXT_SHIFT           16
+#define BCM43xx_DMA32_RXRING                           0x14
+#define BCM43xx_DMA32_RXINDEX                          0x18
+#define BCM43xx_DMA32_RXSTATUS                         0x1C
+#define                BCM43xx_DMA32_RXDPTR                    0x00000FFF
+#define                BCM43xx_DMA32_RXSTATE                   0x0000F000
+#define                        BCM43xx_DMA32_RXSTAT_DISABLED   0x00000000
+#define                        BCM43xx_DMA32_RXSTAT_ACTIVE     0x00001000
+#define                        BCM43xx_DMA32_RXSTAT_IDLEWAIT   0x00002000
+#define                        BCM43xx_DMA32_RXSTAT_STOPPED    0x00003000
+#define                BCM43xx_DMA32_RXERROR                   0x000F0000
+#define                        BCM43xx_DMA32_RXERR_NOERR       0x00000000
+#define                        BCM43xx_DMA32_RXERR_PROT        0x00010000
+#define                        BCM43xx_DMA32_RXERR_OVERFLOW    0x00020000
+#define                        BCM43xx_DMA32_RXERR_BUFWRITE    0x00030000
+#define                        BCM43xx_DMA32_RXERR_DESCREAD    0x00040000
+#define                BCM43xx_DMA32_RXACTIVE                  0xFFF00000
+
+/* 32-bit DMA descriptor. */
+struct bcm43xx_dmadesc32 {
+       __le32 control;
+       __le32 address;
+} __attribute__((__packed__));
+#define BCM43xx_DMA32_DCTL_BYTECNT             0x00001FFF
+#define BCM43xx_DMA32_DCTL_ADDREXT_MASK                0x00030000
+#define BCM43xx_DMA32_DCTL_ADDREXT_SHIFT       16
+#define BCM43xx_DMA32_DCTL_DTABLEEND           0x10000000
+#define BCM43xx_DMA32_DCTL_IRQ                 0x20000000
+#define BCM43xx_DMA32_DCTL_FRAMEEND            0x40000000
+#define BCM43xx_DMA32_DCTL_FRAMESTART          0x80000000
+
+/* Address field Routing value. */
+#define BCM43xx_DMA32_ROUTING                  0xC0000000
+#define BCM43xx_DMA32_ROUTING_SHIFT            30
+#define                BCM43xx_DMA32_NOTRANS           0x00000000
+#define                BCM43xx_DMA32_CLIENTTRANS       0x40000000
+
+
+
+/*** 64-bit DMA Engine. ***/
+
+/* 64-bit DMA controller registers. */
+#define BCM43xx_DMA64_TXCTL                            0x00
+#define                BCM43xx_DMA64_TXENABLE                  0x00000001
+#define                BCM43xx_DMA64_TXSUSPEND                 0x00000002
+#define                BCM43xx_DMA64_TXLOOPBACK                0x00000004
+#define                BCM43xx_DMA64_TXFLUSH                   0x00000010
+#define                BCM43xx_DMA64_TXADDREXT_MASK            0x00030000
+#define                BCM43xx_DMA64_TXADDREXT_SHIFT           16
+#define BCM43xx_DMA64_TXINDEX                          0x04
+#define BCM43xx_DMA64_TXRINGLO                         0x08
+#define BCM43xx_DMA64_TXRINGHI                         0x0C
+#define BCM43xx_DMA64_TXSTATUS                         0x10
+#define                BCM43xx_DMA64_TXSTATDPTR                0x00001FFF
+#define                BCM43xx_DMA64_TXSTAT                    0xF0000000
+#define                        BCM43xx_DMA64_TXSTAT_DISABLED   0x00000000
+#define                        BCM43xx_DMA64_TXSTAT_ACTIVE     0x10000000
+#define                        BCM43xx_DMA64_TXSTAT_IDLEWAIT   0x20000000
+#define                        BCM43xx_DMA64_TXSTAT_STOPPED    0x30000000
+#define                        BCM43xx_DMA64_TXSTAT_SUSP       0x40000000
+#define BCM43xx_DMA64_TXERROR                          0x14
+#define                BCM43xx_DMA64_TXERRDPTR                 0x0001FFFF
+#define                BCM43xx_DMA64_TXERR                     0xF0000000
+#define                        BCM43xx_DMA64_TXERR_NOERR       0x00000000
+#define                        BCM43xx_DMA64_TXERR_PROT        0x10000000
+#define                        BCM43xx_DMA64_TXERR_UNDERRUN    0x20000000
+#define                        BCM43xx_DMA64_TXERR_TRANSFER    0x30000000
+#define                        BCM43xx_DMA64_TXERR_DESCREAD    0x40000000
+#define                        BCM43xx_DMA64_TXERR_CORE        0x50000000
+#define BCM43xx_DMA64_RXCTL                            0x20
+#define                BCM43xx_DMA64_RXENABLE                  0x00000001
+#define                BCM43xx_DMA64_RXFROFF_MASK              0x000000FE
+#define                BCM43xx_DMA64_RXFROFF_SHIFT             1
+#define                BCM43xx_DMA64_RXDIRECTFIFO              0x00000100
+#define                BCM43xx_DMA64_RXADDREXT_MASK            0x00030000
+#define                BCM43xx_DMA64_RXADDREXT_SHIFT           16
+#define BCM43xx_DMA64_RXINDEX                          0x24
+#define BCM43xx_DMA64_RXRINGLO                         0x28
+#define BCM43xx_DMA64_RXRINGHI                         0x2C
+#define BCM43xx_DMA64_RXSTATUS                         0x30
+#define                BCM43xx_DMA64_RXSTATDPTR                0x00001FFF
+#define                BCM43xx_DMA64_RXSTAT                    0xF0000000
+#define                        BCM43xx_DMA64_RXSTAT_DISABLED   0x00000000
+#define                        BCM43xx_DMA64_RXSTAT_ACTIVE     0x10000000
+#define                        BCM43xx_DMA64_RXSTAT_IDLEWAIT   0x20000000
+#define                        BCM43xx_DMA64_RXSTAT_STOPPED    0x30000000
+#define                        BCM43xx_DMA64_RXSTAT_SUSP       0x40000000
+#define BCM43xx_DMA64_RXERROR                          0x34
+#define                BCM43xx_DMA64_RXERRDPTR                 0x0001FFFF
+#define                BCM43xx_DMA64_RXERR                     0xF0000000
+#define                        BCM43xx_DMA64_RXERR_NOERR       0x00000000
+#define                        BCM43xx_DMA64_RXERR_PROT        0x10000000
+#define                        BCM43xx_DMA64_RXERR_UNDERRUN    0x20000000
+#define                        BCM43xx_DMA64_RXERR_TRANSFER    0x30000000
+#define                        BCM43xx_DMA64_RXERR_DESCREAD    0x40000000
+#define                        BCM43xx_DMA64_RXERR_CORE        0x50000000
+
+/* 64-bit DMA descriptor. */
+struct bcm43xx_dmadesc64 {
+       __le32 control0;
+       __le32 control1;
+       __le32 address_low;
+       __le32 address_high;
+} __attribute__((__packed__));
+#define BCM43xx_DMA64_DCTL0_DTABLEEND          0x10000000
+#define BCM43xx_DMA64_DCTL0_IRQ                        0x20000000
+#define BCM43xx_DMA64_DCTL0_FRAMEEND           0x40000000
+#define BCM43xx_DMA64_DCTL0_FRAMESTART         0x80000000
+#define BCM43xx_DMA64_DCTL1_BYTECNT            0x00001FFF
+#define BCM43xx_DMA64_DCTL1_ADDREXT_MASK       0x00030000
+#define BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT      16
+
+/* Address field Routing value. */
+#define BCM43xx_DMA64_ROUTING                  0xC0000000
+#define BCM43xx_DMA64_ROUTING_SHIFT            30
+#define                BCM43xx_DMA64_NOTRANS           0x00000000
+#define                BCM43xx_DMA64_CLIENTTRANS       0x80000000
+
+
+
+struct bcm43xx_dmadesc_generic {
+       union {
+               struct bcm43xx_dmadesc32 dma32;
+               struct bcm43xx_dmadesc64 dma64;
+       } __attribute__((__packed__));
+} __attribute__((__packed__));
+
 
 /* Misc DMA constants */
 #define BCM43xx_DMA_RINGMEMSIZE                PAGE_SIZE
-#define BCM43xx_DMA_BUSADDRMAX         0x3FFFFFFF
-#define BCM43xx_DMA_DMABUSADDROFFSET   (1 << 30)
-#define BCM43xx_DMA1_RX_FRAMEOFFSET    30
-#define BCM43xx_DMA4_RX_FRAMEOFFSET    0
+#define BCM43xx_DMA0_RX_FRAMEOFFSET    30
+#define BCM43xx_DMA3_RX_FRAMEOFFSET    0
+
 
 /* DMA engine tuning knobs */
 #define BCM43xx_TXRING_SLOTS           512
 #define BCM43xx_RXRING_SLOTS           64
-#define BCM43xx_DMA1_RXBUFFERSIZE      (2304 + 100)
-#define BCM43xx_DMA4_RXBUFFERSIZE      16
+#define BCM43xx_DMA0_RX_BUFFERSIZE     (2304 + 100)
+#define BCM43xx_DMA3_RX_BUFFERSIZE     16
 /* Suspend the tx queue, if less than this percent slots are free. */
 #define BCM43xx_TXSUSPEND_PERCENT      20
 /* Resume the tx queue, if more than this percent slots are free. */
@@ -85,17 +201,6 @@ struct bcm43xx_private;
 struct bcm43xx_private;
 struct bcm43xx_xmitstatus;
 
-
-struct bcm43xx_dmadesc {
-       __le32 _control;
-       __le32 _address;
-} __attribute__((__packed__));
-
-/* Macros to access the bcm43xx_dmadesc struct */
-#define get_desc_ctl(desc)             le32_to_cpu((desc)->_control)
-#define set_desc_ctl(desc, ctl)                do { (desc)->_control = 
cpu_to_le32(ctl); } while (0)
-#define get_desc_addr(desc)            le32_to_cpu((desc)->_address)
-#define set_desc_addr(desc, addr)      do { (desc)->_address = 
cpu_to_le32(addr); } while (0)
 
 struct bcm43xx_dmadesc_meta {
        /* The kernel DMA-able buffer. */
@@ -105,15 +210,14 @@ struct bcm43xx_dmadesc_meta {
 };
 
 struct bcm43xx_dmaring {
-       struct bcm43xx_private *bcm;
        /* Kernel virtual base address of the ring memory. */
-       struct bcm43xx_dmadesc *vbase;
-       /* DMA memory offset */
-       dma_addr_t memoffset;
+       void *descbase;
+       /* Meta data about all descriptors. */
+       struct bcm43xx_dmadesc_meta *meta;
+       /* DMA Routing value. */
+       u32 routing;
        /* (Unadjusted) DMA base bus-address of the ring memory. */
        dma_addr_t dmabase;
-       /* Meta data about all descriptors. */
-       struct bcm43xx_dmadesc_meta *meta;
        /* Number of descriptor slots in the ring. */
        int nr_slots;
        /* Number of used descriptor slots. */
@@ -127,12 +231,17 @@ struct bcm43xx_dmaring {
        u32 frameoffset;
        /* Descriptor buffer size. */
        u16 rx_buffersize;
-       /* The MMIO base register of the DMA controller, this
-        * ring is posted to.
-        */
+       /* The MMIO base register of the DMA controller. */
        u16 mmio_base;
-       u8 tx:1,        /* TRUE, if this is a TX ring. */
-          suspended:1; /* TRUE, if transfers are suspended on this ring. */
+       /* DMA controller index number (0-5). */
+       int index;
+       /* Boolean. Is this a TX ring? */
+       u8 tx;
+       /* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
+       u8 dma64;
+       /* Boolean. Are transfers suspended on this ring? */
+       u8 suspended;
+       struct bcm43xx_private *bcm;
 #ifdef CONFIG_BCM43XX_DEBUG
        /* Maximum number of used slots. */
        int max_used_slots;
@@ -141,6 +250,34 @@ struct bcm43xx_dmaring {
 
 
 static inline
+int bcm43xx_dma_desc2idx(struct bcm43xx_dmaring *ring,
+                        struct bcm43xx_dmadesc_generic *desc)
+{
+       if (ring->dma64) {
+               struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
+               return (int)(&(desc->dma64) - dd64);
+       } else {
+               struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
+               return (int)(&(desc->dma32) - dd32);
+       }
+}
+
+static inline
+struct bcm43xx_dmadesc_generic * bcm43xx_dma_idx2desc(struct bcm43xx_dmaring 
*ring,
+                                                     int slot,
+                                                     struct 
bcm43xx_dmadesc_meta **meta)
+{
+       *meta = &(ring->meta[slot]);
+       if (ring->dma64) {
+               struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
+               return (struct bcm43xx_dmadesc_generic *)(&(dd64[slot]));
+       } else {
+               struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
+               return (struct bcm43xx_dmadesc_generic *)(&(dd32[slot]));
+       }
+}
+
+static inline
 u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
                     u16 offset)
 {
@@ -159,9 +296,13 @@ void bcm43xx_dma_free(struct bcm43xx_pri
 void bcm43xx_dma_free(struct bcm43xx_private *bcm);
 
 int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
-                                  u16 dmacontroller_mmio_base);
+                                  u16 dmacontroller_mmio_base,
+                                  int dma64);
 int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
-                                  u16 dmacontroller_mmio_base);
+                                  u16 dmacontroller_mmio_base,
+                                  int dma64);
+
+u16 bcm43xx_dmacontroller_base(int dma64bit, int dmacontroller_idx);
 
 void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
 void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
@@ -173,7 +314,6 @@ int bcm43xx_dma_tx(struct bcm43xx_privat
                   struct ieee80211_txb *txb);
 void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
 
-
 #else /* CONFIG_BCM43XX_DMA */
 
 
@@ -188,13 +328,15 @@ void bcm43xx_dma_free(struct bcm43xx_pri
 }
 static inline
 int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
-                                  u16 dmacontroller_mmio_base)
+                                  u16 dmacontroller_mmio_base,
+                                  int dma64)
 {
        return 0;
 }
 static inline
 int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
-                                  u16 dmacontroller_mmio_base)
+                                  u16 dmacontroller_mmio_base,
+                                  int dma64)
 {
        return 0;
 }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_leds.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c       Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c       Wed Oct 03 10:00:44 
2007 +0100
@@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned l
        struct bcm43xx_private *bcm = led->bcm;
        unsigned long flags;
 
-       bcm43xx_lock_irqonly(bcm, flags);
+       spin_lock_irqsave(&bcm->leds_lock, flags);
        if (led->blink_interval) {
                bcm43xx_led_changestate(led);
                mod_timer(&led->blink_timer, jiffies + led->blink_interval);
        }
-       bcm43xx_unlock_irqonly(bcm, flags);
+       spin_unlock_irqrestore(&bcm->leds_lock, flags);
 }
 
 static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
@@ -177,7 +177,9 @@ void bcm43xx_leds_update(struct bcm43xx_
        int i, turn_on;
        unsigned long interval = 0;
        u16 ledctl;
-
+       unsigned long flags;
+
+       spin_lock_irqsave(&bcm->leds_lock, flags);
        ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
        for (i = 0; i < BCM43xx_NR_LEDS; i++) {
                led = &(bcm->leds[i]);
@@ -266,6 +268,7 @@ void bcm43xx_leds_update(struct bcm43xx_
                        ledctl &= ~(1 << i);
        }
        bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
+       spin_unlock_irqrestore(&bcm->leds_lock, flags);
 }
 
 void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
@@ -274,7 +277,9 @@ void bcm43xx_leds_switch_all(struct bcm4
        u16 ledctl;
        int i;
        int bit_on;
-
+       unsigned long flags;
+
+       spin_lock_irqsave(&bcm->leds_lock, flags);
        ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
        for (i = 0; i < BCM43xx_NR_LEDS; i++) {
                led = &(bcm->leds[i]);
@@ -290,4 +295,5 @@ void bcm43xx_leds_switch_all(struct bcm4
                        ledctl &= ~(1 << i);
        }
        bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
-}
+       spin_unlock_irqrestore(&bcm->leds_lock, flags);
+}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_main.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c       Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c       Wed Oct 03 10:00:44 
2007 +0100
@@ -509,22 +509,19 @@ static void bcm43xx_synchronize_irq(stru
 }
 
 /* Make sure we don't receive more data from the device. */
-static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 
*oldstate)
+static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm)
 {
        unsigned long flags;
-       u32 old;
-
-       bcm43xx_lock_irqonly(bcm, flags);
+
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
-               bcm43xx_unlock_irqonly(bcm, flags);
+               spin_unlock_irqrestore(&bcm->irq_lock, flags);
                return -EBUSY;
        }
-       old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
-       bcm43xx_unlock_irqonly(bcm, flags);
+       bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
+       bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); /* flush */
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
        bcm43xx_synchronize_irq(bcm);
-
-       if (oldstate)
-               *oldstate = old;
 
        return 0;
 }
@@ -537,7 +534,6 @@ static int bcm43xx_read_radioinfo(struct
        u16 manufact;
        u16 version;
        u8 revision;
-       s8 i;
 
        if (bcm->chip_id == 0x4317) {
                if (bcm->chip_rev == 0x00)
@@ -580,19 +576,10 @@ static int bcm43xx_read_radioinfo(struct
        radio->version = version;
        radio->revision = revision;
 
-       /* Set default attenuation values. */
-       radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
-       radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
-       radio->txctl1 = bcm43xx_default_txctl1(bcm);
-       radio->txctl2 = 0xFFFF;
        if (phy->type == BCM43xx_PHYTYPE_A)
                radio->txpower_desired = bcm->sprom.maxpower_aphy;
        else
                radio->txpower_desired = bcm->sprom.maxpower_bgphy;
-
-       /* Initialize the in-memory nrssi Lookup Table. */
-       for (i = 0; i < 64; i++)
-               radio->nrssi_lt[i] = i;
 
        return 0;
 
@@ -1250,10 +1237,6 @@ int bcm43xx_switch_core(struct bcm43xx_p
                goto out;
 
        bcm->current_core = new_core;
-       bcm->current_80211_core_idx = -1;
-       if (new_core->id == BCM43xx_COREID_80211)
-               bcm->current_80211_core_idx = (int)(new_core - 
&(bcm->core_80211[0]));
-
 out:
        return err;
 }
@@ -1389,6 +1372,7 @@ void bcm43xx_wireless_core_reset(struct 
        if ((bcm43xx_core_enabled(bcm)) &&
            !bcm43xx_using_pio(bcm)) {
 //FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
+#if 0
 #ifndef CONFIG_BCM947XX
                /* reset all used DMA controllers. */
                bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
@@ -1398,6 +1382,7 @@ void bcm43xx_wireless_core_reset(struct 
                bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
                if (bcm->current_core->rev < 5)
                        bcm43xx_dmacontroller_rx_reset(bcm, 
BCM43xx_MMIO_DMA4_BASE);
+#endif
 #endif
        }
        if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
@@ -1423,43 +1408,23 @@ static void bcm43xx_wireless_core_disabl
        bcm43xx_core_disable(bcm, 0);
 }
 
-/* Mark the current 80211 core inactive.
- * "active_80211_core" is the other 80211 core, which is used.
- */
-static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm,
-                                              struct bcm43xx_coreinfo 
*active_80211_core)
+/* Mark the current 80211 core inactive. */
+static void bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm)
 {
        u32 sbtmstatelow;
-       struct bcm43xx_coreinfo *old_core;
-       int err = 0;
 
        bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
        bcm43xx_radio_turn_off(bcm);
        sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
-       sbtmstatelow &= ~0x200a0000;
-       sbtmstatelow |= 0xa0000;
+       sbtmstatelow &= 0xDFF5FFFF;
+       sbtmstatelow |= 0x000A0000;
        bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
        udelay(1);
        sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
-       sbtmstatelow &= ~0xa0000;
-       sbtmstatelow |= 0x80000;
+       sbtmstatelow &= 0xFFF5FFFF;
+       sbtmstatelow |= 0x00080000;
        bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
        udelay(1);
-
-       if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G) {
-               old_core = bcm->current_core;
-               err = bcm43xx_switch_core(bcm, active_80211_core);
-               if (err)
-                       goto out;
-               sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
-               sbtmstatelow &= ~0x20000000;
-               sbtmstatelow |= 0x20000000;
-               bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
-               err = bcm43xx_switch_core(bcm, old_core);
-       }
-
-out:
-       return err;
 }
 
 static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
@@ -1484,17 +1449,32 @@ static void handle_irq_transmit_status(s
 
                bcm43xx_debugfs_log_txstat(bcm, &stat);
 
-               if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
+               if (stat.flags & BCM43xx_TXSTAT_FLAG_AMPDU)
                        continue;
-               if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
-                       //TODO: packet was not acked (was lost)
-               }
-               //TODO: There are more (unknown) flags to test. see 
bcm43xx_main.h
+               if (stat.flags & BCM43xx_TXSTAT_FLAG_INTER)
+                       continue;
 
                if (bcm43xx_using_pio(bcm))
                        bcm43xx_pio_handle_xmitstatus(bcm, &stat);
                else
                        bcm43xx_dma_handle_xmitstatus(bcm, &stat);
+       }
+}
+
+static void drain_txstatus_queue(struct bcm43xx_private *bcm)
+{
+       u32 dummy;
+
+       if (bcm->current_core->rev < 5)
+               return;
+       /* Read all entries from the microcode TXstatus FIFO
+        * and throw them away.
+        */
+       while (1) {
+               dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
+               if (!dummy)
+                       break;
+               dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
        }
 }
 
@@ -1581,17 +1561,7 @@ static void handle_irq_noise(struct bcm4
                else
                        average -= 48;
 
-/* FIXME: This is wrong, but people want fancy stats. well... */
-bcm->stats.noise = average;
-               if (average > -65)
-                       bcm->stats.link_quality = 0;
-               else if (average > -75)
-                       bcm->stats.link_quality = 1;
-               else if (average > -85)
-                       bcm->stats.link_quality = 2;
-               else
-                       bcm->stats.link_quality = 3;
-//             dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", 
bcm->stats.link_quality, average);
+               bcm->stats.noise = average;
 drop_calculation:
                bcm->noisecalc.calculation_running = 0;
                return;
@@ -1709,8 +1679,9 @@ static void bcm43xx_interrupt_tasklet(st
 static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
 {
        u32 reason;
-       u32 dma_reason[4];
-       int activity = 0;
+       u32 dma_reason[6];
+       u32 merged_dma_reason = 0;
+       int i, activity = 0;
        unsigned long flags;
 
 #ifdef CONFIG_BCM43XX_DEBUG
@@ -1720,12 +1691,12 @@ static void bcm43xx_interrupt_tasklet(st
 # define bcmirq_handled(irq)   do { /* nothing */ } while (0)
 #endif /* CONFIG_BCM43XX_DEBUG*/
 
-       bcm43xx_lock_irqonly(bcm, flags);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        reason = bcm->irq_reason;
-       dma_reason[0] = bcm->dma_reason[0];
-       dma_reason[1] = bcm->dma_reason[1];
-       dma_reason[2] = bcm->dma_reason[2];
-       dma_reason[3] = bcm->dma_reason[3];
+       for (i = 5; i >= 0; i--) {
+               dma_reason[i] = bcm->dma_reason[i];
+               merged_dma_reason |= dma_reason[i];
+       }
 
        if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
                /* TX error. We get this when Template Ram is written in wrong 
endianess
@@ -1736,27 +1707,25 @@ static void bcm43xx_interrupt_tasklet(st
                printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
                bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
        }
-       if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
-                    (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
-                    (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
-                    (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
+       if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
                printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
-                                    "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
+                                    "0x%08X, 0x%08X, 0x%08X, "
+                                    "0x%08X, 0x%08X, 0x%08X\n",
                        dma_reason[0], dma_reason[1],
-                       dma_reason[2], dma_reason[3]);
+                       dma_reason[2], dma_reason[3],
+                       dma_reason[4], dma_reason[5]);
                bcm43xx_controller_restart(bcm, "DMA error");
                mmiowb();
-               bcm43xx_unlock_irqonly(bcm, flags);
+               spin_unlock_irqrestore(&bcm->irq_lock, flags);
                return;
        }
-       if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
-                    (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
-                    (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
-                    (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
+       if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
                printkl(KERN_ERR PFX "DMA error: "
-                                    "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
+                                    "0x%08X, 0x%08X, 0x%08X, "
+                                    "0x%08X, 0x%08X, 0x%08X\n",
                        dma_reason[0], dma_reason[1],
-                       dma_reason[2], dma_reason[3]);
+                       dma_reason[2], dma_reason[3],
+                       dma_reason[4], dma_reason[5]);
        }
 
        if (reason & BCM43xx_IRQ_PS) {
@@ -1791,8 +1760,6 @@ static void bcm43xx_interrupt_tasklet(st
        }
 
        /* Check the DMA reason registers for received data. */
-       assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
-       assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
        if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
                if (bcm43xx_using_pio(bcm))
                        bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
@@ -1800,13 +1767,17 @@ static void bcm43xx_interrupt_tasklet(st
                        bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
                /* We intentionally don't set "activity" to 1, here. */
        }
+       assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
+       assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
        if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
                if (bcm43xx_using_pio(bcm))
                        bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
                else
-                       bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1);
+                       bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
                activity = 1;
        }
+       assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
+       assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
        bcmirq_handled(BCM43xx_IRQ_RX);
 
        if (reason & BCM43xx_IRQ_XMIT_STATUS) {
@@ -1834,7 +1805,7 @@ static void bcm43xx_interrupt_tasklet(st
                bcm43xx_leds_update(bcm, activity);
        bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
        mmiowb();
-       bcm43xx_unlock_irqonly(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
 }
 
 static void pio_irq_workaround(struct bcm43xx_private *bcm,
@@ -1863,14 +1834,18 @@ static void bcm43xx_interrupt_ack(struct
 
        bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
 
+       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
+                       bcm->dma_reason[0]);
        bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
-                       bcm->dma_reason[0]);
+                       bcm->dma_reason[1]);
        bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
-                       bcm->dma_reason[1]);
+                       bcm->dma_reason[2]);
        bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
-                       bcm->dma_reason[2]);
+                       bcm->dma_reason[3]);
        bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
-                       bcm->dma_reason[3]);
+                       bcm->dma_reason[4]);
+       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
+                       bcm->dma_reason[5]);
 }
 
 /* Interrupt handler top-half */
@@ -1885,14 +1860,8 @@ static irqreturn_t bcm43xx_interrupt_han
 
        spin_lock(&bcm->irq_lock);
 
-       /* Only accept IRQs, if we are initialized properly.
-        * This avoids an RX race while initializing.
-        * We should probably not enable IRQs before we are initialized
-        * completely, but some careful work is needed to fix this. I think it
-        * is best to stay with this cheap workaround for now... .
-        */
-       if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED))
-               goto out;
+       assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
+       assert(bcm->current_core->id == BCM43xx_COREID_80211);
 
        reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
        if (reason == 0xffffffff) {
@@ -1904,14 +1873,18 @@ static irqreturn_t bcm43xx_interrupt_han
        if (!reason)
                goto out;
 
-       bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
-                            & 0x0001dc00;
-       bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
-                            & 0x0000dc00;
-       bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
-                            & 0x0000dc00;
-       bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
-                            & 0x0001dc00;
+       bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
+                            & 0x0001DC00;
+       bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
+                            & 0x0000DC00;
+       bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
+                            & 0x0000DC00;
+       bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
+                            & 0x0001DC00;
+       bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
+                            & 0x0000DC00;
+       bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
+                            & 0x0000DC00;
 
        bcm43xx_interrupt_ack(bcm, reason);
 
@@ -1930,16 +1903,18 @@ out:
 
 static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
 {
+       struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
+
        if (bcm->firmware_norelease && !force)
                return; /* Suspending or controller reset. */
-       release_firmware(bcm->ucode);
-       bcm->ucode = NULL;
-       release_firmware(bcm->pcm);
-       bcm->pcm = NULL;
-       release_firmware(bcm->initvals0);
-       bcm->initvals0 = NULL;
-       release_firmware(bcm->initvals1);
-       bcm->initvals1 = NULL;
+       release_firmware(phy->ucode);
+       phy->ucode = NULL;
+       release_firmware(phy->pcm);
+       phy->pcm = NULL;
+       release_firmware(phy->initvals0);
+       phy->initvals0 = NULL;
+       release_firmware(phy->initvals1);
+       phy->initvals1 = NULL;
 }
 
 static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
@@ -1950,11 +1925,11 @@ static int bcm43xx_request_firmware(stru
        int nr;
        char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
 
-       if (!bcm->ucode) {
+       if (!phy->ucode) {
                snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
                         (rev >= 5 ? 5 : rev),
                         modparam_fwpostfix);
-               err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev);
+               err = request_firmware(&phy->ucode, buf, &bcm->pci_dev->dev);
                if (err) {
                        printk(KERN_ERR PFX 
                               "Error: Microcode \"%s\" not available or load 
failed.\n",
@@ -1963,12 +1938,12 @@ static int bcm43xx_request_firmware(stru
                }
        }
 
-       if (!bcm->pcm) {
+       if (!phy->pcm) {
                snprintf(buf, ARRAY_SIZE(buf),
                         "bcm43xx_pcm%d%s.fw",
                         (rev < 5 ? 4 : 5),
                         modparam_fwpostfix);
-               err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev);
+               err = request_firmware(&phy->pcm, buf, &bcm->pci_dev->dev);
                if (err) {
                        printk(KERN_ERR PFX
                               "Error: PCM \"%s\" not available or load 
failed.\n",
@@ -1977,7 +1952,7 @@ static int bcm43xx_request_firmware(stru
                }
        }
 
-       if (!bcm->initvals0) {
+       if (!phy->initvals0) {
                if (rev == 2 || rev == 4) {
                        switch (phy->type) {
                        case BCM43xx_PHYTYPE_A:
@@ -2008,20 +1983,20 @@ static int bcm43xx_request_firmware(stru
                snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
                         nr, modparam_fwpostfix);
 
-               err = request_firmware(&bcm->initvals0, buf, 
&bcm->pci_dev->dev);
+               err = request_firmware(&phy->initvals0, buf, 
&bcm->pci_dev->dev);
                if (err) {
                        printk(KERN_ERR PFX 
                               "Error: InitVals \"%s\" not available or load 
failed.\n",
                                buf);
                        goto error;
                }
-               if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) {
+               if (phy->initvals0->size % sizeof(struct bcm43xx_initval)) {
                        printk(KERN_ERR PFX "InitVals fileformat error.\n");
                        goto error;
                }
        }
 
-       if (!bcm->initvals1) {
+       if (!phy->initvals1) {
                if (rev >= 5) {
                        u32 sbtmstatehigh;
 
@@ -2043,14 +2018,14 @@ static int bcm43xx_request_firmware(stru
                        snprintf(buf, ARRAY_SIZE(buf), 
"bcm43xx_initval%02d%s.fw",
                                 nr, modparam_fwpostfix);
 
-                       err = request_firmware(&bcm->initvals1, buf, 
&bcm->pci_dev->dev);
+                       err = request_firmware(&phy->initvals1, buf, 
&bcm->pci_dev->dev);
                        if (err) {
                                printk(KERN_ERR PFX 
                                       "Error: InitVals \"%s\" not available or 
load failed.\n",
                                        buf);
                                goto error;
                        }
-                       if (bcm->initvals1->size % sizeof(struct 
bcm43xx_initval)) {
+                       if (phy->initvals1->size % sizeof(struct 
bcm43xx_initval)) {
                                printk(KERN_ERR PFX "InitVals fileformat 
error.\n");
                                goto error;
                        }
@@ -2070,12 +2045,13 @@ err_noinitval:
 
 static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
 {
+       struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
        const u32 *data;
        unsigned int i, len;
 
        /* Upload Microcode. */
-       data = (u32 *)(bcm->ucode->data);
-       len = bcm->ucode->size / sizeof(u32);
+       data = (u32 *)(phy->ucode->data);
+       len = phy->ucode->size / sizeof(u32);
        bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
        for (i = 0; i < len; i++) {
                bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
@@ -2084,8 +2060,8 @@ static void bcm43xx_upload_microcode(str
        }
 
        /* Upload PCM data. */
-       data = (u32 *)(bcm->pcm->data);
-       len = bcm->pcm->size / sizeof(u32);
+       data = (u32 *)(phy->pcm->data);
+       len = phy->pcm->size / sizeof(u32);
        bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
        bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
        bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
@@ -2131,15 +2107,16 @@ err_format:
 
 static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
 {
+       struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
        int err;
 
-       err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval 
*)bcm->initvals0->data,
-                                    bcm->initvals0->size / sizeof(struct 
bcm43xx_initval));
+       err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval 
*)phy->initvals0->data,
+                                    phy->initvals0->size / sizeof(struct 
bcm43xx_initval));
        if (err)
                goto out;
-       if (bcm->initvals1) {
-               err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval 
*)bcm->initvals1->data,
-                                            bcm->initvals1->size / 
sizeof(struct bcm43xx_initval));
+       if (phy->initvals1) {
+               err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval 
*)phy->initvals1->data,
+                                            phy->initvals1->size / 
sizeof(struct bcm43xx_initval));
                if (err)
                        goto out;
        }
@@ -2156,9 +2133,7 @@ static struct pci_device_id bcm43xx_47xx
 
 static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
 {
-       int res;
-       unsigned int i;
-       u32 data;
+       int err;
 
        bcm->irq = bcm->pci_dev->irq;
 #ifdef CONFIG_BCM947XX
@@ -2175,32 +2150,12 @@ static int bcm43xx_initialize_irq(struct
                }
        }
 #endif
-       res = request_irq(bcm->irq, bcm43xx_interrupt_handler,
+       err = request_irq(bcm->irq, bcm43xx_interrupt_handler,
                          IRQF_SHARED, KBUILD_MODNAME, bcm);
-       if (res) {
+       if (err)
                printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
-               return -ENODEV;
-       }
-       bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff);
-       bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
-       i = 0;
-       while (1) {
-               data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
-               if (data == BCM43xx_IRQ_READY)
-                       break;
-               i++;
-               if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
-                       printk(KERN_ERR PFX "Card IRQ register not responding. "
-                                           "Giving up.\n");
-                       free_irq(bcm->irq, bcm);
-                       return -ENODEV;
-               }
-               udelay(10);
-       }
-       // dummy read
-       bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
-
-       return 0;
+
+       return err;
 }
 
 /* Switch to the core used to write the GPIO register.
@@ -2298,13 +2253,17 @@ static int bcm43xx_gpio_cleanup(struct b
 /* http://bcm-specs.sipsolutions.net/EnableMac */
 void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
 {
-       bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
-                       bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
-                       | BCM43xx_SBF_MAC_ENABLED);
-       bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
-       bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
-       bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
-       bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
+       bcm->mac_suspended--;
+       assert(bcm->mac_suspended >= 0);
+       if (bcm->mac_suspended == 0) {
+               bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+                               bcm43xx_read32(bcm, 
BCM43xx_MMIO_STATUS_BITFIELD)
+                               | BCM43xx_SBF_MAC_ENABLED);
+               bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 
BCM43xx_IRQ_READY);
+               bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy 
read */
+               bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read 
*/
+               bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
+       }
 }
 
 /* http://bcm-specs.sipsolutions.net/SuspendMAC */
@@ -2313,18 +2272,23 @@ void bcm43xx_mac_suspend(struct bcm43xx_
        int i;
        u32 tmp;
 
-       bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
-       bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
-                       bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
-                       & ~BCM43xx_SBF_MAC_ENABLED);
-       bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
-       for (i = 100000; i; i--) {
-               tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
-               if (tmp & BCM43xx_IRQ_READY)
-                       return;
-               udelay(10);
-       }
-       printkl(KERN_ERR PFX "MAC suspend failed\n");
+       assert(bcm->mac_suspended >= 0);
+       if (bcm->mac_suspended == 0) {
+               bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
+               bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+                               bcm43xx_read32(bcm, 
BCM43xx_MMIO_STATUS_BITFIELD)
+                               & ~BCM43xx_SBF_MAC_ENABLED);
+               bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read 
*/
+               for (i = 10000; i; i--) {
+                       tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
+                       if (tmp & BCM43xx_IRQ_READY)
+                               goto out;
+                       udelay(1);
+               }
+               printkl(KERN_ERR PFX "MAC suspend failed\n");
+       }
+out:
+       bcm->mac_suspended++;
 }
 
 void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
@@ -2394,7 +2358,6 @@ static void bcm43xx_chip_cleanup(struct 
        if (!modparam_noleds)
                bcm43xx_leds_exit(bcm);
        bcm43xx_gpio_cleanup(bcm);
-       free_irq(bcm->irq, bcm);
        bcm43xx_release_firmware(bcm, 0);
 }
 
@@ -2406,7 +2369,7 @@ static int bcm43xx_chip_init(struct bcm4
        struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
        struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
        int err;
-       int tmp;
+       int i, tmp;
        u32 value32;
        u16 value16;
 
@@ -2419,13 +2382,53 @@ static int bcm43xx_chip_init(struct bcm4
                goto out;
        bcm43xx_upload_microcode(bcm);
 
-       err = bcm43xx_initialize_irq(bcm);
+       bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xFFFFFFFF);
+       bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
+       i = 0;
+       while (1) {
+               value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
+               if (value32 == BCM43xx_IRQ_READY)
+                       break;
+               i++;
+               if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
+                       printk(KERN_ERR PFX "IRQ_READY timeout\n");
+                       err = -ENODEV;
+                       goto err_release_fw;
+               }
+               udelay(10);
+       }
+       bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
+
+       value16 = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+                                    BCM43xx_UCODE_REVISION);
+
+       dprintk(KERN_INFO PFX "Microcode rev 0x%x, pl 0x%x "
+               "(20%.2i-%.2i-%.2i  %.2i:%.2i:%.2i)\n", value16,
+               bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+                                  BCM43xx_UCODE_PATCHLEVEL),
+               (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+                                   BCM43xx_UCODE_DATE) >> 12) & 0xf,
+               (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+                                   BCM43xx_UCODE_DATE) >> 8) & 0xf,
+               bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+                                  BCM43xx_UCODE_DATE) & 0xff,
+               (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+                                  BCM43xx_UCODE_TIME) >> 11) & 0x1f,
+               (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+                                  BCM43xx_UCODE_TIME) >> 5) & 0x3f,
+               bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+                                  BCM43xx_UCODE_TIME) & 0x1f);
+
+       if ( value16 > 0x128 ) {
+               dprintk(KERN_ERR PFX
+                       "Firmware: no support for microcode rev > 0x128\n");
+               err = -1;
+               goto err_release_fw;
+       }
+
+       err = bcm43xx_gpio_init(bcm);
        if (err)
                goto err_release_fw;
-
-       err = bcm43xx_gpio_init(bcm);
-       if (err)
-               goto err_free_irq;
 
        err = bcm43xx_upload_initvals(bcm);
        if (err)
@@ -2489,10 +2492,12 @@ static int bcm43xx_chip_init(struct bcm4
                bcm43xx_write32(bcm, 0x018C, 0x02000000);
        }
        bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
-       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00);
+       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
+       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
        bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
-       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00);
-       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00);
+       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
+       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
+       bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
 
        value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
        value32 |= 0x00100000;
@@ -2509,8 +2514,6 @@ err_radio_off:
        bcm43xx_radio_turn_off(bcm);
 err_gpio_cleanup:
        bcm43xx_gpio_cleanup(bcm);
-err_free_irq:
-       free_irq(bcm->irq, bcm);
 err_release_fw:
        bcm43xx_release_firmware(bcm, 1);
        goto out;
@@ -2550,11 +2553,9 @@ static void bcm43xx_init_struct_phyinfo(
 {
        /* Initialize a "phyinfo" structure. The structure is already
         * zeroed out.
+        * This is called on insmod time to initialize members.
         */
-       phy->antenna_diversity = 0xFFFF;
        phy->savedpctlreg = 0xFFFF;
-       phy->minlowsig[0] = 0xFFFF;
-       phy->minlowsig[1] = 0xFFFF;
        spin_lock_init(&phy->lock);
 }
 
@@ -2562,14 +2563,11 @@ static void bcm43xx_init_struct_radioinf
 {
        /* Initialize a "radioinfo" structure. The structure is already
         * zeroed out.
+        * This is called on insmod time to initialize members.
         */
        radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
        radio->channel = 0xFF;
        radio->initial_channel = 0xFF;
-       radio->lofcal = 0xFFFF;
-       radio->initval = 0xFFFF;
-       radio->nrssi[0] = -1000;
-       radio->nrssi[1] = -1000;
 }
 
 static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
@@ -2587,7 +2585,6 @@ static int bcm43xx_probe_cores(struct bc
                                    * BCM43xx_MAX_80211_CORES);
        memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
                                        * BCM43xx_MAX_80211_CORES);
-       bcm->current_80211_core_idx = -1;
        bcm->nr_80211_available = 0;
        bcm->current_core = NULL;
        bcm->active_80211_core = NULL;
@@ -2757,6 +2754,7 @@ static int bcm43xx_probe_cores(struct bc
                                goto out;
                        }
                        bcm->nr_80211_available++;
+                       core->priv = ext_80211;
                        bcm43xx_init_struct_phyinfo(&ext_80211->phy);
                        bcm43xx_init_struct_radioinfo(&ext_80211->radio);
                        break;
@@ -2857,7 +2855,8 @@ static void bcm43xx_wireless_core_cleanu
 }
 
 /* http://bcm-specs.sipsolutions.net/80211Init */
-static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
+static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
+                                     int active_wlcore)
 {
        struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
        struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
@@ -2939,19 +2938,26 @@ static int bcm43xx_wireless_core_init(st
        if (bcm->current_core->rev >= 5)
                bcm43xx_write16(bcm, 0x043C, 0x000C);
 
-       if (bcm43xx_using_pio(bcm))
-               err = bcm43xx_pio_init(bcm);
-       else
-               err = bcm43xx_dma_init(bcm);
-       if (err)
-               goto err_chip_cleanup;
+       if (active_wlcore) {
+               if (bcm43xx_using_pio(bcm))
+                       err = bcm43xx_pio_init(bcm);
+               else
+                       err = bcm43xx_dma_init(bcm);
+               if (err)
+                       goto err_chip_cleanup;
+       }
        bcm43xx_write16(bcm, 0x0612, 0x0050);
        bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
        bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
 
-       bcm43xx_mac_enable(bcm);
-       bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
-
+       if (active_wlcore) {
+               if (radio->initial_channel != 0xFF)
+                       bcm43xx_radio_selectchannel(bcm, 
radio->initial_channel, 0);
+       }
+
+       /* Don't enable MAC/IRQ here, as it will race with the IRQ handler.
+        * We enable it later.
+        */
        bcm->current_core->initialized = 1;
 out:
        return err;
@@ -3064,11 +3070,6 @@ out_switch_back:
        err = bcm43xx_switch_core(bcm, old_core);
 out:
        return err;
-}
-
-static void bcm43xx_softmac_init(struct bcm43xx_private *bcm)
-{
-       ieee80211softmac_start(bcm->net_dev);
 }
 
 static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
@@ -3178,51 +3179,51 @@ static void bcm43xx_periodic_work_handle
        int badness;
 
        badness = estimate_periodic_work_badness(bcm->periodic_state);
+       mutex_lock(&bcm->mutex);
+
+       /* We must fake a started transmission here, as we are going to
+        * disable TX. If we wouldn't fake a TX, it would be possible to
+        * trigger the netdev watchdog, if the last real TX is already
+        * some time on the past (slightly less than 5secs)
+        */
+       bcm->net_dev->trans_start = jiffies;
+       netif_tx_disable(bcm->net_dev);
+
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (badness > BADNESS_LIMIT) {
                /* Periodic work will take a long time, so we want it to
                 * be preemtible.
                 */
-               bcm43xx_lock_irqonly(bcm, flags);
-               netif_stop_queue(bcm->net_dev);
+               bcm43xx_mac_suspend(bcm);
                if (bcm43xx_using_pio(bcm))
                        bcm43xx_pio_freeze_txqueues(bcm);
                savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
-               bcm43xx_unlock_irqonly(bcm, flags);
-               bcm43xx_lock_noirq(bcm);
+               spin_unlock_irqrestore(&bcm->irq_lock, flags);
                bcm43xx_synchronize_irq(bcm);
-       } else {
-               /* Periodic work should take short time, so we want low
-                * locking overhead.
-                */
-               bcm43xx_lock_irqsafe(bcm, flags);
        }
 
        do_periodic_work(bcm);
 
        if (badness > BADNESS_LIMIT) {
-               bcm43xx_lock_irqonly(bcm, flags);
-               if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
-                       tasklet_enable(&bcm->isr_tasklet);
-                       bcm43xx_interrupt_enable(bcm, savedirqs);
-                       if (bcm43xx_using_pio(bcm))
-                               bcm43xx_pio_thaw_txqueues(bcm);
-               }
-               netif_wake_queue(bcm->net_dev);
-               mmiowb();
-               bcm43xx_unlock_irqonly(bcm, flags);
-               bcm43xx_unlock_noirq(bcm);
-       } else {
-               mmiowb();
-               bcm43xx_unlock_irqsafe(bcm, flags);
-       }
-}
-
-static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
+               spin_lock_irqsave(&bcm->irq_lock, flags);
+               tasklet_enable(&bcm->isr_tasklet);
+               bcm43xx_interrupt_enable(bcm, savedirqs);
+               if (bcm43xx_using_pio(bcm))
+                       bcm43xx_pio_thaw_txqueues(bcm);
+               bcm43xx_mac_enable(bcm);
+       }
+       mmiowb();
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       netif_wake_queue(bcm->net_dev);
+       mutex_unlock(&bcm->mutex);
+}
+
+void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
 {
        cancel_rearming_delayed_work(&bcm->periodic_work);
 }
 
-static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
+void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
 {
        struct work_struct *work = &(bcm->periodic_work);
 
@@ -3243,9 +3244,9 @@ static int bcm43xx_rng_read(struct hwrng
        struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
        unsigned long flags;
 
-       bcm43xx_lock_irqonly(bcm, flags);
+       spin_lock_irqsave(&(bcm)->irq_lock, flags);
        *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
-       bcm43xx_unlock_irqonly(bcm, flags);
+       spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
 
        return (sizeof(u16));
 }
@@ -3271,139 +3272,330 @@ static int bcm43xx_rng_init(struct bcm43
        return err;
 }
 
+static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
+{
+       int ret = 0;
+       int i, err;
+       struct bcm43xx_coreinfo *core;
+
+       bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
+       for (i = 0; i < bcm->nr_80211_available; i++) {
+               core = &(bcm->core_80211[i]);
+               assert(core->available);
+               if (!core->initialized)
+                       continue;
+               err = bcm43xx_switch_core(bcm, core);
+               if (err) {
+                       dprintk(KERN_ERR PFX "shutdown_all_wireless_cores "
+                                            "switch_core failed (%d)\n", err);
+                       ret = err;
+                       continue;
+               }
+               bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
+               bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read 
*/
+               bcm43xx_wireless_core_cleanup(bcm);
+               if (core == bcm->active_80211_core)
+                       bcm->active_80211_core = NULL;
+       }
+       free_irq(bcm->irq, bcm);
+       bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
+
+       return ret;
+}
+
 /* This is the opposite of bcm43xx_init_board() */
 static void bcm43xx_free_board(struct bcm43xx_private *bcm)
 {
-       int i, err;
-
-       bcm43xx_lock_noirq(bcm);
+       bcm43xx_rng_exit(bcm);
        bcm43xx_sysfs_unregister(bcm);
        bcm43xx_periodic_tasks_delete(bcm);
 
-       bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
-
-       bcm43xx_rng_exit(bcm);
+       mutex_lock(&(bcm)->mutex);
+       bcm43xx_shutdown_all_wireless_cores(bcm);
+       bcm43xx_pctl_set_crystal(bcm, 0);
+       mutex_unlock(&(bcm)->mutex);
+}
+
+static void prepare_phydata_for_init(struct bcm43xx_phyinfo *phy)
+{
+       phy->antenna_diversity = 0xFFFF;
+       memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
+       memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
+
+       /* Flags */
+       phy->calibrated = 0;
+       phy->is_locked = 0;
+
+       if (phy->_lo_pairs) {
+               memset(phy->_lo_pairs, 0,
+                      sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT);
+       }
+       memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
+}
+
+static void prepare_radiodata_for_init(struct bcm43xx_private *bcm,
+                                      struct bcm43xx_radioinfo *radio)
+{
+       int i;
+
+       /* Set default attenuation values. */
+       radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
+       radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
+       radio->txctl1 = bcm43xx_default_txctl1(bcm);
+       radio->txctl2 = 0xFFFF;
+       radio->txpwr_offset = 0;
+
+       /* NRSSI */
+       radio->nrssislope = 0;
+       for (i = 0; i < ARRAY_SIZE(radio->nrssi); i++)
+               radio->nrssi[i] = -1000;
+       for (i = 0; i < ARRAY_SIZE(radio->nrssi_lt); i++)
+               radio->nrssi_lt[i] = i;
+
+       radio->lofcal = 0xFFFF;
+       radio->initval = 0xFFFF;
+
+       radio->aci_enable = 0;
+       radio->aci_wlan_automatic = 0;
+       radio->aci_hw_rssi = 0;
+}
+
+static void prepare_priv_for_init(struct bcm43xx_private *bcm)
+{
+       int i;
+       struct bcm43xx_coreinfo *core;
+       struct bcm43xx_coreinfo_80211 *wlext;
+
+       assert(!bcm->active_80211_core);
+
+       bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
+
+       /* Flags */
+       bcm->was_initialized = 0;
+       bcm->reg124_set_0x4 = 0;
+
+       /* Stats */
+       memset(&bcm->stats, 0, sizeof(bcm->stats));
+
+       /* Wireless core data */
        for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
-               if (!bcm->core_80211[i].available)
+               core = &(bcm->core_80211[i]);
+               wlext = core->priv;
+
+               if (!core->available)
                        continue;
-               if (!bcm->core_80211[i].initialized)
+               assert(wlext == &(bcm->core_80211_ext[i]));
+
+               prepare_phydata_for_init(&wlext->phy);
+               prepare_radiodata_for_init(bcm, &wlext->radio);
+       }
+
+       /* IRQ related flags */
+       bcm->irq_reason = 0;
+       memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
+       bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
+
+       bcm->mac_suspended = 1;
+
+       /* Noise calculation context */
+       memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
+
+       /* Periodic work context */
+       bcm->periodic_state = 0;
+}
+
+static int wireless_core_up(struct bcm43xx_private *bcm,
+                           int active_wlcore)
+{
+       int err;
+
+       if (!bcm43xx_core_enabled(bcm))
+               bcm43xx_wireless_core_reset(bcm, 1);
+       if (!active_wlcore)
+               bcm43xx_wireless_core_mark_inactive(bcm);
+       err = bcm43xx_wireless_core_init(bcm, active_wlcore);
+       if (err)
+               goto out;
+       if (!active_wlcore)
+               bcm43xx_radio_turn_off(bcm);
+out:
+       return err;
+}
+
+/* Select and enable the "to be used" wireless core.
+ * Locking: bcm->mutex must be aquired before calling this.
+ *          bcm->irq_lock must not be aquired.
+ */
+int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
+                                int phytype)
+{
+       int i, err;
+       struct bcm43xx_coreinfo *active_core = NULL;
+       struct bcm43xx_coreinfo_80211 *active_wlext = NULL;
+       struct bcm43xx_coreinfo *core;
+       struct bcm43xx_coreinfo_80211 *wlext;
+       int adjust_active_sbtmstatelow = 0;
+
+       might_sleep();
+
+       if (phytype < 0) {
+               /* If no phytype is requested, select the first core. */
+               assert(bcm->core_80211[0].available);
+               wlext = bcm->core_80211[0].priv;
+               phytype = wlext->phy.type;
+       }
+       /* Find the requested core. */
+       for (i = 0; i < bcm->nr_80211_available; i++) {
+               core = &(bcm->core_80211[i]);
+               wlext = core->priv;
+               if (wlext->phy.type == phytype) {
+                       active_core = core;
+                       active_wlext = wlext;
+                       break;
+               }
+       }
+       if (!active_core)
+               return -ESRCH; /* No such PHYTYPE on this board. */
+
+       if (bcm->active_80211_core) {
+               /* We already selected a wl core in the past.
+                * So first clean up everything.
+                */
+               dprintk(KERN_INFO PFX "select_wireless_core: cleanup\n");
+               ieee80211softmac_stop(bcm->net_dev);
+               bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
+               err = bcm43xx_disable_interrupts_sync(bcm);
+               assert(!err);
+               tasklet_enable(&bcm->isr_tasklet);
+               err = bcm43xx_shutdown_all_wireless_cores(bcm);
+               if (err)
+                       goto error;
+               /* Ok, everything down, continue to re-initialize. */
+               bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
+       }
+
+       /* Reset all data structures. */
+       prepare_priv_for_init(bcm);
+
+       err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
+       if (err)
+               goto error;
+
+       /* Mark all unused cores "inactive". */
+       for (i = 0; i < bcm->nr_80211_available; i++) {
+               core = &(bcm->core_80211[i]);
+               wlext = core->priv;
+
+               if (core == active_core)
                        continue;
-
-               err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
-               assert(err == 0);
-               bcm43xx_wireless_core_cleanup(bcm);
-       }
-
-       bcm43xx_pctl_set_crystal(bcm, 0);
-
+               err = bcm43xx_switch_core(bcm, core);
+               if (err) {
+                       dprintk(KERN_ERR PFX "Could not switch to inactive "
+                                            "802.11 core (%d)\n", err);
+                       goto error;
+               }
+               err = wireless_core_up(bcm, 0);
+               if (err) {
+                       dprintk(KERN_ERR PFX "core_up for inactive 802.11 core "
+                                            "failed (%d)\n", err);
+                       goto error;
+               }
+               adjust_active_sbtmstatelow = 1;
+       }
+
+       /* Now initialize the active 802.11 core. */
+       err = bcm43xx_switch_core(bcm, active_core);
+       if (err) {
+               dprintk(KERN_ERR PFX "Could not switch to active "
+                                    "802.11 core (%d)\n", err);
+               goto error;
+       }
+       if (adjust_active_sbtmstatelow &&
+           active_wlext->phy.type == BCM43xx_PHYTYPE_G) {
+               u32 sbtmstatelow;
+
+               sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
+               sbtmstatelow |= 0x20000000;
+               bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
+       }
+       err = wireless_core_up(bcm, 1);
+       if (err) {
+               dprintk(KERN_ERR PFX "core_up for active 802.11 core "
+                                    "failed (%d)\n", err);
+               goto error;
+       }
+       err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
+       if (err)
+               goto error;
+       bcm->active_80211_core = active_core;
+
+       bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
+       bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 
*)(bcm->net_dev->dev_addr));
+       bcm43xx_security_init(bcm);
+       drain_txstatus_queue(bcm);
+       ieee80211softmac_start(bcm->net_dev);
+
+       /* Let's go! Be careful after enabling the IRQs.
+        * Don't switch cores, for example.
+        */
+       bcm43xx_mac_enable(bcm);
+       bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
+       err = bcm43xx_initialize_irq(bcm);
+       if (err)
+               goto error;
+       bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
+
+       dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
+               active_wlext->phy.type);
+
+       return 0;
+
+error:
        bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
-       bcm43xx_unlock_noirq(bcm);
+       bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
+       return err;
 }
 
 static int bcm43xx_init_board(struct bcm43xx_private *bcm)
 {
-       int i, err;
-       int connect_phy;
-
-       might_sleep();
-
-       bcm43xx_lock_noirq(bcm);
-       bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
-
+       int err;
+
+       mutex_lock(&(bcm)->mutex);
+
+       tasklet_enable(&bcm->isr_tasklet);
        err = bcm43xx_pctl_set_crystal(bcm, 1);
        if (err)
-               goto out;
+               goto err_tasklet;
        err = bcm43xx_pctl_init(bcm);
        if (err)
                goto err_crystal_off;
-       err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
+       err = bcm43xx_select_wireless_core(bcm, -1);
        if (err)
                goto err_crystal_off;
-
-       tasklet_enable(&bcm->isr_tasklet);
-       for (i = 0; i < bcm->nr_80211_available; i++) {
-               err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
-               assert(err != -ENODEV);
-               if (err)
-                       goto err_80211_unwind;
-
-               /* Enable the selected wireless core.
-                * Connect PHY only on the first core.
-                */
-               if (!bcm43xx_core_enabled(bcm)) {
-                       if (bcm->nr_80211_available == 1) {
-                               connect_phy = 
bcm43xx_current_phy(bcm)->connected;
-                       } else {
-                               if (i == 0)
-                                       connect_phy = 1;
-                               else
-                                       connect_phy = 0;
-                       }
-                       bcm43xx_wireless_core_reset(bcm, connect_phy);
-               }
-
-               if (i != 0)
-                       bcm43xx_wireless_core_mark_inactive(bcm, 
&bcm->core_80211[0]);
-
-               err = bcm43xx_wireless_core_init(bcm);
-               if (err)
-                       goto err_80211_unwind;
-
-               if (i != 0) {
-                       bcm43xx_mac_suspend(bcm);
-                       bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
-                       bcm43xx_radio_turn_off(bcm);
-               }
-       }
-       bcm->active_80211_core = &bcm->core_80211[0];
-       if (bcm->nr_80211_available >= 2) {
-               bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
-               bcm43xx_mac_enable(bcm);
-       }
+       err = bcm43xx_sysfs_register(bcm);
+       if (err)
+               goto err_wlshutdown;
        err = bcm43xx_rng_init(bcm);
        if (err)
-               goto err_80211_unwind;
-       bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
-       bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 
*)(bcm->net_dev->dev_addr));
-       dprintk(KERN_INFO PFX "80211 cores initialized\n");
-       bcm43xx_security_init(bcm);
-       bcm43xx_softmac_init(bcm);
-
-       bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
-
-       if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) {
-               bcm43xx_mac_suspend(bcm);
-               bcm43xx_radio_selectchannel(bcm, 
bcm43xx_current_radio(bcm)->initial_channel, 0);
-               bcm43xx_mac_enable(bcm);
-       }
-
-       /* Initialization of the board is done. Flag it as such. */
-       bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
-
+               goto err_sysfs_unreg;
        bcm43xx_periodic_tasks_setup(bcm);
-       bcm43xx_sysfs_register(bcm);
-       //FIXME: check for bcm43xx_sysfs_register failure. This function is a 
bit messy regarding unwinding, though...
 
        /*FIXME: This should be handled by softmac instead. */
        schedule_work(&bcm->softmac->associnfo.work);
 
-       assert(err == 0);
 out:
-       bcm43xx_unlock_noirq(bcm);
+       mutex_unlock(&(bcm)->mutex);
 
        return err;
 
-err_80211_unwind:
-       tasklet_disable(&bcm->isr_tasklet);
-       /* unwind all 80211 initialization */
-       for (i = 0; i < bcm->nr_80211_available; i++) {
-               if (!bcm->core_80211[i].initialized)
-                       continue;
-               bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
-               bcm43xx_wireless_core_cleanup(bcm);
-       }
+err_sysfs_unreg:
+       bcm43xx_sysfs_unregister(bcm);
+err_wlshutdown:
+       bcm43xx_shutdown_all_wireless_cores(bcm);
 err_crystal_off:
        bcm43xx_pctl_set_crystal(bcm, 0);
+err_tasklet:
+       tasklet_disable(&bcm->isr_tasklet);
        goto out;
 }
 
@@ -3647,7 +3839,8 @@ static void bcm43xx_ieee80211_set_chan(s
        struct bcm43xx_radioinfo *radio;
        unsigned long flags;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
                bcm43xx_mac_suspend(bcm);
                bcm43xx_radio_selectchannel(bcm, channel, 0);
@@ -3656,7 +3849,8 @@ static void bcm43xx_ieee80211_set_chan(s
                radio = bcm43xx_current_radio(bcm);
                radio->initial_channel = channel;
        }
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 }
 
 /* set_security() callback in struct ieee80211_device */
@@ -3670,7 +3864,8 @@ static void bcm43xx_ieee80211_set_securi
        
        dprintk(KERN_INFO PFX "set security called");
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
 
        for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
                if (sec->flags & (1<<keyidx)) {
@@ -3739,7 +3934,8 @@ static void bcm43xx_ieee80211_set_securi
                } else
                                bcm43xx_clear_keys(bcm);
        }
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 }
 
 /* hard_start_xmit() callback in struct ieee80211_device */
@@ -3751,12 +3947,14 @@ static int bcm43xx_ieee80211_hard_start_
        int err = -ENODEV;
        unsigned long flags;
 
-       bcm43xx_lock_irqonly(bcm, flags);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
                err = bcm43xx_tx(bcm, txb);
-       bcm43xx_unlock_irqonly(bcm, flags);
-
-       return err;
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+
+       if (unlikely(err))
+               return NETDEV_TX_BUSY;
+       return NETDEV_TX_OK;
 }
 
 static struct net_device_stats * bcm43xx_net_get_stats(struct net_device 
*net_dev)
@@ -3769,9 +3967,9 @@ static void bcm43xx_net_tx_timeout(struc
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
        unsigned long flags;
 
-       bcm43xx_lock_irqonly(bcm, flags);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        bcm43xx_controller_restart(bcm, "TX timeout");
-       bcm43xx_unlock_irqonly(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3781,7 +3979,8 @@ static void bcm43xx_net_poll_controller(
        unsigned long flags;
 
        local_irq_save(flags);
-       bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
+       if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
+               bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
        local_irq_restore(flags);
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -3799,9 +3998,10 @@ static int bcm43xx_net_stop(struct net_d
        int err;
 
        ieee80211softmac_stop(net_dev);
-       err = bcm43xx_disable_interrupts_sync(bcm, NULL);
+       err = bcm43xx_disable_interrupts_sync(bcm);
        assert(!err);
        bcm43xx_free_board(bcm);
+       flush_scheduled_work();
 
        return 0;
 }
@@ -3818,10 +4018,12 @@ static int bcm43xx_init_private(struct b
        bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
 
        bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
+       bcm->mac_suspended = 1;
        bcm->pci_dev = pci_dev;
        bcm->net_dev = net_dev;
        bcm->bad_frames_preempt = modparam_bad_frames_preempt;
        spin_lock_init(&bcm->irq_lock);
+       spin_lock_init(&bcm->leds_lock);
        mutex_init(&bcm->mutex);
        tasklet_init(&bcm->isr_tasklet,
                     (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
@@ -3940,7 +4142,6 @@ static void __devexit bcm43xx_remove_one
        bcm43xx_debugfs_remove_device(bcm);
        unregister_netdev(net_dev);
        bcm43xx_detach_board(bcm);
-       assert(bcm->ucode == NULL);
        free_ieee80211softmac(net_dev);
 }
 
@@ -3950,47 +4151,31 @@ static void bcm43xx_chip_reset(void *_bc
 static void bcm43xx_chip_reset(void *_bcm)
 {
        struct bcm43xx_private *bcm = _bcm;
-       struct net_device *net_dev = bcm->net_dev;
-       struct pci_dev *pci_dev = bcm->pci_dev;
-       int err;
-       int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
-
-       netif_stop_queue(bcm->net_dev);
-       tasklet_disable(&bcm->isr_tasklet);
-
-       bcm->firmware_norelease = 1;
-       if (was_initialized)
-               bcm43xx_free_board(bcm);
-       bcm->firmware_norelease = 0;
-       bcm43xx_detach_board(bcm);
-       err = bcm43xx_init_private(bcm, net_dev, pci_dev);
-       if (err)
-               goto failure;
-       err = bcm43xx_attach_board(bcm);
-       if (err)
-               goto failure;
-       if (was_initialized) {
-               err = bcm43xx_init_board(bcm);
-               if (err)
-                       goto failure;
-       }
-       netif_wake_queue(bcm->net_dev);
-       printk(KERN_INFO PFX "Controller restarted\n");
-
-       return;
-failure:
-       printk(KERN_ERR PFX "Controller restart failed\n");
+       struct bcm43xx_phyinfo *phy;
+       int err = -ENODEV;
+
+       mutex_lock(&(bcm)->mutex);
+       if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
+               bcm43xx_periodic_tasks_delete(bcm);
+               phy = bcm43xx_current_phy(bcm);
+               err = bcm43xx_select_wireless_core(bcm, phy->type);
+               if (!err)
+                       bcm43xx_periodic_tasks_setup(bcm);
+       }
+       mutex_unlock(&(bcm)->mutex);
+
+       printk(KERN_ERR PFX "Controller restart%s\n",
+              (err == 0) ? "ed" : " failed");
 }
 
 /* Hard-reset the chip.
  * This can be called from interrupt or process context.
- * Make sure to _not_ re-enable device interrupts after this has been called.
-*/
+ * bcm->irq_lock must be locked.
+ */
 void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char 
*reason)
 {
-       bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING);
-       bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
-       bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
+       if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
+               return;
        printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
        INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
        schedule_work(&bcm->restart_work);
@@ -4002,21 +4187,16 @@ static int bcm43xx_suspend(struct pci_de
 {
        struct net_device *net_dev = pci_get_drvdata(pdev);
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-       unsigned long flags;
-       int try_to_shutdown = 0, err;
+       int err;
 
        dprintk(KERN_INFO PFX "Suspending...\n");
 
-       bcm43xx_lock_irqsafe(bcm, flags);
-       bcm->was_initialized = (bcm43xx_status(bcm) == 
BCM43xx_STAT_INITIALIZED);
-       if (bcm->was_initialized)
-               try_to_shutdown = 1;
-       bcm43xx_unlock_irqsafe(bcm, flags);
-
        netif_device_detach(net_dev);
-       if (try_to_shutdown) {
+       bcm->was_initialized = 0;
+       if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
+               bcm->was_initialized = 1;
                ieee80211softmac_stop(net_dev);
-               err = bcm43xx_disable_interrupts_sync(bcm, 
&bcm->irq_savedstate);
+               err = bcm43xx_disable_interrupts_sync(bcm);
                if (unlikely(err)) {
                        dprintk(KERN_ERR PFX "Suspend failed.\n");
                        return -EAGAIN;
@@ -4049,17 +4229,14 @@ static int bcm43xx_resume(struct pci_dev
        pci_restore_state(pdev);
 
        bcm43xx_chipset_attach(bcm);
-       if (bcm->was_initialized) {
-               bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
+       if (bcm->was_initialized)
                err = bcm43xx_init_board(bcm);
-       }
        if (err) {
                printk(KERN_ERR PFX "Resume failed!\n");
                return err;
        }
-
        netif_device_attach(net_dev);
-       
+
        dprintk(KERN_INFO PFX "Device resumed.\n");
 
        return 0;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_main.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h       Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h       Wed Oct 03 10:00:44 
2007 +0100
@@ -133,10 +133,16 @@ void bcm43xx_dummy_transmission(struct b
 
 int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo 
*new_core);
 
+int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
+                                int phytype);
+
 void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
 
 void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
 void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
+
+void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm);
+void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm);
 
 void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char 
*reason);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_phy.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c        Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c        Wed Oct 03 10:00:44 
2007 +0100
@@ -81,6 +81,16 @@ static void bcm43xx_phy_initg(struct bcm
 static void bcm43xx_phy_initg(struct bcm43xx_private *bcm);
 
 
+static inline
+void bcm43xx_voluntary_preempt(void)
+{
+       assert(!in_atomic() && !in_irq() &&
+              !in_interrupt() && !irqs_disabled());
+#ifndef CONFIG_PREEMPT
+       cond_resched();
+#endif /* CONFIG_PREEMPT */
+}
+
 void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm)
 {
        struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
@@ -133,22 +143,14 @@ void bcm43xx_phy_calibrate(struct bcm43x
 void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm)
 {
        struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-       unsigned long flags;
 
        bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */
        if (phy->calibrated)
                return;
        if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) {
-               /* We do not want to be preempted while calibrating
-                * the hardware.
-                */
-               local_irq_save(flags);
-
                bcm43xx_wireless_core_reset(bcm, 0);
                bcm43xx_phy_initg(bcm);
                bcm43xx_wireless_core_reset(bcm, 1);
-
-               local_irq_restore(flags);
        }
        phy->calibrated = 1;
 }
@@ -359,7 +361,7 @@ static void bcm43xx_phy_setupg(struct bc
        if (phy->rev <= 2)
                for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
                        bcm43xx_ilt_write(bcm, 0x1400 + i, 
bcm43xx_ilt_noisescaleg1[i]);
-       else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
+       else if ((phy->rev >= 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
                for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
                        bcm43xx_ilt_write(bcm, 0x1400 + i, 
bcm43xx_ilt_noisescaleg3[i]);
        else
@@ -369,7 +371,7 @@ static void bcm43xx_phy_setupg(struct bc
        if (phy->rev == 2)
                for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
                        bcm43xx_ilt_write(bcm, 0x5000 + i, 
bcm43xx_ilt_sigmasqr1[i]);
-       else if ((phy->rev > 2) && (phy->rev <= 7))
+       else if ((phy->rev > 2) && (phy->rev <= 8))
                for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
                        bcm43xx_ilt_write(bcm, 0x5000 + i, 
bcm43xx_ilt_sigmasqr2[i]);
        
@@ -1195,7 +1197,7 @@ static void bcm43xx_phy_initg(struct bcm
 
        if (phy->rev == 1)
                bcm43xx_phy_initb5(bcm);
-       else if (phy->rev >= 2 && phy->rev <= 7)
+       else
                bcm43xx_phy_initb6(bcm);
        if (phy->rev >= 2 || phy->connected)
                bcm43xx_phy_inita(bcm);
@@ -1239,23 +1241,22 @@ static void bcm43xx_phy_initg(struct bcm
                bcm43xx_phy_lo_g_measure(bcm);
        } else {
                if (radio->version == 0x2050 && radio->revision == 8) {
-                       //FIXME
+                       bcm43xx_radio_write16(bcm, 0x0052,
+                                             (radio->txctl1 << 4) | 
radio->txctl2);
                } else {
                        bcm43xx_radio_write16(bcm, 0x0052,
                                              (bcm43xx_radio_read16(bcm, 0x0052)
                                               & 0xFFF0) | radio->txctl1);
                }
                if (phy->rev >= 6) {
-                       /*
                        bcm43xx_phy_write(bcm, 0x0036,
                                          (bcm43xx_phy_read(bcm, 0x0036)
-                                          & 0xF000) | (FIXME << 12));
-                       */
+                                          & 0xF000) | (radio->txctl2 << 12));
                }
                if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
                        bcm43xx_phy_write(bcm, 0x002E, 0x8075);
                else
-                       bcm43xx_phy_write(bcm, 0x003E, 0x807F);
+                       bcm43xx_phy_write(bcm, 0x002E, 0x807F);
                if (phy->rev < 2)
                        bcm43xx_phy_write(bcm, 0x002F, 0x0101);
                else
@@ -1299,7 +1300,9 @@ static u16 bcm43xx_phy_lo_b_r15_loop(str
 {
        int i;
        u16 ret = 0;
-
+       unsigned long flags;
+
+       local_irq_save(flags);
        for (i = 0; i < 10; i++){
                bcm43xx_phy_write(bcm, 0x0015, 0xAFA0);
                udelay(1);
@@ -1309,6 +1312,8 @@ static u16 bcm43xx_phy_lo_b_r15_loop(str
                udelay(40);
                ret += bcm43xx_phy_read(bcm, 0x002C);
        }
+       local_irq_restore(flags);
+       bcm43xx_voluntary_preempt();
 
        return ret;
 }
@@ -1435,6 +1440,7 @@ u16 bcm43xx_phy_lo_g_deviation_subval(st
        }
        ret = bcm43xx_phy_read(bcm, 0x002D);
        local_irq_restore(flags);
+       bcm43xx_voluntary_preempt();
 
        return ret;
 }
@@ -1760,6 +1766,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
                        bcm43xx_radio_write16(bcm, 0x43, i);
                        bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
                        udelay(10);
+                       bcm43xx_voluntary_preempt();
 
                        bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
 
@@ -1803,6 +1810,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
                                              radio->txctl2
                                              | (3/*txctl1*/ << 4));//FIXME: 
shouldn't txctl1 be zero here and 3 in the loop above?
                        udelay(10);
+                       bcm43xx_voluntary_preempt();
 
                        bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
 
@@ -1824,6 +1832,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
                bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2);
                udelay(2);
                bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3);
+               bcm43xx_voluntary_preempt();
        } else
                bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0);
        bcm43xx_phy_lo_adjust(bcm, is_initializing);
@@ -2188,12 +2197,6 @@ int bcm43xx_phy_init(struct bcm43xx_priv
 {
        struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
        int err = -ENODEV;
-       unsigned long flags;
-
-       /* We do not want to be preempted while calibrating
-        * the hardware.
-        */
-       local_irq_save(flags);
 
        switch (phy->type) {
        case BCM43xx_PHYTYPE_A:
@@ -2227,7 +2230,6 @@ int bcm43xx_phy_init(struct bcm43xx_priv
                err = 0;
                break;
        }
-       local_irq_restore(flags);
        if (err)
                printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_pio.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c        Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c        Wed Oct 03 10:00:44 
2007 +0100
@@ -262,7 +262,7 @@ static void tx_tasklet(unsigned long d)
        int err;
        u16 txctl;
 
-       bcm43xx_lock_irqonly(bcm, flags);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
 
        if (queue->tx_frozen)
                goto out_unlock;
@@ -300,7 +300,7 @@ static void tx_tasklet(unsigned long d)
                continue;
        }
 out_unlock:
-       bcm43xx_unlock_irqonly(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
 }
 
 static void setup_txqueues(struct bcm43xx_pioqueue *queue)
diff -r aafef975e518 -r 3e8752eb6d9c 
drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c      Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c      Wed Oct 03 10:00:44 
2007 +0100
@@ -120,12 +120,14 @@ static ssize_t bcm43xx_attr_sprom_show(s
                        GFP_KERNEL);
        if (!sprom)
                return -ENOMEM;
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        err = bcm43xx_sprom_read(bcm, sprom);
        if (!err)
                err = sprom2hex(sprom, buf, PAGE_SIZE);
        mmiowb();
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
        kfree(sprom);
 
        return err;
@@ -150,10 +152,14 @@ static ssize_t bcm43xx_attr_sprom_store(
        err = hex2sprom(sprom, buf, count);
        if (err)
                goto out_kfree;
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
+       spin_lock(&bcm->leds_lock);
        err = bcm43xx_sprom_write(bcm, sprom);
        mmiowb();
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock(&bcm->leds_lock);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 out_kfree:
        kfree(sprom);
 
@@ -170,13 +176,12 @@ static ssize_t bcm43xx_attr_interfmode_s
                                            char *buf)
 {
        struct bcm43xx_private *bcm = dev_to_bcm(dev);
-       int err;
        ssize_t count = 0;
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
 
-       bcm43xx_lock_noirq(bcm);
+       mutex_lock(&bcm->mutex);
 
        switch (bcm43xx_current_radio(bcm)->interfmode) {
        case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -191,11 +196,10 @@ static ssize_t bcm43xx_attr_interfmode_s
        default:
                assert(0);
        }
-       err = 0;
-
-       bcm43xx_unlock_noirq(bcm);
-
-       return err ? err : count;
+
+       mutex_unlock(&bcm->mutex);
+
+       return count;
 
 }
 
@@ -229,7 +233,8 @@ static ssize_t bcm43xx_attr_interfmode_s
                return -EINVAL;
        }
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
 
        err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
        if (err) {
@@ -237,7 +242,8 @@ static ssize_t bcm43xx_attr_interfmode_s
                                    "supported by device\n");
        }
        mmiowb();
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return err ? err : count;
 }
@@ -251,23 +257,21 @@ static ssize_t bcm43xx_attr_preamble_sho
                                          char *buf)
 {
        struct bcm43xx_private *bcm = dev_to_bcm(dev);
-       int err;
        ssize_t count;
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
 
-       bcm43xx_lock_noirq(bcm);
+       mutex_lock(&bcm->mutex);
 
        if (bcm->short_preamble)
                count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble 
enabled)\n");
        else
                count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble 
disabled)\n");
 
-       err = 0;
-       bcm43xx_unlock_noirq(bcm);
-
-       return err ? err : count;
+       mutex_unlock(&bcm->mutex);
+
+       return count;
 }
 
 static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
@@ -276,7 +280,6 @@ static ssize_t bcm43xx_attr_preamble_sto
 {
        struct bcm43xx_private *bcm = dev_to_bcm(dev);
        unsigned long flags;
-       int err;
        int value;
 
        if (!capable(CAP_NET_ADMIN))
@@ -285,14 +288,15 @@ static ssize_t bcm43xx_attr_preamble_sto
        value = get_boolean(buf, count);
        if (value < 0)
                return value;
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
 
        bcm->short_preamble = !!value;
 
-       err = 0;
-       bcm43xx_unlock_irqsafe(bcm, flags);
-
-       return err ? err : count;
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
+
+       return count;
 }
 
 static DEVICE_ATTR(shortpreamble, 0644,
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_wx.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c Wed Oct 03 10:00:44 2007 +0100
@@ -56,12 +56,11 @@ static int bcm43xx_wx_get_name(struct ne
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
        int i;
-       unsigned long flags;
        struct bcm43xx_phyinfo *phy;
        char suffix[7] = { 0 };
        int have_a = 0, have_b = 0, have_g = 0;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
        for (i = 0; i < bcm->nr_80211_available; i++) {
                phy = &(bcm->core_80211_ext[i].phy);
                switch (phy->type) {
@@ -77,7 +76,7 @@ static int bcm43xx_wx_get_name(struct ne
                        assert(0);
                }
        }
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        i = 0;
        if (have_a) {
@@ -111,7 +110,9 @@ static int bcm43xx_wx_set_channelfreq(st
        int freq;
        int err = -EINVAL;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
+
        if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
                channel = data->freq.m;
                freq = bcm43xx_channel_to_freq(bcm, channel);
@@ -131,7 +132,8 @@ static int bcm43xx_wx_set_channelfreq(st
                err = 0;
        }
 out_unlock:
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return err;
 }
@@ -143,11 +145,10 @@ static int bcm43xx_wx_get_channelfreq(st
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
        struct bcm43xx_radioinfo *radio;
-       unsigned long flags;
        int err = -ENODEV;
        u16 channel;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
        radio = bcm43xx_current_radio(bcm);
        channel = radio->channel;
        if (channel == 0xFF) {
@@ -162,7 +163,7 @@ static int bcm43xx_wx_get_channelfreq(st
 
        err = 0;
 out_unlock:
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        return err;
 }
@@ -180,13 +181,15 @@ static int bcm43xx_wx_set_mode(struct ne
        if (mode == IW_MODE_AUTO)
                mode = BCM43xx_INITIAL_IWMODE;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
                if (bcm->ieee->iw_mode != mode)
                        bcm43xx_set_iwmode(bcm, mode);
        } else
                bcm->ieee->iw_mode = mode;
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -197,11 +200,10 @@ static int bcm43xx_wx_get_mode(struct ne
                               char *extra)
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-       unsigned long flags;
-
-       bcm43xx_lock_irqsafe(bcm, flags);
+
+       mutex_lock(&bcm->mutex);
        data->mode = bcm->ieee->iw_mode;
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -214,7 +216,6 @@ static int bcm43xx_wx_get_rangeparams(st
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
        struct iw_range *range = (struct iw_range *)extra;
        const struct ieee80211_geo *geo;
-       unsigned long flags;
        int i, j;
        struct bcm43xx_phyinfo *phy;
 
@@ -254,7 +255,7 @@ static int bcm43xx_wx_get_rangeparams(st
                          IW_ENC_CAPA_CIPHER_TKIP |
                          IW_ENC_CAPA_CIPHER_CCMP;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
        phy = bcm43xx_current_phy(bcm);
 
        range->num_bitrates = 0;
@@ -301,7 +302,7 @@ static int bcm43xx_wx_get_rangeparams(st
        }
        range->num_frequency = j;
 
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -314,11 +315,11 @@ static int bcm43xx_wx_set_nick(struct ne
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
        size_t len;
 
-       bcm43xx_lock_noirq(bcm);
+       mutex_lock(&bcm->mutex);
        len =  min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
        memcpy(bcm->nick, extra, len);
        bcm->nick[len] = '\0';
-       bcm43xx_unlock_noirq(bcm);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -331,12 +332,12 @@ static int bcm43xx_wx_get_nick(struct ne
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
        size_t len;
 
-       bcm43xx_lock_noirq(bcm);
+       mutex_lock(&bcm->mutex);
        len = strlen(bcm->nick) + 1;
        memcpy(extra, bcm->nick, len);
        data->data.length = (__u16)len;
        data->data.flags = 1;
-       bcm43xx_unlock_noirq(bcm);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -350,7 +351,8 @@ static int bcm43xx_wx_set_rts(struct net
        unsigned long flags;
        int err = -EINVAL;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (data->rts.disabled) {
                bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
                err = 0;
@@ -361,7 +363,8 @@ static int bcm43xx_wx_set_rts(struct net
                        err = 0;
                }
        }
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return err;
 }
@@ -372,13 +375,12 @@ static int bcm43xx_wx_get_rts(struct net
                              char *extra)
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-       unsigned long flags;
-
-       bcm43xx_lock_irqsafe(bcm, flags);
+
+       mutex_lock(&bcm->mutex);
        data->rts.value = bcm->rts_threshold;
        data->rts.fixed = 0;
        data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -392,7 +394,8 @@ static int bcm43xx_wx_set_frag(struct ne
        unsigned long flags;
        int err = -EINVAL;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (data->frag.disabled) {
                bcm->ieee->fts = MAX_FRAG_THRESHOLD;
                err = 0;
@@ -403,7 +406,8 @@ static int bcm43xx_wx_set_frag(struct ne
                        err = 0;
                }
        }
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return err;
 }
@@ -414,13 +418,12 @@ static int bcm43xx_wx_get_frag(struct ne
                               char *extra)
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-       unsigned long flags;
-
-       bcm43xx_lock_irqsafe(bcm, flags);
+
+       mutex_lock(&bcm->mutex);
        data->frag.value = bcm->ieee->fts;
        data->frag.fixed = 0;
        data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -442,7 +445,8 @@ static int bcm43xx_wx_set_xmitpower(stru
                return -EOPNOTSUPP;
        }
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
                goto out_unlock;
        radio = bcm43xx_current_radio(bcm);
@@ -466,7 +470,8 @@ static int bcm43xx_wx_set_xmitpower(stru
        err = 0;
 
 out_unlock:
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return err;
 }
@@ -478,10 +483,9 @@ static int bcm43xx_wx_get_xmitpower(stru
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
        struct bcm43xx_radioinfo *radio;
-       unsigned long flags;
        int err = -ENODEV;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
        if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
                goto out_unlock;
        radio = bcm43xx_current_radio(bcm);
@@ -493,7 +497,7 @@ static int bcm43xx_wx_get_xmitpower(stru
 
        err = 0;
 out_unlock:
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        return err;
 }
@@ -580,7 +584,8 @@ static int bcm43xx_wx_set_interfmode(str
                return -EINVAL;
        }
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
                err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
                if (err) {
@@ -595,7 +600,8 @@ static int bcm43xx_wx_set_interfmode(str
                } else
                        bcm43xx_current_radio(bcm)->interfmode = mode;
        }
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return err;
 }
@@ -606,12 +612,11 @@ static int bcm43xx_wx_get_interfmode(str
                                     char *extra)
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-       unsigned long flags;
        int mode;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
        mode = bcm43xx_current_radio(bcm)->interfmode;
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        switch (mode) {
        case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -641,9 +646,11 @@ static int bcm43xx_wx_set_shortpreamble(
        int on;
 
        on = *((int *)extra);
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        bcm->short_preamble = !!on;
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -654,12 +661,11 @@ static int bcm43xx_wx_get_shortpreamble(
                                        char *extra)
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-       unsigned long flags;
        int on;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
        on = bcm->short_preamble;
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        if (on)
                strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
@@ -681,11 +687,13 @@ static int bcm43xx_wx_set_swencryption(s
        
        on = *((int *)extra);
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        bcm->ieee->host_encrypt = !!on;
        bcm->ieee->host_decrypt = !!on;
        bcm->ieee->host_build_iv = !on;
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 
        return 0;
 }
@@ -696,12 +704,11 @@ static int bcm43xx_wx_get_swencryption(s
                                       char *extra)
 {
        struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-       unsigned long flags;
        int on;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
        on = bcm->ieee->host_encrypt;
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       mutex_unlock(&bcm->mutex);
 
        if (on)
                strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
@@ -764,11 +771,13 @@ static int bcm43xx_wx_sprom_read(struct 
        if (!sprom)
                goto out;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
        err = -ENODEV;
        if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
                err = bcm43xx_sprom_read(bcm, sprom);
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
        if (!err)
                data->data.length = sprom2hex(sprom, extra);
        kfree(sprom);
@@ -809,11 +818,15 @@ static int bcm43xx_wx_sprom_write(struct
        if (err)
                goto out_kfree;
 
-       bcm43xx_lock_irqsafe(bcm, flags);
+       mutex_lock(&bcm->mutex);
+       spin_lock_irqsave(&bcm->irq_lock, flags);
+       spin_lock(&bcm->leds_lock);
        err = -ENODEV;
        if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
                err = bcm43xx_sprom_write(bcm, sprom);
-       bcm43xx_unlock_irqsafe(bcm, flags);
+       spin_unlock(&bcm->leds_lock);
+       spin_unlock_irqrestore(&bcm->irq_lock, flags);
+       mutex_unlock(&bcm->mutex);
 out_kfree:
        kfree(sprom);
 out:
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h       Tue Oct 02 09:52:15 
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h       Wed Oct 03 10:00:44 
2007 +0100
@@ -137,14 +137,8 @@ struct bcm43xx_xmitstatus {
        u16 unknown; //FIXME
 };
 
-#define BCM43xx_TXSTAT_FLAG_ACK                0x01
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x02
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x04
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x08
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x10
-#define BCM43xx_TXSTAT_FLAG_IGNORE     0x20
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x40
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x80
+#define BCM43xx_TXSTAT_FLAG_AMPDU      0x10
+#define BCM43xx_TXSTAT_FLAG_INTER      0x20
 
 u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate);
 u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/zd1211rw/zd_chip.c
--- a/drivers/net/wireless/zd1211rw/zd_chip.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c   Wed Oct 03 10:00:44 2007 +0100
@@ -717,7 +717,7 @@ static int zd1211b_hw_reset_phy(struct z
                { CR21,  0x0e }, { CR22,  0x23 }, { CR23,  0x90 },
                { CR24,  0x14 }, { CR25,  0x40 }, { CR26,  0x10 },
                { CR27,  0x10 }, { CR28,  0x7f }, { CR29,  0x80 },
-               { CR30,  0x49 }, /* jointly decoder, no ASIC */
+               { CR30,  0x4b }, /* ASIC/FWT, no jointly decoder */
                { CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
                { CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
                { CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
diff -r aafef975e518 -r 3e8752eb6d9c drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/pci/pci-sysfs.c   Wed Oct 03 10:00:44 2007 +0100
@@ -571,6 +571,9 @@ int pci_create_sysfs_dev_files (struct p
  */
 void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
 {
+       if (!sysfs_initialized)
+               return;
+
        if (pdev->cfg_size < 4096)
                sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
        else
diff -r aafef975e518 -r 3e8752eb6d9c drivers/pci/quirks.c
--- a/drivers/pci/quirks.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/pci/quirks.c      Wed Oct 03 10:00:44 2007 +0100
@@ -684,33 +684,6 @@ static void __devinit quirk_vt82c598_id(
        pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C597_0,     
quirk_vt82c598_id );
-
-#ifdef CONFIG_ACPI_SLEEP
-
-/*
- * Some VIA systems boot with the abnormal status flag set. This can cause
- * the BIOS to re-POST the system on resume rather than passing control
- * back to the OS.  Clear the flag on boot
- */
-static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev)
-{
-       u32 reg;
-
-       acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
-                               &reg);
-
-       if (reg & 0x800) {
-               printk("Clearing abnormal poweroff flag\n");
-               acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
-                                       ACPI_REGISTER_PM1_STATUS,
-                                       (u16)0x800);
-       }
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 
quirk_via_abnormal_poweroff);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, 
quirk_via_abnormal_poweroff);
-
-#endif
 
 /*
  * CardBus controllers have a legacy base address that enables them
diff -r aafef975e518 -r 3e8752eb6d9c drivers/pcmcia/ds.c
--- a/drivers/pcmcia/ds.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/pcmcia/ds.c       Wed Oct 03 10:00:44 2007 +0100
@@ -1264,6 +1264,11 @@ static void pcmcia_bus_remove_socket(str
        socket->pcmcia_state.dead = 1;
        pccard_register_pcmcia(socket, NULL);
 
+       /* unregister any unbound devices */
+       mutex_lock(&socket->skt_mutex);
+       pcmcia_card_remove(socket, NULL);
+       mutex_unlock(&socket->skt_mutex);
+
        pcmcia_put_socket(socket);
 
        return;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/rtc/rtc-max6902.c
--- a/drivers/rtc/rtc-max6902.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/rtc/rtc-max6902.c Wed Oct 03 10:00:44 2007 +0100
@@ -137,7 +137,7 @@ static int max6902_get_datetime(struct d
        dt->tm_min      = BCD2BIN(chip->buf[2]);
        dt->tm_hour     = BCD2BIN(chip->buf[3]);
        dt->tm_mday     = BCD2BIN(chip->buf[4]);
-       dt->tm_mon      = BCD2BIN(chip->buf[5] - 1);
+       dt->tm_mon      = BCD2BIN(chip->buf[5]) - 1;
        dt->tm_wday     = BCD2BIN(chip->buf[6]);
        dt->tm_year = BCD2BIN(chip->buf[7]);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/rtc/rtc-pcf8563.c
--- a/drivers/rtc/rtc-pcf8563.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/rtc/rtc-pcf8563.c Wed Oct 03 10:00:44 2007 +0100
@@ -95,7 +95,7 @@ static int pcf8563_get_datetime(struct i
        tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
        tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
        tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR])
-               + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 100 : 0);
+               + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 0 : 100);
 
        dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
                "mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -135,7 +135,7 @@ static int pcf8563_set_datetime(struct i
 
        /* year and century */
        buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
-       if (tm->tm_year / 100)
+       if (tm->tm_year < 100)
                buf[PCF8563_REG_MO] |= PCF8563_MO_C;
 
        buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c        Wed Oct 03 10:00:44 2007 +0100
@@ -2539,15 +2539,28 @@ static void ahc_linux_get_signalling(str
 static void ahc_linux_get_signalling(struct Scsi_Host *shost)
 {
        struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
-       u8 mode = ahc_inb(ahc, SBLKCTL);
-
-       if (mode & ENAB40)
-               spi_signalling(shost) = SPI_SIGNAL_LVD;
-       else if (mode & ENAB20)
+       unsigned long flags;
+       u8 mode;
+
+       if (!(ahc->features & AHC_ULTRA2)) {
+               /* non-LVD chipset, may not have SBLKCTL reg */
                spi_signalling(shost) = 
                        ahc->features & AHC_HVD ?
                        SPI_SIGNAL_HVD :
                        SPI_SIGNAL_SE;
+               return;
+       }
+
+       ahc_lock(ahc, &flags);
+       ahc_pause(ahc);
+       mode = ahc_inb(ahc, SBLKCTL);
+       ahc_unpause(ahc);
+       ahc_unlock(ahc, &flags);
+
+       if (mode & ENAB40)
+               spi_signalling(shost) = SPI_SIGNAL_LVD;
+       else if (mode & ENAB20)
+               spi_signalling(shost) = SPI_SIGNAL_SE;
        else
                spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
 }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/scsi/sata_mv.c
--- a/drivers/scsi/sata_mv.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/scsi/sata_mv.c    Wed Oct 03 10:00:44 2007 +0100
@@ -463,6 +463,7 @@ static const struct ata_port_operations 
 
        .qc_prep                = mv_qc_prep_iie,
        .qc_issue               = mv_qc_issue,
+       .data_xfer              = ata_mmio_data_xfer,
 
        .eng_timeout            = mv_eng_timeout,
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/scsi/scsi_lib.c   Wed Oct 03 10:00:44 2007 +0100
@@ -191,6 +191,7 @@ int scsi_execute(struct scsi_device *sde
                goto out;
 
        req->cmd_len = COMMAND_SIZE(cmd[0]);
+       memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
        memcpy(req->cmd, cmd, req->cmd_len);
        req->sense = sense;
        req->sense_len = 0;
@@ -408,6 +409,7 @@ int scsi_execute_async(struct scsi_devic
                goto free_req;
 
        req->cmd_len = cmd_len;
+       memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
        memcpy(req->cmd, cmd, req->cmd_len);
        req->sense = sioc->sense;
        req->sense_len = 0;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/serial/serial_core.c
--- a/drivers/serial/serial_core.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/serial/serial_core.c      Wed Oct 03 10:00:44 2007 +0100
@@ -1932,6 +1932,9 @@ int uart_suspend_port(struct uart_driver
        if (state->info && state->info->flags & UIF_INITIALIZED) {
                const struct uart_ops *ops = port->ops;
 
+               state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
+                                    | UIF_SUSPENDED;
+
                spin_lock_irq(&port->lock);
                ops->stop_tx(port);
                ops->set_mctrl(port, 0);
@@ -1991,7 +1994,7 @@ int uart_resume_port(struct uart_driver 
                console_start(port->cons);
        }
 
-       if (state->info && state->info->flags & UIF_INITIALIZED) {
+       if (state->info && state->info->flags & UIF_SUSPENDED) {
                const struct uart_ops *ops = port->ops;
                int ret;
 
@@ -2003,15 +2006,17 @@ int uart_resume_port(struct uart_driver 
                        ops->set_mctrl(port, port->mctrl);
                        ops->start_tx(port);
                        spin_unlock_irq(&port->lock);
+                       state->info->flags |= UIF_INITIALIZED;
                } else {
                        /*
                         * Failed to resume - maybe hardware went away?
                         * Clear the "initialized" flag so we won't try
                         * to call the low level drivers shutdown method.
                         */
-                       state->info->flags &= ~UIF_INITIALIZED;
                        uart_shutdown(state);
                }
+
+               state->info->flags &= ~UIF_SUSPENDED;
        }
 
        mutex_unlock(&state->mutex);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/serial/serial_cs.c
--- a/drivers/serial/serial_cs.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/serial/serial_cs.c        Wed Oct 03 10:00:44 2007 +0100
@@ -185,14 +185,12 @@ static int serial_suspend(struct pcmcia_
 
 static int serial_resume(struct pcmcia_device *link)
 {
-       if (pcmcia_dev_present(link)) {
-               struct serial_info *info = link->priv;
-               int i;
-
-               for (i = 0; i < info->ndev; i++)
-                       serial8250_resume_port(info->line[i]);
-               wakeup_card(info);
-       }
+       struct serial_info *info = link->priv;
+       int i;
+
+       for (i = 0; i < info->ndev; i++)
+               serial8250_resume_port(info->line[i]);
+       wakeup_card(info);
 
        return 0;
 }
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/class/usblp.c Wed Oct 03 10:00:44 2007 +0100
@@ -701,6 +701,7 @@ static ssize_t usblp_write(struct file *
                usblp->wcomplete = 0;
                err = usb_submit_urb(usblp->writeurb, GFP_KERNEL);
                if (err) {
+                       usblp->wcomplete = 1;
                        if (err != -ENOMEM)
                                count = -EIO;
                        else
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c  Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/core/devio.c  Wed Oct 03 10:00:44 2007 +0100
@@ -59,6 +59,9 @@
 #define USB_DEVICE_MAX                 USB_MAXBUS * 128
 static struct class *usb_device_class;
 
+/* Mutual exclusion for removal, open, and release */
+DEFINE_MUTEX(usbfs_mutex);
+
 struct async {
        struct list_head asynclist;
        struct dev_state *ps;
@@ -541,15 +544,13 @@ static int usbdev_open(struct inode *ino
        struct dev_state *ps;
        int ret;
 
-       /* 
-        * no locking necessary here, as chrdev_open has the kernel lock
-        * (still acquire the kernel lock for safety)
-        */
+       /* Protect against simultaneous removal or release */
+       mutex_lock(&usbfs_mutex);
+
        ret = -ENOMEM;
        if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
-               goto out_nolock;
-
-       lock_kernel();
+               goto out;
+
        ret = -ENOENT;
        /* check if we are called from a real node or usbfs */
        if (imajor(inode) == USB_DEVICE_MAJOR)
@@ -579,9 +580,8 @@ static int usbdev_open(struct inode *ino
        list_add_tail(&ps->list, &dev->filelist);
        file->private_data = ps;
  out:
-       unlock_kernel();
- out_nolock:
-        return ret;
+       mutex_unlock(&usbfs_mutex);
+       return ret;
 }
 
 static int usbdev_release(struct inode *inode, struct file *file)
@@ -591,7 +591,12 @@ static int usbdev_release(struct inode *
        unsigned int ifnum;
 
        usb_lock_device(dev);
+
+       /* Protect against simultaneous open */
+       mutex_lock(&usbfs_mutex);
        list_del_init(&ps->list);
+       mutex_unlock(&usbfs_mutex);
+
        for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
                        ifnum++) {
                if (test_bit(ifnum, &ps->ifclaimed))
@@ -600,9 +605,8 @@ static int usbdev_release(struct inode *
        destroy_all_async(ps);
        usb_unlock_device(dev);
        usb_put_dev(dev);
-       ps->dev = NULL;
        kfree(ps);
-        return 0;
+       return 0;
 }
 
 static int proc_control(struct dev_state *ps, void __user *arg)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/core/notify.c
--- a/drivers/usb/core/notify.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/core/notify.c Wed Oct 03 10:00:44 2007 +0100
@@ -50,8 +50,11 @@ void usb_notify_add_device(struct usb_de
 
 void usb_notify_remove_device(struct usb_device *udev)
 {
+       /* Protect against simultaneous usbfs open */
+       mutex_lock(&usbfs_mutex);
        blocking_notifier_call_chain(&usb_notifier_list,
                        USB_DEVICE_REMOVE, udev);
+       mutex_unlock(&usbfs_mutex);
 }
 
 void usb_notify_add_bus(struct usb_bus *ubus)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/core/usb.h
--- a/drivers/usb/core/usb.h    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/core/usb.h    Wed Oct 03 10:00:44 2007 +0100
@@ -59,6 +59,7 @@ extern const char *usbcore_name;
 extern const char *usbcore_name;
 
 /* usbfs stuff */
+extern struct mutex usbfs_mutex;
 extern struct usb_driver usbfs_driver;
 extern struct file_operations usbfs_devices_fops;
 extern struct file_operations usbfs_device_file_operations;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/gadget/ether.c
--- a/drivers/usb/gadget/ether.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/gadget/ether.c        Wed Oct 03 10:00:44 2007 +0100
@@ -262,7 +262,7 @@ MODULE_PARM_DESC(host_addr, "Host Ethern
 #define DEV_CONFIG_CDC
 #endif
 
-#ifdef CONFIG_USB_GADGET_MUSBHDRC
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
 #define DEV_CONFIG_CDC
 #endif
 
@@ -2564,7 +2564,7 @@ static struct usb_gadget_driver eth_driv
 
        .function       = (char *) driver_desc,
        .bind           = eth_bind,
-       .unbind         = __exit_p(eth_unbind),
+       .unbind         = eth_unbind,
 
        .setup          = eth_setup,
        .disconnect     = eth_disconnect,
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/input/hid-core.c      Wed Oct 03 10:00:44 2007 +0100
@@ -1734,10 +1734,10 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
        { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
        { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN | 
HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
        { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
        { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN | 
HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
        { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN },
        { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
        { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/input/hid-input.c
--- a/drivers/usb/input/hid-input.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/input/hid-input.c     Wed Oct 03 10:00:44 2007 +0100
@@ -123,6 +123,12 @@ static struct hidinput_key_translation p
        { }
 };
 
+static struct hidinput_key_translation powerbook_iso_keyboard[] = {
+       { KEY_GRAVE,    KEY_102ND },
+       { KEY_102ND,    KEY_GRAVE },
+       { }
+};
+
 static int usbhid_pb_fnmode = 1;
 module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
 MODULE_PARM_DESC(pb_fnmode,
@@ -197,6 +203,14 @@ static int hidinput_pb_event(struct hid_
                }
        }
 
+       if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
+               trans = find_translation(powerbook_iso_keyboard, usage->code);
+               if (trans) {
+                       input_event(input, usage->type, trans->to, value);
+                       return 1;
+               }
+       }
+
        return 0;
 }
 
@@ -211,6 +225,9 @@ static void hidinput_pb_setup(struct inp
                set_bit(trans->to, input->keybit);
 
        for (trans = powerbook_numlock_keys; trans->from; trans++)
+               set_bit(trans->to, input->keybit);
+
+       for (trans = powerbook_iso_keyboard; trans->from; trans++)
                set_bit(trans->to, input->keybit);
 }
 #else
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/input/hid.h
--- a/drivers/usb/input/hid.h   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/input/hid.h   Wed Oct 03 10:00:44 2007 +0100
@@ -260,6 +260,7 @@ struct hid_item {
 #define HID_QUIRK_POWERBOOK_HAS_FN             0x00001000
 #define HID_QUIRK_POWERBOOK_FN_ON              0x00002000
 #define HID_QUIRK_INVERT_HWHEEL                        0x00004000
+#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD       0x00010000
 
 /*
  * This is the global environment of the parser. This information is
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/input/usbtouchscreen.c
--- a/drivers/usb/input/usbtouchscreen.c        Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/input/usbtouchscreen.c        Wed Oct 03 10:00:44 2007 +0100
@@ -522,7 +522,7 @@ static int usbtouch_probe(struct usb_int
                                     type->max_press, 0, 0);
 
        usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
-                        usb_rcvintpipe(usbtouch->udev, 0x81),
+                        usb_rcvintpipe(usbtouch->udev, 
endpoint->bEndpointAddress),
                         usbtouch->data, type->rept_size,
                         usbtouch_irq, usbtouch, endpoint->bInterval);
 
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/fbmem.c
--- a/drivers/video/fbmem.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/fbmem.c     Wed Oct 03 10:00:44 2007 +0100
@@ -554,7 +554,8 @@ static int fbmem_read_proc(char *buf, ch
        int clen;
 
        clen = 0;
-       for (fi = registered_fb; fi < &registered_fb[FB_MAX] && len < 4000; 
fi++)
+       for (fi = registered_fb; fi < &registered_fb[FB_MAX] && clen < 4000;
+            fi++)
                if (*fi)
                        clen += sprintf(buf + clen, "%d %s\n",
                                        (*fi)->node,
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/fbsysfs.c
--- a/drivers/video/fbsysfs.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/fbsysfs.c   Wed Oct 03 10:00:44 2007 +0100
@@ -396,6 +396,12 @@ static ssize_t store_bl_curve(struct cla
        struct fb_info *fb_info = class_get_devdata(class_device);
        u8 tmp_curve[FB_BACKLIGHT_LEVELS];
        unsigned int i;
+
+       /* Some drivers don't use framebuffer_alloc(), but those also
+        * don't have backlights.
+        */
+       if (!fb_info || !fb_info->bl_dev)
+               return -ENODEV;
 
        if (count != (FB_BACKLIGHT_LEVELS / 8 * 24))
                return -EINVAL;
@@ -429,6 +435,12 @@ static ssize_t show_bl_curve(struct clas
        struct fb_info *fb_info = class_get_devdata(class_device);
        ssize_t len = 0;
        unsigned int i;
+
+       /* Some drivers don't use framebuffer_alloc(), but those also
+        * don't have backlights.
+        */
+       if (!fb_info || !fb_info->bl_dev)
+               return -ENODEV;
 
        mutex_lock(&fb_info->bl_mutex);
        for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/nvidia/nv_hw.c
--- a/drivers/video/nvidia/nv_hw.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/nvidia/nv_hw.c      Wed Oct 03 10:00:44 2007 +0100
@@ -145,12 +145,18 @@ static void nvGetClocks(struct nvidia_pa
 
        if (par->Architecture >= NV_ARCH_40) {
                pll = NV_RD32(par->PMC, 0x4020);
-               P = (pll >> 16) & 0x03;
+               P = (pll >> 16) & 0x07;
                pll = NV_RD32(par->PMC, 0x4024);
                M = pll & 0xFF;
                N = (pll >> 8) & 0xFF;
-               MB = (pll >> 16) & 0xFF;
-               NB = (pll >> 24) & 0xFF;
+               if (((par->Chipset & 0xfff0) == 0x0290) ||
+                               ((par->Chipset & 0xfff0) == 0x0390)) {
+                       MB = 1;
+                       NB = 1;
+               } else {
+                       MB = (pll >> 16) & 0xFF;
+                       NB = (pll >> 24) & 0xFF;
+               }
                *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
 
                pll = NV_RD32(par->PMC, 0x4000);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/nvidia/nv_setup.c
--- a/drivers/video/nvidia/nv_setup.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/nvidia/nv_setup.c   Wed Oct 03 10:00:44 2007 +0100
@@ -359,6 +359,7 @@ int NVCommonSetup(struct fb_info *info)
        case 0x0186:
        case 0x0187:
        case 0x018D:
+       case 0x0228:
        case 0x0286:
        case 0x028C:
        case 0x0316:
@@ -382,6 +383,10 @@ int NVCommonSetup(struct fb_info *info)
        case 0x034C:
        case 0x0160:
        case 0x0166:
+       case 0x0169:
+       case 0x016B:
+       case 0x016C:
+       case 0x016D:
        case 0x00C8:
        case 0x00CC:
        case 0x0144:
@@ -639,11 +644,22 @@ int NVCommonSetup(struct fb_info *info)
                par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1;
                par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033;
 
-               printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight);
+               printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, 
par->fpHeight);
        }
 
        if (monA)
                info->monspecs = *monA;
+
+       if (!par->FlatPanel || !par->twoHeads)
+               par->FPDither = 0;
+
+       par->LVDS = 0;
+       if (par->FlatPanel && par->twoHeads) {
+               NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004);
+               if (par->PRAMDAC0[0x08b4] & 1)
+                       par->LVDS = 1;
+               printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS");
+       }
 
        kfree(edidA);
        kfree(edidB);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/nvidia/nv_type.h
--- a/drivers/video/nvidia/nv_type.h    Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/nvidia/nv_type.h    Wed Oct 03 10:00:44 2007 +0100
@@ -129,6 +129,7 @@ struct nvidia_par {
        int fpHeight;
        int PanelTweak;
        int paneltweak;
+       int LVDS;
        int pm_state;
        u32 crtcSync_read;
        u32 fpSyncs;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/nvidia/nvidia.c
--- a/drivers/video/nvidia/nvidia.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/nvidia/nvidia.c     Wed Oct 03 10:00:44 2007 +0100
@@ -1145,20 +1145,20 @@ static u32 __devinit nvidia_get_arch(str
        case 0x0340:            /* GeForceFX 5700 */
                arch = NV_ARCH_30;
                break;
-       case 0x0040:
-       case 0x00C0:
-       case 0x0120:
+       case 0x0040:            /* GeForce 6800 */
+       case 0x00C0:            /* GeForce 6800 */
+       case 0x0120:            /* GeForce 6800 */
        case 0x0130:
-       case 0x0140:
-       case 0x0160:
-       case 0x01D0:
-       case 0x0090:
-       case 0x0210:
-       case 0x0220:
+       case 0x0140:            /* GeForce 6600 */
+       case 0x0160:            /* GeForce 6200 */
+       case 0x01D0:            /* GeForce 7200, 7300, 7400 */
+       case 0x0090:            /* GeForce 7800 */
+       case 0x0210:            /* GeForce 6800 */
+       case 0x0220:            /* GeForce 6200 */
        case 0x0230:
-       case 0x0240:
-       case 0x0290:
-       case 0x0390:
+       case 0x0240:            /* GeForce 6100 */
+       case 0x0290:            /* GeForce 7900 */
+       case 0x0390:            /* GeForce 7600 */
                arch = NV_ARCH_40;
                break;
        case 0x0020:            /* TNT, TNT2 */
diff -r aafef975e518 -r 3e8752eb6d9c fs/buffer.c
--- a/fs/buffer.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/buffer.c       Wed Oct 03 10:00:44 2007 +0100
@@ -838,7 +838,10 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode);
  */
 int __set_page_dirty_buffers(struct page *page)
 {
-       struct address_space * const mapping = page->mapping;
+       struct address_space * const mapping = page_mapping(page);
+
+       if (unlikely(!mapping))
+               return !TestSetPageDirty(page);
 
        spin_lock(&mapping->private_lock);
        if (page_has_buffers(page)) {
@@ -1176,8 +1179,21 @@ grow_buffers(struct block_device *bdev, 
        } while ((size << sizebits) < PAGE_SIZE);
 
        index = block >> sizebits;
+
+       /*
+        * Check for a block which wants to lie outside our maximum possible
+        * pagecache index.  (this comparison is done using sector_t types).
+        */
+       if (unlikely(index != block >> sizebits)) {
+               char b[BDEVNAME_SIZE];
+
+               printk(KERN_ERR "%s: requested out-of-range block %llu for "
+                       "device %s\n",
+                       __FUNCTION__, (unsigned long long)block,
+                       bdevname(bdev, b));
+               return -EIO;
+       }
        block = index << sizebits;
-
        /* Create a page with the proper size buffers.. */
        page = grow_dev_page(bdev, block, index, size);
        if (!page)
@@ -1204,12 +1220,16 @@ __getblk_slow(struct block_device *bdev,
 
        for (;;) {
                struct buffer_head * bh;
+               int ret;
 
                bh = __find_get_block(bdev, block, size);
                if (bh)
                        return bh;
 
-               if (!grow_buffers(bdev, block, size))
+               ret = grow_buffers(bdev, block, size);
+               if (ret < 0)
+                       return NULL;
+               if (ret == 0)
                        free_more_memory();
        }
 }
diff -r aafef975e518 -r 3e8752eb6d9c fs/cifs/CHANGES
--- a/fs/cifs/CHANGES   Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/cifs/CHANGES   Wed Oct 03 10:00:44 2007 +0100
@@ -6,7 +6,11 @@ on requests on other threads.  Improve P
 (lock cancel now works, and unlock of merged range works even
 to Windows servers now).  Fix oops on mount to lanman servers
 (win9x, os/2 etc.) when null password.  Do not send listxattr
-(SMB to query all EAs) if nouser_xattr specified.
+(SMB to query all EAs) if nouser_xattr specified.  Return error
+in rename 2nd attempt retry (ie report if rename by handle also
+fails, after rename by path fails, we were not reporting whether
+the retry worked or not).
+
 
 Version 1.44
 ------------
diff -r aafef975e518 -r 3e8752eb6d9c fs/cifs/file.c
--- a/fs/cifs/file.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/cifs/file.c    Wed Oct 03 10:00:44 2007 +0100
@@ -752,6 +752,7 @@ int cifs_lock(struct file *file, int cmd
                        int stored_rc = 0;
                        struct cifsLockInfo *li, *tmp;
 
+                       rc = 0;
                        down(&fid->lock_sem);
                        list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
                                if (pfLock->fl_start <= li->offset &&
@@ -766,7 +767,7 @@ int cifs_lock(struct file *file, int cmd
                                        kfree(li);
                                }
                        }
-               up(&fid->lock_sem);
+                       up(&fid->lock_sem);
                }
        }
 
diff -r aafef975e518 -r 3e8752eb6d9c fs/cifs/inode.c
--- a/fs/cifs/inode.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/cifs/inode.c   Wed Oct 03 10:00:44 2007 +0100
@@ -880,10 +880,14 @@ int cifs_rename(struct inode *source_ino
                        kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
                if (info_buf_source != NULL) {
                        info_buf_target = info_buf_source + 1;
-                       rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
-                               info_buf_source, cifs_sb_source->local_nls, 
-                               cifs_sb_source->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                       if (pTcon->ses->capabilities & CAP_UNIX)
+                               rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
+                                       info_buf_source, 
+                                       cifs_sb_source->local_nls,
+                                       cifs_sb_source->mnt_cifs_flags &
+                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                       /* else rc is still EEXIST so will fall through to
+                          unlink the target and retry rename */
                        if (rc == 0) {
                                rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
                                                info_buf_target,
@@ -932,7 +936,7 @@ int cifs_rename(struct inode *source_ino
                                 cifs_sb_source->mnt_cifs_flags & 
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
                if (rc==0) {
-                       CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
+                       rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
                                              cifs_sb_source->local_nls, 
                                              cifs_sb_source->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
diff -r aafef975e518 -r 3e8752eb6d9c fs/compat.c
--- a/fs/compat.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/compat.c       Wed Oct 03 10:00:44 2007 +0100
@@ -873,7 +873,7 @@ asmlinkage long compat_sys_mount(char __
 
        retval = -EINVAL;
 
-       if (type_page) {
+       if (type_page && data_page) {
                if (!strcmp((char *)type_page, SMBFS_NAME)) {
                        do_smb_super_data_conv((void *)data_page);
                } else if (!strcmp((char *)type_page, NCPFS_NAME)) {
diff -r aafef975e518 -r 3e8752eb6d9c fs/ext2/super.c
--- a/fs/ext2/super.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/ext2/super.c   Wed Oct 03 10:00:44 2007 +0100
@@ -701,10 +701,14 @@ static int ext2_fill_super(struct super_
                set_opt(sbi->s_mount_opt, GRPID);
        if (def_mount_opts & EXT2_DEFM_UID16)
                set_opt(sbi->s_mount_opt, NO_UID32);
+#ifdef CONFIG_EXT2_FS_XATTR
        if (def_mount_opts & EXT2_DEFM_XATTR_USER)
                set_opt(sbi->s_mount_opt, XATTR_USER);
+#endif
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
        if (def_mount_opts & EXT2_DEFM_ACL)
                set_opt(sbi->s_mount_opt, POSIX_ACL);
+#endif
        
        if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
                set_opt(sbi->s_mount_opt, ERRORS_PANIC);
diff -r aafef975e518 -r 3e8752eb6d9c fs/ext3/super.c
--- a/fs/ext3/super.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/ext3/super.c   Wed Oct 03 10:00:44 2007 +0100
@@ -1451,10 +1451,14 @@ static int ext3_fill_super (struct super
                set_opt(sbi->s_mount_opt, GRPID);
        if (def_mount_opts & EXT3_DEFM_UID16)
                set_opt(sbi->s_mount_opt, NO_UID32);
+#ifdef CONFIG_EXT3_FS_XATTR
        if (def_mount_opts & EXT3_DEFM_XATTR_USER)
                set_opt(sbi->s_mount_opt, XATTR_USER);
+#endif
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
        if (def_mount_opts & EXT3_DEFM_ACL)
                set_opt(sbi->s_mount_opt, POSIX_ACL);
+#endif
        if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA)
                sbi->s_mount_opt |= EXT3_MOUNT_JOURNAL_DATA;
        else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED)
diff -r aafef975e518 -r 3e8752eb6d9c fs/fuse/dir.c
--- a/fs/fuse/dir.c     Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/fuse/dir.c     Wed Oct 03 10:00:44 2007 +0100
@@ -138,6 +138,7 @@ static int fuse_dentry_revalidate(struct
                struct fuse_entry_out outarg;
                struct fuse_conn *fc;
                struct fuse_req *req;
+               struct fuse_req *forget_req;
 
                /* Doesn't hurt to "reset" the validity timeout */
                fuse_invalidate_entry_cache(entry);
@@ -151,21 +152,29 @@ static int fuse_dentry_revalidate(struct
                if (IS_ERR(req))
                        return 0;
 
+               forget_req = fuse_get_req(fc);
+               if (IS_ERR(forget_req)) {
+                       fuse_put_request(fc, req);
+                       return 0;
+               }
+
                fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
                request_send(fc, req);
                err = req->out.h.error;
+               fuse_put_request(fc, req);
                /* Zero nodeid is same as -ENOENT */
                if (!err && !outarg.nodeid)
                        err = -ENOENT;
                if (!err) {
                        struct fuse_inode *fi = get_fuse_inode(inode);
                        if (outarg.nodeid != get_node_id(inode)) {
-                               fuse_send_forget(fc, req, outarg.nodeid, 1);
+                               fuse_send_forget(fc, forget_req,
+                                                outarg.nodeid, 1);
                                return 0;
                        }
                        fi->nlookup ++;
                }
-               fuse_put_request(fc, req);
+               fuse_put_request(fc, forget_req);
                if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
                        return 0;
 
@@ -214,6 +223,7 @@ static struct dentry *fuse_lookup(struct
        struct inode *inode = NULL;
        struct fuse_conn *fc = get_fuse_conn(dir);
        struct fuse_req *req;
+       struct fuse_req *forget_req;
 
        if (entry->d_name.len > FUSE_NAME_MAX)
                return ERR_PTR(-ENAMETOOLONG);
@@ -222,9 +232,16 @@ static struct dentry *fuse_lookup(struct
        if (IS_ERR(req))
                return ERR_PTR(PTR_ERR(req));
 
+       forget_req = fuse_get_req(fc);
+       if (IS_ERR(forget_req)) {
+               fuse_put_request(fc, req);
+               return ERR_PTR(PTR_ERR(forget_req));
+       }
+
        fuse_lookup_init(req, dir, entry, &outarg);
        request_send(fc, req);
        err = req->out.h.error;
+       fuse_put_request(fc, req);
        /* Zero nodeid is same as -ENOENT, but with valid timeout */
        if (!err && outarg.nodeid &&
            (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode)))
@@ -233,11 +250,11 @@ static struct dentry *fuse_lookup(struct
                inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
                                  &outarg.attr);
                if (!inode) {
-                       fuse_send_forget(fc, req, outarg.nodeid, 1);
+                       fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
                        return ERR_PTR(-ENOMEM);
                }
        }
-       fuse_put_request(fc, req);
+       fuse_put_request(fc, forget_req);
        if (err && err != -ENOENT)
                return ERR_PTR(err);
 
@@ -375,6 +392,13 @@ static int create_new_entry(struct fuse_
        struct fuse_entry_out outarg;
        struct inode *inode;
        int err;
+       struct fuse_req *forget_req;
+
+       forget_req = fuse_get_req(fc);
+       if (IS_ERR(forget_req)) {
+               fuse_put_request(fc, req);
+               return PTR_ERR(forget_req);
+       }
 
        req->in.h.nodeid = get_node_id(dir);
        req->out.numargs = 1;
@@ -382,24 +406,24 @@ static int create_new_entry(struct fuse_
        req->out.args[0].value = &outarg;
        request_send(fc, req);
        err = req->out.h.error;
-       if (err) {
-               fuse_put_request(fc, req);
-               return err;
-       }
+       fuse_put_request(fc, req);
+       if (err)
+               goto out_put_forget_req;
+
        err = -EIO;
        if (invalid_nodeid(outarg.nodeid))
-               goto out_put_request;
+               goto out_put_forget_req;
 
        if ((outarg.attr.mode ^ mode) & S_IFMT)
-               goto out_put_request;
+               goto out_put_forget_req;
 
        inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
                          &outarg.attr);
        if (!inode) {
-               fuse_send_forget(fc, req, outarg.nodeid, 1);
+               fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
                return -ENOMEM;
        }
-       fuse_put_request(fc, req);
+       fuse_put_request(fc, forget_req);
 
        if (dir_alias(inode)) {
                iput(inode);
@@ -411,8 +435,8 @@ static int create_new_entry(struct fuse_
        fuse_invalidate_attr(dir);
        return 0;
 
- out_put_request:
-       fuse_put_request(fc, req);
+ out_put_forget_req:
+       fuse_put_request(fc, forget_req);
        return err;
 }
 
@@ -935,14 +959,30 @@ static void iattr_to_fattr(struct iattr 
        }
 }
 
+static void fuse_vmtruncate(struct inode *inode, loff_t offset)
+{
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       int need_trunc;
+
+       spin_lock(&fc->lock);
+       need_trunc = inode->i_size > offset;
+       i_size_write(inode, offset);
+       spin_unlock(&fc->lock);
+
+       if (need_trunc) {
+               struct address_space *mapping = inode->i_mapping;
+               unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
+               truncate_inode_pages(mapping, offset);
+       }
+}
+
 /*
  * Set attributes, and at the same time refresh them.
  *
  * Truncation is slightly complicated, because the 'truncate' request
  * may fail, in which case we don't want to touch the mapping.
- * vmtruncate() doesn't allow for this case.  So do the rlimit
- * checking by hand and call vmtruncate() only after the file has
- * actually been truncated.
+ * vmtruncate() doesn't allow for this case, so do the rlimit checking
+ * and the actual truncation by hand.
  */
 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
 {
@@ -993,12 +1033,8 @@ static int fuse_setattr(struct dentry *e
                        make_bad_inode(inode);
                        err = -EIO;
                } else {
-                       if (is_truncate) {
-                               loff_t origsize = i_size_read(inode);
-                               i_size_write(inode, outarg.attr.size);
-                               if (origsize > outarg.attr.size)
-                                       vmtruncate(inode, outarg.attr.size);
-                       }
+                       if (is_truncate)
+                               fuse_vmtruncate(inode, outarg.attr.size);
                        fuse_change_attributes(inode, &outarg.attr);
                        fi->i_time = time_to_jiffies(outarg.attr_valid,
                                                     outarg.attr_valid_nsec);
diff -r aafef975e518 -r 3e8752eb6d9c fs/fuse/file.c
--- a/fs/fuse/file.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/fuse/file.c    Wed Oct 03 10:00:44 2007 +0100
@@ -481,8 +481,10 @@ static int fuse_commit_write(struct file
                err = -EIO;
        if (!err) {
                pos += count;
-               if (pos > i_size_read(inode))
+               spin_lock(&fc->lock);
+               if (pos > inode->i_size)
                        i_size_write(inode, pos);
+               spin_unlock(&fc->lock);
 
                if (offset == 0 && to == PAGE_CACHE_SIZE) {
                        clear_page_dirty(page);
@@ -586,8 +588,12 @@ static ssize_t fuse_direct_io(struct fil
        }
        fuse_put_request(fc, req);
        if (res > 0) {
-               if (write && pos > i_size_read(inode))
-                       i_size_write(inode, pos);
+               if (write) {
+                       spin_lock(&fc->lock);
+                       if (pos > inode->i_size)
+                               i_size_write(inode, pos);
+                       spin_unlock(&fc->lock);
+               }
                *ppos = pos;
        }
        fuse_invalidate_attr(inode);
diff -r aafef975e518 -r 3e8752eb6d9c fs/fuse/inode.c
--- a/fs/fuse/inode.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/fuse/inode.c   Wed Oct 03 10:00:44 2007 +0100
@@ -109,6 +109,7 @@ static int fuse_remount_fs(struct super_
 
 void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
 {
+       struct fuse_conn *fc = get_fuse_conn(inode);
        if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
                invalidate_inode_pages(inode->i_mapping);
 
@@ -117,7 +118,9 @@ void fuse_change_attributes(struct inode
        inode->i_nlink   = attr->nlink;
        inode->i_uid     = attr->uid;
        inode->i_gid     = attr->gid;
+       spin_lock(&fc->lock);
        i_size_write(inode, attr->size);
+       spin_unlock(&fc->lock);
        inode->i_blksize = PAGE_CACHE_SIZE;
        inode->i_blocks  = attr->blocks;
        inode->i_atime.tv_sec   = attr->atime;
@@ -131,7 +134,7 @@ static void fuse_init_inode(struct inode
 static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
 {
        inode->i_mode = attr->mode & S_IFMT;
-       i_size_write(inode, attr->size);
+       inode->i_size = attr->size;
        if (S_ISREG(inode->i_mode)) {
                fuse_init_common(inode);
                fuse_init_file_inode(inode);
diff -r aafef975e518 -r 3e8752eb6d9c fs/hfs/super.c
--- a/fs/hfs/super.c    Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/hfs/super.c    Wed Oct 03 10:00:44 2007 +0100
@@ -391,11 +391,13 @@ static int hfs_fill_super(struct super_b
                hfs_find_exit(&fd);
                goto bail_no_root;
        }
+       res = -EINVAL;
        root_inode = hfs_iget(sb, &fd.search_key->cat, &rec);
        hfs_find_exit(&fd);
        if (!root_inode)
                goto bail_no_root;
 
+       res = -ENOMEM;
        sb->s_root = d_alloc_root(root_inode);
        if (!sb->s_root)
                goto bail_iput;
diff -r aafef975e518 -r 3e8752eb6d9c fs/jbd/commit.c
--- a/fs/jbd/commit.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/jbd/commit.c   Wed Oct 03 10:00:44 2007 +0100
@@ -158,6 +158,117 @@ static int journal_write_commit_record(j
        journal_put_journal_head(descriptor);
 
        return (ret == -EIO);
+}
+
+void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
+{
+       int i;
+
+       for (i = 0; i < bufs; i++) {
+               wbuf[i]->b_end_io = end_buffer_write_sync;
+               /* We use-up our safety reference in submit_bh() */
+               submit_bh(WRITE, wbuf[i]);
+       }
+}
+
+/*
+ *  Submit all the data buffers to disk
+ */
+static void journal_submit_data_buffers(journal_t *journal,
+                               transaction_t *commit_transaction)
+{
+       struct journal_head *jh;
+       struct buffer_head *bh;
+       int locked;
+       int bufs = 0;
+       struct buffer_head **wbuf = journal->j_wbuf;
+
+       /*
+        * Whenever we unlock the journal and sleep, things can get added
+        * onto ->t_sync_datalist, so we have to keep looping back to
+        * write_out_data until we *know* that the list is empty.
+        *
+        * Cleanup any flushed data buffers from the data list.  Even in
+        * abort mode, we want to flush this out as soon as possible.
+        */
+write_out_data:
+       cond_resched();
+       spin_lock(&journal->j_list_lock);
+
+       while (commit_transaction->t_sync_datalist) {
+               jh = commit_transaction->t_sync_datalist;
+               bh = jh2bh(jh);
+               locked = 0;
+
+               /* Get reference just to make sure buffer does not disappear
+                * when we are forced to drop various locks */
+               get_bh(bh);
+               /* If the buffer is dirty, we need to submit IO and hence
+                * we need the buffer lock. We try to lock the buffer without
+                * blocking. If we fail, we need to drop j_list_lock and do
+                * blocking lock_buffer().
+                */
+               if (buffer_dirty(bh)) {
+                       if (test_set_buffer_locked(bh)) {
+                               BUFFER_TRACE(bh, "needs blocking lock");
+                               spin_unlock(&journal->j_list_lock);
+                               /* Write out all data to prevent deadlocks */
+                               journal_do_submit_data(wbuf, bufs);
+                               bufs = 0;
+                               lock_buffer(bh);
+                               spin_lock(&journal->j_list_lock);
+                       }
+                       locked = 1;
+               }
+               /* We have to get bh_state lock. Again out of order, sigh. */
+               if (!inverted_lock(journal, bh)) {
+                       jbd_lock_bh_state(bh);
+                       spin_lock(&journal->j_list_lock);
+               }
+               /* Someone already cleaned up the buffer? */
+               if (!buffer_jbd(bh)
+                       || jh->b_transaction != commit_transaction
+                       || jh->b_jlist != BJ_SyncData) {
+                       jbd_unlock_bh_state(bh);
+                       if (locked)
+                               unlock_buffer(bh);
+                       BUFFER_TRACE(bh, "already cleaned up");
+                       put_bh(bh);
+                       continue;
+               }
+               if (locked && test_clear_buffer_dirty(bh)) {
+                       BUFFER_TRACE(bh, "needs writeout, adding to array");
+                       wbuf[bufs++] = bh;
+                       __journal_file_buffer(jh, commit_transaction,
+                                               BJ_Locked);
+                       jbd_unlock_bh_state(bh);
+                       if (bufs == journal->j_wbufsize) {
+                               spin_unlock(&journal->j_list_lock);
+                               journal_do_submit_data(wbuf, bufs);
+                               bufs = 0;
+                               goto write_out_data;
+                       }
+               }
+               else {
+                       BUFFER_TRACE(bh, "writeout complete: unfile");
+                       __journal_unfile_buffer(jh);
+                       jbd_unlock_bh_state(bh);
+                       if (locked)
+                               unlock_buffer(bh);
+                       journal_remove_journal_head(bh);
+                       /* Once for our safety reference, once for
+                        * journal_remove_journal_head() */
+                       put_bh(bh);
+                       put_bh(bh);
+               }
+
+               if (lock_need_resched(&journal->j_list_lock)) {
+                       spin_unlock(&journal->j_list_lock);
+                       goto write_out_data;
+               }
+       }
+       spin_unlock(&journal->j_list_lock);
+       journal_do_submit_data(wbuf, bufs);
 }
 
 /*
@@ -313,80 +424,13 @@ void journal_commit_transaction(journal_
         * Now start flushing things to disk, in the order they appear
         * on the transaction lists.  Data blocks go first.
         */
-
        err = 0;
-       /*
-        * Whenever we unlock the journal and sleep, things can get added
-        * onto ->t_sync_datalist, so we have to keep looping back to
-        * write_out_data until we *know* that the list is empty.
-        */
-       bufs = 0;
-       /*
-        * Cleanup any flushed data buffers from the data list.  Even in
-        * abort mode, we want to flush this out as soon as possible.
-        */
-write_out_data:
-       cond_resched();
+       journal_submit_data_buffers(journal, commit_transaction);
+
+       /*
+        * Wait for all previously submitted IO to complete.
+        */
        spin_lock(&journal->j_list_lock);
-
-       while (commit_transaction->t_sync_datalist) {
-               struct buffer_head *bh;
-
-               jh = commit_transaction->t_sync_datalist;
-               commit_transaction->t_sync_datalist = jh->b_tnext;
-               bh = jh2bh(jh);
-               if (buffer_locked(bh)) {
-                       BUFFER_TRACE(bh, "locked");
-                       if (!inverted_lock(journal, bh))
-                               goto write_out_data;
-                       __journal_temp_unlink_buffer(jh);
-                       __journal_file_buffer(jh, commit_transaction,
-                                               BJ_Locked);
-                       jbd_unlock_bh_state(bh);
-                       if (lock_need_resched(&journal->j_list_lock)) {
-                               spin_unlock(&journal->j_list_lock);
-                               goto write_out_data;
-                       }
-               } else {
-                       if (buffer_dirty(bh)) {
-                               BUFFER_TRACE(bh, "start journal writeout");
-                               get_bh(bh);
-                               wbuf[bufs++] = bh;
-                               if (bufs == journal->j_wbufsize) {
-                                       jbd_debug(2, "submit %d writes\n",
-                                                       bufs);
-                                       spin_unlock(&journal->j_list_lock);
-                                       ll_rw_block(SWRITE, bufs, wbuf);
-                                       journal_brelse_array(wbuf, bufs);
-                                       bufs = 0;
-                                       goto write_out_data;
-                               }
-                       } else {
-                               BUFFER_TRACE(bh, "writeout complete: unfile");
-                               if (!inverted_lock(journal, bh))
-                                       goto write_out_data;
-                               __journal_unfile_buffer(jh);
-                               jbd_unlock_bh_state(bh);
-                               journal_remove_journal_head(bh);
-                               put_bh(bh);
-                               if (lock_need_resched(&journal->j_list_lock)) {
-                                       spin_unlock(&journal->j_list_lock);
-                                       goto write_out_data;
-                               }
-                       }
-               }
-       }
-
-       if (bufs) {
-               spin_unlock(&journal->j_list_lock);
-               ll_rw_block(SWRITE, bufs, wbuf);
-               journal_brelse_array(wbuf, bufs);
-               spin_lock(&journal->j_list_lock);
-       }
-
-       /*
-        * Wait for all previously submitted IO to complete.
-        */
        while (commit_transaction->t_locked_list) {
                struct buffer_head *bh;
 
diff -r aafef975e518 -r 3e8752eb6d9c fs/jfs/jfs_imap.c
--- a/fs/jfs/jfs_imap.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/jfs/jfs_imap.c Wed Oct 03 10:00:44 2007 +0100
@@ -318,7 +318,7 @@ int diRead(struct inode *ip)
        struct inomap *imap;
        int block_offset;
        int inodes_left;
-       uint pageno;
+       unsigned long pageno;
        int rel_inode;
 
        jfs_info("diRead: ino = %ld", ip->i_ino);
@@ -606,7 +606,7 @@ int diWrite(tid_t tid, struct inode *ip)
        int block_offset;
        int inodes_left;
        struct metapage *mp;
-       uint pageno;
+       unsigned long pageno;
        int rel_inode;
        int dioffset;
        struct inode *ipimap;
diff -r aafef975e518 -r 3e8752eb6d9c fs/nfs/dir.c
--- a/fs/nfs/dir.c      Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/nfs/dir.c      Wed Oct 03 10:00:44 2007 +0100
@@ -902,9 +902,15 @@ static struct dentry *nfs_lookup(struct 
 
        lock_kernel();
 
-       /* If we're doing an exclusive create, optimize away the lookup */
-       if (nfs_is_exclusive_create(dir, nd))
-               goto no_entry;
+       /*
+        * If we're doing an exclusive create, optimize away the lookup
+        * but don't hash the dentry.
+        */
+       if (nfs_is_exclusive_create(dir, nd)) {
+               d_instantiate(dentry, NULL);
+               res = NULL;
+               goto out_unlock;
+       }
 
        error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
        if (error == -ENOENT)
@@ -1156,6 +1162,8 @@ int nfs_instantiate(struct dentry *dentr
        if (IS_ERR(inode))
                goto out_err;
        d_instantiate(dentry, inode);
+       if (d_unhashed(dentry))
+               d_rehash(dentry);
        return 0;
 out_err:
        d_drop(dentry);
diff -r aafef975e518 -r 3e8752eb6d9c fs/nfsd/nfs2acl.c
--- a/fs/nfsd/nfs2acl.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/nfsd/nfs2acl.c Wed Oct 03 10:00:44 2007 +0100
@@ -287,11 +287,18 @@ static int nfsaclsvc_release_getacl(stru
        return 1;
 }
 
-static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
-               struct nfsd_fhandle *resp)
+static int nfsaclsvc_release_attrstat(struct svc_rqst *rqstp, u32 *p,
+               struct nfsd_attrstat *resp)
 {
        fh_put(&resp->fh);
        return 1;
+}
+
+static int nfsaclsvc_release_access(struct svc_rqst *rqstp, u32 *p,
+               struct nfsd3_accessres *resp)
+{
+       fh_put(&resp->fh);
+       return 1;
 }
 
 #define nfsaclsvc_decode_voidargs      NULL
@@ -322,9 +329,9 @@ static struct svc_procedure         nfsd_acl_pr
 static struct svc_procedure            nfsd_acl_procedures2[] = {
   PROC(null,   void,           void,           void,     RC_NOCACHE, ST),
   PROC(getacl, getacl,         getacl,         getacl,   RC_NOCACHE, 
ST+1+2*(1+ACL)),
-  PROC(setacl, setacl,         attrstat,       fhandle,  RC_NOCACHE, ST+AT),
-  PROC(getattr, fhandle,       attrstat,       fhandle,  RC_NOCACHE, ST+AT),
-  PROC(access, access,         access,         fhandle,  RC_NOCACHE, ST+AT+1),
+  PROC(setacl, setacl,         attrstat,       attrstat, RC_NOCACHE, ST+AT),
+  PROC(getattr, fhandle,       attrstat,       attrstat, RC_NOCACHE, ST+AT),
+  PROC(access, access,         access,         access,   RC_NOCACHE, ST+AT+1),
 };
 
 struct svc_version     nfsd_acl_version2 = {
diff -r aafef975e518 -r 3e8752eb6d9c fs/splice.c
--- a/fs/splice.c       Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/splice.c       Wed Oct 03 10:00:44 2007 +0100
@@ -607,7 +607,7 @@ find_page:
                        ret = -ENOMEM;
                        page = page_cache_alloc_cold(mapping);
                        if (unlikely(!page))
-                               goto out_nomem;
+                               goto out_ret;
 
                        /*
                         * This will also lock the page
@@ -666,7 +666,7 @@ find_page:
                if (sd->pos + this_len > isize)
                        vmtruncate(mapping->host, isize);
 
-               goto out;
+               goto out_ret;
        }
 
        if (buf->page != page) {
@@ -698,7 +698,7 @@ out:
 out:
        page_cache_release(page);
        unlock_page(page);
-out_nomem:
+out_ret:
        return ret;
 }
 
diff -r aafef975e518 -r 3e8752eb6d9c fs/sysfs/file.c
--- a/fs/sysfs/file.c   Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/sysfs/file.c   Wed Oct 03 10:00:44 2007 +0100
@@ -483,11 +483,6 @@ int sysfs_update_file(struct kobject * k
                    (victim->d_parent->d_inode == dir->d_inode)) {
                        victim->d_inode->i_mtime = CURRENT_TIME;
                        fsnotify_modify(victim);
-
-                       /**
-                        * Drop reference from initial sysfs_get_dentry().
-                        */
-                       dput(victim);
                        res = 0;
                } else
                        d_drop(victim);
diff -r aafef975e518 -r 3e8752eb6d9c include/Kbuild
--- a/include/Kbuild    Tue Oct 02 09:52:15 2007 +0100
+++ b/include/Kbuild    Wed Oct 03 10:00:44 2007 +0100
@@ -1,2 +1,9 @@ header-y += asm-generic/ linux/ scsi/ so
-header-y += asm-generic/ linux/ scsi/ sound/ mtd/ rdma/ video/
-header-y += asm-$(ARCH)/ 
+header-y += asm-generic/
+header-y += linux/
+header-y += scsi/
+header-y += sound/
+header-y += mtd/
+header-y += rdma/
+header-y += video/
+
+header-y += asm-$(ARCH)/
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-alpha/Kbuild
--- a/include/asm-alpha/Kbuild  Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-alpha/Kbuild  Wed Oct 03 10:00:44 2007 +0100
@@ -1,5 +1,11 @@ include include/asm-generic/Kbuild.asm
 include include/asm-generic/Kbuild.asm
 
-unifdef-y += console.h fpu.h sysinfo.h compiler.h
+header-y += gentrap.h
+header-y += regdef.h
+header-y += pal.h
+header-y += reg.h
 
-header-y += gentrap.h regdef.h pal.h reg.h
+unifdef-y += console.h
+unifdef-y += fpu.h
+unifdef-y += sysinfo.h
+unifdef-y += compiler.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-arm/elf.h
--- a/include/asm-arm/elf.h     Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-arm/elf.h     Wed Oct 03 10:00:44 2007 +0100
@@ -8,9 +8,6 @@
 
 #include <asm/ptrace.h>
 #include <asm/user.h>
-#ifdef __KERNEL
-#include <asm/procinfo.h>
-#endif
 
 typedef unsigned long elf_greg_t;
 typedef unsigned long elf_freg_t[3];
@@ -32,11 +29,6 @@ typedef struct user_fp elf_fpregset_t;
 typedef struct user_fp elf_fpregset_t;
 
 /*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ( ((x)->e_machine == EM_ARM) && (ELF_PROC_OK((x))) )
-
-/*
  * These are used to set parameters in the core dumps.
  */
 #define ELF_CLASS      ELFCLASS32
@@ -46,6 +38,14 @@ typedef struct user_fp elf_fpregset_t;
 #define ELF_DATA       ELFDATA2LSB
 #endif
 #define ELF_ARCH       EM_ARM
+
+#ifdef __KERNEL__
+#include <asm/procinfo.h>
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( ((x)->e_machine == EM_ARM) && (ELF_PROC_OK((x))) )
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE      4096
@@ -82,8 +82,6 @@ typedef struct user_fp elf_fpregset_t;
 #define ELF_PLATFORM_SIZE 8
 extern char elf_platform[];
 #define ELF_PLATFORM   (elf_platform)
-
-#ifdef __KERNEL__
 
 /*
  * 32-bit code is always OK.  Some cpus can do 26-bit, some can't.
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-arm/page.h
--- a/include/asm-arm/page.h    Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-arm/page.h    Wed Oct 03 10:00:44 2007 +0100
@@ -10,13 +10,13 @@
 #ifndef _ASMARM_PAGE_H
 #define _ASMARM_PAGE_H
 
+
+#ifdef __KERNEL__
 
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT             12
 #define PAGE_SIZE              (1UL << PAGE_SHIFT)
 #define PAGE_MASK              (~(PAGE_SIZE-1))
-
-#ifdef __KERNEL__
 
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-arm/unistd.h
--- a/include/asm-arm/unistd.h  Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-arm/unistd.h  Wed Oct 03 10:00:44 2007 +0100
@@ -347,6 +347,19 @@
 #define __NR_mbind                     (__NR_SYSCALL_BASE+319)
 #define __NR_get_mempolicy             (__NR_SYSCALL_BASE+320)
 #define __NR_set_mempolicy             (__NR_SYSCALL_BASE+321)
+#define __NR_openat                    (__NR_SYSCALL_BASE+322)
+#define __NR_mkdirat                   (__NR_SYSCALL_BASE+323)
+#define __NR_mknodat                   (__NR_SYSCALL_BASE+324)
+#define __NR_fchownat                  (__NR_SYSCALL_BASE+325)
+#define __NR_futimesat                 (__NR_SYSCALL_BASE+326)
+#define __NR_fstatat64                 (__NR_SYSCALL_BASE+327)
+#define __NR_unlinkat                  (__NR_SYSCALL_BASE+328)
+#define __NR_renameat                  (__NR_SYSCALL_BASE+329)
+#define __NR_linkat                    (__NR_SYSCALL_BASE+330)
+#define __NR_symlinkat                 (__NR_SYSCALL_BASE+331)
+#define __NR_readlinkat                        (__NR_SYSCALL_BASE+332)
+#define __NR_fchmodat                  (__NR_SYSCALL_BASE+333)
+#define __NR_faccessat                 (__NR_SYSCALL_BASE+334)
 
 /*
  * The following SWIs are ARM private.
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-arm26/Kbuild
--- a/include/asm-arm26/Kbuild  Tue Oct 02 09:52:15 2007 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-include include/asm-generic/Kbuild.asm
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/Kbuild
--- a/include/asm-cris/Kbuild   Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/Kbuild   Wed Oct 03 10:00:44 2007 +0100
@@ -1,1 +1,5 @@ include include/asm-generic/Kbuild.asm
 include include/asm-generic/Kbuild.asm
+
+header-y += arch-v10/ arch-v32/
+
+unifdef-y += rs485.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/arch-v10/Kbuild
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/include/asm-cris/arch-v10/Kbuild  Wed Oct 03 10:00:44 2007 +0100
@@ -0,0 +1,2 @@
+header-y += ptrace.h
+header-y += user.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/arch-v32/Kbuild
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/include/asm-cris/arch-v32/Kbuild  Wed Oct 03 10:00:44 2007 +0100
@@ -0,0 +1,2 @@
+header-y += ptrace.h
+header-y += user.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/byteorder.h
--- a/include/asm-cris/byteorder.h      Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/byteorder.h      Wed Oct 03 10:00:44 2007 +0100
@@ -3,14 +3,15 @@
 
 #ifdef __GNUC__
 
+#ifdef __KERNEL__
 #include <asm/arch/byteorder.h>
 
 /* defines are necessary because the other files detect the presence
  * of a defined __arch_swab32, not an inline
  */
-
 #define __arch__swab32(x) ___arch__swab32(x)
 #define __arch__swab16(x) ___arch__swab16(x)
+#endif /* __KERNEL__ */
 
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 #  define __BYTEORDER_HAS_U64__
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/elf.h
--- a/include/asm-cris/elf.h    Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/elf.h    Wed Oct 03 10:00:44 2007 +0100
@@ -5,7 +5,6 @@
  * ELF register definitions..
  */
 
-#include <asm/arch/elf.h>
 #include <asm/user.h>
 
 #define R_CRIS_NONE             0
@@ -45,6 +44,9 @@ typedef unsigned long elf_fpregset_t;
 #define ELF_CLASS      ELFCLASS32
 #define ELF_DATA       ELFDATA2LSB
 #define ELF_ARCH       EM_CRIS
+
+#ifdef __KERNEL__
+#include <asm/arch/elf.h>
 
 /* The master for these definitions is {binutils}/include/elf/cris.h:  */
 /* User symbols in this file have a leading underscore.  */
@@ -87,8 +89,8 @@ typedef unsigned long elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
-#endif
+
+#endif /* __KERNEL__ */
 
 #endif
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/page.h
--- a/include/asm-cris/page.h   Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/page.h   Wed Oct 03 10:00:44 2007 +0100
@@ -1,5 +1,7 @@
 #ifndef _CRIS_PAGE_H
 #define _CRIS_PAGE_H
+
+#ifdef __KERNEL__
 
 #include <asm/arch/page.h>
 
@@ -11,8 +13,6 @@
 #define PAGE_SIZE      (1 << PAGE_SHIFT)
 #endif
 #define PAGE_MASK      (~(PAGE_SIZE-1))
-
-#ifdef __KERNEL__
 
 #define clear_page(page)        memset((void *)(page), 0, PAGE_SIZE)
 #define copy_page(to,from)      memcpy((void *)(to), (void *)(from), PAGE_SIZE)
@@ -73,10 +73,10 @@ typedef struct { unsigned long pgprot; }
 #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#endif /* __KERNEL__ */
-
 #include <asm-generic/memory_model.h>
 #include <asm-generic/page.h>
 
+#endif /* __KERNEL__ */
+
 #endif /* _CRIS_PAGE_H */
 
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/posix_types.h
--- a/include/asm-cris/posix_types.h    Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/posix_types.h    Wed Oct 03 10:00:44 2007 +0100
@@ -5,8 +5,6 @@
 
 #ifndef __ARCH_CRIS_POSIX_TYPES_H
 #define __ARCH_CRIS_POSIX_TYPES_H
-
-#include <asm/bitops.h>
 
 /*
  * This file is generally used by user-level software, so you need to
@@ -53,9 +51,8 @@ typedef struct {
 #endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
 } __kernel_fsid_t;
 
-/* should this ifdef be here ?  */
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+#ifdef __KERNEL__
+#include <asm/bitops.h>
 
 #undef __FD_SET
 #define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp))
@@ -69,6 +66,6 @@ typedef struct {
 #undef __FD_ZERO
 #define __FD_ZERO(fdsetp) memset((void *)(fdsetp), 0, __FDSET_LONGS << 2)
 
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#endif /* __KERNEL__ */
 
 #endif /* __ARCH_CRIS_POSIX_TYPES_H */
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/unistd.h
--- a/include/asm-cris/unistd.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/unistd.h Wed Oct 03 10:00:44 2007 +0100
@@ -1,7 +1,5 @@
 #ifndef _ASM_CRIS_UNISTD_H_
 #define _ASM_CRIS_UNISTD_H_
-
-#include <asm/arch/unistd.h>
 
 /*
  * This file contains the system call numbers, and stub macros for libc.
@@ -299,6 +297,7 @@
 
 #define NR_syscalls 289
 
+#include <asm/arch/unistd.h>
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
@@ -322,7 +321,6 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
-#endif
 
 #ifdef __KERNEL_SYSCALLS__
 
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-generic/Kbuild
--- a/include/asm-generic/Kbuild        Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-generic/Kbuild        Wed Oct 03 10:00:44 2007 +0100
@@ -1,3 +1,12 @@ header-y += atomic.h errno-base.h errno.
-header-y += atomic.h errno-base.h errno.h fcntl.h ioctl.h ipc.h mman.h \
-       signal.h statfs.h
-unifdef-y := resource.h siginfo.h
+header-y += atomic.h
+header-y += errno-base.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ipc.h
+header-y += mman.h
+header-y += signal.h
+header-y += statfs.h
+
+unifdef-y += resource.h
+unifdef-y += siginfo.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-generic/Kbuild.asm
--- a/include/asm-generic/Kbuild.asm    Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-generic/Kbuild.asm    Wed Oct 03 10:00:44 2007 +0100
@@ -1,8 +1,34 @@ unifdef-y += a.out.h auxvec.h byteorder.
-unifdef-y += a.out.h auxvec.h byteorder.h errno.h fcntl.h ioctl.h      \
-       ioctls.h ipcbuf.h mman.h msgbuf.h param.h poll.h                \
-       posix_types.h ptrace.h resource.h sembuf.h shmbuf.h shmparam.h  \
-       sigcontext.h siginfo.h signal.h socket.h sockios.h stat.h       \
-       statfs.h termbits.h termios.h types.h unistd.h user.h
+unifdef-y += a.out.h
+unifdef-y += auxvec.h
+unifdef-y += byteorder.h
+unifdef-y += errno.h
+unifdef-y += fcntl.h
+unifdef-y += ioctl.h
+unifdef-y += ioctls.h
+unifdef-y += ipcbuf.h
+unifdef-y += mman.h
+unifdef-y += msgbuf.h
+unifdef-y += param.h
+unifdef-y += poll.h
+unifdef-y += posix_types.h
+unifdef-y += ptrace.h
+unifdef-y += resource.h
+unifdef-y += sembuf.h
+unifdef-y += shmbuf.h
+unifdef-y += sigcontext.h
+unifdef-y += siginfo.h
+unifdef-y += signal.h
+unifdef-y += socket.h
+unifdef-y += sockios.h
+unifdef-y += stat.h
+unifdef-y += statfs.h
+unifdef-y += termbits.h
+unifdef-y += termios.h
+unifdef-y += types.h
+unifdef-y += unistd.h
+unifdef-y += user.h
 
 # These probably shouldn't be exported
-unifdef-y += elf.h page.h
+unifdef-y += shmparam.h
+unifdef-y += elf.h
+unifdef-y += page.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-generic/audit_change_attr.h
--- a/include/asm-generic/audit_change_attr.h   Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-generic/audit_change_attr.h   Wed Oct 03 10:00:44 2007 +0100
@@ -1,16 +1,20 @@ __NR_chmod,
 __NR_chmod,
 __NR_fchmod,
+#ifdef __NR_chown
 __NR_chown,
 __NR_fchown,
 __NR_lchown,
+#endif
 __NR_setxattr,
 __NR_lsetxattr,
 __NR_fsetxattr,
 __NR_removexattr,
 __NR_lremovexattr,
 __NR_fremovexattr,
+#ifdef __NR_fchownat
 __NR_fchownat,
 __NR_fchmodat,
+#endif
 #ifdef __NR_chown32
 __NR_chown32,
 __NR_fchown32,
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-generic/audit_dir_write.h
--- a/include/asm-generic/audit_dir_write.h     Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-generic/audit_dir_write.h     Wed Oct 03 10:00:44 2007 +0100
@@ -1,14 +1,18 @@ __NR_rename,
 __NR_rename,
 __NR_mkdir,
 __NR_rmdir,
+#ifdef __NR_creat
 __NR_creat,
+#endif
 __NR_link,
 __NR_unlink,
 __NR_symlink,
 __NR_mknod,
+#ifdef __NR_mkdirat
 __NR_mkdirat,
 __NR_mknodat,
 __NR_unlinkat,
 __NR_renameat,
 __NR_linkat,
 __NR_symlinkat,
+#endif
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-h8300/page.h
--- a/include/asm-h8300/page.h  Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-h8300/page.h  Wed Oct 03 10:00:44 2007 +0100

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.