From: Greg Kroah-Hartman Date: Thu, 14 Jan 2010 19:09:43 +0000 (-0800) Subject: more .32 patches X-Git-Tag: v2.6.32.4~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9f39a0062f28cbd7cf4547fcd4f1cbdc39b2b505;p=thirdparty%2Fkernel%2Fstable-queue.git more .32 patches --- diff --git a/queue-2.6.32/ath5k-fix-eeprom-checksum-check-for-custom-sized-eeproms.patch b/queue-2.6.32/ath5k-fix-eeprom-checksum-check-for-custom-sized-eeproms.patch new file mode 100644 index 00000000000..329f2199416 --- /dev/null +++ b/queue-2.6.32/ath5k-fix-eeprom-checksum-check-for-custom-sized-eeproms.patch @@ -0,0 +1,104 @@ +From 359207c687cc8f4f9845c8dadd0d6dabad44e584 Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Mon, 4 Jan 2010 10:40:39 -0500 +Subject: ath5k: Fix eeprom checksum check for custom sized eeproms + +From: Luis R. Rodriguez + +commit 359207c687cc8f4f9845c8dadd0d6dabad44e584 upstream. + +Commit 8bf3d79bc401ca417ccf9fc076d3295d1a71dbf5 enabled EEPROM +checksum checks to avoid bogus bug reports but failed to address +updating the code to consider devices with custom EEPROM sizes. +Devices with custom sized EEPROMs have the upper limit size stuffed +in the EEPROM. Use this as the upper limit instead of the static +default size. In case of a checksum error also provide back the +max size and whether or not this was the default size or a custom +one. If the EEPROM is busted we add a failsafe check to ensure +we don't loop forever or try to read bogus areas of hardware. + +This closes bug 14874 + +http://bugzilla.kernel.org/show_bug.cgi?id=14874 + +Cc: David Quan +Cc: Stephen Beahm +Reported-by: Joshua Covington +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath5k/eeprom.c | 32 +++++++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath5k/eeprom.h | 8 ++++++++ + 2 files changed, 37 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ath/ath5k/eeprom.c ++++ b/drivers/net/wireless/ath/ath5k/eeprom.c +@@ -97,7 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw + struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; + int ret; + u16 val; +- u32 cksum, offset; ++ u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; + + /* + * Read values from EEPROM and store them in the capability structure +@@ -116,12 +116,38 @@ ath5k_eeprom_init_header(struct ath5k_hw + * Validate the checksum of the EEPROM date. There are some + * devices with invalid EEPROMs. + */ +- for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { ++ AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val); ++ if (val) { ++ eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) << ++ AR5K_EEPROM_SIZE_ENDLOC_SHIFT; ++ AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val); ++ eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE; ++ ++ /* ++ * Fail safe check to prevent stupid loops due ++ * to busted EEPROMs. XXX: This value is likely too ++ * big still, waiting on a better value. ++ */ ++ if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) { ++ ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: " ++ "%d (0x%04x) max expected: %d (0x%04x)\n", ++ eep_max, eep_max, ++ 3 * AR5K_EEPROM_INFO_MAX, ++ 3 * AR5K_EEPROM_INFO_MAX); ++ return -EIO; ++ } ++ } ++ ++ for (cksum = 0, offset = 0; offset < eep_max; offset++) { + AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); + cksum ^= val; + } + if (cksum != AR5K_EEPROM_INFO_CKSUM) { +- ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); ++ ATH5K_ERR(ah->ah_sc, "Invalid EEPROM " ++ "checksum: 0x%04x eep_max: 0x%04x (%s)\n", ++ cksum, eep_max, ++ eep_max == AR5K_EEPROM_INFO_MAX ? ++ "default size" : "custom size"); + return -EIO; + } + +--- a/drivers/net/wireless/ath/ath5k/eeprom.h ++++ b/drivers/net/wireless/ath/ath5k/eeprom.h +@@ -37,6 +37,14 @@ + #define AR5K_EEPROM_RFKILL_POLARITY_S 1 + + #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ ++ ++/* FLASH(EEPROM) Defines for AR531X chips */ ++#define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */ ++#define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */ ++#define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0 ++#define AR5K_EEPROM_SIZE_UPPER_SHIFT 4 ++#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12 ++ + #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ + #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ + #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) diff --git a/queue-2.6.32/cfg80211-fix-syntax-error-on-user-regulatory-hints.patch b/queue-2.6.32/cfg80211-fix-syntax-error-on-user-regulatory-hints.patch new file mode 100644 index 00000000000..f078d5b3948 --- /dev/null +++ b/queue-2.6.32/cfg80211-fix-syntax-error-on-user-regulatory-hints.patch @@ -0,0 +1,32 @@ +From e12822e1d3fface0d9e1095c5177e10141bd6bd6 Mon Sep 17 00:00:00 2001 +From: Luis R. Rodriguez +Date: Mon, 4 Jan 2010 11:37:39 -0500 +Subject: cfg80211: fix syntax error on user regulatory hints + +From: Luis R. Rodriguez + +commit e12822e1d3fface0d9e1095c5177e10141bd6bd6 upstream. + +This fixes a syntax error when setting up the user regulatory +hint. This change yields the same exact binary object though +so it ends up just being a syntax typo fix, fortunately. + +Signed-off-by: Luis R. Rodriguez +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/reg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -1714,7 +1714,7 @@ int regulatory_hint_user(const char *alp + request->wiphy_idx = WIPHY_IDX_STALE; + request->alpha2[0] = alpha2[0]; + request->alpha2[1] = alpha2[1]; +- request->initiator = NL80211_REGDOM_SET_BY_USER, ++ request->initiator = NL80211_REGDOM_SET_BY_USER; + + queue_regulatory_request(request); + diff --git a/queue-2.6.32/drm-i915-remove-render-reclock-support.patch b/queue-2.6.32/drm-i915-remove-render-reclock-support.patch new file mode 100644 index 00000000000..31a6813074f --- /dev/null +++ b/queue-2.6.32/drm-i915-remove-render-reclock-support.patch @@ -0,0 +1,186 @@ +From cda9d05c499093c67b4a376a15009923acc2127a Mon Sep 17 00:00:00 2001 +From: Jesse Barnes +Date: Thu, 17 Dec 2009 11:11:13 -0800 +Subject: drm/i915: remove render reclock support + +From: Jesse Barnes + +commit cda9d05c499093c67b4a376a15009923acc2127a upstream. + +This code generally fails to adjust the render clock, and when it does, +it conflicts with some other register settings and can cause problems. + +So remove this code altogether. I'm reworking it now to do the right +thing, but the only bit it will share is the VBT check for whether +reclocking is supported, so I'm leaving that bit. + +Reverts most of 652c393a3368af84359da37c45afc35a91144960 ("add dynamic +clock frequency control"), though for many the regressions showed up +in the later 181a5336d6cc836f05507410d66988c483ad0154 ("Fix render +reclock availability detection"). + +Signed-off-by: Jesse Barnes +Signed-off-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_display.c | 127 ----------------------------------- + 1 file changed, 127 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -3737,125 +3737,6 @@ static void intel_gpu_idle_timer(unsigne + queue_work(dev_priv->wq, &dev_priv->idle_work); + } + +-void intel_increase_renderclock(struct drm_device *dev, bool schedule) +-{ +- drm_i915_private_t *dev_priv = dev->dev_private; +- +- if (IS_IGDNG(dev)) +- return; +- +- if (!dev_priv->render_reclock_avail) { +- DRM_DEBUG("not reclocking render clock\n"); +- return; +- } +- +- /* Restore render clock frequency to original value */ +- if (IS_G4X(dev) || IS_I9XX(dev)) +- pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock); +- else if (IS_I85X(dev)) +- pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock); +- DRM_DEBUG("increasing render clock frequency\n"); +- +- /* Schedule downclock */ +- if (schedule) +- mod_timer(&dev_priv->idle_timer, jiffies + +- msecs_to_jiffies(GPU_IDLE_TIMEOUT)); +-} +- +-void intel_decrease_renderclock(struct drm_device *dev) +-{ +- drm_i915_private_t *dev_priv = dev->dev_private; +- +- if (IS_IGDNG(dev)) +- return; +- +- if (!dev_priv->render_reclock_avail) { +- DRM_DEBUG("not reclocking render clock\n"); +- return; +- } +- +- if (IS_G4X(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK; +- gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } else if (IS_I965G(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~I965_GC_RENDER_CLOCK_MASK; +- gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } else if (IS_I945G(dev) || IS_I945GM(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~I945_GC_RENDER_CLOCK_MASK; +- gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } else if (IS_I915G(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~I915_GC_RENDER_CLOCK_MASK; +- gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } else if (IS_I85X(dev)) { +- u16 hpllcc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, HPLLCC, &hpllcc); +- +- /* Up to maximum... */ +- hpllcc &= ~GC_CLOCK_CONTROL_MASK; +- hpllcc |= GC_CLOCK_133_200; +- +- pci_write_config_word(dev->pdev, HPLLCC, hpllcc); +- } +- DRM_DEBUG("decreasing render clock frequency\n"); +-} +- +-/* Note that no increase function is needed for this - increase_renderclock() +- * will also rewrite these bits +- */ +-void intel_decrease_displayclock(struct drm_device *dev) +-{ +- if (IS_IGDNG(dev)) +- return; +- +- if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) || +- IS_I915GM(dev)) { +- u16 gcfgc; +- +- /* Adjust render clock... */ +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); +- +- /* Down to minimum... */ +- gcfgc &= ~0xf0; +- gcfgc |= 0x80; +- +- pci_write_config_word(dev->pdev, GCFGC, gcfgc); +- } +-} +- + #define CRTC_IDLE_TIMEOUT 1000 /* ms */ + + static void intel_crtc_idle_timer(unsigned long arg) +@@ -3969,12 +3850,6 @@ static void intel_idle_update(struct wor + + mutex_lock(&dev->struct_mutex); + +- /* GPU isn't processing, downclock it. */ +- if (!dev_priv->busy) { +- intel_decrease_renderclock(dev); +- intel_decrease_displayclock(dev); +- } +- + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + /* Skip inactive CRTCs */ + if (!crtc->fb) +@@ -4009,7 +3884,6 @@ void intel_mark_busy(struct drm_device * + return; + + dev_priv->busy = true; +- intel_increase_renderclock(dev, true); + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (!crtc->fb) +@@ -4514,7 +4388,6 @@ void intel_modeset_cleanup(struct drm_de + del_timer_sync(&intel_crtc->idle_timer); + } + +- intel_increase_renderclock(dev, false); + del_timer_sync(&dev_priv->idle_timer); + + mutex_unlock(&dev->struct_mutex); diff --git a/queue-2.6.32/iwl-off-by-one-bug.patch b/queue-2.6.32/iwl-off-by-one-bug.patch new file mode 100644 index 00000000000..16183fd1b59 --- /dev/null +++ b/queue-2.6.32/iwl-off-by-one-bug.patch @@ -0,0 +1,38 @@ +From 8a9ac160e844c7ce8074f6aa531feefb4acdee7c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Sun, 3 Jan 2010 11:19:35 +0200 +Subject: iwl: off by one bug + +From: Dan Carpenter + +commit 8a9ac160e844c7ce8074f6aa531feefb4acdee7c upstream. + +tid is used as an array offset. + agg = &priv->stations[sta_id].tid[tid].agg; + iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); + +It should be limitted to MAX_TID_COUNT - 1; + struct iwl_tid_data tid[MAX_TID_COUNT]; + +regards, +dan carpenter + +Signed-off-by: Dan Carpenter +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-4965.c ++++ b/drivers/net/wireless/iwlwifi/iwl-4965.c +@@ -2087,7 +2087,7 @@ static void iwl4965_rx_reply_tx(struct i + struct ieee80211_tx_info *info; + struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + u32 status = le32_to_cpu(tx_resp->u.status); +- int tid = MAX_TID_COUNT; ++ int tid = MAX_TID_COUNT - 1; + int sta_id; + int freed; + u8 *qc = NULL; diff --git a/queue-2.6.32/iwlwifi-fix-iwl_queue_used-bug-when-read_ptr-write_ptr.patch b/queue-2.6.32/iwlwifi-fix-iwl_queue_used-bug-when-read_ptr-write_ptr.patch new file mode 100644 index 00000000000..afdadfdc401 --- /dev/null +++ b/queue-2.6.32/iwlwifi-fix-iwl_queue_used-bug-when-read_ptr-write_ptr.patch @@ -0,0 +1,125 @@ +From c8106d7625a58ee4387cb2efe3e82320ad44b467 Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Fri, 8 Jan 2010 10:04:30 -0800 +Subject: iwlwifi: fix iwl_queue_used bug when read_ptr == write_ptr + +From: Zhu Yi + +commit c8106d7625a58ee4387cb2efe3e82320ad44b467 upstream. + +When txq read_ptr equals to write_ptr, iwl_queue_used should +always return false. Because there is no used TFD in this case. + +This is a complementary fix to the fix already included in commit "iwl3945: +fix panic in iwl3945 driver". Both fixes are needed to address the panic +below. + +This problem was discussed on linux-wireless in +http://thread.gmane.org/gmane.linux.kernel.wireless.general/43568 + +<1>[ 7290.414172] IP: [] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945] +<4>[ 7290.414205] PGD 0 +<1>[ 7290.414214] Thread overran stack, or stack corrupted +<0>[ 7290.414229] Oops: 0002 [#1] PREEMPT SMP +<0>[ 7290.414246] last sysfs file: /sys/devices/platform/coretemp.1/temp1_input +<4>[ 7290.414265] CPU 0 +<4>[ 7290.414274] Modules linked in: af_packet nfsd usb_storage usb_libusual cpufreq_powersave exportfs cpufreq_conservative iwl3945 nfs cpufreq_userspace snd_hda_codec_realtek acpi_cpufreq uvcvideo lockd iwlcore snd_hda_intel joydev coretemp nfs_acl videodev snd_hda_codec mac80211 v4l1_compat snd_hwdep sbp2 v4l2_compat_ioctl32 uhci_hcd psmouse auth_rpcgss ohci1394 cfg80211 ehci_hcd video ieee1394 snd_pcm serio_raw battery ac nvidia(P) usbcore output sunrpc evdev lirc_ene0100 snd_page_alloc rfkill tg3 libphy fuse lzo lzo_decompress lzo_compress +<6>[ 7290.414486] Pid: 0, comm: swapper Tainted: P 2.6.32-rc8-wl #213 Aspire 5720 +<6>[ 7290.414507] RIP: 0010:[] [] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945] +<6>[ 7290.414541] RSP: 0018:ffff880002203d60 EFLAGS: 00010246 +<6>[ 7290.414557] RAX: 000000000000004f RBX: ffff880064c11600 RCX: 0000000000000013 +<6>[ 7290.414576] RDX: ffffffffa0ddcf20 RSI: ffff8800512b7008 RDI: 0000000000000038 +<6>[ 7290.414596] RBP: ffff880002203dd0 R08: 0000000000000000 R09: 0000000000000100 +<6>[ 7290.414616] R10: 0000000000000001 R11: 0000000000000000 R12: 00000000000000a0 +<6>[ 7290.414635] R13: 0000000000000002 R14: 0000000000000013 R15: 0000000000020201 +<6>[ 7290.414655] FS: 0000000000000000(0000) GS:ffff880002200000(0000) knlGS:0000000000000000 +<6>[ 7290.414677] CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b +<6>[ 7290.414693] CR2: 0000000000000041 CR3: 0000000001001000 CR4: 00000000000006f0 +<6>[ 7290.414712] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +<6>[ 7290.414732] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +<4>[ 7290.414752] Process swapper (pid: 0, threadinfo ffffffff81524000, task ffffffff81528b60) +<0>[ 7290.414772] Stack: +<4>[ 7290.414780] ffff880002203da0 0000000000000046 0000000000000000 0000000000000046 +<4>[ 7290.414804] <0> 0000000000000282 0000000000000282 0000000000000282 ffff880064c12010 +<4>[ 7290.414830] <0> ffff880002203db0 ffff880064c11600 ffff880064c12e50 ffff8800512b7000 +<0>[ 7290.414858] Call Trace: +<0>[ 7290.414867] +<4>[ 7290.414884] [] iwl3945_irq_tasklet+0x657/0x1740 [iwl3945] +<4>[ 7290.414910] [] ? _spin_unlock+0x30/0x60 +<4>[ 7290.414931] [] tasklet_action+0x101/0x110 +<4>[ 7290.414950] [] __do_softirq+0xc0/0x160 +<4>[ 7290.414968] [] call_softirq+0x1c/0x30 +<4>[ 7290.414986] [] do_softirq+0x75/0xb0 +<4>[ 7290.415003] [] irq_exit+0x95/0xa0 +<4>[ 7290.415020] [] do_IRQ+0x77/0xf0 +<4>[ 7290.415038] [] ret_from_intr+0x0/0xf +<0>[ 7290.415052] +<4>[ 7290.415067] [] ? acpi_idle_enter_bm+0x270/0x2a5 +<4>[ 7290.415087] [] ? acpi_idle_enter_bm+0x27a/0x2a5 +<4>[ 7290.415107] [] ? acpi_idle_enter_bm+0x270/0x2a5 +<4>[ 7290.415130] [] ? cpuidle_idle_call+0x93/0xf0 +<4>[ 7290.415149] [] ? cpu_idle+0xa7/0x110 +<4>[ 7290.415168] [] ? rest_init+0x75/0x80 +<4>[ 7290.415187] [] ? start_kernel+0x3a7/0x3b3 +<4>[ 7290.415206] [] ? x86_64_start_reservations+0x125/0x129 +<4>[ 7290.415227] [] ? x86_64_start_kernel+0xe4/0xeb +<0>[ 7290.415243] Code: 00 41 39 ce 0f 8d e8 01 00 00 48 8b 47 40 48 63 d2 48 69 d2 98 00 00 00 4c 8b 04 02 48 c7 c2 20 cf dd a0 49 8d 78 38 49 8d 40 4f 47 09 00 c6 47 0c 00 c6 47 0f 00 c6 47 12 00 c6 47 15 00 49 +<1>[ 7290.415382] RIP [] iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945] +<4>[ 7290.415410] RSP +<0>[ 7290.415421] CR2: 0000000000000041 +<4>[ 7290.415436] ---[ end trace ec46807277caa515 ]--- +<0>[ 7290.415450] Kernel panic - not syncing: Fatal exception in interrupt +<4>[ 7290.415468] Pid: 0, comm: swapper Tainted: P D 2.6.32-rc8-wl #213 +<4>[ 7290.415486] Call Trace: +<4>[ 7290.415495] [] panic+0x7d/0x13a +<4>[ 7290.415519] [] oops_end+0xda/0xe0 +<4>[ 7290.415538] [] no_context+0xea/0x250 +<4>[ 7290.415557] [] ? select_task_rq_fair+0x511/0x780 +<4>[ 7290.415578] [] __bad_area_nosemaphore+0x125/0x1e0 +<4>[ 7290.415597] [] ? __enqueue_entity+0x7c/0x80 +<4>[ 7290.415616] [] ? enqueue_task_fair+0x111/0x150 +<4>[ 7290.415636] [] bad_area_nosemaphore+0xe/0x10 +<4>[ 7290.415656] [] do_page_fault+0x26a/0x320 +<4>[ 7290.415674] [] page_fault+0x1f/0x30 +<4>[ 7290.415697] [] ? iwl3945_rx_reply_tx+0xc1/0x450 [iwl3945] +<4>[ 7290.415723] [] iwl3945_irq_tasklet+0x657/0x1740 [iwl3945] +<4>[ 7290.415746] [] ? _spin_unlock+0x30/0x60 +<4>[ 7290.415764] [] tasklet_action+0x101/0x110 +<4>[ 7290.415783] [] __do_softirq+0xc0/0x160 +<4>[ 7290.415801] [] call_softirq+0x1c/0x30 +<4>[ 7290.415818] [] do_softirq+0x75/0xb0 +<4>[ 7290.415835] [] irq_exit+0x95/0xa0 +<4>[ 7290.415852] [] do_IRQ+0x77/0xf0 +<4>[ 7290.415869] [] ret_from_intr+0x0/0xf +<4>[ 7290.415883] [] ? acpi_idle_enter_bm+0x270/0x2a5 +<4>[ 7290.415911] [] ? acpi_idle_enter_bm+0x27a/0x2a5 +<4>[ 7290.415931] [] ? acpi_idle_enter_bm+0x270/0x2a5 +<4>[ 7290.415952] [] ? cpuidle_idle_call+0x93/0xf0 +<4>[ 7290.415971] [] ? cpu_idle+0xa7/0x110 +<4>[ 7290.415989] [] ? rest_init+0x75/0x80 +<4>[ 7290.416007] [] ? start_kernel+0x3a7/0x3b3 +<4>[ 7290.416026] [] ? x86_64_start_reservations+0x125/0x129 +<4>[ 7290.416047] [] ? x86_64_start_kernel+0xe4/0xeb + +Reported-by: Maxim Levitsky +Tested-by: Maxim Levitsky +Signed-off-by: Zhu Yi +Signed-off-by: Reinette Chatre +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-dev.h ++++ b/drivers/net/wireless/iwlwifi/iwl-dev.h +@@ -703,7 +703,7 @@ extern void iwl_txq_ctx_stop(struct iwl_ + extern int iwl_queue_space(const struct iwl_queue *q); + static inline int iwl_queue_used(const struct iwl_queue *q, int i) + { +- return q->write_ptr > q->read_ptr ? ++ return q->write_ptr >= q->read_ptr ? + (i >= q->read_ptr && i < q->write_ptr) : + !(i < q->read_ptr && i >= q->write_ptr); + } diff --git a/queue-2.6.32/kernel-sysctl.c-fix-stable-merge-error-in-nommu-mmap_min_addr.patch b/queue-2.6.32/kernel-sysctl.c-fix-stable-merge-error-in-nommu-mmap_min_addr.patch new file mode 100644 index 00000000000..aa33038226d --- /dev/null +++ b/queue-2.6.32/kernel-sysctl.c-fix-stable-merge-error-in-nommu-mmap_min_addr.patch @@ -0,0 +1,38 @@ +From vapier@gentoo.org Thu Jan 14 11:04:41 2010 +From: Mike Frysinger +Date: Fri, 8 Jan 2010 00:40:42 -0500 +Subject: kernel/sysctl.c: fix stable merge error in NOMMU mmap_min_addr +To: stable@kernel.org, stable-review@kernel.org, linux-kernel@vger.kernel.org +Cc: Linus Torvalds , Andrew Morton , Greg Kroah-Hartman , David Howells , James Morris , Alan Cox +Message-ID: <1262929242-7175-1-git-send-email-vapier@gentoo.org> + + +Stable commit 0399123f3dcce1a515d021107ec0fb4413ca3efa didn't match the +original upstream commit. The CONFIG_MMU check was added much too early +in the list disabling a lot of proc entries in the process. + +Signed-off-by: Mike Frysinger +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sysctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -1200,7 +1200,6 @@ static struct ctl_table vm_table[] = { + .extra2 = (void *)&hugetlb_infinity, + }, + #endif +-#ifdef CONFIG_MMU + { + .ctl_name = VM_LOWMEM_RESERVE_RATIO, + .procname = "lowmem_reserve_ratio", +@@ -1346,6 +1345,7 @@ static struct ctl_table vm_table[] = { + .strategy = &sysctl_jiffies, + }, + #endif ++#ifdef CONFIG_MMU + { + .ctl_name = CTL_UNNUMBERED, + .procname = "mmap_min_addr", diff --git a/queue-2.6.32/libertas-remove-carrier-signaling-from-the-scan-code.patch b/queue-2.6.32/libertas-remove-carrier-signaling-from-the-scan-code.patch new file mode 100644 index 00000000000..ccd9f095846 --- /dev/null +++ b/queue-2.6.32/libertas-remove-carrier-signaling-from-the-scan-code.patch @@ -0,0 +1,60 @@ +From 659c8e5243caf14564155ad8421404f044dd8031 Mon Sep 17 00:00:00 2001 +From: Samuel Ortiz +Date: Fri, 18 Dec 2009 11:36:49 +0100 +Subject: libertas: Remove carrier signaling from the scan code + +From: Samuel Ortiz + +commit 659c8e5243caf14564155ad8421404f044dd8031 upstream. + +There is no reason to signal a carrier off when doing a 802.11 scan. + +Cc: Holger Schurig +Signed-off-by: Samuel Ortiz +Acked-by: Dan Williams +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/libertas/scan.c | 22 ++++++++-------------- + 1 file changed, 8 insertions(+), 14 deletions(-) + +--- a/drivers/net/wireless/libertas/scan.c ++++ b/drivers/net/wireless/libertas/scan.c +@@ -399,11 +399,8 @@ int lbs_scan_networks(struct lbs_private + chan_count = lbs_scan_create_channel_list(priv, chan_list); + + netif_stop_queue(priv->dev); +- netif_carrier_off(priv->dev); +- if (priv->mesh_dev) { ++ if (priv->mesh_dev) + netif_stop_queue(priv->mesh_dev); +- netif_carrier_off(priv->mesh_dev); +- } + + /* Prepare to continue an interrupted scan */ + lbs_deb_scan("chan_count %d, scan_channel %d\n", +@@ -467,16 +464,13 @@ out2: + priv->scan_channel = 0; + + out: +- if (priv->connect_status == LBS_CONNECTED) { +- netif_carrier_on(priv->dev); +- if (!priv->tx_pending_len) +- netif_wake_queue(priv->dev); +- } +- if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) { +- netif_carrier_on(priv->mesh_dev); +- if (!priv->tx_pending_len) +- netif_wake_queue(priv->mesh_dev); +- } ++ if (priv->connect_status == LBS_CONNECTED && !priv->tx_pending_len) ++ netif_wake_queue(priv->dev); ++ ++ if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED) && ++ !priv->tx_pending_len) ++ netif_wake_queue(priv->mesh_dev); ++ + kfree(chan_list); + + lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret); diff --git a/queue-2.6.32/mac80211-add-missing-sanity-checks-for-action-frames.patch b/queue-2.6.32/mac80211-add-missing-sanity-checks-for-action-frames.patch new file mode 100644 index 00000000000..e213f3ffcd2 --- /dev/null +++ b/queue-2.6.32/mac80211-add-missing-sanity-checks-for-action-frames.patch @@ -0,0 +1,51 @@ +From d79074488083ec0d7ecd15352192dc1631f25643 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 7 Jan 2010 20:23:53 +0100 +Subject: mac80211: add missing sanity checks for action frames + +From: Felix Fietkau + +commit d79074488083ec0d7ecd15352192dc1631f25643 upstream. + +Various missing sanity checks caused rejected action frames to be +interpreted as channel switch announcements, which can cause a client +mode interface to switch away from its operating channel, thereby losing +connectivity. This patch ensures that only spectrum management action +frames are processed by the CSA handling function and prevents rejected +action frames from getting processed by the MLME code. + +Signed-off-by: Felix Fietkau +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/mlme.c | 4 +++- + net/mac80211/rx.c | 4 ++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1953,7 +1953,9 @@ static void ieee80211_sta_rx_queued_mgmt + rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); + break; + case IEEE80211_STYPE_ACTION: +- /* XXX: differentiate, can only happen for CSA now! */ ++ if (mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT) ++ break; ++ + ieee80211_sta_process_chanswitch(sdata, + &mgmt->u.action.u.chan_switch.sw_elem, + ifmgd->associated); +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1810,6 +1810,10 @@ ieee80211_rx_h_action(struct ieee80211_r + } + break; + default: ++ /* do not process rejected action frames */ ++ if (mgmt->u.action.category & 0x80) ++ return RX_DROP_MONITOR; ++ + return RX_CONTINUE; + } + diff --git a/queue-2.6.32/mac80211-fix-endian-error.patch b/queue-2.6.32/mac80211-fix-endian-error.patch new file mode 100644 index 00000000000..05fd1d568fe --- /dev/null +++ b/queue-2.6.32/mac80211-fix-endian-error.patch @@ -0,0 +1,35 @@ +From b49bb574e44226b332c28439999d196ddec2f643 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 8 Jan 2010 19:00:00 +0100 +Subject: mac80211: fix endian error + +From: Johannes Berg + +commit b49bb574e44226b332c28439999d196ddec2f643 upstream. + +I forgot to convert the radiotap length to +CPU endian, which sparse found thankfully. + +Signed-off-by: Johannes Berg +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/iface.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -673,10 +673,10 @@ static u16 ieee80211_monitor_select_queu + return 0; + + if (skb->len < 4 || +- skb->len < rtap->it_len + 2 /* frame control */) ++ skb->len < le16_to_cpu(rtap->it_len) + 2 /* frame control */) + return 0; /* doesn't matter, frame will be dropped */ + +- hdr = (void *)((u8 *)skb->data + rtap->it_len); ++ hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); + + if (!ieee80211_is_data(hdr->frame_control)) { + skb->priority = 7; diff --git a/queue-2.6.32/mac80211-fix-queue-selection-for-packets-injected-via-monitor-interface.patch b/queue-2.6.32/mac80211-fix-queue-selection-for-packets-injected-via-monitor-interface.patch new file mode 100644 index 00000000000..23fa789eeac --- /dev/null +++ b/queue-2.6.32/mac80211-fix-queue-selection-for-packets-injected-via-monitor-interface.patch @@ -0,0 +1,34 @@ +From 045cfb71a3901005bf6dcedae98cecb3360a0bfc Mon Sep 17 00:00:00 2001 +From: Lennert Buytenhek +Date: Thu, 7 Jan 2010 15:01:42 +0100 +Subject: mac80211: fix queue selection for packets injected via monitor interface + +From: Lennert Buytenhek + +commit 045cfb71a3901005bf6dcedae98cecb3360a0bfc upstream. + +Commit 'mac80211: fix skb buffering issue' added an ->ndo_select_queue() +for monitor interfaces which can end up dereferencing ieee802_1d_to_ac[] +beyond the end of the array for injected data packets (as skb->priority +isn't guaranteed to be zero or within [0:7]), which then triggers the +WARN_ON in net/core/dev.c:dev_cap_txqueue(). Fix this by always setting +the priority to zero on injected data frames. + +Signed-off-by: Lennert Buytenhek +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/iface.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -683,6 +683,7 @@ static u16 ieee80211_monitor_select_queu + return ieee802_1d_to_ac[skb->priority]; + } + ++ skb->priority = 0; + return ieee80211_downgrade_queue(local, skb); + } + diff --git a/queue-2.6.32/mac80211-fix-skb-buffering-issue.patch b/queue-2.6.32/mac80211-fix-skb-buffering-issue.patch new file mode 100644 index 00000000000..12d663972fe --- /dev/null +++ b/queue-2.6.32/mac80211-fix-skb-buffering-issue.patch @@ -0,0 +1,351 @@ +From cf0277e714a0db302a8f80e1b85fd61c32cf00b3 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Tue, 5 Jan 2010 18:00:58 +0100 +Subject: mac80211: fix skb buffering issue + +From: Johannes Berg + +commit cf0277e714a0db302a8f80e1b85fd61c32cf00b3 upstream. + +Since I removed the master netdev, we've been +keeping internal queues only, and even before +that we never told the networking stack above +the virtual interfaces about congestion. This +means that packets are queued in mac80211 and +the upper layers never know, possibly leading +to memory exhaustion and other problems. + +This patch makes all interfaces multiqueue and +uses ndo_select_queue to put the packets into +queues per AC. Additionally, when the driver +stops a queue, we now stop all corresponding +queues for the virtual interfaces as well. + +The injection case will use VO by default for +non-data frames, and BE for data frames, but +downgrade any data frames according to ACM. It +needs to be fleshed out in the future to allow +chosing the queue/AC in radiotap. + +Reported-by: Lennert Buytenhek +Signed-off-by: Johannes Berg +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/iface.c | 39 +++++++++++++++++++- + net/mac80211/rx.c | 4 +- + net/mac80211/tx.c | 5 ++ + net/mac80211/util.c | 12 ++++++ + net/mac80211/wme.c | 96 +++++++++++++++++++++++++++++++++++++-------------- + net/mac80211/wme.h | 8 +++- + 6 files changed, 132 insertions(+), 32 deletions(-) + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -15,12 +15,14 @@ + #include + #include + #include ++#include + #include "ieee80211_i.h" + #include "sta_info.h" + #include "debugfs_netdev.h" + #include "mesh.h" + #include "led.h" + #include "driver-ops.h" ++#include "wme.h" + + /** + * DOC: Interface list locking +@@ -642,6 +644,12 @@ static void ieee80211_teardown_sdata(str + WARN_ON(flushed); + } + ++static u16 ieee80211_netdev_select_queue(struct net_device *dev, ++ struct sk_buff *skb) ++{ ++ return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); ++} ++ + static const struct net_device_ops ieee80211_dataif_ops = { + .ndo_open = ieee80211_open, + .ndo_stop = ieee80211_stop, +@@ -650,8 +658,34 @@ static const struct net_device_ops ieee8 + .ndo_set_multicast_list = ieee80211_set_multicast_list, + .ndo_change_mtu = ieee80211_change_mtu, + .ndo_set_mac_address = eth_mac_addr, ++ .ndo_select_queue = ieee80211_netdev_select_queue, + }; + ++static u16 ieee80211_monitor_select_queue(struct net_device *dev, ++ struct sk_buff *skb) ++{ ++ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_hdr *hdr; ++ struct ieee80211_radiotap_header *rtap = (void *)skb->data; ++ ++ if (local->hw.queues < 4) ++ return 0; ++ ++ if (skb->len < 4 || ++ skb->len < rtap->it_len + 2 /* frame control */) ++ return 0; /* doesn't matter, frame will be dropped */ ++ ++ hdr = (void *)((u8 *)skb->data + rtap->it_len); ++ ++ if (!ieee80211_is_data(hdr->frame_control)) { ++ skb->priority = 7; ++ return ieee802_1d_to_ac[skb->priority]; ++ } ++ ++ return ieee80211_downgrade_queue(local, skb); ++} ++ + static const struct net_device_ops ieee80211_monitorif_ops = { + .ndo_open = ieee80211_open, + .ndo_stop = ieee80211_stop, +@@ -660,6 +694,7 @@ static const struct net_device_ops ieee8 + .ndo_set_multicast_list = ieee80211_set_multicast_list, + .ndo_change_mtu = ieee80211_change_mtu, + .ndo_set_mac_address = eth_mac_addr, ++ .ndo_select_queue = ieee80211_monitor_select_queue, + }; + + static void ieee80211_if_setup(struct net_device *dev) +@@ -768,8 +803,8 @@ int ieee80211_if_add(struct ieee80211_lo + + ASSERT_RTNL(); + +- ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, +- name, ieee80211_if_setup); ++ ndev = alloc_netdev_mq(sizeof(*sdata) + local->hw.vif_data_size, ++ name, ieee80211_if_setup, local->hw.queues); + if (!ndev) + return -ENOMEM; + dev_net_set(ndev, wiphy_net(local->hw.wiphy)); +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1548,7 +1548,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + memset(info, 0, sizeof(*info)); + info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; + info->control.vif = &rx->sdata->vif; +- ieee80211_select_queue(local, fwd_skb); ++ skb_set_queue_mapping(skb, ++ ieee80211_select_queue(rx->sdata, fwd_skb)); ++ ieee80211_set_qos_hdr(local, skb); + if (is_multicast_ether_addr(fwd_hdr->addr1)) + IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, + fwded_mcast); +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1482,7 +1482,7 @@ static void ieee80211_xmit(struct ieee80 + return; + } + +- ieee80211_select_queue(local, skb); ++ ieee80211_set_qos_hdr(local, skb); + ieee80211_tx(sdata, skb, false); + dev_put(sdata->dev); + } +@@ -2226,6 +2226,9 @@ void ieee80211_tx_skb(struct ieee80211_s + if (!encrypt) + info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + ++ /* send all internal mgmt frames on VO */ ++ skb_set_queue_mapping(skb, 0); ++ + /* + * The other path calling ieee80211_xmit is from the tasklet, + * and while we can handle concurrent transmissions locking +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -269,6 +269,7 @@ static void __ieee80211_wake_queue(struc + enum queue_stop_reason reason) + { + struct ieee80211_local *local = hw_to_local(hw); ++ struct ieee80211_sub_if_data *sdata; + + if (WARN_ON(queue >= hw->queues)) + return; +@@ -281,6 +282,11 @@ static void __ieee80211_wake_queue(struc + + if (!skb_queue_empty(&local->pending[queue])) + tasklet_schedule(&local->tx_pending_tasklet); ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(sdata, &local->interfaces, list) ++ netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); ++ rcu_read_unlock(); + } + + void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, +@@ -305,11 +311,17 @@ static void __ieee80211_stop_queue(struc + enum queue_stop_reason reason) + { + struct ieee80211_local *local = hw_to_local(hw); ++ struct ieee80211_sub_if_data *sdata; + + if (WARN_ON(queue >= hw->queues)) + return; + + __set_bit(reason, &local->queue_stop_reasons[queue]); ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(sdata, &local->interfaces, list) ++ netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue)); ++ rcu_read_unlock(); + } + + void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, +--- a/net/mac80211/wme.c ++++ b/net/mac80211/wme.c +@@ -44,22 +44,69 @@ static int wme_downgrade_ac(struct sk_bu + } + + +-/* Indicate which queue to use. */ +-static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb) ++/* Indicate which queue to use. */ ++u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; ++ struct ieee80211_local *local = sdata->local; ++ struct sta_info *sta = NULL; ++ u32 sta_flags = 0; ++ const u8 *ra = NULL; ++ bool qos = false; + +- if (!ieee80211_is_data(hdr->frame_control)) { +- /* management frames go on AC_VO queue, but are sent +- * without QoS control fields */ +- return 0; ++ if (local->hw.queues < 4 || skb->len < 6) { ++ skb->priority = 0; /* required for correct WPA/11i MIC */ ++ return min_t(u16, local->hw.queues - 1, ++ ieee802_1d_to_ac[skb->priority]); ++ } ++ ++ rcu_read_lock(); ++ switch (sdata->vif.type) { ++ case NL80211_IFTYPE_AP_VLAN: ++ rcu_read_lock(); ++ sta = rcu_dereference(sdata->u.vlan.sta); ++ if (sta) ++ sta_flags = get_sta_flags(sta); ++ rcu_read_unlock(); ++ if (sta) ++ break; ++ case NL80211_IFTYPE_AP: ++ ra = skb->data; ++ break; ++ case NL80211_IFTYPE_WDS: ++ ra = sdata->u.wds.remote_addr; ++ break; ++#ifdef CONFIG_MAC80211_MESH ++ case NL80211_IFTYPE_MESH_POINT: ++ /* ++ * XXX: This is clearly broken ... but already was before, ++ * because ieee80211_fill_mesh_addresses() would clear A1 ++ * except for multicast addresses. ++ */ ++ break; ++#endif ++ case NL80211_IFTYPE_STATION: ++ ra = sdata->u.mgd.bssid; ++ break; ++ case NL80211_IFTYPE_ADHOC: ++ ra = skb->data; ++ break; ++ default: ++ break; + } + +- if (0 /* injected */) { +- /* use AC from radiotap */ ++ if (!sta && ra && !is_multicast_ether_addr(ra)) { ++ sta = sta_info_get(sdata, ra); ++ if (sta) ++ sta_flags = get_sta_flags(sta); + } + +- if (!ieee80211_is_data_qos(hdr->frame_control)) { ++ if (sta_flags & WLAN_STA_WME) ++ qos = true; ++ ++ rcu_read_unlock(); ++ ++ if (!qos) { + skb->priority = 0; /* required for correct WPA/11i MIC */ + return ieee802_1d_to_ac[skb->priority]; + } +@@ -68,6 +115,12 @@ static u16 classify80211(struct ieee8021 + * data frame has */ + skb->priority = cfg80211_classify8021d(skb); + ++ return ieee80211_downgrade_queue(local, skb); ++} ++ ++u16 ieee80211_downgrade_queue(struct ieee80211_local *local, ++ struct sk_buff *skb) ++{ + /* in case we are a client verify acm is not set for this ac */ + while (unlikely(local->wmm_acm & BIT(skb->priority))) { + if (wme_downgrade_ac(skb)) { +@@ -85,24 +138,17 @@ static u16 classify80211(struct ieee8021 + return ieee802_1d_to_ac[skb->priority]; + } + +-void ieee80211_select_queue(struct ieee80211_local *local, struct sk_buff *skb) ++void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; +- u16 queue; +- u8 tid; +- +- queue = classify80211(local, skb); +- if (unlikely(queue >= local->hw.queues)) +- queue = local->hw.queues - 1; +- +- /* +- * Now we know the 1d priority, fill in the QoS header if +- * there is one (and we haven't done this before). +- */ ++ struct ieee80211_hdr *hdr = (void *)skb->data; ++ ++ /* Fill in the QoS header if there is one. */ + if (ieee80211_is_data_qos(hdr->frame_control)) { + u8 *p = ieee80211_get_qos_ctl(hdr); +- u8 ack_policy = 0; ++ u8 ack_policy = 0, tid; ++ + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ + if (unlikely(local->wifi_wme_noack_test)) + ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << + QOS_CONTROL_ACK_POLICY_SHIFT; +@@ -110,6 +156,4 @@ void ieee80211_select_queue(struct ieee8 + *p++ = ack_policy | tid; + *p = 0; + } +- +- skb_set_queue_mapping(skb, queue); + } +--- a/net/mac80211/wme.h ++++ b/net/mac80211/wme.h +@@ -20,7 +20,11 @@ + + extern const int ieee802_1d_to_ac[8]; + +-void ieee80211_select_queue(struct ieee80211_local *local, +- struct sk_buff *skb); ++u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb); ++void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb); ++u16 ieee80211_downgrade_queue(struct ieee80211_local *local, ++ struct sk_buff *skb); ++ + + #endif /* _WME_H */ diff --git a/queue-2.6.32/series b/queue-2.6.32/series index 8714409c919..f33669245f0 100644 --- a/queue-2.6.32/series +++ b/queue-2.6.32/series @@ -34,3 +34,15 @@ netfilter-nf_ct_ftp-fix-out-of-bounds-read-in-update_nl_seq.patch hwmon-coretemp-fix-tjmax-for-atom-n450-d410-d510-cpus.patch hwmon-adt7462-fix-pin-28-monitoring.patch quota-fix-dquot_transfer-for-filesystems-different-from-ext4.patch +xen-fix-hang-on-suspend.patch +iwlwifi-fix-iwl_queue_used-bug-when-read_ptr-write_ptr.patch +ath5k-fix-eeprom-checksum-check-for-custom-sized-eeproms.patch +cfg80211-fix-syntax-error-on-user-regulatory-hints.patch +iwl-off-by-one-bug.patch +mac80211-fix-skb-buffering-issue.patch +mac80211-fix-queue-selection-for-packets-injected-via-monitor-interface.patch +mac80211-add-missing-sanity-checks-for-action-frames.patch +mac80211-fix-endian-error.patch +drm-i915-remove-render-reclock-support.patch +libertas-remove-carrier-signaling-from-the-scan-code.patch +kernel-sysctl.c-fix-stable-merge-error-in-nommu-mmap_min_addr.patch diff --git a/queue-2.6.32/xen-fix-hang-on-suspend.patch b/queue-2.6.32/xen-fix-hang-on-suspend.patch new file mode 100644 index 00000000000..aa2e1594977 --- /dev/null +++ b/queue-2.6.32/xen-fix-hang-on-suspend.patch @@ -0,0 +1,79 @@ +From c5cae661d6cf808b6984762f763261adf35f3eb7 Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Thu, 17 Dec 2009 13:57:09 +0000 +Subject: xen: fix hang on suspend. + +From: Ian Campbell + +commit c5cae661d6cf808b6984762f763261adf35f3eb7 upstream. + +In 65f63384 "xen: improve error handling in do_suspend" I said: + - xs_suspend()/xs_resume() and dpm_suspend_noirq()/dpm_resume_noirq() were not + nested in the obvious way. +and changed the ordering of the calls as so: + BEFORE AFTER + xs_suspend dpm_suspend_noirq + dpm_suspend_noirq xs_suspend + *SUSPEND* *SUSPEND* + dpm_resume_noirq dpm_resume_noirq + xs_resume xs_resume +Clearly this is not an improvement and I was talking rubbish. + +In particular the new ordering is susceptible to a hang if a xenstore write is +in progress at the point at which the suspend kicks in. When the suspend +process calls xs_suspend it tries to take the request_mutex but if a write is +in progress it could be looping in xenbus_xs.c:read_reply() waiting for +something to arrive on &xs_state.reply_list while holding the request_mutex +(taken in the caller of read_reply). + +However if we have done dpm_suspend_noirq before xs_suspend then we won't get +any more xenstore interrupts and process_msg() will never be woken up to add +anything to the reply_list. + +Fix this by calling xs_suspend before dpm_suspend_noirq. If dpm_suspend_noirq +fails then make sure we go through the xs_suspend_cancel() code path. + +Signed-off-by: Ian Campbell +Acked-by: Jeremy Fitzhardinge +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/xen/manage.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/xen/manage.c ++++ b/drivers/xen/manage.c +@@ -102,15 +102,15 @@ static void do_suspend(void) + goto out_thaw; + } + ++ printk(KERN_DEBUG "suspending xenstore...\n"); ++ xs_suspend(); ++ + err = dpm_suspend_noirq(PMSG_SUSPEND); + if (err) { + printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); + goto out_resume; + } + +- printk(KERN_DEBUG "suspending xenstore...\n"); +- xs_suspend(); +- + err = stop_machine(xen_suspend, &cancelled, cpumask_of(0)); + + dpm_resume_noirq(PMSG_RESUME); +@@ -120,13 +120,13 @@ static void do_suspend(void) + cancelled = 1; + } + ++out_resume: + if (!cancelled) { + xen_arch_resume(); + xs_resume(); + } else + xs_suspend_cancel(); + +-out_resume: + dpm_resume_end(PMSG_RESUME); + + /* Make sure timer events get retriggered on all CPUs */