// 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 ddk.protocol.usb;

using ddk.protocol.usb.request;
using zircon.hw.usb;
using zx;

[Layout = "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,
               vector<voidptr> 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, vector<voidptr> read);

    /// Queues a USB request.
    RequestQueue(ddk.protocol.usb.request.UsbRequest? usb_request,
                 ddk.protocol.usb.request.UsbRequestComplete? complete_cb) -> ();

    /// Returns the speed of the device.
    GetSpeed() -> (zircon.hw.usb.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(zircon.hw.usb.UsbEndpointDescriptor ep_desc,
                   zircon.hw.usb.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) -> (usize 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() -> (zircon.hw.usb.UsbDeviceDescriptor desc);

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

    /// Returns the configuration descriptor for the specified configuration.
    GetConfigurationDescriptor(uint8 configuration) -> (zx.status s, vector<voidptr> desc);

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

    /// returns the USB descriptors for the USB device or interface.
    GetDescriptors() -> (vector<voidptr> 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,
                                                           vector<voidptr> 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() -> (usize size);
};

