aboutsummaryrefslogtreecommitdiffstats
path: root/usb.current
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-06-14 16:03:47 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-06-14 16:03:47 -0700
commit209280a6e58de1ade661eea4bb94571bad7a5f8c (patch)
tree6c5579373755a4becb87e94e3d5155e7c99337ea /usb.current
parent02bdf5fc5f222119ecfa709354e540a594ae4b10 (diff)
downloadpatches-209280a6e58de1ade661eea4bb94571bad7a5f8c.tar.gz
patches
Diffstat (limited to 'usb.current')
-rw-r--r--usb.current/usb-g_serial-don-t-set-low_latency-flag.patch59
-rw-r--r--usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch31
-rw-r--r--usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch50
-rw-r--r--usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch34
-rw-r--r--usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch196
5 files changed, 370 insertions, 0 deletions
diff --git a/usb.current/usb-g_serial-don-t-set-low_latency-flag.patch b/usb.current/usb-g_serial-don-t-set-low_latency-flag.patch
new file mode 100644
index 00000000000000..3a04c087c82c5b
--- /dev/null
+++ b/usb.current/usb-g_serial-don-t-set-low_latency-flag.patch
@@ -0,0 +1,59 @@
+From jon.povey@racelogic.co.uk Mon Jun 14 15:21:46 2010
+From: Jon Povey <jon.povey@racelogic.co.uk>
+Date: Mon, 14 Jun 2010 19:41:04 +0900
+Subject: USB: g_serial: don't set low_latency flag
+To: linux-usb@vger.kernel.org
+Cc: Jon Povey <jon.povey@racelogic.co.uk>, chrisv@cyberswitching.com, david-b@pacbell.net
+Message-ID: <1276512064-3229-1-git-send-email-jon.povey@racelogic.co.uk>
+
+
+No longer set low_latency flag as it causes this warning backtrace:
+
+ WARNING: at kernel/mutex.c:207 __mutex_lock_slowpath+0x6c/0x288()
+
+Fix associated locking and wakeups.
+
+Signed-off-by: Jon Povey <jon.povey@racelogic.co.uk>
+Cc: Maulik Mankad <x0082077@ti.com>
+CcL stable <stable@kernel.org>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/u_serial.c | 15 ++-------------
+ 1 file changed, 2 insertions(+), 13 deletions(-)
+
+--- a/drivers/usb/gadget/u_serial.c
++++ b/drivers/usb/gadget/u_serial.c
+@@ -536,17 +536,11 @@ recycle:
+ list_move(&req->list, &port->read_pool);
+ }
+
+- /* Push from tty to ldisc; this is immediate with low_latency, and
+- * may trigger callbacks to this driver ... so drop the spinlock.
++ /* Push from tty to ldisc; without low_latency set this is handled by
++ * a workqueue, so we won't get callbacks and can hold port_lock
+ */
+ if (tty && do_push) {
+- spin_unlock_irq(&port->port_lock);
+ tty_flip_buffer_push(tty);
+- wake_up_interruptible(&tty->read_wait);
+- spin_lock_irq(&port->port_lock);
+-
+- /* tty may have been closed */
+- tty = port->port_tty;
+ }
+
+
+@@ -784,11 +778,6 @@ static int gs_open(struct tty_struct *tt
+ port->open_count = 1;
+ port->openclose = false;
+
+- /* low_latency means ldiscs work in tasklet context, without
+- * needing a workqueue schedule ... easier to keep up.
+- */
+- tty->low_latency = 1;
+-
+ /* if connected, start the I/O stream */
+ if (port->port_usb) {
+ struct gserial *gser = port->port_usb;
diff --git a/usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch b/usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch
new file mode 100644
index 00000000000000..833a9258c4db2e
--- /dev/null
+++ b/usb.current/usb-g_serial-fix-tty-cleanup-on-unload.patch
@@ -0,0 +1,31 @@
+From jon.povey@racelogic.co.uk Mon Jun 14 15:22:32 2010
+From: Jon Povey <jon.povey@racelogic.co.uk>
+Date: Mon, 14 Jun 2010 19:42:10 +0900
+Subject: USB: g_serial: fix tty cleanup on unload
+To: linux-usb@vger.kernel.org
+Cc: Jon Povey <jon.povey@racelogic.co.uk>, chrisv@cyberswitching.com, david-b@pacbell.net
+Message-ID: <1276512130-3317-1-git-send-email-jon.povey@racelogic.co.uk>
+
+
+Call put_tty_driver() in cleanup function, to fix Oops when trying to open
+gadget serial char device after module unload.
+
+Signed-off-by: Jon Povey <jon.povey@racelogic.co.uk>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/u_serial.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/gadget/u_serial.c
++++ b/drivers/usb/gadget/u_serial.c
+@@ -1184,6 +1184,7 @@ void gserial_cleanup(void)
+ n_ports = 0;
+
+ tty_unregister_driver(gs_tty_driver);
++ put_tty_driver(gs_tty_driver);
+ gs_tty_driver = NULL;
+
+ pr_debug("%s: cleaned up ttyGS* support\n", __func__);
diff --git a/usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch b/usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch
new file mode 100644
index 00000000000000..e5677d0b03fdec
--- /dev/null
+++ b/usb.current/usb-gadget-g_fs-possible-invalid-pointer-reference-bug-fixed.patch
@@ -0,0 +1,50 @@
+From m.nazarewicz@samsung.com Mon Jun 14 15:23:58 2010
+From: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Date: Mon, 14 Jun 2010 10:43:34 +0200
+Subject: [PATCH] USB: gadget: g_fs: possible invalid pointer reference bug fixed
+To: linux-usb@vger.kernel.org
+Cc: David Brownell <dbrownell@users.sourceforge.net>, Kyungmin Park <kyungmin.park@samsung.com>, Marek Szyprowski <m.szyprowski@samsung.com>, linux-kernel@vger.kernel.org
+Message-ID: <f8fbee30a711b740b5875514715c3c58b4eb196c.1276170819.git.m.nazarewicz@samsung.com>
+
+
+During __gfs_do_config() some invalid pointers may be left
+in usb_configuration::interfaces array from previous calls
+to the __gfs_do_config() for the same configuration. This
+will always happen if an user space function which has
+a fewer then the last user space function registers itself.
+Composite's set_config() function that a pointer after the
+last interface in usb_configuration::interface is NULL
+unless the array is full.
+
+This patch makes the __gfs_do_config() make sure that if the
+usb_configuration::interface is not full then a pointer
+after the last interface is NULL.
+
+Signed-off-by: Michal Nazarewicz <m.nazarewicz@samsung.com>
+Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/g_ffs.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/gadget/g_ffs.c
++++ b/drivers/usb/gadget/g_ffs.c
+@@ -392,6 +392,17 @@ static int __gfs_do_config(struct usb_co
+ if (unlikely(ret < 0))
+ return ret;
+
++ /* After previous do_configs there may be some invalid
++ * pointers in c->interface array. This happens every time
++ * a user space function with fewer interfaces than a user
++ * space function that was run before the new one is run. The
++ * compasit's set_config() assumes that if there is no more
++ * then MAX_CONFIG_INTERFACES interfaces in a configuration
++ * then there is a NULL pointer after the last interface in
++ * c->interface array. We need to make sure this is true. */
++ if (c->next_interface_id < ARRAY_SIZE(c->interface))
++ c->interface[c->next_interface_id] = NULL;
++
+ return 0;
+ }
+
diff --git a/usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch b/usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch
new file mode 100644
index 00000000000000..720e5023a9b3fd
--- /dev/null
+++ b/usb.current/usb-r8a66597-fix-failure-in-change-of-status.patch
@@ -0,0 +1,34 @@
+From nobuhiro.iwamatsu.yj@renesas.com Mon Jun 14 15:48:15 2010
+From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Date: Mon, 7 Jun 2010 16:55:56 +0900
+Subject: USB: r8a66597: Fix failure in change of status
+To: gregkh@suse.de
+Cc: stern@rowland.harvard.edu, shimoda.yoshihiro@renesas.com, Paul Mundt <lethal@linux-sh.org>
+Message-ID: <AANLkTimQgvU-pG67QWVjXY5rzLCclelHc7hhsUb_fpJF@mail.gmail.com>
+
+
+In the change by 749da5f82fe33ff68dd4aa1a5e35cd9aa6246dab,
+The change in the status when the USB device is connected is wrong.
+Therefore, the device is not recognized.
+
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+CC: Paul Mundt" <lethal@linux-sh.org>
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/r8a66597-hcd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/r8a66597-hcd.c
++++ b/drivers/usb/host/r8a66597-hcd.c
+@@ -1065,7 +1065,7 @@ static void r8a66597_usb_connect(struct
+ else if (speed == LSMODE)
+ rh->port |= USB_PORT_STAT_LOW_SPEED;
+
+- rh->port &= USB_PORT_STAT_RESET;
++ rh->port &= ~USB_PORT_STAT_RESET;
+ rh->port |= USB_PORT_STAT_ENABLE;
+ }
+
diff --git a/usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch b/usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch
new file mode 100644
index 00000000000000..ba943d301b1b08
--- /dev/null
+++ b/usb.current/usb-xhci-fix-bug-in-link-trb-activation-change.patch
@@ -0,0 +1,196 @@
+From sarah.a.sharp@linux.intel.com Mon Jun 14 15:25:09 2010
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 10 Jun 2010 12:25:28 -0700
+Subject: USB: xHCI: Fix bug in link TRB activation change.
+To: Greg KH <gregkh@suse.de>
+Cc: linux-usb@vger.kernel.org, John Youn <John.Youn@synopsys.com>
+Message-ID: <20100610192528.GA17572@xanatos>
+Content-Disposition: inline
+
+
+Commit 6c12db90f19727c76990e7f4801c67a148b30111 introduced a bug for
+control transfers. The patch was supposed to change when the link TRBs at
+the end of each ring segment were given to the hardware. If a transfer
+descriptor (TD) ended just before the link TRB, the code wouldn't give
+back the link TRB to the hardware; instead it would be given back in
+prepare_ring() just before the next TD was enqueued at the top of the
+ring.
+
+Unfortunately, the code relied on checking the chain bit of the TRB to
+determine whether the TD ended just before the link TRB. It assumed that
+the ring enqueuing code would call prepare_ring() before enqueuing the
+next TD. However, control transfers are made of multiple TDs, and
+prepare_ring() is only called once before enqueuing two or three TDs.
+
+If the first or second TD of the control transfer ended just before the
+link TRB, then the code in inc_enq() would not move the enqueue pointer
+past the link TRB, and the link TRB would get overwritten. This would
+cause the xHCI driver to start writing to memory past the ring segment,
+and eventually the system would crash or hang.
+
+The fix is to add a flag to inc_enq() that says whether the caller will
+enqueue more TDs before calling prepare_ring(). If the chain bit is
+cleared (meaning this is the last TRB in a TD), and the caller will not
+enqueue more TDs, then we defer giving back the link TRB.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 62 +++++++++++++++++++++++++++++++------------
+ 1 file changed, 46 insertions(+), 16 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -182,8 +182,12 @@ static void inc_deq(struct xhci_hcd *xhc
+ * set, but other sections talk about dealing with the chain bit set. This was
+ * fixed in the 0.96 specification errata, but we have to assume that all 0.95
+ * xHCI hardware can't handle the chain bit being cleared on a link TRB.
++ *
++ * @more_trbs_coming: Will you enqueue more TRBs before calling
++ * prepare_transfer()?
+ */
+-static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer)
++static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,
++ bool consumer, bool more_trbs_coming)
+ {
+ u32 chain;
+ union xhci_trb *next;
+@@ -199,15 +203,28 @@ static void inc_enq(struct xhci_hcd *xhc
+ while (last_trb(xhci, ring, ring->enq_seg, next)) {
+ if (!consumer) {
+ if (ring != xhci->event_ring) {
+- if (chain) {
+- next->link.control |= TRB_CHAIN;
+-
+- /* Give this link TRB to the hardware */
+- wmb();
+- next->link.control ^= TRB_CYCLE;
+- } else {
++ /*
++ * If the caller doesn't plan on enqueueing more
++ * TDs before ringing the doorbell, then we
++ * don't want to give the link TRB to the
++ * hardware just yet. We'll give the link TRB
++ * back in prepare_ring() just before we enqueue
++ * the TD at the top of the ring.
++ */
++ if (!chain && !more_trbs_coming)
+ break;
++
++ /* If we're not dealing with 0.95 hardware,
++ * carry over the chain bit of the previous TRB
++ * (which may mean the chain bit is cleared).
++ */
++ if (!xhci_link_trb_quirk(xhci)) {
++ next->link.control &= ~TRB_CHAIN;
++ next->link.control |= chain;
+ }
++ /* Give this link TRB to the hardware */
++ wmb();
++ next->link.control ^= TRB_CYCLE;
+ }
+ /* Toggle the cycle bit after the last ring segment. */
+ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) {
+@@ -1707,9 +1724,12 @@ void xhci_handle_event(struct xhci_hcd *
+ /*
+ * Generic function for queueing a TRB on a ring.
+ * The caller must have checked to make sure there's room on the ring.
++ *
++ * @more_trbs_coming: Will you enqueue more TRBs before calling
++ * prepare_transfer()?
+ */
+ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring,
+- bool consumer,
++ bool consumer, bool more_trbs_coming,
+ u32 field1, u32 field2, u32 field3, u32 field4)
+ {
+ struct xhci_generic_trb *trb;
+@@ -1719,7 +1739,7 @@ static void queue_trb(struct xhci_hcd *x
+ trb->field[1] = field2;
+ trb->field[2] = field3;
+ trb->field[3] = field4;
+- inc_enq(xhci, ring, consumer);
++ inc_enq(xhci, ring, consumer, more_trbs_coming);
+ }
+
+ /*
+@@ -1988,6 +2008,7 @@ static int queue_bulk_sg_tx(struct xhci_
+ int trb_buff_len, this_sg_len, running_total;
+ bool first_trb;
+ u64 addr;
++ bool more_trbs_coming;
+
+ struct xhci_generic_trb *start_trb;
+ int start_cycle;
+@@ -2073,7 +2094,11 @@ static int queue_bulk_sg_tx(struct xhci_
+ length_field = TRB_LEN(trb_buff_len) |
+ remainder |
+ TRB_INTR_TARGET(0);
+- queue_trb(xhci, ep_ring, false,
++ if (num_trbs > 1)
++ more_trbs_coming = true;
++ else
++ more_trbs_coming = false;
++ queue_trb(xhci, ep_ring, false, more_trbs_coming,
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
+@@ -2124,6 +2149,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+ int num_trbs;
+ struct xhci_generic_trb *start_trb;
+ bool first_trb;
++ bool more_trbs_coming;
+ int start_cycle;
+ u32 field, length_field;
+
+@@ -2212,7 +2238,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+ length_field = TRB_LEN(trb_buff_len) |
+ remainder |
+ TRB_INTR_TARGET(0);
+- queue_trb(xhci, ep_ring, false,
++ if (num_trbs > 1)
++ more_trbs_coming = true;
++ else
++ more_trbs_coming = false;
++ queue_trb(xhci, ep_ring, false, more_trbs_coming,
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
+@@ -2291,7 +2321,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ /* Queue setup TRB - see section 6.4.1.2.1 */
+ /* FIXME better way to translate setup_packet into two u32 fields? */
+ setup = (struct usb_ctrlrequest *) urb->setup_packet;
+- queue_trb(xhci, ep_ring, false,
++ queue_trb(xhci, ep_ring, false, true,
+ /* FIXME endianness is probably going to bite my ass here. */
+ setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16,
+ setup->wIndex | setup->wLength << 16,
+@@ -2307,7 +2337,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ if (urb->transfer_buffer_length > 0) {
+ if (setup->bRequestType & USB_DIR_IN)
+ field |= TRB_DIR_IN;
+- queue_trb(xhci, ep_ring, false,
++ queue_trb(xhci, ep_ring, false, true,
+ lower_32_bits(urb->transfer_dma),
+ upper_32_bits(urb->transfer_dma),
+ length_field,
+@@ -2324,7 +2354,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+ field = 0;
+ else
+ field = TRB_DIR_IN;
+- queue_trb(xhci, ep_ring, false,
++ queue_trb(xhci, ep_ring, false, false,
+ 0,
+ 0,
+ TRB_INTR_TARGET(0),
+@@ -2361,7 +2391,7 @@ static int queue_command(struct xhci_hcd
+ "unfailable commands failed.\n");
+ return -ENOMEM;
+ }
+- queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3,
++ queue_trb(xhci, xhci->cmd_ring, false, false, field1, field2, field3,
+ field4 | xhci->cmd_ring->cycle_state);
+ return 0;
+ }