// 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.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(fuchsia.hardware.usb.request.UsbRequest? usb_request,
                 fuchsia.hardware.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);
};

