aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r--drivers/usb/host/ehci-sched.c182
1 files changed, 85 insertions, 97 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 805ec633a652..a92526d6e5ae 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -880,8 +880,7 @@ static int intr_submit (
880 880
881 spin_lock_irqsave (&ehci->lock, flags); 881 spin_lock_irqsave (&ehci->lock, flags);
882 882
883 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, 883 if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
884 &ehci_to_hcd(ehci)->flags))) {
885 status = -ESHUTDOWN; 884 status = -ESHUTDOWN;
886 goto done_not_linked; 885 goto done_not_linked;
887 } 886 }
@@ -1075,15 +1074,6 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
1075 if (stream->ep) 1074 if (stream->ep)
1076 stream->ep->hcpriv = NULL; 1075 stream->ep->hcpriv = NULL;
1077 1076
1078 if (stream->rescheduled) {
1079 ehci_info (ehci, "ep%d%s-iso rescheduled "
1080 "%lu times in %lu seconds\n",
1081 stream->bEndpointAddress, is_in ? "in" : "out",
1082 stream->rescheduled,
1083 ((jiffies - stream->start)/HZ)
1084 );
1085 }
1086
1087 kfree(stream); 1077 kfree(stream);
1088 } 1078 }
1089} 1079}
@@ -1396,30 +1386,25 @@ iso_stream_schedule (
1396 struct ehci_iso_stream *stream 1386 struct ehci_iso_stream *stream
1397) 1387)
1398{ 1388{
1399 u32 now, next, start, period; 1389 u32 now, next, start, period, span;
1400 int status; 1390 int status;
1401 unsigned mod = ehci->periodic_size << 3; 1391 unsigned mod = ehci->periodic_size << 3;
1402 struct ehci_iso_sched *sched = urb->hcpriv; 1392 struct ehci_iso_sched *sched = urb->hcpriv;
1403 struct pci_dev *pdev;
1404 1393
1405 if (sched->span > (mod - SCHEDULE_SLOP)) { 1394 period = urb->interval;
1406 ehci_dbg (ehci, "iso request %p too long\n", urb); 1395 span = sched->span;
1407 status = -EFBIG; 1396 if (!stream->highspeed) {
1408 goto fail; 1397 period <<= 3;
1398 span <<= 3;
1409 } 1399 }
1410 1400
1411 if ((stream->depth + sched->span) > mod) { 1401 if (span > mod - SCHEDULE_SLOP) {
1412 ehci_dbg (ehci, "request %p would overflow (%d+%d>%d)\n", 1402 ehci_dbg (ehci, "iso request %p too long\n", urb);
1413 urb, stream->depth, sched->span, mod);
1414 status = -EFBIG; 1403 status = -EFBIG;
1415 goto fail; 1404 goto fail;
1416 } 1405 }
1417 1406
1418 period = urb->interval; 1407 now = ehci_readl(ehci, &ehci->regs->frame_index) & (mod - 1);
1419 if (!stream->highspeed)
1420 period <<= 3;
1421
1422 now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
1423 1408
1424 /* Typical case: reuse current schedule, stream is still active. 1409 /* Typical case: reuse current schedule, stream is still active.
1425 * Hopefully there are no gaps from the host falling behind 1410 * Hopefully there are no gaps from the host falling behind
@@ -1427,34 +1412,35 @@ iso_stream_schedule (
1427 * slot in the schedule, implicitly assuming URB_ISO_ASAP. 1412 * slot in the schedule, implicitly assuming URB_ISO_ASAP.
1428 */ 1413 */
1429 if (likely (!list_empty (&stream->td_list))) { 1414 if (likely (!list_empty (&stream->td_list))) {
1430 pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); 1415 u32 excess;
1431 start = stream->next_uframe;
1432 1416
1433 /* For high speed devices, allow scheduling within the 1417 /* For high speed devices, allow scheduling within the
1434 * isochronous scheduling threshold. For full speed devices, 1418 * isochronous scheduling threshold. For full speed devices
1435 * don't. (Work around for Intel ICH9 bug.) 1419 * and Intel PCI-based controllers, don't (work around for
1420 * Intel ICH9 bug).
1436 */ 1421 */
1437 if (!stream->highspeed && 1422 if (!stream->highspeed && ehci->fs_i_thresh)
1438 pdev->vendor == PCI_VENDOR_ID_INTEL)
1439 next = now + ehci->i_thresh; 1423 next = now + ehci->i_thresh;
1440 else 1424 else
1441 next = now; 1425 next = now;
1442 1426
1443 /* Fell behind (by up to twice the slop amount)? */ 1427 /* Fell behind (by up to twice the slop amount)?
1444 if (((start - next) & (mod - 1)) >= 1428 * We decide based on the time of the last currently-scheduled
1445 mod - 2 * SCHEDULE_SLOP) 1429 * slot, not the time of the next available slot.
1446 start += period * DIV_ROUND_UP( 1430 */
1447 (next - start) & (mod - 1), 1431 excess = (stream->next_uframe - period - next) & (mod - 1);
1448 period); 1432 if (excess >= mod - 2 * SCHEDULE_SLOP)
1449 1433 start = next + excess - mod + period *
1450 /* Tried to schedule too far into the future? */ 1434 DIV_ROUND_UP(mod - excess, period);
1451 if (unlikely(((start - now) & (mod - 1)) + sched->span 1435 else
1452 >= mod - 2 * SCHEDULE_SLOP)) { 1436 start = next + excess + period;
1437 if (start - now >= mod) {
1438 ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
1439 urb, start - now - period, period,
1440 mod);
1453 status = -EFBIG; 1441 status = -EFBIG;
1454 goto fail; 1442 goto fail;
1455 } 1443 }
1456 stream->next_uframe = start;
1457 goto ready;
1458 } 1444 }
1459 1445
1460 /* need to schedule; when's the next (u)frame we could start? 1446 /* need to schedule; when's the next (u)frame we could start?
@@ -1463,51 +1449,60 @@ iso_stream_schedule (
1463 * can also help high bandwidth if the dma and irq loads don't 1449 * can also help high bandwidth if the dma and irq loads don't
1464 * jump until after the queue is primed. 1450 * jump until after the queue is primed.
1465 */ 1451 */
1466 start = SCHEDULE_SLOP + (now & ~0x07); 1452 else {
1467 start %= mod; 1453 start = SCHEDULE_SLOP + (now & ~0x07);
1468 stream->next_uframe = start; 1454
1469 1455 /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
1470 /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ 1456
1471 1457 /* find a uframe slot with enough bandwidth */
1472 /* find a uframe slot with enough bandwidth */ 1458 next = start + period;
1473 for (; start < (stream->next_uframe + period); start++) { 1459 for (; start < next; start++) {
1474 int enough_space; 1460
1475 1461 /* check schedule: enough space? */
1476 /* check schedule: enough space? */ 1462 if (stream->highspeed) {
1477 if (stream->highspeed) 1463 if (itd_slot_ok(ehci, mod, start,
1478 enough_space = itd_slot_ok (ehci, mod, start, 1464 stream->usecs, period))
1479 stream->usecs, period); 1465 break;
1480 else { 1466 } else {
1481 if ((start % 8) >= 6) 1467 if ((start % 8) >= 6)
1482 continue; 1468 continue;
1483 enough_space = sitd_slot_ok (ehci, mod, stream, 1469 if (sitd_slot_ok(ehci, mod, stream,
1484 start, sched, period); 1470 start, sched, period))
1471 break;
1472 }
1485 } 1473 }
1486 1474
1487 /* schedule it here if there's enough bandwidth */ 1475 /* no room in the schedule */
1488 if (enough_space) { 1476 if (start == next) {
1489 stream->next_uframe = start % mod; 1477 ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
1490 goto ready; 1478 urb, now, now + mod);
1479 status = -ENOSPC;
1480 goto fail;
1491 } 1481 }
1492 } 1482 }
1493 1483
1494 /* no room in the schedule */ 1484 /* Tried to schedule too far into the future? */
1495 ehci_dbg (ehci, "iso %ssched full %p (now %d max %d)\n", 1485 if (unlikely(start - now + span - period
1496 list_empty (&stream->td_list) ? "" : "re", 1486 >= mod - 2 * SCHEDULE_SLOP)) {
1497 urb, now, now + mod); 1487 ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n",
1498 status = -ENOSPC; 1488 urb, start - now, span - period,
1489 mod - 2 * SCHEDULE_SLOP);
1490 status = -EFBIG;
1491 goto fail;
1492 }
1499 1493
1500fail: 1494 stream->next_uframe = start & (mod - 1);
1501 iso_sched_free (stream, sched);
1502 urb->hcpriv = NULL;
1503 return status;
1504 1495
1505ready:
1506 /* report high speed start in uframes; full speed, in frames */ 1496 /* report high speed start in uframes; full speed, in frames */
1507 urb->start_frame = stream->next_uframe; 1497 urb->start_frame = stream->next_uframe;
1508 if (!stream->highspeed) 1498 if (!stream->highspeed)
1509 urb->start_frame >>= 3; 1499 urb->start_frame >>= 3;
1510 return 0; 1500 return 0;
1501
1502 fail:
1503 iso_sched_free(stream, sched);
1504 urb->hcpriv = NULL;
1505 return status;
1511} 1506}
1512 1507
1513/*-------------------------------------------------------------------------*/ 1508/*-------------------------------------------------------------------------*/
@@ -1602,7 +1597,7 @@ itd_link_urb (
1602 struct ehci_iso_sched *iso_sched = urb->hcpriv; 1597 struct ehci_iso_sched *iso_sched = urb->hcpriv;
1603 struct ehci_itd *itd; 1598 struct ehci_itd *itd;
1604 1599
1605 next_uframe = stream->next_uframe % mod; 1600 next_uframe = stream->next_uframe & (mod - 1);
1606 1601
1607 if (unlikely (list_empty(&stream->td_list))) { 1602 if (unlikely (list_empty(&stream->td_list))) {
1608 ehci_to_hcd(ehci)->self.bandwidth_allocated 1603 ehci_to_hcd(ehci)->self.bandwidth_allocated
@@ -1613,7 +1608,6 @@ itd_link_urb (
1613 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out", 1608 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
1614 urb->interval, 1609 urb->interval,
1615 next_uframe >> 3, next_uframe & 0x7); 1610 next_uframe >> 3, next_uframe & 0x7);
1616 stream->start = jiffies;
1617 } 1611 }
1618 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; 1612 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
1619 1613
@@ -1639,14 +1633,13 @@ itd_link_urb (
1639 itd_patch(ehci, itd, iso_sched, packet, uframe); 1633 itd_patch(ehci, itd, iso_sched, packet, uframe);
1640 1634
1641 next_uframe += stream->interval; 1635 next_uframe += stream->interval;
1642 stream->depth += stream->interval; 1636 next_uframe &= mod - 1;
1643 next_uframe %= mod;
1644 packet++; 1637 packet++;
1645 1638
1646 /* link completed itds into the schedule */ 1639 /* link completed itds into the schedule */
1647 if (((next_uframe >> 3) != frame) 1640 if (((next_uframe >> 3) != frame)
1648 || packet == urb->number_of_packets) { 1641 || packet == urb->number_of_packets) {
1649 itd_link (ehci, frame % ehci->periodic_size, itd); 1642 itd_link(ehci, frame & (ehci->periodic_size - 1), itd);
1650 itd = NULL; 1643 itd = NULL;
1651 } 1644 }
1652 } 1645 }
@@ -1695,7 +1688,6 @@ itd_complete (
1695 1688
1696 t = hc32_to_cpup(ehci, &itd->hw_transaction [uframe]); 1689 t = hc32_to_cpup(ehci, &itd->hw_transaction [uframe]);
1697 itd->hw_transaction [uframe] = 0; 1690 itd->hw_transaction [uframe] = 0;
1698 stream->depth -= stream->interval;
1699 1691
1700 /* report transfer status */ 1692 /* report transfer status */
1701 if (unlikely (t & ISO_ERRS)) { 1693 if (unlikely (t & ISO_ERRS)) {
@@ -1815,8 +1807,7 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
1815 1807
1816 /* schedule ... need to lock */ 1808 /* schedule ... need to lock */
1817 spin_lock_irqsave (&ehci->lock, flags); 1809 spin_lock_irqsave (&ehci->lock, flags);
1818 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, 1810 if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
1819 &ehci_to_hcd(ehci)->flags))) {
1820 status = -ESHUTDOWN; 1811 status = -ESHUTDOWN;
1821 goto done_not_linked; 1812 goto done_not_linked;
1822 } 1813 }
@@ -2024,9 +2015,8 @@ sitd_link_urb (
2024 "sched devp %s ep%d%s-iso [%d] %dms/%04x\n", 2015 "sched devp %s ep%d%s-iso [%d] %dms/%04x\n",
2025 urb->dev->devpath, stream->bEndpointAddress & 0x0f, 2016 urb->dev->devpath, stream->bEndpointAddress & 0x0f,
2026 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out", 2017 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
2027 (next_uframe >> 3) % ehci->periodic_size, 2018 (next_uframe >> 3) & (ehci->periodic_size - 1),
2028 stream->interval, hc32_to_cpu(ehci, stream->splits)); 2019 stream->interval, hc32_to_cpu(ehci, stream->splits));
2029 stream->start = jiffies;
2030 } 2020 }
2031 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; 2021 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
2032 2022
@@ -2047,13 +2037,12 @@ sitd_link_urb (
2047 sitd->urb = urb; 2037 sitd->urb = urb;
2048 2038
2049 sitd_patch(ehci, stream, sitd, sched, packet); 2039 sitd_patch(ehci, stream, sitd, sched, packet);
2050 sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, 2040 sitd_link(ehci, (next_uframe >> 3) & (ehci->periodic_size - 1),
2051 sitd); 2041 sitd);
2052 2042
2053 next_uframe += stream->interval << 3; 2043 next_uframe += stream->interval << 3;
2054 stream->depth += stream->interval << 3;
2055 } 2044 }
2056 stream->next_uframe = next_uframe % mod; 2045 stream->next_uframe = next_uframe & (mod - 1);
2057 2046
2058 /* don't need that schedule data any more */ 2047 /* don't need that schedule data any more */
2059 iso_sched_free (stream, sched); 2048 iso_sched_free (stream, sched);
@@ -2111,7 +2100,6 @@ sitd_complete (
2111 desc->actual_length = desc->length - SITD_LENGTH(t); 2100 desc->actual_length = desc->length - SITD_LENGTH(t);
2112 urb->actual_length += desc->actual_length; 2101 urb->actual_length += desc->actual_length;
2113 } 2102 }
2114 stream->depth -= stream->interval << 3;
2115 2103
2116 /* handle completion now? */ 2104 /* handle completion now? */
2117 if ((urb_index + 1) != urb->number_of_packets) 2105 if ((urb_index + 1) != urb->number_of_packets)
@@ -2201,8 +2189,7 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
2201 2189
2202 /* schedule ... need to lock */ 2190 /* schedule ... need to lock */
2203 spin_lock_irqsave (&ehci->lock, flags); 2191 spin_lock_irqsave (&ehci->lock, flags);
2204 if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, 2192 if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) {
2205 &ehci_to_hcd(ehci)->flags))) {
2206 status = -ESHUTDOWN; 2193 status = -ESHUTDOWN;
2207 goto done_not_linked; 2194 goto done_not_linked;
2208 } 2195 }
@@ -2263,7 +2250,7 @@ scan_periodic (struct ehci_hcd *ehci)
2263 now_uframe = ehci->next_uframe; 2250 now_uframe = ehci->next_uframe;
2264 if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { 2251 if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
2265 clock = ehci_readl(ehci, &ehci->regs->frame_index); 2252 clock = ehci_readl(ehci, &ehci->regs->frame_index);
2266 clock_frame = (clock >> 3) % ehci->periodic_size; 2253 clock_frame = (clock >> 3) & (ehci->periodic_size - 1);
2267 } else { 2254 } else {
2268 clock = now_uframe + mod - 1; 2255 clock = now_uframe + mod - 1;
2269 clock_frame = -1; 2256 clock_frame = -1;
@@ -2272,7 +2259,7 @@ scan_periodic (struct ehci_hcd *ehci)
2272 free_cached_lists(ehci); 2259 free_cached_lists(ehci);
2273 ehci->clock_frame = clock_frame; 2260 ehci->clock_frame = clock_frame;
2274 } 2261 }
2275 clock %= mod; 2262 clock &= mod - 1;
2276 clock_frame = clock >> 3; 2263 clock_frame = clock >> 3;
2277 2264
2278 for (;;) { 2265 for (;;) {
@@ -2361,7 +2348,7 @@ restart:
2361 * frame is current. 2348 * frame is current.
2362 */ 2349 */
2363 if (((frame == clock_frame) || 2350 if (((frame == clock_frame) ||
2364 (((frame + 1) % ehci->periodic_size) 2351 (((frame + 1) & (ehci->periodic_size - 1))
2365 == clock_frame)) 2352 == clock_frame))
2366 && live 2353 && live
2367 && (q.sitd->hw_results & 2354 && (q.sitd->hw_results &
@@ -2428,7 +2415,8 @@ restart:
2428 || ehci->periodic_sched == 0) 2415 || ehci->periodic_sched == 0)
2429 break; 2416 break;
2430 ehci->next_uframe = now_uframe; 2417 ehci->next_uframe = now_uframe;
2431 now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; 2418 now = ehci_readl(ehci, &ehci->regs->frame_index) &
2419 (mod - 1);
2432 if (now_uframe == now) 2420 if (now_uframe == now)
2433 break; 2421 break;
2434 2422
@@ -2441,7 +2429,7 @@ restart:
2441 } 2429 }
2442 } else { 2430 } else {
2443 now_uframe++; 2431 now_uframe++;
2444 now_uframe %= mod; 2432 now_uframe &= mod - 1;
2445 } 2433 }
2446 } 2434 }
2447} 2435}