blob: 7305899e52f1f41badf5818dac3626d29fc5fb34 [file] [log] [blame]
// 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.
/// NandOperation's are submitted for processing via the queue() method of the
/// Nand Protocol. Once submitted, the contents of the NandOperation may be modified
/// while it's being processed.
///
/// The completion_cb() must eventually be called upon success or failure and
/// at that point the cookie field must contain whatever value was in it when
/// the NandOperation was originally queued.
///
/// corrected_bit_flips are always related to nand_info.ecc_bits, so it is
/// possible to obtain a value that is larger than what is being read (in the oob
/// case). On the other hand, if errors cannot be corrected, the operation will
/// fail, and corrected_bit_flips will be undefined.
library fuchsia.hardware.nand;
using fuchsia.hardware.nandinfo;
using zx;
/// NOTE: The protocol can be extended with barriers to support controllers that
/// may issue multiple simultaneous request to the IO chips.
type NandOp = strict enum : uint32 {
READ = 0x1;
WRITE = 0x2;
ERASE = 0x3;
READ_BYTES = 0x4;
WRITE_BYTES = 0x5;
};
/// A single operation can read or write an arbitrary number of pages,
/// including out of band (OOB) data for each page. If either regular
/// data or OOB is not required, the relevant VMO handle should be set to
/// ZX_HANDLE_INVALID.
///
/// Note that length dictates the number of pages to access, regardless
/// of the type of data requested: regular data, OOB or both.
///
/// The OOB data will be copied to (and from) a contiguous memory range
/// starting at the given offset. Note that said offset is given in nand
/// pages even though OOB is just a handful of bytes per page. In other
/// words, after said offset, the OOB data for each page is located
/// nand_info.oob_size bytes apart.
///
/// For example, to read 5 pages worth of data + OOB, with page size of
/// 2 kB and 16 bytes of OOB per page, setting:
///
/// data_vmo = oob_vmo = vmo_handle
/// length = 5
/// offset_nand = 20
/// offset_data_vmo = 0
/// offset_oob_vmo = 5
///
/// will transfer pages [20, 24] to the first 2048 * 5 bytes of the vmo,
/// followed by 16 * 5 bytes of OOB data starting at offset 2048 * 5.
type NandReadWrite = resource struct {
/// Command.
command NandOp;
/// vmo of data to read or write.
data_vmo zx.Handle:VMO;
/// vmo of OOB data to read or write.
oob_vmo zx.Handle:VMO;
/// Number of pages to access.
/// (0 is invalid).
length uint32;
/// Offset into nand, in pages.
offset_nand uint32;
/// Data vmo offset in (nand) pages.
offset_data_vmo uint64;
/// OOB vmo offset in (nand) pages.
offset_oob_vmo uint64;
/// Return value from READ_DATA, max corrected bit flips in any
/// underlying ECC chunk read. The caller can compare this value
/// against ecc_bits to decide whether the nand erase block needs to
/// be recycled.
corrected_bit_flips uint32;
};
/// This is the same as |NandReadWrite|, except all values are in bytes rather
/// than pages. This doesn't support reading/writing OOB data.
/// Not supported by all NAND devices.
type NandReadWriteBytes = resource struct {
/// Command.
command NandOp;
/// vmo of data to read or write.
data_vmo zx.Handle:VMO;
/// Number of bytes to read or write.
/// 0 is invalid.
length uint64;
/// Offset into nand, in bytes.
offset_nand uint64;
/// Data vmo offset in bytes.
offset_data_vmo uint64;
};
type NandErase = struct {
/// Command.
command NandOp;
/// Offset into nand, in erase blocks.
first_block uint32;
/// Number of blocks to erase. (0 is invalid).
num_blocks uint32;
};
type NandOperation = strict resource union {
/// All Commands.
1: command NandOp;
/// NAND_OP_READ, NAND_OP_WRITE.
2: rw NandReadWrite;
/// NAND_OP_ERASE.
3: erase NandErase;
/// NAND_OP_READ_BYTES, NAND_OP_WRITE_BYTES.
4: rw_bytes NandReadWriteBytes;
};
@transport("Banjo")
@banjo_layout("ddk-protocol")
closed protocol Nand {
/// Obtains the parameters of the nand device and the required
/// size of |NandOperation|. The |NandOperation| submitted via Queue() must have
/// `nand_op_size - sizeof(NandOperation)` bytes available at the end of the
/// structure for the use of the driver.
strict Query() -> (struct {
info fuchsia.hardware.nandinfo.NandInfo;
nand_op_size uint64;
});
/// Submits an IO request for processing. Success or failure will be reported
/// via the callback. The callback may be called before the Queue() method returns.
/// Should return ZX_ERR_IO *only* when error occurred due to underlying hardware.
/// When the hardware is not able to correct all bitflips for a page, the
/// driver should return ZX_ERR_IO_DATA_INTEGRITY.
@async
strict Queue(resource struct {
@in_out
op NandOperation;
}) -> (resource struct {
status zx.Status;
@mutable
op NandOperation;
});
/// Gets the list of bad erase blocks, as reported by the nand manufacturer.
/// This should only be called before writing any data to the nand, and the
/// returned data should be saved somewhere else, along blocks that become
/// bad after they've been in use.
strict GetFactoryBadBlockList() -> (struct {
status zx.Status;
bad_blocks vector<uint32>:MAX;
});
};