Exemplo n.º 1
0
/**
 *
 * vq_ring_add_buffer
 *
 */
static uint16_t vq_ring_add_buffer(struct virtqueue *vq,
				   struct vring_desc *desc, uint16_t head_idx,
				   struct llist *buffer, int readable,
				   int writable)
{

	struct vring_desc *dp;
	int i, needed;
	uint16_t idx;

	(void)vq;

	needed = readable + writable;

	for (i = 0, idx = head_idx; (i < needed && buffer != VQ_NULL);
	     i++, idx = dp->next, buffer = buffer->next) {

		VQASSERT(vq, idx != VQ_RING_DESC_CHAIN_END,
			 "premature end of free desc chain");

		dp = &desc[idx];
		dp->addr = env_map_vatopa(buffer->data);
		dp->len = buffer->attr;
		dp->flags = 0;

		if (i < needed - 1)
			dp->flags |= VRING_DESC_F_NEXT;

		/* Readable buffers are inserted into vring before the writable buffers. */
		if (i >= readable)
			dp->flags |= VRING_DESC_F_WRITE;
	}

	return (idx);
}
Exemplo n.º 2
0
/**
 * rpmsg_get_rx_buffer
 *
 * Retrieves the received buffer from the virtqueue.
 *
 * @param rdev - pointer to remote device
 * @param len  - size of received buffer
 * @param idx  - index of buffer
 *
 * @return - pointer to received buffer
 *
 */
void *rpmsg_get_rx_buffer(struct remote_device *rdev, unsigned long *len,
                          unsigned short *idx) {

    void *data;
    if (rdev->role == RPMSG_REMOTE) {
        data = virtqueue_get_buffer(rdev->rvq, len);
    } else {
        data = virtqueue_get_available_buffer(rdev->rvq, idx, len);
    }
    return ((void *) env_map_vatopa(data));
}
Exemplo n.º 3
0
/**
 * virtqueue_add_single_buffer - Enqueues single buffer in vring
 *
 * @param vq                    - Pointer to VirtIO queue control block
 * @param cookie                - Pointer to hold call back data
 * @param buffer_addr           - Address of buffer
 * @param len                   - Length of buffer
 * @param writable              - If buffer writable
 * @param has_next              - If buffers for subsequent call are
 *                                to be chained
 *
 * @return                      - Function status
 */
int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,
				void *buffer_addr, uint32_t len, int writable,
				boolean has_next)
{

	struct vq_desc_extra *dxp;
	struct vring_desc *dp;
	uint16_t head_idx;
	uint16_t idx;
	int status = VQUEUE_SUCCESS;

	VQ_PARAM_CHK(vq == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
	VQ_PARAM_CHK(vq->vq_free_cnt == 0, status, ERROR_VRING_FULL);

	VQUEUE_BUSY(vq);

	if (status == VQUEUE_SUCCESS) {

		VQASSERT(vq, cookie != VQ_NULL, "enqueuing with no cookie");

		head_idx = vq->vq_desc_head_idx;
		dxp = &vq->vq_descx[head_idx];

		dxp->cookie = cookie;
		dxp->ndescs = 1;
		idx = head_idx;

		dp = &vq->vq_ring.desc[idx];
		dp->addr = env_map_vatopa(buffer_addr);
		dp->len = len;
		dp->flags = 0;
		idx = dp->next;

		if (has_next)
			dp->flags |= VRING_DESC_F_NEXT;
		if (writable)
			dp->flags |= VRING_DESC_F_WRITE;

		vq->vq_desc_head_idx = idx;
		vq->vq_free_cnt--;

		if (vq->vq_free_cnt == 0) {
			VQ_RING_ASSERT_CHAIN_TERM(vq);
		} else {
			VQ_RING_ASSERT_VALID_IDX(vq, idx);
		}

		vq_ring_update_avail(vq, head_idx);
	}

	VQUEUE_IDLE(vq);

	return (status);
}
Exemplo n.º 4
0
/**
 * rpmsg_get_tx_buffer
 *
 * Provides buffer to transmit messages.
 *
 * @param rdev - pointer to remote device
 * @param len  - length of returned buffer
 * @param idx  - buffer index
 *
 * return - pointer to buffer.
 */
void *rpmsg_get_tx_buffer(struct remote_device *rdev, int *len,
                          unsigned short *idx) {
    void *data;

    if (rdev->role == RPMSG_REMOTE) {
        data = virtqueue_get_buffer(rdev->tvq, (unsigned long *) len);
        if (data == RPMSG_NULL) {
            data = sh_mem_get_buffer(rdev->mem_pool);
            *len = RPMSG_BUFFER_SIZE;
        }
    } else {
        data = virtqueue_get_available_buffer(rdev->tvq, idx,
                                              (unsigned long *) len);
    }
    return ((void *) env_map_vatopa(data));
}