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

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

 



On Mon, Nov 21, 2011 at 1:07 PM, Oliver Neukum <oneukum@xxxxxxx> wrote:
> 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
>
>

Ok , i checked above patch and with this  audio modules donot get unbind now .
i am using usb device ( ipod ) as capture only device for usb audio streaming .
will the above patch also cease i/o related to usb capture  in pre
reset functionality
and restore it in post reset ?

Also , i have not test the case with the above patch when usb audio
streaming (capture ) is in progress
and a usb reset is issued .

Thanx & Regards
Amit Nagal
--
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