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 0 : spdk_nvme_zns_ns_get_data(struct spdk_nvme_ns *ns)
11 : {
12 0 : return ns->nsdata_zns;
13 : }
14 :
15 : uint64_t
16 0 : spdk_nvme_zns_ns_get_zone_size_sectors(struct spdk_nvme_ns *ns)
17 : {
18 0 : const struct spdk_nvme_zns_ns_data *nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
19 0 : const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns);
20 0 : uint32_t format_index;
21 :
22 0 : format_index = spdk_nvme_ns_get_format_index(nsdata);
23 :
24 0 : return nsdata_zns->lbafe[format_index].zsze;
25 0 : }
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 0 : spdk_nvme_zns_ns_get_num_zones(struct spdk_nvme_ns *ns)
35 : {
36 0 : return spdk_nvme_ns_get_num_sectors(ns) / spdk_nvme_zns_ns_get_zone_size_sectors(ns);
37 : }
38 :
39 : uint32_t
40 0 : spdk_nvme_zns_ns_get_max_open_zones(struct spdk_nvme_ns *ns)
41 : {
42 0 : const struct spdk_nvme_zns_ns_data *nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
43 :
44 0 : return nsdata_zns->mor + 1;
45 0 : }
46 :
47 : uint32_t
48 0 : spdk_nvme_zns_ns_get_max_active_zones(struct spdk_nvme_ns *ns)
49 : {
50 0 : const struct spdk_nvme_zns_ns_data *nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
51 :
52 0 : return nsdata_zns->mar + 1;
53 0 : }
54 :
55 : const struct spdk_nvme_zns_ctrlr_data *
56 0 : spdk_nvme_zns_ctrlr_get_data(struct spdk_nvme_ctrlr *ctrlr)
57 : {
58 0 : return ctrlr->cdata_zns;
59 : }
60 :
61 : uint32_t
62 0 : spdk_nvme_zns_ctrlr_get_max_zone_append_size(const struct spdk_nvme_ctrlr *ctrlr)
63 : {
64 0 : 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 0 : cb_fn, cb_arg, io_flags, 0, 0);
75 : }
76 :
77 : int
78 0 : 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 0 : return nvme_ns_cmd_zone_append_with_md(ns, qpair, buffer, metadata, zslba, lba_count,
84 0 : 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 0 : 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 0 : io_flags, reset_sgl_fn, next_sge_fn,
109 0 : metadata, apptag_mask, apptag);
110 : }
111 :
112 : static int
113 0 : 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 0 : struct nvme_request *req;
119 0 : struct spdk_nvme_cmd *cmd;
120 :
121 0 : req = nvme_allocate_request_user_copy(qpair, payload, payload_size, cb_fn, cb_arg, false);
122 0 : if (req == NULL) {
123 0 : return -ENOMEM;
124 : }
125 :
126 0 : cmd = &req->cmd;
127 0 : cmd->opc = SPDK_NVME_OPC_ZONE_MGMT_RECV;
128 0 : cmd->nsid = ns->id;
129 :
130 0 : *(uint64_t *)&cmd->cdw10 = slba;
131 0 : cmd->cdw12 = spdk_nvme_bytes_to_numd(payload_size);
132 0 : cmd->cdw13 = zone_recv_action | zra_spec_field << 8 | zra_spec_feats << 16;
133 :
134 0 : return nvme_qpair_submit_request(qpair, req);
135 0 : }
136 :
137 : int
138 0 : 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 0 : return nvme_zns_zone_mgmt_recv(ns, qpair, payload, payload_size, slba,
144 0 : SPDK_NVME_ZONE_REPORT, report_opts, partial_report,
145 0 : 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 0 : SPDK_NVME_ZONE_EXTENDED_REPORT, report_opts, partial_report,
156 0 : cb_fn, cb_arg);
157 : }
158 :
159 : static int
160 0 : 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 0 : struct nvme_request *req;
165 0 : struct spdk_nvme_cmd *cmd;
166 :
167 0 : req = nvme_allocate_request_null(qpair, cb_fn, cb_arg);
168 0 : if (req == NULL) {
169 0 : return -ENOMEM;
170 : }
171 :
172 0 : cmd = &req->cmd;
173 0 : cmd->opc = SPDK_NVME_OPC_ZONE_MGMT_SEND;
174 0 : cmd->nsid = ns->id;
175 :
176 0 : if (!select_all) {
177 0 : *(uint64_t *)&cmd->cdw10 = slba;
178 0 : }
179 :
180 0 : cmd->cdw13 = zone_send_action | select_all << 8;
181 :
182 0 : return nvme_qpair_submit_request(qpair, req);
183 0 : }
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 0 : 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 0 : 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 0 : cb_fn, cb_arg);
207 : }
208 :
209 : int
210 0 : 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 0 : return nvme_zns_zone_mgmt_send(ns, qpair, slba, select_all, SPDK_NVME_ZONE_RESET,
214 0 : 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 0 : 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 0 : struct nvme_request *req;
231 0 : 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 0 : }
|