blob: 405bf4c543787c71e3e245e6d6813b43788d308f [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.
// WARNING: This file is machine generated by fidlc.
#pragma once
#include <ddk/protocol/nand.h>
#include <ddktl/device-internal.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/device/nand.h>
#include <zircon/types.h>
#include "nand-internal.h"
// DDK nand-protocol support
//
// :: Proxies ::
//
// ddk::NandProtocolProxy is a simple wrapper around
// nand_protocol_t. It does not own the pointers passed to it
//
// :: Mixins ::
//
// ddk::NandProtocol is a mixin class that simplifies writing DDK drivers
// that implement the nand protocol. It doesn't set the base protocol.
//
// :: Examples ::
//
// // A driver that implements a ZX_PROTOCOL_NAND device.
// class NandDevice {
// using NandDeviceType = ddk::Device<NandDevice, /* ddk mixins */>;
//
// class NandDevice : public NandDeviceType,
// public ddk::NandProtocol<NandDevice> {
// public:
// NandDevice(zx_device_t* parent)
// : NandDeviceType("my-nand-protocol-device", parent) {}
//
// void NandQuery(nand_info_t* out_info, size_t* out_nand_op_size);
//
// void NandQueue(nand_operation_t* op, nand_queue_callback callback, void* cookie);
//
// zx_status_t NandGetFactoryBadBlockList(uint32_t* out_bad_blocks_list, size_t
// bad_blocks_count, size_t* out_bad_blocks_actual);
//
// ...
// };
namespace ddk {
template <typename D>
class NandProtocol : public internal::base_protocol {
public:
NandProtocol() {
internal::CheckNandProtocolSubclass<D>();
ops_.query = NandQuery;
ops_.queue = NandQueue;
ops_.get_factory_bad_block_list = NandGetFactoryBadBlockList;
// Can only inherit from one base_protocol implementation.
ZX_ASSERT(ddk_proto_id_ = 0);
ddk_proto_id_ = ZX_PROTOCOL_NAND;
ddk_proto_ops_ = &ops_;
}
protected:
nand_protocol_ops_t ops_ = {};
private:
// Obtains the parameters of the nand device (nand_info_t) and the required
// size of nand_op_t. The nand_op_t's submitted via queue() must have
// nand_op_size_out - sizeof(nand_op_t) bytes available at the end of the
// structure for the use of the driver.
static void NandQuery(void* ctx, nand_info_t* out_info, size_t* out_nand_op_size) {
static_cast<D*>(ctx)->NandQuery(out_info, out_nand_op_size);
}
// Submits an IO request for processing. Success or failure will be reported
// via the completion_cb() in the nand_op_t. The callback may be called
// before the queue() method returns.
static void NandQueue(void* ctx, nand_operation_t* op, nand_queue_callback callback,
void* cookie) {
static_cast<D*>(ctx)->NandQueue(op, callback, cookie);
}
// Gets the list of bad erase blocks, as reported by the nand manufacturer.
// The caller must allocate a table large enough to hold the expected number
// of entries, and pass the size of that table on |bad_block_len|.
// On return, |num_bad_blocks| contains the number of bad blocks found.
// 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.
static zx_status_t NandGetFactoryBadBlockList(void* ctx, uint32_t* out_bad_blocks_list,
size_t bad_blocks_count,
size_t* out_bad_blocks_actual) {
return static_cast<D*>(ctx)->NandGetFactoryBadBlockList(
out_bad_blocks_list, bad_blocks_count, out_bad_blocks_actual);
}
};
class NandProtocolProxy {
public:
NandProtocolProxy() : ops_(nullptr), ctx_(nullptr) {}
NandProtocolProxy(const nand_protocol_t* proto) : ops_(proto->ops), ctx_(proto->ctx) {}
void GetProto(nand_protocol_t* proto) {
proto->ctx = ctx_;
proto->ops = ops_;
}
bool is_valid() { return ops_ != nullptr; }
void clear() {
ctx_ = nullptr;
ops_ = nullptr;
}
// Obtains the parameters of the nand device (nand_info_t) and the required
// size of nand_op_t. The nand_op_t's submitted via queue() must have
// nand_op_size_out - sizeof(nand_op_t) bytes available at the end of the
// structure for the use of the driver.
void Query(nand_info_t* out_info, size_t* out_nand_op_size) {
ops_->query(ctx_, out_info, out_nand_op_size);
}
// Submits an IO request for processing. Success or failure will be reported
// via the completion_cb() in the nand_op_t. The callback may be called
// before the queue() method returns.
void Queue(nand_operation_t* op, nand_queue_callback callback, void* cookie) {
ops_->queue(ctx_, op, callback, cookie);
}
// Gets the list of bad erase blocks, as reported by the nand manufacturer.
// The caller must allocate a table large enough to hold the expected number
// of entries, and pass the size of that table on |bad_block_len|.
// On return, |num_bad_blocks| contains the number of bad blocks found.
// 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.
zx_status_t GetFactoryBadBlockList(uint32_t* out_bad_blocks_list, size_t bad_blocks_count,
size_t* out_bad_blocks_actual) {
return ops_->get_factory_bad_block_list(ctx_, out_bad_blocks_list, bad_blocks_count,
out_bad_blocks_actual);
}
private:
nand_protocol_ops_t* ops_;
void* ctx_;
};
} // namespace ddk