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
This commit is contained in:
rsun3 2009-06-11 10:24:50 +00:00
parent 94ca8fffcb
commit 9277fdf8e7
1 changed files with 41 additions and 15 deletions

View File

@ -93,7 +93,6 @@ IsaBusControllerDriverSupported (
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_PCI_IO_PROTOCOL *PciIo;
EFI_ISA_ACPI_PROTOCOL *IsaAcpi; EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
// //
@ -127,6 +126,15 @@ IsaBusControllerDriverSupported (
Controller, Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER 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)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@ -145,10 +153,10 @@ IsaBusControllerDriverSupported (
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
Controller, Controller,
&gEfiPciIoProtocolGuid, &gEfiPciIoProtocolGuid,
(VOID **) &PciIo, NULL,
This->DriverBindingHandle, This->DriverBindingHandle,
Controller, Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL EFI_OPEN_PROTOCOL_TEST_PROTOCOL
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
@ -257,7 +265,7 @@ IsaBusControllerDriverStart (
Controller, Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER EFI_OPEN_PROTOCOL_BY_DRIVER
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
return Status; return Status;
} }
@ -272,7 +280,7 @@ IsaBusControllerDriverStart (
Controller, Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER EFI_OPEN_PROTOCOL_BY_DRIVER
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
// //
// Close opened protocol // Close opened protocol
// //
@ -347,6 +355,10 @@ IsaBusControllerDriverStart (
// //
// Create handle for this ISA device // 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 ( Status = IsaCreateDevice (
This, This,
Controller, Controller,
@ -437,6 +449,7 @@ IsaBusControllerDriverStop (
BOOLEAN AllChildrenStopped; BOOLEAN AllChildrenStopped;
ISA_IO_DEVICE *IsaIoDevice; ISA_IO_DEVICE *IsaIoDevice;
EFI_ISA_IO_PROTOCOL *IsaIo; EFI_ISA_IO_PROTOCOL *IsaIo;
EFI_PCI_IO_PROTOCOL *PciIo;
if (NumberOfChildren == 0) { if (NumberOfChildren == 0) {
// //
@ -489,6 +502,16 @@ IsaBusControllerDriverStop (
IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo); 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 ( Status = gBS->UninstallMultipleProtocolInterfaces (
ChildHandleBuffer[Index], ChildHandleBuffer[Index],
&gEfiDevicePathProtocolGuid, &gEfiDevicePathProtocolGuid,
@ -499,18 +522,21 @@ IsaBusControllerDriverStop (
); );
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
//
// Close the child handle
//
Status = gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
ChildHandleBuffer[Index]
);
gBS->FreePool (IsaIoDevice->DevicePath); gBS->FreePool (IsaIoDevice->DevicePath);
gBS->FreePool (IsaIoDevice); 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
);
} }
} }