int nvshm_iobuf_ref_cluster(struct nvshm_iobuf *iob) { int ref, ret = 0; struct nvshm_iobuf *_phy_list, *_phy_leaf; struct nvshm_handle *handle = nvshm_get_handle(); _phy_list = iob; while (_phy_list) { _phy_leaf = _phy_list; while (_phy_leaf) { ref = nvshm_iobuf_ref(_phy_leaf); ret = (ref > ret) ? ref : ret; if (_phy_leaf->sg_next) { _phy_leaf = NVSHM_B2A(handle, _phy_leaf->sg_next); } else { _phy_leaf = NULL; } } if (_phy_list->next) _phy_list = NVSHM_B2A(handle, _phy_list->next); else _phy_list = NULL; } return ret; }
int nvshm_queue_put(struct nvshm_handle *handle, struct nvshm_iobuf *iob) { unsigned long f; spin_lock_irqsave(&handle->qlock, f); if (!handle->shared_queue_tail) { spin_unlock_irqrestore(&handle->qlock, f); pr_err("%s: Queue not init!\n", __func__); return -EINVAL; } if (!iob) { pr_err("%s: Queueing null pointer!\n", __func__); spin_unlock_irqrestore(&handle->qlock, f); return -EINVAL; } /* Sanity check */ if (handle->shared_queue_tail->qnext) { pr_err("%s: illegal queue pointer detected!\n", __func__); spin_unlock_irqrestore(&handle->qlock, f); return -EINVAL; } pr_debug("%s (%p)->%p/%d/%d->%p\n", __func__, handle->shared_queue_tail, iob, iob->chan, iob->length, iob->next); /* Take a reference on queued iobuf */ nvshm_iobuf_ref(iob); /* Flush iobuf(s) in cache */ flush_iob_list(handle, iob); handle->shared_queue_tail->qnext = NVSHM_A2B(handle, iob); /* Flush guard element from cache */ FLUSH_CPU_DCACHE(handle->shared_queue_tail, sizeof(struct nvshm_iobuf)); handle->shared_queue_tail = iob; spin_unlock_irqrestore(&handle->qlock, f); return 0; }