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;
 
        int generation;
        int type;
 
-       /* Under transacting. */
-       if (!port->idling)
+       /* Under transacting or error state. */
+       if (!port->idling || port->error)
                return;
 
        /* Nothing to do. */
                if (port->consume_bytes == 0) {
                        port->next_ktime = ktime_set(0, 0);
                        schedule_work(&port->work);
+               } else {
+                       /* Fatal error. */
+                       port->error = true;
                }
                return;
        }
        port->fill = fill;
        port->idling = true;
        port->next_ktime = ktime_set(0, 0);
+       port->error = false;
 
        INIT_WORK(&port->work, midi_port_work);
 
 
        struct work_struct work;
        bool idling;
        ktime_t next_ktime;
+       bool error;
 
        u64 addr;
        struct fw_transaction transaction;
 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);
+       }
 }
 
 /**
 snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port)
 {
        port->substream = NULL;
+       port->error = false;
 }
 
 #endif