On Mon, Dec 17, 2018 at 12:33:49PM +0100, Christian Gromm wrote:
> +static void release_adapter(struct sound_adapter *adpt)
> +{
> +     struct channel *channel, *tmp;
> +
> +     list_for_each_entry_safe(channel, tmp, &adpt->dev_list, list) {
> +             list_del(&channel->list);
> +             kfree(channel);
> +     }
> +     snd_card_free(adpt->card);

I'm sorry for drawing this out.  I should have seen this problem in the
v2 patch.  snd_card_free() does not take NULL pointers.  We need to
say:

        if (adpt->card)
                snd_card_free(adpt->card);

> +     list_del(&adpt->list);
> +     kfree(adpt);
> +}
> +
>  /**
>   * audio_probe_channel - probe function of the driver module
>   * @iface: pointer to interface instance
> @@ -553,7 +581,7 @@ static int audio_probe_channel(struct most_interface 
> *iface, int channel_id,
>                              char *arg_list)
>  {
>       struct channel *channel;
> -     struct snd_card *card;
> +     struct sound_adapter *adpt;
>       struct snd_pcm *pcm;
>       int playback_count = 0;
>       int capture_count = 0;
> @@ -561,6 +589,7 @@ static int audio_probe_channel(struct most_interface 
> *iface, int channel_id,
>       int direction;
>       char *card_name;
>       u16 ch_num;
> +     u8 create = 0;
>       char *sample_res;
>  
>       if (!iface)
> @@ -571,6 +600,39 @@ static int audio_probe_channel(struct most_interface 
> *iface, int channel_id,
>               return -EINVAL;
>       }
>  
> +     ret = split_arg_list(arg_list, &card_name, &ch_num, &sample_res,
> +                          &create);
> +     if (ret < 0)
> +             return ret;
> +
> +     list_for_each_entry(adpt, &adpt_list, list) {
> +             if (adpt->iface != iface)
> +                     continue;
> +             if (adpt->registered)
> +                     return -ENOSPC;
> +             adpt->pcm_dev_idx++;
> +             goto skip_adpt_alloc;
> +     }
> +     adpt = kzalloc(sizeof(*adpt), GFP_KERNEL);
> +     if (!adpt)
> +             return -ENOMEM;
> +
> +     adpt->iface = iface;
> +     INIT_LIST_HEAD(&adpt->dev_list);
> +     iface->priv = adpt;
> +     list_add_tail(&adpt->list, &adpt_list);
> +     ret = snd_card_new(&iface->dev, -1, card_name, THIS_MODULE,
> +                        sizeof(*channel), &adpt->card);
> +     if (ret < 0)
> +             goto err_free_card;

Otherwise this error path will oops.

[ Snip ]

>  err_free_card:
> -     snd_card_free(card);
> +     release_adapter(adpt);
>       return ret;
>  }

I feel quite bad for making you redo this over and over.  :(

regards,
dan carpenter
_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to