summaryrefslogtreecommitdiff
path: root/common/usb_storage.c
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2012-07-20 09:12:43 +0200
committerWolfgang Denk <wd@denx.de>2012-07-20 09:12:43 +0200
commit3ec81d758c09d6887a77a1b1259d044a2905bc8e (patch)
treef86e0095994be54d6a94c01c7dd5d977d56e0fce /common/usb_storage.c
parentad8439d4645200b5a4f230dd07b73ae956b88c1e (diff)
parent1b4bd0e66cd3b5124669c78bc968510b1040e9d9 (diff)
downloadolio-uboot-2014.01-3ec81d758c09d6887a77a1b1259d044a2905bc8e.tar.xz
olio-uboot-2014.01-3ec81d758c09d6887a77a1b1259d044a2905bc8e.zip
Merge branch 'master' of git://git.denx.de/u-boot-usb
* 'master' of git://git.denx.de/u-boot-usb: usb_storage: fix ehci driver max transfer size smsc95xx: align buffers to cache line size ehci-hcd: change debug() to printf() in case of errors usb: check return value of submit_{control, bulk}_msg usb: pass cache-aligned buffer to usb_get_descriptor() ehci-hcd: fix external buffer cache handling ehci-hcd.c, musb_core, usb.h: Add USB_DMA_MINALIGN define for cache alignment ehci-hcd: program asynclistaddr before every transfer common.h: Introduce DEFINE_CACHE_ALIGN_BUFFER ehci-omap: Do not call dcache_off from omap_ehci_hcd_init Signed-off-by: Wolfgang Denk <wd@denx.de>
Diffstat (limited to 'common/usb_storage.c')
-rw-r--r--common/usb_storage.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/common/usb_storage.c b/common/usb_storage.c
index faad23706..bdc306f58 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -150,12 +150,17 @@ struct us_data {
unsigned int irqpipe; /* pipe for release_irq */
unsigned char irqmaxp; /* max packed for irq Pipe */
unsigned char irqinterval; /* Intervall for IRQ Pipe */
- unsigned long max_xfer_blk; /* Max blocks per xfer */
ccb *srb; /* current srb */
trans_reset transport_reset; /* reset routine */
trans_cmnd transport; /* transport routine */
};
+/*
+ * 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)
+
static struct us_data usb_stor[USB_MAX_STOR_DEV];
@@ -1041,7 +1046,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;
+ unsigned long start, blks, buf_addr, max_xfer_blk;
unsigned short smallblks;
struct usb_device *dev;
struct us_data *ss;
@@ -1083,12 +1088,14 @@ unsigned long usb_stor_read(int device, unsigned long blknr,
/* XXX need some comment here */
retry = 2;
srb->pdata = (unsigned char *)buf_addr;
- if (blks > ss->max_xfer_blk)
- smallblks = ss->max_xfer_blk;
+ 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;
else
smallblks = (unsigned short) blks;
retry_it:
- if (smallblks == ss->max_xfer_blk)
+ if (smallblks == max_xfer_blk)
usb_show_progress();
srb->datalen = usb_dev_desc[device].blksz * smallblks;
srb->pdata = (unsigned char *)buf_addr;
@@ -1109,7 +1116,7 @@ retry_it:
start, smallblks, buf_addr);
usb_disable_asynch(0); /* asynch transfer allowed */
- if (blkcnt >= ss->max_xfer_blk)
+ if (blkcnt >= max_xfer_blk)
debug("\n");
return blkcnt;
}
@@ -1117,7 +1124,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;
+ unsigned long start, blks, buf_addr, max_xfer_blk;
unsigned short smallblks;
struct usb_device *dev;
struct us_data *ss;
@@ -1162,12 +1169,14 @@ unsigned long usb_stor_write(int device, unsigned long blknr,
*/
retry = 2;
srb->pdata = (unsigned char *)buf_addr;
- if (blks > ss->max_xfer_blk)
- smallblks = ss->max_xfer_blk;
+ 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;
else
smallblks = (unsigned short) blks;
retry_it:
- if (smallblks == ss->max_xfer_blk)
+ if (smallblks == max_xfer_blk)
usb_show_progress();
srb->datalen = usb_dev_desc[device].blksz * smallblks;
srb->pdata = (unsigned char *)buf_addr;
@@ -1188,7 +1197,7 @@ retry_it:
start, smallblks, buf_addr);
usb_disable_asynch(0); /* asynch transfer allowed */
- if (blkcnt >= ss->max_xfer_blk)
+ if (blkcnt >= max_xfer_blk)
debug("\n");
return blkcnt;
@@ -1415,12 +1424,6 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
USB_STOR_PRINTF(" address %d\n", dev_desc->target);
USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
- /*
- * The U-Boot EHCI driver cannot handle more than 4096 * 5 bytes in a
- * transfer without running itself out of qt_buffers.
- */
- ss->max_xfer_blk = (4096 * 5) / dev_desc->blksz;
-
init_part(dev_desc);
USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);