Module Name: src Committed By: thorpej Date: Fri Jul 9 01:29:21 UTC 2021
Modified Files: src/sys/arch/alpha/alpha: autoconf.c Log Message: If we're netbooting on a system with, for example, an ISA DE204 Ethernet interface, we don't have sufficient information to find the device using the bus/slot scheme that we do with a PCI network interface. However, in these cases, some versions of the SRM console supply the MAC address of the interface in the booted_dev environment variable, like so: BOOTP 1 1 0 0 0 5 0 08-00-2B-xx-xx-xx 1 So, if we weren't able to find the booted device by the usual means, check for this and, if we find a MAC address, try to find the network interface by the MAC address. To generate a diff of this commit: cvs rdiff -u -r1.57 -r1.58 src/sys/arch/alpha/alpha/autoconf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/alpha/alpha/autoconf.c diff -u src/sys/arch/alpha/alpha/autoconf.c:1.57 src/sys/arch/alpha/alpha/autoconf.c:1.58 --- src/sys/arch/alpha/alpha/autoconf.c:1.57 Sat May 22 15:05:36 2021 +++ src/sys/arch/alpha/alpha/autoconf.c Fri Jul 9 01:29:20 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: autoconf.c,v 1.57 2021/05/22 15:05:36 thorpej Exp $ */ +/* $NetBSD: autoconf.c,v 1.58 2021/07/09 01:29:20 thorpej Exp $ */ /* * Copyright (c) 1992, 1993 @@ -42,7 +42,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.57 2021/05/22 15:05:36 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.58 2021/07/09 01:29:20 thorpej Exp $"); #include "pci.h" @@ -57,6 +57,9 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v #include <dev/pci/pcivar.h> +#include <net/if.h> +#include <net/if_ether.h> + #include <machine/autoconf.h> #include <machine/alpha.h> #include <machine/cpu.h> @@ -66,8 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v struct bootdev_data *bootdev_data; -void parse_prom_bootdev(void); -static inline int atoi(const char *); +static void parse_prom_bootdev(void); /* * cpu_configure: @@ -138,6 +140,86 @@ qemu_find_rootdev(void) booted_device = device_find_by_xname(cp); } +static bool +parse_dec_macaddr(const char *str, uint8_t enaddr[ETHER_ADDR_LEN]) +{ + char *cp; + long long l; + int i; + + /* + * DEC Ethernet address strings are formatted like so: + * + * XX-XX-XX-XX-XX-XX + */ + + for (i = 0; i < ETHER_ADDR_LEN; i++) { + l = strtoll(str, &cp, 16); + if (l < 0 || l > 0xff) { + /* Not a valid MAC address. */ + return false; + } + if (*cp == '-') { + /* Octet separator. */ + enaddr[i] = (uint8_t)l; + str = cp + 1; + continue; + } + if (*cp == ' ' || *cp == '\0') { + /* End of the string. */ + enaddr[i] = (uint8_t)l; + return i == ETHER_ADDR_LEN - 1; + } + /* Bogus character. */ + break; + } + + /* Encountered bogus character or didn't reach end of string. */ + return false; +} + +static void +netboot_find_rootdev_planb(void) +{ + struct psref psref; + uint8_t enaddr[ETHER_ADDR_LEN]; + char ifname[IFNAMSIZ]; + int i; + + if (strncasecmp(bootinfo.booted_dev, "BOOTP ", 6) != 0 && + strncasecmp(bootinfo.booted_dev, "MOP ", 4) != 0) { + /* We weren't netbooted. */ + return; + } + + for (i = 2; bootinfo.booted_dev[i] != '\0'; i++) { + if (bootinfo.booted_dev[i] == '-') { + if (parse_dec_macaddr(&bootinfo.booted_dev[i - 2], + enaddr)) { + /* Found it! */ + break; + } + } + } + if (bootinfo.booted_dev[i] == '\0') { + /* No MAC address in string. */ + return; + } + + /* Now try to look up the interface by the link address. */ + struct ifnet *ifp = if_get_bylla(enaddr, ETHER_ADDR_LEN, &psref); + if (ifp == NULL) { + /* No interface attached with that MAC address. */ + return; + } + + strlcpy(ifname, if_name(ifp), sizeof(ifname)); + if_put(ifp, &psref); + + /* Ok! Now look up the device_t by name! */ + booted_device = device_find_by_xname(ifname); +} + void cpu_rootconf(void) { @@ -147,13 +229,33 @@ cpu_rootconf(void) } if (booted_device == NULL) { + /* + * It's possible that we netbooted from an Ethernet + * interface that can't be matched via the usual + * logic in device_register() (a DE204 in an ISA slot, + * for example). In these cases, the console may have + * provided us with a MAC address that we can use to + * try and find the interface, * e.g.: + * + * BOOTP 1 1 0 0 0 5 0 08-00-2B-xx-xx-xx 1 + */ + netboot_find_rootdev_planb(); + } + + if (booted_device == NULL) { printf("WARNING: can't figure what device matches \"%s\"\n", bootinfo.booted_dev); } rootconf(); } -void +static inline int +atoi(const char *s) +{ + return (int)strtoll(s, NULL, 10); +} + +static void parse_prom_bootdev(void) { static char hacked_boot_dev[128]; @@ -213,12 +315,6 @@ parse_prom_bootdev(void) bootdev_data = &bd; } -static inline int -atoi(const char *s) -{ - return (int)strtoll(s, NULL, 10); -} - void device_register(device_t dev, void *aux) {