Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146170820
D7450.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
22 KB
Referenced Files
None
Subscribers
None
D7450.id.diff
View Options
Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.h
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -1112,29 +1112,8 @@
#endif
typedef struct netvsc_packet_ {
- uint8_t is_data_pkt; /* One byte */
- uint16_t vlan_tci;
- uint32_t status;
-
- /* Completion */
- union {
- struct {
- uint64_t rx_completion_tid;
- void *rx_completion_context;
- /* This is no longer used */
- pfn_on_send_rx_completion on_rx_completion;
- } rx;
- struct {
- uint64_t send_completion_tid;
- void *send_completion_context;
- /* Still used in netvsc and filter code */
- pfn_on_send_rx_completion on_send_completion;
- } send;
- } compl;
- uint32_t send_buf_section_idx;
- uint32_t send_buf_section_size;
-
- void *rndis_mesg;
+ uint16_t vlan_tci;
+ uint32_t status;
uint32_t tot_data_buf_len;
void *data;
} netvsc_packet;
@@ -1270,14 +1249,15 @@
* Externs
*/
extern int hv_promisc_mode;
+struct hn_send_ctx;
void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status);
netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc,
void *additional_info, struct hn_rx_ring *rxr);
int hv_nv_on_device_remove(struct hn_softc *sc,
boolean_t destroy_channel);
-int hv_nv_on_send(struct vmbus_channel *chan, netvsc_packet *pkt,
- struct vmbus_gpa *gpa, int gpa_cnt);
+int hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
+ struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
void hv_nv_subchan_attach(struct vmbus_channel *chan,
struct hn_rx_ring *rxr);
Index: head/sys/dev/hyperv/netvsc/hv_net_vsc.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -68,6 +68,12 @@
static void hv_nv_on_receive(netvsc_dev *net_dev,
struct hn_rx_ring *rxr, struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkt);
+static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg);
+
+static struct hn_send_ctx hn_send_ctx_none =
+ HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
/*
*
@@ -141,6 +147,7 @@
static int
hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
{
+ struct hn_send_ctx sndc;
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret = 0;
@@ -189,9 +196,10 @@
/* Send the gpadl notification request */
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
if (ret != 0) {
goto cleanup;
}
@@ -240,6 +248,7 @@
static int
hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
{
+ struct hn_send_ctx sndc;
netvsc_dev *net_dev;
nvsp_msg *init_pkt;
int ret = 0;
@@ -287,9 +296,10 @@
/* Send the gpadl notification request */
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
if (ret != 0) {
goto cleanup;
}
@@ -348,8 +358,7 @@
ret = vmbus_chan_send(net_dev->sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
- (uint64_t)(uintptr_t)revoke_pkt);
-
+ (uint64_t)(uintptr_t)&hn_send_ctx_none);
/*
* If we failed here, we might as well return and have a leak
* rather than continue and a bugchk
@@ -414,9 +423,8 @@
NETVSC_SEND_BUFFER_ID;
ret = vmbus_chan_send(net_dev->sc->hn_prichan,
- VMBUS_CHANPKT_TYPE_INBAND, 0,
- revoke_pkt, sizeof(nvsp_msg),
- (uint64_t)(uintptr_t)revoke_pkt);
+ VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
+ (uint64_t)(uintptr_t)&hn_send_ctx_none);
/*
* If we failed here, we might as well return and have a leak
* rather than continue and a bugchk
@@ -466,6 +474,7 @@
hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
uint32_t nvsp_ver)
{
+ struct hn_send_ctx sndc;
nvsp_msg *init_pkt;
int ret;
@@ -480,9 +489,10 @@
init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver;
/* Send the init request */
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
if (ret != 0)
return (-1);
@@ -524,7 +534,7 @@
/* Send the configuration packet */
ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none);
if (ret != 0)
return (-EINVAL);
@@ -602,7 +612,7 @@
/* Send the init request */
ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&hn_send_ctx_none);
if (ret != 0) {
goto cleanup;
}
@@ -731,6 +741,43 @@
return (0);
}
+void
+hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused,
+ const struct nvsp_msg_ *msg)
+{
+ /* Copy the response back */
+ memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg));
+ sema_post(&net_dev->channel_init_sema);
+}
+
+static void
+hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
+ struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
+ const struct nvsp_msg_ *msg __unused)
+{
+ /* EMPTY */
+}
+
+void
+hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx)
+{
+ u_long mask;
+ uint32_t idx;
+
+ idx = chim_idx / BITS_PER_LONG;
+ KASSERT(idx < net_dev->bitsmap_words,
+ ("invalid chimney index 0x%x", chim_idx));
+
+ mask = 1UL << (chim_idx % BITS_PER_LONG);
+ KASSERT(net_dev->send_section_bitsmap[idx] & mask,
+ ("index bitmap 0x%lx, chimney index %u, "
+ "bitmap idx %d, bitmask 0x%lx",
+ net_dev->send_section_bitsmap[idx], chim_idx, idx, mask));
+
+ atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask);
+}
+
/*
* Net VSC on send completion
*/
@@ -738,59 +785,15 @@
hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkt)
{
- const nvsp_msg *nvsp_msg_pkt;
- netvsc_packet *net_vsc_pkt;
+ struct hn_send_ctx *sndc;
- 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
- == nvsp_msg_1_type_send_rx_buf_complete
- || nvsp_msg_pkt->hdr.msg_type
- == nvsp_msg_1_type_send_send_buf_complete
- || nvsp_msg_pkt->hdr.msg_type
- == nvsp_msg5_type_subchannel) {
- /* Copy the response back */
- memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt,
- sizeof(nvsp_msg));
- sema_post(&net_dev->channel_init_sema);
- } else if (nvsp_msg_pkt->hdr.msg_type ==
- nvsp_msg_1_type_send_rndis_pkt_complete) {
- /* Get the send context */
- net_vsc_pkt =
- (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) {
- u_long mask;
- int idx;
-
- idx = net_vsc_pkt->send_buf_section_idx /
- BITS_PER_LONG;
- KASSERT(idx < net_dev->bitsmap_words,
- ("invalid section index %u",
- net_vsc_pkt->send_buf_section_idx));
- mask = 1UL <<
- (net_vsc_pkt->send_buf_section_idx %
- BITS_PER_LONG);
-
- KASSERT(net_dev->send_section_bitsmap[idx] &
- mask,
- ("index bitmap 0x%lx, section index %u, "
- "bitmap idx %d, bitmask 0x%lx",
- net_dev->send_section_bitsmap[idx],
- net_vsc_pkt->send_buf_section_idx,
- idx, mask));
- atomic_clear_long(
- &net_dev->send_section_bitsmap[idx], mask);
- }
-
- /* Notify the layer above us */
- net_vsc_pkt->compl.send.on_send_completion(chan,
- net_vsc_pkt->compl.send.send_completion_context);
-
- }
- }
+ sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
+ sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt));
+ /*
+ * NOTE:
+ * 'sndc' CAN NOT be accessed anymore, since it can be freed by
+ * its callback.
+ */
}
/*
@@ -799,14 +802,14 @@
* Returns 0 on success, non-zero on failure.
*/
int
-hv_nv_on_send(struct vmbus_channel *chan,
- netvsc_packet *pkt, struct vmbus_gpa *gpa, int gpa_cnt)
+hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
+ struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
{
nvsp_msg send_msg;
int ret;
send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
- if (pkt->is_data_pkt) {
+ if (is_data_pkt) {
/* 0 is RMC_DATA */
send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
} else {
@@ -815,17 +818,17 @@
}
send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
- pkt->send_buf_section_idx;
+ sndc->hn_chim_idx;
send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
- pkt->send_buf_section_size;
+ sndc->hn_chim_sz;
if (gpa_cnt) {
ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt,
- &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
+ &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
} else {
ret = vmbus_chan_send(chan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt);
+ &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
}
return (ret);
Index: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -166,7 +166,7 @@
struct hn_tx_ring *txr;
int refs;
uint32_t flags; /* HN_TXD_FLAG_ */
- netvsc_packet netvsc_pkt; /* XXX to be removed */
+ struct hn_send_ctx send_ctx;
bus_dmamap_t data_dmap;
@@ -781,14 +781,14 @@
}
static void
-hn_tx_done(struct vmbus_channel *chan, void *xpkt)
+hn_tx_done(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
+ struct vmbus_channel *chan, const struct nvsp_msg_ *msg __unused)
{
- netvsc_packet *packet = xpkt;
- struct hn_txdesc *txd;
+ struct hn_txdesc *txd = sndc->hn_cbarg;
struct hn_tx_ring *txr;
- txd = (struct hn_txdesc *)(uintptr_t)
- packet->compl.send.send_completion_tid;
+ if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ hn_chim_free(net_dev, sndc->hn_chim_idx);
txr = txd->txr;
KASSERT(txr->hn_chan == chan,
@@ -835,16 +835,14 @@
bus_dma_segment_t segs[HN_TX_DATA_SEGCNT_MAX];
int error, nsegs, i;
struct mbuf *m_head = *m_head0;
- netvsc_packet *packet;
rndis_msg *rndis_mesg;
rndis_packet *rndis_pkt;
rndis_per_packet_info *rppi;
struct rndis_hash_value *hash_value;
- uint32_t rndis_msg_size;
+ uint32_t rndis_msg_size, tot_data_buf_len, send_buf_section_idx;
+ int send_buf_section_size;
- packet = &txd->netvsc_pkt;
- packet->is_data_pkt = TRUE;
- packet->tot_data_buf_len = m_head->m_pkthdr.len;
+ tot_data_buf_len = m_head->m_pkthdr.len;
/*
* extension points to the area reserved for the
@@ -859,7 +857,7 @@
rndis_pkt = &rndis_mesg->msg.packet;
rndis_pkt->data_offset = sizeof(rndis_packet);
- rndis_pkt->data_length = packet->tot_data_buf_len;
+ rndis_pkt->data_length = tot_data_buf_len;
rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet);
rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
@@ -967,15 +965,14 @@
}
}
- rndis_mesg->msg_len = packet->tot_data_buf_len + rndis_msg_size;
- packet->tot_data_buf_len = rndis_mesg->msg_len;
+ rndis_mesg->msg_len = tot_data_buf_len + rndis_msg_size;
+ tot_data_buf_len = rndis_mesg->msg_len;
/*
* Chimney send, if the packet could fit into one chimney buffer.
*/
- if (packet->tot_data_buf_len < txr->hn_tx_chimney_size) {
+ if (tot_data_buf_len < txr->hn_tx_chimney_size) {
netvsc_dev *net_dev = txr->hn_sc->net_dev;
- uint32_t send_buf_section_idx;
txr->hn_tx_chimney_tried++;
send_buf_section_idx =
@@ -990,9 +987,7 @@
dest += rndis_msg_size;
m_copydata(m_head, 0, m_head->m_pkthdr.len, dest);
- packet->send_buf_section_idx = send_buf_section_idx;
- packet->send_buf_section_size =
- packet->tot_data_buf_len;
+ send_buf_section_size = tot_data_buf_len;
txr->hn_gpa_cnt = 0;
txr->hn_tx_chimney++;
goto done;
@@ -1039,16 +1034,14 @@
gpa->gpa_len = segs[i].ds_len;
}
- packet->send_buf_section_idx =
- NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
- packet->send_buf_section_size = 0;
+ send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ send_buf_section_size = 0;
done:
txd->m = m_head;
/* Set the completion routine */
- packet->compl.send.on_send_completion = hn_tx_done;
- packet->compl.send.send_completion_context = packet;
- packet->compl.send.send_completion_tid = (uint64_t)(uintptr_t)txd;
+ hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd,
+ send_buf_section_idx, send_buf_section_size);
return 0;
}
@@ -1068,7 +1061,7 @@
* Make sure that txd is not freed before ETHER_BPF_MTAP.
*/
hn_txdesc_hold(txd);
- error = hv_nv_on_send(txr->hn_chan, &txd->netvsc_pkt,
+ error = hv_nv_on_send(txr->hn_chan, true, &txd->send_ctx,
txr->hn_gpa, txr->hn_gpa_cnt);
if (!error) {
ETHER_BPF_MTAP(ifp, txd->m);
Index: head/sys/dev/hyperv/netvsc/hv_rndis_filter.h
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.h
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.h
@@ -33,6 +33,7 @@
#include <sys/param.h>
#include <net/ethernet.h>
+#include <dev/hyperv/netvsc/if_hnvar.h>
/*
* Defines
@@ -75,7 +76,7 @@
uint8_t buf_resp[PAGE_SIZE];
/* Simplify allocation by having a netvsc packet inline */
- netvsc_packet pkt;
+ struct hn_send_ctx send_ctx;
/*
* The max request size is sizeof(rndis_msg) + PAGE_SIZE.
Index: head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
===================================================================
--- head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ head/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -85,11 +85,17 @@
static int hv_rf_init_device(rndis_device *device);
static int hv_rf_open_device(rndis_device *device);
static int hv_rf_close_device(rndis_device *device);
-static void hv_rf_on_send_request_completion(struct vmbus_channel *, void *context);
-static void hv_rf_on_send_request_halt_completion(struct vmbus_channel *, void *context);
int
hv_rf_send_offload_request(struct hn_softc *sc,
rndis_offload_params *offloads);
+
+static void hn_rndis_sent_halt(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg);
+static void hn_rndis_sent_cb(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg);
+
/*
* Set the Per-Packet-Info with the specified type
*/
@@ -238,17 +244,14 @@
hv_rf_send_request(rndis_device *device, rndis_request *request,
uint32_t message_type)
{
- netvsc_packet *packet;
netvsc_dev *net_dev = device->net_dev;
- int send_buf_section_idx;
+ uint32_t send_buf_section_idx, tot_data_buf_len;
struct vmbus_gpa gpa[2];
- int gpa_cnt;
+ int gpa_cnt, send_buf_section_size;
+ hn_sent_callback_t cb;
/* Set up the packet to send it */
- packet = &request->pkt;
-
- packet->is_data_pkt = FALSE;
- packet->tot_data_buf_len = request->request_msg.msg_len;
+ tot_data_buf_len = request->request_msg.msg_len;
gpa_cnt = 1;
gpa[0].gpa_page = hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT;
@@ -265,16 +268,12 @@
gpa[1].gpa_len = request->request_msg.msg_len - gpa[0].gpa_len;
}
- packet->compl.send.send_completion_context = request; /* packet */
- if (message_type != REMOTE_NDIS_HALT_MSG) {
- packet->compl.send.on_send_completion =
- hv_rf_on_send_request_completion;
- } else {
- packet->compl.send.on_send_completion =
- hv_rf_on_send_request_halt_completion;
- }
- packet->compl.send.send_completion_tid = (unsigned long)device;
- if (packet->tot_data_buf_len < net_dev->send_section_size) {
+ if (message_type != REMOTE_NDIS_HALT_MSG)
+ cb = hn_rndis_sent_cb;
+ else
+ cb = hn_rndis_sent_halt;
+
+ if (tot_data_buf_len < net_dev->send_section_size) {
send_buf_section_idx = hv_nv_get_next_send_section(net_dev);
if (send_buf_section_idx !=
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
@@ -282,19 +281,20 @@
send_buf_section_idx * net_dev->send_section_size);
memcpy(dest, &request->request_msg, request->request_msg.msg_len);
- packet->send_buf_section_idx = send_buf_section_idx;
- packet->send_buf_section_size = packet->tot_data_buf_len;
+ send_buf_section_size = tot_data_buf_len;
gpa_cnt = 0;
goto sendit;
}
/* Failed to allocate chimney send buffer; move on */
}
- packet->send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
- packet->send_buf_section_size = 0;
+ send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ send_buf_section_size = 0;
sendit:
- return hv_nv_on_send(device->net_dev->sc->hn_prichan, packet,
- gpa, gpa_cnt);
+ hn_send_ctx_init(&request->send_ctx, cb, request,
+ send_buf_section_idx, send_buf_section_size);
+ return hv_nv_on_send(device->net_dev->sc->hn_prichan, false,
+ &request->send_ctx, gpa, gpa_cnt);
}
/*
@@ -1056,6 +1056,7 @@
hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
int nchan, struct hn_rx_ring *rxr)
{
+ struct hn_send_ctx sndc;
int ret;
netvsc_dev *net_dev;
rndis_device *rndis_dev;
@@ -1162,9 +1163,10 @@
init_pkt->msgs.vers_5_msgs.subchannel_request.num_subchannels =
net_dev->num_channel - 1;
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
- init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt);
+ init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
if (ret != 0) {
device_printf(dev, "Fail to allocate subchannel\n");
goto out;
@@ -1235,23 +1237,22 @@
return (hv_rf_close_device((rndis_device *)net_dev->extension));
}
-/*
- * RNDIS filter on send request completion callback
- */
-static void
-hv_rf_on_send_request_completion(struct vmbus_channel *chan __unused,
- void *context __unused)
+static void
+hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
+ struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused)
{
+ if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ hn_chim_free(net_dev, sndc->hn_chim_idx);
}
-/*
- * RNDIS filter on send request (halt only) completion callback
- */
-static void
-hv_rf_on_send_request_halt_completion(struct vmbus_channel *chan __unused,
- void *context)
+static void
+hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
+ struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused)
{
- rndis_request *request = context;
+ rndis_request *request = sndc->hn_cbarg;
+
+ if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
+ hn_chim_free(net_dev, sndc->hn_chim_idx);
/*
* Notify hv_rf_halt_device() about halt completion.
Index: head/sys/dev/hyperv/netvsc/if_hnvar.h
===================================================================
--- head/sys/dev/hyperv/netvsc/if_hnvar.h
+++ head/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2016 Microsoft Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _IF_HNVAR_H_
+#define _IF_HNVAR_H_
+
+#include <sys/param.h>
+#include <dev/hyperv/netvsc/hv_net_vsc.h>
+
+struct netvsc_dev_;
+struct nvsp_msg_;
+
+struct vmbus_channel;
+struct hn_send_ctx;
+
+typedef void (*hn_sent_callback_t)
+ (struct hn_send_ctx *, struct netvsc_dev_ *,
+ struct vmbus_channel *, const struct nvsp_msg_ *);
+
+struct hn_send_ctx {
+ hn_sent_callback_t hn_cb;
+ void *hn_cbarg;
+ uint32_t hn_chim_idx;
+ int hn_chim_sz;
+};
+
+#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
+{ \
+ .hn_cb = cb, \
+ .hn_cbarg = cbarg, \
+ .hn_chim_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, \
+ .hn_chim_sz = 0 \
+}
+
+static __inline void
+hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
+ void *cbarg, uint32_t chim_idx, int chim_sz)
+{
+ sndc->hn_cb = cb;
+ sndc->hn_cbarg = cbarg;
+ sndc->hn_chim_idx = chim_idx;
+ sndc->hn_chim_sz = chim_sz;
+}
+
+static __inline void
+hn_send_ctx_init_simple(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
+ void *cbarg)
+{
+ hn_send_ctx_init(sndc, cb, cbarg,
+ NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, 0);
+}
+
+void hn_nvs_sent_wakeup(struct hn_send_ctx *sndc,
+ struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
+ const struct nvsp_msg_ *msg);
+void hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx);
+
+#endif /* !_IF_HNVAR_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 1, 10:35 AM (20 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29109835
Default Alt Text
D7450.id.diff (22 KB)
Attached To
Mode
D7450: hyperv/hn: Reorganize send done callback.
Attached
Detach File
Event Timeline
Log In to Comment