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 "block_device.h"
6
7 #include <ddk/debug.h>
8 #include <zircon/assert.h>
9
10 #include "nand_driver.h"
11
12 namespace ftl {
13
~BlockDevice()14 BlockDevice::~BlockDevice() {
15 bool volume_created = (DdkGetSize() != 0);
16 if (volume_created) {
17 if (volume_->Unmount() != ZX_OK) {
18 zxlogf(ERROR, "FTL: FtlUmmount() failed");
19 }
20 }
21 }
22
Bind()23 zx_status_t BlockDevice::Bind() {
24 zxlogf(INFO, "FTL: parent: '%s'\n", device_get_name(parent()));
25
26 if (device_get_protocol(parent(), ZX_PROTOCOL_NAND, &parent_) != ZX_OK) {
27 zxlogf(ERROR, "FTL: device '%s' does not support nand protocol\n",
28 device_get_name(parent()));
29 return ZX_ERR_NOT_SUPPORTED;
30 }
31
32 // Get the optional bad block protocol.
33 if (device_get_protocol(parent(), ZX_PROTOCOL_BAD_BLOCK, &bad_block_) != ZX_OK) {
34 zxlogf(WARN, "FTL: Parent device '%s': does not support bad_block protocol\n",
35 device_get_name(parent()));
36 }
37
38 zx_status_t status = Init();
39 if (status != ZX_OK) {
40 return status;
41 }
42 return DdkAdd("ftl");
43 }
44
DdkUnbind()45 void BlockDevice::DdkUnbind() {
46 DdkRemove();
47 }
48
Init()49 zx_status_t BlockDevice::Init() {
50 if (!InitFtl()) {
51 return ZX_ERR_NO_RESOURCES;
52 }
53
54 return ZX_OK;
55 }
56
OnVolumeAdded(uint32_t page_size,uint32_t num_pages)57 bool BlockDevice::OnVolumeAdded(uint32_t page_size, uint32_t num_pages) {
58 params_ = {page_size, num_pages};
59 zxlogf(INFO, "FTL: %d pages of %d bytes\n", num_pages, page_size);
60 return true;
61 }
62
InitFtl()63 bool BlockDevice::InitFtl() {
64 std::unique_ptr<NandDriver> driver = NandDriver::Create(&parent_, &bad_block_);
65 memcpy(guid_, driver->info().partition_guid, ZBI_PARTITION_GUID_LEN);
66
67 if (!volume_) {
68 volume_ = std::make_unique<ftl::VolumeImpl>(this);
69 }
70
71 const char* error = volume_->Init(std::move(driver));
72 if (error) {
73 zxlogf(ERROR, "FTL: %s\n", error);
74 return false;
75 }
76
77 zxlogf(INFO, "FTL: InitFtl ok\n");
78 return true;
79 }
80
81 } // namespace ftl.
82