aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/virtio/gpu/virtio_gpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/virtio/gpu/virtio_gpu.c')
-rw-r--r--sys/dev/virtio/gpu/virtio_gpu.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/sys/dev/virtio/gpu/virtio_gpu.c b/sys/dev/virtio/gpu/virtio_gpu.c
index 668eb170304a..b95bae9fe286 100644
--- a/sys/dev/virtio/gpu/virtio_gpu.c
+++ b/sys/dev/virtio/gpu/virtio_gpu.c
@@ -445,21 +445,33 @@ vtgpu_alloc_virtqueue(struct vtgpu_softc *sc)
}
static int
-vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen,
- void *resp, size_t resplen)
+vtgpu_req_resp2(struct vtgpu_softc *sc, void *req1, size_t req1len,
+ void *req2, size_t req2len, void *resp, size_t resplen)
{
struct sglist sg;
- struct sglist_seg segs[2];
- int error;
+ struct sglist_seg segs[3];
+ int error, rcount;
- sglist_init(&sg, 2, segs);
+ sglist_init(&sg, 3, segs);
- error = sglist_append(&sg, req, reqlen);
+ rcount = 1;
+ error = sglist_append(&sg, req1, req1len);
if (error != 0) {
device_printf(sc->vtgpu_dev,
- "Unable to append the request to the sglist: %d\n", error);
+ "Unable to append the request to the sglist: %d\n",
+ error);
return (error);
}
+ if (req2 != NULL) {
+ error = sglist_append(&sg, req2, req2len);
+ if (error != 0) {
+ device_printf(sc->vtgpu_dev,
+ "Unable to append the request to the sglist: %d\n",
+ error);
+ return (error);
+ }
+ rcount++;
+ }
error = sglist_append(&sg, resp, resplen);
if (error != 0) {
device_printf(sc->vtgpu_dev,
@@ -467,7 +479,7 @@ vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen,
error);
return (error);
}
- error = virtqueue_enqueue(sc->vtgpu_ctrl_vq, resp, &sg, 1, 1);
+ error = virtqueue_enqueue(sc->vtgpu_ctrl_vq, resp, &sg, rcount, 1);
if (error != 0) {
device_printf(sc->vtgpu_dev, "Enqueue failed: %d\n", error);
return (error);
@@ -480,6 +492,13 @@ vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen,
}
static int
+vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen,
+ void *resp, size_t resplen)
+{
+ return (vtgpu_req_resp2(sc, req, reqlen, NULL, 0, resp, resplen));
+}
+
+static int
vtgpu_get_display_info(struct vtgpu_softc *sc)
{
struct {
@@ -559,9 +578,15 @@ static int
vtgpu_attach_backing(struct vtgpu_softc *sc)
{
struct {
+ /*
+ * Split the backing and mem request arguments as some
+ * hypervisors, e.g. Parallels Desktop, don't work when
+ * they are enqueued together.
+ */
struct {
struct virtio_gpu_resource_attach_backing backing;
- struct virtio_gpu_mem_entry mem[1];
+ char pad;
+ struct virtio_gpu_mem_entry mem;
} req;
char pad;
struct virtio_gpu_ctrl_hdr resp;
@@ -577,11 +602,11 @@ vtgpu_attach_backing(struct vtgpu_softc *sc)
s.req.backing.resource_id = htole32(VTGPU_RESOURCE_ID);
s.req.backing.nr_entries = htole32(1);
- s.req.mem[0].addr = htole64(sc->vtgpu_fb_info.fb_pbase);
- s.req.mem[0].length = htole32(sc->vtgpu_fb_info.fb_size);
+ s.req.mem.addr = htole64(sc->vtgpu_fb_info.fb_pbase);
+ s.req.mem.length = htole32(sc->vtgpu_fb_info.fb_size);
- error = vtgpu_req_resp(sc, &s.req, sizeof(s.req), &s.resp,
- sizeof(s.resp));
+ error = vtgpu_req_resp2(sc, &s.req.backing, sizeof(s.req.backing),
+ &s.req.mem, sizeof(s.req.mem), &s.resp, sizeof(s.resp));
if (error != 0)
return (error);