@@ -180,7 +180,7 @@ static void snd_timer_request(struct snd_timer_id *tid)
180
180
*
181
181
* call this with register_mutex down.
182
182
*/
183
- static void snd_timer_check_slave (struct snd_timer_instance * slave )
183
+ static int snd_timer_check_slave (struct snd_timer_instance * slave )
184
184
{
185
185
struct snd_timer * timer ;
186
186
struct snd_timer_instance * master ;
@@ -190,16 +190,21 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
190
190
list_for_each_entry (master , & timer -> open_list_head , open_list ) {
191
191
if (slave -> slave_class == master -> slave_class &&
192
192
slave -> slave_id == master -> slave_id ) {
193
+ if (master -> timer -> num_instances >=
194
+ master -> timer -> max_instances )
195
+ return - EBUSY ;
193
196
list_move_tail (& slave -> open_list ,
194
197
& master -> slave_list_head );
198
+ master -> timer -> num_instances ++ ;
195
199
spin_lock_irq (& slave_active_lock );
196
200
slave -> master = master ;
197
201
slave -> timer = master -> timer ;
198
202
spin_unlock_irq (& slave_active_lock );
199
- return ;
203
+ return 0 ;
200
204
}
201
205
}
202
206
}
207
+ return 0 ;
203
208
}
204
209
205
210
/*
@@ -208,15 +213,19 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
208
213
*
209
214
* call this with register_mutex down.
210
215
*/
211
- static void snd_timer_check_master (struct snd_timer_instance * master )
216
+ static int snd_timer_check_master (struct snd_timer_instance * master )
212
217
{
213
218
struct snd_timer_instance * slave , * tmp ;
214
219
215
220
/* check all pending slaves */
216
221
list_for_each_entry_safe (slave , tmp , & snd_timer_slave_list , open_list ) {
217
222
if (slave -> slave_class == master -> slave_class &&
218
223
slave -> slave_id == master -> slave_id ) {
224
+ if (master -> timer -> num_instances >=
225
+ master -> timer -> max_instances )
226
+ return - EBUSY ;
219
227
list_move_tail (& slave -> open_list , & master -> slave_list_head );
228
+ master -> timer -> num_instances ++ ;
220
229
spin_lock_irq (& slave_active_lock );
221
230
spin_lock (& master -> timer -> lock );
222
231
slave -> master = master ;
@@ -228,8 +237,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
228
237
spin_unlock_irq (& slave_active_lock );
229
238
}
230
239
}
240
+ return 0 ;
231
241
}
232
242
243
+ static int snd_timer_close_locked (struct snd_timer_instance * timeri );
244
+
233
245
/*
234
246
* open a timer instance
235
247
* when opening a master, the slave id must be here given.
@@ -240,6 +252,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
240
252
{
241
253
struct snd_timer * timer ;
242
254
struct snd_timer_instance * timeri = NULL ;
255
+ int err ;
243
256
244
257
if (tid -> dev_class == SNDRV_TIMER_CLASS_SLAVE ) {
245
258
/* open a slave instance */
@@ -259,10 +272,14 @@ int snd_timer_open(struct snd_timer_instance **ti,
259
272
timeri -> slave_id = tid -> device ;
260
273
timeri -> flags |= SNDRV_TIMER_IFLG_SLAVE ;
261
274
list_add_tail (& timeri -> open_list , & snd_timer_slave_list );
262
- snd_timer_check_slave (timeri );
275
+ err = snd_timer_check_slave (timeri );
276
+ if (err < 0 ) {
277
+ snd_timer_close_locked (timeri );
278
+ timeri = NULL ;
279
+ }
263
280
mutex_unlock (& register_mutex );
264
281
* ti = timeri ;
265
- return 0 ;
282
+ return err ;
266
283
}
267
284
268
285
/* open a master instance */
@@ -288,6 +305,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
288
305
return - EBUSY ;
289
306
}
290
307
}
308
+ if (timer -> num_instances >= timer -> max_instances ) {
309
+ mutex_unlock (& register_mutex );
310
+ return - EBUSY ;
311
+ }
291
312
timeri = snd_timer_instance_new (owner , timer );
292
313
if (!timeri ) {
293
314
mutex_unlock (& register_mutex );
@@ -314,32 +335,35 @@ int snd_timer_open(struct snd_timer_instance **ti,
314
335
}
315
336
316
337
list_add_tail (& timeri -> open_list , & timer -> open_list_head );
317
- snd_timer_check_master (timeri );
338
+ timer -> num_instances ++ ;
339
+ err = snd_timer_check_master (timeri );
340
+ if (err < 0 ) {
341
+ snd_timer_close_locked (timeri );
342
+ timeri = NULL ;
343
+ }
318
344
mutex_unlock (& register_mutex );
319
345
* ti = timeri ;
320
- return 0 ;
346
+ return err ;
321
347
}
322
348
EXPORT_SYMBOL (snd_timer_open );
323
349
324
350
/*
325
351
* close a timer instance
352
+ * call this with register_mutex down.
326
353
*/
327
- int snd_timer_close (struct snd_timer_instance * timeri )
354
+ static int snd_timer_close_locked (struct snd_timer_instance * timeri )
328
355
{
329
356
struct snd_timer * timer = NULL ;
330
357
struct snd_timer_instance * slave , * tmp ;
331
358
332
- if (snd_BUG_ON (!timeri ))
333
- return - ENXIO ;
334
-
335
- mutex_lock (& register_mutex );
336
359
list_del (& timeri -> open_list );
337
360
338
361
/* force to stop the timer */
339
362
snd_timer_stop (timeri );
340
363
341
364
timer = timeri -> timer ;
342
365
if (timer ) {
366
+ timer -> num_instances -- ;
343
367
/* wait, until the active callback is finished */
344
368
spin_lock_irq (& timer -> lock );
345
369
while (timeri -> flags & SNDRV_TIMER_IFLG_CALLBACK ) {
@@ -355,6 +379,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
355
379
list_for_each_entry_safe (slave , tmp , & timeri -> slave_list_head ,
356
380
open_list ) {
357
381
list_move_tail (& slave -> open_list , & snd_timer_slave_list );
382
+ timer -> num_instances -- ;
358
383
slave -> master = NULL ;
359
384
slave -> timer = NULL ;
360
385
list_del_init (& slave -> ack_list );
@@ -382,9 +407,24 @@ int snd_timer_close(struct snd_timer_instance *timeri)
382
407
module_put (timer -> module );
383
408
}
384
409
385
- mutex_unlock (& register_mutex );
386
410
return 0 ;
387
411
}
412
+
413
+ /*
414
+ * close a timer instance
415
+ */
416
+ int snd_timer_close (struct snd_timer_instance * timeri )
417
+ {
418
+ int err ;
419
+
420
+ if (snd_BUG_ON (!timeri ))
421
+ return - ENXIO ;
422
+
423
+ mutex_lock (& register_mutex );
424
+ err = snd_timer_close_locked (timeri );
425
+ mutex_unlock (& register_mutex );
426
+ return err ;
427
+ }
388
428
EXPORT_SYMBOL (snd_timer_close );
389
429
390
430
unsigned long snd_timer_resolution (struct snd_timer_instance * timeri )
@@ -856,6 +896,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
856
896
spin_lock_init (& timer -> lock );
857
897
tasklet_init (& timer -> task_queue , snd_timer_tasklet ,
858
898
(unsigned long )timer );
899
+ timer -> max_instances = 1000 ; /* default limit per timer */
859
900
if (card != NULL ) {
860
901
timer -> module = card -> module ;
861
902
err = snd_device_new (card , SNDRV_DEV_TIMER , timer , & ops );
0 commit comments