xref: /freebsd/sys/dev/vmware/pvscsi/pvscsi.h (revision 90aac0d83bc9645f51ef0c2aeae6f9c0540bb031)
1 /*-
2  * Copyright (c) 2018 VMware, Inc.
3  *
4  * SPDX-License-Identifier: (BSD-2-Clause OR GPL-2.0)
5  */
6 
7 #ifndef _PVSCSI_H_
8 #define _PVSCSI_H_
9 
10 #define	MASK(v)	((1 << (v)) - 1)
11 
12 #define	PCI_VENDOR_ID_VMWARE		0x15ad
13 #define	PCI_DEVICE_ID_VMWARE_PVSCSI	0x07c0
14 
15 enum pvscsi_reg_offset {
16 	PVSCSI_REG_OFFSET_COMMAND		= 0x0000,
17 	PVSCSI_REG_OFFSET_COMMAND_DATA		= 0x0004,
18 	PVSCSI_REG_OFFSET_COMMAND_STATUS	= 0x0008,
19 	PVSCSI_REG_OFFSET_LAST_STS_0		= 0x0100,
20 	PVSCSI_REG_OFFSET_LAST_STS_1		= 0x0104,
21 	PVSCSI_REG_OFFSET_LAST_STS_2		= 0x0108,
22 	PVSCSI_REG_OFFSET_LAST_STS_3		= 0x010c,
23 	PVSCSI_REG_OFFSET_INTR_STATUS		= 0x100c,
24 	PVSCSI_REG_OFFSET_INTR_MASK		= 0x2010,
25 	PVSCSI_REG_OFFSET_KICK_NON_RW_IO	= 0x3014,
26 	PVSCSI_REG_OFFSET_DEBUG			= 0x3018,
27 	PVSCSI_REG_OFFSET_KICK_RW_IO		= 0x4018,
28 };
29 
30 enum pvscsi_commands {
31 	PVSCSI_CMD_FIRST			= 0,
32 
33 	PVSCSI_CMD_ADAPTER_RESET		= 1,
34 	PVSCSI_CMD_ISSUE_SCSI			= 2,
35 	PVSCSI_CMD_SETUP_RINGS			= 3,
36 	PVSCSI_CMD_RESET_BUS			= 4,
37 	PVSCSI_CMD_RESET_DEVICE			= 5,
38 	PVSCSI_CMD_ABORT_CMD			= 6,
39 	PVSCSI_CMD_CONFIG			= 7,
40 	PVSCSI_CMD_SETUP_MSG_RING		= 8,
41 	PVSCSI_CMD_DEVICE_UNPLUG		= 9,
42 	PVSCSI_CMD_SETUP_REQCALLTHRESHOLD	= 10,
43 	PVSCSI_CMD_GET_MAX_TARGETS		= 11,
44 
45 	PVSCSI_CMD_LAST				= 12,
46 };
47 
48 struct pvscsi_cmd_desc_reset_device {
49 	uint32_t	target;
50 	uint8_t		lun[8];
51 };
52 
53 struct pvscsi_cmd_desc_abort_cmd {
54 	uint64_t	context;
55 	uint32_t	target;
56 	uint32_t	pad;
57 };
58 
59 #define	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES	32
60 #define	PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES	16
61 
62 struct pvscsi_cmd_desc_setup_rings {
63 	uint32_t	req_ring_num_pages;
64 	uint32_t	cmp_ring_num_pages;
65 	uint64_t	rings_state_ppn;
66 	uint64_t	req_ring_ppns[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
67 	uint64_t	cmp_ring_ppns[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
68 };
69 
70 struct pvscsi_cmd_desc_setup_msg_ring {
71 	uint32_t	num_pages;
72 	uint32_t	pad_;
73 	uint64_t	ring_ppns[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES];
74 };
75 
76 struct pvscsi_rings_state {
77 	uint32_t	req_prod_idx;
78 	uint32_t	req_cons_idx;
79 	uint32_t	req_num_entries_log2;
80 	uint32_t	cmp_prod_idx;
81 	uint32_t	cmp_cons_idx;
82 	uint32_t	cmp_num_entries_log2;
83 	uint32_t	req_call_threshold;
84 	uint8_t		_pad[100];
85 	uint32_t	msg_prod_idx;
86 	uint32_t	msg_cons_idx;
87 	uint32_t	msg_num_entries_log2;
88 };
89 
90 #define	PVSCSI_FLAG_CMD_WITH_SG_LIST	(1 << 0)
91 #define	PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB	(1 << 1)
92 #define	PVSCSI_FLAG_CMD_DIR_NONE	(1 << 2)
93 #define	PVSCSI_FLAG_CMD_DIR_TOHOST	(1 << 3)
94 #define	PVSCSI_FLAG_CMD_DIR_TODEVICE	(1 << 4)
95 
96 #define	PVSCSI_FLAG_RESERVED_MASK	(~MASK(5))
97 
98 #define	PVSCSI_INTR_CMPL_0	(1 << 0)
99 #define	PVSCSI_INTR_CMPL_1	(1 << 1)
100 #define	PVSCSI_INTR_CMPL_MASK	MASK(2)
101 
102 #define	PVSCSI_INTR_MSG_0	(1 << 2)
103 #define	PVSCSI_INTR_MSG_1	(1 << 3)
104 #define	PVSCSI_INTR_MSG_MASK	(MASK(2) << 2)
105 
106 #define	PVSCSI_INTR_ALL_SUPPORTED	MASK(4)
107 
108 struct pvscsi_ring_req_desc {
109 	uint64_t	context;
110 	uint64_t	data_addr;
111 	uint64_t	data_len;
112 	uint64_t	sense_addr;
113 	uint32_t	sense_len;
114 	uint32_t	flags;
115 	uint8_t		cdb[16];
116 	uint8_t		cdb_len;
117 	uint8_t		lun[8];
118 	uint8_t		tag;
119 	uint8_t		bus;
120 	uint8_t		target;
121 	uint16_t	vcpu_hint;
122 	uint8_t		unused[58];
123 };
124 
125 struct pvscsi_ring_cmp_desc {
126 	uint64_t	context;
127 	uint64_t	data_len;
128 	uint32_t	sense_len;
129 	uint16_t	host_status;
130 	uint16_t	scsi_status;
131 	uint32_t	_pad[2];
132 };
133 
134 #define	PVSCSI_MAX_SG_ENTRIES_PER_SEGMENT	128
135 #define	PVSCSI_MAX_NUM_SG_SEGMENTS		128
136 #define	PVSCSI_SGE_FLAG_CHAIN_ELEMENT		(1 << 0)
137 
138 struct pvscsi_sg_element {
139 	uint64_t	addr;
140 	uint32_t	length;
141 	uint32_t	flags;
142 };
143 
144 enum pvscsi_msg_type {
145 	PVSCSI_MSG_DEV_ADDED	= 0,
146 	PVSCSI_MSG_DEV_REMOVED	= 1,
147 	PVSCSI_MSG_LAST	= 2,
148 };
149 
150 struct pvscsi_ring_msg_desc {
151 	uint32_t	type;
152 	uint32_t	args[31];
153 };
154 
155 struct pvscsi_ring_msg_dev_status_changed {
156 	uint32_t	type;
157 	uint32_t	bus;
158 	uint32_t	target;
159 	uint8_t		lun[8];
160 	uint32_t	pad[27];
161 };
162 
163 struct pvscsi_cmd_desc_setup_req_call {
164 	uint32_t	enable;
165 };
166 
167 #define	PVSCSI_MAX_NUM_PAGES_REQ_RING	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
168 #define	PVSCSI_MAX_NUM_PAGES_CMP_RING	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
169 #define	PVSCSI_MAX_NUM_PAGES_MSG_RING	PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES
170 
171 #define	PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \
172 	(PAGE_SIZE / sizeof(struct pvscsi_ring_req_desc))
173 #define	PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE \
174 	(PAGE_SIZE / sizeof(struct pvscs_ring_cmp_desc))
175 #define	PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE \
176 	(PAGE_SIZE / sizeof(struct pvscsi_ring_msg_desc))
177 
178 #define	PVSCSI_MAX_REQ_QUEUE_DEPTH \
179 	(PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE)
180 #define	PVSCSI_MAX_CMP_QUEUE_DEPTH \
181 	(PVSCSI_MAX_NUM_PAGES_CMP_RING * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE)
182 #define	PVSCSI_MAX_QUEUE_DEPTH \
183 	MAX(PVSCSI_MAX_REQ_QUEUE_DEPTH, PVSCSI_MAX_CMP_QUEUE_DEPTH)
184 
185 enum pvscsi_host_status {
186 	BTSTAT_SUCCESS		= 0x00,
187 	BTSTAT_LINKED_COMMAND_COMPLETED			= 0x0a,
188 	BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG	= 0x0b,
189 	BTSTAT_DATA_UNDERRUN	= 0x0c,
190 	BTSTAT_SELTIMEO		= 0x11,
191 	BTSTAT_DATARUN		= 0x12,
192 	BTSTAT_BUSFREE		= 0x13,
193 	BTSTAT_INVPHASE		= 0x14,
194 	BTSTAT_INVCODE		= 0x15,
195 	BTSTAT_INVOPCODE	= 0x16,
196 	BTSTAT_LUNMISMATCH	= 0x17,
197 	BTSTAT_INVPARAM		= 0x1a,
198 	BTSTAT_SENSFAILED	= 0x1b,
199 	BTSTAT_TAGREJECT	= 0x1c,
200 	BTSTAT_BADMSG		= 0x1d,
201 	BTSTAT_HAHARDWARE	= 0x20,
202 	BTSTAT_NORESPONSE	= 0x21,
203 	BTSTAT_SENTRST		= 0x22,
204 	BTSTAT_RECVRST		= 0x23,
205 	BTSTAT_DISCONNECT	= 0x24,
206 	BTSTAT_BUSRESET		= 0x25,
207 	BTSTAT_ABORTQUEUE	= 0x26,
208 	BTSTAT_HASOFTWARE	= 0x27,
209 	BTSTAT_HATIMEOUT	= 0x30,
210 	BTSTAT_SCSIPARITY	= 0x34,
211 };
212 
213 #endif /* !_PVSCSI_H_ */
214