--- /dev/null
+From eeb4bcb4771679d7b3446c0293334faee11b090a Mon Sep 17 00:00:00 2001
+From: Kamal Mostafa <kamal@canonical.com>
+Date: Sat, 1 May 2010 12:09:49 -0700
+Subject: ACPI: video: fix acpi_backlight=video
+
+From: Kamal Mostafa <kamal@canonical.com>
+
+commit eeb4bcb4771679d7b3446c0293334faee11b090a upstream.
+
+Make "acpi_backlight=video" param enable ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO
+as intended, instead of incorrectly enabling video output switching.
+
+BugLink: http://bugs.launchpad.net/bugs/573120
+
+Signed-off-by: Kamal Mostafa <kamal@canonical.com>
+Acked-by: Zhang Rui <rui.zhang@intel.com>
+Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
+Cc: Jiri Kosina <jkosina@suse.cz>
+Acked-by: Thomas Renninger <trenn@suse.de>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/video_detect.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -250,7 +250,7 @@ static int __init acpi_backlight(char *s
+ ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR;
+ if (!strcmp("video", str))
+ acpi_video_support |=
+- ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO;
++ ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO;
+ }
+ return 1;
+ }
--- /dev/null
+From 66668b6fb6861fad7f6bfef6646ac84693474c9a Mon Sep 17 00:00:00 2001
+From: Daniel T Chen <crimsun@ubuntu.com>
+Date: Sun, 23 May 2010 20:47:45 -0400
+Subject: ALSA: hda: Fix model quirk for Dell M1730
+
+From: Daniel T Chen <crimsun@ubuntu.com>
+
+commit 66668b6fb6861fad7f6bfef6646ac84693474c9a upstream.
+
+BugLink: https://launchpad.net/bugs/576160
+
+Symptom: Currently (2.6.32.12) the Dell M1730 uses the 3stack model
+quirk. Unfortunately this means that capture is not functional out-
+of-the-box despite ensuring that capture settings are unmuted and
+raised fully.
+
+Test case: boot from Ubuntu 10.04 LTS live cd; capture does not
+work.
+
+Resolution: Correct the model quirk for Dell M1730 to rely on the
+BIOS configuration.
+
+This patch also trivially sorts the quirk into the correct section
+based on the comments.
+
+Reported-and-Tested-By: <picdragon99@msn.com>
+Tested-By: Daren Hayward
+Tested-By: Tobias Krais
+Signed-off-by: Daniel T Chen <crimsun@ubuntu.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/patch_sigmatel.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -2078,12 +2078,12 @@ static struct snd_pci_quirk stac927x_cfg
+ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000,
+ "Intel D965", STAC_D965_3ST),
+ /* Dell 3 stack systems */
+- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST),
+ /* Dell 3 stack systems with verb table in BIOS */
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS),
++ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_BIOS),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_BIOS),
--- /dev/null
+From 61bb42c37dfa9016dcacc86bcd41362ab2457d4a Mon Sep 17 00:00:00 2001
+From: Daniel T Chen <crimsun@ubuntu.com>
+Date: Sat, 29 May 2010 11:04:11 -0400
+Subject: ALSA: hda: Use LPIB for a Shuttle device
+
+From: Daniel T Chen <crimsun@ubuntu.com>
+
+commit 61bb42c37dfa9016dcacc86bcd41362ab2457d4a upstream.
+
+BugLink: https://launchpad.net/bugs/551949
+
+Symptom: On the reporter's Shuttle device, using PulseAudio in Ubuntu
+10.04 LTS results in "popping clicking" audio with the PA crashing
+shortly thereafter.
+
+Test case: Using Ubuntu 10.04 LTS (Linux 2.6.32.12), Linux 2.6.33, or
+Linux 2.6.34, adjust the HDA device's volume with PulseAudio.
+
+Resolution: add SSID for this machine to the position_fix quirk table,
+explicitly specifying the LPIB method.
+
+Reported-and-Tested-By: Christian Mehlis <mehlis@inf.fu-berlin.de>
+Signed-off-by: Daniel T Chen <crimsun@ubuntu.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/hda_intel.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2272,6 +2272,7 @@ static struct snd_pci_quirk position_fix
+ SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
++ SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
--- /dev/null
+From 7a68be94e22e7643038726ebc14360752a91800b Mon Sep 17 00:00:00 2001
+From: Daniel T Chen <crimsun@ubuntu.com>
+Date: Sat, 22 May 2010 12:05:41 -0400
+Subject: ALSA: hda: Use LPIB for Acer Aspire 5110
+
+From: Daniel T Chen <crimsun@ubuntu.com>
+
+commit 7a68be94e22e7643038726ebc14360752a91800b upstream.
+
+BugLink: https://launchpad.net/bugs/583983
+
+Symptom: on a significant number of hardware, booting from a live cd
+results in capture working correctly, but once the distribution is
+installed, booting from the install results in capture not working.
+
+Test case: boot from Ubuntu 10.04 LTS live cd; capture works correctly.
+Install to HD and reboot; capture does not work. Reproduced with 2.6.32
+mainline build (vanilla kernel.org compile).
+
+Resolution: add SSID for Acer Aspire 5110 to the position_fix quirk
+table, explicitly specifying the LPIB method.
+
+I'll be sending additional patches for these SSIDs as bug reports are
+confirmed.
+
+Reported-and-Tested-By: Leo
+Signed-off-by: Daniel T Chen <crimsun@ubuntu.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/hda_intel.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2263,6 +2263,7 @@ static int azx_dev_free(struct snd_devic
+ * white/black-listing for position_fix
+ */
+ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
++ SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
--- /dev/null
+From e96d3127760a2fc509bca6bf7e61e8bc61497aeb Mon Sep 17 00:00:00 2001
+From: Daniel T Chen <crimsun@ubuntu.com>
+Date: Thu, 27 May 2010 18:32:18 -0400
+Subject: ALSA: hda: Use LPIB for Sony VPCS11V9E
+
+From: Daniel T Chen <crimsun@ubuntu.com>
+
+commit e96d3127760a2fc509bca6bf7e61e8bc61497aeb upstream.
+
+BugLink: https://launchpad.net/bugs/586347
+
+Symptom: On the Sony VPCS11V9E, using GStreamer-based applications with
+PulseAudio in Ubuntu 10.04 LTS results in stuttering audio. It appears
+to worsen with increased I/O.
+
+Test case: use Rhythmbox under increased I/O pressure. This symptom is
+reproducible in the current daily stable alsa-driver snapshots (at least
+up until 21 May 2010; later snapshots fail to build from source due to
+missing preprocessor directives when compiled against 2.6.32).
+
+Resolution: add SSID for this machine to the position_fix quirk table,
+explicitly specifying the LPIB method.
+
+Reported-and-Tested-By: Lauri Kainulainen <lauri@sokkelo.net>
+Signed-off-by: Daniel T Chen <crimsun@ubuntu.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/hda_intel.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2269,6 +2269,7 @@ static struct snd_pci_quirk position_fix
+ SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
++ SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
--- /dev/null
+From 4e0938dba7fccf37a4aecba4d937da7f312b5d55 Mon Sep 17 00:00:00 2001
+From: Daniel T Chen <crimsun@ubuntu.com>
+Date: Sat, 22 May 2010 13:12:22 -0400
+Subject: ALSA: hda: Use LPIB for Toshiba A100-259
+
+From: Daniel T Chen <crimsun@ubuntu.com>
+
+commit 4e0938dba7fccf37a4aecba4d937da7f312b5d55 upstream.
+
+BugLink: https://launchpad.net/bugs/549560
+
+Symptom: on a significant number of hardware, booting from a live cd
+results in capture working correctly, but once the distribution is
+installed, booting from the install results in capture not working.
+
+Test case: boot from Ubuntu 10.04 LTS live cd; capture works correctly.
+Install to HD and reboot; capture does not work. Reproduced with 2.6.32
+mainline build (vanilla kernel.org compile)
+
+Resolution: add SSID for Toshiba A100-259 to the position_fix quirk
+table, explicitly specifying the LPIB method.
+
+I'll be sending additional patches for these SSIDs as bug reports are
+confirmed.
+
+This patch also trivially sorts the quirk table in ascending order by
+subsystem vendor.
+
+Reported-and-Tested-by: <davide.molteni@gmail.com>
+Signed-off-by: Daniel T Chen <crimsun@ubuntu.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/hda_intel.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2267,8 +2267,9 @@ static struct snd_pci_quirk position_fix
+ SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
+- SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
++ SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
++ SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
--- /dev/null
+From b406e6103baa3da85950f22d3d46d21a8da654c5 Mon Sep 17 00:00:00 2001
+From: Clemens Ladisch <clemens@ladisch.de>
+Date: Tue, 25 May 2010 09:01:46 +0200
+Subject: ALSA: pcm: fix delta calculation at boundary wraparound
+
+From: Clemens Ladisch <clemens@ladisch.de>
+
+commit b406e6103baa3da85950f22d3d46d21a8da654c5 upstream.
+
+In the cleanup of the hw_ptr update functions in 2.6.33, the calculation
+of the delta value was changed to use the modulo operator to protect
+against a negative difference due to the pointer wrapping around at the
+boundary.
+
+However, the ptr variables are unsigned, so a negative difference would
+result in the two complement's value which has no relation to the actual
+difference relative to the boundary; the result is typically some value
+near LONG_MAX-boundary. Furthermore, even if the modulo operation would
+be done with signed types, the result of a negative dividend could be
+negative.
+
+The invalid delta value is then caught by the following checks, but this
+means that the pointer update is ignored.
+
+To fix this, use a range check as in the other pointer calculations.
+
+Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/core/pcm_lib.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/sound/core/pcm_lib.c
++++ b/sound/core/pcm_lib.c
+@@ -345,7 +345,9 @@ static int snd_pcm_update_hw_ptr0(struct
+ new_hw_ptr = hw_base + pos;
+ }
+ __delta:
+- delta = (new_hw_ptr - old_hw_ptr) % runtime->boundary;
++ delta = new_hw_ptr - old_hw_ptr;
++ if (delta < 0)
++ delta += runtime->boundary;
+ if (xrun_debug(substream, in_interrupt ?
+ XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
+ char name[16];
--- /dev/null
+From ead4046b2fdfd69acc4272e693afd249ad3eb689 Mon Sep 17 00:00:00 2001
+From: Clemens Ladisch <clemens@ladisch.de>
+Date: Fri, 21 May 2010 09:15:59 +0200
+Subject: ALSA: pcm: fix the fix of the runtime->boundary calculation
+
+From: Clemens Ladisch <clemens@ladisch.de>
+
+commit ead4046b2fdfd69acc4272e693afd249ad3eb689 upstream.
+
+Commit 7910b4a1db63fefc3d291853d33c34c5b6352e8e in 2.6.34 changed the
+runtime->boundary calculation to make this value a multiple of both the
+buffer_size and the period_size, because the latter is assumed by the
+runtime->hw_ptr_interrupt calculation.
+
+However, due to the lack of a ioctl that could read the software
+parameters before they are set, the kernel requires that alsa-lib
+calculates the boundary value, too. The changed algorithm leads to
+a different boundary value used by alsa-lib, which makes, e.g., mplayer
+fail to play a 44.1 kHz file because the silence_size parameter is now
+invalid; bug report:
+<https://bugtrack.alsa-project.org/alsa-bug/view.php?id=5015>.
+
+This patch reverts the change to the boundary calculation, and instead
+fixes the hw_ptr_interrupt calculation to be period-aligned regardless
+of the boundary value.
+
+Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/core/pcm_lib.c | 9 +++++++--
+ sound/core/pcm_native.c | 39 +++------------------------------------
+ 2 files changed, 10 insertions(+), 38 deletions(-)
+
+--- a/sound/core/pcm_lib.c
++++ b/sound/core/pcm_lib.c
+@@ -441,8 +441,13 @@ static int snd_pcm_update_hw_ptr0(struct
+ snd_pcm_playback_silence(substream, new_hw_ptr);
+
+ if (in_interrupt) {
+- runtime->hw_ptr_interrupt = new_hw_ptr -
+- (new_hw_ptr % runtime->period_size);
++ delta = new_hw_ptr - runtime->hw_ptr_interrupt;
++ if (delta < 0)
++ delta += runtime->boundary;
++ delta -= (snd_pcm_uframes_t)delta % runtime->period_size;
++ runtime->hw_ptr_interrupt += delta;
++ if (runtime->hw_ptr_interrupt >= runtime->boundary)
++ runtime->hw_ptr_interrupt -= runtime->boundary;
+ }
+ runtime->hw_ptr_base = hw_base;
+ runtime->status->hw_ptr = new_hw_ptr;
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -27,7 +27,6 @@
+ #include <linux/pm_qos_params.h>
+ #include <linux/uio.h>
+ #include <linux/dma-mapping.h>
+-#include <linux/math64.h>
+ #include <sound/core.h>
+ #include <sound/control.h>
+ #include <sound/info.h>
+@@ -370,38 +369,6 @@ static int period_to_usecs(struct snd_pc
+ return usecs;
+ }
+
+-static int calc_boundary(struct snd_pcm_runtime *runtime)
+-{
+- u_int64_t boundary;
+-
+- boundary = (u_int64_t)runtime->buffer_size *
+- (u_int64_t)runtime->period_size;
+-#if BITS_PER_LONG < 64
+- /* try to find lowest common multiple for buffer and period */
+- if (boundary > LONG_MAX - runtime->buffer_size) {
+- u_int32_t remainder = -1;
+- u_int32_t divident = runtime->buffer_size;
+- u_int32_t divisor = runtime->period_size;
+- while (remainder) {
+- remainder = divident % divisor;
+- if (remainder) {
+- divident = divisor;
+- divisor = remainder;
+- }
+- }
+- boundary = div_u64(boundary, divisor);
+- if (boundary > LONG_MAX - runtime->buffer_size)
+- return -ERANGE;
+- }
+-#endif
+- if (boundary == 0)
+- return -ERANGE;
+- runtime->boundary = boundary;
+- while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
+- runtime->boundary *= 2;
+- return 0;
+-}
+-
+ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+ {
+@@ -477,9 +444,9 @@ static int snd_pcm_hw_params(struct snd_
+ runtime->stop_threshold = runtime->buffer_size;
+ runtime->silence_threshold = 0;
+ runtime->silence_size = 0;
+- err = calc_boundary(runtime);
+- if (err < 0)
+- goto _error;
++ runtime->boundary = runtime->buffer_size;
++ while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
++ runtime->boundary *= 2;
+
+ snd_pcm_timer_resolution_change(substream);
+ runtime->status->state = SNDRV_PCM_STATE_SETUP;
--- /dev/null
+From e7971c80a8e0299f91272ad8e8ac4167623e1862 Mon Sep 17 00:00:00 2001
+From: Andreas Bombe <aeb@debian.org>
+Date: Mon, 17 May 2010 23:12:46 -0700
+Subject: ARCNET: Limit com20020 PCI ID matches for SOHARD cards
+
+From: Andreas Bombe <aeb@debian.org>
+
+commit e7971c80a8e0299f91272ad8e8ac4167623e1862 upstream.
+
+The SH SOHARD ARCNET cards are implemented using generic PLX Technology
+PCI<->IOBus bridges. Subvendor and subdevice IDs were not specified,
+causing the driver to attach to any such bridge and likely crash the
+system by attempting to initialize an unrelated device.
+
+Fix by specifying subvendor and subdevice according to the values found
+in the PCI-ID Repository at http://pci-ids.ucw.cz/ .
+
+Signed-off-by: Andreas Bombe <aeb@debian.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/arcnet/com20020-pci.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/arcnet/com20020-pci.c
++++ b/drivers/net/arcnet/com20020-pci.c
+@@ -164,8 +164,8 @@ static DEFINE_PCI_DEVICE_TABLE(com20020p
+ { 0x1571, 0xa204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+ { 0x1571, 0xa205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+ { 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+- { 0x10B5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+- { 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
++ { 0x10B5, 0x9030, 0x10B5, 0x2978, 0, 0, ARC_CAN_10MBIT },
++ { 0x10B5, 0x9050, 0x10B5, 0x2273, 0, 0, ARC_CAN_10MBIT },
+ { 0x14BA, 0x6000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+ { 0x10B5, 0x2200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+ {0,}
--- /dev/null
+From fa9dc265ace9774e62f0e31108e5f47911124bda Mon Sep 17 00:00:00 2001
+From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Date: Wed, 19 May 2010 09:37:41 +0900
+Subject: cpumask: fix compat getaffinity
+
+From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+
+commit fa9dc265ace9774e62f0e31108e5f47911124bda upstream.
+
+Commit a45185d2d "cpumask: convert kernel/compat.c" broke libnuma, which
+abuses sched_getaffinity to find out NR_CPUS in order to parse
+/sys/devices/system/node/node*/cpumap.
+
+On NUMA systems with less than 32 possibly CPUs, the current
+compat_sys_sched_getaffinity now returns '4' instead of the actual
+NR_CPUS/8, which makes libnuma bail out when parsing the cpumap.
+
+The libnuma call sched_getaffinity(0, bitmap, 4096) at first. It mean
+the libnuma expect the return value of sched_getaffinity() is either len
+argument or NR_CPUS. But it doesn't expect to return nr_cpu_ids.
+
+Strictly speaking, userland requirement are
+
+1) Glibc assume the return value mean the lengh of initialized
+ of mask argument. E.g. if sched_getaffinity(1024) return 128,
+ glibc make zero fill rest 896 byte.
+2) Libnuma assume the return value can be used to guess NR_CPUS
+ in kernel. It assume len-arg<NR_CPUS makes -EINVAL. But
+ it try len=4096 at first and 4096 is always bigger than
+ NR_CPUS. Then, if we remove strange min_length normalization,
+ we never hit -EINVAL case.
+
+sched_getaffinity() already solved this issue. This patch adapts
+compat_sys_sched_getaffinity() to match the non-compat case.
+
+Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
+Acked-by: Rusty Russell <rusty@rustcorp.com.au>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Reported-by: Ken Werner <ken.werner@web.de>
+Cc: Andi Kleen <andi@firstfloor.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/compat.c | 25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+--- a/kernel/compat.c
++++ b/kernel/compat.c
+@@ -495,29 +495,26 @@ asmlinkage long compat_sys_sched_getaffi
+ {
+ int ret;
+ cpumask_var_t mask;
+- unsigned long *k;
+- unsigned int min_length = cpumask_size();
+
+- if (nr_cpu_ids <= BITS_PER_COMPAT_LONG)
+- min_length = sizeof(compat_ulong_t);
+-
+- if (len < min_length)
++ if ((len * BITS_PER_BYTE) < nr_cpu_ids)
++ return -EINVAL;
++ if (len & (sizeof(compat_ulong_t)-1))
+ return -EINVAL;
+
+ if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+ return -ENOMEM;
+
+ ret = sched_getaffinity(pid, mask);
+- if (ret < 0)
+- goto out;
++ if (ret == 0) {
++ size_t retlen = min_t(size_t, len, cpumask_size());
+
+- k = cpumask_bits(mask);
+- ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8);
+- if (ret == 0)
+- ret = min_length;
+-
+-out:
++ if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
++ ret = -EFAULT;
++ else
++ ret = retlen;
++ }
+ free_cpumask_var(mask);
++
+ return ret;
+ }
+
--- /dev/null
+From fd6be105b883244127a734ac9f14ae94a022dcc0 Mon Sep 17 00:00:00 2001
+From: Tony Breeds <tony@bakeyournoodle.com>
+Date: Wed, 19 May 2010 15:46:36 +1000
+Subject: mutex: Fix optimistic spinning vs. BKL
+
+From: Tony Breeds <tony@bakeyournoodle.com>
+
+commit fd6be105b883244127a734ac9f14ae94a022dcc0 upstream.
+
+Currently, we can hit a nasty case with optimistic
+spinning on mutexes:
+
+ CPU A tries to take a mutex, while holding the BKL
+
+ CPU B tried to take the BLK while holding the mutex
+
+This looks like a AB-BA scenario but in practice, is
+allowed and happens due to the auto-release on
+schedule() nature of the BKL.
+
+In that case, the optimistic spinning code can get us
+into a situation where instead of going to sleep, A
+will spin waiting for B who is spinning waiting for
+A, and the only way out of that loop is the
+need_resched() test in mutex_spin_on_owner().
+
+This patch fixes it by completely disabling spinning
+if we own the BKL. This adds one more detail to the
+extensive list of reasons why it's a bad idea for
+kernel code to be holding the BKL.
+
+Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
+Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
+Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+LKML-Reference: <20100519054636.GC12389@ozlabs.org>
+[ added an unlikely() attribute to the branch ]
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/mutex.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/kernel/mutex.c
++++ b/kernel/mutex.c
+@@ -172,6 +172,13 @@ __mutex_lock_common(struct mutex *lock,
+ struct thread_info *owner;
+
+ /*
++ * If we own the BKL, then don't spin. The owner of
++ * the mutex might be waiting on us to release the BKL.
++ */
++ if (unlikely(current->lock_depth >= 0))
++ break;
++
++ /*
+ * If there's an owner, wait for it to either
+ * release the lock or go to sleep.
+ */
--- /dev/null
+From 91885258e8343bb65c08f668d7e6c16563eb4284 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Fri, 19 Mar 2010 08:06:28 -0400
+Subject: nfsd: don't break lease while servicing a COMMIT
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 91885258e8343bb65c08f668d7e6c16563eb4284 upstream.
+
+This is the second attempt to fix the problem whereby a COMMIT call
+causes a lease break and triggers a possible deadlock.
+
+The problem is that nfsd attempts to break a lease on a COMMIT call.
+This triggers a delegation recall if the lease is held for a delegation.
+If the client is the one holding the delegation and it's the same one on
+which it's issuing the COMMIT, then it can't return that delegation
+until the COMMIT is complete. But, nfsd won't complete the COMMIT until
+the delegation is returned. The client and server are essentially
+deadlocked until the state is marked bad (due to the client not
+responding on the callback channel).
+
+The first patch attempted to deal with this by eliminating the open of
+the file altogether and simply had nfsd_commit pass a NULL file pointer
+to the vfs_fsync_range. That would conflict with some work in progress
+by Christoph Hellwig to clean up the fsync interface, so this patch
+takes a different approach.
+
+This declares a new NFSD_MAY_NOT_BREAK_LEASE access flag that indicates
+to nfsd_open that it should not break any leases when opening the file,
+and has nfsd_commit set that flag on the nfsd_open call.
+
+For now, this patch leaves nfsd_commit opening the file with write
+access since I'm not clear on what sort of access would be more
+appropriate.
+
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nfsd/vfs.c | 8 +++++---
+ fs/nfsd/vfs.h | 1 +
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -724,7 +724,7 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ struct inode *inode;
+ int flags = O_RDONLY|O_LARGEFILE;
+ __be32 err;
+- int host_err;
++ int host_err = 0;
+
+ validate_process_creds();
+
+@@ -761,7 +761,8 @@ nfsd_open(struct svc_rqst *rqstp, struct
+ * Check to see if there are any leases on this file.
+ * This may block while leases are broken.
+ */
+- host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
++ if (!(access & NFSD_MAY_NOT_BREAK_LEASE))
++ host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
+ if (host_err == -EWOULDBLOCK)
+ host_err = -ETIMEDOUT;
+ if (host_err) /* NOMEM or WOULDBLOCK */
+@@ -1169,7 +1170,8 @@ nfsd_commit(struct svc_rqst *rqstp, stru
+ goto out;
+ }
+
+- err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file);
++ err = nfsd_open(rqstp, fhp, S_IFREG,
++ NFSD_MAY_WRITE|NFSD_MAY_NOT_BREAK_LEASE, &file);
+ if (err)
+ goto out;
+ if (EX_ISSYNC(fhp->fh_export)) {
+--- a/fs/nfsd/vfs.h
++++ b/fs/nfsd/vfs.h
+@@ -20,6 +20,7 @@
+ #define NFSD_MAY_OWNER_OVERRIDE 64
+ #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/
+ #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256
++#define NFSD_MAY_NOT_BREAK_LEASE 512
+
+ #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
+ #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
--- /dev/null
+From 15ddb4aec54422ead137b03ea4e9b3f5db3f7cc2 Mon Sep 17 00:00:00 2001
+From: Pavel Emelyanov <xemul@openvz.org>
+Date: Fri, 14 May 2010 15:33:36 +0400
+Subject: NFSD: don't report compiled-out versions as present
+
+From: Pavel Emelyanov <xemul@openvz.org>
+
+commit 15ddb4aec54422ead137b03ea4e9b3f5db3f7cc2 upstream.
+
+The /proc/fs/nfsd/versions file calls nfsd_vers() to check whether
+the particular nfsd version is present/available. The problem is
+that once I turn off e.g. NFSD-V4 this call returns -1 which is
+true from the callers POV which is wrong.
+
+The proposal is to report false in that case.
+
+The bug has existed since 6658d3a7bbfd1768 "[PATCH] knfsd: remove
+nfsd_versbits as intermediate storage for desired versions".
+
+Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
+Acked-by: NeilBrown <neilb@suse.de>
+Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nfsd/nfssvc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -120,7 +120,7 @@ u32 nfsd_supported_minorversion;
+ int nfsd_vers(int vers, enum vers_op change)
+ {
+ if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
+- return -1;
++ return 0;
+ switch(change) {
+ case NFSD_SET:
+ nfsd_versions[vers] = nfsd_version[vers];
--- /dev/null
+From d989ff7cf8d14f1b523f63ba0bf2ec1a9b7c25bc Mon Sep 17 00:00:00 2001
+From: John W. Linville <linville@tuxdriver.com>
+Date: Wed, 28 Apr 2010 19:14:42 -0400
+Subject: rtl8180: fix tx status reporting
+
+From: John W. Linville <linville@tuxdriver.com>
+
+commit d989ff7cf8d14f1b523f63ba0bf2ec1a9b7c25bc upstream.
+
+When reporting Tx status, indicate that only one rate was used.
+Otherwise, the rate is frozen at rate index 0 (i.e. 1Mb/s).
+
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/rtl818x/rtl8180_dev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
++++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
+@@ -188,6 +188,7 @@ static void rtl8180_handle_tx(struct iee
+ info->flags |= IEEE80211_TX_STAT_ACK;
+
+ info->status.rates[0].count = (flags & 0xFF) + 1;
++ info->status.rates[1].idx = -1;
+
+ ieee80211_tx_status_irqsafe(dev, skb);
+ if (ring->entries - skb_queue_len(&ring->queue) == 2)
--- /dev/null
+From 95cc2c70c139936a2142bcd583da8af6f9d88efb Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Fri, 14 May 2010 11:48:50 +0200
+Subject: sata_nv: use ata_pci_sff_activate_host() instead of ata_host_activate()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 95cc2c70c139936a2142bcd583da8af6f9d88efb upstream.
+
+sata_nv was incorrectly using ata_host_activate() instead of
+ata_pci_sff_activate_host() leading to IRQ assignment failure in
+legacy mode. Fix it.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Cc: Robert Hancock <hancockr@shaw.ca>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/sata_nv.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/ata/sata_nv.c
++++ b/drivers/ata/sata_nv.c
+@@ -2479,8 +2479,7 @@ static int nv_init_one(struct pci_dev *p
+ }
+
+ pci_set_master(pdev);
+- return ata_host_activate(host, pdev->irq, ipriv->irq_handler,
+- IRQF_SHARED, ipriv->sht);
++ return ata_pci_sff_activate_host(host, ipriv->irq_handler, ipriv->sht);
+ }
+
+ #ifdef CONFIG_PM
posix_timer-fix-error-path-in-timer_create.patch
libata-disable-atapi-an-by-default.patch
libata-don-t-flush-dcache-on-slab-pages.patch
+cpumask-fix-compat-getaffinity.patch
+nfsd-don-t-report-compiled-out-versions-as-present.patch
+nfsd-don-t-break-lease-while-servicing-a-commit.patch
+sata_nv-use-ata_pci_sff_activate_host-instead-of-ata_host_activate.patch
+arcnet-limit-com20020-pci-id-matches-for-sohard-cards.patch
+rtl8180-fix-tx-status-reporting.patch
+staging-vt6655-fix-kernel-bug-on-driver-wpa-initialization.patch
+staging-rt2870-add-device-id-of-melco.-inc.-wli-uc-g301n.patch
+staging-batman-adv-don-t-have-interrupts-disabled-while-sending.patch
+staging-batman-adv-fix-vis-output-bug-for-secondary-interfaces.patch
+staging-batman-adv-fixing-wrap-around-bug-in-vis.patch
+mutex-fix-optimistic-spinning-vs.-bkl.patch
+alsa-pcm-fix-delta-calculation-at-boundary-wraparound.patch
+alsa-pcm-fix-the-fix-of-the-runtime-boundary-calculation.patch
+alsa-hda-fix-model-quirk-for-dell-m1730.patch
+alsa-hda-use-lpib-for-toshiba-a100-259.patch
+alsa-hda-use-lpib-for-acer-aspire-5110.patch
+alsa-hda-use-lpib-for-sony-vpcs11v9e.patch
+alsa-hda-use-lpib-for-a-shuttle-device.patch
+acpi-video-fix-acpi_backlight-video.patch
--- /dev/null
+From 107c32fe68f0b64acb7edd31d44d79b87c7fa8b4 Mon Sep 17 00:00:00 2001
+From: Andrew Lunn <andrew@lunn.ch>
+Date: Mon, 22 Mar 2010 22:46:13 +0100
+Subject: Staging: batman-adv: don't have interrupts disabled while sending.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andrew Lunn <andrew@lunn.ch>
+
+commit 107c32fe68f0b64acb7edd31d44d79b87c7fa8b4 upstream.
+
+send_vis_packets() would disable interrupts before calling
+dev_queue_xmit() which resulting in a backtrace in local_bh_enable().
+Fix this by using kref on the vis_info object so that we can call
+send_vis_packets() without holding vis_hash_lock. vis_hash_lock also
+used to protect recv_list, so we now need a new lock to protect that
+instead of vis_hash_lock.
+
+Also a few checkpatch cleanups.
+
+Reported-by: Linus Lüssing <linus.luessing@web.de>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
+Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/batman-adv/vis.c | 198 +++++++++++++++++++++++++++------------
+ drivers/staging/batman-adv/vis.h | 1
+ 2 files changed, 139 insertions(+), 60 deletions(-)
+
+--- a/drivers/staging/batman-adv/vis.c
++++ b/drivers/staging/batman-adv/vis.c
+@@ -29,22 +29,26 @@
+
+ struct hashtable_t *vis_hash;
+ DEFINE_SPINLOCK(vis_hash_lock);
++static DEFINE_SPINLOCK(recv_list_lock);
+ static struct vis_info *my_vis_info;
+ static struct list_head send_list; /* always locked with vis_hash_lock */
+
+ static void start_vis_timer(void);
+
+ /* free the info */
+-static void free_info(void *data)
++static void free_info(struct kref *ref)
+ {
+- struct vis_info *info = data;
++ struct vis_info *info = container_of(ref, struct vis_info, refcount);
+ struct recvlist_node *entry, *tmp;
++ unsigned long flags;
+
+ list_del_init(&info->send_list);
++ spin_lock_irqsave(&recv_list_lock, flags);
+ list_for_each_entry_safe(entry, tmp, &info->recv_list, list) {
+ list_del(&entry->list);
+ kfree(entry);
+ }
++ spin_unlock_irqrestore(&recv_list_lock, flags);
+ kfree(info);
+ }
+
+@@ -142,36 +146,65 @@ void proc_vis_read_entry(struct seq_file
+ }
+ }
+
++/* add the info packet to the send list, if it was not
++ * already linked in. */
++static void send_list_add(struct vis_info *info)
++{
++ if (list_empty(&info->send_list)) {
++ kref_get(&info->refcount);
++ list_add_tail(&info->send_list, &send_list);
++ }
++}
++
++/* delete the info packet from the send list, if it was
++ * linked in. */
++static void send_list_del(struct vis_info *info)
++{
++ if (!list_empty(&info->send_list)) {
++ list_del_init(&info->send_list);
++ kref_put(&info->refcount, free_info);
++ }
++}
++
+ /* tries to add one entry to the receive list. */
+ static void recv_list_add(struct list_head *recv_list, char *mac)
+ {
+ struct recvlist_node *entry;
++ unsigned long flags;
++
+ entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC);
+ if (!entry)
+ return;
+
+ memcpy(entry->mac, mac, ETH_ALEN);
++ spin_lock_irqsave(&recv_list_lock, flags);
+ list_add_tail(&entry->list, recv_list);
++ spin_unlock_irqrestore(&recv_list_lock, flags);
+ }
+
+ /* returns 1 if this mac is in the recv_list */
+ static int recv_list_is_in(struct list_head *recv_list, char *mac)
+ {
+ struct recvlist_node *entry;
++ unsigned long flags;
+
++ spin_lock_irqsave(&recv_list_lock, flags);
+ list_for_each_entry(entry, recv_list, list) {
+- if (memcmp(entry->mac, mac, ETH_ALEN) == 0)
++ if (memcmp(entry->mac, mac, ETH_ALEN) == 0) {
++ spin_unlock_irqrestore(&recv_list_lock, flags);
+ return 1;
++ }
+ }
+-
++ spin_unlock_irqrestore(&recv_list_lock, flags);
+ return 0;
+ }
+
+ /* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old,
+- * broken.. ). vis hash must be locked outside. is_new is set when the packet
++ * broken.. ). vis hash must be locked outside. is_new is set when the packet
+ * is newer than old entries in the hash. */
+ static struct vis_info *add_packet(struct vis_packet *vis_packet,
+- int vis_info_len, int *is_new)
++ int vis_info_len, int *is_new,
++ int make_broadcast)
+ {
+ struct vis_info *info, *old_info;
+ struct vis_info search_elem;
+@@ -198,13 +231,15 @@ static struct vis_info *add_packet(struc
+ }
+ /* remove old entry */
+ hash_remove(vis_hash, old_info);
+- free_info(old_info);
++ send_list_del(old_info);
++ kref_put(&old_info->refcount, free_info);
+ }
+
+ info = kmalloc(sizeof(struct vis_info) + vis_info_len, GFP_ATOMIC);
+ if (info == NULL)
+ return NULL;
+
++ kref_init(&info->refcount);
+ INIT_LIST_HEAD(&info->send_list);
+ INIT_LIST_HEAD(&info->recv_list);
+ info->first_seen = jiffies;
+@@ -214,16 +249,21 @@ static struct vis_info *add_packet(struc
+ /* initialize and add new packet. */
+ *is_new = 1;
+
++ /* Make it a broadcast packet, if required */
++ if (make_broadcast)
++ memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
++
+ /* repair if entries is longer than packet. */
+ if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
+- info->packet.entries = vis_info_len / sizeof(struct vis_info_entry);
++ info->packet.entries = vis_info_len /
++ sizeof(struct vis_info_entry);
+
+ recv_list_add(&info->recv_list, info->packet.sender_orig);
+
+ /* try to add it */
+ if (hash_add(vis_hash, info) < 0) {
+ /* did not work (for some reason) */
+- free_info(info);
++ kref_put(&old_info->refcount, free_info);
+ info = NULL;
+ }
+
+@@ -234,22 +274,21 @@ static struct vis_info *add_packet(struc
+ void receive_server_sync_packet(struct vis_packet *vis_packet, int vis_info_len)
+ {
+ struct vis_info *info;
+- int is_new;
++ int is_new, make_broadcast;
+ unsigned long flags;
+ int vis_server = atomic_read(&vis_mode);
+
++ make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC);
++
+ spin_lock_irqsave(&vis_hash_lock, flags);
+- info = add_packet(vis_packet, vis_info_len, &is_new);
++ info = add_packet(vis_packet, vis_info_len, &is_new, make_broadcast);
+ if (info == NULL)
+ goto end;
+
+ /* only if we are server ourselves and packet is newer than the one in
+ * hash.*/
+- if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) {
+- memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+- if (list_empty(&info->send_list))
+- list_add_tail(&info->send_list, &send_list);
+- }
++ if (vis_server == VIS_TYPE_SERVER_SYNC && is_new)
++ send_list_add(info);
+ end:
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+ }
+@@ -262,31 +301,32 @@ void receive_client_update_packet(struct
+ int is_new;
+ unsigned long flags;
+ int vis_server = atomic_read(&vis_mode);
++ int are_target = 0;
+
+ /* clients shall not broadcast. */
+ if (is_bcast(vis_packet->target_orig))
+ return;
+
++ /* Are we the target for this VIS packet? */
++ if (vis_server == VIS_TYPE_SERVER_SYNC &&
++ is_my_mac(vis_packet->target_orig))
++ are_target = 1;
++
+ spin_lock_irqsave(&vis_hash_lock, flags);
+- info = add_packet(vis_packet, vis_info_len, &is_new);
++ info = add_packet(vis_packet, vis_info_len, &is_new, are_target);
+ if (info == NULL)
+ goto end;
+ /* note that outdated packets will be dropped at this point. */
+
+
+ /* send only if we're the target server or ... */
+- if (vis_server == VIS_TYPE_SERVER_SYNC &&
+- is_my_mac(info->packet.target_orig) &&
+- is_new) {
++ if (are_target && is_new) {
+ info->packet.vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */
+- memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+- if (list_empty(&info->send_list))
+- list_add_tail(&info->send_list, &send_list);
++ send_list_add(info);
+
+ /* ... we're not the recipient (and thus need to forward). */
+ } else if (!is_my_mac(info->packet.target_orig)) {
+- if (list_empty(&info->send_list))
+- list_add_tail(&info->send_list, &send_list);
++ send_list_add(info);
+ }
+ end:
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+@@ -361,14 +401,17 @@ static int generate_vis_packet(void)
+ while (hash_iterate(orig_hash, &hashit_global)) {
+ orig_node = hashit_global.bucket->data;
+ if (orig_node->router != NULL
+- && compare_orig(orig_node->router->addr, orig_node->orig)
++ && compare_orig(orig_node->router->addr,
++ orig_node->orig)
+ && orig_node->batman_if
+ && (orig_node->batman_if->if_active == IF_ACTIVE)
+ && orig_node->router->tq_avg > 0) {
+
+ /* fill one entry into buffer. */
+ entry = &entry_array[info->packet.entries];
+- memcpy(entry->src, orig_node->batman_if->net_dev->dev_addr, ETH_ALEN);
++ memcpy(entry->src,
++ orig_node->batman_if->net_dev->dev_addr,
++ ETH_ALEN);
+ memcpy(entry->dest, orig_node->orig, ETH_ALEN);
+ entry->quality = orig_node->router->tq_avg;
+ info->packet.entries++;
+@@ -400,6 +443,8 @@ static int generate_vis_packet(void)
+ return 0;
+ }
+
++/* free old vis packets. Must be called with this vis_hash_lock
++ * held */
+ static void purge_vis_packets(void)
+ {
+ HASHIT(hashit);
+@@ -412,7 +457,8 @@ static void purge_vis_packets(void)
+ if (time_after(jiffies,
+ info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
+ hash_remove_bucket(vis_hash, &hashit);
+- free_info(info);
++ send_list_del(info);
++ kref_put(&info->refcount, free_info);
+ }
+ }
+ }
+@@ -422,6 +468,8 @@ static void broadcast_vis_packet(struct
+ HASHIT(hashit);
+ struct orig_node *orig_node;
+ unsigned long flags;
++ struct batman_if *batman_if;
++ uint8_t dstaddr[ETH_ALEN];
+
+ spin_lock_irqsave(&orig_hash_lock, flags);
+
+@@ -430,45 +478,56 @@ static void broadcast_vis_packet(struct
+ orig_node = hashit.bucket->data;
+
+ /* if it's a vis server and reachable, send it. */
+- if (orig_node &&
+- (orig_node->flags & VIS_SERVER) &&
+- orig_node->batman_if &&
+- orig_node->router) {
++ if ((!orig_node) || (!orig_node->batman_if) ||
++ (!orig_node->router))
++ continue;
++ if (!(orig_node->flags & VIS_SERVER))
++ continue;
++ /* don't send it if we already received the packet from
++ * this node. */
++ if (recv_list_is_in(&info->recv_list, orig_node->orig))
++ continue;
++
++ memcpy(info->packet.target_orig, orig_node->orig, ETH_ALEN);
++ batman_if = orig_node->batman_if;
++ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
++ spin_unlock_irqrestore(&orig_hash_lock, flags);
++
++ send_raw_packet((unsigned char *)&info->packet,
++ packet_length, batman_if, dstaddr);
++
++ spin_lock_irqsave(&orig_hash_lock, flags);
+
+- /* don't send it if we already received the packet from
+- * this node. */
+- if (recv_list_is_in(&info->recv_list, orig_node->orig))
+- continue;
+-
+- memcpy(info->packet.target_orig,
+- orig_node->orig, ETH_ALEN);
+-
+- send_raw_packet((unsigned char *) &info->packet,
+- packet_length,
+- orig_node->batman_if,
+- orig_node->router->addr);
+- }
+ }
+- memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
++ memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
+ }
+
+ static void unicast_vis_packet(struct vis_info *info, int packet_length)
+ {
+ struct orig_node *orig_node;
+ unsigned long flags;
++ struct batman_if *batman_if;
++ uint8_t dstaddr[ETH_ALEN];
+
+ spin_lock_irqsave(&orig_hash_lock, flags);
+ orig_node = ((struct orig_node *)
+ hash_find(orig_hash, info->packet.target_orig));
+
+- if ((orig_node != NULL) &&
+- (orig_node->batman_if != NULL) &&
+- (orig_node->router != NULL)) {
+- send_raw_packet((unsigned char *) &info->packet, packet_length,
+- orig_node->batman_if,
+- orig_node->router->addr);
+- }
++ if ((!orig_node) || (!orig_node->batman_if) || (!orig_node->router))
++ goto out;
++
++ /* don't lock while sending the packets ... we therefore
++ * copy the required data before sending */
++ batman_if = orig_node->batman_if;
++ memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
++ spin_unlock_irqrestore(&orig_hash_lock, flags);
++
++ send_raw_packet((unsigned char *)&info->packet,
++ packet_length, batman_if, dstaddr);
++ return;
++
++out:
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+ }
+
+@@ -502,15 +561,24 @@ static void send_vis_packets(struct work
+ unsigned long flags;
+
+ spin_lock_irqsave(&vis_hash_lock, flags);
++
+ purge_vis_packets();
+
+- if (generate_vis_packet() == 0)
++ if (generate_vis_packet() == 0) {
+ /* schedule if generation was successful */
+- list_add_tail(&my_vis_info->send_list, &send_list);
++ send_list_add(my_vis_info);
++ }
+
+ list_for_each_entry_safe(info, temp, &send_list, send_list) {
+- list_del_init(&info->send_list);
++
++ kref_get(&info->refcount);
++ spin_unlock_irqrestore(&vis_hash_lock, flags);
++
+ send_vis_packet(info);
++
++ spin_lock_irqsave(&vis_hash_lock, flags);
++ send_list_del(info);
++ kref_put(&info->refcount, free_info);
+ }
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+ start_vis_timer();
+@@ -543,6 +611,7 @@ int vis_init(void)
+ my_vis_info->first_seen = jiffies - atomic_read(&vis_interval);
+ INIT_LIST_HEAD(&my_vis_info->recv_list);
+ INIT_LIST_HEAD(&my_vis_info->send_list);
++ kref_init(&my_vis_info->refcount);
+ my_vis_info->packet.version = COMPAT_VERSION;
+ my_vis_info->packet.packet_type = BAT_VIS;
+ my_vis_info->packet.ttl = TTL;
+@@ -556,9 +625,9 @@ int vis_init(void)
+
+ if (hash_add(vis_hash, my_vis_info) < 0) {
+ printk(KERN_ERR
+- "batman-adv:Can't add own vis packet into hash\n");
+- free_info(my_vis_info); /* not in hash, need to remove it
+- * manually. */
++ "batman-adv:Can't add own vis packet into hash\n");
++ /* not in hash, need to remove it manually. */
++ kref_put(&my_vis_info->refcount, free_info);
+ goto err;
+ }
+
+@@ -572,6 +641,15 @@ err:
+ return 0;
+ }
+
++/* Decrease the reference count on a hash item info */
++static void free_info_ref(void *data)
++{
++ struct vis_info *info = data;
++
++ send_list_del(info);
++ kref_put(&info->refcount, free_info);
++}
++
+ /* shutdown vis-server */
+ void vis_quit(void)
+ {
+@@ -583,7 +661,7 @@ void vis_quit(void)
+
+ spin_lock_irqsave(&vis_hash_lock, flags);
+ /* properly remove, kill timers ... */
+- hash_delete(vis_hash, free_info);
++ hash_delete(vis_hash, free_info_ref);
+ vis_hash = NULL;
+ my_vis_info = NULL;
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+--- a/drivers/staging/batman-adv/vis.h
++++ b/drivers/staging/batman-adv/vis.h
+@@ -29,6 +29,7 @@ struct vis_info {
+ /* list of server-neighbors we received a vis-packet
+ * from. we should not reply to them. */
+ struct list_head send_list;
++ struct kref refcount;
+ /* this packet might be part of the vis send queue. */
+ struct vis_packet packet;
+ /* vis_info may follow here*/
--- /dev/null
+From f6497e38fda6970819daacb67725d67474079381 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
+Date: Mon, 22 Mar 2010 22:46:14 +0100
+Subject: Staging: batman-adv: Fix VIS output bug for secondary interfaces
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
+
+commit f6497e38fda6970819daacb67725d67474079381 upstream.
+
+TQ and HNA records for originators on secondary interfaces were
+wrongly being included on the primary interface. Ensure we output a
+line for each source interface on every node, so we correctly separate
+primary and secondary interface records.
+
+Signed-off-by: Linus Lüssing <linus.luessing@web.de>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/batman-adv/proc.c | 51 ++++++++++++++++++++++++++------------
+ drivers/staging/batman-adv/vis.c | 25 ++++++------------
+ drivers/staging/batman-adv/vis.h | 7 +++--
+ 3 files changed, 49 insertions(+), 34 deletions(-)
+
+--- a/drivers/staging/batman-adv/proc.c
++++ b/drivers/staging/batman-adv/proc.c
+@@ -41,7 +41,7 @@ static int proc_interfaces_read(struct s
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(batman_if, &if_list, list) {
+- seq_printf(seq, "[%8s] %s %s \n",
++ seq_printf(seq, "[%8s] %s %s\n",
+ (batman_if->if_active == IF_ACTIVE ?
+ "active" : "inactive"),
+ batman_if->dev,
+@@ -188,18 +188,18 @@ static int proc_originators_read(struct
+ rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
++ seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
+ goto end;
+ }
+
+ if (((struct batman_if *)if_list.next)->if_active != IF_ACTIVE) {
+ rcu_read_unlock();
+- seq_printf(seq, "BATMAN disabled - primary interface not active \n");
++ seq_printf(seq, "BATMAN disabled - primary interface not active\n");
+ goto end;
+ }
+
+ seq_printf(seq,
+- " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s] \n",
++ " %-14s (%s/%i) %17s [%10s]: %20s ... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s]\n",
+ "Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
+ "Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
+ ((struct batman_if *)if_list.next)->dev,
+@@ -240,7 +240,7 @@ static int proc_originators_read(struct
+ spin_unlock_irqrestore(&orig_hash_lock, flags);
+
+ if (batman_count == 0)
+- seq_printf(seq, "No batman nodes in range ... \n");
++ seq_printf(seq, "No batman nodes in range ...\n");
+
+ end:
+ return 0;
+@@ -262,7 +262,7 @@ static int proc_transt_local_read(struct
+ rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
++ seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
+ goto end;
+ }
+
+@@ -294,7 +294,7 @@ static int proc_transt_global_read(struc
+ rcu_read_lock();
+ if (list_empty(&if_list)) {
+ rcu_read_unlock();
+- seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it \n");
++ seq_printf(seq, "BATMAN disabled - please specify interfaces to enable it\n");
+ goto end;
+ }
+ rcu_read_unlock();
+@@ -350,9 +350,9 @@ static int proc_vis_srv_read(struct seq_
+ {
+ int vis_server = atomic_read(&vis_mode);
+
+- seq_printf(seq, "[%c] client mode (server disabled) \n",
++ seq_printf(seq, "[%c] client mode (server disabled)\n",
+ (vis_server == VIS_TYPE_CLIENT_UPDATE) ? 'x' : ' ');
+- seq_printf(seq, "[%c] server mode (server enabled) \n",
++ seq_printf(seq, "[%c] server mode (server enabled)\n",
+ (vis_server == VIS_TYPE_SERVER_SYNC) ? 'x' : ' ');
+
+ return 0;
+@@ -369,6 +369,8 @@ static int proc_vis_data_read(struct seq
+ struct vis_info *info;
+ struct vis_info_entry *entries;
+ HLIST_HEAD(vis_if_list);
++ struct if_list_entry *entry;
++ struct hlist_node *pos, *n;
+ int i;
+ char tmp_addr_str[ETH_STR_LEN];
+ unsigned long flags;
+@@ -387,17 +389,34 @@ static int proc_vis_data_read(struct seq
+ info = hashit.bucket->data;
+ entries = (struct vis_info_entry *)
+ ((char *)info + sizeof(struct vis_info));
+- addr_to_string(tmp_addr_str, info->packet.vis_orig);
+- seq_printf(seq, "%s,", tmp_addr_str);
+
+ for (i = 0; i < info->packet.entries; i++) {
+- proc_vis_read_entry(seq, &entries[i], &vis_if_list,
+- info->packet.vis_orig);
++ if (entries[i].quality == 0)
++ continue;
++ proc_vis_insert_interface(entries[i].src, &vis_if_list,
++ compare_orig(entries[i].src,
++ info->packet.vis_orig));
+ }
+
+- /* add primary/secondary records */
+- proc_vis_read_prim_sec(seq, &vis_if_list);
+- seq_printf(seq, "\n");
++ hlist_for_each_entry(entry, pos, &vis_if_list, list) {
++ addr_to_string(tmp_addr_str, entry->addr);
++ seq_printf(seq, "%s,", tmp_addr_str);
++
++ for (i = 0; i < info->packet.entries; i++)
++ proc_vis_read_entry(seq, &entries[i],
++ entry->addr, entry->primary);
++
++ /* add primary/secondary records */
++ if (compare_orig(entry->addr, info->packet.vis_orig))
++ proc_vis_read_prim_sec(seq, &vis_if_list);
++
++ seq_printf(seq, "\n");
++ }
++
++ hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
++ hlist_del(&entry->list);
++ kfree(entry);
++ }
+ }
+ spin_unlock_irqrestore(&vis_hash_lock, flags);
+
+--- a/drivers/staging/batman-adv/vis.c
++++ b/drivers/staging/batman-adv/vis.c
+@@ -86,7 +86,7 @@ static int vis_info_choose(void *data, i
+
+ /* insert interface to the list of interfaces of one originator, if it
+ * does not already exist in the list */
+-static void proc_vis_insert_interface(const uint8_t *interface,
++void proc_vis_insert_interface(const uint8_t *interface,
+ struct hlist_head *if_list,
+ bool primary)
+ {
+@@ -111,39 +111,32 @@ void proc_vis_read_prim_sec(struct seq_f
+ struct hlist_head *if_list)
+ {
+ struct if_list_entry *entry;
+- struct hlist_node *pos, *n;
++ struct hlist_node *pos;
+ char tmp_addr_str[ETH_STR_LEN];
+
+- hlist_for_each_entry_safe(entry, pos, n, if_list, list) {
+- if (entry->primary) {
++ hlist_for_each_entry(entry, pos, if_list, list) {
++ if (entry->primary)
+ seq_printf(seq, "PRIMARY, ");
+- } else {
++ else {
+ addr_to_string(tmp_addr_str, entry->addr);
+ seq_printf(seq, "SEC %s, ", tmp_addr_str);
+ }
+-
+- hlist_del(&entry->list);
+- kfree(entry);
+ }
+ }
+
+ /* read an entry */
+ void proc_vis_read_entry(struct seq_file *seq,
+ struct vis_info_entry *entry,
+- struct hlist_head *if_list,
+- uint8_t *vis_orig)
++ uint8_t *src,
++ bool primary)
+ {
+ char to[40];
+
+ addr_to_string(to, entry->dest);
+- if (entry->quality == 0) {
+- proc_vis_insert_interface(vis_orig, if_list, true);
++ if (primary && entry->quality == 0)
+ seq_printf(seq, "HNA %s, ", to);
+- } else {
+- proc_vis_insert_interface(entry->src, if_list,
+- compare_orig(entry->src, vis_orig));
++ else if (compare_orig(entry->src, src))
+ seq_printf(seq, "TQ %s %d, ", to, entry->quality);
+- }
+ }
+
+ /* add the info packet to the send list, if it was not
+--- a/drivers/staging/batman-adv/vis.h
++++ b/drivers/staging/batman-adv/vis.h
+@@ -49,10 +49,13 @@ struct recvlist_node {
+ extern struct hashtable_t *vis_hash;
+ extern spinlock_t vis_hash_lock;
+
++void proc_vis_insert_interface(const uint8_t *interface,
++ struct hlist_head *if_list,
++ bool primary);
+ void proc_vis_read_entry(struct seq_file *seq,
+ struct vis_info_entry *entry,
+- struct hlist_head *if_list,
+- uint8_t *vis_orig);
++ uint8_t *src,
++ bool primary);
+ void proc_vis_read_prim_sec(struct seq_file *seq,
+ struct hlist_head *if_list);
+ void receive_server_sync_packet(struct vis_packet *vis_packet,
--- /dev/null
+From ea4ceb18b525fd7016c10995c0f1313a729c7e2b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
+Date: Mon, 22 Mar 2010 22:46:15 +0100
+Subject: Staging: batman-adv: Fixing wrap-around bug in vis
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Linus=20L=C3=BCssing?= <linus.luessing@web.de>
+
+commit ea4ceb18b525fd7016c10995c0f1313a729c7e2b upstream.
+
+When the seqno for a vis packet had a wrap around from i.e. 255 to 0,
+add_packet() would falsely claim the older packet with the seqno 255 as
+newer as the one with the seqno of 0 and would therefore ignore the new
+packet. This happens with all following vis packets until the old vis
+packet expires after 180 seconds timeout. This patch fixes this issue
+and gets rid of these highly undesired 3min. breaks for the vis-server.
+
+Signed-off-by: Linus Lüssing <linus.luessing@web.de>
+Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/batman-adv/vis.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/batman-adv/vis.c
++++ b/drivers/staging/batman-adv/vis.c
+@@ -27,6 +27,22 @@
+ #include "hard-interface.h"
+ #include "hash.h"
+
++/* Returns the smallest signed integer in two's complement with the sizeof x */
++#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
++
++/* Checks if a sequence number x is a predecessor/successor of y.
++ they handle overflows/underflows and can correctly check for a
++ predecessor/successor unless the variable sequence number has grown by
++ more then 2**(bitwidth(x)-1)-1.
++ This means that for a uint8_t with the maximum value 255, it would think:
++ * when adding nothing - it is neither a predecessor nor a successor
++ * before adding more than 127 to the starting value - it is a predecessor,
++ * when adding 128 - it is neither a predecessor nor a successor,
++ * after adding more than 127 to the starting value - it is a successor */
++#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \
++ _dummy > smallest_signed_int(_dummy); })
++#define seq_after(x, y) seq_before(y, x)
++
+ struct hashtable_t *vis_hash;
+ DEFINE_SPINLOCK(vis_hash_lock);
+ static DEFINE_SPINLOCK(recv_list_lock);
+@@ -212,7 +228,7 @@ static struct vis_info *add_packet(struc
+ old_info = hash_find(vis_hash, &search_elem);
+
+ if (old_info != NULL) {
+- if (vis_packet->seqno - old_info->packet.seqno <= 0) {
++ if (!seq_after(vis_packet->seqno, old_info->packet.seqno)) {
+ if (old_info->packet.seqno == vis_packet->seqno) {
+ recv_list_add(&old_info->recv_list,
+ vis_packet->sender_orig);
--- /dev/null
+From de37cd49b5a54facef174cf34496919857436e8f Mon Sep 17 00:00:00 2001
+From: Nobuhiro KUSUNO <n-kusuno@fc4.so-net.ne.jp>
+Date: Thu, 6 May 2010 05:23:28 +0900
+Subject: Staging: rt2870: add device ID of MelCo.,Inc. WLI-UC-G301N
+
+From: Nobuhiro KUSUNO <n-kusuno@fc4.so-net.ne.jp>
+
+commit de37cd49b5a54facef174cf34496919857436e8f upstream.
+
+My wireless LAN module 'MelCo.,Inc. WLI-UC-G301N' works fine,
+if the following line is added into 2870_main_dev.c.
+
+Signed-off-by: Nobhiro KUSUNO <n-kusuno@fc4.so-net.ne.jp>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/rt2860/usb_main_dev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/rt2860/usb_main_dev.c
++++ b/drivers/staging/rt2860/usb_main_dev.c
+@@ -98,6 +98,7 @@ struct usb_device_id rtusb_usb_id[] = {
+ {USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */
+ {USB_DEVICE(0x7392, 0x7718)},
+ {USB_DEVICE(0x7392, 0x7717)},
++ {USB_DEVICE(0x0411, 0x016f)}, /* MelCo.,Inc. WLI-UC-G301N */
+ {USB_DEVICE(0x1737, 0x0070)}, /* Linksys WUSB100 */
+ {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */
+ {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */
--- /dev/null
+From f65515275ea3e45fdcd0fb78455f542d6fdca086 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Sun, 9 May 2010 22:10:02 -0500
+Subject: staging: vt6655: Fix kernel BUG on driver wpa initialization
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit f65515275ea3e45fdcd0fb78455f542d6fdca086 upstream.
+
+In http://bugzilla.novell.com/show_bug.cgi?id=597299, the vt6655 driver
+generates a kernel BUG on a NULL pointer dereference at NULL. This problem
+has been traced to a failure in the wpa_set_wpadev() routine. As the vt6656
+driver does not call this routine, the vt6655 code is similarly set to skip
+the call.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Tested-by: Richard Meek <osl2008@googlemail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/vt6655/device_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/staging/vt6655/device_main.c
++++ b/drivers/staging/vt6655/device_main.c
+@@ -1090,11 +1090,13 @@ device_found1(struct pci_dev *pcid, cons
+ }
+ //2008-07-21-01<Add>by MikeLiu
+ //register wpadev
++#if 0
+ if(wpa_set_wpadev(pDevice, 1)!=0) {
+ printk("Fail to Register WPADEV?\n");
+ unregister_netdev(pDevice->dev);
+ free_netdev(dev);
+ }
++#endif
+ device_print_info(pDevice);
+ pci_set_drvdata(pcid, pDevice);
+ return 0;