Page MenuHomeFreeBSD

D5680.1790810668.diff
No OneTemporary

Size
41 KB
Referenced Files
None
Subscribers
None

D5680.1790810668.diff

Index: sys/boot/Makefile.arm
===================================================================
--- sys/boot/Makefile.arm
+++ sys/boot/Makefile.arm
@@ -4,4 +4,8 @@
SUBDIR+= fdt
.endif
+.if ${MK_ZFS} != "no"
+SUBDIR+= zfs
+.endif
+
SUBDIR+= efi uboot
Index: sys/boot/arm/uboot/Makefile
===================================================================
--- sys/boot/arm/uboot/Makefile
+++ sys/boot/arm/uboot/Makefile
@@ -38,6 +38,11 @@
.else
LOADER_FDT_SUPPORT= no
.endif
+.if ${MK_ZFS} != "no"
+LOADER_ZFS_SUPPORT= yes
+.else
+LOADER_ZFS_SUPPORT= no
+.endif
.if ${LOADER_DISK_SUPPORT} == "yes"
CFLAGS+= -DLOADER_DISK_SUPPORT
@@ -77,6 +82,14 @@
LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
.endif
+.if ${LOADER_ZFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_ZFS_SUPPORT
+LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a
+
+CFLAGS+= -I${.CURDIR}/../../zfs
+CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs
+.endif
+
CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE
.if ${MK_FORTH} != "no"
@@ -114,8 +127,8 @@
# clang doesn't understand %D as a specifier to printf
NO_WERROR.clang=
-DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND}
-LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} -lstand
+DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBZFSBOOT} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBZFSBOOT} -lstand
OBJS+= ${SRCS:N*.h:R:S/$/.o/g}
Index: sys/boot/arm/uboot/conf.c
===================================================================
--- sys/boot/arm/uboot/conf.c
+++ sys/boot/arm/uboot/conf.c
@@ -31,6 +31,9 @@
#include <stand.h>
#include "bootstrap.h"
#include "libuboot.h"
+#if defined(LOADER_ZFS_SUPPORT)
+#include <libzfs.h>
+#endif
#if defined(LOADER_NET_SUPPORT)
#include "dev_net.h"
@@ -43,10 +46,16 @@
#if defined(LOADER_NET_SUPPORT)
&netdev,
#endif
+#if defined(LOADER_ZFS_SUPPORT)
+ &zfs_dev,
+#endif
NULL
};
struct fs_ops *file_system[] = {
+#if defined(LOADER_ZFS_SUPPORT)
+ &zfs_fsops,
+#endif
#if defined(LOADER_UFS_SUPPORT)
&ufs_fsops,
#endif
Index: sys/boot/arm/uboot/version
===================================================================
--- sys/boot/arm/uboot/version
+++ sys/boot/arm/uboot/version
@@ -3,6 +3,7 @@
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
+1.3: ZFS support added
1.2: Extended with NAND FS support.
1.1: Flattened Device Tree blob support.
1.0: Added storage support. Booting from HDD, USB, etc. is now possible.
Index: sys/boot/uboot/common/main.c
===================================================================
--- sys/boot/uboot/common/main.c
+++ sys/boot/uboot/common/main.c
@@ -2,6 +2,7 @@
* Copyright (c) 2000 Benno Rice <benno@jeamland.net>
* Copyright (c) 2000 Stephane Potvin <sepotvin@videotron.ca>
* Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * Copyright (c) 2016 Vladimir Belian <fate10@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,30 +38,39 @@
#include "glue.h"
#include "libuboot.h"
+#ifdef LOADER_ZFS_SUPPORT
+#include <libzfs.h>
+#endif
+
#ifndef nitems
#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
#endif
-struct uboot_devdesc currdev;
+#ifdef DEBUG
+#define PRINT_DEBUG_INFO() do { \
+ printf("signature:\n"); \
+ printf(" version\t= %d\n", sig->version); \
+ printf(" checksum\t= 0x%08x\n", sig->checksum); \
+ printf(" sc entry\t= 0x%08x\n", sig->syscall); \
+ printf("\naddresses info:\n"); \
+ printf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext); \
+ printf(" _edata = 0x%08x\n", (uint32_t)_edata); \
+ printf(" __sbss_start = 0x%08x\n", (uint32_t)__sbss_start); \
+ printf(" __sbss_end = 0x%08x\n", (uint32_t)__sbss_end); \
+ printf(" __bss_start = 0x%08x\n", (uint32_t)__bss_start); \
+ printf(" _end = 0x%08x\n", (uint32_t)_end); \
+ printf(" syscall entry = 0x%08x\n", (uint32_t)syscall_ptr); \
+ printf(" uboot_heap_start = 0x%08x\n", (uint32_t)uboot_heap_start); \
+ printf(" uboot_heap_end = 0x%08x\n", (uint32_t)uboot_heap_end); } while (0)
+#else
+#define PRINT_DEBUG_INFO()
+#endif
+
struct arch_switch archsw; /* MI/MD interface boundary */
-int devs_no;
uintptr_t uboot_heap_start;
uintptr_t uboot_heap_end;
-struct device_type {
- const char *name;
- int type;
-} device_types[] = {
- { "disk", DEV_TYP_STOR },
- { "ide", DEV_TYP_STOR | DT_STOR_IDE },
- { "mmc", DEV_TYP_STOR | DT_STOR_MMC },
- { "sata", DEV_TYP_STOR | DT_STOR_SATA },
- { "scsi", DEV_TYP_STOR | DT_STOR_SCSI },
- { "usb", DEV_TYP_STOR | DT_STOR_USB },
- { "net", DEV_TYP_NET }
-};
-
extern char end[];
extern char bootprog_name[];
extern char bootprog_rev[];
@@ -78,31 +88,71 @@
extern int command_fdt_internal(int argc, char *argv[]);
#endif
+#ifdef LOADER_ZFS_SUPPORT
+static uint64_t zfs_pools[UB_MAX_DEV];
+
static void
-dump_sig(struct api_signature *sig)
+uboot_zfs_probe(void)
{
-#ifdef DEBUG
- printf("signature:\n");
- printf(" version\t= %d\n", sig->version);
- printf(" checksum\t= 0x%08x\n", sig->checksum);
- printf(" sc entry\t= 0x%08x\n", sig->syscall);
-#endif
+ char dname[SPECNAMELEN + 1];
+ uint64_t id;
+ int p, n = 0, i = 0, maxp = 0;
+
+ bzero(&zfs_pools, sizeof(zfs_pools));
+
+ while (ub_dev_get(DEV_TYP_STOR, &i) != NULL) {
+ snprintf(dname, sizeof(dname), "disk%d:", n++);
+ id = 0;
+ if (zfs_probe_dev(dname, &id) == 0) {
+ if (id == 0)
+ continue;
+
+ /* skip pool guid duplicates if found */
+ for (p = 0; (p < maxp) && (zfs_pools[p] != id); p++) ;
+ if (p < maxp)
+ continue;
+
+ zfs_pools[maxp++] = id;
+ }
+ }
}
-static void
-dump_addr_info(void)
+static const char *
+probe_zfs(const char *dstr)
{
-#ifdef DEBUG
- printf("\naddresses info:\n");
- printf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext);
- printf(" _edata = 0x%08x\n", (uint32_t)_edata);
- printf(" __sbss_start = 0x%08x\n", (uint32_t)__sbss_start);
- printf(" __sbss_end = 0x%08x\n", (uint32_t)__sbss_end);
- printf(" __sbss_start = 0x%08x\n", (uint32_t)__bss_start);
- printf(" _end = 0x%08x\n", (uint32_t)_end);
- printf(" syscall entry = 0x%08x\n", (uint32_t)syscall_ptr);
-#endif
+ struct zfs_devdesc dev;
+ char *p = NULL, *buf;
+ int i, l;
+
+ if ((dstr != NULL) && (strncasecmp(dstr, "zfs", 3) != 0))
+ return (NULL);
+
+ if ((dstr != NULL) && ((dstr = strchr(dstr, ' ')) != NULL))
+ dstr++;
+
+ for (i = 0; zfs_pools[i] != 0; i++) {
+ bzero(&dev, sizeof(dev));
+ dev.d_dev = &zfs_dev;
+ dev.d_type = dev.d_dev->dv_type;
+ dev.pool_guid = zfs_pools[i];
+ buf = zfs_fmtdev(&dev);
+
+ p = strchr(buf, ':') + 1;
+ l = strcspn(p, ":/");
+ if ((buf != NULL) && ((dstr == NULL) || (*dstr == '\0') ||
+ ((l == strlen(dstr)) && (strncmp(dstr, p, l) == 0))))
+ break;
+ buf = NULL;
+ }
+ if (buf != NULL) {
+ init_zfs_bootenv(buf);
+ return (zfs_fmtdev(&dev));
+ }
+ printf("could not find %s zfs pool\n",
+ (((dstr == NULL) || (*dstr == '\0'))) ? "any" : dstr);
+ return (NULL);
}
+#endif
static uint64_t
memsize(struct sys_info *si, int flags)
@@ -133,266 +183,204 @@
size = memsize(si, t[i]);
if (size > 0)
printf("%s: %juMB\n", ub_mem_type(t[i]),
- (uintmax_t)(size / 1024 / 1024));
+ (uintmax_t)(size / 1024 / 1024));
}
}
-static const char *
-get_device_type(const char *devstr, int *devtype)
+static struct devsw *
+search_devsw(int type)
{
int i;
- int namelen;
- struct device_type *dt;
-
- if (devstr) {
- for (i = 0; i < nitems(device_types); i++) {
- dt = &device_types[i];
- namelen = strlen(dt->name);
- if (strncmp(dt->name, devstr, namelen) == 0) {
- *devtype = dt->type;
- return (devstr + namelen);
- }
- }
- printf("Unknown device type '%s'\n", devstr);
- }
- *devtype = -1;
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_type == type)
+ return (devsw[i]);
return (NULL);
}
-static const char *
-device_typename(int type)
-{
- int i;
-
- for (i = 0; i < nitems(device_types); i++)
- if (device_types[i].type == type)
- return (device_types[i].name);
-
- return ("<unknown>");
-}
-
/*
- * Parse a device string into type, unit, slice and partition numbers. A
- * returned value of -1 for type indicates a search should be done for the
- * first loadable device, otherwise a returned value of -1 for unit
- * indicates a search should be done for the first loadable device of the
- * given type.
+ * Parse a device string into unit, slice and partition numbers.
*
* The returned values for slice and partition are interpreted by
* disk_open().
*
- * Valid device strings: For device types:
+ * Valid device strings:
*
- * <type_name> DEV_TYP_STOR, DEV_TYP_NET
- * <type_name><unit> DEV_TYP_STOR, DEV_TYP_NET
- * <type_name><unit>: DEV_TYP_STOR, DEV_TYP_NET
- * <type_name><unit>:<slice> DEV_TYP_STOR
- * <type_name><unit>:<slice>. DEV_TYP_STOR
- * <type_name><unit>:<slice>.<partition> DEV_TYP_STOR
- *
- * For valid type names, see the device_types array, above.
+ * <unit>
+ * <unit>:
+ * <unit>:<slice>
+ * <unit>:<slice>.
+ * <unit>:<slice>.<partition>
*
* Slice numbers are 1-based. 0 is a wildcard.
*/
-static void
-get_load_device(int *type, int *unit, int *slice, int *partition)
+static int
+decode_devstr(const char *dstr, int *unit, int *slice, int *partition)
{
- char *devstr;
const char *p;
char *endp;
- *type = -1;
- *unit = -1;
- *slice = 0;
- *partition = -1;
-
- devstr = ub_env_get("loaderdev");
- if (devstr == NULL) {
- printf("U-Boot env: loaderdev not set, will probe all devices.\n");
- return;
- }
- printf("U-Boot env: loaderdev='%s'\n", devstr);
-
- p = get_device_type(devstr, type);
-
/* Ignore optional spaces after the device name. */
- while (*p == ' ')
- p++;
+ while (*dstr == ' ')
+ dstr++;
- /* Unknown device name, or a known name without unit number. */
- if ((*type == -1) || (*p == '\0')) {
- return;
+ /* No unit number present. */
+ if (*dstr == '\0') {
+ return (-1);
}
-
/* Malformed unit number. */
- if (!isdigit(*p)) {
- *type = -1;
- return;
- }
+ if (!isdigit(*dstr))
+ return (0);
- /* Guaranteed to extract a number from the string, as *p is a digit. */
- *unit = strtol(p, &endp, 10);
- p = endp;
+ /* Guaranteed to extract a number from the string, as *dstr is a digit. */
+ *unit = strtol(dstr, &endp, 10);
+ dstr = endp;
- /* Known device name with unit number and nothing else. */
- if (*p == '\0') {
- return;
- }
+ /* Unit number and nothing else. */
+ if (*dstr == '\0')
+ return (1);
/* Device string is malformed beyond unit number. */
- if (*p != ':') {
- *type = -1;
- *unit = -1;
- return;
- }
-
- p++;
+ if (*dstr != ':')
+ return (0);
+ dstr++;
/* No slice and partition specification. */
- if ('\0' == *p )
- return;
+ if (*dstr == '\0')
+ return (1);
- /* Only DEV_TYP_STOR devices can have a slice specification. */
- if (!(*type & DEV_TYP_STOR)) {
- *type = -1;
- *unit = -1;
- return;
- }
-
- *slice = strtoul(p, &endp, 10);
+ *slice = strtoul(dstr, &endp, 10);
/* Malformed slice number. */
- if (p == endp) {
- *type = -1;
- *unit = -1;
- *slice = 0;
- return;
- }
-
- p = endp;
+ if (dstr == endp)
+ return (0);
+ dstr = endp;
/* No partition specification. */
- if (*p == '\0')
- return;
+ if (*dstr == '\0')
+ return (1);
/* Device string is malformed beyond slice number. */
- if (*p != '.') {
- *type = -1;
- *unit = -1;
- *slice = 0;
- return;
- }
-
- p++;
+ if (*dstr != '.')
+ return (0);
+ dstr++;
/* No partition specification. */
- if (*p == '\0')
- return;
+ if (*dstr == '\0')
+ return (1);
- *partition = strtol(p, &endp, 10);
- p = endp;
+ *partition = strtol(dstr, &endp, 10);
- /* Full, valid device string. */
+ /* Full, valid device string. */
if (*endp == '\0')
- return;
+ return (1);
/* Junk beyond partition number. */
- *type = -1;
- *unit = -1;
- *slice = 0;
- *partition = -1;
+ return (0);
}
static void
-print_disk_probe_info()
+print_disk_probe_info(struct uboot_devdesc dev)
{
- char slice[32];
- char partition[32];
- if (currdev.d_disk.slice > 0)
- sprintf(slice, "%d", currdev.d_disk.slice);
- else
- strcpy(slice, "<auto>");
+ printf(" Checking unit=%d ", dev.d_unit);
- if (currdev.d_disk.partition >= 0)
- sprintf(partition, "%d", currdev.d_disk.partition);
+ if (dev.d_disk.slice > 0)
+ printf("slice=%d ", dev.d_disk.slice);
else
- strcpy(partition, "<auto>");
-
- printf(" Checking unit=%d slice=%s partition=%s...",
- currdev.d_unit, slice, partition);
-
+ printf("slice=<auto> ");
+ if (dev.d_disk.partition >= 0)
+ printf("partition=%d...", dev.d_disk.partition);
+ else
+ printf("partition=<auto>...");
}
-static int
-probe_disks(int devidx, int load_type, int load_unit, int load_slice,
- int load_partition)
+static const char *
+probe_disks(const char *dstr)
{
- int open_result, unit;
+ struct device_info *di;
+ struct uboot_devdesc dev;
struct open_file f;
-
- currdev.d_disk.slice = load_slice;
- currdev.d_disk.partition = load_partition;
-
- f.f_devdata = &currdev;
- open_result = -1;
-
- if (load_type == -1) {
- printf(" Probing all disk devices...\n");
- /* Try each disk in succession until one works. */
- for (currdev.d_unit = 0; currdev.d_unit < UB_MAX_DEV;
- currdev.d_unit++) {
- print_disk_probe_info();
- open_result = devsw[devidx]->dv_open(&f, &currdev);
- if (open_result == 0) {
- printf(" good.\n");
- return (0);
- }
- printf("\n");
- }
- return (-1);
- }
-
- if (load_unit == -1) {
- printf(" Probing all %s devices...\n", device_typename(load_type));
- /* Try each disk of given type in succession until one works. */
- for (unit = 0; unit < UB_MAX_DEV; unit++) {
- currdev.d_unit = uboot_diskgetunit(load_type, unit);
- if (currdev.d_unit == -1)
+ int stlist[] = {
+ DT_STOR_IDE, DT_STOR_SCSI, DT_STOR_USB, DT_STOR_MMC,
+ DT_STOR_SATA
+ };
+ int type = DEV_TYP_STOR;
+ int nunits = 0, res = -1, valid = -1;
+ int i, v;
+ char *s;
+
+ bzero(&dev, sizeof(dev));
+
+ if ((dev.d_dev = search_devsw(DEVT_DISK)) == NULL)
+ return (NULL);
+
+ /* parse devstr if any */
+ if (dstr != NULL) {
+ for (i = 0; i < nitems(stlist); i++) {
+ v = strlen(s = ub_stor_type(stlist[i]));
+ if (strncasecmp(dstr, s, v) == 0) {
+ type = stlist[i];
break;
- print_disk_probe_info();
- open_result = devsw[devidx]->dv_open(&f, &currdev);
- if (open_result == 0) {
- printf(" good.\n");
- return (0);
}
- printf("\n");
}
- return (-1);
+ /* if device type is none above may be it's genereal disk type */
+ if ((strncasecmp(dstr, "disk", 4) != 0) && (type == DEV_TYP_STOR))
+ return (NULL);
+ if ((res = decode_devstr(&dstr[v], &dev.d_unit,
+ &dev.d_disk.slice, &dev.d_disk.partition)) == 0)
+ return (NULL);
}
-
- if ((currdev.d_unit = uboot_diskgetunit(load_type, load_unit)) != -1) {
- print_disk_probe_info();
- open_result = devsw[devidx]->dv_open(&f,&currdev);
- if (open_result == 0) {
+ /* calculate real unit address, offset and number of units */
+ for (v = i = 0; (di = ub_dev_get(DEV_TYP_STOR, &i)) != NULL; v++)
+ if ((di->type & type) && (nunits++ == dev.d_unit))
+ valid = dev.d_unit += v;
+ if (valid == -1)
+ return (NULL);
+
+ printf("Found U-Boot device: %s\n", dev.d_dev->dv_name);
+ dev.d_type = dev.d_dev->dv_type;
+ dev.d_disk.partition = -1;
+ f.f_devdata = &dev;
+
+ /* probe only one device unit if unit number is specified */
+ if (res > 0)
+ nunits = 1;
+ while (nunits--) {
+ print_disk_probe_info(dev);
+ if ((dev.d_dev)->dv_open(&f, &dev) == 0) {
printf(" good.\n");
- return (0);
+ return (uboot_fmtdev(&dev));
}
printf("\n");
+ dev.d_unit++;
}
+ return (NULL);
+}
- printf(" Requested disk type/unit/slice/partition not found\n");
- return (-1);
+static const char *
+probe_net(const char *dstr)
+{
+ struct uboot_devdesc dev;
+ int i;
+
+ bzero(&dev, sizeof(dev));
+
+ if ((dstr != NULL) && (strncasecmp(dstr, "net", 3) != 0))
+ return (NULL);
+ if ((dev.d_dev = search_devsw(DEVT_NET)) == NULL)
+ return (NULL);
+ dev.d_type = dev.d_dev->dv_type;
+
+ return (uboot_fmtdev(&dev));
}
int
main(int argc, char **argv)
{
struct api_signature *sig = NULL;
- int load_type, load_unit, load_slice, load_partition;
- int i;
- const char *ldev;
+ int i, devs_no;
+ const char *devstr, *ldev;
/*
* We first check if a command line argument was passed to us containing
@@ -422,7 +410,11 @@
* alloc() is usable. The stack is buried inside us, so this is safe.
*/
uboot_heap_start = round_page((uintptr_t)end);
+#ifndef LOADER_ZFS_SUPPORT
uboot_heap_end = uboot_heap_start + 512 * 1024;
+#else
+ uboot_heap_end = uboot_heap_start + 2 * 1024 * 1024;
+#endif
setheap((void *)uboot_heap_start, (void *)uboot_heap_end);
/*
@@ -436,11 +428,19 @@
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
printf("\n");
- dump_sig(sig);
- dump_addr_info();
-
+ PRINT_DEBUG_INFO();
meminfo();
+ archsw.arch_loadaddr = uboot_loadaddr;
+ archsw.arch_getdev = uboot_getdev;
+ archsw.arch_copyin = uboot_copyin;
+ archsw.arch_copyout = uboot_copyout;
+ archsw.arch_readin = uboot_readin;
+ archsw.arch_autoload = uboot_autoload;
+#ifdef LOADER_ZFS_SUPPORT
+ /* Note this needs to be set before ZFS init. */
+ archsw.arch_zfs_probe = uboot_zfs_probe;
+#endif
/*
* Enumerate U-Boot devices
*/
@@ -448,74 +448,58 @@
panic("no U-Boot devices found");
printf("Number of U-Boot devices: %d\n", devs_no);
- get_load_device(&load_type, &load_unit, &load_slice, &load_partition);
+ devstr = ub_env_get("loaderdev");
+ if (devstr == NULL)
+ printf("U-Boot env: loaderdev not set, will probe all devices.\n");
+ else
+ printf("U-Boot env: loaderdev='%s'\n", devstr);
/*
* March through the device switch probing for things.
*/
- for (i = 0; devsw[i] != NULL; i++) {
-
- if (devsw[i]->dv_init == NULL)
- continue;
- if ((devsw[i]->dv_init)() != 0)
- continue;
-
- printf("Found U-Boot device: %s\n", devsw[i]->dv_name);
-
- currdev.d_dev = devsw[i];
- currdev.d_type = currdev.d_dev->dv_type;
- currdev.d_unit = 0;
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
- if ((load_type == -1 || (load_type & DEV_TYP_STOR)) &&
- strcmp(devsw[i]->dv_name, "disk") == 0) {
- if (probe_disks(i, load_type, load_unit, load_slice,
- load_partition) == 0)
- break;
- }
-
- if ((load_type == -1 || (load_type & DEV_TYP_NET)) &&
- strcmp(devsw[i]->dv_name, "net") == 0)
+ do {
+#ifdef LOADER_ZFS_SUPPORT
+ if ((ldev = probe_zfs(devstr)) != NULL)
+ break;
+#endif
+ if ((ldev = probe_disks(devstr)) != NULL)
break;
- }
- /*
- * If we couldn't find a boot device, return an error to u-boot.
- * U-boot may be running a boot script that can try something different
- * so returning an error is better than forcing a reboot.
- */
- if (devsw[i] == NULL) {
+ if ((ldev = probe_net(devstr)) != NULL)
+ break;
+ /*
+ * If we couldn't find a boot device, return an error to u-boot.
+ * U-boot may be running a boot script that can try something
+ * different so returning an error is better than forcing a reboot.
+ */
printf("No boot device found!\n");
return (0xbadef1ce);
- }
+ } while (0);
+
+ printf("Booting from %s\n", ldev);
- ldev = uboot_fmtdev(&currdev);
env_setenv("currdev", EV_VOLATILE, ldev, uboot_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, ldev, env_noset, env_nounset);
- printf("Booting from %s\n", ldev);
setenv("LINES", "24", 1); /* optional */
setenv("prompt", "loader>", 1);
- archsw.arch_loadaddr = uboot_loadaddr;
- archsw.arch_getdev = uboot_getdev;
- archsw.arch_copyin = uboot_copyin;
- archsw.arch_copyout = uboot_copyout;
- archsw.arch_readin = uboot_readin;
- archsw.arch_autoload = uboot_autoload;
-
interact(NULL); /* doesn't return */
return (0);
}
-
COMMAND_SET(heap, "heap", "show heap usage", command_heap);
static int
command_heap(int argc, char *argv[])
{
printf("heap base at %p, top at %p, used %td\n", end, sbrk(0),
- sbrk(0) - end);
+ sbrk(0) - end);
return (CMD_OK);
}
@@ -536,16 +520,17 @@
static int
command_devinfo(int argc, char *argv[])
{
- int i;
+ struct device_info *di;
+ int i = 0;
- if ((devs_no = ub_dev_enum()) == 0) {
+ if (ub_dev_enum() == 0) {
command_errmsg = "no U-Boot devices found!?";
return (CMD_ERROR);
}
-
printf("U-Boot devices:\n");
- for (i = 0; i < devs_no; i++) {
- ub_dump_di(i);
+ while ((di = ub_dev_get(DEV_TYP_NET | DEV_TYP_STOR, &i)) != NULL) {
+ printf("device info (%d):\n", i - 1);
+ ub_dump_di(di);
printf("\n");
}
return (CMD_OK);
@@ -561,7 +546,6 @@
command_errmsg = "could not retrieve U-Boot sys info!?";
return (CMD_ERROR);
}
-
printf("U-Boot system info:\n");
ub_dump_si(si);
return (CMD_OK);
@@ -602,7 +586,6 @@
var = &var[len + 1];
}
}
-
/*
* If the user prepended "uboot." (which is how they usually see these
* names) strip it off as a convenience.
@@ -610,13 +593,11 @@
if (strncmp(var, "uboot.", 6) == 0) {
var = &var[6];
}
-
/* If there is no variable name left, punt. */
if (var[0] == 0) {
printf("empty variable name\n");
return;
}
-
val = ub_env_get(var);
if (action == UBENV_SHOW) {
if (val == NULL)
@@ -648,7 +629,6 @@
command_errmsg = "usage: 'ubenv <import|show> [var ...]";
return (CMD_ERROR);
}
-
if (argc > 2) {
for (i = 2; i < argc; i++)
handle_uboot_env_var(action, argv[i]);
@@ -660,7 +640,6 @@
handle_uboot_env_var(action, var);
}
}
-
return (CMD_OK);
}
COMMAND_SET(ubenv, "ubenv", "show or import U-Boot env vars", command_ubenv);
@@ -681,3 +660,54 @@
COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt);
#endif
+
+#ifdef LOADER_ZFS_SUPPORT
+COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset",
+ command_lszfs);
+
+static int
+command_lszfs(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 2) {
+ command_errmsg = "wrong number of arguments";
+ return (CMD_ERROR);
+ }
+ err = zfs_list(argv[1]);
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+ return (CMD_OK);
+}
+
+COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
+ command_reloadbe);
+
+static int
+command_reloadbe(int argc, char *argv[])
+{
+ int err;
+ char *root;
+
+ if (argc > 2) {
+ command_errmsg = "wrong number of arguments";
+ return (CMD_ERROR);
+ }
+ if (argc == 2) {
+ err = zfs_bootenv(argv[1]);
+ } else {
+ root = getenv("zfs_be_root");
+ if (root == NULL) {
+ return (CMD_OK);
+ }
+ err = zfs_bootenv(root);
+ }
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+ return (CMD_OK);
+}
+#endif
Index: sys/boot/uboot/lib/Makefile
===================================================================
--- sys/boot/uboot/lib/Makefile
+++ sys/boot/uboot/lib/Makefile
@@ -20,6 +20,19 @@
CFLAGS+= -DLOADER_DISK_SUPPORT
.endif
+.if ${MK_ZFS} != "no"
+LOADER_ZFS_SUPPORT= yes
+
+CFLAGS+= -I${.CURDIR}/../../zfs
+CFLAGS+= -I${.CURDIR}/../../../cddl/boot/zfs
+.else
+LOADER_ZFS_SUPPORT= no
+.endif
+
+.if ${LOADER_ZFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_ZFS_SUPPORT
+.endif
+
.if ${MK_FDT} != "no"
LOADER_FDT_SUPPORT= yes
.else
Index: sys/boot/uboot/lib/devicename.c
===================================================================
--- sys/boot/uboot/lib/devicename.c
+++ sys/boot/uboot/lib/devicename.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2016 Vladimir Belian <fate10@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,13 +30,15 @@
#include <stand.h>
#include <string.h>
+#ifdef LOADER_ZFS_SUPPORT
+#include <libzfs.h>
+#endif
#include "bootstrap.h"
#include "disk.h"
#include "libuboot.h"
-static int uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
- const char **path);
+static int uboot_parsedev(struct uboot_devdesc **, const char *, const char **);
/*
* Point (dev) at an allocated device specifier for the device matching the
@@ -53,14 +56,13 @@
* device, go with the current device.
*/
if ((devspec == NULL) || (devspec[0] == '/') ||
- (strchr(devspec, ':') == NULL)) {
+ (strchr(devspec, ':') == NULL)) {
- if (((rv = uboot_parsedev(dev, getenv("currdev"), NULL)) == 0)
- && (path != NULL))
- *path = devspec;
+ rv = uboot_parsedev(dev, getenv("currdev"), NULL);
+ if ((rv == 0) && (path != NULL))
+ *path = devspec;
return(rv);
}
-
/*
* Try to parse the device name off the beginning of the devspec.
*/
@@ -82,101 +84,101 @@
*
*/
static int
-uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
- const char **path)
+uboot_parsedev(struct uboot_devdesc **dev, const char *devspec, const char **path)
{
struct uboot_devdesc *idev;
struct devsw *dv;
- char *cp;
const char *np;
- int i, unit, err;
+ char *cp;
+ int i, err = 0;
/* minimum length check */
if (strlen(devspec) < 2)
return(EINVAL);
/* look for a device that matches */
- for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
- if (!strncmp(devspec, devsw[i]->dv_name,
- strlen(devsw[i]->dv_name))) {
- dv = devsw[i];
+ for (i = 0; devsw[i] != NULL; i++) {
+ dv = devsw[i];
+ if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
break;
- }
}
if (dv == NULL)
- return(ENOENT);
- idev = malloc(sizeof(struct uboot_devdesc));
- err = 0;
- np = (devspec + strlen(dv->dv_name));
+ return (ENOENT);
+ if ((idev = malloc(sizeof(struct uboot_devdesc))) == NULL)
+ return (ENOMEM);
+
+ np = devspec + strlen(dv->dv_name);
switch(dv->dv_type) {
- case DEVT_NONE:
+#ifdef LOADER_ZFS_SUPPORT
+ case DEVT_ZFS:
+ err = zfs_parsedev((struct zfs_devdesc *)idev, np, path);
break;
-
+#endif
#ifdef LOADER_DISK_SUPPORT
case DEVT_DISK:
err = disk_parsedev((struct disk_devdesc *)idev, np, path);
- if (err != 0)
- goto fail;
break;
#endif
-
case DEVT_NET:
- unit = 0;
-
+ idev->d_unit = 0;
if (*np && (*np != ':')) {
- /* get unit number if present */
- unit = strtol(np, &cp, 0);
+ idev->d_unit = strtol(np, &cp, 0);
if (cp == np) {
- err = EUNIT;
- goto fail;
+ idev->d_unit = -1;
+ err = EINVAL;
+ break;
}
}
+ else {
+ cp = (char *)np;
+ }
if (*cp && (*cp != ':')) {
err = EINVAL;
- goto fail;
+ break;
}
- idev->d_unit = unit;
-
if (path != NULL)
*path = (*cp == 0) ? cp : cp + 1;
break;
-
+ case DEVT_NONE:
+ free(idev);
+ return (0);
default:
err = EINVAL;
- goto fail;
+ }
+ if (err) {
+ free(idev);
+ return (err);
}
idev->d_dev = dv;
idev->d_type = dv->dv_type;
- if (dev == NULL) {
- free(idev);
- } else {
+
+ if (dev != NULL)
*dev = idev;
- }
- return (0);
+ else
+ free(idev);
-fail:
- free(idev);
- return (err);
+ return (0);
}
-
char *
uboot_fmtdev(void *vdev)
{
struct uboot_devdesc *dev = (struct uboot_devdesc *)vdev;
- static char buf[128];
+ static char buf[UB_MAXNAMELEN];
switch(dev->d_type) {
+#ifdef LOADER_ZFS_SUPPORT
+ case DEVT_ZFS:
+ return (zfs_fmtdev(vdev));
+#endif
case DEVT_NONE:
strcpy(buf, "(no device)");
break;
-
case DEVT_DISK:
#ifdef LOADER_DISK_SUPPORT
return (disk_fmtdev(vdev));
#endif
-
case DEVT_NET:
sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
break;
Index: sys/boot/uboot/lib/disk.c
===================================================================
--- sys/boot/uboot/lib/disk.c
+++ sys/boot/uboot/lib/disk.c
@@ -2,6 +2,7 @@
* Copyright (c) 2008 Semihalf, Rafal Jaworowski
* Copyright (c) 2009 Semihalf, Piotr Ziecik
* Copyright (c) 2012 Andrey V. Elsukov <ae@FreeBSD.org>
+ * Copyright (c) 2016 Vladimir Belian <fate10@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -46,24 +47,18 @@
#include "libuboot.h"
#define stor_printf(fmt, args...) do { \
- printf("%s%d: ", dev->d_dev->dv_name, dev->d_unit); \
- printf(fmt, ##args); \
+ printf("%s%d: ", dev->d_dev->dv_name, dev->d_unit); \
+ printf(fmt, ##args); \
} while (0)
#ifdef DEBUG
#define debugf(fmt, args...) do { printf("%s(): ", __func__); \
- printf(fmt,##args); } while (0)
+ printf(fmt,##args); } while (0)
#else
#define debugf(fmt, args...)
#endif
-static struct {
- int opened; /* device is opened */
- int handle; /* storage device handle */
- int type; /* storage type */
- off_t blocks; /* block count */
- u_int bsize; /* block size */
-} stor_info[UB_MAX_DEV];
+static struct device_info *stor_info[UB_MAX_DEV];
#define SI(dev) (stor_info[(dev)->d_unit])
@@ -95,38 +90,19 @@
static int
stor_init(void)
{
- struct device_info *di;
- int i;
+ int i = 0;
- if (devs_no == 0) {
+ if (ub_dev_enum() == 0) {
printf("No U-Boot devices! Really enumerated?\n");
return (-1);
}
-
- for (i = 0; i < devs_no; i++) {
- di = ub_dev_get(i);
- if ((di != NULL) && (di->type & DEV_TYP_STOR)) {
- if (stor_info_no >= UB_MAX_DEV) {
- printf("Too many storage devices: %d\n",
- stor_info_no);
- return (-1);
- }
- stor_info[stor_info_no].handle = i;
- stor_info[stor_info_no].opened = 0;
- stor_info[stor_info_no].type = di->type;
- stor_info[stor_info_no].blocks =
- di->di_stor.block_count;
- stor_info[stor_info_no].bsize =
- di->di_stor.block_size;
- stor_info_no++;
- }
- }
+ while ((stor_info[stor_info_no++] = ub_dev_get(DEV_TYP_STOR, &i)) != NULL) ;
+ stor_info_no--;
if (!stor_info_no) {
debugf("No storage devices\n");
return (-1);
}
-
debugf("storage devices found: %d\n", stor_info_no);
return (0);
}
@@ -137,8 +113,9 @@
int i;
for (i = 0; i < stor_info_no; i++)
- if (stor_info[i].opened > 0)
- ub_dev_close(stor_info[i].handle);
+ if (stor_info[i]->state == DEV_STA_OPEN)
+ ub_dev_close(stor_info[i]);
+
disk_cleanup(&uboot_storage);
}
@@ -150,18 +127,20 @@
daddr_t bcount;
int err;
+ if (dev->d_unit < 0 || dev->d_unit >= stor_info_no)
+ return (EIO);
+
if (rw != F_READ) {
stor_printf("write attempt, operation not supported!\n");
return (EROFS);
}
-
- if (size % SI(dev).bsize) {
+ if (size % SI(dev)->di_stor.block_size) {
stor_printf("size=%zu not multiple of device "
- "block size=%d\n",
- size, SI(dev).bsize);
+ "block size=%d\n",
+ size, (int) SI(dev)->di_stor.block_size);
return (EIO);
}
- bcount = size / SI(dev).bsize;
+ bcount = size / SI(dev)->di_stor.block_size;
if (rsize)
*rsize = 0;
@@ -193,17 +172,16 @@
if (dev->d_unit < 0 || dev->d_unit >= stor_info_no)
return (EIO);
- if (SI(dev).opened == 0) {
- err = ub_dev_open(SI(dev).handle);
+ if (SI(dev)->state == DEV_STA_CLOSED) {
+ err = ub_dev_open(SI(dev));
if (err != 0) {
stor_printf("device open failed with error=%d, "
- "handle=%d\n", err, SI(dev).handle);
+ "unit=%d\n", err, dev->d_unit);
return (ENXIO);
}
- SI(dev).opened++;
}
- return (disk_open(dev, SI(dev).blocks * SI(dev).bsize,
- SI(dev).bsize, 0));
+ return (disk_open(dev, SI(dev)->di_stor.block_count * SI(dev)->di_stor.block_size,
+ SI(dev)->di_stor.block_size, 0));
}
static int
@@ -223,17 +201,15 @@
debugf("reading blk=%d size=%d @ 0x%08x\n", (int)blk, size, (uint32_t)buf);
- err = ub_dev_read(SI(dev).handle, buf, size, blk, &real_size);
+ err = ub_dev_read(SI(dev), buf, size, blk, &real_size);
if (err != 0) {
stor_printf("read failed, error=%d\n", err);
return (EIO);
}
-
if (real_size != size) {
stor_printf("real size != size\n");
err = EIO;
}
-
return (err);
}
@@ -250,7 +226,7 @@
dev.d_slice = -1;
dev.d_partition = -1;
sprintf(line, "\tdisk%d (%s)\n", i,
- ub_stor_type(SI(&dev).type));
+ ub_stor_type(SI(&dev)->type));
pager_output(line);
if (stor_opendev(&dev) == 0) {
sprintf(line, "\tdisk%d", i);
@@ -266,39 +242,19 @@
struct disk_devdesc *dev;
dev = (struct disk_devdesc *)f->f_devdata;
+ if (dev->d_unit < 0 || dev->d_unit >= stor_info_no)
+ return (EIO);
+
switch (cmd) {
case DIOCGSECTORSIZE:
- *(u_int *)data = SI(dev).bsize;
+ *(u_int *)data = SI(dev)->di_stor.block_size;
break;
case DIOCGMEDIASIZE:
- *(off_t *)data = SI(dev).bsize * SI(dev).blocks;
+ *(off_t *)data =
+ SI(dev)->di_stor.block_size * SI(dev)->di_stor.block_count;
break;
default:
return (ENOTTY);
}
return (0);
}
-
-
-/*
- * Return the device unit number for the given type and type-relative unit
- * number.
- */
-int
-uboot_diskgetunit(int type, int type_unit)
-{
- int local_type_unit;
- int i;
-
- local_type_unit = 0;
- for (i = 0; i < stor_info_no; i++) {
- if ((stor_info[i].type & type) == type) {
- if (local_type_unit == type_unit) {
- return (i);
- }
- local_type_unit++;
- }
- }
-
- return (-1);
-}
Index: sys/boot/uboot/lib/glue.h
===================================================================
--- sys/boot/uboot/lib/glue.h
+++ sys/boot/uboot/lib/glue.h
@@ -92,14 +92,14 @@
/* devices */
int ub_dev_enum(void);
-int ub_dev_open(int);
-int ub_dev_close(int);
-int ub_dev_read(int, void *, lbasize_t, lbastart_t, lbasize_t *);
-int ub_dev_send(int, void *, int);
-int ub_dev_recv(int, void *, int, int *);
-struct device_info *ub_dev_get(int);
-
-void ub_dump_di(int);
+int ub_dev_open(struct device_info *);
+int ub_dev_close(struct device_info *);
+int ub_dev_read(struct device_info *, void *, lbasize_t, lbastart_t, lbasize_t *);
+int ub_dev_send(struct device_info *, void *, int);
+int ub_dev_recv(struct device_info *, void *, int, int *);
+struct device_info *ub_dev_get(int, int *);
+
+void ub_dump_di(struct device_info *);
void ub_dump_si(struct sys_info *);
char *ub_mem_type(int);
char *ub_stor_type(int);
Index: sys/boot/uboot/lib/glue.c
===================================================================
--- sys/boot/uboot/lib/glue.c
+++ sys/boot/uboot/lib/glue.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * Copyright (c) 2016 Vladimir Belian <fate10@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -241,12 +242,20 @@
***************************************************************************/
static struct device_info devices[UB_MAX_DEV];
+static int devs_num = -1;
struct device_info *
-ub_dev_get(int i)
+ub_dev_get(int type, int *i)
{
- return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
+ if ((i == NULL) || (*i < 0))
+ return (NULL);
+
+ while (*i < devs_num)
+ if (devices[(*i)++].type & type)
+ return (&devices[*i - 1]);
+
+ return (NULL);
}
/*
@@ -259,30 +268,24 @@
ub_dev_enum(void)
{
struct device_info *di;
- int n = 0;
+
+ if (devs_num != -1)
+ return (devs_num);
memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
di = &devices[0];
- if (!syscall(API_DEV_ENUM, NULL, di))
- return (0);
-
- while (di->cookie != NULL) {
-
- if (++n >= UB_MAX_DEV)
- break;
+ for (devs_num = 0; syscall(API_DEV_ENUM, NULL, di);) {
+ if ((di->cookie == NULL) || (++devs_num >= UB_MAX_DEV))
+ return (devs_num);
/* take another device_info */
di++;
/* pass on the previous cookie */
- di->cookie = devices[n - 1].cookie;
-
- if (!syscall(API_DEV_ENUM, NULL, di))
- return (0);
+ di->cookie = devices[devs_num - 1].cookie;
}
-
- return (n);
+ return (devs_num = 0);
}
/*
@@ -291,82 +294,37 @@
* returns: 0 when OK, err otherwise
*/
int
-ub_dev_open(int handle)
+ub_dev_open(struct device_info *di)
{
- struct device_info *di;
int err = 0;
- if (handle < 0 || handle >= UB_MAX_DEV)
- return (API_EINVAL);
-
- di = &devices[handle];
- if (!syscall(API_DEV_OPEN, &err, di))
- return (-1);
-
- return (err);
+ return ((!syscall(API_DEV_OPEN, &err, di)) ? -1 : err);
}
int
-ub_dev_close(int handle)
-{
- struct device_info *di;
-
- if (handle < 0 || handle >= UB_MAX_DEV)
- return (API_EINVAL);
-
- di = &devices[handle];
- if (!syscall(API_DEV_CLOSE, NULL, di))
- return (-1);
-
- return (0);
-}
-
-/*
- * Validates device for read/write, it has to:
- *
- * - have sane handle
- * - be opened
- *
- * returns: 0/1 accordingly
- */
-static int
-dev_valid(int handle)
+ub_dev_close(struct device_info *di)
{
- if (handle < 0 || handle >= UB_MAX_DEV)
- return (0);
-
- if (devices[handle].state != DEV_STA_OPEN)
- return (0);
-
- return (1);
+ return ((!syscall(API_DEV_CLOSE, NULL, di)) ? -1 : 0);
}
static int
-dev_stor_valid(int handle)
+dev_valid(struct device_info *di, int type)
{
- if (!dev_valid(handle))
- return (0);
-
- if (!(devices[handle].type & DEV_TYP_STOR))
- return (0);
-
- return (1);
+ return (((di->state == DEV_STA_OPEN) && (di->type & type)) ? 1 : 0);
}
int
-ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
- lbasize_t *rlen)
+ub_dev_read(struct device_info *di, void *buf, lbasize_t len,
+ lbastart_t start, lbasize_t *rlen)
{
- struct device_info *di;
lbasize_t act_len;
int err = 0;
- if (!dev_stor_valid(handle))
+ if (!dev_valid(di, DEV_TYP_STOR))
return (API_ENODEV);
- di = &devices[handle];
if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
return (API_ESYSC);
@@ -376,29 +334,14 @@
return (err);
}
-static int
-dev_net_valid(int handle)
-{
-
- if (!dev_valid(handle))
- return (0);
-
- if (devices[handle].type != DEV_TYP_NET)
- return (0);
-
- return (1);
-}
-
int
-ub_dev_recv(int handle, void *buf, int len, int *rlen)
+ub_dev_recv(struct device_info *di, void *buf, int len, int *rlen)
{
- struct device_info *di;
int err = 0, act_len;
- if (!dev_net_valid(handle))
+ if (!dev_valid(di, DEV_TYP_NET))
return (API_ENODEV);
- di = &devices[handle];
if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
return (API_ESYSC);
@@ -409,15 +352,13 @@
}
int
-ub_dev_send(int handle, void *buf, int len)
+ub_dev_send(struct device_info *di, void *buf, int len)
{
- struct device_info *di;
int err = 0;
- if (!dev_net_valid(handle))
+ if (!dev_valid(di, DEV_TYP_NET))
return (API_ENODEV);
- di = &devices[handle];
if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
return (API_ESYSC);
@@ -463,12 +404,10 @@
}
void
-ub_dump_di(int handle)
+ub_dump_di(struct device_info *di)
{
- struct device_info *di = ub_dev_get(handle);
int i;
- printf("device info (%d):\n", handle);
printf(" cookie\t= 0x%p\n", di->cookie);
printf(" type\t\t= 0x%08x\n", di->type);
Index: sys/boot/uboot/lib/libuboot.h
===================================================================
--- sys/boot/uboot/lib/libuboot.h
+++ sys/boot/uboot/lib/libuboot.h
@@ -49,6 +49,8 @@
*/
#define PKTALIGN 32
+#define UB_MAXNAMELEN 128
+
int uboot_getdev(void **vdev, const char *devspec, const char **path);
char *uboot_fmtdev(void *vdev);
int uboot_setcurrdev(struct env_var *ev, int flags, const void *value);
@@ -72,6 +74,3 @@
extern struct file_format uboot_elf;
void reboot(void);
-
-int uboot_diskgetunit(int type, int type_unit);
-
Index: sys/boot/uboot/lib/net.c
===================================================================
--- sys/boot/uboot/lib/net.c
+++ sys/boot/uboot/lib/net.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2000-2001 Benno Rice
* Copyright (c) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
+ * Copyright (c) 2016 Vladimir Belian <fate10@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -80,7 +81,7 @@
uint8_t sc_rxbuf[ETHER_MAX_LEN];
uint8_t sc_txbuf[ETHER_MAX_LEN + PKTALIGN];
uint8_t *sc_txbufp;
- int sc_handle; /* device handle for ub_dev_xxx */
+ struct device_info *sc_dinfo; /* device handle for ub_dev_xxx */
};
static struct uboot_softc uboot_softc;
@@ -210,25 +211,16 @@
static int
net_probe(struct netif *nif, void *machdep_hint)
{
- struct device_info *di;
- int i;
+ int i = 0;
- for (i = 0; i < devs_no; i++)
- if ((di = ub_dev_get(i)) != NULL)
- if (di->type == DEV_TYP_NET)
- break;
-
- if (i == devs_no) {
+ if ((uboot_softc.sc_dinfo = ub_dev_get(DEV_TYP_NET, &i)) == NULL)
printf("net_probe: no network devices found, maybe not"
- " enumerated yet..?\n");
+ " enumerated yet..?\n");
return (-1);
- }
#if defined(NETIF_DEBUG)
- printf("net_probe: network device found: %d\n", i);
+ printf("net_probe: network device found: %d\n", i - 1);
#endif
- uboot_softc.sc_handle = i;
-
return (0);
}
@@ -258,7 +250,7 @@
memcpy(sc->sc_txbufp, pkt, len);
- rv = ub_dev_send(sc->sc_handle, sc->sc_txbufp, sendlen);
+ rv = ub_dev_send(sc->sc_dinfo, sc->sc_txbufp, sendlen);
#if defined(NETIF_DEBUG)
printf("net_put: ub_send returned %d\n", rv);
@@ -284,7 +276,7 @@
#endif
t = getsecs();
do {
- err = ub_dev_recv(sc->sc_handle, sc->sc_rxbuf, len, &rlen);
+ err = ub_dev_recv(sc->sc_dinfo, sc->sc_rxbuf, len, &rlen);
if (err != 0) {
printf("net_get: ub_dev_recv() failed, error=%d\n",
@@ -316,18 +308,16 @@
{
struct netif *nif = desc->io_netif;
struct uboot_softc *sc;
- struct device_info *di;
int err;
sc = nif->nif_devdata = &uboot_softc;
- if ((err = ub_dev_open(sc->sc_handle)) != 0)
+ if ((err = ub_dev_open(sc->sc_dinfo)) != 0)
panic("%s%d: initialisation failed with error %d\n",
nif->nif_driver->netif_bname, nif->nif_unit, err);
/* Get MAC address */
- di = ub_dev_get(sc->sc_handle);
- memcpy(desc->myea, di->di_net.hwaddr, 6);
+ memcpy(desc->myea, sc->sc_dinfo->di_net.hwaddr, 6);
if (memcmp (desc->myea, "\0\0\0\0\0\0", 6) == 0) {
panic("%s%d: empty ethernet address!",
nif->nif_driver->netif_bname, nif->nif_unit);
@@ -356,7 +346,7 @@
struct uboot_softc *sc = nif->nif_devdata;
int err;
- if ((err = ub_dev_close(sc->sc_handle)) != 0)
+ if ((err = ub_dev_close(sc->sc_dinfo)) != 0)
panic("%s%d: net_end failed with error %d\n",
nif->nif_driver->netif_bname, nif->nif_unit, err);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Sep 30, 11:24 PM (11 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30047840
Default Alt Text
D5680.1790810668.diff (41 KB)

Event Timeline