Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3ef9cb9 authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai
Browse files

ALSA: firewire-lib: add a restriction for a transaction at once



Currently, when waiting for a response, callers can start another
transaction by scheduling another work. This is not good for error
processing of transaction, especially the first response is too late.

This commit serialize request/response transactions, by adding one
boolean member to represent idling state.

Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 585d7cba
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ static void async_midi_port_callback(struct fw_card *card, int rcode,

	if (rcode == RCODE_COMPLETE && substream != NULL)
		snd_rawmidi_transmit_ack(substream, port->consume_bytes);

	port->idling = true;
}

static void midi_port_work(struct work_struct *work)
@@ -86,6 +88,10 @@ static void midi_port_work(struct work_struct *work)
	int generation;
	int type;

	/* Under transacting. */
	if (!port->idling)
		return;

	/* Nothing to do. */
	if (substream == NULL || snd_rawmidi_transmit_empty(substream))
		return;
@@ -110,6 +116,8 @@ static void midi_port_work(struct work_struct *work)
		type = TCODE_WRITE_BLOCK_REQUEST;

	/* Start this transaction. */
	port->idling = false;

	/*
	 * In Linux FireWire core, when generation is updated with memory
	 * barrier, node id has already been updated. In this module, After
@@ -150,6 +158,7 @@ int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
	port->parent = fw_parent_device(unit);
	port->addr = addr;
	port->fill = fill;
	port->idling = true;

	INIT_WORK(&port->work, midi_port_work);

+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ typedef int (*snd_fw_async_midi_port_fill)(
struct snd_fw_async_midi_port {
	struct fw_device *parent;
	struct work_struct work;
	bool idling;

	u64 addr;
	struct fw_transaction transaction;