On Fri, 31 Jan 2014, Stephen Warren wrote: > This is due to the following code: > > static void _dwc2_hcd_endpoint_reset(struct usb_hcd *hcd, > struct usb_host_endpoint *ep) > { > struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); > ... > struct usb_device *udev; > ... > udev = to_usb_device(hsotg->dev); > ... > usb_settoggle(udev, epnum, is_out, 0); > if (is_control) > usb_settoggle(udev, epnum, !is_out, 0); > > The problem is that hsotg->dev is assigned as follows: > > static int dwc2_driver_probe(struct platform_device *dev) > ... > hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL); > ... > hsotg->dev = &dev->dev; > > As such, it's not legal to call to_usb_device() on it.
This clearly is a bug. I suspect the driver has other bugs too, such as not holding the private lock over a large enough region. > What ends up happening, simply due to memory allocation order, is that > the memory writes inside usb_settoggle() end up setting the SDHCI struct > platform_device's num_resources to 0, so that it's call to > platform_get_resource() fails. > > With the DWC2 move patch reverted, some other random piece of memory is > being corrupted, which just happens not to cause any visible problem. > Likely it's some other struct platform_device that's already had its > resources read by the time DWC2 probes and corrupts them. > > (Yes, this was hard to find!) > > I honestly can't see how to solve this myself, since the whole DWC2 > driver doesn't seem to have a struct usb_device * hanging around that we > can stash somewhere for it to look up later. Perhaps someone more > familiar with the USB stack can help with that. The correct solution is to set qh = ep->hcpriv; udev = qh->udev; However, the driver doesn't store udev in qh (dwc2_qh_init() should do this, but it doesn't). In fact, the field doesn't even exist. Alan Stern _______________________________________________ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel