Example #1
0
void shutdown_kbdfront(struct kbdfront_dev *dev)
{
    char* err = NULL;
    XenbusState state;

    char path[strlen(dev->backend) + 1 + 5 + 1];
    char nodename[strlen(dev->nodename) + 1 + 5 + 1];

    printk("close kbd: backend at %s\n",dev->backend);

    snprintf(path, sizeof(path), "%s/state", dev->backend);
    snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing)) != NULL) {
        printk("shutdown_kbdfront: error changing state to %d: %s\n",
                XenbusStateClosing, err);
        goto close_kbdfront;
    }
    state = xenbus_read_integer(path);
    while (err == NULL && state < XenbusStateClosing)
        err = xenbus_wait_for_state_change(path, &state, &dev->events);
    if (err) free(err);

    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed)) != NULL) {
        printk("shutdown_kbdfront: error changing state to %d: %s\n",
                XenbusStateClosed, err);
        goto close_kbdfront;
    }
    state = xenbus_read_integer(path);
    while (state < XenbusStateClosed) {
        err = xenbus_wait_for_state_change(path, &state, &dev->events);
        if (err) free(err);
    }

    if ((err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising)) != NULL) {
        printk("shutdown_kbdfront: error changing state to %d: %s\n",
                XenbusStateInitialising, err);
        goto close_kbdfront;
    }
    err = NULL;
    state = xenbus_read_integer(path);
    while (err == NULL && (state < XenbusStateInitWait || state >= XenbusStateClosed))
    err = xenbus_wait_for_state_change(path, &state, &dev->events);

close_kbdfront:
    if (err) free(err);
    xenbus_unwatch_path_token(XBT_NIL, path, path);

    snprintf(path, sizeof(path), "%s/page-ref", nodename);
    xenbus_rm(XBT_NIL, path);
    snprintf(path, sizeof(path), "%s/event-channel", nodename);
    xenbus_rm(XBT_NIL, path);
    snprintf(path, sizeof(path), "%s/request-abs-pointer", nodename);
    xenbus_rm(XBT_NIL, path);

    if (!err)
        free_kbdfront(dev);
}
Example #2
0
struct kbdfront_dev *init_kbdfront(char *_nodename, int abs_pointer)
{
    xenbus_transaction_t xbt;
    char* err;
    char* message=NULL;
    struct xenkbd_page *s;
    int retry=0;
    char* msg = NULL;
    char* nodename = _nodename ? _nodename : "device/vkbd/0";
    struct kbdfront_dev *dev;

    char path[strlen(nodename) + strlen("/backend-id") + 1];

    printk("******************* KBDFRONT for %s **********\n\n\n", nodename);

    dev = malloc(sizeof(*dev));
    memset(dev, 0, sizeof(*dev));
    dev->nodename = strdup(nodename);
#ifdef HAVE_LIBC
    dev->fd = -1;
#endif

    snprintf(path, sizeof(path), "%s/backend-id", nodename);
    dev->dom = xenbus_read_integer(path);
    evtchn_alloc_unbound(dev->dom, kbdfront_handler, dev, &dev->evtchn);

    dev->page = s = (struct xenkbd_page*) alloc_page();
    memset(s,0,PAGE_SIZE);

    dev->events = NULL;

    s->in_cons = s->in_prod = 0;
    s->out_cons = s->out_prod = 0;

again:
    err = xenbus_transaction_start(&xbt);
    if (err) {
        printk("starting transaction\n");
        free(err);
    }

    err = xenbus_printf(xbt, nodename, "page-ref","%lu", virt_to_mfn(s));
    if (err) {
        message = "writing page-ref";
        goto abort_transaction;
    }
    err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
    if (err) {
        message = "writing event-channel";
        goto abort_transaction;
    }
    if (abs_pointer) {
        err = xenbus_printf(xbt, nodename, "request-abs-pointer", "1");
        if (err) {
            message = "writing event-channel";
            goto abort_transaction;
        }
    }

    snprintf(path, sizeof(path), "%s/state", nodename);
    err = xenbus_switch_state(xbt, path, XenbusStateInitialised);
    if (err) {
        printk("error writing initialized: %s\n", err);
        free(err);
    }

    err = xenbus_transaction_end(xbt, 0, &retry);
    free(err);
    if (retry) {
        goto again;
        printk("completing transaction\n");
    }

    goto done;

abort_transaction:
    free(err);
    err = xenbus_transaction_end(xbt, 1, &retry);
    printk("Abort transaction %s\n", message);
    goto error;

done:

    snprintf(path, sizeof(path), "%s/backend", nodename);
    msg = xenbus_read(XBT_NIL, path, &dev->backend);
    if (msg) {
        printk("Error %s when reading the backend path %s\n", msg, path);
        goto error;
    }

    printk("backend at %s\n", dev->backend);

    {
        XenbusState state;
        char path[strlen(dev->backend) + strlen("/state") + 1];
        char frontpath[strlen(nodename) + strlen("/state") + 1];

        snprintf(path, sizeof(path), "%s/state", dev->backend);

        xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);

        err = NULL;
        state = xenbus_read_integer(path);
        while (err == NULL && state < XenbusStateConnected)
            err = xenbus_wait_for_state_change(path, &state, &dev->events);
        if (state != XenbusStateConnected) {
            printk("backend not available, state=%d\n", state);
            free(err);
            err = xenbus_unwatch_path_token(XBT_NIL, path, path);
            goto error;
        }

        printk("%s connected\n", dev->backend);

        snprintf(frontpath, sizeof(frontpath), "%s/state", nodename);
        if((err = xenbus_switch_state(XBT_NIL, frontpath, XenbusStateConnected))
                != NULL) {
            printk("error switching state: %s\n", err);
            free(err);
            err = xenbus_unwatch_path_token(XBT_NIL, path, path);
            goto error;
        }
    }
    unmask_evtchn(dev->evtchn);

    printk("************************** KBDFRONT\n");

    return dev;
error:
    free(msg);
    free(err);
    free_kbdfront(dev);
    return NULL;
}
Example #3
0
struct kbdfront_dev *init_kbdfront(char *_nodename, int abs_pointer)
{
    xenbus_transaction_t xbt;
    char* err;
    char* message=NULL;
    struct xenkbd_page *s;
    int retry=0;
    char* msg;
    char* nodename = _nodename ? _nodename : "device/vkbd/0";
    struct kbdfront_dev *dev;

    char path[strlen(nodename) + 1 + 10 + 1];

    printk("******************* KBDFRONT for %s **********\n\n\n", nodename);

    dev = malloc(sizeof(*dev));
    dev->nodename = strdup(nodename);
#ifdef HAVE_LIBC
    dev->fd = -1;
#endif

    snprintf(path, sizeof(path), "%s/backend-id", nodename);
    dev->dom = xenbus_read_integer(path); 
    evtchn_alloc_unbound(dev->dom, kbdfront_handler, dev, &dev->evtchn);

    dev->page = s = (struct xenkbd_page*) alloc_page();
    memset(s,0,PAGE_SIZE);

    dev->events = NULL;

    s->in_cons = s->in_prod = 0;
    s->out_cons = s->out_prod = 0;

again:
    err = xenbus_transaction_start(&xbt);
    if (err) {
        printk("starting transaction\n");
    }

    err = xenbus_printf(xbt, nodename, "page-ref","%u", virt_to_mfn(s));
    if (err) {
        message = "writing page-ref";
        goto abort_transaction;
    }
    err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
    if (err) {
        message = "writing event-channel";
        goto abort_transaction;
    }
    if (abs_pointer) {
        err = xenbus_printf(xbt, nodename, "request-abs-pointer", "1");
        if (err) {
            message = "writing event-channel";
            goto abort_transaction;
        }
    }

    err = xenbus_printf(xbt, nodename, "state", "%u", 3); /* initialized */
    if (err)
        printk("error writing initialized: %s\n", err);


    err = xenbus_transaction_end(xbt, 0, &retry);
    if (retry) {
            goto again;
        printk("completing transaction\n");
    }

    goto done;

abort_transaction:
    xenbus_transaction_end(xbt, 1, &retry);
    goto error;

done:

    snprintf(path, sizeof(path), "%s/backend", nodename);
    msg = xenbus_read(XBT_NIL, path, &dev->backend);
    if (msg) {
        printk("Error %s when reading the backend path %s\n", msg, path);
        goto error;
    }

    printk("backend at %s\n", dev->backend);

    {
        char path[strlen(dev->backend) + 1 + 6 + 1];

        snprintf(path, sizeof(path), "%s/state", dev->backend);

        xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);

        xenbus_wait_for_value(path, "4", &dev->events);

        printk("%s connected\n", dev->backend);

        err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 4); /* connected */
    }
    unmask_evtchn(dev->evtchn);

    printk("************************** KBDFRONT\n");

    return dev;
error:
    free_kbdfront(dev);
    return NULL;
}