struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch,
		struct nvhost_hwctx *hwctx,
		struct nvhost_submit_hdr_ext *hdr,
		struct nvmap_client *nvmap,
		int priority,
		int clientid)
{
	struct nvhost_job *job = NULL;
	int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0;
	int err = 0;

	job = vzalloc(job_size(hdr));
	if (!job)
		goto error;

	kref_init(&job->ref);
	job->ch = ch;
	job->hwctx = hwctx;
	if (hwctx)
		hwctx->h->get(hwctx);
	job->nvmap = nvmap ? nvmap_client_get(nvmap) : NULL;

	err = alloc_gathers(job, num_cmdbufs);
	if (err)
		goto error;

	init_fields(job, hdr, priority, clientid);

	return job;

error:
	if (job)
		nvhost_job_put(job);
	return NULL;
}
Beispiel #2
0
static void add_to_sync_queue(struct sync_queue *queue,
			      u32 sync_point_id, u32 sync_point_value,
			      u32 nr_slots, struct nvmap_client *user_nvmap,
			      struct nvmap_handle **handles, u32 nr_handles,
			      u32 first_get,
			      struct nvhost_userctx_timeout *timeout)
{
	struct nvhost_cdma *cdma;
	struct nvhost_master *host;
	u32 size, write = queue->write;
	u32 *p = queue->buffer + write;

	cdma = container_of(queue, struct nvhost_cdma, sync_queue);
	host = cdma_to_dev(cdma);

	BUG_ON(sync_point_id == NVSYNCPT_INVALID);
	BUG_ON(sync_queue_space(queue) < nr_handles);

	size  = SQ_IDX_HANDLES;
	size += entry_size(nr_handles);

	write += size;
	BUG_ON(write > host->sync_queue_size);

	p[SQ_IDX_SYNCPT_ID] = sync_point_id;
	p[SQ_IDX_SYNCPT_VAL] = sync_point_value;
	p[SQ_IDX_FIRST_GET] = first_get;
	p[SQ_IDX_TIMEOUT] = timeout->timeout;
	p[SQ_IDX_NUM_SLOTS] = nr_slots;
	p[SQ_IDX_NUM_HANDLES] = nr_handles;

	*(void **)(&p[SQ_IDX_TIMEOUT_CTX]) = timeout;

	BUG_ON(!user_nvmap);
	*(struct nvmap_client **)(&p[SQ_IDX_NVMAP_CTX]) =
		nvmap_client_get(user_nvmap);

	if (nr_handles) {
		memcpy(&p[SQ_IDX_HANDLES], handles,
			(nr_handles * sizeof(struct nvmap_handle *)));
	}

	/* If there's not enough room for another entry, wrap to the start. */
	if ((write + SYNC_QUEUE_MIN_ENTRY) > host->sync_queue_size) {
		/*
		 * It's an error for the read position to be zero, as that
		 * would mean we emptied the queue while adding something.
		 */
		BUG_ON(queue->read == 0);
		write = 0;
	}
	queue->write = write;
}
struct nvhost_job *nvhost_job_realloc(
		struct nvhost_job *oldjob,
		struct nvhost_hwctx *hwctx,
		struct nvhost_submit_hdr_ext *hdr,
		struct nvmap_client *nvmap,
		int priority, int clientid)
{
	struct nvhost_job *newjob = NULL;
	int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0;
	int err = 0;

	newjob = vzalloc(job_size(hdr));
	if (!newjob)
		goto error;
	kref_init(&newjob->ref);
	newjob->ch = oldjob->ch;
	newjob->hwctx = hwctx;
	if (hwctx)
		newjob->hwctx->h->get(newjob->hwctx);
	newjob->timeout = oldjob->timeout;
	newjob->nvmap = nvmap ? nvmap_client_get(nvmap) : NULL;

	err = realloc_gathers(oldjob, newjob, num_cmdbufs);
	if (err)
		goto error;

	nvhost_job_put(oldjob);

	init_fields(newjob, hdr, priority, clientid);

	return newjob;

error:
	if (newjob)
		nvhost_job_put(newjob);
	if (oldjob)
		nvhost_job_put(oldjob);
	return NULL;
}
Beispiel #4
0
struct mem_mgr *nvhost_nvmap_get_mgr(struct mem_mgr *mgr)
{
	return (struct mem_mgr *)nvmap_client_get((struct nvmap_client *)mgr);
}