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