1 /* 2 * Implementation of generic HCD 3 */ 4 5 #include <string.h> /* memcpy */ 6 7 #include <minix/drivers.h> /* errno with sign */ 8 9 #include <usbd/hcd_common.h> 10 #include <usbd/hcd_ddekit.h> 11 #include <usbd/hcd_interface.h> 12 #include <usbd/hcd_schedule.h> 13 #include <usbd/usbd_common.h> 14 15 16 /*===========================================================================* 17 * Local declarations * 18 *===========================================================================*/ 19 /* Thread to handle device logic */ 20 static void hcd_device_thread(void *); 21 22 /* Procedure that locks device thread forever in case of error/completion */ 23 static void hcd_device_finish(hcd_device_state *, const char *); 24 25 /* Procedure that finds device, waiting for given EP interrupt */ 26 static hcd_device_state * hcd_get_child_for_ep(hcd_device_state *, hcd_reg1); 27 28 /* For HCD level, hub handling */ 29 static void hcd_add_child(hcd_device_state *, hcd_reg1, hcd_speed); 30 static void hcd_delete_child(hcd_device_state *, hcd_reg1); 31 static void hcd_disconnect_tree(hcd_device_state *); 32 static void hcd_dump_tree(hcd_device_state *, hcd_reg1); 33 34 /* Typical USD device communication procedures */ 35 static int hcd_enumerate(hcd_device_state *); 36 static int hcd_get_device_descriptor(hcd_device_state *); 37 static int hcd_set_address(hcd_device_state *); 38 static int hcd_get_descriptor_tree(hcd_device_state *); 39 static int hcd_set_configuration(hcd_device_state *, hcd_reg1); 40 static void hcd_handle_urb(hcd_device_state *); 41 static void hcd_complete_urb(hcd_device_state *); 42 static int hcd_control_urb(hcd_device_state *, hcd_urb *); 43 static int hcd_non_control_urb(hcd_device_state *, hcd_urb *); 44 45 /* For internal use by more general methods */ 46 static int hcd_setup_packet(hcd_device_state *, hcd_ctrlrequest *, hcd_reg1); 47 static int hcd_finish_setup(hcd_device_state *, void *); 48 static int hcd_data_transfer(hcd_device_state *, hcd_datarequest *); 49 50 /* TODO: This is not meant to be explicitly visible outside DDEKit library 51 * but there is no other way to set thread priority for now */ 52 extern void _ddekit_thread_set_myprio(int); 53 54 55 /*===========================================================================* 56 * Local definitions * 57 *===========================================================================*/ 58 /* TODO: This was added for compatibility with DDELinux drivers that 59 * allow receiving less data than expected in URB, without error */ 60 #define HCD_ANY_LENGTH 0xFFFFFFFFu 61 62 /* This doesn't seem to be specified in standard but abnormal values 63 * are unlikely so check for this was added below */ 64 #define HCD_SANE_DESCRIPTOR_LENGTH 2048 65 66 67 /*===========================================================================* 68 * hcd_handle_event * 69 *===========================================================================*/ 70 void 71 hcd_handle_event(hcd_device_state * device, hcd_event event, hcd_reg1 val) 72 { 73 DEBUG_DUMP; 74 75 /* Invalid device may be supplied */ 76 if (EXIT_SUCCESS != hcd_check_device(device)) { 77 USB_MSG("No device available for event: 0x%02X, value: 0x%02X", 78 event, val); 79 return; 80 } 81 82 #ifdef HCD_DUMP_DEVICE_TREE 83 /* This can be unlocked to dump current USB device tree on event */ 84 { 85 /* Go to the base of USB device tree and 86 * print the current state of it */ 87 hcd_device_state * base; 88 89 base = device; 90 91 while (NULL != base->parent) 92 base = base->parent; 93 94 USB_MSG("Current state of USB device tree:"); 95 hcd_dump_tree(base, 0); 96 } 97 #endif 98 99 /* Handle event and forward control to device thread when required */ 100 switch (event) { 101 case HCD_EVENT_CONNECTED: 102 USB_ASSERT((HCD_STATE_DISCONNECTED == device->state), 103 "Device not marked as 'disconnected' " 104 "for 'connection' event"); 105 106 /* Try creating new thread for device */ 107 if (hcd_connect_device(device, hcd_device_thread)) 108 USB_MSG("Device creation failed, nothing more " 109 "will happen until disconnected"); 110 111 break; 112 113 case HCD_EVENT_DISCONNECTED: 114 USB_ASSERT((HCD_STATE_DISCONNECTED != device->state), 115 "Device is marked as 'disconnected' " 116 "for 'disconnection' event"); 117 118 /* Make this device and all attached children 119 * disconnect recursively */ 120 hcd_disconnect_tree(device); 121 122 break; 123 124 case HCD_EVENT_PORT_LS_CONNECTED: 125 USB_ASSERT((HCD_STATE_DISCONNECTED != device->state), 126 "Device is marked as 'disconnected' " 127 "for 'hub port LS attach' event"); 128 129 USB_MSG("Low speed device connected at " 130 "hub 0x%p, port %u", device, val); 131 132 hcd_add_child(device, val, HCD_SPEED_LOW); 133 break; 134 135 case HCD_EVENT_PORT_FS_CONNECTED: 136 USB_ASSERT((HCD_STATE_DISCONNECTED != device->state), 137 "Device is marked as 'disconnected' " 138 "for 'hub port FS attach' event"); 139 140 USB_MSG("Full speed device connected at " 141 "hub 0x%p, port %u", device, val); 142 143 hcd_add_child(device, val, HCD_SPEED_FULL); 144 break; 145 146 case HCD_EVENT_PORT_HS_CONNECTED: 147 USB_ASSERT((HCD_STATE_DISCONNECTED != device->state), 148 "Device is marked as 'disconnected' " 149 "for 'hub port HS attach' event"); 150 151 USB_MSG("High speed device connected at " 152 "hub 0x%p, port %u", device, val); 153 154 hcd_add_child(device, val, HCD_SPEED_HIGH); 155 break; 156 157 case HCD_EVENT_PORT_DISCONNECTED: 158 USB_ASSERT((HCD_STATE_DISCONNECTED != device->state), 159 "Device is marked as 'disconnected' " 160 "for 'hub port detach' event"); 161 162 hcd_delete_child(device, val); 163 164 USB_MSG("Device disconnected from " 165 "hub 0x%p, port %u", device, val); 166 167 break; 168 169 case HCD_EVENT_ENDPOINT: 170 USB_ASSERT((HCD_STATE_DISCONNECTED != device->state), 171 "Parent device is marked as 'disconnected' " 172 "for 'endpoint' event"); 173 174 /* Alters 'device' when endpoint is allocated to 175 * child rather than parent (hub), which allows 176 * proper thread to continue */ 177 device = hcd_get_child_for_ep(device, val); 178 179 /* Check if anything at all, waits for such endpoint */ 180 if (device) 181 /* Allow device thread, waiting for endpoint 182 * event, to continue with its logic */ 183 hcd_device_continue(device, event, val); 184 else 185 USB_MSG("No device waits for endpoint %u", val); 186 187 break; 188 189 case HCD_EVENT_URB: 190 USB_ASSERT((HCD_STATE_DISCONNECTED != device->state), 191 "Device is marked as 'disconnected' " 192 "for 'URB' event"); 193 194 /* Allow device thread to continue with it's logic */ 195 hcd_device_continue(device, event, val); 196 197 break; 198 199 default: 200 USB_ASSERT(0, "Illegal HCD event"); 201 } 202 } 203 204 205 /*===========================================================================* 206 * hcd_update_port * 207 *===========================================================================*/ 208 void 209 hcd_update_port(hcd_driver_state * driver, hcd_event event) 210 { 211 DEBUG_DUMP; 212 213 switch (event) { 214 case HCD_EVENT_CONNECTED: 215 /* Check if already assigned */ 216 USB_ASSERT(NULL == driver->port_device, 217 "Device was already connected before " 218 "receiving 'connection' event"); 219 220 /* Assign new blank device */ 221 driver->port_device = hcd_new_device(); 222 223 /* Associate this device with driver */ 224 driver->port_device->driver = driver; 225 break; 226 227 case HCD_EVENT_DISCONNECTED: 228 /* Check if already released */ 229 USB_ASSERT(NULL != driver->port_device, 230 "Device was already disconnected before " 231 "receiving 'disconnection' event"); 232 233 /* Release device */ 234 hcd_delete_device(driver->port_device); 235 236 /* Clear port device pointer */ 237 driver->port_device = NULL; 238 break; 239 240 default: 241 USB_ASSERT(0, "Illegal port update event"); 242 } 243 } 244 245 246 /*===========================================================================* 247 * hcd_device_thread * 248 *===========================================================================*/ 249 static void 250 hcd_device_thread(void * thread_args) 251 { 252 hcd_device_state * this_device; 253 254 DEBUG_DUMP; 255 256 /* Set device thread priority higher so it 257 * won't change context unless explicitly locked */ 258 _ddekit_thread_set_myprio(2); 259 260 /* Retrieve structures from generic data */ 261 this_device = (hcd_device_state *)thread_args; 262 263 /* Enumeration sequence */ 264 if (EXIT_SUCCESS != hcd_enumerate(this_device)) 265 hcd_device_finish(this_device, "USB device enumeration failed"); 266 267 /* Tell everyone that device was connected */ 268 hcd_connect_cb(this_device); 269 270 /* Fully configured */ 271 this_device->state = HCD_STATE_CONNECTED; 272 273 USB_DBG("Waiting for URBs"); 274 275 /* Start handling URB's */ 276 for(;;) { 277 /* Block and wait for something like 'submit URB' */ 278 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_UNUSED_VAL); 279 hcd_handle_urb(this_device); 280 } 281 282 /* Finish device handling to avoid leaving thread */ 283 hcd_device_finish(this_device, "USB device handling completed"); 284 } 285 286 287 /*===========================================================================* 288 * hcd_device_finish * 289 *===========================================================================*/ 290 static void 291 hcd_device_finish(hcd_device_state * this_device, const char * finish_msg) 292 { 293 DEBUG_DUMP; 294 295 USB_MSG("USB device handling finished with message: '%s'", finish_msg); 296 297 /* Lock forever */ 298 for (;;) { 299 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_UNUSED_VAL); 300 USB_MSG("Failed attempt to continue finished thread"); 301 } 302 } 303 304 305 /*===========================================================================* 306 * hcd_get_child_for_ep * 307 *===========================================================================*/ 308 static hcd_device_state * 309 hcd_get_child_for_ep(hcd_device_state * device, hcd_reg1 ep) 310 { 311 hcd_device_state * child_found; 312 hcd_device_state * final_found; 313 hcd_device_state * child; 314 hcd_reg1 child_num; 315 316 DEBUG_DUMP; 317 318 /* Nothing yet */ 319 final_found = NULL; 320 321 /* Check if any children (and their children) wait for EP event */ 322 /* Every device in tree is checked every time so errors can be found */ 323 for (child_num = 0; child_num < HCD_CHILDREN; child_num++) { 324 /* Device, to be checked for EP event recursively... */ 325 child = device->child[child_num]; 326 327 /* ...but only if attached */ 328 if (NULL != child) { 329 /* Look deeper first */ 330 child_found = hcd_get_child_for_ep(child, ep); 331 332 if (NULL != child_found) { 333 /* Only one device can wait for EP event */ 334 USB_ASSERT((NULL == final_found), 335 "More than one device waits for EP"); 336 /* Remember what was found */ 337 final_found = child_found; 338 } 339 } 340 } 341 342 /* Check this device last */ 343 if ((HCD_EVENT_ENDPOINT == device->wait_event) && 344 (ep == device->wait_ep)) { 345 /* Only one device can wait for EP event */ 346 USB_ASSERT((NULL == final_found), 347 "More than one device waits for EP"); 348 /* Remember what was found */ 349 final_found = device; 350 } 351 352 return final_found; 353 } 354 355 356 /*===========================================================================* 357 * hcd_add_child * 358 *===========================================================================*/ 359 static void 360 hcd_add_child(hcd_device_state * parent, hcd_reg1 port, hcd_speed speed) 361 { 362 DEBUG_DUMP; 363 364 USB_ASSERT(port < HCD_CHILDREN, "Port number too high"); 365 USB_ASSERT(NULL == parent->child[port], "Child device already exists"); 366 367 /* Basic addition */ 368 parent->child[port] = hcd_new_device(); 369 parent->child[port]->parent = parent; 370 371 /* Inherit parent's driver */ 372 parent->child[port]->driver = parent->driver; 373 374 /* Remember speed, determined by hub driver */ 375 parent->child[port]->speed = speed; 376 377 /* Try creating new thread for device */ 378 if (hcd_connect_device(parent->child[port], hcd_device_thread)) 379 USB_MSG("Device creation failed, nothing more " 380 "will happen until disconnected"); 381 } 382 383 384 /*===========================================================================* 385 * hcd_delete_child * 386 *===========================================================================*/ 387 static void 388 hcd_delete_child(hcd_device_state * parent, hcd_reg1 port) 389 { 390 hcd_device_state * child; 391 392 DEBUG_DUMP; 393 394 USB_ASSERT(port < HCD_CHILDREN, "Port number too high"); 395 396 child = parent->child[port]; /* Child to be detached */ 397 398 USB_ASSERT(NULL != child, "Child device does not exist"); 399 400 /* Make this child device and all its attached children 401 * disconnect recursively */ 402 hcd_disconnect_tree(child); 403 404 /* Delete to release device itself */ 405 hcd_delete_device(child); 406 407 /* Mark as released */ 408 parent->child[port] = NULL; 409 } 410 411 412 /*===========================================================================* 413 * hcd_disconnect_tree * 414 *===========================================================================*/ 415 static void 416 hcd_disconnect_tree(hcd_device_state * device) 417 { 418 hcd_reg1 child_num; 419 420 DEBUG_DUMP; 421 422 /* Generate disconnect event for all children */ 423 for (child_num = 0; child_num < HCD_CHILDREN; child_num++) { 424 if (NULL != device->child[child_num]) 425 hcd_handle_event(device, HCD_EVENT_PORT_DISCONNECTED, 426 child_num); 427 } 428 429 /* If this device was detached during URB handling, some steps must be 430 * taken to ensure that no process/thread is waiting for completion */ 431 if (NULL != device->urb) { 432 USB_MSG("Unplugged device had unhandled URB"); 433 /* Tell device driver that device was detached */ 434 /* TODO: ENODEV selected for that */ 435 device->urb->inout_status = ENODEV; 436 hcd_complete_urb(device); 437 } 438 439 /* If connect callback was used before, call 440 * it's equivalent to signal disconnection */ 441 if (HCD_STATE_CONNECTED == device->state) 442 hcd_disconnect_cb(device); 443 444 /* Handle device disconnection (freeing memory etc.) */ 445 hcd_disconnect_device(device); 446 } 447 448 449 /*===========================================================================* 450 * hcd_dump_tree * 451 *===========================================================================*/ 452 static void 453 hcd_dump_tree(hcd_device_state * device, hcd_reg1 level) 454 { 455 hcd_reg1 child_num; 456 457 /* DEBUG_DUMP; */ /* Let's keep tree output cleaner */ 458 459 USB_MSG("Device on level %03u: 0x%p", level, device); 460 461 /* Traverse device tree recursively */ 462 for (child_num = 0; child_num < HCD_CHILDREN; child_num++) { 463 if (NULL != device->child[child_num]) 464 hcd_dump_tree(device->child[child_num], level + 1); 465 } 466 } 467 468 469 /*===========================================================================* 470 * hcd_enumerate * 471 *===========================================================================*/ 472 static int 473 hcd_enumerate(hcd_device_state * this_device) 474 { 475 hcd_driver_state * d; 476 477 DEBUG_DUMP; 478 479 d = this_device->driver; 480 481 /* Having a parent device also means being reseted by it 482 * so only reset devices that have no parents */ 483 if (NULL == this_device->parent) { 484 /* First let driver reset device */ 485 if (EXIT_SUCCESS != d->reset_device(d->private_data, 486 &(this_device->speed))) { 487 USB_MSG("Failed to reset device"); 488 return EXIT_FAILURE; 489 } 490 } 491 492 /* Default MaxPacketSize, based on speed */ 493 if (HCD_SPEED_HIGH == this_device->speed) 494 this_device->max_packet_size = HCD_HS_MAXPACKETSIZE; 495 else 496 this_device->max_packet_size = HCD_LS_MAXPACKETSIZE; 497 498 /* Get device descriptor */ 499 if (EXIT_SUCCESS != hcd_get_device_descriptor(this_device)) { 500 USB_MSG("Failed to get device descriptor"); 501 return EXIT_FAILURE; 502 } 503 504 /* Remember max packet size from device descriptor */ 505 this_device->max_packet_size = this_device->device_desc.bMaxPacketSize; 506 507 /* Dump device descriptor in debug mode */ 508 #ifdef DEBUG 509 { 510 hcd_device_descriptor * d; 511 d = &(this_device->device_desc); 512 513 USB_DBG("<<DEVICE>>"); 514 USB_DBG("bLength %02X", d->bLength); 515 USB_DBG("bDescriptorType %02X", d->bDescriptorType); 516 USB_DBG("bcdUSB %04X", UGETW(d->bcdUSB)); 517 USB_DBG("bDeviceClass %02X", d->bDeviceClass); 518 USB_DBG("bDeviceSubClass %02X", d->bDeviceSubClass); 519 USB_DBG("bDeviceProtocol %02X", d->bDeviceProtocol); 520 USB_DBG("bMaxPacketSize %02X", d->bMaxPacketSize); 521 USB_DBG("idVendor %04X", UGETW(d->idVendor)); 522 USB_DBG("idProduct %04X", UGETW(d->idProduct)); 523 USB_DBG("bcdDevice %04X", UGETW(d->bcdDevice)); 524 USB_DBG("iManufacturer %02X", d->iManufacturer); 525 USB_DBG("iProduct %02X", d->iProduct); 526 USB_DBG("iSerialNumber %02X", d->iSerialNumber); 527 USB_DBG("bNumConfigurations %02X", d->bNumConfigurations); 528 } 529 #endif 530 531 /* Set reserved address */ 532 if (EXIT_SUCCESS != hcd_set_address(this_device)) { 533 USB_MSG("Failed to set device address"); 534 return EXIT_FAILURE; 535 } 536 537 /* Sleep 5msec to allow addressing */ 538 hcd_os_nanosleep(HCD_NANOSLEEP_MSEC(5)); 539 540 /* Remember what was assigned in hardware */ 541 this_device->current_address = this_device->reserved_address; 542 543 /* Get other descriptors */ 544 if (EXIT_SUCCESS != hcd_get_descriptor_tree(this_device)) { 545 USB_MSG("Failed to get configuration descriptor tree"); 546 return EXIT_FAILURE; 547 } 548 549 /* TODO: Always use first configuration, as there is no support for 550 * multiple configurations in DDEKit/devman and devices rarely have 551 * more than one anyway */ 552 /* Set configuration */ 553 if (EXIT_SUCCESS != hcd_set_configuration(this_device, 554 HCD_SET_CONFIG_NUM(HCD_DEFAULT_CONFIG))) { 555 USB_MSG("Failed to set configuration"); 556 return EXIT_FAILURE; 557 } 558 559 USB_DBG("Enumeration completed"); 560 561 return EXIT_SUCCESS; 562 } 563 564 565 /*===========================================================================* 566 * hcd_get_device_descriptor * 567 *===========================================================================*/ 568 static int 569 hcd_get_device_descriptor(hcd_device_state * this_device) 570 { 571 hcd_ctrlrequest setup; 572 hcd_urb urb; 573 574 DEBUG_DUMP; 575 576 /* TODO: magic numbers, no header for these */ 577 /* Format setup packet */ 578 setup.bRequestType = 0x80; /* IN */ 579 setup.bRequest = 0x06; /* Get descriptor */ 580 setup.wValue = 0x0100; /* Device */ 581 setup.wIndex = 0x0000; 582 setup.wLength = sizeof(this_device->device_desc); 583 584 /* Prepare self-URB */ 585 memset(&urb, 0, sizeof(urb)); 586 urb.direction = HCD_DIRECTION_IN; 587 urb.endpoint = HCD_DEFAULT_EP; 588 urb.in_setup = &setup; 589 urb.inout_data = (hcd_reg1 *)(&(this_device->device_desc)); 590 urb.target_device = this_device; 591 urb.type = HCD_TRANSFER_CONTROL; 592 593 /* Put it to be scheduled and wait for control to get back */ 594 hcd_schedule_internal_urb(&urb); 595 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_UNUSED_VAL); 596 hcd_handle_urb(this_device); 597 598 /* Check if URB submission completed successfully */ 599 if (urb.inout_status) { 600 USB_MSG("URB submission failed"); 601 return EXIT_FAILURE; 602 } 603 604 /* Check if expected size was received */ 605 if (urb.out_size != setup.wLength) { 606 USB_MSG("URB submission returned invalid amount of data"); 607 return EXIT_FAILURE; 608 } 609 610 return EXIT_SUCCESS; 611 } 612 613 614 /*===========================================================================* 615 * hcd_set_address * 616 *===========================================================================*/ 617 static int 618 hcd_set_address(hcd_device_state * this_device) 619 { 620 hcd_ctrlrequest setup; 621 hcd_urb urb; 622 623 DEBUG_DUMP; 624 625 /* Check for legal USB device address (must be non-zero as well) */ 626 USB_ASSERT((this_device->reserved_address > HCD_DEFAULT_ADDR) && 627 (this_device->reserved_address <= HCD_LAST_ADDR), 628 "Illegal device address supplied"); 629 630 /* TODO: magic numbers, no header for these */ 631 setup.bRequestType = 0x00; /* OUT */ 632 setup.bRequest = 0x05; /* Set address */ 633 setup.wValue = this_device->reserved_address; 634 setup.wIndex = 0x0000; 635 setup.wLength = 0x0000; 636 637 /* Prepare self-URB */ 638 memset(&urb, 0, sizeof(urb)); 639 urb.direction = HCD_DIRECTION_OUT; 640 urb.endpoint = HCD_DEFAULT_EP; 641 urb.in_setup = &setup; 642 urb.inout_data = NULL; 643 urb.target_device = this_device; 644 urb.type = HCD_TRANSFER_CONTROL; 645 646 /* Put it to be scheduled and wait for control to get back */ 647 hcd_schedule_internal_urb(&urb); 648 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_UNUSED_VAL); 649 hcd_handle_urb(this_device); 650 651 /* Check if URB submission completed successfully */ 652 if (urb.inout_status) { 653 USB_MSG("URB submission failed"); 654 return EXIT_FAILURE; 655 } 656 657 /* Check if expected size was received */ 658 if (urb.out_size != setup.wLength) { 659 USB_MSG("URB submission returned invalid amount of data"); 660 return EXIT_FAILURE; 661 } 662 663 return EXIT_SUCCESS; 664 } 665 666 667 /*===========================================================================* 668 * hcd_get_descriptor_tree * 669 *===========================================================================*/ 670 static int 671 hcd_get_descriptor_tree(hcd_device_state * this_device) 672 { 673 hcd_config_descriptor temp_config_descriptor; 674 hcd_ctrlrequest setup; 675 hcd_urb urb; 676 677 /* To receive data */ 678 hcd_reg4 expected_length; 679 hcd_reg1 * expected_buffer; 680 681 int retval; 682 683 DEBUG_DUMP; 684 685 /* Initially */ 686 retval = EXIT_FAILURE; 687 expected_buffer = NULL; 688 689 /* First part gets only configuration to find out total length */ 690 { 691 /* TODO: Default configuration is hard-coded 692 * but others are rarely used anyway */ 693 /* TODO: magic numbers, no header for these */ 694 setup.bRequestType = 0x80; /* IN */ 695 setup.bRequest = 0x06; /* Get descriptor */ 696 setup.wValue = 0x0200 | HCD_DEFAULT_CONFIG; 697 setup.wIndex = 0x0000; 698 setup.wLength = sizeof(temp_config_descriptor); 699 700 /* Prepare self-URB */ 701 memset(&urb, 0, sizeof(urb)); 702 urb.direction = HCD_DIRECTION_IN; 703 urb.endpoint = HCD_DEFAULT_EP; 704 urb.in_setup = &setup; 705 urb.inout_data = (hcd_reg1 *)(&temp_config_descriptor); 706 urb.target_device = this_device; 707 urb.type = HCD_TRANSFER_CONTROL; 708 709 /* Put it to be scheduled and wait for control to get back */ 710 hcd_schedule_internal_urb(&urb); 711 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_UNUSED_VAL); 712 hcd_handle_urb(this_device); 713 714 /* Check if URB submission completed successfully */ 715 if (urb.inout_status) { 716 USB_MSG("URB submission failed"); 717 goto FINISH; 718 } 719 720 /* Check if expected size was received */ 721 if (urb.out_size != setup.wLength) { 722 USB_MSG("URB submission returned " 723 "invalid amount of data"); 724 goto FINISH; 725 } 726 } 727 728 /* Get total expected length */ 729 expected_length = UGETW(temp_config_descriptor.wTotalLength); 730 731 /* Check for abnormal value */ 732 if (expected_length > HCD_SANE_DESCRIPTOR_LENGTH) { 733 USB_MSG("Total descriptor length declared is too high"); 734 goto FINISH; 735 } 736 737 /* Get descriptor buffer to hold everything expected */ 738 if (NULL == (expected_buffer = malloc(expected_length))) { 739 USB_MSG("Descriptor allocation failed"); 740 goto FINISH; 741 } 742 743 /* Second part gets all available descriptors */ 744 { 745 /* TODO: Default configuration is hard-coded 746 * but others are rarely used anyway */ 747 /* TODO: magic numbers, no header for these */ 748 setup.bRequestType = 0x80; /* IN */ 749 setup.bRequest = 0x06; /* Get descriptor */ 750 setup.wValue = 0x0200 | HCD_DEFAULT_CONFIG; 751 setup.wIndex = 0x0000; 752 setup.wLength = expected_length; 753 754 /* Prepare self-URB */ 755 memset(&urb, 0, sizeof(urb)); 756 urb.direction = HCD_DIRECTION_IN; 757 urb.endpoint = HCD_DEFAULT_EP; 758 urb.in_setup = &setup; 759 urb.inout_data = expected_buffer; 760 urb.target_device = this_device; 761 urb.type = HCD_TRANSFER_CONTROL; 762 763 /* Put it to be scheduled and wait for control to get back */ 764 hcd_schedule_internal_urb(&urb); 765 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_UNUSED_VAL); 766 hcd_handle_urb(this_device); 767 768 /* Check if URB submission completed successfully */ 769 if (urb.inout_status) { 770 USB_MSG("URB submission failed"); 771 goto FINISH; 772 } 773 774 /* Check if expected size was received */ 775 if (urb.out_size != setup.wLength) { 776 USB_MSG("URB submission returned " 777 "invalid amount of data"); 778 goto FINISH; 779 } 780 } 781 782 if (EXIT_SUCCESS != hcd_buffer_to_tree(expected_buffer, 783 (int)expected_length, 784 &(this_device->config_tree))) { 785 USB_MSG("Broken descriptor data"); 786 goto FINISH; 787 } 788 789 /* No errors occurred */ 790 retval = EXIT_SUCCESS; 791 792 FINISH: 793 794 /* Release allocated buffer */ 795 if (expected_buffer) 796 free(expected_buffer); 797 798 return retval; 799 } 800 801 802 /*===========================================================================* 803 * hcd_set_configuration * 804 *===========================================================================*/ 805 static int 806 hcd_set_configuration(hcd_device_state * this_device, hcd_reg1 configuration) 807 { 808 hcd_ctrlrequest setup; 809 hcd_urb urb; 810 811 DEBUG_DUMP; 812 813 /* TODO: magic numbers, no header for these */ 814 setup.bRequestType = 0x00; /* OUT */ 815 setup.bRequest = 0x09; /* Set configuration */ 816 setup.wValue = configuration; 817 setup.wIndex = 0x0000; 818 setup.wLength = 0x0000; 819 820 /* Prepare self-URB */ 821 memset(&urb, 0, sizeof(urb)); 822 urb.direction = HCD_DIRECTION_OUT; 823 urb.endpoint = HCD_DEFAULT_EP; 824 urb.in_setup = &setup; 825 urb.inout_data = NULL; 826 urb.target_device = this_device; 827 urb.type = HCD_TRANSFER_CONTROL; 828 829 /* Put it to be scheduled and wait for control to get back */ 830 hcd_schedule_internal_urb(&urb); 831 hcd_device_wait(this_device, HCD_EVENT_URB, HCD_UNUSED_VAL); 832 hcd_handle_urb(this_device); 833 834 return urb.inout_status; 835 } 836 837 838 /*===========================================================================* 839 * hcd_handle_urb * 840 *===========================================================================*/ 841 static void 842 hcd_handle_urb(hcd_device_state * this_device) 843 { 844 hcd_urb * urb; 845 int transfer_status; 846 847 DEBUG_DUMP; 848 849 /* Retrieve URB */ 850 urb = this_device->urb; 851 852 USB_ASSERT(NULL != urb, "No URB supplied"); 853 USB_ASSERT(this_device == urb->target_device, "Unknown device for URB"); 854 855 /* Only if URB parsing was completed... */ 856 if (EXIT_SUCCESS == urb->inout_status) { 857 858 transfer_status = EXIT_FAILURE; 859 860 /* ...check for URB to handle */ 861 switch (urb->type) { 862 case HCD_TRANSFER_CONTROL: 863 transfer_status = hcd_control_urb( 864 this_device, urb); 865 break; 866 867 case HCD_TRANSFER_BULK: 868 case HCD_TRANSFER_INTERRUPT: 869 transfer_status = hcd_non_control_urb( 870 this_device, urb); 871 break; 872 873 default: 874 USB_MSG("Unsupported transfer type 0x%02X", 875 (int)urb->type); 876 break; 877 } 878 879 /* In case of error, only dump message */ 880 if (EXIT_SUCCESS != transfer_status) 881 USB_MSG("USB transfer failed"); 882 883 } else 884 USB_MSG("Invalid URB supplied"); 885 886 /* Perform completion routine */ 887 hcd_complete_urb(this_device); 888 } 889 890 891 /*===========================================================================* 892 * hcd_complete_urb * 893 *===========================================================================*/ 894 static void 895 hcd_complete_urb(hcd_device_state * this_device) 896 { 897 DEBUG_DUMP; 898 899 /* Signal scheduler that URB was handled */ 900 this_device->urb->handled(this_device->urb); 901 902 /* Use this callback in case it is an external URB */ 903 hcd_completion_cb(this_device->urb); 904 905 /* Make device forget about this URB */ 906 this_device->urb = NULL; 907 } 908 909 910 /*===========================================================================* 911 * hcd_control_urb * 912 *===========================================================================*/ 913 static int 914 hcd_control_urb(hcd_device_state * this_device, hcd_urb * urb) 915 { 916 DEBUG_DUMP; 917 918 /* Assume bad values unless something different occurs later */ 919 urb->inout_status = EINVAL; 920 921 /* Must have setup packet for control transfer */ 922 if (NULL == urb->in_setup) { 923 USB_MSG("No setup packet in URB, for control transfer"); 924 return EXIT_FAILURE; 925 } 926 927 /* TODO: Only EP0 can have control transfer */ 928 if (HCD_DEFAULT_EP != urb->endpoint) { 929 USB_MSG("Control transfer for non zero EP"); 930 return EXIT_FAILURE; 931 } 932 933 /* Setup and URB directions should match */ 934 if (((urb->in_setup->bRequestType >> 7) & 0x01) != urb->direction) { 935 USB_MSG("URB Direction mismatch"); 936 return EXIT_FAILURE; 937 } 938 939 /* Send setup packet */ 940 if (EXIT_SUCCESS != hcd_setup_packet(this_device, urb->in_setup, 941 urb->endpoint)) { 942 USB_MSG("Sending URB setup packet, failed"); 943 urb->inout_status = EPIPE; 944 return EXIT_FAILURE; 945 } 946 947 /* Put what was read back into URB */ 948 if (EXIT_SUCCESS != hcd_finish_setup(this_device, urb->inout_data)) 949 return EXIT_FAILURE; 950 951 /* Write transfer output info to URB */ 952 urb->out_size = (hcd_reg4)this_device->control_len; 953 urb->inout_status = EXIT_SUCCESS; 954 955 return EXIT_SUCCESS; 956 } 957 958 959 /*===========================================================================* 960 * hcd_non_control_urb * 961 *===========================================================================*/ 962 static int 963 hcd_non_control_urb(hcd_device_state * this_device, hcd_urb * urb) 964 { 965 hcd_endpoint * e; 966 hcd_datarequest request; 967 968 DEBUG_DUMP; 969 970 /* Assume bad values unless something different occurs later */ 971 urb->inout_status = EINVAL; 972 973 /* Must have data buffer to send/receive */ 974 if (NULL == urb->inout_data) { 975 USB_MSG("No data packet in URB"); 976 return EXIT_FAILURE; 977 } 978 979 if (HCD_DEFAULT_EP == urb->endpoint) { 980 USB_MSG("Non-control transfer for EP0"); 981 return EXIT_FAILURE; 982 } 983 984 /* Check if EP number is valid within remembered descriptor tree */ 985 e = hcd_tree_find_ep(&(this_device->config_tree), urb->endpoint); 986 987 if (NULL == e) { 988 USB_MSG("Invalid EP number for this device"); 989 return EXIT_FAILURE; 990 } 991 992 /* Check if remembered descriptor direction, matches the one in URB */ 993 if (((e->descriptor.bEndpointAddress >> 7) & 0x01) != urb->direction) { 994 USB_MSG("EP direction mismatch"); 995 return EXIT_FAILURE; 996 } 997 998 /* Check if remembered type matches */ 999 if (UE_GET_XFERTYPE(e->descriptor.bmAttributes) != urb->type) { 1000 USB_MSG("EP type mismatch"); 1001 return EXIT_FAILURE; 1002 } 1003 1004 /* Check if remembered interval matches */ 1005 if ((hcd_reg1)e->descriptor.bInterval != urb->interval) { 1006 USB_MSG("EP interval mismatch"); 1007 return EXIT_FAILURE; 1008 } 1009 1010 /* Assign URB values to data request structure */ 1011 request.type = urb->type; 1012 request.endpoint = urb->endpoint; 1013 request.direction = urb->direction; 1014 request.data_left = (int)urb->in_size; 1015 request.data = urb->inout_data; 1016 /* TODO: This was changed to allow software scheduler to work correctly 1017 * by switching URBs when they NAK, rather than waiting forever if URB 1018 * which requires such waiting, was issued */ 1019 #if 0 1020 request.interval = urb->interval; 1021 #else 1022 request.interval = HCD_DEFAULT_NAKLIMIT; 1023 #endif 1024 1025 /* Assign to let know how much data can be transfered at a time */ 1026 request.max_packet_size = UGETW(e->descriptor.wMaxPacketSize); 1027 1028 /* Let know how to configure EP for speed */ 1029 request.speed = this_device->speed; 1030 1031 /* Start sending data */ 1032 if (EXIT_SUCCESS != hcd_data_transfer(this_device, &request)) { 1033 USB_MSG("URB non-control transfer, failed"); 1034 urb->inout_status = EPIPE; 1035 return EXIT_FAILURE; 1036 } 1037 1038 /* Transfer successfully completed update URB */ 1039 USB_ASSERT(request.data_left >= 0, 1040 "Negative amount of transfer data remains"); 1041 urb->out_size = urb->in_size - (hcd_reg4)request.data_left; 1042 urb->inout_status = EXIT_SUCCESS; 1043 1044 return EXIT_SUCCESS; 1045 } 1046 1047 1048 /*===========================================================================* 1049 * hcd_setup_packet * 1050 *===========================================================================*/ 1051 static int 1052 hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup, 1053 hcd_reg1 ep) 1054 { 1055 hcd_driver_state * d; 1056 hcd_reg1 * current_byte; 1057 int rx_len; 1058 1059 DEBUG_DUMP; 1060 1061 /* Should have been set at enumeration or with default values */ 1062 USB_ASSERT(this_device->max_packet_size >= HCD_LS_MAXPACKETSIZE, 1063 "Illegal MaxPacketSize"); 1064 USB_ASSERT(ep <= HCD_LAST_EP, "Invalid EP number"); 1065 USB_ASSERT(this_device->current_address <= HCD_LAST_ADDR, 1066 "Invalid device address"); 1067 1068 /* Initially... */ 1069 d = this_device->driver; 1070 current_byte = this_device->control_data;/* Start reading into this */ 1071 this_device->control_len = 0; /* Nothing read yet */ 1072 1073 /* Set parameters for further communication */ 1074 d->setup_device(d->private_data, ep, this_device->current_address, 1075 NULL, NULL); 1076 1077 /* Send setup packet */ 1078 d->setup_stage(d->private_data, setup); 1079 1080 /* Wait for response */ 1081 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, ep); 1082 1083 /* Check response */ 1084 if (EXIT_SUCCESS != d->check_error(d->private_data, 1085 HCD_TRANSFER_CONTROL, 1086 ep, 1087 HCD_DIRECTION_UNUSED)) 1088 return EXIT_FAILURE; 1089 1090 /* For data packets... */ 1091 if (setup->wLength > 0) { 1092 1093 /* TODO: magic number */ 1094 /* ...IN data packets */ 1095 if (setup->bRequestType & 0x80) { 1096 1097 for(;;) { 1098 1099 /* Try getting data */ 1100 d->in_data_stage(d->private_data); 1101 1102 /* Wait for response */ 1103 hcd_device_wait(this_device, 1104 HCD_EVENT_ENDPOINT, ep); 1105 1106 /* Check response */ 1107 if (EXIT_SUCCESS != d->check_error( 1108 d->private_data, 1109 HCD_TRANSFER_CONTROL, 1110 ep, 1111 HCD_DIRECTION_UNUSED)) 1112 return EXIT_FAILURE; 1113 1114 /* Read data received as response */ 1115 rx_len = d->read_data(d->private_data, 1116 current_byte, ep); 1117 1118 /* Increment */ 1119 current_byte += rx_len; 1120 this_device->control_len += rx_len; 1121 1122 /* If max sized packet was read (or more)... */ 1123 if (rx_len >= (int)this_device->max_packet_size) 1124 /* ...try reading next packet even if 1125 * zero bytes may be received */ 1126 continue; 1127 1128 /* If less than max data was read... */ 1129 if (rx_len < (int)this_device->max_packet_size) 1130 /* ...it must have been 1131 * the last packet */ 1132 break; 1133 1134 /* Unreachable during normal operation */ 1135 USB_MSG("rx_len: %d; max_packet_size: %d", 1136 rx_len, this_device->max_packet_size); 1137 USB_ASSERT(0, "Illegal state of data " 1138 "receive operation"); 1139 } 1140 1141 } else { 1142 /* TODO: Unimplemented OUT DATA stage */ 1143 d->out_data_stage(d->private_data); 1144 1145 return EXIT_FAILURE; 1146 } 1147 } 1148 1149 /* Status stages */ 1150 if (setup->bRequestType & 0x80) { 1151 1152 /* Try confirming data receive */ 1153 d->out_status_stage(d->private_data); 1154 1155 /* Wait for response */ 1156 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, ep); 1157 1158 /* Check response */ 1159 if (EXIT_SUCCESS != d->check_error(d->private_data, 1160 HCD_TRANSFER_CONTROL, 1161 ep, 1162 HCD_DIRECTION_UNUSED)) 1163 return EXIT_FAILURE; 1164 1165 } else { 1166 1167 /* Try getting status confirmation */ 1168 d->in_status_stage(d->private_data); 1169 1170 /* Wait for response */ 1171 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, ep); 1172 1173 /* Check response */ 1174 if (EXIT_SUCCESS != d->check_error(d->private_data, 1175 HCD_TRANSFER_CONTROL, 1176 ep, 1177 HCD_DIRECTION_UNUSED)) 1178 return EXIT_FAILURE; 1179 1180 /* Read zero data from response to clear registers */ 1181 if (0 != d->read_data(d->private_data, NULL, ep)) 1182 return EXIT_FAILURE; 1183 } 1184 1185 return EXIT_SUCCESS; 1186 } 1187 1188 1189 /*===========================================================================* 1190 * hcd_finish_setup * 1191 *===========================================================================*/ 1192 static int 1193 hcd_finish_setup(hcd_device_state * this_device, void * output) 1194 { 1195 DEBUG_DUMP; 1196 1197 /* Validate setup transfer output length */ 1198 if (this_device->control_len < 0) { 1199 USB_MSG("Negative control transfer output length"); 1200 return EXIT_FAILURE; 1201 } 1202 1203 /* Length is valid but output not supplied */ 1204 if (NULL == output) 1205 return EXIT_SUCCESS; 1206 1207 /* Finally, copy when needed */ 1208 memcpy(output, this_device->control_data, this_device->control_len); 1209 1210 return EXIT_SUCCESS; 1211 } 1212 1213 1214 /*===========================================================================* 1215 * hcd_data_transfer * 1216 *===========================================================================*/ 1217 static int 1218 hcd_data_transfer(hcd_device_state * this_device, hcd_datarequest * request) 1219 { 1220 hcd_driver_state * d; 1221 hcd_datarequest temp_req; 1222 int transfer_len; 1223 1224 DEBUG_DUMP; 1225 1226 USB_ASSERT((request->endpoint <= HCD_LAST_EP) && 1227 (request->endpoint > HCD_DEFAULT_EP), 1228 "Invalid EP number"); 1229 USB_ASSERT((this_device->current_address <= HCD_LAST_ADDR) && 1230 (this_device->current_address > HCD_DEFAULT_ADDR), 1231 "Invalid device address"); 1232 1233 /* Initially... */ 1234 d = this_device->driver; 1235 1236 /* Set parameters for further communication */ 1237 d->setup_device(d->private_data, request->endpoint, 1238 this_device->current_address, 1239 &(this_device->ep_tx_tog[request->endpoint]), 1240 &(this_device->ep_rx_tog[request->endpoint])); 1241 1242 /* Check transfer direction first */ 1243 if (HCD_DIRECTION_IN == request->direction) { 1244 1245 do { 1246 /* Start actual data transfer */ 1247 d->rx_stage(d->private_data, request); 1248 1249 /* Wait for response */ 1250 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, 1251 request->endpoint); 1252 1253 /* Check response */ 1254 if (EXIT_SUCCESS != d->check_error(d->private_data, 1255 request->type, 1256 request->endpoint, 1257 HCD_DIRECTION_IN)) 1258 return EXIT_FAILURE; 1259 1260 /* Read data received as response */ 1261 transfer_len = d->read_data(d->private_data, 1262 request->data, 1263 request->endpoint); 1264 1265 request->data_left -= transfer_len; 1266 request->data += transfer_len; 1267 1268 /* Total length shall not become negative */ 1269 if (request->data_left < 0) { 1270 USB_MSG("Invalid amount of data received"); 1271 return EXIT_FAILURE; 1272 } 1273 1274 } while (0 != request->data_left); 1275 1276 } else if (HCD_DIRECTION_OUT == request->direction) { 1277 1278 do { 1279 temp_req = *request; 1280 1281 /* Decide temporary transfer size */ 1282 if (temp_req.data_left > (int)temp_req.max_packet_size) 1283 temp_req.data_left = 1284 (int)temp_req.max_packet_size; 1285 1286 /* Alter actual transfer size */ 1287 request->data += temp_req.data_left; 1288 request->data_left -= temp_req.data_left; 1289 1290 /* Total length shall not become negative */ 1291 USB_ASSERT(request->data_left >= 0, 1292 "Invalid amount of transfer data calculated"); 1293 1294 /* Start actual data transfer */ 1295 d->tx_stage(d->private_data, &temp_req); 1296 1297 /* Wait for response */ 1298 hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, 1299 request->endpoint); 1300 1301 /* Check response */ 1302 if (EXIT_SUCCESS != d->check_error(d->private_data, 1303 request->type, 1304 request->endpoint, 1305 HCD_DIRECTION_OUT)) 1306 return EXIT_FAILURE; 1307 1308 } while (0 != request->data_left); 1309 1310 } else 1311 USB_ASSERT(0, "Invalid transfer direction"); 1312 1313 return EXIT_SUCCESS; 1314 } 1315