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 // Cancel transfers on the default pipe and put its USBID to prevent 333 // further transfers from being queued. 334 if (fDefaultPipe != NULL) { 335 fDefaultPipe->PutUSBID(false); 336 fDefaultPipe->CancelQueuedTransfers(true); 337 fDefaultPipe->WaitForUnbusy(); 338 } 339 340 // Destroy open endpoints. Do not send a device request to unconfigure 341 // though, since we may be deleted because the device was unplugged already. 342 Unconfigure(false); 343 344 if (fNode != NULL) { 345 status_t error = gDeviceManager->unregister_node(fNode); 346 if (error != B_OK && error != B_BUSY) 347 TRACE_ERROR("failed to unregister device node\n"); 348 fNode = NULL; 349 } 350 351 // Destroy all Interfaces in the Configurations hierarchy. 352 for (int32 i = 0; fConfigurations != NULL 353 && i < fDeviceDescriptor.num_configurations; i++) { 354 usb_configuration_info* configuration = &fConfigurations[i]; 355 if (configuration == NULL || configuration->interface == NULL) 356 continue; 357 358 for (size_t j = 0; j < configuration->interface_count; j++) { 359 usb_interface_list* interfaceList = &configuration->interface[j]; 360 if (interfaceList->alt == NULL) 361 continue; 362 363 for (size_t k = 0; k < interfaceList->alt_count; k++) { 364 usb_interface_info* interface = &interfaceList->alt[k]; 365 Interface* interfaceObject = 366 (Interface*)GetStack()->GetObject(interface->handle); 367 if (interfaceObject != NULL) 368 interfaceObject->SetBusy(false); 369 delete interfaceObject; 370 interface->handle = 0; 371 } 372 } 373 } 374 375 // Remove ourselves from the stack before deleting public structures. 376 PutUSBID(); 377 delete fDefaultPipe; 378 379 if (fConfigurations == NULL) { 380 // we didn't get far in device setup, so everything below is unneeded 381 return; 382 } 383 384 // Free the Configurations hierarchy. 385 for (int32 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 386 usb_configuration_info* configuration = &fConfigurations[i]; 387 if (configuration == NULL) 388 continue; 389 390 free(configuration->descr); 391 if (configuration->interface == NULL) 392 continue; 393 394 for (size_t j = 0; j < configuration->interface_count; j++) { 395 usb_interface_list* interfaceList = &configuration->interface[j]; 396 if (interfaceList->alt == NULL) 397 continue; 398 399 for (size_t k = 0; k < interfaceList->alt_count; k++) { 400 usb_interface_info* interface = &interfaceList->alt[k]; 401 free(interface->endpoint); 402 free(interface->generic); 403 } 404 405 free(interfaceList->alt); 406 } 407 408 free(configuration->interface); 409 } 410 411 free(fConfigurations); 412 } 413 414 415 status_t 416 Device::InitCheck() 417 { 418 if (fInitOK) 419 return B_OK; 420 421 return B_ERROR; 422 } 423 424 425 status_t 426 Device::Changed(change_item** changeList, bool added) 427 { 428 fAvailable = added; 429 change_item* changeItem = new(std::nothrow) change_item; 430 if (changeItem == NULL) 431 return B_NO_MEMORY; 432 433 changeItem->added = added; 434 changeItem->device = this; 435 changeItem->link = *changeList; 436 *changeList = changeItem; 437 return B_OK; 438 } 439 440 441 status_t 442 Device::GetDescriptor(uint8 descriptorType, uint8 index, uint16 languageID, 443 void* data, size_t dataLength, size_t* actualLength) 444 { 445 if (!fAvailable) 446 return B_ERROR; 447 448 return fDefaultPipe->SendRequest( 449 USB_REQTYPE_DEVICE_IN | USB_REQTYPE_STANDARD, 450 USB_REQUEST_GET_DESCRIPTOR, (descriptorType << 8) | index, 451 languageID, dataLength, data, dataLength, actualLength); 452 } 453 454 455 const usb_configuration_info* 456 Device::Configuration() const 457 { 458 return fCurrentConfiguration; 459 } 460 461 462 const usb_configuration_info* 463 Device::ConfigurationAt(uint8 index) const 464 { 465 if (index >= fDeviceDescriptor.num_configurations) 466 return NULL; 467 468 return &fConfigurations[index]; 469 } 470 471 472 status_t 473 Device::SetConfiguration(const usb_configuration_info* configuration) 474 { 475 if (!configuration) 476 return Unconfigure(true); 477 478 for (uint8 i = 0; i < fDeviceDescriptor.num_configurations; i++) { 479 if (configuration->descr->configuration_value 480 == fConfigurations[i].descr->configuration_value) 481 return SetConfigurationAt(i); 482 } 483 484 return B_BAD_VALUE; 485 } 486 487 488 status_t 489 Device::SetConfigurationAt(uint8 index) 490 { 491 if (!fAvailable) 492 return B_ERROR; 493 if (index >= fDeviceDescriptor.num_configurations) 494 return B_BAD_VALUE; 495 if (&fConfigurations[index] == fCurrentConfiguration) 496 return B_OK; 497 498 // Destroy our open endpoints 499 Unconfigure(false); 500 501 // Tell the device to set the configuration 502 status_t result = fDefaultPipe->SendRequest( 503 USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, 504 USB_REQUEST_SET_CONFIGURATION, 505 fConfigurations[index].descr->configuration_value, 0, 0, NULL, 0, NULL); 506 if (result < B_OK) 507 return result; 508 509 // Set current configuration 510 fCurrentConfiguration = &fConfigurations[index]; 511 512 // Initialize all the endpoints that are now active 513 InitEndpoints(-1); 514 515 // Wait some for the configuration being finished 516 if (!fIsRootHub) 517 snooze(USB_DELAY_SET_CONFIGURATION); 518 return B_OK; 519 } 520 521 522 void 523 Device::InitEndpoints(int32 interfaceIndex) 524 { 525 for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) { 526 if (interfaceIndex >= 0 && j != (size_t)interfaceIndex) 527 continue; 528 529 usb_interface_info* interfaceInfo 530 = fCurrentConfiguration->interface[j].active; 531 if (interfaceInfo == NULL) 532 continue; 533 534 for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { 535 usb_endpoint_info* endpoint = &interfaceInfo->endpoint[i]; 536 Pipe* pipe = NULL; 537 538 usb_endpoint_ss_companion_descriptor* comp_descr = NULL; 539 if (fSpeed == USB_SPEED_SUPERSPEED) { 540 // We should have a companion descriptor for this device. 541 // Let's find it: it'll be the "i"th one. 542 size_t k = 0; 543 for (size_t j = 0; j < interfaceInfo->generic_count; j++) { 544 usb_descriptor* desc = interfaceInfo->generic[j]; 545 if (desc->endpoint.descriptor_type 546 != USB_DESCRIPTOR_ENDPOINT_SS_COMPANION) { 547 continue; 548 } 549 if (k == i) { 550 comp_descr = 551 (usb_endpoint_ss_companion_descriptor*)desc; 552 break; 553 } 554 k++; 555 } 556 if (comp_descr == NULL) { 557 TRACE_ERROR("SuperSpeed device without an endpoint companion " 558 "descriptor!"); 559 } 560 } 561 562 Pipe::pipeDirection direction = Pipe::Out; 563 if ((endpoint->descr->endpoint_address & 0x80) != 0) 564 direction = Pipe::In; 565 566 switch (endpoint->descr->attributes & 0x03) { 567 case USB_ENDPOINT_ATTR_CONTROL: // Control Endpoint 568 pipe = new(std::nothrow) ControlPipe(this); 569 direction = Pipe::Default; 570 break; 571 572 case USB_ENDPOINT_ATTR_ISOCHRONOUS: // Isochronous Endpoint 573 pipe = new(std::nothrow) IsochronousPipe(this); 574 break; 575 576 case USB_ENDPOINT_ATTR_BULK: // Bulk Endpoint 577 pipe = new(std::nothrow) BulkPipe(this); 578 break; 579 580 case USB_ENDPOINT_ATTR_INTERRUPT: // Interrupt Endpoint 581 pipe = new(std::nothrow) InterruptPipe(this); 582 break; 583 } 584 585 if (pipe == NULL) { 586 TRACE_ERROR("failed to allocate pipe\n"); 587 endpoint->handle = 0; 588 continue; 589 } 590 591 pipe->InitCommon(fDeviceAddress, 592 endpoint->descr->endpoint_address & 0x0f, 593 fSpeed, direction, endpoint->descr->max_packet_size, 594 endpoint->descr->interval, fHubAddress, fHubPort); 595 if (comp_descr != NULL) { 596 pipe->InitSuperSpeed(comp_descr->max_burst, 597 comp_descr->bytes_per_interval); 598 } 599 endpoint->handle = pipe->USBID(); 600 } 601 } 602 } 603 604 605 status_t 606 Device::Unconfigure(bool atDeviceLevel) 607 { 608 // If we only want to destroy our open pipes before setting 609 // another configuration unconfigure will be called with 610 // atDevice = false. otherwise we explicitly want to unconfigure 611 // the device and have to send it the corresponding request. 612 if (atDeviceLevel && fAvailable) { 613 status_t result = fDefaultPipe->SendRequest( 614 USB_REQTYPE_DEVICE_OUT | USB_REQTYPE_STANDARD, 615 USB_REQUEST_SET_CONFIGURATION, 0, 0, 0, NULL, 0, NULL); 616 if (result < B_OK) 617 return result; 618 619 snooze(USB_DELAY_SET_CONFIGURATION); 620 } 621 622 if (!fCurrentConfiguration) 623 return B_OK; 624 625 ClearEndpoints(-1); 626 fCurrentConfiguration = NULL; 627 return B_OK; 628 } 629 630 631 void 632 Device::ClearEndpoints(int32 interfaceIndex) 633 { 634 if (fCurrentConfiguration == NULL 635 || fCurrentConfiguration->interface == NULL) 636 return; 637 638 for (size_t j = 0; j < fCurrentConfiguration->interface_count; j++) { 639 if (interfaceIndex >= 0 && j != (size_t)interfaceIndex) 640 continue; 641 642 usb_interface_info* interfaceInfo 643 = fCurrentConfiguration->interface[j].active; 644 if (interfaceInfo == NULL || interfaceInfo->endpoint == NULL) 645 continue; 646 647 for (size_t i = 0; i < interfaceInfo->endpoint_count; i++) { 648 usb_endpoint_info* endpoint = &interfaceInfo->endpoint[i]; 649 Pipe* pipe = (Pipe*)GetStack()->GetObject(endpoint->handle); 650 if (pipe != NULL) 651 pipe->SetBusy(false); 652 delete pipe; 653 endpoint->handle = 0; 654 } 655 } 656 } 657 658 659 status_t 660 Device::SetAltInterface(const usb_interface_info* interface) 661 { 662 uint8 interfaceNumber = interface->descr->interface_number; 663 // Tell the device to set the alternate settings 664 status_t result = fDefaultPipe->SendRequest( 665 USB_REQTYPE_INTERFACE_OUT | USB_REQTYPE_STANDARD, 666 USB_REQUEST_SET_INTERFACE, 667 interface->descr->alternate_setting, interfaceNumber, 0, NULL, 0, NULL); 668 if (result < B_OK) 669 return result; 670 671 // Clear the no longer active endpoints 672 ClearEndpoints(interfaceNumber); 673 674 // Update the active pointer of the interface list 675 usb_interface_list* interfaceList 676 = &fCurrentConfiguration->interface[interfaceNumber]; 677 interfaceList->active 678 = &interfaceList->alt[interface->descr->alternate_setting]; 679 680 // Initialize the new endpoints 681 InitEndpoints(interfaceNumber); 682 return result; 683 } 684 685 686 const usb_device_descriptor* 687 Device::DeviceDescriptor() const 688 { 689 return &fDeviceDescriptor; 690 } 691 692 693 status_t 694 Device::ReportDevice(usb_support_descriptor* supportDescriptors, 695 uint32 supportDescriptorCount, const usb_notify_hooks* hooks, 696 usb_driver_cookie** cookies, bool added, bool recursive) 697 { 698 TRACE("reporting device\n"); 699 bool supported = false; 700 if (supportDescriptorCount == 0 || supportDescriptors == NULL) 701 supported = true; 702 703 for (uint32 i = 0; !supported && i < supportDescriptorCount; i++) { 704 if ((supportDescriptors[i].vendor != 0 705 && fDeviceDescriptor.vendor_id != supportDescriptors[i].vendor) 706 || (supportDescriptors[i].product != 0 707 && fDeviceDescriptor.product_id 708 != supportDescriptors[i].product)) 709 continue; 710 711 if ((supportDescriptors[i].dev_class == 0 712 || fDeviceDescriptor.device_class 713 == supportDescriptors[i].dev_class) 714 && (supportDescriptors[i].dev_subclass == 0 715 || fDeviceDescriptor.device_subclass 716 == supportDescriptors[i].dev_subclass) 717 && (supportDescriptors[i].dev_protocol == 0 718 || fDeviceDescriptor.device_protocol 719 == supportDescriptors[i].dev_protocol)) { 720 supported = true; 721 } 722 723 // we have to check all interfaces for matching class/subclass/protocol 724 for (uint32 j = 0; 725 !supported && j < fDeviceDescriptor.num_configurations; j++) { 726 for (uint32 k = 0; 727 !supported && k < fConfigurations[j].interface_count; k++) { 728 for (uint32 l = 0; !supported 729 && l < fConfigurations[j].interface[k].alt_count; l++) { 730 usb_interface_descriptor* descriptor 731 = fConfigurations[j].interface[k].alt[l].descr; 732 if ((supportDescriptors[i].dev_class == 0 733 || descriptor->interface_class 734 == supportDescriptors[i].dev_class) 735 && (supportDescriptors[i].dev_subclass == 0 736 || descriptor->interface_subclass 737 == supportDescriptors[i].dev_subclass) 738 && (supportDescriptors[i].dev_protocol == 0 739 || descriptor->interface_protocol 740 == supportDescriptors[i].dev_protocol)) { 741 supported = true; 742 } 743 } 744 } 745 } 746 } 747 748 if (!supported) 749 return B_UNSUPPORTED; 750 751 if ((added && hooks->device_added == NULL) 752 || (!added && hooks->device_removed == NULL)) { 753 // hooks are not installed, but report success to indicate that 754 // the driver supports the device 755 return B_OK; 756 } 757 758 usb_id id = USBID(); 759 if (added) { 760 usb_driver_cookie* cookie = new(std::nothrow) usb_driver_cookie; 761 if (hooks->device_added(id, &cookie->cookie) >= B_OK) { 762 cookie->device = id; 763 cookie->link = *cookies; 764 *cookies = cookie; 765 } else 766 delete cookie; 767 } else { 768 usb_driver_cookie** pointer = cookies; 769 usb_driver_cookie* cookie = *cookies; 770 while (cookie != NULL) { 771 if (cookie->device == id) 772 break; 773 pointer = &cookie->link; 774 cookie = cookie->link; 775 } 776 777 if (cookie == NULL) { 778 // the device is supported, but there is no cookie. this most 779 // probably means that the device_added hook above failed. 780 return B_OK; 781 } 782 783 hooks->device_removed(cookie->cookie); 784 *pointer = cookie->link; 785 delete cookie; 786 } 787 788 return B_OK; 789 } 790 791 792 status_t 793 Device::BuildDeviceName(char* string, uint32* index, size_t bufferSize, 794 Device* device) 795 { 796 if (!Parent() || (Parent()->Type() & USB_OBJECT_HUB) == 0) 797 return B_ERROR; 798 799 ((Hub*)Parent())->BuildDeviceName(string, index, bufferSize, this); 800 return B_OK; 801 } 802 803 804 status_t 805 Device::SetFeature(uint16 selector) 806 { 807 if (!fAvailable) 808 return B_ERROR; 809 810 TRACE("set feature %u\n", selector); 811 return fDefaultPipe->SendRequest( 812 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, 813 USB_REQUEST_SET_FEATURE, selector, 0, 0, NULL, 0, NULL); 814 } 815 816 817 status_t 818 Device::ClearFeature(uint16 selector) 819 { 820 if (!fAvailable) 821 return B_ERROR; 822 823 TRACE("clear feature %u\n", selector); 824 return fDefaultPipe->SendRequest( 825 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_OUT, 826 USB_REQUEST_CLEAR_FEATURE, selector, 0, 0, NULL, 0, NULL); 827 } 828 829 830 status_t 831 Device::GetStatus(uint16* status) 832 { 833 if (!fAvailable) 834 return B_ERROR; 835 836 TRACE("get status\n"); 837 return fDefaultPipe->SendRequest( 838 USB_REQTYPE_STANDARD | USB_REQTYPE_DEVICE_IN, 839 USB_REQUEST_GET_STATUS, 0, 0, 2, (void*)status, 2, NULL); 840 } 841 842 843 device_node* 844 Device::RegisterNode(device_node *parent) 845 { 846 usb_id id = USBID(); 847 if (parent == NULL) 848 parent = ((Device*)Parent())->Node(); 849 850 // determine how many attributes we will need 851 uint32 deviceAttrTotal = 1; 852 for (uint32 j = 0; j < fDeviceDescriptor.num_configurations; j++) { 853 for (uint32 k = 0; k < fConfigurations[j].interface_count; k++) { 854 for (uint32 l = 0; l < fConfigurations[j].interface[k].alt_count; l++) { 855 deviceAttrTotal += 3; 856 } 857 } 858 } 859 860 BStackOrHeapArray<device_attr, 16> attrs(deviceAttrTotal + 4 + 5); 861 attrs[0] = { B_DEVICE_BUS, B_STRING_TYPE, { .string = "usb" } }; 862 863 // location 864 attrs[1] = { USB_DEVICE_ID_ITEM, B_UINT32_TYPE, { .ui32 = id } }; 865 attrs[2] = { B_DEVICE_FLAGS, B_UINT32_TYPE, { .ui32 = B_FIND_MULTIPLE_CHILDREN } }; 866 attrs[3] = { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { .string = "USB device" } }; 867 868 uint32 attrCount = 4; 869 870 if (fDeviceDescriptor.vendor_id != 0) { 871 attrs[attrCount].name = B_DEVICE_VENDOR_ID; 872 attrs[attrCount].type = B_UINT16_TYPE; 873 attrs[attrCount].value.ui16 = fDeviceDescriptor.vendor_id; 874 attrCount++; 875 876 attrs[attrCount].name = B_DEVICE_ID; 877 attrs[attrCount].type = B_UINT16_TYPE; 878 attrs[attrCount].value.ui16 = fDeviceDescriptor.product_id; 879 attrCount++; 880 } 881 882 uint32 attrClassesIndex = attrCount; 883 884 if (fDeviceDescriptor.device_class != 0) { 885 attrs[attrCount].name = USB_DEVICE_CLASS; 886 attrs[attrCount].type = B_UINT8_TYPE; 887 attrs[attrCount].value.ui8 = fDeviceDescriptor.device_class; 888 attrCount++; 889 890 attrs[attrCount].name = USB_DEVICE_SUBCLASS; 891 attrs[attrCount].type = B_UINT8_TYPE; 892 attrs[attrCount].value.ui8 = fDeviceDescriptor.device_subclass; 893 attrCount++; 894 895 attrs[attrCount].name = USB_DEVICE_PROTOCOL; 896 attrs[attrCount].type = B_UINT8_TYPE; 897 attrs[attrCount].value.ui8 = fDeviceDescriptor.device_protocol; 898 attrCount++; 899 } 900 901 for (uint32 j = 0; j < fDeviceDescriptor.num_configurations; j++) { 902 for (uint32 k = 0; k < fConfigurations[j].interface_count; k++) { 903 for (uint32 l = 0; l < fConfigurations[j].interface[k].alt_count; l++) { 904 usb_interface_descriptor* descriptor 905 = fConfigurations[j].interface[k].alt[l].descr; 906 bool found = false; 907 for (uint32 i = attrClassesIndex; i < attrCount;) { 908 if (attrs[i++].value.ui8 != descriptor->interface_class) 909 continue; 910 if (attrs[i++].value.ui8 != descriptor->interface_subclass) 911 continue; 912 if (attrs[i++].value.ui8 != descriptor->interface_protocol) 913 continue; 914 found = true; 915 break; 916 } 917 if (found) 918 continue; 919 920 attrs[attrCount].name = USB_DEVICE_CLASS; 921 attrs[attrCount].type = B_UINT8_TYPE; 922 attrs[attrCount].value.ui8 = descriptor->interface_class; 923 attrCount++; 924 925 attrs[attrCount].name = USB_DEVICE_SUBCLASS; 926 attrs[attrCount].type = B_UINT8_TYPE; 927 attrs[attrCount].value.ui8 = descriptor->interface_subclass; 928 attrCount++; 929 930 attrs[attrCount].name = USB_DEVICE_PROTOCOL; 931 attrs[attrCount].type = B_UINT8_TYPE; 932 attrs[attrCount].value.ui8 = descriptor->interface_protocol; 933 attrCount++; 934 } 935 } 936 } 937 938 attrs[attrCount].name = NULL; 939 attrs[attrCount].type = 0; 940 attrs[attrCount].value.string = NULL; 941 attrCount++; 942 943 device_node* node = NULL; 944 if (gDeviceManager->register_node(parent, USB_DEVICE_MODULE_NAME, attrs, 945 NULL, &node) != B_OK) { 946 TRACE_ERROR("failed to register device node\n"); 947 } else 948 fNode = node; 949 return node; 950 } 951