Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2009-11-20 19:18:16 +0100
committerMichal Marek <mmarek@suse.cz>2009-11-20 19:18:16 +0100
commitdb6d82b45ff086d7d539a7ace36d5762d2d45f53 (patch)
treefdc3cbfe30e196542689b72d34e5f3b7f4c4eed5
parentdac526a62b9511052de51513c614c345959d18a2 (diff)
parente89dd117da49d32ef9c0c49bf15e3b26d14b74f9 (diff)
Merge branch 'master' into SLE11-SP1
-rw-r--r--kernel-source.changes199
-rw-r--r--patches.arch/s390-message-catalog.diff2
-rw-r--r--patches.drivers/aacraid-24701-update2
-rw-r--r--patches.drivers/bnx2-entropy-source.patch42
-rw-r--r--patches.drivers/e1000-entropy-source.patch49
-rw-r--r--patches.drivers/e1000e-entropy-source.patch90
-rw-r--r--patches.drivers/igb-add-support-for-82576NS-SerDes-adapter.patch56
-rw-r--r--patches.drivers/igb-entropy-source.patch73
-rw-r--r--patches.drivers/ixgbe-entropy-source.patch92
-rw-r--r--patches.drivers/megaraid-04.12-update1572
-rw-r--r--patches.drivers/phy-broadcom-bug-fixes-for-sp1.patch382
-rw-r--r--patches.drivers/tg3-entropy-source.patch63
-rw-r--r--patches.drivers/tg3-update-version-to-3.104.patch2446
-rw-r--r--patches.fixes/scsi-fix-bug-with-dma-maps-on-nested-scsi-objects153
-rw-r--r--patches.fixes/scsi-introduce-helper-function-for-blocking-eh248
-rw-r--r--patches.fixes/scsi-skip-nonscsi-device-for-dma106
-rw-r--r--patches.suse/crasher-26.diff14
-rw-r--r--patches.suse/export-sync_page_range189
-rw-r--r--patches.suse/init-move-populate_rootfs-back-to-start_kernel20
-rw-r--r--patches.suse/kdb-common128
-rw-r--r--patches.suse/kdb-ia64114
-rw-r--r--patches.suse/kdb-x8630
-rw-r--r--patches.suse/ocfs2-allocation-resrvations.patch2
-rw-r--r--patches.suse/perfmon2.patch420
-rw-r--r--patches.suse/perfmon2_ioctl.patch2
-rw-r--r--patches.suse/rlim-0001-SECURITY-selinux-fix-update_rlimit_cpu-parameter.patch31
-rw-r--r--patches.suse/rlim-0002-SECURITY-add-task_struct-to-setrlimit.patch113
-rw-r--r--patches.suse/rlim-0003-core-add-task_struct-to-update_rlimit_cpu.patch75
-rw-r--r--patches.suse/rlim-0004-sys_setrlimit-make-sure-rlim_max-never-grows.patch65
-rw-r--r--patches.suse/rlim-0005-core-split-sys_setrlimit.patch112
-rw-r--r--patches.suse/rlim-0006-core-allow-setrlimit-to-non-current-tasks.patch55
-rw-r--r--patches.suse/rlim-0007-core-optimize-setrlimit-for-current-task.patch49
-rw-r--r--patches.suse/rlim-0008-FS-proc-make-limits-writable.patch123
-rw-r--r--patches.suse/rlim-0009-core-posix-cpu-timers-cleanup-rlimits-usage.patch116
-rw-r--r--patches.suse/rlim-0010-core-do-security-check-under-task_lock.patch59
-rw-r--r--patches.suse/rlim-0011-resource-add-helpers-for-fetching-rlimits.patch54
-rw-r--r--patches.suse/rlim-0012-IA64-use-helpers-for-rlimits.patch58
-rw-r--r--patches.suse/rlim-0013-PPC-use-helpers-for-rlimits.patch57
-rw-r--r--patches.suse/rlim-0014-S390-use-helpers-for-rlimits.patch46
-rw-r--r--patches.suse/rlim-0015-SPARC-use-helpers-for-rlimits.patch56
-rw-r--r--patches.suse/rlim-0016-X86-use-helpers-for-rlimits.patch59
-rw-r--r--patches.suse/rlim-0017-FS-use-helpers-for-rlimits.patch155
-rw-r--r--patches.suse/rlim-0018-MM-use-helpers-for-rlimits.patch158
-rw-r--r--patches.suse/rlim-0019-core-use-helpers-for-rlimits.patch191
-rw-r--r--patches.suse/rlim-0020-misc-use-helpers-for-rlimits.patch75
-rw-r--r--patches.suse/rlim-0021-core-rename-setrlimit-to-do_setrlimit.patch63
-rw-r--r--patches.suse/rlim-0022-core-implement-getprlimit-and-setprlimit-syscalls.patch142
-rw-r--r--patches.suse/rlim-0023-unistd-add-__NR_-get-set-prlimit-syscall-numbers.patch76
-rw-r--r--patches.suse/rlim-0024-COMPAT-add-get-put_compat_rlimit.patch105
-rw-r--r--patches.suse/rlim-0025-x86-add-ia32-compat-prlimit-syscalls.patch69
-rw-r--r--patches.suse/stack-unwind4
-rw-r--r--rpm/macros.kernel-source1
-rwxr-xr-xscripts/sequence-patch.sh2
-rw-r--r--series.conf45
54 files changed, 8163 insertions, 545 deletions
diff --git a/kernel-source.changes b/kernel-source.changes
index 250bd80be8..b36ac1b56c 100644
--- a/kernel-source.changes
+++ b/kernel-source.changes
@@ -4,6 +4,205 @@ Fri Nov 20 17:54:23 CET 2009 - mmarek@suse.cz
- config.conf: Remove the -desktop flavor from kernel-syms.
-------------------------------------------------------------------
+Fri Nov 20 17:29:45 CET 2009 - mmarek@suse.cz
+
+- patches.suse/export-sync_page_range: Revert "vfs: Remove
+ generic_osync_inode() and sync_page_range{_nolock}()"
+ (bnc#557231).
+
+-------------------------------------------------------------------
+Fri Nov 20 17:26:01 CET 2009 - jbeulich@novell.com
+
+- patches.suse/init-move-populate_rootfs-back-to-start_kernel:
+ Fix a bad-pointer warning.
+
+-------------------------------------------------------------------
+Fri Nov 20 15:07:41 CET 2009 - agruen@suse.de
+
+- rpm/macros.kernel-source: Add kernel_module_package_moddir()
+ macro for cross-distro compatibility (FATE 305225).
+
+-------------------------------------------------------------------
+Fri Nov 20 15:02:22 CET 2009 - jslaby@suse.cz
+
+- patches.suse/rlim-0001-SECURITY-selinux-fix-update_rlimit_cpu-parameter.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0002-SECURITY-add-task_struct-to-setrlimit.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0003-core-add-task_struct-to-update_rlimit_cpu.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0004-sys_setrlimit-make-sure-rlim_max-never-grows.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0005-core-split-sys_setrlimit.patch: Update
+ references (FATE#305733).
+- patches.suse/rlim-0006-core-allow-setrlimit-to-non-current-tasks.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0007-core-optimize-setrlimit-for-current-task.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0008-FS-proc-make-limits-writable.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0009-core-posix-cpu-timers-cleanup-rlimits-usage.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0010-core-do-security-check-under-task_lock.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0011-resource-add-helpers-for-fetching-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0012-IA64-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0013-PPC-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0014-S390-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0015-SPARC-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0016-X86-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0017-FS-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0018-MM-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0019-core-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0020-misc-use-helpers-for-rlimits.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0021-core-rename-setrlimit-to-do_setrlimit.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0022-core-implement-getprlimit-and-setprlimit-syscalls.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0023-unistd-add-__NR_-get-set-prlimit-syscall-numbers.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0024-COMPAT-add-get-put_compat_rlimit.patch:
+ Update references (FATE#305733).
+- patches.suse/rlim-0025-x86-add-ia32-compat-prlimit-syscalls.patch:
+ Update references (FATE#305733).
+
+-------------------------------------------------------------------
+Fri Nov 20 14:38:38 CET 2009 - jslaby@suse.cz
+
+- Add writable resource limits support
+- patches.suse/perfmon2.patch: Refresh.
+- patches.suse/rlim-0001-SECURITY-selinux-fix-update_rlimit_cpu-parameter.patch:
+ SECURITY: selinux, fix update_rlimit_cpu parameter.
+- patches.suse/rlim-0002-SECURITY-add-task_struct-to-setrlimit.patch:
+ SECURITY: add task_struct to setrlimit.
+- patches.suse/rlim-0003-core-add-task_struct-to-update_rlimit_cpu.patch:
+ core: add task_struct to update_rlimit_cpu.
+- patches.suse/rlim-0004-sys_setrlimit-make-sure-rlim_max-never-grows.patch:
+ sys_setrlimit: make sure ->rlim_max never grows.
+- patches.suse/rlim-0005-core-split-sys_setrlimit.patch: core:
+ split sys_setrlimit.
+- patches.suse/rlim-0006-core-allow-setrlimit-to-non-current-tasks.patch:
+ core: allow setrlimit to non-current tasks.
+- patches.suse/rlim-0007-core-optimize-setrlimit-for-current-task.patch:
+ core: optimize setrlimit for current task.
+- patches.suse/rlim-0008-FS-proc-make-limits-writable.patch:
+ FS: proc, make limits writable.
+- patches.suse/rlim-0009-core-posix-cpu-timers-cleanup-rlimits-usage.patch:
+ core: posix-cpu-timers, cleanup rlimits usage.
+- patches.suse/rlim-0010-core-do-security-check-under-task_lock.patch:
+ core: do security check under task_lock.
+- patches.suse/rlim-0011-resource-add-helpers-for-fetching-rlimits.patch:
+ resource: add helpers for fetching rlimits.
+- patches.suse/rlim-0012-IA64-use-helpers-for-rlimits.patch:
+ IA64: use helpers for rlimits.
+- patches.suse/rlim-0013-PPC-use-helpers-for-rlimits.patch: PPC:
+ use helpers for rlimits.
+- patches.suse/rlim-0014-S390-use-helpers-for-rlimits.patch:
+ S390: use helpers for rlimits.
+- patches.suse/rlim-0015-SPARC-use-helpers-for-rlimits.patch:
+ SPARC: use helpers for rlimits.
+- patches.suse/rlim-0016-X86-use-helpers-for-rlimits.patch: X86:
+ use helpers for rlimits.
+- patches.suse/rlim-0017-FS-use-helpers-for-rlimits.patch: FS:
+ use helpers for rlimits.
+- patches.suse/rlim-0018-MM-use-helpers-for-rlimits.patch: MM:
+ use helpers for rlimits.
+- patches.suse/rlim-0019-core-use-helpers-for-rlimits.patch:
+ core: use helpers for rlimits.
+- patches.suse/rlim-0020-misc-use-helpers-for-rlimits.patch:
+ misc: use helpers for rlimits.
+- patches.suse/rlim-0021-core-rename-setrlimit-to-do_setrlimit.patch:
+ core: rename setrlimit to do_setrlimit.
+- patches.suse/rlim-0022-core-implement-getprlimit-and-setprlimit-syscalls.patch:
+ core: implement getprlimit and setprlimit syscalls.
+- patches.suse/rlim-0023-unistd-add-__NR_-get-set-prlimit-syscall-numbers.patch:
+ unistd: add __NR_[get|set]prlimit syscall numbers.
+- patches.suse/rlim-0024-COMPAT-add-get-put_compat_rlimit.patch:
+ COMPAT: add get/put_compat_rlimit.
+- patches.suse/rlim-0025-x86-add-ia32-compat-prlimit-syscalls.patch:
+ x86: add ia32 compat prlimit syscalls.
+
+-------------------------------------------------------------------
+Fri Nov 20 14:11:56 CET 2009 - bphilips@suse.de
+
+- patches.drivers/phy-broadcom-bug-fixes-for-sp1.patch:
+ phy/broadcom: bug fixes for SP1 (FATE#307117, bnc#556234).
+- patches.drivers/tg3-update-version-to-3.104.patch: tg3: Update
+ version to 3.104 (bnc#556234, FATE#307117).
+
+-------------------------------------------------------------------
+Fri Nov 20 14:11:26 CET 2009 - bphilips@suse.de
+
+- patches.drivers/phy-broadcom-bug-fixes-for-sp1.patch:
+ phy/broadcom: bug fixes for SP1 (FATE#307117, bnc#556234).
+- patches.drivers/tg3-update-version-to-3.104.patch: tg3: Update
+ version to 3.104 (bnc#556234, FATE#307117).
+
+-------------------------------------------------------------------
+Fri Nov 20 13:58:29 CET 2009 - hare@suse.de
+
+- patches.drivers/megaraid-04.12-update: megaraid: Update
+ megaraid_sas to version 04.12 (FATE#307125).
+
+-------------------------------------------------------------------
+Fri Nov 20 13:41:37 CET 2009 - bphilips@suse.de
+
+- patches.drivers/bnx2-entropy-source.patch: bnx2: entropy source
+ (FATE#307517).
+- patches.drivers/e1000-entropy-source.patch: Enable e1000 as
+ entropy source (disabled by default) (FATE#307517).
+- patches.drivers/e1000e-entropy-source.patch: Enable e1000e as
+ entropy source (disabled by default) (FATE#307517).
+- patches.drivers/igb-entropy-source.patch: Enable igb as entropy
+ source (disabled by default) (FATE#307517).
+- patches.drivers/ixgbe-entropy-source.patch: Enable ixgbe as
+ entropy source (disabled by default) (FATE#307517).
+- patches.drivers/tg3-entropy-source.patch: tg3: entropy source
+ (FATE#307517).
+
+-------------------------------------------------------------------
+Fri Nov 20 13:16:20 CET 2009 - hare@suse.de
+
+- patches.fixes/scsi-fix-bug-with-dma-maps-on-nested-scsi-objects:
+ scsi_lib_dma: fix bug with dma maps on nested scsi objects
+ (bnc#556595).
+- patches.fixes/scsi-introduce-helper-function-for-blocking-eh:
+ scsi_transport_fc: Introduce helper function for blocking
+ scsi_eh (bnc#556595).
+- patches.fixes/scsi-skip-nonscsi-device-for-dma: Delete.
+
+-------------------------------------------------------------------
+Fri Nov 20 12:32:48 CET 2009 - hare@suse.de
+
+Whitespace cleanup for series2git:
+- patches.arch/s390-message-catalog.diff: Refresh.
+- patches.drivers/aacraid-24701-update: Refresh.
+- patches.suse/crasher-26.diff: Refresh.
+- patches.suse/kdb-common: Refresh.
+- patches.suse/kdb-ia64: Refresh.
+- patches.suse/kdb-x86: Refresh.
+- patches.suse/ocfs2-allocation-resrvations.patch: Refresh.
+- patches.suse/perfmon2.patch: Refresh.
+- patches.suse/perfmon2_ioctl.patch: Refresh.
+- patches.suse/stack-unwind: Refresh.
+
+-------------------------------------------------------------------
+Fri Nov 20 12:19:54 CET 2009 - bphilips@suse.de
+
+- patches.drivers/igb-add-support-for-82576NS-SerDes-adapter.patch:
+ igb: add support for 82576NS SerDes adapter (FATE#306856).
+
+-------------------------------------------------------------------
Fri Nov 20 09:06:24 CET 2009 - jbeulich@novell.com
- patches.suse/dm-mpath-evaluate-request-result-and-sense:
diff --git a/patches.arch/s390-message-catalog.diff b/patches.arch/s390-message-catalog.diff
index 294f8e06a5..46ae47e50e 100644
--- a/patches.arch/s390-message-catalog.diff
+++ b/patches.arch/s390-message-catalog.diff
@@ -5512,7 +5512,7 @@ diff -urpN linux-2.6/Documentation/kmsg/s390/qeth linux-2.6-patched/Documentatio
+ * or VSWITCH uses the network layer (layer 3).
+ * User action:
+ * If you are connecting to an ETHERNET guest LAN or VSWITCH, set the layer2 sysfs
-+ * attribute of the qeth device to 1. If you are connecting to an IP guest LAN or
++ * attribute of the qeth device to 1. If you are connecting to an IP guest LAN or
+ * VSWITCH, set the layer2 sysfs attribute of the qeth device to 0.
+ */
+
diff --git a/patches.drivers/aacraid-24701-update b/patches.drivers/aacraid-24701-update
index 844e82c695..7a036426e0 100644
--- a/patches.drivers/aacraid-24701-update
+++ b/patches.drivers/aacraid-24701-update
@@ -279,7 +279,7 @@ index 0391d75..7e7e262 100644
int status;
-
+ unsigned long mflags;
-+
++
/*
* HBA gets first crack
*/
diff --git a/patches.drivers/bnx2-entropy-source.patch b/patches.drivers/bnx2-entropy-source.patch
new file mode 100644
index 0000000000..be8fc71bd2
--- /dev/null
+++ b/patches.drivers/bnx2-entropy-source.patch
@@ -0,0 +1,42 @@
+From: Brandon Philips <bphilips@suse.de>
+Subject: [PATCH] bnx2: entropy source
+Patch-mainline: never
+References: FATE#307517
+
+Current disk-less systems have no entropy source whatsoever. Therefore, the
+network drivers tg3, bnx2, e1000, e1000e, igb and ixgbe should be enabled to
+feed entropy to the kernel via the IRQF_SAMPLE_RANDOM flag when loaded. This
+option shall not be enabled by default but implemented via a module option to
+be activated by the administrator.
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+
+---
+ drivers/net/bnx2.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+Index: linux-2.6.31-master/drivers/net/bnx2.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/bnx2.c
++++ linux-2.6.31-master/drivers/net/bnx2.c
+@@ -85,6 +85,10 @@ MODULE_FIRMWARE(FW_MIPS_FILE_09);
+ MODULE_FIRMWARE(FW_RV2P_FILE_09);
+ MODULE_FIRMWARE(FW_RV2P_FILE_09_Ax);
+
++static int entropy = 0;
++module_param(entropy, int, 0);
++MODULE_PARM_DESC(entropy, "Allow bnx2 to populate the /dev/random entropy pool");
++
+ static int disable_msi = 0;
+
+ module_param(disable_msi, int, 0);
+@@ -6060,6 +6064,9 @@ bnx2_request_irq(struct bnx2 *bp)
+ else
+ flags = IRQF_SHARED;
+
++ if (entropy)
++ flags |= IRQF_SAMPLE_RANDOM;
++
+ for (i = 0; i < bp->irq_nvecs; i++) {
+ irq = &bp->irq_tbl[i];
+ rc = request_irq(irq->vector, irq->handler, flags, irq->name,
diff --git a/patches.drivers/e1000-entropy-source.patch b/patches.drivers/e1000-entropy-source.patch
new file mode 100644
index 0000000000..c68a77c19c
--- /dev/null
+++ b/patches.drivers/e1000-entropy-source.patch
@@ -0,0 +1,49 @@
+From: Jiri Benc <jbenc@suse.cz>
+Subject: Enable e1000 as entropy source (disabled by default)
+References: FATE#307517
+Patch-mainline: never
+
+Based on the patch by Oracle:
+
+> e1000: Add IRQF_SAMPLE_RANDOM flag to e1000 as a module option
+>
+> This patch allows for the bnx2 to add to the /dev/random entropy pool
+> via a module parameter, entropy.
+>
+> 0 - default for EL5 - do not populate the entropy pool
+> 1 - optional - Uses IRQF_SAMPLE_RANDOM flag on request_irq calls to populate
+> the /dev/random pool
+>
+> Signed-off-by: John Sobecki <john.sobecki@oracle.com>
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+
+---
+ drivers/net/e1000/e1000_main.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+Index: linux-2.6.31-master/drivers/net/e1000/e1000_main.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/e1000/e1000_main.c
++++ linux-2.6.31-master/drivers/net/e1000/e1000_main.c
+@@ -213,6 +213,10 @@ static int debug = NETIF_MSG_DRV | NETIF
+ module_param(debug, int, 0);
+ MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
++static int entropy = 0;
++module_param(entropy, int, 0);
++MODULE_PARM_DESC(entropy, "Allow e1000 to populate the /dev/random entropy pool");
++
+ /**
+ * e1000_init_module - Driver Registration Routine
+ *
+@@ -262,6 +266,9 @@ static int e1000_request_irq(struct e100
+ int irq_flags = IRQF_SHARED;
+ int err;
+
++ if (entropy)
++ irq_flags |= IRQF_SAMPLE_RANDOM;
++
+ err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
+ netdev);
+ if (err) {
diff --git a/patches.drivers/e1000e-entropy-source.patch b/patches.drivers/e1000e-entropy-source.patch
new file mode 100644
index 0000000000..2931fe0dc9
--- /dev/null
+++ b/patches.drivers/e1000e-entropy-source.patch
@@ -0,0 +1,90 @@
+From: Jiri Benc <jbenc@suse.cz>
+Subject: Enable e1000e as entropy source (disabled by default)
+References: FATE#307517
+Patch-mainline: never
+
+Current disk-less systems have no entropy source whatsoever. Therefore, the
+network drivers tg3, bnx2, e1000, e1000e, igb and ixgbe should be enabled to
+feed entropy to the kernel via the IRQF_SAMPLE_RANDOM flag when loaded. This
+option shall not be enabled by default but implemented via a module option to
+be activated by the administrator.
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+
+---
+ drivers/net/e1000e/e1000.h | 1 +
+ drivers/net/e1000e/netdev.c | 12 ++++++++----
+ drivers/net/e1000e/param.c | 4 ++++
+ 3 files changed, 13 insertions(+), 4 deletions(-)
+
+Index: linux-2.6.31-master/drivers/net/e1000e/netdev.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/e1000e/netdev.c
++++ linux-2.6.31-master/drivers/net/e1000e/netdev.c
+@@ -1481,8 +1481,8 @@ static int e1000_request_msix(struct e10
+ else
+ memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
+ err = request_irq(adapter->msix_entries[vector].vector,
+- &e1000_intr_msix_rx, 0, adapter->rx_ring->name,
+- netdev);
++ &e1000_intr_msix_rx, entropy ? IRQF_SAMPLE_RANDOM : 0,
++ adapter->rx_ring->name, netdev);
+ if (err)
+ goto out;
+ adapter->rx_ring->itr_register = E1000_EITR_82574(vector);
+@@ -1523,6 +1523,7 @@ static int e1000_request_irq(struct e100
+ {
+ struct net_device *netdev = adapter->netdev;
+ int err;
++ int irq_flags = 0;
+
+ if (adapter->msix_entries) {
+ err = e1000_request_msix(adapter);
+@@ -1534,7 +1535,8 @@ static int e1000_request_irq(struct e100
+ e1000e_set_interrupt_capability(adapter);
+ }
+ if (adapter->flags & FLAG_MSI_ENABLED) {
+- err = request_irq(adapter->pdev->irq, &e1000_intr_msi, 0,
++ err = request_irq(adapter->pdev->irq, &e1000_intr_msi,
++ entropy ? IRQF_SAMPLE_RANDOM : 0,
+ netdev->name, netdev);
+ if (!err)
+ return err;
+@@ -1544,7 +1546,9 @@ static int e1000_request_irq(struct e100
+ adapter->int_mode = E1000E_INT_MODE_LEGACY;
+ }
+
+- err = request_irq(adapter->pdev->irq, &e1000_intr, IRQF_SHARED,
++ if (entropy)
++ irq_flags |= IRQF_SAMPLE_RANDOM;
++ err = request_irq(adapter->pdev->irq, &e1000_intr, irq_flags,
+ netdev->name, netdev);
+ if (err)
+ e_err("Unable to allocate interrupt, Error: %d\n", err);
+Index: linux-2.6.31-master/drivers/net/e1000e/param.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/e1000e/param.c
++++ linux-2.6.31-master/drivers/net/e1000e/param.c
+@@ -31,6 +31,10 @@
+
+ #include "e1000.h"
+
++int entropy = 0;
++module_param(entropy, int, 0);
++MODULE_PARM_DESC(entropy, "Allow e1000e to populate the /dev/random entropy pool");
++
+ /*
+ * This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+Index: linux-2.6.31-master/drivers/net/e1000e/e1000.h
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/e1000e/e1000.h
++++ linux-2.6.31-master/drivers/net/e1000e/e1000.h
+@@ -457,6 +457,7 @@ extern void e1000e_set_interrupt_capabil
+ extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
+
+ extern unsigned int copybreak;
++extern int entropy;
+
+ extern char *e1000e_get_hw_dev_name(struct e1000_hw *hw);
+
diff --git a/patches.drivers/igb-add-support-for-82576NS-SerDes-adapter.patch b/patches.drivers/igb-add-support-for-82576NS-SerDes-adapter.patch
new file mode 100644
index 0000000000..779d512cc2
--- /dev/null
+++ b/patches.drivers/igb-add-support-for-82576NS-SerDes-adapter.patch
@@ -0,0 +1,56 @@
+From 747d49baaf4e3f4ad5ae77477830da026eeef69d Mon Sep 17 00:00:00 2001
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+Date: Mon, 5 Oct 2009 06:33:27 +0000
+Subject: [PATCH] igb: add support for 82576NS SerDes adapter
+Patch-mainline: 2.6.33 - picked from net-next-2.6
+References: FATE#306856
+
+This patch adds the device ID necessary to support the 82576NS SerDes
+adapter.
+
+Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+---
+ drivers/net/igb/e1000_82575.c | 1 +
+ drivers/net/igb/e1000_hw.h | 1 +
+ drivers/net/igb/igb_main.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+Index: linux-2.6.31-master/drivers/net/igb/e1000_82575.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/igb/e1000_82575.c
++++ linux-2.6.31-master/drivers/net/igb/e1000_82575.c
+@@ -81,6 +81,7 @@ static s32 igb_get_invariants_82575(stru
+ break;
+ case E1000_DEV_ID_82576:
+ case E1000_DEV_ID_82576_NS:
++ case E1000_DEV_ID_82576_NS_SERDES:
+ case E1000_DEV_ID_82576_FIBER:
+ case E1000_DEV_ID_82576_SERDES:
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+Index: linux-2.6.31-master/drivers/net/igb/e1000_hw.h
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/igb/e1000_hw.h
++++ linux-2.6.31-master/drivers/net/igb/e1000_hw.h
+@@ -42,6 +42,7 @@ struct e1000_hw;
+ #define E1000_DEV_ID_82576_SERDES 0x10E7
+ #define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
+ #define E1000_DEV_ID_82576_NS 0x150A
++#define E1000_DEV_ID_82576_NS_SERDES 0x1518
+ #define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
+ #define E1000_DEV_ID_82575EB_COPPER 0x10A7
+ #define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
+Index: linux-2.6.31-master/drivers/net/igb/igb_main.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/igb/igb_main.c
++++ linux-2.6.31-master/drivers/net/igb/igb_main.c
+@@ -63,6 +63,7 @@ static const struct e1000_info *igb_info
+ static struct pci_device_id igb_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
diff --git a/patches.drivers/igb-entropy-source.patch b/patches.drivers/igb-entropy-source.patch
new file mode 100644
index 0000000000..64caffa99e
--- /dev/null
+++ b/patches.drivers/igb-entropy-source.patch
@@ -0,0 +1,73 @@
+From: Jiri Benc <jbenc@suse.cz>
+Subject: Enable igb as entropy source (disabled by default)
+References: FATE#307517
+Patch-mainline: never
+
+Current disk-less systems have no entropy source whatsoever. Therefore, the
+network drivers tg3, bnx2, e1000, e1000e, igb and ixgbe should be enabled to
+feed entropy to the kernel via the IRQF_SAMPLE_RANDOM flag when loaded. This
+option shall not be enabled by default but implemented via a module option to
+be activated by the administrator.
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+
+---
+ drivers/net/igb/igb_main.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+Index: linux-2.6.31-master/drivers/net/igb/igb_main.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/igb/igb_main.c
++++ linux-2.6.31-master/drivers/net/igb/igb_main.c
+@@ -60,6 +60,10 @@ static const struct e1000_info *igb_info
+ [board_82575] = &e1000_82575_info,
+ };
+
++static int entropy = 0;
++module_param(entropy, int, 0);
++MODULE_PARM_DESC(entropy, "Allow igb to populate the /dev/random entropy pool");
++
+ static struct pci_device_id igb_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
+@@ -647,8 +651,8 @@ static int igb_request_msix(struct igb_a
+ else
+ memcpy(ring->name, netdev->name, IFNAMSIZ);
+ err = request_irq(adapter->msix_entries[vector].vector,
+- &igb_msix_rx, 0, ring->name,
+- &(adapter->rx_ring[i]));
++ &igb_msix_rx, entropy ? IRQF_SAMPLE_RANDOM : 0,
++ ring->name, &(adapter->rx_ring[i]));
+ if (err)
+ goto out;
+ ring->itr_register = E1000_EITR(0) + (vector << 2);
+@@ -750,6 +754,10 @@ static int igb_request_irq(struct igb_ad
+ struct net_device *netdev = adapter->netdev;
+ struct e1000_hw *hw = &adapter->hw;
+ int err = 0;
++ int irq_flags = 0;
++
++ if (entropy)
++ irq_flags = IRQF_SAMPLE_RANDOM;
+
+ if (adapter->msix_entries) {
+ err = igb_request_msix(adapter);
+@@ -778,7 +786,7 @@ static int igb_request_irq(struct igb_ad
+ }
+
+ if (adapter->flags & IGB_FLAG_HAS_MSI) {
+- err = request_irq(adapter->pdev->irq, &igb_intr_msi, 0,
++ err = request_irq(adapter->pdev->irq, &igb_intr_msi, irq_flags,
+ netdev->name, netdev);
+ if (!err)
+ goto request_done;
+@@ -787,7 +795,8 @@ static int igb_request_irq(struct igb_ad
+ adapter->flags &= ~IGB_FLAG_HAS_MSI;
+ }
+
+- err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
++ irq_flags |= IRQF_SHARED;
++ err = request_irq(adapter->pdev->irq, &igb_intr, irq_flags,
+ netdev->name, netdev);
+
+ if (err)
diff --git a/patches.drivers/ixgbe-entropy-source.patch b/patches.drivers/ixgbe-entropy-source.patch
new file mode 100644
index 0000000000..cc68afa083
--- /dev/null
+++ b/patches.drivers/ixgbe-entropy-source.patch
@@ -0,0 +1,92 @@
+From: Jiri Benc <jbenc@suse.cz>
+Subject: Enable ixgbe as entropy source (disabled by default)
+References: FATE#307517
+Patch-mainline: never
+
+Current disk-less systems have no entropy source whatsoever. Therefore, the
+network drivers tg3, bnx2, e1000, e1000e, igb and ixgbe should be enabled to
+feed entropy to the kernel via the IRQF_SAMPLE_RANDOM flag when loaded. This
+option shall not be enabled by default but implemented via a module option to
+be activated by the administrator.
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+
+---
+ drivers/net/ixgbe/ixgbe_main.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+Index: linux-2.6.31-master/drivers/net/ixgbe/ixgbe_main.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/ixgbe/ixgbe_main.c
++++ linux-2.6.31-master/drivers/net/ixgbe/ixgbe_main.c
+@@ -54,6 +54,11 @@ static const char ixgbe_driver_string[]
+ const char ixgbe_driver_version[] = DRV_VERSION;
+ static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
+
++static int entropy = 0;
++module_param(entropy, int, 0);
++MODULE_PARM_DESC(entropy, "Allow ixgbe to populate the /dev/random entropy pool");
++
++
+ static const struct ixgbe_info *ixgbe_info_tbl[] = {
+ [board_82598] = &ixgbe_82598_info,
+ [board_82599] = &ixgbe_82599_info,
+@@ -1627,6 +1632,7 @@ static int ixgbe_request_msix_irqs(struc
+ irqreturn_t (*handler)(int, void *);
+ int i, vector, q_vectors, err;
+ int ri=0, ti=0;
++ int irq_flags;
+
+ /* Decrement for Other and TCP Timer vectors */
+ q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+@@ -1642,20 +1648,26 @@ static int ixgbe_request_msix_irqs(struc
+ for (vector = 0; vector < q_vectors; vector++) {
+ handler = SET_HANDLER(adapter->q_vector[vector]);
+
++ irq_flags = 0;
+ if(handler == &ixgbe_msix_clean_rx) {
+ sprintf(adapter->name[vector], "%s-%s-%d",
+ netdev->name, "rx", ri++);
++ if (entropy)
++ irq_flags = IRQF_SAMPLE_RANDOM;
+ }
+ else if(handler == &ixgbe_msix_clean_tx) {
+ sprintf(adapter->name[vector], "%s-%s-%d",
+ netdev->name, "tx", ti++);
+ }
+- else
++ else {
+ sprintf(adapter->name[vector], "%s-%s-%d",
+ netdev->name, "TxRx", vector);
++ if (entropy)
++ irq_flags = IRQF_SAMPLE_RANDOM;
++ }
+
+ err = request_irq(adapter->msix_entries[vector].vector,
+- handler, 0, adapter->name[vector],
++ handler, irq_flags, adapter->name[vector],
+ adapter->q_vector[vector]);
+ if (err) {
+ DPRINTK(PROBE, ERR,
+@@ -1834,14 +1846,19 @@ static int ixgbe_request_irq(struct ixgb
+ {
+ struct net_device *netdev = adapter->netdev;
+ int err;
++ int irq_flags = 0;
++
++ if (entropy)
++ irq_flags = IRQF_SAMPLE_RANDOM;
+
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ err = ixgbe_request_msix_irqs(adapter);
+ } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
+- err = request_irq(adapter->pdev->irq, &ixgbe_intr, 0,
++ err = request_irq(adapter->pdev->irq, &ixgbe_intr, irq_flags,
+ netdev->name, netdev);
+ } else {
+- err = request_irq(adapter->pdev->irq, &ixgbe_intr, IRQF_SHARED,
++ irq_flags |= IRQF_SHARED;
++ err = request_irq(adapter->pdev->irq, &ixgbe_intr, irq_flags,
+ netdev->name, netdev);
+ }
+
diff --git a/patches.drivers/megaraid-04.12-update b/patches.drivers/megaraid-04.12-update
new file mode 100644
index 0000000000..e150f71a08
--- /dev/null
+++ b/patches.drivers/megaraid-04.12-update
@@ -0,0 +1,1572 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 20 Nov 2009 13:55:02 +0100
+Subject: megaraid: Update megaraid_sas to version 04.12
+References: FATE#307125
+
+This patch updates the megaraid_sas driver to version 0.4.12-rc1.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
+index a39addc..134c63e 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.c
++++ b/drivers/scsi/megaraid/megaraid_sas.c
+@@ -10,7 +10,7 @@
+ * 2 of the License, or (at your option) any later version.
+ *
+ * FILE : megaraid_sas.c
+- * Version : v00.00.04.01-rc1
++ * Version : v00.00.04.12-rc1
+ *
+ * Authors:
+ * (email-id : megaraidlinux@lsi.com)
+@@ -40,6 +40,7 @@
+ #include <linux/compat.h>
+ #include <linux/blkdev.h>
+ #include <linux/mutex.h>
++#include <linux/poll.h>
+
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_cmnd.h>
+@@ -75,6 +76,10 @@ static struct pci_device_id megasas_pci_table[] = {
+ /* gen2*/
+ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
+ /* gen2*/
++ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
++ /* skinny*/
++ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
++ /* skinny*/
+ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
+ /* xscale IOP, vega */
+ {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
+@@ -89,8 +94,14 @@ static struct megasas_mgmt_info megasas_mgmt_info;
+ static struct fasync_struct *megasas_async_queue;
+ static DEFINE_MUTEX(megasas_async_queue_mutex);
+
++static int megasas_poll_wait_aen;
++static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
++static u32 support_poll_for_event;
+ static u32 megasas_dbg_lvl;
+
++/* define lock for aen poll */
++spinlock_t poll_aen_lock;
++
+ static void
+ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
+ u8 alt_status);
+@@ -215,7 +226,10 @@ megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
+ * @regs : MFI register set
+ */
+ static inline void
+-megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs)
++megasas_fire_cmd_xscale(struct megasas_instance *instance,
++ dma_addr_t frame_phys_addr,
++ u32 frame_count,
++ struct megasas_register_set __iomem *regs)
+ {
+ writel((frame_phys_addr >> 3)|(frame_count),
+ &(regs)->inbound_queue_port);
+@@ -312,7 +326,10 @@ megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
+ * @regs : MFI register set
+ */
+ static inline void
+-megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)
++megasas_fire_cmd_ppc(struct megasas_instance *instance,
++ dma_addr_t frame_phys_addr,
++ u32 frame_count,
++ struct megasas_register_set __iomem *regs)
+ {
+ writel((frame_phys_addr | (frame_count<<1))|1,
+ &(regs)->inbound_queue_port);
+@@ -328,6 +345,104 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
+ };
+
+ /**
++ * megasas_enable_intr_skinny - Enables interrupts
++ * @regs: MFI register set
++ */
++static inline void
++megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
++{
++ writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
++
++ writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
++
++ /* Dummy readl to force pci flush */
++ readl(&regs->outbound_intr_mask);
++}
++
++/**
++ * megasas_disable_intr_skinny - Disables interrupt
++ * @regs: MFI register set
++ */
++static inline void
++megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
++{
++ u32 mask = 0xFFFFFFFF;
++ writel(mask, &regs->outbound_intr_mask);
++ /* Dummy readl to force pci flush */
++ readl(&regs->outbound_intr_mask);
++}
++
++/**
++ * megasas_read_fw_status_reg_skinny - returns the current FW status value
++ * @regs: MFI register set
++ */
++static u32
++megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
++{
++ return readl(&(regs)->outbound_scratch_pad);
++}
++
++/**
++ * megasas_clear_interrupt_skinny - Check & clear interrupt
++ * @regs: MFI register set
++ */
++static int
++megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
++{
++ u32 status;
++ /*
++ * Check if it is our interrupt
++ */
++ status = readl(&regs->outbound_intr_status);
++
++ if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
++ return 1;
++ }
++
++ /*
++ * Clear the interrupt by writing back the same value
++ */
++ writel(status, &regs->outbound_intr_status);
++
++ /*
++ * dummy read to flush PCI
++ */
++ readl(&regs->outbound_intr_status);
++
++ return 0;
++}
++
++/**
++ * megasas_fire_cmd_skinny - Sends command to the FW
++ * @frame_phys_addr : Physical address of cmd
++ * @frame_count : Number of frames for the command
++ * @regs : MFI register set
++ */
++static inline void
++megasas_fire_cmd_skinny(struct megasas_instance *instance,
++ dma_addr_t frame_phys_addr,
++ u32 frame_count,
++ struct megasas_register_set __iomem *regs)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&instance->fire_lock, flags);
++ writel(0, &(regs)->inbound_high_queue_port);
++ writel((frame_phys_addr | (frame_count<<1))|1,
++ &(regs)->inbound_low_queue_port);
++ spin_unlock_irqrestore(&instance->fire_lock, flags);
++}
++
++static struct megasas_instance_template megasas_instance_template_skinny = {
++
++ .fire_cmd = megasas_fire_cmd_skinny,
++ .enable_intr = megasas_enable_intr_skinny,
++ .disable_intr = megasas_disable_intr_skinny,
++ .clear_intr = megasas_clear_intr_skinny,
++ .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
++};
++
++
++/**
+ * The following functions are defined for gen2 (deviceid : 0x78 0x79)
+ * controllers
+ */
+@@ -404,7 +519,9 @@ megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
+ * @regs : MFI register set
+ */
+ static inline void
+-megasas_fire_cmd_gen2(dma_addr_t frame_phys_addr, u32 frame_count,
++megasas_fire_cmd_gen2(struct megasas_instance *instance,
++ dma_addr_t frame_phys_addr,
++ u32 frame_count,
+ struct megasas_register_set __iomem *regs)
+ {
+ writel((frame_phys_addr | (frame_count<<1))|1,
+@@ -446,7 +563,8 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
+ /*
+ * Issue the frame using inbound queue port
+ */
+- instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
++ instance->instancet->fire_cmd(instance,
++ cmd->frame_phys_addr, 0, instance->reg_set);
+
+ /*
+ * Wait for cmd_status to change
+@@ -477,7 +595,8 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
+ {
+ cmd->cmd_status = ENODATA;
+
+- instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
++ instance->instancet->fire_cmd(instance,
++ cmd->frame_phys_addr, 0, instance->reg_set);
+
+ wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA),
+ MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
+@@ -522,7 +641,8 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
+ cmd->sync_cmd = 1;
+ cmd->cmd_status = 0xFF;
+
+- instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
++ instance->instancet->fire_cmd(instance,
++ cmd->frame_phys_addr, 0, instance->reg_set);
+
+ /*
+ * Wait for this cmd to complete
+@@ -592,6 +712,35 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ return sge_count;
+ }
+
++/**
++ * megasas_make_sgl_skinny - Prepares IEEE SGL
++ * @instance: Adapter soft state
++ * @scp: SCSI command from the mid-layer
++ * @mfi_sgl: SGL to be filled in
++ *
++ * If successful, this function returns the number of SG elements. Otherwise,
++ * it returnes -1.
++ */
++static int
++megasas_make_sgl_skinny(struct megasas_instance *instance,
++ struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
++{
++ int i;
++ int sge_count;
++ struct scatterlist *os_sgl;
++
++ sge_count = scsi_dma_map(scp);
++
++ if (sge_count) {
++ scsi_for_each_sg(scp, os_sgl, sge_count, i) {
++ mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
++ mfi_sgl->sge_skinny[i].phys_addr =
++ sg_dma_address(os_sgl);
++ }
++ }
++ return sge_count;
++}
++
+ /**
+ * megasas_get_frame_count - Computes the number of frames
+ * @frame_type : type of frame- io or pthru frame
+@@ -600,7 +749,8 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ * Returns the number of frames required for numnber of sge's (sge_count)
+ */
+
+-static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
++static u32 megasas_get_frame_count(struct megasas_instance *instance,
++ u8 sge_count, u8 frame_type)
+ {
+ int num_cnt;
+ int sge_bytes;
+@@ -610,6 +760,10 @@ static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
+ sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
+ sizeof(struct megasas_sge32);
+
++ if (instance->flag_ieee) {
++ sge_sz = sizeof(struct megasas_sge_skinny);
++ }
++
+ /*
+ * Main frame can contain 2 SGEs for 64-bit SGLs and
+ * 3 SGEs for 32-bit SGLs for ldio &
+@@ -617,12 +771,16 @@ static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
+ * 2 SGEs for 32-bit SGLs for pthru frame
+ */
+ if (unlikely(frame_type == PTHRU_FRAME)) {
+- if (IS_DMA64)
++ if (instance->flag_ieee == 1) {
++ num_cnt = sge_count - 1;
++ } else if (IS_DMA64)
+ num_cnt = sge_count - 1;
+ else
+ num_cnt = sge_count - 2;
+ } else {
+- if (IS_DMA64)
++ if (instance->flag_ieee == 1) {
++ num_cnt = sge_count - 1;
++ } else if (IS_DMA64)
+ num_cnt = sge_count - 2;
+ else
+ num_cnt = sge_count - 3;
+@@ -671,6 +829,10 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ else if (scp->sc_data_direction == PCI_DMA_NONE)
+ flags = MFI_FRAME_DIR_NONE;
+
++ if (instance->flag_ieee == 1) {
++ flags |= MFI_FRAME_IEEE;
++ }
++
+ /*
+ * Prepare the DCDB frame
+ */
+@@ -687,9 +849,24 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);
+
+ /*
++ * If the command is for the tape device, set the
++ * pthru timeout to the os layer timeout value.
++ */
++ if (scp->device->type == TYPE_TAPE) {
++ if ((scp->request->timeout / HZ) > 0xFFFF)
++ pthru->timeout = 0xFFFF;
++ else
++ pthru->timeout = scp->request->timeout / HZ;
++ }
++
++ /*
+ * Construct SGL
+ */
+- if (IS_DMA64) {
++ if (instance->flag_ieee == 1) {
++ pthru->flags |= MFI_FRAME_SGL64;
++ pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
++ &pthru->sgl);
++ } else if (IS_DMA64) {
+ pthru->flags |= MFI_FRAME_SGL64;
+ pthru->sge_count = megasas_make_sgl64(instance, scp,
+ &pthru->sgl);
+@@ -708,7 +885,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ * Compute the total number of frames this command consumes. FW uses
+ * this number to pull sufficient number of frames from host memory.
+ */
+- cmd->frame_count = megasas_get_frame_count(pthru->sge_count,
++ cmd->frame_count = megasas_get_frame_count(instance, pthru->sge_count,
+ PTHRU_FRAME);
+
+ return cmd->frame_count;
+@@ -739,6 +916,10 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
+ flags = MFI_FRAME_DIR_READ;
+
++ if (instance->flag_ieee == 1) {
++ flags |= MFI_FRAME_IEEE;
++ }
++
+ /*
+ * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
+ */
+@@ -809,7 +990,11 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ /*
+ * Construct SGL
+ */
+- if (IS_DMA64) {
++ if (instance->flag_ieee) {
++ ldio->flags |= MFI_FRAME_SGL64;
++ ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
++ &ldio->sgl);
++ } else if (IS_DMA64) {
+ ldio->flags |= MFI_FRAME_SGL64;
+ ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
+ } else
+@@ -826,7 +1011,8 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
+ * Compute the total number of frames this command consumes. FW uses
+ * this number to pull sufficient number of frames from host memory.
+ */
+- cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME);
++ cmd->frame_count = megasas_get_frame_count(instance,
++ ldio->sge_count, IO_FRAME);
+
+ return cmd->frame_count;
+ }
+@@ -983,7 +1169,8 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
+ */
+ atomic_inc(&instance->fw_outstanding);
+
+- instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
++ instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
++ cmd->frame_count-1, instance->reg_set);
+ /*
+ * Check if we have pend cmds to be completed
+ */
+@@ -1000,24 +1187,76 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
+ return 0;
+ }
+
++static struct megasas_instance *megasas_lookup_instance(u16 host_no)
++{
++ int i;
++
++ for (i = 0; i < megasas_mgmt_info.max_index; i++) {
++
++ if ((megasas_mgmt_info.instance[i]) &&
++ (megasas_mgmt_info.instance[i]->host->host_no == host_no))
++ return megasas_mgmt_info.instance[i];
++ }
++
++ return NULL;
++}
++
+ static int megasas_slave_configure(struct scsi_device *sdev)
+ {
++ u16 pd_index = 0;
++ struct megasas_instance *instance ;
++
++ instance = megasas_lookup_instance(sdev->host->host_no);
++
+ /*
+- * Don't export physical disk devices to the disk driver.
+- *
+- * FIXME: Currently we don't export them to the midlayer at all.
+- * That will be fixed once LSI engineers have audited the
+- * firmware for possible issues.
+- */
+- if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
++ * Don't export physical disk devices to the disk driver.
++ *
++ * FIXME: Currently we don't export them to the midlayer at all.
++ * That will be fixed once LSI engineers have audited the
++ * firmware for possible issues.
++ */
++ if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
++ sdev->type == TYPE_DISK) {
++ pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
++ sdev->id;
++ if (instance->pd_list[pd_index].driveState ==
++ MR_PD_STATE_SYSTEM) {
++ blk_queue_rq_timeout(sdev->request_queue,
++ MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
++ return 0;
++ }
+ return -ENXIO;
++ }
+
+ /*
+- * The RAID firmware may require extended timeouts.
+- */
+- if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
+- blk_queue_rq_timeout(sdev->request_queue,
+- MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
++ * The RAID firmware may require extended timeouts.
++ */
++ blk_queue_rq_timeout(sdev->request_queue,
++ MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
++ return 0;
++}
++
++static int megasas_slave_alloc(struct scsi_device *sdev)
++{
++ u16 pd_index = 0;
++ struct megasas_instance *instance ;
++ instance = megasas_lookup_instance(sdev->host->host_no);
++ if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
++ (sdev->type == TYPE_DISK)) {
++ /*
++ * Open the OS scan to the SYSTEM PD
++ */
++ pd_index =
++ (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
++ sdev->id;
++ if ((instance->pd_list[pd_index].driveState ==
++ MR_PD_STATE_SYSTEM) &&
++ (instance->pd_list[pd_index].driveType ==
++ TYPE_DISK)) {
++ return 0;
++ }
++ return -ENXIO;
++ }
+ return 0;
+ }
+
+@@ -1072,7 +1311,14 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
+
+ spin_lock_irqsave(instance->host->host_lock, flags);
+ instance->flag &= ~MEGASAS_FW_BUSY;
+- instance->host->can_queue =
++ if ((instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
++ (instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
++ instance->host->can_queue =
++ instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
++ } else
++ instance->host->can_queue =
+ instance->max_fw_cmds - MEGASAS_INT_CMDS;
+
+ spin_unlock_irqrestore(instance->host->host_lock, flags);
+@@ -1117,8 +1363,16 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
+ * Send signal to FW to stop processing any pending cmds.
+ * The controller will be taken offline by the OS now.
+ */
+- writel(MFI_STOP_ADP,
++ if ((instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
++ (instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
++ writel(MFI_STOP_ADP,
++ &instance->reg_set->reserved_0[0]);
++ } else {
++ writel(MFI_STOP_ADP,
+ &instance->reg_set->inbound_doorbell);
++ }
+ megasas_dump_pending_frames(instance);
+ instance->hw_crit_error = 1;
+ return FAILED;
+@@ -1266,6 +1520,8 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
+ return 0;
+ }
+
++static void megasas_aen_polling(struct work_struct *work);
++
+ /**
+ * megasas_service_aen - Processes an event notification
+ * @instance: Adapter soft state
+@@ -1281,16 +1537,36 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
+ static void
+ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
+ {
++ unsigned long flags;
+ /*
+ * Don't signal app if it is just an aborted previously registered aen
+ */
+- if (!cmd->abort_aen)
++ if ((!cmd->abort_aen) && (instance->unload == 0)) {
++ spin_lock_irqsave(&poll_aen_lock, flags);
++ megasas_poll_wait_aen = 1;
++ spin_unlock_irqrestore(&poll_aen_lock, flags);
++ wake_up(&megasas_poll_wait);
+ kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
++ }
+ else
+ cmd->abort_aen = 0;
+
+ instance->aen_cmd = NULL;
+ megasas_return_cmd(instance, cmd);
++
++ if (instance->unload == 0) {
++ struct megasas_aen_event *ev;
++ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
++ if (!ev) {
++ printk(KERN_ERR "megasas_service_aen: out of memory\n");
++ } else {
++ ev->instance = instance;
++ instance->ev = ev;
++ INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
++ schedule_delayed_work(
++ (struct delayed_work *)&ev->hotplug_work, 0);
++ }
++ }
+ }
+
+ /*
+@@ -1302,6 +1578,7 @@ static struct scsi_host_template megasas_template = {
+ .name = "LSI SAS based MegaRAID driver",
+ .proc_name = "megaraid_sas",
+ .slave_configure = megasas_slave_configure,
++ .slave_alloc = megasas_slave_alloc,
+ .queuecommand = megasas_queue_command,
+ .eh_device_reset_handler = megasas_reset_device,
+ .eh_bus_reset_handler = megasas_reset_bus_host,
+@@ -1370,6 +1647,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
+ {
+ int exception = 0;
+ struct megasas_header *hdr = &cmd->frame->hdr;
++ unsigned long flags;
+
+ if (cmd->scmd)
+ cmd->scmd->SCp.ptr = NULL;
+@@ -1459,6 +1737,12 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
+ case MFI_CMD_SMP:
+ case MFI_CMD_STP:
+ case MFI_CMD_DCMD:
++ if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
++ cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
++ spin_lock_irqsave(&poll_aen_lock, flags);
++ megasas_poll_wait_aen = 0;
++ spin_unlock_irqrestore(&poll_aen_lock, flags);
++ }
+
+ /*
+ * See if got an event notification
+@@ -1536,6 +1820,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ u8 max_wait;
+ u32 fw_state;
+ u32 cur_state;
++ u32 abs_state, curr_abs_state;
+
+ fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) & MFI_STATE_MASK;
+
+@@ -1545,6 +1830,9 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+
+ while (fw_state != MFI_STATE_READY) {
+
++ abs_state =
++ instance->instancet->read_fw_status_reg(instance->reg_set);
++
+ switch (fw_state) {
+
+ case MFI_STATE_FAULT:
+@@ -1556,18 +1844,36 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ /*
+ * Set the CLR bit in inbound doorbell
+ */
+- writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+- &instance->reg_set->inbound_doorbell);
++ if ((instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
++ (instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
++
++ writel(
++ MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
++ &instance->reg_set->reserved_0[0]);
++ } else {
++ writel(
++ MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
++ &instance->reg_set->inbound_doorbell);
++ }
+
+- max_wait = 2;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_WAIT_HANDSHAKE;
+ break;
+
+ case MFI_STATE_BOOT_MESSAGE_PENDING:
+- writel(MFI_INIT_HOTPLUG,
+- &instance->reg_set->inbound_doorbell);
++ if ((instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
++ (instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
++ writel(MFI_INIT_HOTPLUG,
++ &instance->reg_set->reserved_0[0]);
++ } else
++ writel(MFI_INIT_HOTPLUG,
++ &instance->reg_set->inbound_doorbell);
+
+- max_wait = 10;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
+ break;
+
+@@ -1576,9 +1882,17 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ * Bring it to READY state; assuming max wait 10 secs
+ */
+ instance->instancet->disable_intr(instance->reg_set);
+- writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
++ if ((instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
++ (instance->pdev->device ==
++ PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
++ writel(MFI_RESET_FLAGS,
++ &instance->reg_set->reserved_0[0]);
++ } else
++ writel(MFI_RESET_FLAGS,
++ &instance->reg_set->inbound_doorbell);
+
+- max_wait = 60;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_OPERATIONAL;
+ break;
+
+@@ -1586,32 +1900,32 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ /*
+ * This state should not last for more than 2 seconds
+ */
+- max_wait = 2;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_UNDEFINED;
+ break;
+
+ case MFI_STATE_BB_INIT:
+- max_wait = 2;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_BB_INIT;
+ break;
+
+ case MFI_STATE_FW_INIT:
+- max_wait = 20;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_FW_INIT;
+ break;
+
+ case MFI_STATE_FW_INIT_2:
+- max_wait = 20;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_FW_INIT_2;
+ break;
+
+ case MFI_STATE_DEVICE_SCAN:
+- max_wait = 20;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_DEVICE_SCAN;
+ break;
+
+ case MFI_STATE_FLUSH_CACHE:
+- max_wait = 20;
++ max_wait = MEGASAS_RESET_WAIT_TIME;
+ cur_state = MFI_STATE_FLUSH_CACHE;
+ break;
+
+@@ -1627,8 +1941,10 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ for (i = 0; i < (max_wait * 1000); i++) {
+ fw_state = instance->instancet->read_fw_status_reg(instance->reg_set) &
+ MFI_STATE_MASK ;
++ curr_abs_state =
++ instance->instancet->read_fw_status_reg(instance->reg_set);
+
+- if (fw_state == cur_state) {
++ if (abs_state == curr_abs_state) {
+ msleep(1);
+ } else
+ break;
+@@ -1637,7 +1953,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ /*
+ * Return error if fw_state hasn't changed after max_wait
+ */
+- if (fw_state == cur_state) {
++ if (curr_abs_state == abs_state) {
+ printk(KERN_DEBUG "FW state [%d] hasn't changed "
+ "in %d secs\n", fw_state, max_wait);
+ return -ENODEV;
+@@ -1715,6 +2031,10 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
+ sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
+ sizeof(struct megasas_sge32);
+
++ if (instance->flag_ieee) {
++ sge_sz = sizeof(struct megasas_sge_skinny);
++ }
++
+ /*
+ * Calculated the number of 64byte frames required for SGL
+ */
+@@ -1777,6 +2097,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance)
+ }
+
+ cmd->frame->io.context = cmd->index;
++ cmd->frame->io.pad_0 = 0;
+ }
+
+ return 0;
+@@ -1882,6 +2203,97 @@ static int megasas_alloc_cmds(struct megasas_instance *instance)
+ return 0;
+ }
+
++/*
++ * megasas_get_pd_list_info - Returns FW's pd_list structure
++ * @instance: Adapter soft state
++ * @pd_list: pd_list structure
++ *
++ * Issues an internal command (DCMD) to get the FW's controller PD
++ * list structure. This information is mainly used to find out SYSTEM
++ * supported by the FW.
++ */
++static int
++megasas_get_pd_list(struct megasas_instance *instance)
++{
++ int ret = 0, pd_index = 0;
++ struct megasas_cmd *cmd;
++ struct megasas_dcmd_frame *dcmd;
++ struct MR_PD_LIST *ci;
++ struct MR_PD_ADDRESS *pd_addr;
++ dma_addr_t ci_h = 0;
++
++ cmd = megasas_get_cmd(instance);
++
++ if (!cmd) {
++ printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
++ return -ENOMEM;
++ }
++
++ dcmd = &cmd->frame->dcmd;
++
++ ci = pci_alloc_consistent(instance->pdev,
++ MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
++
++ if (!ci) {
++ printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
++ megasas_return_cmd(instance, cmd);
++ return -ENOMEM;
++ }
++
++ memset(ci, 0, sizeof(*ci));
++ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
++
++ dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
++ dcmd->mbox.b[1] = 0;
++ dcmd->cmd = MFI_CMD_DCMD;
++ dcmd->cmd_status = 0xFF;
++ dcmd->sge_count = 1;
++ dcmd->flags = MFI_FRAME_DIR_READ;
++ dcmd->timeout = 0;
++ dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
++ dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
++ dcmd->sgl.sge32[0].phys_addr = ci_h;
++ dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
++
++ if (!megasas_issue_polled(instance, cmd)) {
++ ret = 0;
++ } else {
++ ret = -1;
++ }
++
++ /*
++ * the following function will get the instance PD LIST.
++ */
++
++ pd_addr = ci->addr;
++
++ if ( ret == 0 &&
++ (ci->count <
++ (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
++
++ memset(instance->pd_list, 0,
++ MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
++
++ for (pd_index = 0; pd_index < ci->count; pd_index++) {
++
++ instance->pd_list[pd_addr->deviceId].tid =
++ pd_addr->deviceId;
++ instance->pd_list[pd_addr->deviceId].driveType =
++ pd_addr->scsiDevType;
++ instance->pd_list[pd_addr->deviceId].driveState =
++ MR_PD_STATE_SYSTEM;
++ pd_addr++;
++ }
++ }
++
++ pci_free_consistent(instance->pdev,
++ MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
++ ci, ci_h);
++ megasas_return_cmd(instance, cmd);
++
++ return ret;
++}
++
+ /**
+ * megasas_get_controller_info - Returns FW's controller structure
+ * @instance: Adapter soft state
+@@ -2081,6 +2493,8 @@ static int megasas_init_mfi(struct megasas_instance *instance)
+ * Map the message registers
+ */
+ if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
++ (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
++ (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+ (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
+ instance->base_addr = pci_resource_start(instance->pdev, 1);
+ } else {
+@@ -2111,6 +2525,10 @@ static int megasas_init_mfi(struct megasas_instance *instance)
+ case PCI_DEVICE_ID_LSI_SAS0079GEN2:
+ instance->instancet = &megasas_instance_template_gen2;
+ break;
++ case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
++ case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
++ instance->instancet = &megasas_instance_template_skinny;
++ break;
+ case PCI_DEVICE_ID_LSI_SAS1064R:
+ case PCI_DEVICE_ID_DELL_PERC5:
+ default:
+@@ -2166,6 +2584,10 @@ static int megasas_init_mfi(struct megasas_instance *instance)
+ if (megasas_issue_init_mfi(instance))
+ goto fail_fw_init;
+
++ memset(instance->pd_list, 0 ,
++ (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
++ megasas_get_pd_list(instance);
++
+ ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
+
+ /*
+@@ -2409,6 +2831,11 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
+ dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
+ dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);
+
++ if (instance->aen_cmd != NULL) {
++ megasas_return_cmd(instance, cmd);
++ return 0;
++ }
++
+ /*
+ * Store reference to the cmd used to register for AEN. When an
+ * application wants us to register for AEN, we have to abort this
+@@ -2419,7 +2846,8 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
+ /*
+ * Issue the aen registration frame
+ */
+- instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
++ instance->instancet->fire_cmd(instance,
++ cmd->frame_phys_addr, 0, instance->reg_set);
+
+ return 0;
+ }
+@@ -2465,7 +2893,13 @@ static int megasas_io_attach(struct megasas_instance *instance)
+ */
+ host->irq = instance->pdev->irq;
+ host->unique_id = instance->unique_id;
+- host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS;
++ if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
++ (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
++ host->can_queue =
++ instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
++ } else
++ host->can_queue =
++ instance->max_fw_cmds - MEGASAS_INT_CMDS;
+ host->this_id = instance->init_id;
+ host->sg_tablesize = instance->max_num_sge;
+ host->max_sectors = instance->max_sectors_per_req;
+@@ -2572,6 +3006,9 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+
+ *instance->producer = 0;
+ *instance->consumer = 0;
++ megasas_poll_wait_aen = 0;
++ instance->flag_ieee = 0;
++ instance->ev = NULL;
+
+ instance->evt_detail = pci_alloc_consistent(pdev,
+ sizeof(struct
+@@ -2595,10 +3032,11 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ init_waitqueue_head(&instance->abort_cmd_wait_q);
+
+ spin_lock_init(&instance->cmd_pool_lock);
++ spin_lock_init(&instance->fire_lock);
+ spin_lock_init(&instance->completion_lock);
++ spin_lock_init(&poll_aen_lock);
+
+ mutex_init(&instance->aen_mutex);
+- sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+
+ /*
+ * Initialize PCI related and misc parameters
+@@ -2608,8 +3046,16 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
+ instance->init_id = MEGASAS_DEFAULT_INIT_ID;
+
++ if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
++ (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
++ instance->flag_ieee = 1;
++ sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
++ } else
++ sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
++
+ megasas_dbg_lvl = 0;
+ instance->flag = 0;
++ instance->unload = 1;
+ instance->last_time = 0;
+
+ /*
+@@ -2655,6 +3101,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ if (megasas_io_attach(instance))
+ goto fail_io_attach;
+
++ instance->unload = 0;
+ return 0;
+
+ fail_start_aen:
+@@ -2778,12 +3225,23 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
+
+ instance = pci_get_drvdata(pdev);
+ host = instance->host;
++ instance->unload = 1;
+
+ if (poll_mode_io)
+ del_timer_sync(&instance->io_completion_timer);
+
+ megasas_flush_cache(instance);
+ megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
++
++ /* cancel the delayed work if this work still in queue */
++ if (instance->ev != NULL) {
++ struct megasas_aen_event *ev = instance->ev;
++ cancel_delayed_work(
++ (struct delayed_work *)&ev->hotplug_work);
++ flush_scheduled_work();
++ instance->ev = NULL;
++ }
++
+ tasklet_kill(&instance->isr_tasklet);
+
+ pci_set_drvdata(instance->pdev, instance);
+@@ -2873,6 +3331,8 @@ megasas_resume(struct pci_dev *pdev)
+ megasas_start_timer(instance, &instance->io_completion_timer,
+ megasas_io_completion_timer,
+ MEGASAS_COMPLETION_TIMER_INTERVAL);
++ instance->unload = 0;
++
+ return 0;
+
+ fail_irq:
+@@ -2913,6 +3373,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
+ struct megasas_instance *instance;
+
+ instance = pci_get_drvdata(pdev);
++ instance->unload = 1;
+ host = instance->host;
+
+ if (poll_mode_io)
+@@ -2921,6 +3382,16 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
+ scsi_remove_host(instance->host);
+ megasas_flush_cache(instance);
+ megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
++
++ /* cancel the delayed work if this work still in queue*/
++ if (instance->ev != NULL) {
++ struct megasas_aen_event *ev = instance->ev;
++ cancel_delayed_work(
++ (struct delayed_work *)&ev->hotplug_work);
++ flush_scheduled_work();
++ instance->ev = NULL;
++ }
++
+ tasklet_kill(&instance->isr_tasklet);
+
+ /*
+@@ -2969,6 +3440,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
+ static void megasas_shutdown(struct pci_dev *pdev)
+ {
+ struct megasas_instance *instance = pci_get_drvdata(pdev);
++ instance->unload = 1;
+ megasas_flush_cache(instance);
+ megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
+ }
+@@ -3016,6 +3488,23 @@ static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
+ }
+
+ /**
++ * megasas_mgmt_poll - char node "poll" entry point
++ * */
++static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
++{
++ unsigned int mask;
++ unsigned long flags;
++ poll_wait(file, &megasas_poll_wait, wait);
++ spin_lock_irqsave(&poll_aen_lock, flags);
++ if (megasas_poll_wait_aen)
++ mask = (POLLIN | POLLRDNORM);
++ else
++ mask = 0;
++ spin_unlock_irqrestore(&poll_aen_lock, flags);
++ return mask;
++}
++
++/**
+ * megasas_mgmt_fw_ioctl - Issues management ioctls to FW
+ * @instance: Adapter soft state
+ * @argp: User's ioctl packet
+@@ -3032,7 +3521,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ int error = 0, i;
+ void *sense = NULL;
+ dma_addr_t sense_handle;
+- u32 *sense_ptr;
++ unsigned long *sense_ptr;
+
+ memset(kbuff_arr, 0, sizeof(kbuff_arr));
+
+@@ -3056,6 +3545,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ */
+ memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
+ cmd->frame->hdr.context = cmd->index;
++ cmd->frame->hdr.pad_0 = 0;
+
+ /*
+ * The management interface between applications and the fw uses
+@@ -3109,7 +3599,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ }
+
+ sense_ptr =
+- (u32 *) ((unsigned long)cmd->frame + ioc->sense_off);
++ (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
+ *sense_ptr = sense_handle;
+ }
+
+@@ -3140,8 +3630,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ * sense_ptr points to the location that has the user
+ * sense buffer address
+ */
+- sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
+- ioc->sense_off);
++ sense_ptr = (unsigned long *) ((unsigned long)ioc->frame.raw +
++ ioc->sense_off);
+
+ if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
+ sense, ioc->sense_len)) {
+@@ -3177,20 +3667,6 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ return error;
+ }
+
+-static struct megasas_instance *megasas_lookup_instance(u16 host_no)
+-{
+- int i;
+-
+- for (i = 0; i < megasas_mgmt_info.max_index; i++) {
+-
+- if ((megasas_mgmt_info.instance[i]) &&
+- (megasas_mgmt_info.instance[i]->host->host_no == host_no))
+- return megasas_mgmt_info.instance[i];
+- }
+-
+- return NULL;
+-}
+-
+ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
+ {
+ struct megasas_iocpacket __user *user_ioc =
+@@ -3214,6 +3690,17 @@ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
+ goto out_kfree_ioc;
+ }
+
++ if (instance->hw_crit_error == 1) {
++ printk(KERN_DEBUG "Controller in Crit ERROR\n");
++ error = -ENODEV;
++ goto out_kfree_ioc;
++ }
++
++ if (instance->unload == 1) {
++ error = -ENODEV;
++ goto out_kfree_ioc;
++ }
++
+ /*
+ * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
+ */
+@@ -3249,6 +3736,14 @@ static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
+ if (!instance)
+ return -ENODEV;
+
++ if (instance->hw_crit_error == 1) {
++ error = -ENODEV;
++ }
++
++ if (instance->unload == 1) {
++ return -ENODEV;
++ }
++
+ mutex_lock(&instance->aen_mutex);
+ error = megasas_register_aen(instance, aen.seq_num,
+ aen.class_locale_word);
+@@ -3337,6 +3832,7 @@ static const struct file_operations megasas_mgmt_fops = {
+ .open = megasas_mgmt_open,
+ .fasync = megasas_mgmt_fasync,
+ .unlocked_ioctl = megasas_mgmt_ioctl,
++ .poll = megasas_mgmt_poll,
+ #ifdef CONFIG_COMPAT
+ .compat_ioctl = megasas_mgmt_compat_ioctl,
+ #endif
+@@ -3378,6 +3874,15 @@ static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
+ NULL);
+
+ static ssize_t
++megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
++{
++ return sprintf(buf, "%u\n", support_poll_for_event);
++}
++
++static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
++ megasas_sysfs_show_support_poll_for_event, NULL);
++
++static ssize_t
+ megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
+ {
+ return sprintf(buf, "%u\n", megasas_dbg_lvl);
+@@ -3451,6 +3956,92 @@ out:
+ return retval;
+ }
+
++static void
++megasas_aen_polling(struct work_struct *work)
++{
++ struct megasas_aen_event *ev =
++ container_of(work, struct megasas_aen_event, hotplug_work);
++ struct megasas_instance *instance = ev->instance;
++ union megasas_evt_class_locale class_locale;
++ struct Scsi_Host *host;
++ struct scsi_device *sdev1;
++ u16 pd_index = 0;
++ int i, j, doscan = 0;
++ u32 seq_num;
++ int error;
++
++ if (!instance) {
++ printk(KERN_ERR "invalid instance!\n");
++ kfree(ev);
++ return;
++ }
++ instance->ev = NULL;
++ host = instance->host;
++ if (instance->evt_detail) {
++
++ switch (instance->evt_detail->code) {
++ case MR_EVT_PD_INSERTED:
++ case MR_EVT_PD_REMOVED:
++ case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
++ doscan = 1;
++ break;
++ default:
++ doscan = 0;
++ break;
++ }
++ } else {
++ printk(KERN_ERR "invalid evt_detail!\n");
++ kfree(ev);
++ return;
++ }
++
++ if (doscan) {
++ printk(KERN_INFO "scanning ...\n");
++ megasas_get_pd_list(instance);
++ for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
++ for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
++ pd_index = i*MEGASAS_MAX_DEV_PER_CHANNEL + j;
++ sdev1 = scsi_device_lookup(host, i, j, 0);
++ if (instance->pd_list[pd_index].driveState ==
++ MR_PD_STATE_SYSTEM) {
++ if (!sdev1) {
++ scsi_add_device(host, i, j, 0);
++ }
++ if (sdev1)
++ scsi_device_put(sdev1);
++ } else {
++ if (sdev1) {
++ scsi_remove_device(sdev1);
++ scsi_device_put(sdev1);
++ }
++ }
++ }
++ }
++ }
++
++ if ( instance->aen_cmd != NULL ) {
++ kfree(ev);
++ return ;
++ }
++
++ seq_num = instance->evt_detail->seq_num + 1;
++
++ /* Register AEN with FW for latest sequence number plus 1 */
++ class_locale.members.reserved = 0;
++ class_locale.members.locale = MR_EVT_LOCALE_ALL;
++ class_locale.members.class = MR_EVT_CLASS_DEBUG;
++ mutex_lock(&instance->aen_mutex);
++ error = megasas_register_aen(instance, seq_num,
++ class_locale.word);
++ mutex_unlock(&instance->aen_mutex);
++
++ if (error)
++ printk(KERN_ERR "register aen failed error %x\n", error);
++
++ kfree(ev);
++}
++
++
+ static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
+ megasas_sysfs_show_poll_mode_io,
+ megasas_sysfs_set_poll_mode_io);
+@@ -3468,6 +4059,8 @@ static int __init megasas_init(void)
+ printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
+ MEGASAS_EXT_VERSION);
+
++ support_poll_for_event = 2;
++
+ memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
+
+ /*
+@@ -3500,6 +4093,12 @@ static int __init megasas_init(void)
+ &driver_attr_release_date);
+ if (rval)
+ goto err_dcf_rel_date;
++
++ rval = driver_create_file(&megasas_pci_driver.driver,
++ &driver_attr_support_poll_for_event);
++ if (rval)
++ goto err_dcf_support_poll_for_event;
++
+ rval = driver_create_file(&megasas_pci_driver.driver,
+ &driver_attr_dbg_lvl);
+ if (rval)
+@@ -3516,7 +4115,12 @@ err_dcf_poll_mode_io:
+ &driver_attr_dbg_lvl);
+ err_dcf_dbg_lvl:
+ driver_remove_file(&megasas_pci_driver.driver,
++ &driver_attr_support_poll_for_event);
++
++err_dcf_support_poll_for_event:
++ driver_remove_file(&megasas_pci_driver.driver,
+ &driver_attr_release_date);
++
+ err_dcf_rel_date:
+ driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
+ err_dcf_attr_ver:
+diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
+index 0d03324..72b28e4 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.h
++++ b/drivers/scsi/megaraid/megaraid_sas.h
+@@ -18,9 +18,9 @@
+ /*
+ * MegaRAID SAS Driver meta data
+ */
+-#define MEGASAS_VERSION "00.00.04.01"
+-#define MEGASAS_RELDATE "July 24, 2008"
+-#define MEGASAS_EXT_VERSION "Thu July 24 11:41:51 PST 2008"
++#define MEGASAS_VERSION "00.00.04.12-rc1"
++#define MEGASAS_RELDATE "Sep. 17, 2009"
++#define MEGASAS_EXT_VERSION "Thu Sep. 17 11:41:51 PST 2009"
+
+ /*
+ * Device IDs
+@@ -30,6 +30,8 @@
+ #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413
+ #define PCI_DEVICE_ID_LSI_SAS1078GEN2 0x0078
+ #define PCI_DEVICE_ID_LSI_SAS0079GEN2 0x0079
++#define PCI_DEVICE_ID_LSI_SAS0073SKINNY 0x0073
++#define PCI_DEVICE_ID_LSI_SAS0071SKINNY 0x0071
+
+ /*
+ * =====================================
+@@ -94,6 +96,7 @@
+ #define MFI_FRAME_DIR_WRITE 0x0008
+ #define MFI_FRAME_DIR_READ 0x0010
+ #define MFI_FRAME_DIR_BOTH 0x0018
++#define MFI_FRAME_IEEE 0x0020
+
+ /*
+ * Definition for cmd_status
+@@ -131,6 +134,7 @@
+ #define MR_DCMD_CLUSTER 0x08000000
+ #define MR_DCMD_CLUSTER_RESET_ALL 0x08010100
+ #define MR_DCMD_CLUSTER_RESET_LD 0x08010200
++#define MR_DCMD_PD_LIST_QUERY 0x02010100
+
+ /*
+ * MFI command completion codes
+@@ -251,9 +255,100 @@ enum MR_EVT_ARGS {
+ MR_EVT_ARGS_STR,
+ MR_EVT_ARGS_TIME,
+ MR_EVT_ARGS_ECC,
++ MR_EVT_ARGS_LD_PROP,
++ MR_EVT_ARGS_PD_SPARE,
++ MR_EVT_ARGS_PD_INDEX,
++ MR_EVT_ARGS_DIAG_PASS,
++ MR_EVT_ARGS_DIAG_FAIL,
++ MR_EVT_ARGS_PD_LBA_LBA,
++ MR_EVT_ARGS_PORT_PHY,
++ MR_EVT_ARGS_PD_MISSING,
++ MR_EVT_ARGS_PD_ADDRESS,
++ MR_EVT_ARGS_BITMAP,
++ MR_EVT_ARGS_CONNECTOR,
++ MR_EVT_ARGS_PD_PD,
++ MR_EVT_ARGS_PD_FRU,
++ MR_EVT_ARGS_PD_PATHINFO,
++ MR_EVT_ARGS_PD_POWER_STATE,
++ MR_EVT_ARGS_GENERIC,
++};
+
++/*
++ * define constants for device list query options
++ */
++enum MR_PD_QUERY_TYPE {
++ MR_PD_QUERY_TYPE_ALL = 0,
++ MR_PD_QUERY_TYPE_STATE = 1,
++ MR_PD_QUERY_TYPE_POWER_STATE = 2,
++ MR_PD_QUERY_TYPE_MEDIA_TYPE = 3,
++ MR_PD_QUERY_TYPE_SPEED = 4,
++ MR_PD_QUERY_TYPE_EXPOSED_TO_HOST = 5,
+ };
+
++#define MR_EVT_CFG_CLEARED 0x0004
++#define MR_EVT_LD_STATE_CHANGE 0x0051
++#define MR_EVT_PD_INSERTED 0x005b
++#define MR_EVT_PD_REMOVED 0x0070
++#define MR_EVT_LD_CREATED 0x008a
++#define MR_EVT_LD_DELETED 0x008b
++#define MR_EVT_FOREIGN_CFG_IMPORTED 0x00db
++#define MR_EVT_LD_OFFLINE 0x00fc
++#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED 0x0152
++#define MAX_LOGICAL_DRIVES 64
++
++enum MR_PD_STATE {
++ MR_PD_STATE_UNCONFIGURED_GOOD = 0x00,
++ MR_PD_STATE_UNCONFIGURED_BAD = 0x01,
++ MR_PD_STATE_HOT_SPARE = 0x02,
++ MR_PD_STATE_OFFLINE = 0x10,
++ MR_PD_STATE_FAILED = 0x11,
++ MR_PD_STATE_REBUILD = 0x14,
++ MR_PD_STATE_ONLINE = 0x18,
++ MR_PD_STATE_COPYBACK = 0x20,
++ MR_PD_STATE_SYSTEM = 0x40,
++ };
++
++
++ /*
++ * defines the physical drive address structure
++ */
++struct MR_PD_ADDRESS {
++ u16 deviceId;
++ u16 enclDeviceId;
++
++ union {
++ struct {
++ u8 enclIndex;
++ u8 slotNumber;
++ } mrPdAddress;
++ struct {
++ u8 enclPosition;
++ u8 enclConnectorIndex;
++ } mrEnclAddress;
++ };
++ u8 scsiDevType;
++ union {
++ u8 connectedPortBitmap;
++ u8 connectedPortNumbers;
++ };
++ u64 sasAddr[2];
++} __packed;
++
++/*
++ * defines the physical drive list structure
++ */
++struct MR_PD_LIST {
++ u32 size;
++ u32 count;
++ struct MR_PD_ADDRESS addr[1];
++} __packed;
++
++struct megasas_pd_list {
++ u16 tid;
++ u8 driveType;
++ u8 driveState;
++} __packed;
++
+ /*
+ * SAS controller properties
+ */
+@@ -282,7 +377,7 @@ struct megasas_ctrl_prop {
+ u8 expose_encl_devices;
+ u8 reserved[38];
+
+-} __attribute__ ((packed));
++} __packed;
+
+ /*
+ * SAS controller information
+@@ -525,7 +620,7 @@ struct megasas_ctrl_info {
+
+ u8 pad[0x800 - 0x6a0];
+
+-} __attribute__ ((packed));
++} __packed;
+
+ /*
+ * ===============================
+@@ -540,6 +635,8 @@ struct megasas_ctrl_info {
+ #define MEGASAS_DEFAULT_INIT_ID -1
+ #define MEGASAS_MAX_LUN 8
+ #define MEGASAS_MAX_LD 64
++#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \
++ MEGASAS_MAX_DEV_PER_CHANNEL)
+
+ #define MEGASAS_DBG_LVL 1
+
+@@ -570,6 +667,7 @@ struct megasas_ctrl_info {
+ * is shown below
+ */
+ #define MEGASAS_INT_CMDS 32
++#define MEGASAS_SKINNY_INT_CMDS 5
+
+ /*
+ * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
+@@ -584,6 +682,8 @@ struct megasas_ctrl_info {
+ #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000
+ #define MFI_REPLY_GEN2_MESSAGE_INTERRUPT 0x00000001
+ #define MFI_GEN2_ENABLE_INTERRUPT_MASK (0x00000001 | 0x00000004)
++#define MFI_REPLY_SKINNY_MESSAGE_INTERRUPT 0x40000000
++#define MFI_SKINNY_ENABLE_INTERRUPT_MASK (0x00000001)
+
+ /*
+ * register set for both 1068 and 1078 controllers
+@@ -644,10 +744,17 @@ struct megasas_sge64 {
+
+ } __attribute__ ((packed));
+
++struct megasas_sge_skinny {
++ u64 phys_addr;
++ u32 length;
++ u32 flag;
++} __packed;
++
+ union megasas_sgl {
+
+ struct megasas_sge32 sge32[1];
+ struct megasas_sge64 sge64[1];
++ struct megasas_sge_skinny sge_skinny[1];
+
+ } __attribute__ ((packed));
+
+@@ -1061,16 +1168,10 @@ struct megasas_evt_detail {
+
+ } __attribute__ ((packed));
+
+- struct megasas_instance_template {
+- void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *);
+-
+- void (*enable_intr)(struct megasas_register_set __iomem *) ;
+- void (*disable_intr)(struct megasas_register_set __iomem *);
+-
+- int (*clear_intr)(struct megasas_register_set __iomem *);
+-
+- u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
+- };
++struct megasas_aen_event {
++ struct work_struct hotplug_work;
++ struct megasas_instance *instance;
++};
+
+ struct megasas_instance {
+
+@@ -1085,17 +1186,21 @@ struct megasas_instance {
+ unsigned long base_addr;
+ struct megasas_register_set __iomem *reg_set;
+
++ struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
+ s8 init_id;
+
+ u16 max_num_sge;
+ u16 max_fw_cmds;
+ u32 max_sectors_per_req;
++ struct megasas_aen_event *ev;
+
+ struct megasas_cmd **cmd_list;
+ struct list_head cmd_pool;
+ spinlock_t cmd_pool_lock;
+ /* used to synch producer, consumer ptrs in dpc */
+ spinlock_t completion_lock;
++ /* used to sync fire the cmd to fw */
++ spinlock_t fire_lock;
+ struct dma_pool *frame_dma_pool;
+ struct dma_pool *sense_dma_pool;
+
+@@ -1120,11 +1225,25 @@ struct megasas_instance {
+ struct tasklet_struct isr_tasklet;
+
+ u8 flag;
++ u8 unload;
++ u8 flag_ieee;
+ unsigned long last_time;
+
+ struct timer_list io_completion_timer;
+ };
+
++struct megasas_instance_template {
++ void (*fire_cmd)(struct megasas_instance *, dma_addr_t, \
++ u32, struct megasas_register_set __iomem *);
++
++ void (*enable_intr)(struct megasas_register_set __iomem *) ;
++ void (*disable_intr)(struct megasas_register_set __iomem *);
++
++ int (*clear_intr)(struct megasas_register_set __iomem *);
++
++ u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
++};
++
+ #define MEGASAS_IS_LOGICAL(scp) \
+ (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
+
diff --git a/patches.drivers/phy-broadcom-bug-fixes-for-sp1.patch b/patches.drivers/phy-broadcom-bug-fixes-for-sp1.patch
new file mode 100644
index 0000000000..909af3a2dc
--- /dev/null
+++ b/patches.drivers/phy-broadcom-bug-fixes-for-sp1.patch
@@ -0,0 +1,382 @@
+From: Matt Carlson <mcarlson@broadcom.com>
+Subject: phy/broadcom: bug fixes for SP1
+References: FATE#307117, bnc#556234
+
+commit 8649f13d2d810406da444a6101906041b796fbde
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:30:00 2009 +0000
+
+ broadcom: Consolidate dev_flags definitions
+
+ This patch moves all the dev_flags enumerations outside the broadcom.c
+ file to include/linux/brcmphy.h. The existing flags were not used yet
+ and have been re-enumerated to avoid conflicts.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 219c6efefaa3f5cd05db52cda50402b2e1c9ae21
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:28:33 2009 +0000
+
+ broadcom: Fix slow link problem
+
+ When a 50610 or 50610M is paired against particular remote partners,
+ link is slow to come up. This patch works around the problem.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 47b1b53b41d63f27b308981fde307d415e514431
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:28:04 2009 +0000
+
+ broadcom: Isolate phy dsp accesses
+
+ This patch consolidates the code that requires the SMDSP clock to be
+ enabled into a single function that (hopefully) makes the dependency
+ obvious.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+
+---
+ drivers/net/phy/broadcom.c | 210 +++++++++++++++++++++++++++++++--------------
+ include/linux/brcmphy.h | 19 ++--
+ 2 files changed, 158 insertions(+), 71 deletions(-)
+
+Index: linux-2.6.31-master/drivers/net/phy/broadcom.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/phy/broadcom.c
++++ linux-2.6.31-master/drivers/net/phy/broadcom.c
+@@ -16,6 +16,7 @@
+
+ #include <linux/module.h>
+ #include <linux/phy.h>
++#include <linux/brcmphy.h>
+
+ #define PHY_ID_BCM50610 0x0143bd60
+ #define PHY_ID_BCM50610M 0x0143bd70
+@@ -24,6 +25,9 @@
+ #define BRCM_PHY_MODEL(phydev) \
+ ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
+
++#define BRCM_PHY_REV(phydev) \
++ ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
++
+
+ #define MII_BCM54XX_ECR 0x10 /* BCM54xx extended control register */
+ #define MII_BCM54XX_ECR_IM 0x1000 /* Interrupt mask */
+@@ -94,22 +98,35 @@
+ #define BCM_LED_SRC_OFF 0xe /* Tied high */
+ #define BCM_LED_SRC_ON 0xf /* Tied low */
+
++
+ /*
+ * BCM5482: Shadow registers
+ * Shadow values go into bits [14:10] of register 0x1c to select a shadow
+ * register to access.
+ */
++/* 00101: Spare Control Register 3 */
++#define BCM54XX_SHD_SCR3 0x05
++#define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001
++#define BCM54XX_SHD_SCR3_DLLAPD_DIS 0x0002
++#define BCM54XX_SHD_SCR3_TRDDAPD 0x0004
++
++/* 01010: Auto Power-Down */
++#define BCM54XX_SHD_APD 0x0a
++#define BCM54XX_SHD_APD_EN 0x0020
++
+ #define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 */
+ /* LED3 / ~LINKSPD[2] selector */
+ #define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4)
+ /* LED1 / ~LINKSPD[1] selector */
+ #define BCM5482_SHD_LEDS1_LED1(src) ((src & 0xf) << 0)
++#define BCM54XX_SHD_RGMII_MODE 0x0b /* 01011: RGMII Mode Selector */
+ #define BCM5482_SHD_SSD 0x14 /* 10100: Secondary SerDes control */
+ #define BCM5482_SHD_SSD_LEDM 0x0008 /* SSD LED Mode enable */
+ #define BCM5482_SHD_SSD_EN 0x0001 /* SSD enable */
+ #define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */
+ #define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
+
++
+ /*
+ * EXPANSION SHADOW ACCESS REGISTERS. (PHY REG 0x15, 0x16, and 0x17)
+ */
+@@ -138,16 +155,6 @@
+ #define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */
+ #define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */
+
+-/*
+- * Device flags for PHYs that can be configured for different operating
+- * modes.
+- */
+-#define PHY_BCM_FLAGS_VALID 0x80000000
+-#define PHY_BCM_FLAGS_INTF_XAUI 0x00000020
+-#define PHY_BCM_FLAGS_INTF_SGMII 0x00000010
+-#define PHY_BCM_FLAGS_MODE_1000BX 0x00000002
+-#define PHY_BCM_FLAGS_MODE_COPPER 0x00000001
+-
+
+ /*****************************************************************************/
+ /* Fast Ethernet Transceiver definitions. */
+@@ -237,53 +244,145 @@ static int bcm54xx_auxctl_write(struct p
+ return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
+ }
+
++/* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
+ static int bcm50610_a0_workaround(struct phy_device *phydev)
+ {
+ int err;
+
+- err = bcm54xx_auxctl_write(phydev,
+- MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+- MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
+- MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+- if (err < 0)
+- return err;
+-
+- err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08,
+- MII_BCM54XX_EXP_EXP08_RJCT_2MHZ |
+- MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE);
+- if (err < 0)
+- goto error;
+-
+ err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH0,
+ MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
+ MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
+ if (err < 0)
+- goto error;
++ return err;
+
+ err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH3,
+ MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
+ if (err < 0)
+- goto error;
++ return err;
+
+ err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75,
+ MII_BCM54XX_EXP_EXP75_VDACCTRL);
+ if (err < 0)
+- goto error;
++ return err;
+
+ err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP96,
+ MII_BCM54XX_EXP_EXP96_MYST);
+ if (err < 0)
+- goto error;
++ return err;
+
+ err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP97,
+ MII_BCM54XX_EXP_EXP97_MYST);
+
++ return err;
++}
++
++static int bcm54xx_phydsp_config(struct phy_device *phydev)
++{
++ int err, err2;
++
++ /* Enable the SMDSP clock */
++ err = bcm54xx_auxctl_write(phydev,
++ MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
++ MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
++ MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
++ if (err < 0)
++ return err;
++
++ if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
++ BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) {
++ /* Clear bit 9 to fix a phy interop issue. */
++ err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08,
++ MII_BCM54XX_EXP_EXP08_RJCT_2MHZ);
++ if (err < 0)
++ goto error;
++
++ if (phydev->drv->phy_id == PHY_ID_BCM50610) {
++ err = bcm50610_a0_workaround(phydev);
++ if (err < 0)
++ goto error;
++ }
++ }
++
++ if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
++ int val;
++
++ val = bcm54xx_exp_read(phydev, MII_BCM54XX_EXP_EXP75);
++ if (val < 0)
++ goto error;
++
++ val |= MII_BCM54XX_EXP_EXP75_CM_OSC;
++ err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, val);
++ }
++
+ error:
+- bcm54xx_auxctl_write(phydev,
+- MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+- MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
++ /* Disable the SMDSP clock */
++ err2 = bcm54xx_auxctl_write(phydev,
++ MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
++ MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+
+- return err;
++ /* Return the first error reported. */
++ return err ? err : err2;
++}
++
++static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
++{
++ u32 val, orig;
++ bool clk125en = true;
++
++ /* Abort if we are using an untested phy. */
++ if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 ||
++ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 ||
++ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M)
++ return;
++
++ val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_SCR3);
++ if (val < 0)
++ return;
++
++ orig = val;
++
++ if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
++ BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
++ BRCM_PHY_REV(phydev) >= 0x3) {
++ /*
++ * Here, bit 0 _disables_ CLK125 when set.
++ * This bit is set by default.
++ */
++ clk125en = false;
++ } else {
++ if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
++ /* Here, bit 0 _enables_ CLK125 when set */
++ val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
++ clk125en = false;
++ }
++ }
++
++ if (clk125en == false ||
++ (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
++ val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
++ else
++ val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
++
++ if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY)
++ val |= BCM54XX_SHD_SCR3_TRDDAPD;
++
++ if (orig != val)
++ bcm54xx_shadow_write(phydev, BCM54XX_SHD_SCR3, val);
++
++ val = bcm54xx_shadow_read(phydev, BCM54XX_SHD_APD);
++ if (val < 0)
++ return;
++
++ orig = val;
++
++ if (clk125en == false ||
++ (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
++ val |= BCM54XX_SHD_APD_EN;
++ else
++ val &= ~BCM54XX_SHD_APD_EN;
++
++ if (orig != val)
++ bcm54xx_shadow_write(phydev, BCM54XX_SHD_APD, val);
+ }
+
+ static int bcm54xx_config_init(struct phy_device *phydev)
+@@ -308,38 +407,17 @@ static int bcm54xx_config_init(struct ph
+ if (err < 0)
+ return err;
+
+- if (phydev->drv->phy_id == PHY_ID_BCM50610) {
+- err = bcm50610_a0_workaround(phydev);
+- if (err < 0)
+- return err;
+- }
+-
+- if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
+- int err2;
+-
+- err = bcm54xx_auxctl_write(phydev,
+- MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+- MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
+- MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+- if (err < 0)
+- return err;
+-
+- reg = bcm54xx_exp_read(phydev, MII_BCM54XX_EXP_EXP75);
+- if (reg < 0)
+- goto error;
+-
+- reg |= MII_BCM54XX_EXP_EXP75_CM_OSC;
+- err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, reg);
++ if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
++ BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
++ (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
++ bcm54xx_shadow_write(phydev, BCM54XX_SHD_RGMII_MODE, 0);
++
++ if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) ||
++ (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) ||
++ (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
++ bcm54xx_adjust_rxrefclk(phydev);
+
+-error:
+- err2 = bcm54xx_auxctl_write(phydev,
+- MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+- MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+- if (err)
+- return err;
+- if (err2)
+- return err2;
+- }
++ bcm54xx_phydsp_config(phydev);
+
+ return 0;
+ }
+@@ -564,9 +642,11 @@ static int brcm_fet_config_init(struct p
+ if (err < 0)
+ goto done;
+
+- /* Enable auto power down */
+- err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
+- MII_BRCM_FET_SHDW_AS2_APDE);
++ if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
++ /* Enable auto power down */
++ err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
++ MII_BRCM_FET_SHDW_AS2_APDE);
++ }
+
+ done:
+ /* Disable shadow register access */
+Index: linux-2.6.31-master/include/linux/brcmphy.h
+===================================================================
+--- linux-2.6.31-master.orig/include/linux/brcmphy.h
++++ linux-2.6.31-master/include/linux/brcmphy.h
+@@ -1,6 +1,13 @@
+-#define PHY_BRCM_WIRESPEED_ENABLE 0x00000001
+-#define PHY_BRCM_AUTO_PWRDWN_ENABLE 0x00000002
+-#define PHY_BRCM_APD_CLK125_ENABLE 0x00000004
+-#define PHY_BRCM_STD_IBND_DISABLE 0x00000008
+-#define PHY_BRCM_EXT_IBND_RX_ENABLE 0x00000010
+-#define PHY_BRCM_EXT_IBND_TX_ENABLE 0x00000020
++#define PHY_BCM_FLAGS_MODE_COPPER 0x00000001
++#define PHY_BCM_FLAGS_MODE_1000BX 0x00000002
++#define PHY_BCM_FLAGS_INTF_SGMII 0x00000010
++#define PHY_BCM_FLAGS_INTF_XAUI 0x00000020
++#define PHY_BRCM_WIRESPEED_ENABLE 0x00000100
++#define PHY_BRCM_AUTO_PWRDWN_ENABLE 0x00000200
++#define PHY_BRCM_RX_REFCLK_UNUSED 0x00000400
++#define PHY_BRCM_STD_IBND_DISABLE 0x00000800
++#define PHY_BRCM_EXT_IBND_RX_ENABLE 0x00001000
++#define PHY_BRCM_EXT_IBND_TX_ENABLE 0x00002000
++#define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000
++#define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000
++#define PHY_BCM_FLAGS_VALID 0x80000000
diff --git a/patches.drivers/tg3-entropy-source.patch b/patches.drivers/tg3-entropy-source.patch
new file mode 100644
index 0000000000..cd6a75d725
--- /dev/null
+++ b/patches.drivers/tg3-entropy-source.patch
@@ -0,0 +1,63 @@
+From: Brandon Philips <bphilips@suse.de>
+Subject: [PATCH] tg3: entropy source
+Patch-mainline: never
+References: FATE#307517
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+
+---
+ drivers/net/tg3.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+Index: linux-2.6.31-master/drivers/net/tg3.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/tg3.c
++++ linux-2.6.31-master/drivers/net/tg3.c
+@@ -15,7 +15,6 @@
+ * notice is accompanying it.
+ */
+
+-
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/kernel.h>
+@@ -66,6 +65,10 @@
+
+ #include "tg3.h"
+
++static int entropy = 0;
++module_param(entropy, int, 0);
++MODULE_PARM_DESC(entropy, "Allow tg3 to populate the /dev/random entropy pool");
++
+ #define DRV_MODULE_NAME "tg3"
+ #define PFX DRV_MODULE_NAME ": "
+ #define DRV_MODULE_VERSION "3.102"
+@@ -8020,10 +8023,13 @@ restart_timer:
+ static int tg3_request_irq(struct tg3 *tp, int irq_num)
+ {
+ irq_handler_t fn;
+- unsigned long flags;
++ unsigned long flags = 0;
+ char *name;
+ struct tg3_napi *tnapi = &tp->napi[irq_num];
+
++ if (entropy)
++ flags = IRQF_SAMPLE_RANDOM;
++
+ if (tp->irq_cnt == 1)
+ name = tp->dev->name;
+ else {
+@@ -8036,12 +8042,11 @@ static int tg3_request_irq(struct tg3 *t
+ fn = tg3_msi;
+ if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+ fn = tg3_msi_1shot;
+- flags = IRQF_SAMPLE_RANDOM;
+ } else {
+ fn = tg3_interrupt;
+ if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+ fn = tg3_interrupt_tagged;
+- flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
++ flags |= IRQF_SHARED;
+ }
+
+ return request_irq(tnapi->irq_vec, fn, flags, name, tnapi);
diff --git a/patches.drivers/tg3-update-version-to-3.104.patch b/patches.drivers/tg3-update-version-to-3.104.patch
new file mode 100644
index 0000000000..4be5365731
--- /dev/null
+++ b/patches.drivers/tg3-update-version-to-3.104.patch
@@ -0,0 +1,2446 @@
+From: Matt Carlson <mcarlson@broadcom.com>
+Subject: tg3: Update version to 3.104
+References: bnc#556234, FATE#307117
+
+commit c5d5d1721763842a516529e553433d13b11c3f31
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:52 2009 +0000
+
+ tg3: Update version to 3.104
+
+ This patch updates the tg3 version to 3.104.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 5001e2f638011859c1351f9fe57ca4e545a15c47
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:51 2009 +0000
+
+ tg3: Fix DIDs, Enable 5717 support
+
+ This patch fixes the 5717 variant device ID enumerations and adds those
+ DIDs to the PCI ID table.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit b196c7e45f30cbcd38c83386bc8a04a21477f8d3
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:50 2009 +0000
+
+ tg3: Add rx prod ring consolidation
+
+ This patch adds code to funnel each MSI-X vector's rx packet buffers
+ into a single set of producer rings which will then be submitted to the
+ hardware.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Signed-off-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 66711e66639776685aeaad774488be1857abce26
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:49 2009 +0000
+
+ tg3: Create aliases for rx producer mailbox regs
+
+ The rx producer mailbox registers are used in several spots in the code.
+ The addition of TG3_64BIT_REG_LOW makes register references
+ uncomfortably long. This patch creates an alias for the standard and
+ jumbo ring producer index registers to make the code cleaner.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Signed-off-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 2b2cdb65bec42d38268b2ac115876b066afa7f95
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:48 2009 +0000
+
+ tg3: Lay proucer ring handling groundwork
+
+ The patch increases the number of producer rings available and
+ implements the constructor and destructor code that deals with them.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 4361935afe3abc3e5a93006b99197fac1fabbd50
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:47 2009 +0000
+
+ tg3: Consider rx_std_prod_idx a hw mailbox
+
+ This patch changes how the code uses the rx_std_prod_idx member. In the
+ following patch, the code will be changed so that it will act just like
+ a hardware mailbox. This patch prepares the code so that memory barriers
+ can be more easily inserted.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 411da6407e778bf946911df08bb5afc505422f31
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:46 2009 +0000
+
+ tg3: rename rx_[std|jmb]_ptr
+
+ A later patch is going to add consumer indicies for the producer rings.
+ To keep things readable, this patch renames rx_[std|jmb]_ptr to
+ rx_[std|jmb]_prod_idx.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 86b21e59c9a65c8e46d35ac6c4220f63639828c6
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:45 2009 +0000
+
+ tg3: tg3_alloc_rx_skb(tnapi => tp)
+
+ This patch converts the tnapi argument of tg3_alloc_rx_skb() to tp. The
+ level of indirection is unnecessary.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit a3896167160ce9ad1eadeb88fd2f3971888444ae
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:44 2009 +0000
+
+ tg3: Add prodring parameter to tg3_alloc_rx_skb()
+
+ This patch changes the tg3_alloc_rx_skb() implementation to accept the
+ destination producer ring set pointer as a parameter rather than
+ assuming the source and destination producer rings are the same.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit afc081f83c59a7cf2c025a3ed89d011b5db556eb
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:43 2009 +0000
+
+ tg3: Make tg3_alloc_rx_skb() a dst-only operation
+
+ This patch removes the source index parameter of tg3_alloc_rx_skb(). A
+ later patch will make it possible for the source and destination
+ producer rings to be different. This patch opts to make
+ tg3_alloc_rx_skb() a destination-only implementation and move the code
+ sensitive to the difference elsewhere.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 78f90dcf184b8225a24217605c4289f1986451a3
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:42 2009 +0000
+
+ tg3: Move napi_add calls below tg3_get_invariants
+
+ tg3_get_invariants(), among other things, discovers whether or not
+ the device is MSI-X capable and how many interrupts it supports.
+ This discovery needs to happen before registering NAPI instances with
+ netdev. This patch moves the code block that calls napi_add later in
+ tg3_init_one() so that tg3_get_invariants() has a chance to run first.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 35f2d7d0d7c222a580da0ed91c8d70c54267620a
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:41 2009 +0000
+
+ tg3: Create tg3_poll_msix() for non-zero MSIX vecs
+
+ This patch gives all non-zero MSIX vectors their own NAPI handler. This
+ will make NAPI handling for those vectors slightly more efficient.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit cbf9ca6cf8304beb640a948709c4672bc1d5a55f
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:40 2009 +0000
+
+ tg3: Allow DMAs to cross cacheline boundaries
+
+ By default, the 5717 (and future chips) break up PCIe DMA packets across
+ cacheline boundaries. This isn't necessary on x86. This patch
+ selectively loosens the restriction.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 615774fe598f8ee971a8dfeb1f2ec4211241c433
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:39 2009 +0000
+
+ tg3: Use tg3_start_xmit_dma_bug for 5717 A0
+
+ The A0 revision of the 5717 has problems with short packet fragments.
+ It needs to use the tg3_start_xmit_dma_bug() routine.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit e849cdc309de4a1e49dc3c23c6c36da91b990c9f
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:38 2009 +0000
+
+ tg3: Add new HW_TSO_3 flag for 5717
+
+ The 5717 sets up TSO slightly differently in the transmit path. It
+ looks like this method will be the new way of doing things. This patch
+ defines a flag to indicate this.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 507399f18ea5810de42f0ea228c14305a8f67512
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:37 2009 +0000
+
+ tg3: Refine TSO and MSI discovery
+
+ This patch consolidates the TSO capability discovery code into its own
+ code block. The code that decides whether or not to allow TSO is then
+ cleaned up. Finally, the patch consolidates all MSI and MSIX
+ capability code into a single code block.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit f66a29b03a2637ff052f2b8a81a5417fa44e228b
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:36 2009 +0000
+
+ tg3: Move TG3_FLG2_PROTECTED_NVRAM to tg3_flags3
+
+ We need room for another TSO flag and it would be most efficient if it
+ resided in tg3_flags2. This patch moves the TG3_FLG2_PROTECTED_NVRAM
+ to tg3_flags3 to make room.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 24f4efd4e6c89a4093d0b8653d6669e45de45001
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:35 2009 +0000
+
+ tg3: Napify tg3_start_xmit_dma_bug()
+
+ This patch converts tg3_start_xmit_dma_bug() to accomodate multiple NAPI
+ instances. This is prep work for a later patch in this series.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 87668d352aa8d135bd695a050f18bbfc7b50b506
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:34 2009 +0000
+
+ tg3: Don't touch RCB nic addresses
+
+ This patch avoids reprogramming the RCB NIC addresses for all 5755 and
+ later devices. The address is incorrect for 5717 devices and should be
+ correct by default for all other affected devices.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit c2060fe1f36565e60e622662a4519babd3b72f68
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Fri Nov 13 13:03:33 2009 +0000
+
+ tg3: Add 5717 phy ID
+
+ This patch adds the 5717 phy ID.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 123b43e9716115302a0095e14f2c545811712715
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:33:03 2009 +0000
+
+ tg3: Update version to 3.103
+
+ This patch updates the tg3 version to 3.103.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 52fae0837153e86e4dabaf5df517a0b8b7a20bd7
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:32:38 2009 +0000
+
+ tg3 / broadcom: Optionally disable TXC if no link
+
+ This patch adds code to disable the TXC and RXC reference clocks if link
+ is not available.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit c704dc23cac0e433796bfe0a1fe2f1a64da11ac7
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:32:12 2009 +0000
+
+ tg3 / broadcom: Add APD support for GPHYs
+
+ This patch adds an RXC auto power-down feature to the code that supports
+ the gphys.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 32e5a8d651c0dbb02bf82ca954206282e44c4b11
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:31:39 2009 +0000
+
+ tg3 / broadcom: Add code to disable rxc refclk
+
+ The 5785 does not use the RXC reference clock. Turning it off is
+ desirable as it saves power.
+
+ By default, the 50610 enables the RXC reference clock and the 50610M
+ disables it. Presumably this is one of the reasons why the hardware
+ architect chose one over the other.
+
+ Adding a "rx reference clock disable" flag is not the ideal way to
+ describe the option, as it would force the MAC using a 50610M to set
+ the flag. Ideally we want the flags to represent opt-in behavior that
+ deviates from hardware defaults. Furthermore, the lack of a
+ "disable" flag implies that the requester wants the rx reference clock
+ enabled, which doesn't necessarily follow.
+
+ By presenting the option as a passive statement (rx reference clock
+ unused) rather than a command, I hope to convey an opt-in option to
+ disable the rx reference clock that falls back to hardware defaults if
+ not set. A secondary benefit of this is that it keeps the
+ intelligence about phy defaults in the broadcom module where it belongs
+ and allows the broadcom module more latitude should a bug arise.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit cdd4e09d692bd4f3457b3789279005e112b7696d
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:31:11 2009 +0000
+
+ tg3 / broadcom: Refine AC131 APD support
+
+ Auto power-down (APD) support is a power-saving feature. It should be
+ selectively enabled since it might expose MAC bugs. This patch changes
+ the code to enable APD only if the PHY_BRCM_AUTO_PWRDWN_ENABLE flag is
+ set. The tg3 driver was changed to set this bit.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 63a14ce449dd6d647de2725809159eb072b2c44f
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:30:40 2009 +0000
+
+ tg3 / broadcom: Add PHY_BRCM_CLEAR_RGMII_MODE flag
+
+ Broadcom 50610M parts changed the default definitions of the RGMII mode
+ shadow register. The 5785 needs the RGMII mode selection bits [4:3]
+ cleared.
+
+ The default value of the remaining bits in this register are zero.
+ Rather than unnecessarily burn an extra bit in the dev_flags member in
+ an attempt to enumerate all possible combinations, this patch take a
+ more course grained approach and labels the option as "clear all bits".
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit c73430d04ec75962e20e186d34c40b6d999f0968
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:29:34 2009 +0000
+
+ tg3: Add 50610M phy ID for 5785
+
+ This patch adds the 50610M phy ID for 5785.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 303fc9218246a748304c005e629d658927cf12d0
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:27:34 2009 +0000
+
+ tg3: Extend loopback test timeout
+
+ This patch extends the loopback test timeout from 250 usec to 350 usec.
+ When the 5785 is paired against an AC131 phy, the older timeout is
+ just a little too close to the expected performance based on timings.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit c3df0748ee43101dfc5c94d1f61ddfca0ff5baa4
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:27:02 2009 +0000
+
+ tg3: 5785: Set port mode to MII when link down
+
+ This patch sets the port mode to MII when the link is down for the 5785.
+ Setting the port mode to MII instead of GMII saves power.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 0e5f784c77197edf29d2770b518dc78777d5a480
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:26:38 2009 +0000
+
+ tg3: Add AC131 power down support
+
+ The AC131 does not respect the power down bit (bit 11) of the MII
+ Control Register (reg 0x0). Instead, software is required to put the
+ phy into standby power down mode through the shadow register set. This
+ patch implements support for the AC131 standby power down mode.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 788a035e6061a66c6c77059c417fdc6234e140ff
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:26:03 2009 +0000
+
+ tg3: Improve 5785 PCIe performance
+
+ This patch improves 5785 performance by allowing the write DMA engine to
+ request larger DMA burst sizes than it otherwise would.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit a21771dd189b340328c573da9e005068e8a74c53
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:25:31 2009 +0000
+
+ tg3: Add more PCI DMA map error checking
+
+ This patch adds code to check the status of pci_map_single() before
+ allowing rx buffers to be used. It also converts the pci_map_single()
+ call in tg3_run_loopback() to use skb_dma_map() instead.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Signed-off-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: Benjamin Li <benli@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 52cdf8526fe24f11d300b75458ddee017f3f4c88
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:25:06 2009 +0000
+
+ tg3: Prevent a PCIe tx glitch
+
+ This patch prevents a PCIe tx glitch by allowing the transmitter to go
+ to a low power state.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 3f0e3ad72393db9c2932a2ca86cc1a49294bbc63
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:24:36 2009 +0000
+
+ tg3: Convert PHY_ADDR => TG3_PHY_MII_ADDR
+
+ This patch renames the PHY_ADDR preprocessor definition. The following
+ patch will identify a new member on the MDIO bus, so we want this
+ preprocessor definition to be a little more descriptive.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit f40386c8452f9eead9c5906bfffaaf59f3dc748f
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:24:02 2009 +0000
+
+ tg3: Fix disappearing 57780 devices
+
+ Under certain power saving conditions, 57780 asic rev devices might
+ disappear from the system. The fix is to disallow the PCIe PLL from
+ powering down.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 92c6b8d16a36df3f28b2537bed2a56491fb08f11
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 14:23:27 2009 +0000
+
+ tg3: Fix 5906 transmit hangs
+
+ The 5906 has trouble with fragments that are less than 8 bytes in size.
+ This patch works around the problem by pivoting the 5906's transmit
+ routine to tg3_start_xmit_dma_bug() and introducing a new SHORT_DMA_BUG
+ flag that enables code to detect and react to the problematic condition.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Signed-off-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+commit 0e1406dd404ce55dbe8d68b4b5e2aed7e5c75fdb
+Author: Matt Carlson <mcarlson@broadcom.com>
+Date: Mon Nov 2 12:33:33 2009 +0000
+
+ tg3: Assign flags to fixes in start_xmit_dma_bug
+
+ This patch adds a flag for each bug workaround in
+ tg3_start_xmit_dma_bug(). This is prep work for the following patch.
+
+ Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
+ Reviewed-by: Michael Chan <mchan@broadcom.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+
+---
+ drivers/net/tg3.c | 885 ++++++++++++++++++++++++++++++++++++------------------
+ drivers/net/tg3.h | 73 +++-
+ 2 files changed, 661 insertions(+), 297 deletions(-)
+
+Index: linux-2.6.31-master/drivers/net/tg3.c
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/tg3.c
++++ linux-2.6.31-master/drivers/net/tg3.c
+@@ -68,8 +68,8 @@
+
+ #define DRV_MODULE_NAME "tg3"
+ #define PFX DRV_MODULE_NAME ": "
+-#define DRV_MODULE_VERSION "3.102"
+-#define DRV_MODULE_RELDATE "September 1, 2009"
++#define DRV_MODULE_VERSION "3.104"
++#define DRV_MODULE_RELDATE "November 13, 2009"
+
+ #define TG3_DEF_MAC_MODE 0
+ #define TG3_DEF_RX_MODE 0
+@@ -137,6 +137,12 @@
+ #define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ)
+ #define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)
+
++#define TG3_RX_STD_BUFF_RING_SIZE \
++ (sizeof(struct ring_info) * TG3_RX_RING_SIZE)
++
++#define TG3_RX_JMB_BUFF_RING_SIZE \
++ (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE)
++
+ /* minimum number of free TX descriptors required to wake up TX process */
+ #define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)
+
+@@ -235,6 +241,9 @@ static struct pci_device_id tg3_pci_tbl[
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)},
++ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)},
++ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)},
++ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5724)},
+ {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
+ {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
+ {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
+@@ -396,7 +405,7 @@ static void tg3_write_indirect_mbox(stru
+ TG3_64BIT_REG_LOW, val);
+ return;
+ }
+- if (off == (MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW)) {
++ if (off == TG3_RX_STD_PROD_IDX_REG) {
+ pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX +
+ TG3_64BIT_REG_LOW, val);
+ return;
+@@ -937,9 +946,10 @@ static void tg3_mdio_config_5785(struct
+ u32 val;
+ struct phy_device *phydev;
+
+- phydev = tp->mdio_bus->phy_map[PHY_ADDR];
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+ switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
+ case TG3_PHY_ID_BCM50610:
++ case TG3_PHY_ID_BCM50610M:
+ val = MAC_PHYCFG2_50610_LED_MODES;
+ break;
+ case TG3_PHY_ID_BCMAC131:
+@@ -1031,7 +1041,7 @@ static void tg3_mdio_start(struct tg3 *t
+ if (is_serdes)
+ tp->phy_addr += 7;
+ } else
+- tp->phy_addr = PHY_ADDR;
++ tp->phy_addr = TG3_PHY_MII_ADDR;
+
+ if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+@@ -1062,7 +1072,7 @@ static int tg3_mdio_init(struct tg3 *tp)
+ tp->mdio_bus->read = &tg3_mdio_read;
+ tp->mdio_bus->write = &tg3_mdio_write;
+ tp->mdio_bus->reset = &tg3_mdio_reset;
+- tp->mdio_bus->phy_mask = ~(1 << PHY_ADDR);
++ tp->mdio_bus->phy_mask = ~(1 << TG3_PHY_MII_ADDR);
+ tp->mdio_bus->irq = &tp->mdio_irq[0];
+
+ for (i = 0; i < PHY_MAX_ADDR; i++)
+@@ -1084,7 +1094,7 @@ static int tg3_mdio_init(struct tg3 *tp)
+ return i;
+ }
+
+- phydev = tp->mdio_bus->phy_map[PHY_ADDR];
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+
+ if (!phydev || !phydev->drv) {
+ printk(KERN_WARNING "%s: No PHY devices\n", tp->dev->name);
+@@ -1096,8 +1106,14 @@ static int tg3_mdio_init(struct tg3 *tp)
+ switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
+ case TG3_PHY_ID_BCM57780:
+ phydev->interface = PHY_INTERFACE_MODE_GMII;
++ phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
+ break;
+ case TG3_PHY_ID_BCM50610:
++ case TG3_PHY_ID_BCM50610M:
++ phydev->dev_flags |= PHY_BRCM_CLEAR_RGMII_MODE |
++ PHY_BRCM_RX_REFCLK_UNUSED |
++ PHY_BRCM_DIS_TXCRXC_NOENRGY |
++ PHY_BRCM_AUTO_PWRDWN_ENABLE;
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
+ phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
+ if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+@@ -1111,6 +1127,7 @@ static int tg3_mdio_init(struct tg3 *tp)
+ case TG3_PHY_ID_RTL8201E:
+ case TG3_PHY_ID_BCMAC131:
+ phydev->interface = PHY_INTERFACE_MODE_MII;
++ phydev->dev_flags |= PHY_BRCM_AUTO_PWRDWN_ENABLE;
+ tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
+ break;
+ }
+@@ -1311,7 +1328,7 @@ static void tg3_setup_flow_control(struc
+ u32 old_tx_mode = tp->tx_mode;
+
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
+- autoneg = tp->mdio_bus->phy_map[PHY_ADDR]->autoneg;
++ autoneg = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]->autoneg;
+ else
+ autoneg = tp->link_config.autoneg;
+
+@@ -1348,7 +1365,7 @@ static void tg3_adjust_link(struct net_d
+ u8 oldflowctrl, linkmesg = 0;
+ u32 mac_mode, lcl_adv, rmt_adv;
+ struct tg3 *tp = netdev_priv(dev);
+- struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];
++ struct phy_device *phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+
+ spin_lock_bh(&tp->lock);
+
+@@ -1363,8 +1380,11 @@ static void tg3_adjust_link(struct net_d
+
+ if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10)
+ mac_mode |= MAC_MODE_PORT_MODE_MII;
+- else
++ else if (phydev->speed == SPEED_1000 ||
++ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
+ mac_mode |= MAC_MODE_PORT_MODE_GMII;
++ else
++ mac_mode |= MAC_MODE_PORT_MODE_MII;
+
+ if (phydev->duplex == DUPLEX_HALF)
+ mac_mode |= MAC_MODE_HALF_DUPLEX;
+@@ -1434,7 +1454,7 @@ static int tg3_phy_init(struct tg3 *tp)
+ /* Bring the PHY back to a known state. */
+ tg3_bmcr_reset(tp);
+
+- phydev = tp->mdio_bus->phy_map[PHY_ADDR];
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+
+ /* Attach the MAC to the PHY. */
+ phydev = phy_connect(tp->dev, dev_name(&phydev->dev), tg3_adjust_link,
+@@ -1461,7 +1481,7 @@ static int tg3_phy_init(struct tg3 *tp)
+ SUPPORTED_Asym_Pause);
+ break;
+ default:
+- phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
++ phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
+ return -EINVAL;
+ }
+
+@@ -1479,7 +1499,7 @@ static void tg3_phy_start(struct tg3 *tp
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return;
+
+- phydev = tp->mdio_bus->phy_map[PHY_ADDR];
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+
+ if (tp->link_config.phy_is_low_power) {
+ tp->link_config.phy_is_low_power = 0;
+@@ -1499,13 +1519,13 @@ static void tg3_phy_stop(struct tg3 *tp)
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return;
+
+- phy_stop(tp->mdio_bus->phy_map[PHY_ADDR]);
++ phy_stop(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
+ }
+
+ static void tg3_phy_fini(struct tg3 *tp)
+ {
+ if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+- phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
++ phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
+ tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
+ }
+ }
+@@ -2149,6 +2169,26 @@ static void tg3_power_down_phy(struct tg
+ tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
+ udelay(40);
+ return;
++ } else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
++ u32 phytest;
++ if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) {
++ u32 phy;
++
++ tg3_writephy(tp, MII_ADVERTISE, 0);
++ tg3_writephy(tp, MII_BMCR,
++ BMCR_ANENABLE | BMCR_ANRESTART);
++
++ tg3_writephy(tp, MII_TG3_FET_TEST,
++ phytest | MII_TG3_FET_SHADOW_EN);
++ if (!tg3_readphy(tp, MII_TG3_FET_SHDW_AUXMODE4, &phy)) {
++ phy |= MII_TG3_FET_SHDW_AUXMODE4_SBPD;
++ tg3_writephy(tp,
++ MII_TG3_FET_SHDW_AUXMODE4,
++ phy);
++ }
++ tg3_writephy(tp, MII_TG3_FET_TEST, phytest);
++ }
++ return;
+ } else if (do_low_power) {
+ tg3_writephy(tp, MII_TG3_EXT_CTRL,
+ MII_TG3_EXT_CTRL_FORCE_LED_OFF);
+@@ -2218,7 +2258,7 @@ static void tg3_nvram_unlock(struct tg3
+ static void tg3_enable_nvram_access(struct tg3 *tp)
+ {
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+- !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
++ !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
+ u32 nvaccess = tr32(NVRAM_ACCESS);
+
+ tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+@@ -2229,7 +2269,7 @@ static void tg3_enable_nvram_access(stru
+ static void tg3_disable_nvram_access(struct tg3 *tp)
+ {
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+- !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
++ !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
+ u32 nvaccess = tr32(NVRAM_ACCESS);
+
+ tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
+@@ -2474,7 +2514,7 @@ static int tg3_set_power_state(struct tg
+ struct phy_device *phydev;
+ u32 phyid, advertising;
+
+- phydev = tp->mdio_bus->phy_map[PHY_ADDR];
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+
+ tp->link_config.phy_is_low_power = 1;
+
+@@ -3243,15 +3283,6 @@ relink:
+ pci_write_config_word(tp->pdev,
+ tp->pcie_cap + PCI_EXP_LNKCTL,
+ newlnkctl);
+- } else if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
+- u32 newreg, oldreg = tr32(TG3_PCIE_LNKCTL);
+- if (tp->link_config.active_speed == SPEED_100 ||
+- tp->link_config.active_speed == SPEED_10)
+- newreg = oldreg & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+- else
+- newreg = oldreg | TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+- if (newreg != oldreg)
+- tw32(TG3_PCIE_LNKCTL, newreg);
+ }
+
+ if (current_link_up != netif_carrier_ok(tp->dev)) {
+@@ -4375,6 +4406,17 @@ static void tg3_tx(struct tg3_napi *tnap
+ }
+ }
+
++static void tg3_rx_skb_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
++{
++ if (!ri->skb)
++ return;
++
++ pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping),
++ map_sz, PCI_DMA_FROMDEVICE);
++ dev_kfree_skb_any(ri->skb);
++ ri->skb = NULL;
++}
++
+ /* Returns size of skb allocated or < 0 on error.
+ *
+ * We only need to fill in the address because the other members
+@@ -4386,16 +4428,14 @@ static void tg3_tx(struct tg3_napi *tnap
+ * buffers the cpu only reads the last cacheline of the RX descriptor
+ * (to fetch the error flags, vlan tag, checksum, and opaque cookie).
+ */
+-static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
+- int src_idx, u32 dest_idx_unmasked)
++static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
++ u32 opaque_key, u32 dest_idx_unmasked)
+ {
+- struct tg3 *tp = tnapi->tp;
+ struct tg3_rx_buffer_desc *desc;
+ struct ring_info *map, *src_map;
+ struct sk_buff *skb;
+ dma_addr_t mapping;
+ int skb_size, dest_idx;
+- struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+
+ src_map = NULL;
+ switch (opaque_key) {
+@@ -4403,8 +4443,6 @@ static int tg3_alloc_rx_skb(struct tg3_n
+ dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
+ desc = &tpr->rx_std[dest_idx];
+ map = &tpr->rx_std_buffers[dest_idx];
+- if (src_idx >= 0)
+- src_map = &tpr->rx_std_buffers[src_idx];
+ skb_size = tp->rx_pkt_map_sz;
+ break;
+
+@@ -4412,8 +4450,6 @@ static int tg3_alloc_rx_skb(struct tg3_n
+ dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
+ desc = &tpr->rx_jmb[dest_idx].std;
+ map = &tpr->rx_jmb_buffers[dest_idx];
+- if (src_idx >= 0)
+- src_map = &tpr->rx_jmb_buffers[src_idx];
+ skb_size = TG3_RX_JMB_MAP_SZ;
+ break;
+
+@@ -4435,13 +4471,14 @@ static int tg3_alloc_rx_skb(struct tg3_n
+
+ mapping = pci_map_single(tp->pdev, skb->data, skb_size,
+ PCI_DMA_FROMDEVICE);
++ if (pci_dma_mapping_error(tp->pdev, mapping)) {
++ dev_kfree_skb(skb);
++ return -EIO;
++ }
+
+ map->skb = skb;
+ pci_unmap_addr_set(map, mapping, mapping);
+
+- if (src_map != NULL)
+- src_map->skb = NULL;
+-
+ desc->addr_hi = ((u64)mapping >> 32);
+ desc->addr_lo = ((u64)mapping & 0xffffffff);
+
+@@ -4452,30 +4489,32 @@ static int tg3_alloc_rx_skb(struct tg3_n
+ * members of the RX descriptor are invariant. See notes above
+ * tg3_alloc_rx_skb for full details.
+ */
+-static void tg3_recycle_rx(struct tg3_napi *tnapi, u32 opaque_key,
+- int src_idx, u32 dest_idx_unmasked)
++static void tg3_recycle_rx(struct tg3_napi *tnapi,
++ struct tg3_rx_prodring_set *dpr,
++ u32 opaque_key, int src_idx,
++ u32 dest_idx_unmasked)
+ {
+ struct tg3 *tp = tnapi->tp;
+ struct tg3_rx_buffer_desc *src_desc, *dest_desc;
+ struct ring_info *src_map, *dest_map;
+ int dest_idx;
+- struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
++ struct tg3_rx_prodring_set *spr = &tp->prodring[0];
+
+ switch (opaque_key) {
+ case RXD_OPAQUE_RING_STD:
+ dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
+- dest_desc = &tpr->rx_std[dest_idx];
+- dest_map = &tpr->rx_std_buffers[dest_idx];
+- src_desc = &tpr->rx_std[src_idx];
+- src_map = &tpr->rx_std_buffers[src_idx];
++ dest_desc = &dpr->rx_std[dest_idx];
++ dest_map = &dpr->rx_std_buffers[dest_idx];
++ src_desc = &spr->rx_std[src_idx];
++ src_map = &spr->rx_std_buffers[src_idx];
+ break;
+
+ case RXD_OPAQUE_RING_JUMBO:
+ dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
+- dest_desc = &tpr->rx_jmb[dest_idx].std;
+- dest_map = &tpr->rx_jmb_buffers[dest_idx];
+- src_desc = &tpr->rx_jmb[src_idx].std;
+- src_map = &tpr->rx_jmb_buffers[src_idx];
++ dest_desc = &dpr->rx_jmb[dest_idx].std;
++ dest_map = &dpr->rx_jmb_buffers[dest_idx];
++ src_desc = &spr->rx_jmb[src_idx].std;
++ src_map = &spr->rx_jmb_buffers[src_idx];
+ break;
+
+ default:
+@@ -4487,7 +4526,6 @@ static void tg3_recycle_rx(struct tg3_na
+ pci_unmap_addr(src_map, mapping));
+ dest_desc->addr_hi = src_desc->addr_hi;
+ dest_desc->addr_lo = src_desc->addr_lo;
+-
+ src_map->skb = NULL;
+ }
+
+@@ -4519,10 +4557,11 @@ static int tg3_rx(struct tg3_napi *tnapi
+ {
+ struct tg3 *tp = tnapi->tp;
+ u32 work_mask, rx_std_posted = 0;
++ u32 std_prod_idx, jmb_prod_idx;
+ u32 sw_idx = tnapi->rx_rcb_ptr;
+ u16 hw_idx;
+ int received;
+- struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
++ struct tg3_rx_prodring_set *tpr = tnapi->prodring;
+
+ hw_idx = *(tnapi->rx_rcb_prod_idx);
+ /*
+@@ -4532,7 +4571,10 @@ static int tg3_rx(struct tg3_napi *tnapi
+ rmb();
+ work_mask = 0;
+ received = 0;
++ std_prod_idx = tpr->rx_std_prod_idx;
++ jmb_prod_idx = tpr->rx_jmb_prod_idx;
+ while (sw_idx != hw_idx && budget > 0) {
++ struct ring_info *ri;
+ struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx];
+ unsigned int len;
+ struct sk_buff *skb;
+@@ -4542,16 +4584,16 @@ static int tg3_rx(struct tg3_napi *tnapi
+ desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
+ opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
+ if (opaque_key == RXD_OPAQUE_RING_STD) {
+- struct ring_info *ri = &tpr->rx_std_buffers[desc_idx];
++ ri = &tp->prodring[0].rx_std_buffers[desc_idx];
+ dma_addr = pci_unmap_addr(ri, mapping);
+ skb = ri->skb;
+- post_ptr = &tpr->rx_std_ptr;
++ post_ptr = &std_prod_idx;
+ rx_std_posted++;
+ } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
+- struct ring_info *ri = &tpr->rx_jmb_buffers[desc_idx];
++ ri = &tp->prodring[0].rx_jmb_buffers[desc_idx];
+ dma_addr = pci_unmap_addr(ri, mapping);
+ skb = ri->skb;
+- post_ptr = &tpr->rx_jmb_ptr;
++ post_ptr = &jmb_prod_idx;
+ } else
+ goto next_pkt_nopost;
+
+@@ -4560,7 +4602,7 @@ static int tg3_rx(struct tg3_napi *tnapi
+ if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
+ (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) {
+ drop_it:
+- tg3_recycle_rx(tnapi, opaque_key,
++ tg3_recycle_rx(tnapi, tpr, opaque_key,
+ desc_idx, *post_ptr);
+ drop_it_no_recycle:
+ /* Other statistics kept track of by card. */
+@@ -4580,11 +4622,13 @@ static int tg3_rx(struct tg3_napi *tnapi
+ ) {
+ int skb_size;
+
+- skb_size = tg3_alloc_rx_skb(tnapi, opaque_key,
+- desc_idx, *post_ptr);
++ skb_size = tg3_alloc_rx_skb(tp, tpr, opaque_key,
++ *post_ptr);
+ if (skb_size < 0)
+ goto drop_it;
+
++ ri->skb = NULL;
++
+ pci_unmap_single(tp->pdev, dma_addr, skb_size,
+ PCI_DMA_FROMDEVICE);
+
+@@ -4592,7 +4636,7 @@ static int tg3_rx(struct tg3_napi *tnapi
+ } else {
+ struct sk_buff *copy_skb;
+
+- tg3_recycle_rx(tnapi, opaque_key,
++ tg3_recycle_rx(tnapi, tpr, opaque_key,
+ desc_idx, *post_ptr);
+
+ copy_skb = netdev_alloc_skb(tp->dev,
+@@ -4643,9 +4687,7 @@ next_pkt:
+
+ if (unlikely(rx_std_posted >= tp->rx_std_max_post)) {
+ u32 idx = *post_ptr % TG3_RX_RING_SIZE;
+-
+- tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX +
+- TG3_64BIT_REG_LOW, idx);
++ tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, idx);
+ work_mask &= ~RXD_OPAQUE_RING_STD;
+ rx_std_posted = 0;
+ }
+@@ -4665,33 +4707,45 @@ next_pkt_nopost:
+ tw32_rx_mbox(tnapi->consmbox, sw_idx);
+
+ /* Refill RX ring(s). */
+- if (work_mask & RXD_OPAQUE_RING_STD) {
+- sw_idx = tpr->rx_std_ptr % TG3_RX_RING_SIZE;
+- tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
+- sw_idx);
+- }
+- if (work_mask & RXD_OPAQUE_RING_JUMBO) {
+- sw_idx = tpr->rx_jmb_ptr % TG3_RX_JUMBO_RING_SIZE;
+- tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
+- sw_idx);
++ if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) || tnapi == &tp->napi[1]) {
++ if (work_mask & RXD_OPAQUE_RING_STD) {
++ tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
++ tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
++ tpr->rx_std_prod_idx);
++ }
++ if (work_mask & RXD_OPAQUE_RING_JUMBO) {
++ tpr->rx_jmb_prod_idx = jmb_prod_idx %
++ TG3_RX_JUMBO_RING_SIZE;
++ tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
++ tpr->rx_jmb_prod_idx);
++ }
++ mmiowb();
++ } else if (work_mask) {
++ /* rx_std_buffers[] and rx_jmb_buffers[] entries must be
++ * updated before the producer indices can be updated.
++ */
++ smp_wmb();
++
++ tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE;
++ tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE;
++
++ napi_schedule(&tp->napi[1].napi);
+ }
+- mmiowb();
+
+ return received;
+ }
+
+-static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
++static void tg3_poll_link(struct tg3 *tp)
+ {
+- struct tg3 *tp = tnapi->tp;
+- struct tg3_hw_status *sblk = tnapi->hw_status;
+-
+ /* handle link change and other phy events */
+ if (!(tp->tg3_flags &
+ (TG3_FLAG_USE_LINKCHG_REG |
+ TG3_FLAG_POLL_SERDES))) {
++ struct tg3_hw_status *sblk = tp->napi[0].hw_status;
++
+ if (sblk->status & SD_STATUS_LINK_CHG) {
+ sblk->status = SD_STATUS_UPDATED |
+- (sblk->status & ~SD_STATUS_LINK_CHG);
++ (sblk->status & ~SD_STATUS_LINK_CHG);
+ spin_lock(&tp->lock);
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ tw32_f(MAC_STATUS,
+@@ -4705,6 +4759,98 @@ static int tg3_poll_work(struct tg3_napi
+ spin_unlock(&tp->lock);
+ }
+ }
++}
++
++static void tg3_rx_prodring_xfer(struct tg3 *tp,
++ struct tg3_rx_prodring_set *dpr,
++ struct tg3_rx_prodring_set *spr)
++{
++ u32 si, di, cpycnt, src_prod_idx;
++ int i;
++
++ while (1) {
++ src_prod_idx = spr->rx_std_prod_idx;
++
++ /* Make sure updates to the rx_std_buffers[] entries and the
++ * standard producer index are seen in the correct order.
++ */
++ smp_rmb();
++
++ if (spr->rx_std_cons_idx == src_prod_idx)
++ break;
++
++ if (spr->rx_std_cons_idx < src_prod_idx)
++ cpycnt = src_prod_idx - spr->rx_std_cons_idx;
++ else
++ cpycnt = TG3_RX_RING_SIZE - spr->rx_std_cons_idx;
++
++ cpycnt = min(cpycnt, TG3_RX_RING_SIZE - dpr->rx_std_prod_idx);
++
++ si = spr->rx_std_cons_idx;
++ di = dpr->rx_std_prod_idx;
++
++ memcpy(&dpr->rx_std_buffers[di],
++ &spr->rx_std_buffers[si],
++ cpycnt * sizeof(struct ring_info));
++
++ for (i = 0; i < cpycnt; i++, di++, si++) {
++ struct tg3_rx_buffer_desc *sbd, *dbd;
++ sbd = &spr->rx_std[si];
++ dbd = &dpr->rx_std[di];
++ dbd->addr_hi = sbd->addr_hi;
++ dbd->addr_lo = sbd->addr_lo;
++ }
++
++ spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) %
++ TG3_RX_RING_SIZE;
++ dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) %
++ TG3_RX_RING_SIZE;
++ }
++
++ while (1) {
++ src_prod_idx = spr->rx_jmb_prod_idx;
++
++ /* Make sure updates to the rx_jmb_buffers[] entries and
++ * the jumbo producer index are seen in the correct order.
++ */
++ smp_rmb();
++
++ if (spr->rx_jmb_cons_idx == src_prod_idx)
++ break;
++
++ if (spr->rx_jmb_cons_idx < src_prod_idx)
++ cpycnt = src_prod_idx - spr->rx_jmb_cons_idx;
++ else
++ cpycnt = TG3_RX_JUMBO_RING_SIZE - spr->rx_jmb_cons_idx;
++
++ cpycnt = min(cpycnt,
++ TG3_RX_JUMBO_RING_SIZE - dpr->rx_jmb_prod_idx);
++
++ si = spr->rx_jmb_cons_idx;
++ di = dpr->rx_jmb_prod_idx;
++
++ memcpy(&dpr->rx_jmb_buffers[di],
++ &spr->rx_jmb_buffers[si],
++ cpycnt * sizeof(struct ring_info));
++
++ for (i = 0; i < cpycnt; i++, di++, si++) {
++ struct tg3_rx_buffer_desc *sbd, *dbd;
++ sbd = &spr->rx_jmb[si].std;
++ dbd = &dpr->rx_jmb[di].std;
++ dbd->addr_hi = sbd->addr_hi;
++ dbd->addr_lo = sbd->addr_lo;
++ }
++
++ spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) %
++ TG3_RX_JUMBO_RING_SIZE;
++ dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) %
++ TG3_RX_JUMBO_RING_SIZE;
++ }
++}
++
++static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
++{
++ struct tg3 *tp = tnapi->tp;
+
+ /* run TX completion thread */
+ if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
+@@ -4720,6 +4866,74 @@ static int tg3_poll_work(struct tg3_napi
+ if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
+ work_done += tg3_rx(tnapi, budget - work_done);
+
++ if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
++ int i;
++ u32 std_prod_idx = tp->prodring[0].rx_std_prod_idx;
++ u32 jmb_prod_idx = tp->prodring[0].rx_jmb_prod_idx;
++
++ for (i = 2; i < tp->irq_cnt; i++)
++ tg3_rx_prodring_xfer(tp, tnapi->prodring,
++ tp->napi[i].prodring);
++
++ wmb();
++
++ if (std_prod_idx != tp->prodring[0].rx_std_prod_idx) {
++ u32 mbox = TG3_RX_STD_PROD_IDX_REG;
++ tw32_rx_mbox(mbox, tp->prodring[0].rx_std_prod_idx);
++ }
++
++ if (jmb_prod_idx != tp->prodring[0].rx_jmb_prod_idx) {
++ u32 mbox = TG3_RX_JMB_PROD_IDX_REG;
++ tw32_rx_mbox(mbox, tp->prodring[0].rx_jmb_prod_idx);
++ }
++
++ mmiowb();
++ }
++
++ return work_done;
++}
++
++static int tg3_poll_msix(struct napi_struct *napi, int budget)
++{
++ struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
++ struct tg3 *tp = tnapi->tp;
++ int work_done = 0;
++ struct tg3_hw_status *sblk = tnapi->hw_status;
++
++ while (1) {
++ work_done = tg3_poll_work(tnapi, work_done, budget);
++
++ if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
++ goto tx_recovery;
++
++ if (unlikely(work_done >= budget))
++ break;
++
++ /* tp->last_tag is used in tg3_restart_ints() below
++ * to tell the hw how much work has been processed,
++ * so we must read it before checking for more work.
++ */
++ tnapi->last_tag = sblk->status_tag;
++ tnapi->last_irq_tag = tnapi->last_tag;
++ rmb();
++
++ /* check for RX/TX work to do */
++ if (sblk->idx[0].tx_consumer == tnapi->tx_cons &&
++ *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr) {
++ napi_complete(napi);
++ /* Reenable interrupts. */
++ tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
++ mmiowb();
++ break;
++ }
++ }
++
++ return work_done;
++
++tx_recovery:
++ /* work_done is guaranteed to be less than budget. */
++ napi_complete(napi);
++ schedule_work(&tp->reset_task);
+ return work_done;
+ }
+
+@@ -4731,6 +4945,8 @@ static int tg3_poll(struct napi_struct *
+ struct tg3_hw_status *sblk = tnapi->hw_status;
+
+ while (1) {
++ tg3_poll_link(tp);
++
+ work_done = tg3_poll_work(tnapi, work_done, budget);
+
+ if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+@@ -5093,11 +5309,11 @@ static inline int tg3_40bit_overflow_tes
+ static void tg3_set_txd(struct tg3_napi *, int, dma_addr_t, int, u32, u32);
+
+ /* Workaround 4GB and 40-bit hardware DMA bugs. */
+-static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
+- u32 last_plus_one, u32 *start,
+- u32 base_flags, u32 mss)
++static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
++ struct sk_buff *skb, u32 last_plus_one,
++ u32 *start, u32 base_flags, u32 mss)
+ {
+- struct tg3_napi *tnapi = &tp->napi[0];
++ struct tg3 *tp = tnapi->tp;
+ struct sk_buff *new_skb;
+ dma_addr_t new_addr = 0;
+ u32 entry = *start;
+@@ -5124,7 +5340,8 @@ static int tigon3_dma_hwbug_workaround(s
+ /* Make sure new skb does not cross any 4G boundaries.
+ * Drop the packet if it does.
+ */
+- if (ret || tg3_4g_overflow_test(new_addr, new_skb->len)) {
++ if (ret || ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
++ tg3_4g_overflow_test(new_addr, new_skb->len))) {
+ if (!ret)
+ skb_dma_unmap(&tp->pdev->dev, new_skb,
+ DMA_TO_DEVICE);
+@@ -5179,7 +5396,7 @@ static void tg3_set_txd(struct tg3_napi
+ }
+
+ /* hard_start_xmit for devices that don't have any bugs and
+- * support TG3_FLG2_HW_TSO_2 only.
++ * support TG3_FLG2_HW_TSO_2 and TG3_FLG2_HW_TSO_3 only.
+ */
+ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+@@ -5238,7 +5455,7 @@ static netdev_tx_t tg3_start_xmit(struct
+ hdrlen = ip_tcp_len + tcp_opt_len;
+ }
+
+- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
++ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
+ mss |= (hdrlen & 0xc) << 12;
+ if (hdrlen & 0x10)
+ base_flags |= 0x00000010;
+@@ -5365,9 +5582,13 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+ struct skb_shared_info *sp;
+ int would_hit_hwbug;
+ dma_addr_t mapping;
+- struct tg3_napi *tnapi = &tp->napi[0];
++ struct tg3_napi *tnapi;
++ struct netdev_queue *txq;
+
+- len = skb_headlen(skb);
++ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
++ tnapi = &tp->napi[skb_get_queue_mapping(skb)];
++ if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
++ tnapi++;
+
+ /* We are running in BH disabled context with netif_tx_lock
+ * and TX reclaim runs via tp->napi.poll inside of a software
+@@ -5375,8 +5596,8 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+ * no IRQ context deadlocks to worry about either. Rejoice!
+ */
+ if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
+- if (!netif_queue_stopped(dev)) {
+- netif_stop_queue(dev);
++ if (!netif_tx_queue_stopped(txq)) {
++ netif_tx_stop_queue(txq);
+
+ /* This is a hard error, log it. */
+ printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
+@@ -5389,10 +5610,10 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+ base_flags = 0;
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ base_flags |= TXD_FLAG_TCPUDP_CSUM;
+- mss = 0;
++
+ if ((mss = skb_shinfo(skb)->gso_size) != 0) {
+ struct iphdr *iph;
+- int tcp_opt_len, ip_tcp_len, hdr_len;
++ u32 tcp_opt_len, ip_tcp_len, hdr_len;
+
+ if (skb_header_cloned(skb) &&
+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
+@@ -5423,8 +5644,15 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+ IPPROTO_TCP,
+ 0);
+
+- if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
+- (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
++ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
++ mss |= (hdr_len & 0xc) << 12;
++ if (hdr_len & 0x10)
++ base_flags |= 0x00000010;
++ base_flags |= (hdr_len & 0x3e0) << 5;
++ } else if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)
++ mss |= hdr_len << 9;
++ else if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1) ||
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+ if (tcp_opt_len || iph->ihl > 5) {
+ int tsflags;
+
+@@ -5446,6 +5674,10 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+ (vlan_tx_tag_get(skb) << 16));
+ #endif
+
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
++ !mss && skb->len > ETH_DATA_LEN)
++ base_flags |= TXD_FLAG_JMB_PKT;
++
+ if (skb_dma_map(&tp->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_kfree_skb(skb);
+ goto out_unlock;
+@@ -5459,9 +5691,20 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+
+ would_hit_hwbug = 0;
+
+- if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
++ len = skb_headlen(skb);
++
++ if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) && len <= 8)
+ would_hit_hwbug = 1;
+- else if (tg3_4g_overflow_test(mapping, len))
++
++ if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
++ tg3_4g_overflow_test(mapping, len))
++ would_hit_hwbug = 1;
++
++ if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
++ tg3_40bit_overflow_test(tp, mapping, len))
++ would_hit_hwbug = 1;
++
++ if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
+ would_hit_hwbug = 1;
+
+ tg3_set_txd(tnapi, entry, mapping, len, base_flags,
+@@ -5482,10 +5725,16 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+
+ tnapi->tx_buffers[entry].skb = NULL;
+
+- if (tg3_4g_overflow_test(mapping, len))
++ if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) &&
++ len <= 8)
+ would_hit_hwbug = 1;
+
+- if (tg3_40bit_overflow_test(tp, mapping, len))
++ if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
++ tg3_4g_overflow_test(mapping, len))
++ would_hit_hwbug = 1;
++
++ if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
++ tg3_40bit_overflow_test(tp, mapping, len))
+ would_hit_hwbug = 1;
+
+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+@@ -5509,7 +5758,7 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+ /* If the workaround fails due to memory/mapping
+ * failure, silently drop this packet.
+ */
+- if (tigon3_dma_hwbug_workaround(tp, skb, last_plus_one,
++ if (tigon3_dma_hwbug_workaround(tnapi, skb, last_plus_one,
+ &start, base_flags, mss))
+ goto out_unlock;
+
+@@ -5517,13 +5766,13 @@ static netdev_tx_t tg3_start_xmit_dma_bu
+ }
+
+ /* Packets are ready, update Tx producer idx local and on card. */
+- tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, entry);
++ tw32_tx_mbox(tnapi->prodmbox, entry);
+
+ tnapi->tx_prod = entry;
+ if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
+- netif_stop_queue(dev);
++ netif_tx_stop_queue(txq);
+ if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
+- netif_wake_queue(tp->dev);
++ netif_tx_wake_queue(txq);
+ }
+
+ out_unlock:
+@@ -5594,36 +5843,33 @@ static void tg3_rx_prodring_free(struct
+ struct tg3_rx_prodring_set *tpr)
+ {
+ int i;
+- struct ring_info *rxp;
+
+- for (i = 0; i < TG3_RX_RING_SIZE; i++) {
+- rxp = &tpr->rx_std_buffers[i];
++ if (tpr != &tp->prodring[0]) {
++ for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx;
++ i = (i + 1) % TG3_RX_RING_SIZE)
++ tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
++ tp->rx_pkt_map_sz);
+
+- if (rxp->skb == NULL)
+- continue;
++ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
++ for (i = tpr->rx_jmb_cons_idx;
++ i != tpr->rx_jmb_prod_idx;
++ i = (i + 1) % TG3_RX_JUMBO_RING_SIZE) {
++ tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
++ TG3_RX_JMB_MAP_SZ);
++ }
++ }
+
+- pci_unmap_single(tp->pdev,
+- pci_unmap_addr(rxp, mapping),
+- tp->rx_pkt_map_sz,
+- PCI_DMA_FROMDEVICE);
+- dev_kfree_skb_any(rxp->skb);
+- rxp->skb = NULL;
++ return;
+ }
+
+- if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+- for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+- rxp = &tpr->rx_jmb_buffers[i];
+-
+- if (rxp->skb == NULL)
+- continue;
++ for (i = 0; i < TG3_RX_RING_SIZE; i++)
++ tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
++ tp->rx_pkt_map_sz);
+
+- pci_unmap_single(tp->pdev,
+- pci_unmap_addr(rxp, mapping),
+- TG3_RX_JMB_MAP_SZ,
+- PCI_DMA_FROMDEVICE);
+- dev_kfree_skb_any(rxp->skb);
+- rxp->skb = NULL;
+- }
++ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
++ for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++)
++ tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
++ TG3_RX_JMB_MAP_SZ);
+ }
+ }
+
+@@ -5638,7 +5884,19 @@ static int tg3_rx_prodring_alloc(struct
+ struct tg3_rx_prodring_set *tpr)
+ {
+ u32 i, rx_pkt_dma_sz;
+- struct tg3_napi *tnapi = &tp->napi[0];
++
++ tpr->rx_std_cons_idx = 0;
++ tpr->rx_std_prod_idx = 0;
++ tpr->rx_jmb_cons_idx = 0;
++ tpr->rx_jmb_prod_idx = 0;
++
++ if (tpr != &tp->prodring[0]) {
++ memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE);
++ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)
++ memset(&tpr->rx_jmb_buffers[0], 0,
++ TG3_RX_JMB_BUFF_RING_SIZE);
++ goto done;
++ }
+
+ /* Zero out all descriptors. */
+ memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);
+@@ -5665,7 +5923,7 @@ static int tg3_rx_prodring_alloc(struct
+
+ /* Now allocate fresh SKBs for each rx ring. */
+ for (i = 0; i < tp->rx_pending; i++) {
+- if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_STD, -1, i) < 0) {
++ if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) {
+ printk(KERN_WARNING PFX
+ "%s: Using a smaller RX standard ring, "
+ "only %d out of %d buffers were allocated "
+@@ -5696,8 +5954,8 @@ static int tg3_rx_prodring_alloc(struct
+ }
+
+ for (i = 0; i < tp->rx_jumbo_pending; i++) {
+- if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_JUMBO,
+- -1, i) < 0) {
++ if (tg3_alloc_rx_skb(tp, tpr, RXD_OPAQUE_RING_JUMBO,
++ i) < 0) {
+ printk(KERN_WARNING PFX
+ "%s: Using a smaller RX jumbo ring, "
+ "only %d out of %d buffers were "
+@@ -5741,8 +5999,7 @@ static void tg3_rx_prodring_fini(struct
+ static int tg3_rx_prodring_init(struct tg3 *tp,
+ struct tg3_rx_prodring_set *tpr)
+ {
+- tpr->rx_std_buffers = kzalloc(sizeof(struct ring_info) *
+- TG3_RX_RING_SIZE, GFP_KERNEL);
++ tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL);
+ if (!tpr->rx_std_buffers)
+ return -ENOMEM;
+
+@@ -5752,8 +6009,7 @@ static int tg3_rx_prodring_init(struct t
+ goto err_out;
+
+ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+- tpr->rx_jmb_buffers = kzalloc(sizeof(struct ring_info) *
+- TG3_RX_JUMBO_RING_SIZE,
++ tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE,
+ GFP_KERNEL);
+ if (!tpr->rx_jmb_buffers)
+ goto err_out;
+@@ -5809,9 +6065,10 @@ static void tg3_free_rings(struct tg3 *t
+
+ dev_kfree_skb_any(skb);
+ }
+- }
+
+- tg3_rx_prodring_free(tp, &tp->prodring[0]);
++ if (tp->irq_cnt == 1 || j != tp->irq_cnt - 1)
++ tg3_rx_prodring_free(tp, &tp->prodring[j]);
++ }
+ }
+
+ /* Initialize tx/rx rings for packet processing.
+@@ -5845,9 +6102,13 @@ static int tg3_init_rings(struct tg3 *tp
+ tnapi->rx_rcb_ptr = 0;
+ if (tnapi->rx_rcb)
+ memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
++
++ if ((tp->irq_cnt == 1 || i != tp->irq_cnt - 1) &&
++ tg3_rx_prodring_alloc(tp, &tp->prodring[i]))
++ return -ENOMEM;
+ }
+
+- return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
++ return 0;
+ }
+
+ /*
+@@ -5891,7 +6152,8 @@ static void tg3_free_consistent(struct t
+ tp->hw_stats = NULL;
+ }
+
+- tg3_rx_prodring_fini(tp, &tp->prodring[0]);
++ for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++)
++ tg3_rx_prodring_fini(tp, &tp->prodring[i]);
+ }
+
+ /*
+@@ -5902,8 +6164,10 @@ static int tg3_alloc_consistent(struct t
+ {
+ int i;
+
+- if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
+- return -ENOMEM;
++ for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) {
++ if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
++ goto err_out;
++ }
+
+ tp->hw_stats = pci_alloc_consistent(tp->pdev,
+ sizeof(struct tg3_hw_stats),
+@@ -5947,6 +6211,11 @@ static int tg3_alloc_consistent(struct t
+ break;
+ }
+
++ if (tp->irq_cnt == 1)
++ tnapi->prodring = &tp->prodring[0];
++ else if (i)
++ tnapi->prodring = &tp->prodring[i - 1];
++
+ /*
+ * If multivector RSS is enabled, vector 0 does not handle
+ * rx or tx interrupts. Don't allocate any resources for it.
+@@ -6580,6 +6849,30 @@ static int tg3_chip_reset(struct tg3 *tp
+
+ tg3_mdio_start(tp);
+
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
++ u8 phy_addr;
++
++ phy_addr = tp->phy_addr;
++ tp->phy_addr = TG3_PHY_PCIE_ADDR;
++
++ tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
++ TG3_PCIEPHY_TXB_BLK << TG3_PCIEPHY_BLOCK_SHIFT);
++ val = TG3_PCIEPHY_TX0CTRL1_TXOCM | TG3_PCIEPHY_TX0CTRL1_RDCTL |
++ TG3_PCIEPHY_TX0CTRL1_TXCMV | TG3_PCIEPHY_TX0CTRL1_TKSEL |
++ TG3_PCIEPHY_TX0CTRL1_NB_EN;
++ tg3_writephy(tp, TG3_PCIEPHY_TX0CTRL1, val);
++ udelay(10);
++
++ tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
++ TG3_PCIEPHY_XGXS_BLK1 << TG3_PCIEPHY_BLOCK_SHIFT);
++ val = TG3_PCIEPHY_PWRMGMT4_LOWPWR_EN |
++ TG3_PCIEPHY_PWRMGMT4_L1PLLPD_EN;
++ tg3_writephy(tp, TG3_PCIEPHY_PWRMGMT4, val);
++ udelay(10);
++
++ tp->phy_addr = phy_addr;
++ }
++
+ if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
+ tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
+@@ -7162,15 +7455,9 @@ static int tg3_reset_hw(struct tg3 *tp,
+ tw32(TG3_PCIE_EIDLE_DELAY, val | TG3_PCIE_EIDLE_DELAY_13_CLKS);
+
+ tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR);
+- }
+
+- if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
+- val = tr32(TG3_PCIE_LNKCTL);
+- if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG)
+- val |= TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
+- else
+- val &= ~TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
+- tw32(TG3_PCIE_LNKCTL, val);
++ val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
++ tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
+ }
+
+ /* This works around an issue with Athlon chipsets on
+@@ -7217,9 +7504,12 @@ static int tg3_reset_hw(struct tg3 *tp,
+ if (err)
+ return err;
+
+- if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
+- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
+- GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
++ val = tr32(TG3PCI_DMA_RW_CTRL) &
++ ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
++ tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
++ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
++ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
+ /* This value is determined during the probe time DMA
+ * engine test, tg3_test_dma.
+ */
+@@ -7342,8 +7632,9 @@ static int tg3_reset_hw(struct tg3 *tp,
+ ((u64) tpr->rx_std_mapping >> 32));
+ tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
+ ((u64) tpr->rx_std_mapping & 0xffffffff));
+- tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
+- NIC_SRAM_RX_BUFFER_DESC);
++ if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS))
++ tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
++ NIC_SRAM_RX_BUFFER_DESC);
+
+ /* Disable the mini ring */
+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+@@ -7366,8 +7657,9 @@ static int tg3_reset_hw(struct tg3 *tp,
+ tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
+ (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
+ BDINFO_FLAGS_USE_EXT_RECV);
+- tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
+- NIC_SRAM_RX_JUMBO_BUFFER_DESC);
++ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
++ tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
++ NIC_SRAM_RX_JUMBO_BUFFER_DESC);
+ } else {
+ tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
+ BDINFO_FLAGS_DISABLED);
+@@ -7383,14 +7675,12 @@ static int tg3_reset_hw(struct tg3 *tp,
+
+ tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
+
+- tpr->rx_std_ptr = tp->rx_pending;
+- tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
+- tpr->rx_std_ptr);
++ tpr->rx_std_prod_idx = tp->rx_pending;
++ tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx);
+
+- tpr->rx_jmb_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
++ tpr->rx_jmb_prod_idx = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
+ tp->rx_jumbo_pending : 0;
+- tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
+- tpr->rx_jmb_ptr);
++ tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx);
+
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+ tw32(STD_REPLENISH_LWM, 32);
+@@ -7453,7 +7743,8 @@ static int tg3_reset_hw(struct tg3 *tp,
+ if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+ rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN;
+
+- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
++ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+ rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
+
+@@ -7602,6 +7893,9 @@ static int tg3_reset_hw(struct tg3 *tp,
+ if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+ val |= WDMAC_MODE_STATUS_TAG_FIX;
+
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
++ val |= WDMAC_MODE_BURST_ALL_DATA;
++
+ tw32_f(WDMAC_MODE, val);
+ udelay(40);
+
+@@ -9240,9 +9534,11 @@ static int tg3_get_settings(struct net_d
+ struct tg3 *tp = netdev_priv(dev);
+
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
++ struct phy_device *phydev;
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
+- return phy_ethtool_gset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
++ return phy_ethtool_gset(phydev, cmd);
+ }
+
+ cmd->supported = (SUPPORTED_Autoneg);
+@@ -9281,9 +9577,11 @@ static int tg3_set_settings(struct net_d
+ struct tg3 *tp = netdev_priv(dev);
+
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
++ struct phy_device *phydev;
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
+- return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
++ return phy_ethtool_sset(phydev, cmd);
+ }
+
+ if (cmd->autoneg != AUTONEG_ENABLE &&
+@@ -9436,15 +9734,16 @@ static int tg3_set_tso(struct net_device
+ return 0;
+ }
+ if ((dev->features & NETIF_F_IPV6_CSUM) &&
+- (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)) {
++ ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
++ (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3))) {
+ if (value) {
+ dev->features |= NETIF_F_TSO6;
+- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
++ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+ GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+ dev->features |= NETIF_F_TSO_ECN;
+ } else
+ dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
+@@ -9466,7 +9765,7 @@ static int tg3_nway_reset(struct net_dev
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
+- r = phy_start_aneg(tp->mdio_bus->phy_map[PHY_ADDR]);
++ r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
+ } else {
+ u32 bmcr;
+
+@@ -9585,7 +9884,7 @@ static int tg3_set_pauseparam(struct net
+ u32 newadv;
+ struct phy_device *phydev;
+
+- phydev = tp->mdio_bus->phy_map[PHY_ADDR];
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+
+ if (epause->rx_pause) {
+ if (epause->tx_pause)
+@@ -10338,7 +10637,10 @@ static int tg3_run_loopback(struct tg3 *
+ for (i = 14; i < tx_len; i++)
+ tx_data[i] = (u8) (i & 0xff);
+
+- map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
++ if (skb_dma_map(&tp->pdev->dev, skb, DMA_TO_DEVICE)) {
++ dev_kfree_skb(skb);
++ return -EIO;
++ }
+
+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+ rnapi->coal_now);
+@@ -10349,7 +10651,8 @@ static int tg3_run_loopback(struct tg3 *
+
+ num_pkts = 0;
+
+- tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len, 0, 1);
++ tg3_set_txd(tnapi, tnapi->tx_prod,
++ skb_shinfo(skb)->dma_head, tx_len, 0, 1);
+
+ tnapi->tx_prod++;
+ num_pkts++;
+@@ -10359,8 +10662,8 @@ static int tg3_run_loopback(struct tg3 *
+
+ udelay(10);
+
+- /* 250 usec to allow enough time on some 10/100 Mbps devices. */
+- for (i = 0; i < 25; i++) {
++ /* 350 usec to allow enough time on some 10/100 Mbps devices. */
++ for (i = 0; i < 35; i++) {
+ tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
+ coal_now);
+
+@@ -10373,7 +10676,7 @@ static int tg3_run_loopback(struct tg3 *
+ break;
+ }
+
+- pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE);
++ skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
+ dev_kfree_skb(skb);
+
+ if (tx_idx != tnapi->tx_prod)
+@@ -10565,9 +10868,11 @@ static int tg3_ioctl(struct net_device *
+ int err;
+
+ if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
++ struct phy_device *phydev;
+ if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
+ return -EAGAIN;
+- return phy_mii_ioctl(tp->mdio_bus->phy_map[PHY_ADDR], data, cmd);
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
++ return phy_mii_ioctl(phydev, data, cmd);
+ }
+
+ switch(cmd) {
+@@ -10887,7 +11192,7 @@ static void __devinit tg3_get_5752_nvram
+
+ /* NVRAM protection for TPM */
+ if (nvcfg1 & (1 << 27))
+- tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
++ tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+
+ switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+ case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
+@@ -10928,7 +11233,7 @@ static void __devinit tg3_get_5755_nvram
+
+ /* NVRAM protection for TPM */
+ if (nvcfg1 & (1 << 27)) {
+- tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
++ tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+ protect = 1;
+ }
+
+@@ -11022,7 +11327,7 @@ static void __devinit tg3_get_5761_nvram
+
+ /* NVRAM protection for TPM */
+ if (nvcfg1 & (1 << 27)) {
+- tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
++ tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+ protect = 1;
+ }
+
+@@ -11524,7 +11829,7 @@ static int tg3_nvram_write_block(struct
+
+ tg3_enable_nvram_access(tp);
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+- !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM))
++ !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM))
+ tw32(NVRAM_WRITE1, 0x406);
+
+ grc_mode = tr32(GRC_MODE);
+@@ -12400,10 +12705,9 @@ static int __devinit tg3_get_invariants(
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_USE_PROD_ID_REG) {
+ u32 prod_id_asic_rev;
+
+- if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717C ||
+- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717S ||
+- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718C ||
+- tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718S)
++ if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
++ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
++ tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724)
+ pci_read_config_dword(tp->pdev,
+ TG3PCI_GEN2_PRODID_ASICREV,
+ &prod_id_asic_rev);
+@@ -12586,6 +12890,29 @@ static int __devinit tg3_get_invariants(
+ tp->dev->features |= NETIF_F_IPV6_CSUM;
+ }
+
++ /* Determine TSO capabilities */
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
++ tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
++ else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
++ tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
++ else if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
++ tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 &&
++ tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
++ tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
++ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
++ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
++ tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
++ tp->tg3_flags2 |= TG3_FLG2_TSO_BUG;
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
++ tp->fw_needed = FIRMWARE_TG3TSO5;
++ else
++ tp->fw_needed = FIRMWARE_TG3TSO;
++ }
++
++ tp->irq_max = 1;
++
+ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
+ tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI;
+ if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX ||
+@@ -12597,25 +12924,22 @@ static int __devinit tg3_get_invariants(
+
+ if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+- tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
+ tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
+- } else {
+- tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
+- if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+- ASIC_REV_5750 &&
+- tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
+- tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
+ }
+- }
+
+- tp->irq_max = 1;
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
++ tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
++ tp->irq_max = TG3_IRQ_MAX_VECS;
++ }
++ }
+
+-#ifdef TG3_NAPI
+- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+- tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
+- tp->irq_max = TG3_IRQ_MAX_VECS;
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
++ tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG;
++ else if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) {
++ tp->tg3_flags3 |= TG3_FLG3_4G_DMA_BNDRY_BUG;
++ tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
+ }
+-#endif
+
+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+ (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
+@@ -12926,11 +13250,6 @@ static int __devinit tg3_get_invariants(
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+ tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
+
+- if ((tp->pci_chip_rev_id == CHIPREV_ID_57780_A1 &&
+- tr32(RCVLPC_STATS_ENABLE) & RCVLPC_STATSENAB_ASF_FIX) ||
+- tp->pci_chip_rev_id == CHIPREV_ID_57780_A0)
+- tp->tg3_flags3 |= TG3_FLG3_TOGGLE_10_100_L1PLLPD;
+-
+ err = tg3_mdio_init(tp);
+ if (err)
+ return err;
+@@ -13220,6 +13539,11 @@ static u32 __devinit tg3_calc_dma_bndry(
+ #endif
+ #endif
+
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
++ val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
++ goto out;
++ }
++
+ if (!goal)
+ goto out;
+
+@@ -13414,7 +13738,7 @@ static int __devinit tg3_test_dma(struct
+ {
+ dma_addr_t buf_dma;
+ u32 *buf, saved_dma_rwctrl;
+- int ret;
++ int ret = 0;
+
+ buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma);
+ if (!buf) {
+@@ -13427,6 +13751,9 @@ static int __devinit tg3_test_dma(struct
+
+ tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl);
+
++ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
++ goto out;
++
+ if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+ /* DMA read watermark not used on PCIE */
+ tp->dma_rwctrl |= 0x00180000;
+@@ -13499,7 +13826,6 @@ static int __devinit tg3_test_dma(struct
+ tg3_switch_clocks(tp);
+ #endif
+
+- ret = 0;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+ GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
+ goto out;
+@@ -13678,6 +14004,7 @@ static char * __devinit tg3_phy_string(s
+ case PHY_ID_BCM5756: return "5722/5756";
+ case PHY_ID_BCM5906: return "5906";
+ case PHY_ID_BCM5761: return "5761";
++ case PHY_ID_BCM5717: return "5717";
+ case PHY_ID_BCM8002: return "8002/serdes";
+ case 0: return "serdes";
+ default: return "unknown";
+@@ -13919,51 +14246,6 @@ static int __devinit tg3_init_one(struct
+ tp->rx_pending = TG3_DEF_RX_RING_PENDING;
+ tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
+
+- intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
+- rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
+- sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+- for (i = 0; i < TG3_IRQ_MAX_VECS; i++) {
+- struct tg3_napi *tnapi = &tp->napi[i];
+-
+- tnapi->tp = tp;
+- tnapi->tx_pending = TG3_DEF_TX_RING_PENDING;
+-
+- tnapi->int_mbox = intmbx;
+- if (i < 4)
+- intmbx += 0x8;
+- else
+- intmbx += 0x4;
+-
+- tnapi->consmbox = rcvmbx;
+- tnapi->prodmbox = sndmbx;
+-
+- if (i)
+- tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
+- else
+- tnapi->coal_now = HOSTCC_MODE_NOW;
+-
+- if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
+- break;
+-
+- /*
+- * If we support MSIX, we'll be using RSS. If we're using
+- * RSS, the first vector only handles link interrupts and the
+- * remaining vectors handle rx and tx interrupts. Reuse the
+- * mailbox values for the next iteration. The values we setup
+- * above are still useful for the single vectored mode.
+- */
+- if (!i)
+- continue;
+-
+- rcvmbx += 0x8;
+-
+- if (sndmbx & 0x4)
+- sndmbx -= 0x4;
+- else
+- sndmbx += 0xc;
+- }
+-
+- netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
+ dev->ethtool_ops = &tg3_ethtool_ops;
+ dev->watchdog_timeo = TG3_TX_TIMEOUT;
+ dev->irq = pdev->irq;
+@@ -13975,8 +14257,8 @@ static int __devinit tg3_init_one(struct
+ goto err_out_iounmap;
+ }
+
+- if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
++ if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
++ tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
+ dev->netdev_ops = &tg3_netdev_ops;
+ else
+ dev->netdev_ops = &tg3_netdev_ops_dma_bug;
+@@ -14023,46 +14305,39 @@ static int __devinit tg3_init_one(struct
+
+ tg3_init_bufmgr_config(tp);
+
+- if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
+- tp->fw_needed = FIRMWARE_TG3;
+-
+- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
++ /* Selectively allow TSO based on operating conditions */
++ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
++ (tp->fw_needed && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)))
+ tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+- }
+- else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
+- tp->pci_chip_rev_id == CHIPREV_ID_5705_A0 ||
+- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
+- (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
+- tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
+- } else {
+- tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG;
+- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
+- tp->fw_needed = FIRMWARE_TG3TSO5;
+- else
+- tp->fw_needed = FIRMWARE_TG3TSO;
++ else {
++ tp->tg3_flags2 &= ~(TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG);
++ tp->fw_needed = NULL;
+ }
+
++ if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
++ tp->fw_needed = FIRMWARE_TG3;
++
+ /* TSO is on by default on chips that support hardware TSO.
+ * Firmware TSO on older chips gives lower performance, so it
+ * is off by default, but can be enabled using ethtool.
+ */
+- if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
+- if (dev->features & NETIF_F_IP_CSUM)
+- dev->features |= NETIF_F_TSO;
+- if ((dev->features & NETIF_F_IPV6_CSUM) &&
+- (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2))
++ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) &&
++ (dev->features & NETIF_F_IP_CSUM))
++ dev->features |= NETIF_F_TSO;
++
++ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
++ (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3)) {
++ if (dev->features & NETIF_F_IPV6_CSUM)
+ dev->features |= NETIF_F_TSO6;
+- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
++ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+ (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+ GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
++ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+ dev->features |= NETIF_F_TSO_ECN;
+ }
+
+-
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
+ !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
+ !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
+@@ -14113,6 +14388,53 @@ static int __devinit tg3_init_one(struct
+ tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+ tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
+
++ intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
++ rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
++ sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
++ for (i = 0; i < TG3_IRQ_MAX_VECS; i++) {
++ struct tg3_napi *tnapi = &tp->napi[i];
++
++ tnapi->tp = tp;
++ tnapi->tx_pending = TG3_DEF_TX_RING_PENDING;
++
++ tnapi->int_mbox = intmbx;
++ if (i < 4)
++ intmbx += 0x8;
++ else
++ intmbx += 0x4;
++
++ tnapi->consmbox = rcvmbx;
++ tnapi->prodmbox = sndmbx;
++
++ if (i) {
++ tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
++ netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64);
++ } else {
++ tnapi->coal_now = HOSTCC_MODE_NOW;
++ netif_napi_add(dev, &tnapi->napi, tg3_poll, 64);
++ }
++
++ if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
++ break;
++
++ /*
++ * If we support MSIX, we'll be using RSS. If we're using
++ * RSS, the first vector only handles link interrupts and the
++ * remaining vectors handle rx and tx interrupts. Reuse the
++ * mailbox values for the next iteration. The values we setup
++ * above are still useful for the single vectored mode.
++ */
++ if (!i)
++ continue;
++
++ rcvmbx += 0x8;
++
++ if (sndmbx & 0x4)
++ sndmbx -= 0x4;
++ else
++ sndmbx += 0xc;
++ }
++
+ tg3_init_coal(tp);
+
+ pci_set_drvdata(pdev, dev);
+@@ -14131,13 +14453,14 @@ static int __devinit tg3_init_one(struct
+ tg3_bus_string(tp, str),
+ dev->dev_addr);
+
+- if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
++ if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
++ struct phy_device *phydev;
++ phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+ printk(KERN_INFO
+ "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
+- tp->dev->name,
+- tp->mdio_bus->phy_map[PHY_ADDR]->drv->name,
+- dev_name(&tp->mdio_bus->phy_map[PHY_ADDR]->dev));
+- else
++ tp->dev->name, phydev->drv->name,
++ dev_name(&phydev->dev));
++ } else
+ printk(KERN_INFO
+ "%s: attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n",
+ tp->dev->name, tg3_phy_string(tp),
+Index: linux-2.6.31-master/drivers/net/tg3.h
+===================================================================
+--- linux-2.6.31-master.orig/drivers/net/tg3.h
++++ linux-2.6.31-master/drivers/net/tg3.h
+@@ -46,10 +46,9 @@
+ #define TG3PCI_DEVICE_TIGON3_57788 0x1691
+ #define TG3PCI_DEVICE_TIGON3_5785_G 0x1699 /* GPHY */
+ #define TG3PCI_DEVICE_TIGON3_5785_F 0x16a0 /* 10/100 only */
+-#define TG3PCI_DEVICE_TIGON3_5717C 0x1655
+-#define TG3PCI_DEVICE_TIGON3_5717S 0x1656
+-#define TG3PCI_DEVICE_TIGON3_5718C 0x1665
+-#define TG3PCI_DEVICE_TIGON3_5718S 0x1666
++#define TG3PCI_DEVICE_TIGON3_5717 0x1655
++#define TG3PCI_DEVICE_TIGON3_5718 0x1656
++#define TG3PCI_DEVICE_TIGON3_5724 0x165c
+ /* 0x04 --> 0x64 unused */
+ #define TG3PCI_MSI_DATA 0x00000064
+ /* 0x66 --> 0x68 unused */
+@@ -103,6 +102,7 @@
+ #define CHIPREV_ID_5906_A1 0xc001
+ #define CHIPREV_ID_57780_A0 0x57780000
+ #define CHIPREV_ID_57780_A1 0x57780001
++#define CHIPREV_ID_5717_A0 0x05717000
+ #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
+ #define ASIC_REV_5700 0x07
+ #define ASIC_REV_5701 0x00
+@@ -141,8 +141,7 @@
+ #define METAL_REV_B1 0x01
+ #define METAL_REV_B2 0x02
+ #define TG3PCI_DMA_RW_CTRL 0x0000006c
+-#define DMA_RWCTRL_MIN_DMA 0x000000ff
+-#define DMA_RWCTRL_MIN_DMA_SHIFT 0
++#define DMA_RWCTRL_DIS_CACHE_ALIGNMENT 0x00000001
+ #define DMA_RWCTRL_READ_BNDRY_MASK 0x00000700
+ #define DMA_RWCTRL_READ_BNDRY_DISAB 0x00000000
+ #define DMA_RWCTRL_READ_BNDRY_16 0x00000100
+@@ -242,7 +241,11 @@
+ #define MAILBOX_GENERAL_7 0x00000258 /* 64-bit */
+ #define MAILBOX_RELOAD_STAT 0x00000260 /* 64-bit */
+ #define MAILBOX_RCV_STD_PROD_IDX 0x00000268 /* 64-bit */
++#define TG3_RX_STD_PROD_IDX_REG (MAILBOX_RCV_STD_PROD_IDX + \
++ TG3_64BIT_REG_LOW)
+ #define MAILBOX_RCV_JUMBO_PROD_IDX 0x00000270 /* 64-bit */
++#define TG3_RX_JMB_PROD_IDX_REG (MAILBOX_RCV_JUMBO_PROD_IDX + \
++ TG3_64BIT_REG_LOW)
+ #define MAILBOX_RCV_MINI_PROD_IDX 0x00000278 /* 64-bit */
+ #define MAILBOX_RCVRET_CON_IDX_0 0x00000280 /* 64-bit */
+ #define MAILBOX_RCVRET_CON_IDX_1 0x00000288 /* 64-bit */
+@@ -1264,8 +1267,9 @@
+ #define WDMAC_MODE_FIFOURUN_ENAB 0x00000080
+ #define WDMAC_MODE_FIFOOREAD_ENAB 0x00000100
+ #define WDMAC_MODE_LNGREAD_ENAB 0x00000200
+-#define WDMAC_MODE_RX_ACCEL 0x00000400
++#define WDMAC_MODE_RX_ACCEL 0x00000400
+ #define WDMAC_MODE_STATUS_TAG_FIX 0x20000000
++#define WDMAC_MODE_BURST_ALL_DATA 0xc0000000
+ #define WDMAC_STATUS 0x00004c04
+ #define WDMAC_STATUS_TGTABORT 0x00000004
+ #define WDMAC_STATUS_MSTABORT 0x00000008
+@@ -1953,10 +1957,34 @@
+ #define NIC_SRAM_MBUF_POOL_BASE5705 0x00010000
+ #define NIC_SRAM_MBUF_POOL_SIZE5705 0x0000e000
+
++
+ /* Currently this is fixed. */
+-#define PHY_ADDR 0x01
++#define TG3_PHY_PCIE_ADDR 0x00
++#define TG3_PHY_MII_ADDR 0x01
++
++
++/*** Tigon3 specific PHY PCIE registers. ***/
++
++#define TG3_PCIEPHY_BLOCK_ADDR 0x1f
++#define TG3_PCIEPHY_XGXS_BLK1 0x0801
++#define TG3_PCIEPHY_TXB_BLK 0x0861
++#define TG3_PCIEPHY_BLOCK_SHIFT 4
+
+-/* Tigon3 specific PHY MII registers. */
++/* TG3_PCIEPHY_TXB_BLK */
++#define TG3_PCIEPHY_TX0CTRL1 0x15
++#define TG3_PCIEPHY_TX0CTRL1_TXOCM 0x0003
++#define TG3_PCIEPHY_TX0CTRL1_RDCTL 0x0008
++#define TG3_PCIEPHY_TX0CTRL1_TXCMV 0x0030
++#define TG3_PCIEPHY_TX0CTRL1_TKSEL 0x0040
++#define TG3_PCIEPHY_TX0CTRL1_NB_EN 0x0400
++
++/* TG3_PCIEPHY_XGXS_BLK1 */
++#define TG3_PCIEPHY_PWRMGMT4 0x1a
++#define TG3_PCIEPHY_PWRMGMT4_L1PLLPD_EN 0x0038
++#define TG3_PCIEPHY_PWRMGMT4_LOWPWR_EN 0x4000
++
++
++/*** Tigon3 specific PHY MII registers. ***/
+ #define TG3_BMCR_SPEED1000 0x0040
+
+ #define MII_TG3_CTRL 0x09 /* 1000-baseT control register */
+@@ -2055,6 +2083,9 @@
+ #define MII_TG3_FET_SHDW_MISCCTRL 0x10
+ #define MII_TG3_FET_SHDW_MISCCTRL_MDIX 0x4000
+
++#define MII_TG3_FET_SHDW_AUXMODE4 0x1a
++#define MII_TG3_FET_SHDW_AUXMODE4_SBPD 0x0008
++
+ #define MII_TG3_FET_SHDW_AUXSTAT2 0x1b
+ #define MII_TG3_FET_SHDW_AUXSTAT2_APD 0x0020
+
+@@ -2542,8 +2573,10 @@ struct tg3_ethtool_stats {
+ };
+
+ struct tg3_rx_prodring_set {
+- u32 rx_std_ptr;
+- u32 rx_jmb_ptr;
++ u32 rx_std_prod_idx;
++ u32 rx_std_cons_idx;
++ u32 rx_jmb_prod_idx;
++ u32 rx_jmb_cons_idx;
+ struct tg3_rx_buffer_desc *rx_std;
+ struct tg3_ext_rx_buffer_desc *rx_jmb;
+ struct ring_info *rx_std_buffers;
+@@ -2571,6 +2604,7 @@ struct tg3_napi {
+ u32 consmbox;
+ u32 rx_rcb_ptr;
+ u16 *rx_rcb_prod_idx;
++ struct tg3_rx_prodring_set *prodring;
+
+ struct tg3_rx_buffer_desc *rx_rcb;
+ struct tg3_tx_buffer_desc *tx_ring;
+@@ -2654,7 +2688,7 @@ struct tg3 {
+ struct vlan_group *vlgrp;
+ #endif
+
+- struct tg3_rx_prodring_set prodring[1];
++ struct tg3_rx_prodring_set prodring[TG3_IRQ_MAX_VECS - 1];
+
+
+ /* begin "everything else" cacheline(s) section */
+@@ -2725,7 +2759,7 @@ struct tg3 {
+ #define TG3_FLG2_SERDES_PREEMPHASIS 0x00020000
+ #define TG3_FLG2_5705_PLUS 0x00040000
+ #define TG3_FLG2_5750_PLUS 0x00080000
+-#define TG3_FLG2_PROTECTED_NVRAM 0x00100000
++#define TG3_FLG2_HW_TSO_3 0x00100000
+ #define TG3_FLG2_USING_MSI 0x00200000
+ #define TG3_FLG2_USING_MSIX 0x00400000
+ #define TG3_FLG2_USING_MSI_OR_MSIX (TG3_FLG2_USING_MSI | \
+@@ -2737,7 +2771,9 @@ struct tg3 {
+ #define TG3_FLG2_ICH_WORKAROUND 0x02000000
+ #define TG3_FLG2_5780_CLASS 0x04000000
+ #define TG3_FLG2_HW_TSO_2 0x08000000
+-#define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2)
++#define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | \
++ TG3_FLG2_HW_TSO_2 | \
++ TG3_FLG2_HW_TSO_3)
+ #define TG3_FLG2_1SHOT_MSI 0x10000000
+ #define TG3_FLG2_PHY_JITTER_BUG 0x20000000
+ #define TG3_FLG2_NO_FWARE_REPORTED 0x40000000
+@@ -2745,6 +2781,7 @@ struct tg3 {
+ u32 tg3_flags3;
+ #define TG3_FLG3_NO_NVRAM_ADDR_TRANS 0x00000001
+ #define TG3_FLG3_ENABLE_APE 0x00000002
++#define TG3_FLG3_PROTECTED_NVRAM 0x00000004
+ #define TG3_FLG3_5701_DMA_BUG 0x00000008
+ #define TG3_FLG3_USE_PHYLIB 0x00000010
+ #define TG3_FLG3_MDIOBUS_INITED 0x00000020
+@@ -2756,9 +2793,11 @@ struct tg3 {
+ #define TG3_FLG3_PHY_ENABLE_APD 0x00001000
+ #define TG3_FLG3_5755_PLUS 0x00002000
+ #define TG3_FLG3_NO_NVRAM 0x00004000
+-#define TG3_FLG3_TOGGLE_10_100_L1PLLPD 0x00008000
+ #define TG3_FLG3_PHY_IS_FET 0x00010000
+ #define TG3_FLG3_ENABLE_RSS 0x00020000
++#define TG3_FLG3_4G_DMA_BNDRY_BUG 0x00080000
++#define TG3_FLG3_40BIT_DMA_LIMIT_BUG 0x00100000
++#define TG3_FLG3_SHORT_DMA_BUG 0x00200000
+
+ struct timer_list timer;
+ u16 timer_counter;
+@@ -2825,6 +2864,7 @@ struct tg3 {
+ #define PHY_ID_BCM5756 0xbc050ed0
+ #define PHY_ID_BCM5784 0xbc050fa0
+ #define PHY_ID_BCM5761 0xbc050fd0
++#define PHY_ID_BCM5717 0x5c0d8a00
+ #define PHY_ID_BCM5906 0xdc00ac40
+ #define PHY_ID_BCM8002 0x60010140
+ #define PHY_ID_INVALID 0xffffffff
+@@ -2834,6 +2874,7 @@ struct tg3 {
+ #define PHY_REV_BCM5401_C0 0x6
+ #define PHY_REV_BCM5411_X0 0x1 /* Found on Netgear GA302T */
+ #define TG3_PHY_ID_BCM50610 0x143bd60
++#define TG3_PHY_ID_BCM50610M 0x143bd70
+ #define TG3_PHY_ID_BCMAC131 0x143bc70
+ #define TG3_PHY_ID_RTL8211C 0x001cc910
+ #define TG3_PHY_ID_RTL8201E 0x00008200
+@@ -2865,7 +2906,7 @@ struct tg3 {
+ (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \
+ (X) == PHY_ID_BCM5755 || (X) == PHY_ID_BCM5756 || \
+ (X) == PHY_ID_BCM5906 || (X) == PHY_ID_BCM5761 || \
+- (X) == PHY_ID_BCM8002)
++ (X) == PHY_ID_BCM5717 || (X) == PHY_ID_BCM8002)
+
+ struct tg3_hw_stats *hw_stats;
+ dma_addr_t stats_mapping;
diff --git a/patches.fixes/scsi-fix-bug-with-dma-maps-on-nested-scsi-objects b/patches.fixes/scsi-fix-bug-with-dma-maps-on-nested-scsi-objects
new file mode 100644
index 0000000000..e3f549cf5c
--- /dev/null
+++ b/patches.fixes/scsi-fix-bug-with-dma-maps-on-nested-scsi-objects
@@ -0,0 +1,153 @@
+From: James Bottomley <James.Bottomley@suse.de>
+Date: Thu, 5 Nov 2009 13:33:12 -0600
+Subject: scsi_lib_dma: fix bug with dma maps on nested scsi objects
+References: bnc#556595
+X-Git-scsi-misc: 2cbf595a1dc7c63c8aec257b41cf7631163fae86
+
+Some of our virtual SCSI hosts don't have a proper bus parent at the
+top, which can be a problem for doing DMA on them
+
+This patch makes the host device cache a pointer to the physical bus
+device and provides an extra API for setting it (the normal API picks
+it up from the parent). This patch also modifies the qla2xxx and lpfc
+vport logic to use the new DMA host setting API.
+
+Acked-By: James Smart <james.smart@emulex.com>
+Cc: Stable Tree <stable@kernel.org>
+Signed-off-by: James Bottomley <James.Bottomley@suse.de>
+Acked-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index 5fd2da4..28a753d 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -180,14 +180,20 @@ void scsi_remove_host(struct Scsi_Host *shost)
+ EXPORT_SYMBOL(scsi_remove_host);
+
+ /**
+- * scsi_add_host - add a scsi host
++ * scsi_add_host_with_dma - add a scsi host with dma device
+ * @shost: scsi host pointer to add
+ * @dev: a struct device of type scsi class
++ * @dma_dev: dma device for the host
++ *
++ * Note: You rarely need to worry about this unless you're in a
++ * virtualised host environments, so use the simpler scsi_add_host()
++ * function instead.
+ *
+ * Return value:
+ * 0 on success / != 0 for error
+ **/
+-int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
++int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
++ struct device *dma_dev)
+ {
+ struct scsi_host_template *sht = shost->hostt;
+ int error = -EINVAL;
+@@ -207,6 +213,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
+
+ if (!shost->shost_gendev.parent)
+ shost->shost_gendev.parent = dev ? dev : &platform_bus;
++ shost->dma_dev = dma_dev;
+
+ error = device_add(&shost->shost_gendev);
+ if (error)
+@@ -262,7 +269,7 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
+ fail:
+ return error;
+ }
+-EXPORT_SYMBOL(scsi_add_host);
++EXPORT_SYMBOL(scsi_add_host_with_dma);
+
+ static void scsi_host_dev_release(struct device *dev)
+ {
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 562d8ce..f913f1e 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -2408,7 +2408,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
+ vport->els_tmofunc.function = lpfc_els_timeout;
+ vport->els_tmofunc.data = (unsigned long)vport;
+
+- error = scsi_add_host(shost, dev);
++ error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
+ if (error)
+ goto out_put_shost;
+
+diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index fbcb82a..21e2bc4 100644
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -1654,7 +1654,8 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
+ fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
+ }
+
+- if (scsi_add_host(vha->host, &fc_vport->dev)) {
++ if (scsi_add_host_with_dma(vha->host, &fc_vport->dev,
++ &ha->pdev->dev)) {
+ DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n",
+ vha->host_no, vha->vp_idx));
+ goto vport_create_failed_2;
+diff --git a/drivers/scsi/scsi_lib_dma.c b/drivers/scsi/scsi_lib_dma.c
+index ac6855c..dcd1285 100644
+--- a/drivers/scsi/scsi_lib_dma.c
++++ b/drivers/scsi/scsi_lib_dma.c
+@@ -23,7 +23,7 @@ int scsi_dma_map(struct scsi_cmnd *cmd)
+ int nseg = 0;
+
+ if (scsi_sg_count(cmd)) {
+- struct device *dev = cmd->device->host->shost_gendev.parent;
++ struct device *dev = cmd->device->host->dma_dev;
+
+ nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
+ cmd->sc_data_direction);
+@@ -41,7 +41,7 @@ EXPORT_SYMBOL(scsi_dma_map);
+ void scsi_dma_unmap(struct scsi_cmnd *cmd)
+ {
+ if (scsi_sg_count(cmd)) {
+- struct device *dev = cmd->device->host->shost_gendev.parent;
++ struct device *dev = cmd->device->host->dma_dev;
+
+ dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
+ cmd->sc_data_direction);
+diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
+index 603054d..6ff6bc1 100644
+--- a/include/scsi/scsi_host.h
++++ b/include/scsi/scsi_host.h
+@@ -683,6 +683,12 @@ struct Scsi_Host {
+ void *shost_data;
+
+ /*
++ * Points to the physical bus device we'd use to do DMA
++ * Needed just in case we have virtual hosts.
++ */
++ struct device *dma_dev;
++
++ /*
+ * We should ensure that this is aligned, both for better performance
+ * and also because some compilers (m68k) don't automatically force
+ * alignment to a long boundary.
+@@ -726,7 +732,9 @@ extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
+ extern void scsi_flush_work(struct Scsi_Host *);
+
+ extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
+-extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *);
++extern int __must_check scsi_add_host_with_dma(struct Scsi_Host *,
++ struct device *,
++ struct device *);
+ extern void scsi_scan_host(struct Scsi_Host *);
+ extern void scsi_rescan_device(struct device *);
+ extern void scsi_remove_host(struct Scsi_Host *);
+@@ -737,6 +745,12 @@ extern const char *scsi_host_state_name(enum scsi_host_state);
+
+ extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
+
++static inline int __must_check scsi_add_host(struct Scsi_Host *host,
++ struct device *dev)
++{
++ return scsi_add_host_with_dma(host, dev, dev);
++}
++
+ static inline struct device *scsi_get_device(struct Scsi_Host *shost)
+ {
+ return shost->shost_gendev.parent;
diff --git a/patches.fixes/scsi-introduce-helper-function-for-blocking-eh b/patches.fixes/scsi-introduce-helper-function-for-blocking-eh
new file mode 100644
index 0000000000..6967975add
--- /dev/null
+++ b/patches.fixes/scsi-introduce-helper-function-for-blocking-eh
@@ -0,0 +1,248 @@
+From: Christof Schmitt <christof.schmitt@de.ibm.com>
+Date: Fri, 30 Oct 2009 17:59:29 +0100
+Subject: [PATCH] [SCSI] scsi_transport_fc: Introduce helper function for blocking scsi_eh
+X-Git-scsi-misc: d0148dc708c774a0b5631c8d47c4ceb758634d10
+References: bnc#556595
+
+Move the duplicated code from FC LLDs to SCSI FC transport class.
+
+Acked-by: James Smart <james.smart@emulex.com>
+Acked-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
+Acked-by: Abhijeet Joglekar <abjoglek@cisco.com>
+Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
+Signed-off-by: James Bottomley <James.Bottomley@suse.de>
+Acked-by: Hannes Reinecke <hare@suse.de>
+
+diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
+index b5d1738..8d26d7a 100644
+--- a/drivers/scsi/fnic/fnic_scsi.c
++++ b/drivers/scsi/fnic/fnic_scsi.c
+@@ -1225,22 +1225,6 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
+
+ }
+
+-static void fnic_block_error_handler(struct scsi_cmnd *sc)
+-{
+- struct Scsi_Host *shost = sc->device->host;
+- struct fc_rport *rport = starget_to_rport(scsi_target(sc->device));
+- unsigned long flags;
+-
+- spin_lock_irqsave(shost->host_lock, flags);
+- while (rport->port_state == FC_PORTSTATE_BLOCKED) {
+- spin_unlock_irqrestore(shost->host_lock, flags);
+- msleep(1000);
+- spin_lock_irqsave(shost->host_lock, flags);
+- }
+- spin_unlock_irqrestore(shost->host_lock, flags);
+-
+-}
+-
+ /*
+ * This function is exported to SCSI for sending abort cmnds.
+ * A SCSI IO is represented by a io_req in the driver.
+@@ -1260,7 +1244,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
+ DECLARE_COMPLETION_ONSTACK(tm_done);
+
+ /* Wait for rport to unblock */
+- fnic_block_error_handler(sc);
++ fc_block_scsi_eh(sc);
+
+ /* Get local-port, check ready and link up */
+ lp = shost_priv(sc->device->host);
+@@ -1542,7 +1526,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
+ DECLARE_COMPLETION_ONSTACK(tm_done);
+
+ /* Wait for rport to unblock */
+- fnic_block_error_handler(sc);
++ fc_block_scsi_eh(sc);
+
+ /* Get local-port, check ready and link up */
+ lp = shost_priv(sc->device->host);
+diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
+index c88f59f..e251791 100644
+--- a/drivers/scsi/lpfc/lpfc_scsi.c
++++ b/drivers/scsi/lpfc/lpfc_scsi.c
+@@ -2917,28 +2917,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
+ }
+
+ /**
+- * lpfc_block_error_handler - Routine to block error handler
+- * @cmnd: Pointer to scsi_cmnd data structure.
+- *
+- * This routine blocks execution till fc_rport state is not FC_PORSTAT_BLCOEKD.
+- **/
+-static void
+-lpfc_block_error_handler(struct scsi_cmnd *cmnd)
+-{
+- struct Scsi_Host *shost = cmnd->device->host;
+- struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+-
+- spin_lock_irq(shost->host_lock);
+- while (rport->port_state == FC_PORTSTATE_BLOCKED) {
+- spin_unlock_irq(shost->host_lock);
+- msleep(1000);
+- spin_lock_irq(shost->host_lock);
+- }
+- spin_unlock_irq(shost->host_lock);
+- return;
+-}
+-
+-/**
+ * lpfc_abort_handler - scsi_host_template eh_abort_handler entry point
+ * @cmnd: Pointer to scsi_cmnd data structure.
+ *
+@@ -2961,7 +2939,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
+ int ret = SUCCESS;
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
+
+- lpfc_block_error_handler(cmnd);
++ fc_block_scsi_eh(cmnd);
+ lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
+ BUG_ON(!lpfc_cmd);
+
+@@ -3259,7 +3237,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
+ struct lpfc_scsi_event_header scsi_event;
+ int status;
+
+- lpfc_block_error_handler(cmnd);
++ fc_block_scsi_eh(cmnd);
+
+ status = lpfc_chk_tgt_mapped(vport, cmnd);
+ if (status == FAILED) {
+@@ -3318,7 +3296,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
+ struct lpfc_scsi_event_header scsi_event;
+ int status;
+
+- lpfc_block_error_handler(cmnd);
++ fc_block_scsi_eh(cmnd);
+
+ status = lpfc_chk_tgt_mapped(vport, cmnd);
+ if (status == FAILED) {
+@@ -3384,7 +3362,7 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
+ fc_host_post_vendor_event(shost, fc_get_event_number(),
+ sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
+
+- lpfc_block_error_handler(cmnd);
++ fc_block_scsi_eh(cmnd);
+
+ /*
+ * Since the driver manages a single bus device, reset all
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index d69744a..4166935 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -728,23 +728,6 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport)
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
+
+-static void
+-qla2x00_block_error_handler(struct scsi_cmnd *cmnd)
+-{
+- struct Scsi_Host *shost = cmnd->device->host;
+- struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+- unsigned long flags;
+-
+- spin_lock_irqsave(shost->host_lock, flags);
+- while (rport->port_state == FC_PORTSTATE_BLOCKED) {
+- spin_unlock_irqrestore(shost->host_lock, flags);
+- msleep(1000);
+- spin_lock_irqsave(shost->host_lock, flags);
+- }
+- spin_unlock_irqrestore(shost->host_lock, flags);
+- return;
+-}
+-
+ /**************************************************************************
+ * qla2xxx_eh_abort
+ *
+@@ -774,7 +757,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ struct req_que *req = vha->req;
+ srb_t *spt;
+
+- qla2x00_block_error_handler(cmd);
++ fc_block_scsi_eh(cmd);
+
+ if (!CMD_SP(cmd))
+ return SUCCESS;
+@@ -905,7 +888,7 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
+ fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
+ int err;
+
+- qla2x00_block_error_handler(cmd);
++ fc_block_scsi_eh(cmd);
+
+ if (!fcport)
+ return FAILED;
+@@ -985,7 +968,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
+ unsigned long serial;
+ srb_t *sp = (srb_t *) CMD_SP(cmd);
+
+- qla2x00_block_error_handler(cmd);
++ fc_block_scsi_eh(cmd);
+
+ id = cmd->device->id;
+ lun = cmd->device->lun;
+@@ -1048,7 +1031,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
+ srb_t *sp = (srb_t *) CMD_SP(cmd);
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+
+- qla2x00_block_error_handler(cmd);
++ fc_block_scsi_eh(cmd);
+
+ id = cmd->device->id;
+ lun = cmd->device->lun;
+diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
+index 51ab0c0..4d2877a 100644
+--- a/drivers/scsi/scsi_transport_fc.c
++++ b/drivers/scsi/scsi_transport_fc.c
+@@ -27,6 +27,7 @@
+ */
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/delay.h>
+ #include <scsi/scsi_device.h>
+ #include <scsi/scsi_host.h>
+ #include <scsi/scsi_transport.h>
+@@ -3144,6 +3145,31 @@ fc_scsi_scan_rport(struct work_struct *work)
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ }
+
++/**
++ * fc_block_scsi_eh - Block SCSI eh thread for blocked fc_rport
++ * @cmnd: SCSI command that scsi_eh is trying to recover
++ *
++ * This routine can be called from a FC LLD scsi_eh callback. It
++ * blocks the scsi_eh thread until the fc_rport leaves the
++ * FC_PORTSTATE_BLOCKED. This is necessary to avoid the scsi_eh
++ * failing recovery actions for blocked rports which would lead to
++ * offlined SCSI devices.
++ */
++void fc_block_scsi_eh(struct scsi_cmnd *cmnd)
++{
++ struct Scsi_Host *shost = cmnd->device->host;
++ struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
++ unsigned long flags;
++
++ spin_lock_irqsave(shost->host_lock, flags);
++ while (rport->port_state == FC_PORTSTATE_BLOCKED) {
++ spin_unlock_irqrestore(shost->host_lock, flags);
++ msleep(1000);
++ spin_lock_irqsave(shost->host_lock, flags);
++ }
++ spin_unlock_irqrestore(shost->host_lock, flags);
++}
++EXPORT_SYMBOL(fc_block_scsi_eh);
+
+ /**
+ * fc_vport_setup - allocates and creates a FC virtual port.
+diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
+index fc50bd6..8e86a94 100644
+--- a/include/scsi/scsi_transport_fc.h
++++ b/include/scsi/scsi_transport_fc.h
+@@ -807,5 +807,6 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
+ struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
+ struct fc_vport_identifiers *);
+ int fc_vport_terminate(struct fc_vport *vport);
++void fc_block_scsi_eh(struct scsi_cmnd *cmnd);
+
+ #endif /* SCSI_TRANSPORT_FC_H */
diff --git a/patches.fixes/scsi-skip-nonscsi-device-for-dma b/patches.fixes/scsi-skip-nonscsi-device-for-dma
deleted file mode 100644
index cac87985a0..0000000000
--- a/patches.fixes/scsi-skip-nonscsi-device-for-dma
+++ /dev/null
@@ -1,106 +0,0 @@
-From: James Smart <james.smart@emulex.com>
-Subject: scsi_lib_dma.c : fix bug w/ dma on virtual fc ports
-References: bnc#431294
-
-When the updated scsi dma code was introduced recently, it assumed
-the physical host/adapter was the parent of the scsi host.
-Unfortunately, on FC virtual ports, the parent of the scsi host is
-the virtual port, which does not have dma information.
-
-I have updated the dma routines to use a function that finds the
-first non-scsi object. A non-scsi object is defined to be an object
-that has a non-NULL type (assumes all transport objects have NULL
-types) or a non-scsi_host type.
-
--- james s
-
-Unfortunately the original patch is not correct, as eg the PCI device
-doesn't set the 'type' pointer, so the system will crash miserably.
-We should rather check for the 'bus' argument, and return the original
-argument if we don't find anything.
-
-Signed-off-by: Hannes Reinecke <hare@suse.de>
-
----
- drivers/scsi/scsi_lib.c | 2 +-
- drivers/scsi/scsi_lib_dma.c | 7 +++++--
- include/scsi/scsi_host.h | 24 ++++++++++++++++++++++++
- 3 files changed, 30 insertions(+), 3 deletions(-)
-
---- a/drivers/scsi/scsi_lib.c
-+++ b/drivers/scsi/scsi_lib.c
-@@ -1611,7 +1611,7 @@ struct request_queue *__scsi_alloc_queue
- request_fn_proc *request_fn)
- {
- struct request_queue *q;
-- struct device *dev = shost->shost_gendev.parent;
-+ struct device *dev = dev_to_nonscsi_dev(shost->shost_gendev.parent);
-
- q = blk_init_queue(request_fn, NULL);
- if (!q)
---- a/drivers/scsi/scsi_lib_dma.c
-+++ b/drivers/scsi/scsi_lib_dma.c
-@@ -23,7 +23,8 @@ int scsi_dma_map(struct scsi_cmnd *cmd)
- int nseg = 0;
-
- if (scsi_sg_count(cmd)) {
-- struct device *dev = cmd->device->host->shost_gendev.parent;
-+ struct device *dev = dev_to_nonscsi_dev(
-+ cmd->device->host->shost_gendev.parent);
-
- nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
- cmd->sc_data_direction);
-@@ -41,10 +42,12 @@ EXPORT_SYMBOL(scsi_dma_map);
- void scsi_dma_unmap(struct scsi_cmnd *cmd)
- {
- if (scsi_sg_count(cmd)) {
-- struct device *dev = cmd->device->host->shost_gendev.parent;
-+ struct device *dev = dev_to_nonscsi_dev(
-+ cmd->device->host->shost_gendev.parent);
-
- dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd),
- cmd->sc_data_direction);
- }
- }
- EXPORT_SYMBOL(scsi_dma_unmap);
-+
---- a/include/scsi/scsi_host.h
-+++ b/include/scsi/scsi_host.h
-@@ -698,6 +698,10 @@ static inline void *shost_priv(struct Sc
-
- int scsi_is_host_device(const struct device *);
-
-+/*
-+ * walks object list backward, to find the first shost object.
-+ * Skips over transport objects that may not be stargets, etc
-+ */
- static inline struct Scsi_Host *dev_to_shost(struct device *dev)
- {
- while (!scsi_is_host_device(dev)) {
-@@ -708,6 +712,26 @@ static inline struct Scsi_Host *dev_to_s
- return container_of(dev, struct Scsi_Host, shost_gendev);
- }
-
-+/*
-+ * walks object list backward, to find the first physical
-+ * device object. If none is found return the original device.
-+ */
-+static inline struct device *dev_to_nonscsi_dev(struct device *dev)
-+{
-+ struct device *orig = dev;
-+
-+ while (dev && (dev->bus == NULL || scsi_is_host_device(dev))) {
-+ if (dev->dma_parms) {
-+ dev_printk(KERN_WARNING, dev,
-+ "dma_parms set, bus %p\n",
-+ dev->bus);
-+ break;
-+ }
-+ dev = dev->parent;
-+ }
-+ return dev?dev:orig;
-+}
-+
- static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
- {
- return shost->shost_state == SHOST_RECOVERY ||
diff --git a/patches.suse/crasher-26.diff b/patches.suse/crasher-26.diff
index 0040d3b2e3..07ccda3784 100644
--- a/patches.suse/crasher-26.diff
+++ b/patches.suse/crasher-26.diff
@@ -88,20 +88,20 @@ Subject: slab testing module
+static int sizes[] = { 32, 64, 128, 192, 256, 1024, 2048, 4096 };
+
+struct mem_buf {
-+ char *buf;
-+ int size;
++ char *buf;
++ int size;
+};
+
+static unsigned long crasher_random(void)
+{
-+ rand_seed = rand_seed*69069L+1;
-+ return rand_seed^jiffies;
++ rand_seed = rand_seed*69069L+1;
++ return rand_seed^jiffies;
+}
+
+void crasher_srandom(unsigned long entropy)
+{
-+ rand_seed ^= entropy;
-+ crasher_random();
++ rand_seed ^= entropy;
++ crasher_random();
+}
+
+static char *mem_alloc(int size) {
@@ -119,7 +119,7 @@ Subject: slab testing module
+ if (!p)
+ return;
+ for (i = 0 ; i < size; i++) {
-+ if (p[i] != ((i % 119) + 8)) {
++ if (p[i] != ((i % 119) + 8)) {
+ printk(KERN_CRIT "verify error at %lX offset %d "
+ " wanted %d found %d size %d\n",
+ (unsigned long)(p + i), i, (i % 119) + 8,
diff --git a/patches.suse/export-sync_page_range b/patches.suse/export-sync_page_range
new file mode 100644
index 0000000000..8a506d333e
--- /dev/null
+++ b/patches.suse/export-sync_page_range
@@ -0,0 +1,189 @@
+From 48b8926b6b02382bc774efee2ed2cd6be8770ac0 Mon Sep 17 00:00:00 2001
+From: Michal Marek <mmarek@suse.cz>
+Date: Fri, 20 Nov 2009 17:25:21 +0100
+Subject: [PATCH] Revert "vfs: Remove generic_osync_inode() and sync_page_range{_nolock}()"
+References: bnc#557231
+
+Commit 18f2ee705d98034b0f229a3202d827468d4bffd9 broke iscsitarget, revert
+it temporarily. The exports are marged _GPL though.
+
+Signed-off-by: Michal Marek <mmarek@suse.cz>
+
+---
+ fs/fs-writeback.c | 54 ++++++++++++++++++++++++++++++++++++++
+ include/linux/fs.h | 5 +++
+ include/linux/writeback.h | 4 +++
+ mm/filemap.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 127 insertions(+), 0 deletions(-)
+
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 9d5360c..f68c542 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1280,3 +1280,57 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc)
+ return ret;
+ }
+ EXPORT_SYMBOL(sync_inode);
++
++/**
++ * generic_osync_inode - flush all dirty data for a given inode to disk
++ * @inode: inode to write
++ * @mapping: the address_space that should be flushed
++ * @what: what to write and wait upon
++ *
++ * This can be called by file_write functions for files which have the
++ * O_SYNC flag set, to flush dirty writes to disk.
++ *
++ * @what is a bitmask, specifying which part of the inode's data should be
++ * written and waited upon.
++ *
++ * OSYNC_DATA: i_mapping's dirty data
++ * OSYNC_METADATA: the buffers at i_mapping->private_list
++ * OSYNC_INODE: the inode itself
++ */
++
++int generic_osync_inode(struct inode *inode, struct address_space *mapping, int what)
++{
++ int err = 0;
++ int need_write_inode_now = 0;
++ int err2;
++
++ if (what & OSYNC_DATA)
++ err = filemap_fdatawrite(mapping);
++ if (what & (OSYNC_METADATA|OSYNC_DATA)) {
++ err2 = sync_mapping_buffers(mapping);
++ if (!err)
++ err = err2;
++ }
++ if (what & OSYNC_DATA) {
++ err2 = filemap_fdatawait(mapping);
++ if (!err)
++ err = err2;
++ }
++
++ spin_lock(&inode_lock);
++ if ((inode->i_state & I_DIRTY) &&
++ ((what & OSYNC_INODE) || (inode->i_state & I_DIRTY_DATASYNC)))
++ need_write_inode_now = 1;
++ spin_unlock(&inode_lock);
++
++ if (need_write_inode_now) {
++ err2 = write_inode_now(inode, 1);
++ if (!err)
++ err = err2;
++ }
++ else
++ inode_sync_wait(inode);
++
++ return err;
++}
++EXPORT_SYMBOL_GPL(generic_osync_inode);
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 2620a8c..d2a9ffa 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1459,6 +1459,11 @@ int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
+ #define DT_SOCK 12
+ #define DT_WHT 14
+
++#define OSYNC_METADATA (1<<0)
++#define OSYNC_DATA (1<<1)
++#define OSYNC_INODE (1<<2)
++int generic_osync_inode(struct inode *, struct address_space *, int);
++
+ /*
+ * This is the "filldir" function type, used by readdir() to let
+ * the kernel specify what kind of dirent layout it wants to have.
+diff --git a/include/linux/writeback.h b/include/linux/writeback.h
+index 66ebddc..3676321 100644
+--- a/include/linux/writeback.h
++++ b/include/linux/writeback.h
+@@ -148,6 +148,10 @@ int write_cache_pages(struct address_space *mapping,
+ struct writeback_control *wbc, writepage_t writepage,
+ void *data);
+ int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
++int sync_page_range(struct inode *inode, struct address_space *mapping,
++ loff_t pos, loff_t count);
++int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
++ loff_t pos, loff_t count);
+ void set_page_dirty_balance(struct page *page, int page_mkwrite);
+ void writeback_set_ratelimit(void);
+
+diff --git a/mm/filemap.c b/mm/filemap.c
+index ef169f3..c7283a9 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -332,6 +332,70 @@ int filemap_fdatawait_range(struct address_space *mapping, loff_t start,
+ EXPORT_SYMBOL(filemap_fdatawait_range);
+
+ /**
++ * sync_page_range - write and wait on all pages in the passed range
++ * @inode: target inode
++ * @mapping: target address_space
++ * @pos: beginning offset in pages to write
++ * @count: number of bytes to write
++ *
++ * Write and wait upon all the pages in the passed range. This is a "data
++ * integrity" operation. It waits upon in-flight writeout before starting and
++ * waiting upon new writeout. If there was an IO error, return it.
++ *
++ * We need to re-take i_mutex during the generic_osync_inode list walk because
++ * it is otherwise livelockable.
++ */
++int sync_page_range(struct inode *inode, struct address_space *mapping,
++ loff_t pos, loff_t count)
++{
++ pgoff_t start = pos >> PAGE_CACHE_SHIFT;
++ pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
++ int ret;
++
++ if (!mapping_cap_writeback_dirty(mapping) || !count)
++ return 0;
++ ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
++ if (ret == 0) {
++ mutex_lock(&inode->i_mutex);
++ ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
++ mutex_unlock(&inode->i_mutex);
++ }
++ if (ret == 0)
++ ret = wait_on_page_writeback_range(mapping, start, end);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(sync_page_range);
++
++/**
++ * sync_page_range_nolock - write & wait on all pages in the passed range without locking
++ * @inode: target inode
++ * @mapping: target address_space
++ * @pos: beginning offset in pages to write
++ * @count: number of bytes to write
++ *
++ * Note: Holding i_mutex across sync_page_range_nolock() is not a good idea
++ * as it forces O_SYNC writers to different parts of the same file
++ * to be serialised right until io completion.
++ */
++int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
++ loff_t pos, loff_t count)
++{
++ pgoff_t start = pos >> PAGE_CACHE_SHIFT;
++ pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
++ int ret;
++
++ if (!mapping_cap_writeback_dirty(mapping) || !count)
++ return 0;
++ ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
++ if (ret == 0)
++ ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
++ if (ret == 0)
++ ret = wait_on_page_writeback_range(mapping, start, end);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(sync_page_range_nolock);
++
++/**
+ * filemap_fdatawait - wait for all under-writeback pages to complete
+ * @mapping: address space structure to wait for
+ *
+--
+1.6.4.2
+
diff --git a/patches.suse/init-move-populate_rootfs-back-to-start_kernel b/patches.suse/init-move-populate_rootfs-back-to-start_kernel
index 4af8bbe9c7..164b7ef7f5 100644
--- a/patches.suse/init-move-populate_rootfs-back-to-start_kernel
+++ b/patches.suse/init-move-populate_rootfs-back-to-start_kernel
@@ -40,6 +40,17 @@ Signed-off-by: Jeff Mahoney <jeffm@suse.com>
extern void (*late_time_init)(void);
+--- a/include/linux/kmod.h
++++ b/include/linux/kmod.h
+@@ -98,8 +98,6 @@ call_usermodehelper_keys(char *path, cha
+ return call_usermodehelper_exec(info, wait);
+ }
+
+-extern void usermodehelper_init(void);
+-
+ struct file;
+ extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[],
+ struct file **filp);
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -565,7 +565,7 @@ static void __init clean_rootfs(void)
@@ -84,8 +95,15 @@ Signed-off-by: Jeff Mahoney <jeffm@suse.com>
init_irq_proc();
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
-@@ -536,3 +536,4 @@ void __init usermodehelper_init(void)
+@@ -536,8 +536,10 @@ void __init usermodehelper_init(void)
+ }
+ EXPORT_SYMBOL(call_usermodehelper_pipe);
+
+-void __init usermodehelper_init(void)
++static int __init usermodehelper_init(void)
+ {
khelper_wq = create_singlethread_workqueue("khelper");
BUG_ON(!khelper_wq);
++ return 0;
}
+rootfs_initcall(usermodehelper_init);
diff --git a/patches.suse/kdb-common b/patches.suse/kdb-common
index 4c5c5540b7..69232f2d84 100644
--- a/patches.suse/kdb-common
+++ b/patches.suse/kdb-common
@@ -5261,8 +5261,8 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
usb_set_intfdata(intf, NULL);
if (kbd) {
+#ifdef CONFIG_KDB_USB
-+ /* Detach the keyboard from kdb */
-+ kdb_usb_keyboard_detach(kbd->irq);
++ /* Detach the keyboard from kdb */
++ kdb_usb_keyboard_detach(kbd->irq);
+#endif /* CONFIG_KDB_USB */
usb_kill_urb(kbd->irq);
input_unregister_device(kbd->dev);
@@ -5747,8 +5747,8 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ qtd = list_entry (entry, struct ehci_qtd, qtd_list);
+ urb = qtd->urb;
+
-+ if (urb != kdburb)
-+ continue;
++ if (urb != kdburb)
++ continue;
+
+ /* clean up any state from previous QTD ...*/
+ if (last) {
@@ -5764,12 +5764,12 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+ ehci_urb_done(ehci, last->urb, last_status);
+
-+ /*
-+ * ehci_urb_done() releases and reacquires
++ /*
++ * ehci_urb_done() releases and reacquires
+ * ehci->lock, so release it here.
-+ */
-+ if (spin_is_locked(&ehci->lock))
-+ spin_unlock (&ehci->lock);
++ */
++ if (spin_is_locked(&ehci->lock))
++ spin_unlock (&ehci->lock);
+
+ count++;
+ }
@@ -5881,8 +5881,8 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ * ehci_urb_done() releases and reacquires
+ * ehci->lock, so release it here.
+ */
-+ if (spin_is_locked(&ehci->lock))
-+ spin_unlock (&ehci->lock);
++ if (spin_is_locked(&ehci->lock))
++ spin_unlock (&ehci->lock);
+
+ count++;
+ ehci_qtd_free (ehci, last);
@@ -6046,7 +6046,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+{
+ struct td *td = dl_reverse_done_list (ohci);
+
-+ while (td) {
++ while (td) {
+ struct td *td_next = td->next_dl_td;
+ struct urb *urb = td->urb;
+ urb_priv_t *urb_priv = urb->hcpriv;
@@ -6058,11 +6058,11 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+
+ /* update URB's length and status from TD */
-+ td_done (ohci, urb, td);
-+ urb_priv->td_cnt++;
++ td_done (ohci, urb, td);
++ urb_priv->td_cnt++;
+
+ /* If all this urb's TDs are done, just resubmit it */
-+ if (urb_priv->td_cnt == urb_priv->length) {
++ if (urb_priv->td_cnt == urb_priv->length) {
+ urb->actual_length = 0;
+ urb->status = -EINPROGRESS;
+ td_submit_urb (ohci, urb);
@@ -6077,7 +6077,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ } else if ((ed->hwINFO & cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE))
+ == cpu_to_hc32 (ohci, ED_SKIP)) {
+ td = list_entry (ed->td_list.next, struct td, td_list);
-+ if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) {
++ if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) {
+ ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP);
+ /* ... hc may need waking-up */
+ switch (ed->type) {
@@ -6093,8 +6093,8 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ }
+
-+ td = td_next;
-+ }
++ td = td_next;
++ }
+}
+
+#endif /* CONFIG_KDB_USB */
@@ -6978,7 +6978,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+} disassemble_info;
+
-+
++
+/* Standard disassemblers. Disassemble one instruction at the given
+ target address. Return number of octets processed. */
+typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
@@ -7073,7 +7073,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+/* Document any target specific options available from the disassembler. */
+extern void disassembler_usage (FILE *);
+
-+
++
+/* This block of definitions is for particular callers who read instructions
+ into a buffer before calling the instruction decoder. */
+
@@ -12289,8 +12289,8 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ while(next && counter < iter_threshold) {
+ counter++;
+ if (counter > iter_threshold) {
-+ kdb_printf("\nWARNING: Iteration threshold reached.\n");
-+ kdb_printf("Current threshold: %lld\n", iter_threshold);
++ kdb_printf("\nWARNING: Iteration threshold reached.\n");
++ kdb_printf("Current threshold: %lld\n", iter_threshold);
+ break;
+ }
+ if(flags & C_LISTHEAD) {
@@ -12642,24 +12642,24 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+kdb_pxhelp(int argc, const char **argv)
+{
+ if (have_debug_file) {
-+ kdb_printf ("Some examples of using the px command:\n");
-+ kdb_printf (" the whole structure:\n");
-+ kdb_printf (" px *(task_struct *)0xe0000...\n");
-+ kdb_printf (" one member:\n");
-+ kdb_printf (" px (*(task_struct *)0xe0000...)->comm\n");
-+ kdb_printf (" the address of a member\n");
-+ kdb_printf (" px &((task_struct *)0xe0000...)->children\n");
-+ kdb_printf (" a structure pointed to by a member:\n");
-+ kdb_printf (" px ((*(class_device *)0xe0000...)->class)->name\n");
-+ kdb_printf (" array element:\n");
-+ kdb_printf (" px (cache_sizes *)0xa0000...[0]\n");
-+ kdb_printf (" px (task_struct *)(0xe0000...)->cpus_allowed.bits[0]\n");
++ kdb_printf ("Some examples of using the px command:\n");
++ kdb_printf (" the whole structure:\n");
++ kdb_printf (" px *(task_struct *)0xe0000...\n");
++ kdb_printf (" one member:\n");
++ kdb_printf (" px (*(task_struct *)0xe0000...)->comm\n");
++ kdb_printf (" the address of a member\n");
++ kdb_printf (" px &((task_struct *)0xe0000...)->children\n");
++ kdb_printf (" a structure pointed to by a member:\n");
++ kdb_printf (" px ((*(class_device *)0xe0000...)->class)->name\n");
++ kdb_printf (" array element:\n");
++ kdb_printf (" px (cache_sizes *)0xa0000...[0]\n");
++ kdb_printf (" px (task_struct *)(0xe0000...)->cpus_allowed.bits[0]\n");
+ } else {
-+ kdb_printf ("There is no debug info file.\n");
-+ kdb_printf ("The px/pd/print commands can only evaluate ");
-+ kdb_printf ("arithmetic expressions.\n");
++ kdb_printf ("There is no debug info file.\n");
++ kdb_printf ("The px/pd/print commands can only evaluate ");
++ kdb_printf ("arithmetic expressions.\n");
+ }
-+ return 0;
++ return 0;
+}
+
+/*
@@ -12672,23 +12672,23 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ kdb_printf("no debuginfo file\n");
+ return 0;
+ }
-+ kdb_printf ("Using the walk command:\n");
-+ kdb_printf (" (only the -s (symbolic) form is supported, so -s is ignored)\n");
-+ kdb_printf ("\n");
-+ kdb_printf (" If the list is not linked with list_head structures:\n");
-+ kdb_printf (" walk [-s] struct name-of-forward-pointer address\n");
-+ kdb_printf (" example: walk xyz_struct next 0xe00....\n");
-+ kdb_printf ("\n");
-+ kdb_printf (" If the list is linked with list_head structures, use -hn\n");
-+ kdb_printf (" to walk the 'next' list, -hp for the 'prev' list\n");
-+ kdb_printf (" walk -h[n|p] struct name-of-forward-pointer [member-to-show] address-of-list-head\n");
-+ kdb_printf (" example, to show the entire task_struct:\n");
-+ kdb_printf (" walk -hn task_struct tasks 0xe000....\n");
-+ kdb_printf (" example, to show the task_struct member comm:\n");
-+ kdb_printf (" walk -hn task_struct tasks comm 0xe000....\n");
-+ kdb_printf (" (address is not the address of first member's list_head, ");
-+ kdb_printf ("but of the anchoring list_head\n");
-+ return 0;
++ kdb_printf ("Using the walk command:\n");
++ kdb_printf (" (only the -s (symbolic) form is supported, so -s is ignored)\n");
++ kdb_printf ("\n");
++ kdb_printf (" If the list is not linked with list_head structures:\n");
++ kdb_printf (" walk [-s] struct name-of-forward-pointer address\n");
++ kdb_printf (" example: walk xyz_struct next 0xe00....\n");
++ kdb_printf ("\n");
++ kdb_printf (" If the list is linked with list_head structures, use -hn\n");
++ kdb_printf (" to walk the 'next' list, -hp for the 'prev' list\n");
++ kdb_printf (" walk -h[n|p] struct name-of-forward-pointer [member-to-show] address-of-list-head\n");
++ kdb_printf (" example, to show the entire task_struct:\n");
++ kdb_printf (" walk -hn task_struct tasks 0xe000....\n");
++ kdb_printf (" example, to show the task_struct member comm:\n");
++ kdb_printf (" walk -hn task_struct tasks comm 0xe000....\n");
++ kdb_printf (" (address is not the address of first member's list_head, ");
++ kdb_printf ("but of the anchoring list_head\n");
++ return 0;
+}
+
+/*
@@ -14688,7 +14688,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+ /* mask bit size bits */
+ mask = (((uint64_t)1 << y) - 1);
-+ return (value & mask);
++ return (value & mask);
+}
+
+/*
@@ -16549,7 +16549,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ char str[16];
+
+ /* Step over the back slash
-+ */
++ */
+ cp++;
+ while (*cp != '\'') {
+ str[i++] = *cp++;
@@ -16819,7 +16819,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+
+ /* The next token should be a CAST or an open paren.
-+ * If it's something else, then return an error.
++ * If it's something else, then return an error.
+ */
+ if (curnp->operator == OPEN_PAREN) {
+ free_nodes(curnp);
@@ -22349,7 +22349,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ c = '\n';
+ while (start != end) {
+ char buf[201];
-+ p = buf;
++ p = buf;
+ while (start < end && (c = *KDB_WRAP(start)) && (p - buf) < sizeof(buf)-1) {
+ ++start;
+ *p++ = c;
@@ -23797,7 +23797,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ }
+ }
-+ if (prev_len > prefix_len)
++ if (prev_len > prefix_len)
+ memcpy(prefix_name, ks_namebuf_prev, prev_len+1);
+ return number;
+}
@@ -27495,7 +27495,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ switch(d->type) {
+ case KDB_SYS_DESC_TYPE_LDT:
+ kdb_printf("base=");
-+ kdb_symbol_print(kdb_seg_desc_base((kdb_desc_t *)d), NULL,
++ kdb_symbol_print(kdb_seg_desc_base((kdb_desc_t *)d), NULL,
+ KDB_SP_DEFAULT);
+ kdb_printf(" limit=" kdb_machreg_fmt " dpl=%d\n",
+ KDB_SEG_DESC_LIMIT((kdb_desc_t *)d), d->dpl);
@@ -27509,7 +27509,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ (struct tss_struct *)
+ kdb_seg_desc_base((kdb_desc_t *)d);
+ kdb_printf("base=");
-+ kdb_symbol_print((unsigned long)tss, NULL, KDB_SP_DEFAULT);
++ kdb_symbol_print((unsigned long)tss, NULL, KDB_SP_DEFAULT);
+ kdb_printf(" limit=" kdb_machreg_fmt " dpl=%d\n",
+ KDB_SEG_DESC_LIMIT((kdb_desc_t *)d), d->dpl);
+ display_tss(tss);
@@ -27517,13 +27517,13 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ case KDB_SYS_DESC_TYPE_CALLG16:
+ kdb_printf("segment=0x%4.4x off=", d->segment);
-+ kdb_symbol_print(KDB_SYS_DESC_OFFSET(d), NULL, KDB_SP_DEFAULT);
++ kdb_symbol_print(KDB_SYS_DESC_OFFSET(d), NULL, KDB_SP_DEFAULT);
+ kdb_printf(" dpl=%d wc=%d\n",
+ d->dpl, KDB_SYS_DESC_CALLG_COUNT(d));
+ break;
+ case KDB_SYS_DESC_TYPE_CALLG:
+ kdb_printf("segment=0x%4.4x off=", d->segment);
-+ kdb_symbol_print(KDB_SYS_DESC_OFFSET(d), NULL, KDB_SP_DEFAULT);
++ kdb_symbol_print(KDB_SYS_DESC_OFFSET(d), NULL, KDB_SP_DEFAULT);
+ kdb_printf(" dpl=%d\n", d->dpl);
+ break;
+ default:
diff --git a/patches.suse/kdb-ia64 b/patches.suse/kdb-ia64
index 74afb6f03b..0fc1268d70 100644
--- a/patches.suse/kdb-ia64
+++ b/patches.suse/kdb-ia64
@@ -734,7 +734,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+typedef int (*bfd_qsort_closure_func) (const void *, const void *, const void *);
+extern void bfd_qsort (void *base, bfd_size_type nmemb, bfd_size_type size,
+ bfd_qsort_closure_func cmp, void *closure);
-+
++
+/* File formats. */
+
+typedef enum bfd_format
@@ -810,7 +810,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+/* This BFD has been created by the linker and doesn't correspond
+ to any input file. */
+#define BFD_LINKER_CREATED 0x2000
-+
++
+/* Symbols and relocation. */
+
+/* A count of carsyms (canonical archive symbols). */
@@ -855,7 +855,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ } u; /* bfd* or file position. */
+ int namidx; /* Index into string table. */
+};
-+
++
+/* Linenumber stuff. */
+typedef struct lineno_cache_entry
+{
@@ -867,7 +867,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ } u;
+}
+alent;
-+
++
+/* Object and core file sections. */
+
+#define align_power(addr, align) \
@@ -899,7 +899,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ / bfd_octets_per_byte (bfd))
+
+typedef struct stat stat_type;
-+
++
+typedef enum bfd_print_symbol
+{
+ bfd_print_symbol_name,
@@ -923,7 +923,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+/* Get the name of a stabs type code. */
+
+extern const char *bfd_get_stab_name (int);
-+
++
+/* Hash table routines. There is no way to free up a hash table. */
+
+/* An element in the hash table. Most uses will actually use a larger
@@ -1134,7 +1134,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+extern bfd_boolean bfd_section_already_linked_table_init (void);
+extern void bfd_section_already_linked_table_free (void);
-+
++
+/* Externally visible ECOFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
@@ -16271,7 +16271,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+ Note that each completer needs to be applied in turn, so that if we
+ have the instruction
-+ cmp.lt.unc
++ cmp.lt.unc
+ the completer entries for both "lt" and "unc" would need to be applied
+ to the opcode's value.
+
@@ -16766,7 +16766,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ *ptr += l;
+ }
+}
-+
++
+/* Find the index of the entry in the string table corresponding to
+ STR; return -1 if one does not exist. */
+
@@ -16800,7 +16800,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ return -1;
+}
-+
++
+/* Find the opcode in the main opcode table whose name is STRINGINDEX, or
+ return -1 if one does not exist. */
+
@@ -16838,7 +16838,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ return -1;
+}
-+
++
+/* Find the index of the entry in the completer table that is part of
+ MAIN_ENT (starting from PREV_COMPLETER) that matches NAME, or
+ return -1 if one does not exist. */
@@ -16872,7 +16872,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ return -1;
+}
-+
++
+/* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
+ return the result. */
+
@@ -16888,7 +16888,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ opcode = (opcode & ~mask) | bits;
+ return opcode;
+}
-+
++
+/* Extract BITS number of bits starting from OP_POINTER + BITOFFSET in
+ the dis_table array, and return its value. (BITOFFSET is numbered
+ starting from MSB to LSB, so a BITOFFSET of 0 indicates the MSB of the
@@ -16925,7 +16925,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ return res;
+}
-+
++
+/* Examine the state machine entry at OP_POINTER in the dis_table
+ array, and extract its values into OPVAL and OP. The length of the
+ state entry in bits is returned. */
@@ -16981,7 +16981,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ return oplen;
+}
-+
++
+/* Returns a non-zero value if the opcode in the main_table list at
+ PLACE matches OPCODE and is of type TYPE. */
+
@@ -17022,7 +17022,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ return 1;
+}
-+
++
+/* Find an instruction entry in the ia64_dis_names array that matches
+ opcode OPCODE and is of type TYPE. Returns either a positive index
+ into the array, or a negative value if an entry for OPCODE could
@@ -17205,7 +17205,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ }
+}
-+
++
+/* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
+
+static struct ia64_opcode *
@@ -17228,7 +17228,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ res->dependencies = &op_dependencies[depind];
+ return res;
+}
-+
++
+/* Determine the ia64_opcode entry for the opcode specified by INSN
+ and TYPE. If a valid entry is not found, return NULL. */
+struct ia64_opcode *
@@ -17286,7 +17286,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ completer_table[ci].dependencies);
+ }
+}
-+
++
+/* Search the main_opcode table starting from PLACE for an opcode that
+ matches NAME. Return NULL if one is not found. */
+
@@ -17344,7 +17344,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ return NULL;
+}
-+
++
+/* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
+ if one does not exist.
+
@@ -18341,7 +18341,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+{
+ kdb_printf("\n is enabled");
+ if (bp->bp_hardtype) {
-+ /* Note that bp->bp_hard[NR_CPU] is for x86.
++ /* Note that bp->bp_hard[NR_CPU] is for x86.
+ * The ia64 uses bp->bp_hard[0] only.
+ */
+ kdba_printbpreg(bp->bp_hard[0]);
@@ -18544,7 +18544,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+void
+kdba_alloc_hwbp(kdb_bp_t *bp, int *diagp)
+{
-+ /* Note that bp->bp_hard[NR_CPU] is for x86.
++ /* Note that bp->bp_hard[NR_CPU] is for x86.
+ * The ia64 uses bp->bp_hard[0] only.
+ */
+ bp->bp_hard[0] = kdba_allocbp(&bp->bp_template, diagp);
@@ -19336,7 +19336,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ /* The assembler may generate offset pointing to either slot 1
+ or slot 2 for a long (2-slot) instruction, occupying slots 1
+ and 2. */
-+ insn_addr &= -16UL;
++ insn_addr &= -16UL;
+ ia64_patch(insn_addr + 2,
+ 0x01fffefe000UL, ( ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
+ | ((val & 0x0000000000200000UL) << 0) /* bit 21 -> 21 */
@@ -19352,7 +19352,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ /* The assembler may generate offset pointing to either slot 1
+ or slot 2 for a long (2-slot) instruction, occupying slots 1
+ and 2. */
-+ insn_addr &= -16UL;
++ insn_addr &= -16UL;
+ ia64_patch(insn_addr + 2,
+ 0x011ffffe000UL, ( ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
+ | ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */));
@@ -20421,48 +20421,48 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ jmp_buf!
+
+
-+ offset: description:
++ offset: description:
+ ------- ------------
-+ 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS)
-+ 0x008 r1 (gp)
++ 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS)
++ 0x008 r1 (gp)
+ 0x010 caller's unat
+ 0x018 fpsr
-+ 0x020 r4
-+ 0x028 r5
-+ 0x030 r6
-+ 0x038 r7
-+ 0x040 rp (b0)
-+ 0x048 b1
-+ 0x050 b2
-+ 0x058 b3
-+ 0x060 b4
-+ 0x068 b5
-+ 0x070 ar.pfs
-+ 0x078 ar.lc
-+ 0x080 pr
-+ 0x088 ar.bsp ; unchangeable (see __longjmp.S)
-+ 0x090 ar.unat
++ 0x020 r4
++ 0x028 r5
++ 0x030 r6
++ 0x038 r7
++ 0x040 rp (b0)
++ 0x048 b1
++ 0x050 b2
++ 0x058 b3
++ 0x060 b4
++ 0x068 b5
++ 0x070 ar.pfs
++ 0x078 ar.lc
++ 0x080 pr
++ 0x088 ar.bsp ; unchangeable (see __longjmp.S)
++ 0x090 ar.unat
+ 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat)
+ 0x0a0 f2
+ 0x0b0 f3
+ 0x0c0 f4
+ 0x0d0 f5
+ 0x0e0 f16
-+ 0x0f0 f17
-+ 0x100 f18
-+ 0x110 f19
-+ 0x120 f20
-+ 0x130 f21
-+ 0x130 f22
-+ 0x140 f23
-+ 0x150 f24
-+ 0x160 f25
-+ 0x170 f26
-+ 0x180 f27
-+ 0x190 f28
-+ 0x1a0 f29
-+ 0x1b0 f30
-+ 0x1c0 f31 */
++ 0x0f0 f17
++ 0x100 f18
++ 0x110 f19
++ 0x120 f20
++ 0x130 f21
++ 0x130 f22
++ 0x140 f23
++ 0x150 f24
++ 0x160 f25
++ 0x170 f26
++ 0x180 f27
++ 0x190 f28
++ 0x1a0 f29
++ 0x1b0 f30
++ 0x1c0 f31 */
+
+#ifndef __KERNEL__
+
diff --git a/patches.suse/kdb-x86 b/patches.suse/kdb-x86
index f56e896767..059b81b6a2 100644
--- a/patches.suse/kdb-x86
+++ b/patches.suse/kdb-x86
@@ -1124,7 +1124,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
-+
++
+/* File formats. */
+
+typedef enum bfd_format
@@ -1200,7 +1200,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+/* This BFD has been created by the linker and doesn't correspond
+ to any input file. */
+#define BFD_LINKER_CREATED 0x2000
-+
++
+/* Symbols and relocation. */
+
+/* A count of carsyms (canonical archive symbols). */
@@ -1245,7 +1245,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ } u; /* bfd* or file position. */
+ int namidx; /* Index into string table. */
+};
-+
++
+/* Linenumber stuff. */
+typedef struct lineno_cache_entry
+{
@@ -1257,7 +1257,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ } u;
+}
+alent;
-+
++
+/* Object and core file sections. */
+
+#define align_power(addr, align) \
@@ -1289,7 +1289,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ / bfd_octets_per_byte (bfd))
+
+typedef struct stat stat_type;
-+
++
+typedef enum bfd_print_symbol
+{
+ bfd_print_symbol_name,
@@ -1313,7 +1313,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+/* Get the name of a stabs type code. */
+
+extern const char *bfd_get_stab_name (int);
-+
++
+/* Hash table routines. There is no way to free up a hash table. */
+
+/* An element in the hash table. Most uses will actually use a larger
@@ -1524,7 +1524,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+extern bfd_boolean bfd_section_already_linked_table_init (void);
+extern void bfd_section_already_linked_table_free (void);
-+
++
+/* Externally visible ECOFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
@@ -6044,7 +6044,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
-+
++
+/* File formats. */
+
+typedef enum bfd_format
@@ -6120,7 +6120,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+/* This BFD has been created by the linker and doesn't correspond
+ to any input file. */
+#define BFD_LINKER_CREATED 0x2000
-+
++
+/* Symbols and relocation. */
+
+/* A count of carsyms (canonical archive symbols). */
@@ -6165,7 +6165,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ } u; /* bfd* or file position. */
+ int namidx; /* Index into string table. */
+};
-+
++
+/* Linenumber stuff. */
+typedef struct lineno_cache_entry
+{
@@ -6177,7 +6177,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ } u;
+}
+alent;
-+
++
+/* Object and core file sections. */
+
+#define align_power(addr, align) \
@@ -6209,7 +6209,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ / bfd_octets_per_byte (bfd))
+
+typedef struct stat stat_type;
-+
++
+typedef enum bfd_print_symbol
+{
+ bfd_print_symbol_name,
@@ -6233,7 +6233,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+/* Get the name of a stabs type code. */
+
+extern const char *bfd_get_stab_name (int);
-+
++
+/* Hash table routines. There is no way to free up a hash table. */
+
+/* An element in the hash table. Most uses will actually use a larger
@@ -6444,7 +6444,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+extern bfd_boolean bfd_section_already_linked_table_init (void);
+extern void bfd_section_already_linked_table_free (void);
-+
++
+/* Externally visible ECOFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
@@ -19332,7 +19332,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
+ }
+ kdbnearsym(rip, &symtab);
+ if (old_style) {
-+ if (__kernel_text_address(rip) && !suppress) {
++ if (__kernel_text_address(rip) && !suppress) {
+ bt_print_one(rip, rsp, &ar, &symtab, 0);
+ ++count;
+ }
diff --git a/patches.suse/ocfs2-allocation-resrvations.patch b/patches.suse/ocfs2-allocation-resrvations.patch
index 15828853da..0db41fba3f 100644
--- a/patches.suse/ocfs2-allocation-resrvations.patch
+++ b/patches.suse/ocfs2-allocation-resrvations.patch
@@ -902,7 +902,7 @@ index 0000000..10d13de
+ *
+ * Re-initialize the parameters of a reservation bitmap. This is
+ * useful for local alloc window slides.
-+ *
++ *
+ * If any bitmap parameters have changed, this function will call
+ * ocfs2_trunc_resv against all existing reservations. A future
+ * version will recalculate existing reservations based on the new
diff --git a/patches.suse/perfmon2.patch b/patches.suse/perfmon2.patch
index b3bfad5357..43c671fbc7 100644
--- a/patches.suse/perfmon2.patch
+++ b/patches.suse/perfmon2.patch
@@ -88,10 +88,8 @@ Signed-off-by: Tony Jones <tonyj@suse.de>
perfmon/perfmon_sysfs.c | 525 ++
77 files changed, 15154 insertions(+), 8194 deletions(-)
-Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon
++++ b/Documentation/ABI/testing/sysfs-perfmon
@@ -0,0 +1,87 @@
+What: /sys/kernel/perfmon
+Date: Oct 2008
@@ -99,7 +97,7 @@ Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon
+Contact: eranian@gmail.com
+
+Description: provide the configuration interface for the perfmon subsystems.
-+ The tree contains information about the detected hardware,
++ The tree contains information about the detected hardware,
+ current state of the subsystem as well as some configuration
+ parameters.
+
@@ -114,14 +112,14 @@ Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon
+ /sys/kernel/perfmon/pmc_max_fast_arg (read-only):
+
+ Number of perfmon syscall arguments copied directly onto the
-+ stack (copy_from_user) for pfm_write_pmcs(). Copying to the
++ stack (copy_from_user) for pfm_write_pmcs(). Copying to the
+ stack avoids having to allocate a buffer. The unit is the
+ number of pfarg_pmc_t structures.
+
+ /sys/kernel/perfmon/pmd_max_fast_arg (read-only):
+
+ Number of perfmon syscall arguments copied directly onto the
-+ stack (copy_from_user) for pfm_write_pmds()/pfm_read_pmds().
++ stack (copy_from_user) for pfm_write_pmds()/pfm_read_pmds().
+ Copying to the stack avoids having to allocate a buffer. The
+ unit is the number of pfarg_pmd_t structures.
+
@@ -133,18 +131,18 @@ Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon
+ /sys/kernel/perfmon/smpl_buffer_mem_cur (read-only):
+
+ Reports the amount of memory currently dedicated to sampling
-+ buffers by the kernel. The unit is byte.
++ buffers by the kernel. The unit is byte.
+
-+ /sys/kernel/perfmon/smpl_buffer_mem_max (read-write):
++ /sys/kernel/perfmon/smpl_buffer_mem_max (read-write):
+
+ Maximum amount of kernel memory usable for sampling buffers.
+ -1 means everything that is available. Unit is byte.
+
-+ /sys/kernel/perfmon/smpl_buffer_mem_cur (read-only):
++ /sys/kernel/perfmon/smpl_buffer_mem_cur (read-only):
+
+ Current utilization of kernel memory in bytes.
+
-+ /sys/kernel/perfmon/sys_group (read-write):
++ /sys/kernel/perfmon/sys_group (read-write):
+
+ Users group allowed to create a system-wide perfmon context
+ (session). -1 means any group.
@@ -152,7 +150,7 @@ Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon
+ /sys/kernel/perfmon/task_group (read-write):
+
+ Users group allowed to create a per-thread context (session).
-+ -1 means any group.
++ -1 means any group.
+
+ /sys/kernel/perfmon/sys_sessions_count (read-only):
+
@@ -164,7 +162,7 @@ Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon
+ Number of per-thread contexts (sessions) currently attached
+ to threads.
+
-+ /sys/kernel/perfmon/version (read-only):
++ /sys/kernel/perfmon/version (read-only):
+
+ Perfmon interface revision number.
+
@@ -180,10 +178,8 @@ Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon
+ Currently defined:
+ - bit 0: if set, then reserved bitfield are ignored on PMC writes
+
-Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon-fmt
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon-fmt
++++ b/Documentation/ABI/testing/sysfs-perfmon-fmt
@@ -0,0 +1,18 @@
+What: /sys/kernel/perfmon/formats
+Date: 2007
@@ -203,10 +199,8 @@ Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon-fmt
+
+ Version number of the format in clear text and null terminated.
+
-Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon-pmu
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon-pmu
++++ b/Documentation/ABI/testing/sysfs-perfmon-pmu
@@ -0,0 +1,48 @@
+What: /sys/kernel/perfmon/pmu
+Date: Nov 2007
@@ -256,11 +250,9 @@ Index: linux-2.6.31-master/Documentation/ABI/testing/sysfs-perfmon-pmu
+
+ The width in bits of the registers. This field is only
+ relevant for counter registers.
-Index: linux-2.6.31-master/Documentation/kernel-parameters.txt
-===================================================================
---- linux-2.6.31-master.orig/Documentation/kernel-parameters.txt
-+++ linux-2.6.31-master/Documentation/kernel-parameters.txt
-@@ -1998,6 +1998,9 @@ and is between 256 and 4096 characters.
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1998,6 +1998,9 @@ and is between 256 and 4096 characters.
allocator. This parameter is primarily for debugging
and performance comparison.
@@ -270,10 +262,8 @@ Index: linux-2.6.31-master/Documentation/kernel-parameters.txt
pf. [PARIDE]
See Documentation/blockdev/paride.txt.
-Index: linux-2.6.31-master/Documentation/perfmon2-debugfs.txt
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/Documentation/perfmon2-debugfs.txt
++++ b/Documentation/perfmon2-debugfs.txt
@@ -0,0 +1,126 @@
+ The perfmon2 debug and statistics interface
+ ------------------------------------------
@@ -401,10 +391,8 @@ Index: linux-2.6.31-master/Documentation/perfmon2-debugfs.txt
+ handles asynchronous perfmon2 work for per-thread contexts
+ (sessions).
+
-Index: linux-2.6.31-master/Documentation/perfmon2.txt
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/Documentation/perfmon2.txt
++++ b/Documentation/perfmon2.txt
@@ -0,0 +1,221 @@
+ The perfmon hardware monitoring interface
+ ------------------------------------------
@@ -627,10 +615,8 @@ Index: linux-2.6.31-master/Documentation/perfmon2.txt
+IX/ Documentation
+
+ Visit http://perfmon2.sf.net
-Index: linux-2.6.31-master/MAINTAINERS
-===================================================================
---- linux-2.6.31-master.orig/MAINTAINERS
-+++ linux-2.6.31-master/MAINTAINERS
+--- a/MAINTAINERS
++++ b/MAINTAINERS
@@ -4094,6 +4094,14 @@ F: arch/*/lib/perf_event.c
F: arch/*/kernel/perf_callchain.c
F: tools/perf/
@@ -646,10 +632,8 @@ Index: linux-2.6.31-master/MAINTAINERS
PERSONALITY HANDLING
M: Christoph Hellwig <hch@infradead.org>
L: linux-abi-devel@lists.sourceforge.net
-Index: linux-2.6.31-master/Makefile
-===================================================================
---- linux-2.6.31-master.orig/Makefile
-+++ linux-2.6.31-master/Makefile
+--- a/Makefile
++++ b/Makefile
@@ -672,6 +672,7 @@ export mod_strip_cmd
ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
@@ -658,10 +642,8 @@ Index: linux-2.6.31-master/Makefile
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
-Index: linux-2.6.31-master/arch/ia64/Kconfig
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/Kconfig
-+++ linux-2.6.31-master/arch/ia64/Kconfig
+--- a/arch/ia64/Kconfig
++++ b/arch/ia64/Kconfig
@@ -531,14 +531,6 @@ config IA64_CPE_MIGRATE
build this functionality as a kernel loadable module. Installing
the module will turn on the functionality.
@@ -686,10 +668,8 @@ Index: linux-2.6.31-master/arch/ia64/Kconfig
endmenu
menu "Power management and ACPI options"
-Index: linux-2.6.31-master/arch/ia64/Makefile
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/Makefile
-+++ linux-2.6.31-master/arch/ia64/Makefile
+--- a/arch/ia64/Makefile
++++ b/arch/ia64/Makefile
@@ -54,6 +54,7 @@ core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/
core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
core-$(CONFIG_IA64_XEN_GUEST) += arch/ia64/dig/
@@ -698,10 +678,8 @@ Index: linux-2.6.31-master/arch/ia64/Makefile
core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/
core-$(CONFIG_KVM) += arch/ia64/kvm/
core-$(CONFIG_XEN) += arch/ia64/xen/
-Index: linux-2.6.31-master/arch/ia64/configs/generic_defconfig
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/configs/generic_defconfig
-+++ linux-2.6.31-master/arch/ia64/configs/generic_defconfig
+--- a/arch/ia64/configs/generic_defconfig
++++ b/arch/ia64/configs/generic_defconfig
@@ -209,7 +209,6 @@ CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
@@ -728,10 +706,8 @@ Index: linux-2.6.31-master/arch/ia64/configs/generic_defconfig
# Power management and ACPI options
#
CONFIG_PM=y
-Index: linux-2.6.31-master/arch/ia64/include/asm/Kbuild
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/include/asm/Kbuild
-+++ linux-2.6.31-master/arch/ia64/include/asm/Kbuild
+--- a/arch/ia64/include/asm/Kbuild
++++ b/arch/ia64/include/asm/Kbuild
@@ -4,10 +4,12 @@ header-y += break.h
header-y += fpu.h
header-y += ia64regs.h
@@ -746,10 +722,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/Kbuild
unifdef-y += gcc_intrin.h
unifdef-y += intrinsics.h
-Index: linux-2.6.31-master/arch/ia64/include/asm/hw_irq.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/include/asm/hw_irq.h
-+++ linux-2.6.31-master/arch/ia64/include/asm/hw_irq.h
+--- a/arch/ia64/include/asm/hw_irq.h
++++ b/arch/ia64/include/asm/hw_irq.h
@@ -67,9 +67,9 @@ extern int ia64_last_device_vector;
#define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
@@ -761,10 +735,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/hw_irq.h
#define IA64_IPI_LOCAL_TLB_FLUSH 0xfc /* SMP flush local TLB */
#define IA64_IPI_RESCHEDULE 0xfd /* SMP reschedule */
#define IA64_IPI_VECTOR 0xfe /* inter-processor interrupt vector */
-Index: linux-2.6.31-master/arch/ia64/include/asm/perfmon.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/include/asm/perfmon.h
-+++ linux-2.6.31-master/arch/ia64/include/asm/perfmon.h
+--- a/arch/ia64/include/asm/perfmon.h
++++ b/arch/ia64/include/asm/perfmon.h
@@ -1,279 +1,59 @@
/*
- * Copyright (C) 2001-2003 Hewlett-Packard Co
@@ -1086,10 +1058,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/perfmon.h
-#endif /* _ASM_IA64_PERFMON_H */
+#endif /* _ASM_IA64_PERFMON_H_ */
-Index: linux-2.6.31-master/arch/ia64/include/asm/perfmon_compat.h
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/include/asm/perfmon_compat.h
++++ b/arch/ia64/include/asm/perfmon_compat.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2001-2006 Hewlett-Packard Development Company, L.P.
@@ -1258,10 +1228,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/perfmon_compat.h
+#define PFM_REG_HAS_ERROR(flag) (((flag) & PFM_REG_RETFL_MASK) != 0)
+
+#endif /* _ASM_IA64_PERFMON_COMPAT_H_ */
-Index: linux-2.6.31-master/arch/ia64/include/asm/perfmon_default_smpl.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/include/asm/perfmon_default_smpl.h
-+++ linux-2.6.31-master/arch/ia64/include/asm/perfmon_default_smpl.h
+--- a/arch/ia64/include/asm/perfmon_default_smpl.h
++++ b/arch/ia64/include/asm/perfmon_default_smpl.h
@@ -1,83 +1,106 @@
/*
- * Copyright (C) 2002-2003 Hewlett-Packard Co
@@ -1418,10 +1386,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/perfmon_default_smpl.h
-#endif /* __PERFMON_DEFAULT_SMPL_H__ */
+#endif /* __ASM_IA64_PERFMON_DEFAULT_SMPL_H__ */
-Index: linux-2.6.31-master/arch/ia64/include/asm/perfmon_kern.h
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/include/asm/perfmon_kern.h
++++ b/arch/ia64/include/asm/perfmon_kern.h
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2001-2007 Hewlett-Packard Development Company, L.P.
@@ -1777,10 +1743,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/perfmon_kern.h
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_IA64_PERFMON_KERN_H_ */
-Index: linux-2.6.31-master/arch/ia64/include/asm/processor.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/include/asm/processor.h
-+++ linux-2.6.31-master/arch/ia64/include/asm/processor.h
+--- a/arch/ia64/include/asm/processor.h
++++ b/arch/ia64/include/asm/processor.h
@@ -42,7 +42,6 @@
#define IA64_THREAD_FPH_VALID (__IA64_UL(1) << 0) /* floating-point high state valid? */
@@ -1812,10 +1776,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/processor.h
.dbr = {0, }, \
.ibr = {0, }, \
.fph = {{{{0}}}, } \
-Index: linux-2.6.31-master/arch/ia64/include/asm/system.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/include/asm/system.h
-+++ linux-2.6.31-master/arch/ia64/include/asm/system.h
+--- a/arch/ia64/include/asm/system.h
++++ b/arch/ia64/include/asm/system.h
@@ -217,6 +217,7 @@ struct task_struct;
extern void ia64_save_extra (struct task_struct *task);
extern void ia64_load_extra (struct task_struct *task);
@@ -1855,10 +1817,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/system.h
ia64_psr(task_pt_regs(next))->dfh = !ia64_is_local_fpu_owner(next); \
(last) = ia64_switch_to((next)); \
} while (0)
-Index: linux-2.6.31-master/arch/ia64/include/asm/thread_info.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/include/asm/thread_info.h
-+++ linux-2.6.31-master/arch/ia64/include/asm/thread_info.h
+--- a/arch/ia64/include/asm/thread_info.h
++++ b/arch/ia64/include/asm/thread_info.h
@@ -107,6 +107,8 @@ struct thread_info {
#define TIF_DB_DISABLED 19 /* debug trap disabled for fsyscall */
#define TIF_FREEZE 20 /* is freezing for suspend */
@@ -1877,10 +1837,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/thread_info.h
/* "work to do on user-return" bits */
#define TIF_ALLWORK_MASK (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SYSCALL_AUDIT|\
-Index: linux-2.6.31-master/arch/ia64/include/asm/unistd.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/include/asm/unistd.h
-+++ linux-2.6.31-master/arch/ia64/include/asm/unistd.h
+--- a/arch/ia64/include/asm/unistd.h
++++ b/arch/ia64/include/asm/unistd.h
@@ -311,11 +311,23 @@
#define __NR_preadv 1319
#define __NR_pwritev 1320
@@ -1906,10 +1864,8 @@ Index: linux-2.6.31-master/arch/ia64/include/asm/unistd.h
/*
* The following defines stop scripts/checksyscalls.sh from complaining about
-Index: linux-2.6.31-master/arch/ia64/kernel/Makefile
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/Makefile
-+++ linux-2.6.31-master/arch/ia64/kernel/Makefile
+--- a/arch/ia64/kernel/Makefile
++++ b/arch/ia64/kernel/Makefile
@@ -9,7 +9,7 @@ endif
extra-y := head.o init_task.o vmlinux.lds
@@ -1927,10 +1883,8 @@ Index: linux-2.6.31-master/arch/ia64/kernel/Makefile
obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
-Index: linux-2.6.31-master/arch/ia64/kernel/entry.S
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/entry.S
-+++ linux-2.6.31-master/arch/ia64/kernel/entry.S
+--- a/arch/ia64/kernel/entry.S
++++ b/arch/ia64/kernel/entry.S
@@ -1806,6 +1806,18 @@ sys_call_table:
data8 sys_preadv
data8 sys_pwritev // 1320
@@ -1950,10 +1904,8 @@ Index: linux-2.6.31-master/arch/ia64/kernel/entry.S
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
-Index: linux-2.6.31-master/arch/ia64/kernel/irq_ia64.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/irq_ia64.c
-+++ linux-2.6.31-master/arch/ia64/kernel/irq_ia64.c
+--- a/arch/ia64/kernel/irq_ia64.c
++++ b/arch/ia64/kernel/irq_ia64.c
@@ -40,10 +40,6 @@
#include <asm/system.h>
#include <asm/tlbflush.h>
@@ -1975,9 +1927,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/irq_ia64.c
platform_irq_init();
}
-Index: linux-2.6.31-master/arch/ia64/kernel/perfmon.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/perfmon.c
+--- a/arch/ia64/kernel/perfmon.c
+++ /dev/null
@@ -1,6840 +0,0 @@
-/*
@@ -4280,7 +4230,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/perfmon.c
- * if ((mm->total_vm << PAGE_SHIFT) + len> task->rlim[RLIMIT_AS].rlim_cur)
- * return -ENOMEM;
- */
-- if (size > task->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
+- if (size > task_rlim_get_cur(task, RLIMIT_MEMLOCK))
- return -ENOMEM;
-
- /*
@@ -8820,9 +8770,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/perfmon.c
- return -ENOSYS;
-}
-#endif /* CONFIG_PERFMON */
-Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_default_smpl.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/perfmon_default_smpl.c
+--- a/arch/ia64/kernel/perfmon_default_smpl.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
@@ -9121,9 +9069,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_default_smpl.c
-module_init(pfm_default_smpl_init_module);
-module_exit(pfm_default_smpl_cleanup_module);
-
-Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_generic.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/perfmon_generic.h
+--- a/arch/ia64/kernel/perfmon_generic.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
@@ -9171,9 +9117,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_generic.h
- .pmc_desc = pfm_gen_pmc_desc
-};
-
-Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_itanium.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/perfmon_itanium.h
+--- a/arch/ia64/kernel/perfmon_itanium.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
@@ -9291,9 +9235,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_itanium.h
-};
-
-
-Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_mckinley.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/perfmon_mckinley.h
+--- a/arch/ia64/kernel/perfmon_mckinley.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
@@ -9483,9 +9425,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_mckinley.h
-};
-
-
-Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_montecito.h
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/perfmon_montecito.h
+--- a/arch/ia64/kernel/perfmon_montecito.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
@@ -9757,10 +9697,8 @@ Index: linux-2.6.31-master/arch/ia64/kernel/perfmon_montecito.h
- .num_dbrs = 8,
- .use_rr_dbregs = 1 /* debug register are use for range retrictions */
-};
-Index: linux-2.6.31-master/arch/ia64/kernel/process.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/process.c
-+++ linux-2.6.31-master/arch/ia64/kernel/process.c
+--- a/arch/ia64/kernel/process.c
++++ b/arch/ia64/kernel/process.c
@@ -29,6 +29,7 @@
#include <linux/kdebug.h>
#include <linux/utsname.h>
@@ -9791,7 +9729,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/process.c
void
do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
{
-@@ -181,14 +182,9 @@ do_notify_resume_user(sigset_t *unused,
+@@ -181,14 +182,9 @@ do_notify_resume_user(sigset_t *unused,
return;
}
@@ -9809,7 +9747,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/process.c
/* deal with pending signal delivery */
if (test_thread_flag(TIF_SIGPENDING)) {
-@@ -212,22 +208,15 @@ do_notify_resume_user(sigset_t *unused,
+@@ -212,22 +208,15 @@ do_notify_resume_user(sigset_t *unused,
local_irq_disable(); /* force interrupt disable */
}
@@ -9959,10 +9897,8 @@ Index: linux-2.6.31-master/arch/ia64/kernel/process.c
if (IS_IA32_PROCESS(task_pt_regs(current)))
ia32_drop_ia64_partial_page_list(current);
}
-Index: linux-2.6.31-master/arch/ia64/kernel/ptrace.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/ptrace.c
-+++ linux-2.6.31-master/arch/ia64/kernel/ptrace.c
+--- a/arch/ia64/kernel/ptrace.c
++++ b/arch/ia64/kernel/ptrace.c
@@ -19,6 +19,7 @@
#include <linux/security.h>
#include <linux/audit.h>
@@ -9981,7 +9917,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/ptrace.c
#include "entry.h"
-@@ -2104,7 +2102,6 @@ access_uarea(struct task_struct *child,
+@@ -2104,7 +2102,6 @@ access_uarea(struct task_struct *child,
"address 0x%lx\n", addr);
return -1;
}
@@ -9989,7 +9925,7 @@ Index: linux-2.6.31-master/arch/ia64/kernel/ptrace.c
/*
* Check if debug registers are used by perfmon. This
* test must be done once we know that we can do the
-@@ -2122,9 +2119,8 @@ access_uarea(struct task_struct *child,
+@@ -2122,9 +2119,8 @@ access_uarea(struct task_struct *child,
* IA64_THREAD_DBG_VALID. The registers are restored
* by the PMU context switch code.
*/
@@ -10000,10 +9936,8 @@ Index: linux-2.6.31-master/arch/ia64/kernel/ptrace.c
if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
child->thread.flags |= IA64_THREAD_DBG_VALID;
-Index: linux-2.6.31-master/arch/ia64/kernel/setup.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/setup.c
-+++ linux-2.6.31-master/arch/ia64/kernel/setup.c
+--- a/arch/ia64/kernel/setup.c
++++ b/arch/ia64/kernel/setup.c
@@ -45,6 +45,7 @@
#include <linux/cpufreq.h>
#include <linux/kexec.h>
@@ -10021,10 +9955,8 @@ Index: linux-2.6.31-master/arch/ia64/kernel/setup.c
}
void __init
-Index: linux-2.6.31-master/arch/ia64/kernel/smpboot.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/smpboot.c
-+++ linux-2.6.31-master/arch/ia64/kernel/smpboot.c
+--- a/arch/ia64/kernel/smpboot.c
++++ b/arch/ia64/kernel/smpboot.c
@@ -39,6 +39,7 @@
#include <linux/efi.h>
#include <linux/percpu.h>
@@ -10063,11 +9995,9 @@ Index: linux-2.6.31-master/arch/ia64/kernel/smpboot.c
return 0;
}
-Index: linux-2.6.31-master/arch/ia64/kernel/sys_ia64.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/kernel/sys_ia64.c
-+++ linux-2.6.31-master/arch/ia64/kernel/sys_ia64.c
-@@ -293,3 +293,11 @@ sys_pciconfig_write (unsigned long bus,
+--- a/arch/ia64/kernel/sys_ia64.c
++++ b/arch/ia64/kernel/sys_ia64.c
+@@ -293,3 +293,11 @@ sys_pciconfig_write (unsigned long bus,
}
#endif /* CONFIG_PCI */
@@ -10079,10 +10009,8 @@ Index: linux-2.6.31-master/arch/ia64/kernel/sys_ia64.c
+ return -ENOSYS;
+}
+#endif
-Index: linux-2.6.31-master/arch/ia64/lib/Makefile
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/lib/Makefile
-+++ linux-2.6.31-master/arch/ia64/lib/Makefile
+--- a/arch/ia64/lib/Makefile
++++ b/arch/ia64/lib/Makefile
@@ -13,7 +13,6 @@ lib-y := __divsi3.o __udivsi3.o __modsi3
obj-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
@@ -10091,10 +10019,8 @@ Index: linux-2.6.31-master/arch/ia64/lib/Makefile
AFLAGS___divdi3.o =
AFLAGS___udivdi3.o = -DUNSIGNED
-Index: linux-2.6.31-master/arch/ia64/oprofile/perfmon.c
-===================================================================
---- linux-2.6.31-master.orig/arch/ia64/oprofile/perfmon.c
-+++ linux-2.6.31-master/arch/ia64/oprofile/perfmon.c
+--- a/arch/ia64/oprofile/perfmon.c
++++ b/arch/ia64/oprofile/perfmon.c
@@ -10,25 +10,30 @@
#include <linux/kernel.h>
#include <linux/oprofile.h>
@@ -10117,7 +10043,7 @@ Index: linux-2.6.31-master/arch/ia64/oprofile/perfmon.c
+ struct pt_regs *regs;
+ struct pfm_ovfl_arg *arg;
+
-+ regs = data;
++ regs = data;
+ arg = &ctx->ovfl_arg;
- arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1;
@@ -10174,10 +10100,8 @@ Index: linux-2.6.31-master/arch/ia64/oprofile/perfmon.c
- pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid);
+ pfm_fmt_unregister(&oprofile_fmt);
}
-Index: linux-2.6.31-master/arch/ia64/perfmon/Kconfig
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/Kconfig
++++ b/arch/ia64/perfmon/Kconfig
@@ -0,0 +1,67 @@
+menu "Hardware Performance Monitoring support"
+config PERFMON
@@ -10246,10 +10170,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/Kconfig
+ help
+ Enables support for Itanium 2 9000 (Montecito) PMU.
+endmenu
-Index: linux-2.6.31-master/arch/ia64/perfmon/Makefile
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/Makefile
++++ b/arch/ia64/perfmon/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
@@ -10262,10 +10184,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/Makefile
+obj-$(CONFIG_IA64_PERFMON_ITANIUM) += perfmon_itanium.o
+obj-$(CONFIG_IA64_PERFMON_MCKINLEY) += perfmon_mckinley.o
+obj-$(CONFIG_IA64_PERFMON_MONTECITO) += perfmon_montecito.o
-Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/perfmon.c
++++ b/arch/ia64/perfmon/perfmon.c
@@ -0,0 +1,937 @@
+/*
+ * This file implements the IA-64 specific
@@ -11204,10 +11124,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon.c
+
+ return 0;
+}
-Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_compat.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/perfmon_compat.c
++++ b/arch/ia64/perfmon/perfmon_compat.c
@@ -0,0 +1,1221 @@
+/*
+ * This file implements the IA-64 specific
@@ -12430,10 +12348,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_compat.c
+ perfmon_proc->proc_fops = &pfm_proc_fops;
+ return 0;
+}
-Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_default_smpl.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/perfmon_default_smpl.c
++++ b/arch/ia64/perfmon/perfmon_default_smpl.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2002-2006 Hewlett-Packard Development Company, L.P.
@@ -12708,10 +12624,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_default_smpl.c
+
+module_init(pfm_default_fmt_init_module);
+module_exit(pfm_default_fmt_cleanup_module);
-Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_generic.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/perfmon_generic.c
++++ b/arch/ia64/perfmon/perfmon_generic.c
@@ -0,0 +1,148 @@
+/*
+ * This file contains the generic PMU register description tables
@@ -12861,10 +12775,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_generic.c
+
+module_init(pfm_gen_pmu_init_module);
+module_exit(pfm_gen_pmu_cleanup_module);
-Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_itanium.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/perfmon_itanium.c
++++ b/arch/ia64/perfmon/perfmon_itanium.c
@@ -0,0 +1,232 @@
+/*
+ * This file contains the Itanium PMU register description tables
@@ -13098,10 +13010,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_itanium.c
+module_init(pfm_ita_pmu_init_module);
+module_exit(pfm_ita_pmu_cleanup_module);
+
-Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_mckinley.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/perfmon_mckinley.c
++++ b/arch/ia64/perfmon/perfmon_mckinley.c
@@ -0,0 +1,290 @@
+/*
+ * This file contains the McKinley PMU register description tables
@@ -13393,10 +13303,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_mckinley.c
+
+module_init(pfm_mck_pmu_init_module);
+module_exit(pfm_mck_pmu_cleanup_module);
-Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_montecito.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/arch/ia64/perfmon/perfmon_montecito.c
++++ b/arch/ia64/perfmon/perfmon_montecito.c
@@ -0,0 +1,412 @@
+/*
+ * This file contains the McKinley PMU register description tables
@@ -13810,10 +13718,8 @@ Index: linux-2.6.31-master/arch/ia64/perfmon/perfmon_montecito.c
+
+module_init(pfm_mont_pmu_init_module);
+module_exit(pfm_mont_pmu_cleanup_module);
-Index: linux-2.6.31-master/include/linux/Kbuild
-===================================================================
---- linux-2.6.31-master.orig/include/linux/Kbuild
-+++ linux-2.6.31-master/include/linux/Kbuild
+--- a/include/linux/Kbuild
++++ b/include/linux/Kbuild
@@ -165,6 +165,10 @@ header-y += utime.h
header-y += veth.h
header-y += videotext.h
@@ -13825,10 +13731,8 @@ Index: linux-2.6.31-master/include/linux/Kbuild
unifdef-y += acct.h
unifdef-y += adb.h
-Index: linux-2.6.31-master/include/linux/perfmon.h
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/include/linux/perfmon.h
++++ b/include/linux/perfmon.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2001-2006 Hewlett-Packard Development Company, L.P.
@@ -14043,10 +13947,8 @@ Index: linux-2.6.31-master/include/linux/perfmon.h
+#define PFM_VERSION_MINOR(x) ((x) & 0xffff)
+
+#endif /* __LINUX_PERFMON_H__ */
-Index: linux-2.6.31-master/include/linux/perfmon_dfl_smpl.h
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/include/linux/perfmon_dfl_smpl.h
++++ b/include/linux/perfmon_dfl_smpl.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
@@ -14126,10 +14028,8 @@ Index: linux-2.6.31-master/include/linux/perfmon_dfl_smpl.h
+ (PFM_DFL_SMPL_VERSION_MIN & 0xffff))
+
+#endif /* __PERFMON_DFL_SMPL_H__ */
-Index: linux-2.6.31-master/include/linux/perfmon_fmt.h
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/include/linux/perfmon_fmt.h
++++ b/include/linux/perfmon_fmt.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2001-2006 Hewlett-Packard Development Company, L.P.
@@ -14214,10 +14114,8 @@ Index: linux-2.6.31-master/include/linux/perfmon_fmt.h
+void pfm_sysfs_remove_fmt(struct pfm_smpl_fmt *fmt);
+
+#endif /* __PERFMON_FMT_H__ */
-Index: linux-2.6.31-master/include/linux/perfmon_kern.h
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/include/linux/perfmon_kern.h
++++ b/include/linux/perfmon_kern.h
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2001-2006 Hewlett-Packard Development Company, L.P.
@@ -14762,10 +14660,8 @@ Index: linux-2.6.31-master/include/linux/perfmon_kern.h
+#endif /* CONFIG_PERFMON */
+
+#endif /* __LINUX_PERFMON_KERN_H__ */
-Index: linux-2.6.31-master/include/linux/perfmon_pmu.h
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/include/linux/perfmon_pmu.h
++++ b/include/linux/perfmon_pmu.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
@@ -14960,10 +14856,8 @@ Index: linux-2.6.31-master/include/linux/perfmon_pmu.h
+int pfm_sysfs_add_pmu(struct pfm_pmu_config *pmu);
+
+#endif /* __PERFMON_PMU_H__ */
-Index: linux-2.6.31-master/include/linux/sched.h
-===================================================================
---- linux-2.6.31-master.orig/include/linux/sched.h
-+++ linux-2.6.31-master/include/linux/sched.h
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
@@ -101,6 +101,7 @@ struct bio;
struct fs_struct;
struct bts_context;
@@ -14982,10 +14876,8 @@ Index: linux-2.6.31-master/include/linux/sched.h
};
/* Future-safe accessor for struct task_struct's cpus_allowed. */
-Index: linux-2.6.31-master/include/linux/syscalls.h
-===================================================================
---- linux-2.6.31-master.orig/include/linux/syscalls.h
-+++ linux-2.6.31-master/include/linux/syscalls.h
+--- a/include/linux/syscalls.h
++++ b/include/linux/syscalls.h
@@ -29,6 +29,13 @@ struct msqid_ds;
struct new_utsname;
struct nfsctl_arg;
@@ -15000,7 +14892,7 @@ Index: linux-2.6.31-master/include/linux/syscalls.h
struct pollfd;
struct rlimit;
struct rusage;
-@@ -875,6 +882,29 @@ asmlinkage long sys_ppoll(struct pollfd
+@@ -879,6 +886,29 @@ asmlinkage long sys_ppoll(struct pollfd
int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
@@ -15030,10 +14922,8 @@ Index: linux-2.6.31-master/include/linux/syscalls.h
asmlinkage long sys_perf_event_open(
struct perf_event_attr __user *attr_uptr,
-Index: linux-2.6.31-master/kernel/sched.c
-===================================================================
---- linux-2.6.31-master.orig/kernel/sched.c
-+++ linux-2.6.31-master/kernel/sched.c
+--- a/kernel/sched.c
++++ b/kernel/sched.c
@@ -71,6 +71,7 @@
#include <linux/debugfs.h>
#include <linux/ctype.h>
@@ -15042,10 +14932,8 @@ Index: linux-2.6.31-master/kernel/sched.c
#include <asm/tlb.h>
#include <asm/irq_regs.h>
-Index: linux-2.6.31-master/kernel/sys_ni.c
-===================================================================
---- linux-2.6.31-master.orig/kernel/sys_ni.c
-+++ linux-2.6.31-master/kernel/sys_ni.c
+--- a/kernel/sys_ni.c
++++ b/kernel/sys_ni.c
@@ -134,6 +134,19 @@ cond_syscall(sys_io_cancel);
cond_syscall(sys_io_getevents);
cond_syscall(sys_syslog);
@@ -15066,10 +14954,8 @@ Index: linux-2.6.31-master/kernel/sys_ni.c
/* arch-specific weak syscall entries */
cond_syscall(sys_pciconfig_read);
cond_syscall(sys_pciconfig_write);
-Index: linux-2.6.31-master/perfmon/Makefile
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/Makefile
++++ b/perfmon/Makefile
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P.
@@ -15083,10 +14969,8 @@ Index: linux-2.6.31-master/perfmon/Makefile
+ perfmon_activate.o perfmon_ctx.o perfmon_fmt.o
+
+obj-$(CONFIG_PERFMON_DEBUG_FS) += perfmon_debugfs.o
-Index: linux-2.6.31-master/perfmon/perfmon_activate.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_activate.c
++++ b/perfmon/perfmon_activate.c
@@ -0,0 +1,276 @@
+/*
+ * perfmon_activate.c: perfmon2 start/stop functions
@@ -15364,10 +15248,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_activate.c
+ */
+ return 0;
+}
-Index: linux-2.6.31-master/perfmon/perfmon_attach.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_attach.c
++++ b/perfmon/perfmon_attach.c
@@ -0,0 +1,487 @@
+/*
+ * perfmon_attach.c: perfmon2 load/unload functions
@@ -15856,10 +15738,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_attach.c
+ if (free_ok)
+ pfm_free_context(ctx);
+}
-Index: linux-2.6.31-master/perfmon/perfmon_ctx.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_ctx.c
++++ b/perfmon/perfmon_ctx.c
@@ -0,0 +1,301 @@
+/*
+ * perfmon_ctx.c: perfmon2 context functions
@@ -16135,8 +16015,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_ctx.c
+error_alloc:
+ /*
+ * free arch, sets, smpl_buffer
-+ * conf, pmu
-+ */
++ * conf, pmu
++ */
+ pfm_free_context(ctx);
+ return ret;
+error_smpl:
@@ -16162,10 +16042,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_ctx.c
+ }
+ return 0;
+}
-Index: linux-2.6.31-master/perfmon/perfmon_ctxsw.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_ctxsw.c
++++ b/perfmon/perfmon_ctxsw.c
@@ -0,0 +1,337 @@
+/*
+ * perfmon_cxtsw.c: perfmon2 context switch code
@@ -16504,10 +16382,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_ctxsw.c
+ pfm_stats_inc(ctxswin_count);
+ pfm_stats_add(ctxswin_ns, sched_clock() - now);
+}
-Index: linux-2.6.31-master/perfmon/perfmon_debugfs.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_debugfs.c
++++ b/perfmon/perfmon_debugfs.c
@@ -0,0 +1,168 @@
+/*
+ * perfmon_debugfs.c: perfmon2 statistics interface to debugfs
@@ -16677,10 +16553,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_debugfs.c
+ }
+ return -1;
+}
-Index: linux-2.6.31-master/perfmon/perfmon_dfl_smpl.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_dfl_smpl.c
++++ b/perfmon/perfmon_dfl_smpl.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 1999-2006 Hewlett-Packard Development Company, L.P.
@@ -16980,10 +16854,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_dfl_smpl.c
+
+module_init(pfm_dfl_fmt_init_module);
+module_exit(pfm_dfl_fmt_cleanup_module);
-Index: linux-2.6.31-master/perfmon/perfmon_file.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_file.c
++++ b/perfmon/perfmon_file.c
@@ -0,0 +1,646 @@
+/*
+ * perfmon_file.c: perfmon2 file input/output functions
@@ -17631,10 +17503,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_file.c
+{
+ return anon_inode_getfd("[pfmfd]", &pfm_file_ops, ctx, O_RDONLY);
+}
-Index: linux-2.6.31-master/perfmon/perfmon_fmt.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_fmt.c
++++ b/perfmon/perfmon_fmt.c
@@ -0,0 +1,219 @@
+/*
+ * perfmon_fmt.c: perfmon2 sampling buffer format management
@@ -17855,10 +17725,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_fmt.c
+ pfm_sysfs_add_fmt(entry);
+ }
+}
-Index: linux-2.6.31-master/perfmon/perfmon_hotplug.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_hotplug.c
++++ b/perfmon/perfmon_hotplug.c
@@ -0,0 +1,158 @@
+/*
+ * perfmon_hotplug.c: handling of CPU hotplug
@@ -18018,10 +17886,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_hotplug.c
+ return ret;
+}
+#endif /* CONFIG_HOTPLUG_CPU */
-Index: linux-2.6.31-master/perfmon/perfmon_init.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_init.c
++++ b/perfmon/perfmon_init.c
@@ -0,0 +1,130 @@
+/*
+ * perfmon.c: perfmon2 global initialization functions
@@ -18153,10 +18019,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_init.c
+ * compiled in.
+ */
+subsys_initcall(pfm_init);
-Index: linux-2.6.31-master/perfmon/perfmon_intr.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_intr.c
++++ b/perfmon/perfmon_intr.c
@@ -0,0 +1,626 @@
+/*
+ * perfmon_intr.c: perfmon2 interrupt handling
@@ -18784,10 +18648,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_intr.c
+}
+EXPORT_SYMBOL(pfm_interrupt_handler);
+
-Index: linux-2.6.31-master/perfmon/perfmon_msg.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_msg.c
++++ b/perfmon/perfmon_msg.c
@@ -0,0 +1,229 @@
+/*
+ * perfmon_msg.c: perfmon2 notification message queue management
@@ -19018,10 +18880,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_msg.c
+ ctx->msgq_tail & PFM_MSGQ_MASK,
+ m->type);
+}
-Index: linux-2.6.31-master/perfmon/perfmon_pmu.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_pmu.c
++++ b/perfmon/perfmon_pmu.c
@@ -0,0 +1,640 @@
+/*
+ * perfmon_pmu.c: perfmon2 PMU configuration management
@@ -19586,11 +19446,11 @@ Index: linux-2.6.31-master/perfmon/perfmon_pmu.c
+ memset(unavail_pmds, 0, sizeof(unavail_pmds));
+
+ /*
-+ * gather unavailable registers
-+ *
-+ * cannot use pfm_pmu_conf->regs_all as it
-+ * is not yet initialized
-+ */
++ * gather unavailable registers
++ *
++ * cannot use pfm_pmu_conf->regs_all as it
++ * is not yet initialized
++ */
+ ret = pfm_arch_reserve_regs(unavail_pmcs, unavail_pmds);
+ if (ret) {
+ pfm_pmu_acquired = 0;
@@ -19663,10 +19523,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_pmu.c
+ }
+ spin_unlock(&pfm_pmu_acq_lock);
+}
-Index: linux-2.6.31-master/perfmon/perfmon_priv.h
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_priv.h
++++ b/perfmon/perfmon_priv.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2001-2006 Hewlett-Packard Development Company, L.P.
@@ -19846,10 +19704,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_priv.h
+#endif /* CONFIG_PERFMON */
+
+#endif /* __PERFMON_PRIV_H__ */
-Index: linux-2.6.31-master/perfmon/perfmon_res.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_res.c
++++ b/perfmon/perfmon_res.c
@@ -0,0 +1,425 @@
+/*
+ * perfmon_res.c: perfmon2 resource allocations
@@ -19964,11 +19820,11 @@ Index: linux-2.6.31-master/perfmon/perfmon_res.c
+ locked = mm->locked_vm << PAGE_SHIFT;
+ locked += size;
+
-+ if (locked > current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) {
++ if (locked > rlim_get_cur(RLIMIT_MEMLOCK)) {
+
+ PFM_DBG("RLIMIT_MEMLOCK reached ask_locked=%lu rlim_cur=%lu",
+ locked,
-+ current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur);
++ rlim_get_cur(RLIMIT_MEMLOCK));
+
+ up_write(&mm->mmap_sem);
+ mmput(mm);
@@ -20276,10 +20132,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_res.c
+ spin_unlock_irqrestore(&pfm_res_lock, flags);
+ return strlen(buf);
+}
-Index: linux-2.6.31-master/perfmon/perfmon_rw.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_rw.c
++++ b/perfmon/perfmon_rw.c
@@ -0,0 +1,643 @@
+/*
+ * perfmon.c: perfmon2 PMC/PMD read/write system calls
@@ -20924,10 +20778,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_rw.c
+error:
+ return ret;
+}
-Index: linux-2.6.31-master/perfmon/perfmon_sets.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_sets.c
++++ b/perfmon/perfmon_sets.c
@@ -0,0 +1,873 @@
+/*
+ * perfmon_sets.c: perfmon2 event sets and multiplexing functions
@@ -21802,10 +21654,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_sets.c
+ }
+ return 0;
+}
-Index: linux-2.6.31-master/perfmon/perfmon_smpl.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_smpl.c
++++ b/perfmon/perfmon_smpl.c
@@ -0,0 +1,888 @@
+/*
+ * perfmon_smpl.c: perfmon2 sampling management
@@ -22695,10 +22545,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_smpl.c
+
+ f->fmt_unload(ctx);
+}
-Index: linux-2.6.31-master/perfmon/perfmon_syscalls.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_syscalls.c
++++ b/perfmon/perfmon_syscalls.c
@@ -0,0 +1,1067 @@
+/*
+ * perfmon_syscalls.c: perfmon2 system call interface
@@ -23767,10 +23615,8 @@ Index: linux-2.6.31-master/perfmon/perfmon_syscalls.c
+ pfm_release_ctx_from_fd(&cookie);
+ return ret;
+}
-Index: linux-2.6.31-master/perfmon/perfmon_sysfs.c
-===================================================================
--- /dev/null
-+++ linux-2.6.31-master/perfmon/perfmon_sysfs.c
++++ b/perfmon/perfmon_sysfs.c
@@ -0,0 +1,525 @@
+/*
+ * perfmon_sysfs.c: perfmon2 sysfs interface
diff --git a/patches.suse/perfmon2_ioctl.patch b/patches.suse/perfmon2_ioctl.patch
index ee987fbe2b..16a9420b19 100644
--- a/patches.suse/perfmon2_ioctl.patch
+++ b/patches.suse/perfmon2_ioctl.patch
@@ -177,7 +177,7 @@ Index: linux-2.6.32-rc5-0.0.35.a1b1c3a/perfmon/perfmon_control.c
+
+ return sys_pfm_create_evtsets(d->fd,
+ (struct pfarg_setdesc __user *)_PTR(d->req),
-+ d->count);
++ d->count);
+}
+
+static long pfm_control_getinfo_evtsets(union pfm_control *cdata, int compat)
diff --git a/patches.suse/rlim-0001-SECURITY-selinux-fix-update_rlimit_cpu-parameter.patch b/patches.suse/rlim-0001-SECURITY-selinux-fix-update_rlimit_cpu-parameter.patch
new file mode 100644
index 0000000000..1dc8e73602
--- /dev/null
+++ b/patches.suse/rlim-0001-SECURITY-selinux-fix-update_rlimit_cpu-parameter.patch
@@ -0,0 +1,31 @@
+From 4048a22b8afcb58cfcbd82514ad0e5fb9c99cb34 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Fri, 28 Aug 2009 10:47:16 +0200
+Subject: [PATCH 01/25] SECURITY: selinux, fix update_rlimit_cpu parameter
+References: FATE#305733
+
+Don't pass rlim_cur member of RLIM_NLIMITS-1=RLIMIT_RTTIME limit
+to update_rlimit_cpu() in selinux_bprm_committing_creds.
+
+Use proper rlim[RLIMIT_CPU].rlim_cur instead.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Acked-by: James Morris <jmorris@namei.org>
+Cc: Stephen Smalley <sds@tycho.nsa.gov>
+Cc: Eric Paris <eparis@parisplace.org>
+Cc: David Howells <dhowells@redhat.com>
+---
+ security/selinux/hooks.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -2366,7 +2366,7 @@ static void selinux_bprm_committing_cred
+ initrlim = init_task.signal->rlim + i;
+ rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
+ }
+- update_rlimit_cpu(rlim->rlim_cur);
++ update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur);
+ }
+ }
+
diff --git a/patches.suse/rlim-0002-SECURITY-add-task_struct-to-setrlimit.patch b/patches.suse/rlim-0002-SECURITY-add-task_struct-to-setrlimit.patch
new file mode 100644
index 0000000000..b0d0dd5971
--- /dev/null
+++ b/patches.suse/rlim-0002-SECURITY-add-task_struct-to-setrlimit.patch
@@ -0,0 +1,113 @@
+From 9a95d4c6a9c40114cc124a1155237895d5add7e2 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Wed, 26 Aug 2009 18:41:16 +0200
+Subject: [PATCH 02/25] SECURITY: add task_struct to setrlimit
+References: FATE#305733
+
+Add task_struct to task_setrlimit of security_operations to be able to set
+rlimit of different task than current.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Acked-by: Eric Paris <eparis@redhat.com>
+Acked-by: James Morris <jmorris@namei.org>
+---
+ include/linux/security.h | 9 ++++++---
+ kernel/sys.c | 2 +-
+ security/capability.c | 3 ++-
+ security/security.c | 5 +++--
+ security/selinux/hooks.c | 7 ++++---
+ 5 files changed, 16 insertions(+), 10 deletions(-)
+
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -1570,7 +1570,8 @@ struct security_operations {
+ int (*task_setnice) (struct task_struct *p, int nice);
+ int (*task_setioprio) (struct task_struct *p, int ioprio);
+ int (*task_getioprio) (struct task_struct *p);
+- int (*task_setrlimit) (unsigned int resource, struct rlimit *new_rlim);
++ int (*task_setrlimit) (struct task_struct *p, unsigned int resource,
++ struct rlimit *new_rlim);
+ int (*task_setscheduler) (struct task_struct *p, int policy,
+ struct sched_param *lp);
+ int (*task_getscheduler) (struct task_struct *p);
+@@ -1835,7 +1836,8 @@ int security_task_setgroups(struct group
+ int security_task_setnice(struct task_struct *p, int nice);
+ int security_task_setioprio(struct task_struct *p, int ioprio);
+ int security_task_getioprio(struct task_struct *p);
+-int security_task_setrlimit(unsigned int resource, struct rlimit *new_rlim);
++int security_task_setrlimit(struct task_struct *p, unsigned int resource,
++ struct rlimit *new_rlim);
+ int security_task_setscheduler(struct task_struct *p,
+ int policy, struct sched_param *lp);
+ int security_task_getscheduler(struct task_struct *p);
+@@ -2451,7 +2453,8 @@ static inline int security_task_getiopri
+ return 0;
+ }
+
+-static inline int security_task_setrlimit(unsigned int resource,
++static inline int security_task_setrlimit(struct task_struct *p,
++ unsigned int resource,
+ struct rlimit *new_rlim)
+ {
+ return 0;
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1256,7 +1256,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+ if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
+ return -EPERM;
+
+- retval = security_task_setrlimit(resource, &new_rlim);
++ retval = security_task_setrlimit(current, resource, &new_rlim);
+ if (retval)
+ return retval;
+
+--- a/security/capability.c
++++ b/security/capability.c
+@@ -450,7 +450,8 @@ static int cap_task_getioprio(struct tas
+ return 0;
+ }
+
+-static int cap_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
++static int cap_task_setrlimit(struct task_struct *p, unsigned int resource,
++ struct rlimit *new_rlim)
+ {
+ return 0;
+ }
+--- a/security/security.c
++++ b/security/security.c
+@@ -782,9 +782,10 @@ int security_task_getioprio(struct task_
+ return security_ops->task_getioprio(p);
+ }
+
+-int security_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
++int security_task_setrlimit(struct task_struct *p, unsigned int resource,
++ struct rlimit *new_rlim)
+ {
+- return security_ops->task_setrlimit(resource, new_rlim);
++ return security_ops->task_setrlimit(p, resource, new_rlim);
+ }
+
+ int security_task_setscheduler(struct task_struct *p,
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -3390,16 +3390,17 @@ static int selinux_task_getioprio(struct
+ return current_has_perm(p, PROCESS__GETSCHED);
+ }
+
+-static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
++static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
++ struct rlimit *new_rlim)
+ {
+- struct rlimit *old_rlim = current->signal->rlim + resource;
++ struct rlimit *old_rlim = p->signal->rlim + resource;
+
+ /* Control the ability to change the hard limit (whether
+ lowering or raising it), so that the hard limit can
+ later be used as a safe reset point for the soft limit
+ upon context transitions. See selinux_bprm_committing_creds. */
+ if (old_rlim->rlim_max != new_rlim->rlim_max)
+- return current_has_perm(current, PROCESS__SETRLIMIT);
++ return current_has_perm(p, PROCESS__SETRLIMIT);
+
+ return 0;
+ }
diff --git a/patches.suse/rlim-0003-core-add-task_struct-to-update_rlimit_cpu.patch b/patches.suse/rlim-0003-core-add-task_struct-to-update_rlimit_cpu.patch
new file mode 100644
index 0000000000..e7c3b1a82a
--- /dev/null
+++ b/patches.suse/rlim-0003-core-add-task_struct-to-update_rlimit_cpu.patch
@@ -0,0 +1,75 @@
+From 67d3dda03cca0d2316779c094c9e55eb21d1e825 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Fri, 28 Aug 2009 14:05:12 +0200
+Subject: [PATCH 03/25] core: add task_struct to update_rlimit_cpu
+References: FATE#305733
+
+Add task_struct as a parameter to update_rlimit_cpu to be able to set
+rlimit_cpu of different task than current.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Acked-by: James Morris <jmorris@namei.org>
+---
+ include/linux/posix-timers.h | 2 +-
+ kernel/posix-cpu-timers.c | 10 +++++-----
+ kernel/sys.c | 2 +-
+ security/selinux/hooks.c | 3 ++-
+ 4 files changed, 9 insertions(+), 8 deletions(-)
+
+--- a/include/linux/posix-timers.h
++++ b/include/linux/posix-timers.h
+@@ -117,6 +117,6 @@ void set_process_cpu_timer(struct task_s
+
+ long clock_nanosleep_restart(struct restart_block *restart_block);
+
+-void update_rlimit_cpu(unsigned long rlim_new);
++void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new);
+
+ #endif
+--- a/kernel/posix-cpu-timers.c
++++ b/kernel/posix-cpu-timers.c
+@@ -13,16 +13,16 @@
+ /*
+ * Called after updating RLIMIT_CPU to set timer expiration if necessary.
+ */
+-void update_rlimit_cpu(unsigned long rlim_new)
++void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new)
+ {
+ cputime_t cputime = secs_to_cputime(rlim_new);
+- struct signal_struct *const sig = current->signal;
++ struct signal_struct *const sig = task->signal;
+
+ if (cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) ||
+ cputime_gt(sig->it[CPUCLOCK_PROF].expires, cputime)) {
+- spin_lock_irq(&current->sighand->siglock);
+- set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
+- spin_unlock_irq(&current->sighand->siglock);
++ spin_lock_irq(&task->sighand->siglock);
++ set_process_cpu_timer(task, CPUCLOCK_PROF, &cputime, NULL);
++ spin_unlock_irq(&task->sighand->siglock);
+ }
+ }
+
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1286,7 +1286,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+ if (new_rlim.rlim_cur == RLIM_INFINITY)
+ goto out;
+
+- update_rlimit_cpu(new_rlim.rlim_cur);
++ update_rlimit_cpu(current, new_rlim.rlim_cur);
+ out:
+ return 0;
+ }
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -2366,7 +2366,8 @@ static void selinux_bprm_committing_cred
+ initrlim = init_task.signal->rlim + i;
+ rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
+ }
+- update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur);
++ update_rlimit_cpu(current,
++ current->signal->rlim[RLIMIT_CPU].rlim_cur);
+ }
+ }
+
diff --git a/patches.suse/rlim-0004-sys_setrlimit-make-sure-rlim_max-never-grows.patch b/patches.suse/rlim-0004-sys_setrlimit-make-sure-rlim_max-never-grows.patch
new file mode 100644
index 0000000000..9e3e405b3a
--- /dev/null
+++ b/patches.suse/rlim-0004-sys_setrlimit-make-sure-rlim_max-never-grows.patch
@@ -0,0 +1,65 @@
+From aa8cb746a49ab9e576e8c958c242c772f8392eff Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Thu, 3 Sep 2009 19:21:45 +0200
+Subject: [PATCH 04/25] sys_setrlimit: make sure ->rlim_max never grows
+References: FATE#305733
+
+Mostly preparation for Jiri's changes, but probably makes sense anyway.
+
+sys_setrlimit() checks new_rlim.rlim_max <= old_rlim->rlim_max, but when
+it takes task_lock() old_rlim->rlim_max can be already lowered. Move this
+check under task_lock().
+
+Currently this is not important, we can only race with our sub-thread,
+this means the application is stupid. But when we change the code to allow
+the update of !current task's limits, it becomes important to make sure
+->rlim_max can be lowered "reliably" even if we race with the application
+doing sys_setrlimit().
+
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+---
+ kernel/sys.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1249,10 +1249,6 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+ return -EFAULT;
+ if (new_rlim.rlim_cur > new_rlim.rlim_max)
+ return -EINVAL;
+- old_rlim = current->signal->rlim + resource;
+- if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
+- !capable(CAP_SYS_RESOURCE))
+- return -EPERM;
+ if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
+ return -EPERM;
+
+@@ -1270,11 +1266,16 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+ new_rlim.rlim_cur = 1;
+ }
+
++ old_rlim = current->signal->rlim + resource;
+ task_lock(current->group_leader);
+- *old_rlim = new_rlim;
++ if ((new_rlim.rlim_max <= old_rlim->rlim_max) ||
++ capable(CAP_SYS_RESOURCE))
++ *old_rlim = new_rlim;
++ else
++ retval = -EPERM;
+ task_unlock(current->group_leader);
+
+- if (resource != RLIMIT_CPU)
++ if (retval || resource != RLIMIT_CPU)
+ goto out;
+
+ /*
+@@ -1288,7 +1289,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+
+ update_rlimit_cpu(current, new_rlim.rlim_cur);
+ out:
+- return 0;
++ return retval;
+ }
+
+ /*
diff --git a/patches.suse/rlim-0005-core-split-sys_setrlimit.patch b/patches.suse/rlim-0005-core-split-sys_setrlimit.patch
new file mode 100644
index 0000000000..2084a7166e
--- /dev/null
+++ b/patches.suse/rlim-0005-core-split-sys_setrlimit.patch
@@ -0,0 +1,112 @@
+From 94a19e33a28127f2fe2d4fc5cf9e2f916a1b5aee Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Wed, 26 Aug 2009 23:45:34 +0200
+Subject: [PATCH 05/25] core: split sys_setrlimit
+References: FATE#305733
+
+Create setrlimit from sys_setrlimit and declare setrlimit in
+the resource header. This is to allow rlimits to be changed not
+only by syscall, but later from proc code too.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+---
+ include/linux/resource.h | 2 ++
+ kernel/sys.c | 44 ++++++++++++++++++++++++++------------------
+ 2 files changed, 28 insertions(+), 18 deletions(-)
+
+--- a/include/linux/resource.h
++++ b/include/linux/resource.h
+@@ -71,5 +71,7 @@ struct rlimit {
+ #include <asm/resource.h>
+
+ int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
++int setrlimit(struct task_struct *tsk, unsigned int resource,
++ struct rlimit *new_rlim);
+
+ #endif
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1238,42 +1238,39 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned
+
+ #endif
+
+-SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
++int setrlimit(struct task_struct *tsk, unsigned int resource,
++ struct rlimit *new_rlim)
+ {
+- struct rlimit new_rlim, *old_rlim;
++ struct rlimit *old_rlim;
+ int retval;
+
+- if (resource >= RLIM_NLIMITS)
++ if (new_rlim->rlim_cur > new_rlim->rlim_max)
+ return -EINVAL;
+- if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
+- return -EFAULT;
+- if (new_rlim.rlim_cur > new_rlim.rlim_max)
+- return -EINVAL;
+- if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
++ if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
+ return -EPERM;
+
+- retval = security_task_setrlimit(current, resource, &new_rlim);
++ retval = security_task_setrlimit(tsk, resource, new_rlim);
+ if (retval)
+ return retval;
+
+- if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
++ if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
+ /*
+ * The caller is asking for an immediate RLIMIT_CPU
+ * expiry. But we use the zero value to mean "it was
+ * never set". So let's cheat and make it one second
+ * instead
+ */
+- new_rlim.rlim_cur = 1;
++ new_rlim->rlim_cur = 1;
+ }
+
+- old_rlim = current->signal->rlim + resource;
+- task_lock(current->group_leader);
+- if ((new_rlim.rlim_max <= old_rlim->rlim_max) ||
++ old_rlim = tsk->signal->rlim + resource;
++ task_lock(tsk->group_leader);
++ if ((new_rlim->rlim_max <= old_rlim->rlim_max) ||
+ capable(CAP_SYS_RESOURCE))
+- *old_rlim = new_rlim;
++ *old_rlim = *new_rlim;
+ else
+ retval = -EPERM;
+- task_unlock(current->group_leader);
++ task_unlock(tsk->group_leader);
+
+ if (retval || resource != RLIMIT_CPU)
+ goto out;
+@@ -1284,14 +1281,25 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+ * very long-standing error, and fixing it now risks breakage of
+ * applications, so we live with it
+ */
+- if (new_rlim.rlim_cur == RLIM_INFINITY)
++ if (new_rlim->rlim_cur == RLIM_INFINITY)
+ goto out;
+
+- update_rlimit_cpu(current, new_rlim.rlim_cur);
++ update_rlimit_cpu(tsk, new_rlim->rlim_cur);
+ out:
+ return retval;
+ }
+
++SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
++{
++ struct rlimit new_rlim;
++
++ if (resource >= RLIM_NLIMITS)
++ return -EINVAL;
++ if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
++ return -EFAULT;
++ return setrlimit(current, resource, &new_rlim);
++}
++
+ /*
+ * It would make sense to put struct rusage in the task_struct,
+ * except that would make the task_struct be *really big*. After
diff --git a/patches.suse/rlim-0006-core-allow-setrlimit-to-non-current-tasks.patch b/patches.suse/rlim-0006-core-allow-setrlimit-to-non-current-tasks.patch
new file mode 100644
index 0000000000..0b3abaaa3e
--- /dev/null
+++ b/patches.suse/rlim-0006-core-allow-setrlimit-to-non-current-tasks.patch
@@ -0,0 +1,55 @@
+From c8e713c441649b167cc9f0b608d4c7afc9ea7d33 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Fri, 28 Aug 2009 14:08:17 +0200
+Subject: [PATCH 06/25] core: allow setrlimit to non-current tasks
+References: FATE#305733
+
+Add locking to allow setrlimit accept task parameter other than
+current.
+
+Namely, lock tasklist_lock for read and check whether the task
+structure has sighand non-null. Do all the signal processing under
+that lock still held.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+---
+ kernel/sys.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1238,6 +1238,7 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned
+
+ #endif
+
++/* make sure you are allowed to change @tsk limits before calling this */
+ int setrlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim)
+ {
+@@ -1249,9 +1250,16 @@ int setrlimit(struct task_struct *tsk, u
+ if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
+ return -EPERM;
+
++ /* protect tsk->signal and tsk->sighand from disappearing */
++ read_lock(&tasklist_lock);
++ if (!tsk->sighand) {
++ retval = -ESRCH;
++ goto out;
++ }
++
+ retval = security_task_setrlimit(tsk, resource, new_rlim);
+ if (retval)
+- return retval;
++ goto out;
+
+ if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
+ /*
+@@ -1286,6 +1294,7 @@ int setrlimit(struct task_struct *tsk, u
+
+ update_rlimit_cpu(tsk, new_rlim->rlim_cur);
+ out:
++ read_unlock(&tasklist_lock);
+ return retval;
+ }
+
diff --git a/patches.suse/rlim-0007-core-optimize-setrlimit-for-current-task.patch b/patches.suse/rlim-0007-core-optimize-setrlimit-for-current-task.patch
new file mode 100644
index 0000000000..0e107c4018
--- /dev/null
+++ b/patches.suse/rlim-0007-core-optimize-setrlimit-for-current-task.patch
@@ -0,0 +1,49 @@
+From 6ac09da8ed3dadb3d734c77066c5e6d7501585f7 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Fri, 28 Aug 2009 14:08:17 +0200
+Subject: [PATCH 07/25] core: optimize setrlimit for current task
+References: FATE#305733
+
+Don't take tasklist lock for 'current'. It's not needed, since
+current->sighand/signal can't disappear.
+
+This improves serlimit called especially via sys_setrlimit.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+---
+ kernel/sys.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1250,11 +1250,14 @@ int setrlimit(struct task_struct *tsk, u
+ if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
+ return -EPERM;
+
+- /* protect tsk->signal and tsk->sighand from disappearing */
+- read_lock(&tasklist_lock);
+- if (!tsk->sighand) {
+- retval = -ESRCH;
+- goto out;
++ /* optimization: 'current' doesn't need locking, e.g. setrlimit */
++ if (tsk != current) {
++ /* protect tsk->signal and tsk->sighand from disappearing */
++ read_lock(&tasklist_lock);
++ if (!tsk->sighand) {
++ retval = -ESRCH;
++ goto out;
++ }
+ }
+
+ retval = security_task_setrlimit(tsk, resource, new_rlim);
+@@ -1294,7 +1297,8 @@ int setrlimit(struct task_struct *tsk, u
+
+ update_rlimit_cpu(tsk, new_rlim->rlim_cur);
+ out:
+- read_unlock(&tasklist_lock);
++ if (tsk != current)
++ read_unlock(&tasklist_lock);
+ return retval;
+ }
+
diff --git a/patches.suse/rlim-0008-FS-proc-make-limits-writable.patch b/patches.suse/rlim-0008-FS-proc-make-limits-writable.patch
new file mode 100644
index 0000000000..646a0fe340
--- /dev/null
+++ b/patches.suse/rlim-0008-FS-proc-make-limits-writable.patch
@@ -0,0 +1,123 @@
+From bb885e769131db8e0e2a90c5537e1dac8cf92f6d Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Wed, 26 Aug 2009 21:24:30 +0200
+Subject: [PATCH 08/25] FS: proc, make limits writable
+References: FATE#305733
+
+Allow writing strings such as
+Max core file size=0:unlimited
+to /proc/<pid>/limits to change limits.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+---
+ fs/proc/base.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 76 insertions(+), 2 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -128,6 +128,8 @@ struct pid_entry {
+ NULL, &proc_single_file_operations, \
+ { .proc_show = show } )
+
++static ssize_t proc_info_read(struct file * file, char __user * buf,
++ size_t count, loff_t *ppos);
+ /*
+ * Count the number of hardlinks for the pid_entry table, excluding the .
+ * and .. links.
+@@ -521,6 +523,74 @@ static int proc_pid_limits(struct task_s
+ return count;
+ }
+
++static ssize_t limits_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
++ char str[32 + 1 + 16 + 1 + 16 + 1], *delim, *next;
++ struct rlimit new_rlimit;
++ unsigned int i;
++ int ret;
++
++ if (!task) {
++ count = -ESRCH;
++ goto out;
++ }
++ if (copy_from_user(str, buf, min(count, sizeof(str) - 1))) {
++ count = -EFAULT;
++ goto put_task;
++ }
++
++ str[min(count, sizeof(str) - 1)] = 0;
++
++ delim = strchr(str, '=');
++ if (!delim) {
++ count = -EINVAL;
++ goto put_task;
++ }
++ *delim++ = 0; /* for easy 'str' usage */
++ new_rlimit.rlim_cur = simple_strtoul(delim, &next, 0);
++ if (*next != ':') {
++ if (strncmp(delim, "unlimited:", 10)) {
++ count = -EINVAL;
++ goto put_task;
++ }
++ new_rlimit.rlim_cur = RLIM_INFINITY;
++ next = delim + 9; /* move to ':' */
++ }
++ delim = next + 1;
++ new_rlimit.rlim_max = simple_strtoul(delim, &next, 0);
++ if (*next != 0) {
++ if (strcmp(delim, "unlimited")) {
++ count = -EINVAL;
++ goto put_task;
++ }
++ new_rlimit.rlim_max = RLIM_INFINITY;
++ }
++
++ for (i = 0; i < RLIM_NLIMITS; i++)
++ if (!strcmp(str, lnames[i].name))
++ break;
++ if (i >= RLIM_NLIMITS) {
++ count = -EINVAL;
++ goto put_task;
++ }
++
++ ret = setrlimit(task, i, &new_rlimit);
++ if (ret)
++ count = ret;
++
++put_task:
++ put_task_struct(task);
++out:
++ return count;
++}
++
++static const struct file_operations proc_pid_limits_operations = {
++ .read = proc_info_read,
++ .write = limits_write,
++};
++
+ #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+ static int proc_pid_syscall(struct task_struct *task, char *buffer)
+ {
+@@ -2500,7 +2570,9 @@ static const struct pid_entry tgid_base_
+ INF("auxv", S_IRUSR, proc_pid_auxv),
+ ONE("status", S_IRUGO, proc_pid_status),
+ ONE("personality", S_IRUSR, proc_pid_personality),
+- INF("limits", S_IRUSR, proc_pid_limits),
++ NOD("limits", S_IFREG|S_IRUSR|S_IWUSR, NULL,
++ &proc_pid_limits_operations,
++ { .proc_read = proc_pid_limits }),
+ #ifdef CONFIG_SCHED_DEBUG
+ REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
+ #endif
+@@ -2834,7 +2906,9 @@ static const struct pid_entry tid_base_s
+ INF("auxv", S_IRUSR, proc_pid_auxv),
+ ONE("status", S_IRUGO, proc_pid_status),
+ ONE("personality", S_IRUSR, proc_pid_personality),
+- INF("limits", S_IRUSR, proc_pid_limits),
++ NOD("limits", S_IFREG|S_IRUSR|S_IWUSR, NULL,
++ &proc_pid_limits_operations,
++ { .proc_read = proc_pid_limits }),
+ #ifdef CONFIG_SCHED_DEBUG
+ REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
+ #endif
diff --git a/patches.suse/rlim-0009-core-posix-cpu-timers-cleanup-rlimits-usage.patch b/patches.suse/rlim-0009-core-posix-cpu-timers-cleanup-rlimits-usage.patch
new file mode 100644
index 0000000000..2e61313341
--- /dev/null
+++ b/patches.suse/rlim-0009-core-posix-cpu-timers-cleanup-rlimits-usage.patch
@@ -0,0 +1,116 @@
+From ec2d308382afdbcc65cd52c348dc136353f8068d Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Mon, 16 Nov 2009 12:13:35 +0100
+Subject: [PATCH 09/25] core: posix-cpu-timers, cleanup rlimits usage
+References: FATE#305733
+
+Fetch rlimit (both hard and soft) values only once and work on them.
+It removes many accesses through sig structure and makes the code
+cleaner.
+
+Mostly a preparation for writable resource limits support.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Peter Zijlstra <peterz@infradead.org>
+---
+ kernel/posix-cpu-timers.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+--- a/kernel/posix-cpu-timers.c
++++ b/kernel/posix-cpu-timers.c
+@@ -983,6 +983,7 @@ static void check_thread_timers(struct t
+ int maxfire;
+ struct list_head *timers = tsk->cpu_timers;
+ struct signal_struct *const sig = tsk->signal;
++ unsigned long soft;
+
+ maxfire = 20;
+ tsk->cputime_expires.prof_exp = cputime_zero;
+@@ -1031,9 +1032,9 @@ static void check_thread_timers(struct t
+ /*
+ * Check for the special case thread timers.
+ */
+- if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) {
++ soft = sig->rlim[RLIMIT_RTTIME].rlim_cur;
++ if (soft != RLIM_INFINITY) {
+ unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max;
+- unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur;
+
+ if (hard != RLIM_INFINITY &&
+ tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
+@@ -1044,14 +1045,13 @@ static void check_thread_timers(struct t
+ __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
+ return;
+ }
+- if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) {
++ if (tsk->rt.timeout > DIV_ROUND_UP(soft, USEC_PER_SEC/HZ)) {
+ /*
+ * At the soft limit, send a SIGXCPU every second.
+ */
+- if (sig->rlim[RLIMIT_RTTIME].rlim_cur
+- < sig->rlim[RLIMIT_RTTIME].rlim_max) {
+- sig->rlim[RLIMIT_RTTIME].rlim_cur +=
+- USEC_PER_SEC;
++ if (soft < hard) {
++ soft += USEC_PER_SEC;
++ sig->rlim[RLIMIT_RTTIME].rlim_cur = soft;
+ }
+ printk(KERN_INFO
+ "RT Watchdog Timeout: %s[%d]\n",
+@@ -1122,13 +1122,14 @@ static void check_process_timers(struct
+ unsigned long long sum_sched_runtime, sched_expires;
+ struct list_head *timers = sig->cpu_timers;
+ struct task_cputime cputime;
++ unsigned long cpu_cur_lim = sig->rlim[RLIMIT_CPU].rlim_cur;
+
+ /*
+ * Don't sample the current process CPU clocks if there are no timers.
+ */
+ if (list_empty(&timers[CPUCLOCK_PROF]) &&
+ cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) &&
+- sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY &&
++ cpu_cur_lim == RLIM_INFINITY &&
+ list_empty(&timers[CPUCLOCK_VIRT]) &&
+ cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) &&
+ list_empty(&timers[CPUCLOCK_SCHED])) {
+@@ -1195,10 +1196,11 @@ static void check_process_timers(struct
+ check_cpu_itimer(tsk, &sig->it[CPUCLOCK_VIRT], &virt_expires, utime,
+ SIGVTALRM);
+
+- if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
++ if (cpu_cur_lim != RLIM_INFINITY) {
+ unsigned long psecs = cputime_to_secs(ptime);
++ unsigned long hard = sig->rlim[RLIMIT_CPU].rlim_max;
+ cputime_t x;
+- if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) {
++ if (psecs >= hard) {
+ /*
+ * At the hard limit, we just die.
+ * No need to calculate anything else now.
+@@ -1206,17 +1208,17 @@ static void check_process_timers(struct
+ __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
+ return;
+ }
+- if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
++ if (psecs >= cpu_cur_lim) {
+ /*
+ * At the soft limit, send a SIGXCPU every second.
+ */
+ __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
+- if (sig->rlim[RLIMIT_CPU].rlim_cur
+- < sig->rlim[RLIMIT_CPU].rlim_max) {
+- sig->rlim[RLIMIT_CPU].rlim_cur++;
++ if (cpu_cur_lim < hard) {
++ cpu_cur_lim++;
++ sig->rlim[RLIMIT_CPU].rlim_cur = cpu_cur_lim;
+ }
+ }
+- x = secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
++ x = secs_to_cputime(cpu_cur_lim);
+ if (cputime_eq(prof_expires, cputime_zero) ||
+ cputime_lt(x, prof_expires)) {
+ prof_expires = x;
diff --git a/patches.suse/rlim-0010-core-do-security-check-under-task_lock.patch b/patches.suse/rlim-0010-core-do-security-check-under-task_lock.patch
new file mode 100644
index 0000000000..f405a47373
--- /dev/null
+++ b/patches.suse/rlim-0010-core-do-security-check-under-task_lock.patch
@@ -0,0 +1,59 @@
+From 97559fca2402df0b7ea0fc04afb7ea9dcfbc96e7 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 17:37:04 +0100
+Subject: [PATCH 10/25] core: do security check under task_lock
+References: FATE#305733
+
+Do security_task_setrlimit under task_lock. Other tasks may
+change limits under our hands while we are checking limits
+inside the function. From now on, they can't.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Acked-by: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+---
+ kernel/sys.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1243,7 +1243,7 @@ int setrlimit(struct task_struct *tsk, u
+ struct rlimit *new_rlim)
+ {
+ struct rlimit *old_rlim;
+- int retval;
++ int retval = 0;
+
+ if (new_rlim->rlim_cur > new_rlim->rlim_max)
+ return -EINVAL;
+@@ -1260,10 +1260,6 @@ int setrlimit(struct task_struct *tsk, u
+ }
+ }
+
+- retval = security_task_setrlimit(tsk, resource, new_rlim);
+- if (retval)
+- goto out;
+-
+ if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
+ /*
+ * The caller is asking for an immediate RLIMIT_CPU
+@@ -1276,11 +1272,13 @@ int setrlimit(struct task_struct *tsk, u
+
+ old_rlim = tsk->signal->rlim + resource;
+ task_lock(tsk->group_leader);
+- if ((new_rlim->rlim_max <= old_rlim->rlim_max) ||
+- capable(CAP_SYS_RESOURCE))
+- *old_rlim = *new_rlim;
+- else
++ if ((new_rlim->rlim_max > old_rlim->rlim_max) &&
++ !capable(CAP_SYS_RESOURCE))
+ retval = -EPERM;
++ if (!retval)
++ retval = security_task_setrlimit(tsk, resource, new_rlim);
++ if (!retval)
++ *old_rlim = *new_rlim;
+ task_unlock(tsk->group_leader);
+
+ if (retval || resource != RLIMIT_CPU)
diff --git a/patches.suse/rlim-0011-resource-add-helpers-for-fetching-rlimits.patch b/patches.suse/rlim-0011-resource-add-helpers-for-fetching-rlimits.patch
new file mode 100644
index 0000000000..3b3780ebd0
--- /dev/null
+++ b/patches.suse/rlim-0011-resource-add-helpers-for-fetching-rlimits.patch
@@ -0,0 +1,54 @@
+From 029f955ef4e3887f52af67b9a95d6cbbed0e55b4 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Thu, 19 Nov 2009 17:16:37 +0100
+Subject: [PATCH 11/25] resource: add helpers for fetching rlimits
+References: FATE#305733
+
+We want to be sure that compiler fetches the limit variable only
+once, so add helpers for fetching current and maximal resource
+limits which do that.
+
+Add them to sched.h (instead of resource.h) due to circular
+dependency
+sched.h->resource.h->task_struct
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+---
+ include/linux/sched.h | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -2574,6 +2574,28 @@ static inline void mm_init_owner(struct
+ }
+ #endif /* CONFIG_MM_OWNER */
+
++static inline unsigned long task_rlim_get_cur(const struct task_struct *tsk,
++ unsigned int limit)
++{
++ return ACCESS_ONCE(tsk->signal->rlim[limit].rlim_cur);
++}
++
++static inline unsigned long task_rlim_get_max(const struct task_struct *tsk,
++ unsigned int limit)
++{
++ return ACCESS_ONCE(tsk->signal->rlim[limit].rlim_max);
++}
++
++static inline unsigned long rlim_get_cur(unsigned int limit)
++{
++ return task_rlim_get_cur(current, limit);
++}
++
++static inline unsigned long rlim_get_max(unsigned int limit)
++{
++ return task_rlim_get_max(current, limit);
++}
++
+ #define TASK_STATE_TO_CHAR_STR "RSDTtZX"
+
+ #endif /* __KERNEL__ */
diff --git a/patches.suse/rlim-0012-IA64-use-helpers-for-rlimits.patch b/patches.suse/rlim-0012-IA64-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..b78749b5de
--- /dev/null
+++ b/patches.suse/rlim-0012-IA64-use-helpers-for-rlimits.patch
@@ -0,0 +1,58 @@
+From 94b789f87b5559ce210aa6de1b84b018fe1e91f3 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 16:42:19 +0100
+Subject: [PATCH 12/25] IA64: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: linux-ia64@vger.kernel.org
+---
+ arch/ia64/kernel/perfmon.c | 2 +-
+ arch/ia64/kernel/sys_ia64.c | 2 +-
+ arch/ia64/mm/init.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/ia64/kernel/perfmon.c
++++ b/arch/ia64/kernel/perfmon.c
+@@ -2298,7 +2298,7 @@ pfm_smpl_buffer_alloc(struct task_struct
+ * if ((mm->total_vm << PAGE_SHIFT) + len> task->rlim[RLIMIT_AS].rlim_cur)
+ * return -ENOMEM;
+ */
+- if (size > task->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
++ if (size > task_rlim_get_cur(task, RLIMIT_MEMLOCK))
+ return -ENOMEM;
+
+ /*
+--- a/arch/ia64/kernel/sys_ia64.c
++++ b/arch/ia64/kernel/sys_ia64.c
+@@ -129,7 +129,7 @@ ia64_brk (unsigned long brk)
+ goto out;
+
+ /* Check against rlimit.. */
+- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
++ rlim = rlim_get_cur(RLIMIT_DATA);
+ if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
+ goto out;
+
+--- a/arch/ia64/mm/init.c
++++ b/arch/ia64/mm/init.c
+@@ -91,7 +91,7 @@ dma_mark_clean(void *addr, size_t size)
+ inline void
+ ia64_set_rbs_bot (void)
+ {
+- unsigned long stack_size = current->signal->rlim[RLIMIT_STACK].rlim_max & -16;
++ unsigned long stack_size = rlim_get_max(RLIMIT_STACK) & -16;
+
+ if (stack_size > MAX_USER_STACK_SIZE)
+ stack_size = MAX_USER_STACK_SIZE;
diff --git a/patches.suse/rlim-0013-PPC-use-helpers-for-rlimits.patch b/patches.suse/rlim-0013-PPC-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..11bab47668
--- /dev/null
+++ b/patches.suse/rlim-0013-PPC-use-helpers-for-rlimits.patch
@@ -0,0 +1,57 @@
+From ca9c6cfe9b154fc6691b5a26ed4f9e03c9398ed7 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 16:44:23 +0100
+Subject: [PATCH 13/25] PPC: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: linuxppc-dev@ozlabs.org
+---
+ arch/powerpc/mm/mmap_64.c | 4 ++--
+ arch/powerpc/platforms/cell/spufs/coredump.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/powerpc/mm/mmap_64.c
++++ b/arch/powerpc/mm/mmap_64.c
+@@ -47,7 +47,7 @@ static inline int mmap_is_legacy(void)
+ if (current->personality & ADDR_COMPAT_LAYOUT)
+ return 1;
+
+- if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
++ if (rlim_get_cur(RLIMIT_STACK) == RLIM_INFINITY)
+ return 1;
+
+ return sysctl_legacy_va_layout;
+@@ -77,7 +77,7 @@ static unsigned long mmap_rnd(void)
+
+ static inline unsigned long mmap_base(void)
+ {
+- unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
++ unsigned long gap = rlim_get_cur(RLIMIT_STACK);
+
+ if (gap < MIN_GAP)
+ gap = MIN_GAP;
+--- a/arch/powerpc/platforms/cell/spufs/coredump.c
++++ b/arch/powerpc/platforms/cell/spufs/coredump.c
+@@ -54,7 +54,7 @@ static ssize_t do_coredump_read(int num,
+ */
+ static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset)
+ {
+- unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
++ unsigned long limit = rlim_get_cur(RLIMIT_CORE);
+ ssize_t written;
+
+ if (*foffset + nr > limit)
diff --git a/patches.suse/rlim-0014-S390-use-helpers-for-rlimits.patch b/patches.suse/rlim-0014-S390-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..a5cb505841
--- /dev/null
+++ b/patches.suse/rlim-0014-S390-use-helpers-for-rlimits.patch
@@ -0,0 +1,46 @@
+From 05960ee0431878f1c669d11a0fff0afe522e56b1 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 16:46:08 +0100
+Subject: [PATCH 14/25] S390: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: linux390@de.ibm.com
+Cc: linux-s390@vger.kernel.org
+---
+ arch/s390/mm/mmap.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/mm/mmap.c
++++ b/arch/s390/mm/mmap.c
+@@ -40,7 +40,7 @@
+
+ static inline unsigned long mmap_base(void)
+ {
+- unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
++ unsigned long gap = rlim_get_cur(RLIMIT_STACK);
+
+ if (gap < MIN_GAP)
+ gap = MIN_GAP;
+@@ -61,7 +61,7 @@ static inline int mmap_is_legacy(void)
+ #endif
+ return sysctl_legacy_va_layout ||
+ (current->personality & ADDR_COMPAT_LAYOUT) ||
+- current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY;
++ rlim_get_cur(RLIMIT_STACK) == RLIM_INFINITY;
+ }
+
+ #ifndef CONFIG_64BIT
diff --git a/patches.suse/rlim-0015-SPARC-use-helpers-for-rlimits.patch b/patches.suse/rlim-0015-SPARC-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..137102d086
--- /dev/null
+++ b/patches.suse/rlim-0015-SPARC-use-helpers-for-rlimits.patch
@@ -0,0 +1,56 @@
+From 65dd41da8ba049ffcf3b9796ac8c26f716ee6262 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 16:47:34 +0100
+Subject: [PATCH 15/25] SPARC: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: sparclinux@vger.kernel.org
+---
+ arch/sparc/kernel/sys_sparc_64.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/sparc/kernel/sys_sparc_64.c
++++ b/arch/sparc/kernel/sys_sparc_64.c
+@@ -361,6 +361,7 @@ EXPORT_SYMBOL(get_fb_unmapped_area);
+ void arch_pick_mmap_layout(struct mm_struct *mm)
+ {
+ unsigned long random_factor = 0UL;
++ unsigned long gap;
+
+ if (current->flags & PF_RANDOMIZE) {
+ random_factor = get_random_int();
+@@ -375,9 +376,10 @@ void arch_pick_mmap_layout(struct mm_str
+ * Fall back to the standard layout if the personality
+ * bit is set, or if the expected stack growth is unlimited:
+ */
++ gap = rlim_get_cur(RLIMIT_STACK);
+ if (!test_thread_flag(TIF_32BIT) ||
+ (current->personality & ADDR_COMPAT_LAYOUT) ||
+- current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
++ gap == RLIM_INFINITY ||
+ sysctl_legacy_va_layout) {
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
+ mm->get_unmapped_area = arch_get_unmapped_area;
+@@ -385,9 +387,7 @@ void arch_pick_mmap_layout(struct mm_str
+ } else {
+ /* We know it's 32-bit */
+ unsigned long task_size = STACK_TOP32;
+- unsigned long gap;
+
+- gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+ if (gap < 128 * 1024 * 1024)
+ gap = 128 * 1024 * 1024;
+ if (gap > (task_size / 6 * 5))
diff --git a/patches.suse/rlim-0016-X86-use-helpers-for-rlimits.patch b/patches.suse/rlim-0016-X86-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..a87838482f
--- /dev/null
+++ b/patches.suse/rlim-0016-X86-use-helpers-for-rlimits.patch
@@ -0,0 +1,59 @@
+From b325f6533086b40fd4575882515a14061e0d66b6 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 16:49:54 +0100
+Subject: [PATCH 16/25] X86: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: x86@kernel.org
+---
+ arch/x86/ia32/ia32_aout.c | 2 +-
+ arch/x86/mm/mmap.c | 6 ++++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/ia32/ia32_aout.c
++++ b/arch/x86/ia32/ia32_aout.c
+@@ -297,7 +297,7 @@ static int load_aout_binary(struct linux
+ * size limits imposed on them by creating programs with large
+ * arrays in the data or bss.
+ */
+- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
++ rlim = rlim_get_cur(RLIMIT_DATA);
+ if (rlim >= RLIM_INFINITY)
+ rlim = ~0;
+ if (ex.a_data + ex.a_bss > rlim)
+--- a/arch/x86/mm/mmap.c
++++ b/arch/x86/mm/mmap.c
+@@ -71,7 +71,8 @@ static int mmap_is_legacy(void)
+ if (current->personality & ADDR_COMPAT_LAYOUT)
+ return 1;
+
+- if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY)
++ if (rlim_get_cur(RLIMIT_STACK)
++ == RLIM_INFINITY)
+ return 1;
+
+ return sysctl_legacy_va_layout;
+@@ -96,7 +97,8 @@ static unsigned long mmap_rnd(void)
+
+ static unsigned long mmap_base(void)
+ {
+- unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
++ unsigned long gap =
++ rlim_get_cur(RLIMIT_STACK);
+
+ if (gap < MIN_GAP)
+ gap = MIN_GAP;
diff --git a/patches.suse/rlim-0017-FS-use-helpers-for-rlimits.patch b/patches.suse/rlim-0017-FS-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..3a94822e4c
--- /dev/null
+++ b/patches.suse/rlim-0017-FS-use-helpers-for-rlimits.patch
@@ -0,0 +1,155 @@
+From f7560274303359535b28a9bd26bf6574824b17ed Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 17:09:05 +0100
+Subject: [PATCH 17/25] FS: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: linux-fsdevel@vger.kernel.org
+---
+ fs/attr.c | 2 +-
+ fs/binfmt_aout.c | 2 +-
+ fs/binfmt_flat.c | 2 +-
+ fs/exec.c | 8 ++++----
+ fs/fcntl.c | 2 +-
+ fs/file.c | 2 +-
+ fs/proc/array.c | 4 ++--
+ fs/select.c | 2 +-
+ 8 files changed, 12 insertions(+), 12 deletions(-)
+
+--- a/fs/attr.c
++++ b/fs/attr.c
+@@ -82,7 +82,7 @@ int inode_newsize_ok(const struct inode
+ if (inode->i_size < offset) {
+ unsigned long limit;
+
+- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
++ limit = rlim_get_cur(RLIMIT_FSIZE);
+ if (limit != RLIM_INFINITY && offset > limit)
+ goto out_sig;
+ if (offset > inode->i_sb->s_maxbytes)
+--- a/fs/binfmt_aout.c
++++ b/fs/binfmt_aout.c
+@@ -246,7 +246,7 @@ static int load_aout_binary(struct linux
+ * size limits imposed on them by creating programs with large
+ * arrays in the data or bss.
+ */
+- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
++ rlim = rlim_get_cur(RLIMIT_DATA);
+ if (rlim >= RLIM_INFINITY)
+ rlim = ~0;
+ if (ex.a_data + ex.a_bss > rlim)
+--- a/fs/binfmt_flat.c
++++ b/fs/binfmt_flat.c
+@@ -501,7 +501,7 @@ static int load_flat_file(struct linux_b
+ * size limits imposed on them by creating programs with large
+ * arrays in the data or bss.
+ */
+- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
++ rlim = rlim_get_cur(RLIMIT_DATA);
+ if (rlim >= RLIM_INFINITY)
+ rlim = ~0;
+ if (data_len + bss_len > rlim) {
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -196,7 +196,7 @@ static struct page *get_arg_page(struct
+ * to work from.
+ */
+ rlim = current->signal->rlim;
+- if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
++ if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
+ put_page(page);
+ return NULL;
+ }
+@@ -575,7 +575,7 @@ int setup_arg_pages(struct linux_binprm
+
+ #ifdef CONFIG_STACK_GROWSUP
+ /* Limit stack size to 1GB */
+- stack_base = current->signal->rlim[RLIMIT_STACK].rlim_max;
++ stack_base = rlim_get_max(RLIMIT_STACK);
+ if (stack_base > (1 << 30))
+ stack_base = 1 << 30;
+
+@@ -1503,7 +1503,7 @@ static int format_corename(char *corenam
+ /* core limit size */
+ case 'c':
+ rc = snprintf(out_ptr, out_end - out_ptr,
+- "%lu", current->signal->rlim[RLIMIT_CORE].rlim_cur);
++ "%lu", rlim_get_cur(RLIMIT_CORE));
+ if (rc > out_end - out_ptr)
+ goto out;
+ out_ptr += rc;
+@@ -1762,7 +1762,7 @@ void do_coredump(long signr, int exit_co
+ int retval = 0;
+ int flag = 0;
+ int ispipe = 0;
+- unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
++ unsigned long core_limit = rlim_get_cur(RLIMIT_CORE);
+ char **helper_argv = NULL;
+ int helper_argc = 0;
+ int dump_count = 0;
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -344,7 +344,7 @@ static long do_fcntl(int fd, unsigned in
+ switch (cmd) {
+ case F_DUPFD:
+ case F_DUPFD_CLOEXEC:
+- if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
++ if (arg >= rlim_get_cur(RLIMIT_NOFILE))
+ break;
+ err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
+ if (err >= 0) {
+--- a/fs/file.c
++++ b/fs/file.c
+@@ -257,7 +257,7 @@ int expand_files(struct files_struct *fi
+ * N.B. For clone tasks sharing a files structure, this test
+ * will limit the total number of files that can be opened.
+ */
+- if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
++ if (nr >= rlim_get_cur(RLIMIT_NOFILE))
+ return -EMFILE;
+
+ /* Do we need to expand? */
+--- a/fs/proc/array.c
++++ b/fs/proc/array.c
+@@ -266,7 +266,7 @@ static inline void task_sig(struct seq_f
+ collect_sigign_sigcatch(p, &ignored, &caught);
+ num_threads = atomic_read(&p->signal->count);
+ qsize = atomic_read(&__task_cred(p)->user->sigpending);
+- qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
++ qlim = task_rlim_get_cur(p, RLIMIT_SIGPENDING);
+ unlock_task_sighand(p, &flags);
+ }
+
+@@ -491,7 +491,7 @@ static int do_task_stat(struct seq_file
+ cutime = sig->cutime;
+ cstime = sig->cstime;
+ cgtime = sig->cgtime;
+- rsslim = sig->rlim[RLIMIT_RSS].rlim_cur;
++ rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
+
+ /* add up live thread stats at the group level */
+ if (whole) {
+--- a/fs/select.c
++++ b/fs/select.c
+@@ -821,7 +821,7 @@ int do_sys_poll(struct pollfd __user *uf
+ struct poll_list *walk = head;
+ unsigned long todo = nfds;
+
+- if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
++ if (nfds > rlim_get_cur(RLIMIT_NOFILE))
+ return -EINVAL;
+
+ len = min_t(unsigned int, nfds, N_STACK_PPS);
diff --git a/patches.suse/rlim-0018-MM-use-helpers-for-rlimits.patch b/patches.suse/rlim-0018-MM-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..9e0b58c158
--- /dev/null
+++ b/patches.suse/rlim-0018-MM-use-helpers-for-rlimits.patch
@@ -0,0 +1,158 @@
+From f1d278d060007742ea242720d6649cf2f5c8f3f3 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 17:11:07 +0100
+Subject: [PATCH 18/25] MM: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: linux-mm@kvack.org
+---
+ mm/filemap.c | 2 +-
+ mm/mlock.c | 12 ++++++------
+ mm/mmap.c | 13 +++++++------
+ mm/mremap.c | 2 +-
+ 4 files changed, 15 insertions(+), 14 deletions(-)
+
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -1974,7 +1974,7 @@ EXPORT_SYMBOL(iov_iter_single_seg_count)
+ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk)
+ {
+ struct inode *inode = file->f_mapping->host;
+- unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
++ unsigned long limit = rlim_get_cur(RLIMIT_FSIZE);
+
+ if (unlikely(*pos < 0))
+ return -EINVAL;
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -25,7 +25,7 @@ int can_do_mlock(void)
+ {
+ if (capable(CAP_IPC_LOCK))
+ return 1;
+- if (current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur != 0)
++ if (rlim_get_cur(RLIMIT_MEMLOCK) != 0)
+ return 1;
+ return 0;
+ }
+@@ -490,7 +490,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st
+ locked = len >> PAGE_SHIFT;
+ locked += current->mm->locked_vm;
+
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
+ lock_limit >>= PAGE_SHIFT;
+
+ /* check against resource limits */
+@@ -553,7 +553,7 @@ SYSCALL_DEFINE1(mlockall, int, flags)
+
+ down_write(&current->mm->mmap_sem);
+
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
+ lock_limit >>= PAGE_SHIFT;
+
+ ret = -ENOMEM;
+@@ -587,7 +587,7 @@ int user_shm_lock(size_t size, struct us
+ int allowed = 0;
+
+ locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
+ if (lock_limit == RLIM_INFINITY)
+ allowed = 1;
+ lock_limit >>= PAGE_SHIFT;
+@@ -621,12 +621,12 @@ int account_locked_memory(struct mm_stru
+
+ down_write(&mm->mmap_sem);
+
+- lim = rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
++ lim = ACCESS_ONCE(rlim[RLIMIT_AS].rlim_cur) >> PAGE_SHIFT;
+ vm = mm->total_vm + pgsz;
+ if (lim < vm)
+ goto out;
+
+- lim = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
++ lim = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur) >> PAGE_SHIFT;
+ vm = mm->locked_vm + pgsz;
+ if (lim < vm)
+ goto out;
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -266,7 +266,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
+ * segment grow beyond its set limit the in case where the limit is
+ * not page aligned -Ram Gupta
+ */
+- rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
++ rlim = rlim_get_cur(RLIMIT_DATA);
+ if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
+ (mm->end_data - mm->start_data) > rlim)
+ goto out;
+@@ -990,7 +990,7 @@ unsigned long do_mmap_pgoff(struct file
+ unsigned long locked, lock_limit;
+ locked = len >> PAGE_SHIFT;
+ locked += mm->locked_vm;
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
+ lock_limit >>= PAGE_SHIFT;
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+ return -EAGAIN;
+@@ -1565,7 +1565,7 @@ static int acct_stack_growth(struct vm_a
+ return -ENOMEM;
+
+ /* Stack limit test */
+- if (size > rlim[RLIMIT_STACK].rlim_cur)
++ if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur))
+ return -ENOMEM;
+
+ /* mlock limit tests */
+@@ -1573,7 +1573,8 @@ static int acct_stack_growth(struct vm_a
+ unsigned long locked;
+ unsigned long limit;
+ locked = mm->locked_vm + grow;
+- limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
++ limit = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur);
++ limit >>= PAGE_SHIFT;
+ if (locked > limit && !capable(CAP_IPC_LOCK))
+ return -ENOMEM;
+ }
+@@ -2026,7 +2027,7 @@ unsigned long do_brk(unsigned long addr,
+ unsigned long locked, lock_limit;
+ locked = len >> PAGE_SHIFT;
+ locked += mm->locked_vm;
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
+ lock_limit >>= PAGE_SHIFT;
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK))
+ return -EAGAIN;
+@@ -2240,7 +2241,7 @@ int may_expand_vm(struct mm_struct *mm,
+ unsigned long cur = mm->total_vm; /* pages */
+ unsigned long lim;
+
+- lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
++ lim = rlim_get_cur(RLIMIT_AS) >> PAGE_SHIFT;
+
+ if (cur + npages > lim)
+ return 0;
+--- a/mm/mremap.c
++++ b/mm/mremap.c
+@@ -358,7 +358,7 @@ unsigned long do_mremap(unsigned long ad
+ if (vma->vm_flags & VM_LOCKED) {
+ unsigned long locked, lock_limit;
+ locked = mm->locked_vm << PAGE_SHIFT;
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
+ locked += new_len - old_len;
+ ret = -EAGAIN;
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK))
diff --git a/patches.suse/rlim-0019-core-use-helpers-for-rlimits.patch b/patches.suse/rlim-0019-core-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..91a3a1efcd
--- /dev/null
+++ b/patches.suse/rlim-0019-core-use-helpers-for-rlimits.patch
@@ -0,0 +1,191 @@
+From 956b69d5e131e52183843ac2dc949810a565eb97 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 17:27:37 +0100
+Subject: [PATCH 19/25] core: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Peter Zijlstra <peterz@infradead.org>
+---
+ kernel/fork.c | 10 ++++++----
+ kernel/perf_event.c | 2 +-
+ kernel/posix-cpu-timers.c | 16 +++++++++-------
+ kernel/sched.c | 4 ++--
+ kernel/sched_rt.c | 5 +++--
+ kernel/signal.c | 2 +-
+ kernel/sys.c | 3 +--
+ 7 files changed, 23 insertions(+), 19 deletions(-)
+
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -822,6 +822,8 @@ void __cleanup_sighand(struct sighand_st
+ */
+ static void posix_cpu_timers_init_group(struct signal_struct *sig)
+ {
++ unsigned long cpu_limit;
++
+ /* Thread group counters. */
+ thread_group_cputime_init(sig);
+
+@@ -836,9 +838,9 @@ static void posix_cpu_timers_init_group(
+ sig->cputime_expires.virt_exp = cputime_zero;
+ sig->cputime_expires.sched_exp = 0;
+
+- if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
+- sig->cputime_expires.prof_exp =
+- secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
++ cpu_limit = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
++ if (cpu_limit != RLIM_INFINITY) {
++ sig->cputime_expires.prof_exp = secs_to_cputime(cpu_limit);
+ sig->cputimer.running = 1;
+ }
+
+@@ -1028,7 +1030,7 @@ static struct task_struct *copy_process(
+ #endif
+ retval = -EAGAIN;
+ if (atomic_read(&p->real_cred->user->processes) >=
+- p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
++ task_rlim_get_cur(p, RLIMIT_NPROC)) {
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
+ p->real_cred->user != INIT_USER)
+ goto bad_fork_free;
+--- a/kernel/perf_event.c
++++ b/kernel/perf_event.c
+@@ -2420,7 +2420,7 @@ static int perf_mmap(struct file *file,
+ if (user_locked > user_lock_limit)
+ extra = user_locked - user_lock_limit;
+
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK);
+ lock_limit >>= PAGE_SHIFT;
+ locked = vma->vm_mm->locked_vm + extra;
+
+--- a/kernel/posix-cpu-timers.c
++++ b/kernel/posix-cpu-timers.c
+@@ -640,7 +640,7 @@ static void arm_timer(struct k_itimer *t
+ if (expires_le(sig->it[CPUCLOCK_PROF].expires,
+ exp->cpu))
+ break;
+- i = sig->rlim[RLIMIT_CPU].rlim_cur;
++ i = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
+ if (i != RLIM_INFINITY &&
+ i <= cputime_to_secs(exp->cpu))
+ break;
+@@ -1032,9 +1032,10 @@ static void check_thread_timers(struct t
+ /*
+ * Check for the special case thread timers.
+ */
+- soft = sig->rlim[RLIMIT_RTTIME].rlim_cur;
++ soft = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].rlim_cur);
+ if (soft != RLIM_INFINITY) {
+- unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max;
++ unsigned long hard = ACCESS_ONCE(sig->rlim[RLIMIT_RTTIME].
++ rlim_max);
+
+ if (hard != RLIM_INFINITY &&
+ tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
+@@ -1122,7 +1123,7 @@ static void check_process_timers(struct
+ unsigned long long sum_sched_runtime, sched_expires;
+ struct list_head *timers = sig->cpu_timers;
+ struct task_cputime cputime;
+- unsigned long cpu_cur_lim = sig->rlim[RLIMIT_CPU].rlim_cur;
++ unsigned long cpu_cur_lim = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
+
+ /*
+ * Don't sample the current process CPU clocks if there are no timers.
+@@ -1198,7 +1199,8 @@ static void check_process_timers(struct
+
+ if (cpu_cur_lim != RLIM_INFINITY) {
+ unsigned long psecs = cputime_to_secs(ptime);
+- unsigned long hard = sig->rlim[RLIMIT_CPU].rlim_max;
++ unsigned long hard =
++ ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_max);
+ cputime_t x;
+ if (psecs >= hard) {
+ /*
+@@ -1385,7 +1387,7 @@ static inline int fastpath_timer_check(s
+ return 1;
+ }
+
+- return sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY;
++ return ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur) != RLIM_INFINITY;
+ }
+
+ /*
+@@ -1483,7 +1485,7 @@ void set_process_cpu_timer(struct task_s
+ * If the RLIMIT_CPU timer will expire before the
+ * ITIMER_PROF timer, we have nothing else to do.
+ */
+- if (tsk->signal->rlim[RLIMIT_CPU].rlim_cur
++ if (task_rlim_get_cur(tsk, RLIMIT_CPU)
+ < cputime_to_secs(*newval))
+ return;
+ }
+--- a/kernel/sched.c
++++ b/kernel/sched.c
+@@ -6072,7 +6072,7 @@ int can_nice(const struct task_struct *p
+ /* convert nice value [19,-20] to rlimit style value [1,40] */
+ int nice_rlim = 20 - nice;
+
+- return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur ||
++ return (nice_rlim <= task_rlim_get_cur(p, RLIMIT_NICE) ||
+ capable(CAP_SYS_NICE));
+ }
+
+@@ -6257,7 +6257,7 @@ recheck:
+
+ if (!lock_task_sighand(p, &flags))
+ return -ESRCH;
+- rlim_rtprio = p->signal->rlim[RLIMIT_RTPRIO].rlim_cur;
++ rlim_rtprio = task_rlim_get_cur(p, RLIMIT_RTPRIO);
+ unlock_task_sighand(p, &flags);
+
+ /* can't set/change the rt policy */
+--- a/kernel/sched_rt.c
++++ b/kernel/sched_rt.c
+@@ -1683,8 +1683,9 @@ static void watchdog(struct rq *rq, stru
+ if (!p->signal)
+ return;
+
+- soft = p->signal->rlim[RLIMIT_RTTIME].rlim_cur;
+- hard = p->signal->rlim[RLIMIT_RTTIME].rlim_max;
++ /* max may change after cur was read, this will be fixed next tick */
++ soft = task_rlim_get_cur(p, RLIMIT_RTTIME);
++ hard = task_rlim_get_max(p, RLIMIT_RTTIME);
+
+ if (soft != RLIM_INFINITY) {
+ unsigned long next;
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -209,7 +209,7 @@ static struct sigqueue *__sigqueue_alloc
+ atomic_inc(&user->sigpending);
+ if (override_rlimit ||
+ atomic_read(&user->sigpending) <=
+- t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
++ task_rlim_get_cur(t, RLIMIT_SIGPENDING))
+ q = kmem_cache_alloc(sigqueue_cachep, flags);
+ if (unlikely(q == NULL)) {
+ atomic_dec(&user->sigpending);
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -572,8 +572,7 @@ static int set_user(struct cred *new)
+ return -EINVAL;
+ }
+
+- if (atomic_read(&new_user->processes) >=
+- current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
++ if (atomic_read(&new_user->processes) >= rlim_get_cur(RLIMIT_NPROC) &&
+ new_user != INIT_USER) {
+ free_uid(new_user);
+ return -EAGAIN;
diff --git a/patches.suse/rlim-0020-misc-use-helpers-for-rlimits.patch b/patches.suse/rlim-0020-misc-use-helpers-for-rlimits.patch
new file mode 100644
index 0000000000..8ebd3174c1
--- /dev/null
+++ b/patches.suse/rlim-0020-misc-use-helpers-for-rlimits.patch
@@ -0,0 +1,75 @@
+From 5d1db5104154014e63d3d1ea52f29599aca44e01 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Sat, 14 Nov 2009 17:28:10 +0100
+Subject: [PATCH 20/25] misc: use helpers for rlimits
+References: FATE#305733
+
+Make sure compiler won't do weird things with limits. E.g. fetching
+them twice may return 2 different values after writable limits are
+implemented.
+
+I.e. either use newly added rlimit helpers or ACCESS_ONCE if not
+applicable.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Roland Dreier <rolandd@cisco.com>
+Cc: Sean Hefty <sean.hefty@intel.com>
+Cc: Hal Rosenstock <hal.rosenstock@gmail.com>
+Cc: linux-rdma@vger.kernel.org
+---
+ drivers/infiniband/core/umem.c | 2 +-
+ drivers/infiniband/hw/ipath/ipath_user_pages.c | 3 +--
+ ipc/mqueue.c | 2 +-
+ ipc/shm.c | 3 +--
+ 4 files changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/infiniband/core/umem.c
++++ b/drivers/infiniband/core/umem.c
+@@ -136,7 +136,7 @@ struct ib_umem *ib_umem_get(struct ib_uc
+ down_write(&current->mm->mmap_sem);
+
+ locked = npages + current->mm->locked_vm;
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+
+ if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
+ ret = -ENOMEM;
+--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
++++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
+@@ -59,8 +59,7 @@ static int __get_user_pages(unsigned lon
+ size_t got;
+ int ret;
+
+- lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
+- PAGE_SHIFT;
++ lock_limit = rlim_get_cur(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+
+ if (num_pages > lock_limit) {
+ ret = -ENOMEM;
+--- a/ipc/mqueue.c
++++ b/ipc/mqueue.c
+@@ -153,7 +153,7 @@ static struct inode *mqueue_get_inode(st
+ spin_lock(&mq_lock);
+ if (u->mq_bytes + mq_bytes < u->mq_bytes ||
+ u->mq_bytes + mq_bytes >
+- p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
++ task_rlim_get_cur(p, RLIMIT_MSGQUEUE)) {
+ spin_unlock(&mq_lock);
+ goto out_inode;
+ }
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -761,8 +761,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
+ if (euid != shp->shm_perm.uid &&
+ euid != shp->shm_perm.cuid)
+ goto out_unlock;
+- if (cmd == SHM_LOCK &&
+- !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
++ if (cmd == SHM_LOCK && !rlim_get_cur(RLIMIT_MEMLOCK))
+ goto out_unlock;
+ }
+
diff --git a/patches.suse/rlim-0021-core-rename-setrlimit-to-do_setrlimit.patch b/patches.suse/rlim-0021-core-rename-setrlimit-to-do_setrlimit.patch
new file mode 100644
index 0000000000..05ebb91186
--- /dev/null
+++ b/patches.suse/rlim-0021-core-rename-setrlimit-to-do_setrlimit.patch
@@ -0,0 +1,63 @@
+From 6ddb0d889e3c1f2941e1266d0134ba5b8c6f5d89 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Mon, 9 Nov 2009 16:11:49 +0100
+Subject: [PATCH 21/25] core: rename setrlimit to do_setrlimit
+References: FATE#305733
+
+Rename it so that it makes more sense in the field of syscalls
+(i.e. do_* is used for functions called by syscall wrappers but
+also when called from other paths).
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+---
+ fs/proc/base.c | 2 +-
+ include/linux/resource.h | 2 +-
+ kernel/sys.c | 4 ++--
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -576,7 +576,7 @@ static ssize_t limits_write(struct file
+ goto put_task;
+ }
+
+- ret = setrlimit(task, i, &new_rlimit);
++ ret = do_setrlimit(task, i, &new_rlimit);
+ if (ret)
+ count = ret;
+
+--- a/include/linux/resource.h
++++ b/include/linux/resource.h
+@@ -71,7 +71,7 @@ struct rlimit {
+ #include <asm/resource.h>
+
+ int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
+-int setrlimit(struct task_struct *tsk, unsigned int resource,
++int do_setrlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim);
+
+ #endif
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1238,7 +1238,7 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned
+ #endif
+
+ /* make sure you are allowed to change @tsk limits before calling this */
+-int setrlimit(struct task_struct *tsk, unsigned int resource,
++int do_setrlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim)
+ {
+ struct rlimit *old_rlim;
+@@ -1307,7 +1307,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+ return -EINVAL;
+ if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
+ return -EFAULT;
+- return setrlimit(current, resource, &new_rlim);
++ return do_setrlimit(current, resource, &new_rlim);
+ }
+
+ /*
diff --git a/patches.suse/rlim-0022-core-implement-getprlimit-and-setprlimit-syscalls.patch b/patches.suse/rlim-0022-core-implement-getprlimit-and-setprlimit-syscalls.patch
new file mode 100644
index 0000000000..038e7508ea
--- /dev/null
+++ b/patches.suse/rlim-0022-core-implement-getprlimit-and-setprlimit-syscalls.patch
@@ -0,0 +1,142 @@
+From df372707d825aca81f81b258d7ab6ab9c400ffa5 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Tue, 20 Oct 2009 00:54:12 +0000
+Subject: [PATCH 22/25] core: implement getprlimit and setprlimit syscalls
+References: FATE#305733
+
+This patch adds the code to support the sys_setprlimit and set_getprlimit
+syscalls which modify the rlim values of a selected process.
+
+Based on Neil's work. Thank him.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: Neil Horman <nhorman@tuxdriver.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+---
+ include/linux/syscalls.h | 4 ++
+ kernel/sys.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 90 insertions(+)
+
+--- a/include/linux/syscalls.h
++++ b/include/linux/syscalls.h
+@@ -702,11 +702,15 @@ asmlinkage long sys_newuname(struct new_
+
+ asmlinkage long sys_getrlimit(unsigned int resource,
+ struct rlimit __user *rlim);
++asmlinkage long sys_getprlimit(pid_t pid, unsigned int resource,
++ struct rlimit __user *rlim);
+ #if defined(COMPAT_RLIM_OLD_INFINITY) || !(defined(CONFIG_IA64))
+ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim);
+ #endif
+ asmlinkage long sys_setrlimit(unsigned int resource,
+ struct rlimit __user *rlim);
++asmlinkage long sys_setprlimit(pid_t pid, unsigned int resource,
++ struct rlimit __user *rlim);
+ asmlinkage long sys_getrusage(int who, struct rusage __user *ru);
+ asmlinkage long sys_umask(int mask);
+
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -1212,6 +1212,61 @@ SYSCALL_DEFINE2(getrlimit, unsigned int,
+ }
+ }
+
++static int check_prlimit_permission(struct task_struct *task)
++{
++ const struct cred *cred = current_cred(), *tcred;
++ int ret = 0;
++
++ rcu_read_lock();
++ tcred = __task_cred(task);
++ if ((cred->uid != tcred->euid ||
++ cred->uid != tcred->suid ||
++ cred->uid != tcred->uid ||
++ cred->gid != tcred->egid ||
++ cred->gid != tcred->sgid ||
++ cred->gid != tcred->gid) &&
++ !capable(CAP_SYS_RESOURCE)) {
++ ret = -EPERM;
++ }
++ rcu_read_unlock();
++ return ret;
++}
++
++SYSCALL_DEFINE3(getprlimit, pid_t, pid, unsigned int, resource,
++ struct rlimit __user *, rlim)
++{
++ struct rlimit val;
++ struct task_struct *tsk;
++ int ret;
++
++ if (resource >= RLIM_NLIMITS)
++ return -EINVAL;
++
++ read_lock(&tasklist_lock);
++
++ tsk = find_task_by_vpid(pid);
++ if (!tsk || !tsk->sighand) {
++ ret = -ESRCH;
++ goto err_unlock;
++ }
++
++ ret = check_prlimit_permission(tsk);
++ if (ret)
++ goto err_unlock;
++
++ task_lock(tsk->group_leader);
++ val = tsk->signal->rlim[resource];
++ task_unlock(tsk->group_leader);
++
++ read_unlock(&tasklist_lock);
++
++ return copy_to_user(rlim, &val, sizeof(*rlim)) ? -EFAULT : 0;
++err_unlock:
++ read_unlock(&tasklist_lock);
++ return ret;
++}
++
++
+ #ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
+
+ /*
+@@ -1310,6 +1365,37 @@ SYSCALL_DEFINE2(setrlimit, unsigned int,
+ return do_setrlimit(current, resource, &new_rlim);
+ }
+
++SYSCALL_DEFINE3(setprlimit, pid_t, pid, unsigned int, resource,
++ struct rlimit __user *, rlim)
++{
++ struct task_struct *tsk;
++ struct rlimit new_rlim;
++ int ret;
++
++ if (resource >= RLIM_NLIMITS)
++ return -EINVAL;
++
++ if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
++ return -EFAULT;
++
++ rcu_read_lock();
++ tsk = find_task_by_vpid(pid);
++ if (!tsk) {
++ rcu_read_unlock();
++ return -ESRCH;
++ }
++ get_task_struct(tsk);
++ rcu_read_unlock();
++
++ ret = check_prlimit_permission(tsk);
++ if (!ret)
++ ret = do_setrlimit(tsk, resource, &new_rlim);
++
++ put_task_struct(tsk);
++
++ return ret;
++}
++
+ /*
+ * It would make sense to put struct rusage in the task_struct,
+ * except that would make the task_struct be *really big*. After
diff --git a/patches.suse/rlim-0023-unistd-add-__NR_-get-set-prlimit-syscall-numbers.patch b/patches.suse/rlim-0023-unistd-add-__NR_-get-set-prlimit-syscall-numbers.patch
new file mode 100644
index 0000000000..8d86afdad1
--- /dev/null
+++ b/patches.suse/rlim-0023-unistd-add-__NR_-get-set-prlimit-syscall-numbers.patch
@@ -0,0 +1,76 @@
+From 09c2dd540df181677fe3755693afb42230dad4a0 Mon Sep 17 00:00:00 2001
+From: Neil Horman <nhorman@tuxdriver.com>
+Date: Tue, 20 Oct 2009 00:55:03 +0000
+Subject: [PATCH 23/25] unistd: add __NR_[get|set]prlimit syscall numbers
+References: FATE#305733
+
+Add __NR_[get|set]prlimit syscall numbers to asm-generic. Add them
+also to asm-x86.
+
+Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+---
+ arch/x86/include/asm/unistd_32.h | 4 +++-
+ arch/x86/include/asm/unistd_64.h | 4 ++++
+ arch/x86/kernel/syscall_table_32.S | 2 ++
+ include/asm-generic/unistd.h | 6 +++++-
+ 4 files changed, 14 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/include/asm/unistd_32.h
++++ b/arch/x86/include/asm/unistd_32.h
+@@ -342,10 +342,12 @@
+ #define __NR_pwritev 334
+ #define __NR_rt_tgsigqueueinfo 335
+ #define __NR_perf_event_open 336
++#define __NR_getprlimit 337
++#define __NR_setprlimit 338
+
+ #ifdef __KERNEL__
+
+-#define NR_syscalls 337
++#define NR_syscalls 339
+
+ #define __ARCH_WANT_IPC_PARSE_VERSION
+ #define __ARCH_WANT_OLD_READDIR
+--- a/arch/x86/include/asm/unistd_64.h
++++ b/arch/x86/include/asm/unistd_64.h
+@@ -661,6 +661,10 @@ __SYSCALL(__NR_pwritev, sys_pwritev)
+ __SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
+ #define __NR_perf_event_open 298
+ __SYSCALL(__NR_perf_event_open, sys_perf_event_open)
++#define __NR_getprlimit 299
++__SYSCALL(__NR_getprlimit, sys_getprlimit)
++#define __NR_setprlimit 300
++__SYSCALL(__NR_setprlimit, sys_setprlimit)
+
+ #ifndef __NO_STUBS
+ #define __ARCH_WANT_OLD_READDIR
+--- a/arch/x86/kernel/syscall_table_32.S
++++ b/arch/x86/kernel/syscall_table_32.S
+@@ -336,3 +336,5 @@ ENTRY(sys_call_table)
+ .long sys_pwritev
+ .long sys_rt_tgsigqueueinfo /* 335 */
+ .long sys_perf_event_open
++ .long sys_getprlimit
++ .long sys_setprlimit
+--- a/include/asm-generic/unistd.h
++++ b/include/asm-generic/unistd.h
+@@ -622,9 +622,13 @@ __SYSCALL(__NR_move_pages, sys_move_page
+ __SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
+ #define __NR_perf_event_open 241
+ __SYSCALL(__NR_perf_event_open, sys_perf_event_open)
++#define __NR_getprlimit 242
++__SYSCALL(__NR_getprlimit, sys_getprlimit)
++#define __NR_setprlimit 243
++__SYSCALL(__NR_setprlimit, sys_setprlimit)
+
+ #undef __NR_syscalls
+-#define __NR_syscalls 242
++#define __NR_syscalls 244
+
+ /*
+ * All syscalls below here should go away really,
diff --git a/patches.suse/rlim-0024-COMPAT-add-get-put_compat_rlimit.patch b/patches.suse/rlim-0024-COMPAT-add-get-put_compat_rlimit.patch
new file mode 100644
index 0000000000..a96b3c5d85
--- /dev/null
+++ b/patches.suse/rlim-0024-COMPAT-add-get-put_compat_rlimit.patch
@@ -0,0 +1,105 @@
+From d1fc22e4e07d1ba9fcd4b37229bf7eea29946106 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Wed, 11 Nov 2009 17:21:37 +0100
+Subject: [PATCH 24/25] COMPAT: add get/put_compat_rlimit
+References: FATE#305733
+
+Extract those functions from compat_sys_[gs]etrlimit for later
+use with newly added rlimit syscalls.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+---
+ kernel/compat.c | 61 ++++++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 40 insertions(+), 21 deletions(-)
+
+--- a/kernel/compat.c
++++ b/kernel/compat.c
+@@ -274,6 +274,39 @@ asmlinkage long compat_sys_sigprocmask(i
+ return ret;
+ }
+
++static int get_compat_rlimit(struct rlimit *dst,
++ const struct compat_rlimit __user *src)
++{
++ if (!access_ok(VERIFY_READ, src, sizeof(*src)) ||
++ __get_user(dst->rlim_cur, &src->rlim_cur) ||
++ __get_user(dst->rlim_max, &src->rlim_max))
++ return -EFAULT;
++
++ if (dst->rlim_cur == COMPAT_RLIM_INFINITY)
++ dst->rlim_cur = RLIM_INFINITY;
++ if (dst->rlim_max == COMPAT_RLIM_INFINITY)
++ dst->rlim_max = RLIM_INFINITY;
++ return 0;
++}
++
++static int put_compat_rlimit(const struct rlimit *src,
++ struct compat_rlimit __user *dst)
++{
++ struct rlimit r = *src;
++
++ if (r.rlim_cur > COMPAT_RLIM_INFINITY)
++ r.rlim_cur = COMPAT_RLIM_INFINITY;
++ if (r.rlim_max > COMPAT_RLIM_INFINITY)
++ r.rlim_max = COMPAT_RLIM_INFINITY;
++
++ if (!access_ok(VERIFY_WRITE, dst, sizeof(*dst)) ||
++ __put_user(r.rlim_cur, &dst->rlim_cur) ||
++ __put_user(r.rlim_max, &dst->rlim_max))
++ return -EFAULT;
++
++ return 0;
++}
++
+ asmlinkage long compat_sys_setrlimit(unsigned int resource,
+ struct compat_rlimit __user *rlim)
+ {
+@@ -284,17 +317,12 @@ asmlinkage long compat_sys_setrlimit(uns
+ if (resource >= RLIM_NLIMITS)
+ return -EINVAL;
+
+- if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
+- __get_user(r.rlim_cur, &rlim->rlim_cur) ||
+- __get_user(r.rlim_max, &rlim->rlim_max))
+- return -EFAULT;
++ ret = get_compat_rlimit(&r, rlim);
++ if (ret)
++ return ret;
+
+- if (r.rlim_cur == COMPAT_RLIM_INFINITY)
+- r.rlim_cur = RLIM_INFINITY;
+- if (r.rlim_max == COMPAT_RLIM_INFINITY)
+- r.rlim_max = RLIM_INFINITY;
+ set_fs(KERNEL_DS);
+- ret = sys_setrlimit(resource, (struct rlimit __user *) &r);
++ ret = sys_setrlimit(resource, (struct rlimit __force __user *)&r);
+ set_fs(old_fs);
+ return ret;
+ }
+@@ -336,19 +364,10 @@ asmlinkage long compat_sys_getrlimit (un
+ mm_segment_t old_fs = get_fs();
+
+ set_fs(KERNEL_DS);
+- ret = sys_getrlimit(resource, (struct rlimit __user *) &r);
++ ret = sys_getrlimit(resource, (struct rlimit __force __user *)&r);
+ set_fs(old_fs);
+- if (!ret) {
+- if (r.rlim_cur > COMPAT_RLIM_INFINITY)
+- r.rlim_cur = COMPAT_RLIM_INFINITY;
+- if (r.rlim_max > COMPAT_RLIM_INFINITY)
+- r.rlim_max = COMPAT_RLIM_INFINITY;
+-
+- if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
+- __put_user(r.rlim_cur, &rlim->rlim_cur) ||
+- __put_user(r.rlim_max, &rlim->rlim_max))
+- return -EFAULT;
+- }
++ if (!ret)
++ ret = put_compat_rlimit(&r, rlim);
+ return ret;
+ }
+
diff --git a/patches.suse/rlim-0025-x86-add-ia32-compat-prlimit-syscalls.patch b/patches.suse/rlim-0025-x86-add-ia32-compat-prlimit-syscalls.patch
new file mode 100644
index 0000000000..e1550709c5
--- /dev/null
+++ b/patches.suse/rlim-0025-x86-add-ia32-compat-prlimit-syscalls.patch
@@ -0,0 +1,69 @@
+From b24afabe9dcf3ecaba66ca98f5929b3b94535617 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@novell.com>
+Date: Wed, 11 Nov 2009 17:28:06 +0100
+Subject: [PATCH 25/25] x86: add ia32 compat prlimit syscalls
+References: FATE#305733
+
+To support 32/64-bit compatibility (rlimit structure contains 2 longs)
+for prlimit syscalls, add compat wrappers for them.
+
+Signed-off-by: Jiri Slaby <jslaby@novell.com>
+Cc: James Morris <jmorris@namei.org>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+---
+ arch/x86/ia32/ia32entry.S | 2 ++
+ kernel/compat.c | 32 ++++++++++++++++++++++++++++++++
+ 2 files changed, 34 insertions(+)
+
+--- a/arch/x86/ia32/ia32entry.S
++++ b/arch/x86/ia32/ia32entry.S
+@@ -841,4 +841,6 @@ ia32_sys_call_table:
+ .quad compat_sys_pwritev
+ .quad compat_sys_rt_tgsigqueueinfo /* 335 */
+ .quad sys_perf_event_open
++ .quad compat_sys_getprlimit
++ .quad compat_sys_setprlimit
+ ia32_syscall_end:
+--- a/kernel/compat.c
++++ b/kernel/compat.c
+@@ -371,6 +371,38 @@ asmlinkage long compat_sys_getrlimit (un
+ return ret;
+ }
+
++asmlinkage long compat_sys_setprlimit(pid_t pid, unsigned int resource,
++ struct compat_rlimit __user *rlim)
++{
++ mm_segment_t old_fs = get_fs ();
++ struct rlimit r;
++ int ret;
++
++ ret = get_compat_rlimit(&r, rlim);
++ if (ret)
++ return ret;
++
++ set_fs(KERNEL_DS);
++ ret = sys_setprlimit(pid, resource, (struct rlimit __force __user *)&r);
++ set_fs(old_fs);
++ return ret;
++}
++
++asmlinkage long compat_sys_getprlimit(pid_t pid, unsigned int resource,
++ struct compat_rlimit __user *rlim)
++{
++ mm_segment_t old_fs = get_fs();
++ struct rlimit r;
++ int ret;
++
++ set_fs(KERNEL_DS);
++ ret = sys_getprlimit(pid, resource, (struct rlimit __force __user *)&r);
++ set_fs(old_fs);
++ if (!ret)
++ ret = put_compat_rlimit(&r, rlim);
++ return ret;
++}
++
+ int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
+ {
+ if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
diff --git a/patches.suse/stack-unwind b/patches.suse/stack-unwind
index 18d31cf26d..27452b1ec4 100644
--- a/patches.suse/stack-unwind
+++ b/patches.suse/stack-unwind
@@ -552,7 +552,7 @@ Update Jan 17 2009 jeffm:
+#define EH_FRAME \
+ /* Unwind data binary search table */ \
+ . = ALIGN(8); \
-+ .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \
++ .eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_unwind_hdr) = .; \
+ *(.eh_frame_hdr) \
+ VMLINUX_SYMBOL(__end_unwind_hdr) = .; \
@@ -561,7 +561,7 @@ Update Jan 17 2009 jeffm:
+ . = ALIGN(8); \
+ .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_unwind) = .; \
-+ *(.eh_frame) \
++ *(.eh_frame) \
+ VMLINUX_SYMBOL(__end_unwind) = .; \
+ }
+#else
diff --git a/rpm/macros.kernel-source b/rpm/macros.kernel-source
index 4d3f69e5e3..3b207550bd 100644
--- a/rpm/macros.kernel-source
+++ b/rpm/macros.kernel-source
@@ -24,6 +24,7 @@
echo "%%global flavors_to_build${flavors_to_build:-%%nil}" \
echo "%%{expand:%%(test -z '%flavors_to_build' && echo %%%%internal_kmp_error)}" \
echo "%%global kernel_source() /usr/src/linux-obj/%_target_cpu/%%%%{1}" \
+ echo "%%global kernel_module_package_moddir() updates" \
\
echo "%package -n %{-n*}%{!-n:%name}-kmp-_dummy_" \
echo "Version: %version" \
diff --git a/scripts/sequence-patch.sh b/scripts/sequence-patch.sh
index 011b4fe8b8..e848cc45c3 100755
--- a/scripts/sequence-patch.sh
+++ b/scripts/sequence-patch.sh
@@ -465,7 +465,7 @@ echo "[ Tree: $PATCH_DIR ]"
if test -e supported.conf; then
echo "[ Generating Module.supported ]"
- scripts/guards external < supported.conf > $PATCH_DIR/Module.supported
+ scripts/guards base external < supported.conf > $PATCH_DIR/Module.supported
fi
[ $# -gt 0 ] && exit $status
diff --git a/series.conf b/series.conf
index e62e7b2ffa..d0d6cc12c6 100644
--- a/series.conf
+++ b/series.conf
@@ -91,6 +91,7 @@
patches.suse/kvm-as-kmp
patches.suse/export-release_open_intent
patches.suse/export-security_inode_permission
+ patches.suse/export-sync_page_range
########################################################
# Bug workarounds for binutils
@@ -116,6 +117,34 @@
patches.fixes/seccomp-disable-tsc-option
patches.suse/hung_task_timeout-configurable-default
+ # writable limits
+ patches.suse/rlim-0001-SECURITY-selinux-fix-update_rlimit_cpu-parameter.patch
+ patches.suse/rlim-0002-SECURITY-add-task_struct-to-setrlimit.patch
+ patches.suse/rlim-0003-core-add-task_struct-to-update_rlimit_cpu.patch
+ patches.suse/rlim-0004-sys_setrlimit-make-sure-rlim_max-never-grows.patch
+ patches.suse/rlim-0005-core-split-sys_setrlimit.patch
+ patches.suse/rlim-0006-core-allow-setrlimit-to-non-current-tasks.patch
+ patches.suse/rlim-0007-core-optimize-setrlimit-for-current-task.patch
+ patches.suse/rlim-0008-FS-proc-make-limits-writable.patch
+ patches.suse/rlim-0009-core-posix-cpu-timers-cleanup-rlimits-usage.patch
+ patches.suse/rlim-0010-core-do-security-check-under-task_lock.patch
+ patches.suse/rlim-0011-resource-add-helpers-for-fetching-rlimits.patch
+ patches.suse/rlim-0012-IA64-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0013-PPC-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0014-S390-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0015-SPARC-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0016-X86-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0017-FS-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0018-MM-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0019-core-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0020-misc-use-helpers-for-rlimits.patch
+ patches.suse/rlim-0021-core-rename-setrlimit-to-do_setrlimit.patch
+ patches.suse/rlim-0022-core-implement-getprlimit-and-setprlimit-syscalls.patch
+ patches.suse/rlim-0023-unistd-add-__NR_-get-set-prlimit-syscall-numbers.patch
+ patches.suse/rlim-0024-COMPAT-add-get-put_compat_rlimit.patch
+ patches.suse/rlim-0025-x86-add-ia32-compat-prlimit-syscalls.patch
+
+
########################################################
# Architecture-specific patches. These used to be all
# at the end of series.conf, but since we don't do
@@ -403,7 +432,8 @@
+needs_update patches.drivers/mpt-fusion-4.16.00.00-update
patches.drivers/hpsa
- patches.fixes/scsi-skip-nonscsi-device-for-dma
+ patches.fixes/scsi-fix-bug-with-dma-maps-on-nested-scsi-objects
+ patches.fixes/scsi-introduce-helper-function-for-blocking-eh
patches.fixes/scsi-dh-queuedata-accessors
patches.fixes/scsi-dh-alua-retry-UA
patches.fixes/scsi-add-tgps-setting
@@ -416,6 +446,7 @@
patches.fixes/scsi-check-host-lookup-failure
patches.drivers/aacraid-24701-update
+ patches.drivers/megaraid-04.12-update
# Remaining SCSI patches (garloff)
patches.suse/scsi-error-test-unit-ready-timeout
@@ -442,6 +473,18 @@
patches.fixes/tg3-fix-default-wol.patch
patches.drivers/ehea-modinfo.patch
+needs_update-32 patches.drivers/tg3_libphy_workaround
+ patches.drivers/igb-add-support-for-82576NS-SerDes-adapter.patch
+
+ # entropy FATE##307517
+ patches.drivers/bnx2-entropy-source.patch
+ patches.drivers/e1000-entropy-source.patch
+ patches.drivers/e1000e-entropy-source.patch
+ patches.drivers/igb-entropy-source.patch
+ patches.drivers/ixgbe-entropy-source.patch
+ patches.drivers/tg3-entropy-source.patch
+
+ patches.drivers/phy-broadcom-bug-fixes-for-sp1.patch
+ patches.drivers/tg3-update-version-to-3.104.patch
#FCOE update (fate#306857, fate#306859, bnc#551175)
patches.suse/libfc-fix-typo-in-retry-check-on-received-prli.patch