1250199Sgrehan/*-
2324461Ssephe * Copyright (c) 2009-2012,2017 Microsoft Corp.
3250199Sgrehan * Copyright (c) 2012 NetApp Inc.
4250199Sgrehan * Copyright (c) 2012 Citrix Inc.
5250199Sgrehan * All rights reserved.
6250199Sgrehan *
7250199Sgrehan * Redistribution and use in source and binary forms, with or without
8250199Sgrehan * modification, are permitted provided that the following conditions
9250199Sgrehan * are met:
10250199Sgrehan * 1. Redistributions of source code must retain the above copyright
11250199Sgrehan *    notice unmodified, this list of conditions, and the following
12250199Sgrehan *    disclaimer.
13250199Sgrehan * 2. Redistributions in binary form must reproduce the above copyright
14250199Sgrehan *    notice, this list of conditions and the following disclaimer in the
15250199Sgrehan *    documentation and/or other materials provided with the distribution.
16250199Sgrehan *
17250199Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18250199Sgrehan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19250199Sgrehan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20250199Sgrehan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21250199Sgrehan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22250199Sgrehan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23250199Sgrehan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24250199Sgrehan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25250199Sgrehan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26250199Sgrehan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27256276Sdim *
28256276Sdim * $FreeBSD: stable/10/sys/dev/hyperv/storvsc/hv_vstorage.h 324461 2017-10-10 02:22:34Z sephe $
29250199Sgrehan */
30250199Sgrehan
31250199Sgrehan#ifndef __HV_VSTORAGE_H__
32250199Sgrehan#define __HV_VSTORAGE_H__
33250199Sgrehan
34250199Sgrehan/*
35250199Sgrehan * Major/minor macros.  Minor version is in LSB, meaning that earlier flat
36250199Sgrehan * version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1).
37250199Sgrehan */
38250199Sgrehan
39250199Sgrehan#define VMSTOR_PROTOCOL_MAJOR(VERSION_)         (((VERSION_) >> 8) & 0xff)
40250199Sgrehan#define VMSTOR_PROTOCOL_MINOR(VERSION_)         (((VERSION_)     ) & 0xff)
41250199Sgrehan#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \
42250199Sgrehan                                                 (((MINOR_) & 0xff)     ))
43250199Sgrehan
44300656Ssephe#define VMSTOR_PROTOCOL_VERSION_WIN6       VMSTOR_PROTOCOL_VERSION(2, 0)
45300656Ssephe#define VMSTOR_PROTOCOL_VERSION_WIN7       VMSTOR_PROTOCOL_VERSION(4, 2)
46300656Ssephe#define VMSTOR_PROTOCOL_VERSION_WIN8       VMSTOR_PROTOCOL_VERSION(5, 1)
47300656Ssephe#define VMSTOR_PROTOCOL_VERSION_WIN8_1     VMSTOR_PROTOCOL_VERSION(6, 0)
48300656Ssephe#define VMSTOR_PROTOCOL_VERSION_WIN10      VMSTOR_PROTOCOL_VERSION(6, 2)
49250199Sgrehan/*
50250199Sgrehan * Invalid version.
51250199Sgrehan */
52250199Sgrehan#define VMSTOR_INVALID_PROTOCOL_VERSION  -1
53250199Sgrehan
54250199Sgrehan/*
55250199Sgrehan * Version history:
56250199Sgrehan * V1 Beta                    0.1
57250199Sgrehan * V1 RC < 2008/1/31          1.0
58250199Sgrehan * V1 RC > 2008/1/31          2.0
59283644Swhu * Win7: 4.2
60283644Swhu * Win8: 5.1
61250199Sgrehan */
62250199Sgrehan
63283280Swhu#define VMSTOR_PROTOCOL_VERSION_CURRENT	VMSTOR_PROTOCOL_VERSION(5, 1)
64250199Sgrehan
65250199Sgrehan/**
66250199Sgrehan *  Packet structure ops describing virtual storage requests.
67250199Sgrehan */
68250199Sgrehanenum vstor_packet_ops {
69250199Sgrehan	VSTOR_OPERATION_COMPLETEIO            = 1,
70250199Sgrehan	VSTOR_OPERATION_REMOVEDEVICE          = 2,
71250199Sgrehan	VSTOR_OPERATION_EXECUTESRB            = 3,
72250199Sgrehan	VSTOR_OPERATION_RESETLUN              = 4,
73250199Sgrehan	VSTOR_OPERATION_RESETADAPTER          = 5,
74250199Sgrehan	VSTOR_OPERATION_RESETBUS              = 6,
75250199Sgrehan	VSTOR_OPERATION_BEGININITIALIZATION   = 7,
76250199Sgrehan	VSTOR_OPERATION_ENDINITIALIZATION     = 8,
77250199Sgrehan	VSTOR_OPERATION_QUERYPROTOCOLVERSION  = 9,
78250199Sgrehan	VSTOR_OPERATION_QUERYPROPERTIES       = 10,
79283280Swhu	VSTOR_OPERATION_ENUMERATE_BUS         = 11,
80283280Swhu	VSTOR_OPERATION_FCHBA_DATA            = 12,
81283280Swhu	VSTOR_OPERATION_CREATE_MULTI_CHANNELS = 13,
82283280Swhu	VSTOR_OPERATION_MAXIMUM               = 13
83250199Sgrehan};
84250199Sgrehan
85250199Sgrehan
86250199Sgrehan/*
87250199Sgrehan *  Platform neutral description of a scsi request -
88250199Sgrehan *  this remains the same across the write regardless of 32/64 bit
89250199Sgrehan *  note: it's patterned off the Windows DDK SCSI_PASS_THROUGH structure
90250199Sgrehan */
91250199Sgrehan
92250199Sgrehan#define CDB16GENERIC_LENGTH			0x10
93283644Swhu#define SENSE_BUFFER_SIZE			0x14
94250199Sgrehan#define MAX_DATA_BUFFER_LENGTH_WITH_PADDING	0x14
95250199Sgrehan
96283644Swhu#define POST_WIN7_STORVSC_SENSE_BUFFER_SIZE	0x14
97283644Swhu#define PRE_WIN8_STORVSC_SENSE_BUFFER_SIZE	0x12
98283644Swhu
99283644Swhu
100283644Swhustruct vmscsi_win8_extension {
101283644Swhu	/*
102283644Swhu	 * The following were added in Windows 8
103283644Swhu	 */
104283644Swhu	uint16_t reserve;
105283644Swhu	uint8_t  queue_tag;
106283644Swhu	uint8_t  queue_action;
107283644Swhu	uint32_t srb_flags;
108283644Swhu	uint32_t time_out_value;
109283644Swhu	uint32_t queue_sort_ey;
110283644Swhu} __packed;
111283644Swhu
112250199Sgrehanstruct vmscsi_req {
113250199Sgrehan	uint16_t length;
114250199Sgrehan	uint8_t  srb_status;
115250199Sgrehan	uint8_t  scsi_status;
116250199Sgrehan
117250199Sgrehan	/* HBA number, set to the order number detected by initiator. */
118250199Sgrehan	uint8_t  port;
119250199Sgrehan	/* SCSI bus number or bus_id, different from CAM's path_id. */
120250199Sgrehan	uint8_t  path_id;
121250199Sgrehan
122250199Sgrehan	uint8_t  target_id;
123250199Sgrehan	uint8_t  lun;
124250199Sgrehan
125250199Sgrehan	uint8_t  cdb_len;
126250199Sgrehan	uint8_t  sense_info_len;
127250199Sgrehan	uint8_t  data_in;
128250199Sgrehan	uint8_t  reserved;
129250199Sgrehan
130250199Sgrehan	uint32_t transfer_len;
131250199Sgrehan
132250199Sgrehan	union {
133250199Sgrehan	    uint8_t cdb[CDB16GENERIC_LENGTH];
134250199Sgrehan
135250199Sgrehan	    uint8_t sense_data[SENSE_BUFFER_SIZE];
136250199Sgrehan
137250199Sgrehan	    uint8_t reserved_array[MAX_DATA_BUFFER_LENGTH_WITH_PADDING];
138256276Sdim	} u;
139250199Sgrehan
140283644Swhu	/*
141283644Swhu	 * The following was added in win8.
142283644Swhu	 */
143283644Swhu	struct vmscsi_win8_extension win8_extension;
144283644Swhu
145250199Sgrehan} __packed;
146250199Sgrehan
147250199Sgrehan/**
148250199Sgrehan *  This structure is sent during the initialization phase to get the different
149250199Sgrehan *  properties of the channel.
150250199Sgrehan */
151250199Sgrehan
152250199Sgrehanstruct vmstor_chan_props {
153250199Sgrehan	uint16_t proto_ver;
154250199Sgrehan	uint8_t  path_id;
155250199Sgrehan	uint8_t  target_id;
156250199Sgrehan
157283280Swhu	uint16_t max_channel_cnt;
158283280Swhu
159250199Sgrehan	/**
160250199Sgrehan	 * Note: port number is only really known on the client side
161250199Sgrehan	 */
162283280Swhu	uint16_t port;
163250199Sgrehan	uint32_t flags;
164250199Sgrehan	uint32_t max_transfer_bytes;
165250199Sgrehan
166250199Sgrehan	/**
167250199Sgrehan	 *  This id is unique for each channel and will correspond with
168250199Sgrehan	 *  vendor specific data in the inquiry_ata
169250199Sgrehan	 */
170250199Sgrehan	uint64_t unique_id;
171250199Sgrehan
172250199Sgrehan} __packed;
173250199Sgrehan
174250199Sgrehan/**
175250199Sgrehan *  This structure is sent during the storage protocol negotiations.
176250199Sgrehan */
177250199Sgrehan
178250199Sgrehanstruct vmstor_proto_ver
179250199Sgrehan{
180250199Sgrehan	/**
181250199Sgrehan	 * Major (MSW) and minor (LSW) version numbers.
182250199Sgrehan	 */
183250199Sgrehan	uint16_t major_minor;
184250199Sgrehan
185250199Sgrehan	uint16_t revision;			/* always zero */
186250199Sgrehan} __packed;
187250199Sgrehan
188250199Sgrehan/**
189250199Sgrehan * Channel Property Flags
190250199Sgrehan */
191250199Sgrehan
192250199Sgrehan#define STORAGE_CHANNEL_REMOVABLE_FLAG                  0x1
193250199Sgrehan#define STORAGE_CHANNEL_EMULATED_IDE_FLAG               0x2
194250199Sgrehan
195250199Sgrehan
196250199Sgrehanstruct vstor_packet {
197250199Sgrehan	/**
198250199Sgrehan	 * Requested operation type
199250199Sgrehan	 */
200250199Sgrehan	enum vstor_packet_ops operation;
201250199Sgrehan
202250199Sgrehan	/*
203250199Sgrehan	 * Flags - see below for values
204250199Sgrehan	 */
205250199Sgrehan	uint32_t flags;
206250199Sgrehan
207250199Sgrehan	/**
208250199Sgrehan	 * Status of the request returned from the server side.
209250199Sgrehan	 */
210250199Sgrehan	uint32_t status;
211250199Sgrehan
212250199Sgrehan	union
213250199Sgrehan	{
214250199Sgrehan	    /**
215250199Sgrehan	     * Structure used to forward SCSI commands from the client to
216250199Sgrehan	     * the server.
217250199Sgrehan	     */
218250199Sgrehan	    struct vmscsi_req vm_srb;
219250199Sgrehan
220250199Sgrehan	    /**
221250199Sgrehan	     * Structure used to query channel properties.
222250199Sgrehan	     */
223250199Sgrehan	    struct vmstor_chan_props chan_props;
224250199Sgrehan
225250199Sgrehan	    /**
226250199Sgrehan	     * Used during version negotiations.
227250199Sgrehan	     */
228250199Sgrehan	    struct vmstor_proto_ver version;
229283280Swhu
230283280Swhu	    /**
231283280Swhu             * Number of multichannels to create
232283280Swhu	     */
233283280Swhu	    uint16_t multi_channels_cnt;
234256276Sdim	} u;
235250199Sgrehan
236250199Sgrehan} __packed;
237250199Sgrehan
238250199Sgrehan
239250199Sgrehan/**
240250199Sgrehan * SRB (SCSI Request Block) Status Codes
241250199Sgrehan */
242250199Sgrehan#define SRB_STATUS_PENDING		0x00
243250199Sgrehan#define SRB_STATUS_SUCCESS		0x01
244250199Sgrehan#define SRB_STATUS_ABORTED		0x02
245250199Sgrehan#define SRB_STATUS_ERROR 		0x04
246316671Ssephe#define SRB_STATUS_INVALID_LUN          0x20
247250199Sgrehan/**
248250199Sgrehan * SRB Status Masks (can be combined with above status codes)
249250199Sgrehan */
250304581Ssephe#define SRB_STATUS_QUEUE_FROZEN         0x40
251304581Ssephe#define SRB_STATUS_AUTOSENSE_VALID      0x80
252250199Sgrehan
253316671Ssephe#define SRB_STATUS(status)	\
254316671Ssephe	((status) & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
255307180Ssephe/*
256307180Ssephe * SRB Flag Bits
257307180Ssephe */
258307180Ssephe
259307180Ssephe#define SRB_FLAGS_QUEUE_ACTION_ENABLE           0x00000002
260307180Ssephe#define SRB_FLAGS_DISABLE_DISCONNECT            0x00000004
261307180Ssephe#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER        0x00000008
262307180Ssephe#define SRB_FLAGS_BYPASS_FROZEN_QUEUE           0x00000010
263307180Ssephe#define SRB_FLAGS_DISABLE_AUTOSENSE             0x00000020
264307180Ssephe#define SRB_FLAGS_DATA_IN                       0x00000040
265307180Ssephe#define SRB_FLAGS_DATA_OUT                      0x00000080
266307180Ssephe#define SRB_FLAGS_NO_DATA_TRANSFER              0x00000000
267307180Ssephe#define SRB_FLAGS_UNSPECIFIED_DIRECTION (SRB_FLAGS_DATA_IN | SRB_FLAGS_DATA_OUT)
268307180Ssephe#define SRB_FLAGS_NO_QUEUE_FREEZE               0x00000100
269307180Ssephe#define SRB_FLAGS_ADAPTER_CACHE_ENABLE          0x00000200
270307180Ssephe#define SRB_FLAGS_FREE_SENSE_BUFFER             0x00000400
271250199Sgrehan/**
272250199Sgrehan *  Packet flags
273250199Sgrehan */
274250199Sgrehan
275250199Sgrehan/**
276250199Sgrehan *  This flag indicates that the server should send back a completion for this
277250199Sgrehan *  packet.
278250199Sgrehan */
279250199Sgrehan#define REQUEST_COMPLETION_FLAG	0x1
280250199Sgrehan
281250199Sgrehan/**
282250199Sgrehan *  This is the set of flags that the vsc can set in any packets it sends
283250199Sgrehan */
284250199Sgrehan#define VSC_LEGAL_FLAGS (REQUEST_COMPLETION_FLAG)
285250199Sgrehan
286250199Sgrehan#endif /* __HV_VSTORAGE_H__ */
287