drivers/gpu/drm/qxl/qxl_release.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/qxl/qxl_release.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/qxl/qxl_release.c
Extension
.c
Size
11787 bytes
Lines
445
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

list_for_each_entry(entry, &release->bos, list) {
			ret = drm_exec_prepare_obj(&release->exec,
						   &entry->bo->tbo.base,
						   1);
			drm_exec_retry_on_contention(&release->exec);
			if (ret)
				goto error;
		}
	}

	list_for_each_entry(entry, &release->bos, list) {
		ret = qxl_release_validate_bo(entry->bo);
		if (ret)
			goto error;
	}
	return 0;
error:
	drm_exec_fini(&release->exec);
	return ret;
}

void qxl_release_backoff_reserve_list(struct qxl_release *release)
{
	/* if only one object on the release its the release itself
	   since these objects are pinned no need to reserve */
	if (list_is_singular(&release->bos))
		return;

	drm_exec_fini(&release->exec);
}

int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
				       enum qxl_surface_cmd_type surface_cmd_type,
				       struct qxl_release *create_rel,
				       struct qxl_release **release)
{
	if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) {
		int idr_ret;
		struct qxl_bo *bo;
		union qxl_release_info *info;

		/* stash the release after the create command */
		idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
		if (idr_ret < 0)
			return idr_ret;
		bo = create_rel->release_bo;

		(*release)->release_bo = bo;
		(*release)->release_offset = create_rel->release_offset + 64;

		qxl_release_list_add(*release, bo);

		info = qxl_release_map(qdev, *release);
		info->id = idr_ret;
		qxl_release_unmap(qdev, *release, info);
		return 0;
	}

	return qxl_alloc_release_reserved(qdev, sizeof(struct qxl_surface_cmd),
					 QXL_RELEASE_SURFACE_CMD, release, NULL);
}

int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
				       int type, struct qxl_release **release,
				       struct qxl_bo **rbo)
{
	struct qxl_bo *bo, *free_bo = NULL;
	int idr_ret;
	int ret = 0;
	union qxl_release_info *info;
	int cur_idx;
	u32 priority;

	if (type == QXL_RELEASE_DRAWABLE) {
		cur_idx = 0;
		priority = 0;
	} else if (type == QXL_RELEASE_SURFACE_CMD) {
		cur_idx = 1;
		priority = 1;
	} else if (type == QXL_RELEASE_CURSOR_CMD) {
		cur_idx = 2;
		priority = 1;
	}
	else {
		DRM_ERROR("got illegal type: %d\n", type);
		return -EINVAL;
	}

	idr_ret = qxl_release_alloc(qdev, type, release);
	if (idr_ret < 0) {

Annotation

Implementation Notes