18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <stdio.h>
38c2ecf20Sopenharmony_ci#include <string.h>
48c2ecf20Sopenharmony_ci#include <inttypes.h>
58c2ecf20Sopenharmony_ci#include "event-parse.h"
68c2ecf20Sopenharmony_ci#include "trace-seq.h"
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_citypedef unsigned long sector_t;
98c2ecf20Sopenharmony_citypedef uint64_t u64;
108c2ecf20Sopenharmony_citypedef unsigned int u32;
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/*
138c2ecf20Sopenharmony_ci *      SCSI opcodes
148c2ecf20Sopenharmony_ci */
158c2ecf20Sopenharmony_ci#define TEST_UNIT_READY			0x00
168c2ecf20Sopenharmony_ci#define REZERO_UNIT			0x01
178c2ecf20Sopenharmony_ci#define REQUEST_SENSE			0x03
188c2ecf20Sopenharmony_ci#define FORMAT_UNIT			0x04
198c2ecf20Sopenharmony_ci#define READ_BLOCK_LIMITS		0x05
208c2ecf20Sopenharmony_ci#define REASSIGN_BLOCKS			0x07
218c2ecf20Sopenharmony_ci#define INITIALIZE_ELEMENT_STATUS	0x07
228c2ecf20Sopenharmony_ci#define READ_6				0x08
238c2ecf20Sopenharmony_ci#define WRITE_6				0x0a
248c2ecf20Sopenharmony_ci#define SEEK_6				0x0b
258c2ecf20Sopenharmony_ci#define READ_REVERSE			0x0f
268c2ecf20Sopenharmony_ci#define WRITE_FILEMARKS			0x10
278c2ecf20Sopenharmony_ci#define SPACE				0x11
288c2ecf20Sopenharmony_ci#define INQUIRY				0x12
298c2ecf20Sopenharmony_ci#define RECOVER_BUFFERED_DATA		0x14
308c2ecf20Sopenharmony_ci#define MODE_SELECT			0x15
318c2ecf20Sopenharmony_ci#define RESERVE				0x16
328c2ecf20Sopenharmony_ci#define RELEASE				0x17
338c2ecf20Sopenharmony_ci#define COPY				0x18
348c2ecf20Sopenharmony_ci#define ERASE				0x19
358c2ecf20Sopenharmony_ci#define MODE_SENSE			0x1a
368c2ecf20Sopenharmony_ci#define START_STOP			0x1b
378c2ecf20Sopenharmony_ci#define RECEIVE_DIAGNOSTIC		0x1c
388c2ecf20Sopenharmony_ci#define SEND_DIAGNOSTIC			0x1d
398c2ecf20Sopenharmony_ci#define ALLOW_MEDIUM_REMOVAL		0x1e
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define READ_FORMAT_CAPACITIES		0x23
428c2ecf20Sopenharmony_ci#define SET_WINDOW			0x24
438c2ecf20Sopenharmony_ci#define READ_CAPACITY			0x25
448c2ecf20Sopenharmony_ci#define READ_10				0x28
458c2ecf20Sopenharmony_ci#define WRITE_10			0x2a
468c2ecf20Sopenharmony_ci#define SEEK_10				0x2b
478c2ecf20Sopenharmony_ci#define POSITION_TO_ELEMENT		0x2b
488c2ecf20Sopenharmony_ci#define WRITE_VERIFY			0x2e
498c2ecf20Sopenharmony_ci#define VERIFY				0x2f
508c2ecf20Sopenharmony_ci#define SEARCH_HIGH			0x30
518c2ecf20Sopenharmony_ci#define SEARCH_EQUAL			0x31
528c2ecf20Sopenharmony_ci#define SEARCH_LOW			0x32
538c2ecf20Sopenharmony_ci#define SET_LIMITS			0x33
548c2ecf20Sopenharmony_ci#define PRE_FETCH			0x34
558c2ecf20Sopenharmony_ci#define READ_POSITION			0x34
568c2ecf20Sopenharmony_ci#define SYNCHRONIZE_CACHE		0x35
578c2ecf20Sopenharmony_ci#define LOCK_UNLOCK_CACHE		0x36
588c2ecf20Sopenharmony_ci#define READ_DEFECT_DATA		0x37
598c2ecf20Sopenharmony_ci#define MEDIUM_SCAN			0x38
608c2ecf20Sopenharmony_ci#define COMPARE				0x39
618c2ecf20Sopenharmony_ci#define COPY_VERIFY			0x3a
628c2ecf20Sopenharmony_ci#define WRITE_BUFFER			0x3b
638c2ecf20Sopenharmony_ci#define READ_BUFFER			0x3c
648c2ecf20Sopenharmony_ci#define UPDATE_BLOCK			0x3d
658c2ecf20Sopenharmony_ci#define READ_LONG			0x3e
668c2ecf20Sopenharmony_ci#define WRITE_LONG			0x3f
678c2ecf20Sopenharmony_ci#define CHANGE_DEFINITION		0x40
688c2ecf20Sopenharmony_ci#define WRITE_SAME			0x41
698c2ecf20Sopenharmony_ci#define UNMAP				0x42
708c2ecf20Sopenharmony_ci#define READ_TOC			0x43
718c2ecf20Sopenharmony_ci#define READ_HEADER			0x44
728c2ecf20Sopenharmony_ci#define GET_EVENT_STATUS_NOTIFICATION	0x4a
738c2ecf20Sopenharmony_ci#define LOG_SELECT			0x4c
748c2ecf20Sopenharmony_ci#define LOG_SENSE			0x4d
758c2ecf20Sopenharmony_ci#define XDWRITEREAD_10			0x53
768c2ecf20Sopenharmony_ci#define MODE_SELECT_10			0x55
778c2ecf20Sopenharmony_ci#define RESERVE_10			0x56
788c2ecf20Sopenharmony_ci#define RELEASE_10			0x57
798c2ecf20Sopenharmony_ci#define MODE_SENSE_10			0x5a
808c2ecf20Sopenharmony_ci#define PERSISTENT_RESERVE_IN		0x5e
818c2ecf20Sopenharmony_ci#define PERSISTENT_RESERVE_OUT		0x5f
828c2ecf20Sopenharmony_ci#define VARIABLE_LENGTH_CMD		0x7f
838c2ecf20Sopenharmony_ci#define REPORT_LUNS			0xa0
848c2ecf20Sopenharmony_ci#define SECURITY_PROTOCOL_IN		0xa2
858c2ecf20Sopenharmony_ci#define MAINTENANCE_IN			0xa3
868c2ecf20Sopenharmony_ci#define MAINTENANCE_OUT			0xa4
878c2ecf20Sopenharmony_ci#define MOVE_MEDIUM			0xa5
888c2ecf20Sopenharmony_ci#define EXCHANGE_MEDIUM			0xa6
898c2ecf20Sopenharmony_ci#define READ_12				0xa8
908c2ecf20Sopenharmony_ci#define SERVICE_ACTION_OUT_12		0xa9
918c2ecf20Sopenharmony_ci#define WRITE_12			0xaa
928c2ecf20Sopenharmony_ci#define SERVICE_ACTION_IN_12		0xab
938c2ecf20Sopenharmony_ci#define WRITE_VERIFY_12			0xae
948c2ecf20Sopenharmony_ci#define VERIFY_12			0xaf
958c2ecf20Sopenharmony_ci#define SEARCH_HIGH_12			0xb0
968c2ecf20Sopenharmony_ci#define SEARCH_EQUAL_12			0xb1
978c2ecf20Sopenharmony_ci#define SEARCH_LOW_12			0xb2
988c2ecf20Sopenharmony_ci#define SECURITY_PROTOCOL_OUT		0xb5
998c2ecf20Sopenharmony_ci#define READ_ELEMENT_STATUS		0xb8
1008c2ecf20Sopenharmony_ci#define SEND_VOLUME_TAG			0xb6
1018c2ecf20Sopenharmony_ci#define WRITE_LONG_2			0xea
1028c2ecf20Sopenharmony_ci#define EXTENDED_COPY			0x83
1038c2ecf20Sopenharmony_ci#define RECEIVE_COPY_RESULTS		0x84
1048c2ecf20Sopenharmony_ci#define ACCESS_CONTROL_IN		0x86
1058c2ecf20Sopenharmony_ci#define ACCESS_CONTROL_OUT		0x87
1068c2ecf20Sopenharmony_ci#define READ_16				0x88
1078c2ecf20Sopenharmony_ci#define WRITE_16			0x8a
1088c2ecf20Sopenharmony_ci#define READ_ATTRIBUTE			0x8c
1098c2ecf20Sopenharmony_ci#define WRITE_ATTRIBUTE			0x8d
1108c2ecf20Sopenharmony_ci#define VERIFY_16			0x8f
1118c2ecf20Sopenharmony_ci#define SYNCHRONIZE_CACHE_16		0x91
1128c2ecf20Sopenharmony_ci#define WRITE_SAME_16			0x93
1138c2ecf20Sopenharmony_ci#define SERVICE_ACTION_BIDIRECTIONAL	0x9d
1148c2ecf20Sopenharmony_ci#define SERVICE_ACTION_IN_16		0x9e
1158c2ecf20Sopenharmony_ci#define SERVICE_ACTION_OUT_16		0x9f
1168c2ecf20Sopenharmony_ci/* values for service action in */
1178c2ecf20Sopenharmony_ci#define	SAI_READ_CAPACITY_16		0x10
1188c2ecf20Sopenharmony_ci#define SAI_GET_LBA_STATUS		0x12
1198c2ecf20Sopenharmony_ci/* values for VARIABLE_LENGTH_CMD service action codes
1208c2ecf20Sopenharmony_ci * see spc4r17 Section D.3.5, table D.7 and D.8 */
1218c2ecf20Sopenharmony_ci#define VLC_SA_RECEIVE_CREDENTIAL	0x1800
1228c2ecf20Sopenharmony_ci/* values for maintenance in */
1238c2ecf20Sopenharmony_ci#define MI_REPORT_IDENTIFYING_INFORMATION		0x05
1248c2ecf20Sopenharmony_ci#define MI_REPORT_TARGET_PGS				0x0a
1258c2ecf20Sopenharmony_ci#define MI_REPORT_ALIASES				0x0b
1268c2ecf20Sopenharmony_ci#define MI_REPORT_SUPPORTED_OPERATION_CODES		0x0c
1278c2ecf20Sopenharmony_ci#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS	0x0d
1288c2ecf20Sopenharmony_ci#define MI_REPORT_PRIORITY				0x0e
1298c2ecf20Sopenharmony_ci#define MI_REPORT_TIMESTAMP				0x0f
1308c2ecf20Sopenharmony_ci#define MI_MANAGEMENT_PROTOCOL_IN			0x10
1318c2ecf20Sopenharmony_ci/* value for MI_REPORT_TARGET_PGS ext header */
1328c2ecf20Sopenharmony_ci#define MI_EXT_HDR_PARAM_FMT		0x20
1338c2ecf20Sopenharmony_ci/* values for maintenance out */
1348c2ecf20Sopenharmony_ci#define MO_SET_IDENTIFYING_INFORMATION	0x06
1358c2ecf20Sopenharmony_ci#define MO_SET_TARGET_PGS		0x0a
1368c2ecf20Sopenharmony_ci#define MO_CHANGE_ALIASES		0x0b
1378c2ecf20Sopenharmony_ci#define MO_SET_PRIORITY			0x0e
1388c2ecf20Sopenharmony_ci#define MO_SET_TIMESTAMP		0x0f
1398c2ecf20Sopenharmony_ci#define MO_MANAGEMENT_PROTOCOL_OUT	0x10
1408c2ecf20Sopenharmony_ci/* values for variable length command */
1418c2ecf20Sopenharmony_ci#define XDREAD_32			0x03
1428c2ecf20Sopenharmony_ci#define XDWRITE_32			0x04
1438c2ecf20Sopenharmony_ci#define XPWRITE_32			0x06
1448c2ecf20Sopenharmony_ci#define XDWRITEREAD_32			0x07
1458c2ecf20Sopenharmony_ci#define READ_32				0x09
1468c2ecf20Sopenharmony_ci#define VERIFY_32			0x0a
1478c2ecf20Sopenharmony_ci#define WRITE_32			0x0b
1488c2ecf20Sopenharmony_ci#define WRITE_SAME_32			0x0d
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci#define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f)
1518c2ecf20Sopenharmony_ci#define SERVICE_ACTION32(cdb) ((cdb[8] << 8) | cdb[9])
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_cistatic const char *
1548c2ecf20Sopenharmony_ciscsi_trace_misc(struct trace_seq *, unsigned char *, int);
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic const char *
1578c2ecf20Sopenharmony_ciscsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	const char *ret = p->buffer + p->len;
1608c2ecf20Sopenharmony_ci	sector_t lba = 0, txlen = 0;
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	lba |= ((cdb[1] & 0x1F) << 16);
1638c2ecf20Sopenharmony_ci	lba |=  (cdb[2] << 8);
1648c2ecf20Sopenharmony_ci	lba |=   cdb[3];
1658c2ecf20Sopenharmony_ci	txlen = cdb[4];
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	trace_seq_printf(p, "lba=%llu txlen=%llu",
1688c2ecf20Sopenharmony_ci			 (unsigned long long)lba, (unsigned long long)txlen);
1698c2ecf20Sopenharmony_ci	trace_seq_putc(p, 0);
1708c2ecf20Sopenharmony_ci	return ret;
1718c2ecf20Sopenharmony_ci}
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_cistatic const char *
1748c2ecf20Sopenharmony_ciscsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	const char *ret = p->buffer + p->len;
1778c2ecf20Sopenharmony_ci	sector_t lba = 0, txlen = 0;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci	lba |= (cdb[2] << 24);
1808c2ecf20Sopenharmony_ci	lba |= (cdb[3] << 16);
1818c2ecf20Sopenharmony_ci	lba |= (cdb[4] << 8);
1828c2ecf20Sopenharmony_ci	lba |=  cdb[5];
1838c2ecf20Sopenharmony_ci	txlen |= (cdb[7] << 8);
1848c2ecf20Sopenharmony_ci	txlen |=  cdb[8];
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u",
1878c2ecf20Sopenharmony_ci			 (unsigned long long)lba, (unsigned long long)txlen,
1888c2ecf20Sopenharmony_ci			 cdb[1] >> 5);
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	if (cdb[0] == WRITE_SAME)
1918c2ecf20Sopenharmony_ci		trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	trace_seq_putc(p, 0);
1948c2ecf20Sopenharmony_ci	return ret;
1958c2ecf20Sopenharmony_ci}
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_cistatic const char *
1988c2ecf20Sopenharmony_ciscsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
1998c2ecf20Sopenharmony_ci{
2008c2ecf20Sopenharmony_ci	const char *ret = p->buffer + p->len;
2018c2ecf20Sopenharmony_ci	sector_t lba = 0, txlen = 0;
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	lba |= (cdb[2] << 24);
2048c2ecf20Sopenharmony_ci	lba |= (cdb[3] << 16);
2058c2ecf20Sopenharmony_ci	lba |= (cdb[4] << 8);
2068c2ecf20Sopenharmony_ci	lba |=  cdb[5];
2078c2ecf20Sopenharmony_ci	txlen |= (cdb[6] << 24);
2088c2ecf20Sopenharmony_ci	txlen |= (cdb[7] << 16);
2098c2ecf20Sopenharmony_ci	txlen |= (cdb[8] << 8);
2108c2ecf20Sopenharmony_ci	txlen |=  cdb[9];
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u",
2138c2ecf20Sopenharmony_ci			 (unsigned long long)lba, (unsigned long long)txlen,
2148c2ecf20Sopenharmony_ci			 cdb[1] >> 5);
2158c2ecf20Sopenharmony_ci	trace_seq_putc(p, 0);
2168c2ecf20Sopenharmony_ci	return ret;
2178c2ecf20Sopenharmony_ci}
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_cistatic const char *
2208c2ecf20Sopenharmony_ciscsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
2218c2ecf20Sopenharmony_ci{
2228c2ecf20Sopenharmony_ci	const char *ret = p->buffer + p->len;
2238c2ecf20Sopenharmony_ci	sector_t lba = 0, txlen = 0;
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[2] << 56);
2268c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[3] << 48);
2278c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[4] << 40);
2288c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[5] << 32);
2298c2ecf20Sopenharmony_ci	lba |= (cdb[6] << 24);
2308c2ecf20Sopenharmony_ci	lba |= (cdb[7] << 16);
2318c2ecf20Sopenharmony_ci	lba |= (cdb[8] << 8);
2328c2ecf20Sopenharmony_ci	lba |=  cdb[9];
2338c2ecf20Sopenharmony_ci	txlen |= (cdb[10] << 24);
2348c2ecf20Sopenharmony_ci	txlen |= (cdb[11] << 16);
2358c2ecf20Sopenharmony_ci	txlen |= (cdb[12] << 8);
2368c2ecf20Sopenharmony_ci	txlen |=  cdb[13];
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u",
2398c2ecf20Sopenharmony_ci			 (unsigned long long)lba, (unsigned long long)txlen,
2408c2ecf20Sopenharmony_ci			 cdb[1] >> 5);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	if (cdb[0] == WRITE_SAME_16)
2438c2ecf20Sopenharmony_ci		trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci	trace_seq_putc(p, 0);
2468c2ecf20Sopenharmony_ci	return ret;
2478c2ecf20Sopenharmony_ci}
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_cistatic const char *
2508c2ecf20Sopenharmony_ciscsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len)
2518c2ecf20Sopenharmony_ci{
2528c2ecf20Sopenharmony_ci	const char *ret = p->buffer + p->len, *cmd;
2538c2ecf20Sopenharmony_ci	sector_t lba = 0, txlen = 0;
2548c2ecf20Sopenharmony_ci	u32 ei_lbrt = 0;
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	switch (SERVICE_ACTION32(cdb)) {
2578c2ecf20Sopenharmony_ci	case READ_32:
2588c2ecf20Sopenharmony_ci		cmd = "READ";
2598c2ecf20Sopenharmony_ci		break;
2608c2ecf20Sopenharmony_ci	case VERIFY_32:
2618c2ecf20Sopenharmony_ci		cmd = "VERIFY";
2628c2ecf20Sopenharmony_ci		break;
2638c2ecf20Sopenharmony_ci	case WRITE_32:
2648c2ecf20Sopenharmony_ci		cmd = "WRITE";
2658c2ecf20Sopenharmony_ci		break;
2668c2ecf20Sopenharmony_ci	case WRITE_SAME_32:
2678c2ecf20Sopenharmony_ci		cmd = "WRITE_SAME";
2688c2ecf20Sopenharmony_ci		break;
2698c2ecf20Sopenharmony_ci	default:
2708c2ecf20Sopenharmony_ci		trace_seq_printf(p, "UNKNOWN");
2718c2ecf20Sopenharmony_ci		goto out;
2728c2ecf20Sopenharmony_ci	}
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[12] << 56);
2758c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[13] << 48);
2768c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[14] << 40);
2778c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[15] << 32);
2788c2ecf20Sopenharmony_ci	lba |= (cdb[16] << 24);
2798c2ecf20Sopenharmony_ci	lba |= (cdb[17] << 16);
2808c2ecf20Sopenharmony_ci	lba |= (cdb[18] << 8);
2818c2ecf20Sopenharmony_ci	lba |=  cdb[19];
2828c2ecf20Sopenharmony_ci	ei_lbrt |= (cdb[20] << 24);
2838c2ecf20Sopenharmony_ci	ei_lbrt |= (cdb[21] << 16);
2848c2ecf20Sopenharmony_ci	ei_lbrt |= (cdb[22] << 8);
2858c2ecf20Sopenharmony_ci	ei_lbrt |=  cdb[23];
2868c2ecf20Sopenharmony_ci	txlen |= (cdb[28] << 24);
2878c2ecf20Sopenharmony_ci	txlen |= (cdb[29] << 16);
2888c2ecf20Sopenharmony_ci	txlen |= (cdb[30] << 8);
2898c2ecf20Sopenharmony_ci	txlen |=  cdb[31];
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	trace_seq_printf(p, "%s_32 lba=%llu txlen=%llu protect=%u ei_lbrt=%u",
2928c2ecf20Sopenharmony_ci			 cmd, (unsigned long long)lba,
2938c2ecf20Sopenharmony_ci			 (unsigned long long)txlen, cdb[10] >> 5, ei_lbrt);
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	if (SERVICE_ACTION32(cdb) == WRITE_SAME_32)
2968c2ecf20Sopenharmony_ci		trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1);
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ciout:
2998c2ecf20Sopenharmony_ci	trace_seq_putc(p, 0);
3008c2ecf20Sopenharmony_ci	return ret;
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_cistatic const char *
3048c2ecf20Sopenharmony_ciscsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
3058c2ecf20Sopenharmony_ci{
3068c2ecf20Sopenharmony_ci	const char *ret = p->buffer + p->len;
3078c2ecf20Sopenharmony_ci	unsigned int regions = cdb[7] << 8 | cdb[8];
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	trace_seq_printf(p, "regions=%u", (regions - 8) / 16);
3108c2ecf20Sopenharmony_ci	trace_seq_putc(p, 0);
3118c2ecf20Sopenharmony_ci	return ret;
3128c2ecf20Sopenharmony_ci}
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_cistatic const char *
3158c2ecf20Sopenharmony_ciscsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len)
3168c2ecf20Sopenharmony_ci{
3178c2ecf20Sopenharmony_ci	const char *ret = p->buffer + p->len, *cmd;
3188c2ecf20Sopenharmony_ci	sector_t lba = 0;
3198c2ecf20Sopenharmony_ci	u32 alloc_len = 0;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	switch (SERVICE_ACTION16(cdb)) {
3228c2ecf20Sopenharmony_ci	case SAI_READ_CAPACITY_16:
3238c2ecf20Sopenharmony_ci		cmd = "READ_CAPACITY_16";
3248c2ecf20Sopenharmony_ci		break;
3258c2ecf20Sopenharmony_ci	case SAI_GET_LBA_STATUS:
3268c2ecf20Sopenharmony_ci		cmd = "GET_LBA_STATUS";
3278c2ecf20Sopenharmony_ci		break;
3288c2ecf20Sopenharmony_ci	default:
3298c2ecf20Sopenharmony_ci		trace_seq_printf(p, "UNKNOWN");
3308c2ecf20Sopenharmony_ci		goto out;
3318c2ecf20Sopenharmony_ci	}
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[2] << 56);
3348c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[3] << 48);
3358c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[4] << 40);
3368c2ecf20Sopenharmony_ci	lba |= ((u64)cdb[5] << 32);
3378c2ecf20Sopenharmony_ci	lba |= (cdb[6] << 24);
3388c2ecf20Sopenharmony_ci	lba |= (cdb[7] << 16);
3398c2ecf20Sopenharmony_ci	lba |= (cdb[8] << 8);
3408c2ecf20Sopenharmony_ci	lba |=  cdb[9];
3418c2ecf20Sopenharmony_ci	alloc_len |= (cdb[10] << 24);
3428c2ecf20Sopenharmony_ci	alloc_len |= (cdb[11] << 16);
3438c2ecf20Sopenharmony_ci	alloc_len |= (cdb[12] << 8);
3448c2ecf20Sopenharmony_ci	alloc_len |=  cdb[13];
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci	trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd,
3478c2ecf20Sopenharmony_ci			 (unsigned long long)lba, alloc_len);
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ciout:
3508c2ecf20Sopenharmony_ci	trace_seq_putc(p, 0);
3518c2ecf20Sopenharmony_ci	return ret;
3528c2ecf20Sopenharmony_ci}
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_cistatic const char *
3558c2ecf20Sopenharmony_ciscsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len)
3568c2ecf20Sopenharmony_ci{
3578c2ecf20Sopenharmony_ci	switch (SERVICE_ACTION32(cdb)) {
3588c2ecf20Sopenharmony_ci	case READ_32:
3598c2ecf20Sopenharmony_ci	case VERIFY_32:
3608c2ecf20Sopenharmony_ci	case WRITE_32:
3618c2ecf20Sopenharmony_ci	case WRITE_SAME_32:
3628c2ecf20Sopenharmony_ci		return scsi_trace_rw32(p, cdb, len);
3638c2ecf20Sopenharmony_ci	default:
3648c2ecf20Sopenharmony_ci		return scsi_trace_misc(p, cdb, len);
3658c2ecf20Sopenharmony_ci	}
3668c2ecf20Sopenharmony_ci}
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_cistatic const char *
3698c2ecf20Sopenharmony_ciscsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len)
3708c2ecf20Sopenharmony_ci{
3718c2ecf20Sopenharmony_ci	const char *ret = p->buffer + p->len;
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	trace_seq_printf(p, "-");
3748c2ecf20Sopenharmony_ci	trace_seq_putc(p, 0);
3758c2ecf20Sopenharmony_ci	return ret;
3768c2ecf20Sopenharmony_ci}
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ciconst char *
3798c2ecf20Sopenharmony_ciscsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len)
3808c2ecf20Sopenharmony_ci{
3818c2ecf20Sopenharmony_ci	switch (cdb[0]) {
3828c2ecf20Sopenharmony_ci	case READ_6:
3838c2ecf20Sopenharmony_ci	case WRITE_6:
3848c2ecf20Sopenharmony_ci		return scsi_trace_rw6(p, cdb, len);
3858c2ecf20Sopenharmony_ci	case READ_10:
3868c2ecf20Sopenharmony_ci	case VERIFY:
3878c2ecf20Sopenharmony_ci	case WRITE_10:
3888c2ecf20Sopenharmony_ci	case WRITE_SAME:
3898c2ecf20Sopenharmony_ci		return scsi_trace_rw10(p, cdb, len);
3908c2ecf20Sopenharmony_ci	case READ_12:
3918c2ecf20Sopenharmony_ci	case VERIFY_12:
3928c2ecf20Sopenharmony_ci	case WRITE_12:
3938c2ecf20Sopenharmony_ci		return scsi_trace_rw12(p, cdb, len);
3948c2ecf20Sopenharmony_ci	case READ_16:
3958c2ecf20Sopenharmony_ci	case VERIFY_16:
3968c2ecf20Sopenharmony_ci	case WRITE_16:
3978c2ecf20Sopenharmony_ci	case WRITE_SAME_16:
3988c2ecf20Sopenharmony_ci		return scsi_trace_rw16(p, cdb, len);
3998c2ecf20Sopenharmony_ci	case UNMAP:
4008c2ecf20Sopenharmony_ci		return scsi_trace_unmap(p, cdb, len);
4018c2ecf20Sopenharmony_ci	case SERVICE_ACTION_IN_16:
4028c2ecf20Sopenharmony_ci		return scsi_trace_service_action_in(p, cdb, len);
4038c2ecf20Sopenharmony_ci	case VARIABLE_LENGTH_CMD:
4048c2ecf20Sopenharmony_ci		return scsi_trace_varlen(p, cdb, len);
4058c2ecf20Sopenharmony_ci	default:
4068c2ecf20Sopenharmony_ci		return scsi_trace_misc(p, cdb, len);
4078c2ecf20Sopenharmony_ci	}
4088c2ecf20Sopenharmony_ci}
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ciunsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s,
4118c2ecf20Sopenharmony_ci						unsigned long long *args)
4128c2ecf20Sopenharmony_ci{
4138c2ecf20Sopenharmony_ci	scsi_trace_parse_cdb(s, (unsigned char *) (unsigned long) args[1], args[2]);
4148c2ecf20Sopenharmony_ci	return 0;
4158c2ecf20Sopenharmony_ci}
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_ciint TEP_PLUGIN_LOADER(struct tep_handle *tep)
4188c2ecf20Sopenharmony_ci{
4198c2ecf20Sopenharmony_ci	tep_register_print_function(tep,
4208c2ecf20Sopenharmony_ci				    process_scsi_trace_parse_cdb,
4218c2ecf20Sopenharmony_ci				    TEP_FUNC_ARG_STRING,
4228c2ecf20Sopenharmony_ci				    "scsi_trace_parse_cdb",
4238c2ecf20Sopenharmony_ci				    TEP_FUNC_ARG_PTR,
4248c2ecf20Sopenharmony_ci				    TEP_FUNC_ARG_PTR,
4258c2ecf20Sopenharmony_ci				    TEP_FUNC_ARG_INT,
4268c2ecf20Sopenharmony_ci				    TEP_FUNC_ARG_VOID);
4278c2ecf20Sopenharmony_ci	return 0;
4288c2ecf20Sopenharmony_ci}
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_civoid TEP_PLUGIN_UNLOADER(struct tep_handle *tep)
4318c2ecf20Sopenharmony_ci{
4328c2ecf20Sopenharmony_ci	tep_unregister_print_function(tep, process_scsi_trace_parse_cdb,
4338c2ecf20Sopenharmony_ci				      "scsi_trace_parse_cdb");
4348c2ecf20Sopenharmony_ci}
435