1、在uboot 下 扫描不到某些品牌的U盘,有的U盘可以扫到
参考 uboot 代码 :common/usb_hub.c 函数 usb_hub_power_on 中有一段代码,
意思是有些USB设备,并没有按照标准的spec来做,或者是和spec有些出入,这个时候需要加一个延时。
解决办法:uboot 下加一个环境变量:
setenv usb_pgood_delay 1000
经过实际测试,这个U盘,需要至少800ms的延时,才可以识别到,这里保险起见,设置了1000ms
另外一种偶发出现的现象,scan的时候 timeout
这种问题的出现,可能是因为 usb 每次传输的数据size 过大导致的。
第二章的问题是一样的。
cmd/usb.c
usb reset = stop + start
usb start ->
->do_usb_start
->usb_stor_scan common/usb_storage.c
->usb_stor_probe_device
-> usb_storage_probe
-> usb_stor_set_max_xfer_blk
2、在uboot 加载U盘里的文件,大文件10M,出现timeout, 加载识别
=> fatload usb 0 $loadaddr bootfw-som0002-g2021-12-13-a6b140f-dirty.bin
EHCI timed out on TD - token=0xa8008d80
在uboot2018 ,上做改动,usb 传输的块数量,默认是65535, 这里需要调整一下,也可以通过 环境变量来动态修改。
diff --git a/common/usb_storage.c b/common/usb_storage.c
index 9cd6474..c7e8c8f 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -71,6 +71,8 @@ static int usb_max_devs; /* number of highest available usb device */
static struct blk_desc usb_dev_desc[USB_MAX_STOR_DEV];
#endif
+#define USB_MAX_XFER_BLK 2000
+
struct us_data;
typedef int (*trans_cmnd)(struct scsi_cmd *cb, struct us_data *data);
typedef int (*trans_reset)(struct us_data *data);
@@ -952,7 +954,7 @@ static void usb_stor_set_max_xfer_blk(struct usb_device *udev,
* there is enough free heap space left, but the SCSI READ(10) and
* WRITE(10) commands are limited to 65535 blocks.
*/
- blk = USHRT_MAX;
+ blk = env_get_ulong("usb_max_blk", 10, USB_MAX_XFER_BLK);
#else
blk = 20;
#endif
@@ -1171,11 +1173,12 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
/* XXX need some comment here */
retry = 2;
srb->pdata = (unsigned char *)buf_addr;
+retry_it:
if (blks > ss->max_xfer_blk)
smallblks = ss->max_xfer_blk;
else
smallblks = (unsigned short) blks;
-retry_it:
+
if (smallblks == ss->max_xfer_blk)
usb_show_progress();
srb->datalen = block_dev->blksz * smallblks;
@@ -1183,6 +1186,27 @@ retry_it:
if (usb_read_10(srb, ss, start, smallblks)) {
debug("Read ERROR\n");
usb_request_sense(srb, ss);
+ if (smallblks > 2047) { /* Dynamically reduce the I/O size. */
+ ss->max_xfer_blk = 2047;
+ debug("step down usb_max_xfer_blk to %d\n", ss->max_xfer_blk);
+ ++retry;
+ }
+ else if (smallblks > 512) {
+ ss->max_xfer_blk = 512;
+ debug("step down usb_max_xfer_blk to %d\n", ss->max_xfer_blk);
+ ++retry;
+ }
+ else if (smallblks > 511) {
+ ss->max_xfer_blk = 511;
+ debug("step down usb_max_xfer_blk to %d\n", ss->max_xfer_blk);
+ ++retry;
+ }
+ else if (smallblks > 63) {
+ ss->max_xfer_blk = 63;
+ debug("step down usb_max_xfer_blk to %d\n", ss->max_xfer_blk);
+ retry += 2;
+ }
+
if (retry--)
goto retry_it;
blkcnt -= blks;
setenv usb_max_blk 2000