1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
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
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
|
/*
*
* Copyright (c) 2009, Microsoft Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Authors:
* Haiyang Zhang <haiyangz@microsoft.com>
* Hank Janssen <hjanssen@microsoft.com>
*
*/
#pragma once
//#include <vmbuspacketformat.h>
//#include <ntddscsi.h>
#define C_ASSERT(x)
//
// public interface to the server
//
//
// Storvsp device interface guid
//
//
// Protocol versions.
//
//
// vstorage.w revision number. This is used in the case of a version match,
// to alert the user that structure sizes may be mismatched even though the
// protocol versions match.
//
#define REVISION_STRING(REVISION_) #REVISION_
#define FILL_VMSTOR_REVISION(RESULT_LVALUE_) \
{ \
char *revisionString = REVISION_STRING($Revision: 6 $) + 11; \
RESULT_LVALUE_ = 0; \
while (*revisionString >= '0' && *revisionString <= '9') \
{ \
RESULT_LVALUE_ *= 10; \
RESULT_LVALUE_ += *revisionString - '0'; \
revisionString++; \
} \
}
//
// Major/minor macros. Minor version is in LSB, meaning that earlier flat
// version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1).
//
#define VMSTOR_PROTOCOL_MAJOR(VERSION_) (((VERSION_) >> 8) & 0xff)
#define VMSTOR_PROTOCOL_MINOR(VERSION_) (((VERSION_) ) & 0xff)
#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \
(((MINOR_) & 0xff) ))
//
// Invalid version.
//
#define VMSTOR_INVALID_PROTOCOL_VERSION -1
//
// Version history:
// V1 Beta 0.1
// V1 RC < 2008/1/31 1.0
// V1 RC > 2008/1/31 2.0
//
#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
//
// This will get replaced with the max transfer length that is possible on
// the host adapter.
// The max transfer length will be published when we offer a vmbus channel.
//
#define MAX_TRANSFER_LENGTH 0x40000
#define DEFAULT_PACKET_SIZE (sizeof(VMDATA_GPA_DIRECT) + \
sizeof(VSTOR_PACKET) + \
(sizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
//
// Packet structure describing virtual storage requests.
//
typedef enum
{
VStorOperationCompleteIo = 1,
VStorOperationRemoveDevice = 2,
VStorOperationExecuteSRB = 3,
VStorOperationResetLun = 4,
VStorOperationResetAdapter = 5,
VStorOperationResetBus = 6,
VStorOperationBeginInitialization = 7,
VStorOperationEndInitialization = 8,
VStorOperationQueryProtocolVersion = 9,
VStorOperationQueryProperties = 10,
VStorOperationMaximum = 10
} VSTOR_PACKET_OPERATION;
//
// Platform neutral description of a scsi request -
// this remains the same across the write regardless of 32/64 bit
// note: it's patterned off the SCSI_PASS_THROUGH structure
//
#pragma pack(push,1)
#define CDB16GENERIC_LENGTH 0x10
#ifndef SENSE_BUFFER_SIZE
#define SENSE_BUFFER_SIZE 0x12
#endif
C_ASSERT(SENSE_BUFFER_SIZE == 0x12);
#define MAX_DATA_BUFFER_LENGTH_WITH_PADDING 0x14
typedef struct
{
unsigned short Length;
unsigned char SrbStatus;
unsigned char ScsiStatus;
unsigned char PortNumber;
unsigned char PathId;
unsigned char TargetId;
unsigned char Lun;
unsigned char CdbLength;
unsigned char SenseInfoLength;
unsigned char DataIn;
unsigned char Reserved;
unsigned int DataTransferLength;
union
{
unsigned char Cdb[CDB16GENERIC_LENGTH];
unsigned char SenseData[SENSE_BUFFER_SIZE];
unsigned char ReservedArray[MAX_DATA_BUFFER_LENGTH_WITH_PADDING];
};
} VMSCSI_REQUEST, *PVMSCSI_REQUEST;
C_ASSERT((sizeof(VMSCSI_REQUEST) % 4) == 0);
//
// This structure is sent during the intialization phase to get the different
// properties of the channel.
//
typedef struct
{
unsigned short ProtocolVersion;
unsigned char PathId;
unsigned char TargetId;
//
// Note: port number is only really known on the client side
//
unsigned int PortNumber;
unsigned int Flags;
unsigned int MaxTransferBytes;
//
// This id is unique for each channel and will correspond with
// vendor specific data in the inquirydata
//
unsigned long long UniqueId;
} VMSTORAGE_CHANNEL_PROPERTIES, *PVMSTORAGE_CHANNEL_PROPERTIES;
C_ASSERT((sizeof(VMSTORAGE_CHANNEL_PROPERTIES) % 4) == 0);
//
// This structure is sent during the storage protocol negotiations.
//
typedef struct
{
//
// Major (MSW) and minor (LSW) version numbers.
//
unsigned short MajorMinor;
//
// Revision number is auto-incremented whenever this file is changed
// (See FILL_VMSTOR_REVISION macro above). Mismatch does not definitely
// indicate incompatibility--but it does indicate mismatched builds.
//
unsigned short Revision;
} VMSTORAGE_PROTOCOL_VERSION, *PVMSTORAGE_PROTOCOL_VERSION;
C_ASSERT((sizeof(VMSTORAGE_PROTOCOL_VERSION) % 4) == 0);
//
// Channel Property Flags
//
#define STORAGE_CHANNEL_REMOVABLE_FLAG 0x1
#define STORAGE_CHANNEL_EMULATED_IDE_FLAG 0x2
typedef struct _VSTOR_PACKET
{
//
// Requested operation type
//
VSTOR_PACKET_OPERATION Operation;
//
// Flags - see below for values
//
unsigned int Flags;
//
// Status of the request returned from the server side.
//
unsigned int Status;
//
// Data payload area
//
union
{
//
// Structure used to forward SCSI commands from the client to the server.
//
VMSCSI_REQUEST VmSrb;
//
// Structure used to query channel properties.
//
VMSTORAGE_CHANNEL_PROPERTIES StorageChannelProperties;
//
// Used during version negotiations.
//
VMSTORAGE_PROTOCOL_VERSION Version;
};
} VSTOR_PACKET, *PVSTOR_PACKET;
C_ASSERT((sizeof(VSTOR_PACKET) % 4) == 0);
//
// Packet flags
//
//
// This flag indicates that the server should send back a completion for this
// packet.
//
#define REQUEST_COMPLETION_FLAG 0x1
//
// This is the set of flags that the vsc can set in any packets it sends
//
#define VSC_LEGAL_FLAGS (REQUEST_COMPLETION_FLAG)
#pragma pack(pop)
|