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