2019-05-27 08:55:05 +02:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2005-04-16 15:20:36 -07:00
/*
* ALSA sequencer Client Manager
* Copyright ( c ) 1998 - 1999 by Frank van de Pol < fvdpol @ coil . demon . nl >
*/
# ifndef __SND_SEQ_CLIENTMGR_H
# define __SND_SEQ_CLIENTMGR_H
# include <sound/seq_kernel.h>
# include <linux/bitops.h>
# include "seq_fifo.h"
# include "seq_ports.h"
# include "seq_lock.h"
/* client manager */
2005-11-17 14:04:02 +01:00
struct snd_seq_user_client {
2005-04-16 15:20:36 -07:00
struct file * file ; /* file struct of client */
/* ... */
2016-03-02 19:26:28 +01:00
struct pid * owner ;
2005-04-16 15:20:36 -07:00
/* fifo */
2005-11-17 14:04:02 +01:00
struct snd_seq_fifo * fifo ; /* queue for incoming events */
2005-04-16 15:20:36 -07:00
int fifo_pool_size ;
} ;
2005-11-17 14:04:02 +01:00
struct snd_seq_kernel_client {
2005-04-16 15:20:36 -07:00
/* ... */
2016-03-02 19:26:28 +01:00
struct snd_card * card ;
2005-04-16 15:20:36 -07:00
} ;
2005-11-17 14:04:02 +01:00
struct snd_seq_client {
2005-04-16 15:20:36 -07:00
snd_seq_client_type_t type ;
unsigned int accept_input : 1 ,
accept_output : 1 ;
ALSA: seq: Add UMP support
Starting from this commit, we add the basic support of UMP (Universal
MIDI Packet) events on ALSA sequencer infrastructure. The biggest
change here is that, for transferring UMP packets that are up to 128
bits, we extend the data payload of ALSA sequencer event record when
the client is declared to support for the new UMP events.
A new event flag bit, SNDRV_SEQ_EVENT_UMP, is defined and it shall be
set for the UMP packet events that have the larger payload of 128
bits, defined as struct snd_seq_ump_event.
For controlling the UMP feature enablement in kernel, a new Kconfig,
CONFIG_SND_SEQ_UMP is introduced. The extended event for UMP is
available only when this Kconfig item is set. Similarly, the size of
the internal snd_seq_event_cell also increases (in 4 bytes) when the
Kconfig item is set. (But the size increase is effective only for
32bit architectures; 64bit archs already have padding there.)
Overall, when CONFIG_SND_SEQ_UMP isn't set, there is no change in the
event and cell, keeping the old sizes.
For applications that want to access the UMP packets, first of all, a
sequencer client has to declare the user-protocol to match with the
latest one via the new SNDRV_SEQ_IOCTL_USER_PVERSION; otherwise it's
treated as if a legacy client without UMP support.
Then the client can switch to the new UMP mode (MIDI 1.0 or MIDI 2.0)
with a new field, midi_version, in snd_seq_client_info. When switched
to UMP mode (midi_version = 1 or 2), the client can write the UMP
events with SNDRV_SEQ_EVENT_UMP flag. For reads, the alignment size
is changed from snd_seq_event (28 bytes) to snd_seq_ump_event (32
bytes). When a UMP sequencer event is delivered to a legacy sequencer
client, it's ignored or handled as an error.
Conceptually, ALSA sequencer client and port correspond to the UMP
Endpoint and Group, respectively; each client may have multiple ports
and each port has the fixed number (16) of channels, total up to 256
channels.
As of this commit, ALSA sequencer core just sends and receives the UMP
events as-is from/to clients. The automatic conversions between the
legacy events and the new UMP events will be implemented in a later
patch.
Along with this commit, bump the sequencer protocol version to 1.0.3.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-26-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-05-23 09:53:46 +02:00
unsigned int midi_version ;
2023-05-23 09:53:45 +02:00
unsigned int user_pversion ;
2005-04-16 15:20:36 -07:00
char name [ 64 ] ; /* client name */
int number ; /* client number */
unsigned int filter ; /* filter flags */
DECLARE_BITMAP ( event_filter , 256 ) ;
2023-05-23 09:53:57 +02:00
unsigned short group_filter ;
2005-04-16 15:20:36 -07:00
snd_use_lock_t use_lock ;
int event_lost ;
/* ports */
int num_ports ; /* number of ports */
struct list_head ports_list_head ;
rwlock_t ports_lock ;
2006-01-16 16:29:08 +01:00
struct mutex ports_mutex ;
2018-01-09 23:11:03 +01:00
struct mutex ioctl_mutex ;
2005-04-16 15:20:36 -07:00
int convert32 ; /* convert 32->64bit */
2023-05-23 09:53:48 +02:00
int ump_endpoint_port ;
2005-04-16 15:20:36 -07:00
/* output pool */
2005-11-17 14:04:02 +01:00
struct snd_seq_pool * pool ; /* memory pool for this client */
2005-04-16 15:20:36 -07:00
union {
2005-11-17 14:04:02 +01:00
struct snd_seq_user_client user ;
struct snd_seq_kernel_client kernel ;
2005-04-16 15:20:36 -07:00
} data ;
2023-05-23 09:53:55 +02:00
/* for UMP */
void * * ump_info ;
2005-04-16 15:20:36 -07:00
} ;
/* usage statistics */
2005-11-17 14:04:02 +01:00
struct snd_seq_usage {
2005-04-16 15:20:36 -07:00
int cur ;
int peak ;
2005-11-17 14:04:02 +01:00
} ;
2005-04-16 15:20:36 -07:00
2005-11-17 14:04:02 +01:00
int client_init_data ( void ) ;
int snd_sequencer_device_init ( void ) ;
void snd_sequencer_device_done ( void ) ;
2005-04-16 15:20:36 -07:00
/* get locked pointer to client */
2005-11-17 14:04:02 +01:00
struct snd_seq_client * snd_seq_client_use_ptr ( int clientid ) ;
2005-04-16 15:20:36 -07:00
/* unlock pointer to client */
# define snd_seq_client_unlock(client) snd_use_lock_free(&(client)->use_lock)
/* dispatch event to client(s) */
2005-11-17 14:04:02 +01:00
int snd_seq_dispatch_event ( struct snd_seq_event_cell * cell , int atomic , int hop ) ;
2005-04-16 15:20:36 -07:00
int snd_seq_kernel_client_write_poll ( int clientid , struct file * file , poll_table * wait ) ;
2005-11-17 14:04:02 +01:00
int snd_seq_client_notify_subscription ( int client , int port ,
struct snd_seq_port_subscribe * info , int evtype ) ;
2005-04-16 15:20:36 -07:00
2023-05-23 09:53:51 +02:00
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 ) ;
2019-04-12 12:44:39 +02:00
/* only for OSS sequencer */
bool snd_seq_client_ioctl_lock ( int clientid ) ;
void snd_seq_client_ioctl_unlock ( int clientid ) ;
2007-12-14 12:59:50 +01:00
extern int seq_client_load [ 15 ] ;
2023-05-23 09:53:40 +02:00
/* for internal use between kernel sequencer clients */
struct snd_seq_client * snd_seq_kernel_client_get ( int client ) ;
void snd_seq_kernel_client_put ( struct snd_seq_client * cptr ) ;
2023-05-23 09:53:51 +02:00
static inline bool snd_seq_client_is_ump ( struct snd_seq_client * c )
{
return c - > midi_version ! = SNDRV_SEQ_CLIENT_LEGACY_MIDI ;
}
static inline bool snd_seq_client_is_midi2 ( struct snd_seq_client * c )
{
return c - > midi_version = = SNDRV_SEQ_CLIENT_UMP_MIDI_2_0 ;
}
2005-04-16 15:20:36 -07:00
# endif