sound/usb/midi.c

Source file repositories/reference/linux-study-clean/sound/usb/midi.c

File Facts

System
Linux kernel
Corpus path
sound/usb/midi.c
Extension
.c
Size
76160 bytes
Lines
2654
Domain
Driver Families
Bucket
sound/usb
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct usb_protocol_ops {
	void (*input)(struct snd_usb_midi_in_endpoint*, uint8_t*, int);
	void (*output)(struct snd_usb_midi_out_endpoint *ep, struct urb *urb);
	void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t);
	void (*init_out_endpoint)(struct snd_usb_midi_out_endpoint *);
	void (*finish_out_endpoint)(struct snd_usb_midi_out_endpoint *);
};

struct snd_usb_midi {
	struct usb_device *dev;
	struct snd_card *card;
	struct usb_interface *iface;
	const struct snd_usb_audio_quirk *quirk;
	struct snd_rawmidi *rmidi;
	const struct usb_protocol_ops *usb_protocol_ops;
	struct list_head list;
	struct timer_list error_timer;
	spinlock_t disc_lock;
	struct rw_semaphore disc_rwsem;
	struct mutex mutex;
	u32 usb_id;
	int next_midi_device;

	struct snd_usb_midi_endpoint {
		struct snd_usb_midi_out_endpoint *out;
		struct snd_usb_midi_in_endpoint *in;
	} endpoints[MIDI_MAX_ENDPOINTS];
	unsigned long input_triggered;
	unsigned int opened[2];
	unsigned char disconnected;
	unsigned char input_running;

	struct snd_kcontrol *roland_load_ctl;
};

struct snd_usb_midi_out_endpoint {
	struct snd_usb_midi *umidi;
	struct out_urb_context {
		struct urb *urb;
		struct snd_usb_midi_out_endpoint *ep;
	} urbs[OUTPUT_URBS];
	unsigned int active_urbs;
	unsigned int drain_urbs;
	int max_transfer;		/* size of urb buffer */
	struct work_struct work;
	unsigned int next_urb;
	spinlock_t buffer_lock;

	struct usbmidi_out_port {
		struct snd_usb_midi_out_endpoint *ep;
		struct snd_rawmidi_substream *substream;
		int active;
		uint8_t cable;		/* cable number << 4 */
		uint8_t state;
#define STATE_UNKNOWN	0
#define STATE_1PARAM	1
#define STATE_2PARAM_1	2
#define STATE_2PARAM_2	3
#define STATE_SYSEX_0	4
#define STATE_SYSEX_1	5
#define STATE_SYSEX_2	6
		uint8_t data[2];
	} ports[0x10];
	int current_port;

	wait_queue_head_t drain_wait;
};

struct snd_usb_midi_in_endpoint {
	struct snd_usb_midi *umidi;
	struct urb *urbs[INPUT_URBS];
	struct usbmidi_in_port {
		struct snd_rawmidi_substream *substream;
		u8 running_status_length;
	} ports[0x10];
	u8 seen_f5;
	bool in_sysex;
	u8 last_cin;
	u8 error_resubmit;
	int current_port;
};

static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep);

static const uint8_t snd_usbmidi_cin_length[] = {
	0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
};

/*
 * Submits the URB, with error handling.

Annotation

Implementation Notes