Annotation of qemu/hw/usb.c, revision 1.1.1.9

1.1       root        1: /*
                      2:  * QEMU USB emulation
                      3:  *
                      4:  * Copyright (c) 2005 Fabrice Bellard
1.1.1.4   root        5:  *
1.1.1.5   root        6:  * 2008 Generic packet handler rewrite by Max Krasnyansky
                      7:  *
1.1       root        8:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      9:  * of this software and associated documentation files (the "Software"), to deal
                     10:  * in the Software without restriction, including without limitation the rights
                     11:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     12:  * copies of the Software, and to permit persons to whom the Software is
                     13:  * furnished to do so, subject to the following conditions:
                     14:  *
                     15:  * The above copyright notice and this permission notice shall be included in
                     16:  * all copies or substantial portions of the Software.
                     17:  *
                     18:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     19:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     20:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     21:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     22:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     23:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     24:  * THE SOFTWARE.
                     25:  */
1.1.1.4   root       26: #include "qemu-common.h"
                     27: #include "usb.h"
1.1.1.9 ! root       28: #include "iov.h"
1.1       root       29: 
1.1.1.9 ! root       30: void usb_attach(USBPort *port)
1.1       root       31: {
1.1.1.9 ! root       32:     USBDevice *dev = port->dev;
        !            33: 
        !            34:     assert(dev != NULL);
        !            35:     assert(dev->attached);
        !            36:     assert(dev->state == USB_STATE_NOTATTACHED);
        !            37:     port->ops->attach(port);
        !            38:     usb_send_msg(dev, USB_MSG_ATTACH);
        !            39: }
        !            40: 
        !            41: void usb_detach(USBPort *port)
        !            42: {
        !            43:     USBDevice *dev = port->dev;
        !            44: 
        !            45:     assert(dev != NULL);
        !            46:     assert(dev->state != USB_STATE_NOTATTACHED);
        !            47:     port->ops->detach(port);
        !            48:     usb_send_msg(dev, USB_MSG_DETACH);
        !            49: }
        !            50: 
        !            51: void usb_reset(USBPort *port)
        !            52: {
        !            53:     USBDevice *dev = port->dev;
        !            54: 
        !            55:     assert(dev != NULL);
        !            56:     usb_detach(port);
        !            57:     usb_attach(port);
        !            58:     usb_send_msg(dev, USB_MSG_RESET);
1.1.1.7   root       59: }
                     60: 
                     61: void usb_wakeup(USBDevice *dev)
                     62: {
                     63:     if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
1.1.1.8   root       64:         dev->port->ops->wakeup(dev->port);
1.1.1.7   root       65:     }
1.1       root       66: }
                     67: 
                     68: /**********************/
1.1.1.5   root       69: 
1.1       root       70: /* generic USB device helpers (you are not forced to use them when
                     71:    writing your USB device driver, but they help handling the
1.1.1.4   root       72:    protocol)
1.1       root       73: */
                     74: 
1.1.1.8   root       75: #define SETUP_STATE_IDLE  0
                     76: #define SETUP_STATE_SETUP 1
                     77: #define SETUP_STATE_DATA  2
                     78: #define SETUP_STATE_ACK   3
1.1       root       79: 
1.1.1.5   root       80: static int do_token_setup(USBDevice *s, USBPacket *p)
                     81: {
                     82:     int request, value, index;
                     83:     int ret = 0;
                     84: 
1.1.1.9 ! root       85:     if (p->iov.size != 8) {
1.1.1.5   root       86:         return USB_RET_STALL;
1.1.1.9 ! root       87:     }
        !            88: 
        !            89:     usb_packet_copy(p, s->setup_buf, p->iov.size);
1.1.1.5   root       90:     s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
                     91:     s->setup_index = 0;
                     92: 
                     93:     request = (s->setup_buf[0] << 8) | s->setup_buf[1];
                     94:     value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
                     95:     index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
1.1.1.8   root       96: 
1.1.1.5   root       97:     if (s->setup_buf[0] & USB_DIR_IN) {
1.1.1.8   root       98:         ret = s->info->handle_control(s, p, request, value, index,
1.1.1.6   root       99:                                       s->setup_len, s->data_buf);
1.1.1.8   root      100:         if (ret == USB_RET_ASYNC) {
                    101:              s->setup_state = SETUP_STATE_SETUP;
                    102:              return USB_RET_ASYNC;
                    103:         }
1.1.1.5   root      104:         if (ret < 0)
                    105:             return ret;
                    106: 
                    107:         if (ret < s->setup_len)
                    108:             s->setup_len = ret;
                    109:         s->setup_state = SETUP_STATE_DATA;
                    110:     } else {
1.1.1.8   root      111:         if (s->setup_len > sizeof(s->data_buf)) {
                    112:             fprintf(stderr,
                    113:                 "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
                    114:                 s->setup_len, sizeof(s->data_buf));
                    115:             return USB_RET_STALL;
                    116:         }
1.1.1.5   root      117:         if (s->setup_len == 0)
                    118:             s->setup_state = SETUP_STATE_ACK;
                    119:         else
                    120:             s->setup_state = SETUP_STATE_DATA;
                    121:     }
                    122: 
                    123:     return ret;
                    124: }
                    125: 
                    126: static int do_token_in(USBDevice *s, USBPacket *p)
                    127: {
                    128:     int request, value, index;
                    129:     int ret = 0;
                    130: 
                    131:     if (p->devep != 0)
1.1.1.6   root      132:         return s->info->handle_data(s, p);
1.1.1.5   root      133: 
                    134:     request = (s->setup_buf[0] << 8) | s->setup_buf[1];
                    135:     value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
                    136:     index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
                    137:  
                    138:     switch(s->setup_state) {
                    139:     case SETUP_STATE_ACK:
                    140:         if (!(s->setup_buf[0] & USB_DIR_IN)) {
1.1.1.8   root      141:             ret = s->info->handle_control(s, p, request, value, index,
1.1.1.6   root      142:                                           s->setup_len, s->data_buf);
1.1.1.8   root      143:             if (ret == USB_RET_ASYNC) {
                    144:                 return USB_RET_ASYNC;
                    145:             }
                    146:             s->setup_state = SETUP_STATE_IDLE;
1.1.1.5   root      147:             if (ret > 0)
                    148:                 return 0;
                    149:             return ret;
                    150:         }
                    151: 
                    152:         /* return 0 byte */
                    153:         return 0;
                    154: 
                    155:     case SETUP_STATE_DATA:
                    156:         if (s->setup_buf[0] & USB_DIR_IN) {
                    157:             int len = s->setup_len - s->setup_index;
1.1.1.9 ! root      158:             if (len > p->iov.size) {
        !           159:                 len = p->iov.size;
        !           160:             }
        !           161:             usb_packet_copy(p, s->data_buf + s->setup_index, len);
1.1.1.5   root      162:             s->setup_index += len;
                    163:             if (s->setup_index >= s->setup_len)
                    164:                 s->setup_state = SETUP_STATE_ACK;
                    165:             return len;
                    166:         }
                    167: 
                    168:         s->setup_state = SETUP_STATE_IDLE;
                    169:         return USB_RET_STALL;
                    170: 
                    171:     default:
                    172:         return USB_RET_STALL;
                    173:     }
                    174: }
                    175: 
                    176: static int do_token_out(USBDevice *s, USBPacket *p)
1.1       root      177: {
1.1.1.5   root      178:     if (p->devep != 0)
1.1.1.6   root      179:         return s->info->handle_data(s, p);
1.1.1.5   root      180: 
                    181:     switch(s->setup_state) {
                    182:     case SETUP_STATE_ACK:
                    183:         if (s->setup_buf[0] & USB_DIR_IN) {
                    184:             s->setup_state = SETUP_STATE_IDLE;
                    185:             /* transfer OK */
                    186:         } else {
                    187:             /* ignore additional output */
                    188:         }
                    189:         return 0;
1.1       root      190: 
1.1.1.5   root      191:     case SETUP_STATE_DATA:
                    192:         if (!(s->setup_buf[0] & USB_DIR_IN)) {
                    193:             int len = s->setup_len - s->setup_index;
1.1.1.9 ! root      194:             if (len > p->iov.size) {
        !           195:                 len = p->iov.size;
        !           196:             }
        !           197:             usb_packet_copy(p, s->data_buf + s->setup_index, len);
1.1.1.5   root      198:             s->setup_index += len;
                    199:             if (s->setup_index >= s->setup_len)
                    200:                 s->setup_state = SETUP_STATE_ACK;
                    201:             return len;
                    202:         }
                    203: 
                    204:         s->setup_state = SETUP_STATE_IDLE;
                    205:         return USB_RET_STALL;
                    206: 
                    207:     default:
                    208:         return USB_RET_STALL;
                    209:     }
                    210: }
                    211: 
                    212: /*
                    213:  * Generic packet handler.
                    214:  * Called by the HC (host controller).
                    215:  *
                    216:  * Returns length of the transaction or one of the USB_RET_XXX codes.
                    217:  */
                    218: int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
                    219: {
1.1.1.3   root      220:     switch(p->pid) {
1.1       root      221:     case USB_MSG_ATTACH:
                    222:         s->state = USB_STATE_ATTACHED;
1.1.1.7   root      223:         if (s->info->handle_attach) {
                    224:             s->info->handle_attach(s);
                    225:         }
1.1.1.5   root      226:         return 0;
                    227: 
1.1       root      228:     case USB_MSG_DETACH:
                    229:         s->state = USB_STATE_NOTATTACHED;
1.1.1.5   root      230:         return 0;
                    231: 
1.1       root      232:     case USB_MSG_RESET:
                    233:         s->remote_wakeup = 0;
                    234:         s->addr = 0;
                    235:         s->state = USB_STATE_DEFAULT;
1.1.1.7   root      236:         if (s->info->handle_reset) {
                    237:             s->info->handle_reset(s);
                    238:         }
1.1.1.5   root      239:         return 0;
                    240:     }
                    241: 
                    242:     /* Rest of the PIDs must match our address */
                    243:     if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
                    244:         return USB_RET_NODEV;
                    245: 
                    246:     switch (p->pid) {
1.1       root      247:     case USB_TOKEN_SETUP:
1.1.1.5   root      248:         return do_token_setup(s, p);
                    249: 
1.1       root      250:     case USB_TOKEN_IN:
1.1.1.5   root      251:         return do_token_in(s, p);
                    252: 
1.1       root      253:     case USB_TOKEN_OUT:
1.1.1.5   root      254:         return do_token_out(s, p);
                    255:  
1.1       root      256:     default:
1.1.1.5   root      257:         return USB_RET_STALL;
1.1       root      258:     }
                    259: }
                    260: 
1.1.1.8   root      261: /* ctrl complete function for devices which use usb_generic_handle_packet and
                    262:    may return USB_RET_ASYNC from their handle_control callback. Device code
                    263:    which does this *must* call this function instead of the normal
                    264:    usb_packet_complete to complete their async control packets. */
                    265: void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p)
                    266: {
1.1.1.9 ! root      267:     if (p->result < 0) {
1.1.1.8   root      268:         s->setup_state = SETUP_STATE_IDLE;
                    269:     }
                    270: 
                    271:     switch (s->setup_state) {
                    272:     case SETUP_STATE_SETUP:
1.1.1.9 ! root      273:         if (p->result < s->setup_len) {
        !           274:             s->setup_len = p->result;
1.1.1.8   root      275:         }
                    276:         s->setup_state = SETUP_STATE_DATA;
1.1.1.9 ! root      277:         p->result = 8;
1.1.1.8   root      278:         break;
                    279: 
                    280:     case SETUP_STATE_ACK:
                    281:         s->setup_state = SETUP_STATE_IDLE;
1.1.1.9 ! root      282:         p->result = 0;
1.1.1.8   root      283:         break;
                    284: 
                    285:     default:
                    286:         break;
                    287:     }
                    288:     usb_packet_complete(s, p);
                    289: }
                    290: 
1.1       root      291: /* XXX: fix overflow */
                    292: int set_usb_string(uint8_t *buf, const char *str)
                    293: {
                    294:     int len, i;
                    295:     uint8_t *q;
                    296: 
                    297:     q = buf;
                    298:     len = strlen(str);
1.1.1.2   root      299:     *q++ = 2 * len + 2;
1.1       root      300:     *q++ = 3;
                    301:     for(i = 0; i < len; i++) {
                    302:         *q++ = str[i];
                    303:         *q++ = 0;
                    304:     }
                    305:     return q - buf;
                    306: }
1.1.1.3   root      307: 
                    308: /* Send an internal message to a USB device.  */
                    309: void usb_send_msg(USBDevice *dev, int msg)
                    310: {
                    311:     USBPacket p;
1.1.1.8   root      312:     int ret;
                    313: 
1.1.1.3   root      314:     memset(&p, 0, sizeof(p));
                    315:     p.pid = msg;
1.1.1.8   root      316:     ret = usb_handle_packet(dev, &p);
1.1.1.5   root      317:     /* This _must_ be synchronous */
1.1.1.8   root      318:     assert(ret != USB_RET_ASYNC);
                    319: }
                    320: 
                    321: /* Hand over a packet to a device for processing.  Return value
                    322:    USB_RET_ASYNC indicates the processing isn't finished yet, the
                    323:    driver will call usb_packet_complete() when done processing it. */
                    324: int usb_handle_packet(USBDevice *dev, USBPacket *p)
                    325: {
                    326:     int ret;
                    327: 
                    328:     assert(p->owner == NULL);
                    329:     ret = dev->info->handle_packet(dev, p);
                    330:     if (ret == USB_RET_ASYNC) {
                    331:         if (p->owner == NULL) {
                    332:             p->owner = dev;
                    333:         } else {
                    334:             /* We'll end up here when usb_handle_packet is called
                    335:              * recursively due to a hub being in the chain.  Nothing
                    336:              * to do.  Leave p->owner pointing to the device, not the
                    337:              * hub. */;
                    338:         }
                    339:     }
                    340:     return ret;
                    341: }
                    342: 
                    343: /* Notify the controller that an async packet is complete.  This should only
                    344:    be called for packets previously deferred by returning USB_RET_ASYNC from
                    345:    handle_packet. */
                    346: void usb_packet_complete(USBDevice *dev, USBPacket *p)
                    347: {
                    348:     /* Note: p->owner != dev is possible in case dev is a hub */
                    349:     assert(p->owner != NULL);
                    350:     p->owner = NULL;
1.1.1.9 ! root      351:     dev->port->ops->complete(dev->port, p);
1.1.1.8   root      352: }
                    353: 
                    354: /* Cancel an active packet.  The packed must have been deferred by
                    355:    returning USB_RET_ASYNC from handle_packet, and not yet
                    356:    completed.  */
                    357: void usb_cancel_packet(USBPacket * p)
                    358: {
                    359:     assert(p->owner != NULL);
                    360:     p->owner->info->cancel_packet(p->owner, p);
                    361:     p->owner = NULL;
1.1.1.5   root      362: }
1.1.1.9 ! root      363: 
        !           364: 
        !           365: void usb_packet_init(USBPacket *p)
        !           366: {
        !           367:     qemu_iovec_init(&p->iov, 1);
        !           368: }
        !           369: 
        !           370: void usb_packet_setup(USBPacket *p, int pid, uint8_t addr, uint8_t ep)
        !           371: {
        !           372:     p->pid = pid;
        !           373:     p->devaddr = addr;
        !           374:     p->devep = ep;
        !           375:     p->result = 0;
        !           376:     qemu_iovec_reset(&p->iov);
        !           377: }
        !           378: 
        !           379: void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len)
        !           380: {
        !           381:     qemu_iovec_add(&p->iov, ptr, len);
        !           382: }
        !           383: 
        !           384: void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes)
        !           385: {
        !           386:     assert(p->result >= 0);
        !           387:     assert(p->result + bytes <= p->iov.size);
        !           388:     switch (p->pid) {
        !           389:     case USB_TOKEN_SETUP:
        !           390:     case USB_TOKEN_OUT:
        !           391:         iov_to_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes);
        !           392:         break;
        !           393:     case USB_TOKEN_IN:
        !           394:         iov_from_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes);
        !           395:         break;
        !           396:     default:
        !           397:         fprintf(stderr, "%s: invalid pid: %x\n", __func__, p->pid);
        !           398:         abort();
        !           399:     }
        !           400:     p->result += bytes;
        !           401: }
        !           402: 
        !           403: void usb_packet_skip(USBPacket *p, size_t bytes)
        !           404: {
        !           405:     assert(p->result >= 0);
        !           406:     assert(p->result + bytes <= p->iov.size);
        !           407:     if (p->pid == USB_TOKEN_IN) {
        !           408:         iov_clear(p->iov.iov, p->iov.niov, p->result, bytes);
        !           409:     }
        !           410:     p->result += bytes;
        !           411: }
        !           412: 
        !           413: void usb_packet_cleanup(USBPacket *p)
        !           414: {
        !           415:     qemu_iovec_destroy(&p->iov);
        !           416: }

unix.superglobalmegacorp.com

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