]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Core/Dxe/Event/event.c
Add some definitions for efi event in Uefi/UefiSpec.h to follow spec.
[mirror_edk2.git] / EdkModulePkg / Core / Dxe / Event / event.c
CommitLineData
6652e7be 1/*++\r
2\r
ce8bd86e 3Copyright (c) 2006 - 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
6652e7be 11\r
12Module Name:\r
13\r
14 event.c\r
15\r
16Abstract:\r
17\r
18 EFI Event support\r
ce8bd86e 19\r
6652e7be 20--*/\r
21\r
22\r
23#include <DxeMain.h>\r
24\r
25//\r
26// Enumerate the valid types\r
27//\r
28UINT32 mEventTable[] = {\r
29 //\r
30 // 0x80000200 Timer event with a notification function that is\r
31 // queue when the event is signaled with SignalEvent()\r
32 //\r
93b0fbc8 33 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
6652e7be 34 //\r
35 // 0x80000000 Timer event without a notification function. It can be\r
36 // signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().\r
37 //\r
93b0fbc8 38 EVT_TIMER,\r
6652e7be 39 //\r
ce8bd86e 40 // 0x00000100 Generic event with a notification function that\r
6652e7be 41 // can be waited on with CheckEvent() or WaitForEvent()\r
42 //\r
93b0fbc8 43 EVT_NOTIFY_WAIT,\r
6652e7be 44 //\r
ce8bd86e 45 // 0x00000200 Generic event with a notification function that\r
6652e7be 46 // is queue when the event is signaled with SignalEvent()\r
47 //\r
93b0fbc8 48 EVT_NOTIFY_SIGNAL,\r
6652e7be 49 //\r
ce8bd86e 50 // 0x00000201 ExitBootServicesEvent.\r
6652e7be 51 //\r
93b0fbc8 52 EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
6652e7be 53 //\r
54 // 0x60000202 SetVirtualAddressMapEvent.\r
55 //\r
93b0fbc8 56 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
6652e7be 57\r
6652e7be 58 //\r
ce8bd86e 59 // 0x00000000 Generic event without a notification function.\r
60 // It can be signaled with SignalEvent() and checked with CheckEvent()\r
6652e7be 61 // or WaitForEvent().\r
62 //\r
63 0x00000000,\r
64 //\r
ce8bd86e 65 // 0x80000100 Timer event with a notification function that can be\r
6652e7be 66 // waited on with CheckEvent() or WaitForEvent()\r
67 //\r
93b0fbc8 68 EVT_TIMER | EVT_NOTIFY_WAIT,\r
6652e7be 69};\r
70\r
1cc8ee78 71STATIC\r
6652e7be 72VOID\r
73CoreAcquireEventLock (\r
74 VOID\r
75 )\r
76/*++\r
77\r
78Routine Description:\r
79\r
80 Enter critical section by acquiring the lock on gEventQueueLock.\r
81\r
82Arguments:\r
83\r
84 None\r
85\r
86Returns:\r
87\r
88 None\r
89\r
90--*/\r
91{\r
92 CoreAcquireLock (&gEventQueueLock);\r
93}\r
94\r
1cc8ee78 95STATIC\r
6652e7be 96VOID\r
97CoreReleaseEventLock (\r
98 VOID\r
99 )\r
100/*++\r
101\r
102Routine Description:\r
103\r
104 Exit critical section by releasing the lock on gEventQueueLock.\r
105\r
106Arguments:\r
107\r
108 None\r
109\r
110Returns:\r
111\r
112 None\r
113\r
114--*/\r
115{\r
116 CoreReleaseLock (&gEventQueueLock);\r
117}\r
118\r
119\r
120EFI_STATUS\r
121CoreInitializeEventServices (\r
122 VOID\r
123 )\r
124/*++\r
125\r
126Routine Description:\r
127\r
128 Initializes "event" support and populates parts of the System and Runtime Table.\r
129\r
130Arguments:\r
131\r
132 None\r
ce8bd86e 133\r
6652e7be 134Returns:\r
135\r
136 EFI_SUCCESS - Always return success\r
137\r
138--*/\r
139{\r
140 UINTN Index;\r
141\r
93b0fbc8 142 for (Index=0; Index <= TPL_HIGH_LEVEL; Index++) {\r
6652e7be 143 InitializeListHead (&gEventQueue[Index]);\r
144 }\r
145\r
146 CoreInitializeTimer ();\r
ce8bd86e 147\r
6652e7be 148 return EFI_SUCCESS;\r
149}\r
150\r
151\r
6652e7be 152VOID\r
153CoreDispatchEventNotifies (\r
154 IN EFI_TPL Priority\r
155 )\r
156/*++\r
157\r
158Routine Description:\r
159\r
ce8bd86e 160 Dispatches all pending events.\r
6652e7be 161\r
162Arguments:\r
163\r
164 Priority - The task priority level of event notifications to dispatch\r
ce8bd86e 165\r
6652e7be 166Returns:\r
167\r
168 None\r
169\r
170--*/\r
171{\r
172 IEVENT *Event;\r
173 LIST_ENTRY *Head;\r
ce8bd86e 174\r
6652e7be 175 CoreAcquireEventLock ();\r
176 ASSERT (gEventQueueLock.OwnerTpl == Priority);\r
177 Head = &gEventQueue[Priority];\r
178\r
179 //\r
180 // Dispatch all the pending notifications\r
181 //\r
182 while (!IsListEmpty (Head)) {\r
ce8bd86e 183\r
6652e7be 184 Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);\r
185 RemoveEntryList (&Event->NotifyLink);\r
186\r
187 Event->NotifyLink.ForwardLink = NULL;\r
188\r
189 //\r
190 // Only clear the SIGNAL status if it is a SIGNAL type event.\r
191 // WAIT type events are only cleared in CheckEvent()\r
192 //\r
93b0fbc8 193 if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
6652e7be 194 Event->SignalCount = 0;\r
195 }\r
196\r
197 CoreReleaseEventLock ();\r
ce8bd86e 198\r
6652e7be 199 //\r
200 // Notify this event\r
201 //\r
202 ASSERT (Event->NotifyFunction != NULL);\r
203 Event->NotifyFunction (Event, Event->NotifyContext);\r
204\r
205 //\r
206 // Check for next pending event\r
207 //\r
208 CoreAcquireEventLock ();\r
209 }\r
210\r
211 gEventPending &= ~(1 << Priority);\r
212 CoreReleaseEventLock ();\r
213}\r
214\r
215\r
6652e7be 216STATIC\r
1cc8ee78 217VOID\r
6652e7be 218CoreNotifyEvent (\r
219 IN IEVENT *Event\r
220 )\r
221/*++\r
222\r
223Routine Description:\r
224\r
225 Queues the event's notification function to fire\r
226\r
227Arguments:\r
228\r
229 Event - The Event to notify\r
ce8bd86e 230\r
6652e7be 231Returns:\r
232\r
233 None\r
234\r
235--*/\r
236{\r
237\r
238 //\r
239 // Event database must be locked\r
240 //\r
241 ASSERT_LOCKED (&gEventQueueLock);\r
242\r
243 //\r
244 // If the event is queued somewhere, remove it\r
245 //\r
246\r
247 if (Event->NotifyLink.ForwardLink != NULL) {\r
248 RemoveEntryList (&Event->NotifyLink);\r
249 Event->NotifyLink.ForwardLink = NULL;\r
250 }\r
251\r
ce8bd86e 252 //\r
6652e7be 253 // Queue the event to the pending notification list\r
254 //\r
255\r
256 InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);\r
257 gEventPending |= (UINTN)(1 << Event->NotifyTpl);\r
258}\r
259\r
260\r
261\r
262VOID\r
263CoreNotifySignalList (\r
264 IN EFI_GUID *EventGroup\r
265 )\r
266/*++\r
267\r
268Routine Description:\r
269 Signals all events in the EventGroup\r
270\r
271Arguments:\r
272 EventGroup - The list to signal\r
ce8bd86e 273\r
6652e7be 274Returns:\r
275\r
276 None\r
277\r
278--*/\r
279{\r
280 LIST_ENTRY *Link;\r
281 LIST_ENTRY *Head;\r
282 IEVENT *Event;\r
283\r
284 CoreAcquireEventLock ();\r
285\r
286 Head = &gEventSignalQueue;\r
287 for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
288 Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);\r
289 if (CompareGuid (&Event->EventGroup, EventGroup)) {\r
290 CoreNotifyEvent (Event);\r
291 }\r
292 }\r
293\r
294 CoreReleaseEventLock ();\r
295}\r
296\r
6652e7be 297EFI_STATUS\r
298EFIAPI\r
299CoreCreateEvent (\r
300 IN UINT32 Type,\r
301 IN EFI_TPL NotifyTpl,\r
302 IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL\r
303 IN VOID *NotifyContext, OPTIONAL\r
304 OUT EFI_EVENT *Event\r
305 )\r
306/*++\r
307\r
308Routine Description:\r
309 Creates a general-purpose event structure\r
310\r
311Arguments:\r
312 Type - The type of event to create and its mode and attributes\r
313 NotifyTpl - The task priority level of event notifications\r
314 NotifyFunction - Pointer to the events notification function\r
315 NotifyContext - Pointer to the notification functions context; corresponds to\r
316 parameter "Context" in the notification function\r
317 Event - Pointer to the newly created event if the call succeeds; undefined otherwise\r
318\r
319Returns:\r
320 EFI_SUCCESS - The event structure was created\r
321 EFI_INVALID_PARAMETER - One of the parameters has an invalid value\r
322 EFI_OUT_OF_RESOURCES - The event could not be allocated\r
323\r
324--*/\r
ce8bd86e 325{\r
6652e7be 326 EFI_GUID *GuidPtr;\r
327 EFI_EVENT_NOTIFY Function;\r
ce8bd86e 328\r
6652e7be 329 GuidPtr = NULL;\r
330 Function = NotifyFunction;\r
331\r
6652e7be 332 //\r
333 // Convert EFI 1.10 Events to thier UEFI 2.0 CreateEventEx mapping\r
ce8bd86e 334 //\r
93b0fbc8 335 if (Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) {\r
6652e7be 336 GuidPtr = &gEfiEventExitBootServicesGuid;\r
93b0fbc8 337 } else if (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {\r
6652e7be 338 GuidPtr = &gEfiEventVirtualAddressChangeGuid;\r
339 }\r
ce8bd86e 340\r
6652e7be 341 return CoreCreateEventEx (Type, NotifyTpl, Function, NotifyContext, GuidPtr, Event);\r
342}\r
343\r
344\r
345EFI_STATUS\r
346EFIAPI\r
347CoreCreateEventEx (\r
348 IN UINT32 Type,\r
349 IN EFI_TPL NotifyTpl,\r
350 IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL\r
351 IN CONST VOID *NotifyContext, OPTIONAL\r
352 IN CONST EFI_GUID *EventGroup, OPTIONAL\r
353 OUT EFI_EVENT *Event\r
354 )\r
355/*++\r
356\r
357Routine Description:\r
358 Creates a general-purpose event structure\r
359\r
360Arguments:\r
361 Type - The type of event to create and its mode and attributes\r
362 NotifyTpl - The task priority level of event notifications\r
363 NotifyFunction - Pointer to the events notification function\r
364 NotifyContext - Pointer to the notification functions context; corresponds to\r
365 parameter "Context" in the notification function\r
366 EventGrout - GUID for EventGroup if NULL act the same as gBS->CreateEvent().\r
367 Event - Pointer to the newly created event if the call succeeds; undefined otherwise\r
368\r
369Returns:\r
370 EFI_SUCCESS - The event structure was created\r
371 EFI_INVALID_PARAMETER - One of the parameters has an invalid value\r
372 EFI_OUT_OF_RESOURCES - The event could not be allocated\r
373\r
374--*/\r
375{\r
376 EFI_STATUS Status;\r
377 IEVENT *IEvent;\r
378 INTN Index;\r
379\r
380\r
93b0fbc8 381 if ((Event == NULL) || (NotifyTpl == TPL_APPLICATION)) {\r
6652e7be 382 return EFI_INVALID_PARAMETER;\r
383 }\r
384\r
385 //\r
386 // Check to make sure no reserved flags are set\r
387 //\r
388 Status = EFI_INVALID_PARAMETER;\r
389 for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) {\r
390 if (Type == mEventTable[Index]) {\r
391 Status = EFI_SUCCESS;\r
392 break;\r
393 }\r
394 }\r
395 if(EFI_ERROR (Status)) {\r
396 return EFI_INVALID_PARAMETER;\r
397 }\r
398\r
399 //\r
400 // If it's a notify type of event, check its parameters\r
401 //\r
93b0fbc8 402 if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL))) {\r
6652e7be 403 //\r
404 // Check for an invalid NotifyFunction or NotifyTpl\r
405 //\r
ce8bd86e 406 if ((NotifyFunction == NULL) ||\r
93b0fbc8 407 (NotifyTpl < TPL_APPLICATION) ||\r
408 (NotifyTpl >= TPL_HIGH_LEVEL)) {\r
6652e7be 409 return EFI_INVALID_PARAMETER;\r
410 }\r
411\r
412 } else {\r
413 //\r
414 // No notification needed, zero ignored values\r
415 //\r
416 NotifyTpl = 0;\r
417 NotifyFunction = NULL;\r
418 NotifyContext = NULL;\r
419 }\r
420\r
421 //\r
422 // Allcoate and initialize a new event structure.\r
423 //\r
424 Status = CoreAllocatePool (\r
93b0fbc8 425 (Type & EVT_RUNTIME) ? EfiRuntimeServicesData: EfiBootServicesData,\r
6652e7be 426 sizeof (IEVENT),\r
427 (VOID **)&IEvent\r
428 );\r
429 if (EFI_ERROR (Status)) {\r
430 return EFI_OUT_OF_RESOURCES;\r
431 }\r
432\r
433 SetMem (IEvent, sizeof (IEVENT), 0);\r
434\r
435 IEvent->Signature = EVENT_SIGNATURE;\r
436 IEvent->Type = Type;\r
ce8bd86e 437\r
6652e7be 438 IEvent->NotifyTpl = NotifyTpl;\r
439 IEvent->NotifyFunction = NotifyFunction;\r
440 IEvent->NotifyContext = (VOID *)NotifyContext;\r
441 if (EventGroup != NULL) {\r
442 CopyGuid (&IEvent->EventGroup, EventGroup);\r
443 IEvent->ExFlag = TRUE;\r
444 }\r
445\r
446 *Event = IEvent;\r
447\r
93b0fbc8 448 if (Type & EVT_RUNTIME) {\r
6652e7be 449 //\r
450 // Keep a list of all RT events so we can tell the RT AP.\r
451 //\r
3ec2611d
LG
452 IEvent->RuntimeData.Type = Type;\r
453 IEvent->RuntimeData.NotifyTpl = NotifyTpl;\r
454 IEvent->RuntimeData.NotifyFunction = NotifyFunction;\r
455 IEvent->RuntimeData.NotifyContext = (VOID *) NotifyContext;\r
456 IEvent->RuntimeData.Event = (EFI_EVENT *) IEvent;\r
457 InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link);\r
6652e7be 458 }\r
459\r
460 CoreAcquireEventLock ();\r
ce8bd86e 461\r
93b0fbc8 462 if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) {\r
6652e7be 463 //\r
464 // The Event's NotifyFunction must be queued whenever the event is signaled\r
465 //\r
466 InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);\r
467 }\r
ce8bd86e 468\r
6652e7be 469 CoreReleaseEventLock ();\r
ce8bd86e 470\r
6652e7be 471 //\r
472 // Done\r
473 //\r
474 return EFI_SUCCESS;\r
475}\r
476\r
477\r
478\r
479EFI_STATUS\r
480EFIAPI\r
481CoreSignalEvent (\r
482 IN EFI_EVENT UserEvent\r
483 )\r
484/*++\r
485\r
486Routine Description:\r
487\r
488 Signals the event. Queues the event to be notified if needed\r
ce8bd86e 489\r
6652e7be 490Arguments:\r
491\r
492 UserEvent - The event to signal\r
ce8bd86e 493\r
6652e7be 494Returns:\r
495\r
496 EFI_INVALID_PARAMETER - Parameters are not valid.\r
ce8bd86e 497\r
6652e7be 498 EFI_SUCCESS - The event was signaled.\r
499\r
500--*/\r
501{\r
502 IEVENT *Event;\r
503\r
504 Event = UserEvent;\r
505\r
506 if (Event == NULL) {\r
507 return EFI_INVALID_PARAMETER;\r
508 }\r
509\r
510 if (Event->Signature != EVENT_SIGNATURE) {\r
511 return EFI_INVALID_PARAMETER;\r
512 }\r
513\r
514 CoreAcquireEventLock ();\r
515\r
516 //\r
517 // If the event is not already signalled, do so\r
518 //\r
519\r
520 if (Event->SignalCount == 0x00000000) {\r
521 Event->SignalCount++;\r
522\r
523 //\r
524 // If signalling type is a notify function, queue it\r
525 //\r
93b0fbc8 526 if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
6652e7be 527 if (Event->ExFlag) {\r
528 //\r
ce8bd86e 529 // The CreateEventEx() style requires all members of the Event Group\r
530 // to be signaled.\r
6652e7be 531 //\r
532 CoreReleaseEventLock ();\r
533 CoreNotifySignalList (&Event->EventGroup);\r
534 CoreAcquireEventLock ();\r
535 } else {\r
536 CoreNotifyEvent (Event);\r
537 }\r
538 }\r
539 }\r
540\r
541 CoreReleaseEventLock ();\r
542 return EFI_SUCCESS;\r
543}\r
544\r
545\r
546EFI_STATUS\r
547EFIAPI\r
548CoreCheckEvent (\r
549 IN EFI_EVENT UserEvent\r
550 )\r
551/*++\r
552\r
553Routine Description:\r
554\r
555 Check the status of an event\r
ce8bd86e 556\r
6652e7be 557Arguments:\r
558\r
559 UserEvent - The event to check\r
ce8bd86e 560\r
6652e7be 561Returns:\r
562\r
563 EFI_SUCCESS - The event is in the signaled state\r
564 EFI_NOT_READY - The event is not in the signaled state\r
565 EFI_INVALID_PARAMETER - Event is of type EVT_NOTIFY_SIGNAL\r
566\r
567--*/\r
568\r
569{\r
570 IEVENT *Event;\r
571 EFI_STATUS Status;\r
572\r
573 Event = UserEvent;\r
574\r
575 if (Event == NULL) {\r
576 return EFI_INVALID_PARAMETER;\r
577 }\r
578\r
579 if (Event->Signature != EVENT_SIGNATURE) {\r
580 return EFI_INVALID_PARAMETER;\r
581 }\r
582\r
93b0fbc8 583 if (Event->Type & EVT_NOTIFY_SIGNAL) {\r
6652e7be 584 return EFI_INVALID_PARAMETER;\r
585 }\r
586\r
587 Status = EFI_NOT_READY;\r
588\r
93b0fbc8 589 if (!Event->SignalCount && (Event->Type & EVT_NOTIFY_WAIT)) {\r
6652e7be 590\r
591 //\r
592 // Queue the wait notify function\r
593 //\r
594\r
595 CoreAcquireEventLock ();\r
596 if (!Event->SignalCount) {\r
597 CoreNotifyEvent (Event);\r
598 }\r
599 CoreReleaseEventLock ();\r
600 }\r
601\r
602 //\r
603 // If the even looks signalled, get the lock and clear it\r
604 //\r
605\r
606 if (Event->SignalCount) {\r
607 CoreAcquireEventLock ();\r
608\r
609 if (Event->SignalCount) {\r
610 Event->SignalCount = 0;\r
611 Status = EFI_SUCCESS;\r
612 }\r
613\r
614 CoreReleaseEventLock ();\r
615 }\r
616\r
617 return Status;\r
618}\r
619\r
620\r
621\r
622EFI_STATUS\r
623EFIAPI\r
624CoreWaitForEvent (\r
625 IN UINTN NumberOfEvents,\r
626 IN EFI_EVENT *UserEvents,\r
627 OUT UINTN *UserIndex\r
628 )\r
629/*++\r
630\r
631Routine Description:\r
632\r
633 Stops execution until an event is signaled.\r
ce8bd86e 634\r
6652e7be 635Arguments:\r
636\r
637 NumberOfEvents - The number of events in the UserEvents array\r
638 UserEvents - An array of EFI_EVENT\r
639 UserIndex - Pointer to the index of the event which satisfied the wait condition\r
ce8bd86e 640\r
6652e7be 641Returns:\r
642\r
643 EFI_SUCCESS - The event indicated by Index was signaled.\r
ce8bd86e 644 EFI_INVALID_PARAMETER - The event indicated by Index has a notification function or\r
6652e7be 645 Event was not a valid type\r
646 EFI_UNSUPPORTED - The current TPL is not TPL_APPLICATION\r
647\r
648--*/\r
649\r
650{\r
651 EFI_STATUS Status;\r
652 UINTN Index;\r
653\r
654 //\r
655 // Can only WaitForEvent at TPL_APPLICATION\r
656 //\r
93b0fbc8 657 if (gEfiCurrentTpl != TPL_APPLICATION) {\r
6652e7be 658 return EFI_UNSUPPORTED;\r
659 }\r
660\r
661 for(;;) {\r
ce8bd86e 662\r
6652e7be 663 for(Index = 0; Index < NumberOfEvents; Index++) {\r
664\r
665 Status = CoreCheckEvent (UserEvents[Index]);\r
666\r
667 //\r
668 // provide index of event that caused problem\r
669 //\r
670 if (Status != EFI_NOT_READY) {\r
671 *UserIndex = Index;\r
672 return Status;\r
673 }\r
674 }\r
675\r
676 //\r
677 // This was the location of the Idle loop callback in EFI 1.x reference\r
678 // code. We don't have that concept in this base at this point.\r
ce8bd86e 679 //\r
6652e7be 680 }\r
681}\r
682\r
683\r
684EFI_STATUS\r
685EFIAPI\r
686CoreCloseEvent (\r
687 IN EFI_EVENT UserEvent\r
688 )\r
689/*++\r
690\r
691Routine Description:\r
692\r
693 Closes an event and frees the event structure.\r
ce8bd86e 694\r
6652e7be 695Arguments:\r
696\r
697 UserEvent - Event to close\r
ce8bd86e 698\r
6652e7be 699Returns:\r
700\r
701 EFI_INVALID_PARAMETER - Parameters are not valid.\r
ce8bd86e 702\r
6652e7be 703 EFI_SUCCESS - The event has been closed\r
704\r
705--*/\r
706\r
707{\r
708 EFI_STATUS Status;\r
709 IEVENT *Event;\r
710\r
711 Event = UserEvent;\r
712\r
713 if (Event == NULL) {\r
714 return EFI_INVALID_PARAMETER;\r
715 }\r
716\r
717 if (Event->Signature != EVENT_SIGNATURE) {\r
718 return EFI_INVALID_PARAMETER;\r
719 }\r
720\r
721 //\r
722 // If it's a timer event, make sure it's not pending\r
723 //\r
93b0fbc8 724 if (Event->Type & EVT_TIMER) {\r
6652e7be 725 CoreSetTimer (Event, TimerCancel, 0);\r
726 }\r
727\r
728 CoreAcquireEventLock ();\r
729\r
730 //\r
731 // If the event is queued somewhere, remove it\r
732 //\r
ce8bd86e 733\r
3ec2611d
LG
734 if (Event->RuntimeData.Link.ForwardLink != NULL) {\r
735 RemoveEntryList (&Event->RuntimeData.Link);\r
6652e7be 736 }\r
ce8bd86e 737\r
6652e7be 738 if (Event->NotifyLink.ForwardLink != NULL) {\r
739 RemoveEntryList (&Event->NotifyLink);\r
740 }\r
741\r
742 if (Event->SignalLink.ForwardLink != NULL) {\r
743 RemoveEntryList (&Event->SignalLink);\r
744 }\r
745\r
746 CoreReleaseEventLock ();\r
747\r
748 //\r
749 // If the event is registered on a protocol notify, then remove it from the protocol database\r
750 //\r
751 CoreUnregisterProtocolNotify (Event);\r
752\r
753 Status = CoreFreePool (Event);\r
754 ASSERT_EFI_ERROR (Status);\r
755\r
756 return Status;\r
757}\r