Annotation of qemu/hw/usb/hcd-uhci.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * USB UHCI controller emulation
                      3:  *
                      4:  * Copyright (c) 2005 Fabrice Bellard
                      5:  *
                      6:  * Copyright (c) 2008 Max Krasnyansky
                      7:  *     Magor rewrite of the UHCI data structures parser and frame processor
                      8:  *     Support for fully async operation and multiple outstanding transactions
                      9:  *
                     10:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     11:  * of this software and associated documentation files (the "Software"), to deal
                     12:  * in the Software without restriction, including without limitation the rights
                     13:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     14:  * copies of the Software, and to permit persons to whom the Software is
                     15:  * furnished to do so, subject to the following conditions:
                     16:  *
                     17:  * The above copyright notice and this permission notice shall be included in
                     18:  * all copies or substantial portions of the Software.
                     19:  *
                     20:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     21:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     22:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     23:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     24:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     25:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     26:  * THE SOFTWARE.
                     27:  */
                     28: #include "hw/hw.h"
                     29: #include "hw/usb.h"
                     30: #include "hw/pci.h"
                     31: #include "qemu-timer.h"
                     32: #include "iov.h"
                     33: #include "dma.h"
                     34: #include "trace.h"
                     35: 
                     36: //#define DEBUG
                     37: //#define DEBUG_DUMP_DATA
                     38: 
                     39: #define UHCI_CMD_FGR      (1 << 4)
                     40: #define UHCI_CMD_EGSM     (1 << 3)
                     41: #define UHCI_CMD_GRESET   (1 << 2)
                     42: #define UHCI_CMD_HCRESET  (1 << 1)
                     43: #define UHCI_CMD_RS       (1 << 0)
                     44: 
                     45: #define UHCI_STS_HCHALTED (1 << 5)
                     46: #define UHCI_STS_HCPERR   (1 << 4)
                     47: #define UHCI_STS_HSERR    (1 << 3)
                     48: #define UHCI_STS_RD       (1 << 2)
                     49: #define UHCI_STS_USBERR   (1 << 1)
                     50: #define UHCI_STS_USBINT   (1 << 0)
                     51: 
                     52: #define TD_CTRL_SPD     (1 << 29)
                     53: #define TD_CTRL_ERROR_SHIFT  27
                     54: #define TD_CTRL_IOS     (1 << 25)
                     55: #define TD_CTRL_IOC     (1 << 24)
                     56: #define TD_CTRL_ACTIVE  (1 << 23)
                     57: #define TD_CTRL_STALL   (1 << 22)
                     58: #define TD_CTRL_BABBLE  (1 << 20)
                     59: #define TD_CTRL_NAK     (1 << 19)
                     60: #define TD_CTRL_TIMEOUT (1 << 18)
                     61: 
                     62: #define UHCI_PORT_SUSPEND (1 << 12)
                     63: #define UHCI_PORT_RESET (1 << 9)
                     64: #define UHCI_PORT_LSDA  (1 << 8)
                     65: #define UHCI_PORT_RD    (1 << 6)
                     66: #define UHCI_PORT_ENC   (1 << 3)
                     67: #define UHCI_PORT_EN    (1 << 2)
                     68: #define UHCI_PORT_CSC   (1 << 1)
                     69: #define UHCI_PORT_CCS   (1 << 0)
                     70: 
                     71: #define UHCI_PORT_READ_ONLY    (0x1bb)
                     72: #define UHCI_PORT_WRITE_CLEAR  (UHCI_PORT_CSC | UHCI_PORT_ENC)
                     73: 
                     74: #define FRAME_TIMER_FREQ 1000
                     75: 
                     76: #define FRAME_MAX_LOOPS  256
                     77: 
                     78: #define NB_PORTS 2
                     79: 
                     80: enum {
                     81:     TD_RESULT_STOP_FRAME = 10,
                     82:     TD_RESULT_COMPLETE,
                     83:     TD_RESULT_NEXT_QH,
                     84:     TD_RESULT_ASYNC_START,
                     85:     TD_RESULT_ASYNC_CONT,
                     86: };
                     87: 
                     88: typedef struct UHCIState UHCIState;
                     89: typedef struct UHCIAsync UHCIAsync;
                     90: typedef struct UHCIQueue UHCIQueue;
                     91: 
                     92: /* 
                     93:  * Pending async transaction.
                     94:  * 'packet' must be the first field because completion
                     95:  * handler does "(UHCIAsync *) pkt" cast.
                     96:  */
                     97: 
                     98: struct UHCIAsync {
                     99:     USBPacket packet;
                    100:     QEMUSGList sgl;
                    101:     UHCIQueue *queue;
                    102:     QTAILQ_ENTRY(UHCIAsync) next;
                    103:     uint32_t  td;
                    104:     uint8_t   isoc;
                    105:     uint8_t   done;
                    106: };
                    107: 
                    108: struct UHCIQueue {
                    109:     uint32_t  token;
                    110:     UHCIState *uhci;
                    111:     QTAILQ_ENTRY(UHCIQueue) next;
                    112:     QTAILQ_HEAD(, UHCIAsync) asyncs;
                    113:     int8_t    valid;
                    114: };
                    115: 
                    116: typedef struct UHCIPort {
                    117:     USBPort port;
                    118:     uint16_t ctrl;
                    119: } UHCIPort;
                    120: 
                    121: struct UHCIState {
                    122:     PCIDevice dev;
                    123:     MemoryRegion io_bar;
                    124:     USBBus bus; /* Note unused when we're a companion controller */
                    125:     uint16_t cmd; /* cmd register */
                    126:     uint16_t status;
                    127:     uint16_t intr; /* interrupt enable register */
                    128:     uint16_t frnum; /* frame number */
                    129:     uint32_t fl_base_addr; /* frame list base address */
                    130:     uint8_t sof_timing;
                    131:     uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
                    132:     int64_t expire_time;
                    133:     QEMUTimer *frame_timer;
                    134:     UHCIPort ports[NB_PORTS];
                    135: 
                    136:     /* Interrupts that should be raised at the end of the current frame.  */
                    137:     uint32_t pending_int_mask;
                    138: 
                    139:     /* Active packets */
                    140:     QTAILQ_HEAD(, UHCIQueue) queues;
                    141:     uint8_t num_ports_vmstate;
                    142: 
                    143:     /* Properties */
                    144:     char *masterbus;
                    145:     uint32_t firstport;
                    146: };
                    147: 
                    148: typedef struct UHCI_TD {
                    149:     uint32_t link;
                    150:     uint32_t ctrl; /* see TD_CTRL_xxx */
                    151:     uint32_t token;
                    152:     uint32_t buffer;
                    153: } UHCI_TD;
                    154: 
                    155: typedef struct UHCI_QH {
                    156:     uint32_t link;
                    157:     uint32_t el_link;
                    158: } UHCI_QH;
                    159: 
                    160: static inline int32_t uhci_queue_token(UHCI_TD *td)
                    161: {
                    162:     /* covers ep, dev, pid -> identifies the endpoint */
                    163:     return td->token & 0x7ffff;
                    164: }
                    165: 
                    166: static UHCIQueue *uhci_queue_get(UHCIState *s, UHCI_TD *td)
                    167: {
                    168:     uint32_t token = uhci_queue_token(td);
                    169:     UHCIQueue *queue;
                    170: 
                    171:     QTAILQ_FOREACH(queue, &s->queues, next) {
                    172:         if (queue->token == token) {
                    173:             return queue;
                    174:         }
                    175:     }
                    176: 
                    177:     queue = g_new0(UHCIQueue, 1);
                    178:     queue->uhci = s;
                    179:     queue->token = token;
                    180:     QTAILQ_INIT(&queue->asyncs);
                    181:     QTAILQ_INSERT_HEAD(&s->queues, queue, next);
                    182:     trace_usb_uhci_queue_add(queue->token);
                    183:     return queue;
                    184: }
                    185: 
                    186: static void uhci_queue_free(UHCIQueue *queue)
                    187: {
                    188:     UHCIState *s = queue->uhci;
                    189: 
                    190:     trace_usb_uhci_queue_del(queue->token);
                    191:     QTAILQ_REMOVE(&s->queues, queue, next);
                    192:     g_free(queue);
                    193: }
                    194: 
                    195: static UHCIAsync *uhci_async_alloc(UHCIQueue *queue, uint32_t addr)
                    196: {
                    197:     UHCIAsync *async = g_new0(UHCIAsync, 1);
                    198: 
                    199:     async->queue = queue;
                    200:     async->td = addr;
                    201:     usb_packet_init(&async->packet);
                    202:     pci_dma_sglist_init(&async->sgl, &queue->uhci->dev, 1);
                    203:     trace_usb_uhci_packet_add(async->queue->token, async->td);
                    204: 
                    205:     return async;
                    206: }
                    207: 
                    208: static void uhci_async_free(UHCIAsync *async)
                    209: {
                    210:     trace_usb_uhci_packet_del(async->queue->token, async->td);
                    211:     usb_packet_cleanup(&async->packet);
                    212:     qemu_sglist_destroy(&async->sgl);
                    213:     g_free(async);
                    214: }
                    215: 
                    216: static void uhci_async_link(UHCIAsync *async)
                    217: {
                    218:     UHCIQueue *queue = async->queue;
                    219:     QTAILQ_INSERT_TAIL(&queue->asyncs, async, next);
                    220:     trace_usb_uhci_packet_link_async(async->queue->token, async->td);
                    221: }
                    222: 
                    223: static void uhci_async_unlink(UHCIAsync *async)
                    224: {
                    225:     UHCIQueue *queue = async->queue;
                    226:     QTAILQ_REMOVE(&queue->asyncs, async, next);
                    227:     trace_usb_uhci_packet_unlink_async(async->queue->token, async->td);
                    228: }
                    229: 
                    230: static void uhci_async_cancel(UHCIAsync *async)
                    231: {
                    232:     trace_usb_uhci_packet_cancel(async->queue->token, async->td, async->done);
                    233:     if (!async->done)
                    234:         usb_cancel_packet(&async->packet);
                    235:     uhci_async_free(async);
                    236: }
                    237: 
                    238: /*
                    239:  * Mark all outstanding async packets as invalid.
                    240:  * This is used for canceling them when TDs are removed by the HCD.
                    241:  */
                    242: static void uhci_async_validate_begin(UHCIState *s)
                    243: {
                    244:     UHCIQueue *queue;
                    245: 
                    246:     QTAILQ_FOREACH(queue, &s->queues, next) {
                    247:         queue->valid--;
                    248:     }
                    249: }
                    250: 
                    251: /*
                    252:  * Cancel async packets that are no longer valid
                    253:  */
                    254: static void uhci_async_validate_end(UHCIState *s)
                    255: {
                    256:     UHCIQueue *queue, *n;
                    257:     UHCIAsync *async;
                    258: 
                    259:     QTAILQ_FOREACH_SAFE(queue, &s->queues, next, n) {
                    260:         if (queue->valid > 0) {
                    261:             continue;
                    262:         }
                    263:         while (!QTAILQ_EMPTY(&queue->asyncs)) {
                    264:             async = QTAILQ_FIRST(&queue->asyncs);
                    265:             uhci_async_unlink(async);
                    266:             uhci_async_cancel(async);
                    267:         }
                    268:         uhci_queue_free(queue);
                    269:     }
                    270: }
                    271: 
                    272: static void uhci_async_cancel_device(UHCIState *s, USBDevice *dev)
                    273: {
                    274:     UHCIQueue *queue;
                    275:     UHCIAsync *curr, *n;
                    276: 
                    277:     QTAILQ_FOREACH(queue, &s->queues, next) {
                    278:         QTAILQ_FOREACH_SAFE(curr, &queue->asyncs, next, n) {
                    279:             if (!usb_packet_is_inflight(&curr->packet) ||
                    280:                 curr->packet.ep->dev != dev) {
                    281:                 continue;
                    282:             }
                    283:             uhci_async_unlink(curr);
                    284:             uhci_async_cancel(curr);
                    285:         }
                    286:     }
                    287: }
                    288: 
                    289: static void uhci_async_cancel_all(UHCIState *s)
                    290: {
                    291:     UHCIQueue *queue;
                    292:     UHCIAsync *curr, *n;
                    293: 
                    294:     QTAILQ_FOREACH(queue, &s->queues, next) {
                    295:         QTAILQ_FOREACH_SAFE(curr, &queue->asyncs, next, n) {
                    296:             uhci_async_unlink(curr);
                    297:             uhci_async_cancel(curr);
                    298:         }
                    299:         uhci_queue_free(queue);
                    300:     }
                    301: }
                    302: 
                    303: static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, UHCI_TD *td)
                    304: {
                    305:     uint32_t token = uhci_queue_token(td);
                    306:     UHCIQueue *queue;
                    307:     UHCIAsync *async;
                    308: 
                    309:     QTAILQ_FOREACH(queue, &s->queues, next) {
                    310:         if (queue->token == token) {
                    311:             break;
                    312:         }
                    313:     }
                    314:     if (queue == NULL) {
                    315:         return NULL;
                    316:     }
                    317: 
                    318:     QTAILQ_FOREACH(async, &queue->asyncs, next) {
                    319:         if (async->td == addr) {
                    320:             return async;
                    321:         }
                    322:     }
                    323: 
                    324:     return NULL;
                    325: }
                    326: 
                    327: static void uhci_update_irq(UHCIState *s)
                    328: {
                    329:     int level;
                    330:     if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
                    331:         ((s->status2 & 2) && (s->intr & (1 << 3))) ||
                    332:         ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
                    333:         ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
                    334:         (s->status & UHCI_STS_HSERR) ||
                    335:         (s->status & UHCI_STS_HCPERR)) {
                    336:         level = 1;
                    337:     } else {
                    338:         level = 0;
                    339:     }
                    340:     qemu_set_irq(s->dev.irq[3], level);
                    341: }
                    342: 
                    343: static void uhci_reset(void *opaque)
                    344: {
                    345:     UHCIState *s = opaque;
                    346:     uint8_t *pci_conf;
                    347:     int i;
                    348:     UHCIPort *port;
                    349: 
                    350:     trace_usb_uhci_reset();
                    351: 
                    352:     pci_conf = s->dev.config;
                    353: 
                    354:     pci_conf[0x6a] = 0x01; /* usb clock */
                    355:     pci_conf[0x6b] = 0x00;
                    356:     s->cmd = 0;
                    357:     s->status = 0;
                    358:     s->status2 = 0;
                    359:     s->intr = 0;
                    360:     s->fl_base_addr = 0;
                    361:     s->sof_timing = 64;
                    362: 
                    363:     for(i = 0; i < NB_PORTS; i++) {
                    364:         port = &s->ports[i];
                    365:         port->ctrl = 0x0080;
                    366:         if (port->port.dev && port->port.dev->attached) {
                    367:             usb_port_reset(&port->port);
                    368:         }
                    369:     }
                    370: 
                    371:     uhci_async_cancel_all(s);
                    372:     uhci_update_irq(s);
                    373: }
                    374: 
                    375: static void uhci_pre_save(void *opaque)
                    376: {
                    377:     UHCIState *s = opaque;
                    378: 
                    379:     uhci_async_cancel_all(s);
                    380: }
                    381: 
                    382: static const VMStateDescription vmstate_uhci_port = {
                    383:     .name = "uhci port",
                    384:     .version_id = 1,
                    385:     .minimum_version_id = 1,
                    386:     .minimum_version_id_old = 1,
                    387:     .fields      = (VMStateField []) {
                    388:         VMSTATE_UINT16(ctrl, UHCIPort),
                    389:         VMSTATE_END_OF_LIST()
                    390:     }
                    391: };
                    392: 
                    393: static const VMStateDescription vmstate_uhci = {
                    394:     .name = "uhci",
                    395:     .version_id = 2,
                    396:     .minimum_version_id = 1,
                    397:     .minimum_version_id_old = 1,
                    398:     .pre_save = uhci_pre_save,
                    399:     .fields      = (VMStateField []) {
                    400:         VMSTATE_PCI_DEVICE(dev, UHCIState),
                    401:         VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState),
                    402:         VMSTATE_STRUCT_ARRAY(ports, UHCIState, NB_PORTS, 1,
                    403:                              vmstate_uhci_port, UHCIPort),
                    404:         VMSTATE_UINT16(cmd, UHCIState),
                    405:         VMSTATE_UINT16(status, UHCIState),
                    406:         VMSTATE_UINT16(intr, UHCIState),
                    407:         VMSTATE_UINT16(frnum, UHCIState),
                    408:         VMSTATE_UINT32(fl_base_addr, UHCIState),
                    409:         VMSTATE_UINT8(sof_timing, UHCIState),
                    410:         VMSTATE_UINT8(status2, UHCIState),
                    411:         VMSTATE_TIMER(frame_timer, UHCIState),
                    412:         VMSTATE_INT64_V(expire_time, UHCIState, 2),
                    413:         VMSTATE_END_OF_LIST()
                    414:     }
                    415: };
                    416: 
                    417: static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
                    418: {
                    419:     UHCIState *s = opaque;
                    420: 
                    421:     addr &= 0x1f;
                    422:     switch(addr) {
                    423:     case 0x0c:
                    424:         s->sof_timing = val;
                    425:         break;
                    426:     }
                    427: }
                    428: 
                    429: static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
                    430: {
                    431:     UHCIState *s = opaque;
                    432:     uint32_t val;
                    433: 
                    434:     addr &= 0x1f;
                    435:     switch(addr) {
                    436:     case 0x0c:
                    437:         val = s->sof_timing;
                    438:         break;
                    439:     default:
                    440:         val = 0xff;
                    441:         break;
                    442:     }
                    443:     return val;
                    444: }
                    445: 
                    446: static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
                    447: {
                    448:     UHCIState *s = opaque;
                    449: 
                    450:     addr &= 0x1f;
                    451:     trace_usb_uhci_mmio_writew(addr, val);
                    452: 
                    453:     switch(addr) {
                    454:     case 0x00:
                    455:         if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
                    456:             /* start frame processing */
                    457:             trace_usb_uhci_schedule_start();
                    458:             s->expire_time = qemu_get_clock_ns(vm_clock) +
                    459:                 (get_ticks_per_sec() / FRAME_TIMER_FREQ);
                    460:             qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock));
                    461:             s->status &= ~UHCI_STS_HCHALTED;
                    462:         } else if (!(val & UHCI_CMD_RS)) {
                    463:             s->status |= UHCI_STS_HCHALTED;
                    464:         }
                    465:         if (val & UHCI_CMD_GRESET) {
                    466:             UHCIPort *port;
                    467:             int i;
                    468: 
                    469:             /* send reset on the USB bus */
                    470:             for(i = 0; i < NB_PORTS; i++) {
                    471:                 port = &s->ports[i];
                    472:                 usb_device_reset(port->port.dev);
                    473:             }
                    474:             uhci_reset(s);
                    475:             return;
                    476:         }
                    477:         if (val & UHCI_CMD_HCRESET) {
                    478:             uhci_reset(s);
                    479:             return;
                    480:         }
                    481:         s->cmd = val;
                    482:         break;
                    483:     case 0x02:
                    484:         s->status &= ~val;
                    485:         /* XXX: the chip spec is not coherent, so we add a hidden
                    486:            register to distinguish between IOC and SPD */
                    487:         if (val & UHCI_STS_USBINT)
                    488:             s->status2 = 0;
                    489:         uhci_update_irq(s);
                    490:         break;
                    491:     case 0x04:
                    492:         s->intr = val;
                    493:         uhci_update_irq(s);
                    494:         break;
                    495:     case 0x06:
                    496:         if (s->status & UHCI_STS_HCHALTED)
                    497:             s->frnum = val & 0x7ff;
                    498:         break;
                    499:     case 0x10 ... 0x1f:
                    500:         {
                    501:             UHCIPort *port;
                    502:             USBDevice *dev;
                    503:             int n;
                    504: 
                    505:             n = (addr >> 1) & 7;
                    506:             if (n >= NB_PORTS)
                    507:                 return;
                    508:             port = &s->ports[n];
                    509:             dev = port->port.dev;
                    510:             if (dev && dev->attached) {
                    511:                 /* port reset */
                    512:                 if ( (val & UHCI_PORT_RESET) &&
                    513:                      !(port->ctrl & UHCI_PORT_RESET) ) {
                    514:                     usb_device_reset(dev);
                    515:                 }
                    516:             }
                    517:             port->ctrl &= UHCI_PORT_READ_ONLY;
                    518:             port->ctrl |= (val & ~UHCI_PORT_READ_ONLY);
                    519:             /* some bits are reset when a '1' is written to them */
                    520:             port->ctrl &= ~(val & UHCI_PORT_WRITE_CLEAR);
                    521:         }
                    522:         break;
                    523:     }
                    524: }
                    525: 
                    526: static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
                    527: {
                    528:     UHCIState *s = opaque;
                    529:     uint32_t val;
                    530: 
                    531:     addr &= 0x1f;
                    532:     switch(addr) {
                    533:     case 0x00:
                    534:         val = s->cmd;
                    535:         break;
                    536:     case 0x02:
                    537:         val = s->status;
                    538:         break;
                    539:     case 0x04:
                    540:         val = s->intr;
                    541:         break;
                    542:     case 0x06:
                    543:         val = s->frnum;
                    544:         break;
                    545:     case 0x10 ... 0x1f:
                    546:         {
                    547:             UHCIPort *port;
                    548:             int n;
                    549:             n = (addr >> 1) & 7;
                    550:             if (n >= NB_PORTS)
                    551:                 goto read_default;
                    552:             port = &s->ports[n];
                    553:             val = port->ctrl;
                    554:         }
                    555:         break;
                    556:     default:
                    557:     read_default:
                    558:         val = 0xff7f; /* disabled port */
                    559:         break;
                    560:     }
                    561: 
                    562:     trace_usb_uhci_mmio_readw(addr, val);
                    563: 
                    564:     return val;
                    565: }
                    566: 
                    567: static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
                    568: {
                    569:     UHCIState *s = opaque;
                    570: 
                    571:     addr &= 0x1f;
                    572:     trace_usb_uhci_mmio_writel(addr, val);
                    573: 
                    574:     switch(addr) {
                    575:     case 0x08:
                    576:         s->fl_base_addr = val & ~0xfff;
                    577:         break;
                    578:     }
                    579: }
                    580: 
                    581: static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
                    582: {
                    583:     UHCIState *s = opaque;
                    584:     uint32_t val;
                    585: 
                    586:     addr &= 0x1f;
                    587:     switch(addr) {
                    588:     case 0x08:
                    589:         val = s->fl_base_addr;
                    590:         break;
                    591:     default:
                    592:         val = 0xffffffff;
                    593:         break;
                    594:     }
                    595:     trace_usb_uhci_mmio_readl(addr, val);
                    596:     return val;
                    597: }
                    598: 
                    599: /* signal resume if controller suspended */
                    600: static void uhci_resume (void *opaque)
                    601: {
                    602:     UHCIState *s = (UHCIState *)opaque;
                    603: 
                    604:     if (!s)
                    605:         return;
                    606: 
                    607:     if (s->cmd & UHCI_CMD_EGSM) {
                    608:         s->cmd |= UHCI_CMD_FGR;
                    609:         s->status |= UHCI_STS_RD;
                    610:         uhci_update_irq(s);
                    611:     }
                    612: }
                    613: 
                    614: static void uhci_attach(USBPort *port1)
                    615: {
                    616:     UHCIState *s = port1->opaque;
                    617:     UHCIPort *port = &s->ports[port1->index];
                    618: 
                    619:     /* set connect status */
                    620:     port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
                    621: 
                    622:     /* update speed */
                    623:     if (port->port.dev->speed == USB_SPEED_LOW) {
                    624:         port->ctrl |= UHCI_PORT_LSDA;
                    625:     } else {
                    626:         port->ctrl &= ~UHCI_PORT_LSDA;
                    627:     }
                    628: 
                    629:     uhci_resume(s);
                    630: }
                    631: 
                    632: static void uhci_detach(USBPort *port1)
                    633: {
                    634:     UHCIState *s = port1->opaque;
                    635:     UHCIPort *port = &s->ports[port1->index];
                    636: 
                    637:     uhci_async_cancel_device(s, port1->dev);
                    638: 
                    639:     /* set connect status */
                    640:     if (port->ctrl & UHCI_PORT_CCS) {
                    641:         port->ctrl &= ~UHCI_PORT_CCS;
                    642:         port->ctrl |= UHCI_PORT_CSC;
                    643:     }
                    644:     /* disable port */
                    645:     if (port->ctrl & UHCI_PORT_EN) {
                    646:         port->ctrl &= ~UHCI_PORT_EN;
                    647:         port->ctrl |= UHCI_PORT_ENC;
                    648:     }
                    649: 
                    650:     uhci_resume(s);
                    651: }
                    652: 
                    653: static void uhci_child_detach(USBPort *port1, USBDevice *child)
                    654: {
                    655:     UHCIState *s = port1->opaque;
                    656: 
                    657:     uhci_async_cancel_device(s, child);
                    658: }
                    659: 
                    660: static void uhci_wakeup(USBPort *port1)
                    661: {
                    662:     UHCIState *s = port1->opaque;
                    663:     UHCIPort *port = &s->ports[port1->index];
                    664: 
                    665:     if (port->ctrl & UHCI_PORT_SUSPEND && !(port->ctrl & UHCI_PORT_RD)) {
                    666:         port->ctrl |= UHCI_PORT_RD;
                    667:         uhci_resume(s);
                    668:     }
                    669: }
                    670: 
                    671: static USBDevice *uhci_find_device(UHCIState *s, uint8_t addr)
                    672: {
                    673:     USBDevice *dev;
                    674:     int i;
                    675: 
                    676:     for (i = 0; i < NB_PORTS; i++) {
                    677:         UHCIPort *port = &s->ports[i];
                    678:         if (!(port->ctrl & UHCI_PORT_EN)) {
                    679:             continue;
                    680:         }
                    681:         dev = usb_find_device(&port->port, addr);
                    682:         if (dev != NULL) {
                    683:             return dev;
                    684:         }
                    685:     }
                    686:     return NULL;
                    687: }
                    688: 
                    689: static void uhci_async_complete(USBPort *port, USBPacket *packet);
                    690: static void uhci_process_frame(UHCIState *s);
                    691: 
                    692: /* return -1 if fatal error (frame must be stopped)
                    693:           0 if TD successful
                    694:           1 if TD unsuccessful or inactive
                    695: */
                    696: static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_t *int_mask)
                    697: {
                    698:     int len = 0, max_len, err, ret;
                    699:     uint8_t pid;
                    700: 
                    701:     max_len = ((td->token >> 21) + 1) & 0x7ff;
                    702:     pid = td->token & 0xff;
                    703: 
                    704:     ret = async->packet.result;
                    705: 
                    706:     if (td->ctrl & TD_CTRL_IOS)
                    707:         td->ctrl &= ~TD_CTRL_ACTIVE;
                    708: 
                    709:     if (ret < 0)
                    710:         goto out;
                    711: 
                    712:     len = async->packet.result;
                    713:     td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
                    714: 
                    715:     /* The NAK bit may have been set by a previous frame, so clear it
                    716:        here.  The docs are somewhat unclear, but win2k relies on this
                    717:        behavior.  */
                    718:     td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
                    719:     if (td->ctrl & TD_CTRL_IOC)
                    720:         *int_mask |= 0x01;
                    721: 
                    722:     if (pid == USB_TOKEN_IN) {
                    723:         if (len > max_len) {
                    724:             ret = USB_RET_BABBLE;
                    725:             goto out;
                    726:         }
                    727: 
                    728:         if ((td->ctrl & TD_CTRL_SPD) && len < max_len) {
                    729:             *int_mask |= 0x02;
                    730:             /* short packet: do not update QH */
                    731:             trace_usb_uhci_packet_complete_shortxfer(async->queue->token,
                    732:                                                     async->td);
                    733:             return TD_RESULT_NEXT_QH;
                    734:         }
                    735:     }
                    736: 
                    737:     /* success */
                    738:     trace_usb_uhci_packet_complete_success(async->queue->token, async->td);
                    739:     return TD_RESULT_COMPLETE;
                    740: 
                    741: out:
                    742:     switch(ret) {
                    743:     case USB_RET_STALL:
                    744:         td->ctrl |= TD_CTRL_STALL;
                    745:         td->ctrl &= ~TD_CTRL_ACTIVE;
                    746:         s->status |= UHCI_STS_USBERR;
                    747:         if (td->ctrl & TD_CTRL_IOC) {
                    748:             *int_mask |= 0x01;
                    749:         }
                    750:         uhci_update_irq(s);
                    751:         trace_usb_uhci_packet_complete_stall(async->queue->token, async->td);
                    752:         return TD_RESULT_NEXT_QH;
                    753: 
                    754:     case USB_RET_BABBLE:
                    755:         td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
                    756:         td->ctrl &= ~TD_CTRL_ACTIVE;
                    757:         s->status |= UHCI_STS_USBERR;
                    758:         if (td->ctrl & TD_CTRL_IOC) {
                    759:             *int_mask |= 0x01;
                    760:         }
                    761:         uhci_update_irq(s);
                    762:         /* frame interrupted */
                    763:         trace_usb_uhci_packet_complete_babble(async->queue->token, async->td);
                    764:         return TD_RESULT_STOP_FRAME;
                    765: 
                    766:     case USB_RET_NAK:
                    767:         td->ctrl |= TD_CTRL_NAK;
                    768:         if (pid == USB_TOKEN_SETUP)
                    769:             break;
                    770:         return TD_RESULT_NEXT_QH;
                    771: 
                    772:     case USB_RET_IOERROR:
                    773:     case USB_RET_NODEV:
                    774:     default:
                    775:        break;
                    776:     }
                    777: 
                    778:     /* Retry the TD if error count is not zero */
                    779: 
                    780:     td->ctrl |= TD_CTRL_TIMEOUT;
                    781:     err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
                    782:     if (err != 0) {
                    783:         err--;
                    784:         if (err == 0) {
                    785:             td->ctrl &= ~TD_CTRL_ACTIVE;
                    786:             s->status |= UHCI_STS_USBERR;
                    787:             if (td->ctrl & TD_CTRL_IOC)
                    788:                 *int_mask |= 0x01;
                    789:             uhci_update_irq(s);
                    790:             trace_usb_uhci_packet_complete_error(async->queue->token,
                    791:                                                  async->td);
                    792:         }
                    793:     }
                    794:     td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
                    795:         (err << TD_CTRL_ERROR_SHIFT);
                    796:     return TD_RESULT_NEXT_QH;
                    797: }
                    798: 
                    799: static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
                    800:                           uint32_t *int_mask, bool queuing)
                    801: {
                    802:     UHCIAsync *async;
                    803:     int len = 0, max_len;
                    804:     uint8_t pid;
                    805:     USBDevice *dev;
                    806:     USBEndpoint *ep;
                    807: 
                    808:     /* Is active ? */
                    809:     if (!(td->ctrl & TD_CTRL_ACTIVE))
                    810:         return TD_RESULT_NEXT_QH;
                    811: 
                    812:     async = uhci_async_find_td(s, addr, td);
                    813:     if (async) {
                    814:         /* Already submitted */
                    815:         async->queue->valid = 32;
                    816: 
                    817:         if (!async->done)
                    818:             return TD_RESULT_ASYNC_CONT;
                    819:         if (queuing) {
                    820:             /* we are busy filling the queue, we are not prepared
                    821:                to consume completed packages then, just leave them
                    822:                in async state */
                    823:             return TD_RESULT_ASYNC_CONT;
                    824:         }
                    825: 
                    826:         uhci_async_unlink(async);
                    827:         goto done;
                    828:     }
                    829: 
                    830:     /* Allocate new packet */
                    831:     async = uhci_async_alloc(uhci_queue_get(s, td), addr);
                    832: 
                    833:     /* valid needs to be large enough to handle 10 frame delay
                    834:      * for initial isochronous requests
                    835:      */
                    836:     async->queue->valid = 32;
                    837:     async->isoc  = td->ctrl & TD_CTRL_IOS;
                    838: 
                    839:     max_len = ((td->token >> 21) + 1) & 0x7ff;
                    840:     pid = td->token & 0xff;
                    841: 
                    842:     dev = uhci_find_device(s, (td->token >> 8) & 0x7f);
                    843:     ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);
                    844:     usb_packet_setup(&async->packet, pid, ep);
                    845:     qemu_sglist_add(&async->sgl, td->buffer, max_len);
                    846:     usb_packet_map(&async->packet, &async->sgl);
                    847: 
                    848:     switch(pid) {
                    849:     case USB_TOKEN_OUT:
                    850:     case USB_TOKEN_SETUP:
                    851:         len = usb_handle_packet(dev, &async->packet);
                    852:         if (len >= 0)
                    853:             len = max_len;
                    854:         break;
                    855: 
                    856:     case USB_TOKEN_IN:
                    857:         len = usb_handle_packet(dev, &async->packet);
                    858:         break;
                    859: 
                    860:     default:
                    861:         /* invalid pid : frame interrupted */
                    862:         uhci_async_free(async);
                    863:         s->status |= UHCI_STS_HCPERR;
                    864:         uhci_update_irq(s);
                    865:         return TD_RESULT_STOP_FRAME;
                    866:     }
                    867:  
                    868:     if (len == USB_RET_ASYNC) {
                    869:         uhci_async_link(async);
                    870:         return TD_RESULT_ASYNC_START;
                    871:     }
                    872: 
                    873:     async->packet.result = len;
                    874: 
                    875: done:
                    876:     len = uhci_complete_td(s, td, async, int_mask);
                    877:     usb_packet_unmap(&async->packet);
                    878:     uhci_async_free(async);
                    879:     return len;
                    880: }
                    881: 
                    882: static void uhci_async_complete(USBPort *port, USBPacket *packet)
                    883: {
                    884:     UHCIAsync *async = container_of(packet, UHCIAsync, packet);
                    885:     UHCIState *s = async->queue->uhci;
                    886: 
                    887:     if (async->isoc) {
                    888:         UHCI_TD td;
                    889:         uint32_t link = async->td;
                    890:         uint32_t int_mask = 0, val;
                    891: 
                    892:         pci_dma_read(&s->dev, link & ~0xf, &td, sizeof(td));
                    893:         le32_to_cpus(&td.link);
                    894:         le32_to_cpus(&td.ctrl);
                    895:         le32_to_cpus(&td.token);
                    896:         le32_to_cpus(&td.buffer);
                    897: 
                    898:         uhci_async_unlink(async);
                    899:         uhci_complete_td(s, &td, async, &int_mask);
                    900:         s->pending_int_mask |= int_mask;
                    901: 
                    902:         /* update the status bits of the TD */
                    903:         val = cpu_to_le32(td.ctrl);
                    904:         pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val));
                    905:         uhci_async_free(async);
                    906:     } else {
                    907:         async->done = 1;
                    908:         uhci_process_frame(s);
                    909:     }
                    910: }
                    911: 
                    912: static int is_valid(uint32_t link)
                    913: {
                    914:     return (link & 1) == 0;
                    915: }
                    916: 
                    917: static int is_qh(uint32_t link)
                    918: {
                    919:     return (link & 2) != 0;
                    920: }
                    921: 
                    922: static int depth_first(uint32_t link)
                    923: {
                    924:     return (link & 4) != 0;
                    925: }
                    926: 
                    927: /* QH DB used for detecting QH loops */
                    928: #define UHCI_MAX_QUEUES 128
                    929: typedef struct {
                    930:     uint32_t addr[UHCI_MAX_QUEUES];
                    931:     int      count;
                    932: } QhDb;
                    933: 
                    934: static void qhdb_reset(QhDb *db)
                    935: {
                    936:     db->count = 0;
                    937: }
                    938: 
                    939: /* Add QH to DB. Returns 1 if already present or DB is full. */
                    940: static int qhdb_insert(QhDb *db, uint32_t addr)
                    941: {
                    942:     int i;
                    943:     for (i = 0; i < db->count; i++)
                    944:         if (db->addr[i] == addr)
                    945:             return 1;
                    946: 
                    947:     if (db->count >= UHCI_MAX_QUEUES)
                    948:         return 1;
                    949: 
                    950:     db->addr[db->count++] = addr;
                    951:     return 0;
                    952: }
                    953: 
                    954: static void uhci_fill_queue(UHCIState *s, UHCI_TD *td)
                    955: {
                    956:     uint32_t int_mask = 0;
                    957:     uint32_t plink = td->link;
                    958:     uint32_t token = uhci_queue_token(td);
                    959:     UHCI_TD ptd;
                    960:     int ret;
                    961: 
                    962:     while (is_valid(plink)) {
                    963:         pci_dma_read(&s->dev, plink & ~0xf, &ptd, sizeof(ptd));
                    964:         le32_to_cpus(&ptd.link);
                    965:         le32_to_cpus(&ptd.ctrl);
                    966:         le32_to_cpus(&ptd.token);
                    967:         le32_to_cpus(&ptd.buffer);
                    968:         if (!(ptd.ctrl & TD_CTRL_ACTIVE)) {
                    969:             break;
                    970:         }
                    971:         if (uhci_queue_token(&ptd) != token) {
                    972:             break;
                    973:         }
                    974:         trace_usb_uhci_td_queue(plink & ~0xf, ptd.ctrl, ptd.token);
                    975:         ret = uhci_handle_td(s, plink, &ptd, &int_mask, true);
                    976:         if (ret == TD_RESULT_ASYNC_CONT) {
                    977:             break;
                    978:         }
                    979:         assert(ret == TD_RESULT_ASYNC_START);
                    980:         assert(int_mask == 0);
                    981:         plink = ptd.link;
                    982:     }
                    983: }
                    984: 
                    985: static void uhci_process_frame(UHCIState *s)
                    986: {
                    987:     uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
                    988:     uint32_t curr_qh, td_count = 0, bytes_count = 0;
                    989:     int cnt, ret;
                    990:     UHCI_TD td;
                    991:     UHCI_QH qh;
                    992:     QhDb qhdb;
                    993: 
                    994:     frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
                    995: 
                    996:     pci_dma_read(&s->dev, frame_addr, &link, 4);
                    997:     le32_to_cpus(&link);
                    998: 
                    999:     int_mask = 0;
                   1000:     curr_qh  = 0;
                   1001: 
                   1002:     qhdb_reset(&qhdb);
                   1003: 
                   1004:     for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
                   1005:         if (is_qh(link)) {
                   1006:             /* QH */
                   1007:             trace_usb_uhci_qh_load(link & ~0xf);
                   1008: 
                   1009:             if (qhdb_insert(&qhdb, link)) {
                   1010:                 /*
                   1011:                  * We're going in circles. Which is not a bug because
                   1012:                  * HCD is allowed to do that as part of the BW management.
                   1013:                  *
                   1014:                  * Stop processing here if
                   1015:                  *  (a) no transaction has been done since we've been
                   1016:                  *      here last time, or
                   1017:                  *  (b) we've reached the usb 1.1 bandwidth, which is
                   1018:                  *      1280 bytes/frame.
                   1019:                  */
                   1020:                 if (td_count == 0) {
                   1021:                     trace_usb_uhci_frame_loop_stop_idle();
                   1022:                     break;
                   1023:                 } else if (bytes_count >= 1280) {
                   1024:                     trace_usb_uhci_frame_loop_stop_bandwidth();
                   1025:                     break;
                   1026:                 } else {
                   1027:                     trace_usb_uhci_frame_loop_continue();
                   1028:                     td_count = 0;
                   1029:                     qhdb_reset(&qhdb);
                   1030:                     qhdb_insert(&qhdb, link);
                   1031:                 }
                   1032:             }
                   1033: 
                   1034:             pci_dma_read(&s->dev, link & ~0xf, &qh, sizeof(qh));
                   1035:             le32_to_cpus(&qh.link);
                   1036:             le32_to_cpus(&qh.el_link);
                   1037: 
                   1038:             if (!is_valid(qh.el_link)) {
                   1039:                 /* QH w/o elements */
                   1040:                 curr_qh = 0;
                   1041:                 link = qh.link;
                   1042:             } else {
                   1043:                 /* QH with elements */
                   1044:                curr_qh = link;
                   1045:                link = qh.el_link;
                   1046:             }
                   1047:             continue;
                   1048:         }
                   1049: 
                   1050:         /* TD */
                   1051:         pci_dma_read(&s->dev, link & ~0xf, &td, sizeof(td));
                   1052:         le32_to_cpus(&td.link);
                   1053:         le32_to_cpus(&td.ctrl);
                   1054:         le32_to_cpus(&td.token);
                   1055:         le32_to_cpus(&td.buffer);
                   1056:         trace_usb_uhci_td_load(curr_qh & ~0xf, link & ~0xf, td.ctrl, td.token);
                   1057: 
                   1058:         old_td_ctrl = td.ctrl;
                   1059:         ret = uhci_handle_td(s, link, &td, &int_mask, false);
                   1060:         if (old_td_ctrl != td.ctrl) {
                   1061:             /* update the status bits of the TD */
                   1062:             val = cpu_to_le32(td.ctrl);
                   1063:             pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val));
                   1064:         }
                   1065: 
                   1066:         switch (ret) {
                   1067:         case TD_RESULT_STOP_FRAME: /* interrupted frame */
                   1068:             goto out;
                   1069: 
                   1070:         case TD_RESULT_NEXT_QH:
                   1071:         case TD_RESULT_ASYNC_CONT:
                   1072:             trace_usb_uhci_td_nextqh(curr_qh & ~0xf, link & ~0xf);
                   1073:             link = curr_qh ? qh.link : td.link;
                   1074:             continue;
                   1075: 
                   1076:         case TD_RESULT_ASYNC_START:
                   1077:             trace_usb_uhci_td_async(curr_qh & ~0xf, link & ~0xf);
                   1078:             if (is_valid(td.link)) {
                   1079:                 uhci_fill_queue(s, &td);
                   1080:             }
                   1081:             link = curr_qh ? qh.link : td.link;
                   1082:             continue;
                   1083: 
                   1084:         case TD_RESULT_COMPLETE:
                   1085:             trace_usb_uhci_td_complete(curr_qh & ~0xf, link & ~0xf);
                   1086:             link = td.link;
                   1087:             td_count++;
                   1088:             bytes_count += (td.ctrl & 0x7ff) + 1;
                   1089: 
                   1090:             if (curr_qh) {
                   1091:                 /* update QH element link */
                   1092:                 qh.el_link = link;
                   1093:                 val = cpu_to_le32(qh.el_link);
                   1094:                 pci_dma_write(&s->dev, (curr_qh & ~0xf) + 4, &val, sizeof(val));
                   1095: 
                   1096:                 if (!depth_first(link)) {
                   1097:                     /* done with this QH */
                   1098:                     curr_qh = 0;
                   1099:                     link    = qh.link;
                   1100:                 }
                   1101:             }
                   1102:             break;
                   1103: 
                   1104:         default:
                   1105:             assert(!"unknown return code");
                   1106:         }
                   1107: 
                   1108:         /* go to the next entry */
                   1109:     }
                   1110: 
                   1111: out:
                   1112:     s->pending_int_mask |= int_mask;
                   1113: }
                   1114: 
                   1115: static void uhci_frame_timer(void *opaque)
                   1116: {
                   1117:     UHCIState *s = opaque;
                   1118: 
                   1119:     /* prepare the timer for the next frame */
                   1120:     s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ);
                   1121: 
                   1122:     if (!(s->cmd & UHCI_CMD_RS)) {
                   1123:         /* Full stop */
                   1124:         trace_usb_uhci_schedule_stop();
                   1125:         qemu_del_timer(s->frame_timer);
                   1126:         uhci_async_cancel_all(s);
                   1127:         /* set hchalted bit in status - UHCI11D 2.1.2 */
                   1128:         s->status |= UHCI_STS_HCHALTED;
                   1129:         return;
                   1130:     }
                   1131: 
                   1132:     /* Complete the previous frame */
                   1133:     if (s->pending_int_mask) {
                   1134:         s->status2 |= s->pending_int_mask;
                   1135:         s->status  |= UHCI_STS_USBINT;
                   1136:         uhci_update_irq(s);
                   1137:     }
                   1138:     s->pending_int_mask = 0;
                   1139: 
                   1140:     /* Start new frame */
                   1141:     s->frnum = (s->frnum + 1) & 0x7ff;
                   1142: 
                   1143:     trace_usb_uhci_frame_start(s->frnum);
                   1144: 
                   1145:     uhci_async_validate_begin(s);
                   1146: 
                   1147:     uhci_process_frame(s);
                   1148: 
                   1149:     uhci_async_validate_end(s);
                   1150: 
                   1151:     qemu_mod_timer(s->frame_timer, s->expire_time);
                   1152: }
                   1153: 
                   1154: static const MemoryRegionPortio uhci_portio[] = {
                   1155:     { 0, 32, 2, .write = uhci_ioport_writew, },
                   1156:     { 0, 32, 2, .read = uhci_ioport_readw, },
                   1157:     { 0, 32, 4, .write = uhci_ioport_writel, },
                   1158:     { 0, 32, 4, .read = uhci_ioport_readl, },
                   1159:     { 0, 32, 1, .write = uhci_ioport_writeb, },
                   1160:     { 0, 32, 1, .read = uhci_ioport_readb, },
                   1161:     PORTIO_END_OF_LIST()
                   1162: };
                   1163: 
                   1164: static const MemoryRegionOps uhci_ioport_ops = {
                   1165:     .old_portio = uhci_portio,
                   1166: };
                   1167: 
                   1168: static USBPortOps uhci_port_ops = {
                   1169:     .attach = uhci_attach,
                   1170:     .detach = uhci_detach,
                   1171:     .child_detach = uhci_child_detach,
                   1172:     .wakeup = uhci_wakeup,
                   1173:     .complete = uhci_async_complete,
                   1174: };
                   1175: 
                   1176: static USBBusOps uhci_bus_ops = {
                   1177: };
                   1178: 
                   1179: static int usb_uhci_common_initfn(PCIDevice *dev)
                   1180: {
                   1181:     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
                   1182:     uint8_t *pci_conf = s->dev.config;
                   1183:     int i;
                   1184: 
                   1185:     pci_conf[PCI_CLASS_PROG] = 0x00;
                   1186:     /* TODO: reset value should be 0. */
                   1187:     pci_conf[PCI_INTERRUPT_PIN] = 4; /* interrupt pin D */
                   1188:     pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
                   1189: 
                   1190:     if (s->masterbus) {
                   1191:         USBPort *ports[NB_PORTS];
                   1192:         for(i = 0; i < NB_PORTS; i++) {
                   1193:             ports[i] = &s->ports[i].port;
                   1194:         }
                   1195:         if (usb_register_companion(s->masterbus, ports, NB_PORTS,
                   1196:                 s->firstport, s, &uhci_port_ops,
                   1197:                 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
                   1198:             return -1;
                   1199:         }
                   1200:     } else {
                   1201:         usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
                   1202:         for (i = 0; i < NB_PORTS; i++) {
                   1203:             usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
                   1204:                               USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
                   1205:         }
                   1206:     }
                   1207:     s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s);
                   1208:     s->num_ports_vmstate = NB_PORTS;
                   1209:     QTAILQ_INIT(&s->queues);
                   1210: 
                   1211:     qemu_register_reset(uhci_reset, s);
                   1212: 
                   1213:     memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
                   1214:     /* Use region 4 for consistency with real hardware.  BSD guests seem
                   1215:        to rely on this.  */
                   1216:     pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
                   1217: 
                   1218:     return 0;
                   1219: }
                   1220: 
                   1221: static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
                   1222: {
                   1223:     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
                   1224:     uint8_t *pci_conf = s->dev.config;
                   1225: 
                   1226:     /* USB misc control 1/2 */
                   1227:     pci_set_long(pci_conf + 0x40,0x00001000);
                   1228:     /* PM capability */
                   1229:     pci_set_long(pci_conf + 0x80,0x00020001);
                   1230:     /* USB legacy support  */
                   1231:     pci_set_long(pci_conf + 0xc0,0x00002000);
                   1232: 
                   1233:     return usb_uhci_common_initfn(dev);
                   1234: }
                   1235: 
                   1236: static int usb_uhci_exit(PCIDevice *dev)
                   1237: {
                   1238:     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
                   1239: 
                   1240:     memory_region_destroy(&s->io_bar);
                   1241:     return 0;
                   1242: }
                   1243: 
                   1244: static Property uhci_properties[] = {
                   1245:     DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
                   1246:     DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
                   1247:     DEFINE_PROP_END_OF_LIST(),
                   1248: };
                   1249: 
                   1250: static void piix3_uhci_class_init(ObjectClass *klass, void *data)
                   1251: {
                   1252:     DeviceClass *dc = DEVICE_CLASS(klass);
                   1253:     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
                   1254: 
                   1255:     k->init = usb_uhci_common_initfn;
                   1256:     k->exit = usb_uhci_exit;
                   1257:     k->vendor_id = PCI_VENDOR_ID_INTEL;
                   1258:     k->device_id = PCI_DEVICE_ID_INTEL_82371SB_2;
                   1259:     k->revision = 0x01;
                   1260:     k->class_id = PCI_CLASS_SERIAL_USB;
                   1261:     dc->vmsd = &vmstate_uhci;
                   1262:     dc->props = uhci_properties;
                   1263: }
                   1264: 
                   1265: static TypeInfo piix3_uhci_info = {
                   1266:     .name          = "piix3-usb-uhci",
                   1267:     .parent        = TYPE_PCI_DEVICE,
                   1268:     .instance_size = sizeof(UHCIState),
                   1269:     .class_init    = piix3_uhci_class_init,
                   1270: };
                   1271: 
                   1272: static void piix4_uhci_class_init(ObjectClass *klass, void *data)
                   1273: {
                   1274:     DeviceClass *dc = DEVICE_CLASS(klass);
                   1275:     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
                   1276: 
                   1277:     k->init = usb_uhci_common_initfn;
                   1278:     k->exit = usb_uhci_exit;
                   1279:     k->vendor_id = PCI_VENDOR_ID_INTEL;
                   1280:     k->device_id = PCI_DEVICE_ID_INTEL_82371AB_2;
                   1281:     k->revision = 0x01;
                   1282:     k->class_id = PCI_CLASS_SERIAL_USB;
                   1283:     dc->vmsd = &vmstate_uhci;
                   1284:     dc->props = uhci_properties;
                   1285: }
                   1286: 
                   1287: static TypeInfo piix4_uhci_info = {
                   1288:     .name          = "piix4-usb-uhci",
                   1289:     .parent        = TYPE_PCI_DEVICE,
                   1290:     .instance_size = sizeof(UHCIState),
                   1291:     .class_init    = piix4_uhci_class_init,
                   1292: };
                   1293: 
                   1294: static void vt82c686b_uhci_class_init(ObjectClass *klass, void *data)
                   1295: {
                   1296:     DeviceClass *dc = DEVICE_CLASS(klass);
                   1297:     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
                   1298: 
                   1299:     k->init = usb_uhci_vt82c686b_initfn;
                   1300:     k->exit = usb_uhci_exit;
                   1301:     k->vendor_id = PCI_VENDOR_ID_VIA;
                   1302:     k->device_id = PCI_DEVICE_ID_VIA_UHCI;
                   1303:     k->revision = 0x01;
                   1304:     k->class_id = PCI_CLASS_SERIAL_USB;
                   1305:     dc->vmsd = &vmstate_uhci;
                   1306:     dc->props = uhci_properties;
                   1307: }
                   1308: 
                   1309: static TypeInfo vt82c686b_uhci_info = {
                   1310:     .name          = "vt82c686b-usb-uhci",
                   1311:     .parent        = TYPE_PCI_DEVICE,
                   1312:     .instance_size = sizeof(UHCIState),
                   1313:     .class_init    = vt82c686b_uhci_class_init,
                   1314: };
                   1315: 
                   1316: static void ich9_uhci1_class_init(ObjectClass *klass, void *data)
                   1317: {
                   1318:     DeviceClass *dc = DEVICE_CLASS(klass);
                   1319:     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
                   1320: 
                   1321:     k->init = usb_uhci_common_initfn;
                   1322:     k->vendor_id = PCI_VENDOR_ID_INTEL;
                   1323:     k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1;
                   1324:     k->revision = 0x03;
                   1325:     k->class_id = PCI_CLASS_SERIAL_USB;
                   1326:     dc->vmsd = &vmstate_uhci;
                   1327:     dc->props = uhci_properties;
                   1328: }
                   1329: 
                   1330: static TypeInfo ich9_uhci1_info = {
                   1331:     .name          = "ich9-usb-uhci1",
                   1332:     .parent        = TYPE_PCI_DEVICE,
                   1333:     .instance_size = sizeof(UHCIState),
                   1334:     .class_init    = ich9_uhci1_class_init,
                   1335: };
                   1336: 
                   1337: static void ich9_uhci2_class_init(ObjectClass *klass, void *data)
                   1338: {
                   1339:     DeviceClass *dc = DEVICE_CLASS(klass);
                   1340:     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
                   1341: 
                   1342:     k->init = usb_uhci_common_initfn;
                   1343:     k->vendor_id = PCI_VENDOR_ID_INTEL;
                   1344:     k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2;
                   1345:     k->revision = 0x03;
                   1346:     k->class_id = PCI_CLASS_SERIAL_USB;
                   1347:     dc->vmsd = &vmstate_uhci;
                   1348:     dc->props = uhci_properties;
                   1349: }
                   1350: 
                   1351: static TypeInfo ich9_uhci2_info = {
                   1352:     .name          = "ich9-usb-uhci2",
                   1353:     .parent        = TYPE_PCI_DEVICE,
                   1354:     .instance_size = sizeof(UHCIState),
                   1355:     .class_init    = ich9_uhci2_class_init,
                   1356: };
                   1357: 
                   1358: static void ich9_uhci3_class_init(ObjectClass *klass, void *data)
                   1359: {
                   1360:     DeviceClass *dc = DEVICE_CLASS(klass);
                   1361:     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
                   1362: 
                   1363:     k->init = usb_uhci_common_initfn;
                   1364:     k->vendor_id = PCI_VENDOR_ID_INTEL;
                   1365:     k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3;
                   1366:     k->revision = 0x03;
                   1367:     k->class_id = PCI_CLASS_SERIAL_USB;
                   1368:     dc->vmsd = &vmstate_uhci;
                   1369:     dc->props = uhci_properties;
                   1370: }
                   1371: 
                   1372: static TypeInfo ich9_uhci3_info = {
                   1373:     .name          = "ich9-usb-uhci3",
                   1374:     .parent        = TYPE_PCI_DEVICE,
                   1375:     .instance_size = sizeof(UHCIState),
                   1376:     .class_init    = ich9_uhci3_class_init,
                   1377: };
                   1378: 
                   1379: static void uhci_register_types(void)
                   1380: {
                   1381:     type_register_static(&piix3_uhci_info);
                   1382:     type_register_static(&piix4_uhci_info);
                   1383:     type_register_static(&vt82c686b_uhci_info);
                   1384:     type_register_static(&ich9_uhci1_info);
                   1385:     type_register_static(&ich9_uhci2_info);
                   1386:     type_register_static(&ich9_uhci3_info);
                   1387: }
                   1388: 
                   1389: type_init(uhci_register_types)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.