diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2010-06-14 16:03:47 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-06-14 16:03:47 -0700 |
| commit | 209280a6e58de1ade661eea4bb94571bad7a5f8c (patch) | |
| tree | 6c5579373755a4becb87e94e3d5155e7c99337ea /usb.current | |
| parent | 02bdf5fc5f222119ecfa709354e540a594ae4b10 (diff) | |
| download | patches-209280a6e58de1ade661eea4bb94571bad7a5f8c.tar.gz | |
patches
Diffstat (limited to 'usb.current')
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; + } |
