diff options
Diffstat (limited to 'drivers/usb/host/uhci-q.c')
-rw-r--r-- | drivers/usb/host/uhci-q.c | 174 |
1 files changed, 102 insertions, 72 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index d3ade4018487..84ed28b34f93 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -29,12 +29,12 @@ static void uhci_set_next_interrupt(struct uhci_hcd *uhci) | |||
29 | { | 29 | { |
30 | if (uhci->is_stopped) | 30 | if (uhci->is_stopped) |
31 | mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); | 31 | mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); |
32 | uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); | 32 | uhci->term_td->status |= cpu_to_hc32(uhci, TD_CTRL_IOC); |
33 | } | 33 | } |
34 | 34 | ||
35 | static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) | 35 | static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) |
36 | { | 36 | { |
37 | uhci->term_td->status &= ~cpu_to_le32(TD_CTRL_IOC); | 37 | uhci->term_td->status &= ~cpu_to_hc32(uhci, TD_CTRL_IOC); |
38 | } | 38 | } |
39 | 39 | ||
40 | 40 | ||
@@ -53,7 +53,7 @@ static void uhci_fsbr_on(struct uhci_hcd *uhci) | |||
53 | uhci->fsbr_is_on = 1; | 53 | uhci->fsbr_is_on = 1; |
54 | lqh = list_entry(uhci->skel_async_qh->node.prev, | 54 | lqh = list_entry(uhci->skel_async_qh->node.prev, |
55 | struct uhci_qh, node); | 55 | struct uhci_qh, node); |
56 | lqh->link = LINK_TO_QH(uhci->skel_term_qh); | 56 | lqh->link = LINK_TO_QH(uhci, uhci->skel_term_qh); |
57 | } | 57 | } |
58 | 58 | ||
59 | static void uhci_fsbr_off(struct uhci_hcd *uhci) | 59 | static void uhci_fsbr_off(struct uhci_hcd *uhci) |
@@ -65,7 +65,7 @@ static void uhci_fsbr_off(struct uhci_hcd *uhci) | |||
65 | uhci->fsbr_is_on = 0; | 65 | uhci->fsbr_is_on = 0; |
66 | lqh = list_entry(uhci->skel_async_qh->node.prev, | 66 | lqh = list_entry(uhci->skel_async_qh->node.prev, |
67 | struct uhci_qh, node); | 67 | struct uhci_qh, node); |
68 | lqh->link = UHCI_PTR_TERM; | 68 | lqh->link = UHCI_PTR_TERM(uhci); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb) | 71 | static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb) |
@@ -131,12 +131,12 @@ static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) | |||
131 | dma_pool_free(uhci->td_pool, td, td->dma_handle); | 131 | dma_pool_free(uhci->td_pool, td, td->dma_handle); |
132 | } | 132 | } |
133 | 133 | ||
134 | static inline void uhci_fill_td(struct uhci_td *td, u32 status, | 134 | static inline void uhci_fill_td(struct uhci_hcd *uhci, struct uhci_td *td, |
135 | u32 token, u32 buffer) | 135 | u32 status, u32 token, u32 buffer) |
136 | { | 136 | { |
137 | td->status = cpu_to_le32(status); | 137 | td->status = cpu_to_hc32(uhci, status); |
138 | td->token = cpu_to_le32(token); | 138 | td->token = cpu_to_hc32(uhci, token); |
139 | td->buffer = cpu_to_le32(buffer); | 139 | td->buffer = cpu_to_hc32(uhci, buffer); |
140 | } | 140 | } |
141 | 141 | ||
142 | static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp) | 142 | static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp) |
@@ -170,11 +170,11 @@ static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, | |||
170 | 170 | ||
171 | td->link = ltd->link; | 171 | td->link = ltd->link; |
172 | wmb(); | 172 | wmb(); |
173 | ltd->link = LINK_TO_TD(td); | 173 | ltd->link = LINK_TO_TD(uhci, td); |
174 | } else { | 174 | } else { |
175 | td->link = uhci->frame[framenum]; | 175 | td->link = uhci->frame[framenum]; |
176 | wmb(); | 176 | wmb(); |
177 | uhci->frame[framenum] = LINK_TO_TD(td); | 177 | uhci->frame[framenum] = LINK_TO_TD(uhci, td); |
178 | uhci->frame_cpu[framenum] = td; | 178 | uhci->frame_cpu[framenum] = td; |
179 | } | 179 | } |
180 | } | 180 | } |
@@ -195,8 +195,10 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, | |||
195 | } else { | 195 | } else { |
196 | struct uhci_td *ntd; | 196 | struct uhci_td *ntd; |
197 | 197 | ||
198 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); | 198 | ntd = list_entry(td->fl_list.next, |
199 | uhci->frame[td->frame] = LINK_TO_TD(ntd); | 199 | struct uhci_td, |
200 | fl_list); | ||
201 | uhci->frame[td->frame] = LINK_TO_TD(uhci, ntd); | ||
200 | uhci->frame_cpu[td->frame] = ntd; | 202 | uhci->frame_cpu[td->frame] = ntd; |
201 | } | 203 | } |
202 | } else { | 204 | } else { |
@@ -253,8 +255,8 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, | |||
253 | memset(qh, 0, sizeof(*qh)); | 255 | memset(qh, 0, sizeof(*qh)); |
254 | qh->dma_handle = dma_handle; | 256 | qh->dma_handle = dma_handle; |
255 | 257 | ||
256 | qh->element = UHCI_PTR_TERM; | 258 | qh->element = UHCI_PTR_TERM(uhci); |
257 | qh->link = UHCI_PTR_TERM; | 259 | qh->link = UHCI_PTR_TERM(uhci); |
258 | 260 | ||
259 | INIT_LIST_HEAD(&qh->queue); | 261 | INIT_LIST_HEAD(&qh->queue); |
260 | INIT_LIST_HEAD(&qh->node); | 262 | INIT_LIST_HEAD(&qh->node); |
@@ -346,9 +348,9 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, | |||
346 | 348 | ||
347 | /* If the QH element pointer is UHCI_PTR_TERM then then currently | 349 | /* If the QH element pointer is UHCI_PTR_TERM then then currently |
348 | * executing URB has already been unlinked, so this one isn't it. */ | 350 | * executing URB has already been unlinked, so this one isn't it. */ |
349 | if (qh_element(qh) == UHCI_PTR_TERM) | 351 | if (qh_element(qh) == UHCI_PTR_TERM(uhci)) |
350 | goto done; | 352 | goto done; |
351 | qh->element = UHCI_PTR_TERM; | 353 | qh->element = UHCI_PTR_TERM(uhci); |
352 | 354 | ||
353 | /* Control pipes don't have to worry about toggles */ | 355 | /* Control pipes don't have to worry about toggles */ |
354 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) | 356 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) |
@@ -358,7 +360,7 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, | |||
358 | WARN_ON(list_empty(&urbp->td_list)); | 360 | WARN_ON(list_empty(&urbp->td_list)); |
359 | td = list_entry(urbp->td_list.next, struct uhci_td, list); | 361 | td = list_entry(urbp->td_list.next, struct uhci_td, list); |
360 | qh->needs_fixup = 1; | 362 | qh->needs_fixup = 1; |
361 | qh->initial_toggle = uhci_toggle(td_token(td)); | 363 | qh->initial_toggle = uhci_toggle(td_token(uhci, td)); |
362 | 364 | ||
363 | done: | 365 | done: |
364 | return ret; | 366 | return ret; |
@@ -368,7 +370,8 @@ done: | |||
368 | * Fix up the data toggles for URBs in a queue, when one of them | 370 | * Fix up the data toggles for URBs in a queue, when one of them |
369 | * terminates early (short transfer, error, or dequeued). | 371 | * terminates early (short transfer, error, or dequeued). |
370 | */ | 372 | */ |
371 | static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) | 373 | static void uhci_fixup_toggles(struct uhci_hcd *uhci, struct uhci_qh *qh, |
374 | int skip_first) | ||
372 | { | 375 | { |
373 | struct urb_priv *urbp = NULL; | 376 | struct urb_priv *urbp = NULL; |
374 | struct uhci_td *td; | 377 | struct uhci_td *td; |
@@ -382,7 +385,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) | |||
382 | 385 | ||
383 | /* When starting with the first URB, if the QH element pointer is | 386 | /* When starting with the first URB, if the QH element pointer is |
384 | * still valid then we know the URB's toggles are okay. */ | 387 | * still valid then we know the URB's toggles are okay. */ |
385 | else if (qh_element(qh) != UHCI_PTR_TERM) | 388 | else if (qh_element(qh) != UHCI_PTR_TERM(uhci)) |
386 | toggle = 2; | 389 | toggle = 2; |
387 | 390 | ||
388 | /* Fix up the toggle for the URBs in the queue. Normally this | 391 | /* Fix up the toggle for the URBs in the queue. Normally this |
@@ -394,15 +397,15 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) | |||
394 | /* If the first TD has the right toggle value, we don't | 397 | /* If the first TD has the right toggle value, we don't |
395 | * need to change any toggles in this URB */ | 398 | * need to change any toggles in this URB */ |
396 | td = list_entry(urbp->td_list.next, struct uhci_td, list); | 399 | td = list_entry(urbp->td_list.next, struct uhci_td, list); |
397 | if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) { | 400 | if (toggle > 1 || uhci_toggle(td_token(uhci, td)) == toggle) { |
398 | td = list_entry(urbp->td_list.prev, struct uhci_td, | 401 | td = list_entry(urbp->td_list.prev, struct uhci_td, |
399 | list); | 402 | list); |
400 | toggle = uhci_toggle(td_token(td)) ^ 1; | 403 | toggle = uhci_toggle(td_token(uhci, td)) ^ 1; |
401 | 404 | ||
402 | /* Otherwise all the toggles in the URB have to be switched */ | 405 | /* Otherwise all the toggles in the URB have to be switched */ |
403 | } else { | 406 | } else { |
404 | list_for_each_entry(td, &urbp->td_list, list) { | 407 | list_for_each_entry(td, &urbp->td_list, list) { |
405 | td->token ^= cpu_to_le32( | 408 | td->token ^= cpu_to_hc32(uhci, |
406 | TD_TOKEN_TOGGLE); | 409 | TD_TOKEN_TOGGLE); |
407 | toggle ^= 1; | 410 | toggle ^= 1; |
408 | } | 411 | } |
@@ -439,7 +442,7 @@ static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
439 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); | 442 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); |
440 | qh->link = pqh->link; | 443 | qh->link = pqh->link; |
441 | wmb(); | 444 | wmb(); |
442 | pqh->link = LINK_TO_QH(qh); | 445 | pqh->link = LINK_TO_QH(uhci, qh); |
443 | } | 446 | } |
444 | 447 | ||
445 | /* | 448 | /* |
@@ -449,7 +452,7 @@ static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
449 | static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh) | 452 | static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh) |
450 | { | 453 | { |
451 | struct uhci_qh *pqh; | 454 | struct uhci_qh *pqh; |
452 | __le32 link_to_new_qh; | 455 | __hc32 link_to_new_qh; |
453 | 456 | ||
454 | /* Find the predecessor QH for our new one and insert it in the list. | 457 | /* Find the predecessor QH for our new one and insert it in the list. |
455 | * The list of QHs is expected to be short, so linear search won't | 458 | * The list of QHs is expected to be short, so linear search won't |
@@ -463,7 +466,7 @@ static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
463 | /* Link it into the schedule */ | 466 | /* Link it into the schedule */ |
464 | qh->link = pqh->link; | 467 | qh->link = pqh->link; |
465 | wmb(); | 468 | wmb(); |
466 | link_to_new_qh = LINK_TO_QH(qh); | 469 | link_to_new_qh = LINK_TO_QH(uhci, qh); |
467 | pqh->link = link_to_new_qh; | 470 | pqh->link = link_to_new_qh; |
468 | 471 | ||
469 | /* If this is now the first FSBR QH, link the terminating skeleton | 472 | /* If this is now the first FSBR QH, link the terminating skeleton |
@@ -481,13 +484,13 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
481 | 484 | ||
482 | /* Set the element pointer if it isn't set already. | 485 | /* Set the element pointer if it isn't set already. |
483 | * This isn't needed for Isochronous queues, but it doesn't hurt. */ | 486 | * This isn't needed for Isochronous queues, but it doesn't hurt. */ |
484 | if (qh_element(qh) == UHCI_PTR_TERM) { | 487 | if (qh_element(qh) == UHCI_PTR_TERM(uhci)) { |
485 | struct urb_priv *urbp = list_entry(qh->queue.next, | 488 | struct urb_priv *urbp = list_entry(qh->queue.next, |
486 | struct urb_priv, node); | 489 | struct urb_priv, node); |
487 | struct uhci_td *td = list_entry(urbp->td_list.next, | 490 | struct uhci_td *td = list_entry(urbp->td_list.next, |
488 | struct uhci_td, list); | 491 | struct uhci_td, list); |
489 | 492 | ||
490 | qh->element = LINK_TO_TD(td); | 493 | qh->element = LINK_TO_TD(uhci, td); |
491 | } | 494 | } |
492 | 495 | ||
493 | /* Treat the queue as if it has just advanced */ | 496 | /* Treat the queue as if it has just advanced */ |
@@ -531,7 +534,7 @@ static void unlink_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
531 | static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh) | 534 | static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh) |
532 | { | 535 | { |
533 | struct uhci_qh *pqh; | 536 | struct uhci_qh *pqh; |
534 | __le32 link_to_next_qh = qh->link; | 537 | __hc32 link_to_next_qh = qh->link; |
535 | 538 | ||
536 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); | 539 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); |
537 | pqh->link = link_to_next_qh; | 540 | pqh->link = link_to_next_qh; |
@@ -728,7 +731,7 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, | |||
728 | 731 | ||
729 | urbp->urb = urb; | 732 | urbp->urb = urb; |
730 | urb->hcpriv = urbp; | 733 | urb->hcpriv = urbp; |
731 | 734 | ||
732 | INIT_LIST_HEAD(&urbp->node); | 735 | INIT_LIST_HEAD(&urbp->node); |
733 | INIT_LIST_HEAD(&urbp->td_list); | 736 | INIT_LIST_HEAD(&urbp->td_list); |
734 | 737 | ||
@@ -755,8 +758,8 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, | |||
755 | /* | 758 | /* |
756 | * Map status to standard result codes | 759 | * Map status to standard result codes |
757 | * | 760 | * |
758 | * <status> is (td_status(td) & 0xF60000), a.k.a. | 761 | * <status> is (td_status(uhci, td) & 0xF60000), a.k.a. |
759 | * uhci_status_bits(td_status(td)). | 762 | * uhci_status_bits(td_status(uhci, td)). |
760 | * Note: <status> does not include the TD_CTRL_NAK bit. | 763 | * Note: <status> does not include the TD_CTRL_NAK bit. |
761 | * <dir_out> is True for output TDs and False for input TDs. | 764 | * <dir_out> is True for output TDs and False for input TDs. |
762 | */ | 765 | */ |
@@ -792,7 +795,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
792 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); | 795 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); |
793 | int len = urb->transfer_buffer_length; | 796 | int len = urb->transfer_buffer_length; |
794 | dma_addr_t data = urb->transfer_dma; | 797 | dma_addr_t data = urb->transfer_dma; |
795 | __le32 *plink; | 798 | __hc32 *plink; |
796 | struct urb_priv *urbp = urb->hcpriv; | 799 | struct urb_priv *urbp = urb->hcpriv; |
797 | int skel; | 800 | int skel; |
798 | 801 | ||
@@ -809,7 +812,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
809 | */ | 812 | */ |
810 | td = qh->dummy_td; | 813 | td = qh->dummy_td; |
811 | uhci_add_td_to_urbp(td, urbp); | 814 | uhci_add_td_to_urbp(td, urbp); |
812 | uhci_fill_td(td, status, destination | uhci_explen(8), | 815 | uhci_fill_td(uhci, td, status, destination | uhci_explen(8), |
813 | urb->setup_dma); | 816 | urb->setup_dma); |
814 | plink = &td->link; | 817 | plink = &td->link; |
815 | status |= TD_CTRL_ACTIVE; | 818 | status |= TD_CTRL_ACTIVE; |
@@ -842,14 +845,14 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
842 | td = uhci_alloc_td(uhci); | 845 | td = uhci_alloc_td(uhci); |
843 | if (!td) | 846 | if (!td) |
844 | goto nomem; | 847 | goto nomem; |
845 | *plink = LINK_TO_TD(td); | 848 | *plink = LINK_TO_TD(uhci, td); |
846 | 849 | ||
847 | /* Alternate Data0/1 (start with Data1) */ | 850 | /* Alternate Data0/1 (start with Data1) */ |
848 | destination ^= TD_TOKEN_TOGGLE; | 851 | destination ^= TD_TOKEN_TOGGLE; |
849 | 852 | ||
850 | uhci_add_td_to_urbp(td, urbp); | 853 | uhci_add_td_to_urbp(td, urbp); |
851 | uhci_fill_td(td, status, destination | uhci_explen(pktsze), | 854 | uhci_fill_td(uhci, td, status, |
852 | data); | 855 | destination | uhci_explen(pktsze), data); |
853 | plink = &td->link; | 856 | plink = &td->link; |
854 | 857 | ||
855 | data += pktsze; | 858 | data += pktsze; |
@@ -857,19 +860,19 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
857 | } | 860 | } |
858 | 861 | ||
859 | /* | 862 | /* |
860 | * Build the final TD for control status | 863 | * Build the final TD for control status |
861 | */ | 864 | */ |
862 | td = uhci_alloc_td(uhci); | 865 | td = uhci_alloc_td(uhci); |
863 | if (!td) | 866 | if (!td) |
864 | goto nomem; | 867 | goto nomem; |
865 | *plink = LINK_TO_TD(td); | 868 | *plink = LINK_TO_TD(uhci, td); |
866 | 869 | ||
867 | /* Change direction for the status transaction */ | 870 | /* Change direction for the status transaction */ |
868 | destination ^= (USB_PID_IN ^ USB_PID_OUT); | 871 | destination ^= (USB_PID_IN ^ USB_PID_OUT); |
869 | destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ | 872 | destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ |
870 | 873 | ||
871 | uhci_add_td_to_urbp(td, urbp); | 874 | uhci_add_td_to_urbp(td, urbp); |
872 | uhci_fill_td(td, status | TD_CTRL_IOC, | 875 | uhci_fill_td(uhci, td, status | TD_CTRL_IOC, |
873 | destination | uhci_explen(0), 0); | 876 | destination | uhci_explen(0), 0); |
874 | plink = &td->link; | 877 | plink = &td->link; |
875 | 878 | ||
@@ -879,11 +882,11 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
879 | td = uhci_alloc_td(uhci); | 882 | td = uhci_alloc_td(uhci); |
880 | if (!td) | 883 | if (!td) |
881 | goto nomem; | 884 | goto nomem; |
882 | *plink = LINK_TO_TD(td); | 885 | *plink = LINK_TO_TD(uhci, td); |
883 | 886 | ||
884 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); | 887 | uhci_fill_td(uhci, td, 0, USB_PID_OUT | uhci_explen(0), 0); |
885 | wmb(); | 888 | wmb(); |
886 | qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE); | 889 | qh->dummy_td->status |= cpu_to_hc32(uhci, TD_CTRL_ACTIVE); |
887 | qh->dummy_td = td; | 890 | qh->dummy_td = td; |
888 | 891 | ||
889 | /* Low-speed transfers get a different queue, and won't hog the bus. | 892 | /* Low-speed transfers get a different queue, and won't hog the bus. |
@@ -917,10 +920,13 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
917 | unsigned long destination, status; | 920 | unsigned long destination, status; |
918 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); | 921 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); |
919 | int len = urb->transfer_buffer_length; | 922 | int len = urb->transfer_buffer_length; |
920 | dma_addr_t data = urb->transfer_dma; | 923 | int this_sg_len; |
921 | __le32 *plink; | 924 | dma_addr_t data; |
925 | __hc32 *plink; | ||
922 | struct urb_priv *urbp = urb->hcpriv; | 926 | struct urb_priv *urbp = urb->hcpriv; |
923 | unsigned int toggle; | 927 | unsigned int toggle; |
928 | struct scatterlist *sg; | ||
929 | int i; | ||
924 | 930 | ||
925 | if (len < 0) | 931 | if (len < 0) |
926 | return -EINVAL; | 932 | return -EINVAL; |
@@ -937,12 +943,26 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
937 | if (usb_pipein(urb->pipe)) | 943 | if (usb_pipein(urb->pipe)) |
938 | status |= TD_CTRL_SPD; | 944 | status |= TD_CTRL_SPD; |
939 | 945 | ||
946 | i = urb->num_sgs; | ||
947 | if (len > 0 && i > 0) { | ||
948 | sg = urb->sg; | ||
949 | data = sg_dma_address(sg); | ||
950 | |||
951 | /* urb->transfer_buffer_length may be smaller than the | ||
952 | * size of the scatterlist (or vice versa) | ||
953 | */ | ||
954 | this_sg_len = min_t(int, sg_dma_len(sg), len); | ||
955 | } else { | ||
956 | sg = NULL; | ||
957 | data = urb->transfer_dma; | ||
958 | this_sg_len = len; | ||
959 | } | ||
940 | /* | 960 | /* |
941 | * Build the DATA TDs | 961 | * Build the DATA TDs |
942 | */ | 962 | */ |
943 | plink = NULL; | 963 | plink = NULL; |
944 | td = qh->dummy_td; | 964 | td = qh->dummy_td; |
945 | do { /* Allow zero length packets */ | 965 | for (;;) { /* Allow zero length packets */ |
946 | int pktsze = maxsze; | 966 | int pktsze = maxsze; |
947 | 967 | ||
948 | if (len <= pktsze) { /* The last packet */ | 968 | if (len <= pktsze) { /* The last packet */ |
@@ -955,20 +975,28 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
955 | td = uhci_alloc_td(uhci); | 975 | td = uhci_alloc_td(uhci); |
956 | if (!td) | 976 | if (!td) |
957 | goto nomem; | 977 | goto nomem; |
958 | *plink = LINK_TO_TD(td); | 978 | *plink = LINK_TO_TD(uhci, td); |
959 | } | 979 | } |
960 | uhci_add_td_to_urbp(td, urbp); | 980 | uhci_add_td_to_urbp(td, urbp); |
961 | uhci_fill_td(td, status, | 981 | uhci_fill_td(uhci, td, status, |
962 | destination | uhci_explen(pktsze) | | 982 | destination | uhci_explen(pktsze) | |
963 | (toggle << TD_TOKEN_TOGGLE_SHIFT), | 983 | (toggle << TD_TOKEN_TOGGLE_SHIFT), |
964 | data); | 984 | data); |
965 | plink = &td->link; | 985 | plink = &td->link; |
966 | status |= TD_CTRL_ACTIVE; | 986 | status |= TD_CTRL_ACTIVE; |
967 | 987 | ||
988 | toggle ^= 1; | ||
968 | data += pktsze; | 989 | data += pktsze; |
990 | this_sg_len -= pktsze; | ||
969 | len -= maxsze; | 991 | len -= maxsze; |
970 | toggle ^= 1; | 992 | if (this_sg_len <= 0) { |
971 | } while (len > 0); | 993 | if (--i <= 0 || len <= 0) |
994 | break; | ||
995 | sg = sg_next(sg); | ||
996 | data = sg_dma_address(sg); | ||
997 | this_sg_len = min_t(int, sg_dma_len(sg), len); | ||
998 | } | ||
999 | } | ||
972 | 1000 | ||
973 | /* | 1001 | /* |
974 | * URB_ZERO_PACKET means adding a 0-length packet, if direction | 1002 | * URB_ZERO_PACKET means adding a 0-length packet, if direction |
@@ -983,10 +1011,10 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
983 | td = uhci_alloc_td(uhci); | 1011 | td = uhci_alloc_td(uhci); |
984 | if (!td) | 1012 | if (!td) |
985 | goto nomem; | 1013 | goto nomem; |
986 | *plink = LINK_TO_TD(td); | 1014 | *plink = LINK_TO_TD(uhci, td); |
987 | 1015 | ||
988 | uhci_add_td_to_urbp(td, urbp); | 1016 | uhci_add_td_to_urbp(td, urbp); |
989 | uhci_fill_td(td, status, | 1017 | uhci_fill_td(uhci, td, status, |
990 | destination | uhci_explen(0) | | 1018 | destination | uhci_explen(0) | |
991 | (toggle << TD_TOKEN_TOGGLE_SHIFT), | 1019 | (toggle << TD_TOKEN_TOGGLE_SHIFT), |
992 | data); | 1020 | data); |
@@ -1001,7 +1029,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
1001 | * fast side but not enough to justify delaying an interrupt | 1029 | * fast side but not enough to justify delaying an interrupt |
1002 | * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT | 1030 | * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT |
1003 | * flag setting. */ | 1031 | * flag setting. */ |
1004 | td->status |= cpu_to_le32(TD_CTRL_IOC); | 1032 | td->status |= cpu_to_hc32(uhci, TD_CTRL_IOC); |
1005 | 1033 | ||
1006 | /* | 1034 | /* |
1007 | * Build the new dummy TD and activate the old one | 1035 | * Build the new dummy TD and activate the old one |
@@ -1009,11 +1037,11 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
1009 | td = uhci_alloc_td(uhci); | 1037 | td = uhci_alloc_td(uhci); |
1010 | if (!td) | 1038 | if (!td) |
1011 | goto nomem; | 1039 | goto nomem; |
1012 | *plink = LINK_TO_TD(td); | 1040 | *plink = LINK_TO_TD(uhci, td); |
1013 | 1041 | ||
1014 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); | 1042 | uhci_fill_td(uhci, td, 0, USB_PID_OUT | uhci_explen(0), 0); |
1015 | wmb(); | 1043 | wmb(); |
1016 | qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE); | 1044 | qh->dummy_td->status |= cpu_to_hc32(uhci, TD_CTRL_ACTIVE); |
1017 | qh->dummy_td = td; | 1045 | qh->dummy_td = td; |
1018 | 1046 | ||
1019 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 1047 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
@@ -1106,7 +1134,7 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, | |||
1106 | * the queue at the status stage transaction, which is | 1134 | * the queue at the status stage transaction, which is |
1107 | * the last TD. */ | 1135 | * the last TD. */ |
1108 | WARN_ON(list_empty(&urbp->td_list)); | 1136 | WARN_ON(list_empty(&urbp->td_list)); |
1109 | qh->element = LINK_TO_TD(td); | 1137 | qh->element = LINK_TO_TD(uhci, td); |
1110 | tmp = td->list.prev; | 1138 | tmp = td->list.prev; |
1111 | ret = -EINPROGRESS; | 1139 | ret = -EINPROGRESS; |
1112 | 1140 | ||
@@ -1115,8 +1143,9 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, | |||
1115 | /* When a bulk/interrupt transfer is short, we have to | 1143 | /* When a bulk/interrupt transfer is short, we have to |
1116 | * fix up the toggles of the following URBs on the queue | 1144 | * fix up the toggles of the following URBs on the queue |
1117 | * before restarting the queue at the next URB. */ | 1145 | * before restarting the queue at the next URB. */ |
1118 | qh->initial_toggle = uhci_toggle(td_token(qh->post_td)) ^ 1; | 1146 | qh->initial_toggle = |
1119 | uhci_fixup_toggles(qh, 1); | 1147 | uhci_toggle(td_token(uhci, qh->post_td)) ^ 1; |
1148 | uhci_fixup_toggles(uhci, qh, 1); | ||
1120 | 1149 | ||
1121 | if (list_empty(&urbp->td_list)) | 1150 | if (list_empty(&urbp->td_list)) |
1122 | td = qh->post_td; | 1151 | td = qh->post_td; |
@@ -1151,7 +1180,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1151 | unsigned int ctrlstat; | 1180 | unsigned int ctrlstat; |
1152 | int len; | 1181 | int len; |
1153 | 1182 | ||
1154 | ctrlstat = td_status(td); | 1183 | ctrlstat = td_status(uhci, td); |
1155 | status = uhci_status_bits(ctrlstat); | 1184 | status = uhci_status_bits(ctrlstat); |
1156 | if (status & TD_CTRL_ACTIVE) | 1185 | if (status & TD_CTRL_ACTIVE) |
1157 | return -EINPROGRESS; | 1186 | return -EINPROGRESS; |
@@ -1161,7 +1190,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1161 | 1190 | ||
1162 | if (status) { | 1191 | if (status) { |
1163 | ret = uhci_map_status(status, | 1192 | ret = uhci_map_status(status, |
1164 | uhci_packetout(td_token(td))); | 1193 | uhci_packetout(td_token(uhci, td))); |
1165 | if ((debug == 1 && ret != -EPIPE) || debug > 1) { | 1194 | if ((debug == 1 && ret != -EPIPE) || debug > 1) { |
1166 | /* Some debugging code */ | 1195 | /* Some debugging code */ |
1167 | dev_dbg(&urb->dev->dev, | 1196 | dev_dbg(&urb->dev->dev, |
@@ -1177,7 +1206,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1177 | } | 1206 | } |
1178 | 1207 | ||
1179 | /* Did we receive a short packet? */ | 1208 | /* Did we receive a short packet? */ |
1180 | } else if (len < uhci_expected_length(td_token(td))) { | 1209 | } else if (len < uhci_expected_length(td_token(uhci, td))) { |
1181 | 1210 | ||
1182 | /* For control transfers, go to the status TD if | 1211 | /* For control transfers, go to the status TD if |
1183 | * this isn't already the last data TD */ | 1212 | * this isn't already the last data TD */ |
@@ -1209,10 +1238,10 @@ err: | |||
1209 | if (ret < 0) { | 1238 | if (ret < 0) { |
1210 | /* Note that the queue has stopped and save | 1239 | /* Note that the queue has stopped and save |
1211 | * the next toggle value */ | 1240 | * the next toggle value */ |
1212 | qh->element = UHCI_PTR_TERM; | 1241 | qh->element = UHCI_PTR_TERM(uhci); |
1213 | qh->is_stopped = 1; | 1242 | qh->is_stopped = 1; |
1214 | qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL); | 1243 | qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL); |
1215 | qh->initial_toggle = uhci_toggle(td_token(td)) ^ | 1244 | qh->initial_toggle = uhci_toggle(td_token(uhci, td)) ^ |
1216 | (ret == -EREMOTEIO); | 1245 | (ret == -EREMOTEIO); |
1217 | 1246 | ||
1218 | } else /* Short packet received */ | 1247 | } else /* Short packet received */ |
@@ -1308,14 +1337,14 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1308 | return -ENOMEM; | 1337 | return -ENOMEM; |
1309 | 1338 | ||
1310 | uhci_add_td_to_urbp(td, urbp); | 1339 | uhci_add_td_to_urbp(td, urbp); |
1311 | uhci_fill_td(td, status, destination | | 1340 | uhci_fill_td(uhci, td, status, destination | |
1312 | uhci_explen(urb->iso_frame_desc[i].length), | 1341 | uhci_explen(urb->iso_frame_desc[i].length), |
1313 | urb->transfer_dma + | 1342 | urb->transfer_dma + |
1314 | urb->iso_frame_desc[i].offset); | 1343 | urb->iso_frame_desc[i].offset); |
1315 | } | 1344 | } |
1316 | 1345 | ||
1317 | /* Set the interrupt-on-completion flag on the last packet. */ | 1346 | /* Set the interrupt-on-completion flag on the last packet. */ |
1318 | td->status |= cpu_to_le32(TD_CTRL_IOC); | 1347 | td->status |= cpu_to_hc32(uhci, TD_CTRL_IOC); |
1319 | 1348 | ||
1320 | /* Add the TDs to the frame list */ | 1349 | /* Add the TDs to the frame list */ |
1321 | frame = urb->start_frame; | 1350 | frame = urb->start_frame; |
@@ -1351,7 +1380,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1351 | 1380 | ||
1352 | uhci_remove_tds_from_frame(uhci, qh->iso_frame); | 1381 | uhci_remove_tds_from_frame(uhci, qh->iso_frame); |
1353 | 1382 | ||
1354 | ctrlstat = td_status(td); | 1383 | ctrlstat = td_status(uhci, td); |
1355 | if (ctrlstat & TD_CTRL_ACTIVE) { | 1384 | if (ctrlstat & TD_CTRL_ACTIVE) { |
1356 | status = -EXDEV; /* TD was added too late? */ | 1385 | status = -EXDEV; /* TD was added too late? */ |
1357 | } else { | 1386 | } else { |
@@ -1602,7 +1631,7 @@ restart: | |||
1602 | * queue, the QH can now be re-activated. */ | 1631 | * queue, the QH can now be re-activated. */ |
1603 | if (!list_empty(&qh->queue)) { | 1632 | if (!list_empty(&qh->queue)) { |
1604 | if (qh->needs_fixup) | 1633 | if (qh->needs_fixup) |
1605 | uhci_fixup_toggles(qh, 0); | 1634 | uhci_fixup_toggles(uhci, qh, 0); |
1606 | 1635 | ||
1607 | /* If the first URB on the queue wants FSBR but its time | 1636 | /* If the first URB on the queue wants FSBR but its time |
1608 | * limit has expired, set the next TD to interrupt on | 1637 | * limit has expired, set the next TD to interrupt on |
@@ -1612,7 +1641,7 @@ restart: | |||
1612 | struct uhci_td *td = list_entry(urbp->td_list.next, | 1641 | struct uhci_td *td = list_entry(urbp->td_list.next, |
1613 | struct uhci_td, list); | 1642 | struct uhci_td, list); |
1614 | 1643 | ||
1615 | td->status |= __cpu_to_le32(TD_CTRL_IOC); | 1644 | td->status |= cpu_to_hc32(uhci, TD_CTRL_IOC); |
1616 | } | 1645 | } |
1617 | 1646 | ||
1618 | uhci_activate_qh(uhci, qh); | 1647 | uhci_activate_qh(uhci, qh); |
@@ -1659,7 +1688,7 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1659 | } else { | 1688 | } else { |
1660 | urbp = list_entry(qh->queue.next, struct urb_priv, node); | 1689 | urbp = list_entry(qh->queue.next, struct urb_priv, node); |
1661 | td = list_entry(urbp->td_list.next, struct uhci_td, list); | 1690 | td = list_entry(urbp->td_list.next, struct uhci_td, list); |
1662 | status = td_status(td); | 1691 | status = td_status(uhci, td); |
1663 | if (!(status & TD_CTRL_ACTIVE)) { | 1692 | if (!(status & TD_CTRL_ACTIVE)) { |
1664 | 1693 | ||
1665 | /* We're okay, the queue has advanced */ | 1694 | /* We're okay, the queue has advanced */ |
@@ -1677,7 +1706,8 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1677 | if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { | 1706 | if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { |
1678 | 1707 | ||
1679 | /* Detect the Intel bug and work around it */ | 1708 | /* Detect the Intel bug and work around it */ |
1680 | if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) { | 1709 | if (qh->post_td && qh_element(qh) == |
1710 | LINK_TO_TD(uhci, qh->post_td)) { | ||
1681 | qh->element = qh->post_td->link; | 1711 | qh->element = qh->post_td->link; |
1682 | qh->advance_jiffies = jiffies; | 1712 | qh->advance_jiffies = jiffies; |
1683 | ret = 1; | 1713 | ret = 1; |