From: Greg Kroah-Hartman Date: Thu, 15 Oct 2009 23:21:23 +0000 (-0700) Subject: more .31 patches X-Git-Tag: v2.6.27.38~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4d8287e2d76932be94265acb9e88fa60fea87b78;p=thirdparty%2Fkernel%2Fstable-queue.git more .31 patches --- diff --git a/queue-2.6.31/iwlwifi-incorrect-method-used-for-finding-valid-otp-blocks.patch b/queue-2.6.31/iwlwifi-incorrect-method-used-for-finding-valid-otp-blocks.patch new file mode 100644 index 00000000000..d0425d90125 --- /dev/null +++ b/queue-2.6.31/iwlwifi-incorrect-method-used-for-finding-valid-otp-blocks.patch @@ -0,0 +1,85 @@ +From 2facba769d7f9e563cf706de709074a2d20f1bba Mon Sep 17 00:00:00 2001 +From: Jay Sternberg +Date: Fri, 2 Oct 2009 13:43:55 -0700 +Subject: iwlwifi: incorrect method used for finding valid OTP blocks + +From: Jay Sternberg + +commit 2facba769d7f9e563cf706de709074a2d20f1bba upstream. + +The address stored in the next link address is a word address but when +reading the OTP blocks, a byte address is used. Also if the blocks are +full and the last link pointer is not zero, then none of the blocks are +valid so return an error. + +The algorithm is simply valid blocks have a next address and that +address's contents is zero. + +Using the wrong address for the next link address gets arbitrary data, +obviously. In cases seen, the first block is considered valid when it is not. + +If the block has in fact been invalidated there may be old data or +there may be no data, bad data, or partial data, there is no way of +telling. Without this patch it is possible that a device with valid OTP data +is unable to work. + +Signed-off-by: Jay Sternberg +Signed-off-by: Reinette Chatre +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-eeprom.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c ++++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c +@@ -335,7 +335,6 @@ static int iwl_find_otp_image(struct iwl + u16 *validblockaddr) + { + u16 next_link_addr = 0, link_value = 0, valid_addr; +- int ret = 0; + int usedblocks = 0; + + /* set addressing mode to absolute to traverse the link list */ +@@ -355,29 +354,29 @@ static int iwl_find_otp_image(struct iwl + * check for more block on the link list + */ + valid_addr = next_link_addr; +- next_link_addr = link_value; ++ next_link_addr = link_value * sizeof(u16); + IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", + usedblocks, next_link_addr); + if (iwl_read_otp_word(priv, next_link_addr, &link_value)) + return -EINVAL; + if (!link_value) { + /* +- * reach the end of link list, ++ * reach the end of link list, return success and + * set address point to the starting address + * of the image + */ +- goto done; ++ *validblockaddr = valid_addr; ++ /* skip first 2 bytes (link list pointer) */ ++ *validblockaddr += 2; ++ return 0; + } + /* more in the link list, continue */ + usedblocks++; +- } while (usedblocks < priv->cfg->max_ll_items); +- /* OTP full, use last block */ +- IWL_DEBUG_INFO(priv, "OTP is full, use last block\n"); +-done: +- *validblockaddr = valid_addr; +- /* skip first 2 bytes (link list pointer) */ +- *validblockaddr += 2; +- return ret; ++ } while (usedblocks <= priv->cfg->max_ll_items); ++ ++ /* OTP has no valid blocks */ ++ IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n"); ++ return -EINVAL; + } + + /** diff --git a/queue-2.6.31/mac80211-fix-vlan-and-optimise-rx.patch b/queue-2.6.31/mac80211-fix-vlan-and-optimise-rx.patch new file mode 100644 index 00000000000..bae797d8389 --- /dev/null +++ b/queue-2.6.31/mac80211-fix-vlan-and-optimise-rx.patch @@ -0,0 +1,87 @@ +From fbc44bf7177dfd61381da55405550b693943a432 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Thu, 1 Oct 2009 22:06:29 +0200 +Subject: mac80211: fix vlan and optimise RX + +From: Johannes Berg + +commit fbc44bf7177dfd61381da55405550b693943a432 upstream. + +When receiving data frames, we can send them only to +the interface they belong to based on transmitting +station (this doesn't work for probe requests). Also, +don't try to handle other frames for AP_VLAN at all +since those interface should only receive data. + +Additionally, the transmit side must check that the +station we're sending a frame to is actually on the +interface we're transmitting on, and not transmit +packets to functions that live on other interfaces, +so validate that as well. + +Another bug fix is needed in sta_info.c where in the +VLAN case when adding/removing stations we overwrite +the sdata variable we still need. + +Signed-off-by: Johannes Berg +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/rx.c | 10 ++++++++-- + net/mac80211/sta_info.c | 2 ++ + net/mac80211/tx.c | 3 ++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2155,11 +2155,17 @@ static void __ieee80211_rx_handle_packet + + skb = rx.skb; + +- list_for_each_entry_rcu(sdata, &local->interfaces, list) { ++ if (rx.sdata && ieee80211_is_data(hdr->frame_control)) { ++ rx.flags |= IEEE80211_RX_RA_MATCH; ++ prepares = prepare_for_handlers(rx.sdata, &rx, hdr); ++ if (prepares) ++ prev = rx.sdata; ++ } else list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!netif_running(sdata->dev)) + continue; + +- if (sdata->vif.type == NL80211_IFTYPE_MONITOR) ++ if (sdata->vif.type == NL80211_IFTYPE_MONITOR || ++ sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + continue; + + rx.flags |= IEEE80211_RX_RA_MATCH; +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -360,6 +360,7 @@ int sta_info_insert(struct sta_info *sta + u.ap); + + drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta); ++ sdata = sta->sdata; + } + + #ifdef CONFIG_MAC80211_VERBOSE_DEBUG +@@ -494,6 +495,7 @@ static void __sta_info_unlink(struct sta + + drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, + &(*sta)->sta); ++ sdata = (*sta)->sdata; + } + + if (ieee80211_vif_is_mesh(&sdata->vif)) { +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1736,7 +1736,8 @@ int ieee80211_subif_start_xmit(struct sk + if (!is_multicast_ether_addr(hdr.addr1)) { + rcu_read_lock(); + sta = sta_info_get(local, hdr.addr1); +- if (sta) ++ /* XXX: in the future, use sdata to look up the sta */ ++ if (sta && sta->sdata == sdata) + sta_flags = get_sta_flags(sta); + rcu_read_unlock(); + } diff --git a/queue-2.6.31/series b/queue-2.6.31/series index f1d2c3b862b..16ef59a164d 100644 --- a/queue-2.6.31/series +++ b/queue-2.6.31/series @@ -38,3 +38,8 @@ macintosh-don-t-assume-i2c-device-probing-always-succeeds.patch i2c-hide-probe-errors-caused-by-acpi-resource-conflicts.patch alsa-don-t-assume-i2c-device-probing-always-succeeds.patch bsdacct-switch-credentials-for-writing-to-the-accounting-file.patch +sysfs-allow-sysfs_notify_dirent-to-be-called-from-interrupt-context.patch +staging-rt2860sta-prevent-a-panic-when-disabling-when-associated.patch +usb-storage-workaround-devices-with-bogus-sense-size.patch +iwlwifi-incorrect-method-used-for-finding-valid-otp-blocks.patch +mac80211-fix-vlan-and-optimise-rx.patch diff --git a/queue-2.6.31/staging-rt2860sta-prevent-a-panic-when-disabling-when-associated.patch b/queue-2.6.31/staging-rt2860sta-prevent-a-panic-when-disabling-when-associated.patch new file mode 100644 index 00000000000..e8be0d80444 --- /dev/null +++ b/queue-2.6.31/staging-rt2860sta-prevent-a-panic-when-disabling-when-associated.patch @@ -0,0 +1,34 @@ +From 0af49167b1e5ba154e90d2c454bf4624ee47df80 Mon Sep 17 00:00:00 2001 +From: Darren Salt +Date: Wed, 14 Oct 2009 02:19:22 +0100 +Subject: Staging: rt2860sta: prevent a panic when disabling when associated + +From: Darren Salt + +commit 0af49167b1e5ba154e90d2c454bf4624ee47df80 upstream. + +This fixes a panic which is triggered when the hardware "disappears" from +beneath the driver, i.e. when wireless is toggled off via Fn-F2 on various +EeePC models. + +Ref. bug report http://bugzilla.kernel.org/show_bug.cgi?id=13390 + panic http://bugzilla.kernel.org/attachment.cgi?id=21928 + +Signed-off-by: Darren Salt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rt2860/common/cmm_data_2860.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/staging/rt2860/common/cmm_data_2860.c ++++ b/drivers/staging/rt2860/common/cmm_data_2860.c +@@ -363,6 +363,8 @@ int RtmpPCIMgmtKickOut( + ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; + + pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa; ++ if (!pTxD) ++ return 0; + + pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket; + pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL; diff --git a/queue-2.6.31/sysfs-allow-sysfs_notify_dirent-to-be-called-from-interrupt-context.patch b/queue-2.6.31/sysfs-allow-sysfs_notify_dirent-to-be-called-from-interrupt-context.patch new file mode 100644 index 00000000000..23b29a30a4f --- /dev/null +++ b/queue-2.6.31/sysfs-allow-sysfs_notify_dirent-to-be-called-from-interrupt-context.patch @@ -0,0 +1,97 @@ +From 83db93f4de2d9ae441a491d1dc61c2204f0195de Mon Sep 17 00:00:00 2001 +From: Neil Brown +Date: Tue, 15 Sep 2009 16:05:51 -0700 +Subject: sysfs: Allow sysfs_notify_dirent to be called from interrupt context. + +From: Neil Brown + +commit 83db93f4de2d9ae441a491d1dc61c2204f0195de upstream. + +sysfs_notify_dirent is a simple atomic operation that can be used to +alert user-space that new data can be read from a sysfs attribute. + +Unfortunately it cannot currently be called from non-process context +because of its use of spin_lock which is sometimes taken with +interrupts enabled. + +So change all lockers of sysfs_open_dirent_lock to disable interrupts, +thus making sysfs_notify_dirent safe to be called from non-process +context (as drivers/md does in md_safemode_timeout). + +sysfs_get_open_dirent is (documented as being) only called from +process context, so it uses spin_lock_irq. Other places +use spin_lock_irqsave. + +The usage for sysfs_notify_dirent in md_safemode_timeout was +introduced in 2.6.28, so this patch is suitable for that and more +recent kernels. + +Reported-by: Joel Andres Granados +Signed-off-by: NeilBrown +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + fs/sysfs/file.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/fs/sysfs/file.c ++++ b/fs/sysfs/file.c +@@ -268,7 +268,7 @@ static int sysfs_get_open_dirent(struct + struct sysfs_open_dirent *od, *new_od = NULL; + + retry: +- spin_lock(&sysfs_open_dirent_lock); ++ spin_lock_irq(&sysfs_open_dirent_lock); + + if (!sd->s_attr.open && new_od) { + sd->s_attr.open = new_od; +@@ -281,7 +281,7 @@ static int sysfs_get_open_dirent(struct + list_add_tail(&buffer->list, &od->buffers); + } + +- spin_unlock(&sysfs_open_dirent_lock); ++ spin_unlock_irq(&sysfs_open_dirent_lock); + + if (od) { + kfree(new_od); +@@ -315,8 +315,9 @@ static void sysfs_put_open_dirent(struct + struct sysfs_buffer *buffer) + { + struct sysfs_open_dirent *od = sd->s_attr.open; ++ unsigned long flags; + +- spin_lock(&sysfs_open_dirent_lock); ++ spin_lock_irqsave(&sysfs_open_dirent_lock, flags); + + list_del(&buffer->list); + if (atomic_dec_and_test(&od->refcnt)) +@@ -324,7 +325,7 @@ static void sysfs_put_open_dirent(struct + else + od = NULL; + +- spin_unlock(&sysfs_open_dirent_lock); ++ spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); + + kfree(od); + } +@@ -456,8 +457,9 @@ static unsigned int sysfs_poll(struct fi + void sysfs_notify_dirent(struct sysfs_dirent *sd) + { + struct sysfs_open_dirent *od; ++ unsigned long flags; + +- spin_lock(&sysfs_open_dirent_lock); ++ spin_lock_irqsave(&sysfs_open_dirent_lock, flags); + + od = sd->s_attr.open; + if (od) { +@@ -465,7 +467,7 @@ void sysfs_notify_dirent(struct sysfs_di + wake_up_interruptible(&od->poll); + } + +- spin_unlock(&sysfs_open_dirent_lock); ++ spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); + } + EXPORT_SYMBOL_GPL(sysfs_notify_dirent); + diff --git a/queue-2.6.31/usb-storage-workaround-devices-with-bogus-sense-size.patch b/queue-2.6.31/usb-storage-workaround-devices-with-bogus-sense-size.patch new file mode 100644 index 00000000000..7201f5a8609 --- /dev/null +++ b/queue-2.6.31/usb-storage-workaround-devices-with-bogus-sense-size.patch @@ -0,0 +1,64 @@ +From b8430e1b82b7e514d76a88eb70a7d8831d50df1e Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Tue, 13 Oct 2009 15:53:47 +1100 +Subject: usb-storage: Workaround devices with bogus sense size + +From: Benjamin Herrenschmidt + +commit b8430e1b82b7e514d76a88eb70a7d8831d50df1e upstream. + +usb-storage: Workaround devices with bogus sense size + +Some devices, such as Huawei E169, advertise more than the standard +amount of sense data, causing us to set US_FL_SANE_SENSE, assuming +they support it. However, they subsequently fail the request sense +with that size. + +This works around it generically. When a sense request fails due to +a device returning an error, US_FL_SANE_SENSE was set, and that sense +request used a larger sense size, we retry with a smaller size before +giving up. + +Based on an original patch by Ben Efros + +Signed-off-by: Benjamin Herrenschmidt +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/transport.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/usb/storage/transport.c ++++ b/drivers/usb/storage/transport.c +@@ -696,7 +696,7 @@ void usb_stor_invoke_transport(struct sc + /* device supports and needs bigger sense buffer */ + if (us->fflags & US_FL_SANE_SENSE) + sense_size = ~0; +- ++Retry_Sense: + US_DEBUGP("Issuing auto-REQUEST_SENSE\n"); + + scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size); +@@ -720,6 +720,21 @@ void usb_stor_invoke_transport(struct sc + srb->result = DID_ABORT << 16; + goto Handle_Errors; + } ++ ++ /* Some devices claim to support larger sense but fail when ++ * trying to request it. When a transport failure happens ++ * using US_FS_SANE_SENSE, we always retry with a standard ++ * (small) sense request. This fixes some USB GSM modems ++ */ ++ if (temp_result == USB_STOR_TRANSPORT_FAILED && ++ (us->fflags & US_FL_SANE_SENSE) && ++ sense_size != US_SENSE_SIZE) { ++ US_DEBUGP("-- auto-sense failure, retry small sense\n"); ++ sense_size = US_SENSE_SIZE; ++ goto Retry_Sense; ++ } ++ ++ /* Other failures */ + if (temp_result != USB_STOR_TRANSPORT_GOOD) { + US_DEBUGP("-- auto-sense failure\n"); +