sound/usb/bcd2000/bcd2000.c

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

File Facts

System
Linux kernel
Corpus path
sound/usb/bcd2000/bcd2000.c
Extension
.c
Size
11299 bytes
Lines
453
Domain
Driver Families
Bucket
sound/usb
Inferred role
Driver Families: implementation source
Status
source 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 bcd2000 {
	struct usb_device *dev;
	struct snd_card *card;
	struct usb_interface *intf;
	int card_index;

	int midi_out_active;
	struct snd_rawmidi *rmidi;
	struct snd_rawmidi_substream *midi_receive_substream;
	struct snd_rawmidi_substream *midi_out_substream;

	unsigned char midi_in_buf[BUFSIZE];
	unsigned char midi_out_buf[BUFSIZE];

	struct urb *midi_out_urb;
	struct urb *midi_in_urb;

	struct usb_anchor anchor;
};

static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;

static DEFINE_MUTEX(devices_mutex);
static DECLARE_BITMAP(devices_used, SNDRV_CARDS);
static struct usb_driver bcd2000_driver;

#ifdef CONFIG_SND_DEBUG
static void bcd2000_dump_buffer(const char *prefix, const char *buf, int len)
{
	print_hex_dump(KERN_DEBUG, prefix,
			DUMP_PREFIX_NONE, 16, 1,
			buf, len, false);
}
#else
static void bcd2000_dump_buffer(const char *prefix, const char *buf, int len) {}
#endif

static int bcd2000_midi_input_open(struct snd_rawmidi_substream *substream)
{
	return 0;
}

static int bcd2000_midi_input_close(struct snd_rawmidi_substream *substream)
{
	return 0;
}

/* (de)register midi substream from client */
static void bcd2000_midi_input_trigger(struct snd_rawmidi_substream *substream,
						int up)
{
	struct bcd2000 *bcd2k = substream->rmidi->private_data;
	bcd2k->midi_receive_substream = up ? substream : NULL;
}

static void bcd2000_midi_handle_input(struct bcd2000 *bcd2k,
				const unsigned char *buf, unsigned int buf_len)
{
	unsigned int payload_length, tocopy;
	struct snd_rawmidi_substream *midi_receive_substream;

	midi_receive_substream = READ_ONCE(bcd2k->midi_receive_substream);
	if (!midi_receive_substream)
		return;

	bcd2000_dump_buffer(PREFIX "received from device: ", buf, buf_len);

	if (buf_len < 2)
		return;

	payload_length = buf[0];

	/* ignore packets without payload */
	if (payload_length == 0)
		return;

	tocopy = min(payload_length, buf_len-1);

	bcd2000_dump_buffer(PREFIX "sending to userspace: ",
					&buf[1], tocopy);

	snd_rawmidi_receive(midi_receive_substream,
					&buf[1], tocopy);
}

static void bcd2000_midi_send(struct bcd2000 *bcd2k)
{
	int len, ret;
	struct snd_rawmidi_substream *midi_out_substream;

Annotation

Implementation Notes