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]
Date:   Thu, 19 Jul 2018 12:22:15 +0100
From:   Jorge Sanjuan <jorge.sanjuan@...ethink.co.uk>
To:     tiwai@...e.de
Cc:     alsa-devel@...a-project.org, linux-kernel@...r.kernel.org
Subject: [PATCH 4/4] ALSA: usb-audio: Add UAC3 Power Domains to suspend/resume

Set the UAC3 Power Domain state for an Audio Streaming interface
to D2 state before suspending the device (usb_driver callback).
This lets the device know there is no intention to use any of the
Units in the Audio Function and that the host is not going to
even listen for wake-up events (interrupts) on the units.

If the usb_driver gets resumed, the state D1 (idle) will be
set.

Signed-off-by: Jorge Sanjuan <jorge.sanjuan@...ethink.co.uk>
---
 sound/usb/card.c |  9 +++++++++
 sound/usb/pcm.c  | 30 ++++++++++++++++++++++++++++++
 sound/usb/pcm.h  |  2 ++
 3 files changed, 41 insertions(+)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index a1ed798a1c6b..9c2a15b805c3 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -808,6 +808,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
 		snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
 	if (!chip->num_suspended_intf++) {
 		list_for_each_entry(as, &chip->pcm_list, list) {
+			snd_usb_pcm_suspend(as);
 			snd_pcm_suspend_all(as->pcm);
 			as->substream[0].need_setup_ep =
 				as->substream[1].need_setup_ep = true;
@@ -824,6 +825,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
 static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
 {
 	struct snd_usb_audio *chip = usb_get_intfdata(intf);
+	struct snd_usb_stream *as;
 	struct usb_mixer_interface *mixer;
 	struct list_head *p;
 	int err = 0;
@@ -834,6 +836,13 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
 		return 0;
 
 	atomic_inc(&chip->active); /* avoid autopm */
+
+	list_for_each_entry(as, &chip->pcm_list, list) {
+		err = snd_usb_pcm_resume(as);
+		if (err < 0)
+			goto err_out;
+	}
+
 	/*
 	 * ALSA leaves material resumption to user space
 	 * we just notify and restart the mixers
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 0ae5f539706d..266f7028d01b 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -729,6 +729,36 @@ static int snd_usb_pcm_change_state(struct snd_usb_substream *subs, int state)
 	return 0;
 }
 
+int snd_usb_pcm_suspend(struct snd_usb_stream *as)
+{
+	int ret;
+
+	ret = snd_usb_pcm_change_state(&as->substream[0], UAC3_PD_STATE_D2);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_usb_pcm_change_state(&as->substream[1], UAC3_PD_STATE_D2);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int snd_usb_pcm_resume(struct snd_usb_stream *as)
+{
+	int ret;
+
+	ret = snd_usb_pcm_change_state(&as->substream[0], UAC3_PD_STATE_D1);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_usb_pcm_change_state(&as->substream[1], UAC3_PD_STATE_D1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
 /*
  * hw_params callback
  *
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h
index f77ec58bf1a1..9833627c1eca 100644
--- a/sound/usb/pcm.h
+++ b/sound/usb/pcm.h
@@ -6,6 +6,8 @@ snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
 				    unsigned int rate);
 
 void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream);
+int snd_usb_pcm_suspend(struct snd_usb_stream *as);
+int snd_usb_pcm_resume(struct snd_usb_stream *as);
 
 int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
 		       struct usb_host_interface *alts,
-- 
2.11.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ