4242#endif
4343
4444struct snd_compr_file {
45+ struct list_head list ;
4546 unsigned long caps ;
4647 struct snd_compr_stream stream ;
4748};
@@ -117,6 +118,7 @@ static int snd_compr_open(struct inode *inode, struct file *f)
117118 ret = - ENOMEM ;
118119 goto __error ;
119120 }
121+ INIT_LIST_HEAD (& data -> list );
120122
121123 INIT_DELAYED_WORK (& data -> stream .error_work , error_delayed_work );
122124
@@ -136,8 +138,11 @@ static int snd_compr_open(struct inode *inode, struct file *f)
136138#endif
137139 data -> stream .runtime = runtime ;
138140 f -> private_data = (void * )data ;
139- scoped_guard (mutex , & compr -> lock )
141+ scoped_guard (mutex , & compr -> lock ) {
140142 ret = compr -> ops -> open (& data -> stream );
143+ if (!ret )
144+ list_add_tail (& data -> list , & compr -> open_list );
145+ }
141146
142147__error :
143148 if (ret ) {
@@ -153,17 +158,23 @@ static int snd_compr_free(struct inode *inode, struct file *f)
153158{
154159 struct snd_compr_file * data = f -> private_data ;
155160 struct snd_compr_runtime * runtime = data -> stream .runtime ;
161+ struct snd_compr * compr = data -> stream .device ;
156162
157163 cancel_delayed_work_sync (& data -> stream .error_work );
158164
159- switch (runtime -> state ) {
160- case SNDRV_PCM_STATE_RUNNING :
161- case SNDRV_PCM_STATE_DRAINING :
162- case SNDRV_PCM_STATE_PAUSED :
163- data -> stream .ops -> trigger (& data -> stream , SNDRV_PCM_TRIGGER_STOP );
164- break ;
165- default :
166- break ;
165+ scoped_guard (mutex , & compr -> lock ) {
166+ if (!list_empty (& data -> list ))
167+ list_del_init (& data -> list );
168+
169+ switch (runtime -> state ) {
170+ case SNDRV_PCM_STATE_RUNNING :
171+ case SNDRV_PCM_STATE_DRAINING :
172+ case SNDRV_PCM_STATE_PAUSED :
173+ data -> stream .ops -> trigger (& data -> stream , SNDRV_PCM_TRIGGER_STOP );
174+ break ;
175+ default :
176+ break ;
177+ }
167178 }
168179
169180 snd_compr_task_free_all (& data -> stream );
@@ -1440,8 +1451,27 @@ static int snd_compress_dev_register(struct snd_device *device)
14401451static int snd_compress_dev_disconnect (struct snd_device * device )
14411452{
14421453 struct snd_compr * compr ;
1454+ struct snd_compr_file * data ;
14431455
14441456 compr = device -> device_data ;
1457+ scoped_guard (mutex , & compr -> lock ) {
1458+ list_for_each_entry (data , & compr -> open_list , list ) {
1459+ switch (data -> stream .runtime -> state ) {
1460+ case SNDRV_PCM_STATE_RUNNING :
1461+ case SNDRV_PCM_STATE_DRAINING :
1462+ case SNDRV_PCM_STATE_PAUSED :
1463+ data -> stream .ops -> trigger (& data -> stream ,
1464+ SNDRV_PCM_TRIGGER_STOP );
1465+ break ;
1466+ default :
1467+ break ;
1468+ }
1469+
1470+ data -> stream .runtime -> state = SNDRV_PCM_STATE_DISCONNECTED ;
1471+ wake_up (& data -> stream .runtime -> sleep );
1472+ }
1473+ }
1474+
14451475 snd_unregister_device (compr -> dev );
14461476 return 0 ;
14471477}
@@ -1549,6 +1579,7 @@ int snd_compress_new(struct snd_card *card, int device,
15491579 compr -> device = device ;
15501580 compr -> direction = dirn ;
15511581 mutex_init (& compr -> lock );
1582+ INIT_LIST_HEAD (& compr -> open_list );
15521583
15531584 snd_compress_set_id (compr , id );
15541585
0 commit comments