⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 seq_clientmgr.c

📁 鼎力推荐!本程序是基于嵌入式LUNUX系统开发的源程序代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return snd_seq_queue_delete(client->number, info.queue);}/* GET_QUEUE_INFO ioctl() */static int snd_seq_ioctl_get_queue_info(client_t *client, void __user *arg){	snd_seq_queue_info_t info;	queue_t *q;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	q = queueptr(info.queue);	if (q == NULL)		return -EINVAL;	memset(&info, 0, sizeof(info));	info.queue = q->queue;	info.owner = q->owner;	info.locked = q->locked;	strlcpy(info.name, q->name, sizeof(info.name));	queuefree(q);	if (copy_to_user(arg, &info, sizeof(info)))		return -EFAULT;	return 0;}/* SET_QUEUE_INFO ioctl() */static int snd_seq_ioctl_set_queue_info(client_t *client, void __user *arg){	snd_seq_queue_info_t info;	queue_t *q;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	if (info.owner != client->number)		return -EINVAL;	/* change owner/locked permission */	if (snd_seq_queue_check_access(info.queue, client->number)) {		if (snd_seq_queue_set_owner(info.queue, client->number, info.locked) < 0)			return -EPERM;		if (info.locked)			snd_seq_queue_use(info.queue, client->number, 1);	} else {		return -EPERM;	}		q = queueptr(info.queue);	if (! q)		return -EINVAL;	if (q->owner != client->number) {		queuefree(q);		return -EPERM;	}	strlcpy(q->name, info.name, sizeof(q->name));	queuefree(q);	return 0;}/* GET_NAMED_QUEUE ioctl() */static int snd_seq_ioctl_get_named_queue(client_t *client, void __user *arg){	snd_seq_queue_info_t info;	queue_t *q;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	q = snd_seq_queue_find_name(info.name);	if (q == NULL)		return -EINVAL;	info.queue = q->queue;	info.owner = q->owner;	info.locked = q->locked;	queuefree(q);	if (copy_to_user(arg, &info, sizeof(info)))		return -EFAULT;	return 0;}/* GET_QUEUE_STATUS ioctl() */static int snd_seq_ioctl_get_queue_status(client_t * client, void __user *arg){	snd_seq_queue_status_t status;	queue_t *queue;	seq_timer_t *tmr;	if (copy_from_user(&status, arg, sizeof(status)))		return -EFAULT;	queue = queueptr(status.queue);	if (queue == NULL)		return -EINVAL;	memset(&status, 0, sizeof(status));	status.queue = queue->queue;		tmr = queue->timer;	status.events = queue->tickq->cells + queue->timeq->cells;	status.time = snd_seq_timer_get_cur_time(tmr);	status.tick = snd_seq_timer_get_cur_tick(tmr);	status.running = tmr->running;	status.flags = queue->flags;	queuefree(queue);	if (copy_to_user(arg, &status, sizeof(status)))		return -EFAULT;	return 0;}/* GET_QUEUE_TEMPO ioctl() */static int snd_seq_ioctl_get_queue_tempo(client_t * client, void __user *arg){	snd_seq_queue_tempo_t tempo;	queue_t *queue;	seq_timer_t *tmr;	if (copy_from_user(&tempo, arg, sizeof(tempo)))		return -EFAULT;	queue = queueptr(tempo.queue);	if (queue == NULL)		return -EINVAL;	memset(&tempo, 0, sizeof(tempo));	tempo.queue = queue->queue;		tmr = queue->timer;	tempo.tempo = tmr->tempo;	tempo.ppq = tmr->ppq;	tempo.skew_value = tmr->skew;	tempo.skew_base = tmr->skew_base;	queuefree(queue);	if (copy_to_user(arg, &tempo, sizeof(tempo)))		return -EFAULT;	return 0;}/* SET_QUEUE_TEMPO ioctl() */int snd_seq_set_queue_tempo(int client, snd_seq_queue_tempo_t *tempo){	if (!snd_seq_queue_check_access(tempo->queue, client))		return -EPERM;	return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo);}static int snd_seq_ioctl_set_queue_tempo(client_t * client, void __user *arg){	int result;	snd_seq_queue_tempo_t tempo;	if (copy_from_user(&tempo, arg, sizeof(tempo)))		return -EFAULT;	result = snd_seq_set_queue_tempo(client->number, &tempo);	return result < 0 ? result : 0;}/* GET_QUEUE_TIMER ioctl() */static int snd_seq_ioctl_get_queue_timer(client_t * client, void __user *arg){	snd_seq_queue_timer_t timer;	queue_t *queue;	seq_timer_t *tmr;	if (copy_from_user(&timer, arg, sizeof(timer)))		return -EFAULT;	queue = queueptr(timer.queue);	if (queue == NULL)		return -EINVAL;	if (down_interruptible(&queue->timer_mutex)) {		queuefree(queue);		return -ERESTARTSYS;	}	tmr = queue->timer;	memset(&timer, 0, sizeof(timer));	timer.queue = queue->queue;	timer.type = tmr->type;	if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {		timer.u.alsa.id = tmr->alsa_id;		timer.u.alsa.resolution = tmr->preferred_resolution;	}	up(&queue->timer_mutex);	queuefree(queue);		if (copy_to_user(arg, &timer, sizeof(timer)))		return -EFAULT;	return 0;}/* SET_QUEUE_TIMER ioctl() */static int snd_seq_ioctl_set_queue_timer(client_t * client, void __user *arg){	int result = 0;	snd_seq_queue_timer_t timer;	if (copy_from_user(&timer, arg, sizeof(timer)))		return -EFAULT;	if (timer.type != SNDRV_SEQ_TIMER_ALSA)		return -EINVAL;	if (snd_seq_queue_check_access(timer.queue, client->number)) {		queue_t *q;		seq_timer_t *tmr;		q = queueptr(timer.queue);		if (q == NULL)			return -ENXIO;		if (down_interruptible(&q->timer_mutex)) {			queuefree(q);			return -ERESTARTSYS;		}		tmr = q->timer;		snd_seq_queue_timer_close(timer.queue);		tmr->type = timer.type;		if (tmr->type == SNDRV_SEQ_TIMER_ALSA) {			tmr->alsa_id = timer.u.alsa.id;			tmr->preferred_resolution = timer.u.alsa.resolution;		}		result = snd_seq_queue_timer_open(timer.queue);		up(&q->timer_mutex);		queuefree(q);	} else {		return -EPERM;	}		return result;}/* GET_QUEUE_CLIENT ioctl() */static int snd_seq_ioctl_get_queue_client(client_t * client, void __user *arg){	snd_seq_queue_client_t info;	int used;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	used = snd_seq_queue_is_used(info.queue, client->number);	if (used < 0)		return -EINVAL;	info.used = used;	info.client = client->number;	if (copy_to_user(arg, &info, sizeof(info)))		return -EFAULT;	return 0;}/* SET_QUEUE_CLIENT ioctl() */static int snd_seq_ioctl_set_queue_client(client_t * client, void __user *arg){	int err;	snd_seq_queue_client_t info;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	if (info.used >= 0) {		err = snd_seq_queue_use(info.queue, client->number, info.used);		if (err < 0)			return err;	}	return snd_seq_ioctl_get_queue_client(client, arg);}/* GET_CLIENT_POOL ioctl() */static int snd_seq_ioctl_get_client_pool(client_t * client, void __user *arg){	snd_seq_client_pool_t info;	client_t *cptr;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	cptr = snd_seq_client_use_ptr(info.client);	if (cptr == NULL)		return -ENOENT;	memset(&info, 0, sizeof(info));	info.output_pool = cptr->pool->size;	info.output_room = cptr->pool->room;	info.output_free = info.output_pool;	if (cptr->pool)		info.output_free = snd_seq_unused_cells(cptr->pool);	if (cptr->type == USER_CLIENT) {		info.input_pool = cptr->data.user.fifo_pool_size;		info.input_free = info.input_pool;		if (cptr->data.user.fifo)			info.input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool);	} else {		info.input_pool = 0;		info.input_free = 0;	}	snd_seq_client_unlock(cptr);		if (copy_to_user(arg, &info, sizeof(info)))		return -EFAULT;	return 0;}/* SET_CLIENT_POOL ioctl() */static int snd_seq_ioctl_set_client_pool(client_t * client, void __user *arg){	snd_seq_client_pool_t info;	int rc;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	if (client->number != info.client)		return -EINVAL; /* can't change other clients */	if (info.output_pool >= 1 && info.output_pool <= SNDRV_SEQ_MAX_EVENTS &&	    (! snd_seq_write_pool_allocated(client) ||	     info.output_pool != client->pool->size)) {		if (snd_seq_write_pool_allocated(client)) {			/* remove all existing cells */			snd_seq_queue_client_leave_cells(client->number);			snd_seq_pool_done(client->pool);		}		client->pool->size = info.output_pool;		rc = snd_seq_pool_init(client->pool);		if (rc < 0)			return rc;	}	if (client->type == USER_CLIENT && client->data.user.fifo != NULL &&	    info.input_pool >= 1 &&	    info.input_pool <= SNDRV_SEQ_MAX_CLIENT_EVENTS &&	    info.input_pool != client->data.user.fifo_pool_size) {		/* change pool size */		rc = snd_seq_fifo_resize(client->data.user.fifo, info.input_pool);		if (rc < 0)			return rc;		client->data.user.fifo_pool_size = info.input_pool;	}	if (info.output_room >= 1 &&	    info.output_room <= client->pool->size) {		client->pool->room  = info.output_room;	}	return snd_seq_ioctl_get_client_pool(client, arg);}/* REMOVE_EVENTS ioctl() */static int snd_seq_ioctl_remove_events(client_t * client, void __user *arg){	snd_seq_remove_events_t info;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	/*	 * Input mostly not implemented XXX.	 */	if (info.remove_mode & SNDRV_SEQ_REMOVE_INPUT) {		/*		 * No restrictions so for a user client we can clear		 * the whole fifo		 */		if (client->type == USER_CLIENT)			snd_seq_fifo_clear(client->data.user.fifo);	}	if (info.remove_mode & SNDRV_SEQ_REMOVE_OUTPUT)		snd_seq_queue_remove_cells(client->number, &info);	return 0;}/* * get subscription info */static int snd_seq_ioctl_get_subscription(client_t *client, void __user *arg){	int result;	client_t *sender = NULL;	client_port_t *sport = NULL;	snd_seq_port_subscribe_t subs;	subscribers_t *p;	if (copy_from_user(&subs, arg, sizeof(subs)))		return -EFAULT;	result = -EINVAL;	if ((sender = snd_seq_client_use_ptr(subs.sender.client)) == NULL)		goto __end;	if ((sport = snd_seq_port_use_ptr(sender, subs.sender.port)) == NULL)		goto __end;	p = snd_seq_port_get_subscription(&sport->c_src, &subs.dest);	if (p) {		result = 0;		subs = p->info;	} else		result = -ENOENT;      __end:      	if (sport)		snd_seq_port_unlock(sport);	if (sender)		snd_seq_client_unlock(sender);	if (result >= 0) {		if (copy_to_user(arg, &subs, sizeof(subs)))			return -EFAULT;	}	return result;}/* * get subscription info - check only its presence */static int snd_seq_ioctl_query_subs(client_t *client, void __user *arg){	int result = -ENXIO;	client_t *cptr = NULL;	client_port_t *port = NULL;	snd_seq_query_subs_t subs;	port_subs_info_t *group;	struct list_head *p;	int i;	if (copy_from_user(&subs, arg, sizeof(subs)))		return -EFAULT;	if ((cptr = snd_seq_client_use_ptr(subs.root.client)) == NULL)		goto __end;	if ((port = snd_seq_port_use_ptr(cptr, subs.root.port)) == NULL)		goto __end;	switch (subs.type) {	case SNDRV_SEQ_QUERY_SUBS_READ:		group = &port->c_src;		break;	case SNDRV_SEQ_QUERY_SUBS_WRITE:		group = &port->c_dest;		break;	default:		goto __end;	}	down_read(&group->list_mutex);	/* search for the subscriber */	subs.num_subs = group->count;	i = 0;	result = -ENOENT;	list_for_each(p, &group->list_head) {		if (i++ == subs.index) {			/* found! */			subscribers_t *s;			if (subs.type == SNDRV_SEQ_QUERY_SUBS_READ) {				s = list_entry(p, subscribers_t, src_list);				subs.addr = s->info.dest;			} else {				s = list_entry(p, subscribers_t, dest_list);				subs.addr = s->info.sender;			}			subs.flags = s->info.flags;			subs.queue = s->info.queue;			result = 0;			break;		}	}	up_read(&group->list_mutex);      __end:   	if (port)		snd_seq_port_unlock(port);	if (cptr)		snd_seq_client_unlock(cptr);	if (result >= 0) {		if (copy_to_user(arg, &subs, sizeof(subs)))			return -EFAULT;	}	return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -