aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSepherosa Ziehau <sephe@FreeBSD.org>2016-08-22 07:51:46 +0000
committerSepherosa Ziehau <sephe@FreeBSD.org>2016-08-22 07:51:46 +0000
commit8f556f25982ae84cf5130fab07626a76119d93b0 (patch)
treed90e5ef11ffa81e76a104a384cdd77972aaad4e4
parentef56e63fb329544ab53a1d48d6cecc8671d87515 (diff)
downloadsrc-8f556f25982ae84cf5130fab07626a76119d93b0.tar.gz
src-8f556f25982ae84cf5130fab07626a76119d93b0.zip
hyperv/hn: Factor out function to execute NVS transactions.
MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D7577
Notes
Notes: svn path=/head/; revision=304594
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c91
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis_filter.c24
-rw-r--r--sys/dev/hyperv/netvsc/if_hnvar.h8
3 files changed, 55 insertions, 68 deletions
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index f5741d671e5a..251be6a7e03e 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -74,6 +74,8 @@ static void hv_nv_on_receive(struct hn_softc *sc,
static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
struct hn_softc *, struct vmbus_channel *chan,
const void *, int);
+static void hn_nvs_sent_xact(struct hn_send_ctx *, struct hn_softc *sc,
+ struct vmbus_channel *, const void *, int);
static struct hn_send_ctx hn_send_ctx_none =
HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
@@ -105,6 +107,25 @@ hn_chim_alloc(struct hn_softc *sc)
return (ret);
}
+const void *
+hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
+ void *req, int reqlen, size_t *resp_len)
+{
+ struct hn_send_ctx sndc;
+ int error;
+
+ hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, 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 (vmbus_xact_wait(xact, resp_len));
+}
+
/*
* Net VSC initialize receive buffer with net VSP
*
@@ -114,11 +135,10 @@ hn_chim_alloc(struct hn_softc *sc)
static int
hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc, int rxbuf_size)
{
- struct vmbus_xact *xact;
+ struct vmbus_xact *xact = NULL;
struct hn_nvs_rxbuf_conn *conn;
const struct hn_nvs_rxbuf_connresp *resp;
size_t resp_len;
- struct hn_send_ctx sndc;
uint32_t status;
int error;
@@ -150,43 +170,33 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc, int rxbuf_size)
error = ENXIO;
goto cleanup;
}
-
conn = vmbus_xact_req_data(xact);
conn->nvs_type = HN_NVS_TYPE_RXBUF_CONN;
conn->nvs_gpadl = sc->hn_rxbuf_gpadl;
conn->nvs_sig = HN_NVS_RXBUF_SIG;
- hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
- vmbus_xact_activate(xact);
-
- error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
- conn, sizeof(*conn), &sndc);
- if (error != 0) {
- if_printf(sc->hn_ifp, "send nvs rxbuf conn failed: %d\n",
- error);
- vmbus_xact_deactivate(xact);
- vmbus_xact_put(xact);
+ resp = hn_nvs_xact_execute(sc, xact, conn, sizeof(*conn), &resp_len);
+ if (resp == NULL) {
+ if_printf(sc->hn_ifp, "exec rxbuf conn failed\n");
+ error = EIO;
goto cleanup;
}
-
- resp = vmbus_xact_wait(xact, &resp_len);
if (resp_len < sizeof(*resp)) {
if_printf(sc->hn_ifp, "invalid rxbuf conn resp length %zu\n",
resp_len);
- vmbus_xact_put(xact);
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);
- vmbus_xact_put(xact);
error = EINVAL;
goto cleanup;
}
status = resp->nvs_status;
vmbus_xact_put(xact);
+ xact = NULL;
if (status != HN_NVS_STATUS_OK) {
if_printf(sc->hn_ifp, "rxbuf conn failed: %x\n", status);
@@ -198,6 +208,8 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc, int rxbuf_size)
return (0);
cleanup:
+ if (xact != NULL)
+ vmbus_xact_put(xact);
hv_nv_destroy_rx_buffer(sc);
return (error);
}
@@ -208,8 +220,7 @@ cleanup:
static int
hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
{
- struct hn_send_ctx sndc;
- struct vmbus_xact *xact;
+ struct vmbus_xact *xact = NULL;
struct hn_nvs_chim_conn *chim;
const struct hn_nvs_chim_connresp *resp;
size_t resp_len;
@@ -242,37 +253,26 @@ hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
error = ENXIO;
goto cleanup;
}
-
chim = vmbus_xact_req_data(xact);
chim->nvs_type = HN_NVS_TYPE_CHIM_CONN;
chim->nvs_gpadl = sc->hn_chim_gpadl;
chim->nvs_sig = HN_NVS_CHIM_SIG;
- hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
- vmbus_xact_activate(xact);
-
- error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
- chim, sizeof(*chim), &sndc);
- if (error) {
- if_printf(sc->hn_ifp, "send nvs chim conn failed: %d\n",
- error);
- vmbus_xact_deactivate(xact);
- vmbus_xact_put(xact);
+ resp = hn_nvs_xact_execute(sc, xact, chim, sizeof(*chim), &resp_len);
+ if (resp == NULL) {
+ if_printf(sc->hn_ifp, "exec chim conn failed\n");
+ error = EIO;
goto cleanup;
}
-
- resp = vmbus_xact_wait(xact, &resp_len);
if (resp_len < sizeof(*resp)) {
if_printf(sc->hn_ifp, "invalid chim conn resp length %zu\n",
resp_len);
- vmbus_xact_put(xact);
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);
- vmbus_xact_put(xact);
error = EINVAL;
goto cleanup;
}
@@ -280,6 +280,7 @@ hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
status = resp->nvs_status;
sectsz = resp->nvs_sectsz;
vmbus_xact_put(xact);
+ xact = NULL;
if (status != HN_NVS_STATUS_OK) {
if_printf(sc->hn_ifp, "chim conn failed: %x\n", status);
@@ -316,6 +317,8 @@ hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
return 0;
cleanup:
+ if (xact != NULL)
+ vmbus_xact_put(xact);
hv_nv_destroy_send_buffer(sc);
return (error);
}
@@ -419,38 +422,28 @@ hv_nv_destroy_send_buffer(struct hn_softc *sc)
static int
hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, uint32_t nvs_ver)
{
- struct hn_send_ctx sndc;
struct vmbus_xact *xact;
struct hn_nvs_init *init;
const struct hn_nvs_init_resp *resp;
size_t resp_len;
uint32_t status;
- int error;
xact = vmbus_xact_get(sc->hn_xact, sizeof(*init));
if (xact == NULL) {
if_printf(sc->hn_ifp, "no xact for nvs init\n");
return (ENXIO);
}
-
init = vmbus_xact_req_data(xact);
init->nvs_type = HN_NVS_TYPE_INIT;
init->nvs_ver_min = nvs_ver;
init->nvs_ver_max = nvs_ver;
- vmbus_xact_activate(xact);
- hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
-
- error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
- init, sizeof(*init), &sndc);
- if (error) {
- if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error);
- vmbus_xact_deactivate(xact);
+ resp = hn_nvs_xact_execute(sc, xact, init, sizeof(*init), &resp_len);
+ if (resp == NULL) {
+ if_printf(sc->hn_ifp, "exec init failed\n");
vmbus_xact_put(xact);
- return (error);
+ return (EIO);
}
-
- resp = vmbus_xact_wait(xact, &resp_len);
if (resp_len < sizeof(*resp)) {
if_printf(sc->hn_ifp, "invalid init resp length %zu\n",
resp_len);
@@ -655,7 +648,7 @@ hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
return (0);
}
-void
+static void
hn_nvs_sent_xact(struct hn_send_ctx *sndc,
struct hn_softc *sc __unused, struct vmbus_channel *chan __unused,
const void *data, int dlen)
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
index 9267508356b3..ac6f2aaf0053 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -1030,7 +1030,6 @@ int
hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
int *nchan0, struct hn_rx_ring *rxr)
{
- struct hn_send_ctx sndc;
int ret;
rndis_device *rndis_dev;
rndis_offload_params offloads;
@@ -1041,7 +1040,7 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
struct hn_nvs_subch_req *req;
const struct hn_nvs_subch_resp *resp;
size_t resp_len;
- struct vmbus_xact *xact;
+ struct vmbus_xact *xact = NULL;
uint32_t status, nsubch;
int nchan = *nchan0;
@@ -1136,36 +1135,26 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
ret = ENXIO;
goto out;
}
-
req = vmbus_xact_req_data(xact);
req->nvs_type = HN_NVS_TYPE_SUBCH_REQ;
req->nvs_op = HN_NVS_SUBCH_OP_ALLOC;
req->nvs_nsubch = nchan - 1;
- hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
- vmbus_xact_activate(xact);
-
- ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
- req, sizeof(*req), &sndc);
- if (ret != 0) {
- if_printf(sc->hn_ifp, "send nvs subch req failed: %d\n", ret);
- vmbus_xact_deactivate(xact);
- vmbus_xact_put(xact);
+ resp = hn_nvs_xact_execute(sc, xact, req, sizeof(*req), &resp_len);
+ if (resp == NULL) {
+ if_printf(sc->hn_ifp, "exec subch failed\n");
+ ret = EIO;
goto out;
}
-
- resp = vmbus_xact_wait(xact, &resp_len);
if (resp_len < sizeof(*resp)) {
if_printf(sc->hn_ifp, "invalid subch resp length %zu\n",
resp_len);
- vmbus_xact_put(xact);
ret = EINVAL;
goto out;
}
if (resp->nvs_type != HN_NVS_TYPE_SUBCH_RESP) {
if_printf(sc->hn_ifp, "not subch resp, type %u\n",
resp->nvs_type);
- vmbus_xact_put(xact);
ret = EINVAL;
goto out;
}
@@ -1173,6 +1162,7 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
status = resp->nvs_status;
nsubch = resp->nvs_nsubch;
vmbus_xact_put(xact);
+ xact = NULL;
if (status != HN_NVS_STATUS_OK) {
if_printf(sc->hn_ifp, "subch req failed: %x\n", status);
@@ -1189,6 +1179,8 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
ret = hv_rf_set_rss_param(rndis_dev, nchan);
*nchan0 = nchan;
out:
+ if (xact != NULL)
+ vmbus_xact_put(xact);
return (ret);
}
diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h
index 8a5ebd619144..82dbaaeb1507 100644
--- a/sys/dev/hyperv/netvsc/if_hnvar.h
+++ b/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -107,9 +107,11 @@ hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen,
(uint64_t)(uintptr_t)sndc));
}
-void hn_nvs_sent_xact(struct hn_send_ctx *sndc,
- struct hn_softc *sc, struct vmbus_channel *chan,
- const void *data, int dlen);
+struct vmbus_xact;
+
+const void *hn_nvs_xact_execute(struct hn_softc *sc,
+ struct vmbus_xact *xact, void *req, int reqlen,
+ size_t *resp_len);
uint32_t hn_chim_alloc(struct hn_softc *sc);
void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);