static int vndclose(dev_t dev, int flags, int mode, struct lwp *l) { int unit = vndunit(dev); struct vnd_softc *sc; int error = 0, part; #ifdef DEBUG if (vnddebug & VDB_FOLLOW) printf("vndclose(0x%"PRIx64", 0x%x, 0x%x, %p)\n", dev, flags, mode, l); #endif sc = device_lookup_private(&vnd_cd, unit); if (sc == NULL) return ENXIO; if ((error = vndlock(sc)) != 0) return error; part = DISKPART(dev); /* ...that much closer to allowing unconfiguration... */ switch (mode) { case S_IFCHR: sc->sc_dkdev.dk_copenmask &= ~(1 << part); break; case S_IFBLK: sc->sc_dkdev.dk_bopenmask &= ~(1 << part); break; } sc->sc_dkdev.dk_openmask = sc->sc_dkdev.dk_copenmask | sc->sc_dkdev.dk_bopenmask; vndunlock(sc); if ((sc->sc_flags & VNF_INITED) == 0) { if ((error = vnd_destroy(sc->sc_dev)) != 0) { aprint_error_dev(sc->sc_dev, "unable to detach instance\n"); return error; } } return 0; }
static int vnd_lkm(struct lkm_table *lkmtp, int cmd) { int error = 0, i; device_t dev; if (cmd == LKM_E_LOAD) { error = config_cfdriver_attach(&vnd_cd); if (error) { aprint_error("%s: unable to register cfdriver\n", vnd_cd.cd_name); return error; } vndattach(0); } else if (cmd == LKM_E_UNLOAD) { for (i = 0; i < vnd_cd.cd_ndevs; i++) { dev = device_lookup(&vnd_cd, i); if (dev != NULL && (error = vnd_destroy(dev)) != 0) return 0; } if ((error = config_cfattach_detach(vnd_cd.cd_name, &vnd_ca)) != 0) { aprint_error("%s: unable to deregister cfattach\n", vnd_cd.cd_name); return error; } if ((error = config_cfdriver_detach(&vnd_cd)) != 0) { aprint_error("%s: unable to deregister cfdriver\n", vnd_cd.cd_name); return error; } } return (error); }