Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Nov 2015 18:17:53 +0000 (UTC)
From:      Zbigniew Bodek <zbb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r291402 - in head/sys/boot: common usb/storage
Message-ID:  <201511271817.tARIHrfj019050@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zbb
Date: Fri Nov 27 18:17:53 2015
New Revision: 291402
URL: https://svnweb.freebsd.org/changeset/base/291402

Log:
  Implement simple ops for umass_disk
  
  The initial IOCTL implementation supports reading disk physical
  geometry.
  Two additional functions were added. They allow reading/writing raw
  data to the disk (default partition).
  
  Submitted by:  Wojciech Macek <wma@semihalf.com>
  Obtained from: Semihalf
  Sponsored by:  Juniper Networks Inc.
  Differential Revision: https://reviews.freebsd.org/D4143

Modified:
  head/sys/boot/common/disk.c
  head/sys/boot/common/disk.h
  head/sys/boot/usb/storage/umass_loader.c

Modified: head/sys/boot/common/disk.c
==============================================================================
--- head/sys/boot/common/disk.c	Fri Nov 27 18:16:10 2015	(r291401)
+++ head/sys/boot/common/disk.c	Fri Nov 27 18:17:53 2015	(r291402)
@@ -233,6 +233,42 @@ disk_print(struct disk_devdesc *dev, cha
 }
 
 int
+disk_read(struct disk_devdesc *dev, void *buf, off_t offset, u_int blocks)
+{
+	struct open_disk *od;
+	int ret;
+
+	od = (struct open_disk *)dev->d_opendata;
+	ret = dev->d_dev->dv_strategy(dev, F_READ, dev->d_offset + offset,
+	    blocks * od->sectorsize, buf, NULL);
+
+	return (ret);
+}
+
+int
+disk_write(struct disk_devdesc *dev, void *buf, off_t offset, u_int blocks)
+{
+	struct open_disk *od;
+	int ret;
+
+	od = (struct open_disk *)dev->d_opendata;
+	ret = dev->d_dev->dv_strategy(dev, F_WRITE, dev->d_offset + offset,
+	    blocks * od->sectorsize, buf, NULL);
+
+	return (ret);
+}
+
+int
+disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *buf)
+{
+
+	if (dev->d_dev->dv_ioctl)
+		return ((*dev->d_dev->dv_ioctl)(dev->d_opendata, cmd, buf));
+
+	return (ENXIO);
+}
+
+int
 disk_open(struct disk_devdesc *dev, off_t mediasize, u_int sectorsize,
     u_int flags)
 {

Modified: head/sys/boot/common/disk.h
==============================================================================
--- head/sys/boot/common/disk.h	Fri Nov 27 18:16:10 2015	(r291401)
+++ head/sys/boot/common/disk.h	Fri Nov 27 18:17:53 2015	(r291402)
@@ -89,6 +89,11 @@ struct disk_devdesc
 	off_t		d_offset;
 };
 
+enum disk_ioctl {
+	IOCTL_GET_BLOCKS,
+	IOCTL_GET_BLOCK_SIZE
+};
+
 /*
  * Parse disk metadata and initialise dev->d_offset.
  */
@@ -97,6 +102,11 @@ extern int disk_open(struct disk_devdesc
 #define	DISK_F_NOCACHE	0x0001		/* Do not use metadata caching */
 extern int disk_close(struct disk_devdesc *dev);
 extern void disk_cleanup(const struct devsw *d_dev);
+extern int disk_ioctl(struct disk_devdesc *dev, u_long cmd, void *buf);
+extern int disk_read(struct disk_devdesc *dev, void *buf, off_t offset,
+    u_int blocks);
+extern int disk_write(struct disk_devdesc *dev, void *buf, off_t offset,
+    u_int blocks);
 
 /*
  * Print information about slices on a disk.

Modified: head/sys/boot/usb/storage/umass_loader.c
==============================================================================
--- head/sys/boot/usb/storage/umass_loader.c	Fri Nov 27 18:16:10 2015	(r291401)
+++ head/sys/boot/usb/storage/umass_loader.c	Fri Nov 27 18:17:53 2015	(r291402)
@@ -47,6 +47,7 @@ static int umass_disk_init(void);
 static int umass_disk_open(struct open_file *,...);
 static int umass_disk_close(struct open_file *);
 static void umass_disk_cleanup(void);
+static int umass_disk_ioctl(struct open_file *, u_long, void *);
 static int umass_disk_strategy(void *, int, daddr_t, size_t, char *, size_t *);
 static void umass_disk_print(int);
 
@@ -57,7 +58,7 @@ struct devsw umass_disk = {
 	.dv_strategy = umass_disk_strategy,
 	.dv_open = umass_disk_open,
 	.dv_close = umass_disk_close,
-	.dv_ioctl = noioctl,
+	.dv_ioctl = umass_disk_ioctl,
 	.dv_print = umass_disk_print,
 	.dv_cleanup = umass_disk_cleanup,
 };
@@ -136,6 +137,30 @@ umass_disk_open(struct open_file *f,...)
 }
 
 static int
+umass_disk_ioctl(struct open_file *f __unused, u_long cmd, void *buf)
+{
+	uint32_t nblock;
+	uint32_t blocksize;
+
+	switch (cmd) {
+	case IOCTL_GET_BLOCK_SIZE:
+	case IOCTL_GET_BLOCKS:
+		if (usb_msc_read_capacity(umass_uaa.device, 0,
+		    &nblock, &blocksize) != 0)
+			return (EINVAL);
+
+		if (cmd == IOCTL_GET_BLOCKS)
+			*(uint32_t*)buf = nblock;
+		else
+			*(uint32_t*)buf = blocksize;
+
+		return (0);
+	default:
+		return (ENXIO);
+	}
+}
+
+static int
 umass_disk_close(struct open_file *f)
 {
 	struct disk_devdesc *dev;



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