--- /dev/null
+From b0cf4dfb7cd21556efd9a6a67edcba0840b4d98d Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 7 Apr 2010 20:55:47 -0700
+Subject: 3c503: Fix IRQ probing
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit b0cf4dfb7cd21556efd9a6a67edcba0840b4d98d upstream.
+
+The driver attempts to select an IRQ for the NIC automatically by
+testing which of the supported IRQs are available and then probing
+each available IRQ with probe_irq_{on,off}(). There are obvious race
+conditions here, besides which:
+1. The test for availability is done by passing a NULL handler, which
+ now always returns -EINVAL, thus the device cannot be opened:
+ <http://bugs.debian.org/566522>
+2. probe_irq_off() will report only the first ISA IRQ handled,
+ potentially leading to a false negative.
+
+There was another bug that meant it ignored all error codes from
+request_irq() except -EBUSY, so it would 'succeed' despite this
+(possibly causing conflicts with other ISA devices). This was fixed
+by ab08999d6029bb2c79c16be5405d63d2bedbdfea 'WARNING: some
+request_irq() failures ignored in el2_open()', which exposed bug 1.
+
+This patch:
+1. Replaces the use of probe_irq_{on,off}() with a real interrupt handler
+2. Adds a delay before checking the interrupt-seen flag
+3. Disables interrupts on all failure paths
+4. Distinguishes error codes from the second request_irq() call,
+ consistently with the first
+
+Compile-tested only.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/3c503.c | 42 ++++++++++++++++++++++++++++++------------
+ 1 file changed, 30 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/3c503.c
++++ b/drivers/net/3c503.c
+@@ -380,6 +380,12 @@ out:
+ return retval;
+ }
+
++static irqreturn_t el2_probe_interrupt(int irq, void *seen)
++{
++ *(bool *)seen = true;
++ return IRQ_HANDLED;
++}
++
+ static int
+ el2_open(struct net_device *dev)
+ {
+@@ -391,23 +397,35 @@ el2_open(struct net_device *dev)
+
+ outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */
+ do {
+- retval = request_irq(*irqp, NULL, 0, "bogus", dev);
+- if (retval >= 0) {
++ bool seen;
++
++ retval = request_irq(*irqp, el2_probe_interrupt, 0,
++ dev->name, &seen);
++ if (retval == -EBUSY)
++ continue;
++ if (retval < 0)
++ goto err_disable;
++
+ /* Twinkle the interrupt, and check if it's seen. */
+- unsigned long cookie = probe_irq_on();
++ seen = false;
++ smp_wmb();
+ outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
+ outb_p(0x00, E33G_IDCFR);
+- if (*irqp == probe_irq_off(cookie) && /* It's a good IRQ line! */
+- ((retval = request_irq(dev->irq = *irqp,
+- eip_interrupt, 0,
+- dev->name, dev)) == 0))
+- break;
+- } else {
+- if (retval != -EBUSY)
+- return retval;
+- }
++ msleep(1);
++ free_irq(*irqp, el2_probe_interrupt);
++ if (!seen)
++ continue;
++
++ retval = request_irq(dev->irq = *irqp, eip_interrupt, 0,
++ dev->name, dev);
++ if (retval == -EBUSY)
++ continue;
++ if (retval < 0)
++ goto err_disable;
+ } while (*++irqp);
++
+ if (*irqp == 0) {
++ err_disable:
+ outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
+ return -EAGAIN;
+ }
--- /dev/null
+From c9a8bbb7704cbf515c0fc68970abbe4e91d68521 Mon Sep 17 00:00:00 2001
+From: Rafael J. Wysocki <rjw@sisk.pl>
+Date: Tue, 8 Jun 2010 10:49:45 +0200
+Subject: ACPI / ACPICA: Avoid writing full enable masks to GPE registers
+
+From: Rafael J. Wysocki <rjw@sisk.pl>
+
+commit c9a8bbb7704cbf515c0fc68970abbe4e91d68521 upstream.
+
+ACPICA uses acpi_hw_write_gpe_enable_reg() to re-enable a GPE after
+an event signaled by it has been handled. However, this function
+writes the entire GPE enable mask to the GPE's enable register which
+may not be correct. Namely, if one of the other GPEs in the same
+register was previously enabled by acpi_enable_gpe() and subsequently
+disabled using acpi_set_gpe(), acpi_hw_write_gpe_enable_reg() will
+re-enable it along with the target GPE.
+
+To fix this issue rework acpi_hw_write_gpe_enable_reg() so that it
+calls acpi_hw_low_set_gpe() with a special action value,
+ACPI_GPE_COND_ENABLE, that will make it only enable the GPE if the
+corresponding bit in its register's enable_for_run mask is set.
+
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/acpica/hwgpe.c | 18 +++++-------------
+ include/acpi/actypes.h | 1 +
+ 2 files changed, 6 insertions(+), 13 deletions(-)
+
+--- a/drivers/acpi/acpica/hwgpe.c
++++ b/drivers/acpi/acpica/hwgpe.c
+@@ -118,6 +118,10 @@ acpi_hw_low_set_gpe(struct acpi_gpe_even
+ register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
+ gpe_register_info);
+ switch (action) {
++ case ACPI_GPE_COND_ENABLE:
++ if (!(register_bit & gpe_register_info->enable_for_run))
++ return (AE_BAD_PARAMETER);
++
+ case ACPI_GPE_ENABLE:
+ ACPI_SET_BIT(enable_mask, register_bit);
+ break;
+@@ -154,23 +158,11 @@ acpi_hw_low_set_gpe(struct acpi_gpe_even
+ acpi_status
+ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info)
+ {
+- struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
+
+ ACPI_FUNCTION_ENTRY();
+
+- /* Get the info block for the entire GPE register */
+-
+- gpe_register_info = gpe_event_info->register_info;
+- if (!gpe_register_info) {
+- return (AE_NOT_EXIST);
+- }
+-
+- /* Write the entire GPE (runtime) enable register */
+-
+- status = acpi_hw_write(gpe_register_info->enable_for_run,
+- &gpe_register_info->enable_address);
+-
++ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE);
+ return (status);
+ }
+
+--- a/include/acpi/actypes.h
++++ b/include/acpi/actypes.h
+@@ -665,6 +665,7 @@ typedef u32 acpi_event_status;
+
+ #define ACPI_GPE_ENABLE 0
+ #define ACPI_GPE_DISABLE 1
++#define ACPI_GPE_COND_ENABLE 2
+
+ /*
+ * GPE info flags - Per GPE
--- /dev/null
+From ce43ace02320a3fb9614ddb27edc3a8700d68b26 Mon Sep 17 00:00:00 2001
+From: Rafael J. Wysocki <rjw@sisk.pl>
+Date: Tue, 8 Jun 2010 10:50:20 +0200
+Subject: ACPI / ACPICA: Fix GPE initialization
+
+From: Rafael J. Wysocki <rjw@sisk.pl>
+
+commit ce43ace02320a3fb9614ddb27edc3a8700d68b26 upstream.
+
+While developing the GPE reference counting code we overlooked the
+fact that acpi_ev_update_gpes() could have enabled GPEs before
+acpi_ev_initialize_gpe_block() was called. As a result, some GPEs
+are enabled twice during the initialization.
+
+To fix this issue avoid calling acpi_enable_gpe() from
+acpi_ev_initialize_gpe_block() for the GPEs that have nonzero
+runtime reference counters.
+
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Len Brown <len.brown@intel.com>
+
+---
+ drivers/acpi/acpica/evgpeblk.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/drivers/acpi/acpica/evgpeblk.c
++++ b/drivers/acpi/acpica/evgpeblk.c
+@@ -1023,6 +1023,19 @@ acpi_ev_initialize_gpe_block(struct acpi
+ /* Get the info block for this particular GPE */
+ gpe_index = (acpi_size)i * ACPI_GPE_REGISTER_WIDTH + j;
+ gpe_event_info = &gpe_block->event_info[gpe_index];
++ gpe_number = gpe_index + gpe_block->block_base_number;
++
++ /*
++ * If the GPE has already been enabled for runtime
++ * signaling, make sure it remains enabled, but do not
++ * increment its reference counter.
++ */
++ if (gpe_event_info->runtime_count) {
++ acpi_set_gpe(gpe_device, gpe_number,
++ ACPI_GPE_ENABLE);
++ gpe_enabled_count++;
++ continue;
++ }
+
+ if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
+ wake_gpe_count++;
+@@ -1033,7 +1046,6 @@ acpi_ev_initialize_gpe_block(struct acpi
+ if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD))
+ continue;
+
+- gpe_number = gpe_index + gpe_block->block_base_number;
+ status = acpi_enable_gpe(gpe_device, gpe_number,
+ ACPI_GPE_TYPE_RUNTIME);
+ if (ACPI_FAILURE(status))
--- /dev/null
+From fd247447c1d94a79d5cfc647430784306b3a8323 Mon Sep 17 00:00:00 2001
+From: Rafael J. Wysocki <rjw@sisk.pl>
+Date: Tue, 8 Jun 2010 10:49:08 +0200
+Subject: ACPI / ACPICA: Fix low-level GPE manipulation code
+
+From: Rafael J. Wysocki <rjw@sisk.pl>
+
+commit fd247447c1d94a79d5cfc647430784306b3a8323 upstream.
+
+ACPICA uses acpi_ev_enable_gpe() for enabling GPEs at the low level,
+which is incorrect, because this function only enables the GPE if the
+corresponding bit in its enable register's enable_for_run mask is set.
+This causes acpi_set_gpe() to work incorrectly if used for enabling
+GPEs that were not previously enabled with acpi_enable_gpe(). As a
+result, among other things, wakeup-only GPEs are never enabled by
+acpi_enable_wakeup_device(), so the devices that use them are unable
+to wake up the system.
+
+To fix this issue remove acpi_ev_enable_gpe() and its counterpart
+acpi_ev_disable_gpe() and replace acpi_hw_low_disable_gpe() with
+acpi_hw_low_set_gpe() that will be used instead to manipulate GPE
+enable bits at the low level. Make the users of acpi_ev_enable_gpe()
+and acpi_ev_disable_gpe() call acpi_hw_low_set_gpe() instead and
+make sure that GPE enable masks are only updated by acpi_enable_gpe()
+and acpi_disable_gpe() when GPE reference counters change from 0
+to 1 and from 1 to 0, respectively.
+
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/acpi/acpica/acevents.h | 4 --
+ drivers/acpi/acpica/achware.h | 3 +
+ drivers/acpi/acpica/evgpe.c | 78 +----------------------------------------
+ drivers/acpi/acpica/evxfevnt.c | 66 ++++++++++++++++++++++++++++++----
+ drivers/acpi/acpica/hwgpe.c | 26 +++++++++++--
+ include/acpi/acexcep.h | 2 -
+ 6 files changed, 84 insertions(+), 95 deletions(-)
+
+--- a/drivers/acpi/acpica/acevents.h
++++ b/drivers/acpi/acpica/acevents.h
+@@ -78,10 +78,6 @@ acpi_ev_queue_notify_request(struct acpi
+ acpi_status
+ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info);
+
+-acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
+-
+-acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
+-
+ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
+ u32 gpe_number);
+
+--- a/drivers/acpi/acpica/achware.h
++++ b/drivers/acpi/acpica/achware.h
+@@ -93,7 +93,8 @@ acpi_status acpi_hw_write_port(acpi_io_a
+ u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
+ struct acpi_gpe_register_info *gpe_register_info);
+
+-acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
++acpi_status
++acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action);
+
+ acpi_status
+ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info);
+--- a/drivers/acpi/acpica/evgpe.c
++++ b/drivers/acpi/acpica/evgpe.c
+@@ -94,76 +94,6 @@ acpi_ev_update_gpe_enable_masks(struct a
+
+ /*******************************************************************************
+ *
+- * FUNCTION: acpi_ev_enable_gpe
+- *
+- * PARAMETERS: gpe_event_info - GPE to enable
+- *
+- * RETURN: Status
+- *
+- * DESCRIPTION: Enable a GPE based on the GPE type
+- *
+- ******************************************************************************/
+-
+-acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
+-{
+- acpi_status status;
+-
+- ACPI_FUNCTION_TRACE(ev_enable_gpe);
+-
+- /* Make sure HW enable masks are updated */
+-
+- status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
+- if (ACPI_FAILURE(status))
+- return_ACPI_STATUS(status);
+-
+- /* Clear the GPE (of stale events), then enable it */
+- status = acpi_hw_clear_gpe(gpe_event_info);
+- if (ACPI_FAILURE(status))
+- return_ACPI_STATUS(status);
+-
+- /* Enable the requested GPE */
+- status = acpi_hw_write_gpe_enable_reg(gpe_event_info);
+- return_ACPI_STATUS(status);
+-}
+-
+-/*******************************************************************************
+- *
+- * FUNCTION: acpi_ev_disable_gpe
+- *
+- * PARAMETERS: gpe_event_info - GPE to disable
+- *
+- * RETURN: Status
+- *
+- * DESCRIPTION: Disable a GPE based on the GPE type
+- *
+- ******************************************************************************/
+-
+-acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
+-{
+- acpi_status status;
+-
+- ACPI_FUNCTION_TRACE(ev_disable_gpe);
+-
+- /* Make sure HW enable masks are updated */
+-
+- status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
+- if (ACPI_FAILURE(status))
+- return_ACPI_STATUS(status);
+-
+- /*
+- * Even if we don't know the GPE type, make sure that we always
+- * disable it. low_disable_gpe will just clear the enable bit for this
+- * GPE and write it. It will not write out the current GPE enable mask,
+- * since this may inadvertently enable GPEs too early, if a rogue GPE has
+- * come in during ACPICA initialization - possibly as a result of AML or
+- * other code that has enabled the GPE.
+- */
+- status = acpi_hw_low_disable_gpe(gpe_event_info);
+- return_ACPI_STATUS(status);
+-}
+-
+-/*******************************************************************************
+- *
+ * FUNCTION: acpi_ev_get_gpe_event_info
+ *
+ * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1
+@@ -388,10 +318,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as
+ return_VOID;
+ }
+
+- /* Set the GPE flags for return to enabled state */
+-
+- (void)acpi_ev_update_gpe_enable_masks(gpe_event_info);
+-
+ /*
+ * Take a snapshot of the GPE info for this level - we copy the info to
+ * prevent a race condition with remove_handler/remove_block.
+@@ -544,7 +470,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
+ * Disable the GPE, so it doesn't keep firing before the method has a
+ * chance to run (it runs asynchronously with interrupts enabled).
+ */
+- status = acpi_ev_disable_gpe(gpe_event_info);
++ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "Unable to disable GPE[%2X]",
+@@ -578,7 +504,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_eve
+ * Disable the GPE. The GPE will remain disabled until the ACPICA
+ * Core Subsystem is restarted, or a handler is installed.
+ */
+- status = acpi_ev_disable_gpe(gpe_event_info);
++ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "Unable to disable GPE[%2X]",
+--- a/drivers/acpi/acpica/evxfevnt.c
++++ b/drivers/acpi/acpica/evxfevnt.c
+@@ -201,6 +201,44 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
+
+ /*******************************************************************************
+ *
++ * FUNCTION: acpi_clear_and_enable_gpe
++ *
++ * PARAMETERS: gpe_event_info - GPE to enable
++ *
++ * RETURN: Status
++ *
++ * DESCRIPTION: Clear the given GPE from stale events and enable it.
++ *
++ ******************************************************************************/
++static acpi_status
++acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
++{
++ acpi_status status;
++
++ /*
++ * We will only allow a GPE to be enabled if it has either an
++ * associated method (_Lxx/_Exx) or a handler. Otherwise, the
++ * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
++ * first time it fires.
++ */
++ if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
++ return_ACPI_STATUS(AE_NO_HANDLER);
++ }
++
++ /* Clear the GPE (of stale events) */
++ status = acpi_hw_clear_gpe(gpe_event_info);
++ if (ACPI_FAILURE(status)) {
++ return_ACPI_STATUS(status);
++ }
++
++ /* Enable the requested GPE */
++ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
++
++ return_ACPI_STATUS(status);
++}
++
++/*******************************************************************************
++ *
+ * FUNCTION: acpi_set_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device
+@@ -235,11 +273,11 @@ acpi_status acpi_set_gpe(acpi_handle gpe
+
+ switch (action) {
+ case ACPI_GPE_ENABLE:
+- status = acpi_ev_enable_gpe(gpe_event_info);
++ status = acpi_clear_and_enable_gpe(gpe_event_info);
+ break;
+
+ case ACPI_GPE_DISABLE:
+- status = acpi_ev_disable_gpe(gpe_event_info);
++ status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
+ break;
+
+ default:
+@@ -291,9 +329,13 @@ acpi_status acpi_enable_gpe(acpi_handle
+
+ if (type & ACPI_GPE_TYPE_RUNTIME) {
+ if (++gpe_event_info->runtime_count == 1) {
+- status = acpi_ev_enable_gpe(gpe_event_info);
+- if (ACPI_FAILURE(status))
++ status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
++ if (ACPI_SUCCESS(status)) {
++ status = acpi_clear_and_enable_gpe(gpe_event_info);
++ }
++ if (ACPI_FAILURE(status)) {
+ gpe_event_info->runtime_count--;
++ }
+ }
+ }
+
+@@ -308,7 +350,7 @@ acpi_status acpi_enable_gpe(acpi_handle
+ * system into a sleep state.
+ */
+ if (++gpe_event_info->wakeup_count == 1)
+- acpi_ev_update_gpe_enable_masks(gpe_event_info);
++ status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
+ }
+
+ unlock_and_exit:
+@@ -351,8 +393,16 @@ acpi_status acpi_disable_gpe(acpi_handle
+ }
+
+ if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) {
+- if (--gpe_event_info->runtime_count == 0)
+- status = acpi_ev_disable_gpe(gpe_event_info);
++ if (--gpe_event_info->runtime_count == 0) {
++ status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
++ if (ACPI_SUCCESS(status)) {
++ status = acpi_hw_low_set_gpe(gpe_event_info,
++ ACPI_GPE_DISABLE);
++ }
++ if (ACPI_FAILURE(status)) {
++ gpe_event_info->runtime_count++;
++ }
++ }
+ }
+
+ if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) {
+@@ -361,7 +411,7 @@ acpi_status acpi_disable_gpe(acpi_handle
+ * states, so we don't need to disable them here.
+ */
+ if (--gpe_event_info->wakeup_count == 0)
+- acpi_ev_update_gpe_enable_masks(gpe_event_info);
++ status = acpi_ev_update_gpe_enable_masks(gpe_event_info);
+ }
+
+ unlock_and_exit:
+--- a/drivers/acpi/acpica/hwgpe.c
++++ b/drivers/acpi/acpica/hwgpe.c
+@@ -78,23 +78,27 @@ u32 acpi_hw_gpe_register_bit(struct acpi
+
+ /******************************************************************************
+ *
+- * FUNCTION: acpi_hw_low_disable_gpe
++ * FUNCTION: acpi_hw_low_set_gpe
+ *
+ * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
++ * action - Enable or disable
+ *
+ * RETURN: Status
+ *
+- * DESCRIPTION: Disable a single GPE in the enable register.
++ * DESCRIPTION: Enable or disable a single GPE in its enable register.
+ *
+ ******************************************************************************/
+
+-acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
++acpi_status
++acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
+ {
+ struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
+ u32 enable_mask;
+ u32 register_bit;
+
++ ACPI_FUNCTION_ENTRY();
++
+ /* Get the info block for the entire GPE register */
+
+ gpe_register_info = gpe_event_info->register_info;
+@@ -109,11 +113,23 @@ acpi_status acpi_hw_low_disable_gpe(stru
+ return (status);
+ }
+
+- /* Clear just the bit that corresponds to this GPE */
++ /* Set or clear just the bit that corresponds to this GPE */
+
+ register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
+ gpe_register_info);
+- ACPI_CLEAR_BIT(enable_mask, register_bit);
++ switch (action) {
++ case ACPI_GPE_ENABLE:
++ ACPI_SET_BIT(enable_mask, register_bit);
++ break;
++
++ case ACPI_GPE_DISABLE:
++ ACPI_CLEAR_BIT(enable_mask, register_bit);
++ break;
++
++ default:
++ ACPI_ERROR((AE_INFO, "Invalid action\n"));
++ return (AE_BAD_PARAMETER);
++ }
+
+ /* Write the updated enable mask */
+
+--- a/include/acpi/acexcep.h
++++ b/include/acpi/acexcep.h
+@@ -87,7 +87,7 @@
+ #define AE_NO_GLOBAL_LOCK (acpi_status) (0x0017 | AE_CODE_ENVIRONMENTAL)
+ #define AE_ABORT_METHOD (acpi_status) (0x0018 | AE_CODE_ENVIRONMENTAL)
+ #define AE_SAME_HANDLER (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL)
+-#define AE_WAKE_ONLY_GPE (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
++#define AE_NO_HANDLER (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
+ #define AE_OWNER_ID_LIMIT (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
+
+ #define AE_CODE_ENV_MAX 0x001B
--- /dev/null
+From 9d3c752de65dbfa6e522f1d666deb0ac152ef367 Mon Sep 17 00:00:00 2001
+From: Rafael J. Wysocki <rjw@sisk.pl>
+Date: Tue, 8 Jun 2010 10:50:53 +0200
+Subject: ACPI / ACPICA: Fix sysfs GPE interface
+
+From: Rafael J. Wysocki <rjw@sisk.pl>
+
+commit 9d3c752de65dbfa6e522f1d666deb0ac152ef367 upstream.
+
+The sysfs interface allowing user space to disable/enable GPEs
+doesn't work correctly, because a GPE disabled this way will be
+re-enabled shortly by acpi_ev_asynch_enable_gpe() if it was
+previosuly enabled by acpi_enable_gpe() (in which case the
+corresponding bit in its enable register's enable_for_run mask is
+set).
+
+To address this issue make the sysfs GPE interface use
+acpi_enable_gpe() and acpi_disable_gpe() instead of acpi_set_gpe()
+so that GPE reference counters are modified by it along with the
+values of GPE enable registers.
+
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/system.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/system.c
++++ b/drivers/acpi/system.c
+@@ -389,10 +389,12 @@ static ssize_t counter_set(struct kobjec
+ if (index < num_gpes) {
+ if (!strcmp(buf, "disable\n") &&
+ (status & ACPI_EVENT_FLAG_ENABLED))
+- result = acpi_set_gpe(handle, index, ACPI_GPE_DISABLE);
++ result = acpi_disable_gpe(handle, index,
++ ACPI_GPE_TYPE_RUNTIME);
+ else if (!strcmp(buf, "enable\n") &&
+ !(status & ACPI_EVENT_FLAG_ENABLED))
+- result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE);
++ result = acpi_enable_gpe(handle, index,
++ ACPI_GPE_TYPE_RUNTIME);
+ else if (!strcmp(buf, "clear\n") &&
+ (status & ACPI_EVENT_FLAG_SET))
+ result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR);
--- /dev/null
+From e4e9a735991c80fb0fc1bd4a13a93681c3c17ce0 Mon Sep 17 00:00:00 2001
+From: Rafael J. Wysocki <rjw@sisk.pl>
+Date: Tue, 8 Jun 2010 10:48:26 +0200
+Subject: ACPI / ACPICA: Use helper function for computing GPE masks
+
+From: Rafael J. Wysocki <rjw@sisk.pl>
+
+commit e4e9a735991c80fb0fc1bd4a13a93681c3c17ce0 upstream.
+
+In quite a few places ACPICA needs to compute a GPE enable mask with
+only one bit, corresponding to a given GPE, set. Currently, that
+computation is always open coded which leads to unnecessary code
+duplication. Fix this by introducing a helper function for computing
+one-bit GPE enable masks and using it where appropriate.
+
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/acpica/achware.h | 3 ++
+ drivers/acpi/acpica/evgpe.c | 7 ++---
+ drivers/acpi/acpica/hwgpe.c | 52 ++++++++++++++++++++++++++++++++----------
+ 3 files changed, 46 insertions(+), 16 deletions(-)
+
+--- a/drivers/acpi/acpica/achware.h
++++ b/drivers/acpi/acpica/achware.h
+@@ -90,6 +90,9 @@ acpi_status acpi_hw_write_port(acpi_io_a
+ /*
+ * hwgpe - GPE support
+ */
++u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
++ struct acpi_gpe_register_info *gpe_register_info);
++
+ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
+
+ acpi_status
+--- a/drivers/acpi/acpica/evgpe.c
++++ b/drivers/acpi/acpica/evgpe.c
+@@ -68,7 +68,7 @@ acpi_status
+ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info)
+ {
+ struct acpi_gpe_register_info *gpe_register_info;
+- u8 register_bit;
++ u32 register_bit;
+
+ ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks);
+
+@@ -77,9 +77,8 @@ acpi_ev_update_gpe_enable_masks(struct a
+ return_ACPI_STATUS(AE_NOT_EXIST);
+ }
+
+- register_bit = (u8)
+- (1 <<
+- (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
++ register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
++ gpe_register_info);
+
+ ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit);
+ ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
+--- a/drivers/acpi/acpica/hwgpe.c
++++ b/drivers/acpi/acpica/hwgpe.c
+@@ -57,6 +57,27 @@ acpi_hw_enable_wakeup_gpe_block(struct a
+
+ /******************************************************************************
+ *
++ * FUNCTION: acpi_hw_gpe_register_bit
++ *
++ * PARAMETERS: gpe_event_info - Info block for the GPE
++ * gpe_register_info - Info block for the GPE register
++ *
++ * RETURN: Status
++ *
++ * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given
++ * GPE set.
++ *
++ ******************************************************************************/
++
++u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
++ struct acpi_gpe_register_info *gpe_register_info)
++{
++ return (u32)1 << (gpe_event_info->gpe_number -
++ gpe_register_info->base_gpe_number);
++}
++
++/******************************************************************************
++ *
+ * FUNCTION: acpi_hw_low_disable_gpe
+ *
+ * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
+@@ -72,6 +93,7 @@ acpi_status acpi_hw_low_disable_gpe(stru
+ struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
+ u32 enable_mask;
++ u32 register_bit;
+
+ /* Get the info block for the entire GPE register */
+
+@@ -89,9 +111,9 @@ acpi_status acpi_hw_low_disable_gpe(stru
+
+ /* Clear just the bit that corresponds to this GPE */
+
+- ACPI_CLEAR_BIT(enable_mask, ((u32)1 <<
+- (gpe_event_info->gpe_number -
+- gpe_register_info->base_gpe_number)));
++ register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
++ gpe_register_info);
++ ACPI_CLEAR_BIT(enable_mask, register_bit);
+
+ /* Write the updated enable mask */
+
+@@ -150,21 +172,28 @@ acpi_hw_write_gpe_enable_reg(struct acpi
+
+ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
+ {
++ struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
+- u8 register_bit;
++ u32 register_bit;
+
+ ACPI_FUNCTION_ENTRY();
+
+- register_bit = (u8)(1 <<
+- (gpe_event_info->gpe_number -
+- gpe_event_info->register_info->base_gpe_number));
++ /* Get the info block for the entire GPE register */
++
++ gpe_register_info = gpe_event_info->register_info;
++ if (!gpe_register_info) {
++ return (AE_NOT_EXIST);
++ }
++
++ register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
++ gpe_register_info);
+
+ /*
+ * Write a one to the appropriate bit in the status register to
+ * clear this GPE.
+ */
+ status = acpi_hw_write(register_bit,
+- &gpe_event_info->register_info->status_address);
++ &gpe_register_info->status_address);
+
+ return (status);
+ }
+@@ -187,7 +216,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_e
+ acpi_event_status * event_status)
+ {
+ u32 in_byte;
+- u8 register_bit;
++ u32 register_bit;
+ struct acpi_gpe_register_info *gpe_register_info;
+ acpi_status status;
+ acpi_event_status local_event_status = 0;
+@@ -204,9 +233,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_e
+
+ /* Get the register bitmask for this GPE */
+
+- register_bit = (u8)(1 <<
+- (gpe_event_info->gpe_number -
+- gpe_event_info->register_info->base_gpe_number));
++ register_bit = acpi_hw_gpe_register_bit(gpe_event_info,
++ gpe_register_info);
+
+ /* GPE currently enabled? (enabled for runtime?) */
+
--- /dev/null
+From 856b185dd23da39e562983fbf28860f54e661b41 Mon Sep 17 00:00:00 2001
+From: Alex Chiang <achiang@canonical.com>
+Date: Thu, 17 Jun 2010 09:08:54 -0600
+Subject: ACPI: processor: fix processor_physically_present on UP
+
+From: Alex Chiang <achiang@canonical.com>
+
+commit 856b185dd23da39e562983fbf28860f54e661b41 upstream.
+
+The commit 5d554a7bb06 (ACPI: processor: add internal
+processor_physically_present()) is broken on uniprocessor (UP)
+configurations, as acpi_get_cpuid() will always return -1.
+
+We use the value of num_possible_cpus() to tell us whether we got
+an invalid cpuid from acpi_get_cpuid() in the SMP case, or if
+instead, we are UP, in which case num_possible_cpus() is #defined
+as 1.
+
+We use num_possible_cpus() instead of num_online_cpus() to
+protect ourselves against the scenario of CPU hotplug, and we've
+taken down all the CPUs except one.
+
+Thanks to Jan Pogadl for initial report and analysis and Chen
+Gong for review.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=16357
+
+Reported-by: Jan Pogadl <pogadl.jan@googlemail.com>:
+Reviewed-by: Chen Gong <gong.chen@linux.intel.com>
+Signed-off-by: Alex Chiang <achiang@canonical.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Cc: Thomas Renninger <trenn@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/processor_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/acpi/processor_core.c
++++ b/drivers/acpi/processor_core.c
+@@ -223,7 +223,7 @@ static bool processor_physically_present
+ type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
+ cpuid = acpi_get_cpuid(handle, type, acpi_id);
+
+- if (cpuid == -1)
++ if ((cpuid == -1) && (num_possible_cpus() > 1))
+ return false;
+
+ return true;
--- /dev/null
+From 2a6b69765ad794389f2fc3e14a0afa1a995221c2 Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <mjg@redhat.com>
+Date: Fri, 28 May 2010 16:32:15 -0400
+Subject: ACPI: Store NVS state even when entering suspend to RAM
+
+From: Matthew Garrett <mjg@redhat.com>
+
+commit 2a6b69765ad794389f2fc3e14a0afa1a995221c2 upstream.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=13931 describes a bug where
+a system fails to successfully resume after the second suspend. Maxim
+Levitsky discovered that this could be rectified by forcibly saving
+and restoring the ACPI non-volatile state. The spec indicates that this
+is only required for S4, but testing the behaviour of Windows by adding
+an ACPI NVS region to qemu's e820 map and registering a custom memory
+read/write handler reveals that it's saved and restored even over suspend
+to RAM. We should mimic that behaviour to avoid other broken platforms.
+
+Signed-off-by: Matthew Garrett <mjg@redhat.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Cc: Rafael Wysocki <rjw@sisk.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/sleep.c | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/acpi/sleep.c
++++ b/drivers/acpi/sleep.c
+@@ -112,6 +112,8 @@ static int __acpi_pm_prepare(void)
+ {
+ int error = acpi_sleep_prepare(acpi_target_sleep_state);
+
++ suspend_nvs_save();
++
+ if (error)
+ acpi_target_sleep_state = ACPI_STATE_S0;
+ return error;
+@@ -140,6 +142,8 @@ static void acpi_pm_finish(void)
+ {
+ u32 acpi_state = acpi_target_sleep_state;
+
++ suspend_nvs_free();
++
+ if (acpi_state == ACPI_STATE_S0)
+ return;
+
+@@ -189,6 +193,11 @@ static int acpi_suspend_begin(suspend_st
+ u32 acpi_state = acpi_suspend_states[pm_state];
+ int error = 0;
+
++ error = suspend_nvs_alloc();
++
++ if (error)
++ return error;
++
+ if (sleep_states[acpi_state]) {
+ acpi_target_sleep_state = acpi_state;
+ acpi_sleep_tts_switch(acpi_target_sleep_state);
+@@ -264,6 +273,8 @@ static int acpi_suspend_enter(suspend_st
+ if (acpi_state == ACPI_STATE_S3)
+ acpi_restore_state_mem();
+
++ suspend_nvs_restore();
++
+ return ACPI_SUCCESS(status) ? 0 : -EFAULT;
+ }
+
+@@ -430,12 +441,6 @@ static int acpi_hibernation_enter(void)
+ return ACPI_SUCCESS(status) ? 0 : -EFAULT;
+ }
+
+-static void acpi_hibernation_finish(void)
+-{
+- suspend_nvs_free();
+- acpi_pm_finish();
+-}
+-
+ static void acpi_hibernation_leave(void)
+ {
+ /*
+@@ -473,7 +478,7 @@ static struct platform_hibernation_ops a
+ .begin = acpi_hibernation_begin,
+ .end = acpi_pm_end,
+ .pre_snapshot = acpi_hibernation_pre_snapshot,
+- .finish = acpi_hibernation_finish,
++ .finish = acpi_pm_finish,
+ .prepare = acpi_pm_prepare,
+ .enter = acpi_hibernation_enter,
+ .leave = acpi_hibernation_leave,
+@@ -526,7 +531,7 @@ static struct platform_hibernation_ops a
+ .begin = acpi_hibernation_begin_old,
+ .end = acpi_pm_end,
+ .pre_snapshot = acpi_hibernation_pre_snapshot_old,
+- .finish = acpi_hibernation_finish,
++ .finish = acpi_pm_finish,
+ .prepare = acpi_pm_disable_gpes,
+ .enter = acpi_hibernation_enter,
+ .leave = acpi_hibernation_leave,
--- /dev/null
+From b6855772f4a22c4fbdd4fcaceff5c8a527035123 Mon Sep 17 00:00:00 2001
+From: Bob Copeland <me@bobcopeland.com>
+Date: Fri, 18 Jun 2010 13:15:23 -0400
+Subject: ath5k: initialize ah->ah_current_channel
+
+From: Bob Copeland <me@bobcopeland.com>
+
+commit b6855772f4a22c4fbdd4fcaceff5c8a527035123 upstream.
+
+ath5k assumes ah_current_channel is always a valid pointer in
+several places, but a newly created interface may not have a
+channel. To avoid null pointer dereferences, set it up to point
+to the first available channel until later reconfigured.
+
+This fixes the following oops:
+$ rmmod ath5k
+$ insmod ath5k
+$ iw phy0 set distance 11000
+
+BUG: unable to handle kernel NULL pointer dereference at 00000006
+IP: [<d0a1ff24>] ath5k_hw_set_coverage_class+0x74/0x1b0 [ath5k]
+*pde = 00000000
+Oops: 0000 [#1]
+last sysfs file: /sys/devices/pci0000:00/0000:00:0e.0/ieee80211/phy0/index
+Modules linked in: usbhid option usb_storage usbserial usblp evdev lm90
+scx200_acb i2c_algo_bit i2c_dev i2c_core via_rhine ohci_hcd ne2k_pci
+8390 leds_alix2 xt_IMQ imq nf_nat_tftp nf_conntrack_tftp nf_nat_irc nf_cc
+
+Pid: 1597, comm: iw Not tainted (2.6.32.14 #8)
+EIP: 0060:[<d0a1ff24>] EFLAGS: 00010296 CPU: 0
+EIP is at ath5k_hw_set_coverage_class+0x74/0x1b0 [ath5k]
+EAX: 000000c2 EBX: 00000000 ECX: ffffffff EDX: c12d2080
+ESI: 00000019 EDI: cf8c0000 EBP: d0a30edc ESP: cfa09bf4
+ DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
+Process iw (pid: 1597, ti=cfa09000 task=cf88a000 task.ti=cfa09000)
+Stack:
+ d0a34f35 d0a353f8 d0a30edc 000000fe cf8c0000 00000000 1900063d cfa8c9e0
+<0> cfa8c9e8 cfa8c0c0 cfa8c000 d0a27f0c 199d84b4 cfa8c200 00000010 d09bfdc7
+<0> 00000000 00000000 ffffffff d08e0d28 cf9263c0 00000001 cfa09cc4 00000000
+Call Trace:
+ [<d0a27f0c>] ? ath5k_hw_attach+0xc8c/0x3c10 [ath5k]
+ [<d09bfdc7>] ? __ieee80211_request_smps+0x1347/0x1580 [mac80211]
+ [<d08e0d28>] ? nl80211_send_scan_start+0x7b8/0x4520 [cfg80211]
+ [<c10f5db9>] ? nla_parse+0x59/0xc0
+ [<c11ca8d9>] ? genl_rcv_msg+0x169/0x1a0
+ [<c11ca770>] ? genl_rcv_msg+0x0/0x1a0
+ [<c11c7e68>] ? netlink_rcv_skb+0x38/0x90
+ [<c11c9649>] ? genl_rcv+0x19/0x30
+ [<c11c7c03>] ? netlink_unicast+0x1b3/0x220
+ [<c11c893e>] ? netlink_sendmsg+0x26e/0x290
+ [<c11a409e>] ? sock_sendmsg+0xbe/0xf0
+ [<c1032780>] ? autoremove_wake_function+0x0/0x50
+ [<c104d846>] ? __alloc_pages_nodemask+0x106/0x530
+ [<c1074933>] ? do_lookup+0x53/0x1b0
+ [<c10766f9>] ? __link_path_walk+0x9b9/0x9e0
+ [<c11acab0>] ? verify_iovec+0x50/0x90
+ [<c11a42b1>] ? sys_sendmsg+0x1e1/0x270
+ [<c1048e50>] ? find_get_page+0x10/0x50
+ [<c104a96f>] ? filemap_fault+0x5f/0x370
+ [<c1059159>] ? __do_fault+0x319/0x370
+ [<c11a55b4>] ? sys_socketcall+0x244/0x290
+ [<c101962c>] ? do_page_fault+0x1ec/0x270
+ [<c1019440>] ? do_page_fault+0x0/0x270
+ [<c1002ae5>] ? syscall_call+0x7/0xb
+Code: 00 b8 fe 00 00 00 b9 f8 53 a3 d0 89 5c 24 14 89 7c 24 10 89 44 24
+0c 89 6c 24 08 89 4c 24 04 c7 04 24 35 4f a3 d0 e8 7c 30 60 f0 <0f> b7
+43 06 ba 06 00 00 00 a8 10 75 0e 83 e0 20 83 f8 01 19 d2
+EIP: [<d0a1ff24>] ath5k_hw_set_coverage_class+0x74/0x1b0 [ath5k] SS:ESP
+0068:cfa09bf4
+CR2: 0000000000000006
+---[ end trace 54f73d6b10ceb87b ]---
+
+Reported-by: Steve Brown <sbrown@cortland.com>
+Signed-off-by: Bob Copeland <me@bobcopeland.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/ath/ath5k/attach.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/ath/ath5k/attach.c
++++ b/drivers/net/wireless/ath/ath5k/attach.c
+@@ -124,6 +124,7 @@ int ath5k_hw_attach(struct ath5k_softc *
+ ah->ah_cw_min = AR5K_TUNE_CWMIN;
+ ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
+ ah->ah_software_retry = false;
++ ah->ah_current_channel = &sc->channels[0];
+
+ /*
+ * Find the mac version
--- /dev/null
+From 1b99973f1c82707e46e8cb9416865a1e955e8f8c Mon Sep 17 00:00:00 2001
+From: Tao Ma <tao.ma@oracle.com>
+Date: Thu, 24 Jun 2010 07:43:57 +0800
+Subject: block: Don't count_vm_events for discard bio in submit_bio.
+
+From: Tao Ma <tao.ma@oracle.com>
+
+commit 1b99973f1c82707e46e8cb9416865a1e955e8f8c upstream.
+
+In submit_bio, we count vm events by check READ/WRITE.
+But actually DISCARD_NOBARRIER also has the WRITE flag set.
+It looks as if in blkdev_issue_discard, we also add a
+page as the payload and the bio_has_data check isn't enough.
+So add another check for discard bio.
+
+Signed-off-by: Tao Ma <tao.ma@oracle.com>
+Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ block/blk-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -1556,7 +1556,7 @@ void submit_bio(int rw, struct bio *bio)
+ * If it's a regular read/write or a barrier with data attached,
+ * go through the normal accounting stuff before submission.
+ */
+- if (bio_has_data(bio)) {
++ if (bio_has_data(bio) && !(rw & (1 << BIO_RW_DISCARD))) {
+ if (rw & WRITE) {
+ count_vm_events(PGPGOUT, count);
+ } else {
--- /dev/null
+From f048fa9c8686119c3858a463cab6121dced7c0bf Mon Sep 17 00:00:00 2001
+From: Michael Chan <mchan@broadcom.com>
+Date: Tue, 1 Jun 2010 15:05:36 +0000
+Subject: bnx2: Fix hang during rmmod bnx2.
+
+From: Michael Chan <mchan@broadcom.com>
+
+commit f048fa9c8686119c3858a463cab6121dced7c0bf upstream.
+
+The regression is caused by:
+
+commit 4327ba435a56ada13eedf3eb332e583c7a0586a9
+ bnx2: Fix netpoll crash.
+
+If ->open() and ->close() are called multiple times, the same napi structs
+will be added to dev->napi_list multiple times, corrupting the dev->napi_list.
+This causes free_netdev() to hang during rmmod.
+
+We fix this by calling netif_napi_del() during ->close().
+
+Also, bnx2_init_napi() must not be in the __devinit section since it is
+called by ->open().
+
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/bnx2.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/bnx2.c
++++ b/drivers/net/bnx2.c
+@@ -247,6 +247,7 @@ static const struct flash_spec flash_570
+ MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
+
+ static void bnx2_init_napi(struct bnx2 *bp);
++static void bnx2_del_napi(struct bnx2 *bp);
+
+ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)
+ {
+@@ -6265,6 +6266,7 @@ open_err:
+ bnx2_free_skbs(bp);
+ bnx2_free_irq(bp);
+ bnx2_free_mem(bp);
++ bnx2_del_napi(bp);
+ return rc;
+ }
+
+@@ -6523,6 +6525,7 @@ bnx2_close(struct net_device *dev)
+ bnx2_free_irq(bp);
+ bnx2_free_skbs(bp);
+ bnx2_free_mem(bp);
++ bnx2_del_napi(bp);
+ bp->link_up = 0;
+ netif_carrier_off(bp->dev);
+ bnx2_set_power_state(bp, PCI_D3hot);
+@@ -8213,7 +8216,16 @@ bnx2_bus_string(struct bnx2 *bp, char *s
+ return str;
+ }
+
+-static void __devinit
++static void
++bnx2_del_napi(struct bnx2 *bp)
++{
++ int i;
++
++ for (i = 0; i < bp->irq_nvecs; i++)
++ netif_napi_del(&bp->bnx2_napi[i].napi);
++}
++
++static void
+ bnx2_init_napi(struct bnx2 *bp)
+ {
+ int i;
--- /dev/null
+From a6f80fb7b5986fda663d94079d3bba0937a6b6ff Mon Sep 17 00:00:00 2001
+From: Andre Osterhues <aosterhues@escrypt.com>
+Date: Tue, 13 Jul 2010 15:59:17 -0500
+Subject: ecryptfs: Bugfix for error related to ecryptfs_hash_buckets
+
+From: Andre Osterhues <aosterhues@escrypt.com>
+
+commit a6f80fb7b5986fda663d94079d3bba0937a6b6ff upstream.
+
+The function ecryptfs_uid_hash wrongly assumes that the
+second parameter to hash_long() is the number of hash
+buckets instead of the number of hash bits.
+This patch fixes that and renames the variable
+ecryptfs_hash_buckets to ecryptfs_hash_bits to make it
+clearer.
+
+Fixes: CVE-2010-2492
+
+Signed-off-by: Andre Osterhues <aosterhues@escrypt.com>
+Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/messaging.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/fs/ecryptfs/messaging.c
++++ b/fs/ecryptfs/messaging.c
+@@ -31,9 +31,9 @@ static struct mutex ecryptfs_msg_ctx_lis
+
+ static struct hlist_head *ecryptfs_daemon_hash;
+ struct mutex ecryptfs_daemon_hash_mux;
+-static int ecryptfs_hash_buckets;
++static int ecryptfs_hash_bits;
+ #define ecryptfs_uid_hash(uid) \
+- hash_long((unsigned long)uid, ecryptfs_hash_buckets)
++ hash_long((unsigned long)uid, ecryptfs_hash_bits)
+
+ static u32 ecryptfs_msg_counter;
+ static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr;
+@@ -486,18 +486,19 @@ int ecryptfs_init_messaging(void)
+ }
+ mutex_init(&ecryptfs_daemon_hash_mux);
+ mutex_lock(&ecryptfs_daemon_hash_mux);
+- ecryptfs_hash_buckets = 1;
+- while (ecryptfs_number_of_users >> ecryptfs_hash_buckets)
+- ecryptfs_hash_buckets++;
++ ecryptfs_hash_bits = 1;
++ while (ecryptfs_number_of_users >> ecryptfs_hash_bits)
++ ecryptfs_hash_bits++;
+ ecryptfs_daemon_hash = kmalloc((sizeof(struct hlist_head)
+- * ecryptfs_hash_buckets), GFP_KERNEL);
++ * (1 << ecryptfs_hash_bits)),
++ GFP_KERNEL);
+ if (!ecryptfs_daemon_hash) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "%s: Failed to allocate memory\n", __func__);
+ mutex_unlock(&ecryptfs_daemon_hash_mux);
+ goto out;
+ }
+- for (i = 0; i < ecryptfs_hash_buckets; i++)
++ for (i = 0; i < (1 << ecryptfs_hash_bits); i++)
+ INIT_HLIST_HEAD(&ecryptfs_daemon_hash[i]);
+ mutex_unlock(&ecryptfs_daemon_hash_mux);
+ ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx)
+@@ -554,7 +555,7 @@ void ecryptfs_release_messaging(void)
+ int i;
+
+ mutex_lock(&ecryptfs_daemon_hash_mux);
+- for (i = 0; i < ecryptfs_hash_buckets; i++) {
++ for (i = 0; i < (1 << ecryptfs_hash_bits); i++) {
+ int rc;
+
+ hlist_for_each_entry(daemon, elem,
--- /dev/null
+From b70f4e85bfc4d7000036355b714a92d5c574f1be Mon Sep 17 00:00:00 2001
+From: Tony Luck <tony.luck@intel.com>
+Date: Wed, 30 Jun 2010 10:46:16 -0700
+Subject: [IA64] Fix spinaphore down_spin()
+
+From: Tony Luck <tony.luck@intel.com>
+
+commit b70f4e85bfc4d7000036355b714a92d5c574f1be upstream.
+
+Typo in down_spin() meant it only read the low 32 bits of the
+"serve" value, instead of the full 64 bits. This results in the
+system hanging when the values in ticket/serve get larger than
+32-bits. A big enough system running the right test can hit this
+in a just a few hours.
+
+Broken since 883a3acf5b0d4782ac35981227a0d094e8b44850
+ [IA64] Re-implement spinaphores using ticket lock concepts
+
+Reported via IRC by Bjorn Helgaas
+
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/ia64/mm/tlb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/ia64/mm/tlb.c
++++ b/arch/ia64/mm/tlb.c
+@@ -121,7 +121,7 @@ static inline void down_spin(struct spin
+ ia64_invala();
+
+ for (;;) {
+- asm volatile ("ld4.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
++ asm volatile ("ld8.c.nc %0=[%1]" : "=r"(serve) : "r"(&ss->serve) : "memory");
+ if (time_before(t, serve))
+ return;
+ cpu_relax();
--- /dev/null
+From 3d61510f4ecacfe47c75c0eb51c0659dfa77fb1b Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 2 Apr 2010 13:21:58 -0400
+Subject: HID: usbhid: enable remote wakeup for keyboards
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 3d61510f4ecacfe47c75c0eb51c0659dfa77fb1b upstream.
+
+This patch (as1365) enables remote wakeup by default for USB keyboard
+devices. Keyboards in general are supposed to be wakeup devices, but
+the correct place to enable it depends on the device's bus; no single
+approach will work for all keyboard devices. In particular, this
+covers only USB keyboards (and then only those supporting the boot
+protocol).
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hid/usbhid/hid-core.c | 7 +++++--
+ drivers/hid/usbhid/usbkbd.c | 1 +
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/hid/usbhid/hid-core.c
++++ b/drivers/hid/usbhid/hid-core.c
+@@ -1019,12 +1019,15 @@ static int usbhid_start(struct hid_devic
+ /* Some keyboards don't work until their LEDs have been set.
+ * Since BIOSes do set the LEDs, it must be safe for any device
+ * that supports the keyboard boot protocol.
++ * In addition, enable remote wakeup by default for all keyboard
++ * devices supporting the boot protocol.
+ */
+ if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT &&
+ interface->desc.bInterfaceProtocol ==
+- USB_INTERFACE_PROTOCOL_KEYBOARD)
++ USB_INTERFACE_PROTOCOL_KEYBOARD) {
+ usbhid_set_leds(hid);
+-
++ device_set_wakeup_enable(&dev->dev, 1);
++ }
+ return 0;
+
+ fail:
+--- a/drivers/hid/usbhid/usbkbd.c
++++ b/drivers/hid/usbhid/usbkbd.c
+@@ -313,6 +313,7 @@ static int usb_kbd_probe(struct usb_inte
+ goto fail2;
+
+ usb_set_intfdata(iface, kbd);
++ device_set_wakeup_enable(&dev->dev, 1);
+ return 0;
+
+ fail2:
--- /dev/null
+From 2e65a2075cc740b485ab203430bdf3459d5551b6 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 26 Jul 2010 01:12:37 -0700
+Subject: Input: RX51 keymap - fix recent compile breakage
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 2e65a2075cc740b485ab203430bdf3459d5551b6 upstream.
+
+Commit 3fea60261e73 ("Input: twl40300-keypad - fix handling of "all
+ground" rows") broke compilation as I managed to use non-existent
+keycodes.
+
+Reported-by: Arjan van de Ven <arjan@infradead.org>
+Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/arm/mach-omap2/board-rx51-peripherals.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
++++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
+@@ -192,10 +192,10 @@ static int board_keymap[] = {
+ KEY(4, 4, KEY_LEFTCTRL),
+ KEY(4, 5, KEY_RIGHTALT),
+ KEY(4, 6, KEY_LEFTSHIFT),
+- KEY(4, 8, KEY_10),
++ KEY(4, 8, KEY_F10),
+
+ KEY(5, 0, KEY_Y),
+- KEY(5, 8, KEY_11),
++ KEY(5, 8, KEY_F11),
+
+ KEY(6, 0, KEY_U),
+
--- /dev/null
+From a6866ac93e6cb68091326e80b4fa4619a5957644 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Thu, 20 May 2010 10:54:40 -0700
+Subject: iwl3945: enable stuck queue detection on 3945
+
+From: Reinette Chatre <reinette.chatre@intel.com>
+
+commit a6866ac93e6cb68091326e80b4fa4619a5957644 upstream.
+
+We learn from
+http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=1834 and
+https://bugzilla.redhat.com/show_bug.cgi?id=589777
+that 3945 can also suffer from a stuck command queue. Enable stuck queue
+detection for iwl3945 to enable recovery in this case.
+
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-3945.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
++++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
+@@ -2792,6 +2792,7 @@ static struct iwl_lib_ops iwl3945_lib =
+ .isr = iwl_isr_legacy,
+ .config_ap = iwl3945_config_ap,
+ .add_bcast_station = iwl3945_add_bcast_station,
++ .recover_from_tx_stall = iwl_bg_monitor_recover,
+ };
+
+ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
--- /dev/null
+From b561e8274f75831ee87e4ea378cbb1f9f050a51a Mon Sep 17 00:00:00 2001
+From: Shanyu Zhao <shanyu.zhao@intel.com>
+Date: Tue, 1 Jun 2010 17:13:58 -0700
+Subject: iwlagn: verify flow id in compressed BA packet
+
+From: Shanyu Zhao <shanyu.zhao@intel.com>
+
+commit b561e8274f75831ee87e4ea378cbb1f9f050a51a upstream.
+
+The flow id (scd_flow) in a compressed BA packet should match the txq_id
+of the queue from which the aggregated packets were sent. However, in
+some hardware like the 1000 series, sometimes the flow id is 0 for the
+txq_id (10 to 19). This can cause the annoying message:
+[ 2213.306191] iwlagn 0000:01:00.0: Received BA when not expected
+[ 2213.310178] iwlagn 0000:01:00.0: Read index for DMA queue txq id (0),
+index 5, is out of range [0-256] 7 7.
+
+And even worse, if agg->wait_for_ba is true when the bad BA is arriving,
+this can cause system hang due to NULL pointer dereference because the
+code is operating in a wrong tx queue!
+
+Signed-off-by: Shanyu Zhao <shanyu.zhao@intel.com>
+Signed-off-by: Pradeep Kulkarni <pradeepx.kulkarni@intel.com>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-tx.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
++++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
+@@ -1635,6 +1635,11 @@ void iwl_rx_reply_compressed_ba(struct i
+ sta_id = ba_resp->sta_id;
+ tid = ba_resp->tid;
+ agg = &priv->stations[sta_id].tid[tid].agg;
++ if (unlikely(agg->txq_id != scd_flow)) {
++ IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n",
++ scd_flow, agg->txq_id);
++ return;
++ }
+
+ /* Find index just before block-ack window */
+ index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
--- /dev/null
+From b74e31a9bc1013e69b85b139072485dc153453dd Mon Sep 17 00:00:00 2001
+From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Date: Mon, 1 Mar 2010 17:23:50 -0800
+Subject: iwlwifi: Recover TX flow stall due to stuck queue
+
+From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+
+commit b74e31a9bc1013e69b85b139072485dc153453dd upstream.
+
+Monitors the internal TX queues periodically. When a queue is stuck
+for some unknown conditions causing the throughput to drop and the
+transfer is stop, the driver will force firmware reload and bring the
+system back to normal operational state.
+
+The iwlwifi devices behave differently in this regard so this feature is
+made part of the ops infrastructure so we can have more control on how to
+monitor and recover from tx queue stall case per device.
+
+Signed-off-by: Trieu 'Andrew' Nguyen <trieux.t.nguyen@intel.com>
+Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-1000.c | 3
+ drivers/net/wireless/iwlwifi/iwl-3945.c | 2
+ drivers/net/wireless/iwlwifi/iwl-4965.c | 1
+ drivers/net/wireless/iwlwifi/iwl-5000.c | 9 ++
+ drivers/net/wireless/iwlwifi/iwl-6000.c | 8 ++
+ drivers/net/wireless/iwlwifi/iwl-agn.c | 16 ++++
+ drivers/net/wireless/iwlwifi/iwl-core.c | 93 ++++++++++++++++++++++++++++
+ drivers/net/wireless/iwlwifi/iwl-core.h | 7 ++
+ drivers/net/wireless/iwlwifi/iwl-dev.h | 10 +++
+ drivers/net/wireless/iwlwifi/iwl-tx.c | 2
+ drivers/net/wireless/iwlwifi/iwl3945-base.c | 16 ++++
+ 11 files changed, 167 insertions(+)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
+@@ -211,6 +211,7 @@ static struct iwl_lib_ops iwl1000_lib =
+ .set_ct_kill = iwl1000_set_ct_threshold,
+ },
+ .add_bcast_station = iwl_add_bcast_station,
++ .recover_from_tx_stall = iwl_bg_monitor_recover,
+ };
+
+ static const struct iwl_ops iwl1000_ops = {
+@@ -248,6 +249,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
+ .support_ct_kill_exit = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl1000_bg_cfg = {
+@@ -276,6 +278,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
+ .support_ct_kill_exit = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
+--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
++++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
+@@ -2827,6 +2827,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
+ .led_compensation = 64,
+ .broken_powersave = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ static struct iwl_cfg iwl3945_abg_cfg = {
+@@ -2845,6 +2846,7 @@ static struct iwl_cfg iwl3945_abg_cfg =
+ .led_compensation = 64,
+ .broken_powersave = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
+--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
+@@ -2251,6 +2251,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
+ .led_compensation = 61,
+ .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ /* Module firmware */
+--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
+@@ -1500,6 +1500,7 @@ struct iwl_lib_ops iwl5000_lib = {
+ .set_ct_kill = iwl5000_set_ct_threshold,
+ },
+ .add_bcast_station = iwl_add_bcast_station,
++ .recover_from_tx_stall = iwl_bg_monitor_recover,
+ };
+
+ static struct iwl_lib_ops iwl5150_lib = {
+@@ -1554,6 +1555,7 @@ static struct iwl_lib_ops iwl5150_lib =
+ .set_ct_kill = iwl5150_set_ct_threshold,
+ },
+ .add_bcast_station = iwl_add_bcast_station,
++ .recover_from_tx_stall = iwl_bg_monitor_recover,
+ };
+
+ static const struct iwl_ops iwl5000_ops = {
+@@ -1603,6 +1605,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
+ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl5100_bgn_cfg = {
+@@ -1629,6 +1632,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
+ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl5100_abg_cfg = {
+@@ -1653,6 +1657,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
+ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl5100_agn_cfg = {
+@@ -1679,6 +1684,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
+ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl5350_agn_cfg = {
+@@ -1705,6 +1711,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
+ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl5150_agn_cfg = {
+@@ -1731,6 +1738,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
+ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl5150_abg_cfg = {
+@@ -1755,6 +1763,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
+ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
+--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
+@@ -277,6 +277,7 @@ static struct iwl_lib_ops iwl6000_lib =
+ .set_ct_kill = iwl6000_set_ct_threshold,
+ },
+ .add_bcast_station = iwl_add_bcast_station,
++ .recover_from_tx_stall = iwl_bg_monitor_recover,
+ };
+
+ static const struct iwl_ops iwl6000_ops = {
+@@ -342,6 +343,7 @@ static struct iwl_lib_ops iwl6050_lib =
+ .set_calib_version = iwl6050_set_calib_version,
+ },
+ .add_bcast_station = iwl_add_bcast_station,
++ .recover_from_tx_stall = iwl_bg_monitor_recover,
+ };
+
+ static const struct iwl_ops iwl6050_ops = {
+@@ -385,6 +387,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
+ .support_ct_kill_exit = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl6000i_2abg_cfg = {
+@@ -416,6 +419,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
+ .support_ct_kill_exit = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl6000i_2bg_cfg = {
+@@ -447,6 +451,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
+ .support_ct_kill_exit = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl6050_2agn_cfg = {
+@@ -479,6 +484,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
+ .support_ct_kill_exit = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .chain_noise_scale = 1500,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl6050_2abg_cfg = {
+@@ -510,6 +516,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
+ .support_ct_kill_exit = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .chain_noise_scale = 1500,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ struct iwl_cfg iwl6000_3agn_cfg = {
+@@ -542,6 +549,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
+ .support_ct_kill_exit = true,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .chain_noise_scale = 1000,
++ .monitor_recover_period = IWL_MONITORING_PERIOD,
+ };
+
+ MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -2106,6 +2106,13 @@ static void iwl_alive_start(struct iwl_p
+ /* After the ALIVE response, we can send host commands to the uCode */
+ set_bit(STATUS_ALIVE, &priv->status);
+
++ if (priv->cfg->ops->lib->recover_from_tx_stall) {
++ /* Enable timer to monitor the driver queues */
++ mod_timer(&priv->monitor_recover,
++ jiffies +
++ msecs_to_jiffies(priv->cfg->monitor_recover_period));
++ }
++
+ if (iwl_is_rfkill(priv))
+ return;
+
+@@ -3316,6 +3323,13 @@ static void iwl_setup_deferred_work(stru
+ priv->ucode_trace.data = (unsigned long)priv;
+ priv->ucode_trace.function = iwl_bg_ucode_trace;
+
++ if (priv->cfg->ops->lib->recover_from_tx_stall) {
++ init_timer(&priv->monitor_recover);
++ priv->monitor_recover.data = (unsigned long)priv;
++ priv->monitor_recover.function =
++ priv->cfg->ops->lib->recover_from_tx_stall;
++ }
++
+ if (!priv->cfg->use_isr_legacy)
+ tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ iwl_irq_tasklet, (unsigned long)priv);
+@@ -3336,6 +3350,8 @@ static void iwl_cancel_deferred_work(str
+ cancel_work_sync(&priv->beacon_update);
+ del_timer_sync(&priv->statistics_periodic);
+ del_timer_sync(&priv->ucode_trace);
++ if (priv->cfg->ops->lib->recover_from_tx_stall)
++ del_timer_sync(&priv->monitor_recover);
+ }
+
+ static void iwl_init_hw_rates(struct iwl_priv *priv,
+--- a/drivers/net/wireless/iwlwifi/iwl-core.c
++++ b/drivers/net/wireless/iwlwifi/iwl-core.c
+@@ -3403,6 +3403,99 @@ int iwl_force_reset(struct iwl_priv *pri
+ }
+ return 0;
+ }
++EXPORT_SYMBOL(iwl_force_reset);
++
++/**
++ * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
++ *
++ * During normal condition (no queue is stuck), the timer is continually set to
++ * execute every monitor_recover_period milliseconds after the last timer
++ * expired. When the queue read_ptr is at the same place, the timer is
++ * shorten to 100mSecs. This is
++ * 1) to reduce the chance that the read_ptr may wrap around (not stuck)
++ * 2) to detect the stuck queues quicker before the station and AP can
++ * disassociate each other.
++ *
++ * This function monitors all the tx queues and recover from it if any
++ * of the queues are stuck.
++ * 1. It first check the cmd queue for stuck conditions. If it is stuck,
++ * it will recover by resetting the firmware and return.
++ * 2. Then, it checks for station association. If it associates it will check
++ * other queues. If any queue is stuck, it will recover by resetting
++ * the firmware.
++ * Note: It the number of times the queue read_ptr to be at the same place to
++ * be MAX_REPEAT+1 in order to consider to be stuck.
++ */
++/*
++ * The maximum number of times the read pointer of the tx queue at the
++ * same place without considering to be stuck.
++ */
++#define MAX_REPEAT (2)
++static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
++{
++ struct iwl_tx_queue *txq;
++ struct iwl_queue *q;
++
++ txq = &priv->txq[cnt];
++ q = &txq->q;
++ /* queue is empty, skip */
++ if (q->read_ptr != q->write_ptr) {
++ if (q->read_ptr == q->last_read_ptr) {
++ /* a queue has not been read from last time */
++ if (q->repeat_same_read_ptr > MAX_REPEAT) {
++ IWL_ERR(priv,
++ "queue %d stuck %d time. Fw reload.\n",
++ q->id, q->repeat_same_read_ptr);
++ q->repeat_same_read_ptr = 0;
++ iwl_force_reset(priv, IWL_FW_RESET);
++ } else {
++ q->repeat_same_read_ptr++;
++ IWL_DEBUG_RADIO(priv,
++ "queue %d, not read %d time\n",
++ q->id,
++ q->repeat_same_read_ptr);
++ mod_timer(&priv->monitor_recover, jiffies +
++ msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS));
++ }
++ return 1;
++ } else {
++ q->last_read_ptr = q->read_ptr;
++ q->repeat_same_read_ptr = 0;
++ }
++ }
++ return 0;
++}
++
++void iwl_bg_monitor_recover(unsigned long data)
++{
++ struct iwl_priv *priv = (struct iwl_priv *)data;
++ int cnt;
++
++ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
++ return;
++
++ /* monitor and check for stuck cmd queue */
++ if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM))
++ return;
++
++ /* monitor and check for other stuck queues */
++ if (iwl_is_associated(priv)) {
++ for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
++ /* skip as we already checked the command queue */
++ if (cnt == IWL_CMD_QUEUE_NUM)
++ continue;
++ if (iwl_check_stuck_queue(priv, cnt))
++ return;
++ }
++ }
++ /*
++ * Reschedule the timer to occur in
++ * priv->cfg->monitor_recover_period
++ */
++ mod_timer(&priv->monitor_recover,
++ jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period));
++}
++EXPORT_SYMBOL(iwl_bg_monitor_recover);
+
+ #ifdef CONFIG_PM
+
+--- a/drivers/net/wireless/iwlwifi/iwl-core.h
++++ b/drivers/net/wireless/iwlwifi/iwl-core.h
+@@ -191,6 +191,8 @@ struct iwl_lib_ops {
+ struct iwl_temp_ops temp_ops;
+ /* station management */
+ void (*add_bcast_station)(struct iwl_priv *priv);
++ /* recover from tx queue stall */
++ void (*recover_from_tx_stall)(unsigned long data);
+ };
+
+ struct iwl_led_ops {
+@@ -295,6 +297,8 @@ struct iwl_cfg {
+ const bool support_wimax_coexist;
+ u8 plcp_delta_threshold;
+ s32 chain_noise_scale;
++ /* timer period for monitor the driver queues */
++ u32 monitor_recover_period;
+ };
+
+ /***************************
+@@ -577,6 +581,9 @@ static inline u16 iwl_pcie_link_ctl(stru
+ pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+ return pci_lnk_ctl;
+ }
++
++void iwl_bg_monitor_recover(unsigned long data);
++
+ #ifdef CONFIG_PM
+ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
+ int iwl_pci_resume(struct pci_dev *pdev);
+--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
+@@ -183,6 +183,10 @@ struct iwl_queue {
+ int n_bd; /* number of BDs in this queue */
+ int write_ptr; /* 1-st empty entry (index) host_w*/
+ int read_ptr; /* last used entry (index) host_r*/
++ /* use for monitoring and recovering the stuck queue */
++ int last_read_ptr; /* storing the last read_ptr */
++ /* number of time read_ptr and last_read_ptr are the same */
++ u8 repeat_same_read_ptr;
+ dma_addr_t dma_addr; /* physical addr for BD's */
+ int n_window; /* safe queue window */
+ u32 id;
+@@ -1039,6 +1043,11 @@ struct iwl_event_log {
+ #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
+ #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
+
++/* timer constants use to monitor and recover stuck tx queues in mSecs */
++#define IWL_MONITORING_PERIOD (1000)
++#define IWL_ONE_HUNDRED_MSECS (100)
++#define IWL_SIXTY_SECS (60000)
++
+ enum iwl_reset {
+ IWL_RF_RESET = 0,
+ IWL_FW_RESET,
+@@ -1339,6 +1348,7 @@ struct iwl_priv {
+ struct work_struct run_time_calib_work;
+ struct timer_list statistics_periodic;
+ struct timer_list ucode_trace;
++ struct timer_list monitor_recover;
+ bool hw_ready;
+ /*For 3945*/
+ #define IWL_DEFAULT_TX_POWER 0x0F
+--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
++++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
+@@ -310,6 +310,8 @@ static int iwl_queue_init(struct iwl_pri
+ q->high_mark = 2;
+
+ q->write_ptr = q->read_ptr = 0;
++ q->last_read_ptr = 0;
++ q->repeat_same_read_ptr = 0;
+
+ return 0;
+ }
+--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
+@@ -2513,6 +2513,13 @@ static void iwl3945_alive_start(struct i
+ /* After the ALIVE response, we can send commands to 3945 uCode */
+ set_bit(STATUS_ALIVE, &priv->status);
+
++ if (priv->cfg->ops->lib->recover_from_tx_stall) {
++ /* Enable timer to monitor the driver queues */
++ mod_timer(&priv->monitor_recover,
++ jiffies +
++ msecs_to_jiffies(priv->cfg->monitor_recover_period));
++ }
++
+ if (iwl_is_rfkill(priv))
+ return;
+
+@@ -3783,6 +3790,13 @@ static void iwl3945_setup_deferred_work(
+
+ iwl3945_hw_setup_deferred_work(priv);
+
++ if (priv->cfg->ops->lib->recover_from_tx_stall) {
++ init_timer(&priv->monitor_recover);
++ priv->monitor_recover.data = (unsigned long)priv;
++ priv->monitor_recover.function =
++ priv->cfg->ops->lib->recover_from_tx_stall;
++ }
++
+ tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+ iwl3945_irq_tasklet, (unsigned long)priv);
+ }
+@@ -3795,6 +3809,8 @@ static void iwl3945_cancel_deferred_work
+ cancel_delayed_work(&priv->scan_check);
+ cancel_delayed_work(&priv->alive_start);
+ cancel_work_sync(&priv->beacon_update);
++ if (priv->cfg->ops->lib->recover_from_tx_stall)
++ del_timer_sync(&priv->monitor_recover);
+ }
+
+ static struct attribute *iwl3945_sysfs_entries[] = {
--- /dev/null
+From 1c938663d58b5b2965976a6f54cc51b5d6f691aa Mon Sep 17 00:00:00 2001
+From: Krzysztof Halasa <khc@pm.waw.pl>
+Date: Fri, 11 Jun 2010 01:08:20 +0200
+Subject: kbuild: Fix modpost segfault
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Krzysztof Halasa <khc@pm.waw.pl>
+
+commit 1c938663d58b5b2965976a6f54cc51b5d6f691aa upstream.
+
+Alan <alan@clueserver.org> writes:
+
+> program: /home/alan/GitTrees/linux-2.6-mid-ref/scripts/mod/modpost -o
+> Module.symvers -S vmlinux.o
+>
+> Program received signal SIGSEGV, Segmentation fault.
+
+It just hit me.
+It's the offset calculation in reloc_location() which overflows:
+ return (void *)elf->hdr + sechdrs[section].sh_offset +
+ (r->r_offset - sechdrs[section].sh_addr);
+
+E.g. for the first rodata r entry:
+r->r_offset < sechdrs[section].sh_addr
+and the expression in the parenthesis produces 0xFFFFFFE0 or something
+equally wise.
+
+Reported-by: Alan <alan@clueserver.org>
+Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>
+Tested-by: Alan <alan@clueserver.org>
+Signed-off-by: Michal Marek <mmarek@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ scripts/mod/modpost.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/scripts/mod/modpost.c
++++ b/scripts/mod/modpost.c
+@@ -1318,7 +1318,7 @@ static unsigned int *reloc_location(stru
+ int section = sechdr->sh_info;
+
+ return (void *)elf->hdr + sechdrs[section].sh_offset +
+- (r->r_offset - sechdrs[section].sh_addr);
++ r->r_offset - sechdrs[section].sh_addr;
+ }
+
+ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
--- /dev/null
+From 76f273640134f3eb8257179cd5b3bc6ba5fe4a96 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Wed, 28 Apr 2010 17:03:15 +0200
+Subject: mac80211: fix supported rates IE if AP doesn't give us it's rates
+
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+
+commit 76f273640134f3eb8257179cd5b3bc6ba5fe4a96 upstream.
+
+If AP do not provide us supported rates before assiociation, send
+all rates we are supporting instead of empty information element.
+
+v1 -> v2: Add comment.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/mac80211/work.c | 28 +++++++++++++++++++---------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+--- a/net/mac80211/work.c
++++ b/net/mac80211/work.c
+@@ -213,15 +213,25 @@ static void ieee80211_send_assoc(struct
+
+ sband = local->hw.wiphy->bands[wk->chan->band];
+
+- /*
+- * Get all rates supported by the device and the AP as
+- * some APs don't like getting a superset of their rates
+- * in the association request (e.g. D-Link DAP 1353 in
+- * b-only mode)...
+- */
+- rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
+- wk->assoc.supp_rates_len,
+- sband, &rates);
++ if (wk->assoc.supp_rates_len) {
++ /*
++ * Get all rates supported by the device and the AP as
++ * some APs don't like getting a superset of their rates
++ * in the association request (e.g. D-Link DAP 1353 in
++ * b-only mode)...
++ */
++ rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
++ wk->assoc.supp_rates_len,
++ sband, &rates);
++ } else {
++ /*
++ * In case AP not provide any supported rates information
++ * before association, we send information element(s) with
++ * all rates that we support.
++ */
++ rates = ~0;
++ rates_len = sband->n_bitrates;
++ }
+
+ skb = alloc_skb(local->hw.extra_tx_headroom +
+ sizeof(*mgmt) + /* bit too much but doesn't matter */
--- /dev/null
+From 98a0f86a54bb195c28ae1ccb5a5f5cda12cf7121 Mon Sep 17 00:00:00 2001
+From: Bruno Randolf <randolf.bruno@googlemail.com>
+Date: Mon, 12 Jul 2010 00:40:28 +0900
+Subject: MIPS: MTX-1: Fix PCI on the MeshCube and related boards
+
+From: Bruno Randolf <randolf.bruno@googlemail.com>
+
+commit 98a0f86a54bb195c28ae1ccb5a5f5cda12cf7121 upstream.
+
+This patch fixes a regression introduced by commit "MIPS: Alchemy: MTX-1:
+Use linux gpio api." (bb706b28bbd647c2fd7f22d6bf03a18b9552be05) which broke
+PCI bus operation. The problem is caused by alchemy_gpio2_enable() which
+resets the GPIO2 block. Two PCI signals (PCI_SERR and PCI_RST) are connected
+to GPIO2 and they obviously do not to like the reset. Since GPIO2 is
+correctly initialized by the boot monitor (YAMON) it is not necessary to
+call this function, so just remove it.
+
+Also replace gpio_set_value() with alchemy_gpio_set_value() to avoid
+problems in case gpiolib gets initialized after PCI. And since alchemy
+gpio_set_value() calls au_sync() we don't have to au_sync() again later.
+
+Signed-off-by: Bruno Randolf <br1@einfach.org>
+To: linux-mips@linux-mips.org
+To: manuel.lauss@googlemail.com
+Patchwork: https://patchwork.linux-mips.org/patch/1448/
+Tested-by: Florian Fainelli <florian@openwrt.org>
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/mips/alchemy/mtx-1/board_setup.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/arch/mips/alchemy/mtx-1/board_setup.c
++++ b/arch/mips/alchemy/mtx-1/board_setup.c
+@@ -67,8 +67,6 @@ static void mtx1_power_off(void)
+
+ void __init board_setup(void)
+ {
+- alchemy_gpio2_enable();
+-
+ #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* Enable USB power switch */
+ alchemy_gpio_direction_output(204, 0);
+@@ -117,11 +115,11 @@ mtx1_pci_idsel(unsigned int devsel, int
+
+ if (assert && devsel != 0)
+ /* Suppress signal to Cardbus */
+- gpio_set_value(1, 0); /* set EXT_IO3 OFF */
++ alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */
+ else
+- gpio_set_value(1, 1); /* set EXT_IO3 ON */
++ alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */
+
+- au_sync_udelay(1);
++ udelay(1);
+ return 1;
+ }
+
--- /dev/null
+From a78f9f4668949a6588b8872f162e86685c63d023 Mon Sep 17 00:00:00 2001
+From: Tao Ma <tao.ma@oracle.com>
+Date: Fri, 9 Jul 2010 14:53:11 +0800
+Subject: ocfs2: make xattr extension work with new local alloc reservation.
+
+From: Tao Ma <tao.ma@oracle.com>
+
+commit a78f9f4668949a6588b8872f162e86685c63d023 upstream.
+
+The old ocfs2_xattr_extent_allocation is too optimistic about
+the clusters we can get. So actually if the file system is
+too fragmented, ocfs2_add_clusters_in_btree will return us
+with EGAIN and we need to allocate clusters once again.
+
+So this patch change it to a while loop so that we can allocate
+clusters until we reach clusters_to_add.
+
+Signed-off-by: Tao Ma <tao.ma@oracle.com>
+Signed-off-by: Joel Becker <joel.becker@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ocfs2/xattr.c | 88 ++++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 52 insertions(+), 36 deletions(-)
+
+--- a/fs/ocfs2/xattr.c
++++ b/fs/ocfs2/xattr.c
+@@ -708,7 +708,7 @@ static int ocfs2_xattr_extend_allocation
+ struct ocfs2_xattr_value_buf *vb,
+ struct ocfs2_xattr_set_ctxt *ctxt)
+ {
+- int status = 0;
++ int status = 0, credits;
+ handle_t *handle = ctxt->handle;
+ enum ocfs2_alloc_restarted why;
+ u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters);
+@@ -718,43 +718,59 @@ static int ocfs2_xattr_extend_allocation
+
+ ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb);
+
+- status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
+- OCFS2_JOURNAL_ACCESS_WRITE);
+- if (status < 0) {
+- mlog_errno(status);
+- goto leave;
++ while (clusters_to_add) {
++ status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
++ OCFS2_JOURNAL_ACCESS_WRITE);
++ if (status < 0) {
++ mlog_errno(status);
++ break;
++ }
++
++ prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters);
++ status = ocfs2_add_clusters_in_btree(handle,
++ &et,
++ &logical_start,
++ clusters_to_add,
++ 0,
++ ctxt->data_ac,
++ ctxt->meta_ac,
++ &why);
++ if ((status < 0) && (status != -EAGAIN)) {
++ if (status != -ENOSPC)
++ mlog_errno(status);
++ break;
++ }
++
++ status = ocfs2_journal_dirty(handle, vb->vb_bh);
++ if (status < 0) {
++ mlog_errno(status);
++ break;
++ }
++
++ clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) -
++ prev_clusters;
++
++ if (why != RESTART_NONE && clusters_to_add) {
++ /*
++ * We can only fail in case the alloc file doesn't give
++ * up enough clusters.
++ */
++ BUG_ON(why == RESTART_META);
++
++ mlog(0, "restarting xattr value extension for %u"
++ " clusters,.\n", clusters_to_add);
++ credits = ocfs2_calc_extend_credits(inode->i_sb,
++ &vb->vb_xv->xr_list,
++ clusters_to_add);
++ status = ocfs2_extend_trans(handle, credits);
++ if (status < 0) {
++ status = -ENOMEM;
++ mlog_errno(status);
++ break;
++ }
++ }
+ }
+
+- prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters);
+- status = ocfs2_add_clusters_in_btree(handle,
+- &et,
+- &logical_start,
+- clusters_to_add,
+- 0,
+- ctxt->data_ac,
+- ctxt->meta_ac,
+- &why);
+- if (status < 0) {
+- mlog_errno(status);
+- goto leave;
+- }
+-
+- status = ocfs2_journal_dirty(handle, vb->vb_bh);
+- if (status < 0) {
+- mlog_errno(status);
+- goto leave;
+- }
+-
+- clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) - prev_clusters;
+-
+- /*
+- * We should have already allocated enough space before the transaction,
+- * so no need to restart.
+- */
+- BUG_ON(why != RESTART_NONE || clusters_to_add);
+-
+-leave:
+-
+ return status;
+ }
+
--- /dev/null
+From e4f1ac2122413736bf2791d3af6533f36b46fc61 Mon Sep 17 00:00:00 2001
+From: Dominik Brodowski <linux@dominikbrodowski.net>
+Date: Sat, 19 Jun 2010 14:33:56 +0200
+Subject: pcmcia: do not initialize the present flag too late.
+
+From: Dominik Brodowski <linux@dominikbrodowski.net>
+
+commit e4f1ac2122413736bf2791d3af6533f36b46fc61 upstream.
+
+The "present" flag was initialized too late -- possibly, a card
+was already registered at this time, so re-setting the flag to 0
+caused pcmcia_dev_present() to fail.
+
+Reported-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pcmcia/ds.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/pcmcia/ds.c
++++ b/drivers/pcmcia/ds.c
+@@ -1366,6 +1366,7 @@ static int __devinit pcmcia_bus_add_sock
+ INIT_LIST_HEAD(&socket->devices_list);
+ memset(&socket->pcmcia_state, 0, sizeof(u8));
+ socket->device_count = 0;
++ atomic_set(&socket->present, 0);
+
+ ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);
+ if (ret) {
+@@ -1374,8 +1375,6 @@ static int __devinit pcmcia_bus_add_sock
+ return ret;
+ }
+
+- atomic_set(&socket->present, 0);
+-
+ return 0;
+ }
+
mfd-remove-unneeded-and-dangerous-clearing-of-clientdata.patch
firmware_class-fix-memory-leak-free-allocated-pages.patch
revert-remove-rwsem-lock-from-cpufreq_gov_stop-call-second-call-site.patch
+v4l-dvb-dvb-core-fix-ule-decapsulation-bug.patch
+v4l-dvb-fusionhdtv-use-quick-reads-for-i2c-ir-device-probing.patch
+v4l-dvb-budget-select-correct-frontends.patch
+3c503-fix-irq-probing.patch
+mac80211-fix-supported-rates-ie-if-ap-doesn-t-give-us-it-s-rates.patch
+bnx2-fix-hang-during-rmmod-bnx2.patch
+xfs-prevent-swapext-from-operating-on-write-only-files.patch
+v4l-dvb-uvcvideo-add-support-for-unbranded-arkmicro-18ec-3290-webcams.patch
+v4l-dvb-uvcvideo-add-support-for-packard-bell-easynote-mx52-integrated-webcam.patch
+v4l-dvb-uvcvideo-add-support-for-v4l2_pix_fmt_y16.patch
+block-don-t-count_vm_events-for-discard-bio-in-submit_bio.patch
+iwlagn-verify-flow-id-in-compressed-ba-packet.patch
+iwlwifi-recover-tx-flow-stall-due-to-stuck-queue.patch
+iwl3945-enable-stuck-queue-detection-on-3945.patch
+suspend-move-nvs-save-restore-code-to-generic-suspend-functionality.patch
+acpi-store-nvs-state-even-when-entering-suspend-to-ram.patch
+kbuild-fix-modpost-segfault.patch
+acpi-acpica-use-helper-function-for-computing-gpe-masks.patch
+acpi-acpica-fix-low-level-gpe-manipulation-code.patch
+acpi-acpica-avoid-writing-full-enable-masks-to-gpe-registers.patch
+acpi-acpica-fix-gpe-initialization.patch
+acpi-acpica-fix-sysfs-gpe-interface.patch
+fix-spinaphore-down_spin.patch
+ecryptfs-bugfix-for-error-related-to-ecryptfs_hash_buckets.patch
+pcmcia-do-not-initialize-the-present-flag-too-late.patch
+mips-mtx-1-fix-pci-on-the-meshcube-and-related-boards.patch
+hid-usbhid-enable-remote-wakeup-for-keyboards.patch
+ath5k-initialize-ah-ah_current_channel.patch
+input-rx51-keymap-fix-recent-compile-breakage.patch
+ocfs2-make-xattr-extension-work-with-new-local-alloc-reservation.patch
+acpi-processor-fix-processor_physically_present-on-up.patch
--- /dev/null
+From dd4c4f17d722ffeb2515bf781400675a30fcead7 Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <mjg@redhat.com>
+Date: Fri, 28 May 2010 16:32:14 -0400
+Subject: suspend: Move NVS save/restore code to generic suspend functionality
+
+From: Matthew Garrett <mjg@redhat.com>
+
+commit dd4c4f17d722ffeb2515bf781400675a30fcead7 upstream.
+
+Saving platform non-volatile state may be required for suspend to RAM as
+well as hibernation. Move it to more generic code.
+
+Signed-off-by: Matthew Garrett <mjg@redhat.com>
+Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
+Tested-by: Maxim Levitsky <maximlevitsky@gmail.com>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/kernel/e820.c | 2
+ drivers/acpi/sleep.c | 12 +--
+ include/linux/suspend.h | 26 ++++----
+ kernel/power/Kconfig | 9 +-
+ kernel/power/Makefile | 2
+ kernel/power/hibernate_nvs.c | 136 -------------------------------------------
+ kernel/power/nvs.c | 136 +++++++++++++++++++++++++++++++++++++++++++
+ kernel/power/suspend.c | 6 +
+ 8 files changed, 168 insertions(+), 161 deletions(-)
+
+--- a/arch/x86/kernel/e820.c
++++ b/arch/x86/kernel/e820.c
+@@ -729,7 +729,7 @@ static int __init e820_mark_nvs_memory(v
+ struct e820entry *ei = &e820.map[i];
+
+ if (ei->type == E820_NVS)
+- hibernate_nvs_register(ei->addr, ei->size);
++ suspend_nvs_register(ei->addr, ei->size);
+ }
+
+ return 0;
+--- a/drivers/acpi/sleep.c
++++ b/drivers/acpi/sleep.c
+@@ -393,7 +393,7 @@ static int acpi_hibernation_begin(void)
+ {
+ int error;
+
+- error = s4_no_nvs ? 0 : hibernate_nvs_alloc();
++ error = s4_no_nvs ? 0 : suspend_nvs_alloc();
+ if (!error) {
+ acpi_target_sleep_state = ACPI_STATE_S4;
+ acpi_sleep_tts_switch(acpi_target_sleep_state);
+@@ -407,7 +407,7 @@ static int acpi_hibernation_pre_snapshot
+ int error = acpi_pm_prepare();
+
+ if (!error)
+- hibernate_nvs_save();
++ suspend_nvs_save();
+
+ return error;
+ }
+@@ -432,7 +432,7 @@ static int acpi_hibernation_enter(void)
+
+ static void acpi_hibernation_finish(void)
+ {
+- hibernate_nvs_free();
++ suspend_nvs_free();
+ acpi_pm_finish();
+ }
+
+@@ -452,7 +452,7 @@ static void acpi_hibernation_leave(void)
+ panic("ACPI S4 hardware signature mismatch");
+ }
+ /* Restore the NVS memory area */
+- hibernate_nvs_restore();
++ suspend_nvs_restore();
+ }
+
+ static int acpi_pm_pre_restore(void)
+@@ -501,7 +501,7 @@ static int acpi_hibernation_begin_old(vo
+
+ if (!error) {
+ if (!s4_no_nvs)
+- error = hibernate_nvs_alloc();
++ error = suspend_nvs_alloc();
+ if (!error)
+ acpi_target_sleep_state = ACPI_STATE_S4;
+ }
+@@ -513,7 +513,7 @@ static int acpi_hibernation_pre_snapshot
+ int error = acpi_pm_disable_gpes();
+
+ if (!error)
+- hibernate_nvs_save();
++ suspend_nvs_save();
+
+ return error;
+ }
+--- a/include/linux/suspend.h
++++ b/include/linux/suspend.h
+@@ -256,22 +256,22 @@ static inline int hibernate(void) { retu
+ static inline bool system_entering_hibernation(void) { return false; }
+ #endif /* CONFIG_HIBERNATION */
+
+-#ifdef CONFIG_HIBERNATION_NVS
+-extern int hibernate_nvs_register(unsigned long start, unsigned long size);
+-extern int hibernate_nvs_alloc(void);
+-extern void hibernate_nvs_free(void);
+-extern void hibernate_nvs_save(void);
+-extern void hibernate_nvs_restore(void);
+-#else /* CONFIG_HIBERNATION_NVS */
+-static inline int hibernate_nvs_register(unsigned long a, unsigned long b)
++#ifdef CONFIG_SUSPEND_NVS
++extern int suspend_nvs_register(unsigned long start, unsigned long size);
++extern int suspend_nvs_alloc(void);
++extern void suspend_nvs_free(void);
++extern void suspend_nvs_save(void);
++extern void suspend_nvs_restore(void);
++#else /* CONFIG_SUSPEND_NVS */
++static inline int suspend_nvs_register(unsigned long a, unsigned long b)
+ {
+ return 0;
+ }
+-static inline int hibernate_nvs_alloc(void) { return 0; }
+-static inline void hibernate_nvs_free(void) {}
+-static inline void hibernate_nvs_save(void) {}
+-static inline void hibernate_nvs_restore(void) {}
+-#endif /* CONFIG_HIBERNATION_NVS */
++static inline int suspend_nvs_alloc(void) { return 0; }
++static inline void suspend_nvs_free(void) {}
++static inline void suspend_nvs_save(void) {}
++static inline void suspend_nvs_restore(void) {}
++#endif /* CONFIG_SUSPEND_NVS */
+
+ #ifdef CONFIG_PM_SLEEP
+ void save_processor_state(void);
+--- a/kernel/power/Kconfig
++++ b/kernel/power/Kconfig
+@@ -99,9 +99,13 @@ config PM_SLEEP_ADVANCED_DEBUG
+ depends on PM_ADVANCED_DEBUG
+ default n
+
++config SUSPEND_NVS
++ bool
++
+ config SUSPEND
+ bool "Suspend to RAM and standby"
+ depends on PM && ARCH_SUSPEND_POSSIBLE
++ select SUSPEND_NVS if HAS_IOMEM
+ default y
+ ---help---
+ Allow the system to enter sleep states in which main memory is
+@@ -130,13 +134,10 @@ config SUSPEND_FREEZER
+
+ Turning OFF this setting is NOT recommended! If in doubt, say Y.
+
+-config HIBERNATION_NVS
+- bool
+-
+ config HIBERNATION
+ bool "Hibernation (aka 'suspend to disk')"
+ depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
+- select HIBERNATION_NVS if HAS_IOMEM
++ select SUSPEND_NVS if HAS_IOMEM
+ ---help---
+ Enable the suspend to disk (STD) functionality, which is usually
+ called "hibernation" in user interfaces. STD checkpoints the
+--- a/kernel/power/Makefile
++++ b/kernel/power/Makefile
+@@ -9,6 +9,6 @@ obj-$(CONFIG_FREEZER) += process.o
+ obj-$(CONFIG_SUSPEND) += suspend.o
+ obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o
+ obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o
+-obj-$(CONFIG_HIBERNATION_NVS) += hibernate_nvs.o
++obj-$(CONFIG_SUSPEND_NVS) += nvs.o
+
+ obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o
+--- a/kernel/power/hibernate_nvs.c
++++ /dev/null
+@@ -1,136 +0,0 @@
+-/*
+- * linux/kernel/power/hibernate_nvs.c - Routines for handling NVS memory
+- *
+- * Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+- *
+- * This file is released under the GPLv2.
+- */
+-
+-#include <linux/io.h>
+-#include <linux/kernel.h>
+-#include <linux/list.h>
+-#include <linux/mm.h>
+-#include <linux/slab.h>
+-#include <linux/suspend.h>
+-
+-/*
+- * Platforms, like ACPI, may want us to save some memory used by them during
+- * hibernation and to restore the contents of this memory during the subsequent
+- * resume. The code below implements a mechanism allowing us to do that.
+- */
+-
+-struct nvs_page {
+- unsigned long phys_start;
+- unsigned int size;
+- void *kaddr;
+- void *data;
+- struct list_head node;
+-};
+-
+-static LIST_HEAD(nvs_list);
+-
+-/**
+- * hibernate_nvs_register - register platform NVS memory region to save
+- * @start - physical address of the region
+- * @size - size of the region
+- *
+- * The NVS region need not be page-aligned (both ends) and we arrange
+- * things so that the data from page-aligned addresses in this region will
+- * be copied into separate RAM pages.
+- */
+-int hibernate_nvs_register(unsigned long start, unsigned long size)
+-{
+- struct nvs_page *entry, *next;
+-
+- while (size > 0) {
+- unsigned int nr_bytes;
+-
+- entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL);
+- if (!entry)
+- goto Error;
+-
+- list_add_tail(&entry->node, &nvs_list);
+- entry->phys_start = start;
+- nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK);
+- entry->size = (size < nr_bytes) ? size : nr_bytes;
+-
+- start += entry->size;
+- size -= entry->size;
+- }
+- return 0;
+-
+- Error:
+- list_for_each_entry_safe(entry, next, &nvs_list, node) {
+- list_del(&entry->node);
+- kfree(entry);
+- }
+- return -ENOMEM;
+-}
+-
+-/**
+- * hibernate_nvs_free - free data pages allocated for saving NVS regions
+- */
+-void hibernate_nvs_free(void)
+-{
+- struct nvs_page *entry;
+-
+- list_for_each_entry(entry, &nvs_list, node)
+- if (entry->data) {
+- free_page((unsigned long)entry->data);
+- entry->data = NULL;
+- if (entry->kaddr) {
+- iounmap(entry->kaddr);
+- entry->kaddr = NULL;
+- }
+- }
+-}
+-
+-/**
+- * hibernate_nvs_alloc - allocate memory necessary for saving NVS regions
+- */
+-int hibernate_nvs_alloc(void)
+-{
+- struct nvs_page *entry;
+-
+- list_for_each_entry(entry, &nvs_list, node) {
+- entry->data = (void *)__get_free_page(GFP_KERNEL);
+- if (!entry->data) {
+- hibernate_nvs_free();
+- return -ENOMEM;
+- }
+- }
+- return 0;
+-}
+-
+-/**
+- * hibernate_nvs_save - save NVS memory regions
+- */
+-void hibernate_nvs_save(void)
+-{
+- struct nvs_page *entry;
+-
+- printk(KERN_INFO "PM: Saving platform NVS memory\n");
+-
+- list_for_each_entry(entry, &nvs_list, node)
+- if (entry->data) {
+- entry->kaddr = ioremap(entry->phys_start, entry->size);
+- memcpy(entry->data, entry->kaddr, entry->size);
+- }
+-}
+-
+-/**
+- * hibernate_nvs_restore - restore NVS memory regions
+- *
+- * This function is going to be called with interrupts disabled, so it
+- * cannot iounmap the virtual addresses used to access the NVS region.
+- */
+-void hibernate_nvs_restore(void)
+-{
+- struct nvs_page *entry;
+-
+- printk(KERN_INFO "PM: Restoring platform NVS memory\n");
+-
+- list_for_each_entry(entry, &nvs_list, node)
+- if (entry->data)
+- memcpy(entry->kaddr, entry->data, entry->size);
+-}
+--- /dev/null
++++ b/kernel/power/nvs.c
+@@ -0,0 +1,136 @@
++/*
++ * linux/kernel/power/hibernate_nvs.c - Routines for handling NVS memory
++ *
++ * Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
++ *
++ * This file is released under the GPLv2.
++ */
++
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/suspend.h>
++
++/*
++ * Platforms, like ACPI, may want us to save some memory used by them during
++ * suspend and to restore the contents of this memory during the subsequent
++ * resume. The code below implements a mechanism allowing us to do that.
++ */
++
++struct nvs_page {
++ unsigned long phys_start;
++ unsigned int size;
++ void *kaddr;
++ void *data;
++ struct list_head node;
++};
++
++static LIST_HEAD(nvs_list);
++
++/**
++ * suspend_nvs_register - register platform NVS memory region to save
++ * @start - physical address of the region
++ * @size - size of the region
++ *
++ * The NVS region need not be page-aligned (both ends) and we arrange
++ * things so that the data from page-aligned addresses in this region will
++ * be copied into separate RAM pages.
++ */
++int suspend_nvs_register(unsigned long start, unsigned long size)
++{
++ struct nvs_page *entry, *next;
++
++ while (size > 0) {
++ unsigned int nr_bytes;
++
++ entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL);
++ if (!entry)
++ goto Error;
++
++ list_add_tail(&entry->node, &nvs_list);
++ entry->phys_start = start;
++ nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK);
++ entry->size = (size < nr_bytes) ? size : nr_bytes;
++
++ start += entry->size;
++ size -= entry->size;
++ }
++ return 0;
++
++ Error:
++ list_for_each_entry_safe(entry, next, &nvs_list, node) {
++ list_del(&entry->node);
++ kfree(entry);
++ }
++ return -ENOMEM;
++}
++
++/**
++ * suspend_nvs_free - free data pages allocated for saving NVS regions
++ */
++void suspend_nvs_free(void)
++{
++ struct nvs_page *entry;
++
++ list_for_each_entry(entry, &nvs_list, node)
++ if (entry->data) {
++ free_page((unsigned long)entry->data);
++ entry->data = NULL;
++ if (entry->kaddr) {
++ iounmap(entry->kaddr);
++ entry->kaddr = NULL;
++ }
++ }
++}
++
++/**
++ * suspend_nvs_alloc - allocate memory necessary for saving NVS regions
++ */
++int suspend_nvs_alloc(void)
++{
++ struct nvs_page *entry;
++
++ list_for_each_entry(entry, &nvs_list, node) {
++ entry->data = (void *)__get_free_page(GFP_KERNEL);
++ if (!entry->data) {
++ suspend_nvs_free();
++ return -ENOMEM;
++ }
++ }
++ return 0;
++}
++
++/**
++ * suspend_nvs_save - save NVS memory regions
++ */
++void suspend_nvs_save(void)
++{
++ struct nvs_page *entry;
++
++ printk(KERN_INFO "PM: Saving platform NVS memory\n");
++
++ list_for_each_entry(entry, &nvs_list, node)
++ if (entry->data) {
++ entry->kaddr = ioremap(entry->phys_start, entry->size);
++ memcpy(entry->data, entry->kaddr, entry->size);
++ }
++}
++
++/**
++ * suspend_nvs_restore - restore NVS memory regions
++ *
++ * This function is going to be called with interrupts disabled, so it
++ * cannot iounmap the virtual addresses used to access the NVS region.
++ */
++void suspend_nvs_restore(void)
++{
++ struct nvs_page *entry;
++
++ printk(KERN_INFO "PM: Restoring platform NVS memory\n");
++
++ list_for_each_entry(entry, &nvs_list, node)
++ if (entry->data)
++ memcpy(entry->kaddr, entry->data, entry->size);
++}
+--- a/kernel/power/suspend.c
++++ b/kernel/power/suspend.c
+@@ -16,6 +16,12 @@
+ #include <linux/cpu.h>
+ #include <linux/syscalls.h>
+ #include <linux/gfp.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/suspend.h>
+
+ #include "power.h"
+
--- /dev/null
+From d46b36e7f927772bb72524dc9f1e384e3cb4a975 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 15 May 2010 13:45:37 -0300
+Subject: V4L/DVB: budget: Select correct frontends
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit d46b36e7f927772bb72524dc9f1e384e3cb4a975 upstream.
+
+Update the Kconfig selections to match the code.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/dvb/ttpci/Kconfig | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/dvb/ttpci/Kconfig
++++ b/drivers/media/dvb/ttpci/Kconfig
+@@ -68,13 +68,14 @@ config DVB_BUDGET
+ select DVB_VES1820 if !DVB_FE_CUSTOMISE
+ select DVB_L64781 if !DVB_FE_CUSTOMISE
+ select DVB_TDA8083 if !DVB_FE_CUSTOMISE
+- select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+- select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+ select DVB_S5H1420 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10086 if !DVB_FE_CUSTOMISE
+ select DVB_TDA826X if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_TDA1004X if !DVB_FE_CUSTOMISE
++ select DVB_ISL6423 if !DVB_FE_CUSTOMISE
++ select DVB_STV090x if !DVB_FE_CUSTOMISE
++ select DVB_STV6110x if !DVB_FE_CUSTOMISE
+ help
+ Support for simple SAA7146 based DVB cards (so called Budget-
+ or Nova-PCI cards) without onboard MPEG2 decoder, and without
--- /dev/null
+From 5c331fc8c19e181bffab46e9d18e1637cdc47170 Mon Sep 17 00:00:00 2001
+From: Ang Way Chuang <wcang79@gmail.com>
+Date: Thu, 27 May 2010 02:02:09 -0300
+Subject: V4L/DVB: dvb-core: Fix ULE decapsulation bug
+
+From: Ang Way Chuang <wcang79@gmail.com>
+
+commit 5c331fc8c19e181bffab46e9d18e1637cdc47170 upstream.
+
+Fix ULE decapsulation bug when less than 4 bytes of ULE SNDU is packed
+into the remaining bytes of a MPEG2-TS frame
+
+ULE (Unidirectional Lightweight Encapsulation RFC 4326) decapsulation
+code has a bug that incorrectly treats ULE SNDU packed into the
+remaining 2 or 3 bytes of a MPEG2-TS frame as having invalid pointer
+field on the subsequent MPEG2-TS frame.
+
+Signed-off-by: Ang Way Chuang <wcang@nav6.org>
+Acked-by: Jarod Wilson <jarod@redhat.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/dvb/dvb-core/dvb_net.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/dvb/dvb-core/dvb_net.c
++++ b/drivers/media/dvb/dvb-core/dvb_net.c
+@@ -350,6 +350,7 @@ static void dvb_net_ule( struct net_devi
+ const u8 *ts, *ts_end, *from_where = NULL;
+ u8 ts_remain = 0, how_much = 0, new_ts = 1;
+ struct ethhdr *ethh = NULL;
++ bool error = false;
+
+ #ifdef ULE_DEBUG
+ /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */
+@@ -459,10 +460,16 @@ static void dvb_net_ule( struct net_devi
+
+ /* Drop partly decoded SNDU, reset state, resync on PUSI. */
+ if (priv->ule_skb) {
+- dev_kfree_skb( priv->ule_skb );
++ error = true;
++ dev_kfree_skb(priv->ule_skb);
++ }
++
++ if (error || priv->ule_sndu_remain) {
+ dev->stats.rx_errors++;
+ dev->stats.rx_frame_errors++;
++ error = false;
+ }
++
+ reset_ule(priv);
+ priv->need_pusi = 1;
+ continue;
+@@ -534,6 +541,7 @@ static void dvb_net_ule( struct net_devi
+ from_where += 2;
+ }
+
++ priv->ule_sndu_remain = priv->ule_sndu_len + 2;
+ /*
+ * State of current TS:
+ * ts_remain (remaining bytes in the current TS cell)
+@@ -543,6 +551,7 @@ static void dvb_net_ule( struct net_devi
+ */
+ switch (ts_remain) {
+ case 1:
++ priv->ule_sndu_remain--;
+ priv->ule_sndu_type = from_where[0] << 8;
+ priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */
+ ts_remain -= 1; from_where += 1;
+@@ -556,6 +565,7 @@ static void dvb_net_ule( struct net_devi
+ default: /* complete ULE header is present in current TS. */
+ /* Extract ULE type field. */
+ if (priv->ule_sndu_type_1) {
++ priv->ule_sndu_type_1 = 0;
+ priv->ule_sndu_type |= from_where[0];
+ from_where += 1; /* points to payload start. */
+ ts_remain -= 1;
--- /dev/null
+From 806b07c29b711aaf90c81d2a19711607769f8246 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <khali@linux-fr.org>
+Date: Wed, 26 May 2010 10:05:11 -0300
+Subject: V4L/DVB: FusionHDTV: Use quick reads for I2C IR device probing
+
+From: Jean Delvare <khali@linux-fr.org>
+
+commit 806b07c29b711aaf90c81d2a19711607769f8246 upstream.
+
+IR support on FusionHDTV cards is broken since kernel 2.6.31. One side
+effect of the switch to the standard binding model for IR I2C devices
+was to let i2c-core do the probing instead of the ir-kbd-i2c driver.
+There is a slight difference between the two probe methods: i2c-core
+uses 0-byte writes, while the ir-kbd-i2c was using 0-byte reads. As
+some IR I2C devices only support reads, the new probe method fails to
+detect them.
+
+For now, revert to letting the driver do the probe, using 0-byte
+reads. In the future, i2c-core will be extended to let callers of
+i2c_new_probed_device() provide a custom probing function.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Tested-by: "Timothy D. Lenz" <tlenz@vorgon.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/cx23885/cx23885-i2c.c | 12 +++++++++++-
+ drivers/media/video/cx88/cx88-i2c.c | 16 +++++++++++++++-
+ 2 files changed, 26 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/video/cx23885/cx23885-i2c.c
++++ b/drivers/media/video/cx23885/cx23885-i2c.c
+@@ -365,7 +365,17 @@ int cx23885_i2c_register(struct cx23885_
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+- i2c_new_probed_device(&bus->i2c_adap, &info, addr_list);
++ /*
++ * We can't call i2c_new_probed_device() because it uses
++ * quick writes for probing and the IR receiver device only
++ * replies to reads.
++ */
++ if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0,
++ I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK,
++ NULL) >= 0) {
++ info.addr = addr_list[0];
++ i2c_new_device(&bus->i2c_adap, &info);
++ }
+ }
+
+ return bus->i2c_rc;
+--- a/drivers/media/video/cx88/cx88-i2c.c
++++ b/drivers/media/video/cx88/cx88-i2c.c
+@@ -188,10 +188,24 @@ int cx88_i2c_init(struct cx88_core *core
+ 0x18, 0x6b, 0x71,
+ I2C_CLIENT_END
+ };
++ const unsigned short *addrp;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+- i2c_new_probed_device(&core->i2c_adap, &info, addr_list);
++ /*
++ * We can't call i2c_new_probed_device() because it uses
++ * quick writes for probing and at least some R receiver
++ * devices only reply to reads.
++ */
++ for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) {
++ if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0,
++ I2C_SMBUS_READ, 0,
++ I2C_SMBUS_QUICK, NULL) >= 0) {
++ info.addr = *addrp;
++ i2c_new_device(&core->i2c_adap, &info);
++ break;
++ }
++ }
+ }
+ return core->i2c_rc;
+ }
--- /dev/null
+From f129b03ba272c86c42ad476684caa0d6109cb383 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Sat, 13 Mar 2010 18:12:15 -0300
+Subject: V4L/DVB: uvcvideo: Add support for Packard Bell EasyNote MX52 integrated webcam
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+commit f129b03ba272c86c42ad476684caa0d6109cb383 upstream.
+
+The camera requires the STREAM_NO_FID quirk. Add a corresponding entry
+in the device IDs list.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvc_driver.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/media/video/uvc/uvc_driver.c
++++ b/drivers/media/video/uvc/uvc_driver.c
+@@ -2105,6 +2105,15 @@ static struct usb_device_id uvc_ids[] =
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
++ /* Syntek (Packard Bell EasyNote MX52 */
++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
++ | USB_DEVICE_ID_MATCH_INT_INFO,
++ .idVendor = 0x174f,
++ .idProduct = 0x8a12,
++ .bInterfaceClass = USB_CLASS_VIDEO,
++ .bInterfaceSubClass = 1,
++ .bInterfaceProtocol = 0,
++ .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Syntek (Asus F9SG) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
--- /dev/null
+From 1e4d05bc95a0fe2972c5c91ed45466587d07cd2c Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 4 Mar 2010 07:51:25 -0300
+Subject: V4L/DVB: uvcvideo: Add support for unbranded Arkmicro 18ec:3290 webcams
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+commit 1e4d05bc95a0fe2972c5c91ed45466587d07cd2c upstream.
+
+The camera requires the PROBE_DEF quirk. Add a corresponding entry in
+the device IDs list.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvc_driver.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/media/video/uvc/uvc_driver.c
++++ b/drivers/media/video/uvc/uvc_driver.c
+@@ -2169,6 +2169,15 @@ static struct usb_device_id uvc_ids[] =
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
++ /* Arkmicro unbranded */
++ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
++ | USB_DEVICE_ID_MATCH_INT_INFO,
++ .idVendor = 0x18ec,
++ .idProduct = 0x3290,
++ .bInterfaceClass = USB_CLASS_VIDEO,
++ .bInterfaceSubClass = 1,
++ .bInterfaceProtocol = 0,
++ .driver_info = UVC_QUIRK_PROBE_DEF },
+ /* Bodelin ProScopeHR */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_DEV_HI
--- /dev/null
+From 61421206833a4085d9bdf35b2b84cd9a67dfdfac Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Mon, 12 Apr 2010 10:41:22 -0300
+Subject: V4L/DVB: uvcvideo: Add support for V4L2_PIX_FMT_Y16
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+commit 61421206833a4085d9bdf35b2b84cd9a67dfdfac upstream.
+
+The Miricle 307K (17dc:0202) camera reports a 16-bit greyscale format,
+support it in the driver.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvc_driver.c | 7 ++++++-
+ drivers/media/video/uvc/uvcvideo.h | 4 +++-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/video/uvc/uvc_driver.c
++++ b/drivers/media/video/uvc/uvc_driver.c
+@@ -91,11 +91,16 @@ static struct uvc_format_desc uvc_fmts[]
+ .fcc = V4L2_PIX_FMT_UYVY,
+ },
+ {
+- .name = "Greyscale",
++ .name = "Greyscale (8-bit)",
+ .guid = UVC_GUID_FORMAT_Y800,
+ .fcc = V4L2_PIX_FMT_GREY,
+ },
+ {
++ .name = "Greyscale (16-bit)",
++ .guid = UVC_GUID_FORMAT_Y16,
++ .fcc = V4L2_PIX_FMT_Y16,
++ },
++ {
+ .name = "RGB Bayer",
+ .guid = UVC_GUID_FORMAT_BY8,
+ .fcc = V4L2_PIX_FMT_SBGGR8,
+--- a/drivers/media/video/uvc/uvcvideo.h
++++ b/drivers/media/video/uvc/uvcvideo.h
+@@ -131,11 +131,13 @@ struct uvc_xu_control {
+ #define UVC_GUID_FORMAT_Y800 \
+ { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
++#define UVC_GUID_FORMAT_Y16 \
++ { 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
++ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+ #define UVC_GUID_FORMAT_BY8 \
+ { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+
+-
+ /* ------------------------------------------------------------------------
+ * Driver specific constants.
+ */
--- /dev/null
+From 1817176a86352f65210139d4c794ad2d19fc6b63 Mon Sep 17 00:00:00 2001
+From: Dan Rosenberg <dan.j.rosenberg@gmail.com>
+Date: Thu, 24 Jun 2010 12:07:47 +1000
+Subject: xfs: prevent swapext from operating on write-only files
+
+From: Dan Rosenberg <dan.j.rosenberg@gmail.com>
+
+commit 1817176a86352f65210139d4c794ad2d19fc6b63 upstream.
+
+This patch prevents user "foo" from using the SWAPEXT ioctl to swap
+a write-only file owned by user "bar" into a file owned by "foo" and
+subsequently reading it. It does so by checking that the file
+descriptors passed to the ioctl are also opened for reading.
+
+Signed-off-by: Dan Rosenberg <dan.j.rosenberg@gmail.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/xfs/xfs_dfrag.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/xfs/xfs_dfrag.c
++++ b/fs/xfs/xfs_dfrag.c
+@@ -69,7 +69,9 @@ xfs_swapext(
+ goto out;
+ }
+
+- if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) {
++ if (!(file->f_mode & FMODE_WRITE) ||
++ !(file->f_mode & FMODE_READ) ||
++ (file->f_flags & O_APPEND)) {
+ error = XFS_ERROR(EBADF);
+ goto out_put_file;
+ }
+@@ -81,6 +83,7 @@ xfs_swapext(
+ }
+
+ if (!(tmp_file->f_mode & FMODE_WRITE) ||
++ !(tmp_file->f_mode & FMODE_READ) ||
+ (tmp_file->f_flags & O_APPEND)) {
+ error = XFS_ERROR(EBADF);
+ goto out_put_tmp_file;