#include <common.h>
+#include <blk.h>
+#include <bootdev.h>
#include <command.h>
#include <dm.h>
#include <errno.h>
+#include <log.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>
+#include <linux/delay.h>
#include <part.h>
#include <usb.h>
int action; /* what to do */
int ip_wanted; /* needed */
int *irq_handle; /* for USB int requests */
- unsigned int irqpipe; /* pipe for release_irq */
+ unsigned int irqpipe; /* pipe for release_irq */
unsigned char irqmaxp; /* max packed for irq Pipe */
unsigned char irqinterval; /* Intervall for IRQ Pipe */
struct scsi_cmd *srb; /* current srb */
for (blk_first_device(IF_TYPE_USB, &dev);
dev;
blk_next_device(&dev)) {
- struct blk_desc *desc = dev_get_uclass_platdata(dev);
+ struct blk_desc *desc = dev_get_uclass_plat(dev);
printf(" Device %d: ", desc->devnum);
dev_print(desc);
debug("\n\nProbing for storage\n");
#if CONFIG_IS_ENABLED(BLK)
/*
- * We store the us_data in the mass storage device's platdata. It
+ * We store the us_data in the mass storage device's plat. It
* is shared by all LUNs (block devices) attached to this mass storage
* device.
*/
- data = dev_get_platdata(udev->dev);
+ data = dev_get_plat(udev->dev);
if (!usb_storage_probe(udev, 0, data))
return 0;
max_lun = usb_get_max_lun(data);
return ret;
}
- blkdev = dev_get_uclass_platdata(dev);
+ blkdev = dev_get_uclass_plat(dev);
blkdev->target = 0xff;
blkdev->lun = lun;
if (ret)
return ret;
}
+
+ ret = blk_probe_or_unbind(dev);
+ if (ret)
+ return ret;
+
+ ret = bootdev_setup_sibling_blk(dev, "usb_bootdev");
+ if (ret) {
+ int ret2;
+
+ ret2 = device_unbind(dev);
+ if (ret2)
+ return log_msg_ret("bootdev", ret2);
+ return log_msg_ret("bootdev", ret);
+ }
}
#else
/* We don't have space to even probe if we hit the maximum */
return 0;
}
/* if our try counter reaches 0, bail out */
- debug(" %ld, data %d\n",
- us->pusb_dev->status, partial);
+ debug(" %ld, data %d\n",
+ us->pusb_dev->status, partial);
if (!maxtry--)
return result;
}
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;
-
-#if !CONFIG_IS_ENABLED(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;
return 0;
/* Setup device */
#if CONFIG_IS_ENABLED(BLK)
- block_dev = dev_get_uclass_platdata(dev);
+ block_dev = dev_get_uclass_plat(dev);
udev = dev_get_parent_priv(dev_get_parent(dev));
debug("\nusb_read: udev %d\n", block_dev->devnum);
#else
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;
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 %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");
/* Setup device */
#if CONFIG_IS_ENABLED(BLK)
- block_dev = dev_get_uclass_platdata(dev);
+ block_dev = dev_get_uclass_plat(dev);
udev = dev_get_parent_priv(dev_get_parent(dev));
debug("\nusb_read: udev %d\n", block_dev->devnum);
#else
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;
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 %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 */
.of_match = usb_mass_storage_ids,
.probe = usb_mass_storage_probe,
#if CONFIG_IS_ENABLED(BLK)
- .platdata_auto_alloc_size = sizeof(struct us_data),
+ .plat_auto = sizeof(struct us_data),
#endif
};