linux/sound/usb/midi2.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * MIDI 2.0 support
 */

#include <linux/bitops.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/wait.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/usb/audio.h>
#include <linux/usb/midi.h>
#include <linux/usb/midi-v2.h>

#include <sound/core.h>
#include <sound/control.h>
#include <sound/ump.h>
#include "usbaudio.h"
#include "midi.h"
#include "midi2.h"
#include "helper.h"

static bool midi2_enable =;
module_param(midi2_enable, bool, 0444);
MODULE_PARM_DESC();

static bool midi2_ump_probe =;
module_param(midi2_ump_probe, bool, 0444);
MODULE_PARM_DESC();

/* stream direction; just shorter names */
enum {};

#define NUM_URBS

struct snd_usb_midi2_urb;
struct snd_usb_midi2_endpoint;
struct snd_usb_midi2_ump;
struct snd_usb_midi2_interface;

/* URB context */
struct snd_usb_midi2_urb {};

/* A USB MIDI input/output endpoint */
struct snd_usb_midi2_endpoint {};

/* A UMP endpoint - one or two USB MIDI endpoints are assigned */
struct snd_usb_midi2_ump {};

/* top-level instance per USB MIDI interface */
struct snd_usb_midi2_interface {};

/* submit URBs as much as possible; used for both input and output */
static void do_submit_urbs_locked(struct snd_usb_midi2_endpoint *ep,
				  int (*prepare)(struct snd_usb_midi2_endpoint *,
						 struct urb *))
{}

/* prepare for output submission: copy from rawmidi buffer to urb packet */
static int prepare_output_urb(struct snd_usb_midi2_endpoint *ep,
			      struct urb *urb)
{}

static void submit_output_urbs_locked(struct snd_usb_midi2_endpoint *ep)
{}

/* URB completion for output; re-filling and re-submit */
static void output_urb_complete(struct urb *urb)
{}

/* prepare for input submission: just set the buffer length */
static int prepare_input_urb(struct snd_usb_midi2_endpoint *ep,
			     struct urb *urb)
{}

static void submit_input_urbs_locked(struct snd_usb_midi2_endpoint *ep)
{}

/* URB completion for input; copy into rawmidi buffer and resubmit */
static void input_urb_complete(struct urb *urb)
{}

/* URB submission helper; for both direction */
static void submit_io_urbs(struct snd_usb_midi2_endpoint *ep)
{}

/* kill URBs for close, suspend and disconnect */
static void kill_midi_urbs(struct snd_usb_midi2_endpoint *ep, bool suspending)
{}

/* wait until all URBs get freed */
static void drain_urb_queue(struct snd_usb_midi2_endpoint *ep)
{}

/* release URBs for an EP */
static void free_midi_urbs(struct snd_usb_midi2_endpoint *ep)
{}

/* allocate URBs for an EP */
/* the callers should handle allocation errors via free_midi_urbs() */
static int alloc_midi_urbs(struct snd_usb_midi2_endpoint *ep)
{}

static struct snd_usb_midi2_endpoint *
ump_to_endpoint(struct snd_ump_endpoint *ump, int dir)
{}

/* ump open callback */
static int snd_usb_midi_v2_open(struct snd_ump_endpoint *ump, int dir)
{}

/* ump close callback */
static void snd_usb_midi_v2_close(struct snd_ump_endpoint *ump, int dir)
{}

/* ump trigger callback */
static void snd_usb_midi_v2_trigger(struct snd_ump_endpoint *ump, int dir,
				    int up)
{}

/* ump drain callback */
static void snd_usb_midi_v2_drain(struct snd_ump_endpoint *ump, int dir)
{}

/* allocate and start all input streams */
static int start_input_streams(struct snd_usb_midi2_interface *umidi)
{}

static const struct snd_ump_ops snd_usb_midi_v2_ump_ops =;

/* create a USB MIDI 2.0 endpoint object */
static int create_midi2_endpoint(struct snd_usb_midi2_interface *umidi,
				 struct usb_host_endpoint *hostep,
				 const struct usb_ms20_endpoint_descriptor *ms_ep)
{}

/* destructor for endpoint; from snd_usb_midi_v2_free() */
static void free_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)
{}

/* call all endpoint destructors */
static void free_all_midi2_endpoints(struct snd_usb_midi2_interface *umidi)
{}

/* find a MIDI STREAMING descriptor with a given subtype */
static void *find_usb_ms_endpoint_descriptor(struct usb_host_endpoint *hostep,
					     unsigned char subtype)
{}

/* get the full group terminal block descriptors and return the size */
static int get_group_terminal_block_descs(struct snd_usb_midi2_interface *umidi)
{}

/* find the corresponding group terminal block descriptor */
static const struct usb_ms20_gr_trm_block_descriptor *
find_group_terminal_block(struct snd_usb_midi2_interface *umidi, int id)
{}

/* fill up the information from GTB */
static int parse_group_terminal_block(struct snd_usb_midi2_ump *rmidi,
				      const struct usb_ms20_gr_trm_block_descriptor *desc)
{}

/* allocate and parse for each assigned group terminal block */
static int parse_group_terminal_blocks(struct snd_usb_midi2_interface *umidi)
{}

/* parse endpoints included in the given interface and create objects */
static int parse_midi_2_0_endpoints(struct snd_usb_midi2_interface *umidi)
{}

static void free_all_midi2_umps(struct snd_usb_midi2_interface *umidi)
{}

static int create_midi2_ump(struct snd_usb_midi2_interface *umidi,
			    struct snd_usb_midi2_endpoint *ep_in,
			    struct snd_usb_midi2_endpoint *ep_out,
			    int blk_id)
{}

/* find the UMP EP with the given USB block id */
static struct snd_usb_midi2_ump *
find_midi2_ump(struct snd_usb_midi2_interface *umidi, int blk_id)
{}

/* look for the matching output endpoint and create UMP object if found */
static int find_matching_ep_partner(struct snd_usb_midi2_interface *umidi,
				    struct snd_usb_midi2_endpoint *ep,
				    int blk_id)
{}

/* Call UMP helper to parse UMP endpoints;
 * this needs to be called after starting the input streams for bi-directional
 * communications
 */
static int parse_ump_endpoints(struct snd_usb_midi2_interface *umidi)
{}

/* create a UMP block from a GTB entry */
static int create_gtb_block(struct snd_usb_midi2_ump *rmidi, int dir, int blk)
{}

/* Create UMP blocks for each UMP EP */
static int create_blocks_from_gtb(struct snd_usb_midi2_interface *umidi)
{}

/* attach legacy rawmidis */
static int attach_legacy_rawmidi(struct snd_usb_midi2_interface *umidi)
{}

static void snd_usb_midi_v2_free(struct snd_usb_midi2_interface *umidi)
{}

/* parse the interface for MIDI 2.0 */
static int parse_midi_2_0(struct snd_usb_midi2_interface *umidi)
{}

/* is the given interface for MIDI 2.0? */
static bool is_midi2_altset(struct usb_host_interface *hostif)
{}

/* change the altsetting */
static int set_altset(struct snd_usb_midi2_interface *umidi)
{}

/* fill UMP Endpoint name string from USB descriptor */
static void fill_ump_ep_name(struct snd_ump_endpoint *ump,
			     struct usb_device *dev, int id)
{}

/* fill the fallback name string for each rawmidi instance */
static void set_fallback_rawmidi_names(struct snd_usb_midi2_interface *umidi)
{}

/* create MIDI interface; fallback to MIDI 1.0 if needed */
int snd_usb_midi_v2_create(struct snd_usb_audio *chip,
			   struct usb_interface *iface,
			   const struct snd_usb_audio_quirk *quirk,
			   unsigned int usb_id)
{}

static void suspend_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)
{}

void snd_usb_midi_v2_suspend_all(struct snd_usb_audio *chip)
{}

static void resume_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)
{}

void snd_usb_midi_v2_resume_all(struct snd_usb_audio *chip)
{}

void snd_usb_midi_v2_disconnect_all(struct snd_usb_audio *chip)
{}

/* release the MIDI instance */
void snd_usb_midi_v2_free_all(struct snd_usb_audio *chip)
{}