svn commit: r307080 - in stable/10/sys/dev/hyperv: include netvsc storvsc utilities vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Wed Oct 12 02:09:55 UTC 2016
Author: sephe
Date: Wed Oct 12 02:09:53 2016
New Revision: 307080
URL: https://svnweb.freebsd.org/changeset/base/307080
Log:
MFC 302885,302886
302885
hyperv/vmbus: Cleanup channel receiving.
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D7202
302886
hyperv/vmbus: Cleanup channel packet receiving.
Sponsored by: Microsoft OSTC
Differential Revision: https://reviews.freebsd.org/D7204
Modified:
stable/10/sys/dev/hyperv/include/hyperv.h
stable/10/sys/dev/hyperv/include/vmbus.h
stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c
stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c
stable/10/sys/dev/hyperv/utilities/hv_kvp.c
stable/10/sys/dev/hyperv/utilities/hv_shutdown.c
stable/10/sys/dev/hyperv/utilities/hv_timesync.c
stable/10/sys/dev/hyperv/vmbus/hv_channel.c
stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/hyperv/include/hyperv.h
==============================================================================
--- stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/include/hyperv.h Wed Oct 12 02:09:53 2016 (r307080)
@@ -90,28 +90,6 @@ struct hyperv_guid {
int hyperv_guid2str(const struct hyperv_guid *, char *, size_t);
-typedef struct {
- uint16_t type;
- uint16_t data_offset8;
- uint16_t length8;
- uint16_t flags;
- uint64_t transaction_id;
-} __packed hv_vm_packet_descriptor;
-
-typedef struct {
- uint32_t byte_count;
- uint32_t byte_offset;
-} __packed hv_vm_transfer_page;
-
-typedef struct {
- hv_vm_packet_descriptor d;
- uint16_t transfer_page_set_id;
- hv_bool_uint8_t sender_owns_set;
- uint8_t reserved;
- uint32_t range_count;
- hv_vm_transfer_page ranges[1];
-} __packed hv_vm_transfer_page_packet_header;
-
#define HW_MACADDR_LEN 6
/*
@@ -298,20 +276,6 @@ hv_set_channel_read_state(hv_vmbus_chann
channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD;
}
-int hv_vmbus_channel_recv_packet(
- hv_vmbus_channel* channel,
- void* buffer,
- uint32_t buffer_len,
- uint32_t* buffer_actual_len,
- uint64_t* request_id);
-
-int hv_vmbus_channel_recv_packet_raw(
- hv_vmbus_channel* channel,
- void* buffer,
- uint32_t buffer_len,
- uint32_t* buffer_actual_len,
- uint64_t* request_id);
-
int hv_vmbus_channel_open(
hv_vmbus_channel* channel,
uint32_t send_ring_buffer_size,
Modified: stable/10/sys/dev/hyperv/include/vmbus.h
==============================================================================
--- stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/include/vmbus.h Wed Oct 12 02:09:53 2016 (r307080)
@@ -47,6 +47,19 @@ struct vmbus_gpa {
uint64_t gpa_page;
} __packed;
+#define VMBUS_CHANPKT_SIZE_SHIFT 3
+
+#define VMBUS_CHANPKT_GETLEN(pktlen) \
+ (((int)(pktlen)) << VMBUS_CHANPKT_SIZE_SHIFT)
+
+struct vmbus_chanpkt_hdr {
+ uint16_t cph_type; /* VMBUS_CHANPKT_TYPE_ */
+ uint16_t cph_hlen; /* header len, in 8 bytes */
+ uint16_t cph_tlen; /* total len, in 8 bytes */
+ uint16_t cph_flags; /* VMBUS_CHANPKT_FLAG_ */
+ uint64_t cph_xactid;
+} __packed;
+
#define VMBUS_CHANPKT_TYPE_INBAND 0x0006
#define VMBUS_CHANPKT_TYPE_RXBUF 0x0007
#define VMBUS_CHANPKT_TYPE_GPA 0x0009
@@ -54,11 +67,33 @@ struct vmbus_gpa {
#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */
+#define VMBUS_CHANPKT_CONST_DATA(pkt) \
+ (const void *)((const uint8_t *)(pkt) + \
+ VMBUS_CHANPKT_GETLEN((pkt)->cph_hlen))
+
+struct vmbus_rxbuf_desc {
+ uint32_t rb_len;
+ uint32_t rb_ofs;
+} __packed;
+
+struct vmbus_chanpkt_rxbuf {
+ struct vmbus_chanpkt_hdr cp_hdr;
+ uint16_t cp_rxbuf_id;
+ uint16_t cp_rsvd;
+ uint32_t cp_rxbuf_cnt;
+ struct vmbus_rxbuf_desc cp_rxbuf[];
+} __packed;
+
#define VMBUS_CHAN_SGLIST_MAX 32
#define VMBUS_CHAN_PRPLIST_MAX 32
struct hv_vmbus_channel;
+int vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen,
+ uint64_t *xactid);
+int vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan,
+ struct vmbus_chanpkt_hdr *pkt, int *pktlen);
+
int vmbus_chan_send(struct hv_vmbus_channel *chan, uint16_t type,
uint16_t flags, void *data, int dlen, uint64_t xactid);
int vmbus_chan_send_sglist(struct hv_vmbus_channel *chan,
Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c Wed Oct 12 02:09:53 2016 (r307080)
@@ -63,12 +63,12 @@ static int hv_nv_destroy_send_buffer(ne
static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
static int hv_nv_connect_to_vsp(struct hn_softc *sc);
static void hv_nv_on_send_completion(netvsc_dev *net_dev,
- struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt);
+ struct hv_vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt);
static void hv_nv_on_receive_completion(struct hv_vmbus_channel *chan,
uint64_t tid, uint32_t status);
static void hv_nv_on_receive(netvsc_dev *net_dev,
struct hn_softc *sc, struct hv_vmbus_channel *chan,
- hv_vm_packet_descriptor *pkt);
+ const struct vmbus_chanpkt_hdr *pkt);
/*
*
@@ -725,13 +725,12 @@ hv_nv_on_device_remove(struct hn_softc *
*/
static void
hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan,
- hv_vm_packet_descriptor *pkt)
+ const struct vmbus_chanpkt_hdr *pkt)
{
- nvsp_msg *nvsp_msg_pkt;
+ const nvsp_msg *nvsp_msg_pkt;
netvsc_packet *net_vsc_pkt;
- nvsp_msg_pkt =
- (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
+ nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete
|| nvsp_msg_pkt->hdr.msg_type
@@ -748,7 +747,7 @@ hv_nv_on_send_completion(netvsc_dev *net
nvsp_msg_1_type_send_rndis_pkt_complete) {
/* Get the send context */
net_vsc_pkt =
- (netvsc_packet *)(unsigned long)pkt->transaction_id;
+ (netvsc_packet *)(unsigned long)pkt->cph_xactid;
if (NULL != net_vsc_pkt) {
if (net_vsc_pkt->send_buf_section_idx !=
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
@@ -828,10 +827,10 @@ hv_nv_on_send(struct hv_vmbus_channel *c
*/
static void
hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc,
- struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt)
+ struct hv_vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
{
- hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
- nvsp_msg *nvsp_msg_pkt;
+ const struct vmbus_chanpkt_rxbuf *pkt;
+ const nvsp_msg *nvsp_msg_pkt;
netvsc_packet vsc_pkt;
netvsc_packet *net_vsc_pkt = &vsc_pkt;
device_t dev = sc->hn_dev;
@@ -839,43 +838,31 @@ hv_nv_on_receive(netvsc_dev *net_dev, st
int i = 0;
int status = nvsp_status_success;
- /*
- * All inbound packets other than send completion should be
- * xfer page packet.
- */
- if (pkt->type != VMBUS_CHANPKT_TYPE_RXBUF) {
- device_printf(dev, "packet type %d is invalid!\n", pkt->type);
- return;
- }
-
- nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt
- + (pkt->data_offset8 << 3));
+ nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);
/* Make sure this is a valid nvsp packet */
if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
- device_printf(dev, "packet hdr type %d is invalid!\n",
- pkt->type);
+ device_printf(dev, "packet hdr type %u is invalid!\n",
+ nvsp_msg_pkt->hdr.msg_type);
return;
}
- vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt;
+ pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
- if (vm_xfer_page_pkt->transfer_page_set_id !=
- NETVSC_RECEIVE_BUFFER_ID) {
- device_printf(dev, "transfer_page_set_id %d is invalid!\n",
- vm_xfer_page_pkt->transfer_page_set_id);
+ if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
+ device_printf(dev, "rxbuf_id %d is invalid!\n",
+ pkt->cp_rxbuf_id);
return;
}
- count = vm_xfer_page_pkt->range_count;
+ count = pkt->cp_rxbuf_cnt;
/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
for (i = 0; i < count; i++) {
net_vsc_pkt->status = nvsp_status_success;
- net_vsc_pkt->data = (void *)((unsigned long)net_dev->rx_buf +
- vm_xfer_page_pkt->ranges[i].byte_offset);
- net_vsc_pkt->tot_data_buf_len =
- vm_xfer_page_pkt->ranges[i].byte_count;
+ net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
+ pkt->cp_rxbuf[i].rb_ofs);
+ net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
hv_rf_on_receive(net_dev, chan, net_vsc_pkt);
if (net_vsc_pkt->status != nvsp_status_success) {
@@ -888,8 +875,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st
* messages (not just data messages) will trigger a response
* message back to the host.
*/
- hv_nv_on_receive_completion(chan, vm_xfer_page_pkt->d.transaction_id,
- status);
+ hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
}
/*
@@ -933,19 +919,19 @@ retry_send_cmplt:
* Net VSC receiving vRSS send table from VSP
*/
static void
-hv_nv_send_table(struct hn_softc *sc, hv_vm_packet_descriptor *pkt)
+hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
{
netvsc_dev *net_dev;
- nvsp_msg *nvsp_msg_pkt;
+ const nvsp_msg *nvsp_msg_pkt;
int i;
- uint32_t count, *table;
+ uint32_t count;
+ const uint32_t *table;
net_dev = hv_nv_get_inbound_net_device(sc);
if (!net_dev)
return;
- nvsp_msg_pkt =
- (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
+ nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
if (nvsp_msg_pkt->hdr.msg_type !=
nvsp_msg5_type_send_indirection_table) {
@@ -961,8 +947,8 @@ hv_nv_send_table(struct hn_softc *sc, hv
return;
}
- table = (uint32_t *)
- ((unsigned long)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
+ table = (const uint32_t *)
+ ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);
for (i = 0; i < count; i++)
@@ -979,44 +965,40 @@ hv_nv_on_channel_callback(void *xchan)
device_t dev = chan->ch_dev;
struct hn_softc *sc = device_get_softc(dev);
netvsc_dev *net_dev;
- uint32_t bytes_rxed;
- uint64_t request_id;
- hv_vm_packet_descriptor *desc;
- uint8_t *buffer;
+ void *buffer;
int bufferlen = NETVSC_PACKET_SIZE;
- int ret = 0;
net_dev = hv_nv_get_inbound_net_device(sc);
if (net_dev == NULL)
return;
buffer = chan->hv_chan_rdbuf;
-
do {
- ret = hv_vmbus_channel_recv_packet_raw(chan,
- buffer, bufferlen, &bytes_rxed, &request_id);
+ struct vmbus_chanpkt_hdr *pkt = buffer;
+ uint32_t bytes_rxed;
+ int ret;
+
+ bytes_rxed = bufferlen;
+ ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
if (ret == 0) {
if (bytes_rxed > 0) {
- desc = (hv_vm_packet_descriptor *)buffer;
- switch (desc->type) {
+ switch (pkt->cph_type) {
case VMBUS_CHANPKT_TYPE_COMP:
hv_nv_on_send_completion(net_dev, chan,
- desc);
+ pkt);
break;
case VMBUS_CHANPKT_TYPE_RXBUF:
- hv_nv_on_receive(net_dev, sc, chan, desc);
+ hv_nv_on_receive(net_dev, sc, chan, pkt);
break;
case VMBUS_CHANPKT_TYPE_INBAND:
- hv_nv_send_table(sc, desc);
+ hv_nv_send_table(sc, pkt);
break;
default:
device_printf(dev,
- "hv_cb recv unknow type %d "
- " packet\n", desc->type);
+ "unknown chan pkt %u\n",
+ pkt->cph_type);
break;
}
- } else {
- break;
}
} else if (ret == ENOBUFS) {
/* Handle large packet */
@@ -1035,6 +1017,9 @@ hv_nv_on_channel_callback(void *xchan)
break;
}
bufferlen = bytes_rxed;
+ } else {
+ /* No more packets */
+ break;
}
} while (1);
Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c Wed Oct 12 02:09:53 2016 (r307080)
@@ -780,12 +780,10 @@ hv_storvsc_on_channel_callback(void *xch
struct hv_storvsc_request *request;
struct vstor_packet *vstor_packet;
- ret = hv_vmbus_channel_recv_packet(
- channel,
- packet,
- roundup2(VSTOR_PKT_SIZE, 8),
- &bytes_recvd,
- &request_id);
+ bytes_recvd = roundup2(VSTOR_PKT_SIZE, 8);
+ ret = vmbus_chan_recv(channel, packet, &bytes_recvd, &request_id);
+ KASSERT(ret != ENOBUFS, ("storvsc recvbuf is not large enough"));
+ /* XXX check bytes_recvd to make sure that it contains enough data */
while ((ret == 0) && (bytes_recvd > 0)) {
request = (struct hv_storvsc_request *)(uintptr_t)request_id;
@@ -819,12 +817,16 @@ hv_storvsc_on_channel_callback(void *xch
break;
}
}
- ret = hv_vmbus_channel_recv_packet(
- channel,
- packet,
- roundup2(VSTOR_PKT_SIZE, 8),
- &bytes_recvd,
- &request_id);
+
+ bytes_recvd = roundup2(VSTOR_PKT_SIZE, 8),
+ ret = vmbus_chan_recv(channel, packet, &bytes_recvd,
+ &request_id);
+ KASSERT(ret != ENOBUFS,
+ ("storvsc recvbuf is not large enough"));
+ /*
+ * XXX check bytes_recvd to make sure that it contains
+ * enough data
+ */
}
}
Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c Wed Oct 12 02:09:53 2016 (r307080)
@@ -52,7 +52,7 @@ hv_heartbeat_cb(void *context)
{
uint8_t* buf;
hv_vmbus_channel* channel;
- uint32_t recvlen;
+ int recvlen;
uint64_t requestid;
int ret;
@@ -64,8 +64,10 @@ hv_heartbeat_cb(void *context)
buf = softc->receive_buffer;;
channel = softc->channel;
- ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE, &recvlen,
- &requestid);
+ recvlen = PAGE_SIZE;
+ ret = vmbus_chan_recv(channel, buf, &recvlen, &requestid);
+ KASSERT(ret != ENOBUFS, ("hvheartbeat recvbuf is not large enough"));
+ /* XXX check recvlen to make sure that it contains enough data */
if ((ret == 0) && recvlen > 0) {
Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Wed Oct 12 02:09:53 2016 (r307080)
@@ -626,8 +626,10 @@ hv_kvp_process_request(void *context, in
kvp_buf = sc->util_sc.receive_buffer;;
channel = sc->util_sc.channel;
- ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE,
- &recvlen, &requestid);
+ recvlen = 2 * PAGE_SIZE;
+ ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid);
+ KASSERT(ret != ENOBUFS, ("hvkvp recvbuf is not large enough"));
+ /* XXX check recvlen to make sure that it contains enough data */
while ((ret == 0) && (recvlen > 0)) {
@@ -691,9 +693,11 @@ hv_kvp_process_request(void *context, in
/*
* Try reading next buffer
*/
- recvlen = 0;
- ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE,
- &recvlen, &requestid);
+ recvlen = 2 * PAGE_SIZE;
+ ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid);
+ KASSERT(ret != ENOBUFS, ("hvkvp recvbuf is not large enough"));
+ /* XXX check recvlen to make sure that it contains enough data */
+
hv_kvp_log_info("%s: read: context %p, ret =%d, recvlen=%d\n",
__func__, context, ret, recvlen);
}
Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c Wed Oct 12 02:09:53 2016 (r307080)
@@ -67,8 +67,11 @@ hv_shutdown_cb(void *context)
softc = (hv_util_sc*)context;
buf = softc->receive_buffer;;
channel = softc->channel;
- ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE,
- &recv_len, &request_id);
+
+ recv_len = PAGE_SIZE;
+ ret = vmbus_chan_recv(channel, buf, &recv_len, &request_id);
+ KASSERT(ret != ENOBUFS, ("hvshutdown recvbuf is not large enough"));
+ /* XXX check recv_len to make sure that it contains enough data */
if ((ret == 0) && recv_len > 0) {
Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c Wed Oct 12 02:09:53 2016 (r307080)
@@ -144,8 +144,10 @@ hv_timesync_cb(void *context)
channel = softc->util_sc.channel;
time_buf = softc->util_sc.receive_buffer;
- ret = hv_vmbus_channel_recv_packet(channel, time_buf,
- PAGE_SIZE, &recvlen, &requestId);
+ recvlen = PAGE_SIZE;
+ ret = vmbus_chan_recv(channel, time_buf, &recvlen, &requestId);
+ KASSERT(ret != ENOBUFS, ("hvtimesync recvbuf is not large enough"));
+ /* XXX check recvlen to make sure that it contains enough data */
if ((ret == 0) && recvlen > 0) {
icmsghdrp = (struct hv_vmbus_icmsg_hdr *) &time_buf[
Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c Wed Oct 12 02:09:53 2016 (r307080)
@@ -736,84 +736,60 @@ vmbus_chan_send_prplist(struct hv_vmbus_
return error;
}
-/**
- * @brief Retrieve the user packet on the specified channel
- */
int
-hv_vmbus_channel_recv_packet(
- hv_vmbus_channel* channel,
- void* Buffer,
- uint32_t buffer_len,
- uint32_t* buffer_actual_len,
- uint64_t* request_id)
+vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen0,
+ uint64_t *xactid)
{
- int ret;
- uint32_t user_len;
- uint32_t packet_len;
- hv_vm_packet_descriptor desc;
-
- *buffer_actual_len = 0;
- *request_id = 0;
-
- ret = hv_ring_buffer_peek(&channel->inbound, &desc,
- sizeof(hv_vm_packet_descriptor));
- if (ret != 0)
- return (0);
+ struct vmbus_chanpkt_hdr pkt;
+ int error, dlen, hlen;
- packet_len = desc.length8 << 3;
- user_len = packet_len - (desc.data_offset8 << 3);
+ error = hv_ring_buffer_peek(&chan->inbound, &pkt, sizeof(pkt));
+ if (error)
+ return error;
- *buffer_actual_len = user_len;
+ hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen);
+ dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen;
- if (user_len > buffer_len)
- return (EINVAL);
+ if (*dlen0 < dlen) {
+ /* Return the size of this packet's data. */
+ *dlen0 = dlen;
+ return ENOBUFS;
+ }
- *request_id = desc.transaction_id;
+ *xactid = pkt.cph_xactid;
+ *dlen0 = dlen;
- /* Copy over the packet to the user buffer */
- ret = hv_ring_buffer_read(&channel->inbound, Buffer, user_len,
- (desc.data_offset8 << 3));
+ /* Skip packet header */
+ error = hv_ring_buffer_read(&chan->inbound, data, dlen, hlen);
+ KASSERT(!error, ("hv_ring_buffer_read failed"));
- return (0);
+ return 0;
}
-/**
- * @brief Retrieve the raw packet on the specified channel
- */
int
-hv_vmbus_channel_recv_packet_raw(
- hv_vmbus_channel* channel,
- void* buffer,
- uint32_t buffer_len,
- uint32_t* buffer_actual_len,
- uint64_t* request_id)
+vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan,
+ struct vmbus_chanpkt_hdr *pkt0, int *pktlen0)
{
- int ret;
- uint32_t packetLen;
- hv_vm_packet_descriptor desc;
+ struct vmbus_chanpkt_hdr pkt;
+ int error, pktlen;
- *buffer_actual_len = 0;
- *request_id = 0;
+ error = hv_ring_buffer_peek(&chan->inbound, &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 = hv_ring_buffer_read(&chan->inbound, pkt0, pktlen, 0);
+ KASSERT(!error, ("hv_ring_buffer_read failed"));
- ret = hv_ring_buffer_peek(
- &channel->inbound, &desc,
- sizeof(hv_vm_packet_descriptor));
-
- if (ret != 0)
- return (0);
-
- packetLen = desc.length8 << 3;
- *buffer_actual_len = packetLen;
-
- if (packetLen > buffer_len)
- return (ENOBUFS);
-
- *request_id = desc.transaction_id;
-
- /* Copy over the entire packet to the user buffer */
- ret = hv_ring_buffer_read(&channel->inbound, buffer, packetLen, 0);
-
- return (0);
+ return 0;
}
static void
Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Wed Oct 12 02:03:05 2016 (r307079)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h Wed Oct 12 02:09:53 2016 (r307080)
@@ -112,7 +112,6 @@ CTASSERT(sizeof(struct vmbus_mnf) == PAG
* Channel packets
*/
-#define VMBUS_CHANPKT_SIZE_SHIFT 3
#define VMBUS_CHANPKT_SIZE_ALIGN (1 << VMBUS_CHANPKT_SIZE_SHIFT)
#define VMBUS_CHANPKT_SETLEN(pktlen, len) \
@@ -123,14 +122,6 @@ do { \
#define VMBUS_CHANPKT_TOTLEN(tlen) \
roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN)
-struct vmbus_chanpkt_hdr {
- uint16_t cph_type;
- uint16_t cph_hlen; /* header len, in 8 bytes */
- uint16_t cph_tlen; /* total len, in 8 bytes */
- uint16_t cph_flags;
- uint64_t cph_xactid;
-} __packed;
-
struct vmbus_chanpkt {
struct vmbus_chanpkt_hdr cp_hdr;
} __packed;
More information about the svn-src-stable-10
mailing list