diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 49bfc096e4..e2af67d2f0 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -460,10 +460,12 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) /* We found a USB Keyboard, install it. */ usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0); + debug("USB KBD: found set idle...\n"); #if !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) && \ !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE) - debug("USB KBD: found set idle...\n"); usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE / 4, 0); +#else + usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0); #endif debug("USB KBD: enable interrupt pipe...\n"); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1e5a6e2b20..bf02221c9f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1214,6 +1214,7 @@ static int _ehci_submit_control_msg(struct usb_device *dev, unsigned long pipe, struct int_queue { int elementsize; + unsigned long pipe; struct QH *first; struct QH *current; struct QH *last; @@ -1269,7 +1270,7 @@ static struct int_queue *_ehci_create_int_queue(struct usb_device *dev, { struct ehci_ctrl *ctrl = ehci_get_ctrl(dev); struct int_queue *result = NULL; - int i; + uint32_t i, toggle; /* * Interrupt transfers requiring several transactions are not supported @@ -1309,6 +1310,7 @@ static struct int_queue *_ehci_create_int_queue(struct usb_device *dev, goto fail1; } result->elementsize = elementsize; + result->pipe = pipe; result->first = memalign(USB_DMA_MINALIGN, sizeof(struct QH) * queuesize); if (!result->first) { @@ -1326,6 +1328,8 @@ static struct int_queue *_ehci_create_int_queue(struct usb_device *dev, memset(result->first, 0, sizeof(struct QH) * queuesize); memset(result->tds, 0, sizeof(struct qTD) * queuesize); + toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); + for (i = 0; i < queuesize; i++) { struct QH *qh = result->first + i; struct qTD *td = result->tds + i; @@ -1357,7 +1361,9 @@ static struct int_queue *_ehci_create_int_queue(struct usb_device *dev, td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); debug("communication direction is '%s'\n", usb_pipein(pipe) ? "in" : "out"); - td->qt_token = cpu_to_hc32((elementsize << 16) | + td->qt_token = cpu_to_hc32( + QT_TOKEN_DT(toggle) | + (elementsize << 16) | ((usb_pipein(pipe) ? 1 : 0) << 8) | /* IN/OUT token */ 0x80); /* active */ td->qt_buffer[0] = @@ -1372,6 +1378,7 @@ static struct int_queue *_ehci_create_int_queue(struct usb_device *dev, cpu_to_hc32((td->qt_buffer[0] + 0x4000) & ~0xfff); *buf = buffer + i * elementsize; + toggle ^= 1; } flush_dcache_range((unsigned long)buffer, @@ -1426,6 +1433,8 @@ static void *_ehci_poll_int_queue(struct usb_device *dev, { struct QH *cur = queue->current; struct qTD *cur_td; + uint32_t token, toggle; + unsigned long pipe = queue->pipe; /* depleted queue */ if (cur == NULL) { @@ -1436,12 +1445,15 @@ static void *_ehci_poll_int_queue(struct usb_device *dev, cur_td = &queue->tds[queue->current - queue->first]; invalidate_dcache_range((unsigned long)cur_td, ALIGN_END_ADDR(struct qTD, cur_td, 1)); - if (QT_TOKEN_GET_STATUS(hc32_to_cpu(cur_td->qt_token)) & - QT_TOKEN_STATUS_ACTIVE) { - debug("Exit poll_int_queue with no completed intr transfer. token is %x\n", - hc32_to_cpu(cur_td->qt_token)); + token = hc32_to_cpu(cur_td->qt_token); + if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE) { + debug("Exit poll_int_queue with no completed intr transfer. token is %x\n", token); return NULL; } + + toggle = QT_TOKEN_GET_DT(token); + usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), toggle); + if (!(cur->qh_link & QH_LINK_TERMINATE)) queue->current++; else @@ -1452,7 +1464,7 @@ static void *_ehci_poll_int_queue(struct usb_device *dev, queue->elementsize)); debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n", - hc32_to_cpu(cur_td->qt_token), cur, queue->first); + token, cur, queue->first); return cur->buffer; } diff --git a/include/usb.h b/include/usb.h index c709ce2cf6..dca512d394 100644 --- a/include/usb.h +++ b/include/usb.h @@ -171,17 +171,6 @@ enum usb_init_type { * this is how the lowlevel part communicate with the outer world */ -#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \ - defined(CONFIG_USB_EHCI) || defined(CONFIG_USB_OHCI_NEW) || \ - defined(CONFIG_USB_SL811HS) || defined(CONFIG_USB_ISP116X_HCD) || \ - defined(CONFIG_USB_R8A66597_HCD) || defined(CONFIG_USB_DAVINCI) || \ - defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \ - defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \ - defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \ - defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \ - defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2) || \ - defined(CONFIG_USB_EMUL) - int usb_lowlevel_init(int index, enum usb_init_type init, void **controller); int usb_lowlevel_stop(int index); @@ -216,12 +205,8 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue); * in boards init functions e.g. udc_disconnect() used for * forced device disconnection from host. */ -#elif defined(CONFIG_USB_GADGET_PXA2XX) - extern void udc_disconnect(void); -#endif - /* * board-specific hardware initialization, called by * usb drivers and u-boot commands