Merge branch 'master' of git://git.denx.de/u-boot-usb
* '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>
This commit is contained in:
commit
3ec81d758c
12
common/usb.c
12
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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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_CACHE_ALIGN_BUFFER(type, name, size) \
|
||||
char __##name[ROUND(size * sizeof(type), ARCH_DMA_MINALIGN) + \
|
||||
ARCH_DMA_MINALIGN - 1]; \
|
||||
#define ALLOC_ALIGN_BUFFER(type, name, size, align) \
|
||||
char __##name[ROUND(size * sizeof(type), align) + (align - 1)]; \
|
||||
\
|
||||
type *name = (type *) ALIGN((uintptr_t)__##name, ARCH_DMA_MINALIGN)
|
||||
type *name = (type *) ALIGN((uintptr_t)__##name, align)
|
||||
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
|
||||
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); \
|
||||
\
|
||||
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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user