[U-Boot] [PATCH v2] usb: fix usb_stor_read/write on DM
Benoît Thébaudeau
benoit.thebaudeau.dev at gmail.com
Fri Jul 14 21:46:14 UTC 2017
On Fri, Jul 14, 2017 at 1:50 PM, Marek Vasut <marex at denx.de> wrote:
> On 07/14/2017 01:03 PM, Masahiro Yamada wrote:
>> 2017-07-14 19:07 GMT+09:00 Marek Vasut <marex at denx.de>:
>>> On 07/14/2017 04:31 AM, Masahiro Yamada wrote:
>>>> Prior to DM, we could not enable different types of USB controllers
>>>> at the same time. DM was supposed to loosen the limitation. It is
>>>> true that we can compile drivers, but they do not work.
>>>>
>>>> For example, if EHCI is enabled, xHCI fails as follows:
>>>>
>>>> => usb read 82000000 0 2000
>>>>
>>>> USB read: device 0 block # 0, count 8192 ... WARN halted endpoint, queueing URB anyway.
>>>> Unexpected XHCI event TRB, skipping... (3fb54010 00000001 13000000 01008401)
>>>> BUG: failure at drivers/usb/host/xhci-ring.c:489/abort_td()!
>>>> BUG!
>>>> ### ERROR ### Please RESET the board ###
>>>>
>>>> The cause of the error seems the following code:
>>>>
>>>> #ifdef CONFIG_USB_EHCI_HCD
>>>> /*
>>>> * The U-Boot EHCI driver can handle any transfer length as long as there is
>>>> * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands are
>>>> * limited to 65535 blocks.
>>>> */
>>>> #define USB_MAX_XFER_BLK 65535
>>>> #else
>>>> #define USB_MAX_XFER_BLK 20
>>>> #endif
>>>>
>>>> To fix the problem, choose the chunk size at run-time for CONFIG_BLK.
>>>
>>> What happens if CONFIG_BLK is not set ?
>>
>> USB_MAX_XFER_BLK is chosen.
>
> And can we fix that even for non-CONFIG_BLK ?
>
>>> Why is it 20 for XHCI anyway ?
>>
>> You are the maintainer.
>> (I hope) you have better knowledge with this.
>
> Heh, way to deflect the question. I seem to remember some discussion
> about the DMA (?) limitation on XHCI, but I'd have to dig through the ML
> archives myself.
>
>> Looks like the following commit was picked up by you.
>
> 5 years ago, way before DM was what it is today .
And even way before the introduction of XHCI into U-Boot, which means
that this 20 was targeting OHCI or proprietary HCDs, not XHCI.
USB_MAX_READ_BLK was already set to 20 in the initial revision of
usb_storage.c. As I said in the commit message, this 20 was certainly
not optimal for these non-EHCI HCDs, but it restored the previous
(i.e. pre-5dd95cf) behavior for these HCDs instead of using the 5 * 4
KiB code, which was specific to ehci-hcd.c at that time. Without
knowing the rationale for the legacy 20 blocks, the safest approach
for non-EHCI HCDs was to use this value in order to avoid breaking a
platform or something. Looking at ohci-hcd.c, it limits the transfer
size to (N_URB_TD - 2) * 4 KiB, with N_URB_TD set to 48, so the
maximum number of transfers would depend on the MSC block size.
dwc2.c, isp116x-hcd.c, r8a66597-hcd.c, and sl811-hcd.c do not seem to
have any limit caused by these drivers. The limit with the current
XHCI code seems to be 64 * 64 KiB. So, nowadays, USB_MAX_XFER_BLK
could be set to 65535 for all HCDs but OHCI and XHCI, which require
specific rules depending on the MSC block size.
>> commit cffcc503580907d733e694d505e12ff6ec6c679a
>> Author: Benoît Thébaudeau <benoit.thebaudeau at advansee.com>
>> AuthorDate: Fri Aug 10 18:26:50 2012 +0200
>> Commit: Marek Vasut <marex at denx.de>
>> CommitDate: Sat Sep 1 16:21:52 2012 +0200
>>
>> usb_storage: Restore non-EHCI support
>>
>> The commit 5dd95cf made the MSC driver EHCI-specific. This patch restores a
>> basic support of non-EHCI HCDs, like before that commit.
>>
>> The fallback transfer size is certainly not optimal, but at least
>> it should work
>> like before.
>>
>> Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau at advansee.com>
>> Cc: Marek Vasut <marex at denx.de>
>> Cc: Ilya Yanok <ilya.yanok at cogentembedded.com>
>> Cc: Stefan Herbrechtsmeier <stefan at herbrechtsmeier.net>
>>
>> diff --git a/common/usb_storage.c b/common/usb_storage.c
>> index bdc306f587fd..0cd6399a3c42 100644
>> --- a/common/usb_storage.c
>> +++ b/common/usb_storage.c
>> @@ -155,11 +155,15 @@ struct us_data {
>> trans_cmnd transport; /* transport routine */
>> };
>>
>> +#ifdef CONFIG_USB_EHCI
>> /*
>> * The U-Boot EHCI driver cannot handle more than 5 page aligned buffers
>> * of 4096 bytes in a transfer without running itself out of qt_buffers
>> */
>> #define USB_MAX_XFER_BLK(start, blksz) (((4096 * 5) - (start % 4096)) / blksz)
>> +#else
>> +#define USB_MAX_XFER_BLK(start, blksz) 20
>> +#endif
>>
>> static struct us_data usb_stor[USB_MAX_STOR_DEV];
Best regards,
Benoît
More information about the U-Boot
mailing list