diff --git a/sys/arch/zaurus/stand/zboot/boot.c b/sys/arch/zaurus/stand/zboot/boot.c index 83b54378feb2..6d0b4a15edaa 100644 --- a/sys/arch/zaurus/stand/zboot/boot.c +++ b/sys/arch/zaurus/stand/zboot/boot.c @@ -1,4 +1,4 @@ -/* $NetBSD: boot.c,v 1.2 2011/01/22 19:19:25 joerg Exp $ */ +/* $NetBSD: boot.c,v 1.3 2011/06/20 12:39:21 nonaka Exp $ */ /* * Copyright (c) 2009 NONAKA Kimihiro @@ -128,7 +128,7 @@ parsebootfile(const char *fname, char **fsname, char **devname, } while (isnum(fname[i])); } -#define isvalidpart(c) ((c) >= 'a' && (c) <= 'a' + MAXPARTITIONS) +#define isvalidpart(c) ((c) >= 'a' && (c) < 'a' + MAXPARTITIONS) if (i < devlen) { if (!isvalidpart(fname[i])) return (EPART); diff --git a/sys/arch/zaurus/stand/zboot/compat_linux.h b/sys/arch/zaurus/stand/zboot/compat_linux.h index 3d6849eb3413..fbab58bc800b 100644 --- a/sys/arch/zaurus/stand/zboot/compat_linux.h +++ b/sys/arch/zaurus/stand/zboot/compat_linux.h @@ -1,4 +1,4 @@ -/* $NetBSD: compat_linux.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */ +/* $NetBSD: compat_linux.h,v 1.2 2011/06/20 12:39:21 nonaka Exp $ */ /* $OpenBSD: compat_linux.h,v 1.8 2007/06/16 00:26:33 deraadt Exp $ */ /* @@ -60,6 +60,7 @@ struct vnode; #define __NR_ioctl (__NR_SYSCALL_BASE + LINUX_SYS_ioctl) #define __NR_select (__NR_SYSCALL_BASE + LINUX_SYS_select) #define __NR_stat (__NR_SYSCALL_BASE + LINUX_SYS_stat) +#define __NR_fstat (__NR_SYSCALL_BASE + LINUX_SYS_fstat) #define __NR_syscall (__NR_SYSCALL_BASE + 113) #undef SYS_select diff --git a/sys/arch/zaurus/stand/zboot/diskprobe.c b/sys/arch/zaurus/stand/zboot/diskprobe.c index 4804c01dcf51..dd5a1728f976 100644 --- a/sys/arch/zaurus/stand/zboot/diskprobe.c +++ b/sys/arch/zaurus/stand/zboot/diskprobe.c @@ -1,4 +1,4 @@ -/* $NetBSD: diskprobe.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */ +/* $NetBSD: diskprobe.c,v 1.2 2011/06/20 12:39:21 nonaka Exp $ */ /* $OpenBSD: diskprobe.c,v 1.3 2006/10/13 00:00:55 krw Exp $ */ /* @@ -40,14 +40,20 @@ #include "boot.h" #include "disk.h" #include "unixdev.h" +#include "pathnames.h" #include "compat_linux.h" +/* All the info on /proc/partitions */ +struct partinfo { + char devname[MAXDEVNAME]; + TAILQ_ENTRY(partinfo) list; +}; +TAILQ_HEAD(partlist_lh, partinfo); +struct partlist_lh partlist; + /* Disk spin-up wait timeout. */ static u_int timeout = 10; -/* Local Prototypes */ -static void hardprobe(char *buf, size_t bufsiz); - /* List of disk devices we found/probed */ struct disklist_lh disklist; @@ -129,11 +135,130 @@ hardprobe(char *buf, size_t bufsiz) strlcat(buf, "none...", bufsiz); } +static void +getpartitions(void) +{ + struct linux_stat sb; + struct partinfo *pip; + char *bc, *top, *next, *p, *q; + int fd, off, len; + + fd = uopen(_PATH_PARTITIONS, LINUX_O_RDONLY); + if (fd == -1) + return; + + if (ufstat(fd, &sb) < 0) { + uclose(fd); + return; + } + + bc = alloc(sb.lst_size + 1); + if (bc == NULL) { + printf("Could not allocate memory for %s\n", _PATH_PARTITIONS); + uclose(fd); + return; + } + + off = 0; + do { + len = uread(fd, bc + off, 1024); + if (len <= 0) + break; + off += len; + } while (len > 0); + bc[off] = '\0'; + + uclose(fd); + + /* bc now contains the whole /proc/partitions */ + for (p = bc; *p != '\0'; p = next) { + top = p; + + /* readline */ + for (; *p != '\0' && *p != '\r' && *p != '\n'; p++) + continue; + if (*p == '\r') { + *p++ = '\0'; + if (*p == '\n') + *p++ = '\0'; + } else if (*p == '\n') + *p++ = '\0'; + next = p; + + /* + * /proc/partitions format: + * major minor #blocks name + * + * %d %d %d %s + * + * e.g.: + * major minor #blocks name + * + * 22 0 7962192 hdc + * 22 1 10079 hdc1 + * 60 0 965120 mmcda + * 60 1 43312 mmcda1 + */ + + /* trailing space */ + for (p = top; *p == ' ' || *p == '\t'; p++) + continue; + + /* major */ + for (; isdigit(*p); p++) + continue; + if (*p != ' ' && *p != '\t') + continue; /* next line */ + for (; *p == ' ' || *p == '\t'; p++) + continue; + + /* minor */ + for (; isdigit(*p); p++) + continue; + if (*p != ' ' && *p != '\t') + continue; /* next line */ + for (; *p == ' ' || *p == '\t'; p++) + continue; + + /* #blocks */ + for (; isdigit(*p); p++) + continue; + if (*p != ' ' && *p != '\t') + continue; /* next line */ + for (; *p == ' ' || *p == '\t'; p++) + continue; + + /* name */ + for (q = p; isalpha(*p) || isdigit(*p); p++) + continue; + if (*p != ' ' && *p != '\t' && *p != '\0') + continue; /* next line */ + if (isdigit(p[-1])) + continue; /* next line */ + *p = '\0'; + + pip = alloc(sizeof(*pip)); + if (pip == NULL) { + printf("Could not allocate memory for partition\n"); + continue; /* next line */ + } + memset(pip, 0, sizeof(*pip)); + snprintf(pip->devname, sizeof(pip->devname), "/dev/%s", q); + TAILQ_INSERT_TAIL(&partlist, pip, list); + } + + dealloc(bc, 0); +} + /* Probe for all BIOS supported disks */ void diskprobe(char *buf, size_t bufsiz) { + /* get available disk list from /proc/partitions */ + TAILQ_INIT(&partlist); + getpartitions(); + /* Init stuff */ TAILQ_INIT(&disklist); @@ -207,12 +332,22 @@ bios_getdiskinfo(int dev, bios_diskinfo_t *bdi) { static char path[PATH_MAX]; struct linux_stat sb; + struct partinfo *pip; memset(bdi, 0, sizeof *bdi); bdi->bios_number = -1; bios_devpath(dev, -1, path); + /* Check device name in /proc/partitions */ + for (pip = TAILQ_FIRST(&partlist); pip != NULL; + pip = TAILQ_NEXT(pip, list)) { + if (!strcmp(path, pip->devname)) + break; + } + if (pip == NULL) + return "no device node"; + if (ustat(path, &sb) != 0) return "no device node"; diff --git a/sys/arch/zaurus/stand/zboot/pathnames.h b/sys/arch/zaurus/stand/zboot/pathnames.h index ef3f1ee9ce25..aa3f9b9a34ea 100644 --- a/sys/arch/zaurus/stand/zboot/pathnames.h +++ b/sys/arch/zaurus/stand/zboot/pathnames.h @@ -1,4 +1,4 @@ -/* $NetBSD: pathnames.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */ +/* $NetBSD: pathnames.h,v 1.2 2011/06/20 12:39:21 nonaka Exp $ */ /* $OpenBSD: pathnames.h,v 1.3 2005/01/14 08:10:16 uwe Exp $ */ /* @@ -17,5 +17,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define _PATH_BOOTCONF "/boot.cfg" -#define _PATH_ZBOOT "/proc/zboot" +#define _PATH_BOOTCONF "/boot.cfg" +#define _PATH_ZBOOT "/proc/zboot" +#define _PATH_PARTITIONS "/proc/partitions" diff --git a/sys/arch/zaurus/stand/zboot/unixdev.h b/sys/arch/zaurus/stand/zboot/unixdev.h index 32c886e0fb96..90caef6f7720 100644 --- a/sys/arch/zaurus/stand/zboot/unixdev.h +++ b/sys/arch/zaurus/stand/zboot/unixdev.h @@ -1,4 +1,4 @@ -/* $NetBSD: unixdev.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */ +/* $NetBSD: unixdev.h,v 1.2 2011/06/20 12:39:21 nonaka Exp $ */ /* $OpenBSD: unixdev.h,v 1.1 2005/05/24 20:38:20 uwe Exp $ */ /* @@ -59,6 +59,7 @@ off_t ulseek(int, off_t, int); void uexit(int) __attribute__((noreturn)); int uselect(int, fd_set *, fd_set *, fd_set *, struct linux_timeval *); int ustat(const char *, struct linux_stat *); +int ufstat(int, struct linux_stat *); int syscall(int, ...); int __syscall(quad_t, ...); diff --git a/sys/arch/zaurus/stand/zboot/unixsys.S b/sys/arch/zaurus/stand/zboot/unixsys.S index 62d6996f64c2..41cd7c54b446 100644 --- a/sys/arch/zaurus/stand/zboot/unixsys.S +++ b/sys/arch/zaurus/stand/zboot/unixsys.S @@ -1,4 +1,4 @@ -/* $NetBSD: unixsys.S,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */ +/* $NetBSD: unixsys.S,v 1.2 2011/06/20 12:39:21 nonaka Exp $ */ /* $OpenBSD: unixsys.S,v 1.6 2005/05/24 20:38:20 uwe Exp $ */ /* @@ -36,6 +36,7 @@ RSYSCALL(close) RSYSCALL(lseek32) RSYSCALL(ioctl) RSYSCALL(stat) +RSYSCALL(fstat) 1: cmn r0, #4096 diff --git a/sys/arch/zaurus/stand/zboot/version b/sys/arch/zaurus/stand/zboot/version index a535c1248c09..da9a39911c60 100644 --- a/sys/arch/zaurus/stand/zboot/version +++ b/sys/arch/zaurus/stand/zboot/version @@ -1,7 +1,8 @@ -$NetBSD: version,v 1.1 2009/03/02 09:33:02 nonaka Exp $ +$NetBSD: version,v 1.2 2011/06/20 12:39:21 nonaka Exp $ NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this file is important - make sure the entries are appended on end, last item is taken as the current. 1.0: Initial version. +1.1: Support SL-C1000.