]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Usb/UsbKb/Dxe/efikey.c
Fix component name bugs when input Controller Name is invalid
[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 0xa,
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 Found = TRUE;
301 }
302 }
303
304 if (!Found) {
305 //
306 // No interrupt endpoint found, then return unsupported.
307 //
308 gBS->FreePool (UsbKeyboardDevice);
309 gBS->CloseProtocol (
310 Controller,
311 &gEfiUsbIoProtocolGuid,
312 This->DriverBindingHandle,
313 Controller
314 );
315 return EFI_UNSUPPORTED;
316 }
317
318 UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE;
319 UsbKeyboardDevice->SimpleInput.Reset = USBKeyboardReset;
320 UsbKeyboardDevice->SimpleInput.ReadKeyStroke = USBKeyboardReadKeyStroke;
321 Status = gBS->CreateEvent (
322 EFI_EVENT_NOTIFY_WAIT,
323 EFI_TPL_NOTIFY,
324 USBKeyboardWaitForKey,
325 UsbKeyboardDevice,
326 &(UsbKeyboardDevice->SimpleInput.WaitForKey)
327 );
328
329 if (EFI_ERROR (Status)) {
330 gBS->FreePool (UsbKeyboardDevice);
331 gBS->CloseProtocol (
332 Controller,
333 &gEfiUsbIoProtocolGuid,
334 This->DriverBindingHandle,
335 Controller
336 );
337 return Status;
338 }
339
340 //
341 // Install simple txt in protocol interface
342 // for the usb keyboard device.
343 // Usb keyboard is a hot plug device, and expected to work immediately
344 // when plugging into system, so a HotPlugDeviceGuid is installed onto
345 // the usb keyboard device handle, to distinguish it from other conventional
346 // console devices.
347 //
348 Status = gBS->InstallMultipleProtocolInterfaces (
349 &Controller,
350 &gEfiSimpleTextInProtocolGuid,
351 &UsbKeyboardDevice->SimpleInput,
352 &gEfiHotPlugDeviceGuid,
353 NULL,
354 NULL
355 );
356 if (EFI_ERROR (Status)) {
357 gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
358 gBS->FreePool (UsbKeyboardDevice);
359 gBS->CloseProtocol (
360 Controller,
361 &gEfiUsbIoProtocolGuid,
362 This->DriverBindingHandle,
363 Controller
364 );
365 return Status;
366 }
367
368 //
369 // Reset USB Keyboard Device
370 //
371 Status = UsbKeyboardDevice->SimpleInput.Reset (
372 &UsbKeyboardDevice->SimpleInput,
373 TRUE
374 );
375 if (EFI_ERROR (Status)) {
376 gBS->UninstallMultipleProtocolInterfaces (
377 Controller,
378 &gEfiSimpleTextInProtocolGuid,
379 &UsbKeyboardDevice->SimpleInput,
380 &gEfiHotPlugDeviceGuid,
381 NULL,
382 NULL
383 );
384 gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
385 gBS->FreePool (UsbKeyboardDevice);
386 gBS->CloseProtocol (
387 Controller,
388 &gEfiUsbIoProtocolGuid,
389 This->DriverBindingHandle,
390 Controller
391 );
392 return Status;
393 }
394 //
395 // submit async interrupt transfer
396 //
397 EndpointAddr = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress;
398 PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval;
399 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);
400
401 Status = UsbIo->UsbAsyncInterruptTransfer (
402 UsbIo,
403 EndpointAddr,
404 TRUE,
405 PollingInterval,
406 PacketSize,
407 KeyboardHandler,
408 UsbKeyboardDevice
409 );
410
411 if (EFI_ERROR (Status)) {
412
413 gBS->UninstallMultipleProtocolInterfaces (
414 Controller,
415 &gEfiSimpleTextInProtocolGuid,
416 &UsbKeyboardDevice->SimpleInput,
417 &gEfiHotPlugDeviceGuid,
418 NULL,
419 NULL
420 );
421 gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
422 gBS->FreePool (UsbKeyboardDevice);
423 gBS->CloseProtocol (
424 Controller,
425 &gEfiUsbIoProtocolGuid,
426 This->DriverBindingHandle,
427 Controller
428 );
429 return Status;
430 }
431
432 UsbKeyboardDevice->ControllerNameTable = NULL;
433 AddUnicodeString (
434 "eng",
435 gUsbKeyboardComponentName.SupportedLanguages,
436 &UsbKeyboardDevice->ControllerNameTable,
437 (CHAR16 *) L"Generic Usb Keyboard"
438 );
439
440 return EFI_SUCCESS;
441 }
442
443
444 EFI_STATUS
445 EFIAPI
446 USBKeyboardDriverBindingStop (
447 IN EFI_DRIVER_BINDING_PROTOCOL *This,
448 IN EFI_HANDLE Controller,
449 IN UINTN NumberOfChildren,
450 IN EFI_HANDLE *ChildHandleBuffer
451 )
452 /*++
453
454 Routine Description:
455 Stop.
456
457 Arguments:
458 This - EFI_DRIVER_BINDING_PROTOCOL
459 Controller - Controller handle
460 NumberOfChildren - Child handle number
461 ChildHandleBuffer - Child handle buffer
462 Returns:
463 EFI_SUCCESS - Success
464 EFI_UNSUPPORTED - Can't support
465 --*/
466 {
467 EFI_STATUS Status;
468 EFI_SIMPLE_TEXT_IN_PROTOCOL *SimpleInput;
469 USB_KB_DEV *UsbKeyboardDevice;
470 EFI_USB_IO_PROTOCOL *UsbIo;
471
472 Status = gBS->OpenProtocol (
473 Controller,
474 &gEfiSimpleTextInProtocolGuid,
475 (VOID **) &SimpleInput,
476 This->DriverBindingHandle,
477 Controller,
478 EFI_OPEN_PROTOCOL_BY_DRIVER
479 );
480 if (EFI_ERROR (Status)) {
481 return EFI_UNSUPPORTED;
482 }
483
484 //
485 // Get USB_KB_DEV instance.
486 //
487 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput);
488
489 gBS->CloseProtocol (
490 Controller,
491 &gEfiSimpleTextInProtocolGuid,
492 This->DriverBindingHandle,
493 Controller
494 );
495
496 UsbIo = UsbKeyboardDevice->UsbIo;
497 //
498 // Uninstall the Asyn Interrupt Transfer from this device
499 // will disable the key data input from this device
500 //
501 KbdReportStatusCode (
502 UsbKeyboardDevice->DevicePath,
503 EFI_PROGRESS_CODE,
504 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE)
505 );
506
507 //
508 // Destroy asynchronous interrupt transfer
509 //
510 UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer (
511 UsbKeyboardDevice->UsbIo,
512 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,
513 FALSE,
514 UsbKeyboardDevice->IntEndpointDescriptor.Interval,
515 0,
516 NULL,
517 NULL
518 );
519
520 gBS->CloseProtocol (
521 Controller,
522 &gEfiUsbIoProtocolGuid,
523 This->DriverBindingHandle,
524 Controller
525 );
526
527 Status = gBS->UninstallMultipleProtocolInterfaces (
528 Controller,
529 &gEfiSimpleTextInProtocolGuid,
530 &UsbKeyboardDevice->SimpleInput,
531 &gEfiHotPlugDeviceGuid,
532 NULL,
533 NULL
534 );
535 //
536 // free all the resources.
537 //
538 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
539 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
540 gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey);
541
542 if (UsbKeyboardDevice->ControllerNameTable != NULL) {
543 FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable);
544 }
545
546 gBS->FreePool (UsbKeyboardDevice);
547
548 return Status;
549
550 }
551
552
553 EFI_STATUS
554 EFIAPI
555 USBKeyboardReset (
556 IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
557 IN BOOLEAN ExtendedVerification
558 )
559 /*++
560
561 Routine Description:
562 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.Reset() function.
563
564 Arguments:
565 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
566 ExtendedVerification
567 Indicates that the driver may perform a more exhaustive
568 verification operation of the device during reset.
569
570 Returns:
571 EFI_SUCCESS - Success
572 EFI_DEVICE_ERROR - Hardware Error
573 --*/
574 {
575 EFI_STATUS Status;
576 USB_KB_DEV *UsbKeyboardDevice;
577 EFI_USB_IO_PROTOCOL *UsbIo;
578
579 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
580
581 UsbIo = UsbKeyboardDevice->UsbIo;
582
583 KbdReportStatusCode (
584 UsbKeyboardDevice->DevicePath,
585 EFI_PROGRESS_CODE,
586 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET)
587 );
588
589 //
590 // Non Exhaustive reset:
591 // only reset private data structures.
592 //
593 if (!ExtendedVerification) {
594 //
595 // Clear the key buffer of this Usb keyboard
596 //
597 KbdReportStatusCode (
598 UsbKeyboardDevice->DevicePath,
599 EFI_PROGRESS_CODE,
600 (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER)
601 );
602
603 InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));
604 UsbKeyboardDevice->CurKeyChar = 0;
605 return EFI_SUCCESS;
606 }
607
608 //
609 // Exhaustive reset
610 //
611 Status = InitUSBKeyboard (UsbKeyboardDevice);
612 UsbKeyboardDevice->CurKeyChar = 0;
613 if (EFI_ERROR (Status)) {
614 return EFI_DEVICE_ERROR;
615 }
616
617 return EFI_SUCCESS;
618 }
619
620 STATIC
621 EFI_STATUS
622 EFIAPI
623 USBKeyboardReadKeyStroke (
624 IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
625 OUT EFI_INPUT_KEY *Key
626 )
627 /*++
628
629 Routine Description:
630 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.ReadKeyStroke() function.
631
632 Arguments:
633 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
634 Key A pointer to a buffer that is filled in with the keystroke
635 information for the key that was pressed.
636
637 Returns:
638 EFI_SUCCESS - Success
639 --*/
640 {
641 USB_KB_DEV *UsbKeyboardDevice;
642 EFI_STATUS Status;
643 UINT8 KeyChar;
644
645 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
646
647 //
648 // if there is no saved ASCII byte, fetch it
649 // by calling USBKeyboardCheckForKey().
650 //
651 if (UsbKeyboardDevice->CurKeyChar == 0) {
652 Status = USBKeyboardCheckForKey (UsbKeyboardDevice);
653 if (EFI_ERROR (Status)) {
654 return Status;
655 }
656 }
657
658 Key->UnicodeChar = 0;
659 Key->ScanCode = SCAN_NULL;
660
661 KeyChar = UsbKeyboardDevice->CurKeyChar;
662
663 UsbKeyboardDevice->CurKeyChar = 0;
664
665 //
666 // Translate saved ASCII byte into EFI_INPUT_KEY
667 //
668 Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, Key);
669
670 return Status;
671
672 }
673
674 STATIC
675 VOID
676 EFIAPI
677 USBKeyboardWaitForKey (
678 IN EFI_EVENT Event,
679 IN VOID *Context
680 )
681 /*++
682
683 Routine Description:
684 Handler function for WaitForKey event.
685
686 Arguments:
687 Event Event to be signaled when a key is pressed.
688 Context Points to USB_KB_DEV instance.
689
690 Returns:
691 VOID
692 --*/
693 {
694 USB_KB_DEV *UsbKeyboardDevice;
695
696 UsbKeyboardDevice = (USB_KB_DEV *) Context;
697
698 if (UsbKeyboardDevice->CurKeyChar == 0) {
699
700 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) {
701 return ;
702 }
703 }
704 //
705 // If has key pending, signal the event.
706 //
707 gBS->SignalEvent (Event);
708 }
709
710
711 STATIC
712 EFI_STATUS
713 USBKeyboardCheckForKey (
714 IN USB_KB_DEV *UsbKeyboardDevice
715 )
716 /*++
717
718 Routine Description:
719 Check whether there is key pending.
720
721 Arguments:
722 UsbKeyboardDevice The USB_KB_DEV instance.
723
724 Returns:
725 EFI_SUCCESS - Success
726 --*/
727 {
728 EFI_STATUS Status;
729 UINT8 KeyChar;
730
731 //
732 // Fetch raw data from the USB keyboard input,
733 // and translate it into ASCII data.
734 //
735 Status = USBParseKey (UsbKeyboardDevice, &KeyChar);
736 if (EFI_ERROR (Status)) {
737 return Status;
738 }
739
740 UsbKeyboardDevice->CurKeyChar = KeyChar;
741 return EFI_SUCCESS;
742 }
743
744 VOID
745 KbdReportStatusCode (
746 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
747 IN EFI_STATUS_CODE_TYPE CodeType,
748 IN EFI_STATUS_CODE_VALUE Value
749 )
750 /*++
751
752 Routine Description:
753 Report Status Code in Usb Bot Driver
754
755 Arguments:
756 DevicePath - Use this to get Device Path
757 CodeType - Status Code Type
758 CodeValue - Status Code Value
759
760 Returns:
761 None
762
763 --*/
764 {
765
766 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
767 CodeType,
768 Value,
769 DevicePath
770 );
771 }