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

using fuchsia.hardware.usb.descriptor;
using fuchsia.hardware.usb.request;
using zx;

[Transport = "Banjo", BanjoLayout = "ddk-protocol"]
protocol Usb {
    // Initiates a control transfer with the device in the OUT direction.
    ControlOut(uint8 request_type, uint8 request, uint16 value, uint16 index, zx.time timeout,
               [Buffer] vector<uint8>:MAX write) -> (zx.status status);

    // Initiates a control transfer with the device in the IN direction.
    ControlIn(uint8 request_type, uint8 request, uint16 value, uint16 index, zx.time timeout)
        -> (zx.status status, [Buffer] vector<uint8>:MAX read);

    /// Queues a USB request.
    RequestQueue([InOut] fuchsia.hardware.usb.request.UsbRequest usb_request,
                 [InOut] fuchsia.hardware.usb.request.UsbRequestCompleteCallback complete_cb) -> ();

    /// Returns the speed of the device.
    GetSpeed() -> (fuchsia.hardware.usb.descriptor.UsbSpeed s);

    /// Selects an alternate setting for a USB interface.
    SetInterface(uint8 interface_number, uint8 alt_setting) -> (zx.status s);

    /// Returns the currently selected configuration for the device.
    GetConfiguration() -> (uint8 configuration);

    /// Selects the configuration for the device.
    SetConfiguration(uint8 configuration) -> (zx.status s);

    /// Enables a USB endpoint, configuring it as specified by the provided descriptors.
    EnableEndpoint(fuchsia.hardware.usb.descriptor.UsbEndpointDescriptor ep_desc,
                   fuchsia.hardware.usb.descriptor.UsbSsEpCompDescriptor ss_com_desc,
                   bool enable) -> (zx.status s);

    /// Resets an endpoint that is in a halted or error state.
    /// Endpoints will be halted if the device returns a STALL in response to a USB transaction.
    /// When that occurs, the transaction will fail with ERR_IO_REFUSED.
    /// usb_reset_endpoint() the endpoint to normal running state.
    ResetEndpoint(uint8 ep_address) -> (zx.status s);

    /// Resets the device and restores the prior configuration.
    /// Returns ZX_ERR_BAD_STATE if the device is already being reset.
    ResetDevice() -> (zx.status s);

    /// Returns the maximum amount of data that can be transferred on an endpoint in a single
    /// transaction.
    GetMaxTransferSize(uint8 ep_address) -> (uint64 s);

    /// Returns the device ID for the device.
    /// This ID is generated by and used internally by the USB HCI controller driver.
    GetDeviceId() -> (uint32 dev_id);

    /// Returns the device's device descriptor.
    GetDeviceDescriptor() -> (fuchsia.hardware.usb.descriptor.UsbDeviceDescriptor desc);

    /// Returns the length of the configuration descriptor for the specified configuration.
    GetConfigurationDescriptorLength(uint8 configuration) -> (zx.status s, uint64 length);

    /// Returns the configuration descriptor for the specified configuration.
    GetConfigurationDescriptor(uint8 configuration) -> (zx.status s, [Buffer] vector<uint8>:MAX desc);

    /// Returns the length of the USB descriptors for the USB device or interface.
    GetDescriptorsLength() -> (uint64 length);

    /// returns the USB descriptors for the USB device or interface.
    GetDescriptors() -> ([Buffer] vector<uint8>:MAX descs);

    /// Fetch the descriptor using the provided descriptor ID and language ID.  If
    /// the language ID requested is not available, the first entry of the language
    /// ID table will be used instead and be provided in the updated version of the
    /// parameter.
    ///
    /// The string will be encoded using UTF-8, and will be truncated to fit the
    /// space provided by the buflen parameter.  buflen will be updated to indicate
    /// the amount of space needed to hold the actual UTF-8 encoded string lenth, and
    /// may be larger than the original value passed.  Embedded nulls may be present
    /// in the string, and the result may not be null terminated if the string
    /// occupies the entire provided buffer.
    GetStringDescriptor(uint8 desc_id, uint16 lang_id) -> (zx.status s, uint16 lang_id,
                                                           [Buffer] vector<uint8>:MAX string);
    /// Cancels all transactions currently queued on the specified endpoint.
    CancelAll(uint8 ep_address) -> (zx.status s);

    /// Returns the current frame (in milliseconds), used for isochronous transfers.
    GetCurrentFrame() -> (uint64 frame);

    /// Returns the size needed for a |usb_request_t|, including private storage needed by
    /// all layers of the USB stack.
    GetRequestSize() -> (uint64 size);
};
