On Fri, Jan 31, 2014 at 11:48:37PM -0700, Stephen Warren wrote:
> On 01/31/2014 11:12 AM, Andre Heider wrote:
> > On Mon, Jan 13, 2014 at 01:50:09PM -0800, Paul Zimmerman wrote:
> >> The DWC2 driver should now be in good enough shape to move out of
> >> staging. I have stress tested it overnight on RPI running mass
> >> storage and Ethernet transfers in parallel, and for several days
> >> on our proprietary PCI-based platform.
> ...
> > this looks just fine, but for whatever reason it breaks sdhci on my rpi.
> > With today's Linus' master the dwc2 controller seems to initialize fine,
> > but I get this upon boot:
> > 
> > [    1.783316] sdhci-bcm2835 20300000.sdhci: sdhci_pltfm_init failed -12
> > [    1.794820] sdhci-bcm2835: probe of 20300000.sdhci failed with error -12
> >
> > That is:
> > 
> >             struct sdhci_host *sdhci_pltfm_init(struct platform_device 
> > *pdev,
> >                                                     const struct 
> > sdhci_pltfm_data *pdata,
> >                                                     size_t priv_size)
> >             {
> >                     ...
> > 
> >                     iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >                     if (!iomem) {
> >                             ret = -ENOMEM;
> >                             goto err;
> >                     }
> 
> 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.
> 
> 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!)

Nice work, but how did you pinpoint this? Am I missing some option/tool
or did I just not stare for long enough?

> 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.
_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to