aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/ehci-hcd.c12
-rw-r--r--drivers/usb/host/ehci-sched.c53
-rw-r--r--drivers/usb/host/ehci.h3
3 files changed, 16 insertions, 52 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 98b945840c9e..fb1966cf5649 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1085,8 +1085,14 @@ rescan:
1085 * accelerate iso completions ... so spin a while. 1085 * accelerate iso completions ... so spin a while.
1086 */ 1086 */
1087 if (qh->hw == NULL) { 1087 if (qh->hw == NULL) {
1088 ehci_vdbg (ehci, "iso delay\n"); 1088 struct ehci_iso_stream *stream = ep->hcpriv;
1089 goto idle_timeout; 1089
1090 if (!list_empty(&stream->td_list))
1091 goto idle_timeout;
1092
1093 /* BUG_ON(!list_empty(&stream->free_list)); */
1094 kfree(stream);
1095 goto done;
1090 } 1096 }
1091 1097
1092 if (ehci->rh_state < EHCI_RH_RUNNING) 1098 if (ehci->rh_state < EHCI_RH_RUNNING)
@@ -1127,8 +1133,8 @@ idle_timeout:
1127 list_empty (&qh->qtd_list) ? "" : "(has tds)"); 1133 list_empty (&qh->qtd_list) ? "" : "(has tds)");
1128 break; 1134 break;
1129 } 1135 }
1136 done:
1130 ep->hcpriv = NULL; 1137 ep->hcpriv = NULL;
1131done:
1132 spin_unlock_irqrestore (&ehci->lock, flags); 1138 spin_unlock_irqrestore (&ehci->lock, flags);
1133} 1139}
1134 1140
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 1e4f13c11b6a..11b2f21d7ac1 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -934,7 +934,6 @@ iso_stream_alloc (gfp_t mem_flags)
934 INIT_LIST_HEAD(&stream->td_list); 934 INIT_LIST_HEAD(&stream->td_list);
935 INIT_LIST_HEAD(&stream->free_list); 935 INIT_LIST_HEAD(&stream->free_list);
936 stream->next_uframe = -1; 936 stream->next_uframe = -1;
937 stream->refcount = 1;
938 } 937 }
939 return stream; 938 return stream;
940} 939}
@@ -1034,32 +1033,6 @@ iso_stream_init (
1034 stream->maxp = maxp; 1033 stream->maxp = maxp;
1035} 1034}
1036 1035
1037static void
1038iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
1039{
1040 stream->refcount--;
1041
1042 /* free whenever just a dev->ep reference remains.
1043 * not like a QH -- no persistent state (toggle, halt)
1044 */
1045 if (stream->refcount == 1) {
1046 // BUG_ON (!list_empty(&stream->td_list));
1047
1048 if (stream->ep)
1049 stream->ep->hcpriv = NULL;
1050
1051 kfree(stream);
1052 }
1053}
1054
1055static inline struct ehci_iso_stream *
1056iso_stream_get (struct ehci_iso_stream *stream)
1057{
1058 if (likely (stream != NULL))
1059 stream->refcount++;
1060 return stream;
1061}
1062
1063static struct ehci_iso_stream * 1036static struct ehci_iso_stream *
1064iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) 1037iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
1065{ 1038{
@@ -1080,7 +1053,6 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
1080 if (unlikely (stream == NULL)) { 1053 if (unlikely (stream == NULL)) {
1081 stream = iso_stream_alloc(GFP_ATOMIC); 1054 stream = iso_stream_alloc(GFP_ATOMIC);
1082 if (likely (stream != NULL)) { 1055 if (likely (stream != NULL)) {
1083 /* dev->ep owns the initial refcount */
1084 ep->hcpriv = stream; 1056 ep->hcpriv = stream;
1085 stream->ep = ep; 1057 stream->ep = ep;
1086 iso_stream_init(ehci, stream, urb->dev, urb->pipe, 1058 iso_stream_init(ehci, stream, urb->dev, urb->pipe,
@@ -1095,9 +1067,6 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)
1095 stream = NULL; 1067 stream = NULL;
1096 } 1068 }
1097 1069
1098 /* caller guarantees an eventual matching iso_stream_put */
1099 stream = iso_stream_get (stream);
1100
1101 spin_unlock_irqrestore (&ehci->lock, flags); 1070 spin_unlock_irqrestore (&ehci->lock, flags);
1102 return stream; 1071 return stream;
1103} 1072}
@@ -1611,7 +1580,7 @@ static void itd_link_urb(
1611 itd = list_entry (iso_sched->td_list.next, 1580 itd = list_entry (iso_sched->td_list.next,
1612 struct ehci_itd, itd_list); 1581 struct ehci_itd, itd_list);
1613 list_move_tail (&itd->itd_list, &stream->td_list); 1582 list_move_tail (&itd->itd_list, &stream->td_list);
1614 itd->stream = iso_stream_get (stream); 1583 itd->stream = stream;
1615 itd->urb = urb; 1584 itd->urb = urb;
1616 itd_init (ehci, stream, itd); 1585 itd_init (ehci, stream, itd);
1617 } 1586 }
@@ -1735,7 +1704,6 @@ itd_complete (
1735 dev->devpath, stream->bEndpointAddress & 0x0f, 1704 dev->devpath, stream->bEndpointAddress & 0x0f,
1736 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); 1705 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
1737 } 1706 }
1738 iso_stream_put (ehci, stream);
1739 1707
1740done: 1708done:
1741 itd->urb = NULL; 1709 itd->urb = NULL;
@@ -1750,7 +1718,6 @@ done:
1750 start_free_itds(ehci); 1718 start_free_itds(ehci);
1751 } 1719 }
1752 1720
1753 iso_stream_put(ehci, stream);
1754 return retval; 1721 return retval;
1755} 1722}
1756 1723
@@ -1807,12 +1774,9 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
1807 itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); 1774 itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
1808 else 1775 else
1809 usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); 1776 usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
1810done_not_linked: 1777 done_not_linked:
1811 spin_unlock_irqrestore (&ehci->lock, flags); 1778 spin_unlock_irqrestore (&ehci->lock, flags);
1812 1779 done:
1813done:
1814 if (unlikely (status < 0))
1815 iso_stream_put (ehci, stream);
1816 return status; 1780 return status;
1817} 1781}
1818 1782
@@ -2028,7 +1992,7 @@ static void sitd_link_urb(
2028 sitd = list_entry (sched->td_list.next, 1992 sitd = list_entry (sched->td_list.next,
2029 struct ehci_sitd, sitd_list); 1993 struct ehci_sitd, sitd_list);
2030 list_move_tail (&sitd->sitd_list, &stream->td_list); 1994 list_move_tail (&sitd->sitd_list, &stream->td_list);
2031 sitd->stream = iso_stream_get (stream); 1995 sitd->stream = stream;
2032 sitd->urb = urb; 1996 sitd->urb = urb;
2033 1997
2034 sitd_patch(ehci, stream, sitd, sched, packet); 1998 sitd_patch(ehci, stream, sitd, sched, packet);
@@ -2126,7 +2090,6 @@ sitd_complete (
2126 dev->devpath, stream->bEndpointAddress & 0x0f, 2090 dev->devpath, stream->bEndpointAddress & 0x0f,
2127 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); 2091 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
2128 } 2092 }
2129 iso_stream_put (ehci, stream);
2130 2093
2131done: 2094done:
2132 sitd->urb = NULL; 2095 sitd->urb = NULL;
@@ -2141,7 +2104,6 @@ done:
2141 start_free_itds(ehci); 2104 start_free_itds(ehci);
2142 } 2105 }
2143 2106
2144 iso_stream_put(ehci, stream);
2145 return retval; 2107 return retval;
2146} 2108}
2147 2109
@@ -2195,12 +2157,9 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
2195 sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); 2157 sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
2196 else 2158 else
2197 usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); 2159 usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
2198done_not_linked: 2160 done_not_linked:
2199 spin_unlock_irqrestore (&ehci->lock, flags); 2161 spin_unlock_irqrestore (&ehci->lock, flags);
2200 2162 done:
2201done:
2202 if (status < 0)
2203 iso_stream_put (ehci, stream);
2204 return status; 2163 return status;
2205} 2164}
2206 2165
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index bcfbb175e2b4..755e30b0000b 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -386,7 +386,7 @@ struct ehci_qh_hw {
386} __attribute__ ((aligned(32))); 386} __attribute__ ((aligned(32)));
387 387
388struct ehci_qh { 388struct ehci_qh {
389 struct ehci_qh_hw *hw; 389 struct ehci_qh_hw *hw; /* Must come first */
390 /* the rest is HCD-private */ 390 /* the rest is HCD-private */
391 dma_addr_t qh_dma; /* address of qh */ 391 dma_addr_t qh_dma; /* address of qh */
392 union ehci_shadow qh_next; /* ptr to qh; or periodic */ 392 union ehci_shadow qh_next; /* ptr to qh; or periodic */
@@ -453,7 +453,6 @@ struct ehci_iso_stream {
453 /* first field matches ehci_hq, but is NULL */ 453 /* first field matches ehci_hq, but is NULL */
454 struct ehci_qh_hw *hw; 454 struct ehci_qh_hw *hw;
455 455
456 u32 refcount;
457 u8 bEndpointAddress; 456 u8 bEndpointAddress;
458 u8 highspeed; 457 u8 highspeed;
459 struct list_head td_list; /* queued itds/sitds */ 458 struct list_head td_list; /* queued itds/sitds */