diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-07 14:56:51 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-07 14:56:51 -0700 |
commit | 0c5b40fb181690fcd94f9bb9d2bccf1dd9d0473b (patch) | |
tree | 460cbf3ac6ed4f8210bbcff10111d075617290c1 | |
parent | 1f8ea72769b02f78266813657eb11ed6835190c4 (diff) | |
download | stable-queue-0c5b40fb181690fcd94f9bb9d2bccf1dd9d0473b.tar.gz |
.39 patches
30 files changed, 1987 insertions, 0 deletions
diff --git a/queue-2.6.39/.inet_diag-fix-inet_diag_bc_audit.patch.swp b/queue-2.6.39/.inet_diag-fix-inet_diag_bc_audit.patch.swp Binary files differdeleted file mode 100644 index 8aba45d7cf..0000000000 --- a/queue-2.6.39/.inet_diag-fix-inet_diag_bc_audit.patch.swp +++ /dev/null diff --git a/queue-2.6.39/arm-samsung-serial-fix-on-handling-of-one-clock-source.patch b/queue-2.6.39/arm-samsung-serial-fix-on-handling-of-one-clock-source.patch new file mode 100644 index 0000000000..d7c4dc1e83 --- /dev/null +++ b/queue-2.6.39/arm-samsung-serial-fix-on-handling-of-one-clock-source.patch @@ -0,0 +1,75 @@ +From 470f22975448a65a1084a6f0721fa5df15323f02 Mon Sep 17 00:00:00 2001 +From: Boojin Kim <boojin.kim@samsung.com> +Date: Fri, 27 May 2011 19:04:03 -0700 +Subject: ARM: SAMSUNG: serial: Fix on handling of one clock source + for UART + +From: Boojin Kim <boojin.kim@samsung.com> + +commit 470f22975448a65a1084a6f0721fa5df15323f02 upstream. + +This patch fixes the way of comparison for handling of two or more +clock sources for UART. + +For example, if just only one clock source is defined even though +there are two clock sources for UART, the serial driver does not +set proper clock up. Of course, it is problem. + +So this patch changes the condition of comparison to avoid useless +setup clock and adds a flag 'NO_NEED_CHECK_CLKSRC' which means +selection of source clock is not required. + +In addition, since the Exynos4210 has only one clock source for UART +this patch adds the flag into its common_init_uarts(). + +Signed-off-by: Boojin Kim <boojin.kim@samsung.com> +Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/arm/mach-exynos4/init.c | 1 + + arch/arm/plat-samsung/include/plat/regs-serial.h | 2 ++ + drivers/tty/serial/s5pv210.c | 4 ++-- + 3 files changed, 5 insertions(+), 2 deletions(-) + +--- a/arch/arm/mach-exynos4/init.c ++++ b/arch/arm/mach-exynos4/init.c +@@ -35,6 +35,7 @@ void __init exynos4_common_init_uarts(st + tcfg->clocks = exynos4_serial_clocks; + tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks); + } ++ tcfg->flags |= NO_NEED_CHECK_CLKSRC; + } + + s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); +--- a/arch/arm/plat-samsung/include/plat/regs-serial.h ++++ b/arch/arm/plat-samsung/include/plat/regs-serial.h +@@ -224,6 +224,8 @@ + #define S5PV210_UFSTAT_RXMASK (255<<0) + #define S5PV210_UFSTAT_RXSHIFT (0) + ++#define NO_NEED_CHECK_CLKSRC 1 ++ + #ifndef __ASSEMBLY__ + + /* struct s3c24xx_uart_clksrc +--- a/drivers/tty/serial/s5pv210.c ++++ b/drivers/tty/serial/s5pv210.c +@@ -31,7 +31,7 @@ static int s5pv210_serial_setsource(stru + struct s3c2410_uartcfg *cfg = port->dev->platform_data; + unsigned long ucon = rd_regl(port, S3C2410_UCON); + +- if ((cfg->clocks_size) == 1) ++ if (cfg->flags & NO_NEED_CHECK_CLKSRC) + return 0; + + if (strcmp(clk->name, "pclk") == 0) +@@ -56,7 +56,7 @@ static int s5pv210_serial_getsource(stru + + clk->divisor = 1; + +- if ((cfg->clocks_size) == 1) ++ if (cfg->flags & NO_NEED_CHECK_CLKSRC) + return 0; + + switch (ucon & S5PV210_UCON_CLKMASK) { diff --git a/queue-2.6.39/ath5k-disable-fast-channel-switching-by-default.patch b/queue-2.6.39/ath5k-disable-fast-channel-switching-by-default.patch new file mode 100644 index 0000000000..330aa3082c --- /dev/null +++ b/queue-2.6.39/ath5k-disable-fast-channel-switching-by-default.patch @@ -0,0 +1,73 @@ +From a99168eece601d2a79ecfcb968ce226f2f30cf98 Mon Sep 17 00:00:00 2001 +From: Nick Kossifidis <mickflemm@gmail.com> +Date: Thu, 2 Jun 2011 03:09:48 +0300 +Subject: ath5k: Disable fast channel switching by default + +From: Nick Kossifidis <mickflemm@gmail.com> + +commit a99168eece601d2a79ecfcb968ce226f2f30cf98 upstream. + +Disable fast channel change by default on AR2413/AR5413 due to +some bug reports (it still works for me but it's better to be safe). +Add a module parameter "fastchanswitch" in case anyone wants to enable +it and play with it. + +Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> +Tested-by: Sedat Dilek <sedat.dilek@gmail.com> +Signed-off-by: John W. Linville <linville@tuxdriver.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/net/wireless/ath/ath5k/base.c | 11 ++++++++++- + drivers/net/wireless/ath/ath5k/reset.c | 5 ++++- + 2 files changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath5k/base.c ++++ b/drivers/net/wireless/ath/ath5k/base.c +@@ -72,6 +72,11 @@ static int modparam_all_channels; + module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); + MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); + ++static int modparam_fastchanswitch; ++module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); ++MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); ++ ++ + /* Module info */ + MODULE_AUTHOR("Jiri Slaby"); + MODULE_AUTHOR("Nick Kossifidis"); +@@ -2644,6 +2649,7 @@ ath5k_reset(struct ath5k_softc *sc, stru + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + int ret, ani_mode; ++ bool fast; + + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); + +@@ -2663,7 +2669,10 @@ ath5k_reset(struct ath5k_softc *sc, stru + ath5k_drain_tx_buffs(sc); + if (chan) + sc->curchan = chan; +- ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL, ++ ++ fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0; ++ ++ ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, + skip_pcu); + if (ret) { + ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); +--- a/drivers/net/wireless/ath/ath5k/reset.c ++++ b/drivers/net/wireless/ath/ath5k/reset.c +@@ -1119,8 +1119,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, + /* Non fatal, can happen eg. + * on mode change */ + ret = 0; +- } else ++ } else { ++ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET, ++ "fast chan change successful\n"); + return 0; ++ } + } + + /* diff --git a/queue-2.6.39/ath5k-fix-memory-leak-when-fewer-than-n_pd_curves-are-in.patch b/queue-2.6.39/ath5k-fix-memory-leak-when-fewer-than-n_pd_curves-are-in.patch new file mode 100644 index 0000000000..f345c3380e --- /dev/null +++ b/queue-2.6.39/ath5k-fix-memory-leak-when-fewer-than-n_pd_curves-are-in.patch @@ -0,0 +1,44 @@ +From a0b8de350be458b33248e48b2174d9af8a4c4798 Mon Sep 17 00:00:00 2001 +From: "Eugene A. Shatokhin" <dame_eugene@mail.ru> +Date: Tue, 28 Jun 2011 23:04:51 -0400 +Subject: ath5k: fix memory leak when fewer than N_PD_CURVES are in + use + +From: "Eugene A. Shatokhin" <dame_eugene@mail.ru> + +commit a0b8de350be458b33248e48b2174d9af8a4c4798 upstream. + +We would free the proper number of curves, but in the wrong +slots, due to a missing level of indirection through +the pdgain_idx table. + +It's simpler just to try to free all four slots, so do that. + +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/eeprom.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/ath/ath5k/eeprom.c ++++ b/drivers/net/wireless/ath/ath5k/eeprom.c +@@ -1565,14 +1565,12 @@ ath5k_eeprom_free_pcal_info(struct ath5k + if (!chinfo[pier].pd_curves) + continue; + +- for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { ++ for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) { + struct ath5k_pdgain_info *pd = + &chinfo[pier].pd_curves[pdg]; + +- if (pd != NULL) { +- kfree(pd->pd_step); +- kfree(pd->pd_pwr); +- } ++ kfree(pd->pd_step); ++ kfree(pd->pd_pwr); + } + + kfree(chinfo[pier].pd_curves); diff --git a/queue-2.6.39/ath9k-fix-suspend-resume-when-no-interface-is-up.patch b/queue-2.6.39/ath9k-fix-suspend-resume-when-no-interface-is-up.patch new file mode 100644 index 0000000000..4e268d1c4f --- /dev/null +++ b/queue-2.6.39/ath9k-fix-suspend-resume-when-no-interface-is-up.patch @@ -0,0 +1,36 @@ +From c31eb8e926835582cd186b33a7a864880a4c0c79 Mon Sep 17 00:00:00 2001 +From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> +Date: Tue, 28 Jun 2011 18:21:19 +0530 +Subject: ath9k: Fix suspend/resume when no interface is UP + +From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> + +commit c31eb8e926835582cd186b33a7a864880a4c0c79 upstream. + +When no interface has been brought up, the chip's power +state continued as AWAKE. So during resume, the chip never +been powered up. + +Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> +Signed-off-by: John W. Linville <linville@tuxdriver.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/net/wireless/ath/ath9k/pci.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -278,6 +278,12 @@ static int ath_pci_suspend(struct device + + ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); + ++ /* The device has to be moved to FULLSLEEP forcibly. ++ * Otherwise the chip never moved to full sleep, ++ * when no interface is up. ++ */ ++ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); ++ + return 0; + } + diff --git a/queue-2.6.39/clocksource-make-watchdog-robust-vs.-interruption.patch b/queue-2.6.39/clocksource-make-watchdog-robust-vs.-interruption.patch new file mode 100644 index 0000000000..ea419f89b0 --- /dev/null +++ b/queue-2.6.39/clocksource-make-watchdog-robust-vs.-interruption.patch @@ -0,0 +1,100 @@ +From b5199515c25cca622495eb9c6a8a1d275e775088 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner <tglx@linutronix.de> +Date: Thu, 16 Jun 2011 16:22:08 +0200 +Subject: clocksource: Make watchdog robust vs. interruption + +From: Thomas Gleixner <tglx@linutronix.de> + +commit b5199515c25cca622495eb9c6a8a1d275e775088 upstream. + +The clocksource watchdog code is interruptible and it has been +observed that this can trigger false positives which disable the TSC. + +The reason is that an interrupt storm or a long running interrupt +handler between the read of the watchdog source and the read of the +TSC brings the two far enough apart that the delta is larger than the +unstable treshold. Move both reads into a short interrupt disabled +region to avoid that. + +Reported-and-tested-by: Vernon Mauery <vernux@us.ibm.com> +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + include/linux/clocksource.h | 1 + + kernel/time/clocksource.c | 24 +++++++++++++----------- + 2 files changed, 14 insertions(+), 11 deletions(-) + +--- a/include/linux/clocksource.h ++++ b/include/linux/clocksource.h +@@ -192,6 +192,7 @@ struct clocksource { + #ifdef CONFIG_CLOCKSOURCE_WATCHDOG + /* Watchdog related data, used by the framework */ + struct list_head wd_list; ++ cycle_t cs_last; + cycle_t wd_last; + #endif + }; +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -185,7 +185,6 @@ static struct clocksource *watchdog; + static struct timer_list watchdog_timer; + static DECLARE_WORK(watchdog_work, clocksource_watchdog_work); + static DEFINE_SPINLOCK(watchdog_lock); +-static cycle_t watchdog_last; + static int watchdog_running; + + static int clocksource_watchdog_kthread(void *data); +@@ -254,11 +253,6 @@ static void clocksource_watchdog(unsigne + if (!watchdog_running) + goto out; + +- wdnow = watchdog->read(watchdog); +- wd_nsec = clocksource_cyc2ns((wdnow - watchdog_last) & watchdog->mask, +- watchdog->mult, watchdog->shift); +- watchdog_last = wdnow; +- + list_for_each_entry(cs, &watchdog_list, wd_list) { + + /* Clocksource already marked unstable? */ +@@ -268,19 +262,28 @@ static void clocksource_watchdog(unsigne + continue; + } + ++ local_irq_disable(); + csnow = cs->read(cs); ++ wdnow = watchdog->read(watchdog); ++ local_irq_enable(); + + /* Clocksource initialized ? */ + if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) { + cs->flags |= CLOCK_SOURCE_WATCHDOG; +- cs->wd_last = csnow; ++ cs->wd_last = wdnow; ++ cs->cs_last = csnow; + continue; + } + +- /* Check the deviation from the watchdog clocksource. */ +- cs_nsec = clocksource_cyc2ns((csnow - cs->wd_last) & ++ wd_nsec = clocksource_cyc2ns((wdnow - cs->wd_last) & watchdog->mask, ++ watchdog->mult, watchdog->shift); ++ ++ cs_nsec = clocksource_cyc2ns((csnow - cs->cs_last) & + cs->mask, cs->mult, cs->shift); +- cs->wd_last = csnow; ++ cs->cs_last = csnow; ++ cs->wd_last = wdnow; ++ ++ /* Check the deviation from the watchdog clocksource. */ + if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) { + clocksource_unstable(cs, cs_nsec - wd_nsec); + continue; +@@ -318,7 +321,6 @@ static inline void clocksource_start_wat + return; + init_timer(&watchdog_timer); + watchdog_timer.function = clocksource_watchdog; +- watchdog_last = watchdog->read(watchdog); + watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; + add_timer_on(&watchdog_timer, cpumask_first(cpu_online_mask)); + watchdog_running = 1; diff --git a/queue-2.6.39/connector-correctly-set-the-error-code-in-case-of-success.patch b/queue-2.6.39/connector-correctly-set-the-error-code-in-case-of-success.patch new file mode 100644 index 0000000000..99cad69716 --- /dev/null +++ b/queue-2.6.39/connector-correctly-set-the-error-code-in-case-of-success.patch @@ -0,0 +1,32 @@ +From 663dd6dcaf7e95526e469e91f41972a9c0cca30c Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" <kys@microsoft.com> +Date: Tue, 17 May 2011 15:25:38 -0700 +Subject: Connector: Correctly set the error code in case of success + when dispatching receive callbacks + +From: "K. Y. Srinivasan" <kys@microsoft.com> + +commit 663dd6dcaf7e95526e469e91f41972a9c0cca30c upstream. + +The recent changes to the connector code introduced this bug where even +when a callback was invoked, we would return an error resulting in +double freeing of the skb. This patch fixes this bug. + +Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> +Acked-by: Evgeniy Polyakov <zbr@ioremap.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/connector/connector.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/connector/connector.c ++++ b/drivers/connector/connector.c +@@ -139,6 +139,7 @@ static int cn_call_callback(struct sk_bu + spin_unlock_bh(&dev->cbdev->queue_lock); + + if (cbq != NULL) { ++ err = 0; + cbq->callback(msg, nsp); + kfree_skb(skb); + cn_queue_release_callback(cbq); diff --git a/queue-2.6.39/connector-set-the-cn_netlink_users-correctly.patch b/queue-2.6.39/connector-set-the-cn_netlink_users-correctly.patch new file mode 100644 index 0000000000..ba410f872d --- /dev/null +++ b/queue-2.6.39/connector-set-the-cn_netlink_users-correctly.patch @@ -0,0 +1,31 @@ +From ea2c00095c022846dd8dfd211de05154d3e4e1b8 Mon Sep 17 00:00:00 2001 +From: "K. Y. Srinivasan" <kys@microsoft.com> +Date: Tue, 17 May 2011 15:25:37 -0700 +Subject: Connector: Set the CN_NETLINK_USERS correctly + +From: "K. Y. Srinivasan" <kys@microsoft.com> + +commit ea2c00095c022846dd8dfd211de05154d3e4e1b8 upstream. + +The CN_NETLINK_USERS must be set to the highest valid index +1. +Thanks to Evgeniy for pointing this out. + +Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> +Acked-by: Evgeniy Polyakov <zbr@ioremap.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + include/linux/connector.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/connector.h ++++ b/include/linux/connector.h +@@ -44,7 +44,7 @@ + #define CN_VAL_DRBD 0x1 + #define CN_KVP_IDX 0x9 /* HyperV KVP */ + +-#define CN_NETLINK_USERS 9 ++#define CN_NETLINK_USERS 10 /* Highest index + 1 */ + + /* + * Maximum connector's message size. diff --git a/queue-2.6.39/drm-i915-fix-gen6-snb-missed-blt-ring-interrupts.patch b/queue-2.6.39/drm-i915-fix-gen6-snb-missed-blt-ring-interrupts.patch new file mode 100644 index 0000000000..7bb2f7a2da --- /dev/null +++ b/queue-2.6.39/drm-i915-fix-gen6-snb-missed-blt-ring-interrupts.patch @@ -0,0 +1,58 @@ +From 498e720b96379d8ee9c294950a01534a73defcf3 Mon Sep 17 00:00:00 2001 +From: Daniel J Blueman <daniel.blueman@gmail.com> +Date: Fri, 17 Jun 2011 11:32:19 -0700 +Subject: drm/i915: Fix gen6 (SNB) missed BLT ring interrupts. + +From: Daniel J Blueman <daniel.blueman@gmail.com> + +commit 498e720b96379d8ee9c294950a01534a73defcf3 upstream. + +The failure appeared in dmesg as: + +[drm:i915_hangcheck_ring_idle] *ERROR* Hangcheck timer elapsed... blt +ring idle [waiting on 35064155, at 35064155], missed IRQ? + +This works around that problem on by making the blitter command +streamer write interrupt state to the Hardware Status Page when a +MI_USER_INTERRUPT command is decoded, which appears to force the seqno +out to memory before the interrupt happens. + +v1->v2: Moved to prior interrupt handler installation and RMW flags as +per feedback. +v2->v3: Removed RMW of flags (by anholt) + +Signed-off-by: Daniel J Blueman <daniel.blueman@gmail.com> +Signed-off-by: Eric Anholt <eric@anholt.net> +Tested-by: Chris Wilson <chris@chris-wilson.co.uk> [v1] +Tested-by: Eric Anholt <eric@anholt.net> [v1,v3] + (incidence of the bug with a testcase went from avg 2/1000 to + 0/12651 in the latest test run (plus more for v1)) +Tested-by: Kenneth Graunke <kenneth@whitecape.org> [v1] +Tested-by: Robert Hooker <robert.hooker@canonical.com> [v1] +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33394 +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/i915_irq.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -1567,6 +1567,16 @@ static void ironlake_irq_preinstall(stru + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + + I915_WRITE(HWSTAM, 0xeffe); ++ if (IS_GEN6(dev)) { ++ /* Workaround stalls observed on Sandy Bridge GPUs by ++ * making the blitter command streamer generate a ++ * write to the Hardware Status Page for ++ * MI_USER_INTERRUPT. This appears to serialize the ++ * previous seqno write out before the interrupt ++ * happens. ++ */ ++ I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT); ++ } + + /* XXX hotplug from PCH */ + diff --git a/queue-2.6.39/drm-populate-irq_by_busid-member-for-pci.patch b/queue-2.6.39/drm-populate-irq_by_busid-member-for-pci.patch new file mode 100644 index 0000000000..8bb3ee8812 --- /dev/null +++ b/queue-2.6.39/drm-populate-irq_by_busid-member-for-pci.patch @@ -0,0 +1,49 @@ +From 45e97ab65026a3391cb2c938f834ca5db4d2e5b3 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang <w.sang@pengutronix.de> +Date: Wed, 15 Jun 2011 11:26:47 +0200 +Subject: drm: populate irq_by_busid-member for pci +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Wolfram Sang <w.sang@pengutronix.de> + +commit 45e97ab65026a3391cb2c938f834ca5db4d2e5b3 upstream. + +Commit 8410ea (drm: rework PCI/platform driver interface) implemented +drm_pci_irq_by_busid() but forgot to make it available in the +drm_pci_bus-struct. + +This caused a freeze on my Radeon9600-equipped laptop when executing glxgears. +Thanks to Michel for noticing the flaw. + +[airlied: made function static also] + +Reported-by: Michel Dänzer <daenzer@vmware.com> +Signed-off-by: Wolfram Sang <w.sang@pengutronix.de> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/drm_pci.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/drm_pci.c ++++ b/drivers/gpu/drm/drm_pci.c +@@ -251,7 +251,7 @@ err: + } + + +-int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p) ++static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p) + { + if ((p->busnum >> 8) != drm_get_pci_domain(dev) || + (p->busnum & 0xff) != dev->pdev->bus->number || +@@ -292,6 +292,7 @@ static struct drm_bus drm_pci_bus = { + .get_name = drm_pci_get_name, + .set_busid = drm_pci_set_busid, + .set_unique = drm_pci_set_unique, ++ .irq_by_busid = drm_pci_irq_by_busid, + .agp_init = drm_pci_agp_init, + }; + diff --git a/queue-2.6.39/drm-radeon-kms-atom-fix-duallink-on-some-early-dce3.2-cards.patch b/queue-2.6.39/drm-radeon-kms-atom-fix-duallink-on-some-early-dce3.2-cards.patch new file mode 100644 index 0000000000..852fd0d24b --- /dev/null +++ b/queue-2.6.39/drm-radeon-kms-atom-fix-duallink-on-some-early-dce3.2-cards.patch @@ -0,0 +1,41 @@ +From 8323fa6ba313ae2664420ec34d56a7fb0bbbe525 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexdeucher@gmail.com> +Date: Fri, 17 Jun 2011 13:13:52 -0400 +Subject: drm/radeon/kms/atom: fix duallink on some early DCE3.2 cards + +From: Alex Deucher <alexdeucher@gmail.com> + +commit 8323fa6ba313ae2664420ec34d56a7fb0bbbe525 upstream. + +Certain revisions of the vbios on DCE3.2 cards have a bug +in the transmitter control table which prevents duallink from +being enabled properly on some cards. The action switch statement +jumps to the wrong offset for the OUTPUT_ENABLE action. The fix +is to use the ENABLE action rather than the OUTPUT_ENABLE action +on the affected cards. In fixed version of the vbios, both +actions jump to the same offset, so the change should be safe. + +Reported-and-tested-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Alex Deucher <alexdeucher@gmail.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/radeon_encoders.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/radeon_encoders.c ++++ b/drivers/gpu/drm/radeon/radeon_encoders.c +@@ -1294,7 +1294,11 @@ radeon_atom_encoder_dpms(struct drm_enco + if (is_dig) { + switch (mode) { + case DRM_MODE_DPMS_ON: +- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); ++ /* some early dce3.2 boards have a bug in their transmitter control table */ ++ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); ++ else ++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); + if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + diff --git a/queue-2.6.39/drm-radeon-kms-fix-chremap-setup-on-rv770-ce.patch b/queue-2.6.39/drm-radeon-kms-fix-chremap-setup-on-rv770-ce.patch new file mode 100644 index 0000000000..91f8963ab3 --- /dev/null +++ b/queue-2.6.39/drm-radeon-kms-fix-chremap-setup-on-rv770-ce.patch @@ -0,0 +1,37 @@ +From daf54f1f363a61c618662ef66d4bf09d2b090941 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexdeucher@gmail.com> +Date: Thu, 30 Jun 2011 08:59:55 -0400 +Subject: drm/radeon/kms: Fix chremap setup on RV770 CE + +From: Alex Deucher <alexdeucher@gmail.com> + +commit daf54f1f363a61c618662ef66d4bf09d2b090941 upstream. + +CE variant requires a different chremap setup. + +Fixes: +https://bugzilla.kernel.org/show_bug.cgi?id=35472 + +Signed-off-by: Alex Deucher <alexdeucher@gmail.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/rv770.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/gpu/drm/radeon/rv770.c ++++ b/drivers/gpu/drm/radeon/rv770.c +@@ -572,6 +572,12 @@ static void rv770_program_channel_remap( + else + tcp_chan_steer = 0x00fac688; + ++ /* RV770 CE has special chremap setup */ ++ if (rdev->pdev->device == 0x944e) { ++ tcp_chan_steer = 0x00b08b08; ++ mc_shared_chremap = 0x00b08b08; ++ } ++ + WREG32(TCP_CHAN_STEER, tcp_chan_steer); + WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); + } diff --git a/queue-2.6.39/mm-memory-failure.c-fix-page-isolated-count-mismatch.patch b/queue-2.6.39/mm-memory-failure.c-fix-page-isolated-count-mismatch.patch new file mode 100644 index 0000000000..fe6b2bfe2e --- /dev/null +++ b/queue-2.6.39/mm-memory-failure.c-fix-page-isolated-count-mismatch.patch @@ -0,0 +1,56 @@ +From 5db8a73a8d7cc6a66afbf25ed7fda338caa8f5f9 Mon Sep 17 00:00:00 2001 +From: Minchan Kim <minchan.kim@gmail.com> +Date: Wed, 15 Jun 2011 15:08:48 -0700 +Subject: mm/memory-failure.c: fix page isolated count mismatch + +From: Minchan Kim <minchan.kim@gmail.com> + +commit 5db8a73a8d7cc6a66afbf25ed7fda338caa8f5f9 upstream. + +Pages isolated for migration are accounted with the vmstat counters +NR_ISOLATE_[ANON|FILE]. Callers of migrate_pages() are expected to +increment these counters when pages are isolated from the LRU. Once the +pages have been migrated, they are put back on the LRU or freed and the +isolated count is decremented. + +Memory failure is not properly accounting for pages it isolates causing +the NR_ISOLATED counters to be negative. On SMP builds, this goes +unnoticed as negative counters are treated as 0 due to expected per-cpu +drift. On UP builds, the counter is treated by too_many_isolated() as a +large value causing processes to enter D state during page reclaim or +compaction. This patch accounts for pages isolated by memory failure +correctly. + +[mel@csn.ul.ie: rewrote changelog] +Reviewed-by: Andrea Arcangeli <aarcange@redhat.com> +Signed-off-by: Minchan Kim <minchan.kim@gmail.com> +Cc: Andi Kleen <andi@firstfloor.org> +Acked-by: Mel Gorman <mel@csn.ul.ie> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + mm/memory-failure.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/mm/memory-failure.c ++++ b/mm/memory-failure.c +@@ -52,6 +52,7 @@ + #include <linux/swapops.h> + #include <linux/hugetlb.h> + #include <linux/memory_hotplug.h> ++#include <linux/mm_inline.h> + #include "internal.h" + + int sysctl_memory_failure_early_kill __read_mostly = 0; +@@ -1463,7 +1464,8 @@ int soft_offline_page(struct page *page, + ret = isolate_lru_page(page); + if (!ret) { + LIST_HEAD(pagelist); +- ++ inc_zone_page_state(page, NR_ISOLATED_ANON + ++ page_is_file_cache(page)); + list_add(&page->lru, &pagelist); + ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, + 0, true); diff --git a/queue-2.6.39/oprofile-x86-fix-race-in-nmi-handler-while-starting.patch b/queue-2.6.39/oprofile-x86-fix-race-in-nmi-handler-while-starting.patch new file mode 100644 index 0000000000..dc2d5693ba --- /dev/null +++ b/queue-2.6.39/oprofile-x86-fix-race-in-nmi-handler-while-starting.patch @@ -0,0 +1,71 @@ +From 8fe7e94eb71430cf63a742f3c19739d82a662758 Mon Sep 17 00:00:00 2001 +From: Robert Richter <robert.richter@amd.com> +Date: Wed, 1 Jun 2011 15:31:44 +0200 +Subject: oprofile, x86: Fix race in nmi handler while starting + counters + +From: Robert Richter <robert.richter@amd.com> + +commit 8fe7e94eb71430cf63a742f3c19739d82a662758 upstream. + +In some rare cases, nmis are generated immediately after the nmi +handler of the cpu was started. This causes the counter not to be +enabled. Before enabling the nmi handlers we need to set variable +ctr_running first and make sure its value is written to memory. + +Also, the patch makes all existing barriers a memory barrier instead +of a compiler barrier only. + +Reported-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> +Signed-off-by: Robert Richter <robert.richter@amd.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/oprofile/nmi_int.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/arch/x86/oprofile/nmi_int.c ++++ b/arch/x86/oprofile/nmi_int.c +@@ -112,8 +112,10 @@ static void nmi_cpu_start(void *dummy) + static int nmi_start(void) + { + get_online_cpus(); +- on_each_cpu(nmi_cpu_start, NULL, 1); + ctr_running = 1; ++ /* make ctr_running visible to the nmi handler: */ ++ smp_mb(); ++ on_each_cpu(nmi_cpu_start, NULL, 1); + put_online_cpus(); + return 0; + } +@@ -504,15 +506,18 @@ static int nmi_setup(void) + + nmi_enabled = 0; + ctr_running = 0; +- barrier(); ++ /* make variables visible to the nmi handler: */ ++ smp_mb(); + err = register_die_notifier(&profile_exceptions_nb); + if (err) + goto fail; + + get_online_cpus(); + register_cpu_notifier(&oprofile_cpu_nb); +- on_each_cpu(nmi_cpu_setup, NULL, 1); + nmi_enabled = 1; ++ /* make nmi_enabled visible to the nmi handler: */ ++ smp_mb(); ++ on_each_cpu(nmi_cpu_setup, NULL, 1); + put_online_cpus(); + + return 0; +@@ -531,7 +536,8 @@ static void nmi_shutdown(void) + nmi_enabled = 0; + ctr_running = 0; + put_online_cpus(); +- barrier(); ++ /* make variables visible to the nmi handler: */ ++ smp_mb(); + unregister_die_notifier(&profile_exceptions_nb); + msrs = &get_cpu_var(cpu_msrs); + model->shutdown(msrs); diff --git a/queue-2.6.39/pm-free-memory-bitmaps-if-opening-dev-snapshot-fails.patch b/queue-2.6.39/pm-free-memory-bitmaps-if-opening-dev-snapshot-fails.patch new file mode 100644 index 0000000000..9ff8188f38 --- /dev/null +++ b/queue-2.6.39/pm-free-memory-bitmaps-if-opening-dev-snapshot-fails.patch @@ -0,0 +1,39 @@ +From 8440f4b19494467883f8541b7aa28c7bbf6ac92b Mon Sep 17 00:00:00 2001 +From: Michal Kubecek <mkubecek@suse.cz> +Date: Sat, 18 Jun 2011 20:34:01 +0200 +Subject: PM: Free memory bitmaps if opening /dev/snapshot fails + +From: Michal Kubecek <mkubecek@suse.cz> + +commit 8440f4b19494467883f8541b7aa28c7bbf6ac92b upstream. + +When opening /dev/snapshot device, snapshot_open() creates memory +bitmaps which are freed in snapshot_release(). But if any of the +callbacks called by pm_notifier_call_chain() returns NOTIFY_BAD, open() +fails, snapshot_release() is never called and bitmaps are not freed. +Next attempt to open /dev/snapshot then triggers BUG_ON() check in +create_basic_memory_bitmaps(). This happens e.g. when vmwatchdog module +is active on s390x. + +Signed-off-by: Michal Kubecek <mkubecek@suse.cz> +Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + kernel/power/user.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/kernel/power/user.c ++++ b/kernel/power/user.c +@@ -113,8 +113,10 @@ static int snapshot_open(struct inode *i + if (error) + pm_notifier_call_chain(PM_POST_RESTORE); + } +- if (error) ++ if (error) { ++ free_basic_memory_bitmaps(); + atomic_inc(&snapshot_device_available); ++ } + data->frozen = 0; + data->ready = 0; + data->platform_support = 0; diff --git a/queue-2.6.39/pxa168_eth-fix-race-in-transmit-path.patch b/queue-2.6.39/pxa168_eth-fix-race-in-transmit-path.patch new file mode 100644 index 0000000000..a412556bac --- /dev/null +++ b/queue-2.6.39/pxa168_eth-fix-race-in-transmit-path.patch @@ -0,0 +1,35 @@ +From 384420409d9b5d4443940abace49363d26135412 Mon Sep 17 00:00:00 2001 +From: Richard Cochran <richardcochran@gmail.com> +Date: Sun, 19 Jun 2011 21:48:06 +0000 +Subject: pxa168_eth: fix race in transmit path. + +From: Richard Cochran <richardcochran@gmail.com> + +commit 384420409d9b5d4443940abace49363d26135412 upstream. + +Because the socket buffer is freed in the completion interrupt, it is not +safe to access it after submitting it to the hardware. + +Cc: Sachin Sanap <ssanap@marvell.com> +Cc: Zhangfei Gao <zgao6@marvell.com> +Cc: Philip Rakity <prakity@marvell.com> +Signed-off-by: Richard Cochran <richard.cochran@omicron.at> +Acked-by: Eric Dumazet <eric.dumazet@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/net/pxa168_eth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/pxa168_eth.c ++++ b/drivers/net/pxa168_eth.c +@@ -1273,7 +1273,7 @@ static int pxa168_eth_start_xmit(struct + wmb(); + wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD); + +- stats->tx_bytes += skb->len; ++ stats->tx_bytes += length; + stats->tx_packets++; + dev->trans_start = jiffies; + if (pep->tx_ring_size - pep->tx_desc_count <= 1) { diff --git a/queue-2.6.39/revert-drm-i915-enable-gmbus-for-post-gen2-chipsets.patch b/queue-2.6.39/revert-drm-i915-enable-gmbus-for-post-gen2-chipsets.patch new file mode 100644 index 0000000000..1e1cdb5e50 --- /dev/null +++ b/queue-2.6.39/revert-drm-i915-enable-gmbus-for-post-gen2-chipsets.patch @@ -0,0 +1,38 @@ +From 826c7e4147f902737b281e8a5a7d7aa33fd63316 Mon Sep 17 00:00:00 2001 +From: Jean Delvare <khali@linux-fr.org> +Date: Sat, 4 Jun 2011 19:34:56 +0000 +Subject: Revert "drm/i915: Enable GMBUS for post-gen2 chipsets" + +From: Jean Delvare <khali@linux-fr.org> + +commit 826c7e4147f902737b281e8a5a7d7aa33fd63316 upstream. + +Revert commit 8f9a3f9b63b8cd3f03be9dc53533f90bd4120e5f. This fixes a +hang when loading the eeprom driver (see bug #35572.) GMBUS will be +re-enabled later, differently. + +Signed-off-by: Jean Delvare <khali@linux-fr.org> +Reported-by: Marek Otahal <markotahal@gmail.com> +Tested-by: Yermandu Patapitafious <yermandu.dev@gmail.com> +Tested-by: Andrew Lutomirski <luto@mit.edu> +Acked-by: Chris Wilson <chris@chris-wilson.co.uk> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Cc: Ben Hutchings <ben@decadent.org.uk> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/i915/intel_i2c.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_i2c.c ++++ b/drivers/gpu/drm/i915/intel_i2c.c +@@ -401,8 +401,7 @@ int intel_setup_gmbus(struct drm_device + bus->reg0 = i | GMBUS_RATE_100KHZ; + + /* XXX force bit banging until GMBUS is fully debugged */ +- if (IS_GEN2(dev)) +- bus->force_bit = intel_gpio_create(dev_priv, i); ++ bus->force_bit = intel_gpio_create(dev_priv, i); + } + + intel_i2c_reset(dev_priv->dev); diff --git a/queue-2.6.39/series b/queue-2.6.39/series index 07c16cbb0d..f81b3f19aa 100644 --- a/queue-2.6.39/series +++ b/queue-2.6.39/series @@ -20,3 +20,31 @@ migrate-don-t-account-swapcache-as-shmem.patch hwmon-ibmaem-initialize-sysfs-attributes.patch hwmon-s3c-initialize-sysfs-attributes.patch hwmon-ibmpex-initialize-sysfs-attributes.patch +revert-drm-i915-enable-gmbus-for-post-gen2-chipsets.patch +drm-radeon-kms-atom-fix-duallink-on-some-early-dce3.2-cards.patch +drm-radeon-kms-fix-chremap-setup-on-rv770-ce.patch +drm-i915-fix-gen6-snb-missed-blt-ring-interrupts.patch +drm-populate-irq_by_busid-member-for-pci.patch +xen-support-config_maxsmp.patch +xen-partially-revert-xen-set-max_pfn_mapped-to-the-last.patch +xen-pci-use-the-int_src_ovr-irq-instead-of-gsi-to-preset.patch +xen-mmu-fix-for-linker-errors-when-config_smp-is-not.patch +xen-pci-move-check-for-acpi_sci_override_gsi-to.patch +clocksource-make-watchdog-robust-vs.-interruption.patch +arm-samsung-serial-fix-on-handling-of-one-clock-source.patch +tty-ldisc-do-not-close-until-there-are-readers.patch +connector-set-the-cn_netlink_users-correctly.patch +connector-correctly-set-the-error-code-in-case-of-success.patch +xhci-reject-double-add-of-active-endpoints.patch +xhci-add-reset-on-resume-quirk-for-asrock-p67-host.patch +xhci-always-set-urb-status-to-zero-for-isoc-endpoints.patch +usb-free-bandwidth-when-usb_disable_device-is-called.patch +usb-add-new-ft232h-chip-to-drivers-usb-serial-ftdi_sio.c.patch +mm-memory-failure.c-fix-page-isolated-count-mismatch.patch +pm-free-memory-bitmaps-if-opening-dev-snapshot-fails.patch +ath5k-fix-memory-leak-when-fewer-than-n_pd_curves-are-in.patch +ath5k-disable-fast-channel-switching-by-default.patch +pxa168_eth-fix-race-in-transmit-path.patch +ath9k-fix-suspend-resume-when-no-interface-is-up.patch +x86-suspend-restore-misc_enable-msr-in-realmode-wakeup.patch +oprofile-x86-fix-race-in-nmi-handler-while-starting.patch diff --git a/queue-2.6.39/tty-ldisc-do-not-close-until-there-are-readers.patch b/queue-2.6.39/tty-ldisc-do-not-close-until-there-are-readers.patch new file mode 100644 index 0000000000..fe5d6ae30a --- /dev/null +++ b/queue-2.6.39/tty-ldisc-do-not-close-until-there-are-readers.patch @@ -0,0 +1,100 @@ +From 92f6fa09bd453ffe3351fa1f1377a1b7cfa911e6 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby <jslaby@suse.cz> +Date: Sun, 5 Jun 2011 14:16:16 +0200 +Subject: TTY: ldisc, do not close until there are readers + +From: Jiri Slaby <jslaby@suse.cz> + +commit 92f6fa09bd453ffe3351fa1f1377a1b7cfa911e6 upstream. + +We restored tty_ldisc_wait_idle in 100eeae2c5c (TTY: restore +tty_ldisc_wait_idle). We used it in the ldisc changing path to fix the +case where there are tasks in n_tty_read waiting for data and somebody +tries to change ldisc. + +Similar to the case above, there may be also tasks waiting in +n_tty_read while hangup is performed. As 65b770468e98 (tty-ldisc: turn +ldisc user count into a proper refcount) removed the wait-until-idle +from all paths, hangup path won't wait for them to disappear either +now. So add it back even to the hangup path. + +There is a difference, we need uninterruptible sleep as there is +obviously HUP signal pending. So tty_ldisc_wait_idle now sleeps +without possibility to be interrupted. This is what original +tty_ldisc_wait_idle did. After the wait idle reintroduction +(100eeae2c5c), we have had interruptible sleeps for the ldisc changing +path. But as there is a 5s timeout anyway, we don't allow it to be +interrupted from now on. It's not worth the added complexity of +deciding what kind of sleep we want. + +Before 65b770468e98 tty_ldisc_release was called also from +tty_ldisc_release. It is called from tty_release, so I don't think we +need to restore that one. + +This is nicely reproducible after constifying the timing when +drivers/tty/n_tty.c is patched as follows ("TTY: ntty, add one more +sanity check" patch is needed to actually see it explode): +%% -1548,6 +1549,7 @@ static int n_tty_open(struct tty_struct *tty) + + /* These are ugly. Currently a malloc failure here can panic */ + if (!tty->read_buf) { ++ msleep(100); + tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); + if (!tty->read_buf) + return -ENOMEM; +%% -1785,6 +1788,7 @@ do_it_again: + break; + } + timeout = schedule_timeout(timeout); ++ msleep(20); + continue; + } + __set_current_state(TASK_RUNNING); +===== With a process: ===== + while (1) { + int fd = open(argv[1], O_RDWR); + read(fd, buf, sizeof(buf)); + close(fd); + } +===== and its child: ===== + setsid(); + while (1) { + int fd = open(tty, O_RDWR|O_NOCTTY); + ioctl(fd, TIOCSCTTY, 1); + vhangup(); + close(fd); + usleep(100 * (10 + random() % 1000)); + } +===== EOF ===== + +References: https://bugzilla.novell.com/show_bug.cgi?id=693374 +References: https://bugzilla.novell.com/show_bug.cgi?id=694509 +Signed-off-by: Jiri Slaby <jslaby@suse.cz> +Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/tty/tty_ldisc.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/tty/tty_ldisc.c ++++ b/drivers/tty/tty_ldisc.c +@@ -555,7 +555,7 @@ static void tty_ldisc_flush_works(struct + static int tty_ldisc_wait_idle(struct tty_struct *tty) + { + int ret; +- ret = wait_event_interruptible_timeout(tty_ldisc_idle, ++ ret = wait_event_timeout(tty_ldisc_idle, + atomic_read(&tty->ldisc->users) == 1, 5 * HZ); + if (ret < 0) + return ret; +@@ -763,6 +763,8 @@ static int tty_ldisc_reinit(struct tty_s + if (IS_ERR(ld)) + return -1; + ++ WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); ++ + tty_ldisc_close(tty, tty->ldisc); + tty_ldisc_put(tty->ldisc); + tty->ldisc = NULL; diff --git a/queue-2.6.39/usb-add-new-ft232h-chip-to-drivers-usb-serial-ftdi_sio.c.patch b/queue-2.6.39/usb-add-new-ft232h-chip-to-drivers-usb-serial-ftdi_sio.c.patch new file mode 100644 index 0000000000..f36d6afc38 --- /dev/null +++ b/queue-2.6.39/usb-add-new-ft232h-chip-to-drivers-usb-serial-ftdi_sio.c.patch @@ -0,0 +1,119 @@ +From 309427b6351b763917caac3e4b2ab5651df99823 Mon Sep 17 00:00:00 2001 +From: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> +Date: Fri, 17 Jun 2011 17:30:23 +0200 +Subject: USB: Add new FT232H chip to drivers/usb/serial/ftdi_sio.c + +From: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> + +commit 309427b6351b763917caac3e4b2ab5651df99823 upstream. + +appended patch adds support for the new FTDI FT232H chip. This chip is a +single channel version of the dual FT2232H/quad FT4232H, coming with it's +own default PID 0x6014 (FT2232H uses the same PID 0x6010 like FT2232C, +FT4232H has also it's own PID). + +The patch was checked on an UM232H module and a terminal program with TX/RX +shorted to that typing in the terminal reproduced the characters. + +Signed-off-by: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/ftdi_sio.c | 19 ++++++++++++++----- + drivers/usb/serial/ftdi_sio.h | 3 ++- + drivers/usb/serial/ftdi_sio_ids.h | 1 + + 3 files changed, 17 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -179,6 +179,7 @@ static struct usb_device_id id_table_com + { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_232H_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, +@@ -848,7 +849,8 @@ static const char *ftdi_chip_name[] = { + [FT2232C] = "FT2232C", + [FT232RL] = "FT232RL", + [FT2232H] = "FT2232H", +- [FT4232H] = "FT4232H" ++ [FT4232H] = "FT4232H", ++ [FT232H] = "FT232H" + }; + + +@@ -1168,6 +1170,7 @@ static __u32 get_ftdi_divisor(struct tty + break; + case FT2232H: /* FT2232H chip */ + case FT4232H: /* FT4232H chip */ ++ case FT232H: /* FT232H chip */ + if ((baud <= 12000000) & (baud >= 1200)) { + div_value = ftdi_2232h_baud_to_divisor(baud); + } else if (baud < 1200) { +@@ -1429,9 +1432,12 @@ static void ftdi_determine_type(struct u + } else if (version < 0x600) { + /* Assume it's an FT232BM (or FT245BM) */ + priv->chip_type = FT232BM; +- } else { +- /* Assume it's an FT232R */ ++ } else if (version < 0x900) { ++ /* Assume it's an FT232RL */ + priv->chip_type = FT232RL; ++ } else { ++ /* Assume it's an FT232H */ ++ priv->chip_type = FT232H; + } + dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); + } +@@ -1559,7 +1565,8 @@ static int create_sysfs_attrs(struct usb + priv->chip_type == FT2232C || + priv->chip_type == FT232RL || + priv->chip_type == FT2232H || +- priv->chip_type == FT4232H)) { ++ priv->chip_type == FT4232H || ++ priv->chip_type == FT232H)) { + retval = device_create_file(&port->dev, + &dev_attr_latency_timer); + } +@@ -1580,7 +1587,8 @@ static void remove_sysfs_attrs(struct us + priv->chip_type == FT2232C || + priv->chip_type == FT232RL || + priv->chip_type == FT2232H || +- priv->chip_type == FT4232H) { ++ priv->chip_type == FT4232H || ++ priv->chip_type == FT232H) { + device_remove_file(&port->dev, &dev_attr_latency_timer); + } + } +@@ -2212,6 +2220,7 @@ static int ftdi_tiocmget(struct tty_stru + case FT232RL: + case FT2232H: + case FT4232H: ++ case FT232H: + len = 2; + break; + default: +--- a/drivers/usb/serial/ftdi_sio.h ++++ b/drivers/usb/serial/ftdi_sio.h +@@ -156,7 +156,8 @@ enum ftdi_chip_type { + FT2232C = 4, + FT232RL = 5, + FT2232H = 6, +- FT4232H = 7 ++ FT4232H = 7, ++ FT232H = 8 + }; + + enum ftdi_sio_baudrate { +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -22,6 +22,7 @@ + #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ + #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ + #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ ++#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */ + #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ + #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ + diff --git a/queue-2.6.39/usb-free-bandwidth-when-usb_disable_device-is-called.patch b/queue-2.6.39/usb-free-bandwidth-when-usb_disable_device-is-called.patch new file mode 100644 index 0000000000..2915996300 --- /dev/null +++ b/queue-2.6.39/usb-free-bandwidth-when-usb_disable_device-is-called.patch @@ -0,0 +1,150 @@ +From fccf4e86200b8f5edd9a65da26f150e32ba79808 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Date: Sun, 5 Jun 2011 23:22:22 -0700 +Subject: USB: Free bandwidth when usb_disable_device is called. + +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> + +commit fccf4e86200b8f5edd9a65da26f150e32ba79808 upstream. + +Tanya ran into an issue when trying to switch a UAS device from the BOT +configuration to the UAS configuration via the bConfigurationValue sysfs +file. Before installing the UAS configuration, set_bConfigurationValue() +calls usb_disable_device(). That function is supposed to remove all host +controller resources associated with that device, but it leaves some state +in the xHCI host controller. + +Commit 0791971ba8fbc44e4f476079f856335ed45e6324 + usb: allow drivers to use allocated bandwidth until unbound +added a call to usb_disable_device() in usb_set_configuration(), before +the xHCI bandwidth functions were invoked. That commit fixed a bug, but +also introduced a bug that is triggered when a configured device is +switched to a new configuration. + +usb_disable_device() goes through all the motions of unbinding the drivers +attached to active interfaces and removing the USB core structures +associated with those interfaces, but it doesn't actually remove the +endpoints from the internal xHCI host controller bandwidth structures. + +When usb_disable_device() calls usb_disable_endpoint() with reset_hardware +set to true, the entries in udev->ep_out and udev->ep_in will be set to +NULL. Usually, when the USB core installs a new configuration, +usb_hcd_alloc_bandwidth() will drop all non-NULL endpoints in udev->ep_out +and udev->ep_in before adding any new endpoints. However, when the new +UAS configuration was added, all those entries were null, so none of the +old endpoints in the BOT configuration were dropped. + +The xHCI driver blindly added the UAS configuration endpoints, and some of +the endpoint addresses overlapped with the old BOT configuration +endpoints. This caused the xHCI host to reject the Configure Endpoint +command. Now that the xHCI driver code is cleaned up to reject a +double-add of active endpoints, we need to fix the USB core to properly +drop old endpoints in usb_disable_device(). + +If the host controller driver needs bandwidth checking support, make +usb_disable_device() call usb_disable_endpoint() with +reset_hardware set to false, drop the endpoints from the xHCI host +controller, and then call usb_disable_endpoint() again with +reset_hardware set to true. + +The first call to usb_disable_endpoint() will cancel any pending URBs and +wait on them to be freed in usb_hcd_disable_endpoint(), but will keep the +pointers in udev->ep_out and udev->ep in intact. Then +usb_hcd_alloc_bandwidth() will use those pointers to know which endpoints +to drop. + +The final call to usb_disable_endpoint() will do two things: + +1. It will call usb_hcd_disable_endpoint() again, which should be harmless +since the ep->urb_list should be empty after the first call to +usb_disable_endpoint() returns. + +2. It will set the entries in udev->ep_out and udev->ep in to NULL, and call +usb_hcd_disable_endpoint(). That call will have no effect, since the xHCI +driver doesn't set the endpoint_disable function pointer. + +Note that usb_disable_device() will now need to be called with +hcd->bandwidth_mutex held. + +This should be backported to kernels as old as 2.6.32. + +Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Reported-by: Tanya Brokhman <tlinder@codeaurora.org> +Cc: ablay@codeaurora.org +Cc: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/core/hub.c | 3 +++ + drivers/usb/core/message.c | 15 ++++++++++++++- + 2 files changed, 17 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1643,6 +1643,7 @@ void usb_disconnect(struct usb_device ** + { + struct usb_device *udev = *pdev; + int i; ++ struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + if (!udev) { + pr_debug ("%s nodev\n", __func__); +@@ -1670,7 +1671,9 @@ void usb_disconnect(struct usb_device ** + * so that the hardware is now fully quiesced. + */ + dev_dbg (&udev->dev, "unregistering device\n"); ++ mutex_lock(hcd->bandwidth_mutex); + usb_disable_device(udev, 0); ++ mutex_unlock(hcd->bandwidth_mutex); + usb_hcd_synchronize_unlinks(udev); + + usb_remove_ep_devs(&udev->ep0); +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -1135,10 +1135,13 @@ void usb_disable_interface(struct usb_de + * Deallocates hcd/hardware state for the endpoints (nuking all or most + * pending urbs) and usbcore state for the interfaces, so that usbcore + * must usb_set_configuration() before any interfaces could be used. ++ * ++ * Must be called with hcd->bandwidth_mutex held. + */ + void usb_disable_device(struct usb_device *dev, int skip_ep0) + { + int i; ++ struct usb_hcd *hcd = bus_to_hcd(dev->bus); + + /* getting rid of interfaces will disconnect + * any drivers bound to them (a key side effect) +@@ -1172,6 +1175,16 @@ void usb_disable_device(struct usb_devic + + dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, + skip_ep0 ? "non-ep0" : "all"); ++ if (hcd->driver->check_bandwidth) { ++ /* First pass: Cancel URBs, leave endpoint pointers intact. */ ++ for (i = skip_ep0; i < 16; ++i) { ++ usb_disable_endpoint(dev, i, false); ++ usb_disable_endpoint(dev, i + USB_DIR_IN, false); ++ } ++ /* Remove endpoints from the host controller internal state */ ++ usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); ++ /* Second pass: remove endpoint pointers */ ++ } + for (i = skip_ep0; i < 16; ++i) { + usb_disable_endpoint(dev, i, true); + usb_disable_endpoint(dev, i + USB_DIR_IN, true); +@@ -1727,6 +1740,7 @@ free_interfaces: + /* if it's already configured, clear out old state first. + * getting rid of old interfaces means unbinding their drivers. + */ ++ mutex_lock(hcd->bandwidth_mutex); + if (dev->state != USB_STATE_ADDRESS) + usb_disable_device(dev, 1); /* Skip ep0 */ + +@@ -1739,7 +1753,6 @@ free_interfaces: + * host controller will not allow submissions to dropped endpoints. If + * this call fails, the device state is unchanged. + */ +- mutex_lock(hcd->bandwidth_mutex); + ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); + if (ret < 0) { + mutex_unlock(hcd->bandwidth_mutex); diff --git a/queue-2.6.39/x86-suspend-restore-misc_enable-msr-in-realmode-wakeup.patch b/queue-2.6.39/x86-suspend-restore-misc_enable-msr-in-realmode-wakeup.patch new file mode 100644 index 0000000000..ff07b4176c --- /dev/null +++ b/queue-2.6.39/x86-suspend-restore-misc_enable-msr-in-realmode-wakeup.patch @@ -0,0 +1,104 @@ +From 7a3136666bc0f0419f7aaa7b1fabb4b0e0a7fb76 Mon Sep 17 00:00:00 2001 +From: Kees Cook <kees.cook@canonical.com> +Date: Wed, 6 Jul 2011 18:10:34 -0700 +Subject: x86, suspend: Restore MISC_ENABLE MSR in realmode wakeup + +From: Kees Cook <kees.cook@canonical.com> + +commit 7a3136666bc0f0419f7aaa7b1fabb4b0e0a7fb76 upstream. + +Some BIOSes will reset the Intel MISC_ENABLE MSR (specifically the +XD_DISABLE bit) when resuming from S3, which can interact poorly with +ebba638ae723d8a8fc2f7abce5ec18b688b791d7. In 32bit PAE mode, this can +lead to a fault when EFER is restored by the kernel wakeup routines, +due to it setting the NX bit for a CPU that (thanks to the BIOS reset) +now incorrectly thinks it lacks the NX feature. (64bit is not affected +because it uses a common CPU bring-up that specifically handles the +XD_DISABLE bit.) + +The need for MISC_ENABLE being restored so early is specific to the S3 +resume path. Normally, MISC_ENABLE is saved in save_processor_state(), +but this happens after the resume header is created, so just reproduce +the logic here. (acpi_suspend_lowlevel() creates the header, calls +do_suspend_lowlevel, which calls save_processor_state(), so the saved +processor context isn't available during resume header creation.) + +[ hpa: Consider for stable if OK in mainline ] + +Signed-off-by: Kees Cook <kees.cook@canonical.com> +Link: http://lkml.kernel.org/r/20110707011034.GA8523@outflux.net +Signed-off-by: H. Peter Anvin <hpa@zytor.com> +Cc: Rafael J. Wysocki <rjw@sisk.pl> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/kernel/acpi/realmode/wakeup.S | 14 ++++++++++++++ + arch/x86/kernel/acpi/realmode/wakeup.h | 6 ++++++ + arch/x86/kernel/acpi/sleep.c | 6 ++++++ + 3 files changed, 26 insertions(+) + +--- a/arch/x86/kernel/acpi/realmode/wakeup.S ++++ b/arch/x86/kernel/acpi/realmode/wakeup.S +@@ -28,6 +28,8 @@ pmode_cr3: .long 0 /* Saved %cr3 */ + pmode_cr4: .long 0 /* Saved %cr4 */ + pmode_efer: .quad 0 /* Saved EFER */ + pmode_gdt: .quad 0 ++pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */ ++pmode_behavior: .long 0 /* Wakeup behavior flags */ + realmode_flags: .long 0 + real_magic: .long 0 + trampoline_segment: .word 0 +@@ -91,6 +93,18 @@ wakeup_code: + /* Call the C code */ + calll main + ++ /* Restore MISC_ENABLE before entering protected mode, in case ++ BIOS decided to clear XD_DISABLE during S3. */ ++ movl pmode_behavior, %eax ++ btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax ++ jnc 1f ++ ++ movl pmode_misc_en, %eax ++ movl pmode_misc_en + 4, %edx ++ movl $MSR_IA32_MISC_ENABLE, %ecx ++ wrmsr ++1: ++ + /* Do any other stuff... */ + + #ifndef CONFIG_64BIT +--- a/arch/x86/kernel/acpi/realmode/wakeup.h ++++ b/arch/x86/kernel/acpi/realmode/wakeup.h +@@ -21,6 +21,9 @@ struct wakeup_header { + u32 pmode_efer_low; /* Protected mode EFER */ + u32 pmode_efer_high; + u64 pmode_gdt; ++ u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */ ++ u32 pmode_misc_en_high; ++ u32 pmode_behavior; /* Wakeup routine behavior flags */ + u32 realmode_flags; + u32 real_magic; + u16 trampoline_segment; /* segment with trampoline code, 64-bit only */ +@@ -39,4 +42,7 @@ extern struct wakeup_header wakeup_heade + #define WAKEUP_HEADER_SIGNATURE 0x51ee1111 + #define WAKEUP_END_SIGNATURE 0x65a22c82 + ++/* Wakeup behavior bits */ ++#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 ++ + #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ +--- a/arch/x86/kernel/acpi/sleep.c ++++ b/arch/x86/kernel/acpi/sleep.c +@@ -77,6 +77,12 @@ int acpi_suspend_lowlevel(void) + + header->pmode_cr0 = read_cr0(); + header->pmode_cr4 = read_cr4_safe(); ++ header->pmode_behavior = 0; ++ if (!rdmsr_safe(MSR_IA32_MISC_ENABLE, ++ &header->pmode_misc_en_low, ++ &header->pmode_misc_en_high)) ++ header->pmode_behavior |= ++ (1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE); + header->realmode_flags = acpi_realmode_flags; + header->real_magic = 0x12345678; + diff --git a/queue-2.6.39/xen-mmu-fix-for-linker-errors-when-config_smp-is-not.patch b/queue-2.6.39/xen-mmu-fix-for-linker-errors-when-config_smp-is-not.patch new file mode 100644 index 0000000000..71d9c8a2c1 --- /dev/null +++ b/queue-2.6.39/xen-mmu-fix-for-linker-errors-when-config_smp-is-not.patch @@ -0,0 +1,35 @@ +From 32dd11942aeb47f91209a446d6b10063c5b69389 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Date: Thu, 30 Jun 2011 09:12:40 -0400 +Subject: xen/mmu: Fix for linker errors when CONFIG_SMP is not + defined. + +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> + +commit 32dd11942aeb47f91209a446d6b10063c5b69389 upstream. + +Simple enough - we use an extern defined symbol which is not +defined when CONFIG_SMP is not defined. This fixes the linker +dying. + +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/xen/mmu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -1354,7 +1354,11 @@ static void xen_flush_tlb_others(const s + { + struct { + struct mmuext_op op; ++#ifdef CONFIG_SMP + DECLARE_BITMAP(mask, num_processors); ++#else ++ DECLARE_BITMAP(mask, NR_CPUS); ++#endif + } *args; + struct multicall_space mcs; + diff --git a/queue-2.6.39/xen-partially-revert-xen-set-max_pfn_mapped-to-the-last.patch b/queue-2.6.39/xen-partially-revert-xen-set-max_pfn_mapped-to-the-last.patch new file mode 100644 index 0000000000..c97c994853 --- /dev/null +++ b/queue-2.6.39/xen-partially-revert-xen-set-max_pfn_mapped-to-the-last.patch @@ -0,0 +1,54 @@ +From a91d92875ee94e4703fd017ccaadb48cfb344994 Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> +Date: Fri, 3 Jun 2011 09:51:34 +0000 +Subject: xen: partially revert "xen: set max_pfn_mapped to the last + pfn mapped" + +From: Stefano Stabellini <stefano.stabellini@eu.citrix.com> + +commit a91d92875ee94e4703fd017ccaadb48cfb344994 upstream. + +We only need to set max_pfn_mapped to the last pfn mapped on x86_64 to +make sure that cleanup_highmap doesn't remove important mappings at +_end. + +We don't need to do this on x86_32 because cleanup_highmap is not called +on x86_32. Besides lowering max_pfn_mapped on x86_32 has the unwanted +side effect of limiting the amount of memory available for the 1:1 +kernel pagetable allocation. + +This patch reverts the x86_32 part of the original patch. + +Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/xen/mmu.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -1722,6 +1722,11 @@ static __init void xen_map_identity_earl + for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) { + pte_t pte; + ++#ifdef CONFIG_X86_32 ++ if (pfn > max_pfn_mapped) ++ max_pfn_mapped = pfn; ++#endif ++ + if (!pte_none(pte_page[pteidx])) + continue; + +@@ -1889,7 +1894,9 @@ __init pgd_t *xen_setup_kernel_pagetable + initial_kernel_pmd = + extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE); + +- max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->mfn_list)); ++ max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) + ++ xen_start_info->nr_pt_frames * PAGE_SIZE + ++ 512*1024); + + kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd); + memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD); diff --git a/queue-2.6.39/xen-pci-move-check-for-acpi_sci_override_gsi-to.patch b/queue-2.6.39/xen-pci-move-check-for-acpi_sci_override_gsi-to.patch new file mode 100644 index 0000000000..001a5d0018 --- /dev/null +++ b/queue-2.6.39/xen-pci-move-check-for-acpi_sci_override_gsi-to.patch @@ -0,0 +1,153 @@ +From ee339fe63ac408e4604c1c88b1f9a428f2511b70 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Date: Wed, 6 Jul 2011 09:43:16 -0400 +Subject: xen/pci: Move check for acpi_sci_override_gsi to + xen_setup_acpi_sci. + +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> + +commit ee339fe63ac408e4604c1c88b1f9a428f2511b70 upstream. + +Previously we would check for acpi_sci_override_gsi == gsi every time +a PCI device was enabled. That works during early bootup, but later +on it could lead to triggering unnecessarily the acpi_gsi_to_irq(..) lookup. +The reason is that acpi_sci_override_gsi was declared in __initdata and +after early bootup could contain bogus values. + +This patch moves the check for acpi_sci_override_gsi to the +site where the ACPI SCI is preset. + +Reported-by: Raghavendra D Prabhu <rprabhu@wnohang.net> +Tested-by: Raghavendra D Prabhu <rprabhu@wnohang.net> +[http://lists.xensource.com/archives/html/xen-devel/2011-07/msg00154.html] +Suggested-by: Ian Campbell <ijc@hellion.org.uk> +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/pci/xen.c | 56 ++++++++++++++++++++++++++--------------------------- + 1 file changed, 28 insertions(+), 28 deletions(-) + +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -316,13 +316,12 @@ int __init pci_xen_hvm_init(void) + } + + #ifdef CONFIG_XEN_DOM0 +-static int xen_register_pirq(u32 gsi, int triggering) ++static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) + { + int rc, pirq, irq = -1; + struct physdev_map_pirq map_irq; + int shareable = 0; + char *name; +- bool gsi_override = false; + + if (!xen_pv_domain()) + return -1; +@@ -334,31 +333,12 @@ static int xen_register_pirq(u32 gsi, in + shareable = 1; + name = "ioapic-level"; + } +- + pirq = xen_allocate_pirq_gsi(gsi); + if (pirq < 0) + goto out; + +- /* Before we bind the GSI to a Linux IRQ, check whether +- * we need to override it with bus_irq (IRQ) value. Usually for +- * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: +- * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) +- * but there are oddballs where the IRQ != GSI: +- * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) +- * which ends up being: gsi_to_irq[9] == 20 +- * (which is what acpi_gsi_to_irq ends up calling when starting the +- * the ACPI interpreter and keels over since IRQ 9 has not been +- * setup as we had setup IRQ 20 for it). +- */ +- if (gsi == acpi_sci_override_gsi) { +- /* Check whether the GSI != IRQ */ +- acpi_gsi_to_irq(gsi, &irq); +- if (irq != gsi) +- /* Bugger, we MUST have that IRQ. */ +- gsi_override = true; +- } +- if (gsi_override) +- irq = xen_bind_pirq_gsi_to_irq(irq, pirq, shareable, name); ++ if (gsi_override >= 0) ++ irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name); + else + irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); + if (irq < 0) +@@ -381,7 +361,7 @@ out: + return irq; + } + +-static int xen_register_gsi(u32 gsi, int triggering, int polarity) ++static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity) + { + int rc, irq; + struct physdev_setup_gsi setup_gsi; +@@ -392,7 +372,7 @@ static int xen_register_gsi(u32 gsi, int + printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", + gsi, triggering, polarity); + +- irq = xen_register_pirq(gsi, triggering); ++ irq = xen_register_pirq(gsi, gsi_override, triggering); + + setup_gsi.gsi = gsi; + setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); +@@ -414,6 +394,8 @@ static __init void xen_setup_acpi_sci(vo + int rc; + int trigger, polarity; + int gsi = acpi_sci_override_gsi; ++ int irq = -1; ++ int gsi_override = -1; + + if (!gsi) + return; +@@ -430,7 +412,25 @@ static __init void xen_setup_acpi_sci(vo + printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " + "polarity=%d\n", gsi, trigger, polarity); + +- gsi = xen_register_gsi(gsi, trigger, polarity); ++ /* Before we bind the GSI to a Linux IRQ, check whether ++ * we need to override it with bus_irq (IRQ) value. Usually for ++ * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: ++ * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) ++ * but there are oddballs where the IRQ != GSI: ++ * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) ++ * which ends up being: gsi_to_irq[9] == 20 ++ * (which is what acpi_gsi_to_irq ends up calling when starting the ++ * the ACPI interpreter and keels over since IRQ 9 has not been ++ * setup as we had setup IRQ 20 for it). ++ */ ++ /* Check whether the GSI != IRQ */ ++ if (acpi_gsi_to_irq(gsi, &irq) == 0) { ++ if (irq >= 0 && irq != gsi) ++ /* Bugger, we MUST have that IRQ. */ ++ gsi_override = irq; ++ } ++ ++ gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); + printk(KERN_INFO "xen: acpi sci %d\n", gsi); + + return; +@@ -439,7 +439,7 @@ static __init void xen_setup_acpi_sci(vo + static int acpi_register_gsi_xen(struct device *dev, u32 gsi, + int trigger, int polarity) + { +- return xen_register_gsi(gsi, trigger, polarity); ++ return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity); + } + + static int __init pci_xen_initial_domain(void) +@@ -478,7 +478,7 @@ void __init xen_setup_pirqs(void) + if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) + continue; + +- xen_register_pirq(irq, ++ xen_register_pirq(irq, -1 /* no GSI override */, + trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); + } + } diff --git a/queue-2.6.39/xen-pci-use-the-int_src_ovr-irq-instead-of-gsi-to-preset.patch b/queue-2.6.39/xen-pci-use-the-int_src_ovr-irq-instead-of-gsi-to-preset.patch new file mode 100644 index 0000000000..c630b5b2ee --- /dev/null +++ b/queue-2.6.39/xen-pci-use-the-int_src_ovr-irq-instead-of-gsi-to-preset.patch @@ -0,0 +1,103 @@ +From 155a16f21923bc2f04161ac92acca986371ef27b Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Date: Thu, 30 Jun 2011 09:18:27 -0400 +Subject: xen/pci: Use the INT_SRC_OVR IRQ (instead of GSI) to preset + the ACPI SCI IRQ. + +From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> + +commit 155a16f21923bc2f04161ac92acca986371ef27b upstream. + +In the past we would use the GSI value to preset the ACPI SCI +IRQ which worked great as GSI == IRQ: + +ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) + +While that is most often seen, there are some oddities: + +ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) + +which means that GSI 20 (or pin 20) is to be overriden for IRQ 9. +Our code that presets the interrupt for ACPI SCI however would +use the GSI 20 instead of IRQ 9 ending up with: + +xen: sci override: global_irq=20 trigger=0 polarity=1 +xen: registering gsi 20 triggering 0 polarity 1 +xen: --> pirq=20 -> irq=20 +xen: acpi sci 20 +.. snip.. +calling acpi_init+0x0/0xbc @ 1 +ACPI: SCI (IRQ9) allocation failed +ACPI Exception: AE_NOT_ACQUIRED, Unable to install System Control Interrupt handler (20110413/evevent-119) +ACPI: Unable to start the ACPI Interpreter + +as the ACPI interpreter made a call to 'acpi_gsi_to_irq' which got nine. +It used that value to request an IRQ (request_irq) and since that was not +present it failed. + +The fix is to recognize that for interrupts that are overriden (in our +case we only care about the ACPI SCI) we should use the IRQ number +to present the IRQ instead of the using GSI. End result is that we get: + +xen: sci override: global_irq=20 trigger=0 polarity=1 +xen: registering gsi 20 triggering 0 polarity 1 +xen: --> pirq=20 -> irq=9 (gsi=9) +xen: acpi sci 9 + +which fixes the ACPI interpreter failing on startup. + +Reported-by: Liwei <xieliwei@gmail.com> +Tested-by: Liwei <xieliwei@gmail.com> +[http://lists.xensource.com/archives/html/xen-devel/2011-06/msg01727.html] +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/pci/xen.c | 26 ++++++++++++++++++++++++-- + 1 file changed, 24 insertions(+), 2 deletions(-) + +--- a/arch/x86/pci/xen.c ++++ b/arch/x86/pci/xen.c +@@ -322,6 +322,7 @@ static int xen_register_pirq(u32 gsi, in + struct physdev_map_pirq map_irq; + int shareable = 0; + char *name; ++ bool gsi_override = false; + + if (!xen_pv_domain()) + return -1; +@@ -338,11 +339,32 @@ static int xen_register_pirq(u32 gsi, in + if (pirq < 0) + goto out; + +- irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); ++ /* Before we bind the GSI to a Linux IRQ, check whether ++ * we need to override it with bus_irq (IRQ) value. Usually for ++ * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: ++ * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) ++ * but there are oddballs where the IRQ != GSI: ++ * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) ++ * which ends up being: gsi_to_irq[9] == 20 ++ * (which is what acpi_gsi_to_irq ends up calling when starting the ++ * the ACPI interpreter and keels over since IRQ 9 has not been ++ * setup as we had setup IRQ 20 for it). ++ */ ++ if (gsi == acpi_sci_override_gsi) { ++ /* Check whether the GSI != IRQ */ ++ acpi_gsi_to_irq(gsi, &irq); ++ if (irq != gsi) ++ /* Bugger, we MUST have that IRQ. */ ++ gsi_override = true; ++ } ++ if (gsi_override) ++ irq = xen_bind_pirq_gsi_to_irq(irq, pirq, shareable, name); ++ else ++ irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); + if (irq < 0) + goto out; + +- printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d\n", pirq, irq); ++ printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi); + + map_irq.domid = DOMID_SELF; + map_irq.type = MAP_PIRQ_TYPE_GSI; diff --git a/queue-2.6.39/xen-support-config_maxsmp.patch b/queue-2.6.39/xen-support-config_maxsmp.patch new file mode 100644 index 0000000000..9630f317f7 --- /dev/null +++ b/queue-2.6.39/xen-support-config_maxsmp.patch @@ -0,0 +1,77 @@ +From 900cba8881b39dfbc7c8062098504ab93f5387a8 Mon Sep 17 00:00:00 2001 +From: Andrew Jones <drjones@redhat.com> +Date: Fri, 18 Dec 2009 10:31:31 +0100 +Subject: xen: support CONFIG_MAXSMP + +From: Andrew Jones <drjones@redhat.com> + +commit 900cba8881b39dfbc7c8062098504ab93f5387a8 upstream. + +The MAXSMP config option requires CPUMASK_OFFSTACK, which in turn +requires we init the memory for the maps while we bring up the cpus. +MAXSMP also increases NR_CPUS to 4096. This increase in size exposed an +issue in the argument construction for multicalls from +xen_flush_tlb_others. The args should only need space for the actual +number of cpus. + +Also in 2.6.39 it exposes a bootup problem. + +BUG: unable to handle kernel NULL pointer dereference at (null) +IP: [<ffffffff8157a1d3>] set_cpu_sibling_map+0x123/0x30d +... +Call Trace: +[<ffffffff81039a3f>] ? xen_restore_fl_direct_reloc+0x4/0x4 +[<ffffffff819dc4db>] xen_smp_prepare_cpus+0x36/0x135 +.. + +Signed-off-by: Andrew Jones <drjones@redhat.com> +[v2: Updated to compile on 3.0] +[v3: Updated to compile when CONFIG_SMP is not defined] +Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/x86/xen/mmu.c | 3 ++- + arch/x86/xen/smp.c | 7 +++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -59,6 +59,7 @@ + #include <asm/page.h> + #include <asm/init.h> + #include <asm/pat.h> ++#include <asm/smp.h> + + #include <asm/xen/hypercall.h> + #include <asm/xen/hypervisor.h> +@@ -1353,7 +1354,7 @@ static void xen_flush_tlb_others(const s + { + struct { + struct mmuext_op op; +- DECLARE_BITMAP(mask, NR_CPUS); ++ DECLARE_BITMAP(mask, num_processors); + } *args; + struct multicall_space mcs; + +--- a/arch/x86/xen/smp.c ++++ b/arch/x86/xen/smp.c +@@ -206,11 +206,18 @@ static void __init xen_smp_prepare_boot_ + static void __init xen_smp_prepare_cpus(unsigned int max_cpus) + { + unsigned cpu; ++ unsigned int i; + + xen_init_lock_cpu(0); + + smp_store_cpu_info(0); + cpu_data(0).x86_max_cores = 1; ++ ++ for_each_possible_cpu(i) { ++ zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL); ++ zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL); ++ zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL); ++ } + set_cpu_sibling_map(0); + + if (xen_smp_intr_init(0)) diff --git a/queue-2.6.39/xhci-add-reset-on-resume-quirk-for-asrock-p67-host.patch b/queue-2.6.39/xhci-add-reset-on-resume-quirk-for-asrock-p67-host.patch new file mode 100644 index 0000000000..f7660f8a8b --- /dev/null +++ b/queue-2.6.39/xhci-add-reset-on-resume-quirk-for-asrock-p67-host.patch @@ -0,0 +1,69 @@ +From c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9 Mon Sep 17 00:00:00 2001 +From: Maarten Lankhorst <m.b.lankhorst@gmail.com> +Date: Wed, 15 Jun 2011 23:47:21 +0200 +Subject: xhci: Add reset on resume quirk for asrock p67 host + +From: Maarten Lankhorst <m.b.lankhorst@gmail.com> + +commit c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9 upstream. + +The asrock p67 xhci controller completely dies on resume, add a +quirk for this, to bring the host back online after a suspend. + +This should be backported to stable kernels as old as 2.6.37. + +Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com> +Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/xhci-pci.c | 8 ++++++++ + drivers/usb/host/xhci.c | 2 ++ + drivers/usb/host/xhci.h | 1 + + 3 files changed, 11 insertions(+) + +--- a/drivers/usb/host/xhci-pci.c ++++ b/drivers/usb/host/xhci-pci.c +@@ -28,6 +28,9 @@ + #define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 + #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 + ++#define PCI_VENDOR_ID_ETRON 0x1b6f ++#define PCI_DEVICE_ID_ASROCK_P67 0x7023 ++ + static const char hcd_name[] = "xhci_hcd"; + + /* called after powerup, by probe or system-pm "wakeup" */ +@@ -120,6 +123,11 @@ static int xhci_pci_setup(struct usb_hcd + "has broken MSI implementation\n", + pdev->revision); + } ++ if (pdev->vendor == PCI_VENDOR_ID_ETRON && ++ pdev->device == PCI_DEVICE_ID_ASROCK_P67) { ++ xhci->quirks |= XHCI_RESET_ON_RESUME; ++ xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); ++ } + + if (pdev->vendor == PCI_VENDOR_ID_NEC) + xhci->quirks |= XHCI_NEC_HOST; +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -759,6 +759,8 @@ int xhci_resume(struct xhci_hcd *xhci, b + msleep(100); + + spin_lock_irq(&xhci->lock); ++ if (xhci->quirks & XHCI_RESET_ON_RESUME) ++ hibernated = true; + + if (!hibernated) { + /* step 1: restore register */ +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1287,6 +1287,7 @@ struct xhci_hcd { + #define XHCI_NEC_HOST (1 << 2) + #define XHCI_AMD_PLL_FIX (1 << 3) + #define XHCI_BROKEN_MSI (1 << 6) ++#define XHCI_RESET_ON_RESUME (1 << 7) + /* There are two roothubs to keep track of bus suspend info for */ + struct xhci_bus_state bus_state[2]; + /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ diff --git a/queue-2.6.39/xhci-always-set-urb-status-to-zero-for-isoc-endpoints.patch b/queue-2.6.39/xhci-always-set-urb-status-to-zero-for-isoc-endpoints.patch new file mode 100644 index 0000000000..86a90b070a --- /dev/null +++ b/queue-2.6.39/xhci-always-set-urb-status-to-zero-for-isoc-endpoints.patch @@ -0,0 +1,97 @@ +From b3df3f9c7df9a8d85e03e158d35487618a160901 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Date: Wed, 15 Jun 2011 19:57:46 -0700 +Subject: xhci: Always set urb->status to zero for isoc endpoints. + +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> + +commit b3df3f9c7df9a8d85e03e158d35487618a160901 upstream. + +When the xHCI driver encounters a Missed Service Interval event for an +isochronous endpoint ring, it means the host controller skipped over +one or more isochronous TDs. For TD that is skipped, skip_isoc_td() is +called. This sets the frame descriptor status to -EXDEV, and also sets +the value stored in the int pointed to by status to -EXDEV. + +If the isochronous TD happens to be the last TD in an URB, +handle_tx_event() will use the status variable to give back the URB to +the USB core. That means drivers will see urb->status as -EXDEV. + +It turns out that EHCI, UHCI, and OHCI always set urb->status to zero for +an isochronous urb, regardless of what the frame status is. See +itd_complete() in ehci-sched.c: + + } else { + /* URB was too late */ + desc->status = -EXDEV; + } + } + + /* handle completion now? */ + if (likely ((urb_index + 1) != urb->number_of_packets)) + goto done; + + /* ASSERT: it's really the last itd for this urb + list_for_each_entry (itd, &stream->td_list, itd_list) + BUG_ON (itd->urb == urb); + */ + + /* give urb back to the driver; completion often (re)submits */ + dev = urb->dev; + ehci_urb_done(ehci, urb, 0); + +ehci_urb_done() completes the URB with the status of the third argument, which +is always zero in this case. + +It turns out that many USB webcam drivers, such as uvcvideo, cannot +handle urb->status set to a non-zero value. They will not resubmit +their isochronous URBs in that case, and userspace will see a frozen +video. + +Change the xHCI driver to be consistent with the EHCI and UHCI driver, +and always set urb->status to 0 for isochronous URBs. + +This patch should be backported to kernels as old as 2.6.36 + +Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Cc: "Xu, Andiry" <Andiry.Xu@amd.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/xhci-ring.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1768,9 +1768,6 @@ static int process_isoc_td(struct xhci_h + } + } + +- if ((idx == urb_priv->length - 1) && *status == -EINPROGRESS) +- *status = 0; +- + return finish_td(xhci, td, event_trb, event, ep, status, false); + } + +@@ -1788,8 +1785,7 @@ static int skip_isoc_td(struct xhci_hcd + idx = urb_priv->td_cnt; + frame = &td->urb->iso_frame_desc[idx]; + +- /* The transfer is partly done */ +- *status = -EXDEV; ++ /* The transfer is partly done. */ + frame->status = -EXDEV; + + /* calc actual length */ +@@ -2139,6 +2135,11 @@ cleanup: + "status = %d\n", + urb, urb->actual_length, status); + spin_unlock(&xhci->lock); ++ /* EHCI, UHCI, and OHCI always unconditionally set the ++ * urb->status of an isochronous endpoint to 0. ++ */ ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ++ status = 0; + usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); + spin_lock(&xhci->lock); + } diff --git a/queue-2.6.39/xhci-reject-double-add-of-active-endpoints.patch b/queue-2.6.39/xhci-reject-double-add-of-active-endpoints.patch new file mode 100644 index 0000000000..4c15acc0be --- /dev/null +++ b/queue-2.6.39/xhci-reject-double-add-of-active-endpoints.patch @@ -0,0 +1,83 @@ +From fa75ac379e63c2864e9049b5e8615e40f65c1e70 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Date: Sun, 5 Jun 2011 23:10:04 -0700 +Subject: xhci: Reject double add of active endpoints. + +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> + +commit fa75ac379e63c2864e9049b5e8615e40f65c1e70 upstream. + +While trying to switch a UAS device from the BOT configuration to the UAS +configuration via the bConfigurationValue file, Tanya ran into an issue in +the USB core. usb_disable_device() sets entries in udev->ep_out and +udev->ep_out to NULL, but doesn't call into the xHCI bandwidth management +functions to remove the BOT configuration endpoints from the xHCI host's +internal structures. + +The USB core would then attempt to add endpoints for the UAS +configuration, and some of the endpoints had the same address as endpoints +in the BOT configuration. The xHCI driver blindly added the endpoints +again, but the xHCI host controller rejected the Configure Endpoint +command because active endpoints were added without being dropped. + +Make the xHCI driver reject calls to xhci_add_endpoint() that attempt to +add active endpoints without first calling xhci_drop_endpoint(). + +This should be backported to kernels as old as 2.6.31. + +Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Reported-by: Tanya Brokhman <tlinder@codeaurora.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/xhci.c | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1396,6 +1396,7 @@ int xhci_add_endpoint(struct usb_hcd *hc + u32 added_ctxs; + unsigned int last_ctx; + u32 new_add_flags, new_drop_flags, new_slot_info; ++ struct xhci_virt_device *virt_dev; + int ret = 0; + + ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); +@@ -1418,11 +1419,25 @@ int xhci_add_endpoint(struct usb_hcd *hc + return 0; + } + +- in_ctx = xhci->devs[udev->slot_id]->in_ctx; +- out_ctx = xhci->devs[udev->slot_id]->out_ctx; ++ virt_dev = xhci->devs[udev->slot_id]; ++ in_ctx = virt_dev->in_ctx; ++ out_ctx = virt_dev->out_ctx; + ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + ep_index = xhci_get_endpoint_index(&ep->desc); + ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); ++ ++ /* If this endpoint is already in use, and the upper layers are trying ++ * to add it again without dropping it, reject the addition. ++ */ ++ if (virt_dev->eps[ep_index].ring && ++ !(le32_to_cpu(ctrl_ctx->drop_flags) & ++ xhci_get_endpoint_flag(&ep->desc))) { ++ xhci_warn(xhci, "Trying to add endpoint 0x%x " ++ "without dropping it.\n", ++ (unsigned int) ep->desc.bEndpointAddress); ++ return -EINVAL; ++ } ++ + /* If the HCD has already noted the endpoint is enabled, + * ignore this request. + */ +@@ -1437,8 +1452,7 @@ int xhci_add_endpoint(struct usb_hcd *hc + * process context, not interrupt context (or so documenation + * for usb_set_interface() and usb_set_configuration() claim). + */ +- if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], +- udev, ep, GFP_NOIO) < 0) { ++ if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) { + dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", + __func__, ep->desc.bEndpointAddress); + return -ENOMEM; |