/* * The audio module is itself a pseudo driver, as it contains the * logic to support un-associated nodes. (Think generic /dev/mixer * and /dev/sndstat used by OSS.) */ static int audio_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { audio_dev_t *adev; /* pseudo devices don't need S/R support */ if ((cmd != DDI_ATTACH) || (dip == NULL)) { return (DDI_FAILURE); } if (ddi_get_instance(dip) != 0) { return (DDI_FAILURE); } /* this can't fail */ adev = audio_dev_alloc(dip, 0); adev->d_flags = DEV_SNDSTAT_CAP; audio_dev_set_description(adev, "Audio Common Code"); audio_dev_set_version(adev, "pseudo"); ddi_set_driver_private(dip, adev); /* look up our properties! */ if (audio_dev_register(adev) != NULL) { audio_dev_free(adev); return (DDI_FAILURE); } ddi_report_dev(dip); return (DDI_SUCCESS); }
static int audio_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { audio_dev_t *adev; /* pseudo devices don't need S/R support */ if (cmd != DDI_DETACH) { return (DDI_FAILURE); } if (dip == NULL) { return (DDI_FAILURE); } if ((adev = ddi_get_driver_private(dip)) == NULL) { return (DDI_FAILURE); } if (audio_dev_unregister(adev) != DDI_SUCCESS) { return (DDI_FAILURE); } audio_dev_free(adev); return (DDI_SUCCESS); }
/* * audio1575_destroy() * * Description: * This routine releases all resources held by the device instance, * as part of either detach or a failure in attach. * * Arguments: * audio1575_state_t *state The device soft state. */ void audio1575_destroy(audio1575_state_t *statep) { ddi_acc_handle_t pcih; /* stop DMA engines */ audio1575_dma_stop(statep, B_FALSE); if (statep->regsh != NULL) { /* reset the codec */ PUT32(M1575_SCR_REG, M1575_SCR_COLDRST); } if ((pcih = statep->pcih) != NULL) { /* turn off the AC_LINK clock */ pci_config_put8(pcih, M1575_PCIACD_REG, 0); pci_config_put8(pcih, M1575_PCIACD_REG, 4); pci_config_put8(pcih, M1575_PCIACD_REG, 0); } /* Disable PCI I/O and Memory Spaces */ audio1575_pci_disable(statep); audio1575_free_port(statep->ports[M1575_PLAY]); audio1575_free_port(statep->ports[M1575_REC]); audio1575_unmap_regs(statep); if (statep->ac97 != NULL) { ac97_free(statep->ac97); } if (statep->adev != NULL) { audio_dev_free(statep->adev); } kmem_free(statep, sizeof (*statep)); }
/* * audioixp_destroy() * * Description: * This routine releases all resources held by the device instance, * as part of either detach or a failure in attach. * * Arguments: * audioixp_state_t *state The device soft state. */ void audioixp_destroy(audioixp_state_t *statep) { if (!statep->suspended) { PUT32(IXP_AUDIO_INT, GET32(IXP_AUDIO_INT)); PUT32(IXP_AUDIO_INT_EN, 0); /* * put the audio controller into quiet state, everything off */ CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA); CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA); } if (statep->intr_added) { ddi_remove_intr(statep->dip, 0, statep->iblock); } if (statep->ksp) { kstat_delete(statep->ksp); } audioixp_free_port(statep->play_port); audioixp_free_port(statep->rec_port); audioixp_unmap_regs(statep); if (statep->ac97) { ac97_free(statep->ac97); } if (statep->adev) { audio_dev_free(statep->adev); } mutex_destroy(&statep->inst_lock); kmem_free(statep, sizeof (*statep)); }