]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/Uefi/Devices/Console/daConsole.c
Add Socket Libraries.
[mirror_edk2.git] / StdLib / LibC / Uefi / Devices / Console / daConsole.c
CommitLineData
53e1e5c6 1/** @file\r
2 Abstract device driver for the UEFI Console.\r
3\r
4 Manipulates abstractions for stdin, stdout, stderr.\r
5\r
6 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
7 This program and the accompanying materials are licensed and made available under\r
8 the terms and conditions of the BSD License that accompanies this distribution.\r
9 The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php.\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16#include <Uefi.h>\r
17#include <Library/BaseLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
20#include <Protocol/SimpleTextIn.h>\r
21#include <Protocol/SimpleTextOut.h>\r
22\r
23#include <LibConfig.h>\r
24#include <sys/EfiSysCall.h>\r
25\r
26#include <errno.h>\r
27#include <wctype.h>\r
28#include <wchar.h>\r
29#include <sys/fcntl.h>\r
30#include <kfile.h>\r
31#include <Device/Device.h>\r
32#include <MainData.h>\r
33\r
34static const CHAR16* const\r
35stdioNames[NUM_SPECIAL] = {\r
36 L"stdin:", L"stdout:", L"stderr:"\r
37};\r
38\r
39static const int stdioFlags[NUM_SPECIAL] = {\r
40 O_RDONLY, // stdin\r
41 O_WRONLY, // stdout\r
42 O_WRONLY // stderr\r
43};\r
44\r
45static DeviceNode *ConNode[NUM_SPECIAL];\r
46static ConInstance *ConInstanceList;\r
47\r
d7ce7006 48static wchar_t *ConReadBuf;\r
49\r
50/* Flags settable by Ioctl */\r
51static BOOLEAN TtyCooked;\r
52static BOOLEAN TtyEcho;\r
53\r
53e1e5c6 54ssize_t\r
55WideTtyCvt( CHAR16 *dest, const char *buf, size_t n)\r
56{\r
57 UINTN i;\r
58 wint_t wc;\r
59\r
60 for(i = 0; i < n; ++i) {\r
61 wc = btowc(*buf++);\r
62 if( wc == 0) {\r
63 break;\r
64 };\r
65 if(wc < 0) {\r
66 wc = BLOCKELEMENT_LIGHT_SHADE;\r
67 }\r
68 if(wc == L'\n') {\r
69 *dest++ = L'\r';\r
70 }\r
71 *dest++ = (CHAR16)wc;\r
72 }\r
73 *dest = 0;\r
74 return (ssize_t)i;\r
75}\r
76\r
77static\r
78int\r
79EFIAPI\r
80da_ConClose(\r
81 IN struct __filedes *filp\r
82)\r
83{\r
84 ConInstance *Stream;\r
85\r
86 Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
87 // Quick check to see if Stream looks reasonable\r
88 if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'\r
89 EFIerrno = RETURN_INVALID_PARAMETER;\r
90 return -1; // Looks like a bad File Descriptor pointer\r
91 }\r
92 gMD->StdIo[Stream->InstanceNum] = NULL; // Mark the stream as closed\r
93 return RETURN_SUCCESS;\r
94}\r
95\r
96static\r
97off_t\r
98EFIAPI\r
99da_ConSeek(\r
100 struct __filedes *filp,\r
101 off_t Position,\r
102 int whence ///< Ignored by Console\r
103)\r
104{\r
105 ConInstance *Stream;\r
106 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;\r
107 XYoffset CursorPos;\r
108\r
109 Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
110 // Quick check to see if Stream looks reasonable\r
111 if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'\r
112 EFIerrno = RETURN_INVALID_PARAMETER;\r
113 return -1; // Looks like a bad This pointer\r
114 }\r
115 if(Stream->InstanceNum == STDIN_FILENO) {\r
116 // Seek is not valid for stdin\r
117 EFIerrno = RETURN_UNSUPPORTED;\r
118 return -1;\r
119 }\r
120 // Everything is OK to do the final verification and "seek".\r
121 Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;\r
122 CursorPos.Offset = Position;\r
123\r
124 EFIerrno = Proto->SetCursorPosition(Proto,\r
125 (INTN)CursorPos.XYpos.Column,\r
126 (INTN)CursorPos.XYpos.Row);\r
127\r
128 if(RETURN_ERROR(EFIerrno)) {\r
129 return -1;\r
130 }\r
131 else {\r
132 return Position;\r
133 }\r
134}\r
135\r
53e1e5c6 136/* Write a NULL terminated WCS to the EFI console.\r
137\r
138 @param[in,out] BufferSize Number of bytes in Buffer. Set to zero if\r
139 the string couldn't be displayed.\r
140 @param[in] Buffer The WCS string to be displayed\r
141\r
142 @return The number of characters written.\r
143*/\r
144static\r
145ssize_t\r
146EFIAPI\r
147da_ConWrite(\r
148 IN struct __filedes *filp,\r
149 IN off_t *Position,\r
150 IN size_t BufferSize,\r
151 IN const void *Buffer\r
152 )\r
153{\r
154 EFI_STATUS Status;\r
155 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;\r
156 ConInstance *Stream;\r
157 ssize_t NumChar;\r
158 //XYoffset CursorPos;\r
159\r
160 Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
161 // Quick check to see if Stream looks reasonable\r
162 if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'\r
163 EFIerrno = RETURN_INVALID_PARAMETER;\r
164 return -1; // Looks like a bad This pointer\r
165 }\r
166 if(Stream->InstanceNum == STDIN_FILENO) {\r
167 // Write is not valid for stdin\r
168 EFIerrno = RETURN_UNSUPPORTED;\r
169 return -1;\r
170 }\r
171 // Everything is OK to do the write.\r
172 Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;\r
173\r
174 // Convert string from MBCS to WCS and translate \n to \r\n.\r
175 NumChar = WideTtyCvt(gMD->UString, (const char *)Buffer, BufferSize);\r
176 //if(NumChar > 0) {\r
177 // BufferSize = (size_t)(NumChar * sizeof(CHAR16));\r
178 //}\r
179 BufferSize = NumChar;\r
180\r
181 //if( Position != NULL) {\r
182 // CursorPos.Offset = (UINT64)*Position;\r
183\r
184 // Status = Proto->SetCursorPosition(Proto,\r
185 // (INTN)CursorPos.XYpos.Column,\r
186 // (INTN)CursorPos.XYpos.Row);\r
187 // if(RETURN_ERROR(Status)) {\r
188 // return -1;\r
189 // }\r
190 //}\r
191\r
192 // Send the Unicode buffer to the console\r
193 Status = Proto->OutputString( Proto, gMD->UString);\r
194 // Depending on status, update BufferSize and return\r
195 if(RETURN_ERROR(Status)) {\r
196 BufferSize = 0; // We don't really know how many characters made it out\r
197 }\r
198 else {\r
199 //BufferSize = NumChar;\r
200 Stream->NumWritten += NumChar;\r
201 }\r
202 EFIerrno = Status;\r
203 return BufferSize;\r
204}\r
205\r
d7ce7006 206/** Read characters from the console input device.\r
207\r
208 @param[in,out] filp Pointer to file descriptor for this file.\r
209 @param[in,out] offset Ignored.\r
210 @param[in] BufferSize Buffer size, in bytes.\r
211 @param[out] Buffer Buffer in which to place the read characters.\r
212\r
213 @return Number of bytes actually placed into Buffer.\r
214\r
215 @todo Handle encodings other than ASCII-7 and UEFI.\r
216**/\r
217static\r
218ssize_t\r
219EFIAPI\r
220da_ConRead(\r
221 IN OUT struct __filedes *filp,\r
222 IN OUT off_t *offset, // Console ignores this\r
223 IN size_t BufferSize,\r
224 OUT VOID *Buffer\r
225)\r
226{\r
227 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;\r
228 ConInstance *Stream;\r
229 wchar_t *OutPtr;\r
230 EFI_INPUT_KEY Key;\r
231 UINTN NumChar;\r
232 UINTN Edex;\r
233 EFI_STATUS Status = RETURN_SUCCESS;\r
234 UINTN i;\r
235 char EchoBuff[MB_CUR_MAX + 1];\r
236 int NumEcho;\r
237\r
238 Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
239 // Quick check to see if Stream looks reasonable\r
240 if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'\r
241 EFIerrno = RETURN_INVALID_PARAMETER;\r
242 return -1; // Looks like a bad This pointer\r
243 }\r
244 if(Stream->InstanceNum != STDIN_FILENO) {\r
245 // Read only valid for stdin\r
246 EFIerrno = RETURN_UNSUPPORTED;\r
247 return -1;\r
248 }\r
249 // It looks like things are OK for trying to read\r
250 // We will accumulate *BufferSize characters or until we encounter\r
251 // an "activation" character. Currently any control character.\r
252 Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;\r
253 OutPtr = ConReadBuf;\r
254 NumChar = (BufferSize > MAX_INPUT)? MAX_INPUT : BufferSize;\r
255 i = 0;\r
256 do {\r
257 if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {\r
258 Status = gBS->WaitForEvent( 1, &Proto->WaitForKey, &Edex);\r
259 if(Status != RETURN_SUCCESS) {\r
260 break;\r
261 }\r
262 Status = Proto->ReadKeyStroke(Proto, &Key);\r
263 if(Status != RETURN_SUCCESS) {\r
264 break;\r
265 }\r
266 }\r
267 else {\r
268 Key.ScanCode = Stream->UnGetKey.ScanCode;\r
269 Key.UnicodeChar = Stream->UnGetKey.UnicodeChar;\r
270 Stream->UnGetKey.ScanCode = SCAN_NULL;\r
271 Stream->UnGetKey.UnicodeChar = CHAR_NULL;\r
272 }\r
273 if(Key.ScanCode == SCAN_NULL) {\r
274 NumEcho = 0;\r
275 if(TtyCooked && (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {\r
276 *OutPtr++ = CHAR_LINEFEED;\r
277 NumEcho = wctomb(EchoBuff, CHAR_LINEFEED);\r
278 }\r
279 else {\r
280 *OutPtr++ = Key.UnicodeChar;\r
281 NumEcho = wctomb(EchoBuff, Key.UnicodeChar);\r
282 }\r
283 ++i;\r
284 EchoBuff[NumEcho] = 0; /* Terminate the Echo buffer */\r
285 if(TtyEcho) {\r
286 /* Echo the character just input */\r
287 da_ConWrite(&gMD->fdarray[STDOUT_FILENO], NULL, 2, EchoBuff);\r
288 }\r
289 }\r
290 if(iswcntrl(Key.UnicodeChar)) { // If a control character, or a scan code\r
291 break;\r
292 }\r
293 } while(i < NumChar);\r
294\r
295 *OutPtr = L'\0'; // Terminate the input buffer\r
296\r
297 /* Convert the input buffer and place in Buffer.\r
298 If the fully converted input buffer won't fit, write what will and\r
299 leave the rest in ConReadBuf with ConReadLeft indicating how many\r
300 unconverted characters remain in ConReadBuf.\r
301 */\r
302 NumEcho = (int)wcstombs(Buffer, ConReadBuf, BufferSize); /* Re-use NumEcho to hold number of bytes in Buffer */\r
303 /* More work needs to be done before locales other than C can be supported. */\r
304\r
305 EFIerrno = Status;\r
306 return (ssize_t)NumEcho; // Will be 0 if we didn't get a key\r
307}\r
308\r
53e1e5c6 309/** Console-specific helper function for the fstat() function.\r
310\r
311 st_size Set to number of characters read for stdin and number written for stdout and stderr.\r
312 st_physsize 1 for stdin, 0 if QueryMode error, else max X and Y coordinates for the current mode.\r
313 st_curpos 0 for stdin, current X & Y coordinates for stdout and stderr\r
314 st_blksize Set to 1 since this is a character device\r
315\r
316 All other members of the stat structure are left unchanged.\r
317**/\r
318static\r
319int\r
320EFIAPI\r
321da_ConStat(\r
322 struct __filedes *filp,\r
323 struct stat *Buffer,\r
324 void *Something\r
325 )\r
326{\r
327 ConInstance *Stream;\r
328 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Proto;\r
329 XYoffset CursorPos;\r
330 INT32 OutMode;\r
331 UINTN ModeCol;\r
332 UINTN ModeRow;\r
333\r
334// ConGetInfo\r
335 Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
336 // Quick check to see if Stream looks reasonable\r
337 if ((Stream->Cookie != CON_COOKIE) || // Cookie == 'IoAb'\r
338 (Buffer == NULL))\r
339 {\r
340 EFIerrno = RETURN_INVALID_PARAMETER;\r
341 return -1;\r
342 }\r
343 // All of our parameters are correct, so fill in the information.\r
344 Buffer->st_blksize = 1;\r
345\r
346// ConGetPosition\r
347 if(Stream->InstanceNum == STDIN_FILENO) {\r
348 // This is stdin\r
349 Buffer->st_curpos = 0;\r
350 Buffer->st_size = (off_t)Stream->NumRead;\r
351 Buffer->st_physsize = 1;\r
352 }\r
353 else {\r
354 Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)Stream->Dev;\r
355 CursorPos.XYpos.Column = (UINT32)Proto->Mode->CursorColumn;\r
356 CursorPos.XYpos.Row = (UINT32)Proto->Mode->CursorRow;\r
357 Buffer->st_curpos = (off_t)CursorPos.Offset;\r
358 Buffer->st_size = (off_t)Stream->NumWritten;\r
359\r
360 OutMode = Proto->Mode->Mode;\r
361 EFIerrno = Proto->QueryMode(Proto, (UINTN)OutMode, &ModeCol, &ModeRow);\r
362 if(RETURN_ERROR(EFIerrno)) {\r
363 Buffer->st_physsize = 0;\r
364 }\r
365 else {\r
366 CursorPos.XYpos.Column = (UINT32)ModeCol;\r
367 CursorPos.XYpos.Row = (UINT32)ModeRow;\r
368 Buffer->st_physsize = (off_t)CursorPos.Offset;\r
369 }\r
370 }\r
371 return 0;\r
372}\r
373\r
374static\r
375int\r
376EFIAPI\r
377da_ConIoctl(\r
378 struct __filedes *filp,\r
379 ULONGN cmd,\r
380 void *argp\r
381 )\r
382{\r
383 return -EPERM;\r
384}\r
385\r
386/** Open an abstract Console Device.\r
387**/\r
388int\r
389EFIAPI\r
390da_ConOpen(\r
d7ce7006 391 DeviceNode *DevNode,\r
53e1e5c6 392 struct __filedes *filp,\r
d7ce7006 393 int DevInstance, // Not used for console devices\r
53e1e5c6 394 wchar_t *Path, // Not used for console devices\r
d7ce7006 395 wchar_t *MPath // Not used for console devices\r
53e1e5c6 396 )\r
397{\r
398 ConInstance *Stream;\r
399\r
400 if((filp == NULL) ||\r
d7ce7006 401 (DevNode == NULL))\r
53e1e5c6 402 {\r
403 EFIerrno = RETURN_INVALID_PARAMETER;\r
404 return -1;\r
405 }\r
d7ce7006 406 Stream = (ConInstance *)DevNode->InstanceList;\r
53e1e5c6 407 // Quick check to see if Stream looks reasonable\r
408 if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'\r
409 EFIerrno = RETURN_INVALID_PARAMETER;\r
410 return -1; // Looks like a bad This pointer\r
411 }\r
d7ce7006 412 gMD->StdIo[Stream->InstanceNum] = Stream;\r
53e1e5c6 413 filp->f_iflags |= (S_IFREG | _S_IFCHR | _S_ICONSOLE);\r
414 filp->f_offset = 0;\r
415 filp->f_ops = &Stream->Abstraction;\r
416\r
417 return 0;\r
418}\r
419\r
420#include <sys/poll.h>\r
421/* Returns a bit mask describing which operations could be completed immediately.\r
422\r
423 (POLLIN | POLLRDNORM) A Unicode character is available to read\r
424 (POLLIN) A ScanCode is ready.\r
425 (POLLOUT) The device is ready for output - always set on stdout and stderr.\r
426\r
427*/\r
428static\r
429short\r
430EFIAPI\r
431da_ConPoll(\r
432 struct __filedes *filp,\r
433 short events\r
434 )\r
435{\r
436 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *Proto;\r
437 ConInstance *Stream;\r
438 EFI_STATUS Status = RETURN_SUCCESS;\r
439 short RdyMask = 0;\r
440\r
441 Stream = BASE_CR(filp->f_ops, ConInstance, Abstraction);\r
442 // Quick check to see if Stream looks reasonable\r
443 if(Stream->Cookie != CON_COOKIE) { // Cookie == 'IoAb'\r
444 EFIerrno = RETURN_INVALID_PARAMETER;\r
445 return POLLNVAL; // Looks like a bad filp pointer\r
446 }\r
447 if(Stream->InstanceNum == 0) {\r
448 // Only input is supported for this device\r
449 Proto = (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *)Stream->Dev;\r
450 if((Stream->UnGetKey.UnicodeChar == CHAR_NULL) && (Stream->UnGetKey.ScanCode == SCAN_NULL)) {\r
451 Status = Proto->ReadKeyStroke(Proto, &Stream->UnGetKey);\r
452 if(Status == RETURN_SUCCESS) {\r
453 RdyMask = POLLIN;\r
454 if(Stream->UnGetKey.UnicodeChar != CHAR_NULL) {\r
455 RdyMask |= POLLRDNORM;\r
456 }\r
457 }\r
458 else {\r
459 Stream->UnGetKey.ScanCode = SCAN_NULL;\r
460 Stream->UnGetKey.UnicodeChar = CHAR_NULL;\r
461 }\r
462 }\r
463 }\r
464 else if(Stream->InstanceNum < NUM_SPECIAL) { // Not 0, is it 1 or 2?\r
465 // Only output is supported for this device\r
466 RdyMask = POLLOUT;\r
467 }\r
468 else {\r
469 RdyMask = POLLERR; // Not one of the standard streams\r
470 }\r
471 EFIerrno = Status;\r
472\r
473 return (RdyMask & (events | POLL_RETONLY));\r
474}\r
475\r
476/** Construct the Console stream devices: stdin, stdout, stderr.\r
477\r
478 Allocate the instance structure and populate it with the information for\r
479 each stream device.\r
480**/\r
481RETURN_STATUS\r
482EFIAPI\r
483__Cons_construct(\r
484 IN EFI_HANDLE ImageHandle,\r
485 IN EFI_SYSTEM_TABLE *SystemTable\r
486)\r
487{\r
488 ConInstance *Stream;\r
489 RETURN_STATUS Status = RETURN_SUCCESS;\r
490 int i;\r
491\r
492 ConInstanceList = (ConInstance *)AllocateZeroPool(NUM_SPECIAL * sizeof(ConInstance));\r
d7ce7006 493 ConReadBuf = (wchar_t *)AllocateZeroPool((MAX_INPUT + 1) * sizeof(wchar_t));\r
494 if((ConInstanceList == NULL) || (ConReadBuf == NULL)) {\r
53e1e5c6 495 return RETURN_OUT_OF_RESOURCES;\r
496 }\r
497\r
498 for( i = 0; i < NUM_SPECIAL; ++i) {\r
499 // Get pointer to instance.\r
500 Stream = &ConInstanceList[i];\r
501\r
502 Stream->Cookie = CON_COOKIE;\r
503 Stream->InstanceNum = i;\r
504\r
505 switch(i) {\r
506 case STDIN_FILENO:\r
507 Stream->Dev = SystemTable->ConIn;\r
508 break;\r
509 case STDOUT_FILENO:\r
510 Stream->Dev = SystemTable->ConOut;\r
511 break;\r
512 case STDERR_FILENO:\r
513 if(SystemTable->StdErr == NULL) {\r
514 Stream->Dev = SystemTable->ConOut;\r
515 }\r
516 else {\r
517 Stream->Dev = SystemTable->StdErr;\r
518 }\r
519 break;\r
520 default:\r
521 return RETURN_VOLUME_CORRUPTED; // This is a "should never happen" case.\r
522 }\r
523\r
524 Stream->Abstraction.fo_close = &da_ConClose;\r
525 Stream->Abstraction.fo_read = &da_ConRead;\r
526 Stream->Abstraction.fo_write = &da_ConWrite;\r
527 Stream->Abstraction.fo_stat = &da_ConStat;\r
528 Stream->Abstraction.fo_lseek = &da_ConSeek;\r
529 Stream->Abstraction.fo_fcntl = &fnullop_fcntl;\r
530 Stream->Abstraction.fo_ioctl = &da_ConIoctl;\r
531 Stream->Abstraction.fo_poll = &da_ConPoll;\r
532 Stream->Abstraction.fo_flush = &fnullop_flush;\r
533 Stream->Abstraction.fo_delete = &fbadop_delete;\r
534 Stream->Abstraction.fo_mkdir = &fbadop_mkdir;\r
535 Stream->Abstraction.fo_rmdir = &fbadop_rmdir;\r
536 Stream->Abstraction.fo_rename = &fbadop_rename;\r
537\r
538 Stream->NumRead = 0;\r
539 Stream->NumWritten = 0;\r
540 Stream->UnGetKey.ScanCode = SCAN_NULL;\r
541 Stream->UnGetKey.UnicodeChar = CHAR_NULL;\r
542\r
543 if(Stream->Dev == NULL) {\r
544 continue; // No device for this stream.\r
545 }\r
546 ConNode[i] = __DevRegister(stdioNames[i], NULL, &da_ConOpen, Stream, 1, sizeof(ConInstance), stdioFlags[i]);\r
547 if(ConNode[i] == NULL) {\r
548 Status = EFIerrno;\r
549 break;\r
550 }\r
551 Stream->Parent = ConNode[i];\r
552 }\r
d7ce7006 553 /* Initialize Ioctl flags until Ioctl is really implemented. */\r
554 TtyCooked = TRUE;\r
555 TtyEcho = TRUE;\r
556\r
53e1e5c6 557 return Status;\r
558}\r
559\r
560RETURN_STATUS\r
561EFIAPI\r
562__Cons_deconstruct(\r
563 IN EFI_HANDLE ImageHandle,\r
564 IN EFI_SYSTEM_TABLE *SystemTable\r
565)\r
566{\r
567 int i;\r
568\r
569 for(i = 0; i < NUM_SPECIAL; ++i) {\r
570 if(ConNode[i] != NULL) {\r
571 FreePool(ConNode[i]);\r
572 }\r
573 }\r
574 if(ConInstanceList != NULL) {\r
575 FreePool(ConInstanceList);\r
576 }\r
d7ce7006 577 if(ConReadBuf != NULL) {\r
578 FreePool(ConReadBuf);\r
579 }\r
53e1e5c6 580\r
581 return RETURN_SUCCESS;\r
582}\r
583\r
584/* ######################################################################### */\r
585#if 0 /* Not implemented for Console */\r
586\r
587static\r
588int\r
589EFIAPI\r
590da_ConCntl(\r
591 struct __filedes *filp,\r
592 UINT32,\r
593 void *,\r
594 void *\r
595 )\r
596{\r
597}\r
598\r
599static\r
600int\r
601EFIAPI\r
602da_ConFlush(\r
603 struct __filedes *filp\r
604 )\r
605{\r
606 return 0;\r
607}\r
608#endif /* Not implemented for Console */\r