blob: 0e7d4850ca9e2b99643256081aa2fc82e5d10d0a [file] [log] [blame]
// Copyright 2019 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;
using fuchsia.unknown;
using zx;
/// The maximum value for a transfer size, identifying that there
/// effectively exists no maximum for a single operation.
const MAX_TRANSFER_UNBOUNDED uint32 = 0xFFFFFFFF;
/// Value reserved for "invalid" VmoId. Will never be allocated by the server,
/// and may be utilized as a local value for an unallocated ID.
const VMOID_INVALID uint16 = 0;
/// Represents a session with a block device.
///
/// This protocol encodes the underlying object's lifetime in both directions; the underlying object
/// is alive iff both ends of the protocol are open. That is:
///
/// - Closing the client end causes the object to be destroyed.
/// - Observing a closure of the server end indicates the object no longer exists.
///
/// The object can be destroyed synchronously using [`fuchsia.unknown/Closeable.Close`].
closed protocol Session {
compose fuchsia.unknown.Closeable;
/// Returns a handle to the client end of the FIFO.
strict GetFifo() -> (resource struct {
fifo zx.Handle:<FIFO>;
}) error zx.Status;
/// Attaches a VMO to the session.
///
/// Returns an identifer that can be used to refer to the VMO.
strict AttachVmo(resource struct {
vmo zx.Handle:VMO;
}) -> (struct {
// TODO(https://fxbug.dev/42054535): consider removing the outer struct when the issue is
// resolved.
vmoid @generated_name("VmoId") struct {
id uint16;
};
}) error zx.Status;
};
type BlockInfo = struct {
/// The number of blocks in this block device.
block_count uint64;
/// The size of a single block.
block_size uint32;
/// The maximum size, in bytes, of a transfer.
/// Set to MAX_TRANSFER_UNBOUNDED if no such maximum exists.
max_transfer_size uint32;
/// Identifiers about the device.
flags @generated_name("Flag") strict bits : uint32 {
/// All writes to the block device will fail.
READONLY = 0x00000001;
/// The block device may be removed from the device during operation.
REMOVABLE = 0x00000002;
/// The device has a bootdata partition map.
BOOTPART = 0x00000004;
/// The device provides trim support.
TRIM_SUPPORT = 0x00000008;
/// The device provides fua support.
FUA_SUPPORT = 0x00000010;
};
};
/// Describes a re-mapping of a block range. See OffsetMap.
/// Note that all fields are in *blocks*, not bytes.
@available(added=HEAD)
type BlockOffsetMapping = struct {
source_block_offset uint64;
target_block_offset uint64;
length uint64;
};
/// Defines access to a device which is accessible in block-granularity chunks
/// for reading and writing.
closed protocol Block {
/// Get information about the underlying block device.
strict GetInfo() -> (struct {
// TODO(https://fxbug.dev/42054535): consider removing the outer struct when the issue is
// resolved.
info BlockInfo;
}) error zx.Status;
/// Opens a new FIFO-based session on the block device.
strict OpenSession(resource struct {
session server_end:Session;
});
/// Opens a new FIFO-based session on the block device, providing a mapping which is
/// transparently applied to device offsets in block FIFO requests.
///
/// This interface is intended to be used internally between nested Block implementations, in
/// order to provide passthrough I/O. For example, a fixed partition map (e.g. GPT) will serve
/// a Block protocol for each partition, and will respond to OpenSession requests by calling
/// OpenSessionWithOffsetMap on the underlying block device, establishing itself as the source
/// for translating client block offsets (relative to the partition start) to absolute offsets.
/// The client can then communicate directly with the underlying block device, and the partition
/// offsets can be transparently applied to requests.
strict OpenSessionWithOffsetMap(resource struct {
session server_end:Session;
mapping BlockOffsetMapping;
});
};