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