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