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 devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel