sound/firewire/oxfw/oxfw-midi.c

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

File Facts

System
Linux kernel
Corpus path
sound/firewire/oxfw/oxfw-midi.c
Extension
.c
Size
4257 bytes
Lines
181
Domain
Driver Families
Bucket
sound/firewire
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

if (err >= 0) {
			++oxfw->substreams_count;
			err = snd_oxfw_stream_start_duplex(oxfw);
			if (err < 0)
				--oxfw->substreams_count;
		}
	}

	if (err < 0)
		snd_oxfw_stream_lock_release(oxfw);

	return err;
}

static int midi_playback_open(struct snd_rawmidi_substream *substream)
{
	struct snd_oxfw *oxfw = substream->rmidi->private_data;
	int err;

	err = snd_oxfw_stream_lock_try(oxfw);
	if (err < 0)
		return err;

	scoped_guard(mutex, &oxfw->mutex) {
		err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 0, 0, 0, 0);
		if (err >= 0) {
			++oxfw->substreams_count;
			err = snd_oxfw_stream_start_duplex(oxfw);
		}
	}

	if (err < 0)
		snd_oxfw_stream_lock_release(oxfw);

	return err;
}

static int midi_capture_close(struct snd_rawmidi_substream *substream)
{
	struct snd_oxfw *oxfw = substream->rmidi->private_data;

	scoped_guard(mutex, &oxfw->mutex) {
		--oxfw->substreams_count;
		snd_oxfw_stream_stop_duplex(oxfw);
	}

	snd_oxfw_stream_lock_release(oxfw);
	return 0;
}

static int midi_playback_close(struct snd_rawmidi_substream *substream)
{
	struct snd_oxfw *oxfw = substream->rmidi->private_data;

	scoped_guard(mutex, &oxfw->mutex) {
		--oxfw->substreams_count;
		snd_oxfw_stream_stop_duplex(oxfw);
	}

	snd_oxfw_stream_lock_release(oxfw);
	return 0;
}

static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up)
{
	struct snd_oxfw *oxfw = substrm->rmidi->private_data;

	guard(spinlock_irqsave)(&oxfw->lock);

	if (up)
		amdtp_am824_midi_trigger(&oxfw->tx_stream,
					 substrm->number, substrm);
	else
		amdtp_am824_midi_trigger(&oxfw->tx_stream,
					 substrm->number, NULL);
}

static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up)
{
	struct snd_oxfw *oxfw = substrm->rmidi->private_data;

	guard(spinlock_irqsave)(&oxfw->lock);

	if (up)
		amdtp_am824_midi_trigger(&oxfw->rx_stream,
					 substrm->number, substrm);
	else
		amdtp_am824_midi_trigger(&oxfw->rx_stream,
					 substrm->number, NULL);
}

Annotation

Implementation Notes