// 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.
@available(added=7)
library fuchsia.hardware.usb;

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

@transport("Banjo")
@banjo_layout("ddk-protocol")
closed protocol Usb {
    // Initiates a control transfer with the device in the OUT direction.
    strict ControlOut(struct {
        request_type uint8;
        request uint8;
        value uint16;
        index uint16;
        timeout zx.Time;
        @buffer
        write vector<uint8>:MAX;
    }) -> (struct {
        status zx.Status;
    });

    // Initiates a control transfer with the device in the IN direction.
    strict ControlIn(struct {
        request_type uint8;
        request uint8;
        value uint16;
        index uint16;
        timeout zx.Time;
    }) -> (struct {
        status zx.Status;
        @buffer
        read vector<uint8>:MAX;
    });

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

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

    /// Selects an alternate setting for a USB interface.
    strict SetInterface(struct {
        interface_number uint8;
        alt_setting uint8;
    }) -> (struct {
        s zx.Status;
    });

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

    /// Selects the configuration for the device.
    strict SetConfiguration(struct {
        configuration uint8;
    }) -> (struct {
        s zx.Status;
    });

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

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

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

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

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

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

    /// Returns the length of the configuration descriptor for the specified configuration.
    strict GetConfigurationDescriptorLength(struct {
        configuration uint8;
    }) -> (struct {
        s zx.Status;
        length uint64;
    });

    /// Returns the configuration descriptor for the specified configuration.
    strict GetConfigurationDescriptor(struct {
        configuration uint8;
    }) -> (struct {
        s zx.Status;
        @buffer
        desc vector<uint8>:MAX;
    });

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

    /// returns the USB descriptors for the USB device or interface.
    strict GetDescriptors() -> (struct {
        @buffer
        descs vector<uint8>:MAX;
    });

    /// 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.
    strict GetStringDescriptor(struct {
        desc_id uint8;
        lang_id uint16;
    }) -> (struct {
        s zx.Status;
        lang_id uint16;
        @buffer
        string vector<uint8>:MAX;
    });
    /// Cancels all transactions currently queued on the specified endpoint.
    strict CancelAll(struct {
        ep_address uint8;
    }) -> (struct {
        s zx.Status;
    });

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

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