From cffcc503580907d733e694d505e12ff6ec6c679a Mon Sep 17 00:00:00 2001 From: Benoît Thébaudeau Date: Fri, 10 Aug 2012 18:26:50 +0200 Subject: usb_storage: Restore non-EHCI support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- common/usb_storage.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'common/usb_storage.c') diff --git a/common/usb_storage.c b/common/usb_storage.c index bdc306f58..0cd6399a3 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]; -- cgit v1.2.3-70-g09d2 From 4bee5c83ea46b5c7a5670f7decd6ba2515483d9c Mon Sep 17 00:00:00 2001 From: Benoît Thébaudeau Date: Fri, 10 Aug 2012 18:23:25 +0200 Subject: usb_storage: Remove EHCI constraints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the EHCI driver allocates its qTDs from the heap, the MSC driver is only limited by the SCSI commands it uses. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- common/usb_storage.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'common/usb_storage.c') diff --git a/common/usb_storage.c b/common/usb_storage.c index 0cd6399a3..099edd3fa 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -157,12 +157,13 @@ struct us_data { #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 + * 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(start, blksz) (((4096 * 5) - (start % 4096)) / blksz) +#define USB_MAX_XFER_BLK 65535 #else -#define USB_MAX_XFER_BLK(start, blksz) 20 +#define USB_MAX_XFER_BLK 20 #endif static struct us_data usb_stor[USB_MAX_STOR_DEV]; @@ -1050,7 +1051,7 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor, unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, void *buffer) { - unsigned long start, blks, buf_addr, max_xfer_blk; + unsigned long start, blks, buf_addr; unsigned short smallblks; struct usb_device *dev; struct us_data *ss; @@ -1092,14 +1093,12 @@ unsigned long usb_stor_read(int device, unsigned long blknr, /* XXX need some comment here */ retry = 2; srb->pdata = (unsigned char *)buf_addr; - max_xfer_blk = USB_MAX_XFER_BLK(buf_addr, - usb_dev_desc[device].blksz); - if (blks > max_xfer_blk) - smallblks = (unsigned short) max_xfer_blk; + if (blks > USB_MAX_XFER_BLK) + smallblks = USB_MAX_XFER_BLK; else smallblks = (unsigned short) blks; retry_it: - if (smallblks == max_xfer_blk) + if (smallblks == USB_MAX_XFER_BLK) usb_show_progress(); srb->datalen = usb_dev_desc[device].blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; @@ -1120,7 +1119,7 @@ retry_it: start, smallblks, buf_addr); usb_disable_asynch(0); /* asynch transfer allowed */ - if (blkcnt >= max_xfer_blk) + if (blkcnt >= USB_MAX_XFER_BLK) debug("\n"); return blkcnt; } @@ -1128,7 +1127,7 @@ retry_it: unsigned long usb_stor_write(int device, unsigned long blknr, unsigned long blkcnt, const void *buffer) { - unsigned long start, blks, buf_addr, max_xfer_blk; + unsigned long start, blks, buf_addr; unsigned short smallblks; struct usb_device *dev; struct us_data *ss; @@ -1173,14 +1172,12 @@ unsigned long usb_stor_write(int device, unsigned long blknr, */ retry = 2; srb->pdata = (unsigned char *)buf_addr; - max_xfer_blk = USB_MAX_XFER_BLK(buf_addr, - usb_dev_desc[device].blksz); - if (blks > max_xfer_blk) - smallblks = (unsigned short) max_xfer_blk; + if (blks > USB_MAX_XFER_BLK) + smallblks = USB_MAX_XFER_BLK; else smallblks = (unsigned short) blks; retry_it: - if (smallblks == max_xfer_blk) + if (smallblks == USB_MAX_XFER_BLK) usb_show_progress(); srb->datalen = usb_dev_desc[device].blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; @@ -1201,7 +1198,7 @@ retry_it: start, smallblks, buf_addr); usb_disable_asynch(0); /* asynch transfer allowed */ - if (blkcnt >= max_xfer_blk) + if (blkcnt >= USB_MAX_XFER_BLK) debug("\n"); return blkcnt; -- cgit v1.2.3-70-g09d2 From 3e8581bb95899e21b01d86e9fe5ad7358bbef142 Mon Sep 17 00:00:00 2001 From: Benoît Thébaudeau Date: Fri, 10 Aug 2012 18:27:11 +0200 Subject: usb_stor_BBB_transport: Do not delay when not required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a 5-ms delay in usb_stor_BBB_transport, which occurs every 10 kiB of data for fragmented fatload usb, i.e. roughly 500 ms of delay per MiB. This adds up to quite a bit of delay if you're loading a large ramdisk. The purpose of this delay should be to debounce the 5-V/100-mA USB power up. This patch skips the delay if the device has already been queried as ready. Signed-off-by: Jim Shimer Rework following the review: - Rebase against the latest u-boot-usb master. - Replace typedef with #define. - Use the existing flags struct field instead of adding a new field. - Remove the setter function. - Remove the typecasts. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier Cc: Jim Shimer --- common/usb_storage.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'common/usb_storage.c') diff --git a/common/usb_storage.c b/common/usb_storage.c index 099edd3fa..ccfe811ee 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -136,6 +136,7 @@ struct us_data { struct usb_device *pusb_dev; /* this usb_device */ unsigned int flags; /* from filter initially */ +# define USB_READY (1 << 0) unsigned char ifnum; /* interface number */ unsigned char ep_in; /* in endpoint */ unsigned char ep_out; /* out ....... */ @@ -698,7 +699,8 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us) usb_stor_BBB_reset(us); return USB_STOR_TRANSPORT_FAILED; } - mdelay(5); + if (!(us->flags & USB_READY)) + mdelay(5); pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in); pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out); /* DATA phase + error handling */ @@ -963,8 +965,10 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss) srb->cmd[1] = srb->lun << 5; srb->datalen = 0; srb->cmdlen = 12; - if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) + if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) { + ss->flags |= USB_READY; return 0; + } usb_request_sense(srb, ss); mdelay(100); } while (retries--); @@ -1114,6 +1118,7 @@ retry_it: blks -= smallblks; buf_addr += srb->datalen; } while (blks != 0); + ss->flags &= ~USB_READY; USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n", start, smallblks, buf_addr); @@ -1193,6 +1198,7 @@ retry_it: blks -= smallblks; buf_addr += srb->datalen; } while (blks != 0); + ss->flags &= ~USB_READY; USB_STOR_PRINTF("usb_write: end startblk %lx, blccnt %x buffer %lx\n", start, smallblks, buf_addr); @@ -1404,6 +1410,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, cap[0] = 2880; cap[1] = 0x200; } + ss->flags &= ~USB_READY; USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0], cap[1]); #if 0 -- cgit v1.2.3-70-g09d2 From b7006958ea367394e39e82532317a44491ed52ac Mon Sep 17 00:00:00 2001 From: Jim Shimer Date: Mon, 30 Jul 2012 22:11:28 -0400 Subject: usb: Optimize USB storage read/write Trim down the IO times by removing uneeded test unit reeady calls. Signed-off-by: Jim Shimer --- common/usb_storage.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'common/usb_storage.c') diff --git a/common/usb_storage.c b/common/usb_storage.c index ccfe811ee..4aeed827c 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -1083,12 +1083,6 @@ unsigned long usb_stor_read(int device, unsigned long blknr, buf_addr = (unsigned long)buffer; start = blknr; blks = blkcnt; - if (usb_test_unit_ready(srb, ss)) { - printf("Device NOT ready\n Request Sense returned %02X %02X" - " %02X\n", srb->sense_buf[2], srb->sense_buf[12], - srb->sense_buf[13]); - return 0; - } USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx" " buffer %lx\n", device, start, blks, buf_addr); @@ -1161,12 +1155,6 @@ unsigned long usb_stor_write(int device, unsigned long blknr, buf_addr = (unsigned long)buffer; start = blknr; blks = blkcnt; - if (usb_test_unit_ready(srb, ss)) { - printf("Device NOT ready\n Request Sense returned %02X %02X" - " %02X\n", srb->sense_buf[2], srb->sense_buf[12], - srb->sense_buf[13]); - return 0; - } USB_STOR_PRINTF("\nusb_write: dev %d startblk %lx, blccnt %lx" " buffer %lx\n", device, start, blks, buf_addr); -- cgit v1.2.3-70-g09d2