summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/netvsc/hn_nvs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/hyperv/netvsc/hn_nvs.c')
-rw-r--r--sys/dev/hyperv/netvsc/hn_nvs.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/sys/dev/hyperv/netvsc/hn_nvs.c b/sys/dev/hyperv/netvsc/hn_nvs.c
index 4a44340..3110b02 100644
--- a/sys/dev/hyperv/netvsc/hn_nvs.c
+++ b/sys/dev/hyperv/netvsc/hn_nvs.c
@@ -62,8 +62,8 @@ __FBSDID("$FreeBSD$");
static int hn_nvs_conn_chim(struct hn_softc *);
static int hn_nvs_conn_rxbuf(struct hn_softc *);
-static int hn_nvs_disconn_chim(struct hn_softc *);
-static int hn_nvs_disconn_rxbuf(struct hn_softc *);
+static void hn_nvs_disconn_chim(struct hn_softc *);
+static void hn_nvs_disconn_rxbuf(struct hn_softc *);
static int hn_nvs_conf_ndis(struct hn_softc *, int);
static int hn_nvs_init_ndis(struct hn_softc *);
static int hn_nvs_doinit(struct hn_softc *, uint32_t);
@@ -109,10 +109,8 @@ hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
vmbus_xact_deactivate(xact);
return (NULL);
}
- if (HN_CAN_SLEEP(sc))
- hdr = vmbus_xact_wait(xact, &resplen);
- else
- hdr = vmbus_xact_busywait(xact, &resplen);
+ hdr = vmbus_chan_xact_wait(sc->hn_prichan, xact, &resplen,
+ HN_CAN_SLEEP(sc));
/*
* Check this NVS response message.
@@ -275,8 +273,14 @@ hn_nvs_conn_chim(struct hn_softc *sc)
goto cleanup;
}
if (sectsz == 0) {
+ /*
+ * Can't use chimney sending buffer; done!
+ */
if_printf(sc->hn_ifp, "zero chimney sending buffer "
"section size\n");
+ sc->hn_chim_szmax = 0;
+ sc->hn_chim_cnt = 0;
+ sc->hn_flags |= HN_FLAG_CHIM_CONNECTED;
return (0);
}
@@ -310,7 +314,7 @@ cleanup:
return (error);
}
-static int
+static void
hn_nvs_disconn_rxbuf(struct hn_softc *sc)
{
int error;
@@ -330,7 +334,12 @@ hn_nvs_disconn_rxbuf(struct hn_softc *sc)
if (error) {
if_printf(sc->hn_ifp,
"send nvs rxbuf disconn failed: %d\n", error);
- return (error);
+ /*
+ * Fine for a revoked channel, since the hypervisor
+ * does not drain TX bufring for a revoked channel.
+ */
+ if (!vmbus_chan_is_revoked(sc->hn_prichan))
+ sc->hn_flags |= HN_FLAG_RXBUF_REF;
}
sc->hn_flags &= ~HN_FLAG_RXBUF_CONNECTED;
@@ -359,14 +368,13 @@ hn_nvs_disconn_rxbuf(struct hn_softc *sc)
if (error) {
if_printf(sc->hn_ifp,
"rxbuf gpadl disconn failed: %d\n", error);
- return (error);
+ sc->hn_flags |= HN_FLAG_RXBUF_REF;
}
sc->hn_rxbuf_gpadl = 0;
}
- return (0);
}
-static int
+static void
hn_nvs_disconn_chim(struct hn_softc *sc)
{
int error;
@@ -386,7 +394,12 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
if (error) {
if_printf(sc->hn_ifp,
"send nvs chim disconn failed: %d\n", error);
- return (error);
+ /*
+ * Fine for a revoked channel, since the hypervisor
+ * does not drain TX bufring for a revoked channel.
+ */
+ if (!vmbus_chan_is_revoked(sc->hn_prichan))
+ sc->hn_flags |= HN_FLAG_CHIM_REF;
}
sc->hn_flags &= ~HN_FLAG_CHIM_CONNECTED;
@@ -416,7 +429,7 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
if (error) {
if_printf(sc->hn_ifp,
"chim gpadl disconn failed: %d\n", error);
- return (error);
+ sc->hn_flags |= HN_FLAG_CHIM_REF;
}
sc->hn_chim_gpadl = 0;
}
@@ -424,8 +437,8 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
if (sc->hn_chim_bmap != NULL) {
free(sc->hn_chim_bmap, M_DEVBUF);
sc->hn_chim_bmap = NULL;
+ sc->hn_chim_bmap_cnt = 0;
}
- return (0);
}
static int
@@ -614,8 +627,10 @@ hn_nvs_attach(struct hn_softc *sc, int mtu)
* Connect chimney sending buffer.
*/
error = hn_nvs_conn_chim(sc);
- if (error)
+ if (error) {
+ hn_nvs_disconn_rxbuf(sc);
return (error);
+ }
return (0);
}
OpenPOWER on IntegriCloud