[ALSA] timers: add module refcounting for global timers
[safe/jmp/linux-2.6] / sound / core / timer.c
1 /*
2  *  Timers abstract layer
3  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4  *
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  *
20  */
21
22 #include <sound/driver.h>
23 #include <linux/delay.h>
24 #include <linux/init.h>
25 #include <linux/smp_lock.h>
26 #include <linux/slab.h>
27 #include <linux/time.h>
28 #include <linux/moduleparam.h>
29 #include <linux/string.h>
30 #include <sound/core.h>
31 #include <sound/timer.h>
32 #include <sound/control.h>
33 #include <sound/info.h>
34 #include <sound/minors.h>
35 #include <sound/initval.h>
36 #include <linux/kmod.h>
37 #ifdef CONFIG_KERNELD
38 #include <linux/kerneld.h>
39 #endif
40
41 #if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE)
42 #define DEFAULT_TIMER_LIMIT 3
43 #elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
44 #define DEFAULT_TIMER_LIMIT 2
45 #else
46 #define DEFAULT_TIMER_LIMIT 1
47 #endif
48
49 static int timer_limit = DEFAULT_TIMER_LIMIT;
50 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Takashi Iwai <tiwai@suse.de>");
51 MODULE_DESCRIPTION("ALSA timer interface");
52 MODULE_LICENSE("GPL");
53 module_param(timer_limit, int, 0444);
54 MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
55
56 typedef struct {
57         snd_timer_instance_t *timeri;
58         int tread;                      /* enhanced read with timestamps and events */
59         unsigned long ticks;
60         unsigned long overrun;
61         int qhead;
62         int qtail;
63         int qused;
64         int queue_size;
65         snd_timer_read_t *queue;
66         snd_timer_tread_t *tqueue;
67         spinlock_t qlock;
68         unsigned long last_resolution;
69         unsigned int filter;
70         struct timespec tstamp;         /* trigger tstamp */
71         wait_queue_head_t qchange_sleep;
72         struct fasync_struct *fasync;
73         struct semaphore tread_sem;
74 } snd_timer_user_t;
75
76 /* list of timers */
77 static LIST_HEAD(snd_timer_list);
78
79 /* list of slave instances */
80 static LIST_HEAD(snd_timer_slave_list);
81
82 /* lock for slave active lists */
83 static DEFINE_SPINLOCK(slave_active_lock);
84
85 static DECLARE_MUTEX(register_mutex);
86
87 static int snd_timer_free(snd_timer_t *timer);
88 static int snd_timer_dev_free(snd_device_t *device);
89 static int snd_timer_dev_register(snd_device_t *device);
90 static int snd_timer_dev_unregister(snd_device_t *device);
91
92 static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left);
93
94 /*
95  * create a timer instance with the given owner string.
96  * when timer is not NULL, increments the module counter
97  */
98 static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer)
99 {
100         snd_timer_instance_t *timeri;
101         timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
102         if (timeri == NULL)
103                 return NULL;
104         timeri->owner = kstrdup(owner, GFP_KERNEL);
105         if (! timeri->owner) {
106                 kfree(timeri);
107                 return NULL;
108         }
109         INIT_LIST_HEAD(&timeri->open_list);
110         INIT_LIST_HEAD(&timeri->active_list);
111         INIT_LIST_HEAD(&timeri->ack_list);
112         INIT_LIST_HEAD(&timeri->slave_list_head);
113         INIT_LIST_HEAD(&timeri->slave_active_head);
114
115         timeri->timer = timer;
116         if (timer && !try_module_get(timer->module)) {
117                 kfree(timeri->owner);
118                 kfree(timeri);
119                 return NULL;
120         }
121
122         return timeri;
123 }
124
125 /*
126  * find a timer instance from the given timer id
127  */
128 static snd_timer_t *snd_timer_find(snd_timer_id_t *tid)
129 {
130         snd_timer_t *timer = NULL;
131         struct list_head *p;
132
133         list_for_each(p, &snd_timer_list) {
134                 timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
135
136                 if (timer->tmr_class != tid->dev_class)
137                         continue;
138                 if ((timer->tmr_class == SNDRV_TIMER_CLASS_CARD ||
139                      timer->tmr_class == SNDRV_TIMER_CLASS_PCM) &&
140                     (timer->card == NULL ||
141                      timer->card->number != tid->card))
142                         continue;
143                 if (timer->tmr_device != tid->device)
144                         continue;
145                 if (timer->tmr_subdevice != tid->subdevice)
146                         continue;
147                 return timer;
148         }
149         return NULL;
150 }
151
152 #ifdef CONFIG_KMOD
153
154 static void snd_timer_request(snd_timer_id_t *tid)
155 {
156         if (! current->fs->root)
157                 return;
158         switch (tid->dev_class) {
159         case SNDRV_TIMER_CLASS_GLOBAL:
160                 if (tid->device < timer_limit)
161                         request_module("snd-timer-%i", tid->device);
162                 break;
163         case SNDRV_TIMER_CLASS_CARD:
164         case SNDRV_TIMER_CLASS_PCM:
165                 if (tid->card < snd_ecards_limit)
166                         request_module("snd-card-%i", tid->card);
167                 break;
168         default:
169                 break;
170         }
171 }
172
173 #endif
174
175 /*
176  * look for a master instance matching with the slave id of the given slave.
177  * when found, relink the open_link of the slave.
178  *
179  * call this with register_mutex down.
180  */
181 static void snd_timer_check_slave(snd_timer_instance_t *slave)
182 {
183         snd_timer_t *timer;
184         snd_timer_instance_t *master;
185         struct list_head *p, *q;
186
187         /* FIXME: it's really dumb to look up all entries.. */
188         list_for_each(p, &snd_timer_list) {
189                 timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
190                 list_for_each(q, &timer->open_list_head) {
191                         master = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list);
192                         if (slave->slave_class == master->slave_class &&
193                             slave->slave_id == master->slave_id) {
194                                 list_del(&slave->open_list);
195                                 list_add_tail(&slave->open_list, &master->slave_list_head);
196                                 spin_lock_irq(&slave_active_lock);
197                                 slave->master = master;
198                                 slave->timer = master->timer;
199                                 spin_unlock_irq(&slave_active_lock);
200                                 return;
201                         }
202                 }
203         }
204 }
205
206 /*
207  * look for slave instances matching with the slave id of the given master.
208  * when found, relink the open_link of slaves.
209  *
210  * call this with register_mutex down.
211  */
212 static void snd_timer_check_master(snd_timer_instance_t *master)
213 {
214         snd_timer_instance_t *slave;
215         struct list_head *p, *n;
216
217         /* check all pending slaves */
218         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);
220                 if (slave->slave_class == master->slave_class &&
221                     slave->slave_id == master->slave_id) {
222                         list_del(p);
223                         list_add_tail(p, &master->slave_list_head);
224                         spin_lock_irq(&slave_active_lock);
225                         slave->master = master;
226                         slave->timer = master->timer;
227                         if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
228                                 list_add_tail(&slave->active_list, &master->slave_active_head);
229                         spin_unlock_irq(&slave_active_lock);
230                 }
231         }
232 }
233
234 /*
235  * open a timer instance
236  * when opening a master, the slave id must be here given.
237  */
238 int snd_timer_open(snd_timer_instance_t **ti,
239                    char *owner, snd_timer_id_t *tid,
240                    unsigned int slave_id)
241 {
242         snd_timer_t *timer;
243         snd_timer_instance_t *timeri = NULL;
244         
245         if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
246                 /* open a slave instance */
247                 if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
248                     tid->dev_sclass > SNDRV_TIMER_SCLASS_OSS_SEQUENCER) {
249                         snd_printd("invalid slave class %i\n", tid->dev_sclass);
250                         return -EINVAL;
251                 }
252                 down(&register_mutex);
253                 timeri = snd_timer_instance_new(owner, NULL);
254                 if (!timeri) {
255                         up(&register_mutex);
256                         return -ENOMEM;
257                 }
258                 timeri->slave_class = tid->dev_sclass;
259                 timeri->slave_id = tid->device;
260                 timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
261                 list_add_tail(&timeri->open_list, &snd_timer_slave_list);
262                 snd_timer_check_slave(timeri);
263                 up(&register_mutex);
264                 *ti = timeri;
265                 return 0;
266         }
267
268         /* open a master instance */
269         down(&register_mutex);
270         timer = snd_timer_find(tid);
271 #ifdef CONFIG_KMOD
272         if (timer == NULL) {
273                 up(&register_mutex);
274                 snd_timer_request(tid);
275                 down(&register_mutex);
276                 timer = snd_timer_find(tid);
277         }
278 #endif
279         if (!timer) {
280                 up(&register_mutex);
281                 return -ENODEV;
282         }
283         if (!list_empty(&timer->open_list_head)) {
284                 timeri = list_entry(timer->open_list_head.next,
285                                     snd_timer_instance_t, open_list);
286                 if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
287                         up(&register_mutex);
288                         return -EBUSY;
289                 }
290         }
291         timeri = snd_timer_instance_new(owner, timer);
292         if (!timeri) {
293                 up(&register_mutex);
294                 return -ENOMEM;
295         }
296         timeri->slave_class = tid->dev_sclass;
297         timeri->slave_id = slave_id;
298         if (list_empty(&timer->open_list_head) && timer->hw.open)
299                 timer->hw.open(timer);
300         list_add_tail(&timeri->open_list, &timer->open_list_head);
301         snd_timer_check_master(timeri);
302         up(&register_mutex);
303         *ti = timeri;
304         return 0;
305 }
306
307 static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event);
308
309 /*
310  * close a timer instance
311  */
312 int snd_timer_close(snd_timer_instance_t * timeri)
313 {
314         snd_timer_t *timer = NULL;
315         struct list_head *p, *n;
316         snd_timer_instance_t *slave;
317
318         snd_assert(timeri != NULL, return -ENXIO);
319
320         /* force to stop the timer */
321         snd_timer_stop(timeri);
322
323         if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
324                 /* wait, until the active callback is finished */
325                 spin_lock_irq(&slave_active_lock);
326                 while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
327                         spin_unlock_irq(&slave_active_lock);
328                         udelay(10);
329                         spin_lock_irq(&slave_active_lock);
330                 }
331                 spin_unlock_irq(&slave_active_lock);
332                 down(&register_mutex);
333                 list_del(&timeri->open_list);
334                 up(&register_mutex);
335         } else {
336                 timer = timeri->timer;
337                 /* wait, until the active callback is finished */
338                 spin_lock_irq(&timer->lock);
339                 while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
340                         spin_unlock_irq(&timer->lock);
341                         udelay(10);
342                         spin_lock_irq(&timer->lock);
343                 }
344                 spin_unlock_irq(&timer->lock);
345                 down(&register_mutex);
346                 list_del(&timeri->open_list);
347                 if (timer && list_empty(&timer->open_list_head) && timer->hw.close)
348                         timer->hw.close(timer);
349                 /* remove slave links */
350                 list_for_each_safe(p, n, &timeri->slave_list_head) {
351                         slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
352                         spin_lock_irq(&slave_active_lock);
353                         _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
354                         list_del(p);
355                         list_add_tail(p, &snd_timer_slave_list);
356                         slave->master = NULL;
357                         slave->timer = NULL;
358                         spin_unlock_irq(&slave_active_lock);
359                 }
360                 up(&register_mutex);
361         }
362         if (timeri->private_free)
363                 timeri->private_free(timeri);
364         kfree(timeri->owner);
365         kfree(timeri);
366         if (timer)
367                 module_put(timer->module);
368         return 0;
369 }
370
371 unsigned long snd_timer_resolution(snd_timer_instance_t * timeri)
372 {
373         snd_timer_t * timer;
374
375         if (timeri == NULL)
376                 return 0;
377         if ((timer = timeri->timer) != NULL) {
378                 if (timer->hw.c_resolution)
379                         return timer->hw.c_resolution(timer);
380                 return timer->hw.resolution;
381         }
382         return 0;
383 }
384
385 static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event)
386 {
387         snd_timer_t *timer;
388         unsigned long flags;
389         unsigned long resolution = 0;
390         snd_timer_instance_t *ts;
391         struct list_head *n;
392         struct timespec tstamp;
393
394         getnstimeofday(&tstamp);
395         snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return);
396         if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE)
397                 resolution = snd_timer_resolution(ti);
398         if (ti->ccallback)
399                 ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution);
400         if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
401                 return;
402         timer = ti->timer;
403         if (timer == NULL)
404                 return;
405         if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
406                 return;
407         spin_lock_irqsave(&timer->lock, flags);
408         list_for_each(n, &ti->slave_active_head) {
409                 ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
410                 if (ts->ccallback)
411                         ts->ccallback(ti, event + 100, &tstamp, resolution);
412         }
413         spin_unlock_irqrestore(&timer->lock, flags);
414 }
415
416 static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks)
417 {
418         list_del(&timeri->active_list);
419         list_add_tail(&timeri->active_list, &timer->active_list_head);
420         if (timer->running) {
421                 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
422                         goto __start_now;
423                 timer->flags |= SNDRV_TIMER_FLG_RESCHED;
424                 timeri->flags |= SNDRV_TIMER_IFLG_START;
425                 return 1;       /* delayed start */
426         } else {
427                 timer->sticks = sticks;
428                 timer->hw.start(timer);
429               __start_now:
430                 timer->running++;
431                 timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
432                 return 0;
433         }
434 }
435
436 static int snd_timer_start_slave(snd_timer_instance_t *timeri)
437 {
438         unsigned long flags;
439
440         spin_lock_irqsave(&slave_active_lock, flags);
441         timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
442         if (timeri->master)
443                 list_add_tail(&timeri->active_list, &timeri->master->slave_active_head);
444         spin_unlock_irqrestore(&slave_active_lock, flags);
445         return 1; /* delayed start */
446 }
447
448 /*
449  *  start the timer instance
450  */ 
451 int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
452 {
453         snd_timer_t *timer;
454         int result = -EINVAL;
455         unsigned long flags;
456
457         if (timeri == NULL || ticks < 1)
458                 return -EINVAL;
459         if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
460                 result = snd_timer_start_slave(timeri);
461                 snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
462                 return result;
463         }
464         timer = timeri->timer;
465         if (timer == NULL)
466                 return -EINVAL;
467         spin_lock_irqsave(&timer->lock, flags);
468         timeri->ticks = timeri->cticks = ticks;
469         timeri->pticks = 0;
470         result = snd_timer_start1(timer, timeri, ticks);
471         spin_unlock_irqrestore(&timer->lock, flags);
472         snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START);
473         return result;
474 }
475
476 static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event)
477 {
478         snd_timer_t *timer;
479         unsigned long flags;
480
481         snd_assert(timeri != NULL, return -ENXIO);
482
483         if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) {
484                 if (!keep_flag) {
485                         spin_lock_irqsave(&slave_active_lock, flags);
486                         timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
487                         spin_unlock_irqrestore(&slave_active_lock, flags);
488                 }
489                 goto __end;
490         }
491         timer = timeri->timer;
492         if (!timer)
493                 return -EINVAL;
494         spin_lock_irqsave(&timer->lock, flags);
495         list_del_init(&timeri->ack_list);
496         list_del_init(&timeri->active_list);
497         if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
498             !(--timer->running)) {
499                 timer->hw.stop(timer);
500                 if (timer->flags & SNDRV_TIMER_FLG_RESCHED) {
501                         timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
502                         snd_timer_reschedule(timer, 0);
503                         if (timer->flags & SNDRV_TIMER_FLG_CHANGE) {
504                                 timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
505                                 timer->hw.start(timer);
506                         }
507                 }
508         }
509         if (!keep_flag)
510                 timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START);
511         spin_unlock_irqrestore(&timer->lock, flags);
512       __end:
513         if (event != SNDRV_TIMER_EVENT_RESOLUTION)
514                 snd_timer_notify1(timeri, event);
515         return 0;
516 }
517
518 /*
519  * stop the timer instance.
520  *
521  * do not call this from the timer callback!
522  */
523 int snd_timer_stop(snd_timer_instance_t * timeri)
524 {
525         snd_timer_t *timer;
526         unsigned long flags;
527         int err;
528
529         err = _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_STOP);
530         if (err < 0)
531                 return err;
532         timer = timeri->timer;
533         spin_lock_irqsave(&timer->lock, flags);
534         timeri->cticks = timeri->ticks;
535         timeri->pticks = 0;
536         spin_unlock_irqrestore(&timer->lock, flags);
537         return 0;
538 }
539
540 /*
541  * start again..  the tick is kept.
542  */
543 int snd_timer_continue(snd_timer_instance_t * timeri)
544 {
545         snd_timer_t *timer;
546         int result = -EINVAL;
547         unsigned long flags;
548
549         if (timeri == NULL)
550                 return result;
551         if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
552                 return snd_timer_start_slave(timeri);
553         timer = timeri->timer;
554         if (! timer)
555                 return -EINVAL;
556         spin_lock_irqsave(&timer->lock, flags);
557         if (!timeri->cticks)
558                 timeri->cticks = 1;
559         timeri->pticks = 0;
560         result = snd_timer_start1(timer, timeri, timer->sticks);
561         spin_unlock_irqrestore(&timer->lock, flags);
562         snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE);
563         return result;
564 }
565
566 /*
567  * pause.. remember the ticks left
568  */
569 int snd_timer_pause(snd_timer_instance_t * timeri)
570 {
571         return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
572 }
573
574 /*
575  * reschedule the timer
576  *
577  * start pending instances and check the scheduling ticks.
578  * when the scheduling ticks is changed set CHANGE flag to reprogram the timer.
579  */
580 static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left)
581 {
582         snd_timer_instance_t *ti;
583         unsigned long ticks = ~0UL;
584         struct list_head *p;
585
586         list_for_each(p, &timer->active_list_head) {
587                 ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
588                 if (ti->flags & SNDRV_TIMER_IFLG_START) {
589                         ti->flags &= ~SNDRV_TIMER_IFLG_START;
590                         ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
591                         timer->running++;
592                 }
593                 if (ti->flags & SNDRV_TIMER_IFLG_RUNNING) {
594                         if (ticks > ti->cticks)
595                                 ticks = ti->cticks;
596                 }
597         }
598         if (ticks == ~0UL) {
599                 timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
600                 return;
601         }
602         if (ticks > timer->hw.ticks)
603                 ticks = timer->hw.ticks;
604         if (ticks_left != ticks)
605                 timer->flags |= SNDRV_TIMER_FLG_CHANGE;
606         timer->sticks = ticks;
607 }
608
609 /*
610  * timer tasklet
611  *
612  */
613 static void snd_timer_tasklet(unsigned long arg)
614 {
615         snd_timer_t *timer = (snd_timer_t *) arg;
616         snd_timer_instance_t *ti;
617         struct list_head *p;
618         unsigned long resolution, ticks;
619
620         spin_lock(&timer->lock);
621         /* now process all callbacks */
622         while (!list_empty(&timer->sack_list_head)) {
623                 p = timer->sack_list_head.next;         /* get first item */
624                 ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
625
626                 /* remove from ack_list and make empty */
627                 list_del_init(p);
628                 
629                 ticks = ti->pticks;
630                 ti->pticks = 0;
631                 resolution = ti->resolution;
632
633                 ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
634                 spin_unlock(&timer->lock);
635                 if (ti->callback)
636                         ti->callback(ti, resolution, ticks);
637                 spin_lock(&timer->lock);
638                 ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
639         }
640         spin_unlock(&timer->lock);
641 }
642
643 /*
644  * timer interrupt
645  *
646  * ticks_left is usually equal to timer->sticks.
647  *
648  */
649 void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
650 {
651         snd_timer_instance_t *ti, *ts;
652         unsigned long resolution, ticks;
653         struct list_head *p, *q, *n;
654         int use_tasklet = 0;
655
656         if (timer == NULL)
657                 return;
658
659         spin_lock(&timer->lock);
660
661         /* remember the current resolution */
662         if (timer->hw.c_resolution)
663                 resolution = timer->hw.c_resolution(timer);
664         else
665                 resolution = timer->hw.resolution;
666
667         /* loop for all active instances
668          * here we cannot use list_for_each because the active_list of a processed
669          * instance is relinked to done_list_head before callback is called.
670          */
671         list_for_each_safe(p, n, &timer->active_list_head) {
672                 ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
673                 if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
674                         continue;
675                 ti->pticks += ticks_left;
676                 ti->resolution = resolution;
677                 if (ti->cticks < ticks_left)
678                         ti->cticks = 0;
679                 else
680                         ti->cticks -= ticks_left;
681                 if (ti->cticks) /* not expired */
682                         continue;
683                 if (ti->flags & SNDRV_TIMER_IFLG_AUTO) {
684                         ti->cticks = ti->ticks;
685                 } else {
686                         ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
687                         if (--timer->running)
688                                 list_del(p);
689                 }
690                 if (list_empty(&ti->ack_list)) {
691                         if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
692                             (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
693                                 list_add_tail(&ti->ack_list, &timer->ack_list_head);
694                         } else {
695                                 list_add_tail(&ti->ack_list, &timer->sack_list_head);
696                         }
697                 }
698                 list_for_each(q, &ti->slave_active_head) {
699                         ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list);
700                         ts->pticks = ti->pticks;
701                         ts->resolution = resolution;
702                         if (list_empty(&ts->ack_list)) {
703                                 if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
704                                     (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
705                                         list_add_tail(&ts->ack_list, &timer->ack_list_head);
706                                 } else {
707                                         list_add_tail(&ts->ack_list, &timer->sack_list_head);
708                                 }
709                         }
710                 }
711         }
712         if (timer->flags & SNDRV_TIMER_FLG_RESCHED)
713                 snd_timer_reschedule(timer, ticks_left);
714         if (timer->running) {
715                 if (timer->hw.flags & SNDRV_TIMER_HW_STOP) {
716                         timer->hw.stop(timer);
717                         timer->flags |= SNDRV_TIMER_FLG_CHANGE;
718                 }
719                 if (!(timer->hw.flags & SNDRV_TIMER_HW_AUTO) ||
720                     (timer->flags & SNDRV_TIMER_FLG_CHANGE)) {
721                         /* restart timer */
722                         timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
723                         timer->hw.start(timer);
724                 }
725         } else {
726                 timer->hw.stop(timer);
727         }
728
729         /* now process all fast callbacks */
730         while (!list_empty(&timer->ack_list_head)) {
731                 p = timer->ack_list_head.next;          /* get first item */
732                 ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
733                 
734                 /* remove from ack_list and make empty */
735                 list_del_init(p);
736                 
737                 ticks = ti->pticks;
738                 ti->pticks = 0;
739
740                 ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
741                 spin_unlock(&timer->lock);
742                 if (ti->callback)
743                         ti->callback(ti, resolution, ticks);
744                 spin_lock(&timer->lock);
745                 ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
746         }
747
748         /* do we have any slow callbacks? */
749         use_tasklet = !list_empty(&timer->sack_list_head);
750         spin_unlock(&timer->lock);
751
752         if (use_tasklet)
753                 tasklet_hi_schedule(&timer->task_queue);
754 }
755
756 /*
757
758  */
759
760 int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer)
761 {
762         snd_timer_t *timer;
763         int err;
764         static snd_device_ops_t ops = {
765                 .dev_free = snd_timer_dev_free,
766                 .dev_register = snd_timer_dev_register,
767                 .dev_unregister = snd_timer_dev_unregister
768         };
769
770         snd_assert(tid != NULL, return -EINVAL);
771         snd_assert(rtimer != NULL, return -EINVAL);
772         *rtimer = NULL;
773         timer = kzalloc(sizeof(*timer), GFP_KERNEL);
774         if (timer == NULL)
775                 return -ENOMEM;
776         timer->tmr_class = tid->dev_class;
777         timer->card = card;
778         timer->tmr_device = tid->device;
779         timer->tmr_subdevice = tid->subdevice;
780         if (id)
781                 strlcpy(timer->id, id, sizeof(timer->id));
782         INIT_LIST_HEAD(&timer->device_list);
783         INIT_LIST_HEAD(&timer->open_list_head);
784         INIT_LIST_HEAD(&timer->active_list_head);
785         INIT_LIST_HEAD(&timer->ack_list_head);
786         INIT_LIST_HEAD(&timer->sack_list_head);
787         spin_lock_init(&timer->lock);
788         tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer);
789         if (card != NULL) {
790                 timer->module = card->module;
791                 if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) {
792                         snd_timer_free(timer);
793                         return err;
794                 }
795         }
796         *rtimer = timer;
797         return 0;
798 }
799
800 static int snd_timer_free(snd_timer_t *timer)
801 {
802         snd_assert(timer != NULL, return -ENXIO);
803         if (timer->private_free)
804                 timer->private_free(timer);
805         kfree(timer);
806         return 0;
807 }
808
809 static int snd_timer_dev_free(snd_device_t *device)
810 {
811         snd_timer_t *timer = device->device_data;
812         return snd_timer_free(timer);
813 }
814
815 static int snd_timer_dev_register(snd_device_t *dev)
816 {
817         snd_timer_t *timer = dev->device_data;
818         snd_timer_t *timer1;
819         struct list_head *p;
820
821         snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO);
822         if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
823             !timer->hw.resolution && timer->hw.c_resolution == NULL)
824                 return -EINVAL;
825
826         down(&register_mutex);
827         list_for_each(p, &snd_timer_list) {
828                 timer1 = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
829                 if (timer1->tmr_class > timer->tmr_class)
830                         break;
831                 if (timer1->tmr_class < timer->tmr_class)
832                         continue;
833                 if (timer1->card && timer->card) {
834                         if (timer1->card->number > timer->card->number)
835                                 break;
836                         if (timer1->card->number < timer->card->number)
837                                 continue;
838                 }
839                 if (timer1->tmr_device > timer->tmr_device)
840                         break;
841                 if (timer1->tmr_device < timer->tmr_device)
842                         continue;
843                 if (timer1->tmr_subdevice > timer->tmr_subdevice)
844                         break;
845                 if (timer1->tmr_subdevice < timer->tmr_subdevice)
846                         continue;
847                 /* conflicts.. */
848                 up(&register_mutex);
849                 return -EBUSY;
850         }
851         list_add_tail(&timer->device_list, p);
852         up(&register_mutex);
853         return 0;
854 }
855
856 static int snd_timer_unregister(snd_timer_t *timer)
857 {
858         struct list_head *p, *n;
859         snd_timer_instance_t *ti;
860
861         snd_assert(timer != NULL, return -ENXIO);
862         down(&register_mutex);
863         if (! list_empty(&timer->open_list_head)) {
864                 snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
865                 list_for_each_safe(p, n, &timer->open_list_head) {
866                         list_del_init(p);
867                         ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
868                         ti->timer = NULL;
869                 }
870         }
871         list_del(&timer->device_list);
872         up(&register_mutex);
873         return snd_timer_free(timer);
874 }
875
876 static int snd_timer_dev_unregister(snd_device_t *device)
877 {
878         snd_timer_t *timer = device->device_data;
879         return snd_timer_unregister(timer);
880 }
881
882 void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp)
883 {
884         unsigned long flags;
885         unsigned long resolution = 0;
886         snd_timer_instance_t *ti, *ts;
887         struct list_head *p, *n;
888
889         if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
890                 return;
891         snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return);
892         spin_lock_irqsave(&timer->lock, flags);
893         if (event == SNDRV_TIMER_EVENT_MSTART ||
894             event == SNDRV_TIMER_EVENT_MCONTINUE ||
895             event == SNDRV_TIMER_EVENT_MRESUME) {
896                 if (timer->hw.c_resolution)
897                         resolution = timer->hw.c_resolution(timer);
898                 else
899                         resolution = timer->hw.resolution;
900         }
901         list_for_each(p, &timer->active_list_head) {
902                 ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
903                 if (ti->ccallback)
904                         ti->ccallback(ti, event, tstamp, resolution);
905                 list_for_each(n, &ti->slave_active_head) {
906                         ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
907                         if (ts->ccallback)
908                                 ts->ccallback(ts, event, tstamp, resolution);
909                 }
910         }
911         spin_unlock_irqrestore(&timer->lock, flags);
912 }
913
914 /*
915  * exported functions for global timers
916  */
917 int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer)
918 {
919         snd_timer_id_t tid;
920         
921         tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
922         tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
923         tid.card = -1;
924         tid.device = device;
925         tid.subdevice = 0;
926         return snd_timer_new(NULL, id, &tid, rtimer);
927 }
928
929 int snd_timer_global_free(snd_timer_t *timer)
930 {
931         return snd_timer_free(timer);
932 }
933
934 int snd_timer_global_register(snd_timer_t *timer)
935 {
936         snd_device_t dev;
937
938         memset(&dev, 0, sizeof(dev));
939         dev.device_data = timer;
940         return snd_timer_dev_register(&dev);
941 }
942
943 int snd_timer_global_unregister(snd_timer_t *timer)
944 {
945         return snd_timer_unregister(timer);
946 }
947
948 /* 
949  *  System timer
950  */
951
952 struct snd_timer_system_private {
953         struct timer_list tlist;
954         struct timer * timer;
955         unsigned long last_expires;
956         unsigned long last_jiffies;
957         unsigned long correction;
958 };
959
960 static void snd_timer_s_function(unsigned long data)
961 {
962         snd_timer_t *timer = (snd_timer_t *)data;
963         struct snd_timer_system_private *priv = timer->private_data;
964         unsigned long jiff = jiffies;
965         if (time_after(jiff, priv->last_expires))
966                 priv->correction = (long)jiff - (long)priv->last_expires;
967         snd_timer_interrupt(timer, (long)jiff - (long)priv->last_jiffies);
968 }
969
970 static int snd_timer_s_start(snd_timer_t * timer)
971 {
972         struct snd_timer_system_private *priv;
973         unsigned long njiff;
974
975         priv = (struct snd_timer_system_private *) timer->private_data;
976         njiff = (priv->last_jiffies = jiffies);
977         if (priv->correction > timer->sticks - 1) {
978                 priv->correction -= timer->sticks - 1;
979                 njiff++;
980         } else {
981                 njiff += timer->sticks - priv->correction;
982                 priv->correction -= timer->sticks;
983         }
984         priv->last_expires = priv->tlist.expires = njiff;
985         add_timer(&priv->tlist);
986         return 0;
987 }
988
989 static int snd_timer_s_stop(snd_timer_t * timer)
990 {
991         struct snd_timer_system_private *priv;
992         unsigned long jiff;
993
994         priv = (struct snd_timer_system_private *) timer->private_data;
995         del_timer(&priv->tlist);
996         jiff = jiffies;
997         if (time_before(jiff, priv->last_expires))
998                 timer->sticks = priv->last_expires - jiff;
999         else
1000                 timer->sticks = 1;
1001         return 0;
1002 }
1003
1004 static struct _snd_timer_hardware snd_timer_system =
1005 {
1006         .flags =        SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
1007         .resolution =   1000000000L / HZ,
1008         .ticks =        10000000L,
1009         .start =        snd_timer_s_start,
1010         .stop =         snd_timer_s_stop
1011 };
1012
1013 static void snd_timer_free_system(snd_timer_t *timer)
1014 {
1015         kfree(timer->private_data);
1016 }
1017
1018 static int snd_timer_register_system(void)
1019 {
1020         snd_timer_t *timer;
1021         struct snd_timer_system_private *priv;
1022         int err;
1023
1024         if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0)
1025                 return err;
1026         strcpy(timer->name, "system timer");
1027         timer->hw = snd_timer_system;
1028         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1029         if (priv == NULL) {
1030                 snd_timer_free(timer);
1031                 return -ENOMEM;
1032         }
1033         init_timer(&priv->tlist);
1034         priv->tlist.function = snd_timer_s_function;
1035         priv->tlist.data = (unsigned long) timer;
1036         timer->private_data = priv;
1037         timer->private_free = snd_timer_free_system;
1038         return snd_timer_global_register(timer);
1039 }
1040
1041 /*
1042  *  Info interface
1043  */
1044
1045 static void snd_timer_proc_read(snd_info_entry_t *entry,
1046                                 snd_info_buffer_t * buffer)
1047 {
1048         unsigned long flags;
1049         snd_timer_t *timer;
1050         snd_timer_instance_t *ti;
1051         struct list_head *p, *q;
1052
1053         down(&register_mutex);
1054         list_for_each(p, &snd_timer_list) {
1055                 timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
1056                 switch (timer->tmr_class) {
1057                 case SNDRV_TIMER_CLASS_GLOBAL:
1058                         snd_iprintf(buffer, "G%i: ", timer->tmr_device);
1059                         break;
1060                 case SNDRV_TIMER_CLASS_CARD:
1061                         snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device);
1062                         break;
1063                 case SNDRV_TIMER_CLASS_PCM:
1064                         snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice);
1065                         break;
1066                 default:
1067                         snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice);
1068                 }
1069                 snd_iprintf(buffer, "%s :", timer->name);
1070                 if (timer->hw.resolution)
1071                         snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks);
1072                 if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
1073                         snd_iprintf(buffer, " SLAVE");
1074                 snd_iprintf(buffer, "\n");
1075                 spin_lock_irqsave(&timer->lock, flags);
1076                 list_for_each(q, &timer->open_list_head) {
1077                         ti = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list);
1078                         snd_iprintf(buffer, "  Client %s : %s : lost interrupts %li\n",
1079                                         ti->owner ? ti->owner : "unknown",
1080                                         ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped",
1081                                         ti->lost);
1082                 }
1083                 spin_unlock_irqrestore(&timer->lock, flags);
1084         }
1085         up(&register_mutex);
1086 }
1087
1088 /*
1089  *  USER SPACE interface
1090  */
1091
1092 static void snd_timer_user_interrupt(snd_timer_instance_t *timeri,
1093                                      unsigned long resolution,
1094                                      unsigned long ticks)
1095 {
1096         snd_timer_user_t *tu = timeri->callback_data;
1097         snd_timer_read_t *r;
1098         int prev;
1099         
1100         spin_lock(&tu->qlock);
1101         if (tu->qused > 0) {
1102                 prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
1103                 r = &tu->queue[prev];
1104                 if (r->resolution == resolution) {
1105                         r->ticks += ticks;
1106                         goto __wake;
1107                 }
1108         }
1109         if (tu->qused >= tu->queue_size) {
1110                 tu->overrun++;
1111         } else {
1112                 r = &tu->queue[tu->qtail++];
1113                 tu->qtail %= tu->queue_size;
1114                 r->resolution = resolution;
1115                 r->ticks = ticks;
1116                 tu->qused++;
1117         }
1118       __wake:
1119         spin_unlock(&tu->qlock);
1120         kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1121         wake_up(&tu->qchange_sleep);
1122 }
1123
1124 static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread)
1125 {
1126         if (tu->qused >= tu->queue_size) {
1127                 tu->overrun++;
1128         } else {
1129                 memcpy(&tu->tqueue[tu->qtail++], tread, sizeof(*tread));
1130                 tu->qtail %= tu->queue_size;
1131                 tu->qused++;
1132         }
1133 }
1134
1135 static void snd_timer_user_ccallback(snd_timer_instance_t *timeri,
1136                                      enum sndrv_timer_event event,
1137                                      struct timespec *tstamp,
1138                                      unsigned long resolution)
1139 {
1140         snd_timer_user_t *tu = timeri->callback_data;
1141         snd_timer_tread_t r1;
1142
1143         if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE)
1144                 tu->tstamp = *tstamp;
1145         if ((tu->filter & (1 << event)) == 0 || !tu->tread)
1146                 return;
1147         r1.event = event;
1148         r1.tstamp = *tstamp;
1149         r1.val = resolution;
1150         spin_lock(&tu->qlock);
1151         snd_timer_user_append_to_tqueue(tu, &r1);
1152         spin_unlock(&tu->qlock);
1153         kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1154         wake_up(&tu->qchange_sleep);
1155 }
1156
1157 static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
1158                                       unsigned long resolution,
1159                                       unsigned long ticks)
1160 {
1161         snd_timer_user_t *tu = timeri->callback_data;
1162         snd_timer_tread_t *r, r1;
1163         struct timespec tstamp;
1164         int prev, append = 0;
1165
1166         memset(&tstamp, 0, sizeof(tstamp));
1167         spin_lock(&tu->qlock);
1168         if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
1169                 spin_unlock(&tu->qlock);
1170                 return;
1171         }
1172         if (tu->last_resolution != resolution || ticks > 0)
1173                 getnstimeofday(&tstamp);
1174         if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) {
1175                 r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
1176                 r1.tstamp = tstamp;
1177                 r1.val = resolution;
1178                 snd_timer_user_append_to_tqueue(tu, &r1);
1179                 tu->last_resolution = resolution;
1180                 append++;
1181         }
1182         if ((tu->filter & (1 << SNDRV_TIMER_EVENT_TICK)) == 0)
1183                 goto __wake;
1184         if (ticks == 0)
1185                 goto __wake;
1186         if (tu->qused > 0) {
1187                 prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
1188                 r = &tu->tqueue[prev];
1189                 if (r->event == SNDRV_TIMER_EVENT_TICK) {
1190                         r->tstamp = tstamp;
1191                         r->val += ticks;
1192                         append++;
1193                         goto __wake;
1194                 }
1195         }
1196         r1.event = SNDRV_TIMER_EVENT_TICK;
1197         r1.tstamp = tstamp;
1198         r1.val = ticks;
1199         snd_timer_user_append_to_tqueue(tu, &r1);
1200         append++;
1201       __wake:
1202         spin_unlock(&tu->qlock);
1203         if (append == 0)
1204                 return;
1205         kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1206         wake_up(&tu->qchange_sleep);
1207 }
1208
1209 static int snd_timer_user_open(struct inode *inode, struct file *file)
1210 {
1211         snd_timer_user_t *tu;
1212         
1213         tu = kzalloc(sizeof(*tu), GFP_KERNEL);
1214         if (tu == NULL)
1215                 return -ENOMEM;
1216         spin_lock_init(&tu->qlock);
1217         init_waitqueue_head(&tu->qchange_sleep);
1218         init_MUTEX(&tu->tread_sem);
1219         tu->ticks = 1;
1220         tu->queue_size = 128;
1221         tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
1222         if (tu->queue == NULL) {
1223                 kfree(tu);
1224                 return -ENOMEM;
1225         }
1226         file->private_data = tu;
1227         return 0;
1228 }
1229
1230 static int snd_timer_user_release(struct inode *inode, struct file *file)
1231 {
1232         snd_timer_user_t *tu;
1233
1234         if (file->private_data) {
1235                 tu = file->private_data;
1236                 file->private_data = NULL;
1237                 fasync_helper(-1, file, 0, &tu->fasync);
1238                 if (tu->timeri)
1239                         snd_timer_close(tu->timeri);
1240                 kfree(tu->queue);
1241                 kfree(tu->tqueue);
1242                 kfree(tu);
1243         }
1244         return 0;
1245 }
1246
1247 static void snd_timer_user_zero_id(snd_timer_id_t *id)
1248 {
1249         id->dev_class = SNDRV_TIMER_CLASS_NONE;
1250         id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1251         id->card = -1;
1252         id->device = -1;
1253         id->subdevice = -1;
1254 }
1255
1256 static void snd_timer_user_copy_id(snd_timer_id_t *id, snd_timer_t *timer)
1257 {
1258         id->dev_class = timer->tmr_class;
1259         id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1260         id->card = timer->card ? timer->card->number : -1;
1261         id->device = timer->tmr_device;
1262         id->subdevice = timer->tmr_subdevice;
1263 }
1264
1265 static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
1266 {
1267         snd_timer_id_t id;
1268         snd_timer_t *timer;
1269         struct list_head *p;
1270         
1271         if (copy_from_user(&id, _tid, sizeof(id)))
1272                 return -EFAULT;
1273         down(&register_mutex);
1274         if (id.dev_class < 0) {         /* first item */
1275                 if (list_empty(&snd_timer_list))
1276                         snd_timer_user_zero_id(&id);
1277                 else {
1278                         timer = (snd_timer_t *)list_entry(snd_timer_list.next, snd_timer_t, device_list);
1279                         snd_timer_user_copy_id(&id, timer);
1280                 }
1281         } else {
1282                 switch (id.dev_class) {
1283                 case SNDRV_TIMER_CLASS_GLOBAL:
1284                         id.device = id.device < 0 ? 0 : id.device + 1;
1285                         list_for_each(p, &snd_timer_list) {
1286                                 timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
1287                                 if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
1288                                         snd_timer_user_copy_id(&id, timer);
1289                                         break;
1290                                 }
1291                                 if (timer->tmr_device >= id.device) {
1292                                         snd_timer_user_copy_id(&id, timer);
1293                                         break;
1294                                 }
1295                         }
1296                         if (p == &snd_timer_list)
1297                                 snd_timer_user_zero_id(&id);
1298                         break;
1299                 case SNDRV_TIMER_CLASS_CARD:
1300                 case SNDRV_TIMER_CLASS_PCM:
1301                         if (id.card < 0) {
1302                                 id.card = 0;
1303                         } else {
1304                                 if (id.card < 0) {
1305                                         id.card = 0;
1306                                 } else {
1307                                         if (id.device < 0) {
1308                                                 id.device = 0;
1309                                         } else {
1310                                                 id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1;
1311                                         }
1312                                 }
1313                         }
1314                         list_for_each(p, &snd_timer_list) {
1315                                 timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
1316                                 if (timer->tmr_class > id.dev_class) {
1317                                         snd_timer_user_copy_id(&id, timer);
1318                                         break;
1319                                 }
1320                                 if (timer->tmr_class < id.dev_class)
1321                                         continue;
1322                                 if (timer->card->number > id.card) {
1323                                         snd_timer_user_copy_id(&id, timer);
1324                                         break;
1325                                 }
1326                                 if (timer->card->number < id.card)
1327                                         continue;
1328                                 if (timer->tmr_device > id.device) {
1329                                         snd_timer_user_copy_id(&id, timer);
1330                                         break;
1331                                 }
1332                                 if (timer->tmr_device < id.device)
1333                                         continue;
1334                                 if (timer->tmr_subdevice > id.subdevice) {
1335                                         snd_timer_user_copy_id(&id, timer);
1336                                         break;
1337                                 }
1338                                 if (timer->tmr_subdevice < id.subdevice)
1339                                         continue;
1340                                 snd_timer_user_copy_id(&id, timer);
1341                                 break;
1342                         }
1343                         if (p == &snd_timer_list)
1344                                 snd_timer_user_zero_id(&id);
1345                         break;
1346                 default:
1347                         snd_timer_user_zero_id(&id);
1348                 }
1349         }
1350         up(&register_mutex);
1351         if (copy_to_user(_tid, &id, sizeof(*_tid)))
1352                 return -EFAULT;
1353         return 0;
1354
1355
1356 static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo)
1357 {
1358         snd_timer_ginfo_t *ginfo;
1359         snd_timer_id_t tid;
1360         snd_timer_t *t;
1361         struct list_head *p;
1362         int err = 0;
1363
1364         ginfo = kmalloc(sizeof(*ginfo), GFP_KERNEL);
1365         if (! ginfo)
1366                 return -ENOMEM;
1367         if (copy_from_user(ginfo, _ginfo, sizeof(*ginfo))) {
1368                 kfree(ginfo);
1369                 return -EFAULT;
1370         }
1371         tid = ginfo->tid;
1372         memset(ginfo, 0, sizeof(*ginfo));
1373         ginfo->tid = tid;
1374         down(&register_mutex);
1375         t = snd_timer_find(&tid);
1376         if (t != NULL) {
1377                 ginfo->card = t->card ? t->card->number : -1;
1378                 if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
1379                         ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
1380                 strlcpy(ginfo->id, t->id, sizeof(ginfo->id));
1381                 strlcpy(ginfo->name, t->name, sizeof(ginfo->name));
1382                 ginfo->resolution = t->hw.resolution;
1383                 if (t->hw.resolution_min > 0) {
1384                         ginfo->resolution_min = t->hw.resolution_min;
1385                         ginfo->resolution_max = t->hw.resolution_max;
1386                 }
1387                 list_for_each(p, &t->open_list_head) {
1388                         ginfo->clients++;
1389                 }
1390         } else {
1391                 err = -ENODEV;
1392         }
1393         up(&register_mutex);
1394         if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
1395                 err = -EFAULT;
1396         kfree(ginfo);
1397         return err;
1398 }
1399
1400 static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams)
1401 {
1402         snd_timer_gparams_t gparams;
1403         snd_timer_t *t;
1404         int err;
1405
1406         if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
1407                 return -EFAULT;
1408         down(&register_mutex);
1409         t = snd_timer_find(&gparams.tid);
1410         if (t != NULL) {
1411                 if (list_empty(&t->open_list_head)) {
1412                         if (t->hw.set_period)
1413                                 err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
1414                         else
1415                                 err = -ENOSYS;
1416                 } else {
1417                         err = -EBUSY;
1418                 }
1419         } else {
1420                 err = -ENODEV;
1421         }
1422         up(&register_mutex);
1423         return err;
1424 }
1425
1426 static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus)
1427 {
1428         snd_timer_gstatus_t gstatus;
1429         snd_timer_id_t tid;
1430         snd_timer_t *t;
1431         int err = 0;
1432
1433         if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus)))
1434                 return -EFAULT;
1435         tid = gstatus.tid;
1436         memset(&gstatus, 0, sizeof(gstatus));
1437         gstatus.tid = tid;
1438         down(&register_mutex);
1439         t = snd_timer_find(&tid);
1440         if (t != NULL) {
1441                 if (t->hw.c_resolution)
1442                         gstatus.resolution = t->hw.c_resolution(t);
1443                 else
1444                         gstatus.resolution = t->hw.resolution;
1445                 if (t->hw.precise_resolution) {
1446                         t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den);
1447                 } else {
1448                         gstatus.resolution_num = gstatus.resolution;
1449                         gstatus.resolution_den = 1000000000uL;
1450                 }
1451         } else {
1452                 err = -ENODEV;
1453         }
1454         up(&register_mutex);
1455         if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
1456                 err = -EFAULT;
1457         return err;
1458 }
1459
1460 static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect)
1461 {
1462         snd_timer_user_t *tu;
1463         snd_timer_select_t tselect;
1464         char str[32];
1465         int err = 0;
1466         
1467         tu = file->private_data;
1468         down(&tu->tread_sem);
1469         if (tu->timeri) {
1470                 snd_timer_close(tu->timeri);
1471                 tu->timeri = NULL;
1472         }
1473         if (copy_from_user(&tselect, _tselect, sizeof(tselect))) {
1474                 err = -EFAULT;
1475                 goto __err;
1476         }
1477         sprintf(str, "application %i", current->pid);
1478         if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
1479                 tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
1480         if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0)
1481                 goto __err;
1482
1483         kfree(tu->queue);
1484         tu->queue = NULL;
1485         kfree(tu->tqueue);
1486         tu->tqueue = NULL;
1487         if (tu->tread) {
1488                 tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
1489                 if (tu->tqueue == NULL)
1490                         err = -ENOMEM;
1491         } else {
1492                 tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
1493                 if (tu->queue == NULL)
1494                         err = -ENOMEM;
1495         }
1496         
1497         if (err < 0) {
1498                 snd_timer_close(tu->timeri);
1499                 tu->timeri = NULL;
1500         } else {
1501                 tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
1502                 tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
1503                 tu->timeri->ccallback = snd_timer_user_ccallback;
1504                 tu->timeri->callback_data = (void *)tu;
1505         }
1506
1507       __err:
1508         up(&tu->tread_sem);
1509         return err;
1510 }
1511
1512 static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
1513 {
1514         snd_timer_user_t *tu;
1515         snd_timer_info_t *info;
1516         snd_timer_t *t;
1517         int err = 0;
1518
1519         tu = file->private_data;
1520         snd_assert(tu->timeri != NULL, return -ENXIO);
1521         t = tu->timeri->timer;
1522         snd_assert(t != NULL, return -ENXIO);
1523
1524         info = kzalloc(sizeof(*info), GFP_KERNEL);
1525         if (! info)
1526                 return -ENOMEM;
1527         info->card = t->card ? t->card->number : -1;
1528         if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
1529                 info->flags |= SNDRV_TIMER_FLG_SLAVE;
1530         strlcpy(info->id, t->id, sizeof(info->id));
1531         strlcpy(info->name, t->name, sizeof(info->name));
1532         info->resolution = t->hw.resolution;
1533         if (copy_to_user(_info, info, sizeof(*_info)))
1534                 err = -EFAULT;
1535         kfree(info);
1536         return err;
1537 }
1538
1539 static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params)
1540 {
1541         snd_timer_user_t *tu;
1542         snd_timer_params_t params;
1543         snd_timer_t *t;
1544         snd_timer_read_t *tr;
1545         snd_timer_tread_t *ttr;
1546         int err;
1547         
1548         tu = file->private_data;
1549         snd_assert(tu->timeri != NULL, return -ENXIO);
1550         t = tu->timeri->timer;
1551         snd_assert(t != NULL, return -ENXIO);
1552         if (copy_from_user(&params, _params, sizeof(params)))
1553                 return -EFAULT;
1554         if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) {
1555                 err = -EINVAL;
1556                 goto _end;
1557         }
1558         if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) {
1559                 err = -EINVAL;
1560                 goto _end;
1561         }
1562         if (params.filter & ~((1<<SNDRV_TIMER_EVENT_RESOLUTION)|
1563                               (1<<SNDRV_TIMER_EVENT_TICK)|
1564                               (1<<SNDRV_TIMER_EVENT_START)|
1565                               (1<<SNDRV_TIMER_EVENT_STOP)|
1566                               (1<<SNDRV_TIMER_EVENT_CONTINUE)|
1567                               (1<<SNDRV_TIMER_EVENT_PAUSE)|
1568                               (1<<SNDRV_TIMER_EVENT_SUSPEND)|
1569                               (1<<SNDRV_TIMER_EVENT_RESUME)|
1570                               (1<<SNDRV_TIMER_EVENT_MSTART)|
1571                               (1<<SNDRV_TIMER_EVENT_MSTOP)|
1572                               (1<<SNDRV_TIMER_EVENT_MCONTINUE)|
1573                               (1<<SNDRV_TIMER_EVENT_MPAUSE)|
1574                               (1<<SNDRV_TIMER_EVENT_MSUSPEND)|
1575                               (1<<SNDRV_TIMER_EVENT_MRESUME))) {
1576                 err = -EINVAL;
1577                 goto _end;
1578         }
1579         snd_timer_stop(tu->timeri);
1580         spin_lock_irq(&t->lock);
1581         tu->timeri->flags &= ~(SNDRV_TIMER_IFLG_AUTO|
1582                                SNDRV_TIMER_IFLG_EXCLUSIVE|
1583                                SNDRV_TIMER_IFLG_EARLY_EVENT);
1584         if (params.flags & SNDRV_TIMER_PSFLG_AUTO)
1585                 tu->timeri->flags |= SNDRV_TIMER_IFLG_AUTO;
1586         if (params.flags & SNDRV_TIMER_PSFLG_EXCLUSIVE)
1587                 tu->timeri->flags |= SNDRV_TIMER_IFLG_EXCLUSIVE;
1588         if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT)
1589                 tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT;
1590         spin_unlock_irq(&t->lock);
1591         if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) {
1592                 if (tu->tread) {
1593                         ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
1594                         if (ttr) {
1595                                 kfree(tu->tqueue);
1596                                 tu->queue_size = params.queue_size;
1597                                 tu->tqueue = ttr;
1598                         }
1599                 } else {
1600                         tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
1601                         if (tr) {
1602                                 kfree(tu->queue);
1603                                 tu->queue_size = params.queue_size;
1604                                 tu->queue = tr;
1605                         }
1606                 }
1607         }
1608         tu->qhead = tu->qtail = tu->qused = 0;
1609         if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
1610                 if (tu->tread) {
1611                         snd_timer_tread_t tread;
1612                         tread.event = SNDRV_TIMER_EVENT_EARLY;
1613                         tread.tstamp.tv_sec = 0;
1614                         tread.tstamp.tv_nsec = 0;
1615                         tread.val = 0;
1616                         snd_timer_user_append_to_tqueue(tu, &tread);
1617                 } else {
1618                         snd_timer_read_t *r = &tu->queue[0];
1619                         r->resolution = 0;
1620                         r->ticks = 0;
1621                         tu->qused++;
1622                         tu->qtail++;
1623                 }
1624                 
1625         }
1626         tu->filter = params.filter;
1627         tu->ticks = params.ticks;
1628         err = 0;
1629  _end:
1630         if (copy_to_user(_params, &params, sizeof(params)))
1631                 return -EFAULT;
1632         return err;
1633 }
1634
1635 static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status)
1636 {
1637         snd_timer_user_t *tu;
1638         snd_timer_status_t status;
1639         
1640         tu = file->private_data;
1641         snd_assert(tu->timeri != NULL, return -ENXIO);
1642         memset(&status, 0, sizeof(status));
1643         status.tstamp = tu->tstamp;
1644         status.resolution = snd_timer_resolution(tu->timeri);
1645         status.lost = tu->timeri->lost;
1646         status.overrun = tu->overrun;
1647         spin_lock_irq(&tu->qlock);
1648         status.queue = tu->qused;
1649         spin_unlock_irq(&tu->qlock);
1650         if (copy_to_user(_status, &status, sizeof(status)))
1651                 return -EFAULT;
1652         return 0;
1653 }
1654
1655 static int snd_timer_user_start(struct file *file)
1656 {
1657         int err;
1658         snd_timer_user_t *tu;
1659                 
1660         tu = file->private_data;
1661         snd_assert(tu->timeri != NULL, return -ENXIO);
1662         snd_timer_stop(tu->timeri);
1663         tu->timeri->lost = 0;
1664         tu->last_resolution = 0;
1665         return (err = snd_timer_start(tu->timeri, tu->ticks)) < 0 ? err : 0;
1666 }
1667
1668 static int snd_timer_user_stop(struct file *file)
1669 {
1670         int err;
1671         snd_timer_user_t *tu;
1672                 
1673         tu = file->private_data;
1674         snd_assert(tu->timeri != NULL, return -ENXIO);
1675         return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0;
1676 }
1677
1678 static int snd_timer_user_continue(struct file *file)
1679 {
1680         int err;
1681         snd_timer_user_t *tu;
1682                 
1683         tu = file->private_data;
1684         snd_assert(tu->timeri != NULL, return -ENXIO);
1685         tu->timeri->lost = 0;
1686         return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
1687 }
1688
1689 static int snd_timer_user_pause(struct file *file)
1690 {
1691         int err;
1692         snd_timer_user_t *tu;
1693                 
1694         tu = file->private_data;
1695         snd_assert(tu->timeri != NULL, return -ENXIO);
1696         return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
1697 }
1698
1699 enum {
1700         SNDRV_TIMER_IOCTL_START_OLD = _IO('T', 0x20),
1701         SNDRV_TIMER_IOCTL_STOP_OLD = _IO('T', 0x21),
1702         SNDRV_TIMER_IOCTL_CONTINUE_OLD = _IO('T', 0x22),
1703         SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
1704 };
1705
1706 static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1707 {
1708         snd_timer_user_t *tu;
1709         void __user *argp = (void __user *)arg;
1710         int __user *p = argp;
1711         
1712         tu = file->private_data;
1713         switch (cmd) {
1714         case SNDRV_TIMER_IOCTL_PVERSION:
1715                 return put_user(SNDRV_TIMER_VERSION, p) ? -EFAULT : 0;
1716         case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
1717                 return snd_timer_user_next_device(argp);
1718         case SNDRV_TIMER_IOCTL_TREAD:
1719         {
1720                 int xarg;
1721                 
1722                 down(&tu->tread_sem);
1723                 if (tu->timeri) {       /* too late */
1724                         up(&tu->tread_sem);
1725                         return -EBUSY;
1726                 }
1727                 if (get_user(xarg, p)) {
1728                         up(&tu->tread_sem);
1729                         return -EFAULT;
1730                 }
1731                 tu->tread = xarg ? 1 : 0;
1732                 up(&tu->tread_sem);
1733                 return 0;
1734         }
1735         case SNDRV_TIMER_IOCTL_GINFO:
1736                 return snd_timer_user_ginfo(file, argp);
1737         case SNDRV_TIMER_IOCTL_GPARAMS:
1738                 return snd_timer_user_gparams(file, argp);
1739         case SNDRV_TIMER_IOCTL_GSTATUS:
1740                 return snd_timer_user_gstatus(file, argp);
1741         case SNDRV_TIMER_IOCTL_SELECT:
1742                 return snd_timer_user_tselect(file, argp);
1743         case SNDRV_TIMER_IOCTL_INFO:
1744                 return snd_timer_user_info(file, argp);
1745         case SNDRV_TIMER_IOCTL_PARAMS:
1746                 return snd_timer_user_params(file, argp);
1747         case SNDRV_TIMER_IOCTL_STATUS:
1748                 return snd_timer_user_status(file, argp);
1749         case SNDRV_TIMER_IOCTL_START:
1750         case SNDRV_TIMER_IOCTL_START_OLD:
1751                 return snd_timer_user_start(file);
1752         case SNDRV_TIMER_IOCTL_STOP:
1753         case SNDRV_TIMER_IOCTL_STOP_OLD:
1754                 return snd_timer_user_stop(file);
1755         case SNDRV_TIMER_IOCTL_CONTINUE:
1756         case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
1757                 return snd_timer_user_continue(file);
1758         case SNDRV_TIMER_IOCTL_PAUSE:
1759         case SNDRV_TIMER_IOCTL_PAUSE_OLD:
1760                 return snd_timer_user_pause(file);
1761         }
1762         return -ENOTTY;
1763 }
1764
1765 static int snd_timer_user_fasync(int fd, struct file * file, int on)
1766 {
1767         snd_timer_user_t *tu;
1768         int err;
1769         
1770         tu = file->private_data;
1771         err = fasync_helper(fd, file, on, &tu->fasync);
1772         if (err < 0)
1773                 return err;
1774         return 0;
1775 }
1776
1777 static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset)
1778 {
1779         snd_timer_user_t *tu;
1780         long result = 0, unit;
1781         int err = 0;
1782         
1783         tu = file->private_data;
1784         unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t);
1785         spin_lock_irq(&tu->qlock);
1786         while ((long)count - result >= unit) {
1787                 while (!tu->qused) {
1788                         wait_queue_t wait;
1789
1790                         if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
1791                                 err = -EAGAIN;
1792                                 break;
1793                         }
1794
1795                         set_current_state(TASK_INTERRUPTIBLE);
1796                         init_waitqueue_entry(&wait, current);
1797                         add_wait_queue(&tu->qchange_sleep, &wait);
1798
1799                         spin_unlock_irq(&tu->qlock);
1800                         schedule();
1801                         spin_lock_irq(&tu->qlock);
1802
1803                         remove_wait_queue(&tu->qchange_sleep, &wait);
1804
1805                         if (signal_pending(current)) {
1806                                 err = -ERESTARTSYS;
1807                                 break;
1808                         }
1809                 }
1810
1811                 spin_unlock_irq(&tu->qlock);
1812                 if (err < 0)
1813                         goto _error;
1814
1815                 if (tu->tread) {
1816                         if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) {
1817                                 err = -EFAULT;
1818                                 goto _error;
1819                         }
1820                 } else {
1821                         if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) {
1822                                 err = -EFAULT;
1823                                 goto _error;
1824                         }
1825                 }
1826
1827                 tu->qhead %= tu->queue_size;
1828
1829                 result += unit;
1830                 buffer += unit;
1831
1832                 spin_lock_irq(&tu->qlock);
1833                 tu->qused--;
1834         }
1835         spin_unlock_irq(&tu->qlock);
1836  _error:
1837         return result > 0 ? result : err;
1838 }
1839
1840 static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
1841 {
1842         unsigned int mask;
1843         snd_timer_user_t *tu;
1844
1845         tu = file->private_data;
1846
1847         poll_wait(file, &tu->qchange_sleep, wait);
1848         
1849         mask = 0;
1850         if (tu->qused)
1851                 mask |= POLLIN | POLLRDNORM;
1852
1853         return mask;
1854 }
1855
1856 #ifdef CONFIG_COMPAT
1857 #include "timer_compat.c"
1858 #else
1859 #define snd_timer_user_ioctl_compat     NULL
1860 #endif
1861
1862 static struct file_operations snd_timer_f_ops =
1863 {
1864         .owner =        THIS_MODULE,
1865         .read =         snd_timer_user_read,
1866         .open =         snd_timer_user_open,
1867         .release =      snd_timer_user_release,
1868         .poll =         snd_timer_user_poll,
1869         .unlocked_ioctl =       snd_timer_user_ioctl,
1870         .compat_ioctl = snd_timer_user_ioctl_compat,
1871         .fasync =       snd_timer_user_fasync,
1872 };
1873
1874 static snd_minor_t snd_timer_reg =
1875 {
1876         .comment =      "timer",
1877         .f_ops =        &snd_timer_f_ops,
1878 };
1879
1880 /*
1881  *  ENTRY functions
1882  */
1883
1884 static snd_info_entry_t *snd_timer_proc_entry = NULL;
1885
1886 static int __init alsa_timer_init(void)
1887 {
1888         int err;
1889         snd_info_entry_t *entry;
1890
1891 #ifdef SNDRV_OSS_INFO_DEV_TIMERS
1892         snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer");
1893 #endif
1894         if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) {
1895                 entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
1896                 entry->c.text.read = snd_timer_proc_read;
1897                 if (snd_info_register(entry) < 0) {
1898                         snd_info_free_entry(entry);
1899                         entry = NULL;
1900                 }
1901         }
1902         snd_timer_proc_entry = entry;
1903         if ((err = snd_timer_register_system()) < 0)
1904                 snd_printk(KERN_ERR "unable to register system timer (%i)\n", err);
1905         if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER,
1906                                         NULL, 0, &snd_timer_reg, "timer"))<0)
1907                 snd_printk(KERN_ERR "unable to register timer device (%i)\n", err);
1908         return 0;
1909 }
1910
1911 static void __exit alsa_timer_exit(void)
1912 {
1913         struct list_head *p, *n;
1914
1915         snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0);
1916         /* unregister the system timer */
1917         list_for_each_safe(p, n, &snd_timer_list) {
1918                 snd_timer_t *timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
1919                 snd_timer_unregister(timer);
1920         }
1921         if (snd_timer_proc_entry) {
1922                 snd_info_unregister(snd_timer_proc_entry);
1923                 snd_timer_proc_entry = NULL;
1924         }
1925 #ifdef SNDRV_OSS_INFO_DEV_TIMERS
1926         snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1);
1927 #endif
1928 }
1929
1930 module_init(alsa_timer_init)
1931 module_exit(alsa_timer_exit)
1932
1933 EXPORT_SYMBOL(snd_timer_open);
1934 EXPORT_SYMBOL(snd_timer_close);
1935 EXPORT_SYMBOL(snd_timer_resolution);
1936 EXPORT_SYMBOL(snd_timer_start);
1937 EXPORT_SYMBOL(snd_timer_stop);
1938 EXPORT_SYMBOL(snd_timer_continue);
1939 EXPORT_SYMBOL(snd_timer_pause);
1940 EXPORT_SYMBOL(snd_timer_new);
1941 EXPORT_SYMBOL(snd_timer_notify);
1942 EXPORT_SYMBOL(snd_timer_global_new);
1943 EXPORT_SYMBOL(snd_timer_global_free);
1944 EXPORT_SYMBOL(snd_timer_global_register);
1945 EXPORT_SYMBOL(snd_timer_global_unregister);
1946 EXPORT_SYMBOL(snd_timer_interrupt);