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 == 0) 97 s->setup_state = SETUP_STATE_ACK; 98 else 99 s->setup_state = SETUP_STATE_DATA; 100 } 101 102 return ret; 103 } 104 105 static int do_token_in(USBDevice *s, USBPacket *p) 106 { 107 int request, value, index; 108 int ret = 0; 109 110 if (p->devep != 0) 111 return s->info->handle_data(s, p); 112 113 request = (s->setup_buf[0] << 8) | s->setup_buf[1]; 114 value = (s->setup_buf[3] << 8) | s->setup_buf[2]; 115 index = (s->setup_buf[5] << 8) | s->setup_buf[4]; 116 117 switch(s->setup_state) { 118 case SETUP_STATE_ACK: 119 if (!(s->setup_buf[0] & USB_DIR_IN)) { 120 s->setup_state = SETUP_STATE_IDLE; 121 ret = s->info->handle_control(s, request, value, index, 122 s->setup_len, s->data_buf); 123 if (ret > 0) 124 return 0; 125 return ret; 126 } 127 128 /* return 0 byte */ 129 return 0; 130 131 case SETUP_STATE_DATA: 132 if (s->setup_buf[0] & USB_DIR_IN) { 133 int len = s->setup_len - s->setup_index; 134 if (len > p->len) 135 len = p->len; 136 memcpy(p->data, s->data_buf + s->setup_index, len); 137 s->setup_index += len; 138 if (s->setup_index >= s->setup_len) 139 s->setup_state = SETUP_STATE_ACK; 140 return len; 141 } 142 143 s->setup_state = SETUP_STATE_IDLE; 144 return USB_RET_STALL; 145 146 default: 147 return USB_RET_STALL; 148 } 149 } 150 151 static int do_token_out(USBDevice *s, USBPacket *p) 152 { 153 if (p->devep != 0) 154 return s->info->handle_data(s, p); 155 156 switch(s->setup_state) { 157 case SETUP_STATE_ACK: 158 if (s->setup_buf[0] & USB_DIR_IN) { 159 s->setup_state = SETUP_STATE_IDLE; 160 /* transfer OK */ 161 } else { 162 /* ignore additional output */ 163 } 164 return 0; 165 166 case SETUP_STATE_DATA: 167 if (!(s->setup_buf[0] & USB_DIR_IN)) { 168 int len = s->setup_len - s->setup_index; 169 if (len > p->len) 170 len = p->len; 171 memcpy(s->data_buf + s->setup_index, p->data, len); 172 s->setup_index += len; 173 if (s->setup_index >= s->setup_len) 174 s->setup_state = SETUP_STATE_ACK; 175 return len; 176 } 177 178 s->setup_state = SETUP_STATE_IDLE; 179 return USB_RET_STALL; 180 181 default: 182 return USB_RET_STALL; 183 } 184 } 185 186 /* 187 * Generic packet handler. 188 * Called by the HC (host controller). 189 * 190 * Returns length of the transaction or one of the USB_RET_XXX codes. 191 */ 192 int usb_generic_handle_packet(USBDevice *s, USBPacket *p) 193 { 194 switch(p->pid) { 195 case USB_MSG_ATTACH: 196 s->state = USB_STATE_ATTACHED; 197 if (s->info->handle_attach) { 198 s->info->handle_attach(s); 199 } 200 return 0; 201 202 case USB_MSG_DETACH: 203 s->state = USB_STATE_NOTATTACHED; 204 return 0; 205 206 case USB_MSG_RESET: 207 s->remote_wakeup = 0; 208 s->addr = 0; 209 s->state = USB_STATE_DEFAULT; 210 if (s->info->handle_reset) { 211 s->info->handle_reset(s); 212 } 213 return 0; 214 } 215 216 /* Rest of the PIDs must match our address */ 217 if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr) 218 return USB_RET_NODEV; 219 220 switch (p->pid) { 221 case USB_TOKEN_SETUP: 222 return do_token_setup(s, p); 223 224 case USB_TOKEN_IN: 225 return do_token_in(s, p); 226 227 case USB_TOKEN_OUT: 228 return do_token_out(s, p); 229 230 default: 231 return USB_RET_STALL; 232 } 233 } 234 235 /* XXX: fix overflow */ 236 int set_usb_string(uint8_t *buf, const char *str) 237 { 238 int len, i; 239 uint8_t *q; 240 241 q = buf; 242 len = strlen(str); 243 *q++ = 2 * len + 2; 244 *q++ = 3; 245 for(i = 0; i < len; i++) { 246 *q++ = str[i]; 247 *q++ = 0; 248 } 249 return q - buf; 250 } 251 252 /* Send an internal message to a USB device. */ 253 void usb_send_msg(USBDevice *dev, int msg) 254 { 255 USBPacket p; 256 memset(&p, 0, sizeof(p)); 257 p.pid = msg; 258 dev->info->handle_packet(dev, &p); 259 260 /* This _must_ be synchronous */ 261 } 262