From patchwork Tue Dec 19 17:36:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 755992 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 48FC8C41535 for ; Tue, 19 Dec 2023 17:37:29 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9CDE0E8B; Tue, 19 Dec 2023 18:37:16 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9CDE0E8B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007446; bh=01j4NClY1puDJN1b1SakKTY9YWrRaYS8XQWUncABbvk=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=WtEXUGUYwsygHuqG+MiSq6w/Oae4zxzuWWM04gtrGEoUpfx4WbBTXJYsb2ugY8vWX JDCkTNLqC1+velkZR9xRhj1ZVDsokbvdaphjM2u62BjsJTnnj5hVPAGRNafhSca3iW XNa1TolTH1CnEdVGxhXzKDVVNxI3mfUcqBvHBEwg= Received: by alsa1.perex.cz (Postfix, from userid 50401) id BD425F80212; Tue, 19 Dec 2023 18:36:58 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 1800DF8057D; Tue, 19 Dec 2023 18:36:58 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6D7EBF80563; Tue, 19 Dec 2023 18:36:53 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CADAEF80431 for ; Tue, 19 Dec 2023 18:36:46 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CADAEF80431 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=GyQqenbQ Received: by m.b4.vu (Postfix, from userid 1000) id 432C4604B9F7; Wed, 20 Dec 2023 04:06:42 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 432C4604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007402; bh=w71tYLCSurTXhcu4POdZy7nJlWAOIgIw63TgCjTYSMY=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=GyQqenbQjZ1WXJfzAHedLWE2CsJXMwI+zmf0qoABFBAm81FglS1donj/rCe4Iifpw 9BZToDtCMQK2we0ynaLW+JYIOaunU1BeKpQ7LL32vXrB5ifTSuuturw0vGCSoTH+NJ kANqPvRV/2vr9JBoxGVr/9SXJgqQl2tjMkHjWIwvmaZHh/AsT0giCAMWkCSgXJC2B3 RHb+4dUJhoMuiC291AqHlQ1mTRZX0asnMAkfuxtmnLcLS4+VkqufHC0liDWCaWXllB 9NJGKNMciXVrIj33wEZcOlyOcJCpqDqFt0mevqXkzjs7Ek6SFS0G6x/98hqDzyPrcb bXDUo5q0LCVog== Date: Wed, 20 Dec 2023 04:06:42 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 01/11] ALSA: scarlett2: Update maintainer info Message-ID: <62f32404eaa8663cc304648354b85bcb5914ce72.1703001053.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: LDMSQH6PTI5LYHAXKFNTVQWY3ORAI2TC X-Message-ID-Hash: LDMSQH6PTI5LYHAXKFNTVQWY3ORAI2TC X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Update MAINTAINERS and "enabled" message with GitHub repository links. Signed-off-by: Geoffrey D. Bennett --- MAINTAINERS | 6 ++++-- sound/usb/mixer_scarlett2.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index ea790149af79..ae3f72f57854 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8272,11 +8272,13 @@ L: linux-input@vger.kernel.org S: Maintained F: drivers/input/joystick/fsia6b.c -FOCUSRITE SCARLETT GEN 2/3 MIXER DRIVER +FOCUSRITE SCARLETT2 MIXER DRIVER (Scarlett Gen 2+ and Clarett) M: Geoffrey D. Bennett L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git +W: https://github.com/geoffreybennett/scarlett-gen2 +B: https://github.com/geoffreybennett/scarlett-gen2/issues +T: git https://github.com/geoffreybennett/scarlett-gen2.git F: sound/usb/mixer_scarlett2.c FORCEDETH GIGABIT ETHERNET DRIVER diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index f7c57a2c3028..a0dbdf921745 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -4534,7 +4534,8 @@ int snd_scarlett2_init(struct usb_mixer_interface *mixer) usb_audio_info(chip, "Focusrite %s Mixer Driver enabled (pid=0x%04x); " - "report any issues to g@b4.vu", + "report any issues to " + "https://github.com/geoffreybennett/scarlett-gen2/issues", entry->series_name, USB_ID_PRODUCT(chip->usb_id)); From patchwork Tue Dec 19 17:37:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 756433 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CC67DC41535 for ; Tue, 19 Dec 2023 17:37:50 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 63B6FE87; Tue, 19 Dec 2023 18:37:38 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 63B6FE87 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007468; bh=IPgrM1saYRQovJkWh8Am1q21cREmsnFRR1jQ2LDZ9ks=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=KCmGVz0R1E7TiMUx/+E4OR98z/5+9w6RAC4TqybAD5zTjUrsELXV3oaqdLBnnjLK1 NZjJVGgISZaRver8haCc3xyD+YERhZf6mGKmvHgyLOQjOXRHdOng1veTlbwO/JZQ1D WHQDBZL5B74zD4BIaGIx6JTF9rJKes3KaS5LCS5g= Received: by alsa1.perex.cz (Postfix, from userid 50401) id E88CDF805C5; Tue, 19 Dec 2023 18:37:14 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 0DBECF80589; Tue, 19 Dec 2023 18:37:14 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BA202F8056F; Tue, 19 Dec 2023 18:37:08 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id F237BF80557 for ; Tue, 19 Dec 2023 18:37:04 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz F237BF80557 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=faHNPnoB Received: by m.b4.vu (Postfix, from userid 1000) id 59CC3604B9F7; Wed, 20 Dec 2023 04:07:00 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 59CC3604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007420; bh=8ETulCIE9Z69wcqSdAOg8PPnM13gfiYjvR7IHw2Ie3U=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=faHNPnoB6i6kSJXkV/pAFKVpIboUm0LoeTJRYsqr9OXWofxsLJn1SHa22hFq0tnnT MrjzCx86UGM5/zjM7oTE+a6pdP7oRRUsOuGfeEncgBHQ5bc0LPGKujdVlNcJW4Eoel +GyLuofT5vv/WukZdH+JhqMn9lINj80ByvrCVEgla5lQBnoahUZiI0PmbcLm2gqpCa y6k0soNGslDdXgXMECZhzHat/rgA7vOPnFktH9sRzowChN2Fvbce9QgRuTHz9U179t 5a4dHApBLaXQDlL75ITrz7TxlKWYK2Ol+lqVbEhV3sIo7GtW9k8jaMmoOIfSjd4ZwM V8/RuV0TH+ZWQ== Date: Wed, 20 Dec 2023 04:07:00 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 02/11] ALSA: scarlett2: Add missing error check to scarlett2_config_save() Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: TYILH4UWJMRJZKATDDWXPOUAKR24T6AA X-Message-ID-Hash: TYILH4UWJMRJZKATDDWXPOUAKR24T6AA X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: scarlett2_config_save() was ignoring the return value from scarlett2_usb(). As this function is not called from user-space we can't return the error, so call usb_audio_err() instead. Signed-off-by: Geoffrey D. Bennett Fixes: 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface") --- sound/usb/mixer_scarlett2.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index a0dbdf921745..a0ba53372f7b 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -1524,9 +1524,11 @@ static void scarlett2_config_save(struct usb_mixer_interface *mixer) { __le32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE); - scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD, - &req, sizeof(u32), - NULL, 0); + int err = scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD, + &req, sizeof(u32), + NULL, 0); + if (err < 0) + usb_audio_err(mixer->chip, "config save failed: %d\n", err); } /* Delayed work to save config */ From patchwork Tue Dec 19 17:37:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 756431 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E5184C41535 for ; Tue, 19 Dec 2023 17:40:11 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B57B7E96; Tue, 19 Dec 2023 18:39:59 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B57B7E96 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007609; bh=b5MDa03Vi7XKT0qQS1k8UXSPsp5FYy2d/OBD41hAEBU=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=k4zwr/xiAMEEMGZQDvDxvpPrZULB89edjq7chwprdeLXQkvWlxidGHQcTvWghZib+ 0rgWG0Y0InashrS/Vd4mBaqfBvb7Xe3uMuUtiQEmVyauT2Z6o4aj/nZsljE2GKMQPN gXWUUFgZjDq/rA3rIg6xIuaHZ1YP3rwGexm3chUo= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 34555F805EB; Tue, 19 Dec 2023 18:39:16 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id F4150F805FA; Tue, 19 Dec 2023 18:39:15 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id D4537F8055C; Tue, 19 Dec 2023 18:39:12 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 32C9BF80431 for ; Tue, 19 Dec 2023 18:37:25 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 32C9BF80431 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=J40YY9LR Received: by m.b4.vu (Postfix, from userid 1000) id 3DAD0604B9F7; Wed, 20 Dec 2023 04:07:21 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 3DAD0604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007441; bh=UPNbemMDS4lDUP7V/e0nZI2I2ad47Wkcxstixw5X+Xs=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=J40YY9LRwCJPGApJEpHdQEhpI3svsHm+iZXZ65R5cUmPvpQpsnKs5HSoh3Gi+dVc3 vi97nhwn/8PFD4d4dJ92ylslHyLe/mLU0Cno6DwFSRrvOmVPz0D3JajAGKihthSf19 d1Wd2P9YYhtHa4sHVkd04I/QFD5Q1N0O/eomZEySqzJoTBnix+/IkvwNLrn+027Puk o7wXGk+2HtAuBrT8cKtMuFg3IXWmTiJMkfG0xxuXJ0+l3LKGA9h6DsTMtwhabWY2OX Wc+HpHDRv3sjjvBeDsy5T4nJflAanRYDi+jpqYbVs9bNxL57MCf84h1CIGYYypIeyv 1X83Dfnk905Rw== Date: Wed, 20 Dec 2023 04:07:21 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 03/11] ALSA: scarlett2: Add missing error check to scarlett2_usb_set_config() Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: 3Q6UAA5P7VWVNFLQJPGK7FUTBRA6TYN5 X-Message-ID-Hash: 3Q6UAA5P7VWVNFLQJPGK7FUTBRA6TYN5 X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: scarlett2_usb_set_config() calls scarlett2_usb_get() but was not checking the result. Return the error if it fails rather than continuing with an invalid value. Signed-off-by: Geoffrey D. Bennett Fixes: 9e15fae6c51a ("ALSA: usb-audio: scarlett2: Allow bit-level access to config") --- sound/usb/mixer_scarlett2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index a0ba53372f7b..22285d8038c1 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -1577,7 +1577,10 @@ static int scarlett2_usb_set_config( size = 1; offset = config_item->offset; - scarlett2_usb_get(mixer, offset, &tmp, 1); + err = scarlett2_usb_get(mixer, offset, &tmp, 1); + if (err < 0) + return err; + if (value) tmp |= (1 << index); else From patchwork Tue Dec 19 17:37:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 755991 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C0E98C41535 for ; Tue, 19 Dec 2023 17:38:57 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 94B0B857; Tue, 19 Dec 2023 18:38:44 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 94B0B857 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007534; bh=66a8o9rC4U4wSUF+99ngYard3PbwXPI38SOJm1dFOJc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=DzF6Rk2BzURvXj8AjxidCExWtXuEySHUSoSToW4MHyuyM2UkkVManJ0Lrp+YL5H15 NNkX5aSZ8qCM3sob4JAm60BOZ/Syl2EujmNCNGIHQReyfGxfKxS4AGdvlQswWhrygD 3+XhWgasmS+sq3MV1r2OBS1G3u4kfkQKSGVJzJ1Y= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 33E22F805A9; Tue, 19 Dec 2023 18:38:24 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id C3D72F805B2; Tue, 19 Dec 2023 18:38:22 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id E3747F80578; Tue, 19 Dec 2023 18:38:18 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 679E7F8055C for ; Tue, 19 Dec 2023 18:37:41 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 679E7F8055C Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=cKc80OEX Received: by m.b4.vu (Postfix, from userid 1000) id 6BB85604B9F7; Wed, 20 Dec 2023 04:07:37 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 6BB85604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007457; bh=/ntwoBmCyYetrlV6KCRYSBLcValc73eGigSnWiDbGIw=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=cKc80OEXhySWbhrhuIzUN9bsLXK8Y0Ns7HDb5SvWSrb/+7A8oyD4AIMbWmj+/Dcq7 3YHOQSvZopiPlBoAIzsVMK+69Ag8GEOqOlz899uu06cfzYzW0O4Twm7XmBKC+Y8VfJ FCAxaP0+AmQLTOq2+6qY7/YXIX41HFxzdzrTAY1tiJJ11gvOhuv6we+8M5JwgDG4U0 CE+Y0k1OFXlWWNHOrAxvgv2fzqkBZDuzg49AjYK/MQ6s/72+olYmtXWRNBSBiO1ItX WGb1vk0rp3GYEyiloiGXFtpziQtM1ylJA+flYNXgiubG4mF53pquh6V0laW030GdK2 sf3XiXVB7dpeg== Date: Wed, 20 Dec 2023 04:07:37 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 04/11] ALSA: scarlett2: Add missing error checks to *_ctl_get() Message-ID: <32a5fdc83b05fa74e0fcdd672fbf71d75c5f0a6d.1703001053.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: 22JIMR3B33AS7U2BGZNZXWOFWPK2KVTO X-Message-ID-Hash: 22JIMR3B33AS7U2BGZNZXWOFWPK2KVTO X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The *_ctl_get() functions which call scarlett2_update_*() were not checking the return value. Fix to check the return value and pass to the caller. Signed-off-by: Geoffrey D. Bennett Fixes: 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface") --- sound/usb/mixer_scarlett2.c | 182 +++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 52 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 22285d8038c1..373911937487 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -2100,14 +2100,20 @@ static int scarlett2_sync_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->sync_updated) - scarlett2_update_sync(mixer); + + if (private->sync_updated) { + err = scarlett2_update_sync(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.enumerated.item[0] = private->sync; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } static const struct snd_kcontrol_new scarlett2_sync_ctl = { @@ -2190,14 +2196,20 @@ static int scarlett2_master_volume_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->vol_updated) - scarlett2_update_volumes(mixer); - mutex_unlock(&private->data_mutex); + if (private->vol_updated) { + err = scarlett2_update_volumes(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.integer.value[0] = private->master_vol; - return 0; + +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int line_out_remap(struct scarlett2_data *private, int index) @@ -2223,14 +2235,20 @@ static int scarlett2_volume_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); + int err = 0; mutex_lock(&private->data_mutex); - if (private->vol_updated) - scarlett2_update_volumes(mixer); - mutex_unlock(&private->data_mutex); + if (private->vol_updated) { + err = scarlett2_update_volumes(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.integer.value[0] = private->vol[index]; - return 0; + +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl, @@ -2297,14 +2315,20 @@ static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); + int err = 0; mutex_lock(&private->data_mutex); - if (private->vol_updated) - scarlett2_update_volumes(mixer); - mutex_unlock(&private->data_mutex); + if (private->vol_updated) { + err = scarlett2_update_volumes(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.integer.value[0] = private->mute_switch[index]; - return 0; + +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_mute_ctl_put(struct snd_kcontrol *kctl, @@ -2550,14 +2574,20 @@ static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl, const struct scarlett2_device_info *info = private->info; int index = elem->control + info->level_input_first; + int err = 0; mutex_lock(&private->data_mutex); - if (private->input_other_updated) - scarlett2_update_input_other(mixer); + + if (private->input_other_updated) { + err = scarlett2_update_input_other(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.enumerated.item[0] = private->level_switch[index]; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl, @@ -2608,15 +2638,21 @@ static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->input_other_updated) - scarlett2_update_input_other(mixer); + + if (private->input_other_updated) { + err = scarlett2_update_input_other(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.integer.value[0] = private->pad_switch[elem->control]; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_pad_ctl_put(struct snd_kcontrol *kctl, @@ -2666,14 +2702,20 @@ static int scarlett2_air_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->input_other_updated) - scarlett2_update_input_other(mixer); + + if (private->input_other_updated) { + err = scarlett2_update_input_other(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.integer.value[0] = private->air_switch[elem->control]; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_air_ctl_put(struct snd_kcontrol *kctl, @@ -2723,15 +2765,21 @@ static int scarlett2_phantom_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->input_other_updated) - scarlett2_update_input_other(mixer); + + if (private->input_other_updated) { + err = scarlett2_update_input_other(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.integer.value[0] = private->phantom_switch[elem->control]; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl, @@ -2903,14 +2951,20 @@ static int scarlett2_direct_monitor_ctl_get( struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = elem->head.mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->monitor_other_updated) - scarlett2_update_monitor_other(mixer); + + if (private->monitor_other_updated) { + err = scarlett2_update_monitor_other(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.enumerated.item[0] = private->direct_monitor_switch; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_direct_monitor_ctl_put( @@ -3010,14 +3064,20 @@ static int scarlett2_speaker_switch_enum_ctl_get( struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->monitor_other_updated) - scarlett2_update_monitor_other(mixer); + + if (private->monitor_other_updated) { + err = scarlett2_update_monitor_other(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.enumerated.item[0] = private->speaker_switching_switch; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } /* when speaker switching gets enabled, switch the main/alt speakers @@ -3165,14 +3225,20 @@ static int scarlett2_talkback_enum_ctl_get( struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->monitor_other_updated) - scarlett2_update_monitor_other(mixer); + + if (private->monitor_other_updated) { + err = scarlett2_update_monitor_other(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.enumerated.item[0] = private->talkback_switch; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_talkback_enum_ctl_put( @@ -3320,14 +3386,20 @@ static int scarlett2_dim_mute_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; + int err = 0; mutex_lock(&private->data_mutex); - if (private->vol_updated) - scarlett2_update_volumes(mixer); - mutex_unlock(&private->data_mutex); + if (private->vol_updated) { + err = scarlett2_update_volumes(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.integer.value[0] = private->dim_mute[elem->control]; - return 0; + +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl, @@ -3698,14 +3770,20 @@ static int scarlett2_mux_src_enum_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); + int err = 0; mutex_lock(&private->data_mutex); - if (private->mux_updated) - scarlett2_usb_get_mux(mixer); + + if (private->mux_updated) { + err = scarlett2_usb_get_mux(mixer); + if (err < 0) + goto unlock; + } ucontrol->value.enumerated.item[0] = private->mux[index]; - mutex_unlock(&private->data_mutex); - return 0; +unlock: + mutex_unlock(&private->data_mutex); + return err; } static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl, From patchwork Tue Dec 19 17:37:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 756432 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BF48BC41535 for ; Tue, 19 Dec 2023 17:39:31 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id EE336E8A; Tue, 19 Dec 2023 18:39:19 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EE336E8A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007570; bh=eFRmerzRNKjJBzWoDTVYuFuo2sn+SGeuk2TedMpv6h4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=tjg0iahnDcEGoFrjlGixKkw2MCKQbl/TO+keUVqJe9hQQeHLwHzfLnVHUQhEAagVW Wdz/pDF0Fzx6GQyzuVbOCvRev9hcfITdTOJjml35v4YfToVJNWijJqqza5zKqLczFO 6xy0XxHshOvzwpBbY7fsWc3i7r6VnIwA5QyMvbwM= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6C8FBF8056F; Tue, 19 Dec 2023 18:38:59 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 14DCDF8058C; Tue, 19 Dec 2023 18:38:59 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 11030F8055A; Tue, 19 Dec 2023 18:38:55 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 883F8F8057A for ; Tue, 19 Dec 2023 18:37:56 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 883F8F8057A Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=dndQ2jbx Received: by m.b4.vu (Postfix, from userid 1000) id C4771604B9F7; Wed, 20 Dec 2023 04:07:52 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu C4771604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007472; bh=MhoIaixpik1iUNQTcsUyfLxvHJVzpPig+kV+sgoyrFM=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=dndQ2jbxuzrpogsvzNNG1rKGRTJVLQ+bk1KG4wUT0CwmXAhvvOHsrJ1o2fbr/jp/H xFqv2k/7SMQQ7St6iunL7OyEvOzTP5K918cV1e47/RHs8cVb/6BrFl65qs/DhXsDTz mm9qZhZyxAWpaWizhkM/A7lrPqwawQifWfi1Cu1s6I706rB4nAn57vtLT/el+5GvBC OmlcrJhq8wcNU2gwER6r6Js6Rn/ISWNKVeXz6vuUdW1H8F/ejD2KH+W7+zBeOKfEMY 6cF76oOA6X91eouHojc186I5vHnKAGh9VD6O+g30TZ5XHBhJnqEPwucSe5OF69CI3L NwCtgr0sS4gLw== Date: Wed, 20 Dec 2023 04:07:52 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 05/11] ALSA: scarlett2: Add clamp() in scarlett2_mixer_ctl_put() Message-ID: <3b19fb3da641b587749b85fe1daa1b4e696c0c1b.1703001053.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: MM44SESBU3CANCS45TAOQAGLYRJZXHUT X-Message-ID-Hash: MM44SESBU3CANCS45TAOQAGLYRJZXHUT X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Ensure the value passed to scarlett2_mixer_ctl_put() is between 0 and SCARLETT2_MIXER_MAX_VALUE so we don't attempt to access outside scarlett2_mixer_values[]. Signed-off-by: Geoffrey D. Bennett Fixes: 9e4d5c1be21f ("ALSA: usb-audio: Scarlett Gen 2 mixer interface") --- sound/usb/mixer_scarlett2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 373911937487..f1636a1614da 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -3663,7 +3663,8 @@ static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); oval = private->mix[index]; - val = ucontrol->value.integer.value[0]; + val = clamp(ucontrol->value.integer.value[0], + 0L, (long)SCARLETT2_MIXER_MAX_VALUE); num_mixer_in = port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT]; mix_num = index / num_mixer_in; From patchwork Tue Dec 19 17:38:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 755990 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 72D30C41535 for ; Tue, 19 Dec 2023 17:39:58 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 5C330E96; Tue, 19 Dec 2023 18:39:46 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 5C330E96 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007596; bh=B6AfhooOo/f58PQVWikUFOcOdGWfzWywYJajswstrGQ=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=WX5QJr9rMhaK9z1yJAW8d+6XTAjeulxQID6PmbIpvU78dPS2NAYiaNUhg0lyjEGI3 CQV8aSZ6p1OY+NjqfUZn9A2YGQERfw68aaqurDaNlCxtkZ1JHp1YhWblrcMWpHdKw1 H3KtiZOfDDbzH8+h836oYMBuAQOO1/hDj+OJ3+HE= Received: by alsa1.perex.cz (Postfix, from userid 50401) id E966CF805DF; Tue, 19 Dec 2023 18:39:01 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 5F646F805D4; Tue, 19 Dec 2023 18:39:01 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 6CFCEF8055A; Tue, 19 Dec 2023 18:38:56 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 73830F8055B for ; Tue, 19 Dec 2023 18:38:12 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 73830F8055B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=oT6NOiH7 Received: by m.b4.vu (Postfix, from userid 1000) id 5CB6D604B9F7; Wed, 20 Dec 2023 04:08:09 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 5CB6D604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007489; bh=7GVO3MNMTMsgTji6rIpd6tjr7bcMr8xM2wntNzv+XCk=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=oT6NOiH7qkCP5Ea27LIagVg1gtBMTTHvX0ojS716+ZvMAlTdvHCoWdmNoB/W06Ksx uqb3TYrYmkSNgd3dnCFlbMNYTA2ujK3FVrUpxqWwTccbPapdYovQMbfui+zOs9do+Q u+1URU3/Su+fctIP3uy4rVqV7qxWmhnvXjwHoqg9leZ2FkTZzwPtcqw0iU8EiIuJ2j Uh0UBl1mE7ji5b0dxNiUQW4yDNk97ZS+v8XcfaTJxbXrWii2YpTflPG8ksgXGM5zwS vA83ZSWRAbrfBtDyTlH9dASS8tY2e0WKhxpqqXqal9muo5b36slVjCLvEUermz6QWE R95dXIHBdYnjw== Date: Wed, 20 Dec 2023 04:08:09 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 06/11] ALSA: scarlett2: Add missing mutex lock around get meter levels Message-ID: <77e093c27402c83d0730681448fa4f57583349dd.1703001053.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: BZGKWMMCLLTLEM7DWS7UN5JIIUN42HT2 X-Message-ID-Hash: BZGKWMMCLLTLEM7DWS7UN5JIIUN42HT2 X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: As scarlett2_meter_ctl_get() uses meter_level_map[], the data_mutex should be locked while accessing it. Signed-off-by: Geoffrey D. Bennett Fixes: 2b17abb0dec4 ("ALSA: scarlett2: Remap Level Meter values") --- sound/usb/mixer_scarlett2.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index f1636a1614da..73f5badceb19 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -3880,10 +3880,12 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl, u16 meter_levels[SCARLETT2_MAX_METERS]; int i, err; + mutex_lock(&private->data_mutex); + err = scarlett2_usb_get_meter_levels(elem->head.mixer, elem->channels, meter_levels); if (err < 0) - return err; + goto unlock; /* copy & translate from meter_levels[] using meter_level_map[] */ for (i = 0; i < elem->channels; i++) { @@ -3898,7 +3900,10 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl, ucontrol->value.integer.value[i] = value; } - return 0; +unlock: + mutex_unlock(&private->data_mutex); + + return err; } static const struct snd_kcontrol_new scarlett2_meter_ctl = { From patchwork Tue Dec 19 17:38:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 755989 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D288FC46CA2 for ; Tue, 19 Dec 2023 17:40:30 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id D604DE81; Tue, 19 Dec 2023 18:40:18 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D604DE81 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007628; bh=dmu5WhRsGcFZw9k5Y+O97oyAhHLWwCpvYCbBnGTC3WY=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=bdx8TafZEwLi4QFHMlQA1Qi5lZ2ZIWli4PnvtFPgrSvxnK7kJlDb0aXia5qDNo6sT kQ1vPoANeeu6gy1H318OELzH7ScWYyHF2g9kCQIcEvAe1l/bd+T5H0roJJ01hUtwi8 jxfkJEPupYK4yELtKNDR3dpMdbCunxDw7sZyp/k0= Received: by alsa1.perex.cz (Postfix, from userid 50401) id E2173F805A9; Tue, 19 Dec 2023 18:39:38 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id DFDB9F8060B; Tue, 19 Dec 2023 18:39:33 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 10DDBF8057C; Tue, 19 Dec 2023 18:39:30 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CC2DBF80578 for ; Tue, 19 Dec 2023 18:38:46 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CC2DBF80578 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=tb1sscCU Received: by m.b4.vu (Postfix, from userid 1000) id 141F8604B9F7; Wed, 20 Dec 2023 04:08:42 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 141F8604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007522; bh=NHjcjEOW30LqDt4IfDXMQ9aPNo751eyY/StHwOP1mLE=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=tb1sscCUykSPgoRHHihX2OnSiwKUlM4LfDpvrTM051ia1FS8gbOhavuqhCSA5ntM2 yTVn7+GHII6JVFG0GhvPMIUBenDodRJLJ8oIrp0auU2hvTTKr74qkEnG7wHKvxaGVa EmPZ17k1Jx1/Lu4e8dDehEHI5+6AJTrA5lcT1CuPeDculRlxbQ7kFDR1K87c9asAgt yJ79e9ldGlDQE057gNlGeYuo9alfHvwgeYvLa4XpxfE6bZ6bErxR9Zp0d4KMADjcz5 CCKH6Vnyf+Z2lJcGviZl0sMf2oUBVRg0SbW8XAPFbjWkzWFDKeJqzCBTBVJmZxHjBN ge5JBCR2l3bTg== Date: Wed, 20 Dec 2023 04:08:42 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 07/11] ALSA: scarlett2: Add #defines for firmware upgrade Message-ID: <3077651c21bc8d4f046c68b79ec387aa16fcc5e4.1703001053.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: 3QVAC25NSRALI6Y6FCUOLCCBLFJCUKLS X-Message-ID-Hash: 3QVAC25NSRALI6Y6FCUOLCCBLFJCUKLS X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add #defines for SCARLETT2_USB_* needed for firmware upgrade: reboot, info-flash, info-segment, erase-segment, get-erase, and write-segment. Signed-off-by: Geoffrey D. Bennett --- sound/usb/mixer_scarlett2.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 73f5badceb19..129b9c97871a 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -1137,17 +1137,23 @@ static int scarlett2_get_port_start_num( #define SCARLETT2_USB_CMD_REQ 2 #define SCARLETT2_USB_CMD_RESP 3 -#define SCARLETT2_USB_INIT_1 0x00000000 -#define SCARLETT2_USB_INIT_2 0x00000002 -#define SCARLETT2_USB_GET_METER 0x00001001 -#define SCARLETT2_USB_GET_MIX 0x00002001 -#define SCARLETT2_USB_SET_MIX 0x00002002 -#define SCARLETT2_USB_GET_MUX 0x00003001 -#define SCARLETT2_USB_SET_MUX 0x00003002 -#define SCARLETT2_USB_GET_SYNC 0x00006004 -#define SCARLETT2_USB_GET_DATA 0x00800000 -#define SCARLETT2_USB_SET_DATA 0x00800001 -#define SCARLETT2_USB_DATA_CMD 0x00800002 +#define SCARLETT2_USB_INIT_1 0x00000000 +#define SCARLETT2_USB_INIT_2 0x00000002 +#define SCARLETT2_USB_REBOOT 0x00000003 +#define SCARLETT2_USB_GET_METER 0x00001001 +#define SCARLETT2_USB_GET_MIX 0x00002001 +#define SCARLETT2_USB_SET_MIX 0x00002002 +#define SCARLETT2_USB_GET_MUX 0x00003001 +#define SCARLETT2_USB_SET_MUX 0x00003002 +#define SCARLETT2_USB_INFO_FLASH 0x00004000 +#define SCARLETT2_USB_INFO_SEGMENT 0x00004001 +#define SCARLETT2_USB_ERASE_SEGMENT 0x00004002 +#define SCARLETT2_USB_GET_ERASE 0x00004003 +#define SCARLETT2_USB_WRITE_SEGMENT 0x00004004 +#define SCARLETT2_USB_GET_SYNC 0x00006004 +#define SCARLETT2_USB_GET_DATA 0x00800000 +#define SCARLETT2_USB_SET_DATA 0x00800001 +#define SCARLETT2_USB_DATA_CMD 0x00800002 #define SCARLETT2_USB_CONFIG_SAVE 6 From patchwork Tue Dec 19 17:38:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 756430 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CA771C46CA2 for ; Tue, 19 Dec 2023 17:40:47 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id D081EE8B; Tue, 19 Dec 2023 18:40:35 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D081EE8B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007645; bh=tn9ODqRvSOeSUdoBoirNpihfF73zwBcFrYtZf7syd6w=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=k/nU3wYQNVoBryr+44ArUpQ4TSNBkuZFBcyMyUdADic7MfNYICfOsWvQtNjIu+cMb pUmHsq2pDhqEH1y/Giycp5T+KTGibCCWLRNEVFG1CCKPmB9pNlTPOIUPJhG7UBGpCl hFOigX+t8EmCmnscUrb4sji5rm/c6Eldi+Ghk7wk= Received: by alsa1.perex.cz (Postfix, from userid 50401) id E4870F805A8; Tue, 19 Dec 2023 18:39:43 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id B949AF80603; Tue, 19 Dec 2023 18:39:42 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4D4DDF805A8; Tue, 19 Dec 2023 18:39:39 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id C48FAF805E1 for ; Tue, 19 Dec 2023 18:39:01 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz C48FAF805E1 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=SwQYEH/r Received: by m.b4.vu (Postfix, from userid 1000) id 9E3C6604B9F7; Wed, 20 Dec 2023 04:08:58 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 9E3C6604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007538; bh=i2UBZbVX9JemXjLTX5TBcZIY/bD71bJlRplkQc6myNQ=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=SwQYEH/r64tuYyekgUqn6HmGTxbZ1Ur+jtB5tLCTWIGBbAVFXBw3dFf1QcQvahJ6J iLBoe0FgybnuffxK4MTqG+/uWXDpfWj8z0MVwv/6CXYPPQH3mtu2wig5asCwEUrGaJ 8oOoD9kITWi4btYA5hRubJIF6l/6UmEdlk+IiZCkrx2zsjmemqcy0DU6+RagIBPns/ KoZtxPfHdWtwsAEB/6xuJ/xLMOs6F9pN0B3JZuRD0GymlSYv9Phz1CQAwQvg5a6GXa oQbT8TVnkkOe+H3NXVxbBqpmErbcrwEGENX/lBS3VbNENPpW2eYrkVBArTsroelGI0 PFuP10NQQ8YQg== Date: Wed, 20 Dec 2023 04:08:58 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 08/11] ALSA: scarlett2: Retrieve useful flash segment numbers Message-ID: <70f0108a9cf99b69f7aa920c4bcdb0cf4bf3da98.1703001053.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: DYZDMABPPWIA4MJRVEBXEXKYUK5H3KOO X-Message-ID-Hash: DYZDMABPPWIA4MJRVEBXEXKYUK5H3KOO X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Call SCARLETT2_USB_INFO_FLASH and SCARLETT2_USB_INFO_SEGMENT to find the App_Settings and App_Upgrade flash segment numbers, and store them in the scarlett2_data struct. These will be used later to implement reset to factory defaults and firmware upgrade functions. Signed-off-by: Geoffrey D. Bennett --- sound/usb/mixer_scarlett2.c | 103 ++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 129b9c97871a..34878f9f9a55 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -190,6 +190,11 @@ static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = { 16345 }; +/* Flash segments that we may manipulate */ +#define SCARLETT2_SEGMENT_ID_SETTINGS 0 +#define SCARLETT2_SEGMENT_ID_FIRMWARE 1 +#define SCARLETT2_SEGMENT_ID_COUNT 2 + /* Maximum number of analogue outputs */ #define SCARLETT2_ANALOGUE_MAX 10 @@ -429,6 +434,8 @@ struct scarlett2_data { int num_mux_srcs; int num_mux_dsts; u32 firmware_version; + u8 flash_segment_nums[SCARLETT2_SEGMENT_ID_COUNT]; + u8 flash_segment_blocks[SCARLETT2_SEGMENT_ID_COUNT]; u16 scarlett2_seq; u8 sync_updated; u8 vol_updated; @@ -1160,6 +1167,13 @@ static int scarlett2_get_port_start_num( #define SCARLETT2_USB_VOLUME_STATUS_OFFSET 0x31 #define SCARLETT2_USB_METER_LEVELS_GET_MAGIC 1 +#define SCARLETT2_FLASH_BLOCK_SIZE 4096 +#define SCARLETT2_SEGMENT_NUM_MIN 1 +#define SCARLETT2_SEGMENT_NUM_MAX 4 + +#define SCARLETT2_SEGMENT_SETTINGS_NAME "App_Settings" +#define SCARLETT2_SEGMENT_FIRMWARE_NAME "App_Upgrade" + /* volume status is read together (matches scarlett2_config_items[1]) */ struct scarlett2_usb_volume_status { /* dim/mute buttons */ @@ -4202,6 +4216,90 @@ static int scarlett2_usb_init(struct usb_mixer_interface *mixer) return 0; } +/* Get the flash segment numbers for the App_Settings and App_Upgrade + * segments and put them in the private data + */ +static int scarlett2_get_flash_segment_nums(struct usb_mixer_interface *mixer) +{ + struct scarlett2_data *private = mixer->private_data; + int err, count, i; + + struct { + __le32 size; + __le32 count; + u8 unknown[8]; + } __packed flash_info; + + struct { + __le32 size; + __le32 flags; + char name[16]; + } __packed segment_info; + + err = scarlett2_usb(mixer, SCARLETT2_USB_INFO_FLASH, + NULL, 0, + &flash_info, sizeof(flash_info)); + if (err < 0) + return err; + + count = le32_to_cpu(flash_info.count); + + /* sanity check count */ + if (count < SCARLETT2_SEGMENT_NUM_MIN || + count > SCARLETT2_SEGMENT_NUM_MAX + 1) { + usb_audio_err(mixer->chip, + "invalid flash segment count: %d\n", count); + return -EINVAL; + } + + for (i = 0; i < count; i++) { + __le32 segment_num_req = cpu_to_le32(i); + int flash_segment_id; + + err = scarlett2_usb(mixer, SCARLETT2_USB_INFO_SEGMENT, + &segment_num_req, sizeof(segment_num_req), + &segment_info, sizeof(segment_info)); + if (err < 0) { + usb_audio_err(mixer->chip, + "failed to get flash segment info %d: %d\n", + i, err); + return err; + } + + if (!strncmp(segment_info.name, + SCARLETT2_SEGMENT_SETTINGS_NAME, 16)) + flash_segment_id = SCARLETT2_SEGMENT_ID_SETTINGS; + else if (!strncmp(segment_info.name, + SCARLETT2_SEGMENT_FIRMWARE_NAME, 16)) + flash_segment_id = SCARLETT2_SEGMENT_ID_FIRMWARE; + else + continue; + + private->flash_segment_nums[flash_segment_id] = i; + private->flash_segment_blocks[flash_segment_id] = + le32_to_cpu(segment_info.size) / + SCARLETT2_FLASH_BLOCK_SIZE; + } + + /* segment 0 is App_Gold and we never want to touch that, so + * use 0 as the "not-found" value + */ + if (!private->flash_segment_nums[SCARLETT2_SEGMENT_ID_SETTINGS]) { + usb_audio_err(mixer->chip, + "failed to find flash segment %s\n", + SCARLETT2_SEGMENT_SETTINGS_NAME); + return -EINVAL; + } + if (!private->flash_segment_nums[SCARLETT2_SEGMENT_ID_FIRMWARE]) { + usb_audio_err(mixer->chip, + "failed to find flash segment %s\n", + SCARLETT2_SEGMENT_FIRMWARE_NAME); + return -EINVAL; + } + + return 0; +} + /* Read configuration from the interface on start */ static int scarlett2_read_configs(struct usb_mixer_interface *mixer) { @@ -4517,6 +4615,11 @@ static int snd_scarlett2_controls_create( if (err < 0) return err; + /* Get the upgrade & settings flash segment numbers */ + err = scarlett2_get_flash_segment_nums(mixer); + if (err < 0) + return err; + /* Add firmware version control */ err = scarlett2_add_firmware_version_ctl(mixer); if (err < 0) From patchwork Tue Dec 19 17:39:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 755988 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B4FDFC46CCD for ; Tue, 19 Dec 2023 17:41:03 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 17B60EAD; Tue, 19 Dec 2023 18:40:52 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 17B60EAD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703007662; bh=dz8d53A7UMa3K2UhxohEQElLO6LYJfXODNCXXNUKq4s=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=ANyQABwOMIrcVz+jh4uBgwydnRGYbI6mKovmKmOzvYCG3yRpa9RpcpTq6ucpbdbTD KcVIHFFFI8LHc2OIxbWgMCXwFD27IwuvBXl8KxlmOVv3tF7EEtBEViw5SqeWt6hqqs QDYWBR/vNDek1RTssAWuXHlifeTzsOqWJI2LaP0U= Received: by alsa1.perex.cz (Postfix, from userid 50401) id D5166F805C4; Tue, 19 Dec 2023 18:40:11 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 8601DF805F0; Tue, 19 Dec 2023 18:40:10 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id C0DD6F805BE; Tue, 19 Dec 2023 18:40:02 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 3B9F2F804DA for ; Tue, 19 Dec 2023 18:39:27 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 3B9F2F804DA Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=G/3eEbQ+ Received: by m.b4.vu (Postfix, from userid 1000) id 50551604B9F7; Wed, 20 Dec 2023 04:09:23 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 50551604B9F7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703007563; bh=Wwcw9RjvBs9K31sVeM8U0U+Xy1IA51F7Ah/eptGSN5w=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=G/3eEbQ+yZ3imjDf8F2iRnOtUYpPbT2B/0/463WiEEpnVTl3GereBH1U4xfklNAHr 7nLn6XxQEZ0cAZoGIB4bvbHbKof1oHYqFU03rTkvs+hda78fNlyeLDaGl/CBjWX/cr gfSTGBYlS4y3clVICar56hK2kXPkEtG946OSvyRd0cELVvWQpVm+6RXcFlt1LxUX5o J4BQKc6CopqCgNYRGCiaDwQP2lki9tntrv8iFuQ9KZPr2RkTx4bZPtaARF5XBD/1h5 cbyT+mR1sSBZgZ36wmWYA7Lb0o73GYopSMXahHYaynnLfqz8MbAPub9AiKij4gzxwT oaKuS3GTpmUsQ== Date: Wed, 20 Dec 2023 04:09:23 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 09/11] ALSA: scarlett2: Add skeleton hwdep/ioctl interface Message-ID: <24ffcd47a8a02ebad3c8b2438104af8f0169164e.1703001053.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: DXQW266PRLS6HXNPUQILWHLW5N6MHTXP X-Message-ID-Hash: DXQW266PRLS6HXNPUQILWHLW5N6MHTXP X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add skeleton hwdep/ioctl interface, beginning with SCARLETT2_IOCTL_PVERSION and SCARLETT2_IOCTL_REBOOT. Signed-off-by: Geoffrey D. Bennett --- MAINTAINERS | 1 + include/uapi/sound/scarlett2.h | 34 +++++++++++++++++ sound/usb/mixer_scarlett2.c | 67 +++++++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 include/uapi/sound/scarlett2.h diff --git a/MAINTAINERS b/MAINTAINERS index ae3f72f57854..80c65096538c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8279,6 +8279,7 @@ S: Maintained W: https://github.com/geoffreybennett/scarlett-gen2 B: https://github.com/geoffreybennett/scarlett-gen2/issues T: git https://github.com/geoffreybennett/scarlett-gen2.git +F: include/uapi/sound/scarlett2.h F: sound/usb/mixer_scarlett2.c FORCEDETH GIGABIT ETHERNET DRIVER diff --git a/include/uapi/sound/scarlett2.h b/include/uapi/sound/scarlett2.h new file mode 100644 index 000000000000..ec0b7da335ff --- /dev/null +++ b/include/uapi/sound/scarlett2.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Focusrite Scarlett 2 Protocol Driver for ALSA + * (including Scarlett 2nd Gen, 3rd Gen, Clarett USB, and Clarett+ + * series products) + * + * Copyright (c) 2023 by Geoffrey D. Bennett + */ +#ifndef __UAPI_SOUND_SCARLETT2_H +#define __UAPI_SOUND_SCARLETT2_H + +#include +#include + +#define SCARLETT2_HWDEP_MAJOR 1 +#define SCARLETT2_HWDEP_MINOR 0 +#define SCARLETT2_HWDEP_SUBMINOR 0 + +#define SCARLETT2_HWDEP_VERSION \ + ((SCARLETT2_HWDEP_MAJOR << 16) | \ + (SCARLETT2_HWDEP_MINOR << 8) | \ + SCARLETT2_HWDEP_SUBMINOR) + +#define SCARLETT2_HWDEP_VERSION_MAJOR(v) (((v) >> 16) & 0xFF) +#define SCARLETT2_HWDEP_VERSION_MINOR(v) (((v) >> 8) & 0xFF) +#define SCARLETT2_HWDEP_VERSION_SUBMINOR(v) ((v) & 0xFF) + +/* Get protocol version */ +#define SCARLETT2_IOCTL_PVERSION _IOR('S', 0x60, int) + +/* Reboot */ +#define SCARLETT2_IOCTL_REBOOT _IO('S', 0x61) + +#endif /* __UAPI_SOUND_SCARLETT2_H */ diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 34878f9f9a55..c0c96d7c19fb 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -146,6 +146,9 @@ #include #include +#include + +#include #include "usbaudio.h" #include "mixer.h" @@ -1439,6 +1442,16 @@ static int scarlett2_usb( /* validate the response */ if (err != resp_buf_size) { + + /* ESHUTDOWN and EPROTO are valid responses to a + * reboot request + */ + if (cmd == SCARLETT2_USB_REBOOT && + (err == -ESHUTDOWN || err == -EPROTO)) { + err = 0; + goto unlock; + } + usb_audio_err( mixer->chip, "%s USB response result cmd %x was %d expected %zu\n", @@ -4697,6 +4710,49 @@ static int snd_scarlett2_controls_create( return 0; } +/*** hwdep interface ***/ + +/* Reboot the device. */ +static int scarlett2_reboot(struct usb_mixer_interface *mixer) +{ + return scarlett2_usb(mixer, SCARLETT2_USB_REBOOT, NULL, 0, NULL, 0); +} + +static int scarlett2_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct usb_mixer_interface *mixer = hw->private_data; + + switch (cmd) { + + case SCARLETT2_IOCTL_PVERSION: + return put_user(SCARLETT2_HWDEP_VERSION, + (int __user *)arg) ? -EFAULT : 0; + + case SCARLETT2_IOCTL_REBOOT: + return scarlett2_reboot(mixer); + + default: + return -ENOIOCTLCMD; + } +} + +static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer) +{ + struct snd_hwdep *hw; + int err; + + err = snd_hwdep_new(mixer->chip->card, "Focusrite Control", 0, &hw); + if (err < 0) + return err; + + hw->private_data = mixer; + hw->exclusive = 1; + hw->ops.ioctl = scarlett2_hwdep_ioctl; + + return 0; +} + int snd_scarlett2_init(struct usb_mixer_interface *mixer) { struct snd_usb_audio *chip = mixer->chip; @@ -4738,11 +4794,20 @@ int snd_scarlett2_init(struct usb_mixer_interface *mixer) USB_ID_PRODUCT(chip->usb_id)); err = snd_scarlett2_controls_create(mixer, entry); - if (err < 0) + if (err < 0) { usb_audio_err(mixer->chip, "Error initialising %s Mixer Driver: %d", entry->series_name, err); + return err; + } + + err = scarlett2_hwdep_init(mixer); + if (err < 0) + usb_audio_err(mixer->chip, + "Error creating %s hwdep device: %d", + entry->series_name, + err); return err; } From patchwork Tue Dec 19 17:50:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 756429 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 51E1EC41535 for ; Tue, 19 Dec 2023 17:51:34 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 956AEE97; Tue, 19 Dec 2023 18:51:22 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 956AEE97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703008292; bh=p8y5YuWQn76CrrZESdP5DcgEcd6hdv+lqNaD0jXCMLw=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=P6Cz1g46qzfXNWrWKn2z5AW1k71iyMvMNNqrnRs28IOMDaKvCpaxWVCy0H9ipD/Q3 nodWcNypPXK+nFoPhzqhRGJd/4u761wpVyJsFE8uIf+Y+Tl5hqJi8Xj5x0LXLk2HsO pnEJ08dSzBJHMikWMuyKfXE2LTZTIr+4zwlChm94= Received: by alsa1.perex.cz (Postfix, from userid 50401) id CDA30F80431; Tue, 19 Dec 2023 18:51:00 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 33C51F80431; Tue, 19 Dec 2023 18:51:00 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 10AEBF80425; Tue, 19 Dec 2023 18:50:53 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 34B78F80124 for ; Tue, 19 Dec 2023 18:50:32 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 34B78F80124 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=PcoK4Bd4 Received: by m.b4.vu (Postfix, from userid 1000) id 2DB47604B9CB; Wed, 20 Dec 2023 04:20:29 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 2DB47604B9CB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703008229; bh=sN4jUcW5JJHf7WnupT3n8E5DZ78kAC8RXYMuPJPd1lA=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=PcoK4Bd46l8EQ7acWYWmb1jheHdchWqfFjHSa8NXp8RJ4/lDeNdQwPEYCVeynKfvR ArGk+S2om4IixF8grZwYPklyn7JQcHlTasrnNIQDXdOrXOn9C+xRLBxzeM0xNVqlmk NaBhe/27Jb+ljLkOa19qat9Dq02K2oxBwi3x+O+Of45FidQ/lwYib+Yr0JM2+ShdMH W90odDy21LEB5fhSjJoAYutNfFc4LNpIfmiL6HiJqKeoYDO/QhWwSHSFih1ijQlO6N LIMB0at8ofQlHUxtCfWqi6Zf4WH4ybQ9+V6xiirJjtFvK+yOfIeHEDST/H+XdAWOZS Mjp9G9HP6i/8A== Date: Wed, 20 Dec 2023 04:20:29 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 10/11] ALSA: scarlett2: Add ioctl commands to erase flash segments Message-ID: <227409adb672f174bf3db211e9bda016fb4646ea.1703001053.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: 52MSHAPKTMY6EC4KHUKNEPYGZBEA5SOF X-Message-ID-Hash: 52MSHAPKTMY6EC4KHUKNEPYGZBEA5SOF X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add ioctls: - SCARLETT2_IOCTL_SELECT_FLASH_SEGMENT - SCARLETT2_IOCTL_ERASE_FLASH_SEGMENT - SCARLETT2_IOCTL_GET_ERASE_PROGRESS The settings or the firmware flash segment can be selected and then erased (asynchronous operation), and the erase progress can be monitored. If the erase progress is not monitored, then subsequent hwdep operations will block until the erase is complete. Once the erase is started, ALSA controls that communicate with the device will all return -EBUSY, and the device must be rebooted. Signed-off-by: Geoffrey D. Bennett --- include/uapi/sound/scarlett2.h | 20 ++ sound/usb/mixer_scarlett2.c | 428 ++++++++++++++++++++++++++++++++- 2 files changed, 442 insertions(+), 6 deletions(-) diff --git a/include/uapi/sound/scarlett2.h b/include/uapi/sound/scarlett2.h index ec0b7da335ff..d0ff38ffa154 100644 --- a/include/uapi/sound/scarlett2.h +++ b/include/uapi/sound/scarlett2.h @@ -31,4 +31,24 @@ /* Reboot */ #define SCARLETT2_IOCTL_REBOOT _IO('S', 0x61) +/* Select flash segment */ +#define SCARLETT2_SEGMENT_ID_SETTINGS 0 +#define SCARLETT2_SEGMENT_ID_FIRMWARE 1 +#define SCARLETT2_SEGMENT_ID_COUNT 2 + +#define SCARLETT2_IOCTL_SELECT_FLASH_SEGMENT _IOW('S', 0x62, int) + +/* Erase selected flash segment */ +#define SCARLETT2_IOCTL_ERASE_FLASH_SEGMENT _IO('S', 0x63) + +/* Get selected flash segment erase progress + * 1 through to num_blocks, or 255 for complete + */ +struct scarlett2_flash_segment_erase_progress { + unsigned char progress; + unsigned char num_blocks; +}; +#define SCARLETT2_IOCTL_GET_ERASE_PROGRESS \ + _IOR('S', 0x64, struct scarlett2_flash_segment_erase_progress) + #endif /* __UAPI_SOUND_SCARLETT2_H */ diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index c0c96d7c19fb..ca09d0cd0cae 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -193,11 +193,6 @@ static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = { 16345 }; -/* Flash segments that we may manipulate */ -#define SCARLETT2_SEGMENT_ID_SETTINGS 0 -#define SCARLETT2_SEGMENT_ID_FIRMWARE 1 -#define SCARLETT2_SEGMENT_ID_COUNT 2 - /* Maximum number of analogue outputs */ #define SCARLETT2_ANALOGUE_MAX 10 @@ -267,6 +262,13 @@ enum { SCARLETT2_DIM_MUTE_COUNT = 2, }; +/* Flash Write State */ +enum { + SCARLETT2_FLASH_WRITE_STATE_IDLE = 0, + SCARLETT2_FLASH_WRITE_STATE_SELECTED = 1, + SCARLETT2_FLASH_WRITE_STATE_ERASING = 2 +}; + static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = { "Mute Playback Switch", "Dim Playback Switch" }; @@ -427,6 +429,9 @@ struct scarlett2_data { struct usb_mixer_interface *mixer; struct mutex usb_mutex; /* prevent sending concurrent USB requests */ struct mutex data_mutex; /* lock access to this data */ + u8 hwdep_in_use; + u8 selected_flash_segment_id; + u8 flash_write_state; struct delayed_work work; const struct scarlett2_device_info *info; const char *series_name; @@ -2137,6 +2142,11 @@ static int scarlett2_sync_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->sync_updated) { err = scarlett2_update_sync(mixer); if (err < 0) @@ -2233,6 +2243,11 @@ static int scarlett2_master_volume_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->vol_updated) { err = scarlett2_update_volumes(mixer); if (err < 0) @@ -2272,6 +2287,11 @@ static int scarlett2_volume_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->vol_updated) { err = scarlett2_update_volumes(mixer); if (err < 0) @@ -2295,6 +2315,11 @@ static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->vol[index]; val = ucontrol->value.integer.value[0]; @@ -2352,6 +2377,11 @@ static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->vol_updated) { err = scarlett2_update_volumes(mixer); if (err < 0) @@ -2375,6 +2405,11 @@ static int scarlett2_mute_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->mute_switch[index]; val = !!ucontrol->value.integer.value[0]; @@ -2514,6 +2549,11 @@ static int scarlett2_sw_hw_enum_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->vol_sw_hw_switch[index]; val = !!ucontrol->value.enumerated.item[0]; @@ -2611,6 +2651,11 @@ static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->input_other_updated) { err = scarlett2_update_input_other(mixer); if (err < 0) @@ -2636,6 +2681,11 @@ static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->level_switch[index]; val = !!ucontrol->value.enumerated.item[0]; @@ -2675,6 +2725,11 @@ static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->input_other_updated) { err = scarlett2_update_input_other(mixer); if (err < 0) @@ -2700,6 +2755,11 @@ static int scarlett2_pad_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->pad_switch[index]; val = !!ucontrol->value.integer.value[0]; @@ -2739,6 +2799,11 @@ static int scarlett2_air_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->input_other_updated) { err = scarlett2_update_input_other(mixer); if (err < 0) @@ -2763,6 +2828,11 @@ static int scarlett2_air_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->air_switch[index]; val = !!ucontrol->value.integer.value[0]; @@ -2802,6 +2872,11 @@ static int scarlett2_phantom_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->input_other_updated) { err = scarlett2_update_input_other(mixer); if (err < 0) @@ -2827,6 +2902,11 @@ static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->phantom_switch[index]; val = !!ucontrol->value.integer.value[0]; @@ -2878,6 +2958,11 @@ static int scarlett2_phantom_persistence_ctl_put( mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->phantom_persistence; val = !!ucontrol->value.integer.value[0]; @@ -2988,6 +3073,11 @@ static int scarlett2_direct_monitor_ctl_get( mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->monitor_other_updated) { err = scarlett2_update_monitor_other(mixer); if (err < 0) @@ -3012,6 +3102,11 @@ static int scarlett2_direct_monitor_ctl_put( mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->direct_monitor_switch; val = min(ucontrol->value.enumerated.item[0], 2U); @@ -3101,6 +3196,11 @@ static int scarlett2_speaker_switch_enum_ctl_get( mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->monitor_other_updated) { err = scarlett2_update_monitor_other(mixer); if (err < 0) @@ -3181,6 +3281,11 @@ static int scarlett2_speaker_switch_enum_ctl_put( mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->speaker_switching_switch; val = min(ucontrol->value.enumerated.item[0], 2U); @@ -3262,6 +3367,11 @@ static int scarlett2_talkback_enum_ctl_get( mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->monitor_other_updated) { err = scarlett2_update_monitor_other(mixer); if (err < 0) @@ -3285,6 +3395,11 @@ static int scarlett2_talkback_enum_ctl_put( mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->talkback_switch; val = min(ucontrol->value.enumerated.item[0], 2U); @@ -3349,6 +3464,11 @@ static int scarlett2_talkback_map_ctl_put( mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->talkback_map[index]; val = !!ucontrol->value.integer.value[0]; @@ -3423,6 +3543,11 @@ static int scarlett2_dim_mute_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->vol_updated) { err = scarlett2_update_volumes(mixer); if (err < 0) @@ -3451,6 +3576,11 @@ static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->dim_mute[index]; val = !!ucontrol->value.integer.value[0]; @@ -3695,6 +3825,11 @@ static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->mix[index]; val = clamp(ucontrol->value.integer.value[0], 0L, (long)SCARLETT2_MIXER_MAX_VALUE); @@ -3808,6 +3943,11 @@ static int scarlett2_mux_src_enum_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + if (private->mux_updated) { err = scarlett2_usb_get_mux(mixer); if (err < 0) @@ -3831,6 +3971,11 @@ static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->mux[index]; val = min(ucontrol->value.enumerated.item[0], private->num_mux_srcs - 1U); @@ -3915,6 +4060,11 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + err = scarlett2_usb_get_meter_levels(elem->head.mixer, elem->channels, meter_levels); if (err < 0) @@ -3983,6 +4133,11 @@ static int scarlett2_msd_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->msd_switch; val = !!ucontrol->value.integer.value[0]; @@ -4050,6 +4205,11 @@ static int scarlett2_standalone_ctl_put(struct snd_kcontrol *kctl, mutex_lock(&private->data_mutex); + if (private->hwdep_in_use) { + err = -EBUSY; + goto unlock; + } + oval = private->standalone_switch; val = !!ucontrol->value.integer.value[0]; @@ -4712,12 +4872,241 @@ static int snd_scarlett2_controls_create( /*** hwdep interface ***/ -/* Reboot the device. */ +/* Set private->hwdep_in_use; prevents access to the ALSA controls + * while doing a config erase/firmware upgrade. + */ +static void scarlett2_lock(struct scarlett2_data *private) +{ + mutex_lock(&private->data_mutex); + private->hwdep_in_use = 1; + mutex_unlock(&private->data_mutex); +} + +/* Call SCARLETT2_USB_GET_ERASE to get the erase progress */ +static int scarlett2_get_erase_progress(struct usb_mixer_interface *mixer) +{ + struct scarlett2_data *private = mixer->private_data; + int segment_id, segment_num, err; + u8 erase_resp; + + struct { + __le32 segment_num; + __le32 pad; + } __packed erase_req; + + segment_id = private->selected_flash_segment_id; + segment_num = private->flash_segment_nums[segment_id]; + + if (segment_num < SCARLETT2_SEGMENT_NUM_MIN || + segment_num > SCARLETT2_SEGMENT_NUM_MAX) + return -EFAULT; + + /* Send the erase progress request */ + erase_req.segment_num = cpu_to_le32(segment_num); + erase_req.pad = 0; + + err = scarlett2_usb(mixer, SCARLETT2_USB_GET_ERASE, + &erase_req, sizeof(erase_req), + &erase_resp, sizeof(erase_resp)); + if (err < 0) + return err; + + return erase_resp; +} + +/* Repeatedly call scarlett2_get_erase_progress() until it returns + * 0xff (erase complete) or we've waited 10 seconds (it usually takes + * <3 seconds). + */ +static int scarlett2_wait_for_erase(struct usb_mixer_interface *mixer) +{ + int i, err; + + for (i = 0; i < 100; i++) { + err = scarlett2_get_erase_progress(mixer); + if (err < 0) + return err; + + if (err == 0xff) + return 0; + + msleep(100); + } + + return -ETIMEDOUT; +} + +/* Reboot the device; wait for the erase to complete if one is in + * progress. + */ static int scarlett2_reboot(struct usb_mixer_interface *mixer) { + struct scarlett2_data *private = mixer->private_data; + + if (private->flash_write_state == + SCARLETT2_FLASH_WRITE_STATE_ERASING) { + int err = scarlett2_wait_for_erase(mixer); + + if (err < 0) + return err; + } + return scarlett2_usb(mixer, SCARLETT2_USB_REBOOT, NULL, 0, NULL, 0); } +/* Select a flash segment for erasing (and possibly writing to) */ +static int scarlett2_ioctl_select_flash_segment( + struct usb_mixer_interface *mixer, + unsigned long arg) +{ + struct scarlett2_data *private = mixer->private_data; + int segment_id, segment_num; + + if (get_user(segment_id, (int __user *)arg)) + return -EFAULT; + + /* Check the segment ID and segment number */ + if (segment_id < 0 || segment_id >= SCARLETT2_SEGMENT_ID_COUNT) + return -EINVAL; + + segment_num = private->flash_segment_nums[segment_id]; + if (segment_num < SCARLETT2_SEGMENT_NUM_MIN || + segment_num > SCARLETT2_SEGMENT_NUM_MAX) { + usb_audio_err(mixer->chip, + "%s: invalid segment number %d\n", + __func__, segment_id); + return -EFAULT; + } + + /* If erasing, wait for it to complete */ + if (private->flash_write_state == SCARLETT2_FLASH_WRITE_STATE_ERASING) { + int err = scarlett2_wait_for_erase(mixer); + + if (err < 0) + return err; + } + + /* Save the selected segment ID and set the state to SELECTED */ + private->selected_flash_segment_id = segment_id; + private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_SELECTED; + + return 0; +} + +/* Erase the previously-selected flash segment */ +static int scarlett2_ioctl_erase_flash_segment( + struct usb_mixer_interface *mixer) +{ + struct scarlett2_data *private = mixer->private_data; + int segment_id, segment_num, err; + + struct { + __le32 segment_num; + __le32 pad; + } __packed erase_req; + + if (private->flash_write_state != SCARLETT2_FLASH_WRITE_STATE_SELECTED) + return -EINVAL; + + segment_id = private->selected_flash_segment_id; + segment_num = private->flash_segment_nums[segment_id]; + + if (segment_num < SCARLETT2_SEGMENT_NUM_MIN || + segment_num > SCARLETT2_SEGMENT_NUM_MAX) + return -EFAULT; + + /* Prevent access to ALSA controls that access the device from + * here on + */ + scarlett2_lock(private); + + /* Send the erase request */ + erase_req.segment_num = cpu_to_le32(segment_num); + erase_req.pad = 0; + + err = scarlett2_usb(mixer, SCARLETT2_USB_ERASE_SEGMENT, + &erase_req, sizeof(erase_req), + NULL, 0); + if (err < 0) + return err; + + /* On success, change the state from SELECTED to ERASING */ + private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_ERASING; + + return 0; +} + +/* Get the erase progress from the device */ +static int scarlett2_ioctl_get_erase_progress( + struct usb_mixer_interface *mixer, + unsigned long arg) +{ + struct scarlett2_data *private = mixer->private_data; + struct scarlett2_flash_segment_erase_progress progress; + int segment_id, segment_num, err; + u8 erase_resp; + + struct { + __le32 segment_num; + __le32 pad; + } __packed erase_req; + + /* Check that we're erasing */ + if (private->flash_write_state != SCARLETT2_FLASH_WRITE_STATE_ERASING) + return -EINVAL; + + segment_id = private->selected_flash_segment_id; + segment_num = private->flash_segment_nums[segment_id]; + + if (segment_num < SCARLETT2_SEGMENT_NUM_MIN || + segment_num > SCARLETT2_SEGMENT_NUM_MAX) + return -EFAULT; + + /* Send the erase progress request */ + erase_req.segment_num = cpu_to_le32(segment_num); + erase_req.pad = 0; + + err = scarlett2_usb(mixer, SCARLETT2_USB_GET_ERASE, + &erase_req, sizeof(erase_req), + &erase_resp, sizeof(erase_resp)); + if (err < 0) + return err; + + progress.progress = erase_resp; + progress.num_blocks = private->flash_segment_blocks[segment_id]; + + if (copy_to_user((void __user *)arg, &progress, sizeof(progress))) + return -EFAULT; + + /* If the erase is complete, change the state from ERASING to + * IDLE. + */ + if (progress.progress == 0xff) + private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_IDLE; + + return 0; +} + +static int scarlett2_hwdep_open(struct snd_hwdep *hw, struct file *file) +{ + struct usb_mixer_interface *mixer = hw->private_data; + struct scarlett2_data *private = mixer->private_data; + + /* If erasing, wait for it to complete */ + if (private->flash_write_state == + SCARLETT2_FLASH_WRITE_STATE_ERASING) { + int err = scarlett2_wait_for_erase(mixer); + + if (err < 0) + return err; + } + + /* Set the state to IDLE */ + private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_IDLE; + + return 0; +} + static int scarlett2_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) { @@ -4732,11 +5121,36 @@ static int scarlett2_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, case SCARLETT2_IOCTL_REBOOT: return scarlett2_reboot(mixer); + case SCARLETT2_IOCTL_SELECT_FLASH_SEGMENT: + return scarlett2_ioctl_select_flash_segment(mixer, arg); + + case SCARLETT2_IOCTL_ERASE_FLASH_SEGMENT: + return scarlett2_ioctl_erase_flash_segment(mixer); + + case SCARLETT2_IOCTL_GET_ERASE_PROGRESS: + return scarlett2_ioctl_get_erase_progress(mixer, arg); + default: return -ENOIOCTLCMD; } } +static int scarlett2_hwdep_release(struct snd_hwdep *hw, struct file *file) +{ + struct usb_mixer_interface *mixer = hw->private_data; + struct scarlett2_data *private = mixer->private_data; + + /* Return from the SELECTED or WRITE state to IDLE. + * The ERASING state is left as-is, and checked on next open. + */ + if (private && + private->hwdep_in_use && + private->flash_write_state != SCARLETT2_FLASH_WRITE_STATE_ERASING) + private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_IDLE; + + return 0; +} + static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer) { struct snd_hwdep *hw; @@ -4748,7 +5162,9 @@ static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer) hw->private_data = mixer; hw->exclusive = 1; + hw->ops.open = scarlett2_hwdep_open; hw->ops.ioctl = scarlett2_hwdep_ioctl; + hw->ops.release = scarlett2_hwdep_release; return 0; } From patchwork Tue Dec 19 17:50:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 755987 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5F9CAC41535 for ; Tue, 19 Dec 2023 17:52:00 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 960A4EB1; Tue, 19 Dec 2023 18:51:43 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 960A4EB1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1703008313; bh=PtOhvQyGTaCkKkrCS4V7zjfiML6JyyywRpciCy1sxr0=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Y8E+8H1SJ1VxfwN8zskMR1Xt2zyhu5XBZrCIK/PAoXN50H4we3XGDy+MCKMRxCKbS SIScb+d5zzslN0rsuVdrocxCLEruDnL3NiWJXHKEJJYLp0VfpijCLF5fU+G9BWgvLl D8KoQQ0+kxA8KgI+R0h3MRBUbsaRU1gpIUbvYFXE= Received: by alsa1.perex.cz (Postfix, from userid 50401) id AC844F805C2; Tue, 19 Dec 2023 18:51:12 +0100 (CET) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 40868F805D5; Tue, 19 Dec 2023 18:51:09 +0100 (CET) Received: by alsa1.perex.cz (Postfix, from userid 50401) id BEC3DF805B0; Tue, 19 Dec 2023 18:51:04 +0100 (CET) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id C6F1DF8055C for ; Tue, 19 Dec 2023 18:50:59 +0100 (CET) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz C6F1DF8055C Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key, unprotected) header.d=b4.vu header.i=@b4.vu header.a=rsa-sha256 header.s=m1 header.b=nAPSaB7k Received: by m.b4.vu (Postfix, from userid 1000) id 06DC2604B9CB; Wed, 20 Dec 2023 04:20:56 +1030 (ACDT) DKIM-Filter: OpenDKIM Filter v2.11.0 m.b4.vu 06DC2604B9CB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=b4.vu; s=m1; t=1703008256; bh=YyQGcbQaeEvepBxl5EF5haAlnb5x8IHq3wQvDFU7jms=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=nAPSaB7kQaugVz5gFx3T0aKFuxVzssY/gyK9+M5uiQagQrnc3ykw6Jb1hQ1aeAg09 qy8B0GdnjrEo88fC1S93SGHzxqui8g6kW70Zp1zQAoVV7R5bLCy4sDmUrDpz2Ucax+ i92qzSHY1mOfuZDCGMHbgZcDSCXHIXUcA5Z+FHQz4AFaPzOFZhbYKo2I+a9Q4vOcWQ nzhaIhpE1asHH0azzv0cpZXIa6UgIj6wBFxt8AnsZpXHo8DZg28avLeurufWkmk2Lu AB2a3P+bbxAa7RPZIYXqgthLFKCaONqXDrkxtGewxl7zGMPl4yyyhjhCHui8LShoCn 6kVs0qOTiJQ7g== Date: Wed, 20 Dec 2023 04:20:55 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: Jaroslav Kysela , Takashi Iwai , alsa-devel@alsa-project.org, linux-sound@vger.kernel.org Subject: [PATCH 11/11] ALSA: scarlett2: Add support for uploading new firmware Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: GWX2IIUAIQD5X5A2RFUYT6YEJJZILN4W X-Message-ID-Hash: GWX2IIUAIQD5X5A2RFUYT6YEJJZILN4W X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add ops.write to the hwdep interface. Once the upgrade firmware flash segment has been erased, writes to the hwdep fd are permitted, and translated to SCARLETT2_USB_WRITE_SEGMENT commands to the device. Signed-off-by: Geoffrey D. Bennett --- sound/usb/mixer_scarlett2.c | 96 +++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index ca09d0cd0cae..f1337a379833 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -266,7 +266,8 @@ enum { enum { SCARLETT2_FLASH_WRITE_STATE_IDLE = 0, SCARLETT2_FLASH_WRITE_STATE_SELECTED = 1, - SCARLETT2_FLASH_WRITE_STATE_ERASING = 2 + SCARLETT2_FLASH_WRITE_STATE_ERASING = 2, + SCARLETT2_FLASH_WRITE_STATE_WRITE = 3 }; static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = { @@ -1176,6 +1177,7 @@ static int scarlett2_get_port_start_num( #define SCARLETT2_USB_METER_LEVELS_GET_MAGIC 1 #define SCARLETT2_FLASH_BLOCK_SIZE 4096 +#define SCARLETT2_FLASH_WRITE_MAX 1024 #define SCARLETT2_SEGMENT_NUM_MIN 1 #define SCARLETT2_SEGMENT_NUM_MAX 4 @@ -5079,10 +5081,10 @@ static int scarlett2_ioctl_get_erase_progress( return -EFAULT; /* If the erase is complete, change the state from ERASING to - * IDLE. + * WRITE. */ if (progress.progress == 0xff) - private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_IDLE; + private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_WRITE; return 0; } @@ -5135,6 +5137,93 @@ static int scarlett2_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, } } +static long scarlett2_hwdep_write(struct snd_hwdep *hw, + const char __user *buf, + long count, loff_t *offset) +{ + struct usb_mixer_interface *mixer = hw->private_data; + struct scarlett2_data *private = mixer->private_data; + int segment_id, segment_num, err, len; + int flash_size; + + /* SCARLETT2_USB_WRITE_SEGMENT request data */ + struct { + __le32 segment_num; + __le32 offset; + __le32 pad; + u8 data[]; + } __packed *req; + + /* Calculate the maximum permitted in data[] */ + const size_t max_data_size = SCARLETT2_FLASH_WRITE_MAX - + offsetof(typeof(*req), data); + + /* If erasing, wait for it to complete */ + if (private->flash_write_state == + SCARLETT2_FLASH_WRITE_STATE_ERASING) { + err = scarlett2_wait_for_erase(mixer); + if (err < 0) + return err; + private->flash_write_state = SCARLETT2_FLASH_WRITE_STATE_WRITE; + + /* Check that an erase has been done & completed */ + } else if (private->flash_write_state != + SCARLETT2_FLASH_WRITE_STATE_WRITE) { + return -EINVAL; + } + + /* Check that we're writing to the upgrade firmware */ + segment_id = private->selected_flash_segment_id; + if (segment_id != SCARLETT2_SEGMENT_ID_FIRMWARE) + return -EINVAL; + + segment_num = private->flash_segment_nums[segment_id]; + if (segment_num < SCARLETT2_SEGMENT_NUM_MIN || + segment_num > SCARLETT2_SEGMENT_NUM_MAX) + return -EFAULT; + + /* Validate the offset and count */ + flash_size = private->flash_segment_blocks[segment_id] * + SCARLETT2_FLASH_BLOCK_SIZE; + + if (count < 0 || *offset < 0 || *offset + count >= flash_size) + return -EINVAL; + + if (!count) + return 0; + + /* Limit the *req size to SCARLETT2_FLASH_WRITE_MAX */ + if (count > max_data_size) + count = max_data_size; + + /* Create and send the request */ + len = struct_size(req, data, count); + req = kzalloc(len, GFP_KERNEL); + if (!req) + return -ENOMEM; + + req->segment_num = cpu_to_le32(segment_num); + req->offset = cpu_to_le32(*offset); + req->pad = 0; + + if (copy_from_user(req->data, buf, count)) { + err = -EFAULT; + goto error; + } + + err = scarlett2_usb(mixer, SCARLETT2_USB_WRITE_SEGMENT, + req, len, NULL, 0); + if (err < 0) + goto error; + + *offset += count; + +error: + kfree(req); + + return count; +} + static int scarlett2_hwdep_release(struct snd_hwdep *hw, struct file *file) { struct usb_mixer_interface *mixer = hw->private_data; @@ -5164,6 +5253,7 @@ static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer) hw->exclusive = 1; hw->ops.open = scarlett2_hwdep_open; hw->ops.ioctl = scarlett2_hwdep_ioctl; + hw->ops.write = scarlett2_hwdep_write; hw->ops.release = scarlett2_hwdep_release; return 0;