Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149730993
D5680.1790810668.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
41 KB
Referenced Files
None
Subscribers
None
D5680.1790810668.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D5680: ubldr zfs support
Attached
Detach File
Event Timeline
Log In to Comment