summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/firewire/lib.c11
-rw-r--r--sound/firewire/lib.h8
2 files changed, 15 insertions, 4 deletions
diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c
index 9a98c7cd8744..edf1c8bd25a6 100644
--- a/sound/firewire/lib.c
+++ b/sound/firewire/lib.c
@@ -79,6 +79,9 @@ static void async_midi_port_callback(struct fw_card *card, int rcode,
else if (!rcode_is_permanent_error(rcode))
/* To start next transaction immediately for recovery. */
port->next_ktime = ktime_set(0, 0);
+ else
+ /* Don't continue processing. */
+ port->error = true;
port->idling = true;
@@ -94,8 +97,8 @@ static void midi_port_work(struct work_struct *work)
int generation;
int type;
- /* Under transacting. */
- if (!port->idling)
+ /* Under transacting or error state. */
+ if (!port->idling || port->error)
return;
/* Nothing to do. */
@@ -119,6 +122,9 @@ static void midi_port_work(struct work_struct *work)
if (port->consume_bytes == 0) {
port->next_ktime = ktime_set(0, 0);
schedule_work(&port->work);
+ } else {
+ /* Fatal error. */
+ port->error = true;
}
return;
}
@@ -178,6 +184,7 @@ int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,
port->fill = fill;
port->idling = true;
port->next_ktime = ktime_set(0, 0);
+ port->error = false;
INIT_WORK(&port->work, midi_port_work);
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
index 59e086587212..f3f6f84c48d6 100644
--- a/sound/firewire/lib.h
+++ b/sound/firewire/lib.h
@@ -32,6 +32,7 @@ struct snd_fw_async_midi_port {
struct work_struct work;
bool idling;
ktime_t next_ktime;
+ bool error;
u64 addr;
struct fw_transaction transaction;
@@ -58,8 +59,10 @@ static inline void
snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port,
struct snd_rawmidi_substream *substream)
{
- port->substream = substream;
- schedule_work(&port->work);
+ if (!port->error) {
+ port->substream = substream;
+ schedule_work(&port->work);
+ }
}
/**
@@ -70,6 +73,7 @@ static inline void
snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port)
{
port->substream = NULL;
+ port->error = false;
}
#endif