--- /dev/null
+From 88d686027bb43f585914c77dd363f6e817b42c2a Mon Sep 17 00:00:00 2001
+From: Charles Chin <Charles.Chin@idt.com>
+Date: Thu, 1 Dec 2011 11:21:00 +0100
+Subject: ALSA: hda - Fix S3/S4 problem on machines with VREF-pin mute-LED
+
+From: Charles Chin <Charles.Chin@idt.com>
+
+commit 88d686027bb43f585914c77dd363f6e817b42c2a upstream.
+
+The verb command in stac92xx_post_suspend caused the audio to stop
+working after resuming from S3 mode on HP laptops with the VREF-pin
+mute-LED control. Removing relevant post_suspend registering.
+
+Although removing D3 on AFG is no optimal solution, the impact should
+be small in comparison with the broken S3/S4.
+
+Signed-off-by: Charles Chin <Charles.Chin@idt.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/patch_sigmatel.c | 18 ------------------
+ 1 file changed, 18 deletions(-)
+
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -5035,20 +5035,6 @@ static int stac92xx_pre_resume(struct hd
+ return 0;
+ }
+
+-static int stac92xx_post_suspend(struct hda_codec *codec)
+-{
+- struct sigmatel_spec *spec = codec->spec;
+- if (spec->gpio_led > 8) {
+- /* with vref-out pin used for mute led control
+- * codec AFG is prevented from D3 state, but on
+- * system suspend it can (and should) be used
+- */
+- snd_hda_codec_read(codec, codec->afg, 0,
+- AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+- }
+- return 0;
+-}
+-
+ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+ unsigned int power_state)
+ {
+@@ -5655,8 +5641,6 @@ again:
+ } else {
+ codec->patch_ops.set_power_state =
+ stac92xx_set_power_state;
+- codec->patch_ops.post_suspend =
+- stac92xx_post_suspend;
+ }
+ codec->patch_ops.pre_resume = stac92xx_pre_resume;
+ codec->patch_ops.check_power_status =
+@@ -5978,8 +5962,6 @@ again:
+ } else {
+ codec->patch_ops.set_power_state =
+ stac92xx_set_power_state;
+- codec->patch_ops.post_suspend =
+- stac92xx_post_suspend;
+ }
+ codec->patch_ops.pre_resume = stac92xx_pre_resume;
+ codec->patch_ops.check_power_status =
--- /dev/null
+From 72531c9434fa884d20cb3c36fcec83752f32fdf4 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Tue, 22 Nov 2011 09:46:51 +0800
+Subject: ASoC: Fix wrong define for AD1836_ADC_WORD_OFFSET
+
+From: Axel Lin <axel.lin@gmail.com>
+
+commit 72531c9434fa884d20cb3c36fcec83752f32fdf4 upstream.
+
+According to the datasheet:
+The BIT[5:4] of ADC Control Register 2 is to control the word width.
+ 00 = 25 Bits
+ 01 = 20 Bits
+ 10 = 16 Bits
+ 11 = Invalid
+
+Thus, the AD1836_ADC_WORD_OFFSET should be defined as 4.
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Acked-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/soc/codecs/ad1836.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/codecs/ad1836.h
++++ b/sound/soc/codecs/ad1836.h
+@@ -34,7 +34,7 @@
+
+ #define AD1836_ADC_CTRL2 13
+ #define AD1836_ADC_WORD_LEN_MASK 0x30
+-#define AD1836_ADC_WORD_OFFSET 5
++#define AD1836_ADC_WORD_OFFSET 4
+ #define AD1836_ADC_SERFMT_MASK (7 << 6)
+ #define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
+ #define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
--- /dev/null
+From f64964796dedca340608fb1075ab6baad5625851 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 28 Nov 2011 14:49:26 -0500
+Subject: drm/radeon/kms: add some loop timeouts in pageflip code
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit f64964796dedca340608fb1075ab6baad5625851 upstream.
+
+Avoid infinite loops waiting for surface updates if a GPU
+reset happens while waiting for a page flip.
+
+See:
+https://bugs.freedesktop.org/show_bug.cgi?id=43191
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
+Tested-by: Simon Farnsworth <simon.farnsworth@onelan.co.uk>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/evergreen.c | 7 ++++++-
+ drivers/gpu/drm/radeon/r100.c | 7 ++++++-
+ drivers/gpu/drm/radeon/rs600.c | 7 ++++++-
+ drivers/gpu/drm/radeon/rv770.c | 7 ++++++-
+ 4 files changed, 24 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -82,6 +82,7 @@ u32 evergreen_page_flip(struct radeon_de
+ {
+ struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
+ u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
++ int i;
+
+ /* Lock the graphics update lock */
+ tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
+@@ -99,7 +100,11 @@ u32 evergreen_page_flip(struct radeon_de
+ (u32)crtc_base);
+
+ /* Wait for update_pending to go high. */
+- while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING));
++ for (i = 0; i < rdev->usec_timeout; i++) {
++ if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)
++ break;
++ udelay(1);
++ }
+ DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
+
+ /* Unlock the lock, so double-buffering can take place inside vblank */
+--- a/drivers/gpu/drm/radeon/r100.c
++++ b/drivers/gpu/drm/radeon/r100.c
+@@ -84,13 +84,18 @@ u32 r100_page_flip(struct radeon_device
+ {
+ struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
+ u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
++ int i;
+
+ /* Lock the graphics update lock */
+ /* update the scanout addresses */
+ WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
+
+ /* Wait for update_pending to go high. */
+- while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET));
++ for (i = 0; i < rdev->usec_timeout; i++) {
++ if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
++ break;
++ udelay(1);
++ }
+ DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
+
+ /* Unlock the lock, so double-buffering can take place inside vblank */
+--- a/drivers/gpu/drm/radeon/rs600.c
++++ b/drivers/gpu/drm/radeon/rs600.c
+@@ -62,6 +62,7 @@ u32 rs600_page_flip(struct radeon_device
+ {
+ struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
+ u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
++ int i;
+
+ /* Lock the graphics update lock */
+ tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
+@@ -74,7 +75,11 @@ u32 rs600_page_flip(struct radeon_device
+ (u32)crtc_base);
+
+ /* Wait for update_pending to go high. */
+- while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
++ for (i = 0; i < rdev->usec_timeout; i++) {
++ if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
++ break;
++ udelay(1);
++ }
+ DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
+
+ /* Unlock the lock, so double-buffering can take place inside vblank */
+--- a/drivers/gpu/drm/radeon/rv770.c
++++ b/drivers/gpu/drm/radeon/rv770.c
+@@ -47,6 +47,7 @@ u32 rv770_page_flip(struct radeon_device
+ {
+ struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
+ u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
++ int i;
+
+ /* Lock the graphics update lock */
+ tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
+@@ -66,7 +67,11 @@ u32 rv770_page_flip(struct radeon_device
+ (u32)crtc_base);
+
+ /* Wait for update_pending to go high. */
+- while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
++ for (i = 0; i < rdev->usec_timeout; i++) {
++ if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
++ break;
++ udelay(1);
++ }
+ DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
+
+ /* Unlock the lock, so double-buffering can take place inside vblank */
--- /dev/null
+From 2ed4d9d648cbd4fb1c232a646dbdbdfdd373ca94 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 1 Dec 2011 11:02:11 -0500
+Subject: drm/radeon/kms: add some new pci ids
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 2ed4d9d648cbd4fb1c232a646dbdbdfdd373ca94 upstream.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/drm/drm_pciids.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/include/drm/drm_pciids.h
++++ b/include/drm/drm_pciids.h
+@@ -197,6 +197,14 @@
+ {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
++ {0x1002, 0x6840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
++ {0x1002, 0x6841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
++ {0x1002, 0x6842, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
++ {0x1002, 0x6843, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
++ {0x1002, 0x6849, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
++ {0x1002, 0x6850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
++ {0x1002, 0x6858, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
++ {0x1002, 0x6859, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
--- /dev/null
+From e3420901eba65b1c46bed86d360e3a8685d20734 Mon Sep 17 00:00:00 2001
+From: Matthieu CASTET <castet.matthieu@free.fr>
+Date: Mon, 28 Nov 2011 11:30:22 +0100
+Subject: EHCI : Fix a regression in the ISO scheduler
+
+From: Matthieu CASTET <castet.matthieu@free.fr>
+
+commit e3420901eba65b1c46bed86d360e3a8685d20734 upstream.
+
+Fix a regression that was introduced by commit
+811c926c538f7e8d3c08b630dd5844efd7e000f6 (USB: EHCI: fix HUB TT scheduling
+issue with iso transfer).
+
+We detect an error if next == start, but this means uframe 0 can't be allocated
+anymore for iso transfer...
+
+Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
+Signed-off-by: Matthieu CASTET <castet.matthieu@free.fr>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-sched.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -1476,6 +1476,7 @@ iso_stream_schedule (
+ * jump until after the queue is primed.
+ */
+ else {
++ int done = 0;
+ start = SCHEDULE_SLOP + (now & ~0x07);
+
+ /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
+@@ -1493,18 +1494,18 @@ iso_stream_schedule (
+ if (stream->highspeed) {
+ if (itd_slot_ok(ehci, mod, start,
+ stream->usecs, period))
+- break;
++ done = 1;
+ } else {
+ if ((start % 8) >= 6)
+ continue;
+ if (sitd_slot_ok(ehci, mod, stream,
+ start, sched, period))
+- break;
++ done = 1;
+ }
+- } while (start > next);
++ } while (start > next && !done);
+
+ /* no room in the schedule */
+- if (start == next) {
++ if (!done) {
+ ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
+ urb, now, now + mod);
+ status = -ENOSPC;
--- /dev/null
+From bda63586bc5929e97288cdb371bb6456504867ed Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Mon, 28 Nov 2011 09:44:16 +0100
+Subject: firmware: Sigma: Fix endianess issues
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit bda63586bc5929e97288cdb371bb6456504867ed upstream.
+
+Currently the SigmaDSP firmware loader only works correctly on little-endian
+systems. Fix this by using the proper endianess conversion functions.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Mike Frysinger <vapier@gentoo.org>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/firmware/sigma.c | 2 +-
+ include/linux/sigma.h | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/firmware/sigma.c
++++ b/drivers/firmware/sigma.c
+@@ -133,7 +133,7 @@ int process_sigma_firmware(struct i2c_cl
+ crc = crc32(0, fw->data + sizeof(*ssfw_head),
+ fw->size - sizeof(*ssfw_head));
+ pr_debug("%s: crc=%x\n", __func__, crc);
+- if (crc != ssfw_head->crc)
++ if (crc != le32_to_cpu(ssfw_head->crc))
+ goto done;
+
+ ssfw.pos = sizeof(*ssfw_head);
+--- a/include/linux/sigma.h
++++ b/include/linux/sigma.h
+@@ -24,7 +24,7 @@ struct sigma_firmware {
+ struct sigma_firmware_header {
+ unsigned char magic[7];
+ u8 version;
+- u32 crc;
++ __le32 crc;
+ };
+
+ enum {
+@@ -40,14 +40,14 @@ enum {
+ struct sigma_action {
+ u8 instr;
+ u8 len_hi;
+- u16 len;
+- u16 addr;
++ __le16 len;
++ __be16 addr;
+ unsigned char payload[];
+ };
+
+ static inline u32 sigma_action_len(struct sigma_action *sa)
+ {
+- return (sa->len_hi << 16) | sa->len;
++ return (sa->len_hi << 16) | le16_to_cpu(sa->len);
+ }
+
+ extern int process_sigma_firmware(struct i2c_client *client, const char *name);
--- /dev/null
+From 4f718a29fe4908c2cea782f751e9805319684e2b Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Mon, 28 Nov 2011 09:44:14 +0100
+Subject: firmware: Sigma: Prevent out of bounds memory access
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit 4f718a29fe4908c2cea782f751e9805319684e2b upstream.
+
+The SigmaDSP firmware loader currently does not perform enough boundary size
+checks when processing the firmware. As a result it is possible that a
+malformed firmware can cause an out of bounds memory access.
+
+This patch adds checks which ensure that both the action header and the payload
+are completely inside the firmware data boundaries before processing them.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Mike Frysinger <vapier@gentoo.org>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/firmware/sigma.c | 76 ++++++++++++++++++++++++++++++++++-------------
+ include/linux/sigma.h | 5 ---
+ 2 files changed, 55 insertions(+), 26 deletions(-)
+
+--- a/drivers/firmware/sigma.c
++++ b/drivers/firmware/sigma.c
+@@ -14,13 +14,34 @@
+ #include <linux/module.h>
+ #include <linux/sigma.h>
+
+-/* Return: 0==OK, <0==error, =1 ==no more actions */
++static size_t sigma_action_size(struct sigma_action *sa)
++{
++ size_t payload = 0;
++
++ switch (sa->instr) {
++ case SIGMA_ACTION_WRITEXBYTES:
++ case SIGMA_ACTION_WRITESINGLE:
++ case SIGMA_ACTION_WRITESAFELOAD:
++ payload = sigma_action_len(sa);
++ break;
++ default:
++ break;
++ }
++
++ payload = ALIGN(payload, 2);
++
++ return payload + sizeof(struct sigma_action);
++}
++
++/*
++ * Returns a negative error value in case of an error, 0 if processing of
++ * the firmware should be stopped after this action, 1 otherwise.
++ */
+ static int
+-process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw)
++process_sigma_action(struct i2c_client *client, struct sigma_action *sa)
+ {
+- struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos);
+ size_t len = sigma_action_len(sa);
+- int ret = 0;
++ int ret;
+
+ pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
+ sa->instr, sa->addr, len);
+@@ -29,44 +50,50 @@ process_sigma_action(struct i2c_client *
+ case SIGMA_ACTION_WRITEXBYTES:
+ case SIGMA_ACTION_WRITESINGLE:
+ case SIGMA_ACTION_WRITESAFELOAD:
+- if (ssfw->fw->size < ssfw->pos + len)
+- return -EINVAL;
+ ret = i2c_master_send(client, (void *)&sa->addr, len);
+ if (ret < 0)
+ return -EINVAL;
+ break;
+-
+ case SIGMA_ACTION_DELAY:
+- ret = 0;
+ udelay(len);
+ len = 0;
+ break;
+-
+ case SIGMA_ACTION_END:
+- return 1;
+-
++ return 0;
+ default:
+ return -EINVAL;
+ }
+
+- /* when arrive here ret=0 or sent data */
+- ssfw->pos += sigma_action_size(sa, len);
+- return ssfw->pos == ssfw->fw->size;
++ return 1;
+ }
+
+ static int
+ process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw)
+ {
+- pr_debug("%s: processing %p\n", __func__, ssfw);
++ struct sigma_action *sa;
++ size_t size;
++ int ret;
++
++ while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) {
++ sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos);
++
++ size = sigma_action_size(sa);
++ ssfw->pos += size;
++ if (ssfw->pos > ssfw->fw->size || size == 0)
++ break;
++
++ ret = process_sigma_action(client, sa);
+
+- while (1) {
+- int ret = process_sigma_action(client, ssfw);
+ pr_debug("%s: action returned %i\n", __func__, ret);
+- if (ret == 1)
+- return 0;
+- else if (ret)
++
++ if (ret <= 0)
+ return ret;
+ }
++
++ if (ssfw->pos != ssfw->fw->size)
++ return -EINVAL;
++
++ return 0;
+ }
+
+ int process_sigma_firmware(struct i2c_client *client, const char *name)
+@@ -89,7 +116,14 @@ int process_sigma_firmware(struct i2c_cl
+
+ /* then verify the header */
+ ret = -EINVAL;
+- if (fw->size < sizeof(*ssfw_head))
++
++ /*
++ * Reject too small or unreasonable large files. The upper limit has been
++ * chosen a bit arbitrarily, but it should be enough for all practical
++ * purposes and having the limit makes it easier to avoid integer
++ * overflows later in the loading process.
++ */
++ if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000)
+ goto done;
+
+ ssfw_head = (void *)fw->data;
+--- a/include/linux/sigma.h
++++ b/include/linux/sigma.h
+@@ -50,11 +50,6 @@ static inline u32 sigma_action_len(struc
+ return (sa->len_hi << 16) | sa->len;
+ }
+
+-static inline size_t sigma_action_size(struct sigma_action *sa, u32 payload_len)
+-{
+- return sizeof(*sa) + payload_len + (payload_len % 2);
+-}
+-
+ extern int process_sigma_firmware(struct i2c_client *client, const char *name);
+
+ #endif
--- /dev/null
+From c56935bdc0a8edf50237d3b0205133a5b0adc604 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Mon, 28 Nov 2011 09:44:15 +0100
+Subject: firmware: Sigma: Skip header during CRC generation
+
+From: Lars-Peter Clausen <lars@metafoo.de>
+
+commit c56935bdc0a8edf50237d3b0205133a5b0adc604 upstream.
+
+The firmware header is not part of the CRC, so skip it. Otherwise the firmware
+will be rejected due to non-matching CRCs.
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Mike Frysinger <vapier@gentoo.org>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/firmware/sigma.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/firmware/sigma.c
++++ b/drivers/firmware/sigma.c
+@@ -130,7 +130,8 @@ int process_sigma_firmware(struct i2c_cl
+ if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic)))
+ goto done;
+
+- crc = crc32(0, fw->data, fw->size);
++ crc = crc32(0, fw->data + sizeof(*ssfw_head),
++ fw->size - sizeof(*ssfw_head));
+ pr_debug("%s: crc=%x\n", __func__, crc);
+ if (crc != ssfw_head->crc)
+ goto done;
--- /dev/null
+From b1807719f6acdf18cc4bde3b5400d05d77801494 Mon Sep 17 00:00:00 2001
+From: Benjamin Tissoires <benjamin.tissoires@gmail.com>
+Date: Wed, 16 Nov 2011 11:39:52 +0100
+Subject: HID: Correct General touch PID
+
+From: Benjamin Tissoires <benjamin.tissoires@gmail.com>
+
+commit b1807719f6acdf18cc4bde3b5400d05d77801494 upstream.
+
+Genera Touch told us that 0001 is their single point device
+and 0003 is the multitouch one. Apparently, we made the tests
+someone having a prototype, and not the final product.
+They said it should be safe to do the switch.
+
+This partially reverts 5572da0 ("HID: hid-mulitouch: add support
+for the 'Sensing Win7-TwoFinger'").
+
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hid/hid-core.c | 2 +-
+ drivers/hid/hid-ids.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1728,8 +1728,8 @@ static const struct hid_device_id hid_ig
+ { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
+- { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) },
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -266,7 +266,7 @@
+ #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
+
+ #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc
+-#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0001
++#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
+
+ #define USB_VENDOR_ID_GLAB 0x06c2
+ #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
--- /dev/null
+From 580da35a31f91a594f3090b7a2c39b85cb051a12 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Tue, 29 Nov 2011 22:31:23 +0100
+Subject: IB: Fix RCU lockdep splats
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+commit 580da35a31f91a594f3090b7a2c39b85cb051a12 upstream.
+
+Commit f2c31e32b37 ("net: fix NULL dereferences in check_peer_redir()")
+forgot to take care of infiniband uses of dst neighbours.
+
+Many thanks to Marc Aurele who provided a nice bug report and feedback.
+
+Reported-by: Marc Aurele La France <tsi@ualberta.ca>
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Cc: David Miller <davem@davemloft.net>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+
+---
+ drivers/infiniband/core/addr.c | 9 ++++++---
+ drivers/infiniband/hw/cxgb3/iwch_cm.c | 4 ++++
+ drivers/infiniband/hw/cxgb4/cm.c | 4 ++++
+ drivers/infiniband/hw/mlx4/qp.c | 2 +-
+ drivers/infiniband/hw/nes/nes_cm.c | 6 ++++--
+ drivers/infiniband/ulp/ipoib/ipoib_main.c | 18 +++++++++++-------
+ drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 6 ++++--
+ 7 files changed, 34 insertions(+), 15 deletions(-)
+
+--- a/drivers/infiniband/core/addr.c
++++ b/drivers/infiniband/core/addr.c
+@@ -215,7 +215,9 @@ static int addr4_resolve(struct sockaddr
+
+ neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
+ if (!neigh || !(neigh->nud_state & NUD_VALID)) {
++ rcu_read_lock();
+ neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
++ rcu_read_unlock();
+ ret = -ENODATA;
+ if (neigh)
+ goto release;
+@@ -273,15 +275,16 @@ static int addr6_resolve(struct sockaddr
+ goto put;
+ }
+
++ rcu_read_lock();
+ neigh = dst_get_neighbour(dst);
+ if (!neigh || !(neigh->nud_state & NUD_VALID)) {
+ if (neigh)
+ neigh_event_send(neigh, NULL);
+ ret = -ENODATA;
+- goto put;
++ } else {
++ ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
+ }
+-
+- ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
++ rcu_read_unlock();
+ put:
+ dst_release(dst);
+ return ret;
+--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
++++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
+@@ -1365,8 +1365,10 @@ static int pass_accept_req(struct t3cdev
+ goto reject;
+ }
+ dst = &rt->dst;
++ rcu_read_lock();
+ neigh = dst_get_neighbour(dst);
+ l2t = t3_l2t_get(tdev, neigh, neigh->dev);
++ rcu_read_unlock();
+ if (!l2t) {
+ printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
+ __func__);
+@@ -1936,10 +1938,12 @@ int iwch_connect(struct iw_cm_id *cm_id,
+ }
+ ep->dst = &rt->dst;
+
++ rcu_read_lock();
+ neigh = dst_get_neighbour(ep->dst);
+
+ /* get a l2t entry */
+ ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev);
++ rcu_read_unlock();
+ if (!ep->l2t) {
+ printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
+ err = -ENOMEM;
+--- a/drivers/infiniband/hw/cxgb4/cm.c
++++ b/drivers/infiniband/hw/cxgb4/cm.c
+@@ -1358,6 +1358,7 @@ static int pass_accept_req(struct c4iw_d
+ goto reject;
+ }
+ dst = &rt->dst;
++ rcu_read_lock();
+ neigh = dst_get_neighbour(dst);
+ if (neigh->dev->flags & IFF_LOOPBACK) {
+ pdev = ip_dev_find(&init_net, peer_ip);
+@@ -1384,6 +1385,7 @@ static int pass_accept_req(struct c4iw_d
+ rss_qid = dev->rdev.lldi.rxq_ids[
+ cxgb4_port_idx(neigh->dev) * step];
+ }
++ rcu_read_unlock();
+ if (!l2t) {
+ printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
+ __func__);
+@@ -1909,6 +1911,7 @@ int c4iw_connect(struct iw_cm_id *cm_id,
+ }
+ ep->dst = &rt->dst;
+
++ rcu_read_lock();
+ neigh = dst_get_neighbour(ep->dst);
+
+ /* get a l2t entry */
+@@ -1945,6 +1948,7 @@ int c4iw_connect(struct iw_cm_id *cm_id,
+ ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[
+ cxgb4_port_idx(neigh->dev) * step];
+ }
++ rcu_read_unlock();
+ if (!ep->l2t) {
+ printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
+ err = -ENOMEM;
+--- a/drivers/infiniband/hw/mlx4/qp.c
++++ b/drivers/infiniband/hw/mlx4/qp.c
+@@ -1309,7 +1309,7 @@ static int build_mlx_header(struct mlx4_
+ int is_eth;
+ int is_vlan = 0;
+ int is_grh;
+- u16 vlan;
++ u16 vlan = 0;
+
+ send_size = 0;
+ for (i = 0; i < wr->num_sge; ++i)
+--- a/drivers/infiniband/hw/nes/nes_cm.c
++++ b/drivers/infiniband/hw/nes/nes_cm.c
+@@ -1150,9 +1150,11 @@ static int nes_addr_resolve_neigh(struct
+ neigh_release(neigh);
+ }
+
+- if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
++ if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) {
++ rcu_read_lock();
+ neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
+-
++ rcu_read_unlock();
++ }
+ ip_rt_put(rt);
+ return rc;
+ }
+--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -555,6 +555,7 @@ static int path_rec_start(struct net_dev
+ return 0;
+ }
+
++/* called with rcu_read_lock */
+ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+@@ -636,6 +637,7 @@ err_drop:
+ spin_unlock_irqrestore(&priv->lock, flags);
+ }
+
++/* called with rcu_read_lock */
+ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
+ {
+ struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
+@@ -720,13 +722,14 @@ static int ipoib_start_xmit(struct sk_bu
+ struct neighbour *n = NULL;
+ unsigned long flags;
+
++ rcu_read_lock();
+ if (likely(skb_dst(skb)))
+ n = dst_get_neighbour(skb_dst(skb));
+
+ if (likely(n)) {
+ if (unlikely(!*to_ipoib_neigh(n))) {
+ ipoib_path_lookup(skb, dev);
+- return NETDEV_TX_OK;
++ goto unlock;
+ }
+
+ neigh = *to_ipoib_neigh(n);
+@@ -749,17 +752,17 @@ static int ipoib_start_xmit(struct sk_bu
+ ipoib_neigh_free(dev, neigh);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ipoib_path_lookup(skb, dev);
+- return NETDEV_TX_OK;
++ goto unlock;
+ }
+
+ if (ipoib_cm_get(neigh)) {
+ if (ipoib_cm_up(neigh)) {
+ ipoib_cm_send(dev, skb, ipoib_cm_get(neigh));
+- return NETDEV_TX_OK;
++ goto unlock;
+ }
+ } else if (neigh->ah) {
+ ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha));
+- return NETDEV_TX_OK;
++ goto unlock;
+ }
+
+ if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
+@@ -793,13 +796,14 @@ static int ipoib_start_xmit(struct sk_bu
+ phdr->hwaddr + 4);
+ dev_kfree_skb_any(skb);
+ ++dev->stats.tx_dropped;
+- return NETDEV_TX_OK;
++ goto unlock;
+ }
+
+ unicast_arp_send(skb, dev, phdr);
+ }
+ }
+-
++unlock:
++ rcu_read_unlock();
+ return NETDEV_TX_OK;
+ }
+
+@@ -837,7 +841,7 @@ static int ipoib_hard_header(struct sk_b
+ dst = skb_dst(skb);
+ n = NULL;
+ if (dst)
+- n = dst_get_neighbour(dst);
++ n = dst_get_neighbour_raw(dst);
+ if ((!dst || !n) && daddr) {
+ struct ipoib_pseudoheader *phdr =
+ (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
+--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+@@ -265,7 +265,7 @@ static int ipoib_mcast_join_finish(struc
+
+ skb->dev = dev;
+ if (dst)
+- n = dst_get_neighbour(dst);
++ n = dst_get_neighbour_raw(dst);
+ if (!dst || !n) {
+ /* put pseudoheader back on for next time */
+ skb_push(skb, sizeof (struct ipoib_pseudoheader));
+@@ -721,6 +721,8 @@ out:
+ if (mcast && mcast->ah) {
+ struct dst_entry *dst = skb_dst(skb);
+ struct neighbour *n = NULL;
++
++ rcu_read_lock();
+ if (dst)
+ n = dst_get_neighbour(dst);
+ if (n && !*to_ipoib_neigh(n)) {
+@@ -733,7 +735,7 @@ out:
+ list_add_tail(&neigh->list, &mcast->neigh_list);
+ }
+ }
+-
++ rcu_read_unlock();
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ipoib_send(dev, skb, mcast->ah, IB_MULTICAST_QPN);
+ return;
hugetlb-release-pages-in-the-error-path-of-hugetlb_cow.patch
bridge-correct-ipv6-checksum-after-pull.patch
iwlwifi-allow-pci_enable_msi-fail.patch
+drm-radeon-kms-add-some-new-pci-ids.patch
+drm-radeon-kms-add-some-loop-timeouts-in-pageflip-code.patch
+alsa-hda-fix-s3-s4-problem-on-machines-with-vref-pin-mute-led.patch
+asoc-fix-wrong-define-for-ad1836_adc_word_offset.patch
+firmware-sigma-prevent-out-of-bounds-memory-access.patch
+firmware-sigma-skip-header-during-crc-generation.patch
+firmware-sigma-fix-endianess-issues.patch
+staging-rts_pstor-complete-scanning_done-variable.patch
+staging-usbip-bugfix-for-deadlock.patch
+staging-comedi-fix-oops-for-usb-daq-devices.patch
+staging-comedi-fix-mmap_count.patch
+staging-comedi-fix-signal-handling-in-read-and-write.patch
+usb-musb-pm-fix-context-save-restore-in-suspend-resume-path.patch
+usb-whci-hcd-fix-endian-conversion-in-qset_clear.patch
+hid-correct-general-touch-pid.patch
+usb-ftdi_sio-add-pid-for-propox-ispcable-iii.patch
+usb-option-add-huawei-e353-controlling-interfaces.patch
+usb-option-add-simcom-sim5218.patch
+usb-usb-storage-unusual_devs-entry-for-kingston-dt-101-g2.patch
+ib-fix-rcu-lockdep-splats.patch
+usb-ehci-fix-hub-tt-scheduling-issue-with-iso-transfer.patch
+ehci-fix-a-regression-in-the-iso-scheduler.patch
+xhci-fix-bug-in-xhci_clear_command_ring.patch
--- /dev/null
+From df30b21cb0eed5ba8a8e0cdfeebc66ba8cde821d Mon Sep 17 00:00:00 2001
+From: Federico Vaga <federico.vaga@gmail.com>
+Date: Sat, 29 Oct 2011 09:45:39 +0200
+Subject: Staging: comedi: fix mmap_count
+
+From: Federico Vaga <federico.vaga@gmail.com>
+
+commit df30b21cb0eed5ba8a8e0cdfeebc66ba8cde821d upstream.
+
+In comedi_fops, mmap_count is decremented at comedi_vm_ops->close but
+it is not incremented at comedi_vm_ops->open. This may result in a negative
+counter. The patch introduces the open method to keep the counter
+consistent.
+
+The bug was triggerd by this sample code:
+
+ mmap(0, ...., comedi_fd);
+ fork();
+ exit(0);
+
+Acked-by: Alessandro Rubini <rubini@gnudd.com>
+Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/comedi/comedi_fops.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/comedi/comedi_fops.c
++++ b/drivers/staging/comedi/comedi_fops.c
+@@ -1432,7 +1432,21 @@ static int do_cancel(struct comedi_devic
+ return ret;
+ }
+
+-static void comedi_unmap(struct vm_area_struct *area)
++
++static void comedi_vm_open(struct vm_area_struct *area)
++{
++ struct comedi_async *async;
++ struct comedi_device *dev;
++
++ async = area->vm_private_data;
++ dev = async->subdevice->device;
++
++ mutex_lock(&dev->mutex);
++ async->mmap_count++;
++ mutex_unlock(&dev->mutex);
++}
++
++static void comedi_vm_close(struct vm_area_struct *area)
+ {
+ struct comedi_async *async;
+ struct comedi_device *dev;
+@@ -1446,7 +1460,8 @@ static void comedi_unmap(struct vm_area_
+ }
+
+ static struct vm_operations_struct comedi_vm_ops = {
+- .close = comedi_unmap,
++ .open = comedi_vm_open,
++ .close = comedi_vm_close,
+ };
+
+ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
--- /dev/null
+From 3ffab428f40849ed5f21bcfd7285bdef7902f9ca Mon Sep 17 00:00:00 2001
+From: Bernd Porr <berndporr@f2s.com>
+Date: Tue, 8 Nov 2011 21:23:03 +0000
+Subject: staging: comedi: fix oops for USB DAQ devices.
+
+From: Bernd Porr <berndporr@f2s.com>
+
+commit 3ffab428f40849ed5f21bcfd7285bdef7902f9ca upstream.
+
+This fixes kernel oops when an USB DAQ device is plugged out while it's
+communicating with the userspace software.
+
+Signed-off-by: Bernd Porr <berndporr@f2s.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/comedi/comedi_fops.c | 73 +++++++++++++++++++++++++----------
+ 1 file changed, 54 insertions(+), 19 deletions(-)
+
+--- a/drivers/staging/comedi/comedi_fops.c
++++ b/drivers/staging/comedi/comedi_fops.c
+@@ -1452,9 +1452,6 @@ static struct vm_operations_struct comed
+ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+ const unsigned minor = iminor(file->f_dentry->d_inode);
+- struct comedi_device_file_info *dev_file_info =
+- comedi_get_device_file_info(minor);
+- struct comedi_device *dev = dev_file_info->device;
+ struct comedi_async *async = NULL;
+ unsigned long start = vma->vm_start;
+ unsigned long size;
+@@ -1462,6 +1459,15 @@ static int comedi_mmap(struct file *file
+ int i;
+ int retval;
+ struct comedi_subdevice *s;
++ struct comedi_device_file_info *dev_file_info;
++ struct comedi_device *dev;
++
++ dev_file_info = comedi_get_device_file_info(minor);
++ if (dev_file_info == NULL)
++ return -ENODEV;
++ dev = dev_file_info->device;
++ if (dev == NULL)
++ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ if (!dev->attached) {
+@@ -1528,11 +1534,17 @@ static unsigned int comedi_poll(struct f
+ {
+ unsigned int mask = 0;
+ const unsigned minor = iminor(file->f_dentry->d_inode);
+- struct comedi_device_file_info *dev_file_info =
+- comedi_get_device_file_info(minor);
+- struct comedi_device *dev = dev_file_info->device;
+ struct comedi_subdevice *read_subdev;
+ struct comedi_subdevice *write_subdev;
++ struct comedi_device_file_info *dev_file_info;
++ struct comedi_device *dev;
++ dev_file_info = comedi_get_device_file_info(minor);
++
++ if (dev_file_info == NULL)
++ return -ENODEV;
++ dev = dev_file_info->device;
++ if (dev == NULL)
++ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+ if (!dev->attached) {
+@@ -1578,9 +1590,15 @@ static ssize_t comedi_write(struct file
+ int n, m, count = 0, retval = 0;
+ DECLARE_WAITQUEUE(wait, current);
+ const unsigned minor = iminor(file->f_dentry->d_inode);
+- struct comedi_device_file_info *dev_file_info =
+- comedi_get_device_file_info(minor);
+- struct comedi_device *dev = dev_file_info->device;
++ struct comedi_device_file_info *dev_file_info;
++ struct comedi_device *dev;
++ dev_file_info = comedi_get_device_file_info(minor);
++
++ if (dev_file_info == NULL)
++ return -ENODEV;
++ dev = dev_file_info->device;
++ if (dev == NULL)
++ return -ENODEV;
+
+ if (!dev->attached) {
+ DPRINTK("no driver configured on comedi%i\n", dev->minor);
+@@ -1683,9 +1701,15 @@ static ssize_t comedi_read(struct file *
+ int n, m, count = 0, retval = 0;
+ DECLARE_WAITQUEUE(wait, current);
+ const unsigned minor = iminor(file->f_dentry->d_inode);
+- struct comedi_device_file_info *dev_file_info =
+- comedi_get_device_file_info(minor);
+- struct comedi_device *dev = dev_file_info->device;
++ struct comedi_device_file_info *dev_file_info;
++ struct comedi_device *dev;
++ dev_file_info = comedi_get_device_file_info(minor);
++
++ if (dev_file_info == NULL)
++ return -ENODEV;
++ dev = dev_file_info->device;
++ if (dev == NULL)
++ return -ENODEV;
+
+ if (!dev->attached) {
+ DPRINTK("no driver configured on comedi%i\n", dev->minor);
+@@ -1885,11 +1909,17 @@ ok:
+ static int comedi_close(struct inode *inode, struct file *file)
+ {
+ const unsigned minor = iminor(inode);
+- struct comedi_device_file_info *dev_file_info =
+- comedi_get_device_file_info(minor);
+- struct comedi_device *dev = dev_file_info->device;
+ struct comedi_subdevice *s = NULL;
+ int i;
++ struct comedi_device_file_info *dev_file_info;
++ struct comedi_device *dev;
++ dev_file_info = comedi_get_device_file_info(minor);
++
++ if (dev_file_info == NULL)
++ return -ENODEV;
++ dev = dev_file_info->device;
++ if (dev == NULL)
++ return -ENODEV;
+
+ mutex_lock(&dev->mutex);
+
+@@ -1923,10 +1953,15 @@ static int comedi_close(struct inode *in
+ static int comedi_fasync(int fd, struct file *file, int on)
+ {
+ const unsigned minor = iminor(file->f_dentry->d_inode);
+- struct comedi_device_file_info *dev_file_info =
+- comedi_get_device_file_info(minor);
+-
+- struct comedi_device *dev = dev_file_info->device;
++ struct comedi_device_file_info *dev_file_info;
++ struct comedi_device *dev;
++ dev_file_info = comedi_get_device_file_info(minor);
++
++ if (dev_file_info == NULL)
++ return -ENODEV;
++ dev = dev_file_info->device;
++ if (dev == NULL)
++ return -ENODEV;
+
+ return fasync_helper(fd, file, on, &dev->async_queue);
+ }
--- /dev/null
+From 6a9ce6b654e491981f6ef7e214cbd4f63e033848 Mon Sep 17 00:00:00 2001
+From: Federico Vaga <federico.vaga@gmail.com>
+Date: Sat, 29 Oct 2011 09:47:39 +0200
+Subject: Staging: comedi: fix signal handling in read and write
+
+From: Federico Vaga <federico.vaga@gmail.com>
+
+commit 6a9ce6b654e491981f6ef7e214cbd4f63e033848 upstream.
+
+After sleeping on a wait queue, signal_pending(current) should be
+checked (not before sleeping).
+
+Acked-by: Alessandro Rubini <rubini@gnudd.com>
+Signed-off-by: Federico Vaga <federico.vaga@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/comedi/comedi_fops.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/comedi/comedi_fops.c
++++ b/drivers/staging/comedi/comedi_fops.c
+@@ -1673,11 +1673,11 @@ static ssize_t comedi_write(struct file
+ retval = -EAGAIN;
+ break;
+ }
++ schedule();
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
+- schedule();
+ if (!s->busy)
+ break;
+ if (s->busy != file) {
+@@ -1780,11 +1780,11 @@ static ssize_t comedi_read(struct file *
+ retval = -EAGAIN;
+ break;
+ }
++ schedule();
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
+- schedule();
+ if (!s->busy) {
+ retval = 0;
+ break;
--- /dev/null
+From f7364ba04b0961f3a1f978bbe77102606801e35f Mon Sep 17 00:00:00 2001
+From: wwang <wei_wang@realsil.com.cn>
+Date: Mon, 31 Oct 2011 15:02:53 +0800
+Subject: staging:rts_pstor:Complete scanning_done variable
+
+From: wwang <wei_wang@realsil.com.cn>
+
+commit f7364ba04b0961f3a1f978bbe77102606801e35f upstream.
+
+Complete scanning_done variable if rtsx-scan thread created failed.
+
+Signed-off-by: wwang <wei_wang@realsil.com.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/rts_pstor/rtsx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/rts_pstor/rtsx.c
++++ b/drivers/staging/rts_pstor/rtsx.c
+@@ -1015,6 +1015,7 @@ static int __devinit rtsx_probe(struct p
+ th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan");
+ if (IS_ERR(th)) {
+ printk(KERN_ERR "Unable to start the device-scanning thread\n");
++ complete(&dev->scanning_done);
+ quiesce_and_remove_host(dev);
+ err = PTR_ERR(th);
+ goto errout;
--- /dev/null
+From 438957f8d4a84daa7fa5be6978ad5897a2e9e5e5 Mon Sep 17 00:00:00 2001
+From: Bart Westgeest <bart@elbrys.com>
+Date: Tue, 1 Nov 2011 15:01:28 -0400
+Subject: staging: usbip: bugfix for deadlock
+
+From: Bart Westgeest <bart@elbrys.com>
+
+commit 438957f8d4a84daa7fa5be6978ad5897a2e9e5e5 upstream.
+
+Interrupts must be disabled prior to calling usb_hcd_unlink_urb_from_ep.
+If interrupts are not disabled, it can potentially lead to a deadlock.
+The deadlock is readily reproduceable on a slower (ARM based) device
+such as the TI Pandaboard.
+
+Signed-off-by: Bart Westgeest <bart@elbrys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/vhci_rx.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/usbip/vhci_rx.c
++++ b/drivers/staging/usbip/vhci_rx.c
+@@ -68,6 +68,7 @@ static void vhci_recv_ret_submit(struct
+ {
+ struct usbip_device *ud = &vdev->ud;
+ struct urb *urb;
++ unsigned long flags;
+
+ spin_lock(&vdev->priv_lock);
+ urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
+@@ -101,9 +102,9 @@ static void vhci_recv_ret_submit(struct
+
+ usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+ usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
+
+@@ -141,6 +142,7 @@ static void vhci_recv_ret_unlink(struct
+ {
+ struct vhci_unlink *unlink;
+ struct urb *urb;
++ unsigned long flags;
+
+ usbip_dump_header(pdu);
+
+@@ -170,9 +172,9 @@ static void vhci_recv_ret_unlink(struct
+ urb->status = pdu->u.ret_unlink.status;
+ pr_info("urb->status %d\n", urb->status);
+
+- spin_lock(&the_controller->lock);
++ spin_lock_irqsave(&the_controller->lock, flags);
+ usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
+- spin_unlock(&the_controller->lock);
++ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
+ urb->status);
--- /dev/null
+From 811c926c538f7e8d3c08b630dd5844efd7e000f6 Mon Sep 17 00:00:00 2001
+From: Thomas Poussevin <thomas.poussevin@parrot.com>
+Date: Thu, 27 Oct 2011 18:46:48 +0200
+Subject: USB: EHCI: fix HUB TT scheduling issue with iso transfer
+
+From: Thomas Poussevin <thomas.poussevin@parrot.com>
+
+commit 811c926c538f7e8d3c08b630dd5844efd7e000f6 upstream.
+
+The current TT scheduling doesn't allow to play and then record on a
+full-speed device connected to a high speed hub.
+
+The IN iso stream can only start on the first uframe (0-2 for a 165 us)
+because of CSPLIT transactions.
+For the OUT iso stream there no such restriction. uframe 0-5 are possible.
+
+The idea of this patch is that the first uframe are precious (for IN TT iso
+stream) and we should allocate the last uframes first if possible.
+
+For that we reverse the order of uframe allocation (last uframe first).
+
+Here an example :
+
+hid interrupt stream
+----------------------------------------------------------------------
+uframe | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+----------------------------------------------------------------------
+max_tt_usecs | 125 | 125 | 125 | 125 | 125 | 125 | 30 | 0 |
+----------------------------------------------------------------------
+used usecs on a frame | 13 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+----------------------------------------------------------------------
+
+iso OUT stream
+----------------------------------------------------------------------
+uframe | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+----------------------------------------------------------------------
+max_tt_usecs | 125 | 125 | 125 | 125 | 125 | 125 | 30 | 0 |
+----------------------------------------------------------------------
+used usecs on a frame | 13 | 125 | 39 | 0 | 0 | 0 | 0 | 0 |
+----------------------------------------------------------------------
+
+There no place for iso IN stream (uframe 0-2 are used) and we got "cannot
+submit datapipe for urb 0, error -28: not enough bandwidth" error.
+
+With the patch this become.
+
+iso OUT stream
+----------------------------------------------------------------------
+uframe | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+----------------------------------------------------------------------
+max_tt_usecs | 125 | 125 | 125 | 125 | 125 | 125 | 30 | 0 |
+----------------------------------------------------------------------
+used usecs on a frame | 13 | 0 | 0 | 0 | 125 | 39 | 0 | 0 |
+----------------------------------------------------------------------
+
+iso IN stream
+----------------------------------------------------------------------
+uframe | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+----------------------------------------------------------------------
+max_tt_usecs | 125 | 125 | 125 | 125 | 125 | 125 | 30 | 0 |
+----------------------------------------------------------------------
+used usecs on a frame | 13 | 0 | 125 | 40 | 125 | 39 | 0 | 0 |
+----------------------------------------------------------------------
+
+Signed-off-by: Matthieu Castet <matthieu.castet@parrot.com>
+Signed-off-by: Thomas Poussevin <thomas.poussevin@parrot.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-sched.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -1480,10 +1480,15 @@ iso_stream_schedule (
+
+ /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
+
+- /* find a uframe slot with enough bandwidth */
+- next = start + period;
+- for (; start < next; start++) {
+-
++ /* find a uframe slot with enough bandwidth.
++ * Early uframes are more precious because full-speed
++ * iso IN transfers can't use late uframes,
++ * and therefore they should be allocated last.
++ */
++ next = start;
++ start += period;
++ do {
++ start--;
+ /* check schedule: enough space? */
+ if (stream->highspeed) {
+ if (itd_slot_ok(ehci, mod, start,
+@@ -1496,7 +1501,7 @@ iso_stream_schedule (
+ start, sched, period))
+ break;
+ }
+- }
++ } while (start > next);
+
+ /* no room in the schedule */
+ if (start == next) {
--- /dev/null
+From 307369b0ca06b27b511b61714e335ddfccf19c4f Mon Sep 17 00:00:00 2001
+From: Marcin Kościelnicki <koriakin@0x04.net>
+Date: Wed, 30 Nov 2011 17:01:04 +0100
+Subject: usb: ftdi_sio: add PID for Propox ISPcable III
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Marcin Kościelnicki <koriakin@0x04.net>
+
+commit 307369b0ca06b27b511b61714e335ddfccf19c4f upstream.
+
+Signed-off-by: Marcin Kościelnicki <koriakin@0x04.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 1 +
+ drivers/usb/serial/ftdi_sio_ids.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -735,6 +735,7 @@ static struct usb_device_id id_table_com
+ { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
+ { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID),
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -112,6 +112,7 @@
+
+ /* Propox devices */
+ #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738
++#define FTDI_PROPOX_ISPCABLEIII_PID 0xD739
+
+ /* Lenz LI-USB Computer Interface. */
+ #define FTDI_LENZ_LIUSB_PID 0xD780
--- /dev/null
+From 5d193ce8f1fa7c67c7fd7be2c03ef31eed344a4f Mon Sep 17 00:00:00 2001
+From: Kevin Hilman <khilman@ti.com>
+Date: Tue, 22 Nov 2011 17:18:24 -0800
+Subject: usb: musb: PM: fix context save/restore in suspend/resume path
+
+From: Kevin Hilman <khilman@ti.com>
+
+commit 5d193ce8f1fa7c67c7fd7be2c03ef31eed344a4f upstream.
+
+Currently the driver tries to save context in the suspend path, but
+will cause an abort if the device is already runtime suspended. This
+happens, for example, if MUSB loaded/compiled-in, in host mode, but no
+USB devices are attached. MUSB will be runtime suspended, but then
+attempting a system suspend will crash due to the context save
+being attempted while the device is disabled.
+
+On OMAP, as of v3.1, the driver's ->runtime_suspend() callback will be
+called late in the suspend path (by the PM domain layer) if the driver
+is not already runtime suspended, ensuring a full shutdown.
+
+Therefore, the context save is not needed in the ->suspend() method
+since it will be called in the ->runtime_suspend() method anyways
+(similarily for resume.)
+
+NOTE: this leaves the suspend/resume methods basically empty (with
+ some FIXMEs and comments, but I'll leave it to the maintainers
+ to decide whether to remove them.
+
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_core.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2302,18 +2302,12 @@ static int musb_suspend(struct device *d
+ */
+ }
+
+- musb_save_context(musb);
+-
+ spin_unlock_irqrestore(&musb->lock, flags);
+ return 0;
+ }
+
+ static int musb_resume_noirq(struct device *dev)
+ {
+- struct musb *musb = dev_to_musb(dev);
+-
+- musb_restore_context(musb);
+-
+ /* for static cmos like DaVinci, register values were preserved
+ * unless for some reason the whole soc powered down or the USB
+ * module got reset through the PSC (vs just being disabled).
--- /dev/null
+From 46b1848360c8e634e0b063932a1261062fa0f7d6 Mon Sep 17 00:00:00 2001
+From: Dirk Nehring <dnehring@gmx.net>
+Date: Thu, 24 Nov 2011 19:22:23 +0100
+Subject: usb: option: add Huawei E353 controlling interfaces
+
+From: Dirk Nehring <dnehring@gmx.net>
+
+commit 46b1848360c8e634e0b063932a1261062fa0f7d6 upstream.
+
+This patch creates the missing controlling devices for the Huawei E353
+HSPA+ stick.
+
+Signed-off-by: Dirk Nehring <dnehring@gmx.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -657,6 +657,9 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) },
++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) },
++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) },
++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x08) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
+ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
--- /dev/null
+From ec0cd94d881ca89cc9fb61d00d0f4b2b52e605b3 Mon Sep 17 00:00:00 2001
+From: Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
+Date: Thu, 24 Nov 2011 22:08:56 +0200
+Subject: usb: option: add SIMCom SIM5218
+
+From: Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
+
+commit ec0cd94d881ca89cc9fb61d00d0f4b2b52e605b3 upstream.
+
+Tested with SIM5218EVB-KIT evaluation kit.
+
+Signed-off-by: Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -746,6 +746,7 @@ static const struct usb_device_id option
+ { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
+ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
+ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
++ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
--- /dev/null
+From cec28a5428793b6bc64e56687fb239759d6da74e Mon Sep 17 00:00:00 2001
+From: Qinglin Ye <yestyle@gmail.com>
+Date: Wed, 23 Nov 2011 23:39:32 +0800
+Subject: USB: usb-storage: unusual_devs entry for Kingston DT 101 G2
+
+From: Qinglin Ye <yestyle@gmail.com>
+
+commit cec28a5428793b6bc64e56687fb239759d6da74e upstream.
+
+Kingston DT 101 G2 replies a wrong tag while transporting, add an
+unusal_devs entry to ignore the tag validation.
+
+Signed-off-by: Qinglin Ye <yestyle@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/storage/unusual_devs.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1854,6 +1854,13 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
++/* Reported by Qinglin Ye <yestyle@gmail.com> */
++UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100,
++ "Kingston",
++ "DT 101 G2",
++ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
++ US_FL_BULK_IGNORE_TAG ),
++
+ /* Reported by Francesco Foresti <frafore@tiscali.it> */
+ UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201,
+ "Super Top",
--- /dev/null
+From 8746c83d538cab273d335acb2be226d096f4a5af Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Tue, 22 Nov 2011 10:28:31 +0300
+Subject: USB: whci-hcd: fix endian conversion in qset_clear()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit 8746c83d538cab273d335acb2be226d096f4a5af upstream.
+
+qset->qh.link is an __le64 field and we should be using cpu_to_le64()
+to fill it.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/whci/qset.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/whci/qset.c
++++ b/drivers/usb/host/whci/qset.c
+@@ -124,7 +124,7 @@ void qset_clear(struct whc *whc, struct
+ {
+ qset->td_start = qset->td_end = qset->ntds = 0;
+
+- qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
++ qset->qh.link = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T);
+ qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
+ qset->qh.err_count = 0;
+ qset->qh.scratch[0] = 0;
--- /dev/null
+From 158886cd2cf4599e04f9b7e10cb767f5f39b14f1 Mon Sep 17 00:00:00 2001
+From: Andiry Xu <andiry.xu@amd.com>
+Date: Wed, 30 Nov 2011 16:37:41 +0800
+Subject: xHCI: fix bug in xhci_clear_command_ring()
+
+From: Andiry Xu <andiry.xu@amd.com>
+
+commit 158886cd2cf4599e04f9b7e10cb767f5f39b14f1 upstream.
+
+When system enters suspend, xHCI driver clears command ring by writing zero
+to all the TRBs. However, this also writes zero to the Link TRB, and the ring
+is mangled. This may cause driver accesses wrong memory address and the
+result is unpredicted.
+
+When clear the command ring, keep the last Link TRB intact, only clear its
+cycle bit. This should fix the "command ring full" issue reported by Oliver
+Neukum.
+
+This should be backported to stable kernels as old as 2.6.37, since the
+commit 89821320 "xhci: Fix command ring replay after resume" is merged.
+
+Signed-off-by: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Reported-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -657,7 +657,10 @@ static void xhci_clear_command_ring(stru
+ ring = xhci->cmd_ring;
+ seg = ring->deq_seg;
+ do {
+- memset(seg->trbs, 0, SEGMENT_SIZE);
++ memset(seg->trbs, 0,
++ sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
++ seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
++ cpu_to_le32(~TRB_CYCLE);
+ seg = seg->next;
+ } while (seg != ring->deq_seg);
+