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