Home | History | Annotate | Download | only in FtdiUsbSerialDxe
      1 /** @file
      2   USB Serial Driver that manages USB to Serial and produces Serial IO Protocol.
      3 
      4 Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
      5 Portions Copyright 2012 Ashley DeSimone
      6 This program and the accompanying materials
      7 are licensed and made available under the terms and conditions of the BSD
      8 License which accompanies this distribution.  The full text of the license may
      9 be found at http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 //
     17 
     18 // Tested with VEND_ID 0x0403, DEVICE_ID 0x6001
     19 //
     20 // Driver starts the device with the following values:
     21 // 115200, No parity, 8 data bits, 1 stop bit, No Flow control
     22 //
     23 
     24 #include "FtdiUsbSerialDriver.h"
     25 
     26 //
     27 // Table of supported devices. This is the device information that this
     28 // driver was developed with. Add other FTDI devices as needed.
     29 //
     30 USB_DEVICE gUSBDeviceList[] = {
     31   {VID_FTDI, DID_FTDI_FT232},
     32   {0,0}
     33 };
     34 
     35 //
     36 // USB Serial Driver Global Variables
     37 //
     38 EFI_DRIVER_BINDING_PROTOCOL  gUsbSerialDriverBinding = {
     39   UsbSerialDriverBindingSupported,
     40   UsbSerialDriverBindingStart,
     41   UsbSerialDriverBindingStop,
     42   0xa,
     43   NULL,
     44   NULL
     45 };
     46 
     47 //
     48 // Table with the nearest power of 2 for the numbers 0-15
     49 //
     50 UINT8 gRoundedPowersOf2[16] = { 0, 2, 2, 4, 4, 4, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16 };
     51 
     52 /**
     53   Check to see if the device path node is the Flow control node
     54 
     55   @param[in] FlowControl    The device path node to be checked
     56 
     57   @retval    TRUE           It is the flow control node
     58   @retval    FALSE          It is not the flow control node
     59 
     60 **/
     61 BOOLEAN
     62 IsUartFlowControlNode (
     63   IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl
     64   )
     65 {
     66   return (BOOLEAN) (
     67            (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&
     68            (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&
     69            (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))
     70            );
     71 }
     72 
     73 /**
     74   Checks the device path to see if it contains flow control.
     75 
     76   @param[in] DevicePath    The device path to be checked
     77 
     78   @retval    TRUE          It contains flow control
     79   @retval    FALSE         It does not contain flow control
     80 
     81 **/
     82 BOOLEAN
     83 ContainsFlowControl (
     84   IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
     85   )
     86 {
     87   while (!IsDevicePathEnd (DevicePath)) {
     88     if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH *) DevicePath)) {
     89       return TRUE;
     90     }
     91     DevicePath = NextDevicePathNode (DevicePath);
     92   }
     93   return FALSE;
     94 }
     95 
     96 /**
     97   Transfer the data between the device and host.
     98 
     99   This function transfers the data between the device and host.
    100   BOT transfer is composed of three phases: Command, Data, and Status.
    101   This is the Data phase.
    102 
    103   @param  UsbBot[in]                     The USB BOT device
    104   @param  DataDir[in]                    The direction of the data
    105   @param  Data[in, out]                  The buffer to hold data
    106   @param  TransLen[in, out]              The expected length of the data
    107   @param  Timeout[in]                    The time to wait the command to complete
    108 
    109   @retval EFI_SUCCESS                    The data is transferred
    110   @retval EFI_SUCCESS                    No data to transfer
    111   @retval EFI_NOT_READY                  The device return NAK to the transfer
    112   @retval Others                         Failed to transfer data
    113 
    114 **/
    115 EFI_STATUS
    116 UsbSerialDataTransfer (
    117   IN USB_SER_DEV             *UsbBot,
    118   IN EFI_USB_DATA_DIRECTION  DataDir,
    119   IN OUT VOID                *Data,
    120   IN OUT UINTN               *TransLen,
    121   IN UINT32                  Timeout
    122   )
    123 {
    124   EFI_USB_ENDPOINT_DESCRIPTOR  *Endpoint;
    125   EFI_STATUS                   Status;
    126   UINT32                       Result;
    127 
    128   //
    129   // If no data to transfer, just return EFI_SUCCESS.
    130   //
    131   if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {
    132     return EFI_SUCCESS;
    133   }
    134 
    135   //
    136   // Select the endpoint then issue the transfer
    137   //
    138   if (DataDir == EfiUsbDataIn) {
    139     Endpoint = &UsbBot->InEndpointDescriptor;
    140   } else {
    141     Endpoint = &UsbBot->OutEndpointDescriptor;
    142   }
    143 
    144   Result = 0;
    145   Status = UsbBot->UsbIo->UsbBulkTransfer (
    146                             UsbBot->UsbIo,
    147                             Endpoint->EndpointAddress,
    148                             Data,
    149                             TransLen,
    150                             Timeout,
    151                             &Result
    152                             );
    153   if (EFI_ERROR (Status)) {
    154     if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {
    155       Status = EFI_NOT_READY;
    156     } else {
    157       UsbBot->Shutdown = TRUE; // Fixes infinite loop in older EFI
    158     }
    159     return Status;
    160   }
    161   return Status;
    162 }
    163 
    164 /**
    165   Sets the status values of the Usb Serial Device.
    166 
    167   @param  UsbSerialDevice[in]  Handle to the Usb Serial Device to set the status
    168                                for
    169   @param  StatusBuffer[in]     Buffer holding the status values
    170 
    171   @retval EFI_SUCCESS          The status values were read and set correctly
    172 
    173 **/
    174 EFI_STATUS
    175 EFIAPI
    176 SetStatusInternal (
    177   IN USB_SER_DEV  *UsbSerialDevice,
    178   IN UINT8        *StatusBuffer
    179   )
    180 {
    181   UINT8  Msr;
    182 
    183   Msr = (StatusBuffer[0] & MSR_MASK);
    184 
    185   //
    186   // set the Status values to disabled
    187   //
    188   UsbSerialDevice->StatusValues.CtsState = FALSE;
    189   UsbSerialDevice->StatusValues.DsrState = FALSE;
    190   UsbSerialDevice->StatusValues.RiState  = FALSE;
    191   UsbSerialDevice->StatusValues.SdState  = FALSE;
    192 
    193   //
    194   // Check the values from the status buffer and set the appropriate status
    195   // values to enabled
    196   //
    197   if ((Msr & CTS_MASK) == CTS_MASK) {
    198     UsbSerialDevice->StatusValues.CtsState = TRUE;
    199   }
    200   if ((Msr & DSR_MASK) == DSR_MASK) {
    201     UsbSerialDevice->StatusValues.DsrState = TRUE;
    202   }
    203   if ((Msr & RI_MASK) == RI_MASK) {
    204     UsbSerialDevice->StatusValues.RiState = TRUE;
    205   }
    206   if ((Msr & SD_MASK) == SD_MASK) {
    207     UsbSerialDevice->StatusValues.SdState = TRUE;
    208   }
    209   return EFI_SUCCESS;
    210 }
    211 
    212 /**
    213   Initiates a read operation on the Usb Serial Device.
    214 
    215   @param  UsbSerialDevice[in]        Handle to the USB device to read
    216   @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
    217                                      the amount of data returned in Buffer.
    218                                      Setting this to zero will initiate a read
    219                                      and store all data returned in the internal
    220                                      buffer.
    221   @param  Buffer [out]               The buffer to return the data into.
    222 
    223   @retval EFI_SUCCESS                The data was read.
    224   @retval EFI_DEVICE_ERROR           The device reported an error.
    225   @retval EFI_TIMEOUT                The data write was stopped due to a timeout.
    226 
    227 **/
    228 EFI_STATUS
    229 EFIAPI
    230 ReadDataFromUsb (
    231   IN USB_SER_DEV  *UsbSerialDevice,
    232   IN OUT UINTN    *BufferSize,
    233   OUT VOID        *Buffer
    234   )
    235 {
    236   EFI_STATUS  Status;
    237   UINTN       ReadBufferSize;
    238   UINT8       *ReadBuffer;
    239   UINTN       Index;
    240   EFI_TPL     Tpl;
    241   UINT8       StatusBuffer[2]; // buffer to store the status bytes
    242 
    243   ReadBufferSize = 512;
    244   ReadBuffer     = &(UsbSerialDevice->ReadBuffer[0]);
    245 
    246   if (UsbSerialDevice->Shutdown) {
    247     return EFI_DEVICE_ERROR;
    248   }
    249 
    250   Tpl = gBS->RaiseTPL (TPL_NOTIFY);
    251 
    252   Status = UsbSerialDataTransfer (
    253              UsbSerialDevice,
    254              EfiUsbDataIn,
    255              ReadBuffer,
    256              &ReadBufferSize,
    257              FTDI_TIMEOUT*2  //Padded because timers won't be exactly aligned
    258              );
    259   if (EFI_ERROR (Status)) {
    260     gBS->RestoreTPL (Tpl);
    261     if (Status == EFI_TIMEOUT) {
    262       return EFI_TIMEOUT;
    263     } else {
    264       return EFI_DEVICE_ERROR;
    265     }
    266   }
    267 
    268   //
    269   // Store the status bytes in the status buffer
    270   //
    271   for (Index = 0; Index < 2; Index++) {//only the first 2 bytes are status bytes
    272     StatusBuffer[Index] = ReadBuffer[Index];
    273   }
    274   //
    275   // update the statusvalue field of the usbserialdevice
    276   //
    277   Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);
    278   if (Status != EFI_SUCCESS) {
    279   }
    280 
    281   //
    282   // Store the read data in the read buffer, start at 2 to ignore status bytes
    283   //
    284   for (Index = 2; Index < ReadBufferSize; Index++) {
    285     if (((UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH) == UsbSerialDevice->DataBufferHead) {
    286       break;
    287     }
    288     if (ReadBuffer[Index] == 0x00) {
    289       //
    290       // This is null, do not add
    291       //
    292     } else {
    293       UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferTail] = ReadBuffer[Index];
    294       UsbSerialDevice->DataBufferTail = (UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH;
    295     }
    296   }
    297 
    298   //
    299   // Read characters out of the buffer to satisfy caller's request.
    300   //
    301   for (Index = 0; Index < *BufferSize; Index++) {
    302     if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
    303       break;
    304     }
    305     //
    306     // Still have characters in the buffer to return
    307     //
    308     ((UINT8 *)Buffer)[Index]        = UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferHead];
    309     UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead + 1) % SW_FIFO_DEPTH;
    310   }
    311   //
    312   // Return actual number of bytes returned.
    313   //
    314   *BufferSize = Index;
    315   gBS->RestoreTPL (Tpl);
    316   return EFI_SUCCESS;
    317 }
    318 
    319 /**
    320   Sets the initial status values of the Usb Serial Device by reading the status
    321   bytes from the device.
    322 
    323   @param  UsbSerialDevice[in]  Handle to the Usb Serial Device that needs its
    324                                initial status values set
    325 
    326   @retval EFI_SUCCESS          The status bytes were read successfully and the
    327                                initial status values were set correctly
    328   @retval EFI_TIMEOUT          The read of the status bytes was stopped due to a
    329                                timeout
    330   @retval EFI_DEVICE_ERROR     The device reported an error during the read of
    331                                the status bytes
    332 
    333 **/
    334 EFI_STATUS
    335 EFIAPI
    336 SetInitialStatus (
    337   IN USB_SER_DEV          *UsbSerialDevice
    338   )
    339 {
    340   EFI_STATUS      Status;
    341   UINTN           BufferSize;
    342   EFI_TPL         Tpl;
    343   UINT8           StatusBuffer[2];
    344 
    345   Status          = EFI_UNSUPPORTED;
    346   BufferSize      = sizeof (StatusBuffer);
    347 
    348   if (UsbSerialDevice->Shutdown) {
    349     return EFI_DEVICE_ERROR;
    350   }
    351 
    352   Tpl = gBS->RaiseTPL (TPL_NOTIFY);
    353 
    354   Status = UsbSerialDataTransfer (
    355              UsbSerialDevice,
    356              EfiUsbDataIn,
    357              StatusBuffer,
    358              &BufferSize,
    359              40    //Slightly more than 2x the FTDI polling frequency to make sure that data will be returned
    360              );
    361 
    362   Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);
    363 
    364   gBS->RestoreTPL (Tpl);
    365 
    366   return Status;
    367 }
    368 
    369 /**
    370   UsbSerialDriverCheckInput.
    371   attempts to read data in from the device periodically, stores any read data
    372   and updates the control attributes.
    373 
    374   @param  Event[in]
    375   @param  Context[in]....The current instance of the USB serial device
    376 
    377 **/
    378 VOID
    379 EFIAPI
    380 UsbSerialDriverCheckInput (
    381   IN  EFI_EVENT  Event,
    382   IN  VOID       *Context
    383   )
    384 {
    385   UINTN        BufferSize;
    386   USB_SER_DEV  *UsbSerialDevice;
    387 
    388   UsbSerialDevice = (USB_SER_DEV*)Context;
    389 
    390   if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
    391     //
    392     // Data buffer is empty, try to read from device
    393     //
    394     BufferSize = 0;
    395     ReadDataFromUsb (UsbSerialDevice, &BufferSize, NULL);
    396     if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
    397       //
    398       // Data buffer still has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY
    399       // flag
    400       //
    401       UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
    402     } else {
    403       //
    404       // Read has returned some data, clear the EFI_SERIAL_INPUT_BUFFER_EMPTY
    405       // flag
    406       //
    407       UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
    408     }
    409   } else {
    410     //
    411     // Data buffer has data, no read attempt required
    412     //
    413     UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
    414   }
    415 }
    416 
    417 /**
    418   Encodes the baud rate into the format expected by the Ftdi device.
    419 
    420   @param  BaudRate[in]                The baudrate to be set on the device
    421   @param  EncodedBaudRate[out]        The baud rate encoded in the format
    422                                       expected by the Ftdi device
    423 
    424   @return EFI_SUCCESS                 Baudrate encoding was calculated
    425                                       successfully
    426   @return EFI_INVALID_PARAMETER       An invalid value of BaudRate was received
    427 
    428 **/
    429 EFI_STATUS
    430 EFIAPI
    431 EncodeBaudRateForFtdi (
    432   IN  UINT64  BaudRate,
    433   OUT UINT16  *EncodedBaudRate
    434   )
    435 {
    436   UINT32 Divisor;
    437   UINT32 AdjustedFrequency;
    438   UINT16 Result;
    439 
    440   //
    441   // Check to make sure we won't get an integer overflow
    442   //
    443   if ((BaudRate < 178) || ( BaudRate > ((FTDI_UART_FREQUENCY * 100) / 97))) {
    444     return EFI_INVALID_PARAMETER;
    445   }
    446 
    447   //
    448   // Baud Rates of 2000000 and 3000000 are special cases
    449   //
    450   if ((BaudRate >= FTDI_SPECIAL_CASE_300_MIN) && (BaudRate <= FTDI_SPECIAL_CASE_300_MAX)) {
    451     *EncodedBaudRate = 0;
    452     return EFI_SUCCESS;
    453   }
    454   if ((BaudRate >= FTDI_SPECIAL_CASE_200_MIN) && (BaudRate <= FTDI_SPECIAL_CASE_200_MAX)) {
    455     *EncodedBaudRate = 1;
    456     return EFI_SUCCESS;
    457   }
    458 
    459   //
    460   // Compute divisor
    461   //
    462   Divisor = (FTDI_UART_FREQUENCY << 4) / (UINT32)BaudRate;
    463 
    464   //
    465   // Round the last 4 bits to the nearest power of 2
    466   //
    467   Divisor = (Divisor & ~(0xF)) + (gRoundedPowersOf2[Divisor & 0xF]);
    468 
    469   //
    470   // Check to make sure computed divisor is within
    471   // the min and max that FTDI controller will accept
    472   //
    473   if (Divisor < FTDI_MIN_DIVISOR) {
    474     Divisor = FTDI_MIN_DIVISOR;
    475   } else if (Divisor > FTDI_MAX_DIVISOR) {
    476     Divisor = FTDI_MAX_DIVISOR;
    477   }
    478 
    479   //
    480   // Check to make sure the frequency that the FTDI chip will need to
    481   // generate to attain the requested Baud Rate is within 3% of the
    482   // 3MHz clock frequency that the FTDI chip runs at.
    483   //
    484   // (3MHz * 1600) / 103 = 46601941
    485   // (3MHz * 1600) / 97  = 49484536
    486   //
    487   AdjustedFrequency = (((UINT32)BaudRate) * Divisor);
    488   if ((AdjustedFrequency < FTDI_MIN_FREQUENCY) || (AdjustedFrequency > FTDI_MAX_FREQUENCY)) {
    489     return EFI_INVALID_PARAMETER;
    490   }
    491 
    492   //
    493   // Encode the Divisor into the format FTDI expects
    494   //
    495   Result = (UINT16)(Divisor >> 4);
    496   if ((Divisor & 0x8) != 0) {
    497     Result |= 0x4000;
    498   } else if ((Divisor & 0x4) != 0) {
    499     Result |= 0x8000;
    500   } else if ((Divisor & 0x2) != 0) {
    501     Result |= 0xC000;
    502   }
    503 
    504   *EncodedBaudRate = Result;
    505   return EFI_SUCCESS;
    506 }
    507 
    508 /**
    509   Uses USB I/O to check whether the device is a USB Serial device.
    510 
    511   @param  UsbIo[in]    Pointer to a USB I/O protocol instance.
    512 
    513   @retval TRUE         Device is a USB Serial device.
    514   @retval FALSE        Device is a not USB Serial device.
    515 
    516 **/
    517 BOOLEAN
    518 IsUsbSerial (
    519   IN  EFI_USB_IO_PROTOCOL  *UsbIo
    520   )
    521 {
    522   EFI_STATUS                 Status;
    523   EFI_USB_DEVICE_DESCRIPTOR  DeviceDescriptor;
    524   CHAR16                     *StrMfg;
    525   BOOLEAN                    Found;
    526   UINT32                     Index;
    527 
    528   //
    529   // Get the default device descriptor
    530   //
    531   Status = UsbIo->UsbGetDeviceDescriptor (
    532                     UsbIo,
    533                     &DeviceDescriptor
    534                     );
    535   if (EFI_ERROR (Status)) {
    536     return FALSE;
    537   }
    538 
    539   Found = FALSE;
    540   Index = 0;
    541   while (gUSBDeviceList[Index].VendorId != 0 &&
    542          gUSBDeviceList[Index].DeviceId != 0 &&
    543          !Found                                  ) {
    544     if (DeviceDescriptor.IdProduct == gUSBDeviceList[Index].DeviceId &&
    545         DeviceDescriptor.IdVendor  == gUSBDeviceList[Index].VendorId      ){
    546         //
    547         // Checks to see if a string descriptor can be pulled from the device in
    548         // the selected language. If not False is returned indicating that this
    549         // is not a Usb Serial Device that can be managegd by this driver
    550         //
    551         StrMfg = NULL;
    552         Status = UsbIo->UsbGetStringDescriptor (
    553                           UsbIo,
    554                           USB_US_LANG_ID, // LANGID selector, should make this
    555                                           // more robust to verify lang support
    556                                           // for device
    557                           DeviceDescriptor.StrManufacturer,
    558                           &StrMfg
    559                           );
    560         if (StrMfg != NULL) {
    561           FreePool (StrMfg);
    562         }
    563         if (EFI_ERROR (Status)) {
    564           return FALSE;
    565         }
    566         return TRUE;
    567     }
    568     Index++;
    569   }
    570   return FALSE;
    571 }
    572 
    573 /**
    574   Internal function that sets the Data Bits, Stop Bits and Parity values on the
    575   Usb Serial Device with a single usb control transfer.
    576 
    577   @param  UsbIo[in]                  Usb Io Protocol instance pointer
    578   @param  DataBits[in]               The data bits value to be set on the Usb
    579                                      Serial Device
    580   @param  Parity[in]                 The parity type that will be set on the Usb
    581                                      Serial Device
    582   @param  StopBits[in]               The stop bits type that will be set on the
    583                                      Usb Serial Device
    584   @param  LastSettings[in]           A pointer to the Usb Serial Device's
    585                                      PREVIOUS_ATTRIBUTES item
    586 
    587   @retval EFI_SUCCESS                The data items were correctly set on the
    588                                      USB Serial Device
    589   @retval EFI_INVALID_PARAMETER      An invalid data parameter or an invalid
    590                                      combination or parameters was used
    591   @retval EFI_DEVICE_ERROR           The device is not functioning correctly and
    592                                      the data values were unable to be set
    593 
    594 **/
    595 EFI_STATUS
    596 EFIAPI
    597 SetDataInternal (
    598   IN EFI_USB_IO_PROTOCOL  *UsbIo,
    599   IN UINT8                DataBits,
    600   IN EFI_PARITY_TYPE      Parity,
    601   IN EFI_STOP_BITS_TYPE   StopBits,
    602   IN PREVIOUS_ATTRIBUTES  *LastSettings
    603   )
    604 {
    605   EFI_STATUS              Status;
    606   EFI_USB_DEVICE_REQUEST  DevReq;
    607   UINT32                  ReturnValue;
    608   UINT8                   ConfigurationValue;
    609 
    610   //
    611   // Since data bits settings of 6,7,8 cannot be set with a stop bits setting of
    612   // 1.5 check to see if this happens when the values of last settings are used
    613   //
    614   if ((DataBits == 0) && (StopBits == OneFiveStopBits)) {
    615     if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) || (LastSettings->DataBits == 8)) {
    616       return EFI_INVALID_PARAMETER;
    617     }
    618   } else if ((StopBits == DefaultStopBits) && ((DataBits == 6) || (DataBits == 7) || (DataBits == 8))) {
    619     if (LastSettings->StopBits == OneFiveStopBits) {
    620       return EFI_INVALID_PARAMETER;
    621     }
    622   } else if ((DataBits == 0) && (StopBits == DefaultStopBits)) {
    623     if (LastSettings->StopBits == OneFiveStopBits) {
    624       if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) || (LastSettings->DataBits == 8)) {
    625         return EFI_INVALID_PARAMETER;
    626       }
    627     }
    628   }
    629 
    630   //
    631   // set the DevReq.Value for the usb control transfer to the correct value
    632   // based on the seleceted number of data bits if there is an invalid number of
    633   // data bits requested return EFI_INVALID_PARAMETER
    634   //
    635   if (((DataBits < 5 ) || (DataBits > 8)) && (DataBits != 0)) {
    636     return EFI_INVALID_PARAMETER;
    637   }
    638   if (DataBits == 0) {
    639     //
    640     // use the value of LastDataBits
    641     //
    642     DevReq.Value = SET_DATA_BITS (LastSettings->DataBits);
    643   } else {
    644     //
    645     // use the value of DataBits
    646     //
    647     DevReq.Value = SET_DATA_BITS (DataBits);
    648   }
    649 
    650   //
    651   // Set Parity
    652   //
    653   if (Parity == DefaultParity) {
    654     Parity = LastSettings->Parity;
    655   }
    656 
    657   if (Parity == NoParity) {
    658     DevReq.Value |= SET_PARITY_NONE;
    659   } else if (Parity == EvenParity) {
    660     DevReq.Value |= SET_PARITY_EVEN;
    661   } else if (Parity == OddParity){
    662     DevReq.Value |= SET_PARITY_ODD;
    663   } else if (Parity == MarkParity) {
    664     DevReq.Value |= SET_PARITY_MARK;
    665   } else if (Parity == SpaceParity) {
    666     DevReq.Value |= SET_PARITY_SPACE;
    667   }
    668 
    669   //
    670   // Set Stop Bits
    671   //
    672   if (StopBits == DefaultStopBits) {
    673     StopBits = LastSettings->StopBits;
    674   }
    675 
    676   if (StopBits == OneStopBit) {
    677     DevReq.Value |= SET_STOP_BITS_1;
    678   } else if (StopBits == OneFiveStopBits) {
    679     DevReq.Value |= SET_STOP_BITS_15;
    680   } else if (StopBits == TwoStopBits) {
    681     DevReq.Value |= SET_STOP_BITS_2;
    682   }
    683 
    684   //
    685   // set the rest of the DevReq parameters and perform the usb control transfer
    686   // to set the data bits on the device
    687   //
    688   DevReq.Request     = FTDI_COMMAND_SET_DATA;
    689   DevReq.RequestType = USB_REQ_TYPE_VENDOR;
    690   DevReq.Index       = FTDI_PORT_IDENTIFIER;
    691   DevReq.Length      = 0; // indicates that there is no data phase in this request
    692 
    693   Status = UsbIo->UsbControlTransfer (
    694                     UsbIo,
    695                     &DevReq,
    696                     EfiUsbDataOut,
    697                     WDR_SHORT_TIMEOUT,
    698                     &ConfigurationValue,
    699                     1,
    700                     &ReturnValue
    701                     );
    702   if (EFI_ERROR (Status)) {
    703     goto StatusError;
    704   }
    705   return Status;
    706 
    707 StatusError:
    708   if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
    709     return EFI_DEVICE_ERROR;
    710   } else {
    711     return Status;
    712   }
    713 }
    714 
    715 /**
    716   Internal function that sets the baudrate on the Usb Serial Device.
    717 
    718   @param  UsbIo[in]                  Usb Io Protocol instance pointer
    719   @param  BaudRate[in]               The baudrate value to be set on the device.
    720                                      If this value is 0 the value of LastBaudRate
    721                                      will be used instead
    722   @param  LastBaudRate[in]           The baud rate value that was previously set
    723                                      on the Usb Serial Device
    724 
    725   @retval EFI_SUCCESS                The baudrate was set succesfully
    726   @retval EFI_INVALID_PARAMETER      An invalid baudrate was used
    727   @retval EFI_DEVICE_ERROR           The device is not functioning correctly and
    728                                      the baudrate was unable to be set
    729 
    730 **/
    731 EFI_STATUS
    732 EFIAPI
    733 SetBaudRateInternal (
    734   IN EFI_USB_IO_PROTOCOL  *UsbIo,
    735   IN UINT64               BaudRate,
    736   IN UINT64               LastBaudRate
    737   )
    738 {
    739   EFI_STATUS              Status;
    740   EFI_USB_DEVICE_REQUEST  DevReq;
    741   UINT32                  ReturnValue;
    742   UINT8                   ConfigurationValue;
    743   UINT16                  EncodedBaudRate;
    744   EFI_TPL                 Tpl;
    745 
    746   Tpl    = gBS->RaiseTPL(TPL_NOTIFY);
    747 
    748   //
    749   // set the value of DevReq.Value based on the value of BaudRate
    750   // if 0 is selected as baud rate use the value of LastBaudRate
    751   //
    752   if (BaudRate == 0) {
    753     Status = EncodeBaudRateForFtdi (LastBaudRate, &EncodedBaudRate);
    754     if (EFI_ERROR (Status)) {
    755       gBS->RestoreTPL (Tpl);
    756       //
    757       // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
    758       // succesfull
    759       //
    760       return Status;
    761     }
    762     DevReq.Value = EncodedBaudRate;
    763   } else {
    764     Status = EncodeBaudRateForFtdi (BaudRate, &EncodedBaudRate);
    765     if (EFI_ERROR (Status)) {
    766       gBS->RestoreTPL (Tpl);
    767       //
    768       // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
    769       // successfull
    770       //
    771       return Status;
    772     }
    773     DevReq.Value = EncodedBaudRate;
    774   }
    775 
    776   //
    777   // set the remaining parameters of DevReq and perform the usb control transfer
    778   // to set the device
    779   //
    780   DevReq.Request     = FTDI_COMMAND_SET_BAUDRATE;
    781   DevReq.RequestType = USB_REQ_TYPE_VENDOR;
    782   DevReq.Index       = FTDI_PORT_IDENTIFIER;
    783   DevReq.Length      = 0; // indicates that there is no data phase in this request
    784 
    785   Status = UsbIo->UsbControlTransfer (
    786                     UsbIo,
    787                     &DevReq,
    788                     EfiUsbDataOut,
    789                     WDR_SHORT_TIMEOUT,
    790                     &ConfigurationValue,
    791                     1,
    792                     &ReturnValue
    793                     );
    794   if (EFI_ERROR (Status)) {
    795     goto StatusError;
    796   }
    797   gBS->RestoreTPL (Tpl);
    798   return Status;
    799 
    800 StatusError:
    801   gBS->RestoreTPL (Tpl);
    802   if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
    803     return EFI_DEVICE_ERROR;
    804   } else {
    805     return Status;
    806   }
    807 }
    808 
    809 /**
    810   Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
    811   data bits, and stop bits on a serial device.
    812 
    813   @param  UsbSerialDevice[in]  Pointer to the current instance of the USB Serial
    814                                Device.
    815   @param  BaudRate[in]         The requested baud rate. A BaudRate value of 0
    816                                will use the device's default interface speed.
    817   @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
    818                                side of the serial interface. A ReceiveFifoDepth
    819                                value of 0 will use the device's default FIFO
    820                                depth.
    821   @param  Timeout[in]          The requested time out for a single character in
    822                                microseconds.This timeout applies to both the
    823                                transmit and receive side of the interface.A
    824                                Timeout value of 0 will use the device's default
    825                                time out value.
    826   @param  Parity[in]           The type of parity to use on this serial device.
    827                                A Parity value of DefaultParity will use the
    828                                device's default parity value.
    829   @param  DataBits[in]         The number of data bits to use on the serial
    830                                device. A DataBits value of 0 will use the
    831                                device's default data bit setting.
    832   @param  StopBits[in]         The number of stop bits to use on this serial
    833                                device. A StopBits value of DefaultStopBits will
    834                                use the device's default number of stop bits.
    835 
    836   @retval EFI_SUCCESS          The attributes were set
    837   @retval EFI_DEVICE_ERROR     The attributes were not able to be set
    838 
    839 **/
    840 EFI_STATUS
    841 EFIAPI
    842 SetAttributesInternal (
    843   IN USB_SER_DEV         *UsbSerialDevice,
    844   IN UINT64              BaudRate,
    845   IN UINT32              ReceiveFifoDepth,
    846   IN UINT32              Timeout,
    847   IN EFI_PARITY_TYPE     Parity,
    848   IN UINT8               DataBits,
    849   IN EFI_STOP_BITS_TYPE  StopBits
    850   )
    851 {
    852   EFI_STATUS                Status;
    853   EFI_TPL                   Tpl;
    854   UART_DEVICE_PATH          *Uart;
    855   EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
    856 
    857   Status = EFI_UNSUPPORTED;
    858   Tpl    = gBS->RaiseTPL(TPL_NOTIFY);
    859   Uart   = NULL;
    860 
    861   //
    862   // check for invalid combinations of parameters
    863   //
    864   if (((DataBits >= 6) && (DataBits <= 8)) && (StopBits == OneFiveStopBits)) {
    865     return  EFI_INVALID_PARAMETER;
    866   }
    867 
    868   //
    869   // set data bits, parity and stop bits
    870   //
    871   Status = SetDataInternal (
    872              UsbSerialDevice->UsbIo,
    873              DataBits,
    874              Parity,
    875              StopBits,
    876              &(UsbSerialDevice->LastSettings)
    877              );
    878   if (EFI_ERROR (Status)) {
    879     goto StatusError;
    880   }
    881   //
    882   // set baudrate
    883   //
    884   Status = SetBaudRateInternal (
    885              UsbSerialDevice->UsbIo,
    886              BaudRate,
    887              UsbSerialDevice->LastSettings.BaudRate
    888              );
    889   if (EFI_ERROR (Status)){
    890     goto StatusError;
    891   }
    892 
    893   //
    894   // update the values of UsbSerialDevice->LastSettings and UsbSerialDevice->SerialIo.Mode
    895   //
    896   if (BaudRate == 0) {
    897     UsbSerialDevice->LastSettings.BaudRate   = UsbSerialDevice->LastSettings.BaudRate;
    898     UsbSerialDevice->SerialIo.Mode->BaudRate = UsbSerialDevice->LastSettings.BaudRate;
    899   } else {
    900     UsbSerialDevice->LastSettings.BaudRate   = BaudRate;
    901     UsbSerialDevice->SerialIo.Mode->BaudRate = BaudRate;
    902   }
    903 
    904   UsbSerialDevice->LastSettings.Timeout          = FTDI_TIMEOUT;
    905   UsbSerialDevice->LastSettings.ReceiveFifoDepth = FTDI_MAX_RECEIVE_FIFO_DEPTH;
    906 
    907   if (Parity == DefaultParity) {
    908     UsbSerialDevice->LastSettings.Parity   = UsbSerialDevice->LastSettings.Parity;
    909     UsbSerialDevice->SerialIo.Mode->Parity = UsbSerialDevice->LastSettings.Parity;
    910   } else {
    911     UsbSerialDevice->LastSettings.Parity   = Parity;
    912     UsbSerialDevice->SerialIo.Mode->Parity = Parity;
    913   }
    914   if (DataBits == 0) {
    915     UsbSerialDevice->LastSettings.DataBits   = UsbSerialDevice->LastSettings.DataBits;
    916     UsbSerialDevice->SerialIo.Mode->DataBits = UsbSerialDevice->LastSettings.DataBits;
    917   } else {
    918     UsbSerialDevice->LastSettings.DataBits   = DataBits;
    919     UsbSerialDevice->SerialIo.Mode->DataBits = DataBits;
    920   }
    921   if (StopBits == DefaultStopBits) {
    922     UsbSerialDevice->LastSettings.StopBits   = UsbSerialDevice->LastSettings.StopBits;
    923     UsbSerialDevice->SerialIo.Mode->StopBits = UsbSerialDevice->LastSettings.StopBits;
    924   } else {
    925     UsbSerialDevice->LastSettings.StopBits   = StopBits;
    926     UsbSerialDevice->SerialIo.Mode->StopBits = StopBits;
    927   }
    928 
    929   //
    930   // See if the device path node has changed
    931   //
    932   if (UsbSerialDevice->UartDevicePath.BaudRate == BaudRate &&
    933       UsbSerialDevice->UartDevicePath.DataBits == DataBits &&
    934       UsbSerialDevice->UartDevicePath.StopBits == StopBits &&
    935       UsbSerialDevice->UartDevicePath.Parity == Parity
    936       ) {
    937     gBS->RestoreTPL (Tpl);
    938     return EFI_SUCCESS;
    939   }
    940 
    941   //
    942   // Update the device path
    943   //
    944   UsbSerialDevice->UartDevicePath.BaudRate = BaudRate;
    945   UsbSerialDevice->UartDevicePath.DataBits = DataBits;
    946   UsbSerialDevice->UartDevicePath.StopBits = (UINT8) StopBits;
    947   UsbSerialDevice->UartDevicePath.Parity   = (UINT8) Parity;
    948 
    949   Status = EFI_SUCCESS;
    950   if (UsbSerialDevice->ControllerHandle != NULL) {
    951     RemainingDevicePath = UsbSerialDevice->DevicePath;
    952     while (!IsDevicePathEnd (RemainingDevicePath)) {
    953       Uart = (UART_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
    954       if (Uart->Header.Type == MESSAGING_DEVICE_PATH &&
    955           Uart->Header.SubType == MSG_UART_DP &&
    956           sizeof (UART_DEVICE_PATH) == DevicePathNodeLength ((EFI_DEVICE_PATH *) Uart)) {
    957         Uart->BaudRate = BaudRate;
    958         Uart->DataBits = DataBits;
    959         Uart->StopBits = (UINT8)StopBits;
    960         Uart->Parity   = (UINT8) Parity;
    961         break;
    962         }
    963         RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
    964     }
    965   }
    966 
    967   gBS->RestoreTPL (Tpl);
    968   return Status;
    969 
    970 StatusError:
    971   gBS->RestoreTPL (Tpl);
    972   if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
    973     return EFI_DEVICE_ERROR;
    974   } else {
    975     return Status;
    976   }
    977 }
    978 
    979 /**
    980   Internal function that performs a Usb Control Transfer to set the flow control
    981   on the Usb Serial Device.
    982 
    983   @param  UsbIo[in]                  Usb Io Protocol instance pointer
    984   @param  FlowControlEnable[in]      Data on the Enable/Disable status of Flow
    985                                      Control on the Usb Serial Device
    986 
    987   @retval EFI_SUCCESS                The flow control was set on the Usb Serial
    988                                      device
    989   @retval EFI_INVALID_PARAMETER      An invalid flow control value was used
    990   @retval EFI_EFI_UNSUPPORTED        The operation is not supported
    991   @retval EFI_DEVICE_ERROR           The device is not functioning correctly
    992 
    993 **/
    994 EFI_STATUS
    995 EFIAPI
    996 SetFlowControlInternal (
    997   IN EFI_USB_IO_PROTOCOL  *UsbIo,
    998   IN BOOLEAN              FlowControlEnable
    999   )
   1000 {
   1001   EFI_STATUS               Status;
   1002   EFI_USB_DEVICE_REQUEST   DevReq;
   1003   UINT32                   ReturnValue;
   1004   UINT8                    ConfigurationValue;
   1005 
   1006   //
   1007   // set DevReq.Value based on the value of FlowControlEnable
   1008   //
   1009   if (!FlowControlEnable) {
   1010     DevReq.Value = NO_FLOW_CTRL;
   1011   }
   1012   if (FlowControlEnable) {
   1013     DevReq.Value = XON_XOFF_CTRL;
   1014   }
   1015   //
   1016   // set the remaining DevReq parameters and perform the usb control transfer to
   1017   // set the flow control on the device
   1018   //
   1019   DevReq.Request      = FTDI_COMMAND_SET_FLOW_CTRL;
   1020   DevReq.RequestType  = USB_REQ_TYPE_VENDOR;
   1021   DevReq.Index        = FTDI_PORT_IDENTIFIER;
   1022   DevReq.Length       = 0; // indicates that this transfer has no data phase
   1023   Status              = UsbIo->UsbControlTransfer (
   1024                                  UsbIo,
   1025                                  &DevReq,
   1026                                  EfiUsbDataOut,
   1027                                  WDR_TIMEOUT,
   1028                                  &ConfigurationValue,
   1029                                  1,
   1030                                  &ReturnValue
   1031                                  );
   1032   if (EFI_ERROR (Status)) {
   1033     goto StatusError;
   1034   }
   1035 
   1036   return Status;
   1037 
   1038 StatusError:
   1039   if ((Status != EFI_INVALID_PARAMETER) ||
   1040       (Status != EFI_DEVICE_ERROR)      ||
   1041       (Status != EFI_UNSUPPORTED)          ) {
   1042     return EFI_DEVICE_ERROR;
   1043   } else {
   1044     return Status;
   1045   }
   1046 }
   1047 
   1048 /**
   1049   Internal function that performs a Usb Control Transfer to set the Dtr value on
   1050   the Usb Serial Device.
   1051 
   1052   @param  UsbIo[in]                  Usb Io Protocol instance pointer
   1053   @param  DtrEnable[in]              Data on the Enable/Disable status of the
   1054                                      Dtr for the Usb Serial Device
   1055 
   1056   @retval EFI_SUCCESS                The Dtr value was set on the Usb Serial
   1057                                      Device
   1058   @retval EFI_INVALID_PARAMETER      An invalid Dtr value was used
   1059   @retval EFI_UNSUPPORTED            The operation is not supported
   1060   @retval EFI_DEVICE_ERROR           The device is not functioning correctly
   1061 
   1062 **/
   1063 EFI_STATUS
   1064 EFIAPI
   1065 SetDtrInternal (
   1066   IN EFI_USB_IO_PROTOCOL  *UsbIo,
   1067   IN BOOLEAN              DtrEnable
   1068   )
   1069 {
   1070   EFI_STATUS              Status;
   1071   EFI_USB_DEVICE_REQUEST  DevReq;
   1072   UINT32                  ReturnValue;
   1073   UINT8                   ConfigurationValue;
   1074 
   1075   //
   1076   // set the value of DevReq.Value based on the value of DtrEnable
   1077   //
   1078   if (!DtrEnable) {
   1079     DevReq.Value = SET_DTR_LOW;
   1080   }
   1081   if (DtrEnable) {
   1082     DevReq.Value = SET_DTR_HIGH;
   1083   }
   1084   //
   1085   // set the remaining attributes of DevReq and perform the usb control transfer
   1086   // to set the device
   1087   //
   1088   DevReq.Request      = FTDI_COMMAND_MODEM_CTRL;
   1089   DevReq.RequestType  = USB_REQ_TYPE_VENDOR;
   1090   DevReq.Index        = FTDI_PORT_IDENTIFIER;
   1091   DevReq.Length       = 0; // indicates that there is no data phase in this transfer
   1092 
   1093   Status = UsbIo->UsbControlTransfer (
   1094                     UsbIo,
   1095                     &DevReq,
   1096                     EfiUsbDataOut,
   1097                     WDR_TIMEOUT,
   1098                     &ConfigurationValue,
   1099                     1,
   1100                     &ReturnValue
   1101                     );
   1102   if (EFI_ERROR (Status)) {
   1103     goto StatusError;
   1104   }
   1105   return Status;
   1106 
   1107 StatusError:
   1108   if ((Status != EFI_INVALID_PARAMETER) ||
   1109       (Status != EFI_DEVICE_ERROR)      ||
   1110       (Status != EFI_UNSUPPORTED)          ) {
   1111     return EFI_DEVICE_ERROR;
   1112   } else {
   1113     return Status;
   1114   }
   1115 }
   1116 
   1117 /**
   1118   Internal function that performs a Usb Control Transfer to set the Dtr value on
   1119   the Usb Serial Device.
   1120 
   1121   @param  UsbIo[in]                  Usb Io Protocol instance pointer
   1122   @param  RtsEnable[in]              Data on the Enable/Disable status of the
   1123                                      Rts for the Usb Serial Device
   1124 
   1125   @retval EFI_SUCCESS                The Rts value was set on the Usb Serial
   1126                                      Device
   1127   @retval EFI_INVALID_PARAMETER      An invalid Rts value was used
   1128   @retval EFI_UNSUPPORTED            The operation is not supported
   1129   @retval EFI_DEVICE_ERROR           The device is not functioning correctly
   1130 
   1131 **/
   1132 EFI_STATUS
   1133 EFIAPI
   1134 SetRtsInternal (
   1135   IN EFI_USB_IO_PROTOCOL  *UsbIo,
   1136   IN BOOLEAN              RtsEnable
   1137   )
   1138 {
   1139   EFI_STATUS              Status;
   1140   EFI_USB_DEVICE_REQUEST  DevReq;
   1141   UINT32                  ReturnValue;
   1142   UINT8                   ConfigurationValue;
   1143 
   1144   //
   1145   // set DevReq.Value based on the value of RtsEnable
   1146   //
   1147   if (!RtsEnable) {
   1148     DevReq.Value = SET_RTS_LOW;
   1149   }
   1150   if (RtsEnable) {
   1151     DevReq.Value = SET_RTS_HIGH;
   1152   }
   1153 
   1154   //
   1155   // set the remaining parameters of DevReq and perform the usb control transfer
   1156   // to set the values on the device
   1157   //
   1158   DevReq.Request     = FTDI_COMMAND_MODEM_CTRL;
   1159   DevReq.RequestType = USB_REQ_TYPE_VENDOR;
   1160   DevReq.Index       = FTDI_PORT_IDENTIFIER;
   1161   DevReq.Length      = 0; // indicates that there is no data phase in this request
   1162 
   1163   Status = UsbIo->UsbControlTransfer (
   1164                     UsbIo,
   1165                     &DevReq,
   1166                     EfiUsbDataOut,
   1167                     WDR_TIMEOUT,
   1168                     &ConfigurationValue,
   1169                     1,
   1170                     &ReturnValue
   1171                     );
   1172   if (EFI_ERROR (Status)) {
   1173     goto StatusError;
   1174   }
   1175 
   1176   return Status;
   1177 
   1178 StatusError:
   1179   if ((Status != EFI_INVALID_PARAMETER) ||
   1180       (Status != EFI_DEVICE_ERROR)      ||
   1181       (Status != EFI_UNSUPPORTED)          ) {
   1182     return EFI_DEVICE_ERROR;
   1183   } else {
   1184     return Status;
   1185   }
   1186 }
   1187 
   1188 /**
   1189   Internal function that checks for valid control values and sets the control
   1190   bits on the Usb Serial Device.
   1191 
   1192   @param  UsbSerialDevice[in]        Handle to the Usb Serial Device whose
   1193                                      control bits are being set
   1194   @param  Control[in]                The control value passed to the function
   1195                                      that contains the values of the control
   1196                                      bits that are being set
   1197 
   1198   @retval EFI_SUCCESS                The control bits were set on the Usb Serial
   1199                                      Device
   1200   @retval EFI_INVALID_PARAMETER      An invalid control value was encountered
   1201   @retval EFI_EFI_UNSUPPORTED        The operation is not supported
   1202   @retval EFI_DEVICE_ERROR           The device is not functioning correctly
   1203 
   1204 **/
   1205 EFI_STATUS
   1206 EFIAPI
   1207 SetControlBitsInternal (
   1208   IN USB_SER_DEV   *UsbSerialDevice,
   1209   IN CONTROL_BITS  *Control
   1210   )
   1211 {
   1212   EFI_STATUS                    Status;
   1213   UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;
   1214   EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath;
   1215 
   1216   //
   1217   // check for invalid control parameters hardware and software loopback enabled
   1218   // must always be set to FALSE
   1219   //
   1220   Control->HardwareLoopBack = FALSE;
   1221   Control->SoftwareLoopBack = FALSE;
   1222 
   1223   //
   1224   // set hardware flow control
   1225   //
   1226   Status  = SetFlowControlInternal (
   1227               UsbSerialDevice->UsbIo,
   1228               Control->HardwareFlowControl
   1229               );
   1230   if (EFI_ERROR (Status)) {
   1231     goto StatusError;
   1232   }
   1233 
   1234   //
   1235   // set Dtr state
   1236   //
   1237   Status = SetDtrInternal (UsbSerialDevice->UsbIo, Control->DtrState);
   1238   if (EFI_ERROR (Status)) {
   1239     goto StatusError;
   1240   }
   1241 
   1242   //
   1243   // set Rts state
   1244   //
   1245   Status = SetRtsInternal (UsbSerialDevice->UsbIo, Control->RtsState);
   1246   if (EFI_ERROR (Status)){
   1247     goto StatusError;
   1248   }
   1249 
   1250   //
   1251   // update the remaining control values for UsbSerialDevice->ControlValues
   1252   //
   1253   UsbSerialDevice->ControlValues.DtrState            = Control->DtrState;
   1254   UsbSerialDevice->ControlValues.RtsState            = Control->RtsState;
   1255   UsbSerialDevice->ControlValues.HardwareFlowControl = Control->HardwareFlowControl;
   1256   UsbSerialDevice->ControlValues.HardwareLoopBack    = FALSE;
   1257   UsbSerialDevice->ControlValues.SoftwareLoopBack    = FALSE;
   1258 
   1259   Status = EFI_SUCCESS;
   1260   //
   1261   // Update the device path to have the correct flow control values
   1262   //
   1263   if (UsbSerialDevice->ControllerHandle != NULL) {
   1264     RemainingDevicePath = UsbSerialDevice->DevicePath;
   1265     while (!IsDevicePathEnd (RemainingDevicePath)) {
   1266       FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
   1267       if (FlowControl->Header.Type == MESSAGING_DEVICE_PATH &&
   1268           FlowControl->Header.SubType == MSG_VENDOR_DP &&
   1269           sizeof (UART_FLOW_CONTROL_DEVICE_PATH) == DevicePathNodeLength ((EFI_DEVICE_PATH *) FlowControl)){
   1270         if (UsbSerialDevice->ControlValues.HardwareFlowControl == TRUE) {
   1271           FlowControl->FlowControlMap = UART_FLOW_CONTROL_HARDWARE;
   1272         } else if (UsbSerialDevice->ControlValues.HardwareFlowControl == FALSE) {
   1273           FlowControl->FlowControlMap = 0;
   1274         }
   1275         break;
   1276       }
   1277       RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
   1278     }
   1279   }
   1280 
   1281   return Status;
   1282 
   1283 StatusError:
   1284   if ((Status != EFI_INVALID_PARAMETER) ||
   1285       (Status != EFI_DEVICE_ERROR)      ||
   1286       (Status != EFI_UNSUPPORTED)          ) {
   1287     return EFI_DEVICE_ERROR;
   1288   } else {
   1289     return Status;
   1290   }
   1291 }
   1292 
   1293 /**
   1294   Internal function that calculates the Control value used by GetControlBits()
   1295   based on the status and control values of the Usb Serial Device.
   1296 
   1297   @param  UsbSerialDevice[in]        Handle to the Usb Serial Devie whose status
   1298                                      and control values are being used to set
   1299                                      Control
   1300   @param  Control[out]               On output the formated value of Control
   1301                                      that has been calculated based on the
   1302                                      control and status values of the Usb Serial
   1303                                      Device
   1304 
   1305   @retval EFI_SUCCESS                The value of Control was successfully
   1306                                      calculated
   1307 
   1308 **/
   1309 EFI_STATUS
   1310 EFIAPI
   1311 GetControlBitsInternal (
   1312   IN USB_SER_DEV  *UsbSerialDevice,
   1313   OUT UINT32      *Control
   1314   )
   1315 {
   1316   *Control = 0;
   1317 
   1318   //
   1319   // Check the values of UsbSerialDevice->Status Values and modify control
   1320   // accordingly these values correspond to the modem status register
   1321   //
   1322   if (UsbSerialDevice->StatusValues.CtsState) {
   1323     *Control |= EFI_SERIAL_CLEAR_TO_SEND;
   1324   }
   1325   if (UsbSerialDevice->StatusValues.DsrState) {
   1326     *Control |= EFI_SERIAL_DATA_SET_READY;
   1327   }
   1328   if (UsbSerialDevice->StatusValues.RiState) {
   1329     *Control |= EFI_SERIAL_RING_INDICATE;
   1330   }
   1331   if (UsbSerialDevice->StatusValues.SdState) {
   1332     *Control |= EFI_SERIAL_CARRIER_DETECT;
   1333   }
   1334 
   1335   //
   1336   // check the values of UsbSerialDevice->ControlValues and modify control
   1337   // accordingly these values correspond to the values of the Modem Control
   1338   // Register
   1339   //
   1340   if (UsbSerialDevice->ControlValues.DtrState) {
   1341     *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
   1342   }
   1343   if (UsbSerialDevice->ControlValues.RtsState) {
   1344     *Control |= EFI_SERIAL_REQUEST_TO_SEND;
   1345   }
   1346   if (UsbSerialDevice->ControlValues.HardwareLoopBack) {
   1347     *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;
   1348   }
   1349   if (UsbSerialDevice->ControlValues.HardwareFlowControl) {
   1350     *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
   1351   }
   1352   //
   1353   // check if the buffer is empty since only one is being used if it is empty
   1354   // set both the receive and transmit buffers to empty
   1355   //
   1356   if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
   1357     *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
   1358     *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
   1359   }
   1360   //
   1361   // check for software loopback enable in UsbSerialDevice->ControlValues
   1362   //
   1363   if (UsbSerialDevice->ControlValues.SoftwareLoopBack) {
   1364     *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;
   1365   }
   1366 
   1367   return EFI_SUCCESS;
   1368 }
   1369 
   1370 /**
   1371   Resets the USB Serial Device
   1372 
   1373   This function is the internal method for reseting the device and is called by
   1374   SerialReset()
   1375 
   1376   @param  UsbSerialDevice[in]  A pointer to the USB Serial device
   1377 
   1378   @retval EFI_SUCCESS          The device was reset
   1379   @retval EFI_DEVICE_ERROR     The device could not be reset
   1380 
   1381 **/
   1382 EFI_STATUS
   1383 EFIAPI
   1384 ResetInternal (
   1385   IN USB_SER_DEV  *UsbSerialDevice
   1386   )
   1387 {
   1388   EFI_STATUS              Status;
   1389   EFI_USB_DEVICE_REQUEST  DevReq;
   1390   UINT8                   ConfigurationValue;
   1391   UINT32                  ReturnValue;
   1392 
   1393   DevReq.Request     = FTDI_COMMAND_RESET_PORT;
   1394   DevReq.RequestType = USB_REQ_TYPE_VENDOR;
   1395   DevReq.Value       = RESET_PORT_PURGE_RX;
   1396   DevReq.Index       = FTDI_PORT_IDENTIFIER;
   1397   DevReq.Length      = 0; //indicates that there is not data phase in this request
   1398 
   1399   Status = UsbSerialDevice->UsbIo->UsbControlTransfer (
   1400                                      UsbSerialDevice->UsbIo,
   1401                                      &DevReq,
   1402                                      EfiUsbDataIn,
   1403                                      WDR_TIMEOUT,
   1404                                      &ConfigurationValue,
   1405                                      1,
   1406                                      &ReturnValue
   1407                                      );
   1408   if (EFI_ERROR (Status)) {
   1409     return EFI_DEVICE_ERROR;
   1410   }
   1411 
   1412   DevReq.Request     = FTDI_COMMAND_RESET_PORT;
   1413   DevReq.RequestType = USB_REQ_TYPE_VENDOR;
   1414   DevReq.Value       = RESET_PORT_PURGE_TX;
   1415   DevReq.Index       = FTDI_PORT_IDENTIFIER;
   1416   DevReq.Length      = 0; //indicates that there is no data phase in this request
   1417 
   1418   Status = UsbSerialDevice->UsbIo->UsbControlTransfer (
   1419                                      UsbSerialDevice->UsbIo,
   1420                                      &DevReq,
   1421                                      EfiUsbDataIn,
   1422                                      WDR_TIMEOUT,
   1423                                      &ConfigurationValue,
   1424                                      1,
   1425                                      &ReturnValue
   1426                                      );
   1427   if (EFI_ERROR (Status)) {
   1428     return EFI_DEVICE_ERROR;
   1429   }
   1430   return Status;
   1431 }
   1432 
   1433 /**
   1434   Entrypoint of USB Serial Driver.
   1435 
   1436   This function is the entrypoint of USB Serial Driver. It installs
   1437   Driver Binding Protocols together with Component Name Protocols.
   1438 
   1439   @param  ImageHandle[in]       The firmware allocated handle for the EFI image.
   1440   @param  SystemTable[in]       A pointer to the EFI System Table.
   1441 
   1442   @retval EFI_SUCCESS           The entry point is executed successfully.
   1443 
   1444 **/
   1445 EFI_STATUS
   1446 EFIAPI
   1447 FtdiUsbSerialEntryPoint (
   1448   IN EFI_HANDLE        ImageHandle,
   1449   IN EFI_SYSTEM_TABLE  *SystemTable
   1450   )
   1451 {
   1452   EFI_STATUS  Status;
   1453 
   1454   Status = EfiLibInstallDriverBindingComponentName2 (
   1455              ImageHandle,
   1456              SystemTable,
   1457              &gUsbSerialDriverBinding,
   1458              ImageHandle,
   1459              &gUsbSerialComponentName,
   1460              &gUsbSerialComponentName2
   1461              );
   1462   ASSERT_EFI_ERROR (Status);
   1463   return EFI_SUCCESS;
   1464 }
   1465 
   1466 /**
   1467   Unload function for the Usb Serial Driver.
   1468 
   1469   @param  ImageHandle[in]    The allocated handle for the EFI image
   1470 
   1471   @retval EFI_SUCCESS        The driver was unloaded successfully
   1472 **/
   1473 EFI_STATUS
   1474 EFIAPI
   1475 FtdiUsbSerialUnload (
   1476   IN EFI_HANDLE  ImageHandle
   1477   )
   1478 {
   1479   EFI_STATUS  Status;
   1480   EFI_HANDLE  *HandleBuffer;
   1481   UINTN       HandleCount;
   1482   UINTN       Index;
   1483 
   1484   //
   1485   // Retrieve all handles in the handle database
   1486   //
   1487   Status = gBS->LocateHandleBuffer (
   1488                   AllHandles,
   1489                   NULL,
   1490                   NULL,
   1491                   &HandleCount,
   1492                   &HandleBuffer
   1493                   );
   1494   if (EFI_ERROR (Status)) {
   1495     return Status;
   1496   }
   1497 
   1498   //
   1499   // Disconnect the driver from the handles in the handle database
   1500   //
   1501   for (Index = 0; Index < HandleCount; Index++) {
   1502     Status = gBS->DisconnectController (
   1503                     HandleBuffer[Index],
   1504                     gImageHandle,
   1505                     NULL
   1506                     );
   1507   }
   1508 
   1509   //
   1510   // Free the handle array
   1511   //
   1512   FreePool (HandleBuffer);
   1513 
   1514   //
   1515   // Uninstall protocols installed by the driver in its entrypoint
   1516   //
   1517   Status = gBS->UninstallMultipleProtocolInterfaces (
   1518                   ImageHandle,
   1519                   &gEfiDriverBindingProtocolGuid,
   1520                   &gUsbSerialDriverBinding,
   1521                   &gEfiComponentNameProtocolGuid,
   1522                   &gUsbSerialComponentName,
   1523                   &gEfiComponentName2ProtocolGuid,
   1524                   &gUsbSerialComponentName2,
   1525                   NULL
   1526                   );
   1527   if (EFI_ERROR (Status)) {
   1528     return Status;
   1529   }
   1530 
   1531   return EFI_SUCCESS;
   1532 }
   1533 
   1534 /**
   1535   Check whether USB Serial driver supports this device.
   1536 
   1537   @param  This[in]                   The USB Serial driver binding protocol.
   1538   @param  Controller[in]             The controller handle to check.
   1539   @param  RemainingDevicePath[in]    The remaining device path.
   1540 
   1541   @retval EFI_SUCCESS                The driver supports this controller.
   1542   @retval other                      This device isn't supported.
   1543 
   1544 **/
   1545 EFI_STATUS
   1546 EFIAPI
   1547 UsbSerialDriverBindingSupported (
   1548   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
   1549   IN EFI_HANDLE                   Controller,
   1550   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
   1551   )
   1552 {
   1553   EFI_STATUS           Status;
   1554   EFI_USB_IO_PROTOCOL  *UsbIo;
   1555   UART_DEVICE_PATH     *UartNode;
   1556   UART_FLOW_CONTROL_DEVICE_PATH        *FlowControlNode;
   1557   UINTN                                Index;
   1558   UINTN                                EntryCount;
   1559   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY  *OpenInfoBuffer;
   1560   BOOLEAN                              HasFlowControl;
   1561   EFI_DEVICE_PATH_PROTOCOL             *DevicePath;
   1562   EFI_DEVICE_PATH_PROTOCOL             *ParentDevicePath;
   1563 
   1564   if (RemainingDevicePath != NULL) {
   1565     if (!IsDevicePathEnd (RemainingDevicePath)) {
   1566       Status = EFI_UNSUPPORTED;
   1567       UartNode = (UART_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
   1568       if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||
   1569           UartNode->Header.SubType != MSG_UART_DP ||
   1570           sizeof (UART_DEVICE_PATH) != DevicePathNodeLength ((EFI_DEVICE_PATH *) UartNode)) {
   1571         goto Error;
   1572       }
   1573       FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (UartNode);
   1574       if ((ReadUnaligned32 (&FlowControlNode->FlowControlMap) & ~UART_FLOW_CONTROL_HARDWARE) != 0) {
   1575         goto Error;
   1576       }
   1577     }
   1578   }
   1579 
   1580   //
   1581   // Check if USB I/O Protocol is attached on the controller handle.
   1582   //
   1583   Status = gBS->OpenProtocol (
   1584                   Controller,
   1585                   &gEfiUsbIoProtocolGuid,
   1586                   (VOID **) &UsbIo,
   1587                   This->DriverBindingHandle,
   1588                   Controller,
   1589                   EFI_OPEN_PROTOCOL_BY_DRIVER
   1590                   );
   1591   if (Status == EFI_ALREADY_STARTED) {
   1592     if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {
   1593       return EFI_SUCCESS;
   1594     }
   1595     Status = gBS->OpenProtocolInformation (
   1596                     Controller,
   1597                     &gEfiUsbIoProtocolGuid,
   1598                     &OpenInfoBuffer,
   1599                     &EntryCount
   1600                     );
   1601     if (EFI_ERROR (Status)) {
   1602       return Status;
   1603     }
   1604     for (Index = 0; Index < EntryCount; Index++) {
   1605       if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
   1606         Status = gBS->OpenProtocol (
   1607                         OpenInfoBuffer[Index].ControllerHandle,
   1608                         &gEfiDevicePathProtocolGuid,
   1609                         (VOID **) &DevicePath,
   1610                         This->DriverBindingHandle,
   1611                         Controller,
   1612                         EFI_OPEN_PROTOCOL_GET_PROTOCOL
   1613                         );
   1614         if (!EFI_ERROR (Status)) {
   1615           HasFlowControl = ContainsFlowControl (RemainingDevicePath);
   1616           if (HasFlowControl ^ ContainsFlowControl (DevicePath)) {
   1617             Status = EFI_UNSUPPORTED;
   1618           }
   1619         }
   1620         break;
   1621       }
   1622     }
   1623     FreePool (OpenInfoBuffer);
   1624     return Status;
   1625   }
   1626 
   1627   if (EFI_ERROR (Status)) {
   1628     return Status;
   1629   }
   1630 
   1631   gBS->CloseProtocol (
   1632          Controller,
   1633          &gEfiUsbIoProtocolGuid,
   1634          This->DriverBindingHandle,
   1635          Controller
   1636          );
   1637 
   1638   Status = gBS->OpenProtocol (
   1639                   Controller,
   1640                   &gEfiDevicePathProtocolGuid,
   1641                   (VOID **) &ParentDevicePath,
   1642                   This->DriverBindingHandle,
   1643                   Controller,
   1644                   EFI_OPEN_PROTOCOL_BY_DRIVER
   1645                   );
   1646   if (Status == EFI_ALREADY_STARTED) {
   1647     return EFI_SUCCESS;
   1648   }
   1649   if (EFI_ERROR (Status)) {
   1650     return Status;
   1651   }
   1652 
   1653   //
   1654   // Use the USB I/O Protocol interface to check whether Controller is
   1655   // a USB Serial device that can be managed by this driver.
   1656   //
   1657   Status = EFI_SUCCESS;
   1658 
   1659   if (!IsUsbSerial (UsbIo)) {
   1660     Status = EFI_UNSUPPORTED;
   1661     goto Error;
   1662   }
   1663 
   1664 Error:
   1665   gBS->CloseProtocol (
   1666          Controller,
   1667          &gEfiDevicePathProtocolGuid,
   1668          This->DriverBindingHandle,
   1669          Controller
   1670          );
   1671   return Status;
   1672 }
   1673 
   1674 /**
   1675   Starts the USB Serial device with this driver.
   1676 
   1677   This function produces initializes the USB Serial device and
   1678   produces the Serial IO Protocol.
   1679 
   1680   @param  This[in]                   The USB Serial driver binding instance.
   1681   @param  Controller[in]             Handle of device to bind driver to.
   1682   @param  RemainingDevicePath[in]    Optional parameter use to pick a specific
   1683                                      child device to start.
   1684 
   1685   @retval EFI_SUCCESS                The controller is controlled by the usb USB
   1686                                      Serial driver.
   1687   @retval EFI_UNSUPPORTED            No interrupt endpoint can be found.
   1688   @retval Other                      This controller cannot be started.
   1689 
   1690 **/
   1691 EFI_STATUS
   1692 EFIAPI
   1693 UsbSerialDriverBindingStart (
   1694   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
   1695   IN EFI_HANDLE                   Controller,
   1696   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
   1697   )
   1698 {
   1699   EFI_STATUS                          Status;
   1700   EFI_USB_IO_PROTOCOL                 *UsbIo;
   1701   USB_SER_DEV                         *UsbSerialDevice;
   1702   UINT8                               EndpointNumber;
   1703   EFI_USB_ENDPOINT_DESCRIPTOR         EndpointDescriptor;
   1704   UINT8                               Index;
   1705   BOOLEAN                             FoundIn;
   1706   BOOLEAN                             FoundOut;
   1707   EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
   1708   EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
   1709   UINTN                               EntryCount;
   1710   EFI_SERIAL_IO_PROTOCOL              *SerialIo;
   1711   UART_DEVICE_PATH                    *Uart;
   1712   UART_FLOW_CONTROL_DEVICE_PATH       *FlowControl;
   1713   UINT32                              FlowControlMap;
   1714   UINT32                              Control;
   1715   EFI_DEVICE_PATH_PROTOCOL            *TempDevicePath;
   1716 
   1717   UsbSerialDevice = AllocateZeroPool (sizeof (USB_SER_DEV));
   1718   ASSERT (UsbSerialDevice != NULL);
   1719 
   1720   //
   1721   // Get the Parent Device path
   1722   //
   1723   Status = gBS->OpenProtocol (
   1724                   Controller,
   1725                   &gEfiDevicePathProtocolGuid,
   1726                   (VOID **) &ParentDevicePath,
   1727                   This->DriverBindingHandle,
   1728                   Controller,
   1729                   EFI_OPEN_PROTOCOL_BY_DRIVER
   1730                   );
   1731   if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
   1732     goto ErrorExit1;
   1733   }
   1734 
   1735   //
   1736   // Open USB I/O Protocol
   1737   //
   1738   Status = gBS->OpenProtocol (
   1739                   Controller,
   1740                   &gEfiUsbIoProtocolGuid,
   1741                   (VOID **) &UsbIo,
   1742                   This->DriverBindingHandle,
   1743                   Controller,
   1744                   EFI_OPEN_PROTOCOL_BY_DRIVER
   1745                   );
   1746   if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
   1747     goto ErrorExit1;
   1748   }
   1749 
   1750   if (Status == EFI_ALREADY_STARTED) {
   1751     if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {
   1752       FreePool (UsbSerialDevice);
   1753       return EFI_SUCCESS;
   1754     }
   1755 
   1756     //
   1757     // Check to see if a child handle exists
   1758     //
   1759     Status = gBS->OpenProtocolInformation (
   1760                     Controller,
   1761                     &gEfiSerialIoProtocolGuid,
   1762                     &OpenInfoBuffer,
   1763                     &EntryCount
   1764                     );
   1765     if (EFI_ERROR (Status)) {
   1766       goto ErrorExit1;
   1767     }
   1768 
   1769     Status = EFI_ALREADY_STARTED;
   1770     for (Index = 0; Index < EntryCount; Index++) {
   1771       if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
   1772         Status = gBS->OpenProtocol (
   1773                         OpenInfoBuffer[Index].ControllerHandle,
   1774                         &gEfiSerialIoProtocolGuid,
   1775                         (VOID **) &SerialIo,
   1776                         This->DriverBindingHandle,
   1777                         Controller,
   1778                         EFI_OPEN_PROTOCOL_GET_PROTOCOL
   1779                         );
   1780         if (EFI_ERROR (Status)) {
   1781         }
   1782         if (!EFI_ERROR (Status)) {
   1783           Uart = (UART_DEVICE_PATH *) RemainingDevicePath;
   1784           Status = SerialIo->SetAttributes (
   1785                                SerialIo,
   1786                                Uart->BaudRate,
   1787                                SerialIo->Mode->ReceiveFifoDepth,
   1788                                SerialIo->Mode->Timeout,
   1789                                (EFI_PARITY_TYPE) Uart->Parity,
   1790                                Uart->DataBits,
   1791                                (EFI_STOP_BITS_TYPE) Uart->StopBits
   1792                                );
   1793           FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
   1794           if (!EFI_ERROR (Status) && IsUartFlowControlNode (FlowControl)) {
   1795             Status = SerialIo->GetControl (
   1796                                  SerialIo,
   1797                                  &Control
   1798                                  );
   1799             if (!EFI_ERROR (Status)) {
   1800               if (ReadUnaligned32 (&FlowControl->FlowControlMap) == UART_FLOW_CONTROL_HARDWARE) {
   1801                 Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
   1802               } else {
   1803                 Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
   1804               }
   1805               //
   1806               // Clear bits that are not allowed to be passed to SetControl
   1807               //
   1808               Control &= (EFI_SERIAL_REQUEST_TO_SEND |
   1809                           EFI_SERIAL_DATA_TERMINAL_READY |
   1810                           EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |
   1811                           EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
   1812                           EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);
   1813               Status = SerialIo->SetControl (SerialIo, Control);
   1814             }
   1815           }
   1816         }
   1817         break;
   1818       }
   1819     }
   1820     FreePool (OpenInfoBuffer);
   1821     return Status;
   1822   }
   1823 
   1824   if (RemainingDevicePath != NULL) {
   1825     if (IsDevicePathEnd (RemainingDevicePath)) {
   1826       return EFI_SUCCESS;
   1827     }
   1828   }
   1829 
   1830   UsbSerialDevice->UsbIo = UsbIo;
   1831 
   1832   //
   1833   // Get interface & endpoint descriptor
   1834   //
   1835   UsbIo->UsbGetInterfaceDescriptor (
   1836            UsbIo,
   1837            &UsbSerialDevice->InterfaceDescriptor
   1838            );
   1839 
   1840   EndpointNumber = UsbSerialDevice->InterfaceDescriptor.NumEndpoints;
   1841 
   1842   //
   1843   // Traverse endpoints to find the IN and OUT endpoints that will send and
   1844   // receive data.
   1845   //
   1846   FoundIn = FALSE;
   1847   FoundOut = FALSE;
   1848   for (Index = 0; Index < EndpointNumber; Index++) {
   1849 
   1850     Status = UsbIo->UsbGetEndpointDescriptor (
   1851                       UsbIo,
   1852                       Index,
   1853                       &EndpointDescriptor
   1854                       );
   1855     if (EFI_ERROR (Status)) {
   1856       return Status;
   1857     }
   1858 
   1859     if (EndpointDescriptor.EndpointAddress == FTDI_ENDPOINT_ADDRESS_OUT) {
   1860       //
   1861       // Set the Out endpoint device
   1862       //
   1863       CopyMem (
   1864         &UsbSerialDevice->OutEndpointDescriptor,
   1865         &EndpointDescriptor,
   1866         sizeof(EndpointDescriptor)
   1867         );
   1868       FoundOut = TRUE;
   1869     }
   1870 
   1871     if (EndpointDescriptor.EndpointAddress == FTDI_ENDPOINT_ADDRESS_IN) {
   1872       //
   1873       // Set the In endpoint device
   1874       //
   1875       CopyMem (
   1876         &UsbSerialDevice->InEndpointDescriptor,
   1877         &EndpointDescriptor,
   1878         sizeof(EndpointDescriptor)
   1879         );
   1880       FoundIn = TRUE;
   1881     }
   1882   }
   1883 
   1884   if (!FoundIn || !FoundOut) {
   1885     //
   1886     // No interrupt endpoint found, then return unsupported.
   1887     //
   1888     Status = EFI_UNSUPPORTED;
   1889     goto ErrorExit;
   1890   }
   1891   //
   1892   // set the initial values of UsbSerialDevice->LastSettings to the default
   1893   // values
   1894   //
   1895   UsbSerialDevice->LastSettings.BaudRate         = 115200;
   1896   UsbSerialDevice->LastSettings.DataBits         = 8;
   1897   UsbSerialDevice->LastSettings.Parity           = NoParity;
   1898   UsbSerialDevice->LastSettings.ReceiveFifoDepth = FTDI_MAX_RECEIVE_FIFO_DEPTH;
   1899   UsbSerialDevice->LastSettings.StopBits         = OneStopBit;
   1900   UsbSerialDevice->LastSettings.Timeout          = FTDI_TIMEOUT;
   1901 
   1902   //
   1903   // set the initial values of UsbSerialDevice->ControlValues
   1904   //
   1905   UsbSerialDevice->ControlValues.DtrState            = FALSE;
   1906   UsbSerialDevice->ControlValues.RtsState            = FALSE;
   1907   UsbSerialDevice->ControlValues.HardwareFlowControl = FALSE;
   1908   UsbSerialDevice->ControlValues.HardwareLoopBack    = FALSE;
   1909   UsbSerialDevice->ControlValues.SoftwareLoopBack    = FALSE;
   1910 
   1911   //
   1912   // set the values of UsbSerialDevice->UartDevicePath
   1913   //
   1914   UsbSerialDevice->UartDevicePath.Header.Type    = MESSAGING_DEVICE_PATH;
   1915   UsbSerialDevice->UartDevicePath.Header.SubType = MSG_UART_DP;
   1916   UsbSerialDevice->UartDevicePath.Header.Length[0] = (UINT8) (sizeof (UART_DEVICE_PATH));
   1917   UsbSerialDevice->UartDevicePath.Header.Length[1] = (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8);
   1918 
   1919   //
   1920   // set the values of UsbSerialDevice->FlowControlDevicePath
   1921   UsbSerialDevice->FlowControlDevicePath.Header.Type = MESSAGING_DEVICE_PATH;
   1922   UsbSerialDevice->FlowControlDevicePath.Header.SubType = MSG_VENDOR_DP;
   1923   UsbSerialDevice->FlowControlDevicePath.Header.Length[0] = (UINT8) (sizeof (UART_FLOW_CONTROL_DEVICE_PATH));
   1924   UsbSerialDevice->FlowControlDevicePath.Header.Length[1] = (UINT8) ((sizeof (UART_FLOW_CONTROL_DEVICE_PATH)) >> 8);
   1925   UsbSerialDevice->FlowControlDevicePath.FlowControlMap = 0;
   1926 
   1927   Status = SetAttributesInternal (
   1928              UsbSerialDevice,
   1929              UsbSerialDevice->LastSettings.BaudRate,
   1930              UsbSerialDevice->LastSettings.ReceiveFifoDepth,
   1931              UsbSerialDevice->LastSettings.Timeout,
   1932              UsbSerialDevice->LastSettings.Parity,
   1933              UsbSerialDevice->LastSettings.DataBits,
   1934              UsbSerialDevice->LastSettings.StopBits
   1935              );
   1936 
   1937   ASSERT_EFI_ERROR (Status);
   1938 
   1939   Status = SetControlBitsInternal (
   1940              UsbSerialDevice,
   1941              &(UsbSerialDevice->ControlValues)
   1942              );
   1943 
   1944   ASSERT_EFI_ERROR (Status);
   1945 
   1946   //
   1947   // Publish Serial GUID and protocol
   1948   //
   1949 
   1950   UsbSerialDevice->Signature              = USB_SER_DEV_SIGNATURE;
   1951   UsbSerialDevice->SerialIo.Reset         = SerialReset;
   1952   UsbSerialDevice->SerialIo.SetControl    = SetControlBits;
   1953   UsbSerialDevice->SerialIo.SetAttributes = SetAttributes;
   1954   UsbSerialDevice->SerialIo.GetControl    = GetControlBits;
   1955   UsbSerialDevice->SerialIo.Read          = ReadSerialIo;
   1956   UsbSerialDevice->SerialIo.Write         = WriteSerialIo;
   1957 
   1958   //
   1959   // Set the static Serial IO modes that will display when running
   1960   // "sermode" within the UEFI shell.
   1961   //
   1962 
   1963   UsbSerialDevice->SerialIo.Mode->Timeout  = 0;
   1964   UsbSerialDevice->SerialIo.Mode->BaudRate = 115200;
   1965   UsbSerialDevice->SerialIo.Mode->DataBits = 8;
   1966   UsbSerialDevice->SerialIo.Mode->Parity   = 1;
   1967   UsbSerialDevice->SerialIo.Mode->StopBits = 1;
   1968 
   1969   UsbSerialDevice->ParentDevicePath = ParentDevicePath;
   1970   UsbSerialDevice->ControllerHandle = NULL;
   1971   FlowControl                       = NULL;
   1972   FlowControlMap                    = 0;
   1973 
   1974   //
   1975   // Allocate space for the receive buffer
   1976   //
   1977   UsbSerialDevice->DataBuffer = AllocateZeroPool (SW_FIFO_DEPTH);
   1978 
   1979   //
   1980   // Initialize data buffer pointers.
   1981   // Head==Tail = true means buffer is empty.
   1982   //
   1983   UsbSerialDevice->DataBufferHead = 0;
   1984   UsbSerialDevice->DataBufferTail = 0;
   1985 
   1986   UsbSerialDevice->ControllerNameTable = NULL;
   1987   AddUnicodeString2 (
   1988     "eng",
   1989     gUsbSerialComponentName.SupportedLanguages,
   1990     &UsbSerialDevice->ControllerNameTable,
   1991     L"FTDI USB Serial Adapter",
   1992     TRUE
   1993     );
   1994   AddUnicodeString2 (
   1995     "en",
   1996     gUsbSerialComponentName2.SupportedLanguages,
   1997     &UsbSerialDevice->ControllerNameTable,
   1998     L"FTDI USB Serial Adapter",
   1999     FALSE
   2000     );
   2001 
   2002   Status = SetInitialStatus (UsbSerialDevice);
   2003   ASSERT_EFI_ERROR (Status);
   2004 
   2005   //
   2006   // Create a polling loop to check for input
   2007   //
   2008 
   2009   gBS->CreateEvent (
   2010          EVT_TIMER | EVT_NOTIFY_SIGNAL,
   2011          TPL_CALLBACK,
   2012          UsbSerialDriverCheckInput,
   2013          UsbSerialDevice,
   2014          &(UsbSerialDevice->PollingLoop)
   2015          );
   2016   //
   2017   // add code to set trigger time based on baud rate
   2018   // setting to 0.5s for now
   2019   //
   2020   gBS->SetTimer (
   2021          UsbSerialDevice->PollingLoop,
   2022          TimerPeriodic,
   2023          EFI_TIMER_PERIOD_MILLISECONDS (500)
   2024          );
   2025 
   2026   //
   2027   // Check if the remaining device path is null. If it is not null change the settings
   2028   // of the device to match those on the device path
   2029   //
   2030   if (RemainingDevicePath != NULL) {
   2031     CopyMem (
   2032       &UsbSerialDevice->UartDevicePath,
   2033       RemainingDevicePath,
   2034       sizeof (UART_DEVICE_PATH)
   2035       );
   2036     FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
   2037     if (IsUartFlowControlNode (FlowControl)) {
   2038       UsbSerialDevice->FlowControlDevicePath.FlowControlMap = ReadUnaligned32 (&FlowControl->FlowControlMap);
   2039     } else {
   2040       FlowControl = NULL;
   2041     }
   2042   }
   2043 
   2044   //
   2045   // Build the device path by appending the UART node to the parent device path
   2046   //
   2047   UsbSerialDevice->DevicePath = AppendDevicePathNode (
   2048                                   ParentDevicePath,
   2049                                   (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice->UartDevicePath
   2050                                   );
   2051   //
   2052   // Continue building the device path by appending the flow control node
   2053   //
   2054   TempDevicePath = UsbSerialDevice->DevicePath;
   2055   UsbSerialDevice->DevicePath = AppendDevicePathNode (
   2056                                   TempDevicePath,
   2057                                   (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice->FlowControlDevicePath
   2058                                   );
   2059   FreePool (TempDevicePath);
   2060 
   2061   if (UsbSerialDevice->DevicePath == NULL) {
   2062     Status = EFI_OUT_OF_RESOURCES;
   2063     goto ErrorExit;
   2064   }
   2065 
   2066   //
   2067   // Install protocol interfaces for the device
   2068   //
   2069   Status = gBS->InstallMultipleProtocolInterfaces (
   2070                   &UsbSerialDevice->ControllerHandle,
   2071                   &gEfiDevicePathProtocolGuid,
   2072                   UsbSerialDevice->DevicePath,
   2073                   &gEfiSerialIoProtocolGuid,
   2074                   &UsbSerialDevice->SerialIo,
   2075                   NULL
   2076                   );
   2077   if (EFI_ERROR (Status)){
   2078     goto ErrorExit;
   2079   }
   2080 
   2081   //
   2082   // Open for child device
   2083   //
   2084   Status = gBS->OpenProtocol (
   2085                  Controller,
   2086                  &gEfiUsbIoProtocolGuid,
   2087                  (VOID **) &UsbIo,
   2088                  This->DriverBindingHandle,
   2089                  UsbSerialDevice->ControllerHandle,
   2090                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
   2091                  );
   2092 
   2093   UsbSerialDevice->Shutdown = FALSE;
   2094 
   2095   return EFI_SUCCESS;
   2096 
   2097 ErrorExit:
   2098   //
   2099   // Error handler
   2100   //
   2101 
   2102   Status = gBS->UninstallMultipleProtocolInterfaces (
   2103                   Controller,
   2104                   &gEfiSerialIoProtocolGuid,
   2105                   &UsbSerialDevice->SerialIo,
   2106                   NULL
   2107                   );
   2108   if (EFI_ERROR (Status)) {
   2109     goto ErrorExit1;
   2110   }
   2111 
   2112   FreePool (UsbSerialDevice->DataBuffer);
   2113   FreePool (UsbSerialDevice);
   2114 
   2115   UsbSerialDevice = NULL;
   2116   gBS->CloseProtocol (
   2117          Controller,
   2118          &gEfiUsbIoProtocolGuid,
   2119          This->DriverBindingHandle,
   2120          Controller
   2121          );
   2122 
   2123 ErrorExit1:
   2124   return Status;
   2125 }
   2126 
   2127 /**
   2128   Stop the USB Serial device handled by this driver.
   2129 
   2130   @param  This[in]                   The USB Serial driver binding protocol.
   2131   @param  Controller[in]             The controller to release.
   2132   @param  NumberOfChildren[in]       The number of handles in ChildHandleBuffer.
   2133   @param  ChildHandleBuffer[in]      The array of child handle.
   2134 
   2135   @retval EFI_SUCCESS                The device was stopped.
   2136   @retval EFI_UNSUPPORTED            Serial IO Protocol is not installed on
   2137                                      Controller.
   2138   @retval EFI_DEVICE_ERROR           The device could not be stopped due to a
   2139                                      device error.
   2140   @retval Others                     Fail to uninstall protocols attached on the
   2141                                      device.
   2142 
   2143 **/
   2144 EFI_STATUS
   2145 EFIAPI
   2146 UsbSerialDriverBindingStop (
   2147   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
   2148   IN  EFI_HANDLE                   Controller,
   2149   IN  UINTN                        NumberOfChildren,
   2150   IN  EFI_HANDLE                   *ChildHandleBuffer
   2151   )
   2152 {
   2153   EFI_STATUS                Status;
   2154   EFI_SERIAL_IO_PROTOCOL    *SerialIo;
   2155   EFI_USB_IO_PROTOCOL       *UsbIo;
   2156   USB_SER_DEV               *UsbSerialDevice;
   2157   UINTN                     Index;
   2158   BOOLEAN                   AllChildrenStopped;
   2159 
   2160   Status = EFI_SUCCESS;
   2161   UsbSerialDevice = NULL;
   2162 
   2163   if (NumberOfChildren == 0) {
   2164     //
   2165     // Close the driver
   2166     //
   2167     Status = gBS->CloseProtocol (
   2168                     Controller,
   2169                     &gEfiUsbIoProtocolGuid,
   2170                     This->DriverBindingHandle,
   2171                     Controller
   2172                     );
   2173     Status = gBS->CloseProtocol (
   2174                     Controller,
   2175                     &gEfiDevicePathProtocolGuid,
   2176                     This->DriverBindingHandle,
   2177                     Controller
   2178                     );
   2179     return Status;
   2180   }
   2181 
   2182   AllChildrenStopped = TRUE;
   2183 
   2184   for (Index = 0; Index < NumberOfChildren ;Index++) {
   2185     Status = gBS->OpenProtocol (
   2186                     ChildHandleBuffer[Index],
   2187                     &gEfiSerialIoProtocolGuid,
   2188                     (VOID **) &SerialIo,
   2189                     This->DriverBindingHandle,
   2190                     Controller,
   2191                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
   2192                     );
   2193     if (Status == EFI_SUCCESS) {//!EFI_ERROR (Status)) {
   2194       UsbSerialDevice = USB_SER_DEV_FROM_THIS (SerialIo);
   2195       Status = gBS->CloseProtocol (
   2196                       Controller,
   2197                       &gEfiUsbIoProtocolGuid,
   2198                       This->DriverBindingHandle,
   2199                       ChildHandleBuffer[Index]
   2200                       );
   2201       Status = gBS->UninstallMultipleProtocolInterfaces (
   2202                       ChildHandleBuffer[Index],
   2203                       &gEfiDevicePathProtocolGuid,
   2204                       UsbSerialDevice->DevicePath,
   2205                       &gEfiSerialIoProtocolGuid,
   2206                       &UsbSerialDevice->SerialIo,
   2207                       NULL
   2208                       );
   2209 
   2210       if (EFI_ERROR (Status)) {
   2211         gBS->OpenProtocol (
   2212                Controller,
   2213                &gEfiUsbIoProtocolGuid,
   2214                (VOID **) &UsbIo,
   2215                This->DriverBindingHandle,
   2216                ChildHandleBuffer[Index],
   2217                EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
   2218                );
   2219       } else {
   2220         if (UsbSerialDevice->DevicePath != NULL) {
   2221           gBS->FreePool (UsbSerialDevice->DevicePath);
   2222         }
   2223         gBS->SetTimer (
   2224                UsbSerialDevice->PollingLoop,
   2225                TimerCancel,
   2226                0
   2227                );
   2228         gBS->CloseEvent (UsbSerialDevice->PollingLoop);
   2229         UsbSerialDevice->Shutdown = TRUE;
   2230         FreeUnicodeStringTable (UsbSerialDevice->ControllerNameTable);
   2231         FreePool (UsbSerialDevice->DataBuffer);
   2232         FreePool (UsbSerialDevice);
   2233       }
   2234     }
   2235     if (EFI_ERROR (Status)) {
   2236       AllChildrenStopped = FALSE;
   2237     }
   2238   }
   2239 
   2240   if (!AllChildrenStopped) {
   2241     return EFI_DEVICE_ERROR;
   2242   }
   2243   return EFI_SUCCESS;
   2244 }
   2245 
   2246 //
   2247 // Serial IO Member Functions
   2248 //
   2249 
   2250 /**
   2251   Reset the serial device.
   2252 
   2253   @param  This[in]              Protocol instance pointer.
   2254 
   2255   @retval EFI_SUCCESS           The device was reset.
   2256   @retval EFI_DEVICE_ERROR      The serial device could not be reset.
   2257 
   2258 **/
   2259 EFI_STATUS
   2260 EFIAPI
   2261 SerialReset (
   2262   IN EFI_SERIAL_IO_PROTOCOL  *This
   2263   )
   2264 {
   2265   EFI_STATUS    Status;
   2266   USB_SER_DEV  *UsbSerialDevice;
   2267 
   2268   UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
   2269   Status          = ResetInternal (UsbSerialDevice);
   2270   if (EFI_ERROR (Status)){
   2271     return EFI_DEVICE_ERROR;
   2272   }
   2273   return Status;
   2274 }
   2275 
   2276 /**
   2277   Set the control bits on a serial device.
   2278 
   2279   @param  This[in]             Protocol instance pointer.
   2280   @param  Control[in]          Set the bits of Control that are settable.
   2281 
   2282   @retval EFI_SUCCESS          The new control bits were set on the serial device.
   2283   @retval EFI_UNSUPPORTED      The serial device does not support this operation.
   2284   @retval EFI_DEVICE_ERROR     The serial device is not functioning correctly.
   2285 
   2286 **/
   2287 EFI_STATUS
   2288 EFIAPI
   2289 SetControlBits (
   2290   IN EFI_SERIAL_IO_PROTOCOL  *This,
   2291   IN UINT32                  Control
   2292   )
   2293 {
   2294   EFI_STATUS    Status;
   2295   USB_SER_DEV   *UsbSerialDevice;
   2296   CONTROL_BITS  ControlBits;
   2297 
   2298   UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
   2299 
   2300   //
   2301   // check for invalid control parameters
   2302   //
   2303   if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND          |
   2304                     EFI_SERIAL_DATA_TERMINAL_READY      |
   2305                     EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |
   2306                     EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
   2307                     EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0 ) {
   2308     return EFI_UNSUPPORTED;
   2309   }
   2310 
   2311   //
   2312   // check the control parameters and set the correct setting for
   2313   // the paramerts of ControlBits
   2314   // both loopback enables are always set to FALSE
   2315   //
   2316   ControlBits.HardwareLoopBack = FALSE;
   2317   ControlBits.SoftwareLoopBack = FALSE;
   2318   //
   2319   // check for hardware flow control
   2320   //
   2321   if ((Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) == EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {
   2322     ControlBits.HardwareFlowControl = TRUE;
   2323   } else {
   2324     ControlBits.HardwareFlowControl = FALSE;
   2325   }
   2326   //
   2327   // check for DTR enabled
   2328   //
   2329   if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) {
   2330     ControlBits.DtrState = TRUE;
   2331   } else {
   2332     ControlBits.DtrState = FALSE;
   2333   }
   2334   //
   2335   // check for RTS enabled
   2336   //
   2337   if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) {
   2338     ControlBits.RtsState = TRUE;
   2339   } else {
   2340     ControlBits.RtsState = FALSE;
   2341   }
   2342 
   2343   //
   2344   // set the control values with a call to SetControlBitsInternal()
   2345   //
   2346   Status = SetControlBitsInternal (UsbSerialDevice, &ControlBits);
   2347 
   2348   return Status;
   2349 }
   2350 
   2351 /**
   2352   calls SetAttributesInternal() to set the baud rate, receive FIFO depth,
   2353   transmit/receive time out, parity, data buts, and stop bits on a serial
   2354   device.
   2355 
   2356   @param  This[in]             Protocol instance pointer.
   2357   @param  BaudRate[in]         The requested baud rate. A BaudRate value of 0
   2358                                will use the device's default interface speed.
   2359   @param  ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
   2360                                side of the serial interface. A ReceiveFifoDepth
   2361                                value of 0 will use the device's default FIFO
   2362                                depth.
   2363   @param  Timeout[in]          The requested time out for a single character in
   2364                                microseconds.This timeout applies to both the
   2365                                transmit and receive side of the interface. A
   2366                                Timeout value of 0 will use the device's default
   2367                                time out value.
   2368   @param  Parity[in]           The type of parity to use on this serial device.
   2369                                A Parity value of DefaultParity will use the
   2370                                device's default parity value.
   2371   @param  DataBits[in]         The number of data bits to use on the serial
   2372                                device. A DataBit vaule of 0 will use the
   2373                                device's default data bit setting.
   2374   @param  StopBits[in]         The number of stop bits to use on this serial
   2375                                device. A StopBits value of DefaultStopBits will
   2376                                use the device's default number of stop bits.
   2377 
   2378   @retval EFI_SUCCESS          The attributes were set
   2379   @retval EFI_DEVICE_ERROR     The attributes were not able to be
   2380 
   2381 **/
   2382 EFI_STATUS
   2383 EFIAPI
   2384 SetAttributes (
   2385   IN EFI_SERIAL_IO_PROTOCOL  *This,
   2386   IN UINT64                  BaudRate,
   2387   IN UINT32                  ReceiveFifoDepth,
   2388   IN UINT32                  Timeout,
   2389   IN EFI_PARITY_TYPE         Parity,
   2390   IN UINT8                   DataBits,
   2391   IN EFI_STOP_BITS_TYPE      StopBits
   2392   )
   2393 {
   2394 
   2395   EFI_STATUS   Status;
   2396   USB_SER_DEV  *UsbSerialDevice;
   2397 
   2398   UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
   2399 
   2400   Status = SetAttributesInternal (
   2401              UsbSerialDevice,
   2402              BaudRate,
   2403              ReceiveFifoDepth,
   2404              Timeout,
   2405              Parity,
   2406              DataBits,
   2407              StopBits
   2408              );
   2409   if (EFI_ERROR (Status)) {
   2410     return Status;
   2411   }
   2412 
   2413   return Status;
   2414 }
   2415 
   2416 
   2417 /**
   2418   Retrieves the status of the control bits on a serial device.
   2419 
   2420   @param  This[in]               Protocol instance pointer.
   2421   @param  Control[out]           A pointer to return the current Control signals
   2422                                  from the serial device.
   2423 
   2424   @retval EFI_SUCCESS            The control bits were read from the serial
   2425                                  device.
   2426   @retval EFI_DEVICE_ERROR       The serial device is not functioning correctly.
   2427 
   2428 **/
   2429 EFI_STATUS
   2430 EFIAPI
   2431 GetControlBits (
   2432   IN EFI_SERIAL_IO_PROTOCOL  *This,
   2433   OUT UINT32                 *Control
   2434   )
   2435 {
   2436   USB_SER_DEV  *UsbSerialDevice;
   2437   EFI_STATUS   Status;
   2438 
   2439   UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
   2440 
   2441   *Control        = 0;
   2442 
   2443   Status = GetControlBitsInternal (UsbSerialDevice, Control);
   2444 
   2445   if (EFI_ERROR (Status)) {
   2446     return EFI_DEVICE_ERROR;
   2447   }
   2448   return Status;
   2449 }
   2450 
   2451 /**
   2452   Reads data from a serial device.
   2453 
   2454   @param  This[in]                   Protocol instance pointer.
   2455   @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
   2456                                      the amount of data returned in Buffer.
   2457   @param  Buffer[out]                The buffer to return the data into.
   2458 
   2459   @retval EFI_SUCCESS                The data was read.
   2460   @retval EFI_DEVICE_ERROR           The device reported an error.
   2461   @retval EFI_TIMEOUT                The data write was stopped due to a timeout.
   2462 
   2463 **/
   2464 EFI_STATUS
   2465 EFIAPI
   2466 ReadSerialIo (
   2467   IN EFI_SERIAL_IO_PROTOCOL  *This,
   2468   IN OUT UINTN               *BufferSize,
   2469   OUT VOID                   *Buffer
   2470   )
   2471 {
   2472   UINTN        Index;
   2473   UINTN        RemainingCallerBufferSize;
   2474   USB_SER_DEV  *UsbSerialDevice;
   2475   EFI_STATUS   Status;
   2476 
   2477 
   2478   if (*BufferSize == 0) {
   2479     return EFI_SUCCESS;
   2480   }
   2481 
   2482   if (Buffer == NULL) {
   2483     return EFI_DEVICE_ERROR;
   2484   }
   2485 
   2486   Status          = EFI_SUCCESS;
   2487   UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
   2488 
   2489   //
   2490   // Clear out any data that we already have in our internal buffer
   2491   //
   2492   for (Index = 0; Index < *BufferSize; Index++) {
   2493     if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
   2494       break;
   2495     }
   2496 
   2497     //
   2498     // Still have characters in the buffer to return
   2499     //
   2500     ((UINT8 *)Buffer)[Index] = UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferHead];
   2501     UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead + 1) % SW_FIFO_DEPTH;
   2502   }
   2503 
   2504   //
   2505   // If we haven't filled the caller's buffer using data that we already had on
   2506   // hand We need to generate an additional USB request to try and fill the
   2507   // caller's buffer
   2508   //
   2509   if (Index != *BufferSize) {
   2510     RemainingCallerBufferSize = *BufferSize - Index;
   2511     Status = ReadDataFromUsb (
   2512                UsbSerialDevice,
   2513                &RemainingCallerBufferSize,
   2514                (VOID *)(((CHAR8 *)Buffer) + Index)
   2515                );
   2516     if (!EFI_ERROR (Status)) {
   2517       *BufferSize = RemainingCallerBufferSize + Index;
   2518     } else {
   2519       *BufferSize = Index;
   2520     }
   2521   }
   2522 
   2523   if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
   2524     //
   2525     // Data buffer has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY flag
   2526     //
   2527     UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
   2528   } else {
   2529     //
   2530     // There is some leftover data, clear EFI_SERIAL_INPUT_BUFFER_EMPTY flag
   2531     //
   2532     UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
   2533   }
   2534   return Status;
   2535 }
   2536 
   2537 /**
   2538   Writes data to a serial device.
   2539 
   2540   @param  This[in]                   Protocol instance pointer.
   2541   @param  BufferSize[in, out]        On input, the size of the Buffer. On output,
   2542                                      the amount of data actually written.
   2543   @param  Buffer[in]                 The buffer of data to write
   2544 
   2545   @retval EFI_SUCCESS                The data was written.
   2546   @retval EFI_DEVICE_ERROR           The device reported an error.
   2547   @retval EFI_TIMEOUT                The data write was stopped due to a timeout.
   2548 
   2549 **/
   2550 EFI_STATUS
   2551 EFIAPI
   2552 WriteSerialIo (
   2553   IN EFI_SERIAL_IO_PROTOCOL  *This,
   2554   IN OUT UINTN               *BufferSize,
   2555   IN VOID                    *Buffer
   2556   )
   2557 {
   2558   EFI_STATUS   Status;
   2559   USB_SER_DEV  *UsbSerialDevice;
   2560   EFI_TPL      Tpl;
   2561 
   2562   UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
   2563 
   2564   if (UsbSerialDevice->Shutdown) {
   2565     return EFI_DEVICE_ERROR;
   2566   }
   2567 
   2568   Tpl = gBS->RaiseTPL (TPL_NOTIFY);
   2569 
   2570   Status = UsbSerialDataTransfer (
   2571              UsbSerialDevice,
   2572              EfiUsbDataOut,
   2573              Buffer,
   2574              BufferSize,
   2575              FTDI_TIMEOUT
   2576              );
   2577 
   2578   gBS->RestoreTPL (Tpl);
   2579   if (EFI_ERROR (Status)) {
   2580     if (Status == EFI_TIMEOUT){
   2581       return Status;
   2582     } else {
   2583       return EFI_DEVICE_ERROR;
   2584     }
   2585   }
   2586 
   2587   return EFI_SUCCESS;
   2588 }
   2589