All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Keeping <john@metanate.com>
To: Pavel Hofman <pavel.hofman@ivitera.com>
Cc: Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>,
	"alsa-devel@alsa-project.org" <alsa-devel@alsa-project.org>,
	Julian Scheel <julian@jusst.de>, Jack Pham <jackp@codeaurora.org>,
	"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
	Ruslan Bilovol <ruslan.bilovol@gmail.com>,
	Yunhao Tian <t123yh.xyz@gmail.com>,
	Jerome Brunet <jbrunet@baylibre.com>
Subject: Re: Correct stopping capture and playback substreams?
Date: Tue, 4 Jan 2022 16:21:33 +0000	[thread overview]
Message-ID: <YdR0DeYefGFU+SVX@donbot> (raw)
In-Reply-To: <YdRuU5EB+bj/e9F+@donbot>

On Tue, Jan 04, 2022 at 03:57:09PM +0000, John Keeping wrote:
> On Mon, Jan 03, 2022 at 01:54:13PM +0100, Pavel Hofman wrote:
> > 
> > 
> > Dne 03. 01. 22 v 13:28 Jaroslav Kysela napsal(a):
> > > On 03. 01. 22 13:15, Takashi Iwai wrote:
> > > > On Mon, 03 Jan 2022 12:32:53 +0100,
> > > > Pavel Hofman wrote:
> > > > > 
> > > > > 
> > > > > 
> > > > > Dne 03. 01. 22 v 10:10 Jaroslav Kysela napsal(a):
> > > > > > On 03. 01. 22 9:22, Pavel Hofman wrote:
> > > > > > > 
> > > > > > > Dne 23. 12. 21 v 9:18 Pavel Hofman napsal(a):
> > > > > > > > Hi Takashi,
> > > > > > > > 
> > > > > > > > I am working on stopping alsa streams of audio USB
> > > > > > > > gadget when USB host
> > > > > > > > stops capture/playback/USB cable unplugged.
> > > > > > > > 
> > > > > > > > For capture I used code from AK4114 SPDIF receiver
> > > > > > > > https://elixir.bootlin.com/linux/latest/source/sound/i2c/other/ak4114.c#L590:
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > static void stop_substream(struct uac_rtd_params *prm)
> > > > > > > > {
> > > > > > > >        unsigned long _flags;
> > > > > > > >        struct snd_pcm_substream *substream;
> > > > > > > > 
> > > > > > > >        substream = prm->ss;
> > > > > > > >        if (substream) {
> > > > > > > >            snd_pcm_stream_lock_irqsave(substream, _flags);
> > > > > > > >            if (snd_pcm_running(substream))
> > > > > > > >                // TODO - correct handling for playback substream?
> > > > > > > >                snd_pcm_stop(substream, SNDRV_PCM_STATE_DRAINING);
> > > > > > > >            snd_pcm_stream_unlock_irqrestore(substream, _flags);
> > > > > > > >        }
> > > > > > > > }
> > > > > > > > 
> > > > > > > > For setup I found calling snd_pcm_stop(substream,
> > > > > > > > SNDRV_PCM_STATE_SETUP)
> > > > > > > > (https://elixir.bootlin.com/linux/latest/source/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c#L63)
> > > > > > > > 
> > > > > > > > 
> > > > > > > >     Or for both capture and playback using
> > > > > > > > SNDRV_PCM_STATE_DISCONNECTED
> > > > > > > > (https://elixir.bootlin.com/linux/latest/source/sound/core/pcm.c#L1103).
> > > > > > > > 
> > > > > > > > 
> > > > > > > > Or perhaps using snd_pcm_dev_disconnect(dev) or
> > > > > > > > snd_pcm_drop(substream)?
> > > > > > > > 
> > > > > > > > Please what is the recommended way?
> > > > > > > > 
> > > > > > > 
> > > > > > > Please can I ask for expert view on this issue? E.g. in
> > > > > > > SoX stopping the
> > > > > > > stream with
> > > > > > > SNDRV_PCM_STATE_SETUP/SNDRV_PCM_STATE_DRAINING does not
> > > > > > > stop
> > > > > > > the application, while with SNDRV_PCM_STATE_DISCONNECTED
> > > > > > > SoX exits with
> > > > > > > non-recoverable status. I am considering implementing both methods and
> > > > > > > letting users choose their suitable snd_pcm_stop operation (none
> > > > > > > (default)/SETUP-DRAINING/DISCONNECTED) for the two events (host
> > > > > > > playback/capture stop, cable disconnection) with a
> > > > > > > configfs param. Would
> > > > > > > this make sense?
> > > > > > 
> > > > > > The disconnection state is unrecoverable. It's expected that the
> > > > > > device will be freed and cannot be reused.
> > > > > > 
> > > > > > If you expect to keep the PCM device, we should probably introduce a
> > > > > > new function which puts the device to the SNDRV_PCM_STATE_OPEN
> > > > > > state. In this state, all I/O routines will return -EBADFD for the
> > > > > > applications, so they should close or re-initialize the PCM device
> > > > > > completely.
> > > > > > 
> > > > > > https://elixir.bootlin.com/linux/latest/source/sound/core/pcm_native.c#L794
> > > > > > 
> > > > > > 
> > > > > 
> > > > > The fact is that after closing the USB host can re-open the device
> > > > > with different samplerate (and perhaps later on with different
> > > > > channels count/sample size). That would hint at the need to
> > > > > re-initialize the gadget side before opening  anyway.
> > > > > 
> > > > > As of keeping the device - it's likely some use cases would prefer
> > > > > keeping the device, to minimize the operations needed to react to the
> > > > > host-side playback/capture start.
> > > > > 
> > > > > A function you describe would make sense for this. IMO from the gadget
> > > > > POW there is no difference  between the host stopping playback/capture
> > > > > and cable disconnection, in both cases the data stream is stopped and
> > > > > next stream can have entirely different parameters. Maybe the gadget
> > > > > configfs parameter could only toggle between no action (i.e. current
> > > > > situation) and the new alsa function stopping the stream.
> > > > > 
> > > > > Jaroslav, please can you draft such a function? Perhaps both changes
> > > > > could make it to 5.17.
> > > > 
> > > > (Sorry for the delayed response, as I've been on vacation and now
> > > > catching up the huge pile of backlogs...)
> > > > 
> > > > About the change to keep PCM OPEN state: I'm afraid that the
> > > > disconnection in the host side may happen at any time, and keeping the
> > > > state OPEN would confuse the things if the host is indeed
> > > > unrecoverable.
> > > 
> > > I don't think so. The SNDRV_PCM_IOCTL_HW_PARAMS must be issued by the
> > > application (in the PCM_OPEN state) and if the USB bus connection is no
> > > longer active, it may fail. We can distinguish between host -> device
> > > disconnection and device -> host one. It is not really a similar thing.
> > > 
> > > I think that the idea was to avoid to re-build the whole card / device
> > > structure for the fixed device allocation.
> > > 
> > > Pavel, if the USB host is not connected to the gadget, where the
> > > playback PCM device fails now ? Is the PCM device created or not ?
> > > 
> > 
> > The gaudio PCM device is created when the gadget function is activated
> > (module loaded), regardless whether the USB host is actually connected. The
> > playback/capture fails after the blocking read/write times out. The data
> > delivery/consumption method is simply not called when no usb requests get
> > completed https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_audio.c#L147
> > .
> > 
> > The current code does basically nothing to the alsa pcm stream at
> > capture/playback start/stop by the host (called when altsetting changes in
> > the gadget) https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_audio.c#L468 https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_audio.c#L557
> 
> Thinking about it, I think the current behaviour is probably correct.
> 
> It's not 100% possible to detect when the host stops data transfer - we
> can detect two scenarios:
> 
> 	- Cable disconnected
> 	- Interface alt 0 selected
> 
> but it's equally possible to just leave the device configured as it was
> and stop sending data.
> 
> While resetting state may be necessary when the cable is disconnected,
> if the host is just stopping and restarting the stream then I don't see
> why the gadget application should have to reconfigure the PCM device.
> 
> It's clearly useful to have some indication of host state, but I'm not
> at all convinced the PCM state is the best way to provide that.

D'oh, I totally forgot about the case of changing sample rate here,
which is the new feature in Pavel's proposed patches.

I still think the existing behaviour is correct when the sample rate
hasn't changed.  But if the sample rate changes, maybe we have to force
the gadget application to reconfigure the PCM as the available sample
rate is now different.  And I guess changing the PCM state is necessary
in that case.

But I'd really like to avoid it for a gadget with only one available
sample rate (and ideally in the case where a gadget supporting multiple
sample rates is stopped and re-started at the same rate).


John

WARNING: multiple messages have this Message-ID (diff)
From: John Keeping <john@metanate.com>
To: Pavel Hofman <pavel.hofman@ivitera.com>
Cc: Julian Scheel <julian@jusst.de>,
	"alsa-devel@alsa-project.org" <alsa-devel@alsa-project.org>,
	Takashi Iwai <tiwai@suse.de>,
	"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
	Jack Pham <jackp@codeaurora.org>,
	Ruslan Bilovol <ruslan.bilovol@gmail.com>,
	Yunhao Tian <t123yh.xyz@gmail.com>,
	Jerome Brunet <jbrunet@baylibre.com>
Subject: Re: Correct stopping capture and playback substreams?
Date: Tue, 4 Jan 2022 16:21:33 +0000	[thread overview]
Message-ID: <YdR0DeYefGFU+SVX@donbot> (raw)
In-Reply-To: <YdRuU5EB+bj/e9F+@donbot>

On Tue, Jan 04, 2022 at 03:57:09PM +0000, John Keeping wrote:
> On Mon, Jan 03, 2022 at 01:54:13PM +0100, Pavel Hofman wrote:
> > 
> > 
> > Dne 03. 01. 22 v 13:28 Jaroslav Kysela napsal(a):
> > > On 03. 01. 22 13:15, Takashi Iwai wrote:
> > > > On Mon, 03 Jan 2022 12:32:53 +0100,
> > > > Pavel Hofman wrote:
> > > > > 
> > > > > 
> > > > > 
> > > > > Dne 03. 01. 22 v 10:10 Jaroslav Kysela napsal(a):
> > > > > > On 03. 01. 22 9:22, Pavel Hofman wrote:
> > > > > > > 
> > > > > > > Dne 23. 12. 21 v 9:18 Pavel Hofman napsal(a):
> > > > > > > > Hi Takashi,
> > > > > > > > 
> > > > > > > > I am working on stopping alsa streams of audio USB
> > > > > > > > gadget when USB host
> > > > > > > > stops capture/playback/USB cable unplugged.
> > > > > > > > 
> > > > > > > > For capture I used code from AK4114 SPDIF receiver
> > > > > > > > https://elixir.bootlin.com/linux/latest/source/sound/i2c/other/ak4114.c#L590:
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > static void stop_substream(struct uac_rtd_params *prm)
> > > > > > > > {
> > > > > > > >        unsigned long _flags;
> > > > > > > >        struct snd_pcm_substream *substream;
> > > > > > > > 
> > > > > > > >        substream = prm->ss;
> > > > > > > >        if (substream) {
> > > > > > > >            snd_pcm_stream_lock_irqsave(substream, _flags);
> > > > > > > >            if (snd_pcm_running(substream))
> > > > > > > >                // TODO - correct handling for playback substream?
> > > > > > > >                snd_pcm_stop(substream, SNDRV_PCM_STATE_DRAINING);
> > > > > > > >            snd_pcm_stream_unlock_irqrestore(substream, _flags);
> > > > > > > >        }
> > > > > > > > }
> > > > > > > > 
> > > > > > > > For setup I found calling snd_pcm_stop(substream,
> > > > > > > > SNDRV_PCM_STATE_SETUP)
> > > > > > > > (https://elixir.bootlin.com/linux/latest/source/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c#L63)
> > > > > > > > 
> > > > > > > > 
> > > > > > > >     Or for both capture and playback using
> > > > > > > > SNDRV_PCM_STATE_DISCONNECTED
> > > > > > > > (https://elixir.bootlin.com/linux/latest/source/sound/core/pcm.c#L1103).
> > > > > > > > 
> > > > > > > > 
> > > > > > > > Or perhaps using snd_pcm_dev_disconnect(dev) or
> > > > > > > > snd_pcm_drop(substream)?
> > > > > > > > 
> > > > > > > > Please what is the recommended way?
> > > > > > > > 
> > > > > > > 
> > > > > > > Please can I ask for expert view on this issue? E.g. in
> > > > > > > SoX stopping the
> > > > > > > stream with
> > > > > > > SNDRV_PCM_STATE_SETUP/SNDRV_PCM_STATE_DRAINING does not
> > > > > > > stop
> > > > > > > the application, while with SNDRV_PCM_STATE_DISCONNECTED
> > > > > > > SoX exits with
> > > > > > > non-recoverable status. I am considering implementing both methods and
> > > > > > > letting users choose their suitable snd_pcm_stop operation (none
> > > > > > > (default)/SETUP-DRAINING/DISCONNECTED) for the two events (host
> > > > > > > playback/capture stop, cable disconnection) with a
> > > > > > > configfs param. Would
> > > > > > > this make sense?
> > > > > > 
> > > > > > The disconnection state is unrecoverable. It's expected that the
> > > > > > device will be freed and cannot be reused.
> > > > > > 
> > > > > > If you expect to keep the PCM device, we should probably introduce a
> > > > > > new function which puts the device to the SNDRV_PCM_STATE_OPEN
> > > > > > state. In this state, all I/O routines will return -EBADFD for the
> > > > > > applications, so they should close or re-initialize the PCM device
> > > > > > completely.
> > > > > > 
> > > > > > https://elixir.bootlin.com/linux/latest/source/sound/core/pcm_native.c#L794
> > > > > > 
> > > > > > 
> > > > > 
> > > > > The fact is that after closing the USB host can re-open the device
> > > > > with different samplerate (and perhaps later on with different
> > > > > channels count/sample size). That would hint at the need to
> > > > > re-initialize the gadget side before opening  anyway.
> > > > > 
> > > > > As of keeping the device - it's likely some use cases would prefer
> > > > > keeping the device, to minimize the operations needed to react to the
> > > > > host-side playback/capture start.
> > > > > 
> > > > > A function you describe would make sense for this. IMO from the gadget
> > > > > POW there is no difference  between the host stopping playback/capture
> > > > > and cable disconnection, in both cases the data stream is stopped and
> > > > > next stream can have entirely different parameters. Maybe the gadget
> > > > > configfs parameter could only toggle between no action (i.e. current
> > > > > situation) and the new alsa function stopping the stream.
> > > > > 
> > > > > Jaroslav, please can you draft such a function? Perhaps both changes
> > > > > could make it to 5.17.
> > > > 
> > > > (Sorry for the delayed response, as I've been on vacation and now
> > > > catching up the huge pile of backlogs...)
> > > > 
> > > > About the change to keep PCM OPEN state: I'm afraid that the
> > > > disconnection in the host side may happen at any time, and keeping the
> > > > state OPEN would confuse the things if the host is indeed
> > > > unrecoverable.
> > > 
> > > I don't think so. The SNDRV_PCM_IOCTL_HW_PARAMS must be issued by the
> > > application (in the PCM_OPEN state) and if the USB bus connection is no
> > > longer active, it may fail. We can distinguish between host -> device
> > > disconnection and device -> host one. It is not really a similar thing.
> > > 
> > > I think that the idea was to avoid to re-build the whole card / device
> > > structure for the fixed device allocation.
> > > 
> > > Pavel, if the USB host is not connected to the gadget, where the
> > > playback PCM device fails now ? Is the PCM device created or not ?
> > > 
> > 
> > The gaudio PCM device is created when the gadget function is activated
> > (module loaded), regardless whether the USB host is actually connected. The
> > playback/capture fails after the blocking read/write times out. The data
> > delivery/consumption method is simply not called when no usb requests get
> > completed https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_audio.c#L147
> > .
> > 
> > The current code does basically nothing to the alsa pcm stream at
> > capture/playback start/stop by the host (called when altsetting changes in
> > the gadget) https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_audio.c#L468 https://elixir.bootlin.com/linux/latest/source/drivers/usb/gadget/function/u_audio.c#L557
> 
> Thinking about it, I think the current behaviour is probably correct.
> 
> It's not 100% possible to detect when the host stops data transfer - we
> can detect two scenarios:
> 
> 	- Cable disconnected
> 	- Interface alt 0 selected
> 
> but it's equally possible to just leave the device configured as it was
> and stop sending data.
> 
> While resetting state may be necessary when the cable is disconnected,
> if the host is just stopping and restarting the stream then I don't see
> why the gadget application should have to reconfigure the PCM device.
> 
> It's clearly useful to have some indication of host state, but I'm not
> at all convinced the PCM state is the best way to provide that.

D'oh, I totally forgot about the case of changing sample rate here,
which is the new feature in Pavel's proposed patches.

I still think the existing behaviour is correct when the sample rate
hasn't changed.  But if the sample rate changes, maybe we have to force
the gadget application to reconfigure the PCM as the available sample
rate is now different.  And I guess changing the PCM state is necessary
in that case.

But I'd really like to avoid it for a gadget with only one available
sample rate (and ideally in the case where a gadget supporting multiple
sample rates is stopped and re-started at the same rate).


John

  reply	other threads:[~2022-01-04 16:21 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-23  8:18 Correct stopping capture and playback substreams? Pavel Hofman
2022-01-03  8:22 ` Pavel Hofman
2022-01-03  8:22   ` Pavel Hofman
2022-01-03  9:10   ` Jaroslav Kysela
2022-01-03 11:32     ` Pavel Hofman
2022-01-03 12:15       ` Takashi Iwai
2022-01-03 12:15         ` Takashi Iwai
2022-01-03 12:28         ` Jaroslav Kysela
2022-01-03 12:28           ` Jaroslav Kysela
2022-01-03 12:36           ` Takashi Iwai
2022-01-03 12:36             ` Takashi Iwai
2022-01-03 12:54           ` Pavel Hofman
2022-01-03 12:54             ` Pavel Hofman
2022-01-04 15:57             ` John Keeping
2022-01-04 15:57               ` John Keeping
2022-01-04 16:21               ` John Keeping [this message]
2022-01-04 16:21                 ` John Keeping
2022-01-05 12:07                 ` Pavel Hofman
2022-01-05 12:07                   ` Pavel Hofman
2022-01-03 12:44         ` Pavel Hofman
2022-01-03 12:44           ` Pavel Hofman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YdR0DeYefGFU+SVX@donbot \
    --to=john@metanate.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=jackp@codeaurora.org \
    --cc=jbrunet@baylibre.com \
    --cc=julian@jusst.de \
    --cc=linux-usb@vger.kernel.org \
    --cc=pavel.hofman@ivitera.com \
    --cc=perex@perex.cz \
    --cc=ruslan.bilovol@gmail.com \
    --cc=t123yh.xyz@gmail.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.