blob: ea9eab4cd0ff8090abe84d1b1ffc878dd98c669a [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.
#ifndef SRC_DEVICES_NAND_DRIVERS_NANDPART_NANDPART_H_
#define SRC_DEVICES_NAND_DRIVERS_NANDPART_NANDPART_H_
#include <fuchsia/hardware/badblock/cpp/banjo.h>
#include <fuchsia/hardware/nand/c/banjo.h>
#include <fuchsia/hardware/nand/cpp/banjo.h>
#include <lib/ddk/device.h>
#include <zircon/types.h>
#include <utility>
#include <ddktl/device.h>
#include <fbl/array.h>
#include <fbl/macros.h>
#include <fbl/ref_ptr.h>
#include "bad-block.h"
namespace nand {
class NandPartDevice;
using DeviceType = ddk::Device<NandPartDevice, ddk::GetProtocolable, ddk::Initializable>;
class NandPartDevice : public DeviceType,
public ddk::NandProtocol<NandPartDevice, ddk::base_protocol>,
public ddk::BadBlockProtocol<NandPartDevice> {
public:
// Spawns device nodes based on parent node.
static zx_status_t Create(void* ctx, zx_device_t* parent);
zx_status_t Bind(const char* name, uint32_t copy_count);
// Device protocol implementation.
zx_status_t DdkGetProtocol(uint32_t proto_id, void* protocol);
void DdkInit(ddk::InitTxn txn);
void DdkRelease() { delete this; }
// nand protocol implementation.
void NandQuery(nand_info_t* info_out, size_t* nand_op_size_out);
void NandQueue(nand_operation_t* op, nand_queue_callback completion_cb, void* cookie);
zx_status_t NandGetFactoryBadBlockList(uint32_t* bad_blocks, size_t bad_block_len,
size_t* num_bad_blocks);
// Bad block protocol implementation.
zx_status_t BadBlockGetBadBlockList(uint32_t* bad_block_list, size_t bad_block_list_len,
size_t* bad_block_count);
zx_status_t BadBlockMarkBlockBad(uint32_t block);
private:
explicit NandPartDevice(zx_device_t* parent, const nand_protocol_t& nand_proto,
fbl::RefPtr<BadBlock> bad_block, size_t parent_op_size,
const nand_info_t& nand_info, uint32_t erase_block_start)
: DeviceType(parent),
nand_proto_(nand_proto),
nand_(&nand_proto_),
parent_op_size_(parent_op_size),
nand_info_(nand_info),
erase_block_start_(erase_block_start),
bad_block_(std::move(bad_block)) {}
DISALLOW_COPY_ASSIGN_AND_MOVE(NandPartDevice);
nand_protocol_t nand_proto_;
ddk::NandProtocolClient nand_;
// op_size for parent device.
size_t parent_op_size_;
// info about nand.
nand_info_t nand_info_;
// First erase block for the partition.
uint32_t erase_block_start_;
// Device specific bad block info. Shared between all devices for a given
// parent device.
fbl::RefPtr<BadBlock> bad_block_;
// Cached list of bad blocks for this partition. Lazily instantiated.
fbl::Array<uint32_t> bad_block_list_;
uint32_t extra_partition_copy_count_;
};
} // namespace nand
#endif // SRC_DEVICES_NAND_DRIVERS_NANDPART_NANDPART_H_