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

using ddk.physiter;
using zircon.hw.usb;
using zx;

/// Should be set by the requestor.
struct UsbHeader {
    /// Frame number for scheduling isochronous transfers.
    uint64 frame;
    uint32 device_id;
    /// bEndpointAddress from endpoint descriptor.
    uint8 ep_address;
    /// Number of bytes to transfer.
    zx.off length;
    /// Send zero length packet if length is multiple of max packet size.
    bool send_zlp;
};

/// Response data.
/// (Filled in by processor before |UsbRequestComplete()| is called)
struct UsbResponse {
    /// Status of transaction.
    zx.status status;
    /// Number of bytes actually transferred (on success).
    zx.off actual;
    /// Number of consecutive requests that were silently completed immediately prior to this
    /// request.
    /// This only needs to be checked if the client has set |cb_on_error_only| on any requests,
    /// otherwise it will always be zero.
    uint64 silent_completions_count;
};

struct UsbRequest {
    UsbHeader header;

    /// For control transactions.
    zircon.hw.usb.UsbSetup setup;

    /// VMO handle for payload.
    handle<vmo> vmo_handle;
    usize size;
    /// Offset of the start of data from first page address of the vmo.
    zx.off offset;
    /// Mapped address of the first page of the vmo.
    /// Add offset to get actual data.
    uint64 virt;

    handle pmt;
    /// Phys addresses of the payload.
    vector<zx.paddr>? phys;

    vector<ddk.physiter.PhysIterSgEntry>? sg;

    UsbResponse response;

    /// usb_request_release() frees the request if this is true.
    bool release_frees;

    usize alloc_size;

    /// Set by the requester if the callback should be skipped on successful completion.
    /// This is useful for isochronous requests, where the requester does not care about
    /// most callbacks.
    /// The requester is in charge of keeping track of the order of queued requests and
    /// requeuing silently completed requests.
    ///
    /// There may be cases where a request completes out of order. For example, errors
    /// are reported as soon as possible, rather than preserving queue order.
    /// Due to this, the requester may receive additional callbacks on top of those requested.
    ///
    /// If the requester receives a callback, they should check the response's
    /// |silent_completions_count| to know how many consecutive requests prior to this one
    /// (in relation to queue order for the endpoint) have completed successfully.
    bool cb_on_error_only;
    /// Direct mode -- if set to true, this packet is handled with high priority directly
    /// in interrupt context. It will NOT be safe to block in any callbacks, and all layers
    /// should take the most direct path to route the packet to the requesting driver from
    /// hardware.
    bool direct;
    /// If true, resets an endpoint and does not transfer any data.
    bool reset;
    /// The address of the endpoint to reset.
    uint8 reset_address;
};

[Layout="ddk-callback"]
protocol UsbRequestComplete {
    Callback(UsbRequest? req) -> ();
};
