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