LCOV - code coverage report
Current view: top level - sound/core - timer.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 90 969 9.3 %
Date: 2020-09-30 20:25:40 Functions: 7 70 10.0 %
Branches: 39 699 5.6 %

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

Generated by: LCOV version 1.14