From cd92e3fb28baf796b1f4facf7f12642ee25b45ff Mon Sep 17 00:00:00 2001 From: eric_tian Date: Thu, 23 Jul 2009 12:50:08 +0000 Subject: [PATCH] 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 --- MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c | 119 ++++++++++++++++++++++++++-- 1 file 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 // -- 2.39.2