3 Copyright (c) 2005 - 2007, 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
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.
24 #include <Protocol/ServiceBinding.h>
25 #include <Protocol/SimpleNetwork.h>
26 #include <Protocol/LoadedImage.h>
27 #include <Protocol/NicIp4Config.h>
28 #include <Protocol/ComponentName.h>
29 #include <Protocol/ComponentName2.h>
31 #include <Library/NetLib.h>
32 #include <Library/BaseLib.h>
33 #include <Library/DebugLib.h>
34 #include <Library/BaseMemoryLib.h>
35 #include <Library/UefiBootServicesTableLib.h>
36 #include <Library/UefiRuntimeServicesTableLib.h>
37 #include <Library/UefiLib.h>
38 #include <Library/MemoryAllocationLib.h>
41 EFI_DPC_PROTOCOL
*mDpc
= NULL
;
44 // All the supported IP4 maskes in host byte order.
46 IP4_ADDR mIp4AllMasks
[IP4_MASK_NUM
] = {
85 EFI_IPv4_ADDRESS mZeroIp4Addr
= {{0, 0, 0, 0}};
88 Converts the low nibble of a byte to hex unicode character.
90 @param Nibble lower nibble of a byte.
92 @return Hex unicode character.
102 // This library interface is simply obsolete.
103 // Include the source code to user code.
108 return (CHAR16
)(Nibble
+ L
'0');
111 return (CHAR16
)(Nibble
- 0xA + L
'A');
115 Return the length of the mask. If the mask is invalid,
116 return the invalid length 33, which is IP4_MASK_NUM.
117 NetMask is in the host byte order.
119 @param NetMask The netmask to get the length from
121 @return The length of the netmask, IP4_MASK_NUM if the mask isn't
133 for (Index
= 0; Index
< IP4_MASK_NUM
; Index
++) {
134 if (NetMask
== mIp4AllMasks
[Index
]) {
145 Return the class of the address, such as class a, b, c.
146 Addr is in host byte order.
148 @param Addr The address to get the class from
150 @return IP address class, such as IP4_ADDR_CLASSA
161 ByteOne
= (UINT8
) (Addr
>> 24);
163 if ((ByteOne
& 0x80) == 0) {
164 return IP4_ADDR_CLASSA
;
166 } else if ((ByteOne
& 0xC0) == 0x80) {
167 return IP4_ADDR_CLASSB
;
169 } else if ((ByteOne
& 0xE0) == 0xC0) {
170 return IP4_ADDR_CLASSC
;
172 } else if ((ByteOne
& 0xF0) == 0xE0) {
173 return IP4_ADDR_CLASSD
;
176 return IP4_ADDR_CLASSE
;
183 Check whether the IP is a valid unicast address according to
184 the netmask. If NetMask is zero, use the IP address's class to
185 get the default mask.
187 @param Ip The IP to check againist
188 @param NetMask The mask of the IP
190 @return TRUE if IP is a valid unicast address on the network, otherwise FALSE
202 Class
= NetGetIpClass (Ip
);
204 if ((Ip
== 0) || (Class
>= IP4_ADDR_CLASSD
)) {
209 NetMask
= mIp4AllMasks
[Class
<< 3];
212 if (((Ip
&~NetMask
) == ~NetMask
) || ((Ip
&~NetMask
) == 0)) {
221 Initialize a random seed using current time.
225 @return The random seed initialized with current time.
237 gRT
->GetTime (&Time
, NULL
);
238 Seed
= (~Time
.Hour
<< 24 | Time
.Day
<< 16 | Time
.Minute
<< 8 | Time
.Second
);
239 Seed
^= Time
.Nanosecond
;
240 Seed
^= Time
.Year
<< 7;
247 Extract a UINT32 from a byte stream, then convert it to host
248 byte order. Use this function to avoid alignment error.
250 @param Buf The buffer to extract the UINT32.
252 @return The UINT32 extracted.
263 CopyMem (&Value
, Buf
, sizeof (UINT32
));
264 return NTOHL (Value
);
269 Put a UINT32 to the byte stream. Convert it from host byte order
270 to network byte order before putting.
272 @param Buf The buffer to put the UINT32
273 @param Data The data to put
286 CopyMem (Buf
, &Data
, sizeof (UINT32
));
291 Remove the first entry on the list
293 @param Head The list header
295 @return The entry that is removed from the list, NULL if the list is empty.
306 ASSERT (Head
!= NULL
);
308 if (IsListEmpty (Head
)) {
312 First
= Head
->ForwardLink
;
313 Head
->ForwardLink
= First
->ForwardLink
;
314 First
->ForwardLink
->BackLink
= Head
;
317 First
->ForwardLink
= (LIST_ENTRY
*) NULL
;
318 First
->BackLink
= (LIST_ENTRY
*) NULL
;
326 Remove the last entry on the list
328 @param Head The list head
330 @return The entry that is removed from the list, NULL if the list is empty.
341 ASSERT (Head
!= NULL
);
343 if (IsListEmpty (Head
)) {
347 Last
= Head
->BackLink
;
348 Head
->BackLink
= Last
->BackLink
;
349 Last
->BackLink
->ForwardLink
= Head
;
352 Last
->ForwardLink
= (LIST_ENTRY
*) NULL
;
353 Last
->BackLink
= (LIST_ENTRY
*) NULL
;
361 Insert the NewEntry after the PrevEntry
363 @param PrevEntry The previous entry to insert after
364 @param NewEntry The new entry to insert
372 IN LIST_ENTRY
*PrevEntry
,
373 IN LIST_ENTRY
*NewEntry
376 NewEntry
->BackLink
= PrevEntry
;
377 NewEntry
->ForwardLink
= PrevEntry
->ForwardLink
;
378 PrevEntry
->ForwardLink
->BackLink
= NewEntry
;
379 PrevEntry
->ForwardLink
= NewEntry
;
384 Insert the NewEntry before the PostEntry
386 @param PostEntry The entry to insert before
387 @param NewEntry The new entry to insert
394 NetListInsertBefore (
395 IN LIST_ENTRY
*PostEntry
,
396 IN LIST_ENTRY
*NewEntry
399 NewEntry
->ForwardLink
= PostEntry
;
400 NewEntry
->BackLink
= PostEntry
->BackLink
;
401 PostEntry
->BackLink
->ForwardLink
= NewEntry
;
402 PostEntry
->BackLink
= NewEntry
;
407 Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
409 @param Map The netmap to initialize
420 ASSERT (Map
!= NULL
);
422 InitializeListHead (&Map
->Used
);
423 InitializeListHead (&Map
->Recycled
);
429 To clean up the netmap, that is, release allocated memories.
431 @param Map The netmap to clean up.
446 ASSERT (Map
!= NULL
);
448 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Used
) {
449 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
451 RemoveEntryList (&Item
->Link
);
454 gBS
->FreePool (Item
);
457 ASSERT ((Map
->Count
== 0) && IsListEmpty (&Map
->Used
));
459 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Recycled
) {
460 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
462 RemoveEntryList (&Item
->Link
);
463 gBS
->FreePool (Item
);
466 ASSERT (IsListEmpty (&Map
->Recycled
));
471 Test whether the netmap is empty
473 @param Map The net map to test
475 @return TRUE if the netmap is empty, otherwise FALSE.
484 ASSERT (Map
!= NULL
);
485 return (BOOLEAN
) (Map
->Count
== 0);
490 Return the number of the <Key, Value> pairs in the netmap.
492 @param Map The netmap to get the entry number
494 @return The entry number in the netmap.
508 Allocate an item for the netmap. It will try to allocate
509 a batch of items and return one.
511 @param Map The netmap to allocate item for
513 @return The allocated item or NULL
526 ASSERT (Map
!= NULL
);
528 Head
= &Map
->Recycled
;
530 if (IsListEmpty (Head
)) {
531 for (Index
= 0; Index
< NET_MAP_INCREAMENT
; Index
++) {
532 Item
= AllocatePool (sizeof (NET_MAP_ITEM
));
542 InsertHeadList (Head
, &Item
->Link
);
546 Item
= NET_LIST_HEAD (Head
, NET_MAP_ITEM
, Link
);
547 NetListRemoveHead (Head
);
554 Allocate an item to save the <Key, Value> pair to the head of the netmap.
556 @param Map The netmap to insert into
557 @param Key The user's key
558 @param Value The user's value for the key
560 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
561 @retval EFI_SUCCESS The item is inserted to the head
569 IN VOID
*Value OPTIONAL
574 ASSERT (Map
!= NULL
);
576 Item
= NetMapAllocItem (Map
);
579 return EFI_OUT_OF_RESOURCES
;
584 InsertHeadList (&Map
->Used
, &Item
->Link
);
592 Allocate an item to save the <Key, Value> pair to the tail of the netmap.
594 @param Map The netmap to insert into
595 @param Key The user's key
596 @param Value The user's value for the key
598 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
599 @retval EFI_SUCCESS The item is inserted to the tail
607 IN VOID
*Value OPTIONAL
612 ASSERT (Map
!= NULL
);
614 Item
= NetMapAllocItem (Map
);
617 return EFI_OUT_OF_RESOURCES
;
622 InsertTailList (&Map
->Used
, &Item
->Link
);
631 Check whther the item is in the Map
633 @param Map The netmap to search within
634 @param Item The item to search
636 @return TRUE if the item is in the netmap, otherwise FALSE.
643 IN NET_MAP_ITEM
*Item
646 LIST_ENTRY
*ListEntry
;
648 NET_LIST_FOR_EACH (ListEntry
, &Map
->Used
) {
649 if (ListEntry
== &Item
->Link
) {
659 Find the key in the netmap
661 @param Map The netmap to search within
662 @param Key The key to search
664 @return The point to the item contains the Key, or NULL if Key isn't in the map.
677 ASSERT (Map
!= NULL
);
679 NET_LIST_FOR_EACH (Entry
, &Map
->Used
) {
680 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
682 if (Item
->Key
== Key
) {
692 Remove the item from the netmap
694 @param Map The netmap to remove the item from
695 @param Item The item to remove
696 @param Value The variable to receive the value if not NULL
698 @return The key of the removed item.
705 IN NET_MAP_ITEM
*Item
,
706 OUT VOID
**Value OPTIONAL
709 ASSERT ((Map
!= NULL
) && (Item
!= NULL
));
710 ASSERT (NetItemInMap (Map
, Item
));
712 RemoveEntryList (&Item
->Link
);
714 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
717 *Value
= Item
->Value
;
725 Remove the first entry on the netmap
727 @param Map The netmap to remove the head from
728 @param Value The variable to receive the value if not NULL
730 @return The key of the item removed
737 OUT VOID
**Value OPTIONAL
743 // Often, it indicates a programming error to remove
744 // the first entry in an empty list
746 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
748 Item
= NET_LIST_HEAD (&Map
->Used
, NET_MAP_ITEM
, Link
);
749 RemoveEntryList (&Item
->Link
);
751 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
754 *Value
= Item
->Value
;
762 Remove the last entry on the netmap
764 @param Map The netmap to remove the tail from
765 @param Value The variable to receive the value if not NULL
767 @return The key of the item removed
774 OUT VOID
**Value OPTIONAL
780 // Often, it indicates a programming error to remove
781 // the last entry in an empty list
783 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
785 Item
= NET_LIST_TAIL (&Map
->Used
, NET_MAP_ITEM
, Link
);
786 RemoveEntryList (&Item
->Link
);
788 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
791 *Value
= Item
->Value
;
799 Iterate through the netmap and call CallBack for each item. It will
800 contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
801 from the loop. It returns the CallBack's last return value. This
802 function is delete safe for the current item.
804 @param Map The Map to iterate through
805 @param CallBack The callback function to call for each item.
806 @param Arg The opaque parameter to the callback
808 @return It returns the CallBack's last return value.
815 IN NET_MAP_CALLBACK CallBack
,
826 ASSERT ((Map
!= NULL
) && (CallBack
!= NULL
));
830 if (IsListEmpty (Head
)) {
834 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
835 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
836 Result
= CallBack (Map
, Item
, Arg
);
838 if (EFI_ERROR (Result
)) {
848 This is the default unload handle for all the network drivers.
850 @param ImageHandle The drivers' driver image.
852 @retval EFI_SUCCESS The image is unloaded.
853 @retval Others Failed to unload the image.
858 NetLibDefaultUnload (
859 IN EFI_HANDLE ImageHandle
863 EFI_HANDLE
*DeviceHandleBuffer
;
864 UINTN DeviceHandleCount
;
866 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
867 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
868 EFI_COMPONENT_NAME2_PROTOCOL
*ComponentName2
;
871 // Get the list of all the handles in the handle database.
872 // If there is an error getting the list, then the unload
875 Status
= gBS
->LocateHandleBuffer (
883 if (EFI_ERROR (Status
)) {
888 // Disconnect the driver specified by ImageHandle from all
889 // the devices in the handle database.
891 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
892 Status
= gBS
->DisconnectController (
893 DeviceHandleBuffer
[Index
],
900 // Uninstall all the protocols installed in the driver entry point
902 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
903 Status
= gBS
->HandleProtocol (
904 DeviceHandleBuffer
[Index
],
905 &gEfiDriverBindingProtocolGuid
,
906 (VOID
**) &DriverBinding
909 if (EFI_ERROR (Status
)) {
913 if (DriverBinding
->ImageHandle
!= ImageHandle
) {
917 gBS
->UninstallProtocolInterface (
919 &gEfiDriverBindingProtocolGuid
,
922 Status
= gBS
->HandleProtocol (
923 DeviceHandleBuffer
[Index
],
924 &gEfiComponentNameProtocolGuid
,
925 (VOID
**) &ComponentName
927 if (!EFI_ERROR (Status
)) {
928 gBS
->UninstallProtocolInterface (
930 &gEfiComponentNameProtocolGuid
,
935 Status
= gBS
->HandleProtocol (
936 DeviceHandleBuffer
[Index
],
937 &gEfiComponentName2ProtocolGuid
,
938 (VOID
**) &ComponentName2
940 if (!EFI_ERROR (Status
)) {
941 gBS
->UninstallProtocolInterface (
943 &gEfiComponentName2ProtocolGuid
,
950 // Free the buffer containing the list of handles from the handle database
952 if (DeviceHandleBuffer
!= NULL
) {
953 gBS
->FreePool (DeviceHandleBuffer
);
962 Create a child of the service that is identified by ServiceBindingGuid.
964 @param Controller The controller which has the service installed.
965 @param Image The image handle used to open service.
966 @param ServiceBindingGuid The service's Guid.
967 @param ChildHandle The handle to receive the create child
969 @retval EFI_SUCCESS The child is successfully created.
970 @retval Others Failed to create the child.
975 NetLibCreateServiceChild (
976 IN EFI_HANDLE Controller
,
978 IN EFI_GUID
*ServiceBindingGuid
,
979 OUT EFI_HANDLE
*ChildHandle
983 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
986 ASSERT ((ServiceBindingGuid
!= NULL
) && (ChildHandle
!= NULL
));
989 // Get the ServiceBinding Protocol
991 Status
= gBS
->OpenProtocol (
997 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1000 if (EFI_ERROR (Status
)) {
1007 Status
= Service
->CreateChild (Service
, ChildHandle
);
1013 Destory a child of the service that is identified by ServiceBindingGuid.
1015 @param Controller The controller which has the service installed.
1016 @param Image The image handle used to open service.
1017 @param ServiceBindingGuid The service's Guid.
1018 @param ChildHandle The child to destory
1020 @retval EFI_SUCCESS The child is successfully destoried.
1021 @retval Others Failed to destory the child.
1026 NetLibDestroyServiceChild (
1027 IN EFI_HANDLE Controller
,
1028 IN EFI_HANDLE Image
,
1029 IN EFI_GUID
*ServiceBindingGuid
,
1030 IN EFI_HANDLE ChildHandle
1034 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1036 ASSERT (ServiceBindingGuid
!= NULL
);
1039 // Get the ServiceBinding Protocol
1041 Status
= gBS
->OpenProtocol (
1047 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1050 if (EFI_ERROR (Status
)) {
1055 // destory the child
1057 Status
= Service
->DestroyChild (Service
, ChildHandle
);
1063 Convert the mac address of the simple network protocol installed on
1064 SnpHandle to a unicode string. Callers are responsible for freeing the
1067 @param SnpHandle The handle where the simple network protocol is
1069 @param ImageHandle The image handle used to act as the agent handle to
1070 get the simple network protocol.
1071 @param MacString The pointer to store the address of the string
1072 representation of the mac address.
1074 @retval EFI_OUT_OF_RESOURCES There are not enough memory resource.
1075 @retval other Failed to open the simple network protocol.
1080 NetLibGetMacString (
1081 IN EFI_HANDLE SnpHandle
,
1082 IN EFI_HANDLE ImageHandle
,
1083 IN OUT CHAR16
**MacString
1087 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1088 EFI_SIMPLE_NETWORK_MODE
*Mode
;
1095 // Get the Simple Network protocol from the SnpHandle.
1097 Status
= gBS
->OpenProtocol (
1099 &gEfiSimpleNetworkProtocolGuid
,
1103 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1105 if (EFI_ERROR (Status
)) {
1112 // It takes 2 unicode characters to represent a 1 byte binary buffer.
1113 // Plus one unicode character for the null-terminator.
1115 MacAddress
= AllocatePool ((2 * Mode
->HwAddressSize
+ 1) * sizeof (CHAR16
));
1116 if (MacAddress
== NULL
) {
1117 return EFI_OUT_OF_RESOURCES
;
1121 // Convert the mac address into a unicode string.
1123 for (Index
= 0; Index
< Mode
->HwAddressSize
; Index
++) {
1124 MacAddress
[Index
* 2] = NibbleToHexChar ((UINT8
) (Mode
->CurrentAddress
.Addr
[Index
] >> 4));
1125 MacAddress
[Index
* 2 + 1] = NibbleToHexChar (Mode
->CurrentAddress
.Addr
[Index
]);
1128 MacAddress
[Mode
->HwAddressSize
* 2] = L
'\0';
1130 *MacString
= MacAddress
;
1136 Check the default address used by the IPv4 driver is static or dynamic (acquired
1139 @param Controller The controller handle which has the NIC Ip4 Config Protocol
1140 relative with the default address to judge.
1142 @retval TRUE If the default address is static.
1143 @retval FALSE If the default address is acquired from DHCP.
1148 NetLibDefaultAddressIsStatic (
1149 IN EFI_HANDLE Controller
1153 EFI_NIC_IP4_CONFIG_PROTOCOL
*NicIp4
;
1155 NIC_IP4_CONFIG_INFO
*ConfigInfo
;
1158 Status
= gBS
->HandleProtocol (
1160 &gEfiNicIp4ConfigProtocolGuid
,
1163 if (EFI_ERROR (Status
)) {
1168 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, NULL
);
1169 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1173 ConfigInfo
= AllocatePool (Len
);
1174 if (ConfigInfo
== NULL
) {
1179 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, ConfigInfo
);
1180 if (EFI_ERROR (Status
)) {
1184 IsStatic
= (BOOLEAN
) (ConfigInfo
->Source
== IP4_CONFIG_SOURCE_STATIC
);
1188 gBS
->FreePool (ConfigInfo
);
1194 Create an IPv4 device path node.
1196 @param Node Pointer to the IPv4 device path node.
1197 @param Controller The handle where the NIC IP4 config protocol resides.
1198 @param LocalIp The local IPv4 address.
1199 @param LocalPort The local port.
1200 @param RemoteIp The remote IPv4 address.
1201 @param RemotePort The remote port.
1202 @param Protocol The protocol type in the IP header.
1203 @param UseDefaultAddress Whether this instance is using default address or not.
1209 NetLibCreateIPv4DPathNode (
1210 IN OUT IPv4_DEVICE_PATH
*Node
,
1211 IN EFI_HANDLE Controller
,
1212 IN IP4_ADDR LocalIp
,
1213 IN UINT16 LocalPort
,
1214 IN IP4_ADDR RemoteIp
,
1215 IN UINT16 RemotePort
,
1217 IN BOOLEAN UseDefaultAddress
1220 Node
->Header
.Type
= MESSAGING_DEVICE_PATH
;
1221 Node
->Header
.SubType
= MSG_IPv4_DP
;
1222 SetDevicePathNodeLength (&Node
->Header
, 19);
1224 CopyMem (&Node
->LocalIpAddress
, &LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
1225 CopyMem (&Node
->RemoteIpAddress
, &RemoteIp
, sizeof (EFI_IPv4_ADDRESS
));
1227 Node
->LocalPort
= LocalPort
;
1228 Node
->RemotePort
= RemotePort
;
1230 Node
->Protocol
= Protocol
;
1232 if (!UseDefaultAddress
) {
1233 Node
->StaticIpAddress
= TRUE
;
1235 Node
->StaticIpAddress
= NetLibDefaultAddressIsStatic (Controller
);
1241 Find the UNDI/SNP handle from controller and protocol GUID.
1242 For example, IP will open a MNP child to transmit/receive
1243 packets, when MNP is stopped, IP should also be stopped. IP
1244 needs to find its own private data which is related the IP's
1245 service binding instance that is install on UNDI/SNP handle.
1246 Now, the controller is either a MNP or ARP child handle. But
1247 IP opens these handle BY_DRIVER, use that info, we can get the
1250 @param Controller Then protocol handle to check
1251 @param ProtocolGuid The protocol that is related with the handle.
1253 @return The UNDI/SNP handle or NULL.
1258 NetLibGetNicHandle (
1259 IN EFI_HANDLE Controller
,
1260 IN EFI_GUID
*ProtocolGuid
1263 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenBuffer
;
1269 Status
= gBS
->OpenProtocolInformation (
1276 if (EFI_ERROR (Status
)) {
1282 for (Index
= 0; Index
< OpenCount
; Index
++) {
1283 if (OpenBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1284 Handle
= OpenBuffer
[Index
].ControllerHandle
;
1289 gBS
->FreePool (OpenBuffer
);
1294 Add a Deferred Procedure Call to the end of the DPC queue.
1296 @DpcTpl The EFI_TPL that the DPC should be invoked.
1297 @DpcProcedure Pointer to the DPC's function.
1298 @DpcContext Pointer to the DPC's context. Passed to DpcProcedure
1299 when DpcProcedure is invoked.
1301 @retval EFI_SUCCESS The DPC was queued.
1302 @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL.
1303 DpcProcedure is NULL.
1304 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
1305 add the DPC to the queue.
1312 IN EFI_DPC_PROCEDURE DpcProcedure
,
1313 IN VOID
*DpcContext OPTIONAL
1316 return mDpc
->QueueDpc (mDpc
, DpcTpl
, DpcProcedure
, DpcContext
);
1320 Add a Deferred Procedure Call to the end of the DPC queue.
1322 @retval EFI_SUCCESS One or more DPCs were invoked.
1323 @retval EFI_NOT_FOUND No DPCs were invoked.
1332 return mDpc
->DispatchDpc(mDpc
);
1337 The constructor function caches the pointer to DPC protocol.
1339 The constructor function locates DPC protocol from protocol database.
1340 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
1342 @param ImageHandle The firmware allocated handle for the EFI image.
1343 @param SystemTable A pointer to the EFI System Table.
1345 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
1351 IN EFI_HANDLE ImageHandle
,
1352 IN EFI_SYSTEM_TABLE
*SystemTable
1357 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
1358 ASSERT_EFI_ERROR (Status
);
1359 ASSERT (mDpc
!= NULL
);