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

📄 seq_instr.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
			int atomic){	snd_seq_event_t sev;		memset(&sev, 0, sizeof(sev));	sev.type = SNDRV_SEQ_EVENT_RESULT;	sev.flags = SNDRV_SEQ_TIME_STAMP_REAL | SNDRV_SEQ_EVENT_LENGTH_FIXED |	            SNDRV_SEQ_PRIORITY_NORMAL;	sev.source = ev->dest;	sev.dest = ev->source;	sev.data.result.event = type;	sev.data.result.result = result;#if 0	printk("instr result - type = %i, result = %i, queue = %i, source.client:port = %i:%i, dest.client:port = %i:%i\n",				type, result,				sev.queue,				sev.source.client, sev.source.port,				sev.dest.client, sev.dest.port);#endif	return snd_seq_kernel_client_dispatch(sev.source.client, &sev, atomic, 0);}static int instr_begin(snd_seq_kinstr_ops_t *ops,		       snd_seq_kinstr_list_t *list,		       snd_seq_event_t *ev,		       int atomic, int hop){	unsigned long flags;	spin_lock_irqsave(&list->lock, flags);	if (list->owner >= 0 && list->owner != ev->source.client) {		spin_unlock_irqrestore(&list->lock, flags);		return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_BEGIN, -EBUSY, atomic);	}	list->owner = ev->source.client;	spin_unlock_irqrestore(&list->lock, flags);	return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_BEGIN, 0, atomic);}static int instr_end(snd_seq_kinstr_ops_t *ops,		     snd_seq_kinstr_list_t *list,		     snd_seq_event_t *ev,		     int atomic, int hop){	unsigned long flags;	/* TODO: timeout handling */	spin_lock_irqsave(&list->lock, flags);	if (list->owner == ev->source.client) {		list->owner = -1;		spin_unlock_irqrestore(&list->lock, flags);		return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_END, 0, atomic);	}	spin_unlock_irqrestore(&list->lock, flags);	return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_END, -EINVAL, atomic);}static int instr_info(snd_seq_kinstr_ops_t *ops,		      snd_seq_kinstr_list_t *list,		      snd_seq_event_t *ev,		      int atomic, int hop){	return -ENXIO;}static int instr_format_info(snd_seq_kinstr_ops_t *ops,			     snd_seq_kinstr_list_t *list,			     snd_seq_event_t *ev,			     int atomic, int hop){	return -ENXIO;}static int instr_reset(snd_seq_kinstr_ops_t *ops,		       snd_seq_kinstr_list_t *list,		       snd_seq_event_t *ev,		       int atomic, int hop){	return -ENXIO;}static int instr_status(snd_seq_kinstr_ops_t *ops,			snd_seq_kinstr_list_t *list,			snd_seq_event_t *ev,			int atomic, int hop){	return -ENXIO;}static int instr_put(snd_seq_kinstr_ops_t *ops,		     snd_seq_kinstr_list_t *list,		     snd_seq_event_t *ev,		     int atomic, int hop){	unsigned long flags;	snd_seq_instr_header_t put;	snd_seq_kinstr_t *instr;	int result = -EINVAL, len, key;	if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARUSR)		goto __return;	if (ev->data.ext.len < sizeof(snd_seq_instr_header_t))		goto __return;	if (copy_from_user(&put, (void __user *)ev->data.ext.ptr, sizeof(snd_seq_instr_header_t))) {		result = -EFAULT;		goto __return;	}	snd_instr_lock_ops(list);	if (put.id.instr.std & 0xff000000) {	/* private instrument */		put.id.instr.std &= 0x00ffffff;		put.id.instr.std |= (unsigned int)ev->source.client << 24;	}	if ((instr = snd_seq_instr_find(list, &put.id.instr, 1, 0))) {		snd_seq_instr_free_use(list, instr);		snd_instr_unlock_ops(list);		result = -EBUSY;		goto __return;	}	ops = instr_ops(ops, put.data.data.format);	if (ops == NULL) {		snd_instr_unlock_ops(list);		goto __return;	}	len = ops->add_len;	if (put.data.type == SNDRV_SEQ_INSTR_ATYPE_ALIAS)		len = sizeof(snd_seq_instr_t);	instr = snd_seq_instr_new(len, atomic);	if (instr == NULL) {		snd_instr_unlock_ops(list);		result = -ENOMEM;		goto __return;	}	instr->ops = ops;	instr->instr = put.id.instr;	strlcpy(instr->name, put.data.name, sizeof(instr->name));	instr->type = put.data.type;	if (instr->type == SNDRV_SEQ_INSTR_ATYPE_DATA) {		result = ops->put(ops->private_data,				  instr,				  (void __user *)ev->data.ext.ptr + sizeof(snd_seq_instr_header_t),				  ev->data.ext.len - sizeof(snd_seq_instr_header_t),				  atomic,				  put.cmd);		if (result < 0) {			snd_seq_instr_free(instr, atomic);			snd_instr_unlock_ops(list);			goto __return;		}	}	key = compute_hash_instr_key(&instr->instr);	spin_lock_irqsave(&list->lock, flags);	instr->next = list->hash[key];	list->hash[key] = instr;	list->count++;	spin_unlock_irqrestore(&list->lock, flags);	snd_instr_unlock_ops(list);	result = 0;      __return:	instr_result(ev, SNDRV_SEQ_EVENT_INSTR_PUT, result, atomic);	return result;}static int instr_get(snd_seq_kinstr_ops_t *ops,		     snd_seq_kinstr_list_t *list,		     snd_seq_event_t *ev,		     int atomic, int hop){	return -ENXIO;}static int instr_free(snd_seq_kinstr_ops_t *ops,		      snd_seq_kinstr_list_t *list,		      snd_seq_event_t *ev,		      int atomic, int hop){	snd_seq_instr_header_t ifree;	snd_seq_kinstr_t *instr, *prev;	int result = -EINVAL;	unsigned long flags;	unsigned int hash;	if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARUSR)		goto __return;	if (ev->data.ext.len < sizeof(snd_seq_instr_header_t))		goto __return;	if (copy_from_user(&ifree, (void __user *)ev->data.ext.ptr, sizeof(snd_seq_instr_header_t))) {		result = -EFAULT;		goto __return;	}	if (ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_ALL ||	    ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE ||	    ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_CLUSTER) {	    	result = snd_seq_instr_list_free_cond(list, &ifree, ev->dest.client, atomic);	    	goto __return;	}	if (ifree.cmd == SNDRV_SEQ_INSTR_FREE_CMD_SINGLE) {		if (ifree.id.instr.std & 0xff000000) {			ifree.id.instr.std &= 0x00ffffff;			ifree.id.instr.std |= (unsigned int)ev->source.client << 24;		}		hash = compute_hash_instr_key(&ifree.id.instr);		snd_instr_lock_ops(list);		spin_lock_irqsave(&list->lock, flags);		instr = list->hash[hash];		prev = NULL;		while (instr) {			if (!compare_instr(&instr->instr, &ifree.id.instr, 1))				goto __free_single;			prev = instr;			instr = instr->next;		}		result = -ENOENT;		spin_unlock_irqrestore(&list->lock, flags);		snd_instr_unlock_ops(list);		goto __return;			      __free_single:		if (prev) {			prev->next = instr->next;		} else {			list->hash[hash] = instr->next;		}		if (instr->ops && instr->ops->notify)			instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE);		while (instr->use) {			spin_unlock_irqrestore(&list->lock, flags);			schedule_timeout_interruptible(1);			spin_lock_irqsave(&list->lock, flags);		}						spin_unlock_irqrestore(&list->lock, flags);		result = snd_seq_instr_free(instr, atomic);		snd_instr_unlock_ops(list);		goto __return;	}      __return:	instr_result(ev, SNDRV_SEQ_EVENT_INSTR_FREE, result, atomic);	return result;}static int instr_list(snd_seq_kinstr_ops_t *ops,		      snd_seq_kinstr_list_t *list,		      snd_seq_event_t *ev,		      int atomic, int hop){	return -ENXIO;}static int instr_cluster(snd_seq_kinstr_ops_t *ops,			 snd_seq_kinstr_list_t *list,			 snd_seq_event_t *ev,			 int atomic, int hop){	return -ENXIO;}int snd_seq_instr_event(snd_seq_kinstr_ops_t *ops,			snd_seq_kinstr_list_t *list,			snd_seq_event_t *ev,			int client,			int atomic,			int hop){	int direct = 0;	snd_assert(ops != NULL && list != NULL && ev != NULL, return -EINVAL);	if (snd_seq_ev_is_direct(ev)) {		direct = 1;		switch (ev->type) {		case SNDRV_SEQ_EVENT_INSTR_BEGIN:			return instr_begin(ops, list, ev, atomic, hop);		case SNDRV_SEQ_EVENT_INSTR_END:			return instr_end(ops, list, ev, atomic, hop);		}	}	if ((list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT) && !direct)		return -EINVAL;	switch (ev->type) {	case SNDRV_SEQ_EVENT_INSTR_INFO:		return instr_info(ops, list, ev, atomic, hop);	case SNDRV_SEQ_EVENT_INSTR_FINFO:		return instr_format_info(ops, list, ev, atomic, hop);	case SNDRV_SEQ_EVENT_INSTR_RESET:		return instr_reset(ops, list, ev, atomic, hop);	case SNDRV_SEQ_EVENT_INSTR_STATUS:		return instr_status(ops, list, ev, atomic, hop);	case SNDRV_SEQ_EVENT_INSTR_PUT:		return instr_put(ops, list, ev, atomic, hop);	case SNDRV_SEQ_EVENT_INSTR_GET:		return instr_get(ops, list, ev, atomic, hop);	case SNDRV_SEQ_EVENT_INSTR_FREE:		return instr_free(ops, list, ev, atomic, hop);	case SNDRV_SEQ_EVENT_INSTR_LIST:		return instr_list(ops, list, ev, atomic, hop);	case SNDRV_SEQ_EVENT_INSTR_CLUSTER:		return instr_cluster(ops, list, ev, atomic, hop);	}	return -EINVAL;}			/* *  Init part */static int __init alsa_seq_instr_init(void){	return 0;}static void __exit alsa_seq_instr_exit(void){}module_init(alsa_seq_instr_init)module_exit(alsa_seq_instr_exit)EXPORT_SYMBOL(snd_seq_instr_list_new);EXPORT_SYMBOL(snd_seq_instr_list_free);EXPORT_SYMBOL(snd_seq_instr_list_free_cond);EXPORT_SYMBOL(snd_seq_instr_find);EXPORT_SYMBOL(snd_seq_instr_free_use);EXPORT_SYMBOL(snd_seq_instr_event);

⌨️ 快捷键说明

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