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 ....... */
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
+ * 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 20
+#endif
static struct us_data usb_stor[USB_MAX_STOR_DEV];
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 */
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--);
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;
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);
/* 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;
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);
usb_disable_asynch(0); /* asynch transfer allowed */
- if (blkcnt >= max_xfer_blk)
+ if (blkcnt >= USB_MAX_XFER_BLK)
debug("\n");
return blkcnt;
}
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;
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);
*/
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;
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);
usb_disable_asynch(0); /* asynch transfer allowed */
- if (blkcnt >= max_xfer_blk)
+ if (blkcnt >= USB_MAX_XFER_BLK)
debug("\n");
return blkcnt;
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