]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
837a6001dd44262c670e95f0720374a0a4835412
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbBus / Dxe / usbbus.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 UsbBus.c
15
16 Abstract:
17
18 USB Bus Driver
19
20 Revision History
21
22 --*/
23
24 #include "usbbus.h"
25
26
27 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gUSBDebugLevel = EFI_D_INFO;
28 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gUSBErrorLevel = EFI_D_ERROR;
29
30 //
31 // The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER
32 // structure in the UsbBusDriverControllerDriverStop(). Then we can
33 // Close all opened protocols and release this structure.
34 //
35 STATIC EFI_GUID mUsbBusProtocolGuid = EFI_USB_BUS_PROTOCOL_GUID;
36
37
38
39 //
40 // EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
41 //
42 EFI_STATUS
43 EFIAPI
44 UsbBusControllerDriverSupported (
45 IN EFI_DRIVER_BINDING_PROTOCOL *This,
46 IN EFI_HANDLE Controller,
47 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
48 );
49
50 EFI_STATUS
51 EFIAPI
52 UsbBusControllerDriverStart (
53 IN EFI_DRIVER_BINDING_PROTOCOL *This,
54 IN EFI_HANDLE Controller,
55 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
56 );
57
58 EFI_STATUS
59 EFIAPI
60 UsbBusControllerDriverStop (
61 IN EFI_DRIVER_BINDING_PROTOCOL *This,
62 IN EFI_HANDLE Controller,
63 IN UINTN NumberOfChildren,
64 IN EFI_HANDLE *ChildHandleBuffer
65 );
66
67 EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding = {
68 UsbBusControllerDriverSupported,
69 UsbBusControllerDriverStart,
70 UsbBusControllerDriverStop,
71 0xa,
72 NULL,
73 NULL
74 };
75
76 //
77 // Internal use only
78 //
79 STATIC
80 EFI_STATUS
81 ReportUsbStatusCode (
82 IN USB_BUS_CONTROLLER_DEVICE *UsbBusController,
83 IN EFI_STATUS_CODE_TYPE Type,
84 IN EFI_STATUS_CODE_VALUE Code
85 );
86
87 //
88 // Supported function
89 //
90 VOID
91 InitializeUsbIoInstance (
92 IN USB_IO_CONTROLLER_DEVICE *UsbIoController
93 );
94
95 STATIC
96 USB_IO_CONTROLLER_DEVICE *
97 CreateUsbIoControllerDevice (
98 VOID
99 );
100
101 STATIC
102 EFI_STATUS
103 InitUsbIoController (
104 IN USB_IO_CONTROLLER_DEVICE *UsbIoController
105 );
106
107 //
108 // USB Device Configuration / Deconfiguration
109 //
110 STATIC
111 EFI_STATUS
112 UsbDeviceConfiguration (
113 IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
114 IN EFI_HANDLE HostController,
115 IN UINT8 ParentPort,
116 IN USB_IO_DEVICE *UsbIoDevice
117 );
118
119 //
120 // Usb Bus enumeration function
121 //
122 STATIC
123 VOID
124 RootHubEnumeration (
125 IN EFI_EVENT Event,
126 IN VOID *Context
127 );
128
129 STATIC
130 VOID
131 HubEnumeration (
132 IN EFI_EVENT Event,
133 IN VOID *Context
134 );
135
136 STATIC
137 EFI_STATUS
138 UsbSetTransactionTranslator (
139 IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
140 IN UINT8 ParentPort,
141 IN OUT USB_IO_DEVICE *Device
142 );
143
144 STATIC
145 EFI_STATUS
146 UsbUnsetTransactionTranslator (
147 USB_IO_DEVICE *Device
148 );
149
150 STATIC
151 EFI_STATUS
152 IdentifyDeviceSpeed (
153 USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
154 USB_IO_DEVICE *NewDevice,
155 UINT8 Index
156 );
157
158 STATIC
159 EFI_STATUS
160 ReleasePortToCHC (
161 USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
162 UINT8 PortNum
163 );
164
165 EFI_STATUS
166 ResetRootPort (
167 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
168 IN UINT8 PortNum,
169 IN UINT8 RetryTimes
170 );
171
172 EFI_STATUS
173 ResetHubPort (
174 IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
175 IN UINT8 PortIndex
176 );
177
178 STATIC
179 EFI_STATUS
180 ParentPortReset (
181 IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
182 IN BOOLEAN ReConfigure,
183 IN UINT8 RetryTimes
184 );
185
186 //
187 // Following are address allocate and free functions
188 //
189 STATIC
190 UINT8
191 UsbAllocateAddress (
192 IN UINT8 *AddressPool
193 )
194 /*++
195
196 Routine Description:
197 Allocate address for usb device
198
199 Arguments:
200 AddressPool - Pool of usb device address
201
202 Returns:
203 Usb device address
204
205 --*/
206 {
207 UINT8 ByteIndex;
208 UINT8 BitIndex;
209
210 for (ByteIndex = 0; ByteIndex < 16; ByteIndex++) {
211 for (BitIndex = 0; BitIndex < 8; BitIndex++) {
212 if ((AddressPool[ByteIndex] & (1 << BitIndex)) == 0) {
213 //
214 // Found one, covert to address, and mark it use
215 //
216 AddressPool[ByteIndex] |= (1 << BitIndex);
217 return (UINT8) (ByteIndex * 8 + BitIndex);
218 }
219 }
220 }
221
222 return 0;
223
224 }
225
226 STATIC
227 VOID
228 UsbFreeAddress (
229 IN UINT8 DevAddress,
230 IN UINT8 *AddressPool
231 )
232 /*++
233
234 Routine Description:
235 Free address for usb device
236
237 Arguments:
238 DevAddress - Usb device address
239 AddressPool - Pool of usb device address
240
241 Returns:
242 VOID
243
244 --*/
245 {
246 UINT8 WhichByte;
247 UINT8 WhichBit;
248 //
249 // Locate the position
250 //
251 WhichByte = (UINT8) (DevAddress / 8);
252 WhichBit = (UINT8) (DevAddress & 0x7);
253
254 AddressPool[WhichByte] &= (~(1 << WhichBit));
255 }
256
257 EFI_STATUS
258 EFIAPI
259 UsbBusControllerDriverSupported (
260 IN EFI_DRIVER_BINDING_PROTOCOL *This,
261 IN EFI_HANDLE Controller,
262 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
263 )
264 /*++
265
266 Routine Description:
267 Test to see if this driver supports ControllerHandle. Any ControllerHandle
268 that has UsbHcProtocol installed will be supported.
269
270 Arguments:
271 This - Protocol instance pointer.
272 Controller - Handle of device to test
273 RemainingDevicePath - Device Path Protocol instance pointer
274
275 Returns:
276 EFI_SUCCESS - This driver supports this device.
277 EFI_UNSUPPORTED - This driver does not support this device.
278
279 --*/
280 {
281 EFI_STATUS Status;
282 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
283 EFI_USB2_HC_PROTOCOL *Usb2Hc;
284 EFI_USB_HC_PROTOCOL *UsbHc;
285 EFI_DEV_PATH_PTR Node;
286
287 //
288 // Check Device Path
289 //
290 if (RemainingDevicePath != NULL) {
291 Node.DevPath = RemainingDevicePath;
292 if (Node.DevPath->Type != MESSAGING_DEVICE_PATH ||
293 Node.DevPath->SubType != MSG_USB_DP ||
294 DevicePathNodeLength(Node.DevPath) != sizeof(USB_DEVICE_PATH)) {
295 return EFI_UNSUPPORTED;
296 }
297 }
298
299 //
300 // Open the IO Abstraction(s) needed to perform the supported test
301 //
302 Status = gBS->OpenProtocol (
303 Controller,
304 &gEfiDevicePathProtocolGuid,
305 (VOID **) &ParentDevicePath,
306 This->DriverBindingHandle,
307 Controller,
308 EFI_OPEN_PROTOCOL_BY_DRIVER
309 );
310 if (Status == EFI_ALREADY_STARTED) {
311 return EFI_SUCCESS;
312 }
313
314 if (EFI_ERROR (Status)) {
315 return Status;
316 }
317
318 gBS->CloseProtocol (
319 Controller,
320 &gEfiDevicePathProtocolGuid,
321 This->DriverBindingHandle,
322 Controller
323 );
324
325 //
326 // Check whether USB Host Controller Protocol is already
327 // installed on this handle. If it is installed, we can start
328 // USB Bus Driver now.
329 //
330 Status = gBS->OpenProtocol (
331 Controller,
332 &gEfiUsb2HcProtocolGuid,
333 (VOID **) &Usb2Hc,
334 This->DriverBindingHandle,
335 Controller,
336 EFI_OPEN_PROTOCOL_BY_DRIVER
337 );
338 if (Status == EFI_ALREADY_STARTED) {
339 return EFI_SUCCESS;
340 }
341
342 if (EFI_ERROR (Status)) {
343 Status = gBS->OpenProtocol (
344 Controller,
345 &gEfiUsbHcProtocolGuid,
346 (VOID **) &UsbHc,
347 This->DriverBindingHandle,
348 Controller,
349 EFI_OPEN_PROTOCOL_BY_DRIVER
350 );
351 if (Status == EFI_ALREADY_STARTED) {
352 return EFI_SUCCESS;
353 }
354
355 if (EFI_ERROR (Status)) {
356 return Status;
357 }
358
359 gBS->CloseProtocol (
360 Controller,
361 &gEfiUsbHcProtocolGuid,
362 This->DriverBindingHandle,
363 Controller
364 );
365 return EFI_SUCCESS;
366 }
367
368 gBS->CloseProtocol (
369 Controller,
370 &gEfiUsb2HcProtocolGuid,
371 This->DriverBindingHandle,
372 Controller
373 );
374
375 return EFI_SUCCESS;
376 }
377
378 EFI_STATUS
379 EFIAPI
380 UsbBusControllerDriverStart (
381 IN EFI_DRIVER_BINDING_PROTOCOL *This,
382 IN EFI_HANDLE Controller,
383 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
384 )
385 /*++
386
387 Routine Description:
388
389 Starting the Usb Bus Driver
390
391 Arguments:
392
393 This - Protocol instance pointer.
394 Controller - Handle of device to test
395 RemainingDevicePath - Not used
396
397 Returns:
398
399 EFI_SUCCESS - This driver supports this device.
400 EFI_DEVICE_ERROR - This driver cannot be started due to device
401 EFI_OUT_OF_RESOURCES- Can't allocate memory resources
402
403 --*/
404 {
405 EFI_STATUS Status;
406 EFI_STATUS OpenStatus;
407 USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
408 USB_IO_DEVICE *RootHub;
409 USB_IO_CONTROLLER_DEVICE *RootHubController;
410 UINT8 MaxSpeed;
411 UINT8 PortNumber;
412 UINT8 Is64BitCapable;
413
414 //
415 // Allocate USB_BUS_CONTROLLER_DEVICE structure
416 //
417 UsbBusDev = NULL;
418 UsbBusDev = AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE));
419 if (UsbBusDev == NULL) {
420 return EFI_OUT_OF_RESOURCES;
421 }
422
423 UsbBusDev->Signature = USB_BUS_DEVICE_SIGNATURE;
424 UsbBusDev->AddressPool[0] = 1;
425
426 //
427 // Get the Device Path Protocol on Controller's handle
428 //
429 OpenStatus = gBS->OpenProtocol (
430 Controller,
431 &gEfiDevicePathProtocolGuid,
432 (VOID **) &UsbBusDev->DevicePath,
433 This->DriverBindingHandle,
434 Controller,
435 EFI_OPEN_PROTOCOL_BY_DRIVER
436 );
437
438 if (EFI_ERROR (OpenStatus)) {
439 gBS->FreePool (UsbBusDev);
440 return OpenStatus;
441 }
442 //
443 // Locate the Host Controller Interface
444 //
445 OpenStatus = gBS->OpenProtocol (
446 Controller,
447 &gEfiUsb2HcProtocolGuid,
448 (VOID **) &(UsbBusDev->Usb2HCInterface),
449 This->DriverBindingHandle,
450 Controller,
451 EFI_OPEN_PROTOCOL_BY_DRIVER
452 );
453 if (EFI_ERROR (OpenStatus)) {
454
455 UsbBusDev->Hc2ProtocolSupported = FALSE;
456 OpenStatus = gBS->OpenProtocol (
457 Controller,
458 &gEfiUsbHcProtocolGuid,
459 (VOID **) &(UsbBusDev->UsbHCInterface),
460 This->DriverBindingHandle,
461 Controller,
462 EFI_OPEN_PROTOCOL_BY_DRIVER
463 );
464 if (EFI_ERROR (OpenStatus)) {
465 //
466 // Report Status Code here since we will reset the host controller
467 //
468 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
469 EFI_ERROR_CODE | EFI_ERROR_MINOR,
470 EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,
471 UsbBusDev->DevicePath
472 );
473
474 gBS->CloseProtocol (
475 Controller,
476 &gEfiDevicePathProtocolGuid,
477 This->DriverBindingHandle,
478 Controller
479 );
480 gBS->FreePool (UsbBusDev);
481 return OpenStatus;
482 }
483
484 DEBUG ((gUSBDebugLevel, "UsbHcProtocol Opened.\n"));
485 } else {
486 DEBUG ((gUSBDebugLevel, "Usb2HcProtocol Opened.\n"));
487 UsbBusDev->Hc2ProtocolSupported = TRUE;
488 }
489
490 //
491 // Attach EFI_USB_BUS_PROTOCOL to controller handle,
492 // for locate UsbBusDev later
493 //
494 Status = gBS->InstallProtocolInterface (
495 &Controller,
496 &mUsbBusProtocolGuid,
497 EFI_NATIVE_INTERFACE,
498 &UsbBusDev->BusIdentify
499 );
500
501 if (EFI_ERROR (Status)) {
502
503 gBS->CloseProtocol (
504 Controller,
505 &gEfiDevicePathProtocolGuid,
506 This->DriverBindingHandle,
507 Controller
508 );
509 if (UsbBusDev->Hc2ProtocolSupported) {
510 gBS->CloseProtocol (
511 Controller,
512 &gEfiUsb2HcProtocolGuid,
513 This->DriverBindingHandle,
514 Controller
515 );
516 } else {
517 gBS->CloseProtocol (
518 Controller,
519 &gEfiUsbHcProtocolGuid,
520 This->DriverBindingHandle,
521 Controller
522 );
523 }
524
525 gBS->FreePool (UsbBusDev);
526 return Status;
527 }
528 //
529 // Add root hub to the tree
530 //
531 RootHub = NULL;
532 RootHub = AllocateZeroPool (sizeof (USB_IO_DEVICE));
533 if (RootHub == NULL) {
534 gBS->UninstallProtocolInterface (
535 Controller,
536 &mUsbBusProtocolGuid,
537 &UsbBusDev->BusIdentify
538 );
539 gBS->CloseProtocol (
540 Controller,
541 &gEfiDevicePathProtocolGuid,
542 This->DriverBindingHandle,
543 Controller
544 );
545 if (UsbBusDev->Hc2ProtocolSupported) {
546 gBS->CloseProtocol (
547 Controller,
548 &gEfiUsb2HcProtocolGuid,
549 This->DriverBindingHandle,
550 Controller
551 );
552 } else {
553 gBS->CloseProtocol (
554 Controller,
555 &gEfiUsbHcProtocolGuid,
556 This->DriverBindingHandle,
557 Controller
558 );
559 }
560
561 gBS->FreePool (UsbBusDev);
562 return EFI_OUT_OF_RESOURCES;
563 }
564
565 RootHub->BusController = UsbBusDev;
566 RootHub->DeviceAddress = UsbAllocateAddress (UsbBusDev->AddressPool);
567
568 UsbBusDev->Root = RootHub;
569
570 //
571 // Allocate Root Hub Controller
572 //
573 RootHubController = CreateUsbIoControllerDevice ();
574 if (RootHubController == NULL) {
575 gBS->UninstallProtocolInterface (
576 Controller,
577 &mUsbBusProtocolGuid,
578 &UsbBusDev->BusIdentify
579 );
580 gBS->CloseProtocol (
581 Controller,
582 &gEfiDevicePathProtocolGuid,
583 This->DriverBindingHandle,
584 Controller
585 );
586 if (UsbBusDev->Hc2ProtocolSupported) {
587 gBS->CloseProtocol (
588 Controller,
589 &gEfiUsb2HcProtocolGuid,
590 This->DriverBindingHandle,
591 Controller
592 );
593 } else {
594 gBS->CloseProtocol (
595 Controller,
596 &gEfiUsbHcProtocolGuid,
597 This->DriverBindingHandle,
598 Controller
599 );
600 }
601 gBS->FreePool (UsbBusDev);
602 gBS->FreePool (RootHub);
603 return EFI_OUT_OF_RESOURCES;
604 }
605
606 UsbVirtualHcGetCapability (
607 UsbBusDev,
608 &MaxSpeed,
609 &PortNumber,
610 &Is64BitCapable
611 );
612 RootHubController->DownstreamPorts = PortNumber;
613 RootHubController->UsbDevice = RootHub;
614 RootHubController->IsUsbHub = TRUE;
615 RootHubController->DevicePath = UsbBusDev->DevicePath;
616 RootHubController->HostController = Controller;
617
618 RootHub->NumOfControllers = 1;
619 RootHub->UsbController[0] = RootHubController;
620 RootHub->DeviceSpeed = MaxSpeed;
621
622 //
623 // Report Status Code here since we will reset the host controller
624 //
625 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
626 EFI_PROGRESS_CODE,
627 EFI_IO_BUS_USB | EFI_IOB_PC_RESET,
628 UsbBusDev->DevicePath
629 );
630
631 //
632 // Reset USB Host Controller
633 //
634 UsbVirtualHcReset (
635 UsbBusDev,
636 EFI_USB_HC_RESET_GLOBAL
637 );
638
639 //
640 // Report Status Code while we are going to bring up the Host Controller
641 // and start bus enumeration
642 //
643 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
644 EFI_PROGRESS_CODE,
645 EFI_IO_BUS_USB | EFI_IOB_PC_ENABLE,
646 UsbBusDev->DevicePath
647 );
648
649 //
650 // Start USB Host Controller
651 //
652 UsbVirtualHcSetState (
653 UsbBusDev,
654 EfiUsbHcStateOperational
655 );
656
657 //
658 // Create a timer to query root ports periodically
659 //
660 Status = gBS->CreateEvent (
661 EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
662 EFI_TPL_CALLBACK,
663 RootHubEnumeration,
664 RootHubController,
665 &RootHubController->HubNotify
666 );
667 if (EFI_ERROR (Status)) {
668 gBS->UninstallProtocolInterface (
669 Controller,
670 &mUsbBusProtocolGuid,
671 &UsbBusDev->BusIdentify
672 );
673
674 gBS->CloseProtocol (
675 Controller,
676 &gEfiDevicePathProtocolGuid,
677 This->DriverBindingHandle,
678 Controller
679 );
680
681 if (UsbBusDev->Hc2ProtocolSupported) {
682 gBS->CloseProtocol (
683 Controller,
684 &gEfiUsb2HcProtocolGuid,
685 This->DriverBindingHandle,
686 Controller
687 );
688 } else {
689 gBS->CloseProtocol (
690 Controller,
691 &gEfiUsbHcProtocolGuid,
692 This->DriverBindingHandle,
693 Controller
694 );
695 }
696
697 gBS->FreePool (RootHubController);
698 gBS->FreePool (RootHub);
699 gBS->FreePool (UsbBusDev);
700 return EFI_OUT_OF_RESOURCES;
701 }
702
703 //
704 // Before depending on the timer to check root ports periodically,
705 // here we should check them immediately for the first time, or
706 // there will be an interval between bus start and devices start.
707 //
708 gBS->SignalEvent (RootHubController->HubNotify);
709
710 Status = gBS->SetTimer (
711 RootHubController->HubNotify,
712 TimerPeriodic,
713 BUSPOLLING_PERIOD
714 );
715 if (EFI_ERROR (Status)) {
716 gBS->UninstallProtocolInterface (
717 Controller,
718 &mUsbBusProtocolGuid,
719 &UsbBusDev->BusIdentify
720 );
721
722 gBS->CloseProtocol (
723 Controller,
724 &gEfiDevicePathProtocolGuid,
725 This->DriverBindingHandle,
726 Controller
727 );
728
729 if (UsbBusDev->Hc2ProtocolSupported) {
730 gBS->CloseProtocol (
731 Controller,
732 &gEfiUsb2HcProtocolGuid,
733 This->DriverBindingHandle,
734 Controller
735 );
736 } else {
737 gBS->CloseProtocol (
738 Controller,
739 &gEfiUsbHcProtocolGuid,
740 This->DriverBindingHandle,
741 Controller
742 );
743 }
744
745 gBS->CloseEvent (RootHubController->HubNotify);
746 gBS->FreePool (RootHubController);
747 gBS->FreePool (RootHub);
748 gBS->FreePool (UsbBusDev);
749 return EFI_DEVICE_ERROR;
750 }
751
752 return EFI_SUCCESS;
753 }
754
755 //
756 // Stop the bus controller
757 //
758 EFI_STATUS
759 EFIAPI
760 UsbBusControllerDriverStop (
761 IN EFI_DRIVER_BINDING_PROTOCOL *This,
762 IN EFI_HANDLE Controller,
763 IN UINTN NumberOfChildren,
764 IN EFI_HANDLE *ChildHandleBuffer
765 )
766 /*++
767
768 Routine Description:
769 Stop this driver on ControllerHandle. Support stoping any child handles
770 created by this driver.
771
772 Arguments:
773 This - Protocol instance pointer.
774 Controller - Handle of device to stop driver on
775 NumberOfChildren - Number of Children in the ChildHandleBuffer
776 ChildHandleBuffer - List of handles for the children we need to stop.
777
778 Returns:
779 EFI_SUCCESS
780 EFI_DEVICE_ERROR
781 others
782
783 --*/
784 {
785 EFI_STATUS Status;
786 USB_IO_DEVICE *Root;
787 USB_IO_CONTROLLER_DEVICE *RootHubController;
788 USB_BUS_CONTROLLER_DEVICE *UsbBusController;
789 EFI_USB_BUS_PROTOCOL *UsbIdentifier;
790 UINT8 Index2;
791 USB_IO_CONTROLLER_DEVICE *UsbController;
792 USB_IO_DEVICE *UsbIoDevice;
793 USB_IO_CONTROLLER_DEVICE *HubController;
794 UINTN Index;
795 EFI_USB_IO_PROTOCOL *UsbIo;
796
797 if (NumberOfChildren > 0) {
798
799 for (Index = 0; Index < NumberOfChildren; Index++) {
800 Status = gBS->OpenProtocol (
801 ChildHandleBuffer[Index],
802 &gEfiUsbIoProtocolGuid,
803 (VOID **) &UsbIo,
804 This->DriverBindingHandle,
805 Controller,
806 EFI_OPEN_PROTOCOL_GET_PROTOCOL
807 );
808 if (EFI_ERROR (Status)) {
809 //
810 // We are here since the handle passed in does not support
811 // UsbIo protocol. There are several reasons that will cause
812 // this.
813 // For combo device such as keyboard, it may have 2 devices
814 // in one, namely, keyboard and mouse. If we deconfigure one
815 // of them, the other will be freed at the same time. This will
816 // cause the status error. But this is the correct behavior.
817 // For hub device, if we deconfigure hub first, the other chile
818 // device will be disconnected also, this will also provide us
819 // a status error. Now we will only report EFI_SUCCESS since Uhc
820 // driver will be disconnected at the second time.(pls see
821 // CoreDisconnectController for details)
822 //
823 continue;
824 }
825
826 UsbController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo);
827 UsbIoDevice = UsbController->UsbDevice;
828 HubController = UsbController->Parent;
829 UsbDeviceDeConfiguration (UsbIoDevice);
830 for (Index2 = 0; Index2 < HubController->DownstreamPorts; Index2++) {
831 if (HubController->Children[Index2] == UsbIoDevice) {
832 HubController->Children[Index2] = NULL;
833 }
834 }
835 }
836
837 return EFI_SUCCESS;
838 }
839 //
840 // Get the USB_BUS_CONTROLLER_DEVICE
841 //
842 Status = gBS->OpenProtocol (
843 Controller,
844 &mUsbBusProtocolGuid,
845 (VOID **) &UsbIdentifier,
846 This->DriverBindingHandle,
847 Controller,
848 EFI_OPEN_PROTOCOL_GET_PROTOCOL
849 );
850
851 if (EFI_ERROR (Status)) {
852 return EFI_DEVICE_ERROR;
853 }
854
855 UsbBusController = USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier);
856
857 //
858 // Stop USB Host Controller
859 //
860
861 //
862 // Report Status Code here since we will reset the host controller
863 //
864 ReportUsbStatusCode (
865 UsbBusController,
866 EFI_PROGRESS_CODE,
867 EFI_IO_BUS_USB | EFI_IOB_PC_RESET
868 );
869
870 UsbVirtualHcSetState (
871 UsbBusController,
872 EfiUsbHcStateHalt
873 );
874
875 //
876 // Deconfiguration all its devices
877 //
878 Root = UsbBusController->Root;
879 RootHubController = Root->UsbController[0];
880
881 gBS->CloseEvent (RootHubController->HubNotify);
882
883 for (Index2 = 0; Index2 < RootHubController->DownstreamPorts; Index2++) {
884 if (RootHubController->Children[Index2]) {
885 UsbDeviceDeConfiguration (RootHubController->Children[Index2]);
886 RootHubController->Children[Index2] = NULL;
887 }
888 }
889
890 gBS->FreePool (RootHubController);
891 gBS->FreePool (Root);
892
893 //
894 // Uninstall USB Bus Protocol
895 //
896 gBS->UninstallProtocolInterface (
897 Controller,
898 &mUsbBusProtocolGuid,
899 &UsbBusController->BusIdentify
900 );
901
902 //
903 // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
904 // Opened by this Controller
905 //
906 if (UsbBusController->Hc2ProtocolSupported) {
907 gBS->CloseProtocol (
908 Controller,
909 &gEfiUsb2HcProtocolGuid,
910 This->DriverBindingHandle,
911 Controller
912 );
913 } else {
914 gBS->CloseProtocol (
915 Controller,
916 &gEfiUsbHcProtocolGuid,
917 This->DriverBindingHandle,
918 Controller
919 );
920 }
921
922 gBS->CloseProtocol (
923 Controller,
924 &gEfiDevicePathProtocolGuid,
925 This->DriverBindingHandle,
926 Controller
927 );
928
929 gBS->FreePool (UsbBusController);
930
931 return EFI_SUCCESS;
932 }
933 //
934 // USB Device Configuration
935 //
936 STATIC
937 EFI_STATUS
938 UsbDeviceConfiguration (
939 IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
940 IN EFI_HANDLE HostController,
941 IN UINT8 ParentPort,
942 IN USB_IO_DEVICE *UsbIoDevice
943 )
944 /*++
945
946 Routine Description:
947 Configurate a new device attached to the usb bus
948
949 Arguments:
950 ParentHubController - Parent Hub which this device is connected.
951 HostController - Host Controller handle
952 ParentPort - Parent Hub port which this device is connected.
953 UsbIoDevice - The device to be configured.
954
955 Returns:
956 EFI_SUCCESS
957 EFI_DEVICE_ERROR
958 EFI_OUT_OF_RESOURCES
959
960 --*/
961 {
962 UINT8 DevAddress;
963 UINT8 Index;
964 EFI_STATUS Result;
965 UINT32 Status;
966 CHAR16 *StrManufacturer;
967 CHAR16 *StrProduct;
968 CHAR16 *StrSerialNumber;
969 EFI_USB_IO_PROTOCOL *UsbIo;
970 UINT8 NumOfInterface;
971 USB_IO_CONTROLLER_DEVICE *FirstController;
972 USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
973 USB_IO_CONTROLLER_DEVICE *UsbIoController;
974
975 UsbBusDev = UsbIoDevice->BusController;
976
977 UsbSetTransactionTranslator (
978 ParentHubController,
979 ParentPort,
980 UsbIoDevice
981 );
982
983 //
984 // Since a USB device must have at least on interface,
985 // so create this instance first
986 //
987 FirstController = CreateUsbIoControllerDevice ();
988 FirstController->UsbDevice = UsbIoDevice;
989 UsbIoDevice->UsbController[0] = FirstController;
990 FirstController->InterfaceNumber = 0;
991 FirstController->ParentPort = ParentPort;
992 FirstController->Parent = ParentHubController;
993 FirstController->HostController = HostController;
994
995 InitializeUsbIoInstance (FirstController);
996
997 DEBUG ((gUSBDebugLevel, "Configuration Usb Device at 0x%x...\n", ParentPort));
998
999 //
1000 // Ensure we used the correctly USB I/O instance
1001 //
1002 UsbIo = &FirstController->UsbIo;
1003
1004 if (UsbIoDevice->DeviceSpeed != EFI_USB_SPEED_HIGH) {
1005 ParentPortReset (FirstController, FALSE, 0);
1006 }
1007
1008 //
1009 // First retrieve the 1st 8 bytes of
1010 // in order to get the MaxPacketSize for Endpoint 0
1011 //
1012 for (Index = 0; Index < 3; Index++) {
1013
1014 UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;
1015
1016 gBS->Stall (100 * 1000);
1017
1018 Result = UsbGetDescriptor (
1019 UsbIo,
1020 (USB_DT_DEVICE << 8),
1021 0,
1022 8,
1023 &UsbIoDevice->DeviceDescriptor,
1024 &Status
1025 );
1026 if (!EFI_ERROR (Result)) {
1027 DEBUG (
1028 (gUSBDebugLevel,
1029 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
1030 UsbIoDevice->DeviceDescriptor.MaxPacketSize0)
1031 );
1032 break;
1033 }
1034
1035 }
1036
1037 if (Index == 3) {
1038 ReportUsbStatusCode (
1039 UsbBusDev,
1040 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1041 EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
1042 );
1043 DEBUG ((gUSBErrorLevel, "Get Device Descriptor Fail when configing\n"));
1044 gBS->FreePool (FirstController);
1045 return EFI_DEVICE_ERROR;
1046 }
1047
1048 DevAddress = UsbAllocateAddress (UsbIoDevice->BusController->AddressPool);
1049 if (DevAddress == 0) {
1050 DEBUG ((gUSBErrorLevel, "Cannot allocate address\n"));
1051 gBS->FreePool (FirstController);
1052 return EFI_OUT_OF_RESOURCES;
1053 }
1054
1055 Result = UsbSetDeviceAddress (UsbIo, DevAddress, &Status);
1056
1057 if (EFI_ERROR (Result)) {
1058 DEBUG ((gUSBErrorLevel, "Set address error\n"));
1059 ReportUsbStatusCode (
1060 UsbBusDev,
1061 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1062 EFI_IO_BUS_USB | EFI_IOB_EC_WRITE_ERROR
1063 );
1064
1065 UsbFreeAddress (
1066 DevAddress,
1067 UsbIoDevice->BusController->AddressPool
1068 );
1069
1070 gBS->FreePool (FirstController);
1071 return EFI_DEVICE_ERROR;
1072 }
1073
1074 UsbIoDevice->DeviceAddress = DevAddress;
1075
1076 //
1077 // SetAddress Complete Time by Spec, Max 50ms
1078 //
1079 gBS->Stall (10 * 1000);
1080
1081 //
1082 // Get the whole device descriptor
1083 //
1084 Result = UsbGetDescriptor (
1085 UsbIo,
1086 (USB_DT_DEVICE << 8),
1087 0,
1088 sizeof (EFI_USB_DEVICE_DESCRIPTOR),
1089 &UsbIoDevice->DeviceDescriptor,
1090 &Status
1091 );
1092
1093 if (EFI_ERROR (Result)) {
1094 DEBUG ((gUSBErrorLevel, "Get whole Device Descriptor error\n"));
1095 ReportUsbStatusCode (
1096 UsbBusDev,
1097 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1098 EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
1099 );
1100 UsbFreeAddress (
1101 DevAddress,
1102 UsbIoDevice->BusController->AddressPool
1103 );
1104
1105 gBS->FreePool (FirstController);
1106 return EFI_DEVICE_ERROR;
1107 }
1108 //
1109 // Get & parse all configurations for this device, including
1110 // all configuration descriptors, all interface descriptors, all
1111 // endpoint descriptors
1112 //
1113 Result = UsbGetAllConfigurations (UsbIoDevice);
1114
1115 if (EFI_ERROR (Result)) {
1116 DEBUG ((gUSBErrorLevel, "Failed to get device configuration\n"));
1117 ReportUsbStatusCode (
1118 UsbBusDev,
1119 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1120 EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
1121 );
1122 UsbFreeAddress (
1123 DevAddress,
1124 UsbIoDevice->BusController->AddressPool
1125 );
1126
1127 gBS->FreePool (FirstController);
1128 return EFI_DEVICE_ERROR;
1129 }
1130 //
1131 // Set the 1st configuration value
1132 //
1133 Result = UsbSetDefaultConfiguration (UsbIoDevice);
1134 if (EFI_ERROR (Result)) {
1135 DEBUG ((gUSBErrorLevel, "Failed to set device configuration\n"));
1136 ReportUsbStatusCode (
1137 UsbBusDev,
1138 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1139 EFI_IO_BUS_USB | EFI_IOB_EC_WRITE_ERROR
1140 );
1141 UsbFreeAddress (
1142 DevAddress,
1143 UsbIoDevice->BusController->AddressPool
1144 );
1145
1146 gBS->FreePool (FirstController);
1147 return EFI_DEVICE_ERROR;
1148 }
1149
1150 UsbIoDevice->IsConfigured = TRUE;
1151
1152 //
1153 // Get all string table if applicable
1154 //
1155 Result = UsbGetStringtable (UsbIoDevice);
1156 if (EFI_ERROR (Result)) {
1157 DEBUG ((gUSBDebugLevel, "Device doesn't support string table\n"));
1158 } else {
1159
1160 StrManufacturer = NULL;
1161 UsbIo->UsbGetStringDescriptor (
1162 UsbIo,
1163 UsbIoDevice->LangID[0],
1164 (UsbIoDevice->DeviceDescriptor).StrManufacturer,
1165 &StrManufacturer
1166 );
1167
1168 StrProduct = NULL;
1169 UsbIo->UsbGetStringDescriptor (
1170 UsbIo,
1171 UsbIoDevice->LangID[0],
1172 (UsbIoDevice->DeviceDescriptor).StrProduct,
1173 &StrProduct
1174 );
1175
1176 StrSerialNumber = NULL;
1177 UsbIo->UsbGetStringDescriptor (
1178 UsbIo,
1179 UsbIoDevice->LangID[0],
1180 (UsbIoDevice->DeviceDescriptor).StrSerialNumber,
1181 &StrSerialNumber
1182 );
1183
1184 if (StrManufacturer) {
1185 gBS->FreePool (StrManufacturer);
1186 }
1187
1188 if (StrProduct) {
1189 gBS->FreePool (StrProduct);
1190 }
1191
1192 if (StrSerialNumber) {
1193 gBS->FreePool (StrSerialNumber);
1194 }
1195 }
1196 //
1197 // Create USB_IO_CONTROLLER_DEVICE for
1198 // each detected interface
1199 //
1200 FirstController->CurrentConfigValue =
1201 UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;
1202
1203 NumOfInterface =
1204 UsbIoDevice->ActiveConfig->CongfigDescriptor.NumInterfaces;
1205 UsbIoDevice->NumOfControllers = NumOfInterface;
1206
1207 Result = InitUsbIoController (FirstController);
1208 if (EFI_ERROR (Result)) {
1209 ReportUsbStatusCode (
1210 UsbBusDev,
1211 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1212 EFI_IO_BUS_USB | EFI_IOB_EC_INTERFACE_ERROR
1213 );
1214 gBS->FreePool (FirstController);
1215 UsbIoDevice->UsbController[0] = NULL;
1216 return EFI_DEVICE_ERROR;
1217 }
1218
1219 for (Index = 1; Index < NumOfInterface; Index++) {
1220 UsbIoController = CreateUsbIoControllerDevice ();
1221 UsbIoController->UsbDevice = UsbIoDevice;
1222 UsbIoController->CurrentConfigValue =
1223 UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;
1224 UsbIoController->InterfaceNumber = Index;
1225 UsbIoDevice->UsbController[Index] = UsbIoController;
1226 UsbIoController->ParentPort = ParentPort;
1227 UsbIoController->Parent = ParentHubController;
1228 UsbIoController->HostController = HostController;
1229
1230 //
1231 // First copy the USB_IO Protocol instance
1232 //
1233 CopyMem (
1234 &UsbIoController->UsbIo,
1235 UsbIo,
1236 sizeof (EFI_USB_IO_PROTOCOL)
1237 );
1238
1239 Result = InitUsbIoController (UsbIoController);
1240 if (EFI_ERROR (Result)) {
1241 ReportUsbStatusCode (
1242 UsbBusDev,
1243 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1244 EFI_IO_BUS_USB | EFI_IOB_EC_INTERFACE_ERROR
1245 );
1246 gBS->FreePool (UsbIoController);
1247 UsbIoDevice->UsbController[Index] = NULL;
1248 }
1249 }
1250
1251 return EFI_SUCCESS;
1252 }
1253 //
1254 // USB Device DeConfiguration
1255 //
1256 EFI_STATUS
1257 UsbDeviceDeConfiguration (
1258 IN USB_IO_DEVICE *UsbIoDevice
1259 )
1260 /*++
1261
1262 Routine Description:
1263 Remove Device, Device Handles, Uninstall Protocols.
1264
1265 Arguments:
1266 UsbIoDevice - The device to be deconfigured.
1267
1268 Returns:
1269 EFI_SUCCESS
1270 EFI_DEVICE_ERROR
1271
1272 --*/
1273 {
1274 USB_IO_CONTROLLER_DEVICE *UsbController;
1275 UINT8 index;
1276 USB_IO_DEVICE *ChildDevice;
1277 UINT8 Index;
1278 EFI_USB_IO_PROTOCOL *UsbIo;
1279
1280 //
1281 // Double check UsbIoDevice exists
1282 //
1283 if (UsbIoDevice == NULL) {
1284 return EFI_SUCCESS;
1285 }
1286
1287 UsbUnsetTransactionTranslator (UsbIoDevice);
1288
1289 for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {
1290 //
1291 // Check if it is a hub, if so, de configuration all its
1292 // downstream ports
1293 //
1294 UsbController = UsbIoDevice->UsbController[index];
1295
1296 //
1297 // Check the controller pointer
1298 //
1299 if (UsbController == NULL) {
1300 continue;
1301 }
1302
1303 if (UsbController->IsUsbHub) {
1304
1305 DEBUG ((gUSBDebugLevel, "Hub Deconfig, First Deconfig its downstream ports\n"));
1306
1307 //
1308 // First Remove interrupt transfer request for the status
1309 // change port
1310 //
1311 UsbIo = &UsbController->UsbIo;
1312 UsbIo->UsbAsyncInterruptTransfer (
1313 UsbIo,
1314 UsbController->HubEndpointAddress,
1315 FALSE,
1316 0,
1317 0,
1318 NULL,
1319 NULL
1320 );
1321
1322 if (NULL != UsbController->HubNotify) {
1323 gBS->CloseEvent (UsbController->HubNotify);
1324 }
1325
1326 for (Index = 0; Index < UsbController->DownstreamPorts; Index++) {
1327 if (UsbController->Children[Index]) {
1328 ChildDevice = UsbController->Children[Index];
1329 UsbDeviceDeConfiguration (ChildDevice);
1330 UsbController->Children[Index] = NULL;
1331 }
1332 }
1333 }
1334 //
1335 // If the controller is managed by a device driver, we need to
1336 // disconnect them
1337 //
1338 if (UsbController->IsManagedByDriver) {
1339 gBS->DisconnectController (
1340 UsbController->Handle,
1341 NULL,
1342 NULL
1343 );
1344 }
1345
1346 //
1347 // remove child handle reference to the USB_HC_PROTOCOL
1348 //
1349 if (UsbIoDevice->BusController->Hc2ProtocolSupported) {
1350 gBS->CloseProtocol (
1351 UsbController->HostController,
1352 &gEfiUsb2HcProtocolGuid,
1353 gUsbBusDriverBinding.DriverBindingHandle,
1354 UsbController->Handle
1355 );
1356 } else {
1357 gBS->CloseProtocol (
1358 UsbController->HostController,
1359 &gEfiUsbHcProtocolGuid,
1360 gUsbBusDriverBinding.DriverBindingHandle,
1361 UsbController->Handle
1362 );
1363 }
1364 //
1365 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1366 // installed on this handle
1367 //
1368 gBS->UninstallMultipleProtocolInterfaces (
1369 UsbController->Handle,
1370 &gEfiDevicePathProtocolGuid,
1371 UsbController->DevicePath,
1372 &gEfiUsbIoProtocolGuid,
1373 &UsbController->UsbIo,
1374 NULL
1375 );
1376
1377 if (UsbController->DevicePath != NULL) {
1378 gBS->FreePool (UsbController->DevicePath);
1379 }
1380
1381 gBS->FreePool (UsbController);
1382 UsbIoDevice->UsbController[index] = NULL;
1383 }
1384 //
1385 // Free address for later use
1386 //
1387 UsbFreeAddress (
1388 UsbIoDevice->DeviceAddress,
1389 UsbIoDevice->BusController->AddressPool
1390 );
1391
1392 //
1393 // Free all resouces allocated for all its configurations
1394 //
1395 UsbDestroyAllConfiguration (UsbIoDevice);
1396
1397 if (UsbIoDevice) {
1398 gBS->FreePool (UsbIoDevice);
1399 UsbIoDevice = NULL;
1400 }
1401
1402 return EFI_SUCCESS;
1403 }
1404 //
1405 // After interrupt complete, this function will be called,
1406 // This function need to be well-defined later
1407 //
1408 STATIC
1409 EFI_STATUS
1410 EFIAPI
1411 OnHubInterruptComplete (
1412 IN VOID *Data,
1413 IN UINTN DataLength,
1414 IN VOID *Context,
1415 IN UINT32 Result
1416 )
1417 /*++
1418
1419 Routine Description:
1420 Whenever hub interrupt occurs, this routine will be called to check
1421 which event happens.
1422
1423 Arguments:
1424 Data - Hub interrupt transfer data.
1425 DataLength - The length of the Data.
1426 Context - Hub Controller Device.
1427 Result - Hub interrupt transfer status.
1428
1429 Returns:
1430 EFI_SUCCESS
1431 EFI_DEVICE_ERROR
1432
1433 --*/
1434 {
1435 USB_IO_CONTROLLER_DEVICE *HubController;
1436 UINT8 Index;
1437 UINT8 *ptr;
1438 EFI_USB_IO_PROTOCOL *UsbIo;
1439 UINT32 UsbResult;
1440 BOOLEAN Disconnected;
1441 EFI_STATUS Status;
1442
1443 HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
1444 UsbIo = &HubController->UsbIo;
1445
1446 //
1447 // If something error in this interrupt transfer,
1448 //
1449 if (Result != EFI_USB_NOERROR) {
1450 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
1451 UsbClearEndpointHalt (
1452 UsbIo,
1453 HubController->HubEndpointAddress,
1454 &UsbResult
1455 );
1456 }
1457
1458 //
1459 // Delete & Submit this interrupt again
1460 //
1461 UsbIo->UsbAsyncInterruptTransfer (
1462 UsbIo,
1463 HubController->HubEndpointAddress,
1464 FALSE,
1465 0,
1466 0,
1467 NULL,
1468 NULL
1469 );
1470
1471 //
1472 // try to detect if the hub itself was disconnected or not
1473 //
1474 Status = IsDeviceDisconnected (
1475 HubController,
1476 &Disconnected
1477 );
1478
1479 if (!EFI_ERROR (Status) && Disconnected == TRUE) {
1480 DEBUG ((gUSBErrorLevel, "Hub is disconnected\n"));
1481 return EFI_DEVICE_ERROR;
1482 }
1483 //
1484 // Hub ports < 7
1485 //
1486 UsbIo->UsbAsyncInterruptTransfer (
1487 UsbIo,
1488 HubController->HubEndpointAddress,
1489 TRUE,
1490 100,
1491 1,
1492 OnHubInterruptComplete,
1493 HubController
1494 );
1495
1496 return EFI_DEVICE_ERROR;
1497 }
1498
1499 if (DataLength == 0 || Data == NULL) {
1500 return EFI_SUCCESS;
1501 }
1502
1503 //
1504 // Scan which port has status change
1505 // Bit 0 stands for hub itself, other bit stands for
1506 // the corresponding port
1507 //
1508 for (Index = 0; Index < DataLength * 8; Index++) {
1509 ptr = (UINT8 *) Data + Index / 8;
1510 if ((*ptr) & (1 << (Index & 0x7))) {
1511 HubController->StatusChangePort = Index;
1512 break;
1513 }
1514 }
1515 //
1516 // Signal hub notify event
1517 //
1518 gBS->SignalEvent (HubController->HubNotify);
1519
1520 return EFI_SUCCESS;
1521 }
1522 //
1523 // USB Root Hub Enumerator
1524 //
1525 STATIC
1526 VOID
1527 EFIAPI
1528 RootHubEnumeration (
1529 IN EFI_EVENT Event,
1530 IN VOID *Context
1531 )
1532 /*++
1533
1534 Routine Description:
1535
1536 This is USB RootHub enumerator
1537
1538 Arguments:
1539
1540 Event - Indicating which event is signaled
1541 Context - actually it is a USB_IO_DEVICE
1542
1543 Returns:
1544
1545 VOID
1546
1547 --*/
1548 {
1549 USB_IO_CONTROLLER_DEVICE *HubController;
1550 EFI_USB_PORT_STATUS HubPortStatus;
1551 EFI_STATUS Status;
1552 UINT8 Index;
1553 USB_IO_DEVICE *UsbIoDev;
1554 USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
1555 EFI_HANDLE HostController;
1556 USB_IO_DEVICE *OldUsbIoDevice;
1557 USB_IO_DEVICE *NewDevice;
1558 USB_IO_CONTROLLER_DEVICE *NewController;
1559 UINT8 Index2;
1560 EFI_USB_IO_PROTOCOL *UsbIo;
1561
1562 HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
1563 HostController = HubController->HostController;
1564 UsbBusDev = HubController->UsbDevice->BusController;
1565
1566 //
1567 // Root hub has the address 1
1568 //
1569 UsbIoDev = HubController->UsbDevice;
1570
1571 for (Index = 0; Index < HubController->DownstreamPorts; Index++) {
1572
1573 UsbVirtualHcGetRootHubPortStatus (
1574 UsbBusDev,
1575 Index,
1576 (EFI_USB_PORT_STATUS *) &HubPortStatus
1577 );
1578
1579 if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
1580 continue;
1581 }
1582 //
1583 // Clear root hub status change status
1584 //
1585 UsbVirtualHcClearRootHubPortFeature (
1586 UsbBusDev,
1587 Index,
1588 EfiUsbPortConnectChange
1589 );
1590
1591 gBS->Stall (100 * 1000);
1592
1593 UsbVirtualHcGetRootHubPortStatus (
1594 UsbBusDev,
1595 Index,
1596 (EFI_USB_PORT_STATUS *) &HubPortStatus
1597 );
1598
1599 if (IsPortConnect (HubPortStatus.PortStatus)) {
1600
1601 //
1602 // There is something connected to this port
1603 //
1604 DEBUG ((gUSBDebugLevel, "Something connected to Root Hub at Port0x%x\n", Index));
1605
1606 ReportUsbStatusCode (
1607 UsbBusDev,
1608 EFI_PROGRESS_CODE,
1609 EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
1610 );
1611 //
1612 // if there is something physically detached, but still logically
1613 // attached...
1614 //
1615 OldUsbIoDevice = HubController->Children[Index];
1616
1617 if (NULL != OldUsbIoDevice) {
1618 UsbDeviceDeConfiguration (OldUsbIoDevice);
1619 HubController->Children[Index] = NULL;
1620 }
1621
1622 NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
1623 if (NewDevice == NULL) {
1624 return ;
1625 }
1626 //
1627 // Initialize some fields by copying data from
1628 // its parents
1629 //
1630 NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;
1631 NewDevice->BusController = UsbIoDev->BusController;
1632
1633 //
1634 // Process of identify device speed
1635 //
1636 Status = IdentifyDeviceSpeed (
1637 UsbBusDev,
1638 NewDevice,
1639 Index
1640 );
1641 if (EFI_ERROR (Status)) {
1642 gBS->FreePool (NewDevice);
1643 continue;
1644 }
1645
1646 //
1647 // Configure that device
1648 //
1649 Status = UsbDeviceConfiguration (
1650 HubController,
1651 HostController,
1652 Index,
1653 NewDevice
1654 );
1655 if (EFI_ERROR (Status)) {
1656 gBS->FreePool (NewDevice);
1657 return ;
1658 }
1659 //
1660 // Add this device to the usb bus tree
1661 //
1662 HubController->Children[Index] = NewDevice;
1663
1664 for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
1665 //
1666 // If this device is hub, add to the hub index
1667 //
1668 NewController = NewDevice->UsbController[Index2];
1669
1670 Status = gBS->ConnectController (
1671 NewController->Handle,
1672 NULL,
1673 NULL,
1674 TRUE
1675 );
1676 //
1677 // If connect success, we need to disconnect when
1678 // stop the controller, otherwise we need not call
1679 // gBS->DisconnectController ()
1680 // This is used by those usb devices we don't plan
1681 // to support. We can allocate
1682 // controller handles for them, but we don't have
1683 // device drivers to manage them.
1684 //
1685 NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
1686
1687 if (IsHub (NewController)) {
1688
1689 NewController->IsUsbHub = TRUE;
1690
1691 //
1692 // Configure Hub Controller
1693 //
1694 Status = DoHubConfig (NewController);
1695 if (EFI_ERROR (Status)) {
1696 continue;
1697 }
1698 //
1699 // Create an event to do hub enumeration
1700 //
1701 gBS->CreateEvent (
1702 EFI_EVENT_NOTIFY_SIGNAL,
1703 EFI_TPL_CALLBACK,
1704 HubEnumeration,
1705 NewController,
1706 &NewController->HubNotify
1707 );
1708
1709 //
1710 // Add request to do query hub status
1711 // change endpoint
1712 // Hub ports < 7
1713 //
1714 UsbIo = &NewController->UsbIo;
1715 UsbIo->UsbAsyncInterruptTransfer (
1716 UsbIo,
1717 NewController->HubEndpointAddress,
1718 TRUE,
1719 100,
1720 1,
1721 OnHubInterruptComplete,
1722 NewController
1723 );
1724
1725 }
1726 }
1727 } else {
1728 //
1729 // Something disconnected from USB root hub
1730 //
1731 DEBUG ((gUSBDebugLevel, "Something disconnected from Root Hub at Port0x%x\n", Index));
1732
1733 OldUsbIoDevice = HubController->Children[Index];
1734
1735 UsbDeviceDeConfiguration (OldUsbIoDevice);
1736
1737 HubController->Children[Index] = NULL;
1738
1739 UsbVirtualHcClearRootHubPortFeature (
1740 UsbBusDev,
1741 Index,
1742 EfiUsbPortEnableChange
1743 );
1744 }
1745 }
1746
1747 return ;
1748 }
1749 //
1750 // USB Root Hub Enumerator
1751 //
1752 STATIC
1753 VOID
1754 EFIAPI
1755 HubEnumeration (
1756 IN EFI_EVENT Event,
1757 IN VOID *Context
1758 )
1759 /*++
1760
1761 Routine Description:
1762
1763 This is Usb Hub enumerator
1764
1765 Arguments:
1766
1767 Event - Indicating which event is signaled
1768 Context - actually it is a USB_IO_DEVICE
1769
1770 Returns:
1771
1772 VOID
1773
1774 --*/
1775 {
1776 USB_IO_CONTROLLER_DEVICE *HubController;
1777 EFI_USB_PORT_STATUS HubPortStatus;
1778 EFI_STATUS Status;
1779 USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
1780 EFI_HANDLE HostController;
1781 USB_IO_DEVICE *OldUsbIoDevice;
1782 USB_IO_DEVICE *NewDevice;
1783 USB_IO_CONTROLLER_DEVICE *NewController;
1784 UINT8 Index2;
1785 EFI_USB_IO_PROTOCOL *UsbIo;
1786 UINT8 StatusChangePort;
1787 UINT8 Number;
1788
1789 HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
1790 HostController = HubController->HostController;
1791 UsbBusDev = HubController->UsbDevice->BusController;
1792
1793 //
1794 // Event from Hub, Get the hub controller handle
1795 //
1796 //
1797 // Get the status change endpoint
1798 //
1799 StatusChangePort = HubController->StatusChangePort;
1800
1801 //
1802 // Clear HubController Status Change Bit
1803 //
1804 HubController->StatusChangePort = 0;
1805
1806 if (StatusChangePort == 0) {
1807 //
1808 // Hub changes, we don't handle here
1809 //
1810 return ;
1811 }
1812 //
1813 // Check which event took place at that port
1814 //
1815 UsbIo = &HubController->UsbIo;
1816 Status = HubGetPortStatus (
1817 UsbIo,
1818 StatusChangePort,
1819 (UINT32 *) &HubPortStatus
1820 );
1821
1822 if (EFI_ERROR (Status)) {
1823 return ;
1824 }
1825 //
1826 // Clear some change status
1827 //
1828 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {
1829 //
1830 // Clear Hub port enable change
1831 //
1832 DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));
1833 HubClearPortFeature (
1834 UsbIo,
1835 StatusChangePort,
1836 EfiUsbPortEnableChange
1837 );
1838
1839 HubGetPortStatus (
1840 UsbIo,
1841 StatusChangePort,
1842 (UINT32 *) &HubPortStatus
1843 );
1844 }
1845
1846 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {
1847 //
1848 // Clear Hub reset change
1849 //
1850 DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));
1851 HubClearPortFeature (
1852 UsbIo,
1853 StatusChangePort,
1854 EfiUsbPortResetChange
1855 );
1856
1857 HubGetPortStatus (
1858 UsbIo,
1859 StatusChangePort,
1860 (UINT32 *) &HubPortStatus
1861 );
1862 }
1863
1864 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {
1865 //
1866 // Clear Hub overcurrent change
1867 //
1868 DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));
1869 HubClearPortFeature (
1870 UsbIo,
1871 StatusChangePort,
1872 EfiUsbPortOverCurrentChange
1873 );
1874
1875 HubGetPortStatus (
1876 UsbIo,
1877 StatusChangePort,
1878 (UINT32 *) &HubPortStatus
1879 );
1880 }
1881
1882 if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
1883 //
1884 // First clear port connection change
1885 //
1886 DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));
1887 HubClearPortFeature (
1888 UsbIo,
1889 StatusChangePort,
1890 EfiUsbPortConnectChange
1891 );
1892
1893 HubGetPortStatus (
1894 UsbIo,
1895 StatusChangePort,
1896 (UINT32 *) &HubPortStatus
1897 );
1898
1899 if (IsPortConnect (HubPortStatus.PortStatus)) {
1900
1901 DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));
1902
1903 ReportUsbStatusCode (
1904 UsbBusDev,
1905 EFI_PROGRESS_CODE,
1906 EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
1907 );
1908
1909 //
1910 // if there is something physically detached, but still logically
1911 // attached...
1912 //
1913 OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
1914
1915 if (NULL != OldUsbIoDevice) {
1916 UsbDeviceDeConfiguration (OldUsbIoDevice);
1917 HubController->Children[StatusChangePort - 1] = NULL;
1918 }
1919
1920 NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
1921 if (NewDevice == NULL) {
1922 return ;
1923 }
1924 //
1925 // Initialize some fields
1926 //
1927 NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;
1928 NewDevice->BusController = HubController->UsbDevice->BusController;
1929
1930 //
1931 // There is something connected to this port,
1932 // reset that port
1933 //
1934 // Disable the enable bit in port status
1935 //
1936 HubClearPortFeature (
1937 UsbIo,
1938 StatusChangePort,
1939 EfiUsbPortEnable
1940 );
1941
1942 gBS->Stall (50 * 1000);
1943
1944 //
1945 // Wait for bit change
1946 //
1947 Number = 10;
1948 do {
1949 HubGetPortStatus (
1950 UsbIo,
1951 StatusChangePort,
1952 (UINT32 *) &HubPortStatus
1953 );
1954 gBS->Stall (10 * 1000);
1955 Number -= 1;
1956 } while ((HubPortStatus.PortStatus & USB_PORT_STAT_ENABLE) == 1 && Number > 0);
1957
1958 if (Number == 0) {
1959 //
1960 // Cannot disable port, return error
1961 //
1962 DEBUG ((gUSBErrorLevel, "Disable Port Failed\n"));
1963 gBS->FreePool (NewDevice);
1964 return ;
1965 }
1966
1967 HubSetPortFeature (
1968 UsbIo,
1969 StatusChangePort,
1970 EfiUsbPortReset
1971 );
1972
1973 gBS->Stall (50 * 1000);
1974
1975 //
1976 // Wait for port reset complete
1977 //
1978 Number = 10;
1979 do {
1980 HubGetPortStatus (
1981 UsbIo,
1982 StatusChangePort,
1983 (UINT32 *) &HubPortStatus
1984 );
1985 gBS->Stall (10 * 1000);
1986 Number -= 1;
1987 } while ((HubPortStatus.PortStatus & USB_PORT_STAT_RESET) == 1 && Number > 0);
1988
1989 if (Number == 0) {
1990 //
1991 // Cannot reset port, return error
1992 //
1993 DEBUG ((gUSBErrorLevel, "Reset Port Failed\n"));
1994 gBS->FreePool (NewDevice);
1995 return ;
1996 }
1997 //
1998 // Check high speed or full speed device
1999 //
2000 if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {
2001 DEBUG ((gUSBDebugLevel, "Low Speed Device Attached to Hub\n"));
2002 NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;
2003 } else if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {
2004 DEBUG ((gUSBDebugLevel, "High Speed Device Attached to Hub\n"));
2005 NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;
2006 } else {
2007 DEBUG ((gUSBDebugLevel, "Full Speed Device Attached to Hub\n"));
2008 NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;
2009 }
2010 //
2011 // Configure that device
2012 //
2013 Status = UsbDeviceConfiguration (
2014 HubController,
2015 HostController,
2016 (UINT8) (StatusChangePort - 1),
2017 NewDevice
2018 );
2019
2020 if (EFI_ERROR (Status)) {
2021 gBS->FreePool (NewDevice);
2022 return ;
2023 }
2024 //
2025 // Add this device to the usb bus tree
2026 // StatusChangePort is begin from 1,
2027 //
2028 HubController->Children[StatusChangePort - 1] = NewDevice;
2029
2030 for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
2031 //
2032 // If this device is hub, add to the hub index
2033 //
2034 NewController = NewDevice->UsbController[Index2];
2035
2036 //
2037 // Connect the controller to the driver image
2038 //
2039 Status = gBS->ConnectController (
2040 NewController->Handle,
2041 NULL,
2042 NULL,
2043 TRUE
2044 );
2045 //
2046 // If connect success, we need to disconnect when
2047 // stop the controller, otherwise we need not call
2048 // gBS->DisconnectController ()
2049 // This is used by those usb devices we don't plan
2050 // to support. We can allocate
2051 // controller handles for them, but we don't have
2052 // device drivers to manage them.
2053 //
2054 NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
2055
2056 //
2057 // If this device is hub, add to the hub index
2058 //
2059 if (IsHub (NewController)) {
2060
2061 NewController->IsUsbHub = TRUE;
2062
2063 //
2064 // Configure Hub
2065 //
2066 Status = DoHubConfig (NewController);
2067
2068 if (EFI_ERROR (Status)) {
2069 continue;
2070 }
2071 //
2072 // Create an event to do hub enumeration
2073 //
2074 gBS->CreateEvent (
2075 EFI_EVENT_NOTIFY_SIGNAL,
2076 EFI_TPL_CALLBACK,
2077 HubEnumeration,
2078 NewController,
2079 &NewController->HubNotify
2080 );
2081
2082 //
2083 // Add request to do query hub status
2084 // change endpoint
2085 //
2086 UsbIo = &NewController->UsbIo;
2087 UsbIo->UsbAsyncInterruptTransfer (
2088 UsbIo,
2089 NewController->HubEndpointAddress, // Hub endpoint address
2090 TRUE,
2091 100,
2092 1, // Hub ports < 7
2093 OnHubInterruptComplete,
2094 NewController
2095 );
2096 }
2097 }
2098 } else {
2099 //
2100 // Something disconnected from USB hub
2101 //
2102 DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));
2103
2104 OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
2105
2106 UsbDeviceDeConfiguration (OldUsbIoDevice);
2107
2108 HubController->Children[StatusChangePort - 1] = NULL;
2109
2110 }
2111
2112 return ;
2113 }
2114
2115 return ;
2116 }
2117
2118 STATIC
2119 USB_IO_CONTROLLER_DEVICE *
2120 CreateUsbIoControllerDevice (
2121 VOID
2122 )
2123 /*++
2124
2125 Routine Description:
2126 Allocate a structure for USB_IO_CONTROLLER_DEVICE
2127
2128 Arguments:
2129 N/A
2130
2131 Returns:
2132 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
2133 Or NULL.
2134
2135 --*/
2136 {
2137 USB_IO_CONTROLLER_DEVICE *UsbIoControllerDev;
2138
2139 //
2140 // Allocate USB_IO_CONTROLLER_DEVICE structure
2141 //
2142 UsbIoControllerDev = NULL;
2143 UsbIoControllerDev = AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE));
2144
2145 if (UsbIoControllerDev == NULL) {
2146 return NULL;
2147 }
2148
2149 UsbIoControllerDev->Signature = USB_IO_CONTROLLER_SIGNATURE;
2150
2151 return UsbIoControllerDev;
2152 }
2153
2154 STATIC
2155 EFI_STATUS
2156 InitUsbIoController (
2157 IN USB_IO_CONTROLLER_DEVICE *UsbIoController
2158 )
2159 /*++
2160
2161 Routine Description:
2162 Init and install EFI_USB_IO_PROTOCOL onto that controller.
2163
2164 Arguments:
2165 UsbIoController - The Controller to be operated.
2166
2167 Returns:
2168 EFI_SUCCESS
2169 Others
2170
2171 --*/
2172 {
2173 USB_DEVICE_PATH UsbNode;
2174 EFI_STATUS Status;
2175 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
2176 EFI_USB_HC_PROTOCOL *UsbHcProtocol;
2177 EFI_USB2_HC_PROTOCOL *Usb2HcProtocol;
2178
2179 //
2180 // Build the child device path for each new USB_IO device
2181 //
2182 ZeroMem (&UsbNode, sizeof (UsbNode));
2183 UsbNode.Header.Type = MESSAGING_DEVICE_PATH;
2184 UsbNode.Header.SubType = MSG_USB_DP;
2185 SetDevicePathNodeLength (&UsbNode.Header, sizeof (UsbNode));
2186 UsbNode.InterfaceNumber = UsbIoController->InterfaceNumber;
2187 UsbNode.ParentPortNumber = UsbIoController->ParentPort;
2188 ParentDevicePath = UsbIoController->Parent->DevicePath;
2189
2190 UsbIoController->DevicePath =
2191 AppendDevicePathNode (ParentDevicePath, &UsbNode.Header);
2192 if (UsbIoController->DevicePath == NULL) {
2193 return EFI_OUT_OF_RESOURCES;
2194 }
2195
2196 Status = gBS->InstallMultipleProtocolInterfaces (
2197 &UsbIoController->Handle,
2198 &gEfiDevicePathProtocolGuid,
2199 UsbIoController->DevicePath,
2200 &gEfiUsbIoProtocolGuid,
2201 &UsbIoController->UsbIo,
2202 NULL
2203 );
2204
2205 if (EFI_ERROR (Status)) {
2206 return Status;
2207 }
2208
2209 if (UsbIoController->UsbDevice->BusController->Hc2ProtocolSupported) {
2210 Status = gBS->OpenProtocol (
2211 UsbIoController->HostController,
2212 &gEfiUsb2HcProtocolGuid,
2213 (VOID **)&Usb2HcProtocol,
2214 gUsbBusDriverBinding.DriverBindingHandle,
2215 UsbIoController->Handle,
2216 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2217 );
2218 } else {
2219 Status = gBS->OpenProtocol (
2220 UsbIoController->HostController,
2221 &gEfiUsbHcProtocolGuid,
2222 (VOID **)&UsbHcProtocol,
2223 gUsbBusDriverBinding.DriverBindingHandle,
2224 UsbIoController->Handle,
2225 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2226 );
2227 }
2228
2229 return Status;
2230 }
2231
2232 STATIC
2233 EFI_STATUS
2234 ParentPortReset (
2235 IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
2236 IN BOOLEAN ReConfigure,
2237 IN UINT8 RetryTimes
2238 )
2239 /*++
2240
2241 Routine Description:
2242 Reset parent hub port to which this device is connected.
2243
2244 Arguments:
2245 UsbIoController - Indicating the Usb Controller Device.
2246 ReConfigure - Do we need to reconfigure it.
2247 RetryTimes - Retry Times when failed
2248
2249 Returns:
2250 EFI_SUCCESS
2251 EFI_DEVICE_ERROR
2252
2253 --*/
2254 {
2255 USB_IO_DEVICE *ParentIoDev;
2256 USB_IO_DEVICE *UsbIoDev;
2257 USB_IO_CONTROLLER_DEVICE *ParentController;
2258 UINT8 HubPort;
2259 UINT32 Status;
2260 EFI_STATUS Result;
2261 EFI_USB_IO_PROTOCOL *UsbIo;
2262 UINT8 Address;
2263
2264 ParentController = UsbIoController->Parent;
2265 ParentIoDev = ParentController->UsbDevice;
2266 UsbIoDev = UsbIoController->UsbDevice;
2267 HubPort = UsbIoController->ParentPort;
2268
2269 gBS->Stall (100 * 1000);
2270
2271 if (ParentIoDev->DeviceAddress == 1) {
2272 DEBUG ((gUSBDebugLevel, "Reset from Root Hub 0x%x\n", HubPort));
2273 ResetRootPort (ParentIoDev->BusController, HubPort, RetryTimes);
2274 } else {
2275 DEBUG ((gUSBDebugLevel, "Reset from Hub, Addr 0x%x\n", ParentIoDev->DeviceAddress));
2276 ResetHubPort (ParentController, HubPort + 1);
2277 }
2278 //
2279 // If we only need port reset, just return
2280 //
2281 if (!ReConfigure) {
2282 return EFI_SUCCESS;
2283 }
2284 //
2285 // Re-config that USB device
2286 //
2287 UsbIo = &UsbIoController->UsbIo;
2288
2289 //
2290 // Assign a unique address to this device
2291 //
2292 Address = UsbIoDev->DeviceAddress;
2293 UsbIoDev->DeviceAddress = 0;
2294
2295 Result = UsbSetDeviceAddress (UsbIo, Address, &Status);
2296 UsbIoDev->DeviceAddress = Address;
2297
2298 if (EFI_ERROR (Result)) {
2299 return EFI_DEVICE_ERROR;
2300 }
2301 //
2302 // Set the device to the default configuration
2303 //
2304 Result = UsbSetDefaultConfiguration (UsbIoDev);
2305 if (EFI_ERROR (Result)) {
2306 return EFI_DEVICE_ERROR;
2307 }
2308
2309 return EFI_SUCCESS;
2310 }
2311
2312 EFI_STATUS
2313 EFIAPI
2314 UsbPortReset (
2315 IN EFI_USB_IO_PROTOCOL *This
2316 )
2317 /*++
2318
2319 Routine Description:
2320 Resets and reconfigures the USB controller. This function will
2321 work for all USB devices except USB Hub Controllers.
2322
2323 Arguments:
2324 This - Indicates the calling context.
2325
2326 Returns:
2327 EFI_SUCCESS
2328 EFI_INVALID_PARAMETER
2329 EFI_DEVICE_ERROR
2330
2331 --*/
2332 {
2333 USB_IO_CONTROLLER_DEVICE *UsbIoController;
2334
2335 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
2336
2337 if (IsHub (UsbIoController)) {
2338 return EFI_INVALID_PARAMETER;
2339 }
2340
2341 //
2342 // Since at this time, this device has already been configured,
2343 // it needs to be re-configured.
2344 //
2345 return ParentPortReset (UsbIoController, TRUE, 0);
2346 }
2347
2348 EFI_STATUS
2349 ResetRootPort (
2350 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2351 IN UINT8 PortNum,
2352 IN UINT8 RetryTimes
2353 )
2354 /*++
2355
2356 Routine Description:
2357 Reset Root Hub port.
2358
2359 Arguments:
2360 UsbBusDev - Bus controller of the device.
2361 PortNum - The given port to be reset.
2362 RetryTimes - RetryTimes when failed
2363
2364 Returns:
2365 EFI_SUCCESS
2366 EFI_DEVICE_ERROR
2367
2368 --*/
2369 {
2370 EFI_STATUS Status;
2371 EFI_USB_PORT_STATUS PortStatus;
2372
2373 //
2374 // reset root port
2375 //
2376 Status = UsbVirtualHcSetRootHubPortFeature (
2377 UsbBusDev,
2378 PortNum,
2379 EfiUsbPortReset
2380 );
2381 if (EFI_ERROR (Status)) {
2382 return EFI_DEVICE_ERROR;
2383 }
2384
2385 gBS->Stall (50 * 1000);
2386
2387 //
2388 // clear reset root port
2389 //
2390 Status = UsbVirtualHcClearRootHubPortFeature (
2391 UsbBusDev,
2392 PortNum,
2393 EfiUsbPortReset
2394 );
2395 if (EFI_ERROR (Status)) {
2396 return EFI_DEVICE_ERROR;
2397 }
2398
2399 gBS->Stall (1000);
2400
2401 Status = UsbVirtualHcClearRootHubPortFeature (
2402 UsbBusDev,
2403 PortNum,
2404 EfiUsbPortConnectChange
2405 );
2406 if (EFI_ERROR (Status)) {
2407 return EFI_DEVICE_ERROR;
2408 }
2409
2410 UsbVirtualHcGetRootHubPortStatus (
2411 UsbBusDev,
2412 PortNum,
2413 &PortStatus
2414 );
2415 if (PortStatus.PortStatus & USB_PORT_STAT_OWNER) {
2416 //
2417 // Set port enable
2418 //
2419 Status = UsbVirtualHcSetRootHubPortFeature (
2420 UsbBusDev,
2421 PortNum,
2422 EfiUsbPortEnable
2423 );
2424 if (EFI_ERROR (Status)) {
2425 return EFI_DEVICE_ERROR;
2426 }
2427
2428 Status = UsbVirtualHcClearRootHubPortFeature (
2429 UsbBusDev,
2430 PortNum,
2431 EfiUsbPortEnableChange
2432 );
2433 }
2434
2435 gBS->Stall ((1 + RetryTimes) * 50 * 1000);
2436
2437 return EFI_SUCCESS;
2438 }
2439
2440 EFI_STATUS
2441 ResetHubPort (
2442 IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
2443 IN UINT8 PortIndex
2444 )
2445 /*++
2446
2447 Routine Description:
2448 Reset Hub port.
2449
2450 Arguments:
2451 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2452 PortIndex - The given port to be reset.
2453
2454 Returns:
2455 EFI_SUCCESS
2456 EFI_DEVICE_ERROR
2457
2458 --*/
2459 {
2460 EFI_USB_IO_PROTOCOL *UsbIo;
2461 EFI_USB_PORT_STATUS HubPortStatus;
2462 UINT8 Number;
2463
2464 ASSERT (UsbIoController->IsUsbHub == TRUE);
2465
2466 UsbIo = &UsbIoController->UsbIo;
2467
2468 HubSetPortFeature (
2469 UsbIo,
2470 PortIndex,
2471 EfiUsbPortReset
2472 );
2473
2474 gBS->Stall (10 * 1000);
2475
2476 //
2477 // Wait for port reset complete
2478 //
2479 Number = 10;
2480 do {
2481 HubGetPortStatus (
2482 UsbIo,
2483 PortIndex,
2484 (UINT32 *) &HubPortStatus
2485 );
2486 gBS->Stall (10 * 100);
2487 Number -= 1;
2488 } while ((HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0 && Number > 0);
2489
2490 if (Number == 0) {
2491 //
2492 // Cannot reset port, return error
2493 //
2494 return EFI_DEVICE_ERROR;
2495 }
2496
2497 gBS->Stall (1000);
2498
2499 HubGetPortStatus (
2500 UsbIo,
2501 PortIndex,
2502 (UINT32 *) &HubPortStatus
2503 );
2504 //
2505 // reset port will cause some bits change, clear them
2506 //
2507 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {
2508 DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));
2509 HubClearPortFeature (
2510 UsbIo,
2511 PortIndex,
2512 EfiUsbPortEnableChange
2513 );
2514 }
2515
2516 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {
2517 DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));
2518 HubClearPortFeature (
2519 UsbIo,
2520 PortIndex,
2521 EfiUsbPortResetChange
2522 );
2523 }
2524
2525 return EFI_SUCCESS;
2526 }
2527
2528 STATIC
2529 EFI_STATUS
2530 ReportUsbStatusCode (
2531 IN USB_BUS_CONTROLLER_DEVICE *UsbBusController,
2532 IN EFI_STATUS_CODE_TYPE Type,
2533 IN EFI_STATUS_CODE_VALUE Code
2534 )
2535 /*++
2536
2537 Routine Description:
2538
2539 report a error Status code of USB bus driver controller
2540
2541 Arguments:
2542 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2543 Type - EFI_STATUS_CODE_TYPE
2544 Code - EFI_STATUS_CODE_VALUE
2545 Returns:
2546
2547 None
2548
2549 --*/
2550 {
2551 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2552 Type,
2553 Code,
2554 UsbBusController->DevicePath
2555 );
2556 }
2557
2558 EFI_STATUS
2559 IsDeviceDisconnected (
2560 IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
2561 IN OUT BOOLEAN *Disconnected
2562 )
2563 /*++
2564
2565 Routine Description:
2566 Reset if the device is disconencted or not
2567
2568 Arguments:
2569 UsbIoController - Indicating the Usb Controller Device.
2570 Disconnected - Indicate whether the device is disconencted or not
2571
2572 Returns:
2573 EFI_SUCCESS
2574 EFI_DEVICE_ERROR
2575
2576 --*/
2577 {
2578 USB_IO_DEVICE *ParentIoDev;
2579 USB_IO_DEVICE *UsbIoDev;
2580 USB_IO_CONTROLLER_DEVICE *ParentController;
2581 UINT8 HubPort;
2582 EFI_STATUS Status;
2583 EFI_USB_IO_PROTOCOL *UsbIo;
2584 EFI_USB_PORT_STATUS PortStatus;
2585
2586 ParentController = UsbIoController->Parent;
2587 ParentIoDev = ParentController->UsbDevice;
2588 UsbIoDev = UsbIoController->UsbDevice;
2589 HubPort = UsbIoController->ParentPort;
2590
2591 if (ParentIoDev->DeviceAddress == 1) {
2592 //
2593 // Connected to the root hub
2594 //
2595 UsbVirtualHcGetRootHubPortStatus (
2596 ParentIoDev->BusController,
2597 HubPort,
2598 &PortStatus
2599 );
2600
2601 } else {
2602 UsbIo = &UsbIoController->UsbIo;
2603 Status = HubGetPortStatus (
2604 &ParentController->UsbIo,
2605 HubPort + 1,
2606 (UINT32 *) &PortStatus
2607 );
2608
2609 if (EFI_ERROR (Status)) {
2610 return IsDeviceDisconnected (ParentController, Disconnected);
2611 }
2612 }
2613
2614 *Disconnected = FALSE;
2615
2616 if (!IsPortConnect (PortStatus.PortStatus)) {
2617 *Disconnected = TRUE;
2618 }
2619
2620 return EFI_SUCCESS;
2621 }
2622
2623 STATIC
2624 EFI_STATUS
2625 UsbSetTransactionTranslator (
2626 IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
2627 IN UINT8 ParentPort,
2628 IN OUT USB_IO_DEVICE *Device
2629 )
2630 /*++
2631
2632 Routine Description:
2633
2634 Set Transaction Translator parameter
2635
2636 Arguments:
2637
2638 ParentHubController - Controller structure of the parent Hub device
2639 ParentPort - Number of parent port
2640 Device - Structure of the device
2641
2642 Returns:
2643
2644 EFI_SUCCESS Success
2645 EFI_OUT_OF_RESOURCES Cannot allocate resources
2646
2647 --*/
2648 {
2649 USB_IO_CONTROLLER_DEVICE *AncestorHubController;
2650
2651 AncestorHubController = ParentHubController;
2652 Device->Translator = NULL;
2653
2654 if (EFI_USB_SPEED_HIGH == Device->DeviceSpeed) {
2655 return EFI_SUCCESS;
2656 }
2657
2658 do {
2659 if (EFI_USB_SPEED_HIGH == AncestorHubController->UsbDevice->DeviceSpeed) {
2660 break;
2661 }
2662
2663 if (NULL == AncestorHubController->Parent) {
2664 return EFI_SUCCESS;
2665 }
2666
2667 AncestorHubController = AncestorHubController->Parent;
2668 } while (1);
2669
2670 Device->Translator = AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR));
2671 if (NULL == Device->Translator) {
2672 return EFI_OUT_OF_RESOURCES;
2673 }
2674
2675 Device->Translator->TranslatorHubAddress = AncestorHubController->UsbDevice->DeviceAddress;
2676 Device->Translator->TranslatorPortNumber = ParentPort;
2677
2678 return EFI_SUCCESS;
2679 }
2680
2681 STATIC
2682 EFI_STATUS
2683 UsbUnsetTransactionTranslator (
2684 USB_IO_DEVICE *Device
2685 )
2686 /*++
2687
2688 Routine Description:
2689
2690 Unset Transaction Translator parameter
2691
2692 Arguments:
2693
2694 Device - Structure of the device
2695
2696 Returns:
2697
2698 EFI_SUCCESS Success
2699
2700 --*/
2701 {
2702 if (Device->Translator) {
2703 gBS->FreePool (Device->Translator);
2704 Device->Translator = NULL;
2705 }
2706
2707 return EFI_SUCCESS;
2708 }
2709
2710 STATIC
2711 EFI_STATUS
2712 IdentifyDeviceSpeed (
2713 USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2714 USB_IO_DEVICE *NewDevice,
2715 UINT8 Index
2716 )
2717 /*++
2718
2719 Routine Description:
2720
2721 Identify speed of USB device
2722
2723 Arguments:
2724
2725 UsbBusDev - UsbBus controller structure of the device
2726 NewDevice - Devcie controller structure
2727 Index - Number of the port
2728
2729 Returns:
2730
2731 EFI_SUCCESS Success
2732 EFI_NOT_FOUND Device release to CHC or can't be found
2733
2734 --*/
2735 {
2736 EFI_STATUS Status;
2737 EFI_USB_PORT_STATUS HubPortStatus;
2738
2739 UsbVirtualHcGetRootHubPortStatus (
2740 UsbBusDev,
2741 Index,
2742 (EFI_USB_PORT_STATUS *) &HubPortStatus
2743 );
2744
2745 //
2746 // Check device device
2747 //
2748 if (!(HubPortStatus.PortStatus & USB_PORT_STAT_OWNER)) {
2749 //
2750 // EHC Port Owner
2751 //
2752 if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {
2753 DEBUG ((gUSBDebugLevel, "High Speed Device attached to EHC\n"));
2754 NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;
2755 } else {
2756 Status = ReleasePortToCHC (UsbBusDev, Index);
2757 if (EFI_ERROR (Status)) {
2758 DEBUG ((gUSBErrorLevel, "Fail to release port to CHC\n"));
2759 } else {
2760 DEBUG ((gUSBDebugLevel, "Success to release port to CHC\n"));
2761 }
2762 return EFI_DEVICE_ERROR;
2763 }
2764 } else {
2765 //
2766 // CHC Port Owner
2767 //
2768 if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {
2769 DEBUG ((gUSBDebugLevel, "Low Speed Device attached to CHC\n"));
2770 NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;
2771 } else {
2772 DEBUG ((gUSBDebugLevel, "FULL Speed Device attached to CHC\n"));
2773 NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;
2774 }
2775 }
2776
2777 return EFI_SUCCESS;
2778 }
2779
2780 STATIC
2781 EFI_STATUS
2782 ReleasePortToCHC (
2783 USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2784 UINT8 PortNum
2785 )
2786 /*++
2787
2788 Routine Description:
2789
2790 Set bit to release the port owner to CHC
2791
2792 Arguments:
2793
2794 UsbBusDev - UsbBus controller structure of the device
2795 PortNum - Number of the port
2796
2797 Returns:
2798
2799 EFI_SUCCESS Success
2800 EFI_DEVICE_ERROR Fail
2801
2802 --*/
2803 {
2804 EFI_STATUS Status;
2805
2806 Status = UsbVirtualHcSetRootHubPortFeature (
2807 UsbBusDev,
2808 PortNum,
2809 EfiUsbPortOwner
2810 );
2811
2812 gBS->Stall (100 * 1000);
2813
2814 return Status;
2815 }
2816
2817 EFI_STATUS
2818 EFIAPI
2819 UsbVirtualHcGetCapability (
2820 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2821 OUT UINT8 *MaxSpeed,
2822 OUT UINT8 *PortNumber,
2823 OUT UINT8 *Is64BitCapable
2824 )
2825 /*++
2826
2827 Routine Description:
2828
2829 Virtual interface to Retrieves the capablility of root hub ports
2830 for both Hc2 and Hc protocol.
2831
2832 Arguments:
2833
2834 UsbBusDev - A pointer to bus controller of the device.
2835 MaxSpeed - A pointer to the number of the host controller.
2836 PortNumber - A pointer to the number of the root hub ports.
2837 Is64BitCapable - A pointer to the flag for whether controller supports
2838 64-bit memory addressing.
2839
2840 Returns:
2841
2842 EFI_SUCCESS
2843 The host controller capability were retrieved successfully.
2844 EFI_INVALID_PARAMETER
2845 MaxSpeed or PortNumber or Is64BitCapable is NULL.
2846 EFI_DEVICE_ERROR
2847 An error was encountered while attempting to retrieve the capabilities.
2848
2849 --*/
2850 {
2851 EFI_STATUS Status;
2852
2853 Status = EFI_SUCCESS;
2854
2855 if (UsbBusDev->Hc2ProtocolSupported) {
2856 Status = UsbBusDev->Usb2HCInterface->GetCapability (
2857 UsbBusDev->Usb2HCInterface,
2858 MaxSpeed,
2859 PortNumber,
2860 Is64BitCapable
2861 );
2862 } else {
2863 Status = UsbBusDev->UsbHCInterface->GetRootHubPortNumber (
2864 UsbBusDev->UsbHCInterface,
2865 PortNumber
2866 );
2867 *MaxSpeed = EFI_USB_SPEED_FULL;
2868 *Is64BitCapable = (UINT8) FALSE;
2869 }
2870
2871 return Status;
2872 }
2873
2874 EFI_STATUS
2875 EFIAPI
2876 UsbVirtualHcReset (
2877 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2878 IN UINT16 Attributes
2879 )
2880 /*++
2881
2882 Routine Description:
2883
2884 Virtual interface to provides software reset for the USB host controller
2885 for both Hc2 and Hc protocol.
2886
2887 Arguments:
2888
2889 UsbBusDev - A pointer to bus controller of the device.
2890 Attributes - A bit mask of the reset operation to perform.
2891 See below for a list of the supported bit mask values.
2892
2893 #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
2894 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
2895 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
2896 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
2897
2898 EFI_USB_HC_RESET_GLOBAL
2899 If this bit is set, a global reset signal will be sent to the USB bus.
2900 This resets all of the USB bus logic, including the USB host
2901 controller hardware and all the devices attached on the USB bus.
2902 EFI_USB_HC_RESET_HOST_CONTROLLER
2903 If this bit is set, the USB host controller hardware will be reset.
2904 No reset signal will be sent to the USB bus.
2905 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
2906 If this bit is set, a global reset signal will be sent to the USB bus.
2907 This resets all of the USB bus logic, including the USB host
2908 controller hardware and all the devices attached on the USB bus.
2909 If this is an EHCI controller and the debug port has configured, then
2910 this is will still reset the host controller.
2911 EFI_USB_HC_RESET_HOST_WITH_DEBUG
2912 If this bit is set, the USB host controller hardware will be reset.
2913 If this is an EHCI controller and the debug port has been configured,
2914 then this will still reset the host controller.
2915
2916 Returns:
2917
2918 EFI_SUCCESS
2919 The reset operation succeeded.
2920 EFI_INVALID_PARAMETER
2921 Attributes is not valid.
2922 EFI_UNSUPPOURTED
2923 The type of reset specified by Attributes is not currently supported by
2924 the host controller hardware.
2925 EFI_ACCESS_DENIED
2926 Reset operation is rejected due to the debug port being configured and
2927 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
2928 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
2929 perform reset operation for this host controller.
2930 EFI_DEVICE_ERROR
2931 An error was encountered while attempting to perform
2932 the reset operation.
2933
2934 --*/
2935 {
2936 EFI_STATUS Status;
2937
2938 Status = EFI_SUCCESS;
2939
2940 if (UsbBusDev->Hc2ProtocolSupported) {
2941 Status = UsbBusDev->Usb2HCInterface->Reset (
2942 UsbBusDev->Usb2HCInterface,
2943 EFI_USB_HC_RESET_GLOBAL
2944 );
2945 } else {
2946 Status = UsbBusDev->UsbHCInterface->Reset (
2947 UsbBusDev->UsbHCInterface,
2948 EFI_USB_HC_RESET_GLOBAL
2949 );
2950 }
2951
2952 return Status;
2953 }
2954
2955 EFI_STATUS
2956 EFIAPI
2957 UsbVirtualHcGetState (
2958 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2959 OUT EFI_USB_HC_STATE *State
2960 )
2961 /*++
2962
2963 Routine Description:
2964
2965 Virtual interface to retrieves current state of the USB host controller
2966 for both Hc2 and Hc protocol.
2967
2968 Arguments:
2969
2970 UsbBusDev - A pointer to bus controller of the device.
2971 State - A pointer to the EFI_USB_HC_STATE data structure that
2972 indicates current state of the USB host controller.
2973 Type EFI_USB_HC_STATE is defined below.
2974
2975 typedef enum {
2976 EfiUsbHcStateHalt,
2977 EfiUsbHcStateOperational,
2978 EfiUsbHcStateSuspend,
2979 EfiUsbHcStateMaximum
2980 } EFI_USB_HC_STATE;
2981
2982 Returns:
2983
2984 EFI_SUCCESS
2985 The state information of the host controller was returned in State.
2986 EFI_INVALID_PARAMETER
2987 State is NULL.
2988 EFI_DEVICE_ERROR
2989 An error was encountered while attempting to retrieve the
2990 host controller's current state.
2991
2992 --*/
2993 {
2994 EFI_STATUS Status;
2995
2996 Status = EFI_SUCCESS;
2997
2998 if (UsbBusDev->Hc2ProtocolSupported) {
2999 Status = UsbBusDev->Usb2HCInterface->GetState (
3000 UsbBusDev->Usb2HCInterface,
3001 State
3002 );
3003 } else {
3004 Status = UsbBusDev->UsbHCInterface->GetState (
3005 UsbBusDev->UsbHCInterface,
3006 State
3007 );
3008 }
3009
3010 return Status;
3011 }
3012
3013 EFI_STATUS
3014 EFIAPI
3015 UsbVirtualHcSetState (
3016 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3017 IN EFI_USB_HC_STATE State
3018 )
3019 /*++
3020
3021 Routine Description:
3022
3023 Virtual interface to sets the USB host controller to a specific state
3024 for both Hc2 and Hc protocol.
3025
3026 Arguments:
3027
3028 UsbBusDev - A pointer to bus controller of the device.
3029 State - Indicates the state of the host controller that will be set.
3030
3031 Returns:
3032
3033 EFI_SUCCESS
3034 The USB host controller was successfully placed in the state
3035 specified by State.
3036 EFI_INVALID_PARAMETER
3037 State is invalid.
3038 EFI_DEVICE_ERROR
3039 Failed to set the state specified by State due to device error.
3040
3041 --*/
3042 {
3043 EFI_STATUS Status;
3044
3045 Status = EFI_SUCCESS;
3046
3047 if (UsbBusDev->Hc2ProtocolSupported) {
3048 Status = UsbBusDev->Usb2HCInterface->SetState (
3049 UsbBusDev->Usb2HCInterface,
3050 State
3051 );
3052 } else {
3053 Status = UsbBusDev->UsbHCInterface->SetState (
3054 UsbBusDev->UsbHCInterface,
3055 State
3056 );
3057 }
3058
3059 return Status;
3060 }
3061
3062 EFI_STATUS
3063 EFIAPI
3064 UsbVirtualHcGetRootHubPortStatus (
3065 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3066 IN UINT8 PortNumber,
3067 OUT EFI_USB_PORT_STATUS *PortStatus
3068 )
3069 /*++
3070
3071 Routine Description:
3072
3073 Virtual interface to retrieves the current status of a USB root hub port
3074 both for Hc2 and Hc protocol.
3075
3076 Arguments:
3077
3078 UsbBusDev - A pointer to bus controller of the device.
3079 PortNumber - Specifies the root hub port from which the status
3080 is to be retrieved. This value is zero-based. For example,
3081 if a root hub has two ports, then the first port is numbered 0,
3082 and the second port is numbered 1.
3083 PortStatus - A pointer to the current port status bits and
3084 port status change bits.
3085
3086 Returns:
3087
3088 EFI_SUCCESS The status of the USB root hub port specified by PortNumber
3089 was returned in PortStatus.
3090 EFI_INVALID_PARAMETER PortNumber is invalid.
3091 EFI_DEVICE_ERROR Can't read register
3092
3093 --*/
3094 {
3095 EFI_STATUS Status;
3096
3097 Status = EFI_SUCCESS;
3098
3099 if (UsbBusDev->Hc2ProtocolSupported) {
3100 Status = UsbBusDev->Usb2HCInterface->GetRootHubPortStatus (
3101 UsbBusDev->Usb2HCInterface,
3102 PortNumber,
3103 PortStatus
3104 );
3105 } else {
3106 Status = UsbBusDev->UsbHCInterface->GetRootHubPortStatus (
3107 UsbBusDev->UsbHCInterface,
3108 PortNumber,
3109 PortStatus
3110 );
3111 }
3112
3113 return Status;
3114 }
3115
3116 EFI_STATUS
3117 EFIAPI
3118 UsbVirtualHcSetRootHubPortFeature (
3119 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3120 IN UINT8 PortNumber,
3121 IN EFI_USB_PORT_FEATURE PortFeature
3122 )
3123 /*++
3124
3125 Routine Description:
3126 Virual interface to sets a feature for the specified root hub port
3127 for both Hc2 and Hc protocol.
3128
3129 Arguments:
3130
3131 UsbBusDev - A pointer to bus controller of the device.
3132 PortNumber - Specifies the root hub port whose feature
3133 is requested to be set.
3134 PortFeature - Indicates the feature selector associated
3135 with the feature set request.
3136
3137 Returns:
3138
3139 EFI_SUCCESS
3140 The feature specified by PortFeature was set for the
3141 USB root hub port specified by PortNumber.
3142 EFI_INVALID_PARAMETER
3143 PortNumber is invalid or PortFeature is invalid.
3144 EFI_DEVICE_ERROR
3145 Can't read register
3146
3147 --*/
3148 {
3149 EFI_STATUS Status;
3150
3151 Status = EFI_SUCCESS;
3152
3153 if (UsbBusDev->Hc2ProtocolSupported) {
3154 Status = UsbBusDev->Usb2HCInterface->SetRootHubPortFeature (
3155 UsbBusDev->Usb2HCInterface,
3156 PortNumber,
3157 PortFeature
3158 );
3159 } else {
3160 Status = UsbBusDev->UsbHCInterface->SetRootHubPortFeature (
3161 UsbBusDev->UsbHCInterface,
3162 PortNumber,
3163 PortFeature
3164 );
3165 }
3166
3167 return Status;
3168 }
3169
3170 EFI_STATUS
3171 EFIAPI
3172 UsbVirtualHcClearRootHubPortFeature (
3173 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3174 IN UINT8 PortNumber,
3175 IN EFI_USB_PORT_FEATURE PortFeature
3176 )
3177 /*++
3178
3179 Routine Description:
3180
3181 Virtual interface to clears a feature for the specified root hub port
3182 for both Hc2 and Hc protocol.
3183
3184 Arguments:
3185
3186 UsbBusDev - A pointer to bus controller of the device.
3187 PortNumber - Specifies the root hub port whose feature
3188 is requested to be cleared.
3189 PortFeature - Indicates the feature selector associated with the
3190 feature clear request.
3191
3192 Returns:
3193
3194 EFI_SUCCESS
3195 The feature specified by PortFeature was cleared for the
3196 USB root hub port specified by PortNumber.
3197 EFI_INVALID_PARAMETER
3198 PortNumber is invalid or PortFeature is invalid.
3199 EFI_DEVICE_ERROR
3200 Can't read register
3201
3202 --*/
3203 {
3204 EFI_STATUS Status;
3205
3206 Status = EFI_SUCCESS;
3207
3208 if (UsbBusDev->Hc2ProtocolSupported) {
3209 Status = UsbBusDev->Usb2HCInterface->ClearRootHubPortFeature (
3210 UsbBusDev->Usb2HCInterface,
3211 PortNumber,
3212 PortFeature
3213 );
3214 } else {
3215 Status = UsbBusDev->UsbHCInterface->ClearRootHubPortFeature (
3216 UsbBusDev->UsbHCInterface,
3217 PortNumber,
3218 PortFeature
3219 );
3220 }
3221
3222 return Status;
3223 }
3224
3225 EFI_STATUS
3226 EFIAPI
3227 UsbVirtualHcControlTransfer (
3228 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3229 IN UINT8 DeviceAddress,
3230 IN UINT8 DeviceSpeed,
3231 IN UINTN MaximumPacketLength,
3232 IN EFI_USB_DEVICE_REQUEST *Request,
3233 IN EFI_USB_DATA_DIRECTION TransferDirection,
3234 IN OUT VOID *Data,
3235 IN OUT UINTN *DataLength,
3236 IN UINTN TimeOut,
3237 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3238 OUT UINT32 *TransferResult
3239 )
3240 /*++
3241
3242 Routine Description:
3243
3244 Virtual interface to submits control transfer to a target USB device
3245 for both Hc2 and Hc protocol.
3246
3247 Arguments:
3248
3249 UsbBusDev - A pointer to bus controller of the device.
3250 DeviceAddress - Represents the address of the target device on the USB,
3251 which is assigned during USB enumeration.
3252 DeviceSpeed - Indicates target device speed.
3253 MaximumPacketLength - Indicates the maximum packet size that the
3254 default control transfer endpoint is capable of
3255 sending or receiving.
3256 Request - A pointer to the USB device request that will be sent
3257 to the USB device.
3258 TransferDirection - Specifies the data direction for the transfer.
3259 There are three values available, DataIn, DataOut
3260 and NoData.
3261 Data - A pointer to the buffer of data that will be transmitted
3262 to USB device or received from USB device.
3263 DataLength - Indicates the size, in bytes, of the data buffer
3264 specified by Data.
3265 TimeOut - Indicates the maximum time, in microseconds,
3266 which the transfer is allowed to complete.
3267 Translator - A pointr to the transaction translator data.
3268 TransferResult - A pointer to the detailed result information generated
3269 by this control transfer.
3270
3271 Returns:
3272
3273 EFI_SUCCESS
3274 The control transfer was completed successfully.
3275 EFI_OUT_OF_RESOURCES
3276 The control transfer could not be completed due to a lack of resources.
3277 EFI_INVALID_PARAMETER
3278 Some parameters are invalid.
3279 EFI_TIMEOUT
3280 The control transfer failed due to timeout.
3281 EFI_DEVICE_ERROR
3282 The control transfer failed due to host controller or device error.
3283 Caller should check TranferResult for detailed error information.
3284
3285 --*/
3286 {
3287 EFI_STATUS Status;
3288 BOOLEAN IsSlowDevice;
3289
3290 Status = EFI_SUCCESS;
3291
3292 if (UsbBusDev->Hc2ProtocolSupported) {
3293 Status = UsbBusDev->Usb2HCInterface->ControlTransfer (
3294 UsbBusDev->Usb2HCInterface,
3295 DeviceAddress,
3296 DeviceSpeed,
3297 MaximumPacketLength,
3298 Request,
3299 TransferDirection,
3300 Data,
3301 DataLength,
3302 TimeOut,
3303 Translator,
3304 TransferResult
3305 );
3306 } else {
3307 IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
3308 Status = UsbBusDev->UsbHCInterface->ControlTransfer (
3309 UsbBusDev->UsbHCInterface,
3310 DeviceAddress,
3311 IsSlowDevice,
3312 (UINT8) MaximumPacketLength,
3313 Request,
3314 TransferDirection,
3315 Data,
3316 DataLength,
3317 TimeOut,
3318 TransferResult
3319 );
3320 }
3321
3322 return Status;
3323 }
3324
3325 EFI_STATUS
3326 EFIAPI
3327 UsbVirtualHcBulkTransfer (
3328 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3329 IN UINT8 DeviceAddress,
3330 IN UINT8 EndPointAddress,
3331 IN UINT8 DeviceSpeed,
3332 IN UINTN MaximumPacketLength,
3333 IN UINT8 DataBuffersNumber,
3334 IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
3335 IN OUT UINTN *DataLength,
3336 IN OUT UINT8 *DataToggle,
3337 IN UINTN TimeOut,
3338 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3339 OUT UINT32 *TransferResult
3340 )
3341 /*++
3342
3343 Routine Description:
3344
3345 Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
3346 both for Hc2 and Hc protocol.
3347
3348 Arguments:
3349
3350 UsbBusDev - A pointer to bus controller of the device.
3351 DeviceAddress - Represents the address of the target device on the USB,
3352 which is assigned during USB enumeration.
3353 EndPointAddress - The combination of an endpoint number and an
3354 endpoint direction of the target USB device.
3355 Each endpoint address supports data transfer in
3356 one direction except the control endpoint
3357 (whose default endpoint address is 0).
3358 It is the caller's responsibility to make sure that
3359 the EndPointAddress represents a bulk endpoint.
3360 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
3361 and EFI_USB_SPEED_HIGH.
3362 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3363 is capable of sending or receiving.
3364 DataBuffersNumber - Number of data buffers prepared for the transfer.
3365 Data - Array of pointers to the buffers of data that will be transmitted
3366 to USB device or received from USB device.
3367 DataLength - When input, indicates the size, in bytes, of the data buffer
3368 specified by Data. When output, indicates the actually
3369 transferred data size.
3370 DataToggle - A pointer to the data toggle value. On input, it indicates
3371 the initial data toggle value the bulk transfer should adopt;
3372 on output, it is updated to indicate the data toggle value
3373 of the subsequent bulk transfer.
3374 Translator - A pointr to the transaction translator data.
3375 TimeOut - Indicates the maximum time, in microseconds, which the
3376 transfer is allowed to complete.
3377 TransferResult - A pointer to the detailed result information of the
3378 bulk transfer.
3379
3380 Returns:
3381
3382 EFI_SUCCESS
3383 The bulk transfer was completed successfully.
3384 EFI_OUT_OF_RESOURCES
3385 The bulk transfer could not be submitted due to lack of resource.
3386 EFI_INVALID_PARAMETER
3387 Some parameters are invalid.
3388 EFI_TIMEOUT
3389 The bulk transfer failed due to timeout.
3390 EFI_DEVICE_ERROR
3391 The bulk transfer failed due to host controller or device error.
3392 Caller should check TranferResult for detailed error information.
3393
3394 --*/
3395 {
3396 EFI_STATUS Status;
3397
3398 Status = EFI_SUCCESS;
3399
3400 if (UsbBusDev->Hc2ProtocolSupported) {
3401 Status = UsbBusDev->Usb2HCInterface->BulkTransfer (
3402 UsbBusDev->Usb2HCInterface,
3403 DeviceAddress,
3404 EndPointAddress,
3405 DeviceSpeed,
3406 MaximumPacketLength,
3407 DataBuffersNumber,
3408 Data,
3409 DataLength,
3410 DataToggle,
3411 TimeOut,
3412 Translator,
3413 TransferResult
3414 );
3415 } else {
3416 Status = UsbBusDev->UsbHCInterface->BulkTransfer (
3417 UsbBusDev->UsbHCInterface,
3418 DeviceAddress,
3419 EndPointAddress,
3420 (UINT8) MaximumPacketLength,
3421 *Data,
3422 DataLength,
3423 DataToggle,
3424 TimeOut,
3425 TransferResult
3426 );
3427 }
3428
3429 return Status;
3430 }
3431
3432 EFI_STATUS
3433 EFIAPI
3434 UsbVirtualHcAsyncInterruptTransfer (
3435 IN USB_BUS_CONTROLLER_DEVICE * UsbBusDev,
3436 IN UINT8 DeviceAddress,
3437 IN UINT8 EndPointAddress,
3438 IN UINT8 DeviceSpeed,
3439 IN UINTN MaximumPacketLength,
3440 IN BOOLEAN IsNewTransfer,
3441 IN OUT UINT8 *DataToggle,
3442 IN UINTN PollingInterval,
3443 IN UINTN DataLength,
3444 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,
3445 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
3446 IN VOID *Context OPTIONAL
3447 )
3448 /*++
3449
3450 Routine Description:
3451
3452 Virtual interface to submits an asynchronous interrupt transfer to an
3453 interrupt endpoint of a USB device for both Hc2 and Hc protocol.
3454
3455 Arguments:
3456
3457 UsbBusDev - A pointer to bus controller of the device.
3458 DeviceAddress - Represents the address of the target device on the USB,
3459 which is assigned during USB enumeration.
3460 EndPointAddress - The combination of an endpoint number and an endpoint
3461 direction of the target USB device. Each endpoint address
3462 supports data transfer in one direction except the
3463 control endpoint (whose default endpoint address is 0).
3464 It is the caller's responsibility to make sure that
3465 the EndPointAddress represents an interrupt endpoint.
3466 DeviceSpeed - Indicates device speed.
3467 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3468 is capable of sending or receiving.
3469 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
3470 the host and the target interrupt endpoint.
3471 If FALSE, the specified asynchronous interrupt pipe
3472 is canceled.
3473 DataToggle - A pointer to the data toggle value. On input, it is valid
3474 when IsNewTransfer is TRUE, and it indicates the initial
3475 data toggle value the asynchronous interrupt transfer
3476 should adopt.
3477 On output, it is valid when IsNewTransfer is FALSE,
3478 and it is updated to indicate the data toggle value of
3479 the subsequent asynchronous interrupt transfer.
3480 PollingInterval - Indicates the interval, in milliseconds, that the
3481 asynchronous interrupt transfer is polled.
3482 This parameter is required when IsNewTransfer is TRUE.
3483 DataLength - Indicates the length of data to be received at the
3484 rate specified by PollingInterval from the target
3485 asynchronous interrupt endpoint. This parameter
3486 is only required when IsNewTransfer is TRUE.
3487 Translator - A pointr to the transaction translator data.
3488 CallBackFunction - The Callback function.This function is called at the
3489 rate specified by PollingInterval.This parameter is
3490 only required when IsNewTransfer is TRUE.
3491 Context - The context that is passed to the CallBackFunction.
3492 - This is an optional parameter and may be NULL.
3493
3494 Returns:
3495
3496 EFI_SUCCESS
3497 The asynchronous interrupt transfer request has been successfully
3498 submitted or canceled.
3499 EFI_INVALID_PARAMETER
3500 Some parameters are invalid.
3501 EFI_OUT_OF_RESOURCES
3502 The request could not be completed due to a lack of resources.
3503 EFI_DEVICE_ERROR
3504 Can't read register
3505
3506 --*/
3507 {
3508 EFI_STATUS Status;
3509 BOOLEAN IsSlowDevice;
3510
3511 Status = EFI_SUCCESS;
3512
3513 if (UsbBusDev->Hc2ProtocolSupported) {
3514 Status = UsbBusDev->Usb2HCInterface->AsyncInterruptTransfer (
3515 UsbBusDev->Usb2HCInterface,
3516 DeviceAddress,
3517 EndPointAddress,
3518 DeviceSpeed,
3519 MaximumPacketLength,
3520 IsNewTransfer,
3521 DataToggle,
3522 PollingInterval,
3523 DataLength,
3524 Translator,
3525 CallBackFunction,
3526 Context
3527 );
3528 } else {
3529 IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
3530 Status = UsbBusDev->UsbHCInterface->AsyncInterruptTransfer (
3531 UsbBusDev->UsbHCInterface,
3532 DeviceAddress,
3533 EndPointAddress,
3534 IsSlowDevice,
3535 (UINT8) MaximumPacketLength,
3536 IsNewTransfer,
3537 DataToggle,
3538 PollingInterval,
3539 DataLength,
3540 CallBackFunction,
3541 Context
3542 );
3543 }
3544
3545 return Status;
3546 }
3547
3548 EFI_STATUS
3549 EFIAPI
3550 UsbVirtualHcSyncInterruptTransfer (
3551 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3552 IN UINT8 DeviceAddress,
3553 IN UINT8 EndPointAddress,
3554 IN UINT8 DeviceSpeed,
3555 IN UINTN MaximumPacketLength,
3556 IN OUT VOID *Data,
3557 IN OUT UINTN *DataLength,
3558 IN OUT UINT8 *DataToggle,
3559 IN UINTN TimeOut,
3560 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3561 OUT UINT32 *TransferResult
3562 )
3563 /*++
3564
3565 Routine Description:
3566
3567 Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
3568 of a USB device for both Hc2 and Hc protocol.
3569
3570 Arguments:
3571
3572 UsbBusDev - A pointer to bus controller of the device.
3573 DeviceAddress - Represents the address of the target device on the USB,
3574 which is assigned during USB enumeration.
3575 EndPointAddress - The combination of an endpoint number and an endpoint
3576 direction of the target USB device. Each endpoint
3577 address supports data transfer in one direction
3578 except the control endpoint (whose default
3579 endpoint address is 0). It is the caller's responsibility
3580 to make sure that the EndPointAddress represents
3581 an interrupt endpoint.
3582 DeviceSpeed - Indicates device speed.
3583 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3584 is capable of sending or receiving.
3585 Data - A pointer to the buffer of data that will be transmitted
3586 to USB device or received from USB device.
3587 DataLength - On input, the size, in bytes, of the data buffer specified
3588 by Data. On output, the number of bytes transferred.
3589 DataToggle - A pointer to the data toggle value. On input, it indicates
3590 the initial data toggle value the synchronous interrupt
3591 transfer should adopt;
3592 on output, it is updated to indicate the data toggle value
3593 of the subsequent synchronous interrupt transfer.
3594 TimeOut - Indicates the maximum time, in microseconds, which the
3595 transfer is allowed to complete.
3596 Translator - A pointr to the transaction translator data.
3597 TransferResult - A pointer to the detailed result information from
3598 the synchronous interrupt transfer.
3599
3600 Returns:
3601
3602 EFI_SUCCESS
3603 The synchronous interrupt transfer was completed successfully.
3604 EFI_OUT_OF_RESOURCES
3605 The synchronous interrupt transfer could not be submitted due
3606 to lack of resource.
3607 EFI_INVALID_PARAMETER
3608 Some parameters are invalid.
3609 EFI_TIMEOUT
3610 The synchronous interrupt transfer failed due to timeout.
3611 EFI_DEVICE_ERROR
3612 The synchronous interrupt transfer failed due to host controller
3613 or device error. Caller should check TranferResult for detailed
3614 error information.
3615
3616 --*/
3617 {
3618 EFI_STATUS Status;
3619 BOOLEAN IsSlowDevice;
3620
3621 Status = EFI_SUCCESS;
3622
3623 if (UsbBusDev->Hc2ProtocolSupported) {
3624 Status = UsbBusDev->Usb2HCInterface->SyncInterruptTransfer (
3625 UsbBusDev->Usb2HCInterface,
3626 DeviceAddress,
3627 EndPointAddress,
3628 DeviceSpeed,
3629 MaximumPacketLength,
3630 Data,
3631 DataLength,
3632 DataToggle,
3633 TimeOut,
3634 Translator,
3635 TransferResult
3636 );
3637 } else {
3638 IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
3639 Status = UsbBusDev->UsbHCInterface->SyncInterruptTransfer (
3640 UsbBusDev->UsbHCInterface,
3641 DeviceAddress,
3642 EndPointAddress,
3643 IsSlowDevice,
3644 (UINT8) MaximumPacketLength,
3645 Data,
3646 DataLength,
3647 DataToggle,
3648 TimeOut,
3649 TransferResult
3650 );
3651 }
3652
3653 return Status;
3654 }
3655
3656 EFI_STATUS
3657 EFIAPI
3658 UsbVirtualHcIsochronousTransfer (
3659 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3660 IN UINT8 DeviceAddress,
3661 IN UINT8 EndPointAddress,
3662 IN UINT8 DeviceSpeed,
3663 IN UINTN MaximumPacketLength,
3664 IN UINT8 DataBuffersNumber,
3665 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
3666 IN UINTN DataLength,
3667 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3668 OUT UINT32 *TransferResult
3669 )
3670 /*++
3671
3672 Routine Description:
3673
3674 Virtual interface to submits isochronous transfer to a target USB device
3675 for both Hc2 and Hc protocol.
3676
3677 Arguments:
3678
3679 UsbBusDev - A pointer to bus controller of the device.
3680 DeviceAddress - Represents the address of the target device on the USB,
3681 which is assigned during USB enumeration.
3682 EndPointAddress - End point address
3683 DeviceSpeed - Indicates device speed.
3684 MaximumPacketLength - Indicates the maximum packet size that the
3685 default control transfer endpoint is capable of
3686 sending or receiving.
3687 DataBuffersNumber - Number of data buffers prepared for the transfer.
3688 Data - Array of pointers to the buffers of data that will be
3689 transmitted to USB device or received from USB device.
3690 DataLength - Indicates the size, in bytes, of the data buffer
3691 specified by Data.
3692 Translator - A pointr to the transaction translator data.
3693 TransferResult - A pointer to the detailed result information generated
3694 by this control transfer.
3695
3696 Returns:
3697
3698 EFI_UNSUPPORTED
3699
3700 --*/
3701 {
3702 return EFI_UNSUPPORTED;
3703 }
3704
3705 EFI_STATUS
3706 EFIAPI
3707 UsbVirtualHcAsyncIsochronousTransfer (
3708 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3709 IN UINT8 DeviceAddress,
3710 IN UINT8 EndPointAddress,
3711 IN UINT8 DeviceSpeed,
3712 IN UINTN MaximumPacketLength,
3713 IN UINT8 DataBuffersNumber,
3714 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
3715 IN UINTN DataLength,
3716 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3717 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
3718 IN VOID *Context
3719 )
3720 /*++
3721
3722 Routine Description:
3723
3724 Vitual interface to submits Async isochronous transfer to a target USB device
3725 for both Hc2 and Hc protocol.
3726
3727 Arguments:
3728
3729 UsbBusDev - A pointer to bus controller of the device.
3730 DeviceAddress - Represents the address of the target device on the USB,
3731 which is assigned during USB enumeration.
3732 EndPointAddress - End point address
3733 DeviceSpeed - Indicates device speed.
3734 MaximumPacketLength - Indicates the maximum packet size that the
3735 default control transfer endpoint is capable of
3736 sending or receiving.
3737 DataBuffersNumber - Number of data buffers prepared for the transfer.
3738 Data - Array of pointers to the buffers of data that will be transmitted
3739 to USB device or received from USB device.
3740 DataLength - Indicates the size, in bytes, of the data buffer
3741 specified by Data.
3742 Translator - A pointr to the transaction translator data.
3743 IsochronousCallBack - When the transfer complete, the call back function will be called
3744 Context - Pass to the call back function as parameter
3745
3746 Returns:
3747
3748 EFI_UNSUPPORTED
3749
3750 --*/
3751 {
3752 return EFI_UNSUPPORTED;
3753 }