diff options
Diffstat (limited to 'drivers/usb/musb/musb_host.c')
-rw-r--r-- | drivers/usb/musb/musb_host.c | 159 |
1 files changed, 102 insertions, 57 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3133990f04ec..e45e70bcc5e2 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -378,6 +378,19 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | |||
378 | 378 | ||
379 | switch (qh->type) { | 379 | switch (qh->type) { |
380 | 380 | ||
381 | case USB_ENDPOINT_XFER_CONTROL: | ||
382 | case USB_ENDPOINT_XFER_BULK: | ||
383 | /* fifo policy for these lists, except that NAKing | ||
384 | * should rotate a qh to the end (for fairness). | ||
385 | */ | ||
386 | if (qh->mux == 1) { | ||
387 | head = qh->ring.prev; | ||
388 | list_del(&qh->ring); | ||
389 | kfree(qh); | ||
390 | qh = first_qh(head); | ||
391 | break; | ||
392 | } | ||
393 | |||
381 | case USB_ENDPOINT_XFER_ISOC: | 394 | case USB_ENDPOINT_XFER_ISOC: |
382 | case USB_ENDPOINT_XFER_INT: | 395 | case USB_ENDPOINT_XFER_INT: |
383 | /* this is where periodic bandwidth should be | 396 | /* this is where periodic bandwidth should be |
@@ -388,17 +401,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | |||
388 | kfree(qh); | 401 | kfree(qh); |
389 | qh = NULL; | 402 | qh = NULL; |
390 | break; | 403 | break; |
391 | |||
392 | case USB_ENDPOINT_XFER_CONTROL: | ||
393 | case USB_ENDPOINT_XFER_BULK: | ||
394 | /* fifo policy for these lists, except that NAKing | ||
395 | * should rotate a qh to the end (for fairness). | ||
396 | */ | ||
397 | head = qh->ring.prev; | ||
398 | list_del(&qh->ring); | ||
399 | kfree(qh); | ||
400 | qh = first_qh(head); | ||
401 | break; | ||
402 | } | 404 | } |
403 | } | 405 | } |
404 | return qh; | 406 | return qh; |
@@ -1507,10 +1509,29 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1507 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); | 1509 | musb_writew(hw_ep->regs, MUSB_RXCSR, val); |
1508 | 1510 | ||
1509 | #ifdef CONFIG_USB_INVENTRA_DMA | 1511 | #ifdef CONFIG_USB_INVENTRA_DMA |
1512 | if (usb_pipeisoc(pipe)) { | ||
1513 | struct usb_iso_packet_descriptor *d; | ||
1514 | |||
1515 | d = urb->iso_frame_desc + qh->iso_idx; | ||
1516 | d->actual_length = xfer_len; | ||
1517 | |||
1518 | /* even if there was an error, we did the dma | ||
1519 | * for iso_frame_desc->length | ||
1520 | */ | ||
1521 | if (d->status != EILSEQ && d->status != -EOVERFLOW) | ||
1522 | d->status = 0; | ||
1523 | |||
1524 | if (++qh->iso_idx >= urb->number_of_packets) | ||
1525 | done = true; | ||
1526 | else | ||
1527 | done = false; | ||
1528 | |||
1529 | } else { | ||
1510 | /* done if urb buffer is full or short packet is recd */ | 1530 | /* done if urb buffer is full or short packet is recd */ |
1511 | done = (urb->actual_length + xfer_len >= | 1531 | done = (urb->actual_length + xfer_len >= |
1512 | urb->transfer_buffer_length | 1532 | urb->transfer_buffer_length |
1513 | || dma->actual_len < qh->maxpacket); | 1533 | || dma->actual_len < qh->maxpacket); |
1534 | } | ||
1514 | 1535 | ||
1515 | /* send IN token for next packet, without AUTOREQ */ | 1536 | /* send IN token for next packet, without AUTOREQ */ |
1516 | if (!done) { | 1537 | if (!done) { |
@@ -1547,7 +1568,8 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1547 | if (dma) { | 1568 | if (dma) { |
1548 | struct dma_controller *c; | 1569 | struct dma_controller *c; |
1549 | u16 rx_count; | 1570 | u16 rx_count; |
1550 | int ret; | 1571 | int ret, length; |
1572 | dma_addr_t buf; | ||
1551 | 1573 | ||
1552 | rx_count = musb_readw(epio, MUSB_RXCOUNT); | 1574 | rx_count = musb_readw(epio, MUSB_RXCOUNT); |
1553 | 1575 | ||
@@ -1560,6 +1582,35 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1560 | 1582 | ||
1561 | c = musb->dma_controller; | 1583 | c = musb->dma_controller; |
1562 | 1584 | ||
1585 | if (usb_pipeisoc(pipe)) { | ||
1586 | int status = 0; | ||
1587 | struct usb_iso_packet_descriptor *d; | ||
1588 | |||
1589 | d = urb->iso_frame_desc + qh->iso_idx; | ||
1590 | |||
1591 | if (iso_err) { | ||
1592 | status = -EILSEQ; | ||
1593 | urb->error_count++; | ||
1594 | } | ||
1595 | if (rx_count > d->length) { | ||
1596 | if (status == 0) { | ||
1597 | status = -EOVERFLOW; | ||
1598 | urb->error_count++; | ||
1599 | } | ||
1600 | DBG(2, "** OVERFLOW %d into %d\n",\ | ||
1601 | rx_count, d->length); | ||
1602 | |||
1603 | length = d->length; | ||
1604 | } else | ||
1605 | length = rx_count; | ||
1606 | d->status = status; | ||
1607 | buf = urb->transfer_dma + d->offset; | ||
1608 | } else { | ||
1609 | length = rx_count; | ||
1610 | buf = urb->transfer_dma + | ||
1611 | urb->actual_length; | ||
1612 | } | ||
1613 | |||
1563 | dma->desired_mode = 0; | 1614 | dma->desired_mode = 0; |
1564 | #ifdef USE_MODE1 | 1615 | #ifdef USE_MODE1 |
1565 | /* because of the issue below, mode 1 will | 1616 | /* because of the issue below, mode 1 will |
@@ -1571,6 +1622,12 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1571 | urb->actual_length) | 1622 | urb->actual_length) |
1572 | > qh->maxpacket) | 1623 | > qh->maxpacket) |
1573 | dma->desired_mode = 1; | 1624 | dma->desired_mode = 1; |
1625 | if (rx_count < hw_ep->max_packet_sz_rx) { | ||
1626 | length = rx_count; | ||
1627 | dma->bDesiredMode = 0; | ||
1628 | } else { | ||
1629 | length = urb->transfer_buffer_length; | ||
1630 | } | ||
1574 | #endif | 1631 | #endif |
1575 | 1632 | ||
1576 | /* Disadvantage of using mode 1: | 1633 | /* Disadvantage of using mode 1: |
@@ -1608,12 +1665,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1608 | */ | 1665 | */ |
1609 | ret = c->channel_program( | 1666 | ret = c->channel_program( |
1610 | dma, qh->maxpacket, | 1667 | dma, qh->maxpacket, |
1611 | dma->desired_mode, | 1668 | dma->desired_mode, buf, length); |
1612 | urb->transfer_dma | ||
1613 | + urb->actual_length, | ||
1614 | (dma->desired_mode == 0) | ||
1615 | ? rx_count | ||
1616 | : urb->transfer_buffer_length); | ||
1617 | 1669 | ||
1618 | if (!ret) { | 1670 | if (!ret) { |
1619 | c->channel_release(dma); | 1671 | c->channel_release(dma); |
@@ -1631,19 +1683,6 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1631 | } | 1683 | } |
1632 | } | 1684 | } |
1633 | 1685 | ||
1634 | if (dma && usb_pipeisoc(pipe)) { | ||
1635 | struct usb_iso_packet_descriptor *d; | ||
1636 | int iso_stat = status; | ||
1637 | |||
1638 | d = urb->iso_frame_desc + qh->iso_idx; | ||
1639 | d->actual_length += xfer_len; | ||
1640 | if (iso_err) { | ||
1641 | iso_stat = -EILSEQ; | ||
1642 | urb->error_count++; | ||
1643 | } | ||
1644 | d->status = iso_stat; | ||
1645 | } | ||
1646 | |||
1647 | finish: | 1686 | finish: |
1648 | urb->actual_length += xfer_len; | 1687 | urb->actual_length += xfer_len; |
1649 | qh->offset += xfer_len; | 1688 | qh->offset += xfer_len; |
@@ -1671,22 +1710,9 @@ static int musb_schedule( | |||
1671 | struct list_head *head = NULL; | 1710 | struct list_head *head = NULL; |
1672 | 1711 | ||
1673 | /* use fixed hardware for control and bulk */ | 1712 | /* use fixed hardware for control and bulk */ |
1674 | switch (qh->type) { | 1713 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { |
1675 | case USB_ENDPOINT_XFER_CONTROL: | ||
1676 | head = &musb->control; | 1714 | head = &musb->control; |
1677 | hw_ep = musb->control_ep; | 1715 | hw_ep = musb->control_ep; |
1678 | break; | ||
1679 | case USB_ENDPOINT_XFER_BULK: | ||
1680 | hw_ep = musb->bulk_ep; | ||
1681 | if (is_in) | ||
1682 | head = &musb->in_bulk; | ||
1683 | else | ||
1684 | head = &musb->out_bulk; | ||
1685 | break; | ||
1686 | } | ||
1687 | if (head) { | ||
1688 | idle = list_empty(head); | ||
1689 | list_add_tail(&qh->ring, head); | ||
1690 | goto success; | 1716 | goto success; |
1691 | } | 1717 | } |
1692 | 1718 | ||
@@ -1725,19 +1751,34 @@ static int musb_schedule( | |||
1725 | else | 1751 | else |
1726 | diff = hw_ep->max_packet_sz_tx - qh->maxpacket; | 1752 | diff = hw_ep->max_packet_sz_tx - qh->maxpacket; |
1727 | 1753 | ||
1728 | if (diff > 0 && best_diff > diff) { | 1754 | if (diff >= 0 && best_diff > diff) { |
1729 | best_diff = diff; | 1755 | best_diff = diff; |
1730 | best_end = epnum; | 1756 | best_end = epnum; |
1731 | } | 1757 | } |
1732 | } | 1758 | } |
1733 | if (best_end < 0) | 1759 | /* use bulk reserved ep1 if no other ep is free */ |
1760 | if (best_end > 0 && qh->type == USB_ENDPOINT_XFER_BULK) { | ||
1761 | hw_ep = musb->bulk_ep; | ||
1762 | if (is_in) | ||
1763 | head = &musb->in_bulk; | ||
1764 | else | ||
1765 | head = &musb->out_bulk; | ||
1766 | goto success; | ||
1767 | } else if (best_end < 0) { | ||
1734 | return -ENOSPC; | 1768 | return -ENOSPC; |
1769 | } | ||
1735 | 1770 | ||
1736 | idle = 1; | 1771 | idle = 1; |
1772 | qh->mux = 0; | ||
1737 | hw_ep = musb->endpoints + best_end; | 1773 | hw_ep = musb->endpoints + best_end; |
1738 | musb->periodic[best_end] = qh; | 1774 | musb->periodic[best_end] = qh; |
1739 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); | 1775 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); |
1740 | success: | 1776 | success: |
1777 | if (head) { | ||
1778 | idle = list_empty(head); | ||
1779 | list_add_tail(&qh->ring, head); | ||
1780 | qh->mux = 1; | ||
1781 | } | ||
1741 | qh->hw_ep = hw_ep; | 1782 | qh->hw_ep = hw_ep; |
1742 | qh->hep->hcpriv = qh; | 1783 | qh->hep->hcpriv = qh; |
1743 | if (idle) | 1784 | if (idle) |
@@ -2015,11 +2056,13 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
2015 | sched = &musb->control; | 2056 | sched = &musb->control; |
2016 | break; | 2057 | break; |
2017 | case USB_ENDPOINT_XFER_BULK: | 2058 | case USB_ENDPOINT_XFER_BULK: |
2018 | if (usb_pipein(urb->pipe)) | 2059 | if (qh->mux == 1) { |
2019 | sched = &musb->in_bulk; | 2060 | if (usb_pipein(urb->pipe)) |
2020 | else | 2061 | sched = &musb->in_bulk; |
2021 | sched = &musb->out_bulk; | 2062 | else |
2022 | break; | 2063 | sched = &musb->out_bulk; |
2064 | break; | ||
2065 | } | ||
2023 | default: | 2066 | default: |
2024 | /* REVISIT when we get a schedule tree, periodic | 2067 | /* REVISIT when we get a schedule tree, periodic |
2025 | * transfers won't always be at the head of a | 2068 | * transfers won't always be at the head of a |
@@ -2067,11 +2110,13 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) | |||
2067 | sched = &musb->control; | 2110 | sched = &musb->control; |
2068 | break; | 2111 | break; |
2069 | case USB_ENDPOINT_XFER_BULK: | 2112 | case USB_ENDPOINT_XFER_BULK: |
2070 | if (is_in) | 2113 | if (qh->mux == 1) { |
2071 | sched = &musb->in_bulk; | 2114 | if (is_in) |
2072 | else | 2115 | sched = &musb->in_bulk; |
2073 | sched = &musb->out_bulk; | 2116 | else |
2074 | break; | 2117 | sched = &musb->out_bulk; |
2118 | break; | ||
2119 | } | ||
2075 | default: | 2120 | default: |
2076 | /* REVISIT when we get a schedule tree, periodic transfers | 2121 | /* REVISIT when we get a schedule tree, periodic transfers |
2077 | * won't always be at the head of a singleton queue... | 2122 | * won't always be at the head of a singleton queue... |