diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-02-19 15:51:51 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-23 18:03:45 -0500 |
commit | 28b9325e6ae45ffb5e99fedcafe00f25fcaacf06 (patch) | |
tree | 91391a8e2d11acc50adc5b7c631b2695bee9e453 /drivers/usb/host | |
parent | d0374f4f9c35cdfbee0ade72d06732613b4e6628 (diff) |
UHCI: Add macros for computing DMA values
This patch (as855) adds some convenience macros to uhci-hcd, to help
simplify the code for computing hardware DMA pointers.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/uhci-debug.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.c | 24 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.h | 8 | ||||
-rw-r--r-- | drivers/usb/host/uhci-q.c | 30 |
4 files changed, 34 insertions, 37 deletions
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 5d6c06bc4524..a0677133577b 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -196,7 +196,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
196 | struct uhci_td *td = list_entry(urbp->td_list.next, | 196 | struct uhci_td *td = list_entry(urbp->td_list.next, |
197 | struct uhci_td, list); | 197 | struct uhci_td, list); |
198 | 198 | ||
199 | if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS)) | 199 | if (element != LINK_TO_TD(td)) |
200 | out += sprintf(out, "%*s Element != First TD\n", | 200 | out += sprintf(out, "%*s Element != First TD\n", |
201 | space, ""); | 201 | space, ""); |
202 | i = nurbs = 0; | 202 | i = nurbs = 0; |
@@ -393,7 +393,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
393 | do { | 393 | do { |
394 | td = list_entry(tmp, struct uhci_td, fl_list); | 394 | td = list_entry(tmp, struct uhci_td, fl_list); |
395 | tmp = tmp->next; | 395 | tmp = tmp->next; |
396 | if (cpu_to_le32(td->dma_handle) != link) { | 396 | if (link != LINK_TO_TD(td)) { |
397 | if (nframes > 0) | 397 | if (nframes > 0) |
398 | out += sprintf(out, " link does " | 398 | out += sprintf(out, " link does " |
399 | "not match list entry!\n"); | 399 | "not match list entry!\n"); |
@@ -440,7 +440,7 @@ check_link: | |||
440 | if (qh->link != UHCI_PTR_TERM) | 440 | if (qh->link != UHCI_PTR_TERM) |
441 | out += sprintf(out, " bandwidth reclamation on!\n"); | 441 | out += sprintf(out, " bandwidth reclamation on!\n"); |
442 | 442 | ||
443 | if (qh_element(qh) != cpu_to_le32(uhci->term_td->dma_handle)) | 443 | if (qh_element(qh) != LINK_TO_TD(uhci->term_td)) |
444 | out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); | 444 | out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); |
445 | 445 | ||
446 | continue; | 446 | continue; |
@@ -461,8 +461,7 @@ check_link: | |||
461 | out += sprintf(out, " Skipped %d QHs\n", cnt); | 461 | out += sprintf(out, " Skipped %d QHs\n", cnt); |
462 | 462 | ||
463 | if (i > 1 && i < UHCI_NUM_SKELQH - 1) { | 463 | if (i > 1 && i < UHCI_NUM_SKELQH - 1) { |
464 | if (qh->link != | 464 | if (qh->link != LINK_TO_QH(uhci->skelqh[j])) |
465 | (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH)) | ||
466 | out += sprintf(out, " last QH not linked to next skeleton!\n"); | 465 | out += sprintf(out, " last QH not linked to next skeleton!\n"); |
467 | } | 466 | } |
468 | } | 467 | } |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index ded4df30a631..1f0833ab294a 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -116,7 +116,7 @@ static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) | |||
116 | skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); | 116 | skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); |
117 | if (skelnum <= 1) | 117 | if (skelnum <= 1) |
118 | skelnum = 9; | 118 | skelnum = 9; |
119 | return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle); | 119 | return LINK_TO_QH(uhci->skelqh[skelnum]); |
120 | } | 120 | } |
121 | 121 | ||
122 | #include "uhci-debug.c" | 122 | #include "uhci-debug.c" |
@@ -635,25 +635,21 @@ static int uhci_start(struct usb_hcd *hcd) | |||
635 | uhci->skel_int16_qh->link = | 635 | uhci->skel_int16_qh->link = |
636 | uhci->skel_int8_qh->link = | 636 | uhci->skel_int8_qh->link = |
637 | uhci->skel_int4_qh->link = | 637 | uhci->skel_int4_qh->link = |
638 | uhci->skel_int2_qh->link = UHCI_PTR_QH | | 638 | uhci->skel_int2_qh->link = LINK_TO_QH( |
639 | cpu_to_le32(uhci->skel_int1_qh->dma_handle); | 639 | uhci->skel_int1_qh); |
640 | 640 | ||
641 | uhci->skel_int1_qh->link = UHCI_PTR_QH | | 641 | uhci->skel_int1_qh->link = LINK_TO_QH(uhci->skel_ls_control_qh); |
642 | cpu_to_le32(uhci->skel_ls_control_qh->dma_handle); | 642 | uhci->skel_ls_control_qh->link = LINK_TO_QH(uhci->skel_fs_control_qh); |
643 | uhci->skel_ls_control_qh->link = UHCI_PTR_QH | | 643 | uhci->skel_fs_control_qh->link = LINK_TO_QH(uhci->skel_bulk_qh); |
644 | cpu_to_le32(uhci->skel_fs_control_qh->dma_handle); | 644 | uhci->skel_bulk_qh->link = LINK_TO_QH(uhci->skel_term_qh); |
645 | uhci->skel_fs_control_qh->link = UHCI_PTR_QH | | ||
646 | cpu_to_le32(uhci->skel_bulk_qh->dma_handle); | ||
647 | uhci->skel_bulk_qh->link = UHCI_PTR_QH | | ||
648 | cpu_to_le32(uhci->skel_term_qh->dma_handle); | ||
649 | 645 | ||
650 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ | 646 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ |
651 | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | | 647 | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | |
652 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); | 648 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); |
653 | uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle); | 649 | uhci->term_td->link = LINK_TO_TD(uhci->term_td); |
654 | 650 | ||
655 | uhci->skel_term_qh->link = UHCI_PTR_TERM; | 651 | uhci->skel_term_qh->link = UHCI_PTR_TERM; |
656 | uhci->skel_term_qh->element = cpu_to_le32(uhci->term_td->dma_handle); | 652 | uhci->skel_term_qh->element = LINK_TO_TD(uhci->term_td); |
657 | 653 | ||
658 | /* | 654 | /* |
659 | * Fill the frame list: make all entries point to the proper | 655 | * Fill the frame list: make all entries point to the proper |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 74469b5bcb61..a8c256b44d8e 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -129,6 +129,8 @@ struct uhci_qh { | |||
129 | __le32 element; /* Queue element (TD) pointer */ | 129 | __le32 element; /* Queue element (TD) pointer */ |
130 | 130 | ||
131 | /* Software fields */ | 131 | /* Software fields */ |
132 | dma_addr_t dma_handle; | ||
133 | |||
132 | struct list_head node; /* Node in the list of QHs */ | 134 | struct list_head node; /* Node in the list of QHs */ |
133 | struct usb_host_endpoint *hep; /* Endpoint information */ | 135 | struct usb_host_endpoint *hep; /* Endpoint information */ |
134 | struct usb_device *udev; | 136 | struct usb_device *udev; |
@@ -150,8 +152,6 @@ struct uhci_qh { | |||
150 | int state; /* QH_STATE_xxx; see above */ | 152 | int state; /* QH_STATE_xxx; see above */ |
151 | int type; /* Queue type (control, bulk, etc) */ | 153 | int type; /* Queue type (control, bulk, etc) */ |
152 | 154 | ||
153 | dma_addr_t dma_handle; | ||
154 | |||
155 | unsigned int initial_toggle:1; /* Endpoint's current toggle value */ | 155 | unsigned int initial_toggle:1; /* Endpoint's current toggle value */ |
156 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ | 156 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ |
157 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ | 157 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ |
@@ -171,6 +171,8 @@ static inline __le32 qh_element(struct uhci_qh *qh) { | |||
171 | return element; | 171 | return element; |
172 | } | 172 | } |
173 | 173 | ||
174 | #define LINK_TO_QH(qh) (UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle)) | ||
175 | |||
174 | 176 | ||
175 | /* | 177 | /* |
176 | * Transfer Descriptors | 178 | * Transfer Descriptors |
@@ -264,6 +266,8 @@ static inline u32 td_status(struct uhci_td *td) { | |||
264 | return le32_to_cpu(status); | 266 | return le32_to_cpu(status); |
265 | } | 267 | } |
266 | 268 | ||
269 | #define LINK_TO_TD(td) (cpu_to_le32((td)->dma_handle)) | ||
270 | |||
267 | 271 | ||
268 | /* | 272 | /* |
269 | * Skeleton Queue Headers | 273 | * Skeleton Queue Headers |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 68e66b33e726..a0c6bf6128a3 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -46,8 +46,7 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) | |||
46 | static void uhci_fsbr_on(struct uhci_hcd *uhci) | 46 | static void uhci_fsbr_on(struct uhci_hcd *uhci) |
47 | { | 47 | { |
48 | uhci->fsbr_is_on = 1; | 48 | uhci->fsbr_is_on = 1; |
49 | uhci->skel_term_qh->link = cpu_to_le32( | 49 | uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_fs_control_qh); |
50 | uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; | ||
51 | } | 50 | } |
52 | 51 | ||
53 | static void uhci_fsbr_off(struct uhci_hcd *uhci) | 52 | static void uhci_fsbr_off(struct uhci_hcd *uhci) |
@@ -158,11 +157,11 @@ static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, | |||
158 | 157 | ||
159 | td->link = ltd->link; | 158 | td->link = ltd->link; |
160 | wmb(); | 159 | wmb(); |
161 | ltd->link = cpu_to_le32(td->dma_handle); | 160 | ltd->link = LINK_TO_TD(td); |
162 | } else { | 161 | } else { |
163 | td->link = uhci->frame[framenum]; | 162 | td->link = uhci->frame[framenum]; |
164 | wmb(); | 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; | 165 | uhci->frame_cpu[framenum] = td; |
167 | } | 166 | } |
168 | } | 167 | } |
@@ -184,7 +183,7 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, | |||
184 | struct uhci_td *ntd; | 183 | struct uhci_td *ntd; |
185 | 184 | ||
186 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); | 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; | 187 | uhci->frame_cpu[td->frame] = ntd; |
189 | } | 188 | } |
190 | } else { | 189 | } else { |
@@ -421,7 +420,7 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
421 | struct uhci_td *td = list_entry(urbp->td_list.next, | 420 | struct uhci_td *td = list_entry(urbp->td_list.next, |
422 | struct uhci_td, list); | 421 | struct uhci_td, list); |
423 | 422 | ||
424 | qh->element = cpu_to_le32(td->dma_handle); | 423 | qh->element = LINK_TO_TD(td); |
425 | } | 424 | } |
426 | 425 | ||
427 | /* Treat the queue as if it has just advanced */ | 426 | /* Treat the queue as if it has just advanced */ |
@@ -443,7 +442,7 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
443 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); | 442 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); |
444 | qh->link = pqh->link; | 443 | qh->link = pqh->link; |
445 | wmb(); | 444 | wmb(); |
446 | pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle); | 445 | pqh->link = LINK_TO_QH(qh); |
447 | } | 446 | } |
448 | 447 | ||
449 | /* | 448 | /* |
@@ -737,7 +736,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
737 | td = uhci_alloc_td(uhci); | 736 | td = uhci_alloc_td(uhci); |
738 | if (!td) | 737 | if (!td) |
739 | goto nomem; | 738 | goto nomem; |
740 | *plink = cpu_to_le32(td->dma_handle); | 739 | *plink = LINK_TO_TD(td); |
741 | 740 | ||
742 | /* Alternate Data0/1 (start with Data1) */ | 741 | /* Alternate Data0/1 (start with Data1) */ |
743 | destination ^= TD_TOKEN_TOGGLE; | 742 | destination ^= TD_TOKEN_TOGGLE; |
@@ -757,7 +756,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
757 | td = uhci_alloc_td(uhci); | 756 | td = uhci_alloc_td(uhci); |
758 | if (!td) | 757 | if (!td) |
759 | goto nomem; | 758 | goto nomem; |
760 | *plink = cpu_to_le32(td->dma_handle); | 759 | *plink = LINK_TO_TD(td); |
761 | 760 | ||
762 | /* | 761 | /* |
763 | * It's IN if the pipe is an output pipe or we're not expecting | 762 | * It's IN if the pipe is an output pipe or we're not expecting |
@@ -784,7 +783,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
784 | td = uhci_alloc_td(uhci); | 783 | td = uhci_alloc_td(uhci); |
785 | if (!td) | 784 | if (!td) |
786 | goto nomem; | 785 | goto nomem; |
787 | *plink = cpu_to_le32(td->dma_handle); | 786 | *plink = LINK_TO_TD(td); |
788 | 787 | ||
789 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); | 788 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); |
790 | wmb(); | 789 | wmb(); |
@@ -860,7 +859,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
860 | td = uhci_alloc_td(uhci); | 859 | td = uhci_alloc_td(uhci); |
861 | if (!td) | 860 | if (!td) |
862 | goto nomem; | 861 | goto nomem; |
863 | *plink = cpu_to_le32(td->dma_handle); | 862 | *plink = LINK_TO_TD(td); |
864 | } | 863 | } |
865 | uhci_add_td_to_urbp(td, urbp); | 864 | uhci_add_td_to_urbp(td, urbp); |
866 | uhci_fill_td(td, status, | 865 | uhci_fill_td(td, status, |
@@ -888,7 +887,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
888 | td = uhci_alloc_td(uhci); | 887 | td = uhci_alloc_td(uhci); |
889 | if (!td) | 888 | if (!td) |
890 | goto nomem; | 889 | goto nomem; |
891 | *plink = cpu_to_le32(td->dma_handle); | 890 | *plink = LINK_TO_TD(td); |
892 | 891 | ||
893 | uhci_add_td_to_urbp(td, urbp); | 892 | uhci_add_td_to_urbp(td, urbp); |
894 | uhci_fill_td(td, status, | 893 | uhci_fill_td(td, status, |
@@ -914,7 +913,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
914 | td = uhci_alloc_td(uhci); | 913 | td = uhci_alloc_td(uhci); |
915 | if (!td) | 914 | if (!td) |
916 | goto nomem; | 915 | goto nomem; |
917 | *plink = cpu_to_le32(td->dma_handle); | 916 | *plink = LINK_TO_TD(td); |
918 | 917 | ||
919 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); | 918 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); |
920 | wmb(); | 919 | wmb(); |
@@ -1005,7 +1004,7 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, | |||
1005 | * the queue at the status stage transaction, which is | 1004 | * the queue at the status stage transaction, which is |
1006 | * the last TD. */ | 1005 | * the last TD. */ |
1007 | WARN_ON(list_empty(&urbp->td_list)); | 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; | 1008 | tmp = td->list.prev; |
1010 | ret = -EINPROGRESS; | 1009 | ret = -EINPROGRESS; |
1011 | 1010 | ||
@@ -1566,8 +1565,7 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1566 | if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { | 1565 | if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { |
1567 | 1566 | ||
1568 | /* Detect the Intel bug and work around it */ | 1567 | /* Detect the Intel bug and work around it */ |
1569 | if (qh->post_td && qh_element(qh) == | 1568 | if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) { |
1570 | cpu_to_le32(qh->post_td->dma_handle)) { | ||
1571 | qh->element = qh->post_td->link; | 1569 | qh->element = qh->post_td->link; |
1572 | qh->advance_jiffies = jiffies; | 1570 | qh->advance_jiffies = jiffies; |
1573 | ret = 1; | 1571 | ret = 1; |