1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#ifndef VMW_PVSCSI_H
25#define VMW_PVSCSI_H
26
27#define VMW_PAGE_SIZE (4096)
28#define VMW_PAGE_SHIFT (12)
29
30#define MASK(n) ((1 << (n)) - 1)
31
32
33
34
35enum HostBusAdapterStatus {
36 BTSTAT_SUCCESS = 0x00,
37 BTSTAT_LINKED_COMMAND_COMPLETED = 0x0a,
38 BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b,
39 BTSTAT_DATA_UNDERRUN = 0x0c,
40 BTSTAT_SELTIMEO = 0x11,
41 BTSTAT_DATARUN = 0x12,
42 BTSTAT_BUSFREE = 0x13,
43 BTSTAT_INVPHASE = 0x14,
44
45 BTSTAT_LUNMISMATCH = 0x17,
46
47 BTSTAT_SENSFAILED = 0x1b,
48 BTSTAT_TAGREJECT = 0x1c,
49
50 BTSTAT_BADMSG = 0x1d,
51
52 BTSTAT_HAHARDWARE = 0x20,
53 BTSTAT_NORESPONSE = 0x21,
54
55 BTSTAT_SENTRST = 0x22,
56 BTSTAT_RECVRST = 0x23,
57 BTSTAT_DISCONNECT = 0x24,
58
59 BTSTAT_BUSRESET = 0x25,
60 BTSTAT_ABORTQUEUE = 0x26,
61 BTSTAT_HASOFTWARE = 0x27,
62 BTSTAT_HATIMEOUT = 0x30,
63 BTSTAT_SCSIPARITY = 0x34,
64};
65
66
67
68
69
70
71
72enum PVSCSIRegOffset {
73 PVSCSI_REG_OFFSET_COMMAND = 0x0,
74 PVSCSI_REG_OFFSET_COMMAND_DATA = 0x4,
75 PVSCSI_REG_OFFSET_COMMAND_STATUS = 0x8,
76 PVSCSI_REG_OFFSET_LAST_STS_0 = 0x100,
77 PVSCSI_REG_OFFSET_LAST_STS_1 = 0x104,
78 PVSCSI_REG_OFFSET_LAST_STS_2 = 0x108,
79 PVSCSI_REG_OFFSET_LAST_STS_3 = 0x10c,
80 PVSCSI_REG_OFFSET_INTR_STATUS = 0x100c,
81 PVSCSI_REG_OFFSET_INTR_MASK = 0x2010,
82 PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014,
83 PVSCSI_REG_OFFSET_DEBUG = 0x3018,
84 PVSCSI_REG_OFFSET_KICK_RW_IO = 0x4018,
85};
86
87
88
89
90
91enum PVSCSICommands {
92 PVSCSI_CMD_FIRST = 0,
93
94 PVSCSI_CMD_ADAPTER_RESET = 1,
95 PVSCSI_CMD_ISSUE_SCSI = 2,
96 PVSCSI_CMD_SETUP_RINGS = 3,
97 PVSCSI_CMD_RESET_BUS = 4,
98 PVSCSI_CMD_RESET_DEVICE = 5,
99 PVSCSI_CMD_ABORT_CMD = 6,
100 PVSCSI_CMD_CONFIG = 7,
101 PVSCSI_CMD_SETUP_MSG_RING = 8,
102 PVSCSI_CMD_DEVICE_UNPLUG = 9,
103
104 PVSCSI_CMD_LAST = 10
105};
106
107#define PVSCSI_COMMAND_PROCESSING_SUCCEEDED (0)
108#define PVSCSI_COMMAND_PROCESSING_FAILED (-1)
109#define PVSCSI_COMMAND_NOT_ENOUGH_DATA (-2)
110
111
112
113
114
115struct PVSCSICmdDescResetDevice {
116 uint32_t target;
117 uint8_t lun[8];
118} QEMU_PACKED;
119
120typedef struct PVSCSICmdDescResetDevice PVSCSICmdDescResetDevice;
121
122
123
124
125
126
127
128
129struct PVSCSICmdDescAbortCmd {
130 uint64_t context;
131 uint32_t target;
132 uint32_t pad;
133} QEMU_PACKED;
134
135typedef struct PVSCSICmdDescAbortCmd PVSCSICmdDescAbortCmd;
136
137
138
139
140
141
142
143
144
145
146
147#define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 32
148struct PVSCSICmdDescSetupRings {
149 uint32_t reqRingNumPages;
150 uint32_t cmpRingNumPages;
151 uint64_t ringsStatePPN;
152 uint64_t reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
153 uint64_t cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES];
154} QEMU_PACKED;
155
156typedef struct PVSCSICmdDescSetupRings PVSCSICmdDescSetupRings;
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177#define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 16
178
179struct PVSCSICmdDescSetupMsgRing {
180 uint32_t numPages;
181 uint32_t pad;
182 uint64_t ringPPNs[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES];
183} QEMU_PACKED;
184
185typedef struct PVSCSICmdDescSetupMsgRing PVSCSICmdDescSetupMsgRing;
186
187enum PVSCSIMsgType {
188 PVSCSI_MSG_DEV_ADDED = 0,
189 PVSCSI_MSG_DEV_REMOVED = 1,
190 PVSCSI_MSG_LAST = 2,
191};
192
193
194
195
196
197
198
199
200
201
202struct PVSCSIRingMsgDesc {
203 uint32_t type;
204 uint32_t args[31];
205} QEMU_PACKED;
206
207typedef struct PVSCSIRingMsgDesc PVSCSIRingMsgDesc;
208
209struct PVSCSIMsgDescDevStatusChanged {
210 uint32_t type;
211 uint32_t bus;
212 uint32_t target;
213 uint8_t lun[8];
214 uint32_t pad[27];
215} QEMU_PACKED;
216
217typedef struct PVSCSIMsgDescDevStatusChanged PVSCSIMsgDescDevStatusChanged;
218
219
220
221
222
223
224
225
226
227
228
229
230
231struct PVSCSIRingsState {
232 uint32_t reqProdIdx;
233 uint32_t reqConsIdx;
234 uint32_t reqNumEntriesLog2;
235
236 uint32_t cmpProdIdx;
237 uint32_t cmpConsIdx;
238 uint32_t cmpNumEntriesLog2;
239
240 uint8_t pad[104];
241
242 uint32_t msgProdIdx;
243 uint32_t msgConsIdx;
244 uint32_t msgNumEntriesLog2;
245} QEMU_PACKED;
246
247typedef struct PVSCSIRingsState PVSCSIRingsState;
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285#define PVSCSI_FLAG_CMD_WITH_SG_LIST (1 << 0)
286#define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB (1 << 1)
287#define PVSCSI_FLAG_CMD_DIR_NONE (1 << 2)
288#define PVSCSI_FLAG_CMD_DIR_TOHOST (1 << 3)
289#define PVSCSI_FLAG_CMD_DIR_TODEVICE (1 << 4)
290
291#define PVSCSI_KNOWN_FLAGS \
292 (PVSCSI_FLAG_CMD_WITH_SG_LIST | \
293 PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB | \
294 PVSCSI_FLAG_CMD_DIR_NONE | \
295 PVSCSI_FLAG_CMD_DIR_TOHOST | \
296 PVSCSI_FLAG_CMD_DIR_TODEVICE)
297
298struct PVSCSIRingReqDesc {
299 uint64_t context;
300 uint64_t dataAddr;
301 uint64_t dataLen;
302 uint64_t senseAddr;
303 uint32_t senseLen;
304 uint32_t flags;
305 uint8_t cdb[16];
306 uint8_t cdbLen;
307 uint8_t lun[8];
308 uint8_t tag;
309 uint8_t bus;
310 uint8_t target;
311 uint8_t vcpuHint;
312 uint8_t unused[59];
313} QEMU_PACKED;
314
315typedef struct PVSCSIRingReqDesc PVSCSIRingReqDesc;
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333struct PVSCSISGElement {
334 uint64_t addr;
335 uint32_t length;
336 uint32_t flags;
337} QEMU_PACKED;
338
339typedef struct PVSCSISGElement PVSCSISGElement;
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355struct PVSCSIRingCmpDesc {
356 uint64_t context;
357 uint64_t dataLen;
358 uint32_t senseLen;
359 uint16_t hostStatus;
360 uint16_t scsiStatus;
361 uint32_t pad[2];
362} QEMU_PACKED;
363
364typedef struct PVSCSIRingCmpDesc PVSCSIRingCmpDesc;
365
366
367
368
369
370#define PVSCSI_INTR_CMPL_0 (1 << 0)
371#define PVSCSI_INTR_CMPL_1 (1 << 1)
372#define PVSCSI_INTR_CMPL_MASK MASK(2)
373
374#define PVSCSI_INTR_MSG_0 (1 << 2)
375#define PVSCSI_INTR_MSG_1 (1 << 3)
376#define PVSCSI_INTR_MSG_MASK (MASK(2) << 2)
377
378#define PVSCSI_INTR_ALL_SUPPORTED MASK(4)
379
380
381
382
383#define PVSCSI_MAX_INTRS 24
384
385
386
387
388#define PVSCSI_VECTOR_COMPLETION 0
389
390
391
392
393
394#define PVSCSI_MAX_NUM_PAGES_REQ_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
395#define PVSCSI_MAX_NUM_PAGES_CMP_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES
396#define PVSCSI_MAX_NUM_PAGES_MSG_RING PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES
397
398#define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \
399 (VMW_PAGE_SIZE / sizeof(struct PVSCSIRingReqDesc))
400
401#define PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE \
402 (VMW_PAGE_SIZE / sizeof(PVSCSIRingCmpDesc))
403
404#define PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE \
405 (VMW_PAGE_SIZE / sizeof(PVSCSIRingMsgDesc))
406
407#define PVSCSI_MAX_REQ_QUEUE_DEPTH \
408 (PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE)
409
410#define PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES 1
411#define PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES 1
412#define PVSCSI_MEM_SPACE_MISC_NUM_PAGES 2
413#define PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES 2
414#define PVSCSI_MEM_SPACE_MSIX_NUM_PAGES 2
415
416enum PVSCSIMemSpace {
417 PVSCSI_MEM_SPACE_COMMAND_PAGE = 0,
418 PVSCSI_MEM_SPACE_INTR_STATUS_PAGE = 1,
419 PVSCSI_MEM_SPACE_MISC_PAGE = 2,
420 PVSCSI_MEM_SPACE_KICK_IO_PAGE = 4,
421 PVSCSI_MEM_SPACE_MSIX_TABLE_PAGE = 6,
422 PVSCSI_MEM_SPACE_MSIX_PBA_PAGE = 7,
423};
424
425#define PVSCSI_MEM_SPACE_NUM_PAGES \
426 (PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES + \
427 PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES + \
428 PVSCSI_MEM_SPACE_MISC_NUM_PAGES + \
429 PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES + \
430 PVSCSI_MEM_SPACE_MSIX_NUM_PAGES)
431
432#define PVSCSI_MEM_SPACE_SIZE (PVSCSI_MEM_SPACE_NUM_PAGES * VMW_PAGE_SIZE)
433
434#endif
435