From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750877AbdBBDPa (ORCPT ); Wed, 1 Feb 2017 22:15:30 -0500 Received: from mailout3.samsung.com ([203.254.224.33]:59534 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750726AbdBBDP2 (ORCPT ); Wed, 1 Feb 2017 22:15:28 -0500 X-AuditID: b6c32a35-f79166d000001a4b-bb-5892a44e9038 From: Satendra Singh Thakur To: alsa-devel@alsa-project.org Cc: perex@perex.cz, tiwai@suse.com, o-takashi@sakamocchi.jp, linux-kernel@vger.kernel.org, hemanshu.s@samsung.com, nishant.s4@samsung.com, ycheon.song@samsung.com, satendra singh thakur Subject: [RFC] [ALSA][CONTROL] Added 2 ioctls for reading/writing values of multiple controls in one go (at once) Date: Thu, 02 Feb 2017 08:44:45 +0530 Message-id: <1486005286-25625-1-git-send-email-satendra.t@samsung.com> X-Mailer: git-send-email 1.7.9.5 X-Brightmail-Tracker: H4sIAAAAAAAAAzWSbUhTURjHO7u7d1dpcZ22DoNq3eqDkmt3bHotrSSpVVJSIGLUurmTs9zd 2t0sIyksI0WcikiLhdkrarZcIiYtbYlJH3qhl/UpjFLxZamJRGHW5sVvv+f5///nPOfwkJii E1eRRbwTOXiumCZipV0vEjXJ++/U52lf/cHZD++CEnb8zSTGvu/xEqz3WreErbvbhrGVPW6c bX9TIWUf/WoHbMX1ftmOGOOj2XLC+Cx8jzAGezKNNZ2twOjr/Cg1zvrX5BD5KN2CODNyqBFf YDMX8YUZ9L5Dpp0mQ4qWSWbS2FRazXNWlEFnZeck7yoqjgxFq0u4YleklcMJAr15W7rD5nIi tcUmODPowwyj0zDaVI1Op9PoDUe26AwRyzFkefxrVGJ3J51tmewHF8FbugrEkJDSw8GhXonI Svj2i4+oArGkguoGsNzvlYnFLIBN85+IpcRI+KlEFLoA7B0YXhSIiDDqvYZXAZJMoNbC4BQf 9WDUZwAfhr141BNPueDc0NTidVJqI5z6NyGLspzaBX19o9JoFlJq6K1Pj2YhNUrA2p9fZGJ/ NfT3YSJmwW9DueI48XD8ZadMZBW8NDONi1E3gNXh+0As2gAcWBjDRNd2eLmhTxpljFoBf8xV 4+Khcnj1ikK0GOFkzR8gciYsDwUWn6igjsAR93O8FqhugmWtQInsgrUQCYyd0QicVXDxhZoC m9UPFjcmydANGl5nBwFFAnq53KKsz1PgXIlQag0CSGJ0gvy1N9KSm7nSc8hhMzlcxUgIAkPk Z+ow1coCW2T/eKeJ0acwep2eSdPqUrT0KjmurctTUIWcE51CyI4cSzkJGaO6CJb7hjvMmXGH y9IDjbbe2hMrU4ZdzYmO6zce6PomN28KVU/nD1ZW7HnirHQd/7tJtqfswu3zbQcyc1tqQoGs r8qhga1YaDo8s7Cuab497tZBt3JwfX3d77HdnoIAjtDao3sbzxhWzXRNfX1MZndoT/LN054M LN99cqJow2mPZ9l3WipYOCYJcwjcfxOl9RdHAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrMLMWRmVeSWpSXmKPExsWSnavPp+u7ZFKEwb33phZXLh5isnh1/g2z xeVdc9gs5szYwWQxcelqZovOXf2sFmvPt7JYbPi+ltGiddYRdgdOjw2fm9g89r1dxuZxaJej R9+WVYwe67dcZfH4vEkugC3KzSYjNTEltUghNS85PyUzL91WKTTETddCSSEvMTfVVilC1zck SEmhLDGnFMgzMkADDs4B7sFK+nYJbhmbvz9nKujXqlj55ghjA+MFpS5GTg4JAROJZ2/3MEHY YhIX7q1n62Lk4hAS2MIo8XFdBzNIgg2o6PmcGaxdjBwcIgLyEofe54HUMAs8YJSY8GQbK0iN sECJxM62b+wgNouAqsT7/6/BbF4BN4n1B56zgPRKCChIzJlkM4GRawEjwypGsdSC4tz03OIC A0O94sTc4tK8dL3k/NxNjMAA3XZYSWwHY9sKr0OMAhyMSjy8FfmTIoRYE8uKK3MPMUpwMCuJ 8J6bAxTiTUmsrEotyo8vKs1JLT7EaAq0fSKzlGhyPjB68kriDU1MLSwsTCyNjY0tTJTEeWOn PwsXEkhPLEnNTk0tSC2C6WPi4JRqYIzVXhLi08uftiJ+w31Gn+cntqhPePjvUqHwDf6UsL7f P1amL8mu3lp0fX1s6jyeVevW9TjqvnfefCPPZ71uXsZ1ztDWg7G7VXfq5+7q74kSXq4q8WN/ zgO2r5LtdidvT5g70Vft3Sn/T+k/3lmcN8rd+PFw5d31aeEH3evuf8owM/x1XiSmIUCJpTgj 0VCLuag4EQBGoNkEZgIAAA== X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170202031525epcas1p2164b4ca25afe9fb5cd418d004da961f5 X-Msg-Generator: CA X-Sender-IP: 182.195.34.22 X-Local-Sender: =?UTF-8?B?U2F0ZW5kcmEgU2luZ2ggVGhha3VyG1NSSS1EZWxoaS1TeXN0?= =?UTF-8?B?ZW0gUy9XIFRlYW0b7IK87ISx7KCE7J6QG0NoaWVmIEVuZ2luZWVy?= X-Global-Sender: =?UTF-8?B?U2F0ZW5kcmEgU2luZ2ggVGhha3VyG1NSSS1EZWxoaS1TeXN0?= =?UTF-8?B?ZW0gUy9XIFRlYW0bU2Ftc3VuZyBFbGVjdHJvbmljcxtDaGllZiBFbmdpbmVl?= =?UTF-8?B?cg==?= X-Sender-Code: =?UTF-8?B?QzEwG1NXQUhRG0MxMElEMDJJRDAyODExMg==?= CMS-TYPE: 101P DLP-Filter: Pass X-CFilter-Loop: Reflected X-HopCount: 7 X-CMS-RootMailID: 20170202031525epcas1p2164b4ca25afe9fb5cd418d004da961f5 X-RootMTR: 20170202031525epcas1p2164b4ca25afe9fb5cd418d004da961f5 References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: satendra singh thakur -Added 2 ioctls in alsa driver's control interface -Added an ioctl to read values of multiple elements at once -Added an ioctl to write values of multiple elements at once -In the absence of above ioctls user needs to call N ioctls to read/write value of N elements which requires N context switches -Proposed ioctls will allow accessing N elements' values in a single context switch -Above mentioned ioctl will be useful for alsa utils such as amixer which reads all controls of given sound card Signed-off-by: Satendra Singh Thakur --- include/uapi/sound/asound.h | 8 +++++ sound/core/control.c | 69 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index be353a7..a0dcee7 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h @@ -948,6 +948,11 @@ struct snd_ctl_tlv { unsigned int length; /* in bytes aligned to 4 */ unsigned int tlv[0]; /* first TLV */ }; +/*Struct to read/write multiple element values */ +struct snd_ctl_elem_values { + unsigned int num_vals;/* Number of values*/ + struct snd_ctl_elem_value *pvals;/* Pointer to the array of values */ +}; #define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) #define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info) @@ -974,6 +979,9 @@ struct snd_ctl_tlv { #define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int) #define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int) #define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int) +/*Multipe controls' values read and write*/ +#define SNDRV_CTL_IOCTL_ELEMS_READ _IOWR('U', 0xe0, struct snd_ctl_elem_values) +#define SNDRV_CTL_IOCTL_ELEMS_WRITE _IOWR('U', 0xe1, struct snd_ctl_elem_values) /* * Read interface. diff --git a/sound/core/control.c b/sound/core/control.c index fb096cb..d60dc98 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -942,6 +942,7 @@ static int snd_ctl_elem_read_user(struct snd_card *card, return result; } + static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, struct snd_ctl_elem_value *control) { @@ -1000,6 +1001,70 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, return result; } +/** + * snd_ctl_elems_rw_user - Read/Write values of more than one element, + * one by one + * @card: the card to which element belongs to + * @pucontrols: user-space pointer to struct snd_ctl_elem_values + * @write_flag: this flag distinguises write or read type request + * + * This function reads/writes the value of controls with the given IDs + * of the same card + * Return: On full/partial success, It returns number of successful + * controls read/written. + * On failure, it returns appropriate error + */ +static int snd_ctl_elems_rw_user(struct snd_ctl_file *file, + struct snd_ctl_elem_values __user *pucontrols, + bool write_flag) +{ + struct snd_ctl_elem_values controls; + struct snd_ctl_elem_value control; + struct snd_ctl_elem_value __user *puvals; + struct snd_card *card = file->card; + int result; + int vals; + int controls_count = 0; + + if (copy_from_user(&controls, pucontrols, sizeof(controls))) + return -EFAULT; + if (!controls.num_vals || controls.num_vals > card->controls_count) + return -EINVAL; + /*assign user-space pointer**/ + puvals = (struct snd_ctl_elem_value __user *) controls.pvals; + for (vals = 0; vals < controls.num_vals; vals++) { + if (copy_from_user(&control, puvals + vals, sizeof(control))) + return -EFAULT; + snd_power_lock(card); + result = snd_power_wait(card, SNDRV_CTL_POWER_D0); + if (result >= 0) { + if (write_flag == true) + result = snd_ctl_elem_write(card, file, + &control); + else + result = snd_ctl_elem_read(card, &control); + } + snd_power_unlock(card); + if (result < 0) { + /**If control failed to set/get + * inform user by sending back -1 in reserved field + * so that one can try again for failed elements + */ + control.reserved[0] = (unsigned char) -1; + pr_err("ALSA: control: snd_ctl_elem_write/read failed\ + for control name = %s\n", control.id.name); + } else { + controls_count++; + } + if (copy_to_user(puvals + vals, &control, sizeof(control))) + return -EFAULT; + } + pr_debug("ALSA: control: Num values successfully read/written %u\n",\ + controls_count); + /**Return successful control count to user**/ + return controls_count; +} + static int snd_ctl_elem_lock(struct snd_ctl_file *file, struct snd_ctl_elem_id __user *_id) { @@ -1515,8 +1580,12 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg return snd_ctl_elem_info_user(ctl, argp); case SNDRV_CTL_IOCTL_ELEM_READ: return snd_ctl_elem_read_user(card, argp); + case SNDRV_CTL_IOCTL_ELEMS_READ: + return snd_ctl_elems_rw_user(ctl, argp, false); case SNDRV_CTL_IOCTL_ELEM_WRITE: return snd_ctl_elem_write_user(ctl, argp); + case SNDRV_CTL_IOCTL_ELEMS_WRITE: + return snd_ctl_elems_rw_user(ctl, argp, true); case SNDRV_CTL_IOCTL_ELEM_LOCK: return snd_ctl_elem_lock(ctl, argp); case SNDRV_CTL_IOCTL_ELEM_UNLOCK: -- 1.7.9.5