cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

init.c (30814B)


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