// Copyright 2019 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 "fragment.h"

#include <stdio.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/errors.h>

#include <atomic>
#include <iterator>
#include <memory>

#include <ddk/debug.h>
#include <ddk/fragment-device.h>
#include <ddk/trace/event.h>
#include <fbl/algorithm.h>

#include "ddk/protocol/goldfish/addressspace.h"
#include "proxy-protocol.h"

namespace fragment {

namespace {

void MakeUniqueName(char name[ZX_DEVICE_NAME_MAX + 1]) {
  static std::atomic<size_t> unique_id = 0;
  snprintf(name, ZX_DEVICE_NAME_MAX + 1, "fragment-%zu", unique_id.fetch_add(1));
}

}  // namespace

template <typename ProtoClientType, typename ProtoType>
ProtocolClient<ProtoClientType, ProtoType>::ProtocolClient(zx_device_t* parent, uint32_t proto_id) {
  ProtoClientType* protoptr = &proto_client_;
  zx_status_t status = device_open_protocol_session_multibindable(parent, proto_id, &proto_);
  ZX_DEBUG_ASSERT(status == ZX_OK || status == ZX_ERR_NOT_SUPPORTED);
  if (status == ZX_OK) {
    is_session_ = true;
  } else if (status == ZX_ERR_NOT_SUPPORTED) {
    device_get_protocol(parent, proto_id, &proto_);
  }
  *protoptr = ProtoClientType(&proto_);
}

zx_status_t Fragment::Bind(void* ctx, zx_device_t* parent) {
  char name[ZX_DEVICE_NAME_MAX + 1];
  MakeUniqueName(name);
  auto dev = std::make_unique<Fragment>(parent);
  // The thing before the comma will become the process name, if a new process
  // is created
  const char* proxy_args = "composite-device,";
  auto status = dev->DdkAdd(ddk::DeviceAddArgs(name)
                                .set_flags(DEVICE_ADD_NON_BINDABLE | DEVICE_ADD_MUST_ISOLATE)
                                .set_proxy_args(proxy_args));
  if (status == ZX_OK) {
    // devmgr owns the memory now
    __UNUSED auto ptr = dev.release();
  }
  return status;
}

zx_status_t Fragment::RpcCanvas(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                                uint32_t* out_resp_size, zx::handle* req_handles,
                                uint32_t req_handle_count, zx::handle* resp_handles,
                                uint32_t* resp_handle_count) {
  if (!canvas_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const AmlogicCanvasProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<AmlogicCanvasProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case AmlogicCanvasOp::CONFIG:
      if (req_handle_count != 1) {
        zxlogf(ERROR, "%s received %u handles, expecting 1", __func__, req_handle_count);
        return ZX_ERR_INTERNAL;
      }
      return canvas_client_.proto_client().Config(zx::vmo(std::move(req_handles[0])), req->offset,
                                                  &req->info, &resp->canvas_idx);
    case AmlogicCanvasOp::FREE:
      if (req_handle_count != 0) {
        zxlogf(ERROR, "%s received %u handles, expecting 0", __func__, req_handle_count);
        return ZX_ERR_INTERNAL;
      }
      return canvas_client_.proto_client().Free(req->canvas_idx);
    default:
      zxlogf(ERROR, "%s: unknown clk op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcButtons(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                                 uint32_t* out_resp_size, zx::handle* req_handles,
                                 uint32_t req_handle_count, zx::handle* resp_handles,
                                 uint32_t* resp_handle_count) {
  if (!buttons_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const ButtonsProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<ButtonsProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case ButtonsOp::GET_NOTIFY_CHANNEL:
      if (req_handle_count != 1) {
        zxlogf(ERROR, "%s received %u handles, expecting 1", __func__, req_handle_count);
        return ZX_ERR_INTERNAL;
      }
      return buttons_client_.proto_client().GetChannel(zx::channel(std::move(req_handles[0])));
    default:
      zxlogf(ERROR, "%s: unknown clk op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcClock(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                               uint32_t* out_resp_size, zx::handle* req_handles,
                               uint32_t req_handle_count, zx::handle* resp_handles,
                               uint32_t* resp_handle_count) {
  if (!clock_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const ClockProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<ClockProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case ClockOp::ENABLE:
      return clock_client_.proto_client().Enable();
    case ClockOp::DISABLE:
      return clock_client_.proto_client().Disable();
    case ClockOp::IS_ENABLED:
      return clock_client_.proto_client().IsEnabled(&resp->is_enabled);
    case ClockOp::SET_RATE:
      return clock_client_.proto_client().SetRate(req->rate);
    case ClockOp::QUERY_SUPPORTED_RATE:
      return clock_client_.proto_client().QuerySupportedRate(req->rate, &resp->rate);
    case ClockOp::GET_RATE:
      return clock_client_.proto_client().GetRate(&resp->rate);
    case ClockOp::SET_INPUT:
      return clock_client_.proto_client().SetInput(req->input_idx);
    case ClockOp::GET_NUM_INPUTS:
      return clock_client_.proto_client().GetNumInputs(&resp->num_inputs);
    case ClockOp::GET_INPUT:
      return clock_client_.proto_client().GetInput(&resp->current_input);
    default:
      zxlogf(ERROR, "%s: unknown clk op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcEthBoard(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                                  uint32_t* out_resp_size, zx::handle* req_handles,
                                  uint32_t req_handle_count, zx::handle* resp_handles,
                                  uint32_t* resp_handle_count) {
  if (!eth_board_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const EthBoardProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<ProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case EthBoardOp::RESET_PHY:
      return eth_board_client_.proto_client().ResetPhy();
    default:
      zxlogf(ERROR, "%s: unknown ETH_BOARD op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcGoldfishAddressSpace(const uint8_t* req_buf, uint32_t req_size,
                                              uint8_t* resp_buf, uint32_t* out_resp_size,
                                              zx::handle* req_handles, uint32_t req_handle_count,
                                              zx::handle* resp_handles,
                                              uint32_t* resp_handle_count) {
  if (!goldfish_address_space_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  auto* req = reinterpret_cast<const GoldfishAddressSpaceProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  uint32_t expected_handle_count;
  switch (req->op) {
    case GoldfishAddressSpaceOp::OPEN_CHILD_DRIVER:
      expected_handle_count = 1;
      break;
  }
  if (req_handle_count != expected_handle_count) {
    zxlogf(ERROR, "%s received %u handles, expecting %u op %u", __func__, req_handle_count,
           expected_handle_count, static_cast<uint32_t>(req->op));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<GoldfishAddressSpaceProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case GoldfishAddressSpaceOp::OPEN_CHILD_DRIVER: {
      zx::channel channel(std::move(req_handles[0]));
      return goldfish_address_space_client_.proto_client().OpenChildDriver(req->type,
                                                                           std::move(channel));
    }
    default:
      zxlogf(ERROR, "%s: unknown GoldfishPipe op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcGoldfishPipe(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                                      uint32_t* out_resp_size, zx::handle* req_handles,
                                      uint32_t req_handle_count, zx::handle* resp_handles,
                                      uint32_t* resp_handle_count) {
  if (!goldfish_pipe_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  auto* req = reinterpret_cast<const GoldfishPipeProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  uint32_t expected_handle_count;
  switch (req->op) {
    case GoldfishPipeOp::SET_EVENT:
    case GoldfishPipeOp::CONNECT_SYSMEM:
    case GoldfishPipeOp::REGISTER_SYSMEM_HEAP:
      expected_handle_count = 1;
      break;
    case GoldfishPipeOp::CREATE:
    case GoldfishPipeOp::DESTROY:
    case GoldfishPipeOp::OPEN:
    case GoldfishPipeOp::EXEC:
    case GoldfishPipeOp::GET_BTI:
      expected_handle_count = 0;
      break;
  }
  if (req_handle_count != expected_handle_count) {
    zxlogf(ERROR, "%s received %u handles, expecting %u op %u", __func__, req_handle_count,
           expected_handle_count, static_cast<uint32_t>(req->op));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<GoldfishPipeProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case GoldfishPipeOp::CREATE: {
      int32_t id = 0;
      zx::vmo vmo;
      auto status = goldfish_pipe_client_.proto_client().Create(&id, &vmo);
      if (status == ZX_OK) {
        resp->id = id;
        resp_handles[0] = std::move(vmo);
        *resp_handle_count = 1;
      }
      return status;
    }
    case GoldfishPipeOp::DESTROY: {
      goldfish_pipe_client_.proto_client().Destroy(req->id);
      return ZX_OK;
    }
    case GoldfishPipeOp::SET_EVENT: {
      zx::event pipe_event(std::move(req_handles[0]));
      return goldfish_pipe_client_.proto_client().SetEvent(req->id, std::move(pipe_event));
    }
    case GoldfishPipeOp::OPEN: {
      goldfish_pipe_client_.proto_client().Open(req->id);
      return ZX_OK;
    }
    case GoldfishPipeOp::EXEC: {
      goldfish_pipe_client_.proto_client().Exec(req->id);
      return ZX_OK;
    }
    case GoldfishPipeOp::GET_BTI: {
      zx::bti bti;
      auto status = goldfish_pipe_client_.proto_client().GetBti(&bti);
      if (status == ZX_OK) {
        resp_handles[0] = std::move(bti);
        *resp_handle_count = 1;
      }
      return status;
    }
    case GoldfishPipeOp::CONNECT_SYSMEM: {
      zx::channel connection(std::move(req_handles[0]));
      return goldfish_pipe_client_.proto_client().ConnectSysmem(std::move(connection));
    }
    case GoldfishPipeOp::REGISTER_SYSMEM_HEAP: {
      zx::channel connection(std::move(req_handles[0]));
      return goldfish_pipe_client_.proto_client().RegisterSysmemHeap(req->heap,
                                                                     std::move(connection));
    }
    default:
      zxlogf(ERROR, "%s: unknown GoldfishPipe op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcGpio(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                              uint32_t* out_resp_size, zx::handle* req_handles,
                              uint32_t req_handle_count, zx::handle* resp_handles,
                              uint32_t* resp_handle_count) {
  if (!gpio_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const GpioProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<GpioProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case GpioOp::CONFIG_IN:
      return gpio_client_.proto_client().ConfigIn(req->flags);
    case GpioOp::CONFIG_OUT:
      return gpio_client_.proto_client().ConfigOut(req->value);
    case GpioOp::SET_ALT_FUNCTION:
      return gpio_client_.proto_client().SetAltFunction(req->alt_function);
    case GpioOp::READ:
      return gpio_client_.proto_client().Read(&resp->value);
    case GpioOp::WRITE:
      return gpio_client_.proto_client().Write(req->value);
    case GpioOp::GET_INTERRUPT: {
      zx::interrupt irq;
      auto status = gpio_client_.proto_client().GetInterrupt(req->flags, &irq);
      if (status == ZX_OK) {
        resp_handles[0] = std::move(irq);
        *resp_handle_count = 1;
      }
      return status;
    }
    case GpioOp::RELEASE_INTERRUPT:
      return gpio_client_.proto_client().ReleaseInterrupt();
    case GpioOp::SET_POLARITY:
      return gpio_client_.proto_client().SetPolarity(req->polarity);
    case GpioOp::SET_DRIVE_STRENGTH:
      return gpio_client_.proto_client().SetDriveStrength(req->ds_ua, &resp->out_actual_ds_ua);
    default:
      zxlogf(ERROR, "%s: unknown GPIO op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

void Fragment::I2cTransactCallback(void* cookie, zx_status_t status, const i2c_op_t* op_list,
                                   size_t op_count) {
  auto* ctx = static_cast<I2cTransactContext*>(cookie);
  ctx->result = status;
  if (status == ZX_OK && ctx->read_buf && ctx->read_length) {
    memcpy(ctx->read_buf, op_list[0].data_buffer, ctx->read_length);
  }

  sync_completion_signal(&ctx->completion);
}

zx_status_t Fragment::RpcI2c(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                             uint32_t* out_resp_size, zx::handle* req_handles,
                             uint32_t req_handle_count, zx::handle* resp_handles,
                             uint32_t* resp_handle_count) {
  TRACE_DURATION("i2c", "I2c FragmentProxy RpcI2c");
  if (!i2c_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const I2cProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<I2cProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);
  TRACE_FLOW_END("i2c", "I2c FragmentProxy I2cTransact Flow", req->trace_id);

  switch (req->op) {
    case I2cOp::TRANSACT: {
      i2c_op_t i2c_ops[I2C_MAX_RW_OPS];
      auto* rpc_ops = reinterpret_cast<const I2cProxyOp*>(&req[1]);
      auto op_count = req->op_count;
      if (op_count > countof(i2c_ops)) {
        return ZX_ERR_BUFFER_TOO_SMALL;
      }
      auto* write_buf = reinterpret_cast<const uint8_t*>(&rpc_ops[op_count]);
      size_t read_length = 0;

      for (size_t i = 0; i < op_count; i++) {
        if (rpc_ops[i].is_read) {
          i2c_ops[i].data_buffer = nullptr;
          read_length += rpc_ops[i].length;
        } else {
          i2c_ops[i].data_buffer = write_buf;
          write_buf += rpc_ops[i].length;
        }
        i2c_ops[i].data_size = rpc_ops[i].length;
        i2c_ops[i].is_read = rpc_ops[i].is_read;
        i2c_ops[i].stop = rpc_ops[i].stop;
      }

      I2cTransactContext ctx = {};
      ctx.read_buf = &resp[1];
      ctx.read_length = read_length;

      i2c_client_.proto_client().Transact(i2c_ops, op_count, I2cTransactCallback, &ctx);
      auto status = sync_completion_wait(&ctx.completion, ZX_TIME_INFINITE);
      if (status == ZX_OK) {
        status = ctx.result;
      }
      if (status == ZX_OK) {
        *out_resp_size = static_cast<uint32_t>(sizeof(*resp) + read_length);
      }
      return status;
    }
    case I2cOp::GET_MAX_TRANSFER_SIZE:
      return i2c_client_.proto_client().GetMaxTransferSize(&resp->size);
    case I2cOp::GET_INTERRUPT: {
      zx::interrupt irq;
      auto status = i2c_client_.proto_client().GetInterrupt(req->flags, &irq);
      if (status == ZX_OK) {
        resp_handles[0] = std::move(irq);
        *resp_handle_count = 1;
      }
      return status;
    }
    default:
      zxlogf(ERROR, "%s: unknown I2C op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcPdev(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                              uint32_t* out_resp_size, zx::handle* req_handles,
                              uint32_t req_handle_count, zx::handle* resp_handles,
                              uint32_t* resp_handle_count) {
  if (!pdev_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const PdevProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  auto* resp = reinterpret_cast<PdevProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case PdevOp::GET_MMIO: {
      pdev_mmio_t mmio;
      auto status = pdev_client_.proto_client().GetMmio(req->index, &mmio);
      if (status == ZX_OK) {
        resp->offset = mmio.offset;
        resp->size = mmio.size;
        resp_handles[0].reset(mmio.vmo);
        *resp_handle_count = 1;
      }
      return status;
    }
    case PdevOp::GET_INTERRUPT: {
      zx::interrupt irq;
      auto status = pdev_client_.proto_client().GetInterrupt(req->index, req->flags, &irq);
      if (status == ZX_OK) {
        resp_handles[0] = std::move(irq);
        *resp_handle_count = 1;
      }
      return status;
    }
    case PdevOp::GET_BTI: {
      zx::bti bti;
      auto status = pdev_client_.proto_client().GetBti(req->index, &bti);
      if (status == ZX_OK) {
        resp_handles[0] = std::move(bti);
        *resp_handle_count = 1;
      }
      return status;
    }
    case PdevOp::GET_SMC: {
      zx::resource resource;
      auto status = pdev_client_.proto_client().GetSmc(req->index, &resource);
      if (status == ZX_OK) {
        resp_handles[0] = std::move(resource);
        *resp_handle_count = 1;
      }
      return status;
    }
    case PdevOp::GET_DEVICE_INFO:
      return pdev_client_.proto_client().GetDeviceInfo(&resp->device_info);
    case PdevOp::GET_BOARD_INFO:
      return pdev_client_.proto_client().GetBoardInfo(&resp->board_info);
    default:
      zxlogf(ERROR, "%s: unknown pdev op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcPower(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                               uint32_t* out_resp_size, zx::handle* req_handles,
                               uint32_t req_handle_count, zx::handle* resp_handles,
                               uint32_t* resp_handle_count) {
  if (!power_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const PowerProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __FUNCTION__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }

  auto* resp = reinterpret_cast<PowerProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);
  switch (req->op) {
    case PowerOp::REGISTER:
      return power_client_.proto_client().RegisterPowerDomain(req->min_voltage, req->max_voltage);
    case PowerOp::UNREGISTER:
      return power_client_.proto_client().UnregisterPowerDomain();
    case PowerOp::GET_STATUS:
      return power_client_.proto_client().GetPowerDomainStatus(&resp->status);
    case PowerOp::GET_SUPPORTED_VOLTAGE_RANGE:
      return power_client_.proto_client().GetSupportedVoltageRange(&resp->min_voltage,
                                                                   &resp->max_voltage);
    case PowerOp::REQUEST_VOLTAGE:
      return power_client_.proto_client().RequestVoltage(req->set_voltage, &resp->actual_voltage);
    case PowerOp::WRITE_PMIC_CTRL_REG:
      return power_client_.proto_client().WritePmicCtrlReg(req->reg_addr, req->reg_value);
    case PowerOp::READ_PMIC_CTRL_REG:
      return power_client_.proto_client().ReadPmicCtrlReg(req->reg_addr, &resp->reg_value);
    default:
      zxlogf(ERROR, "%s: unknown Power op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcPwm(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                             uint32_t* out_resp_size, zx::handle* req_handles,
                             uint32_t req_handle_count, zx::handle* resp_handles,
                             uint32_t* resp_handle_count) {
  if (!pwm_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const PwmProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __FUNCTION__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }

  auto* resp = reinterpret_cast<PwmProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);
  switch (req->op) {
    case PwmOp::GET_CONFIG: {
      if (req->config.mode_config_size > MAX_MODE_CFG_SIZE * sizeof(uint8_t)) {
        return ZX_ERR_NO_SPACE;
      }
      resp->config.mode_config_size = req->config.mode_config_size;
      resp->config.mode_config_buffer = resp->mode_cfg;
      return pwm_client_.proto_client().GetConfig(&resp->config);
    }
    case PwmOp::SET_CONFIG: {
      if (req->config.mode_config_size > MAX_MODE_CFG_SIZE * sizeof(uint8_t)) {
        return ZX_ERR_NO_SPACE;
      }
      uint8_t mode_cfg[MAX_MODE_CFG_SIZE] = {0};
      memcpy(mode_cfg, req->mode_cfg, req->config.mode_config_size);
      pwm_config_t cfg = {req->config.polarity, req->config.period_ns, req->config.duty_cycle,
                          mode_cfg, req->config.mode_config_size};
      return pwm_client_.proto_client().SetConfig(&cfg);
    }
    case PwmOp::ENABLE:
      return pwm_client_.proto_client().Enable();
    case PwmOp::DISABLE:
      return pwm_client_.proto_client().Disable();
    default:
      zxlogf(ERROR, "%s: unknown Pwm op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcSpi(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                             uint32_t* out_resp_size, zx::handle* req_handles,
                             uint32_t req_handle_count, zx::handle* resp_handles,
                             uint32_t* resp_handle_count) {
  if (!spi_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto req = reinterpret_cast<const SpiProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }

  auto resp = reinterpret_cast<SpiProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  auto txbuf = reinterpret_cast<const uint8_t*>(&req[1]);
  auto rxbuf = reinterpret_cast<uint8_t*>(&resp[1]);

  switch (req->op) {
    case SpiOp::TRANSMIT: {
      return spi_client_.proto_client().Transmit(txbuf, req->length);
    }
    case SpiOp::RECEIVE: {
      size_t actual;
      *out_resp_size += static_cast<uint32_t>(req->length);
      return spi_client_.proto_client().Receive(static_cast<uint32_t>(req->length), rxbuf,
                                                req->length, &actual);
    }
    case SpiOp::EXCHANGE: {
      size_t actual;
      *out_resp_size += static_cast<uint32_t>(req->length);
      return spi_client_.proto_client().Exchange(txbuf, req->length, rxbuf, req->length, &actual);
    }
    default:
      zxlogf(ERROR, "%s: unknown SPI op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcSysmem(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                                uint32_t* out_resp_size, zx::handle* req_handles,
                                uint32_t req_handle_count, zx::handle* resp_handles,
                                uint32_t* resp_handle_count) {
  if (!sysmem_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const SysmemProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  uint32_t expected_handle_count;
  switch (req->op) {
    case SysmemOp::CONNECT:
    case SysmemOp::REGISTER_HEAP:
    case SysmemOp::REGISTER_SECURE_MEM:
      expected_handle_count = 1;
      break;
    case SysmemOp::UNREGISTER_SECURE_MEM:
      expected_handle_count = 0;
      break;
  }
  if (req_handle_count != expected_handle_count) {
    zxlogf(ERROR, "%s received %u handles, expecting %u op %u", __func__, req_handle_count,
           expected_handle_count, static_cast<uint32_t>(req->op));
    return ZX_ERR_INTERNAL;
  }
  *out_resp_size = sizeof(ProxyResponse);

  switch (req->op) {
    case SysmemOp::CONNECT:
      return sysmem_client_.proto_client().Connect(zx::channel(std::move(req_handles[0])));
    case SysmemOp::REGISTER_HEAP:
      return sysmem_client_.proto_client().RegisterHeap(req->heap,
                                                        zx::channel(std::move(req_handles[0])));
    case SysmemOp::REGISTER_SECURE_MEM:
      return sysmem_client_.proto_client().RegisterSecureMem(
          zx::channel(std::move(req_handles[0])));
    case SysmemOp::UNREGISTER_SECURE_MEM:
      return sysmem_client_.proto_client().UnregisterSecureMem();
    default:
      zxlogf(ERROR, "%s: unknown sysmem op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcTee(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                             uint32_t* out_resp_size, zx::handle* req_handles,
                             uint32_t req_handle_count, zx::handle* resp_handles,
                             uint32_t* resp_handle_count) {
  if (!tee_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const TeeProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  if (req_handle_count < 1 || req_handle_count > 2) {
    zxlogf(ERROR, "%s received %u handles, expecting 1-2", __func__, req_handle_count);
    return ZX_ERR_INTERNAL;
  }
  *out_resp_size = sizeof(ProxyResponse);

  switch (req->op) {
    case TeeOp::CONNECT: {
      zx::channel tee_device_request(std::move(req_handles[0]));
      zx::channel service_provider;
      if (req_handle_count == 2) {
        service_provider.reset(req_handles[1].release());
      }
      return tee_client_.proto_client().Connect(std::move(tee_device_request),
                                                std::move(service_provider));
    }
    default:
      zxlogf(ERROR, "%s: unknown sysmem op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcUms(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                             uint32_t* out_resp_size, zx::handle* req_handles,
                             uint32_t req_handle_count, zx::handle* resp_handles,
                             uint32_t* resp_handle_count) {
  if (!ums_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const UsbModeSwitchProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __FUNCTION__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }

  auto* resp = reinterpret_cast<ProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);
  switch (req->op) {
    case UsbModeSwitchOp::SET_MODE:
      return ums_client_.proto_client().SetMode(req->mode);
    default:
      zxlogf(ERROR, "%s: unknown USB Mode Switch op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcCodec(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                               uint32_t* out_resp_size, zx::handle* req_handles,
                               uint32_t req_handle_count, zx::handle* resp_handles,
                               uint32_t* resp_handle_count) {
  if (!codec_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  auto* req = reinterpret_cast<const CodecProxyRequest*>(req_buf);
  auto* resp = reinterpret_cast<ProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case CodecOp::GET_CHANNEL:
      if (req_handle_count != 1) {
        zxlogf(ERROR, "%s received %u handles, expecting 1", __func__, req_handle_count);
        return ZX_ERR_INTERNAL;
      }
      return codec_client_.proto_client().Connect(zx::channel(std::move(req_handles[0])));
    default:
      zxlogf(ERROR, "%s: unknown CODEC op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcDai(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                             uint32_t* out_resp_size, zx::handle* req_handles,
                             uint32_t req_handle_count, zx::handle* resp_handles,
                             uint32_t* resp_handle_count) {
  if (!dai_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  auto* req = reinterpret_cast<const DaiProxyRequest*>(req_buf);
  auto* resp = reinterpret_cast<DaiProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case DaiOp::GET_CHANNEL:
      if (req_handle_count != 1) {
        zxlogf(ERROR, "%s received %u handles, expecting 1", __func__, req_handle_count);
        return ZX_ERR_INTERNAL;
      }
      return dai_client_.proto_client().Connect(zx::channel(std::move(req_handles[0])));
    default:
      zxlogf(ERROR, "%s: unknown DAI op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcRpmb(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                              uint32_t* out_resp_size, zx::handle* req_handles,
                              uint32_t req_handle_count, zx::handle* resp_handles,
                              uint32_t* resp_handle_count) {
  if (!rpmb_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const RpmbProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }

  auto* resp = reinterpret_cast<ProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case RpmbOp::CONNECT_SERVER:
      if (req_handle_count != 1) {
        zxlogf(ERROR, "%s: expected one handle for %u", __func__, static_cast<uint32_t>(req->op));
        return ZX_ERR_INVALID_ARGS;
      }

      rpmb_client_.proto_client().ConnectServer(zx::channel(req_handles[0].release()));
      return ZX_OK;
    default:
      zxlogf(ERROR, "%s: unknown rpmb op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcRegisters(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                                   uint32_t* out_resp_size, zx::handle* req_handles,
                                   uint32_t req_handle_count, zx::handle* resp_handles,
                                   uint32_t* resp_handle_count) {
  if (!registers_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const RegistersProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }

  auto* resp = reinterpret_cast<ProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case RegistersOp::CONNECT:
      if (req_handle_count != 1) {
        zxlogf(ERROR, "%s: expected one handle for %u", __func__, static_cast<uint32_t>(req->op));
        return ZX_ERR_INVALID_ARGS;
      }

      registers_client_.proto_client().Connect(zx::channel(req_handles[0].release()));
      return ZX_OK;
    default:
      zxlogf(ERROR, "%s: unknown registers op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcVreg(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                              uint32_t* out_resp_size, zx::handle* req_handles,
                              uint32_t req_handle_count, zx::handle* resp_handles,
                              uint32_t* resp_handle_count) {
  if (!vreg_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const VregProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }

  auto* resp = reinterpret_cast<VregProxyResponse*>(resp_buf);
  *out_resp_size = sizeof(*resp);

  switch (req->op) {
    case VregOp::SET_VOLTAGE_STEP:
      return vreg_client_.proto_client().SetVoltageStep(req->step);
    case VregOp::GET_VOLTAGE_STEP:
      resp->step = vreg_client_.proto_client().GetVoltageStep();
      return ZX_OK;
    case VregOp::GET_REGULATOR_PARAMS:
      vreg_client_.proto_client().GetRegulatorParams(&resp->params);
      return ZX_OK;
    default:
      zxlogf(ERROR, "%s: unknown vreg op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::RpcDsi(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
                             uint32_t* out_resp_size, zx::handle* req_handles,
                             uint32_t req_handle_count, zx::handle* resp_handles,
                             uint32_t* resp_handle_count) {
  if (!dsi_client_.proto_client().is_valid()) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  auto* req = reinterpret_cast<const DsiProxyRequest*>(req_buf);
  if (req_size < sizeof(*req)) {
    zxlogf(ERROR, "%s received %u, expecting %zu", __func__, req_size, sizeof(*req));
    return ZX_ERR_INTERNAL;
  }
  *out_resp_size = sizeof(ProxyResponse);
  switch (req->op) {
    case DsiOp::CONNECT:
      if (req_handle_count != 1) {
        zxlogf(ERROR, "%s: expected one handle for %u", __func__, static_cast<uint32_t>(req->op));
        return ZX_ERR_INVALID_ARGS;
      }
      return dsi_client_.proto_client().Connect(zx::channel(req_handles[0].release()));
    default:
      zxlogf(ERROR, "%s: unknown rpmb op %u", __func__, static_cast<uint32_t>(req->op));
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t Fragment::DdkRxrpc(zx_handle_t raw_channel) {
  zx::unowned_channel channel(raw_channel);
  if (!channel->is_valid()) {
    // This driver is stateless, so we don't need to reset anything here
    return ZX_OK;
  }

  uint8_t req_buf[kProxyMaxTransferSize];

  // Ensure all response messages are fully initialized.
  uint8_t resp_buf[kProxyMaxTransferSize] = {};
  auto* req_header = reinterpret_cast<ProxyRequest*>(&req_buf);
  auto* resp_header = reinterpret_cast<ProxyResponse*>(&resp_buf);
  uint32_t actual;

  zx_handle_t req_handles_raw[ZX_CHANNEL_MAX_MSG_HANDLES];
  uint32_t req_handle_count;

  auto status = zx_channel_read(raw_channel, 0, &req_buf, req_handles_raw, sizeof(req_buf),
                                std::size(req_handles_raw), &actual, &req_handle_count);
  if (status != ZX_OK) {
    zxlogf(ERROR, "platform_dev_rxrpc: zx_channel_read failed %d", status);
    return status;
  }

  // There is some expense in constructing/destructing these.  If that becomes an issue, we could
  // create an incremental construction array type to prevent constructing the extras.
  zx::handle req_handles[ZX_CHANNEL_MAX_MSG_HANDLES];
  for (uint32_t handle_index = 0; handle_index < req_handle_count; ++handle_index) {
    // req_handles_raw handle values are ignored after this point, so no need to clear them.
    req_handles[handle_index].reset(req_handles_raw[handle_index]);
  }

  constexpr uint32_t kMaxRespHandles = 1;
  zx::handle resp_handles[kMaxRespHandles];
  uint32_t resp_handle_count = 0;

  resp_header->txid = req_header->txid;
  uint32_t resp_len = 0;

  switch (req_header->proto_id) {
    case ZX_PROTOCOL_AMLOGIC_CANVAS:
      status = RpcCanvas(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                         resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_BUTTONS:
      status = RpcButtons(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                          resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_CLOCK:
      status = RpcClock(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                        resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_ETH_BOARD:
      status = RpcEthBoard(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                           resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_GOLDFISH_ADDRESS_SPACE:
      status = RpcGoldfishAddressSpace(req_buf, actual, resp_buf, &resp_len, req_handles,
                                       req_handle_count, resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_GOLDFISH_PIPE:
      status = RpcGoldfishPipe(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                               resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_GPIO:
      status = RpcGpio(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                       resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_I2C:
      status = RpcI2c(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                      resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_PDEV:
      status = RpcPdev(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                       resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_POWER:
      status = RpcPower(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                        resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_PWM:
      status = RpcPwm(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                      resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_SPI:
      status = RpcSpi(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                      resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_SYSMEM:
      status = RpcSysmem(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                         resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_TEE:
      status = RpcTee(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                      resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_USB_MODE_SWITCH:
      status = RpcUms(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                      resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_CODEC:
      status = RpcCodec(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                        resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_DAI:
      status = RpcDai(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                      resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_RPMB:
      status = RpcRpmb(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                       resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_REGISTERS:
      status = RpcRegisters(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                            resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_VREG:
      status = RpcVreg(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                       resp_handles, &resp_handle_count);
      break;
    case ZX_PROTOCOL_DSI:
      status = RpcDsi(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
                      resp_handles, &resp_handle_count);
      break;
    default:
      zxlogf(ERROR, "%s: unknown protocol %u", __func__, req_header->proto_id);
      return ZX_ERR_INTERNAL;
  }

  ZX_DEBUG_ASSERT(resp_handle_count <= kMaxRespHandles);

  zx_handle_t resp_handles_raw[kMaxRespHandles];
  for (uint32_t handle_index = 0; handle_index < resp_handle_count; ++handle_index) {
    // Will be transferred or closed by zx_channel_write().
    resp_handles_raw[handle_index] = resp_handles[handle_index].release();
  }

  // set op to match request so zx_channel_write will return our response
  resp_header->status = status;
  status = zx_channel_write(raw_channel, 0, resp_header, resp_len,
                            (resp_handle_count ? resp_handles_raw : nullptr), resp_handle_count);
  if (status != ZX_OK) {
    zxlogf(ERROR, "platform_dev_rxrpc: zx_channel_write failed %d", status);
  }
  return status;
}

void Fragment::DdkUnbind(ddk::UnbindTxn txn) { txn.Reply(); }

zx_status_t Fragment::DdkGetProtocol(uint32_t proto_id, void* out_protocol) {
  switch (proto_id) {
    case ZX_PROTOCOL_AMLOGIC_CANVAS: {
      if (!canvas_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      canvas_client_.proto_client().GetProto(static_cast<amlogic_canvas_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_BUTTONS: {
      if (!buttons_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      buttons_client_.proto_client().GetProto(static_cast<buttons_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_CLOCK: {
      if (!clock_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      clock_client_.proto_client().GetProto(static_cast<clock_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_ETH_BOARD: {
      if (!eth_board_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      eth_board_client_.proto_client().GetProto(static_cast<eth_board_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_GOLDFISH_ADDRESS_SPACE: {
      if (!goldfish_address_space_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      goldfish_address_space_client_.proto_client().GetProto(
          static_cast<goldfish_address_space_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_GOLDFISH_PIPE: {
      if (!goldfish_pipe_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      goldfish_pipe_client_.proto_client().GetProto(
          static_cast<goldfish_pipe_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_GPIO: {
      if (!gpio_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      gpio_client_.proto_client().GetProto(static_cast<gpio_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_I2C: {
      if (!i2c_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      i2c_client_.proto_client().GetProto(static_cast<i2c_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_CODEC: {
      if (!codec_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      codec_client_.proto_client().GetProto(static_cast<codec_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_DAI: {
      if (!dai_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      dai_client_.proto_client().GetProto(static_cast<dai_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_PDEV: {
      if (!pdev_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      pdev_client_.proto_client().GetProto(static_cast<pdev_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_PWM: {
      if (!pwm_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      pwm_client_.proto_client().GetProto(static_cast<pwm_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_SPI: {
      if (!spi_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      spi_client_.proto_client().GetProto(static_cast<spi_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_SYSMEM: {
      if (!sysmem_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      sysmem_client_.proto_client().GetProto(static_cast<sysmem_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_TEE: {
      if (!tee_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      tee_client_.proto_client().GetProto(static_cast<tee_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_USB_MODE_SWITCH: {
      if (!ums_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      ums_client_.proto_client().GetProto(static_cast<usb_mode_switch_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_POWER: {
      if (!power_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      power_client_.proto_client().GetProto(static_cast<power_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_POWER_IMPL: {
      if (!power_impl_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      power_impl_client_.proto_client().GetProto(static_cast<power_impl_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_DSI_IMPL: {
      if (!dsi_impl_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      dsi_impl_client_.proto_client().GetProto(static_cast<dsi_impl_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_SDIO: {
      if (!sdio_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      sdio_client_.proto_client().GetProto(static_cast<sdio_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_THERMAL: {
      if (!thermal_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      thermal_client_.proto_client().GetProto(static_cast<thermal_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_ISP: {
      if (!isp_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      isp_client_.proto_client().GetProto(static_cast<isp_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_SHARED_DMA: {
      if (!shared_dma_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      shared_dma_client_.proto_client().GetProto(static_cast<shared_dma_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_USB_PHY: {
      if (!usb_phy_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      usb_phy_client_.proto_client().GetProto(static_cast<usb_phy_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_MIPI_CSI: {
      if (!mipi_csi_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      mipi_csi_client_.proto_client().GetProto(static_cast<mipi_csi_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_CAMERA_SENSOR2: {
      if (!camera_sensor2_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      camera_sensor2_client_.proto_client().GetProto(
          static_cast<camera_sensor2_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_SCPI: {
      if (!scpi_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      scpi_client_.proto_client().GetProto(static_cast<scpi_protocol_t*>(out_protocol));
      return ZX_OK;
    }
    case ZX_PROTOCOL_GDC: {
      if (!gdc_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      gdc_client_.proto_client().GetProto(static_cast<gdc_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_GE2D: {
      if (!ge2d_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      ge2d_client_.proto_client().GetProto(static_cast<ge2d_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_RPMB: {
      if (!rpmb_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      rpmb_client_.proto_client().GetProto(static_cast<rpmb_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_REGISTERS: {
      if (!registers_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      registers_client_.proto_client().GetProto(static_cast<registers_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    case ZX_PROTOCOL_VREG: {
      if (!vreg_client_.proto_client().is_valid()) {
        return ZX_ERR_NOT_SUPPORTED;
      }
      vreg_client_.proto_client().GetProto(static_cast<vreg_protocol_t*>(out_protocol));
      return ZX_OK;
    }

    default:
      return ZX_ERR_NOT_SUPPORTED;
  }
}

void Fragment::DdkRelease() { delete this; }

const zx_driver_ops_t driver_ops = []() {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = Fragment::Bind;
  return ops;
}();

}  // namespace fragment

ZIRCON_DRIVER_BEGIN(fragment, fragment::driver_ops, "zircon", "0.1", 1)
BI_MATCH()  // This driver is excluded from the normal matching process, so this is fine.
ZIRCON_DRIVER_END(fragment)
