]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Mar 2012 19:03:16 +0000 (12:03 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Mar 2012 19:03:16 +0000 (12:03 -0700)
added patches:
usb-gadget-clear-usb_endpoint_descriptor-inside-the-struct-usb_ep-on-disable.patch
usb-gadgetfs-return-number-of-bytes-on-ep0-read-request.patch
usb-gadget-make-g_hid-device-class-conform-to-spec.patch
usb-musb-reselect-index-reg-in-interrupt-context.patch
usb-renesas_usbhs-bugfix-add-.release-function-to-gpriv-gadget.dev.patch

queue-3.3/series
queue-3.3/usb-gadget-clear-usb_endpoint_descriptor-inside-the-struct-usb_ep-on-disable.patch [new file with mode: 0644]
queue-3.3/usb-gadget-make-g_hid-device-class-conform-to-spec.patch [new file with mode: 0644]
queue-3.3/usb-gadgetfs-return-number-of-bytes-on-ep0-read-request.patch [new file with mode: 0644]
queue-3.3/usb-musb-reselect-index-reg-in-interrupt-context.patch [new file with mode: 0644]
queue-3.3/usb-renesas_usbhs-bugfix-add-.release-function-to-gpriv-gadget.dev.patch [new file with mode: 0644]

index 23ae6cd0a249729f20ed5844d515e627f12b76ec..a37b8c94798836393df1f16f0bc428ec73d9c1cb 100644 (file)
@@ -19,3 +19,8 @@ usb-dwc3-gadget-don-t-wrap-around-the-trb-poll-on-non-isoc.patch
 usb-dwc3-fix-bogus-test-in-dwc3_gadget_start_isoc.patch
 usb-dwc3-use-proper-function-for-setting-endpoint-name.patch
 staging-vme-fix-section-mismatches-in-linux-next-20120314.patch
+usb-musb-reselect-index-reg-in-interrupt-context.patch
+usb-gadget-clear-usb_endpoint_descriptor-inside-the-struct-usb_ep-on-disable.patch
+usb-renesas_usbhs-bugfix-add-.release-function-to-gpriv-gadget.dev.patch
+usb-gadgetfs-return-number-of-bytes-on-ep0-read-request.patch
+usb-gadget-make-g_hid-device-class-conform-to-spec.patch
diff --git a/queue-3.3/usb-gadget-clear-usb_endpoint_descriptor-inside-the-struct-usb_ep-on-disable.patch b/queue-3.3/usb-gadget-clear-usb_endpoint_descriptor-inside-the-struct-usb_ep-on-disable.patch
new file mode 100644 (file)
index 0000000..e21359e
--- /dev/null
@@ -0,0 +1,208 @@
+From f9c56cdd3905c96c600456203637bd7ec8ec6383 Mon Sep 17 00:00:00 2001
+From: Ido Shayevitz <idos@codeaurora.org>
+Date: Wed, 8 Feb 2012 13:56:48 +0200
+Subject: usb: gadget: Clear usb_endpoint_descriptor inside the struct usb_ep on disable
+
+From: Ido Shayevitz <idos@codeaurora.org>
+
+commit f9c56cdd3905c96c600456203637bd7ec8ec6383 upstream.
+
+This fix a bug in f_serial, which expect the ep->desc to be NULL after
+disabling an endpoint.
+
+Signed-off-by: Ido Shayevitz <idos@codeaurora.org>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/gadget.c           |    1 +
+ drivers/usb/gadget/amd5536udc.c     |    1 +
+ drivers/usb/gadget/at91_udc.c       |    1 +
+ drivers/usb/gadget/atmel_usba_udc.c |    1 +
+ drivers/usb/gadget/ci13xxx_udc.c    |    1 +
+ drivers/usb/gadget/fsl_qe_udc.c     |    1 +
+ drivers/usb/gadget/fsl_udc_core.c   |    1 +
+ drivers/usb/gadget/goku_udc.c       |    1 +
+ drivers/usb/gadget/langwell_udc.c   |    1 +
+ drivers/usb/gadget/mv_udc_core.c    |    1 +
+ drivers/usb/gadget/omap_udc.c       |    1 +
+ drivers/usb/gadget/pch_udc.c        |    1 +
+ drivers/usb/gadget/pxa25x_udc.c     |    2 ++
+ drivers/usb/gadget/s3c-hsudc.c      |    2 ++
+ drivers/usb/gadget/s3c2410_udc.c    |    2 ++
+ 15 files changed, 18 insertions(+)
+
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -440,6 +440,7 @@ static int __dwc3_gadget_ep_disable(stru
+       dep->stream_capable = false;
+       dep->desc = NULL;
++      dep->endpoint.desc = NULL;
+       dep->comp_desc = NULL;
+       dep->type = 0;
+       dep->flags = 0;
+--- a/drivers/usb/gadget/amd5536udc.c
++++ b/drivers/usb/gadget/amd5536udc.c
+@@ -445,6 +445,7 @@ static void ep_init(struct udc_regs __io
+       VDBG(ep->dev, "ep-%d reset\n", ep->num);
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->ep.ops = &udc_ep_ops;
+       INIT_LIST_HEAD(&ep->queue);
+--- a/drivers/usb/gadget/at91_udc.c
++++ b/drivers/usb/gadget/at91_udc.c
+@@ -558,6 +558,7 @@ static int at91_ep_disable (struct usb_e
+       /* restore the endpoint's pristine config */
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->ep.maxpacket = ep->maxpacket;
+       /* reset fifos and endpoint */
+--- a/drivers/usb/gadget/atmel_usba_udc.c
++++ b/drivers/usb/gadget/atmel_usba_udc.c
+@@ -659,6 +659,7 @@ static int usba_ep_disable(struct usb_ep
+               return -EINVAL;
+       }
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       list_splice_init(&ep->queue, &req_list);
+       if (ep->can_dma) {
+--- a/drivers/usb/gadget/ci13xxx_udc.c
++++ b/drivers/usb/gadget/ci13xxx_udc.c
+@@ -2181,6 +2181,7 @@ static int ep_disable(struct usb_ep *ep)
+       } while (mEp->dir != direction);
+       mEp->desc = NULL;
++      mEp->ep.desc = NULL;
+       spin_unlock_irqrestore(mEp->lock, flags);
+       return retval;
+--- a/drivers/usb/gadget/fsl_qe_udc.c
++++ b/drivers/usb/gadget/fsl_qe_udc.c
+@@ -1638,6 +1638,7 @@ static int qe_ep_disable(struct usb_ep *
+       /* Nuke all pending requests (does flush) */
+       nuke(ep, -ESHUTDOWN);
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->stopped = 1;
+       ep->tx_req = NULL;
+       qe_ep_reset(udc, ep->epnum);
+--- a/drivers/usb/gadget/fsl_udc_core.c
++++ b/drivers/usb/gadget/fsl_udc_core.c
+@@ -659,6 +659,7 @@ static int fsl_ep_disable(struct usb_ep
+       nuke(ep, -ESHUTDOWN);
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->stopped = 1;
+       spin_unlock_irqrestore(&udc->lock, flags);
+--- a/drivers/usb/gadget/goku_udc.c
++++ b/drivers/usb/gadget/goku_udc.c
+@@ -235,6 +235,7 @@ static void ep_reset(struct goku_udc_reg
+       ep->ep.maxpacket = MAX_FIFO_SIZE;
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->stopped = 1;
+       ep->irqs = 0;
+       ep->dma = 0;
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -487,6 +487,7 @@ static int langwell_ep_disable(struct us
+       nuke(ep, -ESHUTDOWN);
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->stopped = 1;
+       spin_unlock_irqrestore(&dev->lock, flags);
+--- a/drivers/usb/gadget/mv_udc_core.c
++++ b/drivers/usb/gadget/mv_udc_core.c
+@@ -608,6 +608,7 @@ static int  mv_ep_disable(struct usb_ep
+       nuke(ep, -ESHUTDOWN);
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->stopped = 1;
+       spin_unlock_irqrestore(&udc->lock, flags);
+--- a/drivers/usb/gadget/omap_udc.c
++++ b/drivers/usb/gadget/omap_udc.c
+@@ -251,6 +251,7 @@ static int omap_ep_disable(struct usb_ep
+       spin_lock_irqsave(&ep->udc->lock, flags);
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       nuke (ep, -ESHUTDOWN);
+       ep->ep.maxpacket = ep->maxpacket;
+       ep->has_dma = 0;
+--- a/drivers/usb/gadget/pch_udc.c
++++ b/drivers/usb/gadget/pch_udc.c
+@@ -1493,6 +1493,7 @@ static int pch_udc_pcd_ep_disable(struct
+       pch_udc_ep_disable(ep);
+       pch_udc_disable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num));
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       INIT_LIST_HEAD(&ep->queue);
+       spin_unlock_irqrestore(&ep->dev->lock, iflags);
+       return 0;
+--- a/drivers/usb/gadget/pxa25x_udc.c
++++ b/drivers/usb/gadget/pxa25x_udc.c
+@@ -283,6 +283,7 @@ static int pxa25x_ep_disable (struct usb
+       pxa25x_ep_fifo_flush (_ep);
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->stopped = 1;
+       local_irq_restore(flags);
+@@ -1192,6 +1193,7 @@ static void udc_reinit(struct pxa25x_udc
+                       list_add_tail (&ep->ep.ep_list, &dev->gadget.ep_list);
+               ep->desc = NULL;
++              ep->ep.desc = NULL;
+               ep->stopped = 0;
+               INIT_LIST_HEAD (&ep->queue);
+               ep->pio_irqs = 0;
+--- a/drivers/usb/gadget/s3c-hsudc.c
++++ b/drivers/usb/gadget/s3c-hsudc.c
+@@ -816,6 +816,7 @@ static int s3c_hsudc_ep_disable(struct u
+       s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN);
+       hsep->desc = 0;
++      hsep->ep.desc = NULL;
+       hsep->stopped = 1;
+       spin_unlock_irqrestore(&hsudc->lock, flags);
+@@ -1005,6 +1006,7 @@ static void s3c_hsudc_initep(struct s3c_
+       hsep->ep.ops = &s3c_hsudc_ep_ops;
+       hsep->fifo = hsudc->regs + S3C_BR(epnum);
+       hsep->desc = 0;
++      hsep->ep.desc = NULL;
+       hsep->stopped = 0;
+       hsep->wedge = 0;
+--- a/drivers/usb/gadget/s3c2410_udc.c
++++ b/drivers/usb/gadget/s3c2410_udc.c
+@@ -1148,6 +1148,7 @@ static int s3c2410_udc_ep_disable(struct
+       dprintk(DEBUG_NORMAL, "ep_disable: %s\n", _ep->name);
+       ep->desc = NULL;
++      ep->ep.desc = NULL;
+       ep->halted = 1;
+       s3c2410_udc_nuke (ep->dev, ep, -ESHUTDOWN);
+@@ -1630,6 +1631,7 @@ static void s3c2410_udc_reinit(struct s3
+               ep->dev = dev;
+               ep->desc = NULL;
++              ep->ep.desc = NULL;
+               ep->halted = 0;
+               INIT_LIST_HEAD (&ep->queue);
+       }
diff --git a/queue-3.3/usb-gadget-make-g_hid-device-class-conform-to-spec.patch b/queue-3.3/usb-gadget-make-g_hid-device-class-conform-to-spec.patch
new file mode 100644 (file)
index 0000000..2be817f
--- /dev/null
@@ -0,0 +1,36 @@
+From 33d2832ab0149a26418d360af3c444969a63fb28 Mon Sep 17 00:00:00 2001
+From: Orjan Friberg <of@flatfrog.com>
+Date: Wed, 7 Mar 2012 17:16:14 +0100
+Subject: USB: gadget: Make g_hid device class conform to spec.
+
+From: Orjan Friberg <of@flatfrog.com>
+
+commit 33d2832ab0149a26418d360af3c444969a63fb28 upstream.
+
+HID devices should specify this in their interface descriptors, not in the
+device descriptor. This fixes a "missing hardware id" bug under Windows 7 with
+a VIA VL800 (3.0) controller.
+
+Signed-off-by: Orjan Friberg <of@flatfrog.com>
+Cc: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/hid.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/hid.c
++++ b/drivers/usb/gadget/hid.c
+@@ -60,9 +60,9 @@ static struct usb_device_descriptor devi
+       /* .bDeviceClass =              USB_CLASS_COMM, */
+       /* .bDeviceSubClass =   0, */
+       /* .bDeviceProtocol =   0, */
+-      .bDeviceClass =         0xEF,
+-      .bDeviceSubClass =      2,
+-      .bDeviceProtocol =      1,
++      .bDeviceClass =         USB_CLASS_PER_INTERFACE,
++      .bDeviceSubClass =      0,
++      .bDeviceProtocol =      0,
+       /* .bMaxPacketSize0 = f(hardware) */
+       /* Vendor and product id can be overridden by module parameters.  */
diff --git a/queue-3.3/usb-gadgetfs-return-number-of-bytes-on-ep0-read-request.patch b/queue-3.3/usb-gadgetfs-return-number-of-bytes-on-ep0-read-request.patch
new file mode 100644 (file)
index 0000000..0f54172
--- /dev/null
@@ -0,0 +1,34 @@
+From 85b4b3c8c189e0159101f7628a71411af072ff69 Mon Sep 17 00:00:00 2001
+From: Thomas Faber <thfabba@gmx.de>
+Date: Fri, 2 Mar 2012 09:41:50 +0100
+Subject: usb: gadgetfs: return number of bytes on ep0 read request
+
+From: Thomas Faber <thfabba@gmx.de>
+
+commit 85b4b3c8c189e0159101f7628a71411af072ff69 upstream.
+
+A read from GadgetFS endpoint 0 during the data stage of a control
+request would always return 0 on success (as returned by
+wait_event_interruptible) despite having written data into the user
+buffer.
+This patch makes it correctly set the return value to the number of
+bytes read.
+
+Signed-off-by: Thomas Faber <thfabba@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/inode.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/gadget/inode.c
++++ b/drivers/usb/gadget/inode.c
+@@ -1043,6 +1043,8 @@ ep0_read (struct file *fd, char __user *
+ // FIXME don't call this with the spinlock held ...
+                               if (copy_to_user (buf, dev->req->buf, len))
+                                       retval = -EFAULT;
++                              else
++                                      retval = len;
+                               clean_req (dev->gadget->ep0, dev->req);
+                               /* NOTE userspace can't yet choose to stall */
+                       }
diff --git a/queue-3.3/usb-musb-reselect-index-reg-in-interrupt-context.patch b/queue-3.3/usb-musb-reselect-index-reg-in-interrupt-context.patch
new file mode 100644 (file)
index 0000000..d95ca47
--- /dev/null
@@ -0,0 +1,109 @@
+From 39287076e46d2c19aaceaa6f0a44168ae4d257ec Mon Sep 17 00:00:00 2001
+From: Supriya Karanth <supriya.karanth@stericsson.com>
+Date: Fri, 17 Feb 2012 14:54:52 +0530
+Subject: usb: musb: Reselect index reg in interrupt context
+
+From: Supriya Karanth <supriya.karanth@stericsson.com>
+
+commit 39287076e46d2c19aaceaa6f0a44168ae4d257ec upstream.
+
+musb INDEX register is getting modified/corrupted during temporary
+un-locking in a SMP system. Set this register with proper value
+after re-acquiring the lock
+
+Scenario:
+---------
+CPU1 is handling a data transfer completion interrupt received for
+the CLASS1 EP
+CPU2 is handling a CLASS2 thread which is queuing data to musb for
+transfer
+
+Below is the error sequence:
+
+         CPU1                   |             CPU2
+--------------------------------------------------------------------
+Data transfer completion inter- |
+rupt recieved.                  |
+                                |
+musb INDEX reg set to CLASS1 EP |
+                                |
+musb LOCK is acquired.          |
+                                |
+                                | CLASS2 thread queues data.
+                                |
+                                | CLASS2 thread tries to acquire musb
+                                | LOCK but lock is already taken by
+                                | CLASS1, so CLASS2 thread is
+                                | spinning.
+                                |
+From Interrupt Context musb     |
+giveback function is called     |
+                                |
+The giveback function releases  | CLASS2 thread now acquires LOCK
+LOCK                            |
+                                |
+ClASS1 Request's completion cal-| ClASS2 schedules the data transfer and
+lback is called                 | sets the MUSB INDEX to Class2 EP number
+                                |
+Interrupt handler for CLASS1 EP |
+tries to acquire LOCK and is    |
+spinning                        |
+                                |
+Interrupt for Class1 EP acquires| Class2 completes the scheduling etc and
+the MUSB LOCK                   | releases the musb LOCK
+                                |
+Interrupt for Class1 EP schedul-|
+es the next data transfer       |
+but musb INDEX register is still|
+set to CLASS2 EP                |
+
+Since the MUSB INDEX register is set to a different endpoint, we
+read and modify the wrong registers. Hence data transfer will not
+happen properly. This results in unpredictable behavior
+
+So, the MUSB INDEX register is set to proper value again when
+interrupt re-acquires the lock
+
+Signed-off-by: Supriya Karanth <supriya.karanth@stericsson.com>
+Signed-off-by: Praveena Nadahally <praveen.nadahally@stericsson.com>
+Reviewed-by: srinidhi kasagar <srinidhi.kasagar@stericsson.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+
+---
+ drivers/usb/musb/musb_gadget.c |   18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -574,6 +574,15 @@ void musb_g_tx(struct musb *musb, u8 epn
+               if (request->actual == request->length) {
+                       musb_g_giveback(musb_ep, request, 0);
++                      /*
++                       * In the giveback function the MUSB lock is
++                       * released and acquired after sometime. During
++                       * this time period the INDEX register could get
++                       * changed by the gadget_queue function especially
++                       * on SMP systems. Reselect the INDEX to be sure
++                       * we are reading/modifying the right registers
++                       */
++                      musb_ep_select(mbase, epnum);
+                       req = musb_ep->desc ? next_request(musb_ep) : NULL;
+                       if (!req) {
+                               dev_dbg(musb->controller, "%s idle now\n",
+@@ -983,6 +992,15 @@ void musb_g_rx(struct musb *musb, u8 epn
+               }
+ #endif
+               musb_g_giveback(musb_ep, request, 0);
++              /*
++               * In the giveback function the MUSB lock is
++               * released and acquired after sometime. During
++               * this time period the INDEX register could get
++               * changed by the gadget_queue function especially
++               * on SMP systems. Reselect the INDEX to be sure
++               * we are reading/modifying the right registers
++               */
++              musb_ep_select(mbase, epnum);
+               req = next_request(musb_ep);
+               if (!req)
diff --git a/queue-3.3/usb-renesas_usbhs-bugfix-add-.release-function-to-gpriv-gadget.dev.patch b/queue-3.3/usb-renesas_usbhs-bugfix-add-.release-function-to-gpriv-gadget.dev.patch
new file mode 100644 (file)
index 0000000..2364fe1
--- /dev/null
@@ -0,0 +1,57 @@
+From 3b2a2e47174cd978258bbb0fdf2e2b1b5ec2144c Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 20 Feb 2012 17:35:50 -0800
+Subject: usb: renesas_usbhs: bugfix: add .release function to gpriv->gadget.dev
+
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+commit 3b2a2e47174cd978258bbb0fdf2e2b1b5ec2144c upstream.
+
+This patch fixup below warning on device_unregister()
+
+renesas_usbhs renesas_usbhs.1: host probed
+renesas_usbhs renesas_usbhs.1: gadget probed
+renesas_usbhs renesas_usbhs.1: irq request err
+------------[ cut here ]------------
+WARNING: at ${LINUX}/drivers/base/core.c:1)
+Device 'gadget' does not have a release() function, it is broken and must be fi.
+Modules linked in:
+[<c000e25c>] (unwind_backtrace+0x0/0xe4) from [<c0016960>] (warn_slowpath_commo)
+[<c0016960>] (warn_slowpath_common+0x4c/0x64) from [<c00169f8>] (warn_slowpath_)
+[<c00169f8>] (warn_slowpath_fmt+0x2c/0x3c) from [<c0185b80>] (device_release+0x)
+[<c0185b80>] (device_release+0x70/0x84) from [<c013e300>] (kobject_cleanup+0x58)
+[<c013e300>] (kobject_cleanup+0x58/0x6c) from [<c01cba14>] (usbhs_mod_gadget_re)
+[<c01cba14>] (usbhs_mod_gadget_remove+0x3c/0x6c) from [<c01c8384>] (usbhs_mod_p)
+[<c01c8384>] (usbhs_mod_probe+0x68/0x80) from [<c01c7f84>] (usbhs_probe+0x1cc/0)
+...
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/renesas_usbhs/mod_gadget.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/renesas_usbhs/mod_gadget.c
++++ b/drivers/usb/renesas_usbhs/mod_gadget.c
+@@ -941,6 +941,11 @@ static int usbhsg_stop(struct usbhs_priv
+       return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED);
+ }
++static void usbhs_mod_gadget_release(struct device *pdev)
++{
++      /* do nothing */
++}
++
+ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
+ {
+       struct usbhsg_gpriv *gpriv;
+@@ -989,6 +994,7 @@ int usbhs_mod_gadget_probe(struct usbhs_
+        */
+       dev_set_name(&gpriv->gadget.dev, "gadget");
+       gpriv->gadget.dev.parent        = dev;
++      gpriv->gadget.dev.release       = usbhs_mod_gadget_release;
+       gpriv->gadget.name              = "renesas_usbhs_udc";
+       gpriv->gadget.ops               = &usbhsg_gadget_ops;
+       gpriv->gadget.max_speed         = USB_SPEED_HIGH;