diff options
Diffstat (limited to 'sys/dev/hyperv/netvsc/hn_nvs.c')
-rw-r--r-- | sys/dev/hyperv/netvsc/hn_nvs.c | 45 |
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); } |