blob: 8e313dce4ac231e2111e10d03794241de7d1b861 [file] [log] [blame]
// Copyright 2018 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.
// WARNING: This file is machine generated by fidlc.
#pragma once
#include <ddk/protocol/usb-dci.h>
#include <ddk/protocol/usb.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/hw/usb.h>
#include <zircon/types.h>
#include "usb-dci-internal.h"
// DDK usb-dci-protocol support
//
// :: Proxies ::
//
// ddk::UsbDciProtocolProxy is a simple wrapper around
// usb_dci_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
// ddk::UsbDciProtocol is a mixin class that simplifies writing DDK drivers
// that implement the usb-dci protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_USB_DCI device.
// class UsbDciDevice {
// using UsbDciDeviceType = ddk::Device<UsbDciDevice, /* ddk mixins */>;
//
// class UsbDciDevice : public UsbDciDeviceType,
// public ddk::UsbDciProtocol<UsbDciDevice> {
// public:
// UsbDciDevice(zx_device_t* parent)
// : UsbDciDeviceType("my-usb-dci-protocol-device", parent) {}
//
// void UsbDciRequestQueue(usb_request_t* req);
//
// zx_status_t UsbDciSetInterface(const usb_dci_interface_t* interface);
//
// zx_status_t UsbDciConfigEp(const usb_endpoint_descriptor_t* ep_desc, const
// usb_ss_ep_comp_descriptor_t* ss_comp_desc);
//
// zx_status_t UsbDciDisableEp(uint8_t ep_address);
//
// zx_status_t UsbDciEpSetStall(uint8_t ep_address);
//
// zx_status_t UsbDciEpClearStall(uint8_t ep_address);
//
// zx_status_t UsbDciGetBti(zx_handle_t* out_bti);
//
// ...
// };
namespace ddk {
// This protocol is used for USB peripheral controller drivers.
// Callbacks implemented by the USB device driver.
template <typename D>
class UsbDciInterface : public internal::base_mixin {
public:
UsbDciInterface() {
internal::CheckUsbDciInterfaceSubclass<D>();
usb_dci_interface_ops_.control = UsbDciInterfaceControl;
usb_dci_interface_ops_.set_connected = UsbDciInterfaceSetConnected;
usb_dci_interface_ops_.set_speed = UsbDciInterfaceSetSpeed;
}
protected:
usb_dci_interface_ops_t usb_dci_interface_ops_ = {};
private:
// callback for handling ep0 control requests
static zx_status_t UsbDciInterfaceControl(void* ctx, const usb_setup_t* setup,
const void* write_buffer, size_t write_size,
void* out_read_buffer, size_t read_size,
size_t* out_read_actual) {
return static_cast<D*>(ctx)->UsbDciInterfaceControl(
setup, write_buffer, write_size, out_read_buffer, read_size, out_read_actual);
}
static void UsbDciInterfaceSetConnected(void* ctx, bool connected) {
static_cast<D*>(ctx)->UsbDciInterfaceSetConnected(connected);
}
static void UsbDciInterfaceSetSpeed(void* ctx, usb_speed_t speed) {
static_cast<D*>(ctx)->UsbDciInterfaceSetSpeed(speed);
}
};
class UsbDciInterfaceProxy {
public:
UsbDciInterfaceProxy() : ops_(nullptr), ctx_(nullptr) {}
UsbDciInterfaceProxy(const usb_dci_interface_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(usb_dci_interface_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
bool is_valid() { return ops_ != nullptr; }
void clear() {
ctx_ = nullptr;
ops_ = nullptr;
}
// callback for handling ep0 control requests
zx_status_t Control(const usb_setup_t* setup, const void* write_buffer, size_t write_size,
void* out_read_buffer, size_t read_size, size_t* out_read_actual) {
return ops_->control(ctx_, setup, write_buffer, write_size, out_read_buffer, read_size,
out_read_actual);
}
void SetConnected(bool connected) { ops_->set_connected(ctx_, connected); }
void SetSpeed(usb_speed_t speed) { ops_->set_speed(ctx_, speed); }
private:
usb_dci_interface_ops_t* ops_;
void* ctx_;
};
template <typename D>
class UsbDciProtocol : public internal::base_protocol {
public:
UsbDciProtocol() {
internal::CheckUsbDciProtocolSubclass<D>();
ops_.request_queue = UsbDciRequestQueue;
ops_.set_interface = UsbDciSetInterface;
ops_.config_ep = UsbDciConfigEp;
ops_.disable_ep = UsbDciDisableEp;
ops_.ep_set_stall = UsbDciEpSetStall;
ops_.ep_clear_stall = UsbDciEpClearStall;
ops_.get_bti = UsbDciGetBti;
ops_.get_request_size = UsbDciGetRequestSize;
// Can only inherit from one base_protocol implementation.
ZX_ASSERT(ddk_proto_id_ == 0);
ddk_proto_id_ = ZX_PROTOCOL_USB_DCI;
ddk_proto_ops_ = &ops_;
}
protected:
usb_dci_protocol_ops_t ops_ = {};
private:
static void UsbDciRequestQueue(void* ctx, usb_request_t* req) {
static_cast<D*>(ctx)->UsbDciRequestQueue(req);
}
// Registers callback interface with the controller driver.
static zx_status_t UsbDciSetInterface(void* ctx, const usb_dci_interface_t* interface) {
return static_cast<D*>(ctx)->UsbDciSetInterface(interface);
}
static zx_status_t UsbDciConfigEp(void* ctx, const usb_endpoint_descriptor_t* ep_desc,
const usb_ss_ep_comp_descriptor_t* ss_comp_desc) {
return static_cast<D*>(ctx)->UsbDciConfigEp(ep_desc, ss_comp_desc);
}
static zx_status_t UsbDciDisableEp(void* ctx, uint8_t ep_address) {
return static_cast<D*>(ctx)->UsbDciDisableEp(ep_address);
}
static zx_status_t UsbDciEpSetStall(void* ctx, uint8_t ep_address) {
return static_cast<D*>(ctx)->UsbDciEpSetStall(ep_address);
}
static zx_status_t UsbDciEpClearStall(void* ctx, uint8_t ep_address) {
return static_cast<D*>(ctx)->UsbDciEpClearStall(ep_address);
}
// Shares a copy of the DCI driver's BTI handle.
static zx_status_t UsbDciGetBti(void* ctx, zx_handle_t* out_bti) {
return static_cast<D*>(ctx)->UsbDciGetBti(out_bti);
}
static size_t UsbDciGetRequestSize(void* ctx) {
return static_cast<D*>(ctx)->UsbDciGetRequestSize();
}
};
class UsbDciProtocolProxy {
public:
UsbDciProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
UsbDciProtocolProxy(const usb_dci_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(usb_dci_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
bool is_valid() { return ops_ != nullptr; }
void clear() {
ctx_ = nullptr;
ops_ = nullptr;
}
void RequestQueue(usb_request_t* req) { ops_->request_queue(ctx_, req); }
// Registers callback interface with the controller driver.
zx_status_t SetInterface(const usb_dci_interface_t* interface) {
return ops_->set_interface(ctx_, interface);
}
zx_status_t ConfigEp(const usb_endpoint_descriptor_t* ep_desc,
const usb_ss_ep_comp_descriptor_t* ss_comp_desc) {
return ops_->config_ep(ctx_, ep_desc, ss_comp_desc);
}
zx_status_t DisableEp(uint8_t ep_address) { return ops_->disable_ep(ctx_, ep_address); }
zx_status_t EpSetStall(uint8_t ep_address) { return ops_->ep_set_stall(ctx_, ep_address); }
zx_status_t EpClearStall(uint8_t ep_address) { return ops_->ep_clear_stall(ctx_, ep_address); }
// Shares a copy of the DCI driver's BTI handle.
zx_status_t GetBti(zx_handle_t* out_bti) { return ops_->get_bti(ctx_, out_bti); }
size_t GetRequestSize() { return ops_->get_request_size(ctx_); }
private:
usb_dci_protocol_ops_t* ops_;
void* ctx_;
};
} // namespace ddk