static int mfi_pci_detach(device_t dev) { struct mfi_softc *sc; int error, devcount, i; device_t *devlist; sc = device_get_softc(dev); sx_xlock(&sc->mfi_config_lock); mtx_lock(&sc->mfi_io_lock); if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) { mtx_unlock(&sc->mfi_io_lock); sx_xunlock(&sc->mfi_config_lock); return (EBUSY); } sc->mfi_detaching = 1; mtx_unlock(&sc->mfi_io_lock); if ((error = device_get_children(sc->mfi_dev, &devlist, &devcount)) != 0) { sx_xunlock(&sc->mfi_config_lock); return error; } for (i = 0; i < devcount; i++) device_delete_child(sc->mfi_dev, devlist[i]); free(devlist, M_TEMP); sx_xunlock(&sc->mfi_config_lock); EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh); mfi_shutdown(sc); mfi_free(sc); mfi_pci_free(sc); return (0); }
static int mfi_pci_detach(device_t dev) { struct mfi_softc *sc; struct mfi_disk *ld; int error; sc = device_get_softc(dev); sx_xlock(&sc->mfi_config_lock); mtx_lock(&sc->mfi_io_lock); if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) { mtx_unlock(&sc->mfi_io_lock); sx_xunlock(&sc->mfi_config_lock); return (EBUSY); } sc->mfi_detaching = 1; mtx_unlock(&sc->mfi_io_lock); while ((ld = TAILQ_FIRST(&sc->mfi_ld_tqh)) != NULL) { if ((error = device_delete_child(dev, ld->ld_dev)) != 0) { sc->mfi_detaching = 0; sx_xunlock(&sc->mfi_config_lock); return (error); } } sx_xunlock(&sc->mfi_config_lock); EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh); mfi_shutdown(sc); mfi_free(sc); mfi_pci_free(sc); return (0); }