Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Jun 2012 11:46:14 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r237704 - in user/ae/bootcode/sys/boot: powerpc/uboot uboot/common uboot/lib
Message-ID:  <201206281146.q5SBkEpU073955@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/disklabel.h>
-
 #include <stand.h>
 #include <string.h>
 
 #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 <sys/param.h>
-#include <sys/endian.h>
-#include <sys/queue.h>
+#include <sys/disk.h>
 #include <netinet/in.h>
 #include <machine/stdarg.h>
 #include <stand.h>
-#include <uuid.h>
-
-#define FSTYPENAMES
-#include <sys/disklabel.h>
-#include <sys/diskmbr.h>
-#include <sys/gpt.h>
 
 #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);
-	}
-}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206281146.q5SBkEpU073955>