Revision 26d53979

b/hw/usb-ehci.c
33 33
#include "trace.h"
34 34

  
35 35
#define EHCI_DEBUG   0
36
#define STATE_DEBUG  0       /* state transitions  */
37 36

  
38
#if EHCI_DEBUG || STATE_DEBUG
37
#if EHCI_DEBUG
39 38
#define DPRINTF printf
40 39
#else
41 40
#define DPRINTF(...)
42 41
#endif
43 42

  
44
#if STATE_DEBUG
45
#define DPRINTF_ST DPRINTF
46
#else
47
#define DPRINTF_ST(...)
48
#endif
49

  
50 43
/* internal processing - reset HC to try and recover */
51 44
#define USB_RET_PROCERR   (-99)
52 45

  
......
417 410
    *data = val; \
418 411
    } while(0)
419 412

  
413
static const char *ehci_state_names[] = {
414
    [ EST_INACTIVE ]     = "INACTIVE",
415
    [ EST_ACTIVE ]       = "ACTIVE",
416
    [ EST_EXECUTING ]    = "EXECUTING",
417
    [ EST_SLEEPING ]     = "SLEEPING",
418
    [ EST_WAITLISTHEAD ] = "WAITLISTHEAD",
419
    [ EST_FETCHENTRY ]   = "FETCH ENTRY",
420
    [ EST_FETCHQH ]      = "FETCH QH",
421
    [ EST_FETCHITD ]     = "FETCH ITD",
422
    [ EST_ADVANCEQUEUE ] = "ADVANCEQUEUE",
423
    [ EST_FETCHQTD ]     = "FETCH QTD",
424
    [ EST_EXECUTE ]      = "EXECUTE",
425
    [ EST_WRITEBACK ]    = "WRITEBACK",
426
    [ EST_HORIZONTALQH ] = "HORIZONTALQH",
427
};
428

  
429
static const char *ehci_mmio_names[] = {
430
    [ CAPLENGTH ]        = "CAPLENGTH",
431
    [ HCIVERSION ]       = "HCIVERSION",
432
    [ HCSPARAMS ]        = "HCSPARAMS",
433
    [ HCCPARAMS ]        = "HCCPARAMS",
434
    [ USBCMD ]           = "USBCMD",
435
    [ USBSTS ]           = "USBSTS",
436
    [ USBINTR ]          = "USBINTR",
437
    [ FRINDEX ]          = "FRINDEX",
438
    [ PERIODICLISTBASE ] = "P-LIST BASE",
439
    [ ASYNCLISTADDR ]    = "A-LIST ADDR",
440
    [ PORTSC_BEGIN ]     = "PORTSC #0",
441
    [ PORTSC_BEGIN + 4]  = "PORTSC #1",
442
    [ PORTSC_BEGIN + 8]  = "PORTSC #2",
443
    [ PORTSC_BEGIN + 12] = "PORTSC #3",
444
    [ CONFIGFLAG ]       = "CONFIGFLAG",
445
};
420 446

  
421
static const char *addr2str(target_phys_addr_t addr)
447
static const char *nr2str(const char **n, size_t len, uint32_t nr)
422 448
{
423
    const char *r            = "unknown";
424
    const char *n[] = {
425
        [ CAPLENGTH ]        = "CAPLENGTH",
426
        [ HCIVERSION ]       = "HCIVERSION",
427
        [ HCSPARAMS ]        = "HCSPARAMS",
428
        [ HCCPARAMS ]        = "HCCPARAMS",
429
        [ USBCMD ]           = "USBCMD",
430
        [ USBSTS ]           = "USBSTS",
431
        [ USBINTR ]          = "USBINTR",
432
        [ FRINDEX ]          = "FRINDEX",
433
        [ PERIODICLISTBASE ] = "P-LIST BASE",
434
        [ ASYNCLISTADDR ]    = "A-LIST ADDR",
435
        [ PORTSC_BEGIN ...
436
          PORTSC_END ]       = "PORTSC",
437
        [ CONFIGFLAG ]       = "CONFIGFLAG",
438
    };
439

  
440
    if (addr < ARRAY_SIZE(n) && n[addr] != NULL) {
441
        return n[addr];
449
    if (nr < len && n[nr] != NULL) {
450
        return n[nr];
442 451
    } else {
443
        return r;
452
        return "unknown";
444 453
    }
445 454
}
446 455

  
456
static const char *state2str(uint32_t state)
457
{
458
    return nr2str(ehci_state_names, ARRAY_SIZE(ehci_state_names), state);
459
}
460

  
461
static const char *addr2str(target_phys_addr_t addr)
462
{
463
    return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names), addr);
464
}
465

  
447 466
static void ehci_trace_usbsts(uint32_t mask, int state)
448 467
{
449 468
    /* interrupts */
......
528 547
    s->usbsts_pending = 0;
529 548
}
530 549

  
550
static void ehci_set_state(EHCIState *s, int async, int state)
551
{
552
    if (async) {
553
        trace_usb_ehci_state("async", state2str(state));
554
        s->astate = state;
555
    } else {
556
        trace_usb_ehci_state("periodic", state2str(state));
557
        s->pstate = state;
558
    }
559
}
560

  
561
static int ehci_get_state(EHCIState *s, int async)
562
{
563
    return async ? s->astate : s->pstate;
564
}
565

  
566
static void ehci_trace_qh(EHCIState *s, target_phys_addr_t addr, EHCIqh *qh)
567
{
568
    trace_usb_ehci_qh(addr, qh->next,
569
                      qh->current_qtd, qh->next_qtd, qh->altnext_qtd,
570
                      get_field(qh->epchar, QH_EPCHAR_RL),
571
                      get_field(qh->epchar, QH_EPCHAR_MPLEN),
572
                      get_field(qh->epchar, QH_EPCHAR_EPS),
573
                      get_field(qh->epchar, QH_EPCHAR_EP),
574
                      get_field(qh->epchar, QH_EPCHAR_DEVADDR),
575
                      (bool)(qh->epchar & QH_EPCHAR_C),
576
                      (bool)(qh->epchar & QH_EPCHAR_H),
577
                      (bool)(qh->epchar & QH_EPCHAR_DTC),
578
                      (bool)(qh->epchar & QH_EPCHAR_I));
579
}
580

  
581
static void ehci_trace_qtd(EHCIState *s, target_phys_addr_t addr, EHCIqtd *qtd)
582
{
583
    trace_usb_ehci_qtd(addr, qtd->next, qtd->altnext,
584
                       get_field(qtd->token, QTD_TOKEN_TBYTES),
585
                       get_field(qtd->token, QTD_TOKEN_CPAGE),
586
                       get_field(qtd->token, QTD_TOKEN_CERR),
587
                       get_field(qtd->token, QTD_TOKEN_PID),
588
                       (bool)(qtd->token & QTD_TOKEN_IOC),
589
                       (bool)(qtd->token & QTD_TOKEN_ACTIVE),
590
                       (bool)(qtd->token & QTD_TOKEN_HALT),
591
                       (bool)(qtd->token & QTD_TOKEN_BABBLE),
592
                       (bool)(qtd->token & QTD_TOKEN_XACTERR));
593
}
594

  
595
static void ehci_trace_itd(EHCIState *s, target_phys_addr_t addr, EHCIitd *itd)
596
{
597
    trace_usb_ehci_itd(addr, itd->next);
598
}
599

  
531 600
/* Attach or detach a device on root hub */
532 601

  
533 602
static void ehci_attach(USBPort *port)
......
1230 1299
/*  This state is the entry point for asynchronous schedule
1231 1300
 *  processing.  Entry here consitutes a EHCI start event state (4.8.5)
1232 1301
 */
1233
static int ehci_state_waitlisthead(EHCIState *ehci,  int async, int *state)
1302
static int ehci_state_waitlisthead(EHCIState *ehci,  int async)
1234 1303
{
1235 1304
    EHCIqh *qh = &ehci->qh;
1236 1305
    int i = 0;
......
1245 1314
    /*  Find the head of the list (4.9.1.1) */
1246 1315
    for(i = 0; i < MAX_QH; i++) {
1247 1316
        get_dwords(NLPTR_GET(entry), (uint32_t *) qh, sizeof(EHCIqh) >> 2);
1317
        ehci_trace_qh(ehci, NLPTR_GET(entry), qh);
1248 1318

  
1249 1319
        if (qh->epchar & QH_EPCHAR_H) {
1250
            DPRINTF_ST("WAITLISTHEAD: QH %08X is the HEAD of the list\n",
1251
                       entry);
1252 1320
            if (async) {
1253 1321
                entry |= (NLPTR_TYPE_QH << 1);
1254 1322
            }
1255 1323

  
1256 1324
            ehci->fetch_addr = entry;
1257
            *state = EST_FETCHENTRY;
1325
            ehci_set_state(ehci, async, EST_FETCHENTRY);
1258 1326
            again = 1;
1259 1327
            goto out;
1260 1328
        }
1261 1329

  
1262
        DPRINTF_ST("WAITLISTHEAD: QH %08X is NOT the HEAD of the list\n",
1263
                   entry);
1264 1330
        entry = qh->next;
1265 1331
        if (entry == ehci->asynclistaddr) {
1266
            DPRINTF("WAITLISTHEAD: reached beginning of QH list\n");
1267 1332
            break;
1268 1333
        }
1269 1334
    }
1270 1335

  
1271 1336
    /* no head found for list. */
1272 1337

  
1273
    *state = EST_ACTIVE;
1338
    ehci_set_state(ehci, async, EST_ACTIVE);
1274 1339

  
1275 1340
out:
1276 1341
    return again;
......
1280 1345
/*  This state is the entry point for periodic schedule processing as
1281 1346
 *  well as being a continuation state for async processing.
1282 1347
 */
1283
static int ehci_state_fetchentry(EHCIState *ehci, int async, int *state)
1348
static int ehci_state_fetchentry(EHCIState *ehci, int async)
1284 1349
{
1285 1350
    int again = 0;
1286 1351
    uint32_t entry = ehci->fetch_addr;
......
1298 1363
#endif
1299 1364
    if (entry < 0x1000) {
1300 1365
        DPRINTF("fetchentry: entry invalid (0x%08x)\n", entry);
1301
        *state = EST_ACTIVE;
1366
        ehci_set_state(ehci, async, EST_ACTIVE);
1302 1367
        goto out;
1303 1368
    }
1304 1369

  
......
1310 1375

  
1311 1376
    switch (NLPTR_TYPE_GET(entry)) {
1312 1377
    case NLPTR_TYPE_QH:
1313
        DPRINTF_ST("FETCHENTRY: entry %X is a Queue Head\n", entry);
1314
        *state = EST_FETCHQH;
1378
        ehci_set_state(ehci, async, EST_FETCHQH);
1315 1379
        ehci->qhaddr = entry;
1316 1380
        again = 1;
1317 1381
        break;
1318 1382

  
1319 1383
    case NLPTR_TYPE_ITD:
1320
        DPRINTF_ST("FETCHENTRY: entry %X is an ITD\n", entry);
1321
        *state = EST_FETCHITD;
1384
        ehci_set_state(ehci, async, EST_FETCHITD);
1322 1385
        ehci->itdaddr = entry;
1323 1386
        again = 1;
1324 1387
        break;
......
1334 1397
    return again;
1335 1398
}
1336 1399

  
1337
static int ehci_state_fetchqh(EHCIState *ehci, int async, int *state)
1400
static int ehci_state_fetchqh(EHCIState *ehci, int async)
1338 1401
{
1339 1402
    EHCIqh *qh = &ehci->qh;
1340 1403
    int reload;
1341 1404
    int again = 0;
1342 1405

  
1343 1406
    get_dwords(NLPTR_GET(ehci->qhaddr), (uint32_t *) qh, sizeof(EHCIqh) >> 2);
1407
    ehci_trace_qh(ehci, NLPTR_GET(ehci->qhaddr), qh);
1344 1408

  
1345 1409
    if (async && (qh->epchar & QH_EPCHAR_H)) {
1346 1410

  
......
1350 1414
        } else {
1351 1415
            DPRINTF("FETCHQH:  QH 0x%08x. H-bit set, reclamation status reset"
1352 1416
                       " - done processing\n", ehci->qhaddr);
1353
            *state = EST_ACTIVE;
1417
            ehci_set_state(ehci, async, EST_ACTIVE);
1354 1418
            goto out;
1355 1419
        }
1356 1420
    }
......
1368 1432

  
1369 1433
    reload = get_field(qh->epchar, QH_EPCHAR_RL);
1370 1434
    if (reload) {
1371
        DPRINTF_ST("FETCHQH: reloading nakcnt to %d\n", reload);
1372 1435
        set_field(&qh->altnext_qtd, reload, QH_ALTNEXT_NAKCNT);
1373 1436
    }
1374 1437

  
1375 1438
    if (qh->token & QTD_TOKEN_HALT) {
1376
        DPRINTF_ST("FETCHQH: QH Halted, go horizontal\n");
1377
        *state = EST_HORIZONTALQH;
1439
        ehci_set_state(ehci, async, EST_HORIZONTALQH);
1378 1440
        again = 1;
1379 1441

  
1380 1442
    } else if ((qh->token & QTD_TOKEN_ACTIVE) && (qh->current_qtd > 0x1000)) {
1381
        DPRINTF_ST("FETCHQH: Active, !Halt, execute - fetch qTD\n");
1382 1443
        ehci->qtdaddr = qh->current_qtd;
1383
        *state = EST_FETCHQTD;
1444
        ehci_set_state(ehci, async, EST_FETCHQTD);
1384 1445
        again = 1;
1385 1446

  
1386 1447
    } else {
1387 1448
        /*  EHCI spec version 1.0 Section 4.10.2 */
1388
        DPRINTF_ST("FETCHQH: !Active, !Halt, advance queue\n");
1389
        *state = EST_ADVANCEQUEUE;
1449
        ehci_set_state(ehci, async, EST_ADVANCEQUEUE);
1390 1450
        again = 1;
1391 1451
    }
1392 1452

  
......
1394 1454
    return again;
1395 1455
}
1396 1456

  
1397
static int ehci_state_fetchitd(EHCIState *ehci, int async, int *state)
1457
static int ehci_state_fetchitd(EHCIState *ehci, int async)
1398 1458
{
1399 1459
    EHCIitd itd;
1400 1460

  
1401 1461
    get_dwords(NLPTR_GET(ehci->itdaddr),(uint32_t *) &itd,
1402 1462
               sizeof(EHCIitd) >> 2);
1403
    DPRINTF_ST("FETCHITD: Fetched ITD at address %08X " "(next is %08X)\n",
1404
               ehci->itdaddr, itd.next);
1463
    ehci_trace_itd(ehci, ehci->itdaddr, &itd);
1405 1464

  
1406 1465
    if (ehci_process_itd(ehci, &itd) != 0) {
1407 1466
        return -1;
......
1410 1469
    put_dwords(NLPTR_GET(ehci->itdaddr), (uint32_t *) &itd,
1411 1470
                sizeof(EHCIitd) >> 2);
1412 1471
    ehci->fetch_addr = itd.next;
1413
    *state = EST_FETCHENTRY;
1472
    ehci_set_state(ehci, async, EST_FETCHENTRY);
1414 1473

  
1415 1474
    return 1;
1416 1475
}
1417 1476

  
1418 1477
/* Section 4.10.2 - paragraph 3 */
1419
static int ehci_state_advqueue(EHCIState *ehci, int async, int *state)
1478
static int ehci_state_advqueue(EHCIState *ehci, int async)
1420 1479
{
1421 1480
#if 0
1422 1481
    /* TO-DO: 4.10.2 - paragraph 2
......
1424 1483
     * go to horizontal QH
1425 1484
     */
1426 1485
    if (I-bit set) {
1427
        *state = EST_HORIZONTALQH;
1486
        ehci_set_state(ehci, async, EST_HORIZONTALQH);
1428 1487
        goto out;
1429 1488
    }
1430 1489
#endif
......
1435 1494
    if (((ehci->qh.token & QTD_TOKEN_TBYTES_MASK) != 0) &&
1436 1495
        (ehci->qh.altnext_qtd > 0x1000) &&
1437 1496
        (NLPTR_TBIT(ehci->qh.altnext_qtd) == 0)) {
1438
        DPRINTF_ST("ADVQUEUE: goto alt next qTD. "
1439
                   "curr 0x%08x next 0x%08x alt 0x%08x (next qh %x)\n",
1440
                   ehci->qh.current_qtd, ehci->qh.altnext_qtd,
1441
                   ehci->qh.next_qtd, ehci->qh.next);
1442 1497
        ehci->qtdaddr = ehci->qh.altnext_qtd;
1443
        *state = EST_FETCHQTD;
1498
        ehci_set_state(ehci, async, EST_FETCHQTD);
1444 1499

  
1445 1500
    /*
1446 1501
     *  next qTD is valid
1447 1502
     */
1448 1503
    } else if ((ehci->qh.next_qtd > 0x1000) &&
1449 1504
               (NLPTR_TBIT(ehci->qh.next_qtd) == 0)) {
1450
        DPRINTF_ST("ADVQUEUE: next qTD. "
1451
                   "curr 0x%08x next 0x%08x alt 0x%08x (next qh %x)\n",
1452
                   ehci->qh.current_qtd, ehci->qh.altnext_qtd,
1453
                   ehci->qh.next_qtd, ehci->qh.next);
1454 1505
        ehci->qtdaddr = ehci->qh.next_qtd;
1455
        *state = EST_FETCHQTD;
1506
        ehci_set_state(ehci, async, EST_FETCHQTD);
1456 1507

  
1457 1508
    /*
1458 1509
     *  no valid qTD, try next QH
1459 1510
     */
1460 1511
    } else {
1461
        DPRINTF_ST("ADVQUEUE: go to horizontal QH\n");
1462
        *state = EST_HORIZONTALQH;
1512
        ehci_set_state(ehci, async, EST_HORIZONTALQH);
1463 1513
    }
1464 1514

  
1465 1515
    return 1;
1466 1516
}
1467 1517

  
1468 1518
/* Section 4.10.2 - paragraph 4 */
1469
static int ehci_state_fetchqtd(EHCIState *ehci, int async, int *state)
1519
static int ehci_state_fetchqtd(EHCIState *ehci, int async)
1470 1520
{
1471 1521
    EHCIqtd *qtd = &ehci->qtd;
1472 1522
    int again = 0;
1473 1523

  
1474 1524
    get_dwords(NLPTR_GET(ehci->qtdaddr),(uint32_t *) qtd, sizeof(EHCIqtd) >> 2);
1525
    ehci_trace_qtd(ehci, NLPTR_GET(ehci->qtdaddr), qtd);
1475 1526

  
1476 1527
    if (qtd->token & QTD_TOKEN_ACTIVE) {
1477
        *state = EST_EXECUTE;
1528
        ehci_set_state(ehci, async, EST_EXECUTE);
1478 1529
        again = 1;
1479 1530
    } else {
1480
        *state = EST_HORIZONTALQH;
1531
        ehci_set_state(ehci, async, EST_HORIZONTALQH);
1481 1532
        again = 1;
1482 1533
    }
1483 1534

  
1484 1535
    return again;
1485 1536
}
1486 1537

  
1487
static int ehci_state_horizqh(EHCIState *ehci, int async, int *state)
1538
static int ehci_state_horizqh(EHCIState *ehci, int async)
1488 1539
{
1489 1540
    int again = 0;
1490 1541

  
1491 1542
    if (ehci->fetch_addr != ehci->qh.next) {
1492 1543
        ehci->fetch_addr = ehci->qh.next;
1493
        *state = EST_FETCHENTRY;
1544
        ehci_set_state(ehci, async, EST_FETCHENTRY);
1494 1545
        again = 1;
1495 1546
    } else {
1496
        *state = EST_ACTIVE;
1547
        ehci_set_state(ehci, async, EST_ACTIVE);
1497 1548
    }
1498 1549

  
1499 1550
    return again;
1500 1551
}
1501 1552

  
1502
static int ehci_state_execute(EHCIState *ehci, int async, int *state)
1553
static int ehci_state_execute(EHCIState *ehci, int async)
1503 1554
{
1504 1555
    EHCIqh *qh = &ehci->qh;
1505 1556
    EHCIqtd *qtd = &ehci->qtd;
......
1507 1558
    int reload, nakcnt;
1508 1559
    int smask;
1509 1560

  
1510
    if (async) {
1511
        DPRINTF_ST(">>>>> ASYNC STATE MACHINE execute QH 0x%08x, QTD 0x%08x\n",
1512
                  ehci->qhaddr, ehci->qtdaddr);
1513
    } else {
1514
        DPRINTF_ST(">>>>> PERIODIC STATE MACHINE execute\n");
1515
    }
1516

  
1517 1561
    if (ehci_qh_do_overlay(ehci, qh, qtd) != 0) {
1518 1562
        return -1;
1519 1563
    }
......
1524 1568
        reload = get_field(qh->epchar, QH_EPCHAR_RL);
1525 1569
        nakcnt = get_field(qh->altnext_qtd, QH_ALTNEXT_NAKCNT);
1526 1570
        if (reload && !nakcnt) {
1527
            DPRINTF_ST("EXECUTE: RL != 0 but NakCnt == 0 -- no execute\n");
1528
            *state = EST_HORIZONTALQH;
1571
            ehci_set_state(ehci, async, EST_HORIZONTALQH);
1529 1572
            again = 1;
1530 1573
            goto out;
1531 1574
        }
......
1538 1581
    if (!async) {
1539 1582
        int transactCtr = get_field(qh->epcap, QH_EPCAP_MULT);
1540 1583
        if (!transactCtr) {
1541
            DPRINTF("ZERO transactctr for int qh, go HORIZ\n");
1542
            *state = EST_HORIZONTALQH;
1584
            ehci_set_state(ehci, async, EST_HORIZONTALQH);
1543 1585
            again = 1;
1544 1586
            goto out;
1545 1587
        }
......
1554 1596
        again = -1;
1555 1597
        goto out;
1556 1598
    }
1557
    *state = EST_EXECUTING;
1599
    ehci_set_state(ehci, async, EST_EXECUTING);
1558 1600

  
1559 1601
    if (ehci->exec_status != USB_RET_ASYNC) {
1560 1602
        again = 1;
......
1564 1606
    return again;
1565 1607
}
1566 1608

  
1567
static int ehci_state_executing(EHCIState *ehci, int async, int *state)
1609
static int ehci_state_executing(EHCIState *ehci, int async)
1568 1610
{
1569 1611
    EHCIqh *qh = &ehci->qh;
1570 1612
    int again = 0;
......
1596 1638
            if (nakcnt) {
1597 1639
                nakcnt--;
1598 1640
            }
1599
            DPRINTF_ST("EXECUTING: Nak occured and RL != 0, dec NakCnt to %d\n",
1600
                    nakcnt);
1601 1641
        } else {
1602 1642
            nakcnt = reload;
1603
            DPRINTF_ST("EXECUTING: Nak didn't occur, reloading to %d\n",
1604
                       nakcnt);
1605 1643
        }
1606 1644
        set_field(&qh->altnext_qtd, nakcnt, QH_ALTNEXT_NAKCNT);
1607 1645
    }
......
1611 1649
     *  in the EHCI spec but we need to do it since we don't share
1612 1650
     *  physical memory with our guest VM.
1613 1651
     */
1614

  
1615
    DPRINTF("EXECUTING: write QH to VM memory: qhaddr 0x%x, next 0x%x\n",
1616
              ehci->qhaddr, qh->next);
1617 1652
    put_dwords(NLPTR_GET(ehci->qhaddr), (uint32_t *) qh, sizeof(EHCIqh) >> 2);
1618 1653

  
1619 1654
    /* 4.10.5 */
1620 1655
    if ((ehci->exec_status == USB_RET_NAK) || (qh->token & QTD_TOKEN_ACTIVE)) {
1621
        *state = EST_HORIZONTALQH;
1656
        ehci_set_state(ehci, async, EST_HORIZONTALQH);
1622 1657
    } else {
1623
        *state = EST_WRITEBACK;
1658
        ehci_set_state(ehci, async, EST_WRITEBACK);
1624 1659
    }
1625 1660

  
1626 1661
    again = 1;
......
1630 1665
}
1631 1666

  
1632 1667

  
1633
static int ehci_state_writeback(EHCIState *ehci, int async, int *state)
1668
static int ehci_state_writeback(EHCIState *ehci, int async)
1634 1669
{
1635 1670
    EHCIqh *qh = &ehci->qh;
1636 1671
    int again = 0;
1637 1672

  
1638 1673
    /*  Write back the QTD from the QH area */
1639
    DPRINTF_ST("WRITEBACK: write QTD to VM memory\n");
1674
    ehci_trace_qtd(ehci, NLPTR_GET(ehci->qtdaddr), (EHCIqtd*) &qh->next_qtd);
1640 1675
    put_dwords(NLPTR_GET(ehci->qtdaddr),(uint32_t *) &qh->next_qtd,
1641 1676
                sizeof(EHCIqtd) >> 2);
1642 1677

  
......
1644 1679
     * but stop after one qtd if periodic
1645 1680
     */
1646 1681
    //if (async) {
1647
        *state = EST_ADVANCEQUEUE;
1682
        ehci_set_state(ehci, async, EST_ADVANCEQUEUE);
1648 1683
        again = 1;
1649 1684
    //} else {
1650
    //    *state = EST_ACTIVE;
1685
    //    ehci_set_state(ehci, async, EST_ACTIVE);
1651 1686
    //}
1652 1687
    return again;
1653 1688
}
......
1656 1691
 * This is the state machine that is common to both async and periodic
1657 1692
 */
1658 1693

  
1659
static int ehci_advance_state(EHCIState *ehci,
1660
                              int async,
1661
                              int state)
1694
static void ehci_advance_state(EHCIState *ehci,
1695
                               int async)
1662 1696
{
1663 1697
    int again;
1664 1698
    int iter = 0;
1665 1699

  
1666 1700
    do {
1667
        if (state == EST_FETCHQH) {
1701
        if (ehci_get_state(ehci, async) == EST_FETCHQH) {
1668 1702
            iter++;
1669 1703
            /* if we are roaming a lot of QH without executing a qTD
1670 1704
             * something is wrong with the linked list. TO-DO: why is
......
1672 1706
             */
1673 1707
            if (iter > MAX_ITERATIONS) {
1674 1708
                DPRINTF("\n*** advance_state: bailing on MAX ITERATIONS***\n");
1675
                state = EST_ACTIVE;
1709
                ehci_set_state(ehci, async, EST_ACTIVE);
1676 1710
                break;
1677 1711
            }
1678 1712
        }
1679
        switch(state) {
1713
        switch(ehci_get_state(ehci, async)) {
1680 1714
        case EST_WAITLISTHEAD:
1681
            again = ehci_state_waitlisthead(ehci, async, &state);
1715
            again = ehci_state_waitlisthead(ehci, async);
1682 1716
            break;
1683 1717

  
1684 1718
        case EST_FETCHENTRY:
1685
            again = ehci_state_fetchentry(ehci, async, &state);
1719
            again = ehci_state_fetchentry(ehci, async);
1686 1720
            break;
1687 1721

  
1688 1722
        case EST_FETCHQH:
1689
            again = ehci_state_fetchqh(ehci, async, &state);
1723
            again = ehci_state_fetchqh(ehci, async);
1690 1724
            break;
1691 1725

  
1692 1726
        case EST_FETCHITD:
1693
            again = ehci_state_fetchitd(ehci, async, &state);
1727
            again = ehci_state_fetchitd(ehci, async);
1694 1728
            break;
1695 1729

  
1696 1730
        case EST_ADVANCEQUEUE:
1697
            again = ehci_state_advqueue(ehci, async, &state);
1731
            again = ehci_state_advqueue(ehci, async);
1698 1732
            break;
1699 1733

  
1700 1734
        case EST_FETCHQTD:
1701
            again = ehci_state_fetchqtd(ehci, async, &state);
1735
            again = ehci_state_fetchqtd(ehci, async);
1702 1736
            break;
1703 1737

  
1704 1738
        case EST_HORIZONTALQH:
1705
            again = ehci_state_horizqh(ehci, async, &state);
1739
            again = ehci_state_horizqh(ehci, async);
1706 1740
            break;
1707 1741

  
1708 1742
        case EST_EXECUTE:
1709 1743
            iter = 0;
1710
            again = ehci_state_execute(ehci, async, &state);
1744
            again = ehci_state_execute(ehci, async);
1711 1745
            break;
1712 1746

  
1713 1747
        case EST_EXECUTING:
1714
            again = ehci_state_executing(ehci, async, &state);
1748
            again = ehci_state_executing(ehci, async);
1715 1749
            break;
1716 1750

  
1717 1751
        case EST_WRITEBACK:
1718
            again = ehci_state_writeback(ehci, async, &state);
1752
            again = ehci_state_writeback(ehci, async);
1719 1753
            break;
1720 1754

  
1721 1755
        default:
......
1733 1767
    while (again);
1734 1768

  
1735 1769
    ehci_commit_interrupt(ehci);
1736
    return state;
1737 1770
}
1738 1771

  
1739 1772
static void ehci_advance_async_state(EHCIState *ehci)
1740 1773
{
1741 1774
    EHCIqh qh;
1742
    int state = ehci->astate;
1775
    int async = 1;
1743 1776

  
1744
    switch(state) {
1777
    switch(ehci_get_state(ehci, async)) {
1745 1778
    case EST_INACTIVE:
1746 1779
        if (!(ehci->usbcmd & USBCMD_ASE)) {
1747 1780
            break;
1748 1781
        }
1749 1782
        ehci_set_usbsts(ehci, USBSTS_ASS);
1750
        ehci->astate = EST_ACTIVE;
1783
        ehci_set_state(ehci, async, EST_ACTIVE);
1751 1784
        // No break, fall through to ACTIVE
1752 1785

  
1753 1786
    case EST_ACTIVE:
1754 1787
        if ( !(ehci->usbcmd & USBCMD_ASE)) {
1755 1788
            ehci_clear_usbsts(ehci, USBSTS_ASS);
1756
            ehci->astate = EST_INACTIVE;
1789
            ehci_set_state(ehci, async, EST_INACTIVE);
1757 1790
            break;
1758 1791
        }
1759 1792

  
......
1775 1808
            break;
1776 1809
        }
1777 1810

  
1778
        DPRINTF_ST("ASYNC: waiting for listhead, starting at %08x\n",
1779
                ehci->asynclistaddr);
1780 1811
        /* check that address register has been set */
1781 1812
        if (ehci->asynclistaddr == 0) {
1782 1813
            break;
1783 1814
        }
1784 1815

  
1785
        state = EST_WAITLISTHEAD;
1816
        ehci_set_state(ehci, async, EST_WAITLISTHEAD);
1786 1817
        /* fall through */
1787 1818

  
1788 1819
    case EST_FETCHENTRY:
......
1791 1822
    case EST_EXECUTING:
1792 1823
        get_dwords(NLPTR_GET(ehci->qhaddr), (uint32_t *) &qh,
1793 1824
                   sizeof(EHCIqh) >> 2);
1794
        ehci->astate = ehci_advance_state(ehci, 1, state);
1825
        ehci_advance_state(ehci, async);
1795 1826
        break;
1796 1827

  
1797 1828
    default:
1798 1829
        /* this should only be due to a developer mistake */
1799 1830
        fprintf(stderr, "ehci: Bad asynchronous state %d. "
1800 1831
                "Resetting to active\n", ehci->astate);
1801
        ehci->astate = EST_ACTIVE;
1832
        ehci_set_state(ehci, async, EST_ACTIVE);
1802 1833
    }
1803 1834
}
1804 1835

  
......
1806 1837
{
1807 1838
    uint32_t entry;
1808 1839
    uint32_t list;
1840
    int async = 0;
1809 1841

  
1810 1842
    // 4.6
1811 1843

  
1812
    switch(ehci->pstate) {
1844
    switch(ehci_get_state(ehci, async)) {
1813 1845
    case EST_INACTIVE:
1814 1846
        if ( !(ehci->frindex & 7) && (ehci->usbcmd & USBCMD_PSE)) {
1815 1847
            ehci_set_usbsts(ehci, USBSTS_PSS);
1816
            ehci->pstate = EST_ACTIVE;
1848
            ehci_set_state(ehci, async, EST_ACTIVE);
1817 1849
            // No break, fall through to ACTIVE
1818 1850
        } else
1819 1851
            break;
......
1821 1853
    case EST_ACTIVE:
1822 1854
        if ( !(ehci->frindex & 7) && !(ehci->usbcmd & USBCMD_PSE)) {
1823 1855
            ehci_clear_usbsts(ehci, USBSTS_PSS);
1824
            ehci->pstate = EST_INACTIVE;
1856
            ehci_set_state(ehci, async, EST_INACTIVE);
1825 1857
            break;
1826 1858
        }
1827 1859

  
......
1838 1870
        DPRINTF("PERIODIC state adv fr=%d.  [%08X] -> %08X\n",
1839 1871
                ehci->frindex / 8, list, entry);
1840 1872
        ehci->fetch_addr = entry;
1841
        ehci->pstate = ehci_advance_state(ehci, 0, EST_FETCHENTRY);
1873
        ehci_set_state(ehci, async, EST_FETCHENTRY);
1874
        ehci_advance_state(ehci, async);
1842 1875
        break;
1843 1876

  
1844 1877
    case EST_EXECUTING:
1845 1878
        DPRINTF("PERIODIC state adv for executing\n");
1846
        ehci->pstate = ehci_advance_state(ehci, 0, EST_EXECUTING);
1879
        ehci_advance_state(ehci, async);
1847 1880
        break;
1848 1881

  
1849 1882
    default:
1850 1883
        /* this should only be due to a developer mistake */
1851 1884
        fprintf(stderr, "ehci: Bad periodic state %d. "
1852 1885
                "Resetting to active\n", ehci->pstate);
1853
        ehci->pstate = EST_ACTIVE;
1886
        ehci_set_state(ehci, async, EST_ACTIVE);
1854 1887
    }
1855 1888
}
1856 1889

  
......
1896 1929
        } else {
1897 1930
            // TODO could this cause periodic frames to get skipped if async
1898 1931
            // active?
1899
            if (ehci->astate != EST_EXECUTING) {
1932
            if (ehci_get_state(ehci, 1) != EST_EXECUTING) {
1900 1933
                ehci_advance_periodic_state(ehci);
1901 1934
            }
1902 1935
        }
......
1913 1946
    /*  Async is not inside loop since it executes everything it can once
1914 1947
     *  called
1915 1948
     */
1916
    if (ehci->pstate != EST_EXECUTING) {
1949
    if (ehci_get_state(ehci, 0) != EST_EXECUTING) {
1917 1950
        ehci_advance_async_state(ehci);
1918 1951
    }
1919 1952

  
b/trace-events
199 199
disable usb_ehci_mmio_readl(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
200 200
disable usb_ehci_mmio_writel(uint32_t addr, const char *str, uint32_t val, uint32_t oldval) "wr mmio %04x [%s] = %x (old: %x)"
201 201
disable usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
202
disable usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
203
disable usb_ehci_qh(uint32_t addr, uint32_t next, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd, int rl, int mplen, int eps, int ep, int devaddr, int c, int h, int dtc, int i) "QH @ %08x: next %08x qtds %08x,%08x,%08x - rl %d, mplen %d, eps %d, ep %d, dev %d, c %d, h %d, dtc %d, i %d"
204
disable usb_ehci_qtd(uint32_t addr, uint32_t next, uint32_t altnext, int tbytes, int cpage, int cerr, int pid, int ioc, int active, int halt, int babble, int xacterr) "QH @ %08x: next %08x altnext %08x - tbytes %d, cpage %d, cerr %d, pid %d, ioc %d, active %d, halt %d, babble %d, xacterr %d"
205
disable usb_ehci_itd(uint32_t addr, uint32_t next) "ITD @ %08x: next %08x"
202 206

  
203 207
# hw/usb-desc.c
204 208
disable usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"

Also available in: Unified diff