ALSA: core: Assure control device to be registered at last
The commit289ca025ee
("ALSA: Use priority list for managing device list") changed the way to register/disconnect/free devices via a single priority list. This helped to make behavior consistent, but it also changed a slight behavior change: namely, the control device is registered earlier than others, while it was supposed to be the very last one. I've put SNDRV_DEV_CONTROL in the current position as the release of ctl elements often conflict with the private ctl elements some PCM or other components may create, which often leads to a double-free. But, the order of register and disconnect should be indeed fixed as expected in the early days: the control device gets registered at last, and disconnected at first. This patch changes the priority list order to move SNDRV_DEV_CONTROL as the last guy to assure the register / disconnect order. Meanwhile, for keeping the messy resource release order, manually treat the control and lowlevel devices as last freed one. Additional note: The lowlevel device is the device where a card driver creates at probe. And, we still keep the release order control -> lowlevel, as there might be link from a control element back to a lowlevel object. Fixes:289ca025ee
("ALSA: Use priority list for managing device list") Reported-by: Tzung-Bi Shih <tzungbi@google.com> Tested-by: Tzung-Bi Shih <tzungbi@google.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
377a879d98
commit
dc82e52492
@ -51,7 +51,6 @@ struct completion;
|
||||
*/
|
||||
enum snd_device_type {
|
||||
SNDRV_DEV_LOWLEVEL,
|
||||
SNDRV_DEV_CONTROL,
|
||||
SNDRV_DEV_INFO,
|
||||
SNDRV_DEV_BUS,
|
||||
SNDRV_DEV_CODEC,
|
||||
@ -62,6 +61,7 @@ enum snd_device_type {
|
||||
SNDRV_DEV_SEQUENCER,
|
||||
SNDRV_DEV_HWDEP,
|
||||
SNDRV_DEV_JACK,
|
||||
SNDRV_DEV_CONTROL, /* NOTE: this must be the last one */
|
||||
};
|
||||
|
||||
enum snd_device_state {
|
||||
|
@ -240,6 +240,15 @@ void snd_device_free_all(struct snd_card *card)
|
||||
|
||||
if (snd_BUG_ON(!card))
|
||||
return;
|
||||
list_for_each_entry_safe_reverse(dev, next, &card->devices, list) {
|
||||
/* exception: free ctl and lowlevel stuff later */
|
||||
if (dev->type == SNDRV_DEV_CONTROL ||
|
||||
dev->type == SNDRV_DEV_LOWLEVEL)
|
||||
continue;
|
||||
__snd_device_free(dev);
|
||||
}
|
||||
|
||||
/* free all */
|
||||
list_for_each_entry_safe_reverse(dev, next, &card->devices, list)
|
||||
__snd_device_free(dev);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user