diff options
Diffstat (limited to 'sound/core/timer.c')
-rw-r--r-- | sound/core/timer.c | 380 |
1 files changed, 222 insertions, 158 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c index 22b104624084..1b90a38d10ff 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); | |||
55 | 55 | ||
56 | typedef struct { | 56 | typedef struct { |
57 | snd_timer_instance_t *timeri; | 57 | snd_timer_instance_t *timeri; |
58 | int tread; /* enhanced read with timestamps and events */ | 58 | int tread; /* enhanced read with timestamps and events */ |
59 | unsigned long ticks; | 59 | unsigned long ticks; |
60 | unsigned long overrun; | 60 | unsigned long overrun; |
61 | int qhead; | 61 | int qhead; |
@@ -95,7 +95,8 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left); | |||
95 | * create a timer instance with the given owner string. | 95 | * create a timer instance with the given owner string. |
96 | * when timer is not NULL, increments the module counter | 96 | * when timer is not NULL, increments the module counter |
97 | */ | 97 | */ |
98 | static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer) | 98 | static snd_timer_instance_t *snd_timer_instance_new(char *owner, |
99 | snd_timer_t *timer) | ||
99 | { | 100 | { |
100 | snd_timer_instance_t *timeri; | 101 | snd_timer_instance_t *timeri; |
101 | timeri = kzalloc(sizeof(*timeri), GFP_KERNEL); | 102 | timeri = kzalloc(sizeof(*timeri), GFP_KERNEL); |
@@ -113,7 +114,7 @@ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *ti | |||
113 | INIT_LIST_HEAD(&timeri->slave_active_head); | 114 | INIT_LIST_HEAD(&timeri->slave_active_head); |
114 | 115 | ||
115 | timeri->timer = timer; | 116 | timeri->timer = timer; |
116 | if (timer && timer->card && !try_module_get(timer->card->module)) { | 117 | if (timer && !try_module_get(timer->module)) { |
117 | kfree(timeri->owner); | 118 | kfree(timeri->owner); |
118 | kfree(timeri); | 119 | kfree(timeri); |
119 | return NULL; | 120 | return NULL; |
@@ -131,7 +132,7 @@ static snd_timer_t *snd_timer_find(snd_timer_id_t *tid) | |||
131 | struct list_head *p; | 132 | struct list_head *p; |
132 | 133 | ||
133 | list_for_each(p, &snd_timer_list) { | 134 | list_for_each(p, &snd_timer_list) { |
134 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 135 | timer = list_entry(p, snd_timer_t, device_list); |
135 | 136 | ||
136 | if (timer->tmr_class != tid->dev_class) | 137 | if (timer->tmr_class != tid->dev_class) |
137 | continue; | 138 | continue; |
@@ -186,13 +187,14 @@ static void snd_timer_check_slave(snd_timer_instance_t *slave) | |||
186 | 187 | ||
187 | /* FIXME: it's really dumb to look up all entries.. */ | 188 | /* FIXME: it's really dumb to look up all entries.. */ |
188 | list_for_each(p, &snd_timer_list) { | 189 | list_for_each(p, &snd_timer_list) { |
189 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 190 | timer = list_entry(p, snd_timer_t, device_list); |
190 | list_for_each(q, &timer->open_list_head) { | 191 | list_for_each(q, &timer->open_list_head) { |
191 | master = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list); | 192 | master = list_entry(q, snd_timer_instance_t, open_list); |
192 | if (slave->slave_class == master->slave_class && | 193 | if (slave->slave_class == master->slave_class && |
193 | slave->slave_id == master->slave_id) { | 194 | slave->slave_id == master->slave_id) { |
194 | list_del(&slave->open_list); | 195 | list_del(&slave->open_list); |
195 | list_add_tail(&slave->open_list, &master->slave_list_head); | 196 | list_add_tail(&slave->open_list, |
197 | &master->slave_list_head); | ||
196 | spin_lock_irq(&slave_active_lock); | 198 | spin_lock_irq(&slave_active_lock); |
197 | slave->master = master; | 199 | slave->master = master; |
198 | slave->timer = master->timer; | 200 | slave->timer = master->timer; |
@@ -216,7 +218,7 @@ static void snd_timer_check_master(snd_timer_instance_t *master) | |||
216 | 218 | ||
217 | /* check all pending slaves */ | 219 | /* check all pending slaves */ |
218 | list_for_each_safe(p, n, &snd_timer_slave_list) { | 220 | list_for_each_safe(p, n, &snd_timer_slave_list) { |
219 | slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); | 221 | slave = list_entry(p, snd_timer_instance_t, open_list); |
220 | if (slave->slave_class == master->slave_class && | 222 | if (slave->slave_class == master->slave_class && |
221 | slave->slave_id == master->slave_id) { | 223 | slave->slave_id == master->slave_id) { |
222 | list_del(p); | 224 | list_del(p); |
@@ -225,7 +227,8 @@ static void snd_timer_check_master(snd_timer_instance_t *master) | |||
225 | slave->master = master; | 227 | slave->master = master; |
226 | slave->timer = master->timer; | 228 | slave->timer = master->timer; |
227 | if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) | 229 | if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) |
228 | list_add_tail(&slave->active_list, &master->slave_active_head); | 230 | list_add_tail(&slave->active_list, |
231 | &master->slave_active_head); | ||
229 | spin_unlock_irq(&slave_active_lock); | 232 | spin_unlock_irq(&slave_active_lock); |
230 | } | 233 | } |
231 | } | 234 | } |
@@ -241,7 +244,7 @@ int snd_timer_open(snd_timer_instance_t **ti, | |||
241 | { | 244 | { |
242 | snd_timer_t *timer; | 245 | snd_timer_t *timer; |
243 | snd_timer_instance_t *timeri = NULL; | 246 | snd_timer_instance_t *timeri = NULL; |
244 | 247 | ||
245 | if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { | 248 | if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { |
246 | /* open a slave instance */ | 249 | /* open a slave instance */ |
247 | if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE || | 250 | if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE || |
@@ -251,6 +254,10 @@ int snd_timer_open(snd_timer_instance_t **ti, | |||
251 | } | 254 | } |
252 | down(®ister_mutex); | 255 | down(®ister_mutex); |
253 | timeri = snd_timer_instance_new(owner, NULL); | 256 | timeri = snd_timer_instance_new(owner, NULL); |
257 | if (!timeri) { | ||
258 | up(®ister_mutex); | ||
259 | return -ENOMEM; | ||
260 | } | ||
254 | timeri->slave_class = tid->dev_sclass; | 261 | timeri->slave_class = tid->dev_sclass; |
255 | timeri->slave_id = tid->device; | 262 | timeri->slave_id = tid->device; |
256 | timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; | 263 | timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; |
@@ -272,33 +279,36 @@ int snd_timer_open(snd_timer_instance_t **ti, | |||
272 | timer = snd_timer_find(tid); | 279 | timer = snd_timer_find(tid); |
273 | } | 280 | } |
274 | #endif | 281 | #endif |
275 | if (timer) { | 282 | if (!timer) { |
276 | if (!list_empty(&timer->open_list_head)) { | ||
277 | timeri = (snd_timer_instance_t *)list_entry(timer->open_list_head.next, snd_timer_instance_t, open_list); | ||
278 | if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { | ||
279 | up(®ister_mutex); | ||
280 | return -EBUSY; | ||
281 | } | ||
282 | } | ||
283 | timeri = snd_timer_instance_new(owner, timer); | ||
284 | if (timeri) { | ||
285 | timeri->slave_class = tid->dev_sclass; | ||
286 | timeri->slave_id = slave_id; | ||
287 | if (list_empty(&timer->open_list_head) && timer->hw.open) | ||
288 | timer->hw.open(timer); | ||
289 | list_add_tail(&timeri->open_list, &timer->open_list_head); | ||
290 | snd_timer_check_master(timeri); | ||
291 | } | ||
292 | } else { | ||
293 | up(®ister_mutex); | 283 | up(®ister_mutex); |
294 | return -ENODEV; | 284 | return -ENODEV; |
295 | } | 285 | } |
286 | if (!list_empty(&timer->open_list_head)) { | ||
287 | timeri = list_entry(timer->open_list_head.next, | ||
288 | snd_timer_instance_t, open_list); | ||
289 | if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { | ||
290 | up(®ister_mutex); | ||
291 | return -EBUSY; | ||
292 | } | ||
293 | } | ||
294 | timeri = snd_timer_instance_new(owner, timer); | ||
295 | if (!timeri) { | ||
296 | up(®ister_mutex); | ||
297 | return -ENOMEM; | ||
298 | } | ||
299 | timeri->slave_class = tid->dev_sclass; | ||
300 | timeri->slave_id = slave_id; | ||
301 | if (list_empty(&timer->open_list_head) && timer->hw.open) | ||
302 | timer->hw.open(timer); | ||
303 | list_add_tail(&timeri->open_list, &timer->open_list_head); | ||
304 | snd_timer_check_master(timeri); | ||
296 | up(®ister_mutex); | 305 | up(®ister_mutex); |
297 | *ti = timeri; | 306 | *ti = timeri; |
298 | return 0; | 307 | return 0; |
299 | } | 308 | } |
300 | 309 | ||
301 | static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event); | 310 | static int _snd_timer_stop(snd_timer_instance_t * timeri, |
311 | int keep_flag, enum sndrv_timer_event event); | ||
302 | 312 | ||
303 | /* | 313 | /* |
304 | * close a timer instance | 314 | * close a timer instance |
@@ -338,11 +348,12 @@ int snd_timer_close(snd_timer_instance_t * timeri) | |||
338 | spin_unlock_irq(&timer->lock); | 348 | spin_unlock_irq(&timer->lock); |
339 | down(®ister_mutex); | 349 | down(®ister_mutex); |
340 | list_del(&timeri->open_list); | 350 | list_del(&timeri->open_list); |
341 | if (timer && list_empty(&timer->open_list_head) && timer->hw.close) | 351 | if (timer && list_empty(&timer->open_list_head) && |
352 | timer->hw.close) | ||
342 | timer->hw.close(timer); | 353 | timer->hw.close(timer); |
343 | /* remove slave links */ | 354 | /* remove slave links */ |
344 | list_for_each_safe(p, n, &timeri->slave_list_head) { | 355 | list_for_each_safe(p, n, &timeri->slave_list_head) { |
345 | slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); | 356 | slave = list_entry(p, snd_timer_instance_t, open_list); |
346 | spin_lock_irq(&slave_active_lock); | 357 | spin_lock_irq(&slave_active_lock); |
347 | _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); | 358 | _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); |
348 | list_del(p); | 359 | list_del(p); |
@@ -357,8 +368,8 @@ int snd_timer_close(snd_timer_instance_t * timeri) | |||
357 | timeri->private_free(timeri); | 368 | timeri->private_free(timeri); |
358 | kfree(timeri->owner); | 369 | kfree(timeri->owner); |
359 | kfree(timeri); | 370 | kfree(timeri); |
360 | if (timer && timer->card) | 371 | if (timer) |
361 | module_put(timer->card->module); | 372 | module_put(timer->module); |
362 | return 0; | 373 | return 0; |
363 | } | 374 | } |
364 | 375 | ||
@@ -376,7 +387,8 @@ unsigned long snd_timer_resolution(snd_timer_instance_t * timeri) | |||
376 | return 0; | 387 | return 0; |
377 | } | 388 | } |
378 | 389 | ||
379 | static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event) | 390 | static void snd_timer_notify1(snd_timer_instance_t *ti, |
391 | enum sndrv_timer_event event) | ||
380 | { | 392 | { |
381 | snd_timer_t *timer; | 393 | snd_timer_t *timer; |
382 | unsigned long flags; | 394 | unsigned long flags; |
@@ -385,9 +397,11 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e | |||
385 | struct list_head *n; | 397 | struct list_head *n; |
386 | struct timespec tstamp; | 398 | struct timespec tstamp; |
387 | 399 | ||
388 | snd_timestamp_now(&tstamp, 1); | 400 | getnstimeofday(&tstamp); |
389 | snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return); | 401 | snd_assert(event >= SNDRV_TIMER_EVENT_START && |
390 | if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE) | 402 | event <= SNDRV_TIMER_EVENT_PAUSE, return); |
403 | if (event == SNDRV_TIMER_EVENT_START || | ||
404 | event == SNDRV_TIMER_EVENT_CONTINUE) | ||
391 | resolution = snd_timer_resolution(ti); | 405 | resolution = snd_timer_resolution(ti); |
392 | if (ti->ccallback) | 406 | if (ti->ccallback) |
393 | ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); | 407 | ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); |
@@ -400,14 +414,15 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e | |||
400 | return; | 414 | return; |
401 | spin_lock_irqsave(&timer->lock, flags); | 415 | spin_lock_irqsave(&timer->lock, flags); |
402 | list_for_each(n, &ti->slave_active_head) { | 416 | list_for_each(n, &ti->slave_active_head) { |
403 | ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list); | 417 | ts = list_entry(n, snd_timer_instance_t, active_list); |
404 | if (ts->ccallback) | 418 | if (ts->ccallback) |
405 | ts->ccallback(ti, event + 100, &tstamp, resolution); | 419 | ts->ccallback(ti, event + 100, &tstamp, resolution); |
406 | } | 420 | } |
407 | spin_unlock_irqrestore(&timer->lock, flags); | 421 | spin_unlock_irqrestore(&timer->lock, flags); |
408 | } | 422 | } |
409 | 423 | ||
410 | static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks) | 424 | static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, |
425 | unsigned long sticks) | ||
411 | { | 426 | { |
412 | list_del(&timeri->active_list); | 427 | list_del(&timeri->active_list); |
413 | list_add_tail(&timeri->active_list, &timer->active_list_head); | 428 | list_add_tail(&timeri->active_list, &timer->active_list_head); |
@@ -434,14 +449,15 @@ static int snd_timer_start_slave(snd_timer_instance_t *timeri) | |||
434 | spin_lock_irqsave(&slave_active_lock, flags); | 449 | spin_lock_irqsave(&slave_active_lock, flags); |
435 | timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; | 450 | timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; |
436 | if (timeri->master) | 451 | if (timeri->master) |
437 | list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); | 452 | list_add_tail(&timeri->active_list, |
453 | &timeri->master->slave_active_head); | ||
438 | spin_unlock_irqrestore(&slave_active_lock, flags); | 454 | spin_unlock_irqrestore(&slave_active_lock, flags); |
439 | return 1; /* delayed start */ | 455 | return 1; /* delayed start */ |
440 | } | 456 | } |
441 | 457 | ||
442 | /* | 458 | /* |
443 | * start the timer instance | 459 | * start the timer instance |
444 | */ | 460 | */ |
445 | int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) | 461 | int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) |
446 | { | 462 | { |
447 | snd_timer_t *timer; | 463 | snd_timer_t *timer; |
@@ -467,7 +483,8 @@ int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) | |||
467 | return result; | 483 | return result; |
468 | } | 484 | } |
469 | 485 | ||
470 | static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event) | 486 | static int _snd_timer_stop(snd_timer_instance_t * timeri, |
487 | int keep_flag, enum sndrv_timer_event event) | ||
471 | { | 488 | { |
472 | snd_timer_t *timer; | 489 | snd_timer_t *timer; |
473 | unsigned long flags; | 490 | unsigned long flags; |
@@ -501,7 +518,8 @@ static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sn | |||
501 | } | 518 | } |
502 | } | 519 | } |
503 | if (!keep_flag) | 520 | if (!keep_flag) |
504 | timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START); | 521 | timeri->flags &= |
522 | ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); | ||
505 | spin_unlock_irqrestore(&timer->lock, flags); | 523 | spin_unlock_irqrestore(&timer->lock, flags); |
506 | __end: | 524 | __end: |
507 | if (event != SNDRV_TIMER_EVENT_RESOLUTION) | 525 | if (event != SNDRV_TIMER_EVENT_RESOLUTION) |
@@ -578,7 +596,7 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left) | |||
578 | struct list_head *p; | 596 | struct list_head *p; |
579 | 597 | ||
580 | list_for_each(p, &timer->active_list_head) { | 598 | list_for_each(p, &timer->active_list_head) { |
581 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); | 599 | ti = list_entry(p, snd_timer_instance_t, active_list); |
582 | if (ti->flags & SNDRV_TIMER_IFLG_START) { | 600 | if (ti->flags & SNDRV_TIMER_IFLG_START) { |
583 | ti->flags &= ~SNDRV_TIMER_IFLG_START; | 601 | ti->flags &= ~SNDRV_TIMER_IFLG_START; |
584 | ti->flags |= SNDRV_TIMER_IFLG_RUNNING; | 602 | ti->flags |= SNDRV_TIMER_IFLG_RUNNING; |
@@ -615,11 +633,11 @@ static void snd_timer_tasklet(unsigned long arg) | |||
615 | /* now process all callbacks */ | 633 | /* now process all callbacks */ |
616 | while (!list_empty(&timer->sack_list_head)) { | 634 | while (!list_empty(&timer->sack_list_head)) { |
617 | p = timer->sack_list_head.next; /* get first item */ | 635 | p = timer->sack_list_head.next; /* get first item */ |
618 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list); | 636 | ti = list_entry(p, snd_timer_instance_t, ack_list); |
619 | 637 | ||
620 | /* remove from ack_list and make empty */ | 638 | /* remove from ack_list and make empty */ |
621 | list_del_init(p); | 639 | list_del_init(p); |
622 | 640 | ||
623 | ticks = ti->pticks; | 641 | ticks = ti->pticks; |
624 | ti->pticks = 0; | 642 | ti->pticks = 0; |
625 | resolution = ti->resolution; | 643 | resolution = ti->resolution; |
@@ -644,7 +662,7 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
644 | { | 662 | { |
645 | snd_timer_instance_t *ti, *ts; | 663 | snd_timer_instance_t *ti, *ts; |
646 | unsigned long resolution, ticks; | 664 | unsigned long resolution, ticks; |
647 | struct list_head *p, *q, *n; | 665 | struct list_head *p, *q, *n, *ack_list_head; |
648 | int use_tasklet = 0; | 666 | int use_tasklet = 0; |
649 | 667 | ||
650 | if (timer == NULL) | 668 | if (timer == NULL) |
@@ -659,11 +677,12 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
659 | resolution = timer->hw.resolution; | 677 | resolution = timer->hw.resolution; |
660 | 678 | ||
661 | /* loop for all active instances | 679 | /* loop for all active instances |
662 | * here we cannot use list_for_each because the active_list of a processed | 680 | * Here we cannot use list_for_each because the active_list of a |
663 | * instance is relinked to done_list_head before callback is called. | 681 | * processed instance is relinked to done_list_head before the callback |
682 | * is called. | ||
664 | */ | 683 | */ |
665 | list_for_each_safe(p, n, &timer->active_list_head) { | 684 | list_for_each_safe(p, n, &timer->active_list_head) { |
666 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); | 685 | ti = list_entry(p, snd_timer_instance_t, active_list); |
667 | if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) | 686 | if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) |
668 | continue; | 687 | continue; |
669 | ti->pticks += ticks_left; | 688 | ti->pticks += ticks_left; |
@@ -681,26 +700,19 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
681 | if (--timer->running) | 700 | if (--timer->running) |
682 | list_del(p); | 701 | list_del(p); |
683 | } | 702 | } |
684 | if (list_empty(&ti->ack_list)) { | 703 | if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || |
685 | if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || | 704 | (ti->flags & SNDRV_TIMER_IFLG_FAST)) |
686 | (ti->flags & SNDRV_TIMER_IFLG_FAST)) { | 705 | ack_list_head = &timer->ack_list_head; |
687 | list_add_tail(&ti->ack_list, &timer->ack_list_head); | 706 | else |
688 | } else { | 707 | ack_list_head = &timer->sack_list_head; |
689 | list_add_tail(&ti->ack_list, &timer->sack_list_head); | 708 | if (list_empty(&ti->ack_list)) |
690 | } | 709 | list_add_tail(&ti->ack_list, ack_list_head); |
691 | } | ||
692 | list_for_each(q, &ti->slave_active_head) { | 710 | list_for_each(q, &ti->slave_active_head) { |
693 | ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list); | 711 | ts = list_entry(q, snd_timer_instance_t, active_list); |
694 | ts->pticks = ti->pticks; | 712 | ts->pticks = ti->pticks; |
695 | ts->resolution = resolution; | 713 | ts->resolution = resolution; |
696 | if (list_empty(&ts->ack_list)) { | 714 | if (list_empty(&ts->ack_list)) |
697 | if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || | 715 | list_add_tail(&ts->ack_list, ack_list_head); |
698 | (ti->flags & SNDRV_TIMER_IFLG_FAST)) { | ||
699 | list_add_tail(&ts->ack_list, &timer->ack_list_head); | ||
700 | } else { | ||
701 | list_add_tail(&ts->ack_list, &timer->sack_list_head); | ||
702 | } | ||
703 | } | ||
704 | } | 716 | } |
705 | } | 717 | } |
706 | if (timer->flags & SNDRV_TIMER_FLG_RESCHED) | 718 | if (timer->flags & SNDRV_TIMER_FLG_RESCHED) |
@@ -723,11 +735,11 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
723 | /* now process all fast callbacks */ | 735 | /* now process all fast callbacks */ |
724 | while (!list_empty(&timer->ack_list_head)) { | 736 | while (!list_empty(&timer->ack_list_head)) { |
725 | p = timer->ack_list_head.next; /* get first item */ | 737 | p = timer->ack_list_head.next; /* get first item */ |
726 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list); | 738 | ti = list_entry(p, snd_timer_instance_t, ack_list); |
727 | 739 | ||
728 | /* remove from ack_list and make empty */ | 740 | /* remove from ack_list and make empty */ |
729 | list_del_init(p); | 741 | list_del_init(p); |
730 | 742 | ||
731 | ticks = ti->pticks; | 743 | ticks = ti->pticks; |
732 | ti->pticks = 0; | 744 | ti->pticks = 0; |
733 | 745 | ||
@@ -751,7 +763,8 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) | |||
751 | 763 | ||
752 | */ | 764 | */ |
753 | 765 | ||
754 | int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer) | 766 | int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, |
767 | snd_timer_t **rtimer) | ||
755 | { | 768 | { |
756 | snd_timer_t *timer; | 769 | snd_timer_t *timer; |
757 | int err; | 770 | int err; |
@@ -779,9 +792,12 @@ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t * | |||
779 | INIT_LIST_HEAD(&timer->ack_list_head); | 792 | INIT_LIST_HEAD(&timer->ack_list_head); |
780 | INIT_LIST_HEAD(&timer->sack_list_head); | 793 | INIT_LIST_HEAD(&timer->sack_list_head); |
781 | spin_lock_init(&timer->lock); | 794 | spin_lock_init(&timer->lock); |
782 | tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); | 795 | tasklet_init(&timer->task_queue, snd_timer_tasklet, |
796 | (unsigned long)timer); | ||
783 | if (card != NULL) { | 797 | if (card != NULL) { |
784 | if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) { | 798 | timer->module = card->module; |
799 | err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); | ||
800 | if (err < 0) { | ||
785 | snd_timer_free(timer); | 801 | snd_timer_free(timer); |
786 | return err; | 802 | return err; |
787 | } | 803 | } |
@@ -811,14 +827,15 @@ static int snd_timer_dev_register(snd_device_t *dev) | |||
811 | snd_timer_t *timer1; | 827 | snd_timer_t *timer1; |
812 | struct list_head *p; | 828 | struct list_head *p; |
813 | 829 | ||
814 | snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO); | 830 | snd_assert(timer != NULL && timer->hw.start != NULL && |
831 | timer->hw.stop != NULL, return -ENXIO); | ||
815 | if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && | 832 | if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && |
816 | !timer->hw.resolution && timer->hw.c_resolution == NULL) | 833 | !timer->hw.resolution && timer->hw.c_resolution == NULL) |
817 | return -EINVAL; | 834 | return -EINVAL; |
818 | 835 | ||
819 | down(®ister_mutex); | 836 | down(®ister_mutex); |
820 | list_for_each(p, &snd_timer_list) { | 837 | list_for_each(p, &snd_timer_list) { |
821 | timer1 = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 838 | timer1 = list_entry(p, snd_timer_t, device_list); |
822 | if (timer1->tmr_class > timer->tmr_class) | 839 | if (timer1->tmr_class > timer->tmr_class) |
823 | break; | 840 | break; |
824 | if (timer1->tmr_class < timer->tmr_class) | 841 | if (timer1->tmr_class < timer->tmr_class) |
@@ -857,7 +874,7 @@ static int snd_timer_unregister(snd_timer_t *timer) | |||
857 | snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); | 874 | snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); |
858 | list_for_each_safe(p, n, &timer->open_list_head) { | 875 | list_for_each_safe(p, n, &timer->open_list_head) { |
859 | list_del_init(p); | 876 | list_del_init(p); |
860 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); | 877 | ti = list_entry(p, snd_timer_instance_t, open_list); |
861 | ti->timer = NULL; | 878 | ti->timer = NULL; |
862 | } | 879 | } |
863 | } | 880 | } |
@@ -872,15 +889,18 @@ static int snd_timer_dev_unregister(snd_device_t *device) | |||
872 | return snd_timer_unregister(timer); | 889 | return snd_timer_unregister(timer); |
873 | } | 890 | } |
874 | 891 | ||
875 | void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp) | 892 | void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, |
893 | struct timespec *tstamp) | ||
876 | { | 894 | { |
877 | unsigned long flags; | 895 | unsigned long flags; |
878 | unsigned long resolution = 0; | 896 | unsigned long resolution = 0; |
879 | snd_timer_instance_t *ti, *ts; | 897 | snd_timer_instance_t *ti, *ts; |
880 | struct list_head *p, *n; | 898 | struct list_head *p, *n; |
881 | 899 | ||
882 | snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return); | 900 | if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) |
883 | snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return); | 901 | return; |
902 | snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && | ||
903 | event <= SNDRV_TIMER_EVENT_MRESUME, return); | ||
884 | spin_lock_irqsave(&timer->lock, flags); | 904 | spin_lock_irqsave(&timer->lock, flags); |
885 | if (event == SNDRV_TIMER_EVENT_MSTART || | 905 | if (event == SNDRV_TIMER_EVENT_MSTART || |
886 | event == SNDRV_TIMER_EVENT_MCONTINUE || | 906 | event == SNDRV_TIMER_EVENT_MCONTINUE || |
@@ -891,11 +911,11 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t | |||
891 | resolution = timer->hw.resolution; | 911 | resolution = timer->hw.resolution; |
892 | } | 912 | } |
893 | list_for_each(p, &timer->active_list_head) { | 913 | list_for_each(p, &timer->active_list_head) { |
894 | ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); | 914 | ti = list_entry(p, snd_timer_instance_t, active_list); |
895 | if (ti->ccallback) | 915 | if (ti->ccallback) |
896 | ti->ccallback(ti, event, tstamp, resolution); | 916 | ti->ccallback(ti, event, tstamp, resolution); |
897 | list_for_each(n, &ti->slave_active_head) { | 917 | list_for_each(n, &ti->slave_active_head) { |
898 | ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list); | 918 | ts = list_entry(n, snd_timer_instance_t, active_list); |
899 | if (ts->ccallback) | 919 | if (ts->ccallback) |
900 | ts->ccallback(ts, event, tstamp, resolution); | 920 | ts->ccallback(ts, event, tstamp, resolution); |
901 | } | 921 | } |
@@ -909,7 +929,7 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t | |||
909 | int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer) | 929 | int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer) |
910 | { | 930 | { |
911 | snd_timer_id_t tid; | 931 | snd_timer_id_t tid; |
912 | 932 | ||
913 | tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL; | 933 | tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL; |
914 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; | 934 | tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; |
915 | tid.card = -1; | 935 | tid.card = -1; |
@@ -937,7 +957,7 @@ int snd_timer_global_unregister(snd_timer_t *timer) | |||
937 | return snd_timer_unregister(timer); | 957 | return snd_timer_unregister(timer); |
938 | } | 958 | } |
939 | 959 | ||
940 | /* | 960 | /* |
941 | * System timer | 961 | * System timer |
942 | */ | 962 | */ |
943 | 963 | ||
@@ -1013,7 +1033,8 @@ static int snd_timer_register_system(void) | |||
1013 | struct snd_timer_system_private *priv; | 1033 | struct snd_timer_system_private *priv; |
1014 | int err; | 1034 | int err; |
1015 | 1035 | ||
1016 | if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0) | 1036 | err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer); |
1037 | if (err < 0) | ||
1017 | return err; | 1038 | return err; |
1018 | strcpy(timer->name, "system timer"); | 1039 | strcpy(timer->name, "system timer"); |
1019 | timer->hw = snd_timer_system; | 1040 | timer->hw = snd_timer_system; |
@@ -1044,33 +1065,41 @@ static void snd_timer_proc_read(snd_info_entry_t *entry, | |||
1044 | 1065 | ||
1045 | down(®ister_mutex); | 1066 | down(®ister_mutex); |
1046 | list_for_each(p, &snd_timer_list) { | 1067 | list_for_each(p, &snd_timer_list) { |
1047 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 1068 | timer = list_entry(p, snd_timer_t, device_list); |
1048 | switch (timer->tmr_class) { | 1069 | switch (timer->tmr_class) { |
1049 | case SNDRV_TIMER_CLASS_GLOBAL: | 1070 | case SNDRV_TIMER_CLASS_GLOBAL: |
1050 | snd_iprintf(buffer, "G%i: ", timer->tmr_device); | 1071 | snd_iprintf(buffer, "G%i: ", timer->tmr_device); |
1051 | break; | 1072 | break; |
1052 | case SNDRV_TIMER_CLASS_CARD: | 1073 | case SNDRV_TIMER_CLASS_CARD: |
1053 | snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device); | 1074 | snd_iprintf(buffer, "C%i-%i: ", |
1075 | timer->card->number, timer->tmr_device); | ||
1054 | break; | 1076 | break; |
1055 | case SNDRV_TIMER_CLASS_PCM: | 1077 | case SNDRV_TIMER_CLASS_PCM: |
1056 | snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice); | 1078 | snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, |
1079 | timer->tmr_device, timer->tmr_subdevice); | ||
1057 | break; | 1080 | break; |
1058 | default: | 1081 | default: |
1059 | snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice); | 1082 | snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, |
1083 | timer->card ? timer->card->number : -1, | ||
1084 | timer->tmr_device, timer->tmr_subdevice); | ||
1060 | } | 1085 | } |
1061 | snd_iprintf(buffer, "%s :", timer->name); | 1086 | snd_iprintf(buffer, "%s :", timer->name); |
1062 | if (timer->hw.resolution) | 1087 | if (timer->hw.resolution) |
1063 | snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks); | 1088 | snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", |
1089 | timer->hw.resolution / 1000, | ||
1090 | timer->hw.resolution % 1000, | ||
1091 | timer->hw.ticks); | ||
1064 | if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) | 1092 | if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) |
1065 | snd_iprintf(buffer, " SLAVE"); | 1093 | snd_iprintf(buffer, " SLAVE"); |
1066 | snd_iprintf(buffer, "\n"); | 1094 | snd_iprintf(buffer, "\n"); |
1067 | spin_lock_irqsave(&timer->lock, flags); | 1095 | spin_lock_irqsave(&timer->lock, flags); |
1068 | list_for_each(q, &timer->open_list_head) { | 1096 | list_for_each(q, &timer->open_list_head) { |
1069 | ti = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list); | 1097 | ti = list_entry(q, snd_timer_instance_t, open_list); |
1070 | snd_iprintf(buffer, " Client %s : %s : lost interrupts %li\n", | 1098 | snd_iprintf(buffer, " Client %s : %s\n", |
1071 | ti->owner ? ti->owner : "unknown", | 1099 | ti->owner ? ti->owner : "unknown", |
1072 | ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped", | 1100 | ti->flags & (SNDRV_TIMER_IFLG_START | |
1073 | ti->lost); | 1101 | SNDRV_TIMER_IFLG_RUNNING) |
1102 | ? "running" : "stopped"); | ||
1074 | } | 1103 | } |
1075 | spin_unlock_irqrestore(&timer->lock, flags); | 1104 | spin_unlock_irqrestore(&timer->lock, flags); |
1076 | } | 1105 | } |
@@ -1088,7 +1117,7 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri, | |||
1088 | snd_timer_user_t *tu = timeri->callback_data; | 1117 | snd_timer_user_t *tu = timeri->callback_data; |
1089 | snd_timer_read_t *r; | 1118 | snd_timer_read_t *r; |
1090 | int prev; | 1119 | int prev; |
1091 | 1120 | ||
1092 | spin_lock(&tu->qlock); | 1121 | spin_lock(&tu->qlock); |
1093 | if (tu->qused > 0) { | 1122 | if (tu->qused > 0) { |
1094 | prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; | 1123 | prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; |
@@ -1113,7 +1142,8 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri, | |||
1113 | wake_up(&tu->qchange_sleep); | 1142 | wake_up(&tu->qchange_sleep); |
1114 | } | 1143 | } |
1115 | 1144 | ||
1116 | static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread) | 1145 | static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, |
1146 | snd_timer_tread_t *tread) | ||
1117 | { | 1147 | { |
1118 | if (tu->qused >= tu->queue_size) { | 1148 | if (tu->qused >= tu->queue_size) { |
1119 | tu->overrun++; | 1149 | tu->overrun++; |
@@ -1132,7 +1162,8 @@ static void snd_timer_user_ccallback(snd_timer_instance_t *timeri, | |||
1132 | snd_timer_user_t *tu = timeri->callback_data; | 1162 | snd_timer_user_t *tu = timeri->callback_data; |
1133 | snd_timer_tread_t r1; | 1163 | snd_timer_tread_t r1; |
1134 | 1164 | ||
1135 | if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE) | 1165 | if (event >= SNDRV_TIMER_EVENT_START && |
1166 | event <= SNDRV_TIMER_EVENT_PAUSE) | ||
1136 | tu->tstamp = *tstamp; | 1167 | tu->tstamp = *tstamp; |
1137 | if ((tu->filter & (1 << event)) == 0 || !tu->tread) | 1168 | if ((tu->filter & (1 << event)) == 0 || !tu->tread) |
1138 | return; | 1169 | return; |
@@ -1155,15 +1186,17 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri, | |||
1155 | struct timespec tstamp; | 1186 | struct timespec tstamp; |
1156 | int prev, append = 0; | 1187 | int prev, append = 0; |
1157 | 1188 | ||
1158 | snd_timestamp_zero(&tstamp); | 1189 | memset(&tstamp, 0, sizeof(tstamp)); |
1159 | spin_lock(&tu->qlock); | 1190 | spin_lock(&tu->qlock); |
1160 | if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) { | 1191 | if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | |
1192 | (1 << SNDRV_TIMER_EVENT_TICK))) == 0) { | ||
1161 | spin_unlock(&tu->qlock); | 1193 | spin_unlock(&tu->qlock); |
1162 | return; | 1194 | return; |
1163 | } | 1195 | } |
1164 | if (tu->last_resolution != resolution || ticks > 0) | 1196 | if (tu->last_resolution != resolution || ticks > 0) |
1165 | snd_timestamp_now(&tstamp, 1); | 1197 | getnstimeofday(&tstamp); |
1166 | if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { | 1198 | if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && |
1199 | tu->last_resolution != resolution) { | ||
1167 | r1.event = SNDRV_TIMER_EVENT_RESOLUTION; | 1200 | r1.event = SNDRV_TIMER_EVENT_RESOLUTION; |
1168 | r1.tstamp = tstamp; | 1201 | r1.tstamp = tstamp; |
1169 | r1.val = resolution; | 1202 | r1.val = resolution; |
@@ -1201,7 +1234,7 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri, | |||
1201 | static int snd_timer_user_open(struct inode *inode, struct file *file) | 1234 | static int snd_timer_user_open(struct inode *inode, struct file *file) |
1202 | { | 1235 | { |
1203 | snd_timer_user_t *tu; | 1236 | snd_timer_user_t *tu; |
1204 | 1237 | ||
1205 | tu = kzalloc(sizeof(*tu), GFP_KERNEL); | 1238 | tu = kzalloc(sizeof(*tu), GFP_KERNEL); |
1206 | if (tu == NULL) | 1239 | if (tu == NULL) |
1207 | return -ENOMEM; | 1240 | return -ENOMEM; |
@@ -1210,7 +1243,8 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) | |||
1210 | init_MUTEX(&tu->tread_sem); | 1243 | init_MUTEX(&tu->tread_sem); |
1211 | tu->ticks = 1; | 1244 | tu->ticks = 1; |
1212 | tu->queue_size = 128; | 1245 | tu->queue_size = 128; |
1213 | tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); | 1246 | tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t), |
1247 | GFP_KERNEL); | ||
1214 | if (tu->queue == NULL) { | 1248 | if (tu->queue == NULL) { |
1215 | kfree(tu); | 1249 | kfree(tu); |
1216 | return -ENOMEM; | 1250 | return -ENOMEM; |
@@ -1259,7 +1293,7 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1259 | snd_timer_id_t id; | 1293 | snd_timer_id_t id; |
1260 | snd_timer_t *timer; | 1294 | snd_timer_t *timer; |
1261 | struct list_head *p; | 1295 | struct list_head *p; |
1262 | 1296 | ||
1263 | if (copy_from_user(&id, _tid, sizeof(id))) | 1297 | if (copy_from_user(&id, _tid, sizeof(id))) |
1264 | return -EFAULT; | 1298 | return -EFAULT; |
1265 | down(®ister_mutex); | 1299 | down(®ister_mutex); |
@@ -1267,7 +1301,8 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1267 | if (list_empty(&snd_timer_list)) | 1301 | if (list_empty(&snd_timer_list)) |
1268 | snd_timer_user_zero_id(&id); | 1302 | snd_timer_user_zero_id(&id); |
1269 | else { | 1303 | else { |
1270 | timer = (snd_timer_t *)list_entry(snd_timer_list.next, snd_timer_t, device_list); | 1304 | timer = list_entry(snd_timer_list.next, |
1305 | snd_timer_t, device_list); | ||
1271 | snd_timer_user_copy_id(&id, timer); | 1306 | snd_timer_user_copy_id(&id, timer); |
1272 | } | 1307 | } |
1273 | } else { | 1308 | } else { |
@@ -1275,7 +1310,7 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1275 | case SNDRV_TIMER_CLASS_GLOBAL: | 1310 | case SNDRV_TIMER_CLASS_GLOBAL: |
1276 | id.device = id.device < 0 ? 0 : id.device + 1; | 1311 | id.device = id.device < 0 ? 0 : id.device + 1; |
1277 | list_for_each(p, &snd_timer_list) { | 1312 | list_for_each(p, &snd_timer_list) { |
1278 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 1313 | timer = list_entry(p, snd_timer_t, device_list); |
1279 | if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) { | 1314 | if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) { |
1280 | snd_timer_user_copy_id(&id, timer); | 1315 | snd_timer_user_copy_id(&id, timer); |
1281 | break; | 1316 | break; |
@@ -1299,12 +1334,16 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1299 | if (id.device < 0) { | 1334 | if (id.device < 0) { |
1300 | id.device = 0; | 1335 | id.device = 0; |
1301 | } else { | 1336 | } else { |
1302 | id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1; | 1337 | if (id.subdevice < 0) { |
1338 | id.subdevice = 0; | ||
1339 | } else { | ||
1340 | id.subdevice++; | ||
1341 | } | ||
1303 | } | 1342 | } |
1304 | } | 1343 | } |
1305 | } | 1344 | } |
1306 | list_for_each(p, &snd_timer_list) { | 1345 | list_for_each(p, &snd_timer_list) { |
1307 | timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 1346 | timer = list_entry(p, snd_timer_t, device_list); |
1308 | if (timer->tmr_class > id.dev_class) { | 1347 | if (timer->tmr_class > id.dev_class) { |
1309 | snd_timer_user_copy_id(&id, timer); | 1348 | snd_timer_user_copy_id(&id, timer); |
1310 | break; | 1349 | break; |
@@ -1343,9 +1382,10 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) | |||
1343 | if (copy_to_user(_tid, &id, sizeof(*_tid))) | 1382 | if (copy_to_user(_tid, &id, sizeof(*_tid))) |
1344 | return -EFAULT; | 1383 | return -EFAULT; |
1345 | return 0; | 1384 | return 0; |
1346 | } | 1385 | } |
1347 | 1386 | ||
1348 | static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo) | 1387 | static int snd_timer_user_ginfo(struct file *file, |
1388 | snd_timer_ginfo_t __user *_ginfo) | ||
1349 | { | 1389 | { |
1350 | snd_timer_ginfo_t *ginfo; | 1390 | snd_timer_ginfo_t *ginfo; |
1351 | snd_timer_id_t tid; | 1391 | snd_timer_id_t tid; |
@@ -1389,7 +1429,8 @@ static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_gi | |||
1389 | return err; | 1429 | return err; |
1390 | } | 1430 | } |
1391 | 1431 | ||
1392 | static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams) | 1432 | static int snd_timer_user_gparams(struct file *file, |
1433 | snd_timer_gparams_t __user *_gparams) | ||
1393 | { | 1434 | { |
1394 | snd_timer_gparams_t gparams; | 1435 | snd_timer_gparams_t gparams; |
1395 | snd_timer_t *t; | 1436 | snd_timer_t *t; |
@@ -1399,23 +1440,26 @@ static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user | |||
1399 | return -EFAULT; | 1440 | return -EFAULT; |
1400 | down(®ister_mutex); | 1441 | down(®ister_mutex); |
1401 | t = snd_timer_find(&gparams.tid); | 1442 | t = snd_timer_find(&gparams.tid); |
1402 | if (t != NULL) { | 1443 | if (!t) { |
1403 | if (list_empty(&t->open_list_head)) { | ||
1404 | if (t->hw.set_period) | ||
1405 | err = t->hw.set_period(t, gparams.period_num, gparams.period_den); | ||
1406 | else | ||
1407 | err = -ENOSYS; | ||
1408 | } else { | ||
1409 | err = -EBUSY; | ||
1410 | } | ||
1411 | } else { | ||
1412 | err = -ENODEV; | 1444 | err = -ENODEV; |
1445 | goto _error; | ||
1446 | } | ||
1447 | if (!list_empty(&t->open_list_head)) { | ||
1448 | err = -EBUSY; | ||
1449 | goto _error; | ||
1413 | } | 1450 | } |
1451 | if (!t->hw.set_period) { | ||
1452 | err = -ENOSYS; | ||
1453 | goto _error; | ||
1454 | } | ||
1455 | err = t->hw.set_period(t, gparams.period_num, gparams.period_den); | ||
1456 | _error: | ||
1414 | up(®ister_mutex); | 1457 | up(®ister_mutex); |
1415 | return err; | 1458 | return err; |
1416 | } | 1459 | } |
1417 | 1460 | ||
1418 | static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus) | 1461 | static int snd_timer_user_gstatus(struct file *file, |
1462 | snd_timer_gstatus_t __user *_gstatus) | ||
1419 | { | 1463 | { |
1420 | snd_timer_gstatus_t gstatus; | 1464 | snd_timer_gstatus_t gstatus; |
1421 | snd_timer_id_t tid; | 1465 | snd_timer_id_t tid; |
@@ -1435,7 +1479,8 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user | |||
1435 | else | 1479 | else |
1436 | gstatus.resolution = t->hw.resolution; | 1480 | gstatus.resolution = t->hw.resolution; |
1437 | if (t->hw.precise_resolution) { | 1481 | if (t->hw.precise_resolution) { |
1438 | t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den); | 1482 | t->hw.precise_resolution(t, &gstatus.resolution_num, |
1483 | &gstatus.resolution_den); | ||
1439 | } else { | 1484 | } else { |
1440 | gstatus.resolution_num = gstatus.resolution; | 1485 | gstatus.resolution_num = gstatus.resolution; |
1441 | gstatus.resolution_den = 1000000000uL; | 1486 | gstatus.resolution_den = 1000000000uL; |
@@ -1449,13 +1494,14 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user | |||
1449 | return err; | 1494 | return err; |
1450 | } | 1495 | } |
1451 | 1496 | ||
1452 | static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect) | 1497 | static int snd_timer_user_tselect(struct file *file, |
1498 | snd_timer_select_t __user *_tselect) | ||
1453 | { | 1499 | { |
1454 | snd_timer_user_t *tu; | 1500 | snd_timer_user_t *tu; |
1455 | snd_timer_select_t tselect; | 1501 | snd_timer_select_t tselect; |
1456 | char str[32]; | 1502 | char str[32]; |
1457 | int err = 0; | 1503 | int err = 0; |
1458 | 1504 | ||
1459 | tu = file->private_data; | 1505 | tu = file->private_data; |
1460 | down(&tu->tread_sem); | 1506 | down(&tu->tread_sem); |
1461 | if (tu->timeri) { | 1507 | if (tu->timeri) { |
@@ -1469,7 +1515,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * | |||
1469 | sprintf(str, "application %i", current->pid); | 1515 | sprintf(str, "application %i", current->pid); |
1470 | if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) | 1516 | if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) |
1471 | tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; | 1517 | tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; |
1472 | if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) | 1518 | err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid); |
1519 | if (err < 0) | ||
1473 | goto __err; | 1520 | goto __err; |
1474 | 1521 | ||
1475 | kfree(tu->queue); | 1522 | kfree(tu->queue); |
@@ -1477,21 +1524,24 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * | |||
1477 | kfree(tu->tqueue); | 1524 | kfree(tu->tqueue); |
1478 | tu->tqueue = NULL; | 1525 | tu->tqueue = NULL; |
1479 | if (tu->tread) { | 1526 | if (tu->tread) { |
1480 | tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); | 1527 | tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), |
1528 | GFP_KERNEL); | ||
1481 | if (tu->tqueue == NULL) | 1529 | if (tu->tqueue == NULL) |
1482 | err = -ENOMEM; | 1530 | err = -ENOMEM; |
1483 | } else { | 1531 | } else { |
1484 | tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); | 1532 | tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t), |
1533 | GFP_KERNEL); | ||
1485 | if (tu->queue == NULL) | 1534 | if (tu->queue == NULL) |
1486 | err = -ENOMEM; | 1535 | err = -ENOMEM; |
1487 | } | 1536 | } |
1488 | 1537 | ||
1489 | if (err < 0) { | 1538 | if (err < 0) { |
1490 | snd_timer_close(tu->timeri); | 1539 | snd_timer_close(tu->timeri); |
1491 | tu->timeri = NULL; | 1540 | tu->timeri = NULL; |
1492 | } else { | 1541 | } else { |
1493 | tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; | 1542 | tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; |
1494 | tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; | 1543 | tu->timeri->callback = tu->tread |
1544 | ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; | ||
1495 | tu->timeri->ccallback = snd_timer_user_ccallback; | 1545 | tu->timeri->ccallback = snd_timer_user_ccallback; |
1496 | tu->timeri->callback_data = (void *)tu; | 1546 | tu->timeri->callback_data = (void *)tu; |
1497 | } | 1547 | } |
@@ -1501,7 +1551,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * | |||
1501 | return err; | 1551 | return err; |
1502 | } | 1552 | } |
1503 | 1553 | ||
1504 | static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info) | 1554 | static int snd_timer_user_info(struct file *file, |
1555 | snd_timer_info_t __user *_info) | ||
1505 | { | 1556 | { |
1506 | snd_timer_user_t *tu; | 1557 | snd_timer_user_t *tu; |
1507 | snd_timer_info_t *info; | 1558 | snd_timer_info_t *info; |
@@ -1528,7 +1579,8 @@ static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info | |||
1528 | return err; | 1579 | return err; |
1529 | } | 1580 | } |
1530 | 1581 | ||
1531 | static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params) | 1582 | static int snd_timer_user_params(struct file *file, |
1583 | snd_timer_params_t __user *_params) | ||
1532 | { | 1584 | { |
1533 | snd_timer_user_t *tu; | 1585 | snd_timer_user_t *tu; |
1534 | snd_timer_params_t params; | 1586 | snd_timer_params_t params; |
@@ -1536,7 +1588,7 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1536 | snd_timer_read_t *tr; | 1588 | snd_timer_read_t *tr; |
1537 | snd_timer_tread_t *ttr; | 1589 | snd_timer_tread_t *ttr; |
1538 | int err; | 1590 | int err; |
1539 | 1591 | ||
1540 | tu = file->private_data; | 1592 | tu = file->private_data; |
1541 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1593 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1542 | t = tu->timeri->timer; | 1594 | t = tu->timeri->timer; |
@@ -1547,7 +1599,8 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1547 | err = -EINVAL; | 1599 | err = -EINVAL; |
1548 | goto _end; | 1600 | goto _end; |
1549 | } | 1601 | } |
1550 | if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { | 1602 | if (params.queue_size > 0 && |
1603 | (params.queue_size < 32 || params.queue_size > 1024)) { | ||
1551 | err = -EINVAL; | 1604 | err = -EINVAL; |
1552 | goto _end; | 1605 | goto _end; |
1553 | } | 1606 | } |
@@ -1580,16 +1633,19 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1580 | if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) | 1633 | if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) |
1581 | tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; | 1634 | tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; |
1582 | spin_unlock_irq(&t->lock); | 1635 | spin_unlock_irq(&t->lock); |
1583 | if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) { | 1636 | if (params.queue_size > 0 && |
1637 | (unsigned int)tu->queue_size != params.queue_size) { | ||
1584 | if (tu->tread) { | 1638 | if (tu->tread) { |
1585 | ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); | 1639 | ttr = kmalloc(params.queue_size * sizeof(*ttr), |
1640 | GFP_KERNEL); | ||
1586 | if (ttr) { | 1641 | if (ttr) { |
1587 | kfree(tu->tqueue); | 1642 | kfree(tu->tqueue); |
1588 | tu->queue_size = params.queue_size; | 1643 | tu->queue_size = params.queue_size; |
1589 | tu->tqueue = ttr; | 1644 | tu->tqueue = ttr; |
1590 | } | 1645 | } |
1591 | } else { | 1646 | } else { |
1592 | tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); | 1647 | tr = kmalloc(params.queue_size * sizeof(*tr), |
1648 | GFP_KERNEL); | ||
1593 | if (tr) { | 1649 | if (tr) { |
1594 | kfree(tu->queue); | 1650 | kfree(tu->queue); |
1595 | tu->queue_size = params.queue_size; | 1651 | tu->queue_size = params.queue_size; |
@@ -1613,7 +1669,6 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1613 | tu->qused++; | 1669 | tu->qused++; |
1614 | tu->qtail++; | 1670 | tu->qtail++; |
1615 | } | 1671 | } |
1616 | |||
1617 | } | 1672 | } |
1618 | tu->filter = params.filter; | 1673 | tu->filter = params.filter; |
1619 | tu->ticks = params.ticks; | 1674 | tu->ticks = params.ticks; |
@@ -1624,11 +1679,12 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ | |||
1624 | return err; | 1679 | return err; |
1625 | } | 1680 | } |
1626 | 1681 | ||
1627 | static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status) | 1682 | static int snd_timer_user_status(struct file *file, |
1683 | snd_timer_status_t __user *_status) | ||
1628 | { | 1684 | { |
1629 | snd_timer_user_t *tu; | 1685 | snd_timer_user_t *tu; |
1630 | snd_timer_status_t status; | 1686 | snd_timer_status_t status; |
1631 | 1687 | ||
1632 | tu = file->private_data; | 1688 | tu = file->private_data; |
1633 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1689 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1634 | memset(&status, 0, sizeof(status)); | 1690 | memset(&status, 0, sizeof(status)); |
@@ -1648,7 +1704,7 @@ static int snd_timer_user_start(struct file *file) | |||
1648 | { | 1704 | { |
1649 | int err; | 1705 | int err; |
1650 | snd_timer_user_t *tu; | 1706 | snd_timer_user_t *tu; |
1651 | 1707 | ||
1652 | tu = file->private_data; | 1708 | tu = file->private_data; |
1653 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1709 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1654 | snd_timer_stop(tu->timeri); | 1710 | snd_timer_stop(tu->timeri); |
@@ -1661,7 +1717,7 @@ static int snd_timer_user_stop(struct file *file) | |||
1661 | { | 1717 | { |
1662 | int err; | 1718 | int err; |
1663 | snd_timer_user_t *tu; | 1719 | snd_timer_user_t *tu; |
1664 | 1720 | ||
1665 | tu = file->private_data; | 1721 | tu = file->private_data; |
1666 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1722 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1667 | return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; | 1723 | return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; |
@@ -1671,7 +1727,7 @@ static int snd_timer_user_continue(struct file *file) | |||
1671 | { | 1727 | { |
1672 | int err; | 1728 | int err; |
1673 | snd_timer_user_t *tu; | 1729 | snd_timer_user_t *tu; |
1674 | 1730 | ||
1675 | tu = file->private_data; | 1731 | tu = file->private_data; |
1676 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1732 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1677 | tu->timeri->lost = 0; | 1733 | tu->timeri->lost = 0; |
@@ -1682,7 +1738,7 @@ static int snd_timer_user_pause(struct file *file) | |||
1682 | { | 1738 | { |
1683 | int err; | 1739 | int err; |
1684 | snd_timer_user_t *tu; | 1740 | snd_timer_user_t *tu; |
1685 | 1741 | ||
1686 | tu = file->private_data; | 1742 | tu = file->private_data; |
1687 | snd_assert(tu->timeri != NULL, return -ENXIO); | 1743 | snd_assert(tu->timeri != NULL, return -ENXIO); |
1688 | return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; | 1744 | return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; |
@@ -1695,12 +1751,13 @@ enum { | |||
1695 | SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), | 1751 | SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), |
1696 | }; | 1752 | }; |
1697 | 1753 | ||
1698 | static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1754 | static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, |
1755 | unsigned long arg) | ||
1699 | { | 1756 | { |
1700 | snd_timer_user_t *tu; | 1757 | snd_timer_user_t *tu; |
1701 | void __user *argp = (void __user *)arg; | 1758 | void __user *argp = (void __user *)arg; |
1702 | int __user *p = argp; | 1759 | int __user *p = argp; |
1703 | 1760 | ||
1704 | tu = file->private_data; | 1761 | tu = file->private_data; |
1705 | switch (cmd) { | 1762 | switch (cmd) { |
1706 | case SNDRV_TIMER_IOCTL_PVERSION: | 1763 | case SNDRV_TIMER_IOCTL_PVERSION: |
@@ -1710,7 +1767,7 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned l | |||
1710 | case SNDRV_TIMER_IOCTL_TREAD: | 1767 | case SNDRV_TIMER_IOCTL_TREAD: |
1711 | { | 1768 | { |
1712 | int xarg; | 1769 | int xarg; |
1713 | 1770 | ||
1714 | down(&tu->tread_sem); | 1771 | down(&tu->tread_sem); |
1715 | if (tu->timeri) { /* too late */ | 1772 | if (tu->timeri) { /* too late */ |
1716 | up(&tu->tread_sem); | 1773 | up(&tu->tread_sem); |
@@ -1758,7 +1815,7 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on) | |||
1758 | { | 1815 | { |
1759 | snd_timer_user_t *tu; | 1816 | snd_timer_user_t *tu; |
1760 | int err; | 1817 | int err; |
1761 | 1818 | ||
1762 | tu = file->private_data; | 1819 | tu = file->private_data; |
1763 | err = fasync_helper(fd, file, on, &tu->fasync); | 1820 | err = fasync_helper(fd, file, on, &tu->fasync); |
1764 | if (err < 0) | 1821 | if (err < 0) |
@@ -1766,12 +1823,13 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on) | |||
1766 | return 0; | 1823 | return 0; |
1767 | } | 1824 | } |
1768 | 1825 | ||
1769 | static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset) | 1826 | static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, |
1827 | size_t count, loff_t *offset) | ||
1770 | { | 1828 | { |
1771 | snd_timer_user_t *tu; | 1829 | snd_timer_user_t *tu; |
1772 | long result = 0, unit; | 1830 | long result = 0, unit; |
1773 | int err = 0; | 1831 | int err = 0; |
1774 | 1832 | ||
1775 | tu = file->private_data; | 1833 | tu = file->private_data; |
1776 | unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t); | 1834 | unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t); |
1777 | spin_lock_irq(&tu->qlock); | 1835 | spin_lock_irq(&tu->qlock); |
@@ -1805,12 +1863,14 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_ | |||
1805 | goto _error; | 1863 | goto _error; |
1806 | 1864 | ||
1807 | if (tu->tread) { | 1865 | if (tu->tread) { |
1808 | if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) { | 1866 | if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], |
1867 | sizeof(snd_timer_tread_t))) { | ||
1809 | err = -EFAULT; | 1868 | err = -EFAULT; |
1810 | goto _error; | 1869 | goto _error; |
1811 | } | 1870 | } |
1812 | } else { | 1871 | } else { |
1813 | if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) { | 1872 | if (copy_to_user(buffer, &tu->queue[tu->qhead++], |
1873 | sizeof(snd_timer_read_t))) { | ||
1814 | err = -EFAULT; | 1874 | err = -EFAULT; |
1815 | goto _error; | 1875 | goto _error; |
1816 | } | 1876 | } |
@@ -1837,7 +1897,7 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait) | |||
1837 | tu = file->private_data; | 1897 | tu = file->private_data; |
1838 | 1898 | ||
1839 | poll_wait(file, &tu->qchange_sleep, wait); | 1899 | poll_wait(file, &tu->qchange_sleep, wait); |
1840 | 1900 | ||
1841 | mask = 0; | 1901 | mask = 0; |
1842 | if (tu->qused) | 1902 | if (tu->qused) |
1843 | mask |= POLLIN | POLLRDNORM; | 1903 | mask |= POLLIN | POLLRDNORM; |
@@ -1881,9 +1941,11 @@ static int __init alsa_timer_init(void) | |||
1881 | snd_info_entry_t *entry; | 1941 | snd_info_entry_t *entry; |
1882 | 1942 | ||
1883 | #ifdef SNDRV_OSS_INFO_DEV_TIMERS | 1943 | #ifdef SNDRV_OSS_INFO_DEV_TIMERS |
1884 | snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer"); | 1944 | snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, |
1945 | "system timer"); | ||
1885 | #endif | 1946 | #endif |
1886 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) { | 1947 | entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); |
1948 | if (entry != NULL) { | ||
1887 | entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128; | 1949 | entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128; |
1888 | entry->c.text.read = snd_timer_proc_read; | 1950 | entry->c.text.read = snd_timer_proc_read; |
1889 | if (snd_info_register(entry) < 0) { | 1951 | if (snd_info_register(entry) < 0) { |
@@ -1893,10 +1955,12 @@ static int __init alsa_timer_init(void) | |||
1893 | } | 1955 | } |
1894 | snd_timer_proc_entry = entry; | 1956 | snd_timer_proc_entry = entry; |
1895 | if ((err = snd_timer_register_system()) < 0) | 1957 | if ((err = snd_timer_register_system()) < 0) |
1896 | snd_printk(KERN_ERR "unable to register system timer (%i)\n", err); | 1958 | snd_printk(KERN_ERR "unable to register system timer (%i)\n", |
1959 | err); | ||
1897 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, | 1960 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, |
1898 | NULL, 0, &snd_timer_reg, "timer"))<0) | 1961 | NULL, 0, &snd_timer_reg, "timer"))<0) |
1899 | snd_printk(KERN_ERR "unable to register timer device (%i)\n", err); | 1962 | snd_printk(KERN_ERR "unable to register timer device (%i)\n", |
1963 | err); | ||
1900 | return 0; | 1964 | return 0; |
1901 | } | 1965 | } |
1902 | 1966 | ||
@@ -1907,7 +1971,7 @@ static void __exit alsa_timer_exit(void) | |||
1907 | snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0); | 1971 | snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0); |
1908 | /* unregister the system timer */ | 1972 | /* unregister the system timer */ |
1909 | list_for_each_safe(p, n, &snd_timer_list) { | 1973 | list_for_each_safe(p, n, &snd_timer_list) { |
1910 | snd_timer_t *timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); | 1974 | snd_timer_t *timer = list_entry(p, snd_timer_t, device_list); |
1911 | snd_timer_unregister(timer); | 1975 | snd_timer_unregister(timer); |
1912 | } | 1976 | } |
1913 | if (snd_timer_proc_entry) { | 1977 | if (snd_timer_proc_entry) { |