[virtmagma] Support for magma_poll
Change-Id: Iba9ad6ec8a6cd735af46c3b9baca8937c41ff3b6
diff --git a/drivers/virtio/virtio_magma.c b/drivers/virtio/virtio_magma.c
index 26ed77b..6d12129 100644
--- a/drivers/virtio/virtio_magma.c
+++ b/drivers/virtio/virtio_magma.c
@@ -1074,6 +1074,45 @@
return virtmagma_check_expected_response_type(request, response);
}
+static int
+ virtmagma_command_magma_poll(struct virtmagma_instance *instance,
+ struct virtmagma_virtio_command *command)
+{
+ int ret;
+ size_t items_size;
+ struct virtio_magma_poll_ctrl *request = command->request_ptr;
+ struct virtio_magma_poll_resp *response = command->response_ptr;
+
+ if (!COMMAND_OK(command, request, response))
+ return -EINVAL;
+
+ /* reallocate request buffer with enough space for the items */
+ /* note: request->count is used as the byte count */
+ items_size = request->count;
+ command->request_size = sizeof(*request) + items_size;
+ command->request_ptr = kzalloc(command->request_size, GFP_KERNEL);
+ if (!command->request_ptr)
+ return -ENOMEM;
+
+ memcpy(command->request_ptr, request, sizeof(*request));
+ ret = copy_from_user((char *)command->request_ptr + sizeof(*request),
+ (void *)request->items, items_size);
+ if (ret)
+ return ret;
+
+ ret = vq_out_send_sync(instance->vi, command);
+ if (ret)
+ return ret;
+
+ ret = virtmagma_check_expected_response_type(request, response);
+ if (ret)
+ return ret;
+
+ return copy_to_user((void *)request->items,
+ (char *)command->request_ptr + sizeof(*request),
+ items_size);
+}
+
static int virtmagma_command_magma_read_notification_channel(
struct virtmagma_instance *instance,
struct virtmagma_virtio_command *command)
@@ -1262,7 +1301,7 @@
switch (request_type) {
case VIRTIO_MAGMA_CMD_CREATE_CONNECTION2:
ret = virtmagma_command_magma_create_connection2(instance,
- &command);
+ &command);
break;
case VIRTIO_MAGMA_CMD_RELEASE_CONNECTION:
ret = virtmagma_command_magma_release_connection(instance,
@@ -1302,6 +1341,9 @@
ret = virtmagma_command_magma_wait_semaphores(instance,
&command);
break;
+ case VIRTIO_MAGMA_CMD_POLL:
+ ret = virtmagma_command_magma_poll(instance, &command);
+ break;
case VIRTIO_MAGMA_CMD_READ_NOTIFICATION_CHANNEL:
ret = virtmagma_command_magma_read_notification_channel(
instance, &command);
diff --git a/include/uapi/linux/virtio_magma.h b/include/uapi/linux/virtio_magma.h
index 451566ea..fcf55b1 100644
--- a/include/uapi/linux/virtio_magma.h
+++ b/include/uapi/linux/virtio_magma.h
@@ -62,6 +62,7 @@
VIRTIO_MAGMA_CMD_QUERY_RETURNS_BUFFER2 = 0x1031,
VIRTIO_MAGMA_CMD_CREATE_CONNECTION2 = 0x1032,
VIRTIO_MAGMA_CMD_INITIALIZE_LOGGING = 0x1033,
+ VIRTIO_MAGMA_CMD_POLL = 0x1034,
/* magma success responses */
VIRTIO_MAGMA_RESP_RELEASE_CONNECTION = 0x2004,
VIRTIO_MAGMA_RESP_GET_ERROR = 0x2005,
@@ -107,6 +108,7 @@
VIRTIO_MAGMA_RESP_QUERY_RETURNS_BUFFER2 = 0x2031,
VIRTIO_MAGMA_RESP_CREATE_CONNECTION2 = 0x2032,
VIRTIO_MAGMA_RESP_INITIALIZE_LOGGING = 0x2033,
+ VIRTIO_MAGMA_RESP_POLL = 0x2034,
/* magma error responses */
VIRTIO_MAGMA_RESP_ERR_UNIMPLEMENTED = 0x3001,
VIRTIO_MAGMA_RESP_ERR_INTERNAL = 0x3002,
@@ -206,6 +208,8 @@
case VIRTIO_MAGMA_RESP_CREATE_CONNECTION2: return "VIRTIO_MAGMA_RESP_CREATE_CONNECTION2";
case VIRTIO_MAGMA_CMD_INITIALIZE_LOGGING: return "VIRTIO_MAGMA_CMD_INITIALIZE_LOGGING";
case VIRTIO_MAGMA_RESP_INITIALIZE_LOGGING: return "VIRTIO_MAGMA_RESP_INITIALIZE_LOGGING";
+ case VIRTIO_MAGMA_CMD_POLL: return "VIRTIO_MAGMA_CMD_POLL";
+ case VIRTIO_MAGMA_RESP_POLL: return "VIRTIO_MAGMA_RESP_POLL";
case VIRTIO_MAGMA_RESP_ERR_UNIMPLEMENTED: return "VIRTIO_MAGMA_RESP_ERR_UNIMPLEMENTED";
case VIRTIO_MAGMA_RESP_ERR_INTERNAL: return "VIRTIO_MAGMA_RESP_ERR_INTERNAL";
case VIRTIO_MAGMA_RESP_ERR_HOST_DISCONNECTED: return "VIRTIO_MAGMA_RESP_ERR_HOST_DISCONNECTED";
@@ -262,6 +266,7 @@
case VIRTIO_MAGMA_CMD_QUERY_RETURNS_BUFFER2: return VIRTIO_MAGMA_RESP_QUERY_RETURNS_BUFFER2;
case VIRTIO_MAGMA_CMD_CREATE_CONNECTION2: return VIRTIO_MAGMA_RESP_CREATE_CONNECTION2;
case VIRTIO_MAGMA_CMD_INITIALIZE_LOGGING: return VIRTIO_MAGMA_RESP_INITIALIZE_LOGGING;
+ case VIRTIO_MAGMA_CMD_POLL: return VIRTIO_MAGMA_RESP_POLL;
default: return VIRTIO_MAGMA_RESP_ERR_INVALID_COMMAND;
}
}
@@ -764,4 +769,16 @@
__le64 result_return;
} __attribute((packed));
+struct virtio_magma_poll_ctrl {
+ struct virtio_magma_ctrl_hdr hdr;
+ __le64 items;
+ __le32 count;
+ __le64 timeout_ns;
+} __attribute((packed));
+
+struct virtio_magma_poll_resp {
+ struct virtio_magma_ctrl_hdr hdr;
+ __le64 result_return;
+} __attribute((packed));
+
#endif /* _LINUX_VIRTIO_MAGMA_H */