Re: Replace audio(9) get_props() with duplex check in open() for play-only drivers

2022-10-27 Thread Mark Kettenis
> Date: Thu, 27 Oct 2022 13:27:43 +
> From: Klemens Nanni 
> 
> Make drivers which do *not* adverise AUDIO_PROP_FULLDPLEX return ENXIO
> in their open() if full-duplex mode was requested.
> 
> This way, sys/dev/audio.c:audio_open() will fail immediately rather than
> later through the to-be-removed get_props() check.
> 
> These are all drivers which simply don't support recording.
> 
> In device-tree based drivers like simpleaudio(4)/rkiis(4) and newer
> Apple ones like aplaudio(4)/aplmca(4), this adds a new open() stub to
> the low-level drivers which merely does the duplex check.
> 
> The rkiis(4) and aplmca(4) stubs don't open anything, but are now
> required for simpleaudio(4) and aplaudio(4) to actually do the low-level
> driver specific duplex check.
> 
> My Pinebook Pro keeps playing audio and recording silence with this diff
> just like before (rkiis(4) is currently play-only):
>   simpleaudio0 at mainbus0
>   simpleaudio1 at mainbus0
>   audio0 at simpleaudio1
> 
>   $ aucat -i song69.wav -o rec.wav
> 
> Builds fine on amd64 and arm64.
> Feedback? Objection? OK?

Sorry, but I'm still not sure I understand how this is supposed to
work.  Because...

> ---
>  sys/arch/arm64/dev/aplaudio.c  | 15 ---
>  sys/arch/arm64/dev/aplmca.c| 20 
>  sys/arch/luna88k/cbus/nec86.c  |  1 -
>  sys/arch/luna88k/cbus/nec86hw.c| 10 --
>  sys/arch/luna88k/cbus/nec86hwvar.h |  2 --
>  sys/dev/fdt/graphaudio.c   | 15 ---
>  sys/dev/fdt/rkiis.c| 20 +++-
>  sys/dev/fdt/simpleaudio.c  | 15 ---
>  sys/dev/ic/arcofi.c| 11 +++
>  sys/dev/pci/maestro.c  | 13 +++--
>  10 files changed, 33 insertions(+), 89 deletions(-)
> 
> diff --git a/sys/arch/arm64/dev/aplaudio.c b/sys/arch/arm64/dev/aplaudio.c
> index 2e06448a882..49b0aac2f38 100644
> --- a/sys/arch/arm64/dev/aplaudio.c
> +++ b/sys/arch/arm64/dev/aplaudio.c
> @@ -55,7 +55,6 @@ voidaplaudio_freem(void *, void *, int);
>  int  aplaudio_set_port(void *, mixer_ctrl_t *);
>  int  aplaudio_get_port(void *, mixer_ctrl_t *);
>  int  aplaudio_query_devinfo(void *, mixer_devinfo_t *);
> -int  aplaudio_get_props(void *);
>  int  aplaudio_round_blocksize(void *, int);
>  size_t   aplaudio_round_buffersize(void *, int, size_t);
>  int  aplaudio_trigger_output(void *, void *, void *, int,
> @@ -74,7 +73,6 @@ const struct audio_hw_if aplaudio_hw_if = {
>   .set_port = aplaudio_set_port,
>   .get_port = aplaudio_get_port,
>   .query_devinfo = aplaudio_query_devinfo,
> - .get_props = aplaudio_get_props,
>   .round_blocksize = aplaudio_round_blocksize,
>   .round_buffersize = aplaudio_round_buffersize,
>   .trigger_output = aplaudio_trigger_output,
> @@ -401,19 +399,6 @@ aplaudio_query_devinfo(void *cookie, mixer_devinfo_t 
> *dip)
>   return ENXIO;
>  }
>  
> -int
> -aplaudio_get_props(void *cookie)
> -{
> - struct aplaudio_softc *sc = cookie;
> - struct dai_device *dai = sc->sc_dai_cpu;
> - const struct audio_hw_if *hwif = dai->dd_hw_if;
> -
> - if (hwif->get_props)
> - return hwif->get_props(dai->dd_cookie);
> -
> - return 0;
> -}
> -
>  int
>  aplaudio_round_blocksize(void *cookie, int block)
>  {
> diff --git a/sys/arch/arm64/dev/aplmca.c b/sys/arch/arm64/dev/aplmca.c
> index 559dd765933..0d323ffc0c6 100644
> --- a/sys/arch/arm64/dev/aplmca.c
> +++ b/sys/arch/arm64/dev/aplmca.c
> @@ -20,6 +20,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -123,11 +124,11 @@ struct aplmca_softc {
>  int  aplmca_set_format(void *, uint32_t, uint32_t, uint32_t);
>  int  aplmca_set_sysclk(void *, uint32_t);
>  
> +int  aplmca_open(void *, int);
>  int  aplmca_set_params(void *, int, int,
>   struct audio_params *, struct audio_params *);
>  void *aplmca_allocm(void *, int, size_t, int, int);
>  void aplmca_freem(void *, void *, int);
> -int  aplmca_get_props(void *);
>  int  aplmca_trigger_output(void *, void *, void *, int,
>   void (*)(void *), void *, struct audio_params *);
>  int  aplmca_trigger_input(void *, void *, void *, int,
> @@ -136,8 +137,8 @@ int   aplmca_halt_output(void *);
>  int  aplmca_halt_input(void *);
>  
>  const struct audio_hw_if aplmca_hw_if = {
> + .open = aplmca_open,
>   .set_params = aplmca_set_params,
> - .get_props = aplmca_get_props,
>   .allocm = aplmca_allocm,
>   .freem = aplmca_freem,
>   .trigger_output = aplmca_trigger_output,
> @@ -380,6 +381,15 @@ aplmca_set_sysclk(void *cookie, uint32_t rate)
>   return clock_set_frequency_idx(sc->sc_node, ad->ad_cluster, rate);
>  }
>  
> +int
> +aplmca_open(void *cookie, int flags)
> +{
> + if (flags & (FWRITE | FREAD))
> + return ENXIO;

Doesn't this mean that you return ENXIO even if only playback is
requested?  Because then flags would still contain 

Re: Replace audio(9) get_props() with duplex check in open() for play-only drivers

2022-10-27 Thread Alexandre Ratchov
On Thu, Oct 27, 2022 at 01:27:43PM +, Klemens Nanni wrote:
> Make drivers which do *not* adverise AUDIO_PROP_FULLDPLEX return ENXIO
> in their open() if full-duplex mode was requested.
> 
> This way, sys/dev/audio.c:audio_open() will fail immediately rather than
> later through the to-be-removed get_props() check.
> 
> These are all drivers which simply don't support recording.
> 
> In device-tree based drivers like simpleaudio(4)/rkiis(4) and newer
> Apple ones like aplaudio(4)/aplmca(4), this adds a new open() stub to
> the low-level drivers which merely does the duplex check.
> 
> The rkiis(4) and aplmca(4) stubs don't open anything, but are now
> required for simpleaudio(4) and aplaudio(4) to actually do the low-level
> driver specific duplex check.
> 
> My Pinebook Pro keeps playing audio and recording silence with this diff
> just like before (rkiis(4) is currently play-only):
>   simpleaudio0 at mainbus0
>   simpleaudio1 at mainbus0
>   audio0 at simpleaudio1
> 
>   $ aucat -i song69.wav -o rec.wav
> 
> Builds fine on amd64 and arm64.
> Feedback? Objection? OK?

IMO, for play-only drivers, the check should be:

if (flags & FREAD)
return ENXIO;

which will reject record-only and full-duplex.



Replace audio(9) get_props() with duplex check in open() for play-only drivers

2022-10-27 Thread Klemens Nanni
Make drivers which do *not* adverise AUDIO_PROP_FULLDPLEX return ENXIO
in their open() if full-duplex mode was requested.

This way, sys/dev/audio.c:audio_open() will fail immediately rather than
later through the to-be-removed get_props() check.

These are all drivers which simply don't support recording.

In device-tree based drivers like simpleaudio(4)/rkiis(4) and newer
Apple ones like aplaudio(4)/aplmca(4), this adds a new open() stub to
the low-level drivers which merely does the duplex check.

The rkiis(4) and aplmca(4) stubs don't open anything, but are now
required for simpleaudio(4) and aplaudio(4) to actually do the low-level
driver specific duplex check.

My Pinebook Pro keeps playing audio and recording silence with this diff
just like before (rkiis(4) is currently play-only):
simpleaudio0 at mainbus0
simpleaudio1 at mainbus0
audio0 at simpleaudio1

$ aucat -i song69.wav -o rec.wav

Builds fine on amd64 and arm64.
Feedback? Objection? OK?
---
 sys/arch/arm64/dev/aplaudio.c  | 15 ---
 sys/arch/arm64/dev/aplmca.c| 20 
 sys/arch/luna88k/cbus/nec86.c  |  1 -
 sys/arch/luna88k/cbus/nec86hw.c| 10 --
 sys/arch/luna88k/cbus/nec86hwvar.h |  2 --
 sys/dev/fdt/graphaudio.c   | 15 ---
 sys/dev/fdt/rkiis.c| 20 +++-
 sys/dev/fdt/simpleaudio.c  | 15 ---
 sys/dev/ic/arcofi.c| 11 +++
 sys/dev/pci/maestro.c  | 13 +++--
 10 files changed, 33 insertions(+), 89 deletions(-)

diff --git a/sys/arch/arm64/dev/aplaudio.c b/sys/arch/arm64/dev/aplaudio.c
index 2e06448a882..49b0aac2f38 100644
--- a/sys/arch/arm64/dev/aplaudio.c
+++ b/sys/arch/arm64/dev/aplaudio.c
@@ -55,7 +55,6 @@ void  aplaudio_freem(void *, void *, int);
 intaplaudio_set_port(void *, mixer_ctrl_t *);
 intaplaudio_get_port(void *, mixer_ctrl_t *);
 intaplaudio_query_devinfo(void *, mixer_devinfo_t *);
-intaplaudio_get_props(void *);
 intaplaudio_round_blocksize(void *, int);
 size_t aplaudio_round_buffersize(void *, int, size_t);
 intaplaudio_trigger_output(void *, void *, void *, int,
@@ -74,7 +73,6 @@ const struct audio_hw_if aplaudio_hw_if = {
.set_port = aplaudio_set_port,
.get_port = aplaudio_get_port,
.query_devinfo = aplaudio_query_devinfo,
-   .get_props = aplaudio_get_props,
.round_blocksize = aplaudio_round_blocksize,
.round_buffersize = aplaudio_round_buffersize,
.trigger_output = aplaudio_trigger_output,
@@ -401,19 +399,6 @@ aplaudio_query_devinfo(void *cookie, mixer_devinfo_t *dip)
return ENXIO;
 }
 
-int
-aplaudio_get_props(void *cookie)
-{
-   struct aplaudio_softc *sc = cookie;
-   struct dai_device *dai = sc->sc_dai_cpu;
-   const struct audio_hw_if *hwif = dai->dd_hw_if;
-
-   if (hwif->get_props)
-   return hwif->get_props(dai->dd_cookie);
-
-   return 0;
-}
-
 int
 aplaudio_round_blocksize(void *cookie, int block)
 {
diff --git a/sys/arch/arm64/dev/aplmca.c b/sys/arch/arm64/dev/aplmca.c
index 559dd765933..0d323ffc0c6 100644
--- a/sys/arch/arm64/dev/aplmca.c
+++ b/sys/arch/arm64/dev/aplmca.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -123,11 +124,11 @@ struct aplmca_softc {
 intaplmca_set_format(void *, uint32_t, uint32_t, uint32_t);
 intaplmca_set_sysclk(void *, uint32_t);
 
+intaplmca_open(void *, int);
 intaplmca_set_params(void *, int, int,
struct audio_params *, struct audio_params *);
 void   *aplmca_allocm(void *, int, size_t, int, int);
 void   aplmca_freem(void *, void *, int);
-intaplmca_get_props(void *);
 intaplmca_trigger_output(void *, void *, void *, int,
void (*)(void *), void *, struct audio_params *);
 intaplmca_trigger_input(void *, void *, void *, int,
@@ -136,8 +137,8 @@ int aplmca_halt_output(void *);
 intaplmca_halt_input(void *);
 
 const struct audio_hw_if aplmca_hw_if = {
+   .open = aplmca_open,
.set_params = aplmca_set_params,
-   .get_props = aplmca_get_props,
.allocm = aplmca_allocm,
.freem = aplmca_freem,
.trigger_output = aplmca_trigger_output,
@@ -380,6 +381,15 @@ aplmca_set_sysclk(void *cookie, uint32_t rate)
return clock_set_frequency_idx(sc->sc_node, ad->ad_cluster, rate);
 }
 
+int
+aplmca_open(void *cookie, int flags)
+{
+   if (flags & (FWRITE | FREAD))
+   return ENXIO;
+
+   return 0;
+}
+
 int
 aplmca_set_params(void *cookie, int setmode, int usemode,
 struct audio_params *play, struct audio_params *rec)
@@ -396,12 +406,6 @@ aplmca_set_params(void *cookie, int setmode, int usemode,
return 0;
 }
 
-int
-aplmca_get_props(void *cookie)
-{
-   return 0;
-}
-
 void *
 aplmca_allocm(void *cookie, int direction, size_t size, int type,
 int flags)
diff --git a/sys/arch/luna88k/cbus/nec86.c