Ejemplo n.º 1
0
static const void *
hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen,
    struct hn_nvs_sendctx *sndc, size_t *comp_len)
{
	struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT];
	int gpa_cnt, error;
	bus_addr_t paddr;

	KASSERT(reqlen <= HN_XACT_REQ_SIZE && reqlen > 0,
	    ("invalid request length %zu", reqlen));

	/*
	 * Setup the SG list.
	 */
	paddr = vmbus_xact_req_paddr(xact);
	KASSERT((paddr & PAGE_MASK) == 0,
	    ("vmbus xact request is not page aligned 0x%jx", (uintmax_t)paddr));
	for (gpa_cnt = 0; gpa_cnt < HN_XACT_REQ_PGCNT; ++gpa_cnt) {
		int len = PAGE_SIZE;

		if (reqlen == 0)
			break;
		if (reqlen < len)
			len = reqlen;

		gpa[gpa_cnt].gpa_page = atop(paddr) + gpa_cnt;
		gpa[gpa_cnt].gpa_len = len;
		gpa[gpa_cnt].gpa_ofs = 0;

		reqlen -= len;
	}
	KASSERT(reqlen == 0, ("still have %zu request data left", reqlen));

	/*
	 * Send this RNDIS control message and wait for its completion
	 * message.
	 */
	vmbus_xact_activate(xact);
	error = hn_nvs_send_rndis_ctrl(sc->hn_prichan, sndc, gpa, gpa_cnt);
	if (error) {
		vmbus_xact_deactivate(xact);
		if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error);
		return (NULL);
	}
	return (vmbus_chan_xact_wait(sc->hn_prichan, xact, comp_len,
	    HN_CAN_SLEEP(sc)));
}
Ejemplo n.º 2
0
static const void *
hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
    void *req, int reqlen, size_t *resplen0, uint32_t type)
{
	struct hn_nvs_sendctx 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_nvs_sendctx_init(&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);
	}
	if (HN_CAN_SLEEP(sc))
		hdr = vmbus_xact_wait(xact, &resplen);
	else
		hdr = vmbus_xact_busywait(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);
}