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