/* Support for VERSION_WIN7 is removed. #define is retained for reference. */ #define SYNTHVID_VERSION_WIN7 SYNTHVID_VERSION(3, 0) #define SYNTHVID_VERSION_WIN8 SYNTHVID_VERSION(3, 2) #define SYNTHVID_VERSION_WIN10 SYNTHVID_VERSION(3, 5)
t = wait_for_completion_timeout(&hv->wait, VMBUS_VSP_TIMEOUT); if (!t) {
drm_err(dev, "Time out on waiting vram location ack\n"); return -ETIMEDOUT;
} if (msg->vram_ack.user_ctx != vram_pp) {
drm_err(dev, "Unable to set VRAM location\n"); return -ENODEV;
}
/* * Hyper-V supports a hardware cursor feature. It's not used by Linux VM, * but the Hyper-V host still draws a point as an extra mouse pointer, * which is unwanted, especially when Xorg is running. * * The hyperv_fb driver uses synthvid_send_ptr() to hide the unwanted * pointer, by setting msg.ptr_pos.is_visible = 1 and setting the * msg.ptr_shape.data. Note: setting msg.ptr_pos.is_visible to 0 doesn't * work in tests. * * Copy synthvid_send_ptr() to hyperv_drm and rename it to * hyperv_hide_hw_ptr(). Note: hyperv_hide_hw_ptr() is also called in the * handler of the SYNTHVID_FEATURE_CHANGE event, otherwise the host still * draws an extra unwanted mouse pointer after the VM Connection window is * closed and reopened.
*/ int hyperv_hide_hw_ptr(struct hv_device *hdev)
{ struct synthvid_msg msg;
t = wait_for_completion_timeout(&hv->wait, VMBUS_VSP_TIMEOUT); if (!t) {
drm_err(dev, "Time out on waiting resolution response\n"); return -ETIMEDOUT;
}
if (msg->resolution_resp.resolution_count == 0) {
drm_err(dev, "No supported resolutions\n"); return -ENODEV;
}
index = msg->resolution_resp.default_resolution_index; if (index >= msg->resolution_resp.resolution_count) {
drm_err(dev, "Invalid resolution index: %d\n", index); return -ENODEV;
}
for (i = 0; i < msg->resolution_resp.resolution_count; i++) {
hv->screen_width_max = max_t(u32, hv->screen_width_max,
msg->resolution_resp.supported_resolution[i].width);
hv->screen_height_max = max_t(u32, hv->screen_height_max,
msg->resolution_resp.supported_resolution[i].height);
}
do {
ret = vmbus_recvpacket(hdev->channel, recv_buf,
VMBUS_MAX_PACKET_SIZE,
&bytes_recvd, &req_id); if (bytes_recvd > 0 &&
recv_buf->pipe_hdr.type == PIPE_MSG_DATA)
hyperv_receive_sub(hdev);
} while (bytes_recvd > 0 && ret == 0);
}
int hyperv_connect_vsp(struct hv_device *hdev)
{ struct hyperv_drm_device *hv = hv_get_drvdata(hdev); struct drm_device *dev = &hv->dev; int ret;
ret = vmbus_open(hdev->channel, VMBUS_RING_BUFSIZE, VMBUS_RING_BUFSIZE,
NULL, 0, hyperv_receive, hdev); if (ret) {
drm_err(dev, "Unable to open vmbus channel\n"); return ret;
}
/* Negotiate the protocol version with host */ switch (vmbus_proto_version) { case VERSION_WIN10: case VERSION_WIN10_V5:
ret = hyperv_negotiate_version(hdev, SYNTHVID_VERSION_WIN10); if (!ret) break;
fallthrough; case VERSION_WIN8: case VERSION_WIN8_1:
ret = hyperv_negotiate_version(hdev, SYNTHVID_VERSION_WIN8); break; default:
ret = hyperv_negotiate_version(hdev, SYNTHVID_VERSION_WIN10); break;
}
if (ret) {
drm_err(dev, "Synthetic video device version not accepted %d\n", ret); goto error;
}
hv->screen_depth = SYNTHVID_DEPTH_WIN8;
if (hyperv_version_ge(hv->synthvid_version, SYNTHVID_VERSION_WIN10)) {
ret = hyperv_get_supported_resolution(hdev); if (ret)
drm_err(dev, "Failed to get supported resolution from host, use default\n");
} else {
hv->screen_width_max = SYNTHVID_WIDTH_WIN8;
hv->screen_height_max = SYNTHVID_HEIGHT_WIN8;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.