// 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 "hid-fifo.h"

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/hidbus.h>
#include <zircon/device/input.h>

#include <zircon/assert.h>
#include <zircon/listnode.h>

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define HID_FLAGS_DEAD         (1 << 0)
#define HID_FLAGS_WRITE_FAILED (1 << 1)

// TODO(johngro) : Get this from a standard header instead of defining our own.
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif

#define foreach_instance(base, instance) \
    list_for_every_entry(&base->instance_list, instance, hid_instance_t, node)
#define bits_to_bytes(n) (((n) + 7) / 8)

// Until we do full HID parsing, we put mouse and keyboard devices into boot
// protocol mode. In particular, a mouse will always send 3 byte reports (see
// ddk/protocol/input.h for the format). This macro sets ioctl return values for
// boot mouse devices to reflect the boot protocol, rather than what the device
// itself reports.
// TODO: update this to include keyboards if we find a keyboard in the wild that
// needs a hack as well.
#define BOOT_MOUSE_HACK 1

typedef struct hid_report_size {
    int16_t id;
    input_report_size_t in_size;
    input_report_size_t out_size;
    input_report_size_t feat_size;
} hid_report_size_t;

typedef struct hid_device {
    zx_device_t* zxdev;

    hid_info_t info;
    hidbus_protocol_t hid;

    // Reassembly buffer for input events too large to fit in a single interrupt
    // transaction.
    uint8_t* rbuf;
    size_t rbuf_size;
    size_t rbuf_filled;
    size_t rbuf_needed;

    size_t hid_report_desc_len;
    uint8_t* hid_report_desc;

    // TODO(johngro, tkilbourn: Do not hardcode this limit!)
#define HID_MAX_REPORT_IDS 32
    size_t num_reports;
    hid_report_size_t sizes[HID_MAX_REPORT_IDS];

    struct list_node instance_list;
    mtx_t instance_lock;

    char name[ZX_DEVICE_NAME_MAX + 1];
} hid_device_t;

typedef struct hid_instance {
    zx_device_t* zxdev;
    hid_device_t* base;

    uint32_t flags;

    zx_hid_fifo_t fifo;

    struct list_node node;
} hid_instance_t;

// Convenience functions for calling hidbus protocol functions

static inline zx_status_t hid_op_query(hid_device_t* hid, uint32_t options, hid_info_t* info) {
    return hid->hid.ops->query(hid->hid.ctx, options, info);
}

static inline zx_status_t hid_op_start(hid_device_t* hid, hidbus_ifc_t* ifc, void* cookie) {
    return hid->hid.ops->start(hid->hid.ctx, ifc, cookie);
}

static inline void hid_op_stop(hid_device_t* hid) {
    hid->hid.ops->stop(hid->hid.ctx);
}

static inline zx_status_t hid_op_get_descriptor(hid_device_t* hid, uint8_t desc_type,
                                                void** data, size_t* len) {
    return hid->hid.ops->get_descriptor(hid->hid.ctx, desc_type, data, len);
}

static inline zx_status_t hid_op_get_report(hid_device_t* hid, uint8_t rpt_type, uint8_t rpt_id,
                                            void* data, size_t len, size_t* out_len) {
    return hid->hid.ops->get_report(hid->hid.ctx, rpt_type, rpt_id, data, len, out_len);
}

static inline zx_status_t hid_op_set_report(hid_device_t* hid, uint8_t rpt_type, uint8_t rpt_id,
                                            void* data, size_t len) {
    return hid->hid.ops->set_report(hid->hid.ctx, rpt_type, rpt_id, data, len);
}

static inline zx_status_t hid_op_get_idle(hid_device_t* hid, uint8_t rpt_id, uint8_t* duration) {
    return hid->hid.ops->get_idle(hid->hid.ctx, rpt_id, duration);
}

static inline zx_status_t hid_op_set_idle(hid_device_t* hid, uint8_t rpt_id, uint8_t duration) {
    return hid->hid.ops->set_idle(hid->hid.ctx, rpt_id, duration);
}

static inline zx_status_t hid_op_get_protocol(hid_device_t* hid, uint8_t* protocol) {
    return hid->hid.ops->get_protocol(hid->hid.ctx, protocol);
}

static inline zx_status_t hid_op_set_protocol(hid_device_t* hid, uint8_t protocol) {
    return hid->hid.ops->set_protocol(hid->hid.ctx, protocol);
}


static input_report_size_t hid_get_report_size_by_id(hid_device_t* hid,
                                                     input_report_id_t id,
                                                     input_report_type_t type) {
    for (size_t i = 0; i < hid->num_reports; i++) {
        if ((hid->sizes[i].id == id) || (hid->num_reports == 1)) {
            switch (type) {
            case INPUT_REPORT_INPUT:
                return bits_to_bytes(hid->sizes[i].in_size);
            case INPUT_REPORT_OUTPUT:
                return bits_to_bytes(hid->sizes[i].out_size);
            case INPUT_REPORT_FEATURE:
                return bits_to_bytes(hid->sizes[i].feat_size);
            }
        }
    }

    return 0;
}

static zx_status_t hid_get_protocol(hid_device_t* hid, void* out_buf, size_t out_len,
                                    size_t* out_actual) {
    if (out_len < sizeof(int)) return ZX_ERR_INVALID_ARGS;

    int* reply = out_buf;
    *reply = INPUT_PROTO_NONE;
    if (hid->info.dev_class == HID_DEV_CLASS_KBD || hid->info.dev_class == HID_DEV_CLASS_KBD_POINTER) {
        *reply = INPUT_PROTO_KBD;
    } else if (hid->info.dev_class == HID_DEV_CLASS_POINTER) {
        *reply = INPUT_PROTO_MOUSE;
    }
    *out_actual = sizeof(*reply);
    return ZX_OK;
}

static zx_status_t hid_get_hid_desc_size(hid_device_t* hid, void* out_buf, size_t out_len,
                                         size_t* out_actual) {
    if (out_len < sizeof(size_t)) return ZX_ERR_INVALID_ARGS;

    size_t* reply = out_buf;
    *reply = hid->hid_report_desc_len;
    *out_actual = sizeof(*reply);
    return ZX_OK;
}

static zx_status_t hid_get_hid_desc(hid_device_t* hid, void* out_buf, size_t out_len,
                                    size_t* out_actual) {
    if (out_len < hid->hid_report_desc_len) return ZX_ERR_INVALID_ARGS;

    memcpy(out_buf, hid->hid_report_desc, hid->hid_report_desc_len);
    *out_actual = hid->hid_report_desc_len;
    return ZX_OK;
}

static zx_status_t hid_get_num_reports(hid_device_t* hid, void* out_buf, size_t out_len,
                                       size_t* out_actual) {
    if (out_len < sizeof(size_t)) return ZX_ERR_INVALID_ARGS;

    size_t* reply = out_buf;
    *reply = hid->num_reports;
    *out_actual = sizeof(*reply);
    return ZX_OK;
}

static zx_status_t hid_get_report_ids(hid_device_t* hid, void* out_buf, size_t out_len,
                                      size_t* out_actual) {
    if (out_len < hid->num_reports * sizeof(input_report_id_t))
        return ZX_ERR_INVALID_ARGS;

    input_report_id_t* reply = out_buf;
    for (size_t i = 0; i < hid->num_reports; i++) {
        *reply++ = (input_report_id_t)hid->sizes[i].id;
    }
    *out_actual =  hid->num_reports * sizeof(input_report_id_t);
    return ZX_OK;
}

static zx_status_t hid_get_report_size(hid_device_t* hid, const void* in_buf, size_t in_len,
                                       void* out_buf, size_t out_len, size_t* out_actual) {
    if (in_len < sizeof(input_get_report_size_t)) return ZX_ERR_INVALID_ARGS;
    if (out_len < sizeof(input_report_size_t)) return ZX_ERR_INVALID_ARGS;

    const input_get_report_size_t* inp = in_buf;

    input_report_size_t* reply = out_buf;
    *reply = hid_get_report_size_by_id(hid, inp->id, inp->type);
    if (*reply == 0) {
        return ZX_ERR_INVALID_ARGS;
    }

    *out_actual = sizeof(*reply);
    return ZX_OK;
}

static ssize_t hid_get_max_input_reportsize(hid_device_t* hid, void* out_buf, size_t out_len,
                                            size_t* out_actual) {
    if (out_len < sizeof(input_report_size_t)) return ZX_ERR_INVALID_ARGS;

    input_report_size_t* reply = out_buf;

    *reply = 0;
    for (size_t i = 0; i < hid->num_reports; i++) {
        if (hid->sizes[i].in_size > *reply)
            *reply = hid->sizes[i].in_size;
    }

    *reply = bits_to_bytes(*reply);
    *out_actual = sizeof(*reply);
    return ZX_OK;
}

static zx_status_t hid_get_report(hid_device_t* hid, const void* in_buf, size_t in_len,
                                  void* out_buf, size_t out_len, size_t* out_actual) {
    if (in_len < sizeof(input_get_report_t)) return ZX_ERR_INVALID_ARGS;
    const input_get_report_t* inp = in_buf;

    input_report_size_t needed = hid_get_report_size_by_id(hid, inp->id, inp->type);
    if (needed == 0) return ZX_ERR_INVALID_ARGS;
    if (out_len < (size_t)needed) return ZX_ERR_BUFFER_TOO_SMALL;

    return hid_op_get_report(hid, inp->type, inp->id, out_buf, out_len, out_actual);
}

static zx_status_t hid_set_report(hid_device_t* hid, const void* in_buf, size_t in_len) {

    if (in_len < sizeof(input_set_report_t)) return ZX_ERR_INVALID_ARGS;
    const input_set_report_t* inp = in_buf;

    input_report_size_t needed = hid_get_report_size_by_id(hid, inp->id, inp->type);
    if (needed == 0) return ZX_ERR_INVALID_ARGS;
    if (in_len - sizeof(input_set_report_t) < (size_t)needed) return ZX_ERR_INVALID_ARGS;

    return hid_op_set_report(hid, inp->type, inp->id, (void*)inp->data,
                             in_len - sizeof(input_set_report_t));
}


static zx_status_t hid_read_instance(void* ctx, void* buf, size_t count, zx_off_t off,
                                     size_t* actual) {
    hid_instance_t* hid = ctx;

    if (hid->flags & HID_FLAGS_DEAD) {
        return ZX_ERR_PEER_CLOSED;
    }

    size_t left;
    mtx_lock(&hid->fifo.lock);
    size_t xfer;
    uint8_t rpt_id;
    ssize_t r = zx_hid_fifo_peek(&hid->fifo, &rpt_id);
    if (r < 1) {
        // fifo is empty
        mtx_unlock(&hid->fifo.lock);
        return ZX_ERR_SHOULD_WAIT;
    }

    xfer = hid_get_report_size_by_id(hid->base, rpt_id, INPUT_REPORT_INPUT);
    if (xfer == 0) {
        zxlogf(ERROR, "error reading hid device: unknown report id (%u)!\n", rpt_id);
        mtx_unlock(&hid->fifo.lock);
        return ZX_ERR_BAD_STATE;
    }

    if (xfer > count) {
        zxlogf(SPEW, "next report: %zd, read count: %zd\n", xfer, count);
        mtx_unlock(&hid->fifo.lock);
        return ZX_ERR_BUFFER_TOO_SMALL;
    }

    r = zx_hid_fifo_read(&hid->fifo, buf, xfer);
    left = zx_hid_fifo_size(&hid->fifo);
    if (left == 0) {
        device_state_clr(hid->zxdev, DEV_STATE_READABLE);
    }
    mtx_unlock(&hid->fifo.lock);
    if (r > 0) {
        *actual = r;
        r = ZX_OK;
    } else if (r == 0) {
        r = ZX_ERR_SHOULD_WAIT;
    }
    return r;
}

static zx_status_t hid_ioctl_instance(void* ctx, uint32_t op,
        const void* in_buf, size_t in_len, void* out_buf, size_t out_len, size_t* out_actual) {
    hid_instance_t* hid = ctx;
    if (hid->flags & HID_FLAGS_DEAD) return ZX_ERR_PEER_CLOSED;

    switch (op) {
    case IOCTL_INPUT_GET_PROTOCOL:
        return hid_get_protocol(hid->base, out_buf, out_len, out_actual);
    case IOCTL_INPUT_GET_REPORT_DESC_SIZE:
        return hid_get_hid_desc_size(hid->base, out_buf, out_len, out_actual);
    case IOCTL_INPUT_GET_REPORT_DESC:
        return hid_get_hid_desc(hid->base, out_buf, out_len, out_actual);
    case IOCTL_INPUT_GET_NUM_REPORTS:
        return hid_get_num_reports(hid->base, out_buf, out_len, out_actual);
    case IOCTL_INPUT_GET_REPORT_IDS:
        return hid_get_report_ids(hid->base, out_buf, out_len, out_actual);
    case IOCTL_INPUT_GET_REPORT_SIZE:
        return hid_get_report_size(hid->base, in_buf, in_len, out_buf, out_len, out_actual);
    case IOCTL_INPUT_GET_MAX_REPORTSIZE:
        return hid_get_max_input_reportsize(hid->base, out_buf, out_len, out_actual);
    case IOCTL_INPUT_GET_REPORT:
        return hid_get_report(hid->base, in_buf, in_len, out_buf, out_len, out_actual);
    case IOCTL_INPUT_SET_REPORT:
        return hid_set_report(hid->base, in_buf, in_len);
    }
    return ZX_ERR_NOT_SUPPORTED;
}

static zx_status_t hid_close_instance(void* ctx, uint32_t flags) {
    hid_instance_t* hid = ctx;
    hid->flags |= HID_FLAGS_DEAD;
    mtx_lock(&hid->base->instance_lock);
    // TODO: refcount the base device and call stop if no instances are open
    list_delete(&hid->node);
    mtx_unlock(&hid->base->instance_lock);
    return ZX_OK;
}

static void hid_release_reassembly_buffer(hid_device_t* dev);

static void hid_release_instance(void* ctx) {
    hid_instance_t* hid = ctx;
    free(hid);
}

zx_protocol_device_t hid_instance_proto = {
    .version = DEVICE_OPS_VERSION,
    .read = hid_read_instance,
    .ioctl = hid_ioctl_instance,
    .close = hid_close_instance,
    .release = hid_release_instance,
};

enum {
    HID_ITEM_TYPE_MAIN = 0,
    HID_ITEM_TYPE_GLOBAL = 1,
    HID_ITEM_TYPE_LOCAL = 2,
};

enum {
    HID_ITEM_MAIN_TAG_INPUT = 8,
    HID_ITEM_MAIN_TAG_OUTPUT = 9,
    HID_ITEM_MAIN_TAG_FEATURE = 11,
};

enum {
    HID_ITEM_GLOBAL_TAG_REPORT_SIZE = 7,
    HID_ITEM_GLOBAL_TAG_REPORT_ID = 8,
    HID_ITEM_GLOBAL_TAG_REPORT_COUNT = 9,
    HID_ITEM_GLOBAL_TAG_PUSH = 10,
    HID_ITEM_GLOBAL_TAG_POP = 11,
};

static void hid_dump_hid_report_desc(hid_device_t* dev) {
    zxlogf(TRACE, "hid: dev %p HID report descriptor\n", dev);
    for (size_t c = 0; c < dev->hid_report_desc_len; c++) {
        zxlogf(TRACE, "%02x ", dev->hid_report_desc[c]);
        if (c % 16 == 15) zxlogf(ERROR, "\n");
    }
    zxlogf(TRACE, "\n");
    zxlogf(TRACE, "hid: num reports: %zd\n", dev->num_reports);
    for (size_t i = 0; i < dev->num_reports; i++) {
        zxlogf(TRACE, "  report id: %u  sizes: in %u out %u feat %u\n",
                dev->sizes[i].id, dev->sizes[i].in_size, dev->sizes[i].out_size,
                dev->sizes[i].feat_size);
    }
}

typedef struct hid_item {
    uint8_t bSize;
    uint8_t bType;
    uint8_t bTag;
    int64_t data;
} hid_item_t;

static const uint8_t* hid_parse_short_item(const uint8_t* buf, const uint8_t* end, hid_item_t* item) {
    switch (*buf & 0x3) {
    case 0:
        item->bSize = 0;
        break;
    case 1:
        item->bSize = 1;
        break;
    case 2:
        item->bSize = 2;
        break;
    case 3:
        item->bSize = 4;
        break;
    }
    item->bType = (*buf >> 2) & 0x3;
    item->bTag = (*buf >> 4) & 0x0f;
    if (buf + item->bSize >= end) {
        // Return a RESERVED item type, and point past the end of the buffer to
        // prevent further parsing.
        item->bType = 0x03;
        return end;
    }
    buf++;

    item->data = 0;
    for (uint8_t i = 0; i < item->bSize; i++) {
        item->data |= *buf << (8*i);
        buf++;
    }
    return buf;
}

static int hid_fetch_or_alloc_report_ndx(input_report_id_t report_id, hid_device_t* dev) {
    ZX_DEBUG_ASSERT(dev->num_reports <= countof(dev->sizes));
    for (size_t i = 0; i < dev->num_reports; i++) {
        if (dev->sizes[i].id == report_id)
            return i;
    }

    if (dev->num_reports < countof(dev->sizes)) {
        dev->sizes[dev->num_reports].id = report_id;
        ZX_DEBUG_ASSERT(dev->sizes[dev->num_reports].in_size == 0);
        ZX_DEBUG_ASSERT(dev->sizes[dev->num_reports].out_size == 0);
        ZX_DEBUG_ASSERT(dev->sizes[dev->num_reports].feat_size == 0);
        return dev->num_reports++;
    } else {
        return -1;
    }

}

typedef struct hid_global_state {
    uint32_t rpt_size;
    uint32_t rpt_count;
    input_report_id_t rpt_id;
    list_node_t node;
} hid_global_state_t;

static zx_status_t hid_push_global_state(list_node_t* stack, hid_global_state_t* state) {
    hid_global_state_t* entry = malloc(sizeof(*entry));
    if (entry == NULL) {
        return ZX_ERR_NO_MEMORY;
    }
    entry->rpt_size = state->rpt_size;
    entry->rpt_count = state->rpt_count;
    entry->rpt_id = state->rpt_id;
    list_add_tail(stack, &entry->node);
    return ZX_OK;
}

static zx_status_t hid_pop_global_state(list_node_t* stack, hid_global_state_t* state) {
    hid_global_state_t* entry = list_remove_tail_type(stack, hid_global_state_t, node);
    if (entry == NULL) {
        return ZX_ERR_BAD_STATE;
    }
    state->rpt_size = entry->rpt_size;
    state->rpt_count = entry->rpt_count;
    state->rpt_id = entry->rpt_id;
    free(entry);
    return ZX_OK;
}

static void hid_clear_global_state(list_node_t* stack) {
    hid_global_state_t* state, *tmp;
    list_for_every_entry_safe(stack, state, tmp, hid_global_state_t, node) {
        list_delete(&state->node);
        free(state);
    }
}

static zx_status_t hid_process_hid_report_desc(hid_device_t* dev) {
    const uint8_t* buf = dev->hid_report_desc;
    const uint8_t* end = buf + dev->hid_report_desc_len;
    zx_status_t status = ZX_OK;
    hid_item_t item;

    bool has_rpt_id = false;
    hid_global_state_t state;
    memset(&state, 0, sizeof(state));
    list_node_t global_stack;
    list_initialize(&global_stack);
    while (buf < end) {
        buf = hid_parse_short_item(buf, end, &item);
        switch (item.bType) {
        case HID_ITEM_TYPE_MAIN: {
            input_report_size_t inc = state.rpt_size * state.rpt_count;
            int idx;
            switch (item.bTag) {
            case HID_ITEM_MAIN_TAG_INPUT:
                idx = hid_fetch_or_alloc_report_ndx(state.rpt_id, dev);
                if (idx < 0) {
                    status = ZX_ERR_NOT_SUPPORTED;
                    goto done;
                }
                dev->sizes[idx].in_size += inc;
                break;
            case HID_ITEM_MAIN_TAG_OUTPUT:
                idx = hid_fetch_or_alloc_report_ndx(state.rpt_id, dev);
                if (idx < 0) {
                    status = ZX_ERR_NOT_SUPPORTED;
                    goto done;
                }
                dev->sizes[idx].out_size += inc;
                break;
            case HID_ITEM_MAIN_TAG_FEATURE:
                idx = hid_fetch_or_alloc_report_ndx(state.rpt_id, dev);
                if (idx < 0) {
                    status = ZX_ERR_NOT_SUPPORTED;
                    goto done;
                }
                dev->sizes[idx].feat_size += inc;
                break;
            default:
                break;
            }
            break;  // case HID_ITEM_TYPE_MAIN
        }
        case HID_ITEM_TYPE_GLOBAL: {
            switch (item.bTag) {
            case HID_ITEM_GLOBAL_TAG_REPORT_SIZE:
                state.rpt_size = (uint32_t)item.data;
                break;
            case HID_ITEM_GLOBAL_TAG_REPORT_ID:
                state.rpt_id = (input_report_id_t)item.data;
                has_rpt_id = true;
                break;
            case HID_ITEM_GLOBAL_TAG_REPORT_COUNT:
                state.rpt_count = (uint32_t)item.data;
                break;
            case HID_ITEM_GLOBAL_TAG_PUSH:
                status = hid_push_global_state(&global_stack, &state);
                if (status != ZX_OK) {
                    goto done;
                }
                break;
            case HID_ITEM_GLOBAL_TAG_POP:
                status = hid_pop_global_state(&global_stack, &state);
                if (status != ZX_OK) {
                    goto done;
                }
                break;
            default:
                break;
            }
            break;  // case HID_ITEM_TYPE_GLOBAL
        }
        default:
            break;
        }
    }
done:
    hid_clear_global_state(&global_stack);

    if (status == ZX_OK) {
#if BOOT_MOUSE_HACK
        // Ignore the HID report descriptor from the device, since we're putting
        // the device into boot protocol mode.
        if (dev->info.dev_class == HID_DEV_CLASS_POINTER) {
            if (dev->info.boot_device) {
                zxlogf(INFO, "hid: boot mouse hack for \"%s\":  "
                       "report count (%zu->1), "
                       "inp sz (%d->24), "
                       "out sz (%d->0), "
                       "feat sz (%d->0)\n",
                       dev->name, dev->num_reports, dev->sizes[0].in_size,
                       dev->sizes[0].out_size, dev->sizes[0].feat_size);
                dev->num_reports = 1;
                dev->sizes[0].id = 0;
                dev->sizes[0].in_size = 24;
                dev->sizes[0].out_size = 0;
                dev->sizes[0].feat_size = 0;
                has_rpt_id = false;
            } else {
                zxlogf(INFO,
                    "hid: boot mouse hack skipped for \"%s\": does not support protocol.\n",
                    dev->name);
            }
        }
#endif
        // If we saw a report ID, adjust the expected report sizes to reflect
        // the fact that we expect a report ID to be prepended to each report.
        ZX_DEBUG_ASSERT(dev->num_reports <= countof(dev->sizes));
        if (has_rpt_id) {
            for (size_t i = 0; i < dev->num_reports; ++i) {
                if (dev->sizes[i].in_size)   dev->sizes[i].in_size   += 8;
                if (dev->sizes[i].out_size)  dev->sizes[i].out_size  += 8;
                if (dev->sizes[i].feat_size) dev->sizes[i].feat_size += 8;
            }
        }
    }

    return status;
}

static void hid_release_reassembly_buffer(hid_device_t* dev) {
    if (dev->rbuf != NULL) {
        free(dev->rbuf);
    }

    dev->rbuf = NULL;
    dev->rbuf_size =  0;
    dev->rbuf_filled =  0;
    dev->rbuf_needed =  0;
}

static zx_status_t hid_init_reassembly_buffer(hid_device_t* dev) {
    ZX_DEBUG_ASSERT(dev->rbuf == NULL);
    ZX_DEBUG_ASSERT(dev->rbuf_size == 0);
    ZX_DEBUG_ASSERT(dev->rbuf_filled == 0);
    ZX_DEBUG_ASSERT(dev->rbuf_needed == 0);

    // TODO(johngro) : Take into account the underlying transport's ability to
    // deliver payloads.  For example, if this is a USB HID device operating at
    // full speed, we can expect it to deliver up to 64 bytes at a time.  If the
    // maximum HID input report size is only 60 bytes, we should not need a
    // reassembly buffer.
    input_report_size_t max_report_size = 0;
    size_t actual = 0;
    zx_status_t res = hid_get_max_input_reportsize(dev, &max_report_size, sizeof(max_report_size),
                                                   &actual);
    if (res < 0) {
        return res;
    } else if (!max_report_size || actual != sizeof(max_report_size)) {
        return ZX_ERR_INTERNAL;
    }

    dev->rbuf = malloc(max_report_size);
    if (dev->rbuf == NULL) {
        return ZX_ERR_NO_MEMORY;
    }

    dev->rbuf_size = max_report_size;
    return ZX_OK;
}

static void hid_release_device(void* ctx) {
    hid_device_t* hid = ctx;

    if (hid->hid_report_desc) {
        free(hid->hid_report_desc);
        hid->hid_report_desc = NULL;
        hid->hid_report_desc_len = 0;
    }
    hid_release_reassembly_buffer(hid);
    free(hid);
}

static zx_status_t hid_open_device(void* ctx, zx_device_t** dev_out, uint32_t flags) {
    hid_device_t* hid = ctx;

    hid_instance_t* inst = calloc(1, sizeof(hid_instance_t));
    if (inst == NULL) {
        return ZX_ERR_NO_MEMORY;
    }
    zx_hid_fifo_init(&inst->fifo);

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "hid",
        .ctx = inst,
        .ops = &hid_instance_proto,
        .proto_id = ZX_PROTOCOL_INPUT,
        .flags = DEVICE_ADD_INSTANCE,
    };

    zx_status_t status = status = device_add(hid->zxdev, &args, &inst->zxdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "hid: error creating instance %d\n", status);
        free(inst);
        return status;
    }
    inst->base = hid;

    mtx_lock(&hid->instance_lock);
    list_add_tail(&hid->instance_list, &inst->node);
    mtx_unlock(&hid->instance_lock);

    *dev_out = inst->zxdev;
    return ZX_OK;
}

static void hid_unbind_device(void* ctx) {
    hid_device_t* hid = ctx;
    mtx_lock(&hid->instance_lock);
    hid_instance_t* instance;
    foreach_instance(hid, instance) {
        instance->flags |= HID_FLAGS_DEAD;
        device_state_set(instance->zxdev, DEV_STATE_READABLE);
    }
    mtx_unlock(&hid->instance_lock);
    device_remove(hid->zxdev);
}

zx_protocol_device_t hid_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .open = hid_open_device,
    .unbind = hid_unbind_device,
    .release = hid_release_device,
};

void hid_io_queue(void* cookie, const uint8_t* buf, size_t len) {
    hid_device_t* hid = cookie;

    mtx_lock(&hid->instance_lock);

    while (len) {
        // Start by figuring out if this payload either completes a partially
        // assembled input report or represents an entire input buffer report on
        // its own.
        const uint8_t* rbuf;
        size_t rlen;
        size_t consumed;

        if (hid->rbuf_needed) {
            // Reassembly is in progress, just continue the process.
            consumed = MIN(len, hid->rbuf_needed);
            ZX_DEBUG_ASSERT (hid->rbuf_size >= hid->rbuf_filled);
            ZX_DEBUG_ASSERT((hid->rbuf_size - hid->rbuf_filled) >= consumed);

            memcpy(hid->rbuf + hid->rbuf_filled, buf, consumed);

            if (consumed == hid->rbuf_needed) {
                // reassembly finished.  Reset the bookkeeping and deliver the
                // payload.
                rbuf = hid->rbuf;
                rlen = hid->rbuf_filled + consumed;
                hid->rbuf_filled = 0;
                hid->rbuf_needed = 0;
            } else {
                // We have not finished the process yet.  Update the bookkeeping
                // and get out.
                hid->rbuf_filled += consumed;
                hid->rbuf_needed -= consumed;
                break;
            }
        } else {
            // No reassembly is in progress.  Start by identifying this report's
            // size.
            size_t  rpt_sz = hid_get_report_size_by_id(hid, buf[0], INPUT_REPORT_INPUT);

            // If we don't recognize this report ID, we are in trouble.  Drop
            // the rest of this payload and hope that the next one gets us back
            // on track.
            if (!rpt_sz) {
                zxlogf(ERROR, "%s: failed to find input report size (report id %u)\n",
                        hid->name, buf[0]);
                break;
            }

            // Is the entire report present in this payload?  If so, just go
            // ahead an deliver it directly from the input buffer.
            if (len >= rpt_sz) {
                rbuf = buf;
                consumed = rlen = rpt_sz;
            } else {
                // Looks likes our report is fragmented over multiple buffers.
                // Start the process of reassembly and get out.
                ZX_DEBUG_ASSERT(hid->rbuf != NULL);
                ZX_DEBUG_ASSERT(hid->rbuf_size >= rpt_sz);
                memcpy(hid->rbuf, buf, len);
                hid->rbuf_filled = len;
                hid->rbuf_needed = rpt_sz - len;
                break;
            }
        }

        ZX_DEBUG_ASSERT(rbuf != NULL);
        ZX_DEBUG_ASSERT(consumed <= len);
        buf += consumed;
        len -= consumed;

        hid_instance_t* instance;
        foreach_instance(hid, instance) {
            mtx_lock(&instance->fifo.lock);
            bool was_empty = zx_hid_fifo_size(&instance->fifo) == 0;
            ssize_t wrote = zx_hid_fifo_write(&instance->fifo, rbuf, rlen);

            if (wrote <= 0) {
                if (!(instance->flags & HID_FLAGS_WRITE_FAILED)) {
                    zxlogf(ERROR, "%s: could not write to hid fifo (ret=%zd)\n",
                            hid->name, wrote);
                    instance->flags |= HID_FLAGS_WRITE_FAILED;
                }
            } else {
                instance->flags &= ~HID_FLAGS_WRITE_FAILED;
                if (was_empty) {
                    device_state_set(instance->zxdev, DEV_STATE_READABLE);
                }
            }
            mtx_unlock(&instance->fifo.lock);
        }
    }

    mtx_unlock(&hid->instance_lock);
}

hidbus_ifc_t hid_ifc = {
    .io_queue = hid_io_queue,
};

static zx_status_t hid_bind(void* ctx, zx_device_t* parent) {
    hid_device_t* hiddev;
    if ((hiddev = calloc(1, sizeof(hid_device_t))) == NULL) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_status_t status;
    if (device_get_protocol(parent, ZX_PROTOCOL_HIDBUS, &hiddev->hid)) {
        zxlogf(ERROR, "hid: bind: no hidbus protocol\n");
        status = ZX_ERR_INTERNAL;
        goto fail;
    }

    if ((status = hid_op_query(hiddev, 0, &hiddev->info)) < 0) {
        zxlogf(ERROR, "hid: bind: hidbus query failed: %d\n", status);
        goto fail;
    }

    mtx_init(&hiddev->instance_lock, mtx_plain);
    list_initialize(&hiddev->instance_list);

    snprintf(hiddev->name, sizeof(hiddev->name), "hid-device-%03d", hiddev->info.dev_num);
    hiddev->name[ZX_DEVICE_NAME_MAX] = 0;

    if (hiddev->info.boot_device) {
        status = hid_op_set_protocol(hiddev, HID_PROTOCOL_BOOT);
        if (status != ZX_OK) {
            zxlogf(ERROR, "hid: could not put HID device into boot protocol: %d\n", status);
            goto fail;
        }

        // Disable numlock
        if (hiddev->info.dev_class == HID_DEV_CLASS_KBD) {
            uint8_t zero = 0;
            hid_op_set_report(hiddev, HID_REPORT_TYPE_OUTPUT, 0, &zero, sizeof(zero));
            // ignore failure for now
        }
    }

    status = hid_op_get_descriptor(hiddev, HID_DESC_TYPE_REPORT,
            (void**)&hiddev->hid_report_desc, &hiddev->hid_report_desc_len);
    if (status != ZX_OK) {
        zxlogf(ERROR, "hid: could not retrieve HID report descriptor: %d\n", status);
        goto fail;
    }

    status = hid_process_hid_report_desc(hiddev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "hid: could not parse hid report descriptor: %d\n", status);
        goto fail;
    }
    hid_dump_hid_report_desc(hiddev);

    status = hid_init_reassembly_buffer(hiddev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "hid: failed to initialize reassembly buffer: %d\n", status);
        goto fail;
    }

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = hiddev->name,
        .ctx = hiddev,
        .ops = &hid_device_proto,
        .proto_id = ZX_PROTOCOL_INPUT,
    };

    status = device_add(parent, &args, &hiddev->zxdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "hid: device_add failed for HID device: %d\n", status);
        goto fail;
    }

    // TODO: delay calling start until we've been opened by someone
    status = hid_op_start(hiddev, &hid_ifc, hiddev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "hid: could not start hid device: %d\n", status);
        device_remove(hiddev->zxdev);
        // Don't fail, since we've been added. Need to let devmgr clean us up.
        return status;
    }

    status = hid_op_set_idle(hiddev, 0, 0);
    if (status != ZX_OK) {
        zxlogf(TRACE, "hid: [W] set_idle failed for %s: %d\n", hiddev->name, status);
        // continue anyway
    }
    return ZX_OK;

fail:
    hid_release_reassembly_buffer(hiddev);
    free(hiddev);
    return status;
}

static zx_driver_ops_t hid_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = hid_bind,
};

ZIRCON_DRIVER_BEGIN(hid, hid_driver_ops, "zircon", "0.1", 1)
    BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_HIDBUS),
ZIRCON_DRIVER_END(hid)
