]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/DebugPortDxe/DebugPort.c
Clean up: update "EFI" to "UEFI" if applicable.
[mirror_edk2.git] / MdeModulePkg / Universal / DebugPortDxe / DebugPort.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 DebugPort.c
15
16 Abstract:
17
18 Top level C file for debugport driver. Contains initialization function.
19 This driver layers on top of SerialIo.
20
21 ALL CODE IN THE SERIALIO STACK MUST BE RE-ENTRANT AND CALLABLE FROM
22 INTERRUPT CONTEXT.
23
24 Revision History
25
26 --*/
27
28
29 #include "DebugPort.h"
30
31 //
32 // Misc. functions local to this module..
33 //
34 STATIC
35 VOID
36 GetDebugPortVariable (
37 DEBUGPORT_DEVICE *DebugPortDevice
38 )
39 /*++
40
41 Routine Description:
42 Local worker function to obtain device path information from DebugPort variable.
43 Records requested settings in DebugPort device structure.
44
45 Arguments:
46 DEBUGPORT_DEVICE *DebugPortDevice,
47
48 Returns:
49
50 Nothing
51
52 --*/
53 {
54 UINTN DataSize;
55 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
56 EFI_STATUS Status;
57
58 DataSize = 0;
59
60 Status = gRT->GetVariable (
61 (CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,
62 &gEfiDebugPortVariableGuid,
63 NULL,
64 &DataSize,
65 DebugPortDevice->DebugPortVariable
66 );
67
68 if (Status == EFI_BUFFER_TOO_SMALL) {
69 if (gDebugPortDevice->DebugPortVariable != NULL) {
70 FreePool (gDebugPortDevice->DebugPortVariable);
71 }
72
73 DebugPortDevice->DebugPortVariable = AllocatePool (DataSize);
74 if (DebugPortDevice->DebugPortVariable != NULL) {
75 gRT->GetVariable (
76 (CHAR16 *) EFI_DEBUGPORT_VARIABLE_NAME,
77 &gEfiDebugPortVariableGuid,
78 NULL,
79 &DataSize,
80 DebugPortDevice->DebugPortVariable
81 );
82 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DebugPortDevice->DebugPortVariable;
83 while (!EfiIsDevicePathEnd (DevicePath) && !EfiIsUartDevicePath (DevicePath)) {
84 DevicePath = EfiNextDevicePathNode (DevicePath);
85 }
86
87 if (EfiIsDevicePathEnd (DevicePath)) {
88 FreePool (gDebugPortDevice->DebugPortVariable);
89 DebugPortDevice->DebugPortVariable = NULL;
90 } else {
91 CopyMem (
92 &DebugPortDevice->BaudRate,
93 &((UART_DEVICE_PATH *) DevicePath)->BaudRate,
94 sizeof (((UART_DEVICE_PATH *) DevicePath)->BaudRate)
95 );
96 DebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
97 DebugPortDevice->Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;
98 CopyMem (
99 &DebugPortDevice->Parity,
100 &((UART_DEVICE_PATH *) DevicePath)->Parity,
101 sizeof (((UART_DEVICE_PATH *) DevicePath)->Parity)
102 );
103 CopyMem (
104 &DebugPortDevice->DataBits,
105 &((UART_DEVICE_PATH *) DevicePath)->DataBits,
106 sizeof (((UART_DEVICE_PATH *) DevicePath)->DataBits)
107 );
108 CopyMem (
109 &DebugPortDevice->StopBits,
110 &((UART_DEVICE_PATH *) DevicePath)->StopBits,
111 sizeof (((UART_DEVICE_PATH *) DevicePath)->StopBits)
112 );
113 }
114 }
115 }
116 }
117
118 //
119 // Globals
120 //
121
122 EFI_DRIVER_BINDING_PROTOCOL gDebugPortDriverBinding = {
123 DebugPortSupported,
124 DebugPortStart,
125 DebugPortStop,
126 DEBUGPORT_DRIVER_VERSION,
127 NULL,
128 NULL
129 };
130
131 DEBUGPORT_DEVICE *gDebugPortDevice;
132
133 //
134 // implementation code
135 //
136
137 EFI_STATUS
138 EFIAPI
139 InitializeDebugPortDriver (
140 IN EFI_HANDLE ImageHandle,
141 IN EFI_SYSTEM_TABLE *SystemTable
142 )
143 /*++
144
145 Routine Description:
146 Driver entry point. Reads DebugPort variable to determine what device and settings
147 to use as the debug port. Binds exclusively to SerialIo. Reverts to defaults \
148 if no variable is found.
149
150 Creates debugport and devicepath protocols on new handle.
151
152 Arguments:
153 ImageHandle,
154 SystemTable
155
156 Returns:
157
158 EFI_UNSUPPORTED
159 EFI_OUT_OF_RESOURCES
160
161 --*/
162 {
163 EFI_STATUS Status;
164
165 //
166 // Install driver model protocol(s).
167 //
168 Status = EfiLibInstallDriverBindingComponentName2 (
169 ImageHandle,
170 SystemTable,
171 &gDebugPortDriverBinding,
172 ImageHandle,
173 &gDebugPortComponentName,
174 &gDebugPortComponentName2
175 );
176 ASSERT_EFI_ERROR (Status);
177 //
178 // Allocate and Initialize dev structure
179 //
180 gDebugPortDevice = AllocateZeroPool (sizeof (DEBUGPORT_DEVICE));
181 if (gDebugPortDevice == NULL) {
182 return EFI_OUT_OF_RESOURCES;
183 }
184 //
185 // Fill in static and default pieces of device structure first.
186 //
187 gDebugPortDevice->Signature = DEBUGPORT_DEVICE_SIGNATURE;
188
189 gDebugPortDevice->DebugPortInterface.Reset = DebugPortReset;
190 gDebugPortDevice->DebugPortInterface.Read = DebugPortRead;
191 gDebugPortDevice->DebugPortInterface.Write = DebugPortWrite;
192 gDebugPortDevice->DebugPortInterface.Poll = DebugPortPoll;
193
194 gDebugPortDevice->BaudRate = DEBUGPORT_UART_DEFAULT_BAUDRATE;
195 gDebugPortDevice->ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
196 gDebugPortDevice->Timeout = DEBUGPORT_UART_DEFAULT_TIMEOUT;
197 gDebugPortDevice->Parity = (EFI_PARITY_TYPE) DEBUGPORT_UART_DEFAULT_PARITY;
198 gDebugPortDevice->DataBits = DEBUGPORT_UART_DEFAULT_DATA_BITS;
199 gDebugPortDevice->StopBits = (EFI_STOP_BITS_TYPE) DEBUGPORT_UART_DEFAULT_STOP_BITS;
200
201 return EFI_SUCCESS;
202 }
203 //
204 // DebugPort driver binding member functions...
205 //
206 EFI_STATUS
207 EFIAPI
208 DebugPortSupported (
209 IN EFI_DRIVER_BINDING_PROTOCOL *This,
210 IN EFI_HANDLE ControllerHandle,
211 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
212 )
213 /*++
214
215 Routine Description:
216 Checks to see that there's not already a DebugPort interface somewhere. If so,
217 fail.
218
219 If there's a DEBUGPORT variable, the device path must match exactly. If there's
220 no DEBUGPORT variable, then device path is not checked and does not matter.
221
222 Checks to see that there's a serial io interface on the controller handle
223 that can be bound BY_DRIVER | EXCLUSIVE.
224
225 If all these tests succeed, then we return EFI_SUCCESS, else, EFI_UNSUPPORTED
226 or other error returned by OpenProtocol.
227
228 Arguments:
229 This
230 ControllerHandle
231 RemainingDevicePath
232
233 Returns:
234 EFI_UNSUPPORTED
235 EFI_OUT_OF_RESOURCES
236 EFI_SUCCESS
237
238 --*/
239 {
240 EFI_STATUS Status;
241 EFI_DEVICE_PATH_PROTOCOL *Dp1;
242 EFI_DEVICE_PATH_PROTOCOL *Dp2;
243 EFI_SERIAL_IO_PROTOCOL *SerialIo;
244 EFI_DEBUGPORT_PROTOCOL *DebugPortInterface;
245 EFI_HANDLE TempHandle;
246
247 //
248 // Check to see that there's not a debugport protocol already published
249 //
250 if (gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **) &DebugPortInterface) != EFI_NOT_FOUND) {
251 return EFI_UNSUPPORTED;
252 }
253 //
254 // Read DebugPort variable to determine debug port selection and parameters
255 //
256 GetDebugPortVariable (gDebugPortDevice);
257
258 if (gDebugPortDevice->DebugPortVariable != NULL) {
259 //
260 // There's a DEBUGPORT variable, so do LocateDevicePath and check to see if
261 // the closest matching handle matches the controller handle, and if it does,
262 // check to see that the remaining device path has the DebugPort GUIDed messaging
263 // device path only. Otherwise, it's a mismatch and EFI_UNSUPPORTED is returned.
264 //
265 Dp1 = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) gDebugPortDevice->DebugPortVariable);
266 if (Dp1 == NULL) {
267 return EFI_OUT_OF_RESOURCES;
268 }
269
270 Dp2 = Dp1;
271
272 Status = gBS->LocateDevicePath (
273 &gEfiSerialIoProtocolGuid,
274 &Dp2,
275 &TempHandle
276 );
277
278 if (Status == EFI_SUCCESS && TempHandle != ControllerHandle) {
279 Status = EFI_UNSUPPORTED;
280 }
281
282 if (Status == EFI_SUCCESS && (Dp2->Type != 3 || Dp2->SubType != 10 || *((UINT16 *) Dp2->Length) != 20)) {
283 Status = EFI_UNSUPPORTED;
284 }
285
286 if (Status == EFI_SUCCESS && CompareMem (&gEfiDebugPortDevicePathGuid, Dp2 + 1, sizeof (EFI_GUID))) {
287 Status = EFI_UNSUPPORTED;
288 }
289
290 FreePool (Dp1);
291 if (EFI_ERROR (Status)) {
292 return Status;
293 }
294 }
295
296 Status = gBS->OpenProtocol (
297 ControllerHandle,
298 &gEfiSerialIoProtocolGuid,
299 (VOID **) &SerialIo,
300 This->DriverBindingHandle,
301 ControllerHandle,
302 EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
303 );
304 if (EFI_ERROR (Status)) {
305 return Status;
306 }
307
308 gBS->CloseProtocol (
309 ControllerHandle,
310 &gEfiSerialIoProtocolGuid,
311 This->DriverBindingHandle,
312 ControllerHandle
313 );
314
315 return EFI_SUCCESS;
316 }
317
318 EFI_STATUS
319 EFIAPI
320 DebugPortStart (
321 IN EFI_DRIVER_BINDING_PROTOCOL *This,
322 IN EFI_HANDLE ControllerHandle,
323 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
324 )
325 /*++
326
327 Routine Description:
328 Binds exclusively to serial io on the controller handle. Produces DebugPort
329 protocol and DevicePath on new handle.
330
331 Arguments:
332 This
333 ControllerHandle
334 RemainingDevicePath
335
336 Returns:
337 EFI_OUT_OF_RESOURCES
338 EFI_SUCCESS
339 --*/
340 {
341 EFI_STATUS Status;
342 DEBUGPORT_DEVICE_PATH DebugPortDP;
343 EFI_DEVICE_PATH_PROTOCOL EndDP;
344 EFI_DEVICE_PATH_PROTOCOL *Dp1;
345
346 Status = gBS->OpenProtocol (
347 ControllerHandle,
348 &gEfiSerialIoProtocolGuid,
349 (VOID **) &gDebugPortDevice->SerialIoBinding,
350 This->DriverBindingHandle,
351 ControllerHandle,
352 EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
353 );
354 if (EFI_ERROR (Status)) {
355 return Status;
356 }
357
358 gDebugPortDevice->SerialIoDeviceHandle = ControllerHandle;
359
360 //
361 // Initialize the Serial Io interface...
362 //
363 Status = gDebugPortDevice->SerialIoBinding->SetAttributes (
364 gDebugPortDevice->SerialIoBinding,
365 gDebugPortDevice->BaudRate,
366 gDebugPortDevice->ReceiveFifoDepth,
367 gDebugPortDevice->Timeout,
368 gDebugPortDevice->Parity,
369 gDebugPortDevice->DataBits,
370 gDebugPortDevice->StopBits
371 );
372 if (EFI_ERROR (Status)) {
373 gDebugPortDevice->BaudRate = 0;
374 gDebugPortDevice->Parity = DefaultParity;
375 gDebugPortDevice->DataBits = 0;
376 gDebugPortDevice->StopBits = DefaultStopBits;
377 gDebugPortDevice->ReceiveFifoDepth = 0;
378 Status = gDebugPortDevice->SerialIoBinding->SetAttributes (
379 gDebugPortDevice->SerialIoBinding,
380 gDebugPortDevice->BaudRate,
381 gDebugPortDevice->ReceiveFifoDepth,
382 gDebugPortDevice->Timeout,
383 gDebugPortDevice->Parity,
384 gDebugPortDevice->DataBits,
385 gDebugPortDevice->StopBits
386 );
387 if (EFI_ERROR (Status)) {
388 gBS->CloseProtocol (
389 ControllerHandle,
390 &gEfiSerialIoProtocolGuid,
391 This->DriverBindingHandle,
392 ControllerHandle
393 );
394 return Status;
395 }
396 }
397
398 gDebugPortDevice->SerialIoBinding->Reset (gDebugPortDevice->SerialIoBinding);
399
400 //
401 // Create device path instance for DebugPort
402 //
403 DebugPortDP.Header.Type = MESSAGING_DEVICE_PATH;
404 DebugPortDP.Header.SubType = MSG_VENDOR_DP;
405 SetDevicePathNodeLength (&(DebugPortDP.Header), sizeof (DebugPortDP));
406 CopyMem (&DebugPortDP.Guid, &gEfiDebugPortDevicePathGuid, sizeof (EFI_GUID));
407
408 Dp1 = DevicePathFromHandle (ControllerHandle);
409 if (Dp1 == NULL) {
410 Dp1 = &EndDP;
411 SetDevicePathEndNode (Dp1);
412 }
413
414 gDebugPortDevice->DebugPortDevicePath = AppendDevicePathNode (Dp1, (EFI_DEVICE_PATH_PROTOCOL *) &DebugPortDP);
415 if (gDebugPortDevice->DebugPortDevicePath == NULL) {
416 return EFI_OUT_OF_RESOURCES;
417 }
418 //
419 // Publish DebugPort and Device Path protocols
420 //
421 Status = gBS->InstallMultipleProtocolInterfaces (
422 &gDebugPortDevice->DebugPortDeviceHandle,
423 &gEfiDevicePathProtocolGuid,
424 gDebugPortDevice->DebugPortDevicePath,
425 &gEfiDebugPortProtocolGuid,
426 &gDebugPortDevice->DebugPortInterface,
427 NULL
428 );
429
430 if (EFI_ERROR (Status)) {
431 gBS->CloseProtocol (
432 ControllerHandle,
433 &gEfiSerialIoProtocolGuid,
434 This->DriverBindingHandle,
435 ControllerHandle
436 );
437 return Status;
438 }
439 //
440 // Connect debugport child to serial io
441 //
442 Status = gBS->OpenProtocol (
443 ControllerHandle,
444 &gEfiSerialIoProtocolGuid,
445 (VOID **) &gDebugPortDevice->SerialIoBinding,
446 This->DriverBindingHandle,
447 gDebugPortDevice->DebugPortDeviceHandle,
448 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
449 );
450
451 if (EFI_ERROR (Status)) {
452 DEBUG_CODE_BEGIN ();
453 UINTN BufferSize;
454
455 BufferSize = 48;
456 DebugPortWrite (
457 &gDebugPortDevice->DebugPortInterface,
458 0,
459 &BufferSize,
460 "DebugPort driver failed to open child controller\n\n"
461 );
462 DEBUG_CODE_END ();
463
464 gBS->CloseProtocol (
465 ControllerHandle,
466 &gEfiSerialIoProtocolGuid,
467 This->DriverBindingHandle,
468 ControllerHandle
469 );
470 return Status;
471 }
472
473 DEBUG_CODE_BEGIN ();
474 UINTN BufferSize;
475
476 BufferSize = 38;
477 DebugPortWrite (
478 &gDebugPortDevice->DebugPortInterface,
479 0,
480 &BufferSize,
481 "Hello World from the DebugPort driver\n\n"
482 );
483 DEBUG_CODE_END ();
484
485 return EFI_SUCCESS;
486 }
487
488 EFI_STATUS
489 EFIAPI
490 DebugPortStop (
491 IN EFI_DRIVER_BINDING_PROTOCOL *This,
492 IN EFI_HANDLE ControllerHandle,
493 IN UINTN NumberOfChildren,
494 IN EFI_HANDLE *ChildHandleBuffer
495 )
496 /*++
497
498 Routine Description:
499 We're never intending to be stopped via the driver model so this just returns
500 EFI_UNSUPPORTED
501
502 Arguments:
503 Per UEFI 2.0 driver model
504
505 Returns:
506 EFI_UNSUPPORTED
507 EFI_SUCCESS
508
509 --*/
510 {
511 EFI_STATUS Status;
512
513 if (NumberOfChildren == 0) {
514 //
515 // Close the bus driver
516 //
517 gBS->CloseProtocol (
518 ControllerHandle,
519 &gEfiSerialIoProtocolGuid,
520 This->DriverBindingHandle,
521 ControllerHandle
522 );
523
524 gDebugPortDevice->SerialIoBinding = NULL;
525
526 gBS->CloseProtocol (
527 ControllerHandle,
528 &gEfiDevicePathProtocolGuid,
529 This->DriverBindingHandle,
530 ControllerHandle
531 );
532
533 FreePool (gDebugPortDevice->DebugPortDevicePath);
534
535 return EFI_SUCCESS;
536 } else {
537 //
538 // Disconnect SerialIo child handle
539 //
540 Status = gBS->CloseProtocol (
541 gDebugPortDevice->SerialIoDeviceHandle,
542 &gEfiSerialIoProtocolGuid,
543 This->DriverBindingHandle,
544 gDebugPortDevice->DebugPortDeviceHandle
545 );
546
547 if (EFI_ERROR (Status)) {
548 return Status;
549 }
550 //
551 // Unpublish our protocols (DevicePath, DebugPort)
552 //
553 Status = gBS->UninstallMultipleProtocolInterfaces (
554 gDebugPortDevice->DebugPortDeviceHandle,
555 &gEfiDevicePathProtocolGuid,
556 gDebugPortDevice->DebugPortDevicePath,
557 &gEfiDebugPortProtocolGuid,
558 &gDebugPortDevice->DebugPortInterface,
559 NULL
560 );
561
562 if (EFI_ERROR (Status)) {
563 gBS->OpenProtocol (
564 ControllerHandle,
565 &gEfiSerialIoProtocolGuid,
566 (VOID **) &gDebugPortDevice->SerialIoBinding,
567 This->DriverBindingHandle,
568 gDebugPortDevice->DebugPortDeviceHandle,
569 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
570 );
571 } else {
572 gDebugPortDevice->DebugPortDeviceHandle = NULL;
573 }
574 }
575
576 return Status;
577 }
578 //
579 // Debugport protocol member functions
580 //
581 EFI_STATUS
582 EFIAPI
583 DebugPortReset (
584 IN EFI_DEBUGPORT_PROTOCOL *This
585 )
586 /*++
587
588 Routine Description:
589 DebugPort protocol member function. Calls SerialIo:GetControl to flush buffer.
590 We cannot call SerialIo:SetAttributes because it uses pool services, which use
591 locks, which affect TPL, so it's not interrupt context safe or re-entrant.
592 SerialIo:Reset() calls SetAttributes, so it can't be used either.
593
594 The port itself should be fine since it was set up during initialization.
595
596 Arguments:
597 This
598
599 Returns:
600
601 EFI_SUCCESS
602
603 --*/
604 {
605 UINTN BufferSize;
606 UINTN BitBucket;
607
608 while (This->Poll (This) == EFI_SUCCESS) {
609 BufferSize = 1;
610 This->Read (This, 0, &BufferSize, &BitBucket);
611 }
612
613 return EFI_SUCCESS;
614 }
615
616 EFI_STATUS
617 EFIAPI
618 DebugPortRead (
619 IN EFI_DEBUGPORT_PROTOCOL *This,
620 IN UINT32 Timeout,
621 IN OUT UINTN *BufferSize,
622 IN VOID *Buffer
623 )
624 /*++
625
626 Routine Description:
627 DebugPort protocol member function. Calls SerialIo:Read() after setting
628 if it's different than the last SerialIo access.
629
630 Arguments:
631 IN EFI_DEBUGPORT_PROTOCOL *This
632 IN UINT32 Timeout,
633 IN OUT UINTN *BufferSize,
634 IN VOID *Buffer
635
636 Returns:
637
638 EFI_STATUS
639
640 --*/
641 {
642 DEBUGPORT_DEVICE *DebugPortDevice;
643 UINTN LocalBufferSize;
644 EFI_STATUS Status;
645 UINT8 *BufferPtr;
646
647 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
648 BufferPtr = Buffer;
649 LocalBufferSize = *BufferSize;
650 do {
651 Status = DebugPortDevice->SerialIoBinding->Read (
652 DebugPortDevice->SerialIoBinding,
653 &LocalBufferSize,
654 BufferPtr
655 );
656 if (Status == EFI_TIMEOUT) {
657 if (Timeout > DEBUGPORT_UART_DEFAULT_TIMEOUT) {
658 Timeout -= DEBUGPORT_UART_DEFAULT_TIMEOUT;
659 } else {
660 Timeout = 0;
661 }
662 } else if (EFI_ERROR (Status)) {
663 break;
664 }
665
666 BufferPtr += LocalBufferSize;
667 LocalBufferSize = *BufferSize - (BufferPtr - (UINT8 *) Buffer);
668 } while (LocalBufferSize != 0 && Timeout > 0);
669
670 *BufferSize = (UINTN) (BufferPtr - (UINT8 *) Buffer);
671
672 return Status;
673 }
674
675 EFI_STATUS
676 EFIAPI
677 DebugPortWrite (
678 IN EFI_DEBUGPORT_PROTOCOL *This,
679 IN UINT32 Timeout,
680 IN OUT UINTN *BufferSize,
681 OUT VOID *Buffer
682 )
683 /*++
684
685 Routine Description:
686 DebugPort protocol member function. Calls SerialIo:Write() Writes 8 bytes at
687 a time and does a GetControl between 8 byte writes to help insure reads are
688 interspersed This is poor-man's flow control..
689
690 Arguments:
691 This - Pointer to DebugPort protocol
692 Timeout - Timeout value
693 BufferSize - On input, the size of Buffer.
694 On output, the amount of data actually written.
695 Buffer - Pointer to buffer to write
696
697 Returns:
698 EFI_SUCCESS - The data was written.
699 EFI_DEVICE_ERROR - The device reported an error.
700 EFI_TIMEOUT - The data write was stopped due to a timeout.
701
702 --*/
703 {
704 DEBUGPORT_DEVICE *DebugPortDevice;
705 UINTN Position;
706 UINTN WriteSize;
707 EFI_STATUS Status;
708 UINT32 SerialControl;
709
710 Status = EFI_SUCCESS;
711 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
712
713 WriteSize = 8;
714 for (Position = 0; Position < *BufferSize && !EFI_ERROR (Status); Position += WriteSize) {
715 DebugPortDevice->SerialIoBinding->GetControl (
716 DebugPortDevice->SerialIoBinding,
717 &SerialControl
718 );
719 if (*BufferSize - Position < 8) {
720 WriteSize = *BufferSize - Position;
721 }
722
723 Status = DebugPortDevice->SerialIoBinding->Write (
724 DebugPortDevice->SerialIoBinding,
725 &WriteSize,
726 &((UINT8 *) Buffer)[Position]
727 );
728 }
729
730 *BufferSize = Position;
731 return Status;
732 }
733
734 EFI_STATUS
735 EFIAPI
736 DebugPortPoll (
737 IN EFI_DEBUGPORT_PROTOCOL *This
738 )
739 /*++
740
741 Routine Description:
742 DebugPort protocol member function. Calls SerialIo:Write() after setting
743 if it's different than the last SerialIo access.
744
745 Arguments:
746 IN EFI_DEBUGPORT_PROTOCOL *This
747
748 Returns:
749 EFI_SUCCESS - At least 1 character is ready to be read from the DebugPort interface
750 EFI_NOT_READY - There are no characters ready to read from the DebugPort interface
751 EFI_DEVICE_ERROR - A hardware failure occured... (from SerialIo)
752
753 --*/
754 {
755 EFI_STATUS Status;
756 UINT32 SerialControl;
757 DEBUGPORT_DEVICE *DebugPortDevice;
758
759 DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
760
761 Status = DebugPortDevice->SerialIoBinding->GetControl (
762 DebugPortDevice->SerialIoBinding,
763 &SerialControl
764 );
765
766 if (!EFI_ERROR (Status)) {
767 if (SerialControl & EFI_SERIAL_INPUT_BUFFER_EMPTY) {
768 Status = EFI_NOT_READY;
769 } else {
770 Status = EFI_SUCCESS;
771 }
772 }
773
774 return Status;
775 }
776
777 EFI_STATUS
778 EFIAPI
779 ImageUnloadHandler (
780 EFI_HANDLE ImageHandle
781 )
782 /*++
783
784 Routine Description:
785 Unload function that is registered in the LoadImage protocol. It un-installs
786 protocols produced and deallocates pool used by the driver. Called by the core
787 when unloading the driver.
788
789 Arguments:
790 EFI_HANDLE ImageHandle
791
792 Returns:
793
794 EFI_SUCCESS
795
796 --*/
797 {
798 EFI_STATUS Status;
799
800 if (gDebugPortDevice->SerialIoBinding != NULL) {
801 return EFI_ABORTED;
802 }
803
804 Status = gBS->UninstallMultipleProtocolInterfaces (
805 ImageHandle,
806 &gEfiDriverBindingProtocolGuid,
807 &gDebugPortDevice->DriverBindingInterface,
808 &gEfiComponentNameProtocolGuid,
809 &gDebugPortDevice->ComponentNameInterface,
810 NULL
811 );
812
813 if (EFI_ERROR (Status)) {
814 return Status;
815 }
816 //
817 // Clean up allocations
818 //
819 if (gDebugPortDevice->DebugPortVariable != NULL) {
820 FreePool (gDebugPortDevice->DebugPortVariable);
821 }
822
823 FreePool (gDebugPortDevice);
824
825 return EFI_SUCCESS;
826 }