LCOV - code coverage report
Current view: top level - sound/core - device.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 67 0.0 %
Date: 2014-02-18 Functions: 0 7 0.0 %
Branches: 0 72 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  Device management routines
       3                 :            :  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
       4                 :            :  *
       5                 :            :  *
       6                 :            :  *   This program is free software; you can redistribute it and/or modify
       7                 :            :  *   it under the terms of the GNU General Public License as published by
       8                 :            :  *   the Free Software Foundation; either version 2 of the License, or
       9                 :            :  *   (at your option) any later version.
      10                 :            :  *
      11                 :            :  *   This program is distributed in the hope that it will be useful,
      12                 :            :  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :            :  *   GNU General Public License for more details.
      15                 :            :  *
      16                 :            :  *   You should have received a copy of the GNU General Public License
      17                 :            :  *   along with this program; if not, write to the Free Software
      18                 :            :  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
      19                 :            :  *
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <linux/slab.h>
      23                 :            : #include <linux/time.h>
      24                 :            : #include <linux/export.h>
      25                 :            : #include <linux/errno.h>
      26                 :            : #include <sound/core.h>
      27                 :            : 
      28                 :            : /**
      29                 :            :  * snd_device_new - create an ALSA device component
      30                 :            :  * @card: the card instance
      31                 :            :  * @type: the device type, SNDRV_DEV_XXX
      32                 :            :  * @device_data: the data pointer of this device
      33                 :            :  * @ops: the operator table
      34                 :            :  *
      35                 :            :  * Creates a new device component for the given data pointer.
      36                 :            :  * The device will be assigned to the card and managed together
      37                 :            :  * by the card.
      38                 :            :  *
      39                 :            :  * The data pointer plays a role as the identifier, too, so the
      40                 :            :  * pointer address must be unique and unchanged.
      41                 :            :  *
      42                 :            :  * Return: Zero if successful, or a negative error code on failure.
      43                 :            :  */
      44                 :          0 : int snd_device_new(struct snd_card *card, snd_device_type_t type,
      45                 :            :                    void *device_data, struct snd_device_ops *ops)
      46                 :            : {
      47                 :            :         struct snd_device *dev;
      48                 :            : 
      49 [ #  # ][ #  # ]:          0 :         if (snd_BUG_ON(!card || !device_data || !ops))
                 [ #  # ]
      50                 :            :                 return -ENXIO;
      51                 :            :         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
      52         [ #  # ]:          0 :         if (dev == NULL) {
      53                 :          0 :                 snd_printk(KERN_ERR "Cannot allocate device\n");
      54                 :          0 :                 return -ENOMEM;
      55                 :            :         }
      56                 :          0 :         dev->card = card;
      57                 :          0 :         dev->type = type;
      58                 :          0 :         dev->state = SNDRV_DEV_BUILD;
      59                 :          0 :         dev->device_data = device_data;
      60                 :          0 :         dev->ops = ops;
      61                 :          0 :         list_add(&dev->list, &card->devices);     /* add to the head of list */
      62                 :          0 :         return 0;
      63                 :            : }
      64                 :            : 
      65                 :            : EXPORT_SYMBOL(snd_device_new);
      66                 :            : 
      67                 :            : /**
      68                 :            :  * snd_device_free - release the device from the card
      69                 :            :  * @card: the card instance
      70                 :            :  * @device_data: the data pointer to release
      71                 :            :  *
      72                 :            :  * Removes the device from the list on the card and invokes the
      73                 :            :  * callbacks, dev_disconnect and dev_free, corresponding to the state.
      74                 :            :  * Then release the device.
      75                 :            :  *
      76                 :            :  * Return: Zero if successful, or a negative error code on failure or if the
      77                 :            :  * device not found.
      78                 :            :  */
      79                 :          0 : int snd_device_free(struct snd_card *card, void *device_data)
      80                 :            : {
      81                 :            :         struct snd_device *dev;
      82                 :            :         
      83         [ #  # ]:          0 :         if (snd_BUG_ON(!card || !device_data))
      84                 :            :                 return -ENXIO;
      85         [ #  # ]:          0 :         list_for_each_entry(dev, &card->devices, list) {
      86         [ #  # ]:          0 :                 if (dev->device_data != device_data)
      87                 :          0 :                         continue;
      88                 :            :                 /* unlink */
      89                 :            :                 list_del(&dev->list);
      90 [ #  # ][ #  # ]:          0 :                 if (dev->state == SNDRV_DEV_REGISTERED &&
      91                 :          0 :                     dev->ops->dev_disconnect)
      92         [ #  # ]:          0 :                         if (dev->ops->dev_disconnect(dev))
      93                 :          0 :                                 snd_printk(KERN_ERR
      94                 :            :                                            "device disconnect failure\n");
      95         [ #  # ]:          0 :                 if (dev->ops->dev_free) {
      96         [ #  # ]:          0 :                         if (dev->ops->dev_free(dev))
      97                 :          0 :                                 snd_printk(KERN_ERR "device free failure\n");
      98                 :            :                 }
      99                 :          0 :                 kfree(dev);
     100                 :          0 :                 return 0;
     101                 :            :         }
     102                 :          0 :         snd_printd("device free %p (from %pF), not found\n", device_data,
     103                 :            :                    __builtin_return_address(0));
     104                 :          0 :         return -ENXIO;
     105                 :            : }
     106                 :            : 
     107                 :            : EXPORT_SYMBOL(snd_device_free);
     108                 :            : 
     109                 :            : /**
     110                 :            :  * snd_device_disconnect - disconnect the device
     111                 :            :  * @card: the card instance
     112                 :            :  * @device_data: the data pointer to disconnect
     113                 :            :  *
     114                 :            :  * Turns the device into the disconnection state, invoking
     115                 :            :  * dev_disconnect callback, if the device was already registered.
     116                 :            :  *
     117                 :            :  * Usually called from snd_card_disconnect().
     118                 :            :  *
     119                 :            :  * Return: Zero if successful, or a negative error code on failure or if the
     120                 :            :  * device not found.
     121                 :            :  */
     122                 :          0 : int snd_device_disconnect(struct snd_card *card, void *device_data)
     123                 :            : {
     124                 :            :         struct snd_device *dev;
     125                 :            : 
     126         [ #  # ]:          0 :         if (snd_BUG_ON(!card || !device_data))
     127                 :            :                 return -ENXIO;
     128         [ #  # ]:          0 :         list_for_each_entry(dev, &card->devices, list) {
     129         [ #  # ]:          0 :                 if (dev->device_data != device_data)
     130                 :          0 :                         continue;
     131 [ #  # ][ #  # ]:          0 :                 if (dev->state == SNDRV_DEV_REGISTERED &&
     132                 :          0 :                     dev->ops->dev_disconnect) {
     133         [ #  # ]:          0 :                         if (dev->ops->dev_disconnect(dev))
     134                 :          0 :                                 snd_printk(KERN_ERR "device disconnect failure\n");
     135                 :          0 :                         dev->state = SNDRV_DEV_DISCONNECTED;
     136                 :            :                 }
     137                 :            :                 return 0;
     138                 :            :         }
     139                 :          0 :         snd_printd("device disconnect %p (from %pF), not found\n", device_data,
     140                 :            :                    __builtin_return_address(0));
     141                 :          0 :         return -ENXIO;
     142                 :            : }
     143                 :            : 
     144                 :            : /**
     145                 :            :  * snd_device_register - register the device
     146                 :            :  * @card: the card instance
     147                 :            :  * @device_data: the data pointer to register
     148                 :            :  *
     149                 :            :  * Registers the device which was already created via
     150                 :            :  * snd_device_new().  Usually this is called from snd_card_register(),
     151                 :            :  * but it can be called later if any new devices are created after
     152                 :            :  * invocation of snd_card_register().
     153                 :            :  *
     154                 :            :  * Return: Zero if successful, or a negative error code on failure or if the
     155                 :            :  * device not found.
     156                 :            :  */
     157                 :          0 : int snd_device_register(struct snd_card *card, void *device_data)
     158                 :            : {
     159                 :            :         struct snd_device *dev;
     160                 :            :         int err;
     161                 :            : 
     162         [ #  # ]:          0 :         if (snd_BUG_ON(!card || !device_data))
     163                 :            :                 return -ENXIO;
     164         [ #  # ]:          0 :         list_for_each_entry(dev, &card->devices, list) {
     165         [ #  # ]:          0 :                 if (dev->device_data != device_data)
     166                 :          0 :                         continue;
     167 [ #  # ][ #  # ]:          0 :                 if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) {
     168         [ #  # ]:          0 :                         if ((err = dev->ops->dev_register(dev)) < 0)
     169                 :            :                                 return err;
     170                 :          0 :                         dev->state = SNDRV_DEV_REGISTERED;
     171                 :          0 :                         return 0;
     172                 :            :                 }
     173                 :            :                 snd_printd("snd_device_register busy\n");
     174                 :            :                 return -EBUSY;
     175                 :            :         }
     176                 :            :         snd_BUG();
     177                 :            :         return -ENXIO;
     178                 :            : }
     179                 :            : 
     180                 :            : EXPORT_SYMBOL(snd_device_register);
     181                 :            : 
     182                 :            : /*
     183                 :            :  * register all the devices on the card.
     184                 :            :  * called from init.c
     185                 :            :  */
     186                 :          0 : int snd_device_register_all(struct snd_card *card)
     187                 :            : {
     188                 :            :         struct snd_device *dev;
     189                 :            :         int err;
     190                 :            :         
     191         [ #  # ]:          0 :         if (snd_BUG_ON(!card))
     192                 :            :                 return -ENXIO;
     193         [ #  # ]:          0 :         list_for_each_entry(dev, &card->devices, list) {
     194 [ #  # ][ #  # ]:          0 :                 if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) {
     195         [ #  # ]:          0 :                         if ((err = dev->ops->dev_register(dev)) < 0)
     196                 :            :                                 return err;
     197                 :          0 :                         dev->state = SNDRV_DEV_REGISTERED;
     198                 :            :                 }
     199                 :            :         }
     200                 :            :         return 0;
     201                 :            : }
     202                 :            : 
     203                 :            : /*
     204                 :            :  * disconnect all the devices on the card.
     205                 :            :  * called from init.c
     206                 :            :  */
     207                 :          0 : int snd_device_disconnect_all(struct snd_card *card)
     208                 :            : {
     209                 :            :         struct snd_device *dev;
     210                 :            :         int err = 0;
     211                 :            : 
     212         [ #  # ]:          0 :         if (snd_BUG_ON(!card))
     213                 :            :                 return -ENXIO;
     214         [ #  # ]:          0 :         list_for_each_entry(dev, &card->devices, list) {
     215         [ #  # ]:          0 :                 if (snd_device_disconnect(card, dev->device_data) < 0)
     216                 :            :                         err = -ENXIO;
     217                 :            :         }
     218                 :            :         return err;
     219                 :            : }
     220                 :            : 
     221                 :            : /*
     222                 :            :  * release all the devices on the card.
     223                 :            :  * called from init.c
     224                 :            :  */
     225                 :          0 : int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd)
     226                 :            : {
     227                 :            :         struct snd_device *dev;
     228                 :            :         int err;
     229                 :            :         unsigned int range_low, range_high, type;
     230                 :            : 
     231         [ #  # ]:          0 :         if (snd_BUG_ON(!card))
     232                 :            :                 return -ENXIO;
     233                 :          0 :         range_low = (__force unsigned int)cmd * SNDRV_DEV_TYPE_RANGE_SIZE;
     234                 :          0 :         range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1;
     235                 :            :       __again:
     236         [ #  # ]:          0 :         list_for_each_entry(dev, &card->devices, list) {
     237                 :          0 :                 type = (__force unsigned int)dev->type;
     238         [ #  # ]:          0 :                 if (type >= range_low && type <= range_high) {
     239         [ #  # ]:          0 :                         if ((err = snd_device_free(card, dev->device_data)) < 0)
     240                 :            :                                 return err;
     241                 :            :                         goto __again;
     242                 :            :                 }
     243                 :            :         }
     244                 :            :         return 0;
     245                 :            : }

Generated by: LCOV version 1.9