xref: /spdk/lib/ftl/ftl_l2p_flat.c (revision 510f4c134a21b45ff3a5add9ebc6c6cf7e49aeab)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "ftl_l2p.h"
7 #include "ftl_core.h"
8 #include "ftl_band.h"
9 #include "ftl_utils.h"
10 #include "ftl_l2p_flat.h"
11 #include "utils/ftl_addr_utils.h"
12 
13 static struct ftl_md *
14 get_l2p_md(struct spdk_ftl_dev *dev)
15 {
16 	return dev->layout.md[FTL_LAYOUT_REGION_TYPE_L2P];
17 }
18 
19 struct ftl_l2p_flat {
20 	void *l2p;
21 	bool is_halted;
22 };
23 
24 void
25 ftl_l2p_flat_pin(struct spdk_ftl_dev *dev, struct ftl_l2p_pin_ctx *pin_ctx)
26 {
27 	assert(dev->num_lbas >= pin_ctx->lba + pin_ctx->count);
28 
29 	ftl_l2p_pin_complete(dev, 0, pin_ctx);
30 }
31 
32 void
33 ftl_l2p_flat_unpin(struct spdk_ftl_dev *dev, uint64_t lba, uint64_t count)
34 {
35 	assert(dev->num_lbas >= lba + count);
36 }
37 
38 void
39 ftl_l2p_flat_set(struct spdk_ftl_dev *dev, uint64_t lba, ftl_addr addr)
40 {
41 	struct ftl_l2p_flat *l2p_flat = dev->l2p;
42 
43 	assert(dev->num_lbas > lba);
44 
45 	ftl_addr_store(dev, l2p_flat->l2p, lba, addr);
46 }
47 
48 ftl_addr
49 ftl_l2p_flat_get(struct spdk_ftl_dev *dev, uint64_t lba)
50 {
51 	struct ftl_l2p_flat *l2p_flat = dev->l2p;
52 
53 	assert(dev->num_lbas > lba);
54 
55 	return ftl_addr_load(dev, l2p_flat->l2p, lba);
56 }
57 
58 static void
59 md_cb(struct spdk_ftl_dev *dev, struct ftl_md *md, int status)
60 {
61 	ftl_l2p_cb cb = md->owner.private;
62 	void *cb_ctx = md->owner.cb_ctx;
63 
64 	cb(dev, status, cb_ctx);
65 }
66 
67 void
68 ftl_l2p_flat_clear(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
69 {
70 	struct ftl_l2p_flat *l2p_flat = dev->l2p;
71 	struct ftl_md *md;
72 
73 	memset(l2p_flat->l2p, (int)FTL_ADDR_INVALID,
74 	       ftl_md_get_buffer_size(get_l2p_md(dev)));
75 
76 	md = get_l2p_md(dev);
77 	md->cb = md_cb;
78 	md->owner.cb_ctx = cb_ctx;
79 	md->owner.private = cb;
80 	ftl_md_persist(md);
81 }
82 
83 static int
84 ftl_l2p_flat_init_dram(struct spdk_ftl_dev *dev, struct ftl_l2p_flat *l2p_flat,
85 		       size_t l2p_size)
86 {
87 	struct ftl_md *md = get_l2p_md(dev);
88 
89 	assert(ftl_md_get_buffer_size(md) >= l2p_size);
90 
91 	l2p_flat->l2p = ftl_md_get_buffer(md);
92 	if (!l2p_flat->l2p) {
93 		FTL_ERRLOG(dev, "Failed to allocate l2p table\n");
94 		return -1;
95 	}
96 
97 	return 0;
98 }
99 
100 int
101 ftl_l2p_flat_init(struct spdk_ftl_dev *dev)
102 {
103 	size_t l2p_size = dev->num_lbas * dev->layout.l2p.addr_size;
104 	struct ftl_l2p_flat *l2p_flat;
105 	int ret;
106 
107 	if (dev->num_lbas == 0) {
108 		FTL_ERRLOG(dev, "Invalid l2p table size\n");
109 		return -1;
110 	}
111 
112 	if (dev->l2p) {
113 		FTL_ERRLOG(dev, "L2p table already allocated\n");
114 		return -1;
115 	}
116 
117 	l2p_flat = calloc(1, sizeof(*l2p_flat));
118 	if (!l2p_flat) {
119 		FTL_ERRLOG(dev, "Failed to allocate l2p_flat\n");
120 		return -1;
121 	}
122 
123 	ret = ftl_l2p_flat_init_dram(dev, l2p_flat, l2p_size);
124 
125 	if (ret) {
126 		free(l2p_flat);
127 		return ret;
128 	}
129 
130 	dev->l2p = l2p_flat;
131 	return 0;
132 }
133 
134 void
135 ftl_l2p_flat_deinit(struct spdk_ftl_dev *dev)
136 {
137 	struct ftl_l2p_flat *l2p_flat = dev->l2p;
138 
139 	if (!l2p_flat) {
140 		return;
141 	}
142 
143 	free(l2p_flat);
144 
145 	dev->l2p = NULL;
146 }
147 
148 void
149 ftl_l2p_flat_unmap(struct spdk_ftl_dev *dev, ftl_l2p_cb cb, void *cb_ctx)
150 {
151 	cb(dev, 0, cb_ctx);
152 }
153 
154 void
155 ftl_l2p_flat_process(struct spdk_ftl_dev *dev)
156 {
157 }
158 
159 bool
160 ftl_l2p_flat_is_halted(struct spdk_ftl_dev *dev)
161 {
162 	return true;
163 }
164 
165 void
166 ftl_l2p_flat_halt(struct spdk_ftl_dev *dev)
167 {
168 }
169