drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c
Extension
.c
Size
4967 bytes
Lines
191
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

if (client != master) {
			spin_lock(&master->lock);
			list_for_each_entry(umem, &master->umem, head) {
				if (umem->object.object == handle) {
					memory = nvkm_memory_ref(umem->memory);
					break;
				}
			}
			spin_unlock(&master->lock);
		}
	} else {
		umem = nvkm_umem(object);
		memory = nvkm_memory_ref(umem->memory);
	}

	return memory ? memory : ERR_PTR(-ENOENT);
}

static int
nvkm_umem_unmap(struct nvkm_object *object)
{
	struct nvkm_umem *umem = nvkm_umem(object);

	if (!umem->map)
		return -EEXIST;

	if (umem->io) {
		if (!IS_ERR(umem->bar)) {
			struct nvkm_device *device = umem->mmu->subdev.device;
			nvkm_vmm_put(nvkm_bar_bar1_vmm(device), &umem->bar);
		} else {
			umem->bar = NULL;
		}
	} else {
		vunmap(umem->map);
		umem->map = NULL;
	}

	return 0;
}

static int
nvkm_umem_map(struct nvkm_object *object, void *argv, u32 argc,
	      enum nvkm_object_map *type, u64 *handle, u64 *length)
{
	struct nvkm_umem *umem = nvkm_umem(object);
	struct nvkm_mmu *mmu = umem->mmu;

	if (!umem->mappable)
		return -EINVAL;
	if (umem->map)
		return -EEXIST;

	if ((umem->type & NVKM_MEM_HOST) && !argc) {
		int ret = nvkm_mem_map_host(umem->memory, &umem->map);
		if (ret)
			return ret;

		*handle = (unsigned long)(void *)umem->map;
		*length = nvkm_memory_size(umem->memory);
		*type = NVKM_OBJECT_MAP_VA;
		return 0;
	} else
	if ((umem->type & NVKM_MEM_VRAM) ||
	    (umem->type & NVKM_MEM_KIND)) {
		int ret = mmu->func->mem.umap(mmu, umem->memory, argv, argc,
					      handle, length, &umem->bar);
		if (ret)
			return ret;

		*type = NVKM_OBJECT_MAP_IO;
	} else {
		return -EINVAL;
	}

	umem->io = (*type == NVKM_OBJECT_MAP_IO);
	return 0;
}

static void *
nvkm_umem_dtor(struct nvkm_object *object)
{
	struct nvkm_umem *umem = nvkm_umem(object);
	spin_lock(&umem->object.client->lock);
	list_del_init(&umem->head);
	spin_unlock(&umem->object.client->lock);
	nvkm_memory_unref(&umem->memory);
	return umem;
}

Annotation

Implementation Notes