svn commit: r238518 - user/ae/bootcode/sys/boot/userboot/userboot

Andrey V. Elsukov ae at FreeBSD.org
Mon Jul 16 08:06:14 UTC 2012


Author: ae
Date: Mon Jul 16 08:06:13 2012
New Revision: 238518
URL: http://svn.freebsd.org/changeset/base/238518

Log:
  Add userdisk_info structure to keep information about disks.

Modified:
  user/ae/bootcode/sys/boot/userboot/userboot/userboot_disk.c

Modified: user/ae/bootcode/sys/boot/userboot/userboot/userboot_disk.c
==============================================================================
--- user/ae/bootcode/sys/boot/userboot/userboot/userboot_disk.c	Mon Jul 16 07:22:22 2012	(r238517)
+++ user/ae/bootcode/sys/boot/userboot/userboot/userboot_disk.c	Mon Jul 16 08:06:13 2012	(r238518)
@@ -39,9 +39,18 @@ __FBSDID("$FreeBSD$");
 #include "disk.h"
 #include "libuserboot.h"
 
+struct userdisk_info {
+	uint64_t	mediasize;
+	uint16_t	sectorsize;
+};
+
 int userboot_disk_maxunit = 0;
 
+static int userdisk_maxunit = 0;
+static struct userdisk_info	*ud_info;
+
 static int	userdisk_init(void);
+static void	userdisk_cleanup(void);
 static int	userdisk_strategy(void *devdata, int flag, daddr_t dblk,
 		    size_t size, char *buf, size_t *rsize);
 static int	userdisk_open(struct open_file *f, ...);
@@ -58,19 +67,45 @@ struct devsw userboot_disk = {
 	userdisk_close,
 	userdisk_ioctl,
 	userdisk_print,
-	NULL
+	userdisk_cleanup
 };
 
 /*
- * Nothing to do here.
+ * Initialize userdisk_info structure for each disk.
  */
 static int
 userdisk_init(void)
 {
+	off_t mediasize;
+	u_int sectorsize;
+	int i;
+
+	userdisk_maxunit = userboot_disk_maxunit;
+	if (userdisk_maxunit > 0) {
+		ud_info = malloc(sizeof(*ud_info) * userdisk_maxunit);
+		if (ud_info == NULL)
+			return (ENOMEM);
+		for (i = 0; i < userdisk_maxunit; i++) {
+			if (CALLBACK(diskioctl, i, DIOCGSECTORSIZE,
+			    &sectorsize) != 0 || CALLBACK(diskioctl, i,
+			    DIOCGMEDIASIZE, &mediasize) != 0)
+				return (ENXIO);
+			ud_info[i].mediasize = mediasize;
+			ud_info[i].sectorsize = sectorsize;
+		}
+	}
 
 	return(0);
 }
 
+static void
+userdisk_cleanup(void)
+{
+
+	if (userdisk_maxunit > 0)
+		free(ud_info);
+}
+
 /*
  * Print information about disks
  */
@@ -79,21 +114,17 @@ userdisk_print(int verbose)
 {
 	struct disk_devdesc dev;
 	char line[80];
-	off_t mediasize;
-	u_int sectorsize;
 	int i;
 
-	for (i = 0; i < userboot_disk_maxunit; i++) {
+	for (i = 0; i < userdisk_maxunit; i++) {
 		sprintf(line, "    disk%d:   Guest drive image\n", i);
 		pager_output(line);
-		if (CALLBACK(diskioctl, i, DIOCGSECTORSIZE, &sectorsize) != 0 ||
-		    CALLBACK(diskioctl, i, DIOCGMEDIASIZE, &mediasize) != 0)
-			continue;
 		dev.d_dev = &userboot_disk;
 		dev.d_unit = i;
 		dev.d_slice = -1;
 		dev.d_partition = -1;
-		if (disk_open(&dev, mediasize, sectorsize) == 0) {
+		if (disk_open(&dev, ud_info[i].mediasize,
+		    ud_info[i].sectorsize) == 0) {
 			sprintf(line, "    disk%d", i);
 			disk_print(&dev, line, verbose);
 			disk_close(&dev);
@@ -109,24 +140,16 @@ userdisk_open(struct open_file *f, ...)
 {
 	va_list			ap;
 	struct disk_devdesc	*dev;
-	u_int sectorsize;
-	off_t mediasize;
-	int rc;
 
 	va_start(ap, f);
 	dev = va_arg(ap, struct disk_devdesc *);
 	va_end(ap);
 
-	if (dev->d_unit < 0 || dev->d_unit >= userboot_disk_maxunit)
+	if (dev->d_unit < 0 || dev->d_unit >= userdisk_maxunit)
 		return (EIO);
 
-	rc = CALLBACK(diskioctl, dev->d_unit, DIOCGSECTORSIZE, &sectorsize);
-	if (rc != 0)
-		return (rc);
-	rc = CALLBACK(diskioctl, dev->d_unit, DIOCGMEDIASIZE, &mediasize);
-	if (rc != 0)
-		return (rc);
-	return (disk_open(dev, mediasize, sectorsize));
+	return (disk_open(dev, ud_info[dev->d_unit].mediasize,
+	    ud_info[dev->d_unit].sectorsize));
 }
 
 static int
@@ -153,7 +176,7 @@ userdisk_strategy(void *devdata, int rw,
 		return (EINVAL);
 	if (rsize)
 		*rsize = 0;
-	off = (dblk + dev->d_offset) * DISK_SECSIZE;
+	off = (dblk + dev->d_offset) * ud_info[dev->d_unit].sectorsize;
 	rc = CALLBACK(diskread, dev->d_unit, off, buf, size, &resid);
 	if (rc)
 		return (rc);


More information about the svn-src-user mailing list