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
This commit is contained in:
eric_tian 2009-07-23 12:50:08 +00:00
parent 44218d2e1e
commit cd92e3fb28

View File

@ -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
//