From owner-svn-src-user@FreeBSD.ORG Thu Jun 28 11:46:15 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 103C0106566B; Thu, 28 Jun 2012 11:46:15 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id ED8E78FC15; Thu, 28 Jun 2012 11:46:14 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q5SBkEHX073962; Thu, 28 Jun 2012 11:46:14 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q5SBkEpU073955; Thu, 28 Jun 2012 11:46:14 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201206281146.q5SBkEpU073955@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Thu, 28 Jun 2012 11:46:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r237704 - in user/ae/bootcode/sys/boot: powerpc/uboot uboot/common uboot/lib X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Jun 2012 11:46:15 -0000 Author: ae Date: Thu Jun 28 11:46:14 2012 New Revision: 237704 URL: http://svn.freebsd.org/changeset/base/237704 Log: Rename uboot's disk.c into storage.c. Use new API in the uboot's disk driver to get access to partition tables. Added: user/ae/bootcode/sys/boot/uboot/lib/storage.c - copied, changed from r237683, user/ae/bootcode/sys/boot/uboot/lib/disk.c Deleted: user/ae/bootcode/sys/boot/uboot/lib/disk.c Modified: user/ae/bootcode/sys/boot/powerpc/uboot/Makefile user/ae/bootcode/sys/boot/uboot/common/main.c user/ae/bootcode/sys/boot/uboot/lib/Makefile user/ae/bootcode/sys/boot/uboot/lib/devicename.c user/ae/bootcode/sys/boot/uboot/lib/libuboot.h Modified: user/ae/bootcode/sys/boot/powerpc/uboot/Makefile ============================================================================== --- user/ae/bootcode/sys/boot/powerpc/uboot/Makefile Thu Jun 28 11:15:48 2012 (r237703) +++ user/ae/bootcode/sys/boot/powerpc/uboot/Makefile Thu Jun 28 11:46:14 2012 (r237704) @@ -29,6 +29,12 @@ LOADER_FDT_SUPPORT= no .if ${LOADER_DISK_SUPPORT} == "yes" CFLAGS+= -DLOADER_DISK_SUPPORT +.if !defined(LOADER_NO_MBR_SUPPORT) +CFLAGS+= -DLOADER_MBR_SUPPORT +.endif +.if !defined(LOADER_NO_GPT_SUPPORT) +CFLAGS+= -DLOADER_GPT_SUPPORT +.endif .endif .if ${LOADER_UFS_SUPPORT} == "yes" CFLAGS+= -DLOADER_UFS_SUPPORT Modified: user/ae/bootcode/sys/boot/uboot/common/main.c ============================================================================== --- user/ae/bootcode/sys/boot/uboot/common/main.c Thu Jun 28 11:15:48 2012 (r237703) +++ user/ae/bootcode/sys/boot/uboot/common/main.c Thu Jun 28 11:46:14 2012 (r237704) @@ -185,7 +185,7 @@ main(void) if (strncmp(devsw[i]->dv_name, "disk", strlen(devsw[i]->dv_name)) == 0) { f.f_devdata = &currdev; - currdev.d_disk.pnum = 0; + currdev.d_kind.disk.slice = 0; if (devsw[i]->dv_open(&f,&currdev) == 0) break; } Modified: user/ae/bootcode/sys/boot/uboot/lib/Makefile ============================================================================== --- user/ae/bootcode/sys/boot/uboot/lib/Makefile Thu Jun 28 11:15:48 2012 (r237703) +++ user/ae/bootcode/sys/boot/uboot/lib/Makefile Thu Jun 28 11:46:14 2012 (r237704) @@ -6,8 +6,8 @@ LIB= uboot INTERNALLIB= WARNS?= 2 -SRCS= crc32.c console.c copy.c devicename.c disk.c elf_freebsd.c glue.c -SRCS+= module.c net.c reboot.c time.c +SRCS= crc32.c console.c copy.c devicename.c elf_freebsd.c glue.c +SRCS+= module.c net.c reboot.c storage.c time.c CFLAGS+= -ffreestanding -msoft-float Modified: user/ae/bootcode/sys/boot/uboot/lib/devicename.c ============================================================================== --- user/ae/bootcode/sys/boot/uboot/lib/devicename.c Thu Jun 28 11:15:48 2012 (r237703) +++ user/ae/bootcode/sys/boot/uboot/lib/devicename.c Thu Jun 28 11:46:14 2012 (r237704) @@ -27,12 +27,11 @@ #include __FBSDID("$FreeBSD$"); -#include - #include #include #include "bootstrap.h" +#include "disk.h" #include "libuboot.h" static int uboot_parsedev(struct uboot_devdesc **dev, const char *devspec, @@ -90,7 +89,7 @@ uboot_parsedev(struct uboot_devdesc **de struct devsw *dv; char *cp; const char *np; - int i, unit, pnum, ptype, err; + int i, unit, err; /* minimum length check */ if (strlen(devspec) < 2) @@ -115,49 +114,9 @@ uboot_parsedev(struct uboot_devdesc **de break; case DEVT_DISK: - unit = -1; - pnum = -1; - ptype = -1; - if (*np && (*np != ':')) { - /* next comes the unit number */ - unit = strtol(np, &cp, 10); - if (cp == np) { - err = EUNIT; - goto fail; - } - if (*cp && (*cp != ':')) { - /* get partition */ - if (*cp == 'p' && *(cp + 1) && - *(cp + 1) != ':') { - pnum = strtol(cp + 1, &cp, 10); - ptype = PTYPE_GPT; - } else if (*cp == 's' && *(cp + 1) && - *(cp + 1) != ':') { - pnum = strtol(cp + 1, &cp, 10); - ptype = PTYPE_MBR; - } else { - pnum = *cp - 'a'; - ptype = PTYPE_BSDLABEL; - if ((pnum < 0) || - (pnum >= MAXPARTITIONS)) { - err = EPART; - goto fail; - } - cp++; - } - } - } - if (*cp && (*cp != ':')) { - err = EINVAL; + err = disk_parsedev((struct disk_devdesc *)idev, np, path); + if (err != 0) goto fail; - } - - idev->d_unit = unit; - idev->d_disk.pnum = pnum; - idev->d_disk.ptype = ptype; - idev->d_disk.data = NULL; - if (path != NULL) - *path = (*cp == 0) ? cp : cp + 1; break; case DEVT_NET: @@ -204,7 +163,6 @@ char * uboot_fmtdev(void *vdev) { struct uboot_devdesc *dev = (struct uboot_devdesc *)vdev; - char *cp; static char buf[128]; switch(dev->d_type) { @@ -213,22 +171,7 @@ uboot_fmtdev(void *vdev) break; case DEVT_DISK: - cp = buf; - cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_unit); - if (dev->d_kind.disk.pnum >= 0) { - if (dev->d_kind.disk.ptype == PTYPE_BSDLABEL) - cp += sprintf(cp, "%c", - dev->d_kind.disk.pnum + 'a'); - else if (dev->d_kind.disk.ptype == PTYPE_GPT) - cp += sprintf(cp, "p%i", - dev->d_kind.disk.pnum); - else if (dev->d_kind.disk.ptype == PTYPE_MBR) - cp += sprintf(cp, "s%i", - dev->d_kind.disk.pnum); - } - - strcat(cp, ":"); - break; + return (disk_fmtdev(vdev)); case DEVT_NET: sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); Modified: user/ae/bootcode/sys/boot/uboot/lib/libuboot.h ============================================================================== --- user/ae/bootcode/sys/boot/uboot/lib/libuboot.h Thu Jun 28 11:15:48 2012 (r237703) +++ user/ae/bootcode/sys/boot/uboot/lib/libuboot.h Thu Jun 28 11:46:14 2012 (r237704) @@ -35,18 +35,13 @@ struct uboot_devdesc union { struct { void *data; - int pnum; - int ptype; + int slice; + int partition; + off_t offset; } disk; } d_kind; }; -#define d_disk d_kind.disk - -#define PTYPE_BSDLABEL 1 -#define PTYPE_GPT 2 -#define PTYPE_MBR 3 - /* * Default network packet alignment in memory */ Copied and modified: user/ae/bootcode/sys/boot/uboot/lib/storage.c (from r237683, user/ae/bootcode/sys/boot/uboot/lib/disk.c) ============================================================================== --- user/ae/bootcode/sys/boot/uboot/lib/disk.c Thu Jun 28 03:48:54 2012 (r237683, copy source) +++ user/ae/bootcode/sys/boot/uboot/lib/storage.c Thu Jun 28 11:46:14 2012 (r237704) @@ -34,20 +34,14 @@ __FBSDID("$FreeBSD$"); #include -#include -#include +#include #include #include #include -#include - -#define FSTYPENAMES -#include -#include -#include #include "api_public.h" #include "bootstrap.h" +#include "disk.h" #include "glue.h" #include "libuboot.h" @@ -66,51 +60,28 @@ __FBSDID("$FreeBSD$"); #define debugf(fmt, args...) #endif -struct gpt_part { - int gp_index; - uuid_t gp_type; - uint64_t gp_start; - uint64_t gp_end; -}; +static struct { + int opened; /* device open count */ + int handle; /* storage device handle */ + int type; /* storage type */ + off_t blocks; /* block count */ + u_int bsize; /* block size */ +} stor_info[UB_MAX_DEV]; -struct open_dev { - int od_bsize; /* block size */ - int od_bstart; /* start block offset from beginning of disk */ - union { - struct { - struct disklabel bsdlabel; - } _bsd; - struct { - struct gpt_part *gpt_partitions; - int gpt_nparts; - } _gpt; - } _data; -}; +#define SI(dev) (stor_info[(dev)->d_unit]) -#define od_bsdlabel _data._bsd.bsdlabel -#define od_nparts _data._gpt.gpt_nparts -#define od_partitions _data._gpt.gpt_partitions - -static uuid_t efi = GPT_ENT_TYPE_EFI; -static uuid_t freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT; -static uuid_t freebsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS; -static uuid_t freebsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP; -static uuid_t freebsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS; -static uuid_t ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA; - -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; +static int stor_opendev(struct disk_devdesc *); +static int stor_readdev(struct disk_devdesc *, daddr_t, size_t, char *); /* 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 int stor_ioctl(struct open_file *f, u_long cmd, void *data); static void stor_print(int); +static void stor_cleanup(void); struct devsw uboot_storage = { "disk", @@ -119,24 +90,16 @@ struct devsw uboot_storage = { stor_strategy, stor_open, stor_close, - noioctl, - stor_print + stor_ioctl, + stor_print, + stor_cleanup }; -static void -uuid_letoh(uuid_t *uuid) -{ - - uuid->time_low = le32toh(uuid->time_low); - uuid->time_mid = le16toh(uuid->time_mid); - uuid->time_hi_and_version = le16toh(uuid->time_hi_and_version); -} - static int stor_init(void) { struct device_info *di; - int i, found = 0; + int i; if (devs_no == 0) { printf("No U-Boot devices! Really enumerated?\n"); @@ -151,12 +114,17 @@ stor_init(void) stor_info_no); return (-1); } - stor_info[stor_info_no++] = i; - found = 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; } } - if (!found) { + if (!stor_info_no) { debugf("No storage devices\n"); return (-1); } @@ -165,32 +133,39 @@ stor_init(void) return (0); } +static void +stor_cleanup(void) +{ + int i; + + for (i = 0; i < stor_info_no; i++) + if (stor_info[i].opened > 0) + ub_dev_close(stor_info[i].handle); +} + static int 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); + struct disk_devdesc *dev = (struct disk_devdesc *)devdata; + daddr_t bcount; + int err; if (rw != F_READ) { stor_printf("write attempt, operation not supported!\n"); return (EROFS); } - if (size % od->od_bsize) { + if (size % SI(dev).bsize) { stor_printf("size=%d not multiple of device block size=%d\n", - size, od->od_bsize); + size, SI(dev).bsize); return (EIO); } - bcount = size / od->od_bsize; - + bcount = size / SI(dev).bsize; if (rsize) *rsize = 0; - err = stor_readdev(dev, blk + od->od_bstart, bcount, buf); + err = stor_readdev(dev, blk + dev->d_offset, bcount, buf); if (!err && rsize) *rsize = size; @@ -201,340 +176,54 @@ static int stor_open(struct open_file *f, ...) { va_list ap; - struct open_dev *od; - struct uboot_devdesc *dev; - int err; + struct disk_devdesc *dev; va_start(ap, f); - dev = va_arg(ap, struct uboot_devdesc *); + dev = va_arg(ap, struct disk_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)); + return (stor_opendev(dev)); } static int -stor_open_gpt(struct open_dev *od, struct uboot_devdesc *dev) +stor_opendev(struct disk_devdesc *dev) { - char *buf; - struct dos_partition *dp; - struct gpt_hdr *hdr; - struct gpt_ent *ent; - daddr_t slba, lba, elba; - int eps, part, i; - int err = 0; - - od->od_nparts = 0; - od->od_partitions = NULL; - - /* Devices with block size smaller than 512 bytes cannot use GPT */ - if (od->od_bsize < 512) - return (ENXIO); - - /* Allocate 1 block */ - buf = malloc(od->od_bsize); - if (!buf) { - stor_printf("could not allocate memory for GPT\n"); - return (ENOMEM); - } - - /* Read MBR */ - err = stor_readdev(dev, 0, 1, buf); - if (err) { - stor_printf("GPT read error=%d\n", err); - err = EIO; - goto out; - } - - /* Check the slice table magic. */ - if (le16toh(*((uint16_t *)(buf + DOSMAGICOFFSET))) != DOSMAGIC) { - err = ENXIO; - goto out; - } - - /* Check GPT slice */ - dp = (struct dos_partition *)(buf + DOSPARTOFF); - part = 0; - - for (i = 0; i < NDOSPART; i++) { - if (dp[i].dp_typ == 0xee) - part += 1; - else if (dp[i].dp_typ != 0x00) { - err = EINVAL; - goto out; - } - } - - if (part != 1) { - err = EINVAL; - goto out; - } - - /* Read primary GPT header */ - err = stor_readdev(dev, 1, 1, buf); - if (err) { - stor_printf("GPT read error=%d\n", err); - err = EIO; - goto out; - } - - hdr = (struct gpt_hdr *)buf; - - /* Check GPT header */ - if (bcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0 || - le64toh(hdr->hdr_lba_self) != 1 || - le32toh(hdr->hdr_revision) < 0x00010000 || - le32toh(hdr->hdr_entsz) < sizeof(*ent) || - od->od_bsize % le32toh(hdr->hdr_entsz) != 0) { - debugf("Invalid GPT header!\n"); - err = EINVAL; - goto out; - } - - /* Count number of valid partitions */ - part = 0; - eps = od->od_bsize / le32toh(hdr->hdr_entsz); - slba = le64toh(hdr->hdr_lba_table); - elba = slba + le32toh(hdr->hdr_entries) / eps; - - for (lba = slba; lba < elba; lba++) { - err = stor_readdev(dev, lba, 1, buf); - if (err) { - stor_printf("GPT read error=%d\n", err); - err = EIO; - goto out; - } - - ent = (struct gpt_ent *)buf; - - for (i = 0; i < eps; i++) { - if (uuid_is_nil(&ent[i].ent_type, NULL) || - le64toh(ent[i].ent_lba_start) == 0 || - le64toh(ent[i].ent_lba_end) < - le64toh(ent[i].ent_lba_start)) - continue; - - part += 1; - } - } - - /* Save information about partitions */ - if (part != 0) { - od->od_nparts = part; - od->od_partitions = malloc(part * sizeof(struct gpt_part)); - if (!od->od_partitions) { - stor_printf("could not allocate memory for GPT\n"); - err = ENOMEM; - goto out; - } - - part = 0; - for (lba = slba; lba < elba; lba++) { - err = stor_readdev(dev, lba, 1, buf); - if (err) { - stor_printf("GPT read error=%d\n", err); - err = EIO; - goto out; - } - - ent = (struct gpt_ent *)buf; - - for (i = 0; i < eps; i++) { - if (uuid_is_nil(&ent[i].ent_type, NULL) || - le64toh(ent[i].ent_lba_start) == 0 || - le64toh(ent[i].ent_lba_end) < - le64toh(ent[i].ent_lba_start)) - continue; - - od->od_partitions[part].gp_index = (lba - slba) - * eps + i + 1; - od->od_partitions[part].gp_type = - ent[i].ent_type; - od->od_partitions[part].gp_start = - le64toh(ent[i].ent_lba_start); - od->od_partitions[part].gp_end = - le64toh(ent[i].ent_lba_end); - - uuid_letoh(&od->od_partitions[part].gp_type); - part += 1; - } - } - } - - dev->d_disk.ptype = PTYPE_GPT; - /* - * If index of partition to open (dev->d_disk.pnum) is not defined - * we set it to the index of the first existing partition. This - * handles cases when only a disk device is specified (without full - * partition information) by the caller. - */ - if ((od->od_nparts > 0) && (dev->d_disk.pnum == 0)) - dev->d_disk.pnum = od->od_partitions[0].gp_index; - - for (i = 0; i < od->od_nparts; i++) - if (od->od_partitions[i].gp_index == dev->d_disk.pnum) - od->od_bstart = od->od_partitions[i].gp_start; - -out: - if (err && od->od_partitions) - free(od->od_partitions); - - free(buf); - return (err); -} - -static int -stor_open_mbr(struct open_dev *od, struct uboot_devdesc *dev) -{ - char *buf = NULL; - struct dos_partition *dp; - int err, i, part; - - od->od_nparts = 0; - od->od_partitions = NULL; - - /* Block size must be at least 512 bytes. */ - if (od->od_bsize < 512) - return (ENXIO); - - /* Read MBR */ - buf = malloc(od->od_bsize); - if (!buf) { - stor_printf("could not allocate memory for MBR\n"); - return (ENOMEM); - } - err = stor_readdev(dev, 0, 1, buf); - if (err) { - stor_printf("MBR read error=%d\n", err); - err = EIO; - goto out; - } - - /* Check the slice table magic. */ - if (le16toh(*((uint16_t *)(buf + DOSMAGICOFFSET))) != DOSMAGIC) { - err = ENXIO; - goto out; - } - - /* Save information about partitions. */ - dp = (struct dos_partition *)(buf + DOSPARTOFF); - od->od_partitions = calloc(NDOSPART, sizeof(struct gpt_part)); - if (!od->od_partitions) { - stor_printf("could not allocate memory for MBR partitions\n"); - err = ENOMEM; - goto out; - } + int err; - part = 0; - for (i = 0; i < NDOSPART; i++) { - u_int32_t start = le32dec(&dp[i].dp_start); - u_int32_t size = le32dec(&dp[i].dp_size); - uuid_t *u = NULL; - - /* Map MBR partition types to GPT partition types. */ - switch (dp[i].dp_typ) { - case DOSPTYP_386BSD: - u = &freebsd_ufs; - break; - /* XXX Other types XXX */ - } + if (dev->d_unit < 0 || dev->d_unit >= stor_info_no) + return (EIO); - if (u) { - od->od_partitions[part].gp_type = *u; - od->od_partitions[part].gp_index = i + 1; - od->od_partitions[part].gp_start = start; - od->od_partitions[part].gp_end = start + size; - part += 1; + if (SI(dev).opened == 0) { + err = ub_dev_open(SI(dev).handle); + if (err != 0) { + stor_printf("device open failed with error=%d, " + "handle=%d\n", err, SI(dev).handle); + return (ENXIO); } + SI(dev).opened++; } - od->od_nparts = part; - - if (od->od_nparts == 0) { - err = EINVAL; - goto out; - } - - dev->d_disk.ptype = PTYPE_MBR; - - /* XXX Be smarter here? XXX */ - if (dev->d_disk.pnum == 0) - dev->d_disk.pnum = od->od_partitions[0].gp_index; - - for (i = 0; i < od->od_nparts; i++) - if (od->od_partitions[i].gp_index == dev->d_disk.pnum) - od->od_bstart = od->od_partitions[i].gp_start; - -out: - if (err && od->od_partitions) - free(od->od_partitions); - free(buf); - return (err); + return (disk_open(dev, SI(dev).blocks * SI(dev).bsize, + SI(dev).bsize)); } static int -stor_open_bsdlabel(struct open_dev *od, struct uboot_devdesc *dev) +stor_close(struct open_file *f) { - 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); - } + struct disk_devdesc *dev; - /* 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_bstart = dl->d_partitions[dev->d_disk.pnum].p_offset; - dev->d_disk.ptype = PTYPE_BSDLABEL; - - debugf("bstart=%d\n", od->od_bstart); - -out: - free(buf); - return (err); + dev = (struct disk_devdesc *)(f->f_devdata); + return (disk_close(dev)); } static int -stor_readdev(struct uboot_devdesc *dev, daddr_t blk, size_t size, char *buf) +stor_readdev(struct disk_devdesc *dev, daddr_t blk, size_t size, char *buf) { lbasize_t real_size; - int err, handle; + int err; debugf("reading blk=%d size=%d @ 0x%08x\n", (int)blk, size, (uint32_t)buf); - handle = stor_info[dev->d_unit]; - err = ub_dev_read(handle, buf, size, blk, &real_size); + err = ub_dev_read(SI(dev).handle, buf, size, blk, &real_size); if (err != 0) { stor_printf("read failed, error=%d\n", err); return (EIO); @@ -549,228 +238,46 @@ stor_readdev(struct uboot_devdesc *dev, } -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; - - err = stor_open_gpt(od, dev); - if (err != 0) - err = stor_open_mbr(od, dev); - if (err != 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) -{ - struct open_dev *od; - int err, h; - - od = (struct open_dev *)dev->d_disk.data; - if (dev->d_disk.ptype == PTYPE_GPT && od->od_nparts != 0) - free(od->od_partitions); - if (dev->d_disk.ptype == PTYPE_MBR && od->od_nparts != 0) - free(od->od_partitions); - - free(od); - 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_gpt(struct uboot_devdesc *dev, char *prefix, int verbose) +stor_print(int verbose) { - struct open_dev *od = (struct open_dev *)dev->d_disk.data; - struct gpt_part *gp; - char line[80]; - char *fs; + struct disk_devdesc dev; + static char line[80]; int i; - for (i = 0; i < od->od_nparts; i++) { - gp = &od->od_partitions[i]; - - if (uuid_equal(&gp->gp_type, &efi, NULL)) - fs = "EFI"; - else if (uuid_equal(&gp->gp_type, &ms_basic_data, NULL)) - fs = "FAT/NTFS"; - else if (uuid_equal(&gp->gp_type, &freebsd_boot, NULL)) - fs = "FreeBSD Boot"; - else if (uuid_equal(&gp->gp_type, &freebsd_ufs, NULL)) - fs = "FreeBSD UFS"; - else if (uuid_equal(&gp->gp_type, &freebsd_swap, NULL)) - fs = "FreeBSD Swap"; - else if (uuid_equal(&gp->gp_type, &freebsd_zfs, NULL)) - fs = "FreeBSD ZFS"; - else - fs = "unknown"; - - sprintf(line, " %sp%u: %s %s (%lld - %lld)\n", prefix, - gp->gp_index, fs, - display_size(gp->gp_end + 1 - gp->gp_start), gp->gp_start, - gp->gp_end); - + for (i = 0; i < stor_info_no; i++) { + dev.d_dev = &uboot_storage; + dev.d_unit = i; + dev.d_slice = -1; + dev.d_partition = -1; + sprintf(line, "\tdisk%d (%s)\n", i, + ub_stor_type(SI(&dev).type)); pager_output(line); + if (stor_opendev(&dev) == 0) { + sprintf(line, "\tdisk%d", i); + disk_print(&dev, line, verbose); + disk_close(&dev); + } } } -static void -stor_print_one(int i, struct device_info *di, int verbose) +static int +stor_ioctl(struct open_file *f, u_long cmd, void *data) { - 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.pnum = -1; - dev.d_disk.data = NULL; - - if (stor_opendev(&od, &dev) == 0) { - dev.d_disk.data = od; - - if (dev.d_disk.ptype == PTYPE_GPT) { - sprintf(line, "\t\tdisk%d", i); - stor_print_gpt(&dev, line, verbose); - } else if (dev.d_disk.ptype == PTYPE_BSDLABEL) { - sprintf(line, "\t\tdisk%d", i); - stor_print_bsdlabel(&dev, line, verbose); - } + struct disk_devdesc *dev; - stor_closedev(&dev); + dev = (struct disk_devdesc *)f->f_devdata; + switch (cmd) { + case DIOCGSECTORSIZE: + *(u_int *)data = SI(dev).bsize; + break; + case DIOCGMEDIASIZE: + *(off_t *)data = SI(dev).bsize * SI(dev).blocks; + break; + default: + return (ENOTTY); } + return (0); } -static void -stor_print(int verbose) -{ - struct device_info *di; - int i; - for (i = 0; i < stor_info_no; i++) { - di = ub_dev_get(stor_info[i]); - if (di != NULL) - stor_print_one(i, di, verbose); - } -}