/*
 * close port
 */
static int
snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg)
{
	struct snd_emux *emu;
	struct snd_emux_port *p;

	if (snd_BUG_ON(!arg))
		return -ENXIO;
	p = arg->private_data;
	if (snd_BUG_ON(!p))
		return -ENXIO;

	emu = p->emu;
	if (snd_BUG_ON(!emu))
		return -ENXIO;

	mutex_lock(&emu->register_mutex);
	snd_emux_sounds_off_all(p);
	snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port));
	snd_seq_event_port_detach(p->chset.client, p->chset.port);
	snd_emux_dec_count(emu);

	mutex_unlock(&emu->register_mutex);
	return 0;
}
/*
 * load patch
 */
static int
snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
			    const char __user *buf, int offs, int count)
{
	struct snd_emux *emu;
	struct snd_emux_port *p;
	int rc;

	if (snd_BUG_ON(!arg))
		return -ENXIO;
	p = arg->private_data;
	if (snd_BUG_ON(!p))
		return -ENXIO;

	emu = p->emu;
	if (snd_BUG_ON(!emu))
		return -ENXIO;

	if (format == GUS_PATCH)
		rc = snd_soundfont_load_guspatch(emu->sflist, buf, count,
						 SF_CLIENT_NO(p->chset.port));
	else if (format == SNDRV_OSS_SOUNDFONT_PATCH) {
		struct soundfont_patch_info patch;
		if (count < (int)sizeof(patch))
			rc = -EINVAL;
		if (copy_from_user(&patch, buf, sizeof(patch)))
			rc = -EFAULT;
		if (patch.type >= SNDRV_SFNT_LOAD_INFO &&
		    patch.type <= SNDRV_SFNT_PROBE_DATA)
			rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port));
		else {
			if (emu->ops.load_fx)
				rc = emu->ops.load_fx(emu, patch.type, patch.optarg, buf, count);
			else
				rc = -EINVAL;
		}
	} else
		rc = 0;
	return rc;
}
/*
 * close port
 */
static int
snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg)
{
	struct snd_emux *emu;
	struct snd_emux_port *p;

	snd_assert(arg != NULL, return -ENXIO);
	p = arg->private_data;
	snd_assert(p != NULL, return -ENXIO);

	emu = p->emu;
	snd_assert(emu != NULL, return -ENXIO);

	mutex_lock(&emu->register_mutex);
	snd_emux_sounds_off_all(p);
	snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port));
	snd_seq_event_port_detach(p->chset.client, p->chset.port);
	snd_emux_dec_count(emu);

	mutex_unlock(&emu->register_mutex);
	return 0;
}