From patchwork Fri Sep 26 08:03:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 4979151 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 8897E9F402 for ; Fri, 26 Sep 2014 08:03:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8214F202E5 for ; Fri, 26 Sep 2014 08:03:40 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id C0F55202BE for ; Fri, 26 Sep 2014 08:03:37 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 9B082260484; Fri, 26 Sep 2014 10:03:33 +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=-1.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 75022260474; Fri, 26 Sep 2014 10:03:22 +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 161DB260475; Fri, 26 Sep 2014 10:03:21 +0200 (CEST) Received: from mail-pa0-f54.google.com (mail-pa0-f54.google.com [209.85.220.54]) by alsa0.perex.cz (Postfix) with ESMTP id D86C0260472 for ; Fri, 26 Sep 2014 10:03:12 +0200 (CEST) Received: by mail-pa0-f54.google.com with SMTP id ey11so879266pad.13 for ; Fri, 26 Sep 2014 01:03:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:message-id:from:to:cc:subject:in-reply-to:references :user-agent:mime-version:content-type; bh=jcWNrUrrpPDWnqj0hMI2w1FFz+EipmpoVf+v/gNIe/4=; b=B35omWG8swyWx6X9oJqijST2ZTlgT7vJio9bYK5xfJeV++jxMxC4f1diPX9VePlrXR Q4+BDXiQs3oPROvcWpcVW0k3mQ9IlAjRcpZ0LaL78GOMaTRNUNK37MDMBhVdJNgJFNej 2rzGpUoe0XOPOINA7q8PwuKkK4LkvjG+UxOuVR/yr14zF4IYD3epnbpRKOuYPaXauWhx mOHPoIWotwQbdtF5xKgIHg6alqqGX+XB3z8tIGUhBpqXYVtL6tQFZAJeOKFk/0i52CJT wH5GFRgwTFlwEnQsvUS5QBljaVWq4cb/LyZH3vRJlvlazMD4YMVFSSKLb2MH+wEoPz6K yXbw== X-Received: by 10.70.128.1 with SMTP id nk1mr35507998pdb.97.1411718591239; Fri, 26 Sep 2014 01:03:11 -0700 (PDT) Received: from remon.gmail.com (49.14.32.202.bf.2iij.net. [202.32.14.49]) by mx.google.com with ESMTPSA id nv1sm4167257pbc.18.2014.09.26.01.03.08 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 26 Sep 2014 01:03:10 -0700 (PDT) Date: Fri, 26 Sep 2014 01:03:10 -0700 (PDT) Message-ID: <87lhp6n70k.wl%kuninori.morimoto.gx@gmail.com> From: Kuninori Morimoto To: Clemens Ladisch In-Reply-To: <54251749.4040603@ladisch.de> References: <87wq8rm20r.wl%kuninori.morimoto.gx@gmail.com> <54251749.4040603@ladisch.de> User-Agent: Wanderlust/2.14.0 Emacs/23.3 Mule/6.0 MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Cc: Linux-ALSA , Mark Brown , "shiiba \(Renesas\)" , Kuninori Morimoto Subject: Re: [alsa-devel] Question about SNDRV_PCM_STATE_DRAINING and DMA transfer 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 Hi Clemens Thank you for your explain > > We noticed that DMA seems transfered +1 time when Ctrl-C happen. > > But, is this correct ? is this our driver bug ? > > [...] > > 7. DMA transfer interrupt happen > > > > It calls snd_pcm_period_elapsed() and try to transfer next 2048 byte > > snd_pcm_playback_avail() in snd_pcm_update_state() return 8192 this time. > > then, it calls snd_pcm_drain_done() > > > > 9. snd_soc_dai_ops :: trigger called with SNDRV_PCM_TRIGGER_STOP > > > > driver stops DMA transfer > > There is no strong synchronization between snd_pcm_drain() and the rest > of the system; snd_pcm_drain() just waits for an underrun to happen. > > In other words, the last actual DMA transfer is likely to contain > invalid (outdated) samples, but gets aborted immediately. I wonder why we need drain ? This "likely to contain invalid samples" will be solved if we can skip "complete drain" ? ------------------- ------------------- Best regards --- Kuninori Morimoto diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 6f3e10c..841a5e0 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -501,7 +501,7 @@ int snd_pcm_status(struct snd_pcm_substream *substream, struct snd_pcm_status *status); int snd_pcm_start(struct snd_pcm_substream *substream); int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status); -int snd_pcm_drain_done(struct snd_pcm_substream *substream); +int snd_pcm_drain_abort(struct snd_pcm_substream *substream); #ifdef CONFIG_PM int snd_pcm_suspend(struct snd_pcm_substream *substream); int snd_pcm_suspend_all(struct snd_pcm *pcm); diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 9acc77e..fbdbbde5 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -286,10 +286,8 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream, if (avail > runtime->avail_max) runtime->avail_max = avail; if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { - if (avail >= runtime->buffer_size) { - snd_pcm_drain_done(substream); - return -EPIPE; - } + snd_pcm_drain_abort(substream); + return -EPIPE; } else { if (avail >= runtime->stop_threshold) { xrun(substream); diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 8cd2f93..f3c48de 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -977,7 +977,7 @@ EXPORT_SYMBOL(snd_pcm_stop); * * Return: Zero if succesful, or a negative error code. */ -int snd_pcm_drain_done(struct snd_pcm_substream *substream) +int snd_pcm_drain_abort(struct snd_pcm_substream *substream) { return snd_pcm_action_single(&snd_pcm_action_stop, substream, SNDRV_PCM_STATE_SETUP);