1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * NVM Express device driver tracepoints 4 * Copyright (c) 2018 Johannes Thumshirn, SUSE Linux GmbH 5 */ 6 7 #include <asm/unaligned.h> 8 #include "trace.h" 9 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 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 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 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 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 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 97 trace_seq_printf(p, "fid=0x%x, sel=0x%x, cdw11=0x%x", fid, sel, cdw11); 98 trace_seq_putc(p, 0); 99 100 return ret; 101 } 102 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 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); 122 u8 lbaf = cdw10[0] & 0xF; 123 u8 mset = (cdw10[0] >> 4) & 0x1; 124 u8 pi = (cdw10[0] >> 5) & 0x7; 125 u8 pil = cdw10[1] & 0x1; 126 u8 ses = (cdw10[1] >> 1) & 0x7; 127 128 trace_seq_printf(p, "lbaf=%u, mset=%u, pi=%u, pil=%u, ses=%u", 129 lbaf, mset, pi, pil, ses); 130 131 trace_seq_putc(p, 0); 132 133 return ret; 134 } 135 136 static const char *nvme_trace_read_write(struct trace_seq *p, u8 *cdw10) 137 { 138 const char *ret = trace_seq_buffer_ptr(p); 139 u64 slba = get_unaligned_le64(cdw10); 140 u16 length = get_unaligned_le16(cdw10 + 8); 141 u16 control = get_unaligned_le16(cdw10 + 10); 142 u32 dsmgmt = get_unaligned_le32(cdw10 + 12); 143 u32 reftag = get_unaligned_le32(cdw10 + 16); 144 145 trace_seq_printf(p, 146 "slba=%llu, len=%u, ctrl=0x%x, dsmgmt=%u, reftag=%u", 147 slba, length, control, dsmgmt, reftag); 148 trace_seq_putc(p, 0); 149 150 return ret; 151 } 152 153 static const char *nvme_trace_dsm(struct trace_seq *p, u8 *cdw10) 154 { 155 const char *ret = trace_seq_buffer_ptr(p); 156 157 trace_seq_printf(p, "nr=%u, attributes=%u", 158 get_unaligned_le32(cdw10), 159 get_unaligned_le32(cdw10 + 4)); 160 trace_seq_putc(p, 0); 161 162 return ret; 163 } 164 165 static const char *nvme_trace_zone_mgmt_send(struct trace_seq *p, u8 *cdw10) 166 { 167 const char *ret = trace_seq_buffer_ptr(p); 168 u64 slba = get_unaligned_le64(cdw10); 169 u8 zsa = cdw10[12]; 170 u8 all = cdw10[13]; 171 172 trace_seq_printf(p, "slba=%llu, zsa=%u, all=%u", slba, zsa, all); 173 trace_seq_putc(p, 0); 174 175 return ret; 176 } 177 178 static const char *nvme_trace_zone_mgmt_recv(struct trace_seq *p, u8 *cdw10) 179 { 180 const char *ret = trace_seq_buffer_ptr(p); 181 u64 slba = get_unaligned_le64(cdw10); 182 u32 numd = get_unaligned_le32(cdw10 + 8); 183 u8 zra = cdw10[12]; 184 u8 zrasf = cdw10[13]; 185 u8 pr = cdw10[14]; 186 187 trace_seq_printf(p, "slba=%llu, numd=%u, zra=%u, zrasf=%u, pr=%u", 188 slba, numd, zra, zrasf, pr); 189 trace_seq_putc(p, 0); 190 191 return ret; 192 } 193 194 static const char *nvme_trace_common(struct trace_seq *p, u8 *cdw10) 195 { 196 const char *ret = trace_seq_buffer_ptr(p); 197 198 trace_seq_printf(p, "cdw10=%*ph", 24, cdw10); 199 trace_seq_putc(p, 0); 200 201 return ret; 202 } 203 204 const char *nvme_trace_parse_admin_cmd(struct trace_seq *p, 205 u8 opcode, u8 *cdw10) 206 { 207 switch (opcode) { 208 case nvme_admin_delete_sq: 209 return nvme_trace_delete_sq(p, cdw10); 210 case nvme_admin_create_sq: 211 return nvme_trace_create_sq(p, cdw10); 212 case nvme_admin_delete_cq: 213 return nvme_trace_delete_cq(p, cdw10); 214 case nvme_admin_create_cq: 215 return nvme_trace_create_cq(p, cdw10); 216 case nvme_admin_identify: 217 return nvme_trace_admin_identify(p, cdw10); 218 case nvme_admin_set_features: 219 return nvme_trace_admin_set_features(p, cdw10); 220 case nvme_admin_get_features: 221 return nvme_trace_admin_get_features(p, cdw10); 222 case nvme_admin_get_lba_status: 223 return nvme_trace_get_lba_status(p, cdw10); 224 case nvme_admin_format_nvm: 225 return nvme_trace_admin_format_nvm(p, cdw10); 226 default: 227 return nvme_trace_common(p, cdw10); 228 } 229 } 230 231 const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p, 232 u8 opcode, u8 *cdw10) 233 { 234 switch (opcode) { 235 case nvme_cmd_read: 236 case nvme_cmd_write: 237 case nvme_cmd_write_zeroes: 238 case nvme_cmd_zone_append: 239 return nvme_trace_read_write(p, cdw10); 240 case nvme_cmd_dsm: 241 return nvme_trace_dsm(p, cdw10); 242 case nvme_cmd_zone_mgmt_send: 243 return nvme_trace_zone_mgmt_send(p, cdw10); 244 case nvme_cmd_zone_mgmt_recv: 245 return nvme_trace_zone_mgmt_recv(p, cdw10); 246 default: 247 return nvme_trace_common(p, cdw10); 248 } 249 } 250 251 static const char *nvme_trace_fabrics_property_set(struct trace_seq *p, u8 *spc) 252 { 253 const char *ret = trace_seq_buffer_ptr(p); 254 u8 attrib = spc[0]; 255 u32 ofst = get_unaligned_le32(spc + 4); 256 u64 value = get_unaligned_le64(spc + 8); 257 258 trace_seq_printf(p, "attrib=%u, ofst=0x%x, value=0x%llx", 259 attrib, ofst, value); 260 trace_seq_putc(p, 0); 261 return ret; 262 } 263 264 static const char *nvme_trace_fabrics_connect(struct trace_seq *p, u8 *spc) 265 { 266 const char *ret = trace_seq_buffer_ptr(p); 267 u16 recfmt = get_unaligned_le16(spc); 268 u16 qid = get_unaligned_le16(spc + 2); 269 u16 sqsize = get_unaligned_le16(spc + 4); 270 u8 cattr = spc[6]; 271 u32 kato = get_unaligned_le32(spc + 8); 272 273 trace_seq_printf(p, "recfmt=%u, qid=%u, sqsize=%u, cattr=%u, kato=%u", 274 recfmt, qid, sqsize, cattr, kato); 275 trace_seq_putc(p, 0); 276 return ret; 277 } 278 279 static const char *nvme_trace_fabrics_property_get(struct trace_seq *p, u8 *spc) 280 { 281 const char *ret = trace_seq_buffer_ptr(p); 282 u8 attrib = spc[0]; 283 u32 ofst = get_unaligned_le32(spc + 4); 284 285 trace_seq_printf(p, "attrib=%u, ofst=0x%x", attrib, ofst); 286 trace_seq_putc(p, 0); 287 return ret; 288 } 289 290 static const char *nvme_trace_fabrics_common(struct trace_seq *p, u8 *spc) 291 { 292 const char *ret = trace_seq_buffer_ptr(p); 293 294 trace_seq_printf(p, "specific=%*ph", 24, spc); 295 trace_seq_putc(p, 0); 296 return ret; 297 } 298 299 const char *nvme_trace_parse_fabrics_cmd(struct trace_seq *p, 300 u8 fctype, u8 *spc) 301 { 302 switch (fctype) { 303 case nvme_fabrics_type_property_set: 304 return nvme_trace_fabrics_property_set(p, spc); 305 case nvme_fabrics_type_connect: 306 return nvme_trace_fabrics_connect(p, spc); 307 case nvme_fabrics_type_property_get: 308 return nvme_trace_fabrics_property_get(p, spc); 309 default: 310 return nvme_trace_fabrics_common(p, spc); 311 } 312 } 313 314 const char *nvme_trace_disk_name(struct trace_seq *p, char *name) 315 { 316 const char *ret = trace_seq_buffer_ptr(p); 317 318 if (*name) 319 trace_seq_printf(p, "disk=%s, ", name); 320 trace_seq_putc(p, 0); 321 322 return ret; 323 } 324 325 EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_sq); 326