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,
+ §orsize) != 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, §orsize) != 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, §orsize);
- 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