drivers/gpu/drm/vmwgfx/vmwgfx_gem.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
Extension
.c
Size
8843 bytes
Lines
351
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 (!ret) {
			if (drm_WARN_ON(obj->dev, map->is_iomem)) {
				dma_buf_vunmap(obj->import_attach->dmabuf, map);
				return -EIO;
			}
		}
	} else {
		ret = ttm_bo_vmap(bo, map);
	}

	return ret;
}

static void vmw_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
{
	if (drm_gem_is_imported(obj))
		dma_buf_vunmap(obj->import_attach->dmabuf, map);
	else
		drm_gem_ttm_vunmap(obj, map);
}

static int vmw_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
{
	int ret;

	if (drm_gem_is_imported(obj)) {
		/*
		 * Reset both vm_ops and vm_private_data, so we don't end up with
		 * vm_ops pointing to our implementation if the dma-buf backend
		 * doesn't set those fields.
		 */
		vma->vm_private_data = NULL;
		vma->vm_ops = NULL;

		ret = dma_buf_mmap(obj->dma_buf, vma, 0);

		/* Drop the reference drm_gem_mmap_obj() acquired.*/
		if (!ret)
			drm_gem_object_put(obj);

		return ret;
	}

	return drm_gem_ttm_mmap(obj, vma);
}

static const struct vm_operations_struct vmw_vm_ops = {
	.pfn_mkwrite = vmw_bo_vm_mkwrite,
	.page_mkwrite = vmw_bo_vm_mkwrite,
	.fault = vmw_bo_vm_fault,
	.open = ttm_bo_vm_open,
	.close = ttm_bo_vm_close,
};

const struct drm_gem_object_funcs vmw_gem_object_funcs = {
	.free = vmw_gem_object_free,
	.open = vmw_gem_object_open,
	.close = vmw_gem_object_close,
	.print_info = drm_gem_ttm_print_info,
	.pin = vmw_gem_object_pin,
	.unpin = vmw_gem_object_unpin,
	.get_sg_table = vmw_gem_object_get_sg_table,
	.vmap = vmw_gem_vmap,
	.vunmap = vmw_gem_vunmap,
	.mmap = vmw_gem_mmap,
	.vm_ops = &vmw_vm_ops,
};

int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv,
				      struct drm_file *filp,
				      uint32_t size,
				      uint32_t *handle,
				      struct vmw_bo **p_vbo)
{
	int ret;
	struct vmw_bo_params params = {
		.domain = (dev_priv->has_mob) ? VMW_BO_DOMAIN_SYS : VMW_BO_DOMAIN_VRAM,
		.busy_domain = VMW_BO_DOMAIN_SYS,
		.bo_type = ttm_bo_type_device,
		.size = size,
		.pin = false
	};

	ret = vmw_bo_create(dev_priv, &params, p_vbo);
	if (ret != 0)
		goto out_no_bo;

	ret = drm_gem_handle_create(filp, &(*p_vbo)->tbo.base, handle);
out_no_bo:
	return ret;

Annotation

Implementation Notes