Date: Wed, 19 Nov 2008 17:34:28 +0000 (UTC) From: Rafal Jaworowski <raj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r185099 - in head/sys: boot/arm/uboot boot/uboot/lib sys Message-ID: <200811191734.mAJHYSCw023563@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: raj Date: Wed Nov 19 17:34:28 2008 New Revision: 185099 URL: http://svn.freebsd.org/changeset/base/185099 Log: Initial storage functionality for U-Boot support library. - Only non-sliced bsdlabel style partitioning is currently supported (but provisions are made towards GPT support, which should follow soon) - Enable storage support in loader on ARM Obtained from: Semihalf Modified: head/sys/boot/arm/uboot/Makefile head/sys/boot/arm/uboot/conf.c head/sys/boot/arm/uboot/version head/sys/boot/uboot/lib/devicename.c head/sys/boot/uboot/lib/disk.c head/sys/boot/uboot/lib/glue.c head/sys/boot/uboot/lib/glue.h head/sys/boot/uboot/lib/libuboot.h head/sys/boot/uboot/lib/net.c head/sys/sys/disklabel.h Modified: head/sys/boot/arm/uboot/Makefile ============================================================================== --- head/sys/boot/arm/uboot/Makefile Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/arm/uboot/Makefile Wed Nov 19 17:34:28 2008 (r185099) @@ -10,8 +10,8 @@ WARNS?= 1 # Architecture-specific loader code SRCS= start.S conf.c vers.c -LOADER_DISK_SUPPORT?= no -LOADER_UFS_SUPPORT?= no +LOADER_DISK_SUPPORT?= yes +LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no LOADER_NET_SUPPORT?= yes Modified: head/sys/boot/arm/uboot/conf.c ============================================================================== --- head/sys/boot/arm/uboot/conf.c Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/arm/uboot/conf.c Wed Nov 19 17:34:28 2008 (r185099) @@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$"); struct devsw *devsw[] = { #if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) - &uboot_disk, + &uboot_storage, #endif #if defined(LOADER_NET_SUPPORT) &netdev, Modified: head/sys/boot/arm/uboot/version ============================================================================== --- head/sys/boot/arm/uboot/version Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/arm/uboot/version Wed Nov 19 17:34:28 2008 (r185099) @@ -3,4 +3,5 @@ $FreeBSD$ 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.0: Added storage support. Booting from HDD, USB, etc. is now possible. 0.5: Initial U-Boot/arm version (netbooting only). Modified: head/sys/boot/uboot/lib/devicename.c ============================================================================== --- head/sys/boot/uboot/lib/devicename.c Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/uboot/lib/devicename.c Wed Nov 19 17:34:28 2008 (r185099) @@ -64,7 +64,7 @@ uboot_getdev(void **vdev, const char *de /* * Try to parse the device name off the beginning of the devspec. */ - return(uboot_parsedev(dev, devspec, path)); + return (uboot_parsedev(dev, devspec, path)); } /* @@ -78,7 +78,7 @@ uboot_getdev(void **vdev, const char *de * * For disk-type devices, the syntax is: * - * disk<unit>[s<slice>][<partition>]: + * disk<unit>[<partition>]: * */ static int @@ -86,10 +86,10 @@ uboot_parsedev(struct uboot_devdesc **de const char **path) { struct uboot_devdesc *idev; - struct devsw *dv; - char *cp; - const char *np; - int i, unit, slice, partition, err; + struct devsw *dv; + char *cp; + const char *np; + int i, unit, partition, err; /* minimum length check */ if (strlen(devspec) < 2) @@ -110,12 +110,11 @@ uboot_parsedev(struct uboot_devdesc **de np = (devspec + strlen(dv->dv_name)); switch(dv->dv_type) { - case DEVT_NONE: /* XXX what to do here? Do we care? */ + case DEVT_NONE: break; case DEVT_DISK: unit = -1; - slice = -1; partition = -1; if (*np && (*np != ':')) { /* next comes the unit number */ @@ -124,16 +123,8 @@ uboot_parsedev(struct uboot_devdesc **de err = EUNIT; goto fail; } - if (*cp == 's') { /* got a slice number */ - np = cp + 1; - slice = strtol(np, &cp, 10); - if (cp == np) { - err = ESLICE; - goto fail; - } - } if (*cp && (*cp != ':')) { - /* get a partition number */ + /* get partition */ partition = *cp - 'a'; if ((partition < 0) || (partition >= MAXPARTITIONS)) { @@ -145,12 +136,12 @@ uboot_parsedev(struct uboot_devdesc **de } if (*cp && (*cp != ':')) { err = EINVAL; - goto fail; + goto fail; } idev->d_unit = unit; - idev->d_kind.disk.slice = slice; - idev->d_kind.disk.partition = partition; + idev->d_disk.partition = partition; + idev->d_disk.data = NULL; if (path != NULL) *path = (*cp == 0) ? cp : cp + 1; break; @@ -170,9 +161,7 @@ uboot_parsedev(struct uboot_devdesc **de err = EINVAL; goto fail; } - - if (dv->dv_type == DEVT_NET) - idev->d_unit = unit; + idev->d_unit = unit; if (path != NULL) *path = (*cp == 0) ? cp : cp + 1; @@ -212,8 +201,6 @@ uboot_fmtdev(void *vdev) case DEVT_DISK: cp = buf; cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_unit); - if (dev->d_kind.disk.slice > 0) - cp += sprintf(cp, "s%d", dev->d_kind.disk.slice); if (dev->d_kind.disk.partition >= 0) cp += sprintf(cp, "%c", dev->d_kind.disk.partition + 'a'); Modified: head/sys/boot/uboot/lib/disk.c ============================================================================== --- head/sys/boot/uboot/lib/disk.c Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/uboot/lib/disk.c Wed Nov 19 17:34:28 2008 (r185099) @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2000 Benno Rice. + * Copyright (c) 2008 Semihalf, Rafal Jaworowski * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,99 +11,453 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - /* - * Disk I/O routines using U-Boot - TODO + * Block storage I/O routines for U-Boot */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <sys/param.h> #include <sys/queue.h> - #include <netinet/in.h> #include <machine/stdarg.h> #include <stand.h> +#include <uuid.h> + +#define FSTYPENAMES +#include <sys/disklabel.h> +#include "api_public.h" #include "bootstrap.h" +#include "glue.h" +#include "libuboot.h" -static int d_init(void); -static int d_strategy(void *devdata, int flag, daddr_t dblk, - size_t size, char *buf, size_t *rsize); -static int d_open(struct open_file *f, ...); -static int d_close(struct open_file *f); -static int d_ioctl(struct open_file *f, u_long cmd, void *data); -static void d_print(int verbose); +#define DEBUG +#undef DEBUG -struct devsw uboot_disk = { - "block", - DEVT_DISK, - d_init, - d_strategy, - d_open, - d_close, - d_ioctl, - d_print +#define stor_printf(fmt, args...) do { \ + 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) +#else +#define debugf(fmt, args...) +#endif + +struct gpt_part { + int gp_index; + uuid_t gp_type; + uint64_t gp_start; + uint64_t gp_end; }; -struct opened_dev { - u_int count; - SLIST_ENTRY(opened_dev) link; +struct open_dev { + int od_bsize; /* block size */ + int od_bstart; /* start block offset from beginning of disk */ + int od_type; +#define OD_BSDLABEL 0x0001 +#define OD_GPT 0x0002 + union { + struct { + struct disklabel bsdlabel; + } _bsd; + struct { + struct gpt_part *gpt_partitions; + int gpt_nparts; + } _gpt; + } _data; }; -SLIST_HEAD(, opened_dev) opened_devs = SLIST_HEAD_INITIALIZER(opened_dev); +#define od_bsdlabel _data._bsd.bsdlabel +#define od_nparts _data._gpt.gpt_nparts +#define od_partitions _data._gpt.gpt_partitions + +static int stor_info[UB_MAX_DEV]; +static int stor_info_no = 0; +static int stor_opendev(struct open_dev **, struct uboot_devdesc *); +static int stor_closedev(struct uboot_devdesc *); +static int stor_readdev(struct uboot_devdesc *, daddr_t, size_t, char *); +static int stor_open_count = 0; + +/* devsw I/F */ +static int stor_init(void); +static int stor_strategy(void *, int, daddr_t, size_t, char *, size_t *); +static int stor_open(struct open_file *, ...); +static int stor_close(struct open_file *); +static void stor_print(int); + +struct devsw uboot_storage = { + "disk", + DEVT_DISK, + stor_init, + stor_strategy, + stor_open, + stor_close, + noioctl, + stor_print +}; static int -d_init(void) +stor_init(void) { + struct device_info *di; + int i, found = 0; + + if (devs_no == 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++] = i; + found = 1; + } + } + + if (!found) { + printf("No storage devices\n"); + return (-1); + } - return 0; + debugf("storage devices found: %d\n", stor_info_no); + return (0); } static int -d_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, +stor_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize) { + struct uboot_devdesc *dev = (struct uboot_devdesc *)devdata; + struct open_dev *od = (struct open_dev *)dev->d_disk.data; + int bcount, err; + + debugf("od=%p, size=%d, bsize=%d\n", od, size, od->od_bsize); + + if (rw != F_READ) { + stor_printf("write attempt, operation not supported!\n"); + return (EROFS); + } + + if (size % od->od_bsize) { + stor_printf("size=%d not multiple of device block size=%d\n", + size, od->od_bsize); + return (EIO); + } + bcount = size / od->od_bsize; + + if (rsize) + *rsize = 0; + + err = stor_readdev(dev, blk + od->od_bstart, bcount, buf); + if (!err && rsize) + *rsize = size; - return (EINVAL); + return (err); } static int -d_open(struct open_file *f, ...) +stor_open(struct open_file *f, ...) { + va_list ap; + struct open_dev *od; + struct uboot_devdesc *dev; + int err; - return (EINVAL); + va_start(ap, f); + dev = va_arg(ap, struct uboot_devdesc *); + va_end(ap); + + if ((err = stor_opendev(&od, dev)) != 0) + return (err); + + ((struct uboot_devdesc *)(f->f_devdata))->d_disk.data = od; + + return (0); +} + +static int +stor_close(struct open_file *f) +{ + struct uboot_devdesc *dev; + + dev = (struct uboot_devdesc *)(f->f_devdata); + + return (stor_closedev(dev)); } static int -d_close(struct open_file *f) +stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev) { - return (EINVAL); + /* TODO */ + return (ENXIO); } static int -d_ioctl(struct open_file *f, u_long cmd, void *data) +stor_open_bsdlabel(struct open_dev *od, struct uboot_devdesc *dev) +{ + char *buf; + struct disklabel *dl; + int err = 0; + + /* Allocate 1 block */ + buf = malloc(od->od_bsize); + if (!buf) { + stor_printf("could not allocate memory for disklabel\n"); + return (ENOMEM); + } + + /* Read disklabel */ + err = stor_readdev(dev, LABELSECTOR, 1, buf); + if (err) { + stor_printf("disklabel read error=%d\n", err); + err = ERDLAB; + goto out; + } + bcopy(buf + LABELOFFSET, &od->od_bsdlabel, sizeof(struct disklabel)); + dl = &od->od_bsdlabel; + + if (dl->d_magic != DISKMAGIC) { + stor_printf("no disklabel magic!\n"); + err = EUNLAB; + goto out; + } + od->od_type = OD_BSDLABEL; + od->od_bstart = dl->d_partitions[dev->d_disk.partition].p_offset; + + debugf("bstart=%d\n", od->od_bstart); + +out: + free(buf); + return (err); +} + +static int +stor_readdev(struct uboot_devdesc *dev, daddr_t blk, size_t size, char *buf) +{ + lbasize_t real_size; + int err, handle; + + debugf("reading size=%d @ 0x%08x\n", size, (uint32_t)buf); + + handle = stor_info[dev->d_unit]; + err = ub_dev_read(handle, 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); +} + + +static int +stor_opendev(struct open_dev **odp, struct uboot_devdesc *dev) +{ + struct device_info *di; + struct open_dev *od; + int err, h; + + h = stor_info[dev->d_unit]; + + debugf("refcount=%d\n", stor_open_count); + + /* + * There can be recursive open calls from the infrastructure, but at + * U-Boot level open the device only the first time. + */ + if (stor_open_count > 0) + stor_open_count++; + else if ((err = ub_dev_open(h)) != 0) { + stor_printf("device open failed with error=%d, handle=%d\n", + err, h); + *odp = NULL; + return (ENXIO); + } + + if ((di = ub_dev_get(h)) == NULL) + panic("could not retrieve U-Boot device_info, handle=%d", h); + + if ((od = malloc(sizeof(struct open_dev))) == NULL) { + stor_printf("could not allocate memory for open_dev\n"); + return (ENOMEM); + } + od->od_bsize = di->di_stor.block_size; + od->od_bstart = 0; + od->od_type = 0; + + if ((err = stor_open_gpt(od, dev)) != 0) + err = stor_open_bsdlabel(od, dev); + + if (err != 0) + free(od); + else { + stor_open_count = 1; + *odp = od; + } + + return (err); +} + +static int +stor_closedev(struct uboot_devdesc *dev) +{ + int err, h; + + free((struct open_dev *)dev->d_disk.data); + dev->d_disk.data = NULL; + + if (--stor_open_count == 0) { + h = stor_info[dev->d_unit]; + if ((err = ub_dev_close(h)) != 0) { + stor_printf("device close failed with error=%d, " + "handle=%d\n", err, h); + return (ENXIO); + } + } + + return (0); +} + +/* Given a size in 512 byte sectors, convert it to a human-readable number. */ +/* XXX stolen from sys/boot/i386/libi386/biosdisk.c, should really be shared */ +static char * +display_size(uint64_t size) +{ + static char buf[80]; + char unit; + + size /= 2; + unit = 'K'; + if (size >= 10485760000LL) { + size /= 1073741824; + unit = 'T'; + } else if (size >= 10240000) { + size /= 1048576; + unit = 'G'; + } else if (size >= 10000) { + size /= 1024; + unit = 'M'; + } + sprintf(buf, "%.6ld%cB", (long)size, unit); + return (buf); +} + +static void +stor_print_bsdlabel(struct uboot_devdesc *dev, char *prefix, int verbose) +{ + char buf[512], line[80]; + struct disklabel *dl; + uint32_t off, size; + int err, i, t; + + /* Read disklabel */ + err = stor_readdev(dev, LABELSECTOR, 1, buf); + if (err) { + sprintf(line, "%s%d: disklabel read error=%d\n", + dev->d_dev->dv_name, dev->d_unit, err); + pager_output(line); + return; + } + dl = (struct disklabel *)buf; + + if (dl->d_magic != DISKMAGIC) { + sprintf(line, "%s%d: no disklabel magic!\n", + dev->d_dev->dv_name, dev->d_unit); + pager_output(line); + return; + } + + /* Print partitions info */ + for (i = 0; i < dl->d_npartitions; i++) { + if ((t = dl->d_partitions[i].p_fstype) < FSMAXTYPES) { + + off = dl->d_partitions[i].p_offset; + size = dl->d_partitions[i].p_size; + if (fstypenames[t] == NULL || size == 0) + continue; + + if ((('a' + i) == 'c') && (!verbose)) + continue; + + sprintf(line, " %s%c: %s %s (%d - %d)\n", prefix, + 'a' + i, fstypenames[t], display_size(size), + off, off + size); + + pager_output(line); + } + } +} + +static void +stor_print_one(int i, struct device_info *di, int verbose) { + struct uboot_devdesc dev; + struct open_dev *od; + char line[80]; + + sprintf(line, "\tdisk%d (%s)\n", i, ub_stor_type(di->type)); + pager_output(line); + + dev.d_dev = &uboot_storage; + dev.d_unit = i; + dev.d_disk.partition = -1; + dev.d_disk.data = NULL; + + if (stor_opendev(&od, &dev) == 0) { + dev.d_disk.data = od; + + if (od->od_type == OD_GPT) { + /* TODO */ + + } else if (od->od_type == OD_BSDLABEL) { + sprintf(line, "\t\tdisk%d", i); + stor_print_bsdlabel(&dev, line, verbose); + } - return (EINVAL); + stor_closedev(&dev); + } } static void -d_print(int verbose) +stor_print(int verbose) { + struct device_info *di; + int i; - return; + for (i = 0; i < stor_info_no; i++) { + di = ub_dev_get(stor_info[i]); + if (di != NULL) + stor_print_one(i, di, verbose); + } } Modified: head/sys/boot/uboot/lib/glue.c ============================================================================== --- head/sys/boot/uboot/lib/glue.c Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/uboot/lib/glue.c Wed Nov 19 17:34:28 2008 (r185099) @@ -454,7 +454,7 @@ ub_dev_send(int handle, void *buf, int l return (err); } -static char * +char * ub_stor_type(int type) { Modified: head/sys/boot/uboot/lib/glue.h ============================================================================== --- head/sys/boot/uboot/lib/glue.h Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/uboot/lib/glue.h Wed Nov 19 17:34:28 2008 (r185099) @@ -81,5 +81,6 @@ struct device_info *ub_dev_get(int); void ub_dump_di(int); void ub_dump_si(struct sys_info *); char *ub_mem_type(int); +char *ub_stor_type(int); #endif /* _API_GLUE_H_ */ Modified: head/sys/boot/uboot/lib/libuboot.h ============================================================================== --- head/sys/boot/uboot/lib/libuboot.h Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/uboot/lib/libuboot.h Wed Nov 19 17:34:28 2008 (r185099) @@ -27,11 +27,6 @@ * $FreeBSD$ */ -/* - * Fully-qualified device descriptor. - * Note, this must match the 'struct devdesc' declaration - * in bootstrap.h. - */ struct uboot_devdesc { struct devsw *d_dev; @@ -40,28 +35,29 @@ struct uboot_devdesc union { struct { void *data; - int slice; int partition; } disk; } d_kind; }; +#define d_disk d_kind.disk + /* * Default network packet alignment in memory */ #define PKTALIGN 32 -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); +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); +extern int devs_no; extern struct netif_driver uboot_net; -extern struct devsw uboot_disk; +extern struct devsw uboot_storage; ssize_t uboot_copyin(const void *src, vm_offset_t dest, const size_t len); ssize_t uboot_copyout(const vm_offset_t src, void *dest, const size_t len); ssize_t uboot_readin(const int fd, vm_offset_t dest, const size_t len); - extern int uboot_autoload(void); struct preloaded_file; @@ -69,4 +65,4 @@ struct file_format; extern struct file_format uboot_elf; -void reboot(void); +void reboot(void); Modified: head/sys/boot/uboot/lib/net.c ============================================================================== --- head/sys/boot/uboot/lib/net.c Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/boot/uboot/lib/net.c Wed Nov 19 17:34:28 2008 (r185099) @@ -59,7 +59,6 @@ static int net_get(struct iodesc *, void static int net_put(struct iodesc *, void *, size_t); static void net_end(struct netif *); -extern int devs_no; extern struct netif_stats net_stats[]; struct netif_dif net_ifs[] = { Modified: head/sys/sys/disklabel.h ============================================================================== --- head/sys/sys/disklabel.h Wed Nov 19 17:07:01 2008 (r185098) +++ head/sys/sys/disklabel.h Wed Nov 19 17:34:28 2008 (r185099) @@ -52,7 +52,7 @@ /* XXX these should be defined per controller (or drive) elsewhere, not here! */ #if defined(__i386__) || defined(__amd64__) || defined(__arm__) || \ - defined(__ia64__) + defined(__ia64__) || defined(__powerpc__) #define LABELSECTOR 1 /* sector containing label */ #define LABELOFFSET 0 /* offset of label in sector */ #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811191734.mAJHYSCw023563>