summaryrefslogtreecommitdiff
path: root/common/usb_storage.c
diff options
context:
space:
mode:
authorBartlomiej Sieka <tur@semihalf.com>2006-08-22 10:38:18 +0200
committerBartlomiej Sieka <tur@semihalf.com>2006-08-22 10:38:18 +0200
commitddde6b7cf8341a15ad46551dc611488e9a3f36e6 (patch)
treec2c0adc8236516de0fbcff26403da04e84c0601e /common/usb_storage.c
parent6d3bc9b8cfd5d60708f95ded007cda7bc29ac089 (diff)
downloadu-boot-imx-ddde6b7cf8341a15ad46551dc611488e9a3f36e6.zip
u-boot-imx-ddde6b7cf8341a15ad46551dc611488e9a3f36e6.tar.gz
u-boot-imx-ddde6b7cf8341a15ad46551dc611488e9a3f36e6.tar.bz2
Add a fix for a buggy USB device on the FO300 board.
Diffstat (limited to 'common/usb_storage.c')
-rw-r--r--common/usb_storage.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/common/usb_storage.c b/common/usb_storage.c
index e64470c..69ecf18 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -916,6 +916,28 @@ static int usb_read_10(ccb *srb,struct us_data *ss, unsigned long start, unsigne
}
+#ifdef CONFIG_USB_BIN_FIXUP
+/*
+ * Some USB storage devices queried for SCSI identification data respond with
+ * binary strings, which if output to the console freeze the terminal. The
+ * workaround is to modify the vendor and product strings read from such
+ * device with proper values (as reported by 'usb info').
+ *
+ * Vendor and product length limits are taken from the definition of
+ * block_dev_desc_t in include/part.h.
+ */
+static void usb_bin_fixup(struct usb_device_descriptor descriptor,
+ unsigned char vendor[],
+ unsigned char product[]) {
+ const unsigned char max_vendor_len = 40;
+ const unsigned char max_product_len = 20;
+ if (descriptor.idVendor == 0x0424 && descriptor.idProduct == 0x223a) {
+ strncpy(vendor, "SMSC", max_vendor_len);
+ strncpy(product, "Flash Media Cntrller", max_product_len);
+ }
+}
+#endif /* CONFIG_USB_BIN_FIXUP */
+
#define USB_MAX_READ_BLK 20
unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer)
@@ -1171,6 +1193,9 @@ int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t
dev_desc->vendor[8] = 0;
dev_desc->product[16] = 0;
dev_desc->revision[4] = 0;
+#ifdef CONFIG_USB_BIN_FIXUP
+ usb_bin_fixup(dev->descriptor, dev_desc->vendor, dev_desc->product);
+#endif /* CONFIG_USB_BIN_FIXUP */
USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n",usb_stor_buf[2],usb_stor_buf[3]);
if(usb_test_unit_ready(pccb,ss)) {
printf("Device NOT ready\n Request Sense returned %02X %02X %02X\n",pccb->sense_buf[2],pccb->sense_buf[12],pccb->sense_buf[13]);