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>
29 #include <Library/NetLib.h>
30 #include <Library/BaseLib.h>
31 #include <Library/DebugLib.h>
32 #include <Library/BaseMemoryLib.h>
33 #include <Library/UefiBootServicesTableLib.h>
34 #include <Library/UefiRuntimeServicesTableLib.h>
35 #include <Library/UefiLib.h>
36 #include <Library/MemoryAllocationLib.h>
39 EFI_DPC_PROTOCOL
*mDpc
= NULL
;
42 // All the supported IP4 maskes in host byte order.
44 IP4_ADDR mIp4AllMasks
[IP4_MASK_NUM
] = {
83 EFI_IPv4_ADDRESS mZeroIp4Addr
= {{0, 0, 0, 0}};
86 Converts the low nibble of a byte to hex unicode character.
88 @param Nibble lower nibble of a byte.
90 @return Hex unicode character.
100 // This library interface is simply obsolete.
101 // Include the source code to user code.
106 return (CHAR16
)(Nibble
+ L
'0');
109 return (CHAR16
)(Nibble
- 0xA + L
'A');
113 Return the length of the mask. If the mask is invalid,
114 return the invalid length 33, which is IP4_MASK_NUM.
115 NetMask is in the host byte order.
117 @param NetMask The netmask to get the length from
119 @return The length of the netmask, IP4_MASK_NUM if the mask isn't
130 for (Index
= 0; Index
< IP4_MASK_NUM
; Index
++) {
131 if (NetMask
== mIp4AllMasks
[Index
]) {
142 Return the class of the address, such as class a, b, c.
143 Addr is in host byte order.
145 @param Addr The address to get the class from
147 @return IP address class, such as IP4_ADDR_CLASSA
157 ByteOne
= (UINT8
) (Addr
>> 24);
159 if ((ByteOne
& 0x80) == 0) {
160 return IP4_ADDR_CLASSA
;
162 } else if ((ByteOne
& 0xC0) == 0x80) {
163 return IP4_ADDR_CLASSB
;
165 } else if ((ByteOne
& 0xE0) == 0xC0) {
166 return IP4_ADDR_CLASSC
;
168 } else if ((ByteOne
& 0xF0) == 0xE0) {
169 return IP4_ADDR_CLASSD
;
172 return IP4_ADDR_CLASSE
;
179 Check whether the IP is a valid unicast address according to
180 the netmask. If NetMask is zero, use the IP address's class to
181 get the default mask.
183 @param Ip The IP to check againist
184 @param NetMask The mask of the IP
186 @return TRUE if IP is a valid unicast address on the network, otherwise FALSE
197 Class
= NetGetIpClass (Ip
);
199 if ((Ip
== 0) || (Class
>= IP4_ADDR_CLASSD
)) {
204 NetMask
= mIp4AllMasks
[Class
<< 3];
207 if (((Ip
&~NetMask
) == ~NetMask
) || ((Ip
&~NetMask
) == 0)) {
216 Initialize a random seed using current time.
220 @return The random seed initialized with current time.
231 gRT
->GetTime (&Time
, NULL
);
232 Seed
= (~Time
.Hour
<< 24 | Time
.Day
<< 16 | Time
.Minute
<< 8 | Time
.Second
);
233 Seed
^= Time
.Nanosecond
;
234 Seed
^= Time
.Year
<< 7;
241 Extract a UINT32 from a byte stream, then convert it to host
242 byte order. Use this function to avoid alignment error.
244 @param Buf The buffer to extract the UINT32.
246 @return The UINT32 extracted.
256 NetCopyMem (&Value
, Buf
, sizeof (UINT32
));
257 return NTOHL (Value
);
262 Put a UINT32 to the byte stream. Convert it from host byte order
263 to network byte order before putting.
265 @param Buf The buffer to put the UINT32
266 @param Data The data to put
278 NetCopyMem (Buf
, &Data
, sizeof (UINT32
));
283 Remove the first entry on the list
285 @param Head The list header
287 @return The entry that is removed from the list, NULL if the list is empty.
295 NET_LIST_ENTRY
*First
;
297 ASSERT (Head
!= NULL
);
299 if (NetListIsEmpty (Head
)) {
303 First
= Head
->ForwardLink
;
304 Head
->ForwardLink
= First
->ForwardLink
;
305 First
->ForwardLink
->BackLink
= Head
;
308 First
->ForwardLink
= (LIST_ENTRY
*) NULL
;
309 First
->BackLink
= (LIST_ENTRY
*) NULL
;
317 Remove the last entry on the list
319 @param Head The list head
321 @return The entry that is removed from the list, NULL if the list is empty.
329 NET_LIST_ENTRY
*Last
;
331 ASSERT (Head
!= NULL
);
333 if (NetListIsEmpty (Head
)) {
337 Last
= Head
->BackLink
;
338 Head
->BackLink
= Last
->BackLink
;
339 Last
->BackLink
->ForwardLink
= Head
;
342 Last
->ForwardLink
= (LIST_ENTRY
*) NULL
;
343 Last
->BackLink
= (LIST_ENTRY
*) NULL
;
351 Insert the NewEntry after the PrevEntry
353 @param PrevEntry The previous entry to insert after
354 @param NewEntry The new entry to insert
361 IN NET_LIST_ENTRY
*PrevEntry
,
362 IN NET_LIST_ENTRY
*NewEntry
365 NewEntry
->BackLink
= PrevEntry
;
366 NewEntry
->ForwardLink
= PrevEntry
->ForwardLink
;
367 PrevEntry
->ForwardLink
->BackLink
= NewEntry
;
368 PrevEntry
->ForwardLink
= NewEntry
;
373 Insert the NewEntry before the PostEntry
375 @param PostEntry The entry to insert before
376 @param NewEntry The new entry to insert
382 NetListInsertBefore (
383 IN NET_LIST_ENTRY
*PostEntry
,
384 IN NET_LIST_ENTRY
*NewEntry
387 NewEntry
->ForwardLink
= PostEntry
;
388 NewEntry
->BackLink
= PostEntry
->BackLink
;
389 PostEntry
->BackLink
->ForwardLink
= NewEntry
;
390 PostEntry
->BackLink
= NewEntry
;
395 Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
397 @param Map The netmap to initialize
407 ASSERT (Map
!= NULL
);
409 NetListInit (&Map
->Used
);
410 NetListInit (&Map
->Recycled
);
416 To clean up the netmap, that is, release allocated memories.
418 @param Map The netmap to clean up.
429 NET_LIST_ENTRY
*Entry
;
430 NET_LIST_ENTRY
*Next
;
432 ASSERT (Map
!= NULL
);
434 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Used
) {
435 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
437 NetListRemoveEntry (&Item
->Link
);
443 ASSERT ((Map
->Count
== 0) && NetListIsEmpty (&Map
->Used
));
445 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Recycled
) {
446 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
448 NetListRemoveEntry (&Item
->Link
);
452 ASSERT (NetListIsEmpty (&Map
->Recycled
));
457 Test whether the netmap is empty
459 @param Map The net map to test
461 @return TRUE if the netmap is empty, otherwise FALSE.
469 ASSERT (Map
!= NULL
);
470 return (BOOLEAN
) (Map
->Count
== 0);
475 Return the number of the <Key, Value> pairs in the netmap.
477 @param Map The netmap to get the entry number
479 @return The entry number in the netmap.
492 Allocate an item for the netmap. It will try to allocate
493 a batch of items and return one.
495 @param Map The netmap to allocate item for
497 @return The allocated item or NULL
507 NET_LIST_ENTRY
*Head
;
510 ASSERT (Map
!= NULL
);
512 Head
= &Map
->Recycled
;
514 if (NetListIsEmpty (Head
)) {
515 for (Index
= 0; Index
< NET_MAP_INCREAMENT
; Index
++) {
516 Item
= NetAllocatePool (sizeof (NET_MAP_ITEM
));
526 NetListInsertHead (Head
, &Item
->Link
);
530 Item
= NET_LIST_HEAD (Head
, NET_MAP_ITEM
, Link
);
531 NetListRemoveHead (Head
);
538 Allocate an item to save the <Key, Value> pair to the head of the netmap.
540 @param Map The netmap to insert into
541 @param Key The user's key
542 @param Value The user's value for the key
544 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
545 @retval EFI_SUCCESS The item is inserted to the head
552 IN VOID
*Value OPTIONAL
557 ASSERT (Map
!= NULL
);
559 Item
= NetMapAllocItem (Map
);
562 return EFI_OUT_OF_RESOURCES
;
567 NetListInsertHead (&Map
->Used
, &Item
->Link
);
575 Allocate an item to save the <Key, Value> pair to the tail of the netmap.
577 @param Map The netmap to insert into
578 @param Key The user's key
579 @param Value The user's value for the key
581 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item
582 @retval EFI_SUCCESS The item is inserted to the tail
589 IN VOID
*Value OPTIONAL
594 ASSERT (Map
!= NULL
);
596 Item
= NetMapAllocItem (Map
);
599 return EFI_OUT_OF_RESOURCES
;
604 NetListInsertTail (&Map
->Used
, &Item
->Link
);
613 Check whther the item is in the Map
615 @param Map The netmap to search within
616 @param Item The item to search
618 @return TRUE if the item is in the netmap, otherwise FALSE.
625 IN NET_MAP_ITEM
*Item
628 NET_LIST_ENTRY
*ListEntry
;
630 NET_LIST_FOR_EACH (ListEntry
, &Map
->Used
) {
631 if (ListEntry
== &Item
->Link
) {
641 Find the key in the netmap
643 @param Map The netmap to search within
644 @param Key The key to search
646 @return The point to the item contains the Key, or NULL if Key isn't in the map.
655 NET_LIST_ENTRY
*Entry
;
658 ASSERT (Map
!= NULL
);
660 NET_LIST_FOR_EACH (Entry
, &Map
->Used
) {
661 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
663 if (Item
->Key
== Key
) {
673 Remove the item from the netmap
675 @param Map The netmap to remove the item from
676 @param Item The item to remove
677 @param Value The variable to receive the value if not NULL
679 @return The key of the removed item.
685 IN NET_MAP_ITEM
*Item
,
686 OUT VOID
**Value OPTIONAL
689 ASSERT ((Map
!= NULL
) && (Item
!= NULL
));
690 ASSERT (NetItemInMap (Map
, Item
));
692 NetListRemoveEntry (&Item
->Link
);
694 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
697 *Value
= Item
->Value
;
705 Remove the first entry on the netmap
707 @param Map The netmap to remove the head from
708 @param Value The variable to receive the value if not NULL
710 @return The key of the item removed
716 OUT VOID
**Value OPTIONAL
722 // Often, it indicates a programming error to remove
723 // the first entry in an empty list
725 ASSERT (Map
&& !NetListIsEmpty (&Map
->Used
));
727 Item
= NET_LIST_HEAD (&Map
->Used
, NET_MAP_ITEM
, Link
);
728 NetListRemoveEntry (&Item
->Link
);
730 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
733 *Value
= Item
->Value
;
741 Remove the last entry on the netmap
743 @param Map The netmap to remove the tail from
744 @param Value The variable to receive the value if not NULL
746 @return The key of the item removed
752 OUT VOID
**Value OPTIONAL
758 // Often, it indicates a programming error to remove
759 // the last entry in an empty list
761 ASSERT (Map
&& !NetListIsEmpty (&Map
->Used
));
763 Item
= NET_LIST_TAIL (&Map
->Used
, NET_MAP_ITEM
, Link
);
764 NetListRemoveEntry (&Item
->Link
);
766 NetListInsertHead (&Map
->Recycled
, &Item
->Link
);
769 *Value
= Item
->Value
;
777 Iterate through the netmap and call CallBack for each item. It will
778 contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
779 from the loop. It returns the CallBack's last return value. This
780 function is delete safe for the current item.
782 @param Map The Map to iterate through
783 @param CallBack The callback function to call for each item.
784 @param Arg The opaque parameter to the callback
786 @return It returns the CallBack's last return value.
792 IN NET_MAP_CALLBACK CallBack
,
797 NET_LIST_ENTRY
*Entry
;
798 NET_LIST_ENTRY
*Next
;
799 NET_LIST_ENTRY
*Head
;
803 ASSERT ((Map
!= NULL
) && (CallBack
!= NULL
));
807 if (NetListIsEmpty (Head
)) {
811 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
812 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
813 Result
= CallBack (Map
, Item
, Arg
);
815 if (EFI_ERROR (Result
)) {
825 This is the default unload handle for all the network drivers.
827 @param ImageHandle The drivers' driver image.
829 @retval EFI_SUCCESS The image is unloaded.
830 @retval Others Failed to unload the image.
835 NetLibDefaultUnload (
836 IN EFI_HANDLE ImageHandle
840 EFI_HANDLE
*DeviceHandleBuffer
;
841 UINTN DeviceHandleCount
;
843 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
844 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
845 EFI_DRIVER_CONFIGURATION_PROTOCOL
*DriverConfiguration
;
846 EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics
;
849 // Get the list of all the handles in the handle database.
850 // If there is an error getting the list, then the unload
853 Status
= gBS
->LocateHandleBuffer (
861 if (EFI_ERROR (Status
)) {
866 // Disconnect the driver specified by ImageHandle from all
867 // the devices in the handle database.
869 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
870 Status
= gBS
->DisconnectController (
871 DeviceHandleBuffer
[Index
],
878 // Uninstall all the protocols installed in the driver entry point
880 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
881 Status
= gBS
->HandleProtocol (
882 DeviceHandleBuffer
[Index
],
883 &gEfiDriverBindingProtocolGuid
,
884 (VOID
**) &DriverBinding
887 if (EFI_ERROR (Status
)) {
891 if (DriverBinding
->ImageHandle
!= ImageHandle
) {
895 gBS
->UninstallProtocolInterface (
897 &gEfiDriverBindingProtocolGuid
,
900 Status
= gBS
->HandleProtocol (
901 DeviceHandleBuffer
[Index
],
902 &gEfiComponentNameProtocolGuid
,
903 (VOID
**) &ComponentName
905 if (!EFI_ERROR (Status
)) {
906 gBS
->UninstallProtocolInterface (
908 &gEfiComponentNameProtocolGuid
,
913 Status
= gBS
->HandleProtocol (
914 DeviceHandleBuffer
[Index
],
915 &gEfiDriverConfigurationProtocolGuid
,
916 (VOID
**) &DriverConfiguration
919 if (!EFI_ERROR (Status
)) {
920 gBS
->UninstallProtocolInterface (
922 &gEfiDriverConfigurationProtocolGuid
,
927 Status
= gBS
->HandleProtocol (
928 DeviceHandleBuffer
[Index
],
929 &gEfiDriverDiagnosticsProtocolGuid
,
930 (VOID
**) &DriverDiagnostics
933 if (!EFI_ERROR (Status
)) {
934 gBS
->UninstallProtocolInterface (
936 &gEfiDriverDiagnosticsProtocolGuid
,
943 // Free the buffer containing the list of handles from the handle database
945 if (DeviceHandleBuffer
!= NULL
) {
946 gBS
->FreePool (DeviceHandleBuffer
);
955 Create a child of the service that is identified by ServiceBindingGuid.
957 @param Controller The controller which has the service installed.
958 @param Image The image handle used to open service.
959 @param ServiceBindingGuid The service's Guid.
960 @param ChildHandle The handle to receive the create child
962 @retval EFI_SUCCESS The child is successfully created.
963 @retval Others Failed to create the child.
967 NetLibCreateServiceChild (
968 IN EFI_HANDLE Controller
,
970 IN EFI_GUID
*ServiceBindingGuid
,
971 OUT EFI_HANDLE
*ChildHandle
975 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
978 ASSERT ((ServiceBindingGuid
!= NULL
) && (ChildHandle
!= NULL
));
981 // Get the ServiceBinding Protocol
983 Status
= gBS
->OpenProtocol (
989 EFI_OPEN_PROTOCOL_GET_PROTOCOL
992 if (EFI_ERROR (Status
)) {
999 Status
= Service
->CreateChild (Service
, ChildHandle
);
1005 Destory a child of the service that is identified by ServiceBindingGuid.
1007 @param Controller The controller which has the service installed.
1008 @param Image The image handle used to open service.
1009 @param ServiceBindingGuid The service's Guid.
1010 @param ChildHandle The child to destory
1012 @retval EFI_SUCCESS The child is successfully destoried.
1013 @retval Others Failed to destory the child.
1017 NetLibDestroyServiceChild (
1018 IN EFI_HANDLE Controller
,
1019 IN EFI_HANDLE Image
,
1020 IN EFI_GUID
*ServiceBindingGuid
,
1021 IN EFI_HANDLE ChildHandle
1025 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1027 ASSERT (ServiceBindingGuid
!= NULL
);
1030 // Get the ServiceBinding Protocol
1032 Status
= gBS
->OpenProtocol (
1038 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1041 if (EFI_ERROR (Status
)) {
1046 // destory the child
1048 Status
= Service
->DestroyChild (Service
, ChildHandle
);
1054 Convert the mac address of the simple network protocol installed on
1055 SnpHandle to a unicode string. Callers are responsible for freeing the
1058 @param SnpHandle The handle where the simple network protocol is
1060 @param ImageHandle The image handle used to act as the agent handle to
1061 get the simple network protocol.
1062 @param MacString The pointer to store the address of the string
1063 representation of the mac address.
1065 @retval EFI_OUT_OF_RESOURCES There are not enough memory resource.
1066 @retval other Failed to open the simple network protocol.
1070 NetLibGetMacString (
1071 IN EFI_HANDLE SnpHandle
,
1072 IN EFI_HANDLE ImageHandle
,
1073 IN OUT CHAR16
**MacString
1077 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1078 EFI_SIMPLE_NETWORK_MODE
*Mode
;
1085 // Get the Simple Network protocol from the SnpHandle.
1087 Status
= gBS
->OpenProtocol (
1089 &gEfiSimpleNetworkProtocolGuid
,
1093 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1095 if (EFI_ERROR (Status
)) {
1102 // It takes 2 unicode characters to represent a 1 byte binary buffer.
1103 // Plus one unicode character for the null-terminator.
1105 MacAddress
= NetAllocatePool ((2 * Mode
->HwAddressSize
+ 1) * sizeof (CHAR16
));
1106 if (MacAddress
== NULL
) {
1107 return EFI_OUT_OF_RESOURCES
;
1111 // Convert the mac address into a unicode string.
1113 for (Index
= 0; Index
< Mode
->HwAddressSize
; Index
++) {
1114 MacAddress
[Index
* 2] = NibbleToHexChar ((UINT8
) (Mode
->CurrentAddress
.Addr
[Index
] >> 4));
1115 MacAddress
[Index
* 2 + 1] = NibbleToHexChar (Mode
->CurrentAddress
.Addr
[Index
]);
1118 MacAddress
[Mode
->HwAddressSize
* 2] = L
'\0';
1120 *MacString
= MacAddress
;
1126 Check the default address used by the IPv4 driver is static or dynamic (acquired
1129 @param Controller The controller handle which has the NIC Ip4 Config Protocol
1130 relative with the default address to judge.
1132 @retval TRUE If the default address is static.
1133 @retval FALSE If the default address is acquired from DHCP.
1138 NetLibDefaultAddressIsStatic (
1139 IN EFI_HANDLE Controller
1143 EFI_NIC_IP4_CONFIG_PROTOCOL
*NicIp4
;
1145 NIC_IP4_CONFIG_INFO
*ConfigInfo
;
1148 Status
= gBS
->HandleProtocol (
1150 &gEfiNicIp4ConfigProtocolGuid
,
1153 if (EFI_ERROR (Status
)) {
1158 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, NULL
);
1159 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1163 ConfigInfo
= NetAllocatePool (Len
);
1164 if (ConfigInfo
== NULL
) {
1169 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, ConfigInfo
);
1170 if (EFI_ERROR (Status
)) {
1174 IsStatic
= (BOOLEAN
) (ConfigInfo
->Source
== IP4_CONFIG_SOURCE_STATIC
);
1178 NetFreePool (ConfigInfo
);
1184 Create an IPv4 device path node.
1186 @param Node Pointer to the IPv4 device path node.
1187 @param Controller The handle where the NIC IP4 config protocol resides.
1188 @param LocalIp The local IPv4 address.
1189 @param LocalPort The local port.
1190 @param RemoteIp The remote IPv4 address.
1191 @param RemotePort The remote port.
1192 @param Protocol The protocol type in the IP header.
1193 @param UseDefaultAddress Whether this instance is using default address or not.
1198 NetLibCreateIPv4DPathNode (
1199 IN OUT IPv4_DEVICE_PATH
*Node
,
1200 IN EFI_HANDLE Controller
,
1201 IN IP4_ADDR LocalIp
,
1202 IN UINT16 LocalPort
,
1203 IN IP4_ADDR RemoteIp
,
1204 IN UINT16 RemotePort
,
1206 IN BOOLEAN UseDefaultAddress
1209 Node
->Header
.Type
= MESSAGING_DEVICE_PATH
;
1210 Node
->Header
.SubType
= MSG_IPv4_DP
;
1211 SetDevicePathNodeLength (&Node
->Header
, 19);
1213 NetCopyMem (&Node
->LocalIpAddress
, &LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
1214 NetCopyMem (&Node
->RemoteIpAddress
, &RemoteIp
, sizeof (EFI_IPv4_ADDRESS
));
1216 Node
->LocalPort
= LocalPort
;
1217 Node
->RemotePort
= RemotePort
;
1219 Node
->Protocol
= Protocol
;
1221 if (!UseDefaultAddress
) {
1222 Node
->StaticIpAddress
= TRUE
;
1224 Node
->StaticIpAddress
= NetLibDefaultAddressIsStatic (Controller
);
1230 Find the UNDI/SNP handle from controller and protocol GUID.
1231 For example, IP will open a MNP child to transmit/receive
1232 packets, when MNP is stopped, IP should also be stopped. IP
1233 needs to find its own private data which is related the IP's
1234 service binding instance that is install on UNDI/SNP handle.
1235 Now, the controller is either a MNP or ARP child handle. But
1236 IP opens these handle BY_DRIVER, use that info, we can get the
1239 @param Controller Then protocol handle to check
1240 @param ProtocolGuid The protocol that is related with the handle.
1242 @return The UNDI/SNP handle or NULL.
1246 NetLibGetNicHandle (
1247 IN EFI_HANDLE Controller
,
1248 IN EFI_GUID
*ProtocolGuid
1251 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenBuffer
;
1257 Status
= gBS
->OpenProtocolInformation (
1264 if (EFI_ERROR (Status
)) {
1270 for (Index
= 0; Index
< OpenCount
; Index
++) {
1271 if (OpenBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1272 Handle
= OpenBuffer
[Index
].ControllerHandle
;
1277 gBS
->FreePool (OpenBuffer
);
1282 Add a Deferred Procedure Call to the end of the DPC queue.
1284 @DpcTpl The EFI_TPL that the DPC should be invoked.
1285 @DpcProcedure Pointer to the DPC's function.
1286 @DpcContext Pointer to the DPC's context. Passed to DpcProcedure
1287 when DpcProcedure is invoked.
1289 @retval EFI_SUCCESS The DPC was queued.
1290 @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL.
1291 DpcProcedure is NULL.
1292 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
1293 add the DPC to the queue.
1299 IN EFI_DPC_PROCEDURE DpcProcedure
,
1300 IN VOID
*DpcContext OPTIONAL
1303 return mDpc
->QueueDpc (mDpc
, DpcTpl
, DpcProcedure
, DpcContext
);
1307 Add a Deferred Procedure Call to the end of the DPC queue.
1309 @retval EFI_SUCCESS One or more DPCs were invoked.
1310 @retval EFI_NOT_FOUND No DPCs were invoked.
1318 return mDpc
->DispatchDpc(mDpc
);
1323 The constructor function caches the pointer to DPC protocol.
1325 The constructor function locates DPC protocol from protocol database.
1326 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
1328 @param ImageHandle The firmware allocated handle for the EFI image.
1329 @param SystemTable A pointer to the EFI System Table.
1331 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
1337 IN EFI_HANDLE ImageHandle
,
1338 IN EFI_SYSTEM_TABLE
*SystemTable
1343 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
1344 ASSERT_EFI_ERROR (Status
);
1345 ASSERT (mDpc
!= NULL
);