]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/scsi/scsi_trace.c
UBUNTU: Ubuntu-4.15.0-96.97
[mirror_ubuntu-bionic-kernel.git] / drivers / scsi / scsi_trace.c
CommitLineData
bf816235
KT
1/*
2 * Copyright (C) 2010 FUJITSU LIMITED
3 * Copyright (C) 2010 Tomohiro Kusumi <kusumi.tomohiro@jp.fujitsu.com>
4 *
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.
8 *
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.
13 *
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
17 */
18#include <linux/kernel.h>
19#include <linux/trace_seq.h>
5141f16a 20#include <asm/unaligned.h>
bf816235
KT
21#include <trace/events/scsi.h>
22
c446c1f9 23#define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f)
eeaf76c8 24#define SERVICE_ACTION32(cdb) (get_unaligned_be16(&cdb[8]))
bf816235
KT
25
26static const char *
27scsi_trace_misc(struct trace_seq *, unsigned char *, int);
28
29static const char *
30scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
31{
7b039cb4 32 const char *ret = trace_seq_buffer_ptr(p);
016ea8d7 33 u32 lba = 0, txlen;
bf816235
KT
34
35 lba |= ((cdb[1] & 0x1F) << 16);
36 lba |= (cdb[2] << 8);
37 lba |= cdb[3];
016ea8d7
BVA
38 /*
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)).
41 */
42 txlen = cdb[4] ? cdb[4] : 256;
bf816235 43
016ea8d7 44 trace_seq_printf(p, "lba=%u txlen=%u", lba, txlen);
bf816235
KT
45 trace_seq_putc(p, 0);
46
47 return ret;
48}
49
50static const char *
51scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
52{
7b039cb4 53 const char *ret = trace_seq_buffer_ptr(p);
eeaf76c8 54 u32 lba, txlen;
bf816235 55
eeaf76c8
BVA
56 lba = get_unaligned_be32(&cdb[2]);
57 txlen = get_unaligned_be16(&cdb[7]);
bf816235 58
eeaf76c8 59 trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen,
c446c1f9 60 cdb[1] >> 5);
c498bf1a
MP
61
62 if (cdb[0] == WRITE_SAME)
63 trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
64
bf816235
KT
65 trace_seq_putc(p, 0);
66
67 return ret;
68}
69
70static const char *
71scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
72{
7b039cb4 73 const char *ret = trace_seq_buffer_ptr(p);
eeaf76c8
BVA
74 u32 lba, txlen;
75
76 lba = get_unaligned_be32(&cdb[2]);
77 txlen = get_unaligned_be32(&cdb[6]);
78
79 trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen,
c446c1f9 80 cdb[1] >> 5);
bf816235
KT
81 trace_seq_putc(p, 0);
82
83 return ret;
84}
85
86static const char *
87scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
88{
7b039cb4 89 const char *ret = trace_seq_buffer_ptr(p);
eeaf76c8
BVA
90 u64 lba;
91 u32 txlen;
92
93 lba = get_unaligned_be64(&cdb[2]);
94 txlen = get_unaligned_be32(&cdb[10]);
95
96 trace_seq_printf(p, "lba=%llu txlen=%u protect=%u", lba, txlen,
c446c1f9
MP
97 cdb[1] >> 5);
98
99 if (cdb[0] == WRITE_SAME_16)
100 trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
101
bf816235
KT
102 trace_seq_putc(p, 0);
103
104 return ret;
105}
106
107static const char *
108scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len)
109{
7b039cb4 110 const char *ret = trace_seq_buffer_ptr(p), *cmd;
eeaf76c8
BVA
111 u64 lba;
112 u32 ei_lbrt, txlen;
c446c1f9
MP
113
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:
91c40f24 128 trace_seq_puts(p, "UNKNOWN");
c446c1f9
MP
129 goto out;
130 }
bf816235 131
eeaf76c8
BVA
132 lba = get_unaligned_be64(&cdb[12]);
133 ei_lbrt = get_unaligned_be32(&cdb[20]);
134 txlen = get_unaligned_be32(&cdb[28]);
135
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);
c446c1f9
MP
138
139 if (SERVICE_ACTION32(cdb) == WRITE_SAME_32)
140 trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1);
141
142out:
143 trace_seq_putc(p, 0);
144
145 return ret;
146}
147
148static const char *
149scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
150{
7b039cb4 151 const char *ret = trace_seq_buffer_ptr(p);
eeaf76c8 152 unsigned int regions = get_unaligned_be16(&cdb[7]);
c446c1f9
MP
153
154 trace_seq_printf(p, "regions=%u", (regions - 8) / 16);
155 trace_seq_putc(p, 0);
156
157 return ret;
158}
159
160static const char *
161scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len)
162{
7b039cb4 163 const char *ret = trace_seq_buffer_ptr(p), *cmd;
eeaf76c8
BVA
164 u64 lba;
165 u32 alloc_len;
c446c1f9
MP
166
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:
91c40f24 175 trace_seq_puts(p, "UNKNOWN");
c446c1f9
MP
176 goto out;
177 }
178
eeaf76c8
BVA
179 lba = get_unaligned_be64(&cdb[2]);
180 alloc_len = get_unaligned_be32(&cdb[10]);
181
182 trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, lba, alloc_len);
bf816235 183
c446c1f9 184out:
bf816235
KT
185 trace_seq_putc(p, 0);
186
187 return ret;
188}
189
5141f16a
HR
190static const char *
191scsi_trace_maintenance_in(struct trace_seq *p, unsigned char *cdb, int len)
192{
193 const char *ret = trace_seq_buffer_ptr(p), *cmd;
194 u32 alloc_len;
195
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;
224 }
225
226 alloc_len = get_unaligned_be32(&cdb[6]);
227
228 trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len);
229
230out:
231 trace_seq_putc(p, 0);
232
233 return ret;
234}
235
236static const char *
237scsi_trace_maintenance_out(struct trace_seq *p, unsigned char *cdb, int len)
238{
239 const char *ret = trace_seq_buffer_ptr(p), *cmd;
240 u32 alloc_len;
241
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;
264 }
265
266 alloc_len = get_unaligned_be32(&cdb[6]);
267
268 trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len);
269
270out:
271 trace_seq_putc(p, 0);
272
273 return ret;
274}
275
0008f1e7
HR
276static const char *
277scsi_trace_zbc_in(struct trace_seq *p, unsigned char *cdb, int len)
278{
279 const char *ret = trace_seq_buffer_ptr(p), *cmd;
280 u64 zone_id;
281 u32 alloc_len;
282 u8 options;
283
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;
291 }
292
293 zone_id = get_unaligned_be64(&cdb[2]);
294 alloc_len = get_unaligned_be32(&cdb[10]);
295 options = cdb[14] & 0x3f;
296
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);
300
301out:
302 trace_seq_putc(p, 0);
303
304 return ret;
305}
306
307static const char *
308scsi_trace_zbc_out(struct trace_seq *p, unsigned char *cdb, int len)
309{
310 const char *ret = trace_seq_buffer_ptr(p), *cmd;
311 u64 zone_id;
312
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;
329 }
330
331 zone_id = get_unaligned_be64(&cdb[2]);
332
333 trace_seq_printf(p, "%s zone=%llu all=%u", cmd,
334 (unsigned long long)zone_id, cdb[14] & 1);
335
336out:
337 trace_seq_putc(p, 0);
338
339 return ret;
340}
341
bf816235
KT
342static const char *
343scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len)
344{
c446c1f9 345 switch (SERVICE_ACTION32(cdb)) {
bf816235 346 case READ_32:
c446c1f9 347 case VERIFY_32:
bf816235 348 case WRITE_32:
c446c1f9 349 case WRITE_SAME_32:
bf816235
KT
350 return scsi_trace_rw32(p, cdb, len);
351 default:
352 return scsi_trace_misc(p, cdb, len);
353 }
354}
355
356static const char *
357scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len)
358{
7b039cb4 359 const char *ret = trace_seq_buffer_ptr(p);
bf816235 360
f50332ff 361 trace_seq_putc(p, '-');
bf816235
KT
362 trace_seq_putc(p, 0);
363
364 return ret;
365}
366
367const char *
368scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len)
369{
370 switch (cdb[0]) {
371 case READ_6:
372 case WRITE_6:
373 return scsi_trace_rw6(p, cdb, len);
374 case READ_10:
c446c1f9 375 case VERIFY:
bf816235 376 case WRITE_10:
c446c1f9 377 case WRITE_SAME:
bf816235
KT
378 return scsi_trace_rw10(p, cdb, len);
379 case READ_12:
c446c1f9 380 case VERIFY_12:
bf816235
KT
381 case WRITE_12:
382 return scsi_trace_rw12(p, cdb, len);
383 case READ_16:
c446c1f9 384 case VERIFY_16:
bf816235 385 case WRITE_16:
c446c1f9 386 case WRITE_SAME_16:
bf816235 387 return scsi_trace_rw16(p, cdb, len);
c446c1f9
MP
388 case UNMAP:
389 return scsi_trace_unmap(p, cdb, len);
eb846d9f 390 case SERVICE_ACTION_IN_16:
c446c1f9 391 return scsi_trace_service_action_in(p, cdb, len);
bf816235
KT
392 case VARIABLE_LENGTH_CMD:
393 return scsi_trace_varlen(p, cdb, len);
5141f16a
HR
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);
0008f1e7
HR
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);
bf816235
KT
402 default:
403 return scsi_trace_misc(p, cdb, len);
404 }
405}