sound/core/control_compat.c

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

File Facts

System
Linux kernel
Corpus path
sound/core/control_compat.c
Extension
.c
Size
12926 bytes
Lines
489
Domain
Driver Families
Bucket
sound/core
Inferred role
Driver Families: implementation source
Status
source 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_ctl_elem_list32 {
	u32 offset;
	u32 space;
	u32 used;
	u32 count;
	u32 pids;
	unsigned char reserved[50];
} /* don't set packed attribute here */;

static int snd_ctl_elem_list_compat(struct snd_card *card,
				    struct snd_ctl_elem_list32 __user *data32)
{
	struct snd_ctl_elem_list data = {};
	compat_caddr_t ptr;
	int err;

	/* offset, space, used, count */
	if (copy_from_user(&data, data32, 4 * sizeof(u32)))
		return -EFAULT;
	/* pids */
	if (get_user(ptr, &data32->pids))
		return -EFAULT;
	data.pids = compat_ptr(ptr);
	err = snd_ctl_elem_list(card, &data);
	if (err < 0)
		return err;
	/* copy the result */
	if (copy_to_user(data32, &data, 4 * sizeof(u32)))
		return -EFAULT;
	return 0;
}

/*
 * control element info
 * it uses union, so the things are not easy..
 */

struct snd_ctl_elem_info32 {
	struct snd_ctl_elem_id id; // the size of struct is same
	s32 type;
	u32 access;
	u32 count;
	s32 owner;
	union {
		struct {
			s32 min;
			s32 max;
			s32 step;
		} integer;
		struct {
			u64 min;
			u64 max;
			u64 step;
		} integer64;
		struct {
			u32 items;
			u32 item;
			char name[64];
			u64 names_ptr;
			u32 names_length;
		} enumerated;
		unsigned char reserved[128];
	} value;
	unsigned char reserved[64];
} __packed;

static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
				    struct snd_ctl_elem_info32 __user *data32)
{
	struct snd_card *card = ctl->card;
	int err;
	struct snd_ctl_elem_info *data __free(kfree) =
		kzalloc_obj(*data);

	if (! data)
		return -ENOMEM;

	/* copy id */
	if (copy_from_user(&data->id, &data32->id, sizeof(data->id)))
		return -EFAULT;
	/* we need to copy the item index.
	 * hope this doesn't break anything..
	 */
	if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
		return -EFAULT;

	err = snd_power_ref_and_wait(card);
	if (err < 0)
		return err;
	err = snd_ctl_elem_info(ctl, data);

Annotation

Implementation Notes