#include <common.h>
+#include <blk.h>
#include <command.h>
#include <dm.h>
#include <errno.h>
-#include <inttypes.h>
#include <mapmem.h>
#include <memalign.h>
#include <asm/byteorder.h>
+#include <asm/cache.h>
#include <asm/processor.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
static int usb_max_devs; /* number of highest available usb device */
-#ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(BLK)
static struct blk_desc usb_dev_desc[USB_MAX_STOR_DEV];
#endif
unsigned short max_xfer_blk; /* maximum transfer blocks */
};
-#ifndef CONFIG_BLK
+#if !CONFIG_IS_ENABLED(BLK)
static struct us_data usb_stor[USB_MAX_STOR_DEV];
#endif
struct blk_desc *dev_desc);
int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
struct us_data *ss);
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
lbaint_t blkcnt, void *buffer);
static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
int usb_stor_info(void)
{
int count = 0;
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
struct udevice *dev;
for (blk_first_device(IF_TYPE_USB, &dev);
{
int lun, max_lun;
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
struct us_data *data;
int ret;
#else
#endif
debug("\n\nProbing for storage\n");
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
/*
* We store the us_data in the mass storage device's platdata. It
* is shared by all LUNs (block devices) attached to this mass storage
blkdev->lun = lun;
ret = usb_stor_get_info(udev, data, blkdev);
- if (ret == 1)
- ret = blk_prepare_device(dev);
- if (!ret) {
+ if (ret == 1) {
usb_max_devs++;
debug("%s: Found device %p\n", __func__, udev);
} else {
if (mode == 1)
printf(" scanning usb for storage devices... ");
-#ifndef CONFIG_DM_USB
+#if !CONFIG_IS_ENABLED(DM_USB)
unsigned char i;
usb_disable_asynch(1); /* asynch transfer not allowed */
int timeout;
us->ip_wanted = 1;
- submit_int_msg(us->pusb_dev, us->irqpipe,
- (void *) &us->ip_data, us->irqmaxp, us->irqinterval);
+ usb_int_msg(us->pusb_dev, us->irqpipe,
+ (void *)&us->ip_data, us->irqmaxp, us->irqinterval, false);
timeout = 1000;
while (timeout--) {
if (us->ip_wanted == 0)
static void usb_stor_set_max_xfer_blk(struct usb_device *udev,
struct us_data *us)
{
- unsigned short blk;
- size_t __maybe_unused size;
- int __maybe_unused ret;
-
-#ifndef CONFIG_DM_USB
-#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.
+ * Limit the total size of a transfer to 120 KB.
+ *
+ * Some devices are known to choke with anything larger. It seems like
+ * the problem stems from the fact that original IDE controllers had
+ * only an 8-bit register to hold the number of sectors in one transfer
+ * and even those couldn't handle a full 256 sectors.
+ *
+ * Because we want to make sure we interoperate with as many devices as
+ * possible, we will maintain a 240 sector transfer size limit for USB
+ * Mass Storage devices.
+ *
+ * Tests show that other operating have similar limits with Microsoft
+ * Windows 7 limiting transfers to 128 sectors for both USB2 and USB3
+ * and Apple Mac OS X 10.11 limiting transfers to 256 sectors for USB2
+ * and 2048 for USB3 devices.
*/
- blk = USHRT_MAX;
-#else
- blk = 20;
-#endif
-#else
+ unsigned short blk = 240;
+
+#if CONFIG_IS_ENABLED(DM_USB)
+ size_t size;
+ int ret;
+
ret = usb_get_max_xfer_size(udev, (size_t *)&size);
- if (ret < 0) {
- /* unimplemented, let's use default 20 */
- blk = 20;
- } else {
- if (size > USHRT_MAX * 512)
- size = USHRT_MAX * 512;
+ if ((ret >= 0) && (size < blk * 512))
blk = size / 512;
- }
#endif
us->max_xfer_blk = blk;
}
#endif /* CONFIG_USB_BIN_FIXUP */
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
lbaint_t blkcnt, void *buffer)
#else
struct us_data *ss;
int retry;
struct scsi_cmd *srb = &usb_ccb;
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
struct blk_desc *block_dev;
#endif
if (blkcnt == 0)
return 0;
/* Setup device */
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
block_dev = dev_get_uclass_platdata(dev);
udev = dev_get_parent_priv(dev_get_parent(dev));
debug("\nusb_read: udev %d\n", block_dev->devnum);
ss = (struct us_data *)udev->privptr;
usb_disable_asynch(1); /* asynch transfer not allowed */
+ usb_lock_async(udev, 1);
srb->lun = block_dev->lun;
buf_addr = (uintptr_t)buffer;
start = blknr;
blks = blkcnt;
- debug("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF " buffer %"
- PRIxPTR "\n", block_dev->devnum, start, blks, buf_addr);
+ debug("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
+ block_dev->devnum, start, blks, buf_addr);
do {
/* XXX need some comment here */
srb->pdata = (unsigned char *)buf_addr;
if (usb_read_10(srb, ss, start, smallblks)) {
debug("Read ERROR\n");
+ ss->flags &= ~USB_READY;
usb_request_sense(srb, ss);
if (retry--)
goto retry_it;
blks -= smallblks;
buf_addr += srb->datalen;
} while (blks != 0);
- ss->flags &= ~USB_READY;
- debug("usb_read: end startblk " LBAF
- ", blccnt %x buffer %" PRIxPTR "\n",
+ debug("usb_read: end startblk " LBAF ", blccnt %x buffer %lx\n",
start, smallblks, buf_addr);
+ usb_lock_async(udev, 0);
usb_disable_asynch(0); /* asynch transfer allowed */
if (blkcnt >= ss->max_xfer_blk)
debug("\n");
return blkcnt;
}
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
lbaint_t blkcnt, const void *buffer)
#else
struct us_data *ss;
int retry;
struct scsi_cmd *srb = &usb_ccb;
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
struct blk_desc *block_dev;
#endif
return 0;
/* Setup device */
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
block_dev = dev_get_uclass_platdata(dev);
udev = dev_get_parent_priv(dev_get_parent(dev));
debug("\nusb_read: udev %d\n", block_dev->devnum);
ss = (struct us_data *)udev->privptr;
usb_disable_asynch(1); /* asynch transfer not allowed */
+ usb_lock_async(udev, 1);
srb->lun = block_dev->lun;
buf_addr = (uintptr_t)buffer;
start = blknr;
blks = blkcnt;
- debug("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF " buffer %"
- PRIxPTR "\n", block_dev->devnum, start, blks, buf_addr);
+ debug("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF " buffer %lx\n",
+ block_dev->devnum, start, blks, buf_addr);
do {
/* If write fails retry for max retry count else
srb->pdata = (unsigned char *)buf_addr;
if (usb_write_10(srb, ss, start, smallblks)) {
debug("Write ERROR\n");
+ ss->flags &= ~USB_READY;
usb_request_sense(srb, ss);
if (retry--)
goto retry_it;
blks -= smallblks;
buf_addr += srb->datalen;
} while (blks != 0);
- ss->flags &= ~USB_READY;
- debug("usb_write: end startblk " LBAF ", blccnt %x buffer %"
- PRIxPTR "\n", start, smallblks, buf_addr);
+ debug("usb_write: end startblk " LBAF ", blccnt %x buffer %lx\n",
+ start, smallblks, buf_addr);
+ usb_lock_async(udev, 0);
usb_disable_asynch(0); /* asynch transfer allowed */
if (blkcnt >= ss->max_xfer_blk)
debug("\n");
memset(pccb->pdata, 0, 8);
if (usb_read_capacity(pccb, ss) != 0) {
printf("READ_CAP ERROR\n");
+ ss->flags &= ~USB_READY;
cap[0] = 2880;
cap[1] = 0x200;
}
- ss->flags &= ~USB_READY;
debug("Read Capacity returns: 0x%08x, 0x%08x\n", cap[0], cap[1]);
#if 0
if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
return 1;
}
-#ifdef CONFIG_DM_USB
+#if CONFIG_IS_ENABLED(DM_USB)
static int usb_mass_storage_probe(struct udevice *dev)
{
.id = UCLASS_MASS_STORAGE,
.of_match = usb_mass_storage_ids,
.probe = usb_mass_storage_probe,
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
.platdata_auto_alloc_size = sizeof(struct us_data),
#endif
};
U_BOOT_USB_DEVICE(usb_mass_storage, mass_storage_id_table);
#endif
-#ifdef CONFIG_BLK
+#if CONFIG_IS_ENABLED(BLK)
static const struct blk_ops usb_storage_ops = {
.read = usb_stor_read,
.write = usb_stor_write,