# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.600.1.10 -> 1.600.1.11 # drivers/usb/host/ohci-hcd.c 1.24 -> 1.25 # drivers/usb/core/hcd.c 1.32 -> 1.33 # drivers/usb/host/ohci-dbg.c 1.10 -> 1.11 # drivers/usb/host/uhci-hcd.c 1.12 -> 1.13 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/09/04 rmk@arm.linux.org.uk 1.600.1.11 # [PATCH] 2.5.32-usb # # 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. # -------------------------------------------- # diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c --- a/drivers/usb/core/hcd.c Thu Sep 5 08:51:07 2002 +++ b/drivers/usb/core/hcd.c Thu Sep 5 08:51:07 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 -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c --- a/drivers/usb/host/ohci-dbg.c Thu Sep 5 08:51:07 2002 +++ b/drivers/usb/host/ohci-dbg.c Thu Sep 5 08:51:07 2002 @@ -208,7 +208,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 -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c --- a/drivers/usb/host/ohci-hcd.c Thu Sep 5 08:51:07 2002 +++ b/drivers/usb/host/ohci-hcd.c Thu Sep 5 08:51:07 2002 @@ -519,7 +519,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); diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c --- a/drivers/usb/host/uhci-hcd.c Thu Sep 5 08:51:07 2002 +++ b/drivers/usb/host/uhci-hcd.c Thu Sep 5 08:51:07 2002 @@ -2329,6 +2329,7 @@ err_alloc_skeltd: usb_free_dev(udev); + hcd->self.root_hub = NULL; err_alloc_root_hub: pci_pool_destroy(uhci->qh_pool);