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 "nand_operation.h"
6
7 #include <ddk/debug.h>
8 #include <ddk/driver.h>
9 #include <zircon/process.h>
10
11 namespace ftl {
12
SetDataVmo(size_t num_bytes)13 zx_status_t NandOperation::SetDataVmo(size_t num_bytes) {
14 nand_operation_t* operation = GetOperation();
15 if (!operation) {
16 return ZX_ERR_NO_MEMORY;
17 }
18 zx_status_t status = GetVmo(num_bytes);
19 if (status != ZX_OK) {
20 return status;
21 }
22
23 operation->rw.data_vmo = mapper_.vmo().get();
24 return ZX_OK;
25 }
26
SetOobVmo(size_t num_bytes)27 zx_status_t NandOperation::SetOobVmo(size_t num_bytes) {
28 nand_operation_t* operation = GetOperation();
29 if (!operation) {
30 return ZX_ERR_NO_MEMORY;
31 }
32 zx_status_t status = GetVmo(num_bytes);
33 if (status != ZX_OK) {
34 return status;
35 }
36
37 operation->rw.oob_vmo = mapper_.vmo().get();
38 return ZX_OK;
39 }
40
GetOperation()41 nand_operation_t* NandOperation::GetOperation() {
42 if (!raw_buffer_) {
43 CreateOperation();
44 }
45 return reinterpret_cast<nand_operation_t*>(raw_buffer_.get());
46 }
47
Execute(OobDoubler * parent)48 zx_status_t NandOperation::Execute(OobDoubler* parent) {
49 parent->Queue(GetOperation(), OnCompletion, this);
50 zx_status_t status = sync_completion_wait(&event_, ZX_SEC(60));
51 sync_completion_reset(&event_);
52 if (status != ZX_OK) {
53 return status;
54 }
55 return status_;
56 }
57
58 // Static.
OnCompletion(void * cookie,zx_status_t status,nand_operation_t * op)59 void NandOperation::OnCompletion(void* cookie, zx_status_t status, nand_operation_t* op) {
60 NandOperation* operation = reinterpret_cast<NandOperation*>(cookie);
61 operation->status_ = status;
62 sync_completion_signal(&operation->event_);
63 }
64
GetVmo(size_t num_bytes)65 zx_status_t NandOperation::GetVmo(size_t num_bytes) {
66 if (mapper_.start()) {
67 return ZX_OK;
68 }
69
70 return mapper_.CreateAndMap(num_bytes, "");
71 }
72
CreateOperation()73 void NandOperation::CreateOperation() {
74 ZX_DEBUG_ASSERT(op_size_ >= sizeof(nand_operation_t));
75 raw_buffer_.reset(new char[op_size_]);
76
77 memset(raw_buffer_.get(), 0, op_size_);
78 }
79
80 } // namespace ftl.
81