Currently restoring PCI attributes are put in child uninstall logic, if one child is uninstalled, PCI attributes are restored, it will bring problem for stopping the next child. we do not restore the PCI attributes until all child handles are uninstalled.

Signed-off-by: Li Elvin <elvin.li@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13275 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
li-elvin 2012-05-04 12:21:41 +00:00
parent 490173cecf
commit eca7d27193
2 changed files with 108 additions and 49 deletions

View File

@ -1,7 +1,7 @@
/** @file
ConsoleOut Routines that speak VGA.
Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -37,6 +37,12 @@ UINT8 mVgaRightMaskTable[] = { 0x80, 0xc0, 0xe0, 0xf0,
UINT8 mVgaBitMaskTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
//
// Save controller attributes during first start
//
UINT64 mOriginalPciAttributes;
BOOLEAN mPciAttributesSaved = FALSE;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL mVgaColorToGraphicsOutputColor[] = {
{ 0x00, 0x00, 0x00, 0x00 },
{ 0x98, 0x00, 0x00, 0x00 },
@ -235,9 +241,7 @@ BiosVideoDriverBindingStart (
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
UINTN Flags;
UINT64 OriginalPciAttributes;
UINT64 Supports;
BOOLEAN PciAttributesSaved;
//
// Initialize local variables
@ -281,21 +285,22 @@ BiosVideoDriverBindingStart (
return Status;
}
PciAttributesSaved = FALSE;
//
// Save original PCI attributes
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationGet,
0,
&OriginalPciAttributes
);
if (EFI_ERROR (Status)) {
goto Done;
if (!mPciAttributesSaved) {
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationGet,
0,
&mOriginalPciAttributes
);
if (EFI_ERROR (Status)) {
goto Done;
}
mPciAttributesSaved = TRUE;
}
PciAttributesSaved = TRUE;
//
// Get supported PCI attributes
@ -398,8 +403,7 @@ BiosVideoDriverBindingStart (
PciIo,
LegacyBios,
ParentDevicePath,
RemainingDevicePath,
OriginalPciAttributes
RemainingDevicePath
);
Done:
@ -415,16 +419,18 @@ Done:
EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED,
ParentDevicePath
);
if (PciAttributesSaved) {
//
// Restore original PCI attributes
//
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSet,
OriginalPciAttributes,
NULL
);
if (!HasChildHandle (Controller)) {
if (mPciAttributesSaved) {
//
// Restore original PCI attributes
//
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSet,
mOriginalPciAttributes,
NULL
);
}
}
//
// Release PCI I/O Protocols on the controller handle.
@ -465,6 +471,7 @@ BiosVideoDriverBindingStop (
EFI_STATUS Status;
BOOLEAN AllChildrenStopped;
UINTN Index;
EFI_PCI_IO_PROTOCOL *PciIo;
AllChildrenStopped = TRUE;
@ -494,6 +501,29 @@ BiosVideoDriverBindingStop (
return EFI_DEVICE_ERROR;
}
if (!HasChildHandle (Controller)) {
if (mPciAttributesSaved) {
Status = gBS->HandleProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo
);
ASSERT_EFI_ERROR (Status);
//
// Restore original PCI attributes
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationSet,
mOriginalPciAttributes,
NULL
);
ASSERT_EFI_ERROR (Status);
}
}
return EFI_SUCCESS;
}
@ -507,7 +537,6 @@ BiosVideoDriverBindingStop (
@param ParentLegacyBios Parent LegacyBios interface
@param ParentDevicePath Parent Device Path
@param RemainingDevicePath Remaining Device Path
@param OriginalPciAttributes Original PCI Attributes
@retval EFI_SUCCESS If a child handle was added
@retval other A child handle was not added
@ -520,8 +549,7 @@ BiosVideoChildHandleInstall (
IN EFI_PCI_IO_PROTOCOL *ParentPciIo,
IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
IN UINT64 OriginalPciAttributes
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
@ -684,7 +712,6 @@ BiosVideoChildHandleInstall (
// When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally
//
BiosVideoPrivate->PciIo = ParentPciIo;
BiosVideoPrivate->OriginalPciAttributes = OriginalPciAttributes;
//
// Check for VESA BIOS Extensions for modes that are compatible with Graphics Output
@ -871,17 +898,6 @@ BiosVideoChildHandleUninstall (
Regs.H.BL = 0;
BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
//
// Restore original PCI attributes
//
Status = BiosVideoPrivate->PciIo->Attributes (
BiosVideoPrivate->PciIo,
EfiPciIoAttributeOperationSet,
BiosVideoPrivate->OriginalPciAttributes,
NULL
);
ASSERT_EFI_ERROR (Status);
//
// Close PCI I/O protocol that opened by child handle
//
@ -1193,6 +1209,42 @@ SearchEdidTiming (
return FALSE;
}
/**
Check if all video child handles have been uninstalled.
@param Controller Video controller handle
@return TRUE Child handles exist.
@return FALSE All video child handles have been uninstalled.
**/
BOOLEAN
HasChildHandle (
IN EFI_HANDLE Controller
)
{
UINTN Index;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
UINTN EntryCount;
BOOLEAN HasChild;
EFI_STATUS Status;
EntryCount = 0;
HasChild = FALSE;
Status = gBS->OpenProtocolInformation (
Controller,
&gEfiPciIoProtocolGuid,
&OpenInfoBuffer,
&EntryCount
);
for (Index = 0; Index < EntryCount; Index++) {
if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
HasChild = TRUE;
}
}
return HasChild;
}
/**
Check for VBE device.

View File

@ -1,6 +1,6 @@
/** @file
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -88,10 +88,6 @@ typedef struct {
//
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
//
// Original PCI attributes
//
UINT64 OriginalPciAttributes;
//
// Produced Protocols
@ -484,7 +480,6 @@ BiosVideoNotifyExitBootServices (
@param ParentLegacyBios Parent LegacyBios interface
@param ParentDevicePath Parent Device Path
@param RemainingDevicePath Remaining Device Path
@param OriginalPciAttributes Original PCI Attributes
@retval EFI_SUCCESS If a child handle was added
@retval other A child handle was not added
@ -497,8 +492,7 @@ BiosVideoChildHandleInstall (
IN EFI_PCI_IO_PROTOCOL *ParentPciIo,
IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios,
IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
IN UINT64 OriginalPciAttributes
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
@ -529,4 +523,17 @@ BiosVideoDeviceReleaseResource (
BIOS_VIDEO_DEV *BiosVideoPrivate
);
/**
Check if all video child handles have been uninstalled.
@param Controller Video controller handle
@return TRUE Child handles exist.
@return FALSE All video child handles have been uninstalled.
**/
BOOLEAN
HasChildHandle (
IN EFI_HANDLE Controller
);
#endif