|
@@ -28,12 +28,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
28
|
28
|
#include <ipxe/in.h>
|
29
|
29
|
#include <ipxe/pci.h>
|
30
|
30
|
#include <ipxe/efi/efi.h>
|
31
|
|
-#include <ipxe/efi/Protocol/DriverBinding.h>
|
32
|
|
-#include <ipxe/efi/Protocol/PciIo.h>
|
|
31
|
+#include <ipxe/efi/efi_pci.h>
|
|
32
|
+#include <ipxe/efi/efi_driver.h>
|
33
|
33
|
#include <ipxe/efi/Protocol/SimpleNetwork.h>
|
34
|
|
-#include <ipxe/efi/Protocol/ComponentName2.h>
|
35
|
34
|
#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
|
36
|
|
-#include <config/general.h>
|
|
35
|
+#include <ipxe/efi/Protocol/DevicePath.h>
|
37
|
36
|
|
38
|
37
|
/** @file
|
39
|
38
|
*
|
|
@@ -43,6 +42,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
43
|
42
|
|
44
|
43
|
/** An SNP device */
|
45
|
44
|
struct efi_snp_device {
|
|
45
|
+ /** List of SNP devices */
|
|
46
|
+ struct list_head list;
|
46
|
47
|
/** The underlying iPXE network device */
|
47
|
48
|
struct net_device *netdev;
|
48
|
49
|
/** EFI device handle */
|
|
@@ -81,14 +82,6 @@ struct efi_snp_device {
|
81
|
82
|
static EFI_GUID efi_simple_network_protocol_guid
|
82
|
83
|
= EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
|
83
|
84
|
|
84
|
|
-/** EFI driver binding protocol GUID */
|
85
|
|
-static EFI_GUID efi_driver_binding_protocol_guid
|
86
|
|
- = EFI_DRIVER_BINDING_PROTOCOL_GUID;
|
87
|
|
-
|
88
|
|
-/** EFI component name protocol GUID */
|
89
|
|
-static EFI_GUID efi_component_name2_protocol_guid
|
90
|
|
- = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
|
91
|
|
-
|
92
|
85
|
/** EFI device path protocol GUID */
|
93
|
86
|
static EFI_GUID efi_device_path_protocol_guid
|
94
|
87
|
= EFI_DEVICE_PATH_PROTOCOL_GUID;
|
|
@@ -107,9 +100,8 @@ static EFI_GUID efi_nii31_protocol_guid = {
|
107
|
100
|
{ 0xBC, 0x81, 0x76, 0x7F, 0x1F, 0x97, 0x7A, 0x89 }
|
108
|
101
|
};
|
109
|
102
|
|
110
|
|
-/** EFI PCI I/O protocol GUID */
|
111
|
|
-static EFI_GUID efi_pci_io_protocol_guid
|
112
|
|
- = EFI_PCI_IO_PROTOCOL_GUID;
|
|
103
|
+/** List of SNP devices */
|
|
104
|
+static LIST_HEAD ( efi_snp_devices );
|
113
|
105
|
|
114
|
106
|
/**
|
115
|
107
|
* Set EFI SNP mode based on iPXE net device parameters
|
|
@@ -750,188 +742,58 @@ static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
|
750
|
742
|
};
|
751
|
743
|
|
752
|
744
|
/**
|
753
|
|
- * Locate net device corresponding to EFI device
|
754
|
|
- *
|
755
|
|
- * @v driver EFI driver
|
756
|
|
- * @v device EFI device
|
757
|
|
- * @ret netdev Net device, or NULL if not found
|
758
|
|
- */
|
759
|
|
-static struct net_device *
|
760
|
|
-efi_snp_netdev ( EFI_DRIVER_BINDING_PROTOCOL *driver, EFI_HANDLE device ) {
|
761
|
|
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
762
|
|
- union {
|
763
|
|
- EFI_PCI_IO_PROTOCOL *pci;
|
764
|
|
- void *interface;
|
765
|
|
- } u;
|
766
|
|
- UINTN pci_segment, pci_bus, pci_dev, pci_fn;
|
767
|
|
- unsigned int pci_busdevfn;
|
768
|
|
- struct net_device *netdev = NULL;
|
769
|
|
- EFI_STATUS efirc;
|
770
|
|
-
|
771
|
|
- /* See if device is a PCI device */
|
772
|
|
- if ( ( efirc = bs->OpenProtocol ( device,
|
773
|
|
- &efi_pci_io_protocol_guid,
|
774
|
|
- &u.interface,
|
775
|
|
- driver->DriverBindingHandle,
|
776
|
|
- device,
|
777
|
|
- EFI_OPEN_PROTOCOL_BY_DRIVER )) !=0 ){
|
778
|
|
- DBGCP ( driver, "SNPDRV %p device %p is not a PCI device\n",
|
779
|
|
- driver, device );
|
780
|
|
- goto out_no_pci_io;
|
781
|
|
- }
|
782
|
|
-
|
783
|
|
- /* Get PCI bus:dev.fn address */
|
784
|
|
- if ( ( efirc = u.pci->GetLocation ( u.pci, &pci_segment, &pci_bus,
|
785
|
|
- &pci_dev, &pci_fn ) ) != 0 ) {
|
786
|
|
- DBGC ( driver, "SNPDRV %p device %p could not get PCI "
|
787
|
|
- "location: %s\n",
|
788
|
|
- driver, device, efi_strerror ( efirc ) );
|
789
|
|
- goto out_no_pci_location;
|
790
|
|
- }
|
791
|
|
- DBGCP ( driver, "SNPDRV %p device %p is PCI %04lx:%02lx:%02lx.%lx\n",
|
792
|
|
- driver, device, ( ( unsigned long ) pci_segment ),
|
793
|
|
- ( ( unsigned long ) pci_bus ), ( ( unsigned long ) pci_dev ),
|
794
|
|
- ( ( unsigned long ) pci_fn ) );
|
795
|
|
-
|
796
|
|
- /* Look up corresponding network device */
|
797
|
|
- pci_busdevfn = PCI_BUSDEVFN ( pci_bus, pci_dev, pci_fn );
|
798
|
|
- if ( ( netdev = find_netdev_by_location ( BUS_TYPE_PCI,
|
799
|
|
- pci_busdevfn ) ) == NULL ) {
|
800
|
|
- DBGCP ( driver, "SNPDRV %p device %p is not a iPXE network "
|
801
|
|
- "device\n", driver, device );
|
802
|
|
- goto out_no_netdev;
|
803
|
|
- }
|
804
|
|
- DBGC ( driver, "SNPDRV %p device %p is %s\n",
|
805
|
|
- driver, device, netdev->name );
|
806
|
|
-
|
807
|
|
- out_no_netdev:
|
808
|
|
- out_no_pci_location:
|
809
|
|
- bs->CloseProtocol ( device, &efi_pci_io_protocol_guid,
|
810
|
|
- driver->DriverBindingHandle, device );
|
811
|
|
- out_no_pci_io:
|
812
|
|
- return netdev;
|
813
|
|
-}
|
814
|
|
-
|
815
|
|
-/**
|
816
|
|
- * Locate SNP corresponding to EFI device
|
|
745
|
+ * Locate SNP device corresponding to network device
|
817
|
746
|
*
|
818
|
|
- * @v driver EFI driver
|
819
|
|
- * @v device EFI device
|
820
|
|
- * @ret snp EFI SNP, or NULL if not found
|
|
747
|
+ * @v netdev Network device
|
|
748
|
+ * @ret snp SNP device, or NULL if not found
|
821
|
749
|
*/
|
822
|
|
-static struct efi_snp_device *
|
823
|
|
-efi_snp_snpdev ( EFI_DRIVER_BINDING_PROTOCOL *driver, EFI_HANDLE device ) {
|
824
|
|
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
825
|
|
- union {
|
826
|
|
- EFI_SIMPLE_NETWORK_PROTOCOL *snp;
|
827
|
|
- void *interface;
|
828
|
|
- } u;
|
829
|
|
- struct efi_snp_device *snpdev = NULL;
|
830
|
|
- EFI_STATUS efirc;
|
|
750
|
+static struct efi_snp_device * efi_snp_demux ( struct net_device *netdev ) {
|
|
751
|
+ struct efi_snp_device *snpdev;
|
831
|
752
|
|
832
|
|
- if ( ( efirc = bs->OpenProtocol ( device,
|
833
|
|
- &efi_simple_network_protocol_guid,
|
834
|
|
- &u.interface,
|
835
|
|
- driver->DriverBindingHandle,
|
836
|
|
- device,
|
837
|
|
- EFI_OPEN_PROTOCOL_GET_PROTOCOL))!=0){
|
838
|
|
- DBGC ( driver, "SNPDRV %p device %p could not locate SNP: "
|
839
|
|
- "%s\n", driver, device, efi_strerror ( efirc ) );
|
840
|
|
- goto err_no_snp;
|
|
753
|
+ list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
|
|
754
|
+ if ( snpdev->netdev == netdev )
|
|
755
|
+ return snpdev;
|
841
|
756
|
}
|
842
|
|
-
|
843
|
|
- snpdev = container_of ( u.snp, struct efi_snp_device, snp );
|
844
|
|
- DBGCP ( driver, "SNPDRV %p device %p is SNPDEV %p\n",
|
845
|
|
- driver, device, snpdev );
|
846
|
|
-
|
847
|
|
- bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
|
848
|
|
- driver->DriverBindingHandle, device );
|
849
|
|
- err_no_snp:
|
850
|
|
- return snpdev;
|
|
757
|
+ return NULL;
|
851
|
758
|
}
|
852
|
759
|
|
853
|
760
|
/**
|
854
|
|
- * Check to see if driver supports a device
|
|
761
|
+ * Create SNP device
|
855
|
762
|
*
|
856
|
|
- * @v driver EFI driver
|
857
|
|
- * @v device EFI device
|
858
|
|
- * @v child Path to child device, if any
|
859
|
|
- * @ret efirc EFI status code
|
860
|
|
- */
|
861
|
|
-static EFI_STATUS EFIAPI
|
862
|
|
-efi_snp_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
863
|
|
- EFI_HANDLE device,
|
864
|
|
- EFI_DEVICE_PATH_PROTOCOL *child ) {
|
865
|
|
- struct net_device *netdev;
|
866
|
|
-
|
867
|
|
- DBGCP ( driver, "SNPDRV %p DRIVER_SUPPORTED %p (%p)\n",
|
868
|
|
- driver, device, child );
|
869
|
|
-
|
870
|
|
- netdev = efi_snp_netdev ( driver, device );
|
871
|
|
- return ( netdev ? 0 : EFI_UNSUPPORTED );
|
872
|
|
-}
|
873
|
|
-
|
874
|
|
-/**
|
875
|
|
- * Attach driver to device
|
876
|
|
- *
|
877
|
|
- * @v driver EFI driver
|
878
|
|
- * @v device EFI device
|
879
|
|
- * @v child Path to child device, if any
|
880
|
|
- * @ret efirc EFI status code
|
|
763
|
+ * @v netdev Network device
|
|
764
|
+ * @ret rc Return status code
|
881
|
765
|
*/
|
882
|
|
-static EFI_STATUS EFIAPI
|
883
|
|
-efi_snp_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
884
|
|
- EFI_HANDLE device,
|
885
|
|
- EFI_DEVICE_PATH_PROTOCOL *child ) {
|
|
766
|
+static int efi_snp_probe ( struct net_device *netdev ) {
|
886
|
767
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
887
|
|
- EFI_DEVICE_PATH_PROTOCOL *path;
|
888
|
|
- EFI_DEVICE_PATH_PROTOCOL *subpath;
|
889
|
|
- MAC_ADDR_DEVICE_PATH *macpath;
|
|
768
|
+ struct efi_pci_device *efipci;
|
890
|
769
|
struct efi_snp_device *snpdev;
|
891
|
|
- struct net_device *netdev;
|
892
|
|
- size_t subpath_len;
|
|
770
|
+ EFI_DEVICE_PATH_PROTOCOL *path_end;
|
|
771
|
+ MAC_ADDR_DEVICE_PATH *macpath;
|
893
|
772
|
size_t path_prefix_len = 0;
|
894
|
773
|
unsigned int i;
|
895
|
774
|
EFI_STATUS efirc;
|
|
775
|
+ int rc;
|
896
|
776
|
|
897
|
|
- DBGCP ( driver, "SNPDRV %p DRIVER_START %p (%p)\n",
|
898
|
|
- driver, device, child );
|
899
|
|
-
|
900
|
|
- /* Determine device path prefix length */
|
901
|
|
- if ( ( efirc = bs->OpenProtocol ( device,
|
902
|
|
- &efi_device_path_protocol_guid,
|
903
|
|
- ( void * ) &path,
|
904
|
|
- driver->DriverBindingHandle,
|
905
|
|
- device,
|
906
|
|
- EFI_OPEN_PROTOCOL_BY_DRIVER )) !=0 ){
|
907
|
|
- DBGCP ( driver, "SNPDRV %p device %p has no device path\n",
|
908
|
|
- driver, device );
|
909
|
|
- goto err_no_device_path;
|
910
|
|
- }
|
911
|
|
- subpath = path;
|
912
|
|
- while ( subpath->Type != END_DEVICE_PATH_TYPE ) {
|
913
|
|
- subpath_len = ( ( subpath->Length[1] << 8 ) |
|
914
|
|
- subpath->Length[0] );
|
915
|
|
- path_prefix_len += subpath_len;
|
916
|
|
- subpath = ( ( ( void * ) subpath ) + subpath_len );
|
|
777
|
+ /* Find EFI PCI device */
|
|
778
|
+ efipci = efipci_find ( netdev->dev );
|
|
779
|
+ if ( ! efipci ) {
|
|
780
|
+ DBG ( "SNP skipping non-PCI device %s\n", netdev->name );
|
|
781
|
+ rc = 0;
|
|
782
|
+ goto err_no_pci;
|
917
|
783
|
}
|
918
|
784
|
|
|
785
|
+ /* Calculate device path prefix length */
|
|
786
|
+ path_end = efi_devpath_end ( efipci->path );
|
|
787
|
+ path_prefix_len = ( ( ( void * ) path_end ) -
|
|
788
|
+ ( ( void * ) efipci->path ) );
|
|
789
|
+
|
919
|
790
|
/* Allocate the SNP device */
|
920
|
791
|
snpdev = zalloc ( sizeof ( *snpdev ) + path_prefix_len +
|
921
|
792
|
sizeof ( *macpath ) );
|
922
|
793
|
if ( ! snpdev ) {
|
923
|
|
- efirc = EFI_OUT_OF_RESOURCES;
|
|
794
|
+ rc = -ENOMEM;
|
924
|
795
|
goto err_alloc_snp;
|
925
|
796
|
}
|
926
|
|
-
|
927
|
|
- /* Identify the net device */
|
928
|
|
- netdev = efi_snp_netdev ( driver, device );
|
929
|
|
- if ( ! netdev ) {
|
930
|
|
- DBGC ( snpdev, "SNPDEV %p cannot find netdev for device %p\n",
|
931
|
|
- snpdev, device );
|
932
|
|
- efirc = EFI_UNSUPPORTED;
|
933
|
|
- goto err_no_netdev;
|
934
|
|
- }
|
935
|
797
|
snpdev->netdev = netdev_get ( netdev );
|
936
|
798
|
|
937
|
799
|
/* Sanity check */
|
|
@@ -939,7 +801,7 @@ efi_snp_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
939
|
801
|
DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
|
940
|
802
|
"length %d for %s\n", snpdev,
|
941
|
803
|
netdev->ll_protocol->ll_addr_len, netdev->name );
|
942
|
|
- efirc = EFI_INVALID_PARAMETER;
|
|
804
|
+ rc = -ENOTSUP;
|
943
|
805
|
goto err_ll_addr_len;
|
944
|
806
|
}
|
945
|
807
|
|
|
@@ -951,6 +813,7 @@ efi_snp_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
951
|
813
|
&snpdev->snp.WaitForPacket ) ) != 0 ){
|
952
|
814
|
DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
|
953
|
815
|
snpdev, efi_strerror ( efirc ) );
|
|
816
|
+ rc = EFIRC_TO_RC ( efirc );
|
954
|
817
|
goto err_create_event;
|
955
|
818
|
}
|
956
|
819
|
|
|
@@ -973,9 +836,9 @@ efi_snp_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
973
|
836
|
}
|
974
|
837
|
|
975
|
838
|
/* Populate the device path */
|
976
|
|
- memcpy ( &snpdev->path, path, path_prefix_len );
|
|
839
|
+ memcpy ( &snpdev->path, efipci->path, path_prefix_len );
|
977
|
840
|
macpath = ( ( ( void * ) &snpdev->path ) + path_prefix_len );
|
978
|
|
- subpath = ( ( void * ) ( macpath + 1 ) );
|
|
841
|
+ path_end = ( ( void * ) ( macpath + 1 ) );
|
979
|
842
|
memset ( macpath, 0, sizeof ( *macpath ) );
|
980
|
843
|
macpath->Header.Type = MESSAGING_DEVICE_PATH;
|
981
|
844
|
macpath->Header.SubType = MSG_MAC_ADDR_DP;
|
|
@@ -983,10 +846,10 @@ efi_snp_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
983
|
846
|
memcpy ( &macpath->MacAddress, netdev->ll_addr,
|
984
|
847
|
sizeof ( macpath->MacAddress ) );
|
985
|
848
|
macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
|
986
|
|
- memset ( subpath, 0, sizeof ( *subpath ) );
|
987
|
|
- subpath->Type = END_DEVICE_PATH_TYPE;
|
988
|
|
- subpath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
989
|
|
- subpath->Length[0] = sizeof ( *subpath );
|
|
849
|
+ memset ( path_end, 0, sizeof ( *path_end ) );
|
|
850
|
+ path_end->Type = END_DEVICE_PATH_TYPE;
|
|
851
|
+ path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
|
852
|
+ path_end->Length[0] = sizeof ( *path_end );
|
990
|
853
|
|
991
|
854
|
/* Install the SNP */
|
992
|
855
|
if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
|
|
@@ -998,9 +861,13 @@ efi_snp_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
998
|
861
|
NULL ) ) != 0 ) {
|
999
|
862
|
DBGC ( snpdev, "SNPDEV %p could not install protocols: "
|
1000
|
863
|
"%s\n", snpdev, efi_strerror ( efirc ) );
|
|
864
|
+ rc = EFIRC_TO_RC ( efirc );
|
1001
|
865
|
goto err_install_protocol_interface;
|
1002
|
866
|
}
|
1003
|
867
|
|
|
868
|
+ /* Add to list of SNP devices */
|
|
869
|
+ list_add ( &snpdev->list, &efi_snp_devices );
|
|
870
|
+
|
1004
|
871
|
DBGC ( snpdev, "SNPDEV %p installed for %s as device %p\n",
|
1005
|
872
|
snpdev, netdev->name, snpdev->handle );
|
1006
|
873
|
return 0;
|
|
@@ -1017,44 +884,39 @@ efi_snp_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
1017
|
884
|
err_create_event:
|
1018
|
885
|
err_ll_addr_len:
|
1019
|
886
|
netdev_put ( netdev );
|
1020
|
|
- err_no_netdev:
|
1021
|
887
|
free ( snpdev );
|
1022
|
888
|
err_alloc_snp:
|
1023
|
|
- bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
|
1024
|
|
- driver->DriverBindingHandle, device );
|
1025
|
|
- err_no_device_path:
|
1026
|
|
- return efirc;
|
|
889
|
+ err_no_pci:
|
|
890
|
+ return rc;
|
1027
|
891
|
}
|
1028
|
892
|
|
1029
|
893
|
/**
|
1030
|
|
- * Detach driver from device
|
|
894
|
+ * Handle SNP device or link state change
|
1031
|
895
|
*
|
1032
|
|
- * @v driver EFI driver
|
1033
|
|
- * @v device EFI device
|
1034
|
|
- * @v num_children Number of child devices
|
1035
|
|
- * @v children List of child devices
|
1036
|
|
- * @ret efirc EFI status code
|
|
896
|
+ * @v netdev Network device
|
1037
|
897
|
*/
|
1038
|
|
-static EFI_STATUS EFIAPI
|
1039
|
|
-efi_snp_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
1040
|
|
- EFI_HANDLE device,
|
1041
|
|
- UINTN num_children,
|
1042
|
|
- EFI_HANDLE *children ) {
|
|
898
|
+static void efi_snp_notify ( struct net_device *netdev __unused ) {
|
|
899
|
+ /* Nothing to do */
|
|
900
|
+}
|
|
901
|
+
|
|
902
|
+/**
|
|
903
|
+ * Destroy SNP device
|
|
904
|
+ *
|
|
905
|
+ * @v netdev Network device
|
|
906
|
+ */
|
|
907
|
+static void efi_snp_remove ( struct net_device *netdev ) {
|
1043
|
908
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
1044
|
909
|
struct efi_snp_device *snpdev;
|
1045
|
910
|
|
1046
|
|
- DBGCP ( driver, "SNPDRV %p DRIVER_STOP %p (%ld %p)\n",
|
1047
|
|
- driver, device, ( ( unsigned long ) num_children ), children );
|
1048
|
|
-
|
1049
|
911
|
/* Locate SNP device */
|
1050
|
|
- snpdev = efi_snp_snpdev ( driver, device );
|
|
912
|
+ snpdev = efi_snp_demux ( netdev );
|
1051
|
913
|
if ( ! snpdev ) {
|
1052
|
|
- DBGC ( driver, "SNPDRV %p device %p could not find SNPDEV\n",
|
1053
|
|
- driver, device );
|
1054
|
|
- return EFI_DEVICE_ERROR;
|
|
914
|
+ DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
|
|
915
|
+ return;
|
1055
|
916
|
}
|
1056
|
917
|
|
1057
|
918
|
/* Uninstall the SNP */
|
|
919
|
+ list_del ( &snpdev->list );
|
1058
|
920
|
bs->UninstallMultipleProtocolInterfaces (
|
1059
|
921
|
snpdev->handle,
|
1060
|
922
|
&efi_simple_network_protocol_guid, &snpdev->snp,
|
|
@@ -1065,87 +927,12 @@ efi_snp_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver,
|
1065
|
927
|
bs->CloseEvent ( snpdev->snp.WaitForPacket );
|
1066
|
928
|
netdev_put ( snpdev->netdev );
|
1067
|
929
|
free ( snpdev );
|
1068
|
|
- bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
|
1069
|
|
- driver->DriverBindingHandle, device );
|
1070
|
|
- return 0;
|
1071
|
930
|
}
|
1072
|
931
|
|
1073
|
|
-/** EFI SNP driver binding */
|
1074
|
|
-static EFI_DRIVER_BINDING_PROTOCOL efi_snp_binding = {
|
1075
|
|
- efi_snp_driver_supported,
|
1076
|
|
- efi_snp_driver_start,
|
1077
|
|
- efi_snp_driver_stop,
|
1078
|
|
- 0x10,
|
1079
|
|
- NULL,
|
1080
|
|
- NULL
|
|
932
|
+/** SNP driver */
|
|
933
|
+struct net_driver efi_snp_driver __net_driver = {
|
|
934
|
+ .name = "SNP",
|
|
935
|
+ .probe = efi_snp_probe,
|
|
936
|
+ .notify = efi_snp_notify,
|
|
937
|
+ .remove = efi_snp_remove,
|
1081
|
938
|
};
|
1082
|
|
-
|
1083
|
|
-/**
|
1084
|
|
- * Look up driver name
|
1085
|
|
- *
|
1086
|
|
- * @v wtf Component name protocol
|
1087
|
|
- * @v language Language to use
|
1088
|
|
- * @v driver_name Driver name to fill in
|
1089
|
|
- * @ret efirc EFI status code
|
1090
|
|
- */
|
1091
|
|
-static EFI_STATUS EFIAPI
|
1092
|
|
-efi_snp_get_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
|
1093
|
|
- CHAR8 *language __unused, CHAR16 **driver_name ) {
|
1094
|
|
-
|
1095
|
|
- *driver_name = L"" PRODUCT_SHORT_NAME " Driver";
|
1096
|
|
- return 0;
|
1097
|
|
-}
|
1098
|
|
-
|
1099
|
|
-/**
|
1100
|
|
- * Look up controller name
|
1101
|
|
- *
|
1102
|
|
- * @v wtf Component name protocol
|
1103
|
|
- * @v device Device
|
1104
|
|
- * @v child Child device, or NULL
|
1105
|
|
- * @v language Language to use
|
1106
|
|
- * @v driver_name Device name to fill in
|
1107
|
|
- * @ret efirc EFI status code
|
1108
|
|
- */
|
1109
|
|
-static EFI_STATUS EFIAPI
|
1110
|
|
-efi_snp_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *wtf __unused,
|
1111
|
|
- EFI_HANDLE device __unused,
|
1112
|
|
- EFI_HANDLE child __unused,
|
1113
|
|
- CHAR8 *language __unused,
|
1114
|
|
- CHAR16 **controller_name __unused ) {
|
1115
|
|
-
|
1116
|
|
- /* Just let EFI use the default Device Path Name */
|
1117
|
|
- return EFI_UNSUPPORTED;
|
1118
|
|
-}
|
1119
|
|
-
|
1120
|
|
-/** EFI SNP component name protocol */
|
1121
|
|
-static EFI_COMPONENT_NAME2_PROTOCOL efi_snp_name = {
|
1122
|
|
- efi_snp_get_driver_name,
|
1123
|
|
- efi_snp_get_controller_name,
|
1124
|
|
- "en"
|
1125
|
|
-};
|
1126
|
|
-
|
1127
|
|
-/**
|
1128
|
|
- * Install EFI SNP driver
|
1129
|
|
- *
|
1130
|
|
- * @ret rc Return status code
|
1131
|
|
- */
|
1132
|
|
-int efi_snp_install ( void ) {
|
1133
|
|
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
1134
|
|
- EFI_DRIVER_BINDING_PROTOCOL *driver = &efi_snp_binding;
|
1135
|
|
- EFI_STATUS efirc;
|
1136
|
|
-
|
1137
|
|
- driver->ImageHandle = efi_image_handle;
|
1138
|
|
- if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
|
1139
|
|
- &driver->DriverBindingHandle,
|
1140
|
|
- &efi_driver_binding_protocol_guid, driver,
|
1141
|
|
- &efi_component_name2_protocol_guid, &efi_snp_name,
|
1142
|
|
- NULL ) ) != 0 ) {
|
1143
|
|
- DBGC ( driver, "SNPDRV %p could not install protocols: "
|
1144
|
|
- "%s\n", driver, efi_strerror ( efirc ) );
|
1145
|
|
- return EFIRC_TO_RC ( efirc );
|
1146
|
|
- }
|
1147
|
|
-
|
1148
|
|
- DBGC ( driver, "SNPDRV %p driver binding installed as %p\n",
|
1149
|
|
- driver, driver->DriverBindingHandle );
|
1150
|
|
- return 0;
|
1151
|
|
-}
|