diff options
| -rw-r--r-- | common/usb.c | 12 | ||||
| -rw-r--r-- | common/usb_storage.c | 37 | ||||
| -rw-r--r-- | drivers/usb/eth/smsc95xx.c | 13 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-hcd.c | 96 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-omap.c | 1 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_core.h | 2 | ||||
| -rw-r--r-- | include/common.h | 21 | ||||
| -rw-r--r-- | include/usb.h | 10 | 
8 files changed, 117 insertions, 75 deletions
| diff --git a/common/usb.c b/common/usb.c index c80155ce7..1b40228b2 100644 --- a/common/usb.c +++ b/common/usb.c @@ -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); diff --git a/common/usb_storage.c b/common/usb_storage.c index faad23706..bdc306f58 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -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); diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c index c7aebea4e..c62a8c112 100644 --- a/drivers/usb/eth/smsc95xx.c +++ b/drivers/usb/eth/smsc95xx.c @@ -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; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 04300be11..2a82a2912 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -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); diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 1ed77107e..292673bf0 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -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); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index a8adcce00..e91436929 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -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  /* diff --git a/include/common.h b/include/common.h index d1dd65a85..be9c278ee 100644 --- a/include/common.h +++ b/include/common.h @@ -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 diff --git a/include/usb.h b/include/usb.h index 6da91e723..ba3d169ea 100644 --- a/include/usb.h +++ b/include/usb.h @@ -29,6 +29,16 @@  #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 */ |