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

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

unix.superglobalmegacorp.com

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