1 #include "hw/usb.h" 2 #include "hw/usb/desc.h" 3 #include "trace.h" 4 5 /* ------------------------------------------------------------------ */ 6 7 static uint8_t usb_lo(uint16_t val) 8 { 9 return val & 0xff; 10 } 11 12 static uint8_t usb_hi(uint16_t val) 13 { 14 return (val >> 8) & 0xff; 15 } 16 17 int usb_desc_device(const USBDescID *id, const USBDescDevice *dev, 18 uint8_t *dest, size_t len) 19 { 20 uint8_t bLength = 0x12; 21 USBDescriptor *d = (void *)dest; 22 23 if (len < bLength) { 24 return -1; 25 } 26 27 d->bLength = bLength; 28 d->bDescriptorType = USB_DT_DEVICE; 29 30 d->u.device.bcdUSB_lo = usb_lo(dev->bcdUSB); 31 d->u.device.bcdUSB_hi = usb_hi(dev->bcdUSB); 32 d->u.device.bDeviceClass = dev->bDeviceClass; 33 d->u.device.bDeviceSubClass = dev->bDeviceSubClass; 34 d->u.device.bDeviceProtocol = dev->bDeviceProtocol; 35 d->u.device.bMaxPacketSize0 = dev->bMaxPacketSize0; 36 37 d->u.device.idVendor_lo = usb_lo(id->idVendor); 38 d->u.device.idVendor_hi = usb_hi(id->idVendor); 39 d->u.device.idProduct_lo = usb_lo(id->idProduct); 40 d->u.device.idProduct_hi = usb_hi(id->idProduct); 41 d->u.device.bcdDevice_lo = usb_lo(id->bcdDevice); 42 d->u.device.bcdDevice_hi = usb_hi(id->bcdDevice); 43 d->u.device.iManufacturer = id->iManufacturer; 44 d->u.device.iProduct = id->iProduct; 45 d->u.device.iSerialNumber = id->iSerialNumber; 46 47 d->u.device.bNumConfigurations = dev->bNumConfigurations; 48 49 return bLength; 50 } 51 52 int usb_desc_device_qualifier(const USBDescDevice *dev, 53 uint8_t *dest, size_t len) 54 { 55 uint8_t bLength = 0x0a; 56 USBDescriptor *d = (void *)dest; 57 58 if (len < bLength) { 59 return -1; 60 } 61 62 d->bLength = bLength; 63 d->bDescriptorType = USB_DT_DEVICE_QUALIFIER; 64 65 d->u.device_qualifier.bcdUSB_lo = usb_lo(dev->bcdUSB); 66 d->u.device_qualifier.bcdUSB_hi = usb_hi(dev->bcdUSB); 67 d->u.device_qualifier.bDeviceClass = dev->bDeviceClass; 68 d->u.device_qualifier.bDeviceSubClass = dev->bDeviceSubClass; 69 d->u.device_qualifier.bDeviceProtocol = dev->bDeviceProtocol; 70 d->u.device_qualifier.bMaxPacketSize0 = dev->bMaxPacketSize0; 71 d->u.device_qualifier.bNumConfigurations = dev->bNumConfigurations; 72 d->u.device_qualifier.bReserved = 0; 73 74 return bLength; 75 } 76 77 int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len) 78 { 79 uint8_t bLength = 0x09; 80 uint16_t wTotalLength = 0; 81 USBDescriptor *d = (void *)dest; 82 int i, rc; 83 84 if (len < bLength) { 85 return -1; 86 } 87 88 d->bLength = bLength; 89 d->bDescriptorType = USB_DT_CONFIG; 90 91 d->u.config.bNumInterfaces = conf->bNumInterfaces; 92 d->u.config.bConfigurationValue = conf->bConfigurationValue; 93 d->u.config.iConfiguration = conf->iConfiguration; 94 d->u.config.bmAttributes = conf->bmAttributes; 95 d->u.config.bMaxPower = conf->bMaxPower; 96 wTotalLength += bLength; 97 98 /* handle grouped interfaces if any */ 99 for (i = 0; i < conf->nif_groups; i++) { 100 rc = usb_desc_iface_group(&(conf->if_groups[i]), 101 dest + wTotalLength, 102 len - wTotalLength); 103 if (rc < 0) { 104 return rc; 105 } 106 wTotalLength += rc; 107 } 108 109 /* handle normal (ungrouped / no IAD) interfaces if any */ 110 for (i = 0; i < conf->nif; i++) { 111 rc = usb_desc_iface(conf->ifs + i, dest + wTotalLength, len - wTotalLength); 112 if (rc < 0) { 113 return rc; 114 } 115 wTotalLength += rc; 116 } 117 118 d->u.config.wTotalLength_lo = usb_lo(wTotalLength); 119 d->u.config.wTotalLength_hi = usb_hi(wTotalLength); 120 return wTotalLength; 121 } 122 123 int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest, 124 size_t len) 125 { 126 int pos = 0; 127 int i = 0; 128 129 /* handle interface association descriptor */ 130 uint8_t bLength = 0x08; 131 132 if (len < bLength) { 133 return -1; 134 } 135 136 dest[0x00] = bLength; 137 dest[0x01] = USB_DT_INTERFACE_ASSOC; 138 dest[0x02] = iad->bFirstInterface; 139 dest[0x03] = iad->bInterfaceCount; 140 dest[0x04] = iad->bFunctionClass; 141 dest[0x05] = iad->bFunctionSubClass; 142 dest[0x06] = iad->bFunctionProtocol; 143 dest[0x07] = iad->iFunction; 144 pos += bLength; 145 146 /* handle associated interfaces in this group */ 147 for (i = 0; i < iad->nif; i++) { 148 int rc = usb_desc_iface(&(iad->ifs[i]), dest + pos, len - pos); 149 if (rc < 0) { 150 return rc; 151 } 152 pos += rc; 153 } 154 155 return pos; 156 } 157 158 int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len) 159 { 160 uint8_t bLength = 0x09; 161 int i, rc, pos = 0; 162 USBDescriptor *d = (void *)dest; 163 164 if (len < bLength) { 165 return -1; 166 } 167 168 d->bLength = bLength; 169 d->bDescriptorType = USB_DT_INTERFACE; 170 171 d->u.interface.bInterfaceNumber = iface->bInterfaceNumber; 172 d->u.interface.bAlternateSetting = iface->bAlternateSetting; 173 d->u.interface.bNumEndpoints = iface->bNumEndpoints; 174 d->u.interface.bInterfaceClass = iface->bInterfaceClass; 175 d->u.interface.bInterfaceSubClass = iface->bInterfaceSubClass; 176 d->u.interface.bInterfaceProtocol = iface->bInterfaceProtocol; 177 d->u.interface.iInterface = iface->iInterface; 178 pos += bLength; 179 180 for (i = 0; i < iface->ndesc; i++) { 181 rc = usb_desc_other(iface->descs + i, dest + pos, len - pos); 182 if (rc < 0) { 183 return rc; 184 } 185 pos += rc; 186 } 187 188 for (i = 0; i < iface->bNumEndpoints; i++) { 189 rc = usb_desc_endpoint(iface->eps + i, dest + pos, len - pos); 190 if (rc < 0) { 191 return rc; 192 } 193 pos += rc; 194 } 195 196 return pos; 197 } 198 199 int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len) 200 { 201 uint8_t bLength = ep->is_audio ? 0x09 : 0x07; 202 uint8_t extralen = ep->extra ? ep->extra[0] : 0; 203 USBDescriptor *d = (void *)dest; 204 205 if (len < bLength + extralen) { 206 return -1; 207 } 208 209 d->bLength = bLength; 210 d->bDescriptorType = USB_DT_ENDPOINT; 211 212 d->u.endpoint.bEndpointAddress = ep->bEndpointAddress; 213 d->u.endpoint.bmAttributes = ep->bmAttributes; 214 d->u.endpoint.wMaxPacketSize_lo = usb_lo(ep->wMaxPacketSize); 215 d->u.endpoint.wMaxPacketSize_hi = usb_hi(ep->wMaxPacketSize); 216 d->u.endpoint.bInterval = ep->bInterval; 217 if (ep->is_audio) { 218 d->u.endpoint.bRefresh = ep->bRefresh; 219 d->u.endpoint.bSynchAddress = ep->bSynchAddress; 220 } 221 if (ep->extra) { 222 memcpy(dest + bLength, ep->extra, extralen); 223 } 224 225 return bLength + extralen; 226 } 227 228 int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len) 229 { 230 int bLength = desc->length ? desc->length : desc->data[0]; 231 232 if (len < bLength) { 233 return -1; 234 } 235 236 memcpy(dest, desc->data, bLength); 237 return bLength; 238 } 239 240 /* ------------------------------------------------------------------ */ 241 242 static void usb_desc_ep_init(USBDevice *dev) 243 { 244 const USBDescIface *iface; 245 int i, e, pid, ep; 246 247 usb_ep_init(dev); 248 for (i = 0; i < dev->ninterfaces; i++) { 249 iface = dev->ifaces[i]; 250 if (iface == NULL) { 251 continue; 252 } 253 for (e = 0; e < iface->bNumEndpoints; e++) { 254 pid = (iface->eps[e].bEndpointAddress & USB_DIR_IN) ? 255 USB_TOKEN_IN : USB_TOKEN_OUT; 256 ep = iface->eps[e].bEndpointAddress & 0x0f; 257 usb_ep_set_type(dev, pid, ep, iface->eps[e].bmAttributes & 0x03); 258 usb_ep_set_ifnum(dev, pid, ep, iface->bInterfaceNumber); 259 usb_ep_set_max_packet_size(dev, pid, ep, 260 iface->eps[e].wMaxPacketSize); 261 } 262 } 263 } 264 265 static const USBDescIface *usb_desc_find_interface(USBDevice *dev, 266 int nif, int alt) 267 { 268 const USBDescIface *iface; 269 int g, i; 270 271 if (!dev->config) { 272 return NULL; 273 } 274 for (g = 0; g < dev->config->nif_groups; g++) { 275 for (i = 0; i < dev->config->if_groups[g].nif; i++) { 276 iface = &dev->config->if_groups[g].ifs[i]; 277 if (iface->bInterfaceNumber == nif && 278 iface->bAlternateSetting == alt) { 279 return iface; 280 } 281 } 282 } 283 for (i = 0; i < dev->config->nif; i++) { 284 iface = &dev->config->ifs[i]; 285 if (iface->bInterfaceNumber == nif && 286 iface->bAlternateSetting == alt) { 287 return iface; 288 } 289 } 290 return NULL; 291 } 292 293 static int usb_desc_set_interface(USBDevice *dev, int index, int value) 294 { 295 const USBDescIface *iface; 296 int old; 297 298 iface = usb_desc_find_interface(dev, index, value); 299 if (iface == NULL) { 300 return -1; 301 } 302 303 old = dev->altsetting[index]; 304 dev->altsetting[index] = value; 305 dev->ifaces[index] = iface; 306 usb_desc_ep_init(dev); 307 308 if (old != value) { 309 usb_device_set_interface(dev, index, old, value); 310 } 311 return 0; 312 } 313 314 static int usb_desc_set_config(USBDevice *dev, int value) 315 { 316 int i; 317 318 if (value == 0) { 319 dev->configuration = 0; 320 dev->ninterfaces = 0; 321 dev->config = NULL; 322 } else { 323 for (i = 0; i < dev->device->bNumConfigurations; i++) { 324 if (dev->device->confs[i].bConfigurationValue == value) { 325 dev->configuration = value; 326 dev->ninterfaces = dev->device->confs[i].bNumInterfaces; 327 dev->config = dev->device->confs + i; 328 assert(dev->ninterfaces <= USB_MAX_INTERFACES); 329 } 330 } 331 if (i < dev->device->bNumConfigurations) { 332 return -1; 333 } 334 } 335 336 for (i = 0; i < dev->ninterfaces; i++) { 337 usb_desc_set_interface(dev, i, 0); 338 } 339 for (; i < USB_MAX_INTERFACES; i++) { 340 dev->altsetting[i] = 0; 341 dev->ifaces[i] = NULL; 342 } 343 344 return 0; 345 } 346 347 static void usb_desc_setdefaults(USBDevice *dev) 348 { 349 const USBDesc *desc = usb_device_get_usb_desc(dev); 350 351 assert(desc != NULL); 352 switch (dev->speed) { 353 case USB_SPEED_LOW: 354 case USB_SPEED_FULL: 355 dev->device = desc->full; 356 break; 357 case USB_SPEED_HIGH: 358 dev->device = desc->high; 359 break; 360 } 361 usb_desc_set_config(dev, 0); 362 } 363 364 void usb_desc_init(USBDevice *dev) 365 { 366 const USBDesc *desc = usb_device_get_usb_desc(dev); 367 368 assert(desc != NULL); 369 dev->speed = USB_SPEED_FULL; 370 dev->speedmask = 0; 371 if (desc->full) { 372 dev->speedmask |= USB_SPEED_MASK_FULL; 373 } 374 if (desc->high) { 375 dev->speedmask |= USB_SPEED_MASK_HIGH; 376 } 377 usb_desc_setdefaults(dev); 378 } 379 380 void usb_desc_attach(USBDevice *dev) 381 { 382 const USBDesc *desc = usb_device_get_usb_desc(dev); 383 384 assert(desc != NULL); 385 if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) { 386 dev->speed = USB_SPEED_HIGH; 387 } else if (desc->full && (dev->port->speedmask & USB_SPEED_MASK_FULL)) { 388 dev->speed = USB_SPEED_FULL; 389 } else { 390 fprintf(stderr, "usb: port/device speed mismatch for \"%s\"\n", 391 usb_device_get_product_desc(dev)); 392 return; 393 } 394 usb_desc_setdefaults(dev); 395 } 396 397 void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str) 398 { 399 USBDescString *s; 400 401 QLIST_FOREACH(s, &dev->strings, next) { 402 if (s->index == index) { 403 break; 404 } 405 } 406 if (s == NULL) { 407 s = g_malloc0(sizeof(*s)); 408 s->index = index; 409 QLIST_INSERT_HEAD(&dev->strings, s, next); 410 } 411 g_free(s->str); 412 s->str = g_strdup(str); 413 } 414 415 const char *usb_desc_get_string(USBDevice *dev, uint8_t index) 416 { 417 USBDescString *s; 418 419 QLIST_FOREACH(s, &dev->strings, next) { 420 if (s->index == index) { 421 return s->str; 422 } 423 } 424 return NULL; 425 } 426 427 int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len) 428 { 429 uint8_t bLength, pos, i; 430 const char *str; 431 432 if (len < 4) { 433 return -1; 434 } 435 436 if (index == 0) { 437 /* language ids */ 438 dest[0] = 4; 439 dest[1] = USB_DT_STRING; 440 dest[2] = 0x09; 441 dest[3] = 0x04; 442 return 4; 443 } 444 445 str = usb_desc_get_string(dev, index); 446 if (str == NULL) { 447 str = usb_device_get_usb_desc(dev)->str[index]; 448 if (str == NULL) { 449 return 0; 450 } 451 } 452 453 bLength = strlen(str) * 2 + 2; 454 dest[0] = bLength; 455 dest[1] = USB_DT_STRING; 456 i = 0; pos = 2; 457 while (pos+1 < bLength && pos+1 < len) { 458 dest[pos++] = str[i++]; 459 dest[pos++] = 0; 460 } 461 return pos; 462 } 463 464 int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len) 465 { 466 const USBDesc *desc = usb_device_get_usb_desc(dev); 467 const USBDescDevice *other_dev; 468 uint8_t buf[256]; 469 uint8_t type = value >> 8; 470 uint8_t index = value & 0xff; 471 int ret = -1; 472 473 if (dev->speed == USB_SPEED_HIGH) { 474 other_dev = usb_device_get_usb_desc(dev)->full; 475 } else { 476 other_dev = usb_device_get_usb_desc(dev)->high; 477 } 478 479 switch(type) { 480 case USB_DT_DEVICE: 481 ret = usb_desc_device(&desc->id, dev->device, buf, sizeof(buf)); 482 trace_usb_desc_device(dev->addr, len, ret); 483 break; 484 case USB_DT_CONFIG: 485 if (index < dev->device->bNumConfigurations) { 486 ret = usb_desc_config(dev->device->confs + index, buf, sizeof(buf)); 487 } 488 trace_usb_desc_config(dev->addr, index, len, ret); 489 break; 490 case USB_DT_STRING: 491 ret = usb_desc_string(dev, index, buf, sizeof(buf)); 492 trace_usb_desc_string(dev->addr, index, len, ret); 493 break; 494 495 case USB_DT_DEVICE_QUALIFIER: 496 if (other_dev != NULL) { 497 ret = usb_desc_device_qualifier(other_dev, buf, sizeof(buf)); 498 } 499 trace_usb_desc_device_qualifier(dev->addr, len, ret); 500 break; 501 case USB_DT_OTHER_SPEED_CONFIG: 502 if (other_dev != NULL && index < other_dev->bNumConfigurations) { 503 ret = usb_desc_config(other_dev->confs + index, buf, sizeof(buf)); 504 buf[0x01] = USB_DT_OTHER_SPEED_CONFIG; 505 } 506 trace_usb_desc_other_speed_config(dev->addr, index, len, ret); 507 break; 508 509 case USB_DT_DEBUG: 510 /* ignore silently */ 511 break; 512 513 default: 514 fprintf(stderr, "%s: %d unknown type %d (len %zd)\n", __FUNCTION__, 515 dev->addr, type, len); 516 break; 517 } 518 519 if (ret > 0) { 520 if (ret > len) { 521 ret = len; 522 } 523 memcpy(dest, buf, ret); 524 } 525 return ret; 526 } 527 528 int usb_desc_handle_control(USBDevice *dev, USBPacket *p, 529 int request, int value, int index, int length, uint8_t *data) 530 { 531 const USBDesc *desc = usb_device_get_usb_desc(dev); 532 int ret = -1; 533 534 assert(desc != NULL); 535 switch(request) { 536 case DeviceOutRequest | USB_REQ_SET_ADDRESS: 537 dev->addr = value; 538 trace_usb_set_addr(dev->addr); 539 ret = 0; 540 break; 541 542 case DeviceRequest | USB_REQ_GET_DESCRIPTOR: 543 ret = usb_desc_get_descriptor(dev, value, data, length); 544 break; 545 546 case DeviceRequest | USB_REQ_GET_CONFIGURATION: 547 /* 548 * 9.4.2: 0 should be returned if the device is unconfigured, otherwise 549 * the non zero value of bConfigurationValue. 550 */ 551 data[0] = dev->config ? dev->config->bConfigurationValue : 0; 552 ret = 1; 553 break; 554 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: 555 ret = usb_desc_set_config(dev, value); 556 trace_usb_set_config(dev->addr, value, ret); 557 break; 558 559 case DeviceRequest | USB_REQ_GET_STATUS: { 560 const USBDescConfig *config = dev->config ? 561 dev->config : &dev->device->confs[0]; 562 563 data[0] = 0; 564 /* 565 * Default state: Device behavior when this request is received while 566 * the device is in the Default state is not specified. 567 * We return the same value that a configured device would return if 568 * it used the first configuration. 569 */ 570 if (config->bmAttributes & 0x40) { 571 data[0] |= 1 << USB_DEVICE_SELF_POWERED; 572 } 573 if (dev->remote_wakeup) { 574 data[0] |= 1 << USB_DEVICE_REMOTE_WAKEUP; 575 } 576 data[1] = 0x00; 577 ret = 2; 578 break; 579 } 580 case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: 581 if (value == USB_DEVICE_REMOTE_WAKEUP) { 582 dev->remote_wakeup = 0; 583 ret = 0; 584 } 585 trace_usb_clear_device_feature(dev->addr, value, ret); 586 break; 587 case DeviceOutRequest | USB_REQ_SET_FEATURE: 588 if (value == USB_DEVICE_REMOTE_WAKEUP) { 589 dev->remote_wakeup = 1; 590 ret = 0; 591 } 592 trace_usb_set_device_feature(dev->addr, value, ret); 593 break; 594 595 case InterfaceRequest | USB_REQ_GET_INTERFACE: 596 if (index < 0 || index >= dev->ninterfaces) { 597 break; 598 } 599 data[0] = dev->altsetting[index]; 600 ret = 1; 601 break; 602 case InterfaceOutRequest | USB_REQ_SET_INTERFACE: 603 ret = usb_desc_set_interface(dev, index, value); 604 trace_usb_set_interface(dev->addr, index, value, ret); 605 break; 606 607 } 608 return ret; 609 } 610