lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250810124958.25309-7-ramiserifpersia@gmail.com>
Date: Sun, 10 Aug 2025 14:49:57 +0200
From: Šerif Rami <ramiserifpersia@...il.com>
To: Jaroslav Kysela <perex@...ex.cz>,
	Takashi Iwai <tiwai@...e.com>
Cc: linux-sound@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Šerif Rami <ramiserifpersia@...il.com>
Subject: [PATCH 6/7] ALSA: usb-audio: us144mkii: Add deep sleep and code style alignments

Add a deep sleep vendor command to be sent during suspend, allowing the
device to enter a lower power state.

This commit also includes code style alignments and implements some
leftover suggestions that were missed in previous commits.

Signed-off-by: Šerif Rami <ramiserifpersia@...il.com>
---
 sound/usb/usx2y/us144mkii.c          |  8 ++++
 sound/usb/usx2y/us144mkii.h          |  2 +
 sound/usb/usx2y/us144mkii_controls.c | 70 ++++++++++++++++++++--------
 sound/usb/usx2y/us144mkii_pcm.c      |  5 +-
 4 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/sound/usb/usx2y/us144mkii.c b/sound/usb/usx2y/us144mkii.c
index a225963c50d2..de2abea5c889 100644
--- a/sound/usb/usx2y/us144mkii.c
+++ b/sound/usb/usx2y/us144mkii.c
@@ -322,6 +322,13 @@ static int tascam_suspend(struct usb_interface *intf, pm_message_t message)
 	usb_kill_anchored_urbs(&tascam->midi_in_anchor);
 	usb_kill_anchored_urbs(&tascam->midi_out_anchor);
 
+	dev_info(&intf->dev, "sending deep sleep command\n");
+	int err = usb_control_msg(tascam->dev, usb_sndctrlpipe(tascam->dev, 0),
+				  VENDOR_REQ_DEEP_SLEEP, RT_H2D_VENDOR_DEV,
+				  0x0000, 0x0000, NULL, 0, USB_CTRL_TIMEOUT_MS);
+	if (err < 0)
+		dev_err(&intf->dev, "deep sleep command failed: %d\n", err);
+
 	return 0;
 }
 
@@ -495,6 +502,7 @@ static int tascam_probe(struct usb_interface *intf,
 	INIT_WORK(&tascam->stop_work, tascam_stop_work_handler);
 	INIT_WORK(&tascam->stop_pcm_work, tascam_stop_pcm_work_handler);
 	INIT_WORK(&tascam->capture_work, tascam_capture_work_handler);
+	init_completion(&tascam->midi_out_drain_completion);
 
 	if (kfifo_alloc(&tascam->midi_in_fifo, MIDI_IN_FIFO_SIZE, GFP_KERNEL)) {
 		snd_card_free(card);
diff --git a/sound/usb/usx2y/us144mkii.h b/sound/usb/usx2y/us144mkii.h
index 9b7749764fc8..ecc4c2fed9e6 100644
--- a/sound/usb/usx2y/us144mkii.h
+++ b/sound/usb/usx2y/us144mkii.h
@@ -46,6 +46,7 @@ enum uac_control_selector {
 
 enum tascam_vendor_request {
 	VENDOR_REQ_REGISTER_WRITE = 0x41,
+	VENDOR_REQ_DEEP_SLEEP = 0x44,
 	VENDOR_REQ_MODE_CONTROL = 0x49,
 };
 
@@ -261,6 +262,7 @@ struct tascam_card {
 	unsigned long midi_out_urbs_in_flight;
 	u8 midi_running_status;
 	struct timer_list error_timer;
+	struct completion midi_out_drain_completion;
 
 	/* --- Feedback Sync State --- */
 	unsigned int feedback_accumulator_pattern[FEEDBACK_ACCUMULATOR_SIZE];
diff --git a/sound/usb/usx2y/us144mkii_controls.c b/sound/usb/usx2y/us144mkii_controls.c
index 4262b7f45139..bbc8da5c8e8d 100644
--- a/sound/usb/usx2y/us144mkii_controls.c
+++ b/sound/usb/usx2y/us144mkii_controls.c
@@ -53,8 +53,11 @@ static int tascam_line_out_get(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+	int val;
 
-	ucontrol->value.enumerated.item[0] = tascam->line_out_source;
+	guard(spinlock_irqsave)(&tascam->lock);
+	val = tascam->line_out_source;
+	ucontrol->value.enumerated.item[0] = val;
 	return 0;
 }
 
@@ -73,13 +76,17 @@ static int tascam_line_out_put(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
 
 	if (ucontrol->value.enumerated.item[0] > 1)
 		return -EINVAL;
-	if (tascam->line_out_source == ucontrol->value.enumerated.item[0])
-		return 0;
-	tascam->line_out_source = ucontrol->value.enumerated.item[0];
-	return 1;
+
+	guard(spinlock_irqsave)(&tascam->lock);
+	if (tascam->line_out_source != ucontrol->value.enumerated.item[0]) {
+		tascam->line_out_source = ucontrol->value.enumerated.item[0];
+		changed = 1;
+	}
+	return changed;
 }
 
 /**
@@ -115,8 +122,11 @@ static int tascam_digital_out_get(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
 	struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+	int val;
 
-	ucontrol->value.enumerated.item[0] = tascam->digital_out_source;
+	guard(spinlock_irqsave)(&tascam->lock);
+	val = tascam->digital_out_source;
+	ucontrol->value.enumerated.item[0] = val;
 	return 0;
 }
 
@@ -136,13 +146,17 @@ static int tascam_digital_out_put(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_value *ucontrol)
 {
 	struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
 
 	if (ucontrol->value.enumerated.item[0] > 1)
 		return -EINVAL;
-	if (tascam->digital_out_source == ucontrol->value.enumerated.item[0])
-		return 0;
-	tascam->digital_out_source = ucontrol->value.enumerated.item[0];
-	return 1;
+
+	guard(spinlock_irqsave)(&tascam->lock);
+	if (tascam->digital_out_source != ucontrol->value.enumerated.item[0]) {
+		tascam->digital_out_source = ucontrol->value.enumerated.item[0];
+		changed = 1;
+	}
+	return changed;
 }
 
 /**
@@ -196,8 +210,11 @@ static int tascam_capture_12_get(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+	int val;
 
-	ucontrol->value.enumerated.item[0] = tascam->capture_12_source;
+	guard(spinlock_irqsave)(&tascam->lock);
+	val = tascam->capture_12_source;
+	ucontrol->value.enumerated.item[0] = val;
 	return 0;
 }
 
@@ -217,13 +234,17 @@ static int tascam_capture_12_put(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
 
 	if (ucontrol->value.enumerated.item[0] > 1)
 		return -EINVAL;
-	if (tascam->capture_12_source == ucontrol->value.enumerated.item[0])
-		return 0;
-	tascam->capture_12_source = ucontrol->value.enumerated.item[0];
-	return 1;
+
+	guard(spinlock_irqsave)(&tascam->lock);
+	if (tascam->capture_12_source != ucontrol->value.enumerated.item[0]) {
+		tascam->capture_12_source = ucontrol->value.enumerated.item[0];
+		changed = 1;
+	}
+	return changed;
 }
 
 /**
@@ -260,8 +281,11 @@ static int tascam_capture_34_get(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+	int val;
 
-	ucontrol->value.enumerated.item[0] = tascam->capture_34_source;
+	guard(spinlock_irqsave)(&tascam->lock);
+	val = tascam->capture_34_source;
+	ucontrol->value.enumerated.item[0] = val;
 	return 0;
 }
 
@@ -281,13 +305,17 @@ static int tascam_capture_34_put(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct tascam_card *tascam = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
 
 	if (ucontrol->value.enumerated.item[0] > 1)
 		return -EINVAL;
-	if (tascam->capture_34_source == ucontrol->value.enumerated.item[0])
-		return 0;
-	tascam->capture_34_source = ucontrol->value.enumerated.item[0];
-	return 1;
+
+	guard(spinlock_irqsave)(&tascam->lock);
+	if (tascam->capture_34_source != ucontrol->value.enumerated.item[0]) {
+		tascam->capture_34_source = ucontrol->value.enumerated.item[0];
+		changed = 1;
+	}
+	return changed;
 }
 
 /**
@@ -349,10 +377,12 @@ static int tascam_samplerate_get(struct snd_kcontrol *kcontrol,
 	int err;
 	u32 rate = 0;
 
+	guard(spinlock_irqsave)(&tascam->lock);
 	if (tascam->current_rate > 0) {
 		ucontrol->value.integer.value[0] = tascam->current_rate;
 		return 0;
 	}
+	// Lock is released here before kmalloc and usb_control_msg
 
 	buf = kmalloc(3, GFP_KERNEL);
 	if (!buf)
diff --git a/sound/usb/usx2y/us144mkii_pcm.c b/sound/usb/usx2y/us144mkii_pcm.c
index 953d5e7a7235..5a066ce0dbd8 100644
--- a/sound/usb/usx2y/us144mkii_pcm.c
+++ b/sound/usb/usx2y/us144mkii_pcm.c
@@ -115,11 +115,12 @@ void process_capture_routing_us144mkii(struct tascam_card *tascam,
 int us144mkii_configure_device_for_rate(struct tascam_card *tascam, int rate)
 {
 	struct usb_device *dev = tascam->dev;
-	u8 *rate_payload_buf;
 	u16 rate_vendor_wValue;
 	int err = 0;
 	const u8 *current_payload_src;
 
+	u8 *rate_payload_buf __free(kfree);
+
 	static const u8 payload_44100[] = { 0x44, 0xac, 0x00 };
 	static const u8 payload_48000[] = { 0x80, 0xbb, 0x00 };
 	static const u8 payload_88200[] = { 0x88, 0x58, 0x01 };
@@ -209,14 +210,12 @@ int us144mkii_configure_device_for_rate(struct tascam_card *tascam, int rate)
 	if (err < 0)
 		goto fail;
 
-	kfree(rate_payload_buf);
 	return 0;
 
 fail:
 	dev_err(&dev->dev,
 		"Device configuration failed at rate %d with error %d\n", rate,
 		err);
-	kfree(rate_payload_buf);
 	return err;
 }
 
-- 
2.39.5


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ