From patchwork Thu Oct 8 23:10:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 7356981 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 5C4FF9F4DC for ; Thu, 8 Oct 2015 23:12:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5CBFB207B2 for ; Thu, 8 Oct 2015 23:12:38 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id EE2F62078D for ; Thu, 8 Oct 2015 23:12:36 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 0B63D2668FD; Fri, 9 Oct 2015 01:12:36 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 66299266825; Fri, 9 Oct 2015 01:10:50 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id EC86726680B; Fri, 9 Oct 2015 01:10:44 +0200 (CEST) Received: from smtp302.phy.lolipop.jp (smtp302.phy.lolipop.jp [210.157.22.85]) by alsa0.perex.cz (Postfix) with ESMTP id 68DC126512F for ; Fri, 9 Oct 2015 01:10:34 +0200 (CEST) Received: from smtp302.phy.lolipop.lan (HELO smtp302.phy.lolipop.jp) (172.17.1.85) (smtp-auth username m12129643-o-takashi, mechanism plain) by smtp302.phy.lolipop.jp (qpsmtpd/0.82) with ESMTPA; Fri, 09 Oct 2015 08:10:32 +0900 Received: from 127.0.0.1 (127.0.0.1) by smtp302.phy.lolipop.jp (LOLIPOP-Fsecure); Fri, 09 Oct 2015 08:10:29 +0900 (JST) X-Virus-Status: clean(LOLIPOP-Fsecure) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Fri, 9 Oct 2015 08:10:28 +0900 Message-Id: <1444345829-17408-5-git-send-email-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1444345829-17408-1-git-send-email-o-takashi@sakamocchi.jp> References: <1444345829-17408-1-git-send-email-o-takashi@sakamocchi.jp> Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sf.net Subject: [alsa-devel] [PATCH 4/5] ALSA: firewire-lib: add throttle for MIDI data rate X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Typically, the target devices have internal buffer to adjust output of received MIDI messages for MIDI serial bus, while the capacity of the buffer is limited. IEEE 1394 transactions can transfer more MIDI messages than MIDI serial bus can. This can cause buffer over flow in device side. This commit adds throttle to limit MIDI data rate by counting intervals between two MIDI messages. Usual MIDI messages consists of two or three bytes. This requires 1.302 to 1.953 mili-seconds interval between these messages. This commit uses kernel monotonic time service to calculate the time of next transaction. Signed-off-by: Takashi Sakamoto --- sound/firewire/lib.c | 18 +++++++++++++++++- sound/firewire/lib.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/sound/firewire/lib.c b/sound/firewire/lib.c index 3e9afd7..9a98c7c 100644 --- a/sound/firewire/lib.c +++ b/sound/firewire/lib.c @@ -76,6 +76,9 @@ 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); + else if (!rcode_is_permanent_error(rcode)) + /* To start next transaction immediately for recovery. */ + port->next_ktime = ktime_set(0, 0); port->idling = true; @@ -99,6 +102,12 @@ static void midi_port_work(struct work_struct *work) 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. @@ -107,8 +116,10 @@ static void midi_port_work(struct work_struct *work) 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; } @@ -118,6 +129,10 @@ static void midi_port_work(struct work_struct *work) 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; @@ -162,6 +177,7 @@ int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port, port->addr = addr; port->fill = fill; port->idling = true; + port->next_ktime = ktime_set(0, 0); INIT_WORK(&port->work, midi_port_work); diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h index 0af06f4..59e0865 100644 --- a/sound/firewire/lib.h +++ b/sound/firewire/lib.h @@ -31,6 +31,7 @@ struct snd_fw_async_midi_port { struct fw_device *parent; struct work_struct work; bool idling; + ktime_t next_ktime; u64 addr; struct fw_transaction transaction;