Object create and destroy were implemented specifically for dev parts
device objects. Create general purpose APIs for use by upper layer
drivers.

Signed-off-by: Daniel Jurgens <[email protected]>
Reviewed-by: Parav Pandit <[email protected]>
Reviewed-by: Xuan Zhuo <[email protected]>

---
v4: Moved this logic from virtio_pci_modern to new file
    virtio_admin_commands.
v5: Added missing params, and synced names in comments (Alok Tiwari)
---
 drivers/virtio/virtio_admin_commands.c | 75 ++++++++++++++++++++++++++
 include/linux/virtio_admin.h           | 44 +++++++++++++++
 2 files changed, 119 insertions(+)

diff --git a/drivers/virtio/virtio_admin_commands.c 
b/drivers/virtio/virtio_admin_commands.c
index 94751d16b3c4..2b80548ba3bc 100644
--- a/drivers/virtio/virtio_admin_commands.c
+++ b/drivers/virtio/virtio_admin_commands.c
@@ -88,3 +88,78 @@ int virtio_admin_cap_set(struct virtio_device *vdev,
        return err;
 }
 EXPORT_SYMBOL_GPL(virtio_admin_cap_set);
+
+int virtio_admin_obj_create(struct virtio_device *vdev,
+                           u16 obj_type,
+                           u32 obj_id,
+                           u16 group_type,
+                           u64 group_member_id,
+                           const void *obj_specific_data,
+                           size_t obj_specific_data_size)
+{
+       size_t data_size = sizeof(struct 
virtio_admin_cmd_resource_obj_create_data);
+       struct virtio_admin_cmd_resource_obj_create_data *obj_create_data;
+       struct virtio_admin_cmd cmd = {};
+       struct scatterlist data_sg;
+       void *data;
+       int err;
+
+       if (!vdev->config->admin_cmd_exec)
+               return -EOPNOTSUPP;
+
+       data_size += obj_specific_data_size;
+       data = kzalloc(data_size, GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       obj_create_data = data;
+       obj_create_data->hdr.type = cpu_to_le16(obj_type);
+       obj_create_data->hdr.id = cpu_to_le32(obj_id);
+       memcpy(obj_create_data->resource_obj_specific_data, obj_specific_data,
+              obj_specific_data_size);
+       sg_init_one(&data_sg, data, data_size);
+
+       cmd.opcode = cpu_to_le16(VIRTIO_ADMIN_CMD_RESOURCE_OBJ_CREATE);
+       cmd.group_type = cpu_to_le16(group_type);
+       cmd.group_member_id = cpu_to_le64(group_member_id);
+       cmd.data_sg = &data_sg;
+
+       err = vdev->config->admin_cmd_exec(vdev, &cmd);
+       kfree(data);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(virtio_admin_obj_create);
+
+int virtio_admin_obj_destroy(struct virtio_device *vdev,
+                            u16 obj_type,
+                            u32 obj_id,
+                            u16 group_type,
+                            u64 group_member_id)
+{
+       struct virtio_admin_cmd_resource_obj_cmd_hdr *data;
+       struct virtio_admin_cmd cmd = {};
+       struct scatterlist data_sg;
+       int err;
+
+       if (!vdev->config->admin_cmd_exec)
+               return -EOPNOTSUPP;
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->type = cpu_to_le16(obj_type);
+       data->id = cpu_to_le32(obj_id);
+       sg_init_one(&data_sg, data, sizeof(*data));
+       cmd.opcode = cpu_to_le16(VIRTIO_ADMIN_CMD_RESOURCE_OBJ_DESTROY);
+       cmd.group_type = cpu_to_le16(group_type);
+       cmd.group_member_id = cpu_to_le64(group_member_id);
+       cmd.data_sg = &data_sg;
+
+       err = vdev->config->admin_cmd_exec(vdev, &cmd);
+       kfree(data);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(virtio_admin_obj_destroy);
diff --git a/include/linux/virtio_admin.h b/include/linux/virtio_admin.h
index 36df97b6487a..039b996f73ec 100644
--- a/include/linux/virtio_admin.h
+++ b/include/linux/virtio_admin.h
@@ -77,4 +77,48 @@ int virtio_admin_cap_set(struct virtio_device *vdev,
                         const void *caps,
                         size_t cap_size);
 
+/**
+ * virtio_admin_obj_create - Create an object on a virtio device
+ * @vdev: the virtio device
+ * @obj_type: type of object to create
+ * @obj_id: ID for the new object
+ * @group_type: administrative group type for the operation
+ * @group_member_id: member identifier within the administrative group
+ * @obj_specific_data: object-specific data for creation
+ * @obj_specific_data_size: size of the object-specific data in bytes
+ *
+ * Creates a new object on the virtio device with the specified type and ID.
+ * The object may require object-specific data for proper initialization.
+ *
+ * Return: 0 on success, -EOPNOTSUPP if the device doesn't support admin
+ * operations or object creation, or a negative error code on other failures.
+ */
+int virtio_admin_obj_create(struct virtio_device *vdev,
+                           u16 obj_type,
+                           u32 obj_id,
+                           u16 group_type,
+                           u64 group_member_id,
+                           const void *obj_specific_data,
+                           size_t obj_specific_data_size);
+
+/**
+ * virtio_admin_obj_destroy - Destroy an object on a virtio device
+ * @vdev: the virtio device
+ * @obj_type: type of object to destroy
+ * @obj_id: ID of the object to destroy
+ * @group_type: administrative group type for the operation
+ * @group_member_id: member identifier within the administrative group
+ *
+ * Destroys an existing object on the virtio device with the specified type
+ * and ID.
+ *
+ * Return: 0 on success, -EOPNOTSUPP if the device doesn't support admin
+ * operations or object destruction, or a negative error code on other 
failures.
+ */
+int virtio_admin_obj_destroy(struct virtio_device *vdev,
+                            u16 obj_type,
+                            u32 obj_id,
+                            u16 group_type,
+                            u64 group_member_id);
+
 #endif /* _LINUX_VIRTIO_ADMIN_H */
-- 
2.50.1


Reply via email to