4 Copyright (c) 2005 - 2007, Intel Corporation.<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Protocol/ServiceBinding.h>
17 #include <Protocol/SimpleNetwork.h>
18 #include <Protocol/NicIp4Config.h>
19 #include <Protocol/ComponentName.h>
20 #include <Protocol/ComponentName2.h>
21 #include <Protocol/Dpc.h>
23 #include <Library/NetLib.h>
24 #include <Library/BaseLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/UefiBootServicesTableLib.h>
28 #include <Library/UefiRuntimeServicesTableLib.h>
29 #include <Library/MemoryAllocationLib.h>
30 #include <Library/DevicePathLib.h>
32 EFI_DPC_PROTOCOL
*mDpc
= NULL
;
34 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mNetLibHexStr
[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
37 // All the supported IP4 maskes in host byte order.
39 IP4_ADDR gIp4AllMasks
[IP4_MASK_NUM
] = {
78 EFI_IPv4_ADDRESS mZeroIp4Addr
= {{0, 0, 0, 0}};
81 Return the length of the mask. If the mask is invalid,
82 return the invalid length 33, which is IP4_MASK_NUM.
83 NetMask is in the host byte order.
85 @param[in] NetMask The netmask to get the length from.
87 @return The length of the netmask, IP4_MASK_NUM if the mask isn't.
98 for (Index
= 0; Index
< IP4_MASK_NUM
; Index
++) {
99 if (NetMask
== gIp4AllMasks
[Index
]) {
110 Return the class of the address, such as class a, b, c.
111 Addr is in host byte order.
113 @param[in] Addr The address to get the class from.
115 @return IP address class, such as IP4_ADDR_CLASSA.
126 ByteOne
= (UINT8
) (Addr
>> 24);
128 if ((ByteOne
& 0x80) == 0) {
129 return IP4_ADDR_CLASSA
;
131 } else if ((ByteOne
& 0xC0) == 0x80) {
132 return IP4_ADDR_CLASSB
;
134 } else if ((ByteOne
& 0xE0) == 0xC0) {
135 return IP4_ADDR_CLASSC
;
137 } else if ((ByteOne
& 0xF0) == 0xE0) {
138 return IP4_ADDR_CLASSD
;
141 return IP4_ADDR_CLASSE
;
148 Check whether the IP is a valid unicast address according to
149 the netmask. If NetMask is zero, use the IP address's class to
150 get the default mask.
152 @param[in] Ip The IP to check against.
153 @param[in] NetMask The mask of the IP.
155 @return TRUE if IP is a valid unicast address on the network, otherwise FALSE.
167 Class
= NetGetIpClass (Ip
);
169 if ((Ip
== 0) || (Class
>= IP4_ADDR_CLASSD
)) {
174 NetMask
= gIp4AllMasks
[Class
<< 3];
177 if (((Ip
&~NetMask
) == ~NetMask
) || ((Ip
&~NetMask
) == 0)) {
186 Initialize a random seed using current time.
188 @return The random seed initialized with current time.
200 gRT
->GetTime (&Time
, NULL
);
201 Seed
= (~Time
.Hour
<< 24 | Time
.Day
<< 16 | Time
.Minute
<< 8 | Time
.Second
);
202 Seed
^= Time
.Nanosecond
;
203 Seed
^= Time
.Year
<< 7;
210 Extract a UINT32 from a byte stream, then convert it to host
211 byte order. Use this function to avoid alignment error.
213 @param[in] Buf The buffer to extract the UINT32.
215 @return The UINT32 extracted.
226 CopyMem (&Value
, Buf
, sizeof (UINT32
));
227 return NTOHL (Value
);
232 Put a UINT32 to the byte stream. Convert it from host byte order
233 to network byte order before putting.
235 @param[in, out] Buf The buffer to put the UINT32.
236 @param[in] Data The data to put.
247 CopyMem (Buf
, &Data
, sizeof (UINT32
));
252 Remove the first entry on the list.
254 @param[in, out] Head The list header.
256 @return The entry that is removed from the list, NULL if the list is empty.
262 IN OUT LIST_ENTRY
*Head
267 ASSERT (Head
!= NULL
);
269 if (IsListEmpty (Head
)) {
273 First
= Head
->ForwardLink
;
274 Head
->ForwardLink
= First
->ForwardLink
;
275 First
->ForwardLink
->BackLink
= Head
;
278 First
->ForwardLink
= (LIST_ENTRY
*) NULL
;
279 First
->BackLink
= (LIST_ENTRY
*) NULL
;
287 Remove the last entry on the list.
289 @param[in, out] Head The list head.
291 @return The entry that is removed from the list, NULL if the list is empty.
297 IN OUT LIST_ENTRY
*Head
302 ASSERT (Head
!= NULL
);
304 if (IsListEmpty (Head
)) {
308 Last
= Head
->BackLink
;
309 Head
->BackLink
= Last
->BackLink
;
310 Last
->BackLink
->ForwardLink
= Head
;
313 Last
->ForwardLink
= (LIST_ENTRY
*) NULL
;
314 Last
->BackLink
= (LIST_ENTRY
*) NULL
;
322 Insert the NewEntry after the PrevEntry.
324 @param[in, out] PrevEntry The previous entry to insert after.
325 @param[in, out] NewEntry The new entry to insert.
331 IN OUT LIST_ENTRY
*PrevEntry
,
332 IN OUT LIST_ENTRY
*NewEntry
335 NewEntry
->BackLink
= PrevEntry
;
336 NewEntry
->ForwardLink
= PrevEntry
->ForwardLink
;
337 PrevEntry
->ForwardLink
->BackLink
= NewEntry
;
338 PrevEntry
->ForwardLink
= NewEntry
;
343 Insert the NewEntry before the PostEntry.
345 @param[in, out] PostEntry The entry to insert before.
346 @param[in, out] NewEntry The new entry to insert.
351 NetListInsertBefore (
352 IN OUT LIST_ENTRY
*PostEntry
,
353 IN OUT LIST_ENTRY
*NewEntry
356 NewEntry
->ForwardLink
= PostEntry
;
357 NewEntry
->BackLink
= PostEntry
->BackLink
;
358 PostEntry
->BackLink
->ForwardLink
= NewEntry
;
359 PostEntry
->BackLink
= NewEntry
;
364 Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
366 @param[in, out] Map The netmap to initialize.
375 ASSERT (Map
!= NULL
);
377 InitializeListHead (&Map
->Used
);
378 InitializeListHead (&Map
->Recycled
);
384 To clean up the netmap, that is, release allocated memories.
386 @param[in, out] Map The netmap to clean up.
399 ASSERT (Map
!= NULL
);
401 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Used
) {
402 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
404 RemoveEntryList (&Item
->Link
);
407 gBS
->FreePool (Item
);
410 ASSERT ((Map
->Count
== 0) && IsListEmpty (&Map
->Used
));
412 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Recycled
) {
413 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
415 RemoveEntryList (&Item
->Link
);
416 gBS
->FreePool (Item
);
419 ASSERT (IsListEmpty (&Map
->Recycled
));
424 Test whether the netmap is empty.
426 @param[in] Map The net map to test.
428 @return TRUE if the netmap is empty, otherwise FALSE.
437 ASSERT (Map
!= NULL
);
438 return (BOOLEAN
) (Map
->Count
== 0);
443 Return the number of the <Key, Value> pairs in the netmap.
445 @param[in] Map The netmap to get the entry number.
447 @return The entry number in the netmap.
461 Allocate an item for the netmap. It will try to allocate.
462 a batch of items and return one.
464 @param[in, out] Map The netmap to allocate item for.
466 @return The allocated item. If NULL, the
467 allocation failed due to resource limit.
479 ASSERT (Map
!= NULL
);
481 Head
= &Map
->Recycled
;
483 if (IsListEmpty (Head
)) {
484 for (Index
= 0; Index
< NET_MAP_INCREAMENT
; Index
++) {
485 Item
= AllocatePool (sizeof (NET_MAP_ITEM
));
495 InsertHeadList (Head
, &Item
->Link
);
499 Item
= NET_LIST_HEAD (Head
, NET_MAP_ITEM
, Link
);
500 NetListRemoveHead (Head
);
507 Allocate an item to save the <Key, Value> pair to the head of the netmap.
509 @param[in, out] Map The netmap to insert into.
510 @param[in] Key The user's key.
511 @param[in] Value The user's value for the key.
513 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item.
514 @retval EFI_SUCCESS The item is inserted to the head.
522 IN VOID
*Value OPTIONAL
527 ASSERT (Map
!= NULL
);
529 Item
= NetMapAllocItem (Map
);
532 return EFI_OUT_OF_RESOURCES
;
537 InsertHeadList (&Map
->Used
, &Item
->Link
);
545 Allocate an item to save the <Key, Value> pair to the tail of the netmap.
547 @param[in, out] Map The netmap to insert into.
548 @param[in] Key The user's key.
549 @param[in] Value The user's value for the key.
551 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item.
552 @retval EFI_SUCCESS The item is inserted to the tail.
560 IN VOID
*Value OPTIONAL
565 ASSERT (Map
!= NULL
);
567 Item
= NetMapAllocItem (Map
);
570 return EFI_OUT_OF_RESOURCES
;
575 InsertTailList (&Map
->Used
, &Item
->Link
);
584 Check whther the item is in the Map.
586 @param[in] Map The netmap to search within.
587 @param[in] Item The item to search.
589 @return TRUE if the item is in the netmap, otherwise FALSE.
595 IN NET_MAP_ITEM
*Item
598 LIST_ENTRY
*ListEntry
;
600 NET_LIST_FOR_EACH (ListEntry
, &Map
->Used
) {
601 if (ListEntry
== &Item
->Link
) {
611 Find the key in the netmap.
613 @param[in] Map The netmap to search within.
614 @param[in] Key The key to search.
616 @return The point to the item contains the Key, or NULL if Key isn't in the map.
629 ASSERT (Map
!= NULL
);
631 NET_LIST_FOR_EACH (Entry
, &Map
->Used
) {
632 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
634 if (Item
->Key
== Key
) {
644 Remove the item from the netmap.
646 @param[in, out] Map The netmap to remove the item from.
647 @param[in, out] Item The item to remove.
648 @param[out] Value The variable to receive the value if not NULL.
650 @return The key of the removed item.
657 IN OUT NET_MAP_ITEM
*Item
,
658 OUT VOID
**Value OPTIONAL
661 ASSERT ((Map
!= NULL
) && (Item
!= NULL
));
662 ASSERT (NetItemInMap (Map
, Item
));
664 RemoveEntryList (&Item
->Link
);
666 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
669 *Value
= Item
->Value
;
677 Remove the first entry on the netmap.
679 @param[in, out] Map The netmap to remove the head from.
680 @param[out] Value The variable to receive the value if not NULL.
682 @return The key of the item removed.
689 OUT VOID
**Value OPTIONAL
695 // Often, it indicates a programming error to remove
696 // the first entry in an empty list
698 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
700 Item
= NET_LIST_HEAD (&Map
->Used
, NET_MAP_ITEM
, Link
);
701 RemoveEntryList (&Item
->Link
);
703 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
706 *Value
= Item
->Value
;
714 Remove the last entry on the netmap.
716 @param[in, out] Map The netmap to remove the tail from.
717 @param[out] Value The variable to receive the value if not NULL.
719 @return The key of the item removed.
726 OUT VOID
**Value OPTIONAL
732 // Often, it indicates a programming error to remove
733 // the last entry in an empty list
735 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
737 Item
= NET_LIST_TAIL (&Map
->Used
, NET_MAP_ITEM
, Link
);
738 RemoveEntryList (&Item
->Link
);
740 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
743 *Value
= Item
->Value
;
751 Iterate through the netmap and call CallBack for each item. It will
752 contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
753 from the loop. It returns the CallBack's last return value. This
754 function is delete safe for the current item.
756 @param[in] Map The Map to iterate through.
757 @param[in] CallBack The callback function to call for each item.
758 @param[in] Arg The opaque parameter to the callback.
760 @retval EFI_SUCCESS There is no item in the netmap or CallBack for each item
762 @retval Others It returns the CallBack's last return value.
769 IN NET_MAP_CALLBACK CallBack
,
780 ASSERT ((Map
!= NULL
) && (CallBack
!= NULL
));
784 if (IsListEmpty (Head
)) {
788 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
789 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
790 Result
= CallBack (Map
, Item
, Arg
);
792 if (EFI_ERROR (Result
)) {
802 This is the default unload handle for all the network drivers.
804 @param[in] ImageHandle The drivers' driver image.
806 @retval EFI_SUCCESS The image is unloaded.
807 @retval Others Failed to unload the image.
812 NetLibDefaultUnload (
813 IN EFI_HANDLE ImageHandle
817 EFI_HANDLE
*DeviceHandleBuffer
;
818 UINTN DeviceHandleCount
;
820 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
821 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
822 EFI_COMPONENT_NAME2_PROTOCOL
*ComponentName2
;
825 // Get the list of all the handles in the handle database.
826 // If there is an error getting the list, then the unload
829 Status
= gBS
->LocateHandleBuffer (
837 if (EFI_ERROR (Status
)) {
842 // Disconnect the driver specified by ImageHandle from all
843 // the devices in the handle database.
845 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
846 Status
= gBS
->DisconnectController (
847 DeviceHandleBuffer
[Index
],
854 // Uninstall all the protocols installed in the driver entry point
856 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
857 Status
= gBS
->HandleProtocol (
858 DeviceHandleBuffer
[Index
],
859 &gEfiDriverBindingProtocolGuid
,
860 (VOID
**) &DriverBinding
863 if (EFI_ERROR (Status
)) {
867 if (DriverBinding
->ImageHandle
!= ImageHandle
) {
871 gBS
->UninstallProtocolInterface (
873 &gEfiDriverBindingProtocolGuid
,
876 Status
= gBS
->HandleProtocol (
877 DeviceHandleBuffer
[Index
],
878 &gEfiComponentNameProtocolGuid
,
879 (VOID
**) &ComponentName
881 if (!EFI_ERROR (Status
)) {
882 gBS
->UninstallProtocolInterface (
884 &gEfiComponentNameProtocolGuid
,
889 Status
= gBS
->HandleProtocol (
890 DeviceHandleBuffer
[Index
],
891 &gEfiComponentName2ProtocolGuid
,
892 (VOID
**) &ComponentName2
894 if (!EFI_ERROR (Status
)) {
895 gBS
->UninstallProtocolInterface (
897 &gEfiComponentName2ProtocolGuid
,
904 // Free the buffer containing the list of handles from the handle database
906 if (DeviceHandleBuffer
!= NULL
) {
907 gBS
->FreePool (DeviceHandleBuffer
);
916 Create a child of the service that is identified by ServiceBindingGuid.
918 @param[in] Controller The controller which has the service installed.
919 @param[in] Image The image handle used to open service.
920 @param[in] ServiceBindingGuid The service's Guid.
921 @param[in, out] ChildHandle The handle to receive the create child
923 @retval EFI_SUCCESS The child is successfully created.
924 @retval Others Failed to create the child.
929 NetLibCreateServiceChild (
930 IN EFI_HANDLE Controller
,
932 IN EFI_GUID
*ServiceBindingGuid
,
933 IN OUT EFI_HANDLE
*ChildHandle
937 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
940 ASSERT ((ServiceBindingGuid
!= NULL
) && (ChildHandle
!= NULL
));
943 // Get the ServiceBinding Protocol
945 Status
= gBS
->OpenProtocol (
951 EFI_OPEN_PROTOCOL_GET_PROTOCOL
954 if (EFI_ERROR (Status
)) {
961 Status
= Service
->CreateChild (Service
, ChildHandle
);
967 Destory a child of the service that is identified by ServiceBindingGuid.
969 @param[in] Controller The controller which has the service installed.
970 @param[in] Image The image handle used to open service.
971 @param[in] ServiceBindingGuid The service's Guid.
972 @param[in] ChildHandle The child to destory
974 @retval EFI_SUCCESS The child is successfully destoried.
975 @retval Others Failed to destory the child.
980 NetLibDestroyServiceChild (
981 IN EFI_HANDLE Controller
,
983 IN EFI_GUID
*ServiceBindingGuid
,
984 IN EFI_HANDLE ChildHandle
988 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
990 ASSERT (ServiceBindingGuid
!= NULL
);
993 // Get the ServiceBinding Protocol
995 Status
= gBS
->OpenProtocol (
1001 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1004 if (EFI_ERROR (Status
)) {
1009 // destory the child
1011 Status
= Service
->DestroyChild (Service
, ChildHandle
);
1017 Convert the mac address of the simple network protocol installed on
1018 SnpHandle to a unicode string. Callers are responsible for freeing the
1021 @param[in] SnpHandle The handle where the simple network protocol is
1023 @param[in] ImageHandle The image handle used to act as the agent handle to
1024 get the simple network protocol.
1025 @param[out] MacString The pointer to store the address of the string
1026 representation of the mac address.
1028 @retval EFI_SUCCESS Convert the mac address a unicode string successfully.
1029 @retval EFI_OUT_OF_RESOURCES There are not enough memory resource.
1030 @retval Others Failed to open the simple network protocol.
1035 NetLibGetMacString (
1036 IN EFI_HANDLE SnpHandle
,
1037 IN EFI_HANDLE ImageHandle
,
1038 OUT CHAR16
**MacString
1042 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1043 EFI_SIMPLE_NETWORK_MODE
*Mode
;
1050 // Get the Simple Network protocol from the SnpHandle.
1052 Status
= gBS
->OpenProtocol (
1054 &gEfiSimpleNetworkProtocolGuid
,
1058 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1060 if (EFI_ERROR (Status
)) {
1067 // It takes 2 unicode characters to represent a 1 byte binary buffer.
1068 // Plus one unicode character for the null-terminator.
1070 MacAddress
= AllocatePool ((2 * Mode
->HwAddressSize
+ 1) * sizeof (CHAR16
));
1071 if (MacAddress
== NULL
) {
1072 return EFI_OUT_OF_RESOURCES
;
1076 // Convert the mac address into a unicode string.
1078 for (Index
= 0; Index
< Mode
->HwAddressSize
; Index
++) {
1079 MacAddress
[Index
* 2] = (CHAR16
) mNetLibHexStr
[(Mode
->CurrentAddress
.Addr
[Index
] >> 4) & 0x0F];
1080 MacAddress
[Index
* 2 + 1] = (CHAR16
) mNetLibHexStr
[Mode
->CurrentAddress
.Addr
[Index
] & 0x0F];
1083 MacAddress
[Mode
->HwAddressSize
* 2] = L
'\0';
1085 *MacString
= MacAddress
;
1091 Check the default address used by the IPv4 driver is static or dynamic (acquired
1094 @param[in] Controller The controller handle which has the NIC Ip4 Config Protocol
1095 relative with the default address to judge.
1097 @retval TRUE If the default address is static.
1098 @retval FALSE If the default address is acquired from DHCP.
1102 NetLibDefaultAddressIsStatic (
1103 IN EFI_HANDLE Controller
1107 EFI_NIC_IP4_CONFIG_PROTOCOL
*NicIp4
;
1109 NIC_IP4_CONFIG_INFO
*ConfigInfo
;
1112 Status
= gBS
->HandleProtocol (
1114 &gEfiNicIp4ConfigProtocolGuid
,
1117 if (EFI_ERROR (Status
)) {
1122 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, NULL
);
1123 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1127 ConfigInfo
= AllocatePool (Len
);
1128 if (ConfigInfo
== NULL
) {
1133 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, ConfigInfo
);
1134 if (EFI_ERROR (Status
)) {
1138 IsStatic
= (BOOLEAN
) (ConfigInfo
->Source
== IP4_CONFIG_SOURCE_STATIC
);
1142 gBS
->FreePool (ConfigInfo
);
1148 Create an IPv4 device path node.
1150 @param[in, out] Node Pointer to the IPv4 device path node.
1151 @param[in] Controller The handle where the NIC IP4 config protocol resides.
1152 @param[in] LocalIp The local IPv4 address.
1153 @param[in] LocalPort The local port.
1154 @param[in] RemoteIp The remote IPv4 address.
1155 @param[in] RemotePort The remote port.
1156 @param[in] Protocol The protocol type in the IP header.
1157 @param[in] UseDefaultAddress Whether this instance is using default address or not.
1162 NetLibCreateIPv4DPathNode (
1163 IN OUT IPv4_DEVICE_PATH
*Node
,
1164 IN EFI_HANDLE Controller
,
1165 IN IP4_ADDR LocalIp
,
1166 IN UINT16 LocalPort
,
1167 IN IP4_ADDR RemoteIp
,
1168 IN UINT16 RemotePort
,
1170 IN BOOLEAN UseDefaultAddress
1173 Node
->Header
.Type
= MESSAGING_DEVICE_PATH
;
1174 Node
->Header
.SubType
= MSG_IPv4_DP
;
1175 SetDevicePathNodeLength (&Node
->Header
, 19);
1177 CopyMem (&Node
->LocalIpAddress
, &LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
1178 CopyMem (&Node
->RemoteIpAddress
, &RemoteIp
, sizeof (EFI_IPv4_ADDRESS
));
1180 Node
->LocalPort
= LocalPort
;
1181 Node
->RemotePort
= RemotePort
;
1183 Node
->Protocol
= Protocol
;
1185 if (!UseDefaultAddress
) {
1186 Node
->StaticIpAddress
= TRUE
;
1188 Node
->StaticIpAddress
= NetLibDefaultAddressIsStatic (Controller
);
1194 Find the UNDI/SNP handle from controller and protocol GUID.
1195 For example, IP will open a MNP child to transmit/receive
1196 packets, when MNP is stopped, IP should also be stopped. IP
1197 needs to find its own private data which is related the IP's
1198 service binding instance that is install on UNDI/SNP handle.
1199 Now, the controller is either a MNP or ARP child handle. But
1200 IP opens these handle BY_DRIVER, use that info, we can get the
1203 @param[in] Controller Then protocol handle to check.
1204 @param[in] ProtocolGuid The protocol that is related with the handle.
1206 @return The UNDI/SNP handle or NULL for errors.
1211 NetLibGetNicHandle (
1212 IN EFI_HANDLE Controller
,
1213 IN EFI_GUID
*ProtocolGuid
1216 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenBuffer
;
1222 Status
= gBS
->OpenProtocolInformation (
1229 if (EFI_ERROR (Status
)) {
1235 for (Index
= 0; Index
< OpenCount
; Index
++) {
1236 if (OpenBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1237 Handle
= OpenBuffer
[Index
].ControllerHandle
;
1242 gBS
->FreePool (OpenBuffer
);
1247 Add a Deferred Procedure Call to the end of the DPC queue.
1249 @param[in] DpcTpl The EFI_TPL that the DPC should be invoked.
1250 @param[in] DpcProcedure Pointer to the DPC's function.
1251 @param[in] DpcContext Pointer to the DPC's context. Passed to DpcProcedure
1252 when DpcProcedure is invoked.
1254 @retval EFI_SUCCESS The DPC was queued.
1255 @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL, or DpcProcedure
1257 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
1258 add the DPC to the queue.
1265 IN EFI_DPC_PROCEDURE DpcProcedure
,
1266 IN VOID
*DpcContext OPTIONAL
1269 return mDpc
->QueueDpc (mDpc
, DpcTpl
, DpcProcedure
, DpcContext
);
1273 Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl
1274 value greater than or equal to the current TPL are invoked in the order that
1275 they were queued. DPCs with higher DpcTpl values are invoked before DPCs with
1276 lower DpcTpl values.
1278 @retval EFI_SUCCESS One or more DPCs were invoked.
1279 @retval EFI_NOT_FOUND No DPCs were invoked.
1288 return mDpc
->DispatchDpc(mDpc
);
1292 The constructor function caches the pointer to DPC protocol.
1294 The constructor function locates DPC protocol from protocol database.
1295 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
1297 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1298 @param[in] SystemTable A pointer to the EFI System Table.
1300 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
1306 IN EFI_HANDLE ImageHandle
,
1307 IN EFI_SYSTEM_TABLE
*SystemTable
1312 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
1313 ASSERT_EFI_ERROR (Status
);
1314 ASSERT (mDpc
!= NULL
);