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_get_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 sel = cdw10[1] & 0x7; 81 u32 cdw11 = get_unaligned_le32(cdw10 + 4); 82 83 trace_seq_printf(p, "fid=0x%x sel=0x%x cdw11=0x%x", fid, sel, cdw11); 84 trace_seq_putc(p, 0); 85 86 return ret; 87 } 88 89 static const char *nvme_trace_read_write(struct trace_seq *p, u8 *cdw10) 90 { 91 const char *ret = trace_seq_buffer_ptr(p); 92 u64 slba = get_unaligned_le64(cdw10); 93 u16 length = get_unaligned_le16(cdw10 + 8); 94 u16 control = get_unaligned_le16(cdw10 + 10); 95 u32 dsmgmt = get_unaligned_le32(cdw10 + 12); 96 u32 reftag = get_unaligned_le32(cdw10 + 16); 97 98 trace_seq_printf(p, 99 "slba=%llu, len=%u, ctrl=0x%x, dsmgmt=%u, reftag=%u", 100 slba, length, control, dsmgmt, reftag); 101 trace_seq_putc(p, 0); 102 103 return ret; 104 } 105 106 static const char *nvme_trace_dsm(struct trace_seq *p, u8 *cdw10) 107 { 108 const char *ret = trace_seq_buffer_ptr(p); 109 110 trace_seq_printf(p, "nr=%u, attributes=%u", 111 get_unaligned_le32(cdw10), 112 get_unaligned_le32(cdw10 + 4)); 113 trace_seq_putc(p, 0); 114 115 return ret; 116 } 117 118 static const char *nvme_trace_common(struct trace_seq *p, u8 *cdw10) 119 { 120 const char *ret = trace_seq_buffer_ptr(p); 121 122 trace_seq_printf(p, "cdw10=%*ph", 24, cdw10); 123 trace_seq_putc(p, 0); 124 125 return ret; 126 } 127 128 const char *nvme_trace_parse_admin_cmd(struct trace_seq *p, 129 u8 opcode, u8 *cdw10) 130 { 131 switch (opcode) { 132 case nvme_admin_delete_sq: 133 return nvme_trace_delete_sq(p, cdw10); 134 case nvme_admin_create_sq: 135 return nvme_trace_create_sq(p, cdw10); 136 case nvme_admin_delete_cq: 137 return nvme_trace_delete_cq(p, cdw10); 138 case nvme_admin_create_cq: 139 return nvme_trace_create_cq(p, cdw10); 140 case nvme_admin_identify: 141 return nvme_trace_admin_identify(p, cdw10); 142 case nvme_admin_get_features: 143 return nvme_trace_admin_get_features(p, cdw10); 144 default: 145 return nvme_trace_common(p, cdw10); 146 } 147 } 148 149 const char *nvme_trace_parse_nvm_cmd(struct trace_seq *p, 150 u8 opcode, u8 *cdw10) 151 { 152 switch (opcode) { 153 case nvme_cmd_read: 154 case nvme_cmd_write: 155 case nvme_cmd_write_zeroes: 156 return nvme_trace_read_write(p, cdw10); 157 case nvme_cmd_dsm: 158 return nvme_trace_dsm(p, cdw10); 159 default: 160 return nvme_trace_common(p, cdw10); 161 } 162 } 163 164 static const char *nvme_trace_fabrics_property_set(struct trace_seq *p, u8 *spc) 165 { 166 const char *ret = trace_seq_buffer_ptr(p); 167 u8 attrib = spc[0]; 168 u32 ofst = get_unaligned_le32(spc + 4); 169 u64 value = get_unaligned_le64(spc + 8); 170 171 trace_seq_printf(p, "attrib=%u, ofst=0x%x, value=0x%llx", 172 attrib, ofst, value); 173 trace_seq_putc(p, 0); 174 return ret; 175 } 176 177 static const char *nvme_trace_fabrics_connect(struct trace_seq *p, u8 *spc) 178 { 179 const char *ret = trace_seq_buffer_ptr(p); 180 u16 recfmt = get_unaligned_le16(spc); 181 u16 qid = get_unaligned_le16(spc + 2); 182 u16 sqsize = get_unaligned_le16(spc + 4); 183 u8 cattr = spc[6]; 184 u32 kato = get_unaligned_le32(spc + 8); 185 186 trace_seq_printf(p, "recfmt=%u, qid=%u, sqsize=%u, cattr=%u, kato=%u", 187 recfmt, qid, sqsize, cattr, kato); 188 trace_seq_putc(p, 0); 189 return ret; 190 } 191 192 static const char *nvme_trace_fabrics_property_get(struct trace_seq *p, u8 *spc) 193 { 194 const char *ret = trace_seq_buffer_ptr(p); 195 u8 attrib = spc[0]; 196 u32 ofst = get_unaligned_le32(spc + 4); 197 198 trace_seq_printf(p, "attrib=%u, ofst=0x%x", attrib, ofst); 199 trace_seq_putc(p, 0); 200 return ret; 201 } 202 203 static const char *nvme_trace_fabrics_common(struct trace_seq *p, u8 *spc) 204 { 205 const char *ret = trace_seq_buffer_ptr(p); 206 207 trace_seq_printf(p, "specific=%*ph", 24, spc); 208 trace_seq_putc(p, 0); 209 return ret; 210 } 211 212 const char *nvme_trace_parse_fabrics_cmd(struct trace_seq *p, 213 u8 fctype, u8 *spc) 214 { 215 switch (fctype) { 216 case nvme_fabrics_type_property_set: 217 return nvme_trace_fabrics_property_set(p, spc); 218 case nvme_fabrics_type_connect: 219 return nvme_trace_fabrics_connect(p, spc); 220 case nvme_fabrics_type_property_get: 221 return nvme_trace_fabrics_property_get(p, spc); 222 default: 223 return nvme_trace_fabrics_common(p, spc); 224 } 225 } 226 227 const char *nvme_trace_disk_name(struct trace_seq *p, char *name) 228 { 229 const char *ret = trace_seq_buffer_ptr(p); 230 231 if (*name) 232 trace_seq_printf(p, "disk=%s, ", name); 233 trace_seq_putc(p, 0); 234 235 return ret; 236 } 237 238 EXPORT_TRACEPOINT_SYMBOL_GPL(nvme_sq); 239