#include <linux/init.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/minors.h>
#include <linux/kmod.h>
#include <sound/seq_kernel.h>
#include <sound/ump.h>
#include "seq_clientmgr.h"
#include "seq_memory.h"
#include "seq_queue.h"
#include "seq_timer.h"
#include "seq_info.h"
#include "seq_system.h"
#include "seq_ump_convert.h"
#include <sound/seq_device.h>
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
#endif
#define SNDRV_SEQ_GLOBAL_CLIENTS …
#define SNDRV_SEQ_CLIENTS_PER_CARD …
#define SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN …
#define SNDRV_SEQ_LFLG_INPUT …
#define SNDRV_SEQ_LFLG_OUTPUT …
#define SNDRV_SEQ_LFLG_OPEN …
static DEFINE_SPINLOCK(clients_lock);
static DEFINE_MUTEX(register_mutex);
static char clienttablock[SNDRV_SEQ_MAX_CLIENTS];
static struct snd_seq_client *clienttab[SNDRV_SEQ_MAX_CLIENTS];
static struct snd_seq_usage client_usage;
static int bounce_error_event(struct snd_seq_client *client,
struct snd_seq_event *event,
int err, int atomic, int hop);
static int snd_seq_deliver_single_event(struct snd_seq_client *client,
struct snd_seq_event *event,
int atomic, int hop);
#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
static void free_ump_info(struct snd_seq_client *client);
#endif
static inline unsigned short snd_seq_file_flags(struct file *file)
{ … }
static inline int snd_seq_write_pool_allocated(struct snd_seq_client *client)
{ … }
static struct snd_seq_client *clientptr(int clientid)
{ … }
struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
{ … }
bool snd_seq_client_ioctl_lock(int clientid)
{ … }
EXPORT_SYMBOL_GPL(…);
void snd_seq_client_ioctl_unlock(int clientid)
{ … }
EXPORT_SYMBOL_GPL(…);
static void usage_alloc(struct snd_seq_usage *res, int num)
{ … }
static void usage_free(struct snd_seq_usage *res, int num)
{ … }
int __init client_init_data(void)
{ … }
static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
{ … }
static int seq_free_client1(struct snd_seq_client *client)
{ … }
static void seq_free_client(struct snd_seq_client * client)
{ … }
static int snd_seq_open(struct inode *inode, struct file *file)
{ … }
static int snd_seq_release(struct inode *inode, struct file *file)
{ … }
static bool event_is_compatible(const struct snd_seq_client *client,
const struct snd_seq_event *ev)
{ … }
static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
loff_t *offset)
{ … }
static int check_port_perm(struct snd_seq_client_port *port, unsigned int flags)
{ … }
static struct snd_seq_client *get_event_dest_client(struct snd_seq_event *event)
{ … }
static int bounce_error_event(struct snd_seq_client *client,
struct snd_seq_event *event,
int err, int atomic, int hop)
{ … }
static int update_timestamp_of_queue(struct snd_seq_event *event,
int queue, int real_time)
{ … }
int __snd_seq_deliver_single_event(struct snd_seq_client *dest,
struct snd_seq_client_port *dest_port,
struct snd_seq_event *event,
int atomic, int hop)
{ … }
static int snd_seq_deliver_single_event(struct snd_seq_client *client,
struct snd_seq_event *event,
int atomic, int hop)
{ … }
static int __deliver_to_subscribers(struct snd_seq_client *client,
struct snd_seq_event *event,
struct snd_seq_client_port *src_port,
int atomic, int hop)
{ … }
static int deliver_to_subscribers(struct snd_seq_client *client,
struct snd_seq_event *event,
int atomic, int hop)
{ … }
static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_event *event,
int atomic, int hop)
{ … }
int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
{ … }
static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
struct snd_seq_event *event,
struct file *file, int blocking,
int atomic, int hop,
struct mutex *mutexp)
{ … }
static int check_event_type_and_length(struct snd_seq_event *ev)
{ … }
static ssize_t snd_seq_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
{ … }
static __poll_t snd_seq_poll(struct file *file, poll_table * wait)
{ … }
static int snd_seq_ioctl_pversion(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_user_pversion(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_client_id(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void *arg)
{ … }
static void get_client_info(struct snd_seq_client *cptr,
struct snd_seq_client_info *info)
{ … }
static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_delete_port(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client, void *arg)
{ … }
#define PERM_RD …
#define PERM_WR …
static int check_subscription_permission(struct snd_seq_client *client,
struct snd_seq_client_port *sport,
struct snd_seq_client_port *dport,
struct snd_seq_port_subscribe *subs)
{ … }
int snd_seq_client_notify_subscription(int client, int port,
struct snd_seq_port_subscribe *info,
int evtype)
{ … }
static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client,
void *arg)
{ … }
int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
{ … }
EXPORT_SYMBOL(…);
static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_get_queue_client(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
{ … }
static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,
void *arg)
{ … }
static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client,
void *arg)
{ … }
#if IS_ENABLED(CONFIG_SND_SEQ_UMP)
#define NUM_UMP_INFOS …
static void free_ump_info(struct snd_seq_client *client)
{ … }
static void terminate_ump_info_strings(void *p, int type)
{ … }
#ifdef CONFIG_SND_PROC_FS
static void dump_ump_info(struct snd_info_buffer *buffer,
struct snd_seq_client *client)
{ … }
#endif
static int snd_seq_ioctl_client_ump_info(struct snd_seq_client *caller,
unsigned int cmd,
unsigned long arg)
{ … }
#endif
static const struct ioctl_handler { … } ioctl_handlers[] = …;
static long snd_seq_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{ … }
#ifdef CONFIG_COMPAT
#include "seq_compat.c"
#else
#define snd_seq_ioctl_compat …
#endif
int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
const char *name_fmt, ...)
{ … }
EXPORT_SYMBOL(…);
int snd_seq_delete_kernel_client(int client)
{ … }
EXPORT_SYMBOL(…);
int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev,
struct file *file, bool blocking)
{ … }
EXPORT_SYMBOL(…);
int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
int atomic, int hop)
{ … }
EXPORT_SYMBOL(…);
int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
{ … }
EXPORT_SYMBOL(…);
int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
{ … }
EXPORT_SYMBOL(…);
struct snd_seq_client *snd_seq_kernel_client_get(int id)
{ … }
EXPORT_SYMBOL_GPL(…);
void snd_seq_kernel_client_put(struct snd_seq_client *cptr)
{ … }
EXPORT_SYMBOL_GPL(…);
#ifdef CONFIG_SND_PROC_FS
static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer,
struct snd_seq_port_subs_info *group,
int is_src, char *msg)
{ … }
#define FLAG_PERM_RD(perm) …
#define FLAG_PERM_WR(perm) …
#define FLAG_PERM_EX(perm) …
#define FLAG_PERM_DUPLEX(perm) …
static const char *port_direction_name(unsigned char dir)
{ … }
static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
struct snd_seq_client *client)
{ … }
static const char *midi_version_string(unsigned int version)
{ … }
void snd_seq_info_clients_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{ … }
#endif
static const struct file_operations snd_seq_f_ops = …;
static struct device *seq_dev;
int __init snd_sequencer_device_init(void)
{ … }
void snd_sequencer_device_done(void)
{ … }