Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b01d9f28 authored by Rusty Russell's avatar Rusty Russell
Browse files

Module autoprobing support for virtio drivers.



This adds the logic to convert the virtio ids into module aliases, and
includes a modalias entry in sysfs and the env var to make probing work.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 31610434
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -20,10 +20,19 @@ static ssize_t status_show(struct device *_d,
	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
	return sprintf(buf, "0x%08x", dev->config->get_status(dev));
}
static ssize_t modalias_show(struct device *_d,
			     struct device_attribute *attr, char *buf)
{
	struct virtio_device *dev = container_of(_d,struct virtio_device,dev);

	return sprintf(buf, "virtio:d%08Xv%08X\n",
		       dev->id.device, dev->id.vendor);
}
static struct device_attribute virtio_dev_attrs[] = {
	__ATTR_RO(device),
	__ATTR_RO(vendor),
	__ATTR_RO(status),
	__ATTR_RO(modalias),
	__ATTR_NULL
};

@@ -51,10 +60,19 @@ static int virtio_dev_match(struct device *_dv, struct device_driver *_dr)
	return 0;
}

static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env)
{
	struct virtio_device *dev = container_of(_dv,struct virtio_device,dev);

	return add_uevent_var(env, "MODALIAS=virtio:d%08Xv%08X",
			      dev->id.device, dev->id.vendor);
}

static struct bus_type virtio_bus = {
	.name  = "virtio",
	.match = virtio_dev_match,
	.dev_attrs = virtio_dev_attrs,
	.uevent = virtio_uevent,
};

static void add_status(struct virtio_device *dev, unsigned status)
+18 −0
Original line number Diff line number Diff line
@@ -525,6 +525,20 @@ static int do_ssb_entry(const char *filename,
	return 1;
}

/* Looks like: virtio:dNvN */
static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
			   char *alias)
{
	id->device = TO_NATIVE(id->device);
	id->vendor = TO_NATIVE(id->vendor);

	strcpy(alias, "virtio:");
	ADD(alias, "d", 1, id->device);
	ADD(alias, "v", id->vendor != VIRTIO_DEV_ANY_ID, id->vendor);

	return 1;
}

/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
@@ -651,6 +665,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
		do_table(symval, sym->st_size,
			 sizeof(struct ssb_device_id), "ssb",
			 do_ssb_entry, mod);
	else if (sym_is(symname, "__mod_virtio_device_table"))
		do_table(symval, sym->st_size,
			 sizeof(struct virtio_device_id), "virtio",
			 do_virtio_entry, mod);
	free(zeros);
}