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 gIp4AllMasks
[IP4_MASK_NUM
] = {
85 EFI_IPv4_ADDRESS mZeroIp4Addr
= {{0, 0, 0, 0}};
88 Return the length of the mask. If the mask is invalid,
89 return the invalid length 33, which is IP4_MASK_NUM.
90 NetMask is in the host byte order.
92 @param NetMask The netmask to get the length from
94 @return The length of the netmask, IP4_MASK_NUM if the mask isn't
106 for (Index
= 0; Index
< IP4_MASK_NUM
; Index
++) {
107 if (NetMask
== gIp4AllMasks
[Index
]) {
118 Return the class of the address, such as class a, b, c.
119 Addr is in host byte order.
121 @param Addr The address to get the class from
123 @return IP address class, such as IP4_ADDR_CLASSA
134 ByteOne
= (UINT8
) (Addr
>> 24);
136 if ((ByteOne
& 0x80) == 0) {
137 return IP4_ADDR_CLASSA
;
139 } else if ((ByteOne
& 0xC0) == 0x80) {
140 return IP4_ADDR_CLASSB
;
142 } else if ((ByteOne
& 0xE0) == 0xC0) {
143 return IP4_ADDR_CLASSC
;
145 } else if ((ByteOne
& 0xF0) == 0xE0) {
146 return IP4_ADDR_CLASSD
;
149 return IP4_ADDR_CLASSE
;
156 Check whether the IP is a valid unicast address according to
157 the netmask. If NetMask is zero, use the IP address's class to
158 get the default mask.
160 @param Ip The IP to check againist
161 @param NetMask The mask of the IP
163 @return TRUE if IP is a valid unicast address on the network, otherwise FALSE
175 Class
= NetGetIpClass (Ip
);
177 if ((Ip
== 0) || (Class
>= IP4_ADDR_CLASSD
)) {
182 NetMask
= gIp4AllMasks
[Class
<< 3];
185 if (((Ip
&~NetMask
) == ~NetMask
) || ((Ip
&~NetMask
) == 0)) {
194 Initialize a random seed using current time.
198 @return The random seed initialized with current time.
210 gRT
->GetTime (&Time
, NULL
);
211 Seed
= (~Time
.Hour
<< 24 | Time
.Day
<< 16 | Time
.Minute
<< 8 | Time
.Second
);
212 Seed
^= Time
.Nanosecond
;
213 Seed
^= Time
.Year
<< 7;
220 Extract a UINT32 from a byte stream, then convert it to host
221 byte order. Use this function to avoid alignment error.
223 @param Buf The buffer to extract the UINT32.
225 @return The UINT32 extracted.
236 CopyMem (&Value
, Buf
, sizeof (UINT32
));
237 return NTOHL (Value
);
242 Put a UINT32 to the byte stream. Convert it from host byte order
243 to network byte order before putting.
245 @param Buf The buffer to put the UINT32
246 @param Data The data to put
259 CopyMem (Buf
, &Data
, sizeof (UINT32
));
264 Remove the first entry on the list
266 @param Head The list header
268 @return The entry that is removed from the list, NULL if the list is empty.
279 ASSERT (Head
!= NULL
);
281 if (IsListEmpty (Head
)) {
285 First
= Head
->ForwardLink
;
286 Head
->ForwardLink
= First
->ForwardLink
;
287 First
->ForwardLink
->BackLink
= Head
;
290 First
->ForwardLink
= (LIST_ENTRY
*) NULL
;
291 First
->BackLink
= (LIST_ENTRY
*) NULL
;
299 Remove the last entry on the list
301 @param Head The list head
303 @return The entry that is removed from the list, NULL if the list is empty.
314 ASSERT (Head
!= NULL
);
316 if (IsListEmpty (Head
)) {
320 Last
= Head
->BackLink
;
321 Head
->BackLink
= Last
->BackLink
;
322 Last
->BackLink
->ForwardLink
= Head
;
325 Last
->ForwardLink
= (LIST_ENTRY
*) NULL
;
326 Last
->BackLink
= (LIST_ENTRY
*) NULL
;
334 Insert the NewEntry after the PrevEntry
336 @param PrevEntry The previous entry to insert after
337 @param NewEntry The new entry to insert
345 IN LIST_ENTRY
*PrevEntry
,
346 IN LIST_ENTRY
*NewEntry
349 NewEntry
->BackLink
= PrevEntry
;
350 NewEntry
->ForwardLink
= PrevEntry
->ForwardLink
;
351 PrevEntry
->ForwardLink
->BackLink
= NewEntry
;
352 PrevEntry
->ForwardLink
= NewEntry
;
357 Insert the NewEntry before the PostEntry
359 @param PostEntry The entry to insert before
360 @param NewEntry The new entry to insert
367 NetListInsertBefore (
368 IN LIST_ENTRY
*PostEntry
,
369 IN LIST_ENTRY
*NewEntry
372 NewEntry
->ForwardLink
= PostEntry
;
373 NewEntry
->BackLink
= PostEntry
->BackLink
;
374 PostEntry
->BackLink
->ForwardLink
= NewEntry
;
375 PostEntry
->BackLink
= NewEntry
;
380 Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
382 @param Map The netmap to initialize
393 ASSERT (Map
!= NULL
);
395 InitializeListHead (&Map
->Used
);
396 InitializeListHead (&Map
->Recycled
);
402 To clean up the netmap, that is, release allocated memories.
404 @param Map The netmap to clean up.
419 ASSERT (Map
!= NULL
);
421 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Used
) {
422 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
424 RemoveEntryList (&Item
->Link
);
427 gBS
->FreePool (Item
);
430 ASSERT ((Map
->Count
== 0) && IsListEmpty (&Map
->Used
));
432 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Recycled
) {
433 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
435 RemoveEntryList (&Item
->Link
);
436 gBS
->FreePool (Item
);
439 ASSERT (IsListEmpty (&Map
->Recycled
));
444 Test whether the netmap is empty
446 @param Map The net map to test
448 @return TRUE if the netmap is empty, otherwise FALSE.
457 ASSERT (Map
!= NULL
);
458 return (BOOLEAN
) (Map
->Count
== 0);
463 Return the number of the <Key, Value> pairs in the netmap.
465 @param Map The netmap to get the entry number
467 @return The entry number in the netmap.
481 Allocate an item for the netmap. It will try to allocate
482 a batch of items and return one.
484 @param Map The netmap to allocate item for
486 @return The allocated item or NULL
498 ASSERT (Map
!= NULL
);
500 Head
= &Map
->Recycled
;
502 if (IsListEmpty (Head
)) {
503 for (Index
= 0; Index
< NET_MAP_INCREAMENT
; Index
++) {
504 Item
= AllocatePool (sizeof (NET_MAP_ITEM
));
514 InsertHeadList (Head
, &Item
->Link
);
518 Item
= NET_LIST_HEAD (Head
, NET_MAP_ITEM
, Link
);
519 NetListRemoveHead (Head
);
526 Allocate an item to save the <Key, Value> pair to the head of the netmap.
528 @param Map The netmap to insert into
529 @param Key The user's key
530 @param Value The user's value for the key
532 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
533 @retval EFI_SUCCESS The item is inserted to the head
541 IN VOID
*Value OPTIONAL
546 ASSERT (Map
!= NULL
);
548 Item
= NetMapAllocItem (Map
);
551 return EFI_OUT_OF_RESOURCES
;
556 InsertHeadList (&Map
->Used
, &Item
->Link
);
564 Allocate an item to save the <Key, Value> pair to the tail of the netmap.
566 @param Map The netmap to insert into
567 @param Key The user's key
568 @param Value The user's value for the key
570 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
571 @retval EFI_SUCCESS The item is inserted to the tail
579 IN VOID
*Value OPTIONAL
584 ASSERT (Map
!= NULL
);
586 Item
= NetMapAllocItem (Map
);
589 return EFI_OUT_OF_RESOURCES
;
594 InsertTailList (&Map
->Used
, &Item
->Link
);
603 Check whther the item is in the Map
605 @param Map The netmap to search within
606 @param Item The item to search
608 @return TRUE if the item is in the netmap, otherwise FALSE.
614 IN NET_MAP_ITEM
*Item
617 LIST_ENTRY
*ListEntry
;
619 NET_LIST_FOR_EACH (ListEntry
, &Map
->Used
) {
620 if (ListEntry
== &Item
->Link
) {
630 Find the key in the netmap
632 @param Map The netmap to search within
633 @param Key The key to search
635 @return The point to the item contains the Key, or NULL if Key isn't in the map.
648 ASSERT (Map
!= NULL
);
650 NET_LIST_FOR_EACH (Entry
, &Map
->Used
) {
651 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
653 if (Item
->Key
== Key
) {
663 Remove the item from the netmap
665 @param Map The netmap to remove the item from
666 @param Item The item to remove
667 @param Value The variable to receive the value if not NULL
669 @return The key of the removed item.
676 IN NET_MAP_ITEM
*Item
,
677 OUT VOID
**Value OPTIONAL
680 ASSERT ((Map
!= NULL
) && (Item
!= NULL
));
681 ASSERT (NetItemInMap (Map
, Item
));
683 RemoveEntryList (&Item
->Link
);
685 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
688 *Value
= Item
->Value
;
696 Remove the first entry on the netmap
698 @param Map The netmap to remove the head from
699 @param Value The variable to receive the value if not NULL
701 @return The key of the item removed
708 OUT VOID
**Value OPTIONAL
714 // Often, it indicates a programming error to remove
715 // the first entry in an empty list
717 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
719 Item
= NET_LIST_HEAD (&Map
->Used
, NET_MAP_ITEM
, Link
);
720 RemoveEntryList (&Item
->Link
);
722 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
725 *Value
= Item
->Value
;
733 Remove the last entry on the netmap
735 @param Map The netmap to remove the tail from
736 @param Value The variable to receive the value if not NULL
738 @return The key of the item removed
745 OUT VOID
**Value OPTIONAL
751 // Often, it indicates a programming error to remove
752 // the last entry in an empty list
754 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
756 Item
= NET_LIST_TAIL (&Map
->Used
, NET_MAP_ITEM
, Link
);
757 RemoveEntryList (&Item
->Link
);
759 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
762 *Value
= Item
->Value
;
770 Iterate through the netmap and call CallBack for each item. It will
771 contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
772 from the loop. It returns the CallBack's last return value. This
773 function is delete safe for the current item.
775 @param Map The Map to iterate through
776 @param CallBack The callback function to call for each item.
777 @param Arg The opaque parameter to the callback
779 @return It returns the CallBack's last return value.
786 IN NET_MAP_CALLBACK CallBack
,
797 ASSERT ((Map
!= NULL
) && (CallBack
!= NULL
));
801 if (IsListEmpty (Head
)) {
805 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
806 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
807 Result
= CallBack (Map
, Item
, Arg
);
809 if (EFI_ERROR (Result
)) {
819 This is the default unload handle for all the network drivers.
821 @param ImageHandle The drivers' driver image.
823 @retval EFI_SUCCESS The image is unloaded.
824 @retval Others Failed to unload the image.
829 NetLibDefaultUnload (
830 IN EFI_HANDLE ImageHandle
834 EFI_HANDLE
*DeviceHandleBuffer
;
835 UINTN DeviceHandleCount
;
837 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
838 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
839 EFI_COMPONENT_NAME2_PROTOCOL
*ComponentName2
;
842 // Get the list of all the handles in the handle database.
843 // If there is an error getting the list, then the unload
846 Status
= gBS
->LocateHandleBuffer (
854 if (EFI_ERROR (Status
)) {
859 // Disconnect the driver specified by ImageHandle from all
860 // the devices in the handle database.
862 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
863 Status
= gBS
->DisconnectController (
864 DeviceHandleBuffer
[Index
],
871 // Uninstall all the protocols installed in the driver entry point
873 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
874 Status
= gBS
->HandleProtocol (
875 DeviceHandleBuffer
[Index
],
876 &gEfiDriverBindingProtocolGuid
,
877 (VOID
**) &DriverBinding
880 if (EFI_ERROR (Status
)) {
884 if (DriverBinding
->ImageHandle
!= ImageHandle
) {
888 gBS
->UninstallProtocolInterface (
890 &gEfiDriverBindingProtocolGuid
,
893 Status
= gBS
->HandleProtocol (
894 DeviceHandleBuffer
[Index
],
895 &gEfiComponentNameProtocolGuid
,
896 (VOID
**) &ComponentName
898 if (!EFI_ERROR (Status
)) {
899 gBS
->UninstallProtocolInterface (
901 &gEfiComponentNameProtocolGuid
,
906 Status
= gBS
->HandleProtocol (
907 DeviceHandleBuffer
[Index
],
908 &gEfiComponentName2ProtocolGuid
,
909 (VOID
**) &ComponentName2
911 if (!EFI_ERROR (Status
)) {
912 gBS
->UninstallProtocolInterface (
914 &gEfiComponentName2ProtocolGuid
,
921 // Free the buffer containing the list of handles from the handle database
923 if (DeviceHandleBuffer
!= NULL
) {
924 gBS
->FreePool (DeviceHandleBuffer
);
933 Create a child of the service that is identified by ServiceBindingGuid.
935 @param Controller The controller which has the service installed.
936 @param Image The image handle used to open service.
937 @param ServiceBindingGuid The service's Guid.
938 @param ChildHandle The handle to receive the create child
940 @retval EFI_SUCCESS The child is successfully created.
941 @retval Others Failed to create the child.
946 NetLibCreateServiceChild (
947 IN EFI_HANDLE Controller
,
949 IN EFI_GUID
*ServiceBindingGuid
,
950 OUT EFI_HANDLE
*ChildHandle
954 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
957 ASSERT ((ServiceBindingGuid
!= NULL
) && (ChildHandle
!= NULL
));
960 // Get the ServiceBinding Protocol
962 Status
= gBS
->OpenProtocol (
968 EFI_OPEN_PROTOCOL_GET_PROTOCOL
971 if (EFI_ERROR (Status
)) {
978 Status
= Service
->CreateChild (Service
, ChildHandle
);
984 Destory a child of the service that is identified by ServiceBindingGuid.
986 @param Controller The controller which has the service installed.
987 @param Image The image handle used to open service.
988 @param ServiceBindingGuid The service's Guid.
989 @param ChildHandle The child to destory
991 @retval EFI_SUCCESS The child is successfully destoried.
992 @retval Others Failed to destory the child.
997 NetLibDestroyServiceChild (
998 IN EFI_HANDLE Controller
,
1000 IN EFI_GUID
*ServiceBindingGuid
,
1001 IN EFI_HANDLE ChildHandle
1005 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1007 ASSERT (ServiceBindingGuid
!= NULL
);
1010 // Get the ServiceBinding Protocol
1012 Status
= gBS
->OpenProtocol (
1018 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1021 if (EFI_ERROR (Status
)) {
1026 // destory the child
1028 Status
= Service
->DestroyChild (Service
, ChildHandle
);
1034 Convert the mac address of the simple network protocol installed on
1035 SnpHandle to a unicode string. Callers are responsible for freeing the
1038 @param SnpHandle The handle where the simple network protocol is
1040 @param ImageHandle The image handle used to act as the agent handle to
1041 get the simple network protocol.
1042 @param MacString The pointer to store the address of the string
1043 representation of the mac address.
1045 @retval EFI_OUT_OF_RESOURCES There are not enough memory resource.
1046 @retval other Failed to open the simple network protocol.
1051 NetLibGetMacString (
1052 IN EFI_HANDLE SnpHandle
,
1053 IN EFI_HANDLE ImageHandle
,
1054 IN OUT CHAR16
**MacString
1058 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1059 EFI_SIMPLE_NETWORK_MODE
*Mode
;
1066 // Get the Simple Network protocol from the SnpHandle.
1068 Status
= gBS
->OpenProtocol (
1070 &gEfiSimpleNetworkProtocolGuid
,
1074 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1076 if (EFI_ERROR (Status
)) {
1083 // It takes 2 unicode characters to represent a 1 byte binary buffer.
1084 // Plus one unicode character for the null-terminator.
1086 MacAddress
= AllocatePool ((2 * Mode
->HwAddressSize
+ 1) * sizeof (CHAR16
));
1087 if (MacAddress
== NULL
) {
1088 return EFI_OUT_OF_RESOURCES
;
1092 // Convert the mac address into a unicode string.
1094 for (Index
= 0; Index
< Mode
->HwAddressSize
; Index
++) {
1095 MacAddress
[Index
* 2] = NibbleToHexChar ((UINT8
) (Mode
->CurrentAddress
.Addr
[Index
] >> 4));
1096 MacAddress
[Index
* 2 + 1] = NibbleToHexChar (Mode
->CurrentAddress
.Addr
[Index
]);
1099 MacAddress
[Mode
->HwAddressSize
* 2] = L
'\0';
1101 *MacString
= MacAddress
;
1107 Check the default address used by the IPv4 driver is static or dynamic (acquired
1110 @param Controller The controller handle which has the NIC Ip4 Config Protocol
1111 relative with the default address to judge.
1113 @retval TRUE If the default address is static.
1114 @retval FALSE If the default address is acquired from DHCP.
1118 NetLibDefaultAddressIsStatic (
1119 IN EFI_HANDLE Controller
1123 EFI_NIC_IP4_CONFIG_PROTOCOL
*NicIp4
;
1125 NIC_IP4_CONFIG_INFO
*ConfigInfo
;
1128 Status
= gBS
->HandleProtocol (
1130 &gEfiNicIp4ConfigProtocolGuid
,
1133 if (EFI_ERROR (Status
)) {
1138 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, NULL
);
1139 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1143 ConfigInfo
= AllocatePool (Len
);
1144 if (ConfigInfo
== NULL
) {
1149 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, ConfigInfo
);
1150 if (EFI_ERROR (Status
)) {
1154 IsStatic
= (BOOLEAN
) (ConfigInfo
->Source
== IP4_CONFIG_SOURCE_STATIC
);
1158 gBS
->FreePool (ConfigInfo
);
1164 Create an IPv4 device path node.
1166 @param Node Pointer to the IPv4 device path node.
1167 @param Controller The handle where the NIC IP4 config protocol resides.
1168 @param LocalIp The local IPv4 address.
1169 @param LocalPort The local port.
1170 @param RemoteIp The remote IPv4 address.
1171 @param RemotePort The remote port.
1172 @param Protocol The protocol type in the IP header.
1173 @param UseDefaultAddress Whether this instance is using default address or not.
1179 NetLibCreateIPv4DPathNode (
1180 IN OUT IPv4_DEVICE_PATH
*Node
,
1181 IN EFI_HANDLE Controller
,
1182 IN IP4_ADDR LocalIp
,
1183 IN UINT16 LocalPort
,
1184 IN IP4_ADDR RemoteIp
,
1185 IN UINT16 RemotePort
,
1187 IN BOOLEAN UseDefaultAddress
1190 Node
->Header
.Type
= MESSAGING_DEVICE_PATH
;
1191 Node
->Header
.SubType
= MSG_IPv4_DP
;
1192 SetDevicePathNodeLength (&Node
->Header
, 19);
1194 CopyMem (&Node
->LocalIpAddress
, &LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
1195 CopyMem (&Node
->RemoteIpAddress
, &RemoteIp
, sizeof (EFI_IPv4_ADDRESS
));
1197 Node
->LocalPort
= LocalPort
;
1198 Node
->RemotePort
= RemotePort
;
1200 Node
->Protocol
= Protocol
;
1202 if (!UseDefaultAddress
) {
1203 Node
->StaticIpAddress
= TRUE
;
1205 Node
->StaticIpAddress
= NetLibDefaultAddressIsStatic (Controller
);
1211 Find the UNDI/SNP handle from controller and protocol GUID.
1212 For example, IP will open a MNP child to transmit/receive
1213 packets, when MNP is stopped, IP should also be stopped. IP
1214 needs to find its own private data which is related the IP's
1215 service binding instance that is install on UNDI/SNP handle.
1216 Now, the controller is either a MNP or ARP child handle. But
1217 IP opens these handle BY_DRIVER, use that info, we can get the
1220 @param Controller Then protocol handle to check
1221 @param ProtocolGuid The protocol that is related with the handle.
1223 @return The UNDI/SNP handle or NULL.
1228 NetLibGetNicHandle (
1229 IN EFI_HANDLE Controller
,
1230 IN EFI_GUID
*ProtocolGuid
1233 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenBuffer
;
1239 Status
= gBS
->OpenProtocolInformation (
1246 if (EFI_ERROR (Status
)) {
1252 for (Index
= 0; Index
< OpenCount
; Index
++) {
1253 if (OpenBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1254 Handle
= OpenBuffer
[Index
].ControllerHandle
;
1259 gBS
->FreePool (OpenBuffer
);
1264 Add a Deferred Procedure Call to the end of the DPC queue.
1266 @DpcTpl The EFI_TPL that the DPC should be invoked.
1267 @DpcProcedure Pointer to the DPC's function.
1268 @DpcContext Pointer to the DPC's context. Passed to DpcProcedure
1269 when DpcProcedure is invoked.
1271 @retval EFI_SUCCESS The DPC was queued.
1272 @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL.
1273 DpcProcedure is NULL.
1274 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
1275 add the DPC to the queue.
1282 IN EFI_DPC_PROCEDURE DpcProcedure
,
1283 IN VOID
*DpcContext OPTIONAL
1286 return mDpc
->QueueDpc (mDpc
, DpcTpl
, DpcProcedure
, DpcContext
);
1290 Add a Deferred Procedure Call to the end of the DPC queue.
1292 @retval EFI_SUCCESS One or more DPCs were invoked.
1293 @retval EFI_NOT_FOUND No DPCs were invoked.
1302 return mDpc
->DispatchDpc(mDpc
);
1307 The constructor function caches the pointer to DPC protocol.
1309 The constructor function locates DPC protocol from protocol database.
1310 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
1312 @param ImageHandle The firmware allocated handle for the EFI image.
1313 @param SystemTable A pointer to the EFI System Table.
1315 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
1321 IN EFI_HANDLE ImageHandle
,
1322 IN EFI_SYSTEM_TABLE
*SystemTable
1327 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
1328 ASSERT_EFI_ERROR (Status
);
1329 ASSERT (mDpc
!= NULL
);