/* create new fifo */
fifo_t *snd_seq_fifo_new(int poolsize)
{
	fifo_t *f;

	f = snd_kcalloc(sizeof(fifo_t), GFP_KERNEL);
	if (f == NULL) {
		snd_printd("malloc failed for snd_seq_fifo_new() \n");
		return NULL;
	}

	f->pool = snd_seq_pool_new(poolsize);
	if (f->pool == NULL) {
		kfree(f);
		return NULL;
	}
	if (snd_seq_pool_init(f->pool) < 0) {
		snd_seq_pool_delete(&f->pool);
		kfree(f);
		return NULL;
	}

	spin_lock_init(&f->lock);
	snd_use_lock_init(&f->use_lock);
	init_waitqueue_head(&f->input_sleep);
	atomic_set(&f->overflow, 0);

	f->head = NULL;
	f->tail = NULL;
	f->cells = 0;
	
	return f;
}
Exemplo n.º 2
0
/* allocate event chunk */
static snd_seq_event_chunk_t *snd_seq_chunk_allocate(int numcells)
{
	snd_seq_event_chunk_t *chunkptr;

	chunkptr = snd_kcalloc(sizeof(snd_seq_event_chunk_t) +
			       sizeof(snd_seq_event_cell_t) * numcells, GFP_KERNEL);
	if (chunkptr)
		chunkptr->cells = numcells;
	return chunkptr;
}
Exemplo n.º 3
0
static snd_info_entry_t *snd_info_create_entry(const char *name)
{
	snd_info_entry_t *entry;
	entry = (snd_info_entry_t *) snd_kcalloc(sizeof(snd_info_entry_t), GFP_KERNEL);
	if (entry == NULL)
		return NULL;
	entry->name = snd_kmalloc_strdup(name, GFP_KERNEL);
	if (entry->name == NULL) {
		kfree(entry);
		return NULL;
	}
	entry->mode = S_IFREG | S_IRUGO;
	entry->content = SNDRV_INFO_CONTENT_TEXT;
	init_MUTEX(&entry->access);
	return entry;
}
Exemplo n.º 4
0
/* create new prioq (constructor) */
prioq_t *snd_seq_prioq_new(void)
{
	prioq_t *f;

	f = snd_kcalloc(sizeof(prioq_t), GFP_KERNEL);
	if (f == NULL) {
		snd_printd("oops: malloc failed for snd_seq_prioq_new()\n");
		return NULL;
	}
	
	spin_lock_init(&f->lock);
	f->head = NULL;
	f->tail = NULL;
	f->cells = 0;
	
	return f;
}
Exemplo n.º 5
0
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;
}
/*
 * create and register a new timer.
 * if queue is not started yet, start it.
 */
seq_oss_timer_t *
snd_seq_oss_timer_new(seq_oss_devinfo_t *dp)
{
	seq_oss_timer_t *rec;

	rec = snd_kcalloc(sizeof(*rec), GFP_KERNEL);
	if (rec == NULL)
		return NULL;

	rec->dp = dp;
	rec->cur_tick = 0;
	rec->realtime = 0;
	rec->running = 0;
	rec->oss_tempo = 60;
	rec->oss_timebase = 100;
	calc_alsa_tempo(rec);

	return rec;
}
/* init new memory pool */
pool_t *snd_seq_pool_new(int poolsize)
{
	pool_t *pool;

	/* create pool block */
	pool = snd_kcalloc(sizeof(pool_t), GFP_KERNEL);
	if (pool == NULL) {
		snd_printd("seq: malloc failed for pool\n");
		return NULL;
	}
	spin_lock_init(&pool->lock);
	pool->ptr = NULL;
	pool->free = NULL;
	pool->total_elements = 0;
	atomic_set(&pool->counter, 0);
	pool->closing = 0;
	init_waitqueue_head(&pool->output_sleep);
	
	pool->size = poolsize;

	/* init statistics */
	pool->max_used = 0;
	return pool;
}
Exemplo n.º 8
0
/*
 * attach virtual rawmidi devices
 */
int snd_emux_init_virmidi(snd_emux_t *emu, snd_card_t *card)
{
	int i;

	emu->vmidi = NULL;
	if (emu->midi_ports <= 0)
		return 0;

	emu->vmidi = snd_kcalloc(sizeof(snd_rawmidi_t*) * emu->midi_ports, GFP_KERNEL);
	if (emu->vmidi == NULL)
		return -ENOMEM;

	for (i = 0; i < emu->midi_ports; i++) {
		snd_rawmidi_t *rmidi;
		snd_virmidi_dev_t *rdev;
		if (snd_virmidi_new(card, emu->midi_devidx + i, &rmidi) < 0)
			goto __error;
		rdev = snd_magic_cast(snd_virmidi_dev_t, rmidi->private_data, continue);
		sprintf(rmidi->name, "%s Synth MIDI", emu->name);
		rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
		rdev->client = emu->client;
		rdev->port = emu->ports[i];
		if (snd_device_register(card, rmidi) < 0) {
			snd_device_free(card, rmidi);
			goto __error;
		}
		emu->vmidi[i] = rmidi;
		//snd_printk("virmidi %d ok\n", i);
	}
	return 0;

__error:
	//snd_printk("error init..\n");
	snd_emux_delete_virmidi(emu);
	return -ENOMEM;
}
Exemplo n.º 9
0
/* register new midi synth port */
int
snd_seq_midisynth_register_port(snd_seq_device_t *dev)
{
	seq_midisynth_client_t *client;
	seq_midisynth_t *msynth, *ms;
	snd_seq_port_info_t port;
	snd_rawmidi_info_t info;
	int newclient = 0, p, ports;
	snd_seq_client_callback_t callbacks;
	snd_seq_port_callback_t pcallbacks;
	snd_seq_client_info_t inf;
	snd_card_t *card = dev->card;
	int device = dev->device;
	unsigned int input_count = 0, output_count = 0;

	snd_assert(card != NULL && device >= 0 && device < SNDRV_RAWMIDI_DEVICES, return -EINVAL);
	info.device = device;
	info.stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
	info.subdevice = 0;
	if (snd_rawmidi_info_select(card, &info) >= 0)
		output_count = info.subdevices_count;
	info.stream = SNDRV_RAWMIDI_STREAM_INPUT;
	if (snd_rawmidi_info_select(card, &info) >= 0) {
		input_count = info.subdevices_count;
	}
	ports = output_count;
	if (ports < input_count)
		ports = input_count;
	if (ports == 0)
		return -ENODEV;
	if (ports > (256 / SNDRV_RAWMIDI_DEVICES))
		ports = 256 / SNDRV_RAWMIDI_DEVICES;

	down(&register_mutex);
	client = synths[card->number];
	if (client == NULL) {
		newclient = 1;
		client = snd_kcalloc(sizeof(seq_midisynth_client_t), GFP_KERNEL);
		if (client == NULL) {
			up(&register_mutex);
			return -ENOMEM;
		}
		memset(&callbacks, 0, sizeof(callbacks));
		callbacks.private_data = client;
		callbacks.allow_input = callbacks.allow_output = 1;
		client->seq_client = snd_seq_create_kernel_client(card, 0, &callbacks);
		if (client->seq_client < 0) {
			kfree(client);
			up(&register_mutex);
			return -ENOMEM;
		}
		/* set our client name */
		memset(&inf,0,sizeof(snd_seq_client_info_t));
		inf.client = client->seq_client;
		inf.type = KERNEL_CLIENT;
		sprintf(inf.name, "External MIDI %i", card->number);
		snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &inf);
	}

	msynth = snd_kcalloc(sizeof(seq_midisynth_t) * ports, GFP_KERNEL);
	if (msynth == NULL)
		goto __nomem;

	for (p = 0; p < ports; p++) {
		ms = &msynth[p];

		if (snd_seq_midisynth_new(ms, card, device, p) < 0)
			goto __nomem;

		/* declare port */
		memset(&port, 0, sizeof(port));
		port.addr.client = client->seq_client;
		port.addr.port = device * (256 / SNDRV_RAWMIDI_DEVICES) + p;
		port.flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
		memset(&info, 0, sizeof(info));
		info.device = device;
		if (p < output_count)
			info.stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
		else
			info.stream = SNDRV_RAWMIDI_STREAM_INPUT;
		info.subdevice = p;
		if (snd_rawmidi_info_select(card, &info) >= 0)
			strcpy(port.name, info.subname);
		if (! port.name[0]) {
			if (ports > 1)
				sprintf(port.name, "MIDI %d-%d-%d", card->number, device, p);
			else
				sprintf(port.name, "MIDI %d-%d", card->number, device);
		}
		if ((info.flags & SNDRV_RAWMIDI_INFO_OUTPUT) && p < output_count)
			port.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
		if ((info.flags & SNDRV_RAWMIDI_INFO_INPUT) && p < input_count)
			port.capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
		if ((port.capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
		    info.flags & SNDRV_RAWMIDI_INFO_DUPLEX)
			port.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
		port.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
		port.midi_channels = 16;
		memset(&pcallbacks, 0, sizeof(pcallbacks));
		pcallbacks.owner = THIS_MODULE;
		pcallbacks.private_data = ms;
		pcallbacks.subscribe = midisynth_subscribe;
		pcallbacks.unsubscribe = midisynth_unsubscribe;
		pcallbacks.use = midisynth_use;
		pcallbacks.unuse = midisynth_unuse;
		pcallbacks.event_input = event_process_midi;
		port.kernel = &pcallbacks;
		if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, &port)<0)
			goto __nomem;
		ms->seq_client = client->seq_client;
		ms->seq_port = port.addr.port;
	}
	client->ports_per_device[device] = ports;
	client->ports[device] = msynth;
	client->num_ports++;
	if (newclient)
		synths[card->number] = client;
	up(&register_mutex);
	return 0;	/* success */

      __nomem:
	if (msynth != NULL) {
	      	for (p = 0; p < ports; p++)
	      		snd_seq_midisynth_delete(&msynth[p]);
		kfree(msynth);
	}
	if (newclient) {
		snd_seq_delete_kernel_client(client->seq_client);
		kfree(client);
	}
	up(&register_mutex);
	return -ENOMEM;
}
Exemplo n.º 10
0
static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops,
					     gf1_instrument_t *ip,
					     char **data,
					     long *len,
					     int atomic)
{
	gf1_wave_t *wp, *prev;
	gf1_xwave_t xp;
	int err, gfp_mask;
	unsigned int real_size;
	
	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
	if (*len < sizeof(xp))
		return -EINVAL;
	if (copy_from_user(&xp, *data, sizeof(xp)))
		return -EFAULT;
	*data += sizeof(xp);
	*len -= sizeof(xp);
	wp = (gf1_wave_t *)snd_kcalloc(sizeof(*wp), gfp_mask);
	if (wp == NULL)
		return -ENOMEM;
	wp->share_id[0] = le32_to_cpu(xp.share_id[0]);
	wp->share_id[1] = le32_to_cpu(xp.share_id[1]);
	wp->share_id[2] = le32_to_cpu(xp.share_id[2]);
	wp->share_id[3] = le32_to_cpu(xp.share_id[3]);
	wp->format = le32_to_cpu(xp.format);
	wp->size = le32_to_cpu(xp.size);
	wp->start = le32_to_cpu(xp.start);
	wp->loop_start = le32_to_cpu(xp.loop_start);
	wp->loop_end = le32_to_cpu(xp.loop_end);
	wp->loop_repeat = le16_to_cpu(xp.loop_repeat);
	wp->flags = xp.flags;
	wp->sample_rate = le32_to_cpu(xp.sample_rate);
	wp->low_frequency = le32_to_cpu(xp.low_frequency);
	wp->high_frequency = le32_to_cpu(xp.high_frequency);
	wp->root_frequency = le32_to_cpu(xp.root_frequency);
	wp->tune = le16_to_cpu(xp.tune);
	wp->balance = xp.balance;
	memcpy(wp->envelope_rate, xp.envelope_rate, 6);
	memcpy(wp->envelope_offset, xp.envelope_offset, 6);
	wp->tremolo_sweep = xp.tremolo_sweep;
	wp->tremolo_rate = xp.tremolo_rate;
	wp->tremolo_depth = xp.tremolo_depth;
	wp->vibrato_sweep = xp.vibrato_sweep;
	wp->vibrato_rate = xp.vibrato_rate;
	wp->vibrato_depth = xp.vibrato_depth;
	wp->scale_frequency = le16_to_cpu(xp.scale_frequency);
	wp->scale_factor = le16_to_cpu(xp.scale_factor);
	real_size = snd_seq_gf1_size(wp->size, wp->format);
	if (real_size > *len) {
		kfree(wp);
		return -ENOMEM;
	}
	if (ops->put_sample) {
		err = ops->put_sample(ops->private_data, wp,
				      *data, real_size, atomic);
		if (err < 0) {
			kfree(wp);
			return err;
		}
	}
	*data += real_size;
	*len -= real_size;
	prev = ip->wave;
	if (prev) {
		while (prev->next) prev = prev->next;
		prev->next = wp;
	} else {
		ip->wave = wp;
	}
	return 0;
}
Exemplo n.º 11
0
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;
}