]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UnixPkg/UnixSerialIoDxe/UnixSerialIo.c
updated the Bus Driver that is able to create all or one of its child handles on...
[mirror_edk2.git] / UnixPkg / UnixSerialIoDxe / UnixSerialIo.c
index edbfd0ad1353bfb715bea6e085946292d9b775cb..ff9bced4e98a7ffca598eaf725766b0e336198e3 100644 (file)
@@ -222,13 +222,54 @@ Returns:
   EFI_UNIX_IO_PROTOCOL      *UnixIo;\r
   UART_DEVICE_PATH          *UartNode;\r
 \r
+  //\r
+  // Check RemainingDevicePath validation\r
+  //\r
+  if (RemainingDevicePath != NULL) {\r
+    //\r
+    // Check if RemainingDevicePath is the End of Device Path Node, \r
+    // if yes, go on checking other conditions\r
+    //\r
+    if (!IsDevicePathEnd (RemainingDevicePath)) {\r
+      //\r
+      // If RemainingDevicePath isn't the End of Device Path Node,\r
+      // check its validation\r
+      //\r
+      Status = EFI_UNSUPPORTED;\r
+      UartNode  = (UART_DEVICE_PATH *) RemainingDevicePath;\r
+      if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||\r
+          UartNode->Header.SubType != MSG_UART_DP ||\r
+          DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL *)UartNode) != sizeof(UART_DEVICE_PATH)) {\r
+        goto Error;\r
+      }\r
+      if (UartNode->BaudRate < 0 || UartNode->BaudRate > SERIAL_PORT_MAX_BAUD_RATE) {\r
+        goto Error;\r
+      }\r
+      if (UartNode->Parity < NoParity || UartNode->Parity > SpaceParity) {\r
+        goto Error;\r
+      }\r
+      if (UartNode->DataBits < 5 || UartNode->DataBits > 8) {\r
+        goto Error;\r
+      }\r
+      if (UartNode->StopBits < OneStopBit || UartNode->StopBits > TwoStopBits) {\r
+        goto Error;\r
+      }\r
+      if ((UartNode->DataBits == 5) && (UartNode->StopBits == TwoStopBits)) {\r
+        goto Error;\r
+      }\r
+      if ((UartNode->DataBits >= 6) && (UartNode->DataBits <= 8) && (UartNode->StopBits == OneFiveStopBits)) {\r
+        goto Error;\r
+      }\r
+    }\r
+  }\r
+\r
   //\r
   // Open the IO Abstraction(s) needed to perform the supported test\r
   //\r
   Status = gBS->OpenProtocol (\r
                   Handle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID**)&ParentDevicePath,\r
+                  &gEfiUnixIoProtocolGuid,\r
+                  (VOID**)&UnixIo,\r
                   This->DriverBindingHandle,\r
                   Handle,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -241,17 +282,23 @@ Returns:
     return Status;\r
   }\r
 \r
+  //\r
+  // Close the I/O Abstraction(s) used to perform the supported test\r
+  //\r
   gBS->CloseProtocol (\r
         Handle,\r
-        &gEfiDevicePathProtocolGuid,\r
+        &gEfiUnixIoProtocolGuid,\r
         This->DriverBindingHandle,\r
         Handle\r
         );\r
 \r
+  //\r
+  // Open the EFI Device Path protocol needed to perform the supported test\r
+  //\r
   Status = gBS->OpenProtocol (\r
                   Handle,\r
-                  &gEfiUnixIoProtocolGuid,\r
-                  (VOID**)&UnixIo,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID**)&ParentDevicePath,\r
                   This->DriverBindingHandle,\r
                   Handle,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -264,6 +311,16 @@ Returns:
     return Status;\r
   }\r
 \r
+  //\r
+  // Close protocol, don't use device path protocol in the Support() function\r
+  //\r
+  gBS->CloseProtocol (\r
+        Handle,\r
+        &gEfiDevicePathProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Handle\r
+        );\r
+\r
   //\r
   // Make sure that the Unix Thunk Protocol is valid\r
   //\r
@@ -280,46 +337,9 @@ Returns:
     goto Error;\r
   }\r
 \r
-  if (RemainingDevicePath != NULL) {\r
-    Status    = EFI_UNSUPPORTED;\r
-    UartNode  = (UART_DEVICE_PATH *) RemainingDevicePath;\r
-    if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||\r
-        UartNode->Header.SubType != MSG_UART_DP ||\r
-        DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL *)UartNode) != sizeof(UART_DEVICE_PATH)) {\r
-      goto Error;\r
-    }\r
-    if (UartNode->BaudRate < 0 || UartNode->BaudRate > SERIAL_PORT_MAX_BAUD_RATE) {\r
-      goto Error;\r
-    }\r
-    if (UartNode->Parity < NoParity || UartNode->Parity > SpaceParity) {\r
-      goto Error;\r
-    }\r
-    if (UartNode->DataBits < 5 || UartNode->DataBits > 8) {\r
-      goto Error;\r
-    }\r
-    if (UartNode->StopBits < OneStopBit || UartNode->StopBits > TwoStopBits) {\r
-      goto Error;\r
-    }\r
-    if ((UartNode->DataBits == 5) && (UartNode->StopBits == TwoStopBits)) {\r
-      goto Error;\r
-    }\r
-    if ((UartNode->DataBits >= 6) && (UartNode->DataBits <= 8) && (UartNode->StopBits == OneFiveStopBits)) {\r
-      goto Error;\r
-    }\r
-    Status = EFI_SUCCESS;\r
-  }\r
+  return EFI_SUCCESS;\r
 \r
 Error:\r
-  //\r
-  // Close the I/O Abstraction(s) used to perform the supported test\r
-  //\r
-  gBS->CloseProtocol (\r
-        Handle,\r
-        &gEfiUnixIoProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Handle\r
-        );\r
-\r
   return Status;\r
 }\r
 \r
@@ -353,6 +373,7 @@ Returns:
   UINTN                               Index;\r
   EFI_SERIAL_IO_PROTOCOL              *SerialIo;\r
   CHAR8                               AsciiDevName[1024];\r
+  UART_DEVICE_PATH                    *UartNode;\r
 \r
   DEBUG ((EFI_D_INFO, "SerialIo drive binding start!\r\n"));\r
   Private   = NULL;\r
@@ -396,7 +417,10 @@ Returns:
 \r
   if (Status == EFI_ALREADY_STARTED) {\r
 \r
-    if (RemainingDevicePath == NULL) {\r
+    if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {\r
+      //\r
+      // If RemainingDevicePath is NULL or is the End of Device Path Node\r
+      //\r
       return EFI_SUCCESS;\r
     }\r
 \r
@@ -426,15 +450,15 @@ Returns:
                         EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                         );\r
         if (!EFI_ERROR (Status)) {\r
-          CopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH));\r
+          UartNode = (UART_DEVICE_PATH *) RemainingDevicePath;\r
           Status = SerialIo->SetAttributes (\r
                               SerialIo,\r
-                              Node.BaudRate,\r
+                              UartNode->BaudRate,\r
                               SerialIo->Mode->ReceiveFifoDepth,\r
                               SerialIo->Mode->Timeout,\r
-                              Node.Parity,\r
-                              Node.DataBits,\r
-                              Node.StopBits\r
+                              UartNode->Parity,\r
+                              UartNode->DataBits,\r
+                              UartNode->StopBits\r
                               );\r
         }\r
         break;\r
@@ -442,7 +466,47 @@ Returns:
     }\r
 \r
     FreePool (OpenInfoBuffer);\r
-    return Status;\r
+    if (Index < EntryCount) {\r
+      //\r
+      // If gEfiUnixIoProtocolGuid is opened by one child device, return\r
+      //\r
+      return Status;\r
+    }\r
+    //\r
+    // If gEfiUnixIoProtocolGuid is not opened by any child device,\r
+    // go further to create child device handle based on RemainingDevicePath\r
+    //\r
+  }\r
+\r
+  if (RemainingDevicePath == NULL) {\r
+    //\r
+    // Build the device path by appending the UART node to the ParentDevicePath\r
+    // from the UnixIo handle. The Uart setings are zero here, since\r
+    // SetAttribute() will update them to match the default setings.\r
+    //\r
+    ZeroMem (&Node, sizeof (UART_DEVICE_PATH));\r
+    Node.Header.Type     = MESSAGING_DEVICE_PATH;\r
+    Node.Header.SubType  = MSG_UART_DP;\r
+    SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &Node, sizeof (UART_DEVICE_PATH));\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
+    //\r
+    // Match the configuration of the RemainingDevicePath. IsHandleSupported()\r
+    // already checked to make sure the RemainingDevicePath contains settings\r
+    // that we can support.\r
+    //\r
+    CopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH));\r
+\r
+  } else {\r
+    //\r
+    // If RemainingDevicePath is the End of Device Path Node,\r
+    // skip enumerate any device and return EFI_SUCESSS\r
+    // \r
+    return EFI_SUCCESS;\r
   }\r
 \r
   //\r
@@ -486,6 +550,8 @@ Returns:
   Private->Fifo.Last              = 0;\r
   Private->Fifo.Surplus           = SERIAL_MAX_BUFFER_SIZE;\r
 \r
+  CopyMem (&Private->UartDevicePath, &Node, sizeof (UART_DEVICE_PATH));\r
+\r
   AddUnicodeString (\r
     "eng",\r
     gUnixSerialIoComponentName.SupportedLanguages,\r
@@ -502,24 +568,7 @@ Returns:
   Private->SerialIo.Read          = UnixSerialIoRead;\r
   Private->SerialIo.Mode          = &Private->SerialIoMode;\r
 \r
-  if (RemainingDevicePath != NULL) {\r
-    //\r
-    // Match the configuration of the RemainingDevicePath. IsHandleSupported()\r
-    // already checked to make sure the RemainingDevicePath contains settings\r
-    // that we can support.\r
-    //\r
-    CopyMem (&Private->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH));\r
-  } else {\r
-    //\r
-    // Build the device path by appending the UART node to the ParentDevicePath\r
-    // from the UnixIo handle. The Uart setings are zero here, since\r
-    // SetAttribute() will update them to match the default setings.\r
-    //\r
-    ZeroMem (&Private->UartDevicePath, sizeof (UART_DEVICE_PATH));\r
-    Private->UartDevicePath.Header.Type     = MESSAGING_DEVICE_PATH;\r
-    Private->UartDevicePath.Header.SubType  = MSG_UART_DP;\r
-    SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath, sizeof (UART_DEVICE_PATH));\r
-  }\r
+\r
 \r
   //\r
   // Build the device path by appending the UART node to the ParentDevicePath\r