sound/core/seq_device.c

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

File Facts

System
Linux kernel
Corpus path
sound/core/seq_device.c
Extension
.c
Size
7843 bytes
Lines
338
Domain
Driver Families
Bucket
sound/core
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static int snd_seq_bus_match(struct device *dev, const struct device_driver *drv)
{
	struct snd_seq_device *sdev = to_seq_dev(dev);
	const struct snd_seq_driver *sdrv = to_seq_drv(drv);

	return strcmp(sdrv->id, sdev->id) == 0 &&
		sdrv->argsize == sdev->argsize;
}

static int snd_seq_bus_probe(struct device *dev)
{
	struct snd_seq_device *sdev = to_seq_dev(dev);
	const struct snd_seq_driver *sdrv = to_seq_drv(dev->driver);

	if (sdrv->probe)
		return sdrv->probe(sdev);
	else
		return 0;
}

static void snd_seq_bus_remove(struct device *dev)
{
	struct snd_seq_device *sdev = to_seq_dev(dev);
	const struct snd_seq_driver *sdrv = to_seq_drv(dev->driver);

	if (sdrv->remove)
		sdrv->remove(sdev);
}

static const struct bus_type snd_seq_bus_type = {
	.name = "snd_seq",
	.match = snd_seq_bus_match,
	.probe = snd_seq_bus_probe,
	.remove = snd_seq_bus_remove,
};

/*
 * proc interface -- just for compatibility
 */
#ifdef CONFIG_SND_PROC_FS
static struct snd_info_entry *info_entry;

static int print_dev_info(struct device *dev, void *data)
{
	struct snd_seq_device *sdev = to_seq_dev(dev);
	struct snd_info_buffer *buffer = data;

	snd_iprintf(buffer, "snd-%s,%s,%d\n", sdev->id,
		    dev->driver ? "loaded" : "empty",
		    dev->driver ? 1 : 0);
	return 0;
}

static void snd_seq_device_info(struct snd_info_entry *entry,
				struct snd_info_buffer *buffer)
{
	bus_for_each_dev(&snd_seq_bus_type, NULL, buffer, print_dev_info);
}
#endif

/*
 * load all registered drivers (called from seq_clientmgr.c)
 */

#ifdef CONFIG_MODULES
/* flag to block auto-loading */
static atomic_t snd_seq_in_init = ATOMIC_INIT(1); /* blocked as default */

static int request_seq_drv(struct device *dev, void *data)
{
	struct snd_seq_device *sdev = to_seq_dev(dev);

	if (!dev->driver)
		request_module("snd-%s", sdev->id);
	return 0;
}

static void autoload_drivers(struct work_struct *work)
{
	/* avoid reentrance */
	if (atomic_inc_return(&snd_seq_in_init) == 1)
		bus_for_each_dev(&snd_seq_bus_type, NULL, NULL,
				 request_seq_drv);
	atomic_dec(&snd_seq_in_init);
}

static DECLARE_WORK(autoload_work, autoload_drivers);

static void queue_autoload_drivers(void)
{

Annotation

Implementation Notes