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 #include "oob_doubler.h"
6
7 #include <ddktl/protocol/nand.h>
8 #include <unittest/unittest.h>
9
10 namespace {
11
12 constexpr uint32_t kPageSize = 100;
13 constexpr uint32_t kOobSize = 10;
14 constexpr uint32_t kBlockSize = 50;
15 constexpr size_t kOpSize = 42;
16 constexpr size_t kUnchanged = 20;
17
18 class NandTester : public ddk::NandProtocol<NandTester> {
19 public:
NandTester()20 NandTester() : proto_({&nand_protocol_ops_, this}) {
21 info_.page_size = kPageSize;
22 info_.oob_size = kOobSize;
23 info_.pages_per_block = kBlockSize;
24 info_.num_blocks = kUnchanged;
25 info_.ecc_bits = kUnchanged;
26 }
27
proto()28 nand_protocol_t* proto() { return &proto_; }
operation()29 nand_operation_t* operation() { return &operation_; }
30
NandQuery(fuchsia_hardware_nand_Info * out_info,size_t * out_nand_op_size)31 void NandQuery(fuchsia_hardware_nand_Info* out_info, size_t* out_nand_op_size) {
32 *out_info = info_;
33 *out_nand_op_size = kOpSize;
34 }
35
NandQueue(nand_operation_t * operation,nand_queue_callback callback,void * cookie)36 void NandQueue(nand_operation_t* operation, nand_queue_callback callback, void* cookie) {
37 operation_ = *operation;
38 }
39
NandGetFactoryBadBlockList(uint32_t * out_bad_blocks_list,size_t bad_blocks_count,size_t * out_bad_blocks_actual)40 zx_status_t NandGetFactoryBadBlockList(uint32_t* out_bad_blocks_list, size_t bad_blocks_count,
41 size_t* out_bad_blocks_actual) {
42 return ZX_OK;
43 }
44
45 private:
46 nand_protocol_t proto_;
47 fuchsia_hardware_nand_Info info_ = {};
48 nand_operation_t operation_ = {};
49 };
50
TrivialLifetimeTest()51 bool TrivialLifetimeTest() {
52 BEGIN_TEST;
53 NandTester tester;
54 ftl::OobDoubler doubler(tester.proto(), false);
55 END_TEST;
56 }
57
QueryDisabledTest()58 bool QueryDisabledTest() {
59 BEGIN_TEST;
60 NandTester tester;
61 ftl::OobDoubler doubler(tester.proto(), false);
62
63 fuchsia_hardware_nand_Info info;
64 size_t op_size;
65 doubler.Query(&info, &op_size);
66 EXPECT_EQ(kPageSize, info.page_size);
67 EXPECT_EQ(kOobSize, info.oob_size);
68 EXPECT_EQ(kBlockSize, info.pages_per_block);
69 EXPECT_EQ(kUnchanged, info.num_blocks);
70 EXPECT_EQ(kUnchanged, info.ecc_bits);
71 EXPECT_EQ(kOpSize, op_size);
72 END_TEST;
73 }
74
QueryEnabledTest()75 bool QueryEnabledTest() {
76 BEGIN_TEST;
77 NandTester tester;
78 ftl::OobDoubler doubler(tester.proto(), true);
79
80 fuchsia_hardware_nand_Info info;
81 size_t op_size;
82 doubler.Query(&info, &op_size);
83 EXPECT_EQ(kPageSize * 2, info.page_size);
84 EXPECT_EQ(kOobSize * 2, info.oob_size);
85 EXPECT_EQ(kBlockSize / 2, info.pages_per_block);
86 EXPECT_EQ(kUnchanged, info.num_blocks);
87 EXPECT_EQ(kUnchanged, info.ecc_bits);
88 EXPECT_EQ(kOpSize, op_size);
89 END_TEST;
90 }
91
QueueDisabledTest()92 bool QueueDisabledTest() {
93 BEGIN_TEST;
94 NandTester tester;
95 ftl::OobDoubler doubler(tester.proto(), false);
96
97 nand_operation_t op = {};
98 op.command = NAND_OP_READ;
99 op.rw.length = 5;
100 op.rw.offset_nand = 6;
101 op.rw.offset_data_vmo = 7;
102 op.rw.offset_oob_vmo = 8;
103 doubler.Queue(&op, nullptr, nullptr);
104
105 nand_operation_t* result = tester.operation();
106 EXPECT_EQ(NAND_OP_READ, result->command);
107 EXPECT_EQ(5, result->rw.length);
108 EXPECT_EQ(6, result->rw.offset_nand);
109 EXPECT_EQ(7, result->rw.offset_data_vmo);
110 EXPECT_EQ(8, result->rw.offset_oob_vmo);
111 END_TEST;
112 }
113
QueueEnabledTest()114 bool QueueEnabledTest() {
115 BEGIN_TEST;
116 NandTester tester;
117 ftl::OobDoubler doubler(tester.proto(), true);
118
119 nand_operation_t op = {};
120 op.command = NAND_OP_READ;
121 op.rw.length = 5;
122 op.rw.offset_nand = 6;
123 op.rw.offset_data_vmo = 7;
124 op.rw.offset_oob_vmo = 8;
125 doubler.Queue(&op, nullptr, nullptr);
126
127 nand_operation_t* result = tester.operation();
128 EXPECT_EQ(NAND_OP_READ, result->command);
129 EXPECT_EQ(10, result->rw.length);
130 EXPECT_EQ(12, result->rw.offset_nand);
131 EXPECT_EQ(14, result->rw.offset_data_vmo);
132 EXPECT_EQ(16, result->rw.offset_oob_vmo);
133 END_TEST;
134 }
135
136 } // namespace
137
138 BEGIN_TEST_CASE(OobDoublerTests)
139 RUN_TEST_SMALL(TrivialLifetimeTest)
140 RUN_TEST_SMALL(QueryDisabledTest)
141 RUN_TEST_SMALL(QueryEnabledTest)
142 RUN_TEST_SMALL(QueueDisabledTest)
143 RUN_TEST_SMALL(QueueEnabledTest)
144 END_TEST_CASE(OobDoublerTests)
145