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