aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-02-19 15:51:51 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-23 18:03:45 -0500
commit28b9325e6ae45ffb5e99fedcafe00f25fcaacf06 (patch)
tree91391a8e2d11acc50adc5b7c631b2695bee9e453 /drivers/usb/host
parentd0374f4f9c35cdfbee0ade72d06732613b4e6628 (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.c9
-rw-r--r--drivers/usb/host/uhci-hcd.c24
-rw-r--r--drivers/usb/host/uhci-hcd.h8
-rw-r--r--drivers/usb/host/uhci-q.c30
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)
46static void uhci_fsbr_on(struct uhci_hcd *uhci) 46static 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
53static void uhci_fsbr_off(struct uhci_hcd *uhci) 52static 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;