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