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