Loading sound/core/timer.c +37 −20 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,7 @@ typedef struct { struct timespec tstamp; /* trigger tstamp */ struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; struct fasync_struct *fasync; struct semaphore tread_sem; } snd_timer_user_t; } snd_timer_user_t; /* list of timers */ /* list of timers */ Loading Loading @@ -1208,6 +1209,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; return -ENOMEM; spin_lock_init(&tu->qlock); spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); init_waitqueue_head(&tu->qchange_sleep); init_MUTEX(&tu->tread_sem); tu->ticks = 1; tu->ticks = 1; tu->queue_size = 128; tu->queue_size = 128; tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); Loading Loading @@ -1454,18 +1456,23 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * snd_timer_user_t *tu; snd_timer_user_t *tu; snd_timer_select_t tselect; snd_timer_select_t tselect; char str[32]; char str[32]; int err; int err = 0; tu = file->private_data; tu = file->private_data; if (tu->timeri) down(&tu->tread_sem); if (tu->timeri) { snd_timer_close(tu->timeri); snd_timer_close(tu->timeri); if (copy_from_user(&tselect, _tselect, sizeof(tselect))) tu->timeri = NULL; return -EFAULT; } if (copy_from_user(&tselect, _tselect, sizeof(tselect))) { err = -EFAULT; goto __err; } sprintf(str, "application %i", current->pid); sprintf(str, "application %i", current->pid); if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) return err; goto __err; if (tu->queue) { if (tu->queue) { kfree(tu->queue); kfree(tu->queue); Loading @@ -1477,23 +1484,27 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * } } if (tu->tread) { if (tu->tread) { tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); if (tu->tqueue == NULL) { if (tu->tqueue == NULL) snd_timer_close(tu->timeri); err = -ENOMEM; return -ENOMEM; } } else { } else { tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); if (tu->queue == NULL) { if (tu->queue == NULL) snd_timer_close(tu->timeri); err = -ENOMEM; return -ENOMEM; } } } if (err < 0) { snd_timer_close(tu->timeri); tu->timeri = NULL; } else { tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; 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->ccallback = snd_timer_user_ccallback; tu->timeri->callback_data = (void *)tu; tu->timeri->callback_data = (void *)tu; return 0; } __err: up(&tu->tread_sem); 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) Loading Loading @@ -1685,11 +1696,17 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned l { { int xarg; int xarg; if (tu->timeri) /* too late */ down(&tu->tread_sem); if (tu->timeri) { /* too late */ up(&tu->tread_sem); return -EBUSY; return -EBUSY; if (get_user(xarg, p)) } if (get_user(xarg, p)) { up(&tu->tread_sem); return -EFAULT; return -EFAULT; } tu->tread = xarg ? 1 : 0; tu->tread = xarg ? 1 : 0; up(&tu->tread_sem); return 0; return 0; } } case SNDRV_TIMER_IOCTL_GINFO: case SNDRV_TIMER_IOCTL_GINFO: Loading Loading
sound/core/timer.c +37 −20 Original line number Original line Diff line number Diff line Loading @@ -69,6 +69,7 @@ typedef struct { struct timespec tstamp; /* trigger tstamp */ struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; struct fasync_struct *fasync; struct semaphore tread_sem; } snd_timer_user_t; } snd_timer_user_t; /* list of timers */ /* list of timers */ Loading Loading @@ -1208,6 +1209,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; return -ENOMEM; spin_lock_init(&tu->qlock); spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); init_waitqueue_head(&tu->qchange_sleep); init_MUTEX(&tu->tread_sem); tu->ticks = 1; tu->ticks = 1; tu->queue_size = 128; tu->queue_size = 128; tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); Loading Loading @@ -1454,18 +1456,23 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * snd_timer_user_t *tu; snd_timer_user_t *tu; snd_timer_select_t tselect; snd_timer_select_t tselect; char str[32]; char str[32]; int err; int err = 0; tu = file->private_data; tu = file->private_data; if (tu->timeri) down(&tu->tread_sem); if (tu->timeri) { snd_timer_close(tu->timeri); snd_timer_close(tu->timeri); if (copy_from_user(&tselect, _tselect, sizeof(tselect))) tu->timeri = NULL; return -EFAULT; } if (copy_from_user(&tselect, _tselect, sizeof(tselect))) { err = -EFAULT; goto __err; } sprintf(str, "application %i", current->pid); sprintf(str, "application %i", current->pid); if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) return err; goto __err; if (tu->queue) { if (tu->queue) { kfree(tu->queue); kfree(tu->queue); Loading @@ -1477,23 +1484,27 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user * } } if (tu->tread) { if (tu->tread) { tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); if (tu->tqueue == NULL) { if (tu->tqueue == NULL) snd_timer_close(tu->timeri); err = -ENOMEM; return -ENOMEM; } } else { } else { tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); if (tu->queue == NULL) { if (tu->queue == NULL) snd_timer_close(tu->timeri); err = -ENOMEM; return -ENOMEM; } } } if (err < 0) { snd_timer_close(tu->timeri); tu->timeri = NULL; } else { tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; 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->ccallback = snd_timer_user_ccallback; tu->timeri->callback_data = (void *)tu; tu->timeri->callback_data = (void *)tu; return 0; } __err: up(&tu->tread_sem); 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) Loading Loading @@ -1685,11 +1696,17 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned l { { int xarg; int xarg; if (tu->timeri) /* too late */ down(&tu->tread_sem); if (tu->timeri) { /* too late */ up(&tu->tread_sem); return -EBUSY; return -EBUSY; if (get_user(xarg, p)) } if (get_user(xarg, p)) { up(&tu->tread_sem); return -EFAULT; return -EFAULT; } tu->tread = xarg ? 1 : 0; tu->tread = xarg ? 1 : 0; up(&tu->tread_sem); return 0; return 0; } } case SNDRV_TIMER_IOCTL_GINFO: case SNDRV_TIMER_IOCTL_GINFO: Loading