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

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

unix.superglobalmegacorp.com

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