// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <ctype.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#include <ddk/driver.h>
#include <driver-info/driver-info.h>
#include <launchpad/launchpad.h>
#include <zircon/assert.h>
#include <zircon/ktrace.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/policy.h>
#include <zircon/device/dmctl.h>
#include <fdio/io.h>

#include "acpi.h"

#include "devcoordinator.h"
#include "devmgr.h"
#include "log.h"
#include "memfs-private.h"

extern zx_handle_t virtcon_open;

uint32_t log_flags = LOG_ERROR | LOG_INFO;

static void dc_dump_state(void);
static void dc_dump_devprops(void);
static void dc_dump_drivers(void);

static zx_handle_t dmctl_socket;

static void dmprintf(const char* fmt, ...) {
    if (dmctl_socket == ZX_HANDLE_INVALID) {
        return;
    }
    char buf[1024];
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    size_t actual;
    if (zx_socket_write(dmctl_socket, 0, buf, strlen(buf), &actual) < 0) {
        zx_handle_close(dmctl_socket);
        dmctl_socket = ZX_HANDLE_INVALID;
    }
}

static zx_status_t handle_dmctl_write(size_t len, const char* cmd) {
    if (len == 4) {
        if (!memcmp(cmd, "dump", 4)) {
            dc_dump_state();
            return ZX_OK;
        }
        if (!memcmp(cmd, "help", 4)) {
            dmprintf("dump        - dump device tree\n"
                     "poweroff    - power off the system\n"
                     "shutdown    - power off the system\n"
                     "reboot      - reboot the system\n"
                     "kerneldebug - send a command to the kernel\n"
                     "ktraceoff   - stop kernel tracing\n"
                     "ktraceon    - start kernel tracing\n"
                     "devprops    - dump published devices and their binding properties\n"
                     "drivers     - list discovered drivers and their properties\n"
                     );
            return ZX_OK;
        }
    }
    if ((len == 6) && !memcmp(cmd, "reboot", 6)) {
        devmgr_vfs_exit();
        devhost_acpi_reboot();
        return ZX_OK;
    }
    if ((len == 7) && !memcmp(cmd, "drivers", 7)) {
        dc_dump_drivers();
        return ZX_OK;
    }
    if (len == 8) {
        if (!memcmp(cmd, "poweroff", 8) || !memcmp(cmd, "shutdown", 8)) {
            devmgr_vfs_exit();
            devhost_acpi_poweroff();
            return ZX_OK;
        }
        if (!memcmp(cmd, "ktraceon", 8)) {
            zx_ktrace_control(get_root_resource(), KTRACE_ACTION_START, KTRACE_GRP_ALL, NULL);
            return ZX_OK;
        }
        if (!memcmp(cmd, "devprops", 8)) {
            dc_dump_devprops();
            return ZX_OK;
        }
    }
    if ((len == 9) && (!memcmp(cmd, "ktraceoff", 9))) {
        zx_ktrace_control(get_root_resource(), KTRACE_ACTION_STOP, 0, NULL);
        zx_ktrace_control(get_root_resource(), KTRACE_ACTION_REWIND, 0, NULL);
        return ZX_OK;
    }
    if ((len > 12) && !memcmp(cmd, "kerneldebug ", 12)) {
        return zx_debug_send_command(get_root_resource(), cmd + 12, len - 12);
    }
    if ((len > 11) && !memcmp(cmd, "add-driver:", 11)) {
        len -= 11;
        char path[len + 1];
        memcpy(path, cmd + 11, len);
        path[len] = 0;
        load_driver(path);
        return ZX_OK;
    }
    dmprintf("unknown command\n");
    log(ERROR, "dmctl: unknown command '%.*s'\n", (int) len, cmd);
    return ZX_ERR_NOT_SUPPORTED;
}

//TODO: these are copied from devhost.h
#define ID_HJOBROOT 4
zx_handle_t get_sysinfo_job_root(void);


static zx_status_t dc_handle_device(port_handler_t* ph, zx_signals_t signals, uint32_t evt);
static zx_status_t dc_attempt_bind(driver_t* drv, device_t* dev);

static bool dc_running;

static zx_handle_t dc_watch_channel;

static zx_handle_t devhost_job;
port_t dc_port;

// All Drivers
static list_node_t list_drivers = LIST_INITIAL_VALUE(list_drivers);

// Drivers to add to All Drivers
static list_node_t list_drivers_new = LIST_INITIAL_VALUE(list_drivers_new);

// All Devices (excluding static immortal devices)
static list_node_t list_devices = LIST_INITIAL_VALUE(list_devices);

static driver_t* libname_to_driver(const char* libname) {
    driver_t* drv;
    list_for_every_entry(&list_drivers, drv, driver_t, node) {
        if (!strcmp(libname, drv->libname)) {
            return drv;
        }
    }
    return NULL;
}

static zx_status_t libname_to_vmo(const char* libname, zx_handle_t* out) {
    driver_t* drv = libname_to_driver(libname);
    if (drv == NULL) {
        log(ERROR, "devcoord: cannot find driver '%s'\n", libname);
        return ZX_ERR_NOT_FOUND;
    }
    int fd = open(libname, O_RDONLY);
    if (fd < 0) {
        log(ERROR, "devcoord: cannot open driver '%s'\n", libname);
        return ZX_ERR_IO;
    }
    zx_status_t r = fdio_get_vmo(fd, out);
    close(fd);
    if (r < 0) {
        log(ERROR, "devcoord: cannot get driver vmo '%s'\n", libname);
    }
    return r;
}

static device_t root_device = {
    .flags = DEV_CTX_IMMORTAL | DEV_CTX_BUSDEV | DEV_CTX_MULTI_BIND,
    .protocol_id = ZX_PROTOCOL_ROOT,
    .name = "root",
    .libname = "",
    .args = "root,,",
    .children = LIST_INITIAL_VALUE(root_device.children),
    .pending = LIST_INITIAL_VALUE(root_device.pending),
    .refcount = 1,
};

static device_t misc_device = {
    .flags = DEV_CTX_IMMORTAL | DEV_CTX_BUSDEV | DEV_CTX_MULTI_BIND,
    .protocol_id = ZX_PROTOCOL_MISC_PARENT,
    .name = "misc",
    .libname = "",
    .args = "misc,,",
    .children = LIST_INITIAL_VALUE(misc_device.children),
    .pending = LIST_INITIAL_VALUE(misc_device.pending),
    .refcount = 1,
};

static zx_handle_t acpi_rpc[2] = { ZX_HANDLE_INVALID, ZX_HANDLE_INVALID };

static device_t acpi_device = {
    .flags = DEV_CTX_IMMORTAL | DEV_CTX_BUSDEV,
    .protocol_id = ZX_PROTOCOL_ACPI_BUS,
    .name = "acpi",
    .libname = "",
    .args = "acpi,,",
    .children = LIST_INITIAL_VALUE(acpi_device.children),
    .pending = LIST_INITIAL_VALUE(acpi_device.pending),
    .refcount = 1,
};

static device_t platform_device = {
    .flags = DEV_CTX_IMMORTAL | DEV_CTX_BUSDEV,
    .name = "platform",
    .libname = "",
    .args = "platform,,",
    .children = LIST_INITIAL_VALUE(platform_device.children),
    .pending = LIST_INITIAL_VALUE(platform_device.pending),
    .refcount = 1,
};

device_t socket_device = {
    .flags = DEV_CTX_IMMORTAL,
    .protocol_id = 0,
    .name = "socket",
    .libname = "",
    .args = "",
    .children = LIST_INITIAL_VALUE(socket_device.children),
    .pending = LIST_INITIAL_VALUE(socket_device.pending),
    .refcount = 1,
};

void devmgr_set_mdi(zx_handle_t mdi_handle) {
    // MDI VMO handle is passed via via the resource handle
    platform_device.hrsrc = mdi_handle;
}

static void dc_dump_device(device_t* dev, size_t indent) {
    zx_koid_t pid = dev->host ? dev->host->koid : 0;
    char extra[256];
    if (log_flags & LOG_DEVLC) {
        snprintf(extra, sizeof(extra), " dev=%p ref=%d", dev, dev->refcount);
    } else {
        extra[0] = 0;
    }
    if (pid == 0) {
        dmprintf("%*s[%s]%s\n", (int) (indent * 3), "", dev->name, extra);
    } else {
        dmprintf("%*s%c%s%c pid=%zu%s %s\n",
                 (int) (indent * 3), "",
                 dev->flags & DEV_CTX_SHADOW ? '<' : '[',
                 dev->name,
                 dev->flags & DEV_CTX_SHADOW ? '>' : ']',
                 pid, extra,
                 dev->libname ? dev->libname : "");
    }
    device_t* child;
    if (dev->shadow) {
        indent++;
        dc_dump_device(dev->shadow, indent);
    }
    list_for_every_entry(&dev->children, child, device_t, node) {
        dc_dump_device(child, indent + 1);
    }
}

static void dc_dump_state(void) {
    dc_dump_device(&root_device, 0);
    dc_dump_device(&misc_device, 1);
    dc_dump_device(&acpi_device, 1);
    if (platform_device.hrsrc != ZX_HANDLE_INVALID) {
        dc_dump_device(&platform_device, 1);
    }
}

static void dc_dump_device_props(device_t* dev) {
    if (dev->host) {
        dmprintf("Name [%s]%s%s%s\n",
                 dev->name,
                 dev->libname ? " Driver [" : "",
                 dev->libname ? dev->libname : "",
                 dev->libname ? "]" : "");
        dmprintf("Flags   :%s%s%s%s%s%s%s\n",
                 dev->flags & DEV_CTX_IMMORTAL   ? " Immortal"  : "",
                 dev->flags & DEV_CTX_BUSDEV     ? " BusDev"    : "",
                 dev->flags & DEV_CTX_MULTI_BIND ? " MultiBind" : "",
                 dev->flags & DEV_CTX_BOUND      ? " Bound"     : "",
                 dev->flags & DEV_CTX_DEAD       ? " Dead"      : "",
                 dev->flags & DEV_CTX_ZOMBIE     ? " Zombie"    : "",
                 dev->flags & DEV_CTX_SHADOW     ? " Shadow"    : "");

        char a = (char)((dev->protocol_id >> 24) & 0xFF);
        char b = (char)((dev->protocol_id >> 16) & 0xFF);
        char c = (char)((dev->protocol_id >> 8) & 0xFF);
        char d = (char)(dev->protocol_id & 0xFF);
        dmprintf("ProtoId : '%c%c%c%c' 0x%08x(%u)\n",
                 isprint(a) ? a : '.',
                 isprint(b) ? b : '.',
                 isprint(c) ? c : '.',
                 isprint(d) ? d : '.',
                 dev->protocol_id,
                 dev->protocol_id);

        dmprintf("%u Propert%s\n", dev->prop_count, dev->prop_count == 1 ? "y" : "ies");
        for (uint32_t i = 0; i < dev->prop_count; ++i) {
            const zx_device_prop_t* p = dev->props + i;
            const char* param_name = di_bind_param_name(p->id);

            if (param_name) {
                dmprintf("[%2u/%2u] : Value 0x%08x Id %s\n",
                         i, dev->prop_count, p->value, param_name);
            } else {
                dmprintf("[%2u/%2u] : Value 0x%08x Id 0x%04hx\n",
                         i, dev->prop_count, p->value, p->id);
            }
        }
        dmprintf("\n");
    }

    device_t* child;
    if (dev->shadow) {
        dc_dump_device_props(dev->shadow);
    }
    list_for_every_entry(&dev->children, child, device_t, node) {
        dc_dump_device_props(child);
    }
}

static void dc_dump_devprops(void) {
    dc_dump_device_props(&root_device);
    dc_dump_device_props(&misc_device);
    dc_dump_device_props(&acpi_device);
    if (platform_device.hrsrc != ZX_HANDLE_INVALID) {
        dc_dump_device_props(&platform_device);
    }
}

static void dc_dump_drivers(void) {
    driver_t* drv;
    bool first = true;
    list_for_every_entry(&list_drivers, drv, driver_t, node) {
        dmprintf("%sName    : %s\n", first ? "" : "\n", drv->name);
        dmprintf("Driver  : %s\n", drv->libname ? drv->libname : "(null)");
        dmprintf("Flags   : 0x%08x\n", drv->flags);
        if (drv->binding_size) {
            char line[256];
            uint32_t count = drv->binding_size / sizeof(drv->binding[0]);
            dmprintf("Binding : %u instruction%s (%u bytes)\n",
                     count, (count == 1) ? "" : "s", drv->binding_size);
            for (uint32_t i = 0; i < count; ++i) {
                di_dump_bind_inst(drv->binding + i, line, sizeof(line));
                dmprintf("[%u/%u]: %s\n", i + 1, count, line);
            }
        }
        first = false;
    }
}

static void dc_handle_new_device(device_t* dev);
static void dc_handle_new_driver(void);

#define WORK_IDLE 0
#define WORK_DEVICE_ADDED 1
#define WORK_DRIVER_ADDED 2

static list_node_t list_pending_work = LIST_INITIAL_VALUE(list_pending_work);
static list_node_t list_unbound_devices = LIST_INITIAL_VALUE(list_unbound_devices);

static void queue_work(work_t* work, uint32_t op, uint32_t arg) {
    ZX_ASSERT(work->op == WORK_IDLE);
    work->op = op;
    work->arg = arg;
    list_add_tail(&list_pending_work, &work->node);
}

static void cancel_work(work_t* work) {
    if (work->op != WORK_IDLE) {
        list_delete(&work->node);
        work->op = WORK_IDLE;
    }
}

static void process_work(work_t* work) {
    uint32_t op = work->op;
    work->op = WORK_IDLE;

    switch (op) {
    case WORK_DEVICE_ADDED: {
        device_t* dev = containerof(work, device_t, work);
        dc_handle_new_device(dev);
        break;
    }
    case WORK_DRIVER_ADDED: {
        dc_handle_new_driver();
        break;
    }
    default:
        log(ERROR, "devcoord: unknown work: op=%u\n", op);
    }
}

static const char* devhost_bin = "/boot/bin/devhost";

zx_handle_t get_service_root(void);

static zx_status_t dc_get_topo_path(device_t* dev, char* out, size_t max) {
    char tmp[max];
    char* path = tmp + max - 1;
    *path = 0;
    size_t total = 1;

    while (dev != NULL) {
        if (dev->flags & DEV_CTX_SHADOW) {
            dev = dev->parent;
        }
        const char* name;

        if (dev->parent) {
            name = dev->name;
        } else if (!strcmp(misc_device.name, dev->name)) {
            name = "dev/misc";
        } else if (!strcmp(acpi_device.name, dev->name)) {
            name = "dev/acpi";
        } else {
            name = "dev";
        }
        size_t len = strlen(name) + 1;
        if (len > (max - total)) {
            return ZX_ERR_BUFFER_TOO_SMALL;
        }
        memcpy(path - len + 1, name, len - 1);
        path -= len;
        *path = '/';
        total += len;
        dev = dev->parent;
    }

    memcpy(out, path, total);
    return ZX_OK;
}

//TODO: use a better device identifier
static zx_status_t dc_notify(device_t* dev, uint32_t op) {
    if (dc_watch_channel == ZX_HANDLE_INVALID) {
        return ZX_ERR_BAD_STATE;
    }
    zx_status_t r;
    if (op == DEVMGR_OP_DEVICE_ADDED) {
        size_t propslen = sizeof(zx_device_prop_t) * dev->prop_count;
        size_t len = sizeof(devmgr_event_t) + propslen;
        char msg[len + DC_PATH_MAX];
        devmgr_event_t* evt = (void*) msg;
        memset(evt, 0, sizeof(devmgr_event_t));
        memcpy(msg + sizeof(devmgr_event_t), dev->props, propslen);
        if (dc_get_topo_path(dev, msg + len, DC_PATH_MAX) < 0) {
            return ZX_OK;
        }
        size_t pathlen = strlen(msg + len);
        len += pathlen;
        evt->opcode = op;
        if (dev->flags & DEV_CTX_BOUND) {
            evt->flags |= DEVMGR_FLAGS_BOUND;
        }
        evt->id = (uintptr_t) dev;
        evt->u.add.protocol_id = dev->protocol_id;
        evt->u.add.props_len = propslen;
        evt->u.add.path_len = pathlen;
        r = zx_channel_write(dc_watch_channel, 0, msg, len, NULL, 0);
    } else {
        devmgr_event_t evt;
        memset(&evt, 0, sizeof(evt));
        evt.opcode = op;
        if (dev->flags & DEV_CTX_BOUND) {
            evt.flags |= DEVMGR_FLAGS_BOUND;
        }
        evt.id = (uintptr_t) dev;
        r = zx_channel_write(dc_watch_channel, 0, &evt, sizeof(evt), NULL, 0);
    }
    if (r < 0) {
        zx_handle_close(dc_watch_channel);
        dc_watch_channel = ZX_HANDLE_INVALID;
    }
    return r;
}

static void dc_watch(zx_handle_t h) {
    if (dc_watch_channel != ZX_HANDLE_INVALID) {
        zx_handle_close(dc_watch_channel);
    }
    dc_watch_channel = h;
    device_t* dev;
    list_for_every_entry(&list_devices, dev, device_t, anode) {
        if (dev->flags & (DEV_CTX_DEAD | DEV_CTX_ZOMBIE)) {
            // if device is dead, ignore it
            continue;
        }
        if (dc_notify(dev, DEVMGR_OP_DEVICE_ADDED) < 0) {
            break;
        }
    }
}

static zx_status_t dc_launch_devhost(devhost_t* host,
                                     const char* name, zx_handle_t hrpc) {
    launchpad_t* lp;
    launchpad_create_with_jobs(devhost_job, 0, name, &lp);
    launchpad_load_from_file(lp, devhost_bin);
    launchpad_set_args(lp, 1, &devhost_bin);

    launchpad_add_handle(lp, hrpc, PA_HND(PA_USER0, 0));

    zx_handle_t h;
    //TODO: limit root resource to root devhost only
    zx_handle_duplicate(get_root_resource(), ZX_RIGHT_SAME_RIGHTS, &h);
    launchpad_add_handle(lp, h, PA_HND(PA_RESOURCE, 0));

    // Inherit devmgr's environment (including kernel cmdline)
    launchpad_clone(lp, LP_CLONE_ENVIRON);

    const char* nametable[2] = { "/", "/svc", };
    size_t name_count = 0;

    //TODO: eventually devhosts should not have vfs access
    launchpad_add_handle(lp, vfs_create_global_root_handle(),
                         PA_HND(PA_NS_DIR, name_count++));

    //TODO: constrain to /svc/device
    if ((h = get_service_root()) != ZX_HANDLE_INVALID) {
        launchpad_add_handle(lp, h, PA_HND(PA_NS_DIR, name_count++));
    }

    launchpad_set_nametable(lp, name_count, nametable);

    //TODO: limit root job access to root devhost only
    launchpad_add_handle(lp, get_sysinfo_job_root(),
                         PA_HND(PA_USER0, ID_HJOBROOT));

    //TODO: pass a channel to the acpi devhost to rpc with
    //      devcoordinator, so it can call reboot/poweroff/ps0.
    //      come up with a better way to wire this up.
    if (!strcmp(name, "devhost:acpi")) {
        launchpad_add_handle(lp, acpi_rpc[1], PA_HND(PA_USER0, 10));
    }

    const char* errmsg;
    zx_status_t status = launchpad_go(lp, &host->proc, &errmsg);
    if (status < 0) {
        log(ERROR, "devcoord: launch devhost '%s': failed: %d: %s\n",
            name, status, errmsg);
        return status;
    }
    zx_info_handle_basic_t info;
    if (zx_object_get_info(host->proc, ZX_INFO_HANDLE_BASIC, &info,
                           sizeof(info), NULL, NULL) == ZX_OK) {
        host->koid = info.koid;
    }
    log(INFO, "devcoord: launch devhost '%s': pid=%zu\n",
        name, host->koid);

    return ZX_OK;
}

static zx_status_t dc_new_devhost(const char* name, devhost_t** out) {
    devhost_t* dh = calloc(1, sizeof(devhost_t));
    if (dh == NULL) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_handle_t hrpc;
    zx_status_t r;
    if ((r = zx_channel_create(0, &hrpc, &dh->hrpc)) < 0) {
        free(dh);
        return r;
    }

    if ((r = dc_launch_devhost(dh, name, hrpc)) < 0) {
        zx_handle_close(dh->hrpc);
        free(dh);
        return r;
    }

    list_initialize(&dh->devices);

    *out = dh;
    return ZX_OK;
}

static void dc_release_devhost(devhost_t* dh) {
    log(DEVLC, "devcoord: release host %p\n", dh);
    dh->refcount--;
    if (dh->refcount > 0) {
        return;
    }
    log(INFO, "devcoord: destroy host %p\n", dh);
    zx_handle_close(dh->hrpc);
    zx_task_kill(dh->proc);
    zx_handle_close(dh->proc);
    free(dh);
}

// called when device children or shadows are removed
static void dc_release_device(device_t* dev) {
    log(DEVLC, "devcoord: release dev %p name='%s' ref=%d\n", dev, dev->name, dev->refcount);

    dev->refcount--;
    if (dev->refcount > 0) {
        return;
    }

    // Immortal devices are never destroyed
    if (dev->flags & DEV_CTX_IMMORTAL) {
        return;
    }

    log(DEVLC, "devcoord: destroy dev %p name='%s'\n", dev, dev->name);

    devfs_unpublish(dev);

    if (dev->hrpc != ZX_HANDLE_INVALID) {
        zx_handle_close(dev->hrpc);
        dev->hrpc = ZX_HANDLE_INVALID;
        dev->ph.handle = ZX_HANDLE_INVALID;
    }
    if (dev->hrsrc != ZX_HANDLE_INVALID) {
        zx_handle_close(dev->hrsrc);
        dev->hrsrc = ZX_HANDLE_INVALID;
    }
    dev->host = NULL;

    cancel_work(&dev->work);

    //TODO: cancel any pending rpc responses
    free(dev);
}

// Add a new device to a parent device (same devhost)
// New device is published in devfs.
// Caller closes handles on error, so we don't have to.
static zx_status_t dc_add_device(device_t* parent,
                                 zx_handle_t* handle, size_t hcount,
                                 dc_msg_t* msg, const char* name,
                                 const char* args, const void* data) {
    if (hcount == 0) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (msg->datalen % sizeof(zx_device_prop_t)) {
        return ZX_ERR_INVALID_ARGS;
    }
    device_t* dev;
    // allocate device struct, followed by space for props, followed
    // by space for bus arguments, followed by space for the name
    size_t sz = sizeof(*dev) + msg->datalen + msg->argslen + msg->namelen + 2;
    if ((dev = calloc(1, sz)) == NULL) {
        return ZX_ERR_NO_MEMORY;
    }
    list_initialize(&dev->children);
    list_initialize(&dev->pending);
    dev->hrpc = handle[0];
    dev->hrsrc = (hcount > 1) ? handle[1] : ZX_HANDLE_INVALID;
    dev->prop_count = msg->datalen / sizeof(zx_device_prop_t);
    dev->protocol_id = msg->protocol_id;

    char* text = (char*) (dev->props + dev->prop_count);
    memcpy(text, args, msg->argslen + 1);
    dev->args = text;

    text += msg->argslen + 1;
    memcpy(text, name, msg->namelen + 1);

    char* text2 = strchr(text, ',');
    if (text2 != NULL) {
        *text2++ = 0;
        dev->name = text2;
        dev->libname = text;
    } else {
        dev->name = text;
        dev->libname = "";
    }

    memcpy(dev->props, data, msg->datalen);

    if (strlen(dev->name) > ZX_DEVICE_NAME_MAX) {
        free(dev);
        return ZX_ERR_INVALID_ARGS;
    }

    // If we have bus device args or resource handle
    // we are, by definition a bus device.
    if (args[0] || (dev->hrsrc != ZX_HANDLE_INVALID)) {
        dev->flags |= DEV_CTX_BUSDEV;
    }

    // We exist within our parent's device host
    dev->host = parent->host;

    // If our parent is a shadow, for the purpose
    // of devicefs, we need to work with *its* parent
    // which is the device that it is shadowing.
    if (parent->flags & DEV_CTX_SHADOW) {
        parent = parent->parent;
    }

    zx_status_t r;
    if ((r = devfs_publish(parent, dev)) < 0) {
        free(dev);
        return r;
    }

    dev->ph.handle = handle[0];
    dev->ph.waitfor = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
    dev->ph.func = dc_handle_device;
    if ((r = port_wait(&dc_port, &dev->ph)) < 0) {
        devfs_unpublish(dev);
        free(dev);
        return r;
    }

    if (dev->host) {
        //TODO host == NULL should be impossible
        dev->host->refcount++;
        list_add_tail(&dev->host->devices, &dev->dhnode);
    }
    dev->refcount = 1;
    dev->parent = parent;
    list_add_tail(&parent->children, &dev->node);
    parent->refcount++;

    list_add_tail(&list_devices, &dev->anode);

    log(DEVLC, "devcoord: dev %p name='%s' ++ref=%d (child)\n",
        parent, parent->name, parent->refcount);

    log(DEVLC, "devcoord: publish %p '%s' props=%u args='%s' parent=%p\n",
        dev, dev->name, dev->prop_count, dev->args, dev->parent);

    dc_notify(dev, DEVMGR_OP_DEVICE_ADDED);
    queue_work(&dev->work, WORK_DEVICE_ADDED, 0);
    return ZX_OK;
}

// Remove device from parent
// forced indicates this is removal due to a channel close
// or process exit, which means we should remove all other
// devices that share the devhost at the same time
static zx_status_t dc_remove_device(device_t* dev, bool forced) {
    if (dev->flags & DEV_CTX_ZOMBIE) {
        // This device was removed due to its devhost dying
        // (process exit or some other channel on that devhost
        // closing), and is now receiving the final remove call
        dev->flags &= (~DEV_CTX_ZOMBIE);
        dc_release_device(dev);
        return ZX_OK;
    }
    if (dev->flags & DEV_CTX_DEAD) {
        // This should not happen
        log(ERROR, "devcoord: cannot remove dev %p name='%s' twice!\n", dev, dev->name);
        return ZX_ERR_BAD_STATE;
    }
    if (dev->flags & DEV_CTX_IMMORTAL) {
        // This too should not happen
        log(ERROR, "devcoord: cannot remove dev %p name='%s' (immortal)\n", dev, dev->name);
        return ZX_ERR_BAD_STATE;
    }

    log(DEVLC, "devcoord: remove %p name='%s' parent=%p\n", dev, dev->name, dev->parent);
    dev->flags |= DEV_CTX_DEAD;

    // remove from devfs, preventing further OPEN attempts
    devfs_unpublish(dev);

    // detach from devhost
    devhost_t* dh = dev->host;
    if (dh != NULL) {
        dev->host = NULL;
        list_delete(&dev->dhnode);

        // If we are responding to a disconnect,
        // we'll remove all the other devices on this devhost too.
        // A side-effect of this is that the devhost will be released,
        // as well as any shadow devices.
        if (forced) {
            dh->flags |= DEV_HOST_DYING;

            device_t* next;
            device_t* last = NULL;
            while ((next = list_peek_head_type(&dh->devices, device_t, dhnode)) != NULL) {
                if (last == next) {
                    // This shouldn't be possbile, but let's not infinite-loop if it happens
                    log(ERROR, "devcoord: fatal: failed to remove dev %p from devhost\n", next);
                    exit(1);
                }
                dc_remove_device(next, false);
                last = next;
            }

            //TODO: set a timer so if this devhost does not finish dying
            //      in a reasonable amount of time, we fix the glitch.
        }

        dc_release_devhost(dh);
    }

    // if we have a parent, disconnect and downref it
    device_t* parent = dev->parent;
    if (parent != NULL) {
        dev->parent = NULL;
        if (dev->flags & DEV_CTX_SHADOW) {
            parent->shadow = NULL;
        } else {
            list_delete(&dev->node);
            if (list_is_empty(&parent->children)) {
                parent->flags &= (~DEV_CTX_BOUND);

                //TODO: This code is to cause the bind process to
                //      restart and get a new devhost to be launched
                //      when a devhost dies.  It should probably be
                //      more tied to devhost teardown than it is.

                // IF we are the last child of our parent
                // AND our parent is not itself dead
                // AND our parent is a BUSDEV
                // AND our parent's devhost is not dying
                // THEN we will want to rebind our parent
                if (!(parent->flags & DEV_CTX_DEAD) && (parent->flags & DEV_CTX_BUSDEV) &&
                    ((parent->host == NULL) || !(parent->host->flags & DEV_HOST_DYING))) {

                    log(DEVLC, "devcoord: bus device %p name='%s' is unbound\n",
                        parent, parent->name);

                    //TODO: introduce timeout, exponential backoff
                    queue_work(&parent->work, WORK_DEVICE_ADDED, 0);
                }
            }
        }
        dc_release_device(parent);
    }

    if (!(dev->flags & DEV_CTX_SHADOW)) {
        // remove from list of all devices
        list_delete(&dev->anode);
        dc_notify(dev, DEVMGR_OP_DEVICE_REMOVED);
    }

    if (forced) {
        // release the ref held by the devhost
        dc_release_device(dev);
    } else {
        // Mark the device as a zombie but don't drop the
        // (likely) final reference.  The caller needs to
        // finish replying to the RPC and dropping the
        // reference would close the RPC channel.
        dev->flags |= DEV_CTX_ZOMBIE;
    }
    return ZX_OK;
}

static zx_status_t dc_bind_device(device_t* dev, const char* drvlibname) {
     log(INFO, "devcoord: dc_bind_device() '%s'\n", drvlibname);

    // shouldn't be possible to get a bind request for a shadow device
    if (dev->flags & DEV_CTX_SHADOW) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // A libname of "" means a general rebind request
    // instead of a specific request
    bool autobind = (drvlibname[0] == 0);

    //TODO: disallow if we're in the middle of enumeration, etc
    driver_t* drv;
    list_for_every_entry(&list_drivers, drv, driver_t, node) {
        if (autobind || !strcmp(drv->libname, drvlibname)) {
            if (dc_is_bindable(drv, dev->protocol_id,
                               dev->props, dev->prop_count, autobind)) {
                log(SPEW, "devcoord: drv='%s' bindable to dev='%s'\n",
                    drv->name, dev->name);
                dc_attempt_bind(drv, dev);
                break;
            }
        }
    }

    return ZX_OK;
};

static zx_status_t dc_handle_device_read(device_t* dev) {
    dc_msg_t msg;
    zx_handle_t hin[2];
    uint32_t msize = sizeof(msg);
    uint32_t hcount = 2;

    if (dev->flags & DEV_CTX_DEAD) {
        log(ERROR, "devcoord: dev %p already dead (in read)\n", dev);
        return ZX_ERR_INTERNAL;
    }

    zx_status_t r;
    if ((r = zx_channel_read(dev->hrpc, 0, &msg, hin,
                             msize, hcount, &msize, &hcount)) < 0) {
        return r;
    }

    const void* data;
    const char* name;
    const char* args;
    if ((r = dc_msg_unpack(&msg, msize, &data, &name, &args)) < 0) {
        while (hcount > 0) {
            zx_handle_close(hin[--hcount]);
        }
        return ZX_ERR_INTERNAL;
    }

    dc_status_t dcs;
    dcs.txid = msg.txid;

    switch (msg.op) {
    case DC_OP_ADD_DEVICE:
        log(RPC_IN, "devcoord: rpc: add-device '%s' args='%s'\n", name, args);
        if ((r = dc_add_device(dev, hin, hcount, &msg, name, args, data)) < 0) {
            while (hcount > 0) {
                zx_handle_close(hin[--hcount]);
            }
        }
        break;

    case DC_OP_REMOVE_DEVICE:
        if (hcount != 0) {
            goto fail_wrong_hcount;
        }
        log(RPC_IN, "devcoord: rpc: remove-device '%s'\n", dev->name);
        dc_remove_device(dev, false);
        goto disconnect;

    case DC_OP_BIND_DEVICE:
        if (hcount != 0) {
            goto fail_wrong_hcount;
        }
        log(RPC_IN, "devcoord: rpc: bind-device '%s'\n", dev->name);
        r = dc_bind_device(dev, args);
        break;

    case DC_OP_DM_COMMAND:
        if (hcount > 1) {
            goto fail_wrong_hcount;
        }
        if (hcount == 1) {
            dmctl_socket = hin[0];
        }
        r = handle_dmctl_write(msg.datalen, data);
        if (dmctl_socket != ZX_HANDLE_INVALID) {
            zx_handle_close(dmctl_socket);
            dmctl_socket = ZX_HANDLE_INVALID;
        }
        break;

    case DC_OP_DM_OPEN_VIRTCON:
        if (hcount != 1) {
            goto fail_wrong_hcount;
        }
        if (zx_channel_write(virtcon_open, 0, NULL, 0, hin, 1) < 0) {
            zx_handle_close(hin[0]);
        }
        r = ZX_OK;
        break;

    case DC_OP_DM_WATCH:
        if (hcount != 1) {
            goto fail_wrong_hcount;
        }
        dc_watch(hin[0]);
        r = ZX_OK;
        break;

    case DC_OP_GET_TOPO_PATH: {
        if (hcount != 0) {
            goto fail_wrong_hcount;
        }
        struct {
            dc_status_t rsp;
            char path[DC_PATH_MAX];
        } reply;
        if ((r = dc_get_topo_path(dev, reply.path, DC_PATH_MAX)) < 0) {
            break;
        }
        reply.rsp.status = ZX_OK;
        reply.rsp.txid = msg.txid;
        if ((r = zx_channel_write(dev->hrpc, 0, &reply, sizeof(reply), NULL, 0)) < 0) {
            return r;
        }
        return ZX_OK;
    }
    case DC_OP_STATUS: {
        if (hcount != 0) {
            goto fail_wrong_hcount;
        }
        // all of these return directly and do not write a
        // reply, since this message is a reply itself
        pending_t* pending = list_remove_tail_type(&dev->pending, pending_t, node);
        if (pending == NULL) {
            log(ERROR, "devcoord: rpc: spurious status message\n");
            return ZX_OK;
        }
        switch (pending->op) {
        case PENDING_BIND:
            if (msg.status != ZX_OK) {
                log(ERROR, "devcoord: rpc: bind-driver '%s' status %d\n",
                    dev->name, msg.status);
            } else {
                dc_notify(dev, DEVMGR_OP_DEVICE_CHANGED);
            }
            //TODO: try next driver, clear BOUND flag
            break;
        }
        free(pending);
        return ZX_OK;
    }

    default:
        log(ERROR, "devcoord: invalid rpc op %08x\n", msg.op);
        r = ZX_ERR_NOT_SUPPORTED;
        goto fail_close_handles;
    }

done:
    dcs.status = r;
    if ((r = zx_channel_write(dev->hrpc, 0, &dcs, sizeof(dcs), NULL, 0)) < 0) {
        return r;
    }
    return ZX_OK;

disconnect:
    dcs.status = ZX_OK;
    zx_channel_write(dev->hrpc, 0, &dcs, sizeof(dcs), NULL, 0);
    return ZX_ERR_STOP;

fail_wrong_hcount:
    r = ZX_ERR_INVALID_ARGS;
fail_close_handles:
    while (hcount > 0) {
        zx_handle_close(hin[--hcount]);
    }
    goto done;
}

#define dev_from_ph(ph) containerof(ph, device_t, ph)

// handle inbound RPCs from devhost to devices
static zx_status_t dc_handle_device(port_handler_t* ph, zx_signals_t signals, uint32_t evt) {
    device_t* dev = dev_from_ph(ph);

    if (signals & ZX_CHANNEL_READABLE) {
        zx_status_t r;
        if ((r = dc_handle_device_read(dev)) < 0) {
            if (r != ZX_ERR_STOP) {
                log(ERROR, "devcoord: device %p name='%s' rpc status: %d\n",
                    dev, dev->name, r);
            }
            dc_remove_device(dev, true);
            return ZX_ERR_STOP;
        }
        return ZX_OK;
    }
    if (signals & ZX_CHANNEL_PEER_CLOSED) {
        log(ERROR, "devcoord: device %p name='%s' disconnected!\n", dev, dev->name);
        dc_remove_device(dev, true);
        return ZX_ERR_STOP;
    }
    log(ERROR, "devcoord: no work? %08x\n", signals);
    return ZX_OK;
}

// send message to devhost, requesting the creation of a device
static zx_status_t dh_create_device(device_t* dev, devhost_t* dh,
                                    const char* args) {
    dc_msg_t msg;
    uint32_t mlen;
    zx_status_t r;

    // Where to get information to send to devhost from?
    // Shadow devices defer to the device they're shadowing,
    // otherwise we use the information from the device itself.
    device_t* info = (dev->flags & DEV_CTX_SHADOW) ? dev->parent : dev;
    const char* libname = info->libname;

    if ((r = dc_msg_pack(&msg, &mlen, NULL, 0, libname, args)) < 0) {
        return r;
    }

    uint32_t hcount = 0;
    zx_handle_t handle[3], hrpc;
    if ((r = zx_channel_create(0, handle, &hrpc)) < 0) {
        return r;
    }
    hcount++;

    if (libname[0]) {
        if ((r = libname_to_vmo(libname, handle + 1)) < 0) {
            goto fail;
        }
        hcount++;
        msg.op = DC_OP_CREATE_DEVICE;
    } else {
        msg.op = DC_OP_CREATE_DEVICE_STUB;
    }

    if (info->hrsrc != ZX_HANDLE_INVALID) {
        if ((r = zx_handle_duplicate(info->hrsrc, ZX_RIGHT_SAME_RIGHTS, handle + hcount)) < 0) {
            goto fail;
        }
        hcount++;
    }

    msg.txid = 0;
    msg.protocol_id = dev->protocol_id;

    if ((r = zx_channel_write(dh->hrpc, 0, &msg, mlen, handle, hcount)) < 0) {
        goto fail;
    }

    dev->hrpc = hrpc;
    dev->ph.handle = hrpc;
    dev->ph.waitfor = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
    dev->ph.func = dc_handle_device;
    if ((r = port_wait(&dc_port, &dev->ph)) < 0) {
        goto fail_watch;
    }
    dev->host = dh;
    dh->refcount++;
    list_add_tail(&dh->devices, &dev->dhnode);
    return ZX_OK;

fail:
    while (hcount > 0) {
        zx_handle_close(handle[--hcount]);
    }
fail_watch:
    zx_handle_close(hrpc);
    return r;
}

static zx_status_t dc_create_shadow(device_t* parent) {
    if (parent->shadow != NULL) {
        return ZX_OK;
    }

    size_t namelen = strlen(parent->name);
    size_t liblen = strlen(parent->libname);
    device_t* dev = calloc(1, sizeof(device_t) + namelen + liblen + 2);
    if (dev == NULL) {
        return ZX_ERR_NO_MEMORY;
    }
    char* text = (char*) (dev + 1);
    memcpy(text, parent->name, namelen + 1);
    dev->name = text;
    text += namelen + 1;
    memcpy(text, parent->libname, liblen + 1);
    dev->libname = text;

    list_initialize(&dev->children);
    list_initialize(&dev->pending);
    dev->flags = DEV_CTX_SHADOW;
    dev->protocol_id = parent->protocol_id;
    dev->parent = parent;
    dev->refcount = 1;
    parent->shadow = dev;
    parent->refcount++;
    log(DEVLC, "devcoord: dev %p name='%s' ++ref=%d (shadow)\n",
        parent, parent->name, parent->refcount);
    return ZX_OK;
}

// send message to devhost, requesting the binding of a driver to a device
static zx_status_t dh_bind_driver(device_t* dev, const char* libname) {
    dc_msg_t msg;
    uint32_t mlen;

    pending_t* pending = malloc(sizeof(pending_t));
    if (pending == NULL) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_status_t r;
    if ((r = dc_msg_pack(&msg, &mlen, NULL, 0, libname, NULL)) < 0) {
        free(pending);
        return r;
    }

    zx_handle_t vmo;
    if ((r = libname_to_vmo(libname, &vmo)) < 0) {
        free(pending);
        return r;
    }

    msg.txid = 0;
    msg.op = DC_OP_BIND_DRIVER;

    if ((r = zx_channel_write(dev->hrpc, 0, &msg, mlen, &vmo, 1)) < 0) {
        free(pending);
        return r;
    }

    dev->flags |= DEV_CTX_BOUND;
    pending->op = PENDING_BIND;
    pending->ctx = NULL;
    list_add_tail(&dev->pending, &pending->node);
    return ZX_OK;
}

static zx_status_t dc_attempt_bind(driver_t* drv, device_t* dev) {
    // cannot bind driver to already bound device
    if ((dev->flags & DEV_CTX_BOUND) && (!(dev->flags & DEV_CTX_MULTI_BIND))) {
        return ZX_ERR_BAD_STATE;
    }
    if (!(dev->flags & DEV_CTX_BUSDEV)) {
        // non-busdev is pretty simple
        if (dev->host == NULL) {
            log(ERROR, "devcoord: can't bind to device without devhost\n");
            return ZX_ERR_BAD_STATE;
        }
        return dh_bind_driver(dev, drv->libname);
    }

    // busdev args are "processname,args"
    const char* arg0 = (dev->flags & DEV_CTX_SHADOW) ? dev->parent->args : dev->args;
    const char* arg1 = strchr(arg0, ',');
    if (arg1 == NULL) {
        return ZX_ERR_INTERNAL;
    }
    size_t arg0len = arg1 - arg0;
    arg1++;

    char devhostname[32];
    snprintf(devhostname, sizeof(devhostname), "devhost:%.*s", (int) arg0len, arg0);

    zx_status_t r;
    if ((r = dc_create_shadow(dev)) < 0) {
        log(ERROR, "devcoord: cannot create shadow device: %d\n", r);
        return r;
    }

    // if this device has no devhost, first instantiate it
    if (dev->shadow->host == NULL) {
        if ((r = dc_new_devhost(devhostname, &dev->shadow->host)) < 0) {
            log(ERROR, "devcoord: dh_new_devhost: %d\n", r);
            return r;
        }
        if ((r = dh_create_device(dev->shadow, dev->shadow->host, arg1)) < 0) {
            log(ERROR, "devcoord: dh_create_device: %d\n", r);
            return r;
        }
    }

    return dh_bind_driver(dev->shadow, drv->libname);
}

static void dc_handle_new_device(device_t* dev) {
    driver_t* drv;

    list_for_every_entry(&list_drivers, drv, driver_t, node) {
        if (dc_is_bindable(drv, dev->protocol_id,
                           dev->props, dev->prop_count, true)) {
            log(SPEW, "devcoord: drv='%s' bindable to dev='%s'\n",
                drv->name, dev->name);

            dc_attempt_bind(drv, dev);
            if (!(dev->flags & DEV_CTX_MULTI_BIND)) {
                break;
            }
        }
    }
}

// device binding program that pure (parentless)
// misc devices use to get published in the misc devhost
static struct zx_bind_inst misc_device_binding =
    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_MISC_PARENT);

static bool is_misc_driver(driver_t* drv) {
    return (drv->binding_size == sizeof(misc_device_binding)) &&
        (memcmp(&misc_device_binding, drv->binding, sizeof(misc_device_binding)) == 0);
}

// device binding program that special root-level
// devices use to get published in the root devhost
static struct zx_bind_inst root_device_binding =
    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_ROOT);

static bool is_root_driver(driver_t* drv) {
    return (drv->binding_size == sizeof(root_device_binding)) &&
        (memcmp(&root_device_binding, drv->binding, sizeof(root_device_binding)) == 0);
}

static bool is_acpi_bus_driver(driver_t* drv) {
    // only our built-in acpi driver should bind as acpi bus
    // so compare library path instead of binding program
    return !strcmp(drv->libname, "/boot/driver/bus-acpi.so");
}

static bool is_platform_bus_driver(driver_t* drv) {
    // only our built-in platform-bus driver should bind as platform bus
    // so compare library path instead of binding program
    return !strcmp(drv->libname, "/boot/driver/platform-bus.so");
}

static work_t new_driver_work;

void dc_driver_added(driver_t* drv, const char* version) {
    if (dc_running) {
        list_add_head(&list_drivers_new, &drv->node);
        if (new_driver_work.op == WORK_IDLE) {
            queue_work(&new_driver_work, WORK_DRIVER_ADDED, 0);
        }
        return;
    }
    if (version[0] == '!') {
        // debugging / development hack
        // prioritize drivers with version "!..." over others
        list_add_head(&list_drivers, &drv->node);
    } else {
        list_add_tail(&list_drivers, &drv->node);
    }
}

device_t* coordinator_init(zx_handle_t root_job) {
    printf("coordinator_init()\n");

    zx_status_t status = zx_job_create(root_job, 0u, &devhost_job);
    if (status < 0) {
        log(ERROR, "devcoord: unable to create devhost job\n");
    }
    static const zx_policy_basic_t policy[] = {
        { ZX_POL_BAD_HANDLE, ZX_POL_ACTION_EXCEPTION },
    };
    status = zx_job_set_policy(devhost_job, ZX_JOB_POL_RELATIVE,
                               ZX_JOB_POL_BASIC, &policy, countof(policy));
    if (status < 0) {
        log(ERROR, "devcoord: zx_job_set_policy() failed\n");
    }
    zx_object_set_property(devhost_job, ZX_PROP_NAME, "zircon-drivers", 15);

    port_init(&dc_port);

    return &root_device;
}

//TODO: The acpisvc needs to become the acpi bus device
//      For now, we launch it manually here so PCI can work
static void acpi_init(void) {
    zx_status_t status = zx_channel_create(0, &acpi_rpc[0], &acpi_rpc[1]);
    if (status != ZX_OK) {
        return;
    }
    devhost_acpi_set_rpc(acpi_rpc[0]);
}

void dc_bind_driver(driver_t* drv) {
    if (dc_running) {
        printf("devcoord: driver '%s' added\n", drv->name);
    }
    if (is_root_driver(drv)) {
        dc_attempt_bind(drv, &root_device);
    } else if (is_misc_driver(drv)) {
        dc_attempt_bind(drv, &misc_device);
    } else if (is_acpi_bus_driver(drv)) {
        dc_attempt_bind(drv, &acpi_device);
    } else if (is_platform_bus_driver(drv) &&
               (platform_device.hrsrc != ZX_HANDLE_INVALID)) {
        dc_attempt_bind(drv, &platform_device);
    } else if (dc_running) {
        device_t* dev;
        list_for_every_entry(&list_devices, dev, device_t, anode) {
            if (dev->flags & (DEV_CTX_BOUND | DEV_CTX_DEAD | DEV_CTX_ZOMBIE)) {
                // if device is already bound or being destroyed, skip it
                continue;
            }
            if (dc_is_bindable(drv, dev->protocol_id,
                               dev->props, dev->prop_count, true)) {
                log(INFO, "devcoord: drv='%s' bindable to dev='%s'\n",
                    drv->name, dev->name);

                dc_attempt_bind(drv, dev);
            }
        }
    }
}

void dc_handle_new_driver(void) {
    driver_t* drv;
    while ((drv = list_remove_head_type(&list_drivers_new, driver_t, node)) != NULL) {
        list_add_tail(&list_drivers, &drv->node);
        dc_bind_driver(drv);
    }
}

#define CTL_SCAN_SYSTEM 1

static bool system_available;
static bool system_loaded;

static zx_status_t dc_control_event(port_handler_t* ph, zx_signals_t signals, uint32_t evt) {
    switch (evt) {
    case CTL_SCAN_SYSTEM:
        if (!system_loaded) {
            system_loaded = true;
            find_loadable_drivers("/system/driver");
            find_loadable_drivers("/system/lib/driver");
        }
        break;
    }
    return ZX_OK;
}

static port_handler_t control_handler = {
    .func = dc_control_event,
};


void load_system_drivers(void) {
    system_available = true;
    port_queue(&dc_port, &control_handler, CTL_SCAN_SYSTEM);
}

void coordinator(void) {
    log(INFO, "devmgr: coordinator()\n");

    if (getenv_bool("devmgr.verbose", false)) {
        log_flags |= LOG_DEVLC;
    }

// TODO(MG-1074): Conditionally initialize ACPI if it is present.
#if defined(__x86_64__)
    acpi_init();
#endif

    devfs_publish(&root_device, &misc_device);
    devfs_publish(&root_device, &socket_device);
    devfs_publish(&root_device, &acpi_device);
    if (platform_device.hrsrc != ZX_HANDLE_INVALID) {
        devfs_publish(&root_device, &platform_device);
    }

    find_loadable_drivers("/boot/driver");
    find_loadable_drivers("/boot/driver/test");
    find_loadable_drivers("/boot/lib/driver");

    // Special case early handling for the ramdisk boot
    // path where /system is present before the coordinator
    // starts.  This avoids breaking the "priority hack" and
    // can be removed once the real driver priority system
    // exists.
    if (system_available) {
        dc_control_event(&control_handler, 0, CTL_SCAN_SYSTEM);
    }

    driver_t* drv;
    list_for_every_entry(&list_drivers, drv, driver_t, node) {
        dc_bind_driver(drv);
    }

    dc_running = true;

    for (;;) {
        zx_status_t status;
        if (list_is_empty(&list_pending_work)) {
            status = port_dispatch(&dc_port, ZX_TIME_INFINITE, true);
        } else {
            status = port_dispatch(&dc_port, 0, true);
            if (status == ZX_ERR_TIMED_OUT) {
                process_work(list_remove_head_type(&list_pending_work, work_t, node));
                continue;
            }
        }
        if (status != ZX_OK) {
            log(ERROR, "devcoord: port dispatch ended: %d\n", status);
        }
    }
}
