Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : /*
3 : : * Timers abstract layer
4 : : * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
5 : : */
6 : :
7 : : #include <linux/delay.h>
8 : : #include <linux/init.h>
9 : : #include <linux/slab.h>
10 : : #include <linux/time.h>
11 : : #include <linux/mutex.h>
12 : : #include <linux/device.h>
13 : : #include <linux/module.h>
14 : : #include <linux/string.h>
15 : : #include <linux/sched/signal.h>
16 : : #include <sound/core.h>
17 : : #include <sound/timer.h>
18 : : #include <sound/control.h>
19 : : #include <sound/info.h>
20 : : #include <sound/minors.h>
21 : : #include <sound/initval.h>
22 : : #include <linux/kmod.h>
23 : :
24 : : /* internal flags */
25 : : #define SNDRV_TIMER_IFLG_PAUSED 0x00010000
26 : : #define SNDRV_TIMER_IFLG_DEAD 0x00020000
27 : :
28 : : #if IS_ENABLED(CONFIG_SND_HRTIMER)
29 : : #define DEFAULT_TIMER_LIMIT 4
30 : : #else
31 : : #define DEFAULT_TIMER_LIMIT 1
32 : : #endif
33 : :
34 : : static int timer_limit = DEFAULT_TIMER_LIMIT;
35 : : static int timer_tstamp_monotonic = 1;
36 : : MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
37 : : MODULE_DESCRIPTION("ALSA timer interface");
38 : : MODULE_LICENSE("GPL");
39 : : module_param(timer_limit, int, 0444);
40 : : MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
41 : : module_param(timer_tstamp_monotonic, int, 0444);
42 : : MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
43 : :
44 : : MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER);
45 : : MODULE_ALIAS("devname:snd/timer");
46 : :
47 : : enum timer_tread_format {
48 : : TREAD_FORMAT_NONE = 0,
49 : : TREAD_FORMAT_TIME64,
50 : : TREAD_FORMAT_TIME32,
51 : : };
52 : :
53 : : struct snd_timer_tread32 {
54 : : int event;
55 : : s32 tstamp_sec;
56 : : s32 tstamp_nsec;
57 : : unsigned int val;
58 : : };
59 : :
60 : : struct snd_timer_tread64 {
61 : : int event;
62 : : u8 pad1[4];
63 : : s64 tstamp_sec;
64 : : s64 tstamp_nsec;
65 : : unsigned int val;
66 : : u8 pad2[4];
67 : : };
68 : :
69 : : struct snd_timer_user {
70 : : struct snd_timer_instance *timeri;
71 : : int tread; /* enhanced read with timestamps and events */
72 : : unsigned long ticks;
73 : : unsigned long overrun;
74 : : int qhead;
75 : : int qtail;
76 : : int qused;
77 : : int queue_size;
78 : : bool disconnected;
79 : : struct snd_timer_read *queue;
80 : : struct snd_timer_tread64 *tqueue;
81 : : spinlock_t qlock;
82 : : unsigned long last_resolution;
83 : : unsigned int filter;
84 : : struct timespec64 tstamp; /* trigger tstamp */
85 : : wait_queue_head_t qchange_sleep;
86 : : struct fasync_struct *fasync;
87 : : struct mutex ioctl_lock;
88 : : };
89 : :
90 : : struct snd_timer_status32 {
91 : : s32 tstamp_sec; /* Timestamp - last update */
92 : : s32 tstamp_nsec;
93 : : unsigned int resolution; /* current period resolution in ns */
94 : : unsigned int lost; /* counter of master tick lost */
95 : : unsigned int overrun; /* count of read queue overruns */
96 : : unsigned int queue; /* used queue size */
97 : : unsigned char reserved[64]; /* reserved */
98 : : };
99 : :
100 : : #define SNDRV_TIMER_IOCTL_STATUS32 _IOR('T', 0x14, struct snd_timer_status32)
101 : :
102 : : struct snd_timer_status64 {
103 : : s64 tstamp_sec; /* Timestamp - last update */
104 : : s64 tstamp_nsec;
105 : : unsigned int resolution; /* current period resolution in ns */
106 : : unsigned int lost; /* counter of master tick lost */
107 : : unsigned int overrun; /* count of read queue overruns */
108 : : unsigned int queue; /* used queue size */
109 : : unsigned char reserved[64]; /* reserved */
110 : : };
111 : :
112 : : #define SNDRV_TIMER_IOCTL_STATUS64 _IOR('T', 0x14, struct snd_timer_status64)
113 : :
114 : : /* list of timers */
115 : : static LIST_HEAD(snd_timer_list);
116 : :
117 : : /* list of slave instances */
118 : : static LIST_HEAD(snd_timer_slave_list);
119 : :
120 : : /* lock for slave active lists */
121 : : static DEFINE_SPINLOCK(slave_active_lock);
122 : :
123 : : #define MAX_SLAVE_INSTANCES 1000
124 : : static int num_slaves;
125 : :
126 : : static DEFINE_MUTEX(register_mutex);
127 : :
128 : : static int snd_timer_free(struct snd_timer *timer);
129 : : static int snd_timer_dev_free(struct snd_device *device);
130 : : static int snd_timer_dev_register(struct snd_device *device);
131 : : static int snd_timer_dev_disconnect(struct snd_device *device);
132 : :
133 : : static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left);
134 : :
135 : : /*
136 : : * create a timer instance with the given owner string.
137 : : */
138 : 0 : struct snd_timer_instance *snd_timer_instance_new(const char *owner)
139 : : {
140 : 0 : struct snd_timer_instance *timeri;
141 : :
142 : 0 : timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
143 [ # # ]: 0 : if (timeri == NULL)
144 : : return NULL;
145 : 0 : timeri->owner = kstrdup(owner, GFP_KERNEL);
146 [ # # ]: 0 : if (! timeri->owner) {
147 : 0 : kfree(timeri);
148 : 0 : return NULL;
149 : : }
150 : 0 : INIT_LIST_HEAD(&timeri->open_list);
151 : 0 : INIT_LIST_HEAD(&timeri->active_list);
152 : 0 : INIT_LIST_HEAD(&timeri->ack_list);
153 : 0 : INIT_LIST_HEAD(&timeri->slave_list_head);
154 : 0 : INIT_LIST_HEAD(&timeri->slave_active_head);
155 : :
156 : 0 : return timeri;
157 : : }
158 : : EXPORT_SYMBOL(snd_timer_instance_new);
159 : :
160 : 0 : void snd_timer_instance_free(struct snd_timer_instance *timeri)
161 : : {
162 [ # # ]: 0 : if (timeri) {
163 [ # # ]: 0 : if (timeri->private_free)
164 : 0 : timeri->private_free(timeri);
165 : 0 : kfree(timeri->owner);
166 : 0 : kfree(timeri);
167 : : }
168 : 0 : }
169 : : EXPORT_SYMBOL(snd_timer_instance_free);
170 : :
171 : : /*
172 : : * find a timer instance from the given timer id
173 : : */
174 : 0 : static struct snd_timer *snd_timer_find(struct snd_timer_id *tid)
175 : : {
176 : 0 : struct snd_timer *timer = NULL;
177 : :
178 [ # # ]: 0 : list_for_each_entry(timer, &snd_timer_list, device_list) {
179 [ # # ]: 0 : if (timer->tmr_class != tid->dev_class)
180 : 0 : continue;
181 [ # # ]: 0 : if ((timer->tmr_class == SNDRV_TIMER_CLASS_CARD ||
182 : 0 : timer->tmr_class == SNDRV_TIMER_CLASS_PCM) &&
183 [ # # ]: 0 : (timer->card == NULL ||
184 [ # # ]: 0 : timer->card->number != tid->card))
185 : 0 : continue;
186 [ # # ]: 0 : if (timer->tmr_device != tid->device)
187 : 0 : continue;
188 [ # # ]: 0 : if (timer->tmr_subdevice != tid->subdevice)
189 : 0 : continue;
190 : : return timer;
191 : : }
192 : : return NULL;
193 : : }
194 : :
195 : : #ifdef CONFIG_MODULES
196 : :
197 : 0 : static void snd_timer_request(struct snd_timer_id *tid)
198 : : {
199 [ # # # ]: 0 : switch (tid->dev_class) {
200 : 0 : case SNDRV_TIMER_CLASS_GLOBAL:
201 [ # # ]: 0 : if (tid->device < timer_limit)
202 : 0 : request_module("snd-timer-%i", tid->device);
203 : : break;
204 : 0 : case SNDRV_TIMER_CLASS_CARD:
205 : : case SNDRV_TIMER_CLASS_PCM:
206 [ # # ]: 0 : if (tid->card < snd_ecards_limit)
207 : 0 : request_module("snd-card-%i", tid->card);
208 : : break;
209 : : default:
210 : : break;
211 : : }
212 : 0 : }
213 : :
214 : : #endif
215 : :
216 : : /* move the slave if it belongs to the master; return 1 if match */
217 : 0 : static int check_matching_master_slave(struct snd_timer_instance *master,
218 : : struct snd_timer_instance *slave)
219 : : {
220 [ # # ]: 0 : if (slave->slave_class != master->slave_class ||
221 : : slave->slave_id != master->slave_id)
222 : : return 0;
223 [ # # ]: 0 : if (master->timer->num_instances >= master->timer->max_instances)
224 : : return -EBUSY;
225 : 0 : list_move_tail(&slave->open_list, &master->slave_list_head);
226 : 0 : master->timer->num_instances++;
227 : 0 : spin_lock_irq(&slave_active_lock);
228 : 0 : spin_lock(&master->timer->lock);
229 : 0 : slave->master = master;
230 : 0 : slave->timer = master->timer;
231 [ # # ]: 0 : if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
232 : 0 : list_add_tail(&slave->active_list, &master->slave_active_head);
233 : 0 : spin_unlock(&master->timer->lock);
234 : 0 : spin_unlock_irq(&slave_active_lock);
235 : 0 : return 1;
236 : : }
237 : :
238 : : /*
239 : : * look for a master instance matching with the slave id of the given slave.
240 : : * when found, relink the open_link of the slave.
241 : : *
242 : : * call this with register_mutex down.
243 : : */
244 : 0 : static int snd_timer_check_slave(struct snd_timer_instance *slave)
245 : : {
246 : 0 : struct snd_timer *timer;
247 : 0 : struct snd_timer_instance *master;
248 : 0 : int err = 0;
249 : :
250 : : /* FIXME: it's really dumb to look up all entries.. */
251 [ # # ]: 0 : list_for_each_entry(timer, &snd_timer_list, device_list) {
252 [ # # ]: 0 : list_for_each_entry(master, &timer->open_list_head, open_list) {
253 : 0 : err = check_matching_master_slave(master, slave);
254 [ # # ]: 0 : if (err != 0) /* match found or error */
255 : 0 : goto out;
256 : : }
257 : : }
258 : 0 : out:
259 : 0 : return err < 0 ? err : 0;
260 : : }
261 : :
262 : : /*
263 : : * look for slave instances matching with the slave id of the given master.
264 : : * when found, relink the open_link of slaves.
265 : : *
266 : : * call this with register_mutex down.
267 : : */
268 : 0 : static int snd_timer_check_master(struct snd_timer_instance *master)
269 : : {
270 : 0 : struct snd_timer_instance *slave, *tmp;
271 : 0 : int err = 0;
272 : :
273 : : /* check all pending slaves */
274 [ # # ]: 0 : list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) {
275 : 0 : err = check_matching_master_slave(master, slave);
276 [ # # ]: 0 : if (err < 0)
277 : : break;
278 : : }
279 : 0 : return err < 0 ? err : 0;
280 : : }
281 : :
282 : : static void snd_timer_close_locked(struct snd_timer_instance *timeri,
283 : : struct device **card_devp_to_put);
284 : :
285 : : /*
286 : : * open a timer instance
287 : : * when opening a master, the slave id must be here given.
288 : : */
289 : 0 : int snd_timer_open(struct snd_timer_instance *timeri,
290 : : struct snd_timer_id *tid,
291 : : unsigned int slave_id)
292 : : {
293 : 0 : struct snd_timer *timer;
294 : 0 : struct device *card_dev_to_put = NULL;
295 : 0 : int err;
296 : :
297 : 0 : mutex_lock(®ister_mutex);
298 [ # # ]: 0 : if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
299 : : /* open a slave instance */
300 [ # # ]: 0 : if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
301 : : tid->dev_sclass > SNDRV_TIMER_SCLASS_OSS_SEQUENCER) {
302 : 0 : pr_debug("ALSA: timer: invalid slave class %i\n",
303 : : tid->dev_sclass);
304 : 0 : err = -EINVAL;
305 : 0 : goto unlock;
306 : : }
307 [ # # ]: 0 : if (num_slaves >= MAX_SLAVE_INSTANCES) {
308 : 0 : err = -EBUSY;
309 : 0 : goto unlock;
310 : : }
311 : 0 : timeri->slave_class = tid->dev_sclass;
312 : 0 : timeri->slave_id = tid->device;
313 : 0 : timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
314 : 0 : list_add_tail(&timeri->open_list, &snd_timer_slave_list);
315 : 0 : num_slaves++;
316 : 0 : err = snd_timer_check_slave(timeri);
317 : 0 : goto list_added;
318 : : }
319 : :
320 : : /* open a master instance */
321 : 0 : timer = snd_timer_find(tid);
322 : : #ifdef CONFIG_MODULES
323 [ # # ]: 0 : if (!timer) {
324 : 0 : mutex_unlock(®ister_mutex);
325 : 0 : snd_timer_request(tid);
326 : 0 : mutex_lock(®ister_mutex);
327 : 0 : timer = snd_timer_find(tid);
328 : : }
329 : : #endif
330 [ # # ]: 0 : if (!timer) {
331 : 0 : err = -ENODEV;
332 : 0 : goto unlock;
333 : : }
334 [ # # ]: 0 : if (!list_empty(&timer->open_list_head)) {
335 : 0 : struct snd_timer_instance *t =
336 : 0 : list_entry(timer->open_list_head.next,
337 : : struct snd_timer_instance, open_list);
338 [ # # ]: 0 : if (t->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
339 : 0 : err = -EBUSY;
340 : 0 : goto unlock;
341 : : }
342 : : }
343 [ # # ]: 0 : if (timer->num_instances >= timer->max_instances) {
344 : 0 : err = -EBUSY;
345 : 0 : goto unlock;
346 : : }
347 [ # # ]: 0 : if (!try_module_get(timer->module)) {
348 : 0 : err = -EBUSY;
349 : 0 : goto unlock;
350 : : }
351 : : /* take a card refcount for safe disconnection */
352 [ # # ]: 0 : if (timer->card) {
353 : 0 : get_device(&timer->card->card_dev);
354 : 0 : card_dev_to_put = &timer->card->card_dev;
355 : : }
356 : :
357 [ # # # # ]: 0 : if (list_empty(&timer->open_list_head) && timer->hw.open) {
358 : 0 : err = timer->hw.open(timer);
359 [ # # ]: 0 : if (err) {
360 : 0 : module_put(timer->module);
361 : 0 : goto unlock;
362 : : }
363 : : }
364 : :
365 : 0 : timeri->timer = timer;
366 : 0 : timeri->slave_class = tid->dev_sclass;
367 : 0 : timeri->slave_id = slave_id;
368 : :
369 : 0 : list_add_tail(&timeri->open_list, &timer->open_list_head);
370 : 0 : timer->num_instances++;
371 : 0 : err = snd_timer_check_master(timeri);
372 : 0 : list_added:
373 [ # # ]: 0 : if (err < 0)
374 : 0 : snd_timer_close_locked(timeri, &card_dev_to_put);
375 : :
376 : 0 : unlock:
377 : 0 : mutex_unlock(®ister_mutex);
378 : : /* put_device() is called after unlock for avoiding deadlock */
379 [ # # # # ]: 0 : if (err < 0 && card_dev_to_put)
380 : 0 : put_device(card_dev_to_put);
381 : 0 : return err;
382 : : }
383 : : EXPORT_SYMBOL(snd_timer_open);
384 : :
385 : : /*
386 : : * close a timer instance
387 : : * call this with register_mutex down.
388 : : */
389 : 0 : static void snd_timer_close_locked(struct snd_timer_instance *timeri,
390 : : struct device **card_devp_to_put)
391 : : {
392 : 0 : struct snd_timer *timer = timeri->timer;
393 : 0 : struct snd_timer_instance *slave, *tmp;
394 : :
395 [ # # ]: 0 : if (timer) {
396 : 0 : spin_lock_irq(&timer->lock);
397 : 0 : timeri->flags |= SNDRV_TIMER_IFLG_DEAD;
398 : 0 : spin_unlock_irq(&timer->lock);
399 : : }
400 : :
401 [ # # ]: 0 : if (!list_empty(&timeri->open_list)) {
402 [ # # ]: 0 : list_del_init(&timeri->open_list);
403 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
404 : 0 : num_slaves--;
405 : : }
406 : :
407 : : /* force to stop the timer */
408 : 0 : snd_timer_stop(timeri);
409 : :
410 [ # # ]: 0 : if (timer) {
411 : 0 : timer->num_instances--;
412 : : /* wait, until the active callback is finished */
413 : 0 : spin_lock_irq(&timer->lock);
414 [ # # ]: 0 : while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
415 : 0 : spin_unlock_irq(&timer->lock);
416 : 0 : udelay(10);
417 : 0 : spin_lock_irq(&timer->lock);
418 : : }
419 : 0 : spin_unlock_irq(&timer->lock);
420 : :
421 : : /* remove slave links */
422 : 0 : spin_lock_irq(&slave_active_lock);
423 : 0 : spin_lock(&timer->lock);
424 : 0 : timeri->timer = NULL;
425 [ # # ]: 0 : list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
426 : : open_list) {
427 : 0 : list_move_tail(&slave->open_list, &snd_timer_slave_list);
428 : 0 : timer->num_instances--;
429 : 0 : slave->master = NULL;
430 : 0 : slave->timer = NULL;
431 : 0 : list_del_init(&slave->ack_list);
432 : 0 : list_del_init(&slave->active_list);
433 : : }
434 : 0 : spin_unlock(&timer->lock);
435 : 0 : spin_unlock_irq(&slave_active_lock);
436 : :
437 : : /* slave doesn't need to release timer resources below */
438 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
439 : : timer = NULL;
440 : : }
441 : :
442 [ # # ]: 0 : if (timer) {
443 [ # # # # ]: 0 : if (list_empty(&timer->open_list_head) && timer->hw.close)
444 : 0 : timer->hw.close(timer);
445 : : /* release a card refcount for safe disconnection */
446 [ # # ]: 0 : if (timer->card)
447 : 0 : *card_devp_to_put = &timer->card->card_dev;
448 : 0 : module_put(timer->module);
449 : : }
450 : 0 : }
451 : :
452 : : /*
453 : : * close a timer instance
454 : : */
455 : 0 : void snd_timer_close(struct snd_timer_instance *timeri)
456 : : {
457 : 0 : struct device *card_dev_to_put = NULL;
458 : :
459 [ # # ]: 0 : if (snd_BUG_ON(!timeri))
460 : 0 : return;
461 : :
462 : 0 : mutex_lock(®ister_mutex);
463 : 0 : snd_timer_close_locked(timeri, &card_dev_to_put);
464 : 0 : mutex_unlock(®ister_mutex);
465 : : /* put_device() is called after unlock for avoiding deadlock */
466 [ # # ]: 0 : if (card_dev_to_put)
467 : 0 : put_device(card_dev_to_put);
468 : : }
469 : : EXPORT_SYMBOL(snd_timer_close);
470 : :
471 : 0 : static unsigned long snd_timer_hw_resolution(struct snd_timer *timer)
472 : : {
473 : 0 : if (timer->hw.c_resolution)
474 : 0 : return timer->hw.c_resolution(timer);
475 : : else
476 : 0 : return timer->hw.resolution;
477 : : }
478 : :
479 : 0 : unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
480 : : {
481 : 0 : struct snd_timer * timer;
482 : 0 : unsigned long ret = 0;
483 : 0 : unsigned long flags;
484 : :
485 [ # # ]: 0 : if (timeri == NULL)
486 : : return 0;
487 : 0 : timer = timeri->timer;
488 [ # # ]: 0 : if (timer) {
489 : 0 : spin_lock_irqsave(&timer->lock, flags);
490 [ # # ]: 0 : ret = snd_timer_hw_resolution(timer);
491 : 0 : spin_unlock_irqrestore(&timer->lock, flags);
492 : : }
493 : : return ret;
494 : : }
495 : : EXPORT_SYMBOL(snd_timer_resolution);
496 : :
497 : 0 : static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
498 : : {
499 : 0 : struct snd_timer *timer = ti->timer;
500 : 0 : unsigned long resolution = 0;
501 : 0 : struct snd_timer_instance *ts;
502 : 0 : struct timespec64 tstamp;
503 : :
504 [ # # ]: 0 : if (timer_tstamp_monotonic)
505 : 0 : ktime_get_ts64(&tstamp);
506 : : else
507 : 0 : ktime_get_real_ts64(&tstamp);
508 [ # # ]: 0 : if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START ||
509 : : event > SNDRV_TIMER_EVENT_PAUSE))
510 : 0 : return;
511 [ # # ]: 0 : if (timer &&
512 : 0 : (event == SNDRV_TIMER_EVENT_START ||
513 [ # # ]: 0 : event == SNDRV_TIMER_EVENT_CONTINUE))
514 [ # # ]: 0 : resolution = snd_timer_hw_resolution(timer);
515 [ # # ]: 0 : if (ti->ccallback)
516 : 0 : ti->ccallback(ti, event, &tstamp, resolution);
517 [ # # ]: 0 : if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
518 : : return;
519 [ # # ]: 0 : if (timer == NULL)
520 : : return;
521 [ # # ]: 0 : if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
522 : : return;
523 [ # # ]: 0 : list_for_each_entry(ts, &ti->slave_active_head, active_list)
524 [ # # ]: 0 : if (ts->ccallback)
525 : 0 : ts->ccallback(ts, event + 100, &tstamp, resolution);
526 : : }
527 : :
528 : : /* start/continue a master timer */
529 : 0 : static int snd_timer_start1(struct snd_timer_instance *timeri,
530 : : bool start, unsigned long ticks)
531 : : {
532 : 0 : struct snd_timer *timer;
533 : 0 : int result;
534 : 0 : unsigned long flags;
535 : :
536 : 0 : timer = timeri->timer;
537 [ # # ]: 0 : if (!timer)
538 : : return -EINVAL;
539 : :
540 : 0 : spin_lock_irqsave(&timer->lock, flags);
541 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) {
542 : 0 : result = -EINVAL;
543 : 0 : goto unlock;
544 : : }
545 [ # # # # ]: 0 : if (timer->card && timer->card->shutdown) {
546 : 0 : result = -ENODEV;
547 : 0 : goto unlock;
548 : : }
549 [ # # ]: 0 : if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
550 : : SNDRV_TIMER_IFLG_START)) {
551 : 0 : result = -EBUSY;
552 : 0 : goto unlock;
553 : : }
554 : :
555 [ # # ]: 0 : if (start)
556 : 0 : timeri->ticks = timeri->cticks = ticks;
557 [ # # ]: 0 : else if (!timeri->cticks)
558 : 0 : timeri->cticks = 1;
559 : 0 : timeri->pticks = 0;
560 : :
561 [ # # ]: 0 : list_move_tail(&timeri->active_list, &timer->active_list_head);
562 [ # # ]: 0 : if (timer->running) {
563 [ # # ]: 0 : if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
564 : 0 : goto __start_now;
565 : 0 : timer->flags |= SNDRV_TIMER_FLG_RESCHED;
566 : 0 : timeri->flags |= SNDRV_TIMER_IFLG_START;
567 : 0 : result = 1; /* delayed start */
568 : : } else {
569 [ # # ]: 0 : if (start)
570 : 0 : timer->sticks = ticks;
571 : 0 : timer->hw.start(timer);
572 : 0 : __start_now:
573 : 0 : timer->running++;
574 : 0 : timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
575 : 0 : result = 0;
576 : : }
577 [ # # ]: 0 : snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START :
578 : : SNDRV_TIMER_EVENT_CONTINUE);
579 : 0 : unlock:
580 : 0 : spin_unlock_irqrestore(&timer->lock, flags);
581 : 0 : return result;
582 : : }
583 : :
584 : : /* start/continue a slave timer */
585 : 0 : static int snd_timer_start_slave(struct snd_timer_instance *timeri,
586 : : bool start)
587 : : {
588 : 0 : unsigned long flags;
589 : 0 : int err;
590 : :
591 : 0 : spin_lock_irqsave(&slave_active_lock, flags);
592 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_DEAD) {
593 : 0 : err = -EINVAL;
594 : 0 : goto unlock;
595 : : }
596 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) {
597 : 0 : err = -EBUSY;
598 : 0 : goto unlock;
599 : : }
600 : 0 : timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
601 [ # # # # ]: 0 : if (timeri->master && timeri->timer) {
602 : 0 : spin_lock(&timeri->timer->lock);
603 : 0 : list_add_tail(&timeri->active_list,
604 [ # # ]: 0 : &timeri->master->slave_active_head);
605 [ # # ]: 0 : snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START :
606 : : SNDRV_TIMER_EVENT_CONTINUE);
607 : 0 : spin_unlock(&timeri->timer->lock);
608 : : }
609 : : err = 1; /* delayed start */
610 : 0 : unlock:
611 : 0 : spin_unlock_irqrestore(&slave_active_lock, flags);
612 : 0 : return err;
613 : : }
614 : :
615 : : /* stop/pause a master timer */
616 : 0 : static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop)
617 : : {
618 : 0 : struct snd_timer *timer;
619 : 0 : int result = 0;
620 : 0 : unsigned long flags;
621 : :
622 : 0 : timer = timeri->timer;
623 [ # # ]: 0 : if (!timer)
624 : : return -EINVAL;
625 : 0 : spin_lock_irqsave(&timer->lock, flags);
626 [ # # ]: 0 : if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING |
627 : : SNDRV_TIMER_IFLG_START))) {
628 : 0 : result = -EBUSY;
629 : 0 : goto unlock;
630 : : }
631 [ # # ]: 0 : list_del_init(&timeri->ack_list);
632 : 0 : list_del_init(&timeri->active_list);
633 [ # # # # ]: 0 : if (timer->card && timer->card->shutdown)
634 : 0 : goto unlock;
635 [ # # ]: 0 : if (stop) {
636 : 0 : timeri->cticks = timeri->ticks;
637 : 0 : timeri->pticks = 0;
638 : : }
639 [ # # ]: 0 : if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) &&
640 [ # # ]: 0 : !(--timer->running)) {
641 : 0 : timer->hw.stop(timer);
642 [ # # ]: 0 : if (timer->flags & SNDRV_TIMER_FLG_RESCHED) {
643 : 0 : timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
644 : 0 : snd_timer_reschedule(timer, 0);
645 [ # # ]: 0 : if (timer->flags & SNDRV_TIMER_FLG_CHANGE) {
646 : 0 : timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
647 : 0 : timer->hw.start(timer);
648 : : }
649 : : }
650 : : }
651 : 0 : timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
652 [ # # ]: 0 : if (stop)
653 : 0 : timeri->flags &= ~SNDRV_TIMER_IFLG_PAUSED;
654 : : else
655 : 0 : timeri->flags |= SNDRV_TIMER_IFLG_PAUSED;
656 [ # # ]: 0 : snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
657 : : SNDRV_TIMER_EVENT_PAUSE);
658 : 0 : unlock:
659 : 0 : spin_unlock_irqrestore(&timer->lock, flags);
660 : 0 : return result;
661 : : }
662 : :
663 : : /* stop/pause a slave timer */
664 : 0 : static int snd_timer_stop_slave(struct snd_timer_instance *timeri, bool stop)
665 : : {
666 : 0 : unsigned long flags;
667 : :
668 : 0 : spin_lock_irqsave(&slave_active_lock, flags);
669 [ # # ]: 0 : if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) {
670 : 0 : spin_unlock_irqrestore(&slave_active_lock, flags);
671 : 0 : return -EBUSY;
672 : : }
673 : 0 : timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
674 [ # # ]: 0 : if (timeri->timer) {
675 : 0 : spin_lock(&timeri->timer->lock);
676 [ # # ]: 0 : list_del_init(&timeri->ack_list);
677 : 0 : list_del_init(&timeri->active_list);
678 [ # # ]: 0 : snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
679 : : SNDRV_TIMER_EVENT_PAUSE);
680 : 0 : spin_unlock(&timeri->timer->lock);
681 : : }
682 : 0 : spin_unlock_irqrestore(&slave_active_lock, flags);
683 : 0 : return 0;
684 : : }
685 : :
686 : : /*
687 : : * start the timer instance
688 : : */
689 : 0 : int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
690 : : {
691 [ # # ]: 0 : if (timeri == NULL || ticks < 1)
692 : : return -EINVAL;
693 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
694 : 0 : return snd_timer_start_slave(timeri, true);
695 : : else
696 : 0 : return snd_timer_start1(timeri, true, ticks);
697 : : }
698 : : EXPORT_SYMBOL(snd_timer_start);
699 : :
700 : : /*
701 : : * stop the timer instance.
702 : : *
703 : : * do not call this from the timer callback!
704 : : */
705 : 0 : int snd_timer_stop(struct snd_timer_instance *timeri)
706 : : {
707 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
708 : 0 : return snd_timer_stop_slave(timeri, true);
709 : : else
710 : 0 : return snd_timer_stop1(timeri, true);
711 : : }
712 : : EXPORT_SYMBOL(snd_timer_stop);
713 : :
714 : : /*
715 : : * start again.. the tick is kept.
716 : : */
717 : 0 : int snd_timer_continue(struct snd_timer_instance *timeri)
718 : : {
719 : : /* timer can continue only after pause */
720 [ # # ]: 0 : if (!(timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
721 : : return -EINVAL;
722 : :
723 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
724 : 0 : return snd_timer_start_slave(timeri, false);
725 : : else
726 : 0 : return snd_timer_start1(timeri, false, 0);
727 : : }
728 : : EXPORT_SYMBOL(snd_timer_continue);
729 : :
730 : : /*
731 : : * pause.. remember the ticks left
732 : : */
733 : 0 : int snd_timer_pause(struct snd_timer_instance * timeri)
734 : : {
735 [ # # ]: 0 : if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
736 : 0 : return snd_timer_stop_slave(timeri, false);
737 : : else
738 : 0 : return snd_timer_stop1(timeri, false);
739 : : }
740 : : EXPORT_SYMBOL(snd_timer_pause);
741 : :
742 : : /*
743 : : * reschedule the timer
744 : : *
745 : : * start pending instances and check the scheduling ticks.
746 : : * when the scheduling ticks is changed set CHANGE flag to reprogram the timer.
747 : : */
748 : 0 : static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left)
749 : : {
750 : 0 : struct snd_timer_instance *ti;
751 : 0 : unsigned long ticks = ~0UL;
752 : :
753 [ # # ]: 0 : list_for_each_entry(ti, &timer->active_list_head, active_list) {
754 [ # # ]: 0 : if (ti->flags & SNDRV_TIMER_IFLG_START) {
755 : 0 : ti->flags &= ~SNDRV_TIMER_IFLG_START;
756 : 0 : ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
757 : 0 : timer->running++;
758 : : }
759 [ # # ]: 0 : if (ti->flags & SNDRV_TIMER_IFLG_RUNNING) {
760 : 0 : if (ticks > ti->cticks)
761 : : ticks = ti->cticks;
762 : : }
763 : : }
764 [ # # ]: 0 : if (ticks == ~0UL) {
765 : 0 : timer->flags &= ~SNDRV_TIMER_FLG_RESCHED;
766 : 0 : return;
767 : : }
768 : 0 : if (ticks > timer->hw.ticks)
769 : : ticks = timer->hw.ticks;
770 [ # # ]: 0 : if (ticks_left != ticks)
771 : 0 : timer->flags |= SNDRV_TIMER_FLG_CHANGE;
772 : 0 : timer->sticks = ticks;
773 : : }
774 : :
775 : : /* call callbacks in timer ack list */
776 : 0 : static void snd_timer_process_callbacks(struct snd_timer *timer,
777 : : struct list_head *head)
778 : : {
779 : 0 : struct snd_timer_instance *ti;
780 : 0 : unsigned long resolution, ticks;
781 : :
782 [ # # ]: 0 : while (!list_empty(head)) {
783 : 0 : ti = list_first_entry(head, struct snd_timer_instance,
784 : : ack_list);
785 : :
786 : : /* remove from ack_list and make empty */
787 [ # # ]: 0 : list_del_init(&ti->ack_list);
788 : :
789 [ # # ]: 0 : if (!(ti->flags & SNDRV_TIMER_IFLG_DEAD)) {
790 : 0 : ticks = ti->pticks;
791 : 0 : ti->pticks = 0;
792 : 0 : resolution = ti->resolution;
793 : 0 : ti->flags |= SNDRV_TIMER_IFLG_CALLBACK;
794 : 0 : spin_unlock(&timer->lock);
795 [ # # ]: 0 : if (ti->callback)
796 : 0 : ti->callback(ti, resolution, ticks);
797 : 0 : spin_lock(&timer->lock);
798 : 0 : ti->flags &= ~SNDRV_TIMER_IFLG_CALLBACK;
799 : : }
800 : : }
801 : 0 : }
802 : :
803 : : /* clear pending instances from ack list */
804 : 0 : static void snd_timer_clear_callbacks(struct snd_timer *timer,
805 : : struct list_head *head)
806 : : {
807 : 0 : unsigned long flags;
808 : :
809 : 0 : spin_lock_irqsave(&timer->lock, flags);
810 [ # # ]: 0 : while (!list_empty(head))
811 : 0 : list_del_init(head->next);
812 : 0 : spin_unlock_irqrestore(&timer->lock, flags);
813 : 0 : }
814 : :
815 : : /*
816 : : * timer tasklet
817 : : *
818 : : */
819 : 0 : static void snd_timer_tasklet(unsigned long arg)
820 : : {
821 : 0 : struct snd_timer *timer = (struct snd_timer *) arg;
822 : 0 : unsigned long flags;
823 : :
824 [ # # # # ]: 0 : if (timer->card && timer->card->shutdown) {
825 : 0 : snd_timer_clear_callbacks(timer, &timer->sack_list_head);
826 : 0 : return;
827 : : }
828 : :
829 : 0 : spin_lock_irqsave(&timer->lock, flags);
830 : 0 : snd_timer_process_callbacks(timer, &timer->sack_list_head);
831 : 0 : spin_unlock_irqrestore(&timer->lock, flags);
832 : : }
833 : :
834 : : /*
835 : : * timer interrupt
836 : : *
837 : : * ticks_left is usually equal to timer->sticks.
838 : : *
839 : : */
840 : 0 : void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
841 : : {
842 : 0 : struct snd_timer_instance *ti, *ts, *tmp;
843 : 0 : unsigned long resolution;
844 : 0 : struct list_head *ack_list_head;
845 : 0 : unsigned long flags;
846 : 0 : int use_tasklet = 0;
847 : :
848 [ # # ]: 0 : if (timer == NULL)
849 : : return;
850 : :
851 [ # # # # ]: 0 : if (timer->card && timer->card->shutdown) {
852 : 0 : snd_timer_clear_callbacks(timer, &timer->ack_list_head);
853 : 0 : return;
854 : : }
855 : :
856 : 0 : spin_lock_irqsave(&timer->lock, flags);
857 : :
858 : : /* remember the current resolution */
859 [ # # ]: 0 : resolution = snd_timer_hw_resolution(timer);
860 : :
861 : : /* loop for all active instances
862 : : * Here we cannot use list_for_each_entry because the active_list of a
863 : : * processed instance is relinked to done_list_head before the callback
864 : : * is called.
865 : : */
866 [ # # ]: 0 : list_for_each_entry_safe(ti, tmp, &timer->active_list_head,
867 : : active_list) {
868 [ # # ]: 0 : if (ti->flags & SNDRV_TIMER_IFLG_DEAD)
869 : 0 : continue;
870 [ # # ]: 0 : if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
871 : 0 : continue;
872 : 0 : ti->pticks += ticks_left;
873 : 0 : ti->resolution = resolution;
874 [ # # ]: 0 : if (ti->cticks < ticks_left)
875 : 0 : ti->cticks = 0;
876 : : else
877 : 0 : ti->cticks -= ticks_left;
878 [ # # ]: 0 : if (ti->cticks) /* not expired */
879 : 0 : continue;
880 [ # # ]: 0 : if (ti->flags & SNDRV_TIMER_IFLG_AUTO) {
881 : 0 : ti->cticks = ti->ticks;
882 : : } else {
883 : 0 : ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
884 : 0 : --timer->running;
885 : 0 : list_del_init(&ti->active_list);
886 : : }
887 [ # # ]: 0 : if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
888 [ # # ]: 0 : (ti->flags & SNDRV_TIMER_IFLG_FAST))
889 : 0 : ack_list_head = &timer->ack_list_head;
890 : : else
891 : 0 : ack_list_head = &timer->sack_list_head;
892 [ # # ]: 0 : if (list_empty(&ti->ack_list))
893 : 0 : list_add_tail(&ti->ack_list, ack_list_head);
894 [ # # ]: 0 : list_for_each_entry(ts, &ti->slave_active_head, active_list) {
895 : 0 : ts->pticks = ti->pticks;
896 : 0 : ts->resolution = resolution;
897 [ # # ]: 0 : if (list_empty(&ts->ack_list))
898 : 0 : list_add_tail(&ts->ack_list, ack_list_head);
899 : : }
900 : : }
901 [ # # ]: 0 : if (timer->flags & SNDRV_TIMER_FLG_RESCHED)
902 : 0 : snd_timer_reschedule(timer, timer->sticks);
903 [ # # ]: 0 : if (timer->running) {
904 [ # # ]: 0 : if (timer->hw.flags & SNDRV_TIMER_HW_STOP) {
905 : 0 : timer->hw.stop(timer);
906 : 0 : timer->flags |= SNDRV_TIMER_FLG_CHANGE;
907 : : }
908 [ # # ]: 0 : if (!(timer->hw.flags & SNDRV_TIMER_HW_AUTO) ||
909 [ # # ]: 0 : (timer->flags & SNDRV_TIMER_FLG_CHANGE)) {
910 : : /* restart timer */
911 : 0 : timer->flags &= ~SNDRV_TIMER_FLG_CHANGE;
912 : 0 : timer->hw.start(timer);
913 : : }
914 : : } else {
915 : 0 : timer->hw.stop(timer);
916 : : }
917 : :
918 : : /* now process all fast callbacks */
919 : 0 : snd_timer_process_callbacks(timer, &timer->ack_list_head);
920 : :
921 : : /* do we have any slow callbacks? */
922 : 0 : use_tasklet = !list_empty(&timer->sack_list_head);
923 : 0 : spin_unlock_irqrestore(&timer->lock, flags);
924 : :
925 [ # # ]: 0 : if (use_tasklet)
926 : 0 : tasklet_schedule(&timer->task_queue);
927 : : }
928 : : EXPORT_SYMBOL(snd_timer_interrupt);
929 : :
930 : : /*
931 : :
932 : : */
933 : :
934 : 60 : int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
935 : : struct snd_timer **rtimer)
936 : : {
937 : 60 : struct snd_timer *timer;
938 : 60 : int err;
939 : 60 : static const struct snd_device_ops ops = {
940 : : .dev_free = snd_timer_dev_free,
941 : : .dev_register = snd_timer_dev_register,
942 : : .dev_disconnect = snd_timer_dev_disconnect,
943 : : };
944 : :
945 [ + - ]: 60 : if (snd_BUG_ON(!tid))
946 : : return -EINVAL;
947 [ - + ]: 60 : if (tid->dev_class == SNDRV_TIMER_CLASS_CARD ||
948 : : tid->dev_class == SNDRV_TIMER_CLASS_PCM) {
949 [ # # # # ]: 0 : if (WARN_ON(!card))
950 : : return -EINVAL;
951 : : }
952 [ + - ]: 60 : if (rtimer)
953 : 60 : *rtimer = NULL;
954 : 60 : timer = kzalloc(sizeof(*timer), GFP_KERNEL);
955 [ + - ]: 60 : if (!timer)
956 : : return -ENOMEM;
957 : 60 : timer->tmr_class = tid->dev_class;
958 : 60 : timer->card = card;
959 : 60 : timer->tmr_device = tid->device;
960 : 60 : timer->tmr_subdevice = tid->subdevice;
961 [ + - ]: 60 : if (id)
962 : 60 : strlcpy(timer->id, id, sizeof(timer->id));
963 : 60 : timer->sticks = 1;
964 : 60 : INIT_LIST_HEAD(&timer->device_list);
965 : 60 : INIT_LIST_HEAD(&timer->open_list_head);
966 : 60 : INIT_LIST_HEAD(&timer->active_list_head);
967 : 60 : INIT_LIST_HEAD(&timer->ack_list_head);
968 : 60 : INIT_LIST_HEAD(&timer->sack_list_head);
969 : 60 : spin_lock_init(&timer->lock);
970 : 60 : tasklet_init(&timer->task_queue, snd_timer_tasklet,
971 : : (unsigned long)timer);
972 : 60 : timer->max_instances = 1000; /* default limit per timer */
973 [ - + ]: 60 : if (card != NULL) {
974 : 0 : timer->module = card->module;
975 : 0 : err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
976 [ # # ]: 0 : if (err < 0) {
977 : 0 : snd_timer_free(timer);
978 : 0 : return err;
979 : : }
980 : : }
981 [ + - ]: 60 : if (rtimer)
982 : 60 : *rtimer = timer;
983 : : return 0;
984 : : }
985 : : EXPORT_SYMBOL(snd_timer_new);
986 : :
987 : 0 : static int snd_timer_free(struct snd_timer *timer)
988 : : {
989 [ # # ]: 0 : if (!timer)
990 : : return 0;
991 : :
992 : 0 : mutex_lock(®ister_mutex);
993 [ # # ]: 0 : if (! list_empty(&timer->open_list_head)) {
994 : 0 : struct list_head *p, *n;
995 : 0 : struct snd_timer_instance *ti;
996 : 0 : pr_warn("ALSA: timer %p is busy?\n", timer);
997 [ # # ]: 0 : list_for_each_safe(p, n, &timer->open_list_head) {
998 : 0 : list_del_init(p);
999 : 0 : ti = list_entry(p, struct snd_timer_instance, open_list);
1000 : 0 : ti->timer = NULL;
1001 : : }
1002 : : }
1003 : 0 : list_del(&timer->device_list);
1004 : 0 : mutex_unlock(®ister_mutex);
1005 : :
1006 [ # # ]: 0 : if (timer->private_free)
1007 : 0 : timer->private_free(timer);
1008 : 0 : kfree(timer);
1009 : 0 : return 0;
1010 : : }
1011 : :
1012 : 0 : static int snd_timer_dev_free(struct snd_device *device)
1013 : : {
1014 : 0 : struct snd_timer *timer = device->device_data;
1015 : 0 : return snd_timer_free(timer);
1016 : : }
1017 : :
1018 : 60 : static int snd_timer_dev_register(struct snd_device *dev)
1019 : : {
1020 : 60 : struct snd_timer *timer = dev->device_data;
1021 : 60 : struct snd_timer *timer1;
1022 : :
1023 [ + - + - : 120 : if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop))
+ - + - ]
1024 : : return -ENXIO;
1025 [ + - ]: 60 : if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
1026 [ - + - - ]: 60 : !timer->hw.resolution && timer->hw.c_resolution == NULL)
1027 : : return -EINVAL;
1028 : :
1029 : 60 : mutex_lock(®ister_mutex);
1030 [ + + ]: 90 : list_for_each_entry(timer1, &snd_timer_list, device_list) {
1031 [ + - ]: 30 : if (timer1->tmr_class > timer->tmr_class)
1032 : : break;
1033 [ - + ]: 30 : if (timer1->tmr_class < timer->tmr_class)
1034 : 0 : continue;
1035 [ - + - - ]: 30 : if (timer1->card && timer->card) {
1036 [ # # ]: 0 : if (timer1->card->number > timer->card->number)
1037 : : break;
1038 [ # # ]: 0 : if (timer1->card->number < timer->card->number)
1039 : 0 : continue;
1040 : : }
1041 [ + - ]: 30 : if (timer1->tmr_device > timer->tmr_device)
1042 : : break;
1043 [ + - ]: 30 : if (timer1->tmr_device < timer->tmr_device)
1044 : 30 : continue;
1045 [ # # ]: 0 : if (timer1->tmr_subdevice > timer->tmr_subdevice)
1046 : : break;
1047 [ # # ]: 0 : if (timer1->tmr_subdevice < timer->tmr_subdevice)
1048 : 0 : continue;
1049 : : /* conflicts.. */
1050 : 0 : mutex_unlock(®ister_mutex);
1051 : 0 : return -EBUSY;
1052 : : }
1053 : 60 : list_add_tail(&timer->device_list, &timer1->device_list);
1054 : 60 : mutex_unlock(®ister_mutex);
1055 : 60 : return 0;
1056 : : }
1057 : :
1058 : 0 : static int snd_timer_dev_disconnect(struct snd_device *device)
1059 : : {
1060 : 0 : struct snd_timer *timer = device->device_data;
1061 : 0 : struct snd_timer_instance *ti;
1062 : :
1063 : 0 : mutex_lock(®ister_mutex);
1064 : 0 : list_del_init(&timer->device_list);
1065 : : /* wake up pending sleepers */
1066 [ # # ]: 0 : list_for_each_entry(ti, &timer->open_list_head, open_list) {
1067 [ # # ]: 0 : if (ti->disconnect)
1068 : 0 : ti->disconnect(ti);
1069 : : }
1070 : 0 : mutex_unlock(®ister_mutex);
1071 : 0 : return 0;
1072 : : }
1073 : :
1074 : 0 : void snd_timer_notify(struct snd_timer *timer, int event, struct timespec64 *tstamp)
1075 : : {
1076 : 0 : unsigned long flags;
1077 : 0 : unsigned long resolution = 0;
1078 : 0 : struct snd_timer_instance *ti, *ts;
1079 : :
1080 [ # # # # ]: 0 : if (timer->card && timer->card->shutdown)
1081 : : return;
1082 [ # # ]: 0 : if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
1083 : : return;
1084 [ # # ]: 0 : if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART ||
1085 : : event > SNDRV_TIMER_EVENT_MRESUME))
1086 : : return;
1087 : 0 : spin_lock_irqsave(&timer->lock, flags);
1088 : 0 : if (event == SNDRV_TIMER_EVENT_MSTART ||
1089 [ # # # # ]: 0 : event == SNDRV_TIMER_EVENT_MCONTINUE ||
1090 : : event == SNDRV_TIMER_EVENT_MRESUME)
1091 [ # # ]: 0 : resolution = snd_timer_hw_resolution(timer);
1092 [ # # ]: 0 : list_for_each_entry(ti, &timer->active_list_head, active_list) {
1093 [ # # ]: 0 : if (ti->ccallback)
1094 : 0 : ti->ccallback(ti, event, tstamp, resolution);
1095 [ # # ]: 0 : list_for_each_entry(ts, &ti->slave_active_head, active_list)
1096 [ # # ]: 0 : if (ts->ccallback)
1097 : 0 : ts->ccallback(ts, event, tstamp, resolution);
1098 : : }
1099 : 0 : spin_unlock_irqrestore(&timer->lock, flags);
1100 : : }
1101 : : EXPORT_SYMBOL(snd_timer_notify);
1102 : :
1103 : : /*
1104 : : * exported functions for global timers
1105 : : */
1106 : 60 : int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer)
1107 : : {
1108 : 60 : struct snd_timer_id tid;
1109 : :
1110 : 60 : tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
1111 : 60 : tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1112 : 60 : tid.card = -1;
1113 : 60 : tid.device = device;
1114 : 60 : tid.subdevice = 0;
1115 : 30 : return snd_timer_new(NULL, id, &tid, rtimer);
1116 : : }
1117 : : EXPORT_SYMBOL(snd_timer_global_new);
1118 : :
1119 : 0 : int snd_timer_global_free(struct snd_timer *timer)
1120 : : {
1121 : 0 : return snd_timer_free(timer);
1122 : : }
1123 : : EXPORT_SYMBOL(snd_timer_global_free);
1124 : :
1125 : 60 : int snd_timer_global_register(struct snd_timer *timer)
1126 : : {
1127 : 60 : struct snd_device dev;
1128 : :
1129 : 60 : memset(&dev, 0, sizeof(dev));
1130 : 60 : dev.device_data = timer;
1131 : 60 : return snd_timer_dev_register(&dev);
1132 : : }
1133 : : EXPORT_SYMBOL(snd_timer_global_register);
1134 : :
1135 : : /*
1136 : : * System timer
1137 : : */
1138 : :
1139 : : struct snd_timer_system_private {
1140 : : struct timer_list tlist;
1141 : : struct snd_timer *snd_timer;
1142 : : unsigned long last_expires;
1143 : : unsigned long last_jiffies;
1144 : : unsigned long correction;
1145 : : };
1146 : :
1147 : 0 : static void snd_timer_s_function(struct timer_list *t)
1148 : : {
1149 : 0 : struct snd_timer_system_private *priv = from_timer(priv, t,
1150 : : tlist);
1151 : 0 : struct snd_timer *timer = priv->snd_timer;
1152 : 0 : unsigned long jiff = jiffies;
1153 [ # # ]: 0 : if (time_after(jiff, priv->last_expires))
1154 : 0 : priv->correction += (long)jiff - (long)priv->last_expires;
1155 : 0 : snd_timer_interrupt(timer, (long)jiff - (long)priv->last_jiffies);
1156 : 0 : }
1157 : :
1158 : 0 : static int snd_timer_s_start(struct snd_timer * timer)
1159 : : {
1160 : 0 : struct snd_timer_system_private *priv;
1161 : 0 : unsigned long njiff;
1162 : :
1163 : 0 : priv = (struct snd_timer_system_private *) timer->private_data;
1164 : 0 : njiff = (priv->last_jiffies = jiffies);
1165 [ # # ]: 0 : if (priv->correction > timer->sticks - 1) {
1166 : 0 : priv->correction -= timer->sticks - 1;
1167 : 0 : njiff++;
1168 : : } else {
1169 : 0 : njiff += timer->sticks - priv->correction;
1170 : 0 : priv->correction = 0;
1171 : : }
1172 : 0 : priv->last_expires = njiff;
1173 : 0 : mod_timer(&priv->tlist, njiff);
1174 : 0 : return 0;
1175 : : }
1176 : :
1177 : 0 : static int snd_timer_s_stop(struct snd_timer * timer)
1178 : : {
1179 : 0 : struct snd_timer_system_private *priv;
1180 : 0 : unsigned long jiff;
1181 : :
1182 : 0 : priv = (struct snd_timer_system_private *) timer->private_data;
1183 : 0 : del_timer(&priv->tlist);
1184 : 0 : jiff = jiffies;
1185 [ # # ]: 0 : if (time_before(jiff, priv->last_expires))
1186 : 0 : timer->sticks = priv->last_expires - jiff;
1187 : : else
1188 : 0 : timer->sticks = 1;
1189 : 0 : priv->correction = 0;
1190 : 0 : return 0;
1191 : : }
1192 : :
1193 : 0 : static int snd_timer_s_close(struct snd_timer *timer)
1194 : : {
1195 : 0 : struct snd_timer_system_private *priv;
1196 : :
1197 : 0 : priv = (struct snd_timer_system_private *)timer->private_data;
1198 : 0 : del_timer_sync(&priv->tlist);
1199 : 0 : return 0;
1200 : : }
1201 : :
1202 : : static const struct snd_timer_hardware snd_timer_system =
1203 : : {
1204 : : .flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
1205 : : .resolution = 1000000000L / HZ,
1206 : : .ticks = 10000000L,
1207 : : .close = snd_timer_s_close,
1208 : : .start = snd_timer_s_start,
1209 : : .stop = snd_timer_s_stop
1210 : : };
1211 : :
1212 : 0 : static void snd_timer_free_system(struct snd_timer *timer)
1213 : : {
1214 : 0 : kfree(timer->private_data);
1215 : 0 : }
1216 : :
1217 : 30 : static int snd_timer_register_system(void)
1218 : : {
1219 : 30 : struct snd_timer *timer;
1220 : 30 : struct snd_timer_system_private *priv;
1221 : 30 : int err;
1222 : :
1223 : 30 : err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer);
1224 [ + - ]: 30 : if (err < 0)
1225 : : return err;
1226 : 30 : strcpy(timer->name, "system timer");
1227 : 30 : timer->hw = snd_timer_system;
1228 : 30 : priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1229 [ - + ]: 30 : if (priv == NULL) {
1230 : 0 : snd_timer_free(timer);
1231 : 0 : return -ENOMEM;
1232 : : }
1233 : 30 : priv->snd_timer = timer;
1234 : 30 : timer_setup(&priv->tlist, snd_timer_s_function, 0);
1235 : 30 : timer->private_data = priv;
1236 : 30 : timer->private_free = snd_timer_free_system;
1237 : 30 : return snd_timer_global_register(timer);
1238 : : }
1239 : :
1240 : : #ifdef CONFIG_SND_PROC_FS
1241 : : /*
1242 : : * Info interface
1243 : : */
1244 : :
1245 : 0 : static void snd_timer_proc_read(struct snd_info_entry *entry,
1246 : : struct snd_info_buffer *buffer)
1247 : : {
1248 : 0 : struct snd_timer *timer;
1249 : 0 : struct snd_timer_instance *ti;
1250 : :
1251 : 0 : mutex_lock(®ister_mutex);
1252 [ # # ]: 0 : list_for_each_entry(timer, &snd_timer_list, device_list) {
1253 [ # # # # ]: 0 : if (timer->card && timer->card->shutdown)
1254 : 0 : continue;
1255 [ # # # # ]: 0 : switch (timer->tmr_class) {
1256 : 0 : case SNDRV_TIMER_CLASS_GLOBAL:
1257 : 0 : snd_iprintf(buffer, "G%i: ", timer->tmr_device);
1258 : 0 : break;
1259 : 0 : case SNDRV_TIMER_CLASS_CARD:
1260 : 0 : snd_iprintf(buffer, "C%i-%i: ",
1261 : : timer->card->number, timer->tmr_device);
1262 : 0 : break;
1263 : 0 : case SNDRV_TIMER_CLASS_PCM:
1264 : 0 : snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number,
1265 : : timer->tmr_device, timer->tmr_subdevice);
1266 : 0 : break;
1267 : 0 : default:
1268 [ # # ]: 0 : snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class,
1269 : : timer->card ? timer->card->number : -1,
1270 : : timer->tmr_device, timer->tmr_subdevice);
1271 : : }
1272 : 0 : snd_iprintf(buffer, "%s :", timer->name);
1273 [ # # ]: 0 : if (timer->hw.resolution)
1274 : 0 : snd_iprintf(buffer, " %lu.%03luus (%lu ticks)",
1275 : : timer->hw.resolution / 1000,
1276 : : timer->hw.resolution % 1000,
1277 : : timer->hw.ticks);
1278 [ # # ]: 0 : if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
1279 : 0 : snd_iprintf(buffer, " SLAVE");
1280 : 0 : snd_iprintf(buffer, "\n");
1281 [ # # ]: 0 : list_for_each_entry(ti, &timer->open_list_head, open_list)
1282 [ # # # # ]: 0 : snd_iprintf(buffer, " Client %s : %s\n",
1283 : : ti->owner ? ti->owner : "unknown",
1284 : : ti->flags & (SNDRV_TIMER_IFLG_START |
1285 : : SNDRV_TIMER_IFLG_RUNNING)
1286 : : ? "running" : "stopped");
1287 : : }
1288 : 0 : mutex_unlock(®ister_mutex);
1289 : 0 : }
1290 : :
1291 : : static struct snd_info_entry *snd_timer_proc_entry;
1292 : :
1293 : 30 : static void __init snd_timer_proc_init(void)
1294 : : {
1295 : 30 : struct snd_info_entry *entry;
1296 : :
1297 : 30 : entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
1298 [ + - ]: 30 : if (entry != NULL) {
1299 : 30 : entry->c.text.read = snd_timer_proc_read;
1300 [ - + ]: 30 : if (snd_info_register(entry) < 0) {
1301 : 0 : snd_info_free_entry(entry);
1302 : 0 : entry = NULL;
1303 : : }
1304 : : }
1305 : 30 : snd_timer_proc_entry = entry;
1306 : 30 : }
1307 : :
1308 : 0 : static void __exit snd_timer_proc_done(void)
1309 : : {
1310 : 0 : snd_info_free_entry(snd_timer_proc_entry);
1311 : 0 : }
1312 : : #else /* !CONFIG_SND_PROC_FS */
1313 : : #define snd_timer_proc_init()
1314 : : #define snd_timer_proc_done()
1315 : : #endif
1316 : :
1317 : : /*
1318 : : * USER SPACE interface
1319 : : */
1320 : :
1321 : 0 : static void snd_timer_user_interrupt(struct snd_timer_instance *timeri,
1322 : : unsigned long resolution,
1323 : : unsigned long ticks)
1324 : : {
1325 : 0 : struct snd_timer_user *tu = timeri->callback_data;
1326 : 0 : struct snd_timer_read *r;
1327 : 0 : int prev;
1328 : :
1329 : 0 : spin_lock(&tu->qlock);
1330 [ # # ]: 0 : if (tu->qused > 0) {
1331 [ # # ]: 0 : prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
1332 : 0 : r = &tu->queue[prev];
1333 [ # # ]: 0 : if (r->resolution == resolution) {
1334 : 0 : r->ticks += ticks;
1335 : 0 : goto __wake;
1336 : : }
1337 : : }
1338 [ # # ]: 0 : if (tu->qused >= tu->queue_size) {
1339 : 0 : tu->overrun++;
1340 : : } else {
1341 : 0 : r = &tu->queue[tu->qtail++];
1342 : 0 : tu->qtail %= tu->queue_size;
1343 : 0 : r->resolution = resolution;
1344 : 0 : r->ticks = ticks;
1345 : 0 : tu->qused++;
1346 : : }
1347 : 0 : __wake:
1348 : 0 : spin_unlock(&tu->qlock);
1349 : 0 : kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1350 : 0 : wake_up(&tu->qchange_sleep);
1351 : 0 : }
1352 : :
1353 : 0 : static void snd_timer_user_append_to_tqueue(struct snd_timer_user *tu,
1354 : : struct snd_timer_tread64 *tread)
1355 : : {
1356 [ # # ]: 0 : if (tu->qused >= tu->queue_size) {
1357 : 0 : tu->overrun++;
1358 : : } else {
1359 : 0 : memcpy(&tu->tqueue[tu->qtail++], tread, sizeof(*tread));
1360 : 0 : tu->qtail %= tu->queue_size;
1361 : 0 : tu->qused++;
1362 : : }
1363 : 0 : }
1364 : :
1365 : 0 : static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
1366 : : int event,
1367 : : struct timespec64 *tstamp,
1368 : : unsigned long resolution)
1369 : : {
1370 : 0 : struct snd_timer_user *tu = timeri->callback_data;
1371 : 0 : struct snd_timer_tread64 r1;
1372 : 0 : unsigned long flags;
1373 : :
1374 [ # # ]: 0 : if (event >= SNDRV_TIMER_EVENT_START &&
1375 : : event <= SNDRV_TIMER_EVENT_PAUSE)
1376 : 0 : tu->tstamp = *tstamp;
1377 [ # # # # ]: 0 : if ((tu->filter & (1 << event)) == 0 || !tu->tread)
1378 : 0 : return;
1379 : 0 : memset(&r1, 0, sizeof(r1));
1380 : 0 : r1.event = event;
1381 : 0 : r1.tstamp_sec = tstamp->tv_sec;
1382 : 0 : r1.tstamp_nsec = tstamp->tv_nsec;
1383 : 0 : r1.val = resolution;
1384 : 0 : spin_lock_irqsave(&tu->qlock, flags);
1385 : 0 : snd_timer_user_append_to_tqueue(tu, &r1);
1386 : 0 : spin_unlock_irqrestore(&tu->qlock, flags);
1387 : 0 : kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1388 : 0 : wake_up(&tu->qchange_sleep);
1389 : : }
1390 : :
1391 : 0 : static void snd_timer_user_disconnect(struct snd_timer_instance *timeri)
1392 : : {
1393 : 0 : struct snd_timer_user *tu = timeri->callback_data;
1394 : :
1395 : 0 : tu->disconnected = true;
1396 : 0 : wake_up(&tu->qchange_sleep);
1397 : 0 : }
1398 : :
1399 : 0 : static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1400 : : unsigned long resolution,
1401 : : unsigned long ticks)
1402 : : {
1403 : 0 : struct snd_timer_user *tu = timeri->callback_data;
1404 : 0 : struct snd_timer_tread64 *r, r1;
1405 : 0 : struct timespec64 tstamp;
1406 : 0 : int prev, append = 0;
1407 : :
1408 : 0 : memset(&r1, 0, sizeof(r1));
1409 : 0 : memset(&tstamp, 0, sizeof(tstamp));
1410 : 0 : spin_lock(&tu->qlock);
1411 [ # # ]: 0 : if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
1412 : : (1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
1413 : 0 : spin_unlock(&tu->qlock);
1414 : 0 : return;
1415 : : }
1416 [ # # # # ]: 0 : if (tu->last_resolution != resolution || ticks > 0) {
1417 [ # # ]: 0 : if (timer_tstamp_monotonic)
1418 : 0 : ktime_get_ts64(&tstamp);
1419 : : else
1420 : 0 : ktime_get_real_ts64(&tstamp);
1421 : : }
1422 [ # # ]: 0 : if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
1423 [ # # ]: 0 : tu->last_resolution != resolution) {
1424 : 0 : r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
1425 : 0 : r1.tstamp_sec = tstamp.tv_sec;
1426 : 0 : r1.tstamp_nsec = tstamp.tv_nsec;
1427 : 0 : r1.val = resolution;
1428 : 0 : snd_timer_user_append_to_tqueue(tu, &r1);
1429 : 0 : tu->last_resolution = resolution;
1430 : 0 : append++;
1431 : : }
1432 [ # # ]: 0 : if ((tu->filter & (1 << SNDRV_TIMER_EVENT_TICK)) == 0)
1433 : 0 : goto __wake;
1434 [ # # ]: 0 : if (ticks == 0)
1435 : 0 : goto __wake;
1436 [ # # ]: 0 : if (tu->qused > 0) {
1437 [ # # ]: 0 : prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
1438 : 0 : r = &tu->tqueue[prev];
1439 [ # # ]: 0 : if (r->event == SNDRV_TIMER_EVENT_TICK) {
1440 : 0 : r->tstamp_sec = tstamp.tv_sec;
1441 : 0 : r->tstamp_nsec = tstamp.tv_nsec;
1442 : 0 : r->val += ticks;
1443 : 0 : append++;
1444 : 0 : goto __wake;
1445 : : }
1446 : : }
1447 : 0 : r1.event = SNDRV_TIMER_EVENT_TICK;
1448 : 0 : r1.tstamp_sec = tstamp.tv_sec;
1449 : 0 : r1.tstamp_nsec = tstamp.tv_nsec;
1450 : 0 : r1.val = ticks;
1451 : 0 : snd_timer_user_append_to_tqueue(tu, &r1);
1452 : 0 : append++;
1453 : 0 : __wake:
1454 : 0 : spin_unlock(&tu->qlock);
1455 [ # # ]: 0 : if (append == 0)
1456 : : return;
1457 : 0 : kill_fasync(&tu->fasync, SIGIO, POLL_IN);
1458 : 0 : wake_up(&tu->qchange_sleep);
1459 : : }
1460 : :
1461 : 0 : static int realloc_user_queue(struct snd_timer_user *tu, int size)
1462 : : {
1463 : 0 : struct snd_timer_read *queue = NULL;
1464 : 0 : struct snd_timer_tread64 *tqueue = NULL;
1465 : :
1466 [ # # ]: 0 : if (tu->tread) {
1467 : 0 : tqueue = kcalloc(size, sizeof(*tqueue), GFP_KERNEL);
1468 [ # # ]: 0 : if (!tqueue)
1469 : : return -ENOMEM;
1470 : : } else {
1471 : 0 : queue = kcalloc(size, sizeof(*queue), GFP_KERNEL);
1472 [ # # ]: 0 : if (!queue)
1473 : : return -ENOMEM;
1474 : : }
1475 : :
1476 : 0 : spin_lock_irq(&tu->qlock);
1477 : 0 : kfree(tu->queue);
1478 : 0 : kfree(tu->tqueue);
1479 : 0 : tu->queue_size = size;
1480 : 0 : tu->queue = queue;
1481 : 0 : tu->tqueue = tqueue;
1482 : 0 : tu->qhead = tu->qtail = tu->qused = 0;
1483 : 0 : spin_unlock_irq(&tu->qlock);
1484 : :
1485 : 0 : return 0;
1486 : : }
1487 : :
1488 : 0 : static int snd_timer_user_open(struct inode *inode, struct file *file)
1489 : : {
1490 : 0 : struct snd_timer_user *tu;
1491 : 0 : int err;
1492 : :
1493 : 0 : err = stream_open(inode, file);
1494 [ # # ]: 0 : if (err < 0)
1495 : : return err;
1496 : :
1497 : 0 : tu = kzalloc(sizeof(*tu), GFP_KERNEL);
1498 [ # # ]: 0 : if (tu == NULL)
1499 : : return -ENOMEM;
1500 : 0 : spin_lock_init(&tu->qlock);
1501 : 0 : init_waitqueue_head(&tu->qchange_sleep);
1502 : 0 : mutex_init(&tu->ioctl_lock);
1503 : 0 : tu->ticks = 1;
1504 [ # # ]: 0 : if (realloc_user_queue(tu, 128) < 0) {
1505 : 0 : kfree(tu);
1506 : 0 : return -ENOMEM;
1507 : : }
1508 : 0 : file->private_data = tu;
1509 : 0 : return 0;
1510 : : }
1511 : :
1512 : 0 : static int snd_timer_user_release(struct inode *inode, struct file *file)
1513 : : {
1514 : 0 : struct snd_timer_user *tu;
1515 : :
1516 [ # # ]: 0 : if (file->private_data) {
1517 : 0 : tu = file->private_data;
1518 : 0 : file->private_data = NULL;
1519 : 0 : mutex_lock(&tu->ioctl_lock);
1520 [ # # ]: 0 : if (tu->timeri) {
1521 : 0 : snd_timer_close(tu->timeri);
1522 : 0 : snd_timer_instance_free(tu->timeri);
1523 : : }
1524 : 0 : mutex_unlock(&tu->ioctl_lock);
1525 : 0 : kfree(tu->queue);
1526 : 0 : kfree(tu->tqueue);
1527 : 0 : kfree(tu);
1528 : : }
1529 : 0 : return 0;
1530 : : }
1531 : :
1532 : 0 : static void snd_timer_user_zero_id(struct snd_timer_id *id)
1533 : : {
1534 : 0 : id->dev_class = SNDRV_TIMER_CLASS_NONE;
1535 : 0 : id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1536 : 0 : id->card = -1;
1537 : 0 : id->device = -1;
1538 : 0 : id->subdevice = -1;
1539 : 0 : }
1540 : :
1541 : 0 : static void snd_timer_user_copy_id(struct snd_timer_id *id, struct snd_timer *timer)
1542 : : {
1543 : 0 : id->dev_class = timer->tmr_class;
1544 : 0 : id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1545 : 0 : id->card = timer->card ? timer->card->number : -1;
1546 : 0 : id->device = timer->tmr_device;
1547 : 0 : id->subdevice = timer->tmr_subdevice;
1548 : 0 : }
1549 : :
1550 : 0 : static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
1551 : : {
1552 : 0 : struct snd_timer_id id;
1553 : 0 : struct snd_timer *timer;
1554 : 0 : struct list_head *p;
1555 : :
1556 [ # # ]: 0 : if (copy_from_user(&id, _tid, sizeof(id)))
1557 : : return -EFAULT;
1558 : 0 : mutex_lock(®ister_mutex);
1559 [ # # ]: 0 : if (id.dev_class < 0) { /* first item */
1560 [ # # ]: 0 : if (list_empty(&snd_timer_list))
1561 : 0 : snd_timer_user_zero_id(&id);
1562 : : else {
1563 : 0 : timer = list_entry(snd_timer_list.next,
1564 : : struct snd_timer, device_list);
1565 [ # # ]: 0 : snd_timer_user_copy_id(&id, timer);
1566 : : }
1567 : : } else {
1568 [ # # # ]: 0 : switch (id.dev_class) {
1569 : 0 : case SNDRV_TIMER_CLASS_GLOBAL:
1570 : 0 : id.device = id.device < 0 ? 0 : id.device + 1;
1571 [ # # ]: 0 : list_for_each(p, &snd_timer_list) {
1572 : 0 : timer = list_entry(p, struct snd_timer, device_list);
1573 [ # # ]: 0 : if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
1574 [ # # ]: 0 : snd_timer_user_copy_id(&id, timer);
1575 : : break;
1576 : : }
1577 [ # # ]: 0 : if (timer->tmr_device >= id.device) {
1578 [ # # ]: 0 : snd_timer_user_copy_id(&id, timer);
1579 : : break;
1580 : : }
1581 : : }
1582 [ # # ]: 0 : if (p == &snd_timer_list)
1583 : 0 : snd_timer_user_zero_id(&id);
1584 : : break;
1585 : 0 : case SNDRV_TIMER_CLASS_CARD:
1586 : : case SNDRV_TIMER_CLASS_PCM:
1587 [ # # ]: 0 : if (id.card < 0) {
1588 : 0 : id.card = 0;
1589 : : } else {
1590 [ # # ]: 0 : if (id.device < 0) {
1591 : 0 : id.device = 0;
1592 : : } else {
1593 [ # # ]: 0 : if (id.subdevice < 0)
1594 : 0 : id.subdevice = 0;
1595 [ # # ]: 0 : else if (id.subdevice < INT_MAX)
1596 : 0 : id.subdevice++;
1597 : : }
1598 : : }
1599 [ # # ]: 0 : list_for_each(p, &snd_timer_list) {
1600 : 0 : timer = list_entry(p, struct snd_timer, device_list);
1601 [ # # ]: 0 : if (timer->tmr_class > id.dev_class) {
1602 [ # # ]: 0 : snd_timer_user_copy_id(&id, timer);
1603 : : break;
1604 : : }
1605 [ # # ]: 0 : if (timer->tmr_class < id.dev_class)
1606 : 0 : continue;
1607 [ # # ]: 0 : if (timer->card->number > id.card) {
1608 [ # # ]: 0 : snd_timer_user_copy_id(&id, timer);
1609 : : break;
1610 : : }
1611 [ # # ]: 0 : if (timer->card->number < id.card)
1612 : 0 : continue;
1613 [ # # ]: 0 : if (timer->tmr_device > id.device) {
1614 [ # # ]: 0 : snd_timer_user_copy_id(&id, timer);
1615 : : break;
1616 : : }
1617 [ # # ]: 0 : if (timer->tmr_device < id.device)
1618 : 0 : continue;
1619 [ # # ]: 0 : if (timer->tmr_subdevice > id.subdevice) {
1620 [ # # ]: 0 : snd_timer_user_copy_id(&id, timer);
1621 : : break;
1622 : : }
1623 [ # # ]: 0 : if (timer->tmr_subdevice < id.subdevice)
1624 : 0 : continue;
1625 [ # # ]: 0 : snd_timer_user_copy_id(&id, timer);
1626 : : break;
1627 : : }
1628 [ # # ]: 0 : if (p == &snd_timer_list)
1629 : 0 : snd_timer_user_zero_id(&id);
1630 : : break;
1631 : : default:
1632 : 0 : snd_timer_user_zero_id(&id);
1633 : : }
1634 : : }
1635 : 0 : mutex_unlock(®ister_mutex);
1636 [ # # ]: 0 : if (copy_to_user(_tid, &id, sizeof(*_tid)))
1637 : 0 : return -EFAULT;
1638 : : return 0;
1639 : : }
1640 : :
1641 : : static int snd_timer_user_ginfo(struct file *file,
1642 : : struct snd_timer_ginfo __user *_ginfo)
1643 : : {
1644 : : struct snd_timer_ginfo *ginfo;
1645 : : struct snd_timer_id tid;
1646 : : struct snd_timer *t;
1647 : : struct list_head *p;
1648 : : int err = 0;
1649 : :
1650 : : ginfo = memdup_user(_ginfo, sizeof(*ginfo));
1651 : : if (IS_ERR(ginfo))
1652 : : return PTR_ERR(ginfo);
1653 : :
1654 : : tid = ginfo->tid;
1655 : : memset(ginfo, 0, sizeof(*ginfo));
1656 : : ginfo->tid = tid;
1657 : : mutex_lock(®ister_mutex);
1658 : : t = snd_timer_find(&tid);
1659 : : if (t != NULL) {
1660 : : ginfo->card = t->card ? t->card->number : -1;
1661 : : if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
1662 : : ginfo->flags |= SNDRV_TIMER_FLG_SLAVE;
1663 : : strlcpy(ginfo->id, t->id, sizeof(ginfo->id));
1664 : : strlcpy(ginfo->name, t->name, sizeof(ginfo->name));
1665 : : ginfo->resolution = t->hw.resolution;
1666 : : if (t->hw.resolution_min > 0) {
1667 : : ginfo->resolution_min = t->hw.resolution_min;
1668 : : ginfo->resolution_max = t->hw.resolution_max;
1669 : : }
1670 : : list_for_each(p, &t->open_list_head) {
1671 : : ginfo->clients++;
1672 : : }
1673 : : } else {
1674 : : err = -ENODEV;
1675 : : }
1676 : : mutex_unlock(®ister_mutex);
1677 : : if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
1678 : : err = -EFAULT;
1679 : : kfree(ginfo);
1680 : : return err;
1681 : : }
1682 : :
1683 : 0 : static int timer_set_gparams(struct snd_timer_gparams *gparams)
1684 : : {
1685 : 0 : struct snd_timer *t;
1686 : 0 : int err;
1687 : :
1688 : 0 : mutex_lock(®ister_mutex);
1689 : 0 : t = snd_timer_find(&gparams->tid);
1690 [ # # ]: 0 : if (!t) {
1691 : 0 : err = -ENODEV;
1692 : 0 : goto _error;
1693 : : }
1694 [ # # ]: 0 : if (!list_empty(&t->open_list_head)) {
1695 : 0 : err = -EBUSY;
1696 : 0 : goto _error;
1697 : : }
1698 [ # # ]: 0 : if (!t->hw.set_period) {
1699 : 0 : err = -ENOSYS;
1700 : 0 : goto _error;
1701 : : }
1702 : 0 : err = t->hw.set_period(t, gparams->period_num, gparams->period_den);
1703 : 0 : _error:
1704 : 0 : mutex_unlock(®ister_mutex);
1705 : 0 : return err;
1706 : : }
1707 : :
1708 : : static int snd_timer_user_gparams(struct file *file,
1709 : : struct snd_timer_gparams __user *_gparams)
1710 : : {
1711 : : struct snd_timer_gparams gparams;
1712 : :
1713 : : if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
1714 : : return -EFAULT;
1715 : : return timer_set_gparams(&gparams);
1716 : : }
1717 : :
1718 : : static int snd_timer_user_gstatus(struct file *file,
1719 : : struct snd_timer_gstatus __user *_gstatus)
1720 : : {
1721 : : struct snd_timer_gstatus gstatus;
1722 : : struct snd_timer_id tid;
1723 : : struct snd_timer *t;
1724 : : int err = 0;
1725 : :
1726 : : if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus)))
1727 : : return -EFAULT;
1728 : : tid = gstatus.tid;
1729 : : memset(&gstatus, 0, sizeof(gstatus));
1730 : : gstatus.tid = tid;
1731 : : mutex_lock(®ister_mutex);
1732 : : t = snd_timer_find(&tid);
1733 : : if (t != NULL) {
1734 : : spin_lock_irq(&t->lock);
1735 : : gstatus.resolution = snd_timer_hw_resolution(t);
1736 : : if (t->hw.precise_resolution) {
1737 : : t->hw.precise_resolution(t, &gstatus.resolution_num,
1738 : : &gstatus.resolution_den);
1739 : : } else {
1740 : : gstatus.resolution_num = gstatus.resolution;
1741 : : gstatus.resolution_den = 1000000000uL;
1742 : : }
1743 : : spin_unlock_irq(&t->lock);
1744 : : } else {
1745 : : err = -ENODEV;
1746 : : }
1747 : : mutex_unlock(®ister_mutex);
1748 : : if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
1749 : : err = -EFAULT;
1750 : : return err;
1751 : : }
1752 : :
1753 : : static int snd_timer_user_tselect(struct file *file,
1754 : : struct snd_timer_select __user *_tselect)
1755 : : {
1756 : : struct snd_timer_user *tu;
1757 : : struct snd_timer_select tselect;
1758 : : char str[32];
1759 : : int err = 0;
1760 : :
1761 : : tu = file->private_data;
1762 : : if (tu->timeri) {
1763 : : snd_timer_close(tu->timeri);
1764 : : snd_timer_instance_free(tu->timeri);
1765 : : tu->timeri = NULL;
1766 : : }
1767 : : if (copy_from_user(&tselect, _tselect, sizeof(tselect))) {
1768 : : err = -EFAULT;
1769 : : goto __err;
1770 : : }
1771 : : sprintf(str, "application %i", current->pid);
1772 : : if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
1773 : : tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
1774 : : tu->timeri = snd_timer_instance_new(str);
1775 : : if (!tu->timeri) {
1776 : : err = -ENOMEM;
1777 : : goto __err;
1778 : : }
1779 : :
1780 : : tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
1781 : : tu->timeri->callback = tu->tread
1782 : : ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
1783 : : tu->timeri->ccallback = snd_timer_user_ccallback;
1784 : : tu->timeri->callback_data = (void *)tu;
1785 : : tu->timeri->disconnect = snd_timer_user_disconnect;
1786 : :
1787 : : err = snd_timer_open(tu->timeri, &tselect.id, current->pid);
1788 : : if (err < 0) {
1789 : : snd_timer_instance_free(tu->timeri);
1790 : : tu->timeri = NULL;
1791 : : }
1792 : :
1793 : : __err:
1794 : : return err;
1795 : : }
1796 : :
1797 : : static int snd_timer_user_info(struct file *file,
1798 : : struct snd_timer_info __user *_info)
1799 : : {
1800 : : struct snd_timer_user *tu;
1801 : : struct snd_timer_info *info;
1802 : : struct snd_timer *t;
1803 : : int err = 0;
1804 : :
1805 : : tu = file->private_data;
1806 : : if (!tu->timeri)
1807 : : return -EBADFD;
1808 : : t = tu->timeri->timer;
1809 : : if (!t)
1810 : : return -EBADFD;
1811 : :
1812 : : info = kzalloc(sizeof(*info), GFP_KERNEL);
1813 : : if (! info)
1814 : : return -ENOMEM;
1815 : : info->card = t->card ? t->card->number : -1;
1816 : : if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
1817 : : info->flags |= SNDRV_TIMER_FLG_SLAVE;
1818 : : strlcpy(info->id, t->id, sizeof(info->id));
1819 : : strlcpy(info->name, t->name, sizeof(info->name));
1820 : : info->resolution = t->hw.resolution;
1821 : : if (copy_to_user(_info, info, sizeof(*_info)))
1822 : : err = -EFAULT;
1823 : : kfree(info);
1824 : : return err;
1825 : : }
1826 : :
1827 : : static int snd_timer_user_params(struct file *file,
1828 : : struct snd_timer_params __user *_params)
1829 : : {
1830 : : struct snd_timer_user *tu;
1831 : : struct snd_timer_params params;
1832 : : struct snd_timer *t;
1833 : : int err;
1834 : :
1835 : : tu = file->private_data;
1836 : : if (!tu->timeri)
1837 : : return -EBADFD;
1838 : : t = tu->timeri->timer;
1839 : : if (!t)
1840 : : return -EBADFD;
1841 : : if (copy_from_user(¶ms, _params, sizeof(params)))
1842 : : return -EFAULT;
1843 : : if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
1844 : : u64 resolution;
1845 : :
1846 : : if (params.ticks < 1) {
1847 : : err = -EINVAL;
1848 : : goto _end;
1849 : : }
1850 : :
1851 : : /* Don't allow resolution less than 1ms */
1852 : : resolution = snd_timer_resolution(tu->timeri);
1853 : : resolution *= params.ticks;
1854 : : if (resolution < 1000000) {
1855 : : err = -EINVAL;
1856 : : goto _end;
1857 : : }
1858 : : }
1859 : : if (params.queue_size > 0 &&
1860 : : (params.queue_size < 32 || params.queue_size > 1024)) {
1861 : : err = -EINVAL;
1862 : : goto _end;
1863 : : }
1864 : : if (params.filter & ~((1<<SNDRV_TIMER_EVENT_RESOLUTION)|
1865 : : (1<<SNDRV_TIMER_EVENT_TICK)|
1866 : : (1<<SNDRV_TIMER_EVENT_START)|
1867 : : (1<<SNDRV_TIMER_EVENT_STOP)|
1868 : : (1<<SNDRV_TIMER_EVENT_CONTINUE)|
1869 : : (1<<SNDRV_TIMER_EVENT_PAUSE)|
1870 : : (1<<SNDRV_TIMER_EVENT_SUSPEND)|
1871 : : (1<<SNDRV_TIMER_EVENT_RESUME)|
1872 : : (1<<SNDRV_TIMER_EVENT_MSTART)|
1873 : : (1<<SNDRV_TIMER_EVENT_MSTOP)|
1874 : : (1<<SNDRV_TIMER_EVENT_MCONTINUE)|
1875 : : (1<<SNDRV_TIMER_EVENT_MPAUSE)|
1876 : : (1<<SNDRV_TIMER_EVENT_MSUSPEND)|
1877 : : (1<<SNDRV_TIMER_EVENT_MRESUME))) {
1878 : : err = -EINVAL;
1879 : : goto _end;
1880 : : }
1881 : : snd_timer_stop(tu->timeri);
1882 : : spin_lock_irq(&t->lock);
1883 : : tu->timeri->flags &= ~(SNDRV_TIMER_IFLG_AUTO|
1884 : : SNDRV_TIMER_IFLG_EXCLUSIVE|
1885 : : SNDRV_TIMER_IFLG_EARLY_EVENT);
1886 : : if (params.flags & SNDRV_TIMER_PSFLG_AUTO)
1887 : : tu->timeri->flags |= SNDRV_TIMER_IFLG_AUTO;
1888 : : if (params.flags & SNDRV_TIMER_PSFLG_EXCLUSIVE)
1889 : : tu->timeri->flags |= SNDRV_TIMER_IFLG_EXCLUSIVE;
1890 : : if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT)
1891 : : tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT;
1892 : : spin_unlock_irq(&t->lock);
1893 : : if (params.queue_size > 0 &&
1894 : : (unsigned int)tu->queue_size != params.queue_size) {
1895 : : err = realloc_user_queue(tu, params.queue_size);
1896 : : if (err < 0)
1897 : : goto _end;
1898 : : }
1899 : : spin_lock_irq(&tu->qlock);
1900 : : tu->qhead = tu->qtail = tu->qused = 0;
1901 : : if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
1902 : : if (tu->tread) {
1903 : : struct snd_timer_tread64 tread;
1904 : : memset(&tread, 0, sizeof(tread));
1905 : : tread.event = SNDRV_TIMER_EVENT_EARLY;
1906 : : tread.tstamp_sec = 0;
1907 : : tread.tstamp_nsec = 0;
1908 : : tread.val = 0;
1909 : : snd_timer_user_append_to_tqueue(tu, &tread);
1910 : : } else {
1911 : : struct snd_timer_read *r = &tu->queue[0];
1912 : : r->resolution = 0;
1913 : : r->ticks = 0;
1914 : : tu->qused++;
1915 : : tu->qtail++;
1916 : : }
1917 : : }
1918 : : tu->filter = params.filter;
1919 : : tu->ticks = params.ticks;
1920 : : spin_unlock_irq(&tu->qlock);
1921 : : err = 0;
1922 : : _end:
1923 : : if (copy_to_user(_params, ¶ms, sizeof(params)))
1924 : : return -EFAULT;
1925 : : return err;
1926 : : }
1927 : :
1928 : : static int snd_timer_user_status32(struct file *file,
1929 : : struct snd_timer_status32 __user *_status)
1930 : : {
1931 : : struct snd_timer_user *tu;
1932 : : struct snd_timer_status32 status;
1933 : :
1934 : : tu = file->private_data;
1935 : : if (!tu->timeri)
1936 : : return -EBADFD;
1937 : : memset(&status, 0, sizeof(status));
1938 : : status.tstamp_sec = tu->tstamp.tv_sec;
1939 : : status.tstamp_nsec = tu->tstamp.tv_nsec;
1940 : : status.resolution = snd_timer_resolution(tu->timeri);
1941 : : status.lost = tu->timeri->lost;
1942 : : status.overrun = tu->overrun;
1943 : : spin_lock_irq(&tu->qlock);
1944 : : status.queue = tu->qused;
1945 : : spin_unlock_irq(&tu->qlock);
1946 : : if (copy_to_user(_status, &status, sizeof(status)))
1947 : : return -EFAULT;
1948 : : return 0;
1949 : : }
1950 : :
1951 : : static int snd_timer_user_status64(struct file *file,
1952 : : struct snd_timer_status64 __user *_status)
1953 : : {
1954 : : struct snd_timer_user *tu;
1955 : : struct snd_timer_status64 status;
1956 : :
1957 : : tu = file->private_data;
1958 : : if (!tu->timeri)
1959 : : return -EBADFD;
1960 : : memset(&status, 0, sizeof(status));
1961 : : status.tstamp_sec = tu->tstamp.tv_sec;
1962 : : status.tstamp_nsec = tu->tstamp.tv_nsec;
1963 : : status.resolution = snd_timer_resolution(tu->timeri);
1964 : : status.lost = tu->timeri->lost;
1965 : : status.overrun = tu->overrun;
1966 : : spin_lock_irq(&tu->qlock);
1967 : : status.queue = tu->qused;
1968 : : spin_unlock_irq(&tu->qlock);
1969 : : if (copy_to_user(_status, &status, sizeof(status)))
1970 : : return -EFAULT;
1971 : : return 0;
1972 : : }
1973 : :
1974 : : static int snd_timer_user_start(struct file *file)
1975 : : {
1976 : : int err;
1977 : : struct snd_timer_user *tu;
1978 : :
1979 : : tu = file->private_data;
1980 : : if (!tu->timeri)
1981 : : return -EBADFD;
1982 : : snd_timer_stop(tu->timeri);
1983 : : tu->timeri->lost = 0;
1984 : : tu->last_resolution = 0;
1985 : : err = snd_timer_start(tu->timeri, tu->ticks);
1986 : : if (err < 0)
1987 : : return err;
1988 : : return 0;
1989 : : }
1990 : :
1991 : 0 : static int snd_timer_user_stop(struct file *file)
1992 : : {
1993 : 0 : int err;
1994 : 0 : struct snd_timer_user *tu;
1995 : :
1996 : 0 : tu = file->private_data;
1997 : 0 : if (!tu->timeri)
1998 : : return -EBADFD;
1999 : 0 : err = snd_timer_stop(tu->timeri);
2000 : 0 : if (err < 0)
2001 : : return err;
2002 : : return 0;
2003 : : }
2004 : :
2005 : : static int snd_timer_user_continue(struct file *file)
2006 : : {
2007 : : int err;
2008 : : struct snd_timer_user *tu;
2009 : :
2010 : : tu = file->private_data;
2011 : : if (!tu->timeri)
2012 : : return -EBADFD;
2013 : : /* start timer instead of continue if it's not used before */
2014 : : if (!(tu->timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
2015 : : return snd_timer_user_start(file);
2016 : : tu->timeri->lost = 0;
2017 : : err = snd_timer_continue(tu->timeri);
2018 : : if (err < 0)
2019 : : return err;
2020 : : return 0;
2021 : : }
2022 : :
2023 : 0 : static int snd_timer_user_pause(struct file *file)
2024 : : {
2025 : 0 : int err;
2026 : 0 : struct snd_timer_user *tu;
2027 : :
2028 : 0 : tu = file->private_data;
2029 : 0 : if (!tu->timeri)
2030 : : return -EBADFD;
2031 : 0 : err = snd_timer_pause(tu->timeri);
2032 : 0 : if (err < 0)
2033 : : return err;
2034 : : return 0;
2035 : : }
2036 : :
2037 : 0 : static int snd_timer_user_tread(void __user *argp, struct snd_timer_user *tu,
2038 : : unsigned int cmd, bool compat)
2039 : : {
2040 : 0 : int __user *p = argp;
2041 : 0 : int xarg, old_tread;
2042 : :
2043 [ # # ]: 0 : if (tu->timeri) /* too late */
2044 : : return -EBUSY;
2045 [ # # ]: 0 : if (get_user(xarg, p))
2046 : : return -EFAULT;
2047 : :
2048 : 0 : old_tread = tu->tread;
2049 : :
2050 [ # # ]: 0 : if (!xarg)
2051 : 0 : tu->tread = TREAD_FORMAT_NONE;
2052 : 0 : else if (cmd == SNDRV_TIMER_IOCTL_TREAD64 ||
2053 [ # # ]: 0 : (IS_ENABLED(CONFIG_64BIT) && !compat))
2054 : 0 : tu->tread = TREAD_FORMAT_TIME64;
2055 : : else
2056 : 0 : tu->tread = TREAD_FORMAT_TIME32;
2057 : :
2058 [ # # # # ]: 0 : if (tu->tread != old_tread &&
2059 : 0 : realloc_user_queue(tu, tu->queue_size) < 0) {
2060 : 0 : tu->tread = old_tread;
2061 : 0 : return -ENOMEM;
2062 : : }
2063 : :
2064 : : return 0;
2065 : : }
2066 : :
2067 : : enum {
2068 : : SNDRV_TIMER_IOCTL_START_OLD = _IO('T', 0x20),
2069 : : SNDRV_TIMER_IOCTL_STOP_OLD = _IO('T', 0x21),
2070 : : SNDRV_TIMER_IOCTL_CONTINUE_OLD = _IO('T', 0x22),
2071 : : SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
2072 : : };
2073 : :
2074 : 0 : static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
2075 : : unsigned long arg, bool compat)
2076 : : {
2077 : 0 : struct snd_timer_user *tu;
2078 : 0 : void __user *argp = (void __user *)arg;
2079 : 0 : int __user *p = argp;
2080 : :
2081 : 0 : tu = file->private_data;
2082 [ # # # # : 0 : switch (cmd) {
# # # # #
# # # # #
# # ]
2083 : : case SNDRV_TIMER_IOCTL_PVERSION:
2084 [ # # ]: 0 : return put_user(SNDRV_TIMER_VERSION, p) ? -EFAULT : 0;
2085 : 0 : case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
2086 : 0 : return snd_timer_user_next_device(argp);
2087 : 0 : case SNDRV_TIMER_IOCTL_TREAD_OLD:
2088 : : case SNDRV_TIMER_IOCTL_TREAD64:
2089 : 0 : return snd_timer_user_tread(argp, tu, cmd, compat);
2090 : 0 : case SNDRV_TIMER_IOCTL_GINFO:
2091 : 0 : return snd_timer_user_ginfo(file, argp);
2092 : 0 : case SNDRV_TIMER_IOCTL_GPARAMS:
2093 : 0 : return snd_timer_user_gparams(file, argp);
2094 : 0 : case SNDRV_TIMER_IOCTL_GSTATUS:
2095 : 0 : return snd_timer_user_gstatus(file, argp);
2096 : 0 : case SNDRV_TIMER_IOCTL_SELECT:
2097 : 0 : return snd_timer_user_tselect(file, argp);
2098 : 0 : case SNDRV_TIMER_IOCTL_INFO:
2099 : 0 : return snd_timer_user_info(file, argp);
2100 : 0 : case SNDRV_TIMER_IOCTL_PARAMS:
2101 : 0 : return snd_timer_user_params(file, argp);
2102 : 0 : case SNDRV_TIMER_IOCTL_STATUS32:
2103 : 0 : return snd_timer_user_status32(file, argp);
2104 : 0 : case SNDRV_TIMER_IOCTL_STATUS64:
2105 : 0 : return snd_timer_user_status64(file, argp);
2106 : 0 : case SNDRV_TIMER_IOCTL_START:
2107 : : case SNDRV_TIMER_IOCTL_START_OLD:
2108 : 0 : return snd_timer_user_start(file);
2109 : 0 : case SNDRV_TIMER_IOCTL_STOP:
2110 : : case SNDRV_TIMER_IOCTL_STOP_OLD:
2111 [ # # ]: 0 : return snd_timer_user_stop(file);
2112 : 0 : case SNDRV_TIMER_IOCTL_CONTINUE:
2113 : : case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
2114 : 0 : return snd_timer_user_continue(file);
2115 : 0 : case SNDRV_TIMER_IOCTL_PAUSE:
2116 : : case SNDRV_TIMER_IOCTL_PAUSE_OLD:
2117 [ # # ]: 0 : return snd_timer_user_pause(file);
2118 : : }
2119 : : return -ENOTTY;
2120 : : }
2121 : :
2122 : 0 : static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
2123 : : unsigned long arg)
2124 : : {
2125 : 0 : struct snd_timer_user *tu = file->private_data;
2126 : 0 : long ret;
2127 : :
2128 : 0 : mutex_lock(&tu->ioctl_lock);
2129 : 0 : ret = __snd_timer_user_ioctl(file, cmd, arg, false);
2130 : 0 : mutex_unlock(&tu->ioctl_lock);
2131 : 0 : return ret;
2132 : : }
2133 : :
2134 : 0 : static int snd_timer_user_fasync(int fd, struct file * file, int on)
2135 : : {
2136 : 0 : struct snd_timer_user *tu;
2137 : :
2138 : 0 : tu = file->private_data;
2139 : 0 : return fasync_helper(fd, file, on, &tu->fasync);
2140 : : }
2141 : :
2142 : 0 : static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
2143 : : size_t count, loff_t *offset)
2144 : : {
2145 : 0 : struct snd_timer_tread64 *tread;
2146 : 0 : struct snd_timer_tread32 tread32;
2147 : 0 : struct snd_timer_user *tu;
2148 : 0 : long result = 0, unit;
2149 : 0 : int qhead;
2150 : 0 : int err = 0;
2151 : :
2152 : 0 : tu = file->private_data;
2153 [ # # ]: 0 : switch (tu->tread) {
2154 : : case TREAD_FORMAT_TIME64:
2155 : : unit = sizeof(struct snd_timer_tread64);
2156 : : break;
2157 : : case TREAD_FORMAT_TIME32:
2158 : : unit = sizeof(struct snd_timer_tread32);
2159 : : break;
2160 : : case TREAD_FORMAT_NONE:
2161 : : unit = sizeof(struct snd_timer_read);
2162 : : break;
2163 : : default:
2164 [ # # ]: 0 : WARN_ONCE(1, "Corrupt snd_timer_user\n");
2165 : : return -ENOTSUPP;
2166 : : }
2167 : :
2168 : 0 : mutex_lock(&tu->ioctl_lock);
2169 : 0 : spin_lock_irq(&tu->qlock);
2170 [ # # ]: 0 : while ((long)count - result >= unit) {
2171 [ # # ]: 0 : while (!tu->qused) {
2172 : 0 : wait_queue_entry_t wait;
2173 : :
2174 [ # # # # ]: 0 : if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
2175 : 0 : err = -EAGAIN;
2176 : 0 : goto _error;
2177 : : }
2178 : :
2179 : 0 : set_current_state(TASK_INTERRUPTIBLE);
2180 : 0 : init_waitqueue_entry(&wait, current);
2181 : 0 : add_wait_queue(&tu->qchange_sleep, &wait);
2182 : :
2183 : 0 : spin_unlock_irq(&tu->qlock);
2184 : 0 : mutex_unlock(&tu->ioctl_lock);
2185 : 0 : schedule();
2186 : 0 : mutex_lock(&tu->ioctl_lock);
2187 : 0 : spin_lock_irq(&tu->qlock);
2188 : :
2189 : 0 : remove_wait_queue(&tu->qchange_sleep, &wait);
2190 : :
2191 [ # # ]: 0 : if (tu->disconnected) {
2192 : 0 : err = -ENODEV;
2193 : 0 : goto _error;
2194 : : }
2195 [ # # ]: 0 : if (signal_pending(current)) {
2196 : 0 : err = -ERESTARTSYS;
2197 : 0 : goto _error;
2198 : : }
2199 : : }
2200 : :
2201 : 0 : qhead = tu->qhead++;
2202 : 0 : tu->qhead %= tu->queue_size;
2203 : 0 : tu->qused--;
2204 : 0 : spin_unlock_irq(&tu->qlock);
2205 : :
2206 : 0 : tread = &tu->tqueue[qhead];
2207 : :
2208 [ # # # # ]: 0 : switch (tu->tread) {
2209 : : case TREAD_FORMAT_TIME64:
2210 [ # # # # ]: 0 : if (copy_to_user(buffer, tread,
2211 : : sizeof(struct snd_timer_tread64)))
2212 : : err = -EFAULT;
2213 : : break;
2214 : 0 : case TREAD_FORMAT_TIME32:
2215 : 0 : memset(&tread32, 0, sizeof(tread32));
2216 : 0 : tread32 = (struct snd_timer_tread32) {
2217 : 0 : .event = tread->event,
2218 : 0 : .tstamp_sec = tread->tstamp_sec,
2219 : 0 : .tstamp_nsec = tread->tstamp_nsec,
2220 : 0 : .val = tread->val,
2221 : : };
2222 : :
2223 [ # # ]: 0 : if (copy_to_user(buffer, &tread32, sizeof(tread32)))
2224 : 0 : err = -EFAULT;
2225 : : break;
2226 : 0 : case TREAD_FORMAT_NONE:
2227 [ # # # # ]: 0 : if (copy_to_user(buffer, &tu->queue[qhead],
2228 : : sizeof(struct snd_timer_read)))
2229 : : err = -EFAULT;
2230 : : break;
2231 : : default:
2232 : : err = -ENOTSUPP;
2233 : : break;
2234 : : }
2235 : :
2236 : 0 : spin_lock_irq(&tu->qlock);
2237 [ # # ]: 0 : if (err < 0)
2238 : 0 : goto _error;
2239 : 0 : result += unit;
2240 : 0 : buffer += unit;
2241 : : }
2242 : 0 : _error:
2243 : 0 : spin_unlock_irq(&tu->qlock);
2244 : 0 : mutex_unlock(&tu->ioctl_lock);
2245 [ # # ]: 0 : return result > 0 ? result : err;
2246 : : }
2247 : :
2248 : 0 : static __poll_t snd_timer_user_poll(struct file *file, poll_table * wait)
2249 : : {
2250 : 0 : __poll_t mask;
2251 : 0 : struct snd_timer_user *tu;
2252 : :
2253 : 0 : tu = file->private_data;
2254 : :
2255 [ # # ]: 0 : poll_wait(file, &tu->qchange_sleep, wait);
2256 : :
2257 : 0 : mask = 0;
2258 : 0 : spin_lock_irq(&tu->qlock);
2259 [ # # ]: 0 : if (tu->qused)
2260 : 0 : mask |= EPOLLIN | EPOLLRDNORM;
2261 [ # # ]: 0 : if (tu->disconnected)
2262 : 0 : mask |= EPOLLERR;
2263 : 0 : spin_unlock_irq(&tu->qlock);
2264 : :
2265 : 0 : return mask;
2266 : : }
2267 : :
2268 : : #ifdef CONFIG_COMPAT
2269 : : #include "timer_compat.c"
2270 : : #else
2271 : : #define snd_timer_user_ioctl_compat NULL
2272 : : #endif
2273 : :
2274 : : static const struct file_operations snd_timer_f_ops =
2275 : : {
2276 : : .owner = THIS_MODULE,
2277 : : .read = snd_timer_user_read,
2278 : : .open = snd_timer_user_open,
2279 : : .release = snd_timer_user_release,
2280 : : .llseek = no_llseek,
2281 : : .poll = snd_timer_user_poll,
2282 : : .unlocked_ioctl = snd_timer_user_ioctl,
2283 : : .compat_ioctl = snd_timer_user_ioctl_compat,
2284 : : .fasync = snd_timer_user_fasync,
2285 : : };
2286 : :
2287 : : /* unregister the system timer */
2288 : 0 : static void snd_timer_free_all(void)
2289 : : {
2290 : 0 : struct snd_timer *timer, *n;
2291 : :
2292 [ # # ]: 0 : list_for_each_entry_safe(timer, n, &snd_timer_list, device_list)
2293 : 0 : snd_timer_free(timer);
2294 : 0 : }
2295 : :
2296 : : static struct device timer_dev;
2297 : :
2298 : : /*
2299 : : * ENTRY functions
2300 : : */
2301 : :
2302 : 30 : static int __init alsa_timer_init(void)
2303 : : {
2304 : 30 : int err;
2305 : :
2306 : 30 : snd_device_initialize(&timer_dev, NULL);
2307 : 30 : dev_set_name(&timer_dev, "timer");
2308 : :
2309 : : #ifdef SNDRV_OSS_INFO_DEV_TIMERS
2310 : : snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
2311 : : "system timer");
2312 : : #endif
2313 : :
2314 : 30 : err = snd_timer_register_system();
2315 [ - + ]: 30 : if (err < 0) {
2316 : 0 : pr_err("ALSA: unable to register system timer (%i)\n", err);
2317 : 0 : goto put_timer;
2318 : : }
2319 : :
2320 : 30 : err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
2321 : : &snd_timer_f_ops, NULL, &timer_dev);
2322 [ - + ]: 30 : if (err < 0) {
2323 : 0 : pr_err("ALSA: unable to register timer device (%i)\n", err);
2324 : 0 : snd_timer_free_all();
2325 : 0 : goto put_timer;
2326 : : }
2327 : :
2328 : 30 : snd_timer_proc_init();
2329 : 30 : return 0;
2330 : :
2331 : 0 : put_timer:
2332 : 0 : put_device(&timer_dev);
2333 : 0 : return err;
2334 : : }
2335 : :
2336 : 0 : static void __exit alsa_timer_exit(void)
2337 : : {
2338 : 0 : snd_unregister_device(&timer_dev);
2339 : 0 : snd_timer_free_all();
2340 : 0 : put_device(&timer_dev);
2341 : 0 : snd_timer_proc_done();
2342 : : #ifdef SNDRV_OSS_INFO_DEV_TIMERS
2343 : : snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1);
2344 : : #endif
2345 : 0 : }
2346 : :
2347 : : module_init(alsa_timer_init)
2348 : : module_exit(alsa_timer_exit)
|