static int auich_detach(device_t self, int flags) { struct auich_softc *sc = device_private(self); /* audio */ if (sc->sc_audiodev != NULL) config_detach(sc->sc_audiodev, flags); /* sysctl */ sysctl_teardown(&sc->sc_log); mutex_enter(&sc->sc_lock); /* audio_encoding_set */ auconv_delete_encodings(sc->sc_encodings); auconv_delete_encodings(sc->sc_spdif_encodings); /* ac97 */ if (sc->codec_if != NULL) sc->codec_if->vtbl->detach(sc->codec_if); mutex_exit(&sc->sc_lock); mutex_destroy(&sc->sc_lock); mutex_destroy(&sc->sc_intr_lock); /* PCI */ if (sc->sc_ih != NULL) pci_intr_disestablish(sc->sc_pc, sc->sc_ih); if (sc->mix_size != 0) bus_space_unmap(sc->iot, sc->mix_ioh, sc->mix_size); if (sc->aud_size != 0) bus_space_unmap(sc->iot, sc->aud_ioh, sc->aud_size); return 0; }
static int auvia_detach(device_t self, int flags) { int rc; struct auvia_softc *sc = device_private(self); if ((rc = config_detach_children(self, flags)) != 0) return rc; pmf_device_deregister(self); mutex_enter(&sc->sc_lock); auconv_delete_encodings(sc->sc_encodings); auconv_delete_encodings(sc->sc_spdif_encodings); if (sc->codec_if != NULL) sc->codec_if->vtbl->detach(sc->codec_if); mutex_exit(&sc->sc_lock); /* XXX restore compatibility? */ if (sc->sc_ih != NULL) pci_intr_disestablish(sc->sc_pc, sc->sc_ih); bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize); if (sc->sc_play.sc_dma_ops != NULL) { auvia_free(sc, sc->sc_play.sc_dma_ops, sc->sc_play.sc_dma_op_count * sizeof(struct auvia_dma_op)); } if (sc->sc_record.sc_dma_ops != NULL) { auvia_free(sc, sc->sc_record.sc_dma_ops, sc->sc_play.sc_dma_op_count * sizeof(struct auvia_dma_op)); } mutex_destroy(&sc->sc_lock); mutex_destroy(&sc->sc_intr_lock); return 0; }