]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 30 Apr 2012 05:26:27 +0000 (01:26 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 30 Apr 2012 05:26:27 +0000 (01:26 -0400)
added patches:
autofs-make-the-autofsv5-packet-file-descriptor-use-a-packetized-pipe.patch
pipes-add-a-packetized-pipe-mode-for-writing.patch
usb-cdc-wdm-fix-race-leading-leading-to-memory-corruption.patch
usb-ehci-fix-crash-during-suspend-on-asus-computers.patch
usb-gadget-dummy-do-not-call-pullup-on-udc_stop.patch
usb-gadget-storage-gadgets-send-wrong-error-code-for-unknown-commands.patch
usb-gadget-uvc-uvc_request_data-length-field-must-be-signed.patch

queue-3.3/autofs-make-the-autofsv5-packet-file-descriptor-use-a-packetized-pipe.patch [new file with mode: 0644]
queue-3.3/pipes-add-a-packetized-pipe-mode-for-writing.patch [new file with mode: 0644]
queue-3.3/series
queue-3.3/usb-cdc-wdm-fix-race-leading-leading-to-memory-corruption.patch [new file with mode: 0644]
queue-3.3/usb-ehci-fix-crash-during-suspend-on-asus-computers.patch [new file with mode: 0644]
queue-3.3/usb-gadget-dummy-do-not-call-pullup-on-udc_stop.patch [new file with mode: 0644]
queue-3.3/usb-gadget-storage-gadgets-send-wrong-error-code-for-unknown-commands.patch [new file with mode: 0644]
queue-3.3/usb-gadget-uvc-uvc_request_data-length-field-must-be-signed.patch [new file with mode: 0644]

diff --git a/queue-3.3/autofs-make-the-autofsv5-packet-file-descriptor-use-a-packetized-pipe.patch b/queue-3.3/autofs-make-the-autofsv5-packet-file-descriptor-use-a-packetized-pipe.patch
new file mode 100644 (file)
index 0000000..7fe5e92
--- /dev/null
@@ -0,0 +1,110 @@
+From 64f371bc3107e69efce563a3d0f0e6880de0d537 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Sun, 29 Apr 2012 13:30:08 -0700
+Subject: autofs: make the autofsv5 packet file descriptor use a packetized pipe
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 64f371bc3107e69efce563a3d0f0e6880de0d537 upstream.
+
+The autofs packet size has had a very unfortunate size problem on x86:
+because the alignment of 'u64' differs in 32-bit and 64-bit modes, and
+because the packet data was not 8-byte aligned, the size of the autofsv5
+packet structure differed between 32-bit and 64-bit modes despite
+looking otherwise identical (300 vs 304 bytes respectively).
+
+We first fixed that up by making the 64-bit compat mode know about this
+problem in commit a32744d4abae ("autofs: work around unhappy compat
+problem on x86-64"), and that made a 32-bit 'systemd' work happily on a
+64-bit kernel because everything then worked the same way as on a 32-bit
+kernel.
+
+But it turned out that 'automount' had actually known and worked around
+this problem in user space, so fixing the kernel to do the proper 32-bit
+compatibility handling actually *broke* 32-bit automount on a 64-bit
+kernel, because it knew that the packet sizes were wrong and expected
+those incorrect sizes.
+
+As a result, we ended up reverting that compatibility mode fix, and
+thus breaking systemd again, in commit fcbf94b9dedd.
+
+With both automount and systemd doing a single read() system call, and
+verifying that they get *exactly* the size they expect but using
+different sizes, it seemed that fixing one of them inevitably seemed to
+break the other.  At one point, a patch I seriously considered applying
+from Michael Tokarev did a "strcmp()" to see if it was automount that
+was doing the operation.  Ugly, ugly.
+
+However, a prettier solution exists now thanks to the packetized pipe
+mode.  By marking the communication pipe as being packetized (by simply
+setting the O_DIRECT flag), we can always just write the bigger packet
+size, and if user-space does a smaller read, it will just get that
+partial end result and the extra alignment padding will simply be thrown
+away.
+
+This makes both automount and systemd happy, since they now get the size
+they asked for, and the kernel side of autofs simply no longer needs to
+care - it could pad out the packet arbitrarily.
+
+Of course, if there is some *other* user of autofs (please, please,
+please tell me it ain't so - and we haven't heard of any) that tries to
+read the packets with multiple writes, that other user will now be
+broken - the whole point of the packetized mode is that one system call
+gets exactly one packet, and you cannot read a packet in pieces.
+
+Tested-by: Michael Tokarev <mjt@tls.msk.ru>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Cc: David Miller <davem@davemloft.net>
+Cc: Ian Kent <raven@themaw.net>
+Cc: Thomas Meyer <thomas@m3y3r.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/autofs4/autofs_i.h  |   11 +++++++++++
+ fs/autofs4/dev-ioctl.c |    2 +-
+ fs/autofs4/inode.c     |    2 +-
+ 3 files changed, 13 insertions(+), 2 deletions(-)
+
+--- a/fs/autofs4/autofs_i.h
++++ b/fs/autofs4/autofs_i.h
+@@ -269,6 +269,17 @@ int autofs4_fill_super(struct super_bloc
+ struct autofs_info *autofs4_new_ino(struct autofs_sb_info *);
+ void autofs4_clean_ino(struct autofs_info *);
++static inline int autofs_prepare_pipe(struct file *pipe)
++{
++      if (!pipe->f_op || !pipe->f_op->write)
++              return -EINVAL;
++      if (!S_ISFIFO(pipe->f_dentry->d_inode->i_mode))
++              return -EINVAL;
++      /* We want a packet pipe */
++      pipe->f_flags |= O_DIRECT;
++      return 0;
++}
++
+ /* Queue management functions */
+ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
+--- a/fs/autofs4/dev-ioctl.c
++++ b/fs/autofs4/dev-ioctl.c
+@@ -376,7 +376,7 @@ static int autofs_dev_ioctl_setpipefd(st
+                       err = -EBADF;
+                       goto out;
+               }
+-              if (!pipe->f_op || !pipe->f_op->write) {
++              if (autofs_prepare_pipe(pipe) < 0) {
+                       err = -EPIPE;
+                       fput(pipe);
+                       goto out;
+--- a/fs/autofs4/inode.c
++++ b/fs/autofs4/inode.c
+@@ -293,7 +293,7 @@ int autofs4_fill_super(struct super_bloc
+               printk("autofs: could not open pipe file descriptor\n");
+               goto fail_dput;
+       }
+-      if (!pipe->f_op || !pipe->f_op->write)
++      if (autofs_prepare_pipe(pipe) < 0)
+               goto fail_fput;
+       sbi->pipe = pipe;
+       sbi->pipefd = pipefd;
diff --git a/queue-3.3/pipes-add-a-packetized-pipe-mode-for-writing.patch b/queue-3.3/pipes-add-a-packetized-pipe-mode-for-writing.patch
new file mode 100644 (file)
index 0000000..2e8d558
--- /dev/null
@@ -0,0 +1,139 @@
+From 9883035ae7edef3ec62ad215611cb8e17d6a1a5d Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Sun, 29 Apr 2012 13:12:42 -0700
+Subject: pipes: add a "packetized pipe" mode for writing
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 9883035ae7edef3ec62ad215611cb8e17d6a1a5d upstream.
+
+The actual internal pipe implementation is already really about
+individual packets (called "pipe buffers"), and this simply exposes that
+as a special packetized mode.
+
+When we are in the packetized mode (marked by O_DIRECT as suggested by
+Alan Cox), a write() on a pipe will not merge the new data with previous
+writes, so each write will get a pipe buffer of its own.  The pipe
+buffer is then marked with the PIPE_BUF_FLAG_PACKET flag, which in turn
+will tell the reader side to break the read at that boundary (and throw
+away any partial packet contents that do not fit in the read buffer).
+
+End result: as long as you do writes less than PIPE_BUF in size (so that
+the pipe doesn't have to split them up), you can now treat the pipe as a
+packet interface, where each read() system call will read one packet at
+a time.  You can just use a sufficiently big read buffer (PIPE_BUF is
+sufficient, since bigger than that doesn't guarantee atomicity anyway),
+and the return value of the read() will naturally give you the size of
+the packet.
+
+NOTE! We do not support zero-sized packets, and zero-sized reads and
+writes to a pipe continue to be no-ops.  Also note that big packets will
+currently be split at write time, but that the size at which that
+happens is not really specified (except that it's bigger than PIPE_BUF).
+Currently that limit is the system page size, but we might want to
+explicitly support bigger packets some day.
+
+The main user for this is going to be the autofs packet interface,
+allowing us to stop having to care so deeply about exact packet sizes
+(which have had bugs with 32/64-bit compatibility modes).  But user
+space can create packetized pipes with "pipe2(fd, O_DIRECT)", which will
+fail with an EINVAL on kernels that do not support this interface.
+
+Tested-by: Michael Tokarev <mjt@tls.msk.ru>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Cc: David Miller <davem@davemloft.net>
+Cc: Ian Kent <raven@themaw.net>
+Cc: Thomas Meyer <thomas@m3y3r.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/pipe.c                 |   31 +++++++++++++++++++++++++++++--
+ include/linux/pipe_fs_i.h |    1 +
+ 2 files changed, 30 insertions(+), 2 deletions(-)
+
+--- a/fs/pipe.c
++++ b/fs/pipe.c
+@@ -345,6 +345,16 @@ static const struct pipe_buf_operations
+       .get = generic_pipe_buf_get,
+ };
++static const struct pipe_buf_operations packet_pipe_buf_ops = {
++      .can_merge = 0,
++      .map = generic_pipe_buf_map,
++      .unmap = generic_pipe_buf_unmap,
++      .confirm = generic_pipe_buf_confirm,
++      .release = anon_pipe_buf_release,
++      .steal = generic_pipe_buf_steal,
++      .get = generic_pipe_buf_get,
++};
++
+ static ssize_t
+ pipe_read(struct kiocb *iocb, const struct iovec *_iov,
+          unsigned long nr_segs, loff_t pos)
+@@ -406,6 +416,13 @@ redo:
+                       ret += chars;
+                       buf->offset += chars;
+                       buf->len -= chars;
++
++                      /* Was it a packet buffer? Clean up and exit */
++                      if (buf->flags & PIPE_BUF_FLAG_PACKET) {
++                              total_len = chars;
++                              buf->len = 0;
++                      }
++
+                       if (!buf->len) {
+                               buf->ops = NULL;
+                               ops->release(pipe, buf);
+@@ -458,6 +475,11 @@ redo:
+       return ret;
+ }
++static inline int is_packetized(struct file *file)
++{
++      return (file->f_flags & O_DIRECT) != 0;
++}
++
+ static ssize_t
+ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
+           unsigned long nr_segs, loff_t ppos)
+@@ -592,6 +614,11 @@ redo2:
+                       buf->ops = &anon_pipe_buf_ops;
+                       buf->offset = 0;
+                       buf->len = chars;
++                      buf->flags = 0;
++                      if (is_packetized(filp)) {
++                              buf->ops = &packet_pipe_buf_ops;
++                              buf->flags = PIPE_BUF_FLAG_PACKET;
++                      }
+                       pipe->nrbufs = ++bufs;
+                       pipe->tmp_page = NULL;
+@@ -1012,7 +1039,7 @@ struct file *create_write_pipe(int flags
+               goto err_dentry;
+       f->f_mapping = inode->i_mapping;
+-      f->f_flags = O_WRONLY | (flags & O_NONBLOCK);
++      f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT));
+       f->f_version = 0;
+       return f;
+@@ -1056,7 +1083,7 @@ int do_pipe_flags(int *fd, int flags)
+       int error;
+       int fdw, fdr;
+-      if (flags & ~(O_CLOEXEC | O_NONBLOCK))
++      if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
+               return -EINVAL;
+       fw = create_write_pipe(flags);
+--- a/include/linux/pipe_fs_i.h
++++ b/include/linux/pipe_fs_i.h
+@@ -8,6 +8,7 @@
+ #define PIPE_BUF_FLAG_LRU     0x01    /* page is on the LRU */
+ #define PIPE_BUF_FLAG_ATOMIC  0x02    /* was atomically mapped */
+ #define PIPE_BUF_FLAG_GIFT    0x04    /* page is a gift */
++#define PIPE_BUF_FLAG_PACKET  0x08    /* read() as a packet */
+ /**
+  *    struct pipe_buffer - a linux kernel pipe buffer
index 5000dbdd0f995a36da2a4a063061b7d91a1ccb41..a0d177ff2dbc2b456da1bba0cca2833641ead9ea 100644 (file)
@@ -26,3 +26,10 @@ drm-i915-fix-integer-overflow-in-i915_gem_do_execbuffer.patch
 i387-ptrace-breaks-the-lazy-fpu-restore-logic.patch
 nl80211-ensure-interface-is-up-in-various-apis.patch
 alsa-hda-add-external-mic-quirk-for-asus-zenbook-ux31e.patch
+usb-cdc-wdm-fix-race-leading-leading-to-memory-corruption.patch
+usb-ehci-fix-crash-during-suspend-on-asus-computers.patch
+usb-gadget-storage-gadgets-send-wrong-error-code-for-unknown-commands.patch
+usb-gadget-dummy-do-not-call-pullup-on-udc_stop.patch
+usb-gadget-uvc-uvc_request_data-length-field-must-be-signed.patch
+pipes-add-a-packetized-pipe-mode-for-writing.patch
+autofs-make-the-autofsv5-packet-file-descriptor-use-a-packetized-pipe.patch
diff --git a/queue-3.3/usb-cdc-wdm-fix-race-leading-leading-to-memory-corruption.patch b/queue-3.3/usb-cdc-wdm-fix-race-leading-leading-to-memory-corruption.patch
new file mode 100644 (file)
index 0000000..1fadcf0
--- /dev/null
@@ -0,0 +1,60 @@
+From 5c22837adca7c30b66121cf18ad3e160134268d4 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver@neukum.org>
+Date: Thu, 26 Apr 2012 21:59:10 +0200
+Subject: USB: cdc-wdm: fix race leading leading to memory corruption
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit 5c22837adca7c30b66121cf18ad3e160134268d4 upstream.
+
+This patch fixes a race whereby a pointer to a buffer
+would be overwritten while the buffer was in use leading
+to a double free and a memory leak. This causes crashes.
+This bug was introduced in 2.6.34
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Tested-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-wdm.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -108,8 +108,9 @@ static void wdm_out_callback(struct urb
+       spin_lock(&desc->iuspin);
+       desc->werr = urb->status;
+       spin_unlock(&desc->iuspin);
+-      clear_bit(WDM_IN_USE, &desc->flags);
+       kfree(desc->outbuf);
++      desc->outbuf = NULL;
++      clear_bit(WDM_IN_USE, &desc->flags);
+       wake_up(&desc->wait);
+ }
+@@ -312,7 +313,7 @@ static ssize_t wdm_write
+       if (we < 0)
+               return -EIO;
+-      desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
++      buf = kmalloc(count, GFP_KERNEL);
+       if (!buf) {
+               rv = -ENOMEM;
+               goto outnl;
+@@ -376,10 +377,12 @@ static ssize_t wdm_write
+       req->wIndex = desc->inum;
+       req->wLength = cpu_to_le16(count);
+       set_bit(WDM_IN_USE, &desc->flags);
++      desc->outbuf = buf;
+       rv = usb_submit_urb(desc->command, GFP_KERNEL);
+       if (rv < 0) {
+               kfree(buf);
++              desc->outbuf = NULL;
+               clear_bit(WDM_IN_USE, &desc->flags);
+               dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
+       } else {
diff --git a/queue-3.3/usb-ehci-fix-crash-during-suspend-on-asus-computers.patch b/queue-3.3/usb-ehci-fix-crash-during-suspend-on-asus-computers.patch
new file mode 100644 (file)
index 0000000..b3aed76
--- /dev/null
@@ -0,0 +1,88 @@
+From 151b61284776be2d6f02d48c23c3625678960b97 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 24 Apr 2012 14:07:22 -0400
+Subject: USB: EHCI: fix crash during suspend on ASUS computers
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 151b61284776be2d6f02d48c23c3625678960b97 upstream.
+
+This patch (as1545) fixes a problem affecting several ASUS computers:
+The machine crashes or corrupts memory when going into suspend if the
+ehci-hcd driver is bound to any controllers.  Users have been forced
+to unbind or unload ehci-hcd before putting their systems to sleep.
+
+After extensive testing, it was determined that the machines don't
+like going into suspend when any EHCI controllers are in the PCI D3
+power state.  Presumably this is a firmware bug, but there's nothing
+we can do about it except to avoid putting the controllers in D3
+during system sleep.
+
+The patch adds a new flag to indicate whether the problem is present,
+and avoids changing the controller's power state if the flag is set.
+Runtime suspend is unaffected; this matters only for system suspend.
+However as a side effect, the controller will not respond to remote
+wakeup requests while the system is asleep.  Hence USB wakeup is not
+functional -- but of course, this is already true in the current state
+of affairs.
+
+This fixes Bugzilla #42728.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Steven Rostedt <rostedt@goodmis.org>
+Tested-by: Andrey Rahmatullin <wrar@wrar.name>
+Tested-by: Oleksij Rempel (fishor) <bug-track@fisher-privat.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hcd-pci.c  |    9 +++++++++
+ drivers/usb/host/ehci-pci.c |    8 ++++++++
+ include/linux/usb/hcd.h     |    2 ++
+ 3 files changed, 19 insertions(+)
+
+--- a/drivers/usb/core/hcd-pci.c
++++ b/drivers/usb/core/hcd-pci.c
+@@ -491,6 +491,15 @@ static int hcd_pci_suspend_noirq(struct
+       pci_save_state(pci_dev);
++      /*
++       * Some systems crash if an EHCI controller is in D3 during
++       * a sleep transition.  We have to leave such controllers in D0.
++       */
++      if (hcd->broken_pci_sleep) {
++              dev_dbg(dev, "Staying in PCI D0\n");
++              return retval;
++      }
++
+       /* If the root hub is dead rather than suspended, disallow remote
+        * wakeup.  usb_hc_died() should ensure that both hosts are marked as
+        * dying, so we only need to check the primary roothub.
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -144,6 +144,14 @@ static int ehci_pci_setup(struct usb_hcd
+                       hcd->has_tt = 1;
+                       tdi_reset(ehci);
+               }
++              if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) {
++                      /* EHCI #1 or #2 on 6 Series/C200 Series chipset */
++                      if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) {
++                              ehci_info(ehci, "broken D3 during system sleep on ASUS\n");
++                              hcd->broken_pci_sleep = 1;
++                              device_set_wakeup_capable(&pdev->dev, false);
++                      }
++              }
+               break;
+       case PCI_VENDOR_ID_TDI:
+               if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -126,6 +126,8 @@ struct usb_hcd {
+       unsigned                wireless:1;     /* Wireless USB HCD */
+       unsigned                authorized_default:1;
+       unsigned                has_tt:1;       /* Integrated TT in root hub */
++      unsigned                broken_pci_sleep:1;     /* Don't put the
++                      controller in PCI-D3 for system sleep */
+       int                     irq;            /* irq allocated */
+       void __iomem            *regs;          /* device memory/io */
diff --git a/queue-3.3/usb-gadget-dummy-do-not-call-pullup-on-udc_stop.patch b/queue-3.3/usb-gadget-dummy-do-not-call-pullup-on-udc_stop.patch
new file mode 100644 (file)
index 0000000..76a9e0f
--- /dev/null
@@ -0,0 +1,32 @@
+From 15b120d67019d691e4389372967332d74a80522a Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@ti.com>
+Date: Wed, 18 Apr 2012 13:59:30 +0300
+Subject: usb: gadget: dummy: do not call pullup() on udc_stop()
+
+From: Felipe Balbi <balbi@ti.com>
+
+commit 15b120d67019d691e4389372967332d74a80522a upstream.
+
+pullup() is already called properly by udc-core.c and
+there's no need to call it from udc_stop(), in fact that
+will cause issues.
+
+Reviewed-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/dummy_hcd.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/usb/gadget/dummy_hcd.c
++++ b/drivers/usb/gadget/dummy_hcd.c
+@@ -924,7 +924,6 @@ static int dummy_udc_stop(struct usb_gad
+       dum->driver = NULL;
+-      dummy_pullup(&dum->gadget, 0);
+       return 0;
+ }
diff --git a/queue-3.3/usb-gadget-storage-gadgets-send-wrong-error-code-for-unknown-commands.patch b/queue-3.3/usb-gadget-storage-gadgets-send-wrong-error-code-for-unknown-commands.patch
new file mode 100644 (file)
index 0000000..d209d9d
--- /dev/null
@@ -0,0 +1,50 @@
+From c85dcdac5852295cf6822f5c4331a6ddab72581f Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 11 Apr 2012 16:09:10 -0400
+Subject: USB: gadget: storage gadgets send wrong error code for unknown commands
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit c85dcdac5852295cf6822f5c4331a6ddab72581f upstream.
+
+This patch (as1539) fixes a minor bug in the mass-storage gadget
+drivers.  When an unknown command is received, the error code sent
+back is "Invalid Field in CDB" rather than "Invalid Command".  This is
+because the bitmask of CDB bytes allowed to be nonzero is incorrect.
+
+When handling an unknown command, we don't care which command bytes
+are nonzero.  All the bits in the mask should be set, not just eight
+of them.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: <Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/f_mass_storage.c |    2 +-
+ drivers/usb/gadget/file_storage.c   |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/f_mass_storage.c
++++ b/drivers/usb/gadget/f_mass_storage.c
+@@ -2190,7 +2190,7 @@ unknown_cmnd:
+               common->data_size_from_cmnd = 0;
+               sprintf(unknown, "Unknown x%02x", common->cmnd[0]);
+               reply = check_command(common, common->cmnd_size,
+-                                    DATA_DIR_UNKNOWN, 0xff, 0, unknown);
++                                    DATA_DIR_UNKNOWN, ~0, 0, unknown);
+               if (reply == 0) {
+                       common->curlun->sense_data = SS_INVALID_COMMAND;
+                       reply = -EINVAL;
+--- a/drivers/usb/gadget/file_storage.c
++++ b/drivers/usb/gadget/file_storage.c
+@@ -2579,7 +2579,7 @@ static int do_scsi_command(struct fsg_de
+               fsg->data_size_from_cmnd = 0;
+               sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);
+               if ((reply = check_command(fsg, fsg->cmnd_size,
+-                              DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) {
++                              DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) {
+                       fsg->curlun->sense_data = SS_INVALID_COMMAND;
+                       reply = -EINVAL;
+               }
diff --git a/queue-3.3/usb-gadget-uvc-uvc_request_data-length-field-must-be-signed.patch b/queue-3.3/usb-gadget-uvc-uvc_request_data-length-field-must-be-signed.patch
new file mode 100644 (file)
index 0000000..b9a369f
--- /dev/null
@@ -0,0 +1,44 @@
+From 6f6543f53f9ce136e01d7114bf6f0818ca54fb41 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 24 Apr 2012 11:29:42 +0200
+Subject: usb gadget: uvc: uvc_request_data::length field must be signed
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+commit 6f6543f53f9ce136e01d7114bf6f0818ca54fb41 upstream.
+
+The field is used to pass the UVC request data length, but can also be
+used to signal an error when setting it to a negative value. Switch from
+unsigned int to __s32.
+
+Reported-by: Fernandez Gonzalo <gfernandez@copreci.es>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/uvc.h      |    2 +-
+ drivers/usb/gadget/uvc_v4l2.c |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/uvc.h
++++ b/drivers/usb/gadget/uvc.h
+@@ -28,7 +28,7 @@
+ struct uvc_request_data
+ {
+-      unsigned int length;
++      __s32 length;
+       __u8 data[60];
+ };
+--- a/drivers/usb/gadget/uvc_v4l2.c
++++ b/drivers/usb/gadget/uvc_v4l2.c
+@@ -39,7 +39,7 @@ uvc_send_response(struct uvc_device *uvc
+       if (data->length < 0)
+               return usb_ep_set_halt(cdev->gadget->ep0);
+-      req->length = min(uvc->event_length, data->length);
++      req->length = min_t(unsigned int, uvc->event_length, data->length);
+       req->zero = data->length < uvc->event_length;
+       req->dma = DMA_ADDR_INVALID;