]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
start 2.6.18.1 review cycle
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 11 Oct 2006 21:10:21 +0000 (14:10 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 11 Oct 2006 21:10:21 +0000 (14:10 -0700)
69 files changed:
review-2.6.18/0001-HEADERS-One-line-per-header-in-Kbuild-files-to-reduce-conflicts.patch [moved from queue-2.6.18/0001-HEADERS-One-line-per-header-in-Kbuild-files-to-reduce-conflicts.patch with 100% similarity]
review-2.6.18/0002-HEADERS-Fix-ARM-make-headers_check.patch [moved from queue-2.6.18/0002-HEADERS-Fix-ARM-make-headers_check.patch with 100% similarity]
review-2.6.18/0003-Fix-make-headers_check-on-sh.patch [moved from queue-2.6.18/0003-Fix-make-headers_check-on-sh.patch with 100% similarity]
review-2.6.18/0004-Fix-make-headers_check-on-sh64.patch [moved from queue-2.6.18/0004-Fix-make-headers_check-on-sh64.patch with 100% similarity]
review-2.6.18/0005-Fix-make-headers_check-on-m32r.patch [moved from queue-2.6.18/0005-Fix-make-headers_check-on-m32r.patch with 100% similarity]
review-2.6.18/0006-Fix-exported-headers-for-SPARC-SPARC64.patch [moved from queue-2.6.18/0006-Fix-exported-headers-for-SPARC-SPARC64.patch with 100% similarity]
review-2.6.18/0007-Fix-m68knommu-exported-headers.patch [moved from queue-2.6.18/0007-Fix-m68knommu-exported-headers.patch with 100% similarity]
review-2.6.18/0008-Fix-H8300-exported-headers.patch [moved from queue-2.6.18/0008-Fix-H8300-exported-headers.patch with 100% similarity]
review-2.6.18/0009-Remove-ARM26-header-export.patch [moved from queue-2.6.18/0009-Remove-ARM26-header-export.patch with 100% similarity]
review-2.6.18/0010-Remove-UML-header-export.patch [moved from queue-2.6.18/0010-Remove-UML-header-export.patch with 100% similarity]
review-2.6.18/0011-Don-t-advertise-or-allow-headers_-install-check-where-inappropriate.patch [moved from queue-2.6.18/0011-Don-t-advertise-or-allow-headers_-install-check-where-inappropriate.patch with 100% similarity]
review-2.6.18/0012-Fix-v850-exported-headers.patch [moved from queue-2.6.18/0012-Fix-v850-exported-headers.patch with 100% similarity]
review-2.6.18/0013-Clean-up-exported-headers-on-CRIS.patch [moved from queue-2.6.18/0013-Clean-up-exported-headers-on-CRIS.patch with 100% similarity]
review-2.6.18/0014-Remove-offsetof-from-user-visible-linux-stddef.h.patch [moved from queue-2.6.18/0014-Remove-offsetof-from-user-visible-linux-stddef.h.patch with 100% similarity]
review-2.6.18/0015-powerpc-fix-building-gdb-against-asm-ptrace.h.patch [moved from queue-2.6.18/0015-powerpc-fix-building-gdb-against-asm-ptrace.h.patch with 100% similarity]
review-2.6.18/alsa-fix-initiailization-of-user-space-controls.patch [moved from queue-2.6.18/alsa-fix-initiailization-of-user-space-controls.patch with 100% similarity]
review-2.6.18/backlight-fix-oops-in-__mutex_lock_slowpath-during-head-sys-class-graphics-fb0.patch [moved from queue-2.6.18/backlight-fix-oops-in-__mutex_lock_slowpath-during-head-sys-class-graphics-fb0.patch with 100% similarity]
review-2.6.18/bcm43xx-fix-regressions-in-2.6.18.patch [moved from queue-2.6.18/bcm43xx-fix-regressions-in-2.6.18.patch with 100% similarity]
review-2.6.18/block-layer-elv_iosched_show-should-get-elv_list_lock.patch [moved from queue-2.6.18/block-layer-elv_iosched_show-should-get-elv_list_lock.patch with 100% similarity]
review-2.6.18/cpu-to-node-relationship-fixup-acpi_map_cpu2node.patch [moved from queue-2.6.18/cpu-to-node-relationship-fixup-acpi_map_cpu2node.patch with 98% similarity]
review-2.6.18/cpu-to-node-relationship-fixup-map-cpu-to-node.patch [moved from queue-2.6.18/cpu-to-node-relationship-fixup-map-cpu-to-node.patch with 98% similarity]
review-2.6.18/cpufreq-fix-some-more-cpu-hotplug-locking.patch [moved from queue-2.6.18/cpufreq-fix-some-more-cpu-hotplug-locking.patch with 100% similarity]
review-2.6.18/do-not-free-non-slab-allocated-per_cpu_pageset.patch [moved from queue-2.6.18/do-not-free-non-slab-allocated-per_cpu_pageset.patch with 100% similarity]
review-2.6.18/fbdev-correct-buffer-size-limit-in-fbmem_read_proc.patch [moved from queue-2.6.18/fbdev-correct-buffer-size-limit-in-fbmem_read_proc.patch with 100% similarity]
review-2.6.18/fix-longstanding-load-balancing-bug-in-the-scheduler.patch [moved from queue-2.6.18/fix-longstanding-load-balancing-bug-in-the-scheduler.patch with 99% similarity]
review-2.6.18/fix-vidioc_enumstd-bug.patch [moved from queue-2.6.18/fix-vidioc_enumstd-bug.patch with 100% similarity]
review-2.6.18/i386-bootioremap-kexec-fix.patch [moved from queue-2.6.18/i386-bootioremap-kexec-fix.patch with 100% similarity]
review-2.6.18/i386-fix-flat-mode-numa-on-a-real-numa-system.patch [moved from queue-2.6.18/i386-fix-flat-mode-numa-on-a-real-numa-system.patch with 100% similarity]
review-2.6.18/ib-mthca-fix-lid-used-for-sending-traps.patch [moved from queue-2.6.18/ib-mthca-fix-lid-used-for-sending-traps.patch with 100% similarity]
review-2.6.18/ide-generic-jmicron-fix.patch [moved from queue-2.6.18/ide-generic-jmicron-fix.patch with 100% similarity]
review-2.6.18/invalidate_inode_pages2-ignore-page-refcounts.patch [moved from queue-2.6.18/invalidate_inode_pages2-ignore-page-refcounts.patch with 100% similarity]
review-2.6.18/ipv6-bh_lock_sock_nested-on-tcp_v6_rcv.patch [moved from queue-2.6.18/ipv6-bh_lock_sock_nested-on-tcp_v6_rcv.patch with 100% similarity]
review-2.6.18/ipv6-disable-sg-for-gso-unless-we-have-checksum.patch [moved from queue-2.6.18/ipv6-disable-sg-for-gso-unless-we-have-checksum.patch with 100% similarity]
review-2.6.18/jbd-fix-commit-of-ordered-data-buffers.patch [moved from queue-2.6.18/jbd-fix-commit-of-ordered-data-buffers.patch with 100% similarity]
review-2.6.18/load_module-no-bug-if-module_subsys-uninitialized.patch [moved from queue-2.6.18/load_module-no-bug-if-module_subsys-uninitialized.patch with 100% similarity]
review-2.6.18/mbox [new file with mode: 0644]
review-2.6.18/md-fix-problem-where-hot-added-drives-are-not-resynced.patch [moved from queue-2.6.18/md-fix-problem-where-hot-added-drives-are-not-resynced.patch with 100% similarity]
review-2.6.18/mm-bug-in-set_page_dirty_buffers.patch [moved from queue-2.6.18/mm-bug-in-set_page_dirty_buffers.patch with 100% similarity]
review-2.6.18/mv643xx_eth-fix-obvious-typo-which-caused-build-breakage.patch [moved from queue-2.6.18/mv643xx_eth-fix-obvious-typo-which-caused-build-breakage.patch with 100% similarity]
review-2.6.18/net_sched-fix-fallout-from-dev-qdisc-rcu-change.patch [moved from queue-2.6.18/net_sched-fix-fallout-from-dev-qdisc-rcu-change.patch with 100% similarity]
review-2.6.18/netdrvr-lp486e-fix-typo.patch [moved from queue-2.6.18/netdrvr-lp486e-fix-typo.patch with 100% similarity]
review-2.6.18/netfilter-nat-fix-notrack-checksum-handling.patch [moved from queue-2.6.18/netfilter-nat-fix-notrack-checksum-handling.patch with 100% similarity]
review-2.6.18/pkt_sched-cls_basic-use-unsigned-int-when-generating-handle.patch [moved from queue-2.6.18/pkt_sched-cls_basic-use-unsigned-int-when-generating-handle.patch with 100% similarity]
review-2.6.18/powerpc-fix-ohare-ide-irq-workaround-on-old-powermacs.patch [moved from queue-2.6.18/powerpc-fix-ohare-ide-irq-workaround-on-old-powermacs.patch with 100% similarity]
review-2.6.18/rtc-driver-rtc-pcf8563-century-bit-inversed.patch [moved from queue-2.6.18/rtc-driver-rtc-pcf8563-century-bit-inversed.patch with 100% similarity]
review-2.6.18/rtc-lockdep-fix-workaround.patch [moved from queue-2.6.18/rtc-lockdep-fix-workaround.patch with 100% similarity]
review-2.6.18/s390-user-readable-uninitialised-kernel-memory.patch [moved from queue-2.6.18/s390-user-readable-uninitialised-kernel-memory.patch with 100% similarity]
review-2.6.18/sata_mv-fix-oops.patch [moved from queue-2.6.18/sata_mv-fix-oops.patch with 100% similarity]
review-2.6.18/scx200_hrt-fix-precedence-bug-manifesting-as-27x-clock-in-1-mhz-mode.patch [moved from queue-2.6.18/scx200_hrt-fix-precedence-bug-manifesting-as-27x-clock-in-1-mhz-mode.patch with 100% similarity]
review-2.6.18/series [moved from queue-2.6.18/series with 100% similarity]
review-2.6.18/sky2-network-driver-device-ids.patch [moved from queue-2.6.18/sky2-network-driver-device-ids.patch with 100% similarity]
review-2.6.18/sky2-tx-pause-bug-fix.patch [moved from queue-2.6.18/sky2-tx-pause-bug-fix.patch with 100% similarity]
review-2.6.18/sparc64-fix-serious-bug-in-sched_clock-on-sparc64.patch [moved from queue-2.6.18/sparc64-fix-serious-bug-in-sched_clock-on-sparc64.patch with 100% similarity]
review-2.6.18/sparc64-fix-sparc64-ramdisk-handling.patch [moved from queue-2.6.18/sparc64-fix-sparc64-ramdisk-handling.patch with 100% similarity]
review-2.6.18/sysfs-remove-duplicated-dput-in-sysfs_update_file.patch [moved from queue-2.6.18/sysfs-remove-duplicated-dput-in-sysfs_update_file.patch with 100% similarity]
review-2.6.18/tcp-fix-and-simplify-microsecond-rtt-sampling.patch [moved from queue-2.6.18/tcp-fix-and-simplify-microsecond-rtt-sampling.patch with 100% similarity]
review-2.6.18/uml-allow-using-again-x86-x86_64-crypto-code.patch [moved from queue-2.6.18/uml-allow-using-again-x86-x86_64-crypto-code.patch with 100% similarity]
review-2.6.18/uml-fix-uml-build-failure.patch [moved from queue-2.6.18/uml-fix-uml-build-failure.patch with 100% similarity]
review-2.6.18/uml-use-defconfig_list-to-avoid-reading-host-s-config.patch [moved from queue-2.6.18/uml-use-defconfig_list-to-avoid-reading-host-s-config.patch with 100% similarity]
review-2.6.18/usb-allow-compile-in-g_ether-fix-typo.patch [moved from queue-2.6.18/usb-allow-compile-in-g_ether-fix-typo.patch with 100% similarity]
review-2.6.18/video-cx24123-fix-pll-divisor-setup.patch [moved from queue-2.6.18/video-cx24123-fix-pll-divisor-setup.patch with 100% similarity]
review-2.6.18/video-fix-msp343xg-handling-regression.patch [moved from queue-2.6.18/video-fix-msp343xg-handling-regression.patch with 100% similarity]
review-2.6.18/video-pvrusb2-improve-24xxx-config-option-description.patch [moved from queue-2.6.18/video-pvrusb2-improve-24xxx-config-option-description.patch with 100% similarity]
review-2.6.18/video-pvrusb2-limit-hor-res-for-24xxx-devices.patch [moved from queue-2.6.18/video-pvrusb2-limit-hor-res-for-24xxx-devices.patch with 100% similarity]
review-2.6.18/video-pvrusb2-solve-mutex-deadlock.patch [moved from queue-2.6.18/video-pvrusb2-solve-mutex-deadlock.patch with 100% similarity]
review-2.6.18/video-pvrusb2-suppress-compiler-warning.patch [moved from queue-2.6.18/video-pvrusb2-suppress-compiler-warning.patch with 100% similarity]
review-2.6.18/x86-64-calgary-iommu-fix-off-by-one-when-calculating-register-space-location.patch [moved from queue-2.6.18/x86-64-calgary-iommu-fix-off-by-one-when-calculating-register-space-location.patch with 100% similarity]
review-2.6.18/zd1211rw-zd1211b-asic-fwt-not-jointly-decoder.patch [moved from queue-2.6.18/zd1211rw-zd1211b-asic-fwt-not-jointly-decoder.patch with 100% similarity]
review-2.6.18/zone_reclaim-dynamic-slab-reclaim.patch [moved from queue-2.6.18/zone_reclaim-dynamic-slab-reclaim.patch with 100% similarity]

similarity index 98%
rename from queue-2.6.18/cpu-to-node-relationship-fixup-acpi_map_cpu2node.patch
rename to review-2.6.18/cpu-to-node-relationship-fixup-acpi_map_cpu2node.patch
index 75be70449ee5e8b37647009902783d7389fef30c..0de1af2fa840fab42fc2ea1955921b32b3729b5f 100644 (file)
@@ -27,7 +27,7 @@ hot-add.  We now have acpi_map_pxm_to_node() which is also
 used at boot.  It's suitable here.
 
 Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
-Cc: "Luck, Tony" <tony.luck@intel.com>
+Cc: Tony Luck <tony.luck@intel.com>
 Signed-off-by: Andrew Morton <akpm@osdl.org>
 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 
similarity index 98%
rename from queue-2.6.18/cpu-to-node-relationship-fixup-map-cpu-to-node.patch
rename to review-2.6.18/cpu-to-node-relationship-fixup-map-cpu-to-node.patch
index 9fc7a9c3c5a4e81a101d72ff25f7f5980eecb15a..4d9661f804e5ac95fb1e706f0f1c2d9fa56c38f9 100644 (file)
@@ -21,7 +21,7 @@ This mapping should be done before cpu onlining.
 This patch also handles cpu hotremove case.
 
 Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
-Cc: "Luck, Tony" <tony.luck@intel.com>
+Cc: Tony Luck <tony.luck@intel.com>
 Signed-off-by: Andrew Morton <akpm@osdl.org>
 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 
similarity index 99%
rename from queue-2.6.18/fix-longstanding-load-balancing-bug-in-the-scheduler.patch
rename to review-2.6.18/fix-longstanding-load-balancing-bug-in-the-scheduler.patch
index e95a777830da0cf6ba756e45488de2373793672a..4b84d84a213601d1bfced14499e0e9712a01ce62 100644 (file)
@@ -47,7 +47,7 @@ contains other local variable.
 
 Signed-off-by: Christoph Lameter <clameter@sgi.com>
 Cc: John Hawkes <hawkes@sgi.com>
-Cc: "Siddha, Suresh B" <suresh.b.siddha@intel.com>
+Cc: Suresh Siddha <suresh.b.siddha@intel.com>
 Cc: Ingo Molnar <mingo@elte.hu>
 Cc: Nick Piggin <nickpiggin@yahoo.com.au>
 Cc: Peter Williams <pwil3058@bigpond.net.au>
diff --git a/review-2.6.18/mbox b/review-2.6.18/mbox
new file mode 100644 (file)
index 0000000..fe047a1
--- /dev/null
@@ -0,0 +1,11782 @@
+From greg@quad.kroah.org Wed Oct 11 13:48:29 2006
+Message-Id: <20061011204829.555132013@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:47:57 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Patrick McHardy <kaber@trash.net>,
+ "David S. Miller" <davem@davemloft.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 01/67] NET_SCHED: Fix fallout from dev->qdisc RCU change
+Content-Disposition: inline; filename=net_sched-fix-fallout-from-dev-qdisc-rcu-change.patch
+Status: RO
+Content-Length: 8212
+Lines: 268
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Patrick McHardy <kaber@trash.net>
+
+The move of qdisc destruction to a rcu callback broke locking in the
+entire qdisc layer by invalidating previously valid assumptions about
+the context in which changes to the qdisc tree occur.
+
+The two assumptions were:
+
+- since changes only happen in process context, read_lock doesn't need
+  bottem half protection. Now invalid since destruction of inner qdiscs,
+  classifiers, actions and estimators happens in the RCU callback unless
+  they're manually deleted, resulting in dead-locks when read_lock in
+  process context is interrupted by write_lock_bh in bottem half context.
+
+- since changes only happen under the RTNL, no additional locking is
+  necessary for data not used during packet processing (f.e. u32_list).
+  Again, since destruction now happens in the RCU callback, this assumption
+  is not valid anymore, causing races while using this data, which can
+  result in corruption or use-after-free.
+
+Instead of "fixing" this by disabling bottem halfs everywhere and adding
+new locks/refcounting, this patch makes these assumptions valid again by
+moving destruction back to process context. Since only the dev->qdisc
+pointer is protected by RCU, but ->enqueue and the qdisc tree are still
+protected by dev->qdisc_lock, destruction of the tree can be performed
+immediately and only the final free needs to happen in the rcu callback
+to make sure dev_queue_xmit doesn't access already freed memory.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/core/dev.c          |   14 +++++-----
+ net/sched/cls_api.c     |    4 +-
+ net/sched/sch_api.c     |   16 +++++------
+ net/sched/sch_generic.c |   66 +++++++++++++++---------------------------------
+ 4 files changed, 39 insertions(+), 61 deletions(-)
+
+--- linux-2.6.18.orig/net/core/dev.c
++++ linux-2.6.18/net/core/dev.c
+@@ -1478,14 +1478,16 @@ gso:
+       if (q->enqueue) {
+               /* Grab device queue */
+               spin_lock(&dev->queue_lock);
++              q = dev->qdisc;
++              if (q->enqueue) {
++                      rc = q->enqueue(skb, q);
++                      qdisc_run(dev);
++                      spin_unlock(&dev->queue_lock);
+-              rc = q->enqueue(skb, q);
+-
+-              qdisc_run(dev);
+-
++                      rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
++                      goto out;
++              }
+               spin_unlock(&dev->queue_lock);
+-              rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
+-              goto out;
+       }
+       /* The device has no queue. Common case for software devices:
+--- linux-2.6.18.orig/net/sched/cls_api.c
++++ linux-2.6.18/net/sched/cls_api.c
+@@ -401,7 +401,7 @@ static int tc_dump_tfilter(struct sk_buf
+       if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
+               return skb->len;
+-      read_lock_bh(&qdisc_tree_lock);
++      read_lock(&qdisc_tree_lock);
+       if (!tcm->tcm_parent)
+               q = dev->qdisc_sleeping;
+       else
+@@ -458,7 +458,7 @@ errout:
+       if (cl)
+               cops->put(q, cl);
+ out:
+-      read_unlock_bh(&qdisc_tree_lock);
++      read_unlock(&qdisc_tree_lock);
+       dev_put(dev);
+       return skb->len;
+ }
+--- linux-2.6.18.orig/net/sched/sch_api.c
++++ linux-2.6.18/net/sched/sch_api.c
+@@ -195,14 +195,14 @@ struct Qdisc *qdisc_lookup(struct net_de
+ {
+       struct Qdisc *q;
+-      read_lock_bh(&qdisc_tree_lock);
++      read_lock(&qdisc_tree_lock);
+       list_for_each_entry(q, &dev->qdisc_list, list) {
+               if (q->handle == handle) {
+-                      read_unlock_bh(&qdisc_tree_lock);
++                      read_unlock(&qdisc_tree_lock);
+                       return q;
+               }
+       }
+-      read_unlock_bh(&qdisc_tree_lock);
++      read_unlock(&qdisc_tree_lock);
+       return NULL;
+ }
+@@ -837,7 +837,7 @@ static int tc_dump_qdisc(struct sk_buff 
+                       continue;
+               if (idx > s_idx)
+                       s_q_idx = 0;
+-              read_lock_bh(&qdisc_tree_lock);
++              read_lock(&qdisc_tree_lock);
+               q_idx = 0;
+               list_for_each_entry(q, &dev->qdisc_list, list) {
+                       if (q_idx < s_q_idx) {
+@@ -846,12 +846,12 @@ static int tc_dump_qdisc(struct sk_buff 
+                       }
+                       if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
+                                         cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
+-                              read_unlock_bh(&qdisc_tree_lock);
++                              read_unlock(&qdisc_tree_lock);
+                               goto done;
+                       }
+                       q_idx++;
+               }
+-              read_unlock_bh(&qdisc_tree_lock);
++              read_unlock(&qdisc_tree_lock);
+       }
+ done:
+@@ -1074,7 +1074,7 @@ static int tc_dump_tclass(struct sk_buff
+       s_t = cb->args[0];
+       t = 0;
+-      read_lock_bh(&qdisc_tree_lock);
++      read_lock(&qdisc_tree_lock);
+       list_for_each_entry(q, &dev->qdisc_list, list) {
+               if (t < s_t || !q->ops->cl_ops ||
+                   (tcm->tcm_parent &&
+@@ -1096,7 +1096,7 @@ static int tc_dump_tclass(struct sk_buff
+                       break;
+               t++;
+       }
+-      read_unlock_bh(&qdisc_tree_lock);
++      read_unlock(&qdisc_tree_lock);
+       cb->args[0] = t;
+--- linux-2.6.18.orig/net/sched/sch_generic.c
++++ linux-2.6.18/net/sched/sch_generic.c
+@@ -45,11 +45,10 @@
+    The idea is the following:
+    - enqueue, dequeue are serialized via top level device
+      spinlock dev->queue_lock.
+-   - tree walking is protected by read_lock_bh(qdisc_tree_lock)
++   - tree walking is protected by read_lock(qdisc_tree_lock)
+      and this lock is used only in process context.
+-   - updates to tree are made under rtnl semaphore or
+-     from softirq context (__qdisc_destroy rcu-callback)
+-     hence this lock needs local bh disabling.
++   - updates to tree are made only under rtnl semaphore,
++     hence this lock may be made without local bh disabling.
+    qdisc_tree_lock must be grabbed BEFORE dev->queue_lock!
+  */
+@@ -57,14 +56,14 @@ DEFINE_RWLOCK(qdisc_tree_lock);
+ void qdisc_lock_tree(struct net_device *dev)
+ {
+-      write_lock_bh(&qdisc_tree_lock);
++      write_lock(&qdisc_tree_lock);
+       spin_lock_bh(&dev->queue_lock);
+ }
+ void qdisc_unlock_tree(struct net_device *dev)
+ {
+       spin_unlock_bh(&dev->queue_lock);
+-      write_unlock_bh(&qdisc_tree_lock);
++      write_unlock(&qdisc_tree_lock);
+ }
+ /* 
+@@ -483,20 +482,6 @@ void qdisc_reset(struct Qdisc *qdisc)
+ static void __qdisc_destroy(struct rcu_head *head)
+ {
+       struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu);
+-      struct Qdisc_ops  *ops = qdisc->ops;
+-
+-#ifdef CONFIG_NET_ESTIMATOR
+-      gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
+-#endif
+-      write_lock(&qdisc_tree_lock);
+-      if (ops->reset)
+-              ops->reset(qdisc);
+-      if (ops->destroy)
+-              ops->destroy(qdisc);
+-      write_unlock(&qdisc_tree_lock);
+-      module_put(ops->owner);
+-
+-      dev_put(qdisc->dev);
+       kfree((char *) qdisc - qdisc->padded);
+ }
+@@ -504,32 +489,23 @@ static void __qdisc_destroy(struct rcu_h
+ void qdisc_destroy(struct Qdisc *qdisc)
+ {
+-      struct list_head cql = LIST_HEAD_INIT(cql);
+-      struct Qdisc *cq, *q, *n;
++      struct Qdisc_ops  *ops = qdisc->ops;
+       if (qdisc->flags & TCQ_F_BUILTIN ||
+-              !atomic_dec_and_test(&qdisc->refcnt))
++          !atomic_dec_and_test(&qdisc->refcnt))
+               return;
+-      if (!list_empty(&qdisc->list)) {
+-              if (qdisc->ops->cl_ops == NULL)
+-                      list_del(&qdisc->list);
+-              else
+-                      list_move(&qdisc->list, &cql);
+-      }
+-
+-      /* unlink inner qdiscs from dev->qdisc_list immediately */
+-      list_for_each_entry(cq, &cql, list)
+-              list_for_each_entry_safe(q, n, &qdisc->dev->qdisc_list, list)
+-                      if (TC_H_MAJ(q->parent) == TC_H_MAJ(cq->handle)) {
+-                              if (q->ops->cl_ops == NULL)
+-                                      list_del_init(&q->list);
+-                              else
+-                                      list_move_tail(&q->list, &cql);
+-                      }
+-      list_for_each_entry_safe(cq, n, &cql, list)
+-              list_del_init(&cq->list);
++      list_del(&qdisc->list);
++#ifdef CONFIG_NET_ESTIMATOR
++      gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
++#endif
++      if (ops->reset)
++              ops->reset(qdisc);
++      if (ops->destroy)
++              ops->destroy(qdisc);
++      module_put(ops->owner);
++      dev_put(qdisc->dev);
+       call_rcu(&qdisc->q_rcu, __qdisc_destroy);
+ }
+@@ -549,15 +525,15 @@ void dev_activate(struct net_device *dev
+                               printk(KERN_INFO "%s: activation failed\n", dev->name);
+                               return;
+                       }
+-                      write_lock_bh(&qdisc_tree_lock);
++                      write_lock(&qdisc_tree_lock);
+                       list_add_tail(&qdisc->list, &dev->qdisc_list);
+-                      write_unlock_bh(&qdisc_tree_lock);
++                      write_unlock(&qdisc_tree_lock);
+               } else {
+                       qdisc =  &noqueue_qdisc;
+               }
+-              write_lock_bh(&qdisc_tree_lock);
++              write_lock(&qdisc_tree_lock);
+               dev->qdisc_sleeping = qdisc;
+-              write_unlock_bh(&qdisc_tree_lock);
++              write_unlock(&qdisc_tree_lock);
+       }
+       if (!netif_carrier_ok(dev))
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:29 2006
+Message-Id: <20061011204829.698586192@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:47:58 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Jeff Dike <jdike@addtoit.com>,
+ Paolo Blaisorblade Giarrusso <blaisorblade@yahoo.it>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 02/67] uml: allow using again x86/x86_64 crypto code
+Content-Disposition: inline; filename=uml-allow-using-again-x86-x86_64-crypto-code.patch
+Status: RO
+Content-Length: 2104
+Lines: 57
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+
+Enable compilation of x86_64 crypto code;, and add the needed constant
+to make the code compile again (that macro was added to i386 asm-offsets
+between 2.6.17 and 2.6.18, in 6c2bb98bc33ae33c7a33a133a4cd5a06395fece5).
+
+Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+Acked-by: Jeff Dike <jdike@addtoit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/um/Makefile-x86_64                        |    2 +-
+ arch/um/include/common-offsets.h               |    1 +
+ arch/um/include/sysdep-i386/kernel-offsets.h   |    1 +
+ arch/um/include/sysdep-x86_64/kernel-offsets.h |    1 +
+ 4 files changed, 4 insertions(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/arch/um/Makefile-x86_64
++++ linux-2.6.18/arch/um/Makefile-x86_64
+@@ -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
+--- linux-2.6.18.orig/arch/um/include/common-offsets.h
++++ linux-2.6.18/arch/um/include/common-offsets.h
+@@ -15,3 +15,4 @@ DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
+ 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));
+--- linux-2.6.18.orig/arch/um/include/sysdep-i386/kernel-offsets.h
++++ linux-2.6.18/arch/um/include/sysdep-i386/kernel-offsets.h
+@@ -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) \
+--- linux-2.6.18.orig/arch/um/include/sysdep-x86_64/kernel-offsets.h
++++ linux-2.6.18/arch/um/include/sysdep-x86_64/kernel-offsets.h
+@@ -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>
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:29 2006
+Message-Id: <20061011204829.838812877@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:47:59 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Jeff Dike <jdike@addtoit.com>,
+ Paolo Blaisorblade Giarrusso <blaisorblade@yahoo.it>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 03/67] uml: use DEFCONFIG_LIST to avoid reading hosts config
+Content-Disposition: inline; filename=uml-use-defconfig_list-to-avoid-reading-host-s-config.patch
+Status: RO
+Content-Length: 1680
+Lines: 45
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+
+This should make sure that, for UML, host's configuration files are not
+considered, which avoids various pains to the user. Our dependency are such that
+the obtained Kconfig will be valid and will lead to successful compilation -
+however they cannot prevent an user from disabling any boot device, and if an
+option is not set in the read .config (say /boot/config-XXX), with make
+menuconfig ARCH=um, it is not set. This always disables UBD and all console I/O
+channels, which leads to non-working UML kernels, so this bothers users -
+especially now, since it will happen on almost every machine
+(/boot/config-`uname -r` exists almost on every machine). It can be workarounded
+with make defconfig ARCH=um, but it is non-obvious and can be avoided, so please
+_do_ merge this patch.
+
+Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+Acked-by: Jeff Dike <jdike@addtoit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/um/Kconfig |    5 +++++
+ init/Kconfig    |    1 +
+ 2 files changed, 6 insertions(+)
+
+--- linux-2.6.18.orig/arch/um/Kconfig
++++ linux-2.6.18/arch/um/Kconfig
+@@ -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
+--- linux-2.6.18.orig/init/Kconfig
++++ linux-2.6.18/init/Kconfig
+@@ -1,5 +1,6 @@
+ config DEFCONFIG_LIST
+       string
++      depends on !UML
+       option defconfig_list
+       default "/lib/modules/$UNAME_RELEASE/.config"
+       default "/etc/kernel-config"
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:30 2006
+Message-Id: <20061011204829.981729631@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:00 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Jeff Dike <jdike@addtoit.com>,
+ Paolo Giarrusso <blaisorblade@yahoo.it>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 04/67] UML: Fix UML build failure
+Content-Disposition: inline; filename=uml-fix-uml-build-failure.patch
+Status: RO
+Content-Length: 2645
+Lines: 89
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jeff Dike <jdike@addtoit.com>
+
+don't know if the following is already queued, it fixes an ARCH=um build
+failure, evidence here:
+http://marc.theaimsgroup.com/?l=linux-kernel&m=115875912525137&w=2
+and following thread.
+Cc-ing uml maintainers and I hope I didn't follow too many
+Submitting-patches rules...
+
+The patch is taken from:
+http://user-mode-linux.sourceforge.net/work/current/2.6/2.6.18/patches/no-syscallx
+
+Since the syscallx macros seem to be under threat, this patch stops
+using them, using syscall instead.
+
+Acked-by: Jeff Dike <jdike@addtoit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ arch/um/os-Linux/process.c      |    4 +---
+ arch/um/os-Linux/sys-i386/tls.c |    4 +---
+ arch/um/os-Linux/tls.c          |    7 ++-----
+ 3 files changed, 4 insertions(+), 11 deletions(-)
+
+--- linux-2.6.18.orig/arch/um/os-Linux/process.c
++++ linux-2.6.18/arch/um/os-Linux/process.c
+@@ -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)
+--- linux-2.6.18.orig/arch/um/os-Linux/sys-i386/tls.c
++++ linux-2.6.18/arch/um/os-Linux/sys-i386/tls.c
+@@ -3,8 +3,6 @@
+ #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.
+  * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
+@@ -17,7 +15,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;
+--- linux-2.6.18.orig/arch/um/os-Linux/tls.c
++++ linux-2.6.18/arch/um/os-Linux/tls.c
+@@ -48,14 +48,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 +63,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;
+       }
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:30 2006
+Message-Id: <20061011204830.122500304@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:01 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>,
+ Hans Verkuil <hverkuil@xs4all.nl>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 05/67] Video: Fix msp343xG handling regression
+Content-Disposition: inline; filename=video-fix-msp343xg-handling-regression.patch
+Status: RO
+Content-Length: 2204
+Lines: 57
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Hans Verkuil <hverkuil@xs4all.nl>
+
+The msp3430G and msp3435G models cannot do Automatic Standard Detection,
+so these should be forced to BTSC. These chips are early production
+versions for the msp34xxG series and are quite rare.
+
+The workaround for kernel 2.6.18 is to use 'standard=32' as msp3400 module
+option.
+
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/msp3400-driver.c   |    2 ++
+ drivers/media/video/msp3400-driver.h   |    1 +
+ drivers/media/video/msp3400-kthreads.c |    5 +++--
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/drivers/media/video/msp3400-driver.c
++++ linux-2.6.18/drivers/media/video/msp3400-driver.c
+@@ -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) {
+--- linux-2.6.18.orig/drivers/media/video/msp3400-driver.h
++++ linux-2.6.18/drivers/media/video/msp3400-driver.h
+@@ -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;
+--- linux-2.6.18.orig/drivers/media/video/msp3400-kthreads.c
++++ linux-2.6.18/drivers/media/video/msp3400-kthreads.c
+@@ -960,9 +960,10 @@ int msp34xxg_thread(void *data)
+               /* setup the chip*/
+               msp34xxg_reset(client);
+-              state->std = state->radio ? 0x40 : msp_standard;
+-              /* start autodetect */
++              state->std = state->radio ? 0x40 :
++                      (state->force_btsc && msp_standard == 1) ? 32 : msp_standard;
+               msp_write_dem(client, 0x20, state->std);
++              /* start autodetect */
+               if (state->std != 1)
+                       goto unmute;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:30 2006
+Message-Id: <20061011204830.269772413@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:02 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>,
+ Yeasah Pell <yeasah@schwide.net>,
+ Steven Toth <stoth@hauppauge.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 06/67] Video: cx24123: fix PLL divisor setup
+Content-Disposition: inline; filename=video-cx24123-fix-pll-divisor-setup.patch
+Status: RO
+Content-Length: 1331
+Lines: 33
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Yeasah Pell <yeasah@schwide.net>
+
+The cx24109 datasheet says: "NOTE: if A=0, then N=N+1"
+
+The current code is the result of a misinterpretation of the datasheet to
+mean exactly the opposite of the requirement -- The actual value of N is 1
+greater than the value written when A is 0, so 1 needs to be *subtracted*
+from it to compensate.
+
+Signed-off-by: Yeasah Pell <yeasah@schwide.net>
+Signed-off-by: Steven Toth <stoth@hauppauge.com>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/dvb/frontends/cx24123.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/drivers/media/dvb/frontends/cx24123.c
++++ linux-2.6.18/drivers/media/dvb/frontends/cx24123.c
+@@ -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;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:30 2006
+Message-Id: <20061011204830.407704508@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:03 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>,
+ Mike Isely <isely@pobox.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 07/67] Video: pvrusb2: Solve mutex deadlock
+Content-Disposition: inline; filename=video-pvrusb2-solve-mutex-deadlock.patch
+Status: RO
+Content-Length: 5633
+Lines: 140
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Mike Isely <isely@pobox.com>
+
+There is a mutex ordering problem between the pvrusb2 driver and the
+v4l core.  Two different pathways take mutexes in opposing orders and
+this (under rare circumstances) can cause a deadlock.  The two mutexes
+in question are videodev_lock in the v4l core and device_lock inside
+the pvrusb2 driver.  The device_lock instance in the driver protects a
+private global array of context pointers which had been implemented in
+advance of v4l core changes which eliminate the video_set_drvdata()
+and video_get_drvdata() functions.
+
+This patch restores the use of video_get_drvdata() and
+video_set_drvdata(), eliminating the need for the array and the mutex.
+(This is actually a patch to restore the previous implementation.)  We
+can do this for 2.6.18 since those functions are in fact still
+present.  A better (and larger) solution will be done for later
+kernels.
+
+Signed-off-by: Mike Isely <isely@pobox.com>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
++++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+@@ -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"
+@@ -35,21 +36,11 @@ 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;
+ };
+@@ -703,12 +694,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 +785,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];
+-              }
++              struct video_device *vdev = video_devdata(file);
++              dip = (struct pvr2_v4l2_dev *)video_get_drvdata(vdev);
+       }
+-      mutex_unlock(&device_lock);
+       if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
+@@ -1066,7 +1028,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 +1043,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 +1056,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);
+
+_______________________________________________
+stable mailing list
+stable@linux.kernel.org
+http://linux.kernel.org/mailman/listinfo/stable
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:30 2006
+Message-Id: <20061011204830.550521847@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:04 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>,
+ Mike Isely <isely@pobox.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 08/67] Video: pvrusb2: improve 24XXX config option description
+Content-Disposition: inline; filename=video-pvrusb2-improve-24xxx-config-option-description.patch
+Status: RO
+Content-Length: 1292
+Lines: 34
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Mike Isely <isely@pobox.com>
+
+The CONFIG_VIDEO_PVRUSB2_24XXX is not nearly as "experimental" as the
+description suggests.  So refine the description to better match reality.
+
+Signed-off-by: Mike Isely <isely@pobox.com>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/pvrusb2/Kconfig |    9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- linux-2.6.18.orig/drivers/media/video/pvrusb2/Kconfig
++++ linux-2.6.18/drivers/media/video/pvrusb2/Kconfig
+@@ -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)"
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:30 2006
+Message-Id: <20061011204830.689702727@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:05 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>,
+ Mike Isely <isely@pobox.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 09/67] Video: pvrusb2: Suppress compiler warning
+Content-Disposition: inline; filename=video-pvrusb2-suppress-compiler-warning.patch
+Status: RO
+Content-Length: 1763
+Lines: 40
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Mike Isely <isely@pobox.com>
+
+The pvrusb2 driver needs to call video_devdata() in order to correctly
+transform a file pointer into a video_device pointer.  Unfortunately
+the prototype for this function has been marked V4L1-only and there's
+no official substitute that I can find for V4L2.  Adding to the
+mystery is that the implementation for this function exists whether or
+not V4L1 compatibility has been selected.  The upshot of all this is
+that we get a compilation warning here about a missing prototype but
+the code links OK.  This fix solves the warning by copying the
+prototype into the source file that is using it.  Yes this is a hack,
+but it's a safe one for 2.6.18 (any alternative would be much more
+intrusive).  A better solution should be forthcoming for the next
+kernel.
+
+Signed-off-by: Mike Isely <isely@pobox.com>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/pvrusb2/pvrusb2-v4l2.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+@@ -32,6 +32,12 @@
+ #include <linux/videodev2.h>
+ #include <media/v4l2-common.h>
++/* Mike Isely <isely@pobox.com> 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;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:30 2006
+Message-Id: <20061011204830.831929616@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:06 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ v4l-dvb maintainer list <v4l-dvb-maintainer@linuxtv.org>,
+ Mike Isely <isely@pobox.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 10/67] Video: pvrusb2: Limit hor res for 24xxx devices
+Content-Disposition: inline; filename=video-pvrusb2-limit-hor-res-for-24xxx-devices.patch
+Status: RO
+Content-Length: 6666
+Lines: 182
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Mike Isely <isely@pobox.com>
+
+Currently it is not understood how to properly control the horizontal
+capture resolution on 24xxx devices.  The pvrusb2 driver is doing
+everything it should (pass resolution paramter(s) to cx2341x and
+cx25840 modules) but for some reason the result is corrupted video if
+any resolution other than 720 is used.  This patch causes the driver
+to only permit a horizontal resolution of 720 to be used on 24xxx
+devices.  Even if the app requests something else, the driver will
+force the resolution back to 720.  This patch still allows full
+control of the resolution for 29xxx devices.
+
+Signed-off-by: Mike Isely <isely@pobox.com>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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         |   34 +++++++++++----------
+ 4 files changed, 65 insertions(+), 22 deletions(-)
+
+--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+@@ -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);
+--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+@@ -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 */
+--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-hdw.c
++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+@@ -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",
+--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+@@ -456,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;
++                      hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES);
++                      vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES);
+-                      if (h < 200) {
+-                              h = 200;
+-                      } else if (h > 625) {
+-                              h = 625;
++                      lmin = pvr2_ctrl_get_min(hcp);
++                      lmax = pvr2_ctrl_get_max(hcp);
++                      if (w < lmin) {
++                              w = lmin;
++                      } else if (w > lmax) {
++                              w = lmax;
+                       }
+-                      if (w < 320) {
+-                              w = 320;
+-                      } else if (w > 720) {
+-                              w = 720;
++                      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],
+@@ -476,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:
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:31 2006
+Message-Id: <20061011204830.971722680@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:07 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Daniel Drake <dsd@gentoo.org>,
+ "John W. Linville" <linville@tuxdriver.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 11/67] zd1211rw: ZD1211B ASIC/FWT, not jointly decoder
+Content-Disposition: inline; filename=zd1211rw-zd1211b-asic-fwt-not-jointly-decoder.patch
+Status: RO
+Content-Length: 1092
+Lines: 26
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Daniel Drake <dsd@gentoo.org>
+
+The vendor driver chooses this value based on an ifndef ASIC,
+and ASIC is never defined.
+
+Signed-off-by: Daniel Drake <dsd@gentoo.org>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/zd1211rw/zd_chip.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/drivers/net/wireless/zd1211rw/zd_chip.c
++++ linux-2.6.18/drivers/net/wireless/zd1211rw/zd_chip.c
+@@ -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 },
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:31 2006
+Message-Id: <20061011204831.111811660@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:08 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ gregkh@suse.de,
+ bunk@stusta.de
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Martin Schwidefsky <schwidefsky@de.ibm.com>
+Subject: [patch 12/67] S390: user readable uninitialised kernel memory (CVE-2006-5174)
+Content-Disposition: inline; filename=s390-user-readable-uninitialised-kernel-memory.patch
+Status: RO
+Content-Length: 1793
+Lines: 62
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+[S390] user readable uninitialised kernel memory.
+
+A user space program can read uninitialised kernel memory
+by appending to a file from a bad address and then reading
+the result back. The cause is the copy_from_user function
+that does not clear the remaining bytes of the kernel
+buffer after it got a fault on the user space address.
+
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/s390/lib/uaccess.S   |   12 +++++++++++-
+ arch/s390/lib/uaccess64.S |   12 +++++++++++-
+ 2 files changed, 22 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/arch/s390/lib/uaccess.S
++++ linux-2.6.18/arch/s390/lib/uaccess.S
+@@ -40,7 +40,17 @@ __copy_from_user_asm:
+       # 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:    lgr     %r5,%r3         # copy remaining size
++      ahi     %r5,-1          # subtract 1 for xc loop
++      bras    %r4,8f
++      xc      0(1,%2),0(%2)
++7:    xc      0(256,%2),0(%2)
++      la      %r2,256(%r2)
++8:    ahji    %r5,-256
++      jnm     7b
++      ex      %r5,0(%r2)
++9:    lr      %r2,%r3
+       br      %r14
+         .section __ex_table,"a"
+       .long   0b,4b
+--- linux-2.6.18.orig/arch/s390/lib/uaccess64.S
++++ linux-2.6.18/arch/s390/lib/uaccess64.S
+@@ -40,7 +40,17 @@ __copy_from_user_asm:
+       # 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(%r2)
++9:    lgr     %r2,%r3
+       br      %r14
+         .section __ex_table,"a"
+       .quad   0b,4b
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:31 2006
+Message-Id: <20061011204831.268686965@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:09 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Jack Morgenstein <jackm@dev.mellanox.co.il>,
+ "Michael S. Tsirkin" <mst@mellanox.co.il>,
+ Roland Dreier <rolandd@cisco.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 13/67] IB/mthca: Fix lid used for sending traps
+Content-Disposition: inline; filename=ib-mthca-fix-lid-used-for-sending-traps.patch
+Status: RO
+Content-Length: 1338
+Lines: 33
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jack Morgenstein <jackm@dev.mellanox.co.il>
+
+The SM LID used to send traps to is incorrectly set to port LID.  This
+is a regression from 2.6.17 -- after a PortInfo MAD is received, no
+traps are sent to the SM LID.  The traps go to the loopback interface
+instead, and are dropped there.  The SM LID should be taken from the
+sm_lid of the PortInfo response.
+
+The bug was introduced by commit 12bbb2b7be7f5564952ebe0196623e97464b8ac5:
+       IB/mthca: Add client reregister event generation
+
+Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
+Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
+Signed-off-by: Roland Dreier <rolandd@cisco.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/infiniband/hw/mthca/mthca_mad.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/drivers/infiniband/hw/mthca/mthca_mad.c
++++ linux-2.6.18/drivers/infiniband/hw/mthca/mthca_mad.c
+@@ -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;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:31 2006
+Message-Id: <20061011204831.409966090@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:10 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Tony Lindgren <tony@atomide.com>,
+ David Brownell <david-b@pacbell.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 14/67] USB: Allow compile in g_ether, fix typo
+Content-Disposition: inline; filename=usb-allow-compile-in-g_ether-fix-typo.patch
+Status: RO
+Content-Length: 966
+Lines: 34
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Tony Lindgren <tony@atomide.com>
+
+Allows compiling g_ether in and fixes a typo with MUSB_HDRC
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/ether.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/drivers/usb/gadget/ether.c
++++ linux-2.6.18/drivers/usb/gadget/ether.c
+@@ -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,
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:31 2006
+Message-Id: <20061011204831.550566605@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:11 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Takashi Iwai <tiwai@suse.de>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 15/67] ALSA: Fix initiailization of user-space controls
+Content-Disposition: inline; filename=alsa-fix-initiailization-of-user-space-controls.patch
+Status: RO
+Content-Length: 891
+Lines: 28
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Takashi Iwai <tiwai@suse.de>
+
+ALSA: Fix initiailization of user-space controls
+
+Fix an assertion when accessing a user-defined control due to lack of
+initialization (appears only when CONFIG_SND_DEBUg is enabled).
+
+  ALSA sound/core/control.c:660: BUG? (info->access == 0)
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/core/control.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- linux-2.6.18.orig/sound/core/control.c
++++ linux-2.6.18/sound/core/control.c
+@@ -997,6 +997,7 @@ static int snd_ctl_elem_add(struct snd_c
+       if (ue == NULL)
+               return -ENOMEM;
+       ue->info = *info;
++      ue->info.access = 0;
+       ue->elem_data = (char *)ue + sizeof(*ue);
+       ue->elem_data_size = private_size;
+       kctl.private_free = snd_ctl_elem_user_free;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:31 2006
+Message-Id: <20061011204831.692554244@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:12 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ mm-commits@vger.kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ pbadari@us.ibm.com,
+ jack@suse.cz,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 16/67] jbd: fix commit of ordered data buffers
+Content-Disposition: inline; filename=jbd-fix-commit-of-ordered-data-buffers.patch
+Status: RO
+Content-Length: 7169
+Lines: 233
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jan Kara <jack@suse.cz>
+
+Original commit code assumes, that when a buffer on BJ_SyncData list is
+locked, it is being written to disk.  But this is not true and hence it can
+lead to a potential data loss on crash.  Also the code didn't count with
+the fact that journal_dirty_data() can steal buffers from committing
+transaction and hence could write buffers that no longer belong to the
+committing transaction.  Finally it could possibly happen that we tried
+writing out one buffer several times.
+
+The patch below tries to solve these problems by a complete rewrite of the
+data commit code.  We go through buffers on t_sync_datalist, lock buffers
+needing write out and store them in an array.  Buffers are also immediately
+refiled to BJ_Locked list or unfiled (if the write out is completed).  When
+the array is full or we have to block on buffer lock, we submit all
+accumulated buffers for IO.
+
+[suitable for 2.6.18.x around the 2.6.19-rc2 timeframe]
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Cc: Badari Pulavarty <pbadari@us.ibm.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/jbd/commit.c |  182 ++++++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 113 insertions(+), 69 deletions(-)
+
+--- linux-2.6.18.orig/fs/jbd/commit.c
++++ linux-2.6.18/fs/jbd/commit.c
+@@ -160,6 +160,117 @@ static int journal_write_commit_record(j
+       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);
++}
++
+ /*
+  * journal_commit_transaction
+  *
+@@ -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();
+-      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);
+-      }
++      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_locked_list) {
+               struct buffer_head *bh;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:31 2006
+Message-Id: <20061011204831.830845262@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:13 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ nickpiggin@yahoo.com.au,
+ suresh.b.siddha@intel.com,
+ Christoph Lameter <clameter@sgi.com>,
+ John Hawkes <hawkes@sgi.com>,
+ Ingo Molnar <mingo@elte.hu>,
+ Peter Williams <pwil3058@bigpond.net.au>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 17/67] Fix longstanding load balancing bug in the scheduler
+Content-Disposition: inline; filename=fix-longstanding-load-balancing-bug-in-the-scheduler.patch
+Status: RO
+Content-Length: 6738
+Lines: 207
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Christoph Lameter <christoph@sgi.com>
+
+The scheduler will stop load balancing if the most busy processor contains
+processes pinned via processor affinity.
+
+The scheduler currently only does one search for busiest cpu.  If it cannot
+pull any tasks away from the busiest cpu because they were pinned then the
+scheduler goes into a corner and sulks leaving the idle processors idle.
+
+F.e.  If you have processor 0 busy running four tasks pinned via taskset,
+there are none on processor 1 and one just started two processes on
+processor 2 then the scheduler will not move one of the two processes away
+from processor 2.
+
+This patch fixes that issue by forcing the scheduler to come out of its
+corner and retrying the load balancing by considering other processors for
+load balancing.
+
+This patch was originally developed by John Hawkes and discussed at
+http://marc.theaimsgroup.com/?l=linux-kernel&m=113901368523205&w=2.
+
+I have removed extraneous material and gone back to equipping struct rq
+with the cpu the queue is associated with since this makes the patch much
+easier and it is likely that others in the future will have the same
+difficulty of figuring out which processor owns which runqueue.
+
+The overhead added through these patches is a single word on the stack if
+the kernel is configured to support 32 cpus or less (32 bit).  For 32 bit
+environments the maximum number of cpus that can be configued is 255 which
+would result in the use of 32 bytes additional on the stack.  On IA64 up to
+1k cpus can be configured which will result in the use of 128 additional
+bytes on the stack.  The maximum additional cache footprint is one
+cacheline.  Typically memory use will be much less than a cacheline and the
+additional cpumask will be placed on the stack in a cacheline that already
+contains other local variable.
+
+
+Signed-off-by: Christoph Lameter <clameter@sgi.com>
+Cc: John Hawkes <hawkes@sgi.com>
+Cc: Suresh Siddha <suresh.b.siddha@intel.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Nick Piggin <nickpiggin@yahoo.com.au>
+Cc: Peter Williams <pwil3058@bigpond.net.au>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/sched.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 46 insertions(+), 8 deletions(-)
+
+--- linux-2.6.18.orig/kernel/sched.c
++++ linux-2.6.18/kernel/sched.c
+@@ -238,6 +238,7 @@ struct rq {
+       /* For active balancing */
+       int active_balance;
+       int push_cpu;
++      int cpu;                /* cpu of this runqueue */
+       struct task_struct *migration_thread;
+       struct list_head migration_queue;
+@@ -267,6 +268,15 @@ struct rq {
+ static DEFINE_PER_CPU(struct rq, runqueues);
++static inline int cpu_of(struct rq *rq)
++{
++#ifdef CONFIG_SMP
++      return rq->cpu;
++#else
++      return 0;
++#endif
++}
++
+ /*
+  * The domain tree (rq->sd) is protected by RCU's quiescent state transition.
+  * See detach_destroy_domains: synchronize_sched for details.
+@@ -2211,7 +2221,8 @@ out:
+  */
+ static struct sched_group *
+ find_busiest_group(struct sched_domain *sd, int this_cpu,
+-                 unsigned long *imbalance, enum idle_type idle, int *sd_idle)
++                 unsigned long *imbalance, enum idle_type idle, int *sd_idle,
++                 cpumask_t *cpus)
+ {
+       struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups;
+       unsigned long max_load, avg_load, total_load, this_load, total_pwr;
+@@ -2248,7 +2259,12 @@ find_busiest_group(struct sched_domain *
+               sum_weighted_load = sum_nr_running = avg_load = 0;
+               for_each_cpu_mask(i, group->cpumask) {
+-                      struct rq *rq = cpu_rq(i);
++                      struct rq *rq;
++
++                      if (!cpu_isset(i, *cpus))
++                              continue;
++
++                      rq = cpu_rq(i);
+                       if (*sd_idle && !idle_cpu(i))
+                               *sd_idle = 0;
+@@ -2466,13 +2482,17 @@ ret:
+  */
+ static struct rq *
+ find_busiest_queue(struct sched_group *group, enum idle_type idle,
+-                 unsigned long imbalance)
++                 unsigned long imbalance, cpumask_t *cpus)
+ {
+       struct rq *busiest = NULL, *rq;
+       unsigned long max_load = 0;
+       int i;
+       for_each_cpu_mask(i, group->cpumask) {
++
++              if (!cpu_isset(i, *cpus))
++                      continue;
++
+               rq = cpu_rq(i);
+               if (rq->nr_running == 1 && rq->raw_weighted_load > imbalance)
+@@ -2511,6 +2531,7 @@ static int load_balance(int this_cpu, st
+       struct sched_group *group;
+       unsigned long imbalance;
+       struct rq *busiest;
++      cpumask_t cpus = CPU_MASK_ALL;
+       if (idle != NOT_IDLE && sd->flags & SD_SHARE_CPUPOWER &&
+           !sched_smt_power_savings)
+@@ -2518,13 +2539,15 @@ static int load_balance(int this_cpu, st
+       schedstat_inc(sd, lb_cnt[idle]);
+-      group = find_busiest_group(sd, this_cpu, &imbalance, idle, &sd_idle);
++redo:
++      group = find_busiest_group(sd, this_cpu, &imbalance, idle, &sd_idle,
++                                                      &cpus);
+       if (!group) {
+               schedstat_inc(sd, lb_nobusyg[idle]);
+               goto out_balanced;
+       }
+-      busiest = find_busiest_queue(group, idle, imbalance);
++      busiest = find_busiest_queue(group, idle, imbalance, &cpus);
+       if (!busiest) {
+               schedstat_inc(sd, lb_nobusyq[idle]);
+               goto out_balanced;
+@@ -2549,8 +2572,12 @@ static int load_balance(int this_cpu, st
+               double_rq_unlock(this_rq, busiest);
+               /* All tasks on this runqueue were pinned by CPU affinity */
+-              if (unlikely(all_pinned))
++              if (unlikely(all_pinned)) {
++                      cpu_clear(cpu_of(busiest), cpus);
++                      if (!cpus_empty(cpus))
++                              goto redo;
+                       goto out_balanced;
++              }
+       }
+       if (!nr_moved) {
+@@ -2639,18 +2666,22 @@ load_balance_newidle(int this_cpu, struc
+       unsigned long imbalance;
+       int nr_moved = 0;
+       int sd_idle = 0;
++      cpumask_t cpus = CPU_MASK_ALL;
+       if (sd->flags & SD_SHARE_CPUPOWER && !sched_smt_power_savings)
+               sd_idle = 1;
+       schedstat_inc(sd, lb_cnt[NEWLY_IDLE]);
+-      group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE, &sd_idle);
++redo:
++      group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE,
++                              &sd_idle, &cpus);
+       if (!group) {
+               schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]);
+               goto out_balanced;
+       }
+-      busiest = find_busiest_queue(group, NEWLY_IDLE, imbalance);
++      busiest = find_busiest_queue(group, NEWLY_IDLE, imbalance,
++                              &cpus);
+       if (!busiest) {
+               schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]);
+               goto out_balanced;
+@@ -2668,6 +2699,12 @@ load_balance_newidle(int this_cpu, struc
+                                       minus_1_or_zero(busiest->nr_running),
+                                       imbalance, sd, NEWLY_IDLE, NULL);
+               spin_unlock(&busiest->lock);
++
++              if (!nr_moved) {
++                      cpu_clear(cpu_of(busiest), cpus);
++                      if (!cpus_empty(cpus))
++                              goto redo;
++              }
+       }
+       if (!nr_moved) {
+@@ -6747,6 +6784,7 @@ void __init sched_init(void)
+                       rq->cpu_load[j] = 0;
+               rq->active_balance = 0;
+               rq->push_cpu = 0;
++              rq->cpu = i;
+               rq->migration_thread = NULL;
+               INIT_LIST_HEAD(&rq->migration_queue);
+ #endif
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:32 2006
+Message-Id: <20061011204831.974284972@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:14 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Christoph Lameter <clameter@sgi.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 18/67] zone_reclaim: dynamic slab reclaim
+Content-Disposition: inline; filename=zone_reclaim-dynamic-slab-reclaim.patch
+Status: RO
+Content-Length: 11401
+Lines: 310
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Christoph Lameter <clameter@sgi.com>
+
+http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=0ff38490c836dc379ff7ec45b10a15a662f4e5f6
+
+
+Currently one can enable slab reclaim by setting an explicit option in
+/proc/sys/vm/zone_reclaim_mode.  Slab reclaim is then used as a final
+option if the freeing of unmapped file backed pages is not enough to free
+enough pages to allow a local allocation.
+
+However, that means that the slab can grow excessively and that most memory
+of a node may be used by slabs.  We have had a case where a machine with
+46GB of memory was using 40-42GB for slab.  Zone reclaim was effective in
+dealing with pagecache pages.  However, slab reclaim was only done during
+global reclaim (which is a bit rare on NUMA systems).
+
+This patch implements slab reclaim during zone reclaim.  Zone reclaim
+occurs if there is a danger of an off node allocation.  At that point we
+
+1. Shrink the per node page cache if the number of pagecache
+   pages is more than min_unmapped_ratio percent of pages in a zone.
+
+2. Shrink the slab cache if the number of the nodes reclaimable slab pages
+   (patch depends on earlier one that implements that counter)
+   are more than min_slab_ratio (a new /proc/sys/vm tunable).
+
+The shrinking of the slab cache is a bit problematic since it is not node
+specific.  So we simply calculate what point in the slab we want to reach
+(current per node slab use minus the number of pages that neeed to be
+allocated) and then repeately run the global reclaim until that is
+unsuccessful or we have reached the limit.  I hope we will have zone based
+slab reclaim at some point which will make that easier.
+
+The default for the min_slab_ratio is 5%
+
+Also remove the slab option from /proc/sys/vm/zone_reclaim_mode.
+
+[akpm@osdl.org: cleanups]
+Signed-off-by: Christoph Lameter <clameter@sgi.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/sysctl/vm.txt |   27 +++++++++++++++-----
+ include/linux/mmzone.h      |    3 ++
+ include/linux/swap.h        |    1 
+ include/linux/sysctl.h      |    1 
+ kernel/sysctl.c             |   11 ++++++++
+ mm/page_alloc.c             |   17 ++++++++++++
+ mm/vmscan.c                 |   58 ++++++++++++++++++++++++++++----------------
+ 7 files changed, 90 insertions(+), 28 deletions(-)
+
+--- linux-2.6.18.orig/Documentation/sysctl/vm.txt
++++ linux-2.6.18/Documentation/sysctl/vm.txt
+@@ -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 @@ This is value ORed together of
+ 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,18 +162,13 @@ Allowing regular swap effectively restri
+ 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.
+@@ -182,6 +177,24 @@ 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.
++
++=============================================================
++
+ panic_on_oom
+ This enables or disables panic on out-of-memory feature.  If this is set to 1,
+--- linux-2.6.18.orig/include/linux/mmzone.h
++++ linux-2.6.18/include/linux/mmzone.h
+@@ -155,6 +155,7 @@ struct zone {
+        * zone reclaim becomes active if more unmapped pages exist.
+        */
+       unsigned long           min_unmapped_ratio;
++      unsigned long           min_slab_pages;
+       struct per_cpu_pageset  *pageset[NR_CPUS];
+ #else
+       struct per_cpu_pageset  pageset[NR_CPUS];
+@@ -421,6 +422,8 @@ int percpu_pagelist_fraction_sysctl_hand
+                                       void __user *, size_t *, loff_t *);
+ int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *, int,
+                       struct file *, void __user *, size_t *, loff_t *);
++int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *, int,
++                      struct file *, void __user *, size_t *, loff_t *);
+ #include <linux/topology.h>
+ /* Returns the number of the current Node. */
+--- linux-2.6.18.orig/include/linux/swap.h
++++ linux-2.6.18/include/linux/swap.h
+@@ -190,6 +190,7 @@ extern long vm_total_pages;
+ #ifdef CONFIG_NUMA
+ extern int zone_reclaim_mode;
+ extern int sysctl_min_unmapped_ratio;
++extern int sysctl_min_slab_ratio;
+ extern int zone_reclaim(struct zone *, gfp_t, unsigned int);
+ #else
+ #define zone_reclaim_mode 0
+--- linux-2.6.18.orig/include/linux/sysctl.h
++++ linux-2.6.18/include/linux/sysctl.h
+@@ -191,6 +191,7 @@ enum
+       VM_MIN_UNMAPPED=32,     /* Set min percent of unmapped pages */
+       VM_PANIC_ON_OOM=33,     /* panic at out-of-memory */
+       VM_VDSO_ENABLED=34,     /* map VDSO into new processes? */
++      VM_MIN_SLAB=35,          /* Percent pages ignored by zone reclaim */
+ };
+--- linux-2.6.18.orig/kernel/sysctl.c
++++ linux-2.6.18/kernel/sysctl.c
+@@ -943,6 +943,17 @@ static ctl_table vm_table[] = {
+               .extra1         = &zero,
+               .extra2         = &one_hundred,
+       },
++      {
++              .ctl_name       = VM_MIN_SLAB,
++              .procname       = "min_slab_ratio",
++              .data           = &sysctl_min_slab_ratio,
++              .maxlen         = sizeof(sysctl_min_slab_ratio),
++              .mode           = 0644,
++              .proc_handler   = &sysctl_min_slab_ratio_sysctl_handler,
++              .strategy       = &sysctl_intvec,
++              .extra1         = &zero,
++              .extra2         = &one_hundred,
++      },
+ #endif
+ #ifdef CONFIG_X86_32
+       {
+--- linux-2.6.18.orig/mm/page_alloc.c
++++ linux-2.6.18/mm/page_alloc.c
+@@ -2008,6 +2008,7 @@ static void __meminit free_area_init_cor
+ #ifdef CONFIG_NUMA
+               zone->min_unmapped_ratio = (realsize*sysctl_min_unmapped_ratio)
+                                               / 100;
++              zone->min_slab_pages = (realsize * sysctl_min_slab_ratio) / 100;
+ #endif
+               zone->name = zone_names[j];
+               spin_lock_init(&zone->lock);
+@@ -2318,6 +2319,22 @@ int sysctl_min_unmapped_ratio_sysctl_han
+                               sysctl_min_unmapped_ratio) / 100;
+       return 0;
+ }
++
++int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write,
++      struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
++{
++      struct zone *zone;
++      int rc;
++
++      rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
++      if (rc)
++              return rc;
++
++      for_each_zone(zone)
++              zone->min_slab_pages = (zone->present_pages *
++                              sysctl_min_slab_ratio) / 100;
++      return 0;
++}
+ #endif
+ /*
+--- linux-2.6.18.orig/mm/vmscan.c
++++ linux-2.6.18/mm/vmscan.c
+@@ -1510,7 +1510,6 @@ int zone_reclaim_mode __read_mostly;
+ #define RECLAIM_ZONE (1<<0)   /* Run shrink_cache on the zone */
+ #define RECLAIM_WRITE (1<<1)  /* Writeout pages during reclaim */
+ #define RECLAIM_SWAP (1<<2)   /* Swap pages out during reclaim */
+-#define RECLAIM_SLAB (1<<3)   /* Do a global slab shrink if the zone is out of memory */
+ /*
+  * Priority for ZONE_RECLAIM. This determines the fraction of pages
+@@ -1526,6 +1525,12 @@ int zone_reclaim_mode __read_mostly;
+ int sysctl_min_unmapped_ratio = 1;
+ /*
++ * If the number of slab pages in a zone grows beyond this percentage then
++ * slab reclaim needs to occur.
++ */
++int sysctl_min_slab_ratio = 5;
++
++/*
+  * Try to free up some pages from this zone through reclaim.
+  */
+ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
+@@ -1556,29 +1561,37 @@ static int __zone_reclaim(struct zone *z
+       reclaim_state.reclaimed_slab = 0;
+       p->reclaim_state = &reclaim_state;
+-      /*
+-       * Free memory by calling shrink zone with increasing priorities
+-       * until we have enough memory freed.
+-       */
+-      priority = ZONE_RECLAIM_PRIORITY;
+-      do {
+-              nr_reclaimed += shrink_zone(priority, zone, &sc);
+-              priority--;
+-      } while (priority >= 0 && nr_reclaimed < nr_pages);
++      if (zone_page_state(zone, NR_FILE_PAGES) -
++              zone_page_state(zone, NR_FILE_MAPPED) >
++              zone->min_unmapped_ratio) {
++              /*
++               * Free memory by calling shrink zone with increasing
++               * priorities until we have enough memory freed.
++               */
++              priority = ZONE_RECLAIM_PRIORITY;
++              do {
++                      nr_reclaimed += shrink_zone(priority, zone, &sc);
++                      priority--;
++              } while (priority >= 0 && nr_reclaimed < nr_pages);
++      }
+-      if (nr_reclaimed < nr_pages && (zone_reclaim_mode & RECLAIM_SLAB)) {
++      if (zone_page_state(zone, NR_SLAB) > zone->min_slab_pages) {
+               /*
+                * shrink_slab() does not currently allow us to determine how
+-               * many pages were freed in this zone. So we just shake the slab
+-               * a bit and then go off node for this particular allocation
+-               * despite possibly having freed enough memory to allocate in
+-               * this zone.  If we freed local memory then the next
+-               * allocations will be local again.
++               * many pages were freed in this zone. So we take the current
++               * number of slab pages and shake the slab until it is reduced
++               * by the same nr_pages that we used for reclaiming unmapped
++               * pages.
+                *
+-               * shrink_slab will free memory on all zones and may take
+-               * a long time.
++               * Note that shrink_slab will free memory on all zones and may
++               * take a long time.
+                */
+-              shrink_slab(sc.nr_scanned, gfp_mask, order);
++              unsigned long limit = zone_page_state(zone,
++                              NR_SLAB) - nr_pages;
++
++              while (shrink_slab(sc.nr_scanned, gfp_mask, order) &&
++                      zone_page_state(zone, NR_SLAB) > limit)
++                      ;
+       }
+       p->reclaim_state = NULL;
+@@ -1592,7 +1605,8 @@ int zone_reclaim(struct zone *zone, gfp_
+       int node_id;
+       /*
+-       * Zone reclaim reclaims unmapped file backed pages.
++       * Zone reclaim reclaims unmapped file backed pages and
++       * slab pages if we are over the defined limits.
+        *
+        * A small portion of unmapped file backed pages is needed for
+        * file I/O otherwise pages read by file I/O will be immediately
+@@ -1601,7 +1615,9 @@ int zone_reclaim(struct zone *zone, gfp_
+        * unmapped file backed pages.
+        */
+       if (zone_page_state(zone, NR_FILE_PAGES) -
+-          zone_page_state(zone, NR_FILE_MAPPED) <= zone->min_unmapped_ratio)
++          zone_page_state(zone, NR_FILE_MAPPED) <= zone->min_unmapped_ratio
++          && zone_page_state(zone, NR_SLAB)
++                      <= zone->min_slab_pages)
+               return 0;
+       /*
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:32 2006
+Message-Id: <20061011204832.119108936@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:15 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Jeff Garzik <jeff@garzik.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 19/67] mv643xx_eth: fix obvious typo, which caused build breakage
+Content-Disposition: inline; filename=mv643xx_eth-fix-obvious-typo-which-caused-build-breakage.patch
+Status: RO
+Content-Length: 910
+Lines: 28
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jeff Garzik <jeff@garzik.org>
+
+The last minute fix submitted by the author fixed a bug, but
+broke the driver build.
+
+Noticed by Al Viro, since I can't build on said platform.
+
+Signed-off-by: Jeff Garzik <jeff@garzik.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/net/mv643xx_eth.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/drivers/net/mv643xx_eth.c
++++ linux-2.6.18/drivers/net/mv643xx_eth.c
+@@ -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++;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:32 2006
+Message-Id: <20061011204832.262849711@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:16 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ git-commits-head@vger.kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Jeff Garzik <jeff@garzik.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 20/67] netdrvr: lp486e: fix typo
+Content-Disposition: inline; filename=netdrvr-lp486e-fix-typo.patch
+Status: RO
+Content-Length: 1011
+Lines: 37
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jeff Garzik <jeff@garzik.org>
+
+inside #if 0'd code, but it bugged me.
+
+Really, we should probably just delete the driver.
+
+Signed-off-by: Jeff Garzik <jeff@garzik.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/lp486e.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- linux-2.6.18.orig/drivers/net/lp486e.c
++++ linux-2.6.18/drivers/net/lp486e.c
+@@ -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;
+                       }
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:32 2006
+Message-Id: <20061011204832.408660426@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:17 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Stephen Hemminger <shemminger@osdl.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 21/67] sky2: tx pause bug fix
+Content-Disposition: inline; filename=sky2-tx-pause-bug-fix.patch
+Status: RO
+Content-Length: 1045
+Lines: 28
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Stephen Hemminger <shemminger@osdl.org>
+
+The sky2 driver will hang if transmit flow control is enabled
+and it receives a pause frame. The pause frame gets partially
+processed by hardware but never makes it through to the correct
+logic. This patch made it into 2.6.17 stable, but never got
+accepted for 2.6.18, so it will have to go into 2.6.18.1
+
+See also: http://bugzilla.kernel.org/show_bug.cgi?id=6839
+
+Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/sky2.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/drivers/net/sky2.h
++++ linux-2.6.18/drivers/net/sky2.h
+@@ -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_BAD_FC |
+                         GMR_FS_UN_SIZE | GMR_FS_JABBER,
+ };
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:32 2006
+Message-Id: <20061011204832.547653267@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:18 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ Andrew Morton <akpm@osdl.org>
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Jeff Garzik <jeff@garzik.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 22/67] sky2 network driver device ids
+Content-Disposition: inline; filename=sky2-network-driver-device-ids.patch
+Status: RO
+Content-Length: 1660
+Lines: 41
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Stephen Hemminger <shemminger@osdl.org>
+
+This makes the id table match the current netdev upstream tree.
+
+From: Stephen Hemminger <shemminger@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/sky2.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- linux-2.6.18.orig/drivers/net/sky2.c
++++ linux-2.6.18/drivers/net/sky2.c
+@@ -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 }
+ };
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:32 2006
+Message-Id: <20061011204832.692131048@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:19 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 23/67] One line per header in Kbuild files to reduce conflicts
+Content-Disposition: inline; filename=0001-HEADERS-One-line-per-header-in-Kbuild-files-to-reduce-conflicts.patch
+Status: RO
+Content-Length: 30815
+Lines: 1037
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/Kbuild                        |   11 
+ include/asm-alpha/Kbuild              |   10 
+ include/asm-generic/Kbuild            |   15 +
+ include/asm-generic/Kbuild.asm        |   38 ++-
+ include/asm-i386/Kbuild               |    9 
+ include/asm-ia64/Kbuild               |   18 +
+ include/asm-powerpc/Kbuild            |   45 +++
+ include/asm-s390/Kbuild               |   11 
+ include/asm-sparc/Kbuild              |   24 +-
+ include/asm-sparc64/Kbuild            |   27 +-
+ include/asm-x86_64/Kbuild             |   18 +
+ include/linux/Kbuild                  |  400 ++++++++++++++++++++++++++++------
+ include/linux/byteorder/Kbuild        |    9 
+ include/linux/dvb/Kbuild              |   11 
+ include/linux/netfilter/Kbuild        |   47 +++
+ include/linux/netfilter_arp/Kbuild    |    5 
+ include/linux/netfilter_bridge/Kbuild |   21 +
+ include/linux/netfilter_ipv4/Kbuild   |   82 +++++-
+ include/linux/netfilter_ipv6/Kbuild   |   27 +-
+ include/linux/nfsd/Kbuild             |    9 
+ include/linux/raid/Kbuild             |    3 
+ include/linux/sunrpc/Kbuild           |    2 
+ include/linux/tc_act/Kbuild           |    5 
+ include/linux/tc_ematch/Kbuild        |    5 
+ include/mtd/Kbuild                    |    8 
+ include/rdma/Kbuild                   |    2 
+ include/scsi/Kbuild                   |    4 
+ include/sound/Kbuild                  |   12 -
+ include/video/Kbuild                  |    2 
+ 29 files changed, 721 insertions(+), 159 deletions(-)
+
+--- linux-2.6.18.orig/include/Kbuild
++++ linux-2.6.18/include/Kbuild
+@@ -1,2 +1,9 @@
+-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)/
+--- linux-2.6.18.orig/include/asm-alpha/Kbuild
++++ linux-2.6.18/include/asm-alpha/Kbuild
+@@ -1,5 +1,11 @@
+ 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
+--- linux-2.6.18.orig/include/asm-generic/Kbuild
++++ linux-2.6.18/include/asm-generic/Kbuild
+@@ -1,3 +1,12 @@
+-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
+--- linux-2.6.18.orig/include/asm-generic/Kbuild.asm
++++ linux-2.6.18/include/asm-generic/Kbuild.asm
+@@ -1,8 +1,34 @@
+-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
+--- linux-2.6.18.orig/include/asm-i386/Kbuild
++++ linux-2.6.18/include/asm-i386/Kbuild
+@@ -1,5 +1,10 @@
+ include include/asm-generic/Kbuild.asm
+-header-y += boot.h debugreg.h ldt.h ucontext.h
++header-y += boot.h
++header-y += debugreg.h
++header-y += ldt.h
++header-y += ucontext.h
+-unifdef-y += mtrr.h setup.h vm86.h
++unifdef-y += mtrr.h
++unifdef-y += setup.h
++unifdef-y += vm86.h
+--- linux-2.6.18.orig/include/asm-ia64/Kbuild
++++ linux-2.6.18/include/asm-ia64/Kbuild
+@@ -1,7 +1,17 @@
+ include include/asm-generic/Kbuild.asm
+-header-y += break.h fpu.h fpswa.h gcc_intrin.h ia64regs.h             \
+-       intel_intrin.h intrinsics.h perfmon_default_smpl.h     \
+-       ptrace_offsets.h rse.h setup.h ucontext.h
++header-y += break.h
++header-y += fpu.h
++header-y += fpswa.h
++header-y += gcc_intrin.h
++header-y += ia64regs.h
++header-y += intel_intrin.h
++header-y += intrinsics.h
++header-y += perfmon_default_smpl.h
++header-y += ptrace_offsets.h
++header-y += rse.h
++header-y += setup.h
++header-y += ucontext.h
+-unifdef-y += perfmon.h ustack.h
++unifdef-y += perfmon.h
++unifdef-y += ustack.h
+--- linux-2.6.18.orig/include/asm-powerpc/Kbuild
++++ linux-2.6.18/include/asm-powerpc/Kbuild
+@@ -1,10 +1,41 @@
+ include include/asm-generic/Kbuild.asm
+-unifdef-y += a.out.h asm-compat.h bootx.h byteorder.h cputable.h elf.h        \
+-      nvram.h param.h posix_types.h ptrace.h seccomp.h signal.h       \
+-      termios.h types.h unistd.h
++header-y += auxvec.h
++header-y += ioctls.h
++header-y += mman.h
++header-y += sembuf.h
++header-y += siginfo.h
++header-y += stat.h
++header-y += errno.h
++header-y += ipcbuf.h
++header-y += msgbuf.h
++header-y += shmbuf.h
++header-y += socket.h
++header-y += termbits.h
++header-y += fcntl.h
++header-y += ipc.h
++header-y += poll.h
++header-y += shmparam.h
++header-y += sockios.h
++header-y += ucontext.h
++header-y += ioctl.h
++header-y += linkage.h
++header-y += resource.h
++header-y += sigcontext.h
++header-y += statfs.h
+-header-y += auxvec.h ioctls.h mman.h sembuf.h siginfo.h stat.h errno.h        \
+-      ipcbuf.h msgbuf.h shmbuf.h socket.h termbits.h fcntl.h ipc.h    \
+-      poll.h shmparam.h sockios.h ucontext.h ioctl.h linkage.h        \
+-      resource.h sigcontext.h statfs.h
++unifdef-y += a.out.h
++unifdef-y += asm-compat.h
++unifdef-y += bootx.h
++unifdef-y += byteorder.h
++unifdef-y += cputable.h
++unifdef-y += elf.h
++unifdef-y += nvram.h
++unifdef-y += param.h
++unifdef-y += posix_types.h
++unifdef-y += ptrace.h
++unifdef-y += seccomp.h
++unifdef-y += signal.h
++unifdef-y += termios.h
++unifdef-y += types.h
++unifdef-y += unistd.h
+--- linux-2.6.18.orig/include/asm-s390/Kbuild
++++ linux-2.6.18/include/asm-s390/Kbuild
+@@ -1,4 +1,11 @@
+ include include/asm-generic/Kbuild.asm
+-unifdef-y += cmb.h debug.h
+-header-y += dasd.h qeth.h tape390.h ucontext.h vtoc.h z90crypt.h
++header-y += dasd.h
++header-y += qeth.h
++header-y += tape390.h
++header-y += ucontext.h
++header-y += vtoc.h
++header-y += z90crypt.h
++
++unifdef-y += cmb.h
++unifdef-y += debug.h
+--- linux-2.6.18.orig/include/asm-sparc/Kbuild
++++ linux-2.6.18/include/asm-sparc/Kbuild
+@@ -1,6 +1,22 @@
+ include include/asm-generic/Kbuild.asm
+-unifdef-y += fbio.h perfctr.h psr.h
+-header-y += apc.h asi.h auxio.h bpp.h head.h ipc.h jsflash.h  \
+-      openpromio.h pbm.h pconf.h pgtsun4.h reg.h traps.h      \
+-      turbosparc.h vfc_ioctls.h winmacro.h
++header-y += apc.h
++header-y += asi.h
++header-y += auxio.h
++header-y += bpp.h
++header-y += head.h
++header-y += ipc.h
++header-y += jsflash.h
++header-y += openpromio.h
++header-y += pbm.h
++header-y += pconf.h
++header-y += pgtsun4.h
++header-y += reg.h
++header-y += traps.h
++header-y += turbosparc.h
++header-y += vfc_ioctls.h
++header-y += winmacro.h
++
++unifdef-y += fbio.h
++unifdef-y += perfctr.h
++unifdef-y += psr.h
+--- linux-2.6.18.orig/include/asm-sparc64/Kbuild
++++ linux-2.6.18/include/asm-sparc64/Kbuild
+@@ -4,7 +4,26 @@ ALTARCH := sparc
+ ARCHDEF := defined __sparc__ && defined __arch64__
+ ALTARCHDEF := defined __sparc__ && !defined __arch64__
+-unifdef-y += fbio.h perfctr.h
+-header-y += apb.h asi.h bbc.h bpp.h display7seg.h envctrl.h floppy.h  \
+-      ipc.h kdebug.h mostek.h openprom.h openpromio.h parport.h       \
+-      pconf.h psrcompat.h pstate.h reg.h uctx.h utrap.h watchdog.h
++header-y += apb.h
++header-y += asi.h
++header-y += bbc.h
++header-y += bpp.h
++header-y += display7seg.h
++header-y += envctrl.h
++header-y += floppy.h
++header-y += ipc.h
++header-y += kdebug.h
++header-y += mostek.h
++header-y += openprom.h
++header-y += openpromio.h
++header-y += parport.h
++header-y += pconf.h
++header-y += psrcompat.h
++header-y += pstate.h
++header-y += reg.h
++header-y += uctx.h
++header-y += utrap.h
++header-y += watchdog.h
++
++unifdef-y += fbio.h
++unifdef-y += perfctr.h
+--- linux-2.6.18.orig/include/asm-x86_64/Kbuild
++++ linux-2.6.18/include/asm-x86_64/Kbuild
+@@ -4,8 +4,18 @@ ALTARCH := i386
+ ARCHDEF := defined __x86_64__
+ ALTARCHDEF := defined __i386__
+-header-y += boot.h bootsetup.h cpufeature.h debugreg.h ldt.h \
+-       msr.h prctl.h setup.h sigcontext32.h ucontext.h \
+-       vsyscall32.h
++header-y += boot.h
++header-y += bootsetup.h
++header-y += cpufeature.h
++header-y += debugreg.h
++header-y += ldt.h
++header-y += msr.h
++header-y += prctl.h
++header-y += setup.h
++header-y += sigcontext32.h
++header-y += ucontext.h
++header-y += vsyscall32.h
+-unifdef-y += mce.h mtrr.h vsyscall.h
++unifdef-y += mce.h
++unifdef-y += mtrr.h
++unifdef-y += vsyscall.h
+--- linux-2.6.18.orig/include/linux/Kbuild
++++ linux-2.6.18/include/linux/Kbuild
+@@ -1,63 +1,343 @@
+-header-y := byteorder/ dvb/ hdlc/ isdn/ nfsd/ raid/ sunrpc/ tc_act/   \
+-      netfilter/ netfilter_arp/ netfilter_bridge/ netfilter_ipv4/     \
+-      netfilter_ipv6/
++header-y += byteorder/
++header-y += dvb/
++header-y += hdlc/
++header-y += isdn/
++header-y += nfsd/
++header-y += raid/
++header-y += sunrpc/
++header-y += tc_act/
++header-y += netfilter/
++header-y += netfilter_arp/
++header-y += netfilter_bridge/
++header-y += netfilter_ipv4/
++header-y += netfilter_ipv6/
+-header-y += affs_fs.h affs_hardblocks.h aio_abi.h a.out.h arcfb.h     \
+-      atmapi.h atmbr2684.h atmclip.h atm_eni.h atm_he.h               \
+-      atm_idt77105.h atmioc.h atmlec.h atmmpc.h atm_nicstar.h         \
+-      atmppp.h atmsap.h atmsvc.h atm_zatm.h auto_fs4.h auxvec.h       \
+-      awe_voice.h ax25.h b1lli.h baycom.h bfs_fs.h blkpg.h            \
+-      bpqether.h cdk.h chio.h coda_psdev.h coff.h comstats.h          \
+-      consolemap.h cycx_cfm.h dm-ioctl.h dn.h dqblk_v1.h              \
+-      dqblk_v2.h dqblk_xfs.h efs_fs_sb.h elf-fdpic.h elf.h elf-em.h   \
+-      fadvise.h fd.h fdreg.h ftape-header-segment.h ftape-vendors.h   \
+-      fuse.h futex.h genetlink.h gen_stats.h gigaset_dev.h hdsmart.h  \
+-      hpfs_fs.h hysdn_if.h i2c-dev.h i8k.h icmp.h                     \
+-      if_arcnet.h if_arp.h if_bonding.h if_cablemodem.h if_fc.h       \
+-      if_fddi.h if.h if_hippi.h if_infiniband.h if_packet.h           \
+-      if_plip.h if_ppp.h if_slip.h if_strip.h if_tunnel.h in6.h       \
+-      in_route.h ioctl.h ip.h ipmi_msgdefs.h ip_mp_alg.h ipsec.h      \
+-      ipx.h irda.h isdn_divertif.h iso_fs.h ite_gpio.h ixjuser.h      \
+-      jffs2.h keyctl.h limits.h major.h matroxfb.h meye.h minix_fs.h  \
+-      mmtimer.h mqueue.h mtio.h ncp_no.h netfilter_arp.h netrom.h     \
+-      nfs2.h nfs4_mount.h nfs_mount.h openprom_fs.h param.h           \
+-      pci_ids.h pci_regs.h personality.h pfkeyv2.h pg.h pkt_cls.h     \
+-      pkt_sched.h posix_types.h ppdev.h prctl.h ps2esdi.h qic117.h    \
+-      qnxtypes.h quotaio_v1.h quotaio_v2.h radeonfb.h raw.h           \
+-      resource.h rose.h sctp.h smbno.h snmp.h sockios.h som.h         \
+-      sound.h stddef.h synclink.h telephony.h termios.h ticable.h     \
+-      times.h tiocl.h tipc.h toshiba.h ultrasound.h un.h utime.h      \
+-      utsname.h video_decoder.h video_encoder.h videotext.h vt.h      \
+-      wavefront.h wireless.h xattr.h x25.h zorro_ids.h
++header-y += affs_fs.h
++header-y += affs_hardblocks.h
++header-y += aio_abi.h
++header-y += a.out.h
++header-y += arcfb.h
++header-y += atmapi.h
++header-y += atmbr2684.h
++header-y += atmclip.h
++header-y += atm_eni.h
++header-y += atm_he.h
++header-y += atm_idt77105.h
++header-y += atmioc.h
++header-y += atmlec.h
++header-y += atmmpc.h
++header-y += atm_nicstar.h
++header-y += atmppp.h
++header-y += atmsap.h
++header-y += atmsvc.h
++header-y += atm_zatm.h
++header-y += auto_fs4.h
++header-y += auxvec.h
++header-y += awe_voice.h
++header-y += ax25.h
++header-y += b1lli.h
++header-y += baycom.h
++header-y += bfs_fs.h
++header-y += blkpg.h
++header-y += bpqether.h
++header-y += cdk.h
++header-y += chio.h
++header-y += coda_psdev.h
++header-y += coff.h
++header-y += comstats.h
++header-y += consolemap.h
++header-y += cycx_cfm.h
++header-y += dm-ioctl.h
++header-y += dn.h
++header-y += dqblk_v1.h
++header-y += dqblk_v2.h
++header-y += dqblk_xfs.h
++header-y += efs_fs_sb.h
++header-y += elf-fdpic.h
++header-y += elf.h
++header-y += elf-em.h
++header-y += fadvise.h
++header-y += fd.h
++header-y += fdreg.h
++header-y += ftape-header-segment.h
++header-y += ftape-vendors.h
++header-y += fuse.h
++header-y += futex.h
++header-y += genetlink.h
++header-y += gen_stats.h
++header-y += gigaset_dev.h
++header-y += hdsmart.h
++header-y += hpfs_fs.h
++header-y += hysdn_if.h
++header-y += i2c-dev.h
++header-y += i8k.h
++header-y += icmp.h
++header-y += if_arcnet.h
++header-y += if_arp.h
++header-y += if_bonding.h
++header-y += if_cablemodem.h
++header-y += if_fc.h
++header-y += if_fddi.h
++header-y += if.h
++header-y += if_hippi.h
++header-y += if_infiniband.h
++header-y += if_packet.h
++header-y += if_plip.h
++header-y += if_ppp.h
++header-y += if_slip.h
++header-y += if_strip.h
++header-y += if_tunnel.h
++header-y += in6.h
++header-y += in_route.h
++header-y += ioctl.h
++header-y += ip.h
++header-y += ipmi_msgdefs.h
++header-y += ip_mp_alg.h
++header-y += ipsec.h
++header-y += ipx.h
++header-y += irda.h
++header-y += isdn_divertif.h
++header-y += iso_fs.h
++header-y += ite_gpio.h
++header-y += ixjuser.h
++header-y += jffs2.h
++header-y += keyctl.h
++header-y += limits.h
++header-y += major.h
++header-y += matroxfb.h
++header-y += meye.h
++header-y += minix_fs.h
++header-y += mmtimer.h
++header-y += mqueue.h
++header-y += mtio.h
++header-y += ncp_no.h
++header-y += netfilter_arp.h
++header-y += netrom.h
++header-y += nfs2.h
++header-y += nfs4_mount.h
++header-y += nfs_mount.h
++header-y += openprom_fs.h
++header-y += param.h
++header-y += pci_ids.h
++header-y += pci_regs.h
++header-y += personality.h
++header-y += pfkeyv2.h
++header-y += pg.h
++header-y += pkt_cls.h
++header-y += pkt_sched.h
++header-y += posix_types.h
++header-y += ppdev.h
++header-y += prctl.h
++header-y += ps2esdi.h
++header-y += qic117.h
++header-y += qnxtypes.h
++header-y += quotaio_v1.h
++header-y += quotaio_v2.h
++header-y += radeonfb.h
++header-y += raw.h
++header-y += resource.h
++header-y += rose.h
++header-y += sctp.h
++header-y += smbno.h
++header-y += snmp.h
++header-y += sockios.h
++header-y += som.h
++header-y += sound.h
++header-y += stddef.h
++header-y += synclink.h
++header-y += telephony.h
++header-y += termios.h
++header-y += ticable.h
++header-y += times.h
++header-y += tiocl.h
++header-y += tipc.h
++header-y += toshiba.h
++header-y += ultrasound.h
++header-y += un.h
++header-y += utime.h
++header-y += utsname.h
++header-y += video_decoder.h
++header-y += video_encoder.h
++header-y += videotext.h
++header-y += vt.h
++header-y += wavefront.h
++header-y += wireless.h
++header-y += xattr.h
++header-y += x25.h
++header-y += zorro_ids.h
+-unifdef-y += acct.h adb.h adfs_fs.h agpgart.h apm_bios.h atalk.h      \
+-      atmarp.h atmdev.h atm.h atm_tcp.h audit.h auto_fs.h binfmts.h   \
+-      capability.h capi.h cciss_ioctl.h cdrom.h cm4000_cs.h           \
+-      cn_proc.h coda.h connector.h cramfs_fs.h cuda.h cyclades.h      \
+-      dccp.h dirent.h divert.h elfcore.h errno.h errqueue.h           \
+-      ethtool.h eventpoll.h ext2_fs.h ext3_fs.h fb.h fcntl.h          \
+-      filter.h flat.h fs.h ftape.h gameport.h generic_serial.h        \
+-      genhd.h hayesesp.h hdlcdrv.h hdlc.h hdreg.h hiddev.h hpet.h     \
+-      i2c.h i2o-dev.h icmpv6.h if_bridge.h if_ec.h                    \
+-      if_eql.h if_ether.h if_frad.h if_ltalk.h if_pppox.h             \
+-      if_shaper.h if_tr.h if_tun.h if_vlan.h if_wanpipe.h igmp.h      \
+-      inet_diag.h in.h inotify.h input.h ipc.h ipmi.h ipv6.h          \
+-      ipv6_route.h isdn.h isdnif.h isdn_ppp.h isicom.h jbd.h          \
+-      joystick.h kdev_t.h kd.h kernelcapi.h kernel.h keyboard.h       \
+-      llc.h loop.h lp.h mempolicy.h mii.h mman.h mroute.h msdos_fs.h  \
+-      msg.h nbd.h ncp_fs.h ncp.h ncp_mount.h netdevice.h              \
+-      netfilter_bridge.h netfilter_decnet.h netfilter.h               \
+-      netfilter_ipv4.h netfilter_ipv6.h netfilter_logging.h net.h     \
+-      netlink.h nfs3.h nfs4.h nfsacl.h nfs_fs.h nfs.h nfs_idmap.h     \
+-      n_r3964.h nubus.h nvram.h parport.h patchkey.h pci.h pktcdvd.h  \
+-      pmu.h poll.h ppp_defs.h ppp-comp.h ptrace.h qnx4_fs.h quota.h   \
+-      random.h reboot.h reiserfs_fs.h reiserfs_xattr.h romfs_fs.h     \
+-      route.h rtc.h rtnetlink.h scc.h sched.h sdla.h                  \
+-      selinux_netlink.h sem.h serial_core.h serial.h serio.h shm.h    \
+-      signal.h smb_fs.h smb.h smb_mount.h socket.h sonet.h sonypi.h   \
+-      soundcard.h stat.h sysctl.h tcp.h time.h timex.h tty.h types.h  \
+-      udf_fs_i.h udp.h uinput.h uio.h unistd.h usb_ch9.h              \
+-      usbdevice_fs.h user.h videodev2.h videodev.h wait.h             \
+-      wanrouter.h watchdog.h xfrm.h zftape.h
++unifdef-y += acct.h
++unifdef-y += adb.h
++unifdef-y += adfs_fs.h
++unifdef-y += agpgart.h
++unifdef-y += apm_bios.h
++unifdef-y += atalk.h
++unifdef-y += atmarp.h
++unifdef-y += atmdev.h
++unifdef-y += atm.h
++unifdef-y += atm_tcp.h
++unifdef-y += audit.h
++unifdef-y += auto_fs.h
++unifdef-y += binfmts.h
++unifdef-y += capability.h
++unifdef-y += capi.h
++unifdef-y += cciss_ioctl.h
++unifdef-y += cdrom.h
++unifdef-y += cm4000_cs.h
++unifdef-y += cn_proc.h
++unifdef-y += coda.h
++unifdef-y += connector.h
++unifdef-y += cramfs_fs.h
++unifdef-y += cuda.h
++unifdef-y += cyclades.h
++unifdef-y += dccp.h
++unifdef-y += dirent.h
++unifdef-y += divert.h
++unifdef-y += elfcore.h
++unifdef-y += errno.h
++unifdef-y += errqueue.h
++unifdef-y += ethtool.h
++unifdef-y += eventpoll.h
++unifdef-y += ext2_fs.h
++unifdef-y += ext3_fs.h
++unifdef-y += fb.h
++unifdef-y += fcntl.h
++unifdef-y += filter.h
++unifdef-y += flat.h
++unifdef-y += fs.h
++unifdef-y += ftape.h
++unifdef-y += gameport.h
++unifdef-y += generic_serial.h
++unifdef-y += genhd.h
++unifdef-y += hayesesp.h
++unifdef-y += hdlcdrv.h
++unifdef-y += hdlc.h
++unifdef-y += hdreg.h
++unifdef-y += hiddev.h
++unifdef-y += hpet.h
++unifdef-y += i2c.h
++unifdef-y += i2o-dev.h
++unifdef-y += icmpv6.h
++unifdef-y += if_bridge.h
++unifdef-y += if_ec.h
++unifdef-y += if_eql.h
++unifdef-y += if_ether.h
++unifdef-y += if_frad.h
++unifdef-y += if_ltalk.h
++unifdef-y += if_pppox.h
++unifdef-y += if_shaper.h
++unifdef-y += if_tr.h
++unifdef-y += if_tun.h
++unifdef-y += if_vlan.h
++unifdef-y += if_wanpipe.h
++unifdef-y += igmp.h
++unifdef-y += inet_diag.h
++unifdef-y += in.h
++unifdef-y += inotify.h
++unifdef-y += input.h
++unifdef-y += ipc.h
++unifdef-y += ipmi.h
++unifdef-y += ipv6.h
++unifdef-y += ipv6_route.h
++unifdef-y += isdn.h
++unifdef-y += isdnif.h
++unifdef-y += isdn_ppp.h
++unifdef-y += isicom.h
++unifdef-y += jbd.h
++unifdef-y += joystick.h
++unifdef-y += kdev_t.h
++unifdef-y += kd.h
++unifdef-y += kernelcapi.h
++unifdef-y += kernel.h
++unifdef-y += keyboard.h
++unifdef-y += llc.h
++unifdef-y += loop.h
++unifdef-y += lp.h
++unifdef-y += mempolicy.h
++unifdef-y += mii.h
++unifdef-y += mman.h
++unifdef-y += mroute.h
++unifdef-y += msdos_fs.h
++unifdef-y += msg.h
++unifdef-y += nbd.h
++unifdef-y += ncp_fs.h
++unifdef-y += ncp.h
++unifdef-y += ncp_mount.h
++unifdef-y += netdevice.h
++unifdef-y += netfilter_bridge.h
++unifdef-y += netfilter_decnet.h
++unifdef-y += netfilter.h
++unifdef-y += netfilter_ipv4.h
++unifdef-y += netfilter_ipv6.h
++unifdef-y += netfilter_logging.h
++unifdef-y += net.h
++unifdef-y += netlink.h
++unifdef-y += nfs3.h
++unifdef-y += nfs4.h
++unifdef-y += nfsacl.h
++unifdef-y += nfs_fs.h
++unifdef-y += nfs.h
++unifdef-y += nfs_idmap.h
++unifdef-y += n_r3964.h
++unifdef-y += nubus.h
++unifdef-y += nvram.h
++unifdef-y += parport.h
++unifdef-y += patchkey.h
++unifdef-y += pci.h
++unifdef-y += pktcdvd.h
++unifdef-y += pmu.h
++unifdef-y += poll.h
++unifdef-y += ppp_defs.h
++unifdef-y += ppp-comp.h
++unifdef-y += ptrace.h
++unifdef-y += qnx4_fs.h
++unifdef-y += quota.h
++unifdef-y += random.h
++unifdef-y += reboot.h
++unifdef-y += reiserfs_fs.h
++unifdef-y += reiserfs_xattr.h
++unifdef-y += romfs_fs.h
++unifdef-y += route.h
++unifdef-y += rtc.h
++unifdef-y += rtnetlink.h
++unifdef-y += scc.h
++unifdef-y += sched.h
++unifdef-y += sdla.h
++unifdef-y += selinux_netlink.h
++unifdef-y += sem.h
++unifdef-y += serial_core.h
++unifdef-y += serial.h
++unifdef-y += serio.h
++unifdef-y += shm.h
++unifdef-y += signal.h
++unifdef-y += smb_fs.h
++unifdef-y += smb.h
++unifdef-y += smb_mount.h
++unifdef-y += socket.h
++unifdef-y += sonet.h
++unifdef-y += sonypi.h
++unifdef-y += soundcard.h
++unifdef-y += stat.h
++unifdef-y += sysctl.h
++unifdef-y += tcp.h
++unifdef-y += time.h
++unifdef-y += timex.h
++unifdef-y += tty.h
++unifdef-y += types.h
++unifdef-y += udf_fs_i.h
++unifdef-y += udp.h
++unifdef-y += uinput.h
++unifdef-y += uio.h
++unifdef-y += unistd.h
++unifdef-y += usb_ch9.h
++unifdef-y += usbdevice_fs.h
++unifdef-y += user.h
++unifdef-y += videodev2.h
++unifdef-y += videodev.h
++unifdef-y += wait.h
++unifdef-y += wanrouter.h
++unifdef-y += watchdog.h
++unifdef-y += xfrm.h
++unifdef-y += zftape.h
+-objhdr-y := version.h
++objhdr-y += version.h
+--- linux-2.6.18.orig/include/linux/byteorder/Kbuild
++++ linux-2.6.18/include/linux/byteorder/Kbuild
+@@ -1,2 +1,7 @@
+-unifdef-y += generic.h swabb.h swab.h
+-header-y += big_endian.h little_endian.h pdp_endian.h
++header-y += big_endian.h
++header-y += little_endian.h
++header-y += pdp_endian.h
++
++unifdef-y += generic.h
++unifdef-y += swabb.h
++unifdef-y += swab.h
+--- linux-2.6.18.orig/include/linux/dvb/Kbuild
++++ linux-2.6.18/include/linux/dvb/Kbuild
+@@ -1,2 +1,9 @@
+-header-y += ca.h frontend.h net.h osd.h version.h
+-unifdef-y := audio.h dmx.h video.h
++header-y += ca.h
++header-y += frontend.h
++header-y += net.h
++header-y += osd.h
++header-y += version.h
++
++unifdef-y += audio.h
++unifdef-y += dmx.h
++unifdef-y += video.h
+--- linux-2.6.18.orig/include/linux/netfilter/Kbuild
++++ linux-2.6.18/include/linux/netfilter/Kbuild
+@@ -1,11 +1,38 @@
+-header-y := nf_conntrack_sctp.h nf_conntrack_tuple_common.h           \
+-          nfnetlink_conntrack.h nfnetlink_log.h nfnetlink_queue.h     \
+-          xt_CLASSIFY.h xt_comment.h xt_connbytes.h xt_connmark.h     \
+-          xt_CONNMARK.h xt_conntrack.h xt_dccp.h xt_esp.h             \
+-          xt_helper.h xt_length.h xt_limit.h xt_mac.h xt_mark.h       \
+-          xt_MARK.h xt_multiport.h xt_NFQUEUE.h xt_pkttype.h          \
+-          xt_policy.h xt_realm.h xt_sctp.h xt_state.h xt_string.h     \
+-          xt_tcpmss.h xt_tcpudp.h xt_SECMARK.h xt_CONNSECMARK.h
++header-y += nf_conntrack_sctp.h
++header-y += nf_conntrack_tuple_common.h
++header-y += nfnetlink_conntrack.h
++header-y += nfnetlink_log.h
++header-y += nfnetlink_queue.h
++header-y += xt_CLASSIFY.h
++header-y += xt_comment.h
++header-y += xt_connbytes.h
++header-y += xt_connmark.h
++header-y += xt_CONNMARK.h
++header-y += xt_conntrack.h
++header-y += xt_dccp.h
++header-y += xt_esp.h
++header-y += xt_helper.h
++header-y += xt_length.h
++header-y += xt_limit.h
++header-y += xt_mac.h
++header-y += xt_mark.h
++header-y += xt_MARK.h
++header-y += xt_multiport.h
++header-y += xt_NFQUEUE.h
++header-y += xt_pkttype.h
++header-y += xt_policy.h
++header-y += xt_realm.h
++header-y += xt_sctp.h
++header-y += xt_state.h
++header-y += xt_string.h
++header-y += xt_tcpmss.h
++header-y += xt_tcpudp.h
++header-y += xt_SECMARK.h
++header-y += xt_CONNSECMARK.h
+-unifdef-y := nf_conntrack_common.h nf_conntrack_ftp.h         \
+-      nf_conntrack_tcp.h nfnetlink.h x_tables.h xt_physdev.h
++unifdef-y += nf_conntrack_common.h
++unifdef-y += nf_conntrack_ftp.h
++unifdef-y += nf_conntrack_tcp.h
++unifdef-y += nfnetlink.h
++unifdef-y += x_tables.h
++unifdef-y += xt_physdev.h
+--- linux-2.6.18.orig/include/linux/netfilter_arp/Kbuild
++++ linux-2.6.18/include/linux/netfilter_arp/Kbuild
+@@ -1,2 +1,3 @@
+-header-y := arpt_mangle.h
+-unifdef-y := arp_tables.h
++header-y += arpt_mangle.h
++
++unifdef-y += arp_tables.h
+--- linux-2.6.18.orig/include/linux/netfilter_bridge/Kbuild
++++ linux-2.6.18/include/linux/netfilter_bridge/Kbuild
+@@ -1,4 +1,17 @@
+-header-y += ebt_among.h ebt_arp.h ebt_arpreply.h ebt_ip.h ebt_limit.h \
+-      ebt_log.h ebt_mark_m.h ebt_mark_t.h ebt_nat.h ebt_pkttype.h     \
+-      ebt_redirect.h ebt_stp.h ebt_ulog.h ebt_vlan.h
+-unifdef-y := ebtables.h ebt_802_3.h
++header-y += ebt_among.h
++header-y += ebt_arp.h
++header-y += ebt_arpreply.h
++header-y += ebt_ip.h
++header-y += ebt_limit.h
++header-y += ebt_log.h
++header-y += ebt_mark_m.h
++header-y += ebt_mark_t.h
++header-y += ebt_nat.h
++header-y += ebt_pkttype.h
++header-y += ebt_redirect.h
++header-y += ebt_stp.h
++header-y += ebt_ulog.h
++header-y += ebt_vlan.h
++
++unifdef-y += ebtables.h
++unifdef-y += ebt_802_3.h
+--- linux-2.6.18.orig/include/linux/netfilter_ipv4/Kbuild
++++ linux-2.6.18/include/linux/netfilter_ipv4/Kbuild
+@@ -1,21 +1,63 @@
++header-y += ip_conntrack_helper.h
++header-y += ip_conntrack_helper_h323_asn1.h
++header-y += ip_conntrack_helper_h323_types.h
++header-y += ip_conntrack_protocol.h
++header-y += ip_conntrack_sctp.h
++header-y += ip_conntrack_tcp.h
++header-y += ip_conntrack_tftp.h
++header-y += ip_nat_pptp.h
++header-y += ipt_addrtype.h
++header-y += ipt_ah.h
++header-y += ipt_CLASSIFY.h
++header-y += ipt_CLUSTERIP.h
++header-y += ipt_comment.h
++header-y += ipt_connbytes.h
++header-y += ipt_connmark.h
++header-y += ipt_CONNMARK.h
++header-y += ipt_conntrack.h
++header-y += ipt_dccp.h
++header-y += ipt_dscp.h
++header-y += ipt_DSCP.h
++header-y += ipt_ecn.h
++header-y += ipt_ECN.h
++header-y += ipt_esp.h
++header-y += ipt_hashlimit.h
++header-y += ipt_helper.h
++header-y += ipt_iprange.h
++header-y += ipt_length.h
++header-y += ipt_limit.h
++header-y += ipt_LOG.h
++header-y += ipt_mac.h
++header-y += ipt_mark.h
++header-y += ipt_MARK.h
++header-y += ipt_multiport.h
++header-y += ipt_NFQUEUE.h
++header-y += ipt_owner.h
++header-y += ipt_physdev.h
++header-y += ipt_pkttype.h
++header-y += ipt_policy.h
++header-y += ipt_realm.h
++header-y += ipt_recent.h
++header-y += ipt_REJECT.h
++header-y += ipt_SAME.h
++header-y += ipt_sctp.h
++header-y += ipt_state.h
++header-y += ipt_string.h
++header-y += ipt_tcpmss.h
++header-y += ipt_TCPMSS.h
++header-y += ipt_tos.h
++header-y += ipt_TOS.h
++header-y += ipt_ttl.h
++header-y += ipt_TTL.h
++header-y += ipt_ULOG.h
+-header-y := ip_conntrack_helper.h ip_conntrack_helper_h323_asn1.h     \
+-          ip_conntrack_helper_h323_types.h ip_conntrack_protocol.h    \
+-          ip_conntrack_sctp.h ip_conntrack_tcp.h ip_conntrack_tftp.h  \
+-          ip_nat_pptp.h ipt_addrtype.h ipt_ah.h       \
+-          ipt_CLASSIFY.h ipt_CLUSTERIP.h ipt_comment.h                \
+-          ipt_connbytes.h ipt_connmark.h ipt_CONNMARK.h               \
+-          ipt_conntrack.h ipt_dccp.h ipt_dscp.h ipt_DSCP.h ipt_ecn.h  \
+-          ipt_ECN.h ipt_esp.h ipt_hashlimit.h ipt_helper.h            \
+-          ipt_iprange.h ipt_length.h ipt_limit.h ipt_LOG.h ipt_mac.h  \
+-          ipt_mark.h ipt_MARK.h ipt_multiport.h ipt_NFQUEUE.h         \
+-          ipt_owner.h ipt_physdev.h ipt_pkttype.h ipt_policy.h        \
+-          ipt_realm.h ipt_recent.h ipt_REJECT.h ipt_SAME.h            \
+-          ipt_sctp.h ipt_state.h ipt_string.h ipt_tcpmss.h            \
+-          ipt_TCPMSS.h ipt_tos.h ipt_TOS.h ipt_ttl.h ipt_TTL.h        \
+-          ipt_ULOG.h
+-
+-unifdef-y := ip_conntrack.h ip_conntrack_h323.h ip_conntrack_irc.h    \
+-      ip_conntrack_pptp.h ip_conntrack_proto_gre.h                    \
+-      ip_conntrack_tuple.h ip_nat.h ip_nat_rule.h ip_queue.h          \
+-      ip_tables.h
++unifdef-y += ip_conntrack.h
++unifdef-y += ip_conntrack_h323.h
++unifdef-y += ip_conntrack_irc.h
++unifdef-y += ip_conntrack_pptp.h
++unifdef-y += ip_conntrack_proto_gre.h
++unifdef-y += ip_conntrack_tuple.h
++unifdef-y += ip_nat.h
++unifdef-y += ip_nat_rule.h
++unifdef-y += ip_queue.h
++unifdef-y += ip_tables.h
+--- linux-2.6.18.orig/include/linux/netfilter_ipv6/Kbuild
++++ linux-2.6.18/include/linux/netfilter_ipv6/Kbuild
+@@ -1,6 +1,21 @@
+-header-y += ip6t_HL.h ip6t_LOG.h ip6t_MARK.h ip6t_REJECT.h ip6t_ah.h  \
+-      ip6t_esp.h ip6t_frag.h ip6t_hl.h ip6t_ipv6header.h              \
+-      ip6t_length.h ip6t_limit.h ip6t_mac.h ip6t_mark.h               \
+-      ip6t_multiport.h ip6t_opts.h ip6t_owner.h ip6t_policy.h         \
+-      ip6t_physdev.h ip6t_rt.h
+-unifdef-y := ip6_tables.h
++header-y += ip6t_HL.h
++header-y += ip6t_LOG.h
++header-y += ip6t_MARK.h
++header-y += ip6t_REJECT.h
++header-y += ip6t_ah.h
++header-y += ip6t_esp.h
++header-y += ip6t_frag.h
++header-y += ip6t_hl.h
++header-y += ip6t_ipv6header.h
++header-y += ip6t_length.h
++header-y += ip6t_limit.h
++header-y += ip6t_mac.h
++header-y += ip6t_mark.h
++header-y += ip6t_multiport.h
++header-y += ip6t_opts.h
++header-y += ip6t_owner.h
++header-y += ip6t_policy.h
++header-y += ip6t_physdev.h
++header-y += ip6t_rt.h
++
++unifdef-y += ip6_tables.h
+--- linux-2.6.18.orig/include/linux/nfsd/Kbuild
++++ linux-2.6.18/include/linux/nfsd/Kbuild
+@@ -1,2 +1,7 @@
+-unifdef-y := const.h export.h stats.h syscall.h nfsfh.h debug.h auth.h
+-
++unifdef-y += const.h
++unifdef-y += export.h
++unifdef-y += stats.h
++unifdef-y += syscall.h
++unifdef-y += nfsfh.h
++unifdef-y += debug.h
++unifdef-y += auth.h
+--- linux-2.6.18.orig/include/linux/raid/Kbuild
++++ linux-2.6.18/include/linux/raid/Kbuild
+@@ -1 +1,2 @@
+-header-y += md_p.h md_u.h
++header-y += md_p.h
++header-y += md_u.h
+--- linux-2.6.18.orig/include/linux/sunrpc/Kbuild
++++ linux-2.6.18/include/linux/sunrpc/Kbuild
+@@ -1 +1 @@
+-unifdef-y := debug.h
++unifdef-y += debug.h
+--- linux-2.6.18.orig/include/linux/tc_act/Kbuild
++++ linux-2.6.18/include/linux/tc_act/Kbuild
+@@ -1 +1,4 @@
+-header-y += tc_gact.h tc_ipt.h tc_mirred.h tc_pedit.h
++header-y += tc_gact.h
++header-y += tc_ipt.h
++header-y += tc_mirred.h
++header-y += tc_pedit.h
+--- linux-2.6.18.orig/include/linux/tc_ematch/Kbuild
++++ linux-2.6.18/include/linux/tc_ematch/Kbuild
+@@ -1 +1,4 @@
+-headers-y := tc_em_cmp.h tc_em_meta.h tc_em_nbyte.h tc_em_text.h
++header-y += tc_em_cmp.h
++header-y += tc_em_meta.h
++header-y += tc_em_nbyte.h
++header-y += tc_em_text.h
+--- linux-2.6.18.orig/include/mtd/Kbuild
++++ linux-2.6.18/include/mtd/Kbuild
+@@ -1,2 +1,6 @@
+-unifdef-y := mtd-abi.h
+-header-y := inftl-user.h jffs2-user.h mtd-user.h nftl-user.h
++header-y += inftl-user.h
++header-y += jffs2-user.h
++header-y += mtd-user.h
++header-y += nftl-user.h
++
++unifdef-y += mtd-abi.h
+--- linux-2.6.18.orig/include/rdma/Kbuild
++++ linux-2.6.18/include/rdma/Kbuild
+@@ -1 +1 @@
+-header-y := ib_user_mad.h
++header-y += ib_user_mad.h
+--- linux-2.6.18.orig/include/scsi/Kbuild
++++ linux-2.6.18/include/scsi/Kbuild
+@@ -1,2 +1,4 @@
+ header-y += scsi.h
+-unifdef-y := scsi_ioctl.h sg.h
++
++unifdef-y += scsi_ioctl.h
++unifdef-y += sg.h
+--- linux-2.6.18.orig/include/sound/Kbuild
++++ linux-2.6.18/include/sound/Kbuild
+@@ -1,2 +1,10 @@
+-header-y := asound_fm.h hdsp.h hdspm.h sfnt_info.h sscape_ioctl.h
+-unifdef-y := asequencer.h asound.h emu10k1.h sb16_csp.h 
++header-y += asound_fm.h
++header-y += hdsp.h
++header-y += hdspm.h
++header-y += sfnt_info.h
++header-y += sscape_ioctl.h
++
++unifdef-y += asequencer.h
++unifdef-y += asound.h
++unifdef-y += emu10k1.h
++unifdef-y += sb16_csp.h
+--- linux-2.6.18.orig/include/video/Kbuild
++++ linux-2.6.18/include/video/Kbuild
+@@ -1 +1 @@
+-unifdef-y := sisfb.h
++unifdef-y += sisfb.h
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:32 2006
+Message-Id: <20061011204832.834672953@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:20 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 24/67] Fix ARM make headers_check
+Content-Disposition: inline; filename=0002-HEADERS-Fix-ARM-make-headers_check.patch
+Status: RO
+Content-Length: 2116
+Lines: 80
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+Sanitise the ARM headers exported to userspace.
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-arm/elf.h  |   18 ++++++++----------
+ include/asm-arm/page.h |    4 ++--
+ 2 files changed, 10 insertions(+), 12 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-arm/elf.h
++++ linux-2.6.18/include/asm-arm/elf.h
+@@ -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 elf_greg_t elf_gregset_t[ELF_NGR
+ 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
+@@ -47,6 +39,14 @@ typedef struct user_fp elf_fpregset_t;
+ #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
+@@ -83,8 +83,6 @@ typedef struct user_fp elf_fpregset_t;
+ 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.
+  */
+--- linux-2.6.18.orig/include/asm-arm/page.h
++++ linux-2.6.18/include/asm-arm/page.h
+@@ -11,13 +11,13 @@
+ #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)
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:33 2006
+Message-Id: <20061011204832.975749172@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:21 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Paul Mundt <lethal@linux-sh.org>,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 25/67] Fix make headers_check on sh
+Content-Disposition: inline; filename=0003-Fix-make-headers_check-on-sh.patch
+Status: RO
+Content-Length: 1543
+Lines: 53
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Paul Mundt <lethal@linux-sh.org>
+
+Cleanup for user headers, as noted:
+
+asm-sh/page.h requires asm-generic/memory_model.h, which does not exist in exported headers
+asm-sh/ptrace.h requires asm/ubc.h, which does not exist in exported headers
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sh/kernel/process.c |    1 +
+ include/asm-sh/page.h    |    3 +--
+ include/asm-sh/ptrace.h  |    2 --
+ 3 files changed, 2 insertions(+), 4 deletions(-)
+
+--- linux-2.6.18.orig/arch/sh/kernel/process.c
++++ linux-2.6.18/arch/sh/kernel/process.c
+@@ -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;
+--- linux-2.6.18.orig/include/asm-sh/page.h
++++ linux-2.6.18/include/asm-sh/page.h
+@@ -112,9 +112,8 @@ 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 /* __ASM_SH_PAGE_H */
+--- linux-2.6.18.orig/include/asm-sh/ptrace.h
++++ linux-2.6.18/include/asm-sh/ptrace.h
+@@ -1,8 +1,6 @@
+ #ifndef __ASM_SH_PTRACE_H
+ #define __ASM_SH_PTRACE_H
+-#include <asm/ubc.h>
+-
+ /*
+  * Copyright (C) 1999, 2000  Niibe Yutaka
+  *
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:33 2006
+Message-Id: <20061011204833.126142368@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:22 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Paul Mundt <lethal@linux-sh.org>,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 26/67] Fix make headers_check on sh64
+Content-Disposition: inline; filename=0004-Fix-make-headers_check-on-sh64.patch
+Status: RO
+Content-Length: 2535
+Lines: 81
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Paul Mundt <lethal@linux-sh.org>
+
+Cleanup for user headers, as noted:
+
+asm-sh64/page.h requires asm-generic/memory_model.h, which does not exist in exported headers
+asm-sh64/shmparam.h requires asm/cache.h, which does not exist in exported headers
+asm-sh64/signal.h requires asm/processor.h, which does not exist in exported headers
+asm-sh64/user.h requires asm/processor.h, which does not exist in exported headers
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-sh64/page.h     |    3 +--
+ include/asm-sh64/shmparam.h |   16 ++++------------
+ include/asm-sh64/signal.h   |    1 -
+ include/asm-sh64/user.h     |    1 -
+ 4 files changed, 5 insertions(+), 16 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-sh64/page.h
++++ linux-2.6.18/include/asm-sh64/page.h
+@@ -112,9 +112,8 @@ 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 /* __ASM_SH64_PAGE_H */
+--- linux-2.6.18.orig/include/asm-sh64/shmparam.h
++++ linux-2.6.18/include/asm-sh64/shmparam.h
+@@ -2,19 +2,11 @@
+ #define __ASM_SH64_SHMPARAM_H
+ /*
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License.  See the file "COPYING" in the main directory of this archive
+- * for more details.
+- *
+- * include/asm-sh64/shmparam.h
+- *
+- * Copyright (C) 2000, 2001  Paolo Alberelli
+- *
++ * Set this to a sensible safe default, we'll work out the specifics for the
++ * align mask from the cache descriptor at run-time.
+  */
++#define       SHMLBA  0x4000
+-#include <asm/cache.h>
+-
+-/* attach addr a multiple of this */
+-#define       SHMLBA  (cpu_data->dcache.sets * L1_CACHE_BYTES)
++#define __ARCH_FORCE_SHMLBA
+ #endif /* __ASM_SH64_SHMPARAM_H */
+--- linux-2.6.18.orig/include/asm-sh64/signal.h
++++ linux-2.6.18/include/asm-sh64/signal.h
+@@ -13,7 +13,6 @@
+  */
+ #include <linux/types.h>
+-#include <asm/processor.h>
+ /* Avoid too many header ordering problems.  */
+ struct siginfo;
+--- linux-2.6.18.orig/include/asm-sh64/user.h
++++ linux-2.6.18/include/asm-sh64/user.h
+@@ -13,7 +13,6 @@
+  */
+ #include <linux/types.h>
+-#include <asm/processor.h>
+ #include <asm/ptrace.h>
+ #include <asm/page.h>
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:33 2006
+Message-Id: <20061011204833.271064978@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:23 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Hirokazu Takata <takata@linux-m32r.org>,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 27/67] Fix make headers_check on m32r
+Content-Disposition: inline; filename=0005-Fix-make-headers_check-on-m32r.patch
+Status: RO
+Content-Length: 2677
+Lines: 96
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+> asm-m32r/page.h requires asm-generic/memory_model.h, which does not exist
+> asm-m32r/ptrace.h requires asm/m32r.h, which does not exist
+> asm-m32r/signal.h requires linux/linkage.h, which does not exist
+> asm-m32r/unistd.h requires asm/syscall.h, which does not exist
+> asm-m32r/user.h requires asm/processor.h, which does not exist
+
+Signed-off-by: Hirokazu Takata <takata@linux-m32r.org>
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-m32r/page.h   |    3 +--
+ include/asm-m32r/ptrace.h |    4 ++--
+ include/asm-m32r/signal.h |    1 -
+ include/asm-m32r/unistd.h |    4 ++--
+ include/asm-m32r/user.h   |    1 -
+ 5 files changed, 5 insertions(+), 8 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-m32r/page.h
++++ linux-2.6.18/include/asm-m32r/page.h
+@@ -87,10 +87,9 @@ typedef struct { unsigned long pgprot; }
+ #define devmem_is_allowed(x) 1
+-#endif /* __KERNEL__ */
+-
+ #include <asm-generic/memory_model.h>
+ #include <asm-generic/page.h>
++#endif /* __KERNEL__ */
+ #endif /* _ASM_M32R_PAGE_H */
+--- linux-2.6.18.orig/include/asm-m32r/ptrace.h
++++ linux-2.6.18/include/asm-m32r/ptrace.h
+@@ -12,8 +12,6 @@
+  *   Copyright (C) 2001-2002, 2004  Hirokazu Takata <takata at linux-m32r.org>
+  */
+-#include <asm/m32r.h>         /* M32R_PSW_BSM, M32R_PSW_BPM */
+-
+ /* 0 - 13 are integer registers (general purpose registers).  */
+ #define PT_R4         0
+ #define PT_R5         1
+@@ -140,6 +138,8 @@ struct pt_regs {
+ #ifdef __KERNEL__
++#include <asm/m32r.h>         /* M32R_PSW_BSM, M32R_PSW_BPM */
++
+ #define __ARCH_SYS_PTRACE     1
+ #if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
+--- linux-2.6.18.orig/include/asm-m32r/signal.h
++++ linux-2.6.18/include/asm-m32r/signal.h
+@@ -6,7 +6,6 @@
+ /* orig : i386 2.4.18 */
+ #include <linux/types.h>
+-#include <linux/linkage.h>
+ #include <linux/time.h>
+ #include <linux/compiler.h>
+--- linux-2.6.18.orig/include/asm-m32r/unistd.h
++++ linux-2.6.18/include/asm-m32r/unistd.h
+@@ -3,8 +3,6 @@
+ /* $Id$ */
+-#include <asm/syscall.h>      /* SYSCALL_* */
+-
+ /*
+  * This file contains the system call numbers.
+  */
+@@ -303,6 +301,8 @@
+  * <asm-m32r/errno.h>
+  */
++#include <asm/syscall.h>      /* SYSCALL_* */
++
+ #define __syscall_return(type, res) \
+ do { \
+       if ((unsigned long)(res) >= (unsigned long)(-(124 + 1))) { \
+--- linux-2.6.18.orig/include/asm-m32r/user.h
++++ linux-2.6.18/include/asm-m32r/user.h
+@@ -8,7 +8,6 @@
+  */
+ #include <linux/types.h>
+-#include <asm/processor.h>
+ #include <asm/ptrace.h>
+ #include <asm/page.h>
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:33 2006
+Message-Id: <20061011204833.411138207@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:24 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ "David S. Miller" <davem@davemloft.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 28/67] Fix exported headers for SPARC, SPARC64
+Content-Disposition: inline; filename=0006-Fix-exported-headers-for-SPARC-SPARC64.patch
+Status: RO
+Content-Length: 3611
+Lines: 139
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+Mostly removing files which have no business being used in userspace.
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-sparc/Kbuild       |    7 -------
+ include/asm-sparc/page.h       |    8 ++++----
+ include/asm-sparc64/Kbuild     |    5 +----
+ include/asm-sparc64/page.h     |    9 ++++-----
+ include/asm-sparc64/shmparam.h |    2 ++
+ 5 files changed, 11 insertions(+), 20 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-sparc/Kbuild
++++ linux-2.6.18/include/asm-sparc/Kbuild
+@@ -2,20 +2,13 @@ include include/asm-generic/Kbuild.asm
+ header-y += apc.h
+ header-y += asi.h
+-header-y += auxio.h
+ header-y += bpp.h
+-header-y += head.h
+-header-y += ipc.h
+ header-y += jsflash.h
+ header-y += openpromio.h
+-header-y += pbm.h
+ header-y += pconf.h
+-header-y += pgtsun4.h
+ header-y += reg.h
+ header-y += traps.h
+-header-y += turbosparc.h
+ header-y += vfc_ioctls.h
+-header-y += winmacro.h
+ unifdef-y += fbio.h
+ unifdef-y += perfctr.h
+--- linux-2.6.18.orig/include/asm-sparc/page.h
++++ linux-2.6.18/include/asm-sparc/page.h
+@@ -8,6 +8,8 @@
+ #ifndef _SPARC_PAGE_H
+ #define _SPARC_PAGE_H
++#ifdef __KERNEL__
++
+ #ifdef CONFIG_SUN4
+ #define PAGE_SHIFT   13
+ #else
+@@ -21,8 +23,6 @@
+ #endif
+ #define PAGE_MASK    (~(PAGE_SIZE-1))
+-#ifdef __KERNEL__
+-
+ #include <asm/btfixup.h>
+ #ifndef __ASSEMBLY__
+@@ -160,9 +160,9 @@ extern unsigned long pfn_base;
+ #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 /* _SPARC_PAGE_H */
+--- linux-2.6.18.orig/include/asm-sparc64/Kbuild
++++ linux-2.6.18/include/asm-sparc64/Kbuild
+@@ -8,15 +8,12 @@ header-y += apb.h
+ header-y += asi.h
+ header-y += bbc.h
+ header-y += bpp.h
++header-y += const.h
+ header-y += display7seg.h
+ header-y += envctrl.h
+-header-y += floppy.h
+ header-y += ipc.h
+-header-y += kdebug.h
+-header-y += mostek.h
+ header-y += openprom.h
+ header-y += openpromio.h
+-header-y += parport.h
+ header-y += pconf.h
+ header-y += psrcompat.h
+ header-y += pstate.h
+--- linux-2.6.18.orig/include/asm-sparc64/page.h
++++ linux-2.6.18/include/asm-sparc64/page.h
+@@ -3,6 +3,8 @@
+ #ifndef _SPARC64_PAGE_H
+ #define _SPARC64_PAGE_H
++#ifdef __KERNEL__
++
+ #include <asm/const.h>
+ #if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
+@@ -27,8 +29,6 @@
+ #define DCACHE_ALIASING_POSSIBLE
+ #endif
+-#ifdef __KERNEL__
+-
+ #if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
+ #define HPAGE_SHIFT           22
+ #elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
+@@ -141,8 +141,7 @@ typedef unsigned long pgprot_t;
+ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
+                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+-#endif /* !(__KERNEL__) */
+-
+ #include <asm-generic/page.h>
+-#endif /* !(_SPARC64_PAGE_H) */
++#endif /* __KERNEL__ */
++#endif /* _SPARC64_PAGE_H */
+--- linux-2.6.18.orig/include/asm-sparc64/shmparam.h
++++ linux-2.6.18/include/asm-sparc64/shmparam.h
+@@ -1,6 +1,7 @@
+ /* $Id: shmparam.h,v 1.5 2001/09/24 21:17:57 kanoj Exp $ */
+ #ifndef _ASMSPARC64_SHMPARAM_H
+ #define _ASMSPARC64_SHMPARAM_H
++#ifdef __KERNEL__
+ #include <asm/spitfire.h>
+@@ -8,4 +9,5 @@
+ /* attach addr a multiple of this */
+ #define       SHMLBA  ((PAGE_SIZE > L1DCACHE_SIZE) ? PAGE_SIZE : L1DCACHE_SIZE)
++#endif /* __KERNEL__ */
+ #endif /* _ASMSPARC64_SHMPARAM_H */
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:33 2006
+Message-Id: <20061011204833.554102241@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:25 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 29/67] Fix m68knommu exported headers
+Content-Disposition: inline; filename=0007-Fix-m68knommu-exported-headers.patch
+Status: RO
+Content-Length: 971
+Lines: 43
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+Just clean up asm/page.h
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-m68knommu/page.h |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-m68knommu/page.h
++++ linux-2.6.18/include/asm-m68knommu/page.h
+@@ -1,6 +1,7 @@
+ #ifndef _M68KNOMMU_PAGE_H
+ #define _M68KNOMMU_PAGE_H
++#ifdef __KERNEL__
+ /* PAGE_SHIFT determines the page size */
+@@ -8,8 +9,6 @@
+ #define PAGE_SIZE     (1UL << PAGE_SHIFT)
+ #define PAGE_MASK     (~(PAGE_SIZE-1))
+-#ifdef __KERNEL__
+-
+ #include <asm/setup.h>
+ #ifndef __ASSEMBLY__
+@@ -76,8 +75,8 @@ extern unsigned long memory_end;
+ #endif /* __ASSEMBLY__ */
+-#endif /* __KERNEL__ */
+-
+ #include <asm-generic/page.h>
++#endif /* __KERNEL__ */
++
+ #endif /* _M68KNOMMU_PAGE_H */
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:33 2006
+Message-Id: <20061011204833.694509133@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:26 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 30/67] Fix H8300 exported headers.
+Content-Disposition: inline; filename=0008-Fix-H8300-exported-headers.patch
+Status: RO
+Content-Length: 986
+Lines: 44
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+Just clean up asm/page.h
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-h8300/page.h |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-h8300/page.h
++++ linux-2.6.18/include/asm-h8300/page.h
+@@ -1,6 +1,7 @@
+ #ifndef _H8300_PAGE_H
+ #define _H8300_PAGE_H
++#ifdef __KERNEL__
+ /* PAGE_SHIFT determines the page size */
+@@ -8,8 +9,6 @@
+ #define PAGE_SIZE     (1UL << PAGE_SHIFT)
+ #define PAGE_MASK     (~(PAGE_SIZE-1))
+-#ifdef __KERNEL__
+-
+ #include <asm/setup.h>
+ #ifndef __ASSEMBLY__
+@@ -76,9 +75,9 @@ extern unsigned long memory_end;
+ #endif /* __ASSEMBLY__ */
+-#endif /* __KERNEL__ */
+-
+ #include <asm-generic/memory_model.h>
+ #include <asm-generic/page.h>
++#endif /* __KERNEL__ */
++
+ #endif /* _H8300_PAGE_H */
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:33 2006
+Message-Id: <20061011204833.834681517@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:27 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 31/67] Remove ARM26 header export.
+Content-Disposition: inline; filename=0009-Remove-ARM26-header-export.patch
+Status: RO
+Content-Length: 510
+Lines: 17
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+We ought to be able to use ARM headers; no need for special ARM26 version.
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-arm26/Kbuild |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- linux-2.6.18.orig/include/asm-arm26/Kbuild
++++ /dev/null
+@@ -1 +0,0 @@
+-include include/asm-generic/Kbuild.asm
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:34 2006
+Message-Id: <20061011204833.974462413@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:28 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 32/67] Remove UML header export
+Content-Disposition: inline; filename=0010-Remove-UML-header-export.patch
+Status: RO
+Content-Length: 495
+Lines: 17
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+No need for UML to export headers for userspace to build against.
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-um/Kbuild |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- linux-2.6.18.orig/include/asm-um/Kbuild
++++ /dev/null
+@@ -1 +0,0 @@
+-include include/asm-generic/Kbuild.asm
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:34 2006
+Message-Id: <20061011204834.115376088@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:29 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 33/67] Dont advertise (or allow) headers_{install,check} where inappropriate.
+Content-Disposition: inline; filename=0011-Don-t-advertise-or-allow-headers_-install-check-where-inappropriate.patch
+Status: RO
+Content-Length: 1818
+Lines: 46
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+For architectures which don't have the include/asm-$(ARCH)/Kbuild file,
+like ARM26, UM, etc.
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Makefile |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/Makefile
++++ linux-2.6.18/Makefile
+@@ -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
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:34 2006
+Message-Id: <20061011204834.254852409@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:30 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 34/67] Fix v850 exported headers
+Content-Disposition: inline; filename=0012-Fix-v850-exported-headers.patch
+Status: RO
+Content-Length: 1414
+Lines: 63
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-v850/page.h  |    7 ++++---
+ include/asm-v850/param.h |    4 ++--
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-v850/page.h
++++ linux-2.6.18/include/asm-v850/page.h
+@@ -14,6 +14,8 @@
+ #ifndef __V850_PAGE_H__
+ #define __V850_PAGE_H__
++#ifdef __KERNEL__
++
+ #include <asm/machdep.h>
+@@ -32,7 +34,6 @@
+ #endif
+-#ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+ #define STRICT_MM_TYPECHECKS
+@@ -122,9 +123,9 @@ typedef unsigned long pgprot_t;
+ #define __va(x)                    ((void *)__phys_to_virt ((unsigned long)(x)))
+-#endif /* KERNEL */
+-
+ #include <asm-generic/memory_model.h>
+ #include <asm-generic/page.h>
++#endif /* KERNEL */
++
+ #endif /* __V850_PAGE_H__ */
+--- linux-2.6.18.orig/include/asm-v850/param.h
++++ linux-2.6.18/include/asm-v850/param.h
+@@ -14,8 +14,6 @@
+ #ifndef __V850_PARAM_H__
+ #define __V850_PARAM_H__
+-#include <asm/machdep.h>      /* For HZ */
+-
+ #define EXEC_PAGESIZE 4096
+ #ifndef NOGROUP
+@@ -25,6 +23,8 @@
+ #define MAXHOSTNAMELEN        64      /* max length of hostname */
+ #ifdef __KERNEL__
++#include <asm/machdep.h>      /* For HZ */
++
+ # define USER_HZ      100
+ # define CLOCKS_PER_SEC       USER_HZ
+ #endif
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:34 2006
+Message-Id: <20061011204834.394650750@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:31 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 35/67] Clean up exported headers on CRIS
+Content-Disposition: inline; filename=0013-Clean-up-exported-headers-on-CRIS.patch
+Status: RO
+Content-Length: 4958
+Lines: 180
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+This fixes most of the issues with exported headers on CRIS, although
+we do still need to deal with the asm/arch symlink.
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 +---
+ 8 files changed, 23 insertions(+), 17 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-cris/Kbuild
++++ linux-2.6.18/include/asm-cris/Kbuild
+@@ -1 +1,5 @@
+ include include/asm-generic/Kbuild.asm
++
++header-y += arch-v10/ arch-v32/
++
++unifdef-y += rs485.h
+--- /dev/null
++++ linux-2.6.18/include/asm-cris/arch-v10/Kbuild
+@@ -0,0 +1,2 @@
++header-y += ptrace.h
++header-y += user.h
+--- /dev/null
++++ linux-2.6.18/include/asm-cris/arch-v32/Kbuild
+@@ -0,0 +1,2 @@
++header-y += ptrace.h
++header-y += user.h
+--- linux-2.6.18.orig/include/asm-cris/byteorder.h
++++ linux-2.6.18/include/asm-cris/byteorder.h
+@@ -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__
+--- linux-2.6.18.orig/include/asm-cris/elf.h
++++ linux-2.6.18/include/asm-cris/elf.h
+@@ -5,7 +5,6 @@
+  * ELF register definitions..
+  */
+-#include <asm/arch/elf.h>
+ #include <asm/user.h>
+ #define R_CRIS_NONE             0
+@@ -46,6 +45,9 @@ typedef unsigned long elf_fpregset_t;
+ #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.  */
+ #define EF_CRIS_UNDERSCORE            0x00000001
+@@ -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
+--- linux-2.6.18.orig/include/asm-cris/page.h
++++ linux-2.6.18/include/asm-cris/page.h
+@@ -1,6 +1,8 @@
+ #ifndef _CRIS_PAGE_H
+ #define _CRIS_PAGE_H
++#ifdef __KERNEL__
++
+ #include <asm/arch/page.h>
+ /* PAGE_SHIFT determines the page size */
+@@ -12,8 +14,6 @@
+ #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 */
+--- linux-2.6.18.orig/include/asm-cris/posix_types.h
++++ linux-2.6.18/include/asm-cris/posix_types.h
+@@ -6,8 +6,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
+  * be a little careful about namespace pollution etc.  Also, we cannot
+@@ -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 */
+--- linux-2.6.18.orig/include/asm-cris/unistd.h
++++ linux-2.6.18/include/asm-cris/unistd.h
+@@ -1,8 +1,6 @@
+ #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__
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:34 2006
+Message-Id: <20061011204834.539113773@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:32 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 36/67] Remove offsetof() from user-visible <linux/stddef.h>
+Content-Disposition: inline; filename=0014-Remove-offsetof-from-user-visible-linux-stddef.h.patch
+Status: RO
+Content-Length: 1295
+Lines: 49
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Woodhouse <dwmw2@infradead.org>
+
+It's not used by anything user-visible, and it make g++ unhappy.
+
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ include/linux/Kbuild   |    2 +-
+ include/linux/stddef.h |    2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/include/linux/Kbuild
++++ linux-2.6.18/include/linux/Kbuild
+@@ -143,7 +143,6 @@ header-y += snmp.h
+ header-y += sockios.h
+ header-y += som.h
+ header-y += sound.h
+-header-y += stddef.h
+ header-y += synclink.h
+ header-y += telephony.h
+ header-y += termios.h
+@@ -318,6 +317,7 @@ unifdef-y += sonet.h
+ unifdef-y += sonypi.h
+ unifdef-y += soundcard.h
+ unifdef-y += stat.h
++unifdef-y += stddef.h
+ unifdef-y += sysctl.h
+ unifdef-y += tcp.h
+ unifdef-y += time.h
+--- linux-2.6.18.orig/include/linux/stddef.h
++++ linux-2.6.18/include/linux/stddef.h
+@@ -10,11 +10,13 @@
+ #define NULL ((void *)0)
+ #endif
++#ifdef __KERNEL__
+ #undef offsetof
+ #ifdef __compiler_offsetof
+ #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+ #else
+ #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+ #endif
++#endif /* __KERNEL__ */
+ #endif
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:34 2006
+Message-Id: <20061011204834.679761352@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:33 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Arnd Bergmann <arnd.bergmann@de.ibm.com>,
+ David Woodhouse <dwmw2@infradead.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 37/67] powerpc: fix building gdb against asm/ptrace.h
+Content-Disposition: inline; filename=0015-powerpc-fix-building-gdb-against-asm-ptrace.h.patch
+Status: RO
+Content-Length: 1851
+Lines: 52
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Arnd Bergmann <arnd.bergmann@de.ibm.com>
+
+Ulrich Weigand found a bug with the current version of the
+asm-powerpc/ptrace.h that prevents building at least the
+SPU target version of gdb, since some ptrace opcodes are
+not defined.
+
+The problem seems to have originated in the merging of 32 and
+64 bit versions of that file, the problem is that some opcodes
+are only valid on 64 bit kernels, but are also used by 32 bit
+programs, so they can't depends on the __powerpc64__ symbol.
+
+Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/asm-powerpc/ptrace.h |    4 ----
+ 1 file changed, 4 deletions(-)
+
+--- linux-2.6.18.orig/include/asm-powerpc/ptrace.h
++++ linux-2.6.18/include/asm-powerpc/ptrace.h
+@@ -215,12 +215,10 @@ do {                                                                           \
+ #define PTRACE_GETVRREGS      18
+ #define PTRACE_SETVRREGS      19
+-#ifndef __powerpc64__
+ /* Get/set all the upper 32-bits of the SPE registers, accumulator, and
+  * spefscr, in one go */
+ #define PTRACE_GETEVRREGS     20
+ #define PTRACE_SETEVRREGS     21
+-#endif /* __powerpc64__ */
+ /*
+  * Get or set a debug register. The first 16 are DABR registers and the
+@@ -235,7 +233,6 @@ do {                                                                             \
+ #define PPC_PTRACE_GETFPREGS  0x97    /* Get FPRs 0 - 31 */
+ #define PPC_PTRACE_SETFPREGS  0x96    /* Set FPRs 0 - 31 */
+-#ifdef __powerpc64__
+ /* Calls to trace a 64bit program from a 32bit program */
+ #define PPC_PTRACE_PEEKTEXT_3264 0x95
+ #define PPC_PTRACE_PEEKDATA_3264 0x94
+@@ -243,6 +240,5 @@ do {                                                                             \
+ #define PPC_PTRACE_POKEDATA_3264 0x92
+ #define PPC_PTRACE_PEEKUSR_3264  0x91
+ #define PPC_PTRACE_POKEUSR_3264  0x90
+-#endif /* __powerpc64__ */
+ #endif /* _ASM_POWERPC_PTRACE_H */
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:34 2006
+Message-Id: <20061011204834.825251060@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:34 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ seto.hidetoshi@jp.fujitsu.com,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 38/67] sysfs: remove duplicated dput in sysfs_update_file
+Content-Disposition: inline; filename=sysfs-remove-duplicated-dput-in-sysfs_update_file.patch
+Status: RO
+Content-Length: 2332
+Lines: 75
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
+
+Following function can drops d_count twice against one reference
+by lookup_one_len.
+
+<SOURCE>
+/**
+ * sysfs_update_file - update the modified timestamp on an object attribute.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ */
+int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
+{
+        struct dentry * dir = kobj->dentry;
+        struct dentry * victim;
+        int res = -ENOENT;
+
+        mutex_lock(&dir->d_inode->i_mutex);
+        victim = lookup_one_len(attr->name, dir, strlen(attr->name));
+        if (!IS_ERR(victim)) {
+                /* make sure dentry is really there */
+                if (victim->d_inode &&
+                    (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);
+
+                /**
+                 * Drop the reference acquired from sysfs_get_dentry() above.
+                 */
+                dput(victim);
+        }
+        mutex_unlock(&dir->d_inode->i_mutex);
+
+        return res;
+}
+</SOURCE>
+
+PCI-hotplug (drivers/pci/hotplug/pci_hotplug_core.c) is only user of
+this function. I confirmed that dentry of /sys/bus/pci/slots/XXX/*
+have negative d_count value.
+
+This patch removes unnecessary dput().
+
+Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/sysfs/file.c |    5 -----
+ 1 file changed, 5 deletions(-)
+
+--- linux-2.6.18.orig/fs/sysfs/file.c
++++ linux-2.6.18/fs/sysfs/file.c
+@@ -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);
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:35 2006
+Message-Id: <20061011204834.966941518@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:35 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Benjamin Herrenschmidt <benh@kernel.crashing.org>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 39/67] powerpc: Fix ohare IDE irq workaround on old powermacs
+Content-Disposition: inline; filename=powerpc-fix-ohare-ide-irq-workaround-on-old-powermacs.patch
+Status: RO
+Content-Length: 853
+Lines: 25
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+Looks like a workaround for old bogus OF bitrot... This fixes it and hence fixes
+boot on some performa machines.
+
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/ppc/pmac.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/drivers/ide/ppc/pmac.c
++++ linux-2.6.18/drivers/ide/ppc/pmac.c
+@@ -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);
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:35 2006
+Message-Id: <20061011204835.108766132@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:36 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ haveblue@us.ibm.com,
+ bunk@stusta.de,
+ vgoyal@in.ibm.com,
+ Keith Mannthey <kmannth@us.ibm.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 40/67] i386 bootioremap / kexec fix
+Content-Disposition: inline; filename=i386-bootioremap-kexec-fix.patch
+Status: RO
+Content-Length: 1196
+Lines: 36
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: keith mannthey <kmannth@us.ibm.com>
+
+With CONFIG_PHYSICAL_START set to a non default values the i386
+boot_ioremap code calculated its pte index wrong and users of boot_ioremap
+have their areas incorrectly mapped (for me SRAT table not mapped during
+early boot).  This patch removes the addr < BOOT_PTE_PTRS constraint.
+
+Signed-off-by: Keith Mannthey<kmannth@us.ibm.com>
+Cc: Vivek Goyal <vgoyal@in.ibm.com>
+Cc: Dave Hansen <haveblue@us.ibm.com>
+Cc: Adrian Bunk <bunk@stusta.de>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/i386/mm/boot_ioremap.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/arch/i386/mm/boot_ioremap.c
++++ linux-2.6.18/arch/i386/mm/boot_ioremap.c
+@@ -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)
+ {
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:35 2006
+Message-Id: <20061011204835.255279414@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:37 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ mingo@elte.hu,
+ a.p.zijlstra@chello.nl,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 41/67] rtc: lockdep fix/workaround
+Content-Disposition: inline; filename=rtc-lockdep-fix-workaround.patch
+Status: RO
+Content-Length: 1429
+Lines: 44
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Peter Zijlstra <a.p.zijlstra@chello.nl>
+
+BUG: warning at kernel/lockdep.c:1816/trace_hardirqs_on() (Not tainted)
+ [<c04051ee>] show_trace_log_lvl+0x58/0x171
+ [<c0405802>] show_trace+0xd/0x10
+ [<c040591b>] dump_stack+0x19/0x1b
+ [<c043abee>] trace_hardirqs_on+0xa2/0x11e
+ [<c06143c3>] _spin_unlock_irq+0x22/0x26
+ [<c0541540>] rtc_get_rtc_time+0x32/0x176
+ [<c0419ba4>] hpet_rtc_interrupt+0x92/0x14d
+ [<c0450f94>] handle_IRQ_event+0x20/0x4d
+ [<c0451055>] __do_IRQ+0x94/0xef
+ [<c040678d>] do_IRQ+0x9e/0xbd
+ [<c0404a49>] common_interrupt+0x25/0x2c
+DWARF2 unwinder stuck at common_interrupt+0x25/0x2c
+
+Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Acked-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/rtc.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/drivers/char/rtc.c
++++ linux-2.6.18/drivers/char/rtc.c
+@@ -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;
+ }
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:35 2006
+Message-Id: <20061011204835.399677019@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:38 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ rientjes@cs.washington.edu,
+ clameter@sgi.com,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 42/67] do not free non slab allocated per_cpu_pageset
+Content-Disposition: inline; filename=do-not-free-non-slab-allocated-per_cpu_pageset.patch
+Status: RO
+Content-Length: 898
+Lines: 30
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Rientjes <rientjes@cs.washington.edu>
+
+Stops panic associated with attempting to free a non slab-allocated
+per_cpu_pageset.
+
+Signed-off-by: David Rientjes <rientjes@cs.washington.edu>
+Acked-by: Christoph Lameter <clameter@sgi.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/page_alloc.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/mm/page_alloc.c
++++ linux-2.6.18/mm/page_alloc.c
+@@ -1845,8 +1845,10 @@ static inline void free_zone_pagesets(in
+       for_each_zone(zone) {
+               struct per_cpu_pageset *pset = zone_pcp(zone, cpu);
++              /* Free per_cpu_pageset if it is slab allocated */
++              if (pset != &boot_pageset[cpu])
++                      kfree(pset);
+               zone_pcp(zone, cpu) = NULL;
+-              kfree(pset);
+       }
+ }
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:35 2006
+Message-Id: <20061011204835.534435062@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:39 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ olaf@aepfle.de,
+ daniel.thompson@st.com,
+ Michael Hanselmann <linux-kernel@hansmi.ch>,
+ "Antonino A. Daplas" <adaplas@pol.net>,
+ Jon Smirl <jonsmirl@gmail.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 43/67] backlight: fix oops in __mutex_lock_slowpath during head /sys/class/graphics/fb0/bits_per_pixel /sys/class/graphics/fb0/blank /sys/class/graphics/fb0/console /sys/class/graphics/fb0/cursor /sys/class/graphics/fb0/dev /sys/class/graphics/fb0/device /sys/class/graphics/fb0/mode /sys/class/graphics/fb0/modes /sys/class/graphics/fb0/name /sys/class/graphics/fb0/pan /sys/class/graphics/fb0/rotate /sys/class/graphics/fb0/state /sys/class/graphics/fb0/stride /sys/class/graphics/fb0/subsystem /sys/class/graphics/fb0/uevent /sys/class/graphics/fb0/virtual_size
+Content-Disposition: inline; filename=backlight-fix-oops-in-__mutex_lock_slowpath-during-head-sys-class-graphics-fb0.patch
+Status: RO
+Content-Length: 1499
+Lines: 47
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Michael Hanselmann <linux-kernel@hansmi.ch>
+
+Seems like not all drivers use the framebuffer_alloc() function and won't
+have an initialized mutex.  But those don't have a backlight, anyway.
+
+Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
+Cc: Olaf Hering <olaf@aepfle.de>
+Cc: "Antonino A. Daplas" <adaplas@pol.net>
+Cc: Daniel R Thompson <daniel.thompson@st.com>
+Cc: Jon Smirl <jonsmirl@gmail.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/video/fbsysfs.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- linux-2.6.18.orig/drivers/video/fbsysfs.c
++++ linux-2.6.18/drivers/video/fbsysfs.c
+@@ -397,6 +397,12 @@ static ssize_t store_bl_curve(struct cla
+       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;
+@@ -430,6 +436,12 @@ static ssize_t show_bl_curve(struct clas
+       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)
+               len += snprintf(&buf[len], PAGE_SIZE,
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:35 2006
+Message-Id: <20061011204835.680524921@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:40 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ tony.luck@intel.com,
+ KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 44/67] cpu to node relationship fixup: acpi_map_cpu2node
+Content-Disposition: inline; filename=cpu-to-node-relationship-fixup-acpi_map_cpu2node.patch
+Status: RO
+Content-Length: 1920
+Lines: 57
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+
+Problem description:
+
+  We have additional_cpus= option for allocating possible_cpus.  But nid
+  for possible cpus are not fixed at boot time.  cpus which is offlined at
+  boot or cpus which is not on SRAT is not tied to its node.  This will
+  cause panic at cpu onlining.
+
+Usually, pxm_to_nid() mapping is fixed at boot time by SRAT.
+
+But, unfortunately, some system (my system!) do not include
+full SRAT table for possible cpus.  (Then, I use
+additiona_cpus= option.)
+
+For such possible cpus, pxm<->nid should be fixed at
+hot-add.  We now have acpi_map_pxm_to_node() which is also
+used at boot.  It's suitable here.
+
+Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/ia64/kernel/acpi.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- linux-2.6.18.orig/arch/ia64/kernel/acpi.c
++++ linux-2.6.18/arch/ia64/kernel/acpi.c
+@@ -771,16 +771,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);
+ }
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:35 2006
+Message-Id: <20061011204835.821683328@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:41 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ tony.luck@intel.com,
+ KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 45/67] cpu to node relationship fixup: map cpu to node
+Content-Disposition: inline; filename=cpu-to-node-relationship-fixup-map-cpu-to-node.patch
+Status: RO
+Content-Length: 3368
+Lines: 111
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+
+Assume that a cpu is *physically* offlined at boot time...
+
+Because smpboot.c::smp_boot_cpu_map() canoot find cpu's sapicid,
+numa.c::build_cpu_to_node_map() cannot build cpu<->node map for
+offlined cpu.
+
+For such cpus, cpu_to_node map should be fixed at cpu-hot-add.
+This mapping should be done before cpu onlining.
+
+This patch also handles cpu hotremove case.
+
+Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/ia64/kernel/numa.c     |   34 +++++++++++++++++++++++++++++++---
+ arch/ia64/kernel/topology.c |    4 +++-
+ include/asm-ia64/numa.h     |    6 ++++++
+ 3 files changed, 40 insertions(+), 4 deletions(-)
+
+--- linux-2.6.18.orig/arch/ia64/kernel/numa.c
++++ linux-2.6.18/arch/ia64/kernel/numa.c
+@@ -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);
+       }
+ }
+--- linux-2.6.18.orig/arch/ia64/kernel/topology.c
++++ linux-2.6.18/arch/ia64/kernel/topology.c
+@@ -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);
+--- linux-2.6.18.orig/include/asm-ia64/numa.h
++++ linux-2.6.18/include/asm-ia64/numa.h
+@@ -64,7 +64,13 @@ extern int paddr_to_nid(unsigned long pa
+ #define local_nodeid (cpu_to_node_map[smp_processor_id()])
++extern void map_cpu_to_node(int cpu, int nid);
++extern void unmap_cpu_from_node(int cpu, int nid);
++
++
+ #else /* !CONFIG_NUMA */
++#define map_cpu_to_node(cpu, nid)     do{}while(0)
++#define unmap_cpu_from_node(cpu, nid) do{}while(0)
+ #define paddr_to_nid(addr)    0
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:36 2006
+Message-Id: <20061011204835.964407307@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:42 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ haveblue@us.ibm.com,
+ ak@suse.de,
+ apw@shadowen.org,
+ Keith Mannthey <kmannth@us.ibm.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 46/67] i386: fix flat mode numa on a real numa system
+Content-Disposition: inline; filename=i386-fix-flat-mode-numa-on-a-real-numa-system.patch
+Status: RO
+Content-Length: 1209
+Lines: 38
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: keith mannthey <kmannth@us.ibm.com>
+
+If there is only 1 node in the system cpus should think they are apart of
+some other node.
+
+If cases where a real numa system boots the Flat numa option make sure the
+cpus don't claim to be apart on a non-existent node.
+
+Signed-off-by: Keith Mannthey <kmannth@us.ibm.com>
+Cc: Andy Whitcroft <apw@shadowen.org>
+Cc: Dave Hansen <haveblue@us.ibm.com>
+Cc: Andi Kleen <ak@suse.de>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/i386/kernel/smpboot.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/arch/i386/kernel/smpboot.c
++++ linux-2.6.18/arch/i386/kernel/smpboot.c
+@@ -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)
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:36 2006
+Message-Id: <20061011204836.107282507@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:43 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Mark Huang <mlhuang@cs.princeton.edu>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 47/67] load_module: no BUG if module_subsys uninitialized
+Content-Disposition: inline; filename=load_module-no-bug-if-module_subsys-uninitialized.patch
+Status: RO
+Content-Length: 1729
+Lines: 46
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: "Ed Swierk" <eswierk@arastra.com>
+
+Invoking load_module() before param_sysfs_init() is called crashes in
+mod_sysfs_setup(), since the kset in module_subsys is not initialized yet.
+
+In my case, net-pf-1 is getting modprobed as a result of hotplug trying to
+create a UNIX socket.  Calls to hotplug begin after the topology_init
+initcall.
+
+Another patch for the same symptom (module_subsys-initialize-earlier.patch)
+moves param_sysfs_init() to the subsys initcalls, but this is still not
+early enough in the boot process in some cases.  In particular,
+topology_init() causes /sbin/hotplug to run, which requests net-pf-1 (the
+UNIX socket protocol) which can be compiled as a module.  Moving
+param_sysfs_init() to the postcore initcalls fixes this particular race,
+but there might well be other cases where a usermodehelper causes a module
+to load earlier still.
+
+The patch makes load_module() return an error rather than crashing the
+kernel if invoked before module_subsys is initialized.
+
+Cc: Mark Huang <mlhuang@cs.princeton.edu>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/module.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- linux-2.6.18.orig/kernel/module.c
++++ linux-2.6.18/kernel/module.c
+@@ -1054,6 +1054,12 @@ static int mod_sysfs_setup(struct module
+ {
+       int err;
++      if (!module_subsys.kset.subsys) {
++              printk(KERN_ERR "%s: module_subsys not initialized\n",
++                     mod->name);
++              err = -EINVAL;
++              goto out;
++      }
+       memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj));
+       err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name);
+       if (err)
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:36 2006
+Message-Id: <20061011204836.255315490@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:44 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ mchehab@infradead.org,
+ Jonathan Corbet <corbet@lwn.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 48/67] Fix VIDIOC_ENUMSTD bug
+Content-Disposition: inline; filename=fix-vidioc_enumstd-bug.patch
+Status: RO
+Content-Length: 1294
+Lines: 40
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jonathan Corbet <corbet-v4l@lwn.net>
+
+The v4l2 API documentation for VIDIOC_ENUMSTD says:
+
+       To enumerate all standards applications shall begin at index
+       zero, incrementing by one until the driver returns EINVAL.
+
+The actual code, however, tests the index this way:
+
+               if (index<=0 || index >= vfd->tvnormsize) {
+                        ret=-EINVAL;
+
+So any application which passes in index=0 gets EINVAL right off the bat
+- and, in fact, this is what happens to mplayer.  So I think the
+following patch is called for, and maybe even appropriate for a 2.6.18.x
+stable release.
+
+Signed-off-by: Jonathan Corbet <corbet@lwn.net>
+Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/media/video/videodev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/drivers/media/video/videodev.c
++++ linux-2.6.18/drivers/media/video/videodev.c
+@@ -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;
+               }
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:36 2006
+Message-Id: <20061011204836.389372053@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:45 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ bunk@stusta.de,
+ "David S. Miller" <davem@davemloft.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 49/67] SPARC64: Fix serious bug in sched_clock() on sparc64
+Content-Disposition: inline; filename=sparc64-fix-serious-bug-in-sched_clock-on-sparc64.patch
+Status: RO
+Content-Length: 1095
+Lines: 33
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David S. Miller <davem@davemloft.net>
+
+Unfortunately, sparc64 doesn't have an easy way to do a "64 X 64 -->
+128" bit multiply like PowerPC and IA64 do.  We were doing a
+"64 X 64 --> 64" bit multiple which causes overflow very quickly with
+a 30-bit quotient shift.
+
+So use a quotientshift count of 10 instead of 30, just like x86 and
+ARM do.
+
+This also fixes the wrapping of printk timestamp values every ~17
+seconds.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc64/kernel/time.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/arch/sparc64/kernel/time.c
++++ linux-2.6.18/arch/sparc64/kernel/time.c
+@@ -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();
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:36 2006
+Message-Id: <20061011204836.531921953@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:46 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 50/67] CPUFREQ: Fix some more CPU hotplug locking.
+Content-Disposition: inline; filename=cpufreq-fix-some-more-cpu-hotplug-locking.patch
+Status: RO
+Content-Length: 1577
+Lines: 47
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Dave Jones <davej@redhat.com>
+
+[CPUFREQ] Fix some more CPU hotplug locking.
+
+Lukewarm IQ detected in hotplug locking
+BUG: warning at kernel/cpu.c:38/lock_cpu_hotplug()
+[<b0134a42>] lock_cpu_hotplug+0x42/0x65
+[<b02f8af1>] cpufreq_update_policy+0x25/0xad
+[<b0358756>] kprobe_flush_task+0x18/0x40
+[<b0355aab>] schedule+0x63f/0x68b
+[<b01377c2>] __link_module+0x0/0x1f
+[<b0119e7d>] __cond_resched+0x16/0x34
+[<b03560bf>] cond_resched+0x26/0x31
+[<b0355b0e>] wait_for_completion+0x17/0xb1
+[<f965c547>] cpufreq_stat_cpu_callback+0x13/0x20 [cpufreq_stats]
+[<f9670074>] cpufreq_stats_init+0x74/0x8b [cpufreq_stats]
+[<b0137872>] sys_init_module+0x91/0x174
+[<b0102c81>] sysenter_past_esp+0x56/0x79
+
+As there are other places that call cpufreq_update_policy without
+the hotplug lock, it seems better to keep the hotplug locking
+at the lower level for the time being until this is revamped.
+
+Signed-off-by: Dave Jones <davej@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/cpufreq/cpufreq_stats.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- linux-2.6.18.orig/drivers/cpufreq/cpufreq_stats.c
++++ linux-2.6.18/drivers/cpufreq/cpufreq_stats.c
+@@ -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
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:36 2006
+Message-Id: <20061011204836.675165405@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:47 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ "David S. Miller" <davem@davemloft.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 51/67] IPV6: bh_lock_sock_nested on tcp_v6_rcv
+Content-Disposition: inline; filename=ipv6-bh_lock_sock_nested-on-tcp_v6_rcv.patch
+Status: RO
+Content-Length: 829
+Lines: 27
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Fabio Olive Leite <fleite@redhat.com>
+
+A while ago Ingo patched tcp_v4_rcv on net/ipv4/tcp_ipv4.c to use
+bh_lock_sock_nested and silence a lock validator warning. This fixed
+it for IPv4, but recently I saw a report of the same warning on IPv6.
+
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/tcp_ipv6.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/net/ipv6/tcp_ipv6.c
++++ linux-2.6.18/net/ipv6/tcp_ipv6.c
+@@ -1228,7 +1228,7 @@ process:
+       skb->dev = NULL;
+-      bh_lock_sock(sk);
++      bh_lock_sock_nested(sk);
+       ret = 0;
+       if (!sock_owned_by_user(sk)) {
+ #ifdef CONFIG_NET_DMA
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:36 2006
+Message-Id: <20061011204836.818905342@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:48 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ "David S. Miller" <davem@davemloft.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 52/67] SPARC64: Fix sparc64 ramdisk handling
+Content-Disposition: inline; filename=sparc64-fix-sparc64-ramdisk-handling.patch
+Status: RO
+Content-Length: 1542
+Lines: 38
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David S. Miller <davem@davemloft.net>
+
+[SPARC64]: Kill bogus check from bootmem_init().
+
+There is an ancient and totally incorrect sanity check being
+done on the ramdisk location.  The check assumes that the
+kernel is always loaded to physical address zero, which is
+wrong.  It was trying to validate the ramdisk value by saying that
+if it fell within the kernel image address range it must be wrong.
+
+Anyways, kill this because it actually creates problems.  The
+'ramdisk_image' should always be adjusted down by KERNBASE.
+SILO can easily put the ramdisk in a location which causes
+this test to trigger, breaking things.
+
+[ Based almost entirely upon a patch from Ben Collins. ]
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc64/mm/init.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/arch/sparc64/mm/init.c
++++ linux-2.6.18/arch/sparc64/mm/init.c
+@@ -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) {
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:37 2006
+Message-Id: <20061011204836.963651762@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:49 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 53/67] sata_mv: fix oops
+Content-Disposition: inline; filename=sata_mv-fix-oops.patch
+Status: RO
+Content-Length: 573
+Lines: 21
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jeff Garzik <jeff@garzik.org>
+
+From: Jeff Garzik <jeff@garzik.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/sata_mv.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- linux-2.6.18.orig/drivers/scsi/sata_mv.c
++++ linux-2.6.18/drivers/scsi/sata_mv.c
+@@ -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,
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:37 2006
+Message-Id: <20061011204837.107164911@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:50 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ bunk@stusta.de,
+ Kim Nordlund <kim.nordlund@nokia.com>,
+ Thomas Graf <tgraf@suug.ch>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 54/67] PKT_SCHED: cls_basic: Use unsigned int when generating handle
+Content-Disposition: inline; filename=pkt_sched-cls_basic-use-unsigned-int-when-generating-handle.patch
+Status: RO
+Content-Length: 931
+Lines: 30
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Miller <davem@davemloft.net>
+
+gcc-4.1 and later take advantage of the fact that in the
+C language certain types of overflow/underflow are undefined,
+and this is completely legitimate.
+
+Prevents filters from being added if the first generated
+handle already exists.
+
+Signed-off-by: Kim Nordlund <kim.nordlund@nokia.com>
+Signed-off-by: Thomas Graf <tgraf@suug.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/sched/cls_basic.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/net/sched/cls_basic.c
++++ linux-2.6.18/net/sched/cls_basic.c
+@@ -194,7 +194,7 @@ static int basic_change(struct tcf_proto
+       if (handle)
+               f->handle = handle;
+       else {
+-              int i = 0x80000000;
++              unsigned int i = 0x80000000;
+               do {
+                       if (++head->hgenerator == 0x7FFFFFFF)
+                               head->hgenerator = 1;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:37 2006
+Message-Id: <20061011204837.247280051@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:51 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Herbert Xu <herbert@gondor.apana.org.au>,
+ "David S. Miller" <davem@davemloft.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 55/67] IPV6: Disable SG for GSO unless we have checksum
+Content-Disposition: inline; filename=ipv6-disable-sg-for-gso-unless-we-have-checksum.patch
+Status: RO
+Content-Length: 917
+Lines: 28
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Miller <davem@davemloft.net>
+
+Because the system won't turn off the SG flag for us we
+need to do this manually on the IPv6 path.  Otherwise we
+will throw IPv6 packets with bad checksums at the hardware.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/ipv6_sockglue.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- linux-2.6.18.orig/net/ipv6/ipv6_sockglue.c
++++ linux-2.6.18/net/ipv6/ipv6_sockglue.c
+@@ -123,6 +123,9 @@ static struct sk_buff *ipv6_gso_segment(
+       struct ipv6hdr *ipv6h;
+       struct inet6_protocol *ops;
++      if (!(features & NETIF_F_HW_CSUM))
++              features &= ~NETIF_F_SG;
++
+       if (unlikely(skb_shinfo(skb)->gso_type &
+                    ~(SKB_GSO_UDP |
+                      SKB_GSO_DODGY |
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:37 2006
+Message-Id: <20061011204837.389923303@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:52 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+  <syrius.ml@no-log.org>,
+ "Richard Bollinger" <rabollinger@gmail.com>
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ linux-raid@vger.kernel.org,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 56/67] MD: Fix problem where hot-added drives are not resynced.
+Content-Disposition: inline; filename=md-fix-problem-where-hot-added-drives-are-not-resynced.patch
+Status: RO
+Content-Length: 824
+Lines: 28
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Neil Brown <neilb@suse.de>
+
+If a drive is added with HOT_ADD_DISK rather than ADD_NEW_DISK,
+saved_raid_disk isn't initialised properly, and the drive can be
+included in the array without a resync.
+
+
+From: Neil Brown <neilb@suse.de>
+Cc: <syrius.ml@no-log.org>
+Cc: Richard Bollinger <rabollinger@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/md.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- linux-2.6.18.orig/drivers/md/md.c
++++ linux-2.6.18/drivers/md/md.c
+@@ -3867,6 +3867,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;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:37 2006
+Message-Id: <20061011204837.534696866@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:53 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ John Heffner <jheffner@psc.edu>,
+ Stephen Hemminger <shemminger@osdl.org>,
+ "David S. Miller" <davem@davemloft.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 57/67] TCP: Fix and simplify microsecond rtt sampling
+Content-Disposition: inline; filename=tcp-fix-and-simplify-microsecond-rtt-sampling.patch
+Status: RO
+Content-Length: 2518
+Lines: 74
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: David Miller <davem@davemloft.net>
+
+This changes the microsecond RTT sampling so that samples are taken in
+the same way that RTT samples are taken for the RTO calculator: on the
+last segment acknowledged, and only when the segment hasn't been
+retransmitted.
+
+Signed-off-by: John Heffner <jheffner@psc.edu>
+Acked-by: Stephen Hemminger <shemminger@osdl.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/tcp_input.c |   16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- linux-2.6.18.orig/net/ipv4/tcp_input.c
++++ linux-2.6.18/net/ipv4/tcp_input.c
+@@ -2237,13 +2237,12 @@ static int tcp_tso_acked(struct sock *sk
+       return acked;
+ }
+-static u32 tcp_usrtt(const struct sk_buff *skb)
++static u32 tcp_usrtt(struct timeval *tv)
+ {
+-      struct timeval tv, now;
++      struct timeval now;
+       do_gettimeofday(&now);
+-      skb_get_timestamp(skb, &tv);
+-      return (now.tv_sec - tv.tv_sec) * 1000000 + (now.tv_usec - tv.tv_usec);
++      return (now.tv_sec - tv->tv_sec) * 1000000 + (now.tv_usec - tv->tv_usec);
+ }
+ /* Remove acknowledged frames from the retransmission queue. */
+@@ -2258,6 +2257,7 @@ static int tcp_clean_rtx_queue(struct so
+       u32 pkts_acked = 0;
+       void (*rtt_sample)(struct sock *sk, u32 usrtt)
+               = icsk->icsk_ca_ops->rtt_sample;
++      struct timeval tv;
+       while ((skb = skb_peek(&sk->sk_write_queue)) &&
+              skb != sk->sk_send_head) {
+@@ -2306,8 +2306,7 @@ static int tcp_clean_rtx_queue(struct so
+                               seq_rtt = -1;
+                       } else if (seq_rtt < 0) {
+                               seq_rtt = now - scb->when;
+-                              if (rtt_sample)
+-                                      (*rtt_sample)(sk, tcp_usrtt(skb));
++                              skb_get_timestamp(skb, &tv);
+                       }
+                       if (sacked & TCPCB_SACKED_ACKED)
+                               tp->sacked_out -= tcp_skb_pcount(skb);
+@@ -2320,8 +2319,7 @@ static int tcp_clean_rtx_queue(struct so
+                       }
+               } else if (seq_rtt < 0) {
+                       seq_rtt = now - scb->when;
+-                      if (rtt_sample)
+-                              (*rtt_sample)(sk, tcp_usrtt(skb));
++                      skb_get_timestamp(skb, &tv);
+               }
+               tcp_dec_pcount_approx(&tp->fackets_out, skb);
+               tcp_packets_out_dec(tp, skb);
+@@ -2333,6 +2331,8 @@ static int tcp_clean_rtx_queue(struct so
+       if (acked&FLAG_ACKED) {
+               tcp_ack_update_rtt(sk, acked, seq_rtt);
+               tcp_ack_packets_out(sk, tp);
++              if (rtt_sample && !(acked & FLAG_RETRANS_DATA_ACKED))
++                      (*rtt_sample)(sk, tcp_usrtt(&tv));
+               if (icsk->icsk_ca_ops->pkts_acked)
+                       icsk->icsk_ca_ops->pkts_acked(sk, pkts_acked);
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:37 2006
+Message-Id: <20061011204837.673051501@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:54 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ Andrew Morton <akpm@osdl.org>,
+ Linus Torvalds <torvalds@osdl.org>,
+ Peter Zijlstra <a.p.zijlstra@chello.nl>,
+ Linux Memory Management List <linux-mm@kvack.org>
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ alan@lxorguk.ukuu.org.uk,
+ Greg KH <gregkh@suse.de>,
+ Nick Piggin <npiggin@suse.de>
+Subject: [patch 58/67] mm: bug in set_page_dirty_buffers
+Content-Disposition: inline; filename=mm-bug-in-set_page_dirty_buffers.patch
+Status: RO
+Content-Length: 1335
+Lines: 39
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Nick Piggin <npiggin@suse.de>
+
+This was triggered, but not the fault of, the dirty page accounting
+patches. Suitable for -stable as well, after it goes upstream.
+
+Unable to handle kernel NULL pointer dereference at virtual address 0000004c
+EIP is at _spin_lock+0x12/0x66
+Call Trace:
+ [<401766e7>] __set_page_dirty_buffers+0x15/0xc0
+ [<401401e7>] set_page_dirty+0x2c/0x51
+ [<40140db2>] set_page_dirty_balance+0xb/0x3b
+ [<40145d29>] __do_fault+0x1d8/0x279
+ [<40147059>] __handle_mm_fault+0x125/0x951
+ [<401133f1>] do_page_fault+0x440/0x59f
+ [<4034d0c1>] error_code+0x39/0x40
+ [<08048a33>] 0x8048a33
+ =======================
+
+Signed-off-by: Nick Piggin <npiggin@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/buffer.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/fs/buffer.c
++++ linux-2.6.18/fs/buffer.c
+@@ -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)) {
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:37 2006
+Message-Id: <20061011204837.814723872@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:55 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ geert@linux-m68k.org,
+ adaplas@pol.net,
+  <jurij@wooyd.org>,
+ Willy Tarreau <w@1wt.eu>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 59/67] fbdev: correct buffer size limit in fbmem_read_proc()
+Content-Disposition: inline; filename=fbdev-correct-buffer-size-limit-in-fbmem_read_proc.patch
+Status: RO
+Content-Length: 987
+Lines: 32
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+Address http://bugzilla.kernel.org/show_bug.cgi?id=7189
+
+It should check `clen', not `len'.
+
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Cc: <jurij@wooyd.org>
+Cc: "Antonino A. Daplas" <adaplas@pol.net>
+Cc: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/video/fbmem.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- linux-2.6.18.orig/drivers/video/fbmem.c
++++ linux-2.6.18/drivers/video/fbmem.c
+@@ -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,
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:38 2006
+Message-Id: <20061011204837.955280674@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:56 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ jean-baptiste.maneyrol@teamlog.com,
+ Alessandro Zummo <a.zummo@towertech.it>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 60/67] rtc driver rtc-pcf8563 century bit inversed
+Content-Disposition: inline; filename=rtc-driver-rtc-pcf8563-century-bit-inversed.patch
+Status: RO
+Content-Length: 1385
+Lines: 37
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@teamlog.com>
+
+The century bit PCF8563_MO_C in the month register is misinterpreted.  It
+is set to 1 for the 20th century and 0 for 21th, and the driver is
+expecting the opposite behavior.
+
+Acked-by: Alessandro Zummo <a.zummo@towertech.it>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/rtc/rtc-pcf8563.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/drivers/rtc/rtc-pcf8563.c
++++ linux-2.6.18/drivers/rtc/rtc-pcf8563.c
+@@ -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;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:38 2006
+Message-Id: <20061011204838.098043390@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:57 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ nickpiggin@yahoo.com.au,
+ Chuck Lever <cel@citi.umich.edu>,
+ Peter Zijlstra <a.p.zijlstra@chello.nl>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 61/67] invalidate_inode_pages2(): ignore page refcounts
+Content-Disposition: inline; filename=invalidate_inode_pages2-ignore-page-refcounts.patch
+Status: RO
+Content-Length: 2706
+Lines: 83
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Andrew Morton <akpm@osdl.org>
+
+The recent fix to invalidate_inode_pages() (git commit 016eb4a) managed to
+unfix invalidate_inode_pages2().
+
+The problem is that various bits of code in the kernel can take transient refs
+on pages: the page scanner will do this when inspecting a batch of pages, and
+the lru_cache_add() batching pagevecs also hold a ref.
+
+Net result is transient failures in invalidate_inode_pages2().  This affects
+NFS directory invalidation (observed) and presumably also block-backed
+direct-io (not yet reported).
+
+Fix it by reverting invalidate_inode_pages2() back to the old version which
+ignores the page refcounts.
+
+We may come up with something more clever later, but for now we need a 2.6.18
+fix for NFS.
+
+Cc: Chuck Lever <cel@citi.umich.edu>
+Cc: Nick Piggin <nickpiggin@yahoo.com.au>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ mm/truncate.c |   34 ++++++++++++++++++++++++++++++++--
+ 1 file changed, 32 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/mm/truncate.c
++++ linux-2.6.18/mm/truncate.c
+@@ -270,9 +270,39 @@ unsigned long invalidate_inode_pages(str
+ {
+       return invalidate_mapping_pages(mapping, 0, ~0UL);
+ }
+-
+ EXPORT_SYMBOL(invalidate_inode_pages);
++/*
++ * This is like invalidate_complete_page(), except it ignores the page's
++ * refcount.  We do this because invalidate_inode_pages2() needs stronger
++ * invalidation guarantees, and cannot afford to leave pages behind because
++ * shrink_list() has a temp ref on them, or because they're transiently sitting
++ * in the lru_cache_add() pagevecs.
++ */
++static int
++invalidate_complete_page2(struct address_space *mapping, struct page *page)
++{
++      if (page->mapping != mapping)
++              return 0;
++
++      if (PagePrivate(page) && !try_to_release_page(page, 0))
++              return 0;
++
++      write_lock_irq(&mapping->tree_lock);
++      if (PageDirty(page))
++              goto failed;
++
++      BUG_ON(PagePrivate(page));
++      __remove_from_page_cache(page);
++      write_unlock_irq(&mapping->tree_lock);
++      ClearPageUptodate(page);
++      page_cache_release(page);       /* pagecache ref */
++      return 1;
++failed:
++      write_unlock_irq(&mapping->tree_lock);
++      return 0;
++}
++
+ /**
+  * invalidate_inode_pages2_range - remove range of pages from an address_space
+  * @mapping: the address_space
+@@ -339,7 +369,7 @@ int invalidate_inode_pages2_range(struct
+                               }
+                       }
+                       was_dirty = test_clear_page_dirty(page);
+-                      if (!invalidate_complete_page(mapping, page)) {
++                      if (!invalidate_complete_page2(mapping, page)) {
+                               if (was_dirty)
+                                       set_page_dirty(page);
+                               ret = -EIO;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:38 2006
+Message-Id: <20061011204838.239112168@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:58 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ torvalds@osdl.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ jim.cromie@gmail.com,
+ johnstul@us.ibm.com,
+  <alexander.krause@erazor-zone.de>,
+  <dzpost@dedekind.net>,
+  <phelps@mantara.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 62/67] scx200_hrt: fix precedence bug manifesting as 27x clock in 1 MHz mode
+Content-Disposition: inline; filename=scx200_hrt-fix-precedence-bug-manifesting-as-27x-clock-in-1-mhz-mode.patch
+Status: RO
+Content-Length: 1932
+Lines: 60
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jim Cromie <jim.cromie@gmail.com>
+
+Fix paren-placement / precedence bug breaking initialization for 1 MHz
+clock mode.
+
+Also fix comment spelling error, and fence-post (off-by-one) error on
+symbol used in request_region.
+
+Addresses http://bugzilla.kernel.org/show_bug.cgi?id=7242
+
+Thanks alexander.krause@erazor-zone.de, dzpost@dedekind.net, for the
+reports and patch test, and phelps@mantara.com for the independent patch
+and verification.
+
+Signed-off-by:  Jim Cromie <jim.cromie@gmail.com>
+Cc: <alexander.krause@erazor-zone.de>
+Cc: <dzpost@dedekind.net>
+Cc: <phelps@mantara.com>
+Acked-by: John Stultz <johnstul@us.ibm.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/clocksource/scx200_hrt.c |    4 ++--
+ include/linux/scx200.h           |    2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- linux-2.6.18.orig/drivers/clocksource/scx200_hrt.c
++++ linux-2.6.18/drivers/clocksource/scx200_hrt.c
+@@ -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) {
+--- linux-2.6.18.orig/include/linux/scx200.h
++++ linux-2.6.18/include/linux/scx200.h
+@@ -32,7 +32,7 @@ extern unsigned scx200_cb_base;
+ /* High Resolution Timer */
+ #define SCx200_TIMER_OFFSET 0x08
+-#define SCx200_TIMER_SIZE 0x05
++#define SCx200_TIMER_SIZE 0x06
+ /* Clock Generators */
+ #define SCx200_CLOCKGEN_OFFSET 0x10
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:38 2006
+Message-Id: <20061011204838.381432191@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:48:59 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org,
+ mm-commits@vger.kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 63/67] ide-generic: jmicron fix
+Content-Disposition: inline; filename=ide-generic-jmicron-fix.patch
+Status: RO
+Content-Length: 1335
+Lines: 38
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+
+Some people find their Jmicron pata port reports its disabled even
+though it has devices on it and was boot probed. Fix this
+
+(Candidate for 2.6.18.*, less so for 2.6.19 as we've got a proper
+jmicron driver on the merge for that to replace ide-generic support)
+
+From: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/ide/pci/generic.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- linux-2.6.18.orig/drivers/ide/pci/generic.c
++++ linux-2.6.18/drivers/ide/pci/generic.c
+@@ -245,10 +245,12 @@ static int __devinit generic_init_one(st
+       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) {
++              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:
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:38 2006
+Message-Id: <20061011204838.523281018@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:49:00 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+  <muli@il.ibm.com>,
+  <ak@suse.de>,
+ Jon Mason <jdmason@kudzu.us>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 64/67] x86-64: Calgary IOMMU: Fix off by one when calculating register space location
+Content-Disposition: inline; filename=x86-64-calgary-iommu-fix-off-by-one-when-calculating-register-space-location.patch
+Status: RO
+Content-Length: 2407
+Lines: 57
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Jon Mason <jdmason@kudzu.us>
+
+This patch has already been submitted for inclusion in the 2.6.19
+tree, but not backported to the 2.6.18.  Please pull the bug fix
+below into the stable tree for the 2.6.18.1 release.
+
+The purpose of the code being modified is to determine the location
+of the calgary chip address space.  This is done by a magical formula
+of FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase) to
+find the offset where BIOS puts it.  In this formula,
+OneBasedChassisNumber corresponds to the NUMA node, and rionodeid is
+always 2 or 3 depending on which chip in the system it is.  The
+problem was that we had an off by one error that caused us to account
+some busses to the wrong chip and thus give them the wrong address
+space.
+
+Fixes RH bugzilla #203971.
+
+Signed-off-by: Jon Mason <jdmason@kudzu.us>
+Signed-off-by: Muli Ben-Yehuda <muli@il.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86_64/kernel/pci-calgary.c |   13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/arch/x86_64/kernel/pci-calgary.c
++++ linux-2.6.18/arch/x86_64/kernel/pci-calgary.c
+@@ -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;
+ }
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:38 2006
+Message-Id: <20061011204838.670898799@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:49:01 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Larry Finger <Larry.Finger@lwfinger.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 65/67] bcm43xx: fix regressions in 2.6.18
+Content-Disposition: inline; filename=bcm43xx-fix-regressions-in-2.6.18.patch
+Status: RO
+Content-Length: 132992
+Lines: 4180
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+The bcm43xx code in 2.6.18 has a serious problems not found in 2.6.17, due to
+a change in the locking mechanism introduced to reduce latency. The following patch
+fixes the problems in locking, reduces the latency associated with the periodic
+work tasklet, and contains code needed for those cards that use 64-bit DMA.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/bcm43xx/bcm43xx.h         |  181 ++---
+ drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c |   80 +-
+ drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h |    1 
+ drivers/net/wireless/bcm43xx/bcm43xx_dma.c     |  583 ++++++++++------
+ drivers/net/wireless/bcm43xx/bcm43xx_dma.h     |  296 ++++++--
+ drivers/net/wireless/bcm43xx/bcm43xx_leds.c    |   10 
+ drivers/net/wireless/bcm43xx/bcm43xx_main.c    |  905 ++++++++++++++-----------
+ drivers/net/wireless/bcm43xx/bcm43xx_main.h    |    6 
+ drivers/net/wireless/bcm43xx/bcm43xx_phy.c     |   48 -
+ drivers/net/wireless/bcm43xx/bcm43xx_pio.c     |    4 
+ drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c   |   46 -
+ drivers/net/wireless/bcm43xx/bcm43xx_wx.c      |  121 +--
+ 12 files changed, 1426 insertions(+), 855 deletions(-)
+
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx.h
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx.h
+@@ -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
+@@ -283,6 +306,13 @@
+ #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];
+@@ -763,55 +812,6 @@ struct bcm43xx_private {
+ };
+-/*    *** 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
+ struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
+ {
+@@ -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);
+ }
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
+@@ -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;
+ }
+@@ -339,6 +385,11 @@ static struct file_operations txstat_fop
+       .open = open_file_generic,
+ };
++static struct file_operations restart_fops = {
++      .write = restart_write_file,
++      .open = open_file_generic,
++};
++
+ void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
+ {
+@@ -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);
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
+@@ -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;
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+@@ -4,7 +4,7 @@
+   DMA ringbuffer and descriptor allocation/management
+-  Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
++  Copyright (c) 2005, 2006 Michael Buesch <mbuesch@freenet.de>
+   Some code in this file is derived from the b44.c driver
+   Copyright (C) 2002 David S. Miller
+@@ -109,6 +109,35 @@ void return_slot(struct bcm43xx_dmaring 
+       }
+ }
++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
+ dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
+                         unsigned char *buf,
+@@ -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;
++      u16 offset;
+-      bcm43xx_write32(bcm,
+-                      mmio_base + BCM43xx_DMA_RX_CONTROL,
+-                      0x00000000);
++      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 setup_rx_descbuffer(struct bc
+ 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 @@ out:
+ 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);
++                                      ring->rx_buffersize, 0);
+               }
+-              free_descriptor_buffer(ring, desc, meta, 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;
++              dma->rx_ring3 = ring;
+       }
+-      dprintk(KERN_INFO PFX "DMA initialized\n");
++      dprintk(KERN_INFO PFX "%s DMA initialized\n",
++                      dma64 ? "64-bit" : "32-bit");
+       err = 0;
+ out:
+       return err;
+@@ -605,6 +764,12 @@ out:
+ 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 @@ err_destroy_tx0:
+ 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,21 +797,25 @@ 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);
+       cookie |= (u16)slot;
+@@ -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 @@ struct bcm43xx_dmaring * parse_cookie(st
+ 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)));
++      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 int dma_tx_fragment(struct bcm43xx_dmaring *ring,
+-                         struct sk_buff *skb,
+-                         u8 cur_frag)
++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;
+-      }
++      dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
++      meta->dmaaddr = dmaaddr;
+-      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;
++      fill_descriptor(ring, desc, dmaaddr,
++                      skb->len, 1, 1, 1);
+-      set_desc_ctl(desc, desc_ctl);
+-      set_desc_addr(desc, desc_addr);
+       /* 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;
++              desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
+-              is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND);
++              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 @@ void bcm43xx_dma_handle_xmitstatus(struc
+ 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);
+ }
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
+@@ -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. */
+@@ -86,17 +202,6 @@ 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. */
+       struct sk_buff *skb;
+@@ -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;
+-      /* (Unadjusted) DMA base bus-address of the ring memory. */
+-      dma_addr_t dmabase;
++      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;
+       /* 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 @@ int bcm43xx_dma_init(struct bcm43xx_priv
+ 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;
+ }
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+@@ -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);
+ }
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+@@ -509,23 +509,20 @@ 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,20 +576,11 @@ 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;
+ err_unsupported_radio:
+@@ -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);
+@@ -1399,6 +1383,7 @@ void bcm43xx_wireless_core_reset(struct 
+               if (bcm->current_core->rev < 5)
+                       bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
+ #endif
++#endif
+       }
+       if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
+               bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+@@ -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)
+@@ -1581,17 +1546,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 +1664,9 @@ static void handle_irq_beacon(struct bcm
+ 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 +1676,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 +1692,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 +1745,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 +1752,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 +1790,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 +1819,18 @@ static void bcm43xx_interrupt_ack(struct
+       bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
+-      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
++      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
+                       bcm->dma_reason[0]);
+-      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
++      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
+                       bcm->dma_reason[1]);
+-      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
++      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
+                       bcm->dma_reason[2]);
+-      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
++      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
+                       bcm->dma_reason[3]);
++      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
++                      bcm->dma_reason[4]);
++      bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
++                      bcm->dma_reason[5]);
+ }
+ /* Interrupt handler top-half */
+@@ -1885,14 +1845,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 +1858,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 +1888,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 +1910,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 +1923,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 +1937,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 +1968,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 +2003,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 +2030,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 +2045,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 +2092,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 +2118,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 +2135,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 +2238,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 +2257,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);
++      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");
+       }
+-      printkl(KERN_ERR PFX "MAC suspend failed\n");
++out:
++      bcm->mac_suspended++;
+ }
+ void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
+@@ -2394,7 +2343,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 +2354,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 +2367,53 @@ static int bcm43xx_chip_init(struct bcm4
+               goto out;
+       bcm43xx_upload_microcode(bcm);
+-      err = bcm43xx_initialize_irq(bcm);
+-      if (err)
++      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_free_irq;
++              goto err_release_fw;
+       err = bcm43xx_upload_initvals(bcm);
+       if (err)
+@@ -2489,10 +2477,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 +2499,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 +2538,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 +2548,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 +2570,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 +2739,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 +2840,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 +2923,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;
+@@ -3066,11 +3057,6 @@ 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)
+ {
+       struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
+@@ -3178,51 +3164,43 @@ static void bcm43xx_periodic_work_handle
+       int badness;
+       badness = estimate_periodic_work_badness(bcm->periodic_state);
++      mutex_lock(&bcm->mutex);
++      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);
++              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);
+ }
+-static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
++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 +3221,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 +3249,329 @@ static int bcm43xx_rng_init(struct bcm43
+       return err;
+ }
+-/* This is the opposite of bcm43xx_init_board() */
+-static void bcm43xx_free_board(struct bcm43xx_private *bcm)
++static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
+ {
++      int ret = 0;
+       int i, err;
++      struct bcm43xx_coreinfo *core;
+-      bcm43xx_lock_noirq(bcm);
++      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)
++{
++      bcm43xx_rng_exit(bcm);
+       bcm43xx_sysfs_unregister(bcm);
+       bcm43xx_periodic_tasks_delete(bcm);
+-      bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
++      mutex_lock(&(bcm)->mutex);
++      bcm43xx_shutdown_all_wireless_cores(bcm);
++      bcm43xx_pctl_set_crystal(bcm, 0);
++      mutex_unlock(&(bcm)->mutex);
++}
+-      bcm43xx_rng_exit(bcm);
++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)
+-                      continue;
+-              if (!bcm->core_80211[i].initialized)
++              core = &(bcm->core_80211[i]);
++              wlext = core->priv;
++
++              if (!core->available)
+                       continue;
++              assert(wlext == &(bcm->core_80211_ext[i]));
+-              err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
+-              assert(err == 0);
+-              bcm43xx_wireless_core_cleanup(bcm);
++              prepare_phydata_for_init(&wlext->phy);
++              prepare_radiodata_for_init(bcm, &wlext->radio);
+       }
+-      bcm43xx_pctl_set_crystal(bcm, 0);
++      /* IRQ related flags */
++      bcm->irq_reason = 0;
++      memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
++      bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
+-      bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
+-      bcm43xx_unlock_noirq(bcm);
++      bcm->mac_suspended = 1;
++
++      /* Noise calculation context */
++      memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
++
++      /* Periodic work context */
++      bcm->periodic_state = 0;
+ }
+-static int bcm43xx_init_board(struct bcm43xx_private *bcm)
++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;
+-      int connect_phy;
++      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();
+-      bcm43xx_lock_noirq(bcm);
+-      bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
++      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_crystal(bcm, 1);
+-      if (err)
+-              goto out;
+-      err = bcm43xx_pctl_init(bcm);
+-      if (err)
+-              goto err_crystal_off;
+       err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
+       if (err)
+-              goto err_crystal_off;
++              goto error;
+-      tasklet_enable(&bcm->isr_tasklet);
++      /* Mark all unused cores "inactive". */
+       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;
++              core = &(bcm->core_80211[i]);
++              wlext = core->priv;
+-              /* 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 (core == active_core)
++                      continue;
++              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;
++      }
+-              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;
++      /* 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;
+-              if (i != 0) {
+-                      bcm43xx_mac_suspend(bcm);
+-                      bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
+-                      bcm43xx_radio_turn_off(bcm);
+-              }
++              sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
++              sbtmstatelow |= 0x20000000;
++              bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
+       }
+-      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 = 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_rng_init(bcm);
++      err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
+       if (err)
+-              goto err_80211_unwind;
++              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));
+-      dprintk(KERN_INFO PFX "80211 cores initialized\n");
+       bcm43xx_security_init(bcm);
+-      bcm43xx_softmac_init(bcm);
++      ieee80211softmac_start(bcm->net_dev);
+-      bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
++      /* 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);
+-      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);
+-      }
++      dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
++              active_wlext->phy.type);
+-      /* Initialization of the board is done. Flag it as such. */
+-      bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
++      return 0;
++
++error:
++      bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
++      bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
++      return err;
++}
++static int bcm43xx_init_board(struct bcm43xx_private *bcm)
++{
++      int err;
++
++      mutex_lock(&(bcm)->mutex);
++
++      tasklet_enable(&bcm->isr_tasklet);
++      err = bcm43xx_pctl_set_crystal(bcm, 1);
++      if (err)
++              goto err_tasklet;
++      err = bcm43xx_pctl_init(bcm);
++      if (err)
++              goto err_crystal_off;
++      err = bcm43xx_select_wireless_core(bcm, -1);
++      if (err)
++              goto err_crystal_off;
++      err = bcm43xx_sysfs_register(bcm);
++      if (err)
++              goto err_wlshutdown;
++      err = bcm43xx_rng_init(bcm);
++      if (err)
++              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 +3815,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 +3825,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 +3840,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 +3910,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 +3923,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);
++      spin_unlock_irqrestore(&bcm->irq_lock, flags);
+-      return err;
++      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 +3943,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 +3955,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 +3974,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 +3994,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 +4118,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 +4127,31 @@ static void __devexit bcm43xx_remove_one
+ 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);
++      struct bcm43xx_phyinfo *phy;
++      int err = -ENODEV;
+-      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;
++      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);
+       }
+-      netif_wake_queue(bcm->net_dev);
+-      printk(KERN_INFO PFX "Controller restarted\n");
++      mutex_unlock(&(bcm)->mutex);
+-      return;
+-failure:
+-      printk(KERN_ERR PFX "Controller restart failed\n");
++      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 +4163,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 +4205,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;
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.h
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_main.h
+@@ -133,11 +133,17 @@ 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);
+ int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom);
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+@@ -81,6 +81,16 @@ static const s8 bcm43xx_tssi2dbm_g_table
+ 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_write(struct bcm43xx_pr
+ 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");
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
+@@ -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)
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
+@@ -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);
++      mutex_unlock(&bcm->mutex);
+-      return err ? err : count;
++      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);
++      mutex_unlock(&bcm->mutex);
+-      return err ? err : count;
++      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);
++      spin_unlock_irqrestore(&bcm->irq_lock, flags);
++      mutex_unlock(&bcm->mutex);
+-      return err ? err : count;
++      return count;
+ }
+ static DEVICE_ATTR(shortpreamble, 0644,
+--- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
++++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+@@ -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:
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:38 2006
+Message-Id: <20061011204838.820391023@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:49:02 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Patrick McHardy <kaber@trash.net>,
+ "David S. Miller" <davem@davemloft.net>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 66/67] NETFILTER: NAT: fix NOTRACK checksum handling
+Content-Disposition: inline; filename=netfilter-nat-fix-notrack-checksum-handling.patch
+Status: RO
+Content-Length: 2426
+Lines: 66
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+
+From: Patrick McHardy <kaber@trash.net>
+
+The whole idea with the NOTRACK netfilter target is that
+you can force the netfilter code to avoid connection
+tracking, and all costs assosciated with it, by making
+traffic match a NOTRACK rule.
+
+But this is totally broken by the fact that we do a checksum
+calculation over the packet before we do the NOTRACK bypass
+check, which is very expensive.  People setup NOTRACK rules
+explicitly to avoid all of these kinds of costs.
+
+This patch from Patrick, already in Linus's tree, fixes the
+bug.
+
+Move the check for ip_conntrack_untracked before the call to
+skb_checksum_help to fix NOTRACK excemptions from NAT. Pre-2.6.19
+NAT code breaks TSO by invalidating hardware checksums for every
+packet, even if explicitly excluded from NAT through NOTRACK.
+
+2.6.19 includes a fix that makes NAT and TSO live in harmony,
+but the performance degradation caused by this deserves making
+at least the workaround work properly in -stable.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/netfilter/ip_nat_standalone.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- linux-2.6.18.orig/net/ipv4/netfilter/ip_nat_standalone.c
++++ linux-2.6.18/net/ipv4/netfilter/ip_nat_standalone.c
+@@ -110,12 +110,17 @@ ip_nat_fn(unsigned int hooknum,
+       IP_NF_ASSERT(!((*pskb)->nh.iph->frag_off
+                      & htons(IP_MF|IP_OFFSET)));
++      ct = ip_conntrack_get(*pskb, &ctinfo);
++
++      /* Don't try to NAT if this packet is not conntracked */
++      if (ct == &ip_conntrack_untracked)
++              return NF_ACCEPT;
++
+       /* If we had a hardware checksum before, it's now invalid */
+       if ((*pskb)->ip_summed == CHECKSUM_HW)
+               if (skb_checksum_help(*pskb, (out == NULL)))
+                       return NF_DROP;
+-      ct = ip_conntrack_get(*pskb, &ctinfo);
+       /* Can't track?  It's not due to stress, or conntrack would
+          have dropped it.  Hence it's the user's responsibilty to
+          packet filter it out, or implement conntrack/NAT for that
+@@ -137,10 +142,6 @@ ip_nat_fn(unsigned int hooknum,
+               return NF_ACCEPT;
+       }
+-      /* Don't try to NAT if this packet is not conntracked */
+-      if (ct == &ip_conntrack_untracked)
+-              return NF_ACCEPT;
+-
+       switch (ctinfo) {
+       case IP_CT_RELATED:
+       case IP_CT_RELATED+IP_CT_IS_REPLY:
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:39 2006
+Message-Id: <20061011204838.964518038@quad.kroah.org>
+References: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:49:03 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk,
+ Vasily Tarasov <vtaras@openvz.org>,
+ Jens Axboe <jens.axboe@oracle.com>,
+ Greg Kroah-Hartman <gregkh@suse.de>
+Subject: [patch 67/67] block layer: elv_iosched_show should get elv_list_lock
+Content-Disposition: inline; filename=block-layer-elv_iosched_show-should-get-elv_list_lock.patch
+Status: RO
+Content-Length: 1172
+Lines: 40
+
+
+-stable review patch.  If anyone has any objections, please let us know.
+
+------------------
+From: Vasily Tarasov <vtaras@openvz.org>
+
+elv_iosched_show function iterates other elv_list,
+hence elv_list_lock should be got.
+
+Also the question is: in elv_iosched_show, elv_iosched_store
+q->elevator->elevator_type construction is used without locking q->queue_lock.
+Is it expected?..
+
+Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
+Cc: Jens Axboe <jens.axboe@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ block/elevator.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.18.orig/block/elevator.c
++++ linux-2.6.18/block/elevator.c
+@@ -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;
+
+--
+
+From greg@quad.kroah.org Wed Oct 11 13:48:29 2006
+Message-Id: <20061011204756.642936754@quad.kroah.org>
+User-Agent: quilt/0.45-1
+Date: Wed, 11 Oct 2006 13:47:56 -0700
+From: Greg KH <gregkh@suse.de>
+To: linux-kernel@vger.kernel.org,
+ stable@kernel.org
+Cc: Justin Forbes <jmforbes@linuxtx.org>,
+ Zwane Mwaikambo <zwane@arm.linux.org.uk>,
+ Theodore Ts'o <tytso@mit.edu>,
+ Randy Dunlap <rdunlap@xenotime.net>,
+ Dave Jones <davej@redhat.com>,
+ Chuck Wolber <chuckw@quantumlinux.com>,
+ Chris Wedgwood <reviews@ml.cw.f00f.org>,
+ Michael Krufky <mkrufky@linuxtv.org>,
+ torvalds@osdl.org,
+ akpm@osdl.org,
+ alan@lxorguk.ukuu.org.uk
+Subject: [patch 00/67] 2.6.18-stable review
+Status: RO
+Content-Length: 1211
+Lines: 27
+
+This is the start of the stable review cycle for the 2.6.18.1 release.
+There are 67 patches in this series, all will be posted as a response to
+this one.  If anyone has any issues with these being applied, please let
+us know.  If anyone is a maintainer of the proper subsystem, and wants
+to add a Signed-off-by: line to the patch, please respond with it.
+
+These patches are sent out with a number of different people on the Cc:
+line.  If you wish to be a reviewer, please email stable@kernel.org to
+add your name to the list.  If you want to be off the reviewer list,
+also email us.
+
+Responses should be made by Friday, October 13, 20:00:00 UTC.  Anything
+received after that time might be too late.
+
+And yes, we realize that this is a large number of patches, sorry, we
+have been a bit slow in responding lately.  If there are any patches
+that have been sent to us for the 2.6.18-stable tree, that are not in
+this series, please resend them, as we think we are finally caught up
+with this work.
+
+An all-in-one patch for this series can be found at:
+       http://www.kernel.org/pub/linux/kernel/people/gregkh/stable/patch-2.6.18.1-rc1.gz
+if anyone wants to test this out that way.
+
+thanks,
+
+the -stable release team
+
similarity index 100%
rename from queue-2.6.18/series
rename to review-2.6.18/series