]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Usb/UsbKb/Dxe/efikey.c
a9cdbc8760a0dd496aafabc1217096d4b961b673
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbKb / Dxe / efikey.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 EfiKey.c
15
16 Abstract:
17
18 USB Keyboard Driver
19
20 Revision History
21
22 --*/
23
24 #include "efikey.h"
25 #include "keyboard.h"
26
27 //
28 // Prototypes
29 // Driver model protocol interface
30 //
31 EFI_STATUS
32 EFIAPI
33 USBKeyboardDriverBindingEntryPoint (
34 IN EFI_HANDLE ImageHandle,
35 IN EFI_SYSTEM_TABLE *SystemTable
36 );
37
38 EFI_STATUS
39 EFIAPI
40 USBKeyboardDriverBindingSupported (
41 IN EFI_DRIVER_BINDING_PROTOCOL *This,
42 IN EFI_HANDLE Controller,
43 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
44 );
45
46 EFI_STATUS
47 EFIAPI
48 USBKeyboardDriverBindingStart (
49 IN EFI_DRIVER_BINDING_PROTOCOL *This,
50 IN EFI_HANDLE Controller,
51 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
52 );
53
54 EFI_STATUS
55 EFIAPI
56 USBKeyboardDriverBindingStop (
57 IN EFI_DRIVER_BINDING_PROTOCOL *This,
58 IN EFI_HANDLE Controller,
59 IN UINTN NumberOfChildren,
60 IN EFI_HANDLE *ChildHandleBuffer
61 );
62
63 //
64 // Simple Text In Protocol Interface
65 //
66 STATIC
67 EFI_STATUS
68 EFIAPI
69 USBKeyboardReset (
70 IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
71 IN BOOLEAN ExtendedVerification
72 );
73
74 STATIC
75 EFI_STATUS
76 EFIAPI
77 USBKeyboardReadKeyStroke (
78 IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
79 OUT EFI_INPUT_KEY *Key
80 );
81
82 STATIC
83 VOID
84 EFIAPI
85 USBKeyboardWaitForKey (
86 IN EFI_EVENT Event,
87 IN VOID *Context
88 );
89
90 //
91 // Helper functions
92 //
93 STATIC
94 EFI_STATUS
95 USBKeyboardCheckForKey (
96 IN USB_KB_DEV *UsbKeyboardDevice
97 );
98
99 //
100 // USB Keyboard Driver Global Variables
101 //
102 EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding = {
103 USBKeyboardDriverBindingSupported,
104 USBKeyboardDriverBindingStart,
105 USBKeyboardDriverBindingStop,
106 0x10,
107 NULL,
108 NULL
109 };
110
111 EFI_STATUS
112 EFIAPI
113 USBKeyboardDriverBindingSupported (
114 IN EFI_DRIVER_BINDING_PROTOCOL *This,
115 IN EFI_HANDLE Controller,
116 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
117 )
118 /*++
119
120 Routine Description:
121 Supported.
122
123 Arguments:
124 This - EFI_DRIVER_BINDING_PROTOCOL
125 Controller - Controller handle
126 RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL
127 Returns:
128 EFI_STATUS
129
130 --*/
131 {
132 EFI_STATUS OpenStatus;
133 EFI_USB_IO_PROTOCOL *UsbIo;
134 EFI_STATUS Status;
135
136 //
137 // Check if USB_IO protocol is attached on the controller handle.
138 //
139 OpenStatus = gBS->OpenProtocol (
140 Controller,
141 &gEfiUsbIoProtocolGuid,
142 (VOID **) &UsbIo,
143 This->DriverBindingHandle,
144 Controller,
145 EFI_OPEN_PROTOCOL_BY_DRIVER
146 );
147 if (EFI_ERROR (OpenStatus)) {
148 return OpenStatus;
149 }
150
151 //
152 // Use the USB I/O protocol interface to check whether the Controller is
153 // the Keyboard controller that can be managed by this driver.
154 //
155 Status = EFI_SUCCESS;
156
157 if (!IsUSBKeyboard (UsbIo)) {
158 Status = EFI_UNSUPPORTED;
159 }
160
161 gBS->CloseProtocol (
162 Controller,
163 &gEfiUsbIoProtocolGuid,
164 This->DriverBindingHandle,
165 Controller
166 );
167
168 return Status;
169 }
170
171 EFI_STATUS
172 EFIAPI
173 USBKeyboardDriverBindingStart (
174 IN EFI_DRIVER_BINDING_PROTOCOL *This,
175 IN EFI_HANDLE Controller,
176 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
177 )
178 /*++
179
180 Routine Description:
181 Start.
182
183 Arguments:
184 This - EFI_DRIVER_BINDING_PROTOCOL
185 Controller - Controller handle
186 RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL
187 Returns:
188 EFI_SUCCESS - Success
189 EFI_OUT_OF_RESOURCES - Can't allocate memory
190 EFI_UNSUPPORTED - The Start routine fail
191 --*/
192 {
193 EFI_STATUS Status;
194 EFI_USB_IO_PROTOCOL *UsbIo;
195 USB_KB_DEV *UsbKeyboardDevice;
196 UINT8 EndpointNumber;
197 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
198 UINT8 Index;
199 UINT8 EndpointAddr;
200 UINT8 PollingInterval;
201 UINT8 PacketSize;
202 BOOLEAN Found;
203
204 UsbKeyboardDevice = NULL;
205 Found = FALSE;
206
207 //
208 // Open USB_IO Protocol
209 //
210 Status = gBS->OpenProtocol (
211 Controller,
212 &gEfiUsbIoProtocolGuid,
213 (VOID **) &UsbIo,
214 This->DriverBindingHandle,
215 Controller,
216 EFI_OPEN_PROTOCOL_BY_DRIVER
217 );
218 if (EFI_ERROR (Status)) {
219 return Status;
220 }
221
222 UsbKeyboardDevice = AllocateZeroPool (sizeof (USB_KB_DEV));
223 if (UsbKeyboardDevice == NULL) {
224 gBS->CloseProtocol (
225 Controller,
226 &gEfiUsbIoProtocolGuid,
227 This->DriverBindingHandle,
228 Controller
229 );
230 return EFI_OUT_OF_RESOURCES;
231 }
232 //
233 // Get the Device Path Protocol on Controller's handle
234 //
235 Status = gBS->OpenProtocol (
236 Controller,
237 &gEfiDevicePathProtocolGuid,
238 (VOID **) &UsbKeyboardDevice->DevicePath,
239 This->DriverBindingHandle,
240 Controller,
241 EFI_OPEN_PROTOCOL_GET_PROTOCOL
242 );
243
244 if (EFI_ERROR (Status)) {
245 gBS->FreePool (UsbKeyboardDevice);
246 gBS->CloseProtocol (
247 Controller,
248 &gEfiUsbIoProtocolGuid,
249 This->DriverBindingHandle,
250 Controller
251 );
252 return Status;
253 }
254 //
255 // Report that the usb keyboard is being enabled
256 //
257 KbdReportStatusCode (
258 UsbKeyboardDevice->DevicePath,
259 EFI_PROGRESS_CODE,
260 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE)
261 );
262
263 //
264 // This is pretty close to keyboard detection, so log progress
265 //
266 KbdReportStatusCode (
267 UsbKeyboardDevice->DevicePath,
268 EFI_PROGRESS_CODE,
269 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT)
270 );
271
272 //
273 // Initialize UsbKeyboardDevice
274 //
275 UsbKeyboardDevice->UsbIo = UsbIo;
276
277 //
278 // Get interface & endpoint descriptor
279 //
280 UsbIo->UsbGetInterfaceDescriptor (
281 UsbIo,
282 &UsbKeyboardDevice->InterfaceDescriptor
283 );
284
285 EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints;
286
287 for (Index = 0; Index < EndpointNumber; Index++) {
288
289 UsbIo->UsbGetEndpointDescriptor (
290 UsbIo,
291 Index,
292 &EndpointDescriptor
293 );
294
295 if ((EndpointDescriptor.Attributes & 0x03) == 0x03) {
296 //
297 // We only care interrupt endpoint here
298 //
299 CopyMem (&UsbKeyboardDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof (EndpointDescriptor));
300 //UsbKeyboardDevice->IntEndpointDescriptor = EndpointDescriptor;
301 Found = TRUE;
302 }
303 }
304
305 if (!Found) {
306 //
307 // No interrupt endpoint found, then return unsupported.
308 //
309 gBS->FreePool (UsbKeyboardDevice);
310 gBS->CloseProtocol (
311 Controller,
312 &gEfiUsbIoProtocolGuid,
313 This->DriverBindingHandle,
314 Controller
315 );
316 return EFI_UNSUPPORTED;
317 }
318
319 UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE;
320 UsbKeyboardDevice->SimpleInput.Reset = USBKeyboardReset;
321 UsbKeyboardDevice->SimpleInput.ReadKeyStroke = USBKeyboardReadKeyStroke;
322 Status = gBS->CreateEvent (
323 EFI_EVENT_NOTIFY_WAIT,
324 EFI_TPL_NOTIFY,
325 USBKeyboardWaitForKey,
326 UsbKeyboardDevice,
327 &(UsbKeyboardDevice->SimpleInput.WaitForKey)
328 );
329
330 if (EFI_ERROR (Status)) {
331 gBS->FreePool (UsbKeyboardDevice);
332 gBS->CloseProtocol (
333 Controller,
334 &gEfiUsbIoProtocolGuid,
335 This->DriverBindingHandle,
336 Controller
337 );
338 return Status;
339 }
340
341 //
342 // Install simple txt in protocol interface
343 // for the usb keyboard device.
344 // Usb keyboard is a hot plug device, and expected to work immediately
345 // when plugging into system, so a HotPlugDeviceGuid is installed onto
346 // the usb keyboard device handle, to distinguish it from other conventional
347 // console devices.
348 //
349 Status = gBS->InstallMultipleProtocolInterfaces (
350 &Controller,
351 &gEfiSimpleTextInProtocolGuid,
352 &UsbKeyboardDevice->SimpleInput,
353 &gEfiHotPlugDeviceGuid,
354 NULL,
355 NULL
356 );
357 if (EFI_ERROR (Status)) {
358 gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
359 gBS->FreePool (UsbKeyboardDevice);
360 gBS->CloseProtocol (
361 Controller,
362 &gEfiUsbIoProtocolGuid,
363 This->DriverBindingHandle,
364 Controller
365 );
366 return Status;
367 }
368
369 //
370 // Reset USB Keyboard Device
371 //
372 Status = UsbKeyboardDevice->SimpleInput.Reset (
373 &UsbKeyboardDevice->SimpleInput,
374 TRUE
375 );
376 if (EFI_ERROR (Status)) {
377 gBS->UninstallMultipleProtocolInterfaces (
378 Controller,
379 &gEfiSimpleTextInProtocolGuid,
380 &UsbKeyboardDevice->SimpleInput,
381 &gEfiHotPlugDeviceGuid,
382 NULL,
383 NULL
384 );
385 gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
386 gBS->FreePool (UsbKeyboardDevice);
387 gBS->CloseProtocol (
388 Controller,
389 &gEfiUsbIoProtocolGuid,
390 This->DriverBindingHandle,
391 Controller
392 );
393 return Status;
394 }
395 //
396 // submit async interrupt transfer
397 //
398 EndpointAddr = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress;
399 PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval;
400 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);
401
402 Status = UsbIo->UsbAsyncInterruptTransfer (
403 UsbIo,
404 EndpointAddr,
405 TRUE,
406 PollingInterval,
407 PacketSize,
408 KeyboardHandler,
409 UsbKeyboardDevice
410 );
411
412 if (EFI_ERROR (Status)) {
413
414 gBS->UninstallMultipleProtocolInterfaces (
415 Controller,
416 &gEfiSimpleTextInProtocolGuid,
417 &UsbKeyboardDevice->SimpleInput,
418 &gEfiHotPlugDeviceGuid,
419 NULL,
420 NULL
421 );
422 gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
423 gBS->FreePool (UsbKeyboardDevice);
424 gBS->CloseProtocol (
425 Controller,
426 &gEfiUsbIoProtocolGuid,
427 This->DriverBindingHandle,
428 Controller
429 );
430 return Status;
431 }
432
433 UsbKeyboardDevice->ControllerNameTable = NULL;
434 AddUnicodeString (
435 "eng",
436 gUsbKeyboardComponentName.SupportedLanguages,
437 &UsbKeyboardDevice->ControllerNameTable,
438 (CHAR16 *) L"Generic Usb Keyboard"
439 );
440
441 return EFI_SUCCESS;
442 }
443
444
445 EFI_STATUS
446 EFIAPI
447 USBKeyboardDriverBindingStop (
448 IN EFI_DRIVER_BINDING_PROTOCOL *This,
449 IN EFI_HANDLE Controller,
450 IN UINTN NumberOfChildren,
451 IN EFI_HANDLE *ChildHandleBuffer
452 )
453 /*++
454
455 Routine Description:
456 Stop.
457
458 Arguments:
459 This - EFI_DRIVER_BINDING_PROTOCOL
460 Controller - Controller handle
461 NumberOfChildren - Child handle number
462 ChildHandleBuffer - Child handle buffer
463 Returns:
464 EFI_SUCCESS - Success
465 EFI_UNSUPPORTED - Can't support
466 --*/
467 {
468 EFI_STATUS Status;
469 EFI_SIMPLE_TEXT_IN_PROTOCOL *SimpleInput;
470 USB_KB_DEV *UsbKeyboardDevice;
471 EFI_USB_IO_PROTOCOL *UsbIo;
472
473 Status = gBS->OpenProtocol (
474 Controller,
475 &gEfiSimpleTextInProtocolGuid,
476 (VOID **) &SimpleInput,
477 This->DriverBindingHandle,
478 Controller,
479 EFI_OPEN_PROTOCOL_BY_DRIVER
480 );
481 if (EFI_ERROR (Status)) {
482 return EFI_UNSUPPORTED;
483 }
484
485 //
486 // Get USB_KB_DEV instance.
487 //
488 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput);
489
490 gBS->CloseProtocol (
491 Controller,
492 &gEfiSimpleTextInProtocolGuid,
493 This->DriverBindingHandle,
494 Controller
495 );
496
497 UsbIo = UsbKeyboardDevice->UsbIo;
498 //
499 // Uninstall the Asyn Interrupt Transfer from this device
500 // will disable the key data input from this device
501 //
502 KbdReportStatusCode (
503 UsbKeyboardDevice->DevicePath,
504 EFI_PROGRESS_CODE,
505 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE)
506 );
507
508 //
509 // Destroy asynchronous interrupt transfer
510 //
511 UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer (
512 UsbKeyboardDevice->UsbIo,
513 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
514 FALSE,
515 UsbKeyboardDevice->IntEndpointDescriptor.Interval,
516 0,
517 NULL,
518 NULL
519 );
520
521 gBS->CloseProtocol (
522 Controller,
523 &gEfiUsbIoProtocolGuid,
524 This->DriverBindingHandle,
525 Controller
526 );
527
528 Status = gBS->UninstallMultipleProtocolInterfaces (
529 Controller,
530 &gEfiSimpleTextInProtocolGuid,
531 &UsbKeyboardDevice->SimpleInput,
532 &gEfiHotPlugDeviceGuid,
533 NULL,
534 NULL
535 );
536 //
537 // free all the resources.
538 //
539 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
540 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
541 gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey);
542
543 if (UsbKeyboardDevice->ControllerNameTable != NULL) {
544 FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable);
545 }
546
547 gBS->FreePool (UsbKeyboardDevice);
548
549 return Status;
550
551 }
552
553
554 EFI_STATUS
555 EFIAPI
556 USBKeyboardReset (
557 IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
558 IN BOOLEAN ExtendedVerification
559 )
560 /*++
561
562 Routine Description:
563 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.Reset() function.
564
565 Arguments:
566 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
567 ExtendedVerification
568 Indicates that the driver may perform a more exhaustive
569 verification operation of the device during reset.
570
571 Returns:
572 EFI_SUCCESS - Success
573 EFI_DEVICE_ERROR - Hardware Error
574 --*/
575 {
576 EFI_STATUS Status;
577 USB_KB_DEV *UsbKeyboardDevice;
578 EFI_USB_IO_PROTOCOL *UsbIo;
579
580 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
581
582 UsbIo = UsbKeyboardDevice->UsbIo;
583
584 KbdReportStatusCode (
585 UsbKeyboardDevice->DevicePath,
586 EFI_PROGRESS_CODE,
587 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET)
588 );
589
590 //
591 // Non Exhaustive reset:
592 // only reset private data structures.
593 //
594 if (!ExtendedVerification) {
595 //
596 // Clear the key buffer of this Usb keyboard
597 //
598 KbdReportStatusCode (
599 UsbKeyboardDevice->DevicePath,
600 EFI_PROGRESS_CODE,
601 (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER)
602 );
603
604 InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));
605 UsbKeyboardDevice->CurKeyChar = 0;
606 return EFI_SUCCESS;
607 }
608
609 //
610 // Exhaustive reset
611 //
612 Status = InitUSBKeyboard (UsbKeyboardDevice);
613 UsbKeyboardDevice->CurKeyChar = 0;
614 if (EFI_ERROR (Status)) {
615 return EFI_DEVICE_ERROR;
616 }
617
618 return EFI_SUCCESS;
619 }
620
621 STATIC
622 EFI_STATUS
623 EFIAPI
624 USBKeyboardReadKeyStroke (
625 IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
626 OUT EFI_INPUT_KEY *Key
627 )
628 /*++
629
630 Routine Description:
631 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.ReadKeyStroke() function.
632
633 Arguments:
634 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
635 Key A pointer to a buffer that is filled in with the keystroke
636 information for the key that was pressed.
637
638 Returns:
639 EFI_SUCCESS - Success
640 --*/
641 {
642 USB_KB_DEV *UsbKeyboardDevice;
643 EFI_STATUS Status;
644 UINT8 KeyChar;
645
646 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
647
648 //
649 // if there is no saved ASCII byte, fetch it
650 // by calling USBKeyboardCheckForKey().
651 //
652 if (UsbKeyboardDevice->CurKeyChar == 0) {
653 Status = USBKeyboardCheckForKey (UsbKeyboardDevice);
654 if (EFI_ERROR (Status)) {
655 return Status;
656 }
657 }
658
659 Key->UnicodeChar = 0;
660 Key->ScanCode = SCAN_NULL;
661
662 KeyChar = UsbKeyboardDevice->CurKeyChar;
663
664 UsbKeyboardDevice->CurKeyChar = 0;
665
666 //
667 // Translate saved ASCII byte into EFI_INPUT_KEY
668 //
669 Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, Key);
670
671 return Status;
672
673 }
674
675 STATIC
676 VOID
677 EFIAPI
678 USBKeyboardWaitForKey (
679 IN EFI_EVENT Event,
680 IN VOID *Context
681 )
682 /*++
683
684 Routine Description:
685 Handler function for WaitForKey event.
686
687 Arguments:
688 Event Event to be signaled when a key is pressed.
689 Context Points to USB_KB_DEV instance.
690
691 Returns:
692 VOID
693 --*/
694 {
695 USB_KB_DEV *UsbKeyboardDevice;
696
697 UsbKeyboardDevice = (USB_KB_DEV *) Context;
698
699 if (UsbKeyboardDevice->CurKeyChar == 0) {
700
701 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) {
702 return ;
703 }
704 }
705 //
706 // If has key pending, signal the event.
707 //
708 gBS->SignalEvent (Event);
709 }
710
711
712 STATIC
713 EFI_STATUS
714 USBKeyboardCheckForKey (
715 IN USB_KB_DEV *UsbKeyboardDevice
716 )
717 /*++
718
719 Routine Description:
720 Check whether there is key pending.
721
722 Arguments:
723 UsbKeyboardDevice The USB_KB_DEV instance.
724
725 Returns:
726 EFI_SUCCESS - Success
727 --*/
728 {
729 EFI_STATUS Status;
730 UINT8 KeyChar;
731
732 //
733 // Fetch raw data from the USB keyboard input,
734 // and translate it into ASCII data.
735 //
736 Status = USBParseKey (UsbKeyboardDevice, &KeyChar);
737 if (EFI_ERROR (Status)) {
738 return Status;
739 }
740
741 UsbKeyboardDevice->CurKeyChar = KeyChar;
742 return EFI_SUCCESS;
743 }
744
745 VOID
746 KbdReportStatusCode (
747 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
748 IN EFI_STATUS_CODE_TYPE CodeType,
749 IN EFI_STATUS_CODE_VALUE Value
750 )
751 /*++
752
753 Routine Description:
754 Report Status Code in Usb Bot Driver
755
756 Arguments:
757 DevicePath - Use this to get Device Path
758 CodeType - Status Code Type
759 CodeValue - Status Code Value
760
761 Returns:
762 None
763
764 --*/
765 {
766
767 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
768 CodeType,
769 Value,
770 DevicePath
771 );
772 }