Loading sound/core/timer.c +167 −112 Original line number Diff line number Diff line Loading @@ -95,7 +95,8 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left); * create a timer instance with the given owner string. * when timer is not NULL, increments the module counter */ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer) static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer) { snd_timer_instance_t *timeri; timeri = kzalloc(sizeof(*timeri), GFP_KERNEL); Loading Loading @@ -192,7 +193,8 @@ static void snd_timer_check_slave(snd_timer_instance_t *slave) if (slave->slave_class == master->slave_class && slave->slave_id == master->slave_id) { list_del(&slave->open_list); list_add_tail(&slave->open_list, &master->slave_list_head); list_add_tail(&slave->open_list, &master->slave_list_head); spin_lock_irq(&slave_active_lock); slave->master = master; slave->timer = master->timer; Loading Loading @@ -225,7 +227,8 @@ static void snd_timer_check_master(snd_timer_instance_t *master) slave->master = master; slave->timer = master->timer; if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) list_add_tail(&slave->active_list, &master->slave_active_head); list_add_tail(&slave->active_list, &master->slave_active_head); spin_unlock_irq(&slave_active_lock); } } Loading Loading @@ -304,7 +307,8 @@ int snd_timer_open(snd_timer_instance_t **ti, return 0; } static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event); static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event); /* * close a timer instance Loading Loading @@ -344,7 +348,8 @@ int snd_timer_close(snd_timer_instance_t * timeri) spin_unlock_irq(&timer->lock); down(®ister_mutex); list_del(&timeri->open_list); if (timer && list_empty(&timer->open_list_head) && timer->hw.close) if (timer && list_empty(&timer->open_list_head) && timer->hw.close) timer->hw.close(timer); /* remove slave links */ list_for_each_safe(p, n, &timeri->slave_list_head) { Loading Loading @@ -382,7 +387,8 @@ unsigned long snd_timer_resolution(snd_timer_instance_t * timeri) return 0; } static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event) static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event) { snd_timer_t *timer; unsigned long flags; Loading @@ -392,8 +398,10 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e struct timespec tstamp; getnstimeofday(&tstamp); snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return); if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE) snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return); if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE) resolution = snd_timer_resolution(ti); if (ti->ccallback) ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); Loading @@ -413,7 +421,8 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e spin_unlock_irqrestore(&timer->lock, flags); } static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks) static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks) { list_del(&timeri->active_list); list_add_tail(&timeri->active_list, &timer->active_list_head); Loading @@ -440,7 +449,8 @@ static int snd_timer_start_slave(snd_timer_instance_t *timeri) spin_lock_irqsave(&slave_active_lock, flags); timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; if (timeri->master) list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); spin_unlock_irqrestore(&slave_active_lock, flags); return 1; /* delayed start */ } Loading Loading @@ -473,7 +483,8 @@ int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) return result; } static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event) static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event) { snd_timer_t *timer; unsigned long flags; Loading Loading @@ -507,7 +518,8 @@ static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sn } } if (!keep_flag) timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START); timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); spin_unlock_irqrestore(&timer->lock, flags); __end: if (event != SNDRV_TIMER_EVENT_RESOLUTION) Loading Loading @@ -650,7 +662,7 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) { snd_timer_instance_t *ti, *ts; unsigned long resolution, ticks; struct list_head *p, *q, *n; struct list_head *p, *q, *n, *ack_list_head; int use_tasklet = 0; if (timer == NULL) Loading @@ -665,8 +677,9 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) resolution = timer->hw.resolution; /* loop for all active instances * here we cannot use list_for_each because the active_list of a processed * instance is relinked to done_list_head before callback is called. * Here we cannot use list_for_each because the active_list of a * processed instance is relinked to done_list_head before the callback * is called. */ list_for_each_safe(p, n, &timer->active_list_head) { ti = list_entry(p, snd_timer_instance_t, active_list); Loading @@ -687,26 +700,19 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) if (--timer->running) list_del(p); } if (list_empty(&ti->ack_list)) { if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || (ti->flags & SNDRV_TIMER_IFLG_FAST)) { list_add_tail(&ti->ack_list, &timer->ack_list_head); } else { list_add_tail(&ti->ack_list, &timer->sack_list_head); } } (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); list_for_each(q, &ti->slave_active_head) { ts = list_entry(q, snd_timer_instance_t, active_list); ts->pticks = ti->pticks; ts->resolution = resolution; if (list_empty(&ts->ack_list)) { if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || (ti->flags & SNDRV_TIMER_IFLG_FAST)) { list_add_tail(&ts->ack_list, &timer->ack_list_head); } else { list_add_tail(&ts->ack_list, &timer->sack_list_head); } } if (list_empty(&ts->ack_list)) list_add_tail(&ts->ack_list, ack_list_head); } } if (timer->flags & SNDRV_TIMER_FLG_RESCHED) Loading Loading @@ -757,7 +763,8 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) */ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer) int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t **rtimer) { snd_timer_t *timer; int err; Loading Loading @@ -785,10 +792,12 @@ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t * INIT_LIST_HEAD(&timer->ack_list_head); INIT_LIST_HEAD(&timer->sack_list_head); spin_lock_init(&timer->lock); tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); if (card != NULL) { timer->module = card->module; if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) { err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); if (err < 0) { snd_timer_free(timer); return err; } Loading Loading @@ -818,7 +827,8 @@ static int snd_timer_dev_register(snd_device_t *dev) snd_timer_t *timer1; struct list_head *p; snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO); snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO); if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && !timer->hw.resolution && timer->hw.c_resolution == NULL) return -EINVAL; Loading Loading @@ -879,7 +889,8 @@ static int snd_timer_dev_unregister(snd_device_t *device) return snd_timer_unregister(timer); } void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp) void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp) { unsigned long flags; unsigned long resolution = 0; Loading @@ -888,7 +899,8 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) return; snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return); snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return); spin_lock_irqsave(&timer->lock, flags); if (event == SNDRV_TIMER_EVENT_MSTART || event == SNDRV_TIMER_EVENT_MCONTINUE || Loading Loading @@ -1021,7 +1033,8 @@ static int snd_timer_register_system(void) struct snd_timer_system_private *priv; int err; if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0) err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer); if (err < 0) return err; strcpy(timer->name, "system timer"); timer->hw = snd_timer_system; Loading Loading @@ -1058,27 +1071,35 @@ static void snd_timer_proc_read(snd_info_entry_t *entry, snd_iprintf(buffer, "G%i: ", timer->tmr_device); break; case SNDRV_TIMER_CLASS_CARD: snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device); snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device); break; case SNDRV_TIMER_CLASS_PCM: snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice); snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice); break; default: snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice); snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice); } snd_iprintf(buffer, "%s :", timer->name); if (timer->hw.resolution) snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks); snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks); if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) snd_iprintf(buffer, " SLAVE"); snd_iprintf(buffer, "\n"); spin_lock_irqsave(&timer->lock, flags); list_for_each(q, &timer->open_list_head) { ti = list_entry(q, snd_timer_instance_t, open_list); snd_iprintf(buffer, " Client %s : %s : lost interrupts %li\n", snd_iprintf(buffer, " Client %s : %s\n", ti->owner ? ti->owner : "unknown", ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped", ti->lost); ti->flags & (SNDRV_TIMER_IFLG_START | SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped"); } spin_unlock_irqrestore(&timer->lock, flags); } Loading Loading @@ -1121,7 +1142,8 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri, wake_up(&tu->qchange_sleep); } static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread) static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread) { if (tu->qused >= tu->queue_size) { tu->overrun++; Loading @@ -1140,7 +1162,8 @@ static void snd_timer_user_ccallback(snd_timer_instance_t *timeri, snd_timer_user_t *tu = timeri->callback_data; snd_timer_tread_t r1; if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE) if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE) tu->tstamp = *tstamp; if ((tu->filter & (1 << event)) == 0 || !tu->tread) return; Loading @@ -1165,13 +1188,15 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri, memset(&tstamp, 0, sizeof(tstamp)); spin_lock(&tu->qlock); if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) { 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) getnstimeofday(&tstamp); if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { r1.event = SNDRV_TIMER_EVENT_RESOLUTION; r1.tstamp = tstamp; r1.val = resolution; Loading Loading @@ -1218,7 +1243,8 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) init_MUTEX(&tu->tread_sem); tu->ticks = 1; tu->queue_size = 128; tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); if (tu->queue == NULL) { kfree(tu); return -ENOMEM; Loading Loading @@ -1308,7 +1334,11 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) if (id.device < 0) { id.device = 0; } else { id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1; if (id.subdevice < 0) { id.subdevice = 0; } else { id.subdevice++; } } } } Loading Loading @@ -1354,7 +1384,8 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) return 0; } static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo) static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo) { snd_timer_ginfo_t *ginfo; snd_timer_id_t tid; Loading Loading @@ -1398,7 +1429,8 @@ static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_gi return err; } static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams) static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams) { snd_timer_gparams_t gparams; snd_timer_t *t; Loading @@ -1408,23 +1440,26 @@ static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user 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_period) err = t->hw.set_period(t, gparams.period_num, gparams.period_den); else err = -ENOSYS; } else { if (!t) { err = -ENODEV; goto _error; } if (!list_empty(&t->open_list_head)) { err = -EBUSY; goto _error; } } else { err = -ENODEV; if (!t->hw.set_period) { err = -ENOSYS; goto _error; } err = t->hw.set_period(t, gparams.period_num, gparams.period_den); _error: up(®ister_mutex); return err; } static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus) static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus) { snd_timer_gstatus_t gstatus; snd_timer_id_t tid; Loading @@ -1444,7 +1479,8 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user else gstatus.resolution = t->hw.resolution; if (t->hw.precise_resolution) { t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den); t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den); } else { gstatus.resolution_num = gstatus.resolution; gstatus.resolution_den = 1000000000uL; Loading @@ -1458,7 +1494,8 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user return err; } static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect) static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect) { snd_timer_user_t *tu; snd_timer_select_t tselect; Loading @@ -1478,7 +1515,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * sprintf(str, "application %i", current->pid); if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid); if (err < 0) goto __err; kfree(tu->queue); Loading @@ -1486,11 +1524,13 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * kfree(tu->tqueue); tu->tqueue = NULL; if (tu->tread) { tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); if (tu->tqueue == NULL) err = -ENOMEM; } else { tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); if (tu->queue == NULL) err = -ENOMEM; } Loading @@ -1500,7 +1540,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * tu->timeri = NULL; } else { tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; tu->timeri->ccallback = snd_timer_user_ccallback; tu->timeri->callback_data = (void *)tu; } Loading @@ -1510,7 +1551,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * return err; } static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info) static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info) { snd_timer_user_t *tu; snd_timer_info_t *info; Loading @@ -1537,7 +1579,8 @@ static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info return err; } static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params) static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params) { snd_timer_user_t *tu; snd_timer_params_t params; Loading @@ -1556,7 +1599,8 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ err = -EINVAL; goto _end; } if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { err = -EINVAL; goto _end; } Loading Loading @@ -1589,16 +1633,19 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; spin_unlock_irq(&t->lock); if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) { if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) { if (tu->tread) { ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); ttr = kmalloc(params.queue_size * sizeof(*ttr), GFP_KERNEL); if (ttr) { kfree(tu->tqueue); tu->queue_size = params.queue_size; tu->tqueue = ttr; } } else { tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tr = kmalloc(params.queue_size * sizeof(*tr), GFP_KERNEL); if (tr) { kfree(tu->queue); tu->queue_size = params.queue_size; Loading @@ -1622,7 +1669,6 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ tu->qused++; tu->qtail++; } } tu->filter = params.filter; tu->ticks = params.ticks; Loading @@ -1633,7 +1679,8 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ return err; } static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status) static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status) { snd_timer_user_t *tu; snd_timer_status_t status; Loading Loading @@ -1704,7 +1751,8 @@ enum { SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), }; static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { snd_timer_user_t *tu; void __user *argp = (void __user *)arg; Loading Loading @@ -1775,7 +1823,8 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on) return 0; } static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset) static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset) { snd_timer_user_t *tu; long result = 0, unit; Loading Loading @@ -1814,12 +1863,14 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_ goto _error; if (tu->tread) { if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) { if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) { err = -EFAULT; goto _error; } } else { if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) { if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) { err = -EFAULT; goto _error; } Loading Loading @@ -1890,9 +1941,11 @@ static int __init alsa_timer_init(void) snd_info_entry_t *entry; #ifdef SNDRV_OSS_INFO_DEV_TIMERS snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer"); snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer"); #endif if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) { entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); if (entry != NULL) { entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128; entry->c.text.read = snd_timer_proc_read; if (snd_info_register(entry) < 0) { Loading @@ -1902,10 +1955,12 @@ static int __init alsa_timer_init(void) } snd_timer_proc_entry = entry; if ((err = snd_timer_register_system()) < 0) snd_printk(KERN_ERR "unable to register system timer (%i)\n", err); snd_printk(KERN_ERR "unable to register system timer (%i)\n", err); if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0, &snd_timer_reg, "timer"))<0) snd_printk(KERN_ERR "unable to register timer device (%i)\n", err); snd_printk(KERN_ERR "unable to register timer device (%i)\n", err); return 0; } Loading Loading
sound/core/timer.c +167 −112 Original line number Diff line number Diff line Loading @@ -95,7 +95,8 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left); * create a timer instance with the given owner string. * when timer is not NULL, increments the module counter */ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer) static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer) { snd_timer_instance_t *timeri; timeri = kzalloc(sizeof(*timeri), GFP_KERNEL); Loading Loading @@ -192,7 +193,8 @@ static void snd_timer_check_slave(snd_timer_instance_t *slave) if (slave->slave_class == master->slave_class && slave->slave_id == master->slave_id) { list_del(&slave->open_list); list_add_tail(&slave->open_list, &master->slave_list_head); list_add_tail(&slave->open_list, &master->slave_list_head); spin_lock_irq(&slave_active_lock); slave->master = master; slave->timer = master->timer; Loading Loading @@ -225,7 +227,8 @@ static void snd_timer_check_master(snd_timer_instance_t *master) slave->master = master; slave->timer = master->timer; if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) list_add_tail(&slave->active_list, &master->slave_active_head); list_add_tail(&slave->active_list, &master->slave_active_head); spin_unlock_irq(&slave_active_lock); } } Loading Loading @@ -304,7 +307,8 @@ int snd_timer_open(snd_timer_instance_t **ti, return 0; } static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event); static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event); /* * close a timer instance Loading Loading @@ -344,7 +348,8 @@ int snd_timer_close(snd_timer_instance_t * timeri) spin_unlock_irq(&timer->lock); down(®ister_mutex); list_del(&timeri->open_list); if (timer && list_empty(&timer->open_list_head) && timer->hw.close) if (timer && list_empty(&timer->open_list_head) && timer->hw.close) timer->hw.close(timer); /* remove slave links */ list_for_each_safe(p, n, &timeri->slave_list_head) { Loading Loading @@ -382,7 +387,8 @@ unsigned long snd_timer_resolution(snd_timer_instance_t * timeri) return 0; } static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event) static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event) { snd_timer_t *timer; unsigned long flags; Loading @@ -392,8 +398,10 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e struct timespec tstamp; getnstimeofday(&tstamp); snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return); if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE) snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return); if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE) resolution = snd_timer_resolution(ti); if (ti->ccallback) ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); Loading @@ -413,7 +421,8 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e spin_unlock_irqrestore(&timer->lock, flags); } static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks) static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks) { list_del(&timeri->active_list); list_add_tail(&timeri->active_list, &timer->active_list_head); Loading @@ -440,7 +449,8 @@ static int snd_timer_start_slave(snd_timer_instance_t *timeri) spin_lock_irqsave(&slave_active_lock, flags); timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; if (timeri->master) list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); spin_unlock_irqrestore(&slave_active_lock, flags); return 1; /* delayed start */ } Loading Loading @@ -473,7 +483,8 @@ int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) return result; } static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event) static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event) { snd_timer_t *timer; unsigned long flags; Loading Loading @@ -507,7 +518,8 @@ static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sn } } if (!keep_flag) timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START); timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); spin_unlock_irqrestore(&timer->lock, flags); __end: if (event != SNDRV_TIMER_EVENT_RESOLUTION) Loading Loading @@ -650,7 +662,7 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) { snd_timer_instance_t *ti, *ts; unsigned long resolution, ticks; struct list_head *p, *q, *n; struct list_head *p, *q, *n, *ack_list_head; int use_tasklet = 0; if (timer == NULL) Loading @@ -665,8 +677,9 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) resolution = timer->hw.resolution; /* loop for all active instances * here we cannot use list_for_each because the active_list of a processed * instance is relinked to done_list_head before callback is called. * Here we cannot use list_for_each because the active_list of a * processed instance is relinked to done_list_head before the callback * is called. */ list_for_each_safe(p, n, &timer->active_list_head) { ti = list_entry(p, snd_timer_instance_t, active_list); Loading @@ -687,26 +700,19 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) if (--timer->running) list_del(p); } if (list_empty(&ti->ack_list)) { if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || (ti->flags & SNDRV_TIMER_IFLG_FAST)) { list_add_tail(&ti->ack_list, &timer->ack_list_head); } else { list_add_tail(&ti->ack_list, &timer->sack_list_head); } } (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); list_for_each(q, &ti->slave_active_head) { ts = list_entry(q, snd_timer_instance_t, active_list); ts->pticks = ti->pticks; ts->resolution = resolution; if (list_empty(&ts->ack_list)) { if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || (ti->flags & SNDRV_TIMER_IFLG_FAST)) { list_add_tail(&ts->ack_list, &timer->ack_list_head); } else { list_add_tail(&ts->ack_list, &timer->sack_list_head); } } if (list_empty(&ts->ack_list)) list_add_tail(&ts->ack_list, ack_list_head); } } if (timer->flags & SNDRV_TIMER_FLG_RESCHED) Loading Loading @@ -757,7 +763,8 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left) */ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer) int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t **rtimer) { snd_timer_t *timer; int err; Loading Loading @@ -785,10 +792,12 @@ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t * INIT_LIST_HEAD(&timer->ack_list_head); INIT_LIST_HEAD(&timer->sack_list_head); spin_lock_init(&timer->lock); tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); if (card != NULL) { timer->module = card->module; if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) { err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); if (err < 0) { snd_timer_free(timer); return err; } Loading Loading @@ -818,7 +827,8 @@ static int snd_timer_dev_register(snd_device_t *dev) snd_timer_t *timer1; struct list_head *p; snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO); snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO); if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && !timer->hw.resolution && timer->hw.c_resolution == NULL) return -EINVAL; Loading Loading @@ -879,7 +889,8 @@ static int snd_timer_dev_unregister(snd_device_t *device) return snd_timer_unregister(timer); } void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp) void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp) { unsigned long flags; unsigned long resolution = 0; Loading @@ -888,7 +899,8 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) return; snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return); snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return); spin_lock_irqsave(&timer->lock, flags); if (event == SNDRV_TIMER_EVENT_MSTART || event == SNDRV_TIMER_EVENT_MCONTINUE || Loading Loading @@ -1021,7 +1033,8 @@ static int snd_timer_register_system(void) struct snd_timer_system_private *priv; int err; if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0) err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer); if (err < 0) return err; strcpy(timer->name, "system timer"); timer->hw = snd_timer_system; Loading Loading @@ -1058,27 +1071,35 @@ static void snd_timer_proc_read(snd_info_entry_t *entry, snd_iprintf(buffer, "G%i: ", timer->tmr_device); break; case SNDRV_TIMER_CLASS_CARD: snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device); snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device); break; case SNDRV_TIMER_CLASS_PCM: snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice); snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice); break; default: snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice); snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice); } snd_iprintf(buffer, "%s :", timer->name); if (timer->hw.resolution) snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks); snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks); if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) snd_iprintf(buffer, " SLAVE"); snd_iprintf(buffer, "\n"); spin_lock_irqsave(&timer->lock, flags); list_for_each(q, &timer->open_list_head) { ti = list_entry(q, snd_timer_instance_t, open_list); snd_iprintf(buffer, " Client %s : %s : lost interrupts %li\n", snd_iprintf(buffer, " Client %s : %s\n", ti->owner ? ti->owner : "unknown", ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped", ti->lost); ti->flags & (SNDRV_TIMER_IFLG_START | SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped"); } spin_unlock_irqrestore(&timer->lock, flags); } Loading Loading @@ -1121,7 +1142,8 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri, wake_up(&tu->qchange_sleep); } static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread) static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread) { if (tu->qused >= tu->queue_size) { tu->overrun++; Loading @@ -1140,7 +1162,8 @@ static void snd_timer_user_ccallback(snd_timer_instance_t *timeri, snd_timer_user_t *tu = timeri->callback_data; snd_timer_tread_t r1; if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE) if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE) tu->tstamp = *tstamp; if ((tu->filter & (1 << event)) == 0 || !tu->tread) return; Loading @@ -1165,13 +1188,15 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri, memset(&tstamp, 0, sizeof(tstamp)); spin_lock(&tu->qlock); if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) { 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) getnstimeofday(&tstamp); if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { r1.event = SNDRV_TIMER_EVENT_RESOLUTION; r1.tstamp = tstamp; r1.val = resolution; Loading Loading @@ -1218,7 +1243,8 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) init_MUTEX(&tu->tread_sem); tu->ticks = 1; tu->queue_size = 128; tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); if (tu->queue == NULL) { kfree(tu); return -ENOMEM; Loading Loading @@ -1308,7 +1334,11 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) if (id.device < 0) { id.device = 0; } else { id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1; if (id.subdevice < 0) { id.subdevice = 0; } else { id.subdevice++; } } } } Loading Loading @@ -1354,7 +1384,8 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid) return 0; } static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo) static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo) { snd_timer_ginfo_t *ginfo; snd_timer_id_t tid; Loading Loading @@ -1398,7 +1429,8 @@ static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_gi return err; } static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams) static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams) { snd_timer_gparams_t gparams; snd_timer_t *t; Loading @@ -1408,23 +1440,26 @@ static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user 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_period) err = t->hw.set_period(t, gparams.period_num, gparams.period_den); else err = -ENOSYS; } else { if (!t) { err = -ENODEV; goto _error; } if (!list_empty(&t->open_list_head)) { err = -EBUSY; goto _error; } } else { err = -ENODEV; if (!t->hw.set_period) { err = -ENOSYS; goto _error; } err = t->hw.set_period(t, gparams.period_num, gparams.period_den); _error: up(®ister_mutex); return err; } static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus) static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus) { snd_timer_gstatus_t gstatus; snd_timer_id_t tid; Loading @@ -1444,7 +1479,8 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user else gstatus.resolution = t->hw.resolution; if (t->hw.precise_resolution) { t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den); t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den); } else { gstatus.resolution_num = gstatus.resolution; gstatus.resolution_den = 1000000000uL; Loading @@ -1458,7 +1494,8 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user return err; } static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect) static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect) { snd_timer_user_t *tu; snd_timer_select_t tselect; Loading @@ -1478,7 +1515,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * sprintf(str, "application %i", current->pid); if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid); if (err < 0) goto __err; kfree(tu->queue); Loading @@ -1486,11 +1524,13 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * kfree(tu->tqueue); tu->tqueue = NULL; if (tu->tread) { tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); if (tu->tqueue == NULL) err = -ENOMEM; } else { tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); if (tu->queue == NULL) err = -ENOMEM; } Loading @@ -1500,7 +1540,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * tu->timeri = NULL; } else { tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; tu->timeri->ccallback = snd_timer_user_ccallback; tu->timeri->callback_data = (void *)tu; } Loading @@ -1510,7 +1551,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * return err; } static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info) static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info) { snd_timer_user_t *tu; snd_timer_info_t *info; Loading @@ -1537,7 +1579,8 @@ static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info return err; } static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params) static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params) { snd_timer_user_t *tu; snd_timer_params_t params; Loading @@ -1556,7 +1599,8 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ err = -EINVAL; goto _end; } if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { err = -EINVAL; goto _end; } Loading Loading @@ -1589,16 +1633,19 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; spin_unlock_irq(&t->lock); if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) { if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) { if (tu->tread) { ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); ttr = kmalloc(params.queue_size * sizeof(*ttr), GFP_KERNEL); if (ttr) { kfree(tu->tqueue); tu->queue_size = params.queue_size; tu->tqueue = ttr; } } else { tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tr = kmalloc(params.queue_size * sizeof(*tr), GFP_KERNEL); if (tr) { kfree(tu->queue); tu->queue_size = params.queue_size; Loading @@ -1622,7 +1669,6 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ tu->qused++; tu->qtail++; } } tu->filter = params.filter; tu->ticks = params.ticks; Loading @@ -1633,7 +1679,8 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_ return err; } static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status) static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status) { snd_timer_user_t *tu; snd_timer_status_t status; Loading Loading @@ -1704,7 +1751,8 @@ enum { SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), }; static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { snd_timer_user_t *tu; void __user *argp = (void __user *)arg; Loading Loading @@ -1775,7 +1823,8 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on) return 0; } static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset) static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset) { snd_timer_user_t *tu; long result = 0, unit; Loading Loading @@ -1814,12 +1863,14 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_ goto _error; if (tu->tread) { if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) { if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) { err = -EFAULT; goto _error; } } else { if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) { if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) { err = -EFAULT; goto _error; } Loading Loading @@ -1890,9 +1941,11 @@ static int __init alsa_timer_init(void) snd_info_entry_t *entry; #ifdef SNDRV_OSS_INFO_DEV_TIMERS snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer"); snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer"); #endif if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) { entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL); if (entry != NULL) { entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128; entry->c.text.read = snd_timer_proc_read; if (snd_info_register(entry) < 0) { Loading @@ -1902,10 +1955,12 @@ static int __init alsa_timer_init(void) } snd_timer_proc_entry = entry; if ((err = snd_timer_register_system()) < 0) snd_printk(KERN_ERR "unable to register system timer (%i)\n", err); snd_printk(KERN_ERR "unable to register system timer (%i)\n", err); if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0, &snd_timer_reg, "timer"))<0) snd_printk(KERN_ERR "unable to register timer device (%i)\n", err); snd_printk(KERN_ERR "unable to register timer device (%i)\n", err); return 0; } Loading