linux/sound/core/init.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  Initialization routines
   4 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   5 */
   6
   7#include <linux/init.h>
   8#include <linux/sched.h>
   9#include <linux/module.h>
  10#include <linux/device.h>
  11#include <linux/file.h>
  12#include <linux/slab.h>
  13#include <linux/time.h>
  14#include <linux/ctype.h>
  15#include <linux/pm.h>
  16#include <linux/completion.h>
  17
  18#include <sound/core.h>
  19#include <sound/control.h>
  20#include <sound/info.h>
  21
  22/* monitor files for graceful shutdown (hotplug) */
  23struct snd_monitor_file {
  24        struct file *file;
  25        const struct file_operations *disconnected_f_op;
  26        struct list_head shutdown_list; /* still need to shutdown */
  27        struct list_head list;  /* link of monitor files */
  28};
  29
  30static DEFINE_SPINLOCK(shutdown_lock);
  31static LIST_HEAD(shutdown_files);
  32
  33static const struct file_operations snd_shutdown_f_ops;
  34
  35/* locked for registering/using */
  36static DECLARE_BITMAP(snd_cards_lock, SNDRV_CARDS);
  37static struct snd_card *snd_cards[SNDRV_CARDS];
  38
  39static DEFINE_MUTEX(snd_card_mutex);
  40
  41static char *slots[SNDRV_CARDS];
  42module_param_array(slots, charp, NULL, 0444);
  43MODULE_PARM_DESC(slots, "Module names assigned to the slots.");
  44
  45/* return non-zero if the given index is reserved for the given
  46 * module via slots option
  47 */
  48static int module_slot_match(struct module *module, int idx)
  49{
  50        int match = 1;
  51#ifdef MODULE
  52        const char *s1, *s2;
  53
  54        if (!module || !*module->name || !slots[idx])
  55                return 0;
  56
  57        s1 = module->name;
  58        s2 = slots[idx];
  59        if (*s2 == '!') {
  60                match = 0; /* negative match */
  61                s2++;
  62        }
  63        /* compare module name strings
  64         * hyphens are handled as equivalent with underscore
  65         */
  66        for (;;) {
  67                char c1 = *s1++;
  68                char c2 = *s2++;
  69                if (c1 == '-')
  70                        c1 = '_';
  71                if (c2 == '-')
  72                        c2 = '_';
  73                if (c1 != c2)
  74                        return !match;
  75                if (!c1)
  76                        break;
  77        }
  78#endif /* MODULE */
  79        return match;
  80}
  81
  82#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
  83int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
  84EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
  85#endif
  86
  87static int check_empty_slot(struct module *module, int slot)
  88{
  89        return !slots[slot] || !*slots[slot];
  90}
  91
  92/* return an empty slot number (>= 0) found in the given bitmask @mask.
  93 * @mask == -1 == 0xffffffff means: take any free slot up to 32
  94 * when no slot is available, return the original @mask as is.
  95 */
  96static int get_slot_from_bitmask(int mask, int (*check)(struct module *, int),
  97                                 struct module *module)
  98{
  99        int slot;
 100
 101        for (slot = 0; slot < SNDRV_CARDS; slot++) {
 102                if (slot < 32 && !(mask & (1U << slot)))
 103                        continue;
 104                if (!test_bit(slot, snd_cards_lock)) {
 105                        if (check(module, slot))
 106                                return slot; /* found */
 107                }
 108        }
 109        return mask; /* unchanged */
 110}
 111
 112/* the default release callback set in snd_device_initialize() below;
 113 * this is just NOP for now, as almost all jobs are already done in
 114 * dev_free callback of snd_device chain instead.
 115 */
 116static void default_release(struct device *dev)
 117{
 118}
 119
 120/**
 121 * snd_device_initialize - Initialize struct device for sound devices
 122 * @dev: device to initialize
 123 * @card: card to assign, optional
 124 */
 125void snd_device_initialize(struct device *dev, struct snd_card *card)
 126{
 127        device_initialize(dev);
 128        if (card)
 129                dev->parent = &card->card_dev;
 130        dev->class = sound_class;
 131        dev->release = default_release;
 132}
 133EXPORT_SYMBOL_GPL(snd_device_initialize);
 134
 135static int snd_card_do_free(struct snd_card *card);
 136static const struct attribute_group card_dev_attr_group;
 137
 138static void release_card_device(struct device *dev)
 139{
 140        snd_card_do_free(dev_to_snd_card(dev));
 141}
 142
 143/**
 144 *  snd_card_new - create and initialize a soundcard structure
 145 *  @parent: the parent device object
 146 *  @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
 147 *  @xid: card identification (ASCII string)
 148 *  @module: top level module for locking
 149 *  @extra_size: allocate this extra size after the main soundcard structure
 150 *  @card_ret: the pointer to store the created card instance
 151 *
 152 *  Creates and initializes a soundcard structure.
 153 *
 154 *  The function allocates snd_card instance via kzalloc with the given
 155 *  space for the driver to use freely.  The allocated struct is stored
 156 *  in the given card_ret pointer.
 157 *
 158 *  Return: Zero if successful or a negative error code.
 159 */
 160int snd_card_new(struct device *parent, int idx, const char *xid,
 161                    struct module *module, int extra_size,
 162                    struct snd_card **card_ret)
 163{
 164        struct snd_card *card;
 165        int err;
 166
 167        if (snd_BUG_ON(!card_ret))
 168                return -EINVAL;
 169        *card_ret = NULL;
 170
 171        if (extra_size < 0)
 172                extra_size = 0;
 173        card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
 174        if (!card)
 175                return -ENOMEM;
 176        if (extra_size > 0)
 177                card->private_data = (char *)card + sizeof(struct snd_card);
 178        if (xid)
 179                strlcpy(card->id, xid, sizeof(card->id));
 180        err = 0;
 181        mutex_lock(&snd_card_mutex);
 182        if (idx < 0) /* first check the matching module-name slot */
 183                idx = get_slot_from_bitmask(idx, module_slot_match, module);
 184        if (idx < 0) /* if not matched, assign an empty slot */
 185                idx = get_slot_from_bitmask(idx, check_empty_slot, module);
 186        if (idx < 0)
 187                err = -ENODEV;
 188        else if (idx < snd_ecards_limit) {
 189                if (test_bit(idx, snd_cards_lock))
 190                        err = -EBUSY;   /* invalid */
 191        } else if (idx >= SNDRV_CARDS)
 192                err = -ENODEV;
 193        if (err < 0) {
 194                mutex_unlock(&snd_card_mutex);
 195                dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n",
 196                         idx, snd_ecards_limit - 1, err);
 197                kfree(card);
 198                return err;
 199        }
 200        set_bit(idx, snd_cards_lock);           /* lock it */
 201        if (idx >= snd_ecards_limit)
 202                snd_ecards_limit = idx + 1; /* increase the limit */
 203        mutex_unlock(&snd_card_mutex);
 204        card->dev = parent;
 205        card->number = idx;
 206        card->module = module;
 207        INIT_LIST_HEAD(&card->devices);
 208        init_rwsem(&card->controls_rwsem);
 209        rwlock_init(&card->ctl_files_rwlock);
 210        INIT_LIST_HEAD(&card->controls);
 211        INIT_LIST_HEAD(&card->ctl_files);
 212        spin_lock_init(&card->files_lock);
 213        INIT_LIST_HEAD(&card->files_list);
 214        mutex_init(&card->memory_mutex);
 215#ifdef CONFIG_PM
 216        init_waitqueue_head(&card->power_sleep);
 217#endif
 218        init_waitqueue_head(&card->remove_sleep);
 219        card->sync_irq = -1;
 220
 221        device_initialize(&card->card_dev);
 222        card->card_dev.parent = parent;
 223        card->card_dev.class = sound_class;
 224        card->card_dev.release = release_card_device;
 225        card->card_dev.groups = card->dev_groups;
 226        card->dev_groups[0] = &card_dev_attr_group;
 227        err = kobject_set_name(&card->card_dev.kobj, "card%d", idx);
 228        if (err < 0)
 229                goto __error;
 230
 231        snprintf(card->irq_descr, sizeof(card->irq_descr), "%s:%s",
 232                 dev_driver_string(card->dev), dev_name(&card->card_dev));
 233
 234        /* the control interface cannot be accessed from the user space until */
 235        /* snd_cards_bitmask and snd_cards are set with snd_card_register */
 236        err = snd_ctl_create(card);
 237        if (err < 0) {
 238                dev_err(parent, "unable to register control minors\n");
 239                goto __error;
 240        }
 241        err = snd_info_card_create(card);
 242        if (err < 0) {
 243                dev_err(parent, "unable to create card info\n");
 244                goto __error_ctl;
 245        }
 246        *card_ret = card;
 247        return 0;
 248
 249      __error_ctl:
 250        snd_device_free_all(card);
 251      __error:
 252        put_device(&card->card_dev);
 253        return err;
 254}
 255EXPORT_SYMBOL(snd_card_new);
 256
 257/**
 258 * snd_card_ref - Get the card object from the index
 259 * @idx: the card index
 260 *
 261 * Returns a card object corresponding to the given index or NULL if not found.
 262 * Release the object via snd_card_unref().
 263 */
 264struct snd_card *snd_card_ref(int idx)
 265{
 266        struct snd_card *card;
 267
 268        mutex_lock(&snd_card_mutex);
 269        card = snd_cards[idx];
 270        if (card)
 271                get_device(&card->card_dev);
 272        mutex_unlock(&snd_card_mutex);
 273        return card;
 274}
 275EXPORT_SYMBOL_GPL(snd_card_ref);
 276
 277/* return non-zero if a card is already locked */
 278int snd_card_locked(int card)
 279{
 280        int locked;
 281
 282        mutex_lock(&snd_card_mutex);
 283        locked = test_bit(card, snd_cards_lock);
 284        mutex_unlock(&snd_card_mutex);
 285        return locked;
 286}
 287
 288static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
 289{
 290        return -ENODEV;
 291}
 292
 293static ssize_t snd_disconnect_read(struct file *file, char __user *buf,
 294                                   size_t count, loff_t *offset)
 295{
 296        return -ENODEV;
 297}
 298
 299static ssize_t snd_disconnect_write(struct file *file, const char __user *buf,
 300                                    size_t count, loff_t *offset)
 301{
 302        return -ENODEV;
 303}
 304
 305static int snd_disconnect_release(struct inode *inode, struct file *file)
 306{
 307        struct snd_monitor_file *df = NULL, *_df;
 308
 309        spin_lock(&shutdown_lock);
 310        list_for_each_entry(_df, &shutdown_files, shutdown_list) {
 311                if (_df->file == file) {
 312                        df = _df;
 313                        list_del_init(&df->shutdown_list);
 314                        break;
 315                }
 316        }
 317        spin_unlock(&shutdown_lock);
 318
 319        if (likely(df)) {
 320                if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync)
 321                        df->disconnected_f_op->fasync(-1, file, 0);
 322                return df->disconnected_f_op->release(inode, file);
 323        }
 324
 325        panic("%s(%p, %p) failed!", __func__, inode, file);
 326}
 327
 328static __poll_t snd_disconnect_poll(struct file * file, poll_table * wait)
 329{
 330        return EPOLLERR | EPOLLNVAL;
 331}
 332
 333static long snd_disconnect_ioctl(struct file *file,
 334                                 unsigned int cmd, unsigned long arg)
 335{
 336        return -ENODEV;
 337}
 338
 339static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma)
 340{
 341        return -ENODEV;
 342}
 343
 344static int snd_disconnect_fasync(int fd, struct file *file, int on)
 345{
 346        return -ENODEV;
 347}
 348
 349static const struct file_operations snd_shutdown_f_ops =
 350{
 351        .owner =        THIS_MODULE,
 352        .llseek =       snd_disconnect_llseek,
 353        .read =         snd_disconnect_read,
 354        .write =        snd_disconnect_write,
 355        .release =      snd_disconnect_release,
 356        .poll =         snd_disconnect_poll,
 357        .unlocked_ioctl = snd_disconnect_ioctl,
 358#ifdef CONFIG_COMPAT
 359        .compat_ioctl = snd_disconnect_ioctl,
 360#endif
 361        .mmap =         snd_disconnect_mmap,
 362        .fasync =       snd_disconnect_fasync
 363};
 364
 365/**
 366 *  snd_card_disconnect - disconnect all APIs from the file-operations (user space)
 367 *  @card: soundcard structure
 368 *
 369 *  Disconnects all APIs from the file-operations (user space).
 370 *
 371 *  Return: Zero, otherwise a negative error code.
 372 *
 373 *  Note: The current implementation replaces all active file->f_op with special
 374 *        dummy file operations (they do nothing except release).
 375 */
 376int snd_card_disconnect(struct snd_card *card)
 377{
 378        struct snd_monitor_file *mfile;
 379
 380        if (!card)
 381                return -EINVAL;
 382
 383        spin_lock(&card->files_lock);
 384        if (card->shutdown) {
 385                spin_unlock(&card->files_lock);
 386                return 0;
 387        }
 388        card->shutdown = 1;
 389        spin_unlock(&card->files_lock);
 390
 391        /* replace file->f_op with special dummy operations */
 392        spin_lock(&card->files_lock);
 393        list_for_each_entry(mfile, &card->files_list, list) {
 394                /* it's critical part, use endless loop */
 395                /* we have no room to fail */
 396                mfile->disconnected_f_op = mfile->file->f_op;
 397
 398                spin_lock(&shutdown_lock);
 399                list_add(&mfile->shutdown_list, &shutdown_files);
 400                spin_unlock(&shutdown_lock);
 401
 402                mfile->file->f_op = &snd_shutdown_f_ops;
 403                fops_get(mfile->file->f_op);
 404        }
 405        spin_unlock(&card->files_lock); 
 406
 407        /* notify all connected devices about disconnection */
 408        /* at this point, they cannot respond to any calls except release() */
 409
 410#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 411        if (snd_mixer_oss_notify_callback)
 412                snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_DISCONNECT);
 413#endif
 414
 415        /* notify all devices that we are disconnected */
 416        snd_device_disconnect_all(card);
 417
 418        snd_info_card_disconnect(card);
 419        if (card->registered) {
 420                device_del(&card->card_dev);
 421                card->registered = false;
 422        }
 423
 424        /* disable fops (user space) operations for ALSA API */
 425        mutex_lock(&snd_card_mutex);
 426        snd_cards[card->number] = NULL;
 427        clear_bit(card->number, snd_cards_lock);
 428        mutex_unlock(&snd_card_mutex);
 429
 430#ifdef CONFIG_PM
 431        wake_up(&card->power_sleep);
 432#endif
 433        return 0;       
 434}
 435EXPORT_SYMBOL(snd_card_disconnect);
 436
 437/**
 438 * snd_card_disconnect_sync - disconnect card and wait until files get closed
 439 * @card: card object to disconnect
 440 *
 441 * This calls snd_card_disconnect() for disconnecting all belonging components
 442 * and waits until all pending files get closed.
 443 * It assures that all accesses from user-space finished so that the driver
 444 * can release its resources gracefully.
 445 */
 446void snd_card_disconnect_sync(struct snd_card *card)
 447{
 448        int err;
 449
 450        err = snd_card_disconnect(card);
 451        if (err < 0) {
 452                dev_err(card->dev,
 453                        "snd_card_disconnect error (%d), skipping sync\n",
 454                        err);
 455                return;
 456        }
 457
 458        spin_lock_irq(&card->files_lock);
 459        wait_event_lock_irq(card->remove_sleep,
 460                            list_empty(&card->files_list),
 461                            card->files_lock);
 462        spin_unlock_irq(&card->files_lock);
 463}
 464EXPORT_SYMBOL_GPL(snd_card_disconnect_sync);
 465
 466static int snd_card_do_free(struct snd_card *card)
 467{
 468#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 469        if (snd_mixer_oss_notify_callback)
 470                snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
 471#endif
 472        snd_device_free_all(card);
 473        if (card->private_free)
 474                card->private_free(card);
 475        if (snd_info_card_free(card) < 0) {
 476                dev_warn(card->dev, "unable to free card info\n");
 477                /* Not fatal error */
 478        }
 479        if (card->release_completion)
 480                complete(card->release_completion);
 481        kfree(card);
 482        return 0;
 483}
 484
 485/**
 486 * snd_card_free_when_closed - Disconnect the card, free it later eventually
 487 * @card: soundcard structure
 488 *
 489 * Unlike snd_card_free(), this function doesn't try to release the card
 490 * resource immediately, but tries to disconnect at first.  When the card
 491 * is still in use, the function returns before freeing the resources.
 492 * The card resources will be freed when the refcount gets to zero.
 493 */
 494int snd_card_free_when_closed(struct snd_card *card)
 495{
 496        int ret = snd_card_disconnect(card);
 497        if (ret)
 498                return ret;
 499        put_device(&card->card_dev);
 500        return 0;
 501}
 502EXPORT_SYMBOL(snd_card_free_when_closed);
 503
 504/**
 505 * snd_card_free - frees given soundcard structure
 506 * @card: soundcard structure
 507 *
 508 * This function releases the soundcard structure and the all assigned
 509 * devices automatically.  That is, you don't have to release the devices
 510 * by yourself.
 511 *
 512 * This function waits until the all resources are properly released.
 513 *
 514 * Return: Zero. Frees all associated devices and frees the control
 515 * interface associated to given soundcard.
 516 */
 517int snd_card_free(struct snd_card *card)
 518{
 519        struct completion released;
 520        int ret;
 521
 522        init_completion(&released);
 523        card->release_completion = &released;
 524        ret = snd_card_free_when_closed(card);
 525        if (ret)
 526                return ret;
 527        /* wait, until all devices are ready for the free operation */
 528        wait_for_completion(&released);
 529        return 0;
 530}
 531EXPORT_SYMBOL(snd_card_free);
 532
 533/* retrieve the last word of shortname or longname */
 534static const char *retrieve_id_from_card_name(const char *name)
 535{
 536        const char *spos = name;
 537
 538        while (*name) {
 539                if (isspace(*name) && isalnum(name[1]))
 540                        spos = name + 1;
 541                name++;
 542        }
 543        return spos;
 544}
 545
 546/* return true if the given id string doesn't conflict any other card ids */
 547static bool card_id_ok(struct snd_card *card, const char *id)
 548{
 549        int i;
 550        if (!snd_info_check_reserved_words(id))
 551                return false;
 552        for (i = 0; i < snd_ecards_limit; i++) {
 553                if (snd_cards[i] && snd_cards[i] != card &&
 554                    !strcmp(snd_cards[i]->id, id))
 555                        return false;
 556        }
 557        return true;
 558}
 559
 560/* copy to card->id only with valid letters from nid */
 561static void copy_valid_id_string(struct snd_card *card, const char *src,
 562                                 const char *nid)
 563{
 564        char *id = card->id;
 565
 566        while (*nid && !isalnum(*nid))
 567                nid++;
 568        if (isdigit(*nid))
 569                *id++ = isalpha(*src) ? *src : 'D';
 570        while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) {
 571                if (isalnum(*nid))
 572                        *id++ = *nid;
 573                nid++;
 574        }
 575        *id = 0;
 576}
 577
 578/* Set card->id from the given string
 579 * If the string conflicts with other ids, add a suffix to make it unique.
 580 */
 581static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
 582                                    const char *nid)
 583{
 584        int len, loops;
 585        bool is_default = false;
 586        char *id;
 587        
 588        copy_valid_id_string(card, src, nid);
 589        id = card->id;
 590
 591 again:
 592        /* use "Default" for obviously invalid strings
 593         * ("card" conflicts with proc directories)
 594         */
 595        if (!*id || !strncmp(id, "card", 4)) {
 596                strcpy(id, "Default");
 597                is_default = true;
 598        }
 599
 600        len = strlen(id);
 601        for (loops = 0; loops < SNDRV_CARDS; loops++) {
 602                char *spos;
 603                char sfxstr[5]; /* "_012" */
 604                int sfxlen;
 605
 606                if (card_id_ok(card, id))
 607                        return; /* OK */
 608
 609                /* Add _XYZ suffix */
 610                sprintf(sfxstr, "_%X", loops + 1);
 611                sfxlen = strlen(sfxstr);
 612                if (len + sfxlen >= sizeof(card->id))
 613                        spos = id + sizeof(card->id) - sfxlen - 1;
 614                else
 615                        spos = id + len;
 616                strcpy(spos, sfxstr);
 617        }
 618        /* fallback to the default id */
 619        if (!is_default) {
 620                *id = 0;
 621                goto again;
 622        }
 623        /* last resort... */
 624        dev_err(card->dev, "unable to set card id (%s)\n", id);
 625        if (card->proc_root->name)
 626                strlcpy(card->id, card->proc_root->name, sizeof(card->id));
 627}
 628
 629/**
 630 *  snd_card_set_id - set card identification name
 631 *  @card: soundcard structure
 632 *  @nid: new identification string
 633 *
 634 *  This function sets the card identification and checks for name
 635 *  collisions.
 636 */
 637void snd_card_set_id(struct snd_card *card, const char *nid)
 638{
 639        /* check if user specified own card->id */
 640        if (card->id[0] != '\0')
 641                return;
 642        mutex_lock(&snd_card_mutex);
 643        snd_card_set_id_no_lock(card, nid, nid);
 644        mutex_unlock(&snd_card_mutex);
 645}
 646EXPORT_SYMBOL(snd_card_set_id);
 647
 648static ssize_t
 649card_id_show_attr(struct device *dev,
 650                  struct device_attribute *attr, char *buf)
 651{
 652        struct snd_card *card = container_of(dev, struct snd_card, card_dev);
 653        return scnprintf(buf, PAGE_SIZE, "%s\n", card->id);
 654}
 655
 656static ssize_t
 657card_id_store_attr(struct device *dev, struct device_attribute *attr,
 658                   const char *buf, size_t count)
 659{
 660        struct snd_card *card = container_of(dev, struct snd_card, card_dev);
 661        char buf1[sizeof(card->id)];
 662        size_t copy = count > sizeof(card->id) - 1 ?
 663                                        sizeof(card->id) - 1 : count;
 664        size_t idx;
 665        int c;
 666
 667        for (idx = 0; idx < copy; idx++) {
 668                c = buf[idx];
 669                if (!isalnum(c) && c != '_' && c != '-')
 670                        return -EINVAL;
 671        }
 672        memcpy(buf1, buf, copy);
 673        buf1[copy] = '\0';
 674        mutex_lock(&snd_card_mutex);
 675        if (!card_id_ok(NULL, buf1)) {
 676                mutex_unlock(&snd_card_mutex);
 677                return -EEXIST;
 678        }
 679        strcpy(card->id, buf1);
 680        snd_info_card_id_change(card);
 681        mutex_unlock(&snd_card_mutex);
 682
 683        return count;
 684}
 685
 686static DEVICE_ATTR(id, 0644, card_id_show_attr, card_id_store_attr);
 687
 688static ssize_t
 689card_number_show_attr(struct device *dev,
 690                     struct device_attribute *attr, char *buf)
 691{
 692        struct snd_card *card = container_of(dev, struct snd_card, card_dev);
 693        return scnprintf(buf, PAGE_SIZE, "%i\n", card->number);
 694}
 695
 696static DEVICE_ATTR(number, 0444, card_number_show_attr, NULL);
 697
 698static struct attribute *card_dev_attrs[] = {
 699        &dev_attr_id.attr,
 700        &dev_attr_number.attr,
 701        NULL
 702};
 703
 704static const struct attribute_group card_dev_attr_group = {
 705        .attrs  = card_dev_attrs,
 706};
 707
 708/**
 709 * snd_card_add_dev_attr - Append a new sysfs attribute group to card
 710 * @card: card instance
 711 * @group: attribute group to append
 712 */
 713int snd_card_add_dev_attr(struct snd_card *card,
 714                          const struct attribute_group *group)
 715{
 716        int i;
 717
 718        /* loop for (arraysize-1) here to keep NULL at the last entry */
 719        for (i = 0; i < ARRAY_SIZE(card->dev_groups) - 1; i++) {
 720                if (!card->dev_groups[i]) {
 721                        card->dev_groups[i] = group;
 722                        return 0;
 723                }
 724        }
 725
 726        dev_err(card->dev, "Too many groups assigned\n");
 727        return -ENOSPC;
 728}
 729EXPORT_SYMBOL_GPL(snd_card_add_dev_attr);
 730
 731/**
 732 *  snd_card_register - register the soundcard
 733 *  @card: soundcard structure
 734 *
 735 *  This function registers all the devices assigned to the soundcard.
 736 *  Until calling this, the ALSA control interface is blocked from the
 737 *  external accesses.  Thus, you should call this function at the end
 738 *  of the initialization of the card.
 739 *
 740 *  Return: Zero otherwise a negative error code if the registration failed.
 741 */
 742int snd_card_register(struct snd_card *card)
 743{
 744        int err;
 745
 746        if (snd_BUG_ON(!card))
 747                return -EINVAL;
 748
 749        if (!card->registered) {
 750                err = device_add(&card->card_dev);
 751                if (err < 0)
 752                        return err;
 753                card->registered = true;
 754        }
 755
 756        if ((err = snd_device_register_all(card)) < 0)
 757                return err;
 758        mutex_lock(&snd_card_mutex);
 759        if (snd_cards[card->number]) {
 760                /* already registered */
 761                mutex_unlock(&snd_card_mutex);
 762                return snd_info_card_register(card); /* register pending info */
 763        }
 764        if (*card->id) {
 765                /* make a unique id name from the given string */
 766                char tmpid[sizeof(card->id)];
 767                memcpy(tmpid, card->id, sizeof(card->id));
 768                snd_card_set_id_no_lock(card, tmpid, tmpid);
 769        } else {
 770                /* create an id from either shortname or longname */
 771                const char *src;
 772                src = *card->shortname ? card->shortname : card->longname;
 773                snd_card_set_id_no_lock(card, src,
 774                                        retrieve_id_from_card_name(src));
 775        }
 776        snd_cards[card->number] = card;
 777        mutex_unlock(&snd_card_mutex);
 778        err = snd_info_card_register(card);
 779        if (err < 0)
 780                return err;
 781
 782#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 783        if (snd_mixer_oss_notify_callback)
 784                snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
 785#endif
 786        return 0;
 787}
 788EXPORT_SYMBOL(snd_card_register);
 789
 790#ifdef CONFIG_SND_PROC_FS
 791static void snd_card_info_read(struct snd_info_entry *entry,
 792                               struct snd_info_buffer *buffer)
 793{
 794        int idx, count;
 795        struct snd_card *card;
 796
 797        for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
 798                mutex_lock(&snd_card_mutex);
 799                if ((card = snd_cards[idx]) != NULL) {
 800                        count++;
 801                        snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
 802                                        idx,
 803                                        card->id,
 804                                        card->driver,
 805                                        card->shortname);
 806                        snd_iprintf(buffer, "                      %s\n",
 807                                        card->longname);
 808                }
 809                mutex_unlock(&snd_card_mutex);
 810        }
 811        if (!count)
 812                snd_iprintf(buffer, "--- no soundcards ---\n");
 813}
 814
 815#ifdef CONFIG_SND_OSSEMUL
 816void snd_card_info_read_oss(struct snd_info_buffer *buffer)
 817{
 818        int idx, count;
 819        struct snd_card *card;
 820
 821        for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
 822                mutex_lock(&snd_card_mutex);
 823                if ((card = snd_cards[idx]) != NULL) {
 824                        count++;
 825                        snd_iprintf(buffer, "%s\n", card->longname);
 826                }
 827                mutex_unlock(&snd_card_mutex);
 828        }
 829        if (!count) {
 830                snd_iprintf(buffer, "--- no soundcards ---\n");
 831        }
 832}
 833
 834#endif
 835
 836#ifdef MODULE
 837static void snd_card_module_info_read(struct snd_info_entry *entry,
 838                                      struct snd_info_buffer *buffer)
 839{
 840        int idx;
 841        struct snd_card *card;
 842
 843        for (idx = 0; idx < SNDRV_CARDS; idx++) {
 844                mutex_lock(&snd_card_mutex);
 845                if ((card = snd_cards[idx]) != NULL)
 846                        snd_iprintf(buffer, "%2i %s\n",
 847                                    idx, card->module->name);
 848                mutex_unlock(&snd_card_mutex);
 849        }
 850}
 851#endif
 852
 853int __init snd_card_info_init(void)
 854{
 855        struct snd_info_entry *entry;
 856
 857        entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
 858        if (! entry)
 859                return -ENOMEM;
 860        entry->c.text.read = snd_card_info_read;
 861        if (snd_info_register(entry) < 0)
 862                return -ENOMEM; /* freed in error path */
 863
 864#ifdef MODULE
 865        entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL);
 866        if (!entry)
 867                return -ENOMEM;
 868        entry->c.text.read = snd_card_module_info_read;
 869        if (snd_info_register(entry) < 0)
 870                return -ENOMEM; /* freed in error path */
 871#endif
 872
 873        return 0;
 874}
 875#endif /* CONFIG_SND_PROC_FS */
 876
 877/**
 878 *  snd_component_add - add a component string
 879 *  @card: soundcard structure
 880 *  @component: the component id string
 881 *
 882 *  This function adds the component id string to the supported list.
 883 *  The component can be referred from the alsa-lib.
 884 *
 885 *  Return: Zero otherwise a negative error code.
 886 */
 887  
 888int snd_component_add(struct snd_card *card, const char *component)
 889{
 890        char *ptr;
 891        int len = strlen(component);
 892
 893        ptr = strstr(card->components, component);
 894        if (ptr != NULL) {
 895                if (ptr[len] == '\0' || ptr[len] == ' ')        /* already there */
 896                        return 1;
 897        }
 898        if (strlen(card->components) + 1 + len + 1 > sizeof(card->components)) {
 899                snd_BUG();
 900                return -ENOMEM;
 901        }
 902        if (card->components[0] != '\0')
 903                strcat(card->components, " ");
 904        strcat(card->components, component);
 905        return 0;
 906}
 907EXPORT_SYMBOL(snd_component_add);
 908
 909/**
 910 *  snd_card_file_add - add the file to the file list of the card
 911 *  @card: soundcard structure
 912 *  @file: file pointer
 913 *
 914 *  This function adds the file to the file linked-list of the card.
 915 *  This linked-list is used to keep tracking the connection state,
 916 *  and to avoid the release of busy resources by hotplug.
 917 *
 918 *  Return: zero or a negative error code.
 919 */
 920int snd_card_file_add(struct snd_card *card, struct file *file)
 921{
 922        struct snd_monitor_file *mfile;
 923
 924        mfile = kmalloc(sizeof(*mfile), GFP_KERNEL);
 925        if (mfile == NULL)
 926                return -ENOMEM;
 927        mfile->file = file;
 928        mfile->disconnected_f_op = NULL;
 929        INIT_LIST_HEAD(&mfile->shutdown_list);
 930        spin_lock(&card->files_lock);
 931        if (card->shutdown) {
 932                spin_unlock(&card->files_lock);
 933                kfree(mfile);
 934                return -ENODEV;
 935        }
 936        list_add(&mfile->list, &card->files_list);
 937        get_device(&card->card_dev);
 938        spin_unlock(&card->files_lock);
 939        return 0;
 940}
 941EXPORT_SYMBOL(snd_card_file_add);
 942
 943/**
 944 *  snd_card_file_remove - remove the file from the file list
 945 *  @card: soundcard structure
 946 *  @file: file pointer
 947 *
 948 *  This function removes the file formerly added to the card via
 949 *  snd_card_file_add() function.
 950 *  If all files are removed and snd_card_free_when_closed() was
 951 *  called beforehand, it processes the pending release of
 952 *  resources.
 953 *
 954 *  Return: Zero or a negative error code.
 955 */
 956int snd_card_file_remove(struct snd_card *card, struct file *file)
 957{
 958        struct snd_monitor_file *mfile, *found = NULL;
 959
 960        spin_lock(&card->files_lock);
 961        list_for_each_entry(mfile, &card->files_list, list) {
 962                if (mfile->file == file) {
 963                        list_del(&mfile->list);
 964                        spin_lock(&shutdown_lock);
 965                        list_del(&mfile->shutdown_list);
 966                        spin_unlock(&shutdown_lock);
 967                        if (mfile->disconnected_f_op)
 968                                fops_put(mfile->disconnected_f_op);
 969                        found = mfile;
 970                        break;
 971                }
 972        }
 973        if (list_empty(&card->files_list))
 974                wake_up_all(&card->remove_sleep);
 975        spin_unlock(&card->files_lock);
 976        if (!found) {
 977                dev_err(card->dev, "card file remove problem (%p)\n", file);
 978                return -ENOENT;
 979        }
 980        kfree(found);
 981        put_device(&card->card_dev);
 982        return 0;
 983}
 984EXPORT_SYMBOL(snd_card_file_remove);
 985
 986#ifdef CONFIG_PM
 987/**
 988 *  snd_power_wait - wait until the power-state is changed.
 989 *  @card: soundcard structure
 990 *  @power_state: expected power state
 991 *
 992 *  Waits until the power-state is changed.
 993 *
 994 *  Return: Zero if successful, or a negative error code.
 995 */
 996int snd_power_wait(struct snd_card *card, unsigned int power_state)
 997{
 998        wait_queue_entry_t wait;
 999        int result = 0;
1000
1001        /* fastpath */
1002        if (snd_power_get_state(card) == power_state)
1003                return 0;
1004        init_waitqueue_entry(&wait, current);
1005        add_wait_queue(&card->power_sleep, &wait);
1006        while (1) {
1007                if (card->shutdown) {
1008                        result = -ENODEV;
1009                        break;
1010                }
1011                if (snd_power_get_state(card) == power_state)
1012                        break;
1013                set_current_state(TASK_UNINTERRUPTIBLE);
1014                schedule_timeout(30 * HZ);
1015        }
1016        remove_wait_queue(&card->power_sleep, &wait);
1017        return result;
1018}
1019EXPORT_SYMBOL(snd_power_wait);
1020#endif /* CONFIG_PM */
1021