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

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       root        6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
1.1.1.5 ! root       24: #include "hw.h"
        !            25: #include "usb.h"
        !            26: #include "pci.h"
        !            27: #include "qemu-timer.h"
1.1       root       28: 
                     29: //#define DEBUG
                     30: //#define DEBUG_PACKET
1.1.1.5 ! root       31: //#define DEBUG_ISOCH
1.1       root       32: 
1.1.1.5 ! root       33: #define UHCI_CMD_FGR      (1 << 4)
        !            34: #define UHCI_CMD_EGSM     (1 << 3)
1.1       root       35: #define UHCI_CMD_GRESET   (1 << 2)
                     36: #define UHCI_CMD_HCRESET  (1 << 1)
                     37: #define UHCI_CMD_RS       (1 << 0)
                     38: 
                     39: #define UHCI_STS_HCHALTED (1 << 5)
                     40: #define UHCI_STS_HCPERR   (1 << 4)
                     41: #define UHCI_STS_HSERR    (1 << 3)
                     42: #define UHCI_STS_RD       (1 << 2)
                     43: #define UHCI_STS_USBERR   (1 << 1)
                     44: #define UHCI_STS_USBINT   (1 << 0)
                     45: 
                     46: #define TD_CTRL_SPD     (1 << 29)
                     47: #define TD_CTRL_ERROR_SHIFT  27
                     48: #define TD_CTRL_IOS     (1 << 25)
                     49: #define TD_CTRL_IOC     (1 << 24)
                     50: #define TD_CTRL_ACTIVE  (1 << 23)
                     51: #define TD_CTRL_STALL   (1 << 22)
                     52: #define TD_CTRL_BABBLE  (1 << 20)
                     53: #define TD_CTRL_NAK     (1 << 19)
                     54: #define TD_CTRL_TIMEOUT (1 << 18)
                     55: 
                     56: #define UHCI_PORT_RESET (1 << 9)
                     57: #define UHCI_PORT_LSDA  (1 << 8)
                     58: #define UHCI_PORT_ENC   (1 << 3)
                     59: #define UHCI_PORT_EN    (1 << 2)
                     60: #define UHCI_PORT_CSC   (1 << 1)
                     61: #define UHCI_PORT_CCS   (1 << 0)
                     62: 
                     63: #define FRAME_TIMER_FREQ 1000
                     64: 
                     65: #define FRAME_MAX_LOOPS  100
                     66: 
                     67: #define NB_PORTS 2
                     68: 
                     69: typedef struct UHCIPort {
                     70:     USBPort port;
                     71:     uint16_t ctrl;
                     72: } UHCIPort;
                     73: 
                     74: typedef struct UHCIState {
                     75:     PCIDevice dev;
                     76:     uint16_t cmd; /* cmd register */
                     77:     uint16_t status;
                     78:     uint16_t intr; /* interrupt enable register */
                     79:     uint16_t frnum; /* frame number */
                     80:     uint32_t fl_base_addr; /* frame list base address */
                     81:     uint8_t sof_timing;
                     82:     uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
                     83:     QEMUTimer *frame_timer;
                     84:     UHCIPort ports[NB_PORTS];
1.1.1.4   root       85: 
                     86:     /* Interrupts that should be raised at the end of the current frame.  */
                     87:     uint32_t pending_int_mask;
                     88:     /* For simplicity of implementation we only allow a single pending USB
                     89:        request.  This means all usb traffic on this controller is effectively
                     90:        suspended until that transfer completes.  When the transfer completes
1.1.1.5 ! root       91:        the next transfer from that queue will be processed.  However
1.1.1.4   root       92:        other queues will not be processed until the next frame.  The solution
                     93:        is to allow multiple pending requests.  */
                     94:     uint32_t async_qh;
1.1.1.5 ! root       95:     uint32_t async_frame_addr;
1.1.1.4   root       96:     USBPacket usb_packet;
                     97:     uint8_t usb_buf[2048];
1.1       root       98: } UHCIState;
                     99: 
                    100: typedef struct UHCI_TD {
                    101:     uint32_t link;
                    102:     uint32_t ctrl; /* see TD_CTRL_xxx */
                    103:     uint32_t token;
                    104:     uint32_t buffer;
                    105: } UHCI_TD;
                    106: 
                    107: typedef struct UHCI_QH {
                    108:     uint32_t link;
                    109:     uint32_t el_link;
                    110: } UHCI_QH;
                    111: 
                    112: static void uhci_attach(USBPort *port1, USBDevice *dev);
                    113: 
                    114: static void uhci_update_irq(UHCIState *s)
                    115: {
                    116:     int level;
                    117:     if (((s->status2 & 1) && (s->intr & (1 << 2))) ||
                    118:         ((s->status2 & 2) && (s->intr & (1 << 3))) ||
                    119:         ((s->status & UHCI_STS_USBERR) && (s->intr & (1 << 0))) ||
                    120:         ((s->status & UHCI_STS_RD) && (s->intr & (1 << 1))) ||
                    121:         (s->status & UHCI_STS_HSERR) ||
                    122:         (s->status & UHCI_STS_HCPERR)) {
                    123:         level = 1;
                    124:     } else {
                    125:         level = 0;
                    126:     }
1.1.1.5 ! root      127:     qemu_set_irq(s->dev.irq[3], level);
1.1       root      128: }
                    129: 
                    130: static void uhci_reset(UHCIState *s)
                    131: {
                    132:     uint8_t *pci_conf;
                    133:     int i;
                    134:     UHCIPort *port;
                    135: 
                    136:     pci_conf = s->dev.config;
                    137: 
                    138:     pci_conf[0x6a] = 0x01; /* usb clock */
                    139:     pci_conf[0x6b] = 0x00;
                    140:     s->cmd = 0;
                    141:     s->status = 0;
                    142:     s->status2 = 0;
                    143:     s->intr = 0;
                    144:     s->fl_base_addr = 0;
                    145:     s->sof_timing = 64;
                    146:     for(i = 0; i < NB_PORTS; i++) {
                    147:         port = &s->ports[i];
                    148:         port->ctrl = 0x0080;
                    149:         if (port->port.dev)
                    150:             uhci_attach(&port->port, port->port.dev);
                    151:     }
                    152: }
                    153: 
1.1.1.5 ! root      154: #if 0
        !           155: static void uhci_save(QEMUFile *f, void *opaque)
        !           156: {
        !           157:     UHCIState *s = opaque;
        !           158:     uint8_t num_ports = NB_PORTS;
        !           159:     int i;
        !           160: 
        !           161:     pci_device_save(&s->dev, f);
        !           162: 
        !           163:     qemu_put_8s(f, &num_ports);
        !           164:     for (i = 0; i < num_ports; ++i)
        !           165:         qemu_put_be16s(f, &s->ports[i].ctrl);
        !           166:     qemu_put_be16s(f, &s->cmd);
        !           167:     qemu_put_be16s(f, &s->status);
        !           168:     qemu_put_be16s(f, &s->intr);
        !           169:     qemu_put_be16s(f, &s->frnum);
        !           170:     qemu_put_be32s(f, &s->fl_base_addr);
        !           171:     qemu_put_8s(f, &s->sof_timing);
        !           172:     qemu_put_8s(f, &s->status2);
        !           173:     qemu_put_timer(f, s->frame_timer);
        !           174: }
        !           175: 
        !           176: static int uhci_load(QEMUFile *f, void *opaque, int version_id)
        !           177: {
        !           178:     UHCIState *s = opaque;
        !           179:     uint8_t num_ports;
        !           180:     int i, ret;
        !           181: 
        !           182:     if (version_id > 1)
        !           183:         return -EINVAL;
        !           184: 
        !           185:     ret = pci_device_load(&s->dev, f);
        !           186:     if (ret < 0)
        !           187:         return ret;
        !           188: 
        !           189:     qemu_get_8s(f, &num_ports);
        !           190:     if (num_ports != NB_PORTS)
        !           191:         return -EINVAL;
        !           192: 
        !           193:     for (i = 0; i < num_ports; ++i)
        !           194:         qemu_get_be16s(f, &s->ports[i].ctrl);
        !           195:     qemu_get_be16s(f, &s->cmd);
        !           196:     qemu_get_be16s(f, &s->status);
        !           197:     qemu_get_be16s(f, &s->intr);
        !           198:     qemu_get_be16s(f, &s->frnum);
        !           199:     qemu_get_be32s(f, &s->fl_base_addr);
        !           200:     qemu_get_8s(f, &s->sof_timing);
        !           201:     qemu_get_8s(f, &s->status2);
        !           202:     qemu_get_timer(f, s->frame_timer);
        !           203: 
        !           204:     return 0;
        !           205: }
        !           206: #endif
        !           207: 
1.1       root      208: static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
                    209: {
                    210:     UHCIState *s = opaque;
1.1.1.5 ! root      211: 
1.1       root      212:     addr &= 0x1f;
                    213:     switch(addr) {
                    214:     case 0x0c:
                    215:         s->sof_timing = val;
                    216:         break;
                    217:     }
                    218: }
                    219: 
                    220: static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
                    221: {
                    222:     UHCIState *s = opaque;
                    223:     uint32_t val;
                    224: 
                    225:     addr &= 0x1f;
                    226:     switch(addr) {
                    227:     case 0x0c:
                    228:         val = s->sof_timing;
1.1.1.2   root      229:         break;
1.1       root      230:     default:
                    231:         val = 0xff;
                    232:         break;
                    233:     }
                    234:     return val;
                    235: }
                    236: 
                    237: static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
                    238: {
                    239:     UHCIState *s = opaque;
1.1.1.5 ! root      240: 
1.1       root      241:     addr &= 0x1f;
                    242: #ifdef DEBUG
                    243:     printf("uhci writew port=0x%04x val=0x%04x\n", addr, val);
                    244: #endif
                    245:     switch(addr) {
                    246:     case 0x00:
                    247:         if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
                    248:             /* start frame processing */
                    249:             qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
1.1.1.2   root      250:             s->status &= ~UHCI_STS_HCHALTED;
                    251:         } else if (!(val & UHCI_CMD_RS)) {
                    252:             s->status |= UHCI_STS_HCHALTED;
1.1       root      253:         }
                    254:         if (val & UHCI_CMD_GRESET) {
                    255:             UHCIPort *port;
                    256:             USBDevice *dev;
                    257:             int i;
                    258: 
                    259:             /* send reset on the USB bus */
                    260:             for(i = 0; i < NB_PORTS; i++) {
                    261:                 port = &s->ports[i];
                    262:                 dev = port->port.dev;
                    263:                 if (dev) {
1.1.1.4   root      264:                     usb_send_msg(dev, USB_MSG_RESET);
1.1       root      265:                 }
                    266:             }
                    267:             uhci_reset(s);
                    268:             return;
                    269:         }
                    270:         if (val & UHCI_CMD_HCRESET) {
                    271:             uhci_reset(s);
                    272:             return;
                    273:         }
                    274:         s->cmd = val;
                    275:         break;
                    276:     case 0x02:
                    277:         s->status &= ~val;
                    278:         /* XXX: the chip spec is not coherent, so we add a hidden
                    279:            register to distinguish between IOC and SPD */
                    280:         if (val & UHCI_STS_USBINT)
                    281:             s->status2 = 0;
                    282:         uhci_update_irq(s);
                    283:         break;
                    284:     case 0x04:
                    285:         s->intr = val;
                    286:         uhci_update_irq(s);
                    287:         break;
                    288:     case 0x06:
                    289:         if (s->status & UHCI_STS_HCHALTED)
                    290:             s->frnum = val & 0x7ff;
                    291:         break;
                    292:     case 0x10 ... 0x1f:
                    293:         {
                    294:             UHCIPort *port;
                    295:             USBDevice *dev;
                    296:             int n;
                    297: 
                    298:             n = (addr >> 1) & 7;
                    299:             if (n >= NB_PORTS)
                    300:                 return;
                    301:             port = &s->ports[n];
                    302:             dev = port->port.dev;
                    303:             if (dev) {
                    304:                 /* port reset */
1.1.1.5 ! root      305:                 if ( (val & UHCI_PORT_RESET) &&
1.1       root      306:                      !(port->ctrl & UHCI_PORT_RESET) ) {
1.1.1.4   root      307:                     usb_send_msg(dev, USB_MSG_RESET);
1.1       root      308:                 }
                    309:             }
                    310:             port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
                    311:             /* some bits are reset when a '1' is written to them */
                    312:             port->ctrl &= ~(val & 0x000a);
                    313:         }
                    314:         break;
                    315:     }
                    316: }
                    317: 
                    318: static uint32_t uhci_ioport_readw(void *opaque, uint32_t addr)
                    319: {
                    320:     UHCIState *s = opaque;
                    321:     uint32_t val;
                    322: 
                    323:     addr &= 0x1f;
                    324:     switch(addr) {
                    325:     case 0x00:
                    326:         val = s->cmd;
                    327:         break;
                    328:     case 0x02:
                    329:         val = s->status;
                    330:         break;
                    331:     case 0x04:
                    332:         val = s->intr;
                    333:         break;
                    334:     case 0x06:
                    335:         val = s->frnum;
                    336:         break;
                    337:     case 0x10 ... 0x1f:
                    338:         {
                    339:             UHCIPort *port;
                    340:             int n;
                    341:             n = (addr >> 1) & 7;
1.1.1.5 ! root      342:             if (n >= NB_PORTS)
1.1       root      343:                 goto read_default;
                    344:             port = &s->ports[n];
                    345:             val = port->ctrl;
                    346:         }
                    347:         break;
                    348:     default:
                    349:     read_default:
                    350:         val = 0xff7f; /* disabled port */
                    351:         break;
                    352:     }
                    353: #ifdef DEBUG
                    354:     printf("uhci readw port=0x%04x val=0x%04x\n", addr, val);
                    355: #endif
                    356:     return val;
                    357: }
                    358: 
                    359: static void uhci_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
                    360: {
                    361:     UHCIState *s = opaque;
                    362: 
                    363:     addr &= 0x1f;
                    364: #ifdef DEBUG
                    365:     printf("uhci writel port=0x%04x val=0x%08x\n", addr, val);
                    366: #endif
                    367:     switch(addr) {
                    368:     case 0x08:
                    369:         s->fl_base_addr = val & ~0xfff;
                    370:         break;
                    371:     }
                    372: }
                    373: 
                    374: static uint32_t uhci_ioport_readl(void *opaque, uint32_t addr)
                    375: {
                    376:     UHCIState *s = opaque;
                    377:     uint32_t val;
                    378: 
                    379:     addr &= 0x1f;
                    380:     switch(addr) {
                    381:     case 0x08:
                    382:         val = s->fl_base_addr;
                    383:         break;
                    384:     default:
                    385:         val = 0xffffffff;
                    386:         break;
                    387:     }
                    388:     return val;
                    389: }
                    390: 
1.1.1.5 ! root      391: /* signal resume if controller suspended */
        !           392: static void uhci_resume (void *opaque)
        !           393: {
        !           394:     UHCIState *s = (UHCIState *)opaque;
        !           395: 
        !           396:     if (!s)
        !           397:         return;
        !           398: 
        !           399:     if (s->cmd & UHCI_CMD_EGSM) {
        !           400:         s->cmd |= UHCI_CMD_FGR;
        !           401:         s->status |= UHCI_STS_RD;
        !           402:         uhci_update_irq(s);
        !           403:     }
        !           404: }
        !           405: 
1.1       root      406: static void uhci_attach(USBPort *port1, USBDevice *dev)
                    407: {
                    408:     UHCIState *s = port1->opaque;
                    409:     UHCIPort *port = &s->ports[port1->index];
                    410: 
                    411:     if (dev) {
                    412:         if (port->port.dev) {
                    413:             usb_attach(port1, NULL);
                    414:         }
                    415:         /* set connect status */
1.1.1.3   root      416:         port->ctrl |= UHCI_PORT_CCS | UHCI_PORT_CSC;
                    417: 
1.1       root      418:         /* update speed */
                    419:         if (dev->speed == USB_SPEED_LOW)
                    420:             port->ctrl |= UHCI_PORT_LSDA;
                    421:         else
                    422:             port->ctrl &= ~UHCI_PORT_LSDA;
1.1.1.5 ! root      423: 
        !           424:         uhci_resume(s);
        !           425: 
1.1       root      426:         port->port.dev = dev;
                    427:         /* send the attach message */
1.1.1.4   root      428:         usb_send_msg(dev, USB_MSG_ATTACH);
1.1       root      429:     } else {
                    430:         /* set connect status */
1.1.1.3   root      431:         if (port->ctrl & UHCI_PORT_CCS) {
                    432:             port->ctrl &= ~UHCI_PORT_CCS;
                    433:             port->ctrl |= UHCI_PORT_CSC;
1.1       root      434:         }
                    435:         /* disable port */
                    436:         if (port->ctrl & UHCI_PORT_EN) {
                    437:             port->ctrl &= ~UHCI_PORT_EN;
                    438:             port->ctrl |= UHCI_PORT_ENC;
                    439:         }
1.1.1.5 ! root      440: 
        !           441:         uhci_resume(s);
        !           442: 
1.1       root      443:         dev = port->port.dev;
                    444:         if (dev) {
                    445:             /* send the detach message */
1.1.1.4   root      446:             usb_send_msg(dev, USB_MSG_DETACH);
1.1       root      447:         }
                    448:         port->port.dev = NULL;
                    449:     }
                    450: }
                    451: 
1.1.1.4   root      452: static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
1.1       root      453: {
                    454:     UHCIPort *port;
                    455:     USBDevice *dev;
                    456:     int i, ret;
                    457: 
                    458: #ifdef DEBUG_PACKET
                    459:     {
                    460:         const char *pidstr;
1.1.1.4   root      461:         switch(p->pid) {
1.1       root      462:         case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
                    463:         case USB_TOKEN_IN: pidstr = "IN"; break;
                    464:         case USB_TOKEN_OUT: pidstr = "OUT"; break;
                    465:         default: pidstr = "?"; break;
                    466:         }
                    467:         printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
1.1.1.4   root      468:                s->frnum, pidstr, p->devaddr, p->devep, p->len);
                    469:         if (p->pid != USB_TOKEN_IN) {
1.1       root      470:             printf("     data_out=");
1.1.1.4   root      471:             for(i = 0; i < p->len; i++) {
                    472:                 printf(" %02x", p->data[i]);
1.1       root      473:             }
                    474:             printf("\n");
                    475:         }
                    476:     }
                    477: #endif
                    478:     for(i = 0; i < NB_PORTS; i++) {
                    479:         port = &s->ports[i];
                    480:         dev = port->port.dev;
                    481:         if (dev && (port->ctrl & UHCI_PORT_EN)) {
1.1.1.4   root      482:             ret = dev->handle_packet(dev, p);
1.1       root      483:             if (ret != USB_RET_NODEV) {
                    484: #ifdef DEBUG_PACKET
1.1.1.4   root      485:                 if (ret == USB_RET_ASYNC) {
                    486:                     printf("usb-uhci: Async packet\n");
                    487:                 } else {
1.1       root      488:                     printf("     ret=%d ", ret);
1.1.1.4   root      489:                     if (p->pid == USB_TOKEN_IN && ret > 0) {
1.1       root      490:                         printf("data_in=");
                    491:                         for(i = 0; i < ret; i++) {
1.1.1.4   root      492:                             printf(" %02x", p->data[i]);
1.1       root      493:                         }
                    494:                     }
                    495:                     printf("\n");
                    496:                 }
                    497: #endif
                    498:                 return ret;
                    499:             }
                    500:         }
                    501:     }
                    502:     return USB_RET_NODEV;
                    503: }
                    504: 
1.1.1.4   root      505: static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
                    506: 
1.1       root      507: /* return -1 if fatal error (frame must be stopped)
                    508:           0 if TD successful
                    509:           1 if TD unsuccessful or inactive
                    510: */
1.1.1.5 ! root      511: static int uhci_handle_td(UHCIState *s, UHCI_TD *td, uint32_t *int_mask,
        !           512:                           int completion)
1.1       root      513: {
                    514:     uint8_t pid;
1.1.1.5 ! root      515:     int len = 0, max_len, err, ret = 0;
1.1       root      516: 
1.1.1.4   root      517:     /* ??? This is wrong for async completion.  */
1.1       root      518:     if (td->ctrl & TD_CTRL_IOC) {
                    519:         *int_mask |= 0x01;
                    520:     }
1.1.1.5 ! root      521: 
1.1       root      522:     if (!(td->ctrl & TD_CTRL_ACTIVE))
                    523:         return 1;
                    524: 
                    525:     /* TD is active */
                    526:     max_len = ((td->token >> 21) + 1) & 0x7ff;
                    527:     pid = td->token & 0xff;
1.1.1.5 ! root      528: 
        !           529:     if (completion && (s->async_qh || s->async_frame_addr)) {
1.1.1.4   root      530:         ret = s->usb_packet.len;
1.1       root      531:         if (ret >= 0) {
                    532:             len = ret;
                    533:             if (len > max_len) {
                    534:                 len = max_len;
                    535:                 ret = USB_RET_BABBLE;
                    536:             }
                    537:             if (len > 0) {
                    538:                 /* write the data back */
1.1.1.4   root      539:                 cpu_physical_memory_write(td->buffer, s->usb_buf, len);
1.1       root      540:             }
                    541:         } else {
                    542:             len = 0;
                    543:         }
1.1.1.4   root      544:         s->async_qh = 0;
1.1.1.5 ! root      545:         s->async_frame_addr = 0;
        !           546:     } else if (!completion) {
1.1.1.4   root      547:         s->usb_packet.pid = pid;
                    548:         s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
                    549:         s->usb_packet.devep = (td->token >> 15) & 0xf;
                    550:         s->usb_packet.data = s->usb_buf;
                    551:         s->usb_packet.len = max_len;
                    552:         s->usb_packet.complete_cb = uhci_async_complete_packet;
                    553:         s->usb_packet.complete_opaque = s;
                    554:         switch(pid) {
                    555:         case USB_TOKEN_OUT:
                    556:         case USB_TOKEN_SETUP:
                    557:             cpu_physical_memory_read(td->buffer, s->usb_buf, max_len);
                    558:             ret = uhci_broadcast_packet(s, &s->usb_packet);
                    559:             len = max_len;
                    560:             break;
                    561:         case USB_TOKEN_IN:
                    562:             ret = uhci_broadcast_packet(s, &s->usb_packet);
                    563:             if (ret >= 0) {
                    564:                 len = ret;
                    565:                 if (len > max_len) {
                    566:                     len = max_len;
                    567:                     ret = USB_RET_BABBLE;
                    568:                 }
                    569:                 if (len > 0) {
                    570:                     /* write the data back */
                    571:                     cpu_physical_memory_write(td->buffer, s->usb_buf, len);
                    572:                 }
                    573:             } else {
                    574:                 len = 0;
                    575:             }
                    576:             break;
                    577:         default:
                    578:             /* invalid pid : frame interrupted */
                    579:             s->status |= UHCI_STS_HCPERR;
                    580:             uhci_update_irq(s);
                    581:             return -1;
                    582:         }
                    583:     }
1.1.1.5 ! root      584: 
1.1.1.4   root      585:     if (ret == USB_RET_ASYNC) {
                    586:         return 2;
1.1       root      587:     }
                    588:     if (td->ctrl & TD_CTRL_IOS)
                    589:         td->ctrl &= ~TD_CTRL_ACTIVE;
                    590:     if (ret >= 0) {
                    591:         td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
1.1.1.5 ! root      592:         /* The NAK bit may have been set by a previous frame, so clear it
        !           593:            here.  The docs are somewhat unclear, but win2k relies on this
        !           594:            behavior.  */
        !           595:         td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
        !           596:         if (pid == USB_TOKEN_IN &&
1.1       root      597:             (td->ctrl & TD_CTRL_SPD) &&
                    598:             len < max_len) {
                    599:             *int_mask |= 0x02;
                    600:             /* short packet: do not update QH */
                    601:             return 1;
                    602:         } else {
                    603:             /* success */
                    604:             return 0;
                    605:         }
                    606:     } else {
                    607:         switch(ret) {
                    608:         default:
                    609:         case USB_RET_NODEV:
                    610:         do_timeout:
                    611:             td->ctrl |= TD_CTRL_TIMEOUT;
                    612:             err = (td->ctrl >> TD_CTRL_ERROR_SHIFT) & 3;
                    613:             if (err != 0) {
                    614:                 err--;
                    615:                 if (err == 0) {
                    616:                     td->ctrl &= ~TD_CTRL_ACTIVE;
                    617:                     s->status |= UHCI_STS_USBERR;
                    618:                     uhci_update_irq(s);
                    619:                 }
                    620:             }
1.1.1.5 ! root      621:             td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |
1.1       root      622:                 (err << TD_CTRL_ERROR_SHIFT);
                    623:             return 1;
                    624:         case USB_RET_NAK:
                    625:             td->ctrl |= TD_CTRL_NAK;
                    626:             if (pid == USB_TOKEN_SETUP)
                    627:                 goto do_timeout;
                    628:             return 1;
                    629:         case USB_RET_STALL:
                    630:             td->ctrl |= TD_CTRL_STALL;
                    631:             td->ctrl &= ~TD_CTRL_ACTIVE;
                    632:             return 1;
                    633:         case USB_RET_BABBLE:
                    634:             td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
                    635:             td->ctrl &= ~TD_CTRL_ACTIVE;
                    636:             /* frame interrupted */
                    637:             return -1;
                    638:         }
                    639:     }
                    640: }
                    641: 
1.1.1.4   root      642: static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
                    643: {
                    644:     UHCIState *s = opaque;
                    645:     UHCI_QH qh;
                    646:     UHCI_TD td;
                    647:     uint32_t link;
                    648:     uint32_t old_td_ctrl;
                    649:     uint32_t val;
1.1.1.5 ! root      650:     uint32_t frame_addr;
1.1.1.4   root      651:     int ret;
                    652: 
1.1.1.5 ! root      653:     /* Handle async isochronous packet completion */
        !           654:     frame_addr = s->async_frame_addr;
        !           655:     if (frame_addr) {
        !           656:         cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
        !           657:         le32_to_cpus(&link);
        !           658: 
        !           659:         cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
        !           660:         le32_to_cpus(&td.link);
        !           661:         le32_to_cpus(&td.ctrl);
        !           662:         le32_to_cpus(&td.token);
        !           663:         le32_to_cpus(&td.buffer);
        !           664:         old_td_ctrl = td.ctrl;
        !           665:         ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
        !           666: 
        !           667:         /* update the status bits of the TD */
        !           668:         if (old_td_ctrl != td.ctrl) {
        !           669:             val = cpu_to_le32(td.ctrl);
        !           670:             cpu_physical_memory_write((link & ~0xf) + 4,
        !           671:                                       (const uint8_t *)&val,
        !           672:                                       sizeof(val));
        !           673:         }
        !           674:         if (ret == 2) {
        !           675:             s->async_frame_addr = frame_addr;
        !           676:         } else if (ret == 0) {
        !           677:             /* update qh element link */
        !           678:             val = cpu_to_le32(td.link);
        !           679:             cpu_physical_memory_write(frame_addr,
        !           680:                                       (const uint8_t *)&val,
        !           681:                                       sizeof(val));
        !           682:         }
        !           683:         return;
        !           684:     }
        !           685: 
1.1.1.4   root      686:     link = s->async_qh;
                    687:     if (!link) {
                    688:         /* This should never happen. It means a TD somehow got removed
                    689:            without cancelling the associated async IO request.  */
                    690:         return;
                    691:     }
                    692:     cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
                    693:     le32_to_cpus(&qh.link);
                    694:     le32_to_cpus(&qh.el_link);
                    695:     /* Re-process the queue containing the async packet.  */
                    696:     while (1) {
1.1.1.5 ! root      697:         cpu_physical_memory_read(qh.el_link & ~0xf,
1.1.1.4   root      698:                                  (uint8_t *)&td, sizeof(td));
                    699:         le32_to_cpus(&td.link);
                    700:         le32_to_cpus(&td.ctrl);
                    701:         le32_to_cpus(&td.token);
                    702:         le32_to_cpus(&td.buffer);
                    703:         old_td_ctrl = td.ctrl;
1.1.1.5 ! root      704:         ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
        !           705: 
1.1.1.4   root      706:         /* update the status bits of the TD */
                    707:         if (old_td_ctrl != td.ctrl) {
                    708:             val = cpu_to_le32(td.ctrl);
1.1.1.5 ! root      709:             cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
        !           710:                                       (const uint8_t *)&val,
1.1.1.4   root      711:                                       sizeof(val));
                    712:         }
                    713:         if (ret < 0)
                    714:             break; /* interrupted frame */
                    715:         if (ret == 2) {
                    716:             s->async_qh = link;
                    717:             break;
                    718:         } else if (ret == 0) {
                    719:             /* update qh element link */
                    720:             qh.el_link = td.link;
                    721:             val = cpu_to_le32(qh.el_link);
1.1.1.5 ! root      722:             cpu_physical_memory_write((link & ~0xf) + 4,
        !           723:                                       (const uint8_t *)&val,
1.1.1.4   root      724:                                       sizeof(val));
                    725:             if (!(qh.el_link & 4))
                    726:                 break;
                    727:         }
                    728:         break;
                    729:     }
                    730: }
                    731: 
1.1       root      732: static void uhci_frame_timer(void *opaque)
                    733: {
                    734:     UHCIState *s = opaque;
                    735:     int64_t expire_time;
1.1.1.5 ! root      736:     uint32_t frame_addr, link, old_td_ctrl, val, int_mask;
        !           737:     int cnt, ret;
1.1       root      738:     UHCI_TD td;
                    739:     UHCI_QH qh;
1.1.1.4   root      740:     uint32_t old_async_qh;
1.1       root      741: 
                    742:     if (!(s->cmd & UHCI_CMD_RS)) {
                    743:         qemu_del_timer(s->frame_timer);
1.1.1.2   root      744:         /* set hchalted bit in status - UHCI11D 2.1.2 */
                    745:         s->status |= UHCI_STS_HCHALTED;
1.1       root      746:         return;
                    747:     }
1.1.1.4   root      748:     /* Complete the previous frame.  */
                    749:     s->frnum = (s->frnum + 1) & 0x7ff;
                    750:     if (s->pending_int_mask) {
                    751:         s->status2 |= s->pending_int_mask;
                    752:         s->status |= UHCI_STS_USBINT;
                    753:         uhci_update_irq(s);
                    754:     }
                    755:     old_async_qh = s->async_qh;
1.1       root      756:     frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
                    757:     cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
                    758:     le32_to_cpus(&link);
                    759:     int_mask = 0;
                    760:     cnt = FRAME_MAX_LOOPS;
                    761:     while ((link & 1) == 0) {
                    762:         if (--cnt == 0)
                    763:             break;
                    764:         /* valid frame */
                    765:         if (link & 2) {
                    766:             /* QH */
1.1.1.4   root      767:             if (link == s->async_qh) {
                    768:                 /* We've found a previously issues packet.
                    769:                    Nothing else to do.  */
                    770:                 old_async_qh = 0;
                    771:                 break;
                    772:             }
1.1       root      773:             cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
                    774:             le32_to_cpus(&qh.link);
                    775:             le32_to_cpus(&qh.el_link);
                    776:         depth_first:
                    777:             if (qh.el_link & 1) {
                    778:                 /* no element : go to next entry */
                    779:                 link = qh.link;
                    780:             } else if (qh.el_link & 2) {
                    781:                 /* QH */
                    782:                 link = qh.el_link;
1.1.1.4   root      783:             } else if (s->async_qh) {
                    784:                 /* We can only cope with one pending packet.  Keep looking
                    785:                    for the previously issued packet.  */
                    786:                 link = qh.link;
1.1       root      787:             } else {
                    788:                 /* TD */
                    789:                 if (--cnt == 0)
                    790:                     break;
1.1.1.5 ! root      791:                 cpu_physical_memory_read(qh.el_link & ~0xf,
1.1       root      792:                                          (uint8_t *)&td, sizeof(td));
                    793:                 le32_to_cpus(&td.link);
                    794:                 le32_to_cpus(&td.ctrl);
                    795:                 le32_to_cpus(&td.token);
                    796:                 le32_to_cpus(&td.buffer);
                    797:                 old_td_ctrl = td.ctrl;
1.1.1.5 ! root      798:                 ret = uhci_handle_td(s, &td, &int_mask, 0);
        !           799: 
1.1       root      800:                 /* update the status bits of the TD */
                    801:                 if (old_td_ctrl != td.ctrl) {
                    802:                     val = cpu_to_le32(td.ctrl);
1.1.1.5 ! root      803:                     cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
        !           804:                                               (const uint8_t *)&val,
1.1       root      805:                                               sizeof(val));
                    806:                 }
                    807:                 if (ret < 0)
                    808:                     break; /* interrupted frame */
1.1.1.4   root      809:                 if (ret == 2) {
                    810:                     s->async_qh = link;
                    811:                 } else if (ret == 0) {
1.1       root      812:                     /* update qh element link */
                    813:                     qh.el_link = td.link;
                    814:                     val = cpu_to_le32(qh.el_link);
1.1.1.5 ! root      815:                     cpu_physical_memory_write((link & ~0xf) + 4,
        !           816:                                               (const uint8_t *)&val,
1.1       root      817:                                               sizeof(val));
                    818:                     if (qh.el_link & 4) {
                    819:                         /* depth first */
                    820:                         goto depth_first;
                    821:                     }
                    822:                 }
                    823:                 /* go to next entry */
                    824:                 link = qh.link;
                    825:             }
                    826:         } else {
                    827:             /* TD */
                    828:             cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
                    829:             le32_to_cpus(&td.link);
                    830:             le32_to_cpus(&td.ctrl);
                    831:             le32_to_cpus(&td.token);
                    832:             le32_to_cpus(&td.buffer);
1.1.1.5 ! root      833: 
        !           834:             /* Handle isochonous transfer.  */
        !           835:             /* FIXME: might be more than one isoc in frame */
        !           836:             old_td_ctrl = td.ctrl;
        !           837:             ret = uhci_handle_td(s, &td, &int_mask, 0);
        !           838: 
        !           839:             /* update the status bits of the TD */
        !           840:             if (old_td_ctrl != td.ctrl) {
        !           841:                 val = cpu_to_le32(td.ctrl);
        !           842:                 cpu_physical_memory_write((link & ~0xf) + 4,
        !           843:                                           (const uint8_t *)&val,
        !           844:                                           sizeof(val));
        !           845:             }
        !           846:             if (ret < 0)
        !           847:                 break; /* interrupted frame */
        !           848:             if (ret == 2) {
        !           849:                 s->async_frame_addr = frame_addr;
1.1       root      850:             }
                    851:             link = td.link;
                    852:         }
                    853:     }
1.1.1.4   root      854:     s->pending_int_mask = int_mask;
                    855:     if (old_async_qh) {
                    856:         /* A previously started transfer has disappeared from the transfer
                    857:            list.  There's nothing useful we can do with it now, so just
                    858:            discard the packet and hope it wasn't too important.  */
                    859: #ifdef DEBUG
                    860:         printf("Discarding USB packet\n");
                    861: #endif
                    862:         usb_cancel_packet(&s->usb_packet);
                    863:         s->async_qh = 0;
1.1       root      864:     }
1.1.1.5 ! root      865: 
1.1       root      866:     /* prepare the timer for the next frame */
1.1.1.5 ! root      867:     expire_time = qemu_get_clock(vm_clock) +
1.1       root      868:         (ticks_per_sec / FRAME_TIMER_FREQ);
                    869:     qemu_mod_timer(s->frame_timer, expire_time);
                    870: }
                    871: 
1.1.1.5 ! root      872: static void uhci_map(PCIDevice *pci_dev, int region_num,
1.1       root      873:                     uint32_t addr, uint32_t size, int type)
                    874: {
                    875:     UHCIState *s = (UHCIState *)pci_dev;
                    876: 
                    877:     register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
                    878:     register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
                    879:     register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
                    880:     register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
                    881:     register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
                    882:     register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
                    883: }
                    884: 
1.1.1.5 ! root      885: void usb_uhci_piix3_init(PCIBus *bus, int devfn)
1.1       root      886: {
                    887:     UHCIState *s;
                    888:     uint8_t *pci_conf;
                    889:     int i;
                    890: 
                    891:     s = (UHCIState *)pci_register_device(bus,
                    892:                                         "USB-UHCI", sizeof(UHCIState),
1.1.1.3   root      893:                                         devfn, NULL, NULL);
1.1       root      894:     pci_conf = s->dev.config;
                    895:     pci_conf[0x00] = 0x86;
                    896:     pci_conf[0x01] = 0x80;
                    897:     pci_conf[0x02] = 0x20;
                    898:     pci_conf[0x03] = 0x70;
                    899:     pci_conf[0x08] = 0x01; // revision number
                    900:     pci_conf[0x09] = 0x00;
                    901:     pci_conf[0x0a] = 0x03;
                    902:     pci_conf[0x0b] = 0x0c;
                    903:     pci_conf[0x0e] = 0x00; // header_type
                    904:     pci_conf[0x3d] = 4; // interrupt pin 3
1.1.1.2   root      905:     pci_conf[0x60] = 0x10; // release number
1.1.1.5 ! root      906: 
        !           907:     for(i = 0; i < NB_PORTS; i++) {
        !           908:         qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
        !           909:     }
        !           910:     s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
        !           911: 
        !           912:     uhci_reset(s);
        !           913: 
        !           914:     /* Use region 4 for consistency with real hardware.  BSD guests seem
        !           915:        to rely on this.  */
        !           916:     pci_register_io_region(&s->dev, 4, 0x20,
        !           917:                            PCI_ADDRESS_SPACE_IO, uhci_map);
        !           918: }
        !           919: 
        !           920: void usb_uhci_piix4_init(PCIBus *bus, int devfn)
        !           921: {
        !           922:     UHCIState *s;
        !           923:     uint8_t *pci_conf;
        !           924:     int i;
        !           925: 
        !           926:     s = (UHCIState *)pci_register_device(bus,
        !           927:                                         "USB-UHCI", sizeof(UHCIState),
        !           928:                                         devfn, NULL, NULL);
        !           929:     pci_conf = s->dev.config;
        !           930:     pci_conf[0x00] = 0x86;
        !           931:     pci_conf[0x01] = 0x80;
        !           932:     pci_conf[0x02] = 0x12;
        !           933:     pci_conf[0x03] = 0x71;
        !           934:     pci_conf[0x08] = 0x01; // revision number
        !           935:     pci_conf[0x09] = 0x00;
        !           936:     pci_conf[0x0a] = 0x03;
        !           937:     pci_conf[0x0b] = 0x0c;
        !           938:     pci_conf[0x0e] = 0x00; // header_type
        !           939:     pci_conf[0x3d] = 4; // interrupt pin 3
        !           940:     pci_conf[0x60] = 0x10; // release number
        !           941: 
1.1       root      942:     for(i = 0; i < NB_PORTS; i++) {
1.1.1.3   root      943:         qemu_register_usb_port(&s->ports[i].port, s, i, uhci_attach);
1.1       root      944:     }
                    945:     s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
                    946: 
                    947:     uhci_reset(s);
                    948: 
1.1.1.2   root      949:     /* Use region 4 for consistency with real hardware.  BSD guests seem
                    950:        to rely on this.  */
1.1.1.5 ! root      951:     pci_register_io_region(&s->dev, 4, 0x20,
1.1       root      952:                            PCI_ADDRESS_SPACE_IO, uhci_map);
                    953: }

unix.superglobalmegacorp.com

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