Re: [PATCH v4] Move DWC2 driver out of staging

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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!)

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
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux