brintos

brintos / linux-shallow public Read only

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