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