if (rcode == RCODE_COMPLETE && substream != NULL)
snd_rawmidi_transmit_ack(substream, port->consume_bytes);
+ else if (!rcode_is_permanent_error(rcode))
+ /* To start next transaction immediately for recovery. */
+ port->next_ktime = ktime_set(0, 0);
port->idling = true;
if (substream == NULL || snd_rawmidi_transmit_empty(substream))
return;
+ /* Do it in next chance. */
+ if (ktime_after(port->next_ktime, ktime_get())) {
+ schedule_work(&port->work);
+ return;
+ }
+
/*
* Fill the buffer. The callee must use snd_rawmidi_transmit_peek().
* Later, snd_rawmidi_transmit_ack() is called.
port->consume_bytes = port->fill(substream, port->buf);
if (port->consume_bytes <= 0) {
/* Do it in next chance, immediately. */
- if (port->consume_bytes == 0)
+ if (port->consume_bytes == 0) {
+ port->next_ktime = ktime_set(0, 0);
schedule_work(&port->work);
+ }
return;
}
else
type = TCODE_WRITE_BLOCK_REQUEST;
+ /* Set interval to next transaction. */
+ port->next_ktime = ktime_add_ns(ktime_get(),
+ port->consume_bytes * 8 * NSEC_PER_SEC / 31250);
+
/* Start this transaction. */
port->idling = false;
port->addr = addr;
port->fill = fill;
port->idling = true;
+ port->next_ktime = ktime_set(0, 0);
INIT_WORK(&port->work, midi_port_work);