diff options
-rw-r--r-- | src/include/usr/autoboot.h | 4 | ||||
-rw-r--r-- | src/usr/autoboot.c | 43 |
2 files changed, 29 insertions, 18 deletions
diff --git a/src/include/usr/autoboot.h b/src/include/usr/autoboot.h index cfa4c41e..f562b2b1 100644 --- a/src/include/usr/autoboot.h +++ b/src/include/usr/autoboot.h @@ -10,6 +10,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/in.h> +#include <ipxe/device.h> struct net_device; struct uri; struct settings; @@ -25,12 +26,13 @@ enum uriboot_flags { URIBOOT_NO_SAN_BOOT | \ URIBOOT_NO_SAN_UNHOOK ) +extern struct device_description autoboot_device; + extern int uriboot ( struct uri *filename, struct uri *root_path, int drive, unsigned int flags ); extern struct uri * fetch_next_server_and_filename ( struct settings *settings ); extern int netboot ( struct net_device *netdev ); -extern int autoboot ( void ); extern void ipxe ( struct net_device *netdev ); extern int pxe_menu_boot ( struct net_device *netdev ); diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c index 3a5fb046..c9012f21 100644 --- a/src/usr/autoboot.c +++ b/src/usr/autoboot.c @@ -49,6 +49,9 @@ FILE_LICENCE ( GPL2_OR_LATER ); * */ +/** Device location of preferred autoboot device */ +struct device_description autoboot_device; + /* Disambiguate the various error causes */ #define ENOENT_BOOT __einfo_error ( EINFO_ENOENT_BOOT ) #define EINFO_ENOENT_BOOT \ @@ -74,15 +77,6 @@ __weak int pxe_menu_boot ( struct net_device *netdev __unused ) { } /** - * Identify the boot network device - * - * @ret netdev Boot network device - */ -static struct net_device * find_boot_netdev ( void ) { - return NULL; -} - -/** * Parse next-server and filename into a URI * * @v next_server Next-server address @@ -428,21 +422,36 @@ int netboot ( struct net_device *netdev ) { } /** + * Test if network device matches the autoboot device location + * + * @v netdev Network device + * @ret is_autoboot Network device matches the autoboot device location + */ +static int is_autoboot_device ( struct net_device *netdev ) { + + return ( ( netdev->dev->desc.bus_type == autoboot_device.bus_type ) && + ( netdev->dev->desc.location == autoboot_device.location ) ); +} + +/** * Boot the system */ -int autoboot ( void ) { - struct net_device *boot_netdev; +static int autoboot ( void ) { struct net_device *netdev; int rc = -ENODEV; - /* If we have an identifable boot device, try that first */ - if ( ( boot_netdev = find_boot_netdev() ) ) - rc = netboot ( boot_netdev ); - - /* If that fails, try booting from any of the other devices */ + /* Try booting from each network device. If we have a + * specified autoboot device location, then use only devices + * matching that location. + */ for_each_netdev ( netdev ) { - if ( netdev == boot_netdev ) + + /* Skip any non-matching devices, if applicable */ + if ( autoboot_device.bus_type && + ( ! is_autoboot_device ( netdev ) ) ) continue; + + /* Attempt booting from this device */ rc = netboot ( netdev ); } |