]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
1. Add the GLOBAL_REMOVE_IF_UNREFERENCED to globe variables which are used only in...
[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 0x10,
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 ParentPortReset (FirstController, FALSE, 0);
1005
1006 //
1007 // First retrieve the 1st 8 bytes of
1008 // in order to get the MaxPacketSize for Endpoint 0
1009 //
1010 for (Index = 0; Index < 3; Index++) {
1011
1012 UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;
1013
1014 gBS->Stall (100 * 1000);
1015
1016 Result = UsbGetDescriptor (
1017 UsbIo,
1018 (USB_DT_DEVICE << 8),
1019 0,
1020 8,
1021 &UsbIoDevice->DeviceDescriptor,
1022 &Status
1023 );
1024 if (!EFI_ERROR (Result)) {
1025 DEBUG (
1026 (gUSBDebugLevel,
1027 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
1028 UsbIoDevice->DeviceDescriptor.MaxPacketSize0)
1029 );
1030 break;
1031 }
1032
1033 }
1034
1035 if (Index == 3) {
1036 ReportUsbStatusCode (
1037 UsbBusDev,
1038 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1039 EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
1040 );
1041 DEBUG ((gUSBErrorLevel, "Get Device Descriptor Fail when configing\n"));
1042 gBS->FreePool (FirstController);
1043 return EFI_DEVICE_ERROR;
1044 }
1045
1046 DevAddress = UsbAllocateAddress (UsbIoDevice->BusController->AddressPool);
1047 if (DevAddress == 0) {
1048 DEBUG ((gUSBErrorLevel, "Cannot allocate address\n"));
1049 gBS->FreePool (FirstController);
1050 return EFI_OUT_OF_RESOURCES;
1051 }
1052
1053 Result = UsbSetDeviceAddress (UsbIo, DevAddress, &Status);
1054
1055 if (EFI_ERROR (Result)) {
1056 DEBUG ((gUSBErrorLevel, "Set address error\n"));
1057 ReportUsbStatusCode (
1058 UsbBusDev,
1059 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1060 EFI_IO_BUS_USB | EFI_IOB_EC_WRITE_ERROR
1061 );
1062
1063 UsbFreeAddress (
1064 DevAddress,
1065 UsbIoDevice->BusController->AddressPool
1066 );
1067
1068 gBS->FreePool (FirstController);
1069 return EFI_DEVICE_ERROR;
1070 }
1071
1072 UsbIoDevice->DeviceAddress = DevAddress;
1073
1074 //
1075 // SetAddress Complete Time by Spec, Max 50ms
1076 //
1077 gBS->Stall (10 * 1000);
1078
1079 //
1080 // Get the whole device descriptor
1081 //
1082 Result = UsbGetDescriptor (
1083 UsbIo,
1084 (USB_DT_DEVICE << 8),
1085 0,
1086 sizeof (EFI_USB_DEVICE_DESCRIPTOR),
1087 &UsbIoDevice->DeviceDescriptor,
1088 &Status
1089 );
1090
1091 if (EFI_ERROR (Result)) {
1092 DEBUG ((gUSBErrorLevel, "Get whole Device Descriptor error\n"));
1093 ReportUsbStatusCode (
1094 UsbBusDev,
1095 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1096 EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
1097 );
1098 UsbFreeAddress (
1099 DevAddress,
1100 UsbIoDevice->BusController->AddressPool
1101 );
1102
1103 gBS->FreePool (FirstController);
1104 return EFI_DEVICE_ERROR;
1105 }
1106 //
1107 // Get & parse all configurations for this device, including
1108 // all configuration descriptors, all interface descriptors, all
1109 // endpoint descriptors
1110 //
1111 Result = UsbGetAllConfigurations (UsbIoDevice);
1112
1113 if (EFI_ERROR (Result)) {
1114 DEBUG ((gUSBErrorLevel, "Failed to get device configuration\n"));
1115 ReportUsbStatusCode (
1116 UsbBusDev,
1117 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1118 EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
1119 );
1120 UsbFreeAddress (
1121 DevAddress,
1122 UsbIoDevice->BusController->AddressPool
1123 );
1124
1125 gBS->FreePool (FirstController);
1126 return EFI_DEVICE_ERROR;
1127 }
1128 //
1129 // Set the 1st configuration value
1130 //
1131 Result = UsbSetDefaultConfiguration (UsbIoDevice);
1132 if (EFI_ERROR (Result)) {
1133 DEBUG ((gUSBErrorLevel, "Failed to set device configuration\n"));
1134 ReportUsbStatusCode (
1135 UsbBusDev,
1136 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1137 EFI_IO_BUS_USB | EFI_IOB_EC_WRITE_ERROR
1138 );
1139 UsbFreeAddress (
1140 DevAddress,
1141 UsbIoDevice->BusController->AddressPool
1142 );
1143
1144 gBS->FreePool (FirstController);
1145 return EFI_DEVICE_ERROR;
1146 }
1147
1148 UsbIoDevice->IsConfigured = TRUE;
1149
1150 //
1151 // Get all string table if applicable
1152 //
1153 Result = UsbGetStringtable (UsbIoDevice);
1154 if (EFI_ERROR (Result)) {
1155 DEBUG ((gUSBDebugLevel, "Device doesn't support string table\n"));
1156 } else {
1157
1158 StrManufacturer = NULL;
1159 UsbIo->UsbGetStringDescriptor (
1160 UsbIo,
1161 UsbIoDevice->LangID[0],
1162 (UsbIoDevice->DeviceDescriptor).StrManufacturer,
1163 &StrManufacturer
1164 );
1165
1166 StrProduct = NULL;
1167 UsbIo->UsbGetStringDescriptor (
1168 UsbIo,
1169 UsbIoDevice->LangID[0],
1170 (UsbIoDevice->DeviceDescriptor).StrProduct,
1171 &StrProduct
1172 );
1173
1174 StrSerialNumber = NULL;
1175 UsbIo->UsbGetStringDescriptor (
1176 UsbIo,
1177 UsbIoDevice->LangID[0],
1178 (UsbIoDevice->DeviceDescriptor).StrSerialNumber,
1179 &StrSerialNumber
1180 );
1181
1182 if (StrManufacturer) {
1183 gBS->FreePool (StrManufacturer);
1184 }
1185
1186 if (StrProduct) {
1187 gBS->FreePool (StrProduct);
1188 }
1189
1190 if (StrSerialNumber) {
1191 gBS->FreePool (StrSerialNumber);
1192 }
1193 }
1194 //
1195 // Create USB_IO_CONTROLLER_DEVICE for
1196 // each detected interface
1197 //
1198 FirstController->CurrentConfigValue =
1199 UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;
1200
1201 NumOfInterface =
1202 UsbIoDevice->ActiveConfig->CongfigDescriptor.NumInterfaces;
1203 UsbIoDevice->NumOfControllers = NumOfInterface;
1204
1205 Result = InitUsbIoController (FirstController);
1206 if (EFI_ERROR (Result)) {
1207 ReportUsbStatusCode (
1208 UsbBusDev,
1209 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1210 EFI_IO_BUS_USB | EFI_IOB_EC_INTERFACE_ERROR
1211 );
1212 gBS->FreePool (FirstController);
1213 UsbIoDevice->UsbController[0] = NULL;
1214 return EFI_DEVICE_ERROR;
1215 }
1216
1217 for (Index = 1; Index < NumOfInterface; Index++) {
1218 UsbIoController = CreateUsbIoControllerDevice ();
1219 UsbIoController->UsbDevice = UsbIoDevice;
1220 UsbIoController->CurrentConfigValue =
1221 UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;
1222 UsbIoController->InterfaceNumber = Index;
1223 UsbIoDevice->UsbController[Index] = UsbIoController;
1224 UsbIoController->ParentPort = ParentPort;
1225 UsbIoController->Parent = ParentHubController;
1226 UsbIoController->HostController = HostController;
1227
1228 //
1229 // First copy the USB_IO Protocol instance
1230 //
1231 CopyMem (
1232 &UsbIoController->UsbIo,
1233 UsbIo,
1234 sizeof (EFI_USB_IO_PROTOCOL)
1235 );
1236
1237 Result = InitUsbIoController (UsbIoController);
1238 if (EFI_ERROR (Result)) {
1239 ReportUsbStatusCode (
1240 UsbBusDev,
1241 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1242 EFI_IO_BUS_USB | EFI_IOB_EC_INTERFACE_ERROR
1243 );
1244 gBS->FreePool (UsbIoController);
1245 UsbIoDevice->UsbController[Index] = NULL;
1246 }
1247 }
1248
1249 return EFI_SUCCESS;
1250 }
1251 //
1252 // USB Device DeConfiguration
1253 //
1254 EFI_STATUS
1255 UsbDeviceDeConfiguration (
1256 IN USB_IO_DEVICE *UsbIoDevice
1257 )
1258 /*++
1259
1260 Routine Description:
1261 Remove Device, Device Handles, Uninstall Protocols.
1262
1263 Arguments:
1264 UsbIoDevice - The device to be deconfigured.
1265
1266 Returns:
1267 EFI_SUCCESS
1268 EFI_DEVICE_ERROR
1269
1270 --*/
1271 {
1272 USB_IO_CONTROLLER_DEVICE *UsbController;
1273 UINT8 index;
1274 USB_IO_DEVICE *ChildDevice;
1275 UINT8 Index;
1276 EFI_USB_IO_PROTOCOL *UsbIo;
1277
1278 //
1279 // Double check UsbIoDevice exists
1280 //
1281 if (UsbIoDevice == NULL) {
1282 return EFI_SUCCESS;
1283 }
1284
1285 UsbUnsetTransactionTranslator (UsbIoDevice);
1286
1287 for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {
1288 //
1289 // Check if it is a hub, if so, de configuration all its
1290 // downstream ports
1291 //
1292 UsbController = UsbIoDevice->UsbController[index];
1293
1294 //
1295 // Check the controller pointer
1296 //
1297 if (UsbController == NULL) {
1298 continue;
1299 }
1300
1301 if (UsbController->IsUsbHub) {
1302
1303 DEBUG ((gUSBDebugLevel, "Hub Deconfig, First Deconfig its downstream ports\n"));
1304
1305 //
1306 // First Remove interrupt transfer request for the status
1307 // change port
1308 //
1309 UsbIo = &UsbController->UsbIo;
1310 UsbIo->UsbAsyncInterruptTransfer (
1311 UsbIo,
1312 UsbController->HubEndpointAddress,
1313 FALSE,
1314 0,
1315 0,
1316 NULL,
1317 NULL
1318 );
1319
1320 if (NULL != UsbController->HubNotify) {
1321 gBS->CloseEvent (UsbController->HubNotify);
1322 }
1323
1324 for (Index = 0; Index < UsbController->DownstreamPorts; Index++) {
1325 if (UsbController->Children[Index]) {
1326 ChildDevice = UsbController->Children[Index];
1327 UsbDeviceDeConfiguration (ChildDevice);
1328 UsbController->Children[Index] = NULL;
1329 }
1330 }
1331 }
1332 //
1333 // If the controller is managed by a device driver, we need to
1334 // disconnect them
1335 //
1336 if (UsbController->IsManagedByDriver) {
1337 gBS->DisconnectController (
1338 UsbController->Handle,
1339 NULL,
1340 NULL
1341 );
1342 }
1343
1344 //
1345 // remove child handle reference to the USB_HC_PROTOCOL
1346 //
1347 if (UsbIoDevice->BusController->Hc2ProtocolSupported) {
1348 gBS->CloseProtocol (
1349 UsbController->HostController,
1350 &gEfiUsb2HcProtocolGuid,
1351 gUsbBusDriverBinding.DriverBindingHandle,
1352 UsbController->Handle
1353 );
1354 } else {
1355 gBS->CloseProtocol (
1356 UsbController->HostController,
1357 &gEfiUsbHcProtocolGuid,
1358 gUsbBusDriverBinding.DriverBindingHandle,
1359 UsbController->Handle
1360 );
1361 }
1362 //
1363 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1364 // installed on this handle
1365 //
1366 gBS->UninstallMultipleProtocolInterfaces (
1367 UsbController->Handle,
1368 &gEfiDevicePathProtocolGuid,
1369 UsbController->DevicePath,
1370 &gEfiUsbIoProtocolGuid,
1371 &UsbController->UsbIo,
1372 NULL
1373 );
1374
1375 if (UsbController->DevicePath != NULL) {
1376 gBS->FreePool (UsbController->DevicePath);
1377 }
1378
1379 gBS->FreePool (UsbController);
1380 UsbIoDevice->UsbController[index] = NULL;
1381 }
1382 //
1383 // Free address for later use
1384 //
1385 UsbFreeAddress (
1386 UsbIoDevice->DeviceAddress,
1387 UsbIoDevice->BusController->AddressPool
1388 );
1389
1390 //
1391 // Free all resouces allocated for all its configurations
1392 //
1393 UsbDestroyAllConfiguration (UsbIoDevice);
1394
1395 if (UsbIoDevice) {
1396 gBS->FreePool (UsbIoDevice);
1397 UsbIoDevice = NULL;
1398 }
1399
1400 return EFI_SUCCESS;
1401 }
1402 //
1403 // After interrupt complete, this function will be called,
1404 // This function need to be well-defined later
1405 //
1406 STATIC
1407 EFI_STATUS
1408 EFIAPI
1409 OnHubInterruptComplete (
1410 IN VOID *Data,
1411 IN UINTN DataLength,
1412 IN VOID *Context,
1413 IN UINT32 Result
1414 )
1415 /*++
1416
1417 Routine Description:
1418 Whenever hub interrupt occurs, this routine will be called to check
1419 which event happens.
1420
1421 Arguments:
1422 Data - Hub interrupt transfer data.
1423 DataLength - The length of the Data.
1424 Context - Hub Controller Device.
1425 Result - Hub interrupt transfer status.
1426
1427 Returns:
1428 EFI_SUCCESS
1429 EFI_DEVICE_ERROR
1430
1431 --*/
1432 {
1433 USB_IO_CONTROLLER_DEVICE *HubController;
1434 UINT8 Index;
1435 UINT8 *ptr;
1436 EFI_USB_IO_PROTOCOL *UsbIo;
1437 UINT32 UsbResult;
1438 BOOLEAN Disconnected;
1439 EFI_STATUS Status;
1440
1441 HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
1442 UsbIo = &HubController->UsbIo;
1443
1444 //
1445 // If something error in this interrupt transfer,
1446 //
1447 if (Result != EFI_USB_NOERROR) {
1448 if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
1449 UsbClearEndpointHalt (
1450 UsbIo,
1451 HubController->HubEndpointAddress,
1452 &UsbResult
1453 );
1454 }
1455
1456 //
1457 // Delete & Submit this interrupt again
1458 //
1459 UsbIo->UsbAsyncInterruptTransfer (
1460 UsbIo,
1461 HubController->HubEndpointAddress,
1462 FALSE,
1463 0,
1464 0,
1465 NULL,
1466 NULL
1467 );
1468
1469 //
1470 // try to detect if the hub itself was disconnected or not
1471 //
1472 Status = IsDeviceDisconnected (
1473 HubController,
1474 &Disconnected
1475 );
1476
1477 if (!EFI_ERROR (Status) && Disconnected == TRUE) {
1478 DEBUG ((gUSBErrorLevel, "Hub is disconnected\n"));
1479 return EFI_DEVICE_ERROR;
1480 }
1481 //
1482 // Hub ports < 7
1483 //
1484 UsbIo->UsbAsyncInterruptTransfer (
1485 UsbIo,
1486 HubController->HubEndpointAddress,
1487 TRUE,
1488 100,
1489 1,
1490 OnHubInterruptComplete,
1491 HubController
1492 );
1493
1494 return EFI_DEVICE_ERROR;
1495 }
1496
1497 if (DataLength == 0 || Data == NULL) {
1498 return EFI_SUCCESS;
1499 }
1500
1501 //
1502 // Scan which port has status change
1503 // Bit 0 stands for hub itself, other bit stands for
1504 // the corresponding port
1505 //
1506 for (Index = 0; Index < DataLength * 8; Index++) {
1507 ptr = (UINT8 *) Data + Index / 8;
1508 if ((*ptr) & (1 << (Index & 0x7))) {
1509 HubController->StatusChangePort = Index;
1510 break;
1511 }
1512 }
1513 //
1514 // Signal hub notify event
1515 //
1516 gBS->SignalEvent (HubController->HubNotify);
1517
1518 return EFI_SUCCESS;
1519 }
1520 //
1521 // USB Root Hub Enumerator
1522 //
1523 STATIC
1524 VOID
1525 EFIAPI
1526 RootHubEnumeration (
1527 IN EFI_EVENT Event,
1528 IN VOID *Context
1529 )
1530 /*++
1531
1532 Routine Description:
1533
1534 This is USB RootHub enumerator
1535
1536 Arguments:
1537
1538 Event - Indicating which event is signaled
1539 Context - actually it is a USB_IO_DEVICE
1540
1541 Returns:
1542
1543 VOID
1544
1545 --*/
1546 {
1547 USB_IO_CONTROLLER_DEVICE *HubController;
1548 EFI_USB_PORT_STATUS HubPortStatus;
1549 EFI_STATUS Status;
1550 UINT8 Index;
1551 USB_IO_DEVICE *UsbIoDev;
1552 USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
1553 EFI_HANDLE HostController;
1554 USB_IO_DEVICE *OldUsbIoDevice;
1555 USB_IO_DEVICE *NewDevice;
1556 USB_IO_CONTROLLER_DEVICE *NewController;
1557 UINT8 Index2;
1558 EFI_USB_IO_PROTOCOL *UsbIo;
1559
1560 HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
1561 HostController = HubController->HostController;
1562 UsbBusDev = HubController->UsbDevice->BusController;
1563
1564 //
1565 // Root hub has the address 1
1566 //
1567 UsbIoDev = HubController->UsbDevice;
1568
1569 for (Index = 0; Index < HubController->DownstreamPorts; Index++) {
1570
1571 UsbVirtualHcGetRootHubPortStatus (
1572 UsbBusDev,
1573 Index,
1574 (EFI_USB_PORT_STATUS *) &HubPortStatus
1575 );
1576
1577 if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
1578 continue;
1579 }
1580 //
1581 // Clear root hub status change status
1582 //
1583 UsbVirtualHcClearRootHubPortFeature (
1584 UsbBusDev,
1585 Index,
1586 EfiUsbPortConnectChange
1587 );
1588
1589 gBS->Stall (100 * 1000);
1590
1591 UsbVirtualHcGetRootHubPortStatus (
1592 UsbBusDev,
1593 Index,
1594 (EFI_USB_PORT_STATUS *) &HubPortStatus
1595 );
1596
1597 if (IsPortConnect (HubPortStatus.PortStatus)) {
1598
1599 //
1600 // There is something connected to this port
1601 //
1602 DEBUG ((gUSBDebugLevel, "Something connected to Root Hub at Port0x%x\n", Index));
1603
1604 ReportUsbStatusCode (
1605 UsbBusDev,
1606 EFI_PROGRESS_CODE,
1607 EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
1608 );
1609 //
1610 // if there is something physically detached, but still logically
1611 // attached...
1612 //
1613 OldUsbIoDevice = HubController->Children[Index];
1614
1615 if (NULL != OldUsbIoDevice) {
1616 UsbDeviceDeConfiguration (OldUsbIoDevice);
1617 HubController->Children[Index] = NULL;
1618 }
1619
1620 NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
1621 if (NewDevice == NULL) {
1622 return ;
1623 }
1624 //
1625 // Initialize some fields by copying data from
1626 // its parents
1627 //
1628 NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;
1629 NewDevice->BusController = UsbIoDev->BusController;
1630
1631 //
1632 // Process of identify device speed
1633 //
1634 Status = IdentifyDeviceSpeed (
1635 UsbBusDev,
1636 NewDevice,
1637 Index
1638 );
1639 if (EFI_ERROR (Status)) {
1640 gBS->FreePool (NewDevice);
1641 continue;
1642 }
1643
1644 //
1645 // Configure that device
1646 //
1647 Status = UsbDeviceConfiguration (
1648 HubController,
1649 HostController,
1650 Index,
1651 NewDevice
1652 );
1653 if (EFI_ERROR (Status)) {
1654 gBS->FreePool (NewDevice);
1655 return ;
1656 }
1657 //
1658 // Add this device to the usb bus tree
1659 //
1660 HubController->Children[Index] = NewDevice;
1661
1662 for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
1663 //
1664 // If this device is hub, add to the hub index
1665 //
1666 NewController = NewDevice->UsbController[Index2];
1667
1668 Status = gBS->ConnectController (
1669 NewController->Handle,
1670 NULL,
1671 NULL,
1672 TRUE
1673 );
1674 //
1675 // If connect success, we need to disconnect when
1676 // stop the controller, otherwise we need not call
1677 // gBS->DisconnectController ()
1678 // This is used by those usb devices we don't plan
1679 // to support. We can allocate
1680 // controller handles for them, but we don't have
1681 // device drivers to manage them.
1682 //
1683 NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
1684
1685 if (IsHub (NewController)) {
1686
1687 NewController->IsUsbHub = TRUE;
1688
1689 //
1690 // Configure Hub Controller
1691 //
1692 Status = DoHubConfig (NewController);
1693 if (EFI_ERROR (Status)) {
1694 continue;
1695 }
1696 //
1697 // Create an event to do hub enumeration
1698 //
1699 gBS->CreateEvent (
1700 EFI_EVENT_NOTIFY_SIGNAL,
1701 EFI_TPL_CALLBACK,
1702 HubEnumeration,
1703 NewController,
1704 &NewController->HubNotify
1705 );
1706
1707 //
1708 // Add request to do query hub status
1709 // change endpoint
1710 // Hub ports < 7
1711 //
1712 UsbIo = &NewController->UsbIo;
1713 UsbIo->UsbAsyncInterruptTransfer (
1714 UsbIo,
1715 NewController->HubEndpointAddress,
1716 TRUE,
1717 100,
1718 1,
1719 OnHubInterruptComplete,
1720 NewController
1721 );
1722
1723 }
1724 }
1725 } else {
1726 //
1727 // Something disconnected from USB root hub
1728 //
1729 DEBUG ((gUSBDebugLevel, "Something disconnected from Root Hub at Port0x%x\n", Index));
1730
1731 OldUsbIoDevice = HubController->Children[Index];
1732
1733 UsbDeviceDeConfiguration (OldUsbIoDevice);
1734
1735 HubController->Children[Index] = NULL;
1736
1737 UsbVirtualHcClearRootHubPortFeature (
1738 UsbBusDev,
1739 Index,
1740 EfiUsbPortEnableChange
1741 );
1742 }
1743 }
1744
1745 return ;
1746 }
1747 //
1748 // USB Root Hub Enumerator
1749 //
1750 STATIC
1751 VOID
1752 EFIAPI
1753 HubEnumeration (
1754 IN EFI_EVENT Event,
1755 IN VOID *Context
1756 )
1757 /*++
1758
1759 Routine Description:
1760
1761 This is Usb Hub enumerator
1762
1763 Arguments:
1764
1765 Event - Indicating which event is signaled
1766 Context - actually it is a USB_IO_DEVICE
1767
1768 Returns:
1769
1770 VOID
1771
1772 --*/
1773 {
1774 USB_IO_CONTROLLER_DEVICE *HubController;
1775 EFI_USB_PORT_STATUS HubPortStatus;
1776 EFI_STATUS Status;
1777 USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
1778 EFI_HANDLE HostController;
1779 USB_IO_DEVICE *OldUsbIoDevice;
1780 USB_IO_DEVICE *NewDevice;
1781 USB_IO_CONTROLLER_DEVICE *NewController;
1782 UINT8 Index2;
1783 EFI_USB_IO_PROTOCOL *UsbIo;
1784 UINT8 StatusChangePort;
1785 UINT8 Number;
1786
1787 HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
1788 HostController = HubController->HostController;
1789 UsbBusDev = HubController->UsbDevice->BusController;
1790
1791 //
1792 // Event from Hub, Get the hub controller handle
1793 //
1794 //
1795 // Get the status change endpoint
1796 //
1797 StatusChangePort = HubController->StatusChangePort;
1798
1799 //
1800 // Clear HubController Status Change Bit
1801 //
1802 HubController->StatusChangePort = 0;
1803
1804 if (StatusChangePort == 0) {
1805 //
1806 // Hub changes, we don't handle here
1807 //
1808 return ;
1809 }
1810 //
1811 // Check which event took place at that port
1812 //
1813 UsbIo = &HubController->UsbIo;
1814 Status = HubGetPortStatus (
1815 UsbIo,
1816 StatusChangePort,
1817 (UINT32 *) &HubPortStatus
1818 );
1819
1820 if (EFI_ERROR (Status)) {
1821 return ;
1822 }
1823 //
1824 // Clear some change status
1825 //
1826 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {
1827 //
1828 // Clear Hub port enable change
1829 //
1830 DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));
1831 HubClearPortFeature (
1832 UsbIo,
1833 StatusChangePort,
1834 EfiUsbPortEnableChange
1835 );
1836
1837 HubGetPortStatus (
1838 UsbIo,
1839 StatusChangePort,
1840 (UINT32 *) &HubPortStatus
1841 );
1842 }
1843
1844 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {
1845 //
1846 // Clear Hub reset change
1847 //
1848 DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));
1849 HubClearPortFeature (
1850 UsbIo,
1851 StatusChangePort,
1852 EfiUsbPortResetChange
1853 );
1854
1855 HubGetPortStatus (
1856 UsbIo,
1857 StatusChangePort,
1858 (UINT32 *) &HubPortStatus
1859 );
1860 }
1861
1862 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {
1863 //
1864 // Clear Hub overcurrent change
1865 //
1866 DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));
1867 HubClearPortFeature (
1868 UsbIo,
1869 StatusChangePort,
1870 EfiUsbPortOverCurrentChange
1871 );
1872
1873 HubGetPortStatus (
1874 UsbIo,
1875 StatusChangePort,
1876 (UINT32 *) &HubPortStatus
1877 );
1878 }
1879
1880 if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
1881 //
1882 // First clear port connection change
1883 //
1884 DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));
1885 HubClearPortFeature (
1886 UsbIo,
1887 StatusChangePort,
1888 EfiUsbPortConnectChange
1889 );
1890
1891 HubGetPortStatus (
1892 UsbIo,
1893 StatusChangePort,
1894 (UINT32 *) &HubPortStatus
1895 );
1896
1897 if (IsPortConnect (HubPortStatus.PortStatus)) {
1898
1899 DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));
1900
1901 ReportUsbStatusCode (
1902 UsbBusDev,
1903 EFI_PROGRESS_CODE,
1904 EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
1905 );
1906
1907 //
1908 // if there is something physically detached, but still logically
1909 // attached...
1910 //
1911 OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
1912
1913 if (NULL != OldUsbIoDevice) {
1914 UsbDeviceDeConfiguration (OldUsbIoDevice);
1915 HubController->Children[StatusChangePort - 1] = NULL;
1916 }
1917
1918 NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
1919 if (NewDevice == NULL) {
1920 return ;
1921 }
1922 //
1923 // Initialize some fields
1924 //
1925 NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;
1926 NewDevice->BusController = HubController->UsbDevice->BusController;
1927
1928 //
1929 // There is something connected to this port,
1930 // reset that port
1931 //
1932 // Disable the enable bit in port status
1933 //
1934 HubClearPortFeature (
1935 UsbIo,
1936 StatusChangePort,
1937 EfiUsbPortEnable
1938 );
1939
1940 gBS->Stall (50 * 1000);
1941
1942 //
1943 // Wait for bit change
1944 //
1945 Number = 10;
1946 do {
1947 HubGetPortStatus (
1948 UsbIo,
1949 StatusChangePort,
1950 (UINT32 *) &HubPortStatus
1951 );
1952 gBS->Stall (10 * 1000);
1953 Number -= 1;
1954 } while ((HubPortStatus.PortStatus & USB_PORT_STAT_ENABLE) == 1 && Number > 0);
1955
1956 if (Number == 0) {
1957 //
1958 // Cannot disable port, return error
1959 //
1960 DEBUG ((gUSBErrorLevel, "Disable Port Failed\n"));
1961 gBS->FreePool (NewDevice);
1962 return ;
1963 }
1964
1965 HubSetPortFeature (
1966 UsbIo,
1967 StatusChangePort,
1968 EfiUsbPortReset
1969 );
1970
1971 gBS->Stall (50 * 1000);
1972
1973 //
1974 // Wait for port reset complete
1975 //
1976 Number = 10;
1977 do {
1978 HubGetPortStatus (
1979 UsbIo,
1980 StatusChangePort,
1981 (UINT32 *) &HubPortStatus
1982 );
1983 gBS->Stall (10 * 1000);
1984 Number -= 1;
1985 } while ((HubPortStatus.PortStatus & USB_PORT_STAT_RESET) == 1 && Number > 0);
1986
1987 if (Number == 0) {
1988 //
1989 // Cannot reset port, return error
1990 //
1991 DEBUG ((gUSBErrorLevel, "Reset Port Failed\n"));
1992 gBS->FreePool (NewDevice);
1993 return ;
1994 }
1995 //
1996 // Check high speed or full speed device
1997 //
1998 if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {
1999 DEBUG ((gUSBDebugLevel, "Low Speed Device Attached to Hub\n"));
2000 NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;
2001 } else if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {
2002 DEBUG ((gUSBDebugLevel, "High Speed Device Attached to Hub\n"));
2003 NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;
2004 } else {
2005 DEBUG ((gUSBDebugLevel, "Full Speed Device Attached to Hub\n"));
2006 NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;
2007 }
2008 //
2009 // Configure that device
2010 //
2011 Status = UsbDeviceConfiguration (
2012 HubController,
2013 HostController,
2014 (UINT8) (StatusChangePort - 1),
2015 NewDevice
2016 );
2017
2018 if (EFI_ERROR (Status)) {
2019 gBS->FreePool (NewDevice);
2020 return ;
2021 }
2022 //
2023 // Add this device to the usb bus tree
2024 // StatusChangePort is begin from 1,
2025 //
2026 HubController->Children[StatusChangePort - 1] = NewDevice;
2027
2028 for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
2029 //
2030 // If this device is hub, add to the hub index
2031 //
2032 NewController = NewDevice->UsbController[Index2];
2033
2034 //
2035 // Connect the controller to the driver image
2036 //
2037 Status = gBS->ConnectController (
2038 NewController->Handle,
2039 NULL,
2040 NULL,
2041 TRUE
2042 );
2043 //
2044 // If connect success, we need to disconnect when
2045 // stop the controller, otherwise we need not call
2046 // gBS->DisconnectController ()
2047 // This is used by those usb devices we don't plan
2048 // to support. We can allocate
2049 // controller handles for them, but we don't have
2050 // device drivers to manage them.
2051 //
2052 NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
2053
2054 //
2055 // If this device is hub, add to the hub index
2056 //
2057 if (IsHub (NewController)) {
2058
2059 NewController->IsUsbHub = TRUE;
2060
2061 //
2062 // Configure Hub
2063 //
2064 Status = DoHubConfig (NewController);
2065
2066 if (EFI_ERROR (Status)) {
2067 continue;
2068 }
2069 //
2070 // Create an event to do hub enumeration
2071 //
2072 gBS->CreateEvent (
2073 EFI_EVENT_NOTIFY_SIGNAL,
2074 EFI_TPL_CALLBACK,
2075 HubEnumeration,
2076 NewController,
2077 &NewController->HubNotify
2078 );
2079
2080 //
2081 // Add request to do query hub status
2082 // change endpoint
2083 //
2084 UsbIo = &NewController->UsbIo;
2085 UsbIo->UsbAsyncInterruptTransfer (
2086 UsbIo,
2087 NewController->HubEndpointAddress, // Hub endpoint address
2088 TRUE,
2089 100,
2090 1, // Hub ports < 7
2091 OnHubInterruptComplete,
2092 NewController
2093 );
2094 }
2095 }
2096 } else {
2097 //
2098 // Something disconnected from USB hub
2099 //
2100 DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));
2101
2102 OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
2103
2104 UsbDeviceDeConfiguration (OldUsbIoDevice);
2105
2106 HubController->Children[StatusChangePort - 1] = NULL;
2107
2108 }
2109
2110 return ;
2111 }
2112
2113 return ;
2114 }
2115
2116 STATIC
2117 USB_IO_CONTROLLER_DEVICE *
2118 CreateUsbIoControllerDevice (
2119 VOID
2120 )
2121 /*++
2122
2123 Routine Description:
2124 Allocate a structure for USB_IO_CONTROLLER_DEVICE
2125
2126 Arguments:
2127 N/A
2128
2129 Returns:
2130 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
2131 Or NULL.
2132
2133 --*/
2134 {
2135 USB_IO_CONTROLLER_DEVICE *UsbIoControllerDev;
2136
2137 //
2138 // Allocate USB_IO_CONTROLLER_DEVICE structure
2139 //
2140 UsbIoControllerDev = NULL;
2141 UsbIoControllerDev = AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE));
2142
2143 if (UsbIoControllerDev == NULL) {
2144 return NULL;
2145 }
2146
2147 UsbIoControllerDev->Signature = USB_IO_CONTROLLER_SIGNATURE;
2148
2149 return UsbIoControllerDev;
2150 }
2151
2152 STATIC
2153 EFI_STATUS
2154 InitUsbIoController (
2155 IN USB_IO_CONTROLLER_DEVICE *UsbIoController
2156 )
2157 /*++
2158
2159 Routine Description:
2160 Init and install EFI_USB_IO_PROTOCOL onto that controller.
2161
2162 Arguments:
2163 UsbIoController - The Controller to be operated.
2164
2165 Returns:
2166 EFI_SUCCESS
2167 Others
2168
2169 --*/
2170 {
2171 USB_DEVICE_PATH UsbNode;
2172 EFI_STATUS Status;
2173 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
2174 EFI_USB_HC_PROTOCOL *UsbHcProtocol;
2175 EFI_USB2_HC_PROTOCOL *Usb2HcProtocol;
2176
2177 //
2178 // Build the child device path for each new USB_IO device
2179 //
2180 ZeroMem (&UsbNode, sizeof (UsbNode));
2181 UsbNode.Header.Type = MESSAGING_DEVICE_PATH;
2182 UsbNode.Header.SubType = MSG_USB_DP;
2183 SetDevicePathNodeLength (&UsbNode.Header, sizeof (UsbNode));
2184 UsbNode.InterfaceNumber = UsbIoController->InterfaceNumber;
2185 UsbNode.ParentPortNumber = UsbIoController->ParentPort;
2186 ParentDevicePath = UsbIoController->Parent->DevicePath;
2187
2188 UsbIoController->DevicePath =
2189 AppendDevicePathNode (ParentDevicePath, &UsbNode.Header);
2190 if (UsbIoController->DevicePath == NULL) {
2191 return EFI_OUT_OF_RESOURCES;
2192 }
2193
2194 Status = gBS->InstallMultipleProtocolInterfaces (
2195 &UsbIoController->Handle,
2196 &gEfiDevicePathProtocolGuid,
2197 UsbIoController->DevicePath,
2198 &gEfiUsbIoProtocolGuid,
2199 &UsbIoController->UsbIo,
2200 NULL
2201 );
2202
2203 if (EFI_ERROR (Status)) {
2204 return Status;
2205 }
2206
2207 if (UsbIoController->UsbDevice->BusController->Hc2ProtocolSupported) {
2208 Status = gBS->OpenProtocol (
2209 UsbIoController->HostController,
2210 &gEfiUsb2HcProtocolGuid,
2211 (VOID **)&Usb2HcProtocol,
2212 gUsbBusDriverBinding.DriverBindingHandle,
2213 UsbIoController->Handle,
2214 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2215 );
2216 } else {
2217 Status = gBS->OpenProtocol (
2218 UsbIoController->HostController,
2219 &gEfiUsbHcProtocolGuid,
2220 (VOID **)&UsbHcProtocol,
2221 gUsbBusDriverBinding.DriverBindingHandle,
2222 UsbIoController->Handle,
2223 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2224 );
2225 }
2226
2227 return Status;
2228 }
2229
2230 STATIC
2231 EFI_STATUS
2232 ParentPortReset (
2233 IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
2234 IN BOOLEAN ReConfigure,
2235 IN UINT8 RetryTimes
2236 )
2237 /*++
2238
2239 Routine Description:
2240 Reset parent hub port to which this device is connected.
2241
2242 Arguments:
2243 UsbIoController - Indicating the Usb Controller Device.
2244 ReConfigure - Do we need to reconfigure it.
2245 RetryTimes - Retry Times when failed
2246
2247 Returns:
2248 EFI_SUCCESS
2249 EFI_DEVICE_ERROR
2250
2251 --*/
2252 {
2253 USB_IO_DEVICE *ParentIoDev;
2254 USB_IO_DEVICE *UsbIoDev;
2255 USB_IO_CONTROLLER_DEVICE *ParentController;
2256 UINT8 HubPort;
2257 UINT32 Status;
2258 EFI_STATUS Result;
2259 EFI_USB_IO_PROTOCOL *UsbIo;
2260 UINT8 Address;
2261
2262 ParentController = UsbIoController->Parent;
2263 ParentIoDev = ParentController->UsbDevice;
2264 UsbIoDev = UsbIoController->UsbDevice;
2265 HubPort = UsbIoController->ParentPort;
2266
2267 gBS->Stall (100 * 1000);
2268
2269 if (ParentIoDev->DeviceAddress == 1) {
2270 DEBUG ((gUSBDebugLevel, "Reset from Root Hub 0x%x\n", HubPort));
2271 ResetRootPort (ParentIoDev->BusController, HubPort, RetryTimes);
2272 } else {
2273 DEBUG ((gUSBDebugLevel, "Reset from Hub, Addr 0x%x\n", ParentIoDev->DeviceAddress));
2274 ResetHubPort (ParentController, HubPort + 1);
2275 }
2276 //
2277 // If we only need port reset, just return
2278 //
2279 if (!ReConfigure) {
2280 return EFI_SUCCESS;
2281 }
2282 //
2283 // Re-config that USB device
2284 //
2285 UsbIo = &UsbIoController->UsbIo;
2286
2287 //
2288 // Assign a unique address to this device
2289 //
2290 Address = UsbIoDev->DeviceAddress;
2291 UsbIoDev->DeviceAddress = 0;
2292
2293 Result = UsbSetDeviceAddress (UsbIo, Address, &Status);
2294 UsbIoDev->DeviceAddress = Address;
2295
2296 if (EFI_ERROR (Result)) {
2297 return EFI_DEVICE_ERROR;
2298 }
2299 //
2300 // Set the device to the default configuration
2301 //
2302 Result = UsbSetDefaultConfiguration (UsbIoDev);
2303 if (EFI_ERROR (Result)) {
2304 return EFI_DEVICE_ERROR;
2305 }
2306
2307 return EFI_SUCCESS;
2308 }
2309
2310 EFI_STATUS
2311 EFIAPI
2312 UsbPortReset (
2313 IN EFI_USB_IO_PROTOCOL *This
2314 )
2315 /*++
2316
2317 Routine Description:
2318 Resets and reconfigures the USB controller. This function will
2319 work for all USB devices except USB Hub Controllers.
2320
2321 Arguments:
2322 This - Indicates the calling context.
2323
2324 Returns:
2325 EFI_SUCCESS
2326 EFI_INVALID_PARAMETER
2327 EFI_DEVICE_ERROR
2328
2329 --*/
2330 {
2331 USB_IO_CONTROLLER_DEVICE *UsbIoController;
2332
2333 UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
2334
2335 if (IsHub (UsbIoController)) {
2336 return EFI_INVALID_PARAMETER;
2337 }
2338
2339 //
2340 // Since at this time, this device has already been configured,
2341 // it needs to be re-configured.
2342 //
2343 return ParentPortReset (UsbIoController, TRUE, 0);
2344 }
2345
2346 EFI_STATUS
2347 ResetRootPort (
2348 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2349 IN UINT8 PortNum,
2350 IN UINT8 RetryTimes
2351 )
2352 /*++
2353
2354 Routine Description:
2355 Reset Root Hub port.
2356
2357 Arguments:
2358 UsbBusDev - Bus controller of the device.
2359 PortNum - The given port to be reset.
2360 RetryTimes - RetryTimes when failed
2361
2362 Returns:
2363 EFI_SUCCESS
2364 EFI_DEVICE_ERROR
2365
2366 --*/
2367 {
2368 EFI_STATUS Status;
2369 EFI_USB_PORT_STATUS PortStatus;
2370
2371 //
2372 // reset root port
2373 //
2374 Status = UsbVirtualHcSetRootHubPortFeature (
2375 UsbBusDev,
2376 PortNum,
2377 EfiUsbPortReset
2378 );
2379 if (EFI_ERROR (Status)) {
2380 return EFI_DEVICE_ERROR;
2381 }
2382
2383 gBS->Stall (50 * 1000);
2384
2385 //
2386 // clear reset root port
2387 //
2388 Status = UsbVirtualHcClearRootHubPortFeature (
2389 UsbBusDev,
2390 PortNum,
2391 EfiUsbPortReset
2392 );
2393 if (EFI_ERROR (Status)) {
2394 return EFI_DEVICE_ERROR;
2395 }
2396
2397 gBS->Stall (1000);
2398
2399 Status = UsbVirtualHcClearRootHubPortFeature (
2400 UsbBusDev,
2401 PortNum,
2402 EfiUsbPortConnectChange
2403 );
2404 if (EFI_ERROR (Status)) {
2405 return EFI_DEVICE_ERROR;
2406 }
2407
2408 UsbVirtualHcGetRootHubPortStatus (
2409 UsbBusDev,
2410 PortNum,
2411 &PortStatus
2412 );
2413 if (PortStatus.PortStatus & USB_PORT_STAT_OWNER) {
2414 //
2415 // Set port enable
2416 //
2417 Status = UsbVirtualHcSetRootHubPortFeature (
2418 UsbBusDev,
2419 PortNum,
2420 EfiUsbPortEnable
2421 );
2422 if (EFI_ERROR (Status)) {
2423 return EFI_DEVICE_ERROR;
2424 }
2425
2426 Status = UsbVirtualHcClearRootHubPortFeature (
2427 UsbBusDev,
2428 PortNum,
2429 EfiUsbPortEnableChange
2430 );
2431 }
2432
2433 gBS->Stall ((1 + RetryTimes) * 50 * 1000);
2434
2435 return EFI_SUCCESS;
2436 }
2437
2438 EFI_STATUS
2439 ResetHubPort (
2440 IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
2441 IN UINT8 PortIndex
2442 )
2443 /*++
2444
2445 Routine Description:
2446 Reset Hub port.
2447
2448 Arguments:
2449 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2450 PortIndex - The given port to be reset.
2451
2452 Returns:
2453 EFI_SUCCESS
2454 EFI_DEVICE_ERROR
2455
2456 --*/
2457 {
2458 EFI_USB_IO_PROTOCOL *UsbIo;
2459 EFI_USB_PORT_STATUS HubPortStatus;
2460 UINT8 Number;
2461
2462 ASSERT (UsbIoController->IsUsbHub == TRUE);
2463
2464 UsbIo = &UsbIoController->UsbIo;
2465
2466 HubSetPortFeature (
2467 UsbIo,
2468 PortIndex,
2469 EfiUsbPortReset
2470 );
2471
2472 gBS->Stall (10 * 1000);
2473
2474 //
2475 // Wait for port reset complete
2476 //
2477 Number = 10;
2478 do {
2479 HubGetPortStatus (
2480 UsbIo,
2481 PortIndex,
2482 (UINT32 *) &HubPortStatus
2483 );
2484 gBS->Stall (10 * 100);
2485 Number -= 1;
2486 } while ((HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0 && Number > 0);
2487
2488 if (Number == 0) {
2489 //
2490 // Cannot reset port, return error
2491 //
2492 return EFI_DEVICE_ERROR;
2493 }
2494
2495 gBS->Stall (1000);
2496
2497 HubGetPortStatus (
2498 UsbIo,
2499 PortIndex,
2500 (UINT32 *) &HubPortStatus
2501 );
2502 //
2503 // reset port will cause some bits change, clear them
2504 //
2505 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {
2506 DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));
2507 HubClearPortFeature (
2508 UsbIo,
2509 PortIndex,
2510 EfiUsbPortEnableChange
2511 );
2512 }
2513
2514 if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {
2515 DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));
2516 HubClearPortFeature (
2517 UsbIo,
2518 PortIndex,
2519 EfiUsbPortResetChange
2520 );
2521 }
2522
2523 return EFI_SUCCESS;
2524 }
2525
2526 STATIC
2527 EFI_STATUS
2528 ReportUsbStatusCode (
2529 IN USB_BUS_CONTROLLER_DEVICE *UsbBusController,
2530 IN EFI_STATUS_CODE_TYPE Type,
2531 IN EFI_STATUS_CODE_VALUE Code
2532 )
2533 /*++
2534
2535 Routine Description:
2536
2537 report a error Status code of USB bus driver controller
2538
2539 Arguments:
2540 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2541 Type - EFI_STATUS_CODE_TYPE
2542 Code - EFI_STATUS_CODE_VALUE
2543 Returns:
2544
2545 None
2546
2547 --*/
2548 {
2549 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2550 Type,
2551 Code,
2552 UsbBusController->DevicePath
2553 );
2554 }
2555
2556 EFI_STATUS
2557 IsDeviceDisconnected (
2558 IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
2559 IN OUT BOOLEAN *Disconnected
2560 )
2561 /*++
2562
2563 Routine Description:
2564 Reset if the device is disconencted or not
2565
2566 Arguments:
2567 UsbIoController - Indicating the Usb Controller Device.
2568 Disconnected - Indicate whether the device is disconencted or not
2569
2570 Returns:
2571 EFI_SUCCESS
2572 EFI_DEVICE_ERROR
2573
2574 --*/
2575 {
2576 USB_IO_DEVICE *ParentIoDev;
2577 USB_IO_DEVICE *UsbIoDev;
2578 USB_IO_CONTROLLER_DEVICE *ParentController;
2579 UINT8 HubPort;
2580 EFI_STATUS Status;
2581 EFI_USB_IO_PROTOCOL *UsbIo;
2582 EFI_USB_PORT_STATUS PortStatus;
2583
2584 ParentController = UsbIoController->Parent;
2585 ParentIoDev = ParentController->UsbDevice;
2586 UsbIoDev = UsbIoController->UsbDevice;
2587 HubPort = UsbIoController->ParentPort;
2588
2589 if (ParentIoDev->DeviceAddress == 1) {
2590 //
2591 // Connected to the root hub
2592 //
2593 UsbVirtualHcGetRootHubPortStatus (
2594 ParentIoDev->BusController,
2595 HubPort,
2596 &PortStatus
2597 );
2598
2599 } else {
2600 UsbIo = &UsbIoController->UsbIo;
2601 Status = HubGetPortStatus (
2602 &ParentController->UsbIo,
2603 HubPort + 1,
2604 (UINT32 *) &PortStatus
2605 );
2606
2607 if (EFI_ERROR (Status)) {
2608 return IsDeviceDisconnected (ParentController, Disconnected);
2609 }
2610 }
2611
2612 *Disconnected = FALSE;
2613
2614 if (!IsPortConnect (PortStatus.PortStatus)) {
2615 *Disconnected = TRUE;
2616 }
2617
2618 return EFI_SUCCESS;
2619 }
2620
2621 STATIC
2622 EFI_STATUS
2623 UsbSetTransactionTranslator (
2624 IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
2625 IN UINT8 ParentPort,
2626 IN OUT USB_IO_DEVICE *Device
2627 )
2628 /*++
2629
2630 Routine Description:
2631
2632 Set Transaction Translator parameter
2633
2634 Arguments:
2635
2636 ParentHubController - Controller structure of the parent Hub device
2637 ParentPort - Number of parent port
2638 Device - Structure of the device
2639
2640 Returns:
2641
2642 EFI_SUCCESS Success
2643 EFI_OUT_OF_RESOURCES Cannot allocate resources
2644
2645 --*/
2646 {
2647 USB_IO_CONTROLLER_DEVICE *AncestorHubController;
2648
2649 AncestorHubController = ParentHubController;
2650 Device->Translator = NULL;
2651
2652 if (EFI_USB_SPEED_HIGH == Device->DeviceSpeed) {
2653 return EFI_SUCCESS;
2654 }
2655
2656 do {
2657 if (EFI_USB_SPEED_HIGH == AncestorHubController->UsbDevice->DeviceSpeed) {
2658 break;
2659 }
2660
2661 if (NULL == AncestorHubController->Parent) {
2662 return EFI_SUCCESS;
2663 }
2664
2665 AncestorHubController = AncestorHubController->Parent;
2666 } while (1);
2667
2668 Device->Translator = AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR));
2669 if (NULL == Device->Translator) {
2670 return EFI_OUT_OF_RESOURCES;
2671 }
2672
2673 Device->Translator->TranslatorHubAddress = AncestorHubController->UsbDevice->DeviceAddress;
2674 Device->Translator->TranslatorPortNumber = ParentPort;
2675
2676 return EFI_SUCCESS;
2677 }
2678
2679 STATIC
2680 EFI_STATUS
2681 UsbUnsetTransactionTranslator (
2682 USB_IO_DEVICE *Device
2683 )
2684 /*++
2685
2686 Routine Description:
2687
2688 Unset Transaction Translator parameter
2689
2690 Arguments:
2691
2692 Device - Structure of the device
2693
2694 Returns:
2695
2696 EFI_SUCCESS Success
2697
2698 --*/
2699 {
2700 if (Device->Translator) {
2701 gBS->FreePool (Device->Translator);
2702 Device->Translator = NULL;
2703 }
2704
2705 return EFI_SUCCESS;
2706 }
2707
2708 STATIC
2709 EFI_STATUS
2710 IdentifyDeviceSpeed (
2711 USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2712 USB_IO_DEVICE *NewDevice,
2713 UINT8 Index
2714 )
2715 /*++
2716
2717 Routine Description:
2718
2719 Identify speed of USB device
2720
2721 Arguments:
2722
2723 UsbBusDev - UsbBus controller structure of the device
2724 NewDevice - Devcie controller structure
2725 Index - Number of the port
2726
2727 Returns:
2728
2729 EFI_SUCCESS Success
2730 EFI_NOT_FOUND Device release to CHC or can't be found
2731
2732 --*/
2733 {
2734 EFI_STATUS Status;
2735 EFI_USB_PORT_STATUS HubPortStatus;
2736
2737 UsbVirtualHcGetRootHubPortStatus (
2738 UsbBusDev,
2739 Index,
2740 (EFI_USB_PORT_STATUS *) &HubPortStatus
2741 );
2742
2743 //
2744 // Check device device
2745 //
2746 if (!(HubPortStatus.PortStatus & USB_PORT_STAT_OWNER)) {
2747 //
2748 // EHC Port Owner
2749 //
2750 if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {
2751 DEBUG ((gUSBDebugLevel, "High Speed Device attached to EHC\n"));
2752 NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;
2753 } else {
2754 Status = ReleasePortToCHC (UsbBusDev, Index);
2755 if (EFI_ERROR (Status)) {
2756 DEBUG ((gUSBErrorLevel, "Fail to release port to CHC\n"));
2757 } else {
2758 DEBUG ((gUSBDebugLevel, "Success to release port to CHC\n"));
2759 }
2760 return EFI_DEVICE_ERROR;
2761 }
2762 } else {
2763 //
2764 // CHC Port Owner
2765 //
2766 if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {
2767 DEBUG ((gUSBDebugLevel, "Low Speed Device attached to CHC\n"));
2768 NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;
2769 } else {
2770 DEBUG ((gUSBDebugLevel, "FULL Speed Device attached to CHC\n"));
2771 NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;
2772 }
2773 }
2774
2775 return EFI_SUCCESS;
2776 }
2777
2778 STATIC
2779 EFI_STATUS
2780 ReleasePortToCHC (
2781 USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2782 UINT8 PortNum
2783 )
2784 /*++
2785
2786 Routine Description:
2787
2788 Set bit to release the port owner to CHC
2789
2790 Arguments:
2791
2792 UsbBusDev - UsbBus controller structure of the device
2793 PortNum - Number of the port
2794
2795 Returns:
2796
2797 EFI_SUCCESS Success
2798 EFI_DEVICE_ERROR Fail
2799
2800 --*/
2801 {
2802 EFI_STATUS Status;
2803
2804 Status = UsbVirtualHcSetRootHubPortFeature (
2805 UsbBusDev,
2806 PortNum,
2807 EfiUsbPortOwner
2808 );
2809
2810 gBS->Stall (100 * 1000);
2811
2812 return Status;
2813 }
2814
2815 EFI_STATUS
2816 EFIAPI
2817 UsbVirtualHcGetCapability (
2818 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2819 OUT UINT8 *MaxSpeed,
2820 OUT UINT8 *PortNumber,
2821 OUT UINT8 *Is64BitCapable
2822 )
2823 /*++
2824
2825 Routine Description:
2826
2827 Virtual interface to Retrieves the capablility of root hub ports
2828 for both Hc2 and Hc protocol.
2829
2830 Arguments:
2831
2832 UsbBusDev - A pointer to bus controller of the device.
2833 MaxSpeed - A pointer to the number of the host controller.
2834 PortNumber - A pointer to the number of the root hub ports.
2835 Is64BitCapable - A pointer to the flag for whether controller supports
2836 64-bit memory addressing.
2837
2838 Returns:
2839
2840 EFI_SUCCESS
2841 The host controller capability were retrieved successfully.
2842 EFI_INVALID_PARAMETER
2843 MaxSpeed or PortNumber or Is64BitCapable is NULL.
2844 EFI_DEVICE_ERROR
2845 An error was encountered while attempting to retrieve the capabilities.
2846
2847 --*/
2848 {
2849 EFI_STATUS Status;
2850
2851 Status = EFI_SUCCESS;
2852
2853 if (UsbBusDev->Hc2ProtocolSupported) {
2854 Status = UsbBusDev->Usb2HCInterface->GetCapability (
2855 UsbBusDev->Usb2HCInterface,
2856 MaxSpeed,
2857 PortNumber,
2858 Is64BitCapable
2859 );
2860 } else {
2861 Status = UsbBusDev->UsbHCInterface->GetRootHubPortNumber (
2862 UsbBusDev->UsbHCInterface,
2863 PortNumber
2864 );
2865 *MaxSpeed = EFI_USB_SPEED_FULL;
2866 *Is64BitCapable = (UINT8) FALSE;
2867 }
2868
2869 return Status;
2870 }
2871
2872 EFI_STATUS
2873 EFIAPI
2874 UsbVirtualHcReset (
2875 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2876 IN UINT16 Attributes
2877 )
2878 /*++
2879
2880 Routine Description:
2881
2882 Virtual interface to provides software reset for the USB host controller
2883 for both Hc2 and Hc protocol.
2884
2885 Arguments:
2886
2887 UsbBusDev - A pointer to bus controller of the device.
2888 Attributes - A bit mask of the reset operation to perform.
2889 See below for a list of the supported bit mask values.
2890
2891 #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
2892 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
2893 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
2894 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
2895
2896 EFI_USB_HC_RESET_GLOBAL
2897 If this bit is set, a global reset signal will be sent to the USB bus.
2898 This resets all of the USB bus logic, including the USB host
2899 controller hardware and all the devices attached on the USB bus.
2900 EFI_USB_HC_RESET_HOST_CONTROLLER
2901 If this bit is set, the USB host controller hardware will be reset.
2902 No reset signal will be sent to the USB bus.
2903 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
2904 If this bit is set, a global reset signal will be sent to the USB bus.
2905 This resets all of the USB bus logic, including the USB host
2906 controller hardware and all the devices attached on the USB bus.
2907 If this is an EHCI controller and the debug port has configured, then
2908 this is will still reset the host controller.
2909 EFI_USB_HC_RESET_HOST_WITH_DEBUG
2910 If this bit is set, the USB host controller hardware will be reset.
2911 If this is an EHCI controller and the debug port has been configured,
2912 then this will still reset the host controller.
2913
2914 Returns:
2915
2916 EFI_SUCCESS
2917 The reset operation succeeded.
2918 EFI_INVALID_PARAMETER
2919 Attributes is not valid.
2920 EFI_UNSUPPOURTED
2921 The type of reset specified by Attributes is not currently supported by
2922 the host controller hardware.
2923 EFI_ACCESS_DENIED
2924 Reset operation is rejected due to the debug port being configured and
2925 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
2926 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
2927 perform reset operation for this host controller.
2928 EFI_DEVICE_ERROR
2929 An error was encountered while attempting to perform
2930 the reset operation.
2931
2932 --*/
2933 {
2934 EFI_STATUS Status;
2935
2936 Status = EFI_SUCCESS;
2937
2938 if (UsbBusDev->Hc2ProtocolSupported) {
2939 Status = UsbBusDev->Usb2HCInterface->Reset (
2940 UsbBusDev->Usb2HCInterface,
2941 EFI_USB_HC_RESET_GLOBAL
2942 );
2943 } else {
2944 Status = UsbBusDev->UsbHCInterface->Reset (
2945 UsbBusDev->UsbHCInterface,
2946 EFI_USB_HC_RESET_GLOBAL
2947 );
2948 }
2949
2950 return Status;
2951 }
2952
2953 EFI_STATUS
2954 EFIAPI
2955 UsbVirtualHcGetState (
2956 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
2957 OUT EFI_USB_HC_STATE *State
2958 )
2959 /*++
2960
2961 Routine Description:
2962
2963 Virtual interface to retrieves current state of the USB host controller
2964 for both Hc2 and Hc protocol.
2965
2966 Arguments:
2967
2968 UsbBusDev - A pointer to bus controller of the device.
2969 State - A pointer to the EFI_USB_HC_STATE data structure that
2970 indicates current state of the USB host controller.
2971 Type EFI_USB_HC_STATE is defined below.
2972
2973 typedef enum {
2974 EfiUsbHcStateHalt,
2975 EfiUsbHcStateOperational,
2976 EfiUsbHcStateSuspend,
2977 EfiUsbHcStateMaximum
2978 } EFI_USB_HC_STATE;
2979
2980 Returns:
2981
2982 EFI_SUCCESS
2983 The state information of the host controller was returned in State.
2984 EFI_INVALID_PARAMETER
2985 State is NULL.
2986 EFI_DEVICE_ERROR
2987 An error was encountered while attempting to retrieve the
2988 host controller's current state.
2989
2990 --*/
2991 {
2992 EFI_STATUS Status;
2993
2994 Status = EFI_SUCCESS;
2995
2996 if (UsbBusDev->Hc2ProtocolSupported) {
2997 Status = UsbBusDev->Usb2HCInterface->GetState (
2998 UsbBusDev->Usb2HCInterface,
2999 State
3000 );
3001 } else {
3002 Status = UsbBusDev->UsbHCInterface->GetState (
3003 UsbBusDev->UsbHCInterface,
3004 State
3005 );
3006 }
3007
3008 return Status;
3009 }
3010
3011 EFI_STATUS
3012 EFIAPI
3013 UsbVirtualHcSetState (
3014 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3015 IN EFI_USB_HC_STATE State
3016 )
3017 /*++
3018
3019 Routine Description:
3020
3021 Virtual interface to sets the USB host controller to a specific state
3022 for both Hc2 and Hc protocol.
3023
3024 Arguments:
3025
3026 UsbBusDev - A pointer to bus controller of the device.
3027 State - Indicates the state of the host controller that will be set.
3028
3029 Returns:
3030
3031 EFI_SUCCESS
3032 The USB host controller was successfully placed in the state
3033 specified by State.
3034 EFI_INVALID_PARAMETER
3035 State is invalid.
3036 EFI_DEVICE_ERROR
3037 Failed to set the state specified by State due to device error.
3038
3039 --*/
3040 {
3041 EFI_STATUS Status;
3042
3043 Status = EFI_SUCCESS;
3044
3045 if (UsbBusDev->Hc2ProtocolSupported) {
3046 Status = UsbBusDev->Usb2HCInterface->SetState (
3047 UsbBusDev->Usb2HCInterface,
3048 State
3049 );
3050 } else {
3051 Status = UsbBusDev->UsbHCInterface->SetState (
3052 UsbBusDev->UsbHCInterface,
3053 State
3054 );
3055 }
3056
3057 return Status;
3058 }
3059
3060 EFI_STATUS
3061 EFIAPI
3062 UsbVirtualHcGetRootHubPortStatus (
3063 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3064 IN UINT8 PortNumber,
3065 OUT EFI_USB_PORT_STATUS *PortStatus
3066 )
3067 /*++
3068
3069 Routine Description:
3070
3071 Virtual interface to retrieves the current status of a USB root hub port
3072 both for Hc2 and Hc protocol.
3073
3074 Arguments:
3075
3076 UsbBusDev - A pointer to bus controller of the device.
3077 PortNumber - Specifies the root hub port from which the status
3078 is to be retrieved. This value is zero-based. For example,
3079 if a root hub has two ports, then the first port is numbered 0,
3080 and the second port is numbered 1.
3081 PortStatus - A pointer to the current port status bits and
3082 port status change bits.
3083
3084 Returns:
3085
3086 EFI_SUCCESS The status of the USB root hub port specified by PortNumber
3087 was returned in PortStatus.
3088 EFI_INVALID_PARAMETER PortNumber is invalid.
3089 EFI_DEVICE_ERROR Can't read register
3090
3091 --*/
3092 {
3093 EFI_STATUS Status;
3094
3095 Status = EFI_SUCCESS;
3096
3097 if (UsbBusDev->Hc2ProtocolSupported) {
3098 Status = UsbBusDev->Usb2HCInterface->GetRootHubPortStatus (
3099 UsbBusDev->Usb2HCInterface,
3100 PortNumber,
3101 PortStatus
3102 );
3103 } else {
3104 Status = UsbBusDev->UsbHCInterface->GetRootHubPortStatus (
3105 UsbBusDev->UsbHCInterface,
3106 PortNumber,
3107 PortStatus
3108 );
3109 }
3110
3111 return Status;
3112 }
3113
3114 EFI_STATUS
3115 EFIAPI
3116 UsbVirtualHcSetRootHubPortFeature (
3117 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3118 IN UINT8 PortNumber,
3119 IN EFI_USB_PORT_FEATURE PortFeature
3120 )
3121 /*++
3122
3123 Routine Description:
3124 Virual interface to sets a feature for the specified root hub port
3125 for both Hc2 and Hc protocol.
3126
3127 Arguments:
3128
3129 UsbBusDev - A pointer to bus controller of the device.
3130 PortNumber - Specifies the root hub port whose feature
3131 is requested to be set.
3132 PortFeature - Indicates the feature selector associated
3133 with the feature set request.
3134
3135 Returns:
3136
3137 EFI_SUCCESS
3138 The feature specified by PortFeature was set for the
3139 USB root hub port specified by PortNumber.
3140 EFI_INVALID_PARAMETER
3141 PortNumber is invalid or PortFeature is invalid.
3142 EFI_DEVICE_ERROR
3143 Can't read register
3144
3145 --*/
3146 {
3147 EFI_STATUS Status;
3148
3149 Status = EFI_SUCCESS;
3150
3151 if (UsbBusDev->Hc2ProtocolSupported) {
3152 Status = UsbBusDev->Usb2HCInterface->SetRootHubPortFeature (
3153 UsbBusDev->Usb2HCInterface,
3154 PortNumber,
3155 PortFeature
3156 );
3157 } else {
3158 Status = UsbBusDev->UsbHCInterface->SetRootHubPortFeature (
3159 UsbBusDev->UsbHCInterface,
3160 PortNumber,
3161 PortFeature
3162 );
3163 }
3164
3165 return Status;
3166 }
3167
3168 EFI_STATUS
3169 EFIAPI
3170 UsbVirtualHcClearRootHubPortFeature (
3171 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3172 IN UINT8 PortNumber,
3173 IN EFI_USB_PORT_FEATURE PortFeature
3174 )
3175 /*++
3176
3177 Routine Description:
3178
3179 Virtual interface to clears a feature for the specified root hub port
3180 for both Hc2 and Hc protocol.
3181
3182 Arguments:
3183
3184 UsbBusDev - A pointer to bus controller of the device.
3185 PortNumber - Specifies the root hub port whose feature
3186 is requested to be cleared.
3187 PortFeature - Indicates the feature selector associated with the
3188 feature clear request.
3189
3190 Returns:
3191
3192 EFI_SUCCESS
3193 The feature specified by PortFeature was cleared for the
3194 USB root hub port specified by PortNumber.
3195 EFI_INVALID_PARAMETER
3196 PortNumber is invalid or PortFeature is invalid.
3197 EFI_DEVICE_ERROR
3198 Can't read register
3199
3200 --*/
3201 {
3202 EFI_STATUS Status;
3203
3204 Status = EFI_SUCCESS;
3205
3206 if (UsbBusDev->Hc2ProtocolSupported) {
3207 Status = UsbBusDev->Usb2HCInterface->ClearRootHubPortFeature (
3208 UsbBusDev->Usb2HCInterface,
3209 PortNumber,
3210 PortFeature
3211 );
3212 } else {
3213 Status = UsbBusDev->UsbHCInterface->ClearRootHubPortFeature (
3214 UsbBusDev->UsbHCInterface,
3215 PortNumber,
3216 PortFeature
3217 );
3218 }
3219
3220 return Status;
3221 }
3222
3223 EFI_STATUS
3224 EFIAPI
3225 UsbVirtualHcControlTransfer (
3226 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3227 IN UINT8 DeviceAddress,
3228 IN UINT8 DeviceSpeed,
3229 IN UINTN MaximumPacketLength,
3230 IN EFI_USB_DEVICE_REQUEST *Request,
3231 IN EFI_USB_DATA_DIRECTION TransferDirection,
3232 IN OUT VOID *Data,
3233 IN OUT UINTN *DataLength,
3234 IN UINTN TimeOut,
3235 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3236 OUT UINT32 *TransferResult
3237 )
3238 /*++
3239
3240 Routine Description:
3241
3242 Virtual interface to submits control transfer to a target USB device
3243 for both Hc2 and Hc protocol.
3244
3245 Arguments:
3246
3247 UsbBusDev - A pointer to bus controller of the device.
3248 DeviceAddress - Represents the address of the target device on the USB,
3249 which is assigned during USB enumeration.
3250 DeviceSpeed - Indicates target device speed.
3251 MaximumPacketLength - Indicates the maximum packet size that the
3252 default control transfer endpoint is capable of
3253 sending or receiving.
3254 Request - A pointer to the USB device request that will be sent
3255 to the USB device.
3256 TransferDirection - Specifies the data direction for the transfer.
3257 There are three values available, DataIn, DataOut
3258 and NoData.
3259 Data - A pointer to the buffer of data that will be transmitted
3260 to USB device or received from USB device.
3261 DataLength - Indicates the size, in bytes, of the data buffer
3262 specified by Data.
3263 TimeOut - Indicates the maximum time, in microseconds,
3264 which the transfer is allowed to complete.
3265 Translator - A pointr to the transaction translator data.
3266 TransferResult - A pointer to the detailed result information generated
3267 by this control transfer.
3268
3269 Returns:
3270
3271 EFI_SUCCESS
3272 The control transfer was completed successfully.
3273 EFI_OUT_OF_RESOURCES
3274 The control transfer could not be completed due to a lack of resources.
3275 EFI_INVALID_PARAMETER
3276 Some parameters are invalid.
3277 EFI_TIMEOUT
3278 The control transfer failed due to timeout.
3279 EFI_DEVICE_ERROR
3280 The control transfer failed due to host controller or device error.
3281 Caller should check TranferResult for detailed error information.
3282
3283 --*/
3284 {
3285 EFI_STATUS Status;
3286 BOOLEAN IsSlowDevice;
3287
3288 Status = EFI_SUCCESS;
3289
3290 if (UsbBusDev->Hc2ProtocolSupported) {
3291 Status = UsbBusDev->Usb2HCInterface->ControlTransfer (
3292 UsbBusDev->Usb2HCInterface,
3293 DeviceAddress,
3294 DeviceSpeed,
3295 MaximumPacketLength,
3296 Request,
3297 TransferDirection,
3298 Data,
3299 DataLength,
3300 TimeOut,
3301 Translator,
3302 TransferResult
3303 );
3304 } else {
3305 IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
3306 Status = UsbBusDev->UsbHCInterface->ControlTransfer (
3307 UsbBusDev->UsbHCInterface,
3308 DeviceAddress,
3309 IsSlowDevice,
3310 (UINT8) MaximumPacketLength,
3311 Request,
3312 TransferDirection,
3313 Data,
3314 DataLength,
3315 TimeOut,
3316 TransferResult
3317 );
3318 }
3319
3320 return Status;
3321 }
3322
3323 EFI_STATUS
3324 EFIAPI
3325 UsbVirtualHcBulkTransfer (
3326 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3327 IN UINT8 DeviceAddress,
3328 IN UINT8 EndPointAddress,
3329 IN UINT8 DeviceSpeed,
3330 IN UINTN MaximumPacketLength,
3331 IN UINT8 DataBuffersNumber,
3332 IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
3333 IN OUT UINTN *DataLength,
3334 IN OUT UINT8 *DataToggle,
3335 IN UINTN TimeOut,
3336 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3337 OUT UINT32 *TransferResult
3338 )
3339 /*++
3340
3341 Routine Description:
3342
3343 Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
3344 both for Hc2 and Hc protocol.
3345
3346 Arguments:
3347
3348 UsbBusDev - A pointer to bus controller of the device.
3349 DeviceAddress - Represents the address of the target device on the USB,
3350 which is assigned during USB enumeration.
3351 EndPointAddress - The combination of an endpoint number and an
3352 endpoint direction of the target USB device.
3353 Each endpoint address supports data transfer in
3354 one direction except the control endpoint
3355 (whose default endpoint address is 0).
3356 It is the caller's responsibility to make sure that
3357 the EndPointAddress represents a bulk endpoint.
3358 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
3359 and EFI_USB_SPEED_HIGH.
3360 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3361 is capable of sending or receiving.
3362 DataBuffersNumber - Number of data buffers prepared for the transfer.
3363 Data - Array of pointers to the buffers of data that will be transmitted
3364 to USB device or received from USB device.
3365 DataLength - When input, indicates the size, in bytes, of the data buffer
3366 specified by Data. When output, indicates the actually
3367 transferred data size.
3368 DataToggle - A pointer to the data toggle value. On input, it indicates
3369 the initial data toggle value the bulk transfer should adopt;
3370 on output, it is updated to indicate the data toggle value
3371 of the subsequent bulk transfer.
3372 Translator - A pointr to the transaction translator data.
3373 TimeOut - Indicates the maximum time, in microseconds, which the
3374 transfer is allowed to complete.
3375 TransferResult - A pointer to the detailed result information of the
3376 bulk transfer.
3377
3378 Returns:
3379
3380 EFI_SUCCESS
3381 The bulk transfer was completed successfully.
3382 EFI_OUT_OF_RESOURCES
3383 The bulk transfer could not be submitted due to lack of resource.
3384 EFI_INVALID_PARAMETER
3385 Some parameters are invalid.
3386 EFI_TIMEOUT
3387 The bulk transfer failed due to timeout.
3388 EFI_DEVICE_ERROR
3389 The bulk transfer failed due to host controller or device error.
3390 Caller should check TranferResult for detailed error information.
3391
3392 --*/
3393 {
3394 EFI_STATUS Status;
3395
3396 Status = EFI_SUCCESS;
3397
3398 if (UsbBusDev->Hc2ProtocolSupported) {
3399 Status = UsbBusDev->Usb2HCInterface->BulkTransfer (
3400 UsbBusDev->Usb2HCInterface,
3401 DeviceAddress,
3402 EndPointAddress,
3403 DeviceSpeed,
3404 MaximumPacketLength,
3405 DataBuffersNumber,
3406 Data,
3407 DataLength,
3408 DataToggle,
3409 TimeOut,
3410 Translator,
3411 TransferResult
3412 );
3413 } else {
3414 Status = UsbBusDev->UsbHCInterface->BulkTransfer (
3415 UsbBusDev->UsbHCInterface,
3416 DeviceAddress,
3417 EndPointAddress,
3418 (UINT8) MaximumPacketLength,
3419 *Data,
3420 DataLength,
3421 DataToggle,
3422 TimeOut,
3423 TransferResult
3424 );
3425 }
3426
3427 return Status;
3428 }
3429
3430 EFI_STATUS
3431 EFIAPI
3432 UsbVirtualHcAsyncInterruptTransfer (
3433 IN USB_BUS_CONTROLLER_DEVICE * UsbBusDev,
3434 IN UINT8 DeviceAddress,
3435 IN UINT8 EndPointAddress,
3436 IN UINT8 DeviceSpeed,
3437 IN UINTN MaximumPacketLength,
3438 IN BOOLEAN IsNewTransfer,
3439 IN OUT UINT8 *DataToggle,
3440 IN UINTN PollingInterval,
3441 IN UINTN DataLength,
3442 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,
3443 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
3444 IN VOID *Context OPTIONAL
3445 )
3446 /*++
3447
3448 Routine Description:
3449
3450 Virtual interface to submits an asynchronous interrupt transfer to an
3451 interrupt endpoint of a USB device for both Hc2 and Hc protocol.
3452
3453 Arguments:
3454
3455 UsbBusDev - A pointer to bus controller of the device.
3456 DeviceAddress - Represents the address of the target device on the USB,
3457 which is assigned during USB enumeration.
3458 EndPointAddress - The combination of an endpoint number and an endpoint
3459 direction of the target USB device. Each endpoint address
3460 supports data transfer in one direction except the
3461 control endpoint (whose default endpoint address is 0).
3462 It is the caller's responsibility to make sure that
3463 the EndPointAddress represents an interrupt endpoint.
3464 DeviceSpeed - Indicates device speed.
3465 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3466 is capable of sending or receiving.
3467 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
3468 the host and the target interrupt endpoint.
3469 If FALSE, the specified asynchronous interrupt pipe
3470 is canceled.
3471 DataToggle - A pointer to the data toggle value. On input, it is valid
3472 when IsNewTransfer is TRUE, and it indicates the initial
3473 data toggle value the asynchronous interrupt transfer
3474 should adopt.
3475 On output, it is valid when IsNewTransfer is FALSE,
3476 and it is updated to indicate the data toggle value of
3477 the subsequent asynchronous interrupt transfer.
3478 PollingInterval - Indicates the interval, in milliseconds, that the
3479 asynchronous interrupt transfer is polled.
3480 This parameter is required when IsNewTransfer is TRUE.
3481 DataLength - Indicates the length of data to be received at the
3482 rate specified by PollingInterval from the target
3483 asynchronous interrupt endpoint. This parameter
3484 is only required when IsNewTransfer is TRUE.
3485 Translator - A pointr to the transaction translator data.
3486 CallBackFunction - The Callback function.This function is called at the
3487 rate specified by PollingInterval.This parameter is
3488 only required when IsNewTransfer is TRUE.
3489 Context - The context that is passed to the CallBackFunction.
3490 - This is an optional parameter and may be NULL.
3491
3492 Returns:
3493
3494 EFI_SUCCESS
3495 The asynchronous interrupt transfer request has been successfully
3496 submitted or canceled.
3497 EFI_INVALID_PARAMETER
3498 Some parameters are invalid.
3499 EFI_OUT_OF_RESOURCES
3500 The request could not be completed due to a lack of resources.
3501 EFI_DEVICE_ERROR
3502 Can't read register
3503
3504 --*/
3505 {
3506 EFI_STATUS Status;
3507 BOOLEAN IsSlowDevice;
3508
3509 Status = EFI_SUCCESS;
3510
3511 if (UsbBusDev->Hc2ProtocolSupported) {
3512 Status = UsbBusDev->Usb2HCInterface->AsyncInterruptTransfer (
3513 UsbBusDev->Usb2HCInterface,
3514 DeviceAddress,
3515 EndPointAddress,
3516 DeviceSpeed,
3517 MaximumPacketLength,
3518 IsNewTransfer,
3519 DataToggle,
3520 PollingInterval,
3521 DataLength,
3522 Translator,
3523 CallBackFunction,
3524 Context
3525 );
3526 } else {
3527 IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
3528 Status = UsbBusDev->UsbHCInterface->AsyncInterruptTransfer (
3529 UsbBusDev->UsbHCInterface,
3530 DeviceAddress,
3531 EndPointAddress,
3532 IsSlowDevice,
3533 (UINT8) MaximumPacketLength,
3534 IsNewTransfer,
3535 DataToggle,
3536 PollingInterval,
3537 DataLength,
3538 CallBackFunction,
3539 Context
3540 );
3541 }
3542
3543 return Status;
3544 }
3545
3546 EFI_STATUS
3547 EFIAPI
3548 UsbVirtualHcSyncInterruptTransfer (
3549 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3550 IN UINT8 DeviceAddress,
3551 IN UINT8 EndPointAddress,
3552 IN UINT8 DeviceSpeed,
3553 IN UINTN MaximumPacketLength,
3554 IN OUT VOID *Data,
3555 IN OUT UINTN *DataLength,
3556 IN OUT UINT8 *DataToggle,
3557 IN UINTN TimeOut,
3558 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3559 OUT UINT32 *TransferResult
3560 )
3561 /*++
3562
3563 Routine Description:
3564
3565 Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
3566 of a USB device for both Hc2 and Hc protocol.
3567
3568 Arguments:
3569
3570 UsbBusDev - A pointer to bus controller of the device.
3571 DeviceAddress - Represents the address of the target device on the USB,
3572 which is assigned during USB enumeration.
3573 EndPointAddress - The combination of an endpoint number and an endpoint
3574 direction of the target USB device. Each endpoint
3575 address supports data transfer in one direction
3576 except the control endpoint (whose default
3577 endpoint address is 0). It is the caller's responsibility
3578 to make sure that the EndPointAddress represents
3579 an interrupt endpoint.
3580 DeviceSpeed - Indicates device speed.
3581 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3582 is capable of sending or receiving.
3583 Data - A pointer to the buffer of data that will be transmitted
3584 to USB device or received from USB device.
3585 DataLength - On input, the size, in bytes, of the data buffer specified
3586 by Data. On output, the number of bytes transferred.
3587 DataToggle - A pointer to the data toggle value. On input, it indicates
3588 the initial data toggle value the synchronous interrupt
3589 transfer should adopt;
3590 on output, it is updated to indicate the data toggle value
3591 of the subsequent synchronous interrupt transfer.
3592 TimeOut - Indicates the maximum time, in microseconds, which the
3593 transfer is allowed to complete.
3594 Translator - A pointr to the transaction translator data.
3595 TransferResult - A pointer to the detailed result information from
3596 the synchronous interrupt transfer.
3597
3598 Returns:
3599
3600 EFI_SUCCESS
3601 The synchronous interrupt transfer was completed successfully.
3602 EFI_OUT_OF_RESOURCES
3603 The synchronous interrupt transfer could not be submitted due
3604 to lack of resource.
3605 EFI_INVALID_PARAMETER
3606 Some parameters are invalid.
3607 EFI_TIMEOUT
3608 The synchronous interrupt transfer failed due to timeout.
3609 EFI_DEVICE_ERROR
3610 The synchronous interrupt transfer failed due to host controller
3611 or device error. Caller should check TranferResult for detailed
3612 error information.
3613
3614 --*/
3615 {
3616 EFI_STATUS Status;
3617 BOOLEAN IsSlowDevice;
3618
3619 Status = EFI_SUCCESS;
3620
3621 if (UsbBusDev->Hc2ProtocolSupported) {
3622 Status = UsbBusDev->Usb2HCInterface->SyncInterruptTransfer (
3623 UsbBusDev->Usb2HCInterface,
3624 DeviceAddress,
3625 EndPointAddress,
3626 DeviceSpeed,
3627 MaximumPacketLength,
3628 Data,
3629 DataLength,
3630 DataToggle,
3631 TimeOut,
3632 Translator,
3633 TransferResult
3634 );
3635 } else {
3636 IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
3637 Status = UsbBusDev->UsbHCInterface->SyncInterruptTransfer (
3638 UsbBusDev->UsbHCInterface,
3639 DeviceAddress,
3640 EndPointAddress,
3641 IsSlowDevice,
3642 (UINT8) MaximumPacketLength,
3643 Data,
3644 DataLength,
3645 DataToggle,
3646 TimeOut,
3647 TransferResult
3648 );
3649 }
3650
3651 return Status;
3652 }
3653
3654 EFI_STATUS
3655 EFIAPI
3656 UsbVirtualHcIsochronousTransfer (
3657 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3658 IN UINT8 DeviceAddress,
3659 IN UINT8 EndPointAddress,
3660 IN UINT8 DeviceSpeed,
3661 IN UINTN MaximumPacketLength,
3662 IN UINT8 DataBuffersNumber,
3663 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
3664 IN UINTN DataLength,
3665 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3666 OUT UINT32 *TransferResult
3667 )
3668 /*++
3669
3670 Routine Description:
3671
3672 Virtual interface to submits isochronous transfer to a target USB device
3673 for both Hc2 and Hc protocol.
3674
3675 Arguments:
3676
3677 UsbBusDev - A pointer to bus controller of the device.
3678 DeviceAddress - Represents the address of the target device on the USB,
3679 which is assigned during USB enumeration.
3680 EndPointAddress - End point address
3681 DeviceSpeed - Indicates device speed.
3682 MaximumPacketLength - Indicates the maximum packet size that the
3683 default control transfer endpoint is capable of
3684 sending or receiving.
3685 DataBuffersNumber - Number of data buffers prepared for the transfer.
3686 Data - Array of pointers to the buffers of data that will be
3687 transmitted to USB device or received from USB device.
3688 DataLength - Indicates the size, in bytes, of the data buffer
3689 specified by Data.
3690 Translator - A pointr to the transaction translator data.
3691 TransferResult - A pointer to the detailed result information generated
3692 by this control transfer.
3693
3694 Returns:
3695
3696 EFI_UNSUPPORTED
3697
3698 --*/
3699 {
3700 return EFI_UNSUPPORTED;
3701 }
3702
3703 EFI_STATUS
3704 EFIAPI
3705 UsbVirtualHcAsyncIsochronousTransfer (
3706 IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
3707 IN UINT8 DeviceAddress,
3708 IN UINT8 EndPointAddress,
3709 IN UINT8 DeviceSpeed,
3710 IN UINTN MaximumPacketLength,
3711 IN UINT8 DataBuffersNumber,
3712 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
3713 IN UINTN DataLength,
3714 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
3715 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
3716 IN VOID *Context
3717 )
3718 /*++
3719
3720 Routine Description:
3721
3722 Vitual interface to submits Async isochronous transfer to a target USB device
3723 for both Hc2 and Hc protocol.
3724
3725 Arguments:
3726
3727 UsbBusDev - A pointer to bus controller of the device.
3728 DeviceAddress - Represents the address of the target device on the USB,
3729 which is assigned during USB enumeration.
3730 EndPointAddress - End point address
3731 DeviceSpeed - Indicates device speed.
3732 MaximumPacketLength - Indicates the maximum packet size that the
3733 default control transfer endpoint is capable of
3734 sending or receiving.
3735 DataBuffersNumber - Number of data buffers prepared for the transfer.
3736 Data - Array of pointers to the buffers of data that will be transmitted
3737 to USB device or received from USB device.
3738 DataLength - Indicates the size, in bytes, of the data buffer
3739 specified by Data.
3740 Translator - A pointr to the transaction translator data.
3741 IsochronousCallBack - When the transfer complete, the call back function will be called
3742 Context - Pass to the call back function as parameter
3743
3744 Returns:
3745
3746 EFI_UNSUPPORTED
3747
3748 --*/
3749 {
3750 return EFI_UNSUPPORTED;
3751 }