Commit | Line | Data |
---|---|---|
bc50ad75 | 1 | // SPDX-License-Identifier: GPL-2.0 |
3d030e41 JT |
2 | /* |
3 | * NVM Express device driver tracepoints | |
4 | * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH | |
3d030e41 JT |
5 | */ |
6 | ||
7 | #include <asm/unaligned.h> | |
8 | #include "trace.h" | |
9 | ||
4c0181bf TW |
10 | static const char *nvme_trace_delete_sq(struct trace_seq *p, u8 *cdw10) |
11 | { | |
12 | const char *ret = trace_seq_buffer_ptr(p); | |
13 | u16 sqid = get_unaligned_le16(cdw10); | |
14 | ||
15 | trace_seq_printf(p, "sqid=%u", sqid); | |
16 | trace_seq_putc(p, 0); | |
17 | ||
18 | return ret; | |
19 | } | |
20 | ||
3d030e41 JT |
21 | static const char *nvme_trace_create_sq(struct trace_seq *p, u8 *cdw10) |
22 | { | |
23 | const char *ret = trace_seq_buffer_ptr(p); | |
24 | u16 sqid = get_unaligned_le16(cdw10); | |
25 | u16 qsize = get_unaligned_le16(cdw10 + 2); | |
26 | u16 sq_flags = get_unaligned_le16(cdw10 + 4); | |
27 | u16 cqid = get_unaligned_le16(cdw10 + 6); | |
28 | ||
29 | ||
30 | trace_seq_printf(p, "sqid=%u, qsize=%u, sq_flags=0x%x, cqid=%u", | |
31 | sqid, qsize, sq_flags, cqid); | |
32 | trace_seq_putc(p, 0); | |
33 | ||
34 | return ret; | |
35 | } | |
36 | ||
4c0181bf TW |
37 | static const char *nvme_trace_delete_cq(struct trace_seq *p, u8 *cdw10) |
38 | { | |
39 | const char *ret = trace_seq_buffer_ptr(p); | |
40 | u16 cqid = get_unaligned_le16(cdw10); | |
41 | ||
42 | trace_seq_printf(p, "cqid=%u", cqid); | |
43 | trace_seq_putc(p, 0); | |
44 | ||
45 | return ret; | |
46 | } | |
47 | ||
3d030e41 JT |
48 | static const char *nvme_trace_create_cq(struct trace_seq *p, u8 *cdw10) |
49 | { | |
50 | const char *ret = trace_seq_buffer_ptr(p); | |
51 | u16 cqid = get_unaligned_le16(cdw10); | |
52 | u16 qsize = get_unaligned_le16(cdw10 + 2); | |
53 | u16 cq_flags = get_unaligned_le16(cdw10 + 4); | |
54 | u16 irq_vector = get_unaligned_le16(cdw10 + 6); | |
55 | ||
56 | trace_seq_printf(p, "cqid=%u, qsize=%u, cq_flags=0x%x, irq_vector=%u", | |
57 | cqid, qsize, cq_flags, irq_vector); | |
58 | trace_seq_putc(p, 0); | |
59 | ||
60 | return ret; | |
61 | } | |
62 | ||
63 | static const char *nvme_trace_admin_identify(struct trace_seq *p, u8 *cdw10) | |
64 | { | |
65 | const char *ret = trace_seq_buffer_ptr(p); | |
66 | u8 cns = cdw10[0]; | |
67 | u16 ctrlid = get_unaligned_le16(cdw10 + 2); | |
68 | ||
69 | trace_seq_printf(p, "cns=%u, ctrlid=%u", cns, ctrlid); | |
70 | trace_seq_putc(p, 0); | |
71 | ||
72 | return ret; | |
73 | } | |
74 | ||
a7b5e8d8 HP |
75 | static const char *nvme_trace_admin_set_features(struct trace_seq *p, |
76 | u8 *cdw10) | |
77 | { | |
78 | const char *ret = trace_seq_buffer_ptr(p); | |
79 | u8 fid = cdw10[0]; | |
80 | u8 sv = cdw10[3] & 0x8; | |
81 | u32 cdw11 = get_unaligned_le32(cdw10 + 4); | |
82 | ||
83 | trace_seq_printf(p, "fid=0x%x, sv=0x%x, cdw11=0x%x", fid, sv, cdw11); | |
84 | trace_seq_putc(p, 0); | |
85 | ||
86 | return ret; | |
87 | } | |
88 | ||
d9d53ed3 MG |
89 | static const char *nvme_trace_admin_get_features(struct trace_seq *p, |
90 | u8 *cdw10) | |
91 | { | |
92 | const char *ret = trace_seq_buffer_ptr(p); | |
93 | u8 fid = cdw10[0]; | |
94 | u8 sel = cdw10[1] & 0x7; | |
95 | u32 cdw11 = get_unaligned_le32(cdw10 + 4); | |
96 | ||
a7b5e8d8 | 97 | trace_seq_printf(p, "fid=0x%x, sel=0x%x, cdw11=0x%x", fid, sel, cdw11); |
d9d53ed3 | 98 | trace_seq_putc(p, 0); |
3d030e41 | 99 | |
d9d53ed3 MG |
100 | return ret; |
101 | } | |
3d030e41 | 102 | |
177b06ed MI |
103 | static const char *nvme_trace_get_lba_status(struct trace_seq *p, |
104 | u8 *cdw10) | |
105 | { | |
106 | const char *ret = trace_seq_buffer_ptr(p); | |
107 | u64 slba = get_unaligned_le64(cdw10); | |
108 | u32 mndw = get_unaligned_le32(cdw10 + 8); | |
109 | u16 rl = get_unaligned_le16(cdw10 + 12); | |
110 | u8 atype = cdw10[15]; | |
111 | ||
112 | trace_seq_printf(p, "slba=0x%llx, mndw=0x%x, rl=0x%x, atype=%u", | |
113 | slba, mndw, rl, atype); | |
114 | trace_seq_putc(p, 0); | |
115 | ||
116 | return ret; | |
117 | } | |
118 | ||
3a98c51a MK |
119 | static const char *nvme_trace_admin_format_nvm(struct trace_seq *p, u8 *cdw10) |
120 | { | |
121 | const char *ret = trace_seq_buffer_ptr(p); | |
798edad9 GL |
122 | /* |
123 | * lbafu(bit 13:12) is already in the upper 4 bits, lbafl: bit 03:00. | |
124 | */ | |
125 | u8 lbaf = (cdw10[1] & 0x30) | (cdw10[0] & 0xF); | |
3a98c51a MK |
126 | u8 mset = (cdw10[0] >> 4) & 0x1; |
127 | u8 pi = (cdw10[0] >> 5) & 0x7; | |
128 | u8 pil = cdw10[1] & 0x1; | |
129 | u8 ses = (cdw10[1] >> 1) & 0x7; | |
130 | ||
131 | trace_seq_printf(p, "lbaf=%u, mset=%u, pi=%u, pil=%u, ses=%u", | |
132 | lbaf, mset, pi, pil, ses); | |
133 | ||
134 | trace_seq_putc(p, 0); | |
135 | ||
136 | return ret; | |
137 | } | |
138 | ||
3d030e41 JT |
139 | static const char *nvme_trace_read_write(struct trace_seq *p, u8 *cdw10) |
140 | { | |
141 | const char *ret = trace_seq_buffer_ptr(p); | |
142 | u64 slba = get_unaligned_le64(cdw10); | |
143 | u16 length = get_unaligned_le16(cdw10 + 8); | |
144 | u16 control = get_unaligned_le16(cdw10 + 10); | |
145 | u32 dsmgmt = get_unaligned_le32(cdw10 + 12); | |
146 | u32 reftag = get_unaligned_le32(cdw10 + 16); | |
147 | ||
148 | trace_seq_printf(p, | |
149 | "slba=%llu, len=%u, ctrl=0x%x, dsmgmt=%u, reftag=%u", | |
150 | slba, length, control, dsmgmt, reftag); | |
151 | trace_seq_putc(p, 0); | |
152 | ||
153 | return ret; | |
154 | } | |
155 | ||
156 | static const char *nvme_trace_dsm(struct trace_seq *p, u8 *cdw10) | |
157 | { | |
158 | const char *ret = trace_seq_buffer_ptr(p); | |
159 | ||
160 | trace_seq_printf(p, "nr=%u, attributes=%u", | |
161 | get_unaligned_le32(cdw10), | |
162 | get_unaligned_le32(cdw10 + 4)); | |
163 | trace_seq_putc(p, 0); | |
164 | ||
165 | return ret; | |
166 | } | |
167 | ||
4a407d5e JT |
168 | static const char *nvme_trace_zone_mgmt_send(struct trace_seq *p, u8 *cdw10) |
169 | { | |
8d539f75 GL |
170 | static const char * const zsa_strs[] = { |
171 | [0x01] = "close zone", | |
172 | [0x02] = "finish zone", | |
173 | [0x03] = "open zone", | |
174 | [0x04] = "reset zone", | |
175 | [0x05] = "offline zone", | |
176 | [0x10] = "set zone descriptor extension" | |
177 | }; | |
4a407d5e JT |
178 | const char *ret = trace_seq_buffer_ptr(p); |
179 | u64 slba = get_unaligned_le64(cdw10); | |
8d539f75 | 180 | const char *zsa_str; |
4a407d5e JT |
181 | u8 zsa = cdw10[12]; |
182 | u8 all = cdw10[13]; | |
183 | ||
8d539f75 GL |
184 | if (zsa < ARRAY_SIZE(zsa_strs) && zsa_strs[zsa]) |
185 | zsa_str = zsa_strs[zsa]; | |
186 | else | |
187 | zsa_str = "reserved"; | |
188 | ||
189 | trace_seq_printf(p, "slba=%llu, zsa=%u:%s, all=%u", | |
190 | slba, zsa, zsa_str, all); | |
4a407d5e JT |
191 | trace_seq_putc(p, 0); |
192 | ||
193 | return ret; | |
194 | } | |
195 | ||
196 | static const char *nvme_trace_zone_mgmt_recv(struct trace_seq *p, u8 *cdw10) | |
197 | { | |
8d539f75 GL |
198 | static const char * const zrasf_strs[] = { |
199 | [0x00] = "list all zones", | |
200 | [0x01] = "list the zones in the ZSE: Empty state", | |
201 | [0x02] = "list the zones in the ZSIO: Implicitly Opened state", | |
202 | [0x03] = "list the zones in the ZSEO: Explicitly Opened state", | |
203 | [0x04] = "list the zones in the ZSC: Closed state", | |
204 | [0x05] = "list the zones in the ZSF: Full state", | |
205 | [0x06] = "list the zones in the ZSRO: Read Only state", | |
206 | [0x07] = "list the zones in the ZSO: Offline state", | |
207 | [0x09] = "list the zones that have the zone attribute" | |
208 | }; | |
4a407d5e JT |
209 | const char *ret = trace_seq_buffer_ptr(p); |
210 | u64 slba = get_unaligned_le64(cdw10); | |
211 | u32 numd = get_unaligned_le32(cdw10 + 8); | |
212 | u8 zra = cdw10[12]; | |
213 | u8 zrasf = cdw10[13]; | |
8d539f75 | 214 | const char *zrasf_str; |
4a407d5e JT |
215 | u8 pr = cdw10[14]; |
216 | ||
8d539f75 GL |
217 | if (zrasf < ARRAY_SIZE(zrasf_strs) && zrasf_strs[zrasf]) |
218 | zrasf_str = zrasf_strs[zrasf]; | |
219 | else | |
220 | zrasf_str = "reserved"; | |
221 | ||
222 | trace_seq_printf(p, "slba=%llu, numd=%u, zra=%u, zrasf=%u:%s, pr=%u", | |
223 | slba, numd, zra, zrasf, zrasf_str, pr); | |
4a407d5e JT |
224 | trace_seq_putc(p, 0); |
225 | ||
226 | return ret; | |
227 | } | |
228 | ||
6a0164f9 GL |
229 | static const char *nvme_trace_resv_reg(struct trace_seq *p, u8 *cdw10) |
230 | { | |
231 | const char *ret = trace_seq_buffer_ptr(p); | |
232 | u8 rrega = cdw10[0] & 0x7; | |
233 | u8 iekey = (cdw10[0] >> 3) & 0x1; | |
234 | u8 ptpl = (cdw10[3] >> 6) & 0x3; | |
235 | ||
236 | trace_seq_printf(p, "rrega=%u, iekey=%u, ptpl=%u", | |
237 | rrega, iekey, ptpl); | |
238 | trace_seq_putc(p, 0); | |
239 | ||
240 | return ret; | |
241 | } | |
242 | ||
243 | static const char *nvme_trace_resv_acq(struct trace_seq *p, u8 *cdw10) | |
244 | { | |
245 | const char *ret = trace_seq_buffer_ptr(p); | |
246 | u8 racqa = cdw10[0] & 0x7; | |
247 | u8 iekey = (cdw10[0] >> 3) & 0x1; | |
248 | u8 rtype = cdw10[1]; | |
249 | ||
250 | trace_seq_printf(p, "racqa=%u, iekey=%u, rtype=%u", | |
251 | racqa, iekey, rtype); | |
252 | trace_seq_putc(p, 0); | |
253 | ||
254 | return ret; | |
255 | } | |
256 | ||
257 | static const char *nvme_trace_resv_rel(struct trace_seq *p, u8 *cdw10) | |
258 | { | |
259 | const char *ret = trace_seq_buffer_ptr(p); | |
260 | u8 rrela = cdw10[0] & 0x7; | |
261 | u8 iekey = (cdw10[0] >> 3) & 0x1; | |
262 | u8 rtype = cdw10[1]; | |
263 | ||
264 | trace_seq_printf(p, "rrela=%u, iekey=%u, rtype=%u", | |
265 | rrela, iekey, rtype); | |
266 | trace_seq_putc(p, 0); | |
267 | ||
268 | return ret; | |
269 | } | |
270 | ||
271 | static const char *nvme_trace_resv_report(struct trace_seq *p, u8 *cdw10) | |
272 | { | |
273 | const char *ret = trace_seq_buffer_ptr(p); | |
274 | u32 numd = get_unaligned_le32(cdw10); | |
275 | u8 eds = cdw10[4] & 0x1; | |
276 | ||
277 | trace_seq_printf(p, "numd=%u, eds=%u", numd, eds); | |
278 | trace_seq_putc(p, 0); | |
279 | ||
280 | return ret; | |
281 | } | |
282 | ||
3d030e41 JT |
283 | static const char *nvme_trace_common(struct trace_seq *p, u8 *cdw10) |
284 | { | |
285 | const char *ret = trace_seq_buffer_ptr(p); | |
286 | ||
287 | trace_seq_printf(p, "cdw10=%*ph", 24, cdw10); | |
288 | trace_seq_putc(p, 0); | |
289 | ||
290 | return ret; | |
291 | } | |
292 | ||
293 | const char *nvme_trace_parse_admin_cmd(struct trace_seq *p, | |
294 | u8 opcode, u8 *cdw10) | |
295 | { | |
296 | switch (opcode) { | |
4c0181bf TW |
297 | case nvme_admin_delete_sq: |
298 | return nvme_trace_delete_sq(p, cdw10); | |
3d030e41 JT |
299 | case nvme_admin_create_sq: |
300 | return nvme_trace_create_sq(p, cdw10); | |
4c0181bf TW |
301 | case nvme_admin_delete_cq: |
302 | return nvme_trace_delete_cq(p, cdw10); | |
3d030e41 JT |
303 | case nvme_admin_create_cq: |
304 | return nvme_trace_create_cq(p, cdw10); | |
305 | case nvme_admin_identify: | |
306 | return nvme_trace_admin_identify(p, cdw10); | |
a7b5e8d8 HP |
307 | case nvme_admin_set_features: |
308 | return nvme_trace_admin_set_features(p, cdw10); | |
d9d53ed3 MG |
309 | case nvme_admin_get_features: |
310 | return nvme_trace_admin_get_features(p, cdw10); | |
177b06ed MI |
311 | case nvme_admin_get_lba_status: |
312 | return nvme_trace_get_lba_status(p, cdw10); | |
3a98c51a MK |
313 | case nvme_admin_format_nvm: |
314 | return nvme_trace_admin_format_nvm(p, cdw10); | |
3d030e41 JT |
315 | default: |
316 | return nvme_trace_common(p, cdw10); | |
317 | } | |
318 | } | |
319 | ||
320 | const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p, | |
321 | u8 opcode, u8 *cdw10) | |
322 | { | |
323 | switch (opcode) { | |
324 | case nvme_cmd_read: | |
325 | case nvme_cmd_write: | |
326 | case nvme_cmd_write_zeroes: | |
4a407d5e | 327 | case nvme_cmd_zone_append: |
3d030e41 JT |
328 | return nvme_trace_read_write(p, cdw10); |
329 | case nvme_cmd_dsm: | |
330 | return nvme_trace_dsm(p, cdw10); | |
4a407d5e JT |
331 | case nvme_cmd_zone_mgmt_send: |
332 | return nvme_trace_zone_mgmt_send(p, cdw10); | |
333 | case nvme_cmd_zone_mgmt_recv: | |
334 | return nvme_trace_zone_mgmt_recv(p, cdw10); | |
6a0164f9 GL |
335 | case nvme_cmd_resv_register: |
336 | return nvme_trace_resv_reg(p, cdw10); | |
337 | case nvme_cmd_resv_acquire: | |
338 | return nvme_trace_resv_acq(p, cdw10); | |
339 | case nvme_cmd_resv_release: | |
340 | return nvme_trace_resv_rel(p, cdw10); | |
341 | case nvme_cmd_resv_report: | |
342 | return nvme_trace_resv_report(p, cdw10); | |
3d030e41 JT |
343 | default: |
344 | return nvme_trace_common(p, cdw10); | |
345 | } | |
346 | } | |
6268953e | 347 | |
ad795e47 MI |
348 | static const char *nvme_trace_fabrics_property_set(struct trace_seq *p, u8 *spc) |
349 | { | |
350 | const char *ret = trace_seq_buffer_ptr(p); | |
351 | u8 attrib = spc[0]; | |
352 | u32 ofst = get_unaligned_le32(spc + 4); | |
353 | u64 value = get_unaligned_le64(spc + 8); | |
354 | ||
355 | trace_seq_printf(p, "attrib=%u, ofst=0x%x, value=0x%llx", | |
356 | attrib, ofst, value); | |
357 | trace_seq_putc(p, 0); | |
358 | return ret; | |
359 | } | |
360 | ||
361 | static const char *nvme_trace_fabrics_connect(struct trace_seq *p, u8 *spc) | |
362 | { | |
363 | const char *ret = trace_seq_buffer_ptr(p); | |
364 | u16 recfmt = get_unaligned_le16(spc); | |
365 | u16 qid = get_unaligned_le16(spc + 2); | |
366 | u16 sqsize = get_unaligned_le16(spc + 4); | |
367 | u8 cattr = spc[6]; | |
368 | u32 kato = get_unaligned_le32(spc + 8); | |
369 | ||
370 | trace_seq_printf(p, "recfmt=%u, qid=%u, sqsize=%u, cattr=%u, kato=%u", | |
371 | recfmt, qid, sqsize, cattr, kato); | |
372 | trace_seq_putc(p, 0); | |
373 | return ret; | |
374 | } | |
375 | ||
376 | static const char *nvme_trace_fabrics_property_get(struct trace_seq *p, u8 *spc) | |
377 | { | |
378 | const char *ret = trace_seq_buffer_ptr(p); | |
379 | u8 attrib = spc[0]; | |
380 | u32 ofst = get_unaligned_le32(spc + 4); | |
381 | ||
382 | trace_seq_printf(p, "attrib=%u, ofst=0x%x", attrib, ofst); | |
383 | trace_seq_putc(p, 0); | |
384 | return ret; | |
385 | } | |
386 | ||
f50fff73 HR |
387 | static const char *nvme_trace_fabrics_auth_send(struct trace_seq *p, u8 *spc) |
388 | { | |
389 | const char *ret = trace_seq_buffer_ptr(p); | |
390 | u8 spsp0 = spc[1]; | |
391 | u8 spsp1 = spc[2]; | |
392 | u8 secp = spc[3]; | |
393 | u32 tl = get_unaligned_le32(spc + 4); | |
394 | ||
395 | trace_seq_printf(p, "spsp0=%02x, spsp1=%02x, secp=%02x, tl=%u", | |
396 | spsp0, spsp1, secp, tl); | |
397 | trace_seq_putc(p, 0); | |
398 | return ret; | |
399 | } | |
400 | ||
401 | static const char *nvme_trace_fabrics_auth_receive(struct trace_seq *p, u8 *spc) | |
402 | { | |
403 | const char *ret = trace_seq_buffer_ptr(p); | |
404 | u8 spsp0 = spc[1]; | |
405 | u8 spsp1 = spc[2]; | |
406 | u8 secp = spc[3]; | |
407 | u32 al = get_unaligned_le32(spc + 4); | |
408 | ||
409 | trace_seq_printf(p, "spsp0=%02x, spsp1=%02x, secp=%02x, al=%u", | |
410 | spsp0, spsp1, secp, al); | |
411 | trace_seq_putc(p, 0); | |
412 | return ret; | |
413 | } | |
414 | ||
ad795e47 MI |
415 | static const char *nvme_trace_fabrics_common(struct trace_seq *p, u8 *spc) |
416 | { | |
417 | const char *ret = trace_seq_buffer_ptr(p); | |
418 | ||
91f6d798 | 419 | trace_seq_printf(p, "specific=%*ph", 24, spc); |
ad795e47 MI |
420 | trace_seq_putc(p, 0); |
421 | return ret; | |
422 | } | |
423 | ||
424 | const char *nvme_trace_parse_fabrics_cmd(struct trace_seq *p, | |
425 | u8 fctype, u8 *spc) | |
426 | { | |
427 | switch (fctype) { | |
428 | case nvme_fabrics_type_property_set: | |
429 | return nvme_trace_fabrics_property_set(p, spc); | |
430 | case nvme_fabrics_type_connect: | |
431 | return nvme_trace_fabrics_connect(p, spc); | |
432 | case nvme_fabrics_type_property_get: | |
433 | return nvme_trace_fabrics_property_get(p, spc); | |
f50fff73 HR |
434 | case nvme_fabrics_type_auth_send: |
435 | return nvme_trace_fabrics_auth_send(p, spc); | |
436 | case nvme_fabrics_type_auth_receive: | |
437 | return nvme_trace_fabrics_auth_receive(p, spc); | |
ad795e47 MI |
438 | default: |
439 | return nvme_trace_fabrics_common(p, spc); | |
440 | } | |
441 | } | |
442 | ||
6268953e KB |
443 | const char *nvme_trace_disk_name(struct trace_seq *p, char *name) |
444 | { | |
445 | const char *ret = trace_seq_buffer_ptr(p); | |
446 | ||
447 | if (*name) | |
448 | trace_seq_printf(p, "disk=%s, ", name); | |
449 | trace_seq_putc(p, 0); | |
450 | ||
451 | return ret; | |
452 | } | |
604c01d5 | 453 | |
454 | EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_sq); |