Ps2Keyboard.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /** @file
  2. PS/2 Keyboard driver. Routines that interacts with callers,
  3. conforming to EFI driver model
  4. Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "Ps2Keyboard.h"
  8. //
  9. // Function prototypes
  10. //
  11. /**
  12. Test controller is a keyboard Controller.
  13. @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
  14. @param Controller driver's controller
  15. @param RemainingDevicePath children device path
  16. @retval EFI_UNSUPPORTED controller is not floppy disk
  17. @retval EFI_SUCCESS controller is floppy disk
  18. **/
  19. EFI_STATUS
  20. EFIAPI
  21. KbdControllerDriverSupported (
  22. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  23. IN EFI_HANDLE Controller,
  24. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  25. );
  26. /**
  27. Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
  28. @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
  29. @param Controller driver controller handle
  30. @param RemainingDevicePath Children's device path
  31. @retval whether success to create floppy control instance.
  32. **/
  33. EFI_STATUS
  34. EFIAPI
  35. KbdControllerDriverStart (
  36. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  37. IN EFI_HANDLE Controller,
  38. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  39. );
  40. /**
  41. Stop this driver on ControllerHandle. Support stopping any child handles
  42. created by this driver.
  43. @param This Protocol instance pointer.
  44. @param ControllerHandle Handle of device to stop driver on
  45. @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
  46. children is zero stop the entire bus driver.
  47. @param ChildHandleBuffer List of Child Handles to Stop.
  48. @retval EFI_SUCCESS This driver is removed ControllerHandle
  49. @retval other This driver was not removed from this device
  50. **/
  51. EFI_STATUS
  52. EFIAPI
  53. KbdControllerDriverStop (
  54. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  55. IN EFI_HANDLE Controller,
  56. IN UINTN NumberOfChildren,
  57. IN EFI_HANDLE *ChildHandleBuffer
  58. );
  59. /**
  60. Free the waiting key notify list.
  61. @param ListHead Pointer to list head
  62. @retval EFI_INVALID_PARAMETER ListHead is NULL
  63. @retval EFI_SUCCESS Sucess to free NotifyList
  64. **/
  65. EFI_STATUS
  66. KbdFreeNotifyList (
  67. IN OUT LIST_ENTRY *ListHead
  68. );
  69. //
  70. // DriverBinding Protocol Instance
  71. //
  72. EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver = {
  73. KbdControllerDriverSupported,
  74. KbdControllerDriverStart,
  75. KbdControllerDriverStop,
  76. 0xa,
  77. NULL,
  78. NULL
  79. };
  80. /**
  81. Test controller is a keyboard Controller.
  82. @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
  83. @param Controller driver's controller
  84. @param RemainingDevicePath children device path
  85. @retval EFI_UNSUPPORTED controller is not floppy disk
  86. @retval EFI_SUCCESS controller is floppy disk
  87. **/
  88. EFI_STATUS
  89. EFIAPI
  90. KbdControllerDriverSupported (
  91. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  92. IN EFI_HANDLE Controller,
  93. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  94. )
  95. {
  96. EFI_STATUS Status;
  97. EFI_SIO_PROTOCOL *Sio;
  98. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  99. ACPI_HID_DEVICE_PATH *Acpi;
  100. //
  101. // Check whether the controller is keyboard.
  102. //
  103. Status = gBS->OpenProtocol (
  104. Controller,
  105. &gEfiDevicePathProtocolGuid,
  106. (VOID **) &DevicePath,
  107. This->DriverBindingHandle,
  108. Controller,
  109. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  110. );
  111. if (EFI_ERROR (Status)) {
  112. return Status;
  113. }
  114. do {
  115. Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;
  116. DevicePath = NextDevicePathNode (DevicePath);
  117. } while (!IsDevicePathEnd (DevicePath));
  118. if (DevicePathType (Acpi) != ACPI_DEVICE_PATH ||
  119. (DevicePathSubType (Acpi) != ACPI_DP && DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)) {
  120. return EFI_UNSUPPORTED;
  121. }
  122. if (Acpi->HID != EISA_PNP_ID (0x303) || Acpi->UID != 0) {
  123. return EFI_UNSUPPORTED;
  124. }
  125. //
  126. // Open the IO Abstraction(s) needed to perform the supported test
  127. //
  128. Status = gBS->OpenProtocol (
  129. Controller,
  130. &gEfiSioProtocolGuid,
  131. (VOID **) &Sio,
  132. This->DriverBindingHandle,
  133. Controller,
  134. EFI_OPEN_PROTOCOL_BY_DRIVER
  135. );
  136. if (EFI_ERROR (Status)) {
  137. return Status;
  138. }
  139. //
  140. // Close the I/O Abstraction(s) used to perform the supported test
  141. //
  142. gBS->CloseProtocol (
  143. Controller,
  144. &gEfiSioProtocolGuid,
  145. This->DriverBindingHandle,
  146. Controller
  147. );
  148. return Status;
  149. }
  150. /**
  151. Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
  152. @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
  153. @param Controller driver controller handle
  154. @param RemainingDevicePath Children's device path
  155. @retval whether success to create floppy control instance.
  156. **/
  157. EFI_STATUS
  158. EFIAPI
  159. KbdControllerDriverStart (
  160. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  161. IN EFI_HANDLE Controller,
  162. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  163. )
  164. {
  165. EFI_STATUS Status;
  166. EFI_STATUS Status1;
  167. EFI_SIO_PROTOCOL *Sio;
  168. KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
  169. UINT8 Data;
  170. EFI_STATUS_CODE_VALUE StatusCode;
  171. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  172. StatusCode = 0;
  173. Status = gBS->OpenProtocol (
  174. Controller,
  175. &gEfiDevicePathProtocolGuid,
  176. (VOID **) &DevicePath,
  177. This->DriverBindingHandle,
  178. Controller,
  179. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  180. );
  181. if (EFI_ERROR (Status)) {
  182. return Status;
  183. }
  184. //
  185. // Report that the keyboard is being enabled
  186. //
  187. REPORT_STATUS_CODE_WITH_DEVICE_PATH (
  188. EFI_PROGRESS_CODE,
  189. EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,
  190. DevicePath
  191. );
  192. //
  193. // Get the ISA I/O Protocol on Controller's handle
  194. //
  195. Status = gBS->OpenProtocol (
  196. Controller,
  197. &gEfiSioProtocolGuid,
  198. (VOID **) &Sio,
  199. This->DriverBindingHandle,
  200. Controller,
  201. EFI_OPEN_PROTOCOL_BY_DRIVER
  202. );
  203. if (EFI_ERROR (Status)) {
  204. return Status;
  205. }
  206. //
  207. // Allocate private data
  208. //
  209. ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV));
  210. if (ConsoleIn == NULL) {
  211. Status = EFI_OUT_OF_RESOURCES;
  212. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
  213. goto ErrorExit;
  214. }
  215. //
  216. // Setup the device instance
  217. //
  218. ConsoleIn->Signature = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE;
  219. ConsoleIn->Handle = Controller;
  220. (ConsoleIn->ConIn).Reset = KeyboardEfiReset;
  221. (ConsoleIn->ConIn).ReadKeyStroke = KeyboardReadKeyStroke;
  222. ConsoleIn->DataRegisterAddress = KEYBOARD_8042_DATA_REGISTER;
  223. ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER;
  224. ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
  225. ConsoleIn->DevicePath = DevicePath;
  226. ConsoleIn->ConInEx.Reset = KeyboardEfiResetEx;
  227. ConsoleIn->ConInEx.ReadKeyStrokeEx = KeyboardReadKeyStrokeEx;
  228. ConsoleIn->ConInEx.SetState = KeyboardSetState;
  229. ConsoleIn->ConInEx.RegisterKeyNotify = KeyboardRegisterKeyNotify;
  230. ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify;
  231. InitializeListHead (&ConsoleIn->NotifyList);
  232. //
  233. // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
  234. // When KBC decode (IO port 0x60/0x64 decode) is not enabled,
  235. // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS.
  236. // So instead we read status register to detect after read if KBC decode is enabled.
  237. //
  238. //
  239. // Return code is ignored on purpose.
  240. //
  241. if (!PcdGetBool (PcdFastPS2Detection)) {
  242. KeyboardRead (ConsoleIn, &Data);
  243. if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
  244. //
  245. // If nobody decodes KBC I/O port, it will read back as 0xFF.
  246. // Check the Time-Out and Parity bit to see if it has an active KBC in system
  247. //
  248. Status = EFI_DEVICE_ERROR;
  249. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
  250. goto ErrorExit;
  251. }
  252. }
  253. //
  254. // Setup the WaitForKey event
  255. //
  256. Status = gBS->CreateEvent (
  257. EVT_NOTIFY_WAIT,
  258. TPL_NOTIFY,
  259. KeyboardWaitForKey,
  260. ConsoleIn,
  261. &((ConsoleIn->ConIn).WaitForKey)
  262. );
  263. if (EFI_ERROR (Status)) {
  264. Status = EFI_OUT_OF_RESOURCES;
  265. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
  266. goto ErrorExit;
  267. }
  268. //
  269. // Setup the WaitForKeyEx event
  270. //
  271. Status = gBS->CreateEvent (
  272. EVT_NOTIFY_WAIT,
  273. TPL_NOTIFY,
  274. KeyboardWaitForKeyEx,
  275. ConsoleIn,
  276. &(ConsoleIn->ConInEx.WaitForKeyEx)
  277. );
  278. if (EFI_ERROR (Status)) {
  279. Status = EFI_OUT_OF_RESOURCES;
  280. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
  281. goto ErrorExit;
  282. }
  283. // Setup a periodic timer, used for reading keystrokes at a fixed interval
  284. //
  285. Status = gBS->CreateEvent (
  286. EVT_TIMER | EVT_NOTIFY_SIGNAL,
  287. TPL_NOTIFY,
  288. KeyboardTimerHandler,
  289. ConsoleIn,
  290. &ConsoleIn->TimerEvent
  291. );
  292. if (EFI_ERROR (Status)) {
  293. Status = EFI_OUT_OF_RESOURCES;
  294. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
  295. goto ErrorExit;
  296. }
  297. Status = gBS->SetTimer (
  298. ConsoleIn->TimerEvent,
  299. TimerPeriodic,
  300. KEYBOARD_TIMER_INTERVAL
  301. );
  302. if (EFI_ERROR (Status)) {
  303. Status = EFI_OUT_OF_RESOURCES;
  304. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
  305. goto ErrorExit;
  306. }
  307. Status = gBS->CreateEvent (
  308. EVT_NOTIFY_SIGNAL,
  309. TPL_CALLBACK,
  310. KeyNotifyProcessHandler,
  311. ConsoleIn,
  312. &ConsoleIn->KeyNotifyProcessEvent
  313. );
  314. if (EFI_ERROR (Status)) {
  315. Status = EFI_OUT_OF_RESOURCES;
  316. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
  317. goto ErrorExit;
  318. }
  319. REPORT_STATUS_CODE_WITH_DEVICE_PATH (
  320. EFI_PROGRESS_CODE,
  321. EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
  322. DevicePath
  323. );
  324. //
  325. // Reset the keyboard device
  326. //
  327. Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification));
  328. if (EFI_ERROR (Status)) {
  329. Status = EFI_DEVICE_ERROR;
  330. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
  331. goto ErrorExit;
  332. }
  333. REPORT_STATUS_CODE_WITH_DEVICE_PATH (
  334. EFI_PROGRESS_CODE,
  335. EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED,
  336. DevicePath
  337. );
  338. ConsoleIn->ControllerNameTable = NULL;
  339. AddUnicodeString2 (
  340. "eng",
  341. gPs2KeyboardComponentName.SupportedLanguages,
  342. &ConsoleIn->ControllerNameTable,
  343. L"PS/2 Keyboard Device",
  344. TRUE
  345. );
  346. AddUnicodeString2 (
  347. "en",
  348. gPs2KeyboardComponentName2.SupportedLanguages,
  349. &ConsoleIn->ControllerNameTable,
  350. L"PS/2 Keyboard Device",
  351. FALSE
  352. );
  353. //
  354. // Install protocol interfaces for the keyboard device.
  355. //
  356. Status = gBS->InstallMultipleProtocolInterfaces (
  357. &Controller,
  358. &gEfiSimpleTextInProtocolGuid,
  359. &ConsoleIn->ConIn,
  360. &gEfiSimpleTextInputExProtocolGuid,
  361. &ConsoleIn->ConInEx,
  362. NULL
  363. );
  364. if (EFI_ERROR (Status)) {
  365. StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
  366. goto ErrorExit;
  367. }
  368. return Status;
  369. ErrorExit:
  370. //
  371. // Report error code
  372. //
  373. if (StatusCode != 0) {
  374. REPORT_STATUS_CODE_WITH_DEVICE_PATH (
  375. EFI_ERROR_CODE | EFI_ERROR_MINOR,
  376. StatusCode,
  377. DevicePath
  378. );
  379. }
  380. if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
  381. gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);
  382. }
  383. if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
  384. gBS->CloseEvent (ConsoleIn->TimerEvent);
  385. }
  386. if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
  387. gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
  388. }
  389. if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {
  390. gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
  391. }
  392. KbdFreeNotifyList (&ConsoleIn->NotifyList);
  393. if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
  394. FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
  395. }
  396. //
  397. // Since there will be no timer handler for keyboard input any more,
  398. // exhaust input data just in case there is still keyboard data left
  399. //
  400. if (ConsoleIn != NULL) {
  401. Status1 = EFI_SUCCESS;
  402. while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) {
  403. Status1 = KeyboardRead (ConsoleIn, &Data);;
  404. }
  405. }
  406. if (ConsoleIn != NULL) {
  407. gBS->FreePool (ConsoleIn);
  408. }
  409. gBS->CloseProtocol (
  410. Controller,
  411. &gEfiSioProtocolGuid,
  412. This->DriverBindingHandle,
  413. Controller
  414. );
  415. return Status;
  416. }
  417. /**
  418. Stop this driver on ControllerHandle. Support stopping any child handles
  419. created by this driver.
  420. @param This Protocol instance pointer.
  421. @param ControllerHandle Handle of device to stop driver on
  422. @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
  423. children is zero stop the entire bus driver.
  424. @param ChildHandleBuffer List of Child Handles to Stop.
  425. @retval EFI_SUCCESS This driver is removed ControllerHandle
  426. @retval other This driver was not removed from this device
  427. **/
  428. EFI_STATUS
  429. EFIAPI
  430. KbdControllerDriverStop (
  431. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  432. IN EFI_HANDLE Controller,
  433. IN UINTN NumberOfChildren,
  434. IN EFI_HANDLE *ChildHandleBuffer
  435. )
  436. {
  437. EFI_STATUS Status;
  438. EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
  439. KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
  440. UINT8 Data;
  441. //
  442. // Disable Keyboard
  443. //
  444. Status = gBS->OpenProtocol (
  445. Controller,
  446. &gEfiSimpleTextInProtocolGuid,
  447. (VOID **) &ConIn,
  448. This->DriverBindingHandle,
  449. Controller,
  450. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  451. );
  452. if (EFI_ERROR (Status)) {
  453. return Status;
  454. }
  455. Status = gBS->OpenProtocol (
  456. Controller,
  457. &gEfiSimpleTextInputExProtocolGuid,
  458. NULL,
  459. This->DriverBindingHandle,
  460. Controller,
  461. EFI_OPEN_PROTOCOL_TEST_PROTOCOL
  462. );
  463. if (EFI_ERROR (Status)) {
  464. return Status;
  465. }
  466. ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
  467. //
  468. // Report that the keyboard is being disabled
  469. //
  470. REPORT_STATUS_CODE_WITH_DEVICE_PATH (
  471. EFI_PROGRESS_CODE,
  472. EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE,
  473. ConsoleIn->DevicePath
  474. );
  475. if (ConsoleIn->TimerEvent != NULL) {
  476. gBS->CloseEvent (ConsoleIn->TimerEvent);
  477. ConsoleIn->TimerEvent = NULL;
  478. }
  479. //
  480. // Since there will be no timer handler for keyboard input any more,
  481. // exhaust input data just in case there is still keyboard data left
  482. //
  483. Status = EFI_SUCCESS;
  484. while (!EFI_ERROR (Status)) {
  485. Status = KeyboardRead (ConsoleIn, &Data);;
  486. }
  487. //
  488. // Uninstall the SimpleTextIn and SimpleTextInEx protocols
  489. //
  490. Status = gBS->UninstallMultipleProtocolInterfaces (
  491. Controller,
  492. &gEfiSimpleTextInProtocolGuid,
  493. &ConsoleIn->ConIn,
  494. &gEfiSimpleTextInputExProtocolGuid,
  495. &ConsoleIn->ConInEx,
  496. NULL
  497. );
  498. if (EFI_ERROR (Status)) {
  499. return Status;
  500. }
  501. gBS->CloseProtocol (
  502. Controller,
  503. &gEfiSioProtocolGuid,
  504. This->DriverBindingHandle,
  505. Controller
  506. );
  507. //
  508. // Free other resources
  509. //
  510. if ((ConsoleIn->ConIn).WaitForKey != NULL) {
  511. gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);
  512. (ConsoleIn->ConIn).WaitForKey = NULL;
  513. }
  514. if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {
  515. gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
  516. ConsoleIn->ConInEx.WaitForKeyEx = NULL;
  517. }
  518. if (ConsoleIn->KeyNotifyProcessEvent != NULL) {
  519. gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
  520. ConsoleIn->KeyNotifyProcessEvent = NULL;
  521. }
  522. KbdFreeNotifyList (&ConsoleIn->NotifyList);
  523. FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
  524. gBS->FreePool (ConsoleIn);
  525. return EFI_SUCCESS;
  526. }
  527. /**
  528. Free the waiting key notify list.
  529. @param ListHead Pointer to list head
  530. @retval EFI_INVALID_PARAMETER ListHead is NULL
  531. @retval EFI_SUCCESS Sucess to free NotifyList
  532. **/
  533. EFI_STATUS
  534. KbdFreeNotifyList (
  535. IN OUT LIST_ENTRY *ListHead
  536. )
  537. {
  538. KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
  539. if (ListHead == NULL) {
  540. return EFI_INVALID_PARAMETER;
  541. }
  542. while (!IsListEmpty (ListHead)) {
  543. NotifyNode = CR (
  544. ListHead->ForwardLink,
  545. KEYBOARD_CONSOLE_IN_EX_NOTIFY,
  546. NotifyEntry,
  547. KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
  548. );
  549. RemoveEntryList (ListHead->ForwardLink);
  550. gBS->FreePool (NotifyNode);
  551. }
  552. return EFI_SUCCESS;
  553. }
  554. /**
  555. The module Entry Point for module Ps2Keyboard.
  556. @param[in] ImageHandle The firmware allocated handle for the EFI image.
  557. @param[in] SystemTable A pointer to the EFI System Table.
  558. @retval EFI_SUCCESS The entry point is executed successfully.
  559. @retval other Some error occurs when executing this entry point.
  560. **/
  561. EFI_STATUS
  562. EFIAPI
  563. InitializePs2Keyboard(
  564. IN EFI_HANDLE ImageHandle,
  565. IN EFI_SYSTEM_TABLE *SystemTable
  566. )
  567. {
  568. EFI_STATUS Status;
  569. //
  570. // Install driver model protocol(s).
  571. //
  572. Status = EfiLibInstallDriverBindingComponentName2 (
  573. ImageHandle,
  574. SystemTable,
  575. &gKeyboardControllerDriver,
  576. ImageHandle,
  577. &gPs2KeyboardComponentName,
  578. &gPs2KeyboardComponentName2
  579. );
  580. ASSERT_EFI_ERROR (Status);
  581. return Status;
  582. }