|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 2/5] plat/drivers: Add 9P device initialization
This patch implements the 9P driver and device initialization.
Signed-off-by: Cristian Banu <cristb@xxxxxxxxx>
---
plat/drivers/include/virtio/virtio_9p.h | 9 +++
plat/drivers/virtio/virtio_9p.c | 132 +++++++++++++++++++++++++++++++-
2 files changed, 138 insertions(+), 3 deletions(-)
diff --git a/plat/drivers/include/virtio/virtio_9p.h
b/plat/drivers/include/virtio/virtio_9p.h
index 5459a397a2c8..29158ab718c1 100644
--- a/plat/drivers/include/virtio/virtio_9p.h
+++ b/plat/drivers/include/virtio/virtio_9p.h
@@ -41,4 +41,13 @@
#include <virtio/virtio_config.h>
#include <virtio/virtio_types.h>
+/* Feature bitmap for virtio 9P. */
+#define VIRTIO_9P_F_MOUNT_TAG 0
+
+/* Virtio 9P PCI configuration space layout. */
+struct virtio_9p_config {
+ __u16 tag_len;
+ __u8 tag[0];
+} __packed;
+
#endif /* __PLAT_DRV_VIRTIO_9P_H */
diff --git a/plat/drivers/virtio/virtio_9p.c b/plat/drivers/virtio/virtio_9p.c
index 855548fe4870..798ebe908a6c 100644
--- a/plat/drivers/virtio/virtio_9p.c
+++ b/plat/drivers/virtio/virtio_9p.c
@@ -32,19 +32,145 @@
* THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
*/
+#include <uk/alloc.h>
+#include <uk/essentials.h>
#include <virtio/virtio_bus.h>
#include <virtio/virtio_9p.h>
+#include <uk/plat/spinlock.h>
-static int virtio_9p_add_dev(struct virtio_dev *vdev __unused)
+#define DRIVER_NAME "virtio-9p"
+static struct uk_alloc *a;
+
+/* List of initialized virtio 9p devices. */
+static UK_LIST_HEAD(virtio_9p_device_list);
+static DEFINE_SPINLOCK(virtio_9p_device_list_lock);
+
+struct virtio_9p_device {
+ /* Virtio device. */
+ struct virtio_dev *vdev;
+ /* Mount tag for this virtio device. */
+ char *tag;
+ /* Entry within the virtio devices' list. */
+ struct uk_list_head _list;
+};
+
+static int virtio_9p_feature_negotiate(struct virtio_9p_device *d)
{
- return 0;
+ __u64 host_features;
+ __u16 tag_len;
+ int rc = 0;
+
+ host_features = virtio_feature_get(d->vdev);
+ if (!virtio_has_features(host_features, VIRTIO_9P_F_MOUNT_TAG)) {
+ uk_pr_err(DRIVER_NAME": Host system does not offer MOUNT_TAG
feature\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ virtio_config_get(d->vdev,
+ __offsetof(struct virtio_9p_config, tag_len),
+ &tag_len, 1, sizeof(tag_len));
+
+ d->tag = uk_calloc(a, tag_len + 1, sizeof(*d->tag));
+ if (!d->tag) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ virtio_config_get(d->vdev,
+ __offsetof(struct virtio_9p_config, tag),
+ d->tag, tag_len, 1);
+ d->tag[tag_len] = '\0';
+
+ d->vdev->features &= host_features;
+ virtio_feature_set(d->vdev, d->vdev->features);
+
+out:
+ return rc;
+}
+
+static inline void virtio_9p_feature_set(struct virtio_9p_device *d)
+{
+ d->vdev->features = 0;
+ VIRTIO_FEATURES_UPDATE(d->vdev->features, VIRTIO_9P_F_MOUNT_TAG);
+}
+
+static int virtio_9p_configure(struct virtio_9p_device *d)
+{
+ int rc = 0;
+
+ rc = virtio_9p_feature_negotiate(d);
+ if (rc != 0) {
+ uk_pr_err(DRIVER_NAME": Failed to negotiate the device feature
%d\n",
+ rc);
+ rc = -EINVAL;
+ goto out_status_fail;
+ }
+
+ uk_pr_info(DRIVER_NAME": Configured: features=0x%lx tag=%s\n",
+ d->vdev->features, d->tag);
+out:
+ return rc;
+
+out_status_fail:
+ virtio_dev_status_update(d->vdev, VIRTIO_CONFIG_STATUS_FAIL);
+ goto out;
}
-static int virtio_9p_drv_init(struct uk_alloc *drv_allocator __unused)
+static int virtio_9p_start(struct virtio_9p_device *d)
{
+ virtio_dev_drv_up(d->vdev);
+ uk_pr_info(DRIVER_NAME": %s started\n", d->tag);
+
return 0;
}
+static int virtio_9p_add_dev(struct virtio_dev *vdev)
+{
+ struct virtio_9p_device *d;
+ unsigned long flags;
+ int rc = 0;
+
+ UK_ASSERT(vdev != NULL);
+
+ d = uk_calloc(a, 1, sizeof(*d));
+ if (!d) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ d->vdev = vdev;
+ virtio_9p_feature_set(d);
+ rc = virtio_9p_configure(d);
+ if (rc)
+ goto out_free;
+ rc = virtio_9p_start(d);
+ if (rc)
+ goto out_free;
+
+ ukplat_spin_lock_irqsave(&virtio_9p_device_list_lock, flags);
+ uk_list_add(&d->_list, &virtio_9p_device_list);
+ ukplat_spin_unlock_irqrestore(&virtio_9p_device_list_lock, flags);
+out:
+ return rc;
+out_free:
+ uk_free(a, d);
+ goto out;
+}
+
+static int virtio_9p_drv_init(struct uk_alloc *drv_allocator)
+{
+ int rc = 0;
+
+ if (!drv_allocator) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ a = drv_allocator;
+out:
+ return rc;
+}
+
static const struct virtio_dev_id v9p_dev_id[] = {
{VIRTIO_ID_9P},
{VIRTIO_ID_INVALID} /* List Terminator */
--
2.11.0
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |