struct nvshm_iobuf *nvshm_queue_get(struct nvshm_handle *handle)
{
	struct nvshm_iobuf *dummy, *ret;

	if (!handle->shared_queue_head) {
		pr_err("%s: Queue not init!\n", __func__);
		return NULL;
	}

	dummy = handle->shared_queue_head;
	/* Invalidate lower part of iobuf - upper part can be written by AP */

	INV_CPU_DCACHE(&dummy->qnext,
		       sizeof(struct nvshm_iobuf) / 2);
	ret = NVSHM_B2A(handle, dummy->qnext);

	if (dummy->qnext == NULL)
		return NULL;

	/* Invalidate iobuf(s) and check validity */
	handle->errno = inv_iob_list(handle, ret);

	if (handle->errno) {
		pr_err("%s: queue corruption\n", __func__);
		return NULL;
	}

	handle->shared_queue_head = ret;

	/* Update queue_bb_offset for debug purpose */
	handle->conf->queue_bb_offset = (int)ret
		- (int)handle->ipc_base_virt;

	if ((handle->conf->queue_bb_offset < 0) ||
	    (handle->conf->queue_bb_offset > handle->conf->shmem_size))
		pr_err("%s: out of bound descriptor offset %d addr 0x%p/0x%p\n",
		       __func__,
		       handle->conf->queue_bb_offset,
		       ret,
		       NVSHM_A2B(handle, ret));

	pr_debug("%s (%p)->%p->(%p)\n", __func__,
		 dummy, ret, ret->qnext);

	dummy->qnext = NULL;
	nvshm_iobuf_free(dummy);

	return ret;
}
예제 #2
0
void nvshm_iobuf_free_cluster(struct nvshm_iobuf *list)
{
	struct nvshm_handle *priv = nvshm_get_handle();
	struct nvshm_iobuf *_phy_list, *_to_free, *leaf;
	int n = 0;

	_phy_list = list;
	while (_phy_list) {
		_to_free = list;
		if (list->sg_next) {
			_phy_list = list->sg_next;
			if (_phy_list) {
				leaf = NVSHM_B2A(priv, _phy_list);
				leaf->next = list->next;
			}
		} else {
			_phy_list = list->next;
		}
		list = NVSHM_B2A(priv, _phy_list);
		n++;
		nvshm_iobuf_free(_to_free);
	}
}