cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

emux.c (3371B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
      4 *
      5 *  Routines for control of EMU WaveTable chip
      6 */
      7
      8#include <linux/wait.h>
      9#include <linux/slab.h>
     10#include <linux/string.h>
     11#include <sound/core.h>
     12#include <sound/emux_synth.h>
     13#include <linux/init.h>
     14#include <linux/module.h>
     15#include "emux_voice.h"
     16
     17MODULE_AUTHOR("Takashi Iwai");
     18MODULE_DESCRIPTION("Routines for control of EMU WaveTable chip");
     19MODULE_LICENSE("GPL");
     20
     21/*
     22 * create a new hardware dependent device for Emu8000/Emu10k1
     23 */
     24int snd_emux_new(struct snd_emux **remu)
     25{
     26	struct snd_emux *emu;
     27
     28	*remu = NULL;
     29	emu = kzalloc(sizeof(*emu), GFP_KERNEL);
     30	if (emu == NULL)
     31		return -ENOMEM;
     32
     33	spin_lock_init(&emu->voice_lock);
     34	mutex_init(&emu->register_mutex);
     35
     36	emu->client = -1;
     37#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
     38	emu->oss_synth = NULL;
     39#endif
     40	emu->max_voices = 0;
     41	emu->use_time = 0;
     42
     43	timer_setup(&emu->tlist, snd_emux_timer_callback, 0);
     44	emu->timer_active = 0;
     45
     46	*remu = emu;
     47	return 0;
     48}
     49
     50EXPORT_SYMBOL(snd_emux_new);
     51
     52/*
     53 */
     54static int sf_sample_new(void *private_data, struct snd_sf_sample *sp,
     55				  struct snd_util_memhdr *hdr,
     56				  const void __user *buf, long count)
     57{
     58	struct snd_emux *emu = private_data;
     59	return emu->ops.sample_new(emu, sp, hdr, buf, count);
     60	
     61}
     62
     63static int sf_sample_free(void *private_data, struct snd_sf_sample *sp,
     64				   struct snd_util_memhdr *hdr)
     65{
     66	struct snd_emux *emu = private_data;
     67	return emu->ops.sample_free(emu, sp, hdr);
     68	
     69}
     70
     71static void sf_sample_reset(void *private_data)
     72{
     73	struct snd_emux *emu = private_data;
     74	emu->ops.sample_reset(emu);
     75}
     76
     77int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, char *name)
     78{
     79	int err;
     80	struct snd_sf_callback sf_cb;
     81
     82	if (snd_BUG_ON(!emu->hw || emu->max_voices <= 0))
     83		return -EINVAL;
     84	if (snd_BUG_ON(!card || !name))
     85		return -EINVAL;
     86
     87	emu->card = card;
     88	emu->name = kstrdup(name, GFP_KERNEL);
     89	emu->voices = kcalloc(emu->max_voices, sizeof(struct snd_emux_voice),
     90			      GFP_KERNEL);
     91	if (emu->name == NULL || emu->voices == NULL)
     92		return -ENOMEM;
     93
     94	/* create soundfont list */
     95	memset(&sf_cb, 0, sizeof(sf_cb));
     96	sf_cb.private_data = emu;
     97	if (emu->ops.sample_new)
     98		sf_cb.sample_new = sf_sample_new;
     99	if (emu->ops.sample_free)
    100		sf_cb.sample_free = sf_sample_free;
    101	if (emu->ops.sample_reset)
    102		sf_cb.sample_reset = sf_sample_reset;
    103	emu->sflist = snd_sf_new(&sf_cb, emu->memhdr);
    104	if (emu->sflist == NULL)
    105		return -ENOMEM;
    106
    107	err = snd_emux_init_hwdep(emu);
    108	if (err < 0)
    109		return err;
    110
    111	snd_emux_init_voices(emu);
    112
    113	snd_emux_init_seq(emu, card, index);
    114#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
    115	snd_emux_init_seq_oss(emu);
    116#endif
    117	snd_emux_init_virmidi(emu, card);
    118
    119	snd_emux_proc_init(emu, card, index);
    120	return 0;
    121}
    122
    123EXPORT_SYMBOL(snd_emux_register);
    124
    125/*
    126 */
    127int snd_emux_free(struct snd_emux *emu)
    128{
    129	unsigned long flags;
    130
    131	if (! emu)
    132		return -EINVAL;
    133
    134	spin_lock_irqsave(&emu->voice_lock, flags);
    135	if (emu->timer_active)
    136		del_timer(&emu->tlist);
    137	spin_unlock_irqrestore(&emu->voice_lock, flags);
    138
    139	snd_emux_proc_free(emu);
    140	snd_emux_delete_virmidi(emu);
    141#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
    142	snd_emux_detach_seq_oss(emu);
    143#endif
    144	snd_emux_detach_seq(emu);
    145	snd_emux_delete_hwdep(emu);
    146	snd_sf_free(emu->sflist);
    147	kfree(emu->voices);
    148	kfree(emu->name);
    149	kfree(emu);
    150	return 0;
    151}
    152
    153EXPORT_SYMBOL(snd_emux_free);