]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/QemuVideoDxe/Driver.c
OvmfPkg: QemuVideoDxe: tidy up error checking/handling in & under Start()
[mirror_edk2.git] / OvmfPkg / QemuVideoDxe / Driver.c
index b253ec734edf9e214a916ad58930622f6a81124e..d7716ce6a9df969b259fa096bca4215c926a7aa6 100644 (file)
@@ -203,29 +203,23 @@ QemuVideoControllerDriverStart (
 {\r
   EFI_STATUS                        Status;\r
   QEMU_VIDEO_PRIVATE_DATA           *Private;\r
-  BOOLEAN                           PciAttributesSaved;\r
   EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;\r
-  ACPI_ADR_DEVICE_PATH              AcpiDeviceNode;\r
   PCI_TYPE00                        Pci;\r
   QEMU_VIDEO_CARD                   *Card;\r
-  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc;\r
   EFI_PCI_IO_PROTOCOL               *ChildPciIo;\r
 \r
-  PciAttributesSaved = FALSE;\r
   //\r
   // Allocate Private context data for GOP inteface.\r
   //\r
   Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA));\r
   if (Private == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Error;\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   //\r
   // Set up context record\r
   //\r
   Private->Signature  = QEMU_VIDEO_PRIVATE_DATA_SIGNATURE;\r
-  Private->Handle     = NULL;\r
 \r
   //\r
   // Open PCI I/O Protocol\r
@@ -239,7 +233,7 @@ QemuVideoControllerDriverStart (
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+    goto FreePrivate;\r
   }\r
 \r
   //\r
@@ -253,13 +247,16 @@ QemuVideoControllerDriverStart (
                         &Pci\r
                         );\r
   if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+    goto ClosePciIo;\r
   }\r
 \r
+  //\r
+  // Determine card variant.\r
+  //\r
   Card = QemuVideoDetect(Pci.Hdr.VendorId, Pci.Hdr.DeviceId);\r
   if (Card == NULL) {\r
     Status = EFI_DEVICE_ERROR;\r
-    goto Error;\r
+    goto ClosePciIo;\r
   }\r
   Private->Variant = Card->Variant;\r
 \r
@@ -274,10 +271,12 @@ QemuVideoControllerDriverStart (
                     );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+    goto ClosePciIo;\r
   }\r
-  PciAttributesSaved = TRUE;\r
 \r
+  //\r
+  // Set new PCI attributes\r
+  //\r
   Status = Private->PciIo->Attributes (\r
                             Private->PciIo,\r
                             EfiPciIoAttributeOperationEnable,\r
@@ -285,13 +284,15 @@ QemuVideoControllerDriverStart (
                             NULL\r
                             );\r
   if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+    goto ClosePciIo;\r
   }\r
 \r
   //\r
   // Check whenever the qemu stdvga mmio bar is present (qemu 1.3+).\r
   //\r
   if (Private->Variant == QEMU_VIDEO_BOCHS_MMIO) {\r
+    EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc;\r
+\r
     Status = Private->PciIo->GetBarAttributes (\r
                         Private->PciIo,\r
                         PCI_BAR_IDX2,\r
@@ -322,7 +323,7 @@ QemuVideoControllerDriverStart (
     if ((BochsId & 0xFFF0) != VBE_DISPI_ID0) {\r
       DEBUG ((EFI_D_INFO, "QemuVideo: BochsID mismatch (got 0x%x)\n", BochsId));\r
       Status = EFI_DEVICE_ERROR;\r
-      goto Error;\r
+      goto RestoreAttributes;\r
     }\r
   }\r
 \r
@@ -335,13 +336,15 @@ QemuVideoControllerDriverStart (
                   (VOID **) &ParentDevicePath\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+    goto RestoreAttributes;\r
   }\r
 \r
   //\r
   // Set Gop Device Path\r
   //\r
   if (RemainingDevicePath == NULL) {\r
+    ACPI_ADR_DEVICE_PATH AcpiDeviceNode;\r
+\r
     ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));\r
     AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;\r
     AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;\r
@@ -352,31 +355,37 @@ QemuVideoControllerDriverStart (
                                         ParentDevicePath,\r
                                         (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode\r
                                         );\r
+    if (Private->GopDevicePath == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto RestoreAttributes;\r
+    }\r
   } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
     //\r
     // If RemainingDevicePath isn't the End of Device Path Node, \r
     // only scan the specified device by RemainingDevicePath\r
     //\r
     Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);\r
-  } else {\r
-    //\r
-    // If RemainingDevicePath is the End of Device Path Node, \r
-    // don't create child device and return EFI_SUCCESS\r
-    //\r
-    Private->GopDevicePath = NULL;\r
+    if (Private->GopDevicePath == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto RestoreAttributes;\r
+    }\r
   }\r
-    \r
+\r
+  //\r
+  // Create new child handle and install the device path protocol on it only if\r
+  // RemainingDevicePath equals NULL, or doesn't point to the End of Device\r
+  // Path Node.\r
+  //\r
   if (Private->GopDevicePath != NULL) {\r
-    //\r
-    // Creat child handle and device path protocol firstly\r
-    //\r
-    Private->Handle = NULL;\r
     Status = gBS->InstallMultipleProtocolInterfaces (\r
                     &Private->Handle,\r
                     &gEfiDevicePathProtocolGuid,\r
                     Private->GopDevicePath,\r
                     NULL\r
                     );\r
+    if (EFI_ERROR (Status)) {\r
+      goto FreeGopDevicePath;\r
+    }\r
   }\r
 \r
   //\r
@@ -397,84 +406,86 @@ QemuVideoControllerDriverStart (
     break;\r
   }\r
   if (EFI_ERROR (Status)) {\r
-    goto Error;\r
+    goto UninstallGopDevicePath;\r
   }\r
 \r
+  //\r
+  // If RemainingDevicePath points to the End of Device Path Node, then we\r
+  // haven't created a child handle, and we're done.\r
+  //\r
   if (Private->GopDevicePath == NULL) {\r
-    //\r
-    // If RemainingDevicePath is the End of Device Path Node, \r
-    // don't create child device and return EFI_SUCCESS\r
-    //\r
-    Status = EFI_SUCCESS;\r
-  } else {\r
-\r
-    //\r
-    // Start the GOP software stack.\r
-    //\r
-    Status = QemuVideoGraphicsOutputConstructor (Private);\r
-    ASSERT_EFI_ERROR (Status);\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
-    Status = gBS->InstallMultipleProtocolInterfaces (\r
-                    &Private->Handle,\r
-                    &gEfiGraphicsOutputProtocolGuid,\r
-                    &Private->GraphicsOutput,\r
-                    NULL\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      goto Error;\r
-    }\r
+  //\r
+  // Start the GOP software stack.\r
+  //\r
+  Status = QemuVideoGraphicsOutputConstructor (Private);\r
+  if (EFI_ERROR (Status)) {\r
+    goto FreeModeData;\r
+  }\r
 \r
-    Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &ChildPciIo,\r
-                  This->DriverBindingHandle,\r
-                  Private->Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Private->Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  &Private->GraphicsOutput,\r
+                  NULL\r
                   );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      goto Error;\r
-    }\r
+  if (EFI_ERROR (Status)) {\r
+    goto DestructQemuVideoGraphics;\r
   }\r
 \r
-Error:\r
+  //\r
+  // Reference parent handle from child handle.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                Controller,\r
+                &gEfiPciIoProtocolGuid,\r
+                (VOID **) &ChildPciIo,\r
+                This->DriverBindingHandle,\r
+                Private->Handle,\r
+                EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                );\r
   if (EFI_ERROR (Status)) {\r
-    if (Private) {\r
-      if (Private->PciIo) {\r
-        if (PciAttributesSaved == TRUE) {\r
-          //\r
-          // Restore original PCI attributes\r
-          //\r
-          Private->PciIo->Attributes (\r
-                          Private->PciIo,\r
-                          EfiPciIoAttributeOperationSet,\r
-                          Private->OriginalPciAttributes,\r
-                          NULL\r
-                          );\r
-        }\r
-        //\r
-        // Close the PCI I/O Protocol\r
-        //\r
-        gBS->CloseProtocol (\r
-              Controller,\r
-              &gEfiPciIoProtocolGuid,\r
-              This->DriverBindingHandle,\r
-              Controller\r
-              );\r
-\r
-        gBS->CloseProtocol (\r
-              Controller,\r
-              &gEfiPciIoProtocolGuid,\r
-              This->DriverBindingHandle,\r
-              Private->Handle\r
-              );\r
-      }\r
+    goto UninstallGop;\r
+  }\r
 \r
-      gBS->FreePool (Private);\r
-    }\r
+  return EFI_SUCCESS;\r
+\r
+UninstallGop:\r
+  gBS->UninstallProtocolInterface (Private->Handle,\r
+         &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput);\r
+\r
+DestructQemuVideoGraphics:\r
+  QemuVideoGraphicsOutputDestructor (Private);\r
+\r
+FreeModeData:\r
+  FreePool (Private->ModeData);\r
+\r
+UninstallGopDevicePath:\r
+  //\r
+  // Handles the case transparently when Private->Handle and\r
+  // Private->GopDevicePath are NULL.\r
+  //\r
+  gBS->UninstallProtocolInterface (Private->Handle,\r
+         &gEfiDevicePathProtocolGuid, Private->GopDevicePath);\r
+\r
+FreeGopDevicePath:\r
+  if (Private->GopDevicePath != NULL) {\r
+    FreePool (Private->GopDevicePath);\r
   }\r
 \r
+RestoreAttributes:\r
+  Private->PciIo->Attributes (Private->PciIo, EfiPciIoAttributeOperationSet,\r
+                    Private->OriginalPciAttributes, NULL);\r
+\r
+ClosePciIo:\r
+  gBS->CloseProtocol (Controller, &gEfiPciIoProtocolGuid,\r
+         This->DriverBindingHandle, Controller);\r
+\r
+FreePrivate:\r
+  FreePool (Private);\r
+\r
   return Status;\r
 }\r
 \r