예제 #1
0
파일: gus_main.c 프로젝트: xricson/knoppix
static int snd_gus_free(snd_gus_card_t *gus)
{
	if (gus->gf1.res_port2 == NULL)
		goto __hw_end;
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
	if (gus->seq_dev) {
		snd_device_free(gus->card, gus->seq_dev);
		gus->seq_dev = NULL;
	}
#endif
	snd_gf1_stop(gus);
	snd_gus_init_dma_irq(gus, 0);
      __hw_end:
	if (gus->gf1.res_port1) {
		release_resource(gus->gf1.res_port1);
		kfree_nocheck(gus->gf1.res_port1);
	}
	if (gus->gf1.res_port2) {
		release_resource(gus->gf1.res_port2);
		kfree_nocheck(gus->gf1.res_port2);
	}
	if (gus->gf1.irq >= 0)
		free_irq(gus->gf1.irq, (void *) gus);
	if (gus->gf1.dma1 >= 0) {
		disable_dma(gus->gf1.dma1);
		free_dma(gus->gf1.dma1);
	}
	if (!gus->equal_dma && gus->gf1.dma2 >= 0) {
		disable_dma(gus->gf1.dma2);
		free_dma(gus->gf1.dma2);
	}
	snd_magic_kfree(gus);
	return 0;
}
예제 #2
0
static int snd_uart16550_free(snd_uart16550_t *uart)
{
	if (uart->irq >= 0)
		free_irq(uart->irq, (void *)uart);
	if (uart->res_base)
		release_resource(uart->res_base);
	snd_magic_kfree(uart);
	return 0;
};
예제 #3
0
파일: opl3_lib.c 프로젝트: xricson/knoppix
static int snd_opl3_free(opl3_t *opl3)
{
	if (opl3->res_l_port) {
		release_resource(opl3->res_l_port);
		kfree_nocheck(opl3->res_l_port);
	}
	if (opl3->res_r_port) {
		release_resource(opl3->res_r_port);
		kfree_nocheck(opl3->res_r_port);
	}
	snd_magic_kfree(opl3);
	return 0;
}
예제 #4
0
파일: emux_seq.c 프로젝트: xricson/knoppix
/*
 * release memory block for port
 */
static void
free_port(void *private_data)
{
	snd_emux_port_t *p;

	p = snd_magic_cast(snd_emux_port_t, private_data, return);
	if (p) {
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
		snd_emux_delete_effect(p);
#endif
		if (p->chset.channels)
			kfree(p->chset.channels);
		snd_magic_kfree(p);
	}
}
예제 #5
0
static int snd_vx222_free(vx_core_t *chip)
{
	int i;
	struct snd_vx222 *vx = (struct snd_vx222 *)chip;

	if (chip->irq >= 0)
		free_irq(chip->irq, (void*)chip);
	for (i = 0; i < 2; i++) {
		if (vx->port_res[i]) {
			release_resource(vx->port_res[i]);
			kfree_nocheck(vx->port_res[i]);
		}
	}
	snd_magic_kfree(chip);
	return 0;
}
예제 #6
0
파일: emux_seq.c 프로젝트: xricson/knoppix
snd_emux_port_t *
snd_emux_create_port(snd_emux_t *emu, char *name,
			int max_channels, int oss_port,
			snd_seq_port_callback_t *callback)
{
	snd_emux_port_t *p;
	int i, type, cap;

	/* Allocate structures for this channel */
	if ((p = snd_magic_kcalloc(snd_emux_port_t, 0, GFP_KERNEL)) == NULL) {
		snd_printk("no memory\n");
		return NULL;
	}
	p->chset.channels = snd_kcalloc(max_channels * sizeof(snd_midi_channel_t), GFP_KERNEL);
	if (p->chset.channels == NULL) {
		snd_printk("no memory\n");
		snd_magic_kfree(p);
		return NULL;
	}
	for (i = 0; i < max_channels; i++)
		p->chset.channels[i].number = i;
	p->chset.private_data = p;
	p->chset.max_channels = max_channels;
	p->emu = emu;
	p->chset.client = emu->client;
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
	snd_emux_create_effect(p);
#endif
	callback->private_free = free_port;
	callback->private_data = p;

	cap = SNDRV_SEQ_PORT_CAP_WRITE;
	if (oss_port) {
		type = SNDRV_SEQ_PORT_TYPE_SPECIFIC;
	} else {
		type = DEFAULT_MIDI_TYPE;
		cap |= SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
	}

	p->chset.port = snd_seq_event_port_attach(emu->client, callback,
						  cap, type, max_channels,
						  emu->max_voices, name);

	return p;
}
예제 #7
0
파일: info.c 프로젝트: OS2World/DRV-UNIAUD
static int snd_info_entry_release(struct inode *inode, struct file *file)
{
	snd_info_entry_t *entry;
	snd_info_private_data_t *data;
	int mode;

	mode = file->f_flags & O_ACCMODE;
	data = snd_magic_cast(snd_info_private_data_t, file->private_data, return -ENXIO);
	entry = data->entry;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_TEXT:
		if (mode == O_RDONLY || mode == O_RDWR) {
			vfree(data->rbuffer->buffer);
			kfree(data->rbuffer);
		}
		if (mode == O_WRONLY || mode == O_RDWR) {
			if (entry->c.text.write) {
				entry->c.text.write(entry, data->wbuffer);
				if (data->wbuffer->error) {
					snd_printk("data write error to %s (%i)\n",
						entry->name,
						data->wbuffer->error);
				}
			}
			vfree(data->wbuffer->buffer);
			kfree(data->wbuffer);
		}
		break;
	case SNDRV_INFO_CONTENT_DATA:
		if (entry->c.ops->release)
			entry->c.ops->release(entry, mode,
					      data->file_private_data);
		break;
	}
	dec_mod_count(entry->module);
#ifndef LINUX_2_3
	MOD_DEC_USE_COUNT;
#endif
	snd_magic_kfree(data);
	return 0;
}
예제 #8
0
파일: info.c 프로젝트: OS2World/DRV-UNIAUD
static int snd_info_entry_open(struct inode *inode, struct file *file)
{
	snd_info_entry_t *entry;
	snd_info_private_data_t *data;
	snd_info_buffer_t *buffer;
	struct proc_dir_entry *p;
	int mode, err;

	down(&info_mutex);
	p = (struct proc_dir_entry *) inode->u.generic_ip;
	entry = p == NULL ? NULL : (snd_info_entry_t *)p->data;
	if (entry == NULL) {
		up(&info_mutex);
		return -ENODEV;
	}
#ifndef LINUX_2_3
	MOD_INC_USE_COUNT;
#endif
	if (entry->module && !try_inc_mod_count(entry->module)) {
		err = -EFAULT;
		goto __error1;
	}
	mode = file->f_flags & O_ACCMODE;
	if (mode == O_RDONLY || mode == O_RDWR) {
		if ((entry->content == SNDRV_INFO_CONTENT_TEXT &&
		     !entry->c.text.read_size) ||
		    (entry->content == SNDRV_INFO_CONTENT_DATA &&
		     entry->c.ops->read == NULL) ||
		    entry->content == SNDRV_INFO_CONTENT_DEVICE) {
		    	err = -ENODEV;
		    	goto __error;
		}
	}
	if (mode == O_WRONLY || mode == O_RDWR) {
		if ((entry->content == SNDRV_INFO_CONTENT_TEXT &&
					!entry->c.text.write_size) ||
		    (entry->content == SNDRV_INFO_CONTENT_DATA &&
		    			entry->c.ops->write == NULL) ||
		    entry->content == SNDRV_INFO_CONTENT_DEVICE) {
		    	err = -ENODEV;
		    	goto __error;
		}
	}
	data = snd_magic_kcalloc(snd_info_private_data_t, 0, GFP_KERNEL);
	if (data == NULL) {
		err = -ENOMEM;
		goto __error;
	}
	data->entry = entry;
	switch (entry->content) {
	case SNDRV_INFO_CONTENT_TEXT:
		if (mode == O_RDONLY || mode == O_RDWR) {
			buffer = (snd_info_buffer_t *)
				 	snd_kcalloc(sizeof(snd_info_buffer_t), GFP_KERNEL);
			if (buffer == NULL) {
				snd_magic_kfree(data);
				err = -ENOMEM;
				goto __error;
			}
			buffer->len = (entry->c.text.read_size +
				      (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
			buffer->buffer = vmalloc(buffer->len);
			if (buffer->buffer == NULL) {
				kfree(buffer);
				snd_magic_kfree(data);
				err = -ENOMEM;
				goto __error;
			}
			buffer->curr = buffer->buffer;
			data->rbuffer = buffer;
		}
		if (mode == O_WRONLY || mode == O_RDWR) {
			buffer = (snd_info_buffer_t *)
					snd_kcalloc(sizeof(snd_info_buffer_t), GFP_KERNEL);
			if (buffer == NULL) {
				if (mode == O_RDWR) {
					vfree(data->rbuffer->buffer);
					kfree(data->rbuffer);
				}
				snd_magic_kfree(data);
				err = -ENOMEM;
				goto __error;
			}
			buffer->len = (entry->c.text.write_size +
				      (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
			buffer->buffer = vmalloc(buffer->len);
			if (buffer->buffer == NULL) {
				if (mode == O_RDWR) {
					vfree(data->rbuffer->buffer);
					kfree(data->rbuffer);
				}
				kfree(buffer);
				snd_magic_kfree(data);
				err = -ENOMEM;
				goto __error;
			}
			buffer->curr = buffer->buffer;
			data->wbuffer = buffer;
		}
		break;
	case SNDRV_INFO_CONTENT_DATA:	/* data */
		if (entry->c.ops->open) {
			if ((err = entry->c.ops->open(entry, mode,
						      &data->file_private_data)) < 0) {
				snd_magic_kfree(data);
				goto __error;
			}
		}
		break;
	}
	file->private_data = data;
	up(&info_mutex);
	if (entry->content == SNDRV_INFO_CONTENT_TEXT &&
	    (mode == O_RDONLY || mode == O_RDWR)) {
		if (entry->c.text.read) {
			down(&entry->access);
			entry->c.text.read(entry, data->rbuffer);
			up(&entry->access);
		}
	}
	return 0;

      __error:
	dec_mod_count(entry->module);
      __error1:
#ifndef LINUX_2_3
	MOD_DEC_USE_COUNT;
#endif
	up(&info_mutex);
	return err;
}