]>
Commit | Line | Data |
---|---|---|
2b27bdcc | 1 | // SPDX-License-Identifier: GPL-2.0-only |
bf816235 KT |
2 | /* |
3 | * Copyright (C) 2010 FUJITSU LIMITED | |
4 | * Copyright (C) 2010 Tomohiro Kusumi <kusumi.tomohiro@jp.fujitsu.com> | |
bf816235 KT |
5 | */ |
6 | #include <linux/kernel.h> | |
7 | #include <linux/trace_seq.h> | |
5141f16a | 8 | #include <asm/unaligned.h> |
bf816235 KT |
9 | #include <trace/events/scsi.h> |
10 | ||
c446c1f9 | 11 | #define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f) |
b1335f5b | 12 | #define SERVICE_ACTION32(cdb) (get_unaligned_be16(&cdb[8])) |
bf816235 KT |
13 | |
14 | static const char * | |
15 | scsi_trace_misc(struct trace_seq *, unsigned char *, int); | |
16 | ||
17 | static const char * | |
18 | scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len) | |
19 | { | |
7b039cb4 | 20 | const char *ret = trace_seq_buffer_ptr(p); |
f6b8540f | 21 | u32 lba = 0, txlen; |
bf816235 KT |
22 | |
23 | lba |= ((cdb[1] & 0x1F) << 16); | |
24 | lba |= (cdb[2] << 8); | |
25 | lba |= cdb[3]; | |
f6b8540f BVA |
26 | /* |
27 | * From SBC-2: a TRANSFER LENGTH field set to zero specifies that 256 | |
28 | * logical blocks shall be read (READ(6)) or written (WRITE(6)). | |
29 | */ | |
30 | txlen = cdb[4] ? cdb[4] : 256; | |
bf816235 | 31 | |
f6b8540f | 32 | trace_seq_printf(p, "lba=%u txlen=%u", lba, txlen); |
bf816235 KT |
33 | trace_seq_putc(p, 0); |
34 | ||
35 | return ret; | |
36 | } | |
37 | ||
38 | static const char * | |
39 | scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) | |
40 | { | |
7b039cb4 | 41 | const char *ret = trace_seq_buffer_ptr(p); |
b1335f5b | 42 | u32 lba, txlen; |
bf816235 | 43 | |
b1335f5b BVA |
44 | lba = get_unaligned_be32(&cdb[2]); |
45 | txlen = get_unaligned_be16(&cdb[7]); | |
bf816235 | 46 | |
b1335f5b | 47 | trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen, |
c446c1f9 | 48 | cdb[1] >> 5); |
c498bf1a MP |
49 | |
50 | if (cdb[0] == WRITE_SAME) | |
51 | trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); | |
52 | ||
bf816235 KT |
53 | trace_seq_putc(p, 0); |
54 | ||
55 | return ret; | |
56 | } | |
57 | ||
58 | static const char * | |
59 | scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len) | |
60 | { | |
7b039cb4 | 61 | const char *ret = trace_seq_buffer_ptr(p); |
b1335f5b BVA |
62 | u32 lba, txlen; |
63 | ||
64 | lba = get_unaligned_be32(&cdb[2]); | |
65 | txlen = get_unaligned_be32(&cdb[6]); | |
bf816235 | 66 | |
b1335f5b | 67 | trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen, |
c446c1f9 | 68 | cdb[1] >> 5); |
bf816235 KT |
69 | trace_seq_putc(p, 0); |
70 | ||
71 | return ret; | |
72 | } | |
73 | ||
74 | static const char * | |
75 | scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) | |
76 | { | |
7b039cb4 | 77 | const char *ret = trace_seq_buffer_ptr(p); |
b1335f5b BVA |
78 | u64 lba; |
79 | u32 txlen; | |
80 | ||
81 | lba = get_unaligned_be64(&cdb[2]); | |
82 | txlen = get_unaligned_be32(&cdb[10]); | |
bf816235 | 83 | |
b1335f5b | 84 | trace_seq_printf(p, "lba=%llu txlen=%u protect=%u", lba, txlen, |
c446c1f9 MP |
85 | cdb[1] >> 5); |
86 | ||
87 | if (cdb[0] == WRITE_SAME_16) | |
88 | trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); | |
89 | ||
bf816235 KT |
90 | trace_seq_putc(p, 0); |
91 | ||
92 | return ret; | |
93 | } | |
94 | ||
95 | static const char * | |
96 | scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len) | |
97 | { | |
7b039cb4 | 98 | const char *ret = trace_seq_buffer_ptr(p), *cmd; |
b1335f5b BVA |
99 | u64 lba; |
100 | u32 ei_lbrt, txlen; | |
c446c1f9 MP |
101 | |
102 | switch (SERVICE_ACTION32(cdb)) { | |
103 | case READ_32: | |
104 | cmd = "READ"; | |
105 | break; | |
106 | case VERIFY_32: | |
107 | cmd = "VERIFY"; | |
108 | break; | |
109 | case WRITE_32: | |
110 | cmd = "WRITE"; | |
111 | break; | |
112 | case WRITE_SAME_32: | |
113 | cmd = "WRITE_SAME"; | |
114 | break; | |
115 | default: | |
91c40f24 | 116 | trace_seq_puts(p, "UNKNOWN"); |
c446c1f9 MP |
117 | goto out; |
118 | } | |
bf816235 | 119 | |
b1335f5b BVA |
120 | lba = get_unaligned_be64(&cdb[12]); |
121 | ei_lbrt = get_unaligned_be32(&cdb[20]); | |
122 | txlen = get_unaligned_be32(&cdb[28]); | |
123 | ||
124 | trace_seq_printf(p, "%s_32 lba=%llu txlen=%u protect=%u ei_lbrt=%u", | |
125 | cmd, lba, txlen, cdb[10] >> 5, ei_lbrt); | |
c446c1f9 MP |
126 | |
127 | if (SERVICE_ACTION32(cdb) == WRITE_SAME_32) | |
128 | trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1); | |
129 | ||
130 | out: | |
131 | trace_seq_putc(p, 0); | |
132 | ||
133 | return ret; | |
134 | } | |
135 | ||
136 | static const char * | |
137 | scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len) | |
138 | { | |
7b039cb4 | 139 | const char *ret = trace_seq_buffer_ptr(p); |
b1335f5b | 140 | unsigned int regions = get_unaligned_be16(&cdb[7]); |
c446c1f9 MP |
141 | |
142 | trace_seq_printf(p, "regions=%u", (regions - 8) / 16); | |
143 | trace_seq_putc(p, 0); | |
144 | ||
145 | return ret; | |
146 | } | |
147 | ||
148 | static const char * | |
149 | scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len) | |
150 | { | |
7b039cb4 | 151 | const char *ret = trace_seq_buffer_ptr(p), *cmd; |
b1335f5b BVA |
152 | u64 lba; |
153 | u32 alloc_len; | |
c446c1f9 MP |
154 | |
155 | switch (SERVICE_ACTION16(cdb)) { | |
156 | case SAI_READ_CAPACITY_16: | |
157 | cmd = "READ_CAPACITY_16"; | |
158 | break; | |
159 | case SAI_GET_LBA_STATUS: | |
160 | cmd = "GET_LBA_STATUS"; | |
161 | break; | |
162 | default: | |
91c40f24 | 163 | trace_seq_puts(p, "UNKNOWN"); |
c446c1f9 MP |
164 | goto out; |
165 | } | |
166 | ||
b1335f5b BVA |
167 | lba = get_unaligned_be64(&cdb[2]); |
168 | alloc_len = get_unaligned_be32(&cdb[10]); | |
169 | ||
170 | trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, lba, alloc_len); | |
bf816235 | 171 | |
c446c1f9 | 172 | out: |
bf816235 KT |
173 | trace_seq_putc(p, 0); |
174 | ||
175 | return ret; | |
176 | } | |
177 | ||
5141f16a HR |
178 | static const char * |
179 | scsi_trace_maintenance_in(struct trace_seq *p, unsigned char *cdb, int len) | |
180 | { | |
181 | const char *ret = trace_seq_buffer_ptr(p), *cmd; | |
182 | u32 alloc_len; | |
183 | ||
184 | switch (SERVICE_ACTION16(cdb)) { | |
185 | case MI_REPORT_IDENTIFYING_INFORMATION: | |
186 | cmd = "REPORT_IDENTIFYING_INFORMATION"; | |
187 | break; | |
188 | case MI_REPORT_TARGET_PGS: | |
189 | cmd = "REPORT_TARGET_PORT_GROUPS"; | |
190 | break; | |
191 | case MI_REPORT_ALIASES: | |
192 | cmd = "REPORT_ALIASES"; | |
193 | break; | |
194 | case MI_REPORT_SUPPORTED_OPERATION_CODES: | |
195 | cmd = "REPORT_SUPPORTED_OPERATION_CODES"; | |
196 | break; | |
197 | case MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS: | |
198 | cmd = "REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS"; | |
199 | break; | |
200 | case MI_REPORT_PRIORITY: | |
201 | cmd = "REPORT_PRIORITY"; | |
202 | break; | |
203 | case MI_REPORT_TIMESTAMP: | |
204 | cmd = "REPORT_TIMESTAMP"; | |
205 | break; | |
206 | case MI_MANAGEMENT_PROTOCOL_IN: | |
207 | cmd = "MANAGEMENT_PROTOCOL_IN"; | |
208 | break; | |
209 | default: | |
210 | trace_seq_puts(p, "UNKNOWN"); | |
211 | goto out; | |
212 | } | |
213 | ||
214 | alloc_len = get_unaligned_be32(&cdb[6]); | |
215 | ||
216 | trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len); | |
217 | ||
218 | out: | |
219 | trace_seq_putc(p, 0); | |
220 | ||
221 | return ret; | |
222 | } | |
223 | ||
224 | static const char * | |
225 | scsi_trace_maintenance_out(struct trace_seq *p, unsigned char *cdb, int len) | |
226 | { | |
227 | const char *ret = trace_seq_buffer_ptr(p), *cmd; | |
228 | u32 alloc_len; | |
229 | ||
230 | switch (SERVICE_ACTION16(cdb)) { | |
231 | case MO_SET_IDENTIFYING_INFORMATION: | |
232 | cmd = "SET_IDENTIFYING_INFORMATION"; | |
233 | break; | |
234 | case MO_SET_TARGET_PGS: | |
235 | cmd = "SET_TARGET_PORT_GROUPS"; | |
236 | break; | |
237 | case MO_CHANGE_ALIASES: | |
238 | cmd = "CHANGE_ALIASES"; | |
239 | break; | |
240 | case MO_SET_PRIORITY: | |
241 | cmd = "SET_PRIORITY"; | |
242 | break; | |
243 | case MO_SET_TIMESTAMP: | |
244 | cmd = "SET_TIMESTAMP"; | |
245 | break; | |
246 | case MO_MANAGEMENT_PROTOCOL_OUT: | |
247 | cmd = "MANAGEMENT_PROTOCOL_OUT"; | |
248 | break; | |
249 | default: | |
250 | trace_seq_puts(p, "UNKNOWN"); | |
251 | goto out; | |
252 | } | |
253 | ||
254 | alloc_len = get_unaligned_be32(&cdb[6]); | |
255 | ||
256 | trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len); | |
257 | ||
258 | out: | |
259 | trace_seq_putc(p, 0); | |
260 | ||
261 | return ret; | |
262 | } | |
263 | ||
0008f1e7 HR |
264 | static const char * |
265 | scsi_trace_zbc_in(struct trace_seq *p, unsigned char *cdb, int len) | |
266 | { | |
267 | const char *ret = trace_seq_buffer_ptr(p), *cmd; | |
268 | u64 zone_id; | |
269 | u32 alloc_len; | |
270 | u8 options; | |
271 | ||
272 | switch (SERVICE_ACTION16(cdb)) { | |
273 | case ZI_REPORT_ZONES: | |
274 | cmd = "REPORT_ZONES"; | |
275 | break; | |
276 | default: | |
277 | trace_seq_puts(p, "UNKNOWN"); | |
278 | goto out; | |
279 | } | |
280 | ||
281 | zone_id = get_unaligned_be64(&cdb[2]); | |
282 | alloc_len = get_unaligned_be32(&cdb[10]); | |
283 | options = cdb[14] & 0x3f; | |
284 | ||
285 | trace_seq_printf(p, "%s zone=%llu alloc_len=%u options=%u partial=%u", | |
286 | cmd, (unsigned long long)zone_id, alloc_len, | |
287 | options, (cdb[14] >> 7) & 1); | |
288 | ||
289 | out: | |
290 | trace_seq_putc(p, 0); | |
291 | ||
292 | return ret; | |
293 | } | |
294 | ||
295 | static const char * | |
296 | scsi_trace_zbc_out(struct trace_seq *p, unsigned char *cdb, int len) | |
297 | { | |
298 | const char *ret = trace_seq_buffer_ptr(p), *cmd; | |
299 | u64 zone_id; | |
300 | ||
301 | switch (SERVICE_ACTION16(cdb)) { | |
302 | case ZO_CLOSE_ZONE: | |
303 | cmd = "CLOSE_ZONE"; | |
304 | break; | |
305 | case ZO_FINISH_ZONE: | |
306 | cmd = "FINISH_ZONE"; | |
307 | break; | |
308 | case ZO_OPEN_ZONE: | |
309 | cmd = "OPEN_ZONE"; | |
310 | break; | |
311 | case ZO_RESET_WRITE_POINTER: | |
312 | cmd = "RESET_WRITE_POINTER"; | |
313 | break; | |
314 | default: | |
315 | trace_seq_puts(p, "UNKNOWN"); | |
316 | goto out; | |
317 | } | |
318 | ||
319 | zone_id = get_unaligned_be64(&cdb[2]); | |
320 | ||
321 | trace_seq_printf(p, "%s zone=%llu all=%u", cmd, | |
322 | (unsigned long long)zone_id, cdb[14] & 1); | |
323 | ||
324 | out: | |
325 | trace_seq_putc(p, 0); | |
326 | ||
327 | return ret; | |
328 | } | |
329 | ||
bf816235 KT |
330 | static const char * |
331 | scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len) | |
332 | { | |
c446c1f9 | 333 | switch (SERVICE_ACTION32(cdb)) { |
bf816235 | 334 | case READ_32: |
c446c1f9 | 335 | case VERIFY_32: |
bf816235 | 336 | case WRITE_32: |
c446c1f9 | 337 | case WRITE_SAME_32: |
bf816235 KT |
338 | return scsi_trace_rw32(p, cdb, len); |
339 | default: | |
340 | return scsi_trace_misc(p, cdb, len); | |
341 | } | |
342 | } | |
343 | ||
344 | static const char * | |
345 | scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len) | |
346 | { | |
7b039cb4 | 347 | const char *ret = trace_seq_buffer_ptr(p); |
bf816235 | 348 | |
f50332ff | 349 | trace_seq_putc(p, '-'); |
bf816235 KT |
350 | trace_seq_putc(p, 0); |
351 | ||
352 | return ret; | |
353 | } | |
354 | ||
355 | const char * | |
356 | scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len) | |
357 | { | |
358 | switch (cdb[0]) { | |
359 | case READ_6: | |
360 | case WRITE_6: | |
361 | return scsi_trace_rw6(p, cdb, len); | |
362 | case READ_10: | |
c446c1f9 | 363 | case VERIFY: |
bf816235 | 364 | case WRITE_10: |
c446c1f9 | 365 | case WRITE_SAME: |
bf816235 KT |
366 | return scsi_trace_rw10(p, cdb, len); |
367 | case READ_12: | |
c446c1f9 | 368 | case VERIFY_12: |
bf816235 KT |
369 | case WRITE_12: |
370 | return scsi_trace_rw12(p, cdb, len); | |
371 | case READ_16: | |
c446c1f9 | 372 | case VERIFY_16: |
bf816235 | 373 | case WRITE_16: |
c446c1f9 | 374 | case WRITE_SAME_16: |
bf816235 | 375 | return scsi_trace_rw16(p, cdb, len); |
c446c1f9 MP |
376 | case UNMAP: |
377 | return scsi_trace_unmap(p, cdb, len); | |
eb846d9f | 378 | case SERVICE_ACTION_IN_16: |
c446c1f9 | 379 | return scsi_trace_service_action_in(p, cdb, len); |
bf816235 KT |
380 | case VARIABLE_LENGTH_CMD: |
381 | return scsi_trace_varlen(p, cdb, len); | |
5141f16a HR |
382 | case MAINTENANCE_IN: |
383 | return scsi_trace_maintenance_in(p, cdb, len); | |
384 | case MAINTENANCE_OUT: | |
385 | return scsi_trace_maintenance_out(p, cdb, len); | |
0008f1e7 HR |
386 | case ZBC_IN: |
387 | return scsi_trace_zbc_in(p, cdb, len); | |
388 | case ZBC_OUT: | |
389 | return scsi_trace_zbc_out(p, cdb, len); | |
bf816235 KT |
390 | default: |
391 | return scsi_trace_misc(p, cdb, len); | |
392 | } | |
393 | } |