summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus
diff options
context:
space:
mode:
authoreric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>2009-07-23 12:50:08 +0000
committereric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>2009-07-23 12:50:08 +0000
commitcd92e3fb28baf796b1f4facf7f12642ee25b45ff (patch)
tree6c6027849c4f58a252a0cdb6d2874d6f4a0f8c29 /MdeModulePkg/Bus
parent44218d2e1e9a1fb9b603e4d2ddcb6c4934061792 (diff)
downloadedk2-platforms-cd92e3fb28baf796b1f4facf7f12642ee25b45ff.tar.xz
Adding a segment code to make sure that the EHCI controller get attached to the EHCI controller before the UHCI driver attaches to the UHCI controller
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8984 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Bus')
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c119
1 files changed, 113 insertions, 6 deletions
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index d45bdf630c..aae39b0acb 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -41,11 +41,17 @@ gEhciDriverBinding = {
EhcDriverBindingSupported,
EhcDriverBindingStart,
EhcDriverBindingStop,
- 0x10,
+ 0x30,
NULL,
NULL
};
+///
+/// USB host controller Programming Interface.
+///
+#define PCI_CLASSC_PI_UHCI 0x00
+#define PCI_CLASSC_PI_EHCI 0x20
+
/**
Retrieves the capability of root hub ports.
@@ -1354,9 +1360,8 @@ EhcDriverBindingSupported (
//
// Test whether the controller belongs to Ehci type
//
- if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
- (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
- (UsbClassCReg.PI != EHC_PCI_CLASSC_PI)) {
+ if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB)
+ || ((UsbClassCReg.PI != EHC_PCI_CLASSC_PI) && (UsbClassCReg.PI !=PCI_CLASSC_PI_UHCI))) {
Status = EFI_UNSUPPORTED;
}
@@ -1501,9 +1506,22 @@ EhcDriverBindingStart (
EFI_STATUS Status;
USB2_HC_DEV *Ehc;
EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_PCI_IO_PROTOCOL *Instance;
UINT64 Supports;
UINT64 OriginalPciAttributes;
BOOLEAN PciAttributesSaved;
+ USB_CLASSC UsbClassCReg;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ UINTN UhciSegmentNumber;
+ UINTN UhciBusNumber;
+ UINTN UhciDeviceNumber;
+ UINTN UhciFunctionNumber;
+ UINTN EhciSegmentNumber;
+ UINTN EhciBusNumber;
+ UINTN EhciDeviceNumber;
+ UINTN EhciFunctionNumber;
//
// Open the PciIo Protocol, then enable the USB host controller
@@ -1518,8 +1536,7 @@ EhcDriverBindingStart (
);
if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to open PCI_IO\n"));
- return EFI_DEVICE_ERROR;
+ return Status;
}
PciAttributesSaved = FALSE;
@@ -1559,6 +1576,96 @@ EhcDriverBindingStart (
goto CLOSE_PCIIO;
}
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EHC_PCI_CLASSC,
+ sizeof (USB_CLASSC) / sizeof (UINT8),
+ &UsbClassCReg
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_UNSUPPORTED;
+ goto CLOSE_PCIIO;
+ }
+
+ if ((UsbClassCReg.PI == PCI_CLASSC_PI_UHCI) &&
+ (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&
+ (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB)) {
+ Status = PciIo->GetLocation (
+ PciIo,
+ &UhciSegmentNumber,
+ &UhciBusNumber,
+ &UhciDeviceNumber,
+ &UhciFunctionNumber
+ );
+ if (EFI_ERROR (Status)) {
+ goto CLOSE_PCIIO;
+ }
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ goto CLOSE_PCIIO;
+ }
+
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ //
+ // Get the device path on this handle
+ //
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&Instance
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = Instance->Pci.Read (
+ Instance,
+ EfiPciIoWidthUint8,
+ EHC_PCI_CLASSC,
+ sizeof (USB_CLASSC) / sizeof (UINT8),
+ &UsbClassCReg
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_UNSUPPORTED;
+ goto CLOSE_PCIIO;
+ }
+
+ if ((UsbClassCReg.PI == PCI_CLASSC_PI_EHCI) &&
+ (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&
+ (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB)) {
+ Status = Instance->GetLocation (
+ Instance,
+ &EhciSegmentNumber,
+ &EhciBusNumber,
+ &EhciDeviceNumber,
+ &EhciFunctionNumber
+ );
+ if (EFI_ERROR (Status)) {
+ goto CLOSE_PCIIO;
+ }
+ if (EhciBusNumber == UhciBusNumber) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ EhcDriverBindingStart(This, HandleBuffer[Index], NULL);
+ }
+ }
+ }
+ Status = EFI_NOT_FOUND;
+ goto CLOSE_PCIIO;
+ }
+
//
// Create then install USB2_HC_PROTOCOL
//