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