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

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

unix.superglobalmegacorp.com

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