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