[PATCH] USB: ehci: microframe handling fix

This patch has a one line oops fix, plus related cleanups.

- The bugfix uses microframe scheduling data given to the hardware to
test "is this a periodic QH", rather than testing for nonzero period.
(Prevents an oops by providing the correct answer.)

- The cleanup going along with the patch should make it clearer what's
going on whenever those bitfields are accessed.

The bug came about when, around January, two new kinds of EHCI interrupt
scheduling operation were added, involving both the high speed (24 KBytes
per millisec) and low/full speed (1-64 bytes per millisec) microframe
scheduling. A driver for the Edirol UA-1000 Audio Capture Unit ran into
the oops; it used one of the newly supported high speed modes.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by David Brownell and committed by Linus Torvalds 7dedacf4 003ba515

+16 -9
+1 -1
drivers/usb/host/ehci-dbg.c
··· 527 p.qh->period, 528 le32_to_cpup (&p.qh->hw_info2) 529 /* uframe masks */ 530 - & 0xffff, 531 p.qh); 532 size -= temp; 533 next += temp;
··· 527 p.qh->period, 528 le32_to_cpup (&p.qh->hw_info2) 529 /* uframe masks */ 530 + & (QH_CMASK | QH_SMASK), 531 p.qh); 532 size -= temp; 533 next += temp;
+3 -2
drivers/usb/host/ehci-q.c
··· 222 struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; 223 224 /* S-mask in a QH means it's an interrupt urb */ 225 - if ((qh->hw_info2 & __constant_cpu_to_le32 (0x00ff)) != 0) { 226 227 /* ... update hc-wide periodic stats (for usbfs) */ 228 ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; ··· 428 /* should be rare for periodic transfers, 429 * except maybe high bandwidth ... 430 */ 431 - if (qh->period) { 432 intr_deschedule (ehci, qh); 433 (void) qh_schedule (ehci, qh); 434 } else
··· 222 struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; 223 224 /* S-mask in a QH means it's an interrupt urb */ 225 + if ((qh->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) { 226 227 /* ... update hc-wide periodic stats (for usbfs) */ 228 ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; ··· 428 /* should be rare for periodic transfers, 429 * except maybe high bandwidth ... 430 */ 431 + if ((__constant_cpu_to_le32 (QH_SMASK) 432 + & qh->hw_info2) != 0) { 433 intr_deschedule (ehci, qh); 434 (void) qh_schedule (ehci, qh); 435 } else
+7 -6
drivers/usb/host/ehci-sched.c
··· 301 302 dev_dbg (&qh->dev->dev, 303 "link qh%d-%04x/%p start %d [%d/%d us]\n", 304 - period, le32_to_cpup (&qh->hw_info2) & 0xffff, 305 qh, qh->start, qh->usecs, qh->c_usecs); 306 307 /* high bandwidth, or otherwise every microframe */ ··· 385 386 dev_dbg (&qh->dev->dev, 387 "unlink qh%d-%04x/%p start %d [%d/%d us]\n", 388 - qh->period, le32_to_cpup (&qh->hw_info2) & 0xffff, 389 qh, qh->start, qh->usecs, qh->c_usecs); 390 391 /* qh->qh_next still "live" to HC */ ··· 412 * active high speed queues may need bigger delays... 413 */ 414 if (list_empty (&qh->qtd_list) 415 - || (__constant_cpu_to_le32 (0x0ff << 8) 416 & qh->hw_info2) != 0) 417 wait = 2; 418 else ··· 534 535 /* reuse the previous schedule slots, if we can */ 536 if (frame < qh->period) { 537 - uframe = ffs (le32_to_cpup (&qh->hw_info2) & 0x00ff); 538 status = check_intr_schedule (ehci, frame, --uframe, 539 qh, &c_mask); 540 } else { ··· 570 qh->start = frame; 571 572 /* reset S-frame and (maybe) C-frame masks */ 573 - qh->hw_info2 &= __constant_cpu_to_le32 (~0xffff); 574 qh->hw_info2 |= qh->period 575 ? cpu_to_le32 (1 << uframe) 576 - : __constant_cpu_to_le32 (0xff); 577 qh->hw_info2 |= c_mask; 578 } else 579 ehci_dbg (ehci, "reused qh %p schedule\n", qh);
··· 301 302 dev_dbg (&qh->dev->dev, 303 "link qh%d-%04x/%p start %d [%d/%d us]\n", 304 + period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK), 305 qh, qh->start, qh->usecs, qh->c_usecs); 306 307 /* high bandwidth, or otherwise every microframe */ ··· 385 386 dev_dbg (&qh->dev->dev, 387 "unlink qh%d-%04x/%p start %d [%d/%d us]\n", 388 + qh->period, 389 + le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK), 390 qh, qh->start, qh->usecs, qh->c_usecs); 391 392 /* qh->qh_next still "live" to HC */ ··· 411 * active high speed queues may need bigger delays... 412 */ 413 if (list_empty (&qh->qtd_list) 414 + || (__constant_cpu_to_le32 (QH_CMASK) 415 & qh->hw_info2) != 0) 416 wait = 2; 417 else ··· 533 534 /* reuse the previous schedule slots, if we can */ 535 if (frame < qh->period) { 536 + uframe = ffs (le32_to_cpup (&qh->hw_info2) & QH_SMASK); 537 status = check_intr_schedule (ehci, frame, --uframe, 538 qh, &c_mask); 539 } else { ··· 569 qh->start = frame; 570 571 /* reset S-frame and (maybe) C-frame masks */ 572 + qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK)); 573 qh->hw_info2 |= qh->period 574 ? cpu_to_le32 (1 << uframe) 575 + : __constant_cpu_to_le32 (QH_SMASK); 576 qh->hw_info2 |= c_mask; 577 } else 578 ehci_dbg (ehci, "reused qh %p schedule\n", qh);
+5
drivers/usb/host/ehci.h
··· 385 __le32 hw_info1; /* see EHCI 3.6.2 */ 386 #define QH_HEAD 0x00008000 387 __le32 hw_info2; /* see EHCI 3.6.2 */ 388 __le32 hw_current; /* qtd list - see EHCI 3.6.4 */ 389 390 /* qtd overlay (hardware parts of a struct ehci_qtd) */
··· 385 __le32 hw_info1; /* see EHCI 3.6.2 */ 386 #define QH_HEAD 0x00008000 387 __le32 hw_info2; /* see EHCI 3.6.2 */ 388 + #define QH_SMASK 0x000000ff 389 + #define QH_CMASK 0x0000ff00 390 + #define QH_HUBADDR 0x007f0000 391 + #define QH_HUBPORT 0x3f800000 392 + #define QH_MULT 0xc0000000 393 __le32 hw_current; /* qtd list - see EHCI 3.6.4 */ 394 395 /* qtd overlay (hardware parts of a struct ehci_qtd) */