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