From patchwork Fri Mar 14 14:41:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Sakamoto X-Patchwork-Id: 3832991 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E474D9F369 for ; Fri, 14 Mar 2014 14:42:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E0373202F0 for ; Fri, 14 Mar 2014 14:42:02 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 33D8420279 for ; Fri, 14 Mar 2014 14:42:01 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 2A7E726533F; Fri, 14 Mar 2014 15:41:59 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Status: No, score=-0.6 required=5.0 tests=BAYES_00, RCVD_IN_BL_SPAMCOP_NET,UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id E441D265383; Fri, 14 Mar 2014 15:41:48 +0100 (CET) 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 4F04F265450; Fri, 14 Mar 2014 15:41:45 +0100 (CET) Received: from smtp311.phy.lolipop.jp (smtp311.phy.lolipop.jp [210.157.22.79]) by alsa0.perex.cz (Postfix) with ESMTP id 1D70726533F for ; Fri, 14 Mar 2014 15:41:37 +0100 (CET) Received: from smtp311.phy.lolipop.lan (HELO smtp311.phy.lolipop.jp) (172.17.1.11) (smtp-auth username m12129643-o-takashi, mechanism plain) by smtp311.phy.lolipop.jp (qpsmtpd/0.82) with ESMTPA; Fri, 14 Mar 2014 23:41:35 +0900 Received: from 127.0.0.1 (127.0.0.1) by smtp311.phy.lolipop.jp (LOLIPOP-Fsecure); Fri, 14 Mar 2014 23:41:34 +0900 (JST) X-Virus-Status: clean(LOLIPOP-Fsecure) Message-ID: <5323151D.3010706@sakamocchi.jp> Date: Fri, 14 Mar 2014 23:41:33 +0900 From: Takashi Sakamoto User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-Version: 1.0 To: Clemens Ladisch , Stefan Richter Cc: "alsa-devel@alsa-project.org" , linux1394-devel@lists.sourceforge.net, "ffado-devel@lists.sf.net" Subject: [alsa-devel] [RFC] [PATCH] firewire-lib: add support for AV/C deferred transaction 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: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Clemens and Stefan, Can I request your comments about attached patch? This is for adding support of deferred transaction into snd-firewire-lib. I confirm some BeBoB devices use this type of transaction. If you have no negative comments, I'll add this patch for my series. For 'undefined interval' between INTERIM and final response, I want to use 'FCP_TIMEOUT_MS' (=125msec) again. In specifications which I can read, there is no limit for this interval. But I need to promise to finish this function for callers. According to AV/C general specification, targets can send INTERIM response one time. But this patch allows to accept several ITERIM responses for device quirks. I don't have devices which have such quirks, but there may be such devices and I want to make codes simpler. Regards Takashi Sakamoto o-takashi@sakamocchi.jp From 87b73cc7f5aa389101b362f21ddeb0f1a4cbe984 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Fri, 14 Mar 2014 13:17:43 +0900 Subject: [PATCH] firewire-lib: Add support for deferred transaction Some devices based on BeBoB use this type of transaction. 'Deferred Transaction' is defined in 'AV/C Digital Interface Command Set General Specification' and is used by targets to make a response deferred during processing it. If a target may not be able to complete a command within 100msec since receiving the command, then the target shall return INTERIM response, to which final response will follow later. CONTROL/NOTIFY commands are allowed for deferred transaction. There is an issue. In the specification, the interval between INTERIM response and final response is 'Unspecified interval'. The specification depends on each subunit specification for this interval. But we promise to finish this function for caller. In this reason, I use FCP_TIMEOUT_MS for this interval. Currently it's 125msec. Signed-off-by: Takashi Sakamoto --- sound/firewire/fcp.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/sound/firewire/fcp.c b/sound/firewire/fcp.c index 860c080..56d03fc 100644 --- a/sound/firewire/fcp.c +++ b/sound/firewire/fcp.c @@ -30,6 +30,7 @@ enum fcp_state { STATE_PENDING, STATE_BUS_RESET, STATE_COMPLETE, + STATE_DEFERRED, }; struct fcp_transaction { @@ -40,6 +41,7 @@ struct fcp_transaction { unsigned int response_match_bytes; enum fcp_state state; wait_queue_head_t wait; + bool deferrable; }; /** @@ -81,6 +83,9 @@ int fcp_avc_transaction(struct fw_unit *unit, t.state = STATE_PENDING; init_waitqueue_head(&t.wait); + if (*(const u8 *)command == 0x00 || *(const u8 *)command == 0x03) + t.deferrable = true; + spin_lock_irq(&transactions_lock); list_add_tail(&t.list, &transactions); spin_unlock_irq(&transactions_lock); @@ -93,17 +98,28 @@ int fcp_avc_transaction(struct fw_unit *unit, (void *)command, command_size, 0); if (ret < 0) break; - +deferred: wait_event_timeout(t.wait, t.state != STATE_PENDING, msecs_to_jiffies(FCP_TIMEOUT_MS)); - if (t.state == STATE_COMPLETE) { + if (t.state == STATE_DEFERRED) { + /* + * 'AV/C General Specification' define no time limit + * on command completion once an INTERIM response has + * been sent. but we promise to finish this function + * for a caller. Here we use FCP_TIMEOUT_MS for next + * interval. This is not in the specification. + */ + t.state = STATE_PENDING; + goto deferred; + } else if (t.state == STATE_COMPLETE) { ret = t.response_size; break; } else if (t.state == STATE_BUS_RESET) { msleep(ERROR_DELAY_MS); } else if (++tries >= ERROR_RETRIES) { - dev_err(&t.unit->device, "FCP command timed out\n"); + dev_err(&t.unit->device, + "FCP command timed out\n"); ret = -EIO; break; } @@ -132,7 +148,8 @@ void fcp_bus_reset(struct fw_unit *unit) spin_lock_irq(&transactions_lock); list_for_each_entry(t, &transactions, list) { if (t->unit == unit && - t->state == STATE_PENDING) { + (t->state == STATE_PENDING || + t->state == STATE_DEFERRED)) { t->state = STATE_BUS_RESET; wake_up(&t->wait); } @@ -186,10 +203,15 @@ static void fcp_response(struct fw_card *card, struct fw_request *request, if (t->state == STATE_PENDING && is_matching_response(t, data, length)) { - t->state = STATE_COMPLETE; - t->response_size = min((unsigned int)length, - t->response_size); - memcpy(t->response_buffer, data, t->response_size); + if (t->deferrable && *(const u8 *)data == 0x0f) { + t->state = STATE_DEFERRED; + } else { + t->state = STATE_COMPLETE; + t->response_size = min((unsigned int)length, + t->response_size); + memcpy(t->response_buffer, data, + t->response_size); + } wake_up(&t->wait); } } -- 1.8.3.2