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 <[email protected]>
  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;
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to