{\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
EFI_ISA_ACPI_PROTOCOL *IsaAcpi;\r
\r
//\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
+ //\r
+ // Although this driver creates all child handles at one time,\r
+ // but because all child handles may be not stopped at one time in EFI Driver Binding.Stop(),\r
+ // So it is allowed to create child handles again in successive calls to EFI Driver Binding.Start().\r
+ //\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
Status = gBS->OpenProtocol (\r
Controller,\r
&gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
+ NULL,\r
This->DriverBindingHandle,\r
Controller,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
- if (EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
return Status;\r
}\r
\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
- if (EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
//\r
// Close opened protocol\r
//\r
//\r
// Create handle for this ISA device\r
//\r
+ // If any child device handle was created in previous call to Start() and not stopped\r
+ // in previous call to Stop(), it will not be created again because the\r
+ // InstallMultipleProtocolInterfaces() boot service will reject same device path.\r
+ //\r
Status = IsaCreateDevice (\r
This,\r
Controller,\r
BOOLEAN AllChildrenStopped;\r
ISA_IO_DEVICE *IsaIoDevice;\r
EFI_ISA_IO_PROTOCOL *IsaIo;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
\r
if (NumberOfChildren == 0) {\r
//\r
\r
IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo);\r
\r
+ //\r
+ // Close the child handle\r
+ //\r
+\r
+ Status = gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ ChildHandleBuffer[Index]\r
+ );\r
Status = gBS->UninstallMultipleProtocolInterfaces (\r
ChildHandleBuffer[Index],\r
&gEfiDevicePathProtocolGuid,\r
);\r
\r
if (!EFI_ERROR (Status)) {\r
- //\r
- // Close the child handle\r
- //\r
- Status = gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- ChildHandleBuffer[Index]\r
- );\r
-\r
gBS->FreePool (IsaIoDevice->DevicePath);\r
gBS->FreePool (IsaIoDevice);\r
+ } else {\r
+ //\r
+ // Re-open PCI IO Protocol on behalf of the child device\r
+ // because of failure of destroying the child device handle\r
+ //\r
+ gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ ChildHandleBuffer[Index],\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ ); \r
}\r
}\r
\r