Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2020, Western Digital Corporation. All rights reserved.
3 : : * Copyright (c) 2021 Mellanox Technologies LTD. All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/nvme_zns.h"
7 : : #include "nvme_internal.h"
8 : :
9 : : const struct spdk_nvme_zns_ns_data *
10 : 76 : spdk_nvme_zns_ns_get_data(struct spdk_nvme_ns *ns)
11 : : {
12 : 76 : return ns->nsdata_zns;
13 : : }
14 : :
15 : : uint64_t
16 : 4 : spdk_nvme_zns_ns_get_zone_size_sectors(struct spdk_nvme_ns *ns)
17 : : {
18 : 4 : const struct spdk_nvme_zns_ns_data *nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
19 : 4 : const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns);
20 : : uint32_t format_index;
21 : :
22 : 4 : format_index = spdk_nvme_ns_get_format_index(nsdata);
23 : :
24 : 4 : return nsdata_zns->lbafe[format_index].zsze;
25 : : }
26 : :
27 : : uint64_t
28 : 0 : spdk_nvme_zns_ns_get_zone_size(struct spdk_nvme_ns *ns)
29 : : {
30 : 0 : return spdk_nvme_zns_ns_get_zone_size_sectors(ns) * spdk_nvme_ns_get_sector_size(ns);
31 : : }
32 : :
33 : : uint64_t
34 : 1 : spdk_nvme_zns_ns_get_num_zones(struct spdk_nvme_ns *ns)
35 : : {
36 [ # # ]: 1 : return spdk_nvme_ns_get_num_sectors(ns) / spdk_nvme_zns_ns_get_zone_size_sectors(ns);
37 : : }
38 : :
39 : : uint32_t
40 : 2 : spdk_nvme_zns_ns_get_max_open_zones(struct spdk_nvme_ns *ns)
41 : : {
42 : 2 : const struct spdk_nvme_zns_ns_data *nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
43 : :
44 : 2 : return nsdata_zns->mor + 1;
45 : : }
46 : :
47 : : uint32_t
48 : 2 : spdk_nvme_zns_ns_get_max_active_zones(struct spdk_nvme_ns *ns)
49 : : {
50 : 2 : const struct spdk_nvme_zns_ns_data *nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
51 : :
52 : 2 : return nsdata_zns->mar + 1;
53 : : }
54 : :
55 : : const struct spdk_nvme_zns_ctrlr_data *
56 : 108 : spdk_nvme_zns_ctrlr_get_data(struct spdk_nvme_ctrlr *ctrlr)
57 : : {
58 : 108 : return ctrlr->cdata_zns;
59 : : }
60 : :
61 : : uint32_t
62 : 2 : spdk_nvme_zns_ctrlr_get_max_zone_append_size(const struct spdk_nvme_ctrlr *ctrlr)
63 : : {
64 : 2 : return ctrlr->max_zone_append_size;
65 : : }
66 : :
67 : : int
68 : 0 : spdk_nvme_zns_zone_append(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
69 : : void *buffer, uint64_t zslba,
70 : : uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
71 : : uint32_t io_flags)
72 : : {
73 : 0 : return nvme_ns_cmd_zone_append_with_md(ns, qpair, buffer, NULL, zslba, lba_count,
74 : : cb_fn, cb_arg, io_flags, 0, 0);
75 : : }
76 : :
77 : : int
78 : 244417 : spdk_nvme_zns_zone_append_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
79 : : void *buffer, void *metadata, uint64_t zslba,
80 : : uint32_t lba_count, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
81 : : uint32_t io_flags, uint16_t apptag_mask, uint16_t apptag)
82 : : {
83 : 244417 : return nvme_ns_cmd_zone_append_with_md(ns, qpair, buffer, metadata, zslba, lba_count,
84 : : cb_fn, cb_arg, io_flags, apptag_mask, apptag);
85 : : }
86 : :
87 : : int
88 : 0 : spdk_nvme_zns_zone_appendv(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
89 : : uint64_t zslba, uint32_t lba_count,
90 : : spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
91 : : spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
92 : : spdk_nvme_req_next_sge_cb next_sge_fn)
93 : : {
94 : 0 : return nvme_ns_cmd_zone_appendv_with_md(ns, qpair, zslba, lba_count, cb_fn, cb_arg,
95 : : io_flags, reset_sgl_fn, next_sge_fn,
96 : : NULL, 0, 0);
97 : : }
98 : :
99 : : int
100 : 0 : spdk_nvme_zns_zone_appendv_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
101 : : uint64_t zslba, uint32_t lba_count,
102 : : spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t io_flags,
103 : : spdk_nvme_req_reset_sgl_cb reset_sgl_fn,
104 : : spdk_nvme_req_next_sge_cb next_sge_fn, void *metadata,
105 : : uint16_t apptag_mask, uint16_t apptag)
106 : : {
107 : 0 : return nvme_ns_cmd_zone_appendv_with_md(ns, qpair, zslba, lba_count, cb_fn, cb_arg,
108 : : io_flags, reset_sgl_fn, next_sge_fn,
109 : : metadata, apptag_mask, apptag);
110 : : }
111 : :
112 : : static int
113 : 1 : nvme_zns_zone_mgmt_recv(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
114 : : void *payload, uint32_t payload_size, uint64_t slba,
115 : : uint8_t zone_recv_action, uint8_t zra_spec_field, bool zra_spec_feats,
116 : : spdk_nvme_cmd_cb cb_fn, void *cb_arg)
117 : : {
118 : : struct nvme_request *req;
119 : : struct spdk_nvme_cmd *cmd;
120 : :
121 : 1 : req = nvme_allocate_request_user_copy(qpair, payload, payload_size, cb_fn, cb_arg, false);
122 [ - + ]: 1 : if (req == NULL) {
123 : 0 : return -ENOMEM;
124 : : }
125 : :
126 : 1 : cmd = &req->cmd;
127 : 1 : cmd->opc = SPDK_NVME_OPC_ZONE_MGMT_RECV;
128 : 1 : cmd->nsid = ns->id;
129 : :
130 : 1 : *(uint64_t *)&cmd->cdw10 = slba;
131 : 1 : cmd->cdw12 = spdk_nvme_bytes_to_numd(payload_size);
132 [ # # # # ]: 1 : cmd->cdw13 = zone_recv_action | zra_spec_field << 8 | zra_spec_feats << 16;
133 : :
134 : 1 : return nvme_qpair_submit_request(qpair, req);
135 : : }
136 : :
137 : : int
138 : 1 : spdk_nvme_zns_report_zones(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
139 : : void *payload, uint32_t payload_size, uint64_t slba,
140 : : enum spdk_nvme_zns_zra_report_opts report_opts, bool partial_report,
141 : : spdk_nvme_cmd_cb cb_fn, void *cb_arg)
142 : : {
143 : 1 : return nvme_zns_zone_mgmt_recv(ns, qpair, payload, payload_size, slba,
144 : : SPDK_NVME_ZONE_REPORT, report_opts, partial_report,
145 : : cb_fn, cb_arg);
146 : : }
147 : :
148 : : int
149 : 0 : spdk_nvme_zns_ext_report_zones(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
150 : : void *payload, uint32_t payload_size, uint64_t slba,
151 : : enum spdk_nvme_zns_zra_report_opts report_opts, bool partial_report,
152 : : spdk_nvme_cmd_cb cb_fn, void *cb_arg)
153 : : {
154 : 0 : return nvme_zns_zone_mgmt_recv(ns, qpair, payload, payload_size, slba,
155 : : SPDK_NVME_ZONE_EXTENDED_REPORT, report_opts, partial_report,
156 : : cb_fn, cb_arg);
157 : : }
158 : :
159 : : static int
160 : 43 : nvme_zns_zone_mgmt_send(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
161 : : uint64_t slba, bool select_all, uint8_t zone_send_action,
162 : : spdk_nvme_cmd_cb cb_fn, void *cb_arg)
163 : : {
164 : : struct nvme_request *req;
165 : : struct spdk_nvme_cmd *cmd;
166 : :
167 : 43 : req = nvme_allocate_request_null(qpair, cb_fn, cb_arg);
168 [ - + ]: 43 : if (req == NULL) {
169 : 0 : return -ENOMEM;
170 : : }
171 : :
172 : 43 : cmd = &req->cmd;
173 : 43 : cmd->opc = SPDK_NVME_OPC_ZONE_MGMT_SEND;
174 : 43 : cmd->nsid = ns->id;
175 : :
176 [ + - ]: 43 : if (!select_all) {
177 : 43 : *(uint64_t *)&cmd->cdw10 = slba;
178 : : }
179 : :
180 [ # # ]: 43 : cmd->cdw13 = zone_send_action | select_all << 8;
181 : :
182 : 43 : return nvme_qpair_submit_request(qpair, req);
183 : : }
184 : :
185 : : int
186 : 0 : spdk_nvme_zns_close_zone(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint64_t slba,
187 : : bool select_all, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
188 : : {
189 : 0 : return nvme_zns_zone_mgmt_send(ns, qpair, slba, select_all, SPDK_NVME_ZONE_CLOSE,
190 : : cb_fn, cb_arg);
191 : : }
192 : :
193 : : int
194 : 0 : spdk_nvme_zns_finish_zone(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint64_t slba,
195 : : bool select_all, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
196 : : {
197 : 0 : return nvme_zns_zone_mgmt_send(ns, qpair, slba, select_all, SPDK_NVME_ZONE_FINISH,
198 : : cb_fn, cb_arg);
199 : : }
200 : :
201 : : int
202 : 0 : spdk_nvme_zns_open_zone(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint64_t slba,
203 : : bool select_all, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
204 : : {
205 : 0 : return nvme_zns_zone_mgmt_send(ns, qpair, slba, select_all, SPDK_NVME_ZONE_OPEN,
206 : : cb_fn, cb_arg);
207 : : }
208 : :
209 : : int
210 : 43 : spdk_nvme_zns_reset_zone(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint64_t slba,
211 : : bool select_all, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
212 : : {
213 : 43 : return nvme_zns_zone_mgmt_send(ns, qpair, slba, select_all, SPDK_NVME_ZONE_RESET,
214 : : cb_fn, cb_arg);
215 : : }
216 : :
217 : : int
218 : 0 : spdk_nvme_zns_offline_zone(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, uint64_t slba,
219 : : bool select_all, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
220 : : {
221 : 0 : return nvme_zns_zone_mgmt_send(ns, qpair, slba, select_all, SPDK_NVME_ZONE_OFFLINE,
222 : : cb_fn, cb_arg);
223 : : }
224 : :
225 : : int
226 : 0 : spdk_nvme_zns_set_zone_desc_ext(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
227 : : uint64_t slba, void *buffer, uint32_t payload_size,
228 : : spdk_nvme_cmd_cb cb_fn, void *cb_arg)
229 : : {
230 : : struct nvme_request *req;
231 : : struct spdk_nvme_cmd *cmd;
232 : :
233 [ # # ]: 0 : if (payload_size == 0) {
234 : 0 : return -EINVAL;
235 : : }
236 : :
237 [ # # ]: 0 : if (buffer == NULL) {
238 : 0 : return -EINVAL;
239 : : }
240 : :
241 : 0 : req = nvme_allocate_request_user_copy(qpair, buffer, payload_size, cb_fn, cb_arg, true);
242 [ # # ]: 0 : if (req == NULL) {
243 : 0 : return -ENOMEM;
244 : : }
245 : :
246 : 0 : cmd = &req->cmd;
247 : 0 : cmd->opc = SPDK_NVME_OPC_ZONE_MGMT_SEND;
248 : 0 : cmd->nsid = ns->id;
249 : :
250 : 0 : *(uint64_t *)&cmd->cdw10 = slba;
251 : :
252 : 0 : cmd->cdw13 = SPDK_NVME_ZONE_SET_ZDE;
253 : :
254 : 0 : return nvme_qpair_submit_request(qpair, req);
255 : : }
|