summaryrefslogtreecommitdiff
path: root/IntelFrameworkModulePkg/Bus/Isa
diff options
context:
space:
mode:
authorrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>2009-06-11 10:24:50 +0000
committerrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>2009-06-11 10:24:50 +0000
commit9277fdf8e7e6e5192f723f31fd205a9297c6a0aa (patch)
treefb6ca3ebcb83551ff6c782a2de5065707d4011fd /IntelFrameworkModulePkg/Bus/Isa
parent94ca8fffcbf05cf3f06e7f080296b2b59829c2f7 (diff)
downloadedk2-platforms-9277fdf8e7e6e5192f723f31fd205a9297c6a0aa.tar.xz
ISA Bus driver code scrub. Fix a bug in Stop() that CloseProtocol() on PCI IO Protocol fails because the child device handle is invalid after UninstallMultipleProtocolInterfaces() is called to destroy the child device handle.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8532 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'IntelFrameworkModulePkg/Bus/Isa')
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c
index 6af43dc9d8..e189ed7576 100644
--- a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c
@@ -93,7 +93,6 @@ IsaBusControllerDriverSupported (
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
- EFI_PCI_IO_PROTOCOL *PciIo;
EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
//
@@ -127,6 +126,15 @@ IsaBusControllerDriverSupported (
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
+ //
+ // Although this driver creates all child handles at one time,
+ // but because all child handles may be not stopped at one time in EFI Driver Binding.Stop(),
+ // So it is allowed to create child handles again in successive calls to EFI Driver Binding.Start().
+ //
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
if (EFI_ERROR (Status)) {
return Status;
}
@@ -145,10 +153,10 @@ IsaBusControllerDriverSupported (
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
+ NULL,
This->DriverBindingHandle,
Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
@@ -257,7 +265,7 @@ IsaBusControllerDriverStart (
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
return Status;
}
@@ -272,7 +280,7 @@ IsaBusControllerDriverStart (
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
//
// Close opened protocol
//
@@ -347,6 +355,10 @@ IsaBusControllerDriverStart (
//
// Create handle for this ISA device
//
+ // If any child device handle was created in previous call to Start() and not stopped
+ // in previous call to Stop(), it will not be created again because the
+ // InstallMultipleProtocolInterfaces() boot service will reject same device path.
+ //
Status = IsaCreateDevice (
This,
Controller,
@@ -437,6 +449,7 @@ IsaBusControllerDriverStop (
BOOLEAN AllChildrenStopped;
ISA_IO_DEVICE *IsaIoDevice;
EFI_ISA_IO_PROTOCOL *IsaIo;
+ EFI_PCI_IO_PROTOCOL *PciIo;
if (NumberOfChildren == 0) {
//
@@ -489,6 +502,16 @@ IsaBusControllerDriverStop (
IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo);
+ //
+ // Close the child handle
+ //
+
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index]
+ );
Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandleBuffer[Index],
&gEfiDevicePathProtocolGuid,
@@ -499,18 +522,21 @@ IsaBusControllerDriverStop (
);
if (!EFI_ERROR (Status)) {
- //
- // Close the child handle
- //
- Status = gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- ChildHandleBuffer[Index]
- );
-
gBS->FreePool (IsaIoDevice->DevicePath);
gBS->FreePool (IsaIoDevice);
+ } else {
+ //
+ // Re-open PCI IO Protocol on behalf of the child device
+ // because of failure of destroying the child device handle
+ //
+ gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
}
}