From patchwork Tue Sep 24 13:31:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roxana Nicolescu X-Patchwork-Id: 1988970 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XCglD416Vz1xsN for ; Tue, 24 Sep 2024 23:32:24 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1st5eK-0003o0-1E; Tue, 24 Sep 2024 13:32:16 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1st5eH-0003l0-0I for kernel-team@lists.ubuntu.com; Tue, 24 Sep 2024 13:32:13 +0000 Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id F20553F215 for ; Tue, 24 Sep 2024 13:32:11 +0000 (UTC) Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-718db8e61bfso8326748b3a.0 for ; Tue, 24 Sep 2024 06:32:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727184730; x=1727789530; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8BFF5qt2XQqhUqe7UmHASf7HYsR72n0gRr8Yhhi7Mpg=; b=c3v/elZqDcd2s5V+eAdCmnkWpDopF075rf0foudL0crJRG9jcL0e7/kR4FjvBIWVOQ 3Cq3q5eux+bNICTsRi51j8Wf9SJrHQxUL22JaLaPUwXPKbdQjpf0HqwnvapVerNUWikJ c3RiTeUtUUS8/V6DYBURTLXolPxaiaCtH7B9o41/8EzcX3W/abb2Yk0g770pOGymhplk nQsoQZv0AHut19Nq4KaVvtYdKNZ1MZ9bjLFLJmW/FRsr5qy7gRzHOxaYkxD9YvOuY5E7 qrEy2K3WSBe13JZts8gKTdO9xQE1VOHMfl5kfA7sS5Fs454tiT1JlaGAQIXoXLJXdYSY 9RFw== X-Gm-Message-State: AOJu0YxNEgW0KHOydSqrnnIKdwwpek9X3n4Hn15wjQsqdeWPUQmzLvg/ reU3qaKU9ecX4/7O9KJZbG+rMwdvdvvyp3liLWsQ5rUBWW4SyNtgJvPW1UgOZmtL9/haH5fVIaU b6Z+56755jnM5OXYoAzzViI8ZMJP06pZomt3PCaYqcIwjuOli+25YBXwEyqgzo89VHAWaAgy1SY 1UOLtx9o0wVqAyXUo= X-Received: by 2002:a05:6a21:9216:b0:1cf:506a:cdcc with SMTP id adf61e73a8af0-1d30cb65dedmr23545862637.43.1727184730581; Tue, 24 Sep 2024 06:32:10 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEoHWSDVMv+I001+vuZeK96Mpcu75Q1LXyNz1ztfj4e/A0kmR7o7wSO6s5Lf6bUt36gT+WpJA== X-Received: by 2002:a05:6a21:9216:b0:1cf:506a:cdcc with SMTP id adf61e73a8af0-1d30cb65dedmr23545835637.43.1727184730193; Tue, 24 Sep 2024 06:32:10 -0700 (PDT) Received: from work.lan ([2001:67c:1560:8007::aac:c490]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-71afc85bbbasm1224965b3a.95.2024.09.24.06.32.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Sep 2024 06:32:09 -0700 (PDT) From: Roxana Nicolescu To: kernel-team@lists.ubuntu.com Subject: [SRU][N][PATCH 2/2] ALSA: scarlett2: Implement handling of the ACK notification Date: Tue, 24 Sep 2024 15:31:57 +0200 Message-Id: <20240924133157.15168-3-roxana.nicolescu@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240924133157.15168-1-roxana.nicolescu@canonical.com> References: <20240924133157.15168-1-roxana.nicolescu@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: "Geoffrey D. Bennett" BugLink: https://bugs.launchpad.net/bugs/2076402 After scarlett2_usb() sends a command, it seems that we should wait for an ACK before attempting to read the response. Not doing that didn't seem necessary previously but seems to be causing occasional issues with 4th Gen devices. Signed-off-by: Geoffrey D. Bennett Signed-off-by: Takashi Iwai Message-ID: <452d1263c40fa8eba1cfb24e2055e40a84cbc437.1710264833.git.g@b4.vu> (cherry picked from commit 1b65088958cadab04d5d34a8615e2466b1b48ecb) Signed-off-by: Roxana Nicolescu --- sound/usb/mixer_scarlett2.c | 70 ++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 8390b646c0ae..02c488c80b7e 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -321,6 +321,7 @@ struct scarlett2_notification { void (*func)(struct usb_mixer_interface *mixer); }; +static void scarlett2_notify_ack(struct usb_mixer_interface *mixer); static void scarlett2_notify_sync(struct usb_mixer_interface *mixer); static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer); static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer); @@ -343,7 +344,7 @@ static void scarlett2_notify_pcm_input_switch( /* Arrays of notification callback functions */ static const struct scarlett2_notification scarlett2_notifications[] = { - { 0x00000001, NULL }, /* ack, gets ignored */ + { 0x00000001, scarlett2_notify_ack }, { 0x00000008, scarlett2_notify_sync }, { 0x00200000, scarlett2_notify_dim_mute }, { 0x00400000, scarlett2_notify_monitor }, @@ -353,14 +354,14 @@ static const struct scarlett2_notification scarlett2_notifications[] = { }; static const struct scarlett2_notification scarlett3a_notifications[] = { - { 0x00000001, NULL }, /* ack, gets ignored */ + { 0x00000001, scarlett2_notify_ack }, { 0x00800000, scarlett2_notify_input_other }, { 0x01000000, scarlett2_notify_direct_monitor }, { 0, NULL } }; static const struct scarlett2_notification scarlett4_solo_notifications[] = { - { 0x00000001, NULL }, /* ack, gets ignored */ + { 0x00000001, scarlett2_notify_ack }, { 0x00000008, scarlett2_notify_sync }, { 0x00400000, scarlett2_notify_input_air }, { 0x00800000, scarlett2_notify_direct_monitor }, @@ -371,7 +372,7 @@ static const struct scarlett2_notification scarlett4_solo_notifications[] = { }; static const struct scarlett2_notification scarlett4_2i2_notifications[] = { - { 0x00000001, NULL }, /* ack, gets ignored */ + { 0x00000001, scarlett2_notify_ack }, { 0x00000008, scarlett2_notify_sync }, { 0x00200000, scarlett2_notify_input_safe }, { 0x00400000, scarlett2_notify_autogain }, @@ -387,7 +388,7 @@ static const struct scarlett2_notification scarlett4_2i2_notifications[] = { }; static const struct scarlett2_notification scarlett4_4i4_notifications[] = { - { 0x00000001, NULL }, /* ack, gets ignored */ + { 0x00000001, scarlett2_notify_ack }, { 0x00000008, scarlett2_notify_sync }, { 0x00200000, scarlett2_notify_input_safe }, { 0x00400000, scarlett2_notify_autogain }, @@ -942,7 +943,9 @@ struct scarlett2_device_info { struct scarlett2_data { struct usb_mixer_interface *mixer; struct mutex usb_mutex; /* prevent sending concurrent USB requests */ + struct completion cmd_done; struct mutex data_mutex; /* lock access to this data */ + u8 running; u8 hwdep_in_use; u8 selected_flash_segment_id; u8 flash_write_state; @@ -1960,6 +1963,17 @@ static int scarlett2_usb( goto unlock; } + if (!wait_for_completion_timeout(&private->cmd_done, + msecs_to_jiffies(1000))) { + usb_audio_err( + mixer->chip, + "%s USB request timed out, cmd %x\n", + private->series_name, cmd); + + err = -ETIMEDOUT; + goto unlock; + } + /* send a second message to get the response */ err = scarlett2_usb_rx(dev, private->bInterfaceNumber, @@ -6702,6 +6716,18 @@ static void scarlett2_notify_pcm_input_switch(struct usb_mixer_interface *mixer) scarlett2_notify_mux(mixer); } +/* Handle acknowledgement that a command was received; let + * scarlett2_usb() know that it can proceed + */ +static void scarlett2_notify_ack(struct usb_mixer_interface *mixer) +{ + struct scarlett2_data *private = mixer->private_data; + + /* if running == 0, ignore ACKs */ + if (private->running) + complete(&private->cmd_done); +} + /* Interrupt callback */ static void scarlett2_notify(struct urb *urb) { @@ -6718,6 +6744,12 @@ static void scarlett2_notify(struct urb *urb) data = le32_to_cpu(*(__le32 *)urb->transfer_buffer); + /* Ignore notifications except ACK during initialisation. + * ACK is 0x00000001 on every device. + */ + if (private->running < 2) + data &= 1; + while (data && notifications->mask) { if (data & notifications->mask) { data &= ~notifications->mask; @@ -6738,6 +6770,8 @@ static void scarlett2_notify(struct urb *urb) ustatus != -ESHUTDOWN) { urb->dev = mixer->chip->dev; usb_submit_urb(urb, GFP_ATOMIC); + } else { + complete(&private->cmd_done); } } @@ -6889,6 +6923,8 @@ static int scarlett2_init_notify(struct usb_mixer_interface *mixer) transfer_buffer, private->wMaxPacketSize, scarlett2_notify, mixer, private->bInterval); + init_completion(&private->cmd_done); + return usb_submit_urb(mixer->urb, GFP_KERNEL); } @@ -6911,6 +6947,24 @@ static int scarlett2_usb_init(struct usb_mixer_interface *mixer) if (err < 0) return err; + /* Set up the interrupt polling for notifications. + * When running is: + * 0: all notifications are ignored + * 1: only ACKs are handled + * 2: all notifications are handled + */ + err = scarlett2_init_notify(mixer); + if (err < 0) + return err; + + /* sleep for a moment in case of an outstanding ACK */ + msleep(20); + + /* start handling ACKs, but no other notifications until the + * ALSA controls have been created + */ + private->running = 1; + /* step 1 */ private->scarlett2_seq = 1; err = scarlett2_usb(mixer, SCARLETT2_USB_INIT_1, NULL, 0, NULL, 0); @@ -7308,10 +7362,8 @@ static int snd_scarlett2_controls_create( scarlett2_phantom_update_access(mixer); } - /* Set up the interrupt polling */ - err = scarlett2_init_notify(mixer); - if (err < 0) - return err; + /* Start handling all notifications */ + private->running = 2; return 0; }