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
This commit is contained in:
parent
09a37b41c5
commit
bbcfaa4eb8
@ -232,6 +232,42 @@ disk_print(struct disk_devdesc *dev, char *prefix, int verbose)
|
|||||||
ptable_iterate(od->table, &pa, ptable_print);
|
ptable_iterate(od->table, &pa, ptable_print);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
int
|
||||||
disk_open(struct disk_devdesc *dev, off_t mediasize, u_int sectorsize,
|
disk_open(struct disk_devdesc *dev, off_t mediasize, u_int sectorsize,
|
||||||
u_int flags)
|
u_int flags)
|
||||||
|
@ -89,6 +89,11 @@ struct disk_devdesc
|
|||||||
off_t d_offset;
|
off_t d_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum disk_ioctl {
|
||||||
|
IOCTL_GET_BLOCKS,
|
||||||
|
IOCTL_GET_BLOCK_SIZE
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse disk metadata and initialise dev->d_offset.
|
* Parse disk metadata and initialise dev->d_offset.
|
||||||
*/
|
*/
|
||||||
@ -97,6 +102,11 @@ extern int disk_open(struct disk_devdesc *dev, off_t mediasize,
|
|||||||
#define DISK_F_NOCACHE 0x0001 /* Do not use metadata caching */
|
#define DISK_F_NOCACHE 0x0001 /* Do not use metadata caching */
|
||||||
extern int disk_close(struct disk_devdesc *dev);
|
extern int disk_close(struct disk_devdesc *dev);
|
||||||
extern void disk_cleanup(const struct devsw *d_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.
|
* Print information about slices on a disk.
|
||||||
|
@ -47,6 +47,7 @@ static int umass_disk_init(void);
|
|||||||
static int umass_disk_open(struct open_file *,...);
|
static int umass_disk_open(struct open_file *,...);
|
||||||
static int umass_disk_close(struct open_file *);
|
static int umass_disk_close(struct open_file *);
|
||||||
static void umass_disk_cleanup(void);
|
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 int umass_disk_strategy(void *, int, daddr_t, size_t, char *, size_t *);
|
||||||
static void umass_disk_print(int);
|
static void umass_disk_print(int);
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ struct devsw umass_disk = {
|
|||||||
.dv_strategy = umass_disk_strategy,
|
.dv_strategy = umass_disk_strategy,
|
||||||
.dv_open = umass_disk_open,
|
.dv_open = umass_disk_open,
|
||||||
.dv_close = umass_disk_close,
|
.dv_close = umass_disk_close,
|
||||||
.dv_ioctl = noioctl,
|
.dv_ioctl = umass_disk_ioctl,
|
||||||
.dv_print = umass_disk_print,
|
.dv_print = umass_disk_print,
|
||||||
.dv_cleanup = umass_disk_cleanup,
|
.dv_cleanup = umass_disk_cleanup,
|
||||||
};
|
};
|
||||||
@ -135,6 +136,30 @@ umass_disk_open(struct open_file *f,...)
|
|||||||
return (umass_disk_open_sub(dev));
|
return (umass_disk_open_sub(dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static int
|
||||||
umass_disk_close(struct open_file *f)
|
umass_disk_close(struct open_file *f)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user