Blame src/seq/seq_hw.c

Packit Service db8eaa
/*
Packit Service db8eaa
 *  Sequencer Interface - main file
Packit Service db8eaa
 *  Copyright (c) 2000 by Jaroslav Kysela <perex@perex.cz>
Packit Service db8eaa
 *                        Abramo Bagnara <abramo@alsa-project.org>
Packit Service db8eaa
 *
Packit Service db8eaa
 *
Packit Service db8eaa
 *   This library is free software; you can redistribute it and/or modify
Packit Service db8eaa
 *   it under the terms of the GNU Lesser General Public License as
Packit Service db8eaa
 *   published by the Free Software Foundation; either version 2.1 of
Packit Service db8eaa
 *   the License, or (at your option) any later version.
Packit Service db8eaa
 *
Packit Service db8eaa
 *   This program is distributed in the hope that it will be useful,
Packit Service db8eaa
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service db8eaa
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service db8eaa
 *   GNU Lesser General Public License for more details.
Packit Service db8eaa
 *
Packit Service db8eaa
 *   You should have received a copy of the GNU Lesser General Public
Packit Service db8eaa
 *   License along with this library; if not, write to the Free Software
Packit Service db8eaa
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit Service db8eaa
 *
Packit Service db8eaa
 */
Packit Service db8eaa
Packit Service db8eaa
#include <fcntl.h>
Packit Service db8eaa
#include <sys/ioctl.h>
Packit Service db8eaa
#include "seq_local.h"
Packit Service db8eaa
Packit Service db8eaa
#ifndef PIC
Packit Service db8eaa
/* entry for static linking */
Packit Service db8eaa
const char *_snd_module_seq_hw = "";
Packit Service db8eaa
#endif
Packit Service db8eaa
Packit Service db8eaa
#ifndef DOC_HIDDEN
Packit Service db8eaa
#define SNDRV_FILE_SEQ		ALSA_DEVICE_DIRECTORY "seq"
Packit Service db8eaa
#define SNDRV_FILE_ALOADSEQ	ALOAD_DEVICE_DIRECTORY "aloadSEQ"
Packit Service db8eaa
#define SNDRV_SEQ_VERSION_MAX	SNDRV_PROTOCOL_VERSION(1, 0, 2)
Packit Service db8eaa
Packit Service db8eaa
typedef struct {
Packit Service db8eaa
	int fd;
Packit Service db8eaa
	int version;
Packit Service db8eaa
} snd_seq_hw_t;
Packit Service db8eaa
#endif /* DOC_HIDDEN */
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_close(snd_seq_t *seq)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	int err = 0;
Packit Service db8eaa
Packit Service db8eaa
	if (close(hw->fd)) {
Packit Service db8eaa
		err = -errno;
Packit Service db8eaa
		SYSERR("close failed\n");
Packit Service db8eaa
	}
Packit Service db8eaa
	free(hw);
Packit Service db8eaa
	return err;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_nonblock(snd_seq_t *seq, int nonblock)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	long flags;
Packit Service db8eaa
Packit Service db8eaa
	if ((flags = fcntl(hw->fd, F_GETFL)) < 0) {
Packit Service db8eaa
		SYSERR("F_GETFL failed");
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (nonblock)
Packit Service db8eaa
		flags |= O_NONBLOCK;
Packit Service db8eaa
	else
Packit Service db8eaa
		flags &= ~O_NONBLOCK;
Packit Service db8eaa
	if (fcntl(hw->fd, F_SETFL, flags) < 0) {
Packit Service db8eaa
		SYSERR("F_SETFL for O_NONBLOCK failed");
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_client_id(snd_seq_t *seq)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	int client;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_CLIENT_ID, &client) < 0) {
Packit Service db8eaa
		SYSERR("SNDRV_SEQ_IOCTL_CLIENT_ID failed");
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return client;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SYSTEM_INFO, info) < 0) {
Packit Service db8eaa
		SYSERR("SNDRV_SEQ_IOCTL_SYSTEM_INFO failed");
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_CLIENT_INFO, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_CLIENT_INFO failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (hw->version < SNDRV_PROTOCOL_VERSION(1, 0, 2)) {
Packit Service db8eaa
		info->card = -1;
Packit Service db8eaa
		info->pid = -1;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_set_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_SET_CLIENT_INFO failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_CREATE_PORT, port) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_CREATE_PORT failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_delete_port(snd_seq_t *seq, snd_seq_port_info_t * port)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_DELETE_PORT, port) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_DELETE_PORT failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_port_info(snd_seq_t *seq, snd_seq_port_info_t * info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_PORT_INFO, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_PORT_INFO failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_set_port_info(snd_seq_t *seq, snd_seq_port_info_t * info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_PORT_INFO, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_SET_PORT_INFO failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION, sub) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, sub) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, sub) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_QUERY_SUBS, subs) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_QUERY_SUBS failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_queue_status(snd_seq_t *seq, snd_seq_queue_status_t * status)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS, status) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_queue_tempo(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO, tempo) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_set_queue_tempo(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO, tempo) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_queue_timer(snd_seq_t *seq, snd_seq_queue_timer_t * timer)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER, timer) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_set_queue_timer(snd_seq_t *seq, snd_seq_queue_timer_t * timer)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER, timer) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_queue_client(snd_seq_t *seq, snd_seq_queue_client_t * info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_set_queue_client(snd_seq_t *seq, snd_seq_queue_client_t * info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_CREATE_QUEUE, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_CREATE_QUEUE failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_delete_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_DELETE_QUEUE, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_DELETE_QUEUE failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_queue_info(snd_seq_t *seq, snd_seq_queue_info_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_QUEUE_INFO, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_QUEUE_INFO failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_set_queue_info(snd_seq_t *seq, snd_seq_queue_info_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_QUEUE_INFO, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_SET_QUEUE_INFO failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_named_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static ssize_t snd_seq_hw_write(snd_seq_t *seq, void *buf, size_t len)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	ssize_t result = write(hw->fd, buf, len);
Packit Service db8eaa
	if (result < 0)
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	return result;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static ssize_t snd_seq_hw_read(snd_seq_t *seq, void *buf, size_t len)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	ssize_t result = read(hw->fd, buf, len);
Packit Service db8eaa
	if (result < 0)
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	return result;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_REMOVE_EVENTS, rmp) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_REMOVE_EVENTS failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_GET_CLIENT_POOL failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_SET_CLIENT_POOL failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (hw->version < SNDRV_PROTOCOL_VERSION(1, 0, 2)) {
Packit Service db8eaa
		info->card = -1;
Packit Service db8eaa
		info->pid = -1;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static int snd_seq_hw_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_seq_hw_t *hw = seq->private_data;
Packit Service db8eaa
	if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, info) < 0) {
Packit Service db8eaa
		/*SYSERR("SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT failed");*/
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
static const snd_seq_ops_t snd_seq_hw_ops = {
Packit Service db8eaa
	.close = snd_seq_hw_close,
Packit Service db8eaa
	.nonblock = snd_seq_hw_nonblock,
Packit Service db8eaa
	.system_info = snd_seq_hw_system_info,
Packit Service db8eaa
	.get_client_info = snd_seq_hw_get_client_info,
Packit Service db8eaa
	.set_client_info = snd_seq_hw_set_client_info,
Packit Service db8eaa
	.create_port = snd_seq_hw_create_port,
Packit Service db8eaa
	.delete_port = snd_seq_hw_delete_port,
Packit Service db8eaa
	.get_port_info = snd_seq_hw_get_port_info,
Packit Service db8eaa
	.set_port_info = snd_seq_hw_set_port_info,
Packit Service db8eaa
	.get_port_subscription = snd_seq_hw_get_port_subscription,
Packit Service db8eaa
	.subscribe_port = snd_seq_hw_subscribe_port,
Packit Service db8eaa
	.unsubscribe_port = snd_seq_hw_unsubscribe_port,
Packit Service db8eaa
	.query_port_subscribers = snd_seq_hw_query_port_subscribers,
Packit Service db8eaa
	.get_queue_status = snd_seq_hw_get_queue_status,
Packit Service db8eaa
	.get_queue_tempo = snd_seq_hw_get_queue_tempo,
Packit Service db8eaa
	.set_queue_tempo = snd_seq_hw_set_queue_tempo,
Packit Service db8eaa
	.get_queue_timer = snd_seq_hw_get_queue_timer,
Packit Service db8eaa
	.set_queue_timer = snd_seq_hw_set_queue_timer,
Packit Service db8eaa
	.get_queue_client = snd_seq_hw_get_queue_client,
Packit Service db8eaa
	.set_queue_client = snd_seq_hw_set_queue_client,
Packit Service db8eaa
	.create_queue = snd_seq_hw_create_queue,
Packit Service db8eaa
	.delete_queue = snd_seq_hw_delete_queue,
Packit Service db8eaa
	.get_queue_info = snd_seq_hw_get_queue_info,
Packit Service db8eaa
	.set_queue_info = snd_seq_hw_set_queue_info,
Packit Service db8eaa
	.get_named_queue = snd_seq_hw_get_named_queue,
Packit Service db8eaa
	.write = snd_seq_hw_write,
Packit Service db8eaa
	.read = snd_seq_hw_read,
Packit Service db8eaa
	.remove_events = snd_seq_hw_remove_events,
Packit Service db8eaa
	.get_client_pool = snd_seq_hw_get_client_pool,
Packit Service db8eaa
	.set_client_pool = snd_seq_hw_set_client_pool,
Packit Service db8eaa
	.query_next_client = snd_seq_hw_query_next_client,
Packit Service db8eaa
	.query_next_port = snd_seq_hw_query_next_port,
Packit Service db8eaa
};
Packit Service db8eaa
Packit Service db8eaa
int snd_seq_hw_open(snd_seq_t **handle, const char *name, int streams, int mode)
Packit Service db8eaa
{
Packit Service db8eaa
	int fd, ver, client, fmode, ret;
Packit Service db8eaa
	const char *filename;
Packit Service db8eaa
	snd_seq_t *seq;
Packit Service db8eaa
	snd_seq_hw_t *hw;
Packit Service db8eaa
Packit Service db8eaa
	*handle = NULL;
Packit Service db8eaa
Packit Service db8eaa
	switch (streams) {
Packit Service db8eaa
	case SND_SEQ_OPEN_OUTPUT:
Packit Service db8eaa
		fmode = O_WRONLY;
Packit Service db8eaa
		break;
Packit Service db8eaa
	case SND_SEQ_OPEN_INPUT:
Packit Service db8eaa
		fmode = O_RDONLY;
Packit Service db8eaa
		break;
Packit Service db8eaa
	case SND_SEQ_OPEN_DUPLEX:
Packit Service db8eaa
		fmode = O_RDWR;
Packit Service db8eaa
		break;
Packit Service db8eaa
	default:
Packit Service db8eaa
		assert(0);
Packit Service db8eaa
		return -EINVAL;
Packit Service db8eaa
	}
Packit Service db8eaa
	
Packit Service db8eaa
	if (mode & SND_SEQ_NONBLOCK)
Packit Service db8eaa
		fmode |= O_NONBLOCK;
Packit Service db8eaa
Packit Service db8eaa
	filename = SNDRV_FILE_SEQ;
Packit Service db8eaa
	fd = snd_open_device(filename, fmode);
Packit Service db8eaa
#ifdef SUPPORT_ALOAD
Packit Service db8eaa
	if (fd < 0) {
Packit Service db8eaa
		fd = snd_open_device(SNDRV_FILE_ALOADSEQ, fmode);
Packit Service db8eaa
		if (fd >= 0)
Packit Service db8eaa
			close(fd);
Packit Service db8eaa
		fd = snd_open_device(filename, fmode);
Packit Service db8eaa
	}
Packit Service db8eaa
#endif
Packit Service db8eaa
	if (fd < 0) {
Packit Service db8eaa
		SYSERR("open %s failed", filename);
Packit Service db8eaa
		return -errno;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (ioctl(fd, SNDRV_SEQ_IOCTL_PVERSION, &ver) < 0) {
Packit Service db8eaa
		SYSERR("SNDRV_SEQ_IOCTL_PVERSION failed");
Packit Service db8eaa
		ret = -errno;
Packit Service db8eaa
		close(fd);
Packit Service db8eaa
		return ret;
Packit Service db8eaa
	}
Packit Service db8eaa
	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_SEQ_VERSION_MAX)) {
Packit Service db8eaa
		close(fd);
Packit Service db8eaa
		return -SND_ERROR_INCOMPATIBLE_VERSION;
Packit Service db8eaa
	}
Packit Service db8eaa
	hw = calloc(1, sizeof(snd_seq_hw_t));
Packit Service db8eaa
	if (hw == NULL) {
Packit Service db8eaa
		close(fd);
Packit Service db8eaa
		return -ENOMEM;
Packit Service db8eaa
	}
Packit Service db8eaa
Packit Service db8eaa
	seq = calloc(1, sizeof(snd_seq_t));
Packit Service db8eaa
	if (seq == NULL) {
Packit Service db8eaa
		free(hw);
Packit Service db8eaa
		close(fd);
Packit Service db8eaa
		return -ENOMEM;
Packit Service db8eaa
	}
Packit Service db8eaa
	hw->fd = fd;
Packit Service db8eaa
	hw->version = ver;
Packit Service db8eaa
	if (streams & SND_SEQ_OPEN_OUTPUT) {
Packit Service db8eaa
		seq->obuf = (char *) malloc(seq->obufsize = SND_SEQ_OBUF_SIZE);
Packit Service db8eaa
		if (!seq->obuf) {
Packit Service db8eaa
			free(hw);
Packit Service db8eaa
			free(seq);
Packit Service db8eaa
			close(fd);
Packit Service db8eaa
			return -ENOMEM;
Packit Service db8eaa
		}
Packit Service db8eaa
	}
Packit Service db8eaa
	if (streams & SND_SEQ_OPEN_INPUT) {
Packit Service db8eaa
		seq->ibuf = (snd_seq_event_t *) calloc(sizeof(snd_seq_event_t), seq->ibufsize = SND_SEQ_IBUF_SIZE);
Packit Service db8eaa
		if (!seq->ibuf) {
Packit Service db8eaa
			free(seq->obuf);
Packit Service db8eaa
			free(hw);
Packit Service db8eaa
			free(seq);
Packit Service db8eaa
			close(fd);
Packit Service db8eaa
			return -ENOMEM;
Packit Service db8eaa
		}
Packit Service db8eaa
	}
Packit Service db8eaa
	if (name)
Packit Service db8eaa
		seq->name = strdup(name);
Packit Service db8eaa
	seq->type = SND_SEQ_TYPE_HW;
Packit Service db8eaa
	seq->streams = streams;
Packit Service db8eaa
	seq->mode = mode;
Packit Service db8eaa
	seq->tmpbuf = NULL;
Packit Service db8eaa
	seq->tmpbufsize = 0;
Packit Service db8eaa
	seq->poll_fd = fd;
Packit Service db8eaa
	seq->ops = &snd_seq_hw_ops;
Packit Service db8eaa
	seq->private_data = hw;
Packit Service db8eaa
	client = snd_seq_hw_client_id(seq);
Packit Service db8eaa
	if (client < 0) {
Packit Service db8eaa
		snd_seq_close(seq);
Packit Service db8eaa
		return client;
Packit Service db8eaa
	} else
Packit Service db8eaa
		seq->client = client;
Packit Service db8eaa
Packit Service db8eaa
#ifdef SNDRV_SEQ_IOCTL_RUNNING_MODE
Packit Service db8eaa
	{
Packit Service db8eaa
		struct snd_seq_running_info run_mode;
Packit Service db8eaa
		/* check running mode */
Packit Service db8eaa
		memset(&run_mode, 0, sizeof(run_mode));
Packit Service db8eaa
		run_mode.client = client;
Packit Service db8eaa
#ifdef SNDRV_BIG_ENDIAN
Packit Service db8eaa
		run_mode.big_endian = 1;
Packit Service db8eaa
#else
Packit Service db8eaa
		run_mode.big_endian = 0;
Packit Service db8eaa
#endif
Packit Service db8eaa
		run_mode.cpu_mode = sizeof(long);
Packit Service db8eaa
		ioctl(fd, SNDRV_SEQ_IOCTL_RUNNING_MODE, &run_mode);
Packit Service db8eaa
	}
Packit Service db8eaa
#endif
Packit Service db8eaa
Packit Service db8eaa
	*handle = seq;
Packit Service db8eaa
	return 0;
Packit Service db8eaa
}
Packit Service db8eaa
Packit Service db8eaa
int _snd_seq_hw_open(snd_seq_t **handlep, char *name,
Packit Service db8eaa
		     snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *conf,
Packit Service db8eaa
		     int streams, int mode)
Packit Service db8eaa
{
Packit Service db8eaa
	snd_config_iterator_t i, next;
Packit Service db8eaa
	snd_config_for_each(i, next, conf) {
Packit Service db8eaa
		snd_config_t *n = snd_config_iterator_entry(i);
Packit Service db8eaa
		const char *id;
Packit Service db8eaa
		if (snd_config_get_id(n, &id) < 0)
Packit Service db8eaa
			continue;
Packit Service db8eaa
		if (_snd_conf_generic_id(id))
Packit Service db8eaa
			continue;
Packit Service db8eaa
		return -EINVAL;
Packit Service db8eaa
	}
Packit Service db8eaa
	return snd_seq_hw_open(handlep, name, streams, mode);
Packit Service db8eaa
}
Packit Service db8eaa
SND_DLSYM_BUILD_VERSION(_snd_seq_hw_open, SND_SEQ_DLSYM_VERSION);