]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-usb
authorWolfgang Denk <wd@denx.de>
Fri, 20 Jul 2012 07:12:43 +0000 (09:12 +0200)
committerWolfgang Denk <wd@denx.de>
Fri, 20 Jul 2012 07:12:43 +0000 (09:12 +0200)
* 'master' of git://git.denx.de/u-boot-usb:
  usb_storage: fix ehci driver max transfer size
  smsc95xx: align buffers to cache line size
  ehci-hcd: change debug() to printf() in case of errors
  usb: check return value of submit_{control, bulk}_msg
  usb: pass cache-aligned buffer to usb_get_descriptor()
  ehci-hcd: fix external buffer cache handling
  ehci-hcd.c, musb_core, usb.h: Add USB_DMA_MINALIGN define for cache alignment
  ehci-hcd: program asynclistaddr before every transfer
  common.h: Introduce DEFINE_CACHE_ALIGN_BUFFER
  ehci-omap: Do not call dcache_off from omap_ehci_hcd_init

Signed-off-by: Wolfgang Denk <wd@denx.de>
common/usb.c
common/usb_storage.c
drivers/usb/eth/smsc95xx.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-omap.c
drivers/usb/musb/musb_core.h
include/common.h
include/usb.h

index c80155ce762dec3c5f35d2ca99a41a1691b7ab0e..1b40228b28836697b5cb4715dd269a21c995ac3e 100644 (file)
@@ -188,7 +188,8 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
                   request, requesttype, value, index, size);
        dev->status = USB_ST_NOT_PROC; /*not yet processed */
 
-       submit_control_msg(dev, pipe, data, size, setup_packet);
+       if (submit_control_msg(dev, pipe, data, size, setup_packet) < 0)
+               return -1;
        if (timeout == 0)
                return (int)size;
 
@@ -220,7 +221,8 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
        if (len < 0)
                return -1;
        dev->status = USB_ST_NOT_PROC; /*not yet processed */
-       submit_bulk_msg(dev, pipe, data, len);
+       if (submit_bulk_msg(dev, pipe, data, len) < 0)
+               return -1;
        while (timeout--) {
                if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
                        break;
@@ -799,12 +801,13 @@ int usb_new_device(struct usb_device *dev)
        dev->epmaxpacketin[0] = 8;
        dev->epmaxpacketout[0] = 8;
 
-       err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
+       err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, tmpbuf, 8);
        if (err < 8) {
                printf("\n      USB device not responding, " \
                       "giving up (status=%lX)\n", dev->status);
                return 1;
        }
+       memcpy(&dev->descriptor, tmpbuf, 8);
 #else
        /* This is a Windows scheme of initialization sequence, with double
         * reset of the device (Linux uses the same sequence)
@@ -893,7 +896,7 @@ int usb_new_device(struct usb_device *dev)
        tmp = sizeof(dev->descriptor);
 
        err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-                                &dev->descriptor, sizeof(dev->descriptor));
+                                tmpbuf, sizeof(dev->descriptor));
        if (err < tmp) {
                if (err < 0)
                        printf("unable to get device descriptor (error=%d)\n",
@@ -903,6 +906,7 @@ int usb_new_device(struct usb_device *dev)
                                "(expected %i, got %i)\n", tmp, err);
                return 1;
        }
+       memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
        /* correct le values */
        le16_to_cpus(&dev->descriptor.bcdUSB);
        le16_to_cpus(&dev->descriptor.idVendor);
index faad23706f8d8bca3d3bd08f9ef1d5a4efcd5d38..bdc306f587fd9b73b60220d2b49e1151bbf9b4bd 100644 (file)
@@ -150,12 +150,17 @@ struct us_data {
        unsigned int    irqpipe;                /* pipe for release_irq */
        unsigned char   irqmaxp;                /* max packed for irq Pipe */
        unsigned char   irqinterval;            /* Intervall for IRQ Pipe */
-       unsigned long   max_xfer_blk;           /* Max blocks per xfer */
        ccb             *srb;                   /* current srb */
        trans_reset     transport_reset;        /* reset routine */
        trans_cmnd      transport;              /* transport routine */
 };
 
+/*
+ * The U-Boot EHCI driver cannot handle more than 5 page aligned buffers
+ * of 4096 bytes in a transfer without running itself out of qt_buffers
+ */
+#define USB_MAX_XFER_BLK(start, blksz) (((4096 * 5) - (start % 4096)) / blksz)
+
 static struct us_data usb_stor[USB_MAX_STOR_DEV];
 
 
@@ -1041,7 +1046,7 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor,
 unsigned long usb_stor_read(int device, unsigned long blknr,
                            unsigned long blkcnt, void *buffer)
 {
-       unsigned long start, blks, buf_addr;
+       unsigned long start, blks, buf_addr, max_xfer_blk;
        unsigned short smallblks;
        struct usb_device *dev;
        struct us_data *ss;
@@ -1083,12 +1088,14 @@ unsigned long usb_stor_read(int device, unsigned long blknr,
                /* XXX need some comment here */
                retry = 2;
                srb->pdata = (unsigned char *)buf_addr;
-               if (blks > ss->max_xfer_blk)
-                       smallblks = ss->max_xfer_blk;
+               max_xfer_blk = USB_MAX_XFER_BLK(buf_addr,
+                                               usb_dev_desc[device].blksz);
+               if (blks > max_xfer_blk)
+                       smallblks = (unsigned short) max_xfer_blk;
                else
                        smallblks = (unsigned short) blks;
 retry_it:
-               if (smallblks == ss->max_xfer_blk)
+               if (smallblks == max_xfer_blk)
                        usb_show_progress();
                srb->datalen = usb_dev_desc[device].blksz * smallblks;
                srb->pdata = (unsigned char *)buf_addr;
@@ -1109,7 +1116,7 @@ retry_it:
                        start, smallblks, buf_addr);
 
        usb_disable_asynch(0); /* asynch transfer allowed */
-       if (blkcnt >= ss->max_xfer_blk)
+       if (blkcnt >= max_xfer_blk)
                debug("\n");
        return blkcnt;
 }
@@ -1117,7 +1124,7 @@ retry_it:
 unsigned long usb_stor_write(int device, unsigned long blknr,
                                unsigned long blkcnt, const void *buffer)
 {
-       unsigned long start, blks, buf_addr;
+       unsigned long start, blks, buf_addr, max_xfer_blk;
        unsigned short smallblks;
        struct usb_device *dev;
        struct us_data *ss;
@@ -1162,12 +1169,14 @@ unsigned long usb_stor_write(int device, unsigned long blknr,
                 */
                retry = 2;
                srb->pdata = (unsigned char *)buf_addr;
-               if (blks > ss->max_xfer_blk)
-                       smallblks = ss->max_xfer_blk;
+               max_xfer_blk = USB_MAX_XFER_BLK(buf_addr,
+                                               usb_dev_desc[device].blksz);
+               if (blks > max_xfer_blk)
+                       smallblks = (unsigned short) max_xfer_blk;
                else
                        smallblks = (unsigned short) blks;
 retry_it:
-               if (smallblks == ss->max_xfer_blk)
+               if (smallblks == max_xfer_blk)
                        usb_show_progress();
                srb->datalen = usb_dev_desc[device].blksz * smallblks;
                srb->pdata = (unsigned char *)buf_addr;
@@ -1188,7 +1197,7 @@ retry_it:
                        start, smallblks, buf_addr);
 
        usb_disable_asynch(0); /* asynch transfer allowed */
-       if (blkcnt >= ss->max_xfer_blk)
+       if (blkcnt >= max_xfer_blk)
                debug("\n");
        return blkcnt;
 
@@ -1415,12 +1424,6 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
        USB_STOR_PRINTF(" address %d\n", dev_desc->target);
        USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
 
-       /*
-        * The U-Boot EHCI driver cannot handle more than 4096 * 5 bytes in a
-        * transfer without running itself out of qt_buffers.
-        */
-       ss->max_xfer_blk = (4096 * 5) / dev_desc->blksz;
-
        init_part(dev_desc);
 
        USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
index c7aebea4e39f3feb9e9d0591c086b6e6c6fbdb8b..c62a8c112eb85d77cd0e0b043905fd6dc9f21c63 100644 (file)
@@ -153,13 +153,15 @@ static int curr_eth_dev; /* index for name of next device detected */
 static int smsc95xx_write_reg(struct ueth_data *dev, u32 index, u32 data)
 {
        int len;
+       ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);
 
        cpu_to_le32s(&data);
+       tmpbuf[0] = data;
 
        len = usb_control_msg(dev->pusb_dev, usb_sndctrlpipe(dev->pusb_dev, 0),
                USB_VENDOR_REQUEST_WRITE_REGISTER,
                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-               00, index, &data, sizeof(data), USB_CTRL_SET_TIMEOUT);
+               00, index, tmpbuf, sizeof(data), USB_CTRL_SET_TIMEOUT);
        if (len != sizeof(data)) {
                debug("smsc95xx_write_reg failed: index=%d, data=%d, len=%d",
                      index, data, len);
@@ -171,11 +173,13 @@ static int smsc95xx_write_reg(struct ueth_data *dev, u32 index, u32 data)
 static int smsc95xx_read_reg(struct ueth_data *dev, u32 index, u32 *data)
 {
        int len;
+       ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);
 
        len = usb_control_msg(dev->pusb_dev, usb_rcvctrlpipe(dev->pusb_dev, 0),
                USB_VENDOR_REQUEST_READ_REGISTER,
                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-               00, index, data, sizeof(data), USB_CTRL_GET_TIMEOUT);
+               00, index, tmpbuf, sizeof(data), USB_CTRL_GET_TIMEOUT);
+       *data = tmpbuf[0];
        if (len != sizeof(data)) {
                debug("smsc95xx_read_reg failed: index=%d, len=%d",
                      index, len);
@@ -664,7 +668,8 @@ static int smsc95xx_send(struct eth_device *eth, void* packet, int length)
        int actual_len;
        u32 tx_cmd_a;
        u32 tx_cmd_b;
-       unsigned char msg[PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b)];
+       ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
+                                PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b));
 
        debug("** %s(), len %d, buf %#x\n", __func__, length, (int)msg);
        if (length > PKTSIZE)
@@ -695,7 +700,7 @@ static int smsc95xx_send(struct eth_device *eth, void* packet, int length)
 static int smsc95xx_recv(struct eth_device *eth)
 {
        struct ueth_data *dev = (struct ueth_data *)eth->priv;
-       static unsigned char  recv_buf[AX_RX_URB_SIZE];
+       DEFINE_CACHE_ALIGN_BUFFER(unsigned char, recv_buf, AX_RX_URB_SIZE);
        unsigned char *buf_ptr;
        int err;
        int actual_len;
index 04300be1100acb0c7bf23d4d744d0f13d5ed16b3..2a82a29125a3861cb9912e3db283c12741188f13 100644 (file)
@@ -34,7 +34,10 @@ struct ehci_hccr *hccr;      /* R/O registers, not need for volatile */
 volatile struct ehci_hcor *hcor;
 
 static uint16_t portreset;
-static struct QH qh_list __attribute__((aligned(32)));
+DEFINE_ALIGN_BUFFER(struct QH, qh_list, 1, USB_DMA_MINALIGN);
+
+#define ALIGN_END_ADDR(type, ptr, size)                        \
+       ((uint32_t)(ptr) + roundup((size) * sizeof(type), USB_DMA_MINALIGN))
 
 static struct descriptor {
        struct usb_hub_descriptor hub;
@@ -172,18 +175,15 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
 {
        uint32_t delta, next;
        uint32_t addr = (uint32_t)buf;
-       size_t rsz = roundup(sz, 32);
        int idx;
 
-       if (sz != rsz)
-               debug("EHCI-HCD: Misaligned buffer size (%08x)\n", sz);
-
-       if (addr & 31)
+       if (addr != ALIGN(addr, ARCH_DMA_MINALIGN))
                debug("EHCI-HCD: Misaligned buffer address (%p)\n", buf);
 
+       flush_dcache_range(addr, ALIGN(addr + sz, ARCH_DMA_MINALIGN));
+
        idx = 0;
        while (idx < 5) {
-               flush_dcache_range(addr, addr + rsz);
                td->qt_buffer[idx] = cpu_to_hc32(addr);
                td->qt_buffer_hi[idx] = 0;
                next = (addr + 4096) & ~4095;
@@ -196,7 +196,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
        }
 
        if (idx == 5) {
-               debug("out of buffer pointers (%u bytes left)\n", sz);
+               printf("out of buffer pointers (%u bytes left)\n", sz);
                return -1;
        }
 
@@ -207,8 +207,8 @@ static int
 ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                   int length, struct devrequest *req)
 {
-       static struct QH qh __attribute__((aligned(32)));
-       static struct qTD qtd[3] __attribute__((aligned (32)));
+       ALLOC_ALIGN_BUFFER(struct QH, qh, 1, USB_DMA_MINALIGN);
+       ALLOC_ALIGN_BUFFER(struct qTD, qtd, 3, USB_DMA_MINALIGN);
        int qtd_counter = 0;
 
        volatile struct qTD *vtd;
@@ -229,8 +229,8 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                      le16_to_cpu(req->value), le16_to_cpu(req->value),
                      le16_to_cpu(req->index));
 
-       memset(&qh, 0, sizeof(struct QH));
-       memset(qtd, 0, sizeof(qtd));
+       memset(qh, 0, sizeof(struct QH));
+       memset(qtd, 0, 3 * sizeof(*qtd));
 
        toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
 
@@ -244,7 +244,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
         *   qh_overlay.qt_next ...... 13-10 H
         * - qh_overlay.qt_altnext
         */
-       qh.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
+       qh->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH);
        c = (usb_pipespeed(pipe) != USB_SPEED_HIGH &&
             usb_pipeendpoint(pipe) == 0) ? 1 : 0;
        endpt = (8 << 28) |
@@ -255,14 +255,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
            (usb_pipespeed(pipe) << 12) |
            (usb_pipeendpoint(pipe) << 8) |
            (0 << 7) | (usb_pipedevice(pipe) << 0);
-       qh.qh_endpt1 = cpu_to_hc32(endpt);
+       qh->qh_endpt1 = cpu_to_hc32(endpt);
        endpt = (1 << 30) |
            (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_endpt2 = cpu_to_hc32(endpt);
+       qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
 
-       tdp = &qh.qh_overlay.qt_next;
+       tdp = &qh->qh_overlay.qt_next;
 
        if (req != NULL) {
                /*
@@ -281,7 +281,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                    (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0);
                qtd[qtd_counter].qt_token = cpu_to_hc32(token);
                if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req)) != 0) {
-                       debug("unable construct SETUP td\n");
+                       printf("unable construct SETUP td\n");
                        goto fail;
                }
                /* Update previous qTD! */
@@ -310,7 +310,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                    ((usb_pipein(pipe) ? 1 : 0) << 8) | (0x80 << 0);
                qtd[qtd_counter].qt_token = cpu_to_hc32(token);
                if (ehci_td_buffer(&qtd[qtd_counter], buffer, length) != 0) {
-                       debug("unable construct DATA td\n");
+                       printf("unable construct DATA td\n");
                        goto fail;
                }
                /* Update previous qTD! */
@@ -340,13 +340,16 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                tdp = &qtd[qtd_counter++].qt_next;
        }
 
-       qh_list.qh_link = cpu_to_hc32((uint32_t)&qh | QH_LINK_TYPE_QH);
+       qh_list->qh_link = cpu_to_hc32((uint32_t)qh | QH_LINK_TYPE_QH);
 
        /* Flush dcache */
-       flush_dcache_range((uint32_t)&qh_list,
-               (uint32_t)&qh_list + sizeof(struct QH));
-       flush_dcache_range((uint32_t)&qh, (uint32_t)&qh + sizeof(struct QH));
-       flush_dcache_range((uint32_t)qtd, (uint32_t)qtd + sizeof(qtd));
+       flush_dcache_range((uint32_t)qh_list,
+               ALIGN_END_ADDR(struct QH, qh_list, 1));
+       flush_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1));
+       flush_dcache_range((uint32_t)qtd, ALIGN_END_ADDR(struct qTD, qtd, 3));
+
+       /* Set async. queue head pointer. */
+       ehci_writel(&hcor->or_asynclistaddr, (uint32_t)qh_list);
 
        usbsts = ehci_readl(&hcor->or_usbsts);
        ehci_writel(&hcor->or_usbsts, (usbsts & 0x3f));
@@ -369,12 +372,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
        timeout = USB_TIMEOUT_MS(pipe);
        do {
                /* Invalidate dcache */
-               invalidate_dcache_range((uint32_t)&qh_list,
-                       (uint32_t)&qh_list + sizeof(struct QH));
-               invalidate_dcache_range((uint32_t)&qh,
-                       (uint32_t)&qh + sizeof(struct QH));
+               invalidate_dcache_range((uint32_t)qh_list,
+                       ALIGN_END_ADDR(struct QH, qh_list, 1));
+               invalidate_dcache_range((uint32_t)qh,
+                       ALIGN_END_ADDR(struct QH, qh, 1));
                invalidate_dcache_range((uint32_t)qtd,
-                       (uint32_t)qtd + sizeof(qtd));
+                       ALIGN_END_ADDR(struct qTD, qtd, 3));
 
                token = hc32_to_cpu(vtd->qt_token);
                if (!(token & 0x80))
@@ -382,9 +385,17 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                WATCHDOG_RESET();
        } while (get_timer(ts) < timeout);
 
-       /* Invalidate the memory area occupied by buffer */
-       invalidate_dcache_range(((uint32_t)buffer & ~31),
-               ((uint32_t)buffer & ~31) + roundup(length, 32));
+       /*
+        * Invalidate the memory area occupied by buffer
+        * Don't try to fix the buffer alignment, if it isn't properly
+        * aligned it's upper layer's fault so let invalidate_dcache_range()
+        * vow about it. But we have to fix the length as it's actual
+        * transfer length and can be unaligned. This is potentially
+        * dangerous operation, it's responsibility of the calling
+        * code to make sure enough space is reserved.
+        */
+       invalidate_dcache_range((uint32_t)buffer,
+               ALIGN((uint32_t)buffer + length, ARCH_DMA_MINALIGN));
 
        /* Check that the TD processing happened */
        if (token & 0x80) {
@@ -403,9 +414,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
                goto fail;
        }
 
-       qh_list.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
-
-       token = hc32_to_cpu(qh.qh_overlay.qt_token);
+       token = hc32_to_cpu(qh->qh_overlay.qt_token);
        if (!(token & 0x80)) {
                debug("TOKEN=%#x\n", token);
                switch (token & 0xfc) {
@@ -733,16 +742,13 @@ int usb_lowlevel_init(void)
 #endif
 
        /* Set head of reclaim list */
-       memset(&qh_list, 0, sizeof(qh_list));
-       qh_list.qh_link = cpu_to_hc32((uint32_t)&qh_list | QH_LINK_TYPE_QH);
-       qh_list.qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
-       qh_list.qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
-       qh_list.qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
-       qh_list.qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
-       qh_list.qh_overlay.qt_token = cpu_to_hc32(0x40);
-
-       /* Set async. queue head pointer. */
-       ehci_writel(&hcor->or_asynclistaddr, (uint32_t)&qh_list);
+       memset(qh_list, 0, sizeof(*qh_list));
+       qh_list->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH);
+       qh_list->qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
+       qh_list->qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
+       qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+       qh_list->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+       qh_list->qh_overlay.qt_token = cpu_to_hc32(0x40);
 
        reg = ehci_readl(&hccr->cr_hcsparams);
        descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
index 1ed77107ebb5d79e15989c5fab1b26f0d55abded..292673bf0035ff7a6a1db0e5e5152335abcc69dc 100644 (file)
@@ -246,7 +246,6 @@ int omap_ehci_hcd_init(struct omap_usbhs_board_data *usbhs_pdata)
                if (is_ehci_phy_mode(usbhs_pdata->port_mode[i]))
                        omap_ehci_soft_phy_reset(i);
 
-       dcache_disable();
        hccr = (struct ehci_hccr *)(OMAP_EHCI_BASE);
        hcor = (struct ehci_hcor *)(OMAP_EHCI_BASE + 0x10);
 
index a8adcce00fa4ae558cd72944faa7dad4f956ebf1..e914369297047fcfcfa10ba0037fe30ab9820d83 100644 (file)
@@ -145,7 +145,7 @@ struct musb_regs {
                struct musb_epN_regs epN;
        } ep[16];
 
-} __attribute__((packed, aligned(32)));
+} __attribute__((packed, aligned(USB_DMA_MINALIGN)));
 #endif
 
 /*
index d1dd65a851ea3f27786da1102a11d94cd66ba7f0..be9c278ee8087dcdcdef3fd4b0e6b6d79ed88578 100644 (file)
@@ -39,6 +39,7 @@ typedef volatile unsigned char        vu_char;
 #include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/string.h>
+#include <linux/compiler.h>
 #include <asm/ptrace.h>
 #include <stdarg.h>
 #if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000))
@@ -944,11 +945,25 @@ int cpu_release(int nr, int argc, char * const argv[]);
  * of a function scoped static buffer.  It can not be used to create a cache
  * line aligned global buffer.
  */
+#define ALLOC_ALIGN_BUFFER(type, name, size, align)                    \
+       char __##name[ROUND(size * sizeof(type), align) + (align - 1)]; \
+                                                                       \
+       type *name = (type *) ALIGN((uintptr_t)__##name, align)
 #define ALLOC_CACHE_ALIGN_BUFFER(type, name, size)                     \
-       char __##name[ROUND(size * sizeof(type), ARCH_DMA_MINALIGN) +   \
-                     ARCH_DMA_MINALIGN - 1];                           \
+       ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
+
+/*
+ * DEFINE_CACHE_ALIGN_BUFFER() is similar to ALLOC_CACHE_ALIGN_BUFFER, but it's
+ * purpose is to allow allocating aligned buffers outside of function scope.
+ * Usage of this macro shall be avoided or used with extreme care!
+ */
+#define DEFINE_ALIGN_BUFFER(type, name, size, align)                   \
+       static char __##name[roundup(size * sizeof(type), align)]       \
+                       __aligned(align);                               \
                                                                        \
-       type *name = (type *) ALIGN((uintptr_t)__##name, ARCH_DMA_MINALIGN)
+       static type *name = (type *)__##name
+#define DEFINE_CACHE_ALIGN_BUFFER(type, name, size)                    \
+       DEFINE_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
 
 /* Pull in stuff for the build system */
 #ifdef DO_DEPS_ONLY
index 6da91e7232e92559f508c075529f65f797265109..ba3d169ea8cbf977aaaeb8f95e9cf331537d1d58 100644 (file)
 #include <usb_defs.h>
 #include <usbdescriptors.h>
 
+/*
+ * The EHCI spec says that we must align to at least 32 bytes.  However,
+ * some platforms require larger alignment.
+ */
+#if ARCH_DMA_MINALIGN > 32
+#define USB_DMA_MINALIGN       ARCH_DMA_MINALIGN
+#else
+#define USB_DMA_MINALIGN       32
+#endif
+
 /* Everything is aribtrary */
 #define USB_ALTSETTINGALLOC            4
 #define USB_MAXALTSETTING              128     /* Hard limit */