|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 07/10] plat/xen/drivers/cons: Start Consfront
This patch adds start for the xen console frontend.
Uses XenStore in order to establish connection
to backend.
Signed-off-by: Birlea Costin <costin.birlea@xxxxxxxxx>
---
plat/xen/drivers/cons/consfront.c | 38 ++++++++
plat/xen/drivers/cons/consfront_xb.h | 19 ++++
plat/xen/drivers/cons/consfront_xs.c | 176 +++++++++++++++++++++++++++++++++++
3 files changed, 233 insertions(+)
diff --git a/plat/xen/drivers/cons/consfront.c
b/plat/xen/drivers/cons/consfront.c
index cdbed0f5..4dd57151 100644
--- a/plat/xen/drivers/cons/consfront.c
+++ b/plat/xen/drivers/cons/consfront.c
@@ -216,6 +216,42 @@ static int consfront_release(struct uk_consdev *dev)
return 0;
}
+static int consfront_start(struct uk_consdev *dev)
+{
+ struct consfront_dev *cfdev;
+ int rc = 0;
+
+ UK_ASSERT(dev);
+
+ cfdev = to_consfront(dev);
+ UK_ASSERT(cfdev);
+
+ rc = consfront_xb_connect(cfdev);
+ if (rc < 0) {
+ uk_pr_err("Error connecting to backend: %d.\n", rc);
+ return rc;
+ }
+ uk_pr_info(DRIVER_NAME": %"PRIu16" started\n", cfdev->uid);
+
+ return rc;
+}
+
+static int consfront_stop(struct uk_consdev *dev)
+{
+ struct consfront_dev *cfdev;
+
+ UK_ASSERT(dev);
+
+ cfdev = to_consfront(dev);
+ UK_ASSERT(cfdev);
+
+ consfront_xb_disconnect(cfdev);
+
+ uk_pr_info(DRIVER_NAME": %"PRIu16" stopped\n", cfdev->uid);
+
+ return 0;
+}
+
static void consfront_close(struct uk_consdev *dev)
{
struct consfront_dev *cfdev;
@@ -240,6 +276,8 @@ static const struct uk_consdev_ops consfront_ops = {
.rx_configure = consfront_rx_configure,
.tx_configure = consfront_tx_configure,
.release = consfront_release,
+ .start = consfront_start,
+ .stop = consfront_stop,
.close = consfront_close,
};
diff --git a/plat/xen/drivers/cons/consfront_xb.h
b/plat/xen/drivers/cons/consfront_xb.h
index 0ca1abaf..6b5475f3 100644
--- a/plat/xen/drivers/cons/consfront_xb.h
+++ b/plat/xen/drivers/cons/consfront_xb.h
@@ -44,6 +44,25 @@
#include "consfront.h"
+/**
+ * Write ring entries to Xenstore.
+ * Device changes its state to Connected.
+ * It waits until the backend is connected.
+ *
+ * Return 0 on success, a negative errno value on error.
+ */
+int consfront_xb_connect(struct consfront_dev *cfdev);
+
+/**
+ * Stops the connection with the backend.
+ * The following states are:
+ * Connected -> Closing -> Closed.
+ * Delete ring entries
+ *
+ * Return 0 on success, a negative errno value on error.
+ */
+int consfront_xb_disconnect(struct consfront_dev *cfdev);
+
/*
* Get initial info from the xenstore.
* Ex: backend path.
diff --git a/plat/xen/drivers/cons/consfront_xs.c
b/plat/xen/drivers/cons/consfront_xs.c
index 066a23d9..a1554ae0 100644
--- a/plat/xen/drivers/cons/consfront_xs.c
+++ b/plat/xen/drivers/cons/consfront_xs.c
@@ -40,6 +40,182 @@
#include "consfront_xb.h"
+static void consfront_xb_front_fini(struct consfront_dev *cfdev,
+ xenbus_transaction_t xbt);
+
+#define WAIT_BE_STATE_CHANGE_WHILE_COND(state_cond) \
+ do { \
+ rc = xs_read_integer(XBT_NIL, path, (int *) &be_state); \
+ if (rc < 0) \
+ goto out; \
+ while (!rc && (state_cond)) \
+ rc = xenbus_wait_for_state_change(path, &be_state, \
+ xendev->otherend_watch); \
+ if (rc < 0) \
+ goto out; \
+ } while (0)
+
+
+static int consfront_xb_front_init(struct consfront_dev *cfdev,
+ xenbus_transaction_t xbt)
+{
+ int rc = 0;
+ struct xenbus_device *xendev = cfdev->xendev;
+
+ rc = xs_printf(xbt, xendev->nodename, "ring-ref", "%u",
+ cfdev->ring_ref);
+ if (rc < 0)
+ goto out;
+
+ rc = xs_printf(xbt, xendev->nodename,
+ "port", "%u", cfdev->evtchn);
+ if (rc < 0)
+ goto out;
+
+out:
+ return rc;
+}
+
+static int consfront_xb_transactions(struct consfront_dev *cfdev)
+{
+ struct xenbus_device *xendev = cfdev->xendev;
+ xenbus_transaction_t xbt;
+ char *message = NULL;
+ int rc = 0;
+
+ rc = xs_transaction_start(&xbt);
+ if (rc < 0) {
+ message = "starting transaction";
+ goto abort_transaction;
+ }
+
+ rc = consfront_xb_front_init(cfdev, xbt);
+ if (rc < 0) {
+ message = "writing something";
+ goto abort_transaction;
+ }
+
+ rc = xenbus_switch_state(xbt, xendev, XenbusStateConnected);
+ if (rc < 0) {
+ message = "switching state";
+ goto abort_transaction;
+ }
+
+ rc = xs_transaction_end(xbt, 0);
+ if (rc < 0) {
+ message = "ending transaction";
+ goto abort_transaction;
+ }
+
+ return rc;
+
+abort_transaction:
+ xs_transaction_end(xbt, 1);
+ uk_pr_info("Abort transaction %s: code: %d\n", message, rc);
+ return rc;
+}
+
+static int consfront_xb_wait_be_connect(struct consfront_dev *cfdev)
+{
+ struct xenbus_device *xendev = cfdev->xendev;
+ char path[strlen(xendev->otherend) + strlen("/state") + 1];
+ XenbusState be_state;
+ int rc = 0;
+
+ snprintf(path, sizeof(path), "%s/state", xendev->otherend);
+
+ xendev->otherend_watch = xs_watch_path(XBT_NIL, path);
+ if (PTRISERR(xendev->otherend_watch)) {
+ rc = PTR2ERR(xendev->otherend_watch);
+ goto out;
+ }
+
+ WAIT_BE_STATE_CHANGE_WHILE_COND(be_state < XenbusStateConnected);
+ if (be_state != XenbusStateConnected) {
+ uk_pr_err("Backend not available, state=%s\n",
+ xenbus_state_to_str(be_state));
+ xs_unwatch(XBT_NIL, xendev->otherend_watch);
+ }
+
+out:
+ return rc;
+}
+
+int consfront_xb_connect(struct consfront_dev *cfdev)
+{
+ int rc = 0;
+
+ UK_ASSERT(cfdev);
+
+ rc = consfront_xb_transactions(cfdev);
+ if (rc < 0)
+ goto error;
+
+ rc = consfront_xb_wait_be_connect(cfdev);
+ if (rc < 0)
+ consfront_xb_front_fini(cfdev, XBT_NIL);
+
+error:
+ return rc;
+}
+
+static void consfront_xb_front_fini(struct consfront_dev *cfdev,
+ xenbus_transaction_t xbt)
+{
+ struct xenbus_device *xendev = cfdev->xendev;
+ char path[strlen(xendev->nodename) + sizeof("/ring_ref")];
+
+ sprintf(path, "%s/ring-ref", xendev->nodename);
+ xs_rm(xbt, path);
+
+ sprintf(path, "%s/port", xendev->nodename);
+ xs_rm(xbt, path);
+}
+
+static int consfront_xb_wait_be_disconnect(struct consfront_dev *cfdev)
+{
+ struct xenbus_device *xendev = cfdev->xendev;
+ char path[strlen(xendev->otherend) + strlen("/state") + 1];
+ XenbusState be_state;
+ int rc = 0;
+
+ snprintf(path, sizeof(path), "%s/state", xendev->otherend);
+
+ WAIT_BE_STATE_CHANGE_WHILE_COND(be_state < XenbusStateClosing);
+
+ rc = xenbus_switch_state(XBT_NIL, xendev, XenbusStateClosed);
+ if (rc < 0)
+ goto out;
+
+ WAIT_BE_STATE_CHANGE_WHILE_COND(be_state < XenbusStateClosed);
+
+ xs_unwatch(XBT_NIL, xendev->otherend_watch);
+
+out:
+ return rc;
+}
+
+int consfront_xb_disconnect(struct consfront_dev *cfdev)
+{
+ struct xenbus_device *xendev = cfdev->xendev;
+ int rc = 0;
+
+ uk_pr_info("Close console: backend at %s\n", xendev->otherend);
+
+ rc = xenbus_switch_state(XBT_NIL, xendev, XenbusStateClosing);
+ if (rc < 0)
+ goto out;
+
+ rc = consfront_xb_wait_be_disconnect(cfdev);
+ if (rc < 0)
+ goto out;
+
+ consfront_xb_front_fini(cfdev, XBT_NIL);
+
+out:
+ return rc;
+}
+
int consfront_xb_init(struct consfront_dev *cfdev)
{
struct xenbus_device *xendev;
--
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 |