2 USB Serial Driver that manages USB to Serial and produces Serial IO Protocol.
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
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.
18 // Tested with VEND_ID 0x0403, DEVICE_ID 0x6001
20 // Driver starts the device with the following values:
21 // 115200, No parity, 8 data bits, 1 stop bit, No Flow control
24 #include "FtdiUsbSerialDriver.h"
27 // Table of supported devices. This is the device information that this
28 // driver was developed with. Add other FTDI devices as needed.
30 USB_DEVICE gUSBDeviceList
[] = {
31 {VID_FTDI
, DID_FTDI_FT232
},
36 // USB Serial Driver Global Variables
38 EFI_DRIVER_BINDING_PROTOCOL gUsbSerialDriverBinding
= {
39 UsbSerialDriverBindingSupported
,
40 UsbSerialDriverBindingStart
,
41 UsbSerialDriverBindingStop
,
48 // Table with the nearest power of 2 for the numbers 0-15
50 UINT8 gRoundedPowersOf2
[16] = { 0, 2, 2, 4, 4, 4, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16 };
53 Check to see if the device path node is the Flow control node
55 @param[in] FlowControl The device path node to be checked
57 @retval TRUE It is the flow control node
58 @retval FALSE It is not the flow control node
62 IsUartFlowControlNode (
63 IN UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
67 (DevicePathType (FlowControl
) == MESSAGING_DEVICE_PATH
) &&
68 (DevicePathSubType (FlowControl
) == MSG_VENDOR_DP
) &&
69 (CompareGuid (&FlowControl
->Guid
, &gEfiUartDevicePathGuid
))
74 Checks the device path to see if it contains flow control.
76 @param[in] DevicePath The device path to be checked
78 @retval TRUE It contains flow control
79 @retval FALSE It does not contain flow control
84 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
87 while (!IsDevicePathEnd (DevicePath
)) {
88 if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH
*) DevicePath
)) {
91 DevicePath
= NextDevicePathNode (DevicePath
);
97 Transfer the data between the device and host.
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.
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
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
116 UsbSerialDataTransfer (
117 IN USB_SER_DEV
*UsbBot
,
118 IN EFI_USB_DATA_DIRECTION DataDir
,
120 IN OUT UINTN
*TransLen
,
124 EFI_USB_ENDPOINT_DESCRIPTOR
*Endpoint
;
129 // If no data to transfer, just return EFI_SUCCESS.
131 if ((DataDir
== EfiUsbNoData
) || (*TransLen
== 0)) {
136 // Select the endpoint then issue the transfer
138 if (DataDir
== EfiUsbDataIn
) {
139 Endpoint
= &UsbBot
->InEndpointDescriptor
;
141 Endpoint
= &UsbBot
->OutEndpointDescriptor
;
145 Status
= UsbBot
->UsbIo
->UsbBulkTransfer (
147 Endpoint
->EndpointAddress
,
153 if (EFI_ERROR (Status
)) {
154 if (USB_IS_ERROR (Result
, EFI_USB_ERR_NAK
)) {
155 Status
= EFI_NOT_READY
;
157 UsbBot
->Shutdown
= TRUE
; // Fixes infinite loop in older EFI
165 Sets the status values of the Usb Serial Device.
167 @param UsbSerialDevice[in] Handle to the Usb Serial Device to set the status
169 @param StatusBuffer[in] Buffer holding the status values
171 @retval EFI_SUCCESS The status values were read and set correctly
177 IN USB_SER_DEV
*UsbSerialDevice
,
178 IN UINT8
*StatusBuffer
183 Msr
= (StatusBuffer
[0] & MSR_MASK
);
186 // set the Status values to disabled
188 UsbSerialDevice
->StatusValues
.CtsState
= FALSE
;
189 UsbSerialDevice
->StatusValues
.DsrState
= FALSE
;
190 UsbSerialDevice
->StatusValues
.RiState
= FALSE
;
191 UsbSerialDevice
->StatusValues
.SdState
= FALSE
;
194 // Check the values from the status buffer and set the appropriate status
197 if ((Msr
& CTS_MASK
) == CTS_MASK
) {
198 UsbSerialDevice
->StatusValues
.CtsState
= TRUE
;
200 if ((Msr
& DSR_MASK
) == DSR_MASK
) {
201 UsbSerialDevice
->StatusValues
.DsrState
= TRUE
;
203 if ((Msr
& RI_MASK
) == RI_MASK
) {
204 UsbSerialDevice
->StatusValues
.RiState
= TRUE
;
206 if ((Msr
& SD_MASK
) == SD_MASK
) {
207 UsbSerialDevice
->StatusValues
.SdState
= TRUE
;
213 Initiates a read operation on the Usb Serial Device.
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
221 @param Buffer [out] The buffer to return the data into.
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.
231 IN USB_SER_DEV
*UsbSerialDevice
,
232 IN OUT UINTN
*BufferSize
,
237 UINTN ReadBufferSize
;
241 UINT8 StatusBuffer
[2]; // buffer to store the status bytes
243 ReadBufferSize
= 512;
244 ReadBuffer
= &(UsbSerialDevice
->ReadBuffer
[0]);
246 if (UsbSerialDevice
->Shutdown
) {
247 return EFI_DEVICE_ERROR
;
250 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
252 Status
= UsbSerialDataTransfer (
257 FTDI_TIMEOUT
*2 //Padded because timers won't be exactly aligned
259 if (EFI_ERROR (Status
)) {
260 gBS
->RestoreTPL (Tpl
);
261 if (Status
== EFI_TIMEOUT
) {
264 return EFI_DEVICE_ERROR
;
269 // Store the status bytes in the status buffer
271 for (Index
= 0; Index
< 2; Index
++) {//only the first 2 bytes are status bytes
272 StatusBuffer
[Index
] = ReadBuffer
[Index
];
275 // update the statusvalue field of the usbserialdevice
277 Status
= SetStatusInternal (UsbSerialDevice
, StatusBuffer
);
278 if (Status
!= EFI_SUCCESS
) {
282 // Store the read data in the read buffer, start at 2 to ignore status bytes
284 for (Index
= 2; Index
< ReadBufferSize
; Index
++) {
285 if (((UsbSerialDevice
->DataBufferTail
+ 1) % SW_FIFO_DEPTH
) == UsbSerialDevice
->DataBufferHead
) {
288 if (ReadBuffer
[Index
] == 0x00) {
290 // This is null, do not add
293 UsbSerialDevice
->DataBuffer
[UsbSerialDevice
->DataBufferTail
] = ReadBuffer
[Index
];
294 UsbSerialDevice
->DataBufferTail
= (UsbSerialDevice
->DataBufferTail
+ 1) % SW_FIFO_DEPTH
;
299 // Read characters out of the buffer to satisfy caller's request.
301 for (Index
= 0; Index
< *BufferSize
; Index
++) {
302 if (UsbSerialDevice
->DataBufferHead
== UsbSerialDevice
->DataBufferTail
) {
306 // Still have characters in the buffer to return
308 ((UINT8
*)Buffer
)[Index
] = UsbSerialDevice
->DataBuffer
[UsbSerialDevice
->DataBufferHead
];
309 UsbSerialDevice
->DataBufferHead
= (UsbSerialDevice
->DataBufferHead
+ 1) % SW_FIFO_DEPTH
;
312 // Return actual number of bytes returned.
315 gBS
->RestoreTPL (Tpl
);
320 Sets the initial status values of the Usb Serial Device by reading the status
321 bytes from the device.
323 @param UsbSerialDevice[in] Handle to the Usb Serial Device that needs its
324 initial status values set
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
330 @retval EFI_DEVICE_ERROR The device reported an error during the read of
337 IN USB_SER_DEV
*UsbSerialDevice
343 UINT8 StatusBuffer
[2];
345 Status
= EFI_UNSUPPORTED
;
346 BufferSize
= sizeof (StatusBuffer
);
348 if (UsbSerialDevice
->Shutdown
) {
349 return EFI_DEVICE_ERROR
;
352 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
354 Status
= UsbSerialDataTransfer (
359 40 //Slightly more than 2x the FTDI polling frequency to make sure that data will be returned
362 Status
= SetStatusInternal (UsbSerialDevice
, StatusBuffer
);
364 gBS
->RestoreTPL (Tpl
);
370 UsbSerialDriverCheckInput.
371 attempts to read data in from the device periodically, stores any read data
372 and updates the control attributes.
375 @param Context[in]....The current instance of the USB serial device
380 UsbSerialDriverCheckInput (
386 USB_SER_DEV
*UsbSerialDevice
;
388 UsbSerialDevice
= (USB_SER_DEV
*)Context
;
390 if (UsbSerialDevice
->DataBufferHead
== UsbSerialDevice
->DataBufferTail
) {
392 // Data buffer is empty, try to read from device
395 ReadDataFromUsb (UsbSerialDevice
, &BufferSize
, NULL
);
396 if (UsbSerialDevice
->DataBufferHead
== UsbSerialDevice
->DataBufferTail
) {
398 // Data buffer still has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY
401 UsbSerialDevice
->ControlBits
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
404 // Read has returned some data, clear the EFI_SERIAL_INPUT_BUFFER_EMPTY
407 UsbSerialDevice
->ControlBits
&= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY
);
411 // Data buffer has data, no read attempt required
413 UsbSerialDevice
->ControlBits
&= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY
);
418 Encodes the baud rate into the format expected by the Ftdi device.
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
424 @return EFI_SUCCESS Baudrate encoding was calculated
426 @return EFI_INVALID_PARAMETER An invalid value of BaudRate was received
431 EncodeBaudRateForFtdi (
433 OUT UINT16
*EncodedBaudRate
437 UINT32 AdjustedFrequency
;
441 // Check to make sure we won't get an integer overflow
443 if ((BaudRate
< 178) || ( BaudRate
> ((FTDI_UART_FREQUENCY
* 100) / 97))) {
444 return EFI_INVALID_PARAMETER
;
448 // Baud Rates of 2000000 and 3000000 are special cases
450 if ((BaudRate
>= FTDI_SPECIAL_CASE_300_MIN
) && (BaudRate
<= FTDI_SPECIAL_CASE_300_MAX
)) {
451 *EncodedBaudRate
= 0;
454 if ((BaudRate
>= FTDI_SPECIAL_CASE_200_MIN
) && (BaudRate
<= FTDI_SPECIAL_CASE_200_MAX
)) {
455 *EncodedBaudRate
= 1;
462 Divisor
= (FTDI_UART_FREQUENCY
<< 4) / (UINT32
)BaudRate
;
465 // Round the last 4 bits to the nearest power of 2
467 Divisor
= (Divisor
& ~(0xF)) + (gRoundedPowersOf2
[Divisor
& 0xF]);
470 // Check to make sure computed divisor is within
471 // the min and max that FTDI controller will accept
473 if (Divisor
< FTDI_MIN_DIVISOR
) {
474 Divisor
= FTDI_MIN_DIVISOR
;
475 } else if (Divisor
> FTDI_MAX_DIVISOR
) {
476 Divisor
= FTDI_MAX_DIVISOR
;
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.
484 // (3MHz * 1600) / 103 = 46601941
485 // (3MHz * 1600) / 97 = 49484536
487 AdjustedFrequency
= (((UINT32
)BaudRate
) * Divisor
);
488 if ((AdjustedFrequency
< FTDI_MIN_FREQUENCY
) || (AdjustedFrequency
> FTDI_MAX_FREQUENCY
)) {
489 return EFI_INVALID_PARAMETER
;
493 // Encode the Divisor into the format FTDI expects
495 Result
= (UINT16
)(Divisor
>> 4);
496 if ((Divisor
& 0x8) != 0) {
498 } else if ((Divisor
& 0x4) != 0) {
500 } else if ((Divisor
& 0x2) != 0) {
504 *EncodedBaudRate
= Result
;
509 Uses USB I/O to check whether the device is a USB Serial device.
511 @param UsbIo[in] Pointer to a USB I/O protocol instance.
513 @retval TRUE Device is a USB Serial device.
514 @retval FALSE Device is a not USB Serial device.
519 IN EFI_USB_IO_PROTOCOL
*UsbIo
523 EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor
;
529 // Get the default device descriptor
531 Status
= UsbIo
->UsbGetDeviceDescriptor (
535 if (EFI_ERROR (Status
)) {
541 while (gUSBDeviceList
[Index
].VendorId
!= 0 &&
542 gUSBDeviceList
[Index
].DeviceId
!= 0 &&
544 if (DeviceDescriptor
.IdProduct
== gUSBDeviceList
[Index
].DeviceId
&&
545 DeviceDescriptor
.IdVendor
== gUSBDeviceList
[Index
].VendorId
){
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
552 Status
= UsbIo
->UsbGetStringDescriptor (
554 USB_US_LANG_ID
, // LANGID selector, should make this
555 // more robust to verify lang support
557 DeviceDescriptor
.StrManufacturer
,
560 if (StrMfg
!= NULL
) {
563 if (EFI_ERROR (Status
)) {
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.
577 @param UsbIo[in] Usb Io Protocol instance pointer
578 @param DataBits[in] The data bits value to be set on the Usb
580 @param Parity[in] The parity type that will be set on the Usb
582 @param StopBits[in] The stop bits type that will be set on the
584 @param LastSettings[in] A pointer to the Usb Serial Device's
585 PREVIOUS_ATTRIBUTES item
587 @retval EFI_SUCCESS The data items were correctly set on the
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
598 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
600 IN EFI_PARITY_TYPE Parity
,
601 IN EFI_STOP_BITS_TYPE StopBits
,
602 IN PREVIOUS_ATTRIBUTES
*LastSettings
606 EFI_USB_DEVICE_REQUEST DevReq
;
608 UINT8 ConfigurationValue
;
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
614 if ((DataBits
== 0) && (StopBits
== OneFiveStopBits
)) {
615 if ((LastSettings
->DataBits
== 6) || (LastSettings
->DataBits
== 7) || (LastSettings
->DataBits
== 8)) {
616 return EFI_INVALID_PARAMETER
;
618 } else if ((StopBits
== DefaultStopBits
) && ((DataBits
== 6) || (DataBits
== 7) || (DataBits
== 8))) {
619 if (LastSettings
->StopBits
== OneFiveStopBits
) {
620 return EFI_INVALID_PARAMETER
;
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
;
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
635 if (((DataBits
< 5 ) || (DataBits
> 8)) && (DataBits
!= 0)) {
636 return EFI_INVALID_PARAMETER
;
640 // use the value of LastDataBits
642 DevReq
.Value
= SET_DATA_BITS (LastSettings
->DataBits
);
645 // use the value of DataBits
647 DevReq
.Value
= SET_DATA_BITS (DataBits
);
653 if (Parity
== DefaultParity
) {
654 Parity
= LastSettings
->Parity
;
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
;
672 if (StopBits
== DefaultStopBits
) {
673 StopBits
= LastSettings
->StopBits
;
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
;
685 // set the rest of the DevReq parameters and perform the usb control transfer
686 // to set the data bits on the device
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
693 Status
= UsbIo
->UsbControlTransfer (
702 if (EFI_ERROR (Status
)) {
708 if ((Status
!= EFI_INVALID_PARAMETER
) || (Status
!= EFI_DEVICE_ERROR
)) {
709 return EFI_DEVICE_ERROR
;
716 Internal function that sets the baudrate on the Usb Serial Device.
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
722 @param LastBaudRate[in] The baud rate value that was previously set
723 on the Usb Serial Device
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
733 SetBaudRateInternal (
734 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
736 IN UINT64 LastBaudRate
740 EFI_USB_DEVICE_REQUEST DevReq
;
742 UINT8 ConfigurationValue
;
743 UINT16 EncodedBaudRate
;
746 Tpl
= gBS
->RaiseTPL(TPL_NOTIFY
);
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
753 Status
= EncodeBaudRateForFtdi (LastBaudRate
, &EncodedBaudRate
);
754 if (EFI_ERROR (Status
)) {
755 gBS
->RestoreTPL (Tpl
);
757 // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
762 DevReq
.Value
= EncodedBaudRate
;
764 Status
= EncodeBaudRateForFtdi (BaudRate
, &EncodedBaudRate
);
765 if (EFI_ERROR (Status
)) {
766 gBS
->RestoreTPL (Tpl
);
768 // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
773 DevReq
.Value
= EncodedBaudRate
;
777 // set the remaining parameters of DevReq and perform the usb control transfer
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
785 Status
= UsbIo
->UsbControlTransfer (
794 if (EFI_ERROR (Status
)) {
797 gBS
->RestoreTPL (Tpl
);
801 gBS
->RestoreTPL (Tpl
);
802 if ((Status
!= EFI_INVALID_PARAMETER
) || (Status
!= EFI_DEVICE_ERROR
)) {
803 return EFI_DEVICE_ERROR
;
810 Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
811 data bits, and stop bits on a serial device.
813 @param UsbSerialDevice[in] Pointer to the current instance of the USB Serial
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
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
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.
836 @retval EFI_SUCCESS The attributes were set
837 @retval EFI_DEVICE_ERROR The attributes were not able to be set
842 SetAttributesInternal (
843 IN USB_SER_DEV
*UsbSerialDevice
,
845 IN UINT32 ReceiveFifoDepth
,
847 IN EFI_PARITY_TYPE Parity
,
849 IN EFI_STOP_BITS_TYPE StopBits
854 UART_DEVICE_PATH
*Uart
;
855 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
857 Status
= EFI_UNSUPPORTED
;
858 Tpl
= gBS
->RaiseTPL(TPL_NOTIFY
);
862 // check for invalid combinations of parameters
864 if (((DataBits
>= 6) && (DataBits
<= 8)) && (StopBits
== OneFiveStopBits
)) {
865 return EFI_INVALID_PARAMETER
;
869 // set data bits, parity and stop bits
871 Status
= SetDataInternal (
872 UsbSerialDevice
->UsbIo
,
876 &(UsbSerialDevice
->LastSettings
)
878 if (EFI_ERROR (Status
)) {
884 Status
= SetBaudRateInternal (
885 UsbSerialDevice
->UsbIo
,
887 UsbSerialDevice
->LastSettings
.BaudRate
889 if (EFI_ERROR (Status
)){
894 // update the values of UsbSerialDevice->LastSettings and UsbSerialDevice->SerialIo.Mode
897 UsbSerialDevice
->LastSettings
.BaudRate
= UsbSerialDevice
->LastSettings
.BaudRate
;
898 UsbSerialDevice
->SerialIo
.Mode
->BaudRate
= UsbSerialDevice
->LastSettings
.BaudRate
;
900 UsbSerialDevice
->LastSettings
.BaudRate
= BaudRate
;
901 UsbSerialDevice
->SerialIo
.Mode
->BaudRate
= BaudRate
;
904 UsbSerialDevice
->LastSettings
.Timeout
= FTDI_TIMEOUT
;
905 UsbSerialDevice
->LastSettings
.ReceiveFifoDepth
= FTDI_MAX_RECEIVE_FIFO_DEPTH
;
907 if (Parity
== DefaultParity
) {
908 UsbSerialDevice
->LastSettings
.Parity
= UsbSerialDevice
->LastSettings
.Parity
;
909 UsbSerialDevice
->SerialIo
.Mode
->Parity
= UsbSerialDevice
->LastSettings
.Parity
;
911 UsbSerialDevice
->LastSettings
.Parity
= Parity
;
912 UsbSerialDevice
->SerialIo
.Mode
->Parity
= Parity
;
915 UsbSerialDevice
->LastSettings
.DataBits
= UsbSerialDevice
->LastSettings
.DataBits
;
916 UsbSerialDevice
->SerialIo
.Mode
->DataBits
= UsbSerialDevice
->LastSettings
.DataBits
;
918 UsbSerialDevice
->LastSettings
.DataBits
= DataBits
;
919 UsbSerialDevice
->SerialIo
.Mode
->DataBits
= DataBits
;
921 if (StopBits
== DefaultStopBits
) {
922 UsbSerialDevice
->LastSettings
.StopBits
= UsbSerialDevice
->LastSettings
.StopBits
;
923 UsbSerialDevice
->SerialIo
.Mode
->StopBits
= UsbSerialDevice
->LastSettings
.StopBits
;
925 UsbSerialDevice
->LastSettings
.StopBits
= StopBits
;
926 UsbSerialDevice
->SerialIo
.Mode
->StopBits
= StopBits
;
930 // See if the device path node has changed
932 if (UsbSerialDevice
->UartDevicePath
.BaudRate
== BaudRate
&&
933 UsbSerialDevice
->UartDevicePath
.DataBits
== DataBits
&&
934 UsbSerialDevice
->UartDevicePath
.StopBits
== StopBits
&&
935 UsbSerialDevice
->UartDevicePath
.Parity
== Parity
937 gBS
->RestoreTPL (Tpl
);
942 // Update the device path
944 UsbSerialDevice
->UartDevicePath
.BaudRate
= BaudRate
;
945 UsbSerialDevice
->UartDevicePath
.DataBits
= DataBits
;
946 UsbSerialDevice
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
947 UsbSerialDevice
->UartDevicePath
.Parity
= (UINT8
) Parity
;
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
;
963 RemainingDevicePath
= NextDevicePathNode (RemainingDevicePath
);
967 gBS
->RestoreTPL (Tpl
);
971 gBS
->RestoreTPL (Tpl
);
972 if ((Status
!= EFI_INVALID_PARAMETER
) || (Status
!= EFI_DEVICE_ERROR
)) {
973 return EFI_DEVICE_ERROR
;
980 Internal function that performs a Usb Control Transfer to set the flow control
981 on the Usb Serial Device.
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
987 @retval EFI_SUCCESS The flow control was set on the Usb Serial
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
996 SetFlowControlInternal (
997 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
998 IN BOOLEAN FlowControlEnable
1002 EFI_USB_DEVICE_REQUEST DevReq
;
1004 UINT8 ConfigurationValue
;
1007 // set DevReq.Value based on the value of FlowControlEnable
1009 if (!FlowControlEnable
) {
1010 DevReq
.Value
= NO_FLOW_CTRL
;
1012 if (FlowControlEnable
) {
1013 DevReq
.Value
= XON_XOFF_CTRL
;
1016 // set the remaining DevReq parameters and perform the usb control transfer to
1017 // set the flow control on the device
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 (
1028 &ConfigurationValue
,
1032 if (EFI_ERROR (Status
)) {
1039 if ((Status
!= EFI_INVALID_PARAMETER
) ||
1040 (Status
!= EFI_DEVICE_ERROR
) ||
1041 (Status
!= EFI_UNSUPPORTED
) ) {
1042 return EFI_DEVICE_ERROR
;
1049 Internal function that performs a Usb Control Transfer to set the Dtr value on
1050 the Usb Serial Device.
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
1056 @retval EFI_SUCCESS The Dtr value was set on the Usb Serial
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
1066 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
1067 IN BOOLEAN DtrEnable
1071 EFI_USB_DEVICE_REQUEST DevReq
;
1073 UINT8 ConfigurationValue
;
1076 // set the value of DevReq.Value based on the value of DtrEnable
1079 DevReq
.Value
= SET_DTR_LOW
;
1082 DevReq
.Value
= SET_DTR_HIGH
;
1085 // set the remaining attributes of DevReq and perform the usb control transfer
1086 // to set the device
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
1093 Status
= UsbIo
->UsbControlTransfer (
1098 &ConfigurationValue
,
1102 if (EFI_ERROR (Status
)) {
1108 if ((Status
!= EFI_INVALID_PARAMETER
) ||
1109 (Status
!= EFI_DEVICE_ERROR
) ||
1110 (Status
!= EFI_UNSUPPORTED
) ) {
1111 return EFI_DEVICE_ERROR
;
1118 Internal function that performs a Usb Control Transfer to set the Dtr value on
1119 the Usb Serial Device.
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
1125 @retval EFI_SUCCESS The Rts value was set on the Usb Serial
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
1135 IN EFI_USB_IO_PROTOCOL
*UsbIo
,
1136 IN BOOLEAN RtsEnable
1140 EFI_USB_DEVICE_REQUEST DevReq
;
1142 UINT8 ConfigurationValue
;
1145 // set DevReq.Value based on the value of RtsEnable
1148 DevReq
.Value
= SET_RTS_LOW
;
1151 DevReq
.Value
= SET_RTS_HIGH
;
1155 // set the remaining parameters of DevReq and perform the usb control transfer
1156 // to set the values on the device
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
1163 Status
= UsbIo
->UsbControlTransfer (
1168 &ConfigurationValue
,
1172 if (EFI_ERROR (Status
)) {
1179 if ((Status
!= EFI_INVALID_PARAMETER
) ||
1180 (Status
!= EFI_DEVICE_ERROR
) ||
1181 (Status
!= EFI_UNSUPPORTED
) ) {
1182 return EFI_DEVICE_ERROR
;
1189 Internal function that checks for valid control values and sets the control
1190 bits on the Usb Serial Device.
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
1198 @retval EFI_SUCCESS The control bits were set on the Usb Serial
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
1207 SetControlBitsInternal (
1208 IN USB_SER_DEV
*UsbSerialDevice
,
1209 IN CONTROL_BITS
*Control
1213 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
;
1214 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
1217 // check for invalid control parameters hardware and software loopback enabled
1218 // must always be set to FALSE
1220 Control
->HardwareLoopBack
= FALSE
;
1221 Control
->SoftwareLoopBack
= FALSE
;
1224 // set hardware flow control
1226 Status
= SetFlowControlInternal (
1227 UsbSerialDevice
->UsbIo
,
1228 Control
->HardwareFlowControl
1230 if (EFI_ERROR (Status
)) {
1237 Status
= SetDtrInternal (UsbSerialDevice
->UsbIo
, Control
->DtrState
);
1238 if (EFI_ERROR (Status
)) {
1245 Status
= SetRtsInternal (UsbSerialDevice
->UsbIo
, Control
->RtsState
);
1246 if (EFI_ERROR (Status
)){
1251 // update the remaining control values for UsbSerialDevice->ControlValues
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
;
1259 Status
= EFI_SUCCESS
;
1261 // Update the device path to have the correct flow control values
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;
1277 RemainingDevicePath
= NextDevicePathNode (RemainingDevicePath
);
1284 if ((Status
!= EFI_INVALID_PARAMETER
) ||
1285 (Status
!= EFI_DEVICE_ERROR
) ||
1286 (Status
!= EFI_UNSUPPORTED
) ) {
1287 return EFI_DEVICE_ERROR
;
1294 Internal function that calculates the Control value used by GetControlBits()
1295 based on the status and control values of the Usb Serial Device.
1297 @param UsbSerialDevice[in] Handle to the Usb Serial Devie whose status
1298 and control values are being used to set
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
1305 @retval EFI_SUCCESS The value of Control was successfully
1311 GetControlBitsInternal (
1312 IN USB_SER_DEV
*UsbSerialDevice
,
1319 // Check the values of UsbSerialDevice->Status Values and modify control
1320 // accordingly these values correspond to the modem status register
1322 if (UsbSerialDevice
->StatusValues
.CtsState
) {
1323 *Control
|= EFI_SERIAL_CLEAR_TO_SEND
;
1325 if (UsbSerialDevice
->StatusValues
.DsrState
) {
1326 *Control
|= EFI_SERIAL_DATA_SET_READY
;
1328 if (UsbSerialDevice
->StatusValues
.RiState
) {
1329 *Control
|= EFI_SERIAL_RING_INDICATE
;
1331 if (UsbSerialDevice
->StatusValues
.SdState
) {
1332 *Control
|= EFI_SERIAL_CARRIER_DETECT
;
1336 // check the values of UsbSerialDevice->ControlValues and modify control
1337 // accordingly these values correspond to the values of the Modem Control
1340 if (UsbSerialDevice
->ControlValues
.DtrState
) {
1341 *Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1343 if (UsbSerialDevice
->ControlValues
.RtsState
) {
1344 *Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1346 if (UsbSerialDevice
->ControlValues
.HardwareLoopBack
) {
1347 *Control
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1349 if (UsbSerialDevice
->ControlValues
.HardwareFlowControl
) {
1350 *Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
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
1356 if (UsbSerialDevice
->DataBufferHead
== UsbSerialDevice
->DataBufferTail
) {
1357 *Control
|= EFI_SERIAL_OUTPUT_BUFFER_EMPTY
;
1358 *Control
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1361 // check for software loopback enable in UsbSerialDevice->ControlValues
1363 if (UsbSerialDevice
->ControlValues
.SoftwareLoopBack
) {
1364 *Control
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1371 Resets the USB Serial Device
1373 This function is the internal method for reseting the device and is called by
1376 @param UsbSerialDevice[in] A pointer to the USB Serial device
1378 @retval EFI_SUCCESS The device was reset
1379 @retval EFI_DEVICE_ERROR The device could not be reset
1385 IN USB_SER_DEV
*UsbSerialDevice
1389 EFI_USB_DEVICE_REQUEST DevReq
;
1390 UINT8 ConfigurationValue
;
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
1399 Status
= UsbSerialDevice
->UsbIo
->UsbControlTransfer (
1400 UsbSerialDevice
->UsbIo
,
1404 &ConfigurationValue
,
1408 if (EFI_ERROR (Status
)) {
1409 return EFI_DEVICE_ERROR
;
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
1418 Status
= UsbSerialDevice
->UsbIo
->UsbControlTransfer (
1419 UsbSerialDevice
->UsbIo
,
1423 &ConfigurationValue
,
1427 if (EFI_ERROR (Status
)) {
1428 return EFI_DEVICE_ERROR
;
1434 Entrypoint of USB Serial Driver.
1436 This function is the entrypoint of USB Serial Driver. It installs
1437 Driver Binding Protocols together with Component Name Protocols.
1439 @param ImageHandle[in] The firmware allocated handle for the EFI image.
1440 @param SystemTable[in] A pointer to the EFI System Table.
1442 @retval EFI_SUCCESS The entry point is executed successfully.
1447 FtdiUsbSerialEntryPoint (
1448 IN EFI_HANDLE ImageHandle
,
1449 IN EFI_SYSTEM_TABLE
*SystemTable
1454 Status
= EfiLibInstallDriverBindingComponentName2 (
1457 &gUsbSerialDriverBinding
,
1459 &gUsbSerialComponentName
,
1460 &gUsbSerialComponentName2
1462 ASSERT_EFI_ERROR (Status
);
1467 Unload function for the Usb Serial Driver.
1469 @param ImageHandle[in] The allocated handle for the EFI image
1471 @retval EFI_SUCCESS The driver was unloaded successfully
1475 FtdiUsbSerialUnload (
1476 IN EFI_HANDLE ImageHandle
1480 EFI_HANDLE
*HandleBuffer
;
1485 // Retrieve all handles in the handle database
1487 Status
= gBS
->LocateHandleBuffer (
1494 if (EFI_ERROR (Status
)) {
1499 // Disconnect the driver from the handles in the handle database
1501 for (Index
= 0; Index
< HandleCount
; Index
++) {
1502 Status
= gBS
->DisconnectController (
1503 HandleBuffer
[Index
],
1510 // Free the handle array
1512 FreePool (HandleBuffer
);
1515 // Uninstall protocols installed by the driver in its entrypoint
1517 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1519 &gEfiDriverBindingProtocolGuid
,
1520 &gUsbSerialDriverBinding
,
1521 &gEfiComponentNameProtocolGuid
,
1522 &gUsbSerialComponentName
,
1523 &gEfiComponentName2ProtocolGuid
,
1524 &gUsbSerialComponentName2
,
1527 if (EFI_ERROR (Status
)) {
1535 Check whether USB Serial driver supports this device.
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.
1541 @retval EFI_SUCCESS The driver supports this controller.
1542 @retval other This device isn't supported.
1547 UsbSerialDriverBindingSupported (
1548 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1549 IN EFI_HANDLE Controller
,
1550 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1554 EFI_USB_IO_PROTOCOL
*UsbIo
;
1555 UART_DEVICE_PATH
*UartNode
;
1556 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControlNode
;
1559 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
1560 BOOLEAN HasFlowControl
;
1561 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1562 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
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
)) {
1573 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (UartNode
);
1574 if ((ReadUnaligned32 (&FlowControlNode
->FlowControlMap
) & ~UART_FLOW_CONTROL_HARDWARE
) != 0) {
1581 // Check if USB I/O Protocol is attached on the controller handle.
1583 Status
= gBS
->OpenProtocol (
1585 &gEfiUsbIoProtocolGuid
,
1587 This
->DriverBindingHandle
,
1589 EFI_OPEN_PROTOCOL_BY_DRIVER
1591 if (Status
== EFI_ALREADY_STARTED
) {
1592 if (RemainingDevicePath
== NULL
|| IsDevicePathEnd (RemainingDevicePath
)) {
1595 Status
= gBS
->OpenProtocolInformation (
1597 &gEfiUsbIoProtocolGuid
,
1601 if (EFI_ERROR (Status
)) {
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
,
1612 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1614 if (!EFI_ERROR (Status
)) {
1615 HasFlowControl
= ContainsFlowControl (RemainingDevicePath
);
1616 if (HasFlowControl
^ ContainsFlowControl (DevicePath
)) {
1617 Status
= EFI_UNSUPPORTED
;
1623 FreePool (OpenInfoBuffer
);
1627 if (EFI_ERROR (Status
)) {
1631 gBS
->CloseProtocol (
1633 &gEfiUsbIoProtocolGuid
,
1634 This
->DriverBindingHandle
,
1638 Status
= gBS
->OpenProtocol (
1640 &gEfiDevicePathProtocolGuid
,
1641 (VOID
**) &ParentDevicePath
,
1642 This
->DriverBindingHandle
,
1644 EFI_OPEN_PROTOCOL_BY_DRIVER
1646 if (Status
== EFI_ALREADY_STARTED
) {
1649 if (EFI_ERROR (Status
)) {
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.
1657 Status
= EFI_SUCCESS
;
1659 if (!IsUsbSerial (UsbIo
)) {
1660 Status
= EFI_UNSUPPORTED
;
1665 gBS
->CloseProtocol (
1667 &gEfiDevicePathProtocolGuid
,
1668 This
->DriverBindingHandle
,
1675 Starts the USB Serial device with this driver.
1677 This function produces initializes the USB Serial device and
1678 produces the Serial IO Protocol.
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.
1685 @retval EFI_SUCCESS The controller is controlled by the usb USB
1687 @retval EFI_UNSUPPORTED No interrupt endpoint can be found.
1688 @retval Other This controller cannot be started.
1693 UsbSerialDriverBindingStart (
1694 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1695 IN EFI_HANDLE Controller
,
1696 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1700 EFI_USB_IO_PROTOCOL
*UsbIo
;
1701 USB_SER_DEV
*UsbSerialDevice
;
1702 UINT8 EndpointNumber
;
1703 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
1707 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1708 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
1710 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
1711 UART_DEVICE_PATH
*Uart
;
1712 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
;
1714 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1716 UsbSerialDevice
= AllocateZeroPool (sizeof (USB_SER_DEV
));
1717 ASSERT (UsbSerialDevice
!= NULL
);
1720 // Get the Parent Device path
1722 Status
= gBS
->OpenProtocol (
1724 &gEfiDevicePathProtocolGuid
,
1725 (VOID
**) &ParentDevicePath
,
1726 This
->DriverBindingHandle
,
1728 EFI_OPEN_PROTOCOL_BY_DRIVER
1730 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1735 // Open USB I/O Protocol
1737 Status
= gBS
->OpenProtocol (
1739 &gEfiUsbIoProtocolGuid
,
1741 This
->DriverBindingHandle
,
1743 EFI_OPEN_PROTOCOL_BY_DRIVER
1745 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1749 if (Status
== EFI_ALREADY_STARTED
) {
1750 if (RemainingDevicePath
== NULL
|| IsDevicePathEnd (RemainingDevicePath
)) {
1751 FreePool (UsbSerialDevice
);
1756 // Check to see if a child handle exists
1758 Status
= gBS
->OpenProtocolInformation (
1760 &gEfiSerialIoProtocolGuid
,
1764 if (EFI_ERROR (Status
)) {
1768 Status
= EFI_ALREADY_STARTED
;
1769 for (Index
= 0; Index
< EntryCount
; Index
++) {
1770 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
1771 Status
= gBS
->OpenProtocol (
1772 OpenInfoBuffer
[Index
].ControllerHandle
,
1773 &gEfiSerialIoProtocolGuid
,
1774 (VOID
**) &SerialIo
,
1775 This
->DriverBindingHandle
,
1777 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1779 if (EFI_ERROR (Status
)) {
1781 if (!EFI_ERROR (Status
)) {
1782 Uart
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
1783 Status
= SerialIo
->SetAttributes (
1786 SerialIo
->Mode
->ReceiveFifoDepth
,
1787 SerialIo
->Mode
->Timeout
,
1788 (EFI_PARITY_TYPE
) Uart
->Parity
,
1790 (EFI_STOP_BITS_TYPE
) Uart
->StopBits
1792 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (Uart
);
1793 if (!EFI_ERROR (Status
) && IsUartFlowControlNode (FlowControl
)) {
1794 Status
= SerialIo
->GetControl (
1798 if (!EFI_ERROR (Status
)) {
1799 if (ReadUnaligned32 (&FlowControl
->FlowControlMap
) == UART_FLOW_CONTROL_HARDWARE
) {
1800 Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1802 Control
&= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1805 // Clear bits that are not allowed to be passed to SetControl
1807 Control
&= (EFI_SERIAL_REQUEST_TO_SEND
|
1808 EFI_SERIAL_DATA_TERMINAL_READY
|
1809 EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
|
1810 EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
|
1811 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
);
1812 Status
= SerialIo
->SetControl (SerialIo
, Control
);
1819 FreePool (OpenInfoBuffer
);
1823 if (RemainingDevicePath
!= NULL
) {
1824 if (IsDevicePathEnd (RemainingDevicePath
)) {
1829 UsbSerialDevice
->UsbIo
= UsbIo
;
1832 // Get interface & endpoint descriptor
1834 UsbIo
->UsbGetInterfaceDescriptor (
1836 &UsbSerialDevice
->InterfaceDescriptor
1839 EndpointNumber
= UsbSerialDevice
->InterfaceDescriptor
.NumEndpoints
;
1842 // Traverse endpoints to find the IN and OUT endpoints that will send and
1847 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
1849 Status
= UsbIo
->UsbGetEndpointDescriptor (
1854 if (EFI_ERROR (Status
)) {
1858 if (EndpointDescriptor
.EndpointAddress
== FTDI_ENDPOINT_ADDRESS_OUT
) {
1860 // Set the Out endpoint device
1863 &UsbSerialDevice
->OutEndpointDescriptor
,
1864 &EndpointDescriptor
,
1865 sizeof(EndpointDescriptor
)
1870 if (EndpointDescriptor
.EndpointAddress
== FTDI_ENDPOINT_ADDRESS_IN
) {
1872 // Set the In endpoint device
1875 &UsbSerialDevice
->InEndpointDescriptor
,
1876 &EndpointDescriptor
,
1877 sizeof(EndpointDescriptor
)
1883 if (!FoundIn
|| !FoundOut
) {
1885 // No interrupt endpoint found, then return unsupported.
1887 Status
= EFI_UNSUPPORTED
;
1891 // set the initial values of UsbSerialDevice->LastSettings to the default
1894 UsbSerialDevice
->LastSettings
.BaudRate
= 115200;
1895 UsbSerialDevice
->LastSettings
.DataBits
= 8;
1896 UsbSerialDevice
->LastSettings
.Parity
= NoParity
;
1897 UsbSerialDevice
->LastSettings
.ReceiveFifoDepth
= FTDI_MAX_RECEIVE_FIFO_DEPTH
;
1898 UsbSerialDevice
->LastSettings
.StopBits
= OneStopBit
;
1899 UsbSerialDevice
->LastSettings
.Timeout
= FTDI_TIMEOUT
;
1902 // set the initial values of UsbSerialDevice->ControlValues
1904 UsbSerialDevice
->ControlValues
.DtrState
= FALSE
;
1905 UsbSerialDevice
->ControlValues
.RtsState
= FALSE
;
1906 UsbSerialDevice
->ControlValues
.HardwareFlowControl
= FALSE
;
1907 UsbSerialDevice
->ControlValues
.HardwareLoopBack
= FALSE
;
1908 UsbSerialDevice
->ControlValues
.SoftwareLoopBack
= FALSE
;
1911 // set the values of UsbSerialDevice->UartDevicePath
1913 UsbSerialDevice
->UartDevicePath
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1914 UsbSerialDevice
->UartDevicePath
.Header
.SubType
= MSG_UART_DP
;
1915 UsbSerialDevice
->UartDevicePath
.Header
.Length
[0] = (UINT8
) (sizeof (UART_DEVICE_PATH
));
1916 UsbSerialDevice
->UartDevicePath
.Header
.Length
[1] = (UINT8
) ((sizeof (UART_DEVICE_PATH
)) >> 8);
1919 // set the values of UsbSerialDevice->FlowControlDevicePath
1920 UsbSerialDevice
->FlowControlDevicePath
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1921 UsbSerialDevice
->FlowControlDevicePath
.Header
.SubType
= MSG_VENDOR_DP
;
1922 UsbSerialDevice
->FlowControlDevicePath
.Header
.Length
[0] = (UINT8
) (sizeof (UART_FLOW_CONTROL_DEVICE_PATH
));
1923 UsbSerialDevice
->FlowControlDevicePath
.Header
.Length
[1] = (UINT8
) ((sizeof (UART_FLOW_CONTROL_DEVICE_PATH
)) >> 8);
1924 UsbSerialDevice
->FlowControlDevicePath
.FlowControlMap
= 0;
1926 Status
= SetAttributesInternal (
1928 UsbSerialDevice
->LastSettings
.BaudRate
,
1929 UsbSerialDevice
->LastSettings
.ReceiveFifoDepth
,
1930 UsbSerialDevice
->LastSettings
.Timeout
,
1931 UsbSerialDevice
->LastSettings
.Parity
,
1932 UsbSerialDevice
->LastSettings
.DataBits
,
1933 UsbSerialDevice
->LastSettings
.StopBits
1936 ASSERT_EFI_ERROR (Status
);
1938 Status
= SetControlBitsInternal (
1940 &(UsbSerialDevice
->ControlValues
)
1943 ASSERT_EFI_ERROR (Status
);
1946 // Publish Serial GUID and protocol
1949 UsbSerialDevice
->Signature
= USB_SER_DEV_SIGNATURE
;
1950 UsbSerialDevice
->SerialIo
.Reset
= SerialReset
;
1951 UsbSerialDevice
->SerialIo
.SetControl
= SetControlBits
;
1952 UsbSerialDevice
->SerialIo
.SetAttributes
= SetAttributes
;
1953 UsbSerialDevice
->SerialIo
.GetControl
= GetControlBits
;
1954 UsbSerialDevice
->SerialIo
.Read
= ReadSerialIo
;
1955 UsbSerialDevice
->SerialIo
.Write
= WriteSerialIo
;
1958 // Set the static Serial IO modes that will display when running
1959 // "sermode" within the UEFI shell.
1962 UsbSerialDevice
->SerialIo
.Mode
->Timeout
= 0;
1963 UsbSerialDevice
->SerialIo
.Mode
->BaudRate
= 115200;
1964 UsbSerialDevice
->SerialIo
.Mode
->DataBits
= 8;
1965 UsbSerialDevice
->SerialIo
.Mode
->Parity
= 1;
1966 UsbSerialDevice
->SerialIo
.Mode
->StopBits
= 1;
1968 UsbSerialDevice
->ParentDevicePath
= ParentDevicePath
;
1969 UsbSerialDevice
->ControllerHandle
= NULL
;
1973 // Allocate space for the receive buffer
1975 UsbSerialDevice
->DataBuffer
= AllocateZeroPool (SW_FIFO_DEPTH
);
1978 // Initialize data buffer pointers.
1979 // Head==Tail = true means buffer is empty.
1981 UsbSerialDevice
->DataBufferHead
= 0;
1982 UsbSerialDevice
->DataBufferTail
= 0;
1984 UsbSerialDevice
->ControllerNameTable
= NULL
;
1987 gUsbSerialComponentName
.SupportedLanguages
,
1988 &UsbSerialDevice
->ControllerNameTable
,
1989 L
"FTDI USB Serial Adapter",
1994 gUsbSerialComponentName2
.SupportedLanguages
,
1995 &UsbSerialDevice
->ControllerNameTable
,
1996 L
"FTDI USB Serial Adapter",
2000 Status
= SetInitialStatus (UsbSerialDevice
);
2001 ASSERT_EFI_ERROR (Status
);
2004 // Create a polling loop to check for input
2008 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
2010 UsbSerialDriverCheckInput
,
2012 &(UsbSerialDevice
->PollingLoop
)
2015 // add code to set trigger time based on baud rate
2016 // setting to 0.5s for now
2019 UsbSerialDevice
->PollingLoop
,
2021 EFI_TIMER_PERIOD_MILLISECONDS (500)
2025 // Check if the remaining device path is null. If it is not null change the settings
2026 // of the device to match those on the device path
2028 if (RemainingDevicePath
!= NULL
) {
2030 &UsbSerialDevice
->UartDevicePath
,
2031 RemainingDevicePath
,
2032 sizeof (UART_DEVICE_PATH
)
2034 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (RemainingDevicePath
);
2035 if (IsUartFlowControlNode (FlowControl
)) {
2036 UsbSerialDevice
->FlowControlDevicePath
.FlowControlMap
= ReadUnaligned32 (&FlowControl
->FlowControlMap
);
2043 // Build the device path by appending the UART node to the parent device path
2045 UsbSerialDevice
->DevicePath
= AppendDevicePathNode (
2047 (EFI_DEVICE_PATH_PROTOCOL
*) &UsbSerialDevice
->UartDevicePath
2050 // Continue building the device path by appending the flow control node
2052 TempDevicePath
= UsbSerialDevice
->DevicePath
;
2053 UsbSerialDevice
->DevicePath
= AppendDevicePathNode (
2055 (EFI_DEVICE_PATH_PROTOCOL
*) &UsbSerialDevice
->FlowControlDevicePath
2057 FreePool (TempDevicePath
);
2059 if (UsbSerialDevice
->DevicePath
== NULL
) {
2060 Status
= EFI_OUT_OF_RESOURCES
;
2065 // Install protocol interfaces for the device
2067 Status
= gBS
->InstallMultipleProtocolInterfaces (
2068 &UsbSerialDevice
->ControllerHandle
,
2069 &gEfiDevicePathProtocolGuid
,
2070 UsbSerialDevice
->DevicePath
,
2071 &gEfiSerialIoProtocolGuid
,
2072 &UsbSerialDevice
->SerialIo
,
2075 if (EFI_ERROR (Status
)){
2080 // Open for child device
2082 Status
= gBS
->OpenProtocol (
2084 &gEfiUsbIoProtocolGuid
,
2086 This
->DriverBindingHandle
,
2087 UsbSerialDevice
->ControllerHandle
,
2088 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2091 UsbSerialDevice
->Shutdown
= FALSE
;
2100 Status
= gBS
->UninstallMultipleProtocolInterfaces (
2102 &gEfiSerialIoProtocolGuid
,
2103 &UsbSerialDevice
->SerialIo
,
2106 if (EFI_ERROR (Status
)) {
2110 FreePool (UsbSerialDevice
->DataBuffer
);
2111 FreePool (UsbSerialDevice
);
2113 UsbSerialDevice
= NULL
;
2114 gBS
->CloseProtocol (
2116 &gEfiUsbIoProtocolGuid
,
2117 This
->DriverBindingHandle
,
2126 Stop the USB Serial device handled by this driver.
2128 @param This[in] The USB Serial driver binding protocol.
2129 @param Controller[in] The controller to release.
2130 @param NumberOfChildren[in] The number of handles in ChildHandleBuffer.
2131 @param ChildHandleBuffer[in] The array of child handle.
2133 @retval EFI_SUCCESS The device was stopped.
2134 @retval EFI_UNSUPPORTED Serial IO Protocol is not installed on
2136 @retval EFI_DEVICE_ERROR The device could not be stopped due to a
2138 @retval Others Fail to uninstall protocols attached on the
2144 UsbSerialDriverBindingStop (
2145 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2146 IN EFI_HANDLE Controller
,
2147 IN UINTN NumberOfChildren
,
2148 IN EFI_HANDLE
*ChildHandleBuffer
2152 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
2153 EFI_USB_IO_PROTOCOL
*UsbIo
;
2154 USB_SER_DEV
*UsbSerialDevice
;
2156 BOOLEAN AllChildrenStopped
;
2158 Status
= EFI_SUCCESS
;
2159 UsbSerialDevice
= NULL
;
2161 if (NumberOfChildren
== 0) {
2165 Status
= gBS
->CloseProtocol (
2167 &gEfiUsbIoProtocolGuid
,
2168 This
->DriverBindingHandle
,
2171 Status
= gBS
->CloseProtocol (
2173 &gEfiDevicePathProtocolGuid
,
2174 This
->DriverBindingHandle
,
2180 AllChildrenStopped
= TRUE
;
2182 for (Index
= 0; Index
< NumberOfChildren
;Index
++) {
2183 Status
= gBS
->OpenProtocol (
2184 ChildHandleBuffer
[Index
],
2185 &gEfiSerialIoProtocolGuid
,
2186 (VOID
**) &SerialIo
,
2187 This
->DriverBindingHandle
,
2189 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2191 if (Status
== EFI_SUCCESS
) {//!EFI_ERROR (Status)) {
2192 UsbSerialDevice
= USB_SER_DEV_FROM_THIS (SerialIo
);
2193 Status
= gBS
->CloseProtocol (
2195 &gEfiUsbIoProtocolGuid
,
2196 This
->DriverBindingHandle
,
2197 ChildHandleBuffer
[Index
]
2199 Status
= gBS
->UninstallMultipleProtocolInterfaces (
2200 ChildHandleBuffer
[Index
],
2201 &gEfiDevicePathProtocolGuid
,
2202 UsbSerialDevice
->DevicePath
,
2203 &gEfiSerialIoProtocolGuid
,
2204 &UsbSerialDevice
->SerialIo
,
2208 if (EFI_ERROR (Status
)) {
2211 &gEfiUsbIoProtocolGuid
,
2213 This
->DriverBindingHandle
,
2214 ChildHandleBuffer
[Index
],
2215 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2218 if (UsbSerialDevice
->DevicePath
!= NULL
) {
2219 gBS
->FreePool (UsbSerialDevice
->DevicePath
);
2222 UsbSerialDevice
->PollingLoop
,
2226 gBS
->CloseEvent (UsbSerialDevice
->PollingLoop
);
2227 UsbSerialDevice
->Shutdown
= TRUE
;
2228 FreeUnicodeStringTable (UsbSerialDevice
->ControllerNameTable
);
2229 FreePool (UsbSerialDevice
->DataBuffer
);
2230 FreePool (UsbSerialDevice
);
2233 if (EFI_ERROR (Status
)) {
2234 AllChildrenStopped
= FALSE
;
2238 if (!AllChildrenStopped
) {
2239 return EFI_DEVICE_ERROR
;
2245 // Serial IO Member Functions
2249 Reset the serial device.
2251 @param This[in] Protocol instance pointer.
2253 @retval EFI_SUCCESS The device was reset.
2254 @retval EFI_DEVICE_ERROR The serial device could not be reset.
2260 IN EFI_SERIAL_IO_PROTOCOL
*This
2264 USB_SER_DEV
*UsbSerialDevice
;
2266 UsbSerialDevice
= USB_SER_DEV_FROM_THIS (This
);
2267 Status
= ResetInternal (UsbSerialDevice
);
2268 if (EFI_ERROR (Status
)){
2269 return EFI_DEVICE_ERROR
;
2275 Set the control bits on a serial device.
2277 @param This[in] Protocol instance pointer.
2278 @param Control[in] Set the bits of Control that are settable.
2280 @retval EFI_SUCCESS The new control bits were set on the serial device.
2281 @retval EFI_UNSUPPORTED The serial device does not support this operation.
2282 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
2288 IN EFI_SERIAL_IO_PROTOCOL
*This
,
2293 USB_SER_DEV
*UsbSerialDevice
;
2294 CONTROL_BITS ControlBits
;
2296 UsbSerialDevice
= USB_SER_DEV_FROM_THIS (This
);
2299 // check for invalid control parameters
2301 if ((Control
& (~(EFI_SERIAL_REQUEST_TO_SEND
|
2302 EFI_SERIAL_DATA_TERMINAL_READY
|
2303 EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
|
2304 EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
|
2305 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
))) != 0 ) {
2306 return EFI_UNSUPPORTED
;
2310 // check the control parameters and set the correct setting for
2311 // the paramerts of ControlBits
2312 // both loopback enables are always set to FALSE
2314 ControlBits
.HardwareLoopBack
= FALSE
;
2315 ControlBits
.SoftwareLoopBack
= FALSE
;
2317 // check for hardware flow control
2319 if ((Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) == EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
2320 ControlBits
.HardwareFlowControl
= TRUE
;
2322 ControlBits
.HardwareFlowControl
= FALSE
;
2325 // check for DTR enabled
2327 if ((Control
& EFI_SERIAL_DATA_TERMINAL_READY
) == EFI_SERIAL_DATA_TERMINAL_READY
) {
2328 ControlBits
.DtrState
= TRUE
;
2330 ControlBits
.DtrState
= FALSE
;
2333 // check for RTS enabled
2335 if ((Control
& EFI_SERIAL_REQUEST_TO_SEND
) == EFI_SERIAL_REQUEST_TO_SEND
) {
2336 ControlBits
.RtsState
= TRUE
;
2338 ControlBits
.RtsState
= FALSE
;
2342 // set the control values with a call to SetControlBitsInternal()
2344 Status
= SetControlBitsInternal (UsbSerialDevice
, &ControlBits
);
2350 calls SetAttributesInternal() to set the baud rate, receive FIFO depth,
2351 transmit/receive time out, parity, data buts, and stop bits on a serial
2354 @param This[in] Protocol instance pointer.
2355 @param BaudRate[in] The requested baud rate. A BaudRate value of 0
2356 will use the device's default interface speed.
2357 @param ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
2358 side of the serial interface. A ReceiveFifoDepth
2359 value of 0 will use the device's default FIFO
2361 @param Timeout[in] The requested time out for a single character in
2362 microseconds.This timeout applies to both the
2363 transmit and receive side of the interface. A
2364 Timeout value of 0 will use the device's default
2366 @param Parity[in] The type of parity to use on this serial device.
2367 A Parity value of DefaultParity will use the
2368 device's default parity value.
2369 @param DataBits[in] The number of data bits to use on the serial
2370 device. A DataBit vaule of 0 will use the
2371 device's default data bit setting.
2372 @param StopBits[in] The number of stop bits to use on this serial
2373 device. A StopBits value of DefaultStopBits will
2374 use the device's default number of stop bits.
2376 @retval EFI_SUCCESS The attributes were set
2377 @retval EFI_DEVICE_ERROR The attributes were not able to be
2383 IN EFI_SERIAL_IO_PROTOCOL
*This
,
2385 IN UINT32 ReceiveFifoDepth
,
2387 IN EFI_PARITY_TYPE Parity
,
2389 IN EFI_STOP_BITS_TYPE StopBits
2394 USB_SER_DEV
*UsbSerialDevice
;
2396 UsbSerialDevice
= USB_SER_DEV_FROM_THIS (This
);
2398 Status
= SetAttributesInternal (
2407 if (EFI_ERROR (Status
)) {
2416 Retrieves the status of the control bits on a serial device.
2418 @param This[in] Protocol instance pointer.
2419 @param Control[out] A pointer to return the current Control signals
2420 from the serial device.
2422 @retval EFI_SUCCESS The control bits were read from the serial
2424 @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
2430 IN EFI_SERIAL_IO_PROTOCOL
*This
,
2434 USB_SER_DEV
*UsbSerialDevice
;
2437 UsbSerialDevice
= USB_SER_DEV_FROM_THIS (This
);
2441 Status
= GetControlBitsInternal (UsbSerialDevice
, Control
);
2443 if (EFI_ERROR (Status
)) {
2444 return EFI_DEVICE_ERROR
;
2450 Reads data from a serial device.
2452 @param This[in] Protocol instance pointer.
2453 @param BufferSize[in, out] On input, the size of the Buffer. On output,
2454 the amount of data returned in Buffer.
2455 @param Buffer[out] The buffer to return the data into.
2457 @retval EFI_SUCCESS The data was read.
2458 @retval EFI_DEVICE_ERROR The device reported an error.
2459 @retval EFI_TIMEOUT The data write was stopped due to a timeout.
2465 IN EFI_SERIAL_IO_PROTOCOL
*This
,
2466 IN OUT UINTN
*BufferSize
,
2471 UINTN RemainingCallerBufferSize
;
2472 USB_SER_DEV
*UsbSerialDevice
;
2476 if (*BufferSize
== 0) {
2480 if (Buffer
== NULL
) {
2481 return EFI_DEVICE_ERROR
;
2484 Status
= EFI_SUCCESS
;
2485 UsbSerialDevice
= USB_SER_DEV_FROM_THIS (This
);
2488 // Clear out any data that we already have in our internal buffer
2490 for (Index
= 0; Index
< *BufferSize
; Index
++) {
2491 if (UsbSerialDevice
->DataBufferHead
== UsbSerialDevice
->DataBufferTail
) {
2496 // Still have characters in the buffer to return
2498 ((UINT8
*)Buffer
)[Index
] = UsbSerialDevice
->DataBuffer
[UsbSerialDevice
->DataBufferHead
];
2499 UsbSerialDevice
->DataBufferHead
= (UsbSerialDevice
->DataBufferHead
+ 1) % SW_FIFO_DEPTH
;
2503 // If we haven't filled the caller's buffer using data that we already had on
2504 // hand We need to generate an additional USB request to try and fill the
2507 if (Index
!= *BufferSize
) {
2508 RemainingCallerBufferSize
= *BufferSize
- Index
;
2509 Status
= ReadDataFromUsb (
2511 &RemainingCallerBufferSize
,
2512 (VOID
*)(((CHAR8
*)Buffer
) + Index
)
2514 if (!EFI_ERROR (Status
)) {
2515 *BufferSize
= RemainingCallerBufferSize
+ Index
;
2517 *BufferSize
= Index
;
2521 if (UsbSerialDevice
->DataBufferHead
== UsbSerialDevice
->DataBufferTail
) {
2523 // Data buffer has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY flag
2525 UsbSerialDevice
->ControlBits
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
2528 // There is some leftover data, clear EFI_SERIAL_INPUT_BUFFER_EMPTY flag
2530 UsbSerialDevice
->ControlBits
&= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY
);
2536 Writes data to a serial device.
2538 @param This[in] Protocol instance pointer.
2539 @param BufferSize[in, out] On input, the size of the Buffer. On output,
2540 the amount of data actually written.
2541 @param Buffer[in] The buffer of data to write
2543 @retval EFI_SUCCESS The data was written.
2544 @retval EFI_DEVICE_ERROR The device reported an error.
2545 @retval EFI_TIMEOUT The data write was stopped due to a timeout.
2551 IN EFI_SERIAL_IO_PROTOCOL
*This
,
2552 IN OUT UINTN
*BufferSize
,
2557 USB_SER_DEV
*UsbSerialDevice
;
2560 UsbSerialDevice
= USB_SER_DEV_FROM_THIS (This
);
2562 if (UsbSerialDevice
->Shutdown
) {
2563 return EFI_DEVICE_ERROR
;
2566 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
2568 Status
= UsbSerialDataTransfer (
2576 gBS
->RestoreTPL (Tpl
);
2577 if (EFI_ERROR (Status
)) {
2578 if (Status
== EFI_TIMEOUT
){
2581 return EFI_DEVICE_ERROR
;