Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/virtio/gpu/virtio_gpu.c
| Show First 20 Lines • Show All 439 Lines • ▼ Show 20 Lines | vtgpu_alloc_virtqueue(struct vtgpu_softc *sc) | ||||
| VQ_ALLOC_INFO_INIT(&vq_info[0], 0, NULL, sc, &sc->vtgpu_ctrl_vq, | VQ_ALLOC_INFO_INIT(&vq_info[0], 0, NULL, sc, &sc->vtgpu_ctrl_vq, | ||||
| "%s control", device_get_nameunit(dev)); | "%s control", device_get_nameunit(dev)); | ||||
| return (virtio_alloc_virtqueues(dev, nvqs, vq_info)); | return (virtio_alloc_virtqueues(dev, nvqs, vq_info)); | ||||
| } | } | ||||
| static int | static int | ||||
| vtgpu_req_resp(struct vtgpu_softc *sc, void *req, size_t reqlen, | vtgpu_req_resp2(struct vtgpu_softc *sc, void *req1, size_t req1len, | ||||
| void *resp, size_t resplen) | void *req2, size_t req2len, void *resp, size_t resplen) | ||||
| { | { | ||||
| struct sglist sg; | struct sglist sg; | ||||
| struct sglist_seg segs[2]; | struct sglist_seg segs[3]; | ||||
| int error; | 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) { | if (error != 0) { | ||||
| device_printf(sc->vtgpu_dev, | 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); | 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); | error = sglist_append(&sg, resp, resplen); | ||||
| if (error != 0) { | if (error != 0) { | ||||
| device_printf(sc->vtgpu_dev, | device_printf(sc->vtgpu_dev, | ||||
| "Unable to append the response buffer to the sglist: %d\n", | "Unable to append the response buffer to the sglist: %d\n", | ||||
| error); | error); | ||||
| return (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) { | if (error != 0) { | ||||
| device_printf(sc->vtgpu_dev, "Enqueue failed: %d\n", error); | device_printf(sc->vtgpu_dev, "Enqueue failed: %d\n", error); | ||||
| return (error); | return (error); | ||||
| } | } | ||||
| virtqueue_notify(sc->vtgpu_ctrl_vq); | virtqueue_notify(sc->vtgpu_ctrl_vq); | ||||
| virtqueue_poll(sc->vtgpu_ctrl_vq, NULL); | virtqueue_poll(sc->vtgpu_ctrl_vq, NULL); | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| static int | 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) | vtgpu_get_display_info(struct vtgpu_softc *sc) | ||||
| { | { | ||||
| struct { | struct { | ||||
| struct virtio_gpu_ctrl_hdr req; | struct virtio_gpu_ctrl_hdr req; | ||||
| char pad; | char pad; | ||||
| struct virtio_gpu_resp_display_info resp; | struct virtio_gpu_resp_display_info resp; | ||||
| } s = { 0 }; | } s = { 0 }; | ||||
| int error; | int error; | ||||
| ▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | vtgpu_create_2d(struct vtgpu_softc *sc) | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| static int | static int | ||||
| vtgpu_attach_backing(struct vtgpu_softc *sc) | vtgpu_attach_backing(struct vtgpu_softc *sc) | ||||
| { | { | ||||
| struct { | 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 { | ||||
| struct virtio_gpu_resource_attach_backing backing; | struct virtio_gpu_resource_attach_backing backing; | ||||
| struct virtio_gpu_mem_entry mem[1]; | char pad; | ||||
| struct virtio_gpu_mem_entry mem; | |||||
| } req; | } req; | ||||
| char pad; | char pad; | ||||
| struct virtio_gpu_ctrl_hdr resp; | struct virtio_gpu_ctrl_hdr resp; | ||||
| } s = { 0 }; | } s = { 0 }; | ||||
| int error; | int error; | ||||
| s.req.backing.hdr.type = | s.req.backing.hdr.type = | ||||
| htole32(VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING); | htole32(VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING); | ||||
| s.req.backing.hdr.flags = htole32(VIRTIO_GPU_FLAG_FENCE); | s.req.backing.hdr.flags = htole32(VIRTIO_GPU_FLAG_FENCE); | ||||
| s.req.backing.hdr.fence_id = htole64( | s.req.backing.hdr.fence_id = htole64( | ||||
| atomic_fetchadd_64(&sc->vtgpu_next_fence, 1)); | atomic_fetchadd_64(&sc->vtgpu_next_fence, 1)); | ||||
| s.req.backing.resource_id = htole32(VTGPU_RESOURCE_ID); | s.req.backing.resource_id = htole32(VTGPU_RESOURCE_ID); | ||||
| s.req.backing.nr_entries = htole32(1); | s.req.backing.nr_entries = htole32(1); | ||||
| s.req.mem[0].addr = htole64(sc->vtgpu_fb_info.fb_pbase); | s.req.mem.addr = htole64(sc->vtgpu_fb_info.fb_pbase); | ||||
| s.req.mem[0].length = htole32(sc->vtgpu_fb_info.fb_size); | s.req.mem.length = htole32(sc->vtgpu_fb_info.fb_size); | ||||
| error = vtgpu_req_resp(sc, &s.req, sizeof(s.req), &s.resp, | error = vtgpu_req_resp2(sc, &s.req.backing, sizeof(s.req.backing), | ||||
| sizeof(s.resp)); | &s.req.mem, sizeof(s.req.mem), &s.resp, sizeof(s.resp)); | ||||
| if (error != 0) | if (error != 0) | ||||
| return (error); | return (error); | ||||
| if (s.resp.type != htole32(VIRTIO_GPU_RESP_OK_NODATA)) { | if (s.resp.type != htole32(VIRTIO_GPU_RESP_OK_NODATA)) { | ||||
| device_printf(sc->vtgpu_dev, "Invalid response type %x\n", | device_printf(sc->vtgpu_dev, "Invalid response type %x\n", | ||||
| le32toh(s.resp.type)); | le32toh(s.resp.type)); | ||||
| return (EINVAL); | return (EINVAL); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 117 Lines • Show Last 20 Lines | |||||