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

1.1       root        1: /*
                      2:  * USB UHCI controller emulation
1.1.1.5   root        3:  *
1.1       root        4:  * Copyright (c) 2005 Fabrice Bellard
1.1.1.5   root        5:  *
1.1.1.6   root        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:  *
1.1       root       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:  */
1.1.1.5   root       28: #include "hw.h"
                     29: #include "usb.h"
                     30: #include "pci.h"
                     31: #include "qemu-timer.h"
1.1.1.8   root       32: #include "usb-uhci.h"
1.1.1.13! root       33: #include "iov.h"
        !            34: #include "dma.h"
1.1       root       35: 
                     36: //#define DEBUG
1.1.1.6   root       37: //#define DEBUG_DUMP_DATA
1.1       root       38: 
1.1.1.5   root       39: #define UHCI_CMD_FGR      (1 << 4)
                     40: #define UHCI_CMD_EGSM     (1 << 3)
1.1       root       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: 
1.1.1.11  root       62: #define UHCI_PORT_SUSPEND (1 << 12)
1.1       root       63: #define UHCI_PORT_RESET (1 << 9)
                     64: #define UHCI_PORT_LSDA  (1 << 8)
1.1.1.11  root       65: #define UHCI_PORT_RD    (1 << 6)
1.1       root       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: 
1.1.1.11  root       71: #define UHCI_PORT_READ_ONLY    (0x1bb)
                     72: #define UHCI_PORT_WRITE_CLEAR  (UHCI_PORT_CSC | UHCI_PORT_ENC)
                     73: 
1.1       root       74: #define FRAME_TIMER_FREQ 1000
                     75: 
                     76: #define FRAME_MAX_LOOPS  100
                     77: 
                     78: #define NB_PORTS 2
                     79: 
1.1.1.6   root       80: #ifdef DEBUG
1.1.1.10  root       81: #define DPRINTF printf
1.1.1.6   root       82: 
1.1.1.7   root       83: static const char *pid2str(int pid)
1.1.1.6   root       84: {
                     85:     switch (pid) {
                     86:     case USB_TOKEN_SETUP: return "SETUP";
                     87:     case USB_TOKEN_IN:    return "IN";
                     88:     case USB_TOKEN_OUT:   return "OUT";
                     89:     }
                     90:     return "?";
                     91: }
                     92: 
                     93: #else
1.1.1.10  root       94: #define DPRINTF(...)
1.1.1.6   root       95: #endif
                     96: 
                     97: #ifdef DEBUG_DUMP_DATA
1.1.1.13! root       98: static void dump_data(USBPacket *p, int ret)
1.1.1.6   root       99: {
1.1.1.13! root      100:     iov_hexdump(p->iov.iov, p->iov.niov, stderr, "uhci", ret);
1.1.1.6   root      101: }
                    102: #else
1.1.1.13! root      103: static void dump_data(USBPacket *p, int ret) {}
1.1.1.6   root      104: #endif
                    105: 
1.1.1.12  root      106: typedef struct UHCIState UHCIState;
                    107: 
1.1.1.6   root      108: /* 
                    109:  * Pending async transaction.
                    110:  * 'packet' must be the first field because completion
                    111:  * handler does "(UHCIAsync *) pkt" cast.
                    112:  */
                    113: typedef struct UHCIAsync {
                    114:     USBPacket packet;
1.1.1.13! root      115:     QEMUSGList sgl;
1.1.1.12  root      116:     UHCIState *uhci;
                    117:     QTAILQ_ENTRY(UHCIAsync) next;
1.1.1.6   root      118:     uint32_t  td;
                    119:     uint32_t  token;
                    120:     int8_t    valid;
1.1.1.10  root      121:     uint8_t   isoc;
1.1.1.6   root      122:     uint8_t   done;
                    123: } UHCIAsync;
                    124: 
1.1       root      125: typedef struct UHCIPort {
                    126:     USBPort port;
                    127:     uint16_t ctrl;
                    128: } UHCIPort;
                    129: 
1.1.1.12  root      130: struct UHCIState {
1.1       root      131:     PCIDevice dev;
1.1.1.13! root      132:     MemoryRegion io_bar;
1.1.1.12  root      133:     USBBus bus; /* Note unused when we're a companion controller */
1.1       root      134:     uint16_t cmd; /* cmd register */
                    135:     uint16_t status;
                    136:     uint16_t intr; /* interrupt enable register */
                    137:     uint16_t frnum; /* frame number */
                    138:     uint32_t fl_base_addr; /* frame list base address */
                    139:     uint8_t sof_timing;
                    140:     uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
1.1.1.10  root      141:     int64_t expire_time;
1.1       root      142:     QEMUTimer *frame_timer;
                    143:     UHCIPort ports[NB_PORTS];
1.1.1.4   root      144: 
                    145:     /* Interrupts that should be raised at the end of the current frame.  */
                    146:     uint32_t pending_int_mask;
1.1.1.6   root      147: 
                    148:     /* Active packets */
1.1.1.12  root      149:     QTAILQ_HEAD(,UHCIAsync) async_pending;
1.1.1.8   root      150:     uint8_t num_ports_vmstate;
1.1.1.12  root      151: 
                    152:     /* Properties */
                    153:     char *masterbus;
                    154:     uint32_t firstport;
                    155: };
1.1       root      156: 
                    157: typedef struct UHCI_TD {
                    158:     uint32_t link;
                    159:     uint32_t ctrl; /* see TD_CTRL_xxx */
                    160:     uint32_t token;
                    161:     uint32_t buffer;
                    162: } UHCI_TD;
                    163: 
                    164: typedef struct UHCI_QH {
                    165:     uint32_t link;
                    166:     uint32_t el_link;
                    167: } UHCI_QH;
                    168: 
1.1.1.6   root      169: static UHCIAsync *uhci_async_alloc(UHCIState *s)
                    170: {
1.1.1.13! root      171:     UHCIAsync *async = g_malloc(sizeof(UHCIAsync));
1.1.1.6   root      172: 
                    173:     memset(&async->packet, 0, sizeof(async->packet));
1.1.1.12  root      174:     async->uhci  = s;
1.1.1.6   root      175:     async->valid = 0;
                    176:     async->td    = 0;
                    177:     async->token = 0;
                    178:     async->done  = 0;
1.1.1.10  root      179:     async->isoc  = 0;
1.1.1.13! root      180:     usb_packet_init(&async->packet);
        !           181:     pci_dma_sglist_init(&async->sgl, &s->dev, 1);
1.1.1.6   root      182: 
                    183:     return async;
                    184: }
                    185: 
                    186: static void uhci_async_free(UHCIState *s, UHCIAsync *async)
                    187: {
1.1.1.13! root      188:     usb_packet_cleanup(&async->packet);
        !           189:     qemu_sglist_destroy(&async->sgl);
        !           190:     g_free(async);
1.1.1.6   root      191: }
                    192: 
                    193: static void uhci_async_link(UHCIState *s, UHCIAsync *async)
                    194: {
1.1.1.12  root      195:     QTAILQ_INSERT_HEAD(&s->async_pending, async, next);
1.1.1.6   root      196: }
                    197: 
                    198: static void uhci_async_unlink(UHCIState *s, UHCIAsync *async)
                    199: {
1.1.1.12  root      200:     QTAILQ_REMOVE(&s->async_pending, async, next);
1.1.1.6   root      201: }
                    202: 
                    203: static void uhci_async_cancel(UHCIState *s, UHCIAsync *async)
                    204: {
1.1.1.10  root      205:     DPRINTF("uhci: cancel td 0x%x token 0x%x done %u\n",
1.1.1.6   root      206:            async->td, async->token, async->done);
                    207: 
                    208:     if (!async->done)
                    209:         usb_cancel_packet(&async->packet);
                    210:     uhci_async_free(s, async);
                    211: }
                    212: 
                    213: /*
                    214:  * Mark all outstanding async packets as invalid.
                    215:  * This is used for canceling them when TDs are removed by the HCD.
                    216:  */
                    217: static UHCIAsync *uhci_async_validate_begin(UHCIState *s)
                    218: {
1.1.1.12  root      219:     UHCIAsync *async;
1.1.1.6   root      220: 
1.1.1.12  root      221:     QTAILQ_FOREACH(async, &s->async_pending, next) {
1.1.1.6   root      222:         async->valid--;
                    223:     }
                    224:     return NULL;
                    225: }
                    226: 
                    227: /*
                    228:  * Cancel async packets that are no longer valid
                    229:  */
                    230: static void uhci_async_validate_end(UHCIState *s)
                    231: {
1.1.1.12  root      232:     UHCIAsync *curr, *n;
1.1.1.6   root      233: 
1.1.1.12  root      234:     QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) {
1.1.1.6   root      235:         if (curr->valid > 0) {
                    236:             continue;
                    237:         }
1.1.1.12  root      238:         uhci_async_unlink(s, curr);
                    239:         uhci_async_cancel(s, curr);
                    240:     }
                    241: }
1.1.1.6   root      242: 
1.1.1.12  root      243: static void uhci_async_cancel_device(UHCIState *s, USBDevice *dev)
                    244: {
                    245:     UHCIAsync *curr, *n;
1.1.1.6   root      246: 
1.1.1.12  root      247:     QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) {
                    248:         if (curr->packet.owner != dev) {
                    249:             continue;
                    250:         }
                    251:         uhci_async_unlink(s, curr);
1.1.1.6   root      252:         uhci_async_cancel(s, curr);
                    253:     }
                    254: }
                    255: 
                    256: static void uhci_async_cancel_all(UHCIState *s)
                    257: {
1.1.1.12  root      258:     UHCIAsync *curr, *n;
1.1.1.6   root      259: 
1.1.1.12  root      260:     QTAILQ_FOREACH_SAFE(curr, &s->async_pending, next, n) {
                    261:         uhci_async_unlink(s, curr);
1.1.1.6   root      262:         uhci_async_cancel(s, curr);
                    263:     }
                    264: }
                    265: 
                    266: static UHCIAsync *uhci_async_find_td(UHCIState *s, uint32_t addr, uint32_t token)
                    267: {
1.1.1.12  root      268:     UHCIAsync *async;
1.1.1.6   root      269:     UHCIAsync *match = NULL;
                    270:     int count = 0;
                    271: 
                    272:     /*
                    273:      * We're looking for the best match here. ie both td addr and token.
                    274:      * Otherwise we return last good match. ie just token.
                    275:      * It's ok to match just token because it identifies the transaction
                    276:      * rather well, token includes: device addr, endpoint, size, etc.
                    277:      *
                    278:      * Also since we queue async transactions in reverse order by returning
                    279:      * last good match we restores the order.
                    280:      *
                    281:      * It's expected that we wont have a ton of outstanding transactions.
                    282:      * If we ever do we'd want to optimize this algorithm.
                    283:      */
                    284: 
1.1.1.12  root      285:     QTAILQ_FOREACH(async, &s->async_pending, next) {
1.1.1.6   root      286:         if (async->token == token) {
                    287:             /* Good match */
                    288:             match = async;
                    289: 
                    290:             if (async->td == addr) {
                    291:                 /* Best match */
                    292:                 break;
                    293:             }
                    294:         }
                    295:         count++;
                    296:     }
                    297: 
                    298:     if (count > 64)
                    299:        fprintf(stderr, "uhci: warning lots of async transactions\n");
                    300: 
                    301:     return match;
                    302: }
                    303: 
1.1       root      304: static void uhci_update_irq(UHCIState *s)
                    305: {
                    306:     int level;
                    307:     if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
                    308:         ((s->status2 & 2) && (s->intr & (1 << 3))) ||
                    309:         ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
                    310:         ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
                    311:         (s->status & UHCI_STS_HSERR) ||
                    312:         (s->status & UHCI_STS_HCPERR)) {
                    313:         level = 1;
                    314:     } else {
                    315:         level = 0;
                    316:     }
1.1.1.5   root      317:     qemu_set_irq(s->dev.irq[3], level);
1.1       root      318: }
                    319: 
1.1.1.7   root      320: static void uhci_reset(void *opaque)
1.1       root      321: {
1.1.1.7   root      322:     UHCIState *s = opaque;
1.1       root      323:     uint8_t *pci_conf;
                    324:     int i;
                    325:     UHCIPort *port;
                    326: 
1.1.1.10  root      327:     DPRINTF("uhci: full reset\n");
1.1.1.6   root      328: 
1.1       root      329:     pci_conf = s->dev.config;
                    330: 
                    331:     pci_conf[0x6a] = 0x01; /* usb clock */
                    332:     pci_conf[0x6b] = 0x00;
                    333:     s->cmd = 0;
                    334:     s->status = 0;
                    335:     s->status2 = 0;
                    336:     s->intr = 0;
                    337:     s->fl_base_addr = 0;
                    338:     s->sof_timing = 64;
1.1.1.6   root      339: 
1.1       root      340:     for(i = 0; i < NB_PORTS; i++) {
                    341:         port = &s->ports[i];
                    342:         port->ctrl = 0x0080;
1.1.1.13! root      343:         if (port->port.dev && port->port.dev->attached) {
        !           344:             usb_reset(&port->port);
1.1.1.11  root      345:         }
1.1       root      346:     }
1.1.1.6   root      347: 
                    348:     uhci_async_cancel_all(s);
1.1       root      349: }
                    350: 
1.1.1.8   root      351: static void uhci_pre_save(void *opaque)
1.1.1.5   root      352: {
                    353:     UHCIState *s = opaque;
                    354: 
1.1.1.6   root      355:     uhci_async_cancel_all(s);
1.1.1.5   root      356: }
                    357: 
1.1.1.8   root      358: static const VMStateDescription vmstate_uhci_port = {
                    359:     .name = "uhci port",
                    360:     .version_id = 1,
                    361:     .minimum_version_id = 1,
                    362:     .minimum_version_id_old = 1,
                    363:     .fields      = (VMStateField []) {
                    364:         VMSTATE_UINT16(ctrl, UHCIPort),
                    365:         VMSTATE_END_OF_LIST()
                    366:     }
                    367: };
                    368: 
                    369: static const VMStateDescription vmstate_uhci = {
                    370:     .name = "uhci",
1.1.1.10  root      371:     .version_id = 2,
1.1.1.8   root      372:     .minimum_version_id = 1,
                    373:     .minimum_version_id_old = 1,
                    374:     .pre_save = uhci_pre_save,
                    375:     .fields      = (VMStateField []) {
                    376:         VMSTATE_PCI_DEVICE(dev, UHCIState),
                    377:         VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState),
                    378:         VMSTATE_STRUCT_ARRAY(ports, UHCIState, NB_PORTS, 1,
                    379:                              vmstate_uhci_port, UHCIPort),
                    380:         VMSTATE_UINT16(cmd, UHCIState),
                    381:         VMSTATE_UINT16(status, UHCIState),
                    382:         VMSTATE_UINT16(intr, UHCIState),
                    383:         VMSTATE_UINT16(frnum, UHCIState),
                    384:         VMSTATE_UINT32(fl_base_addr, UHCIState),
                    385:         VMSTATE_UINT8(sof_timing, UHCIState),
                    386:         VMSTATE_UINT8(status2, UHCIState),
                    387:         VMSTATE_TIMER(frame_timer, UHCIState),
1.1.1.10  root      388:         VMSTATE_INT64_V(expire_time, UHCIState, 2),
1.1.1.8   root      389:         VMSTATE_END_OF_LIST()
                    390:     }
                    391: };
1.1.1.5   root      392: 
1.1       root      393: static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
                    394: {
                    395:     UHCIState *s = opaque;
1.1.1.5   root      396: 
1.1       root      397:     addr &= 0x1f;
                    398:     switch(addr) {
                    399:     case 0x0c:
                    400:         s->sof_timing = val;
                    401:         break;
                    402:     }
                    403: }
                    404: 
                    405: static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
                    406: {
                    407:     UHCIState *s = opaque;
                    408:     uint32_t val;
                    409: 
                    410:     addr &= 0x1f;
                    411:     switch(addr) {
                    412:     case 0x0c:
                    413:         val = s->sof_timing;
1.1.1.2   root      414:         break;
1.1       root      415:     default:
                    416:         val = 0xff;
                    417:         break;
                    418:     }
                    419:     return val;
                    420: }
                    421: 
                    422: static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
                    423: {
                    424:     UHCIState *s = opaque;
1.1.1.5   root      425: 
1.1       root      426:     addr &= 0x1f;
1.1.1.10  root      427:     DPRINTF("uhci: writew port=0x%04x val=0x%04x\n", addr, val);
1.1.1.6   root      428: 
1.1       root      429:     switch(addr) {
                    430:     case 0x00:
                    431:         if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
                    432:             /* start frame processing */
1.1.1.12  root      433:             s->expire_time = qemu_get_clock_ns(vm_clock) +
                    434:                 (get_ticks_per_sec() / FRAME_TIMER_FREQ);
                    435:             qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock));
1.1.1.2   root      436:             s->status &= ~UHCI_STS_HCHALTED;
                    437:         } else if (!(val & UHCI_CMD_RS)) {
                    438:             s->status |= UHCI_STS_HCHALTED;
1.1       root      439:         }
                    440:         if (val & UHCI_CMD_GRESET) {
                    441:             UHCIPort *port;
                    442:             USBDevice *dev;
                    443:             int i;
                    444: 
                    445:             /* send reset on the USB bus */
                    446:             for(i = 0; i < NB_PORTS; i++) {
                    447:                 port = &s->ports[i];
                    448:                 dev = port->port.dev;
1.1.1.13! root      449:                 if (dev && dev->attached) {
1.1.1.4   root      450:                     usb_send_msg(dev, USB_MSG_RESET);
1.1       root      451:                 }
                    452:             }
                    453:             uhci_reset(s);
                    454:             return;
                    455:         }
                    456:         if (val & UHCI_CMD_HCRESET) {
                    457:             uhci_reset(s);
                    458:             return;
                    459:         }
                    460:         s->cmd = val;
                    461:         break;
                    462:     case 0x02:
                    463:         s->status &= ~val;
                    464:         /* XXX: the chip spec is not coherent, so we add a hidden
                    465:            register to distinguish between IOC and SPD */
                    466:         if (val & UHCI_STS_USBINT)
                    467:             s->status2 = 0;
                    468:         uhci_update_irq(s);
                    469:         break;
                    470:     case 0x04:
                    471:         s->intr = val;
                    472:         uhci_update_irq(s);
                    473:         break;
                    474:     case 0x06:
                    475:         if (s->status & UHCI_STS_HCHALTED)
                    476:             s->frnum = val & 0x7ff;
                    477:         break;
                    478:     case 0x10 ... 0x1f:
                    479:         {
                    480:             UHCIPort *port;
                    481:             USBDevice *dev;
                    482:             int n;
                    483: 
                    484:             n = (addr >> 1) & 7;
                    485:             if (n >= NB_PORTS)
                    486:                 return;
                    487:             port = &s->ports[n];
                    488:             dev = port->port.dev;
1.1.1.13! root      489:             if (dev && dev->attached) {
1.1       root      490:                 /* port reset */
1.1.1.5   root      491:                 if ( (val & UHCI_PORT_RESET) &&
1.1       root      492:                      !(port->ctrl & UHCI_PORT_RESET) ) {
1.1.1.4   root      493:                     usb_send_msg(dev, USB_MSG_RESET);
1.1       root      494:                 }
                    495:             }
1.1.1.11  root      496:             port->ctrl &= UHCI_PORT_READ_ONLY;
                    497:             port->ctrl |= (val & ~UHCI_PORT_READ_ONLY);
1.1       root      498:             /* some bits are reset when a '1' is written to them */
1.1.1.11  root      499:             port->ctrl &= ~(val & UHCI_PORT_WRITE_CLEAR);
1.1       root      500:         }
                    501:         break;
                    502:     }
                    503: }
                    504: 
                    505: static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
                    506: {
                    507:     UHCIState *s = opaque;
                    508:     uint32_t val;
                    509: 
                    510:     addr &= 0x1f;
                    511:     switch(addr) {
                    512:     case 0x00:
                    513:         val = s->cmd;
                    514:         break;
                    515:     case 0x02:
                    516:         val = s->status;
                    517:         break;
                    518:     case 0x04:
                    519:         val = s->intr;
                    520:         break;
                    521:     case 0x06:
                    522:         val = s->frnum;
                    523:         break;
                    524:     case 0x10 ... 0x1f:
                    525:         {
                    526:             UHCIPort *port;
                    527:             int n;
                    528:             n = (addr >> 1) & 7;
1.1.1.5   root      529:             if (n >= NB_PORTS)
1.1       root      530:                 goto read_default;
                    531:             port = &s->ports[n];
                    532:             val = port->ctrl;
                    533:         }
                    534:         break;
                    535:     default:
                    536:     read_default:
                    537:         val = 0xff7f; /* disabled port */
                    538:         break;
                    539:     }
1.1.1.6   root      540: 
1.1.1.10  root      541:     DPRINTF("uhci: readw port=0x%04x val=0x%04x\n", addr, val);
1.1.1.6   root      542: 
1.1       root      543:     return val;
                    544: }
                    545: 
                    546: static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
                    547: {
                    548:     UHCIState *s = opaque;
                    549: 
                    550:     addr &= 0x1f;
1.1.1.10  root      551:     DPRINTF("uhci: writel port=0x%04x val=0x%08x\n", addr, val);
1.1.1.6   root      552: 
1.1       root      553:     switch(addr) {
                    554:     case 0x08:
                    555:         s->fl_base_addr = val & ~0xfff;
                    556:         break;
                    557:     }
                    558: }
                    559: 
                    560: static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
                    561: {
                    562:     UHCIState *s = opaque;
                    563:     uint32_t val;
                    564: 
                    565:     addr &= 0x1f;
                    566:     switch(addr) {
                    567:     case 0x08:
                    568:         val = s->fl_base_addr;
                    569:         break;
                    570:     default:
                    571:         val = 0xffffffff;
                    572:         break;
                    573:     }
                    574:     return val;
                    575: }
                    576: 
1.1.1.5   root      577: /* signal resume if controller suspended */
                    578: static void uhci_resume (void *opaque)
                    579: {
                    580:     UHCIState *s = (UHCIState *)opaque;
                    581: 
                    582:     if (!s)
                    583:         return;
                    584: 
                    585:     if (s->cmd & UHCI_CMD_EGSM) {
                    586:         s->cmd |= UHCI_CMD_FGR;
                    587:         s->status |= UHCI_STS_RD;
                    588:         uhci_update_irq(s);
                    589:     }
                    590: }
                    591: 
1.1.1.11  root      592: static void uhci_attach(USBPort *port1)
1.1       root      593: {
                    594:     UHCIState *s = port1->opaque;
                    595:     UHCIPort *port = &s->ports[port1->index];
                    596: 
1.1.1.11  root      597:     /* set connect status */
                    598:     port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
1.1.1.3   root      599: 
1.1.1.11  root      600:     /* update speed */
                    601:     if (port->port.dev->speed == USB_SPEED_LOW) {
                    602:         port->ctrl |= UHCI_PORT_LSDA;
                    603:     } else {
                    604:         port->ctrl &= ~UHCI_PORT_LSDA;
                    605:     }
1.1.1.5   root      606: 
1.1.1.11  root      607:     uhci_resume(s);
                    608: }
1.1.1.5   root      609: 
1.1.1.11  root      610: static void uhci_detach(USBPort *port1)
                    611: {
                    612:     UHCIState *s = port1->opaque;
                    613:     UHCIPort *port = &s->ports[port1->index];
1.1.1.5   root      614: 
1.1.1.12  root      615:     uhci_async_cancel_device(s, port1->dev);
                    616: 
1.1.1.11  root      617:     /* set connect status */
                    618:     if (port->ctrl & UHCI_PORT_CCS) {
                    619:         port->ctrl &= ~UHCI_PORT_CCS;
                    620:         port->ctrl |= UHCI_PORT_CSC;
                    621:     }
                    622:     /* disable port */
                    623:     if (port->ctrl & UHCI_PORT_EN) {
                    624:         port->ctrl &= ~UHCI_PORT_EN;
                    625:         port->ctrl |= UHCI_PORT_ENC;
                    626:     }
1.1.1.5   root      627: 
1.1.1.11  root      628:     uhci_resume(s);
                    629: }
                    630: 
1.1.1.12  root      631: static void uhci_child_detach(USBPort *port1, USBDevice *child)
1.1.1.11  root      632: {
1.1.1.12  root      633:     UHCIState *s = port1->opaque;
                    634: 
                    635:     uhci_async_cancel_device(s, child);
                    636: }
                    637: 
                    638: static void uhci_wakeup(USBPort *port1)
                    639: {
                    640:     UHCIState *s = port1->opaque;
                    641:     UHCIPort *port = &s->ports[port1->index];
1.1.1.11  root      642: 
                    643:     if (port->ctrl & UHCI_PORT_SUSPEND && !(port->ctrl & UHCI_PORT_RD)) {
                    644:         port->ctrl |= UHCI_PORT_RD;
                    645:         uhci_resume(s);
1.1       root      646:     }
                    647: }
                    648: 
1.1.1.4   root      649: static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
1.1       root      650: {
                    651:     int i, ret;
                    652: 
1.1.1.13! root      653:     DPRINTF("uhci: packet enter. pid %s addr 0x%02x ep %d len %zd\n",
        !           654:            pid2str(p->pid), p->devaddr, p->devep, p->iov.size);
1.1.1.6   root      655:     if (p->pid == USB_TOKEN_OUT || p->pid == USB_TOKEN_SETUP)
1.1.1.13! root      656:         dump_data(p, 0);
1.1.1.6   root      657: 
                    658:     ret = USB_RET_NODEV;
                    659:     for (i = 0; i < NB_PORTS && ret == USB_RET_NODEV; i++) {
                    660:         UHCIPort *port = &s->ports[i];
                    661:         USBDevice *dev = port->port.dev;
                    662: 
1.1.1.13! root      663:         if (dev && dev->attached && (port->ctrl & UHCI_PORT_EN)) {
1.1.1.12  root      664:             ret = usb_handle_packet(dev, p);
1.1.1.13! root      665:         }
1.1       root      666:     }
1.1.1.6   root      667: 
1.1.1.13! root      668:     DPRINTF("uhci: packet exit. ret %d len %zd\n", ret, p->iov.size);
1.1.1.6   root      669:     if (p->pid == USB_TOKEN_IN && ret > 0)
1.1.1.13! root      670:         dump_data(p, ret);
1.1.1.6   root      671: 
                    672:     return ret;
1.1       root      673: }
                    674: 
1.1.1.12  root      675: static void uhci_async_complete(USBPort *port, USBPacket *packet);
1.1.1.6   root      676: static void uhci_process_frame(UHCIState *s);
1.1.1.4   root      677: 
1.1       root      678: /* return -1 if fatal error (frame must be stopped)
                    679:           0 if TD successful
                    680:           1 if TD unsuccessful or inactive
                    681: */
1.1.1.6   root      682: static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_t *int_mask)
1.1       root      683: {
1.1.1.6   root      684:     int len = 0, max_len, err, ret;
1.1       root      685:     uint8_t pid;
                    686: 
1.1.1.6   root      687:     max_len = ((td->token >> 21) + 1) & 0x7ff;
                    688:     pid = td->token & 0xff;
                    689: 
1.1.1.13! root      690:     ret = async->packet.result;
1.1.1.6   root      691: 
                    692:     if (td->ctrl & TD_CTRL_IOS)
                    693:         td->ctrl &= ~TD_CTRL_ACTIVE;
1.1       root      694: 
1.1.1.6   root      695:     if (ret < 0)
                    696:         goto out;
1.1.1.5   root      697: 
1.1.1.13! root      698:     len = async->packet.result;
1.1.1.6   root      699:     td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
                    700: 
                    701:     /* The NAK bit may have been set by a previous frame, so clear it
                    702:        here.  The docs are somewhat unclear, but win2k relies on this
                    703:        behavior.  */
                    704:     td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
1.1.1.9   root      705:     if (td->ctrl & TD_CTRL_IOC)
                    706:         *int_mask |= 0x01;
1.1.1.6   root      707: 
                    708:     if (pid == USB_TOKEN_IN) {
                    709:         if (len > max_len) {
                    710:             ret = USB_RET_BABBLE;
                    711:             goto out;
1.1.1.4   root      712:         }
1.1.1.5   root      713: 
1.1.1.6   root      714:         if ((td->ctrl & TD_CTRL_SPD) && len < max_len) {
1.1       root      715:             *int_mask |= 0x02;
                    716:             /* short packet: do not update QH */
1.1.1.10  root      717:             DPRINTF("uhci: short packet. td 0x%x token 0x%x\n", async->td, async->token);
1.1       root      718:             return 1;
                    719:         }
1.1.1.6   root      720:     }
                    721: 
                    722:     /* success */
                    723:     return 0;
                    724: 
                    725: out:
                    726:     switch(ret) {
                    727:     case USB_RET_STALL:
                    728:         td->ctrl |= TD_CTRL_STALL;
                    729:         td->ctrl &= ~TD_CTRL_ACTIVE;
1.1.1.12  root      730:         s->status |= UHCI_STS_USBERR;
                    731:         if (td->ctrl & TD_CTRL_IOC) {
                    732:             *int_mask |= 0x01;
                    733:         }
                    734:         uhci_update_irq(s);
1.1.1.6   root      735:         return 1;
                    736: 
                    737:     case USB_RET_BABBLE:
                    738:         td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
                    739:         td->ctrl &= ~TD_CTRL_ACTIVE;
1.1.1.12  root      740:         s->status |= UHCI_STS_USBERR;
                    741:         if (td->ctrl & TD_CTRL_IOC) {
                    742:             *int_mask |= 0x01;
                    743:         }
                    744:         uhci_update_irq(s);
1.1.1.6   root      745:         /* frame interrupted */
                    746:         return -1;
                    747: 
                    748:     case USB_RET_NAK:
                    749:         td->ctrl |= TD_CTRL_NAK;
                    750:         if (pid == USB_TOKEN_SETUP)
                    751:             break;
                    752:        return 1;
                    753: 
                    754:     case USB_RET_NODEV:
                    755:     default:
                    756:        break;
                    757:     }
                    758: 
                    759:     /* Retry the TD if error count is not zero */
                    760: 
                    761:     td->ctrl |= TD_CTRL_TIMEOUT;
                    762:     err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
                    763:     if (err != 0) {
                    764:         err--;
                    765:         if (err == 0) {
1.1       root      766:             td->ctrl &= ~TD_CTRL_ACTIVE;
1.1.1.6   root      767:             s->status |= UHCI_STS_USBERR;
1.1.1.9   root      768:             if (td->ctrl & TD_CTRL_IOC)
                    769:                 *int_mask |= 0x01;
1.1.1.6   root      770:             uhci_update_irq(s);
1.1       root      771:         }
                    772:     }
1.1.1.6   root      773:     td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
                    774:         (err << TD_CTRL_ERROR_SHIFT);
                    775:     return 1;
1.1       root      776: }
                    777: 
1.1.1.6   root      778: static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *int_mask)
                    779: {
                    780:     UHCIAsync *async;
                    781:     int len = 0, max_len;
1.1.1.10  root      782:     uint8_t pid, isoc;
                    783:     uint32_t token;
1.1.1.6   root      784: 
                    785:     /* Is active ? */
                    786:     if (!(td->ctrl & TD_CTRL_ACTIVE))
                    787:         return 1;
                    788: 
1.1.1.10  root      789:     /* token field is not unique for isochronous requests,
                    790:      * so use the destination buffer 
                    791:      */
                    792:     if (td->ctrl & TD_CTRL_IOS) {
                    793:         token = td->buffer;
                    794:         isoc = 1;
                    795:     } else {
                    796:         token = td->token;
                    797:         isoc = 0;
                    798:     }
                    799: 
                    800:     async = uhci_async_find_td(s, addr, token);
1.1.1.6   root      801:     if (async) {
                    802:         /* Already submitted */
                    803:         async->valid = 32;
                    804: 
                    805:         if (!async->done)
                    806:             return 1;
                    807: 
                    808:         uhci_async_unlink(s, async);
                    809:         goto done;
                    810:     }
                    811: 
                    812:     /* Allocate new packet */
                    813:     async = uhci_async_alloc(s);
                    814:     if (!async)
                    815:         return 1;
                    816: 
1.1.1.10  root      817:     /* valid needs to be large enough to handle 10 frame delay
                    818:      * for initial isochronous requests
                    819:      */
                    820:     async->valid = 32;
1.1.1.6   root      821:     async->td    = addr;
1.1.1.10  root      822:     async->token = token;
                    823:     async->isoc  = isoc;
1.1.1.6   root      824: 
                    825:     max_len = ((td->token >> 21) + 1) & 0x7ff;
                    826:     pid = td->token & 0xff;
                    827: 
1.1.1.13! root      828:     usb_packet_setup(&async->packet, pid, (td->token >> 8) & 0x7f,
        !           829:                      (td->token >> 15) & 0xf);
        !           830:     qemu_sglist_add(&async->sgl, td->buffer, max_len);
        !           831:     usb_packet_map(&async->packet, &async->sgl);
1.1.1.6   root      832: 
                    833:     switch(pid) {
                    834:     case USB_TOKEN_OUT:
                    835:     case USB_TOKEN_SETUP:
                    836:         len = uhci_broadcast_packet(s, &async->packet);
                    837:         if (len >= 0)
                    838:             len = max_len;
                    839:         break;
                    840: 
                    841:     case USB_TOKEN_IN:
                    842:         len = uhci_broadcast_packet(s, &async->packet);
                    843:         break;
                    844: 
                    845:     default:
                    846:         /* invalid pid : frame interrupted */
                    847:         uhci_async_free(s, async);
                    848:         s->status |= UHCI_STS_HCPERR;
                    849:         uhci_update_irq(s);
                    850:         return -1;
                    851:     }
                    852:  
                    853:     if (len == USB_RET_ASYNC) {
                    854:         uhci_async_link(s, async);
                    855:         return 2;
                    856:     }
                    857: 
1.1.1.13! root      858:     async->packet.result = len;
1.1.1.6   root      859: 
                    860: done:
                    861:     len = uhci_complete_td(s, td, async, int_mask);
1.1.1.13! root      862:     usb_packet_unmap(&async->packet);
1.1.1.6   root      863:     uhci_async_free(s, async);
                    864:     return len;
                    865: }
                    866: 
1.1.1.12  root      867: static void uhci_async_complete(USBPort *port, USBPacket *packet)
1.1.1.4   root      868: {
1.1.1.12  root      869:     UHCIAsync *async = container_of(packet, UHCIAsync, packet);
                    870:     UHCIState *s = async->uhci;
1.1.1.6   root      871: 
1.1.1.10  root      872:     DPRINTF("uhci: async complete. td 0x%x token 0x%x\n", async->td, async->token);
1.1.1.6   root      873: 
1.1.1.10  root      874:     if (async->isoc) {
                    875:         UHCI_TD td;
                    876:         uint32_t link = async->td;
                    877:         uint32_t int_mask = 0, val;
1.1.1.6   root      878: 
1.1.1.13! root      879:         pci_dma_read(&s->dev, link & ~0xf, (uint8_t *) &td, sizeof(td));
1.1.1.10  root      880:         le32_to_cpus(&td.link);
                    881:         le32_to_cpus(&td.ctrl);
                    882:         le32_to_cpus(&td.token);
                    883:         le32_to_cpus(&td.buffer);
                    884: 
                    885:         uhci_async_unlink(s, async);
                    886:         uhci_complete_td(s, &td, async, &int_mask);
                    887:         s->pending_int_mask |= int_mask;
                    888: 
                    889:         /* update the status bits of the TD */
                    890:         val = cpu_to_le32(td.ctrl);
1.1.1.13! root      891:         pci_dma_write(&s->dev, (link & ~0xf) + 4,
        !           892:                       (const uint8_t *)&val, sizeof(val));
1.1.1.10  root      893:         uhci_async_free(s, async);
                    894:     } else {
                    895:         async->done = 1;
                    896:         uhci_process_frame(s);
                    897:     }
1.1.1.6   root      898: }
                    899: 
                    900: static int is_valid(uint32_t link)
                    901: {
                    902:     return (link & 1) == 0;
                    903: }
                    904: 
                    905: static int is_qh(uint32_t link)
                    906: {
                    907:     return (link & 2) != 0;
                    908: }
                    909: 
                    910: static int depth_first(uint32_t link)
                    911: {
                    912:     return (link & 4) != 0;
                    913: }
                    914: 
                    915: /* QH DB used for detecting QH loops */
                    916: #define UHCI_MAX_QUEUES 128
                    917: typedef struct {
                    918:     uint32_t addr[UHCI_MAX_QUEUES];
                    919:     int      count;
                    920: } QhDb;
                    921: 
                    922: static void qhdb_reset(QhDb *db)
                    923: {
                    924:     db->count = 0;
                    925: }
                    926: 
                    927: /* Add QH to DB. Returns 1 if already present or DB is full. */
                    928: static int qhdb_insert(QhDb *db, uint32_t addr)
                    929: {
                    930:     int i;
                    931:     for (i = 0; i < db->count; i++)
                    932:         if (db->addr[i] == addr)
                    933:             return 1;
                    934: 
                    935:     if (db->count >= UHCI_MAX_QUEUES)
                    936:         return 1;
                    937: 
                    938:     db->addr[db->count++] = addr;
                    939:     return 0;
                    940: }
                    941: 
                    942: static void uhci_process_frame(UHCIState *s)
                    943: {
                    944:     uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
                    945:     uint32_t curr_qh;
                    946:     int cnt, ret;
1.1.1.4   root      947:     UHCI_TD td;
1.1.1.6   root      948:     UHCI_QH qh;
                    949:     QhDb qhdb;
                    950: 
                    951:     frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
                    952: 
1.1.1.10  root      953:     DPRINTF("uhci: processing frame %d addr 0x%x\n" , s->frnum, frame_addr);
1.1.1.6   root      954: 
1.1.1.13! root      955:     pci_dma_read(&s->dev, frame_addr, (uint8_t *)&link, 4);
1.1.1.6   root      956:     le32_to_cpus(&link);
                    957: 
                    958:     int_mask = 0;
                    959:     curr_qh  = 0;
                    960: 
                    961:     qhdb_reset(&qhdb);
                    962: 
                    963:     for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
                    964:         if (is_qh(link)) {
                    965:             /* QH */
                    966: 
                    967:             if (qhdb_insert(&qhdb, link)) {
                    968:                 /*
                    969:                  * We're going in circles. Which is not a bug because
                    970:                  * HCD is allowed to do that as part of the BW management. 
                    971:                  * In our case though it makes no sense to spin here. Sync transations 
                    972:                  * are already done, and async completion handler will re-process 
                    973:                  * the frame when something is ready.
                    974:                  */
1.1.1.10  root      975:                 DPRINTF("uhci: detected loop. qh 0x%x\n", link);
1.1.1.6   root      976:                 break;
                    977:             }
                    978: 
1.1.1.13! root      979:             pci_dma_read(&s->dev, link & ~0xf, (uint8_t *) &qh, sizeof(qh));
1.1.1.6   root      980:             le32_to_cpus(&qh.link);
                    981:             le32_to_cpus(&qh.el_link);
                    982: 
1.1.1.10  root      983:             DPRINTF("uhci: QH 0x%x load. link 0x%x elink 0x%x\n",
1.1.1.6   root      984:                     link, qh.link, qh.el_link);
1.1.1.4   root      985: 
1.1.1.6   root      986:             if (!is_valid(qh.el_link)) {
                    987:                 /* QH w/o elements */
                    988:                 curr_qh = 0;
                    989:                 link = qh.link;
                    990:             } else {
                    991:                 /* QH with elements */
                    992:                curr_qh = link;
                    993:                link = qh.el_link;
                    994:             }
                    995:             continue;
                    996:         }
1.1.1.5   root      997: 
1.1.1.6   root      998:         /* TD */
1.1.1.13! root      999:         pci_dma_read(&s->dev, link & ~0xf, (uint8_t *) &td, sizeof(td));
1.1.1.5   root     1000:         le32_to_cpus(&td.link);
                   1001:         le32_to_cpus(&td.ctrl);
                   1002:         le32_to_cpus(&td.token);
                   1003:         le32_to_cpus(&td.buffer);
                   1004: 
1.1.1.10  root     1005:         DPRINTF("uhci: TD 0x%x load. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n", 
1.1.1.6   root     1006:                 link, td.link, td.ctrl, td.token, curr_qh);
                   1007: 
                   1008:         old_td_ctrl = td.ctrl;
                   1009:         ret = uhci_handle_td(s, link, &td, &int_mask);
1.1.1.5   root     1010:         if (old_td_ctrl != td.ctrl) {
1.1.1.6   root     1011:             /* update the status bits of the TD */
1.1.1.5   root     1012:             val = cpu_to_le32(td.ctrl);
1.1.1.13! root     1013:             pci_dma_write(&s->dev, (link & ~0xf) + 4,
        !          1014:                           (const uint8_t *)&val, sizeof(val));
1.1.1.5   root     1015:         }
1.1.1.6   root     1016: 
                   1017:         if (ret < 0) {
                   1018:             /* interrupted frame */
                   1019:             break;
1.1.1.5   root     1020:         }
                   1021: 
1.1.1.6   root     1022:         if (ret == 2 || ret == 1) {
1.1.1.10  root     1023:             DPRINTF("uhci: TD 0x%x %s. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n",
1.1.1.6   root     1024:                     link, ret == 2 ? "pend" : "skip",
                   1025:                     td.link, td.ctrl, td.token, curr_qh);
1.1.1.5   root     1026: 
1.1.1.6   root     1027:             link = curr_qh ? qh.link : td.link;
                   1028:             continue;
                   1029:         }
                   1030: 
                   1031:         /* completed TD */
                   1032: 
1.1.1.10  root     1033:         DPRINTF("uhci: TD 0x%x done. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n", 
1.1.1.6   root     1034:                 link, td.link, td.ctrl, td.token, curr_qh);
                   1035: 
                   1036:         link = td.link;
                   1037: 
                   1038:         if (curr_qh) {
                   1039:            /* update QH element link */
                   1040:             qh.el_link = link;
1.1.1.4   root     1041:             val = cpu_to_le32(qh.el_link);
1.1.1.13! root     1042:             pci_dma_write(&s->dev, (curr_qh & ~0xf) + 4,
        !          1043:                           (const uint8_t *)&val, sizeof(val));
1.1.1.6   root     1044: 
                   1045:             if (!depth_first(link)) {
                   1046:                /* done with this QH */
                   1047: 
1.1.1.10  root     1048:                DPRINTF("uhci: QH 0x%x done. link 0x%x elink 0x%x\n",
1.1.1.6   root     1049:                        curr_qh, qh.link, qh.el_link);
                   1050: 
                   1051:                curr_qh = 0;
                   1052:                link    = qh.link;
                   1053:             }
1.1.1.4   root     1054:         }
1.1.1.6   root     1055: 
                   1056:         /* go to the next entry */
1.1.1.4   root     1057:     }
1.1.1.6   root     1058: 
1.1.1.10  root     1059:     s->pending_int_mask |= int_mask;
1.1.1.4   root     1060: }
                   1061: 
1.1       root     1062: static void uhci_frame_timer(void *opaque)
                   1063: {
                   1064:     UHCIState *s = opaque;
1.1.1.10  root     1065: 
                   1066:     /* prepare the timer for the next frame */
                   1067:     s->expire_time += (get_ticks_per_sec() / FRAME_TIMER_FREQ);
1.1       root     1068: 
                   1069:     if (!(s->cmd & UHCI_CMD_RS)) {
1.1.1.6   root     1070:         /* Full stop */
1.1       root     1071:         qemu_del_timer(s->frame_timer);
1.1.1.2   root     1072:         /* set hchalted bit in status - UHCI11D 2.1.2 */
                   1073:         s->status |= UHCI_STS_HCHALTED;
1.1.1.6   root     1074: 
1.1.1.10  root     1075:         DPRINTF("uhci: halted\n");
1.1       root     1076:         return;
                   1077:     }
1.1.1.6   root     1078: 
                   1079:     /* Complete the previous frame */
1.1.1.4   root     1080:     if (s->pending_int_mask) {
                   1081:         s->status2 |= s->pending_int_mask;
1.1.1.6   root     1082:         s->status  |= UHCI_STS_USBINT;
1.1.1.4   root     1083:         uhci_update_irq(s);
                   1084:     }
1.1.1.10  root     1085:     s->pending_int_mask = 0;
1.1.1.5   root     1086: 
1.1.1.6   root     1087:     /* Start new frame */
                   1088:     s->frnum = (s->frnum + 1) & 0x7ff;
                   1089: 
1.1.1.10  root     1090:     DPRINTF("uhci: new frame #%u\n" , s->frnum);
1.1.1.6   root     1091: 
                   1092:     uhci_async_validate_begin(s);
                   1093: 
                   1094:     uhci_process_frame(s);
                   1095: 
                   1096:     uhci_async_validate_end(s);
1.1.1.5   root     1097: 
1.1.1.10  root     1098:     qemu_mod_timer(s->frame_timer, s->expire_time);
1.1       root     1099: }
                   1100: 
1.1.1.13! root     1101: static const MemoryRegionPortio uhci_portio[] = {
        !          1102:     { 0, 32, 2, .write = uhci_ioport_writew, },
        !          1103:     { 0, 32, 2, .read = uhci_ioport_readw, },
        !          1104:     { 0, 32, 4, .write = uhci_ioport_writel, },
        !          1105:     { 0, 32, 4, .read = uhci_ioport_readl, },
        !          1106:     { 0, 32, 1, .write = uhci_ioport_writeb, },
        !          1107:     { 0, 32, 1, .read = uhci_ioport_readb, },
        !          1108:     PORTIO_END_OF_LIST()
        !          1109: };
1.1       root     1110: 
1.1.1.13! root     1111: static const MemoryRegionOps uhci_ioport_ops = {
        !          1112:     .old_portio = uhci_portio,
        !          1113: };
1.1       root     1114: 
1.1.1.11  root     1115: static USBPortOps uhci_port_ops = {
                   1116:     .attach = uhci_attach,
                   1117:     .detach = uhci_detach,
1.1.1.12  root     1118:     .child_detach = uhci_child_detach,
1.1.1.11  root     1119:     .wakeup = uhci_wakeup,
1.1.1.12  root     1120:     .complete = uhci_async_complete,
                   1121: };
                   1122: 
                   1123: static USBBusOps uhci_bus_ops = {
1.1.1.11  root     1124: };
                   1125: 
1.1.1.12  root     1126: static int usb_uhci_common_initfn(PCIDevice *dev)
1.1       root     1127: {
1.1.1.12  root     1128:     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
1.1.1.8   root     1129:     uint8_t *pci_conf = s->dev.config;
1.1       root     1130:     int i;
                   1131: 
1.1.1.10  root     1132:     pci_conf[PCI_CLASS_PROG] = 0x00;
                   1133:     /* TODO: reset value should be 0. */
1.1.1.13! root     1134:     pci_conf[PCI_INTERRUPT_PIN] = 4; /* interrupt pin D */
1.1.1.12  root     1135:     pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
1.1.1.5   root     1136: 
1.1.1.12  root     1137:     if (s->masterbus) {
                   1138:         USBPort *ports[NB_PORTS];
                   1139:         for(i = 0; i < NB_PORTS; i++) {
                   1140:             ports[i] = &s->ports[i].port;
                   1141:         }
                   1142:         if (usb_register_companion(s->masterbus, ports, NB_PORTS,
                   1143:                 s->firstport, s, &uhci_port_ops,
                   1144:                 USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
                   1145:             return -1;
                   1146:         }
                   1147:     } else {
                   1148:         usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
                   1149:         for (i = 0; i < NB_PORTS; i++) {
                   1150:             usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
                   1151:                               USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
                   1152:         }
                   1153:     }
                   1154:     s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s);
1.1.1.8   root     1155:     s->num_ports_vmstate = NB_PORTS;
1.1.1.12  root     1156:     QTAILQ_INIT(&s->async_pending);
1.1.1.5   root     1157: 
1.1.1.7   root     1158:     qemu_register_reset(uhci_reset, s);
1.1.1.5   root     1159: 
1.1.1.13! root     1160:     memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
1.1.1.5   root     1161:     /* Use region 4 for consistency with real hardware.  BSD guests seem
                   1162:        to rely on this.  */
1.1.1.13! root     1163:     pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
1.1.1.6   root     1164: 
1.1.1.8   root     1165:     return 0;
1.1.1.5   root     1166: }
                   1167: 
1.1.1.10  root     1168: static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
                   1169: {
                   1170:     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
                   1171:     uint8_t *pci_conf = s->dev.config;
                   1172: 
                   1173:     /* USB misc control 1/2 */
                   1174:     pci_set_long(pci_conf + 0x40,0x00001000);
                   1175:     /* PM capability */
                   1176:     pci_set_long(pci_conf + 0x80,0x00020001);
                   1177:     /* USB legacy support  */
                   1178:     pci_set_long(pci_conf + 0xc0,0x00002000);
                   1179: 
1.1.1.12  root     1180:     return usb_uhci_common_initfn(dev);
1.1.1.10  root     1181: }
                   1182: 
1.1.1.13! root     1183: static int usb_uhci_exit(PCIDevice *dev)
        !          1184: {
        !          1185:     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
        !          1186: 
        !          1187:     memory_region_destroy(&s->io_bar);
        !          1188:     return 0;
        !          1189: }
        !          1190: 
1.1.1.12  root     1191: static Property uhci_properties[] = {
                   1192:     DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
                   1193:     DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
                   1194:     DEFINE_PROP_END_OF_LIST(),
                   1195: };
                   1196: 
1.1.1.8   root     1197: static PCIDeviceInfo uhci_info[] = {
                   1198:     {
                   1199:         .qdev.name    = "piix3-usb-uhci",
                   1200:         .qdev.size    = sizeof(UHCIState),
                   1201:         .qdev.vmsd    = &vmstate_uhci,
1.1.1.12  root     1202:         .init         = usb_uhci_common_initfn,
1.1.1.13! root     1203:         .exit         = usb_uhci_exit,
1.1.1.12  root     1204:         .vendor_id    = PCI_VENDOR_ID_INTEL,
                   1205:         .device_id    = PCI_DEVICE_ID_INTEL_82371SB_2,
                   1206:         .revision     = 0x01,
                   1207:         .class_id     = PCI_CLASS_SERIAL_USB,
                   1208:         .qdev.props   = uhci_properties,
1.1.1.8   root     1209:     },{
                   1210:         .qdev.name    = "piix4-usb-uhci",
                   1211:         .qdev.size    = sizeof(UHCIState),
                   1212:         .qdev.vmsd    = &vmstate_uhci,
1.1.1.12  root     1213:         .init         = usb_uhci_common_initfn,
1.1.1.13! root     1214:         .exit         = usb_uhci_exit,
1.1.1.12  root     1215:         .vendor_id    = PCI_VENDOR_ID_INTEL,
                   1216:         .device_id    = PCI_DEVICE_ID_INTEL_82371AB_2,
                   1217:         .revision     = 0x01,
                   1218:         .class_id     = PCI_CLASS_SERIAL_USB,
                   1219:         .qdev.props   = uhci_properties,
1.1.1.8   root     1220:     },{
1.1.1.10  root     1221:         .qdev.name    = "vt82c686b-usb-uhci",
                   1222:         .qdev.size    = sizeof(UHCIState),
                   1223:         .qdev.vmsd    = &vmstate_uhci,
                   1224:         .init         = usb_uhci_vt82c686b_initfn,
1.1.1.13! root     1225:         .exit         = usb_uhci_exit,
1.1.1.12  root     1226:         .vendor_id    = PCI_VENDOR_ID_VIA,
                   1227:         .device_id    = PCI_DEVICE_ID_VIA_UHCI,
                   1228:         .revision     = 0x01,
                   1229:         .class_id     = PCI_CLASS_SERIAL_USB,
                   1230:         .qdev.props   = uhci_properties,
                   1231:     },{
                   1232:         .qdev.name    = "ich9-usb-uhci1",
                   1233:         .qdev.size    = sizeof(UHCIState),
                   1234:         .qdev.vmsd    = &vmstate_uhci,
                   1235:         .init         = usb_uhci_common_initfn,
                   1236:         .vendor_id    = PCI_VENDOR_ID_INTEL,
                   1237:         .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
                   1238:         .revision     = 0x03,
                   1239:         .class_id     = PCI_CLASS_SERIAL_USB,
                   1240:         .qdev.props   = uhci_properties,
                   1241:     },{
                   1242:         .qdev.name    = "ich9-usb-uhci2",
                   1243:         .qdev.size    = sizeof(UHCIState),
                   1244:         .qdev.vmsd    = &vmstate_uhci,
                   1245:         .init         = usb_uhci_common_initfn,
                   1246:         .vendor_id    = PCI_VENDOR_ID_INTEL,
                   1247:         .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
                   1248:         .revision     = 0x03,
                   1249:         .class_id     = PCI_CLASS_SERIAL_USB,
                   1250:         .qdev.props   = uhci_properties,
                   1251:     },{
                   1252:         .qdev.name    = "ich9-usb-uhci3",
                   1253:         .qdev.size    = sizeof(UHCIState),
                   1254:         .qdev.vmsd    = &vmstate_uhci,
                   1255:         .init         = usb_uhci_common_initfn,
                   1256:         .vendor_id    = PCI_VENDOR_ID_INTEL,
                   1257:         .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
                   1258:         .revision     = 0x03,
                   1259:         .class_id     = PCI_CLASS_SERIAL_USB,
                   1260:         .qdev.props   = uhci_properties,
1.1.1.10  root     1261:     },{
1.1.1.8   root     1262:         /* end of list */
1.1       root     1263:     }
1.1.1.8   root     1264: };
1.1       root     1265: 
1.1.1.8   root     1266: static void uhci_register(void)
                   1267: {
                   1268:     pci_qdev_register_many(uhci_info);
                   1269: }
                   1270: device_init(uhci_register);
1.1       root     1271: 
1.1.1.8   root     1272: void usb_uhci_piix3_init(PCIBus *bus, int devfn)
                   1273: {
                   1274:     pci_create_simple(bus, devfn, "piix3-usb-uhci");
                   1275: }
1.1.1.6   root     1276: 
1.1.1.8   root     1277: void usb_uhci_piix4_init(PCIBus *bus, int devfn)
                   1278: {
                   1279:     pci_create_simple(bus, devfn, "piix4-usb-uhci");
1.1       root     1280: }
1.1.1.10  root     1281: 
                   1282: void usb_uhci_vt82c686b_init(PCIBus *bus, int devfn)
                   1283: {
                   1284:     pci_create_simple(bus, devfn, "vt82c686b-usb-uhci");
                   1285: }

unix.superglobalmegacorp.com

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