From patchwork Thu Aug 13 00:20:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 7004841 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A31D5C05AC for ; Thu, 13 Aug 2015 00:22:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A68CF20741 for ; Thu, 13 Aug 2015 00:22:31 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 6DC4B2045B for ; Thu, 13 Aug 2015 00:22:30 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 56E54265208; Thu, 13 Aug 2015 02:22:29 +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,NO_DNS_FOR_FROM, RCVD_IN_DNSWL_LOW,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 95FF72616F3; Thu, 13 Aug 2015 02:20:48 +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 BA0FA2616F3; Thu, 13 Aug 2015 02:20:45 +0200 (CEST) Received: from smtp301.phy.lolipop.jp (smtp301.phy.lolipop.jp [210.157.22.84]) by alsa0.perex.cz (Postfix) with ESMTP id 91E45261551 for ; Thu, 13 Aug 2015 02:20:36 +0200 (CEST) Received: from smtp301.phy.lolipop.lan (HELO smtp301.phy.lolipop.jp) (172.17.1.84) (smtp-auth username m12129643-o-takashi, mechanism plain) by smtp301.phy.lolipop.jp (qpsmtpd/0.82) with ESMTPA; Thu, 13 Aug 2015 09:20:32 +0900 Received: from 127.0.0.1 (127.0.0.1) by smtp301.phy.lolipop.jp (LOLIPOP-Fsecure); Thu, 13 Aug 2015 09:20:22 +0900 (JST) X-Virus-Status: clean(LOLIPOP-Fsecure) From: Takashi Sakamoto To: clemens@ladisch.de, tiwai@suse.de Date: Thu, 13 Aug 2015 09:20:02 +0900 Message-Id: <1439425221-30826-7-git-send-email-o-takashi@sakamocchi.jp> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1439425221-30826-1-git-send-email-o-takashi@sakamocchi.jp> References: <1439425221-30826-1-git-send-email-o-takashi@sakamocchi.jp> Cc: alsa-devel@alsa-project.org, ffado-devel@lists.sf.net Subject: [alsa-devel] [PATCH 06/25] 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 by jiffies 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. Using jiffies for this purpose is not perfect idea. Further work is needed for better implementation. 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 e309b9b..452728c 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_tick = 0; port->idling = true; @@ -99,6 +102,12 @@ static void midi_port_tasklet(unsigned long data) if (substream == NULL || snd_rawmidi_transmit_empty(substream)) return; + /* Do it in next chance. */ + if (time_is_after_jiffies(port->next_tick)) { + tasklet_schedule(&port->tasklet); + return; + } + /* * Fill the buffer. The callee must use snd_rawmidi_transmit_peek(). * Later, snd_rawmidi_transmit_ack() may be called. @@ -107,8 +116,10 @@ static void midi_port_tasklet(unsigned long data) port->consume_bytes = port->packetize(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_tick = 0; tasklet_schedule(&port->tasklet); + } return; } @@ -118,6 +129,10 @@ static void midi_port_tasklet(unsigned long data) else type = TCODE_WRITE_BLOCK_REQUEST; + /* Set interval to next transaction. */ + port->next_tick = + jiffies_64 + msecs_to_jiffies(port->consume_bytes * 8 / 31250); + /* Start this transaction. */ port->idling = false; generation = port->parent->generation; @@ -153,6 +168,7 @@ int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port, port->addr = addr; port->packetize = packetize; port->idling = true; + port->next_tick = 0; tasklet_init(&port->tasklet, midi_port_tasklet, (unsigned long)port); diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h index 9d76f5c..e4b00e2 100644 --- a/sound/firewire/lib.h +++ b/sound/firewire/lib.h @@ -26,6 +26,7 @@ struct snd_fw_async_midi_port { struct fw_device *parent; struct tasklet_struct tasklet; bool idling; + unsigned long next_tick; __u64 addr; struct fw_transaction transaction;