diff options
author | phk <phk@FreeBSD.org> | 2002-03-16 09:24:19 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2002-03-16 09:24:19 +0000 |
commit | 688687434f7b4bf689cb76a2bfdbcbc2b34bf03d (patch) | |
tree | dc23039ef707ddc22810bca9a45c7b8e4a21d815 /sys/geom/geom_disk.c | |
parent | 160859d70870af6d64ca201c85b7a15c6a0a0e46 (diff) | |
download | FreeBSD-src-688687434f7b4bf689cb76a2bfdbcbc2b34bf03d.zip FreeBSD-src-688687434f7b4bf689cb76a2bfdbcbc2b34bf03d.tar.gz |
Add a generic and general ioctl pass-through mechanism.
It should now be posible to issue ioctls to SCSI CD drives.
Diffstat (limited to 'sys/geom/geom_disk.c')
-rw-r--r-- | sys/geom/geom_disk.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c index 62da840..ed0b8be 100644 --- a/sys/geom/geom_disk.c +++ b/sys/geom/geom_disk.c @@ -115,9 +115,12 @@ g_disk_start(struct bio *bp) struct bio *bp2; dev_t dev; struct disk *dp; + struct g_ioctl *gio; + int error; dp = bp->bio_to->geom->softc; dev = dp->d_dev; + error = 0; switch(bp->bio_cmd) { case BIO_READ: case BIO_WRITE: @@ -134,27 +137,38 @@ g_disk_start(struct bio *bp) case BIO_GETATTR: if (g_haveattr_int(bp, "GEOM::sectorsize", dp->d_label.d_secsize)) - return; - if (g_haveattr_int(bp, "GEOM::fwsectors", + break; + else if (g_haveattr_int(bp, "GEOM::fwsectors", dp->d_label.d_nsectors)) - return; - if (g_haveattr_int(bp, "GEOM::fwheads", + break; + else if (g_haveattr_int(bp, "GEOM::fwheads", dp->d_label.d_ntracks)) - return; - if (g_haveattr_int(bp, "GEOM::fwcylinders", + break; + else if (g_haveattr_int(bp, "GEOM::fwcylinders", dp->d_label.d_ncylinders)) - return; - if (g_haveattr_off_t(bp, "GEOM::mediasize", + break; + else if (g_haveattr_off_t(bp, "GEOM::mediasize", dp->d_label.d_secsize * (off_t)dp->d_label.d_secperunit)) - return; - bp->bio_error = ENOIOCTL; - g_io_deliver(bp); - return; + break; + else if (!strcmp(bp->bio_attribute, "GEOM::ioctl") && + bp->bio_length == sizeof *gio) { + gio = (struct g_ioctl *)bp->bio_data; + mtx_lock(&Giant); + error = devsw(dev)->d_ioctl(dev, gio->cmd, + gio->data, gio->fflag, gio->td); + mtx_unlock(&Giant); + } else + error = ENOIOCTL; + break; default: - bp->bio_error = EOPNOTSUPP; + error = EOPNOTSUPP; + break; + } + if (error) { + bp->bio_error = error; g_io_deliver(bp); - return; } + return; } dev_t |