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 | |
| 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>
| -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; |
