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