xref: /linux/include/uapi/linux/target_core_user.h (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
16f52b16cSGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
27c9e7a6fSAndy Grover #ifndef __TARGET_CORE_USER_H
37c9e7a6fSAndy Grover #define __TARGET_CORE_USER_H
47c9e7a6fSAndy Grover 
57c9e7a6fSAndy Grover /* This header will be used by application too */
67c9e7a6fSAndy Grover 
77c9e7a6fSAndy Grover #include <linux/types.h>
87c9e7a6fSAndy Grover #include <linux/uio.h>
97c9e7a6fSAndy Grover 
100ad46af8SAndy Grover #define TCMU_VERSION "2.0"
117c9e7a6fSAndy Grover 
12572ccdabSRandy Dunlap /**
13572ccdabSRandy Dunlap  * DOC: Ring Design
147c9e7a6fSAndy Grover  * Ring Design
157c9e7a6fSAndy Grover  * -----------
167c9e7a6fSAndy Grover  *
177c9e7a6fSAndy Grover  * The mmaped area is divided into three parts:
18572ccdabSRandy Dunlap  * 1) The mailbox (struct tcmu_mailbox, below);
19572ccdabSRandy Dunlap  * 2) The command ring;
20572ccdabSRandy Dunlap  * 3) Everything beyond the command ring (data).
217c9e7a6fSAndy Grover  *
227c9e7a6fSAndy Grover  * The mailbox tells userspace the offset of the command ring from the
237c9e7a6fSAndy Grover  * start of the shared memory region, and how big the command ring is.
247c9e7a6fSAndy Grover  *
257c9e7a6fSAndy Grover  * The kernel passes SCSI commands to userspace by putting a struct
267c9e7a6fSAndy Grover  * tcmu_cmd_entry in the ring, updating mailbox->cmd_head, and poking
27572ccdabSRandy Dunlap  * userspace via UIO's interrupt mechanism.
287c9e7a6fSAndy Grover  *
297c9e7a6fSAndy Grover  * tcmu_cmd_entry contains a header. If the header type is PAD,
307c9e7a6fSAndy Grover  * userspace should skip hdr->length bytes (mod cmdr_size) to find the
317c9e7a6fSAndy Grover  * next cmd_entry.
327c9e7a6fSAndy Grover  *
337c9e7a6fSAndy Grover  * Otherwise, the entry will contain offsets into the mmaped area that
347c9e7a6fSAndy Grover  * contain the cdb and data buffers -- the latter accessible via the
357c9e7a6fSAndy Grover  * iov array. iov addresses are also offsets into the shared area.
367c9e7a6fSAndy Grover  *
377c9e7a6fSAndy Grover  * When userspace is completed handling the command, set
387c9e7a6fSAndy Grover  * entry->rsp.scsi_status, fill in rsp.sense_buffer if appropriate,
397c9e7a6fSAndy Grover  * and also set mailbox->cmd_tail equal to the old cmd_tail plus
407c9e7a6fSAndy Grover  * hdr->length, mod cmdr_size. If cmd_tail doesn't equal cmd_head, it
417c9e7a6fSAndy Grover  * should process the next packet the same way, and so on.
427c9e7a6fSAndy Grover  */
437c9e7a6fSAndy Grover 
440ad46af8SAndy Grover #define TCMU_MAILBOX_VERSION 2
457c9e7a6fSAndy Grover #define ALIGN_SIZE 64 /* Should be enough for most CPUs */
4632c76de3SSheng Yang #define TCMU_MAILBOX_FLAG_CAP_OOOC (1 << 0) /* Out-of-order completions */
476c3796d1Sbstroesser@ts.fujitsu.com #define TCMU_MAILBOX_FLAG_CAP_READ_LEN (1 << 1) /* Read data length */
48bc2d214aSBodo Stroesser #define TCMU_MAILBOX_FLAG_CAP_TMR (1 << 2) /* TMR notifications */
49018c1491SBodo Stroesser #define TCMU_MAILBOX_FLAG_CAP_KEEP_BUF (1<<3) /* Keep buf after cmd completion */
507c9e7a6fSAndy Grover 
517c9e7a6fSAndy Grover struct tcmu_mailbox {
527c9e7a6fSAndy Grover 	__u16 version;
537c9e7a6fSAndy Grover 	__u16 flags;
547c9e7a6fSAndy Grover 	__u32 cmdr_off;
557c9e7a6fSAndy Grover 	__u32 cmdr_size;
567c9e7a6fSAndy Grover 
577c9e7a6fSAndy Grover 	__u32 cmd_head;
587c9e7a6fSAndy Grover 
597c9e7a6fSAndy Grover 	/* Updated by user. On its own cacheline */
607c9e7a6fSAndy Grover 	__u32 cmd_tail __attribute__((__aligned__(ALIGN_SIZE)));
617c9e7a6fSAndy Grover 
627c9e7a6fSAndy Grover } __packed;
637c9e7a6fSAndy Grover 
647c9e7a6fSAndy Grover enum tcmu_opcode {
657c9e7a6fSAndy Grover 	TCMU_OP_PAD = 0,
667c9e7a6fSAndy Grover 	TCMU_OP_CMD,
67bc2d214aSBodo Stroesser 	TCMU_OP_TMR,
687c9e7a6fSAndy Grover };
697c9e7a6fSAndy Grover 
707c9e7a6fSAndy Grover /*
717c9e7a6fSAndy Grover  * Only a few opcodes, and length is 8-byte aligned, so use low bits for opcode.
727c9e7a6fSAndy Grover  */
737c9e7a6fSAndy Grover struct tcmu_cmd_entry_hdr {
747c9e7a6fSAndy Grover 	__u32 len_op;
750ad46af8SAndy Grover 	__u16 cmd_id;
760ad46af8SAndy Grover 	__u8 kflags;
770ad46af8SAndy Grover #define TCMU_UFLAG_UNKNOWN_OP 0x1
786c3796d1Sbstroesser@ts.fujitsu.com #define TCMU_UFLAG_READ_LEN   0x2
79018c1491SBodo Stroesser #define TCMU_UFLAG_KEEP_BUF   0x4
800ad46af8SAndy Grover 	__u8 uflags;
810ad46af8SAndy Grover 
827c9e7a6fSAndy Grover } __packed;
837c9e7a6fSAndy Grover 
847c9e7a6fSAndy Grover #define TCMU_OP_MASK 0x7
857c9e7a6fSAndy Grover 
tcmu_hdr_get_op(__u32 len_op)860ad46af8SAndy Grover static inline enum tcmu_opcode tcmu_hdr_get_op(__u32 len_op)
877c9e7a6fSAndy Grover {
880ad46af8SAndy Grover 	return len_op & TCMU_OP_MASK;
897c9e7a6fSAndy Grover }
907c9e7a6fSAndy Grover 
tcmu_hdr_set_op(__u32 * len_op,enum tcmu_opcode op)910ad46af8SAndy Grover static inline void tcmu_hdr_set_op(__u32 *len_op, enum tcmu_opcode op)
927c9e7a6fSAndy Grover {
930ad46af8SAndy Grover 	*len_op &= ~TCMU_OP_MASK;
940ad46af8SAndy Grover 	*len_op |= (op & TCMU_OP_MASK);
957c9e7a6fSAndy Grover }
967c9e7a6fSAndy Grover 
tcmu_hdr_get_len(__u32 len_op)970ad46af8SAndy Grover static inline __u32 tcmu_hdr_get_len(__u32 len_op)
987c9e7a6fSAndy Grover {
990ad46af8SAndy Grover 	return len_op & ~TCMU_OP_MASK;
1007c9e7a6fSAndy Grover }
1017c9e7a6fSAndy Grover 
tcmu_hdr_set_len(__u32 * len_op,__u32 len)1020ad46af8SAndy Grover static inline void tcmu_hdr_set_len(__u32 *len_op, __u32 len)
1037c9e7a6fSAndy Grover {
1040ad46af8SAndy Grover 	*len_op &= TCMU_OP_MASK;
1050ad46af8SAndy Grover 	*len_op |= len;
1067c9e7a6fSAndy Grover }
1077c9e7a6fSAndy Grover 
1087c9e7a6fSAndy Grover /* Currently the same as SCSI_SENSE_BUFFERSIZE */
1097c9e7a6fSAndy Grover #define TCMU_SENSE_BUFFERSIZE 96
1107c9e7a6fSAndy Grover 
1117c9e7a6fSAndy Grover struct tcmu_cmd_entry {
1127c9e7a6fSAndy Grover 	struct tcmu_cmd_entry_hdr hdr;
1137c9e7a6fSAndy Grover 
1147c9e7a6fSAndy Grover 	union {
1157c9e7a6fSAndy Grover 		struct {
116762b6f00SDmitry V. Levin 			__u32 iov_cnt;
117762b6f00SDmitry V. Levin 			__u32 iov_bidi_cnt;
118762b6f00SDmitry V. Levin 			__u32 iov_dif_cnt;
119762b6f00SDmitry V. Levin 			__u64 cdb_off;
120762b6f00SDmitry V. Levin 			__u64 __pad1;
121762b6f00SDmitry V. Levin 			__u64 __pad2;
122*5c8c74efSGustavo A. R. Silva 			__DECLARE_FLEX_ARRAY(struct iovec, iov);
1237c9e7a6fSAndy Grover 		} req;
1247c9e7a6fSAndy Grover 		struct {
125762b6f00SDmitry V. Levin 			__u8 scsi_status;
126762b6f00SDmitry V. Levin 			__u8 __pad1;
127762b6f00SDmitry V. Levin 			__u16 __pad2;
1286c3796d1Sbstroesser@ts.fujitsu.com 			__u32 read_len;
1297c9e7a6fSAndy Grover 			char sense_buffer[TCMU_SENSE_BUFFERSIZE];
1307c9e7a6fSAndy Grover 		} rsp;
1317c9e7a6fSAndy Grover 	};
1327c9e7a6fSAndy Grover 
1337c9e7a6fSAndy Grover } __packed;
1347c9e7a6fSAndy Grover 
135bc2d214aSBodo Stroesser struct tcmu_tmr_entry {
136bc2d214aSBodo Stroesser 	struct tcmu_cmd_entry_hdr hdr;
137bc2d214aSBodo Stroesser 
138bc2d214aSBodo Stroesser #define TCMU_TMR_UNKNOWN		0
139bc2d214aSBodo Stroesser #define TCMU_TMR_ABORT_TASK		1
140bc2d214aSBodo Stroesser #define TCMU_TMR_ABORT_TASK_SET		2
141bc2d214aSBodo Stroesser #define TCMU_TMR_CLEAR_ACA		3
142bc2d214aSBodo Stroesser #define TCMU_TMR_CLEAR_TASK_SET		4
143bc2d214aSBodo Stroesser #define TCMU_TMR_LUN_RESET		5
144bc2d214aSBodo Stroesser #define TCMU_TMR_TARGET_WARM_RESET	6
145bc2d214aSBodo Stroesser #define TCMU_TMR_TARGET_COLD_RESET	7
146bc2d214aSBodo Stroesser /* Pseudo reset due to received PR OUT */
147bc2d214aSBodo Stroesser #define TCMU_TMR_LUN_RESET_PRO		128
148bc2d214aSBodo Stroesser 	__u8 tmr_type;
149bc2d214aSBodo Stroesser 
150bc2d214aSBodo Stroesser 	__u8 __pad1;
151bc2d214aSBodo Stroesser 	__u16 __pad2;
152bc2d214aSBodo Stroesser 	__u32 cmd_cnt;
153bc2d214aSBodo Stroesser 	__u64 __pad3;
154bc2d214aSBodo Stroesser 	__u64 __pad4;
15594dfc73eSGustavo A. R. Silva 	__u16 cmd_ids[];
156bc2d214aSBodo Stroesser } __packed;
157bc2d214aSBodo Stroesser 
158762b6f00SDmitry V. Levin #define TCMU_OP_ALIGN_SIZE sizeof(__u64)
1597c9e7a6fSAndy Grover 
1607c9e7a6fSAndy Grover enum tcmu_genl_cmd {
1617c9e7a6fSAndy Grover 	TCMU_CMD_UNSPEC,
1627c9e7a6fSAndy Grover 	TCMU_CMD_ADDED_DEVICE,
1637c9e7a6fSAndy Grover 	TCMU_CMD_REMOVED_DEVICE,
1641068be7bSBryant G. Ly 	TCMU_CMD_RECONFIG_DEVICE,
165b3af66e2SMike Christie 	TCMU_CMD_ADDED_DEVICE_DONE,
166b3af66e2SMike Christie 	TCMU_CMD_REMOVED_DEVICE_DONE,
167b3af66e2SMike Christie 	TCMU_CMD_RECONFIG_DEVICE_DONE,
168b3af66e2SMike Christie 	TCMU_CMD_SET_FEATURES,
1697c9e7a6fSAndy Grover 	__TCMU_CMD_MAX,
1707c9e7a6fSAndy Grover };
1717c9e7a6fSAndy Grover #define TCMU_CMD_MAX (__TCMU_CMD_MAX - 1)
1727c9e7a6fSAndy Grover 
1737c9e7a6fSAndy Grover enum tcmu_genl_attr {
1747c9e7a6fSAndy Grover 	TCMU_ATTR_UNSPEC,
1757c9e7a6fSAndy Grover 	TCMU_ATTR_DEVICE,
1767c9e7a6fSAndy Grover 	TCMU_ATTR_MINOR,
1772d76443eSMike Christie 	TCMU_ATTR_PAD,
1782d76443eSMike Christie 	TCMU_ATTR_DEV_CFG,
1792d76443eSMike Christie 	TCMU_ATTR_DEV_SIZE,
1802d76443eSMike Christie 	TCMU_ATTR_WRITECACHE,
181b3af66e2SMike Christie 	TCMU_ATTR_CMD_STATUS,
182b3af66e2SMike Christie 	TCMU_ATTR_DEVICE_ID,
183b3af66e2SMike Christie 	TCMU_ATTR_SUPP_KERN_CMD_REPLY,
1847c9e7a6fSAndy Grover 	__TCMU_ATTR_MAX,
1857c9e7a6fSAndy Grover };
1867c9e7a6fSAndy Grover #define TCMU_ATTR_MAX (__TCMU_ATTR_MAX - 1)
1877c9e7a6fSAndy Grover 
1887c9e7a6fSAndy Grover #endif
189