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

1.1       root        1: /*
                      2:  * QEMU USB emulation
                      3:  *
                      4:  * Copyright (c) 2005 Fabrice Bellard
1.1.1.4 ! 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.4 ! root       24: #include "qemu-common.h"
        !            25: #include "usb.h"
1.1       root       26: 
                     27: void usb_attach(USBPort *port, USBDevice *dev)
                     28: {
                     29:     port->attach(port, dev);
                     30: }
                     31: 
                     32: /**********************/
                     33: /* generic USB device helpers (you are not forced to use them when
                     34:    writing your USB device driver, but they help handling the
1.1.1.4 ! root       35:    protocol)
1.1       root       36: */
                     37: 
                     38: #define SETUP_STATE_IDLE 0
                     39: #define SETUP_STATE_DATA 1
                     40: #define SETUP_STATE_ACK  2
                     41: 
1.1.1.3   root       42: int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
1.1       root       43: {
                     44:     int l, ret = 0;
1.1.1.3   root       45:     int len = p->len;
                     46:     uint8_t *data = p->data;
1.1       root       47: 
1.1.1.3   root       48:     switch(p->pid) {
1.1       root       49:     case USB_MSG_ATTACH:
                     50:         s->state = USB_STATE_ATTACHED;
                     51:         break;
                     52:     case USB_MSG_DETACH:
                     53:         s->state = USB_STATE_NOTATTACHED;
                     54:         break;
                     55:     case USB_MSG_RESET:
                     56:         s->remote_wakeup = 0;
                     57:         s->addr = 0;
                     58:         s->state = USB_STATE_DEFAULT;
                     59:         s->handle_reset(s);
                     60:         break;
                     61:     case USB_TOKEN_SETUP:
1.1.1.3   root       62:         if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
1.1       root       63:             return USB_RET_NODEV;
                     64:         if (len != 8)
                     65:             goto fail;
                     66:         memcpy(s->setup_buf, data, 8);
                     67:         s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
                     68:         s->setup_index = 0;
                     69:         if (s->setup_buf[0] & USB_DIR_IN) {
1.1.1.4 ! root       70:             ret = s->handle_control(s,
1.1       root       71:                                     (s->setup_buf[0] << 8) | s->setup_buf[1],
                     72:                                     (s->setup_buf[3] << 8) | s->setup_buf[2],
                     73:                                     (s->setup_buf[5] << 8) | s->setup_buf[4],
                     74:                                     s->setup_len,
                     75:                                     s->data_buf);
                     76:             if (ret < 0)
                     77:                 return ret;
                     78:             if (ret < s->setup_len)
                     79:                 s->setup_len = ret;
                     80:             s->setup_state = SETUP_STATE_DATA;
                     81:         } else {
                     82:             if (s->setup_len == 0)
                     83:                 s->setup_state = SETUP_STATE_ACK;
                     84:             else
                     85:                 s->setup_state = SETUP_STATE_DATA;
                     86:         }
                     87:         break;
                     88:     case USB_TOKEN_IN:
1.1.1.3   root       89:         if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
1.1       root       90:             return USB_RET_NODEV;
1.1.1.3   root       91:         switch(p->devep) {
1.1       root       92:         case 0:
                     93:             switch(s->setup_state) {
                     94:             case SETUP_STATE_ACK:
                     95:                 if (!(s->setup_buf[0] & USB_DIR_IN)) {
1.1.1.2   root       96:                     s->setup_state = SETUP_STATE_IDLE;
1.1.1.4 ! root       97:                     ret = s->handle_control(s,
1.1       root       98:                                       (s->setup_buf[0] << 8) | s->setup_buf[1],
                     99:                                       (s->setup_buf[3] << 8) | s->setup_buf[2],
                    100:                                       (s->setup_buf[5] << 8) | s->setup_buf[4],
                    101:                                       s->setup_len,
                    102:                                       s->data_buf);
                    103:                     if (ret > 0)
                    104:                         ret = 0;
                    105:                 } else {
1.1.1.2   root      106:                     /* return 0 byte */
1.1       root      107:                 }
                    108:                 break;
                    109:             case SETUP_STATE_DATA:
                    110:                 if (s->setup_buf[0] & USB_DIR_IN) {
                    111:                     l = s->setup_len - s->setup_index;
                    112:                     if (l > len)
                    113:                         l = len;
                    114:                     memcpy(data, s->data_buf + s->setup_index, l);
                    115:                     s->setup_index += l;
                    116:                     if (s->setup_index >= s->setup_len)
                    117:                         s->setup_state = SETUP_STATE_ACK;
                    118:                     ret = l;
                    119:                 } else {
                    120:                     s->setup_state = SETUP_STATE_IDLE;
                    121:                     goto fail;
                    122:                 }
                    123:                 break;
                    124:             default:
                    125:                 goto fail;
                    126:             }
                    127:             break;
                    128:         default:
1.1.1.3   root      129:             ret = s->handle_data(s, p);
1.1       root      130:             break;
                    131:         }
                    132:         break;
                    133:     case USB_TOKEN_OUT:
1.1.1.3   root      134:         if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
1.1       root      135:             return USB_RET_NODEV;
1.1.1.3   root      136:         switch(p->devep) {
1.1       root      137:         case 0:
                    138:             switch(s->setup_state) {
                    139:             case SETUP_STATE_ACK:
                    140:                 if (s->setup_buf[0] & USB_DIR_IN) {
1.1.1.2   root      141:                     s->setup_state = SETUP_STATE_IDLE;
1.1       root      142:                     /* transfer OK */
                    143:                 } else {
1.1.1.4 ! root      144:                     /* ignore additional output */
1.1       root      145:                 }
                    146:                 break;
                    147:             case SETUP_STATE_DATA:
                    148:                 if (!(s->setup_buf[0] & USB_DIR_IN)) {
                    149:                     l = s->setup_len - s->setup_index;
                    150:                     if (l > len)
                    151:                         l = len;
                    152:                     memcpy(s->data_buf + s->setup_index, data, l);
                    153:                     s->setup_index += l;
                    154:                     if (s->setup_index >= s->setup_len)
                    155:                         s->setup_state = SETUP_STATE_ACK;
                    156:                     ret = l;
                    157:                 } else {
                    158:                     s->setup_state = SETUP_STATE_IDLE;
                    159:                     goto fail;
                    160:                 }
                    161:                 break;
                    162:             default:
                    163:                 goto fail;
                    164:             }
                    165:             break;
                    166:         default:
1.1.1.3   root      167:             ret = s->handle_data(s, p);
1.1       root      168:             break;
                    169:         }
                    170:         break;
                    171:     default:
                    172:     fail:
                    173:         ret = USB_RET_STALL;
                    174:         break;
                    175:     }
                    176:     return ret;
                    177: }
                    178: 
                    179: /* XXX: fix overflow */
                    180: int set_usb_string(uint8_t *buf, const char *str)
                    181: {
                    182:     int len, i;
                    183:     uint8_t *q;
                    184: 
                    185:     q = buf;
                    186:     len = strlen(str);
1.1.1.2   root      187:     *q++ = 2 * len + 2;
1.1       root      188:     *q++ = 3;
                    189:     for(i = 0; i < len; i++) {
                    190:         *q++ = str[i];
                    191:         *q++ = 0;
                    192:     }
                    193:     return q - buf;
                    194: }
1.1.1.3   root      195: 
                    196: /* Send an internal message to a USB device.  */
                    197: void usb_send_msg(USBDevice *dev, int msg)
                    198: {
                    199:     USBPacket p;
                    200:     memset(&p, 0, sizeof(p));
                    201:     p.pid = msg;
                    202:     dev->handle_packet(dev, &p);
                    203: }
                    204: 

unix.superglobalmegacorp.com

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