aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-q.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/uhci-q.c')
-rw-r--r--drivers/usb/host/uhci-q.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 2a7c19501f24..5f18084a116d 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -32,6 +32,8 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci);
32 */ 32 */
33static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci) 33static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci)
34{ 34{
35 if (uhci->is_stopped)
36 mod_timer(&uhci->stall_timer, jiffies);
35 uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); 37 uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC);
36} 38}
37 39
@@ -46,7 +48,7 @@ static inline void uhci_moveto_complete(struct uhci_hcd *uhci,
46 list_move_tail(&urbp->urb_list, &uhci->complete_list); 48 list_move_tail(&urbp->urb_list, &uhci->complete_list);
47} 49}
48 50
49static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *dev) 51static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
50{ 52{
51 dma_addr_t dma_handle; 53 dma_addr_t dma_handle;
52 struct uhci_td *td; 54 struct uhci_td *td;
@@ -61,14 +63,11 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *d
61 td->buffer = 0; 63 td->buffer = 0;
62 64
63 td->frame = -1; 65 td->frame = -1;
64 td->dev = dev;
65 66
66 INIT_LIST_HEAD(&td->list); 67 INIT_LIST_HEAD(&td->list);
67 INIT_LIST_HEAD(&td->remove_list); 68 INIT_LIST_HEAD(&td->remove_list);
68 INIT_LIST_HEAD(&td->fl_list); 69 INIT_LIST_HEAD(&td->fl_list);
69 70
70 usb_get_dev(dev);
71
72 return td; 71 return td;
73} 72}
74 73
@@ -168,13 +167,10 @@ static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
168 if (!list_empty(&td->fl_list)) 167 if (!list_empty(&td->fl_list))
169 dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); 168 dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
170 169
171 if (td->dev)
172 usb_put_dev(td->dev);
173
174 dma_pool_free(uhci->td_pool, td, td->dma_handle); 170 dma_pool_free(uhci->td_pool, td, td->dma_handle);
175} 171}
176 172
177static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, struct usb_device *dev) 173static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci)
178{ 174{
179 dma_addr_t dma_handle; 175 dma_addr_t dma_handle;
180 struct uhci_qh *qh; 176 struct uhci_qh *qh;
@@ -188,14 +184,11 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, struct usb_device *d
188 qh->element = UHCI_PTR_TERM; 184 qh->element = UHCI_PTR_TERM;
189 qh->link = UHCI_PTR_TERM; 185 qh->link = UHCI_PTR_TERM;
190 186
191 qh->dev = dev;
192 qh->urbp = NULL; 187 qh->urbp = NULL;
193 188
194 INIT_LIST_HEAD(&qh->list); 189 INIT_LIST_HEAD(&qh->list);
195 INIT_LIST_HEAD(&qh->remove_list); 190 INIT_LIST_HEAD(&qh->remove_list);
196 191
197 usb_get_dev(dev);
198
199 return qh; 192 return qh;
200} 193}
201 194
@@ -206,9 +199,6 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
206 if (!list_empty(&qh->remove_list)) 199 if (!list_empty(&qh->remove_list))
207 dev_warn(uhci_dev(uhci), "qh %p still in remove_list!\n", qh); 200 dev_warn(uhci_dev(uhci), "qh %p still in remove_list!\n", qh);
208 201
209 if (qh->dev)
210 usb_put_dev(qh->dev);
211
212 dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); 202 dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
213} 203}
214 204
@@ -597,7 +587,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
597 /* 587 /*
598 * Build the TD for the control request setup packet 588 * Build the TD for the control request setup packet
599 */ 589 */
600 td = uhci_alloc_td(uhci, urb->dev); 590 td = uhci_alloc_td(uhci);
601 if (!td) 591 if (!td)
602 return -ENOMEM; 592 return -ENOMEM;
603 593
@@ -626,7 +616,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
626 if (pktsze > maxsze) 616 if (pktsze > maxsze)
627 pktsze = maxsze; 617 pktsze = maxsze;
628 618
629 td = uhci_alloc_td(uhci, urb->dev); 619 td = uhci_alloc_td(uhci);
630 if (!td) 620 if (!td)
631 return -ENOMEM; 621 return -ENOMEM;
632 622
@@ -644,7 +634,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
644 /* 634 /*
645 * Build the final TD for control status 635 * Build the final TD for control status
646 */ 636 */
647 td = uhci_alloc_td(uhci, urb->dev); 637 td = uhci_alloc_td(uhci);
648 if (!td) 638 if (!td)
649 return -ENOMEM; 639 return -ENOMEM;
650 640
@@ -666,7 +656,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur
666 uhci_fill_td(td, status | TD_CTRL_IOC, 656 uhci_fill_td(td, status | TD_CTRL_IOC,
667 destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0); 657 destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0);
668 658
669 qh = uhci_alloc_qh(uhci, urb->dev); 659 qh = uhci_alloc_qh(uhci);
670 if (!qh) 660 if (!qh)
671 return -ENOMEM; 661 return -ENOMEM;
672 662
@@ -865,7 +855,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb
865 status &= ~TD_CTRL_SPD; 855 status &= ~TD_CTRL_SPD;
866 } 856 }
867 857
868 td = uhci_alloc_td(uhci, urb->dev); 858 td = uhci_alloc_td(uhci);
869 if (!td) 859 if (!td)
870 return -ENOMEM; 860 return -ENOMEM;
871 861
@@ -891,7 +881,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb
891 */ 881 */
892 if (usb_pipeout(urb->pipe) && (urb->transfer_flags & URB_ZERO_PACKET) && 882 if (usb_pipeout(urb->pipe) && (urb->transfer_flags & URB_ZERO_PACKET) &&
893 !len && urb->transfer_buffer_length) { 883 !len && urb->transfer_buffer_length) {
894 td = uhci_alloc_td(uhci, urb->dev); 884 td = uhci_alloc_td(uhci);
895 if (!td) 885 if (!td)
896 return -ENOMEM; 886 return -ENOMEM;
897 887
@@ -913,7 +903,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, struct urb
913 * flag setting. */ 903 * flag setting. */
914 td->status |= cpu_to_le32(TD_CTRL_IOC); 904 td->status |= cpu_to_le32(TD_CTRL_IOC);
915 905
916 qh = uhci_alloc_qh(uhci, urb->dev); 906 qh = uhci_alloc_qh(uhci);
917 if (!qh) 907 if (!qh)
918 return -ENOMEM; 908 return -ENOMEM;
919 909
@@ -1096,7 +1086,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb)
1096 if (!urb->iso_frame_desc[i].length) 1086 if (!urb->iso_frame_desc[i].length)
1097 continue; 1087 continue;
1098 1088
1099 td = uhci_alloc_td(uhci, urb->dev); 1089 td = uhci_alloc_td(uhci);
1100 if (!td) 1090 if (!td)
1101 return -ENOMEM; 1091 return -ENOMEM;
1102 1092
@@ -1497,6 +1487,7 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
1497 rescan: 1487 rescan:
1498 uhci->need_rescan = 0; 1488 uhci->need_rescan = 0;
1499 1489
1490 uhci_clear_next_interrupt(uhci);
1500 uhci_get_current_frame_number(uhci); 1491 uhci_get_current_frame_number(uhci);
1501 1492
1502 if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age) 1493 if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age)
@@ -1537,3 +1528,26 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
1537 /* Wake up anyone waiting for an URB to complete */ 1528 /* Wake up anyone waiting for an URB to complete */
1538 wake_up_all(&uhci->waitqh); 1529 wake_up_all(&uhci->waitqh);
1539} 1530}
1531
1532static void check_fsbr(struct uhci_hcd *uhci)
1533{
1534 struct urb_priv *up;
1535
1536 list_for_each_entry(up, &uhci->urb_list, urb_list) {
1537 struct urb *u = up->urb;
1538
1539 spin_lock(&u->lock);
1540
1541 /* Check if the FSBR timed out */
1542 if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT))
1543 uhci_fsbr_timeout(uhci, u);
1544
1545 spin_unlock(&u->lock);
1546 }
1547
1548 /* Really disable FSBR */
1549 if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
1550 uhci->fsbrtimeout = 0;
1551 uhci->skel_term_qh->link = UHCI_PTR_TERM;
1552 }
1553}