/*
 * 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);
}
Exemple #3
0
/*
 * 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));
}