blob: eb23b857b4d57ac43a1b20e2d01877645c66abcb [file] [log] [blame]
// 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.
#pragma once
#include <stdint.h>
#include <ddk/binding.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <zircon/types.h>
#include <zircon/listnode.h>
#include <port/port.h>
typedef struct dc_work work_t;
typedef struct dc_pending pending_t;
typedef struct dc_devhost devhost_t;
typedef struct dc_device device_t;
typedef struct dc_driver driver_t;
typedef struct dc_devnode devnode_t;
struct dc_work {
list_node_t node;
uint32_t op;
uint32_t arg;
void* ptr;
};
struct dc_pending {
list_node_t node;
void* ctx;
uint32_t op;
};
#define PENDING_BIND 1
struct dc_devhost {
port_handler_t ph;
zx_handle_t hrpc;
zx_handle_t proc;
zx_koid_t koid;
int32_t refcount;
uint32_t flags;
// list of all devices on this devhost
list_node_t devices;
};
#define DEV_HOST_DYING 1
struct dc_device {
zx_handle_t hrpc;
zx_handle_t hrsrc;
port_handler_t ph;
devhost_t* host;
const char* name;
const char* libname;
const char* args;
work_t work;
uint32_t flags;
int32_t refcount;
uint32_t protocol_id;
uint32_t prop_count;
devnode_t* self;
devnode_t* link;
device_t* parent;
device_t* shadow;
// listnode for this device in its parent's
// list-of-children
list_node_t node;
// listnode for this device in its devhost's
// list-of-devices
list_node_t dhnode;
// list of all child devices of this device
list_node_t children;
// list of outstanding requests from the devcoord
// to this device's devhost, awaiting a response
list_node_t pending;
// listnode for this device in the all devices list
list_node_t anode;
zx_device_prop_t props[];
};
// This device is never destroyed
#define DEV_CTX_IMMORTAL 0x01
// This device is a bus device
// (a devhost will be created to contain its children)
#define DEV_CTX_BUSDEV 0x02
// This device may be bound multiple times
#define DEV_CTX_MULTI_BIND 0x04
// This device is bound and not eligible for binding
// again until unbound. Not allowed on MULTI_BIND ctx.
#define DEV_CTX_BOUND 0x08
// Device has been remove()'d
#define DEV_CTX_DEAD 0x10
// Device has been removed but its rpc channel is not
// torn down yet. The rpc transport will call remove
// when it notices at which point the device will leave
// the zombie state and drop the reference associated
// with the rpc channel, allowing complete destruction.
#define DEV_CTX_ZOMBIE 0x20
#define DEV_CTX_SHADOW 0x40
struct dc_driver {
const char* name;
const zx_bind_inst_t* binding;
uint32_t binding_size;
uint32_t flags;
struct list_node node;
const char* libname;
};
#define DRIVER_NAME_LEN_MAX 64
zx_status_t devfs_publish(device_t* parent, device_t* dev);
void devfs_unpublish(device_t* dev);
device_t* coordinator_init(zx_handle_t root_job);
void coordinator(void);
void dc_driver_added(driver_t* drv, const char* version);
void load_driver(const char* path);
void find_loadable_drivers(const char* path);
bool dc_is_bindable(driver_t* drv, uint32_t protocol_id,
zx_device_prop_t* props, size_t prop_count,
bool autobind);
#define DC_MAX_DATA 4096
// The first two fields of devcoordinator messages align
// with those of remoteio messages so we avoid needing a
// dedicated channel for forwarding OPEN operations.
// Our opcodes set the high bit to avoid overlap.
typedef struct {
zx_txid_t txid;
uint32_t op;
union {
zx_status_t status;
uint32_t protocol_id;
};
uint32_t datalen;
uint32_t namelen;
uint32_t argslen;
uint8_t data[DC_MAX_DATA];
} dc_msg_t;
typedef struct {
zx_txid_t txid;
zx_status_t status;
} dc_status_t;
// Coord->Host Ops
#define DC_OP_CREATE_DEVICE_STUB 0x80000001
#define DC_OP_CREATE_DEVICE 0x80000002
#define DC_OP_BIND_DRIVER 0x80000003
// Host->Coord Ops
#define DC_OP_STATUS 0x80000010
#define DC_OP_ADD_DEVICE 0x80000011
#define DC_OP_REMOVE_DEVICE 0x80000012
#define DC_OP_BIND_DEVICE 0x80000013
#define DC_OP_GET_TOPO_PATH 0x80000014
// Host->Coord Ops for DmCtl
#define DC_OP_DM_COMMAND 0x80000020
#define DC_OP_DM_OPEN_VIRTCON 0x80000021
#define DC_OP_DM_WATCH 0x80000022
#define DC_PATH_MAX 1024
zx_status_t dc_msg_pack(dc_msg_t* msg, uint32_t* len_out,
const void* data, size_t datalen,
const char* name, const char* args);
zx_status_t dc_msg_unpack(dc_msg_t* msg, size_t len, const void** data,
const char** name, const char** args);
zx_status_t dc_msg_rpc(zx_handle_t h, dc_msg_t* msg, size_t msglen,
zx_handle_t* handles, size_t hcount,
dc_status_t* rsp, size_t rsp_len);
void devmgr_set_mdi(zx_handle_t mdi_handle);