LCOV - code coverage report
Current view: top level - sound/core - timer.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 91 1092 8.3 %
Date: 2022-04-01 13:59:58 Functions: 7 62 11.3 %
Branches: 26 610 4.3 %

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

Generated by: LCOV version 1.14