WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] Apply patch for 2.6.18.8.
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 04 Oct 2007 17:41:51 -0700
Delivery-date: Thu, 04 Oct 2007 18:30:11 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] Apply patch for 2.6.18.8., Xen patchbot-linux-2.6.18-xen <=