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