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; }
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); } }