All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver
@ 2017-08-24  1:46 Takashi Sakamoto
  2017-08-24  1:46 ` [PATCH 1/3] " Takashi Sakamoto
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Takashi Sakamoto @ 2017-08-24  1:46 UTC (permalink / raw)
  To: tiwai; +Cc: alsa-devel, clemens, fulup.arfoll

Hi,

This patchse is the same one which I posted and for merge to upstream.

[alsa-devel] [RFC][PATCH 0/3] ALSA: control: delegate TLV eventing to each driver
http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/124382.html

Nothing changed from the original one.


Takashi Sakamoto (3):
  ALSA: control: delegate TLV eventing to each driver
  ALSA: control: queue TLV event for a set of user-defined element
  ALSA: control: TLV data is unavailable at initial state of
    user-defined element set

 sound/core/control.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] ALSA: control: delegate TLV eventing to each driver
  2017-08-24  1:46 [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver Takashi Sakamoto
@ 2017-08-24  1:46 ` Takashi Sakamoto
  2017-08-24  1:46 ` [PATCH 2/3] ALSA: control: queue TLV event for a set of user-defined element Takashi Sakamoto
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Sakamoto @ 2017-08-24  1:46 UTC (permalink / raw)
  To: tiwai; +Cc: alsa-devel, clemens, fulup.arfoll

In a design of ALSA control core, a set of elements is represented by
'struct snd_kcontrol' to share common attributes. The set of elements
shares TLV (Type-Length-Value) data, too.

On the other hand, in ALSA control interface/protocol for applications,
a TLV operation is committed to an element. Totally, the operation can
have sub-effect to the other elements in the set. For example, TLV_WRITE
operation is expected to change TLV data, which returns to applications.
Applications attempt to change the TLV data per element, but in the above
design, they can effect to elements in the same set.

As a default, ALSA control core has no implementation except for TLV_READ
operation. Thus, the above design looks to have no issue. However, in
kernel APIs of ALSA control component, developers can program a handler
for any request of the TLV operation. Therefore, for elements in a set
which has the handler, applications can commit TLV_WRITE and TLV_COMMAND
requests.

For the above scenario, ALSA control core assist notification. When the
handler returns positive value, the core queueing an event for a requested
element. However, this includes design defects that the event is not
queued for the other element in a set. Actually, developers can program
the handlers to keep per-element TLV data, but it depends on each driver.

As of v4.13-rc6, there's no driver in tree to utilize the notification,
except for user-defined element set. This commit delegates the notification
into each driver to prevent developers from the design defects.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/core/control.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/sound/core/control.c b/sound/core/control.c
index de976a8c0177..d6a8502da828 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1138,6 +1138,8 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
 	ue->tlv_data = container;
 	ue->tlv_data_size = size;
 
+	snd_ctl_notify(ue->card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
+
 	return change;
 }
 
@@ -1423,7 +1425,6 @@ static int call_tlv_handler(struct snd_ctl_file *file, int op_flag,
 	};
 	struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)];
 	int i;
-	int err;
 
 	/* Check support of the request for this element. */
 	for (i = 0; i < ARRAY_SIZE(pairs); ++i) {
@@ -1440,14 +1441,7 @@ static int call_tlv_handler(struct snd_ctl_file *file, int op_flag,
 	if (vd->owner != NULL && vd->owner != file)
 		return -EPERM;
 
-	err = kctl->tlv.c(kctl, op_flag, size, buf);
-	if (err < 0)
-		return err;
-
-	if (err > 0)
-		snd_ctl_notify(file->card, SNDRV_CTL_EVENT_MASK_TLV, id);
-
-	return 0;
+	return kctl->tlv.c(kctl, op_flag, size, buf);
 }
 
 static int read_tlv_buf(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] ALSA: control: queue TLV event for a set of user-defined element
  2017-08-24  1:46 [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver Takashi Sakamoto
  2017-08-24  1:46 ` [PATCH 1/3] " Takashi Sakamoto
@ 2017-08-24  1:46 ` Takashi Sakamoto
  2017-08-24  1:46 ` [PATCH 3/3] ALSA: control: TLV data is unavailable at initial state of user-defined element set Takashi Sakamoto
  2017-08-24  7:17 ` [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Sakamoto @ 2017-08-24  1:46 UTC (permalink / raw)
  To: tiwai; +Cc: alsa-devel, clemens, fulup.arfoll

In a design of user-defined element set, applications allow to change TLV
data on the set. This operation doesn't only affects to a target element,
but also to elements in the set.

This commit generates TLV event for all of elements in the set when the TLV
data is changed.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/core/control.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/sound/core/control.c b/sound/core/control.c
index d6a8502da828..6ddffe85126f 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1117,6 +1117,8 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
 {
 	struct user_element *ue = kctl->private_data;
 	unsigned int *container;
+	struct snd_ctl_elem_id id;
+	int i;
 	int change;
 
 	if (size > 1024 * 128)	/* sane value */
@@ -1138,7 +1140,10 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
 	ue->tlv_data = container;
 	ue->tlv_data_size = size;
 
-	snd_ctl_notify(ue->card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
+	for (i = 0; i < kctl->count; ++i) {
+		snd_ctl_build_ioff(&id, kctl, i);
+		snd_ctl_notify(ue->card, SNDRV_CTL_EVENT_MASK_TLV, &id);
+	}
 
 	return change;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ALSA: control: TLV data is unavailable at initial state of user-defined element set
  2017-08-24  1:46 [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver Takashi Sakamoto
  2017-08-24  1:46 ` [PATCH 1/3] " Takashi Sakamoto
  2017-08-24  1:46 ` [PATCH 2/3] ALSA: control: queue TLV event for a set of user-defined element Takashi Sakamoto
@ 2017-08-24  1:46 ` Takashi Sakamoto
  2017-08-24  7:17 ` [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Sakamoto @ 2017-08-24  1:46 UTC (permalink / raw)
  To: tiwai; +Cc: alsa-devel, clemens, fulup.arfoll

For user-defined element set, in its initial state, TLV data is not
registered. It's firstly available when any application register it by
an additional operation. However, in current implementation, it's available
in its initial state. As a result, applications get -ENXIO to read it.

This commit controls its readability to manage info flags properly. In an
initial state, elements don't have SND_CTL_ELEM_ACCESS_TLV_READ flag. Once
TLV write operation is executed, they get the flag.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/core/control.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/sound/core/control.c b/sound/core/control.c
index 6ddffe85126f..51d4b4ad3e1d 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1118,6 +1118,7 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
 	struct user_element *ue = kctl->private_data;
 	unsigned int *container;
 	struct snd_ctl_elem_id id;
+	unsigned int mask = 0;
 	int i;
 	int change;
 
@@ -1136,13 +1137,21 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
 		return 0;
 	}
 
+	if (ue->tlv_data == NULL) {
+		/* Now TLV data is available. */
+		for (i = 0; i < kctl->count; ++i)
+			kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+		mask = SNDRV_CTL_EVENT_MASK_INFO;
+	}
+
 	kfree(ue->tlv_data);
 	ue->tlv_data = container;
 	ue->tlv_data_size = size;
 
+	mask |= SNDRV_CTL_EVENT_MASK_TLV;
 	for (i = 0; i < kctl->count; ++i) {
 		snd_ctl_build_ioff(&id, kctl, i);
-		snd_ctl_notify(ue->card, SNDRV_CTL_EVENT_MASK_TLV, &id);
+		snd_ctl_notify(ue->card, mask, &id);
 	}
 
 	return change;
@@ -1277,8 +1286,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
 		access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
 	access &= (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 		   SNDRV_CTL_ELEM_ACCESS_INACTIVE |
-		   SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE);
-	if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)
+		   SNDRV_CTL_ELEM_ACCESS_TLV_WRITE);
+
+	/* In initial state, nothing is available as TLV container. */
+	if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
 		access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
 	access |= SNDRV_CTL_ELEM_ACCESS_USER;
 
@@ -1341,7 +1352,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
 		kctl->get = snd_ctl_elem_user_get;
 	if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
 		kctl->put = snd_ctl_elem_user_put;
-	if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)
+	if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
 		kctl->tlv.c = snd_ctl_elem_user_tlv;
 
 	/* This function manage to free the instance on failure. */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver
  2017-08-24  1:46 [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver Takashi Sakamoto
                   ` (2 preceding siblings ...)
  2017-08-24  1:46 ` [PATCH 3/3] ALSA: control: TLV data is unavailable at initial state of user-defined element set Takashi Sakamoto
@ 2017-08-24  7:17 ` Takashi Iwai
  3 siblings, 0 replies; 5+ messages in thread
From: Takashi Iwai @ 2017-08-24  7:17 UTC (permalink / raw)
  To: Takashi Sakamoto; +Cc: alsa-devel, clemens, fulup.arfoll

On Thu, 24 Aug 2017 03:46:13 +0200,
Takashi Sakamoto wrote:
> 
> Hi,
> 
> This patchse is the same one which I posted and for merge to upstream.
> 
> [alsa-devel] [RFC][PATCH 0/3] ALSA: control: delegate TLV eventing to each driver
> http://mailman.alsa-project.org/pipermail/alsa-devel/2017-August/124382.html
> 
> Nothing changed from the original one.
> 
> 
> Takashi Sakamoto (3):
>   ALSA: control: delegate TLV eventing to each driver
>   ALSA: control: queue TLV event for a set of user-defined element
>   ALSA: control: TLV data is unavailable at initial state of
>     user-defined element set

Applied all three patches.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-08-24  7:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-24  1:46 [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver Takashi Sakamoto
2017-08-24  1:46 ` [PATCH 1/3] " Takashi Sakamoto
2017-08-24  1:46 ` [PATCH 2/3] ALSA: control: queue TLV event for a set of user-defined element Takashi Sakamoto
2017-08-24  1:46 ` [PATCH 3/3] ALSA: control: TLV data is unavailable at initial state of user-defined element set Takashi Sakamoto
2017-08-24  7:17 ` [PATCH 0/3] ALSA: control: delegate TLV eventing to each driver Takashi Iwai

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.