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