diff options
author | Alek Du <alek.du@intel.com> | 2009-07-13 19:23:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-23 09:46:29 -0400 |
commit | 3807e26d69b9ad3864fe03224ebebc9610d5802e (patch) | |
tree | 3c85a5cb0686a7e72255c523b963942bbfc60b7f /drivers/usb/host | |
parent | 403dbd36739e344d2d25f56ebbe342248487bd48 (diff) |
USB: EHCI: split ehci_qh into hw and sw parts
The ehci_qh structure merged hw and sw together which is not good:
1. More and more items are being added into ehci_qh, the ehci_qh software
part are unnecessary to be allocated in DMA qh_pool.
2. If HCD has local SRAM, the sw part will consume it too, and it won't
bring any benefit.
3. For non-cache-coherence system, the entire ehci_qh is uncachable, actually
we only need the hw part to be uncacheable. Spliting them will let the sw
part to be cacheable.
Signed-off-by: Alek Du <alek.du@intel.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
CC: 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/ehci-dbg.c | 43 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 14 | ||||
-rw-r--r-- | drivers/usb/host/ehci-mem.c | 26 | ||||
-rw-r--r-- | drivers/usb/host/ehci-q.c | 50 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 66 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 9 |
6 files changed, 127 insertions, 81 deletions
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 1104caa0803b..874d2000bf92 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -134,10 +134,11 @@ dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) | |||
134 | static void __maybe_unused | 134 | static void __maybe_unused |
135 | dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) | 135 | dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) |
136 | { | 136 | { |
137 | struct ehci_qh_hw *hw = qh->hw; | ||
138 | |||
137 | ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label, | 139 | ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label, |
138 | qh, qh->hw_next, qh->hw_info1, qh->hw_info2, | 140 | qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current); |
139 | qh->hw_current); | 141 | dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next); |
140 | dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->hw_qtd_next); | ||
141 | } | 142 | } |
142 | 143 | ||
143 | static void __maybe_unused | 144 | static void __maybe_unused |
@@ -400,31 +401,32 @@ static void qh_lines ( | |||
400 | char *next = *nextp; | 401 | char *next = *nextp; |
401 | char mark; | 402 | char mark; |
402 | __le32 list_end = EHCI_LIST_END(ehci); | 403 | __le32 list_end = EHCI_LIST_END(ehci); |
404 | struct ehci_qh_hw *hw = qh->hw; | ||
403 | 405 | ||
404 | if (qh->hw_qtd_next == list_end) /* NEC does this */ | 406 | if (hw->hw_qtd_next == list_end) /* NEC does this */ |
405 | mark = '@'; | 407 | mark = '@'; |
406 | else | 408 | else |
407 | mark = token_mark(ehci, qh->hw_token); | 409 | mark = token_mark(ehci, hw->hw_token); |
408 | if (mark == '/') { /* qh_alt_next controls qh advance? */ | 410 | if (mark == '/') { /* qh_alt_next controls qh advance? */ |
409 | if ((qh->hw_alt_next & QTD_MASK(ehci)) | 411 | if ((hw->hw_alt_next & QTD_MASK(ehci)) |
410 | == ehci->async->hw_alt_next) | 412 | == ehci->async->hw->hw_alt_next) |
411 | mark = '#'; /* blocked */ | 413 | mark = '#'; /* blocked */ |
412 | else if (qh->hw_alt_next == list_end) | 414 | else if (hw->hw_alt_next == list_end) |
413 | mark = '.'; /* use hw_qtd_next */ | 415 | mark = '.'; /* use hw_qtd_next */ |
414 | /* else alt_next points to some other qtd */ | 416 | /* else alt_next points to some other qtd */ |
415 | } | 417 | } |
416 | scratch = hc32_to_cpup(ehci, &qh->hw_info1); | 418 | scratch = hc32_to_cpup(ehci, &hw->hw_info1); |
417 | hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &qh->hw_current) : 0; | 419 | hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0; |
418 | temp = scnprintf (next, size, | 420 | temp = scnprintf (next, size, |
419 | "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)", | 421 | "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)", |
420 | qh, scratch & 0x007f, | 422 | qh, scratch & 0x007f, |
421 | speed_char (scratch), | 423 | speed_char (scratch), |
422 | (scratch >> 8) & 0x000f, | 424 | (scratch >> 8) & 0x000f, |
423 | scratch, hc32_to_cpup(ehci, &qh->hw_info2), | 425 | scratch, hc32_to_cpup(ehci, &hw->hw_info2), |
424 | hc32_to_cpup(ehci, &qh->hw_token), mark, | 426 | hc32_to_cpup(ehci, &hw->hw_token), mark, |
425 | (cpu_to_hc32(ehci, QTD_TOGGLE) & qh->hw_token) | 427 | (cpu_to_hc32(ehci, QTD_TOGGLE) & hw->hw_token) |
426 | ? "data1" : "data0", | 428 | ? "data1" : "data0", |
427 | (hc32_to_cpup(ehci, &qh->hw_alt_next) >> 1) & 0x0f); | 429 | (hc32_to_cpup(ehci, &hw->hw_alt_next) >> 1) & 0x0f); |
428 | size -= temp; | 430 | size -= temp; |
429 | next += temp; | 431 | next += temp; |
430 | 432 | ||
@@ -435,10 +437,10 @@ static void qh_lines ( | |||
435 | mark = ' '; | 437 | mark = ' '; |
436 | if (hw_curr == td->qtd_dma) | 438 | if (hw_curr == td->qtd_dma) |
437 | mark = '*'; | 439 | mark = '*'; |
438 | else if (qh->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma)) | 440 | else if (hw->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma)) |
439 | mark = '+'; | 441 | mark = '+'; |
440 | else if (QTD_LENGTH (scratch)) { | 442 | else if (QTD_LENGTH (scratch)) { |
441 | if (td->hw_alt_next == ehci->async->hw_alt_next) | 443 | if (td->hw_alt_next == ehci->async->hw->hw_alt_next) |
442 | mark = '#'; | 444 | mark = '#'; |
443 | else if (td->hw_alt_next != list_end) | 445 | else if (td->hw_alt_next != list_end) |
444 | mark = '/'; | 446 | mark = '/'; |
@@ -550,12 +552,15 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |||
550 | next += temp; | 552 | next += temp; |
551 | 553 | ||
552 | do { | 554 | do { |
555 | struct ehci_qh_hw *hw; | ||
556 | |||
553 | switch (hc32_to_cpu(ehci, tag)) { | 557 | switch (hc32_to_cpu(ehci, tag)) { |
554 | case Q_TYPE_QH: | 558 | case Q_TYPE_QH: |
559 | hw = p.qh->hw; | ||
555 | temp = scnprintf (next, size, " qh%d-%04x/%p", | 560 | temp = scnprintf (next, size, " qh%d-%04x/%p", |
556 | p.qh->period, | 561 | p.qh->period, |
557 | hc32_to_cpup(ehci, | 562 | hc32_to_cpup(ehci, |
558 | &p.qh->hw_info2) | 563 | &hw->hw_info2) |
559 | /* uframe masks */ | 564 | /* uframe masks */ |
560 | & (QH_CMASK | QH_SMASK), | 565 | & (QH_CMASK | QH_SMASK), |
561 | p.qh); | 566 | p.qh); |
@@ -576,7 +581,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |||
576 | /* show more info the first time around */ | 581 | /* show more info the first time around */ |
577 | if (temp == seen_count) { | 582 | if (temp == seen_count) { |
578 | u32 scratch = hc32_to_cpup(ehci, | 583 | u32 scratch = hc32_to_cpup(ehci, |
579 | &p.qh->hw_info1); | 584 | &hw->hw_info1); |
580 | struct ehci_qtd *qtd; | 585 | struct ehci_qtd *qtd; |
581 | char *type = ""; | 586 | char *type = ""; |
582 | 587 | ||
@@ -609,7 +614,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) | |||
609 | } else | 614 | } else |
610 | temp = 0; | 615 | temp = 0; |
611 | if (p.qh) { | 616 | if (p.qh) { |
612 | tag = Q_NEXT_TYPE(ehci, p.qh->hw_next); | 617 | tag = Q_NEXT_TYPE(ehci, hw->hw_next); |
613 | p = p.qh->qh_next; | 618 | p = p.qh->qh_next; |
614 | } | 619 | } |
615 | break; | 620 | break; |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2dc15f3ad143..7bee1638dfd7 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -507,6 +507,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
507 | u32 temp; | 507 | u32 temp; |
508 | int retval; | 508 | int retval; |
509 | u32 hcc_params; | 509 | u32 hcc_params; |
510 | struct ehci_qh_hw *hw; | ||
510 | 511 | ||
511 | spin_lock_init(&ehci->lock); | 512 | spin_lock_init(&ehci->lock); |
512 | 513 | ||
@@ -550,12 +551,13 @@ static int ehci_init(struct usb_hcd *hcd) | |||
550 | * from automatically advancing to the next td after short reads. | 551 | * from automatically advancing to the next td after short reads. |
551 | */ | 552 | */ |
552 | ehci->async->qh_next.qh = NULL; | 553 | ehci->async->qh_next.qh = NULL; |
553 | ehci->async->hw_next = QH_NEXT(ehci, ehci->async->qh_dma); | 554 | hw = ehci->async->hw; |
554 | ehci->async->hw_info1 = cpu_to_hc32(ehci, QH_HEAD); | 555 | hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma); |
555 | ehci->async->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); | 556 | hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD); |
556 | ehci->async->hw_qtd_next = EHCI_LIST_END(ehci); | 557 | hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); |
558 | hw->hw_qtd_next = EHCI_LIST_END(ehci); | ||
557 | ehci->async->qh_state = QH_STATE_LINKED; | 559 | ehci->async->qh_state = QH_STATE_LINKED; |
558 | ehci->async->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma); | 560 | hw->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma); |
559 | 561 | ||
560 | /* clear interrupt enables, set irq latency */ | 562 | /* clear interrupt enables, set irq latency */ |
561 | if (log2_irq_thresh < 0 || log2_irq_thresh > 6) | 563 | if (log2_irq_thresh < 0 || log2_irq_thresh > 6) |
@@ -985,7 +987,7 @@ rescan: | |||
985 | /* endpoints can be iso streams. for now, we don't | 987 | /* endpoints can be iso streams. for now, we don't |
986 | * accelerate iso completions ... so spin a while. | 988 | * accelerate iso completions ... so spin a while. |
987 | */ | 989 | */ |
988 | if (qh->hw_info1 == 0) { | 990 | if (qh->hw->hw_info1 == 0) { |
989 | ehci_vdbg (ehci, "iso delay\n"); | 991 | ehci_vdbg (ehci, "iso delay\n"); |
990 | goto idle_timeout; | 992 | goto idle_timeout; |
991 | } | 993 | } |
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 10d52919abbb..aeda96e0af67 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
@@ -75,7 +75,8 @@ static void qh_destroy(struct ehci_qh *qh) | |||
75 | } | 75 | } |
76 | if (qh->dummy) | 76 | if (qh->dummy) |
77 | ehci_qtd_free (ehci, qh->dummy); | 77 | ehci_qtd_free (ehci, qh->dummy); |
78 | dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); | 78 | dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); |
79 | kfree(qh); | ||
79 | } | 80 | } |
80 | 81 | ||
81 | static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | 82 | static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) |
@@ -83,12 +84,14 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | |||
83 | struct ehci_qh *qh; | 84 | struct ehci_qh *qh; |
84 | dma_addr_t dma; | 85 | dma_addr_t dma; |
85 | 86 | ||
86 | qh = (struct ehci_qh *) | 87 | qh = kzalloc(sizeof *qh, GFP_ATOMIC); |
87 | dma_pool_alloc (ehci->qh_pool, flags, &dma); | ||
88 | if (!qh) | 88 | if (!qh) |
89 | return qh; | 89 | goto done; |
90 | 90 | qh->hw = (struct ehci_qh_hw *) | |
91 | memset (qh, 0, sizeof *qh); | 91 | dma_pool_alloc(ehci->qh_pool, flags, &dma); |
92 | if (!qh->hw) | ||
93 | goto fail; | ||
94 | memset(qh->hw, 0, sizeof *qh->hw); | ||
92 | qh->refcount = 1; | 95 | qh->refcount = 1; |
93 | qh->ehci = ehci; | 96 | qh->ehci = ehci; |
94 | qh->qh_dma = dma; | 97 | qh->qh_dma = dma; |
@@ -99,10 +102,15 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | |||
99 | qh->dummy = ehci_qtd_alloc (ehci, flags); | 102 | qh->dummy = ehci_qtd_alloc (ehci, flags); |
100 | if (qh->dummy == NULL) { | 103 | if (qh->dummy == NULL) { |
101 | ehci_dbg (ehci, "no dummy td\n"); | 104 | ehci_dbg (ehci, "no dummy td\n"); |
102 | dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); | 105 | goto fail1; |
103 | qh = NULL; | ||
104 | } | 106 | } |
107 | done: | ||
105 | return qh; | 108 | return qh; |
109 | fail1: | ||
110 | dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); | ||
111 | fail: | ||
112 | kfree(qh); | ||
113 | return NULL; | ||
106 | } | 114 | } |
107 | 115 | ||
108 | /* to share a qh (cpu threads, or hc) */ | 116 | /* to share a qh (cpu threads, or hc) */ |
@@ -180,7 +188,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) | |||
180 | /* QHs for control/bulk/intr transfers */ | 188 | /* QHs for control/bulk/intr transfers */ |
181 | ehci->qh_pool = dma_pool_create ("ehci_qh", | 189 | ehci->qh_pool = dma_pool_create ("ehci_qh", |
182 | ehci_to_hcd(ehci)->self.controller, | 190 | ehci_to_hcd(ehci)->self.controller, |
183 | sizeof (struct ehci_qh), | 191 | sizeof(struct ehci_qh_hw), |
184 | 32 /* byte alignment (for hw parts) */, | 192 | 32 /* byte alignment (for hw parts) */, |
185 | 4096 /* can't cross 4K */); | 193 | 4096 /* can't cross 4K */); |
186 | if (!ehci->qh_pool) { | 194 | if (!ehci->qh_pool) { |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 7673554fa64d..377ed530b920 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -87,31 +87,33 @@ qtd_fill(struct ehci_hcd *ehci, struct ehci_qtd *qtd, dma_addr_t buf, | |||
87 | static inline void | 87 | static inline void |
88 | qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) | 88 | qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) |
89 | { | 89 | { |
90 | struct ehci_qh_hw *hw = qh->hw; | ||
91 | |||
90 | /* writes to an active overlay are unsafe */ | 92 | /* writes to an active overlay are unsafe */ |
91 | BUG_ON(qh->qh_state != QH_STATE_IDLE); | 93 | BUG_ON(qh->qh_state != QH_STATE_IDLE); |
92 | 94 | ||
93 | qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); | 95 | hw->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); |
94 | qh->hw_alt_next = EHCI_LIST_END(ehci); | 96 | hw->hw_alt_next = EHCI_LIST_END(ehci); |
95 | 97 | ||
96 | /* Except for control endpoints, we make hardware maintain data | 98 | /* Except for control endpoints, we make hardware maintain data |
97 | * toggle (like OHCI) ... here (re)initialize the toggle in the QH, | 99 | * toggle (like OHCI) ... here (re)initialize the toggle in the QH, |
98 | * and set the pseudo-toggle in udev. Only usb_clear_halt() will | 100 | * and set the pseudo-toggle in udev. Only usb_clear_halt() will |
99 | * ever clear it. | 101 | * ever clear it. |
100 | */ | 102 | */ |
101 | if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { | 103 | if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { |
102 | unsigned is_out, epnum; | 104 | unsigned is_out, epnum; |
103 | 105 | ||
104 | is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); | 106 | is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); |
105 | epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f; | 107 | epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f; |
106 | if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { | 108 | if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { |
107 | qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | 109 | hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); |
108 | usb_settoggle (qh->dev, epnum, is_out, 1); | 110 | usb_settoggle (qh->dev, epnum, is_out, 1); |
109 | } | 111 | } |
110 | } | 112 | } |
111 | 113 | ||
112 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ | 114 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ |
113 | wmb (); | 115 | wmb (); |
114 | qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); | 116 | hw->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); |
115 | } | 117 | } |
116 | 118 | ||
117 | /* if it weren't for a common silicon quirk (writing the dummy into the qh | 119 | /* if it weren't for a common silicon quirk (writing the dummy into the qh |
@@ -129,7 +131,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
129 | qtd = list_entry (qh->qtd_list.next, | 131 | qtd = list_entry (qh->qtd_list.next, |
130 | struct ehci_qtd, qtd_list); | 132 | struct ehci_qtd, qtd_list); |
131 | /* first qtd may already be partially processed */ | 133 | /* first qtd may already be partially processed */ |
132 | if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw_current) | 134 | if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) |
133 | qtd = NULL; | 135 | qtd = NULL; |
134 | } | 136 | } |
135 | 137 | ||
@@ -260,7 +262,7 @@ __acquires(ehci->lock) | |||
260 | struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; | 262 | struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; |
261 | 263 | ||
262 | /* S-mask in a QH means it's an interrupt urb */ | 264 | /* S-mask in a QH means it's an interrupt urb */ |
263 | if ((qh->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) { | 265 | if ((qh->hw->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) { |
264 | 266 | ||
265 | /* ... update hc-wide periodic stats (for usbfs) */ | 267 | /* ... update hc-wide periodic stats (for usbfs) */ |
266 | ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; | 268 | ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; |
@@ -315,6 +317,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
315 | unsigned count = 0; | 317 | unsigned count = 0; |
316 | u8 state; | 318 | u8 state; |
317 | __le32 halt = HALT_BIT(ehci); | 319 | __le32 halt = HALT_BIT(ehci); |
320 | struct ehci_qh_hw *hw = qh->hw; | ||
318 | 321 | ||
319 | if (unlikely (list_empty (&qh->qtd_list))) | 322 | if (unlikely (list_empty (&qh->qtd_list))) |
320 | return count; | 323 | return count; |
@@ -392,7 +395,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
392 | qtd->hw_token = cpu_to_hc32(ehci, | 395 | qtd->hw_token = cpu_to_hc32(ehci, |
393 | token); | 396 | token); |
394 | wmb(); | 397 | wmb(); |
395 | qh->hw_token = cpu_to_hc32(ehci, token); | 398 | hw->hw_token = cpu_to_hc32(ehci, |
399 | token); | ||
396 | goto retry_xacterr; | 400 | goto retry_xacterr; |
397 | } | 401 | } |
398 | stopped = 1; | 402 | stopped = 1; |
@@ -435,8 +439,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
435 | /* qh unlinked; token in overlay may be most current */ | 439 | /* qh unlinked; token in overlay may be most current */ |
436 | if (state == QH_STATE_IDLE | 440 | if (state == QH_STATE_IDLE |
437 | && cpu_to_hc32(ehci, qtd->qtd_dma) | 441 | && cpu_to_hc32(ehci, qtd->qtd_dma) |
438 | == qh->hw_current) { | 442 | == hw->hw_current) { |
439 | token = hc32_to_cpu(ehci, qh->hw_token); | 443 | token = hc32_to_cpu(ehci, hw->hw_token); |
440 | 444 | ||
441 | /* An unlink may leave an incomplete | 445 | /* An unlink may leave an incomplete |
442 | * async transaction in the TT buffer. | 446 | * async transaction in the TT buffer. |
@@ -449,9 +453,9 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
449 | * patch the qh later and so that completions can't | 453 | * patch the qh later and so that completions can't |
450 | * activate it while we "know" it's stopped. | 454 | * activate it while we "know" it's stopped. |
451 | */ | 455 | */ |
452 | if ((halt & qh->hw_token) == 0) { | 456 | if ((halt & hw->hw_token) == 0) { |
453 | halt: | 457 | halt: |
454 | qh->hw_token |= halt; | 458 | hw->hw_token |= halt; |
455 | wmb (); | 459 | wmb (); |
456 | } | 460 | } |
457 | } | 461 | } |
@@ -510,7 +514,7 @@ halt: | |||
510 | * it after fault cleanup, or recovering from silicon wrongly | 514 | * it after fault cleanup, or recovering from silicon wrongly |
511 | * overlaying the dummy qtd (which reduces DMA chatter). | 515 | * overlaying the dummy qtd (which reduces DMA chatter). |
512 | */ | 516 | */ |
513 | if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END(ehci)) { | 517 | if (stopped != 0 || hw->hw_qtd_next == EHCI_LIST_END(ehci)) { |
514 | switch (state) { | 518 | switch (state) { |
515 | case QH_STATE_IDLE: | 519 | case QH_STATE_IDLE: |
516 | qh_refresh(ehci, qh); | 520 | qh_refresh(ehci, qh); |
@@ -528,7 +532,7 @@ halt: | |||
528 | * except maybe high bandwidth ... | 532 | * except maybe high bandwidth ... |
529 | */ | 533 | */ |
530 | if ((cpu_to_hc32(ehci, QH_SMASK) | 534 | if ((cpu_to_hc32(ehci, QH_SMASK) |
531 | & qh->hw_info2) != 0) { | 535 | & hw->hw_info2) != 0) { |
532 | intr_deschedule (ehci, qh); | 536 | intr_deschedule (ehci, qh); |
533 | (void) qh_schedule (ehci, qh); | 537 | (void) qh_schedule (ehci, qh); |
534 | } else | 538 | } else |
@@ -649,7 +653,7 @@ qh_urb_transaction ( | |||
649 | * (this will usually be overridden later.) | 653 | * (this will usually be overridden later.) |
650 | */ | 654 | */ |
651 | if (is_input) | 655 | if (is_input) |
652 | qtd->hw_alt_next = ehci->async->hw_alt_next; | 656 | qtd->hw_alt_next = ehci->async->hw->hw_alt_next; |
653 | 657 | ||
654 | /* qh makes control packets use qtd toggle; maybe switch it */ | 658 | /* qh makes control packets use qtd toggle; maybe switch it */ |
655 | if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) | 659 | if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) |
@@ -744,6 +748,7 @@ qh_make ( | |||
744 | int is_input, type; | 748 | int is_input, type; |
745 | int maxp = 0; | 749 | int maxp = 0; |
746 | struct usb_tt *tt = urb->dev->tt; | 750 | struct usb_tt *tt = urb->dev->tt; |
751 | struct ehci_qh_hw *hw; | ||
747 | 752 | ||
748 | if (!qh) | 753 | if (!qh) |
749 | return qh; | 754 | return qh; |
@@ -890,8 +895,9 @@ done: | |||
890 | 895 | ||
891 | /* init as live, toggle clear, advance to dummy */ | 896 | /* init as live, toggle clear, advance to dummy */ |
892 | qh->qh_state = QH_STATE_IDLE; | 897 | qh->qh_state = QH_STATE_IDLE; |
893 | qh->hw_info1 = cpu_to_hc32(ehci, info1); | 898 | hw = qh->hw; |
894 | qh->hw_info2 = cpu_to_hc32(ehci, info2); | 899 | hw->hw_info1 = cpu_to_hc32(ehci, info1); |
900 | hw->hw_info2 = cpu_to_hc32(ehci, info2); | ||
895 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); | 901 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); |
896 | qh_refresh (ehci, qh); | 902 | qh_refresh (ehci, qh); |
897 | return qh; | 903 | return qh; |
@@ -933,11 +939,11 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
933 | 939 | ||
934 | /* splice right after start */ | 940 | /* splice right after start */ |
935 | qh->qh_next = head->qh_next; | 941 | qh->qh_next = head->qh_next; |
936 | qh->hw_next = head->hw_next; | 942 | qh->hw->hw_next = head->hw->hw_next; |
937 | wmb (); | 943 | wmb (); |
938 | 944 | ||
939 | head->qh_next.qh = qh; | 945 | head->qh_next.qh = qh; |
940 | head->hw_next = dma; | 946 | head->hw->hw_next = dma; |
941 | 947 | ||
942 | qh_get(qh); | 948 | qh_get(qh); |
943 | qh->xacterrs = 0; | 949 | qh->xacterrs = 0; |
@@ -984,7 +990,7 @@ static struct ehci_qh *qh_append_tds ( | |||
984 | 990 | ||
985 | /* usb_reset_device() briefly reverts to address 0 */ | 991 | /* usb_reset_device() briefly reverts to address 0 */ |
986 | if (usb_pipedevice (urb->pipe) == 0) | 992 | if (usb_pipedevice (urb->pipe) == 0) |
987 | qh->hw_info1 &= ~qh_addr_mask; | 993 | qh->hw->hw_info1 &= ~qh_addr_mask; |
988 | } | 994 | } |
989 | 995 | ||
990 | /* just one way to queue requests: swap with the dummy qtd. | 996 | /* just one way to queue requests: swap with the dummy qtd. |
@@ -1169,7 +1175,7 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1169 | while (prev->qh_next.qh != qh) | 1175 | while (prev->qh_next.qh != qh) |
1170 | prev = prev->qh_next.qh; | 1176 | prev = prev->qh_next.qh; |
1171 | 1177 | ||
1172 | prev->hw_next = qh->hw_next; | 1178 | prev->hw->hw_next = qh->hw->hw_next; |
1173 | prev->qh_next = qh->qh_next; | 1179 | prev->qh_next = qh->qh_next; |
1174 | wmb (); | 1180 | wmb (); |
1175 | 1181 | ||
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index edd61ee90323..327437af2122 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -60,6 +60,20 @@ periodic_next_shadow(struct ehci_hcd *ehci, union ehci_shadow *periodic, | |||
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | static __hc32 * | ||
64 | shadow_next_periodic(struct ehci_hcd *ehci, union ehci_shadow *periodic, | ||
65 | __hc32 tag) | ||
66 | { | ||
67 | switch (hc32_to_cpu(ehci, tag)) { | ||
68 | /* our ehci_shadow.qh is actually software part */ | ||
69 | case Q_TYPE_QH: | ||
70 | return &periodic->qh->hw->hw_next; | ||
71 | /* others are hw parts */ | ||
72 | default: | ||
73 | return periodic->hw_next; | ||
74 | } | ||
75 | } | ||
76 | |||
63 | /* caller must hold ehci->lock */ | 77 | /* caller must hold ehci->lock */ |
64 | static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) | 78 | static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) |
65 | { | 79 | { |
@@ -71,7 +85,8 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) | |||
71 | while (here.ptr && here.ptr != ptr) { | 85 | while (here.ptr && here.ptr != ptr) { |
72 | prev_p = periodic_next_shadow(ehci, prev_p, | 86 | prev_p = periodic_next_shadow(ehci, prev_p, |
73 | Q_NEXT_TYPE(ehci, *hw_p)); | 87 | Q_NEXT_TYPE(ehci, *hw_p)); |
74 | hw_p = here.hw_next; | 88 | hw_p = shadow_next_periodic(ehci, &here, |
89 | Q_NEXT_TYPE(ehci, *hw_p)); | ||
75 | here = *prev_p; | 90 | here = *prev_p; |
76 | } | 91 | } |
77 | /* an interrupt entry (at list end) could have been shared */ | 92 | /* an interrupt entry (at list end) could have been shared */ |
@@ -83,7 +98,7 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) | |||
83 | */ | 98 | */ |
84 | *prev_p = *periodic_next_shadow(ehci, &here, | 99 | *prev_p = *periodic_next_shadow(ehci, &here, |
85 | Q_NEXT_TYPE(ehci, *hw_p)); | 100 | Q_NEXT_TYPE(ehci, *hw_p)); |
86 | *hw_p = *here.hw_next; | 101 | *hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)); |
87 | } | 102 | } |
88 | 103 | ||
89 | /* how many of the uframe's 125 usecs are allocated? */ | 104 | /* how many of the uframe's 125 usecs are allocated? */ |
@@ -93,18 +108,20 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe) | |||
93 | __hc32 *hw_p = &ehci->periodic [frame]; | 108 | __hc32 *hw_p = &ehci->periodic [frame]; |
94 | union ehci_shadow *q = &ehci->pshadow [frame]; | 109 | union ehci_shadow *q = &ehci->pshadow [frame]; |
95 | unsigned usecs = 0; | 110 | unsigned usecs = 0; |
111 | struct ehci_qh_hw *hw; | ||
96 | 112 | ||
97 | while (q->ptr) { | 113 | while (q->ptr) { |
98 | switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) { | 114 | switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) { |
99 | case Q_TYPE_QH: | 115 | case Q_TYPE_QH: |
116 | hw = q->qh->hw; | ||
100 | /* is it in the S-mask? */ | 117 | /* is it in the S-mask? */ |
101 | if (q->qh->hw_info2 & cpu_to_hc32(ehci, 1 << uframe)) | 118 | if (hw->hw_info2 & cpu_to_hc32(ehci, 1 << uframe)) |
102 | usecs += q->qh->usecs; | 119 | usecs += q->qh->usecs; |
103 | /* ... or C-mask? */ | 120 | /* ... or C-mask? */ |
104 | if (q->qh->hw_info2 & cpu_to_hc32(ehci, | 121 | if (hw->hw_info2 & cpu_to_hc32(ehci, |
105 | 1 << (8 + uframe))) | 122 | 1 << (8 + uframe))) |
106 | usecs += q->qh->c_usecs; | 123 | usecs += q->qh->c_usecs; |
107 | hw_p = &q->qh->hw_next; | 124 | hw_p = &hw->hw_next; |
108 | q = &q->qh->qh_next; | 125 | q = &q->qh->qh_next; |
109 | break; | 126 | break; |
110 | // case Q_TYPE_FSTN: | 127 | // case Q_TYPE_FSTN: |
@@ -237,10 +254,10 @@ periodic_tt_usecs ( | |||
237 | continue; | 254 | continue; |
238 | case Q_TYPE_QH: | 255 | case Q_TYPE_QH: |
239 | if (same_tt(dev, q->qh->dev)) { | 256 | if (same_tt(dev, q->qh->dev)) { |
240 | uf = tt_start_uframe(ehci, q->qh->hw_info2); | 257 | uf = tt_start_uframe(ehci, q->qh->hw->hw_info2); |
241 | tt_usecs[uf] += q->qh->tt_usecs; | 258 | tt_usecs[uf] += q->qh->tt_usecs; |
242 | } | 259 | } |
243 | hw_p = &q->qh->hw_next; | 260 | hw_p = &q->qh->hw->hw_next; |
244 | q = &q->qh->qh_next; | 261 | q = &q->qh->qh_next; |
245 | continue; | 262 | continue; |
246 | case Q_TYPE_SITD: | 263 | case Q_TYPE_SITD: |
@@ -375,6 +392,7 @@ static int tt_no_collision ( | |||
375 | for (; frame < ehci->periodic_size; frame += period) { | 392 | for (; frame < ehci->periodic_size; frame += period) { |
376 | union ehci_shadow here; | 393 | union ehci_shadow here; |
377 | __hc32 type; | 394 | __hc32 type; |
395 | struct ehci_qh_hw *hw; | ||
378 | 396 | ||
379 | here = ehci->pshadow [frame]; | 397 | here = ehci->pshadow [frame]; |
380 | type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]); | 398 | type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]); |
@@ -385,17 +403,18 @@ static int tt_no_collision ( | |||
385 | here = here.itd->itd_next; | 403 | here = here.itd->itd_next; |
386 | continue; | 404 | continue; |
387 | case Q_TYPE_QH: | 405 | case Q_TYPE_QH: |
406 | hw = here.qh->hw; | ||
388 | if (same_tt (dev, here.qh->dev)) { | 407 | if (same_tt (dev, here.qh->dev)) { |
389 | u32 mask; | 408 | u32 mask; |
390 | 409 | ||
391 | mask = hc32_to_cpu(ehci, | 410 | mask = hc32_to_cpu(ehci, |
392 | here.qh->hw_info2); | 411 | hw->hw_info2); |
393 | /* "knows" no gap is needed */ | 412 | /* "knows" no gap is needed */ |
394 | mask |= mask >> 8; | 413 | mask |= mask >> 8; |
395 | if (mask & uf_mask) | 414 | if (mask & uf_mask) |
396 | break; | 415 | break; |
397 | } | 416 | } |
398 | type = Q_NEXT_TYPE(ehci, here.qh->hw_next); | 417 | type = Q_NEXT_TYPE(ehci, hw->hw_next); |
399 | here = here.qh->qh_next; | 418 | here = here.qh->qh_next; |
400 | continue; | 419 | continue; |
401 | case Q_TYPE_SITD: | 420 | case Q_TYPE_SITD: |
@@ -498,7 +517,8 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
498 | 517 | ||
499 | dev_dbg (&qh->dev->dev, | 518 | dev_dbg (&qh->dev->dev, |
500 | "link qh%d-%04x/%p start %d [%d/%d us]\n", | 519 | "link qh%d-%04x/%p start %d [%d/%d us]\n", |
501 | period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), | 520 | period, hc32_to_cpup(ehci, &qh->hw->hw_info2) |
521 | & (QH_CMASK | QH_SMASK), | ||
502 | qh, qh->start, qh->usecs, qh->c_usecs); | 522 | qh, qh->start, qh->usecs, qh->c_usecs); |
503 | 523 | ||
504 | /* high bandwidth, or otherwise every microframe */ | 524 | /* high bandwidth, or otherwise every microframe */ |
@@ -517,7 +537,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
517 | if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) | 537 | if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) |
518 | break; | 538 | break; |
519 | prev = periodic_next_shadow(ehci, prev, type); | 539 | prev = periodic_next_shadow(ehci, prev, type); |
520 | hw_p = &here.qh->hw_next; | 540 | hw_p = shadow_next_periodic(ehci, &here, type); |
521 | here = *prev; | 541 | here = *prev; |
522 | } | 542 | } |
523 | 543 | ||
@@ -528,14 +548,14 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
528 | if (qh->period > here.qh->period) | 548 | if (qh->period > here.qh->period) |
529 | break; | 549 | break; |
530 | prev = &here.qh->qh_next; | 550 | prev = &here.qh->qh_next; |
531 | hw_p = &here.qh->hw_next; | 551 | hw_p = &here.qh->hw->hw_next; |
532 | here = *prev; | 552 | here = *prev; |
533 | } | 553 | } |
534 | /* link in this qh, unless some earlier pass did that */ | 554 | /* link in this qh, unless some earlier pass did that */ |
535 | if (qh != here.qh) { | 555 | if (qh != here.qh) { |
536 | qh->qh_next = here; | 556 | qh->qh_next = here; |
537 | if (here.qh) | 557 | if (here.qh) |
538 | qh->hw_next = *hw_p; | 558 | qh->hw->hw_next = *hw_p; |
539 | wmb (); | 559 | wmb (); |
540 | prev->qh = qh; | 560 | prev->qh = qh; |
541 | *hw_p = QH_NEXT (ehci, qh->qh_dma); | 561 | *hw_p = QH_NEXT (ehci, qh->qh_dma); |
@@ -581,7 +601,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
581 | dev_dbg (&qh->dev->dev, | 601 | dev_dbg (&qh->dev->dev, |
582 | "unlink qh%d-%04x/%p start %d [%d/%d us]\n", | 602 | "unlink qh%d-%04x/%p start %d [%d/%d us]\n", |
583 | qh->period, | 603 | qh->period, |
584 | hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), | 604 | hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK), |
585 | qh, qh->start, qh->usecs, qh->c_usecs); | 605 | qh, qh->start, qh->usecs, qh->c_usecs); |
586 | 606 | ||
587 | /* qh->qh_next still "live" to HC */ | 607 | /* qh->qh_next still "live" to HC */ |
@@ -596,6 +616,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
596 | static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) | 616 | static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) |
597 | { | 617 | { |
598 | unsigned wait; | 618 | unsigned wait; |
619 | struct ehci_qh_hw *hw = qh->hw; | ||
599 | 620 | ||
600 | qh_unlink_periodic (ehci, qh); | 621 | qh_unlink_periodic (ehci, qh); |
601 | 622 | ||
@@ -606,14 +627,14 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
606 | */ | 627 | */ |
607 | if (list_empty (&qh->qtd_list) | 628 | if (list_empty (&qh->qtd_list) |
608 | || (cpu_to_hc32(ehci, QH_CMASK) | 629 | || (cpu_to_hc32(ehci, QH_CMASK) |
609 | & qh->hw_info2) != 0) | 630 | & hw->hw_info2) != 0) |
610 | wait = 2; | 631 | wait = 2; |
611 | else | 632 | else |
612 | wait = 55; /* worst case: 3 * 1024 */ | 633 | wait = 55; /* worst case: 3 * 1024 */ |
613 | 634 | ||
614 | udelay (wait); | 635 | udelay (wait); |
615 | qh->qh_state = QH_STATE_IDLE; | 636 | qh->qh_state = QH_STATE_IDLE; |
616 | qh->hw_next = EHCI_LIST_END(ehci); | 637 | hw->hw_next = EHCI_LIST_END(ehci); |
617 | wmb (); | 638 | wmb (); |
618 | } | 639 | } |
619 | 640 | ||
@@ -739,14 +760,15 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
739 | unsigned uframe; | 760 | unsigned uframe; |
740 | __hc32 c_mask; | 761 | __hc32 c_mask; |
741 | unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */ | 762 | unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */ |
763 | struct ehci_qh_hw *hw = qh->hw; | ||
742 | 764 | ||
743 | qh_refresh(ehci, qh); | 765 | qh_refresh(ehci, qh); |
744 | qh->hw_next = EHCI_LIST_END(ehci); | 766 | hw->hw_next = EHCI_LIST_END(ehci); |
745 | frame = qh->start; | 767 | frame = qh->start; |
746 | 768 | ||
747 | /* reuse the previous schedule slots, if we can */ | 769 | /* reuse the previous schedule slots, if we can */ |
748 | if (frame < qh->period) { | 770 | if (frame < qh->period) { |
749 | uframe = ffs(hc32_to_cpup(ehci, &qh->hw_info2) & QH_SMASK); | 771 | uframe = ffs(hc32_to_cpup(ehci, &hw->hw_info2) & QH_SMASK); |
750 | status = check_intr_schedule (ehci, frame, --uframe, | 772 | status = check_intr_schedule (ehci, frame, --uframe, |
751 | qh, &c_mask); | 773 | qh, &c_mask); |
752 | } else { | 774 | } else { |
@@ -784,11 +806,11 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
784 | qh->start = frame; | 806 | qh->start = frame; |
785 | 807 | ||
786 | /* reset S-frame and (maybe) C-frame masks */ | 808 | /* reset S-frame and (maybe) C-frame masks */ |
787 | qh->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK)); | 809 | hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK)); |
788 | qh->hw_info2 |= qh->period | 810 | hw->hw_info2 |= qh->period |
789 | ? cpu_to_hc32(ehci, 1 << uframe) | 811 | ? cpu_to_hc32(ehci, 1 << uframe) |
790 | : cpu_to_hc32(ehci, QH_SMASK); | 812 | : cpu_to_hc32(ehci, QH_SMASK); |
791 | qh->hw_info2 |= c_mask; | 813 | hw->hw_info2 |= c_mask; |
792 | } else | 814 | } else |
793 | ehci_dbg (ehci, "reused qh %p schedule\n", qh); | 815 | ehci_dbg (ehci, "reused qh %p schedule\n", qh); |
794 | 816 | ||
@@ -2188,7 +2210,7 @@ restart: | |||
2188 | case Q_TYPE_QH: | 2210 | case Q_TYPE_QH: |
2189 | /* handle any completions */ | 2211 | /* handle any completions */ |
2190 | temp.qh = qh_get (q.qh); | 2212 | temp.qh = qh_get (q.qh); |
2191 | type = Q_NEXT_TYPE(ehci, q.qh->hw_next); | 2213 | type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next); |
2192 | q = q.qh->qh_next; | 2214 | q = q.qh->qh_next; |
2193 | modified = qh_completions (ehci, temp.qh); | 2215 | modified = qh_completions (ehci, temp.qh); |
2194 | if (unlikely (list_empty (&temp.qh->qtd_list))) | 2216 | if (unlikely (list_empty (&temp.qh->qtd_list))) |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index acec10894078..fa12f20fbfe2 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -299,8 +299,8 @@ union ehci_shadow { | |||
299 | * These appear in both the async and (for interrupt) periodic schedules. | 299 | * These appear in both the async and (for interrupt) periodic schedules. |
300 | */ | 300 | */ |
301 | 301 | ||
302 | struct ehci_qh { | 302 | /* first part defined by EHCI spec */ |
303 | /* first part defined by EHCI spec */ | 303 | struct ehci_qh_hw { |
304 | __hc32 hw_next; /* see EHCI 3.6.1 */ | 304 | __hc32 hw_next; /* see EHCI 3.6.1 */ |
305 | __hc32 hw_info1; /* see EHCI 3.6.2 */ | 305 | __hc32 hw_info1; /* see EHCI 3.6.2 */ |
306 | #define QH_HEAD 0x00008000 | 306 | #define QH_HEAD 0x00008000 |
@@ -318,7 +318,10 @@ struct ehci_qh { | |||
318 | __hc32 hw_token; | 318 | __hc32 hw_token; |
319 | __hc32 hw_buf [5]; | 319 | __hc32 hw_buf [5]; |
320 | __hc32 hw_buf_hi [5]; | 320 | __hc32 hw_buf_hi [5]; |
321 | } __attribute__ ((aligned(32))); | ||
321 | 322 | ||
323 | struct ehci_qh { | ||
324 | struct ehci_qh_hw *hw; | ||
322 | /* the rest is HCD-private */ | 325 | /* the rest is HCD-private */ |
323 | dma_addr_t qh_dma; /* address of qh */ | 326 | dma_addr_t qh_dma; /* address of qh */ |
324 | union ehci_shadow qh_next; /* ptr to qh; or periodic */ | 327 | union ehci_shadow qh_next; /* ptr to qh; or periodic */ |
@@ -358,7 +361,7 @@ struct ehci_qh { | |||
358 | 361 | ||
359 | struct usb_device *dev; /* access to TT */ | 362 | struct usb_device *dev; /* access to TT */ |
360 | unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ | 363 | unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ |
361 | } __attribute__ ((aligned (32))); | 364 | }; |
362 | 365 | ||
363 | /*-------------------------------------------------------------------------*/ | 366 | /*-------------------------------------------------------------------------*/ |
364 | 367 | ||