diff options
Diffstat (limited to 'drivers/usb/musb')
| -rw-r--r-- | drivers/usb/musb/musb_core.c | 6 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_debug.h | 4 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_host.c | 159 | ||||
| -rw-r--r-- | drivers/usb/musb/musb_host.h | 1 | ||||
| -rw-r--r-- | drivers/usb/musb/omap2430.c | 2 | ||||
| -rw-r--r-- | drivers/usb/musb/tusb6010.c | 2 |
6 files changed, 111 insertions, 63 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 4a35745b30b..5280dba9b1f 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -114,8 +114,8 @@ | |||
| 114 | 114 | ||
| 115 | 115 | ||
| 116 | 116 | ||
| 117 | unsigned debug; | 117 | unsigned musb_debug; |
| 118 | module_param(debug, uint, S_IRUGO | S_IWUSR); | 118 | module_param(musb_debug, uint, S_IRUGO | S_IWUSR); |
| 119 | MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); | 119 | MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); |
| 120 | 120 | ||
| 121 | #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" | 121 | #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" |
| @@ -2248,7 +2248,7 @@ static int __init musb_init(void) | |||
| 2248 | "host" | 2248 | "host" |
| 2249 | #endif | 2249 | #endif |
| 2250 | ", debug=%d\n", | 2250 | ", debug=%d\n", |
| 2251 | musb_driver_name, debug); | 2251 | musb_driver_name, musb_debug); |
| 2252 | return platform_driver_probe(&musb_driver, musb_probe); | 2252 | return platform_driver_probe(&musb_driver, musb_probe); |
| 2253 | } | 2253 | } |
| 2254 | 2254 | ||
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h index 4d2794441b1..9fc1db44c72 100644 --- a/drivers/usb/musb/musb_debug.h +++ b/drivers/usb/musb/musb_debug.h | |||
| @@ -48,11 +48,11 @@ | |||
| 48 | __func__, __LINE__ , ## args); \ | 48 | __func__, __LINE__ , ## args); \ |
| 49 | } } while (0) | 49 | } } while (0) |
| 50 | 50 | ||
| 51 | extern unsigned debug; | 51 | extern unsigned musb_debug; |
| 52 | 52 | ||
| 53 | static inline int _dbg_level(unsigned l) | 53 | static inline int _dbg_level(unsigned l) |
| 54 | { | 54 | { |
| 55 | return debug >= l; | 55 | return musb_debug >= l; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | #define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args) | 58 | #define DBG(level, fmt, args...) xprintk(level, KERN_DEBUG, fmt, ## args) |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3133990f04e..e45e70bcc5e 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... |
diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h index 77bcdb9d5b3..0b7fbcd2196 100644 --- a/drivers/usb/musb/musb_host.h +++ b/drivers/usb/musb/musb_host.h | |||
| @@ -53,6 +53,7 @@ struct musb_qh { | |||
| 53 | 53 | ||
| 54 | struct list_head ring; /* of musb_qh */ | 54 | struct list_head ring; /* of musb_qh */ |
| 55 | /* struct musb_qh *next; */ /* for periodic tree */ | 55 | /* struct musb_qh *next; */ /* for periodic tree */ |
| 56 | u8 mux; /* qh multiplexed to hw_ep */ | ||
| 56 | 57 | ||
| 57 | unsigned offset; /* in urb->transfer_buffer */ | 58 | unsigned offset; /* in urb->transfer_buffer */ |
| 58 | unsigned segsize; /* current xfer fragment */ | 59 | unsigned segsize; /* current xfer fragment */ |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 9d2dcb121c5..ce6c162920f 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
| @@ -53,7 +53,9 @@ static void musb_do_idle(unsigned long _musb) | |||
| 53 | { | 53 | { |
| 54 | struct musb *musb = (void *)_musb; | 54 | struct musb *musb = (void *)_musb; |
| 55 | unsigned long flags; | 55 | unsigned long flags; |
| 56 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | ||
| 56 | u8 power; | 57 | u8 power; |
| 58 | #endif | ||
| 57 | u8 devctl; | 59 | u8 devctl; |
| 58 | 60 | ||
| 59 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 61 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index b73b036f3d7..ee8fca92a4a 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
| @@ -605,7 +605,7 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
| 605 | 605 | ||
| 606 | if (musb->board_mode != MUSB_OTG) { | 606 | if (musb->board_mode != MUSB_OTG) { |
| 607 | ERR("Changing mode currently only supported in OTG mode\n"); | 607 | ERR("Changing mode currently only supported in OTG mode\n"); |
| 608 | return; | 608 | return -EINVAL; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); | 611 | otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT); |
