// 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.block.driver;

using fuchsia.hardware.block;
using zx;

alias Vmoid = uint16;

// Dummy vmoid value reserved for "invalid". Will never be allocated; can be
// used as a local value for unallocated / freed ID.
const BLOCK_VMOID_INVALID Vmoid = 0;

const BLOCK_GUID_LEN uint32 = 16;

/// Multiple block I/O operations may be sent at once before a response is
/// actually sent back. Block I/O ops may be sent concurrently to different
/// vmoids, and they also may be sent to different groups at any point in time.
///
/// `MAX_TXN_GROUP_COUNT` "groups" are pre-allocated lanes separated on the
/// block server.  Using a group allows multiple message to be buffered at once
/// on a single communication channel before receiving a response.
///
/// Usage of groups is identified by the `GROUP_ITEM` flag, and is optional.
///
/// These groups may be referred to with a "groupid", in the range [0,
/// `MAX_TXN_GROUP_COUNT`).
///
/// The protocol to communicate with a single group is as follows:
/// 1) SEND [N - 1] messages with an allocated groupid for any value of 1 <= N.
///    The `GROUP_ITEM` flag is set for these messages.
/// 2) SEND a final Nth message with the same groupid. The `GROUP_ITEM
///    | GROUP_LAST` flags are set for this message.
/// 3) RECEIVE a single response from the Block I/O server after all N requests
///    have completed. This response is sent once all operations either complete
///    or a single operation fails. At this point, step (1) may begin again for
///    the same groupid.
///
/// For `READ` and `WRITE`, N may be greater than 1. Otherwise,
/// N == 1 (skipping step (1) in the protocol above).
///
/// Notes:
/// - groupids may operate on any number of vmoids at once.
/// - If additional requests are sent on the same groupid before step (3) has
///   completed, then the additional request will not be processed. If
///   `GROUP_LAST` is set, an error will be returned. Otherwise, the
///   request will be silently dropped.
/// - Messages within a group are not guaranteed to be processed in any order
///   relative to each other.
/// - All requests receive responses, except for ones with `GROUP_ITEM`
///   that do not have `GROUP_LAST` set.
///
/// For example, the following is a valid sequence of transactions:
///
///   -> (groupid = 1, vmoid = 1, OP = Write | GroupItem,             reqid = 1)
///   -> (groupid = 1, vmoid = 2, OP = Write | GroupItem,             reqid = 2)
///   -> (groupid = 2, vmoid = 3, OP = Write | GroupItem | GroupLast, reqid = 0)
///   <- Response sent to groupid = 2, reqid = 0
///   -> (groupid = 1, vmoid = 1, OP = Read | GroupItem | GroupLast,  reqid = 3)
///   <- Response sent to groupid = 1, reqid = 3
///   -> (groupid = 3, vmoid = 1, OP = Write | GroupItem,             reqid = 4)
///   -> (groupid = don't care, vmoid = 1, OP = Read, reqid = 5)
///   <- Response sent to reqid = 5
///   -> (groupid = 3, vmoid = 1, OP = Read | GroupItem | GroupLast,  reqid = 6)
///   <- Response sent to groupid = 3, reqid = 6
///
/// Each transaction reads or writes up to `length` blocks from the device,
/// starting at `dev_offset` blocks, into the VMO associated with `vmoid`,
/// starting at `vmo_offset` blocks.  If the transaction is out of range, for
/// example if `length` is too large or if `dev_offset` is beyond the end of the
/// device, `ZX_ERR_OUT_OF_RANGE` is returned.
const MAX_TXN_GROUP_COUNT uint32 = 8;

/// `READ`, `WRITE`
//
// Note: this data structure is used for the driver <--> driver interfaces,
// while `BlockFifoRequest` is part of a client <--> server interface and
// related to the block FIDL API.
//
// See src/storage/lib/block_client/cpp/block_fifo.h for FIFO protocol.
//
type BlockReadWrite = resource struct {
    /// Opcode and flags.
    command BlockCommand;

    /// Available for temporary use.
    extra uint32;

    /// VMO of data to read or write.
    vmo zx.Handle:VMO;

    /// Transfer length in blocks (0 is invalid).
    length uint32;

    /// Device offset in blocks.
    offset_dev uint64;

    /// VMO offset in blocks.
    offset_vmo uint64;
};

/// `TRIM`
type BlockTrim = struct {
    /// Opcode and flags.
    command BlockCommand;

    /// Transfer length in blocks (0 is invalid).
    length uint32;

    /// Device offset in blocks.
    offset_dev uint64;
};

type BlockOp = strict resource union {
    /// All Commands
    1: command BlockCommand;

    /// Read and Write ops use rw for parameters.
    2: rw BlockReadWrite;
    3: trim BlockTrim;
};

type BlockCommand = struct {
    opcode @generated_name("BlockOpcode") strict enum : uint8 {
        /// Performs a regular data read or write from the device. The operation may
        /// be cached internally.
        READ = 1;
        WRITE = 2;

        /// Write any controller or device cached data to nonvolatile storage.
        FLUSH = 3;

        /// Instructs the device to invalidate a number of blocks, making them  usable
        /// for storing something else. This is basically a "delete" optimization,
        /// where the device is in charge of discarding the old content without
        /// clients having to write a given pattern. The operation may be cached
        /// internally.
        TRIM = 4;

        /// Detaches the VMO from the block device.
        CLOSE_VMO = 5;
    };

    flags @generated_name("BlockIoFlag") strict bits : uint32 {
        /// Associate the following request with `group`.
        GROUP_ITEM = 0x00000001;

        /// Only respond after this request (and all previous within group) have
        /// completed. Only valid with `GROUP_ITEM`.
        GROUP_LAST = 0x00000002;

        /// Mark this operation as "Force Unit Access" (FUA), indicating that
        /// it should not complete until the data is written to the non-volatile
        /// medium (write), and that reads should bypass any on-device caches.
        FORCE_ACCESS = 0x00000004;

        /// The pre-flush flag generates a flush operation before running this operation
        /// and flushes on-device caches. It ensures that previous data is written to
        /// the non-volatile medium. Applying the preflush to an operation in a group
        /// will only apply to the operation with the flag and not all the other
        /// operations in the group. The preflush only applies to an operation where the
        /// preflush flag is set. It does not affect other operations and can proceed in
        /// parallel. If the flush operation fails, the operation will not proceed.
        PREFLUSH = 0x00000008;
    };
};

closed protocol Common {
    /// Obtains the parameters of the block device (`block_info_t`) and the
    /// required size of `block_txn_t`. The `block_txn_t`s submitted via
    /// `Queue()` must have `block_op_size_out - sizeof(block_op_t)` bytes
    /// available at the end of the structure for the use of the driver.
    strict Query() -> (struct {
        info fuchsia.hardware.block.BlockInfo;
        block_op_size uint64;
    });

    /// Submits an I/O request for processing. Ownership of `op` is transferred
    /// to callee until `completion_cb` is invoked. Success or failure will be
    /// reported via the `completion_cb`. This callback may be called before the
    /// `Queue()` method returns.
    @async
    strict Queue(resource struct {
        @in_out
        txn BlockOp;
    }) -> (resource struct {
        status zx.Status;
        @mutable
        op BlockOp;
    });
};

@transport("Banjo")
@banjo_layout("ddk-protocol")
closed protocol BlockImpl {
    compose Common;
};

@transport("Banjo")
@banjo_layout("ddk-protocol")
closed protocol Block {
    compose Common;
};
