]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c
ISA Bus driver code scrub. Fix a bug in Stop() that CloseProtocol() on PCI IO Protoco...
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / IsaBusDxe / IsaBus.c
index 6af43dc9d8ec43f0cb73d4d77cf9ca69b87711f7..e189ed7576e33564ef66bc29ef6b53813fdd5c3e 100644 (file)
@@ -93,7 +93,6 @@ IsaBusControllerDriverSupported (
 {\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
@@ -127,6 +126,15 @@ IsaBusControllerDriverSupported (
                   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
@@ -145,10 +153,10 @@ IsaBusControllerDriverSupported (
   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
@@ -257,7 +265,7 @@ IsaBusControllerDriverStart (
                   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
@@ -272,7 +280,7 @@ IsaBusControllerDriverStart (
                   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
@@ -347,6 +355,10 @@ IsaBusControllerDriverStart (
     //\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
@@ -437,6 +449,7 @@ IsaBusControllerDriverStop (
   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
@@ -489,6 +502,16 @@ IsaBusControllerDriverStop (
 \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
@@ -499,18 +522,21 @@ IsaBusControllerDriverStop (
                       );\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