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