sound/core/info.c

Source file repositories/reference/linux-study-clean/sound/core/info.c

File Facts

System
Linux kernel
Corpus path
sound/core/info.c
Extension
.c
Size
20231 bytes
Lines
888
Domain
Driver Families
Bucket
sound/core
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct snd_info_private_data {
	struct snd_info_buffer *rbuffer;
	struct snd_info_buffer *wbuffer;
	struct snd_info_entry *entry;
	void *file_private_data;
};

static int snd_info_version_init(void);
static void snd_info_clear_entries(struct snd_info_entry *entry);

/*

 */

static struct snd_info_entry *snd_proc_root;
struct snd_info_entry *snd_seq_root;
EXPORT_SYMBOL(snd_seq_root);

#ifdef CONFIG_SND_OSSEMUL
struct snd_info_entry *snd_oss_root;
#endif

static int alloc_info_private(struct snd_info_entry *entry,
			      struct snd_info_private_data **ret)
{
	struct snd_info_private_data *data;

	if (!entry || !entry->p)
		return -ENODEV;
	if (!try_module_get(entry->module))
		return -EFAULT;
	data = kzalloc_obj(*data);
	if (!data) {
		module_put(entry->module);
		return -ENOMEM;
	}
	data->entry = entry;
	*ret = data;
	return 0;
}

static bool valid_pos(loff_t pos, size_t count)
{
	if (pos < 0 || (long) pos != pos || (ssize_t) count < 0)
		return false;
	if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos)
		return false;
	return true;
}

/*
 * file ops for binary proc files
 */
static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
{
	struct snd_info_private_data *data;
	struct snd_info_entry *entry;
	loff_t size;

	data = file->private_data;
	entry = data->entry;
	guard(mutex)(&entry->access);
	if (entry->c.ops->llseek)
		return entry->c.ops->llseek(entry,
					    data->file_private_data,
					    file, offset, orig);

	size = entry->size;
	switch (orig) {
	case SEEK_SET:
		break;
	case SEEK_CUR:
		offset += file->f_pos;
		break;
	case SEEK_END:
		if (!size)
			return -EINVAL;
		offset += size;
		break;
	default:
		return -EINVAL;
	}
	if (offset < 0)
		return -EINVAL;
	if (size && offset > size)
		offset = size;
	file->f_pos = offset;
	return offset;
}

Annotation

Implementation Notes