summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_disk.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-03-16 09:24:19 +0000
committerphk <phk@FreeBSD.org>2002-03-16 09:24:19 +0000
commit688687434f7b4bf689cb76a2bfdbcbc2b34bf03d (patch)
treedc23039ef707ddc22810bca9a45c7b8e4a21d815 /sys/geom/geom_disk.c
parent160859d70870af6d64ca201c85b7a15c6a0a0e46 (diff)
downloadFreeBSD-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.c42
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
OpenPOWER on IntegriCloud