]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Include NII driver within "snp" and "snponly" build targets
authorMichael Brown <mcb30@ipxe.org>
Fri, 17 Oct 2014 15:36:00 +0000 (16:36 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 17 Oct 2014 15:52:31 +0000 (16:52 +0100)
End users almost certainly don't care whether the underlying interface
is SNP or NII/UNDI.  Try to minimise surprise and unnecessary
documentation by including the NII driver whenever the SNP driver is
requested.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/efi/nii.c
src/drivers/net/efi/nii.h [new file with mode: 0644]
src/drivers/net/efi/snp.c
src/drivers/net/efi/snponly.c

index 56b6340bf8ab89def647a84c4278df0aa6696478..d0d7da95affb0d2c6dfb9bd801f5104406524f56 100644 (file)
@@ -28,10 +28,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/umalloc.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/efi_snp.h>
 #include <ipxe/efi/efi_pci.h>
 #include <ipxe/efi/efi_utils.h>
+#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
 #include <ipxe/efi/IndustryStandard/Acpi10.h>
+#include "nii.h"
 
 /** @file
  *
@@ -955,45 +956,13 @@ static struct net_device_operations nii_operations = {
        .poll = nii_poll,
 };
 
-/**
- * Check to see if driver supports a device
- *
- * @v device           EFI device handle
- * @ret rc             Return status code
- */
-static int nii_supported ( EFI_HANDLE device ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_STATUS efirc;
-
-       /* Check that this is not a device we are providing ourselves */
-       if ( find_snpdev ( device ) != NULL ) {
-               DBGCP ( device, "NII %p %s is provided by this binary\n",
-                       device, efi_handle_name ( device ) );
-               return -ENOTTY;
-       }
-
-       /* Test for presence of NII protocol */
-       if ( ( efirc = bs->OpenProtocol ( device,
-                                         &efi_nii31_protocol_guid,
-                                         NULL, efi_image_handle, device,
-                                         EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
-               DBGCP ( device, "NII %p %s is not an NII device\n",
-                       device, efi_handle_name ( device ) );
-               return -EEFI ( efirc );
-       }
-       DBGC ( device, "NII %p %s is an NII device\n",
-              device, efi_handle_name ( device ) );
-
-       return 0;
-}
-
 /**
  * Attach driver to device
  *
  * @v efidev           EFI device
  * @ret rc             Return status code
  */
-static int nii_start ( struct efi_device *efidev ) {
+int nii_start ( struct efi_device *efidev ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        EFI_HANDLE device = efidev->device;
        struct net_device *netdev;
@@ -1106,7 +1075,7 @@ static int nii_start ( struct efi_device *efidev ) {
  *
  * @v efidev           EFI device
  */
-static void nii_stop ( struct efi_device *efidev ) {
+void nii_stop ( struct efi_device *efidev ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        struct net_device *netdev = efidev_get_drvdata ( efidev );
        struct nii_nic *nii = netdev->priv;
@@ -1130,11 +1099,3 @@ static void nii_stop ( struct efi_device *efidev ) {
        netdev_nullify ( netdev );
        netdev_put ( netdev );
 }
-
-/** EFI NII driver */
-struct efi_driver nii_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
-       .name = "NII",
-       .supported = nii_supported,
-       .start = nii_start,
-       .stop = nii_stop,
-};
diff --git a/src/drivers/net/efi/nii.h b/src/drivers/net/efi/nii.h
new file mode 100644 (file)
index 0000000..de0ac68
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _NII_H
+#define _NII_H
+
+/** @file
+ *
+ * NII driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+struct efi_device;
+
+extern int nii_start ( struct efi_device *efidev );
+extern void nii_stop ( struct efi_device *efidev );
+
+#endif /* _NII_H */
index a20bd21aff94f3cc6fe1d18866e67158d02e409a..2b5fc8618827c2964587c606c24b188046f554d5 100644 (file)
@@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/efi/efi_driver.h>
 #include <ipxe/efi/efi_snp.h>
 #include "snpnet.h"
+#include "nii.h"
 
 /** @file
  *
@@ -63,6 +64,38 @@ static int snp_supported ( EFI_HANDLE device ) {
        return 0;
 }
 
+/**
+ * Check to see if driver supports a device
+ *
+ * @v device           EFI device handle
+ * @ret rc             Return status code
+ */
+static int nii_supported ( EFI_HANDLE device ) {
+       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+       EFI_STATUS efirc;
+
+       /* Check that this is not a device we are providing ourselves */
+       if ( find_snpdev ( device ) != NULL ) {
+               DBGCP ( device, "NII %p %s is provided by this binary\n",
+                       device, efi_handle_name ( device ) );
+               return -ENOTTY;
+       }
+
+       /* Test for presence of NII protocol */
+       if ( ( efirc = bs->OpenProtocol ( device,
+                                         &efi_nii31_protocol_guid,
+                                         NULL, efi_image_handle, device,
+                                         EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
+               DBGCP ( device, "NII %p %s is not an NII device\n",
+                       device, efi_handle_name ( device ) );
+               return -EEFI ( efirc );
+       }
+       DBGC ( device, "NII %p %s is an NII device\n",
+              device, efi_handle_name ( device ) );
+
+       return 0;
+}
+
 /** EFI SNP driver */
 struct efi_driver snp_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
        .name = "SNP",
@@ -70,3 +103,11 @@ struct efi_driver snp_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
        .start = snpnet_start,
        .stop = snpnet_stop,
 };
+
+/** EFI NII driver */
+struct efi_driver nii_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
+       .name = "NII",
+       .supported = nii_supported,
+       .start = nii_start,
+       .stop = nii_stop,
+};
index d454ed20b89703023466d76a8e35fab3287cde7b..99f264bca422fe2b21cb12cd55fad0dd23ceef0e 100644 (file)
 
 FILE_LICENCE ( GPL2_OR_LATER );
 
+#include <string.h>
 #include <errno.h>
 #include <ipxe/init.h>
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/efi_driver.h>
+#include <ipxe/efi/efi_utils.h>
 #include <ipxe/efi/Protocol/SimpleNetwork.h>
+#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
 #include "snpnet.h"
+#include "nii.h"
 
 /** @file
  *
- * SNP chainloading-device-only driver
+ * EFI chainloaded-device-only driver
  *
  */
 
+/** A chainloaded protocol */
+struct chained_protocol {
+       /** Protocol GUID */
+       EFI_GUID *protocol;
+       /**
+        * Protocol instance installed on the loaded image's device handle
+        *
+        * We match against the protocol instance (rather than simply
+        * matching against the device handle itself) because some
+        * systems load us via a child of the underlying device, with
+        * a duplicate protocol installed on the child handle.
+        */
+       void *interface;
+};
+
+/** Chainloaded SNP protocol */
+static struct chained_protocol chained_snp = {
+       .protocol = &efi_simple_network_protocol_guid,
+};
+
+/** Chainloaded NII protocol */
+static struct chained_protocol chained_nii = {
+       .protocol = &efi_nii31_protocol_guid,
+};
+
 /**
- * SNP protocol instance installed on the loaded image's device handle
+ * Locate chainloaded protocol instance
  *
- * We match against the SNP protocol instance (rather than simply
- * matching against the device handle itself) because some systems
- * load us via a child of the SNP device, with a duplicate SNP
- * protocol installed on the child handle.
+ * @v chained          Chainloaded protocol
+ * @ret rc             Return status code
  */
-static EFI_SIMPLE_NETWORK_PROTOCOL *snponly;
+static int chained_locate ( struct chained_protocol *chained ) {
+       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+       EFI_HANDLE device = efi_loaded_image->DeviceHandle;
+       EFI_HANDLE parent;
+       EFI_STATUS efirc;
+       int rc;
+
+       /* Locate handle supporting this protocol */
+       if ( ( rc = efi_locate_device ( device, chained->protocol,
+                                       &parent ) ) != 0 ) {
+               DBGC ( device, "CHAINED %p %s does not support %s: %s\n",
+                      device, efi_handle_name ( device ),
+                      efi_guid_ntoa ( chained->protocol ), strerror ( rc ) );
+               goto err_locate_device;
+       }
+       DBGC ( device, "CHAINED %p %s found %s on ", device,
+              efi_handle_name ( device ), efi_guid_ntoa ( chained->protocol ));
+       DBGC ( device, "%p %s\n", parent, efi_handle_name ( parent ) );
+
+       /* Get protocol instance */
+       if ( ( efirc = bs->OpenProtocol ( parent, chained->protocol,
+                                         &chained->interface, efi_image_handle,
+                                         device,
+                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
+               rc = -EEFI ( efirc );
+               DBGC ( device, "CHAINED %p %s could not open %s on ",
+                      device, efi_handle_name ( device ),
+                      efi_guid_ntoa ( chained->protocol ) );
+               DBGC ( device, "%p %s: %s\n",
+                      parent, efi_handle_name ( parent ), strerror ( rc ) );
+               goto err_open_protocol;
+       }
+
+ err_locate_device:
+       bs->CloseProtocol ( parent, chained->protocol, efi_image_handle,
+                           device );
+ err_open_protocol:
+       return rc;
+}
 
 /**
  * Check to see if driver supports a device
  *
  * @v device           EFI device handle
+ * @v chained          Chainloaded protocol
  * @ret rc             Return status code
  */
-static int snponly_supported ( EFI_HANDLE device ) {
+static int chained_supported ( EFI_HANDLE device,
+                              struct chained_protocol *chained ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        EFI_STATUS efirc;
-       union {
-               EFI_SIMPLE_NETWORK_PROTOCOL *snp;
-               void *interface;
-       } snp;
+       void *interface;
        int rc;
 
-       /* Get SNP protocol */
-       if ( ( efirc = bs->OpenProtocol ( device,
-                                         &efi_simple_network_protocol_guid,
-                                         &snp.interface, efi_image_handle,
-                                         device,
+       /* Get protocol */
+       if ( ( efirc = bs->OpenProtocol ( device, chained->protocol, &interface,
+                                         efi_image_handle, device,
                                          EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
                rc = -EEFI ( efirc );
-               DBGCP ( device, "SNPONLY %p %s is not an SNP device\n",
-                       device, efi_handle_name ( device ) );
-               goto err_not_snp;
+               DBGCP ( device, "CHAINED %p %s is not a %s device\n",
+                       device, efi_handle_name ( device ),
+                       efi_guid_ntoa ( chained->protocol ) );
+               goto err_open_protocol;
        }
 
        /* Test for a match against the chainloading device */
-       if ( snp.snp != snponly ) {
-               DBGC ( device, "SNPONLY %p %s SNP %p is not the "
-                      "chainloading SNP\n", device,
-                      efi_handle_name ( device ), snp.snp );
+       if ( interface != chained->interface ) {
+               DBGC ( device, "CHAINED %p %s %p is not the chainloaded "
+                      "%s\n", device, efi_handle_name ( device ),
+                      interface, efi_guid_ntoa ( chained->protocol ) );
                rc = -ENOTTY;
-               goto err_not_snponly;
+               goto err_no_match;
        }
 
        /* Success */
        rc = 0;
-       DBGC ( device, "SNPONLY %p %s SNP %p is the chainloading SNP\n",
-              device, efi_handle_name ( device ), snp.snp );
+       DBGC ( device, "CHAINED %p %s %p is the chainloaded %s\n",
+              device, efi_handle_name ( device ), interface,
+              efi_guid_ntoa ( chained->protocol ) );
 
- err_not_snponly:
-       bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
-                           efi_image_handle, device );
- err_not_snp:
+ err_no_match:
+       bs->CloseProtocol ( device, chained->protocol, efi_image_handle,
+                           device );
+ err_open_protocol:
        return rc;
 }
 
-/** EFI chainloading-device-only driver */
+/**
+ * Check to see if driver supports a device
+ *
+ * @v device           EFI device handle
+ * @ret rc             Return status code
+ */
+static int snponly_supported ( EFI_HANDLE device ) {
+
+       return chained_supported ( device, &chained_snp );
+}
+
+/**
+ * Check to see if driver supports a device
+ *
+ * @v device           EFI device handle
+ * @ret rc             Return status code
+ */
+static int niionly_supported ( EFI_HANDLE device ) {
+
+       return chained_supported ( device, &chained_nii );
+}
+
+/** EFI SNP chainloading-device-only driver */
 struct efi_driver snponly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
        .name = "SNPONLY",
        .supported = snponly_supported,
@@ -98,41 +184,25 @@ struct efi_driver snponly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
        .stop = snpnet_stop,
 };
 
+/** EFI NII chainloading-device-only driver */
+struct efi_driver niionly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
+       .name = "NIIONLY",
+       .supported = niionly_supported,
+       .start = nii_start,
+       .stop = nii_stop,
+};
+
 /**
- * Initialise EFI chainloading-device-only driver
+ * Initialise EFI chainloaded-device-only driver
  *
  */
-static void snponly_init ( void ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-       EFI_HANDLE device = efi_loaded_image->DeviceHandle;
-       union {
-               EFI_SIMPLE_NETWORK_PROTOCOL *snp;
-               void *interface;
-       } snp;
-       EFI_STATUS efirc;
+static void chained_init ( void ) {
 
-       /* Look for SNP protocol on the loaded image's device handle */
-       if ( ( efirc = bs->OpenProtocol ( device,
-                                         &efi_simple_network_protocol_guid,
-                                         &snp.interface, efi_image_handle,
-                                         device,
-                                         EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
-               DBGC ( device, "SNPONLY %p %s is not an SNP device\n",
-                      device, efi_handle_name ( device ) );
-               goto err_open_protocol;
-       }
-
-       /* Record SNP protocol instance */
-       snponly = snp.snp;
-       DBGC ( device, "SNPONLY %p %s found chainloading SNP %p\n",
-              device, efi_handle_name ( device ), snponly );
-
- err_open_protocol:
-       bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
-                           efi_image_handle, device );
+       chained_locate ( &chained_snp );
+       chained_locate ( &chained_nii );
 }
 
-/** EFI chainloading-device-only initialisation function */
-struct init_fn snponly_init_fn __init_fn ( INIT_LATE ) = {
-       .initialise = snponly_init,
+/** EFI chainloaded-device-only initialisation function */
+struct init_fn chained_init_fn __init_fn ( INIT_LATE ) = {
+       .initialise = chained_init,
 };