drivers/gpu/drm/nouveau/nouveau_exec.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nouveau_exec.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nouveau_exec.c
Extension
.c
Size
11663 bytes
Lines
409
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 (unlikely(p->va_len > NV50_DMA_PUSH_MAX_LENGTH)) {
			NV_PRINTK(err, nouveau_cli(__args->file_priv),
				  "pushbuf size exceeds limit: 0x%x max 0x%x\n",
				  p->va_len, NV50_DMA_PUSH_MAX_LENGTH);
			return -EINVAL;
		}
	}

	job = *pjob = kzalloc_obj(*job);
	if (!job)
		return -ENOMEM;

	job->push.count = __args->push.count;
	if (__args->push.count) {
		job->push.s = kmemdup(__args->push.s,
				      sizeof(*__args->push.s) *
				      __args->push.count,
				      GFP_KERNEL);
		if (!job->push.s) {
			ret = -ENOMEM;
			goto err_free_job;
		}
	}

	args.file_priv = __args->file_priv;
	job->chan = __args->chan;

	args.sched = __args->sched;
	/* Plus one to account for the HW fence. */
	args.credits = job->push.count + 1;

	args.in_sync.count = __args->in_sync.count;
	args.in_sync.s = __args->in_sync.s;

	args.out_sync.count = __args->out_sync.count;
	args.out_sync.s = __args->out_sync.s;

	args.ops = &nouveau_exec_job_ops;
	args.resv_usage = DMA_RESV_USAGE_WRITE;

	ret = nouveau_job_init(&job->base, &args);
	if (ret)
		goto err_free_pushs;

	return 0;

err_free_pushs:
	kfree(job->push.s);
err_free_job:
	kfree(job);
	*pjob = NULL;

	return ret;
}

static int
nouveau_exec(struct nouveau_exec_job_args *args)
{
	struct nouveau_exec_job *job;
	int ret;

	ret = nouveau_exec_job_init(&job, args);
	if (ret)
		return ret;

	ret = nouveau_job_submit(&job->base);
	if (ret)
		goto err_job_fini;

	return 0;

err_job_fini:
	nouveau_job_fini(&job->base);
	return ret;
}

static int
nouveau_exec_ucopy(struct nouveau_exec_job_args *args,
		   struct drm_nouveau_exec *req)
{
	struct drm_nouveau_sync **s;
	u32 inc = req->wait_count;
	u64 ins = req->wait_ptr;
	u32 outc = req->sig_count;
	u64 outs = req->sig_ptr;
	u32 pushc = req->push_count;
	u64 pushs = req->push_ptr;
	int ret;

	if (pushc) {

Annotation

Implementation Notes