sound/firewire/motu/motu-hwdep.c

Source file repositories/reference/linux-study-clean/sound/firewire/motu/motu-hwdep.c

File Facts

System
Linux kernel
Corpus path
sound/firewire/motu/motu-hwdep.c
Extension
.c
Size
6796 bytes
Lines
287
Domain
Driver Families
Bucket
sound/firewire
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

snd_motu_register_dsp_message_parser_copy_event(motu, &ev)) {
			ptr = (u32 __user *)(buf + consumed);
			if (consumed + sizeof(ev) > count || put_user(ev, ptr))
				return -EFAULT;
			consumed += sizeof(ev);
		}

		event.motu_register_dsp_change.type = SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE;
		event.motu_register_dsp_change.count =
			(consumed - sizeof(event.motu_register_dsp_change)) / 4;
		if (copy_to_user(buf, &event,
				 min_t(long, count, sizeof(event.motu_register_dsp_change))))
			return -EFAULT;

		count = min_t(long, count, consumed);
	} else {
		spin_unlock_irq(&motu->lock);

		count = 0;
	}

	return count;
}

static __poll_t hwdep_poll(struct snd_hwdep *hwdep, struct file *file,
			       poll_table *wait)
{
	struct snd_motu *motu = hwdep->private_data;

	poll_wait(file, &motu->hwdep_wait, wait);

	guard(spinlock_irq)(&motu->lock);
	if (motu->dev_lock_changed || motu->msg || has_dsp_event(motu))
		return EPOLLIN | EPOLLRDNORM;
	else
		return 0;
}

static int hwdep_get_info(struct snd_motu *motu, void __user *arg)
{
	struct fw_device *dev = fw_parent_device(motu->unit);
	struct snd_firewire_get_info info;

	memset(&info, 0, sizeof(info));
	info.type = SNDRV_FIREWIRE_TYPE_MOTU;
	info.card = dev->card->index;
	*(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);
	*(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);
	strscpy(info.device_name, dev_name(&dev->device),
		sizeof(info.device_name));

	if (copy_to_user(arg, &info, sizeof(info)))
		return -EFAULT;

	return 0;
}

static int hwdep_lock(struct snd_motu *motu)
{
	guard(spinlock_irq)(&motu->lock);

	if (motu->dev_lock_count == 0) {
		motu->dev_lock_count = -1;
		return 0;
	} else {
		return -EBUSY;
	}
}

static int hwdep_unlock(struct snd_motu *motu)
{
	guard(spinlock_irq)(&motu->lock);

	if (motu->dev_lock_count == -1) {
		motu->dev_lock_count = 0;
		return 0;
	} else {
		return -EBADFD;
	}
}

static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)
{
	struct snd_motu *motu = hwdep->private_data;

	guard(spinlock_irq)(&motu->lock);
	if (motu->dev_lock_count == -1)
		motu->dev_lock_count = 0;

	return 0;

Annotation

Implementation Notes