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

📄 seq_clientmgr.c

📁 linux2.6.16版本
💻 C
📖 第 1 页 / 共 5 页
字号:
		snd_seq_client_unlock(sender);	if (receiver)		snd_seq_client_unlock(receiver);	return result;}/* CREATE_QUEUE ioctl() */static int snd_seq_ioctl_create_queue(struct snd_seq_client *client,				      void __user *arg){	struct snd_seq_queue_info info;	int result;	struct snd_seq_queue *q;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	result = snd_seq_queue_alloc(client->number, info.locked, info.flags);	if (result < 0)		return result;	q = queueptr(result);	if (q == NULL)		return -EINVAL;	info.queue = q->queue;	info.locked = q->locked;	info.owner = q->owner;	/* set queue name */	if (! info.name[0])		snprintf(info.name, sizeof(info.name), "Queue-%d", q->queue);	strlcpy(q->name, info.name, sizeof(q->name));	queuefree(q);	if (copy_to_user(arg, &info, sizeof(info)))		return -EFAULT;	return 0;}/* DELETE_QUEUE ioctl() */static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client,				      void __user *arg){	struct snd_seq_queue_info info;	if (copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	return snd_seq_queue_delete(client->number, info.queue);}/* GET_QUEUE_INFO ioctl() */static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,					void __user *arg){	struct snd_seq_queue_info info;	struct snd_seq_queue *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(struct snd_seq_client *client,					void __user *arg){	struct snd_seq_queue_info info;	struct snd_seq_queue *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(struct snd_seq_client *client, void __user *arg){	struct snd_seq_queue_info info;	struct snd_seq_queue *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(struct snd_seq_client *client,					  void __user *arg){	struct snd_seq_queue_status status;	struct snd_seq_queue *queue;	struct snd_seq_timer *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(struct snd_seq_client *client,					 void __user *arg){	struct snd_seq_queue_tempo tempo;	struct snd_seq_queue *queue;	struct snd_seq_timer *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, struct snd_seq_queue_tempo *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(struct snd_seq_client *client,					 void __user *arg){	int result;	struct snd_seq_queue_tempo 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(struct snd_seq_client *client,					 void __user *arg){	struct snd_seq_queue_timer timer;	struct snd_seq_queue *queue;	struct snd_seq_timer *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(struct snd_seq_client *client,					 void __user *arg){	int result = 0;	struct snd_seq_queue_timer 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)) {		struct snd_seq_queue *q;		struct snd_seq_timer *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(struct snd_seq_client *client,					  void __user *arg){	struct snd_seq_queue_client 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(struct snd_seq_client *client,					  void __user *arg){	int err;	struct snd_seq_queue_client 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(struct snd_seq_client *client,					 void __user *arg){	struct snd_seq_client_pool info;	struct snd_seq_client *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(struct snd_seq_client *client,					 void __user *arg){	struct snd_seq_client_pool 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(struct snd_seq_client *client,				       void __user *arg){	struct snd_seq_remove_events 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(struct snd_seq_client *client,					  void __user *arg){	int result;	struct snd_seq_client *sender = NULL;	struct snd_seq_client_port *sport = NULL;	struct snd_seq_port_subscribe subs;	struct snd_seq_subscribers *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(struct snd_seq_client *client,				    void __user *arg)

⌨️ 快捷键说明

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