[PATCH] 2.5.32-usb

From: Russell King (rmk@arm.linux.org.uk)
Date: Sun Sep 01 2002 - 14:01:06 EST


This patch appears not to be in 2.5.32, but applies cleanly.

The following patch fixes 3 problems in USB:

1. Don't pci_map buffers when we know we're not going to pass them
   to a device.

   This was first noticed on ARM (no surprises here); the root hub
   code, rh_call_control(), placed data into the buffer and then
   called usb_hcd_giveback_urb(). This function called
   pci_unmap_single() on this region which promptly destroyed the
   data that rh_call_control() had placed there. This lead to a
   corrupted device descriptor and the "too many configurations"
   message.

2. If controller->hcca is NULL, don't try to dereference it.

3. If we free the root hub (in ohci-hcd.c or uhci-hcd.c), don't
   leave a dangling pointer around to trip us up in usb_disconnect().
   EHCI appears to get this right.

 drivers/usb/core/hcd.c | 21 +++++++++++----------
 drivers/usb/host/ohci-dbg.c | 3 ++-
 drivers/usb/host/ohci-hcd.c | 3 ++-
 drivers/usb/host/uhci-hcd.c | 1 +
 4 files changed, 16 insertions, 12 deletions

diff -ur orig/drivers/usb/core/hcd.c linux/drivers/usb/core/hcd.c
--- orig/drivers/usb/core/hcd.c Fri Aug 30 14:53:19 2002
+++ linux/drivers/usb/core/hcd.c Sun Sep 1 19:51:46 2002
@@ -1020,6 +1020,16 @@
         if (status)
                 return status;
 
+ /* increment urb's reference count as part of giving it to the HCD
+ * (which now controls it). HCD guarantees that it either returns
+ * an error or calls giveback(), but not both.
+ */
+ urb = usb_get_urb (urb);
+ if (urb->dev == hcd->self.root_hub) {
+ urb->transfer_flags |= URB_NO_DMA_MAP;
+ return rh_urb_enqueue (hcd, urb);
+ }
+
         /* lower level hcd code should use *_dma exclusively */
         if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
                 if (usb_pipecontrol (urb->pipe))
@@ -1038,16 +1048,7 @@
                                             : PCI_DMA_TODEVICE);
         }
 
- /* increment urb's reference count as part of giving it to the HCD
- * (which now controls it). HCD guarantees that it either returns
- * an error or calls giveback(), but not both.
- */
- urb = usb_get_urb (urb);
- if (urb->dev == hcd->self.root_hub)
- status = rh_urb_enqueue (hcd, urb);
- else
- status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
- return status;
+ return hcd->driver->urb_enqueue (hcd, urb, mem_flags);
 }
 
 /*-------------------------------------------------------------------------*/
diff -ur orig/drivers/usb/host/ohci-dbg.c linux/drivers/usb/host/ohci-dbg.c
--- orig/drivers/usb/host/ohci-dbg.c Sat Jul 27 13:55:21 2002
+++ linux/drivers/usb/host/ohci-dbg.c Sun Sep 1 17:14:27 2002
@@ -239,7 +239,8 @@
         if (verbose)
                 ohci_dump_periodic (controller, "hcca");
 #endif
- dbg ("hcca frame #%04x", controller->hcca->frame_no);
+ if (controller->hcca)
+ dbg ("hcca frame #%04x", controller->hcca->frame_no);
         ohci_dump_roothub (controller, 1);
 }
 
diff -ur orig/drivers/usb/host/ohci-hcd.c linux/drivers/usb/host/ohci-hcd.c
--- orig/drivers/usb/host/ohci-hcd.c Sat Jul 27 13:55:21 2002
+++ linux/drivers/usb/host/ohci-hcd.c Sun Sep 1 17:26:11 2002
@@ -530,7 +530,8 @@
         usb_connect (udev);
         udev->speed = USB_SPEED_FULL;
         if (usb_register_root_hub (udev, ohci->parent_dev) != 0) {
- usb_free_dev (udev);
+ usb_free_dev (udev);
+ ohci->hcd.self.root_hub = NULL;
                 disable (ohci);
                 ohci->hc_control &= ~OHCI_CTRL_HCFS;
                 writel (ohci->hc_control, &ohci->regs->control);
--- orig/drivers/usb/host/uhci-hcd.c Fri Aug 30 14:53:21 2002
+++ linux/drivers/usb/host/uhci-hcd.c Sun Sep 1 19:58:51 2002
@@ -2340,6 +2340,7 @@
 err_alloc_skeltd:
         usb_free_dev(uhci->rh_dev);
         uhci->rh_dev = NULL;
+ hcd->self.root_hub = NULL;
 
 err_alloc_root_hub:
         pci_pool_destroy(uhci->qh_pool);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Sep 07 2002 - 22:00:14 EST