diff options
| author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-11-05 10:59:25 -0800 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-11-05 10:59:25 -0800 |
| commit | f878c4f193b7327244af8f7de8cf8bc61fb78fe1 (patch) | |
| tree | 0d95465d5a6a8f13259bc149b249f29501e7fb75 /usb.current | |
| parent | 39874450fa07821078746db7b99cc931ca9478cc (diff) | |
| download | patches-f878c4f193b7327244af8f7de8cf8bc61fb78fe1.tar.gz | |
some bugfixes for .32
Diffstat (limited to 'usb.current')
8 files changed, 530 insertions, 0 deletions
diff --git a/usb.current/usb-cdc_acm-fix-memory-leak-after-hangup.patch b/usb.current/usb-cdc_acm-fix-memory-leak-after-hangup.patch new file mode 100644 index 00000000000000..432907a3e4b641 --- /dev/null +++ b/usb.current/usb-cdc_acm-fix-memory-leak-after-hangup.patch @@ -0,0 +1,90 @@ +From francescolavra@interfree.it Thu Nov 5 10:09:43 2009 +From: Francesco Lavra <francescolavra@interfree.it> +Date: Tue, 3 Nov 2009 10:53:07 +0000 (UTC) +Subject: USB: cdc_acm: Fix memory leak after hangup +Message-ID: <loom.20091103T113446-408@post.gmane.org> + + +Am Donnerstag, 10. September 2009 15:43:53 schrieb Dietmar Hilbrich: +> Hello, +> +> i have the following problem with the cdc-acm - driver: +> +> I'm using the driver with an "Ericsson F3507G" on a Thinkpad T400. +> +> If a disable the device (with the RFKill-Switch) while it is used by a +> programm like ppp, the driver doesn't seem to correctly clean up the tty, +> even after the program has been closed) +> +> The tty is still active (e.g. there still exists an entry in +> /sys/dev/char/166:0 if ttyACM0 was used) and if a reacticate the device, +> this device entry will be skipped and the Device-Nodes ttyACM1, ttyACM2 +> and ttyACM3 will be used. +> +> This problem was introduced with the commit +> 10077d4a6674f535abdbe25cdecb1202af7948f1 (before 2.6.31-rc1) and still +> exists in 2.6.31. +> +> I was able the fix this problem with the following patch: +> +> diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +> index 2bfc41e..0970d2f 100644 +> --- a/drivers/usb/class/cdc-acm.c +> +++ b/drivers/usb/class/cdc-acm.c +> @@ -676,6 +676,7 @@ static void acm_tty_hangup(struct tty_struct *tty) +> struct acm *acm = tty->driver_data; +> tty_port_hangup(&acm->port); +> acm_port_down(acm, 0); +> + acm_tty_unregister(acm); +> } + +I have the same problem with cdc-acm (I'm using a Samsung SGH-U900): when I +unplug it from the USB port during a PPP connection, the ppp daemon gets the +hangup correctly (and closes the device), but the struct acm corresponding to +the device disconnected is not freed. Hence reconnecting the device results in +creation of /dev/ttyACM(x+1). The same happens when the system is hibernated +during a PPP connection. + +This memory leak is due to the fact that when the tty is hung up, +tty_port_close_start() returns always zero, and acm_tty_close() never reaches +the point where acm_tty_unregister() is called. + +Here is a fix for this. + +Signed-off-by: Francesco Lavra <francescolavra@interfree.it> +Acked-by: Oliver Neukum <oliver@neukum.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/class/cdc-acm.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -686,15 +686,21 @@ static void acm_tty_close(struct tty_str + + /* Perform the closing process and see if we need to do the hardware + shutdown */ +- if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0) ++ if (!acm) ++ return; ++ if (tty_port_close_start(&acm->port, tty, filp) == 0) { ++ mutex_lock(&open_mutex); ++ if (!acm->dev) { ++ tty_port_tty_set(&acm->port, NULL); ++ acm_tty_unregister(acm); ++ tty->driver_data = NULL; ++ } ++ mutex_unlock(&open_mutex); + return; ++ } + acm_port_down(acm, 0); + tty_port_close_end(&acm->port, tty); +- mutex_lock(&open_mutex); + tty_port_tty_set(&acm->port, NULL); +- if (!acm->dev) +- acm_tty_unregister(acm); +- mutex_unlock(&open_mutex); + } + + static int acm_tty_write(struct tty_struct *tty, diff --git a/usb.current/usb-cdc_acm-fix-race-condition-when-opening-tty.patch b/usb.current/usb-cdc_acm-fix-race-condition-when-opening-tty.patch new file mode 100644 index 00000000000000..8e8d2d2b760959 --- /dev/null +++ b/usb.current/usb-cdc_acm-fix-race-condition-when-opening-tty.patch @@ -0,0 +1,35 @@ +From hsggebhardt@googlemail.com Thu Nov 5 10:08:03 2009 +From: Henry Gebhardt <hsggebhardt@googlemail.com> +Date: Wed, 4 Nov 2009 11:19:28 +0100 +Subject: USB: cdc_acm: Fix race condition when opening tty +To: Oliver Neukum <oliver@neukum.org> +Cc: greg@kroah.com +Message-ID: <1bd893420911040219vbfe58a1redb8c8ed934760bd@mail.gmail.com> + +From: Henry Gebhardt <gebhardt@astro.uni-tuebingen.de> + +If acm_rx_tasklet() gets called before tty_port_block_til_ready() +returns, then bulk IN urbs may not be sent. This fixes it. + +Signed-off-by: Henry Gebhardt <gebhardt@astro.uni-tuebingen.de> +Acked-by: Oliver Neukum <oliver@neukum.org> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/class/cdc-acm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -609,9 +609,9 @@ static int acm_tty_open(struct tty_struc + + acm->throttle = 0; + +- tasklet_schedule(&acm->urb_task); + set_bit(ASYNCB_INITIALIZED, &acm->port.flags); + rv = tty_port_block_til_ready(&acm->port, tty, filp); ++ tasklet_schedule(&acm->urb_task); + done: + mutex_unlock(&acm->mutex); + err_out: diff --git a/usb.current/usb-ohci-quirk-amd-prefetch-for-usb-1.1-iso-transfer.patch b/usb.current/usb-ohci-quirk-amd-prefetch-for-usb-1.1-iso-transfer.patch new file mode 100644 index 00000000000000..f613d1c43f765c --- /dev/null +++ b/usb.current/usb-ohci-quirk-amd-prefetch-for-usb-1.1-iso-transfer.patch @@ -0,0 +1,151 @@ +From libin.yang@amd.com Thu Nov 5 10:03:20 2009 +From: Libin Yang <libin.yang@amd.com> +Date: Wed, 4 Nov 2009 14:55:18 +0800 +Subject: USB: ohci: quirk AMD prefetch for USB 1.1 ISO transfer +To: gregkh@suse.de, david-b@pacbell.net, stern@rowland.harvard.edu +Cc: linux-usb@vger.kernel.org, oliver@neukum.org, "Yang, Libin" <Libin.Yang@amd.com>, "Xu, Andiry" <Andiry.Xu@amd.com> +Message-ID: <1257317719.4833.27.camel@younglee-desktop> + +From: Libin Yang <libin.yang@amd.com> + + +The following patch in the driver is required to avoid USB 1.1 device +failures that may occur due to requests from USB OHCI controllers may +be overwritten if the latency for any pending request by the USB +controller is very long (in the range of milliseconds). + +Signed-off-by: Libin Yang <libin.yang@amd.com> +Cc: David Brownell <dbrownell@users.sourceforge.net> +Cc: Alan Stern <stern@rowland.harvard.edu> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + drivers/usb/host/ohci-hcd.c | 5 +++++ + drivers/usb/host/ohci-pci.c | 20 ++++++++++++++++++++ + drivers/usb/host/ohci-q.c | 18 ++++++++++++------ + drivers/usb/host/ohci.h | 9 +++++++++ + 4 files changed, 46 insertions(+), 6 deletions(-) + +--- a/drivers/usb/host/ohci.h ++++ b/drivers/usb/host/ohci.h +@@ -402,6 +402,7 @@ struct ohci_hcd { + #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ + #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ + #define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ ++#define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ + // there are also chip quirks/bugs in init logic + + struct work_struct nec_work; /* Worker for NEC quirk */ +@@ -433,6 +434,10 @@ static inline int quirk_amdiso(struct oh + { + return ohci->flags & OHCI_QUIRK_AMD_ISO; + } ++static inline int quirk_amdprefetch(struct ohci_hcd *ohci) ++{ ++ return ohci->flags & OHCI_QUIRK_AMD_PREFETCH; ++} + #else + static inline int quirk_nec(struct ohci_hcd *ohci) + { +@@ -446,6 +451,10 @@ static inline int quirk_amdiso(struct oh + { + return 0; + } ++static inline int quirk_amdprefetch(struct ohci_hcd *ohci) ++{ ++ return 0; ++} + #endif + + /* convert between an hcd pointer and the corresponding ohci_hcd */ +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -87,6 +87,7 @@ static int ohci_restart (struct ohci_hcd + #ifdef CONFIG_PCI + static void quirk_amd_pll(int state); + static void amd_iso_dev_put(void); ++static void sb800_prefetch(struct ohci_hcd *ohci, int on); + #else + static inline void quirk_amd_pll(int state) + { +@@ -96,6 +97,10 @@ static inline void amd_iso_dev_put(void) + { + return; + } ++static inline void sb800_prefetch(struct ohci_hcd *ohci, int on) ++{ ++ return; ++} + #endif + + +--- a/drivers/usb/host/ohci-pci.c ++++ b/drivers/usb/host/ohci-pci.c +@@ -177,6 +177,13 @@ static int ohci_quirk_amd700(struct usb_ + return 0; + + pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); ++ ++ /* SB800 needs pre-fetch fix */ ++ if ((rev >= 0x40) && (rev <= 0x4f)) { ++ ohci->flags |= OHCI_QUIRK_AMD_PREFETCH; ++ ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); ++ } ++ + if ((rev > 0x3b) || (rev < 0x30)) { + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; +@@ -262,6 +269,19 @@ static void amd_iso_dev_put(void) + + } + ++static void sb800_prefetch(struct ohci_hcd *ohci, int on) ++{ ++ struct pci_dev *pdev; ++ u16 misc; ++ ++ pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller); ++ pci_read_config_word(pdev, 0x50, &misc); ++ if (on == 0) ++ pci_write_config_word(pdev, 0x50, misc & 0xfcff); ++ else ++ pci_write_config_word(pdev, 0x50, misc | 0x0300); ++} ++ + /* List of quirks for OHCI */ + static const struct pci_device_id ohci_pci_quirks[] = { + { +--- a/drivers/usb/host/ohci-q.c ++++ b/drivers/usb/host/ohci-q.c +@@ -49,9 +49,12 @@ __acquires(ohci->lock) + switch (usb_pipetype (urb->pipe)) { + case PIPE_ISOCHRONOUS: + ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; +- if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 +- && quirk_amdiso(ohci)) +- quirk_amd_pll(1); ++ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { ++ if (quirk_amdiso(ohci)) ++ quirk_amd_pll(1); ++ if (quirk_amdprefetch(ohci)) ++ sb800_prefetch(ohci, 0); ++ } + break; + case PIPE_INTERRUPT: + ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; +@@ -680,9 +683,12 @@ static void td_submit_urb ( + data + urb->iso_frame_desc [cnt].offset, + urb->iso_frame_desc [cnt].length, urb, cnt); + } +- if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 +- && quirk_amdiso(ohci)) +- quirk_amd_pll(0); ++ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { ++ if (quirk_amdiso(ohci)) ++ quirk_amd_pll(0); ++ if (quirk_amdprefetch(ohci)) ++ sb800_prefetch(ohci, 1); ++ } + periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 + && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; + break; diff --git a/usb.current/usb-option.c-add-support-for-d-link-dwm-162-u5.patch b/usb.current/usb-option.c-add-support-for-d-link-dwm-162-u5.patch new file mode 100644 index 00000000000000..6244c8671facec --- /dev/null +++ b/usb.current/usb-option.c-add-support-for-d-link-dwm-162-u5.patch @@ -0,0 +1,45 @@ +From r0bertz@gentoo.org Thu Nov 5 10:19:05 2009 +From: Zhang Le <r0bertz@gentoo.org> +Date: Wed, 4 Nov 2009 23:22:59 +0800 +Subject: USB: option.c: add support for D-Link DWM-162-U5 +To: gregkh@suse.de +Cc: smurf@smurf.noris.de, Zhang Le <r0bertz@gentoo.org> +Message-ID: <1257348179-20430-1-git-send-email-r0bertz@gentoo.org> + + +Add D-Link DWM-162-U5 device id 1e0e:ce16 into option driver. The device +has 4 interfaces, of which 1 is handled by storage and the other 3 by +option driver. + +The device appears first as CD-only 05c6:2100 device and must be +switched to 1e0e:ce16 mode either by using "eject CD" or usb_modeswitch. + +The MessageContent for usb_modeswitch.conf is: +"55534243e0c26a85000000000000061b000000020000000000000000000000" + +Signed-off-by: Zhang Le <r0bertz@gentoo.org> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/option.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -308,6 +308,7 @@ static int option_resume(struct usb_ser + + #define DLINK_VENDOR_ID 0x1186 + #define DLINK_PRODUCT_DWM_652 0x3e04 ++#define DLINK_PRODUCT_DWM_652_U5 0xce16 + + #define QISDA_VENDOR_ID 0x1da5 + #define QISDA_PRODUCT_H21_4512 0x4512 +@@ -586,6 +587,7 @@ static struct usb_device_id option_ids[] + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, + { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, + { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, ++ { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ + { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, + { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, + { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, diff --git a/usb.current/usb-usbmon-fix-bug-in-mon_buff_area_shrink.patch b/usb.current/usb-usbmon-fix-bug-in-mon_buff_area_shrink.patch new file mode 100644 index 00000000000000..89c262ec024a8a --- /dev/null +++ b/usb.current/usb-usbmon-fix-bug-in-mon_buff_area_shrink.patch @@ -0,0 +1,68 @@ +From stern@rowland.harvard.edu Thu Nov 5 10:18:37 2009 +From: Alan Stern <stern@rowland.harvard.edu> +Date: Wed, 4 Nov 2009 11:35:53 -0500 (EST) +Subject: USB: usbmon: fix bug in mon_buff_area_shrink +To: Greg KH <greg@kroah.com>, Pete Zaitcev <zaitcev@redhat.com> +Message-ID: <Pine.LNX.4.44L0.0911041133570.2968-100000@iolanthe.rowland.org> + +This patch (as1299b) fixes a bug in an error-handling path of usbmon's +binary interface. The storage area for URB data is divided into +fixed-size blocks. If an URB's data can't be copied, the area +reserved for it should be decreased to the size of the truncated +information (rounded up to a block boundary). Rounding up the amount +to be removed and subtracting it from the reserved size is definitely +the wrong thing to do. + +Also, when the data for an isochronous URB can't be copied, we can +still copy the isoc packet descriptors. In fact the current code does +copy the descriptors, but then sets the capture length to 0 so they +remain inaccessible. The capture length should be reduced to the +length of the descriptors, not set to 0. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Acked-by: Pete Zaitcev <zaitcev@redhat.com> +CC: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/mon/mon_bin.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/usb/mon/mon_bin.c ++++ b/drivers/usb/mon/mon_bin.c +@@ -348,12 +348,12 @@ static unsigned int mon_buff_area_alloc_ + + /* + * Return a few (kilo-)bytes to the head of the buffer. +- * This is used if a DMA fetch fails. ++ * This is used if a data fetch fails. + */ + static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) + { + +- size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); ++ /* size &= ~(PKT_ALIGN-1); -- we're called with aligned size */ + rp->b_cnt -= size; + if (rp->b_in < size) + rp->b_in += rp->b_size; +@@ -433,6 +433,7 @@ static void mon_bin_event(struct mon_rea + unsigned int urb_length; + unsigned int offset; + unsigned int length; ++ unsigned int delta; + unsigned int ndesc, lendesc; + unsigned char dir; + struct mon_bin_hdr *ep; +@@ -537,8 +538,10 @@ static void mon_bin_event(struct mon_rea + if (length != 0) { + ep->flag_data = mon_bin_get_data(rp, offset, urb, length); + if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ +- ep->len_cap = 0; +- mon_buff_area_shrink(rp, length); ++ delta = (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1); ++ ep->len_cap -= length; ++ delta -= (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1); ++ mon_buff_area_shrink(rp, delta); + } + } else { + ep->flag_data = data_tag; diff --git a/usb.current/usb-xhci-fix-bug-memory-free-after-failed-initialization.patch b/usb.current/usb-xhci-fix-bug-memory-free-after-failed-initialization.patch new file mode 100644 index 00000000000000..beede6576509d1 --- /dev/null +++ b/usb.current/usb-xhci-fix-bug-memory-free-after-failed-initialization.patch @@ -0,0 +1,39 @@ +From sarah.a.sharp@linux.intel.com Thu Nov 5 10:15:20 2009 +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Date: Tue, 3 Nov 2009 22:02:22 -0800 +Subject: USB: xhci: Fix bug memory free after failed initialization. +To: Greg KH <gregkh@suse.de> +Cc: linux-usb@vger.kernel.org +Message-ID: <20091104060222.GA25309@xanatos> +Content-Disposition: inline + + +If the xHCI driver fails during the memory initialization, xhci->ir_set +may not be a valid pointer. Check that it points to valid DMA'able memory +before writing to that address during the memory freeing process. + +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-mem.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -802,9 +802,11 @@ void xhci_mem_cleanup(struct xhci_hcd *x + int i; + + /* Free the Event Ring Segment Table and the actual Event Ring */ +- xhci_writel(xhci, 0, &xhci->ir_set->erst_size); +- xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); +- xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); ++ if (xhci->ir_set) { ++ xhci_writel(xhci, 0, &xhci->ir_set->erst_size); ++ xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); ++ xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); ++ } + size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); + if (xhci->erst.entries) + pci_free_consistent(pdev, size, diff --git a/usb.current/usb-xhci-fix-scratchpad-deallocation.patch b/usb.current/usb-xhci-fix-scratchpad-deallocation.patch new file mode 100644 index 00000000000000..5058d23cda14e7 --- /dev/null +++ b/usb.current/usb-xhci-fix-scratchpad-deallocation.patch @@ -0,0 +1,37 @@ +From sarah.a.sharp@linux.intel.com Thu Nov 5 10:18:01 2009 +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Date: Wed, 4 Nov 2009 11:22:19 -0800 +Subject: USB: xhci: Fix scratchpad deallocation. +To: Greg KH <gregkh@suse.de> +Cc: John Youn <John.Youn@synopsys.com>, linux-usb@vger.kernel.org +Message-ID: <20091104192219.GA5081@xanatos> +Content-Disposition: inline + + +The scratchpad_free() function uses xhci->page_size to free some memory +with pci_free_consistent(). However, the page_size is set to zero before +the call, causing kernel oopses on driver unload. Call scratchpad_free() +before setting xhci->page_size to zero. + +Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Acked-by: John Youn <John.Youn@synopsys.com> +Cc: stable <stable@kernel.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/xhci-mem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -843,9 +843,9 @@ void xhci_mem_cleanup(struct xhci_hcd *x + xhci->dcbaa, xhci->dcbaa->dma); + xhci->dcbaa = NULL; + ++ scratchpad_free(xhci); + xhci->page_size = 0; + xhci->page_shift = 0; +- scratchpad_free(xhci); + } + + int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) diff --git a/usb.current/usb-xhci-fix-trb-physical-to-virtual-address-translation.patch b/usb.current/usb-xhci-fix-trb-physical-to-virtual-address-translation.patch new file mode 100644 index 00000000000000..8a4e4673f604ba --- /dev/null +++ b/usb.current/usb-xhci-fix-trb-physical-to-virtual-address-translation.patch @@ -0,0 +1,65 @@ +From sarah.a.sharp@linux.intel.com Thu Nov 5 10:15:34 2009 +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Date: Tue, 3 Nov 2009 22:02:24 -0800 +Subject: USB: xhci: Fix TRB physical to virtual address translation. +To: Greg KH <gregkh@suse.de> +Cc: linux-usb@vger.kernel.org +Message-ID: <20091104060224.GA24973@xanatos> +Content-Disposition: inline + + +The trb_in_td() function in the xHCI driver is supposed to translate a +physical transfer buffer request (TRB) into a virtual pointer to the ring +segment that TRB is in. + +Unfortunately, a mistake in this function may cause endless loops as the +driver searches through the linked list of ring segments over and over +again. Fix a couple bugs that may lead to loops or bad output: + +1. Bail out if we get a NULL pointer when translating the segment's +private structure and the starting DMA address of the segment chunk. If +this happens, we've been handed a starting TRB pointer from a different +ring. + +2. Make sure the function works when there's multiple segments in the +ring. In the while loop to search through the ring segments, use the +current segment variable (cur_seg), rather than the starting segment +variable (start_seg) that is passed in. + +3. Stop searching the ring if we've run through all the segments in the +ring. + +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 | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -864,9 +864,11 @@ static struct xhci_segment *trb_in_td( + cur_seg = start_seg; + + do { ++ if (start_dma == 0) ++ return 0; + /* We may get an event for a Link TRB in the middle of a TD */ + end_seg_dma = xhci_trb_virt_to_dma(cur_seg, +- &start_seg->trbs[TRBS_PER_SEGMENT - 1]); ++ &cur_seg->trbs[TRBS_PER_SEGMENT - 1]); + /* If the end TRB isn't in this segment, this is set to 0 */ + end_trb_dma = xhci_trb_virt_to_dma(cur_seg, end_trb); + +@@ -893,8 +895,9 @@ static struct xhci_segment *trb_in_td( + } + cur_seg = cur_seg->next; + start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]); +- } while (1); ++ } while (cur_seg != start_seg); + ++ return 0; + } + + /* |
