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.c138
1 files changed, 77 insertions, 61 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index b1b551a3d14e..c4194182dcc4 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -48,10 +48,6 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
48 return NULL; 48 return NULL;
49 49
50 td->dma_handle = dma_handle; 50 td->dma_handle = dma_handle;
51
52 td->link = UHCI_PTR_TERM;
53 td->buffer = 0;
54
55 td->frame = -1; 51 td->frame = -1;
56 52
57 INIT_LIST_HEAD(&td->list); 53 INIT_LIST_HEAD(&td->list);
@@ -221,6 +217,11 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
221 INIT_LIST_HEAD(&qh->node); 217 INIT_LIST_HEAD(&qh->node);
222 218
223 if (udev) { /* Normal QH */ 219 if (udev) { /* Normal QH */
220 qh->dummy_td = uhci_alloc_td(uhci);
221 if (!qh->dummy_td) {
222 dma_pool_free(uhci->qh_pool, qh, dma_handle);
223 return NULL;
224 }
224 qh->state = QH_STATE_IDLE; 225 qh->state = QH_STATE_IDLE;
225 qh->hep = hep; 226 qh->hep = hep;
226 qh->udev = udev; 227 qh->udev = udev;
@@ -244,6 +245,7 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
244 if (qh->udev) { 245 if (qh->udev) {
245 qh->hep->hcpriv = NULL; 246 qh->hep->hcpriv = NULL;
246 usb_put_dev(qh->udev); 247 usb_put_dev(qh->udev);
248 uhci_free_td(uhci, qh->dummy_td);
247 } 249 }
248 dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); 250 dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
249} 251}
@@ -531,22 +533,20 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
531 /* The "pipe" thing contains the destination in bits 8--18 */ 533 /* The "pipe" thing contains the destination in bits 8--18 */
532 destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; 534 destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
533 535
534 /* 3 errors */ 536 /* 3 errors, dummy TD remains inactive */
535 status = TD_CTRL_ACTIVE | uhci_maxerr(3); 537 status = uhci_maxerr(3);
536 if (urb->dev->speed == USB_SPEED_LOW) 538 if (urb->dev->speed == USB_SPEED_LOW)
537 status |= TD_CTRL_LS; 539 status |= TD_CTRL_LS;
538 540
539 /* 541 /*
540 * Build the TD for the control request setup packet 542 * Build the TD for the control request setup packet
541 */ 543 */
542 td = uhci_alloc_td(uhci); 544 td = qh->dummy_td;
543 if (!td)
544 return -ENOMEM;
545
546 uhci_add_td_to_urb(urb, td); 545 uhci_add_td_to_urb(urb, td);
547 uhci_fill_td(td, status, destination | uhci_explen(8), 546 uhci_fill_td(td, status, destination | uhci_explen(8),
548 urb->setup_dma); 547 urb->setup_dma);
549 plink = &td->link; 548 plink = &td->link;
549 status |= TD_CTRL_ACTIVE;
550 550
551 /* 551 /*
552 * If direction is "send", change the packet ID from SETUP (0x2D) 552 * If direction is "send", change the packet ID from SETUP (0x2D)
@@ -568,7 +568,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
568 568
569 td = uhci_alloc_td(uhci); 569 td = uhci_alloc_td(uhci);
570 if (!td) 570 if (!td)
571 return -ENOMEM; 571 goto nomem;
572 *plink = cpu_to_le32(td->dma_handle); 572 *plink = cpu_to_le32(td->dma_handle);
573 573
574 /* Alternate Data0/1 (start with Data1) */ 574 /* Alternate Data0/1 (start with Data1) */
@@ -588,7 +588,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
588 */ 588 */
589 td = uhci_alloc_td(uhci); 589 td = uhci_alloc_td(uhci);
590 if (!td) 590 if (!td)
591 return -ENOMEM; 591 goto nomem;
592 *plink = cpu_to_le32(td->dma_handle); 592 *plink = cpu_to_le32(td->dma_handle);
593 593
594 /* 594 /*
@@ -608,6 +608,20 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
608 uhci_add_td_to_urb(urb, td); 608 uhci_add_td_to_urb(urb, td);
609 uhci_fill_td(td, status | TD_CTRL_IOC, 609 uhci_fill_td(td, status | TD_CTRL_IOC,
610 destination | uhci_explen(0), 0); 610 destination | uhci_explen(0), 0);
611 plink = &td->link;
612
613 /*
614 * Build the new dummy TD and activate the old one
615 */
616 td = uhci_alloc_td(uhci);
617 if (!td)
618 goto nomem;
619 *plink = cpu_to_le32(td->dma_handle);
620
621 uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
622 wmb();
623 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
624 qh->dummy_td = td;
611 625
612 /* Low-speed transfers get a different queue, and won't hog the bus. 626 /* Low-speed transfers get a different queue, and won't hog the bus.
613 * Also, some devices enumerate better without FSBR; the easiest way 627 * Also, some devices enumerate better without FSBR; the easiest way
@@ -620,8 +634,12 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
620 qh->skel = uhci->skel_fs_control_qh; 634 qh->skel = uhci->skel_fs_control_qh;
621 uhci_inc_fsbr(uhci, urb); 635 uhci_inc_fsbr(uhci, urb);
622 } 636 }
623
624 return 0; 637 return 0;
638
639nomem:
640 /* Remove the dummy TD from the td_list so it doesn't get freed */
641 uhci_remove_td_from_urb(qh->dummy_td);
642 return -ENOMEM;
625} 643}
626 644
627/* 645/*
@@ -761,16 +779,19 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
761 int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 779 int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
762 int len = urb->transfer_buffer_length; 780 int len = urb->transfer_buffer_length;
763 dma_addr_t data = urb->transfer_dma; 781 dma_addr_t data = urb->transfer_dma;
764 __le32 *plink, fake_link; 782 __le32 *plink;
783 unsigned int toggle;
765 784
766 if (len < 0) 785 if (len < 0)
767 return -EINVAL; 786 return -EINVAL;
768 787
769 /* The "pipe" thing contains the destination in bits 8--18 */ 788 /* The "pipe" thing contains the destination in bits 8--18 */
770 destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); 789 destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
790 toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
791 usb_pipeout(urb->pipe));
771 792
772 /* 3 errors */ 793 /* 3 errors, dummy TD remains inactive */
773 status = TD_CTRL_ACTIVE | uhci_maxerr(3); 794 status = uhci_maxerr(3);
774 if (urb->dev->speed == USB_SPEED_LOW) 795 if (urb->dev->speed == USB_SPEED_LOW)
775 status |= TD_CTRL_LS; 796 status |= TD_CTRL_LS;
776 if (usb_pipein(urb->pipe)) 797 if (usb_pipein(urb->pipe))
@@ -779,7 +800,8 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
779 /* 800 /*
780 * Build the DATA TDs 801 * Build the DATA TDs
781 */ 802 */
782 plink = &fake_link; 803 plink = NULL;
804 td = qh->dummy_td;
783 do { /* Allow zero length packets */ 805 do { /* Allow zero length packets */
784 int pktsze = maxsze; 806 int pktsze = maxsze;
785 807
@@ -789,24 +811,23 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
789 status &= ~TD_CTRL_SPD; 811 status &= ~TD_CTRL_SPD;
790 } 812 }
791 813
792 td = uhci_alloc_td(uhci); 814 if (plink) {
793 if (!td) 815 td = uhci_alloc_td(uhci);
794 return -ENOMEM; 816 if (!td)
795 *plink = cpu_to_le32(td->dma_handle); 817 goto nomem;
796 818 *plink = cpu_to_le32(td->dma_handle);
819 }
797 uhci_add_td_to_urb(urb, td); 820 uhci_add_td_to_urb(urb, td);
798 uhci_fill_td(td, status, 821 uhci_fill_td(td, status,
799 destination | uhci_explen(pktsze) | 822 destination | uhci_explen(pktsze) |
800 (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), 823 (toggle << TD_TOKEN_TOGGLE_SHIFT),
801 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), 824 data);
802 data);
803 plink = &td->link; 825 plink = &td->link;
826 status |= TD_CTRL_ACTIVE;
804 827
805 data += pktsze; 828 data += pktsze;
806 len -= maxsze; 829 len -= maxsze;
807 830 toggle ^= 1;
808 usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe),
809 usb_pipeout(urb->pipe));
810 } while (len > 0); 831 } while (len > 0);
811 832
812 /* 833 /*
@@ -821,17 +842,17 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
821 urb->transfer_buffer_length > 0) { 842 urb->transfer_buffer_length > 0) {
822 td = uhci_alloc_td(uhci); 843 td = uhci_alloc_td(uhci);
823 if (!td) 844 if (!td)
824 return -ENOMEM; 845 goto nomem;
825 *plink = cpu_to_le32(td->dma_handle); 846 *plink = cpu_to_le32(td->dma_handle);
826 847
827 uhci_add_td_to_urb(urb, td); 848 uhci_add_td_to_urb(urb, td);
828 uhci_fill_td(td, status, destination | uhci_explen(0) | 849 uhci_fill_td(td, status,
829 (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), 850 destination | uhci_explen(0) |
830 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT), 851 (toggle << TD_TOKEN_TOGGLE_SHIFT),
831 data); 852 data);
853 plink = &td->link;
832 854
833 usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), 855 toggle ^= 1;
834 usb_pipeout(urb->pipe));
835 } 856 }
836 857
837 /* Set the interrupt-on-completion flag on the last packet. 858 /* Set the interrupt-on-completion flag on the last packet.
@@ -842,7 +863,27 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
842 * flag setting. */ 863 * flag setting. */
843 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 864 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC);
844 865
866 /*
867 * Build the new dummy TD and activate the old one
868 */
869 td = uhci_alloc_td(uhci);
870 if (!td)
871 goto nomem;
872 *plink = cpu_to_le32(td->dma_handle);
873
874 uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
875 wmb();
876 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE);
877 qh->dummy_td = td;
878
879 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
880 usb_pipeout(urb->pipe), toggle);
845 return 0; 881 return 0;
882
883nomem:
884 /* Remove the dummy TD from the td_list so it doesn't get freed */
885 uhci_remove_td_from_urb(qh->dummy_td);
886 return -ENOMEM;
846} 887}
847 888
848/* 889/*
@@ -1169,31 +1210,6 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1169 * become idle, so we can activate it right away. */ 1210 * become idle, so we can activate it right away. */
1170 if (qh->queue.next == &urbp->node) 1211 if (qh->queue.next == &urbp->node)
1171 uhci_activate_qh(uhci, qh); 1212 uhci_activate_qh(uhci, qh);
1172
1173 /* If the QH is already active, we have a race with the hardware.
1174 * This won't get fixed until dummy TDs are added. */
1175 else if (qh->state == QH_STATE_ACTIVE) {
1176
1177 /* If the URB isn't first on its queue, adjust the link pointer
1178 * of the last TD in the previous URB. */
1179 if (urbp->node.prev != &urbp->qh->queue) {
1180 struct urb_priv *purbp = list_entry(urbp->node.prev,
1181 struct urb_priv, node);
1182 struct uhci_td *ptd = list_entry(purbp->td_list.prev,
1183 struct uhci_td, list);
1184 struct uhci_td *td = list_entry(urbp->td_list.next,
1185 struct uhci_td, list);
1186
1187 ptd->link = cpu_to_le32(td->dma_handle);
1188
1189 }
1190 if (qh_element(qh) == UHCI_PTR_TERM) {
1191 struct uhci_td *td = list_entry(urbp->td_list.next,
1192 struct uhci_td, list);
1193
1194 qh->element = cpu_to_le32(td->dma_handle);
1195 }
1196 }
1197 goto done; 1213 goto done;
1198 1214
1199err_submit_failed: 1215err_submit_failed: