Exemplo n.º 1
0
int
vmbus_chan_recv_pkt(struct vmbus_channel *chan,
    struct vmbus_chanpkt_hdr *pkt0, int *pktlen0)
{
	struct vmbus_chanpkt_hdr pkt;
	int error, pktlen;

	error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt));
	if (error)
		return error;

	pktlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen);
	if (*pktlen0 < pktlen) {
		/* Return the size of this packet. */
		*pktlen0 = pktlen;
		return ENOBUFS;
	}
	*pktlen0 = pktlen;

	/* Include packet header */
	error = vmbus_rxbr_read(&chan->ch_rxbr, pkt0, pktlen, 0);
	KASSERT(!error, ("vmbus_rxbr_read failed"));

	return 0;
}
Exemplo n.º 2
0
int
vmbus_chan_recv(struct vmbus_channel *chan, void *data, int *dlen0,
    uint64_t *xactid)
{
	struct vmbus_chanpkt_hdr pkt;
	int error, dlen, hlen;

	error = vmbus_rxbr_peek(&chan->ch_rxbr, &pkt, sizeof(pkt));
	if (error)
		return error;

	hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen);
	dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen;

	if (*dlen0 < dlen) {
		/* Return the size of this packet's data. */
		*dlen0 = dlen;
		return ENOBUFS;
	}

	*xactid = pkt.cph_xactid;
	*dlen0 = dlen;

	/* Skip packet header */
	error = vmbus_rxbr_read(&chan->ch_rxbr, data, dlen, hlen);
	KASSERT(!error, ("vmbus_rxbr_read failed"));

	return 0;
}
Exemplo n.º 3
0
int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan,
			    void *data, uint32_t *len)
{
	struct vmbus_chanpkt_hdr pkt;
	uint32_t dlen, bufferlen = *len;
	int error;

	error = vmbus_rxbr_peek(&chan->rxbr, &pkt, sizeof(pkt));
	if (error)
		return error;

	if (unlikely(pkt.hlen < VMBUS_CHANPKT_HLEN_MIN)) {
		VMBUS_LOG(ERR, "VMBUS recv, invalid hlen %u", pkt.hlen);
		/* XXX this channel is dead actually. */
		return -EIO;
	}

	if (unlikely(pkt.hlen > pkt.tlen)) {
		VMBUS_LOG(ERR, "VMBUS recv,invalid hlen %u and tlen %u",
			pkt.hlen, pkt.tlen);
		return -EIO;
	}

	/* Length are in quad words */
	dlen = pkt.tlen << VMBUS_CHANPKT_SIZE_SHIFT;
	*len = dlen;

	/* If caller buffer is not large enough */
	if (unlikely(dlen > bufferlen))
		return -ENOBUFS;

	/* Put packet header in data buffer */
	return vmbus_read_and_signal(chan, data, dlen, 0);
}
Exemplo n.º 4
0
static void vmbus_dump_ring(FILE *f, const char *id, const struct vmbus_br *br)
{
	const struct vmbus_bufring *vbr = br->vbr;
	struct vmbus_chanpkt_hdr pkt;

	fprintf(f, "%s windex=%u rindex=%u mask=%u pending=%u feature=%#x\n",
		id, vbr->windex, vbr->rindex, vbr->imask,
		vbr->pending_send, vbr->feature_bits.value);
	fprintf(f, " size=%u avail write=%u read=%u\n",
		br->dsize, vmbus_br_availwrite(br, vbr->windex),
		vmbus_br_availread(br));

	if (vmbus_rxbr_peek(br, &pkt, sizeof(pkt)) == 0)
		fprintf(f, "  pkt type %#x len %u flags %#x xactid %#"PRIx64"\n",
			pkt.type,
			pkt.tlen << VMBUS_CHANPKT_SIZE_SHIFT,
			pkt.flags, pkt.xactid);
}