|
@@ -909,6 +909,10 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
909
|
909
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
910
|
910
|
struct efi_device *efidev;
|
911
|
911
|
struct efi_snp_device *snpdev;
|
|
912
|
+ union {
|
|
913
|
+ EFI_DEVICE_PATH_PROTOCOL *path;
|
|
914
|
+ void *interface;
|
|
915
|
+ } path;
|
912
|
916
|
EFI_DEVICE_PATH_PROTOCOL *path_end;
|
913
|
917
|
MAC_ADDR_DEVICE_PATH *macpath;
|
914
|
918
|
size_t path_prefix_len = 0;
|
|
@@ -923,14 +927,8 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
923
|
927
|
goto err_no_efidev;
|
924
|
928
|
}
|
925
|
929
|
|
926
|
|
- /* Calculate device path prefix length */
|
927
|
|
- path_end = efi_devpath_end ( efidev->path );
|
928
|
|
- path_prefix_len = ( ( ( void * ) path_end ) -
|
929
|
|
- ( ( void * ) efidev->path ) );
|
930
|
|
-
|
931
|
930
|
/* Allocate the SNP device */
|
932
|
|
- snpdev = zalloc ( sizeof ( *snpdev ) + path_prefix_len +
|
933
|
|
- sizeof ( *macpath ) );
|
|
931
|
+ snpdev = zalloc ( sizeof ( *snpdev ) );
|
934
|
932
|
if ( ! snpdev ) {
|
935
|
933
|
rc = -ENOMEM;
|
936
|
934
|
goto err_alloc_snp;
|
|
@@ -993,9 +991,32 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
993
|
991
|
sizeof ( snpdev->name[0] ) ),
|
994
|
992
|
"%s", netdev->name );
|
995
|
993
|
|
|
994
|
+ /* Get the parent device path */
|
|
995
|
+ if ( ( efirc = bs->OpenProtocol ( efidev->device,
|
|
996
|
+ &efi_device_path_protocol_guid,
|
|
997
|
+ &path.interface, efi_image_handle,
|
|
998
|
+ efidev->device,
|
|
999
|
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
|
|
1000
|
+ rc = -EEFI ( efirc );
|
|
1001
|
+ DBGC ( snpdev, "SNPDEV %p cannot get %p %s device path: %s\n",
|
|
1002
|
+ snpdev, efidev->device,
|
|
1003
|
+ efi_handle_name ( efidev->device ), strerror ( rc ) );
|
|
1004
|
+ goto err_open_device_path;
|
|
1005
|
+ }
|
|
1006
|
+
|
|
1007
|
+ /* Allocate the new device path */
|
|
1008
|
+ path_end = efi_devpath_end ( path.path );
|
|
1009
|
+ path_prefix_len = ( ( ( void * ) path_end ) - ( ( void * ) path.path ));
|
|
1010
|
+ snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
|
|
1011
|
+ sizeof ( *path_end ) );
|
|
1012
|
+ if ( ! snpdev->path ) {
|
|
1013
|
+ rc = -ENOMEM;
|
|
1014
|
+ goto err_alloc_device_path;
|
|
1015
|
+ }
|
|
1016
|
+
|
996
|
1017
|
/* Populate the device path */
|
997
|
|
- memcpy ( &snpdev->path, efidev->path, path_prefix_len );
|
998
|
|
- macpath = ( ( ( void * ) &snpdev->path ) + path_prefix_len );
|
|
1018
|
+ memcpy ( snpdev->path, path.path, path_prefix_len );
|
|
1019
|
+ macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
|
999
|
1020
|
path_end = ( ( void * ) ( macpath + 1 ) );
|
1000
|
1021
|
memset ( macpath, 0, sizeof ( *macpath ) );
|
1001
|
1022
|
macpath->Header.Type = MESSAGING_DEVICE_PATH;
|
|
@@ -1013,7 +1034,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
1013
|
1034
|
if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
|
1014
|
1035
|
&snpdev->handle,
|
1015
|
1036
|
&efi_simple_network_protocol_guid, &snpdev->snp,
|
1016
|
|
- &efi_device_path_protocol_guid, &snpdev->path,
|
|
1037
|
+ &efi_device_path_protocol_guid, snpdev->path,
|
1017
|
1038
|
&efi_nii_protocol_guid, &snpdev->nii,
|
1018
|
1039
|
&efi_nii31_protocol_guid, &snpdev->nii,
|
1019
|
1040
|
&efi_component_name2_protocol_guid, &snpdev->name2,
|
|
@@ -1046,6 +1067,10 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
1046
|
1067
|
/* Add to list of SNP devices */
|
1047
|
1068
|
list_add ( &snpdev->list, &efi_snp_devices );
|
1048
|
1069
|
|
|
1070
|
+ /* Close device path */
|
|
1071
|
+ bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
|
|
1072
|
+ efi_image_handle, efidev->device );
|
|
1073
|
+
|
1049
|
1074
|
DBGC ( snpdev, "SNPDEV %p installed for %s as device %p %s\n",
|
1050
|
1075
|
snpdev, netdev->name, snpdev->handle,
|
1051
|
1076
|
efi_handle_name ( snpdev->handle ) );
|
|
@@ -1058,13 +1083,18 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
1058
|
1083
|
bs->UninstallMultipleProtocolInterfaces (
|
1059
|
1084
|
snpdev->handle,
|
1060
|
1085
|
&efi_simple_network_protocol_guid, &snpdev->snp,
|
1061
|
|
- &efi_device_path_protocol_guid, &snpdev->path,
|
|
1086
|
+ &efi_device_path_protocol_guid, snpdev->path,
|
1062
|
1087
|
&efi_nii_protocol_guid, &snpdev->nii,
|
1063
|
1088
|
&efi_nii31_protocol_guid, &snpdev->nii,
|
1064
|
1089
|
&efi_component_name2_protocol_guid, &snpdev->name2,
|
1065
|
1090
|
&efi_load_file_protocol_guid, &snpdev->load_file,
|
1066
|
1091
|
NULL );
|
1067
|
1092
|
err_install_protocol_interface:
|
|
1093
|
+ free ( snpdev->path );
|
|
1094
|
+ err_alloc_device_path:
|
|
1095
|
+ bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
|
|
1096
|
+ efi_image_handle, efidev->device );
|
|
1097
|
+ err_open_device_path:
|
1068
|
1098
|
bs->CloseEvent ( snpdev->snp.WaitForPacket );
|
1069
|
1099
|
err_create_event:
|
1070
|
1100
|
err_ll_addr_len:
|
|
@@ -1124,12 +1154,13 @@ static void efi_snp_remove ( struct net_device *netdev ) {
|
1124
|
1154
|
bs->UninstallMultipleProtocolInterfaces (
|
1125
|
1155
|
snpdev->handle,
|
1126
|
1156
|
&efi_simple_network_protocol_guid, &snpdev->snp,
|
1127
|
|
- &efi_device_path_protocol_guid, &snpdev->path,
|
|
1157
|
+ &efi_device_path_protocol_guid, snpdev->path,
|
1128
|
1158
|
&efi_nii_protocol_guid, &snpdev->nii,
|
1129
|
1159
|
&efi_nii31_protocol_guid, &snpdev->nii,
|
1130
|
1160
|
&efi_component_name2_protocol_guid, &snpdev->name2,
|
1131
|
1161
|
&efi_load_file_protocol_guid, &snpdev->load_file,
|
1132
|
1162
|
NULL );
|
|
1163
|
+ free ( snpdev->path );
|
1133
|
1164
|
bs->CloseEvent ( snpdev->snp.WaitForPacket );
|
1134
|
1165
|
netdev_put ( snpdev->netdev );
|
1135
|
1166
|
free ( snpdev );
|