Browse Source

[autoboot] Allow autoboot device to be identified by link-layer address

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
00c745e5ff
3 changed files with 65 additions and 15 deletions
  1. 2
    4
      src/arch/i386/core/pci_autoboot.c
  2. 4
    2
      src/include/usr/autoboot.h
  3. 59
    9
      src/usr/autoboot.c

+ 2
- 4
src/arch/i386/core/pci_autoboot.c View File

34
  */
34
  */
35
 static void pci_autoboot_init ( void ) {
35
 static void pci_autoboot_init ( void ) {
36
 
36
 
37
-	if ( autoboot_busdevfn ) {
38
-		autoboot_device.bus_type = BUS_TYPE_PCI;
39
-		autoboot_device.location = autoboot_busdevfn;
40
-	}
37
+	if ( autoboot_busdevfn )
38
+		set_autoboot_busloc ( BUS_TYPE_PCI, autoboot_busdevfn );
41
 }
39
 }
42
 
40
 
43
 /** PCI autoboot device initialisation function */
41
 /** PCI autoboot device initialisation function */

+ 4
- 2
src/include/usr/autoboot.h View File

9
 
9
 
10
 FILE_LICENCE ( GPL2_OR_LATER );
10
 FILE_LICENCE ( GPL2_OR_LATER );
11
 
11
 
12
-#include <ipxe/in.h>
13
 #include <ipxe/device.h>
12
 #include <ipxe/device.h>
13
+
14
 struct net_device;
14
 struct net_device;
15
 struct uri;
15
 struct uri;
16
 struct settings;
16
 struct settings;
26
 			 URIBOOT_NO_SAN_BOOT |	   \
26
 			 URIBOOT_NO_SAN_BOOT |	   \
27
 			 URIBOOT_NO_SAN_UNHOOK )
27
 			 URIBOOT_NO_SAN_UNHOOK )
28
 
28
 
29
-extern struct device_description autoboot_device;
29
+extern void set_autoboot_busloc ( unsigned int bus_type,
30
+				  unsigned int location );
31
+extern void set_autoboot_ll_addr ( const void *ll_addr, size_t len );
30
 
32
 
31
 extern int uriboot ( struct uri *filename, struct uri *root_path, int drive,
33
 extern int uriboot ( struct uri *filename, struct uri *root_path, int drive,
32
 		     unsigned int flags );
34
 		     unsigned int flags );

+ 59
- 9
src/usr/autoboot.c View File

49
  *
49
  *
50
  */
50
  */
51
 
51
 
52
-/** Device location of preferred autoboot device */
53
-struct device_description autoboot_device;
52
+/** Link-layer address of preferred autoboot device, if known */
53
+static uint8_t autoboot_ll_addr[MAX_LL_ADDR_LEN];
54
+
55
+/** Device location of preferred autoboot device, if known */
56
+static struct device_description autoboot_desc;
57
+
58
+/** Autoboot device tester */
59
+static int ( * is_autoboot_device ) ( struct net_device *netdev );
54
 
60
 
55
 /* Disambiguate the various error causes */
61
 /* Disambiguate the various error causes */
56
 #define ENOENT_BOOT __einfo_error ( EINFO_ENOENT_BOOT )
62
 #define ENOENT_BOOT __einfo_error ( EINFO_ENOENT_BOOT )
422
 }
428
 }
423
 
429
 
424
 /**
430
 /**
425
- * Test if network device matches the autoboot device location
431
+ * Test if network device matches the autoboot device bus type and location
426
  *
432
  *
427
  * @v netdev		Network device
433
  * @v netdev		Network device
428
- * @ret is_autoboot	Network device matches the autoboot device location
434
+ * @ret is_autoboot	Network device matches the autoboot device
435
+ */
436
+static int is_autoboot_busloc ( struct net_device *netdev ) {
437
+
438
+	return ( ( netdev->dev->desc.bus_type == autoboot_desc.bus_type ) &&
439
+		 ( netdev->dev->desc.location == autoboot_desc.location ) );
440
+}
441
+
442
+/**
443
+ * Identify autoboot device by bus type and location
444
+ *
445
+ * @v bus_type		Bus type
446
+ * @v location		Location
429
  */
447
  */
430
-static int is_autoboot_device ( struct net_device *netdev ) {
448
+void set_autoboot_busloc ( unsigned int bus_type, unsigned int location ) {
449
+
450
+	/* Record autoboot device description */
451
+	autoboot_desc.bus_type = bus_type;
452
+	autoboot_desc.location = location;
453
+
454
+	/* Mark autoboot device as present */
455
+	is_autoboot_device = is_autoboot_busloc;
456
+}
457
+
458
+/**
459
+ * Test if network device matches the autoboot device link-layer address
460
+ *
461
+ * @v netdev		Network device
462
+ * @ret is_autoboot	Network device matches the autoboot device
463
+ */
464
+static int is_autoboot_ll_addr ( struct net_device *netdev ) {
465
+
466
+	return ( memcmp ( netdev->ll_addr, autoboot_ll_addr,
467
+			  netdev->ll_protocol->ll_addr_len ) == 0 );
468
+}
469
+
470
+/**
471
+ * Identify autoboot device by link-layer address
472
+ *
473
+ * @v ll_addr		Link-layer address
474
+ * @v len		Length of link-layer address
475
+ */
476
+void set_autoboot_ll_addr ( const void *ll_addr, size_t len ) {
477
+
478
+	/* Record autoboot link-layer address (truncated if necessary) */
479
+	if ( len > sizeof ( autoboot_ll_addr ) )
480
+		len = sizeof ( autoboot_ll_addr );
481
+	memcpy ( autoboot_ll_addr, ll_addr, len );
431
 
482
 
432
-	return ( ( netdev->dev->desc.bus_type == autoboot_device.bus_type ) &&
433
-		 ( netdev->dev->desc.location == autoboot_device.location ) );
483
+	/* Mark autoboot device as present */
484
+	is_autoboot_device = is_autoboot_ll_addr;
434
 }
485
 }
435
 
486
 
436
 /**
487
 /**
447
 	for_each_netdev ( netdev ) {
498
 	for_each_netdev ( netdev ) {
448
 
499
 
449
 		/* Skip any non-matching devices, if applicable */
500
 		/* Skip any non-matching devices, if applicable */
450
-		if ( autoboot_device.bus_type &&
451
-		     ( ! is_autoboot_device ( netdev ) ) )
501
+		if ( is_autoboot_device && ( ! is_autoboot_device ( netdev ) ) )
452
 			continue;
502
 			continue;
453
 
503
 
454
 		/* Attempt booting from this device */
504
 		/* Attempt booting from this device */

Loading…
Cancel
Save