summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-07-02 10:59:22 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-07-02 10:59:22 +0200
commitdd3c898d06a55a4c6fe94dae3f732a541e983432 (patch)
tree9f8ea0b057a6a1b52c948214d27ccde9378326a9
parent649f558483f9959c0ac4123da8c7b647d9808be5 (diff)
parent40faf584cd60c1e0e083ac75eb9ef5f9e7c071d0 (diff)
downloadbarebox-dd3c898d06a55a4c6fe94dae3f732a541e983432.tar.gz
Merge branch 'for-next/dma-cache-align'
-rw-r--r--arch/arm/cpu/mmu.c4
-rw-r--r--arch/arm/include/asm/dma.h8
-rw-r--r--arch/arm/include/asm/mmu.h13
-rw-r--r--arch/blackfin/include/asm/dma.h13
-rw-r--r--arch/mips/include/asm/dma.h13
-rw-r--r--arch/nios2/include/asm/dma-mapping.h10
-rw-r--r--arch/nios2/include/asm/dma.h8
-rw-r--r--arch/openrisc/include/asm/dma.h13
-rw-r--r--arch/ppc/include/asm/dma.h13
-rw-r--r--arch/sandbox/include/asm/dma.h13
-rw-r--r--arch/x86/include/asm/dma.h13
-rw-r--r--common/block.c7
-rw-r--r--common/partitions.c5
-rw-r--r--drivers/usb/core/usb.c100
-rw-r--r--drivers/usb/gadget/composite.c5
-rw-r--r--drivers/usb/gadget/dfu.c5
-rw-r--r--drivers/usb/gadget/fsl_udc.c5
-rw-r--r--drivers/usb/host/ehci-hcd.c108
-rw-r--r--drivers/usb/host/ehci.h10
-rw-r--r--drivers/usb/storage/transport.c11
-rw-r--r--include/dma.h30
-rw-r--r--include/usb/usb.h3
22 files changed, 269 insertions, 141 deletions
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index c19f931..55b07a4 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -299,11 +299,9 @@ void *dma_alloc_coherent(size_t size)
size = PAGE_ALIGN(size);
ret = xmemalign(4096, size);
-#ifdef CONFIG_MMU
dma_inv_range((unsigned long)ret, (unsigned long)ret + size);
remap_range(ret, size, PTE_FLAGS_UNCACHED);
-#endif
return ret;
}
@@ -320,9 +318,7 @@ void *phys_to_virt(unsigned long phys)
void dma_free_coherent(void *mem, size_t size)
{
-#ifdef CONFIG_MMU
remap_range(mem, size, PTE_FLAGS_CACHED);
-#endif
free(mem);
}
diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h
new file mode 100644
index 0000000..cb9cd1b
--- /dev/null
+++ b/arch/arm/include/asm/dma.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <asm/mmu.h>
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index f5ae7a8..a66da8c 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -1,9 +1,12 @@
#ifndef __ASM_MMU_H
#define __ASM_MMU_H
-#include <asm/pgtable.h>
-#include <malloc.h>
+#include <common.h>
#include <errno.h>
+#include <malloc.h>
+#include <xfuncs.h>
+
+#include <asm/pgtable.h>
#define PMD_SECT_DEF_UNCACHED (PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT)
#define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED)
@@ -23,6 +26,12 @@ static inline void setup_dma_coherent(unsigned long offset)
{
}
+#define dma_alloc dma_alloc
+static inline void *dma_alloc(size_t size)
+{
+ return xmemalign(64, ALIGN(size, 64));
+}
+
#ifdef CONFIG_MMU
void *dma_alloc_coherent(size_t size);
void dma_free_coherent(void *mem, size_t size);
diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h
new file mode 100644
index 0000000..27d269f
--- /dev/null
+++ b/arch/blackfin/include/asm/dma.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __ASM_DMA_H
+#define __ASM_DMA_H
+
+/* empty */
+
+#endif /* __ASM_DMA_H */
diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h
new file mode 100644
index 0000000..27d269f
--- /dev/null
+++ b/arch/mips/include/asm/dma.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __ASM_DMA_H
+#define __ASM_DMA_H
+
+/* empty */
+
+#endif /* __ASM_DMA_H */
diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h
index 5b70f4c..9819a97 100644
--- a/arch/nios2/include/asm/dma-mapping.h
+++ b/arch/nios2/include/asm/dma-mapping.h
@@ -1,8 +1,12 @@
#ifndef __ASM_NIOS2_DMA_MAPPING_H
#define __ASM_NIOS2_DMA_MAPPING_H
+#include <common.h>
+#include <xfuncs.h>
+
#include <asm/cache.h>
+
/* dma_alloc_coherent() return cache-line aligned allocation which is mapped
* to uncached io region.
*
@@ -22,4 +26,10 @@ static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
return (void *)(*handle | IO_REGION_BASE);
}
+#define dma_alloc dma_alloc
+static inline void *dma_alloc(size_t size)
+{
+ return xmemalign(DCACHE_LINE_SIZE, ALIGN(size, DCACHE_LINE_SIZE));
+}
+
#endif /* __ASM_NIOS2_DMA_MAPPING_H */
diff --git a/arch/nios2/include/asm/dma.h b/arch/nios2/include/asm/dma.h
new file mode 100644
index 0000000..8f709d2
--- /dev/null
+++ b/arch/nios2/include/asm/dma.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <asm/dma-mapping.h>
diff --git a/arch/openrisc/include/asm/dma.h b/arch/openrisc/include/asm/dma.h
new file mode 100644
index 0000000..27d269f
--- /dev/null
+++ b/arch/openrisc/include/asm/dma.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __ASM_DMA_H
+#define __ASM_DMA_H
+
+/* empty */
+
+#endif /* __ASM_DMA_H */
diff --git a/arch/ppc/include/asm/dma.h b/arch/ppc/include/asm/dma.h
new file mode 100644
index 0000000..27d269f
--- /dev/null
+++ b/arch/ppc/include/asm/dma.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __ASM_DMA_H
+#define __ASM_DMA_H
+
+/* empty */
+
+#endif /* __ASM_DMA_H */
diff --git a/arch/sandbox/include/asm/dma.h b/arch/sandbox/include/asm/dma.h
new file mode 100644
index 0000000..4595367
--- /dev/null
+++ b/arch/sandbox/include/asm/dma.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __ASM_DMA_H
+#define __ASM_DMA_H
+
+/* empty*/
+
+#endif /* __ASM_DMA_H */
diff --git a/arch/x86/include/asm/dma.h b/arch/x86/include/asm/dma.h
new file mode 100644
index 0000000..27d269f
--- /dev/null
+++ b/arch/x86/include/asm/dma.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __ASM_DMA_H
+#define __ASM_DMA_H
+
+/* empty */
+
+#endif /* __ASM_DMA_H */
diff --git a/common/block.c b/common/block.c
index e40374f..7ad5ecc 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);
}
diff --git a/common/partitions.c b/common/partitions.c
index a8c9625..dc91933 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;
@@ -79,7 +80,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);
@@ -113,7 +114,7 @@ static void __maybe_unused try_dos_partition(struct block_device *blk,
}
on_error:
- free(buffer);
+ dma_free(buffer);
}
/**
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index bd2938d..a5075d5 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,
@@ -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);
}
@@ -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,8 +324,8 @@ 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;
- dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */
+ desc = buf;
+ 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;
@@ -332,10 +334,10 @@ 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;
+ dev->descriptor->bMaxPacketSize0 = desc->bMaxPacketSize0;
/* find the port number we're at */
if (parent) {
@@ -349,20 +351,21 @@ 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;
}
}
- 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;
@@ -383,15 +386,15 @@ 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 */
- 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",
@@ -399,37 +402,37 @@ 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);
- 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);
+ 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,
- 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);
@@ -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)
@@ -454,6 +461,8 @@ 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));
+ usbdev->descriptor = dma_alloc(sizeof(*usbdev->descriptor));
dev_index++;
@@ -471,6 +480,8 @@ void usb_rescan(void)
unregister_device(&dev->dev);
if (dev->hub)
free(dev->hub);
+ dma_free(dev->setup_packet);
+ dma_free(dev->descriptor);
free(dev);
}
@@ -532,6 +543,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 +551,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;
@@ -1284,11 +1297,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;
@@ -1311,7 +1324,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;
@@ -1371,7 +1384,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/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index fd70e62..44e58d7 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -22,6 +22,7 @@
#include <common.h>
#include <errno.h>
+#include <dma.h>
#include <usb/composite.h>
#include <asm/byteorder.h>
@@ -867,7 +868,7 @@ composite_unbind(struct usb_gadget *gadget)
composite->unbind(cdev);
if (cdev->req) {
- kfree(cdev->req->buf);
+ dma_free(cdev->req->buf);
usb_ep_free_request(gadget->ep0, cdev->req);
}
kfree(cdev);
@@ -911,7 +912,7 @@ static int __init composite_bind(struct usb_gadget *gadget)
cdev->req = usb_ep_alloc_request(gadget->ep0);
if (!cdev->req)
goto fail;
- cdev->req->buf = malloc(USB_BUFSIZ);
+ cdev->req->buf = dma_alloc(USB_BUFSIZ);
if (!cdev->req->buf)
goto fail;
cdev->req->complete = composite_setup_complete;
diff --git a/drivers/usb/gadget/dfu.c b/drivers/usb/gadget/dfu.c
index f26c1e4..e205c65 100644
--- a/drivers/usb/gadget/dfu.c
+++ b/drivers/usb/gadget/dfu.c
@@ -40,6 +40,7 @@
* - make 'dnstate' attached to 'struct usb_device_instance'
*/
+#include <dma.h>
#include <asm/byteorder.h>
#include <usb/composite.h>
#include <linux/types.h>
@@ -183,7 +184,7 @@ dfu_unbind(struct usb_configuration *c, struct usb_function *f)
if (gadget_is_dualspeed(c->cdev->gadget))
free(f->hs_descriptors);
- free(dfu->dnreq->buf);
+ dma_free(dfu->dnreq->buf);
usb_ep_free_request(c->cdev->gadget->ep0, dfu->dnreq);
free(dfu);
}
@@ -602,7 +603,7 @@ static int dfu_bind_config(struct usb_configuration *c)
dfu->dnreq = usb_ep_alloc_request(c->cdev->gadget->ep0);
if (!dfu->dnreq)
printf("usb_ep_alloc_request failed\n");
- dfu->dnreq->buf = xmalloc(CONFIG_USBD_DFU_XFER_SIZE);
+ dfu->dnreq->buf = dma_alloc(CONFIG_USBD_DFU_XFER_SIZE);
dfu->dnreq->complete = dn_complete;
dfu->dnreq->zero = 0;
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
index 5b64ec2..627e417 100644
--- a/drivers/usb/gadget/fsl_udc.c
+++ b/drivers/usb/gadget/fsl_udc.c
@@ -1,5 +1,6 @@
#include <common.h>
#include <errno.h>
+#include <dma.h>
#include <init.h>
#include <clock.h>
#include <usb/ch9.h>
@@ -8,7 +9,6 @@
#include <io.h>
#include <poller.h>
#include <asm/byteorder.h>
-#include <asm/mmu.h>
/* ### define USB registers here
*/
@@ -2109,7 +2109,8 @@ static int struct_udc_setup(struct fsl_udc *udc,
udc->status_req = container_of(fsl_alloc_request(NULL),
struct fsl_req, req);
/* allocate a small amount of memory to get valid address */
- udc->status_req->req.buf = xmalloc(8);
+ udc->status_req->req.buf = dma_alloc(8);
+ udc->status_req->req.length = 8;
udc->resume_state = USB_STATE_NOTATTACHED;
udc->usb_state = USB_STATE_POWERED;
udc->ep0_dir = 0;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index a2473a9..c2f48ce 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -120,63 +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;
-
- 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);
-}
-
-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;
@@ -231,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);
@@ -264,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,
@@ -296,11 +242,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));
@@ -363,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));
@@ -384,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. */
@@ -394,11 +345,20 @@ 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);
+ 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;
@@ -413,7 +373,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) {
@@ -451,10 +411,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;
}
@@ -770,9 +730,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);
@@ -878,8 +838,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;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index eac93db..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 {
@@ -179,7 +181,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
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)
diff --git a/include/dma.h b/include/dma.h
new file mode 100644
index 0000000..899f831
--- /dev/null
+++ b/include/dma.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __DMA_H
+#define __DMA_H
+
+#include <malloc.h>
+#include <xfuncs.h>
+
+#include <asm/dma.h>
+
+#ifndef dma_alloc
+static inline void *dma_alloc(size_t size)
+{
+ return xmalloc(size);
+}
+#endif
+
+#ifndef dma_free
+static inline void dma_free(void *mem)
+{
+ free(mem);
+}
+#endif
+
+#endif /* __DMA_H */
diff --git a/include/usb/usb.h b/include/usb/usb.h
index 8691400..19b092e 100644
--- a/include/usb/usb.h
+++ b/include/usb/usb.h
@@ -159,8 +159,9 @@ 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;
int have_langid; /* whether string_langid is valid yet */
int string_langid; /* language ID for strings */