in hv_balloon.c [1404:1463]
static void version_resp(struct hv_dynmem_device *dm,
struct dm_version_response *vresp)
{
struct dm_version_request version_req;
int ret;
if (vresp->is_accepted) {
/*
* We are done; wakeup the
* context waiting for version
* negotiation.
*/
complete(&dm->host_event);
return;
}
/*
* If there are more versions to try, continue
* with negotiations; if not
* shutdown the service since we are not able
* to negotiate a suitable version number
* with the host.
*/
if (dm->next_version == 0)
goto version_error;
memset(&version_req, 0, sizeof(struct dm_version_request));
version_req.hdr.type = DM_VERSION_REQUEST;
version_req.hdr.size = sizeof(struct dm_version_request);
version_req.hdr.trans_id = atomic_inc_return(&trans_id);
version_req.version.version = dm->next_version;
dm->version = version_req.version.version;
/*
* Set the next version to try in case current version fails.
* Win7 protocol ought to be the last one to try.
*/
switch (version_req.version.version) {
case DYNMEM_PROTOCOL_VERSION_WIN8:
dm->next_version = DYNMEM_PROTOCOL_VERSION_WIN7;
version_req.is_last_attempt = 0;
break;
default:
dm->next_version = 0;
version_req.is_last_attempt = 1;
}
ret = vmbus_sendpacket(dm->dev->channel, &version_req,
sizeof(struct dm_version_request),
(unsigned long)NULL,
VM_PKT_DATA_INBAND, 0);
if (ret)
goto version_error;
return;
version_error:
dm->state = DM_INIT_ERROR;
complete(&dm->host_event);
}