[U-Boot] [PATCH 3/3] usb_storage:Fix USB storage capacity detection on 64 bit architectures

Sergey Temerkhanov s.temerkhanov at gmail.com
Wed Apr 1 16:18:46 CEST 2015


This patch fixes USB storage capacity detection breakage on 64-bit systems
which arises due to 'unsigned long' length difference. Old code assumes that
to be 32 bit and breaks because of inappropriate response buffer layout.
Also this fixes a number of build warnings and changes big-endian values
treatment style to be architecture-independent 

Signed-off-by: Sergey Temerkhanov <s.temerkhanov at gmail.com>
Signed-off-by: Radha Mohan Chintakuntla <rchintakuntla at cavium.com>
---
 common/usb_storage.c | 44 +++++++++++++++++++++++---------------------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 1411737..a1dfc58 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -336,8 +336,8 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
 		/* set up the transfer loop */
 		do {
 			/* transfer the data */
-			debug("Bulk xfer 0x%x(%d) try #%d\n",
-			      (unsigned int)buf, this_xfer, 11 - maxtry);
+			debug("Bulk xfer %p(%d) try #%d\n",
+			      buf, this_xfer, 11 - maxtry);
 			result = usb_bulk_msg(us->pusb_dev, pipe, buf,
 					      this_xfer, &partial,
 					      USB_CNTL_TIMEOUT * 5);
@@ -514,6 +514,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	cbw->bCDBLength = srb->cmdlen;
 	/* copy the command data into the CBW command data buffer */
 	/* DST SRC LEN!!! */
+
 	memcpy(cbw->CBWCDB, srb->cmd, srb->cmdlen);
 	result = usb_bulk_msg(us->pusb_dev, pipe, cbw, UMASS_BBB_CBW_SIZE,
 			      &actlen, USB_CNTL_TIMEOUT * 5);
@@ -603,7 +604,7 @@ static int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
 			(void *) &us->ip_data, us->irqmaxp, us->irqinterval);
 	timeout = 1000;
 	while (timeout--) {
-		if ((volatile int *) us->ip_wanted == NULL)
+		if (us->ip_wanted == 0)
 			break;
 		mdelay(10);
 	}
@@ -689,6 +690,7 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 		pipe = pipein;
 	else
 		pipe = pipeout;
+
 	result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen,
 			      &data_actlen, USB_CNTL_TIMEOUT * 5);
 	/* special handling of STALL in DATA phase */
@@ -1067,7 +1069,7 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
 	srb->lun = usb_dev_desc[device].lun;
-	buf_addr = (unsigned long)buffer;
+	buf_addr = (uintptr_t)buffer;
 	start = blknr;
 	blks = blkcnt;
 
@@ -1141,7 +1143,7 @@ unsigned long usb_stor_write(int device, lbaint_t blknr,
 	usb_disable_asynch(1); /* asynch transfer not allowed */
 
 	srb->lun = usb_dev_desc[device].lun;
-	buf_addr = (unsigned long)buffer;
+	buf_addr = (uintptr_t)buffer;
 	start = blknr;
 	blks = blkcnt;
 
@@ -1334,9 +1336,9 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
-	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
-	unsigned long *capacity, *blksz;
+	ALLOC_CACHE_ALIGN_BUFFER(u32, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(u8, usb_stor_buf, 36);
+	u32 capacity, blksz;
 	ccb *pccb = &usb_ccb;
 
 	pccb->pdata = usb_stor_buf;
@@ -1362,9 +1364,9 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		/* drive is removable */
 		dev_desc->removable = 1;
 	}
-	memcpy(&dev_desc->vendor[0], (const void *) &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], (const void *) &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], (const void *) &usb_stor_buf[32], 4);
+	memcpy(dev_desc->vendor, (const void *)&usb_stor_buf[8], 8);
+	memcpy(dev_desc->product, (const void *)&usb_stor_buf[16], 16);
+	memcpy(dev_desc->revision, (const void *)&usb_stor_buf[32], 4);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
@@ -1385,7 +1387,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		}
 		return 0;
 	}
-	pccb->pdata = (unsigned char *)&cap[0];
+	pccb->pdata = (unsigned char *)cap;
 	memset(pccb->pdata, 0, 8);
 	if (usb_read_capacity(pccb, ss) != 0) {
 		printf("READ_CAP ERROR\n");
@@ -1393,21 +1395,21 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		cap[1] = 0x200;
 	}
 	ss->flags &= ~USB_READY;
-	debug("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0], cap[1]);
+	debug("Read Capacity returns: 0x%08x, 0x%08x\n", cap[0], cap[1]);
 #if 0
 	if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */
 		cap[0] >>= 16;
-#endif
+
 	cap[0] = cpu_to_be32(cap[0]);
 	cap[1] = cpu_to_be32(cap[1]);
+#endif
+
+	capacity = be32_to_cpu(cap[0]) + 1;
+	blksz = be32_to_cpu(cap[1]);
 
-	/* this assumes bigendian! */
-	cap[0] += 1;
-	capacity = &cap[0];
-	blksz = &cap[1];
-	debug("Capacity = 0x%lx, blocksz = 0x%lx\n", *capacity, *blksz);
-	dev_desc->lba = *capacity;
-	dev_desc->blksz = *blksz;
+	debug("Capacity = 0x%08x, blocksz = 0x%08x\n", capacity, blksz);
+	dev_desc->lba = capacity;
+	dev_desc->blksz = blksz;
 	dev_desc->log2blksz = LOG2(dev_desc->blksz);
 	dev_desc->type = perq;
 	debug(" address %d\n", dev_desc->target);
-- 
2.3.3



More information about the U-Boot mailing list