xref: /illumos-gate/usr/src/uts/common/io/scsi/adapters/pvscsi/pvscsi.h (revision dd72704bd9e794056c558153663c739e2012d721)
1 /*
2  * Copyright (C) 2008-2014, VMware, Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * 1. Redistributions of source code must retain the above copyright notice,
7  *    this list of conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright notice,
9  *    this list of conditions and the following disclaimer in the documentation
10  *    and/or other materials provided with the distribution.
11  *
12  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
13  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
16  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22  */
23 
24 #ifndef	_PVSCSI_H_
25 #define	_PVSCSI_H_
26 
27 #include <sys/types.h>
28 
29 #define	PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128
30 
31 #define	MASK(n) ((1 << (n)) - 1)	/* make an n-bit mask */
32 
33 #define	PCI_DEVICE_ID_VMWARE_PVSCSI	0x07C0
34 
35 /*
36  * host adapter status/error codes
37  */
38 enum HostBusAdapterStatus {
39 	BTSTAT_SUCCESS		= 0x00,	/* CCB complete normally with */
40 					/* no errors */
41 	BTSTAT_LINKED_COMMAND_COMPLETED = 0x0a,
42 	BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b,
43 	BTSTAT_DATA_UNDERRUN	= 0x0c,
44 	BTSTAT_SELTIMEO		= 0x11,	/* SCSI selection timeout */
45 	BTSTAT_DATARUN		= 0x12,	/* data overrun/underrun */
46 	BTSTAT_BUSFREE		= 0x13,	/* unexpected bus free */
47 	BTSTAT_INVPHASE		= 0x14,	/* invalid bus phase or sequence */
48 					/* requested by target */
49 	BTSTAT_LUNMISMATCH	= 0x17,	/* linked CCB has different LUN from */
50 					/* first CCB */
51 	BTSTAT_INVPARAM		= 0x1a,	/* invalid parameter in CCB */
52 					/* or segment list */
53 	BTSTAT_SENSFAILED	= 0x1b,	/* auto request sense failed */
54 	BTSTAT_TAGREJECT	= 0x1c,	/* SCSI II tagged queueing message */
55 					/* rejected by target */
56 	BTSTAT_BADMSG		= 0x1d,	/* unsupported message received by */
57 					/* the host adapter */
58 	BTSTAT_HAHARDWARE	= 0x20,	/* host adapter hardware failed */
59 	BTSTAT_NORESPONSE	= 0x21,	/* target did not respond to */
60 					/* SCSI ATN, sent a SCSI RST */
61 	BTSTAT_SENTRST		= 0x22,	/* host adapter asserted a SCSI RST */
62 	BTSTAT_RECVRST		= 0x23,	/* other SCSI devices asserted */
63 					/* a SCSI RST */
64 	BTSTAT_DISCONNECT	= 0x24,	/* target device reconnected */
65 					/* improperly (w/o tag) */
66 	BTSTAT_BUSRESET		= 0x25,	/* host adapter issued */
67 					/* BUS device reset */
68 	BTSTAT_ABORTQUEUE	= 0x26,	/* abort queue generated */
69 	BTSTAT_HASOFTWARE	= 0x27,	/* host adapter software error */
70 	BTSTAT_HATIMEOUT	= 0x30,	/* host adapter hardware */
71 					/* timeout error */
72 	BTSTAT_SCSIPARITY	= 0x34,	/* SCSI parity error detected */
73 };
74 
75 /*
76  * SCSI device status values.
77  */
78 enum ScsiDeviceStatus {
79 	SDSTAT_GOOD	= 0x00, /* No errors. */
80 	SDSTAT_CHECK	= 0x02, /* Check condition. */
81 };
82 
83 /*
84  * Register offsets.
85  *
86  * These registers are accessible both via i/o space and mm i/o.
87  */
88 
89 enum PVSCSIRegOffset {
90 	PVSCSI_REG_OFFSET_COMMAND	= 0x0,
91 	PVSCSI_REG_OFFSET_COMMAND_DATA	= 0x4,
92 	PVSCSI_REG_OFFSET_COMMAND_STATUS = 0x8,
93 	PVSCSI_REG_OFFSET_LAST_STS_0	= 0x100,
94 	PVSCSI_REG_OFFSET_LAST_STS_1	= 0x104,
95 	PVSCSI_REG_OFFSET_LAST_STS_2	= 0x108,
96 	PVSCSI_REG_OFFSET_LAST_STS_3	= 0x10c,
97 	PVSCSI_REG_OFFSET_INTR_STATUS	= 0x100c,
98 	PVSCSI_REG_OFFSET_INTR_MASK	= 0x2010,
99 	PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014,
100 	PVSCSI_REG_OFFSET_DEBUG		= 0x3018,
101 	PVSCSI_REG_OFFSET_KICK_RW_IO	= 0x4018,
102 };
103 
104 /*
105  * Virtual h/w commands.
106  */
107 
108 enum PVSCSICommands {
109 	PVSCSI_CMD_FIRST		= 0, /* has to be first */
110 
111 	PVSCSI_CMD_ADAPTER_RESET	= 1,
112 	PVSCSI_CMD_ISSUE_SCSI		= 2,
113 	PVSCSI_CMD_SETUP_RINGS		= 3,
114 	PVSCSI_CMD_RESET_BUS		= 4,
115 	PVSCSI_CMD_RESET_DEVICE		= 5,
116 	PVSCSI_CMD_ABORT_CMD		= 6,
117 	PVSCSI_CMD_CONFIG		= 7,
118 	PVSCSI_CMD_SETUP_MSG_RING	= 8,
119 	PVSCSI_CMD_DEVICE_UNPLUG	= 9,
120 	PVSCSI_CMD_SETUP_REQCALLTHRESHOLD = 10,
121 
122 	PVSCSI_CMD_LAST			= 11  /* has to be last */
123 };
124 
125 /*
126  * Command descriptor for PVSCSI_CMD_RESET_DEVICE --
127  */
128 #pragma pack(1)
129 struct PVSCSICmdDescResetDevice {
130 	uint32_t	target;
131 	uint8_t		lun[8];
132 };
133 #pragma pack()
134 
135 /*
136  * Command descriptor for PVSCSI_CMD_CONFIG --
137  */
138 #pragma pack(1)
139 struct PVSCSICmdDescConfigCmd {
140 	uint64_t	cmpAddr;
141 	uint64_t	configPageAddress;
142 	uint32_t	configPageNum;
143 	uint32_t	_pad;
144 };
145 #pragma pack()
146 
147 /*
148  * Command descriptor for PVSCSI_CMD_SETUP_REQCALLTHRESHOLD --
149  */
150 #pragma pack(1)
151 struct PVSCSICmdDescSetupReqCall {
152 	uint32_t	enable;
153 };
154 #pragma pack()
155 
156 enum PVSCSIConfigPageType {
157 	PVSCSI_CONFIG_PAGE_CONTROLLER	= 0x1958,
158 	PVSCSI_CONFIG_PAGE_PHY		= 0x1959,
159 	PVSCSI_CONFIG_PAGE_DEVICE	= 0x195a,
160 };
161 
162 enum PVSCSIConfigPageAddressType {
163 	PVSCSI_CONFIG_CONTROLLER_ADDRESS = 0x2120,
164 	PVSCSI_CONFIG_BUSTARGET_ADDRESS	= 0x2121,
165 	PVSCSI_CONFIG_PHY_ADDRESS	= 0x2122,
166 };
167 
168 /*
169  * Command descriptor for PVSCSI_CMD_ABORT_CMD --
170  *
171  * - currently does not support specifying the LUN.
172  * - _pad should be 0.
173  */
174 
175 struct PVSCSICmdDescAbortCmd {
176 	uint64_t	context;
177 	uint32_t	target;
178 	uint32_t	_pad;
179 } __packed;
180 
181 /*
182  * Command descriptor for PVSCSI_CMD_SETUP_RINGS --
183  *
184  * Notes:
185  * - reqRingNumPages and cmpRingNumPages need to be power of two.
186  * - reqRingNumPages and cmpRingNumPages need to be different from 0,
187  * - reqRingNumPages and cmpRingNumPages need to be inferior to
188  *   PVSCSI_SETUP_RINGS_MAX_NUM_PAGES.
189  */
190 #define	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 32
191 
192 #pragma pack(1)
193 struct PVSCSICmdDescSetupRings {
194 	uint32_t	reqRingNumPages;
195 	uint32_t	cmpRingNumPages;
196 	uint64_t	ringsStatePPN;
197 	uint64_t	reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
198 	uint64_t	cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
199 };
200 #pragma pack()
201 
202 /*
203  * Command descriptor for PVSCSI_CMD_SETUP_MSG_RING --
204  *
205  * Notes:
206  * - this command was not supported in the initial revision of the h/w
207  *   interface. Before using it, you need to check that it is supported by
208  *   writing PVSCSI_CMD_SETUP_MSG_RING to the 'command' register, then
209  *   immediately after read the 'command status' register:
210  *       * a value of -1 means that the cmd is NOT supported,
211  *       * a value != -1 means that the cmd IS supported.
212  *   If it's supported the 'command status' register should return:
213  *      sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(uint32_t).
214  * - this command should be issued _after_ the usual SETUP_RINGS so that the
215  *   RingsState page is already setup. If not, the command is a nop.
216  * - numPages needs to be a power of two,
217  * - numPages needs to be different from 0,
218  * - _pad should be zero.
219  */
220 #define	PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 16
221 
222 #pragma pack(1)
223 struct PVSCSICmdDescSetupMsgRing {
224 	uint32_t	numPages;
225 	uint32_t	_pad;
226 	uint64_t	ringPPNs[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES];
227 };
228 #pragma pack()
229 
230 enum PVSCSIMsgType {
231 	PVSCSI_MSG_DEV_ADDED	= 0,
232 	PVSCSI_MSG_DEV_REMOVED	= 1,
233 	PVSCSI_MSG_LAST		= 2,
234 };
235 
236 /*
237  * Msg descriptor.
238  *
239  * sizeof(struct PVSCSIRingMsgDesc) == 128.
240  *
241  * - type is of type enum PVSCSIMsgType.
242  * - the content of args depend on the type of event being delivered.
243  */
244 #pragma pack(1)
245 struct PVSCSIRingMsgDesc {
246 	uint32_t	type;
247 	uint32_t	args[31];
248 };
249 #pragma pack()
250 
251 #pragma pack(1)
252 struct PVSCSIMsgDescDevStatusChanged {
253 	uint32_t	type;  /* PVSCSI_MSG_DEV _ADDED / _REMOVED */
254 	uint32_t	bus;
255 	uint32_t	target;
256 	uint8_t		lun[8];
257 	uint32_t	pad[27];
258 };
259 #pragma pack()
260 
261 /*
262  * Rings state.
263  *
264  * - the fields:
265  *    . msgProdIdx,
266  *    . msgConsIdx,
267  *    . msgNumEntriesLog2,
268  *   .. are only used once the SETUP_MSG_RING cmd has been issued.
269  * - '_pad' helps to ensure that the msg related fields are on their own
270  *   cache-line.
271  */
272 #pragma pack(1)
273 struct PVSCSIRingsState {
274 	uint32_t	reqProdIdx;
275 	uint32_t	reqConsIdx;
276 	uint32_t	reqNumEntriesLog2;
277 
278 	uint32_t	cmpProdIdx;
279 	uint32_t	cmpConsIdx;
280 	uint32_t	cmpNumEntriesLog2;
281 
282 	uint32_t	reqCallThreshold;
283 
284 	uint8_t		_pad[100];
285 
286 	uint32_t	msgProdIdx;
287 	uint32_t	msgConsIdx;
288 	uint32_t	msgNumEntriesLog2;
289 };
290 #pragma pack()
291 
292 /*
293  * Request descriptor.
294  *
295  * sizeof(RingReqDesc) = 128
296  *
297  * - context: is a unique identifier of a command. It could normally be any
298  *   64bit value, however we currently store it in the serialNumber variable
299  *   of struct SCSI_Command, so we have the following restrictions due to the
300  *   way this field is handled in the vmkernel storage stack:
301  *    * this value can't be 0,
302  *    * the upper 32bit need to be 0 since serialNumber is as a uint32_t.
303  *   Currently tracked as PR 292060.
304  * - dataLen: contains the total number of bytes that need to be transferred.
305  * - dataAddr:
306  *   * if PVSCSI_FLAG_CMD_WITH_SG_LIST is set: dataAddr is the PA of the first
307  *     s/g table segment, each s/g segment is entirely contained on a single
308  *     page of physical memory,
309  *   * if PVSCSI_FLAG_CMD_WITH_SG_LIST is NOT set, then dataAddr is the PA of
310  *     the buffer used for the DMA transfer,
311  * - flags:
312  *   * PVSCSI_FLAG_CMD_WITH_SG_LIST: see dataAddr above,
313  *   * PVSCSI_FLAG_CMD_DIR_NONE: no DMA involved,
314  *   * PVSCSI_FLAG_CMD_DIR_TOHOST: transfer from device to main memory,
315  *   * PVSCSI_FLAG_CMD_DIR_TODEVICE: transfer from main memory to device,
316  *   * PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB: reserved to handle CDBs larger than
317  *     16bytes. To be specified.
318  * - vcpuHint: vcpuId of the processor that will be most likely waiting for the
319  *   completion of the i/o. For guest OSes that use lowest priority message
320  *   delivery mode (such as windows), we use this "hint" to deliver the
321  *   completion action to the proper vcpu. For now, we can use the vcpuId of
322  *   the processor that initiated the i/o as a likely candidate for the vcpu
323  *   that will be waiting for the completion..
324  * - bus should be 0: we currently only support bus 0 for now.
325  * - unused should be zero'd.
326  */
327 #define	PVSCSI_FLAG_CMD_WITH_SG_LIST	(1 << 0)
328 #define	PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB	(1 << 1)
329 #define	PVSCSI_FLAG_CMD_DIR_NONE	(1 << 2)
330 #define	PVSCSI_FLAG_CMD_DIR_TOHOST	(1 << 3)
331 #define	PVSCSI_FLAG_CMD_DIR_TODEVICE	(1 << 4)
332 
333 #pragma pack(1)
334 struct PVSCSIRingReqDesc {
335 	uint64_t	context;
336 	uint64_t	dataAddr;
337 	uint64_t	dataLen;
338 	uint64_t	senseAddr;
339 	uint32_t	senseLen;
340 	uint32_t	flags;
341 	uint8_t		cdb[16];
342 	uint8_t		cdbLen;
343 	uint8_t		lun[8];
344 	uint8_t		tag;
345 	uint8_t		bus;
346 	uint8_t		target;
347 	uint8_t		vcpuHint;
348 	uint8_t		unused[59];
349 };
350 #pragma pack()
351 
352 /*
353  * Scatter-gather list management.
354  *
355  * As described above, when PVSCSI_FLAG_CMD_WITH_SG_LIST is set in the
356  * RingReqDesc.flags, then RingReqDesc.dataAddr is the PA of the first s/g
357  * table segment.
358  *
359  * - each segment of the s/g table contain a succession of struct
360  *   PVSCSISGElement.
361  * - each segment is entirely contained on a single physical page of memory.
362  * - a "chain" s/g element has the flag PVSCSI_SGE_FLAG_CHAIN_ELEMENT set in
363  *   PVSCSISGElement.flags and in this case:
364  *     * addr is the PA of the next s/g segment,
365  *     * length is undefined, assumed to be 0.
366  */
367 #pragma pack(1)
368 struct PVSCSISGElement {
369 	uint64_t	addr;
370 	uint32_t	length;
371 	uint32_t	flags;
372 };
373 #pragma pack()
374 
375 /*
376  * Completion descriptor.
377  *
378  * sizeof(RingCmpDesc) = 32
379  *
380  * - context: identifier of the command. The same thing that was specified
381  *   under "context" as part of struct RingReqDesc at initiation time,
382  * - dataLen: number of bytes transferred for the actual i/o operation,
383  * - senseLen: number of bytes written into the sense buffer,
384  * - hostStatus: adapter status,
385  * - scsiStatus: device status,
386  * - _pad should be zero.
387  */
388 #pragma pack(1)
389 struct PVSCSIRingCmpDesc {
390 	uint64_t	context;
391 	uint64_t	dataLen;
392 	uint32_t	senseLen;
393 	uint16_t	hostStatus;
394 	uint16_t	scsiStatus;
395 	uint32_t	_pad[2];
396 };
397 #pragma pack()
398 
399 #pragma pack(1)
400 struct PVSCSIConfigPageHeader {
401 	uint32_t	pageNum;
402 	uint16_t	numDwords;
403 	uint16_t	hostStatus;
404 	uint16_t	scsiStatus;
405 	uint16_t	reserved[3];
406 };
407 #pragma pack()
408 
409 #pragma pack(1)
410 struct PVSCSIConfigPageController {
411 	struct PVSCSIConfigPageHeader header;
412 	uint64_t	nodeWWN; /* Device name as defined in the SAS spec. */
413 	uint16_t	manufacturer[64];
414 	uint16_t	serialNumber[64];
415 	uint16_t	opromVersion[32];
416 	uint16_t	hwVersion[32];
417 	uint16_t	firmwareVersion[32];
418 	uint32_t	numPhys;
419 	uint8_t		useConsecutivePhyWWNs;
420 	uint8_t		reserved[3];
421 };
422 #pragma pack()
423 
424 /*
425  * Interrupt status / IRQ bits.
426  */
427 
428 #define	PVSCSI_INTR_CMPL_0	(1 << 0)
429 #define	PVSCSI_INTR_CMPL_1	(1 << 1)
430 #define	PVSCSI_INTR_CMPL_MASK	MASK(2)
431 
432 #define	PVSCSI_INTR_MSG_0	(1 << 2)
433 #define	PVSCSI_INTR_MSG_1	(1 << 3)
434 #define	PVSCSI_INTR_MSG_MASK	(MASK(2) << 2)
435 
436 #define	PVSCSI_INTR_ALL_SUPPORTED MASK(4)
437 
438 /*
439  * Number of MSI-X vectors supported.
440  */
441 #define	PVSCSI_MAX_INTRS	24
442 
443 /*
444  * Enumeration of supported MSI-X vectors
445  */
446 #define	PVSCSI_VECTOR_COMPLETION 0
447 
448 /*
449  * Misc constants for the rings.
450  */
451 
452 #define	PVSCSI_MAX_NUM_PAGES_REQ_RING	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
453 #define	PVSCSI_MAX_NUM_PAGES_CMP_RING	PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
454 #define	PVSCSI_MAX_NUM_PAGES_MSG_RING	PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES
455 
456 #define	PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \
457 	(PAGE_SIZE / sizeof (struct PVSCSIRingReqDesc))
458 
459 #define	PVSCSI_MAX_REQ_QUEUE_DEPTH \
460 	(PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE)
461 
462 #define	PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES	1
463 #define	PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES	1
464 #define	PVSCSI_MEM_SPACE_MISC_NUM_PAGES		2
465 #define	PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES	2
466 #define	PVSCSI_MEM_SPACE_MSIX_NUM_PAGES		2
467 
468 enum PVSCSIMemSpace {
469 	PVSCSI_MEM_SPACE_COMMAND_PAGE		= 0,
470 	PVSCSI_MEM_SPACE_INTR_STATUS_PAGE	= 1,
471 	PVSCSI_MEM_SPACE_MISC_PAGE		= 2,
472 	PVSCSI_MEM_SPACE_KICK_IO_PAGE		= 4,
473 	PVSCSI_MEM_SPACE_MSIX_TABLE_PAGE	= 6,
474 	PVSCSI_MEM_SPACE_MSIX_PBA_PAGE		= 7,
475 };
476 
477 #define	PVSCSI_MEM_SPACE_NUM_PAGES		\
478 	(PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES +	\
479 	PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES +\
480 	PVSCSI_MEM_SPACE_MISC_NUM_PAGES +	\
481 	PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES +	\
482 	PVSCSI_MEM_SPACE_MSIX_NUM_PAGES)
483 
484 #define	PVSCSI_MEM_SPACE_SIZE (PVSCSI_MEM_SPACE_NUM_PAGES * PAGE_SIZE)
485 
486 #endif /* _PVSCSI_H_ */
487