| 62 | } |
| 63 | |
| 64 | static void virtio_gpu_ctrl_send_command(struct virtio_gpu_device *virtio_gpu_dev, |
| 65 | const void *cmd, rt_size_t cmd_len, void *res, rt_size_t res_len) |
| 66 | { |
| 67 | rt_uint16_t idx[2]; |
| 68 | void *addr = &virtio_gpu_dev->gpu_request; |
| 69 | void *ret_res = ((rt_uint8_t *)addr + cmd_len); |
| 70 | struct virtio_device *virtio_dev = &virtio_gpu_dev->virtio_dev; |
| 71 | |
| 72 | #ifdef RT_USING_SMP |
| 73 | rt_base_t level = rt_spin_lock_irqsave(&virtio_dev->spinlock); |
| 74 | #endif |
| 75 | |
| 76 | while (virtio_alloc_desc_chain(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, 2, idx)) |
| 77 | { |
| 78 | #ifdef RT_USING_SMP |
| 79 | rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); |
| 80 | #endif |
| 81 | rt_thread_yield(); |
| 82 | |
| 83 | #ifdef RT_USING_SMP |
| 84 | level = rt_spin_lock_irqsave(&virtio_dev->spinlock); |
| 85 | #endif |
| 86 | } |
| 87 | |
| 88 | rt_memcpy(&virtio_gpu_dev->gpu_request, cmd, cmd_len); |
| 89 | |
| 90 | virtio_fill_desc(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, idx[0], |
| 91 | VIRTIO_VA2PA(addr), cmd_len, VIRTQ_DESC_F_NEXT, idx[1]); |
| 92 | |
| 93 | virtio_fill_desc(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, idx[1], |
| 94 | VIRTIO_VA2PA(addr) + cmd_len, res_len, VIRTQ_DESC_F_WRITE, 0); |
| 95 | |
| 96 | rt_memset(ret_res, 0, res_len); |
| 97 | |
| 98 | virtio_gpu_dev->info[idx[0]].ctrl_valid = RT_TRUE; |
| 99 | |
| 100 | virtio_submit_chain(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, idx[0]); |
| 101 | |
| 102 | virtio_queue_notify(virtio_dev, VIRTIO_GPU_QUEUE_CTRL); |
| 103 | |
| 104 | while (virtio_gpu_dev->info[idx[0]].ctrl_valid) |
| 105 | { |
| 106 | #ifdef RT_USING_SMP |
| 107 | rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); |
| 108 | #endif |
| 109 | rt_thread_yield(); |
| 110 | |
| 111 | #ifdef RT_USING_SMP |
| 112 | level = rt_spin_lock_irqsave(&virtio_dev->spinlock); |
| 113 | #endif |
| 114 | } |
| 115 | |
| 116 | virtio_free_desc_chain(virtio_dev, VIRTIO_GPU_QUEUE_CTRL, idx[0]); |
| 117 | |
| 118 | rt_memcpy(res, ret_res, res_len); |
| 119 | |
| 120 | #ifdef RT_USING_SMP |
| 121 | rt_spin_unlock_irqrestore(&virtio_dev->spinlock, level); |
no test coverage detected