1 /* 2 * Copyright 2003-2014, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 * Niels S. Reedijk 8 */ 9 10 11 #include "usb_private.h" 12 13 #include <StackOrHeapArray.h> 14 15 16 Device::Device(Object* parent, int8 hubAddress, uint8 hubPort, 17 usb_device_descriptor& desc, int8 deviceAddress, usb_speed speed, 18 bool isRootHub, void* controllerCookie) 19 : 20 Object(parent), 21 fDeviceDescriptor(desc), 22 fInitOK(false), 23 fAvailable(true), 24 fIsRootHub(isRootHub), 25 fConfigurations(NULL), 26 fCurrentConfiguration(NULL), 27 fSpeed(speed), 28 fDeviceAddress(deviceAddress), 29 fHubAddress(hubAddress), 30 fHubPort(hubPort), 31 fControllerCookie(controllerCookie), 32 fNode(NULL) 33 { 34 TRACE("creating device\n"); 35 36 fDefaultPipe = new(std::nothrow) ControlPipe(this); 37 if (fDefaultPipe == NULL) { 38 TRACE_ERROR("could not allocate default pipe\n"); 39 return; 40 } 41 42 fDefaultPipe->InitCommon(fDeviceAddress, 0, fSpeed, Pipe::Default, 43 fDeviceDescriptor.max_packet_size_0, 0, fHubAddress, fHubPort); 44 45 // Get the device descriptor 46 // We already have a part of it, but we want it all 47 size_t actualLength; 48 status_t status = GetDescriptor(USB_DESCRIPTOR_DEVICE, 0, 0, 49 (void*)&fDeviceDescriptor, sizeof(fDeviceDescriptor), &actualLength); 50 51 if (status < B_OK || actualLength != sizeof(fDeviceDescriptor)) { 52 TRACE_ERROR("error while getting the device descriptor\n"); 53 return; 54 } 55 56 TRACE("full device descriptor for device %d:\n", fDeviceAddress); 57 TRACE("\tlength:..............%d\n", fDeviceDescriptor.length); 58 TRACE("\tdescriptor_type:.....0x%04x\n", fDeviceDescriptor.descriptor_type); 59 TRACE("\tusb_version:.........0x%04x\n", fDeviceDescriptor.usb_version); 60 TRACE("\tdevice_class:........0x%02x\n", fDeviceDescriptor.device_class); 61 TRACE("\tdevice_subclass:.....0x%02x\n", fDeviceDescriptor.device_subclass); 62 TRACE("\tdevice_protocol:.....0x%02x\n", fDeviceDescriptor.device_protocol); 63 TRACE("\tmax_packet_size_0:...%d\n", fDeviceDescriptor.max_packet_size_0); 64 TRACE("\tvendor_id:...........0x%04x\n", fDeviceDescriptor.vendor_id); 65 TRACE("\tproduct_id:..........0x%04x\n", fDeviceDescriptor.product_id); 66 TRACE("\tdevice_version:......0x%04x\n", fDeviceDescriptor.device_version); 67 TRACE("\tmanufacturer:........0x%02x\n", fDeviceDescriptor.manufacturer); 68 TRACE("\tproduct:.............0x%02x\n", fDeviceDescriptor.product); 69 TRACE("\tserial_number:.......0x%02x\n", fDeviceDescriptor.serial_number); 70 TRACE("\tnum_configurations:..%d\n", fDeviceDescriptor.num_configurations); 71 72 // Get the configurations 73 fConfigurations = (usb_configuration_info*)malloc( 74 fDeviceDescriptor.num_configurations * sizeof(usb_configuration_info)); 75 if (fConfigurations == NULL) { 76 TRACE_ERROR("out of memory during config creations!\n"); 77 return; 78 } 79 80 memset(fConfigurations, 0, fDeviceDescriptor.num_configurations 81 * sizeof(usb_configuration_info)); 82 for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 83 usb_configuration_descriptor configDescriptor; 84 status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0, 85 (void*)&configDescriptor, sizeof(usb_configuration_descriptor), 86 &actualLength); 87 88 if (status < B_OK 89 || actualLength != sizeof(usb_configuration_descriptor)) { 90 TRACE_ERROR("error fetching configuration %" B_PRId32 "\n", i); 91 return; 92 } 93 94 TRACE("configuration %" B_PRId32 "\n", i); 95 TRACE("\tlength:..............%d\n", configDescriptor.length); 96 TRACE("\tdescriptor_type:.....0x%02x\n", 97 configDescriptor.descriptor_type); 98 TRACE("\ttotal_length:........%d\n", configDescriptor.total_length); 99 TRACE("\tnumber_interfaces:...%d\n", 100 configDescriptor.number_interfaces); 101 TRACE("\tconfiguration_value:.0x%02x\n", 102 configDescriptor.configuration_value); 103 TRACE("\tconfiguration:.......0x%02x\n", 104 configDescriptor.configuration); 105 TRACE("\tattributes:..........0x%02x\n", configDescriptor.attributes); 106 TRACE("\tmax_power:...........%d\n", configDescriptor.max_power); 107 108 uint8* configData = (uint8*)malloc(configDescriptor.total_length); 109 if (configData == NULL) { 110 TRACE_ERROR("out of memory when reading config\n"); 111 return; 112 } 113 114 status = GetDescriptor(USB_DESCRIPTOR_CONFIGURATION, i, 0, 115 (void*)configData, configDescriptor.total_length, &actualLength); 116 117 if (status < B_OK || actualLength != configDescriptor.total_length) { 118 TRACE_ERROR("error fetching full configuration" 119 " descriptor %" B_PRId32 " got %" B_PRIuSIZE " expected %" 120 B_PRIu16 "\n", i, actualLength, configDescriptor.total_length); 121 free(configData); 122 return; 123 } 124 125 usb_configuration_descriptor* configuration 126 = (usb_configuration_descriptor*)configData; 127 fConfigurations[i].descr = configuration; 128 fConfigurations[i].interface_count = configuration->number_interfaces; 129 fConfigurations[i].interface = (usb_interface_list*)malloc( 130 configuration->number_interfaces * sizeof(usb_interface_list)); 131 if (fConfigurations[i].interface == NULL) { 132 TRACE_ERROR("out of memory when creating interfaces\n"); 133 return; 134 } 135 136 memset(fConfigurations[i].interface, 0, 137 configuration->number_interfaces * sizeof(usb_interface_list)); 138 139 usb_interface_info* currentInterface = NULL; 140 uint32 descriptorStart = sizeof(usb_configuration_descriptor); 141 while (descriptorStart < actualLength) { 142 switch (configData[descriptorStart + 1]) { 143 case USB_DESCRIPTOR_INTERFACE: 144 { 145 TRACE("got interface descriptor\n"); 146 usb_interface_descriptor* interfaceDescriptor 147 = (usb_interface_descriptor*)&configData[ 148 descriptorStart]; 149 TRACE("\tlength:.............%d\n", 150 interfaceDescriptor->length); 151 TRACE("\tdescriptor_type:....0x%02x\n", 152 interfaceDescriptor->descriptor_type); 153 TRACE("\tinterface_number:...%d\n", 154 interfaceDescriptor->interface_number); 155 TRACE("\talternate_setting:..%d\n", 156 interfaceDescriptor->alternate_setting); 157 TRACE("\tnum_endpoints:......%d\n", 158 interfaceDescriptor->num_endpoints); 159 TRACE("\tinterface_class:....0x%02x\n", 160 interfaceDescriptor->interface_class); 161 TRACE("\tinterface_subclass:.0x%02x\n", 162 interfaceDescriptor->interface_subclass); 163 TRACE("\tinterface_protocol:.0x%02x\n", 164 interfaceDescriptor->interface_protocol); 165 TRACE("\tinterface:..........%d\n", 166 interfaceDescriptor->interface); 167 168 if (interfaceDescriptor->interface_number 169 >= fConfigurations[i].interface_count) { 170 interfaceDescriptor->interface_number 171 = fConfigurations[i].interface_count - 1; 172 TRACE_ERROR("Corrected invalid interface_number!\n"); 173 } 174 175 usb_interface_list* interfaceList = &fConfigurations[i] 176 .interface[interfaceDescriptor->interface_number]; 177 178 // Allocate this alternate 179 interfaceList->alt_count++; 180 usb_interface_info* newAlternates 181 = (usb_interface_info*)realloc(interfaceList->alt, 182 interfaceList->alt_count * sizeof(usb_interface_info)); 183 if (newAlternates == NULL) { 184 TRACE_ERROR("out of memory allocating" 185 " alternate interface\n"); 186 interfaceList->alt_count--; 187 return; 188 } 189 190 interfaceList->alt = newAlternates; 191 192 // Set active interface always to the first one 193 interfaceList->active = interfaceList->alt; 194 195 // Setup this alternate 196 usb_interface_info* interfaceInfo 197 = &interfaceList->alt[interfaceList->alt_count - 1]; 198 interfaceInfo->descr = interfaceDescriptor; 199 interfaceInfo->endpoint_count = 0; 200 interfaceInfo->endpoint = NULL; 201 interfaceInfo->generic_count = 0; 202 interfaceInfo->generic = NULL; 203 204 Interface* interface = new(std::nothrow) Interface(this, 205 interfaceDescriptor->interface_number); 206 if (interface == NULL) { 207 TRACE_ERROR("failed to allocate" 208 " interface object\n"); 209 return; 210 } 211 212 interfaceInfo->handle = interface->USBID(); 213 currentInterface = interfaceInfo; 214 break; 215 } 216 217 case USB_DESCRIPTOR_ENDPOINT: 218 { 219 TRACE("got endpoint descriptor\n"); 220 usb_endpoint_descriptor* endpointDescriptor 221 = (usb_endpoint_descriptor*)&configData[descriptorStart]; 222 TRACE("\tlength:.............%d\n", 223 endpointDescriptor->length); 224 TRACE("\tdescriptor_type:....0x%02x\n", 225 endpointDescriptor->descriptor_type); 226 TRACE("\tendpoint_address:...0x%02x\n", 227 endpointDescriptor->endpoint_address); 228 TRACE("\tattributes:.........0x%02x\n", 229 endpointDescriptor->attributes); 230 TRACE("\tmax_packet_size:....%d\n", 231 endpointDescriptor->max_packet_size); 232 TRACE("\tinterval:...........%d\n", 233 endpointDescriptor->interval); 234 235 if (currentInterface == NULL) 236 break; 237 238 // Allocate this endpoint 239 currentInterface->endpoint_count++; 240 usb_endpoint_info* newEndpoints = (usb_endpoint_info*) 241 realloc(currentInterface->endpoint, 242 currentInterface->endpoint_count 243 * sizeof(usb_endpoint_info)); 244 if (newEndpoints == NULL) { 245 TRACE_ERROR("out of memory allocating new endpoint\n"); 246 currentInterface->endpoint_count--; 247 return; 248 } 249 250 currentInterface->endpoint = newEndpoints; 251 252 // Setup this endpoint 253 usb_endpoint_info* endpointInfo = ¤tInterface 254 ->endpoint[currentInterface->endpoint_count - 1]; 255 endpointInfo->descr = endpointDescriptor; 256 endpointInfo->handle = 0; 257 break; 258 } 259 260 case USB_DESCRIPTOR_ENDPOINT_SS_COMPANION: { 261 if (currentInterface != NULL) { 262 usb_endpoint_descriptor* desc 263 = currentInterface->endpoint[ 264 currentInterface->endpoint_count - 1].descr; 265 if ((uint8*)desc != (&configData[descriptorStart 266 - desc->length])) { 267 TRACE_ERROR("found endpoint companion descriptor " 268 "not immediately following endpoint " 269 "descriptor, ignoring!\n"); 270 break; 271 } 272 // TODO: It'd be nicer if we could store the endpoint 273 // companion descriptor along with the endpoint 274 // descriptor, but as the interface struct is public 275 // API, that would be an ABI break. 276 } 277 278 // fall through 279 } 280 281 default: 282 TRACE("got generic descriptor\n"); 283 usb_generic_descriptor* genericDescriptor 284 = (usb_generic_descriptor*)&configData[descriptorStart]; 285 TRACE("\tlength:.............%d\n", 286 genericDescriptor->length); 287 TRACE("\tdescriptor_type:....0x%02x\n", 288 genericDescriptor->descriptor_type); 289 290 if (currentInterface == NULL) 291 break; 292 293 // Allocate this descriptor 294 currentInterface->generic_count++; 295 usb_descriptor** newGenerics = (usb_descriptor**)realloc( 296 currentInterface->generic, 297 currentInterface->generic_count 298 * sizeof(usb_descriptor*)); 299 if (newGenerics == NULL) { 300 TRACE_ERROR("out of memory allocating" 301 " generic descriptor\n"); 302 currentInterface->generic_count--; 303 return; 304 } 305 306 currentInterface->generic = newGenerics; 307 308 // Add this descriptor 309 currentInterface->generic[ 310 currentInterface->generic_count - 1] 311 = (usb_descriptor*)genericDescriptor; 312 break; 313 } 314 315 descriptorStart += configData[descriptorStart]; 316 } 317 } 318 319 // Set default configuration 320 TRACE("setting default configuration\n"); 321 if (SetConfigurationAt(0) != B_OK) { 322 TRACE_ERROR("failed to set default configuration\n"); 323 return; 324 } 325 326 fInitOK = true; 327 } 328 329 330 Device::~Device() 331 { 332 if (fNode != NULL) { 333 status_t error = gDeviceManager->unregister_node(fNode); 334 if (error != B_OK && error != B_BUSY) 335 TRACE_ERROR("failed to unregister device node\n"); 336 fNode = NULL; 337 } 338 339 // Destroy open endpoints. Do not send a device request to unconfigure 340 // though, since we may be deleted because the device was unplugged already. 341 Unconfigure(false); 342 343 // Destroy all Interfaces in the Configurations hierarchy. 344 for (int32 i = 0; fConfigurations != NULL 345 && i < fDeviceDescriptor.num_configurations; i++) { 346 usb_configuration_info* configuration = &fConfigurations[i]; 347 if (configuration == NULL || configuration->interface == NULL) 348 continue; 349 350 for (size_t j = 0; j < configuration->interface_count; j++) { 351 usb_interface_list* interfaceList = &configuration->interface[j]; 352 if (interfaceList->alt == NULL) 353 continue; 354 355 for (size_t k = 0; k < interfaceList->alt_count; k++) { 356 usb_interface_info* interface = &interfaceList->alt[k]; 357 Interface* interfaceObject = 358 (Interface*)GetStack()->GetObject(interface->handle); 359 interface->handle = 0; 360 if (interfaceObject != NULL) 361 interfaceObject->ReleaseReference(); 362 delete interfaceObject; 363 } 364 } 365 } 366 367 if (fDefaultPipe != NULL) { 368 fDefaultPipe->PutUSBID(false); 369 370 // Also put our ID to prevent further transfers on the default pipe 371 // from being queued. (We have to do this after putting the pipe's ID, 372 // since we are its parent.) 373 PutUSBID(false); 374 375 fDefaultPipe->CancelQueuedTransfers(true); 376 fDefaultPipe->WaitForIdle(); 377 } 378 379 // Ensure we are gone from the stack before deleting public structures. 380 PutUSBID(true); 381 delete fDefaultPipe; 382 383 if (fConfigurations == NULL) { 384 // we didn't get far in device setup, so everything below is unneeded 385 return; 386 } 387 388 // Free the Configurations hierarchy. 389 for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 390 usb_configuration_info* configuration = &fConfigurations[i]; 391 if (configuration == NULL) 392 continue; 393 394 free(configuration->descr); 395 if (configuration->interface == NULL) 396 continue; 397 398 for (size_t j = 0; j < configuration->interface_count; j++) { 399 usb_interface_list* interfaceList = &configuration->interface[j]; 400 if (interfaceList->alt == NULL) 401 continue; 402 403 for (size_t k = 0; k < interfaceList->alt_count; k++) { 404 usb_interface_info* interface = &interfaceList->alt[k]; 405 free(interface->endpoint); 406 free(interface->generic); 407 } 408 409 free(interfaceList->alt); 410 } 411 412 free(configuration->interface); 413 } 414 415 free(fConfigurations); 416 } 417 418 419 status_t 420 Device::InitCheck() 421 { 422 if (fInitOK) 423 return B_OK; 424 425 return B_ERROR; 426 } 427 428 429 status_t 430 Device::Changed(change_item** changeList, bool added) 431 { 432 fAvailable = added; 433 change_item* changeItem = new(std::nothrow) change_item; 434 if (changeItem == NULL) 435 return B_NO_MEMORY; 436 437 changeItem->added = added; 438 changeItem->device = this; 439 changeItem->link = *changeList; 440 *changeList = changeItem; 441 return B_OK; 442 } 443 444 445 status_t 446 Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, 447 void* data, size_t dataLength, size_t* actualLength) 448 { 449 if (!fAvailable) 450 return B_ERROR; 451 452 return fDefaultPipe->SendRequest( 453 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, 454 USB_REQUEST_GET_DESCRIPTOR, (descriptorType << 8) | index, 455 languageID, dataLength, data, dataLength, actualLength); 456 } 457 458 459 const usb_configuration_info* 460 Device::Configuration() const 461 { 462 return fCurrentConfiguration; 463 } 464 465 466 const usb_configuration_info* 467 Device::ConfigurationAt(uint8 index) const 468 { 469 if (index >= fDeviceDescriptor.num_configurations) 470 return NULL; 471 472 return &fConfigurations[index]; 473 } 474 475 476 status_t 477 Device::SetConfiguration(const usb_configuration_info* configuration) 478 { 479 if (!configuration) 480 return Unconfigure(true); 481 482 for (uint8 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 483 if (configuration->descr->configuration_value 484 == fConfigurations[i].descr->configuration_value) 485 return SetConfigurationAt(i); 486 } 487 488 return B_BAD_VALUE; 489 } 490 491 492 status_t 493 Device::SetConfigurationAt(uint8 index) 494 { 495 if (!fAvailable) 496 return B_ERROR; 497 if (index >= fDeviceDescriptor.num_configurations) 498 return B_BAD_VALUE; 499 if (&fConfigurations[index] == fCurrentConfiguration) 500 return B_OK; 501 502 // Destroy our open endpoints 503 Unconfigure(false); 504 505 // Tell the device to set the configuration 506 status_t result = fDefaultPipe->SendRequest( 507 USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, 508 USB_REQUEST_SET_CONFIGURATION, 509 fConfigurations[index].descr->configuration_value, 0, 0, NULL, 0, NULL); 510 if (result < B_OK) 511 return result; 512 513 // Set current configuration 514 fCurrentConfiguration = &fConfigurations[index]; 515 516 // Initialize all the endpoints that are now active 517 InitEndpoints(-1); 518 519 // Wait some for the configuration being finished 520 if (!fIsRootHub) 521 snooze(USB_DELAY_SET_CONFIGURATION); 522 return B_OK; 523 } 524 525 526 void 527 Device::InitEndpoints(int32 interfaceIndex) 528 { 529 for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) { 530 if (interfaceIndex >= 0 && j != (size_t)interfaceIndex) 531 continue; 532 533 usb_interface_info* interfaceInfo 534 = fCurrentConfiguration->interface[j].active; 535 if (interfaceInfo == NULL) 536 continue; 537 538 for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { 539 usb_endpoint_info* endpoint = &interfaceInfo->endpoint[i]; 540 Pipe* pipe = NULL; 541 542 usb_endpoint_ss_companion_descriptor* comp_descr = NULL; 543 if (fSpeed >= USB_SPEED_SUPERSPEED) { 544 // We should have a companion descriptor for this device. 545 // Let's find it: it'll be the "i"th one. 546 size_t k = 0; 547 for (size_t j = 0; j < interfaceInfo->generic_count; j++) { 548 usb_descriptor* desc = interfaceInfo->generic[j]; 549 if (desc->endpoint.descriptor_type 550 != USB_DESCRIPTOR_ENDPOINT_SS_COMPANION) { 551 continue; 552 } 553 if (k == i) { 554 comp_descr = 555 (usb_endpoint_ss_companion_descriptor*)desc; 556 break; 557 } 558 k++; 559 } 560 if (comp_descr == NULL) { 561 TRACE_ERROR("SuperSpeed device without an endpoint companion " 562 "descriptor!"); 563 } 564 } 565 566 Pipe::pipeDirection direction = Pipe::Out; 567 if ((endpoint->descr->endpoint_address & 0x80) != 0) 568 direction = Pipe::In; 569 570 switch (endpoint->descr->attributes & 0x03) { 571 case USB_ENDPOINT_ATTR_CONTROL: // Control Endpoint 572 pipe = new(std::nothrow) ControlPipe(this); 573 direction = Pipe::Default; 574 break; 575 576 case USB_ENDPOINT_ATTR_ISOCHRONOUS: // Isochronous Endpoint 577 pipe = new(std::nothrow) IsochronousPipe(this); 578 break; 579 580 case USB_ENDPOINT_ATTR_BULK: // Bulk Endpoint 581 pipe = new(std::nothrow) BulkPipe(this); 582 break; 583 584 case USB_ENDPOINT_ATTR_INTERRUPT: // Interrupt Endpoint 585 pipe = new(std::nothrow) InterruptPipe(this); 586 break; 587 } 588 589 if (pipe == NULL) { 590 TRACE_ERROR("failed to allocate pipe\n"); 591 endpoint->handle = 0; 592 continue; 593 } 594 595 pipe->InitCommon(fDeviceAddress, 596 endpoint->descr->endpoint_address & 0x0f, 597 fSpeed, direction, endpoint->descr->max_packet_size, 598 endpoint->descr->interval, fHubAddress, fHubPort); 599 if (comp_descr != NULL) { 600 pipe->InitSuperSpeed(comp_descr->max_burst, 601 comp_descr->bytes_per_interval); 602 } 603 endpoint->handle = pipe->USBID(); 604 } 605 } 606 } 607 608 609 status_t 610 Device::Unconfigure(bool atDeviceLevel) 611 { 612 // If we only want to destroy our open pipes before setting 613 // another configuration unconfigure will be called with 614 // atDevice = false. otherwise we explicitly want to unconfigure 615 // the device and have to send it the corresponding request. 616 if (atDeviceLevel && fAvailable) { 617 status_t result = fDefaultPipe->SendRequest( 618 USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, 619 USB_REQUEST_SET_CONFIGURATION, 0, 0, 0, NULL, 0, NULL); 620 if (result < B_OK) 621 return result; 622 623 snooze(USB_DELAY_SET_CONFIGURATION); 624 } 625 626 if (!fCurrentConfiguration) 627 return B_OK; 628 629 ClearEndpoints(-1); 630 fCurrentConfiguration = NULL; 631 return B_OK; 632 } 633 634 635 void 636 Device::ClearEndpoints(int32 interfaceIndex) 637 { 638 if (fCurrentConfiguration == NULL 639 || fCurrentConfiguration->interface == NULL) 640 return; 641 642 for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) { 643 if (interfaceIndex >= 0 && j != (size_t)interfaceIndex) 644 continue; 645 646 usb_interface_info* interfaceInfo 647 = fCurrentConfiguration->interface[j].active; 648 if (interfaceInfo == NULL || interfaceInfo->endpoint == NULL) 649 continue; 650 651 for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { 652 usb_endpoint_info* endpoint = &interfaceInfo->endpoint[i]; 653 Pipe* pipe = (Pipe*)GetStack()->GetObject(endpoint->handle); 654 if (pipe != NULL) 655 pipe->ReleaseReference(); 656 delete pipe; 657 endpoint->handle = 0; 658 } 659 } 660 } 661 662 663 status_t 664 Device::SetAltInterface(const usb_interface_info* interface) 665 { 666 uint8 interfaceNumber = interface->descr->interface_number; 667 // Tell the device to set the alternate settings 668 status_t result = fDefaultPipe->SendRequest( 669 USB_REQTYPE_INTERFACE_OUT | USB_REQTYPE_STANDARD, 670 USB_REQUEST_SET_INTERFACE, 671 interface->descr->alternate_setting, interfaceNumber, 0, NULL, 0, NULL); 672 if (result < B_OK) 673 return result; 674 675 // Clear the no longer active endpoints 676 ClearEndpoints(interfaceNumber); 677 678 // Update the active pointer of the interface list 679 usb_interface_list* interfaceList 680 = &fCurrentConfiguration->interface[interfaceNumber]; 681 interfaceList->active 682 = &interfaceList->alt[interface->descr->alternate_setting]; 683 684 // Initialize the new endpoints 685 InitEndpoints(interfaceNumber); 686 return result; 687 } 688 689 690 const usb_device_descriptor* 691 Device::DeviceDescriptor() const 692 { 693 return &fDeviceDescriptor; 694 } 695 696 697 status_t 698 Device::ReportDevice(usb_support_descriptor* supportDescriptors, 699 uint32 supportDescriptorCount, const usb_notify_hooks* hooks, 700 usb_driver_cookie** cookies, bool added, bool recursive) 701 { 702 TRACE("reporting device\n"); 703 bool supported = false; 704 if (supportDescriptorCount == 0 || supportDescriptors == NULL) 705 supported = true; 706 707 for (uint32 i = 0; !supported && i < supportDescriptorCount; i++) { 708 if ((supportDescriptors[i].vendor != 0 709 && fDeviceDescriptor.vendor_id != supportDescriptors[i].vendor) 710 || (supportDescriptors[i].product != 0 711 && fDeviceDescriptor.product_id 712 != supportDescriptors[i].product)) 713 continue; 714 715 if ((supportDescriptors[i].dev_class == 0 716 || fDeviceDescriptor.device_class 717 == supportDescriptors[i].dev_class) 718 && (supportDescriptors[i].dev_subclass == 0 719 || fDeviceDescriptor.device_subclass 720 == supportDescriptors[i].dev_subclass) 721 && (supportDescriptors[i].dev_protocol == 0 722 || fDeviceDescriptor.device_protocol 723 == supportDescriptors[i].dev_protocol)) { 724 supported = true; 725 } 726 727 // we have to check all interfaces for matching class/subclass/protocol 728 for (uint32 j = 0; 729 !supported && j < fDeviceDescriptor.num_configurations; j++) { 730 for (uint32 k = 0; 731 !supported && k < fConfigurations[j].interface_count; k++) { 732 for (uint32 l = 0; !supported 733 && l < fConfigurations[j].interface[k].alt_count; l++) { 734 usb_interface_descriptor* descriptor 735 = fConfigurations[j].interface[k].alt[l].descr; 736 if ((supportDescriptors[i].dev_class == 0 737 || descriptor->interface_class 738 == supportDescriptors[i].dev_class) 739 && (supportDescriptors[i].dev_subclass == 0 740 || descriptor->interface_subclass 741 == supportDescriptors[i].dev_subclass) 742 && (supportDescriptors[i].dev_protocol == 0 743 || descriptor->interface_protocol 744 == supportDescriptors[i].dev_protocol)) { 745 supported = true; 746 } 747 } 748 } 749 } 750 } 751 752 if (!supported) 753 return B_UNSUPPORTED; 754 755 if ((added && hooks->device_added == NULL) 756 || (!added && hooks->device_removed == NULL)) { 757 // hooks are not installed, but report success to indicate that 758 // the driver supports the device 759 return B_OK; 760 } 761 762 usb_id id = USBID(); 763 if (added) { 764 usb_driver_cookie* cookie = new(std::nothrow) usb_driver_cookie; 765 if (hooks->device_added(id, &cookie->cookie) >= B_OK) { 766 cookie->device = id; 767 cookie->link = *cookies; 768 *cookies = cookie; 769 } else 770 delete cookie; 771 } else { 772 usb_driver_cookie** pointer = cookies; 773 usb_driver_cookie* cookie = *cookies; 774 while (cookie != NULL) { 775 if (cookie->device == id) 776 break; 777 pointer = &cookie->link; 778 cookie = cookie->link; 779 } 780 781 if (cookie == NULL) { 782 // the device is supported, but there is no cookie. this most 783 // probably means that the device_added hook above failed. 784 return B_OK; 785 } 786 787 hooks->device_removed(cookie->cookie); 788 *pointer = cookie->link; 789 delete cookie; 790 } 791 792 return B_OK; 793 } 794 795 796 status_t 797 Device::BuildDeviceName(char* string, uint32* index, size_t bufferSize, 798 Device* device) 799 { 800 if (!Parent() || (Parent()->Type() & USB_OBJECT_HUB) == 0) 801 return B_ERROR; 802 803 ((Hub*)Parent())->BuildDeviceName(string, index, bufferSize, this); 804 return B_OK; 805 } 806 807 808 status_t 809 Device::SetFeature(uint16 selector) 810 { 811 if (!fAvailable) 812 return B_ERROR; 813 814 TRACE("set feature %u\n", selector); 815 return fDefaultPipe->SendRequest( 816 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, 817 USB_REQUEST_SET_FEATURE, selector, 0, 0, NULL, 0, NULL); 818 } 819 820 821 status_t 822 Device::ClearFeature(uint16 selector) 823 { 824 if (!fAvailable) 825 return B_ERROR; 826 827 TRACE("clear feature %u\n", selector); 828 return fDefaultPipe->SendRequest( 829 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, 830 USB_REQUEST_CLEAR_FEATURE, selector, 0, 0, NULL, 0, NULL); 831 } 832 833 834 status_t 835 Device::GetStatus(uint16* status) 836 { 837 if (!fAvailable) 838 return B_ERROR; 839 840 TRACE("get status\n"); 841 return fDefaultPipe->SendRequest( 842 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN, 843 USB_REQUEST_GET_STATUS, 0, 0, 2, (void*)status, 2, NULL); 844 } 845 846 847 device_node* 848 Device::RegisterNode(device_node *parent) 849 { 850 usb_id id = USBID(); 851 if (parent == NULL) 852 parent = ((Device*)Parent())->Node(); 853 854 // determine how many attributes we will need 855 uint32 deviceAttrTotal = 1; 856 for (uint32 j = 0; j < fDeviceDescriptor.num_configurations; j++) { 857 for (uint32 k = 0; k < fConfigurations[j].interface_count; k++) { 858 for (uint32 l = 0; l < fConfigurations[j].interface[k].alt_count; l++) { 859 deviceAttrTotal += 3; 860 } 861 } 862 } 863 864 BStackOrHeapArray<device_attr, 16> attrs(deviceAttrTotal + 4 + 5); 865 attrs[0] = { B_DEVICE_BUS, B_STRING_TYPE, { .string = "usb" } }; 866 867 // location 868 attrs[1] = { USB_DEVICE_ID_ITEM, B_UINT32_TYPE, { .ui32 = id } }; 869 attrs[2] = { B_DEVICE_FLAGS, B_UINT32_TYPE, { .ui32 = B_FIND_MULTIPLE_CHILDREN } }; 870 attrs[3] = { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { .string = "USB device" } }; 871 872 uint32 attrCount = 4; 873 874 if (fDeviceDescriptor.vendor_id != 0) { 875 attrs[attrCount].name = B_DEVICE_VENDOR_ID; 876 attrs[attrCount].type = B_UINT16_TYPE; 877 attrs[attrCount].value.ui16 = fDeviceDescriptor.vendor_id; 878 attrCount++; 879 880 attrs[attrCount].name = B_DEVICE_ID; 881 attrs[attrCount].type = B_UINT16_TYPE; 882 attrs[attrCount].value.ui16 = fDeviceDescriptor.product_id; 883 attrCount++; 884 } 885 886 uint32 attrClassesIndex = attrCount; 887 888 if (fDeviceDescriptor.device_class != 0) { 889 attrs[attrCount].name = USB_DEVICE_CLASS; 890 attrs[attrCount].type = B_UINT8_TYPE; 891 attrs[attrCount].value.ui8 = fDeviceDescriptor.device_class; 892 attrCount++; 893 894 attrs[attrCount].name = USB_DEVICE_SUBCLASS; 895 attrs[attrCount].type = B_UINT8_TYPE; 896 attrs[attrCount].value.ui8 = fDeviceDescriptor.device_subclass; 897 attrCount++; 898 899 attrs[attrCount].name = USB_DEVICE_PROTOCOL; 900 attrs[attrCount].type = B_UINT8_TYPE; 901 attrs[attrCount].value.ui8 = fDeviceDescriptor.device_protocol; 902 attrCount++; 903 } 904 905 for (uint32 j = 0; j < fDeviceDescriptor.num_configurations; j++) { 906 for (uint32 k = 0; k < fConfigurations[j].interface_count; k++) { 907 for (uint32 l = 0; l < fConfigurations[j].interface[k].alt_count; l++) { 908 usb_interface_descriptor* descriptor 909 = fConfigurations[j].interface[k].alt[l].descr; 910 bool found = false; 911 for (uint32 i = attrClassesIndex; i < attrCount;) { 912 if (attrs[i++].value.ui8 != descriptor->interface_class) 913 continue; 914 if (attrs[i++].value.ui8 != descriptor->interface_subclass) 915 continue; 916 if (attrs[i++].value.ui8 != descriptor->interface_protocol) 917 continue; 918 found = true; 919 break; 920 } 921 if (found) 922 continue; 923 924 attrs[attrCount].name = USB_DEVICE_CLASS; 925 attrs[attrCount].type = B_UINT8_TYPE; 926 attrs[attrCount].value.ui8 = descriptor->interface_class; 927 attrCount++; 928 929 attrs[attrCount].name = USB_DEVICE_SUBCLASS; 930 attrs[attrCount].type = B_UINT8_TYPE; 931 attrs[attrCount].value.ui8 = descriptor->interface_subclass; 932 attrCount++; 933 934 attrs[attrCount].name = USB_DEVICE_PROTOCOL; 935 attrs[attrCount].type = B_UINT8_TYPE; 936 attrs[attrCount].value.ui8 = descriptor->interface_protocol; 937 attrCount++; 938 } 939 } 940 } 941 942 attrs[attrCount].name = NULL; 943 attrs[attrCount].type = 0; 944 attrs[attrCount].value.string = NULL; 945 attrCount++; 946 947 device_node* node = NULL; 948 if (gDeviceManager->register_node(parent, USB_DEVICE_MODULE_NAME, attrs, 949 NULL, &node) != B_OK) { 950 TRACE_ERROR("failed to register device node\n"); 951 } else 952 fNode = node; 953 return node; 954 } 955