| From def42946990ebfd8a4cf387a827c1fadda5238eb Mon Sep 17 00:00:00 2001 |
| From: Takashi Sakamoto <o-takashi@sakamocchi.jp> |
| Date: Mon, 23 Dec 2019 18:33:47 +0900 |
| Subject: [PATCH] ALSA: ctl: allow TLV read operation for callback type of |
| element in locked case |
| |
| commit d61fe22c2ae42d9fd76c34ef4224064cca4b04b0 upstream. |
| |
| A design of ALSA control core allows applications to execute three |
| operations for TLV feature; read, write and command. Furthermore, it |
| allows driver developers to process the operations by two ways; allocated |
| array or callback function. In the former, read operation is just allowed, |
| thus developers uses the latter when device driver supports variety of |
| models or the target model is expected to dynamically change information |
| stored in TLV container. |
| |
| The core also allows applications to lock any element so that the other |
| applications can't perform write operation to the element for element |
| value and TLV information. When the element is locked, write and command |
| operation for TLV information are prohibited as well as element value. |
| Any read operation should be allowed in the case. |
| |
| At present, when an element has callback function for TLV information, |
| TLV read operation returns EPERM if the element is locked. On the |
| other hand, the read operation is success when an element has allocated |
| array for TLV information. In both cases, read operation is success for |
| element value expectedly. |
| |
| This commit fixes the bug. This change can be backported to v4.14 |
| kernel or later. |
| |
| Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> |
| Reviewed-by: Jaroslav Kysela <perex@perex.cz> |
| Link: https://lore.kernel.org/r/20191223093347.15279-1-o-takashi@sakamocchi.jp |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/sound/core/control.c b/sound/core/control.c |
| index 5be5b9b931bf..ea99bd961a7a 100644 |
| --- a/sound/core/control.c |
| +++ b/sound/core/control.c |
| @@ -1434,8 +1434,9 @@ static int call_tlv_handler(struct snd_ctl_file *file, int op_flag, |
| if (kctl->tlv.c == NULL) |
| return -ENXIO; |
| |
| - /* When locked, this is unavailable. */ |
| - if (vd->owner != NULL && vd->owner != file) |
| + /* Write and command operations are not allowed for locked element. */ |
| + if (op_flag != SNDRV_CTL_TLV_OP_READ && |
| + vd->owner != NULL && vd->owner != file) |
| return -EPERM; |
| |
| return kctl->tlv.c(kctl, op_flag, size, buf); |
| -- |
| 2.7.4 |
| |