// 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.

library fuchsia.hardware.usb.function;

using fuchsia.hardware.usb.request;
using zircon.hw.usb;
using zx;

[Layout = "ddk-protocol"]
protocol UsbFunction {
    /// Registers callbacks to the USB function driver.
    SetInterface(UsbFunctionInterface @interface) -> (zx.status s);

    /// Allocates a unique interface descriptor number.
    AllocInterface() -> (zx.status s, uint8 intf_num);

    /// Allocates a unique endpoint descriptor number.
    AllocEp(uint8 direction) -> (zx.status s, uint8 address);

    /// Configures an endpoint based on provided descriptors.
    ConfigEp(zircon.hw.usb.UsbEndpointDescriptor ep_desc,
                zircon.hw.usb.UsbSsEpCompDescriptor ss_comp_desc) -> (zx.status s);

    /// Disables the specified endpoint.
    DisableEp(uint8 address) -> (zx.status s);

    /// Adds a string descriptor to the device configuration.
    AllocStringDesc(string @string) -> (zx.status s, uint8 index);

    /// Queues a USB request with the lower level driver.
    RequestQueue(fuchsia.hardware.usb.request.UsbRequest? usb_request,
                 fuchsia.hardware.usb.request.UsbRequestComplete? complete_cb) -> ();

    /// Stalls the specified endpoint.
    EpSetStall(uint8 ep_address) -> (zx.status s);

    /// Clears a stall condition for the specified endpoint.
    EpClearStall(uint8 ep_address) -> (zx.status s);

    /// Returns the size needed for a |usb_request_t|, including private storage needed by the
    /// HCI driver.
    GetRequestSize() -> (usize size);

    /// Cancels all transactions currently queued on the specified endpoint.
    CancelAll(uint8 ep_address) -> (zx.status s);
};

/// Interface implemented by the USB function driver.
[Layout = "ddk-interface"]
protocol UsbFunctionInterface {
    /// Returns the size of the descriptor list for the function.
    GetDescriptorsSize() -> (usize size);

    /// Returns the descriptor list for the function.
    /// TODO(voydanoff) - descriptors will likely vary (different max packet sizes, etc)
    /// depending on whether we are in low/full, high or super speed mode.
    /// We will need to add a usb_speed_t argument to this callback.
    GetDescriptors() -> (vector<voidptr> descriptors);

    /// Callback for handling ep0 control requests.
    Control(zircon.hw.usb.UsbSetup setup, vector<voidptr> write) -> (zx.status status,
                                                                     vector<voidptr> read);
    /// Called to inform the function driver when the USB device configured state changes.
    /// Called with configured == true in response to a SET_CONFIGURATION control request
    /// that selects a configuration that contains this function. In this case, the function driver
    /// should call usb_function_config_ep() to configure its endpoints.
    /// Called with configured == false when configuration is disabled or USB is disconnected.
    /// The function driver should then call usb_function_disable_ep() to disable its endpoints.
    SetConfigured(bool configured, zircon.hw.usb.UsbSpeed speed) -> (zx.status s);

    /// Called to set an alternate setting for an interface due to a SET_INTERFACE control request.
    /// The function driver should call usb_function_config_ep() and/or usb_function_config_ep()
    /// to configure or disable the interface's endpoints as appropriate.
    SetInterface(uint8 interface, uint8 alt_setting) -> (zx.status s);
};
