Linux 4.19.133
[linux/fpc-iii.git] / drivers / scsi / scsi_trace.c
blob22472d140ef7c6bce8955edbc37d1c9270eee10a
1 /*
2 * Copyright (C) 2010 FUJITSU LIMITED
3 * Copyright (C) 2010 Tomohiro Kusumi <kusumi.tomohiro@jp.fujitsu.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 #include <linux/kernel.h>
19 #include <linux/trace_seq.h>
20 #include <asm/unaligned.h>
21 #include <trace/events/scsi.h>
23 #define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f)
24 #define SERVICE_ACTION32(cdb) (get_unaligned_be16(&cdb[8]))
26 static const char *
27 scsi_trace_misc(struct trace_seq *, unsigned char *, int);
29 static const char *
30 scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
32 const char *ret = trace_seq_buffer_ptr(p);
33 u32 lba = 0, txlen;
35 lba |= ((cdb[1] & 0x1F) << 16);
36 lba |= (cdb[2] << 8);
37 lba |= cdb[3];
39 * From SBC-2: a TRANSFER LENGTH field set to zero specifies that 256
40 * logical blocks shall be read (READ(6)) or written (WRITE(6)).
42 txlen = cdb[4] ? cdb[4] : 256;
44 trace_seq_printf(p, "lba=%u txlen=%u", lba, txlen);
45 trace_seq_putc(p, 0);
47 return ret;
50 static const char *
51 scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
53 const char *ret = trace_seq_buffer_ptr(p);
54 u32 lba, txlen;
56 lba = get_unaligned_be32(&cdb[2]);
57 txlen = get_unaligned_be16(&cdb[7]);
59 trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen,
60 cdb[1] >> 5);
62 if (cdb[0] == WRITE_SAME)
63 trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
65 trace_seq_putc(p, 0);
67 return ret;
70 static const char *
71 scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
73 const char *ret = trace_seq_buffer_ptr(p);
74 u32 lba, txlen;
76 lba = get_unaligned_be32(&cdb[2]);
77 txlen = get_unaligned_be32(&cdb[6]);
79 trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen,
80 cdb[1] >> 5);
81 trace_seq_putc(p, 0);
83 return ret;
86 static const char *
87 scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
89 const char *ret = trace_seq_buffer_ptr(p);
90 u64 lba;
91 u32 txlen;
93 lba = get_unaligned_be64(&cdb[2]);
94 txlen = get_unaligned_be32(&cdb[10]);
96 trace_seq_printf(p, "lba=%llu txlen=%u protect=%u", lba, txlen,
97 cdb[1] >> 5);
99 if (cdb[0] == WRITE_SAME_16)
100 trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
102 trace_seq_putc(p, 0);
104 return ret;
107 static const char *
108 scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len)
110 const char *ret = trace_seq_buffer_ptr(p), *cmd;
111 u64 lba;
112 u32 ei_lbrt, txlen;
114 switch (SERVICE_ACTION32(cdb)) {
115 case READ_32:
116 cmd = "READ";
117 break;
118 case VERIFY_32:
119 cmd = "VERIFY";
120 break;
121 case WRITE_32:
122 cmd = "WRITE";
123 break;
124 case WRITE_SAME_32:
125 cmd = "WRITE_SAME";
126 break;
127 default:
128 trace_seq_puts(p, "UNKNOWN");
129 goto out;
132 lba = get_unaligned_be64(&cdb[12]);
133 ei_lbrt = get_unaligned_be32(&cdb[20]);
134 txlen = get_unaligned_be32(&cdb[28]);
136 trace_seq_printf(p, "%s_32 lba=%llu txlen=%u protect=%u ei_lbrt=%u",
137 cmd, lba, txlen, cdb[10] >> 5, ei_lbrt);
139 if (SERVICE_ACTION32(cdb) == WRITE_SAME_32)
140 trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1);
142 out:
143 trace_seq_putc(p, 0);
145 return ret;
148 static const char *
149 scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
151 const char *ret = trace_seq_buffer_ptr(p);
152 unsigned int regions = get_unaligned_be16(&cdb[7]);
154 trace_seq_printf(p, "regions=%u", (regions - 8) / 16);
155 trace_seq_putc(p, 0);
157 return ret;
160 static const char *
161 scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len)
163 const char *ret = trace_seq_buffer_ptr(p), *cmd;
164 u64 lba;
165 u32 alloc_len;
167 switch (SERVICE_ACTION16(cdb)) {
168 case SAI_READ_CAPACITY_16:
169 cmd = "READ_CAPACITY_16";
170 break;
171 case SAI_GET_LBA_STATUS:
172 cmd = "GET_LBA_STATUS";
173 break;
174 default:
175 trace_seq_puts(p, "UNKNOWN");
176 goto out;
179 lba = get_unaligned_be64(&cdb[2]);
180 alloc_len = get_unaligned_be32(&cdb[10]);
182 trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, lba, alloc_len);
184 out:
185 trace_seq_putc(p, 0);
187 return ret;
190 static const char *
191 scsi_trace_maintenance_in(struct trace_seq *p, unsigned char *cdb, int len)
193 const char *ret = trace_seq_buffer_ptr(p), *cmd;
194 u32 alloc_len;
196 switch (SERVICE_ACTION16(cdb)) {
197 case MI_REPORT_IDENTIFYING_INFORMATION:
198 cmd = "REPORT_IDENTIFYING_INFORMATION";
199 break;
200 case MI_REPORT_TARGET_PGS:
201 cmd = "REPORT_TARGET_PORT_GROUPS";
202 break;
203 case MI_REPORT_ALIASES:
204 cmd = "REPORT_ALIASES";
205 break;
206 case MI_REPORT_SUPPORTED_OPERATION_CODES:
207 cmd = "REPORT_SUPPORTED_OPERATION_CODES";
208 break;
209 case MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS:
210 cmd = "REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS";
211 break;
212 case MI_REPORT_PRIORITY:
213 cmd = "REPORT_PRIORITY";
214 break;
215 case MI_REPORT_TIMESTAMP:
216 cmd = "REPORT_TIMESTAMP";
217 break;
218 case MI_MANAGEMENT_PROTOCOL_IN:
219 cmd = "MANAGEMENT_PROTOCOL_IN";
220 break;
221 default:
222 trace_seq_puts(p, "UNKNOWN");
223 goto out;
226 alloc_len = get_unaligned_be32(&cdb[6]);
228 trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len);
230 out:
231 trace_seq_putc(p, 0);
233 return ret;
236 static const char *
237 scsi_trace_maintenance_out(struct trace_seq *p, unsigned char *cdb, int len)
239 const char *ret = trace_seq_buffer_ptr(p), *cmd;
240 u32 alloc_len;
242 switch (SERVICE_ACTION16(cdb)) {
243 case MO_SET_IDENTIFYING_INFORMATION:
244 cmd = "SET_IDENTIFYING_INFORMATION";
245 break;
246 case MO_SET_TARGET_PGS:
247 cmd = "SET_TARGET_PORT_GROUPS";
248 break;
249 case MO_CHANGE_ALIASES:
250 cmd = "CHANGE_ALIASES";
251 break;
252 case MO_SET_PRIORITY:
253 cmd = "SET_PRIORITY";
254 break;
255 case MO_SET_TIMESTAMP:
256 cmd = "SET_TIMESTAMP";
257 break;
258 case MO_MANAGEMENT_PROTOCOL_OUT:
259 cmd = "MANAGEMENT_PROTOCOL_OUT";
260 break;
261 default:
262 trace_seq_puts(p, "UNKNOWN");
263 goto out;
266 alloc_len = get_unaligned_be32(&cdb[6]);
268 trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len);
270 out:
271 trace_seq_putc(p, 0);
273 return ret;
276 static const char *
277 scsi_trace_zbc_in(struct trace_seq *p, unsigned char *cdb, int len)
279 const char *ret = trace_seq_buffer_ptr(p), *cmd;
280 u64 zone_id;
281 u32 alloc_len;
282 u8 options;
284 switch (SERVICE_ACTION16(cdb)) {
285 case ZI_REPORT_ZONES:
286 cmd = "REPORT_ZONES";
287 break;
288 default:
289 trace_seq_puts(p, "UNKNOWN");
290 goto out;
293 zone_id = get_unaligned_be64(&cdb[2]);
294 alloc_len = get_unaligned_be32(&cdb[10]);
295 options = cdb[14] & 0x3f;
297 trace_seq_printf(p, "%s zone=%llu alloc_len=%u options=%u partial=%u",
298 cmd, (unsigned long long)zone_id, alloc_len,
299 options, (cdb[14] >> 7) & 1);
301 out:
302 trace_seq_putc(p, 0);
304 return ret;
307 static const char *
308 scsi_trace_zbc_out(struct trace_seq *p, unsigned char *cdb, int len)
310 const char *ret = trace_seq_buffer_ptr(p), *cmd;
311 u64 zone_id;
313 switch (SERVICE_ACTION16(cdb)) {
314 case ZO_CLOSE_ZONE:
315 cmd = "CLOSE_ZONE";
316 break;
317 case ZO_FINISH_ZONE:
318 cmd = "FINISH_ZONE";
319 break;
320 case ZO_OPEN_ZONE:
321 cmd = "OPEN_ZONE";
322 break;
323 case ZO_RESET_WRITE_POINTER:
324 cmd = "RESET_WRITE_POINTER";
325 break;
326 default:
327 trace_seq_puts(p, "UNKNOWN");
328 goto out;
331 zone_id = get_unaligned_be64(&cdb[2]);
333 trace_seq_printf(p, "%s zone=%llu all=%u", cmd,
334 (unsigned long long)zone_id, cdb[14] & 1);
336 out:
337 trace_seq_putc(p, 0);
339 return ret;
342 static const char *
343 scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len)
345 switch (SERVICE_ACTION32(cdb)) {
346 case READ_32:
347 case VERIFY_32:
348 case WRITE_32:
349 case WRITE_SAME_32:
350 return scsi_trace_rw32(p, cdb, len);
351 default:
352 return scsi_trace_misc(p, cdb, len);
356 static const char *
357 scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len)
359 const char *ret = trace_seq_buffer_ptr(p);
361 trace_seq_putc(p, '-');
362 trace_seq_putc(p, 0);
364 return ret;
367 const char *
368 scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len)
370 switch (cdb[0]) {
371 case READ_6:
372 case WRITE_6:
373 return scsi_trace_rw6(p, cdb, len);
374 case READ_10:
375 case VERIFY:
376 case WRITE_10:
377 case WRITE_SAME:
378 return scsi_trace_rw10(p, cdb, len);
379 case READ_12:
380 case VERIFY_12:
381 case WRITE_12:
382 return scsi_trace_rw12(p, cdb, len);
383 case READ_16:
384 case VERIFY_16:
385 case WRITE_16:
386 case WRITE_SAME_16:
387 return scsi_trace_rw16(p, cdb, len);
388 case UNMAP:
389 return scsi_trace_unmap(p, cdb, len);
390 case SERVICE_ACTION_IN_16:
391 return scsi_trace_service_action_in(p, cdb, len);
392 case VARIABLE_LENGTH_CMD:
393 return scsi_trace_varlen(p, cdb, len);
394 case MAINTENANCE_IN:
395 return scsi_trace_maintenance_in(p, cdb, len);
396 case MAINTENANCE_OUT:
397 return scsi_trace_maintenance_out(p, cdb, len);
398 case ZBC_IN:
399 return scsi_trace_zbc_in(p, cdb, len);
400 case ZBC_OUT:
401 return scsi_trace_zbc_out(p, cdb, len);
402 default:
403 return scsi_trace_misc(p, cdb, len);