summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/netvsc/hv_net_vsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/hyperv/netvsc/hv_net_vsc.c')
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c82
1 files changed, 38 insertions, 44 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index 9518824..66e45b6 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -107,21 +107,45 @@ hn_chim_alloc(struct hn_softc *sc)
const void *
hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
- void *req, int reqlen, size_t *resp_len)
+ void *req, int reqlen, size_t *resplen0, uint32_t type)
{
struct hn_send_ctx sndc;
+ size_t resplen, min_resplen = *resplen0;
+ const struct hn_nvs_hdr *hdr;
int error;
+ KASSERT(min_resplen >= sizeof(*hdr),
+ ("invalid minimum response len %zu", min_resplen));
+
+ /*
+ * Execute the xact setup by the caller.
+ */
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
- vmbus_xact_activate(xact);
+ vmbus_xact_activate(xact);
error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
req, reqlen, &sndc);
if (error) {
vmbus_xact_deactivate(xact);
- return NULL;
+ return (NULL);
}
- return (vmbus_xact_wait(xact, resp_len));
+ hdr = vmbus_xact_wait(xact, &resplen);
+
+ /*
+ * Check this NVS response message.
+ */
+ if (resplen < min_resplen) {
+ if_printf(sc->hn_ifp, "invalid NVS resp len %zu\n", resplen);
+ return (NULL);
+ }
+ if (hdr->nvs_type != type) {
+ if_printf(sc->hn_ifp, "unexpected NVS resp 0x%08x, "
+ "expect 0x%08x\n", hdr->nvs_type, type);
+ return (NULL);
+ }
+ /* All pass! */
+ *resplen0 = resplen;
+ return (hdr);
}
static __inline int
@@ -181,24 +205,14 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc, int rxbuf_size)
conn->nvs_gpadl = sc->hn_rxbuf_gpadl;
conn->nvs_sig = HN_NVS_RXBUF_SIG;
- resp = hn_nvs_xact_execute(sc, xact, conn, sizeof(*conn), &resp_len);
+ resp_len = sizeof(*resp);
+ resp = hn_nvs_xact_execute(sc, xact, conn, sizeof(*conn), &resp_len,
+ HN_NVS_TYPE_RXBUF_CONNRESP);
if (resp == NULL) {
if_printf(sc->hn_ifp, "exec rxbuf conn failed\n");
error = EIO;
goto cleanup;
}
- if (resp_len < sizeof(*resp)) {
- if_printf(sc->hn_ifp, "invalid rxbuf conn resp length %zu\n",
- resp_len);
- error = EINVAL;
- goto cleanup;
- }
- if (resp->nvs_type != HN_NVS_TYPE_RXBUF_CONNRESP) {
- if_printf(sc->hn_ifp, "not rxbuf conn resp, type %u\n",
- resp->nvs_type);
- error = EINVAL;
- goto cleanup;
- }
status = resp->nvs_status;
vmbus_xact_put(xact);
@@ -264,24 +278,14 @@ hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
chim->nvs_gpadl = sc->hn_chim_gpadl;
chim->nvs_sig = HN_NVS_CHIM_SIG;
- resp = hn_nvs_xact_execute(sc, xact, chim, sizeof(*chim), &resp_len);
+ resp_len = sizeof(*resp);
+ resp = hn_nvs_xact_execute(sc, xact, chim, sizeof(*chim), &resp_len,
+ HN_NVS_TYPE_CHIM_CONNRESP);
if (resp == NULL) {
if_printf(sc->hn_ifp, "exec chim conn failed\n");
error = EIO;
goto cleanup;
}
- if (resp_len < sizeof(*resp)) {
- if_printf(sc->hn_ifp, "invalid chim conn resp length %zu\n",
- resp_len);
- error = EINVAL;
- goto cleanup;
- }
- if (resp->nvs_type != HN_NVS_TYPE_CHIM_CONNRESP) {
- if_printf(sc->hn_ifp, "not chim conn resp, type %u\n",
- resp->nvs_type);
- error = EINVAL;
- goto cleanup;
- }
status = resp->nvs_status;
sectsz = resp->nvs_sectsz;
@@ -442,24 +446,14 @@ hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, uint32_t nvs_ver)
init->nvs_ver_min = nvs_ver;
init->nvs_ver_max = nvs_ver;
- resp = hn_nvs_xact_execute(sc, xact, init, sizeof(*init), &resp_len);
+ resp_len = sizeof(*resp);
+ resp = hn_nvs_xact_execute(sc, xact, init, sizeof(*init), &resp_len,
+ HN_NVS_TYPE_INIT_RESP);
if (resp == NULL) {
if_printf(sc->hn_ifp, "exec init failed\n");
vmbus_xact_put(xact);
return (EIO);
}
- if (resp_len < sizeof(*resp)) {
- if_printf(sc->hn_ifp, "invalid init resp length %zu\n",
- resp_len);
- vmbus_xact_put(xact);
- return (EINVAL);
- }
- if (resp->nvs_type != HN_NVS_TYPE_INIT_RESP) {
- if_printf(sc->hn_ifp, "not init resp, type %u\n",
- resp->nvs_type);
- vmbus_xact_put(xact);
- return (EINVAL);
- }
status = resp->nvs_status;
vmbus_xact_put(xact);
@@ -641,7 +635,7 @@ cleanup:
* Net VSC on device remove
*/
int
-hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
+hv_nv_on_device_remove(struct hn_softc *sc)
{
hv_nv_disconnect_from_vsp(sc);
OpenPOWER on IntegriCloud