// 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.descriptor;
using fuchsia.hardware.usb.request;
using zx;

@transport("Banjo")
@banjo_layout("ddk-protocol")
closed protocol UsbFunction {
    /// Registers callbacks to the USB function driver.
    strict SetInterface(resource struct {
        interface client_end:UsbFunctionInterface;
    }) -> (struct {
        s zx.Status;
    });

    /// Allocates a unique interface descriptor number.
    strict AllocInterface() -> (struct {
        s zx.Status;
        intf_num uint8;
    });

    /// Allocates a unique endpoint descriptor number.
    strict AllocEp(struct {
        direction uint8;
    }) -> (struct {
        s zx.Status;
        address uint8;
    });

    /// Configures an endpoint based on provided descriptors.
    strict ConfigEp(struct {
        ep_desc fuchsia.hardware.usb.descriptor.UsbEndpointDescriptor;
        ss_comp_desc fuchsia.hardware.usb.descriptor.UsbSsEpCompDescriptor;
    }) -> (struct {
        s zx.Status;
    });

    /// Disables the specified endpoint.
    strict DisableEp(struct {
        address uint8;
    }) -> (struct {
        s zx.Status;
    });

    /// Adds a string descriptor to the device configuration.
    strict AllocStringDesc(struct {
        string string:MAX;
    }) -> (struct {
        s zx.Status;
        index uint8;
    });

    /// Queues a USB request with the lower level driver.
    strict RequestQueue(resource struct {
        @in_out
        usb_request fuchsia.hardware.usb.request.UsbRequest;
        @in_out
        complete_cb client_end:fuchsia.hardware.usb.request.UsbRequestCompleteCallback;
    }) -> ();

    /// Stalls the specified endpoint.
    strict EpSetStall(struct {
        ep_address uint8;
    }) -> (struct {
        s zx.Status;
    });

    /// Clears a stall condition for the specified endpoint.
    strict EpClearStall(struct {
        ep_address uint8;
    }) -> (struct {
        s zx.Status;
    });

    /// Returns the size needed for a |usb_request_t|, including private storage needed by the
    /// HCI driver.
    strict GetRequestSize() -> (struct {
        size uint64;
    });

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

/// Interface implemented by the USB function driver.
@transport("Banjo")
@banjo_layout("ddk-interface")
closed protocol UsbFunctionInterface {
    /// Returns the size of the descriptor list for the function.
    strict GetDescriptorsSize() -> (struct {
        size uint64;
    });

    /// 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.
    strict GetDescriptors() -> (struct {
        @buffer
        descriptors vector<uint8>:MAX;
    });

    /// Callback for handling ep0 control requests.
    strict Control(struct {
        setup fuchsia.hardware.usb.descriptor.UsbSetup;
        @buffer
        write vector<uint8>:MAX;
    }) -> (struct {
        status zx.Status;
        @buffer
        read vector<uint8>:MAX;
    });
    /// 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.
    strict SetConfigured(struct {
        configured bool;
        speed fuchsia.hardware.usb.descriptor.UsbSpeed;
    }) -> (struct {
        s zx.Status;
    });

    /// 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.
    strict SetInterface(struct {
        interface uint8;
        alt_setting uint8;
    }) -> (struct {
        s zx.Status;
    });
};
