diff options
Diffstat (limited to 'drivers/usb/musb/musb_host.c')
-rw-r--r-- | drivers/usb/musb/musb_host.c | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 2f8ad7f1f482..d227a71d85e1 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -434,7 +434,13 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, | |||
434 | } | 434 | } |
435 | } | 435 | } |
436 | 436 | ||
437 | if (qh != NULL && qh->is_ready) { | 437 | /* |
438 | * The pipe must be broken if current urb->status is set, so don't | ||
439 | * start next urb. | ||
440 | * TODO: to minimize the risk of regression, only check urb->status | ||
441 | * for RX, until we have a test case to understand the behavior of TX. | ||
442 | */ | ||
443 | if ((!status || !is_in) && qh && qh->is_ready) { | ||
438 | dev_dbg(musb->controller, "... next ep%d %cX urb %p\n", | 444 | dev_dbg(musb->controller, "... next ep%d %cX urb %p\n", |
439 | hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); | 445 | hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); |
440 | musb_start_urb(musb, is_in, qh); | 446 | musb_start_urb(musb, is_in, qh); |
@@ -594,14 +600,13 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum) | |||
594 | musb_writew(ep->regs, MUSB_TXCSR, 0); | 600 | musb_writew(ep->regs, MUSB_TXCSR, 0); |
595 | 601 | ||
596 | /* scrub all previous state, clearing toggle */ | 602 | /* scrub all previous state, clearing toggle */ |
597 | } else { | ||
598 | csr = musb_readw(ep->regs, MUSB_RXCSR); | ||
599 | if (csr & MUSB_RXCSR_RXPKTRDY) | ||
600 | WARNING("rx%d, packet/%d ready?\n", ep->epnum, | ||
601 | musb_readw(ep->regs, MUSB_RXCOUNT)); | ||
602 | |||
603 | musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG); | ||
604 | } | 603 | } |
604 | csr = musb_readw(ep->regs, MUSB_RXCSR); | ||
605 | if (csr & MUSB_RXCSR_RXPKTRDY) | ||
606 | WARNING("rx%d, packet/%d ready?\n", ep->epnum, | ||
607 | musb_readw(ep->regs, MUSB_RXCOUNT)); | ||
608 | |||
609 | musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG); | ||
605 | 610 | ||
606 | /* target addr and (for multipoint) hub addr/port */ | 611 | /* target addr and (for multipoint) hub addr/port */ |
607 | if (musb->is_multipoint) { | 612 | if (musb->is_multipoint) { |
@@ -627,7 +632,7 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum) | |||
627 | ep->rx_reinit = 0; | 632 | ep->rx_reinit = 0; |
628 | } | 633 | } |
629 | 634 | ||
630 | static int musb_tx_dma_set_mode_mentor(struct dma_controller *dma, | 635 | static void musb_tx_dma_set_mode_mentor(struct dma_controller *dma, |
631 | struct musb_hw_ep *hw_ep, struct musb_qh *qh, | 636 | struct musb_hw_ep *hw_ep, struct musb_qh *qh, |
632 | struct urb *urb, u32 offset, | 637 | struct urb *urb, u32 offset, |
633 | u32 *length, u8 *mode) | 638 | u32 *length, u8 *mode) |
@@ -664,23 +669,18 @@ static int musb_tx_dma_set_mode_mentor(struct dma_controller *dma, | |||
664 | } | 669 | } |
665 | channel->desired_mode = *mode; | 670 | channel->desired_mode = *mode; |
666 | musb_writew(epio, MUSB_TXCSR, csr); | 671 | musb_writew(epio, MUSB_TXCSR, csr); |
667 | |||
668 | return 0; | ||
669 | } | 672 | } |
670 | 673 | ||
671 | static int musb_tx_dma_set_mode_cppi_tusb(struct dma_controller *dma, | 674 | static void musb_tx_dma_set_mode_cppi_tusb(struct dma_controller *dma, |
672 | struct musb_hw_ep *hw_ep, | 675 | struct musb_hw_ep *hw_ep, |
673 | struct musb_qh *qh, | 676 | struct musb_qh *qh, |
674 | struct urb *urb, | 677 | struct urb *urb, |
675 | u32 offset, | 678 | u32 offset, |
676 | u32 *length, | 679 | u32 *length, |
677 | u8 *mode) | 680 | u8 *mode) |
678 | { | 681 | { |
679 | struct dma_channel *channel = hw_ep->tx_channel; | 682 | struct dma_channel *channel = hw_ep->tx_channel; |
680 | 683 | ||
681 | if (!is_cppi_enabled(hw_ep->musb) && !tusb_dma_omap(hw_ep->musb)) | ||
682 | return -ENODEV; | ||
683 | |||
684 | channel->actual_len = 0; | 684 | channel->actual_len = 0; |
685 | 685 | ||
686 | /* | 686 | /* |
@@ -688,8 +688,6 @@ static int musb_tx_dma_set_mode_cppi_tusb(struct dma_controller *dma, | |||
688 | * to identify the zero-length-final-packet case. | 688 | * to identify the zero-length-final-packet case. |
689 | */ | 689 | */ |
690 | *mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0; | 690 | *mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0; |
691 | |||
692 | return 0; | ||
693 | } | 691 | } |
694 | 692 | ||
695 | static bool musb_tx_dma_program(struct dma_controller *dma, | 693 | static bool musb_tx_dma_program(struct dma_controller *dma, |
@@ -699,15 +697,14 @@ static bool musb_tx_dma_program(struct dma_controller *dma, | |||
699 | struct dma_channel *channel = hw_ep->tx_channel; | 697 | struct dma_channel *channel = hw_ep->tx_channel; |
700 | u16 pkt_size = qh->maxpacket; | 698 | u16 pkt_size = qh->maxpacket; |
701 | u8 mode; | 699 | u8 mode; |
702 | int res; | ||
703 | 700 | ||
704 | if (musb_dma_inventra(hw_ep->musb) || musb_dma_ux500(hw_ep->musb)) | 701 | if (musb_dma_inventra(hw_ep->musb) || musb_dma_ux500(hw_ep->musb)) |
705 | res = musb_tx_dma_set_mode_mentor(dma, hw_ep, qh, urb, | 702 | musb_tx_dma_set_mode_mentor(dma, hw_ep, qh, urb, offset, |
706 | offset, &length, &mode); | 703 | &length, &mode); |
704 | else if (is_cppi_enabled(hw_ep->musb) || tusb_dma_omap(hw_ep->musb)) | ||
705 | musb_tx_dma_set_mode_cppi_tusb(dma, hw_ep, qh, urb, offset, | ||
706 | &length, &mode); | ||
707 | else | 707 | else |
708 | res = musb_tx_dma_set_mode_cppi_tusb(dma, hw_ep, qh, urb, | ||
709 | offset, &length, &mode); | ||
710 | if (res) | ||
711 | return false; | 708 | return false; |
712 | 709 | ||
713 | qh->segsize = length; | 710 | qh->segsize = length; |
@@ -995,9 +992,15 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep, | |||
995 | if (is_in) { | 992 | if (is_in) { |
996 | dma = is_dma_capable() ? ep->rx_channel : NULL; | 993 | dma = is_dma_capable() ? ep->rx_channel : NULL; |
997 | 994 | ||
998 | /* clear nak timeout bit */ | 995 | /* |
996 | * Need to stop the transaction by clearing REQPKT first | ||
997 | * then the NAK Timeout bit ref MUSBMHDRC USB 2.0 HIGH-SPEED | ||
998 | * DUAL-ROLE CONTROLLER Programmer's Guide, section 9.2.2 | ||
999 | */ | ||
999 | rx_csr = musb_readw(epio, MUSB_RXCSR); | 1000 | rx_csr = musb_readw(epio, MUSB_RXCSR); |
1000 | rx_csr |= MUSB_RXCSR_H_WZC_BITS; | 1001 | rx_csr |= MUSB_RXCSR_H_WZC_BITS; |
1002 | rx_csr &= ~MUSB_RXCSR_H_REQPKT; | ||
1003 | musb_writew(epio, MUSB_RXCSR, rx_csr); | ||
1001 | rx_csr &= ~MUSB_RXCSR_DATAERROR; | 1004 | rx_csr &= ~MUSB_RXCSR_DATAERROR; |
1002 | musb_writew(epio, MUSB_RXCSR, rx_csr); | 1005 | musb_writew(epio, MUSB_RXCSR, rx_csr); |
1003 | 1006 | ||
@@ -1551,7 +1554,7 @@ static int musb_rx_dma_iso_cppi41(struct dma_controller *dma, | |||
1551 | struct urb *urb, | 1554 | struct urb *urb, |
1552 | size_t len) | 1555 | size_t len) |
1553 | { | 1556 | { |
1554 | struct dma_channel *channel = hw_ep->tx_channel; | 1557 | struct dma_channel *channel = hw_ep->rx_channel; |
1555 | void __iomem *epio = hw_ep->regs; | 1558 | void __iomem *epio = hw_ep->regs; |
1556 | dma_addr_t *buf; | 1559 | dma_addr_t *buf; |
1557 | u32 length, res; | 1560 | u32 length, res; |
@@ -1870,6 +1873,9 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1870 | status = -EPROTO; | 1873 | status = -EPROTO; |
1871 | musb_writeb(epio, MUSB_RXINTERVAL, 0); | 1874 | musb_writeb(epio, MUSB_RXINTERVAL, 0); |
1872 | 1875 | ||
1876 | rx_csr &= ~MUSB_RXCSR_H_ERROR; | ||
1877 | musb_writew(epio, MUSB_RXCSR, rx_csr); | ||
1878 | |||
1873 | } else if (rx_csr & MUSB_RXCSR_DATAERROR) { | 1879 | } else if (rx_csr & MUSB_RXCSR_DATAERROR) { |
1874 | 1880 | ||
1875 | if (USB_ENDPOINT_XFER_ISOC != qh->type) { | 1881 | if (USB_ENDPOINT_XFER_ISOC != qh->type) { |