To align w/ UEFI 2.3 Spec, PXE driver installs PxeBc, LoadFile and SNP Protocol on IPV4/V6 child handle separately.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11112 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
hhuan13 2010-12-01 07:04:48 +00:00
parent 3ae55b76d9
commit 15f3fc850c
2 changed files with 166 additions and 30 deletions

View File

@ -25,6 +25,13 @@ EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {
NULL NULL
}; };
//
// PXE_PRIVATE_GUID is only used to keep the relationship between
// NIC handle and virtual child handles.
//
EFI_GUID mPxeBcPrivateGuid = PXEBC_PRIVATE_GUID;
/** /**
Get the Nic handle using any child handle in the IPv4 stack. Get the Nic handle using any child handle in the IPv4 stack.
@ -226,11 +233,11 @@ PxeBcDestroyIp4Children (
if (Private->Ip4Nic != NULL) { if (Private->Ip4Nic != NULL) {
// //
// Close PxeBc from the parent Nic handle and destroy the virtual handle. // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.
// //
gBS->CloseProtocol ( gBS->CloseProtocol (
Private->Controller, Private->Controller,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
This->DriverBindingHandle, This->DriverBindingHandle,
Private->Ip4Nic->Controller Private->Ip4Nic->Controller
); );
@ -241,8 +248,28 @@ PxeBcDestroyIp4Children (
Private->Ip4Nic->DevicePath, Private->Ip4Nic->DevicePath,
&gEfiLoadFileProtocolGuid, &gEfiLoadFileProtocolGuid,
&Private->Ip4Nic->LoadFile, &Private->Ip4Nic->LoadFile,
&gEfiPxeBaseCodeProtocolGuid,
&Private->PxeBc,
NULL NULL
); );
if (Private->Snp != NULL) {
//
// Close SNP from the child virtual handle
//
gBS->CloseProtocol (
Private->Ip4Nic->Controller,
&gEfiSimpleNetworkProtocolGuid,
This->DriverBindingHandle,
Private->Ip4Nic->Controller
);
gBS->UninstallProtocolInterface (
Private->Ip4Nic->Controller,
&gEfiSimpleNetworkProtocolGuid,
Private->Snp
);
}
FreePool (Private->Ip4Nic); FreePool (Private->Ip4Nic);
} }
@ -366,22 +393,41 @@ PxeBcDestroyIp6Children (
if (Private->Ip6Nic != NULL) { if (Private->Ip6Nic != NULL) {
// //
// Close PxeBc from the parent Nic handle and destroy the virtual handle. // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.
// //
gBS->CloseProtocol ( gBS->CloseProtocol (
Private->Controller, Private->Controller,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
This->DriverBindingHandle, This->DriverBindingHandle,
Private->Ip6Nic->Controller Private->Ip6Nic->Controller
); );
gBS->UninstallMultipleProtocolInterfaces ( gBS->UninstallMultipleProtocolInterfaces (
Private->Ip6Nic->Controller, Private->Ip6Nic->Controller,
&gEfiDevicePathProtocolGuid, &gEfiDevicePathProtocolGuid,
Private->Ip6Nic->DevicePath, Private->Ip6Nic->DevicePath,
&gEfiLoadFileProtocolGuid, &gEfiLoadFileProtocolGuid,
&Private->Ip6Nic->LoadFile, &Private->Ip6Nic->LoadFile,
&gEfiPxeBaseCodeProtocolGuid,
&Private->PxeBc,
NULL NULL
); );
if (Private->Snp != NULL) {
//
// Close SNP from the child virtual handle
//
gBS->CloseProtocol (
Private->Ip6Nic->Controller,
&gEfiSimpleNetworkProtocolGuid,
This->DriverBindingHandle,
Private->Ip6Nic->Controller
);
gBS->UninstallProtocolInterface (
Private->Ip6Nic->Controller,
&gEfiSimpleNetworkProtocolGuid,
Private->Snp
);
}
FreePool (Private->Ip6Nic); FreePool (Private->Ip6Nic);
} }
@ -415,11 +461,12 @@ PxeBcCreateIp4Children (
{ {
EFI_STATUS Status; EFI_STATUS Status;
IPv4_DEVICE_PATH Ip4Node; IPv4_DEVICE_PATH Ip4Node;
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
EFI_PXE_BASE_CODE_MODE *Mode; EFI_PXE_BASE_CODE_MODE *Mode;
EFI_UDP4_CONFIG_DATA *Udp4CfgData; EFI_UDP4_CONFIG_DATA *Udp4CfgData;
EFI_IP4_CONFIG_DATA *Ip4CfgData; EFI_IP4_CONFIG_DATA *Ip4CfgData;
EFI_IP4_MODE_DATA Ip4ModeData; EFI_IP4_MODE_DATA Ip4ModeData;
PXEBC_PRIVATE_PROTOCOL *Id;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
if (Private->Ip4Nic != NULL) { if (Private->Ip4Nic != NULL) {
// //
@ -629,20 +676,54 @@ PxeBcCreateIp4Children (
Private->Ip4Nic->DevicePath, Private->Ip4Nic->DevicePath,
&gEfiLoadFileProtocolGuid, &gEfiLoadFileProtocolGuid,
&Private->Ip4Nic->LoadFile, &Private->Ip4Nic->LoadFile,
&gEfiPxeBaseCodeProtocolGuid,
&Private->PxeBc,
NULL NULL
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto ON_ERROR; goto ON_ERROR;
} }
if (Private->Snp != NULL) {
// //
// Open PxeBaseCode protocol by child to setup a parent-child relationship between // Install SNP protocol on purpose is for some OS loader backward
// compatibility consideration.
//
Status = gBS->InstallProtocolInterface (
&Private->Ip4Nic->Controller,
&gEfiSimpleNetworkProtocolGuid,
EFI_NATIVE_INTERFACE,
Private->Snp
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Open SNP on the child handle BY_DRIVER. It will prevent any additionally
// layering to perform the experiment.
//
Status = gBS->OpenProtocol (
Private->Ip4Nic->Controller,
&gEfiSimpleNetworkProtocolGuid,
(VOID **) &Snp,
This->DriverBindingHandle,
Private->Ip4Nic->Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
}
//
// Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between
// real NIC handle and the virtual IPv4 NIC handle. // real NIC handle and the virtual IPv4 NIC handle.
// //
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
ControllerHandle, ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
(VOID **) &PxeBc, (VOID **) &Id,
This->DriverBindingHandle, This->DriverBindingHandle,
Private->Ip4Nic->Controller, Private->Ip4Nic->Controller,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
@ -654,7 +735,7 @@ PxeBcCreateIp4Children (
// //
// Set default configure data for Udp4Read and Ip4 instance. // Set default configure data for Udp4Read and Ip4 instance.
// //
Mode = PxeBc->Mode; Mode = Private->PxeBc.Mode;
Udp4CfgData = &Private->Udp4CfgData; Udp4CfgData = &Private->Udp4CfgData;
Ip4CfgData = &Private->Ip4CfgData; Ip4CfgData = &Private->Ip4CfgData;
@ -701,10 +782,11 @@ PxeBcCreateIp6Children (
{ {
EFI_STATUS Status; EFI_STATUS Status;
IPv6_DEVICE_PATH Ip6Node; IPv6_DEVICE_PATH Ip6Node;
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
EFI_UDP6_CONFIG_DATA *Udp6CfgData; EFI_UDP6_CONFIG_DATA *Udp6CfgData;
EFI_IP6_CONFIG_DATA *Ip6CfgData; EFI_IP6_CONFIG_DATA *Ip6CfgData;
EFI_IP6_MODE_DATA Ip6ModeData; EFI_IP6_MODE_DATA Ip6ModeData;
PXEBC_PRIVATE_PROTOCOL *Id;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
if (Private->Ip6Nic != NULL) { if (Private->Ip6Nic != NULL) {
// //
@ -902,20 +984,54 @@ PxeBcCreateIp6Children (
Private->Ip6Nic->DevicePath, Private->Ip6Nic->DevicePath,
&gEfiLoadFileProtocolGuid, &gEfiLoadFileProtocolGuid,
&Private->Ip6Nic->LoadFile, &Private->Ip6Nic->LoadFile,
&gEfiPxeBaseCodeProtocolGuid,
&Private->PxeBc,
NULL NULL
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto ON_ERROR; goto ON_ERROR;
} }
if (Private->Snp != NULL) {
// //
// Open PxeBaseCode protocol by child to setup a parent-child relationship between // Install SNP protocol on purpose is for some OS loader backward
// compatibility consideration.
//
Status = gBS->InstallProtocolInterface (
&Private->Ip6Nic->Controller,
&gEfiSimpleNetworkProtocolGuid,
EFI_NATIVE_INTERFACE,
Private->Snp
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
//
// Open SNP on the child handle BY_DRIVER. It will prevent any additionally
// layering to perform the experiment.
//
Status = gBS->OpenProtocol (
Private->Ip6Nic->Controller,
&gEfiSimpleNetworkProtocolGuid,
(VOID **) &Snp,
This->DriverBindingHandle,
Private->Ip6Nic->Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
}
//
// Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between
// real NIC handle and the virtual IPv6 NIC handle. // real NIC handle and the virtual IPv6 NIC handle.
// //
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
ControllerHandle, ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
(VOID **) &PxeBc, (VOID **) &Id,
This->DriverBindingHandle, This->DriverBindingHandle,
Private->Ip6Nic->Controller, Private->Ip6Nic->Controller,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
@ -1091,15 +1207,15 @@ PxeBcDriverBindingStart (
) )
{ {
PXEBC_PRIVATE_DATA *Private; PXEBC_PRIVATE_DATA *Private;
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
EFI_STATUS Status; EFI_STATUS Status;
EFI_STATUS Ip4Status; EFI_STATUS Ip4Status;
EFI_STATUS Ip6Status; EFI_STATUS Ip6Status;
PXEBC_PRIVATE_PROTOCOL *Id;
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
ControllerHandle, ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
(VOID **) &PxeBc, (VOID **) &Id,
This->DriverBindingHandle, This->DriverBindingHandle,
ControllerHandle, ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL EFI_OPEN_PROTOCOL_GET_PROTOCOL
@ -1108,7 +1224,7 @@ PxeBcDriverBindingStart (
// //
// Skip the initialization if the driver has been started already. // Skip the initialization if the driver has been started already.
// //
Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc); Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);
} else { } else {
// //
// If the driver has not been started yet, it should do initialization. // If the driver has not been started yet, it should do initialization.
@ -1165,17 +1281,22 @@ PxeBcDriverBindingStart (
} }
// //
// Install PxeBaseCode protocol onto the real NIC handler. // Install PxeBaseCodePrivate protocol onto the real NIC handler.
// //
Status = gBS->InstallProtocolInterface ( Status = gBS->InstallProtocolInterface (
&ControllerHandle, &ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
EFI_NATIVE_INTERFACE, EFI_NATIVE_INTERFACE,
&Private->PxeBc &Private->Id
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto ON_ERROR; goto ON_ERROR;
} }
//
// Try to locate SNP protocol.
//
NetLibGetSnpHandle(ControllerHandle, &Private->Snp);
} }
// //
@ -1201,8 +1322,8 @@ PxeBcDriverBindingStart (
ON_ERROR: ON_ERROR:
gBS->UninstallProtocolInterface ( gBS->UninstallProtocolInterface (
ControllerHandle, ControllerHandle,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
&Private->PxeBc &Private->Id
); );
PxeBcDestroyIp4Children (This, Private); PxeBcDestroyIp4Children (This, Private);
PxeBcDestroyIp6Children (This, Private); PxeBcDestroyIp6Children (This, Private);
@ -1242,17 +1363,17 @@ PxeBcDriverBindingStop (
{ {
PXEBC_PRIVATE_DATA *Private; PXEBC_PRIVATE_DATA *Private;
PXEBC_VIRTUAL_NIC *VirtualNic; PXEBC_VIRTUAL_NIC *VirtualNic;
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
EFI_LOAD_FILE_PROTOCOL *LoadFile; EFI_LOAD_FILE_PROTOCOL *LoadFile;
EFI_STATUS Status; EFI_STATUS Status;
EFI_HANDLE NicHandle; EFI_HANDLE NicHandle;
BOOLEAN IsIpv6; BOOLEAN IsIpv6;
PXEBC_PRIVATE_PROTOCOL *Id;
Private = NULL; Private = NULL;
NicHandle = NULL; NicHandle = NULL;
VirtualNic = NULL; VirtualNic = NULL;
LoadFile = NULL; LoadFile = NULL;
PxeBc = NULL; Id = NULL;
IsIpv6 = FALSE; IsIpv6 = FALSE;
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
@ -1278,12 +1399,12 @@ PxeBcDriverBindingStop (
} }
// //
// Try to retrieve the private data by PxeBc protocol. // Try to retrieve the private data by PxeBcPrivate protocol.
// //
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol (
NicHandle, NicHandle,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
(VOID **) &PxeBc, (VOID **) &Id,
This->DriverBindingHandle, This->DriverBindingHandle,
ControllerHandle, ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL EFI_OPEN_PROTOCOL_GET_PROTOCOL
@ -1291,7 +1412,7 @@ PxeBcDriverBindingStop (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc); Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);
} else { } else {
// //
@ -1329,8 +1450,8 @@ PxeBcDriverBindingStop (
if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) { if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {
gBS->UninstallProtocolInterface ( gBS->UninstallProtocolInterface (
NicHandle, NicHandle,
&gEfiPxeBaseCodeProtocolGuid, &mPxeBcPrivateGuid,
&Private->PxeBc &Private->Id
); );
FreePool (Private); FreePool (Private);
} }

View File

@ -51,6 +51,7 @@
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
typedef struct _PXEBC_PRIVATE_DATA PXEBC_PRIVATE_DATA; typedef struct _PXEBC_PRIVATE_DATA PXEBC_PRIVATE_DATA;
typedef struct _PXEBC_PRIVATE_PROTOCOL PXEBC_PRIVATE_PROTOCOL;
typedef struct _PXEBC_VIRTUAL_NIC PXEBC_VIRTUAL_NIC; typedef struct _PXEBC_VIRTUAL_NIC PXEBC_VIRTUAL_NIC;
#include "PxeBcDriver.h" #include "PxeBcDriver.h"
@ -72,13 +73,24 @@ typedef struct _PXEBC_VIRTUAL_NIC PXEBC_VIRTUAL_NIC;
#define PXEBC_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'X', 'E', 'P') #define PXEBC_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'X', 'E', 'P')
#define PXEBC_VIRTUAL_NIC_SIGNATURE SIGNATURE_32 ('P', 'X', 'E', 'V') #define PXEBC_VIRTUAL_NIC_SIGNATURE SIGNATURE_32 ('P', 'X', 'E', 'V')
#define PXEBC_PRIVATE_DATA_FROM_PXEBC(a) CR (a, PXEBC_PRIVATE_DATA, PxeBc, PXEBC_PRIVATE_DATA_SIGNATURE) #define PXEBC_PRIVATE_DATA_FROM_PXEBC(a) CR (a, PXEBC_PRIVATE_DATA, PxeBc, PXEBC_PRIVATE_DATA_SIGNATURE)
#define PXEBC_PRIVATE_DATA_FROM_ID(a) CR (a, PXEBC_PRIVATE_DATA, Id, PXEBC_PRIVATE_DATA_SIGNATURE)
#define PXEBC_VIRTUAL_NIC_FROM_LOADFILE(a) CR (a, PXEBC_VIRTUAL_NIC, LoadFile, PXEBC_VIRTUAL_NIC_SIGNATURE) #define PXEBC_VIRTUAL_NIC_FROM_LOADFILE(a) CR (a, PXEBC_VIRTUAL_NIC, LoadFile, PXEBC_VIRTUAL_NIC_SIGNATURE)
#define PXEBC_PRIVATE_GUID \
{ \
0xa4dfac32, 0xfbb4, 0x4907,{0xb3, 0x13, 0x4, 0xe, 0xe2, 0x42, 0x33, 0x20 } \
}
typedef union { typedef union {
PXEBC_DHCP4_PACKET_CACHE Dhcp4; PXEBC_DHCP4_PACKET_CACHE Dhcp4;
PXEBC_DHCP6_PACKET_CACHE Dhcp6; PXEBC_DHCP6_PACKET_CACHE Dhcp6;
} PXEBC_DHCP_PACKET_CACHE; } PXEBC_DHCP_PACKET_CACHE;
struct _PXEBC_PRIVATE_PROTOCOL {
UINT64 Reserved;
};
struct _PXEBC_VIRTUAL_NIC { struct _PXEBC_VIRTUAL_NIC {
UINT32 Signature; UINT32 Signature;
EFI_HANDLE Controller; EFI_HANDLE Controller;
@ -92,6 +104,9 @@ struct _PXEBC_PRIVATE_DATA {
EFI_HANDLE Controller; EFI_HANDLE Controller;
EFI_HANDLE Image; EFI_HANDLE Image;
PXEBC_PRIVATE_PROTOCOL Id;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
PXEBC_VIRTUAL_NIC *Ip4Nic; PXEBC_VIRTUAL_NIC *Ip4Nic;
PXEBC_VIRTUAL_NIC *Ip6Nic; PXEBC_VIRTUAL_NIC *Ip6Nic;