* [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