Re: regarding usb reset of an interface while probe is happening

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am Montag, 21. November 2011, 05:53:15 schrieb Amit Nagal:

> Thank you for sharing very useful insights .
> Actually in my embedded target , usb audio modules after probe is
> finished , gets unbind .
> when i investigated , the reason is usb reset .
> i am  debugging now to know whether  this usb reset has come from
> userspace or from some other driver .

Well, that is not productive. The reset may be issued for a perfectly
valid reason and be necessary. It would be far better if the audio driver
handled a reset correctly. Could you test this patch?

	Regards
		Oliver

>From 4bf7335b3fb573846f8662ed5050fee8502d5da5 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oliver@xxxxxxxxxx>
Date: Mon, 21 Nov 2011 08:31:23 +0100
Subject: [PATCH] usb-audio: Add reset handler

This is needed on system which share audio interfaces and other
interfaces whose drivers use reset in error handling.

Signed-off-by: Oliver Neukum <oneukum@xxxxxxx>
---
 sound/usb/card.c |   62 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index 0f6dc0d..f38efc0 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -604,6 +604,21 @@ static void usb_audio_disconnect(struct usb_interface *intf)
 				 usb_get_intfdata(intf));
 }
 
+static void suspend_interfaces(struct snd_usb_audio *chip)
+{
+	struct list_head *p;
+	struct snd_usb_stream *as;
+
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
+	if (!chip->num_suspended_intf++) {
+		list_for_each(p, &chip->pcm_list) {
+			as = list_entry(p, struct snd_usb_stream, list);
+			snd_pcm_suspend_all(as->pcm);
+		}
+ 	}
+}
+
+
 #ifdef CONFIG_PM
 
 int snd_usb_autoresume(struct snd_usb_audio *chip)
@@ -625,21 +640,13 @@ void snd_usb_autosuspend(struct snd_usb_audio *chip)
 static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct snd_usb_audio *chip = usb_get_intfdata(intf);
-	struct list_head *p;
-	struct snd_usb_stream *as;
 	struct usb_mixer_interface *mixer;
 
 	if (chip == (void *)-1L)
 		return 0;
 
 	if (!PMSG_IS_AUTO(message)) {
-		snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
-		if (!chip->num_suspended_intf++) {
-			list_for_each(p, &chip->pcm_list) {
-				as = list_entry(p, struct snd_usb_stream, list);
-				snd_pcm_suspend_all(as->pcm);
-			}
- 		}
+		suspend_interfaces(chip);
 	} else {
 		/*
 		 * otherwise we keep the rest of the system in the dark
@@ -695,6 +702,41 @@ static struct usb_device_id usb_audio_ids [] = {
     { }						/* Terminating entry */
 };
 
+static int usb_audo_pre_reset(struct usb_interface *intf)
+{
+	struct snd_usb_audio *chip = usb_get_intfdata(intf);
+	struct usb_mixer_interface *mixer;
+
+	if (chip == (void *)-1L)
+		return 0;
+
+	list_for_each_entry(mixer, &chip->mixer_list, list)
+		snd_usb_mixer_inactivate(mixer);
+	return 0;
+}
+
+static int usb_audio_post_reset(struct usb_interface *intf)
+{
+	struct snd_usb_audio *chip = usb_get_intfdata(intf);
+	struct usb_mixer_interface *mixer;
+	int err;
+
+	if (chip == (void *)-1L)
+		return 0;
+
+	list_for_each_entry(mixer, &chip->mixer_list, list) {
+		err = snd_usb_mixer_activate(mixer);
+		if (err < 0)
+			goto err_out;
+	}
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
+
+	return 0;
+
+err_out:
+	return -EIO;
+}
+
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 /*
@@ -707,6 +749,8 @@ static struct usb_driver usb_audio_driver = {
 	.disconnect =	usb_audio_disconnect,
 	.suspend =	usb_audio_suspend,
 	.resume =	usb_audio_resume,
+	.pre_reset =	usb_audo_pre_reset,
+	.post_reset =	usb_audio_post_reset,
 	.id_table =	usb_audio_ids,
 	.supports_autosuspend = 1,
 };
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux