Update of /cvsroot/alsa/alsa-kernel/core
In directory sc8-pr-cvs1:/tmp/cvs-serv5376/core
Modified Files:
timer.c
Log Message:
Enhanced timer API (global functions - ginfo, gparams, gstatus).
Added filter for tread.
Index: timer.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/timer.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- timer.c 1 Mar 2003 20:42:01 -0000 1.31
+++ timer.c 2 Mar 2003 10:44:12 -0000 1.32
@@ -62,6 +62,7 @@
snd_timer_tread_t *tqueue;
spinlock_t qlock;
unsigned long last_resolution;
+ unsigned int filter;
wait_queue_head_t qchange_sleep;
struct fasync_struct *fasync;
} snd_timer_user_t;
@@ -1071,6 +1072,8 @@
snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data,
return);
snd_timer_tread_t r1;
+ if ((tu->filter & (1 << event)) == 0)
+ return;
r1.event = event;
r1.tstamp = *tstamp;
r1.val = resolution;
@@ -1086,23 +1089,35 @@
snd_timer_user_t *tu = snd_magic_cast(snd_timer_user_t, timeri->callback_data,
return);
snd_timer_tread_t *r, r1;
struct timespec tstamp;
- int prev;
+ int prev, append = 0;
- snd_timestamp_now(&tstamp, 1);
+ snd_timestamp_zero(&tstamp);
spin_lock(&tu->qlock);
- if (tu->last_resolution != resolution) {
+ if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 <<
SNDRV_TIMER_EVENT_TICK))) == 0) {
+ spin_unlock(&tu->qlock);
+ return;
+ }
+ if (tu->last_resolution != resolution || ticks > 0)
+ snd_timestamp_now(&tstamp, 1);
+ if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution
!= resolution) {
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;
}
}
@@ -1110,8 +1125,11 @@
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);
}
@@ -1264,6 +1282,100 @@
return 0;
}
+static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t *_ginfo)
+{
+ snd_timer_ginfo_t ginfo;
+ snd_timer_id_t tid;
+ snd_timer_t *t;
+ struct list_head *p;
+ int err = 0;
+
+ if (copy_from_user(&ginfo, _ginfo, sizeof(ginfo)))
+ return -EFAULT;
+ tid = ginfo.tid;
+ memset(&ginfo, 0, sizeof(ginfo));
+ ginfo.tid = tid;
+ down(®ister_mutex);
+ 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;
+ strncpy(ginfo.id, t->id, sizeof(ginfo.id)-1);
+ strncpy(ginfo.name, t->name, sizeof(ginfo.name)-1);
+ ginfo.ticks = t->hw.ticks;
+ 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;
+ ginfo.resolution_step = t->hw.resolution_step;
+ }
+ list_for_each(p, &t->open_list_head) {
+ ginfo.instances++;
+ }
+ } else {
+ err = -ENOENT;
+ }
+ up(®ister_mutex);
+ if (err >= 0 && copy_to_user(_ginfo, &ginfo, sizeof(ginfo)))
+ err = -EFAULT;
+ return err;
+}
+
+static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t *_gparams)
+{
+ snd_timer_gparams_t gparams;
+ snd_timer_t *t;
+ int err;
+
+ if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
+ return -EFAULT;
+ down(®ister_mutex);
+ t = snd_timer_find(&gparams.tid);
+ if (t != NULL) {
+ if (list_empty(&t->open_list_head)) {
+ if (t->hw.set_resolution)
+ err = t->hw.set_resolution(t, gparams.resolution);
+ else
+ err = -ENOSYS;
+ } else {
+ err = -EBUSY;
+ }
+ } else {
+ err = -ENOENT;
+ }
+ up(®ister_mutex);
+ return err;
+}
+
+static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t *_gstatus)
+{
+ snd_timer_gstatus_t gstatus;
+ snd_timer_id_t tid;
+ snd_timer_t *t;
+ int err = 0;
+
+ if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus)))
+ return -EFAULT;
+ tid = gstatus.tid;
+ memset(&gstatus, 0, sizeof(gstatus));
+ gstatus.tid = tid;
+ down(®ister_mutex);
+ 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;
+ } else {
+ err = -ENOENT;
+ }
+ up(®ister_mutex);
+ if (err >= 0 && copy_from_user(_gstatus, &gstatus, sizeof(gstatus)))
+ err = -EFAULT;
+ return err;
+}
+
static int snd_timer_user_tselect(struct file *file, snd_timer_select_t *_tselect)
{
snd_timer_user_t *tu;
@@ -1357,6 +1469,19 @@
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)|
+ (1<<SNDRV_TIMER_EVENT_MSTART)|
+ (1<<SNDRV_TIMER_EVENT_MSTOP)|
+ (1<<SNDRV_TIMER_EVENT_MCONTINUE)|
+ (1<<SNDRV_TIMER_EVENT_MPAUSE))) {
+ err = -EINVAL;
+ goto _end;
+ }
snd_timer_stop(tu->timeri);
spin_lock_irqsave(&t->lock, flags);
if (params.flags & SNDRV_TIMER_PSFLG_AUTO) {
@@ -1382,6 +1507,7 @@
}
}
}
+ tu->filter = params.filter;
tu->ticks = params.ticks;
err = 0;
_end:
@@ -1466,6 +1592,12 @@
tu->tread = xarg ? 1 : 0;
return 0;
}
+ case SNDRV_TIMER_IOCTL_GINFO:
+ return snd_timer_user_ginfo(file, (snd_timer_ginfo_t *)arg);
+ case SNDRV_TIMER_IOCTL_GPARAMS:
+ return snd_timer_user_gparams(file, (snd_timer_gparams_t *)arg);
+ case SNDRV_TIMER_IOCTL_GSTATUS:
+ return snd_timer_user_gstatus(file, (snd_timer_gstatus_t *)arg);
case SNDRV_TIMER_IOCTL_SELECT:
return snd_timer_user_tselect(file, (snd_timer_select_t *)arg);
case SNDRV_TIMER_IOCTL_INFO:
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog