diff options
author | Jan Andersson <jan@gaisler.com> | 2011-05-18 04:44:51 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-19 19:43:20 -0400 |
commit | 51e2f62fe79651e7ed8e16ba126a163b116fe3d7 (patch) | |
tree | a46c220bf5a9ff3b4fd8195e127e69e0b8619222 /drivers/usb | |
parent | bab1ff1bda27e654dfd382a1fbdfcda1f7ed0a37 (diff) |
USB: UHCI: Add support for big endian descriptors
This patch adds support for universal host controllers that use
big endian descriptors. Support for BE descriptors requires a non-PCI
host controller. For kernels with PCI-only UHCI there should be no
change in behaviour.
This patch tries to replicate the technique used to support BE descriptors
in the EHCI HCD. Parts added to uhci-hcd.h are basically copy'n'paste from
ehci.h.
Signed-off-by: Jan Andersson <jan@gaisler.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/Kconfig | 4 | ||||
-rw-r--r-- | drivers/usb/host/uhci-debug.c | 71 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.c | 16 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.h | 90 | ||||
-rw-r--r-- | drivers/usb/host/uhci-q.c | 131 |
5 files changed, 192 insertions, 120 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index ce9e22bf211c..584424804d0b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -420,6 +420,10 @@ config USB_UHCI_BIG_ENDIAN_MMIO | |||
420 | bool | 420 | bool |
421 | depends on USB_UHCI_SUPPORT_NON_PCI_HC | 421 | depends on USB_UHCI_SUPPORT_NON_PCI_HC |
422 | 422 | ||
423 | config USB_UHCI_BIG_ENDIAN_DESC | ||
424 | bool | ||
425 | depends on USB_UHCI_SUPPORT_NON_PCI_HC | ||
426 | |||
423 | config USB_FHCI_HCD | 427 | config USB_FHCI_HCD |
424 | tristate "Freescale QE USB Host Controller support" | 428 | tristate "Freescale QE USB Host Controller support" |
425 | depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE | 429 | depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index f882a84b1bbb..fc0b0daac93d 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -37,7 +37,8 @@ static void lprintk(char *buf) | |||
37 | } | 37 | } |
38 | } | 38 | } |
39 | 39 | ||
40 | static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space) | 40 | static int uhci_show_td(struct uhci_hcd *uhci, struct uhci_td *td, char *buf, |
41 | int len, int space) | ||
41 | { | 42 | { |
42 | char *out = buf; | 43 | char *out = buf; |
43 | char *spid; | 44 | char *spid; |
@@ -47,8 +48,9 @@ static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space) | |||
47 | if (len < 160) | 48 | if (len < 160) |
48 | return 0; | 49 | return 0; |
49 | 50 | ||
50 | status = td_status(td); | 51 | status = td_status(uhci, td); |
51 | out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td, le32_to_cpu(td->link)); | 52 | out += sprintf(out, "%*s[%p] link (%08x) ", space, "", td, |
53 | hc32_to_cpu(uhci, td->link)); | ||
52 | out += sprintf(out, "e%d %s%s%s%s%s%s%s%s%s%sLength=%x ", | 54 | out += sprintf(out, "e%d %s%s%s%s%s%s%s%s%s%sLength=%x ", |
53 | ((status >> 27) & 3), | 55 | ((status >> 27) & 3), |
54 | (status & TD_CTRL_SPD) ? "SPD " : "", | 56 | (status & TD_CTRL_SPD) ? "SPD " : "", |
@@ -63,7 +65,7 @@ static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space) | |||
63 | (status & TD_CTRL_BITSTUFF) ? "BitStuff " : "", | 65 | (status & TD_CTRL_BITSTUFF) ? "BitStuff " : "", |
64 | status & 0x7ff); | 66 | status & 0x7ff); |
65 | 67 | ||
66 | token = td_token(td); | 68 | token = td_token(uhci, td); |
67 | switch (uhci_packetid(token)) { | 69 | switch (uhci_packetid(token)) { |
68 | case USB_PID_SETUP: | 70 | case USB_PID_SETUP: |
69 | spid = "SETUP"; | 71 | spid = "SETUP"; |
@@ -86,12 +88,13 @@ static int uhci_show_td(struct uhci_td *td, char *buf, int len, int space) | |||
86 | (token >> 8) & 127, | 88 | (token >> 8) & 127, |
87 | (token & 0xff), | 89 | (token & 0xff), |
88 | spid); | 90 | spid); |
89 | out += sprintf(out, "(buf=%08x)\n", le32_to_cpu(td->buffer)); | 91 | out += sprintf(out, "(buf=%08x)\n", hc32_to_cpu(uhci, td->buffer)); |
90 | 92 | ||
91 | return out - buf; | 93 | return out - buf; |
92 | } | 94 | } |
93 | 95 | ||
94 | static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) | 96 | static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, |
97 | char *buf, int len, int space) | ||
95 | { | 98 | { |
96 | char *out = buf; | 99 | char *out = buf; |
97 | struct uhci_td *td; | 100 | struct uhci_td *td; |
@@ -130,9 +133,10 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) | |||
130 | if (urbp->qh->type != USB_ENDPOINT_XFER_ISOC && | 133 | if (urbp->qh->type != USB_ENDPOINT_XFER_ISOC && |
131 | (++i <= 10 || debug > 2)) { | 134 | (++i <= 10 || debug > 2)) { |
132 | out += sprintf(out, "%*s%d: ", space + 2, "", i); | 135 | out += sprintf(out, "%*s%d: ", space + 2, "", i); |
133 | out += uhci_show_td(td, out, len - (out - buf), 0); | 136 | out += uhci_show_td(uhci, td, out, |
137 | len - (out - buf), 0); | ||
134 | } else { | 138 | } else { |
135 | if (td_status(td) & TD_CTRL_ACTIVE) | 139 | if (td_status(uhci, td) & TD_CTRL_ACTIVE) |
136 | ++nactive; | 140 | ++nactive; |
137 | else | 141 | else |
138 | ++ninactive; | 142 | ++ninactive; |
@@ -151,7 +155,7 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
151 | { | 155 | { |
152 | char *out = buf; | 156 | char *out = buf; |
153 | int i, nurbs; | 157 | int i, nurbs; |
154 | __le32 element = qh_element(qh); | 158 | __hc32 element = qh_element(qh); |
155 | char *qtype; | 159 | char *qtype; |
156 | 160 | ||
157 | /* Try to make sure there's enough memory */ | 161 | /* Try to make sure there's enough memory */ |
@@ -168,7 +172,8 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
168 | 172 | ||
169 | out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n", | 173 | out += sprintf(out, "%*s[%p] %s QH link (%08x) element (%08x)\n", |
170 | space, "", qh, qtype, | 174 | space, "", qh, qtype, |
171 | le32_to_cpu(qh->link), le32_to_cpu(element)); | 175 | hc32_to_cpu(uhci, qh->link), |
176 | hc32_to_cpu(uhci, element)); | ||
172 | if (qh->type == USB_ENDPOINT_XFER_ISOC) | 177 | if (qh->type == USB_ENDPOINT_XFER_ISOC) |
173 | out += sprintf(out, "%*s period %d phase %d load %d us, " | 178 | out += sprintf(out, "%*s period %d phase %d load %d us, " |
174 | "frame %x desc [%p]\n", | 179 | "frame %x desc [%p]\n", |
@@ -178,22 +183,22 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
178 | out += sprintf(out, "%*s period %d phase %d load %d us\n", | 183 | out += sprintf(out, "%*s period %d phase %d load %d us\n", |
179 | space, "", qh->period, qh->phase, qh->load); | 184 | space, "", qh->period, qh->phase, qh->load); |
180 | 185 | ||
181 | if (element & UHCI_PTR_QH) | 186 | if (element & UHCI_PTR_QH(uhci)) |
182 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); | 187 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); |
183 | 188 | ||
184 | if (element & UHCI_PTR_DEPTH) | 189 | if (element & UHCI_PTR_DEPTH(uhci)) |
185 | out += sprintf(out, "%*s Depth traverse\n", space, ""); | 190 | out += sprintf(out, "%*s Depth traverse\n", space, ""); |
186 | 191 | ||
187 | if (element & cpu_to_le32(8)) | 192 | if (element & cpu_to_hc32(uhci, 8)) |
188 | out += sprintf(out, "%*s Bit 3 set (bug?)\n", space, ""); | 193 | out += sprintf(out, "%*s Bit 3 set (bug?)\n", space, ""); |
189 | 194 | ||
190 | if (!(element & ~(UHCI_PTR_QH | UHCI_PTR_DEPTH))) | 195 | if (!(element & ~(UHCI_PTR_QH(uhci) | UHCI_PTR_DEPTH(uhci)))) |
191 | out += sprintf(out, "%*s Element is NULL (bug?)\n", space, ""); | 196 | out += sprintf(out, "%*s Element is NULL (bug?)\n", space, ""); |
192 | 197 | ||
193 | if (list_empty(&qh->queue)) { | 198 | if (list_empty(&qh->queue)) { |
194 | out += sprintf(out, "%*s queue is empty\n", space, ""); | 199 | out += sprintf(out, "%*s queue is empty\n", space, ""); |
195 | if (qh == uhci->skel_async_qh) | 200 | if (qh == uhci->skel_async_qh) |
196 | out += uhci_show_td(uhci->term_td, out, | 201 | out += uhci_show_td(uhci, uhci->term_td, out, |
197 | len - (out - buf), 0); | 202 | len - (out - buf), 0); |
198 | } else { | 203 | } else { |
199 | struct urb_priv *urbp = list_entry(qh->queue.next, | 204 | struct urb_priv *urbp = list_entry(qh->queue.next, |
@@ -201,13 +206,13 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
201 | struct uhci_td *td = list_entry(urbp->td_list.next, | 206 | struct uhci_td *td = list_entry(urbp->td_list.next, |
202 | struct uhci_td, list); | 207 | struct uhci_td, list); |
203 | 208 | ||
204 | if (element != LINK_TO_TD(td)) | 209 | if (element != LINK_TO_TD(uhci, td)) |
205 | out += sprintf(out, "%*s Element != First TD\n", | 210 | out += sprintf(out, "%*s Element != First TD\n", |
206 | space, ""); | 211 | space, ""); |
207 | i = nurbs = 0; | 212 | i = nurbs = 0; |
208 | list_for_each_entry(urbp, &qh->queue, node) { | 213 | list_for_each_entry(urbp, &qh->queue, node) { |
209 | if (++i <= 10) | 214 | if (++i <= 10) |
210 | out += uhci_show_urbp(urbp, out, | 215 | out += uhci_show_urbp(uhci, urbp, out, |
211 | len - (out - buf), space + 2); | 216 | len - (out - buf), space + 2); |
212 | else | 217 | else |
213 | ++nurbs; | 218 | ++nurbs; |
@@ -219,7 +224,8 @@ static int uhci_show_qh(struct uhci_hcd *uhci, | |||
219 | 224 | ||
220 | if (qh->dummy_td) { | 225 | if (qh->dummy_td) { |
221 | out += sprintf(out, "%*s Dummy TD\n", space, ""); | 226 | out += sprintf(out, "%*s Dummy TD\n", space, ""); |
222 | out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); | 227 | out += uhci_show_td(uhci, qh->dummy_td, out, |
228 | len - (out - buf), 0); | ||
223 | } | 229 | } |
224 | 230 | ||
225 | return out - buf; | 231 | return out - buf; |
@@ -346,8 +352,8 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
346 | struct uhci_td *td; | 352 | struct uhci_td *td; |
347 | struct list_head *tmp, *head; | 353 | struct list_head *tmp, *head; |
348 | int nframes, nerrs; | 354 | int nframes, nerrs; |
349 | __le32 link; | 355 | __hc32 link; |
350 | __le32 fsbr_link; | 356 | __hc32 fsbr_link; |
351 | 357 | ||
352 | static const char * const qh_names[] = { | 358 | static const char * const qh_names[] = { |
353 | "unlink", "iso", "int128", "int64", "int32", "int16", | 359 | "unlink", "iso", "int128", "int64", "int32", "int16", |
@@ -375,7 +381,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
375 | nframes = 10; | 381 | nframes = 10; |
376 | nerrs = 0; | 382 | nerrs = 0; |
377 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 383 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
378 | __le32 qh_dma; | 384 | __hc32 qh_dma; |
379 | 385 | ||
380 | j = 0; | 386 | j = 0; |
381 | td = uhci->frame_cpu[i]; | 387 | td = uhci->frame_cpu[i]; |
@@ -385,7 +391,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
385 | 391 | ||
386 | if (nframes > 0) { | 392 | if (nframes > 0) { |
387 | out += sprintf(out, "- Frame %d -> (%08x)\n", | 393 | out += sprintf(out, "- Frame %d -> (%08x)\n", |
388 | i, le32_to_cpu(link)); | 394 | i, hc32_to_cpu(uhci, link)); |
389 | j = 1; | 395 | j = 1; |
390 | } | 396 | } |
391 | 397 | ||
@@ -394,7 +400,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
394 | do { | 400 | do { |
395 | td = list_entry(tmp, struct uhci_td, fl_list); | 401 | td = list_entry(tmp, struct uhci_td, fl_list); |
396 | tmp = tmp->next; | 402 | tmp = tmp->next; |
397 | if (link != LINK_TO_TD(td)) { | 403 | if (link != LINK_TO_TD(uhci, td)) { |
398 | if (nframes > 0) | 404 | if (nframes > 0) |
399 | out += sprintf(out, " link does " | 405 | out += sprintf(out, " link does " |
400 | "not match list entry!\n"); | 406 | "not match list entry!\n"); |
@@ -402,7 +408,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
402 | ++nerrs; | 408 | ++nerrs; |
403 | } | 409 | } |
404 | if (nframes > 0) | 410 | if (nframes > 0) |
405 | out += uhci_show_td(td, out, | 411 | out += uhci_show_td(uhci, td, out, |
406 | len - (out - buf), 4); | 412 | len - (out - buf), 4); |
407 | link = td->link; | 413 | link = td->link; |
408 | } while (tmp != head); | 414 | } while (tmp != head); |
@@ -414,11 +420,12 @@ check_link: | |||
414 | if (!j) { | 420 | if (!j) { |
415 | out += sprintf(out, | 421 | out += sprintf(out, |
416 | "- Frame %d -> (%08x)\n", | 422 | "- Frame %d -> (%08x)\n", |
417 | i, le32_to_cpu(link)); | 423 | i, hc32_to_cpu(uhci, link)); |
418 | j = 1; | 424 | j = 1; |
419 | } | 425 | } |
420 | out += sprintf(out, " link does not match " | 426 | out += sprintf(out, " link does not match " |
421 | "QH (%08x)!\n", le32_to_cpu(qh_dma)); | 427 | "QH (%08x)!\n", |
428 | hc32_to_cpu(uhci, qh_dma)); | ||
422 | } else | 429 | } else |
423 | ++nerrs; | 430 | ++nerrs; |
424 | } | 431 | } |
@@ -439,11 +446,11 @@ check_link: | |||
439 | 446 | ||
440 | /* Last QH is the Terminating QH, it's different */ | 447 | /* Last QH is the Terminating QH, it's different */ |
441 | if (i == SKEL_TERM) { | 448 | if (i == SKEL_TERM) { |
442 | if (qh_element(qh) != LINK_TO_TD(uhci->term_td)) | 449 | if (qh_element(qh) != LINK_TO_TD(uhci, uhci->term_td)) |
443 | out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); | 450 | out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); |
444 | link = fsbr_link; | 451 | link = fsbr_link; |
445 | if (!link) | 452 | if (!link) |
446 | link = LINK_TO_QH(uhci->skel_term_qh); | 453 | link = LINK_TO_QH(uhci, uhci->skel_term_qh); |
447 | goto check_qh_link; | 454 | goto check_qh_link; |
448 | } | 455 | } |
449 | 456 | ||
@@ -457,20 +464,20 @@ check_link: | |||
457 | out += uhci_show_qh(uhci, qh, out, | 464 | out += uhci_show_qh(uhci, qh, out, |
458 | len - (out - buf), 4); | 465 | len - (out - buf), 4); |
459 | if (!fsbr_link && qh->skel >= SKEL_FSBR) | 466 | if (!fsbr_link && qh->skel >= SKEL_FSBR) |
460 | fsbr_link = LINK_TO_QH(qh); | 467 | fsbr_link = LINK_TO_QH(uhci, qh); |
461 | } | 468 | } |
462 | if ((cnt -= 10) > 0) | 469 | if ((cnt -= 10) > 0) |
463 | out += sprintf(out, " Skipped %d QHs\n", cnt); | 470 | out += sprintf(out, " Skipped %d QHs\n", cnt); |
464 | 471 | ||
465 | link = UHCI_PTR_TERM; | 472 | link = UHCI_PTR_TERM(uhci); |
466 | if (i <= SKEL_ISO) | 473 | if (i <= SKEL_ISO) |
467 | ; | 474 | ; |
468 | else if (i < SKEL_ASYNC) | 475 | else if (i < SKEL_ASYNC) |
469 | link = LINK_TO_QH(uhci->skel_async_qh); | 476 | link = LINK_TO_QH(uhci, uhci->skel_async_qh); |
470 | else if (!uhci->fsbr_is_on) | 477 | else if (!uhci->fsbr_is_on) |
471 | ; | 478 | ; |
472 | else | 479 | else |
473 | link = LINK_TO_QH(uhci->skel_term_qh); | 480 | link = LINK_TO_QH(uhci, uhci->skel_term_qh); |
474 | check_qh_link: | 481 | check_qh_link: |
475 | if (qh->link != link) | 482 | if (qh->link != link) |
476 | out += sprintf(out, " last QH not linked to next skeleton!\n"); | 483 | out += sprintf(out, " last QH not linked to next skeleton!\n"); |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 79dd822e58d1..32dec7c74584 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -92,7 +92,7 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | |||
92 | /* | 92 | /* |
93 | * Calculate the link pointer DMA value for the first Skeleton QH in a frame. | 93 | * Calculate the link pointer DMA value for the first Skeleton QH in a frame. |
94 | */ | 94 | */ |
95 | static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) | 95 | static __hc32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) |
96 | { | 96 | { |
97 | int skelnum; | 97 | int skelnum; |
98 | 98 | ||
@@ -114,7 +114,7 @@ static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) | |||
114 | skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); | 114 | skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); |
115 | if (skelnum <= 1) | 115 | if (skelnum <= 1) |
116 | skelnum = 9; | 116 | skelnum = 9; |
117 | return LINK_TO_QH(uhci->skelqh[skelnum]); | 117 | return LINK_TO_QH(uhci, uhci->skelqh[skelnum]); |
118 | } | 118 | } |
119 | 119 | ||
120 | #include "uhci-debug.c" | 120 | #include "uhci-debug.c" |
@@ -630,16 +630,16 @@ static int uhci_start(struct usb_hcd *hcd) | |||
630 | * 8 Interrupt queues; link all higher int queues to int1 = async | 630 | * 8 Interrupt queues; link all higher int queues to int1 = async |
631 | */ | 631 | */ |
632 | for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i) | 632 | for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i) |
633 | uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh); | 633 | uhci->skelqh[i]->link = LINK_TO_QH(uhci, uhci->skel_async_qh); |
634 | uhci->skel_async_qh->link = UHCI_PTR_TERM; | 634 | uhci->skel_async_qh->link = UHCI_PTR_TERM(uhci); |
635 | uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh); | 635 | uhci->skel_term_qh->link = LINK_TO_QH(uhci, uhci->skel_term_qh); |
636 | 636 | ||
637 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ | 637 | /* This dummy TD is to work around a bug in Intel PIIX controllers */ |
638 | uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | | 638 | uhci_fill_td(uhci, uhci->term_td, 0, uhci_explen(0) | |
639 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); | 639 | (0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); |
640 | uhci->term_td->link = UHCI_PTR_TERM; | 640 | uhci->term_td->link = UHCI_PTR_TERM(uhci); |
641 | uhci->skel_async_qh->element = uhci->skel_term_qh->element = | 641 | uhci->skel_async_qh->element = uhci->skel_term_qh->element = |
642 | LINK_TO_TD(uhci->term_td); | 642 | LINK_TO_TD(uhci, uhci->term_td); |
643 | 643 | ||
644 | /* | 644 | /* |
645 | * Fill the frame list: make all entries point to the proper | 645 | * 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 0deeab6c9e56..7af2b7052047 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -78,11 +78,11 @@ | |||
78 | #define USBPORT1EN 0x01 | 78 | #define USBPORT1EN 0x01 |
79 | #define USBPORT2EN 0x02 | 79 | #define USBPORT2EN 0x02 |
80 | 80 | ||
81 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) | 81 | #define UHCI_PTR_BITS(uhci) cpu_to_hc32((uhci), 0x000F) |
82 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) | 82 | #define UHCI_PTR_TERM(uhci) cpu_to_hc32((uhci), 0x0001) |
83 | #define UHCI_PTR_QH cpu_to_le32(0x0002) | 83 | #define UHCI_PTR_QH(uhci) cpu_to_hc32((uhci), 0x0002) |
84 | #define UHCI_PTR_DEPTH cpu_to_le32(0x0004) | 84 | #define UHCI_PTR_DEPTH(uhci) cpu_to_hc32((uhci), 0x0004) |
85 | #define UHCI_PTR_BREADTH cpu_to_le32(0x0000) | 85 | #define UHCI_PTR_BREADTH(uhci) cpu_to_hc32((uhci), 0x0000) |
86 | 86 | ||
87 | #define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ | 87 | #define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ |
88 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 88 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
@@ -99,6 +99,22 @@ | |||
99 | 99 | ||
100 | 100 | ||
101 | /* | 101 | /* |
102 | * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to | ||
103 | * __leXX (normally) or __beXX (given UHCI_BIG_ENDIAN_DESC), depending on | ||
104 | * the host controller implementation. | ||
105 | * | ||
106 | * To facilitate the strongest possible byte-order checking from "sparse" | ||
107 | * and so on, we use __leXX unless that's not practical. | ||
108 | */ | ||
109 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_DESC | ||
110 | typedef __u32 __bitwise __hc32; | ||
111 | typedef __u16 __bitwise __hc16; | ||
112 | #else | ||
113 | #define __hc32 __le32 | ||
114 | #define __hc16 __le16 | ||
115 | #endif | ||
116 | |||
117 | /* | ||
102 | * Queue Headers | 118 | * Queue Headers |
103 | */ | 119 | */ |
104 | 120 | ||
@@ -130,8 +146,8 @@ | |||
130 | 146 | ||
131 | struct uhci_qh { | 147 | struct uhci_qh { |
132 | /* Hardware fields */ | 148 | /* Hardware fields */ |
133 | __le32 link; /* Next QH in the schedule */ | 149 | __hc32 link; /* Next QH in the schedule */ |
134 | __le32 element; /* Queue element (TD) pointer */ | 150 | __hc32 element; /* Queue element (TD) pointer */ |
135 | 151 | ||
136 | /* Software fields */ | 152 | /* Software fields */ |
137 | dma_addr_t dma_handle; | 153 | dma_addr_t dma_handle; |
@@ -170,7 +186,8 @@ struct uhci_qh { | |||
170 | */ | 186 | */ |
171 | #define qh_element(qh) ACCESS_ONCE((qh)->element) | 187 | #define qh_element(qh) ACCESS_ONCE((qh)->element) |
172 | 188 | ||
173 | #define LINK_TO_QH(qh) (UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle)) | 189 | #define LINK_TO_QH(uhci, qh) (UHCI_PTR_QH((uhci)) | \ |
190 | cpu_to_hc32((uhci), (qh)->dma_handle)) | ||
174 | 191 | ||
175 | 192 | ||
176 | /* | 193 | /* |
@@ -207,7 +224,7 @@ struct uhci_qh { | |||
207 | /* | 224 | /* |
208 | * for TD <info>: (a.k.a. Token) | 225 | * for TD <info>: (a.k.a. Token) |
209 | */ | 226 | */ |
210 | #define td_token(td) le32_to_cpu((td)->token) | 227 | #define td_token(uhci, td) hc32_to_cpu((uhci), (td)->token) |
211 | #define TD_TOKEN_DEVADDR_SHIFT 8 | 228 | #define TD_TOKEN_DEVADDR_SHIFT 8 |
212 | #define TD_TOKEN_TOGGLE_SHIFT 19 | 229 | #define TD_TOKEN_TOGGLE_SHIFT 19 |
213 | #define TD_TOKEN_TOGGLE (1 << 19) | 230 | #define TD_TOKEN_TOGGLE (1 << 19) |
@@ -240,10 +257,10 @@ struct uhci_qh { | |||
240 | */ | 257 | */ |
241 | struct uhci_td { | 258 | struct uhci_td { |
242 | /* Hardware fields */ | 259 | /* Hardware fields */ |
243 | __le32 link; | 260 | __hc32 link; |
244 | __le32 status; | 261 | __hc32 status; |
245 | __le32 token; | 262 | __hc32 token; |
246 | __le32 buffer; | 263 | __hc32 buffer; |
247 | 264 | ||
248 | /* Software fields */ | 265 | /* Software fields */ |
249 | dma_addr_t dma_handle; | 266 | dma_addr_t dma_handle; |
@@ -258,9 +275,10 @@ struct uhci_td { | |||
258 | * We need a special accessor for the control/status word because it is | 275 | * We need a special accessor for the control/status word because it is |
259 | * subject to asynchronous updates by the controller. | 276 | * subject to asynchronous updates by the controller. |
260 | */ | 277 | */ |
261 | #define td_status(td) le32_to_cpu(ACCESS_ONCE((td)->status)) | 278 | #define td_status(uhci, td) hc32_to_cpu((uhci), \ |
279 | ACCESS_ONCE((td)->status)) | ||
262 | 280 | ||
263 | #define LINK_TO_TD(td) (cpu_to_le32((td)->dma_handle)) | 281 | #define LINK_TO_TD(uhci, td) (cpu_to_hc32((uhci), (td)->dma_handle)) |
264 | 282 | ||
265 | 283 | ||
266 | /* | 284 | /* |
@@ -383,7 +401,7 @@ struct uhci_hcd { | |||
383 | spinlock_t lock; | 401 | spinlock_t lock; |
384 | 402 | ||
385 | dma_addr_t frame_dma_handle; /* Hardware frame list */ | 403 | dma_addr_t frame_dma_handle; /* Hardware frame list */ |
386 | __le32 *frame; | 404 | __hc32 *frame; |
387 | void **frame_cpu; /* CPU's frame list */ | 405 | void **frame_cpu; /* CPU's frame list */ |
388 | 406 | ||
389 | enum uhci_rh_state rh_state; | 407 | enum uhci_rh_state rh_state; |
@@ -412,6 +430,7 @@ struct uhci_hcd { | |||
412 | unsigned int oc_low:1; /* OverCurrent bit active low */ | 430 | unsigned int oc_low:1; /* OverCurrent bit active low */ |
413 | unsigned int wait_for_hp:1; /* Wait for HP port reset */ | 431 | unsigned int wait_for_hp:1; /* Wait for HP port reset */ |
414 | unsigned int big_endian_mmio:1; /* Big endian registers */ | 432 | unsigned int big_endian_mmio:1; /* Big endian registers */ |
433 | unsigned int big_endian_desc:1; /* Big endian descriptors */ | ||
415 | 434 | ||
416 | /* Support for port suspend/resume/reset */ | 435 | /* Support for port suspend/resume/reset */ |
417 | unsigned long port_c_suspend; /* Bit-arrays of ports */ | 436 | unsigned long port_c_suspend; /* Bit-arrays of ports */ |
@@ -603,4 +622,43 @@ static inline void uhci_writeb(const struct uhci_hcd *uhci, u8 val, int reg) | |||
603 | } | 622 | } |
604 | #endif /* CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC */ | 623 | #endif /* CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC */ |
605 | 624 | ||
625 | /* | ||
626 | * The GRLIB GRUSBHC controller can use big endian format for its descriptors. | ||
627 | * | ||
628 | * UHCI controllers accessed through PCI work normally (little-endian | ||
629 | * everywhere), so we don't bother supporting a BE-only mode. | ||
630 | */ | ||
631 | #ifdef CONFIG_USB_UHCI_BIG_ENDIAN_DESC | ||
632 | #define uhci_big_endian_desc(u) ((u)->big_endian_desc) | ||
633 | |||
634 | /* cpu to uhci */ | ||
635 | static inline __hc32 cpu_to_hc32(const struct uhci_hcd *uhci, const u32 x) | ||
636 | { | ||
637 | return uhci_big_endian_desc(uhci) | ||
638 | ? (__force __hc32)cpu_to_be32(x) | ||
639 | : (__force __hc32)cpu_to_le32(x); | ||
640 | } | ||
641 | |||
642 | /* uhci to cpu */ | ||
643 | static inline u32 hc32_to_cpu(const struct uhci_hcd *uhci, const __hc32 x) | ||
644 | { | ||
645 | return uhci_big_endian_desc(uhci) | ||
646 | ? be32_to_cpu((__force __be32)x) | ||
647 | : le32_to_cpu((__force __le32)x); | ||
648 | } | ||
649 | |||
650 | #else | ||
651 | /* cpu to uhci */ | ||
652 | static inline __hc32 cpu_to_hc32(const struct uhci_hcd *uhci, const u32 x) | ||
653 | { | ||
654 | return cpu_to_le32(x); | ||
655 | } | ||
656 | |||
657 | /* uhci to cpu */ | ||
658 | static inline u32 hc32_to_cpu(const struct uhci_hcd *uhci, const __hc32 x) | ||
659 | { | ||
660 | return le32_to_cpu(x); | ||
661 | } | ||
662 | #endif | ||
663 | |||
606 | #endif | 664 | #endif |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index af77abb5c68b..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 | } |
@@ -198,7 +198,7 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, | |||
198 | ntd = list_entry(td->fl_list.next, | 198 | ntd = list_entry(td->fl_list.next, |
199 | struct uhci_td, | 199 | struct uhci_td, |
200 | fl_list); | 200 | fl_list); |
201 | uhci->frame[td->frame] = LINK_TO_TD(ntd); | 201 | uhci->frame[td->frame] = LINK_TO_TD(uhci, ntd); |
202 | uhci->frame_cpu[td->frame] = ntd; | 202 | uhci->frame_cpu[td->frame] = ntd; |
203 | } | 203 | } |
204 | } else { | 204 | } else { |
@@ -255,8 +255,8 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, | |||
255 | memset(qh, 0, sizeof(*qh)); | 255 | memset(qh, 0, sizeof(*qh)); |
256 | qh->dma_handle = dma_handle; | 256 | qh->dma_handle = dma_handle; |
257 | 257 | ||
258 | qh->element = UHCI_PTR_TERM; | 258 | qh->element = UHCI_PTR_TERM(uhci); |
259 | qh->link = UHCI_PTR_TERM; | 259 | qh->link = UHCI_PTR_TERM(uhci); |
260 | 260 | ||
261 | INIT_LIST_HEAD(&qh->queue); | 261 | INIT_LIST_HEAD(&qh->queue); |
262 | INIT_LIST_HEAD(&qh->node); | 262 | INIT_LIST_HEAD(&qh->node); |
@@ -348,9 +348,9 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, | |||
348 | 348 | ||
349 | /* 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 |
350 | * 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. */ |
351 | if (qh_element(qh) == UHCI_PTR_TERM) | 351 | if (qh_element(qh) == UHCI_PTR_TERM(uhci)) |
352 | goto done; | 352 | goto done; |
353 | qh->element = UHCI_PTR_TERM; | 353 | qh->element = UHCI_PTR_TERM(uhci); |
354 | 354 | ||
355 | /* Control pipes don't have to worry about toggles */ | 355 | /* Control pipes don't have to worry about toggles */ |
356 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) | 356 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) |
@@ -360,7 +360,7 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, | |||
360 | WARN_ON(list_empty(&urbp->td_list)); | 360 | WARN_ON(list_empty(&urbp->td_list)); |
361 | td = list_entry(urbp->td_list.next, struct uhci_td, list); | 361 | td = list_entry(urbp->td_list.next, struct uhci_td, list); |
362 | qh->needs_fixup = 1; | 362 | qh->needs_fixup = 1; |
363 | qh->initial_toggle = uhci_toggle(td_token(td)); | 363 | qh->initial_toggle = uhci_toggle(td_token(uhci, td)); |
364 | 364 | ||
365 | done: | 365 | done: |
366 | return ret; | 366 | return ret; |
@@ -370,7 +370,8 @@ done: | |||
370 | * 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 |
371 | * terminates early (short transfer, error, or dequeued). | 371 | * terminates early (short transfer, error, or dequeued). |
372 | */ | 372 | */ |
373 | 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) | ||
374 | { | 375 | { |
375 | struct urb_priv *urbp = NULL; | 376 | struct urb_priv *urbp = NULL; |
376 | struct uhci_td *td; | 377 | struct uhci_td *td; |
@@ -384,7 +385,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) | |||
384 | 385 | ||
385 | /* 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 |
386 | * still valid then we know the URB's toggles are okay. */ | 387 | * still valid then we know the URB's toggles are okay. */ |
387 | else if (qh_element(qh) != UHCI_PTR_TERM) | 388 | else if (qh_element(qh) != UHCI_PTR_TERM(uhci)) |
388 | toggle = 2; | 389 | toggle = 2; |
389 | 390 | ||
390 | /* 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 |
@@ -396,15 +397,15 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) | |||
396 | /* 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 |
397 | * need to change any toggles in this URB */ | 398 | * need to change any toggles in this URB */ |
398 | td = list_entry(urbp->td_list.next, struct uhci_td, list); | 399 | td = list_entry(urbp->td_list.next, struct uhci_td, list); |
399 | if (toggle > 1 || uhci_toggle(td_token(td)) == toggle) { | 400 | if (toggle > 1 || uhci_toggle(td_token(uhci, td)) == toggle) { |
400 | td = list_entry(urbp->td_list.prev, struct uhci_td, | 401 | td = list_entry(urbp->td_list.prev, struct uhci_td, |
401 | list); | 402 | list); |
402 | toggle = uhci_toggle(td_token(td)) ^ 1; | 403 | toggle = uhci_toggle(td_token(uhci, td)) ^ 1; |
403 | 404 | ||
404 | /* Otherwise all the toggles in the URB have to be switched */ | 405 | /* Otherwise all the toggles in the URB have to be switched */ |
405 | } else { | 406 | } else { |
406 | list_for_each_entry(td, &urbp->td_list, list) { | 407 | list_for_each_entry(td, &urbp->td_list, list) { |
407 | td->token ^= cpu_to_le32( | 408 | td->token ^= cpu_to_hc32(uhci, |
408 | TD_TOKEN_TOGGLE); | 409 | TD_TOKEN_TOGGLE); |
409 | toggle ^= 1; | 410 | toggle ^= 1; |
410 | } | 411 | } |
@@ -441,7 +442,7 @@ static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
441 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); | 442 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); |
442 | qh->link = pqh->link; | 443 | qh->link = pqh->link; |
443 | wmb(); | 444 | wmb(); |
444 | pqh->link = LINK_TO_QH(qh); | 445 | pqh->link = LINK_TO_QH(uhci, qh); |
445 | } | 446 | } |
446 | 447 | ||
447 | /* | 448 | /* |
@@ -451,7 +452,7 @@ static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
451 | 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) |
452 | { | 453 | { |
453 | struct uhci_qh *pqh; | 454 | struct uhci_qh *pqh; |
454 | __le32 link_to_new_qh; | 455 | __hc32 link_to_new_qh; |
455 | 456 | ||
456 | /* 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. |
457 | * 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 |
@@ -465,7 +466,7 @@ static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
465 | /* Link it into the schedule */ | 466 | /* Link it into the schedule */ |
466 | qh->link = pqh->link; | 467 | qh->link = pqh->link; |
467 | wmb(); | 468 | wmb(); |
468 | link_to_new_qh = LINK_TO_QH(qh); | 469 | link_to_new_qh = LINK_TO_QH(uhci, qh); |
469 | pqh->link = link_to_new_qh; | 470 | pqh->link = link_to_new_qh; |
470 | 471 | ||
471 | /* 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 |
@@ -483,13 +484,13 @@ static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
483 | 484 | ||
484 | /* Set the element pointer if it isn't set already. | 485 | /* Set the element pointer if it isn't set already. |
485 | * 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. */ |
486 | if (qh_element(qh) == UHCI_PTR_TERM) { | 487 | if (qh_element(qh) == UHCI_PTR_TERM(uhci)) { |
487 | struct urb_priv *urbp = list_entry(qh->queue.next, | 488 | struct urb_priv *urbp = list_entry(qh->queue.next, |
488 | struct urb_priv, node); | 489 | struct urb_priv, node); |
489 | struct uhci_td *td = list_entry(urbp->td_list.next, | 490 | struct uhci_td *td = list_entry(urbp->td_list.next, |
490 | struct uhci_td, list); | 491 | struct uhci_td, list); |
491 | 492 | ||
492 | qh->element = LINK_TO_TD(td); | 493 | qh->element = LINK_TO_TD(uhci, td); |
493 | } | 494 | } |
494 | 495 | ||
495 | /* Treat the queue as if it has just advanced */ | 496 | /* Treat the queue as if it has just advanced */ |
@@ -533,7 +534,7 @@ static void unlink_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
533 | 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) |
534 | { | 535 | { |
535 | struct uhci_qh *pqh; | 536 | struct uhci_qh *pqh; |
536 | __le32 link_to_next_qh = qh->link; | 537 | __hc32 link_to_next_qh = qh->link; |
537 | 538 | ||
538 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); | 539 | pqh = list_entry(qh->node.prev, struct uhci_qh, node); |
539 | pqh->link = link_to_next_qh; | 540 | pqh->link = link_to_next_qh; |
@@ -757,8 +758,8 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, | |||
757 | /* | 758 | /* |
758 | * Map status to standard result codes | 759 | * Map status to standard result codes |
759 | * | 760 | * |
760 | * <status> is (td_status(td) & 0xF60000), a.k.a. | 761 | * <status> is (td_status(uhci, td) & 0xF60000), a.k.a. |
761 | * uhci_status_bits(td_status(td)). | 762 | * uhci_status_bits(td_status(uhci, td)). |
762 | * Note: <status> does not include the TD_CTRL_NAK bit. | 763 | * Note: <status> does not include the TD_CTRL_NAK bit. |
763 | * <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. |
764 | */ | 765 | */ |
@@ -794,7 +795,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
794 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); | 795 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); |
795 | int len = urb->transfer_buffer_length; | 796 | int len = urb->transfer_buffer_length; |
796 | dma_addr_t data = urb->transfer_dma; | 797 | dma_addr_t data = urb->transfer_dma; |
797 | __le32 *plink; | 798 | __hc32 *plink; |
798 | struct urb_priv *urbp = urb->hcpriv; | 799 | struct urb_priv *urbp = urb->hcpriv; |
799 | int skel; | 800 | int skel; |
800 | 801 | ||
@@ -811,7 +812,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
811 | */ | 812 | */ |
812 | td = qh->dummy_td; | 813 | td = qh->dummy_td; |
813 | uhci_add_td_to_urbp(td, urbp); | 814 | uhci_add_td_to_urbp(td, urbp); |
814 | uhci_fill_td(td, status, destination | uhci_explen(8), | 815 | uhci_fill_td(uhci, td, status, destination | uhci_explen(8), |
815 | urb->setup_dma); | 816 | urb->setup_dma); |
816 | plink = &td->link; | 817 | plink = &td->link; |
817 | status |= TD_CTRL_ACTIVE; | 818 | status |= TD_CTRL_ACTIVE; |
@@ -844,14 +845,14 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
844 | td = uhci_alloc_td(uhci); | 845 | td = uhci_alloc_td(uhci); |
845 | if (!td) | 846 | if (!td) |
846 | goto nomem; | 847 | goto nomem; |
847 | *plink = LINK_TO_TD(td); | 848 | *plink = LINK_TO_TD(uhci, td); |
848 | 849 | ||
849 | /* Alternate Data0/1 (start with Data1) */ | 850 | /* Alternate Data0/1 (start with Data1) */ |
850 | destination ^= TD_TOKEN_TOGGLE; | 851 | destination ^= TD_TOKEN_TOGGLE; |
851 | 852 | ||
852 | uhci_add_td_to_urbp(td, urbp); | 853 | uhci_add_td_to_urbp(td, urbp); |
853 | uhci_fill_td(td, status, destination | uhci_explen(pktsze), | 854 | uhci_fill_td(uhci, td, status, |
854 | data); | 855 | destination | uhci_explen(pktsze), data); |
855 | plink = &td->link; | 856 | plink = &td->link; |
856 | 857 | ||
857 | data += pktsze; | 858 | data += pktsze; |
@@ -864,14 +865,14 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
864 | td = uhci_alloc_td(uhci); | 865 | td = uhci_alloc_td(uhci); |
865 | if (!td) | 866 | if (!td) |
866 | goto nomem; | 867 | goto nomem; |
867 | *plink = LINK_TO_TD(td); | 868 | *plink = LINK_TO_TD(uhci, td); |
868 | 869 | ||
869 | /* Change direction for the status transaction */ | 870 | /* Change direction for the status transaction */ |
870 | destination ^= (USB_PID_IN ^ USB_PID_OUT); | 871 | destination ^= (USB_PID_IN ^ USB_PID_OUT); |
871 | destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ | 872 | destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ |
872 | 873 | ||
873 | uhci_add_td_to_urbp(td, urbp); | 874 | uhci_add_td_to_urbp(td, urbp); |
874 | uhci_fill_td(td, status | TD_CTRL_IOC, | 875 | uhci_fill_td(uhci, td, status | TD_CTRL_IOC, |
875 | destination | uhci_explen(0), 0); | 876 | destination | uhci_explen(0), 0); |
876 | plink = &td->link; | 877 | plink = &td->link; |
877 | 878 | ||
@@ -881,11 +882,11 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
881 | td = uhci_alloc_td(uhci); | 882 | td = uhci_alloc_td(uhci); |
882 | if (!td) | 883 | if (!td) |
883 | goto nomem; | 884 | goto nomem; |
884 | *plink = LINK_TO_TD(td); | 885 | *plink = LINK_TO_TD(uhci, td); |
885 | 886 | ||
886 | 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); |
887 | wmb(); | 888 | wmb(); |
888 | qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE); | 889 | qh->dummy_td->status |= cpu_to_hc32(uhci, TD_CTRL_ACTIVE); |
889 | qh->dummy_td = td; | 890 | qh->dummy_td = td; |
890 | 891 | ||
891 | /* 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. |
@@ -921,7 +922,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
921 | int len = urb->transfer_buffer_length; | 922 | int len = urb->transfer_buffer_length; |
922 | int this_sg_len; | 923 | int this_sg_len; |
923 | dma_addr_t data; | 924 | dma_addr_t data; |
924 | __le32 *plink; | 925 | __hc32 *plink; |
925 | struct urb_priv *urbp = urb->hcpriv; | 926 | struct urb_priv *urbp = urb->hcpriv; |
926 | unsigned int toggle; | 927 | unsigned int toggle; |
927 | struct scatterlist *sg; | 928 | struct scatterlist *sg; |
@@ -974,10 +975,10 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
974 | td = uhci_alloc_td(uhci); | 975 | td = uhci_alloc_td(uhci); |
975 | if (!td) | 976 | if (!td) |
976 | goto nomem; | 977 | goto nomem; |
977 | *plink = LINK_TO_TD(td); | 978 | *plink = LINK_TO_TD(uhci, td); |
978 | } | 979 | } |
979 | uhci_add_td_to_urbp(td, urbp); | 980 | uhci_add_td_to_urbp(td, urbp); |
980 | uhci_fill_td(td, status, | 981 | uhci_fill_td(uhci, td, status, |
981 | destination | uhci_explen(pktsze) | | 982 | destination | uhci_explen(pktsze) | |
982 | (toggle << TD_TOKEN_TOGGLE_SHIFT), | 983 | (toggle << TD_TOKEN_TOGGLE_SHIFT), |
983 | data); | 984 | data); |
@@ -1010,10 +1011,10 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
1010 | td = uhci_alloc_td(uhci); | 1011 | td = uhci_alloc_td(uhci); |
1011 | if (!td) | 1012 | if (!td) |
1012 | goto nomem; | 1013 | goto nomem; |
1013 | *plink = LINK_TO_TD(td); | 1014 | *plink = LINK_TO_TD(uhci, td); |
1014 | 1015 | ||
1015 | uhci_add_td_to_urbp(td, urbp); | 1016 | uhci_add_td_to_urbp(td, urbp); |
1016 | uhci_fill_td(td, status, | 1017 | uhci_fill_td(uhci, td, status, |
1017 | destination | uhci_explen(0) | | 1018 | destination | uhci_explen(0) | |
1018 | (toggle << TD_TOKEN_TOGGLE_SHIFT), | 1019 | (toggle << TD_TOKEN_TOGGLE_SHIFT), |
1019 | data); | 1020 | data); |
@@ -1028,7 +1029,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
1028 | * fast side but not enough to justify delaying an interrupt | 1029 | * fast side but not enough to justify delaying an interrupt |
1029 | * 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 |
1030 | * flag setting. */ | 1031 | * flag setting. */ |
1031 | td->status |= cpu_to_le32(TD_CTRL_IOC); | 1032 | td->status |= cpu_to_hc32(uhci, TD_CTRL_IOC); |
1032 | 1033 | ||
1033 | /* | 1034 | /* |
1034 | * Build the new dummy TD and activate the old one | 1035 | * Build the new dummy TD and activate the old one |
@@ -1036,11 +1037,11 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
1036 | td = uhci_alloc_td(uhci); | 1037 | td = uhci_alloc_td(uhci); |
1037 | if (!td) | 1038 | if (!td) |
1038 | goto nomem; | 1039 | goto nomem; |
1039 | *plink = LINK_TO_TD(td); | 1040 | *plink = LINK_TO_TD(uhci, td); |
1040 | 1041 | ||
1041 | 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); |
1042 | wmb(); | 1043 | wmb(); |
1043 | qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE); | 1044 | qh->dummy_td->status |= cpu_to_hc32(uhci, TD_CTRL_ACTIVE); |
1044 | qh->dummy_td = td; | 1045 | qh->dummy_td = td; |
1045 | 1046 | ||
1046 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 1047 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
@@ -1133,7 +1134,7 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, | |||
1133 | * the queue at the status stage transaction, which is | 1134 | * the queue at the status stage transaction, which is |
1134 | * the last TD. */ | 1135 | * the last TD. */ |
1135 | WARN_ON(list_empty(&urbp->td_list)); | 1136 | WARN_ON(list_empty(&urbp->td_list)); |
1136 | qh->element = LINK_TO_TD(td); | 1137 | qh->element = LINK_TO_TD(uhci, td); |
1137 | tmp = td->list.prev; | 1138 | tmp = td->list.prev; |
1138 | ret = -EINPROGRESS; | 1139 | ret = -EINPROGRESS; |
1139 | 1140 | ||
@@ -1142,8 +1143,9 @@ static int uhci_fixup_short_transfer(struct uhci_hcd *uhci, | |||
1142 | /* When a bulk/interrupt transfer is short, we have to | 1143 | /* When a bulk/interrupt transfer is short, we have to |
1143 | * fix up the toggles of the following URBs on the queue | 1144 | * fix up the toggles of the following URBs on the queue |
1144 | * before restarting the queue at the next URB. */ | 1145 | * before restarting the queue at the next URB. */ |
1145 | qh->initial_toggle = uhci_toggle(td_token(qh->post_td)) ^ 1; | 1146 | qh->initial_toggle = |
1146 | uhci_fixup_toggles(qh, 1); | 1147 | uhci_toggle(td_token(uhci, qh->post_td)) ^ 1; |
1148 | uhci_fixup_toggles(uhci, qh, 1); | ||
1147 | 1149 | ||
1148 | if (list_empty(&urbp->td_list)) | 1150 | if (list_empty(&urbp->td_list)) |
1149 | td = qh->post_td; | 1151 | td = qh->post_td; |
@@ -1178,7 +1180,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1178 | unsigned int ctrlstat; | 1180 | unsigned int ctrlstat; |
1179 | int len; | 1181 | int len; |
1180 | 1182 | ||
1181 | ctrlstat = td_status(td); | 1183 | ctrlstat = td_status(uhci, td); |
1182 | status = uhci_status_bits(ctrlstat); | 1184 | status = uhci_status_bits(ctrlstat); |
1183 | if (status & TD_CTRL_ACTIVE) | 1185 | if (status & TD_CTRL_ACTIVE) |
1184 | return -EINPROGRESS; | 1186 | return -EINPROGRESS; |
@@ -1188,7 +1190,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1188 | 1190 | ||
1189 | if (status) { | 1191 | if (status) { |
1190 | ret = uhci_map_status(status, | 1192 | ret = uhci_map_status(status, |
1191 | uhci_packetout(td_token(td))); | 1193 | uhci_packetout(td_token(uhci, td))); |
1192 | if ((debug == 1 && ret != -EPIPE) || debug > 1) { | 1194 | if ((debug == 1 && ret != -EPIPE) || debug > 1) { |
1193 | /* Some debugging code */ | 1195 | /* Some debugging code */ |
1194 | dev_dbg(&urb->dev->dev, | 1196 | dev_dbg(&urb->dev->dev, |
@@ -1204,7 +1206,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1204 | } | 1206 | } |
1205 | 1207 | ||
1206 | /* Did we receive a short packet? */ | 1208 | /* Did we receive a short packet? */ |
1207 | } else if (len < uhci_expected_length(td_token(td))) { | 1209 | } else if (len < uhci_expected_length(td_token(uhci, td))) { |
1208 | 1210 | ||
1209 | /* For control transfers, go to the status TD if | 1211 | /* For control transfers, go to the status TD if |
1210 | * this isn't already the last data TD */ | 1212 | * this isn't already the last data TD */ |
@@ -1236,10 +1238,10 @@ err: | |||
1236 | if (ret < 0) { | 1238 | if (ret < 0) { |
1237 | /* Note that the queue has stopped and save | 1239 | /* Note that the queue has stopped and save |
1238 | * the next toggle value */ | 1240 | * the next toggle value */ |
1239 | qh->element = UHCI_PTR_TERM; | 1241 | qh->element = UHCI_PTR_TERM(uhci); |
1240 | qh->is_stopped = 1; | 1242 | qh->is_stopped = 1; |
1241 | qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL); | 1243 | qh->needs_fixup = (qh->type != USB_ENDPOINT_XFER_CONTROL); |
1242 | qh->initial_toggle = uhci_toggle(td_token(td)) ^ | 1244 | qh->initial_toggle = uhci_toggle(td_token(uhci, td)) ^ |
1243 | (ret == -EREMOTEIO); | 1245 | (ret == -EREMOTEIO); |
1244 | 1246 | ||
1245 | } else /* Short packet received */ | 1247 | } else /* Short packet received */ |
@@ -1335,14 +1337,14 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1335 | return -ENOMEM; | 1337 | return -ENOMEM; |
1336 | 1338 | ||
1337 | uhci_add_td_to_urbp(td, urbp); | 1339 | uhci_add_td_to_urbp(td, urbp); |
1338 | uhci_fill_td(td, status, destination | | 1340 | uhci_fill_td(uhci, td, status, destination | |
1339 | uhci_explen(urb->iso_frame_desc[i].length), | 1341 | uhci_explen(urb->iso_frame_desc[i].length), |
1340 | urb->transfer_dma + | 1342 | urb->transfer_dma + |
1341 | urb->iso_frame_desc[i].offset); | 1343 | urb->iso_frame_desc[i].offset); |
1342 | } | 1344 | } |
1343 | 1345 | ||
1344 | /* Set the interrupt-on-completion flag on the last packet. */ | 1346 | /* Set the interrupt-on-completion flag on the last packet. */ |
1345 | td->status |= cpu_to_le32(TD_CTRL_IOC); | 1347 | td->status |= cpu_to_hc32(uhci, TD_CTRL_IOC); |
1346 | 1348 | ||
1347 | /* Add the TDs to the frame list */ | 1349 | /* Add the TDs to the frame list */ |
1348 | frame = urb->start_frame; | 1350 | frame = urb->start_frame; |
@@ -1378,7 +1380,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1378 | 1380 | ||
1379 | uhci_remove_tds_from_frame(uhci, qh->iso_frame); | 1381 | uhci_remove_tds_from_frame(uhci, qh->iso_frame); |
1380 | 1382 | ||
1381 | ctrlstat = td_status(td); | 1383 | ctrlstat = td_status(uhci, td); |
1382 | if (ctrlstat & TD_CTRL_ACTIVE) { | 1384 | if (ctrlstat & TD_CTRL_ACTIVE) { |
1383 | status = -EXDEV; /* TD was added too late? */ | 1385 | status = -EXDEV; /* TD was added too late? */ |
1384 | } else { | 1386 | } else { |
@@ -1629,7 +1631,7 @@ restart: | |||
1629 | * queue, the QH can now be re-activated. */ | 1631 | * queue, the QH can now be re-activated. */ |
1630 | if (!list_empty(&qh->queue)) { | 1632 | if (!list_empty(&qh->queue)) { |
1631 | if (qh->needs_fixup) | 1633 | if (qh->needs_fixup) |
1632 | uhci_fixup_toggles(qh, 0); | 1634 | uhci_fixup_toggles(uhci, qh, 0); |
1633 | 1635 | ||
1634 | /* 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 |
1635 | * limit has expired, set the next TD to interrupt on | 1637 | * limit has expired, set the next TD to interrupt on |
@@ -1639,7 +1641,7 @@ restart: | |||
1639 | struct uhci_td *td = list_entry(urbp->td_list.next, | 1641 | struct uhci_td *td = list_entry(urbp->td_list.next, |
1640 | struct uhci_td, list); | 1642 | struct uhci_td, list); |
1641 | 1643 | ||
1642 | td->status |= __cpu_to_le32(TD_CTRL_IOC); | 1644 | td->status |= cpu_to_hc32(uhci, TD_CTRL_IOC); |
1643 | } | 1645 | } |
1644 | 1646 | ||
1645 | uhci_activate_qh(uhci, qh); | 1647 | uhci_activate_qh(uhci, qh); |
@@ -1686,7 +1688,7 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1686 | } else { | 1688 | } else { |
1687 | urbp = list_entry(qh->queue.next, struct urb_priv, node); | 1689 | urbp = list_entry(qh->queue.next, struct urb_priv, node); |
1688 | td = list_entry(urbp->td_list.next, struct uhci_td, list); | 1690 | td = list_entry(urbp->td_list.next, struct uhci_td, list); |
1689 | status = td_status(td); | 1691 | status = td_status(uhci, td); |
1690 | if (!(status & TD_CTRL_ACTIVE)) { | 1692 | if (!(status & TD_CTRL_ACTIVE)) { |
1691 | 1693 | ||
1692 | /* We're okay, the queue has advanced */ | 1694 | /* We're okay, the queue has advanced */ |
@@ -1704,7 +1706,8 @@ static int uhci_advance_check(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1704 | if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { | 1706 | if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) { |
1705 | 1707 | ||
1706 | /* Detect the Intel bug and work around it */ | 1708 | /* Detect the Intel bug and work around it */ |
1707 | 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)) { | ||
1708 | qh->element = qh->post_td->link; | 1711 | qh->element = qh->post_td->link; |
1709 | qh->advance_jiffies = jiffies; | 1712 | qh->advance_jiffies = jiffies; |
1710 | ret = 1; | 1713 | ret = 1; |