diff options
author | Alok Kataria <akataria@vmware.com> | 2009-10-13 17:51:05 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:00:49 -0500 |
commit | 851b164231d1117673aa44c00c7622e48b7dfcf4 (patch) | |
tree | dd63a44d5865e788b4864b29d7a173e8aa2471ef /drivers/scsi/vmw_pvscsi.h | |
parent | 96e6586556dfa80112f42895be93c561582d9930 (diff) |
[SCSI] vmw_pvscsi: SCSI driver for VMware's virtual HBA.
This is a driver for VMware's paravirtualized SCSI device,
which should improve disk performance for guests running
under control of VMware hypervisors that support such devices.
Signed-off-by: Alok N Kataria <akataria@vmware.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/vmw_pvscsi.h')
-rw-r--r-- | drivers/scsi/vmw_pvscsi.h | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h new file mode 100644 index 000000000000..62e36e75715e --- /dev/null +++ b/drivers/scsi/vmw_pvscsi.h | |||
@@ -0,0 +1,397 @@ | |||
1 | /* | ||
2 | * VMware PVSCSI header file | ||
3 | * | ||
4 | * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; version 2 of the License and no later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
13 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
14 | * details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | * | ||
20 | * Maintained by: Alok N Kataria <akataria@vmware.com> | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef _VMW_PVSCSI_H_ | ||
25 | #define _VMW_PVSCSI_H_ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | |||
29 | #define PVSCSI_DRIVER_VERSION_STRING "1.0.1.0-k" | ||
30 | |||
31 | #define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128 | ||
32 | |||
33 | #define MASK(n) ((1 << (n)) - 1) /* make an n-bit mask */ | ||
34 | |||
35 | #define PCI_VENDOR_ID_VMWARE 0x15AD | ||
36 | #define PCI_DEVICE_ID_VMWARE_PVSCSI 0x07C0 | ||
37 | |||
38 | /* | ||
39 | * host adapter status/error codes | ||
40 | */ | ||
41 | enum HostBusAdapterStatus { | ||
42 | BTSTAT_SUCCESS = 0x00, /* CCB complete normally with no errors */ | ||
43 | BTSTAT_LINKED_COMMAND_COMPLETED = 0x0a, | ||
44 | BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b, | ||
45 | BTSTAT_DATA_UNDERRUN = 0x0c, | ||
46 | BTSTAT_SELTIMEO = 0x11, /* SCSI selection timeout */ | ||
47 | BTSTAT_DATARUN = 0x12, /* data overrun/underrun */ | ||
48 | BTSTAT_BUSFREE = 0x13, /* unexpected bus free */ | ||
49 | BTSTAT_INVPHASE = 0x14, /* invalid bus phase or sequence requested by target */ | ||
50 | BTSTAT_LUNMISMATCH = 0x17, /* linked CCB has different LUN from first CCB */ | ||
51 | BTSTAT_SENSFAILED = 0x1b, /* auto request sense failed */ | ||
52 | BTSTAT_TAGREJECT = 0x1c, /* SCSI II tagged queueing message rejected by target */ | ||
53 | BTSTAT_BADMSG = 0x1d, /* unsupported message received by the host adapter */ | ||
54 | BTSTAT_HAHARDWARE = 0x20, /* host adapter hardware failed */ | ||
55 | BTSTAT_NORESPONSE = 0x21, /* target did not respond to SCSI ATN, sent a SCSI RST */ | ||
56 | BTSTAT_SENTRST = 0x22, /* host adapter asserted a SCSI RST */ | ||
57 | BTSTAT_RECVRST = 0x23, /* other SCSI devices asserted a SCSI RST */ | ||
58 | BTSTAT_DISCONNECT = 0x24, /* target device reconnected improperly (w/o tag) */ | ||
59 | BTSTAT_BUSRESET = 0x25, /* host adapter issued BUS device reset */ | ||
60 | BTSTAT_ABORTQUEUE = 0x26, /* abort queue generated */ | ||
61 | BTSTAT_HASOFTWARE = 0x27, /* host adapter software error */ | ||
62 | BTSTAT_HATIMEOUT = 0x30, /* host adapter hardware timeout error */ | ||
63 | BTSTAT_SCSIPARITY = 0x34, /* SCSI parity error detected */ | ||
64 | }; | ||
65 | |||
66 | /* | ||
67 | * Register offsets. | ||
68 | * | ||
69 | * These registers are accessible both via i/o space and mm i/o. | ||
70 | */ | ||
71 | |||
72 | enum 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 | * Virtual h/w commands. | ||
89 | */ | ||
90 | |||
91 | enum PVSCSICommands { | ||
92 | PVSCSI_CMD_FIRST = 0, /* has to be first */ | ||
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 /* has to be last */ | ||
105 | }; | ||
106 | |||
107 | /* | ||
108 | * Command descriptor for PVSCSI_CMD_RESET_DEVICE -- | ||
109 | */ | ||
110 | |||
111 | struct PVSCSICmdDescResetDevice { | ||
112 | u32 target; | ||
113 | u8 lun[8]; | ||
114 | } __packed; | ||
115 | |||
116 | /* | ||
117 | * Command descriptor for PVSCSI_CMD_ABORT_CMD -- | ||
118 | * | ||
119 | * - currently does not support specifying the LUN. | ||
120 | * - _pad should be 0. | ||
121 | */ | ||
122 | |||
123 | struct PVSCSICmdDescAbortCmd { | ||
124 | u64 context; | ||
125 | u32 target; | ||
126 | u32 _pad; | ||
127 | } __packed; | ||
128 | |||
129 | /* | ||
130 | * Command descriptor for PVSCSI_CMD_SETUP_RINGS -- | ||
131 | * | ||
132 | * Notes: | ||
133 | * - reqRingNumPages and cmpRingNumPages need to be power of two. | ||
134 | * - reqRingNumPages and cmpRingNumPages need to be different from 0, | ||
135 | * - reqRingNumPages and cmpRingNumPages need to be inferior to | ||
136 | * PVSCSI_SETUP_RINGS_MAX_NUM_PAGES. | ||
137 | */ | ||
138 | |||
139 | #define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 32 | ||
140 | struct PVSCSICmdDescSetupRings { | ||
141 | u32 reqRingNumPages; | ||
142 | u32 cmpRingNumPages; | ||
143 | u64 ringsStatePPN; | ||
144 | u64 reqRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; | ||
145 | u64 cmpRingPPNs[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; | ||
146 | } __packed; | ||
147 | |||
148 | /* | ||
149 | * Command descriptor for PVSCSI_CMD_SETUP_MSG_RING -- | ||
150 | * | ||
151 | * Notes: | ||
152 | * - this command was not supported in the initial revision of the h/w | ||
153 | * interface. Before using it, you need to check that it is supported by | ||
154 | * writing PVSCSI_CMD_SETUP_MSG_RING to the 'command' register, then | ||
155 | * immediately after read the 'command status' register: | ||
156 | * * a value of -1 means that the cmd is NOT supported, | ||
157 | * * a value != -1 means that the cmd IS supported. | ||
158 | * If it's supported the 'command status' register should return: | ||
159 | * sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(u32). | ||
160 | * - this command should be issued _after_ the usual SETUP_RINGS so that the | ||
161 | * RingsState page is already setup. If not, the command is a nop. | ||
162 | * - numPages needs to be a power of two, | ||
163 | * - numPages needs to be different from 0, | ||
164 | * - _pad should be zero. | ||
165 | */ | ||
166 | |||
167 | #define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 16 | ||
168 | |||
169 | struct PVSCSICmdDescSetupMsgRing { | ||
170 | u32 numPages; | ||
171 | u32 _pad; | ||
172 | u64 ringPPNs[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES]; | ||
173 | } __packed; | ||
174 | |||
175 | enum PVSCSIMsgType { | ||
176 | PVSCSI_MSG_DEV_ADDED = 0, | ||
177 | PVSCSI_MSG_DEV_REMOVED = 1, | ||
178 | PVSCSI_MSG_LAST = 2, | ||
179 | }; | ||
180 | |||
181 | /* | ||
182 | * Msg descriptor. | ||
183 | * | ||
184 | * sizeof(struct PVSCSIRingMsgDesc) == 128. | ||
185 | * | ||
186 | * - type is of type enum PVSCSIMsgType. | ||
187 | * - the content of args depend on the type of event being delivered. | ||
188 | */ | ||
189 | |||
190 | struct PVSCSIRingMsgDesc { | ||
191 | u32 type; | ||
192 | u32 args[31]; | ||
193 | } __packed; | ||
194 | |||
195 | struct PVSCSIMsgDescDevStatusChanged { | ||
196 | u32 type; /* PVSCSI_MSG_DEV _ADDED / _REMOVED */ | ||
197 | u32 bus; | ||
198 | u32 target; | ||
199 | u8 lun[8]; | ||
200 | u32 pad[27]; | ||
201 | } __packed; | ||
202 | |||
203 | /* | ||
204 | * Rings state. | ||
205 | * | ||
206 | * - the fields: | ||
207 | * . msgProdIdx, | ||
208 | * . msgConsIdx, | ||
209 | * . msgNumEntriesLog2, | ||
210 | * .. are only used once the SETUP_MSG_RING cmd has been issued. | ||
211 | * - '_pad' helps to ensure that the msg related fields are on their own | ||
212 | * cache-line. | ||
213 | */ | ||
214 | |||
215 | struct PVSCSIRingsState { | ||
216 | u32 reqProdIdx; | ||
217 | u32 reqConsIdx; | ||
218 | u32 reqNumEntriesLog2; | ||
219 | |||
220 | u32 cmpProdIdx; | ||
221 | u32 cmpConsIdx; | ||
222 | u32 cmpNumEntriesLog2; | ||
223 | |||
224 | u8 _pad[104]; | ||
225 | |||
226 | u32 msgProdIdx; | ||
227 | u32 msgConsIdx; | ||
228 | u32 msgNumEntriesLog2; | ||
229 | } __packed; | ||
230 | |||
231 | /* | ||
232 | * Request descriptor. | ||
233 | * | ||
234 | * sizeof(RingReqDesc) = 128 | ||
235 | * | ||
236 | * - context: is a unique identifier of a command. It could normally be any | ||
237 | * 64bit value, however we currently store it in the serialNumber variable | ||
238 | * of struct SCSI_Command, so we have the following restrictions due to the | ||
239 | * way this field is handled in the vmkernel storage stack: | ||
240 | * * this value can't be 0, | ||
241 | * * the upper 32bit need to be 0 since serialNumber is as a u32. | ||
242 | * Currently tracked as PR 292060. | ||
243 | * - dataLen: contains the total number of bytes that need to be transferred. | ||
244 | * - dataAddr: | ||
245 | * * if PVSCSI_FLAG_CMD_WITH_SG_LIST is set: dataAddr is the PA of the first | ||
246 | * s/g table segment, each s/g segment is entirely contained on a single | ||
247 | * page of physical memory, | ||
248 | * * if PVSCSI_FLAG_CMD_WITH_SG_LIST is NOT set, then dataAddr is the PA of | ||
249 | * the buffer used for the DMA transfer, | ||
250 | * - flags: | ||
251 | * * PVSCSI_FLAG_CMD_WITH_SG_LIST: see dataAddr above, | ||
252 | * * PVSCSI_FLAG_CMD_DIR_NONE: no DMA involved, | ||
253 | * * PVSCSI_FLAG_CMD_DIR_TOHOST: transfer from device to main memory, | ||
254 | * * PVSCSI_FLAG_CMD_DIR_TODEVICE: transfer from main memory to device, | ||
255 | * * PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB: reserved to handle CDBs larger than | ||
256 | * 16bytes. To be specified. | ||
257 | * - vcpuHint: vcpuId of the processor that will be most likely waiting for the | ||
258 | * completion of the i/o. For guest OSes that use lowest priority message | ||
259 | * delivery mode (such as windows), we use this "hint" to deliver the | ||
260 | * completion action to the proper vcpu. For now, we can use the vcpuId of | ||
261 | * the processor that initiated the i/o as a likely candidate for the vcpu | ||
262 | * that will be waiting for the completion.. | ||
263 | * - bus should be 0: we currently only support bus 0 for now. | ||
264 | * - unused should be zero'd. | ||
265 | */ | ||
266 | |||
267 | #define PVSCSI_FLAG_CMD_WITH_SG_LIST (1 << 0) | ||
268 | #define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB (1 << 1) | ||
269 | #define PVSCSI_FLAG_CMD_DIR_NONE (1 << 2) | ||
270 | #define PVSCSI_FLAG_CMD_DIR_TOHOST (1 << 3) | ||
271 | #define PVSCSI_FLAG_CMD_DIR_TODEVICE (1 << 4) | ||
272 | |||
273 | struct PVSCSIRingReqDesc { | ||
274 | u64 context; | ||
275 | u64 dataAddr; | ||
276 | u64 dataLen; | ||
277 | u64 senseAddr; | ||
278 | u32 senseLen; | ||
279 | u32 flags; | ||
280 | u8 cdb[16]; | ||
281 | u8 cdbLen; | ||
282 | u8 lun[8]; | ||
283 | u8 tag; | ||
284 | u8 bus; | ||
285 | u8 target; | ||
286 | u8 vcpuHint; | ||
287 | u8 unused[59]; | ||
288 | } __packed; | ||
289 | |||
290 | /* | ||
291 | * Scatter-gather list management. | ||
292 | * | ||
293 | * As described above, when PVSCSI_FLAG_CMD_WITH_SG_LIST is set in the | ||
294 | * RingReqDesc.flags, then RingReqDesc.dataAddr is the PA of the first s/g | ||
295 | * table segment. | ||
296 | * | ||
297 | * - each segment of the s/g table contain a succession of struct | ||
298 | * PVSCSISGElement. | ||
299 | * - each segment is entirely contained on a single physical page of memory. | ||
300 | * - a "chain" s/g element has the flag PVSCSI_SGE_FLAG_CHAIN_ELEMENT set in | ||
301 | * PVSCSISGElement.flags and in this case: | ||
302 | * * addr is the PA of the next s/g segment, | ||
303 | * * length is undefined, assumed to be 0. | ||
304 | */ | ||
305 | |||
306 | struct PVSCSISGElement { | ||
307 | u64 addr; | ||
308 | u32 length; | ||
309 | u32 flags; | ||
310 | } __packed; | ||
311 | |||
312 | /* | ||
313 | * Completion descriptor. | ||
314 | * | ||
315 | * sizeof(RingCmpDesc) = 32 | ||
316 | * | ||
317 | * - context: identifier of the command. The same thing that was specified | ||
318 | * under "context" as part of struct RingReqDesc at initiation time, | ||
319 | * - dataLen: number of bytes transferred for the actual i/o operation, | ||
320 | * - senseLen: number of bytes written into the sense buffer, | ||
321 | * - hostStatus: adapter status, | ||
322 | * - scsiStatus: device status, | ||
323 | * - _pad should be zero. | ||
324 | */ | ||
325 | |||
326 | struct PVSCSIRingCmpDesc { | ||
327 | u64 context; | ||
328 | u64 dataLen; | ||
329 | u32 senseLen; | ||
330 | u16 hostStatus; | ||
331 | u16 scsiStatus; | ||
332 | u32 _pad[2]; | ||
333 | } __packed; | ||
334 | |||
335 | /* | ||
336 | * Interrupt status / IRQ bits. | ||
337 | */ | ||
338 | |||
339 | #define PVSCSI_INTR_CMPL_0 (1 << 0) | ||
340 | #define PVSCSI_INTR_CMPL_1 (1 << 1) | ||
341 | #define PVSCSI_INTR_CMPL_MASK MASK(2) | ||
342 | |||
343 | #define PVSCSI_INTR_MSG_0 (1 << 2) | ||
344 | #define PVSCSI_INTR_MSG_1 (1 << 3) | ||
345 | #define PVSCSI_INTR_MSG_MASK (MASK(2) << 2) | ||
346 | |||
347 | #define PVSCSI_INTR_ALL_SUPPORTED MASK(4) | ||
348 | |||
349 | /* | ||
350 | * Number of MSI-X vectors supported. | ||
351 | */ | ||
352 | #define PVSCSI_MAX_INTRS 24 | ||
353 | |||
354 | /* | ||
355 | * Enumeration of supported MSI-X vectors | ||
356 | */ | ||
357 | #define PVSCSI_VECTOR_COMPLETION 0 | ||
358 | |||
359 | /* | ||
360 | * Misc constants for the rings. | ||
361 | */ | ||
362 | |||
363 | #define PVSCSI_MAX_NUM_PAGES_REQ_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES | ||
364 | #define PVSCSI_MAX_NUM_PAGES_CMP_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES | ||
365 | #define PVSCSI_MAX_NUM_PAGES_MSG_RING PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES | ||
366 | |||
367 | #define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \ | ||
368 | (PAGE_SIZE / sizeof(struct PVSCSIRingReqDesc)) | ||
369 | |||
370 | #define PVSCSI_MAX_REQ_QUEUE_DEPTH \ | ||
371 | (PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE) | ||
372 | |||
373 | #define PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES 1 | ||
374 | #define PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES 1 | ||
375 | #define PVSCSI_MEM_SPACE_MISC_NUM_PAGES 2 | ||
376 | #define PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES 2 | ||
377 | #define PVSCSI_MEM_SPACE_MSIX_NUM_PAGES 2 | ||
378 | |||
379 | enum PVSCSIMemSpace { | ||
380 | PVSCSI_MEM_SPACE_COMMAND_PAGE = 0, | ||
381 | PVSCSI_MEM_SPACE_INTR_STATUS_PAGE = 1, | ||
382 | PVSCSI_MEM_SPACE_MISC_PAGE = 2, | ||
383 | PVSCSI_MEM_SPACE_KICK_IO_PAGE = 4, | ||
384 | PVSCSI_MEM_SPACE_MSIX_TABLE_PAGE = 6, | ||
385 | PVSCSI_MEM_SPACE_MSIX_PBA_PAGE = 7, | ||
386 | }; | ||
387 | |||
388 | #define PVSCSI_MEM_SPACE_NUM_PAGES \ | ||
389 | (PVSCSI_MEM_SPACE_COMMAND_NUM_PAGES + \ | ||
390 | PVSCSI_MEM_SPACE_INTR_STATUS_NUM_PAGES + \ | ||
391 | PVSCSI_MEM_SPACE_MISC_NUM_PAGES + \ | ||
392 | PVSCSI_MEM_SPACE_KICK_IO_NUM_PAGES + \ | ||
393 | PVSCSI_MEM_SPACE_MSIX_NUM_PAGES) | ||
394 | |||
395 | #define PVSCSI_MEM_SPACE_SIZE (PVSCSI_MEM_SPACE_NUM_PAGES * PAGE_SIZE) | ||
396 | |||
397 | #endif /* _VMW_PVSCSI_H_ */ | ||