]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
edk2: Remove packages moved to edk2-platforms
[mirror_edk2.git] / OptionRomPkg / Bus / Usb / FtdiUsbSerialDxe / FtdiUsbSerialDriver.c
diff --git a/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
deleted file mode 100644 (file)
index ac09fae..0000000
+++ /dev/null
@@ -1,2580 +0,0 @@
-/** @file\r
-  USB Serial Driver that manages USB to Serial and produces Serial IO Protocol.\r
-\r
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.\r
-Portions Copyright 2012 Ashley DeSimone\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-//\r
-\r
-// Tested with VEND_ID 0x0403, DEVICE_ID 0x6001\r
-//\r
-// Driver starts the device with the following values:\r
-// 115200, No parity, 8 data bits, 1 stop bit, No Flow control\r
-//\r
-\r
-#include "FtdiUsbSerialDriver.h"\r
-\r
-//\r
-// Table of supported devices. This is the device information that this\r
-// driver was developed with. Add other FTDI devices as needed.\r
-//\r
-USB_DEVICE gUSBDeviceList[] = {\r
-  {VID_FTDI, DID_FTDI_FT232},\r
-  {0,0}\r
-};\r
-\r
-//\r
-// USB Serial Driver Global Variables\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL  gUsbSerialDriverBinding = {\r
-  UsbSerialDriverBindingSupported,\r
-  UsbSerialDriverBindingStart,\r
-  UsbSerialDriverBindingStop,\r
-  0xa,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-//\r
-// Table with the nearest power of 2 for the numbers 0-15\r
-//\r
-UINT8 gRoundedPowersOf2[16] = { 0, 2, 2, 4, 4, 4, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16 };\r
-\r
-/**\r
-  Check to see if the device path node is the Flow control node\r
-\r
-  @param[in] FlowControl    The device path node to be checked\r
-\r
-  @retval    TRUE           It is the flow control node\r
-  @retval    FALSE          It is not the flow control node\r
-\r
-**/\r
-BOOLEAN\r
-IsUartFlowControlNode (\r
-  IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl\r
-  )\r
-{\r
-  return (BOOLEAN) (\r
-           (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&\r
-           (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&\r
-           (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))\r
-           );\r
-}\r
-\r
-/**\r
-  Checks the device path to see if it contains flow control.\r
-\r
-  @param[in] DevicePath    The device path to be checked\r
-\r
-  @retval    TRUE          It contains flow control\r
-  @retval    FALSE         It does not contain flow control\r
-\r
-**/\r
-BOOLEAN\r
-ContainsFlowControl (\r
-  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath\r
-  )\r
-{\r
-  while (!IsDevicePathEnd (DevicePath)) {\r
-    if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH *) DevicePath)) {\r
-      return TRUE;\r
-    }\r
-    DevicePath = NextDevicePathNode (DevicePath);\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Transfer the data between the device and host.\r
-\r
-  This function transfers the data between the device and host.\r
-  BOT transfer is composed of three phases: Command, Data, and Status.\r
-  This is the Data phase.\r
-\r
-  @param  UsbBot[in]                     The USB BOT device\r
-  @param  DataDir[in]                    The direction of the data\r
-  @param  Data[in, out]                  The buffer to hold data\r
-  @param  TransLen[in, out]              The expected length of the data\r
-  @param  Timeout[in]                    The time to wait the command to complete\r
-\r
-  @retval EFI_SUCCESS                    The data is transferred\r
-  @retval EFI_SUCCESS                    No data to transfer\r
-  @retval EFI_NOT_READY                  The device return NAK to the transfer\r
-  @retval Others                         Failed to transfer data\r
-\r
-**/\r
-EFI_STATUS\r
-UsbSerialDataTransfer (\r
-  IN USB_SER_DEV             *UsbBot,\r
-  IN EFI_USB_DATA_DIRECTION  DataDir,\r
-  IN OUT VOID                *Data,\r
-  IN OUT UINTN               *TransLen,\r
-  IN UINT32                  Timeout\r
-  )\r
-{\r
-  EFI_USB_ENDPOINT_DESCRIPTOR  *Endpoint;\r
-  EFI_STATUS                   Status;\r
-  UINT32                       Result;\r
-\r
-  //\r
-  // If no data to transfer, just return EFI_SUCCESS.\r
-  //\r
-  if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Select the endpoint then issue the transfer\r
-  //\r
-  if (DataDir == EfiUsbDataIn) {\r
-    Endpoint = &UsbBot->InEndpointDescriptor;\r
-  } else {\r
-    Endpoint = &UsbBot->OutEndpointDescriptor;\r
-  }\r
-\r
-  Result = 0;\r
-  Status = UsbBot->UsbIo->UsbBulkTransfer (\r
-                            UsbBot->UsbIo,\r
-                            Endpoint->EndpointAddress,\r
-                            Data,\r
-                            TransLen,\r
-                            Timeout,\r
-                            &Result\r
-                            );\r
-  if (EFI_ERROR (Status)) {\r
-    if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {\r
-      Status = EFI_NOT_READY;\r
-    } else {\r
-      UsbBot->Shutdown = TRUE; // Fixes infinite loop in older EFI\r
-    }\r
-    return Status;\r
-  }\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Sets the status values of the Usb Serial Device.\r
-\r
-  @param  UsbSerialDevice[in]  Handle to the Usb Serial Device to set the status\r
-                               for\r
-  @param  StatusBuffer[in]     Buffer holding the status values\r
-\r
-  @retval EFI_SUCCESS          The status values were read and set correctly\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetStatusInternal (\r
-  IN USB_SER_DEV  *UsbSerialDevice,\r
-  IN UINT8        *StatusBuffer\r
-  )\r
-{\r
-  UINT8  Msr;\r
-\r
-  Msr = (StatusBuffer[0] & MSR_MASK);\r
-\r
-  //\r
-  // set the Status values to disabled\r
-  //\r
-  UsbSerialDevice->StatusValues.CtsState = FALSE;\r
-  UsbSerialDevice->StatusValues.DsrState = FALSE;\r
-  UsbSerialDevice->StatusValues.RiState  = FALSE;\r
-  UsbSerialDevice->StatusValues.SdState  = FALSE;\r
-\r
-  //\r
-  // Check the values from the status buffer and set the appropriate status\r
-  // values to enabled\r
-  //\r
-  if ((Msr & CTS_MASK) == CTS_MASK) {\r
-    UsbSerialDevice->StatusValues.CtsState = TRUE;\r
-  }\r
-  if ((Msr & DSR_MASK) == DSR_MASK) {\r
-    UsbSerialDevice->StatusValues.DsrState = TRUE;\r
-  }\r
-  if ((Msr & RI_MASK) == RI_MASK) {\r
-    UsbSerialDevice->StatusValues.RiState = TRUE;\r
-  }\r
-  if ((Msr & SD_MASK) == SD_MASK) {\r
-    UsbSerialDevice->StatusValues.SdState = TRUE;\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Initiates a read operation on the Usb Serial Device.\r
-\r
-  @param  UsbSerialDevice[in]        Handle to the USB device to read\r
-  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,\r
-                                     the amount of data returned in Buffer.\r
-                                     Setting this to zero will initiate a read\r
-                                     and store all data returned in the internal\r
-                                     buffer.\r
-  @param  Buffer [out]               The buffer to return the data into.\r
-\r
-  @retval EFI_SUCCESS                The data was read.\r
-  @retval EFI_DEVICE_ERROR           The device reported an error.\r
-  @retval EFI_TIMEOUT                The data write was stopped due to a timeout.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ReadDataFromUsb (\r
-  IN USB_SER_DEV  *UsbSerialDevice,\r
-  IN OUT UINTN    *BufferSize,\r
-  OUT VOID        *Buffer\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINTN       ReadBufferSize;\r
-  UINT8       *ReadBuffer;\r
-  UINTN       Index;\r
-  EFI_TPL     Tpl;\r
-  UINT8       StatusBuffer[2]; // buffer to store the status bytes\r
-\r
-  ReadBufferSize = 512;\r
-  ReadBuffer     = &(UsbSerialDevice->ReadBuffer[0]);\r
-\r
-  if (UsbSerialDevice->Shutdown) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Status = UsbSerialDataTransfer (\r
-             UsbSerialDevice,\r
-             EfiUsbDataIn,\r
-             ReadBuffer,\r
-             &ReadBufferSize,\r
-             FTDI_TIMEOUT*2  //Padded because timers won't be exactly aligned\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->RestoreTPL (Tpl);\r
-    if (Status == EFI_TIMEOUT) {\r
-      return EFI_TIMEOUT;\r
-    } else {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Store the status bytes in the status buffer\r
-  //\r
-  for (Index = 0; Index < 2; Index++) {//only the first 2 bytes are status bytes\r
-    StatusBuffer[Index] = ReadBuffer[Index];\r
-  }\r
-  //\r
-  // update the statusvalue field of the usbserialdevice\r
-  //\r
-  Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);\r
-  if (Status != EFI_SUCCESS) {\r
-  }\r
-\r
-  //\r
-  // Store the read data in the read buffer, start at 2 to ignore status bytes\r
-  //\r
-  for (Index = 2; Index < ReadBufferSize; Index++) {\r
-    if (((UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH) == UsbSerialDevice->DataBufferHead) {\r
-      break;\r
-    }\r
-    if (ReadBuffer[Index] == 0x00) {\r
-      //\r
-      // This is null, do not add\r
-      //\r
-    } else {\r
-      UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferTail] = ReadBuffer[Index];\r
-      UsbSerialDevice->DataBufferTail = (UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Read characters out of the buffer to satisfy caller's request.\r
-  //\r
-  for (Index = 0; Index < *BufferSize; Index++) {\r
-    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {\r
-      break;\r
-    }\r
-    //\r
-    // Still have characters in the buffer to return\r
-    //\r
-    ((UINT8 *)Buffer)[Index]        = UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferHead];\r
-    UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead + 1) % SW_FIFO_DEPTH;\r
-  }\r
-  //\r
-  // Return actual number of bytes returned.\r
-  //\r
-  *BufferSize = Index;\r
-  gBS->RestoreTPL (Tpl);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Sets the initial status values of the Usb Serial Device by reading the status\r
-  bytes from the device.\r
-\r
-  @param  UsbSerialDevice[in]  Handle to the Usb Serial Device that needs its\r
-                               initial status values set\r
-\r
-  @retval EFI_SUCCESS          The status bytes were read successfully and the\r
-                               initial status values were set correctly\r
-  @retval EFI_TIMEOUT          The read of the status bytes was stopped due to a\r
-                               timeout\r
-  @retval EFI_DEVICE_ERROR     The device reported an error during the read of\r
-                               the status bytes\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetInitialStatus (\r
-  IN USB_SER_DEV          *UsbSerialDevice\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  UINTN           BufferSize;\r
-  EFI_TPL         Tpl;\r
-  UINT8           StatusBuffer[2];\r
-\r
-  Status          = EFI_UNSUPPORTED;\r
-  BufferSize      = sizeof (StatusBuffer);\r
-\r
-  if (UsbSerialDevice->Shutdown) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Status = UsbSerialDataTransfer (\r
-             UsbSerialDevice,\r
-             EfiUsbDataIn,\r
-             StatusBuffer,\r
-             &BufferSize,\r
-             40    //Slightly more than 2x the FTDI polling frequency to make sure that data will be returned\r
-             );\r
-\r
-  Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  UsbSerialDriverCheckInput.\r
-  attempts to read data in from the device periodically, stores any read data\r
-  and updates the control attributes.\r
-\r
-  @param  Event[in]\r
-  @param  Context[in]....The current instance of the USB serial device\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-UsbSerialDriverCheckInput (\r
-  IN  EFI_EVENT  Event,\r
-  IN  VOID       *Context\r
-  )\r
-{\r
-  UINTN        BufferSize;\r
-  USB_SER_DEV  *UsbSerialDevice;\r
-\r
-  UsbSerialDevice = (USB_SER_DEV*)Context;\r
-\r
-  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {\r
-    //\r
-    // Data buffer is empty, try to read from device\r
-    //\r
-    BufferSize = 0;\r
-    ReadDataFromUsb (UsbSerialDevice, &BufferSize, NULL);\r
-    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {\r
-      //\r
-      // Data buffer still has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY\r
-      // flag\r
-      //\r
-      UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;\r
-    } else {\r
-      //\r
-      // Read has returned some data, clear the EFI_SERIAL_INPUT_BUFFER_EMPTY\r
-      // flag\r
-      //\r
-      UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);\r
-    }\r
-  } else {\r
-    //\r
-    // Data buffer has data, no read attempt required\r
-    //\r
-    UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);\r
-  }\r
-}\r
-\r
-/**\r
-  Encodes the baud rate into the format expected by the Ftdi device.\r
-\r
-  @param  BaudRate[in]                The baudrate to be set on the device\r
-  @param  EncodedBaudRate[out]        The baud rate encoded in the format\r
-                                      expected by the Ftdi device\r
-\r
-  @return EFI_SUCCESS                 Baudrate encoding was calculated\r
-                                      successfully\r
-  @return EFI_INVALID_PARAMETER       An invalid value of BaudRate was received\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-EncodeBaudRateForFtdi (\r
-  IN  UINT64  BaudRate,\r
-  OUT UINT16  *EncodedBaudRate\r
-  )\r
-{\r
-  UINT32 Divisor;\r
-  UINT32 AdjustedFrequency;\r
-  UINT16 Result;\r
-\r
-  //\r
-  // Check to make sure we won't get an integer overflow\r
-  //\r
-  if ((BaudRate < 178) || ( BaudRate > ((FTDI_UART_FREQUENCY * 100) / 97))) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Baud Rates of 2000000 and 3000000 are special cases\r
-  //\r
-  if ((BaudRate >= FTDI_SPECIAL_CASE_300_MIN) && (BaudRate <= FTDI_SPECIAL_CASE_300_MAX)) {\r
-    *EncodedBaudRate = 0;\r
-    return EFI_SUCCESS;\r
-  }\r
-  if ((BaudRate >= FTDI_SPECIAL_CASE_200_MIN) && (BaudRate <= FTDI_SPECIAL_CASE_200_MAX)) {\r
-    *EncodedBaudRate = 1;\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Compute divisor\r
-  //\r
-  Divisor = (FTDI_UART_FREQUENCY << 4) / (UINT32)BaudRate;\r
-\r
-  //\r
-  // Round the last 4 bits to the nearest power of 2\r
-  //\r
-  Divisor = (Divisor & ~(0xF)) + (gRoundedPowersOf2[Divisor & 0xF]);\r
-\r
-  //\r
-  // Check to make sure computed divisor is within \r
-  // the min and max that FTDI controller will accept\r
-  //\r
-  if (Divisor < FTDI_MIN_DIVISOR) {\r
-    Divisor = FTDI_MIN_DIVISOR;\r
-  } else if (Divisor > FTDI_MAX_DIVISOR) {\r
-    Divisor = FTDI_MAX_DIVISOR;\r
-  }\r
-\r
-  //\r
-  // Check to make sure the frequency that the FTDI chip will need to\r
-  // generate to attain the requested Baud Rate is within 3% of the\r
-  // 3MHz clock frequency that the FTDI chip runs at.\r
-  //\r
-  // (3MHz * 1600) / 103 = 46601941\r
-  // (3MHz * 1600) / 97  = 49484536\r
-  //\r
-  AdjustedFrequency = (((UINT32)BaudRate) * Divisor);\r
-  if ((AdjustedFrequency < FTDI_MIN_FREQUENCY) || (AdjustedFrequency > FTDI_MAX_FREQUENCY)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Encode the Divisor into the format FTDI expects\r
-  //\r
-  Result = (UINT16)(Divisor >> 4);\r
-  if ((Divisor & 0x8) != 0) {\r
-    Result |= 0x4000;\r
-  } else if ((Divisor & 0x4) != 0) {\r
-    Result |= 0x8000;\r
-  } else if ((Divisor & 0x2) != 0) {\r
-    Result |= 0xC000;\r
-  }\r
-\r
-  *EncodedBaudRate = Result;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Uses USB I/O to check whether the device is a USB Serial device.\r
-\r
-  @param  UsbIo[in]    Pointer to a USB I/O protocol instance.\r
-\r
-  @retval TRUE         Device is a USB Serial device.\r
-  @retval FALSE        Device is a not USB Serial device.\r
-\r
-**/\r
-BOOLEAN\r
-IsUsbSerial (\r
-  IN  EFI_USB_IO_PROTOCOL  *UsbIo\r
-  )\r
-{\r
-  EFI_STATUS                 Status;\r
-  EFI_USB_DEVICE_DESCRIPTOR  DeviceDescriptor;\r
-  CHAR16                     *StrMfg;\r
-  BOOLEAN                    Found;\r
-  UINT32                     Index;\r
-\r
-  //\r
-  // Get the default device descriptor\r
-  //\r
-  Status = UsbIo->UsbGetDeviceDescriptor (\r
-                    UsbIo,\r
-                    &DeviceDescriptor\r
-                    );\r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
-  }\r
-\r
-  Found = FALSE;\r
-  Index = 0;\r
-  while (gUSBDeviceList[Index].VendorId != 0 &&\r
-         gUSBDeviceList[Index].DeviceId != 0 &&\r
-         !Found                                  ) {\r
-    if (DeviceDescriptor.IdProduct == gUSBDeviceList[Index].DeviceId &&\r
-        DeviceDescriptor.IdVendor  == gUSBDeviceList[Index].VendorId      ){\r
-        //\r
-        // Checks to see if a string descriptor can be pulled from the device in\r
-        // the selected language. If not False is returned indicating that this\r
-        // is not a Usb Serial Device that can be managegd by this driver\r
-        //\r
-        StrMfg = NULL;\r
-        Status = UsbIo->UsbGetStringDescriptor (\r
-                          UsbIo,\r
-                          USB_US_LANG_ID, // LANGID selector, should make this\r
-                                          // more robust to verify lang support\r
-                                          // for device\r
-                          DeviceDescriptor.StrManufacturer,\r
-                          &StrMfg\r
-                          );\r
-        if (StrMfg != NULL) {\r
-          FreePool (StrMfg);\r
-        }\r
-        if (EFI_ERROR (Status)) {\r
-          return FALSE;\r
-        }\r
-        return TRUE;\r
-    }\r
-    Index++;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Internal function that sets the Data Bits, Stop Bits and Parity values on the\r
-  Usb Serial Device with a single usb control transfer.\r
-\r
-  @param  UsbIo[in]                  Usb Io Protocol instance pointer\r
-  @param  DataBits[in]               The data bits value to be set on the Usb\r
-                                     Serial Device\r
-  @param  Parity[in]                 The parity type that will be set on the Usb\r
-                                     Serial Device\r
-  @param  StopBits[in]               The stop bits type that will be set on the\r
-                                     Usb Serial Device\r
-  @param  LastSettings[in]           A pointer to the Usb Serial Device's\r
-                                     PREVIOUS_ATTRIBUTES item\r
-\r
-  @retval EFI_SUCCESS                The data items were correctly set on the\r
-                                     USB Serial Device\r
-  @retval EFI_INVALID_PARAMETER      An invalid data parameter or an invalid\r
-                                     combination or parameters was used\r
-  @retval EFI_DEVICE_ERROR           The device is not functioning correctly and\r
-                                     the data values were unable to be set\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetDataInternal (\r
-  IN EFI_USB_IO_PROTOCOL  *UsbIo,\r
-  IN UINT8                DataBits,\r
-  IN EFI_PARITY_TYPE      Parity,\r
-  IN EFI_STOP_BITS_TYPE   StopBits,\r
-  IN PREVIOUS_ATTRIBUTES  *LastSettings\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_USB_DEVICE_REQUEST  DevReq;\r
-  UINT32                  ReturnValue;\r
-  UINT8                   ConfigurationValue;\r
-\r
-  //\r
-  // Since data bits settings of 6,7,8 cannot be set with a stop bits setting of\r
-  // 1.5 check to see if this happens when the values of last settings are used\r
-  //\r
-  if ((DataBits == 0) && (StopBits == OneFiveStopBits)) {\r
-    if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) || (LastSettings->DataBits == 8)) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  } else if ((StopBits == DefaultStopBits) && ((DataBits == 6) || (DataBits == 7) || (DataBits == 8))) {\r
-    if (LastSettings->StopBits == OneFiveStopBits) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  } else if ((DataBits == 0) && (StopBits == DefaultStopBits)) {\r
-    if (LastSettings->StopBits == OneFiveStopBits) {\r
-      if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) || (LastSettings->DataBits == 8)) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // set the DevReq.Value for the usb control transfer to the correct value\r
-  // based on the seleceted number of data bits if there is an invalid number of\r
-  // data bits requested return EFI_INVALID_PARAMETER\r
-  //\r
-  if (((DataBits < 5 ) || (DataBits > 8)) && (DataBits != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  if (DataBits == 0) {\r
-    //\r
-    // use the value of LastDataBits\r
-    //\r
-    DevReq.Value = SET_DATA_BITS (LastSettings->DataBits);\r
-  } else {\r
-    //\r
-    // use the value of DataBits\r
-    //\r
-    DevReq.Value = SET_DATA_BITS (DataBits);\r
-  }\r
-\r
-  //\r
-  // Set Parity\r
-  //\r
-  if (Parity == DefaultParity) {\r
-    Parity = LastSettings->Parity;\r
-  }\r
-\r
-  if (Parity == NoParity) {\r
-    DevReq.Value |= SET_PARITY_NONE;\r
-  } else if (Parity == EvenParity) {\r
-    DevReq.Value |= SET_PARITY_EVEN;\r
-  } else if (Parity == OddParity){\r
-    DevReq.Value |= SET_PARITY_ODD;\r
-  } else if (Parity == MarkParity) {\r
-    DevReq.Value |= SET_PARITY_MARK;\r
-  } else if (Parity == SpaceParity) {\r
-    DevReq.Value |= SET_PARITY_SPACE;\r
-  }\r
-\r
-  //\r
-  // Set Stop Bits\r
-  //\r
-  if (StopBits == DefaultStopBits) {\r
-    StopBits = LastSettings->StopBits;\r
-  }\r
-\r
-  if (StopBits == OneStopBit) {\r
-    DevReq.Value |= SET_STOP_BITS_1;\r
-  } else if (StopBits == OneFiveStopBits) {\r
-    DevReq.Value |= SET_STOP_BITS_15;\r
-  } else if (StopBits == TwoStopBits) {\r
-    DevReq.Value |= SET_STOP_BITS_2;\r
-  }\r
-\r
-  //\r
-  // set the rest of the DevReq parameters and perform the usb control transfer\r
-  // to set the data bits on the device\r
-  //\r
-  DevReq.Request     = FTDI_COMMAND_SET_DATA;\r
-  DevReq.RequestType = USB_REQ_TYPE_VENDOR;\r
-  DevReq.Index       = FTDI_PORT_IDENTIFIER;\r
-  DevReq.Length      = 0; // indicates that there is no data phase in this request\r
-\r
-  Status = UsbIo->UsbControlTransfer (\r
-                    UsbIo,\r
-                    &DevReq,\r
-                    EfiUsbDataOut,\r
-                    WDR_SHORT_TIMEOUT,\r
-                    &ConfigurationValue,\r
-                    1,\r
-                    &ReturnValue\r
-                    );\r
-  if (EFI_ERROR (Status)) {\r
-    goto StatusError;\r
-  }\r
-  return Status;\r
-\r
-StatusError:\r
-  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {\r
-    return EFI_DEVICE_ERROR;\r
-  } else {\r
-    return Status;\r
-  }\r
-}\r
-\r
-/**\r
-  Internal function that sets the baudrate on the Usb Serial Device.\r
-\r
-  @param  UsbIo[in]                  Usb Io Protocol instance pointer\r
-  @param  BaudRate[in]               The baudrate value to be set on the device.\r
-                                     If this value is 0 the value of LastBaudRate\r
-                                     will be used instead\r
-  @param  LastBaudRate[in]           The baud rate value that was previously set\r
-                                     on the Usb Serial Device\r
-\r
-  @retval EFI_SUCCESS                The baudrate was set succesfully\r
-  @retval EFI_INVALID_PARAMETER      An invalid baudrate was used\r
-  @retval EFI_DEVICE_ERROR           The device is not functioning correctly and\r
-                                     the baudrate was unable to be set\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetBaudRateInternal (\r
-  IN EFI_USB_IO_PROTOCOL  *UsbIo,\r
-  IN UINT64               BaudRate,\r
-  IN UINT64               LastBaudRate\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_USB_DEVICE_REQUEST  DevReq;\r
-  UINT32                  ReturnValue;\r
-  UINT8                   ConfigurationValue;\r
-  UINT16                  EncodedBaudRate;\r
-  EFI_TPL                 Tpl;\r
-\r
-  Tpl    = gBS->RaiseTPL(TPL_NOTIFY);\r
-\r
-  //\r
-  // set the value of DevReq.Value based on the value of BaudRate\r
-  // if 0 is selected as baud rate use the value of LastBaudRate\r
-  //\r
-  if (BaudRate == 0) {\r
-    Status = EncodeBaudRateForFtdi (LastBaudRate, &EncodedBaudRate);\r
-    if (EFI_ERROR (Status)) {\r
-      gBS->RestoreTPL (Tpl);\r
-      //\r
-      // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not\r
-      // succesfull\r
-      //\r
-      return Status;\r
-    }\r
-    DevReq.Value = EncodedBaudRate;\r
-  } else {\r
-    Status = EncodeBaudRateForFtdi (BaudRate, &EncodedBaudRate);\r
-    if (EFI_ERROR (Status)) {\r
-      gBS->RestoreTPL (Tpl);\r
-      //\r
-      // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not\r
-      // successfull\r
-      //\r
-      return Status;\r
-    }\r
-    DevReq.Value = EncodedBaudRate;\r
-  }\r
-\r
-  //\r
-  // set the remaining parameters of DevReq and perform the usb control transfer\r
-  // to set the device\r
-  //\r
-  DevReq.Request     = FTDI_COMMAND_SET_BAUDRATE;\r
-  DevReq.RequestType = USB_REQ_TYPE_VENDOR;\r
-  DevReq.Index       = FTDI_PORT_IDENTIFIER;\r
-  DevReq.Length      = 0; // indicates that there is no data phase in this request\r
-\r
-  Status = UsbIo->UsbControlTransfer (\r
-                    UsbIo,\r
-                    &DevReq,\r
-                    EfiUsbDataOut,\r
-                    WDR_SHORT_TIMEOUT,\r
-                    &ConfigurationValue,\r
-                    1,\r
-                    &ReturnValue\r
-                    );\r
-  if (EFI_ERROR (Status)) {\r
-    goto StatusError;\r
-  }\r
-  gBS->RestoreTPL (Tpl);\r
-  return Status;\r
-\r
-StatusError:\r
-  gBS->RestoreTPL (Tpl);\r
-  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {\r
-    return EFI_DEVICE_ERROR;\r
-  } else {\r
-    return Status;\r
-  }\r
-}\r
-\r
-/**\r
-  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,\r
-  data bits, and stop bits on a serial device.\r
-\r
-  @param  UsbSerialDevice[in]  Pointer to the current instance of the USB Serial\r
-                               Device.\r
-  @param  BaudRate[in]         The requested baud rate. A BaudRate value of 0\r
-                               will use the device's default interface speed.\r
-  @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the receive\r
-                               side of the serial interface. A ReceiveFifoDepth\r
-                               value of 0 will use the device's default FIFO\r
-                               depth.\r
-  @param  Timeout[in]          The requested time out for a single character in\r
-                               microseconds.This timeout applies to both the\r
-                               transmit and receive side of the interface.A\r
-                               Timeout value of 0 will use the device's default\r
-                               time out value.\r
-  @param  Parity[in]           The type of parity to use on this serial device.\r
-                               A Parity value of DefaultParity will use the\r
-                               device's default parity value.\r
-  @param  DataBits[in]         The number of data bits to use on the serial\r
-                               device. A DataBits value of 0 will use the\r
-                               device's default data bit setting.\r
-  @param  StopBits[in]         The number of stop bits to use on this serial\r
-                               device. A StopBits value of DefaultStopBits will\r
-                               use the device's default number of stop bits.\r
-\r
-  @retval EFI_SUCCESS          The attributes were set\r
-  @retval EFI_DEVICE_ERROR     The attributes were not able to be set\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetAttributesInternal (\r
-  IN USB_SER_DEV         *UsbSerialDevice,\r
-  IN UINT64              BaudRate,\r
-  IN UINT32              ReceiveFifoDepth,\r
-  IN UINT32              Timeout,\r
-  IN EFI_PARITY_TYPE     Parity,\r
-  IN UINT8               DataBits,\r
-  IN EFI_STOP_BITS_TYPE  StopBits\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  EFI_TPL                   Tpl;\r
-  UART_DEVICE_PATH          *Uart;\r
-  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;\r
-\r
-  Status = EFI_UNSUPPORTED;\r
-  Tpl    = gBS->RaiseTPL(TPL_NOTIFY);\r
-  Uart   = NULL;\r
-\r
-  //\r
-  // check for invalid combinations of parameters\r
-  //\r
-  if (((DataBits >= 6) && (DataBits <= 8)) && (StopBits == OneFiveStopBits)) {\r
-    return  EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // set data bits, parity and stop bits\r
-  //\r
-  Status = SetDataInternal (\r
-             UsbSerialDevice->UsbIo,\r
-             DataBits,\r
-             Parity,\r
-             StopBits,\r
-             &(UsbSerialDevice->LastSettings)\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto StatusError;\r
-  }\r
-  //\r
-  // set baudrate\r
-  //\r
-  Status = SetBaudRateInternal (\r
-             UsbSerialDevice->UsbIo,\r
-             BaudRate,\r
-             UsbSerialDevice->LastSettings.BaudRate\r
-             );\r
-  if (EFI_ERROR (Status)){\r
-    goto StatusError;\r
-  }\r
-\r
-  //\r
-  // update the values of UsbSerialDevice->LastSettings and UsbSerialDevice->SerialIo.Mode\r
-  //\r
-  if (BaudRate == 0) {\r
-    UsbSerialDevice->LastSettings.BaudRate   = UsbSerialDevice->LastSettings.BaudRate;\r
-    UsbSerialDevice->SerialIo.Mode->BaudRate = UsbSerialDevice->LastSettings.BaudRate;\r
-  } else {\r
-    UsbSerialDevice->LastSettings.BaudRate   = BaudRate;\r
-    UsbSerialDevice->SerialIo.Mode->BaudRate = BaudRate;\r
-  }\r
-\r
-  UsbSerialDevice->LastSettings.Timeout          = FTDI_TIMEOUT;\r
-  UsbSerialDevice->LastSettings.ReceiveFifoDepth = FTDI_MAX_RECEIVE_FIFO_DEPTH;\r
-\r
-  if (Parity == DefaultParity) {\r
-    UsbSerialDevice->LastSettings.Parity   = UsbSerialDevice->LastSettings.Parity;\r
-    UsbSerialDevice->SerialIo.Mode->Parity = UsbSerialDevice->LastSettings.Parity;\r
-  } else {\r
-    UsbSerialDevice->LastSettings.Parity   = Parity;\r
-    UsbSerialDevice->SerialIo.Mode->Parity = Parity;\r
-  }\r
-  if (DataBits == 0) {\r
-    UsbSerialDevice->LastSettings.DataBits   = UsbSerialDevice->LastSettings.DataBits;\r
-    UsbSerialDevice->SerialIo.Mode->DataBits = UsbSerialDevice->LastSettings.DataBits;\r
-  } else {\r
-    UsbSerialDevice->LastSettings.DataBits   = DataBits;\r
-    UsbSerialDevice->SerialIo.Mode->DataBits = DataBits;\r
-  }\r
-  if (StopBits == DefaultStopBits) {\r
-    UsbSerialDevice->LastSettings.StopBits   = UsbSerialDevice->LastSettings.StopBits;\r
-    UsbSerialDevice->SerialIo.Mode->StopBits = UsbSerialDevice->LastSettings.StopBits;\r
-  } else {\r
-    UsbSerialDevice->LastSettings.StopBits   = StopBits;\r
-    UsbSerialDevice->SerialIo.Mode->StopBits = StopBits;\r
-  }\r
-\r
-  //\r
-  // See if the device path node has changed\r
-  //\r
-  if (UsbSerialDevice->UartDevicePath.BaudRate == BaudRate &&\r
-      UsbSerialDevice->UartDevicePath.DataBits == DataBits &&\r
-      UsbSerialDevice->UartDevicePath.StopBits == StopBits &&\r
-      UsbSerialDevice->UartDevicePath.Parity == Parity\r
-      ) {\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Update the device path\r
-  //\r
-  UsbSerialDevice->UartDevicePath.BaudRate = BaudRate;\r
-  UsbSerialDevice->UartDevicePath.DataBits = DataBits;\r
-  UsbSerialDevice->UartDevicePath.StopBits = (UINT8) StopBits;\r
-  UsbSerialDevice->UartDevicePath.Parity   = (UINT8) Parity;\r
-\r
-  Status = EFI_SUCCESS;\r
-  if (UsbSerialDevice->ControllerHandle != NULL) {\r
-    RemainingDevicePath = UsbSerialDevice->DevicePath;\r
-    while (!IsDevicePathEnd (RemainingDevicePath)) {\r
-      Uart = (UART_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);\r
-      if (Uart->Header.Type == MESSAGING_DEVICE_PATH &&\r
-          Uart->Header.SubType == MSG_UART_DP &&\r
-          sizeof (UART_DEVICE_PATH) == DevicePathNodeLength ((EFI_DEVICE_PATH *) Uart)) {\r
-        Uart->BaudRate = BaudRate;\r
-        Uart->DataBits = DataBits;\r
-        Uart->StopBits = (UINT8)StopBits;\r
-        Uart->Parity   = (UINT8) Parity;\r
-        break;\r
-        }\r
-        RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);\r
-    }\r
-  }\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-  return Status;\r
-\r
-StatusError:\r
-  gBS->RestoreTPL (Tpl);\r
-  if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {\r
-    return EFI_DEVICE_ERROR;\r
-  } else {\r
-    return Status;\r
-  }\r
-}\r
-\r
-/**\r
-  Internal function that performs a Usb Control Transfer to set the flow control\r
-  on the Usb Serial Device.\r
-\r
-  @param  UsbIo[in]                  Usb Io Protocol instance pointer\r
-  @param  FlowControlEnable[in]      Data on the Enable/Disable status of Flow\r
-                                     Control on the Usb Serial Device\r
-\r
-  @retval EFI_SUCCESS                The flow control was set on the Usb Serial\r
-                                     device\r
-  @retval EFI_INVALID_PARAMETER      An invalid flow control value was used\r
-  @retval EFI_EFI_UNSUPPORTED        The operation is not supported\r
-  @retval EFI_DEVICE_ERROR           The device is not functioning correctly\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetFlowControlInternal (\r
-  IN EFI_USB_IO_PROTOCOL  *UsbIo,\r
-  IN BOOLEAN              FlowControlEnable\r
-  )\r
-{\r
-  EFI_STATUS               Status;\r
-  EFI_USB_DEVICE_REQUEST   DevReq;\r
-  UINT32                   ReturnValue;\r
-  UINT8                    ConfigurationValue;\r
-\r
-  //\r
-  // set DevReq.Value based on the value of FlowControlEnable\r
-  //\r
-  if (!FlowControlEnable) {\r
-    DevReq.Value = NO_FLOW_CTRL;\r
-  }\r
-  if (FlowControlEnable) {\r
-    DevReq.Value = XON_XOFF_CTRL;\r
-  }\r
-  //\r
-  // set the remaining DevReq parameters and perform the usb control transfer to\r
-  // set the flow control on the device\r
-  //\r
-  DevReq.Request      = FTDI_COMMAND_SET_FLOW_CTRL;\r
-  DevReq.RequestType  = USB_REQ_TYPE_VENDOR;\r
-  DevReq.Index        = FTDI_PORT_IDENTIFIER;\r
-  DevReq.Length       = 0; // indicates that this transfer has no data phase\r
-  Status              = UsbIo->UsbControlTransfer (\r
-                                 UsbIo,\r
-                                 &DevReq,\r
-                                 EfiUsbDataOut,\r
-                                 WDR_TIMEOUT,\r
-                                 &ConfigurationValue,\r
-                                 1,\r
-                                 &ReturnValue\r
-                                 );\r
-  if (EFI_ERROR (Status)) {\r
-    goto StatusError;\r
-  }\r
-\r
-  return Status;\r
-\r
-StatusError:\r
-  if ((Status != EFI_INVALID_PARAMETER) ||\r
-      (Status != EFI_DEVICE_ERROR)      ||\r
-      (Status != EFI_UNSUPPORTED)          ) {\r
-    return EFI_DEVICE_ERROR;\r
-  } else {\r
-    return Status;\r
-  }\r
-}\r
-\r
-/**\r
-  Internal function that performs a Usb Control Transfer to set the Dtr value on\r
-  the Usb Serial Device.\r
-\r
-  @param  UsbIo[in]                  Usb Io Protocol instance pointer\r
-  @param  DtrEnable[in]              Data on the Enable/Disable status of the\r
-                                     Dtr for the Usb Serial Device\r
-\r
-  @retval EFI_SUCCESS                The Dtr value was set on the Usb Serial\r
-                                     Device\r
-  @retval EFI_INVALID_PARAMETER      An invalid Dtr value was used\r
-  @retval EFI_UNSUPPORTED            The operation is not supported\r
-  @retval EFI_DEVICE_ERROR           The device is not functioning correctly\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetDtrInternal (\r
-  IN EFI_USB_IO_PROTOCOL  *UsbIo,\r
-  IN BOOLEAN              DtrEnable\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_USB_DEVICE_REQUEST  DevReq;\r
-  UINT32                  ReturnValue;\r
-  UINT8                   ConfigurationValue;\r
-\r
-  //\r
-  // set the value of DevReq.Value based on the value of DtrEnable\r
-  //\r
-  if (!DtrEnable) {\r
-    DevReq.Value = SET_DTR_LOW;\r
-  }\r
-  if (DtrEnable) {\r
-    DevReq.Value = SET_DTR_HIGH;\r
-  }\r
-  //\r
-  // set the remaining attributes of DevReq and perform the usb control transfer\r
-  // to set the device\r
-  //\r
-  DevReq.Request      = FTDI_COMMAND_MODEM_CTRL;\r
-  DevReq.RequestType  = USB_REQ_TYPE_VENDOR;\r
-  DevReq.Index        = FTDI_PORT_IDENTIFIER;\r
-  DevReq.Length       = 0; // indicates that there is no data phase in this transfer\r
-\r
-  Status = UsbIo->UsbControlTransfer (\r
-                    UsbIo,\r
-                    &DevReq,\r
-                    EfiUsbDataOut,\r
-                    WDR_TIMEOUT,\r
-                    &ConfigurationValue,\r
-                    1,\r
-                    &ReturnValue\r
-                    );\r
-  if (EFI_ERROR (Status)) {\r
-    goto StatusError;\r
-  }\r
-  return Status;\r
-\r
-StatusError:\r
-  if ((Status != EFI_INVALID_PARAMETER) ||\r
-      (Status != EFI_DEVICE_ERROR)      ||\r
-      (Status != EFI_UNSUPPORTED)          ) {\r
-    return EFI_DEVICE_ERROR;\r
-  } else {\r
-    return Status;\r
-  }\r
-}\r
-\r
-/**\r
-  Internal function that performs a Usb Control Transfer to set the Dtr value on\r
-  the Usb Serial Device.\r
-  \r
-  @param  UsbIo[in]                  Usb Io Protocol instance pointer\r
-  @param  RtsEnable[in]              Data on the Enable/Disable status of the\r
-                                     Rts for the Usb Serial Device\r
-\r
-  @retval EFI_SUCCESS                The Rts value was set on the Usb Serial\r
-                                     Device\r
-  @retval EFI_INVALID_PARAMETER      An invalid Rts value was used\r
-  @retval EFI_UNSUPPORTED            The operation is not supported\r
-  @retval EFI_DEVICE_ERROR           The device is not functioning correctly\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetRtsInternal (\r
-  IN EFI_USB_IO_PROTOCOL  *UsbIo,\r
-  IN BOOLEAN              RtsEnable\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_USB_DEVICE_REQUEST  DevReq;\r
-  UINT32                  ReturnValue;\r
-  UINT8                   ConfigurationValue;\r
-\r
-  //\r
-  // set DevReq.Value based on the value of RtsEnable\r
-  //\r
-  if (!RtsEnable) {\r
-    DevReq.Value = SET_RTS_LOW;\r
-  }\r
-  if (RtsEnable) {\r
-    DevReq.Value = SET_RTS_HIGH;\r
-  }\r
-\r
-  //\r
-  // set the remaining parameters of DevReq and perform the usb control transfer\r
-  // to set the values on the device\r
-  //\r
-  DevReq.Request     = FTDI_COMMAND_MODEM_CTRL;\r
-  DevReq.RequestType = USB_REQ_TYPE_VENDOR;\r
-  DevReq.Index       = FTDI_PORT_IDENTIFIER;\r
-  DevReq.Length      = 0; // indicates that there is no data phase in this request\r
-\r
-  Status = UsbIo->UsbControlTransfer (\r
-                    UsbIo,\r
-                    &DevReq,\r
-                    EfiUsbDataOut,\r
-                    WDR_TIMEOUT,\r
-                    &ConfigurationValue,\r
-                    1,\r
-                    &ReturnValue\r
-                    );\r
-  if (EFI_ERROR (Status)) {\r
-    goto StatusError;\r
-  }\r
-\r
-  return Status;\r
-\r
-StatusError:\r
-  if ((Status != EFI_INVALID_PARAMETER) ||\r
-      (Status != EFI_DEVICE_ERROR)      ||\r
-      (Status != EFI_UNSUPPORTED)          ) {\r
-    return EFI_DEVICE_ERROR;\r
-  } else {\r
-    return Status;\r
-  }\r
-}\r
-\r
-/**\r
-  Internal function that checks for valid control values and sets the control\r
-  bits on the Usb Serial Device.\r
-\r
-  @param  UsbSerialDevice[in]        Handle to the Usb Serial Device whose\r
-                                     control bits are being set\r
-  @param  Control[in]                The control value passed to the function\r
-                                     that contains the values of the control\r
-                                     bits that are being set\r
-\r
-  @retval EFI_SUCCESS                The control bits were set on the Usb Serial\r
-                                     Device\r
-  @retval EFI_INVALID_PARAMETER      An invalid control value was encountered\r
-  @retval EFI_EFI_UNSUPPORTED        The operation is not supported\r
-  @retval EFI_DEVICE_ERROR           The device is not functioning correctly\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetControlBitsInternal (\r
-  IN USB_SER_DEV   *UsbSerialDevice,\r
-  IN CONTROL_BITS  *Control\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;\r
-  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath;\r
-\r
-  //\r
-  // check for invalid control parameters hardware and software loopback enabled\r
-  // must always be set to FALSE\r
-  //\r
-  Control->HardwareLoopBack = FALSE;\r
-  Control->SoftwareLoopBack = FALSE;\r
-\r
-  //\r
-  // set hardware flow control\r
-  //\r
-  Status  = SetFlowControlInternal (\r
-              UsbSerialDevice->UsbIo,\r
-              Control->HardwareFlowControl\r
-              );\r
-  if (EFI_ERROR (Status)) {\r
-    goto StatusError;\r
-  }\r
-\r
-  //\r
-  // set Dtr state\r
-  //\r
-  Status = SetDtrInternal (UsbSerialDevice->UsbIo, Control->DtrState);\r
-  if (EFI_ERROR (Status)) {\r
-    goto StatusError;\r
-  }\r
-\r
-  //\r
-  // set Rts state\r
-  //\r
-  Status = SetRtsInternal (UsbSerialDevice->UsbIo, Control->RtsState);\r
-  if (EFI_ERROR (Status)){\r
-    goto StatusError;\r
-  }\r
-\r
-  //\r
-  // update the remaining control values for UsbSerialDevice->ControlValues\r
-  //\r
-  UsbSerialDevice->ControlValues.DtrState            = Control->DtrState;\r
-  UsbSerialDevice->ControlValues.RtsState            = Control->RtsState;\r
-  UsbSerialDevice->ControlValues.HardwareFlowControl = Control->HardwareFlowControl;\r
-  UsbSerialDevice->ControlValues.HardwareLoopBack    = FALSE;\r
-  UsbSerialDevice->ControlValues.SoftwareLoopBack    = FALSE;\r
-\r
-  Status = EFI_SUCCESS;\r
-  //\r
-  // Update the device path to have the correct flow control values\r
-  //\r
-  if (UsbSerialDevice->ControllerHandle != NULL) {\r
-    RemainingDevicePath = UsbSerialDevice->DevicePath;\r
-    while (!IsDevicePathEnd (RemainingDevicePath)) {\r
-      FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);\r
-      if (FlowControl->Header.Type == MESSAGING_DEVICE_PATH &&\r
-          FlowControl->Header.SubType == MSG_VENDOR_DP &&\r
-          sizeof (UART_FLOW_CONTROL_DEVICE_PATH) == DevicePathNodeLength ((EFI_DEVICE_PATH *) FlowControl)){\r
-        if (UsbSerialDevice->ControlValues.HardwareFlowControl == TRUE) {\r
-          FlowControl->FlowControlMap = UART_FLOW_CONTROL_HARDWARE;\r
-        } else if (UsbSerialDevice->ControlValues.HardwareFlowControl == FALSE) {\r
-          FlowControl->FlowControlMap = 0;\r
-        }\r
-        break;\r
-      }\r
-      RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);\r
-    }\r
-  }\r
-\r
-  return Status;\r
-\r
-StatusError:\r
-  if ((Status != EFI_INVALID_PARAMETER) ||\r
-      (Status != EFI_DEVICE_ERROR)      ||\r
-      (Status != EFI_UNSUPPORTED)          ) {\r
-    return EFI_DEVICE_ERROR;\r
-  } else {\r
-    return Status;\r
-  }\r
-}\r
-\r
-/**\r
-  Internal function that calculates the Control value used by GetControlBits()\r
-  based on the status and control values of the Usb Serial Device.\r
-\r
-  @param  UsbSerialDevice[in]        Handle to the Usb Serial Devie whose status\r
-                                     and control values are being used to set\r
-                                     Control\r
-  @param  Control[out]               On output the formated value of Control\r
-                                     that has been calculated based on the\r
-                                     control and status values of the Usb Serial\r
-                                     Device\r
-\r
-  @retval EFI_SUCCESS                The value of Control was successfully\r
-                                     calculated\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetControlBitsInternal (\r
-  IN USB_SER_DEV  *UsbSerialDevice,\r
-  OUT UINT32      *Control\r
-  )\r
-{\r
-  *Control = 0;\r
-\r
-  //\r
-  // Check the values of UsbSerialDevice->Status Values and modify control\r
-  // accordingly these values correspond to the modem status register\r
-  //\r
-  if (UsbSerialDevice->StatusValues.CtsState) {\r
-    *Control |= EFI_SERIAL_CLEAR_TO_SEND;\r
-  }\r
-  if (UsbSerialDevice->StatusValues.DsrState) {\r
-    *Control |= EFI_SERIAL_DATA_SET_READY;\r
-  }\r
-  if (UsbSerialDevice->StatusValues.RiState) {\r
-    *Control |= EFI_SERIAL_RING_INDICATE;\r
-  }\r
-  if (UsbSerialDevice->StatusValues.SdState) {\r
-    *Control |= EFI_SERIAL_CARRIER_DETECT;\r
-  }\r
-\r
-  //\r
-  // check the values of UsbSerialDevice->ControlValues and modify control\r
-  // accordingly these values correspond to the values of the Modem Control\r
-  // Register\r
-  //\r
-  if (UsbSerialDevice->ControlValues.DtrState) {\r
-    *Control |= EFI_SERIAL_DATA_TERMINAL_READY;\r
-  }\r
-  if (UsbSerialDevice->ControlValues.RtsState) {\r
-    *Control |= EFI_SERIAL_REQUEST_TO_SEND;\r
-  }\r
-  if (UsbSerialDevice->ControlValues.HardwareLoopBack) {\r
-    *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;\r
-  }\r
-  if (UsbSerialDevice->ControlValues.HardwareFlowControl) {\r
-    *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
-  }\r
-  //\r
-  // check if the buffer is empty since only one is being used if it is empty\r
-  // set both the receive and transmit buffers to empty\r
-  //\r
-  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {\r
-    *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;\r
-    *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;\r
-  }\r
-  //\r
-  // check for software loopback enable in UsbSerialDevice->ControlValues\r
-  //\r
-  if (UsbSerialDevice->ControlValues.SoftwareLoopBack) {\r
-    *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Resets the USB Serial Device\r
-\r
-  This function is the internal method for resetting the device and is called by\r
-  SerialReset()\r
-\r
-  @param  UsbSerialDevice[in]  A pointer to the USB Serial device\r
-\r
-  @retval EFI_SUCCESS          The device was reset\r
-  @retval EFI_DEVICE_ERROR     The device could not be reset\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ResetInternal (\r
-  IN USB_SER_DEV  *UsbSerialDevice\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_USB_DEVICE_REQUEST  DevReq;\r
-  UINT8                   ConfigurationValue;\r
-  UINT32                  ReturnValue;\r
-\r
-  DevReq.Request     = FTDI_COMMAND_RESET_PORT;\r
-  DevReq.RequestType = USB_REQ_TYPE_VENDOR;\r
-  DevReq.Value       = RESET_PORT_PURGE_RX;\r
-  DevReq.Index       = FTDI_PORT_IDENTIFIER;\r
-  DevReq.Length      = 0; //indicates that there is not data phase in this request\r
-\r
-  Status = UsbSerialDevice->UsbIo->UsbControlTransfer (\r
-                                     UsbSerialDevice->UsbIo,\r
-                                     &DevReq,\r
-                                     EfiUsbDataIn,\r
-                                     WDR_TIMEOUT,\r
-                                     &ConfigurationValue,\r
-                                     1,\r
-                                     &ReturnValue\r
-                                     );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  DevReq.Request     = FTDI_COMMAND_RESET_PORT;\r
-  DevReq.RequestType = USB_REQ_TYPE_VENDOR;\r
-  DevReq.Value       = RESET_PORT_PURGE_TX;\r
-  DevReq.Index       = FTDI_PORT_IDENTIFIER;\r
-  DevReq.Length      = 0; //indicates that there is no data phase in this request\r
-\r
-  Status = UsbSerialDevice->UsbIo->UsbControlTransfer (\r
-                                     UsbSerialDevice->UsbIo,\r
-                                     &DevReq,\r
-                                     EfiUsbDataIn,\r
-                                     WDR_TIMEOUT,\r
-                                     &ConfigurationValue,\r
-                                     1,\r
-                                     &ReturnValue\r
-                                     );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Entrypoint of USB Serial Driver.\r
-\r
-  This function is the entrypoint of USB Serial Driver. It installs\r
-  Driver Binding Protocols together with Component Name Protocols.\r
-\r
-  @param  ImageHandle[in]       The firmware allocated handle for the EFI image.\r
-  @param  SystemTable[in]       A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS           The entry point is executed successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FtdiUsbSerialEntryPoint (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  Status = EfiLibInstallDriverBindingComponentName2 (\r
-             ImageHandle,\r
-             SystemTable,\r
-             &gUsbSerialDriverBinding,\r
-             ImageHandle,\r
-             &gUsbSerialComponentName,\r
-             &gUsbSerialComponentName2\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Unload function for the Usb Serial Driver.\r
-\r
-  @param  ImageHandle[in]    The allocated handle for the EFI image\r
-\r
-  @retval EFI_SUCCESS        The driver was unloaded successfully\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FtdiUsbSerialUnload (\r
-  IN EFI_HANDLE  ImageHandle\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_HANDLE  *HandleBuffer;\r
-  UINTN       HandleCount;\r
-  UINTN       Index;\r
-\r
-  //\r
-  // Retrieve all handles in the handle database\r
-  //\r
-  Status = gBS->LocateHandleBuffer (\r
-                  AllHandles,\r
-                  NULL,\r
-                  NULL,\r
-                  &HandleCount,\r
-                  &HandleBuffer\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Disconnect the driver from the handles in the handle database\r
-  //\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    Status = gBS->DisconnectController (\r
-                    HandleBuffer[Index],\r
-                    gImageHandle,\r
-                    NULL\r
-                    );\r
-  }\r
-\r
-  //\r
-  // Free the handle array\r
-  //\r
-  FreePool (HandleBuffer);\r
-\r
-  //\r
-  // Uninstall protocols installed by the driver in its entrypoint\r
-  //\r
-  Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                  ImageHandle,\r
-                  &gEfiDriverBindingProtocolGuid,\r
-                  &gUsbSerialDriverBinding,\r
-                  &gEfiComponentNameProtocolGuid,\r
-                  &gUsbSerialComponentName,\r
-                  &gEfiComponentName2ProtocolGuid,\r
-                  &gUsbSerialComponentName2,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Check whether USB Serial driver supports this device.\r
-\r
-  @param  This[in]                   The USB Serial driver binding protocol.\r
-  @param  Controller[in]             The controller handle to check.\r
-  @param  RemainingDevicePath[in]    The remaining device path.\r
-\r
-  @retval EFI_SUCCESS                The driver supports this controller.\r
-  @retval other                      This device isn't supported.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UsbSerialDriverBindingSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_STATUS           Status;\r
-  EFI_USB_IO_PROTOCOL  *UsbIo;\r
-  UART_DEVICE_PATH     *UartNode;\r
-  UART_FLOW_CONTROL_DEVICE_PATH        *FlowControlNode;\r
-  UINTN                                Index;\r
-  UINTN                                EntryCount;\r
-  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfoBuffer;\r
-  BOOLEAN                              HasFlowControl;\r
-  EFI_DEVICE_PATH_PROTOCOL             *DevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL             *ParentDevicePath;\r
-\r
-  if (RemainingDevicePath != NULL) {\r
-    if (!IsDevicePathEnd (RemainingDevicePath)) {\r
-      Status = EFI_UNSUPPORTED;\r
-      UartNode = (UART_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);\r
-      if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||\r
-          UartNode->Header.SubType != MSG_UART_DP ||\r
-          sizeof (UART_DEVICE_PATH) != DevicePathNodeLength ((EFI_DEVICE_PATH *) UartNode)) {\r
-        goto Error;\r
-      }\r
-      FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (UartNode);\r
-      if ((ReadUnaligned32 (&FlowControlNode->FlowControlMap) & ~UART_FLOW_CONTROL_HARDWARE) != 0) {\r
-        goto Error;\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // Check if USB I/O Protocol is attached on the controller handle.\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiUsbIoProtocolGuid,\r
-                  (VOID **) &UsbIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (Status == EFI_ALREADY_STARTED) {\r
-    if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {\r
-      return EFI_SUCCESS;\r
-    }\r
-    Status = gBS->OpenProtocolInformation (\r
-                    Controller,\r
-                    &gEfiUsbIoProtocolGuid,\r
-                    &OpenInfoBuffer,\r
-                    &EntryCount\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    for (Index = 0; Index < EntryCount; Index++) {\r
-      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
-        Status = gBS->OpenProtocol (\r
-                        OpenInfoBuffer[Index].ControllerHandle,\r
-                        &gEfiDevicePathProtocolGuid,\r
-                        (VOID **) &DevicePath,\r
-                        This->DriverBindingHandle,\r
-                        Controller,\r
-                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                        );\r
-        if (!EFI_ERROR (Status)) {\r
-          HasFlowControl = ContainsFlowControl (RemainingDevicePath);\r
-          if (HasFlowControl ^ ContainsFlowControl (DevicePath)) {\r
-            Status = EFI_UNSUPPORTED;\r
-          }\r
-        }\r
-        break;\r
-      }\r
-    }\r
-    FreePool (OpenInfoBuffer);\r
-    return Status;\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiUsbIoProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (Status == EFI_ALREADY_STARTED) {\r
-    return EFI_SUCCESS;\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Use the USB I/O Protocol interface to check whether Controller is\r
-  // a USB Serial device that can be managed by this driver.\r
-  //\r
-  Status = EFI_SUCCESS;\r
-\r
-  if (!IsUsbSerial (UsbIo)) {\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Error;\r
-  }\r
-\r
-Error:\r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiDevicePathProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Starts the USB Serial device with this driver.\r
-\r
-  This function produces initializes the USB Serial device and\r
-  produces the Serial IO Protocol.\r
-\r
-  @param  This[in]                   The USB Serial driver binding instance.\r
-  @param  Controller[in]             Handle of device to bind driver to.\r
-  @param  RemainingDevicePath[in]    Optional parameter use to pick a specific\r
-                                     child device to start.\r
-\r
-  @retval EFI_SUCCESS                The controller is controlled by the usb USB\r
-                                     Serial driver.\r
-  @retval EFI_UNSUPPORTED            No interrupt endpoint can be found.\r
-  @retval Other                      This controller cannot be started.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UsbSerialDriverBindingStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-  EFI_USB_IO_PROTOCOL                 *UsbIo;\r
-  USB_SER_DEV                         *UsbSerialDevice;\r
-  UINT8                               EndpointNumber;\r
-  EFI_USB_ENDPOINT_DESCRIPTOR         EndpointDescriptor;\r
-  UINT8                               Index;\r
-  BOOLEAN                             FoundIn;\r
-  BOOLEAN                             FoundOut;\r
-  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;\r
-  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
-  UINTN                               EntryCount;\r
-  EFI_SERIAL_IO_PROTOCOL              *SerialIo;\r
-  UART_DEVICE_PATH                    *Uart;\r
-  UART_FLOW_CONTROL_DEVICE_PATH       *FlowControl;\r
-  UINT32                              Control;\r
-  EFI_DEVICE_PATH_PROTOCOL            *TempDevicePath;\r
-\r
-  UsbSerialDevice = AllocateZeroPool (sizeof (USB_SER_DEV));\r
-  ASSERT (UsbSerialDevice != NULL);\r
-\r
-  //\r
-  // Get the Parent Device path\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
-    goto ErrorExit1;\r
-  }\r
-\r
-  //\r
-  // Open USB I/O Protocol\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiUsbIoProtocolGuid,\r
-                  (VOID **) &UsbIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
-    goto ErrorExit1;\r
-  }\r
-\r
-  if (Status == EFI_ALREADY_STARTED) {\r
-    if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {\r
-      FreePool (UsbSerialDevice);\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-    //\r
-    // Check to see if a child handle exists\r
-    //\r
-    Status = gBS->OpenProtocolInformation (\r
-                    Controller,\r
-                    &gEfiSerialIoProtocolGuid,\r
-                    &OpenInfoBuffer,\r
-                    &EntryCount\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      goto ErrorExit1;\r
-    }\r
-\r
-    Status = EFI_ALREADY_STARTED;\r
-    for (Index = 0; Index < EntryCount; Index++) {\r
-      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
-        Status = gBS->OpenProtocol (\r
-                        OpenInfoBuffer[Index].ControllerHandle,\r
-                        &gEfiSerialIoProtocolGuid,\r
-                        (VOID **) &SerialIo,\r
-                        This->DriverBindingHandle,\r
-                        Controller,\r
-                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                        );\r
-        if (EFI_ERROR (Status)) {\r
-        }\r
-        if (!EFI_ERROR (Status)) {\r
-          Uart = (UART_DEVICE_PATH *) RemainingDevicePath;\r
-          Status = SerialIo->SetAttributes (\r
-                               SerialIo,\r
-                               Uart->BaudRate,\r
-                               SerialIo->Mode->ReceiveFifoDepth,\r
-                               SerialIo->Mode->Timeout,\r
-                               (EFI_PARITY_TYPE) Uart->Parity,\r
-                               Uart->DataBits,\r
-                               (EFI_STOP_BITS_TYPE) Uart->StopBits\r
-                               );\r
-          FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);\r
-          if (!EFI_ERROR (Status) && IsUartFlowControlNode (FlowControl)) {\r
-            Status = SerialIo->GetControl (\r
-                                 SerialIo,\r
-                                 &Control\r
-                                 );\r
-            if (!EFI_ERROR (Status)) {\r
-              if (ReadUnaligned32 (&FlowControl->FlowControlMap) == UART_FLOW_CONTROL_HARDWARE) {\r
-                Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
-              } else {\r
-                Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
-              }\r
-              //\r
-              // Clear bits that are not allowed to be passed to SetControl\r
-              //\r
-              Control &= (EFI_SERIAL_REQUEST_TO_SEND | \r
-                          EFI_SERIAL_DATA_TERMINAL_READY |\r
-                          EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |\r
-                          EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |\r
-                          EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);\r
-              Status = SerialIo->SetControl (SerialIo, Control);\r
-            }\r
-          }\r
-        }\r
-        break;\r
-      }\r
-    }\r
-    FreePool (OpenInfoBuffer);\r
-    return Status;\r
-  }\r
-\r
-  if (RemainingDevicePath != NULL) {\r
-    if (IsDevicePathEnd (RemainingDevicePath)) {\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  UsbSerialDevice->UsbIo = UsbIo;\r
-\r
-  //\r
-  // Get interface & endpoint descriptor\r
-  //\r
-  UsbIo->UsbGetInterfaceDescriptor (\r
-           UsbIo,\r
-           &UsbSerialDevice->InterfaceDescriptor\r
-           );\r
-\r
-  EndpointNumber = UsbSerialDevice->InterfaceDescriptor.NumEndpoints;\r
-\r
-  //\r
-  // Traverse endpoints to find the IN and OUT endpoints that will send and\r
-  // receive data.\r
-  //\r
-  FoundIn = FALSE;\r
-  FoundOut = FALSE;\r
-  for (Index = 0; Index < EndpointNumber; Index++) {\r
-\r
-    Status = UsbIo->UsbGetEndpointDescriptor (\r
-                      UsbIo,\r
-                      Index,\r
-                      &EndpointDescriptor\r
-                      );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    if (EndpointDescriptor.EndpointAddress == FTDI_ENDPOINT_ADDRESS_OUT) {\r
-      //\r
-      // Set the Out endpoint device\r
-      //\r
-      CopyMem (\r
-        &UsbSerialDevice->OutEndpointDescriptor,\r
-        &EndpointDescriptor,\r
-        sizeof(EndpointDescriptor)\r
-        );\r
-      FoundOut = TRUE;\r
-    }\r
-\r
-    if (EndpointDescriptor.EndpointAddress == FTDI_ENDPOINT_ADDRESS_IN) {\r
-      //\r
-      // Set the In endpoint device\r
-      //\r
-      CopyMem (\r
-        &UsbSerialDevice->InEndpointDescriptor,\r
-        &EndpointDescriptor,\r
-        sizeof(EndpointDescriptor)\r
-        );\r
-      FoundIn = TRUE;\r
-    }\r
-  }\r
-\r
-  if (!FoundIn || !FoundOut) {\r
-    //\r
-    // No interrupt endpoint found, then return unsupported.\r
-    //\r
-    Status = EFI_UNSUPPORTED;\r
-    goto ErrorExit;\r
-  }\r
-  //\r
-  // set the initial values of UsbSerialDevice->LastSettings to the default\r
-  // values\r
-  //\r
-  UsbSerialDevice->LastSettings.BaudRate         = 115200;\r
-  UsbSerialDevice->LastSettings.DataBits         = 8;\r
-  UsbSerialDevice->LastSettings.Parity           = NoParity;\r
-  UsbSerialDevice->LastSettings.ReceiveFifoDepth = FTDI_MAX_RECEIVE_FIFO_DEPTH;\r
-  UsbSerialDevice->LastSettings.StopBits         = OneStopBit;\r
-  UsbSerialDevice->LastSettings.Timeout          = FTDI_TIMEOUT;\r
-\r
-  //\r
-  // set the initial values of UsbSerialDevice->ControlValues\r
-  //\r
-  UsbSerialDevice->ControlValues.DtrState            = FALSE;\r
-  UsbSerialDevice->ControlValues.RtsState            = FALSE;\r
-  UsbSerialDevice->ControlValues.HardwareFlowControl = FALSE;\r
-  UsbSerialDevice->ControlValues.HardwareLoopBack    = FALSE;\r
-  UsbSerialDevice->ControlValues.SoftwareLoopBack    = FALSE;\r
-\r
-  //\r
-  // set the values of UsbSerialDevice->UartDevicePath\r
-  //\r
-  UsbSerialDevice->UartDevicePath.Header.Type    = MESSAGING_DEVICE_PATH;\r
-  UsbSerialDevice->UartDevicePath.Header.SubType = MSG_UART_DP;\r
-  UsbSerialDevice->UartDevicePath.Header.Length[0] = (UINT8) (sizeof (UART_DEVICE_PATH));\r
-  UsbSerialDevice->UartDevicePath.Header.Length[1] = (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8);\r
-\r
-  //\r
-  // set the values of UsbSerialDevice->FlowControlDevicePath\r
-  UsbSerialDevice->FlowControlDevicePath.Header.Type = MESSAGING_DEVICE_PATH;\r
-  UsbSerialDevice->FlowControlDevicePath.Header.SubType = MSG_VENDOR_DP;\r
-  UsbSerialDevice->FlowControlDevicePath.Header.Length[0] = (UINT8) (sizeof (UART_FLOW_CONTROL_DEVICE_PATH));\r
-  UsbSerialDevice->FlowControlDevicePath.Header.Length[1] = (UINT8) ((sizeof (UART_FLOW_CONTROL_DEVICE_PATH)) >> 8);\r
-  UsbSerialDevice->FlowControlDevicePath.FlowControlMap = 0;\r
-\r
-  Status = SetAttributesInternal (\r
-             UsbSerialDevice, \r
-             UsbSerialDevice->LastSettings.BaudRate,\r
-             UsbSerialDevice->LastSettings.ReceiveFifoDepth, \r
-             UsbSerialDevice->LastSettings.Timeout,\r
-             UsbSerialDevice->LastSettings.Parity, \r
-             UsbSerialDevice->LastSettings.DataBits,\r
-             UsbSerialDevice->LastSettings.StopBits\r
-             );\r
-\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = SetControlBitsInternal (\r
-             UsbSerialDevice,\r
-             &(UsbSerialDevice->ControlValues)\r
-             );\r
-\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Publish Serial GUID and protocol\r
-  //\r
-\r
-  UsbSerialDevice->Signature              = USB_SER_DEV_SIGNATURE;\r
-  UsbSerialDevice->SerialIo.Reset         = SerialReset;\r
-  UsbSerialDevice->SerialIo.SetControl    = SetControlBits;\r
-  UsbSerialDevice->SerialIo.SetAttributes = SetAttributes;\r
-  UsbSerialDevice->SerialIo.GetControl    = GetControlBits;\r
-  UsbSerialDevice->SerialIo.Read          = ReadSerialIo;\r
-  UsbSerialDevice->SerialIo.Write         = WriteSerialIo;\r
-\r
-  //\r
-  // Set the static Serial IO modes that will display when running\r
-  // "sermode" within the UEFI shell.\r
-  //\r
-\r
-  UsbSerialDevice->SerialIo.Mode->Timeout  = 0;\r
-  UsbSerialDevice->SerialIo.Mode->BaudRate = 115200;\r
-  UsbSerialDevice->SerialIo.Mode->DataBits = 8;\r
-  UsbSerialDevice->SerialIo.Mode->Parity   = 1;\r
-  UsbSerialDevice->SerialIo.Mode->StopBits = 1;\r
-\r
-  UsbSerialDevice->ParentDevicePath = ParentDevicePath;\r
-  UsbSerialDevice->ControllerHandle = NULL;\r
-  FlowControl                       = NULL;\r
-\r
-  //\r
-  // Allocate space for the receive buffer\r
-  //\r
-  UsbSerialDevice->DataBuffer = AllocateZeroPool (SW_FIFO_DEPTH);\r
-\r
-  //\r
-  // Initialize data buffer pointers.\r
-  // Head==Tail = true means buffer is empty.\r
-  //\r
-  UsbSerialDevice->DataBufferHead = 0;\r
-  UsbSerialDevice->DataBufferTail = 0;\r
-\r
-  UsbSerialDevice->ControllerNameTable = NULL;\r
-  AddUnicodeString2 (\r
-    "eng",\r
-    gUsbSerialComponentName.SupportedLanguages,\r
-    &UsbSerialDevice->ControllerNameTable,\r
-    L"FTDI USB Serial Adapter",\r
-    TRUE\r
-    );\r
-  AddUnicodeString2 (\r
-    "en",\r
-    gUsbSerialComponentName2.SupportedLanguages,\r
-    &UsbSerialDevice->ControllerNameTable,\r
-    L"FTDI USB Serial Adapter",\r
-    FALSE\r
-    );\r
-\r
-  Status = SetInitialStatus (UsbSerialDevice);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Create a polling loop to check for input\r
-  //\r
-\r
-  gBS->CreateEvent (\r
-         EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-         TPL_CALLBACK,\r
-         UsbSerialDriverCheckInput,\r
-         UsbSerialDevice,\r
-         &(UsbSerialDevice->PollingLoop)\r
-         );\r
-  //\r
-  // add code to set trigger time based on baud rate\r
-  // setting to 0.5s for now\r
-  //\r
-  gBS->SetTimer (\r
-         UsbSerialDevice->PollingLoop,\r
-         TimerPeriodic,\r
-         EFI_TIMER_PERIOD_MILLISECONDS (500)\r
-         );\r
-\r
-  //\r
-  // Check if the remaining device path is null. If it is not null change the settings\r
-  // of the device to match those on the device path\r
-  //\r
-  if (RemainingDevicePath != NULL) {\r
-    CopyMem (\r
-      &UsbSerialDevice->UartDevicePath,\r
-      RemainingDevicePath,\r
-      sizeof (UART_DEVICE_PATH)\r
-      );\r
-    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);\r
-    if (IsUartFlowControlNode (FlowControl)) {\r
-      UsbSerialDevice->FlowControlDevicePath.FlowControlMap = ReadUnaligned32 (&FlowControl->FlowControlMap);\r
-    } else {\r
-      FlowControl = NULL;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Build the device path by appending the UART node to the parent device path\r
-  //\r
-  UsbSerialDevice->DevicePath = AppendDevicePathNode (\r
-                                  ParentDevicePath,\r
-                                  (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice->UartDevicePath\r
-                                  );\r
-  //\r
-  // Continue building the device path by appending the flow control node\r
-  //\r
-  TempDevicePath = UsbSerialDevice->DevicePath;\r
-  UsbSerialDevice->DevicePath = AppendDevicePathNode (\r
-                                  TempDevicePath,\r
-                                  (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice->FlowControlDevicePath\r
-                                  );\r
-  FreePool (TempDevicePath);\r
-\r
-  if (UsbSerialDevice->DevicePath == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ErrorExit;\r
-  }\r
-\r
-  //\r
-  // Install protocol interfaces for the device\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &UsbSerialDevice->ControllerHandle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  UsbSerialDevice->DevicePath,\r
-                  &gEfiSerialIoProtocolGuid,\r
-                  &UsbSerialDevice->SerialIo,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)){\r
-    goto ErrorExit;\r
-  }\r
-\r
-  //\r
-  // Open for child device\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                 Controller,\r
-                 &gEfiUsbIoProtocolGuid,\r
-                 (VOID **) &UsbIo,\r
-                 This->DriverBindingHandle,\r
-                 UsbSerialDevice->ControllerHandle,\r
-                 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-                 );\r
-\r
-  UsbSerialDevice->Shutdown = FALSE;\r
-\r
-  return EFI_SUCCESS;\r
-\r
-ErrorExit:\r
-  //\r
-  // Error handler\r
-  //\r
-\r
-  Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                  Controller,\r
-                  &gEfiSerialIoProtocolGuid,\r
-                  &UsbSerialDevice->SerialIo,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ErrorExit1;\r
-  }\r
-\r
-  FreePool (UsbSerialDevice->DataBuffer);\r
-  FreePool (UsbSerialDevice);\r
-\r
-  UsbSerialDevice = NULL;\r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiUsbIoProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-\r
-ErrorExit1:\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Stop the USB Serial device handled by this driver.\r
-\r
-  @param  This[in]                   The USB Serial driver binding protocol.\r
-  @param  Controller[in]             The controller to release.\r
-  @param  NumberOfChildren[in]       The number of handles in ChildHandleBuffer.\r
-  @param  ChildHandleBuffer[in]      The array of child handle.\r
-\r
-  @retval EFI_SUCCESS                The device was stopped.\r
-  @retval EFI_UNSUPPORTED            Serial IO Protocol is not installed on\r
-                                     Controller.\r
-  @retval EFI_DEVICE_ERROR           The device could not be stopped due to a\r
-                                     device error.\r
-  @retval Others                     Fail to uninstall protocols attached on the\r
-                                     device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UsbSerialDriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN  EFI_HANDLE                   Controller,\r
-  IN  UINTN                        NumberOfChildren,\r
-  IN  EFI_HANDLE                   *ChildHandleBuffer\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  EFI_SERIAL_IO_PROTOCOL    *SerialIo;\r
-  EFI_USB_IO_PROTOCOL       *UsbIo;\r
-  USB_SER_DEV               *UsbSerialDevice;\r
-  UINTN                     Index;\r
-  BOOLEAN                   AllChildrenStopped;\r
-\r
-  Status = EFI_SUCCESS;\r
-  UsbSerialDevice = NULL;\r
-\r
-  if (NumberOfChildren == 0) {\r
-    //\r
-    // Close the driver\r
-    //\r
-    Status = gBS->CloseProtocol (\r
-                    Controller,\r
-                    &gEfiUsbIoProtocolGuid,\r
-                    This->DriverBindingHandle,\r
-                    Controller\r
-                    );\r
-    Status = gBS->CloseProtocol (\r
-                    Controller,\r
-                    &gEfiDevicePathProtocolGuid,\r
-                    This->DriverBindingHandle,\r
-                    Controller\r
-                    );\r
-    return Status;\r
-  }\r
-\r
-  AllChildrenStopped = TRUE;\r
-\r
-  for (Index = 0; Index < NumberOfChildren ;Index++) {\r
-    Status = gBS->OpenProtocol (\r
-                    ChildHandleBuffer[Index],\r
-                    &gEfiSerialIoProtocolGuid,\r
-                    (VOID **) &SerialIo,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-    if (Status == EFI_SUCCESS) {//!EFI_ERROR (Status)) {\r
-      UsbSerialDevice = USB_SER_DEV_FROM_THIS (SerialIo);\r
-      Status = gBS->CloseProtocol (\r
-                      Controller,\r
-                      &gEfiUsbIoProtocolGuid,\r
-                      This->DriverBindingHandle,\r
-                      ChildHandleBuffer[Index]\r
-                      );\r
-      Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                      ChildHandleBuffer[Index],\r
-                      &gEfiDevicePathProtocolGuid,\r
-                      UsbSerialDevice->DevicePath,\r
-                      &gEfiSerialIoProtocolGuid,\r
-                      &UsbSerialDevice->SerialIo,\r
-                      NULL\r
-                      );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        gBS->OpenProtocol (\r
-               Controller,\r
-               &gEfiUsbIoProtocolGuid,\r
-               (VOID **) &UsbIo,\r
-               This->DriverBindingHandle,\r
-               ChildHandleBuffer[Index],\r
-               EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-               );\r
-      } else {\r
-        if (UsbSerialDevice->DevicePath != NULL) {\r
-          gBS->FreePool (UsbSerialDevice->DevicePath);\r
-        }\r
-        gBS->SetTimer (\r
-               UsbSerialDevice->PollingLoop,\r
-               TimerCancel,\r
-               0\r
-               );\r
-        gBS->CloseEvent (UsbSerialDevice->PollingLoop);\r
-        UsbSerialDevice->Shutdown = TRUE;\r
-        FreeUnicodeStringTable (UsbSerialDevice->ControllerNameTable);\r
-        FreePool (UsbSerialDevice->DataBuffer);\r
-        FreePool (UsbSerialDevice);\r
-      }\r
-    }\r
-    if (EFI_ERROR (Status)) {\r
-      AllChildrenStopped = FALSE;\r
-    }\r
-  }\r
-\r
-  if (!AllChildrenStopped) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// Serial IO Member Functions\r
-//\r
-\r
-/**\r
-  Reset the serial device.\r
-\r
-  @param  This[in]              Protocol instance pointer.\r
-\r
-  @retval EFI_SUCCESS           The device was reset.\r
-  @retval EFI_DEVICE_ERROR      The serial device could not be reset.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SerialReset (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  USB_SER_DEV  *UsbSerialDevice;\r
-\r
-  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);\r
-  Status          = ResetInternal (UsbSerialDevice);\r
-  if (EFI_ERROR (Status)){\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Set the control bits on a serial device.\r
-\r
-  @param  This[in]             Protocol instance pointer.\r
-  @param  Control[in]          Set the bits of Control that are settable.\r
-\r
-  @retval EFI_SUCCESS          The new control bits were set on the serial device.\r
-  @retval EFI_UNSUPPORTED      The serial device does not support this operation.\r
-  @retval EFI_DEVICE_ERROR     The serial device is not functioning correctly.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetControlBits (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  IN UINT32                  Control\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-  USB_SER_DEV   *UsbSerialDevice;\r
-  CONTROL_BITS  ControlBits;\r
-  \r
-  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);\r
-  \r
-  //\r
-  // check for invalid control parameters \r
-  //\r
-  if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND          |\r
-                    EFI_SERIAL_DATA_TERMINAL_READY      |\r
-                    EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |\r
-                    EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |\r
-                    EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0 ) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // check the control parameters and set the correct setting for\r
-  // the paramerts of ControlBits\r
-  // both loopback enables are always set to FALSE\r
-  //\r
-  ControlBits.HardwareLoopBack = FALSE;\r
-  ControlBits.SoftwareLoopBack = FALSE;\r
-  //\r
-  // check for hardware flow control\r
-  //\r
-  if ((Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) == EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {\r
-    ControlBits.HardwareFlowControl = TRUE;\r
-  } else {\r
-    ControlBits.HardwareFlowControl = FALSE;\r
-  }\r
-  //\r
-  // check for DTR enabled\r
-  //\r
-  if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) {\r
-    ControlBits.DtrState = TRUE;\r
-  } else {\r
-    ControlBits.DtrState = FALSE;\r
-  }\r
-  //\r
-  // check for RTS enabled\r
-  //\r
-  if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) {\r
-    ControlBits.RtsState = TRUE;\r
-  } else {\r
-    ControlBits.RtsState = FALSE;\r
-  }\r
-\r
-  //\r
-  // set the control values with a call to SetControlBitsInternal()\r
-  //\r
-  Status = SetControlBitsInternal (UsbSerialDevice, &ControlBits);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  calls SetAttributesInternal() to set the baud rate, receive FIFO depth,\r
-  transmit/receive time out, parity, data buts, and stop bits on a serial\r
-  device.\r
-\r
-  @param  This[in]             Protocol instance pointer.\r
-  @param  BaudRate[in]         The requested baud rate. A BaudRate value of 0\r
-                               will use the device's default interface speed.\r
-  @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the receive\r
-                               side of the serial interface. A ReceiveFifoDepth\r
-                               value of 0 will use the device's default FIFO\r
-                               depth.\r
-  @param  Timeout[in]          The requested time out for a single character in\r
-                               microseconds.This timeout applies to both the\r
-                               transmit and receive side of the interface. A\r
-                               Timeout value of 0 will use the device's default\r
-                               time out value.\r
-  @param  Parity[in]           The type of parity to use on this serial device.\r
-                               A Parity value of DefaultParity will use the\r
-                               device's default parity value.\r
-  @param  DataBits[in]         The number of data bits to use on the serial\r
-                               device. A DataBit vaule of 0 will use the\r
-                               device's default data bit setting.\r
-  @param  StopBits[in]         The number of stop bits to use on this serial\r
-                               device. A StopBits value of DefaultStopBits will\r
-                               use the device's default number of stop bits.\r
-\r
-  @retval EFI_SUCCESS          The attributes were set\r
-  @retval EFI_DEVICE_ERROR     The attributes were not able to be\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetAttributes (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  IN UINT64                  BaudRate,\r
-  IN UINT32                  ReceiveFifoDepth,\r
-  IN UINT32                  Timeout,\r
-  IN EFI_PARITY_TYPE         Parity,\r
-  IN UINT8                   DataBits,\r
-  IN EFI_STOP_BITS_TYPE      StopBits\r
-  )\r
-{\r
-\r
-  EFI_STATUS   Status;\r
-  USB_SER_DEV  *UsbSerialDevice;\r
-\r
-  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);\r
-\r
-  Status = SetAttributesInternal (\r
-             UsbSerialDevice,\r
-             BaudRate,\r
-             ReceiveFifoDepth,\r
-             Timeout,\r
-             Parity,\r
-             DataBits,\r
-             StopBits\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Retrieves the status of the control bits on a serial device.\r
-\r
-  @param  This[in]               Protocol instance pointer.\r
-  @param  Control[out]           A pointer to return the current Control signals\r
-                                 from the serial device.\r
-\r
-  @retval EFI_SUCCESS            The control bits were read from the serial\r
-                                 device.\r
-  @retval EFI_DEVICE_ERROR       The serial device is not functioning correctly.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetControlBits (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  OUT UINT32                 *Control\r
-  )\r
-{\r
-  USB_SER_DEV  *UsbSerialDevice;\r
-  EFI_STATUS   Status;\r
-\r
-  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);\r
-\r
-  *Control        = 0;\r
-\r
-  Status = GetControlBitsInternal (UsbSerialDevice, Control);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Reads data from a serial device.\r
-\r
-  @param  This[in]                   Protocol instance pointer.\r
-  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,\r
-                                     the amount of data returned in Buffer.\r
-  @param  Buffer[out]                The buffer to return the data into.\r
-\r
-  @retval EFI_SUCCESS                The data was read.\r
-  @retval EFI_DEVICE_ERROR           The device reported an error.\r
-  @retval EFI_TIMEOUT                The data write was stopped due to a timeout.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ReadSerialIo (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  IN OUT UINTN               *BufferSize,\r
-  OUT VOID                   *Buffer\r
-  )\r
-{\r
-  UINTN        Index;\r
-  UINTN        RemainingCallerBufferSize;\r
-  USB_SER_DEV  *UsbSerialDevice;\r
-  EFI_STATUS   Status;\r
-\r
-\r
-  if (*BufferSize == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (Buffer == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Status          = EFI_SUCCESS;\r
-  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Clear out any data that we already have in our internal buffer\r
-  //\r
-  for (Index = 0; Index < *BufferSize; Index++) {\r
-    if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Still have characters in the buffer to return\r
-    //\r
-    ((UINT8 *)Buffer)[Index] = UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferHead];\r
-    UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead + 1) % SW_FIFO_DEPTH;\r
-  }\r
-\r
-  //\r
-  // If we haven't filled the caller's buffer using data that we already had on\r
-  // hand We need to generate an additional USB request to try and fill the\r
-  // caller's buffer\r
-  //\r
-  if (Index != *BufferSize) {\r
-    RemainingCallerBufferSize = *BufferSize - Index;\r
-    Status = ReadDataFromUsb (\r
-               UsbSerialDevice,\r
-               &RemainingCallerBufferSize,\r
-               (VOID *)(((CHAR8 *)Buffer) + Index)\r
-               );\r
-    if (!EFI_ERROR (Status)) {\r
-      *BufferSize = RemainingCallerBufferSize + Index;\r
-    } else {\r
-      *BufferSize = Index;\r
-    }\r
-  }\r
-\r
-  if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {\r
-    //\r
-    // Data buffer has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY flag\r
-    //\r
-    UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;\r
-  } else {\r
-    //\r
-    // There is some leftover data, clear EFI_SERIAL_INPUT_BUFFER_EMPTY flag\r
-    //\r
-    UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);\r
-  }\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Writes data to a serial device.\r
-\r
-  @param  This[in]                   Protocol instance pointer.\r
-  @param  BufferSize[in, out]        On input, the size of the Buffer. On output,\r
-                                     the amount of data actually written.\r
-  @param  Buffer[in]                 The buffer of data to write\r
-\r
-  @retval EFI_SUCCESS                The data was written.\r
-  @retval EFI_DEVICE_ERROR           The device reported an error.\r
-  @retval EFI_TIMEOUT                The data write was stopped due to a timeout.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-WriteSerialIo (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  IN OUT UINTN               *BufferSize,\r
-  IN VOID                    *Buffer\r
-  )\r
-{\r
-  EFI_STATUS   Status;\r
-  USB_SER_DEV  *UsbSerialDevice;\r
-  EFI_TPL      Tpl;\r
-\r
-  UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);\r
-\r
-  if (UsbSerialDevice->Shutdown) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Status = UsbSerialDataTransfer (\r
-             UsbSerialDevice,\r
-             EfiUsbDataOut,\r
-             Buffer,\r
-             BufferSize,\r
-             FTDI_TIMEOUT\r
-             );\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-  if (EFI_ERROR (Status)) {\r
-    if (Status == EFI_TIMEOUT){\r
-      return Status;\r
-    } else {\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r