1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <memory> 8 9 #include <ddk/protocol/badblock.h> 10 #include <ddk/protocol/nand.h> 11 #include <ddktl/device.h> 12 #include <ddktl/protocol/badblock.h> 13 #include <fbl/macros.h> 14 #include <lib/ftl/volume.h> 15 #include <zircon/boot/image.h> 16 #include <zircon/types.h> 17 18 namespace ftl { 19 20 struct BlockParams { GetSizeBlockParams21 uint64_t GetSize() const { 22 return static_cast<uint64_t>(page_size) * num_pages; 23 } 24 25 uint32_t page_size; 26 uint32_t num_pages; 27 }; 28 29 class BlockDevice; 30 using DeviceType = ddk::Device<BlockDevice, ddk::GetSizable, ddk::Unbindable>; 31 32 // Provides the bulk of the functionality for a FTL-backed block device. 33 class BlockDevice : public DeviceType, public ftl::FtlInstance { 34 public: DeviceType(parent)35 explicit BlockDevice(zx_device_t* parent = nullptr) : DeviceType(parent) {} 36 ~BlockDevice(); 37 38 zx_status_t Bind(); DdkRelease()39 void DdkRelease() { delete this; } 40 void DdkUnbind(); 41 42 // Performs the object initialization. 43 zx_status_t Init(); 44 45 // Device protocol implementation. DdkGetSize()46 zx_off_t DdkGetSize() { return params_.GetSize(); } 47 48 // FtlInstance interface. 49 bool OnVolumeAdded(uint32_t page_size, uint32_t num_pages) final; 50 SetVolumeForTest(std::unique_ptr<ftl::Volume> volume)51 void SetVolumeForTest(std::unique_ptr<ftl::Volume> volume) { 52 volume_ = std::move(volume); 53 } 54 55 DISALLOW_COPY_ASSIGN_AND_MOVE(BlockDevice); 56 57 private: 58 bool InitFtl(); 59 60 BlockParams params_ = {}; 61 62 nand_protocol_t parent_ = {}; 63 bad_block_protocol_t bad_block_ = {}; 64 std::unique_ptr<ftl::Volume> volume_; 65 uint8_t guid_[ZBI_PARTITION_GUID_LEN] = {}; 66 }; 67 68 } // namespace ftl. 69