mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] more dma fixes
@ 2012-06-21  9:55 Sascha Hauer
  2012-06-21  9:55 ` [PATCH 1/9] USB core: allocate setup_packet using dma_alloc Sascha Hauer
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

Hi All,

Based on Marcs series here are some more fixes to the cache handling for
USB/ehci. As Marc already mentioned we have to make sure that buffers which
are used for DMA are cacheline aligned, otherwise we risk corrupting data
around the buffers.

Sascha

----------------------------------------------------------------
Sascha Hauer (9):
      USB core: allocate setup_packet using dma_alloc
      USB core: device descriptor using dma_alloc
      USB core: Allocate tmpbuf using dma_alloc
      USB ehci: Use dma coherent buffers for qh/qtd
      USB ehci: put fields of struct qTD directly into struct QH
      USB storage: use dma_alloc where appropriate
      block: use dma_alloc to allocate buffers
      partition: Use dma_alloc for allocating buffers
      USB ehci: rework cache handling

 common/block.c                  |    7 +--
 common/partitions.c             |    5 +-
 drivers/usb/core/usb.c          |  100 ++++++++++++++++++++----------------
 drivers/usb/host/ehci-hcd.c     |  108 ++++++++++++---------------------------
 drivers/usb/host/ehci.h         |   10 +++-
 drivers/usb/storage/transport.c |   11 ++--
 include/usb/usb.h               |    3 +-
 7 files changed, 115 insertions(+), 129 deletions(-)

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 1/9] USB core: allocate setup_packet using dma_alloc
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  2012-06-21  9:55 ` [PATCH 2/9] USB core: device descriptor " Sascha Hauer
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

The setup packet needs to be dma save.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/core/usb.c |   18 +++++++++++-------
 include/usb/usb.h      |    1 +
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index bd2938d..7333c0e 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -52,6 +52,7 @@
 #include <asm/byteorder.h>
 #include <xfuncs.h>
 #include <init.h>
+#include <dma.h>
 
 #include <usb/usb.h>
 
@@ -67,7 +68,6 @@
 
 static int dev_index;
 static int asynch_allowed;
-static struct devrequest setup_packet;
 
 static int usb_hub_probe(struct usb_device *dev, int ifnum);
 static int hub_port_reset(struct usb_device *dev, int port,
@@ -454,6 +454,7 @@ static struct usb_device *usb_alloc_new_device(void)
 	usbdev->devnum = dev_index + 1;
 	usbdev->maxchild = 0;
 	usbdev->dev.bus = &usb_bus_type;
+	usbdev->setup_packet = dma_alloc(sizeof(*usbdev->setup_packet));
 
 	dev_index++;
 
@@ -471,6 +472,7 @@ void usb_rescan(void)
 		unregister_device(&dev->dev);
 		if (dev->hub)
 			free(dev->hub);
+		dma_free(dev->setup_packet);
 		free(dev);
 	}
 
@@ -532,6 +534,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 {
 	struct usb_host *host = dev->host;
 	int ret;
+	struct devrequest *setup_packet = dev->setup_packet;
 
 	if ((timeout == 0) && (!asynch_allowed)) {
 		/* request for a asynch control pipe is not allowed */
@@ -539,17 +542,18 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
 	}
 
 	/* 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 */
 
-	ret = host->submit_control_msg(dev, pipe, data, size, &setup_packet, timeout);
+	ret = host->submit_control_msg(dev, pipe, data, size, setup_packet,
+			timeout);
 	if (ret)
 		return ret;
 
diff --git a/include/usb/usb.h b/include/usb/usb.h
index 296e4e8..f836593 100644
--- a/include/usb/usb.h
+++ b/include/usb/usb.h
@@ -161,6 +161,7 @@ struct usb_device {
 	int configno;			/* selected config number */
 	struct usb_device_descriptor descriptor; /* Device Descriptor */
 	struct usb_config_descriptor config; /* config descriptor */
+	struct devrequest *setup_packet;
 
 	int have_langid;		/* whether string_langid is valid yet */
 	int string_langid;		/* language ID for strings */
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 2/9] USB core: device descriptor using dma_alloc
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
  2012-06-21  9:55 ` [PATCH 1/9] USB core: allocate setup_packet using dma_alloc Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  2012-06-21  9:55 ` [PATCH 3/9] USB core: Allocate tmpbuf " Sascha Hauer
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

The device descriptor needs to be dma save.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/core/usb.c |   53 +++++++++++++++++++++++++-----------------------
 include/usb/usb.h      |    2 +-
 2 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 7333c0e..264ca2d 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -80,8 +80,8 @@ static void print_usb_device(struct usb_device *dev)
 {
 	printf("Bus %03d Device %03d: ID %04x:%04x %s\n",
 		dev->host->busnum, dev->devnum,
-		dev->descriptor.idVendor,
-		dev->descriptor.idProduct,
+		dev->descriptor->idVendor,
+		dev->descriptor->idProduct,
 		dev->prod);
 }
 
@@ -323,7 +323,7 @@ static int usb_new_device(struct usb_device *dev)
 	 * some more, or keeps on retransmitting the 8 byte header. */
 
 	desc = (struct usb_device_descriptor *)tmpbuf;
-	dev->descriptor.bMaxPacketSize0 = 64;	    /* Start off at 64 bytes  */
+	dev->descriptor->bMaxPacketSize0 = 64;	    /* Start off at 64 bytes  */
 	/* Default to 64 byte max packet size */
 	dev->maxpacketsize = PACKET_SIZE_64;
 	dev->epmaxpacketin[0] = 64;
@@ -335,7 +335,7 @@ static int usb_new_device(struct usb_device *dev)
 		return 1;
 	}
 
-	dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
+	dev->descriptor->bMaxPacketSize0 = desc->bMaxPacketSize0;
 
 	/* find the port number we're at */
 	if (parent) {
@@ -360,9 +360,9 @@ static int usb_new_device(struct usb_device *dev)
 		}
 	}
 
-	dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
-	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
-	switch (dev->descriptor.bMaxPacketSize0) {
+	dev->epmaxpacketin[0] = dev->descriptor->bMaxPacketSize0;
+	dev->epmaxpacketout[0] = dev->descriptor->bMaxPacketSize0;
+	switch (dev->descriptor->bMaxPacketSize0) {
 	case 8:
 		dev->maxpacketsize  = PACKET_SIZE_8;
 		break;
@@ -388,10 +388,10 @@ static int usb_new_device(struct usb_device *dev)
 
 	wait_ms(10);	/* Let the SET_ADDRESS settle */
 
-	tmp = sizeof(dev->descriptor);
+	tmp = sizeof(*dev->descriptor);
 
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-				 &dev->descriptor, sizeof(dev->descriptor));
+				 dev->descriptor, sizeof(*dev->descriptor));
 	if (err < tmp) {
 		if (err < 0)
 			printf("unable to get device descriptor (error=%d)\n",
@@ -402,10 +402,10 @@ static int usb_new_device(struct usb_device *dev)
 		return 1;
 	}
 	/* 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);
+	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);
@@ -417,19 +417,19 @@ static int usb_new_device(struct usb_device *dev)
 		return -1;
 	}
 	USB_PRINTF("new device: Mfr=%d, Product=%d, SerialNumber=%d\n",
-		   dev->descriptor.iManufacturer, dev->descriptor.iProduct,
-		   dev->descriptor.iSerialNumber);
+		   dev->descriptor->iManufacturer, dev->descriptor->iProduct,
+		   dev->descriptor->iSerialNumber);
 	memset(dev->mf, 0, sizeof(dev->mf));
 	memset(dev->prod, 0, sizeof(dev->prod));
 	memset(dev->serial, 0, sizeof(dev->serial));
-	if (dev->descriptor.iManufacturer)
-		usb_string(dev, dev->descriptor.iManufacturer,
+	if (dev->descriptor->iManufacturer)
+		usb_string(dev, dev->descriptor->iManufacturer,
 			   dev->mf, sizeof(dev->mf));
-	if (dev->descriptor.iProduct)
-		usb_string(dev, dev->descriptor.iProduct,
+	if (dev->descriptor->iProduct)
+		usb_string(dev, dev->descriptor->iProduct,
 			   dev->prod, sizeof(dev->prod));
-	if (dev->descriptor.iSerialNumber)
-		usb_string(dev, dev->descriptor.iSerialNumber,
+	if (dev->descriptor->iSerialNumber)
+		usb_string(dev, dev->descriptor->iSerialNumber,
 			   dev->serial, sizeof(dev->serial));
 	/* now prode if the device is a hub */
 	usb_hub_probe(dev, 0);
@@ -455,6 +455,7 @@ static struct usb_device *usb_alloc_new_device(void)
 	usbdev->maxchild = 0;
 	usbdev->dev.bus = &usb_bus_type;
 	usbdev->setup_packet = dma_alloc(sizeof(*usbdev->setup_packet));
+	usbdev->descriptor = dma_alloc(sizeof(*usbdev->descriptor));
 
 	dev_index++;
 
@@ -473,6 +474,7 @@ void usb_rescan(void)
 		if (dev->hub)
 			free(dev->hub);
 		dma_free(dev->setup_packet);
+		dma_free(dev->descriptor);
 		free(dev);
 	}
 
@@ -1288,11 +1290,11 @@ int usb_driver_register(struct usb_driver *drv)
 static int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
 {
 	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
-	    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
+	    id->idVendor != le16_to_cpu(dev->descriptor->idVendor))
 		return 0;
 
 	if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
-	    id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
+	    id->idProduct != le16_to_cpu(dev->descriptor->idProduct))
 		return 0;
 
 	return 1;
@@ -1315,7 +1317,7 @@ static int usb_match_one_id(struct usb_device *usbdev,
 	/* The interface class, subclass, and protocol should never be
 	 * checked for a match if the device class is Vendor Specific,
 	 * unless the match record specifies the Vendor ID. */
-	if (usbdev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+	if (usbdev->descriptor->bDeviceClass == USB_CLASS_VENDOR_SPEC &&
 			!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
 			(id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO))
 		return 0;
@@ -1375,7 +1377,8 @@ static int usb_match(struct device_d *dev, struct driver_d *drv)
 	struct usb_driver *usbdrv = container_of(dev->driver, struct usb_driver, driver);
 	const struct usb_device_id *id;
 
-	debug("matching: 0x%04x 0x%04x\n", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
+	debug("matching: 0x%04x 0x%04x\n", usbdev->descriptor->idVendor,
+			usbdev->descriptor->idProduct);
 
 	id = usb_match_id(usbdev, usbdrv->id_table);
 	if (id) {
diff --git a/include/usb/usb.h b/include/usb/usb.h
index f836593..f273983 100644
--- a/include/usb/usb.h
+++ b/include/usb/usb.h
@@ -159,7 +159,7 @@ struct usb_device {
 	int epmaxpacketout[16];		/* OUTput endpoint specific maximums */
 
 	int configno;			/* selected config number */
-	struct usb_device_descriptor descriptor; /* Device Descriptor */
+	struct usb_device_descriptor *descriptor; /* Device Descriptor */
 	struct usb_config_descriptor config; /* config descriptor */
 	struct devrequest *setup_packet;
 
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 3/9] USB core: Allocate tmpbuf using dma_alloc
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
  2012-06-21  9:55 ` [PATCH 1/9] USB core: allocate setup_packet using dma_alloc Sascha Hauer
  2012-06-21  9:55 ` [PATCH 2/9] USB core: device descriptor " Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  2012-06-21  9:55 ` [PATCH 4/9] USB ehci: Use dma coherent buffers for qh/qtd Sascha Hauer
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

This needs to be dma save.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/core/usb.c |   29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 264ca2d..a5075d5 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -299,12 +299,14 @@ static int usb_new_device(struct usb_device *dev)
 {
 	int addr, err;
 	int tmp;
-	unsigned char tmpbuf[USB_BUFSIZ];
+	void *buf;
 	struct usb_device_descriptor *desc;
 	int port = -1;
 	struct usb_device *parent = dev->parent;
 	unsigned short portstatus;
 
+	buf = dma_alloc(USB_BUFSIZ);
+
 	/* We still haven't set the Address yet */
 	addr = dev->devnum;
 	dev->devnum = 0;
@@ -322,7 +324,7 @@ static int usb_new_device(struct usb_device *dev)
 	 * the maxpacket size is 8 or 16 the device may be waiting to transmit
 	 * some more, or keeps on retransmitting the 8 byte header. */
 
-	desc = (struct usb_device_descriptor *)tmpbuf;
+	desc = buf;
 	dev->descriptor->bMaxPacketSize0 = 64;	    /* Start off at 64 bytes  */
 	/* Default to 64 byte max packet size */
 	dev->maxpacketsize = PACKET_SIZE_64;
@@ -332,7 +334,7 @@ static int usb_new_device(struct usb_device *dev)
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
 	if (err < 0) {
 		USB_PRINTF("%s: usb_get_descriptor() failed with %d\n", __func__, err);
-		return 1;
+		goto err_out;
 	}
 
 	dev->descriptor->bMaxPacketSize0 = desc->bMaxPacketSize0;
@@ -349,14 +351,15 @@ static int usb_new_device(struct usb_device *dev)
 		}
 		if (port < 0) {
 			printf("%s: cannot locate device's port.\n", __func__);
-			return 1;
+			err = -ENODEV;
+			goto err_out;
 		}
 
 		/* reset the port for the second time */
 		err = hub_port_reset(dev->parent, port, &portstatus);
 		if (err < 0) {
 			printf("\n     Couldn't reset port %i\n", port);
-			return 1;
+			goto err_out;
 		}
 	}
 
@@ -383,7 +386,7 @@ static int usb_new_device(struct usb_device *dev)
 	if (err < 0) {
 		printf("\n      USB device not accepting new address " \
 			"(error=%lX)\n", dev->status);
-		return 1;
+		goto err_out;
 	}
 
 	wait_ms(10);	/* Let the SET_ADDRESS settle */
@@ -399,7 +402,7 @@ static int usb_new_device(struct usb_device *dev)
 		else
 			printf("USB device descriptor short read " \
 				"(expected %i, got %i)\n", tmp, err);
-		return 1;
+		goto err_out;
 	}
 	/* correct le values */
 	le16_to_cpus(&dev->descriptor->bcdUSB);
@@ -407,14 +410,14 @@ static 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, buf, 0);
+	usb_parse_config(dev, buf, 0);
 	usb_set_maxpacket(dev);
 	/* we set the default configuration here */
 	if (usb_set_configuration(dev, dev->config.bConfigurationValue)) {
 		printf("failed to set default configuration " \
 			"len %d, status %lX\n", dev->act_len, dev->status);
-		return -1;
+		goto err_out;
 	}
 	USB_PRINTF("new device: Mfr=%d, Product=%d, SerialNumber=%d\n",
 		   dev->descriptor->iManufacturer, dev->descriptor->iProduct,
@@ -441,7 +444,11 @@ static int usb_new_device(struct usb_device *dev)
 	register_device(&dev->dev);
 	list_add_tail(&dev->list, &usb_device_list);
 
-	return 0;
+	err = 0;
+
+err_out:
+	dma_free(buf);
+	return err;
 }
 
 static struct usb_device *usb_alloc_new_device(void)
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 4/9] USB ehci: Use dma coherent buffers for qh/qtd
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
                   ` (2 preceding siblings ...)
  2012-06-21  9:55 ` [PATCH 3/9] USB core: Allocate tmpbuf " Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  2012-06-21  9:55 ` [PATCH 5/9] USB ehci: put fields of struct qTD directly into struct QH Sascha Hauer
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

There's no point in syncing them manually. Instead, use
dma_alloc_coherent and skip the manual flushing/invalidating.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/host/ehci-hcd.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index a2473a9..425406d 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -148,9 +148,6 @@ static void cache_qh(struct ehci_priv *ehci, int flush)
 {
 	int i;
 
-	flush_invalidate(ehci->qh_list, sizeof(struct QH) * NUM_QH, flush);
-	flush_invalidate(ehci->td, sizeof(struct qTD) * NUM_TD, flush);
-
 	for (i = 0; i < NUM_TD; i ++)
 		cache_qtd(&ehci->td[i], flush);
 }
@@ -878,8 +875,8 @@ static int ehci_probe(struct device_d *dev)
 	ehci->hccr = dev_request_mem_region(dev, 0);
 	ehci->hcor = dev_request_mem_region(dev, 1);
 
-	ehci->qh_list = xmemalign(32, sizeof(struct QH) * NUM_QH);
-	ehci->td = xmemalign(32, sizeof(struct qTD) * NUM_TD);
+	ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD);
+	ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD);
 
 	host->init = ehci_init;
 	host->submit_int_msg = submit_int_msg;
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 5/9] USB ehci: put fields of struct qTD directly into struct QH
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
                   ` (3 preceding siblings ...)
  2012-06-21  9:55 ` [PATCH 4/9] USB ehci: Use dma coherent buffers for qh/qtd Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  2012-06-21  9:55 ` [PATCH 6/9] USB storage: use dma_alloc where appropriate Sascha Hauer
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

This allows us to extend struct qTD with non hardware specific
fields.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/host/ehci-hcd.c |   22 +++++++++++-----------
 drivers/usb/host/ehci.h     |    6 +++++-
 2 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 425406d..929c8a6 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -293,11 +293,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	    (dev->portnr << 23) |
 	    (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
 	qh->qh_endpt2 = cpu_to_hc32(endpt);
-	qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
-	qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+	qh->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+	qh->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
 
 	td = NULL;
-	tdp = &qh->qh_overlay.qt_next;
+	tdp = &qh->qt_next;
 
 	toggle =
 	    usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
@@ -391,7 +391,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 			ehci_writel(&ehci->hcor->or_usbcmd, cmd);
 
 			ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, 0, 100 * 1000);
-			ehci_writel(&qh->qh_overlay.qt_token, 0);
+			ehci_writel(&qh->qt_token, 0);
 			return -ETIMEDOUT;
 		}
 	} while (token & 0x80);
@@ -410,7 +410,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 
 	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
 
-	token = hc32_to_cpu(qh->qh_overlay.qt_token);
+	token = hc32_to_cpu(qh->qt_token);
 	if (!(token & 0x80)) {
 		debug("TOKEN=0x%08x\n", token);
 		switch (token & 0xfc) {
@@ -448,10 +448,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 
 fail:
 	printf("fail1\n");
-	td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
+	td = (void *)hc32_to_cpu(qh->qt_next);
 	while (td != (void *)QT_NEXT_TERMINATE) {
-		qh->qh_overlay.qt_next = td->qt_next;
-		td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
+		qh->qt_next = td->qt_next;
+		td = (void *)hc32_to_cpu(qh->qt_next);
 	}
 	return -1;
 }
@@ -767,9 +767,9 @@ static int ehci_init(struct usb_host *host)
 	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
 	ehci->qh_list->qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
 	ehci->qh_list->qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
-	ehci->qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
-	ehci->qh_list->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
-	ehci->qh_list->qh_overlay.qt_token = cpu_to_hc32(0x40);
+	ehci->qh_list->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+	ehci->qh_list->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+	ehci->qh_list->qt_token = cpu_to_hc32(0x40);
 
 	/* Set async. queue head pointer. */
 	ehci_writel(&ehci->hcor->or_asynclistaddr, (uint32_t)ehci->qh_list);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index eac93db..76a3c85 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -179,7 +179,11 @@ struct QH {
 	uint32_t qh_endpt1;
 	uint32_t qh_endpt2;
 	uint32_t qh_curtd;
-	struct qTD qh_overlay;
+	 /* qtd overlay (hardware parts of a struct qTD) */
+	uint32_t qt_next;
+	uint32_t qt_altnext;
+	uint32_t qt_token;
+	uint32_t qt_buffer[5];
 	/*
 	 * Add dummy fill value to make the size of this struct
 	 * aligned to 32 bytes
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 6/9] USB storage: use dma_alloc where appropriate
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
                   ` (4 preceding siblings ...)
  2012-06-21  9:55 ` [PATCH 5/9] USB ehci: put fields of struct qTD directly into struct QH Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  2012-06-21  9:55 ` [PATCH 7/9] block: use dma_alloc to allocate buffers Sascha Hauer
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/storage/transport.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index e7a5972..68170b6 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -26,6 +26,7 @@
 #include <clock.h>
 #include <scsi.h>
 #include <errno.h>
+#include <dma.h>
 
 #undef USB_STOR_DEBUG
 
@@ -65,8 +66,8 @@ int usb_stor_Bulk_clear_endpt_stall(struct us_data *us, unsigned int pipe)
 /* Determine what the maximum LUN supported is */
 int usb_stor_Bulk_max_lun(struct us_data *us)
 {
-	int len;
-	unsigned char iobuf[1];
+	int len, ret = 0;
+	unsigned char *iobuf = dma_alloc(1);
 
 	/* issue the command */
 	iobuf[0] = 0;
@@ -81,7 +82,9 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
 
 	/* if we have a successful request, return the result */
 	if (len > 0)
-		return (int)iobuf[0];
+		ret = iobuf[0];
+
+	dma_free(iobuf);
 
 	/*
 	 * Some devices don't like GetMaxLUN.  They may STALL the control
@@ -90,7 +93,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
 	 * ways.  In these cases the best approach is to use the default
 	 * value: only one LUN.
 	 */
-	return 0;
+	return ret;
 }
 
 int usb_stor_Bulk_transport(ccb *srb, struct us_data *us)
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 7/9] block: use dma_alloc to allocate buffers
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
                   ` (5 preceding siblings ...)
  2012-06-21  9:55 ` [PATCH 6/9] USB storage: use dma_alloc where appropriate Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  2012-06-21  9:55 ` [PATCH 8/9] partition: Use dma_alloc for allocating buffers Sascha Hauer
  2012-06-21  9:55 ` [PATCH 9/9] USB ehci: rework cache handling Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

Drivers may use dma to transfer blocks, so put them into
dma save memory.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/block.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/common/block.c b/common/block.c
index 71ecfd5..f3bcdc8 100644
--- a/common/block.c
+++ b/common/block.c
@@ -24,6 +24,7 @@
 #include <malloc.h>
 #include <linux/err.h>
 #include <linux/list.h>
+#include <dma.h>
 
 #define BLOCKSIZE(blk)	(1 << blk->blockbits)
 
@@ -357,7 +358,7 @@ int blockdevice_register(struct block_device *blk)
 
 	for (i = 0; i < 8; i++) {
 		struct chunk *chunk = xzalloc(sizeof(*chunk));
-		chunk->data = xmalloc(BUFSIZE);
+		chunk->data = dma_alloc(BUFSIZE);
 		chunk->num = i;
 		list_add_tail(&chunk->list, &blk->idle_blocks);
 	}
@@ -376,12 +377,12 @@ int blockdevice_unregister(struct block_device *blk)
 	writebuffer_flush(blk);
 
 	list_for_each_entry_safe(chunk, tmp, &blk->buffered_blocks, list) {
-		free(chunk->data);
+		dma_free(chunk->data);
 		free(chunk);
 	}
 
 	list_for_each_entry_safe(chunk, tmp, &blk->idle_blocks, list) {
-		free(chunk->data);
+		dma_free(chunk->data);
 		free(chunk);
 	}
 
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 8/9] partition: Use dma_alloc for allocating buffers
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
                   ` (6 preceding siblings ...)
  2012-06-21  9:55 ` [PATCH 7/9] block: use dma_alloc to allocate buffers Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  2012-06-21  9:55 ` [PATCH 9/9] USB ehci: rework cache handling Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

Drivers may use dma to transfer blocks, so put them into
dma save memory.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/partitions.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/common/partitions.c b/common/partitions.c
index 74b4f12..3d92838 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -31,6 +31,7 @@
 #include <block.h>
 #include <asm/unaligned.h>
 #include <disks.h>
+#include <dma.h>
 
 struct partition {
 	uint64_t first_sec;
@@ -102,7 +103,7 @@ static void __maybe_unused try_dos_partition(struct block_device *blk,
 	struct partition pentry;
 	int i, rc;
 
-	buffer = xmalloc(SECTOR_SIZE);
+	buffer = dma_alloc(SECTOR_SIZE);
 
 	/* read in the MBR to get the partition table */
 	rc = blk->ops->read(blk, buffer, 0, 1);
@@ -142,7 +143,7 @@ static void __maybe_unused try_dos_partition(struct block_device *blk,
 	}
 
 on_error:
-	free(buffer);
+	dma_free(buffer);
 }
 
 /**
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 9/9] USB ehci: rework cache handling
  2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
                   ` (7 preceding siblings ...)
  2012-06-21  9:55 ` [PATCH 8/9] partition: Use dma_alloc for allocating buffers Sascha Hauer
@ 2012-06-21  9:55 ` Sascha Hauer
  8 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2012-06-21  9:55 UTC (permalink / raw)
  To: barebox

We do not need to invalidate the cache in the poll loop anymore
since the corresponding bit is now in a dma coherent area. Instead,
flush cache before hardware operation and invalidate afterwards. Put
the corresponding code inline since it's shorter.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/host/ehci-hcd.c |   79 ++++++++++++-------------------------------
 drivers/usb/host/ehci.h     |    4 ++-
 2 files changed, 24 insertions(+), 59 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 929c8a6..c2f48ce 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,60 +120,6 @@ static struct descriptor {
 
 #define ehci_is_TDI()	(ehci->flags & EHCI_HAS_TT)
 
-#ifdef CONFIG_MMU
-/*
- * Routines to handle (flush/invalidate) the dcache for the QH and qTD
- * structures and data buffers. This is needed on platforms using this
- * EHCI support with dcache enabled.
- */
-static void flush_invalidate(void *addr, int size, int flush)
-{
-	if (flush) {
-		dma_flush_range((unsigned long)addr, (unsigned long)(addr + size));
-	} else {
-		dma_inv_range((unsigned long)addr, (unsigned long)(addr + size));
-	}
-}
-
-static void cache_qtd(struct qTD *qtd, int flush)
-{
-	u32 *ptr = (u32 *)qtd->qt_buffer[0];
-	int len = (qtd->qt_token & 0x7fff0000) >> 16;
-
-	if (ptr && len)
-		flush_invalidate(ptr, len, flush);
-}
-
-static void cache_qh(struct ehci_priv *ehci, int flush)
-{
-	int i;
-
-	for (i = 0; i < NUM_TD; i ++)
-		cache_qtd(&ehci->td[i], flush);
-}
-
-static inline void ehci_flush_dcache(struct ehci_priv *ehci)
-{
-	cache_qh(ehci, 1);
-}
-
-static inline void ehci_invalidate_dcache(struct ehci_priv *ehci)
-{
-	cache_qh(ehci, 0);
-}
-#else /* CONFIG_MMU */
-/*
- *
- */
-static inline void ehci_flush_dcache(struct ehci_priv *ehci)
-{
-}
-
-static inline void ehci_invalidate_dcache(struct ehci_priv *ehci)
-{
-}
-#endif /* CONFIG_MMU */
-
 static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
 {
 	uint32_t result;
@@ -228,6 +174,9 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
 	int idx;
 
 	addr = (uint32_t) buf;
+	td->qtd_dma = addr;
+	td->length = sz;
+
 	idx = 0;
 	while (idx < 5) {
 		td->qt_buffer[idx] = cpu_to_hc32(addr);
@@ -261,7 +210,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	uint32_t endpt, token, usbsts;
 	uint32_t c, toggle;
 	uint32_t cmd;
-	int ret = 0;
+	int ret = 0, i;
 	uint64_t start, timeout_val;
 
 	debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
@@ -360,7 +309,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	ehci->qh_list->qh_link = cpu_to_hc32((uint32_t) qh | QH_LINK_TYPE_QH);
 
 	/* Flush dcache */
-	ehci_flush_dcache(ehci);
+	if (IS_ENABLED(CONFIG_MMU)) {
+		for (i = 0; i < NUM_TD; i ++) {
+			struct qTD *qtd = &ehci->td[i];
+			if (!qtd->qtd_dma)
+				continue;
+			dma_flush_range(qtd->qtd_dma, qtd->qtd_dma + qtd->length);
+		}
+	}
 
 	usbsts = ehci_readl(&ehci->hcor->or_usbsts);
 	ehci_writel(&ehci->hcor->or_usbsts, (usbsts & 0x3f));
@@ -381,8 +337,6 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 	start = get_time_ns();
 	vtd = td;
 	do {
-		/* Invalidate dcache */
-		ehci_invalidate_dcache(ehci);
 		token = hc32_to_cpu(vtd->qt_token);
 		if (is_timeout(start, timeout_val)) {
 			/* Disable async schedule. */
@@ -396,6 +350,15 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
 		}
 	} while (token & 0x80);
 
+	if (IS_ENABLED(CONFIG_MMU)) {
+		for (i = 0; i < NUM_TD; i ++) {
+			struct qTD *qtd = &ehci->td[i];
+			if (!qtd->qtd_dma)
+				continue;
+			dma_inv_range(qtd->qtd_dma, qtd->qtd_dma + qtd->length);
+		}
+	}
+
 	/* Disable async schedule. */
 	cmd = ehci_readl(&ehci->hcor->or_usbcmd);
 	cmd &= ~CMD_ASE;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 76a3c85..b127b95 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -166,7 +166,9 @@ struct qTD {
 	uint32_t qt_altnext;
 	uint32_t qt_token;
 	uint32_t qt_buffer[5];
-};
+	unsigned long qtd_dma;
+	size_t length;
+} __attribute__ ((aligned (32)));
 
 /* Queue Head (QH). */
 struct QH {
-- 
1.7.10


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

end of thread, other threads:[~2012-06-21  9:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-21  9:55 [PATCH] more dma fixes Sascha Hauer
2012-06-21  9:55 ` [PATCH 1/9] USB core: allocate setup_packet using dma_alloc Sascha Hauer
2012-06-21  9:55 ` [PATCH 2/9] USB core: device descriptor " Sascha Hauer
2012-06-21  9:55 ` [PATCH 3/9] USB core: Allocate tmpbuf " Sascha Hauer
2012-06-21  9:55 ` [PATCH 4/9] USB ehci: Use dma coherent buffers for qh/qtd Sascha Hauer
2012-06-21  9:55 ` [PATCH 5/9] USB ehci: put fields of struct qTD directly into struct QH Sascha Hauer
2012-06-21  9:55 ` [PATCH 6/9] USB storage: use dma_alloc where appropriate Sascha Hauer
2012-06-21  9:55 ` [PATCH 7/9] block: use dma_alloc to allocate buffers Sascha Hauer
2012-06-21  9:55 ` [PATCH 8/9] partition: Use dma_alloc for allocating buffers Sascha Hauer
2012-06-21  9:55 ` [PATCH 9/9] USB ehci: rework cache handling Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox