summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_pc98.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-09-01 20:45:32 +0000
committerphk <phk@FreeBSD.org>2003-09-01 20:45:32 +0000
commit38290a3baa454204f887614a0b0f40532eebc605 (patch)
tree0680a0b284f441a10aeec166634f34c98f8d1389 /sys/geom/geom_pc98.c
parent4e64a48fd83170feaf276dab0b984c5fc41e3896 (diff)
downloadFreeBSD-src-38290a3baa454204f887614a0b0f40532eebc605.zip
FreeBSD-src-38290a3baa454204f887614a0b0f40532eebc605.tar.gz
Simplify the ioctl handling in GEOM.
This replaces the current ioctl processing with a direct call path from geom_dev() where the ioctl arrives (from SPECFS) to any directly connected GEOM class. The inverse of the above is no longer supported. This is the situation were you have one or more intervening GEOM classes, for instance a BSDlabel on top of a MBR or PC98. If you want to issue MBR or PC98 specific ioctls, you will need to issue them on a MBR or PC98 providers. This paves the way for inviting CD's, FD's and other special cases inside GEOM.
Diffstat (limited to 'sys/geom/geom_pc98.c')
-rw-r--r--sys/geom/geom_pc98.c72
1 files changed, 21 insertions, 51 deletions
diff --git a/sys/geom/geom_pc98.c b/sys/geom/geom_pc98.c
index b6d2c21..6be3ed9 100644
--- a/sys/geom/geom_pc98.c
+++ b/sys/geom/geom_pc98.c
@@ -134,39 +134,34 @@ g_pc98_modify(struct g_geom *gp, struct g_pc98_softc *ms, u_char *sec)
return (0);
}
-static void
-g_pc98_ioctl(void *arg, int flag)
+static int
+g_pc98_ioctl(struct g_provider *pp, u_long cmd, void *data, struct thread *td)
{
- struct bio *bp;
struct g_geom *gp;
- struct g_slicer *gsp;
struct g_pc98_softc *ms;
- struct g_ioctl *gio;
+ struct g_slicer *gsp;
struct g_consumer *cp;
- u_char *sec;
int error;
- bp = arg;
- if (flag == EV_CANCEL) {
- g_io_deliver(bp, ENXIO);
- return;
- }
- gp = bp->bio_to->geom;
+ gp = pp->geom;
gsp = gp->softc;
ms = gsp->softc;
- gio = (struct g_ioctl *)bp->bio_data;
- /* The disklabel to set is the ioctl argument. */
- sec = gio->data;
-
- error = g_pc98_modify(gp, ms, sec);
- if (error) {
- g_io_deliver(bp, error);
- return;
+ switch(cmd) {
+ case DIOCSPC98: {
+ DROP_GIANT();
+ g_topology_lock();
+ /* Validate and modify our slicer instance to match. */
+ error = g_pc98_modify(gp, ms, data);
+ cp = LIST_FIRST(&gp->consumer);
+ error = g_write_data(cp, 0, data, 8192);
+ g_topology_unlock();
+ PICKUP_GIANT();
+ return(error);
+ }
+ default:
+ return (ENOIOCTL);
}
- cp = LIST_FIRST(&gp->consumer);
- error = g_write_data(cp, 0, sec, 8192);
- g_io_deliver(bp, error);
}
static int
@@ -176,8 +171,7 @@ g_pc98_start(struct bio *bp)
struct g_geom *gp;
struct g_pc98_softc *mp;
struct g_slicer *gsp;
- struct g_ioctl *gio;
- int idx, error;
+ int idx;
pp = bp->bio_to;
idx = pp->index;
@@ -192,32 +186,7 @@ g_pc98_start(struct bio *bp)
return (1);
}
- /* We only handle ioctl(2) requests of the right format. */
- if (strcmp(bp->bio_attribute, "GEOM::ioctl"))
- return (0);
- else if (bp->bio_length != sizeof(*gio))
- return (0);
- /* Get hold of the ioctl parameters. */
- gio = (struct g_ioctl *)bp->bio_data;
-
- switch (gio->cmd) {
- case DIOCSPC98:
- /*
- * These we cannot do without the topology lock and some
- * some I/O requests. Ask the event-handler to schedule
- * us in a less restricted environment.
- */
- error = g_post_event(g_pc98_ioctl, bp, M_NOWAIT, gp, NULL);
- if (error)
- g_io_deliver(bp, error);
- /*
- * We must return non-zero to indicate that we will deal
- * with this bio, even though we have not done so yet.
- */
- return (1);
- default:
- return (0);
- }
+ return (0);
}
static void
@@ -270,6 +239,7 @@ g_pc98_taste(struct g_class *mp, struct g_provider *pp, int flags)
return (NULL);
g_topology_unlock();
gp->dumpconf = g_pc98_dumpconf;
+ gp->ioctl = g_pc98_ioctl;
do {
if (gp->rank != 2 && flags == G_TF_NORMAL)
break;
OpenPOWER on IntegriCloud