diff options
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 6c9fbe352f7..c787af2ba4b 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -36,6 +36,27 @@ | |||
36 | 36 | ||
37 | static int ehci_get_frame (struct usb_hcd *hcd); | 37 | static int ehci_get_frame (struct usb_hcd *hcd); |
38 | 38 | ||
39 | #ifdef CONFIG_PCI | ||
40 | |||
41 | static unsigned ehci_read_frame_index(struct ehci_hcd *ehci) | ||
42 | { | ||
43 | unsigned uf; | ||
44 | |||
45 | /* | ||
46 | * The MosChip MCS9990 controller updates its microframe counter | ||
47 | * a little before the frame counter, and occasionally we will read | ||
48 | * the invalid intermediate value. Avoid problems by checking the | ||
49 | * microframe number (the low-order 3 bits); if they are 0 then | ||
50 | * re-read the register to get the correct value. | ||
51 | */ | ||
52 | uf = ehci_readl(ehci, &ehci->regs->frame_index); | ||
53 | if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0))) | ||
54 | uf = ehci_readl(ehci, &ehci->regs->frame_index); | ||
55 | return uf; | ||
56 | } | ||
57 | |||
58 | #endif | ||
59 | |||
39 | /*-------------------------------------------------------------------------*/ | 60 | /*-------------------------------------------------------------------------*/ |
40 | 61 | ||
41 | /* | 62 | /* |
@@ -172,7 +193,7 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe) | |||
172 | } | 193 | } |
173 | } | 194 | } |
174 | #ifdef DEBUG | 195 | #ifdef DEBUG |
175 | if (usecs > 100) | 196 | if (usecs > ehci->uframe_periodic_max) |
176 | ehci_err (ehci, "uframe %d sched overrun: %d usecs\n", | 197 | ehci_err (ehci, "uframe %d sched overrun: %d usecs\n", |
177 | frame * 8 + uframe, usecs); | 198 | frame * 8 + uframe, usecs); |
178 | #endif | 199 | #endif |
@@ -482,7 +503,7 @@ static int enable_periodic (struct ehci_hcd *ehci) | |||
482 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | 503 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; |
483 | 504 | ||
484 | /* make sure ehci_work scans these */ | 505 | /* make sure ehci_work scans these */ |
485 | ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) | 506 | ehci->next_uframe = ehci_read_frame_index(ehci) |
486 | % (ehci->periodic_size << 3); | 507 | % (ehci->periodic_size << 3); |
487 | if (unlikely(ehci->broken_periodic)) | 508 | if (unlikely(ehci->broken_periodic)) |
488 | ehci->last_periodic_enable = ktime_get_real(); | 509 | ehci->last_periodic_enable = ktime_get_real(); |
@@ -709,11 +730,8 @@ static int check_period ( | |||
709 | if (uframe >= 8) | 730 | if (uframe >= 8) |
710 | return 0; | 731 | return 0; |
711 | 732 | ||
712 | /* | 733 | /* convert "usecs we need" to "max already claimed" */ |
713 | * 80% periodic == 100 usec/uframe available | 734 | usecs = ehci->uframe_periodic_max - usecs; |
714 | * convert "usecs we need" to "max already claimed" | ||
715 | */ | ||
716 | usecs = 100 - usecs; | ||
717 | 735 | ||
718 | /* we "know" 2 and 4 uframe intervals were rejected; so | 736 | /* we "know" 2 and 4 uframe intervals were rejected; so |
719 | * for period 0, check _every_ microframe in the schedule. | 737 | * for period 0, check _every_ microframe in the schedule. |
@@ -1286,9 +1304,9 @@ itd_slot_ok ( | |||
1286 | { | 1304 | { |
1287 | uframe %= period; | 1305 | uframe %= period; |
1288 | do { | 1306 | do { |
1289 | /* can't commit more than 80% periodic == 100 usec */ | 1307 | /* can't commit more than uframe_periodic_max usec */ |
1290 | if (periodic_usecs (ehci, uframe >> 3, uframe & 0x7) | 1308 | if (periodic_usecs (ehci, uframe >> 3, uframe & 0x7) |
1291 | > (100 - usecs)) | 1309 | > (ehci->uframe_periodic_max - usecs)) |
1292 | return 0; | 1310 | return 0; |
1293 | 1311 | ||
1294 | /* we know urb->interval is 2^N uframes */ | 1312 | /* we know urb->interval is 2^N uframes */ |
@@ -1345,7 +1363,7 @@ sitd_slot_ok ( | |||
1345 | #endif | 1363 | #endif |
1346 | 1364 | ||
1347 | /* check starts (OUT uses more than one) */ | 1365 | /* check starts (OUT uses more than one) */ |
1348 | max_used = 100 - stream->usecs; | 1366 | max_used = ehci->uframe_periodic_max - stream->usecs; |
1349 | for (tmp = stream->raw_mask & 0xff; tmp; tmp >>= 1, uf++) { | 1367 | for (tmp = stream->raw_mask & 0xff; tmp; tmp >>= 1, uf++) { |
1350 | if (periodic_usecs (ehci, frame, uf) > max_used) | 1368 | if (periodic_usecs (ehci, frame, uf) > max_used) |
1351 | return 0; | 1369 | return 0; |
@@ -1354,7 +1372,7 @@ sitd_slot_ok ( | |||
1354 | /* for IN, check CSPLIT */ | 1372 | /* for IN, check CSPLIT */ |
1355 | if (stream->c_usecs) { | 1373 | if (stream->c_usecs) { |
1356 | uf = uframe & 7; | 1374 | uf = uframe & 7; |
1357 | max_used = 100 - stream->c_usecs; | 1375 | max_used = ehci->uframe_periodic_max - stream->c_usecs; |
1358 | do { | 1376 | do { |
1359 | tmp = 1 << uf; | 1377 | tmp = 1 << uf; |
1360 | tmp <<= 8; | 1378 | tmp <<= 8; |
@@ -1412,7 +1430,7 @@ iso_stream_schedule ( | |||
1412 | goto fail; | 1430 | goto fail; |
1413 | } | 1431 | } |
1414 | 1432 | ||
1415 | now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1); | 1433 | now = ehci_read_frame_index(ehci) & (mod - 1); |
1416 | 1434 | ||
1417 | /* Typical case: reuse current schedule, stream is still active. | 1435 | /* Typical case: reuse current schedule, stream is still active. |
1418 | * Hopefully there are no gaps from the host falling behind | 1436 | * Hopefully there are no gaps from the host falling behind |
@@ -1458,30 +1476,36 @@ iso_stream_schedule ( | |||
1458 | * jump until after the queue is primed. | 1476 | * jump until after the queue is primed. |
1459 | */ | 1477 | */ |
1460 | else { | 1478 | else { |
1479 | int done = 0; | ||
1461 | start = SCHEDULE_SLOP + (now & ~0x07); | 1480 | start = SCHEDULE_SLOP + (now & ~0x07); |
1462 | 1481 | ||
1463 | /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ | 1482 | /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ |
1464 | 1483 | ||
1465 | /* find a uframe slot with enough bandwidth */ | 1484 | /* find a uframe slot with enough bandwidth. |
1466 | next = start + period; | 1485 | * Early uframes are more precious because full-speed |
1467 | for (; start < next; start++) { | 1486 | * iso IN transfers can't use late uframes, |
1468 | 1487 | * and therefore they should be allocated last. | |
1488 | */ | ||
1489 | next = start; | ||
1490 | start += period; | ||
1491 | do { | ||
1492 | start--; | ||
1469 | /* check schedule: enough space? */ | 1493 | /* check schedule: enough space? */ |
1470 | if (stream->highspeed) { | 1494 | if (stream->highspeed) { |
1471 | if (itd_slot_ok(ehci, mod, start, | 1495 | if (itd_slot_ok(ehci, mod, start, |
1472 | stream->usecs, period)) | 1496 | stream->usecs, period)) |
1473 | break; | 1497 | done = 1; |
1474 | } else { | 1498 | } else { |
1475 | if ((start % 8) >= 6) | 1499 | if ((start % 8) >= 6) |
1476 | continue; | 1500 | continue; |
1477 | if (sitd_slot_ok(ehci, mod, stream, | 1501 | if (sitd_slot_ok(ehci, mod, stream, |
1478 | start, sched, period)) | 1502 | start, sched, period)) |
1479 | break; | 1503 | done = 1; |
1480 | } | 1504 | } |
1481 | } | 1505 | } while (start > next && !done); |
1482 | 1506 | ||
1483 | /* no room in the schedule */ | 1507 | /* no room in the schedule */ |
1484 | if (start == next) { | 1508 | if (!done) { |
1485 | ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n", | 1509 | ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n", |
1486 | urb, now, now + mod); | 1510 | urb, now, now + mod); |
1487 | status = -ENOSPC; | 1511 | status = -ENOSPC; |
@@ -2279,7 +2303,7 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2279 | */ | 2303 | */ |
2280 | now_uframe = ehci->next_uframe; | 2304 | now_uframe = ehci->next_uframe; |
2281 | if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | 2305 | if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { |
2282 | clock = ehci_readl(ehci, &ehci->regs->frame_index); | 2306 | clock = ehci_read_frame_index(ehci); |
2283 | clock_frame = (clock >> 3) & (ehci->periodic_size - 1); | 2307 | clock_frame = (clock >> 3) & (ehci->periodic_size - 1); |
2284 | } else { | 2308 | } else { |
2285 | clock = now_uframe + mod - 1; | 2309 | clock = now_uframe + mod - 1; |
@@ -2458,8 +2482,7 @@ restart: | |||
2458 | || ehci->periodic_sched == 0) | 2482 | || ehci->periodic_sched == 0) |
2459 | break; | 2483 | break; |
2460 | ehci->next_uframe = now_uframe; | 2484 | ehci->next_uframe = now_uframe; |
2461 | now = ehci_readl(ehci, &ehci->regs->frame_index) & | 2485 | now = ehci_read_frame_index(ehci) & (mod - 1); |
2462 | (mod - 1); | ||
2463 | if (now_uframe == now) | 2486 | if (now_uframe == now) |
2464 | break; | 2487 | break; |
2465 | 2488 | ||