All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] usb: align buffers at cache boundary
@ 2012-02-17 10:50 Puneet Saxena
  2012-02-17 17:23 ` Mike Frysinger
  0 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-02-17 10:50 UTC (permalink / raw)
  To: u-boot

This aligns buffers,passed to usb controller at
dcache boundary.

Buffer "stop" address = "start" address + size.
Stop address can not be aligned even though
"start" address is aligned as size does not fall
at cache line boundary. Therefore "debug" in place of
"printf" is added in "arch/arm/cpu/armv7/cache_v7.c".
Cleaning and invalidating last cache line to avoid
stale data to be reused.

Ignoring "checkpatch.pl" warnings to replace "__attribute__((packed))"
by "__packed" and "__attribute__((aligned(size)))" by "__aligned(size)".
As "__GNUC__" directive should be defined to use "__packed" and
"__aligned(size)" and current patch is not supporting it, ignoring
the "checkpatch.pl" warning.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
Signed-off-by: Jim Lin <jilin@nvidia.com>
---
The patch is applicable on tegra U-Boot Custodian Tree owned by Tom Warren.
To apply the patch clone "git://git.denx.de/u-boot-tegra.git" and checkout
"test" branch.

 arch/arm/cpu/armv7/cache_v7.c |    8 ++++-
 common/cmd_usb.c              |    3 +-
 common/usb.c                  |   42 ++++++++++++++++------------
 common/usb_storage.c          |   60 ++++++++++++++++++++++++-----------------
 drivers/usb/host/ehci-hcd.c   |   12 ++++++++
 include/scsi.h                |    8 +++++-
 include/usb.h                 |    8 +++++-
 7 files changed, 93 insertions(+), 48 deletions(-)

diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index 1b4e808..435d08b 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -192,12 +192,16 @@ static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len)
 	}
 
 	/*
+	 * We can't avoid stop address not aligned with cache-line.
+	 * Allocating cache -aligned buffer might waste memory.
 	 * If stop address is not aligned to cache-line do not
-	 * invalidate the last cache-line
+	 * invalidate the last cache-line and flush the last
+	 * line to prevent affecting somebody else's buffer.
 	 */
 	if (stop & (line_len - 1)) {
-		printf("ERROR: %s - stop address is not aligned - 0x%08x\n",
+		debug("ERROR: %s - stop address is not aligned - 0x%08x\n",
 			__func__, stop);
+		v7_dcache_clean_inval_range(stop, stop + 1, line_len);
 		/* align to the beginning of this cache line */
 		stop &= ~(line_len - 1);
 	}
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 63a11c8..07f7ed6 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,12 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+	static struct devrequest setup_packet
+		__attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
+#else
+	static struct devrequest setup_packet;
+#endif
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -694,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -794,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -921,8 +926,8 @@ int usb_new_device(struct usb_device *dev)
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1076,7 +1081,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1085,13 +1090,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1129,19 +1134,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1190,7 +1195,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1312,16 +1318,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..71e13b1 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,18 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+	static unsigned char usb_stor_buf[512]
+		__attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
+#else
+	static unsigned char usb_stor_buf[512];
+#endif
+
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+	static ccb usb_ccb __attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
+#else
+	static ccb usb_ccb;
+#endif
 
 /*
  * CBI style
@@ -210,17 +220,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -499,7 +509,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +532,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +685,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +743,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +763,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +792,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,7 +1353,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..7929c26 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -132,8 +132,20 @@ static void cache_qtd(struct qTD *qtd, int flush)
 	int len = (qtd->qt_token & 0x7fff0000) >> 16;
 
 	flush_invalidate((u32)qtd, sizeof(struct qTD), flush);
+
+	/*
+	 * Invalidate cache for the aligned address
+	 * and for the data length which is DMAed.
+	 * Do not invalidate again intermidiate address
+	 * as it may not be aligned.
+	 */
+#if CONFIG_SYS_CACHELINE_SIZE
+	if (!((u32) ptr & (CONFIG_SYS_CACHELINE_SIZE - 1)) && len)
+		flush_invalidate((u32)ptr, len, flush);
+#else
 	if (ptr && len)
 		flush_invalidate((u32)ptr, len, flush);
+#endif
 }
 
 
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..c07b1dd 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,13 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
+#else
+	unsigned char		sense_buf[64];
+#endif
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
diff --git a/include/usb.h b/include/usb.h
index 06170cd..55b786e 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -109,7 +109,13 @@ struct usb_device {
 	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	int configno;			/* selected config number */
-	struct usb_device_descriptor descriptor; /* Device Descriptor */
+	 /* Device Descriptor */
+#ifdef CONFIG_SYS_CACHELINE_SIZE
+	struct usb_device_descriptor descriptor
+		__attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
+#else
+	struct usb_device_descriptor descriptor;
+#endif
 	struct usb_config config; /* config descriptor */
 
 	int have_langid;		/* whether string_langid is valid yet */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH] usb: align buffers at cache boundary
  2012-02-17 10:50 [U-Boot] [PATCH] usb: align buffers at cache boundary Puneet Saxena
@ 2012-02-17 17:23 ` Mike Frysinger
  2012-02-23 14:25   ` [U-Boot] [PATCH 1/2] usb: align buffers at cacheline Puneet Saxena
  2012-02-23 14:25   ` [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255" Puneet Saxena
  0 siblings, 2 replies; 83+ messages in thread
From: Mike Frysinger @ 2012-02-17 17:23 UTC (permalink / raw)
  To: u-boot

On Friday 17 February 2012 05:50:21 Puneet Saxena wrote:
> This aligns buffers,passed to usb controller at
> dcache boundary.
> 
> Buffer "stop" address = "start" address + size.
> Stop address can not be aligned even though
> "start" address is aligned as size does not fall
> at cache line boundary. Therefore "debug" in place of
> "printf" is added in "arch/arm/cpu/armv7/cache_v7.c".
> Cleaning and invalidating last cache line to avoid
> stale data to be reused.

the point is to align things based on the DMA constraints, not cacheline 
constraints (with the assumption that DMA constraints will always be equal or 
larger than cachelines and never smaller).  so using CONFIG_SYS_CACHELINE_SIZE 
is wrong.  this is exactly why we have ARCH_DMA_MINALIGN.

> Ignoring "checkpatch.pl" warnings to replace "__attribute__((packed))"
> by "__packed" and "__attribute__((aligned(size)))" by "__aligned(size)".
> As "__GNUC__" directive should be defined to use "__packed" and
> "__aligned(size)" and current patch is not supporting it, ignoring
> the "checkpatch.pl" warning.

i don't understand this.  we have linux/compiler.h which provides these macros 
so you should be able to use them.

so NAK to this implementation for the reasons above

> --- a/arch/arm/cpu/armv7/cache_v7.c
> +++ b/arch/arm/cpu/armv7/cache_v7.c
> 
>  	/*
> +	 * We can't avoid stop address not aligned with cache-line.
> +	 * Allocating cache -aligned buffer might waste memory.
>  	 * If stop address is not aligned to cache-line do not
> -	 * invalidate the last cache-line
> +	 * invalidate the last cache-line and flush the last
> +	 * line to prevent affecting somebody else's buffer.
>  	 */
>  	if (stop & (line_len - 1)) {
> -		printf("ERROR: %s - stop address is not aligned - 0x%08x\n",
> +		debug("ERROR: %s - stop address is not aligned - 0x%08x\n",
>  			__func__, stop);
> +		v7_dcache_clean_inval_range(stop, stop + 1, line_len);
>  		/* align to the beginning of this cache line */
>  		stop &= ~(line_len - 1);
>  	}

pretty sure this is ignoring the problem and so shouldn't get merged

> --- a/common/usb.c
> +++ b/common/usb.c
>
> -static struct devrequest setup_packet;
> +#ifdef CONFIG_SYS_CACHELINE_SIZE
> +	static struct devrequest setup_packet
> +		__attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
> +#else
> +	static struct devrequest setup_packet;
> +#endif

this is used in only one function, so it'd be better to simply move it to that 
one function rather than keeping it as a global.

> --- a/common/usb_storage.c
> +++ b/common/usb_storage.c
> 
> -static unsigned char usb_stor_buf[512];
> +#ifdef CONFIG_SYS_CACHELINE_SIZE
> +	static unsigned char usb_stor_buf[512]
> +		__attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
> +#else
> +	static unsigned char usb_stor_buf[512];
> +#endif

Marek has already posted a patch fixing this

> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -132,8 +132,20 @@ static void cache_qtd(struct qTD *qtd, int flush)
>  	int len = (qtd->qt_token & 0x7fff0000) >> 16;
> 
>  	flush_invalidate((u32)qtd, sizeof(struct qTD), flush);
> +
> +	/*
> +	 * Invalidate cache for the aligned address
> +	 * and for the data length which is DMAed.
> +	 * Do not invalidate again intermidiate address
> +	 * as it may not be aligned.
> +	 */
> +#if CONFIG_SYS_CACHELINE_SIZE
> +	if (!((u32) ptr & (CONFIG_SYS_CACHELINE_SIZE - 1)) && len)
> +		flush_invalidate((u32)ptr, len, flush);
> +#else
>  	if (ptr && len)
>  		flush_invalidate((u32)ptr, len, flush);
> +#endif
>  }

ugh no.  existing code is correct.

> --- a/include/scsi.h
> +++ b/include/scsi.h
> @@ -26,7 +26,13 @@
> 
>  typedef struct SCSI_cmd_block{
>  	unsigned char		cmd[16];					/* command				
   */
> -	unsigned char		sense_buf[64];		/* for request sense */
> +	/* for request sense */
> +#ifdef CONFIG_SYS_CACHELINE_SIZE
> +	unsigned char		sense_buf[64]
> +		__attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
> +#else
> +	unsigned char		sense_buf[64];
> +#endif

pretty sure this is wrong

> --- a/include/usb.h
> +++ b/include/usb.h
> @@ -109,7 +109,13 @@ struct usb_device {
>  	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
> 
>  	int configno;			/* selected config number */
> -	struct usb_device_descriptor descriptor; /* Device Descriptor */
> +	 /* Device Descriptor */
> +#ifdef CONFIG_SYS_CACHELINE_SIZE
> +	struct usb_device_descriptor descriptor
> +		__attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
> +#else
> +	struct usb_device_descriptor descriptor;
> +#endif
>  	struct usb_config config; /* config descriptor */
> 
>  	int have_langid;		/* whether string_langid is valid yet */

as is this
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120217/e26c721c/attachment.pgp>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 1/2] usb: align buffers at cacheline
  2012-02-17 17:23 ` Mike Frysinger
@ 2012-02-23 14:25   ` Puneet Saxena
  2012-02-23 18:15     ` Mike Frysinger
  2012-02-24 12:42     ` Simon Glass
  2012-02-23 14:25   ` [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255" Puneet Saxena
  1 sibling, 2 replies; 83+ messages in thread
From: Puneet Saxena @ 2012-02-23 14:25 UTC (permalink / raw)
  To: u-boot

As DMA expects the buffers to be equal and larger then
cache lines, This aligns buffers at cacheline.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
Signed-off-by: Jim Lin <jilin@nvidia.com>
---
Changes for v2:
   - Split the commit in to 2 commits
   - "ARCH_DMA_MINALIGN" replacement
   - Making stop address cache line aligned by
     making size as multiple of cache line
   - incorporated Marek and Mike's comment
 
 common/cmd_usb.c            |    3 +-
 common/usb.c                |   53 ++++++++++++++++++----------------
 common/usb_storage.c        |   66 ++++++++++++++++++++++--------------------
 drivers/usb/host/ehci-hcd.c |    9 ++++++
 include/scsi.h              |    8 ++++-
 include/usb.h               |    8 ++++-
 6 files changed, 88 insertions(+), 59 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 63a11c8..75926aa 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
+		sizeof(struct devrequest));
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
 		   "value 0x%X index 0x%X length 0x%X\n",
 		   request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	submit_control_msg(dev, pipe, data, size, setup_packet);
 	if (timeout == 0)
 		return (int)size;
 
@@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -842,7 +843,8 @@ int usb_new_device(struct usb_device *dev)
 	dev->epmaxpacketin[0] = 64;
 	dev->epmaxpacketout[0] = 64;
 
-	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
+	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
+			sizeof(struct usb_device_descriptor));
 	if (err < 0) {
 		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
 		return 1;
@@ -921,8 +923,8 @@ int usb_new_device(struct usb_device *dev)
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1076,7 +1078,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1085,13 +1087,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1129,19 +1131,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1190,7 +1192,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1312,16 +1315,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..f8df5ae 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,11 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+#ifdef ARCH_DMA_MINALIGN
+	static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
+#else
+	static ccb usb_ccb;
+#endif
 
 /*
  * CBI style
@@ -210,17 +213,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -233,9 +236,6 @@ int usb_stor_scan(int mode)
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
 		printf("       scanning bus for storage devices... ");
 
@@ -499,7 +499,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +522,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +675,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +733,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +753,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +782,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,10 +1343,14 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
+	/* GJ */
+	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
+
 	pccb->pdata = usb_stor_buf;
 
 	dev_desc->target = dev->devnum;
@@ -1367,9 +1371,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], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	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);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..82652f5 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,6 +120,15 @@ static struct descriptor {
  */
 static void flush_invalidate(u32 addr, int size, int flush)
 {
+	/*
+	 * Size is the bytes actually moved during transaction,
+	 * which may not equal to the cache line. This results
+	 * stop address passed for invalidating cache may not be aligned.
+	 * Therfore making size as nultiple of cache line size.
+	 */
+	if (size & (ARCH_DMA_MINALIGN - 1))
+			size = ((size / ARCH_DMA_MINALIGN) + 1)
+				* ARCH_DMA_MINALIGN;
 	if (flush)
 		flush_dcache_range(addr, addr + size);
 	else
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..c1f573e 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,13 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+#ifdef ARCH_DMA_MINALIGN
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
+#else
+	unsigned char		sense_buf[64];
+#endif
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
diff --git a/include/usb.h b/include/usb.h
index 06170cd..d38817a 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -109,7 +109,13 @@ struct usb_device {
 	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	int configno;			/* selected config number */
-	struct usb_device_descriptor descriptor; /* Device Descriptor */
+	 /* Device Descriptor */
+#ifdef ARCH_DMA_MINALIGN
+	struct usb_device_descriptor descriptor
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
+#else
+	struct usb_device_descriptor descriptor;
+#endif
 	struct usb_config config; /* config descriptor */
 
 	int have_langid;		/* whether string_langid is valid yet */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255"
  2012-02-17 17:23 ` Mike Frysinger
  2012-02-23 14:25   ` [U-Boot] [PATCH 1/2] usb: align buffers at cacheline Puneet Saxena
@ 2012-02-23 14:25   ` Puneet Saxena
  2012-02-23 15:20     ` Tom Rini
  2012-02-23 16:04     ` Tom Warren
  1 sibling, 2 replies; 83+ messages in thread
From: Puneet Saxena @ 2012-02-23 14:25 UTC (permalink / raw)
  To: u-boot

Add a quirk "USB_QUIRK_STRING_FETCH_255", borrowed from Linux
kernel to fetch string using descriptor length then fetch actual bytes
returned in descriptor buffer.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---
Changes for v2:
   - Add quirk for fetching actual bytes

 common/usb.c                    |    4 ++++
 include/configs/tegra2-common.h |    7 +++++++
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 75926aa..cd85c18 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -660,7 +660,11 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
 
 	/* Try to read the string descriptor by asking for the maximum
 	 * possible number of bytes */
+#ifdef USB_QUIRK_STRING_FETCH_255
+	rc = -4;
+#else
 	rc = usb_get_string(dev, langid, index, buf, 255);
+#endif
 
 	/* If that failed try to read the descriptor length, then
 	 * ask for just that many bytes */
diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h
index 266d0e5..51cc200 100644
--- a/include/configs/tegra2-common.h
+++ b/include/configs/tegra2-common.h
@@ -172,4 +172,11 @@
 
 #define CONFIG_TEGRA2_GPIO
 #define CONFIG_CMD_GPIO
+
+/*
+ * Imported the quirk from Linux kernel
+ */
+/* string descriptors must not be fetched using a 255-byte read */
+#define USB_QUIRK_STRING_FETCH_255	0x00000001
+
 #endif /* __TEGRA2_COMMON_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255"
  2012-02-23 14:25   ` [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255" Puneet Saxena
@ 2012-02-23 15:20     ` Tom Rini
  2012-02-23 16:04     ` Tom Warren
  1 sibling, 0 replies; 83+ messages in thread
From: Tom Rini @ 2012-02-23 15:20 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 23, 2012 at 07:55:26PM +0530, Puneet Saxena wrote:

> Add a quirk "USB_QUIRK_STRING_FETCH_255", borrowed from Linux
> kernel to fetch string using descriptor length then fetch actual bytes
> returned in descriptor buffer.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>

I think this is too literal a borrowing.  In the kernel we don't use
CONFIG_... since we have dev->quirks and check that for this flag.  But
here IMHO we should just do CONFIG_USB_QURIK_...

-- 
Tom

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255"
  2012-02-23 14:25   ` [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255" Puneet Saxena
  2012-02-23 15:20     ` Tom Rini
@ 2012-02-23 16:04     ` Tom Warren
  2012-02-24  7:52       ` puneets
  1 sibling, 1 reply; 83+ messages in thread
From: Tom Warren @ 2012-02-23 16:04 UTC (permalink / raw)
  To: u-boot

Puneet,

> -----Original Message-----
> From: Puneet Saxena
> Sent: Thursday, February 23, 2012 7:25 AM
> To: u-boot at lists.denx.de; sjg at chromium.org
> Cc: vapier at gentoo.org; Tom Warren; Puneet Saxena
> Subject: [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255"
> 
> Add a quirk "USB_QUIRK_STRING_FETCH_255", borrowed from Linux kernel to
> fetch string using descriptor length then fetch actual bytes returned in
> descriptor buffer.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> ---
> Changes for v2:
>    - Add quirk for fetching actual bytes
> 
>  common/usb.c                    |    4 ++++
>  include/configs/tegra2-common.h |    7 +++++++
>  2 files changed, 11 insertions(+), 0 deletions(-)
> 
> diff --git a/common/usb.c b/common/usb.c index 75926aa..cd85c18 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -660,7 +660,11 @@ static int usb_string_sub(struct usb_device *dev,
> unsigned int langid,
> 
>  	/* Try to read the string descriptor by asking for the maximum
>  	 * possible number of bytes */
> +#ifdef USB_QUIRK_STRING_FETCH_255
> +	rc = -4;
> +#else
>  	rc = usb_get_string(dev, langid, index, buf, 255);
> +#endif
> 
>  	/* If that failed try to read the descriptor length, then
>  	 * ask for just that many bytes */
> diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-
> common.h index 266d0e5..51cc200 100644
> --- a/include/configs/tegra2-common.h
> +++ b/include/configs/tegra2-common.h
> @@ -172,4 +172,11 @@
> 
>  #define CONFIG_TEGRA2_GPIO
>  #define CONFIG_CMD_GPIO
> +
> +/*
> + * Imported the quirk from Linux kernel  */
> +/* string descriptors must not be fetched using a 255-byte read */
> +#define USB_QUIRK_STRING_FETCH_255	0x00000001
> +
>  #endif /* __TEGRA2_COMMON_H */
> --
> 1.7.1

Make sure you include the USB custodian/expert when submitting USB patches (Remy Bohmer, linux at bohmer.net). Also, as TomR says, this should be a CONFIG_USB_QUIRK_xxx string. Note that it doesn't need a 0x00000001 - #define'ing a switch means it's explicitly enabled - no need for 1 or 0 (see all the other CONFIG_ defines in the config headers).

Tom

-- 
nvpublic

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 1/2] usb: align buffers at cacheline
  2012-02-23 14:25   ` [U-Boot] [PATCH 1/2] usb: align buffers at cacheline Puneet Saxena
@ 2012-02-23 18:15     ` Mike Frysinger
  2012-02-24 11:27       ` puneets
  2012-02-24 12:42     ` Simon Glass
  1 sibling, 1 reply; 83+ messages in thread
From: Mike Frysinger @ 2012-02-23 18:15 UTC (permalink / raw)
  To: u-boot

On Thursday 23 February 2012 09:25:25 Puneet Saxena wrote:
> --- a/common/usb_storage.c
> +++ b/common/usb_storage.c
> 
> -static unsigned char usb_stor_buf[512];
> -static ccb usb_ccb;
> +#ifdef ARCH_DMA_MINALIGN
> +	static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
> +#else
> +	static ccb usb_ccb;
> +#endif

don't use ifdef's.  you may assume that ARCH_DMA_MINALIGN is always defined.  
after all, the ALLOC_CACHE_ALIGN_BUFFER() helper does.

> int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
> 				block_dev_desc_t *dev_desc)
>  {
>  	unsigned char perq, modi;
> -	unsigned long cap[2];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
>  	unsigned long *capacity, *blksz;
>  	ccb *pccb = &usb_ccb;
> 
> +	/* GJ */
> +	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));

you shrunk the buffer to 36 bytes, so that's good.  but the memset() should be 
dropped.  see what i posted to Marek when he tried moving this buffer locally 
if you want background.

> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
>
>  static void flush_invalidate(u32 addr, int size, int flush)
>  {
> +	/*
> +	 * Size is the bytes actually moved during transaction,
> +	 * which may not equal to the cache line. This results
> +	 * stop address passed for invalidating cache may not be aligned.
> +	 * Therfore making size as nultiple of cache line size.
> +	 */
> +	if (size & (ARCH_DMA_MINALIGN - 1))
> +			size = ((size / ARCH_DMA_MINALIGN) + 1)
> +				* ARCH_DMA_MINALIGN;

i don't think this logic should exist at all.  the arch is responsible for 
flushing enough of its cache to cover the requested size.

> --- a/include/scsi.h
> +++ b/include/scsi.h
> 
>  typedef struct SCSI_cmd_block{
>  	unsigned char		cmd[16];			/* command */
> -	unsigned char		sense_buf[64];		/* for request sense */
> +	/* for request sense */
> +#ifdef ARCH_DMA_MINALIGN
> +	unsigned char		sense_buf[64]
> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
> +#else
> +	unsigned char		sense_buf[64];
> +#endif
>
> --- a/include/usb.h
> +++ b/include/usb.h
> struct usb_device {
>  	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
> 
>  	int configno;			/* selected config number */
> -	struct usb_device_descriptor descriptor; /* Device Descriptor */
> +	 /* Device Descriptor */
> +#ifdef ARCH_DMA_MINALIGN
> +	struct usb_device_descriptor descriptor
> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
> +#else
> +	struct usb_device_descriptor descriptor;
> +#endif

i don't think either of these headers should be changed.  find & fix the code 
that is causing a problem.

wrt the other random ALLOC_CACHE_ALIGN_BUFFER() changes, they look OK to me.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120223/42b044b1/attachment.pgp>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255"
  2012-02-23 16:04     ` Tom Warren
@ 2012-02-24  7:52       ` puneets
  0 siblings, 0 replies; 83+ messages in thread
From: puneets @ 2012-02-24  7:52 UTC (permalink / raw)
  To: u-boot

On Thursday 23 February 2012 09:34 PM, Tom Warren wrote:
> Puneet,
>
>> -----Original Message-----
>> From: Puneet Saxena
>> Sent: Thursday, February 23, 2012 7:25 AM
>> To: u-boot at lists.denx.de; sjg at chromium.org
>> Cc: vapier at gentoo.org; Tom Warren; Puneet Saxena
>> Subject: [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255"
>>
>> Add a quirk "USB_QUIRK_STRING_FETCH_255", borrowed from Linux kernel to
>> fetch string using descriptor length then fetch actual bytes returned in
>> descriptor buffer.
>>
>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>> ---
>> Changes for v2:
>>     - Add quirk for fetching actual bytes
>>
>>   common/usb.c                    |    4 ++++
>>   include/configs/tegra2-common.h |    7 +++++++
>>   2 files changed, 11 insertions(+), 0 deletions(-)
>>
>> diff --git a/common/usb.c b/common/usb.c index 75926aa..cd85c18 100644
>> --- a/common/usb.c
>> +++ b/common/usb.c
>> @@ -660,7 +660,11 @@ static int usb_string_sub(struct usb_device *dev,
>> unsigned int langid,
>>
>>   	/* Try to read the string descriptor by asking for the maximum
>>   	 * possible number of bytes */
>> +#ifdef USB_QUIRK_STRING_FETCH_255
>> +	rc = -4;
>> +#else
>>   	rc = usb_get_string(dev, langid, index, buf, 255);
>> +#endif
>>
>>   	/* If that failed try to read the descriptor length, then
>>   	 * ask for just that many bytes */
>> diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-
>> common.h index 266d0e5..51cc200 100644
>> --- a/include/configs/tegra2-common.h
>> +++ b/include/configs/tegra2-common.h
>> @@ -172,4 +172,11 @@
>>
>>   #define CONFIG_TEGRA2_GPIO
>>   #define CONFIG_CMD_GPIO
>> +
>> +/*
>> + * Imported the quirk from Linux kernel  */
>> +/* string descriptors must not be fetched using a 255-byte read */
>> +#define USB_QUIRK_STRING_FETCH_255	0x00000001
>> +
>>   #endif /* __TEGRA2_COMMON_H */
>> --
>> 1.7.1
> Make sure you include the USB custodian/expert when submitting USB patches (Remy Bohmer, linux at bohmer.net). Also, as TomR says, this should be a CONFIG_USB_QUIRK_xxx string. Note that it doesn't need a 0x00000001 - #define'ing a switch means it's explicitly enabled - no need for 1 or 0 (see all the other CONFIG_ defines in the config headers).
>
> Tom
>
My thought of adding "#define USB_QUIRK_STRING_FETCH_255 0x00000001" 
instead "#define USB_QUIRK_STRING_FETCH_255" is, some time in future we 
might have to implement kernel quirk kind of functionality to make generic
implementation. Its not needed as of now. Will incorporate in next patch.

Thanks,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 1/2] usb: align buffers at cacheline
  2012-02-23 18:15     ` Mike Frysinger
@ 2012-02-24 11:27       ` puneets
  0 siblings, 0 replies; 83+ messages in thread
From: puneets @ 2012-02-24 11:27 UTC (permalink / raw)
  To: u-boot

Hi Mike,
On Thursday 23 February 2012 11:45 PM, Mike Frysinger wrote:
> * PGP Signed by an unknown key
>
> On Thursday 23 February 2012 09:25:25 Puneet Saxena wrote:
>> --- a/common/usb_storage.c
>> +++ b/common/usb_storage.c
>>
>> -static unsigned char usb_stor_buf[512];
>> -static ccb usb_ccb;
>> +#ifdef ARCH_DMA_MINALIGN
>> +	static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
>> +#else
>> +	static ccb usb_ccb;
>> +#endif
> don't use ifdef's.  you may assume that ARCH_DMA_MINALIGN is always defined.
> after all, the ALLOC_CACHE_ALIGN_BUFFER() helper does.
>
>> int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
>> 				block_dev_desc_t *dev_desc)
>>   {
>>   	unsigned char perq, modi;
>> -	unsigned long cap[2];
>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
>>   	unsigned long *capacity, *blksz;
>>   	ccb *pccb =&usb_ccb;
>>
>> +	/* GJ */
>> +	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
> you shrunk the buffer to 36 bytes, so that's good.  but the memset() should be
> dropped.  see what i posted to Marek when he tried moving this buffer locally
> if you want background.
>
>> --- a/drivers/usb/host/ehci-hcd.c
>> +++ b/drivers/usb/host/ehci-hcd.c
>>
>>   static void flush_invalidate(u32 addr, int size, int flush)
>>   {
>> +	/*
>> +	 * Size is the bytes actually moved during transaction,
>> +	 * which may not equal to the cache line. This results
>> +	 * stop address passed for invalidating cache may not be aligned.
>> +	 * Therfore making size as nultiple of cache line size.
>> +	 */
>> +	if (size&  (ARCH_DMA_MINALIGN - 1))
>> +			size = ((size / ARCH_DMA_MINALIGN) + 1)
>> +				* ARCH_DMA_MINALIGN;
> i don't think this logic should exist at all.  the arch is responsible for
> flushing enough of its cache to cover the requested size.
>
The patches under review is used to avoid the warnings -

1) ERROR: v7_dcache_inval_range - start address is not aligned - 0x3ffbd5d0

2) ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3ffbd5f0

This piece of code assures that second warning should not appear.

By allocating Buffers cache line aligned we are making sure that "start 
address"
will always be aligned. Arch specific code is taking care of 
flushing/invalidating the
cache as per the requested size but 2nd warning appears before doing that.
As you see in code: stop address = start address + size, so we are 
required to assure
size to be multiple of cacheline(start address we are aligning already). 
The above piece
of code is meant for this.
other option could be to add code in arch specific file to align stop 
address. e.g in "v7_dcache_maint_range@

Cache_v7.c (arch\arm\cpu\armv7)"

>> --- a/include/scsi.h
>> +++ b/include/scsi.h
>>
>>   typedef struct SCSI_cmd_block{
>>   	unsigned char		cmd[16];			/* command */
>> -	unsigned char		sense_buf[64];		/* for request sense */
>> +	/* for request sense */
>> +#ifdef ARCH_DMA_MINALIGN
>> +	unsigned char		sense_buf[64]
>> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
>> +#else
>> +	unsigned char		sense_buf[64];
>> +#endif
>>
>> --- a/include/usb.h
>> +++ b/include/usb.h
>> struct usb_device {
>>   	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
>>
>>   	int configno;			/* selected config number */
>> -	struct usb_device_descriptor descriptor; /* Device Descriptor */
>> +	 /* Device Descriptor */
>> +#ifdef ARCH_DMA_MINALIGN
>> +	struct usb_device_descriptor descriptor
>> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
>> +#else
>> +	struct usb_device_descriptor descriptor;
>> +#endif
> i don't think either of these headers should be changed.  find&  fix the code
> that is causing a problem.
>
IMHO, scsi.h should be changed otherwise we may need to memcpy aligned 
local buffer to
this global buffer in "usb_request_sense @ Usb_storage.c (common).

> wrt the other random ALLOC_CACHE_ALIGN_BUFFER() changes, they look OK to me.
> -mike
>
> * Unknown Key
> * 0xE837F581


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 1/2] usb: align buffers at cacheline
  2012-02-23 14:25   ` [U-Boot] [PATCH 1/2] usb: align buffers at cacheline Puneet Saxena
  2012-02-23 18:15     ` Mike Frysinger
@ 2012-02-24 12:42     ` Simon Glass
  2012-02-27 15:36       ` [U-Boot] [PATCH v2 " Puneet Saxena
                         ` (2 more replies)
  1 sibling, 3 replies; 83+ messages in thread
From: Simon Glass @ 2012-02-24 12:42 UTC (permalink / raw)
  To: u-boot

Hi,

On Thu, Feb 23, 2012 at 6:25 AM, Puneet Saxena <puneets@nvidia.com> wrote:
> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
>
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> Signed-off-by: Jim Lin <jilin@nvidia.com>
> ---
> Changes for v2:
> ? - Split the commit in to 2 commits
> ? - "ARCH_DMA_MINALIGN" replacement
> ? - Making stop address cache line aligned by
> ? ? making size as multiple of cache line
> ? - incorporated Marek and Mike's comment
>
> ?common/cmd_usb.c ? ? ? ? ? ?| ? ?3 +-
> ?common/usb.c ? ? ? ? ? ? ? ?| ? 53 ++++++++++++++++++----------------
> ?common/usb_storage.c ? ? ? ?| ? 66 ++++++++++++++++++++++--------------------
> ?drivers/usb/host/ehci-hcd.c | ? ?9 ++++++
> ?include/scsi.h ? ? ? ? ? ? ?| ? ?8 ++++-
> ?include/usb.h ? ? ? ? ? ? ? | ? ?8 ++++-
> ?6 files changed, 88 insertions(+), 59 deletions(-)

> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index d893b2a..82652f5 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -120,6 +120,15 @@ static struct descriptor {
> ?*/
> ?static void flush_invalidate(u32 addr, int size, int flush)
> ?{
> + ? ? ? /*
> + ? ? ? ?* Size is the bytes actually moved during transaction,
> + ? ? ? ?* which may not equal to the cache line. This results
> + ? ? ? ?* stop address passed for invalidating cache may not be aligned.
> + ? ? ? ?* Therfore making size as nultiple of cache line size.
> + ? ? ? ?*/
> + ? ? ? if (size & (ARCH_DMA_MINALIGN - 1))
> + ? ? ? ? ? ? ? ? ? ? ? size = ((size / ARCH_DMA_MINALIGN) + 1)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * ARCH_DMA_MINALIGN;

Can we just use:

size = ALIGN(size, ARCH_DMA_MINALIGN)

here or does it increase size even if already aligned?

> ? ? ? ?if (flush)
> ? ? ? ? ? ? ? ?flush_dcache_range(addr, addr + size);
> ? ? ? ?else
> diff --git a/include/scsi.h b/include/scsi.h
> index c52759c..c1f573e 100644
> --- a/include/scsi.h
> +++ b/include/scsi.h
> @@ -26,7 +26,13 @@
>
> ?typedef struct SCSI_cmd_block{
> ? ? ? ?unsigned char ? ? ? ? ? cmd[16]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* command ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
> - ? ? ? unsigned char ? ? ? ? ? sense_buf[64]; ? ? ? ? ?/* for request sense */
> + ? ? ? /* for request sense */
> +#ifdef ARCH_DMA_MINALIGN
> + ? ? ? unsigned char ? ? ? ? ? sense_buf[64]
> + ? ? ? ? ? ? ? __attribute__((aligned(ARCH_DMA_MINALIGN)));
> +#else
> + ? ? ? unsigned char ? ? ? ? ? sense_buf[64];
> +#endif

I think Mike said this, but I thought ARCH_DMA_MINALIGN should always
be defined.

Is it possible to align something in the middle of a structure? How
does that work? I'm suppose you have this working, I would just like
to understand what the resulting code does in this case.

> ? ? ? ?unsigned char ? ? ? ? ? status; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* SCSI Status ? ? ? ? ? ? ? ? ? */
> ? ? ? ?unsigned char ? ? ? ? ? target; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* Target ID ? ? ? ? ? ? ? ? ? ? ? ? ? ? */
> ? ? ? ?unsigned char ? ? ? ? ? lun; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* Target LUN ? ? ? ?*/
> diff --git a/include/usb.h b/include/usb.h
> index 06170cd..d38817a 100644
> --- a/include/usb.h
> +++ b/include/usb.h
> @@ -109,7 +109,13 @@ struct usb_device {
> ? ? ? ?int epmaxpacketout[16]; ? ? ? ? /* OUTput endpoint specific maximums */
>
> ? ? ? ?int configno; ? ? ? ? ? ? ? ? ? /* selected config number */
> - ? ? ? struct usb_device_descriptor descriptor; /* Device Descriptor */
> + ? ? ? ?/* Device Descriptor */
> +#ifdef ARCH_DMA_MINALIGN
> + ? ? ? struct usb_device_descriptor descriptor
> + ? ? ? ? ? ? ? __attribute__((aligned(ARCH_DMA_MINALIGN)));
> +#else
> + ? ? ? struct usb_device_descriptor descriptor;
> +#endif

Same question here, it seems even more exotic - maybe you will need a
memcpy somewhere after all?

> ? ? ? ?struct usb_config config; /* config descriptor */
>
> ? ? ? ?int have_langid; ? ? ? ? ? ? ? ?/* whether string_langid is valid yet */
> --
> 1.7.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline
  2012-02-24 12:42     ` Simon Glass
@ 2012-02-27 15:36       ` Puneet Saxena
  2012-02-27 16:49         ` Marek Vasut
  2012-02-27 15:36       ` [U-Boot] [PATCH v2 2/2] usb: Add CONFIG to fetch string descriptor Puneet Saxena
  2012-02-27 15:37       ` [U-Boot] [PATCH 1/2] usb: align buffers at cacheline puneets
  2 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-02-27 15:36 UTC (permalink / raw)
  To: u-boot

As DMA expects the buffers to be equal and larger then
cache lines, This aligns buffers at cacheline.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
Signed-off-by: Jim Lin <jilin@nvidia.com>
---

Changes for V2:
    - Use "ARCH_DMA_MINALIGN" directly  
    - Use "ALIGN" to align size as cacheline 
    - Removed headers from usb.h
    - Send 8 bytes of device descriptor size to read 
      Max packet size 
scsi.h header is needed to avoid extra memcpy from local buffer 
to global buffer.

 common/cmd_usb.c            |    3 +-
 common/usb.c                |   61 ++++++++++++++++++++++++------------------
 common/usb_storage.c        |   59 +++++++++++++++++++----------------------
 disk/part_dos.c             |    2 +-
 drivers/usb/host/ehci-hcd.c |    8 +++++
 include/scsi.h              |    4 ++-
 6 files changed, 77 insertions(+), 60 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 63a11c8..2279459 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
+		sizeof(struct devrequest));
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
 		   "value 0x%X index 0x%X length 0x%X\n",
 		   request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	submit_control_msg(dev, pipe, data, size, setup_packet);
 	if (timeout == 0)
 		return (int)size;
 
@@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
 	dev->epmaxpacketin[0] = 64;
 	dev->epmaxpacketout[0] = 64;
 
-	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
+	desc->bMaxPacketSize0 = 0;
+	/*8 bytes of the descriptor to read Max packet size*/
+	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
+			8);
 	if (err < 0) {
 		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
 		return 1;
@@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
 	tmp = sizeof(dev->descriptor);
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-				 &dev->descriptor, sizeof(dev->descriptor));
+				 desc, sizeof(dev->descriptor));
 	if (err < tmp) {
 		if (err < 0)
 			printf("unable to get device descriptor (error=%d)\n",
@@ -915,14 +919,18 @@ int usb_new_device(struct usb_device *dev)
 				"(expected %i, got %i)\n", tmp, err);
 		return 1;
 	}
+	dev->descriptor.bcdUSB = desc->bcdUSB;
+	dev->descriptor.idVendor = desc->idVendor;
+	dev->descriptor.idProduct = desc->idProduct;
+	dev->descriptor.bcdDevice = desc->bcdDevice;
 	/* correct le values */
 	le16_to_cpus(&dev->descriptor.bcdUSB);
 	le16_to_cpus(&dev->descriptor.idVendor);
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1076,7 +1084,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1085,13 +1093,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1129,19 +1137,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1190,7 +1198,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1312,16 +1321,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..88ca390 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
 
 /*
  * CBI style
@@ -210,17 +209,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
 		printf("       scanning bus for storage devices... ");
 
@@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +729,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +749,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +778,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
@@ -1367,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], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	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);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
diff --git a/disk/part_dos.c b/disk/part_dos.c
index b5bcb37..70211ee 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
-	unsigned char buffer[dev_desc->blksz];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..eb5220b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,6 +120,14 @@ static struct descriptor {
  */
 static void flush_invalidate(u32 addr, int size, int flush)
 {
+	/*
+	 * Size is the bytes actually moved during transaction,
+	 * which may not equal to the cache line. This results
+	 * stop address passed for invalidating cache may not be aligned.
+	 * Therfore making size as multiple of cache line size.
+	 */
+	size = ALIGN(size, ARCH_DMA_MINALIGN);
+
 	if (flush)
 		flush_dcache_range(addr, addr + size);
 	else
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..89ae45f 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,9 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 2/2] usb: Add CONFIG to fetch string descriptor
  2012-02-24 12:42     ` Simon Glass
  2012-02-27 15:36       ` [U-Boot] [PATCH v2 " Puneet Saxena
@ 2012-02-27 15:36       ` Puneet Saxena
  2012-02-27 18:28         ` Mike Frysinger
  2012-02-27 15:37       ` [U-Boot] [PATCH 1/2] usb: align buffers at cacheline puneets
  2 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-02-27 15:36 UTC (permalink / raw)
  To: u-boot

Add "CONFIG_USB_STRING_FETCH" to fetch string using descriptor length
then fetch actual bytes, returned in descriptor buffer.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---

Changes for V2:
   - Change config by "CONFIG_USB_STRING_FETCH"

 common/usb.c                    |    4 ++++
 include/configs/tegra2-common.h |    3 +++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 2279459..83c6c5c 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
 {
 	int rc;
 
+#ifdef CONFIG_USB_STRING_FETCH
+	rc = -1;
+#else
 	/* Try to read the string descriptor by asking for the maximum
 	 * possible number of bytes */
 	rc = usb_get_string(dev, langid, index, buf, 255);
+#endif
 
 	/* If that failed try to read the descriptor length, then
 	 * ask for just that many bytes */
diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h
index 266d0e5..420d2a9 100644
--- a/include/configs/tegra2-common.h
+++ b/include/configs/tegra2-common.h
@@ -93,6 +93,8 @@
 #define CONFIG_USB_EHCI_TXFIFO_THRESH	10
 #define CONFIG_EHCI_IS_TDI
 #define CONFIG_EHCI_DCACHE
+/* string descriptors must not be fetched using a 255-byte read */
+#define CONFIG_USB_STRING_FETCH
 
 /* include default commands */
 #include <config_cmd_default.h>
@@ -172,4 +174,5 @@
 
 #define CONFIG_TEGRA2_GPIO
 #define CONFIG_CMD_GPIO
+
 #endif /* __TEGRA2_COMMON_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH 1/2] usb: align buffers at cacheline
  2012-02-24 12:42     ` Simon Glass
  2012-02-27 15:36       ` [U-Boot] [PATCH v2 " Puneet Saxena
  2012-02-27 15:36       ` [U-Boot] [PATCH v2 2/2] usb: Add CONFIG to fetch string descriptor Puneet Saxena
@ 2012-02-27 15:37       ` puneets
  2 siblings, 0 replies; 83+ messages in thread
From: puneets @ 2012-02-27 15:37 UTC (permalink / raw)
  To: u-boot

Hi,
On Friday 24 February 2012 06:12 PM, Simon Glass wrote:
> Hi,
>
> On Thu, Feb 23, 2012 at 6:25 AM, Puneet Saxena<puneets@nvidia.com>  wrote:
>> As DMA expects the buffers to be equal and larger then
>> cache lines, This aligns buffers at cacheline.
>>
>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>> Signed-off-by: Jim Lin<jilin@nvidia.com>
>> ---
>> Changes for v2:
>>    - Split the commit in to 2 commits
>>    - "ARCH_DMA_MINALIGN" replacement
>>    - Making stop address cache line aligned by
>>      making size as multiple of cache line
>>    - incorporated Marek and Mike's comment
>>
>>   common/cmd_usb.c            |    3 +-
>>   common/usb.c                |   53 ++++++++++++++++++----------------
>>   common/usb_storage.c        |   66 ++++++++++++++++++++++--------------------
>>   drivers/usb/host/ehci-hcd.c |    9 ++++++
>>   include/scsi.h              |    8 ++++-
>>   include/usb.h               |    8 ++++-
>>   6 files changed, 88 insertions(+), 59 deletions(-)
>> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
>> index d893b2a..82652f5 100644
>> --- a/drivers/usb/host/ehci-hcd.c
>> +++ b/drivers/usb/host/ehci-hcd.c
>> @@ -120,6 +120,15 @@ static struct descriptor {
>>   */
>>   static void flush_invalidate(u32 addr, int size, int flush)
>>   {
>> +       /*
>> +        * Size is the bytes actually moved during transaction,
>> +        * which may not equal to the cache line. This results
>> +        * stop address passed for invalidating cache may not be aligned.
>> +        * Therfore making size as nultiple of cache line size.
>> +        */
>> +       if (size&  (ARCH_DMA_MINALIGN - 1))
>> +                       size = ((size / ARCH_DMA_MINALIGN) + 1)
>> +                               * ARCH_DMA_MINALIGN;
> Can we just use:
>
> size = ALIGN(size, ARCH_DMA_MINALIGN)
>
> here or does it increase size even if already aligned?
size = ALIGN(size, ARCH_DMA_MINALIGN) can be used in place of this.
The code in patch does not increase the size if size is already aligned.
>>         if (flush)
>>                 flush_dcache_range(addr, addr + size);
>>         else
>> diff --git a/include/scsi.h b/include/scsi.h
>> index c52759c..c1f573e 100644
>> --- a/include/scsi.h
>> +++ b/include/scsi.h
>> @@ -26,7 +26,13 @@
>>
>>   typedef struct SCSI_cmd_block{
>>         unsigned char           cmd[16];                                        /* command                                 */
>> -       unsigned char           sense_buf[64];          /* for request sense */
>> +       /* for request sense */
>> +#ifdef ARCH_DMA_MINALIGN
>> +       unsigned char           sense_buf[64]
>> +               __attribute__((aligned(ARCH_DMA_MINALIGN)));
>> +#else
>> +       unsigned char           sense_buf[64];
>> +#endif
> I think Mike said this, but I thought ARCH_DMA_MINALIGN should always
> be defined.
>
> Is it possible to align something in the middle of a structure? How
> does that work? I'm suppose you have this working, I would just like
> to understand what the resulting code does in this case.
>
I verified that ARCH_DMA_MINALIGN is already defined so I will not check 
it in next patch.

Yes it would align the variable in middle at the time of instantiating 
the structure.
Compiler generates the addresses of this variable and structure 
variable, as 32 __BYTE__ aligned(cache line is 32).
It try to accommodate all the variables in these two addresses till 32 byte.
Another solution could be, Align whole structure of cacheline and keep 
the buffer as first element.
However in case more than one buffers are in a structure, only option is 
to align individual buffer in place of
whole structure.

>>         unsigned char           status;                                         /* SCSI Status                   */
>>         unsigned char           target;                                         /* Target ID                             */
>>         unsigned char           lun;                                                    /* Target LUN        */
>> diff --git a/include/usb.h b/include/usb.h
>> index 06170cd..d38817a 100644
>> --- a/include/usb.h
>> +++ b/include/usb.h
>> @@ -109,7 +109,13 @@ struct usb_device {
>>         int epmaxpacketout[16];         /* OUTput endpoint specific maximums */
>>
>>         int configno;                   /* selected config number */
>> -       struct usb_device_descriptor descriptor; /* Device Descriptor */
>> +        /* Device Descriptor */
>> +#ifdef ARCH_DMA_MINALIGN
>> +       struct usb_device_descriptor descriptor
>> +               __attribute__((aligned(ARCH_DMA_MINALIGN)));
>> +#else
>> +       struct usb_device_descriptor descriptor;
>> +#endif
> Same question here, it seems even more exotic - maybe you will need a
> memcpy somewhere after all?
>
>>         struct usb_config config; /* config descriptor */
>>
>>         int have_langid;                /* whether string_langid is valid yet */
>> --
>> 1.7.1
>>
> Regards,
> Simon


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline
  2012-02-27 15:36       ` [U-Boot] [PATCH v2 " Puneet Saxena
@ 2012-02-27 16:49         ` Marek Vasut
  2012-02-27 17:03           ` Simon Glass
  2012-02-28  9:34           ` [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline puneets
  0 siblings, 2 replies; 83+ messages in thread
From: Marek Vasut @ 2012-02-27 16:49 UTC (permalink / raw)
  To: u-boot

> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> Signed-off-by: Jim Lin <jilin@nvidia.com>
> ---
> 

First of all, thanks for this patch, it really helps. But, there are a few 
things that concern me.

> Changes for V2:
>     - Use "ARCH_DMA_MINALIGN" directly
>     - Use "ALIGN" to align size as cacheline
>     - Removed headers from usb.h
>     - Send 8 bytes of device descriptor size to read
>       Max packet size
> scsi.h header is needed to avoid extra memcpy from local buffer
> to global buffer.
> 
>  common/cmd_usb.c            |    3 +-
>  common/usb.c                |   61
> ++++++++++++++++++++++++------------------ common/usb_storage.c        |  
> 59 +++++++++++++++++++---------------------- disk/part_dos.c             |
>    2 +-
>  drivers/usb/host/ehci-hcd.c |    8 +++++
>  include/scsi.h              |    4 ++-
>  6 files changed, 77 insertions(+), 60 deletions(-)
> 
> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> index 320667f..bca9d94 100644
> --- a/common/cmd_usb.c
> +++ b/common/cmd_usb.c
> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> unsigned char subclass,
> 
>  void usb_display_string(struct usb_device *dev, int index)
>  {
> -	char buffer[256];
> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);

Why not memalign(), do you want to allocate on stack so badly ?

> +
>  	if (index != 0) {
>  		if (usb_string(dev, index, &buffer[0], 256) > 0)
>  			printf("String: \"%s\"", buffer);
> diff --git a/common/usb.c b/common/usb.c
> index 63a11c8..2279459 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>  static int dev_index;
>  static int running;
>  static int asynch_allowed;
> -static struct devrequest setup_packet;
> 
>  char usb_started; /* flag for the started/stopped USB status */
> 
> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned
> int pipe, unsigned short value, unsigned short index,
>  			void *data, unsigned short size, int timeout)
>  {
> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> +		sizeof(struct devrequest));

DTTO, btw does the setup packet need to be aligned too ?

>  	if ((timeout == 0) && (!asynch_allowed)) {
>  		/* request for a asynch control pipe is not allowed */
>  		return -1;
>  	}
> 
>  	/* set setup command */
> -	setup_packet.requesttype = requesttype;
> -	setup_packet.request = request;
> -	setup_packet.value = cpu_to_le16(value);
> -	setup_packet.index = cpu_to_le16(index);
> -	setup_packet.length = cpu_to_le16(size);
> +	setup_packet->requesttype = requesttype;
> +	setup_packet->request = request;
> +	setup_packet->value = cpu_to_le16(value);
> +	setup_packet->index = cpu_to_le16(index);
> +	setup_packet->length = cpu_to_le16(size);
>  	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>  		   "value 0x%X index 0x%X length 0x%X\n",
>  		   request, requesttype, value, index, size);
>  	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> 
> -	submit_control_msg(dev, pipe, data, size, &setup_packet);
> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>  	if (timeout == 0)
>  		return (int)size;
> 
> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev,
> unsigned int langid, */
>  int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>  {
> -	unsigned char mybuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>  	unsigned char *tbuf;
>  	int err;
>  	unsigned int u, idx;
> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
>  {
>  	int addr, err;
>  	int tmp;
> -	unsigned char tmpbuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);

Why not simply memalign() them all?
> 
>  	/* We still haven't set the Address yet */
>  	addr = dev->devnum;
> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
>  	dev->epmaxpacketin[0] = 64;
>  	dev->epmaxpacketout[0] = 64;
> 
> -	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
> +	desc->bMaxPacketSize0 = 0;
> +	/*8 bytes of the descriptor to read Max packet size*/
> +	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
> +			8);
>  	if (err < 0) {
>  		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
>  		return 1;
> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
>  	tmp = sizeof(dev->descriptor);
> 
>  	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
> -				 &dev->descriptor, sizeof(dev->descriptor));
> +				 desc, sizeof(dev->descriptor));
>  	if (err < tmp) {
>  		if (err < 0)
>  			printf("unable to get device descriptor (error=%d)\n",
> @@ -915,14 +919,18 @@ int usb_new_device(struct usb_device *dev)
>  				"(expected %i, got %i)\n", tmp, err);
>  		return 1;
>  	}
> +	dev->descriptor.bcdUSB = desc->bcdUSB;
> +	dev->descriptor.idVendor = desc->idVendor;
> +	dev->descriptor.idProduct = desc->idProduct;
> +	dev->descriptor.bcdDevice = desc->bcdDevice;

Isn't the above change unrelated?

>  	/* correct le values */
>  	le16_to_cpus(&dev->descriptor.bcdUSB);
>  	le16_to_cpus(&dev->descriptor.idVendor);
>  	le16_to_cpus(&dev->descriptor.idProduct);
>  	le16_to_cpus(&dev->descriptor.bcdDevice);
>  	/* only support for one config for now */
> -	usb_get_configuration_no(dev, &tmpbuf[0], 0);
> -	usb_parse_config(dev, &tmpbuf[0], 0);
> +	usb_get_configuration_no(dev, tmpbuf, 0);
> +	usb_parse_config(dev, tmpbuf, 0);
>  	usb_set_maxpacket(dev);
>  	/* we set the default configuration here */
>  	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
> @@ -1076,7 +1084,7 @@ static int hub_port_reset(struct usb_device *dev, int
> port, unsigned short *portstat)
>  {
>  	int tries;
> -	struct usb_port_status portsts;
> +	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);

Looking at all this stuff, it's already allocated on stack. Ok, I already 
outlined first option -- memalign(), but that'd really put quite a strain on the 
memory allocator -- the other option (and maybe even better) is to use 
__attribute__((aligned)), which will allow the compiler to reorder data 
allocated on the stack so the array you create is aligned and not much space 
around on the stack is wasted. Apparently, ALLOC_CACHE_ALIGN_BUFFER() wastes a 
lot of space on the stack.

>  	unsigned short portstatus, portchange;
> 
>  	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
> @@ -1085,13 +1093,13 @@ static int hub_port_reset(struct usb_device *dev,
> int port, usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
>  		wait_ms(200);
> 
> -		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
> +		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
>  			USB_HUB_PRINTF("get_port_status failed status %lX\n",
>  					dev->status);
>  			return -1;
>  		}
> -		portstatus = le16_to_cpu(portsts.wPortStatus);
> -		portchange = le16_to_cpu(portsts.wPortChange);
> +		portstatus = le16_to_cpu(portsts->wPortStatus);
> +		portchange = le16_to_cpu(portsts->wPortChange);
> 
>  		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
>  				portstatus, portchange,
> @@ -1129,19 +1137,19 @@ static int hub_port_reset(struct usb_device *dev,
> int port, void usb_hub_port_connect_change(struct usb_device *dev, int
> port) {
>  	struct usb_device *usb;
> -	struct usb_port_status portsts;
> +	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>  	unsigned short portstatus;
> 
>  	/* Check status */
> -	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
> +	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
>  		USB_HUB_PRINTF("get_port_status failed\n");
>  		return;
>  	}
> 
> -	portstatus = le16_to_cpu(portsts.wPortStatus);
> +	portstatus = le16_to_cpu(portsts->wPortStatus);
>  	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
>  			portstatus,
> -			le16_to_cpu(portsts.wPortChange),
> +			le16_to_cpu(portsts->wPortChange),
>  			portspeed(portstatus));
> 
>  	/* Clear the connection change status */
> @@ -1190,7 +1198,8 @@ void usb_hub_port_connect_change(struct usb_device
> *dev, int port) int usb_hub_configure(struct usb_device *dev)
>  {
>  	int i;
> -	unsigned char buffer[USB_BUFSIZ], *bitmap;
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
> +	unsigned char *bitmap;
>  	struct usb_hub_descriptor *descriptor;
>  	struct usb_hub_device *hub;
>  #ifdef USB_HUB_DEBUG
> @@ -1312,16 +1321,16 @@ int usb_hub_configure(struct usb_device *dev)
>  	usb_hub_power_on(hub);
> 
>  	for (i = 0; i < dev->maxchild; i++) {
> -		struct usb_port_status portsts;
> +		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>  		unsigned short portstatus, portchange;
> 
> -		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
> +		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
>  			USB_HUB_PRINTF("get_port_status failed\n");
>  			continue;
>  		}
> 
> -		portstatus = le16_to_cpu(portsts.wPortStatus);
> -		portchange = le16_to_cpu(portsts.wPortChange);
> +		portstatus = le16_to_cpu(portsts->wPortStatus);
> +		portchange = le16_to_cpu(portsts->wPortChange);
>  		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
>  				i + 1, portstatus, portchange);
> 
> diff --git a/common/usb_storage.c b/common/usb_storage.c
> index de84c8d..88ca390 100644
> --- a/common/usb_storage.c
> +++ b/common/usb_storage.c
> @@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
>  };
>  #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
> 
> -static unsigned char usb_stor_buf[512];
> -static ccb usb_ccb;
> +static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
> 
>  /*
>   * CBI style
> @@ -210,17 +209,17 @@ int usb_stor_info(void)
>  static unsigned int usb_get_max_lun(struct us_data *us)
>  {
>  	int len;
> -	unsigned char result;
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
>  	len = usb_control_msg(us->pusb_dev,
>  			      usb_rcvctrlpipe(us->pusb_dev, 0),
>  			      US_BBB_GET_MAX_LUN,
>  			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
>  			      0, us->ifnum,
> -			      &result, sizeof(result),
> +			      result, sizeof(char),
>  			      USB_CNTL_TIMEOUT * 5);
>  	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
> -			len, (int) result);
> -	return (len > 0) ? result : 0;
> +			len, (int) *result);
> +	return (len > 0) ? *result : 0;
>  }
> 
>  /*************************************************************************
> ****** @@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
>  	unsigned char i;
>  	struct usb_device *dev;
> 
> -	/* GJ */
> -	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
> -
>  	if (mode == 1)
>  		printf("       scanning bus for storage devices... ");
> 
> @@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
>  	int actlen;
>  	int dir_in;
>  	unsigned int pipe;
> -	umass_bbb_cbw_t cbw;
> +	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
> 
>  	dir_in = US_DIRECTION(srb->cmd[0]);
> 
> @@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
>  	/* always OUT to the ep */
>  	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
> 
> -	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
> -	cbw.dCBWTag = cpu_to_le32(CBWTag++);
> -	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
> -	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
> -	cbw.bCBWLUN = srb->lun;
> -	cbw.bCDBLength = srb->cmdlen;
> +	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
> +	cbw->dCBWTag = cpu_to_le32(CBWTag++);
> +	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
> +	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
> +	cbw->bCBWLUN = srb->lun;
> +	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,
> +	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);
>  	if (result < 0)
>  		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
> @@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data
> *us) int dir_in;
>  	int actlen, data_actlen;
>  	unsigned int pipe, pipein, pipeout;
> -	umass_bbb_csw_t csw;
> +	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
>  #ifdef BBB_XPORT_TRACE
>  	unsigned char *ptr;
>  	int index;
> @@ -733,7 +729,7 @@ st:
>  	retry = 0;
>  again:
>  	USB_STOR_PRINTF("STATUS phase\n");
> -	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
> +	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
>  				&actlen, USB_CNTL_TIMEOUT*5);
> 
>  	/* special handling of STALL in STATUS phase */
> @@ -753,28 +749,28 @@ again:
>  		return USB_STOR_TRANSPORT_FAILED;
>  	}
>  #ifdef BBB_XPORT_TRACE
> -	ptr = (unsigned char *)&csw;
> +	ptr = (unsigned char *)csw;
>  	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
>  		printf("ptr[%d] %#x ", index, ptr[index]);
>  	printf("\n");
>  #endif
>  	/* misuse pipe to get the residue */
> -	pipe = le32_to_cpu(csw.dCSWDataResidue);
> +	pipe = le32_to_cpu(csw->dCSWDataResidue);
>  	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
>  		pipe = srb->datalen - data_actlen;
> -	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
> +	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
>  		USB_STOR_PRINTF("!CSWSIGNATURE\n");
>  		usb_stor_BBB_reset(us);
>  		return USB_STOR_TRANSPORT_FAILED;
> -	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
> +	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
>  		USB_STOR_PRINTF("!Tag\n");
>  		usb_stor_BBB_reset(us);
>  		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
> +	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
>  		USB_STOR_PRINTF(">PHASE\n");
>  		usb_stor_BBB_reset(us);
>  		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
> +	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
>  		USB_STOR_PRINTF("=PHASE\n");
>  		usb_stor_BBB_reset(us);
>  		return USB_STOR_TRANSPORT_FAILED;
> @@ -782,7 +778,7 @@ again:
>  		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
>  			data_actlen, srb->datalen);
>  		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
> +	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
>  		USB_STOR_PRINTF("FAILED\n");
>  		return USB_STOR_TRANSPORT_FAILED;
>  	}
> @@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct
> us_data *ss, block_dev_desc_t *dev_desc)
>  {
>  	unsigned char perq, modi;
> -	unsigned long cap[2];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
>  	unsigned long *capacity, *blksz;
>  	ccb *pccb = &usb_ccb;
> 
> @@ -1367,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], &usb_stor_buf[8], 8);
> -	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
> -	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
> +	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);
>  	dev_desc->vendor[8] = 0;
>  	dev_desc->product[16] = 0;
>  	dev_desc->revision[4] = 0;
> diff --git a/disk/part_dos.c b/disk/part_dos.c
> index b5bcb37..70211ee 100644
> --- a/disk/part_dos.c
> +++ b/disk/part_dos.c
> @@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
> 
>  int test_part_dos (block_dev_desc_t *dev_desc)
>  {
> -	unsigned char buffer[dev_desc->blksz];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
> 
>  	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) 
||
>  	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index d893b2a..eb5220b 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -120,6 +120,14 @@ static struct descriptor {
>   */
>  static void flush_invalidate(u32 addr, int size, int flush)
>  {
> +	/*
> +	 * Size is the bytes actually moved during transaction,
> +	 * which may not equal to the cache line. This results
> +	 * stop address passed for invalidating cache may not be aligned.
> +	 * Therfore making size as multiple of cache line size.
> +	 */
> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> +
>  	if (flush)
>  		flush_dcache_range(addr, addr + size);
>  	else
> diff --git a/include/scsi.h b/include/scsi.h
> index c52759c..89ae45f 100644
> --- a/include/scsi.h
> +++ b/include/scsi.h
> @@ -26,7 +26,9 @@
> 
>  typedef struct SCSI_cmd_block{
>  	unsigned char		cmd[16];					
/* command				   */
> -	unsigned char		sense_buf[64];		/* for request sense */
> +	/* for request sense */
> +	unsigned char		sense_buf[64]
> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
>  	unsigned char		status;						
/* SCSI Status			 */
>  	unsigned char		target;						
/* Target ID				 */
>  	unsigned char		lun;							
/* Target LUN        */

Thanks!

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline
  2012-02-27 16:49         ` Marek Vasut
@ 2012-02-27 17:03           ` Simon Glass
  2012-02-27 17:11             ` Marek Vasut
  2012-02-28  9:34           ` [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline puneets
  1 sibling, 1 reply; 83+ messages in thread
From: Simon Glass @ 2012-02-27 17:03 UTC (permalink / raw)
  To: u-boot

Hi Marek,

On Mon, Feb 27, 2012 at 8:49 AM, Marek Vasut <marex@denx.de> wrote:
>> As DMA expects the buffers to be equal and larger then
>> cache lines, This aligns buffers at cacheline.
>>
>> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
>> Signed-off-by: Jim Lin <jilin@nvidia.com>
>> ---
>>
>
> First of all, thanks for this patch, it really helps. But, there are a few
> things that concern me.
>
>> Changes for V2:
>> ? ? - Use "ARCH_DMA_MINALIGN" directly
>> ? ? - Use "ALIGN" to align size as cacheline
>> ? ? - Removed headers from usb.h
>> ? ? - Send 8 bytes of device descriptor size to read
>> ? ? ? Max packet size
>> scsi.h header is needed to avoid extra memcpy from local buffer
>> to global buffer.
>>
>> ?common/cmd_usb.c ? ? ? ? ? ?| ? ?3 +-
>> ?common/usb.c ? ? ? ? ? ? ? ?| ? 61
>> ++++++++++++++++++++++++------------------ common/usb_storage.c ? ? ? ?|
>> 59 +++++++++++++++++++---------------------- disk/part_dos.c ? ? ? ? ? ? |
>> ? ?2 +-
>> ?drivers/usb/host/ehci-hcd.c | ? ?8 +++++
>> ?include/scsi.h ? ? ? ? ? ? ?| ? ?4 ++-
>> ?6 files changed, 77 insertions(+), 60 deletions(-)
>>
>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
>> index 320667f..bca9d94 100644
>> --- a/common/cmd_usb.c
>> +++ b/common/cmd_usb.c
>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
>> unsigned char subclass,
>>
>> ?void usb_display_string(struct usb_device *dev, int index)
>> ?{
>> - ? ? char buffer[256];
>> + ? ? ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
>
> Why not memalign(), do you want to allocate on stack so badly ?

This issue came up with MMC and there was a strong request not to
sprinkle the code with malloc. In fact the macro above was devised at
some cost just to solve this problem.

[snip]
>> ?{
>> ? ? ? int tries;
>> - ? ? struct usb_port_status portsts;
>> + ? ? ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>
> Looking at all this stuff, it's already allocated on stack. Ok, I already
> outlined first option -- memalign(), but that'd really put quite a strain on the
> memory allocator -- the other option (and maybe even better) is to use
> __attribute__((aligned)), which will allow the compiler to reorder data
> allocated on the stack so the array you create is aligned and not much space
> around on the stack is wasted. Apparently, ALLOC_CACHE_ALIGN_BUFFER() wastes a
> lot of space on the stack.

There was quite a bit of discussion about this related to MMC. I think
the current solution is the result of that discussion...

Regards,
Simon

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline
  2012-02-27 17:03           ` Simon Glass
@ 2012-02-27 17:11             ` Marek Vasut
  2012-02-27 17:27               ` Simon Glass
                                 ` (2 more replies)
  0 siblings, 3 replies; 83+ messages in thread
From: Marek Vasut @ 2012-02-27 17:11 UTC (permalink / raw)
  To: u-boot

> Hi Marek,
> 
> On Mon, Feb 27, 2012 at 8:49 AM, Marek Vasut <marex@denx.de> wrote:
> >> As DMA expects the buffers to be equal and larger then
> >> cache lines, This aligns buffers at cacheline.
> >> 
> >> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> >> Signed-off-by: Jim Lin <jilin@nvidia.com>
> >> ---
> > 
> > First of all, thanks for this patch, it really helps. But, there are a
> > few things that concern me.
> > 
> >> Changes for V2:
> >>     - Use "ARCH_DMA_MINALIGN" directly
> >>     - Use "ALIGN" to align size as cacheline
> >>     - Removed headers from usb.h
> >>     - Send 8 bytes of device descriptor size to read
> >>       Max packet size
> >> scsi.h header is needed to avoid extra memcpy from local buffer
> >> to global buffer.
> >> 
> >>  common/cmd_usb.c            |    3 +-
> >>  common/usb.c                |   61
> >> ++++++++++++++++++++++++------------------ common/usb_storage.c        |
> >> 59 +++++++++++++++++++---------------------- disk/part_dos.c            
> >> | 2 +-
> >>  drivers/usb/host/ehci-hcd.c |    8 +++++
> >>  include/scsi.h              |    4 ++-
> >>  6 files changed, 77 insertions(+), 60 deletions(-)
> >> 
> >> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> >> index 320667f..bca9d94 100644
> >> --- a/common/cmd_usb.c
> >> +++ b/common/cmd_usb.c
> >> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> >> unsigned char subclass,
> >> 
> >>  void usb_display_string(struct usb_device *dev, int index)
> >>  {
> >> -     char buffer[256];
> >> +     ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> > 
> > Why not memalign(), do you want to allocate on stack so badly ?
> 
> This issue came up with MMC and there was a strong request not to
> sprinkle the code with malloc. In fact the macro above was devised at
> some cost just to solve this problem.

This is really weird solution :-(
> 
> [snip]
> 
> >>  {
> >>       int tries;
> >> -     struct usb_port_status portsts;
> >> +     ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
> > 
> > Looking at all this stuff, it's already allocated on stack. Ok, I already
> > outlined first option -- memalign(), but that'd really put quite a strain
> > on the memory allocator -- the other option (and maybe even better) is
> > to use __attribute__((aligned)), which will allow the compiler to
> > reorder data allocated on the stack so the array you create is aligned
> > and not much space around on the stack is wasted. Apparently,
> > ALLOC_CACHE_ALIGN_BUFFER() wastes a lot of space on the stack.
> 
> There was quite a bit of discussion about this related to MMC. I think
> the current solution is the result of that discussion...

Can you please point me to such discussion?

Thanks!

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline
  2012-02-27 17:11             ` Marek Vasut
@ 2012-02-27 17:27               ` Simon Glass
  2012-02-29 14:21               ` [U-Boot] [PATCH v3 " Puneet Saxena
  2012-02-29 14:21               ` [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor Puneet Saxena
  2 siblings, 0 replies; 83+ messages in thread
From: Simon Glass @ 2012-02-27 17:27 UTC (permalink / raw)
  To: u-boot

Hi Marek,

On Mon, Feb 27, 2012 at 9:11 AM, Marek Vasut <marex@denx.de> wrote:
>> Hi Marek,
>>
>> On Mon, Feb 27, 2012 at 8:49 AM, Marek Vasut <marex@denx.de> wrote:
>> >> As DMA expects the buffers to be equal and larger then
>> >> cache lines, This aligns buffers at cacheline.
>> >>
>> >> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
>> >> Signed-off-by: Jim Lin <jilin@nvidia.com>
>> >> ---
>> >
>> > First of all, thanks for this patch, it really helps. But, there are a
>> > few things that concern me.
>> >
>> >> Changes for V2:
>> >> ? ? - Use "ARCH_DMA_MINALIGN" directly
>> >> ? ? - Use "ALIGN" to align size as cacheline
>> >> ? ? - Removed headers from usb.h
>> >> ? ? - Send 8 bytes of device descriptor size to read
>> >> ? ? ? Max packet size
>> >> scsi.h header is needed to avoid extra memcpy from local buffer
>> >> to global buffer.
>> >>
>> >> ?common/cmd_usb.c ? ? ? ? ? ?| ? ?3 +-
>> >> ?common/usb.c ? ? ? ? ? ? ? ?| ? 61
>> >> ++++++++++++++++++++++++------------------ common/usb_storage.c ? ? ? ?|
>> >> 59 +++++++++++++++++++---------------------- disk/part_dos.c
>> >> | 2 +-
>> >> ?drivers/usb/host/ehci-hcd.c | ? ?8 +++++
>> >> ?include/scsi.h ? ? ? ? ? ? ?| ? ?4 ++-
>> >> ?6 files changed, 77 insertions(+), 60 deletions(-)
>> >>
>> >> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
>> >> index 320667f..bca9d94 100644
>> >> --- a/common/cmd_usb.c
>> >> +++ b/common/cmd_usb.c
>> >> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
>> >> unsigned char subclass,
>> >>
>> >> ?void usb_display_string(struct usb_device *dev, int index)
>> >> ?{
>> >> - ? ? char buffer[256];
>> >> + ? ? ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
>> >
>> > Why not memalign(), do you want to allocate on stack so badly ?
>>
>> This issue came up with MMC and there was a strong request not to
>> sprinkle the code with malloc. In fact the macro above was devised at
>> some cost just to solve this problem.
>
> This is really weird solution :-(

It's not pretty under the hood but it solves the problem well for MMC.
Apart from the alignment of buffers, it is as efficient as the
original code.

>>
>> [snip]
>>
>> >> ?{
>> >> ? ? ? int tries;
>> >> - ? ? struct usb_port_status portsts;
>> >> + ? ? ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>> >
>> > Looking at all this stuff, it's already allocated on stack. Ok, I already
>> > outlined first option -- memalign(), but that'd really put quite a strain
>> > on the memory allocator -- the other option (and maybe even better) is
>> > to use __attribute__((aligned)), which will allow the compiler to
>> > reorder data allocated on the stack so the array you create is aligned
>> > and not much space around on the stack is wasted. Apparently,
>> > ALLOC_CACHE_ALIGN_BUFFER() wastes a lot of space on the stack.
>>
>> There was quite a bit of discussion about this related to MMC. I think
>> the current solution is the result of that discussion...
>
> Can you please point me to such discussion?

Start here perhaps and look at the whole thread:

http://lists.denx.de/pipermail/u-boot/2011-August/099152.html

>
> Thanks!

Regards,
Simon

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 2/2] usb: Add CONFIG to fetch string descriptor
  2012-02-27 15:36       ` [U-Boot] [PATCH v2 2/2] usb: Add CONFIG to fetch string descriptor Puneet Saxena
@ 2012-02-27 18:28         ` Mike Frysinger
  0 siblings, 0 replies; 83+ messages in thread
From: Mike Frysinger @ 2012-02-27 18:28 UTC (permalink / raw)
  To: u-boot

On Monday 27 February 2012 10:36:32 Puneet Saxena wrote:
> Add "CONFIG_USB_STRING_FETCH" to fetch string using descriptor length
> then fetch actual bytes, returned in descriptor buffer.

i'm having a hard time understanding what you're trying to say here

new CONFIG_xxx knobs should be documented in top level README

> --- a/include/configs/tegra2-common.h
> +++ b/include/configs/tegra2-common.h
> 
>  #define CONFIG_TEGRA2_GPIO
>  #define CONFIG_CMD_GPIO
> +
>  #endif /* __TEGRA2_COMMON_H */

please do not include unrelated whitespace changes
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120227/3372b6f4/attachment.pgp>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline
  2012-02-27 16:49         ` Marek Vasut
  2012-02-27 17:03           ` Simon Glass
@ 2012-02-28  9:34           ` puneets
  2012-02-29 21:38             ` Marek Vasut
  1 sibling, 1 reply; 83+ messages in thread
From: puneets @ 2012-02-28  9:34 UTC (permalink / raw)
  To: u-boot

Hi Marek,
IMO, Simon has already mentioned the reason of using 
ALLOC_CACHE_ALIGN_BUFFER,
Please find below my explanation about other doubts.
On Monday 27 February 2012 10:19 PM, Marek Vasut wrote:
>> As DMA expects the buffers to be equal and larger then
>> cache lines, This aligns buffers at cacheline.
>>
>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>> Signed-off-by: Jim Lin<jilin@nvidia.com>
>> ---
>>
> First of all, thanks for this patch, it really helps. But, there are a few
> things that concern me.
>
>> Changes for V2:
>>      - Use "ARCH_DMA_MINALIGN" directly
>>      - Use "ALIGN" to align size as cacheline
>>      - Removed headers from usb.h
>>      - Send 8 bytes of device descriptor size to read
>>        Max packet size
>> scsi.h header is needed to avoid extra memcpy from local buffer
>> to global buffer.
>>
>>   common/cmd_usb.c            |    3 +-
>>   common/usb.c                |   61
>> ++++++++++++++++++++++++------------------ common/usb_storage.c        |
>> 59 +++++++++++++++++++---------------------- disk/part_dos.c             |
>>     2 +-
>>   drivers/usb/host/ehci-hcd.c |    8 +++++
>>   include/scsi.h              |    4 ++-
>>   6 files changed, 77 insertions(+), 60 deletions(-)
>>
>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
>> index 320667f..bca9d94 100644
>> --- a/common/cmd_usb.c
>> +++ b/common/cmd_usb.c
>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
>> unsigned char subclass,
>>
>>   void usb_display_string(struct usb_device *dev, int index)
>>   {
>> -     char buffer[256];
>> +     ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> Why not memalign(), do you want to allocate on stack so badly ?
>
>> +
>>        if (index != 0) {
>>                if (usb_string(dev, index,&buffer[0], 256)>  0)
>>                        printf("String: \"%s\"", buffer);
>> diff --git a/common/usb.c b/common/usb.c
>> index 63a11c8..2279459 100644
>> --- a/common/usb.c
>> +++ b/common/usb.c
>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>>   static int dev_index;
>>   static int running;
>>   static int asynch_allowed;
>> -static struct devrequest setup_packet;
>>
>>   char usb_started; /* flag for the started/stopped USB status */
>>
>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned
>> int pipe, unsigned short value, unsigned short index,
>>                        void *data, unsigned short size, int timeout)
>>   {
>> +     ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
>> +             sizeof(struct devrequest));
> DTTO, btw does the setup packet need to be aligned too ?
>
We need to align setup packet as it's used for constructing SETUP 
Transfer descriptor buffer.
Plz see the code - Ehci-hcd.c (drivers\usb\host) Line No - 402.

>>        if ((timeout == 0)&&  (!asynch_allowed)) {
>>                /* request for a asynch control pipe is not allowed */
>>                return -1;
>>        }
>>
>>        /* set setup command */
>> -     setup_packet.requesttype = requesttype;
>> -     setup_packet.request = request;
>> -     setup_packet.value = cpu_to_le16(value);
>> -     setup_packet.index = cpu_to_le16(index);
>> -     setup_packet.length = cpu_to_le16(size);
>> +     setup_packet->requesttype = requesttype;
>> +     setup_packet->request = request;
>> +     setup_packet->value = cpu_to_le16(value);
>> +     setup_packet->index = cpu_to_le16(index);
>> +     setup_packet->length = cpu_to_le16(size);
>>        USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>>                   "value 0x%X index 0x%X length 0x%X\n",
>>                   request, requesttype, value, index, size);
>>        dev->status = USB_ST_NOT_PROC; /*not yet processed */
>>
>> -     submit_control_msg(dev, pipe, data, size,&setup_packet);
>> +     submit_control_msg(dev, pipe, data, size, setup_packet);
>>        if (timeout == 0)
>>                return (int)size;
>>
>> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev,
>> unsigned int langid, */
>>   int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>>   {
>> -     unsigned char mybuf[USB_BUFSIZ];
>> +     ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>>        unsigned char *tbuf;
>>        int err;
>>        unsigned int u, idx;
>> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
>>   {
>>        int addr, err;
>>        int tmp;
>> -     unsigned char tmpbuf[USB_BUFSIZ];
>> +     ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> Why not simply memalign() them all?
>>        /* We still haven't set the Address yet */
>>        addr = dev->devnum;
>> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
>>        dev->epmaxpacketin[0] = 64;
>>        dev->epmaxpacketout[0] = 64;
>>
>> -     err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
>> +     desc->bMaxPacketSize0 = 0;
>> +     /*8 bytes of the descriptor to read Max packet size*/
>> +     err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
>> +                     8);
>>        if (err<  0) {
>>                USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
>>                return 1;
>> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
>>        tmp = sizeof(dev->descriptor);
>>
>>        err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
>> -&dev->descriptor, sizeof(dev->descriptor));
>> +                              desc, sizeof(dev->descriptor));
>>        if (err<  tmp) {
>>                if (err<  0)
>>                        printf("unable to get device descriptor (error=%d)\n",
>> @@ -915,14 +919,18 @@ int usb_new_device(struct usb_device *dev)
>>                                "(expected %i, got %i)\n", tmp, err);
>>                return 1;
>>        }
>> +     dev->descriptor.bcdUSB = desc->bcdUSB;
>> +     dev->descriptor.idVendor = desc->idVendor;
>> +     dev->descriptor.idProduct = desc->idProduct;
>> +     dev->descriptor.bcdDevice = desc->bcdDevice;
> Isn't the above change unrelated?
>
Agreed. Its not useful here at least. Will incorporate in next patch
>>        /* correct le values */
>>        le16_to_cpus(&dev->descriptor.bcdUSB);
>>        le16_to_cpus(&dev->descriptor.idVendor);
>>        le16_to_cpus(&dev->descriptor.idProduct);
>>        le16_to_cpus(&dev->descriptor.bcdDevice);
>>        /* only support for one config for now */
>> -     usb_get_configuration_no(dev,&tmpbuf[0], 0);
>> -     usb_parse_config(dev,&tmpbuf[0], 0);
>> +     usb_get_configuration_no(dev, tmpbuf, 0);
>> +     usb_parse_config(dev, tmpbuf, 0);
>>        usb_set_maxpacket(dev);
>>        /* we set the default configuration here */
>>        if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
>> @@ -1076,7 +1084,7 @@ static int hub_port_reset(struct usb_device *dev, int
>> port, unsigned short *portstat)
>>   {
>>        int tries;
>> -     struct usb_port_status portsts;
>> +     ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
> Looking at all this stuff, it's already allocated on stack. Ok, I already
> outlined first option -- memalign(), but that'd really put quite a strain on the
> memory allocator -- the other option (and maybe even better) is to use
> __attribute__((aligned)), which will allow the compiler to reorder data
> allocated on the stack so the array you create is aligned and not much space
> around on the stack is wasted. Apparently, ALLOC_CACHE_ALIGN_BUFFER() wastes a
> lot of space on the stack.
>
>>        unsigned short portstatus, portchange;
>>
>>        USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
>> @@ -1085,13 +1093,13 @@ static int hub_port_reset(struct usb_device *dev,
>> int port, usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
>>                wait_ms(200);
>>
>> -             if (usb_get_port_status(dev, port + 1,&portsts)<  0) {
>> +             if (usb_get_port_status(dev, port + 1, portsts)<  0) {
>>                        USB_HUB_PRINTF("get_port_status failed status %lX\n",
>>                                        dev->status);
>>                        return -1;
>>                }
>> -             portstatus = le16_to_cpu(portsts.wPortStatus);
>> -             portchange = le16_to_cpu(portsts.wPortChange);
>> +             portstatus = le16_to_cpu(portsts->wPortStatus);
>> +             portchange = le16_to_cpu(portsts->wPortChange);
>>
>>                USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
>>                                portstatus, portchange,
>> @@ -1129,19 +1137,19 @@ static int hub_port_reset(struct usb_device *dev,
>> int port, void usb_hub_port_connect_change(struct usb_device *dev, int
>> port) {
>>        struct usb_device *usb;
>> -     struct usb_port_status portsts;
>> +     ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>>        unsigned short portstatus;
>>
>>        /* Check status */
>> -     if (usb_get_port_status(dev, port + 1,&portsts)<  0) {
>> +     if (usb_get_port_status(dev, port + 1, portsts)<  0) {
>>                USB_HUB_PRINTF("get_port_status failed\n");
>>                return;
>>        }
>>
>> -     portstatus = le16_to_cpu(portsts.wPortStatus);
>> +     portstatus = le16_to_cpu(portsts->wPortStatus);
>>        USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
>>                        portstatus,
>> -                     le16_to_cpu(portsts.wPortChange),
>> +                     le16_to_cpu(portsts->wPortChange),
>>                        portspeed(portstatus));
>>
>>        /* Clear the connection change status */
>> @@ -1190,7 +1198,8 @@ void usb_hub_port_connect_change(struct usb_device
>> *dev, int port) int usb_hub_configure(struct usb_device *dev)
>>   {
>>        int i;
>> -     unsigned char buffer[USB_BUFSIZ], *bitmap;
>> +     ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
>> +     unsigned char *bitmap;
>>        struct usb_hub_descriptor *descriptor;
>>        struct usb_hub_device *hub;
>>   #ifdef USB_HUB_DEBUG
>> @@ -1312,16 +1321,16 @@ int usb_hub_configure(struct usb_device *dev)
>>        usb_hub_power_on(hub);
>>
>>        for (i = 0; i<  dev->maxchild; i++) {
>> -             struct usb_port_status portsts;
>> +             ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>>                unsigned short portstatus, portchange;
>>
>> -             if (usb_get_port_status(dev, i + 1,&portsts)<  0) {
>> +             if (usb_get_port_status(dev, i + 1, portsts)<  0) {
>>                        USB_HUB_PRINTF("get_port_status failed\n");
>>                        continue;
>>                }
>>
>> -             portstatus = le16_to_cpu(portsts.wPortStatus);
>> -             portchange = le16_to_cpu(portsts.wPortChange);
>> +             portstatus = le16_to_cpu(portsts->wPortStatus);
>> +             portchange = le16_to_cpu(portsts->wPortChange);
>>                USB_HUB_PRINTF("Port %d Status %X Change %X\n",
>>                                i + 1, portstatus, portchange);
>>
>> diff --git a/common/usb_storage.c b/common/usb_storage.c
>> index de84c8d..88ca390 100644
>> --- a/common/usb_storage.c
>> +++ b/common/usb_storage.c
>> @@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
>>   };
>>   #define US_DIRECTION(x) ((us_direction[x>>3]>>  (x&  7))&  1)
>>
>> -static unsigned char usb_stor_buf[512];
>> -static ccb usb_ccb;
>> +static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
>>
>>   /*
>>    * CBI style
>> @@ -210,17 +209,17 @@ int usb_stor_info(void)
>>   static unsigned int usb_get_max_lun(struct us_data *us)
>>   {
>>        int len;
>> -     unsigned char result;
>> +     ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
>>        len = usb_control_msg(us->pusb_dev,
>>                              usb_rcvctrlpipe(us->pusb_dev, 0),
>>                              US_BBB_GET_MAX_LUN,
>>                              USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
>>                              0, us->ifnum,
>> -&result, sizeof(result),
>> +                           result, sizeof(char),
>>                              USB_CNTL_TIMEOUT * 5);
>>        USB_STOR_PRINTF("Get Max LUN ->  len = %i, result = %i\n",
>> -                     len, (int) result);
>> -     return (len>  0) ? result : 0;
>> +                     len, (int) *result);
>> +     return (len>  0) ? *result : 0;
>>   }
>>
>>   /*************************************************************************
>> ****** @@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
>>        unsigned char i;
>>        struct usb_device *dev;
>>
>> -     /* GJ */
>> -     memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
>> -
>>        if (mode == 1)
>>                printf("       scanning bus for storage devices... ");
>>
>> @@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
>>        int actlen;
>>        int dir_in;
>>        unsigned int pipe;
>> -     umass_bbb_cbw_t cbw;
>> +     ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
>>
>>        dir_in = US_DIRECTION(srb->cmd[0]);
>>
>> @@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
>>        /* always OUT to the ep */
>>        pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
>>
>> -     cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
>> -     cbw.dCBWTag = cpu_to_le32(CBWTag++);
>> -     cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
>> -     cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
>> -     cbw.bCBWLUN = srb->lun;
>> -     cbw.bCDBLength = srb->cmdlen;
>> +     cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
>> +     cbw->dCBWTag = cpu_to_le32(CBWTag++);
>> +     cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
>> +     cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
>> +     cbw->bCBWLUN = srb->lun;
>> +     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,
>> +     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);
>>        if (result<  0)
>>                USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
>> @@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data
>> *us) int dir_in;
>>        int actlen, data_actlen;
>>        unsigned int pipe, pipein, pipeout;
>> -     umass_bbb_csw_t csw;
>> +     ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
>>   #ifdef BBB_XPORT_TRACE
>>        unsigned char *ptr;
>>        int index;
>> @@ -733,7 +729,7 @@ st:
>>        retry = 0;
>>   again:
>>        USB_STOR_PRINTF("STATUS phase\n");
>> -     result = usb_bulk_msg(us->pusb_dev, pipein,&csw, UMASS_BBB_CSW_SIZE,
>> +     result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
>>                                &actlen, USB_CNTL_TIMEOUT*5);
>>
>>        /* special handling of STALL in STATUS phase */
>> @@ -753,28 +749,28 @@ again:
>>                return USB_STOR_TRANSPORT_FAILED;
>>        }
>>   #ifdef BBB_XPORT_TRACE
>> -     ptr = (unsigned char *)&csw;
>> +     ptr = (unsigned char *)csw;
>>        for (index = 0; index<  UMASS_BBB_CSW_SIZE; index++)
>>                printf("ptr[%d] %#x ", index, ptr[index]);
>>        printf("\n");
>>   #endif
>>        /* misuse pipe to get the residue */
>> -     pipe = le32_to_cpu(csw.dCSWDataResidue);
>> +     pipe = le32_to_cpu(csw->dCSWDataResidue);
>>        if (pipe == 0&&  srb->datalen != 0&&  srb->datalen - data_actlen != 0)
>>                pipe = srb->datalen - data_actlen;
>> -     if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
>> +     if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
>>                USB_STOR_PRINTF("!CSWSIGNATURE\n");
>>                usb_stor_BBB_reset(us);
>>                return USB_STOR_TRANSPORT_FAILED;
>> -     } else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
>> +     } else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
>>                USB_STOR_PRINTF("!Tag\n");
>>                usb_stor_BBB_reset(us);
>>                return USB_STOR_TRANSPORT_FAILED;
>> -     } else if (csw.bCSWStatus>  CSWSTATUS_PHASE) {
>> +     } else if (csw->bCSWStatus>  CSWSTATUS_PHASE) {
>>                USB_STOR_PRINTF(">PHASE\n");
>>                usb_stor_BBB_reset(us);
>>                return USB_STOR_TRANSPORT_FAILED;
>> -     } else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
>> +     } else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
>>                USB_STOR_PRINTF("=PHASE\n");
>>                usb_stor_BBB_reset(us);
>>                return USB_STOR_TRANSPORT_FAILED;
>> @@ -782,7 +778,7 @@ again:
>>                USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
>>                        data_actlen, srb->datalen);
>>                return USB_STOR_TRANSPORT_FAILED;
>> -     } else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
>> +     } else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
>>                USB_STOR_PRINTF("FAILED\n");
>>                return USB_STOR_TRANSPORT_FAILED;
>>        }
>> @@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct
>> us_data *ss, block_dev_desc_t *dev_desc)
>>   {
>>        unsigned char perq, modi;
>> -     unsigned long cap[2];
>> +     ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
>> +     ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
>>        unsigned long *capacity, *blksz;
>>        ccb *pccb =&usb_ccb;
>>
>> @@ -1367,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],&usb_stor_buf[8], 8);
>> -     memcpy(&dev_desc->product[0],&usb_stor_buf[16], 16);
>> -     memcpy(&dev_desc->revision[0],&usb_stor_buf[32], 4);
>> +     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);
>>        dev_desc->vendor[8] = 0;
>>        dev_desc->product[16] = 0;
>>        dev_desc->revision[4] = 0;
>> diff --git a/disk/part_dos.c b/disk/part_dos.c
>> index b5bcb37..70211ee 100644
>> --- a/disk/part_dos.c
>> +++ b/disk/part_dos.c
>> @@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
>>
>>   int test_part_dos (block_dev_desc_t *dev_desc)
>>   {
>> -     unsigned char buffer[dev_desc->blksz];
>> +     ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
>>
>>        if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1)
> ||
>>            (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
>> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
>> index d893b2a..eb5220b 100644
>> --- a/drivers/usb/host/ehci-hcd.c
>> +++ b/drivers/usb/host/ehci-hcd.c
>> @@ -120,6 +120,14 @@ static struct descriptor {
>>    */
>>   static void flush_invalidate(u32 addr, int size, int flush)
>>   {
>> +     /*
>> +      * Size is the bytes actually moved during transaction,
>> +      * which may not equal to the cache line. This results
>> +      * stop address passed for invalidating cache may not be aligned.
>> +      * Therfore making size as multiple of cache line size.
>> +      */
>> +     size = ALIGN(size, ARCH_DMA_MINALIGN);
>> +
>>        if (flush)
>>                flush_dcache_range(addr, addr + size);
>>        else
>> diff --git a/include/scsi.h b/include/scsi.h
>> index c52759c..89ae45f 100644
>> --- a/include/scsi.h
>> +++ b/include/scsi.h
>> @@ -26,7 +26,9 @@
>>
>>   typedef struct SCSI_cmd_block{
>>        unsigned char           cmd[16];
> /* command                                 */
>> -     unsigned char           sense_buf[64];          /* for request sense */
>> +     /* for request sense */
>> +     unsigned char           sense_buf[64]
>> +             __attribute__((aligned(ARCH_DMA_MINALIGN)));
>>        unsigned char           status;
> /* SCSI Status                   */
>>        unsigned char           target;
> /* Target ID                             */
>>        unsigned char           lun;
> /* Target LUN        */
>
> Thanks!
Thanx,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 1/2] usb: align buffers at cacheline
  2012-02-27 17:11             ` Marek Vasut
  2012-02-27 17:27               ` Simon Glass
@ 2012-02-29 14:21               ` Puneet Saxena
  2012-02-29 21:35                 ` Marek Vasut
  2012-02-29 14:21               ` [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor Puneet Saxena
  2 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-02-29 14:21 UTC (permalink / raw)
  To: u-boot

As DMA expects the buffers to be equal and larger then
cache lines, This aligns buffers at cacheline.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---

Changes for V2:
    - Use "ARCH_DMA_MINALIGN" directly
    - Use "ALIGN" to align size as cacheline
    - Removed headers from usb.h
    - Send 8 bytes of device descriptor size to read
      Max packet size
    scsi.h header is needed to avoid extra memcpy from local buffer
    to global buffer.

Changes for V3:
    - Removed local descriptor elements copy to global descriptor elements
    - Removed "Signed-off-by: Jim Lin <jilin@nvidia.com>" from commit message

 common/cmd_usb.c            |    3 +-
 common/usb.c                |   57 ++++++++++++++++++++++-------------------
 common/usb_storage.c        |   59 ++++++++++++++++++++----------------------
 disk/part_dos.c             |    2 +-
 drivers/usb/host/ehci-hcd.c |    8 ++++++
 include/scsi.h              |    4 ++-
 6 files changed, 73 insertions(+), 60 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 63a11c8..191bc5b 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
+		sizeof(struct devrequest));
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
 		   "value 0x%X index 0x%X length 0x%X\n",
 		   request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	submit_control_msg(dev, pipe, data, size, setup_packet);
 	if (timeout == 0)
 		return (int)size;
 
@@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
 	dev->epmaxpacketin[0] = 64;
 	dev->epmaxpacketout[0] = 64;
 
-	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
+	desc->bMaxPacketSize0 = 0;
+	/*8 bytes of the descriptor to read Max packet size*/
+	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
+			8);
 	if (err < 0) {
 		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
 		return 1;
@@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
 	tmp = sizeof(dev->descriptor);
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-				 &dev->descriptor, sizeof(dev->descriptor));
+				 desc, sizeof(dev->descriptor));
 	if (err < tmp) {
 		if (err < 0)
 			printf("unable to get device descriptor (error=%d)\n",
@@ -921,8 +925,8 @@ int usb_new_device(struct usb_device *dev)
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1076,7 +1080,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1085,13 +1089,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1129,19 +1133,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1190,7 +1194,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1312,16 +1317,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..88ca390 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
 
 /*
  * CBI style
@@ -210,17 +209,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
 		printf("       scanning bus for storage devices... ");
 
@@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +729,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +749,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +778,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
@@ -1367,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], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	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);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
diff --git a/disk/part_dos.c b/disk/part_dos.c
index b5bcb37..70211ee 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
-	unsigned char buffer[dev_desc->blksz];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..eb5220b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,6 +120,14 @@ static struct descriptor {
  */
 static void flush_invalidate(u32 addr, int size, int flush)
 {
+	/*
+	 * Size is the bytes actually moved during transaction,
+	 * which may not equal to the cache line. This results
+	 * stop address passed for invalidating cache may not be aligned.
+	 * Therfore making size as multiple of cache line size.
+	 */
+	size = ALIGN(size, ARCH_DMA_MINALIGN);
+
 	if (flush)
 		flush_dcache_range(addr, addr + size);
 	else
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..89ae45f 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,9 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-02-27 17:11             ` Marek Vasut
  2012-02-27 17:27               ` Simon Glass
  2012-02-29 14:21               ` [U-Boot] [PATCH v3 " Puneet Saxena
@ 2012-02-29 14:21               ` Puneet Saxena
  2012-02-29 21:29                 ` Marek Vasut
  2 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-02-29 14:21 UTC (permalink / raw)
  To: u-boot

Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor length
and then pass this length to fetch string descriptor.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---

Changes for V2:
   - Change existing config by "CONFIG_USB_STRING_FETCH"

Changes for V3:
    - Removed extra new line
    - Explained "CONFIG_USB_STRING_FETCH" in top level README

 README                          |    4 ++++
 common/usb.c                    |    4 ++++
 include/configs/tegra2-common.h |    2 ++
 3 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/README b/README
index 7adf7c7..c045a37 100644
--- a/README
+++ b/README
@@ -1138,6 +1138,10 @@ The following options need to be configured:
 		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
 		txfilltuning field in the EHCI controller on reset.
 
+		CONFIG_USB_STRING_FETCH
+		Enables settings to USB core to handle string issues which
+		few devices can not handle.
+
 - USB Device:
 		Define the below if you wish to use the USB console.
 		Once firmware is rebuilt from a serial console issue the
diff --git a/common/usb.c b/common/usb.c
index 191bc5b..a73cb60 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
 {
 	int rc;
 
+#ifdef CONFIG_USB_STRING_FETCH
+	rc = -1;
+#else
 	/* Try to read the string descriptor by asking for the maximum
 	 * possible number of bytes */
 	rc = usb_get_string(dev, langid, index, buf, 255);
+#endif
 
 	/* If that failed try to read the descriptor length, then
 	 * ask for just that many bytes */
diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h
index 266d0e5..d20b49c 100644
--- a/include/configs/tegra2-common.h
+++ b/include/configs/tegra2-common.h
@@ -93,6 +93,8 @@
 #define CONFIG_USB_EHCI_TXFIFO_THRESH	10
 #define CONFIG_EHCI_IS_TDI
 #define CONFIG_EHCI_DCACHE
+/* string descriptors must not be fetched using a 255-byte read */
+#define CONFIG_USB_STRING_FETCH
 
 /* include default commands */
 #include <config_cmd_default.h>
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-02-29 14:21               ` [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor Puneet Saxena
@ 2012-02-29 21:29                 ` Marek Vasut
  2012-03-01 11:07                   ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-02-29 21:29 UTC (permalink / raw)
  To: u-boot

> Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor length
> and then pass this length to fetch string descriptor.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> ---
> 
> Changes for V2:
>    - Change existing config by "CONFIG_USB_STRING_FETCH"
> 
> Changes for V3:
>     - Removed extra new line
>     - Explained "CONFIG_USB_STRING_FETCH" in top level README
> 
>  README                          |    4 ++++
>  common/usb.c                    |    4 ++++
>  include/configs/tegra2-common.h |    2 ++
>  3 files changed, 10 insertions(+), 0 deletions(-)
> 
> diff --git a/README b/README
> index 7adf7c7..c045a37 100644
> --- a/README
> +++ b/README
> @@ -1138,6 +1138,10 @@ The following options need to be configured:
>  		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
>  		txfilltuning field in the EHCI controller on reset.
> 
> +		CONFIG_USB_STRING_FETCH
> +		Enables settings to USB core to handle string issues which
> +		few devices can not handle.
> +
>  - USB Device:
>  		Define the below if you wish to use the USB console.
>  		Once firmware is rebuilt from a serial console issue the
> diff --git a/common/usb.c b/common/usb.c
> index 191bc5b..a73cb60 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device *dev,
> unsigned int langid, {
>  	int rc;
> 
> +#ifdef CONFIG_USB_STRING_FETCH

Shouldn't this be something like ... CONFIG_USB_AVOID_STRING_FETCH then?

Anyway, how come some devices can't handle it? What happens then? What devices 
are those (exact type etc)?

I believe the bug is deeper and adding extra config options can be avoided, what 
do you think?

Thanks!

M

> +	rc = -1;
> +#else
>  	/* Try to read the string descriptor by asking for the maximum
>  	 * possible number of bytes */
>  	rc = usb_get_string(dev, langid, index, buf, 255);
> +#endif
> 
>  	/* If that failed try to read the descriptor length, then
>  	 * ask for just that many bytes */
> diff --git a/include/configs/tegra2-common.h
> b/include/configs/tegra2-common.h index 266d0e5..d20b49c 100644
> --- a/include/configs/tegra2-common.h
> +++ b/include/configs/tegra2-common.h
> @@ -93,6 +93,8 @@
>  #define CONFIG_USB_EHCI_TXFIFO_THRESH	10
>  #define CONFIG_EHCI_IS_TDI
>  #define CONFIG_EHCI_DCACHE
> +/* string descriptors must not be fetched using a 255-byte read */
> +#define CONFIG_USB_STRING_FETCH
> 
>  /* include default commands */
>  #include <config_cmd_default.h>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 1/2] usb: align buffers at cacheline
  2012-02-29 14:21               ` [U-Boot] [PATCH v3 " Puneet Saxena
@ 2012-02-29 21:35                 ` Marek Vasut
  2012-03-01 13:51                   ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-02-29 21:35 UTC (permalink / raw)
  To: u-boot

> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> ---
> 
> Changes for V2:
>     - Use "ARCH_DMA_MINALIGN" directly
>     - Use "ALIGN" to align size as cacheline
>     - Removed headers from usb.h
>     - Send 8 bytes of device descriptor size to read
>       Max packet size
>     scsi.h header is needed to avoid extra memcpy from local buffer
>     to global buffer.
> 
> Changes for V3:
>     - Removed local descriptor elements copy to global descriptor elements
>     - Removed "Signed-off-by: Jim Lin <jilin@nvidia.com>" from commit
> message
> 
>  common/cmd_usb.c            |    3 +-
>  common/usb.c                |   57
> ++++++++++++++++++++++------------------- common/usb_storage.c        |  
> 59 ++++++++++++++++++++---------------------- disk/part_dos.c            
> |    2 +-
>  drivers/usb/host/ehci-hcd.c |    8 ++++++
>  include/scsi.h              |    4 ++-
>  6 files changed, 73 insertions(+), 60 deletions(-)
> 
> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> index 320667f..bca9d94 100644
> --- a/common/cmd_usb.c
> +++ b/common/cmd_usb.c
> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> unsigned char subclass,
> 
>  void usb_display_string(struct usb_device *dev, int index)
>  {
> -	char buffer[256];
> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> +
>  	if (index != 0) {
>  		if (usb_string(dev, index, &buffer[0], 256) > 0)
>  			printf("String: \"%s\"", buffer);
> diff --git a/common/usb.c b/common/usb.c
> index 63a11c8..191bc5b 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>  static int dev_index;
>  static int running;
>  static int asynch_allowed;
> -static struct devrequest setup_packet;
> 
>  char usb_started; /* flag for the started/stopped USB status */
> 
> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned
> int pipe, unsigned short value, unsigned short index,
>  			void *data, unsigned short size, int timeout)
>  {
> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> +		sizeof(struct devrequest));
>  	if ((timeout == 0) && (!asynch_allowed)) {
>  		/* request for a asynch control pipe is not allowed */
>  		return -1;
>  	}
> 
>  	/* set setup command */
> -	setup_packet.requesttype = requesttype;
> -	setup_packet.request = request;
> -	setup_packet.value = cpu_to_le16(value);
> -	setup_packet.index = cpu_to_le16(index);
> -	setup_packet.length = cpu_to_le16(size);
> +	setup_packet->requesttype = requesttype;
> +	setup_packet->request = request;
> +	setup_packet->value = cpu_to_le16(value);
> +	setup_packet->index = cpu_to_le16(index);
> +	setup_packet->length = cpu_to_le16(size);
>  	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>  		   "value 0x%X index 0x%X length 0x%X\n",
>  		   request, requesttype, value, index, size);
>  	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> 
> -	submit_control_msg(dev, pipe, data, size, &setup_packet);
> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>  	if (timeout == 0)
>  		return (int)size;
> 
> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev,
> unsigned int langid, */
>  int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>  {
> -	unsigned char mybuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>  	unsigned char *tbuf;
>  	int err;
>  	unsigned int u, idx;
> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
>  {
>  	int addr, err;
>  	int tmp;
> -	unsigned char tmpbuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> 
>  	/* We still haven't set the Address yet */
>  	addr = dev->devnum;
> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
>  	dev->epmaxpacketin[0] = 64;
>  	dev->epmaxpacketout[0] = 64;
> 
> -	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
> +	desc->bMaxPacketSize0 = 0;
> +	/*8 bytes of the descriptor to read Max packet size*/
> +	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
> +			8);

Did some unrelated addition/change creep in here?

>  	if (err < 0) {
>  		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
>  		return 1;
> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
>  	tmp = sizeof(dev->descriptor);
> 
>  	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
> -				 &dev->descriptor, sizeof(dev->descriptor));
> +				 desc, sizeof(dev->descriptor));

Won't this change (desc) break anything?

>  	if (err < tmp) {
>  		if (err < 0)
>  			printf("unable to get device descriptor (error=%d)\n",

The rest seems fine, from now on it seems to be only matter of trivial fix. 
Thanks for your effort so far!

M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline
  2012-02-28  9:34           ` [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline puneets
@ 2012-02-29 21:38             ` Marek Vasut
  0 siblings, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-02-29 21:38 UTC (permalink / raw)
  To: u-boot

> Hi Marek,
> IMO, Simon has already mentioned the reason of using
> ALLOC_CACHE_ALIGN_BUFFER,
> Please find below my explanation about other doubts.
> 
> On Monday 27 February 2012 10:19 PM, Marek Vasut wrote:
> >> As DMA expects the buffers to be equal and larger then
> >> cache lines, This aligns buffers at cacheline.
> >> 
> >> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >> Signed-off-by: Jim Lin<jilin@nvidia.com>
> >> ---
> > 
> > First of all, thanks for this patch, it really helps. But, there are a
> > few things that concern me.
> > 
> >> Changes for V2:
> >>      - Use "ARCH_DMA_MINALIGN" directly
> >>      - Use "ALIGN" to align size as cacheline
> >>      - Removed headers from usb.h
> >>      - Send 8 bytes of device descriptor size to read
> >>      
> >>        Max packet size
> >> 
> >> scsi.h header is needed to avoid extra memcpy from local buffer
> >> to global buffer.
> >> 
> >>   common/cmd_usb.c            |    3 +-
> >>   common/usb.c                |   61
> >> 
> >> ++++++++++++++++++++++++------------------ common/usb_storage.c        |
> >> 59 +++++++++++++++++++---------------------- disk/part_dos.c            
> >> |
> >> 
> >>     2 +-
> >>   
> >>   drivers/usb/host/ehci-hcd.c |    8 +++++
> >>   include/scsi.h              |    4 ++-
> >>   6 files changed, 77 insertions(+), 60 deletions(-)
> >> 
> >> diff --git a/common/cmd_usb.c b/common/cmd_usb.c

I see, thanks for explaining!

M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-02-29 21:29                 ` Marek Vasut
@ 2012-03-01 11:07                   ` puneets
  2012-03-01 11:45                     ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-01 11:07 UTC (permalink / raw)
  To: u-boot

Hi Marek,
On Thursday 01 March 2012 02:59 AM, Marek Vasut wrote:
>> Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor length
>> and then pass this length to fetch string descriptor.
>>
>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>> ---
>>
>> Changes for V2:
>>     - Change existing config by "CONFIG_USB_STRING_FETCH"
>>
>> Changes for V3:
>>      - Removed extra new line
>>      - Explained "CONFIG_USB_STRING_FETCH" in top level README
>>
>>   README                          |    4 ++++
>>   common/usb.c                    |    4 ++++
>>   include/configs/tegra2-common.h |    2 ++
>>   3 files changed, 10 insertions(+), 0 deletions(-)
>>
>> diff --git a/README b/README
>> index 7adf7c7..c045a37 100644
>> --- a/README
>> +++ b/README
>> @@ -1138,6 +1138,10 @@ The following options need to be configured:
>>   		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
>>   		txfilltuning field in the EHCI controller on reset.
>>
>> +		CONFIG_USB_STRING_FETCH
>> +		Enables settings to USB core to handle string issues which
>> +		few devices can not handle.
>> +
>>   - USB Device:
>>   		Define the below if you wish to use the USB console.
>>   		Once firmware is rebuilt from a serial console issue the
>> diff --git a/common/usb.c b/common/usb.c
>> index 191bc5b..a73cb60 100644
>> --- a/common/usb.c
>> +++ b/common/usb.c
>> @@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device *dev,
>> unsigned int langid, {
>>   	int rc;
>>
>> +#ifdef CONFIG_USB_STRING_FETCH
> Shouldn't this be something like ... CONFIG_USB_AVOID_STRING_FETCH then?
>
> Anyway, how come some devices can't handle it? What happens then? What devices
> are those (exact type etc)?
>
> I believe the bug is deeper and adding extra config options can be avoided, what
> do you think?
>
> Thanks!
>
> M
>
It does not avoid string fetch.
I checked with few mass storage devices that they does not handle string 
descriptor request correctly and so we get
start/stop Cache alignment error. One way is, blacklist those devices by 
vendor id/product id..
etc. This is done in Linux kernel. Plz see Message.c (drivers\usb\core) 
Line: 722.
Blacklisting the device requires a framework to detect the 
device...However this could be achieved
simply with this implementation.

>> +	rc = -1;
>> +#else
>>   	/* Try to read the string descriptor by asking for the maximum
>>   	 * possible number of bytes */
>>   	rc = usb_get_string(dev, langid, index, buf, 255);
>> +#endif
>>
>>   	/* If that failed try to read the descriptor length, then
>>   	 * ask for just that many bytes */
>> diff --git a/include/configs/tegra2-common.h
>> b/include/configs/tegra2-common.h index 266d0e5..d20b49c 100644
>> --- a/include/configs/tegra2-common.h
>> +++ b/include/configs/tegra2-common.h
>> @@ -93,6 +93,8 @@
>>   #define CONFIG_USB_EHCI_TXFIFO_THRESH	10
>>   #define CONFIG_EHCI_IS_TDI
>>   #define CONFIG_EHCI_DCACHE
>> +/* string descriptors must not be fetched using a 255-byte read */
>> +#define CONFIG_USB_STRING_FETCH
>>
>>   /* include default commands */
>>   #include<config_cmd_default.h>


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-03-01 11:07                   ` puneets
@ 2012-03-01 11:45                     ` Marek Vasut
  2012-03-01 12:59                       ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-01 11:45 UTC (permalink / raw)
  To: u-boot

Hi!

> Hi Marek,
> 
> On Thursday 01 March 2012 02:59 AM, Marek Vasut wrote:
> >> Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor length
> >> and then pass this length to fetch string descriptor.
> >> 
> >> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >> ---
> >> 
> >> Changes for V2:
> >>     - Change existing config by "CONFIG_USB_STRING_FETCH"
> >> 
> >> Changes for V3:
> >>      - Removed extra new line
> >>      - Explained "CONFIG_USB_STRING_FETCH" in top level README
> >>   
> >>   README                          |    4 ++++
> >>   common/usb.c                    |    4 ++++
> >>   include/configs/tegra2-common.h |    2 ++
> >>   3 files changed, 10 insertions(+), 0 deletions(-)
> >> 
> >> diff --git a/README b/README
> >> index 7adf7c7..c045a37 100644
> >> --- a/README
> >> +++ b/README
> >> 
> >> @@ -1138,6 +1138,10 @@ The following options need to be configured:
> >>   		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
> >>   		txfilltuning field in the EHCI controller on reset.
> >> 
> >> +		CONFIG_USB_STRING_FETCH
> >> +		Enables settings to USB core to handle string issues which
> >> +		few devices can not handle.
> >> +
> >> 
> >>   - USB Device:
> >>   		Define the below if you wish to use the USB console.
> >>   		Once firmware is rebuilt from a serial console issue the
> >> 
> >> diff --git a/common/usb.c b/common/usb.c
> >> index 191bc5b..a73cb60 100644
> >> --- a/common/usb.c
> >> +++ b/common/usb.c
> >> @@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device *dev,
> >> unsigned int langid, {
> >> 
> >>   	int rc;
> >> 
> >> +#ifdef CONFIG_USB_STRING_FETCH
> > 
> > Shouldn't this be something like ... CONFIG_USB_AVOID_STRING_FETCH then?
> > 
> > Anyway, how come some devices can't handle it? What happens then? What
> > devices are those (exact type etc)?
> > 
> > I believe the bug is deeper and adding extra config options can be
> > avoided, what do you think?
> > 
> > Thanks!
> > 
> > M
> 
> It does not avoid string fetch.

Well it does certainly not call usb_get_string()

> I checked with few mass storage devices that they does not handle string
> descriptor request correctly and so we get
> start/stop Cache alignment error.

Cache alignment error ? Wow, how's that actually related to SUB string fetching? 
Maybe we should manually realign the result then? I still don't really 
understand what you're seeing, sorry ... can you please elaborate?

> One way is, blacklist those devices by
> vendor id/product id..
> etc. This is done in Linux kernel. Plz see Message.c (drivers\usb\core)
> Line: 722.
> Blacklisting the device requires a framework to detect the
> device...However this could be achieved
> simply with this implementation.

Sure, I see your intention, but I still don't get the problem, see above. Can 
you also tell me if there's particular device that's broken and which one is it 
(precise type etc)?

Thanks a lot for your cooperation on this matter!

M

> 
> >> +	rc = -1;
> >> +#else
> >> 
> >>   	/* Try to read the string descriptor by asking for the maximum
> >>   	
> >>   	 * possible number of bytes */
> >>   	
> >>   	rc = usb_get_string(dev, langid, index, buf, 255);
> >> 
> >> +#endif
> >> 
> >>   	/* If that failed try to read the descriptor length, then
> >>   	
> >>   	 * ask for just that many bytes */
> >> 
> >> diff --git a/include/configs/tegra2-common.h
> >> b/include/configs/tegra2-common.h index 266d0e5..d20b49c 100644
> >> --- a/include/configs/tegra2-common.h
> >> +++ b/include/configs/tegra2-common.h
> >> @@ -93,6 +93,8 @@
> >> 
> >>   #define CONFIG_USB_EHCI_TXFIFO_THRESH	10
> >>   #define CONFIG_EHCI_IS_TDI
> >>   #define CONFIG_EHCI_DCACHE
> >> 
> >> +/* string descriptors must not be fetched using a 255-byte read */
> >> +#define CONFIG_USB_STRING_FETCH
> >> 
> >>   /* include default commands */
> >>   #include<config_cmd_default.h>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-03-01 11:45                     ` Marek Vasut
@ 2012-03-01 12:59                       ` puneets
  2012-03-01 13:13                         ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-01 12:59 UTC (permalink / raw)
  To: u-boot

Hi Marek,

On Thursday 01 March 2012 05:15 PM, Marek Vasut wrote:
> Hi!
>
>> Hi Marek,
>>
>> On Thursday 01 March 2012 02:59 AM, Marek Vasut wrote:
>>>> Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor length
>>>> and then pass this length to fetch string descriptor.
>>>>
>>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>>>> ---
>>>>
>>>> Changes for V2:
>>>>      - Change existing config by "CONFIG_USB_STRING_FETCH"
>>>>
>>>> Changes for V3:
>>>>       - Removed extra new line
>>>>       - Explained "CONFIG_USB_STRING_FETCH" in top level README
>>>>
>>>>    README                          |    4 ++++
>>>>    common/usb.c                    |    4 ++++
>>>>    include/configs/tegra2-common.h |    2 ++
>>>>    3 files changed, 10 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/README b/README
>>>> index 7adf7c7..c045a37 100644
>>>> --- a/README
>>>> +++ b/README
>>>>
>>>> @@ -1138,6 +1138,10 @@ The following options need to be configured:
>>>>    		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
>>>>    		txfilltuning field in the EHCI controller on reset.
>>>>
>>>> +		CONFIG_USB_STRING_FETCH
>>>> +		Enables settings to USB core to handle string issues which
>>>> +		few devices can not handle.
>>>> +
>>>>
>>>>    - USB Device:
>>>>    		Define the below if you wish to use the USB console.
>>>>    		Once firmware is rebuilt from a serial console issue the
>>>>
>>>> diff --git a/common/usb.c b/common/usb.c
>>>> index 191bc5b..a73cb60 100644
>>>> --- a/common/usb.c
>>>> +++ b/common/usb.c
>>>> @@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device *dev,
>>>> unsigned int langid, {
>>>>
>>>>    	int rc;
>>>>
>>>> +#ifdef CONFIG_USB_STRING_FETCH
>>> Shouldn't this be something like ... CONFIG_USB_AVOID_STRING_FETCH then?
>>>
>>> Anyway, how come some devices can't handle it? What happens then? What
>>> devices are those (exact type etc)?
>>>
>>> I believe the bug is deeper and adding extra config options can be
>>> avoided, what do you think?
>>>
>>> Thanks!
>>>
>>> M
>> It does not avoid string fetch.
> Well it does certainly not call usb_get_string()
>
Precisely, it avoids fetching string desc of 255 bytes. so better name 
could be
"CONFIG_USB_AVOID_STRING_FETCH_255".  Thanks for your comment.

>> I checked with few mass storage devices that they does not handle string
>> descriptor request correctly and so we get
>> start/stop Cache alignment error.
> Cache alignment error ? Wow, how's that actually related to SUB string fetching?
> Maybe we should manually realign the result then? I still don't really
> understand what you're seeing, sorry ... can you please elaborate?
>
The particular mass storage device is -

Vendor: Kingston Rev: PMAP Prod: DataTraveler 2.0

Type: Removable Hard Disk

Capacity: 1906.0 MB = 1.8 GB (3903488 x 512)

When code tries to read Manufacturing Id..prod id...etc..it passes cache 
aligned buffer "tbuf" in
"usb_string()" @usb.c. Inside "usb_string_sub()", usb_get_string() 
passes as default 255 bytes to fetch string
descriptor.
The code in "ehci_submit_async() " invalidates *partially* the passed 
buffer though we pass aligned buffer and "STD_ASS"
is received. Though it should invalidate only the cached line which is 
equal(~32)  to string desc length.

If we give delay of 1 ms after handshake() the cache alignment warning 
does not spew...but delay of 1 ms is not acceptable.
So I enabled the code to fetch first string desc length and then fetch 
string desc fetch, in this way the issue is resolved.
It makes sense also to fetch string desc length and then actual string 
desc....

Thanks,
Puneet

   One way is, blacklist those devices by
>> vendor id/product id..
>> etc. This is done in Linux kernel. Plz see Message.c (drivers\usb\core)
>> Line: 722.
>> Blacklisting the device requires a framework to detect the
>> device...However this could be achieved
>> simply with this implementation.
> Sure, I see your intention, but I still don't get the problem, see above. Can
> you also tell me if there's particular device that's broken and which one is it
> (precise type etc)?
>
> Thanks a lot for your cooperation on this matter!
>
> M
>
>>>> +	rc = -1;
>>>> +#else
>>>>
>>>>    	/* Try to read the string descriptor by asking for the maximum
>>>>    	
>>>>    	 * possible number of bytes */
>>>>    	
>>>>    	rc = usb_get_string(dev, langid, index, buf, 255);
>>>>
>>>> +#endif
>>>>
>>>>    	/* If that failed try to read the descriptor length, then
>>>>    	
>>>>    	 * ask for just that many bytes */
>>>>
>>>> diff --git a/include/configs/tegra2-common.h
>>>> b/include/configs/tegra2-common.h index 266d0e5..d20b49c 100644
>>>> --- a/include/configs/tegra2-common.h
>>>> +++ b/include/configs/tegra2-common.h
>>>> @@ -93,6 +93,8 @@
>>>>
>>>>    #define CONFIG_USB_EHCI_TXFIFO_THRESH	10
>>>>    #define CONFIG_EHCI_IS_TDI
>>>>    #define CONFIG_EHCI_DCACHE
>>>>
>>>> +/* string descriptors must not be fetched using a 255-byte read */
>>>> +#define CONFIG_USB_STRING_FETCH
>>>>
>>>>    /* include default commands */
>>>>    #include<config_cmd_default.h>


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-03-01 12:59                       ` puneets
@ 2012-03-01 13:13                         ` Marek Vasut
  2012-03-05 12:48                           ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-01 13:13 UTC (permalink / raw)
  To: u-boot

> Hi Marek,
> 
> On Thursday 01 March 2012 05:15 PM, Marek Vasut wrote:
> > Hi!
> > 
> >> Hi Marek,
> >> 
> >> On Thursday 01 March 2012 02:59 AM, Marek Vasut wrote:
> >>>> Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor length
> >>>> and then pass this length to fetch string descriptor.
> >>>> 
> >>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >>>> ---
> >>>> 
> >>>> Changes for V2:
> >>>>      - Change existing config by "CONFIG_USB_STRING_FETCH"
> >>>> 
> >>>> Changes for V3:
> >>>>       - Removed extra new line
> >>>>       - Explained "CONFIG_USB_STRING_FETCH" in top level README
> >>>>    
> >>>>    README                          |    4 ++++
> >>>>    common/usb.c                    |    4 ++++
> >>>>    include/configs/tegra2-common.h |    2 ++
> >>>>    3 files changed, 10 insertions(+), 0 deletions(-)
> >>>> 
> >>>> diff --git a/README b/README
> >>>> index 7adf7c7..c045a37 100644
> >>>> --- a/README
> >>>> +++ b/README
> >>>> 
> >>>> @@ -1138,6 +1138,10 @@ The following options need to be configured:
> >>>>    		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
> >>>>    		txfilltuning field in the EHCI controller on reset.
> >>>> 
> >>>> +		CONFIG_USB_STRING_FETCH
> >>>> +		Enables settings to USB core to handle string issues 
which
> >>>> +		few devices can not handle.
> >>>> +
> >>>> 
> >>>>    - USB Device:
> >>>>    		Define the below if you wish to use the USB console.
> >>>>    		Once firmware is rebuilt from a serial console issue the
> >>>> 
> >>>> diff --git a/common/usb.c b/common/usb.c
> >>>> index 191bc5b..a73cb60 100644
> >>>> --- a/common/usb.c
> >>>> +++ b/common/usb.c
> >>>> @@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device *dev,
> >>>> unsigned int langid, {
> >>>> 
> >>>>    	int rc;
> >>>> 
> >>>> +#ifdef CONFIG_USB_STRING_FETCH
> >>> 
> >>> Shouldn't this be something like ... CONFIG_USB_AVOID_STRING_FETCH
> >>> then?
> >>> 
> >>> Anyway, how come some devices can't handle it? What happens then? What
> >>> devices are those (exact type etc)?
> >>> 
> >>> I believe the bug is deeper and adding extra config options can be
> >>> avoided, what do you think?
> >>> 
> >>> Thanks!
> >>> 
> >>> M
> >> 
> >> It does not avoid string fetch.
> > 
> > Well it does certainly not call usb_get_string()
> 
> Precisely, it avoids fetching string desc of 255 bytes. so better name
> could be
> "CONFIG_USB_AVOID_STRING_FETCH_255".  Thanks for your comment.
> 
> >> I checked with few mass storage devices that they does not handle string
> >> descriptor request correctly and so we get
> >> start/stop Cache alignment error.
> > 
> > Cache alignment error ? Wow, how's that actually related to SUB string
> > fetching? Maybe we should manually realign the result then? I still
> > don't really understand what you're seeing, sorry ... can you please
> > elaborate?
> 
> The particular mass storage device is -
> 
> Vendor: Kingston Rev: PMAP Prod: DataTraveler 2.0
> 
> Type: Removable Hard Disk
> 
> Capacity: 1906.0 MB = 1.8 GB (3903488 x 512)
> 
> When code tries to read Manufacturing Id..prod id...etc..it passes cache
> aligned buffer "tbuf" in
> "usb_string()" @usb.c. Inside "usb_string_sub()", usb_get_string()
> passes as default 255 bytes to fetch string
> descriptor.
> The code in "ehci_submit_async() " invalidates *partially* the passed
> buffer though we pass aligned buffer and "STD_ASS"
> is received. Though it should invalidate only the cached line which is
> equal(~32)  to string desc length.

Hm ... so this means the bug is in ehci_hcd? Maybe the ehci_hcd should be fixed 
to correctly handle caches then?
> 
> If we give delay of 1 ms after handshake() the cache alignment warning
> does not spew...but delay of 1 ms is not acceptable.
> So I enabled the code to fetch first string desc length and then fetch
> string desc fetch, in this way the issue is resolved.
> It makes sense also to fetch string desc length and then actual string
> desc....
> 

I see, I  understand now just about everything but the ehci problem, see above. 
Your explanation was very helpful.

Let's work this out together!

Cheers!

M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 1/2] usb: align buffers at cacheline
  2012-02-29 21:35                 ` Marek Vasut
@ 2012-03-01 13:51                   ` puneets
  2012-03-01 18:38                     ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-01 13:51 UTC (permalink / raw)
  To: u-boot

On Thursday 01 March 2012 03:05 AM, Marek Vasut wrote:
>> As DMA expects the buffers to be equal and larger then
>> cache lines, This aligns buffers at cacheline.
>>
>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>> ---
>>
>> Changes for V2:
>>      - Use "ARCH_DMA_MINALIGN" directly
>>      - Use "ALIGN" to align size as cacheline
>>      - Removed headers from usb.h
>>      - Send 8 bytes of device descriptor size to read
>>        Max packet size
>>      scsi.h header is needed to avoid extra memcpy from local buffer
>>      to global buffer.
>>
>> Changes for V3:
>>      - Removed local descriptor elements copy to global descriptor elements
>>      - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>" from commit
>> message
>>
>>   common/cmd_usb.c            |    3 +-
>>   common/usb.c                |   57
>> ++++++++++++++++++++++------------------- common/usb_storage.c        |
>> 59 ++++++++++++++++++++---------------------- disk/part_dos.c
>> |    2 +-
>>   drivers/usb/host/ehci-hcd.c |    8 ++++++
>>   include/scsi.h              |    4 ++-
>>   6 files changed, 73 insertions(+), 60 deletions(-)
>>
>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
>> index 320667f..bca9d94 100644
>> --- a/common/cmd_usb.c
>> +++ b/common/cmd_usb.c
>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
>> unsigned char subclass,
>>
>>   void usb_display_string(struct usb_device *dev, int index)
>>   {
>> -	char buffer[256];
>> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
>> +
>>   	if (index != 0) {
>>   		if (usb_string(dev, index,&buffer[0], 256)>  0)
>>   			printf("String: \"%s\"", buffer);
>> diff --git a/common/usb.c b/common/usb.c
>> index 63a11c8..191bc5b 100644
>> --- a/common/usb.c
>> +++ b/common/usb.c
>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>>   static int dev_index;
>>   static int running;
>>   static int asynch_allowed;
>> -static struct devrequest setup_packet;
>>
>>   char usb_started; /* flag for the started/stopped USB status */
>>
>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned
>> int pipe, unsigned short value, unsigned short index,
>>   			void *data, unsigned short size, int timeout)
>>   {
>> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
>> +		sizeof(struct devrequest));
>>   	if ((timeout == 0)&&  (!asynch_allowed)) {
>>   		/* request for a asynch control pipe is not allowed */
>>   		return -1;
>>   	}
>>
>>   	/* set setup command */
>> -	setup_packet.requesttype = requesttype;
>> -	setup_packet.request = request;
>> -	setup_packet.value = cpu_to_le16(value);
>> -	setup_packet.index = cpu_to_le16(index);
>> -	setup_packet.length = cpu_to_le16(size);
>> +	setup_packet->requesttype = requesttype;
>> +	setup_packet->request = request;
>> +	setup_packet->value = cpu_to_le16(value);
>> +	setup_packet->index = cpu_to_le16(index);
>> +	setup_packet->length = cpu_to_le16(size);
>>   	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>>   		   "value 0x%X index 0x%X length 0x%X\n",
>>   		   request, requesttype, value, index, size);
>>   	dev->status = USB_ST_NOT_PROC; /*not yet processed */
>>
>> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
>> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>>   	if (timeout == 0)
>>   		return (int)size;
>>
>> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev,
>> unsigned int langid, */
>>   int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>>   {
>> -	unsigned char mybuf[USB_BUFSIZ];
>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>>   	unsigned char *tbuf;
>>   	int err;
>>   	unsigned int u, idx;
>> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
>>   {
>>   	int addr, err;
>>   	int tmp;
>> -	unsigned char tmpbuf[USB_BUFSIZ];
>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
>>
>>   	/* We still haven't set the Address yet */
>>   	addr = dev->devnum;
>> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
>>   	dev->epmaxpacketin[0] = 64;
>>   	dev->epmaxpacketout[0] = 64;
>>
>> -	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
>> +	desc->bMaxPacketSize0 = 0;
>> +	/*8 bytes of the descriptor to read Max packet size*/
>> +	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
>> +			8);
> Did some unrelated addition/change creep in here?
No, This is the fix for the similar issue as is discussed for string 
fetch().
When the device partially fills the passed buffer and we try to 
invalidate the partial buffer
the cache alignment error crops up.

The code in "ehci_submit_async() " invalidates *partially* the passed
buffer though we pass aligned buffer after "STD_ASS"
is received. Actually it should invalidate only the cached line which is
equal(~32) to device desc length.

If we pass actual device desc length the cache alignment error does not 
spew.
Note that here we are aligning the buffer still the error comes.


>>   	if (err<  0) {
>>   		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
>>   		return 1;
>> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
>>   	tmp = sizeof(dev->descriptor);
>>
>>   	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
>> -				&dev->descriptor, sizeof(dev->descriptor));
>> +				 desc, sizeof(dev->descriptor));
> Won't this change (desc) break anything?
Its not breaking any thing. For safer side we could add memcpy to copy 
from local desc
to global desc. What you say?
>>   	if (err<  tmp) {
>>   		if (err<  0)
>>   			printf("unable to get device descriptor (error=%d)\n",
> The rest seems fine, from now on it seems to be only matter of trivial fix.
> Thanks for your effort so far!
>
> M

If rest of the code is fine in [Patch V3 1/2] except these two issue can 
it be acknowledged for up-streaming?

Thanks,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 1/2] usb: align buffers at cacheline
  2012-03-01 13:51                   ` puneets
@ 2012-03-01 18:38                     ` Marek Vasut
  2012-03-02  6:56                       ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-01 18:38 UTC (permalink / raw)
  To: u-boot

> On Thursday 01 March 2012 03:05 AM, Marek Vasut wrote:
> >> As DMA expects the buffers to be equal and larger then
> >> cache lines, This aligns buffers at cacheline.
> >> 
> >> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >> ---
> >> 
> >> Changes for V2:
> >>      - Use "ARCH_DMA_MINALIGN" directly
> >>      - Use "ALIGN" to align size as cacheline
> >>      - Removed headers from usb.h
> >>      - Send 8 bytes of device descriptor size to read
> >>      
> >>        Max packet size
> >>      
> >>      scsi.h header is needed to avoid extra memcpy from local buffer
> >>      to global buffer.
> >> 
> >> Changes for V3:
> >>      - Removed local descriptor elements copy to global descriptor
> >>      elements - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>" from
> >>      commit
> >> 
> >> message
> >> 
> >>   common/cmd_usb.c            |    3 +-
> >>   common/usb.c                |   57
> >> 
> >> ++++++++++++++++++++++------------------- common/usb_storage.c        |
> >> 59 ++++++++++++++++++++---------------------- disk/part_dos.c
> >> 
> >> |    2 +-
> >>   
> >>   drivers/usb/host/ehci-hcd.c |    8 ++++++
> >>   include/scsi.h              |    4 ++-
> >>   6 files changed, 73 insertions(+), 60 deletions(-)
> >> 
> >> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> >> index 320667f..bca9d94 100644
> >> --- a/common/cmd_usb.c
> >> +++ b/common/cmd_usb.c
> >> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> >> unsigned char subclass,
> >> 
> >>   void usb_display_string(struct usb_device *dev, int index)
> >>   {
> >> 
> >> -	char buffer[256];
> >> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> >> +
> >> 
> >>   	if (index != 0) {
> >>   	
> >>   		if (usb_string(dev, index,&buffer[0], 256)>  0)
> >>   		
> >>   			printf("String: \"%s\"", buffer);
> >> 
> >> diff --git a/common/usb.c b/common/usb.c
> >> index 63a11c8..191bc5b 100644
> >> --- a/common/usb.c
> >> +++ b/common/usb.c
> >> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
> >> 
> >>   static int dev_index;
> >>   static int running;
> >>   static int asynch_allowed;
> >> 
> >> -static struct devrequest setup_packet;
> >> 
> >>   char usb_started; /* flag for the started/stopped USB status */
> >> 
> >> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
> >> unsigned int pipe, unsigned short value, unsigned short index,
> >> 
> >>   			void *data, unsigned short size, int timeout)
> >>   
> >>   {
> >> 
> >> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> >> +		sizeof(struct devrequest));
> >> 
> >>   	if ((timeout == 0)&&  (!asynch_allowed)) {
> >>   	
> >>   		/* request for a asynch control pipe is not allowed */
> >>   		return -1;
> >>   	
> >>   	}
> >>   	
> >>   	/* set setup command */
> >> 
> >> -	setup_packet.requesttype = requesttype;
> >> -	setup_packet.request = request;
> >> -	setup_packet.value = cpu_to_le16(value);
> >> -	setup_packet.index = cpu_to_le16(index);
> >> -	setup_packet.length = cpu_to_le16(size);
> >> +	setup_packet->requesttype = requesttype;
> >> +	setup_packet->request = request;
> >> +	setup_packet->value = cpu_to_le16(value);
> >> +	setup_packet->index = cpu_to_le16(index);
> >> +	setup_packet->length = cpu_to_le16(size);
> >> 
> >>   	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
> >>   	
> >>   		   "value 0x%X index 0x%X length 0x%X\n",
> >>   		   request, requesttype, value, index, size);
> >>   	
> >>   	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> >> 
> >> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
> >> +	submit_control_msg(dev, pipe, data, size, setup_packet);
> >> 
> >>   	if (timeout == 0)
> >>   	
> >>   		return (int)size;
> >> 
> >> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev,
> >> unsigned int langid, */
> >> 
> >>   int usb_string(struct usb_device *dev, int index, char *buf, size_t
> >>   size) {
> >> 
> >> -	unsigned char mybuf[USB_BUFSIZ];
> >> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
> >> 
> >>   	unsigned char *tbuf;
> >>   	int err;
> >>   	unsigned int u, idx;
> >> 
> >> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
> >> 
> >>   {
> >>   
> >>   	int addr, err;
> >>   	int tmp;
> >> 
> >> -	unsigned char tmpbuf[USB_BUFSIZ];
> >> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> >> 
> >>   	/* We still haven't set the Address yet */
> >>   	addr = dev->devnum;
> >> 
> >> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
> >> 
> >>   	dev->epmaxpacketin[0] = 64;
> >>   	dev->epmaxpacketout[0] = 64;
> >> 
> >> -	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
> >> +	desc->bMaxPacketSize0 = 0;
> >> +	/*8 bytes of the descriptor to read Max packet size*/
> >> +	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
> >> +			8);
> > 
> > Did some unrelated addition/change creep in here?
> 
> No, This is the fix for the similar issue as is discussed for string
> fetch().
> When the device partially fills the passed buffer and we try to
> invalidate the partial buffer
> the cache alignment error crops up.
> 
> The code in "ehci_submit_async() " invalidates *partially* the passed
> buffer though we pass aligned buffer after "STD_ASS"
> is received. Actually it should invalidate only the cached line which is
> equal(~32) to device desc length.
> 
> If we pass actual device desc length the cache alignment error does not
> spew.
> Note that here we are aligning the buffer still the error comes.

Then please send this fix as a separate patch. And I think ehci_hcd is what 
should be fixed then as I said in the other email, or am I wrong?

> 
> >>   	if (err<  0) {
> >>   	
> >>   		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
> >>   		return 1;
> >> 
> >> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
> >> 
> >>   	tmp = sizeof(dev->descriptor);
> >>   	
> >>   	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
> >> 
> >> -				&dev->descriptor, sizeof(dev->descriptor));
> >> +				 desc, sizeof(dev->descriptor));
> > 
> > Won't this change (desc) break anything?
> 
> Its not breaking any thing. For safer side we could add memcpy to copy
> from local desc
> to global desc. What you say?

What do you mean? So you changed the use from some global variable to different 
(local) variable? This might break stuff I fear :-(

> 
> >>   	if (err<  tmp) {
> >>   	
> >>   		if (err<  0)
> >>   		
> >>   			printf("unable to get device descriptor (error=%d)\n",
> > 
> > The rest seems fine, from now on it seems to be only matter of trivial
> > fix. Thanks for your effort so far!
> > 
> > M
> 
> If rest of the code is fine in [Patch V3 1/2] except these two issue can
> it be acknowledged for up-streaming?

Well, there are those two issues which I'd really prefer to be fixed before 
accepting the code. I believe you can understand why.

Thanks!

M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 1/2] usb: align buffers at cacheline
  2012-03-01 18:38                     ` Marek Vasut
@ 2012-03-02  6:56                       ` puneets
  2012-03-02 10:43                         ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-02  6:56 UTC (permalink / raw)
  To: u-boot

Hi,
On Friday 02 March 2012 12:08 AM, Marek Vasut wrote:
>> On Thursday 01 March 2012 03:05 AM, Marek Vasut wrote:
>>>> As DMA expects the buffers to be equal and larger then
>>>> cache lines, This aligns buffers at cacheline.
>>>>
>>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>>>> ---
>>>>
>>>> Changes for V2:
>>>>       - Use "ARCH_DMA_MINALIGN" directly
>>>>       - Use "ALIGN" to align size as cacheline
>>>>       - Removed headers from usb.h
>>>>       - Send 8 bytes of device descriptor size to read
>>>>
>>>>         Max packet size
>>>>
>>>>       scsi.h header is needed to avoid extra memcpy from local buffer
>>>>       to global buffer.
>>>>
>>>> Changes for V3:
>>>>       - Removed local descriptor elements copy to global descriptor
>>>>       elements - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>" from
>>>>       commit
>>>>
>>>> message
>>>>
>>>>    common/cmd_usb.c            |    3 +-
>>>>    common/usb.c                |   57
>>>>
>>>> ++++++++++++++++++++++------------------- common/usb_storage.c        |
>>>> 59 ++++++++++++++++++++---------------------- disk/part_dos.c
>>>>
>>>> |    2 +-
>>>>
>>>>    drivers/usb/host/ehci-hcd.c |    8 ++++++
>>>>    include/scsi.h              |    4 ++-
>>>>    6 files changed, 73 insertions(+), 60 deletions(-)
>>>>
>>>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
>>>> index 320667f..bca9d94 100644
>>>> --- a/common/cmd_usb.c
>>>> +++ b/common/cmd_usb.c
>>>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
>>>> unsigned char subclass,
>>>>
>>>>    void usb_display_string(struct usb_device *dev, int index)
>>>>    {
>>>>
>>>> -	char buffer[256];
>>>> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
>>>> +
>>>>
>>>>    	if (index != 0) {
>>>>    	
>>>>    		if (usb_string(dev, index,&buffer[0], 256)>   0)
>>>>    		
>>>>    			printf("String: \"%s\"", buffer);
>>>>
>>>> diff --git a/common/usb.c b/common/usb.c
>>>> index 63a11c8..191bc5b 100644
>>>> --- a/common/usb.c
>>>> +++ b/common/usb.c
>>>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>>>>
>>>>    static int dev_index;
>>>>    static int running;
>>>>    static int asynch_allowed;
>>>>
>>>> -static struct devrequest setup_packet;
>>>>
>>>>    char usb_started; /* flag for the started/stopped USB status */
>>>>
>>>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
>>>> unsigned int pipe, unsigned short value, unsigned short index,
>>>>
>>>>    			void *data, unsigned short size, int timeout)
>>>>
>>>>    {
>>>>
>>>> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
>>>> +		sizeof(struct devrequest));
>>>>
>>>>    	if ((timeout == 0)&&   (!asynch_allowed)) {
>>>>    	
>>>>    		/* request for a asynch control pipe is not allowed */
>>>>    		return -1;
>>>>    	
>>>>    	}
>>>>    	
>>>>    	/* set setup command */
>>>>
>>>> -	setup_packet.requesttype = requesttype;
>>>> -	setup_packet.request = request;
>>>> -	setup_packet.value = cpu_to_le16(value);
>>>> -	setup_packet.index = cpu_to_le16(index);
>>>> -	setup_packet.length = cpu_to_le16(size);
>>>> +	setup_packet->requesttype = requesttype;
>>>> +	setup_packet->request = request;
>>>> +	setup_packet->value = cpu_to_le16(value);
>>>> +	setup_packet->index = cpu_to_le16(index);
>>>> +	setup_packet->length = cpu_to_le16(size);
>>>>
>>>>    	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>>>>    	
>>>>    		   "value 0x%X index 0x%X length 0x%X\n",
>>>>    		   request, requesttype, value, index, size);
>>>>    	
>>>>    	dev->status = USB_ST_NOT_PROC; /*not yet processed */
>>>>
>>>> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
>>>> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>>>>
>>>>    	if (timeout == 0)
>>>>    	
>>>>    		return (int)size;
>>>>
>>>> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev,
>>>> unsigned int langid, */
>>>>
>>>>    int usb_string(struct usb_device *dev, int index, char *buf, size_t
>>>>    size) {
>>>>
>>>> -	unsigned char mybuf[USB_BUFSIZ];
>>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>>>>
>>>>    	unsigned char *tbuf;
>>>>    	int err;
>>>>    	unsigned int u, idx;
>>>>
>>>> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
>>>>
>>>>    {
>>>>
>>>>    	int addr, err;
>>>>    	int tmp;
>>>>
>>>> -	unsigned char tmpbuf[USB_BUFSIZ];
>>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
>>>>
>>>>    	/* We still haven't set the Address yet */
>>>>    	addr = dev->devnum;
>>>>
>>>> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
>>>>
>>>>    	dev->epmaxpacketin[0] = 64;
>>>>    	dev->epmaxpacketout[0] = 64;
>>>>
>>>> -	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
>>>> +	desc->bMaxPacketSize0 = 0;
>>>> +	/*8 bytes of the descriptor to read Max packet size*/
>>>> +	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
>>>> +			8);
>>> Did some unrelated addition/change creep in here?
>> No, This is the fix for the similar issue as is discussed for string
>> fetch().
>> When the device partially fills the passed buffer and we try to
>> invalidate the partial buffer
>> the cache alignment error crops up.
>>
>> The code in "ehci_submit_async() " invalidates *partially* the passed
>> buffer though we pass aligned buffer after "STD_ASS"
>> is received. Actually it should invalidate only the cached line which is
>> equal(~32) to device desc length.
>>
>> If we pass actual device desc length the cache alignment error does not
>> spew.
>> Note that here we are aligning the buffer still the error comes.
> Then please send this fix as a separate patch. And I think ehci_hcd is what
> should be fixed then as I said in the other email, or am I wrong?
>
Yes, I will send this fix in separate patch. To address partial 
invalidate issue
will send another patch in "ehci_hcd()".
>>>>    	if (err<   0) {
>>>>    	
>>>>    		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
>>>>    		return 1;
>>>>
>>>> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
>>>>
>>>>    	tmp = sizeof(dev->descriptor);
>>>>    	
>>>>    	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
>>>>
>>>> -				&dev->descriptor, sizeof(dev->descriptor));
>>>> +				 desc, sizeof(dev->descriptor));
>>> Won't this change (desc) break anything?
>> Its not breaking any thing. For safer side we could add memcpy to copy
>> from local desc
>> to global desc. What you say?
> What do you mean? So you changed the use from some global variable to different
> (local) variable? This might break stuff I fear :-(
>
Actually in previous comments  it was said to not cache align  "struct 
usb_device_descriptor descriptor; /* Device Descriptor */ Line:112
usb.h, in header file. So another way is to define cache aligned local 
variable and pass it to "usb_get_descriptor". After returning from
"usb_get_descriptor",  memcpy this buffer to global variable 
"dev->descriptor".
I verified the devices, usb mouse, mass-storage etc... that without this 
memcpy to global variable, its not breaking anything.
That's why I avoided memcpy.
>>>>    	if (err<   tmp) {
>>>>    	
>>>>    		if (err<   0)
>>>>    		
>>>>    			printf("unable to get device descriptor (error=%d)\n",
>>> The rest seems fine, from now on it seems to be only matter of trivial
>>> fix. Thanks for your effort so far!
>>>
>>> M
>> If rest of the code is fine in [Patch V3 1/2] except these two issue can
>> it be acknowledged for up-streaming?
> Well, there are those two issues which I'd really prefer to be fixed before
> accepting the code. I believe you can understand why.
>
> Thanks!
>
> M
Thanx,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 1/2] usb: align buffers at cacheline
  2012-03-02  6:56                       ` puneets
@ 2012-03-02 10:43                         ` Marek Vasut
  2012-03-02 12:50                           ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-02 10:43 UTC (permalink / raw)
  To: u-boot

> Hi,
> 
> On Friday 02 March 2012 12:08 AM, Marek Vasut wrote:
> >> On Thursday 01 March 2012 03:05 AM, Marek Vasut wrote:
> >>>> As DMA expects the buffers to be equal and larger then
> >>>> cache lines, This aligns buffers at cacheline.
> >>>> 
> >>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >>>> ---
> >>>> 
> >>>> Changes for V2:
> >>>>       - Use "ARCH_DMA_MINALIGN" directly
> >>>>       - Use "ALIGN" to align size as cacheline
> >>>>       - Removed headers from usb.h
> >>>>       - Send 8 bytes of device descriptor size to read
> >>>>       
> >>>>         Max packet size
> >>>>       
> >>>>       scsi.h header is needed to avoid extra memcpy from local buffer
> >>>>       to global buffer.
> >>>> 
> >>>> Changes for V3:
> >>>>       - Removed local descriptor elements copy to global descriptor
> >>>>       elements - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>"
> >>>>       from commit
> >>>> 
> >>>> message
> >>>> 
> >>>>    common/cmd_usb.c            |    3 +-
> >>>>    common/usb.c                |   57
> >>>> 
> >>>> ++++++++++++++++++++++------------------- common/usb_storage.c       
> >>>> | 59 ++++++++++++++++++++---------------------- disk/part_dos.c
> >>>> 
> >>>> |    2 +-
> >>>>    
> >>>>    drivers/usb/host/ehci-hcd.c |    8 ++++++
> >>>>    include/scsi.h              |    4 ++-
> >>>>    6 files changed, 73 insertions(+), 60 deletions(-)
> >>>> 
> >>>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> >>>> index 320667f..bca9d94 100644
> >>>> --- a/common/cmd_usb.c
> >>>> +++ b/common/cmd_usb.c
> >>>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> >>>> unsigned char subclass,
> >>>> 
> >>>>    void usb_display_string(struct usb_device *dev, int index)
> >>>>    {
> >>>> 
> >>>> -	char buffer[256];
> >>>> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> >>>> +
> >>>> 
> >>>>    	if (index != 0) {
> >>>>    	
> >>>>    		if (usb_string(dev, index,&buffer[0], 256)>   0)
> >>>>    		
> >>>>    			printf("String: \"%s\"", buffer);
> >>>> 
> >>>> diff --git a/common/usb.c b/common/usb.c
> >>>> index 63a11c8..191bc5b 100644
> >>>> --- a/common/usb.c
> >>>> +++ b/common/usb.c
> >>>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
> >>>> 
> >>>>    static int dev_index;
> >>>>    static int running;
> >>>>    static int asynch_allowed;
> >>>> 
> >>>> -static struct devrequest setup_packet;
> >>>> 
> >>>>    char usb_started; /* flag for the started/stopped USB status */
> >>>> 
> >>>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
> >>>> unsigned int pipe, unsigned short value, unsigned short index,
> >>>> 
> >>>>    			void *data, unsigned short size, int timeout)
> >>>>    
> >>>>    {
> >>>> 
> >>>> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> >>>> +		sizeof(struct devrequest));
> >>>> 
> >>>>    	if ((timeout == 0)&&   (!asynch_allowed)) {
> >>>>    	
> >>>>    		/* request for a asynch control pipe is not allowed */
> >>>>    		return -1;
> >>>>    	
> >>>>    	}
> >>>>    	
> >>>>    	/* set setup command */
> >>>> 
> >>>> -	setup_packet.requesttype = requesttype;
> >>>> -	setup_packet.request = request;
> >>>> -	setup_packet.value = cpu_to_le16(value);
> >>>> -	setup_packet.index = cpu_to_le16(index);
> >>>> -	setup_packet.length = cpu_to_le16(size);
> >>>> +	setup_packet->requesttype = requesttype;
> >>>> +	setup_packet->request = request;
> >>>> +	setup_packet->value = cpu_to_le16(value);
> >>>> +	setup_packet->index = cpu_to_le16(index);
> >>>> +	setup_packet->length = cpu_to_le16(size);
> >>>> 
> >>>>    	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " 
\
> >>>>    	
> >>>>    		   "value 0x%X index 0x%X length 0x%X\n",
> >>>>    		   request, requesttype, value, index, size);
> >>>>    	
> >>>>    	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> >>>> 
> >>>> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
> >>>> +	submit_control_msg(dev, pipe, data, size, setup_packet);
> >>>> 
> >>>>    	if (timeout == 0)
> >>>>    	
> >>>>    		return (int)size;
> >>>> 
> >>>> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev,
> >>>> unsigned int langid, */
> >>>> 
> >>>>    int usb_string(struct usb_device *dev, int index, char *buf, size_t
> >>>>    size) {
> >>>> 
> >>>> -	unsigned char mybuf[USB_BUFSIZ];
> >>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
> >>>> 
> >>>>    	unsigned char *tbuf;
> >>>>    	int err;
> >>>>    	unsigned int u, idx;
> >>>> 
> >>>> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
> >>>> 
> >>>>    {
> >>>>    
> >>>>    	int addr, err;
> >>>>    	int tmp;
> >>>> 
> >>>> -	unsigned char tmpbuf[USB_BUFSIZ];
> >>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> >>>> 
> >>>>    	/* We still haven't set the Address yet */
> >>>>    	addr = dev->devnum;
> >>>> 
> >>>> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
> >>>> 
> >>>>    	dev->epmaxpacketin[0] = 64;
> >>>>    	dev->epmaxpacketout[0] = 64;
> >>>> 
> >>>> -	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
> >>>> +	desc->bMaxPacketSize0 = 0;
> >>>> +	/*8 bytes of the descriptor to read Max packet size*/
> >>>> +	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
> >>>> +			8);
> >>> 
> >>> Did some unrelated addition/change creep in here?
> >> 
> >> No, This is the fix for the similar issue as is discussed for string
> >> fetch().
> >> When the device partially fills the passed buffer and we try to
> >> invalidate the partial buffer
> >> the cache alignment error crops up.
> >> 
> >> The code in "ehci_submit_async() " invalidates *partially* the passed
> >> buffer though we pass aligned buffer after "STD_ASS"
> >> is received. Actually it should invalidate only the cached line which is
> >> equal(~32) to device desc length.
> >> 
> >> If we pass actual device desc length the cache alignment error does not
> >> spew.
> >> Note that here we are aligning the buffer still the error comes.
> > 
> > Then please send this fix as a separate patch. And I think ehci_hcd is
> > what should be fixed then as I said in the other email, or am I wrong?
> 
> Yes, I will send this fix in separate patch. To address partial
> invalidate issue
> will send another patch in "ehci_hcd()".

Very good! I'm really glad we're working towards the proper solution, thanks for 
all the effort you put into it!
> 
> >>>>    	if (err<   0) {
> >>>>    	
> >>>>    		USB_PRINTF("usb_new_device: usb_get_descriptor() 
failed\n");
> >>>>    		return 1;
> >>>> 
> >>>> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
> >>>> 
> >>>>    	tmp = sizeof(dev->descriptor);
> >>>>    	
> >>>>    	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
> >>>> 
> >>>> -				&dev->descriptor, sizeof(dev-
>descriptor));
> >>>> +				 desc, sizeof(dev->descriptor));
> >>> 
> >>> Won't this change (desc) break anything?
> >> 
> >> Its not breaking any thing. For safer side we could add memcpy to copy
> >> from local desc
> >> to global desc. What you say?
> > 
> > What do you mean? So you changed the use from some global variable to
> > different (local) variable? This might break stuff I fear :-(
> 
> Actually in previous comments  it was said to not cache align  "struct
> usb_device_descriptor descriptor; /* Device Descriptor */ Line:112
> usb.h, in header file. So another way is to define cache aligned local
> variable and pass it to "usb_get_descriptor". After returning from
> "usb_get_descriptor",  memcpy this buffer to global variable
> "dev->descriptor".
> I verified the devices, usb mouse, mass-storage etc... that without this
> memcpy to global variable, its not breaking anything.
> That's why I avoided memcpy.

Oh ... maybe the global variable is unneeded at all and using the local only is 
OK?

> 
> >>>>    	if (err<   tmp) {
> >>>>    	
> >>>>    		if (err<   0)
> >>>>    		
> >>>>    			printf("unable to get device descriptor 
(error=%d)\n",
> >>> 
> >>> The rest seems fine, from now on it seems to be only matter of trivial
> >>> fix. Thanks for your effort so far!
> >>> 
> >>> M
> >> 
> >> If rest of the code is fine in [Patch V3 1/2] except these two issue can
> >> it be acknowledged for up-streaming?
> > 
> > Well, there are those two issues which I'd really prefer to be fixed
> > before accepting the code. I believe you can understand why.
> > 
> > Thanks!
> > 
> > M
> 
> Thanx,
> Puneet

No, thank you !

M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 1/2] usb: align buffers at cacheline
  2012-03-02 10:43                         ` Marek Vasut
@ 2012-03-02 12:50                           ` puneets
  2012-03-02 12:58                             ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-02 12:50 UTC (permalink / raw)
  To: u-boot

Hi,
On Friday 02 March 2012 04:13 PM, Marek Vasut wrote:
>> Hi,
>>
>> On Friday 02 March 2012 12:08 AM, Marek Vasut wrote:
>>>> On Thursday 01 March 2012 03:05 AM, Marek Vasut wrote:
>>>>>> As DMA expects the buffers to be equal and larger then
>>>>>> cache lines, This aligns buffers at cacheline.
>>>>>>
>>>>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>>>>>> ---
>>>>>>
>>>>>> Changes for V2:
>>>>>>        - Use "ARCH_DMA_MINALIGN" directly
>>>>>>        - Use "ALIGN" to align size as cacheline
>>>>>>        - Removed headers from usb.h
>>>>>>        - Send 8 bytes of device descriptor size to read
>>>>>>
>>>>>>          Max packet size
>>>>>>
>>>>>>        scsi.h header is needed to avoid extra memcpy from local buffer
>>>>>>        to global buffer.
>>>>>>
>>>>>> Changes for V3:
>>>>>>        - Removed local descriptor elements copy to global descriptor
>>>>>>        elements - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>"
>>>>>>        from commit
>>>>>>
>>>>>> message
>>>>>>
>>>>>>     common/cmd_usb.c            |    3 +-
>>>>>>     common/usb.c                |   57
>>>>>>
>>>>>> ++++++++++++++++++++++------------------- common/usb_storage.c
>>>>>> | 59 ++++++++++++++++++++---------------------- disk/part_dos.c
>>>>>>
>>>>>> |    2 +-
>>>>>>
>>>>>>     drivers/usb/host/ehci-hcd.c |    8 ++++++
>>>>>>     include/scsi.h              |    4 ++-
>>>>>>     6 files changed, 73 insertions(+), 60 deletions(-)
>>>>>>
>>>>>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
>>>>>> index 320667f..bca9d94 100644
>>>>>> --- a/common/cmd_usb.c
>>>>>> +++ b/common/cmd_usb.c
>>>>>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
>>>>>> unsigned char subclass,
>>>>>>
>>>>>>     void usb_display_string(struct usb_device *dev, int index)
>>>>>>     {
>>>>>>
>>>>>> -	char buffer[256];
>>>>>> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
>>>>>> +
>>>>>>
>>>>>>     	if (index != 0) {
>>>>>>     	
>>>>>>     		if (usb_string(dev, index,&buffer[0], 256)>    0)
>>>>>>     		
>>>>>>     			printf("String: \"%s\"", buffer);
>>>>>>
>>>>>> diff --git a/common/usb.c b/common/usb.c
>>>>>> index 63a11c8..191bc5b 100644
>>>>>> --- a/common/usb.c
>>>>>> +++ b/common/usb.c
>>>>>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>>>>>>
>>>>>>     static int dev_index;
>>>>>>     static int running;
>>>>>>     static int asynch_allowed;
>>>>>>
>>>>>> -static struct devrequest setup_packet;
>>>>>>
>>>>>>     char usb_started; /* flag for the started/stopped USB status */
>>>>>>
>>>>>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
>>>>>> unsigned int pipe, unsigned short value, unsigned short index,
>>>>>>
>>>>>>     			void *data, unsigned short size, int timeout)
>>>>>>
>>>>>>     {
>>>>>>
>>>>>> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
>>>>>> +		sizeof(struct devrequest));
>>>>>>
>>>>>>     	if ((timeout == 0)&&    (!asynch_allowed)) {
>>>>>>     	
>>>>>>     		/* request for a asynch control pipe is not allowed */
>>>>>>     		return -1;
>>>>>>     	
>>>>>>     	}
>>>>>>     	
>>>>>>     	/* set setup command */
>>>>>>
>>>>>> -	setup_packet.requesttype = requesttype;
>>>>>> -	setup_packet.request = request;
>>>>>> -	setup_packet.value = cpu_to_le16(value);
>>>>>> -	setup_packet.index = cpu_to_le16(index);
>>>>>> -	setup_packet.length = cpu_to_le16(size);
>>>>>> +	setup_packet->requesttype = requesttype;
>>>>>> +	setup_packet->request = request;
>>>>>> +	setup_packet->value = cpu_to_le16(value);
>>>>>> +	setup_packet->index = cpu_to_le16(index);
>>>>>> +	setup_packet->length = cpu_to_le16(size);
>>>>>>
>>>>>>     	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, "
> \
>>>>>>     	
>>>>>>     		"value 0x%X index 0x%X length 0x%X\n",
>>>>>>     		   request, requesttype, value, index, size);
>>>>>>     	
>>>>>>     	dev->status = USB_ST_NOT_PROC; /*not yet processed */
>>>>>>
>>>>>> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
>>>>>> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>>>>>>
>>>>>>     	if (timeout == 0)
>>>>>>     	
>>>>>>     		return (int)size;
>>>>>>
>>>>>> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device *dev,
>>>>>> unsigned int langid, */
>>>>>>
>>>>>>     int usb_string(struct usb_device *dev, int index, char *buf, size_t
>>>>>>     size) {
>>>>>>
>>>>>> -	unsigned char mybuf[USB_BUFSIZ];
>>>>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>>>>>>
>>>>>>     	unsigned char *tbuf;
>>>>>>     	int err;
>>>>>>     	unsigned int u, idx;
>>>>>>
>>>>>> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
>>>>>>
>>>>>>     {
>>>>>>
>>>>>>     	int addr, err;
>>>>>>     	int tmp;
>>>>>>
>>>>>> -	unsigned char tmpbuf[USB_BUFSIZ];
>>>>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
>>>>>>
>>>>>>     	/* We still haven't set the Address yet */
>>>>>>     	addr = dev->devnum;
>>>>>>
>>>>>> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
>>>>>>
>>>>>>     	dev->epmaxpacketin[0] = 64;
>>>>>>     	dev->epmaxpacketout[0] = 64;
>>>>>>
>>>>>> -	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
>>>>>> +	desc->bMaxPacketSize0 = 0;
>>>>>> +	/*8 bytes of the descriptor to read Max packet size*/
>>>>>> +	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
>>>>>> +			8);
>>>>> Did some unrelated addition/change creep in here?
>>>> No, This is the fix for the similar issue as is discussed for string
>>>> fetch().
>>>> When the device partially fills the passed buffer and we try to
>>>> invalidate the partial buffer
>>>> the cache alignment error crops up.
>>>>
>>>> The code in "ehci_submit_async() " invalidates *partially* the passed
>>>> buffer though we pass aligned buffer after "STD_ASS"
>>>> is received. Actually it should invalidate only the cached line which is
>>>> equal(~32) to device desc length.
>>>>
>>>> If we pass actual device desc length the cache alignment error does not
>>>> spew.
>>>> Note that here we are aligning the buffer still the error comes.
>>> Then please send this fix as a separate patch. And I think ehci_hcd is
>>> what should be fixed then as I said in the other email, or am I wrong?
>> Yes, I will send this fix in separate patch. To address partial
>> invalidate issue
>> will send another patch in "ehci_hcd()".
> Very good! I'm really glad we're working towards the proper solution, thanks for
> all the effort you put into it!
>>>>>>     	if (err<    0) {
>>>>>>     	
>>>>>>     		USB_PRINTF("usb_new_device: usb_get_descriptor()
> failed\n");
>>>>>>     		return 1;
>>>>>>
>>>>>> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
>>>>>>
>>>>>>     	tmp = sizeof(dev->descriptor);
>>>>>>     	
>>>>>>     	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
>>>>>>
>>>>>> -				&dev->descriptor, sizeof(dev-
>> descriptor));
>>>>>> +				 desc, sizeof(dev->descriptor));
>>>>> Won't this change (desc) break anything?
>>>> Its not breaking any thing. For safer side we could add memcpy to copy
>>>> from local desc
>>>> to global desc. What you say?
>>> What do you mean? So you changed the use from some global variable to
>>> different (local) variable? This might break stuff I fear :-(
>> Actually in previous comments  it was said to not cache align  "struct
>> usb_device_descriptor descriptor; /* Device Descriptor */ Line:112
>> usb.h, in header file. So another way is to define cache aligned local
>> variable and pass it to "usb_get_descriptor". After returning from
>> "usb_get_descriptor",  memcpy this buffer to global variable
>> "dev->descriptor".
>> I verified the devices, usb mouse, mass-storage etc... that without this
>> memcpy to global variable, its not breaking anything.
>> That's why I avoided memcpy.
> Oh ... maybe the global variable is unneeded at all and using the local only is
> OK?
>
Investigated further and found that "memcpy" is needed to configure Usb 
version, vendor id, prod Id ..etc
of the device. Its also useful to hook actual device driver and detect 
no. of configuration supported.

I strongly feel we could avoid "memcpy" by making global device desc in 
usb.h Line:112, cache align as done in
scsi.h,Line:30 in this patch and this is accepted also?
>>>>>>     	if (err<    tmp) {
>>>>>>     	
>>>>>>     		if (err<    0)
>>>>>>     		
>>>>>>     			printf("unable to get device descriptor
> (error=%d)\n",
>>>>> The rest seems fine, from now on it seems to be only matter of trivial
>>>>> fix. Thanks for your effort so far!
>>>>>
>>>>> M
>>>> If rest of the code is fine in [Patch V3 1/2] except these two issue can
>>>> it be acknowledged for up-streaming?
>>> Well, there are those two issues which I'd really prefer to be fixed
>>> before accepting the code. I believe you can understand why.
>>>
>>> Thanks!
>>>
>>> M
>> Thanx,
>> Puneet
> No, thank you !
>
> M
Thanx,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 1/2] usb: align buffers at cacheline
  2012-03-02 12:50                           ` puneets
@ 2012-03-02 12:58                             ` Marek Vasut
  2012-03-02 13:35                               ` [U-Boot] [PATCH v4] " Puneet Saxena
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-02 12:58 UTC (permalink / raw)
  To: u-boot

> Hi,
> 
> On Friday 02 March 2012 04:13 PM, Marek Vasut wrote:
> >> Hi,
> >> 
> >> On Friday 02 March 2012 12:08 AM, Marek Vasut wrote:
> >>>> On Thursday 01 March 2012 03:05 AM, Marek Vasut wrote:
> >>>>>> As DMA expects the buffers to be equal and larger then
> >>>>>> cache lines, This aligns buffers at cacheline.
> >>>>>> 
> >>>>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >>>>>> ---
> >>>>>> 
> >>>>>> Changes for V2:
> >>>>>>        - Use "ARCH_DMA_MINALIGN" directly
> >>>>>>        - Use "ALIGN" to align size as cacheline
> >>>>>>        - Removed headers from usb.h
> >>>>>>        - Send 8 bytes of device descriptor size to read
> >>>>>>        
> >>>>>>          Max packet size
> >>>>>>        
> >>>>>>        scsi.h header is needed to avoid extra memcpy from local
> >>>>>>        buffer to global buffer.
> >>>>>> 
> >>>>>> Changes for V3:
> >>>>>>        - Removed local descriptor elements copy to global descriptor
> >>>>>>        elements - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>"
> >>>>>>        from commit
> >>>>>> 
> >>>>>> message
> >>>>>> 
> >>>>>>     common/cmd_usb.c            |    3 +-
> >>>>>>     common/usb.c                |   57
> >>>>>> 
> >>>>>> ++++++++++++++++++++++------------------- common/usb_storage.c
> >>>>>> 
> >>>>>> | 59 ++++++++++++++++++++---------------------- disk/part_dos.c
> >>>>>> | 
> >>>>>> |    2 +-
> >>>>>>     
> >>>>>>     drivers/usb/host/ehci-hcd.c |    8 ++++++
> >>>>>>     include/scsi.h              |    4 ++-
> >>>>>>     6 files changed, 73 insertions(+), 60 deletions(-)
> >>>>>> 
> >>>>>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> >>>>>> index 320667f..bca9d94 100644
> >>>>>> --- a/common/cmd_usb.c
> >>>>>> +++ b/common/cmd_usb.c
> >>>>>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> >>>>>> unsigned char subclass,
> >>>>>> 
> >>>>>>     void usb_display_string(struct usb_device *dev, int index)
> >>>>>>     {
> >>>>>> 
> >>>>>> -	char buffer[256];
> >>>>>> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> >>>>>> +
> >>>>>> 
> >>>>>>     	if (index != 0) {
> >>>>>>     	
> >>>>>>     		if (usb_string(dev, index,&buffer[0], 256)>    0)
> >>>>>>     		
> >>>>>>     			printf("String: \"%s\"", buffer);
> >>>>>> 
> >>>>>> diff --git a/common/usb.c b/common/usb.c
> >>>>>> index 63a11c8..191bc5b 100644
> >>>>>> --- a/common/usb.c
> >>>>>> +++ b/common/usb.c
> >>>>>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
> >>>>>> 
> >>>>>>     static int dev_index;
> >>>>>>     static int running;
> >>>>>>     static int asynch_allowed;
> >>>>>> 
> >>>>>> -static struct devrequest setup_packet;
> >>>>>> 
> >>>>>>     char usb_started; /* flag for the started/stopped USB status */
> >>>>>> 
> >>>>>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
> >>>>>> unsigned int pipe, unsigned short value, unsigned short index,
> >>>>>> 
> >>>>>>     			void *data, unsigned short size, int timeout)
> >>>>>>     
> >>>>>>     {
> >>>>>> 
> >>>>>> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> >>>>>> +		sizeof(struct devrequest));
> >>>>>> 
> >>>>>>     	if ((timeout == 0)&&    (!asynch_allowed)) {
> >>>>>>     	
> >>>>>>     		/* request for a asynch control pipe is not allowed */
> >>>>>>     		return -1;
> >>>>>>     	
> >>>>>>     	}
> >>>>>>     	
> >>>>>>     	/* set setup command */
> >>>>>> 
> >>>>>> -	setup_packet.requesttype = requesttype;
> >>>>>> -	setup_packet.request = request;
> >>>>>> -	setup_packet.value = cpu_to_le16(value);
> >>>>>> -	setup_packet.index = cpu_to_le16(index);
> >>>>>> -	setup_packet.length = cpu_to_le16(size);
> >>>>>> +	setup_packet->requesttype = requesttype;
> >>>>>> +	setup_packet->request = request;
> >>>>>> +	setup_packet->value = cpu_to_le16(value);
> >>>>>> +	setup_packet->index = cpu_to_le16(index);
> >>>>>> +	setup_packet->length = cpu_to_le16(size);
> >>>>>> 
> >>>>>>     	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X,
> >>>>>>     	"
> > 
> > \
> > 
> >>>>>>     		"value 0x%X index 0x%X length 0x%X\n",
> >>>>>>     		
> >>>>>>     		   request, requesttype, value, index, size);
> >>>>>>     	
> >>>>>>     	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> >>>>>> 
> >>>>>> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
> >>>>>> +	submit_control_msg(dev, pipe, data, size, setup_packet);
> >>>>>> 
> >>>>>>     	if (timeout == 0)
> >>>>>>     	
> >>>>>>     		return (int)size;
> >>>>>> 
> >>>>>> @@ -694,7 +695,7 @@ static int usb_string_sub(struct usb_device
> >>>>>> *dev, unsigned int langid, */
> >>>>>> 
> >>>>>>     int usb_string(struct usb_device *dev, int index, char *buf,
> >>>>>>     size_t size) {
> >>>>>> 
> >>>>>> -	unsigned char mybuf[USB_BUFSIZ];
> >>>>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
> >>>>>> 
> >>>>>>     	unsigned char *tbuf;
> >>>>>>     	int err;
> >>>>>>     	unsigned int u, idx;
> >>>>>> 
> >>>>>> @@ -794,7 +795,7 @@ int usb_new_device(struct usb_device *dev)
> >>>>>> 
> >>>>>>     {
> >>>>>>     
> >>>>>>     	int addr, err;
> >>>>>>     	int tmp;
> >>>>>> 
> >>>>>> -	unsigned char tmpbuf[USB_BUFSIZ];
> >>>>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> >>>>>> 
> >>>>>>     	/* We still haven't set the Address yet */
> >>>>>>     	addr = dev->devnum;
> >>>>>> 
> >>>>>> @@ -842,7 +843,10 @@ int usb_new_device(struct usb_device *dev)
> >>>>>> 
> >>>>>>     	dev->epmaxpacketin[0] = 64;
> >>>>>>     	dev->epmaxpacketout[0] = 64;
> >>>>>> 
> >>>>>> -	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
> >>>>>> +	desc->bMaxPacketSize0 = 0;
> >>>>>> +	/*8 bytes of the descriptor to read Max packet size*/
> >>>>>> +	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc,
> >>>>>> +			8);
> >>>>> 
> >>>>> Did some unrelated addition/change creep in here?
> >>>> 
> >>>> No, This is the fix for the similar issue as is discussed for string
> >>>> fetch().
> >>>> When the device partially fills the passed buffer and we try to
> >>>> invalidate the partial buffer
> >>>> the cache alignment error crops up.
> >>>> 
> >>>> The code in "ehci_submit_async() " invalidates *partially* the passed
> >>>> buffer though we pass aligned buffer after "STD_ASS"
> >>>> is received. Actually it should invalidate only the cached line which
> >>>> is equal(~32) to device desc length.
> >>>> 
> >>>> If we pass actual device desc length the cache alignment error does
> >>>> not spew.
> >>>> Note that here we are aligning the buffer still the error comes.
> >>> 
> >>> Then please send this fix as a separate patch. And I think ehci_hcd is
> >>> what should be fixed then as I said in the other email, or am I wrong?
> >> 
> >> Yes, I will send this fix in separate patch. To address partial
> >> invalidate issue
> >> will send another patch in "ehci_hcd()".
> > 
> > Very good! I'm really glad we're working towards the proper solution,
> > thanks for all the effort you put into it!
> > 
> >>>>>>     	if (err<    0) {
> >>>>>>     	
> >>>>>>     		USB_PRINTF("usb_new_device: usb_get_descriptor()
> > 
> > failed\n");
> > 
> >>>>>>     		return 1;
> >>>>>> 
> >>>>>> @@ -905,7 +909,7 @@ int usb_new_device(struct usb_device *dev)
> >>>>>> 
> >>>>>>     	tmp = sizeof(dev->descriptor);
> >>>>>>     	
> >>>>>>     	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
> >>>>>> 
> >>>>>> -				&dev->descriptor, sizeof(dev-
> >> 
> >> descriptor));
> >> 
> >>>>>> +				 desc, sizeof(dev->descriptor));
> >>>>> 
> >>>>> Won't this change (desc) break anything?
> >>>> 
> >>>> Its not breaking any thing. For safer side we could add memcpy to copy
> >>>> from local desc
> >>>> to global desc. What you say?
> >>> 
> >>> What do you mean? So you changed the use from some global variable to
> >>> different (local) variable? This might break stuff I fear :-(
> >> 
> >> Actually in previous comments  it was said to not cache align  "struct
> >> usb_device_descriptor descriptor; /* Device Descriptor */ Line:112
> >> usb.h, in header file. So another way is to define cache aligned local
> >> variable and pass it to "usb_get_descriptor". After returning from
> >> "usb_get_descriptor",  memcpy this buffer to global variable
> >> "dev->descriptor".
> >> I verified the devices, usb mouse, mass-storage etc... that without this
> >> memcpy to global variable, its not breaking anything.
> >> That's why I avoided memcpy.
> > 
> > Oh ... maybe the global variable is unneeded at all and using the local
> > only is OK?
> 
> Investigated further and found that "memcpy" is needed to configure Usb
> version, vendor id, prod Id ..etc
> of the device. Its also useful to hook actual device driver and detect
> no. of configuration supported.
> 
> I strongly feel we could avoid "memcpy" by making global device desc in
> usb.h Line:112, cache align as done in
> scsi.h,Line:30 in this patch and this is accepted also?

We try to make as many things local as possible.

M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-02 12:58                             ` Marek Vasut
@ 2012-03-02 13:35                               ` Puneet Saxena
  2012-03-02 13:46                                 ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-03-02 13:35 UTC (permalink / raw)
  To: u-boot

As DMA expects the buffers to be equal and larger then
cache lines, This aligns buffers at cacheline.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---

Changes for V3:
    - Removed local descriptor elements copy to global descriptor elements
    - Removed "Signed-off-by: Jim Lin <jilin@nvidia.com>" from commit message

Changes for V4:
    - Added memcpy to copy local descriptor to global descriptor.
      Without that, USB version, class, vendor, product Id...etc is not configured.
      This information is useful for loading correct device driver and possible 
      configuration.  


 common/cmd_usb.c            |    3 +-
 common/usb.c                |   56 ++++++++++++++++++++++------------------
 common/usb_storage.c        |   59 ++++++++++++++++++++----------------------
 disk/part_dos.c             |    2 +-
 drivers/usb/host/ehci-hcd.c |    8 ++++++
 include/scsi.h              |    4 ++-
 6 files changed, 73 insertions(+), 59 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 6e21ae2..42a44e2 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
+		sizeof(struct devrequest));
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
 		   "value 0x%X index 0x%X length 0x%X\n",
 		   request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	submit_control_msg(dev, pipe, data, size, setup_packet);
 	if (timeout == 0)
 		return (int)size;
 
@@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -909,7 +910,7 @@ int usb_new_device(struct usb_device *dev)
 	tmp = sizeof(dev->descriptor);
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-				 &dev->descriptor, sizeof(dev->descriptor));
+				 desc, sizeof(dev->descriptor));
 	if (err < tmp) {
 		if (err < 0)
 			printf("unable to get device descriptor (error=%d)\n",
@@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
 				"(expected %i, got %i)\n", tmp, err);
 		return 1;
 	}
+
+	/* Now copy the local device descriptor to global device descriptor*/
+	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));
+
 	/* correct le values */
 	le16_to_cpus(&dev->descriptor.bcdUSB);
 	le16_to_cpus(&dev->descriptor.idVendor);
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1080,7 +1085,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1089,13 +1094,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1133,19 +1138,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1194,7 +1199,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1316,16 +1322,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..88ca390 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
 
 /*
  * CBI style
@@ -210,17 +209,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
 		printf("       scanning bus for storage devices... ");
 
@@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +729,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +749,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +778,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
@@ -1367,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], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	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);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
diff --git a/disk/part_dos.c b/disk/part_dos.c
index b5bcb37..70211ee 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
-	unsigned char buffer[dev_desc->blksz];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..eb5220b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,6 +120,14 @@ static struct descriptor {
  */
 static void flush_invalidate(u32 addr, int size, int flush)
 {
+	/*
+	 * Size is the bytes actually moved during transaction,
+	 * which may not equal to the cache line. This results
+	 * stop address passed for invalidating cache may not be aligned.
+	 * Therfore making size as multiple of cache line size.
+	 */
+	size = ALIGN(size, ARCH_DMA_MINALIGN);
+
 	if (flush)
 		flush_dcache_range(addr, addr + size);
 	else
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..89ae45f 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,9 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-02 13:35                               ` [U-Boot] [PATCH v4] " Puneet Saxena
@ 2012-03-02 13:46                                 ` Marek Vasut
  2012-03-02 14:00                                   ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-02 13:46 UTC (permalink / raw)
  To: u-boot

> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> ---
> 
> Changes for V3:
>     - Removed local descriptor elements copy to global descriptor elements
>     - Removed "Signed-off-by: Jim Lin <jilin@nvidia.com>" from commit
> message
> 
> Changes for V4:
>     - Added memcpy to copy local descriptor to global descriptor.
>       Without that, USB version, class, vendor, product Id...etc is not
> configured. This information is useful for loading correct device driver
> and possible configuration.
> 
> 
>  common/cmd_usb.c            |    3 +-
>  common/usb.c                |   56
> ++++++++++++++++++++++------------------ common/usb_storage.c        |  
> 59 ++++++++++++++++++++---------------------- disk/part_dos.c            
> |    2 +-
>  drivers/usb/host/ehci-hcd.c |    8 ++++++
>  include/scsi.h              |    4 ++-
>  6 files changed, 73 insertions(+), 59 deletions(-)
> 
> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> index 320667f..bca9d94 100644
> --- a/common/cmd_usb.c
> +++ b/common/cmd_usb.c
> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> unsigned char subclass,
> 
>  void usb_display_string(struct usb_device *dev, int index)
>  {
> -	char buffer[256];
> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> +
>  	if (index != 0) {
>  		if (usb_string(dev, index, &buffer[0], 256) > 0)
>  			printf("String: \"%s\"", buffer);
> diff --git a/common/usb.c b/common/usb.c
> index 6e21ae2..42a44e2 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>  static int dev_index;
>  static int running;
>  static int asynch_allowed;
> -static struct devrequest setup_packet;
> 
>  char usb_started; /* flag for the started/stopped USB status */
> 
> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned
> int pipe, unsigned short value, unsigned short index,
>  			void *data, unsigned short size, int timeout)
>  {
> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> +		sizeof(struct devrequest));
>  	if ((timeout == 0) && (!asynch_allowed)) {
>  		/* request for a asynch control pipe is not allowed */
>  		return -1;
>  	}
> 
>  	/* set setup command */
> -	setup_packet.requesttype = requesttype;
> -	setup_packet.request = request;
> -	setup_packet.value = cpu_to_le16(value);
> -	setup_packet.index = cpu_to_le16(index);
> -	setup_packet.length = cpu_to_le16(size);
> +	setup_packet->requesttype = requesttype;
> +	setup_packet->request = request;
> +	setup_packet->value = cpu_to_le16(value);
> +	setup_packet->index = cpu_to_le16(index);
> +	setup_packet->length = cpu_to_le16(size);
>  	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>  		   "value 0x%X index 0x%X length 0x%X\n",
>  		   request, requesttype, value, index, size);
>  	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> 
> -	submit_control_msg(dev, pipe, data, size, &setup_packet);
> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>  	if (timeout == 0)
>  		return (int)size;
> 
> @@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev,
> unsigned int langid, */
>  int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>  {
> -	unsigned char mybuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>  	unsigned char *tbuf;
>  	int err;
>  	unsigned int u, idx;
> @@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
>  {
>  	int addr, err;
>  	int tmp;
> -	unsigned char tmpbuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> 
>  	/* We still haven't set the Address yet */
>  	addr = dev->devnum;
> @@ -909,7 +910,7 @@ int usb_new_device(struct usb_device *dev)
>  	tmp = sizeof(dev->descriptor);
> 
>  	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
> -				 &dev->descriptor, sizeof(dev->descriptor));
> +				 desc, sizeof(dev->descriptor));
>  	if (err < tmp) {
>  		if (err < 0)
>  			printf("unable to get device descriptor (error=%d)\n",
> @@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
>  				"(expected %i, got %i)\n", tmp, err);
>  		return 1;
>  	}
> +
> +	/* Now copy the local device descriptor to global device descriptor*/
> +	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));

Hey, it's almost perfect!

Just one last question -- why do you need to copy this stuff? It's because dev-
>descriptor is unaligned?

M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-02 13:46                                 ` Marek Vasut
@ 2012-03-02 14:00                                   ` puneets
  2012-03-02 14:41                                     ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-02 14:00 UTC (permalink / raw)
  To: u-boot

On Friday 02 March 2012 07:16 PM, Marek Vasut wrote:
>> As DMA expects the buffers to be equal and larger then
>> cache lines, This aligns buffers at cacheline.
>>
>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>> ---
>>
>> Changes for V3:
>>      - Removed local descriptor elements copy to global descriptor elements
>>      - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>" from commit
>> message
>>
>> Changes for V4:
>>      - Added memcpy to copy local descriptor to global descriptor.
>>        Without that, USB version, class, vendor, product Id...etc is not
>> configured. This information is useful for loading correct device driver
>> and possible configuration.
>>
>>
>>   common/cmd_usb.c            |    3 +-
>>   common/usb.c                |   56
>> ++++++++++++++++++++++------------------ common/usb_storage.c        |
>> 59 ++++++++++++++++++++---------------------- disk/part_dos.c
>> |    2 +-
>>   drivers/usb/host/ehci-hcd.c |    8 ++++++
>>   include/scsi.h              |    4 ++-
>>   6 files changed, 73 insertions(+), 59 deletions(-)
>>
>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
>> index 320667f..bca9d94 100644
>> --- a/common/cmd_usb.c
>> +++ b/common/cmd_usb.c
>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
>> unsigned char subclass,
>>
>>   void usb_display_string(struct usb_device *dev, int index)
>>   {
>> -	char buffer[256];
>> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
>> +
>>   	if (index != 0) {
>>   		if (usb_string(dev, index,&buffer[0], 256)>  0)
>>   			printf("String: \"%s\"", buffer);
>> diff --git a/common/usb.c b/common/usb.c
>> index 6e21ae2..42a44e2 100644
>> --- a/common/usb.c
>> +++ b/common/usb.c
>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>>   static int dev_index;
>>   static int running;
>>   static int asynch_allowed;
>> -static struct devrequest setup_packet;
>>
>>   char usb_started; /* flag for the started/stopped USB status */
>>
>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned
>> int pipe, unsigned short value, unsigned short index,
>>   			void *data, unsigned short size, int timeout)
>>   {
>> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
>> +		sizeof(struct devrequest));
>>   	if ((timeout == 0)&&  (!asynch_allowed)) {
>>   		/* request for a asynch control pipe is not allowed */
>>   		return -1;
>>   	}
>>
>>   	/* set setup command */
>> -	setup_packet.requesttype = requesttype;
>> -	setup_packet.request = request;
>> -	setup_packet.value = cpu_to_le16(value);
>> -	setup_packet.index = cpu_to_le16(index);
>> -	setup_packet.length = cpu_to_le16(size);
>> +	setup_packet->requesttype = requesttype;
>> +	setup_packet->request = request;
>> +	setup_packet->value = cpu_to_le16(value);
>> +	setup_packet->index = cpu_to_le16(index);
>> +	setup_packet->length = cpu_to_le16(size);
>>   	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>>   		   "value 0x%X index 0x%X length 0x%X\n",
>>   		   request, requesttype, value, index, size);
>>   	dev->status = USB_ST_NOT_PROC; /*not yet processed */
>>
>> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
>> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>>   	if (timeout == 0)
>>   		return (int)size;
>>
>> @@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev,
>> unsigned int langid, */
>>   int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>>   {
>> -	unsigned char mybuf[USB_BUFSIZ];
>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>>   	unsigned char *tbuf;
>>   	int err;
>>   	unsigned int u, idx;
>> @@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
>>   {
>>   	int addr, err;
>>   	int tmp;
>> -	unsigned char tmpbuf[USB_BUFSIZ];
>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
>>
>>   	/* We still haven't set the Address yet */
>>   	addr = dev->devnum;
>> @@ -909,7 +910,7 @@ int usb_new_device(struct usb_device *dev)
>>   	tmp = sizeof(dev->descriptor);
>>
>>   	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
>> -				&dev->descriptor, sizeof(dev->descriptor));
>> +				 desc, sizeof(dev->descriptor));
>>   	if (err<  tmp) {
>>   		if (err<  0)
>>   			printf("unable to get device descriptor (error=%d)\n",
>> @@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
>>   				"(expected %i, got %i)\n", tmp, err);
>>   		return 1;
>>   	}
>> +
>> +	/* Now copy the local device descriptor to global device descriptor*/
>> +	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));
> Hey, it's almost perfect!
>
> Just one last question -- why do you need to copy this stuff?
We need to copy this stuff as I spoke in previous reply  -
"memcpy" is needed to configure Usb version, vendor id, prod Id ..etc
>  of the device. Its also useful to hook actual device driver and detect
>  no. of configuration supported. The effect can be verified 
with/without using memcpy
in "usb tree" and "usb info" commands.


> It's because dev-
>> descriptor is unaligned?
No, As global dev - descriptor is unaligned we are passing aligned local 
dev-desc and memcpy in global.
> M

Thanx,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-02 14:00                                   ` puneets
@ 2012-03-02 14:41                                     ` Marek Vasut
  2012-03-02 15:21                                       ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-02 14:41 UTC (permalink / raw)
  To: u-boot

> On Friday 02 March 2012 07:16 PM, Marek Vasut wrote:
> >> As DMA expects the buffers to be equal and larger then
> >> cache lines, This aligns buffers at cacheline.
> >> 
> >> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >> ---
> >> 
> >> Changes for V3:
> >>      - Removed local descriptor elements copy to global descriptor
> >>      elements - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>" from
> >>      commit
> >> 
> >> message
> >> 
> >> Changes for V4:
> >>      - Added memcpy to copy local descriptor to global descriptor.
> >>      
> >>        Without that, USB version, class, vendor, product Id...etc is not
> >> 
> >> configured. This information is useful for loading correct device driver
> >> and possible configuration.
> >> 
> >>   common/cmd_usb.c            |    3 +-
> >>   common/usb.c                |   56
> >> 
> >> ++++++++++++++++++++++------------------ common/usb_storage.c        |
> >> 59 ++++++++++++++++++++---------------------- disk/part_dos.c
> >> 
> >> |    2 +-
> >>   
> >>   drivers/usb/host/ehci-hcd.c |    8 ++++++
> >>   include/scsi.h              |    4 ++-
> >>   6 files changed, 73 insertions(+), 59 deletions(-)
> >> 
> >> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> >> index 320667f..bca9d94 100644
> >> --- a/common/cmd_usb.c
> >> +++ b/common/cmd_usb.c
> >> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> >> unsigned char subclass,
> >> 
> >>   void usb_display_string(struct usb_device *dev, int index)
> >>   {
> >> 
> >> -	char buffer[256];
> >> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> >> +
> >> 
> >>   	if (index != 0) {
> >>   	
> >>   		if (usb_string(dev, index,&buffer[0], 256)>  0)
> >>   		
> >>   			printf("String: \"%s\"", buffer);
> >> 
> >> diff --git a/common/usb.c b/common/usb.c
> >> index 6e21ae2..42a44e2 100644
> >> --- a/common/usb.c
> >> +++ b/common/usb.c
> >> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
> >> 
> >>   static int dev_index;
> >>   static int running;
> >>   static int asynch_allowed;
> >> 
> >> -static struct devrequest setup_packet;
> >> 
> >>   char usb_started; /* flag for the started/stopped USB status */
> >> 
> >> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
> >> unsigned int pipe, unsigned short value, unsigned short index,
> >> 
> >>   			void *data, unsigned short size, int timeout)
> >>   
> >>   {
> >> 
> >> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> >> +		sizeof(struct devrequest));
> >> 
> >>   	if ((timeout == 0)&&  (!asynch_allowed)) {
> >>   	
> >>   		/* request for a asynch control pipe is not allowed */
> >>   		return -1;
> >>   	
> >>   	}
> >>   	
> >>   	/* set setup command */
> >> 
> >> -	setup_packet.requesttype = requesttype;
> >> -	setup_packet.request = request;
> >> -	setup_packet.value = cpu_to_le16(value);
> >> -	setup_packet.index = cpu_to_le16(index);
> >> -	setup_packet.length = cpu_to_le16(size);
> >> +	setup_packet->requesttype = requesttype;
> >> +	setup_packet->request = request;
> >> +	setup_packet->value = cpu_to_le16(value);
> >> +	setup_packet->index = cpu_to_le16(index);
> >> +	setup_packet->length = cpu_to_le16(size);
> >> 
> >>   	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
> >>   	
> >>   		   "value 0x%X index 0x%X length 0x%X\n",
> >>   		   request, requesttype, value, index, size);
> >>   	
> >>   	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> >> 
> >> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
> >> +	submit_control_msg(dev, pipe, data, size, setup_packet);
> >> 
> >>   	if (timeout == 0)
> >>   	
> >>   		return (int)size;
> >> 
> >> @@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev,
> >> unsigned int langid, */
> >> 
> >>   int usb_string(struct usb_device *dev, int index, char *buf, size_t
> >>   size) {
> >> 
> >> -	unsigned char mybuf[USB_BUFSIZ];
> >> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
> >> 
> >>   	unsigned char *tbuf;
> >>   	int err;
> >>   	unsigned int u, idx;
> >> 
> >> @@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
> >> 
> >>   {
> >>   
> >>   	int addr, err;
> >>   	int tmp;
> >> 
> >> -	unsigned char tmpbuf[USB_BUFSIZ];
> >> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> >> 
> >>   	/* We still haven't set the Address yet */
> >>   	addr = dev->devnum;
> >> 
> >> @@ -909,7 +910,7 @@ int usb_new_device(struct usb_device *dev)
> >> 
> >>   	tmp = sizeof(dev->descriptor);
> >>   	
> >>   	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
> >> 
> >> -				&dev->descriptor, sizeof(dev->descriptor));
> >> +				 desc, sizeof(dev->descriptor));
> >> 
> >>   	if (err<  tmp) {
> >>   	
> >>   		if (err<  0)
> >>   		
> >>   			printf("unable to get device descriptor (error=%d)\n",
> >> 
> >> @@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
> >> 
> >>   				"(expected %i, got %i)\n", tmp, err);
> >>   		
> >>   		return 1;
> >>   	
> >>   	}
> >> 
> >> +
> >> +	/* Now copy the local device descriptor to global device descriptor*/
> >> +	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));
> > 
> > Hey, it's almost perfect!
> > 
> > Just one last question -- why do you need to copy this stuff?
> 
> We need to copy this stuff as I spoke in previous reply  -
> "memcpy" is needed to configure Usb version, vendor id, prod Id ..etc
> 
> >  of the device. Its also useful to hook actual device driver and detect
> >  no. of configuration supported. The effect can be verified
> 
> with/without using memcpy
> in "usb tree" and "usb info" commands.
> 
> > It's because dev-
> > 
> >> descriptor is unaligned?
> 
> No, As global dev - descriptor is unaligned we are passing aligned local
> dev-desc and memcpy in global.

Can't we just align the global one?
M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-02 14:41                                     ` Marek Vasut
@ 2012-03-02 15:21                                       ` puneets
  2012-03-02 15:59                                         ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-02 15:21 UTC (permalink / raw)
  To: u-boot

On Friday 02 March 2012 08:11 PM, Marek Vasut wrote:
>> On Friday 02 March 2012 07:16 PM, Marek Vasut wrote:
>>>> As DMA expects the buffers to be equal and larger then
>>>> cache lines, This aligns buffers at cacheline.
>>>>
>>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>>>> ---
>>>>
>>>> Changes for V3:
>>>>       - Removed local descriptor elements copy to global descriptor
>>>>       elements - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>" from
>>>>       commit
>>>>
>>>> message
>>>>
>>>> Changes for V4:
>>>>       - Added memcpy to copy local descriptor to global descriptor.
>>>>
>>>>         Without that, USB version, class, vendor, product Id...etc is not
>>>>
>>>> configured. This information is useful for loading correct device driver
>>>> and possible configuration.
>>>>
>>>>    common/cmd_usb.c            |    3 +-
>>>>    common/usb.c                |   56
>>>>
>>>> ++++++++++++++++++++++------------------ common/usb_storage.c        |
>>>> 59 ++++++++++++++++++++---------------------- disk/part_dos.c
>>>>
>>>> |    2 +-
>>>>
>>>>    drivers/usb/host/ehci-hcd.c |    8 ++++++
>>>>    include/scsi.h              |    4 ++-
>>>>    6 files changed, 73 insertions(+), 59 deletions(-)
>>>>
>>>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
>>>> index 320667f..bca9d94 100644
>>>> --- a/common/cmd_usb.c
>>>> +++ b/common/cmd_usb.c
>>>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
>>>> unsigned char subclass,
>>>>
>>>>    void usb_display_string(struct usb_device *dev, int index)
>>>>    {
>>>>
>>>> -	char buffer[256];
>>>> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
>>>> +
>>>>
>>>>    	if (index != 0) {
>>>>    	
>>>>    		if (usb_string(dev, index,&buffer[0], 256)>   0)
>>>>    		
>>>>    			printf("String: \"%s\"", buffer);
>>>>
>>>> diff --git a/common/usb.c b/common/usb.c
>>>> index 6e21ae2..42a44e2 100644
>>>> --- a/common/usb.c
>>>> +++ b/common/usb.c
>>>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>>>>
>>>>    static int dev_index;
>>>>    static int running;
>>>>    static int asynch_allowed;
>>>>
>>>> -static struct devrequest setup_packet;
>>>>
>>>>    char usb_started; /* flag for the started/stopped USB status */
>>>>
>>>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
>>>> unsigned int pipe, unsigned short value, unsigned short index,
>>>>
>>>>    			void *data, unsigned short size, int timeout)
>>>>
>>>>    {
>>>>
>>>> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
>>>> +		sizeof(struct devrequest));
>>>>
>>>>    	if ((timeout == 0)&&   (!asynch_allowed)) {
>>>>    	
>>>>    		/* request for a asynch control pipe is not allowed */
>>>>    		return -1;
>>>>    	
>>>>    	}
>>>>    	
>>>>    	/* set setup command */
>>>>
>>>> -	setup_packet.requesttype = requesttype;
>>>> -	setup_packet.request = request;
>>>> -	setup_packet.value = cpu_to_le16(value);
>>>> -	setup_packet.index = cpu_to_le16(index);
>>>> -	setup_packet.length = cpu_to_le16(size);
>>>> +	setup_packet->requesttype = requesttype;
>>>> +	setup_packet->request = request;
>>>> +	setup_packet->value = cpu_to_le16(value);
>>>> +	setup_packet->index = cpu_to_le16(index);
>>>> +	setup_packet->length = cpu_to_le16(size);
>>>>
>>>>    	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>>>>    	
>>>>    		   "value 0x%X index 0x%X length 0x%X\n",
>>>>    		   request, requesttype, value, index, size);
>>>>    	
>>>>    	dev->status = USB_ST_NOT_PROC; /*not yet processed */
>>>>
>>>> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
>>>> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>>>>
>>>>    	if (timeout == 0)
>>>>    	
>>>>    		return (int)size;
>>>>
>>>> @@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev,
>>>> unsigned int langid, */
>>>>
>>>>    int usb_string(struct usb_device *dev, int index, char *buf, size_t
>>>>    size) {
>>>>
>>>> -	unsigned char mybuf[USB_BUFSIZ];
>>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>>>>
>>>>    	unsigned char *tbuf;
>>>>    	int err;
>>>>    	unsigned int u, idx;
>>>>
>>>> @@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
>>>>
>>>>    {
>>>>
>>>>    	int addr, err;
>>>>    	int tmp;
>>>>
>>>> -	unsigned char tmpbuf[USB_BUFSIZ];
>>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
>>>>
>>>>    	/* We still haven't set the Address yet */
>>>>    	addr = dev->devnum;
>>>>
>>>> @@ -909,7 +910,7 @@ int usb_new_device(struct usb_device *dev)
>>>>
>>>>    	tmp = sizeof(dev->descriptor);
>>>>    	
>>>>    	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
>>>>
>>>> -				&dev->descriptor, sizeof(dev->descriptor));
>>>> +				 desc, sizeof(dev->descriptor));
>>>>
>>>>    	if (err<   tmp) {
>>>>    	
>>>>    		if (err<   0)
>>>>    		
>>>>    			printf("unable to get device descriptor (error=%d)\n",
>>>>
>>>> @@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
>>>>
>>>>    				"(expected %i, got %i)\n", tmp, err);
>>>>    		
>>>>    		return 1;
>>>>    	
>>>>    	}
>>>>
>>>> +
>>>> +	/* Now copy the local device descriptor to global device descriptor*/
>>>> +	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));
>>> Hey, it's almost perfect!
>>>
>>> Just one last question -- why do you need to copy this stuff?
>> We need to copy this stuff as I spoke in previous reply  -
>> "memcpy" is needed to configure Usb version, vendor id, prod Id ..etc
>>
>>>   of the device. Its also useful to hook actual device driver and detect
>>>   no. of configuration supported. The effect can be verified
>> with/without using memcpy
>> in "usb tree" and "usb info" commands.
>>
>>> It's because dev-
>>>
>>>> descriptor is unaligned?
>> No, As global dev - descriptor is unaligned we are passing aligned local
>> dev-desc and memcpy in global.
> Can't we just align the global one?
That's what I did in original patch where I am aligning it by adding the 
line

+        /* Device Descriptor */
+#ifdef ARCH_DMA_MINALIGN
+       struct usb_device_descriptor descriptor
+               __attribute__((aligned(ARCH_DMA_MINALIGN)));
+#else
+       struct usb_device_descriptor descriptor;
+#endif

in usb.h Line:112

> M
Thanx,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-02 15:21                                       ` puneets
@ 2012-03-02 15:59                                         ` Marek Vasut
  2012-03-02 16:45                                           ` Wolfgang Denk
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-02 15:59 UTC (permalink / raw)
  To: u-boot

> On Friday 02 March 2012 08:11 PM, Marek Vasut wrote:
> >> On Friday 02 March 2012 07:16 PM, Marek Vasut wrote:
> >>>> As DMA expects the buffers to be equal and larger then
> >>>> cache lines, This aligns buffers at cacheline.
> >>>> 
> >>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >>>> ---
> >>>> 
> >>>> Changes for V3:
> >>>>       - Removed local descriptor elements copy to global descriptor
> >>>>       elements - Removed "Signed-off-by: Jim Lin<jilin@nvidia.com>"
> >>>>       from commit
> >>>> 
> >>>> message
> >>>> 
> >>>> Changes for V4:
> >>>>       - Added memcpy to copy local descriptor to global descriptor.
> >>>>       
> >>>>         Without that, USB version, class, vendor, product Id...etc is
> >>>>         not
> >>>> 
> >>>> configured. This information is useful for loading correct device
> >>>> driver and possible configuration.
> >>>> 
> >>>>    common/cmd_usb.c            |    3 +-
> >>>>    common/usb.c                |   56
> >>>> 
> >>>> ++++++++++++++++++++++------------------ common/usb_storage.c        |
> >>>> 59 ++++++++++++++++++++---------------------- disk/part_dos.c
> >>>> 
> >>>> |    2 +-
> >>>>    
> >>>>    drivers/usb/host/ehci-hcd.c |    8 ++++++
> >>>>    include/scsi.h              |    4 ++-
> >>>>    6 files changed, 73 insertions(+), 59 deletions(-)
> >>>> 
> >>>> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> >>>> index 320667f..bca9d94 100644
> >>>> --- a/common/cmd_usb.c
> >>>> +++ b/common/cmd_usb.c
> >>>> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> >>>> unsigned char subclass,
> >>>> 
> >>>>    void usb_display_string(struct usb_device *dev, int index)
> >>>>    {
> >>>> 
> >>>> -	char buffer[256];
> >>>> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> >>>> +
> >>>> 
> >>>>    	if (index != 0) {
> >>>>    	
> >>>>    		if (usb_string(dev, index,&buffer[0], 256)>   0)
> >>>>    		
> >>>>    			printf("String: \"%s\"", buffer);
> >>>> 
> >>>> diff --git a/common/usb.c b/common/usb.c
> >>>> index 6e21ae2..42a44e2 100644
> >>>> --- a/common/usb.c
> >>>> +++ b/common/usb.c
> >>>> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
> >>>> 
> >>>>    static int dev_index;
> >>>>    static int running;
> >>>>    static int asynch_allowed;
> >>>> 
> >>>> -static struct devrequest setup_packet;
> >>>> 
> >>>>    char usb_started; /* flag for the started/stopped USB status */
> >>>> 
> >>>> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
> >>>> unsigned int pipe, unsigned short value, unsigned short index,
> >>>> 
> >>>>    			void *data, unsigned short size, int timeout)
> >>>>    
> >>>>    {
> >>>> 
> >>>> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> >>>> +		sizeof(struct devrequest));
> >>>> 
> >>>>    	if ((timeout == 0)&&   (!asynch_allowed)) {
> >>>>    	
> >>>>    		/* request for a asynch control pipe is not allowed */
> >>>>    		return -1;
> >>>>    	
> >>>>    	}
> >>>>    	
> >>>>    	/* set setup command */
> >>>> 
> >>>> -	setup_packet.requesttype = requesttype;
> >>>> -	setup_packet.request = request;
> >>>> -	setup_packet.value = cpu_to_le16(value);
> >>>> -	setup_packet.index = cpu_to_le16(index);
> >>>> -	setup_packet.length = cpu_to_le16(size);
> >>>> +	setup_packet->requesttype = requesttype;
> >>>> +	setup_packet->request = request;
> >>>> +	setup_packet->value = cpu_to_le16(value);
> >>>> +	setup_packet->index = cpu_to_le16(index);
> >>>> +	setup_packet->length = cpu_to_le16(size);
> >>>> 
> >>>>    	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " 
\
> >>>>    	
> >>>>    		   "value 0x%X index 0x%X length 0x%X\n",
> >>>>    		   request, requesttype, value, index, size);
> >>>>    	
> >>>>    	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> >>>> 
> >>>> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
> >>>> +	submit_control_msg(dev, pipe, data, size, setup_packet);
> >>>> 
> >>>>    	if (timeout == 0)
> >>>>    	
> >>>>    		return (int)size;
> >>>> 
> >>>> @@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev,
> >>>> unsigned int langid, */
> >>>> 
> >>>>    int usb_string(struct usb_device *dev, int index, char *buf, size_t
> >>>>    size) {
> >>>> 
> >>>> -	unsigned char mybuf[USB_BUFSIZ];
> >>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
> >>>> 
> >>>>    	unsigned char *tbuf;
> >>>>    	int err;
> >>>>    	unsigned int u, idx;
> >>>> 
> >>>> @@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
> >>>> 
> >>>>    {
> >>>>    
> >>>>    	int addr, err;
> >>>>    	int tmp;
> >>>> 
> >>>> -	unsigned char tmpbuf[USB_BUFSIZ];
> >>>> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> >>>> 
> >>>>    	/* We still haven't set the Address yet */
> >>>>    	addr = dev->devnum;
> >>>> 
> >>>> @@ -909,7 +910,7 @@ int usb_new_device(struct usb_device *dev)
> >>>> 
> >>>>    	tmp = sizeof(dev->descriptor);
> >>>>    	
> >>>>    	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
> >>>> 
> >>>> -				&dev->descriptor, sizeof(dev-
>descriptor));
> >>>> +				 desc, sizeof(dev->descriptor));
> >>>> 
> >>>>    	if (err<   tmp) {
> >>>>    	
> >>>>    		if (err<   0)
> >>>>    		
> >>>>    			printf("unable to get device descriptor 
(error=%d)\n",
> >>>> 
> >>>> @@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
> >>>> 
> >>>>    				"(expected %i, got %i)\n", tmp, err);
> >>>>    		
> >>>>    		return 1;
> >>>>    	
> >>>>    	}
> >>>> 
> >>>> +
> >>>> +	/* Now copy the local device descriptor to global device
> >>>> descriptor*/ +	memcpy(&dev->descriptor, desc,
> >>>> sizeof(dev->descriptor));
> >>> 
> >>> Hey, it's almost perfect!
> >>> 
> >>> Just one last question -- why do you need to copy this stuff?
> >> 
> >> We need to copy this stuff as I spoke in previous reply  -
> >> "memcpy" is needed to configure Usb version, vendor id, prod Id ..etc
> >> 
> >>>   of the device. Its also useful to hook actual device driver and
> >>>   detect no. of configuration supported. The effect can be verified
> >> 
> >> with/without using memcpy
> >> in "usb tree" and "usb info" commands.
> >> 
> >>> It's because dev-
> >>> 
> >>>> descriptor is unaligned?
> >> 
> >> No, As global dev - descriptor is unaligned we are passing aligned local
> >> dev-desc and memcpy in global.
> > 
> > Can't we just align the global one?
> 
> That's what I did in original patch where I am aligning it by adding the
> line
> 
> +        /* Device Descriptor */
> +#ifdef ARCH_DMA_MINALIGN
> +       struct usb_device_descriptor descriptor
> +               __attribute__((aligned(ARCH_DMA_MINALIGN)));
> +#else
> +       struct usb_device_descriptor descriptor;
> +#endif
> 
> in usb.h Line:112
> 
> > M
> 
I see ...and I told you it's wrong? I must have misunderstood, I'm sorry about 
that. But if you actually do this, you can avoid memcpy, right?

M

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-02 15:59                                         ` Marek Vasut
@ 2012-03-02 16:45                                           ` Wolfgang Denk
  2012-03-05  7:16                                             ` [U-Boot] [PATCH v5] " Puneet Saxena
                                                               ` (2 more replies)
  0 siblings, 3 replies; 83+ messages in thread
From: Wolfgang Denk @ 2012-03-02 16:45 UTC (permalink / raw)
  To: u-boot

In message <201203021659.21568.marex@denx.de> you wrote:
>
...
> > That's what I did in original patch where I am aligning it by adding the
> > line
> > 
> > +        /* Device Descriptor */
> > +#ifdef ARCH_DMA_MINALIGN
> > +       struct usb_device_descriptor descriptor
> > +               __attribute__((aligned(ARCH_DMA_MINALIGN)));
> > +#else
> > +       struct usb_device_descriptor descriptor;
> > +#endif
> > 
> > in usb.h Line:112
> > 
> > > M
> > 
> I see ...and I told you it's wrong? I must have misunderstood, I'm sorry about 
> that. But if you actually do this, you can avoid memcpy, right?

And eventually wd can also avoid the #ifdef ?  I guess the
__attribute__((aligned...)) would not hurt anything?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Der Horizont vieler Menschen ist ein Kreis mit Radius Null --
und das nennen sie ihren Standpunkt.

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v5] usb: align buffers at cacheline
  2012-03-02 16:45                                           ` Wolfgang Denk
@ 2012-03-05  7:16                                             ` Puneet Saxena
  2012-03-05 13:24                                               ` Eric Nelson
  2012-03-05  7:27                                             ` [U-Boot] [PATCH v6] " Puneet Saxena
  2012-03-06  3:28                                             ` [U-Boot] [PATCH v4] " Mike Frysinger
  2 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-03-05  7:16 UTC (permalink / raw)
  To: u-boot

As DMA expects the buffers to be equal and larger then
cache lines, This aligns buffers at cacheline.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---
Changes for V4:
    - Added memcpy to copy local descriptor to global descriptor.
      Without that, USB version, class, vendor, product Id...etc is not configured.
      This information is useful for loading correct device driver and possible 
      configuration.  

Changes for V5:
    - Aligned "usb_device_descriptor" using ARCH_DMA_MINALIGN

 common/cmd_usb.c            |    3 +-
 common/usb.c                |   54 ++++++++++++++++++++++-----------------
 common/usb_storage.c        |   59 ++++++++++++++++++++----------------------
 disk/part_dos.c             |    2 +-
 drivers/usb/host/ehci-hcd.c |    8 ++++++
 include/scsi.h              |    4 ++-
 include/usb.h               |    6 +++-
 7 files changed, 76 insertions(+), 60 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 6e21ae2..3005012 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
+		sizeof(struct devrequest));
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
 		   "value 0x%X index 0x%X length 0x%X\n",
 		   request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	submit_control_msg(dev, pipe, data, size, setup_packet);
 	if (timeout == 0)
 		return (int)size;
 
@@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
 				"(expected %i, got %i)\n", tmp, err);
 		return 1;
 	}
+
+	/* Now copy the local device descriptor to global device descriptor*/
+	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));
+
 	/* correct le values */
 	le16_to_cpus(&dev->descriptor.bcdUSB);
 	le16_to_cpus(&dev->descriptor.idVendor);
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1080,7 +1085,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1089,13 +1094,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1133,19 +1138,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1194,7 +1199,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1316,16 +1322,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..88ca390 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
 
 /*
  * CBI style
@@ -210,17 +209,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
 		printf("       scanning bus for storage devices... ");
 
@@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +729,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +749,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +778,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
@@ -1367,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], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	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);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
diff --git a/disk/part_dos.c b/disk/part_dos.c
index b5bcb37..70211ee 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
-	unsigned char buffer[dev_desc->blksz];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..eb5220b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,6 +120,14 @@ static struct descriptor {
  */
 static void flush_invalidate(u32 addr, int size, int flush)
 {
+	/*
+	 * Size is the bytes actually moved during transaction,
+	 * which may not equal to the cache line. This results
+	 * stop address passed for invalidating cache may not be aligned.
+	 * Therfore making size as multiple of cache line size.
+	 */
+	size = ALIGN(size, ARCH_DMA_MINALIGN);
+
 	if (flush)
 		flush_dcache_range(addr, addr + size);
 	else
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..89ae45f 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,9 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
diff --git a/include/usb.h b/include/usb.h
index 06170cd..8c082c1 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -109,9 +109,11 @@ struct usb_device {
 	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	int configno;			/* selected config number */
-	struct usb_device_descriptor descriptor; /* Device Descriptor */
-	struct usb_config config; /* config descriptor */
+	/* Device Descriptor */
+	struct usb_device_descriptor descriptor
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 
+	struct usb_config config; /* config descriptor */
 	int have_langid;		/* whether string_langid is valid yet */
 	int string_langid;		/* language ID for strings */
 	int (*irq_handle)(struct usb_device *dev);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v6] usb: align buffers at cacheline
  2012-03-02 16:45                                           ` Wolfgang Denk
  2012-03-05  7:16                                             ` [U-Boot] [PATCH v5] " Puneet Saxena
@ 2012-03-05  7:27                                             ` Puneet Saxena
  2012-03-05 12:03                                               ` Marek Vasut
  2012-03-06  3:28                                             ` [U-Boot] [PATCH v4] " Mike Frysinger
  2 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-03-05  7:27 UTC (permalink / raw)
  To: u-boot

As DMA expects the buffers to be equal and larger then
cache lines, This aligns buffers at cacheline.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---

Changes for V5:
    - Aligned "usb_device_descriptor" using ARCH_DMA_MINALIGN

Changes for V6: 
    - Cosmetic changes.

 common/cmd_usb.c            |    3 +-
 common/usb.c                |   54 ++++++++++++++++++++++-----------------
 common/usb_storage.c        |   59 ++++++++++++++++++++----------------------
 disk/part_dos.c             |    2 +-
 drivers/usb/host/ehci-hcd.c |    8 ++++++
 include/scsi.h              |    4 ++-
 include/usb.h               |    4 ++-
 7 files changed, 75 insertions(+), 59 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 6e21ae2..3005012 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
+		sizeof(struct devrequest));
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
 		   "value 0x%X index 0x%X length 0x%X\n",
 		   request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	submit_control_msg(dev, pipe, data, size, setup_packet);
 	if (timeout == 0)
 		return (int)size;
 
@@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
 				"(expected %i, got %i)\n", tmp, err);
 		return 1;
 	}
+
+	/* Now copy the local device descriptor to global device descriptor*/
+	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));
+
 	/* correct le values */
 	le16_to_cpus(&dev->descriptor.bcdUSB);
 	le16_to_cpus(&dev->descriptor.idVendor);
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1080,7 +1085,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1089,13 +1094,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1133,19 +1138,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1194,7 +1199,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1316,16 +1322,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..88ca390 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
 
 /*
  * CBI style
@@ -210,17 +209,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
 		printf("       scanning bus for storage devices... ");
 
@@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +729,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +749,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +778,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
@@ -1367,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], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	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);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
diff --git a/disk/part_dos.c b/disk/part_dos.c
index b5bcb37..70211ee 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
-	unsigned char buffer[dev_desc->blksz];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..eb5220b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,6 +120,14 @@ static struct descriptor {
  */
 static void flush_invalidate(u32 addr, int size, int flush)
 {
+	/*
+	 * Size is the bytes actually moved during transaction,
+	 * which may not equal to the cache line. This results
+	 * stop address passed for invalidating cache may not be aligned.
+	 * Therfore making size as multiple of cache line size.
+	 */
+	size = ALIGN(size, ARCH_DMA_MINALIGN);
+
 	if (flush)
 		flush_dcache_range(addr, addr + size);
 	else
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..89ae45f 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,9 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
diff --git a/include/usb.h b/include/usb.h
index 06170cd..5f4f110 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -109,7 +109,9 @@ struct usb_device {
 	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	int configno;			/* selected config number */
-	struct usb_device_descriptor descriptor; /* Device Descriptor */
+	/* Device Descriptor */
+	struct usb_device_descriptor descriptor
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	struct usb_config config; /* config descriptor */
 
 	int have_langid;		/* whether string_langid is valid yet */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v6] usb: align buffers at cacheline
  2012-03-05  7:27                                             ` [U-Boot] [PATCH v6] " Puneet Saxena
@ 2012-03-05 12:03                                               ` Marek Vasut
  2012-03-05 12:21                                                 ` [U-Boot] [PATCH v7] " Puneet Saxena
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-05 12:03 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> ---
> 
> Changes for V5:
>     - Aligned "usb_device_descriptor" using ARCH_DMA_MINALIGN
> 
> Changes for V6:
>     - Cosmetic changes.
> 
>  common/cmd_usb.c            |    3 +-
>  common/usb.c                |   54 ++++++++++++++++++++++-----------------
>  common/usb_storage.c        |   59
> ++++++++++++++++++++---------------------- disk/part_dos.c             |  
>  2 +-
>  drivers/usb/host/ehci-hcd.c |    8 ++++++
>  include/scsi.h              |    4 ++-
>  include/usb.h               |    4 ++-
>  7 files changed, 75 insertions(+), 59 deletions(-)
> 
> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> index 320667f..bca9d94 100644
> --- a/common/cmd_usb.c
> +++ b/common/cmd_usb.c
> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> unsigned char subclass,
> 
>  void usb_display_string(struct usb_device *dev, int index)
>  {
> -	char buffer[256];
> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> +
>  	if (index != 0) {
>  		if (usb_string(dev, index, &buffer[0], 256) > 0)
>  			printf("String: \"%s\"", buffer);
> diff --git a/common/usb.c b/common/usb.c
> index 6e21ae2..3005012 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>  static int dev_index;
>  static int running;
>  static int asynch_allowed;
> -static struct devrequest setup_packet;
> 
>  char usb_started; /* flag for the started/stopped USB status */
> 
> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned
> int pipe, unsigned short value, unsigned short index,
>  			void *data, unsigned short size, int timeout)
>  {
> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> +		sizeof(struct devrequest));
>  	if ((timeout == 0) && (!asynch_allowed)) {
>  		/* request for a asynch control pipe is not allowed */
>  		return -1;
>  	}
> 
>  	/* set setup command */
> -	setup_packet.requesttype = requesttype;
> -	setup_packet.request = request;
> -	setup_packet.value = cpu_to_le16(value);
> -	setup_packet.index = cpu_to_le16(index);
> -	setup_packet.length = cpu_to_le16(size);
> +	setup_packet->requesttype = requesttype;
> +	setup_packet->request = request;
> +	setup_packet->value = cpu_to_le16(value);
> +	setup_packet->index = cpu_to_le16(index);
> +	setup_packet->length = cpu_to_le16(size);
>  	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>  		   "value 0x%X index 0x%X length 0x%X\n",
>  		   request, requesttype, value, index, size);
>  	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> 
> -	submit_control_msg(dev, pipe, data, size, &setup_packet);
> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>  	if (timeout == 0)
>  		return (int)size;
> 
> @@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev,
> unsigned int langid, */
>  int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>  {
> -	unsigned char mybuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>  	unsigned char *tbuf;
>  	int err;
>  	unsigned int u, idx;
> @@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
>  {
>  	int addr, err;
>  	int tmp;
> -	unsigned char tmpbuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> 
>  	/* We still haven't set the Address yet */
>  	addr = dev->devnum;
> @@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
>  				"(expected %i, got %i)\n", tmp, err);
>  		return 1;
>  	}
> +
> +	/* Now copy the local device descriptor to global device descriptor*/
> +	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));
> +

Why is this memcpy() here? Didn't we finally decide to align the global 
descriptor so this is unnecessary?

The rest of the patch is perfect, I'm looking forward to testing it. :-)

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v7] usb: align buffers at cacheline
  2012-03-05 12:03                                               ` Marek Vasut
@ 2012-03-05 12:21                                                 ` Puneet Saxena
  2012-03-05 12:41                                                   ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: Puneet Saxena @ 2012-03-05 12:21 UTC (permalink / raw)
  To: u-boot

As DMA expects the buffers to be equal and larger then
cache lines, This aligns buffers at cacheline.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---

Changes for V6:
    - Cosmetic changes.

Changes for V7:
    - Trivial change, missed removing memcpy. Removed now.  

 common/cmd_usb.c            |    3 +-
 common/usb.c                |   50 +++++++++++++++++++-----------------
 common/usb_storage.c        |   59 ++++++++++++++++++++----------------------
 disk/part_dos.c             |    2 +-
 drivers/usb/host/ehci-hcd.c |    8 ++++++
 include/scsi.h              |    4 ++-
 include/usb.h               |    4 ++-
 7 files changed, 71 insertions(+), 59 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 6e21ae2..4a926a0 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
+		sizeof(struct devrequest));
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
 		   "value 0x%X index 0x%X length 0x%X\n",
 		   request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	submit_control_msg(dev, pipe, data, size, setup_packet);
 	if (timeout == 0)
 		return (int)size;
 
@@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -925,8 +926,8 @@ int usb_new_device(struct usb_device *dev)
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1080,7 +1081,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1089,13 +1090,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1133,19 +1134,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1194,7 +1195,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1316,16 +1318,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..88ca390 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
 
 /*
  * CBI style
@@ -210,17 +209,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
 		printf("       scanning bus for storage devices... ");
 
@@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +729,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +749,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +778,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
@@ -1367,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], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	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);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
diff --git a/disk/part_dos.c b/disk/part_dos.c
index b5bcb37..70211ee 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
-	unsigned char buffer[dev_desc->blksz];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..eb5220b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,6 +120,14 @@ static struct descriptor {
  */
 static void flush_invalidate(u32 addr, int size, int flush)
 {
+	/*
+	 * Size is the bytes actually moved during transaction,
+	 * which may not equal to the cache line. This results
+	 * stop address passed for invalidating cache may not be aligned.
+	 * Therfore making size as multiple of cache line size.
+	 */
+	size = ALIGN(size, ARCH_DMA_MINALIGN);
+
 	if (flush)
 		flush_dcache_range(addr, addr + size);
 	else
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..89ae45f 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,9 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
diff --git a/include/usb.h b/include/usb.h
index 06170cd..5f4f110 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -109,7 +109,9 @@ struct usb_device {
 	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	int configno;			/* selected config number */
-	struct usb_device_descriptor descriptor; /* Device Descriptor */
+	/* Device Descriptor */
+	struct usb_device_descriptor descriptor
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	struct usb_config config; /* config descriptor */
 
 	int have_langid;		/* whether string_langid is valid yet */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v7] usb: align buffers at cacheline
  2012-03-05 12:21                                                 ` [U-Boot] [PATCH v7] " Puneet Saxena
@ 2012-03-05 12:41                                                   ` Marek Vasut
  0 siblings, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-03-05 12:41 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

This patch was scheduled for aplication. Thank you very much for your good work 
on this patch!

I'll do final test on my platform before applying this.

> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> ---
> 
> Changes for V6:
>     - Cosmetic changes.
> 
> Changes for V7:
>     - Trivial change, missed removing memcpy. Removed now.
> 
>  common/cmd_usb.c            |    3 +-
>  common/usb.c                |   50 +++++++++++++++++++-----------------
>  common/usb_storage.c        |   59
> ++++++++++++++++++++---------------------- disk/part_dos.c             |  
>  2 +-
>  drivers/usb/host/ehci-hcd.c |    8 ++++++
>  include/scsi.h              |    4 ++-
>  include/usb.h               |    4 ++-
>  7 files changed, 71 insertions(+), 59 deletions(-)

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-03-01 13:13                         ` Marek Vasut
@ 2012-03-05 12:48                           ` Marek Vasut
  2012-03-05 13:14                             ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-05 12:48 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

> > Hi Marek,
> > 
> > On Thursday 01 March 2012 05:15 PM, Marek Vasut wrote:
> > > Hi!
> > > 
> > >> Hi Marek,
> > >> 
> > >> On Thursday 01 March 2012 02:59 AM, Marek Vasut wrote:
> > >>>> Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor
> > >>>> length and then pass this length to fetch string descriptor.
> > >>>> 
> > >>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> > >>>> ---
> > >>>> 
> > >>>> Changes for V2:
> > >>>>      - Change existing config by "CONFIG_USB_STRING_FETCH"
> > >>>> 
> > >>>> Changes for V3:
> > >>>>       - Removed extra new line
> > >>>>       - Explained "CONFIG_USB_STRING_FETCH" in top level README
> > >>>>    
> > >>>>    README                          |    4 ++++
> > >>>>    common/usb.c                    |    4 ++++
> > >>>>    include/configs/tegra2-common.h |    2 ++
> > >>>>    3 files changed, 10 insertions(+), 0 deletions(-)
> > >>>> 
> > >>>> diff --git a/README b/README
> > >>>> index 7adf7c7..c045a37 100644
> > >>>> --- a/README
> > >>>> +++ b/README
> > >>>> 
> > >>>> @@ -1138,6 +1138,10 @@ The following options need to be configured:
> > >>>>    		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
> > >>>>    		txfilltuning field in the EHCI controller on reset.
> > >>>> 
> > >>>> +		CONFIG_USB_STRING_FETCH
> > >>>> +		Enables settings to USB core to handle string issues
> 
> which
> 
> > >>>> +		few devices can not handle.
> > >>>> +
> > >>>> 
> > >>>>    - USB Device:
> > >>>>    		Define the below if you wish to use the USB console.
> > >>>>    		Once firmware is rebuilt from a serial console issue the
> > >>>> 
> > >>>> diff --git a/common/usb.c b/common/usb.c
> > >>>> index 191bc5b..a73cb60 100644
> > >>>> --- a/common/usb.c
> > >>>> +++ b/common/usb.c
> > >>>> @@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device
> > >>>> *dev, unsigned int langid, {
> > >>>> 
> > >>>>    	int rc;
> > >>>> 
> > >>>> +#ifdef CONFIG_USB_STRING_FETCH
> > >>> 
> > >>> Shouldn't this be something like ... CONFIG_USB_AVOID_STRING_FETCH
> > >>> then?
> > >>> 
> > >>> Anyway, how come some devices can't handle it? What happens then?
> > >>> What devices are those (exact type etc)?
> > >>> 
> > >>> I believe the bug is deeper and adding extra config options can be
> > >>> avoided, what do you think?
> > >>> 
> > >>> Thanks!
> > >>> 
> > >>> M
> > >> 
> > >> It does not avoid string fetch.
> > > 
> > > Well it does certainly not call usb_get_string()
> > 
> > Precisely, it avoids fetching string desc of 255 bytes. so better name
> > could be
> > "CONFIG_USB_AVOID_STRING_FETCH_255".  Thanks for your comment.
> > 
> > >> I checked with few mass storage devices that they does not handle
> > >> string descriptor request correctly and so we get
> > >> start/stop Cache alignment error.
> > > 
> > > Cache alignment error ? Wow, how's that actually related to SUB string
> > > fetching? Maybe we should manually realign the result then? I still
> > > don't really understand what you're seeing, sorry ... can you please
> > > elaborate?
> > 
> > The particular mass storage device is -
> > 
> > Vendor: Kingston Rev: PMAP Prod: DataTraveler 2.0
> > 
> > Type: Removable Hard Disk
> > 
> > Capacity: 1906.0 MB = 1.8 GB (3903488 x 512)
> > 
> > When code tries to read Manufacturing Id..prod id...etc..it passes cache
> > aligned buffer "tbuf" in
> > "usb_string()" @usb.c. Inside "usb_string_sub()", usb_get_string()
> > passes as default 255 bytes to fetch string
> > descriptor.
> > The code in "ehci_submit_async() " invalidates *partially* the passed
> > buffer though we pass aligned buffer and "STD_ASS"
> > is received. Though it should invalidate only the cached line which is
> > equal(~32)  to string desc length.
> 
> Hm ... so this means the bug is in ehci_hcd? Maybe the ehci_hcd should be
> fixed to correctly handle caches then?
> 
> > If we give delay of 1 ms after handshake() the cache alignment warning
> > does not spew...but delay of 1 ms is not acceptable.
> > So I enabled the code to fetch first string desc length and then fetch
> > string desc fetch, in this way the issue is resolved.
> > It makes sense also to fetch string desc length and then actual string
> > desc....
> 
> I see, I  understand now just about everything but the ehci problem, see
> above. Your explanation was very helpful.
> 
> Let's work this out together!
> 
> Cheers!
> 
> M

Is this issue fixed or is this patch still needed? Thanks in advance!

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-03-05 12:48                           ` Marek Vasut
@ 2012-03-05 13:14                             ` puneets
  2012-03-05 21:15                               ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-05 13:14 UTC (permalink / raw)
  To: u-boot

Hi Marek,
On Monday 05 March 2012 06:18 PM, Marek Vasut wrote:
> Dear Puneet Saxena,
>
>>> Hi Marek,
>>>
>>> On Thursday 01 March 2012 05:15 PM, Marek Vasut wrote:
>>>> Hi!
>>>>
>>>>> Hi Marek,
>>>>>
>>>>> On Thursday 01 March 2012 02:59 AM, Marek Vasut wrote:
>>>>>>> Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor
>>>>>>> length and then pass this length to fetch string descriptor.
>>>>>>>
>>>>>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
>>>>>>> ---
>>>>>>>
>>>>>>> Changes for V2:
>>>>>>>       - Change existing config by "CONFIG_USB_STRING_FETCH"
>>>>>>>
>>>>>>> Changes for V3:
>>>>>>>        - Removed extra new line
>>>>>>>        - Explained "CONFIG_USB_STRING_FETCH" in top level README
>>>>>>>
>>>>>>>     README                          |    4 ++++
>>>>>>>     common/usb.c                    |    4 ++++
>>>>>>>     include/configs/tegra2-common.h |    2 ++
>>>>>>>     3 files changed, 10 insertions(+), 0 deletions(-)
>>>>>>>
>>>>>>> diff --git a/README b/README
>>>>>>> index 7adf7c7..c045a37 100644
>>>>>>> --- a/README
>>>>>>> +++ b/README
>>>>>>>
>>>>>>> @@ -1138,6 +1138,10 @@ The following options need to be configured:
>>>>>>>     		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
>>>>>>>     		txfilltuning field in the EHCI controller on reset.
>>>>>>>
>>>>>>> +		CONFIG_USB_STRING_FETCH
>>>>>>> +		Enables settings to USB core to handle string issues
>> which
>>
>>>>>>> +		few devices can not handle.
>>>>>>> +
>>>>>>>
>>>>>>>     - USB Device:
>>>>>>>     		Define the below if you wish to use the USB console.
>>>>>>>     		Once firmware is rebuilt from a serial console issue the
>>>>>>>
>>>>>>> diff --git a/common/usb.c b/common/usb.c
>>>>>>> index 191bc5b..a73cb60 100644
>>>>>>> --- a/common/usb.c
>>>>>>> +++ b/common/usb.c
>>>>>>> @@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device
>>>>>>> *dev, unsigned int langid, {
>>>>>>>
>>>>>>>     	int rc;
>>>>>>>
>>>>>>> +#ifdef CONFIG_USB_STRING_FETCH
>>>>>> Shouldn't this be something like ... CONFIG_USB_AVOID_STRING_FETCH
>>>>>> then?
>>>>>>
>>>>>> Anyway, how come some devices can't handle it? What happens then?
>>>>>> What devices are those (exact type etc)?
>>>>>>
>>>>>> I believe the bug is deeper and adding extra config options can be
>>>>>> avoided, what do you think?
>>>>>>
>>>>>> Thanks!
>>>>>>
>>>>>> M
>>>>> It does not avoid string fetch.
>>>> Well it does certainly not call usb_get_string()
>>> Precisely, it avoids fetching string desc of 255 bytes. so better name
>>> could be
>>> "CONFIG_USB_AVOID_STRING_FETCH_255".  Thanks for your comment.
>>>
>>>>> I checked with few mass storage devices that they does not handle
>>>>> string descriptor request correctly and so we get
>>>>> start/stop Cache alignment error.
>>>> Cache alignment error ? Wow, how's that actually related to SUB string
>>>> fetching? Maybe we should manually realign the result then? I still
>>>> don't really understand what you're seeing, sorry ... can you please
>>>> elaborate?
>>> The particular mass storage device is -
>>>
>>> Vendor: Kingston Rev: PMAP Prod: DataTraveler 2.0
>>>
>>> Type: Removable Hard Disk
>>>
>>> Capacity: 1906.0 MB = 1.8 GB (3903488 x 512)
>>>
>>> When code tries to read Manufacturing Id..prod id...etc..it passes cache
>>> aligned buffer "tbuf" in
>>> "usb_string()" @usb.c. Inside "usb_string_sub()", usb_get_string()
>>> passes as default 255 bytes to fetch string
>>> descriptor.
>>> The code in "ehci_submit_async() " invalidates *partially* the passed
>>> buffer though we pass aligned buffer and "STD_ASS"
>>> is received. Though it should invalidate only the cached line which is
>>> equal(~32)  to string desc length.
>> Hm ... so this means the bug is in ehci_hcd? Maybe the ehci_hcd should be
>> fixed to correctly handle caches then?
>>
>>> If we give delay of 1 ms after handshake() the cache alignment warning
>>> does not spew...but delay of 1 ms is not acceptable.
>>> So I enabled the code to fetch first string desc length and then fetch
>>> string desc fetch, in this way the issue is resolved.
>>> It makes sense also to fetch string desc length and then actual string
>>> desc....
>> I see, I  understand now just about everything but the ehci problem, see
>> above. Your explanation was very helpful.
>>
>> Let's work this out together!
>>
>> Cheers!
>>
>> M
> Is this issue fixed or is this patch still needed? Thanks in advance!
This issue is not fixed and still need a patch to fix root cause, 
explained above.
Note that this issue is observed even though we pass aligned address and
expects something from the device.
> Best regards,
> Marek Vasut
Thanx & Regards,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v5] usb: align buffers at cacheline
  2012-03-05  7:16                                             ` [U-Boot] [PATCH v5] " Puneet Saxena
@ 2012-03-05 13:24                                               ` Eric Nelson
  2012-03-05 13:35                                                 ` Marek Vasut
  2012-03-05 14:46                                                 ` [U-Boot] [PATCH v8] " Puneet Saxena
  0 siblings, 2 replies; 83+ messages in thread
From: Eric Nelson @ 2012-03-05 13:24 UTC (permalink / raw)
  To: u-boot

On 03/05/2012 12:16 AM, Puneet Saxena wrote:
> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
>
> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> ---
> Changes for V4:
>      - Added memcpy to copy local descriptor to global descriptor.
>        Without that, USB version, class, vendor, product Id...etc is not configured.
>        This information is useful for loading correct device driver and possible
>        configuration.
>
> Changes for V5:
>      - Aligned "usb_device_descriptor" using ARCH_DMA_MINALIGN
>
>   common/cmd_usb.c            |    3 +-
>   common/usb.c                |   54 ++++++++++++++++++++++-----------------
>   common/usb_storage.c        |   59 ++++++++++++++++++++----------------------
>   disk/part_dos.c             |    2 +-
>   drivers/usb/host/ehci-hcd.c |    8 ++++++
>   include/scsi.h              |    4 ++-
>   include/usb.h               |    6 +++-
>   7 files changed, 76 insertions(+), 60 deletions(-)
>
> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> index 320667f..bca9d94 100644
> --- a/common/cmd_usb.c
> +++ b/common/cmd_usb.c
> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
>
>   void usb_display_string(struct usb_device *dev, int index)
>   {
> -	char buffer[256];
> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> +
>   	if (index != 0) {
>   		if (usb_string(dev, index,&buffer[0], 256)>  0)
>   			printf("String: \"%s\"", buffer);
> diff --git a/common/usb.c b/common/usb.c
> index 6e21ae2..3005012 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>   static int dev_index;
>   static int running;
>   static int asynch_allowed;
> -static struct devrequest setup_packet;
>
>   char usb_started; /* flag for the started/stopped USB status */
>
> @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
>   			unsigned short value, unsigned short index,
>   			void *data, unsigned short size, int timeout)
>   {
> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> +		sizeof(struct devrequest));

sizeof(struct devrequest) should be 1, right?

See comment for usage:
	http://git.denx.de/?p=u-boot.git;a=blob;f=include/common.h;h=a2c6b27d43cce33d1a00a033e4b33c895c4e1d8d;hb=HEAD#l904

>   	if ((timeout == 0)&&  (!asynch_allowed)) {
>   		/* request for a asynch control pipe is not allowed */
>   		return -1;
>   	}
>
>   	/* set setup command */
> -	setup_packet.requesttype = requesttype;
> -	setup_packet.request = request;
> -	setup_packet.value = cpu_to_le16(value);
> -	setup_packet.index = cpu_to_le16(index);
> -	setup_packet.length = cpu_to_le16(size);
> +	setup_packet->requesttype = requesttype;
> +	setup_packet->request = request;
> +	setup_packet->value = cpu_to_le16(value);
> +	setup_packet->index = cpu_to_le16(index);
> +	setup_packet->length = cpu_to_le16(size);
>   	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>   		   "value 0x%X index 0x%X length 0x%X\n",
>   		   request, requesttype, value, index, size);
>   	dev->status = USB_ST_NOT_PROC; /*not yet processed */
>
> -	submit_control_msg(dev, pipe, data, size,&setup_packet);
> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>   	if (timeout == 0)
>   		return (int)size;
>
> @@ -698,7 +699,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
>    */
>   int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>   {
> -	unsigned char mybuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>   	unsigned char *tbuf;
>   	int err;
>   	unsigned int u, idx;
> @@ -798,7 +799,7 @@ int usb_new_device(struct usb_device *dev)
>   {
>   	int addr, err;
>   	int tmp;
> -	unsigned char tmpbuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
>
>   	/* We still haven't set the Address yet */
>   	addr = dev->devnum;
> @@ -919,14 +920,18 @@ int usb_new_device(struct usb_device *dev)
>   				"(expected %i, got %i)\n", tmp, err);
>   		return 1;
>   	}
> +
> +	/* Now copy the local device descriptor to global device descriptor*/
> +	memcpy(&dev->descriptor, desc, sizeof(dev->descriptor));
> +
>   	/* correct le values */
>   	le16_to_cpus(&dev->descriptor.bcdUSB);
>   	le16_to_cpus(&dev->descriptor.idVendor);
>   	le16_to_cpus(&dev->descriptor.idProduct);
>   	le16_to_cpus(&dev->descriptor.bcdDevice);
>   	/* only support for one config for now */
> -	usb_get_configuration_no(dev,&tmpbuf[0], 0);
> -	usb_parse_config(dev,&tmpbuf[0], 0);
> +	usb_get_configuration_no(dev, tmpbuf, 0);
> +	usb_parse_config(dev, tmpbuf, 0);
>   	usb_set_maxpacket(dev);
>   	/* we set the default configuration here */
>   	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
> @@ -1080,7 +1085,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
>   			unsigned short *portstat)
>   {
>   	int tries;
> -	struct usb_port_status portsts;
> +	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>   	unsigned short portstatus, portchange;
>
>   	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
> @@ -1089,13 +1094,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
>   		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
>   		wait_ms(200);
>
> -		if (usb_get_port_status(dev, port + 1,&portsts)<  0) {
> +		if (usb_get_port_status(dev, port + 1, portsts)<  0) {
>   			USB_HUB_PRINTF("get_port_status failed status %lX\n",
>   					dev->status);
>   			return -1;
>   		}
> -		portstatus = le16_to_cpu(portsts.wPortStatus);
> -		portchange = le16_to_cpu(portsts.wPortChange);
> +		portstatus = le16_to_cpu(portsts->wPortStatus);
> +		portchange = le16_to_cpu(portsts->wPortChange);
>
>   		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
>   				portstatus, portchange,
> @@ -1133,19 +1138,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
>   void usb_hub_port_connect_change(struct usb_device *dev, int port)
>   {
>   	struct usb_device *usb;
> -	struct usb_port_status portsts;
> +	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>   	unsigned short portstatus;
>
>   	/* Check status */
> -	if (usb_get_port_status(dev, port + 1,&portsts)<  0) {
> +	if (usb_get_port_status(dev, port + 1, portsts)<  0) {
>   		USB_HUB_PRINTF("get_port_status failed\n");
>   		return;
>   	}
>
> -	portstatus = le16_to_cpu(portsts.wPortStatus);
> +	portstatus = le16_to_cpu(portsts->wPortStatus);
>   	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
>   			portstatus,
> -			le16_to_cpu(portsts.wPortChange),
> +			le16_to_cpu(portsts->wPortChange),
>   			portspeed(portstatus));
>
>   	/* Clear the connection change status */
> @@ -1194,7 +1199,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
>   int usb_hub_configure(struct usb_device *dev)
>   {
>   	int i;
> -	unsigned char buffer[USB_BUFSIZ], *bitmap;
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
> +	unsigned char *bitmap;
>   	struct usb_hub_descriptor *descriptor;
>   	struct usb_hub_device *hub;
>   #ifdef USB_HUB_DEBUG
> @@ -1316,16 +1322,16 @@ int usb_hub_configure(struct usb_device *dev)
>   	usb_hub_power_on(hub);
>
>   	for (i = 0; i<  dev->maxchild; i++) {
> -		struct usb_port_status portsts;
> +		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>   		unsigned short portstatus, portchange;
>
> -		if (usb_get_port_status(dev, i + 1,&portsts)<  0) {
> +		if (usb_get_port_status(dev, i + 1, portsts)<  0) {
>   			USB_HUB_PRINTF("get_port_status failed\n");
>   			continue;
>   		}
>
> -		portstatus = le16_to_cpu(portsts.wPortStatus);
> -		portchange = le16_to_cpu(portsts.wPortChange);
> +		portstatus = le16_to_cpu(portsts->wPortStatus);
> +		portchange = le16_to_cpu(portsts->wPortChange);
>   		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
>   				i + 1, portstatus, portchange);
>
> diff --git a/common/usb_storage.c b/common/usb_storage.c
> index de84c8d..88ca390 100644
> --- a/common/usb_storage.c
> +++ b/common/usb_storage.c
> @@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
>   };
>   #define US_DIRECTION(x) ((us_direction[x>>3]>>  (x&  7))&  1)
>
> -static unsigned char usb_stor_buf[512];
> -static ccb usb_ccb;
> +static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
>
>   /*
>    * CBI style
> @@ -210,17 +209,17 @@ int usb_stor_info(void)
>   static unsigned int usb_get_max_lun(struct us_data *us)
>   {
>   	int len;
> -	unsigned char result;
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
>   	len = usb_control_msg(us->pusb_dev,
>   			      usb_rcvctrlpipe(us->pusb_dev, 0),
>   			      US_BBB_GET_MAX_LUN,
>   			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
>   			      0, us->ifnum,
> -			&result, sizeof(result),
> +			      result, sizeof(char),
>   			      USB_CNTL_TIMEOUT * 5);
>   	USB_STOR_PRINTF("Get Max LUN ->  len = %i, result = %i\n",
> -			len, (int) result);
> -	return (len>  0) ? result : 0;
> +			len, (int) *result);
> +	return (len>  0) ? *result : 0;
>   }
>
>   /*******************************************************************************
> @@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
>   	unsigned char i;
>   	struct usb_device *dev;
>
> -	/* GJ */
> -	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
> -
>   	if (mode == 1)
>   		printf("       scanning bus for storage devices... ");
>
> @@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
>   	int actlen;
>   	int dir_in;
>   	unsigned int pipe;
> -	umass_bbb_cbw_t cbw;
> +	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
>
>   	dir_in = US_DIRECTION(srb->cmd[0]);
>
> @@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
>   	/* always OUT to the ep */
>   	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
>
> -	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
> -	cbw.dCBWTag = cpu_to_le32(CBWTag++);
> -	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
> -	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
> -	cbw.bCBWLUN = srb->lun;
> -	cbw.bCDBLength = srb->cmdlen;
> +	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
> +	cbw->dCBWTag = cpu_to_le32(CBWTag++);
> +	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
> +	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
> +	cbw->bCBWLUN = srb->lun;
> +	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,
> +	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);
>   	if (result<  0)
>   		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
> @@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
>   	int dir_in;
>   	int actlen, data_actlen;
>   	unsigned int pipe, pipein, pipeout;
> -	umass_bbb_csw_t csw;
> +	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
>   #ifdef BBB_XPORT_TRACE
>   	unsigned char *ptr;
>   	int index;
> @@ -733,7 +729,7 @@ st:
>   	retry = 0;
>   again:
>   	USB_STOR_PRINTF("STATUS phase\n");
> -	result = usb_bulk_msg(us->pusb_dev, pipein,&csw, UMASS_BBB_CSW_SIZE,
> +	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
>   				&actlen, USB_CNTL_TIMEOUT*5);
>
>   	/* special handling of STALL in STATUS phase */
> @@ -753,28 +749,28 @@ again:
>   		return USB_STOR_TRANSPORT_FAILED;
>   	}
>   #ifdef BBB_XPORT_TRACE
> -	ptr = (unsigned char *)&csw;
> +	ptr = (unsigned char *)csw;
>   	for (index = 0; index<  UMASS_BBB_CSW_SIZE; index++)
>   		printf("ptr[%d] %#x ", index, ptr[index]);
>   	printf("\n");
>   #endif
>   	/* misuse pipe to get the residue */
> -	pipe = le32_to_cpu(csw.dCSWDataResidue);
> +	pipe = le32_to_cpu(csw->dCSWDataResidue);
>   	if (pipe == 0&&  srb->datalen != 0&&  srb->datalen - data_actlen != 0)
>   		pipe = srb->datalen - data_actlen;
> -	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
> +	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
>   		USB_STOR_PRINTF("!CSWSIGNATURE\n");
>   		usb_stor_BBB_reset(us);
>   		return USB_STOR_TRANSPORT_FAILED;
> -	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
> +	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
>   		USB_STOR_PRINTF("!Tag\n");
>   		usb_stor_BBB_reset(us);
>   		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus>  CSWSTATUS_PHASE) {
> +	} else if (csw->bCSWStatus>  CSWSTATUS_PHASE) {
>   		USB_STOR_PRINTF(">PHASE\n");
>   		usb_stor_BBB_reset(us);
>   		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
> +	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
>   		USB_STOR_PRINTF("=PHASE\n");
>   		usb_stor_BBB_reset(us);
>   		return USB_STOR_TRANSPORT_FAILED;
> @@ -782,7 +778,7 @@ again:
>   		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
>   			data_actlen, srb->datalen);
>   		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
> +	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
>   		USB_STOR_PRINTF("FAILED\n");
>   		return USB_STOR_TRANSPORT_FAILED;
>   	}
> @@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
>   		      block_dev_desc_t *dev_desc)
>   {
>   	unsigned char perq, modi;
> -	unsigned long cap[2];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
>   	unsigned long *capacity, *blksz;
>   	ccb *pccb =&usb_ccb;
>
> @@ -1367,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],&usb_stor_buf[8], 8);
> -	memcpy(&dev_desc->product[0],&usb_stor_buf[16], 16);
> -	memcpy(&dev_desc->revision[0],&usb_stor_buf[32], 4);
> +	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);
>   	dev_desc->vendor[8] = 0;
>   	dev_desc->product[16] = 0;
>   	dev_desc->revision[4] = 0;
> diff --git a/disk/part_dos.c b/disk/part_dos.c
> index b5bcb37..70211ee 100644
> --- a/disk/part_dos.c
> +++ b/disk/part_dos.c
> @@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
>
>   int test_part_dos (block_dev_desc_t *dev_desc)
>   {
> -	unsigned char buffer[dev_desc->blksz];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
>
>   	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
>   	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index d893b2a..eb5220b 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -120,6 +120,14 @@ static struct descriptor {
>    */
>   static void flush_invalidate(u32 addr, int size, int flush)
>   {
> +	/*
> +	 * Size is the bytes actually moved during transaction,
> +	 * which may not equal to the cache line. This results
> +	 * stop address passed for invalidating cache may not be aligned.
> +	 * Therfore making size as multiple of cache line size.
> +	 */
> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> +
>   	if (flush)
>   		flush_dcache_range(addr, addr + size);
>   	else
> diff --git a/include/scsi.h b/include/scsi.h
> index c52759c..89ae45f 100644
> --- a/include/scsi.h
> +++ b/include/scsi.h
> @@ -26,7 +26,9 @@
>
>   typedef struct SCSI_cmd_block{
>   	unsigned char		cmd[16];					/* command				   */
> -	unsigned char		sense_buf[64];		/* for request sense */
> +	/* for request sense */
> +	unsigned char		sense_buf[64]
> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
>   	unsigned char		status;						/* SCSI Status			 */
>   	unsigned char		target;						/* Target ID				 */
>   	unsigned char		lun;							/* Target LUN        */
> diff --git a/include/usb.h b/include/usb.h
> index 06170cd..8c082c1 100644
> --- a/include/usb.h
> +++ b/include/usb.h
> @@ -109,9 +109,11 @@ struct usb_device {
>   	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
>
>   	int configno;			/* selected config number */
> -	struct usb_device_descriptor descriptor; /* Device Descriptor */
> -	struct usb_config config; /* config descriptor */
> +	/* Device Descriptor */
> +	struct usb_device_descriptor descriptor
> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
>
> +	struct usb_config config; /* config descriptor */
>   	int have_langid;		/* whether string_langid is valid yet */
>   	int string_langid;		/* language ID for strings */
>   	int (*irq_handle)(struct usb_device *dev);

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v5] usb: align buffers at cacheline
  2012-03-05 13:24                                               ` Eric Nelson
@ 2012-03-05 13:35                                                 ` Marek Vasut
  2012-03-05 14:46                                                 ` [U-Boot] [PATCH v8] " Puneet Saxena
  1 sibling, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-03-05 13:35 UTC (permalink / raw)
  To: u-boot

Dear Eric Nelson,

> On 03/05/2012 12:16 AM, Puneet Saxena wrote:
> > As DMA expects the buffers to be equal and larger then
> > cache lines, This aligns buffers at cacheline.
> > 
> > Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> > ---
> > 
> > Changes for V4:
> >      - Added memcpy to copy local descriptor to global descriptor.
> >      
> >        Without that, USB version, class, vendor, product Id...etc is not
> >        configured. This information is useful for loading correct device
> >        driver and possible configuration.
> > 
> > Changes for V5:
> >      - Aligned "usb_device_descriptor" using ARCH_DMA_MINALIGN
> >   
> >   common/cmd_usb.c            |    3 +-
> >   common/usb.c                |   54
> >   ++++++++++++++++++++++----------------- common/usb_storage.c        | 
> >    59 ++++++++++++++++++++---------------------- disk/part_dos.c        
> >       |    2 +-
> >   drivers/usb/host/ehci-hcd.c |    8 ++++++
> >   include/scsi.h              |    4 ++-
> >   include/usb.h               |    6 +++-
> >   7 files changed, 76 insertions(+), 60 deletions(-)
> > 
> > diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> > index 320667f..bca9d94 100644
> > --- a/common/cmd_usb.c
> > +++ b/common/cmd_usb.c
> > @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> > unsigned char subclass,
> > 
> >   void usb_display_string(struct usb_device *dev, int index)
> >   {
> > 
> > -	char buffer[256];
> > +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> > +
> > 
> >   	if (index != 0) {
> >   	
> >   		if (usb_string(dev, index,&buffer[0], 256)>  0)
> >   		
> >   			printf("String: \"%s\"", buffer);
> > 
> > diff --git a/common/usb.c b/common/usb.c
> > index 6e21ae2..3005012 100644
> > --- a/common/usb.c
> > +++ b/common/usb.c
> > @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
> > 
> >   static int dev_index;
> >   static int running;
> >   static int asynch_allowed;
> > 
> > -static struct devrequest setup_packet;
> > 
> >   char usb_started; /* flag for the started/stopped USB status */
> > 
> > @@ -185,23 +184,25 @@ int usb_control_msg(struct usb_device *dev,
> > unsigned int pipe,
> > 
> >   			unsigned short value, unsigned short index,
> >   			void *data, unsigned short size, int timeout)
> >   
> >   {
> > 
> > +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet,
> > +		sizeof(struct devrequest));
> 
> sizeof(struct devrequest) should be 1, right?
> 
> See comment for usage:
> 	http://git.denx.de/?p=u-
boot.git;a=blob;f=include/common.h;h=a2c6b27d43cce
> 33d1a00a033e4b33c895c4e1d8d;hb=HEAD#l904

Oh! Nice catch :)

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-05 13:24                                               ` Eric Nelson
  2012-03-05 13:35                                                 ` Marek Vasut
@ 2012-03-05 14:46                                                 ` Puneet Saxena
  2012-03-05 15:35                                                   ` Marek Vasut
                                                                     ` (2 more replies)
  1 sibling, 3 replies; 83+ messages in thread
From: Puneet Saxena @ 2012-03-05 14:46 UTC (permalink / raw)
  To: u-boot

As DMA expects the buffers to be equal and larger then
cache lines, This aligns buffers at cacheline.

Signed-off-by: Puneet Saxena <puneets@nvidia.com>
---

Changes for V7:
    - Trivial change, missed removing memcpy. Removed now.
Changes for V8:
    - Corrected "setup_packet" allocation using "ALLOC_CACHE_ALIGN_BUFFER". 

 common/cmd_usb.c            |    3 +-
 common/usb.c                |   49 ++++++++++++++++++-----------------
 common/usb_storage.c        |   59 ++++++++++++++++++++----------------------
 disk/part_dos.c             |    2 +-
 drivers/usb/host/ehci-hcd.c |    8 ++++++
 include/scsi.h              |    4 ++-
 include/usb.h               |    4 ++-
 7 files changed, 70 insertions(+), 59 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 320667f..bca9d94 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
 
 void usb_display_string(struct usb_device *dev, int index)
 {
-	char buffer[256];
+	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
+
 	if (index != 0) {
 		if (usb_string(dev, index, &buffer[0], 256) > 0)
 			printf("String: \"%s\"", buffer);
diff --git a/common/usb.c b/common/usb.c
index 6e21ae2..e3db7bc 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
 static int dev_index;
 static int running;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 char usb_started; /* flag for the started/stopped USB status */
 
@@ -185,23 +184,24 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 			unsigned short value, unsigned short index,
 			void *data, unsigned short size, int timeout)
 {
+	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1);
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
 		return -1;
 	}
 
 	/* set setup command */
-	setup_packet.requesttype = requesttype;
-	setup_packet.request = request;
-	setup_packet.value = cpu_to_le16(value);
-	setup_packet.index = cpu_to_le16(index);
-	setup_packet.length = cpu_to_le16(size);
+	setup_packet->requesttype = requesttype;
+	setup_packet->request = request;
+	setup_packet->value = cpu_to_le16(value);
+	setup_packet->index = cpu_to_le16(index);
+	setup_packet->length = cpu_to_le16(size);
 	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
 		   "value 0x%X index 0x%X length 0x%X\n",
 		   request, requesttype, value, index, size);
 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-	submit_control_msg(dev, pipe, data, size, &setup_packet);
+	submit_control_msg(dev, pipe, data, size, setup_packet);
 	if (timeout == 0)
 		return (int)size;
 
@@ -698,7 +698,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
  */
 int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
 {
-	unsigned char mybuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
 	unsigned char *tbuf;
 	int err;
 	unsigned int u, idx;
@@ -798,7 +798,7 @@ int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
 
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
@@ -925,8 +925,8 @@ int usb_new_device(struct usb_device *dev)
 	le16_to_cpus(&dev->descriptor.idProduct);
 	le16_to_cpus(&dev->descriptor.bcdDevice);
 	/* only support for one config for now */
-	usb_get_configuration_no(dev, &tmpbuf[0], 0);
-	usb_parse_config(dev, &tmpbuf[0], 0);
+	usb_get_configuration_no(dev, tmpbuf, 0);
+	usb_parse_config(dev, tmpbuf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
@@ -1080,7 +1080,7 @@ static int hub_port_reset(struct usb_device *dev, int port,
 			unsigned short *portstat)
 {
 	int tries;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus, portchange;
 
 	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
@@ -1089,13 +1089,13 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
 		wait_ms(200);
 
-		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed status %lX\n",
 					dev->status);
 			return -1;
 		}
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 
 		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 				portstatus, portchange,
@@ -1133,19 +1133,19 @@ static int hub_port_reset(struct usb_device *dev, int port,
 void usb_hub_port_connect_change(struct usb_device *dev, int port)
 {
 	struct usb_device *usb;
-	struct usb_port_status portsts;
+	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 	unsigned short portstatus;
 
 	/* Check status */
-	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
+	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
 		USB_HUB_PRINTF("get_port_status failed\n");
 		return;
 	}
 
-	portstatus = le16_to_cpu(portsts.wPortStatus);
+	portstatus = le16_to_cpu(portsts->wPortStatus);
 	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
 			portstatus,
-			le16_to_cpu(portsts.wPortChange),
+			le16_to_cpu(portsts->wPortChange),
 			portspeed(portstatus));
 
 	/* Clear the connection change status */
@@ -1194,7 +1194,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 int usb_hub_configure(struct usb_device *dev)
 {
 	int i;
-	unsigned char buffer[USB_BUFSIZ], *bitmap;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
+	unsigned char *bitmap;
 	struct usb_hub_descriptor *descriptor;
 	struct usb_hub_device *hub;
 #ifdef USB_HUB_DEBUG
@@ -1316,16 +1317,16 @@ int usb_hub_configure(struct usb_device *dev)
 	usb_hub_power_on(hub);
 
 	for (i = 0; i < dev->maxchild; i++) {
-		struct usb_port_status portsts;
+		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
 
-		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
 			USB_HUB_PRINTF("get_port_status failed\n");
 			continue;
 		}
 
-		portstatus = le16_to_cpu(portsts.wPortStatus);
-		portchange = le16_to_cpu(portsts.wPortChange);
+		portstatus = le16_to_cpu(portsts->wPortStatus);
+		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 
diff --git a/common/usb_storage.c b/common/usb_storage.c
index de84c8d..88ca390 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
 };
 #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
 
-static unsigned char usb_stor_buf[512];
-static ccb usb_ccb;
+static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
 
 /*
  * CBI style
@@ -210,17 +209,17 @@ int usb_stor_info(void)
 static unsigned int usb_get_max_lun(struct us_data *us)
 {
 	int len;
-	unsigned char result;
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
 	len = usb_control_msg(us->pusb_dev,
 			      usb_rcvctrlpipe(us->pusb_dev, 0),
 			      US_BBB_GET_MAX_LUN,
 			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
 			      0, us->ifnum,
-			      &result, sizeof(result),
+			      result, sizeof(char),
 			      USB_CNTL_TIMEOUT * 5);
 	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
-			len, (int) result);
-	return (len > 0) ? result : 0;
+			len, (int) *result);
+	return (len > 0) ? *result : 0;
 }
 
 /*******************************************************************************
@@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
 	unsigned char i;
 	struct usb_device *dev;
 
-	/* GJ */
-	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
-
 	if (mode == 1)
 		printf("       scanning bus for storage devices... ");
 
@@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	int actlen;
 	int dir_in;
 	unsigned int pipe;
-	umass_bbb_cbw_t cbw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
 
 	dir_in = US_DIRECTION(srb->cmd[0]);
 
@@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
 	/* always OUT to the ep */
 	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
 
-	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
-	cbw.dCBWTag = cpu_to_le32(CBWTag++);
-	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
-	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
-	cbw.bCBWLUN = srb->lun;
-	cbw.bCDBLength = srb->cmdlen;
+	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
+	cbw->dCBWTag = cpu_to_le32(CBWTag++);
+	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
+	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
+	cbw->bCBWLUN = srb->lun;
+	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,
+	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);
 	if (result < 0)
 		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
@@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
 	int dir_in;
 	int actlen, data_actlen;
 	unsigned int pipe, pipein, pipeout;
-	umass_bbb_csw_t csw;
+	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
 #ifdef BBB_XPORT_TRACE
 	unsigned char *ptr;
 	int index;
@@ -733,7 +729,7 @@ st:
 	retry = 0;
 again:
 	USB_STOR_PRINTF("STATUS phase\n");
-	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
+	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
 				&actlen, USB_CNTL_TIMEOUT*5);
 
 	/* special handling of STALL in STATUS phase */
@@ -753,28 +749,28 @@ again:
 		return USB_STOR_TRANSPORT_FAILED;
 	}
 #ifdef BBB_XPORT_TRACE
-	ptr = (unsigned char *)&csw;
+	ptr = (unsigned char *)csw;
 	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
 		printf("ptr[%d] %#x ", index, ptr[index]);
 	printf("\n");
 #endif
 	/* misuse pipe to get the residue */
-	pipe = le32_to_cpu(csw.dCSWDataResidue);
+	pipe = le32_to_cpu(csw->dCSWDataResidue);
 	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
 		pipe = srb->datalen - data_actlen;
-	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
+	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
 		USB_STOR_PRINTF("!CSWSIGNATURE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
+	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
 		USB_STOR_PRINTF("!Tag\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF(">PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
+	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
 		USB_STOR_PRINTF("=PHASE\n");
 		usb_stor_BBB_reset(us);
 		return USB_STOR_TRANSPORT_FAILED;
@@ -782,7 +778,7 @@ again:
 		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
 			data_actlen, srb->datalen);
 		return USB_STOR_TRANSPORT_FAILED;
-	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
+	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
 		USB_STOR_PRINTF("FAILED\n");
 		return USB_STOR_TRANSPORT_FAILED;
 	}
@@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 		      block_dev_desc_t *dev_desc)
 {
 	unsigned char perq, modi;
-	unsigned long cap[2];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
 	unsigned long *capacity, *blksz;
 	ccb *pccb = &usb_ccb;
 
@@ -1367,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], &usb_stor_buf[8], 8);
-	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
-	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+	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);
 	dev_desc->vendor[8] = 0;
 	dev_desc->product[16] = 0;
 	dev_desc->revision[4] = 0;
diff --git a/disk/part_dos.c b/disk/part_dos.c
index b5bcb37..70211ee 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
 
 int test_part_dos (block_dev_desc_t *dev_desc)
 {
-	unsigned char buffer[dev_desc->blksz];
+	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
 
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d893b2a..eb5220b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,6 +120,14 @@ static struct descriptor {
  */
 static void flush_invalidate(u32 addr, int size, int flush)
 {
+	/*
+	 * Size is the bytes actually moved during transaction,
+	 * which may not equal to the cache line. This results
+	 * stop address passed for invalidating cache may not be aligned.
+	 * Therfore making size as multiple of cache line size.
+	 */
+	size = ALIGN(size, ARCH_DMA_MINALIGN);
+
 	if (flush)
 		flush_dcache_range(addr, addr + size);
 	else
diff --git a/include/scsi.h b/include/scsi.h
index c52759c..89ae45f 100644
--- a/include/scsi.h
+++ b/include/scsi.h
@@ -26,7 +26,9 @@
 
 typedef struct SCSI_cmd_block{
 	unsigned char		cmd[16];					/* command				   */
-	unsigned char		sense_buf[64];		/* for request sense */
+	/* for request sense */
+	unsigned char		sense_buf[64]
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	unsigned char		status;						/* SCSI Status			 */
 	unsigned char		target;						/* Target ID				 */
 	unsigned char		lun;							/* Target LUN        */
diff --git a/include/usb.h b/include/usb.h
index 06170cd..5f4f110 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -109,7 +109,9 @@ struct usb_device {
 	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	int configno;			/* selected config number */
-	struct usb_device_descriptor descriptor; /* Device Descriptor */
+	/* Device Descriptor */
+	struct usb_device_descriptor descriptor
+		__attribute__((aligned(ARCH_DMA_MINALIGN)));
 	struct usb_config config; /* config descriptor */
 
 	int have_langid;		/* whether string_langid is valid yet */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-05 14:46                                                 ` [U-Boot] [PATCH v8] " Puneet Saxena
@ 2012-03-05 15:35                                                   ` Marek Vasut
  2012-03-05 18:18                                                   ` Simon Glass
  2012-03-06  3:07                                                   ` Mike Frysinger
  2 siblings, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-03-05 15:35 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

I replaced the old patch with this one. Thanks!

> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
> 
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> ---
> 
> Changes for V7:
>     - Trivial change, missed removing memcpy. Removed now.
> Changes for V8:
>     - Corrected "setup_packet" allocation using "ALLOC_CACHE_ALIGN_BUFFER".
> 
>  common/cmd_usb.c            |    3 +-
>  common/usb.c                |   49 ++++++++++++++++++-----------------
>  common/usb_storage.c        |   59
> ++++++++++++++++++++---------------------- disk/part_dos.c             |  
>  2 +-
>  drivers/usb/host/ehci-hcd.c |    8 ++++++
>  include/scsi.h              |    4 ++-
>  include/usb.h               |    4 ++-
>  7 files changed, 70 insertions(+), 59 deletions(-)
> 
> diff --git a/common/cmd_usb.c b/common/cmd_usb.c
> index 320667f..bca9d94 100644
> --- a/common/cmd_usb.c
> +++ b/common/cmd_usb.c
> @@ -150,7 +150,8 @@ void usb_display_class_sub(unsigned char dclass,
> unsigned char subclass,
> 
>  void usb_display_string(struct usb_device *dev, int index)
>  {
> -	char buffer[256];
> +	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
> +
>  	if (index != 0) {
>  		if (usb_string(dev, index, &buffer[0], 256) > 0)
>  			printf("String: \"%s\"", buffer);
> diff --git a/common/usb.c b/common/usb.c
> index 6e21ae2..e3db7bc 100644
> --- a/common/usb.c
> +++ b/common/usb.c
> @@ -73,7 +73,6 @@ static struct usb_device usb_dev[USB_MAX_DEVICE];
>  static int dev_index;
>  static int running;
>  static int asynch_allowed;
> -static struct devrequest setup_packet;
> 
>  char usb_started; /* flag for the started/stopped USB status */
> 
> @@ -185,23 +184,24 @@ int usb_control_msg(struct usb_device *dev, unsigned
> int pipe, unsigned short value, unsigned short index,
>  			void *data, unsigned short size, int timeout)
>  {
> +	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1);
>  	if ((timeout == 0) && (!asynch_allowed)) {
>  		/* request for a asynch control pipe is not allowed */
>  		return -1;
>  	}
> 
>  	/* set setup command */
> -	setup_packet.requesttype = requesttype;
> -	setup_packet.request = request;
> -	setup_packet.value = cpu_to_le16(value);
> -	setup_packet.index = cpu_to_le16(index);
> -	setup_packet.length = cpu_to_le16(size);
> +	setup_packet->requesttype = requesttype;
> +	setup_packet->request = request;
> +	setup_packet->value = cpu_to_le16(value);
> +	setup_packet->index = cpu_to_le16(index);
> +	setup_packet->length = cpu_to_le16(size);
>  	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
>  		   "value 0x%X index 0x%X length 0x%X\n",
>  		   request, requesttype, value, index, size);
>  	dev->status = USB_ST_NOT_PROC; /*not yet processed */
> 
> -	submit_control_msg(dev, pipe, data, size, &setup_packet);
> +	submit_control_msg(dev, pipe, data, size, setup_packet);
>  	if (timeout == 0)
>  		return (int)size;
> 
> @@ -698,7 +698,7 @@ static int usb_string_sub(struct usb_device *dev,
> unsigned int langid, */
>  int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
>  {
> -	unsigned char mybuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
>  	unsigned char *tbuf;
>  	int err;
>  	unsigned int u, idx;
> @@ -798,7 +798,7 @@ int usb_new_device(struct usb_device *dev)
>  {
>  	int addr, err;
>  	int tmp;
> -	unsigned char tmpbuf[USB_BUFSIZ];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
> 
>  	/* We still haven't set the Address yet */
>  	addr = dev->devnum;
> @@ -925,8 +925,8 @@ int usb_new_device(struct usb_device *dev)
>  	le16_to_cpus(&dev->descriptor.idProduct);
>  	le16_to_cpus(&dev->descriptor.bcdDevice);
>  	/* only support for one config for now */
> -	usb_get_configuration_no(dev, &tmpbuf[0], 0);
> -	usb_parse_config(dev, &tmpbuf[0], 0);
> +	usb_get_configuration_no(dev, tmpbuf, 0);
> +	usb_parse_config(dev, tmpbuf, 0);
>  	usb_set_maxpacket(dev);
>  	/* we set the default configuration here */
>  	if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
> @@ -1080,7 +1080,7 @@ static int hub_port_reset(struct usb_device *dev, int
> port, unsigned short *portstat)
>  {
>  	int tries;
> -	struct usb_port_status portsts;
> +	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>  	unsigned short portstatus, portchange;
> 
>  	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port);
> @@ -1089,13 +1089,13 @@ static int hub_port_reset(struct usb_device *dev,
> int port, usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
>  		wait_ms(200);
> 
> -		if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
> +		if (usb_get_port_status(dev, port + 1, portsts) < 0) {
>  			USB_HUB_PRINTF("get_port_status failed status %lX\n",
>  					dev->status);
>  			return -1;
>  		}
> -		portstatus = le16_to_cpu(portsts.wPortStatus);
> -		portchange = le16_to_cpu(portsts.wPortChange);
> +		portstatus = le16_to_cpu(portsts->wPortStatus);
> +		portchange = le16_to_cpu(portsts->wPortChange);
> 
>  		USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
>  				portstatus, portchange,
> @@ -1133,19 +1133,19 @@ static int hub_port_reset(struct usb_device *dev,
> int port, void usb_hub_port_connect_change(struct usb_device *dev, int
> port) {
>  	struct usb_device *usb;
> -	struct usb_port_status portsts;
> +	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>  	unsigned short portstatus;
> 
>  	/* Check status */
> -	if (usb_get_port_status(dev, port + 1, &portsts) < 0) {
> +	if (usb_get_port_status(dev, port + 1, portsts) < 0) {
>  		USB_HUB_PRINTF("get_port_status failed\n");
>  		return;
>  	}
> 
> -	portstatus = le16_to_cpu(portsts.wPortStatus);
> +	portstatus = le16_to_cpu(portsts->wPortStatus);
>  	USB_HUB_PRINTF("portstatus %x, change %x, %s\n",
>  			portstatus,
> -			le16_to_cpu(portsts.wPortChange),
> +			le16_to_cpu(portsts->wPortChange),
>  			portspeed(portstatus));
> 
>  	/* Clear the connection change status */
> @@ -1194,7 +1194,8 @@ void usb_hub_port_connect_change(struct usb_device
> *dev, int port) int usb_hub_configure(struct usb_device *dev)
>  {
>  	int i;
> -	unsigned char buffer[USB_BUFSIZ], *bitmap;
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ);
> +	unsigned char *bitmap;
>  	struct usb_hub_descriptor *descriptor;
>  	struct usb_hub_device *hub;
>  #ifdef USB_HUB_DEBUG
> @@ -1316,16 +1317,16 @@ int usb_hub_configure(struct usb_device *dev)
>  	usb_hub_power_on(hub);
> 
>  	for (i = 0; i < dev->maxchild; i++) {
> -		struct usb_port_status portsts;
> +		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
>  		unsigned short portstatus, portchange;
> 
> -		if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
> +		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
>  			USB_HUB_PRINTF("get_port_status failed\n");
>  			continue;
>  		}
> 
> -		portstatus = le16_to_cpu(portsts.wPortStatus);
> -		portchange = le16_to_cpu(portsts.wPortChange);
> +		portstatus = le16_to_cpu(portsts->wPortStatus);
> +		portchange = le16_to_cpu(portsts->wPortChange);
>  		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
>  				i + 1, portstatus, portchange);
> 
> diff --git a/common/usb_storage.c b/common/usb_storage.c
> index de84c8d..88ca390 100644
> --- a/common/usb_storage.c
> +++ b/common/usb_storage.c
> @@ -79,8 +79,7 @@ static const unsigned char us_direction[256/8] = {
>  };
>  #define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
> 
> -static unsigned char usb_stor_buf[512];
> -static ccb usb_ccb;
> +static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
> 
>  /*
>   * CBI style
> @@ -210,17 +209,17 @@ int usb_stor_info(void)
>  static unsigned int usb_get_max_lun(struct us_data *us)
>  {
>  	int len;
> -	unsigned char result;
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, result, 1);
>  	len = usb_control_msg(us->pusb_dev,
>  			      usb_rcvctrlpipe(us->pusb_dev, 0),
>  			      US_BBB_GET_MAX_LUN,
>  			      USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
>  			      0, us->ifnum,
> -			      &result, sizeof(result),
> +			      result, sizeof(char),
>  			      USB_CNTL_TIMEOUT * 5);
>  	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n",
> -			len, (int) result);
> -	return (len > 0) ? result : 0;
> +			len, (int) *result);
> +	return (len > 0) ? *result : 0;
>  }
> 
>  /*************************************************************************
> ****** @@ -233,9 +232,6 @@ int usb_stor_scan(int mode)
>  	unsigned char i;
>  	struct usb_device *dev;
> 
> -	/* GJ */
> -	memset(usb_stor_buf, 0, sizeof(usb_stor_buf));
> -
>  	if (mode == 1)
>  		printf("       scanning bus for storage devices... ");
> 
> @@ -499,7 +495,7 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
>  	int actlen;
>  	int dir_in;
>  	unsigned int pipe;
> -	umass_bbb_cbw_t cbw;
> +	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
> 
>  	dir_in = US_DIRECTION(srb->cmd[0]);
> 
> @@ -522,16 +518,16 @@ int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
>  	/* always OUT to the ep */
>  	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);
> 
> -	cbw.dCBWSignature = cpu_to_le32(CBWSIGNATURE);
> -	cbw.dCBWTag = cpu_to_le32(CBWTag++);
> -	cbw.dCBWDataTransferLength = cpu_to_le32(srb->datalen);
> -	cbw.bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
> -	cbw.bCBWLUN = srb->lun;
> -	cbw.bCDBLength = srb->cmdlen;
> +	cbw->dCBWSignature = cpu_to_le32(CBWSIGNATURE);
> +	cbw->dCBWTag = cpu_to_le32(CBWTag++);
> +	cbw->dCBWDataTransferLength = cpu_to_le32(srb->datalen);
> +	cbw->bCBWFlags = (dir_in ? CBWFLAGS_IN : CBWFLAGS_OUT);
> +	cbw->bCBWLUN = srb->lun;
> +	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,
> +	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);
>  	if (result < 0)
>  		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n");
> @@ -675,7 +671,7 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data
> *us) int dir_in;
>  	int actlen, data_actlen;
>  	unsigned int pipe, pipein, pipeout;
> -	umass_bbb_csw_t csw;
> +	ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
>  #ifdef BBB_XPORT_TRACE
>  	unsigned char *ptr;
>  	int index;
> @@ -733,7 +729,7 @@ st:
>  	retry = 0;
>  again:
>  	USB_STOR_PRINTF("STATUS phase\n");
> -	result = usb_bulk_msg(us->pusb_dev, pipein, &csw, UMASS_BBB_CSW_SIZE,
> +	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,
>  				&actlen, USB_CNTL_TIMEOUT*5);
> 
>  	/* special handling of STALL in STATUS phase */
> @@ -753,28 +749,28 @@ again:
>  		return USB_STOR_TRANSPORT_FAILED;
>  	}
>  #ifdef BBB_XPORT_TRACE
> -	ptr = (unsigned char *)&csw;
> +	ptr = (unsigned char *)csw;
>  	for (index = 0; index < UMASS_BBB_CSW_SIZE; index++)
>  		printf("ptr[%d] %#x ", index, ptr[index]);
>  	printf("\n");
>  #endif
>  	/* misuse pipe to get the residue */
> -	pipe = le32_to_cpu(csw.dCSWDataResidue);
> +	pipe = le32_to_cpu(csw->dCSWDataResidue);
>  	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)
>  		pipe = srb->datalen - data_actlen;
> -	if (CSWSIGNATURE != le32_to_cpu(csw.dCSWSignature)) {
> +	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) {
>  		USB_STOR_PRINTF("!CSWSIGNATURE\n");
>  		usb_stor_BBB_reset(us);
>  		return USB_STOR_TRANSPORT_FAILED;
> -	} else if ((CBWTag - 1) != le32_to_cpu(csw.dCSWTag)) {
> +	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) {
>  		USB_STOR_PRINTF("!Tag\n");
>  		usb_stor_BBB_reset(us);
>  		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus > CSWSTATUS_PHASE) {
> +	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) {
>  		USB_STOR_PRINTF(">PHASE\n");
>  		usb_stor_BBB_reset(us);
>  		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus == CSWSTATUS_PHASE) {
> +	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) {
>  		USB_STOR_PRINTF("=PHASE\n");
>  		usb_stor_BBB_reset(us);
>  		return USB_STOR_TRANSPORT_FAILED;
> @@ -782,7 +778,7 @@ again:
>  		USB_STOR_PRINTF("transferred %dB instead of %ldB\n",
>  			data_actlen, srb->datalen);
>  		return USB_STOR_TRANSPORT_FAILED;
> -	} else if (csw.bCSWStatus == CSWSTATUS_FAILED) {
> +	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) {
>  		USB_STOR_PRINTF("FAILED\n");
>  		return USB_STOR_TRANSPORT_FAILED;
>  	}
> @@ -1343,7 +1339,8 @@ int usb_stor_get_info(struct usb_device *dev, struct
> us_data *ss, block_dev_desc_t *dev_desc)
>  {
>  	unsigned char perq, modi;
> -	unsigned long cap[2];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned long, cap, 2);
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, usb_stor_buf, 36);
>  	unsigned long *capacity, *blksz;
>  	ccb *pccb = &usb_ccb;
> 
> @@ -1367,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], &usb_stor_buf[8], 8);
> -	memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
> -	memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
> +	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);
>  	dev_desc->vendor[8] = 0;
>  	dev_desc->product[16] = 0;
>  	dev_desc->revision[4] = 0;
> diff --git a/disk/part_dos.c b/disk/part_dos.c
> index b5bcb37..70211ee 100644
> --- a/disk/part_dos.c
> +++ b/disk/part_dos.c
> @@ -87,7 +87,7 @@ static int test_block_type(unsigned char *buffer)
> 
>  int test_part_dos (block_dev_desc_t *dev_desc)
>  {
> -	unsigned char buffer[dev_desc->blksz];
> +	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
> 
>  	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) 
||
>  	    (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index d893b2a..eb5220b 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -120,6 +120,14 @@ static struct descriptor {
>   */
>  static void flush_invalidate(u32 addr, int size, int flush)
>  {
> +	/*
> +	 * Size is the bytes actually moved during transaction,
> +	 * which may not equal to the cache line. This results
> +	 * stop address passed for invalidating cache may not be aligned.
> +	 * Therfore making size as multiple of cache line size.
> +	 */
> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> +
>  	if (flush)
>  		flush_dcache_range(addr, addr + size);
>  	else
> diff --git a/include/scsi.h b/include/scsi.h
> index c52759c..89ae45f 100644
> --- a/include/scsi.h
> +++ b/include/scsi.h
> @@ -26,7 +26,9 @@
> 
>  typedef struct SCSI_cmd_block{
>  	unsigned char		cmd[16];					
/* command				   */
> -	unsigned char		sense_buf[64];		/* for request sense */
> +	/* for request sense */
> +	unsigned char		sense_buf[64]
> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
>  	unsigned char		status;						
/* SCSI Status			 */
>  	unsigned char		target;						
/* Target ID				 */
>  	unsigned char		lun;							
/* Target LUN        */
> diff --git a/include/usb.h b/include/usb.h
> index 06170cd..5f4f110 100644
> --- a/include/usb.h
> +++ b/include/usb.h
> @@ -109,7 +109,9 @@ struct usb_device {
>  	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
> 
>  	int configno;			/* selected config number */
> -	struct usb_device_descriptor descriptor; /* Device Descriptor */
> +	/* Device Descriptor */
> +	struct usb_device_descriptor descriptor
> +		__attribute__((aligned(ARCH_DMA_MINALIGN)));
>  	struct usb_config config; /* config descriptor */
> 
>  	int have_langid;		/* whether string_langid is valid yet */

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-05 14:46                                                 ` [U-Boot] [PATCH v8] " Puneet Saxena
  2012-03-05 15:35                                                   ` Marek Vasut
@ 2012-03-05 18:18                                                   ` Simon Glass
  2012-03-06  0:36                                                     ` Marek Vasut
  2012-03-06  7:00                                                     ` puneets
  2012-03-06  3:07                                                   ` Mike Frysinger
  2 siblings, 2 replies; 83+ messages in thread
From: Simon Glass @ 2012-03-05 18:18 UTC (permalink / raw)
  To: u-boot

Hi Puneet,

On Mon, Mar 5, 2012 at 6:46 AM, Puneet Saxena <puneets@nvidia.com> wrote:
> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.
>
> Signed-off-by: Puneet Saxena <puneets@nvidia.com>

Tested on Seaboard:

Tested-by: Simon Glass <sjg@chromium.org>
Acked-by: Simon Glass <sjg@chromium.org>

I do still see a few alignment warnings, but only a tidy fraction of
what we had. Do you see these?

Tegra2 (SeaBoard) # usb start
(Re)start USB...
USB:   Register 10011 NbrPorts 1
USB EHCI 1.00
scanning bus for devices... ERROR: v7_dcache_inval_range - start
address is not aligned - 0x3fbed6f2
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed732
ERROR: v7_dcache_inval_range - start address is not aligned - 0x3fbed484
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed584
ERROR: v7_dcache_inval_range - start address is not aligned - 0x3fbed492
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed592
ERROR: v7_dcache_inval_range - start address is not aligned - 0x3fbed49e
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed59e
ERROR: v7_dcache_inval_range - start address is not aligned - 0x3fbed4a2
ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed582
2 USB Device(s) found
       scanning bus for storage devices... 1 Storage Device(s) found


Regards,
Simon

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor
  2012-03-05 13:14                             ` puneets
@ 2012-03-05 21:15                               ` Marek Vasut
  0 siblings, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-03-05 21:15 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

> Hi Marek,
> 
> On Monday 05 March 2012 06:18 PM, Marek Vasut wrote:
> > Dear Puneet Saxena,
> > 
> >>> Hi Marek,
> >>> 
> >>> On Thursday 01 March 2012 05:15 PM, Marek Vasut wrote:
> >>>> Hi!
> >>>> 
> >>>>> Hi Marek,
> >>>>> 
> >>>>> On Thursday 01 March 2012 02:59 AM, Marek Vasut wrote:
> >>>>>>> Add "CONFIG_USB_STRING_FETCH" to fetch first string descriptor
> >>>>>>> length and then pass this length to fetch string descriptor.
> >>>>>>> 
> >>>>>>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> >>>>>>> ---
> >>>>>>> 
> >>>>>>> Changes for V2:
> >>>>>>>       - Change existing config by "CONFIG_USB_STRING_FETCH"
> >>>>>>> 
> >>>>>>> Changes for V3:
> >>>>>>>        - Removed extra new line
> >>>>>>>        - Explained "CONFIG_USB_STRING_FETCH" in top level README
> >>>>>>>     
> >>>>>>>     README                          |    4 ++++
> >>>>>>>     common/usb.c                    |    4 ++++
> >>>>>>>     include/configs/tegra2-common.h |    2 ++
> >>>>>>>     3 files changed, 10 insertions(+), 0 deletions(-)
> >>>>>>> 
> >>>>>>> diff --git a/README b/README
> >>>>>>> index 7adf7c7..c045a37 100644
> >>>>>>> --- a/README
> >>>>>>> +++ b/README
> >>>>>>> 
> >>>>>>> @@ -1138,6 +1138,10 @@ The following options need to be configured:
> >>>>>>>     		CONFIG_USB_EHCI_TXFIFO_THRESH enables setting of the
> >>>>>>>     		txfilltuning field in the EHCI controller on reset.
> >>>>>>> 
> >>>>>>> +		CONFIG_USB_STRING_FETCH
> >>>>>>> +		Enables settings to USB core to handle string issues
> >> 
> >> which
> >> 
> >>>>>>> +		few devices can not handle.
> >>>>>>> +
> >>>>>>> 
> >>>>>>>     - USB Device:
> >>>>>>>     		Define the below if you wish to use the USB console.
> >>>>>>>     		Once firmware is rebuilt from a serial console issue the
> >>>>>>> 
> >>>>>>> diff --git a/common/usb.c b/common/usb.c
> >>>>>>> index 191bc5b..a73cb60 100644
> >>>>>>> --- a/common/usb.c
> >>>>>>> +++ b/common/usb.c
> >>>>>>> @@ -658,9 +658,13 @@ static int usb_string_sub(struct usb_device
> >>>>>>> *dev, unsigned int langid, {
> >>>>>>> 
> >>>>>>>     	int rc;
> >>>>>>> 
> >>>>>>> +#ifdef CONFIG_USB_STRING_FETCH
> >>>>>> 
> >>>>>> Shouldn't this be something like ... CONFIG_USB_AVOID_STRING_FETCH
> >>>>>> then?
> >>>>>> 
> >>>>>> Anyway, how come some devices can't handle it? What happens then?
> >>>>>> What devices are those (exact type etc)?
> >>>>>> 
> >>>>>> I believe the bug is deeper and adding extra config options can be
> >>>>>> avoided, what do you think?
> >>>>>> 
> >>>>>> Thanks!
> >>>>>> 
> >>>>>> M
> >>>>> 
> >>>>> It does not avoid string fetch.
> >>>> 
> >>>> Well it does certainly not call usb_get_string()
> >>> 
> >>> Precisely, it avoids fetching string desc of 255 bytes. so better name
> >>> could be
> >>> "CONFIG_USB_AVOID_STRING_FETCH_255".  Thanks for your comment.
> >>> 
> >>>>> I checked with few mass storage devices that they does not handle
> >>>>> string descriptor request correctly and so we get
> >>>>> start/stop Cache alignment error.
> >>>> 
> >>>> Cache alignment error ? Wow, how's that actually related to SUB string
> >>>> fetching? Maybe we should manually realign the result then? I still
> >>>> don't really understand what you're seeing, sorry ... can you please
> >>>> elaborate?
> >>> 
> >>> The particular mass storage device is -
> >>> 
> >>> Vendor: Kingston Rev: PMAP Prod: DataTraveler 2.0
> >>> 
> >>> Type: Removable Hard Disk
> >>> 
> >>> Capacity: 1906.0 MB = 1.8 GB (3903488 x 512)
> >>> 
> >>> When code tries to read Manufacturing Id..prod id...etc..it passes
> >>> cache aligned buffer "tbuf" in
> >>> "usb_string()" @usb.c. Inside "usb_string_sub()", usb_get_string()
> >>> passes as default 255 bytes to fetch string
> >>> descriptor.
> >>> The code in "ehci_submit_async() " invalidates *partially* the passed
> >>> buffer though we pass aligned buffer and "STD_ASS"
> >>> is received. Though it should invalidate only the cached line which is
> >>> equal(~32)  to string desc length.
> >> 
> >> Hm ... so this means the bug is in ehci_hcd? Maybe the ehci_hcd should
> >> be fixed to correctly handle caches then?
> >> 
> >>> If we give delay of 1 ms after handshake() the cache alignment warning
> >>> does not spew...but delay of 1 ms is not acceptable.
> >>> So I enabled the code to fetch first string desc length and then fetch
> >>> string desc fetch, in this way the issue is resolved.
> >>> It makes sense also to fetch string desc length and then actual string
> >>> desc....
> >> 
> >> I see, I  understand now just about everything but the ehci problem, see
> >> above. Your explanation was very helpful.
> >> 
> >> Let's work this out together!
> >> 
> >> Cheers!
> >> 
> >> M
> > 
> > Is this issue fixed or is this patch still needed? Thanks in advance!
> 
> This issue is not fixed and still need a patch to fix root cause,
> explained above.
> Note that this issue is observed even though we pass aligned address and
> expects something from the device.

I see, I finally understand the issue. Can I expect a patch from you for this 
issue then?

Thanks in advance!

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-05 18:18                                                   ` Simon Glass
@ 2012-03-06  0:36                                                     ` Marek Vasut
  2012-03-06  0:39                                                       ` Marek Vasut
  2012-03-06  7:00                                                     ` puneets
  1 sibling, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-06  0:36 UTC (permalink / raw)
  To: u-boot

Dear Simon Glass,

> Hi Puneet,
> 
> On Mon, Mar 5, 2012 at 6:46 AM, Puneet Saxena <puneets@nvidia.com> wrote:
> > As DMA expects the buffers to be equal and larger then
> > cache lines, This aligns buffers at cacheline.
> > 
> > Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> 
> Tested on Seaboard:
> 
> Tested-by: Simon Glass <sjg@chromium.org>
> Acked-by: Simon Glass <sjg@chromium.org>
> 

Guys, I'm very happy that we finally got it here. But the USB framework changed 
in mainline recently a bit (usb.c was split to usb.c and usb_hub.c). Puneet, can 
you please adapt your patch and do one last loop?

Thanks in advance!

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-06  0:36                                                     ` Marek Vasut
@ 2012-03-06  0:39                                                       ` Marek Vasut
  0 siblings, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-03-06  0:39 UTC (permalink / raw)
  To: u-boot

> Dear Simon Glass,
> 
> > Hi Puneet,
> > 
> > On Mon, Mar 5, 2012 at 6:46 AM, Puneet Saxena <puneets@nvidia.com> wrote:
> > > As DMA expects the buffers to be equal and larger then
> > > cache lines, This aligns buffers at cacheline.
> > > 
> > > Signed-off-by: Puneet Saxena <puneets@nvidia.com>
> > 
> > Tested on Seaboard:
> > 
> > Tested-by: Simon Glass <sjg@chromium.org>
> > Acked-by: Simon Glass <sjg@chromium.org>
> 
> Guys, I'm very happy that we finally got it here. But the USB framework
> changed in mainline recently a bit (usb.c was split to usb.c and
> usb_hub.c). Puneet, can you please adapt your patch and do one last loop?

Adapt your patch to this tree: git://git.denx.de/u-boot-usb.git master branch.

> 
> Thanks in advance!
> 
> Best regards,
> Marek Vasut

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-05 14:46                                                 ` [U-Boot] [PATCH v8] " Puneet Saxena
  2012-03-05 15:35                                                   ` Marek Vasut
  2012-03-05 18:18                                                   ` Simon Glass
@ 2012-03-06  3:07                                                   ` Mike Frysinger
  2012-03-07  7:12                                                     ` puneets
  2 siblings, 1 reply; 83+ messages in thread
From: Mike Frysinger @ 2012-03-06  3:07 UTC (permalink / raw)
  To: u-boot

On Monday 05 March 2012 09:46:21 Puneet Saxena wrote:
> As DMA expects the buffers to be equal and larger then
> cache lines, This aligns buffers at cacheline.

i don't think this statement is true.  DMA doesn't care about alignment (well, 
some do, but it's not related to cache lines but rather some other restriction 
in the peripheral DMA itself).  what does matter is that cache operations 
operate on cache lines and not individual bytes.  hence the core arm code was 
updated to warn when someone told it to invalidate X bytes but the hardware 
literally could not, so it had to invalidate X + Y bytes.

> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
>
>  static void flush_invalidate(u32 addr, int size, int flush)
>  {
> +	/*
> +	 * Size is the bytes actually moved during transaction,
> +	 * which may not equal to the cache line. This results
> +	 * stop address passed for invalidating cache may not be aligned.
> +	 * Therfore making size as multiple of cache line size.
> +	 */
> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> +
>  	if (flush)
>  		flush_dcache_range(addr, addr + size);
>  	else

i think this is wrong and merely hides the errors from higher up instead of 
fixing them.  the point of the warning was to tell you that the code was 
invalidating *too many* bytes.  this code still invalidates too many bytes 
without any justification as for why it's OK to do here.  further, this code 
path only matters to the invalidation logic, not the flush logic.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120305/0b98fe1a/attachment.pgp>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-02 16:45                                           ` Wolfgang Denk
  2012-03-05  7:16                                             ` [U-Boot] [PATCH v5] " Puneet Saxena
  2012-03-05  7:27                                             ` [U-Boot] [PATCH v6] " Puneet Saxena
@ 2012-03-06  3:28                                             ` Mike Frysinger
  2012-03-06  8:24                                               ` Marek Vasut
  2 siblings, 1 reply; 83+ messages in thread
From: Mike Frysinger @ 2012-03-06  3:28 UTC (permalink / raw)
  To: u-boot

On Friday 02 March 2012 11:45:15 Wolfgang Denk wrote:
> > > That's what I did in original patch where I am aligning it by adding
> > > the line
> > > 
> > > +        /* Device Descriptor */
> > > +#ifdef ARCH_DMA_MINALIGN
> > > +       struct usb_device_descriptor descriptor
> > > +               __attribute__((aligned(ARCH_DMA_MINALIGN)));
> > > +#else
> > > +       struct usb_device_descriptor descriptor;
> > > +#endif
> > > 
> > > in usb.h Line:112
> > > 
> > > > M
> > 
> > I see ...and I told you it's wrong? I must have misunderstood, I'm sorry
> > about that. But if you actually do this, you can avoid memcpy, right?
> 
> And eventually wd can also avoid the #ifdef ?  I guess the
> __attribute__((aligned...)) would not hurt anything?

the reason i disliked that was because it adds padding to the structure.  on 
my system, seems to go from 144 bytes to 160, and the other goes from 1352 to 
1376.  the scsi structure isn't specific to usb either.  i can't tell if this 
is a structure that represents data on the wire ... the fact it's written all 
using char types makes me suspicious.  if it is, then obviously we can't 
change the padding in the struct.

further, it doesn't seem like Linux imposes this restriction at the structure 
level (does it do memcopies instead ?), and imposing it on arbitrary members 
in there w/out documentation easily leads to rot.  if the code changes and no 
longer needs this alignment, how do we tell ?  if the code starts transferring 
another structure, do we end up aligning every member in there until there's 
padding everywhere ?
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120305/514a73d8/attachment.pgp>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-05 18:18                                                   ` Simon Glass
  2012-03-06  0:36                                                     ` Marek Vasut
@ 2012-03-06  7:00                                                     ` puneets
  2012-03-06  8:22                                                       ` Marek Vasut
  1 sibling, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-06  7:00 UTC (permalink / raw)
  To: u-boot

Hi Simon,
I do see only first warning on all the devices and rest of the warnings
on a few mass storage device.

My patch fixing these warnings is not accepted. Please see below link 
for further info -

http://lists.denx.de/pipermail/u-boot/2012-March/119404.html

IMO, these warnings spew when we expects some info e.g. device 
descriptor, manf id, prod id... from the device.
The root cause of the issue is some race condition in H/w due to which, 
even though we receive "STD_ASS"(Async sequence status) as 0
still transfer descriptor token is not updated.

Thanx & Regards,
Puneet

On Monday 05 March 2012 11:48 PM, Simon Glass wrote:
> Hi Puneet,
>
> On Mon, Mar 5, 2012 at 6:46 AM, Puneet Saxena<puneets@nvidia.com>  wrote:
>> As DMA expects the buffers to be equal and larger then
>> cache lines, This aligns buffers at cacheline.
>>
>> Signed-off-by: Puneet Saxena<puneets@nvidia.com>
> Tested on Seaboard:
>
> Tested-by: Simon Glass<sjg@chromium.org>
> Acked-by: Simon Glass<sjg@chromium.org>
>
> I do still see a few alignment warnings, but only a tidy fraction of
> what we had. Do you see these?
>
> Tegra2 (SeaBoard) # usb start
> (Re)start USB...
> USB:   Register 10011 NbrPorts 1
> USB EHCI 1.00
> scanning bus for devices... ERROR: v7_dcache_inval_range - start
> address is not aligned - 0x3fbed6f2
> ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed732
> ERROR: v7_dcache_inval_range - start address is not aligned - 0x3fbed484
> ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed584
> ERROR: v7_dcache_inval_range - start address is not aligned - 0x3fbed492
> ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed592
> ERROR: v7_dcache_inval_range - start address is not aligned - 0x3fbed49e
> ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed59e
> ERROR: v7_dcache_inval_range - start address is not aligned - 0x3fbed4a2
> ERROR: v7_dcache_inval_range - stop address is not aligned - 0x3fbed582
> 2 USB Device(s) found
>         scanning bus for storage devices... 1 Storage Device(s) found
>
>
> Regards,
> Simon


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-06  7:00                                                     ` puneets
@ 2012-03-06  8:22                                                       ` Marek Vasut
  0 siblings, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-03-06  8:22 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

> Hi Simon,
> I do see only first warning on all the devices and rest of the warnings
> on a few mass storage device.
> 
> My patch fixing these warnings is not accepted. Please see below link
> for further info -
> 
> http://lists.denx.de/pipermail/u-boot/2012-March/119404.html
> 
> IMO, these warnings spew when we expects some info e.g. device
> descriptor, manf id, prod id... from the device.
> The root cause of the issue is some race condition in H/w due to which,
> even though we receive "STD_ASS"(Async sequence status) as 0
> still transfer descriptor token is not updated.
> 
> Thanx & Regards,
> Puneet

I'd really love to accept the patch, but I can see it exposes even worse issue, 
so I'd be really happy to fix the root cause of the problem instead of putting 
layers of hack-arounds on top of it.

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-06  3:28                                             ` [U-Boot] [PATCH v4] " Mike Frysinger
@ 2012-03-06  8:24                                               ` Marek Vasut
  2012-03-06 16:42                                                 ` Mike Frysinger
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-06  8:24 UTC (permalink / raw)
  To: u-boot

Dear Mike Frysinger,

> On Friday 02 March 2012 11:45:15 Wolfgang Denk wrote:
> > > > That's what I did in original patch where I am aligning it by adding
> > > > the line
> > > > 
> > > > +        /* Device Descriptor */
> > > > +#ifdef ARCH_DMA_MINALIGN
> > > > +       struct usb_device_descriptor descriptor
> > > > +               __attribute__((aligned(ARCH_DMA_MINALIGN)));
> > > > +#else
> > > > +       struct usb_device_descriptor descriptor;
> > > > +#endif
> > > > 
> > > > in usb.h Line:112
> > > > 
> > > > > M
> > > 
> > > I see ...and I told you it's wrong? I must have misunderstood, I'm
> > > sorry about that. But if you actually do this, you can avoid memcpy,
> > > right?
> > 
> > And eventually wd can also avoid the #ifdef ?  I guess the
> > __attribute__((aligned...)) would not hurt anything?
> 
> the reason i disliked that was because it adds padding to the structure. 
> on my system, seems to go from 144 bytes to 160, and the other goes from
> 1352 to 1376.  the scsi structure isn't specific to usb either.  i can't
> tell if this is a structure that represents data on the wire ... the fact
> it's written all using char types makes me suspicious.  if it is, then
> obviously we can't change the padding in the struct.
> 
> further, it doesn't seem like Linux imposes this restriction at the
> structure level (does it do memcopies instead ?), and imposing it on
> arbitrary members in there w/out documentation easily leads to rot.  if
> the code changes and no longer needs this alignment, how do we tell ?  if
> the code starts transferring another structure, do we end up aligning
> every member in there until there's padding everywhere ?
> -mike

I believe this is OK, we're properly aligning only descriptors. Note that the 
USB stack in linux and in uboot is different.

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v4] usb: align buffers at cacheline
  2012-03-06  8:24                                               ` Marek Vasut
@ 2012-03-06 16:42                                                 ` Mike Frysinger
  0 siblings, 0 replies; 83+ messages in thread
From: Mike Frysinger @ 2012-03-06 16:42 UTC (permalink / raw)
  To: u-boot

On Tuesday 06 March 2012 03:24:34 Marek Vasut wrote:
> > On Friday 02 March 2012 11:45:15 Wolfgang Denk wrote:
> > > > > That's what I did in original patch where I am aligning it by
> > > > > adding the line
> > > > > 
> > > > > +        /* Device Descriptor */
> > > > > +#ifdef ARCH_DMA_MINALIGN
> > > > > +       struct usb_device_descriptor descriptor
> > > > > +               __attribute__((aligned(ARCH_DMA_MINALIGN)));
> > > > > +#else
> > > > > +       struct usb_device_descriptor descriptor;
> > > > > +#endif
> > > > > 
> > > > > in usb.h Line:112
> > > > 
> > > > I see ...and I told you it's wrong? I must have misunderstood, I'm
> > > > sorry about that. But if you actually do this, you can avoid memcpy,
> > > > right?
> > > 
> > > And eventually wd can also avoid the #ifdef ?  I guess the
> > > __attribute__((aligned...)) would not hurt anything?
> > 
> > the reason i disliked that was because it adds padding to the structure.
> > on my system, seems to go from 144 bytes to 160, and the other goes from
> > 1352 to 1376.  the scsi structure isn't specific to usb either.  i can't
> > tell if this is a structure that represents data on the wire ... the fact
> > it's written all using char types makes me suspicious.  if it is, then
> > obviously we can't change the padding in the struct.
> > 
> > further, it doesn't seem like Linux imposes this restriction at the
> > structure level (does it do memcopies instead ?), and imposing it on
> > arbitrary members in there w/out documentation easily leads to rot.  if
> > the code changes and no longer needs this alignment, how do we tell ?  if
> > the code starts transferring another structure, do we end up aligning
> > every member in there until there's padding everywhere ?
> 
> I believe this is OK, we're properly aligning only descriptors.

you're looking at one change (the one quoted above).  i was referring to the 
scsi structure change (which is not quoted above).

> Note that the USB stack in linux and in uboot is different.

i know the stacks are different, but they do share.  my point was that if Linux 
is managing this, then why can't we ?  or maybe we're fighting over an 
insignificant memcpy ... the scsi buffer is all of 64 bytes.  on some systems, 
that's like 1 cache line :P.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120306/086be190/attachment.pgp>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-06  3:07                                                   ` Mike Frysinger
@ 2012-03-07  7:12                                                     ` puneets
  2012-03-07  9:20                                                       ` puneets
                                                                         ` (3 more replies)
  0 siblings, 4 replies; 83+ messages in thread
From: puneets @ 2012-03-07  7:12 UTC (permalink / raw)
  To: u-boot

Hi Mike,
On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
> * PGP Signed by an unknown key
>
> On Monday 05 March 2012 09:46:21 Puneet Saxena wrote:
>> As DMA expects the buffers to be equal and larger then
>> cache lines, This aligns buffers at cacheline.
> i don't think this statement is true.  DMA doesn't care about alignment (well,
> some do, but it's not related to cache lines but rather some other restriction
> in the peripheral DMA itself).  what does matter is that cache operations
> operate on cache lines and not individual bytes.  hence the core arm code was
> updated to warn when someone told it to invalidate X bytes but the hardware
> literally could not, so it had to invalidate X + Y bytes.
>
Agreed, Will update the commit message in next patchset.
>> --- a/drivers/usb/host/ehci-hcd.c
>> +++ b/drivers/usb/host/ehci-hcd.c
>>
>>   static void flush_invalidate(u32 addr, int size, int flush)
>>   {
>> +	/*
>> +	 * Size is the bytes actually moved during transaction,
>> +	 * which may not equal to the cache line. This results
>> +	 * stop address passed for invalidating cache may not be aligned.
>> +	 * Therfore making size as multiple of cache line size.
>> +	 */
>> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
>> +
>>   	if (flush)
>>   		flush_dcache_range(addr, addr + size);
>>   	else
> i think this is wrong and merely hides the errors from higher up instead of
> fixing them.  the point of the warning was to tell you that the code was
> invalidating *too many* bytes.  this code still invalidates too many bytes
> without any justification as for why it's OK to do here.  further, this code
> path only matters to the invalidation logic, not the flush logic.
> -mike
>
The sole purpose of this patch to remove the warnings as start/stop 
address sent for invalidating
is unaligned. Without this patch code works fine but with lots of 
spew...Which we don't want and discussed
in earlier thread which Simon posted. Please have a look on following link.

As I understood, you agree that we need to align start/stop buffer 
address and also agree that
to align stop address we need to align size as start address is already 
aligned.
Now, "why its OK to do here"?
We could have aligned the size in two places, cache_qtd() and cache_qh() 
but then we need to place alignment check
at all the places where size is passed. So I thought better Aligning at 
flush_invalidate() and "ALIGN" macro does not
increase the size if size is already aligned.


> * Unknown Key
> * 0xE837F581
Thanx & Regards,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-07  7:12                                                     ` puneets
@ 2012-03-07  9:20                                                       ` puneets
  2012-03-07 22:06                                                       ` Marek Vasut
                                                                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 83+ messages in thread
From: puneets @ 2012-03-07  9:20 UTC (permalink / raw)
  To: u-boot

Hi Mike,
Forgot to write the link in below mail.
Here is the link: 
http://lists.denx.de/pipermail/u-boot/2011-December/112138.html
Do you want me to show a warning where I am making size as cacheline size?

Thanx & Regards,,
Puneet
On Wednesday 07 March 2012 12:42 PM, puneets wrote:
> Hi Mike,
> On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
>> * PGP Signed by an unknown key
>>
>> On Monday 05 March 2012 09:46:21 Puneet Saxena wrote:
>>> As DMA expects the buffers to be equal and larger then
>>> cache lines, This aligns buffers at cacheline.
>> i don't think this statement is true.  DMA doesn't care about alignment (well,
>> some do, but it's not related to cache lines but rather some other restriction
>> in the peripheral DMA itself).  what does matter is that cache operations
>> operate on cache lines and not individual bytes.  hence the core arm code was
>> updated to warn when someone told it to invalidate X bytes but the hardware
>> literally could not, so it had to invalidate X + Y bytes.
>>
> Agreed, Will update the commit message in next patchset.
>>> --- a/drivers/usb/host/ehci-hcd.c
>>> +++ b/drivers/usb/host/ehci-hcd.c
>>>
>>>    static void flush_invalidate(u32 addr, int size, int flush)
>>>    {
>>> +	/*
>>> +	 * Size is the bytes actually moved during transaction,
>>> +	 * which may not equal to the cache line. This results
>>> +	 * stop address passed for invalidating cache may not be aligned.
>>> +	 * Therfore making size as multiple of cache line size.
>>> +	 */
>>> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
>>> +
>>>    	if (flush)
>>>    		flush_dcache_range(addr, addr + size);
>>>    	else
>> i think this is wrong and merely hides the errors from higher up instead of
>> fixing them.  the point of the warning was to tell you that the code was
>> invalidating *too many* bytes.  this code still invalidates too many bytes
>> without any justification as for why it's OK to do here.  further, this code
>> path only matters to the invalidation logic, not the flush logic.
>> -mike
>>
> The sole purpose of this patch to remove the warnings as start/stop
> address sent for invalidating
> is unaligned. Without this patch code works fine but with lots of
> spew...Which we don't want and discussed
> in earlier thread which Simon posted. Please have a look on following link.
>
> As I understood, you agree that we need to align start/stop buffer
> address and also agree that
> to align stop address we need to align size as start address is already
> aligned.
> Now, "why its OK to do here"?
> We could have aligned the size in two places, cache_qtd() and cache_qh()
> but then we need to place alignment check
> at all the places where size is passed. So I thought better Aligning at
> flush_invalidate() and "ALIGN" macro does not
> increase the size if size is already aligned.
>
>
>> * Unknown Key
>> * 0xE837F581
> Thanx&  Regards,
> Puneet


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-07  7:12                                                     ` puneets
  2012-03-07  9:20                                                       ` puneets
@ 2012-03-07 22:06                                                       ` Marek Vasut
  2012-03-08 11:21                                                         ` puneets
  2012-03-11  2:35                                                       ` Mike Frysinger
  2012-03-16  4:39                                                       ` Marek Vasut
  3 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-07 22:06 UTC (permalink / raw)
  To: u-boot

Dear puneets,

> Hi Mike,
> 
> On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
> > * PGP Signed by an unknown key
> > 
> > On Monday 05 March 2012 09:46:21 Puneet Saxena wrote:
> >> As DMA expects the buffers to be equal and larger then
> >> cache lines, This aligns buffers at cacheline.
> > 
> > i don't think this statement is true.  DMA doesn't care about alignment
> > (well, some do, but it's not related to cache lines but rather some
> > other restriction in the peripheral DMA itself).  what does matter is
> > that cache operations operate on cache lines and not individual bytes. 
> > hence the core arm code was updated to warn when someone told it to
> > invalidate X bytes but the hardware literally could not, so it had to
> > invalidate X + Y bytes.
> 
> Agreed, Will update the commit message in next patchset.
> 
> >> --- a/drivers/usb/host/ehci-hcd.c
> >> +++ b/drivers/usb/host/ehci-hcd.c
> >> 
> >>   static void flush_invalidate(u32 addr, int size, int flush)
> >>   {
> >> 
> >> +	/*
> >> +	 * Size is the bytes actually moved during transaction,
> >> +	 * which may not equal to the cache line. This results
> >> +	 * stop address passed for invalidating cache may not be aligned.
> >> +	 * Therfore making size as multiple of cache line size.
> >> +	 */
> >> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> >> +
> >> 
> >>   	if (flush)
> >>   	
> >>   		flush_dcache_range(addr, addr + size);
> >>   	
> >>   	else
> > 
> > i think this is wrong and merely hides the errors from higher up instead
> > of fixing them.  the point of the warning was to tell you that the code
> > was invalidating *too many* bytes.  this code still invalidates too many
> > bytes without any justification as for why it's OK to do here.  further,
> > this code path only matters to the invalidation logic, not the flush
> > logic. -mike
> 
> The sole purpose of this patch to remove the warnings as start/stop
> address sent for invalidating
> is unaligned. Without this patch code works fine but with lots of
> spew...Which we don't want and discussed
> in earlier thread which Simon posted. Please have a look on following link.
> 
> As I understood, you agree that we need to align start/stop buffer
> address and also agree that
> to align stop address we need to align size as start address is already
> aligned.
> Now, "why its OK to do here"?
> We could have aligned the size in two places, cache_qtd() and cache_qh()
> but then we need to place alignment check
> at all the places where size is passed. So I thought better Aligning at
> flush_invalidate() and "ALIGN" macro does not
> increase the size if size is already aligned.

Actually I have to agree with Mike here. Can you please remove that ALIGN() (and 
all others you might have added)? If it does spew, that's ok and it tells us 
something is wrong in the USB core subsystem. Such stuff can be fixed in 
subsequent patch.

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-07 22:06                                                       ` Marek Vasut
@ 2012-03-08 11:21                                                         ` puneets
  2012-03-08 14:12                                                           ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-08 11:21 UTC (permalink / raw)
  To: u-boot

Hi Marek,
On Thursday 08 March 2012 03:36 AM, Marek Vasut wrote:
> Dear puneets,
>
>> Hi Mike,
>>
>> On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
>>> * PGP Signed by an unknown key
>>>
>>> On Monday 05 March 2012 09:46:21 Puneet Saxena wrote:
>>>> As DMA expects the buffers to be equal and larger then
>>>> cache lines, This aligns buffers at cacheline.
>>> i don't think this statement is true.  DMA doesn't care about alignment
>>> (well, some do, but it's not related to cache lines but rather some
>>> other restriction in the peripheral DMA itself).  what does matter is
>>> that cache operations operate on cache lines and not individual bytes.
>>> hence the core arm code was updated to warn when someone told it to
>>> invalidate X bytes but the hardware literally could not, so it had to
>>> invalidate X + Y bytes.
>> Agreed, Will update the commit message in next patchset.
>>
>>>> --- a/drivers/usb/host/ehci-hcd.c
>>>> +++ b/drivers/usb/host/ehci-hcd.c
>>>>
>>>>    static void flush_invalidate(u32 addr, int size, int flush)
>>>>    {
>>>>
>>>> +	/*
>>>> +	 * Size is the bytes actually moved during transaction,
>>>> +	 * which may not equal to the cache line. This results
>>>> +	 * stop address passed for invalidating cache may not be aligned.
>>>> +	 * Therfore making size as multiple of cache line size.
>>>> +	 */
>>>> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
>>>> +
>>>>
>>>>    	if (flush)
>>>>    	
>>>>    		flush_dcache_range(addr, addr + size);
>>>>    	
>>>>    	else
>>> i think this is wrong and merely hides the errors from higher up instead
>>> of fixing them.  the point of the warning was to tell you that the code
>>> was invalidating *too many* bytes.  this code still invalidates too many
>>> bytes without any justification as for why it's OK to do here.  further,
>>> this code path only matters to the invalidation logic, not the flush
>>> logic. -mike
>> The sole purpose of this patch to remove the warnings as start/stop
>> address sent for invalidating
>> is unaligned. Without this patch code works fine but with lots of
>> spew...Which we don't want and discussed
>> in earlier thread which Simon posted. Please have a look on following link.
>>
>> As I understood, you agree that we need to align start/stop buffer
>> address and also agree that
>> to align stop address we need to align size as start address is already
>> aligned.
>> Now, "why its OK to do here"?
>> We could have aligned the size in two places, cache_qtd() and cache_qh()
>> but then we need to place alignment check
>> at all the places where size is passed. So I thought better Aligning at
>> flush_invalidate() and "ALIGN" macro does not
>> increase the size if size is already aligned.
> Actually I have to agree with Mike here. Can you please remove that ALIGN() (and
> all others you might have added)? If it does spew, that's ok and it tells us
> something is wrong in the USB core subsystem. Such stuff can be fixed in
> subsequent patch.
>
Sorry, I could not understand "(and all others you might have added)".
Do you want me remove any HACK in the patch which is using ALIGN or 
making stop address
aligned? The patch has only the above line to make stop address align 
and rest of the code makes
start address align. Just to confirm, you are fine with the start 
address alignment code in the patch?

> Best regards,
> Marek Vasut
Thanx & Regards,
Puneet

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-08 11:21                                                         ` puneets
@ 2012-03-08 14:12                                                           ` Marek Vasut
  2012-03-09  6:15                                                             ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-08 14:12 UTC (permalink / raw)
  To: u-boot

Dear puneets,

> Hi Marek,
> 
> On Thursday 08 March 2012 03:36 AM, Marek Vasut wrote:
> > Dear puneets,
> > 
> >> Hi Mike,
> >> 
> >> On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
> >>> * PGP Signed by an unknown key
> >>> 
> >>> On Monday 05 March 2012 09:46:21 Puneet Saxena wrote:
> >>>> As DMA expects the buffers to be equal and larger then
> >>>> cache lines, This aligns buffers at cacheline.
> >>> 
> >>> i don't think this statement is true.  DMA doesn't care about alignment
> >>> (well, some do, but it's not related to cache lines but rather some
> >>> other restriction in the peripheral DMA itself).  what does matter is
> >>> that cache operations operate on cache lines and not individual bytes.
> >>> hence the core arm code was updated to warn when someone told it to
> >>> invalidate X bytes but the hardware literally could not, so it had to
> >>> invalidate X + Y bytes.
> >> 
> >> Agreed, Will update the commit message in next patchset.
> >> 
> >>>> --- a/drivers/usb/host/ehci-hcd.c
> >>>> +++ b/drivers/usb/host/ehci-hcd.c
> >>>> 
> >>>>    static void flush_invalidate(u32 addr, int size, int flush)
> >>>>    {
> >>>> 
> >>>> +	/*
> >>>> +	 * Size is the bytes actually moved during transaction,
> >>>> +	 * which may not equal to the cache line. This results
> >>>> +	 * stop address passed for invalidating cache may not be 
aligned.
> >>>> +	 * Therfore making size as multiple of cache line size.
> >>>> +	 */
> >>>> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> >>>> +
> >>>> 
> >>>>    	if (flush)
> >>>>    	
> >>>>    		flush_dcache_range(addr, addr + size);
> >>>>    	
> >>>>    	else
> >>> 
> >>> i think this is wrong and merely hides the errors from higher up
> >>> instead of fixing them.  the point of the warning was to tell you that
> >>> the code was invalidating *too many* bytes.  this code still
> >>> invalidates too many bytes without any justification as for why it's
> >>> OK to do here.  further, this code path only matters to the
> >>> invalidation logic, not the flush logic. -mike
> >> 
> >> The sole purpose of this patch to remove the warnings as start/stop
> >> address sent for invalidating
> >> is unaligned. Without this patch code works fine but with lots of
> >> spew...Which we don't want and discussed
> >> in earlier thread which Simon posted. Please have a look on following
> >> link.
> >> 
> >> As I understood, you agree that we need to align start/stop buffer
> >> address and also agree that
> >> to align stop address we need to align size as start address is already
> >> aligned.
> >> Now, "why its OK to do here"?
> >> We could have aligned the size in two places, cache_qtd() and cache_qh()
> >> but then we need to place alignment check
> >> at all the places where size is passed. So I thought better Aligning at
> >> flush_invalidate() and "ALIGN" macro does not
> >> increase the size if size is already aligned.
> > 
> > Actually I have to agree with Mike here. Can you please remove that
> > ALIGN() (and all others you might have added)? If it does spew, that's
> > ok and it tells us something is wrong in the USB core subsystem. Such
> > stuff can be fixed in subsequent patch.
> 
> Sorry, I could not understand "(and all others you might have added)".
> Do you want me remove any HACK in the patch which is using ALIGN or
> making stop address

No, only such hacks where it's certain they will either invalidate or flush some 
areas that weren't allocated for them, like this ALIGN you did here. This can 
cause trouble that will be very hard to find.

> aligned? The patch has only the above line to make stop address align
> and rest of the code makes
> start address align. Just to confirm, you are fine with the start
> address alignment code in the patch?

The start address alignment you do also aligns the end to the cacheline, doesn't 
it? (at least that's what I believe the macro is supposed to do).

> 
> > Best regards,
> > Marek Vasut
> 
> Thanx & Regards,
> Puneet
> 
> ---------------------------------------------------------------------------
> -------- This email message is for the sole use of the intended
> recipient(s) and may contain confidential information.  Any unauthorized
> review, use, disclosure or distribution is prohibited.  If you are not the
> intended recipient, please contact the sender by reply email and destroy
> all copies of the original message.
> ---------------------------------------------------------------------------
> --------

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-08 14:12                                                           ` Marek Vasut
@ 2012-03-09  6:15                                                             ` puneets
  2012-03-09 12:03                                                               ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-09  6:15 UTC (permalink / raw)
  To: u-boot

Hi Marek,
On Thursday 08 March 2012 07:42 PM, Marek Vasut wrote:
> Dear puneets,
>
>> Hi Marek,
>>
>> On Thursday 08 March 2012 03:36 AM, Marek Vasut wrote:
>>> Dear puneets,
>>>
>>>> Hi Mike,
>>>>
>>>> On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
>>>>> * PGP Signed by an unknown key
>>>>>
>>>>> On Monday 05 March 2012 09:46:21 Puneet Saxena wrote:
>>>>>> As DMA expects the buffers to be equal and larger then
>>>>>> cache lines, This aligns buffers at cacheline.
>>>>> i don't think this statement is true.  DMA doesn't care about alignment
>>>>> (well, some do, but it's not related to cache lines but rather some
>>>>> other restriction in the peripheral DMA itself).  what does matter is
>>>>> that cache operations operate on cache lines and not individual bytes.
>>>>> hence the core arm code was updated to warn when someone told it to
>>>>> invalidate X bytes but the hardware literally could not, so it had to
>>>>> invalidate X + Y bytes.
>>>> Agreed, Will update the commit message in next patchset.
>>>>
>>>>>> --- a/drivers/usb/host/ehci-hcd.c
>>>>>> +++ b/drivers/usb/host/ehci-hcd.c
>>>>>>
>>>>>>     static void flush_invalidate(u32 addr, int size, int flush)
>>>>>>     {
>>>>>>
>>>>>> +	/*
>>>>>> +	 * Size is the bytes actually moved during transaction,
>>>>>> +	 * which may not equal to the cache line. This results
>>>>>> +	 * stop address passed for invalidating cache may not be
> aligned.
>>>>>> +	 * Therfore making size as multiple of cache line size.
>>>>>> +	 */
>>>>>> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
>>>>>> +
>>>>>>
>>>>>>     	if (flush)
>>>>>>     	
>>>>>>     		flush_dcache_range(addr, addr + size);
>>>>>>     	
>>>>>>     	else
>>>>> i think this is wrong and merely hides the errors from higher up
>>>>> instead of fixing them.  the point of the warning was to tell you that
>>>>> the code was invalidating *too many* bytes.  this code still
>>>>> invalidates too many bytes without any justification as for why it's
>>>>> OK to do here.  further, this code path only matters to the
>>>>> invalidation logic, not the flush logic. -mike
>>>> The sole purpose of this patch to remove the warnings as start/stop
>>>> address sent for invalidating
>>>> is unaligned. Without this patch code works fine but with lots of
>>>> spew...Which we don't want and discussed
>>>> in earlier thread which Simon posted. Please have a look on following
>>>> link.
>>>>
>>>> As I understood, you agree that we need to align start/stop buffer
>>>> address and also agree that
>>>> to align stop address we need to align size as start address is already
>>>> aligned.
>>>> Now, "why its OK to do here"?
>>>> We could have aligned the size in two places, cache_qtd() and cache_qh()
>>>> but then we need to place alignment check
>>>> at all the places where size is passed. So I thought better Aligning at
>>>> flush_invalidate() and "ALIGN" macro does not
>>>> increase the size if size is already aligned.
>>> Actually I have to agree with Mike here. Can you please remove that
>>> ALIGN() (and all others you might have added)? If it does spew, that's
>>> ok and it tells us something is wrong in the USB core subsystem. Such
>>> stuff can be fixed in subsequent patch.
>> Sorry, I could not understand "(and all others you might have added)".
>> Do you want me remove any HACK in the patch which is using ALIGN or
>> making stop address
> No, only such hacks where it's certain they will either invalidate or flush some
> areas that weren't allocated for them, like this ALIGN you did here. This can
> cause trouble that will be very hard to find.
>
>> aligned? The patch has only the above line to make stop address align
>> and rest of the code makes
>> start address align. Just to confirm, you are fine with the start
>> address alignment code in the patch?
> The start address alignment you do also aligns the end to the cacheline, doesn't
> it? (at least that's what I believe the macro is supposed to do).
>
Yes, start address alignment also aligns start address at the cache 
line. So, removing
stop address alignment code as depicted above, should make this patch 
acceptable?

Best regards,
>>> Marek Vasut
>> Thanx&  Regards,
>> Puneet
>>
>> ---------------------------------------------------------------------------
>> -------- This email message is for the sole use of the intended
>> recipient(s) and may contain confidential information.  Any unauthorized
>> review, use, disclosure or distribution is prohibited.  If you are not the
>> intended recipient, please contact the sender by reply email and destroy
>> all copies of the original message.
>> ---------------------------------------------------------------------------
>> --------
> Best regards,
> Marek Vasut
Thanx & Regards,
Puneet

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-09  6:15                                                             ` puneets
@ 2012-03-09 12:03                                                               ` Marek Vasut
  0 siblings, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-03-09 12:03 UTC (permalink / raw)
  To: u-boot

Dear puneets,

> Hi Marek,
> 
> On Thursday 08 March 2012 07:42 PM, Marek Vasut wrote:
> > Dear puneets,
> > 
> >> Hi Marek,
> >> 
> >> On Thursday 08 March 2012 03:36 AM, Marek Vasut wrote:
> >>> Dear puneets,
> >>> 
> >>>> Hi Mike,
> >>>> 
> >>>> On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
> >>>>> * PGP Signed by an unknown key
> >>>>> 
> >>>>> On Monday 05 March 2012 09:46:21 Puneet Saxena wrote:
> >>>>>> As DMA expects the buffers to be equal and larger then
> >>>>>> cache lines, This aligns buffers at cacheline.
> >>>>> 
> >>>>> i don't think this statement is true.  DMA doesn't care about
> >>>>> alignment (well, some do, but it's not related to cache lines but
> >>>>> rather some other restriction in the peripheral DMA itself).  what
> >>>>> does matter is that cache operations operate on cache lines and not
> >>>>> individual bytes. hence the core arm code was updated to warn when
> >>>>> someone told it to invalidate X bytes but the hardware literally
> >>>>> could not, so it had to invalidate X + Y bytes.
> >>>> 
> >>>> Agreed, Will update the commit message in next patchset.
> >>>> 
> >>>>>> --- a/drivers/usb/host/ehci-hcd.c
> >>>>>> +++ b/drivers/usb/host/ehci-hcd.c
> >>>>>> 
> >>>>>>     static void flush_invalidate(u32 addr, int size, int flush)
> >>>>>>     {
> >>>>>> 
> >>>>>> +	/*
> >>>>>> +	 * Size is the bytes actually moved during transaction,
> >>>>>> +	 * which may not equal to the cache line. This results
> >>>>>> +	 * stop address passed for invalidating cache may not be
> > 
> > aligned.
> > 
> >>>>>> +	 * Therfore making size as multiple of cache line size.
> >>>>>> +	 */
> >>>>>> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> >>>>>> +
> >>>>>> 
> >>>>>>     	if (flush)
> >>>>>>     	
> >>>>>>     		flush_dcache_range(addr, addr + size);
> >>>>>>     	
> >>>>>>     	else
> >>>>> 
> >>>>> i think this is wrong and merely hides the errors from higher up
> >>>>> instead of fixing them.  the point of the warning was to tell you
> >>>>> that the code was invalidating *too many* bytes.  this code still
> >>>>> invalidates too many bytes without any justification as for why it's
> >>>>> OK to do here.  further, this code path only matters to the
> >>>>> invalidation logic, not the flush logic. -mike
> >>>> 
> >>>> The sole purpose of this patch to remove the warnings as start/stop
> >>>> address sent for invalidating
> >>>> is unaligned. Without this patch code works fine but with lots of
> >>>> spew...Which we don't want and discussed
> >>>> in earlier thread which Simon posted. Please have a look on following
> >>>> link.
> >>>> 
> >>>> As I understood, you agree that we need to align start/stop buffer
> >>>> address and also agree that
> >>>> to align stop address we need to align size as start address is
> >>>> already aligned.
> >>>> Now, "why its OK to do here"?
> >>>> We could have aligned the size in two places, cache_qtd() and
> >>>> cache_qh() but then we need to place alignment check
> >>>> at all the places where size is passed. So I thought better Aligning
> >>>> at flush_invalidate() and "ALIGN" macro does not
> >>>> increase the size if size is already aligned.
> >>> 
> >>> Actually I have to agree with Mike here. Can you please remove that
> >>> ALIGN() (and all others you might have added)? If it does spew, that's
> >>> ok and it tells us something is wrong in the USB core subsystem. Such
> >>> stuff can be fixed in subsequent patch.
> >> 
> >> Sorry, I could not understand "(and all others you might have added)".
> >> Do you want me remove any HACK in the patch which is using ALIGN or
> >> making stop address
> > 
> > No, only such hacks where it's certain they will either invalidate or
> > flush some areas that weren't allocated for them, like this ALIGN you
> > did here. This can cause trouble that will be very hard to find.
> > 
> >> aligned? The patch has only the above line to make stop address align
> >> and rest of the code makes
> >> start address align. Just to confirm, you are fine with the start
> >> address alignment code in the patch?
> > 
> > The start address alignment you do also aligns the end to the cacheline,
> > doesn't it? (at least that's what I believe the macro is supposed to
> > do).
> 
> Yes, start address alignment also aligns start address at the cache
> line. So, removing
> stop address alignment code as depicted above, should make this patch
> acceptable?
> 
Puneet, it's not a problem of acceptability, it's a problem of breaking uboot 
;-) Acceptability goes only after it we are sure doesn't break anything. The 
cache stuff is really fragile so we need to be very careful, please understand 
and let's figure this out together, I feel we're really close.

And yes, I believe removing such dangerous ALIGN() calls will be the last fix 
necessary, unless something other pops up.

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-07  7:12                                                     ` puneets
  2012-03-07  9:20                                                       ` puneets
  2012-03-07 22:06                                                       ` Marek Vasut
@ 2012-03-11  2:35                                                       ` Mike Frysinger
  2012-03-14  2:05                                                         ` Marek Vasut
  2012-03-16  4:39                                                       ` Marek Vasut
  3 siblings, 1 reply; 83+ messages in thread
From: Mike Frysinger @ 2012-03-11  2:35 UTC (permalink / raw)
  To: u-boot

On Wednesday 07 March 2012 02:12:22 puneets wrote:
> On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
> >> --- a/drivers/usb/host/ehci-hcd.c
> >> +++ b/drivers/usb/host/ehci-hcd.c
> >> 
> >>   static void flush_invalidate(u32 addr, int size, int flush)
> >>   {
> >> +	/*
> >> +	 * Size is the bytes actually moved during transaction,
> >> +	 * which may not equal to the cache line. This results
> >> +	 * stop address passed for invalidating cache may not be aligned.
> >> +	 * Therfore making size as multiple of cache line size.
> >> +	 */
> >> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> >> +
> >>   	if (flush)
> >>   		flush_dcache_range(addr, addr + size);
> >>   	else
> > 
> > i think this is wrong and merely hides the errors from higher up instead
> > of fixing them.  the point of the warning was to tell you that the code
> > was invalidating *too many* bytes.  this code still invalidates too many
> > bytes without any justification as for why it's OK to do here.  further,
> > this code path only matters to the invalidation logic, not the flush
> > logic.
> 
> The sole purpose of this patch to remove the warnings as start/stop
> address sent for invalidating
> is unaligned. Without this patch code works fine but with lots of
> spew...Which we don't want and discussed
> in earlier thread which Simon posted. Please have a look on following link.
> 
> As I understood, you agree that we need to align start/stop buffer
> address and also agree that
> to align stop address we need to align size as start address is already
> aligned.
> Now, "why its OK to do here"?
> We could have aligned the size in two places, cache_qtd() and cache_qh()
> but then we need to place alignment check
> at all the places where size is passed. So I thought better Aligning at
> flush_invalidate() and "ALIGN" macro does not
> increase the size if size is already aligned.

i think you missed my point.  consider a func which has local vars like so:
	int i;
	char buf[1024];
	int k;

and let's say you're running on a core that has a cache line size of 32 bytes 
(which is fairly common).  if you execute a data cache invalid insn, the 
smallest region it can invalidate is 32 bytes.  doesn't matter if you only 
want to invalidate a buffer of 8 bytes ... everything else around it gets 
invalidated as well.

now, in the aforementioned stack, if it starts off aligned nicely at a 32 byte 
boundary, the integer "i" will share a cache line with the first 28 bytes of 
buffer "buf", and the integer "k" will share a cache line with the last 4 bytes 
of the buffer "buf".  (let's ignore what might or might not happen based on gcc 
since this example can trivially be expanded to structure layout.)

the trouble is when you attempt to invalidate the contents of "buf".  if the 
cache is in writeback mode (which means you could have changes in the cache 
which are not reflected in external RAM), then invalidating buf will also 
discard values that might be in "i" or "k".  this is why Simon put a warning 
in the core data cache invalidate function.  if the cache were in writethrough 
mode (which also tends to be the default), then most likely things would work 
fine and no one would notice.  or if the data cache was merely flushed, things 
would work, but at a decrease in performance: you'd be flushing cache lines to 
external memory that you know will be overwritten by a following transaction 
-- most likely DMA from a peripheral such as the USB controller, and you'd be 
flushing objects that the DMA wouldn't be touching, so they'd have to get 
refetched from external RAM ("i" and "k" in my example above).

simply rounding the address down to the start of the cache line and the length 
up to a multiple of a cache line to keep the core code from issuing the 
warning doesn't fix the problem i describe above.  you actually get the worst 
of both worlds -- silent runtime misbehavior when extra memory gets 
invalidated.

perhaps the warning in the core code could be dropped and all your changes in 
fringe code obsoleted (such as these USB patches): when it detects that an 
address is starting on an unaligned boundary, *flush* that line first, and then 
let it be invalidated.  accordingly, when the end length is on an unaligned 
boundary, do the same flush-then-invalidate step.  this should also make things 
work without a (significant) loss in performance.  if anything, i suspect the 
overhead of doing runtime buffer size calculations and manually aligning 
pointers (which is what ALLOC_CACHE_ALIGN_BUFFER does) is a wash compared to 
partially flushing cache lines in the core ...

Simon: what do you think of this last idea ?
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120310/8aa995cf/attachment.pgp>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-11  2:35                                                       ` Mike Frysinger
@ 2012-03-14  2:05                                                         ` Marek Vasut
  0 siblings, 0 replies; 83+ messages in thread
From: Marek Vasut @ 2012-03-14  2:05 UTC (permalink / raw)
  To: u-boot

Dear Mike Frysinger,

> On Wednesday 07 March 2012 02:12:22 puneets wrote:
> > On Tuesday 06 March 2012 08:37 AM, Mike Frysinger wrote:
> > >> --- a/drivers/usb/host/ehci-hcd.c
> > >> +++ b/drivers/usb/host/ehci-hcd.c
> > >> 
> > >>   static void flush_invalidate(u32 addr, int size, int flush)
> > >>   {
> > >> 
> > >> +	/*
> > >> +	 * Size is the bytes actually moved during transaction,
> > >> +	 * which may not equal to the cache line. This results
> > >> +	 * stop address passed for invalidating cache may not be 
aligned.
> > >> +	 * Therfore making size as multiple of cache line size.
> > >> +	 */
> > >> +	size = ALIGN(size, ARCH_DMA_MINALIGN);
> > >> +
> > >> 
> > >>   	if (flush)
> > >>   	
> > >>   		flush_dcache_range(addr, addr + size);
> > >>   	
> > >>   	else
> > > 
> > > i think this is wrong and merely hides the errors from higher up
> > > instead of fixing them.  the point of the warning was to tell you that
> > > the code was invalidating *too many* bytes.  this code still
> > > invalidates too many bytes without any justification as for why it's
> > > OK to do here.  further, this code path only matters to the
> > > invalidation logic, not the flush logic.
> > 
> > The sole purpose of this patch to remove the warnings as start/stop
> > address sent for invalidating
> > is unaligned. Without this patch code works fine but with lots of
> > spew...Which we don't want and discussed
> > in earlier thread which Simon posted. Please have a look on following
> > link.
> > 
> > As I understood, you agree that we need to align start/stop buffer
> > address and also agree that
> > to align stop address we need to align size as start address is already
> > aligned.
> > Now, "why its OK to do here"?
> > We could have aligned the size in two places, cache_qtd() and cache_qh()
> > but then we need to place alignment check
> > at all the places where size is passed. So I thought better Aligning at
> > flush_invalidate() and "ALIGN" macro does not
> > increase the size if size is already aligned.
> 
> i think you missed my point.  consider a func which has local vars like so:
> 	int i;
> 	char buf[1024];
> 	int k;
> 
> and let's say you're running on a core that has a cache line size of 32
> bytes (which is fairly common).  if you execute a data cache invalid insn,
> the smallest region it can invalidate is 32 bytes.  doesn't matter if you
> only want to invalidate a buffer of 8 bytes ... everything else around it
> gets invalidated as well.
> 
> now, in the aforementioned stack, if it starts off aligned nicely at a 32
> byte boundary, the integer "i" will share a cache line with the first 28
> bytes of buffer "buf", and the integer "k" will share a cache line with
> the last 4 bytes of the buffer "buf".  (let's ignore what might or might
> not happen based on gcc since this example can trivially be expanded to
> structure layout.)
> 
> the trouble is when you attempt to invalidate the contents of "buf".  if
> the cache is in writeback mode (which means you could have changes in the
> cache which are not reflected in external RAM), then invalidating buf will
> also discard values that might be in "i" or "k".  this is why Simon put a
> warning in the core data cache invalidate function.  if the cache were in
> writethrough mode (which also tends to be the default), then most likely
> things would work fine and no one would notice.  or if the data cache was
> merely flushed, things would work, but at a decrease in performance: you'd
> be flushing cache lines to external memory that you know will be
> overwritten by a following transaction -- most likely DMA from a
> peripheral such as the USB controller, and you'd be flushing objects that
> the DMA wouldn't be touching, so they'd have to get refetched from
> external RAM ("i" and "k" in my example above).
> 
> simply rounding the address down to the start of the cache line and the
> length up to a multiple of a cache line to keep the core code from issuing
> the warning doesn't fix the problem i describe above.  you actually get
> the worst of both worlds -- silent runtime misbehavior when extra memory
> gets invalidated.
> 
> perhaps the warning in the core code could be dropped and all your changes
> in fringe code obsoleted (such as these USB patches): when it detects that
> an address is starting on an unaligned boundary, *flush* that line first,
> and then let it be invalidated.  accordingly, when the end length is on an
> unaligned boundary, do the same flush-then-invalidate step.  this should
> also make things work without a (significant) loss in performance.  if
> anything, i suspect the overhead of doing runtime buffer size calculations
> and manually aligning pointers (which is what ALLOC_CACHE_ALIGN_BUFFER
> does) is a wash compared to partially flushing cache lines in the core ...
> 
> Simon: what do you think of this last idea ?
> -mike

Did we get anywhere with this?

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-07  7:12                                                     ` puneets
                                                                         ` (2 preceding siblings ...)
  2012-03-11  2:35                                                       ` Mike Frysinger
@ 2012-03-16  4:39                                                       ` Marek Vasut
  2012-03-16  7:42                                                         ` puneets
  3 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-16  4:39 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

What's the development on this patch? I gave it a run (find attachment, I 
rebased it), but it doesn't work (alignment issues in ehci_hcd). Even if I added 
a bounce buffer, it still didn't work :-(

Best regards,
Marek Vasut
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0010-USB-Align-buffers-at-cacheline.patch
Type: text/x-patch
Size: 13978 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120316/2b904d83/attachment.bin>

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-16  4:39                                                       ` Marek Vasut
@ 2012-03-16  7:42                                                         ` puneets
  2012-03-16  8:52                                                           ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-16  7:42 UTC (permalink / raw)
  To: u-boot

Hi Marek,
I need to remove the changes in ehci_hcd.c as per Mike's comment and 
adapt my patch for git://git.denx.de/u-boot-usb.git master branch.
So will be sending next patch with the above changes, shortly.

With this resultant patch we see warnings for few start address 
warnings(related to ehci_hcd.c) and stop address warnings.

Warnings due to ehci_hcd.c, can be avoided by giving delay of 1ms in 
after handshake(), but this is a HACK and a proper solution.
Working on the root cause.

Thanks & Regards,
Puneet


On Friday 16 March 2012 10:09 AM, Marek Vasut wrote:
> Dear Puneet Saxena,
>
> What's the development on this patch? I gave it a run (find attachment, I
> rebased it), but it doesn't work (alignment issues in ehci_hcd). Even if I added
> a bounce buffer, it still didn't work :-(
>
> Best regards,
> Marek Vasut


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-16  7:42                                                         ` puneets
@ 2012-03-16  8:52                                                           ` Marek Vasut
  2012-03-19 14:29                                                             ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-16  8:52 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

I hope you found the rebased patch I attached useful.

> Hi Marek,
> I need to remove the changes in ehci_hcd.c as per Mike's comment and
> adapt my patch for git://git.denx.de/u-boot-usb.git master branch.
> So will be sending next patch with the above changes, shortly.

Let me rebase u-boot-usb.git on top of mainline u-boot for you (done) :)

> 
> With this resultant patch we see warnings for few start address
> warnings(related to ehci_hcd.c) and stop address warnings.

This is ok, let's work on it slowly and do it properly :) I'll be happy to 
assist you by testing etc.
> 
> Warnings due to ehci_hcd.c, can be avoided by giving delay of 1ms in
> after handshake(), but this is a HACK and a proper solution.
> Working on the root cause.

I see ... thanks for your efforts!

> 
> Thanks & Regards,
> Puneet
> 

Thank you!

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-16  8:52                                                           ` Marek Vasut
@ 2012-03-19 14:29                                                             ` puneets
  2012-03-19 14:43                                                               ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: puneets @ 2012-03-19 14:29 UTC (permalink / raw)
  To: u-boot

Hi Marek,
I adapted my patch for git://git.denx.de/u-boot-usb.git master branch.
As the build for target "Seaboard" is broken once I enable USB in 
Seaboard.h,
I am unable to test my changes on "u-boot-usb".
I would have to merge lots of changes from "denx-uboot-tegra" to make it 
working for "u-boot-usb.git" master branch.
I can send the adapted patch if it's needed.

Thanks,
Puneet

On Friday 16 March 2012 02:22 PM, Marek Vasut wrote:
> Dear Puneet Saxena,
>
> I hope you found the rebased patch I attached useful.
>
>> Hi Marek,
>> I need to remove the changes in ehci_hcd.c as per Mike's comment and
>> adapt my patch for git://git.denx.de/u-boot-usb.git master branch.
>> So will be sending next patch with the above changes, shortly.
> Let me rebase u-boot-usb.git on top of mainline u-boot for you (done) :)
>
>> With this resultant patch we see warnings for few start address
>> warnings(related to ehci_hcd.c) and stop address warnings.
> This is ok, let's work on it slowly and do it properly :) I'll be happy to
> assist you by testing etc.
>> Warnings due to ehci_hcd.c, can be avoided by giving delay of 1ms in
>> after handshake(), but this is a HACK and a proper solution.
>> Working on the root cause.
> I see ... thanks for your efforts!
>
>> Thanks&  Regards,
>> Puneet
>>
> Thank you!
>
> Best regards,
> Marek Vasut


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-19 14:29                                                             ` puneets
@ 2012-03-19 14:43                                                               ` Marek Vasut
  2012-03-19 15:19                                                                 ` Tom Warren
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-19 14:43 UTC (permalink / raw)
  To: u-boot

Dear Puneet Saxena,

> Hi Marek,
> I adapted my patch for git://git.denx.de/u-boot-usb.git master branch.
> As the build for target "Seaboard" is broken once I enable USB in
> Seaboard.h,
> I am unable to test my changes on "u-boot-usb".

u-boot-usb is forked off the mainline u-boot.git ... tegra stuff likely isn't 
pulled there. Simon, can you tell me when this is gonna be there?

> I would have to merge lots of changes from "denx-uboot-tegra" to make it
> working for "u-boot-usb.git" master branch.
> I can send the adapted patch if it's needed.

The problem I see is that there are important USB patches in mainline, though 
they are not in -tegra. So the approach I'd take if I were you would be to 
rebase -tegra atop of mainline for yourself and then apply your patch. Does that 
work for you?

> 
> Thanks,
> Puneet

Thanks!

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-19 14:43                                                               ` Marek Vasut
@ 2012-03-19 15:19                                                                 ` Tom Warren
  2012-03-19 15:46                                                                   ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: Tom Warren @ 2012-03-19 15:19 UTC (permalink / raw)
  To: u-boot

Marek,

> -----Original Message-----
> From: Marek Vasut [mailto:marek.vasut at gmail.com]
> Sent: Monday, March 19, 2012 7:43 AM
> To: Puneet Saxena
> Cc: Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
> linux at bohmer.net; trini at ti.com; Tom Warren
> Subject: Re: [PATCH v8] usb: align buffers at cacheline
> 
> Dear Puneet Saxena,
> 
> > Hi Marek,
> > I adapted my patch for git://git.denx.de/u-boot-usb.git master branch.
> > As the build for target "Seaboard" is broken once I enable USB in
> > Seaboard.h, I am unable to test my changes on "u-boot-usb".
> 
> u-boot-usb is forked off the mainline u-boot.git ... tegra stuff likely
> isn't pulled there. Simon, can you tell me when this is gonna be there?

Simon's USB/fdt patch set will be pulled into -arm first, then -main, when he adapts the 'panic' putc patchset (implement pre-console putc for fdt warning) to meet with Wolfgang's approval. Once that's done (hopefully early this week), I can submit another pull request to finally get this series in.

Simon - can we have an ETA?

Tom
> 
> > I would have to merge lots of changes from "denx-uboot-tegra" to make
> > it working for "u-boot-usb.git" master branch.
> > I can send the adapted patch if it's needed.
> 
> The problem I see is that there are important USB patches in mainline,
> though they are not in -tegra. So the approach I'd take if I were you would
> be to rebase -tegra atop of mainline for yourself and then apply your patch.
> Does that work for you?
> 
> >
> > Thanks,
> > Puneet
> 
> Thanks!
> 
> Best regards,
> Marek Vasut
-- 
nvpublic

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-19 15:19                                                                 ` Tom Warren
@ 2012-03-19 15:46                                                                   ` Marek Vasut
  2012-04-02 15:59                                                                     ` Tom Warren
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-03-19 15:46 UTC (permalink / raw)
  To: u-boot

Dear Tom Warren,

> Marek,
> 
> > -----Original Message-----
> > From: Marek Vasut [mailto:marek.vasut at gmail.com]
> > Sent: Monday, March 19, 2012 7:43 AM
> > To: Puneet Saxena
> > Cc: Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
> > linux at bohmer.net; trini at ti.com; Tom Warren
> > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > 
> > Dear Puneet Saxena,
> > 
> > > Hi Marek,
> > > I adapted my patch for git://git.denx.de/u-boot-usb.git master branch.
> > > As the build for target "Seaboard" is broken once I enable USB in
> > > Seaboard.h, I am unable to test my changes on "u-boot-usb".
> > 
> > u-boot-usb is forked off the mainline u-boot.git ... tegra stuff likely
> > isn't pulled there. Simon, can you tell me when this is gonna be there?
> 
> Simon's USB/fdt patch set will be pulled into -arm first, then -main, when
> he adapts the 'panic' putc patchset (implement pre-console putc for fdt
> warning) to meet with Wolfgang's approval. Once that's done (hopefully
> early this week), I can submit another pull request to finally get this
> series in.
> 
> Simon - can we have an ETA?

I'd love to see some ETA on u-boot-arm push from Albert Aribaud :-( Albert, 
how're you doing ?

Thanks!

> 
> Tom
> 
> > > I would have to merge lots of changes from "denx-uboot-tegra" to make
> > > it working for "u-boot-usb.git" master branch.
> > > I can send the adapted patch if it's needed.
> > 
> > The problem I see is that there are important USB patches in mainline,
> > though they are not in -tegra. So the approach I'd take if I were you
> > would be to rebase -tegra atop of mainline for yourself and then apply
> > your patch. Does that work for you?
> > 
> > > Thanks,
> > > Puneet
> > 
> > Thanks!
> > 
> > Best regards,
> > Marek Vasut

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-03-19 15:46                                                                   ` Marek Vasut
@ 2012-04-02 15:59                                                                     ` Tom Warren
  2012-04-02 16:11                                                                       ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: Tom Warren @ 2012-04-02 15:59 UTC (permalink / raw)
  To: u-boot

Marek, Puneet, et al.,

> -----Original Message-----
> From: Marek Vasut [mailto:marex at denx.de]
> Sent: Monday, March 19, 2012 8:47 AM
> To: Tom Warren
> Cc: Puneet Saxena; Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
> linux at bohmer.net; trini at ti.com; albert.u.boot at aribaud.net
> Subject: Re: [PATCH v8] usb: align buffers at cacheline
> 
> Dear Tom Warren,
> 
> > Marek,
> >
> > > -----Original Message-----
> > > From: Marek Vasut [mailto:marek.vasut at gmail.com]
> > > Sent: Monday, March 19, 2012 7:43 AM
> > > To: Puneet Saxena
> > > Cc: Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
> > > linux at bohmer.net; trini at ti.com; Tom Warren
> > > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > >
> > > Dear Puneet Saxena,
> > >
> > > > Hi Marek,
> > > > I adapted my patch for git://git.denx.de/u-boot-usb.git master branch.
> > > > As the build for target "Seaboard" is broken once I enable USB in
> > > > Seaboard.h, I am unable to test my changes on "u-boot-usb".
> > >
> > > u-boot-usb is forked off the mainline u-boot.git ... tegra stuff
> > > likely isn't pulled there. Simon, can you tell me when this is gonna be
> there?
> >
> > Simon's USB/fdt patch set will be pulled into -arm first, then -main,
> > when he adapts the 'panic' putc patchset (implement pre-console putc
> > for fdt
> > warning) to meet with Wolfgang's approval. Once that's done (hopefully
> > early this week), I can submit another pull request to finally get
> > this series in.
> >
> > Simon - can we have an ETA?
> 
> I'd love to see some ETA on u-boot-arm push from Albert Aribaud :-( Albert,
> how're you doing ?
> 
> Thanks!
> 

u-boot-tegra/master has the fdt/USB patches, and has been pulled into ARM master.

We need the cacheline/buffer alignment patch now, to remove the volcanic spew whenever you do any USB commands.

Can you guys (Puneet & Marek, and Mike/Simon if necessary) work together to get this in soon?

Thanks,

Tom
> >
> > Tom
> >
> > > > I would have to merge lots of changes from "denx-uboot-tegra" to
> > > > make it working for "u-boot-usb.git" master branch.
> > > > I can send the adapted patch if it's needed.
> > >
> > > The problem I see is that there are important USB patches in
> > > mainline, though they are not in -tegra. So the approach I'd take if
> > > I were you would be to rebase -tegra atop of mainline for yourself
> > > and then apply your patch. Does that work for you?
> > >
> > > > Thanks,
> > > > Puneet
> > >
> > > Thanks!
> > >
> > > Best regards,
> > > Marek Vasut
> 
> Best regards,
> Marek Vasut
-- 
nvpublic

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-04-02 15:59                                                                     ` Tom Warren
@ 2012-04-02 16:11                                                                       ` Marek Vasut
  2012-04-02 16:16                                                                         ` Tom Warren
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-04-02 16:11 UTC (permalink / raw)
  To: u-boot

Dear Tom Warren,

> Marek, Puneet, et al.,
> 
> > -----Original Message-----
> > From: Marek Vasut [mailto:marex at denx.de]
> > Sent: Monday, March 19, 2012 8:47 AM
> > To: Tom Warren
> > Cc: Puneet Saxena; Mike Frysinger; u-boot at lists.denx.de;
> > sjg at chromium.org; linux at bohmer.net; trini at ti.com;
> > albert.u.boot at aribaud.net
> > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > 
> > Dear Tom Warren,
> > 
> > > Marek,
> > > 
> > > > -----Original Message-----
> > > > From: Marek Vasut [mailto:marek.vasut at gmail.com]
> > > > Sent: Monday, March 19, 2012 7:43 AM
> > > > To: Puneet Saxena
> > > > Cc: Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
> > > > linux at bohmer.net; trini at ti.com; Tom Warren
> > > > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > > > 
> > > > Dear Puneet Saxena,
> > > > 
> > > > > Hi Marek,
> > > > > I adapted my patch for git://git.denx.de/u-boot-usb.git master
> > > > > branch. As the build for target "Seaboard" is broken once I enable
> > > > > USB in Seaboard.h, I am unable to test my changes on "u-boot-usb".
> > > > 
> > > > u-boot-usb is forked off the mainline u-boot.git ... tegra stuff
> > > > likely isn't pulled there. Simon, can you tell me when this is gonna
> > > > be
> > 
> > there?
> > 
> > > Simon's USB/fdt patch set will be pulled into -arm first, then -main,
> > > when he adapts the 'panic' putc patchset (implement pre-console putc
> > > for fdt
> > > warning) to meet with Wolfgang's approval. Once that's done (hopefully
> > > early this week), I can submit another pull request to finally get
> > > this series in.
> > > 
> > > Simon - can we have an ETA?
> > 
> > I'd love to see some ETA on u-boot-arm push from Albert Aribaud :-(
> > Albert, how're you doing ?
> > 
> > Thanks!
> 
> u-boot-tegra/master has the fdt/USB patches, and has been pulled into ARM
> master.
> 
> We need the cacheline/buffer alignment patch now, to remove the volcanic
> spew whenever you do any USB commands.
> 
> Can you guys (Puneet & Marek, and Mike/Simon if necessary) work together to
> get this in soon?

Ain't you gonna help us? I believe the patch is really close to be usable, it 
just needs some easy debugging, won't you volunteer, it'd really help? :)

> Thanks,
> 
> Tom
> 
> > > Tom
> > > 
> > > > > I would have to merge lots of changes from "denx-uboot-tegra" to
> > > > > make it working for "u-boot-usb.git" master branch.
> > > > > I can send the adapted patch if it's needed.
> > > > 
> > > > The problem I see is that there are important USB patches in
> > > > mainline, though they are not in -tegra. So the approach I'd take if
> > > > I were you would be to rebase -tegra atop of mainline for yourself
> > > > and then apply your patch. Does that work for you?
> > > > 
> > > > > Thanks,
> > > > > Puneet
> > > > 
> > > > Thanks!
> > > > 
> > > > Best regards,
> > > > Marek Vasut
> > 
> > Best regards,
> > Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-04-02 16:11                                                                       ` Marek Vasut
@ 2012-04-02 16:16                                                                         ` Tom Warren
  2012-04-02 16:32                                                                           ` Marek Vasut
  0 siblings, 1 reply; 83+ messages in thread
From: Tom Warren @ 2012-04-02 16:16 UTC (permalink / raw)
  To: u-boot

Marek,

> -----Original Message-----
> From: Marek Vasut [mailto:marex at denx.de]
> Sent: Monday, April 02, 2012 9:12 AM
> To: Tom Warren
> Cc: Puneet Saxena; Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
> linux at bohmer.net; trini at ti.com; albert.u.boot at aribaud.net
> Subject: Re: [PATCH v8] usb: align buffers at cacheline
> 
> Dear Tom Warren,
> 
> > Marek, Puneet, et al.,
> >
> > > -----Original Message-----
> > > From: Marek Vasut [mailto:marex at denx.de]
> > > Sent: Monday, March 19, 2012 8:47 AM
> > > To: Tom Warren
> > > Cc: Puneet Saxena; Mike Frysinger; u-boot at lists.denx.de;
> > > sjg at chromium.org; linux at bohmer.net; trini at ti.com;
> > > albert.u.boot at aribaud.net
> > > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > >
> > > Dear Tom Warren,
> > >
> > > > Marek,
> > > >
> > > > > -----Original Message-----
> > > > > From: Marek Vasut [mailto:marek.vasut at gmail.com]
> > > > > Sent: Monday, March 19, 2012 7:43 AM
> > > > > To: Puneet Saxena
> > > > > Cc: Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
> > > > > linux at bohmer.net; trini at ti.com; Tom Warren
> > > > > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > > > >
> > > > > Dear Puneet Saxena,
> > > > >
> > > > > > Hi Marek,
> > > > > > I adapted my patch for git://git.denx.de/u-boot-usb.git master
> > > > > > branch. As the build for target "Seaboard" is broken once I
> > > > > > enable USB in Seaboard.h, I am unable to test my changes on "u-
> boot-usb".
> > > > >
> > > > > u-boot-usb is forked off the mainline u-boot.git ... tegra stuff
> > > > > likely isn't pulled there. Simon, can you tell me when this is
> > > > > gonna be
> > >
> > > there?
> > >
> > > > Simon's USB/fdt patch set will be pulled into -arm first, then
> > > > -main, when he adapts the 'panic' putc patchset (implement
> > > > pre-console putc for fdt
> > > > warning) to meet with Wolfgang's approval. Once that's done
> > > > (hopefully early this week), I can submit another pull request to
> > > > finally get this series in.
> > > >
> > > > Simon - can we have an ETA?
> > >
> > > I'd love to see some ETA on u-boot-arm push from Albert Aribaud :-(
> > > Albert, how're you doing ?
> > >
> > > Thanks!
> >
> > u-boot-tegra/master has the fdt/USB patches, and has been pulled into
> > ARM master.
> >
> > We need the cacheline/buffer alignment patch now, to remove the
> > volcanic spew whenever you do any USB commands.
> >
> > Can you guys (Puneet & Marek, and Mike/Simon if necessary) work
> > together to get this in soon?
> 
> Ain't you gonna help us? I believe the patch is really close to be usable,
> it just needs some easy debugging, won't you volunteer, it'd really help? :)
> 
I can apply the latest patch (v8?) and see how much spew is still present, but I (a) have no expertise in cache/USB issues and (b) have a ton of patches to apply/push for Tegra2 and (as soon as those are in) Tegra3, so my BW is limited, and finally (c) this is Puneet's work, and I'd like to see him complete it (with help from the list).

Tom
> > Thanks,
> >
> > Tom
> >
> > > > Tom
> > > >
> > > > > > I would have to merge lots of changes from "denx-uboot-tegra"
> > > > > > to make it working for "u-boot-usb.git" master branch.
> > > > > > I can send the adapted patch if it's needed.
> > > > >
> > > > > The problem I see is that there are important USB patches in
> > > > > mainline, though they are not in -tegra. So the approach I'd
> > > > > take if I were you would be to rebase -tegra atop of mainline
> > > > > for yourself and then apply your patch. Does that work for you?
> > > > >
> > > > > > Thanks,
> > > > > > Puneet
> > > > >
> > > > > Thanks!
> > > > >
> > > > > Best regards,
> > > > > Marek Vasut
> > >
> > > Best regards,
> > > Marek Vasut
-- 
nvpublic

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-04-02 16:16                                                                         ` Tom Warren
@ 2012-04-02 16:32                                                                           ` Marek Vasut
  2012-04-03  6:05                                                                             ` puneets
  0 siblings, 1 reply; 83+ messages in thread
From: Marek Vasut @ 2012-04-02 16:32 UTC (permalink / raw)
  To: u-boot

Dear Tom Warren,

> Marek,
> 
> > -----Original Message-----
> > From: Marek Vasut [mailto:marex at denx.de]
> > Sent: Monday, April 02, 2012 9:12 AM
> > To: Tom Warren
> > Cc: Puneet Saxena; Mike Frysinger; u-boot at lists.denx.de;
> > sjg at chromium.org; linux at bohmer.net; trini at ti.com;
> > albert.u.boot at aribaud.net
> > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > 
> > Dear Tom Warren,
> > 
> > > Marek, Puneet, et al.,
> > > 
> > > > -----Original Message-----
> > > > From: Marek Vasut [mailto:marex at denx.de]
> > > > Sent: Monday, March 19, 2012 8:47 AM
> > > > To: Tom Warren
> > > > Cc: Puneet Saxena; Mike Frysinger; u-boot at lists.denx.de;
> > > > sjg at chromium.org; linux at bohmer.net; trini at ti.com;
> > > > albert.u.boot at aribaud.net
> > > > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > > > 
> > > > Dear Tom Warren,
> > > > 
> > > > > Marek,
> > > > > 
> > > > > > -----Original Message-----
> > > > > > From: Marek Vasut [mailto:marek.vasut at gmail.com]
> > > > > > Sent: Monday, March 19, 2012 7:43 AM
> > > > > > To: Puneet Saxena
> > > > > > Cc: Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
> > > > > > linux at bohmer.net; trini at ti.com; Tom Warren
> > > > > > Subject: Re: [PATCH v8] usb: align buffers at cacheline
> > > > > > 
> > > > > > Dear Puneet Saxena,
> > > > > > 
> > > > > > > Hi Marek,
> > > > > > > I adapted my patch for git://git.denx.de/u-boot-usb.git master
> > > > > > > branch. As the build for target "Seaboard" is broken once I
> > > > > > > enable USB in Seaboard.h, I am unable to test my changes on "u-
> > 
> > boot-usb".
> > 
> > > > > > u-boot-usb is forked off the mainline u-boot.git ... tegra stuff
> > > > > > likely isn't pulled there. Simon, can you tell me when this is
> > > > > > gonna be
> > > > 
> > > > there?
> > > > 
> > > > > Simon's USB/fdt patch set will be pulled into -arm first, then
> > > > > -main, when he adapts the 'panic' putc patchset (implement
> > > > > pre-console putc for fdt
> > > > > warning) to meet with Wolfgang's approval. Once that's done
> > > > > (hopefully early this week), I can submit another pull request to
> > > > > finally get this series in.
> > > > > 
> > > > > Simon - can we have an ETA?
> > > > 
> > > > I'd love to see some ETA on u-boot-arm push from Albert Aribaud :-(
> > > > Albert, how're you doing ?
> > > > 
> > > > Thanks!
> > > 
> > > u-boot-tegra/master has the fdt/USB patches, and has been pulled into
> > > ARM master.
> > > 
> > > We need the cacheline/buffer alignment patch now, to remove the
> > > volcanic spew whenever you do any USB commands.
> > > 
> > > Can you guys (Puneet & Marek, and Mike/Simon if necessary) work
> > > together to get this in soon?
> > 
> > Ain't you gonna help us? I believe the patch is really close to be
> > usable, it just needs some easy debugging, won't you volunteer, it'd
> > really help? :)
> 
> I can apply the latest patch (v8?) and see how much spew is still present,
> but I (a) have no expertise in cache/USB issues and (b) have a ton of
> patches to apply/push for Tegra2 and (as soon as those are in) Tegra3, so
> my BW is limited, and finally (c) this is Puneet's work, and I'd like to
> see him complete it (with help from the list).

Well, everyone does. And that's how FOSS works -- you scratch your own itch by 
sending a patch, thus helping everyone else ;-)

And hey, my boards don't have caches enabled (yet) so this is low-prio for me. 
Sure, if someone has this as a high-prio thing, patch is very welcome :)

> 
> Tom
> 
> > > Thanks,
> > > 
> > > Tom
> > > 
> > > > > Tom
> > > > > 
> > > > > > > I would have to merge lots of changes from "denx-uboot-tegra"
> > > > > > > to make it working for "u-boot-usb.git" master branch.
> > > > > > > I can send the adapted patch if it's needed.
> > > > > > 
> > > > > > The problem I see is that there are important USB patches in
> > > > > > mainline, though they are not in -tegra. So the approach I'd
> > > > > > take if I were you would be to rebase -tegra atop of mainline
> > > > > > for yourself and then apply your patch. Does that work for you?
> > > > > > 
> > > > > > > Thanks,
> > > > > > > Puneet
> > > > > > 
> > > > > > Thanks!
> > > > > > 
> > > > > > Best regards,
> > > > > > Marek Vasut
> > > > 
> > > > Best regards,
> > > > Marek Vasut

^ permalink raw reply	[flat|nested] 83+ messages in thread

* [U-Boot] [PATCH v8] usb: align buffers at cacheline
  2012-04-02 16:32                                                                           ` Marek Vasut
@ 2012-04-03  6:05                                                                             ` puneets
  0 siblings, 0 replies; 83+ messages in thread
From: puneets @ 2012-04-03  6:05 UTC (permalink / raw)
  To: u-boot

Hi Marek/Tom,
As I understood correctly.
I would merge my changes in "denx-uboot-arm/master" as 
"u-boot-tegra/master", where actually I tested my patch, is
pulled in "denx-uboot-arm/master".

Will that work...

Thanks & Regards,
Puneet

On Monday 02 April 2012 10:02 PM, Marek Vasut wrote:
> Dear Tom Warren,
>
>> Marek,
>>
>>> -----Original Message-----
>>> From: Marek Vasut [mailto:marex at denx.de]
>>> Sent: Monday, April 02, 2012 9:12 AM
>>> To: Tom Warren
>>> Cc: Puneet Saxena; Mike Frysinger; u-boot at lists.denx.de;
>>> sjg at chromium.org; linux at bohmer.net; trini at ti.com;
>>> albert.u.boot at aribaud.net
>>> Subject: Re: [PATCH v8] usb: align buffers at cacheline
>>>
>>> Dear Tom Warren,
>>>
>>>> Marek, Puneet, et al.,
>>>>
>>>>> -----Original Message-----
>>>>> From: Marek Vasut [mailto:marex at denx.de]
>>>>> Sent: Monday, March 19, 2012 8:47 AM
>>>>> To: Tom Warren
>>>>> Cc: Puneet Saxena; Mike Frysinger; u-boot at lists.denx.de;
>>>>> sjg at chromium.org; linux at bohmer.net; trini at ti.com;
>>>>> albert.u.boot at aribaud.net
>>>>> Subject: Re: [PATCH v8] usb: align buffers at cacheline
>>>>>
>>>>> Dear Tom Warren,
>>>>>
>>>>>> Marek,
>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: Marek Vasut [mailto:marek.vasut at gmail.com]
>>>>>>> Sent: Monday, March 19, 2012 7:43 AM
>>>>>>> To: Puneet Saxena
>>>>>>> Cc: Mike Frysinger; u-boot at lists.denx.de; sjg at chromium.org;
>>>>>>> linux at bohmer.net; trini at ti.com; Tom Warren
>>>>>>> Subject: Re: [PATCH v8] usb: align buffers at cacheline
>>>>>>>
>>>>>>> Dear Puneet Saxena,
>>>>>>>
>>>>>>>> Hi Marek,
>>>>>>>> I adapted my patch for git://git.denx.de/u-boot-usb.git master
>>>>>>>> branch. As the build for target "Seaboard" is broken once I
>>>>>>>> enable USB in Seaboard.h, I am unable to test my changes on "u-
>>> boot-usb".
>>>
>>>>>>> u-boot-usb is forked off the mainline u-boot.git ... tegra stuff
>>>>>>> likely isn't pulled there. Simon, can you tell me when this is
>>>>>>> gonna be
>>>>> there?
>>>>>
>>>>>> Simon's USB/fdt patch set will be pulled into -arm first, then
>>>>>> -main, when he adapts the 'panic' putc patchset (implement
>>>>>> pre-console putc for fdt
>>>>>> warning) to meet with Wolfgang's approval. Once that's done
>>>>>> (hopefully early this week), I can submit another pull request to
>>>>>> finally get this series in.
>>>>>>
>>>>>> Simon - can we have an ETA?
>>>>> I'd love to see some ETA on u-boot-arm push from Albert Aribaud :-(
>>>>> Albert, how're you doing ?
>>>>>
>>>>> Thanks!
>>>> u-boot-tegra/master has the fdt/USB patches, and has been pulled into
>>>> ARM master.
>>>>
>>>> We need the cacheline/buffer alignment patch now, to remove the
>>>> volcanic spew whenever you do any USB commands.
>>>>
>>>> Can you guys (Puneet&  Marek, and Mike/Simon if necessary) work
>>>> together to get this in soon?
>>> Ain't you gonna help us? I believe the patch is really close to be
>>> usable, it just needs some easy debugging, won't you volunteer, it'd
>>> really help? :)
>> I can apply the latest patch (v8?) and see how much spew is still present,
>> but I (a) have no expertise in cache/USB issues and (b) have a ton of
>> patches to apply/push for Tegra2 and (as soon as those are in) Tegra3, so
>> my BW is limited, and finally (c) this is Puneet's work, and I'd like to
>> see him complete it (with help from the list).
> Well, everyone does. And that's how FOSS works -- you scratch your own itch by
> sending a patch, thus helping everyone else ;-)
>
> And hey, my boards don't have caches enabled (yet) so this is low-prio for me.
> Sure, if someone has this as a high-prio thing, patch is very welcome :)
>
>> Tom
>>
>>>> Thanks,
>>>>
>>>> Tom
>>>>
>>>>>> Tom
>>>>>>
>>>>>>>> I would have to merge lots of changes from "denx-uboot-tegra"
>>>>>>>> to make it working for "u-boot-usb.git" master branch.
>>>>>>>> I can send the adapted patch if it's needed.
>>>>>>> The problem I see is that there are important USB patches in
>>>>>>> mainline, though they are not in -tegra. So the approach I'd
>>>>>>> take if I were you would be to rebase -tegra atop of mainline
>>>>>>> for yourself and then apply your patch. Does that work for you?
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Puneet
>>>>>>> Thanks!
>>>>>>>
>>>>>>> Best regards,
>>>>>>> Marek Vasut
>>>>> Best regards,
>>>>> Marek Vasut


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 83+ messages in thread

end of thread, other threads:[~2012-04-03  6:05 UTC | newest]

Thread overview: 83+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-17 10:50 [U-Boot] [PATCH] usb: align buffers at cache boundary Puneet Saxena
2012-02-17 17:23 ` Mike Frysinger
2012-02-23 14:25   ` [U-Boot] [PATCH 1/2] usb: align buffers at cacheline Puneet Saxena
2012-02-23 18:15     ` Mike Frysinger
2012-02-24 11:27       ` puneets
2012-02-24 12:42     ` Simon Glass
2012-02-27 15:36       ` [U-Boot] [PATCH v2 " Puneet Saxena
2012-02-27 16:49         ` Marek Vasut
2012-02-27 17:03           ` Simon Glass
2012-02-27 17:11             ` Marek Vasut
2012-02-27 17:27               ` Simon Glass
2012-02-29 14:21               ` [U-Boot] [PATCH v3 " Puneet Saxena
2012-02-29 21:35                 ` Marek Vasut
2012-03-01 13:51                   ` puneets
2012-03-01 18:38                     ` Marek Vasut
2012-03-02  6:56                       ` puneets
2012-03-02 10:43                         ` Marek Vasut
2012-03-02 12:50                           ` puneets
2012-03-02 12:58                             ` Marek Vasut
2012-03-02 13:35                               ` [U-Boot] [PATCH v4] " Puneet Saxena
2012-03-02 13:46                                 ` Marek Vasut
2012-03-02 14:00                                   ` puneets
2012-03-02 14:41                                     ` Marek Vasut
2012-03-02 15:21                                       ` puneets
2012-03-02 15:59                                         ` Marek Vasut
2012-03-02 16:45                                           ` Wolfgang Denk
2012-03-05  7:16                                             ` [U-Boot] [PATCH v5] " Puneet Saxena
2012-03-05 13:24                                               ` Eric Nelson
2012-03-05 13:35                                                 ` Marek Vasut
2012-03-05 14:46                                                 ` [U-Boot] [PATCH v8] " Puneet Saxena
2012-03-05 15:35                                                   ` Marek Vasut
2012-03-05 18:18                                                   ` Simon Glass
2012-03-06  0:36                                                     ` Marek Vasut
2012-03-06  0:39                                                       ` Marek Vasut
2012-03-06  7:00                                                     ` puneets
2012-03-06  8:22                                                       ` Marek Vasut
2012-03-06  3:07                                                   ` Mike Frysinger
2012-03-07  7:12                                                     ` puneets
2012-03-07  9:20                                                       ` puneets
2012-03-07 22:06                                                       ` Marek Vasut
2012-03-08 11:21                                                         ` puneets
2012-03-08 14:12                                                           ` Marek Vasut
2012-03-09  6:15                                                             ` puneets
2012-03-09 12:03                                                               ` Marek Vasut
2012-03-11  2:35                                                       ` Mike Frysinger
2012-03-14  2:05                                                         ` Marek Vasut
2012-03-16  4:39                                                       ` Marek Vasut
2012-03-16  7:42                                                         ` puneets
2012-03-16  8:52                                                           ` Marek Vasut
2012-03-19 14:29                                                             ` puneets
2012-03-19 14:43                                                               ` Marek Vasut
2012-03-19 15:19                                                                 ` Tom Warren
2012-03-19 15:46                                                                   ` Marek Vasut
2012-04-02 15:59                                                                     ` Tom Warren
2012-04-02 16:11                                                                       ` Marek Vasut
2012-04-02 16:16                                                                         ` Tom Warren
2012-04-02 16:32                                                                           ` Marek Vasut
2012-04-03  6:05                                                                             ` puneets
2012-03-05  7:27                                             ` [U-Boot] [PATCH v6] " Puneet Saxena
2012-03-05 12:03                                               ` Marek Vasut
2012-03-05 12:21                                                 ` [U-Boot] [PATCH v7] " Puneet Saxena
2012-03-05 12:41                                                   ` Marek Vasut
2012-03-06  3:28                                             ` [U-Boot] [PATCH v4] " Mike Frysinger
2012-03-06  8:24                                               ` Marek Vasut
2012-03-06 16:42                                                 ` Mike Frysinger
2012-02-29 14:21               ` [U-Boot] [PATCH v3 2/2] usb: Add CONFIG to fetch string descriptor Puneet Saxena
2012-02-29 21:29                 ` Marek Vasut
2012-03-01 11:07                   ` puneets
2012-03-01 11:45                     ` Marek Vasut
2012-03-01 12:59                       ` puneets
2012-03-01 13:13                         ` Marek Vasut
2012-03-05 12:48                           ` Marek Vasut
2012-03-05 13:14                             ` puneets
2012-03-05 21:15                               ` Marek Vasut
2012-02-28  9:34           ` [U-Boot] [PATCH v2 1/2] usb: align buffers at cacheline puneets
2012-02-29 21:38             ` Marek Vasut
2012-02-27 15:36       ` [U-Boot] [PATCH v2 2/2] usb: Add CONFIG to fetch string descriptor Puneet Saxena
2012-02-27 18:28         ` Mike Frysinger
2012-02-27 15:37       ` [U-Boot] [PATCH 1/2] usb: align buffers at cacheline puneets
2012-02-23 14:25   ` [U-Boot] [PATCH 2/2] usb: Add quirk "USB_QUIRK_STRING_FETCH_255" Puneet Saxena
2012-02-23 15:20     ` Tom Rini
2012-02-23 16:04     ` Tom Warren
2012-02-24  7:52       ` puneets

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.