uhci-q.c (5a84d159061d914c8dd4aa372ac6e9529c2be453) | uhci-q.c (28b9325e6ae45ffb5e99fedcafe00f25fcaacf06) |
---|---|
1/* 2 * Universal Host Controller Interface driver for USB. 3 * 4 * Maintainer: Alan Stern <stern@rowland.harvard.edu> 5 * 6 * (C) Copyright 1999 Linus Torvalds 7 * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com 8 * (C) Copyright 1999 Randy Dunlap --- 32 unchanged lines hidden (view full) --- 41/* 42 * Full-Speed Bandwidth Reclamation (FSBR). 43 * We turn on FSBR whenever a queue that wants it is advancing, 44 * and leave it on for a short time thereafter. 45 */ 46static void uhci_fsbr_on(struct uhci_hcd *uhci) 47{ 48 uhci->fsbr_is_on = 1; | 1/* 2 * Universal Host Controller Interface driver for USB. 3 * 4 * Maintainer: Alan Stern <stern@rowland.harvard.edu> 5 * 6 * (C) Copyright 1999 Linus Torvalds 7 * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com 8 * (C) Copyright 1999 Randy Dunlap --- 32 unchanged lines hidden (view full) --- 41/* 42 * Full-Speed Bandwidth Reclamation (FSBR). 43 * We turn on FSBR whenever a queue that wants it is advancing, 44 * and leave it on for a short time thereafter. 45 */ 46static void uhci_fsbr_on(struct uhci_hcd *uhci) 47{ 48 uhci->fsbr_is_on = 1; |
49 uhci->skel_term_qh->link = cpu_to_le32( 50 uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; | 49 uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_fs_control_qh); |
51} 52 53static void uhci_fsbr_off(struct uhci_hcd *uhci) 54{ 55 uhci->fsbr_is_on = 0; 56 uhci->skel_term_qh->link = UHCI_PTR_TERM; 57} 58 --- 94 unchanged lines hidden (view full) --- 153 154 ftd = uhci->frame_cpu[framenum]; 155 ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); 156 157 list_add_tail(&td->fl_list, &ftd->fl_list); 158 159 td->link = ltd->link; 160 wmb(); | 50} 51 52static void uhci_fsbr_off(struct uhci_hcd *uhci) 53{ 54 uhci->fsbr_is_on = 0; 55 uhci->skel_term_qh->link = UHCI_PTR_TERM; 56} 57 --- 94 unchanged lines hidden (view full) --- 152 153 ftd = uhci->frame_cpu[framenum]; 154 ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); 155 156 list_add_tail(&td->fl_list, &ftd->fl_list); 157 158 td->link = ltd->link; 159 wmb(); |
161 ltd->link = cpu_to_le32(td->dma_handle); | 160 ltd->link = LINK_TO_TD(td); |
162 } else { 163 td->link = uhci->frame[framenum]; 164 wmb(); | 161 } else { 162 td->link = uhci->frame[framenum]; 163 wmb(); |
165 uhci->frame[framenum] = cpu_to_le32(td->dma_handle); | 164 uhci->frame[framenum] = LINK_TO_TD(td); |
166 uhci->frame_cpu[framenum] = td; 167 } 168} 169 170static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, 171 struct uhci_td *td) 172{ 173 /* If it's not inserted, don't remove it */ --- 5 unchanged lines hidden (view full) --- 179 if (uhci->frame_cpu[td->frame] == td) { 180 if (list_empty(&td->fl_list)) { 181 uhci->frame[td->frame] = td->link; 182 uhci->frame_cpu[td->frame] = NULL; 183 } else { 184 struct uhci_td *ntd; 185 186 ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); | 165 uhci->frame_cpu[framenum] = td; 166 } 167} 168 169static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, 170 struct uhci_td *td) 171{ 172 /* If it's not inserted, don't remove it */ --- 5 unchanged lines hidden (view full) --- 178 if (uhci->frame_cpu[td->frame] == td) { 179 if (list_empty(&td->fl_list)) { 180 uhci->frame[td->frame] = td->link; 181 uhci->frame_cpu[td->frame] = NULL; 182 } else { 183 struct uhci_td *ntd; 184 185 ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); |
187 uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle); | 186 uhci->frame[td->frame] = LINK_TO_TD(ntd); |
188 uhci->frame_cpu[td->frame] = ntd; 189 } 190 } else { 191 struct uhci_td *ptd; 192 193 ptd = list_entry(td->fl_list.prev, struct uhci_td, fl_list); 194 ptd->link = td->link; 195 } --- 220 unchanged lines hidden (view full) --- 416 /* Set the element pointer if it isn't set already. 417 * This isn't needed for Isochronous queues, but it doesn't hurt. */ 418 if (qh_element(qh) == UHCI_PTR_TERM) { 419 struct urb_priv *urbp = list_entry(qh->queue.next, 420 struct urb_priv, node); 421 struct uhci_td *td = list_entry(urbp->td_list.next, 422 struct uhci_td, list); 423 | 187 uhci->frame_cpu[td->frame] = ntd; 188 } 189 } else { 190 struct uhci_td *ptd; 191 192 ptd = list_entry(td->fl_list.prev, struct uhci_td, fl_list); 193 ptd->link = td->link; 194 } --- 220 unchanged lines hidden (view full) --- 415 /* Set the element pointer if it isn't set already. 416 * This isn't needed for Isochronous queues, but it doesn't hurt. */ 417 if (qh_element(qh) == UHCI_PTR_TERM) { 418 struct urb_priv *urbp = list_entry(qh->queue.next, 419 struct urb_priv, node); 420 struct uhci_td *td = list_entry(urbp->td_list.next, 421 struct uhci_td, list); 422 |
424 qh->element = cpu_to_le32(td->dma_handle); | 423 qh->element = LINK_TO_TD(td); |
425 } 426 427 /* Treat the queue as if it has just advanced */ 428 qh->wait_expired = 0; 429 qh->advance_jiffies = jiffies; 430 431 if (qh->state == QH_STATE_ACTIVE) 432 return; --- 5 unchanged lines hidden (view full) --- 438 uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, 439 node); 440 list_move_tail(&qh->node, &qh->skel->node); 441 442 /* Link it into the schedule */ 443 pqh = list_entry(qh->node.prev, struct uhci_qh, node); 444 qh->link = pqh->link; 445 wmb(); | 424 } 425 426 /* Treat the queue as if it has just advanced */ 427 qh->wait_expired = 0; 428 qh->advance_jiffies = jiffies; 429 430 if (qh->state == QH_STATE_ACTIVE) 431 return; --- 5 unchanged lines hidden (view full) --- 437 uhci->next_qh = list_entry(qh->node.next, struct uhci_qh, 438 node); 439 list_move_tail(&qh->node, &qh->skel->node); 440 441 /* Link it into the schedule */ 442 pqh = list_entry(qh->node.prev, struct uhci_qh, node); 443 qh->link = pqh->link; 444 wmb(); |
446 pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle); | 445 pqh->link = LINK_TO_QH(qh); |
447} 448 449/* 450 * Take a QH off the hardware schedule 451 */ 452static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 453{ 454 struct uhci_qh *pqh; --- 277 unchanged lines hidden (view full) --- 732 * Build the DATA TDs 733 */ 734 while (len > 0) { 735 int pktsze = min(len, maxsze); 736 737 td = uhci_alloc_td(uhci); 738 if (!td) 739 goto nomem; | 446} 447 448/* 449 * Take a QH off the hardware schedule 450 */ 451static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) 452{ 453 struct uhci_qh *pqh; --- 277 unchanged lines hidden (view full) --- 731 * Build the DATA TDs 732 */ 733 while (len > 0) { 734 int pktsze = min(len, maxsze); 735 736 td = uhci_alloc_td(uhci); 737 if (!td) 738 goto nomem; |
740 *plink = cpu_to_le32(td->dma_handle); | 739 *plink = LINK_TO_TD(td); |
741 742 /* Alternate Data0/1 (start with Data1) */ 743 destination ^= TD_TOKEN_TOGGLE; 744 745 uhci_add_td_to_urbp(td, urbp); 746 uhci_fill_td(td, status, destination | uhci_explen(pktsze), 747 data); 748 plink = &td->link; 749 750 data += pktsze; 751 len -= pktsze; 752 } 753 754 /* 755 * Build the final TD for control status 756 */ 757 td = uhci_alloc_td(uhci); 758 if (!td) 759 goto nomem; | 740 741 /* Alternate Data0/1 (start with Data1) */ 742 destination ^= TD_TOKEN_TOGGLE; 743 744 uhci_add_td_to_urbp(td, urbp); 745 uhci_fill_td(td, status, destination | uhci_explen(pktsze), 746 data); 747 plink = &td->link; 748 749 data += pktsze; 750 len -= pktsze; 751 } 752 753 /* 754 * Build the final TD for control status 755 */ 756 td = uhci_alloc_td(uhci); 757 if (!td) 758 goto nomem; |
760 *plink = cpu_to_le32(td->dma_handle); | 759 *plink = LINK_TO_TD(td); |
761 762 /* 763 * It's IN if the pipe is an output pipe or we're not expecting 764 * data back. 765 */ 766 destination &= ~TD_TOKEN_PID_MASK; 767 if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) 768 destination |= USB_PID_IN; --- 10 unchanged lines hidden (view full) --- 779 plink = &td->link; 780 781 /* 782 * Build the new dummy TD and activate the old one 783 */ 784 td = uhci_alloc_td(uhci); 785 if (!td) 786 goto nomem; | 760 761 /* 762 * It's IN if the pipe is an output pipe or we're not expecting 763 * data back. 764 */ 765 destination &= ~TD_TOKEN_PID_MASK; 766 if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) 767 destination |= USB_PID_IN; --- 10 unchanged lines hidden (view full) --- 778 plink = &td->link; 779 780 /* 781 * Build the new dummy TD and activate the old one 782 */ 783 td = uhci_alloc_td(uhci); 784 if (!td) 785 goto nomem; |
787 *plink = cpu_to_le32(td->dma_handle); | 786 *plink = LINK_TO_TD(td); |
788 789 uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); 790 wmb(); 791 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); 792 qh->dummy_td = td; 793 794 /* Low-speed transfers get a different queue, and won't hog the bus. 795 * Also, some devices enumerate better without FSBR; the easiest way --- 59 unchanged lines hidden (view full) --- 855 if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) 856 status &= ~TD_CTRL_SPD; 857 } 858 859 if (plink) { 860 td = uhci_alloc_td(uhci); 861 if (!td) 862 goto nomem; | 787 788 uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); 789 wmb(); 790 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); 791 qh->dummy_td = td; 792 793 /* Low-speed transfers get a different queue, and won't hog the bus. 794 * Also, some devices enumerate better without FSBR; the easiest way --- 59 unchanged lines hidden (view full) --- 854 if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) 855 status &= ~TD_CTRL_SPD; 856 } 857 858 if (plink) { 859 td = uhci_alloc_td(uhci); 860 if (!td) 861 goto nomem; |
863 *plink = cpu_to_le32(td->dma_handle); | 862 *plink = LINK_TO_TD(td); |
864 } 865 uhci_add_td_to_urbp(td, urbp); 866 uhci_fill_td(td, status, 867 destination | uhci_explen(pktsze) | 868 (toggle << TD_TOKEN_TOGGLE_SHIFT), 869 data); 870 plink = &td->link; 871 status |= TD_CTRL_ACTIVE; --- 11 unchanged lines hidden (view full) --- 883 * prepared above. 884 */ 885 if ((urb->transfer_flags & URB_ZERO_PACKET) && 886 usb_pipeout(urb->pipe) && len == 0 && 887 urb->transfer_buffer_length > 0) { 888 td = uhci_alloc_td(uhci); 889 if (!td) 890 goto nomem; | 863 } 864 uhci_add_td_to_urbp(td, urbp); 865 uhci_fill_td(td, status, 866 destination | uhci_explen(pktsze) | 867 (toggle << TD_TOKEN_TOGGLE_SHIFT), 868 data); 869 plink = &td->link; 870 status |= TD_CTRL_ACTIVE; --- 11 unchanged lines hidden (view full) --- 882 * prepared above. 883 */ 884 if ((urb->transfer_flags & URB_ZERO_PACKET) && 885 usb_pipeout(urb->pipe) && len == 0 && 886 urb->transfer_buffer_length > 0) { 887 td = uhci_alloc_td(uhci); 888 if (!td) 889 goto nomem; |
891 *plink = cpu_to_le32(td->dma_handle); | 890 *plink = LINK_TO_TD(td); |
892 893 uhci_add_td_to_urbp(td, urbp); 894 uhci_fill_td(td, status, 895 destination | uhci_explen(0) | 896 (toggle << TD_TOKEN_TOGGLE_SHIFT), 897 data); 898 plink = &td->link; 899 --- 9 unchanged lines hidden (view full) --- 909 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 910 911 /* 912 * Build the new dummy TD and activate the old one 913 */ 914 td = uhci_alloc_td(uhci); 915 if (!td) 916 goto nomem; | 891 892 uhci_add_td_to_urbp(td, urbp); 893 uhci_fill_td(td, status, 894 destination | uhci_explen(0) | 895 (toggle << TD_TOKEN_TOGGLE_SHIFT), 896 data); 897 plink = &td->link; 898 --- 9 unchanged lines hidden (view full) --- 908 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); 909 910 /* 911 * Build the new dummy TD and activate the old one 912 */ 913 td = uhci_alloc_td(uhci); 914 if (!td) 915 goto nomem; |
917 *plink = cpu_to_le32(td->dma_handle); | 916 *plink = LINK_TO_TD(td); |
918 919 uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); 920 wmb(); 921 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); 922 qh->dummy_td = td; 923 924 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 925 usb_pipeout(urb->pipe), toggle); --- 74 unchanged lines hidden (view full) --- 1000 1001 td = list_entry(urbp->td_list.prev, struct uhci_td, list); 1002 if (qh->type == USB_ENDPOINT_XFER_CONTROL) { 1003 1004 /* When a control transfer is short, we have to restart 1005 * the queue at the status stage transaction, which is 1006 * the last TD. */ 1007 WARN_ON(list_empty(&urbp->td_list)); | 917 918 uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); 919 wmb(); 920 qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); 921 qh->dummy_td = td; 922 923 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 924 usb_pipeout(urb->pipe), toggle); --- 74 unchanged lines hidden (view full) --- 999 1000 td = list_entry(urbp->td_list.prev, struct uhci_td, list); 1001 if (qh->type == USB_ENDPOINT_XFER_CONTROL) { 1002 1003 /* When a control transfer is short, we have to restart 1004 * the queue at the status stage transaction, which is 1005 * the last TD. */ 1006 WARN_ON(list_empty(&urbp->td_list)); |
1008 qh->element = cpu_to_le32(td->dma_handle); | 1007 qh->element = LINK_TO_TD(td); |
1009 tmp = td->list.prev; 1010 ret = -EINPROGRESS; 1011 1012 } else { 1013 1014 /* When a bulk/interrupt transfer is short, we have to 1015 * fix up the toggles of the following URBs on the queue 1016 * before restarting the queue at the next URB. */ --- 544 unchanged lines hidden (view full) --- 1561 1562 /* The queue hasn't advanced; check for timeout */ 1563 if (qh->wait_expired) 1564 goto done; 1565 1566 if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { 1567 1568 /* Detect the Intel bug and work around it */ | 1008 tmp = td->list.prev; 1009 ret = -EINPROGRESS; 1010 1011 } else { 1012 1013 /* When a bulk/interrupt transfer is short, we have to 1014 * fix up the toggles of the following URBs on the queue 1015 * before restarting the queue at the next URB. */ --- 544 unchanged lines hidden (view full) --- 1560 1561 /* The queue hasn't advanced; check for timeout */ 1562 if (qh->wait_expired) 1563 goto done; 1564 1565 if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { 1566 1567 /* Detect the Intel bug and work around it */ |
1569 if (qh->post_td && qh_element(qh) == 1570 cpu_to_le32(qh->post_td->dma_handle)) { | 1568 if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) { |
1571 qh->element = qh->post_td->link; 1572 qh->advance_jiffies = jiffies; 1573 ret = 1; 1574 goto done; 1575 } 1576 1577 qh->wait_expired = 1; 1578 --- 73 unchanged lines hidden --- | 1569 qh->element = qh->post_td->link; 1570 qh->advance_jiffies = jiffies; 1571 ret = 1; 1572 goto done; 1573 } 1574 1575 qh->wait_expired = 1; 1576 --- 73 unchanged lines hidden --- |