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