1 /** @file 2 3 Wrapper function for usb host controller interface. 4 5 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 17 #include "UsbBus.h" 18 19 // 20 // if RemainingDevicePath== NULL, then all Usb child devices in this bus are wanted. 21 // Use a shor form Usb class Device Path, which could match any usb device, in WantedUsbIoDPList to indicate all Usb devices 22 // are wanted Usb devices 23 // 24 USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath = { 25 { 26 { 27 MESSAGING_DEVICE_PATH, 28 MSG_USB_CLASS_DP, 29 { 30 (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)), 31 (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8) 32 } 33 }, 34 0xffff, // VendorId 35 0xffff, // ProductId 36 0xff, // DeviceClass 37 0xff, // DeviceSubClass 38 0xff // DeviceProtocol 39 }, 40 41 { 42 END_DEVICE_PATH_TYPE, 43 END_ENTIRE_DEVICE_PATH_SUBTYPE, 44 { 45 END_DEVICE_PATH_LENGTH, 46 0 47 } 48 } 49 }; 50 51 52 /** 53 Get the capability of the host controller. 54 55 @param UsbBus The usb driver. 56 @param MaxSpeed The maximum speed this host controller supports. 57 @param NumOfPort The number of the root hub port. 58 @param Is64BitCapable Whether this controller support 64 bit addressing. 59 60 @retval EFI_SUCCESS The host controller capability is returned. 61 @retval Others Failed to retrieve the host controller capability. 62 63 **/ 64 EFI_STATUS 65 UsbHcGetCapability ( 66 IN USB_BUS *UsbBus, 67 OUT UINT8 *MaxSpeed, 68 OUT UINT8 *NumOfPort, 69 OUT UINT8 *Is64BitCapable 70 ) 71 { 72 EFI_STATUS Status; 73 74 if (UsbBus->Usb2Hc != NULL) { 75 Status = UsbBus->Usb2Hc->GetCapability ( 76 UsbBus->Usb2Hc, 77 MaxSpeed, 78 NumOfPort, 79 Is64BitCapable 80 ); 81 82 } else { 83 Status = UsbBus->UsbHc->GetRootHubPortNumber (UsbBus->UsbHc, NumOfPort); 84 85 *MaxSpeed = EFI_USB_SPEED_FULL; 86 *Is64BitCapable = (UINT8) FALSE; 87 } 88 89 return Status; 90 } 91 92 93 /** 94 Reset the host controller. 95 96 @param UsbBus The usb bus driver. 97 @param Attributes The reset type, only global reset is used by this driver. 98 99 @retval EFI_SUCCESS The reset operation succeeded. 100 @retval EFI_INVALID_PARAMETER Attributes is not valid. 101 @retval EFI_UNSUPPOURTED The type of reset specified by Attributes is 102 not currently supported by the host controller. 103 @retval EFI_DEVICE_ERROR Host controller isn't halted to reset. 104 **/ 105 EFI_STATUS 106 UsbHcReset ( 107 IN USB_BUS *UsbBus, 108 IN UINT16 Attributes 109 ) 110 { 111 EFI_STATUS Status; 112 113 if (UsbBus->Usb2Hc != NULL) { 114 Status = UsbBus->Usb2Hc->Reset (UsbBus->Usb2Hc, Attributes); 115 } else { 116 Status = UsbBus->UsbHc->Reset (UsbBus->UsbHc, Attributes); 117 } 118 119 return Status; 120 } 121 122 123 /** 124 Get the current operation state of the host controller. 125 126 @param UsbBus The USB bus driver. 127 @param State The host controller operation state. 128 129 @retval EFI_SUCCESS The operation state is returned in State. 130 @retval Others Failed to get the host controller state. 131 132 **/ 133 EFI_STATUS 134 UsbHcGetState ( 135 IN USB_BUS *UsbBus, 136 OUT EFI_USB_HC_STATE *State 137 ) 138 { 139 EFI_STATUS Status; 140 141 if (UsbBus->Usb2Hc != NULL) { 142 Status = UsbBus->Usb2Hc->GetState (UsbBus->Usb2Hc, State); 143 } else { 144 Status = UsbBus->UsbHc->GetState (UsbBus->UsbHc, State); 145 } 146 147 return Status; 148 } 149 150 151 /** 152 Set the host controller operation state. 153 154 @param UsbBus The USB bus driver. 155 @param State The state to set. 156 157 @retval EFI_SUCCESS The host controller is now working at State. 158 @retval Others Failed to set operation state. 159 160 **/ 161 EFI_STATUS 162 UsbHcSetState ( 163 IN USB_BUS *UsbBus, 164 IN EFI_USB_HC_STATE State 165 ) 166 { 167 EFI_STATUS Status; 168 169 if (UsbBus->Usb2Hc != NULL) { 170 Status = UsbBus->Usb2Hc->SetState (UsbBus->Usb2Hc, State); 171 } else { 172 Status = UsbBus->UsbHc->SetState (UsbBus->UsbHc, State); 173 } 174 175 return Status; 176 } 177 178 179 /** 180 Get the root hub port state. 181 182 @param UsbBus The USB bus driver. 183 @param PortIndex The index of port. 184 @param PortStatus The variable to save port state. 185 186 @retval EFI_SUCCESS The root port state is returned in. 187 @retval Others Failed to get the root hub port state. 188 189 **/ 190 EFI_STATUS 191 UsbHcGetRootHubPortStatus ( 192 IN USB_BUS *UsbBus, 193 IN UINT8 PortIndex, 194 OUT EFI_USB_PORT_STATUS *PortStatus 195 ) 196 { 197 EFI_STATUS Status; 198 199 if (UsbBus->Usb2Hc != NULL) { 200 Status = UsbBus->Usb2Hc->GetRootHubPortStatus (UsbBus->Usb2Hc, PortIndex, PortStatus); 201 } else { 202 Status = UsbBus->UsbHc->GetRootHubPortStatus (UsbBus->UsbHc, PortIndex, PortStatus); 203 } 204 205 return Status; 206 } 207 208 209 /** 210 Set the root hub port feature. 211 212 @param UsbBus The USB bus driver. 213 @param PortIndex The port index. 214 @param Feature The port feature to set. 215 216 @retval EFI_SUCCESS The port feature is set. 217 @retval Others Failed to set port feature. 218 219 **/ 220 EFI_STATUS 221 UsbHcSetRootHubPortFeature ( 222 IN USB_BUS *UsbBus, 223 IN UINT8 PortIndex, 224 IN EFI_USB_PORT_FEATURE Feature 225 ) 226 { 227 EFI_STATUS Status; 228 229 230 if (UsbBus->Usb2Hc != NULL) { 231 Status = UsbBus->Usb2Hc->SetRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature); 232 } else { 233 Status = UsbBus->UsbHc->SetRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature); 234 } 235 236 return Status; 237 } 238 239 240 /** 241 Clear the root hub port feature. 242 243 @param UsbBus The USB bus driver. 244 @param PortIndex The port index. 245 @param Feature The port feature to clear. 246 247 @retval EFI_SUCCESS The port feature is clear. 248 @retval Others Failed to clear port feature. 249 250 **/ 251 EFI_STATUS 252 UsbHcClearRootHubPortFeature ( 253 IN USB_BUS *UsbBus, 254 IN UINT8 PortIndex, 255 IN EFI_USB_PORT_FEATURE Feature 256 ) 257 { 258 EFI_STATUS Status; 259 260 if (UsbBus->Usb2Hc != NULL) { 261 Status = UsbBus->Usb2Hc->ClearRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature); 262 } else { 263 Status = UsbBus->UsbHc->ClearRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature); 264 } 265 266 return Status; 267 } 268 269 270 /** 271 Execute a control transfer to the device. 272 273 @param UsbBus The USB bus driver. 274 @param DevAddr The device address. 275 @param DevSpeed The device speed. 276 @param MaxPacket Maximum packet size of endpoint 0. 277 @param Request The control transfer request. 278 @param Direction The direction of data stage. 279 @param Data The buffer holding data. 280 @param DataLength The length of the data. 281 @param TimeOut Timeout (in ms) to wait until timeout. 282 @param Translator The transaction translator for low/full speed device. 283 @param UsbResult The result of transfer. 284 285 @retval EFI_SUCCESS The control transfer finished without error. 286 @retval Others The control transfer failed, reason returned in UsbReslt. 287 288 **/ 289 EFI_STATUS 290 UsbHcControlTransfer ( 291 IN USB_BUS *UsbBus, 292 IN UINT8 DevAddr, 293 IN UINT8 DevSpeed, 294 IN UINTN MaxPacket, 295 IN EFI_USB_DEVICE_REQUEST *Request, 296 IN EFI_USB_DATA_DIRECTION Direction, 297 IN OUT VOID *Data, 298 IN OUT UINTN *DataLength, 299 IN UINTN TimeOut, 300 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, 301 OUT UINT32 *UsbResult 302 ) 303 { 304 EFI_STATUS Status; 305 BOOLEAN IsSlowDevice; 306 307 if (UsbBus->Usb2Hc != NULL) { 308 Status = UsbBus->Usb2Hc->ControlTransfer ( 309 UsbBus->Usb2Hc, 310 DevAddr, 311 DevSpeed, 312 MaxPacket, 313 Request, 314 Direction, 315 Data, 316 DataLength, 317 TimeOut, 318 Translator, 319 UsbResult 320 ); 321 322 } else { 323 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed); 324 Status = UsbBus->UsbHc->ControlTransfer ( 325 UsbBus->UsbHc, 326 DevAddr, 327 IsSlowDevice, 328 (UINT8) MaxPacket, 329 Request, 330 Direction, 331 Data, 332 DataLength, 333 TimeOut, 334 UsbResult 335 ); 336 } 337 338 return Status; 339 } 340 341 342 /** 343 Execute a bulk transfer to the device's endpoint. 344 345 @param UsbBus The USB bus driver. 346 @param DevAddr The target device address. 347 @param EpAddr The target endpoint address, with direction encoded in 348 bit 7. 349 @param DevSpeed The device's speed. 350 @param MaxPacket The endpoint's max packet size. 351 @param BufferNum The number of data buffer. 352 @param Data Array of pointers to data buffer. 353 @param DataLength The length of data buffer. 354 @param DataToggle On input, the initial data toggle to use, also return 355 the next toggle on output. 356 @param TimeOut The time to wait until timeout. 357 @param Translator The transaction translator for low/full speed device. 358 @param UsbResult The result of USB execution. 359 360 @retval EFI_SUCCESS The bulk transfer is finished without error. 361 @retval Others Failed to execute bulk transfer, result in UsbResult. 362 363 **/ 364 EFI_STATUS 365 UsbHcBulkTransfer ( 366 IN USB_BUS *UsbBus, 367 IN UINT8 DevAddr, 368 IN UINT8 EpAddr, 369 IN UINT8 DevSpeed, 370 IN UINTN MaxPacket, 371 IN UINT8 BufferNum, 372 IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM], 373 IN OUT UINTN *DataLength, 374 IN OUT UINT8 *DataToggle, 375 IN UINTN TimeOut, 376 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, 377 OUT UINT32 *UsbResult 378 ) 379 { 380 EFI_STATUS Status; 381 382 if (UsbBus->Usb2Hc != NULL) { 383 Status = UsbBus->Usb2Hc->BulkTransfer ( 384 UsbBus->Usb2Hc, 385 DevAddr, 386 EpAddr, 387 DevSpeed, 388 MaxPacket, 389 BufferNum, 390 Data, 391 DataLength, 392 DataToggle, 393 TimeOut, 394 Translator, 395 UsbResult 396 ); 397 } else { 398 Status = UsbBus->UsbHc->BulkTransfer ( 399 UsbBus->UsbHc, 400 DevAddr, 401 EpAddr, 402 (UINT8) MaxPacket, 403 *Data, 404 DataLength, 405 DataToggle, 406 TimeOut, 407 UsbResult 408 ); 409 } 410 411 return Status; 412 } 413 414 415 /** 416 Queue or cancel an asynchronous interrupt transfer. 417 418 @param UsbBus The USB bus driver. 419 @param DevAddr The target device address. 420 @param EpAddr The target endpoint address, with direction encoded in 421 bit 7. 422 @param DevSpeed The device's speed. 423 @param MaxPacket The endpoint's max packet size. 424 @param IsNewTransfer Whether this is a new request. If not, cancel the old 425 request. 426 @param DataToggle Data toggle to use on input, next toggle on output. 427 @param PollingInterval The interval to poll the interrupt transfer (in ms). 428 @param DataLength The length of periodical data receive. 429 @param Translator The transaction translator for low/full speed device. 430 @param Callback Function to call when data is received. 431 @param Context The context to the callback. 432 433 @retval EFI_SUCCESS The asynchronous transfer is queued. 434 @retval Others Failed to queue the transfer. 435 436 **/ 437 EFI_STATUS 438 UsbHcAsyncInterruptTransfer ( 439 IN USB_BUS *UsbBus, 440 IN UINT8 DevAddr, 441 IN UINT8 EpAddr, 442 IN UINT8 DevSpeed, 443 IN UINTN MaxPacket, 444 IN BOOLEAN IsNewTransfer, 445 IN OUT UINT8 *DataToggle, 446 IN UINTN PollingInterval, 447 IN UINTN DataLength, 448 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, 449 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, 450 IN VOID *Context OPTIONAL 451 ) 452 { 453 EFI_STATUS Status; 454 BOOLEAN IsSlowDevice; 455 456 if (UsbBus->Usb2Hc != NULL) { 457 Status = UsbBus->Usb2Hc->AsyncInterruptTransfer ( 458 UsbBus->Usb2Hc, 459 DevAddr, 460 EpAddr, 461 DevSpeed, 462 MaxPacket, 463 IsNewTransfer, 464 DataToggle, 465 PollingInterval, 466 DataLength, 467 Translator, 468 Callback, 469 Context 470 ); 471 } else { 472 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed); 473 474 Status = UsbBus->UsbHc->AsyncInterruptTransfer ( 475 UsbBus->UsbHc, 476 DevAddr, 477 EpAddr, 478 IsSlowDevice, 479 (UINT8) MaxPacket, 480 IsNewTransfer, 481 DataToggle, 482 PollingInterval, 483 DataLength, 484 Callback, 485 Context 486 ); 487 } 488 489 return Status; 490 } 491 492 493 /** 494 Execute a synchronous interrupt transfer to the target endpoint. 495 496 @param UsbBus The USB bus driver. 497 @param DevAddr The target device address. 498 @param EpAddr The target endpoint address, with direction encoded in 499 bit 7. 500 @param DevSpeed The device's speed. 501 @param MaxPacket The endpoint's max packet size. 502 @param Data Pointer to data buffer. 503 @param DataLength The length of data buffer. 504 @param DataToggle On input, the initial data toggle to use, also return 505 the next toggle on output. 506 @param TimeOut The time to wait until timeout. 507 @param Translator The transaction translator for low/full speed device. 508 @param UsbResult The result of USB execution. 509 510 @retval EFI_SUCCESS The synchronous interrupt transfer is OK. 511 @retval Others Failed to execute the synchronous interrupt transfer. 512 513 **/ 514 EFI_STATUS 515 UsbHcSyncInterruptTransfer ( 516 IN USB_BUS *UsbBus, 517 IN UINT8 DevAddr, 518 IN UINT8 EpAddr, 519 IN UINT8 DevSpeed, 520 IN UINTN MaxPacket, 521 IN OUT VOID *Data, 522 IN OUT UINTN *DataLength, 523 IN OUT UINT8 *DataToggle, 524 IN UINTN TimeOut, 525 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, 526 OUT UINT32 *UsbResult 527 ) 528 { 529 EFI_STATUS Status; 530 BOOLEAN IsSlowDevice; 531 532 if (UsbBus->Usb2Hc != NULL) { 533 Status = UsbBus->Usb2Hc->SyncInterruptTransfer ( 534 UsbBus->Usb2Hc, 535 DevAddr, 536 EpAddr, 537 DevSpeed, 538 MaxPacket, 539 Data, 540 DataLength, 541 DataToggle, 542 TimeOut, 543 Translator, 544 UsbResult 545 ); 546 } else { 547 IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DevSpeed) ? TRUE : FALSE); 548 Status = UsbBus->UsbHc->SyncInterruptTransfer ( 549 UsbBus->UsbHc, 550 DevAddr, 551 EpAddr, 552 IsSlowDevice, 553 (UINT8) MaxPacket, 554 Data, 555 DataLength, 556 DataToggle, 557 TimeOut, 558 UsbResult 559 ); 560 } 561 562 return Status; 563 } 564 565 566 /** 567 Execute a synchronous Isochronous USB transfer. 568 569 @param UsbBus The USB bus driver. 570 @param DevAddr The target device address. 571 @param EpAddr The target endpoint address, with direction encoded in 572 bit 7. 573 @param DevSpeed The device's speed. 574 @param MaxPacket The endpoint's max packet size. 575 @param BufferNum The number of data buffer. 576 @param Data Array of pointers to data buffer. 577 @param DataLength The length of data buffer. 578 @param Translator The transaction translator for low/full speed device. 579 @param UsbResult The result of USB execution. 580 581 @retval EFI_UNSUPPORTED The isochronous transfer isn't supported now. 582 583 **/ 584 EFI_STATUS 585 UsbHcIsochronousTransfer ( 586 IN USB_BUS *UsbBus, 587 IN UINT8 DevAddr, 588 IN UINT8 EpAddr, 589 IN UINT8 DevSpeed, 590 IN UINTN MaxPacket, 591 IN UINT8 BufferNum, 592 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], 593 IN UINTN DataLength, 594 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, 595 OUT UINT32 *UsbResult 596 ) 597 { 598 return EFI_UNSUPPORTED; 599 } 600 601 602 /** 603 Queue an asynchronous isochronous transfer. 604 605 @param UsbBus The USB bus driver. 606 @param DevAddr The target device address. 607 @param EpAddr The target endpoint address, with direction encoded in 608 bit 7. 609 @param DevSpeed The device's speed. 610 @param MaxPacket The endpoint's max packet size. 611 @param BufferNum The number of data buffer. 612 @param Data Array of pointers to data buffer. 613 @param DataLength The length of data buffer. 614 @param Translator The transaction translator for low/full speed device. 615 @param Callback The function to call when data is transferred. 616 @param Context The context to the callback function. 617 618 @retval EFI_UNSUPPORTED The asynchronous isochronous transfer isn't supported. 619 620 **/ 621 EFI_STATUS 622 UsbHcAsyncIsochronousTransfer ( 623 IN USB_BUS *UsbBus, 624 IN UINT8 DevAddr, 625 IN UINT8 EpAddr, 626 IN UINT8 DevSpeed, 627 IN UINTN MaxPacket, 628 IN UINT8 BufferNum, 629 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM], 630 IN UINTN DataLength, 631 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, 632 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, 633 IN VOID *Context 634 ) 635 { 636 return EFI_UNSUPPORTED; 637 } 638 639 640 /** 641 Open the USB host controller protocol BY_CHILD. 642 643 @param Bus The USB bus driver. 644 @param Child The child handle. 645 646 @return The open protocol return. 647 648 **/ 649 EFI_STATUS 650 UsbOpenHostProtoByChild ( 651 IN USB_BUS *Bus, 652 IN EFI_HANDLE Child 653 ) 654 { 655 EFI_USB_HC_PROTOCOL *UsbHc; 656 EFI_USB2_HC_PROTOCOL *Usb2Hc; 657 EFI_STATUS Status; 658 659 if (Bus->Usb2Hc != NULL) { 660 Status = gBS->OpenProtocol ( 661 Bus->HostHandle, 662 &gEfiUsb2HcProtocolGuid, 663 (VOID **) &Usb2Hc, 664 mUsbBusDriverBinding.DriverBindingHandle, 665 Child, 666 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 667 ); 668 669 } else { 670 Status = gBS->OpenProtocol ( 671 Bus->HostHandle, 672 &gEfiUsbHcProtocolGuid, 673 (VOID **) &UsbHc, 674 mUsbBusDriverBinding.DriverBindingHandle, 675 Child, 676 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 677 ); 678 } 679 680 return Status; 681 } 682 683 684 /** 685 Close the USB host controller protocol BY_CHILD. 686 687 @param Bus The USB bus driver. 688 @param Child The child handle. 689 690 **/ 691 VOID 692 UsbCloseHostProtoByChild ( 693 IN USB_BUS *Bus, 694 IN EFI_HANDLE Child 695 ) 696 { 697 if (Bus->Usb2Hc != NULL) { 698 gBS->CloseProtocol ( 699 Bus->HostHandle, 700 &gEfiUsb2HcProtocolGuid, 701 mUsbBusDriverBinding.DriverBindingHandle, 702 Child 703 ); 704 705 } else { 706 gBS->CloseProtocol ( 707 Bus->HostHandle, 708 &gEfiUsbHcProtocolGuid, 709 mUsbBusDriverBinding.DriverBindingHandle, 710 Child 711 ); 712 } 713 } 714 715 716 /** 717 return the current TPL, copied from the EDKII glue lib. 718 719 @param VOID. 720 721 @return Current TPL. 722 723 **/ 724 EFI_TPL 725 UsbGetCurrentTpl ( 726 VOID 727 ) 728 { 729 EFI_TPL Tpl; 730 731 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); 732 gBS->RestoreTPL (Tpl); 733 734 return Tpl; 735 } 736 737 /** 738 Create a new device path which only contain the first Usb part of the DevicePath. 739 740 @param DevicePath A full device path which contain the usb nodes. 741 742 @return A new device path which only contain the Usb part of the DevicePath. 743 744 **/ 745 EFI_DEVICE_PATH_PROTOCOL * 746 EFIAPI 747 GetUsbDPFromFullDP ( 748 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath 749 ) 750 { 751 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathPtr; 752 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathBeginPtr; 753 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathEndPtr; 754 UINTN Size; 755 756 // 757 // Get the Usb part first Begin node in full device path 758 // 759 UsbDevicePathBeginPtr = DevicePath; 760 while ( (!IsDevicePathEnd (UsbDevicePathBeginPtr))&& 761 ((UsbDevicePathBeginPtr->Type != MESSAGING_DEVICE_PATH) || 762 (UsbDevicePathBeginPtr->SubType != MSG_USB_DP && 763 UsbDevicePathBeginPtr->SubType != MSG_USB_CLASS_DP 764 && UsbDevicePathBeginPtr->SubType != MSG_USB_WWID_DP 765 ))) { 766 767 UsbDevicePathBeginPtr = NextDevicePathNode(UsbDevicePathBeginPtr); 768 } 769 770 // 771 // Get the Usb part first End node in full device path 772 // 773 UsbDevicePathEndPtr = UsbDevicePathBeginPtr; 774 while ((!IsDevicePathEnd (UsbDevicePathEndPtr))&& 775 (UsbDevicePathEndPtr->Type == MESSAGING_DEVICE_PATH) && 776 (UsbDevicePathEndPtr->SubType == MSG_USB_DP || 777 UsbDevicePathEndPtr->SubType == MSG_USB_CLASS_DP 778 || UsbDevicePathEndPtr->SubType == MSG_USB_WWID_DP 779 )) { 780 781 UsbDevicePathEndPtr = NextDevicePathNode(UsbDevicePathEndPtr); 782 } 783 784 Size = GetDevicePathSize (UsbDevicePathBeginPtr); 785 Size -= GetDevicePathSize (UsbDevicePathEndPtr); 786 if (Size ==0){ 787 // 788 // The passed in DevicePath does not contain the usb nodes 789 // 790 return NULL; 791 } 792 793 // 794 // Create a new device path which only contain the above Usb part 795 // 796 UsbDevicePathPtr = AllocateZeroPool (Size + sizeof (EFI_DEVICE_PATH_PROTOCOL)); 797 ASSERT (UsbDevicePathPtr != NULL); 798 CopyMem (UsbDevicePathPtr, UsbDevicePathBeginPtr, Size); 799 // 800 // Append end device path node 801 // 802 UsbDevicePathEndPtr = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) UsbDevicePathPtr + Size); 803 SetDevicePathEndNode (UsbDevicePathEndPtr); 804 return UsbDevicePathPtr; 805 } 806 807 /** 808 Check whether a usb device path is in a DEVICE_PATH_LIST_ITEM list. 809 810 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM. 811 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list. 812 813 @retval TRUE there is a DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP. 814 @retval FALSE there is no DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP. 815 816 **/ 817 BOOLEAN 818 EFIAPI 819 SearchUsbDPInList ( 820 IN EFI_DEVICE_PATH_PROTOCOL *UsbDP, 821 IN LIST_ENTRY *UsbIoDPList 822 ) 823 { 824 LIST_ENTRY *ListIndex; 825 DEVICE_PATH_LIST_ITEM *ListItem; 826 BOOLEAN Found; 827 UINTN UsbDpDevicePathSize; 828 829 // 830 // Check that UsbDP and UsbIoDPList are valid 831 // 832 if ((UsbIoDPList == NULL) || (UsbDP == NULL)) { 833 return FALSE; 834 } 835 836 Found = FALSE; 837 ListIndex = UsbIoDPList->ForwardLink; 838 while (ListIndex != UsbIoDPList){ 839 ListItem = CR(ListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE); 840 // 841 // Compare DEVICE_PATH_LIST_ITEM.DevicePath[] 842 // 843 ASSERT (ListItem->DevicePath != NULL); 844 845 UsbDpDevicePathSize = GetDevicePathSize (UsbDP); 846 if (UsbDpDevicePathSize == GetDevicePathSize (ListItem->DevicePath)) { 847 if ((CompareMem (UsbDP, ListItem->DevicePath, UsbDpDevicePathSize)) == 0) { 848 Found = TRUE; 849 break; 850 } 851 } 852 ListIndex = ListIndex->ForwardLink; 853 } 854 855 return Found; 856 } 857 858 /** 859 Add a usb device path into the DEVICE_PATH_LIST_ITEM list. 860 861 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM. 862 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list. 863 864 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value. 865 @retval EFI_SUCCESS If Add operation is successful, return this value. 866 867 **/ 868 EFI_STATUS 869 EFIAPI 870 AddUsbDPToList ( 871 IN EFI_DEVICE_PATH_PROTOCOL *UsbDP, 872 IN LIST_ENTRY *UsbIoDPList 873 ) 874 { 875 DEVICE_PATH_LIST_ITEM *ListItem; 876 877 // 878 // Check that UsbDP and UsbIoDPList are valid 879 // 880 if ((UsbIoDPList == NULL) || (UsbDP == NULL)) { 881 return EFI_INVALID_PARAMETER; 882 } 883 884 if (SearchUsbDPInList (UsbDP, UsbIoDPList)){ 885 return EFI_SUCCESS; 886 } 887 888 // 889 // Prepare the usbio device path DEVICE_PATH_LIST_ITEM structure. 890 // 891 ListItem = AllocateZeroPool (sizeof (DEVICE_PATH_LIST_ITEM)); 892 ASSERT (ListItem != NULL); 893 ListItem->Signature = DEVICE_PATH_LIST_ITEM_SIGNATURE; 894 ListItem->DevicePath = DuplicateDevicePath (UsbDP); 895 896 InsertTailList (UsbIoDPList, &ListItem->Link); 897 898 return EFI_SUCCESS; 899 } 900 901 /** 902 Check whether usb device, whose interface is UsbIf, matches the usb class which indicated by 903 UsbClassDevicePathPtr whose is a short form usb class device path. 904 905 @param UsbClassDevicePathPtr a short form usb class device path. 906 @param UsbIf a usb device interface. 907 908 @retval TRUE the usb device match the usb class. 909 @retval FALSE the usb device does not match the usb class. 910 911 **/ 912 BOOLEAN 913 EFIAPI 914 MatchUsbClass ( 915 IN USB_CLASS_DEVICE_PATH *UsbClassDevicePathPtr, 916 IN USB_INTERFACE *UsbIf 917 ) 918 { 919 USB_INTERFACE_DESC *IfDesc; 920 EFI_USB_INTERFACE_DESCRIPTOR *ActIfDesc; 921 EFI_USB_DEVICE_DESCRIPTOR *DevDesc; 922 923 924 if ((UsbClassDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) || 925 (UsbClassDevicePathPtr->Header.SubType != MSG_USB_CLASS_DP)){ 926 ASSERT (0); 927 return FALSE; 928 } 929 930 IfDesc = UsbIf->IfDesc; 931 ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING); 932 ActIfDesc = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc); 933 DevDesc = &(UsbIf->Device->DevDesc->Desc); 934 935 // 936 // If connect class policy, determine whether to create device handle by the five fields 937 // in class device path node. 938 // 939 // In addtion, hub interface is always matched for this policy. 940 // 941 if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) && 942 (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE)) { 943 return TRUE; 944 } 945 946 // 947 // If vendor id or product id is 0xffff, they will be ignored. 948 // 949 if ((UsbClassDevicePathPtr->VendorId == 0xffff || UsbClassDevicePathPtr->VendorId == DevDesc->IdVendor) && 950 (UsbClassDevicePathPtr->ProductId == 0xffff || UsbClassDevicePathPtr->ProductId == DevDesc->IdProduct)) { 951 952 // 953 // If Class in Device Descriptor is set to 0, the counterparts in interface should be checked. 954 // 955 if (DevDesc->DeviceClass == 0) { 956 if ((UsbClassDevicePathPtr->DeviceClass == ActIfDesc->InterfaceClass || 957 UsbClassDevicePathPtr->DeviceClass == 0xff) && 958 (UsbClassDevicePathPtr->DeviceSubClass == ActIfDesc->InterfaceSubClass || 959 UsbClassDevicePathPtr->DeviceSubClass == 0xff) && 960 (UsbClassDevicePathPtr->DeviceProtocol == ActIfDesc->InterfaceProtocol || 961 UsbClassDevicePathPtr->DeviceProtocol == 0xff)) { 962 return TRUE; 963 } 964 965 } else if ((UsbClassDevicePathPtr->DeviceClass == DevDesc->DeviceClass || 966 UsbClassDevicePathPtr->DeviceClass == 0xff) && 967 (UsbClassDevicePathPtr->DeviceSubClass == DevDesc->DeviceSubClass || 968 UsbClassDevicePathPtr->DeviceSubClass == 0xff) && 969 (UsbClassDevicePathPtr->DeviceProtocol == DevDesc->DeviceProtocol || 970 UsbClassDevicePathPtr->DeviceProtocol == 0xff)) { 971 972 return TRUE; 973 } 974 } 975 976 return FALSE; 977 } 978 979 /** 980 Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by 981 UsbWWIDDevicePathPtr whose is a short form usb WWID device path. 982 983 @param UsbWWIDDevicePathPtr a short form usb WWID device path. 984 @param UsbIf a usb device interface. 985 986 @retval TRUE the usb device match the usb WWID requirement. 987 @retval FALSE the usb device does not match the usb WWID requirement. 988 989 **/ 990 BOOLEAN 991 MatchUsbWwid ( 992 IN USB_WWID_DEVICE_PATH *UsbWWIDDevicePathPtr, 993 IN USB_INTERFACE *UsbIf 994 ) 995 { 996 USB_INTERFACE_DESC *IfDesc; 997 EFI_USB_INTERFACE_DESCRIPTOR *ActIfDesc; 998 EFI_USB_DEVICE_DESCRIPTOR *DevDesc; 999 EFI_USB_STRING_DESCRIPTOR *StrDesc; 1000 UINT16 Index; 1001 CHAR16 *CompareStr; 1002 UINTN CompareLen; 1003 UINTN Length; 1004 1005 if ((UsbWWIDDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) || 1006 (UsbWWIDDevicePathPtr->Header.SubType != MSG_USB_WWID_DP )){ 1007 ASSERT (0); 1008 return FALSE; 1009 } 1010 1011 IfDesc = UsbIf->IfDesc; 1012 ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING); 1013 ActIfDesc = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc); 1014 DevDesc = &(UsbIf->Device->DevDesc->Desc); 1015 1016 // 1017 // In addition, Hub interface is always matched for this policy. 1018 // 1019 if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) && 1020 (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE)) { 1021 return TRUE; 1022 } 1023 1024 // 1025 // Check Vendor Id, Product Id and Interface Number. 1026 // 1027 if ((DevDesc->IdVendor != UsbWWIDDevicePathPtr->VendorId) || 1028 (DevDesc->IdProduct != UsbWWIDDevicePathPtr->ProductId) || 1029 (ActIfDesc->InterfaceNumber != UsbWWIDDevicePathPtr->InterfaceNumber)) { 1030 return FALSE; 1031 } 1032 1033 // 1034 // Check SerialNumber. 1035 // 1036 if (DevDesc->StrSerialNumber == 0) { 1037 return FALSE; 1038 } 1039 1040 // 1041 // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters. 1042 // 1043 CompareStr = (CHAR16 *) (UINTN) (UsbWWIDDevicePathPtr + 1); 1044 CompareLen = (DevicePathNodeLength (UsbWWIDDevicePathPtr) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16); 1045 if (CompareStr[CompareLen - 1] == L'\0') { 1046 CompareLen--; 1047 } 1048 1049 // 1050 // Compare serial number in each supported language. 1051 // 1052 for (Index = 0; Index < UsbIf->Device->TotalLangId; Index++) { 1053 StrDesc = UsbGetOneString (UsbIf->Device, DevDesc->StrSerialNumber, UsbIf->Device->LangId[Index]); 1054 if (StrDesc == NULL) { 1055 continue; 1056 } 1057 1058 Length = (StrDesc->Length - 2) / sizeof (CHAR16); 1059 if ((Length >= CompareLen) && 1060 (CompareMem (StrDesc->String + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0)) { 1061 return TRUE; 1062 } 1063 } 1064 1065 return FALSE; 1066 } 1067 1068 /** 1069 Free a DEVICE_PATH_LIST_ITEM list. 1070 1071 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list pointer. 1072 1073 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value. 1074 @retval EFI_SUCCESS If free operation is successful, return this value. 1075 1076 **/ 1077 EFI_STATUS 1078 EFIAPI 1079 UsbBusFreeUsbDPList ( 1080 IN LIST_ENTRY *UsbIoDPList 1081 ) 1082 { 1083 LIST_ENTRY *ListIndex; 1084 DEVICE_PATH_LIST_ITEM *ListItem; 1085 1086 // 1087 // Check that ControllerHandle is a valid handle 1088 // 1089 if (UsbIoDPList == NULL) { 1090 return EFI_INVALID_PARAMETER; 1091 } 1092 1093 ListIndex = UsbIoDPList->ForwardLink; 1094 while (ListIndex != UsbIoDPList){ 1095 ListItem = CR(ListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE); 1096 // 1097 // Free DEVICE_PATH_LIST_ITEM.DevicePath[] 1098 // 1099 if (ListItem->DevicePath != NULL){ 1100 FreePool(ListItem->DevicePath); 1101 } 1102 // 1103 // Free DEVICE_PATH_LIST_ITEM itself 1104 // 1105 ListIndex = ListIndex->ForwardLink; 1106 RemoveEntryList (&ListItem->Link); 1107 FreePool (ListItem); 1108 } 1109 1110 InitializeListHead (UsbIoDPList); 1111 return EFI_SUCCESS; 1112 } 1113 1114 /** 1115 Store a wanted usb child device info (its Usb part of device path) which is indicated by 1116 RemainingDevicePath in a Usb bus which is indicated by UsbBusId. 1117 1118 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface. 1119 @param RemainingDevicePath The remaining device patch. 1120 1121 @retval EFI_SUCCESS Add operation is successful. 1122 @retval EFI_INVALID_PARAMETER The parameters are invalid. 1123 1124 **/ 1125 EFI_STATUS 1126 EFIAPI 1127 UsbBusAddWantedUsbIoDP ( 1128 IN EFI_USB_BUS_PROTOCOL *UsbBusId, 1129 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 1130 ) 1131 { 1132 USB_BUS *Bus; 1133 EFI_STATUS Status; 1134 EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr; 1135 1136 // 1137 // Check whether remaining device path is valid 1138 // 1139 if (RemainingDevicePath != NULL && !IsDevicePathEnd (RemainingDevicePath)) { 1140 if ((RemainingDevicePath->Type != MESSAGING_DEVICE_PATH) || 1141 (RemainingDevicePath->SubType != MSG_USB_DP && 1142 RemainingDevicePath->SubType != MSG_USB_CLASS_DP 1143 && RemainingDevicePath->SubType != MSG_USB_WWID_DP 1144 )) { 1145 return EFI_INVALID_PARAMETER; 1146 } 1147 } 1148 1149 if (UsbBusId == NULL){ 1150 return EFI_INVALID_PARAMETER; 1151 } 1152 1153 Bus = USB_BUS_FROM_THIS (UsbBusId); 1154 1155 if (RemainingDevicePath == NULL) { 1156 // 1157 // RemainingDevicePath == NULL means all Usb devices in this bus are wanted. 1158 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices 1159 // are wanted Usb devices 1160 // 1161 Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList); 1162 ASSERT (!EFI_ERROR (Status)); 1163 DevicePathPtr = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) &mAllUsbClassDevicePath); 1164 } else if (!IsDevicePathEnd (RemainingDevicePath)) { 1165 // 1166 // If RemainingDevicePath isn't the End of Device Path Node, 1167 // Create new Usb device path according to the usb part in remaining device path 1168 // 1169 DevicePathPtr = GetUsbDPFromFullDP (RemainingDevicePath); 1170 } else { 1171 // 1172 // If RemainingDevicePath is the End of Device Path Node, 1173 // skip enumerate any device and return EFI_SUCESSS 1174 // 1175 return EFI_SUCCESS; 1176 } 1177 1178 ASSERT (DevicePathPtr != NULL); 1179 Status = AddUsbDPToList (DevicePathPtr, &Bus->WantedUsbIoDPList); 1180 ASSERT (!EFI_ERROR (Status)); 1181 FreePool (DevicePathPtr); 1182 return EFI_SUCCESS; 1183 } 1184 1185 /** 1186 Check whether a usb child device is the wanted device in a bus. 1187 1188 @param Bus The Usb bus's private data pointer. 1189 @param UsbIf The usb child device inferface. 1190 1191 @retval True If a usb child device is the wanted device in a bus. 1192 @retval False If a usb child device is *NOT* the wanted device in a bus. 1193 1194 **/ 1195 BOOLEAN 1196 EFIAPI 1197 UsbBusIsWantedUsbIO ( 1198 IN USB_BUS *Bus, 1199 IN USB_INTERFACE *UsbIf 1200 ) 1201 { 1202 EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr; 1203 LIST_ENTRY *WantedUsbIoDPListPtr; 1204 LIST_ENTRY *WantedListIndex; 1205 DEVICE_PATH_LIST_ITEM *WantedListItem; 1206 BOOLEAN DoConvert; 1207 UINTN FirstDevicePathSize; 1208 1209 // 1210 // Check whether passed in parameters are valid 1211 // 1212 if ((UsbIf == NULL) || (Bus == NULL)) { 1213 return FALSE; 1214 } 1215 // 1216 // Check whether UsbIf is Hub 1217 // 1218 if (UsbIf->IsHub) { 1219 return TRUE; 1220 } 1221 1222 // 1223 // Check whether all Usb devices in this bus are wanted 1224 // 1225 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL *)&mAllUsbClassDevicePath, &Bus->WantedUsbIoDPList)){ 1226 return TRUE; 1227 } 1228 1229 // 1230 // Check whether the Usb device match any item in WantedUsbIoDPList 1231 // 1232 WantedUsbIoDPListPtr = &Bus->WantedUsbIoDPList; 1233 // 1234 // Create new Usb device path according to the usb part in UsbIo full device path 1235 // 1236 DevicePathPtr = GetUsbDPFromFullDP (UsbIf->DevicePath); 1237 ASSERT (DevicePathPtr != NULL); 1238 1239 DoConvert = FALSE; 1240 WantedListIndex = WantedUsbIoDPListPtr->ForwardLink; 1241 while (WantedListIndex != WantedUsbIoDPListPtr){ 1242 WantedListItem = CR(WantedListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE); 1243 ASSERT (WantedListItem->DevicePath->Type == MESSAGING_DEVICE_PATH); 1244 switch (WantedListItem->DevicePath->SubType) { 1245 case MSG_USB_DP: 1246 FirstDevicePathSize = GetDevicePathSize (WantedListItem->DevicePath); 1247 if (FirstDevicePathSize == GetDevicePathSize (DevicePathPtr)) { 1248 if (CompareMem ( 1249 WantedListItem->DevicePath, 1250 DevicePathPtr, 1251 GetDevicePathSize (DevicePathPtr)) == 0 1252 ) { 1253 DoConvert = TRUE; 1254 } 1255 } 1256 break; 1257 case MSG_USB_CLASS_DP: 1258 if (MatchUsbClass((USB_CLASS_DEVICE_PATH *)WantedListItem->DevicePath, UsbIf)) { 1259 DoConvert = TRUE; 1260 } 1261 break; 1262 case MSG_USB_WWID_DP: 1263 if (MatchUsbWwid((USB_WWID_DEVICE_PATH *)WantedListItem->DevicePath, UsbIf)) { 1264 DoConvert = TRUE; 1265 } 1266 break; 1267 default: 1268 ASSERT (0); 1269 break; 1270 } 1271 1272 if (DoConvert) { 1273 break; 1274 } 1275 1276 WantedListIndex = WantedListIndex->ForwardLink; 1277 } 1278 gBS->FreePool (DevicePathPtr); 1279 1280 // 1281 // Check whether the new Usb device path is wanted 1282 // 1283 if (DoConvert){ 1284 return TRUE; 1285 } else { 1286 return FALSE; 1287 } 1288 } 1289 1290 /** 1291 Recursively connnect every wanted usb child device to ensure they all fully connected. 1292 Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device. 1293 1294 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface. 1295 1296 @retval EFI_SUCCESS Connect is done successfully. 1297 @retval EFI_INVALID_PARAMETER The parameter is invalid. 1298 1299 **/ 1300 EFI_STATUS 1301 EFIAPI 1302 UsbBusRecursivelyConnectWantedUsbIo ( 1303 IN EFI_USB_BUS_PROTOCOL *UsbBusId 1304 ) 1305 { 1306 USB_BUS *Bus; 1307 EFI_STATUS Status; 1308 UINTN Index; 1309 EFI_USB_IO_PROTOCOL *UsbIo; 1310 USB_INTERFACE *UsbIf; 1311 UINTN UsbIoHandleCount; 1312 EFI_HANDLE *UsbIoBuffer; 1313 EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath; 1314 1315 if (UsbBusId == NULL){ 1316 return EFI_INVALID_PARAMETER; 1317 } 1318 1319 Bus = USB_BUS_FROM_THIS (UsbBusId); 1320 1321 // 1322 // Get all Usb IO handles in system 1323 // 1324 UsbIoHandleCount = 0; 1325 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer); 1326 if (Status == EFI_NOT_FOUND || UsbIoHandleCount == 0) { 1327 return EFI_SUCCESS; 1328 } 1329 ASSERT (!EFI_ERROR (Status)); 1330 1331 for (Index = 0; Index < UsbIoHandleCount; Index++) { 1332 // 1333 // Check whether the USB IO handle is a child of this bus 1334 // Note: The usb child handle maybe invalid because of hot plugged out during the loop 1335 // 1336 UsbIoDevicePath = NULL; 1337 Status = gBS->HandleProtocol (UsbIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &UsbIoDevicePath); 1338 if (EFI_ERROR (Status) || UsbIoDevicePath == NULL) { 1339 continue; 1340 } 1341 if (CompareMem ( 1342 UsbIoDevicePath, 1343 Bus->DevicePath, 1344 (GetDevicePathSize (Bus->DevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL)) 1345 ) != 0) { 1346 continue; 1347 } 1348 1349 // 1350 // Get the child Usb IO interface 1351 // 1352 Status = gBS->HandleProtocol( 1353 UsbIoBuffer[Index], 1354 &gEfiUsbIoProtocolGuid, 1355 (VOID **) &UsbIo 1356 ); 1357 if (EFI_ERROR (Status)) { 1358 continue; 1359 } 1360 UsbIf = USB_INTERFACE_FROM_USBIO (UsbIo); 1361 1362 if (UsbBusIsWantedUsbIO (Bus, UsbIf)) { 1363 if (!UsbIf->IsManaged) { 1364 // 1365 // Recursively connect the wanted Usb Io handle 1366 // 1367 DEBUG ((EFI_D_INFO, "UsbConnectDriver: TPL before connect is %d\n", (UINT32)UsbGetCurrentTpl ())); 1368 Status = gBS->ConnectController (UsbIf->Handle, NULL, NULL, TRUE); 1369 UsbIf->IsManaged = (BOOLEAN)!EFI_ERROR (Status); 1370 DEBUG ((EFI_D_INFO, "UsbConnectDriver: TPL after connect is %d\n", (UINT32)UsbGetCurrentTpl())); 1371 } 1372 } 1373 } 1374 1375 FreePool (UsbIoBuffer); 1376 1377 return EFI_SUCCESS; 1378 } 1379 1380