// Copyright 2023 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.endpoint;

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

/// Bulk Endpoint Information
type BulkEndpointInfo = table {};

/// Control Endpoint Information
type ControlEndpointInfo = table {};

/// Isochronous Endpoint Information
type IsochronousEndpointInfo = table {
    /// Lead time described in number of transfers.
    1: lead_time uint64;
};

/// Interrupt Endpoint Information
type InterruptEndpointInfo = table {};

/// Endpoint Information
type EndpointInfo = flexible union {
    /// Bulk endpoint information
    1: bulk BulkEndpointInfo;
    /// Control endpoint information
    2: control ControlEndpointInfo;
    /// Isochronous endpoint information
    3: isochronous IsochronousEndpointInfo;
    /// Interrupt endpoint information
    4: interrupt InterruptEndpointInfo;
};

/// Arbitrary limit on the number of VMOs in one call to `RegisterVmos()` or `UnregisterVmos()`.
const VMO_VECTOR_MAX uint32 = 300;
/// Arbitrary limit on the number of Requests in one call to `QueueRequest()`.
const REQUEST_MAX uint32 = 300;

/// VMO information for registering VMOs. Only used for `RegisterVmos()` to convey the ID to register
/// a VMO to and its size.
type VmoInfo = table {
    /// ID corresponding to the VMO to be registered.
    1: id fuchsia.hardware.usb.request.VmoId;
    /// Size of VMO to register.
    2: size uint64;
};

/// VMO handle returned for registered VMOs. Only used as a return value for `UnregisterVmos()` to
/// associate a VMO handle with the VmoId it was registered to.
type VmoHandle = resource table {
    /// ID corresponding to the registered VMO as passed in by `RegisterVmos()` through `VmoInfo`.
    1: id fuchsia.hardware.usb.request.VmoId;
    /// Handle to VMO.
    2: vmo zx.Handle:VMO;
};

/// Completion
type Completion = resource table {
    /// Request completed.
    1: request fuchsia.hardware.usb.request.Request;
    /// Completion status.
    2: status zx.Status;
    /// Bytes successfully transferred.
    3: transfer_size uint64;
};

/// Endpoint Interface.
/// Pre-registered VMOs associated with the Endpoint are tied to the lifetime of the Endpoint. When
/// the Endpoint is closed, all outstanding registered VMOs are unregistered, references to their
/// handles dropped and any necessary actions for DisableEndpoint will be called.
@discoverable
closed protocol Endpoint {
    /// Gets endpoint information
    strict GetInfo() -> (struct {
        info EndpointInfo;
    }) error zx.Status;

    /// Registers and pins VMOs to the vmo_ids. Returns
    ///  * vmo: Handles to successfully registered vmo_ids.
    /// VMO IDs that are already are registered to will fail.
    strict RegisterVmos(resource struct {
        vmo_ids vector<VmoInfo>:VMO_VECTOR_MAX;
    }) -> (resource struct {
        vmos vector<VmoHandle>:VMO_VECTOR_MAX;
    });
    /// Unregisters the VMOs corresponding to the vmo_ids. Returns
    ///  * failed_vmo_ids: vmo_ids that failed to unregister.
    ///  * errors: Error values that correspond 1:1 to failed_vmo_ids above.
    strict UnregisterVmos(struct {
        vmo_ids vector<fuchsia.hardware.usb.request.VmoId>:VMO_VECTOR_MAX;
    }) -> (resource struct {
        failed_vmo_ids vector<fuchsia.hardware.usb.request.VmoId>:VMO_VECTOR_MAX;
        errors vector<zx.Status>:VMO_VECTOR_MAX;
    });

    /// Submit Requests to queue. Processed starting with the 0th Request. Submitting a vector of
    /// Requests allows for pre-buffering.
    ///
    /// Clients are responsible for cache management and ensuring cache coherency.
    ///
    /// After read requests:
    /// - Call zx_cache_flush with ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE on buffers that
    ///   have been mapped by the client.
    /// - Call zx_vmo_op_range with ZX_VMO_OP_CACHE_CLEAN_INVALIDATE on all other buffers.
    ///
    /// Note that writing to any portion of a buffer before OnCompletion is called for that buffer
    /// can corrupt the received data.
    ///
    /// Before write requests:
    /// - Call zx_cache_flush with ZX_CACHE_FLUSH_DATA on buffers that have been mapped by the
    ///   client.
    /// - Call zx_vmo_op_range with ZX_VMO_OP_CACHE_CLEAN on all other buffers.
    ///
    /// Requests may be pre-buffered. In other words, requests may be queued for data that is not
    /// present/ready in the buffer yet. The USB Endpoint Server consuming requests does not care
    /// if the data in the buffer is ready or not and will always process requests on schedule. It
    /// is the responsibility of the USB Endpoint Client that submits requests to ensure that data
    /// is ready on schedule.
    ///  * Definition of "on schedule" varies for different endpoints and controllers. In general,
    ///    this will be communicated by the `lead_time` parameter returned by `GetInfo`.
    strict QueueRequests(resource struct {
        req vector<fuchsia.hardware.usb.request.Request>:REQUEST_MAX;
    });
    /// Called on a completion to notify the device driver of an completion event.
    /// Note that if more than REQUEST_MAX successful requests with defer_completion == true have
    /// been seen, driver may call OnCompletion multiple times when defer_completion == false is
    /// seen (or failure happens) to return all seen requests to the client.
    strict -> OnCompletion(resource struct {
        completion vector<Completion>:REQUEST_MAX;
    });

    /// Cancels all requests. Returns
    ///  * ZX_ERR_IO_NOT_PRESENT: If device is not running, disconnected, or inactive.
    ///  * ZX_ERR_IO: If cancel failed due to an unsuccessful request.
    strict CancelAll() -> () error zx.Status;
};
