drivers/gpu/drm/nouveau/nvkm/core/ioctl.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
Extension
.c
Size
8033 bytes
Lines
314
Domain
Driver Families
Bucket
drivers/gpu
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

while (nvkm_ioctl_sclass_(object, i, &oclass) >= 0) {
			if (i < args->v0.count) {
				args->v0.oclass[i].oclass = oclass.base.oclass;
				args->v0.oclass[i].minver = oclass.base.minver;
				args->v0.oclass[i].maxver = oclass.base.maxver;
			}
			i++;
		}

		args->v0.count = i;
	}

	return ret;
}

static int
nvkm_ioctl_new(struct nvkm_client *client,
	       struct nvkm_object *parent, void *data, u32 size)
{
	union {
		struct nvif_ioctl_new_v0 v0;
	} *args = data;
	struct nvkm_object *object = NULL;
	struct nvkm_oclass oclass;
	int ret = -ENOSYS, i = 0;

	nvif_ioctl(parent, "new size %d\n", size);
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
		nvif_ioctl(parent, "new vers %d handle %08x class %08x object %016llx\n",
			   args->v0.version, args->v0.handle, args->v0.oclass,
			   args->v0.object);
	} else
		return ret;

	if (!parent->func->sclass && !parent->func->uevent) {
		nvif_ioctl(parent, "cannot have children\n");
		return -EINVAL;
	}

	do {
		memset(&oclass, 0x00, sizeof(oclass));
		oclass.handle = args->v0.handle;
		oclass.object = args->v0.object;
		oclass.client = client;
		oclass.parent = parent;
		ret = nvkm_ioctl_sclass_(parent, i++, &oclass);
		if (ret)
			return ret;
	} while (oclass.base.oclass != args->v0.oclass);

	if (oclass.engine) {
		oclass.engine = nvkm_engine_ref(oclass.engine);
		if (IS_ERR(oclass.engine))
			return PTR_ERR(oclass.engine);
	}

	ret = oclass.ctor(&oclass, data, size, &object);
	nvkm_engine_unref(&oclass.engine);
	if (ret == 0) {
		ret = nvkm_object_init(object);
		if (ret == 0) {
			list_add_tail(&object->head, &parent->tree);
			if (nvkm_object_insert(object)) {
				client->data = object;
				return 0;
			}
			ret = -EEXIST;
		}
		nvkm_object_fini(object, NVKM_POWEROFF);
	}

	nvkm_object_del(&object);
	return ret;
}

static int
nvkm_ioctl_del(struct nvkm_client *client,
	       struct nvkm_object *object, void *data, u32 size)
{
	union {
		struct nvif_ioctl_del none;
	} *args = data;
	int ret = -ENOSYS;

	nvif_ioctl(object, "delete size %d\n", size);
	if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
		nvif_ioctl(object, "delete\n");
		nvkm_object_fini(object, NVKM_POWEROFF);
		nvkm_object_del(&object);
	}

Annotation

Implementation Notes