~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/staging/hv/hyperv_storage.h

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Copyright (c) 2011, Microsoft Corporation.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify it
 
6
 * under the terms and conditions of the GNU General Public License,
 
7
 * version 2, as published by the Free Software Foundation.
 
8
 *
 
9
 * This program is distributed in the hope it will be useful, but WITHOUT
 
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
12
 * more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License along with
 
15
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
16
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 
17
 *
 
18
 * Authors:
 
19
 *   Haiyang Zhang <haiyangz@microsoft.com>
 
20
 *   Hank Janssen  <hjanssen@microsoft.com>
 
21
 *   K. Y. Srinivasan <kys@microsoft.com>
 
22
 *
 
23
 */
 
24
 
 
25
#ifndef _HYPERV_STORAGE_H
 
26
#define _HYPERV_STORAGE_H
 
27
 
 
28
 
 
29
/* vstorage.w revision number.  This is used in the case of a version match, */
 
30
/* to alert the user that structure sizes may be mismatched even though the */
 
31
/* protocol versions match. */
 
32
 
 
33
 
 
34
#define REVISION_STRING(REVISION_) #REVISION_
 
35
#define FILL_VMSTOR_REVISION(RESULT_LVALUE_)                            \
 
36
        do {                                                            \
 
37
                char *revision_string                                   \
 
38
                        = REVISION_STRING($Rev : 6 $) + 6;              \
 
39
                RESULT_LVALUE_ = 0;                                     \
 
40
                while (*revision_string >= '0'                          \
 
41
                        && *revision_string <= '9') {                   \
 
42
                        RESULT_LVALUE_ *= 10;                           \
 
43
                        RESULT_LVALUE_ += *revision_string - '0';       \
 
44
                        revision_string++;                              \
 
45
                }                                                       \
 
46
        } while (0)
 
47
 
 
48
/* Major/minor macros.  Minor version is in LSB, meaning that earlier flat */
 
49
/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
 
50
#define VMSTOR_PROTOCOL_MAJOR(VERSION_)         (((VERSION_) >> 8) & 0xff)
 
51
#define VMSTOR_PROTOCOL_MINOR(VERSION_)         (((VERSION_))      & 0xff)
 
52
#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \
 
53
                                                 (((MINOR_) & 0xff)))
 
54
#define VMSTOR_INVALID_PROTOCOL_VERSION         (-1)
 
55
 
 
56
/* Version history: */
 
57
/* V1 Beta                    0.1 */
 
58
/* V1 RC < 2008/1/31          1.0 */
 
59
/* V1 RC > 2008/1/31          2.0 */
 
60
#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
 
61
 
 
62
 
 
63
 
 
64
 
 
65
/*  This will get replaced with the max transfer length that is possible on */
 
66
/*  the host adapter. */
 
67
/*  The max transfer length will be published when we offer a vmbus channel. */
 
68
#define MAX_TRANSFER_LENGTH     0x40000
 
69
#define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) + \
 
70
                        sizeof(struct vstor_packet) +           \
 
71
                        sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
 
72
 
 
73
 
 
74
/*  Packet structure describing virtual storage requests. */
 
75
enum vstor_packet_operation {
 
76
        VSTOR_OPERATION_COMPLETE_IO             = 1,
 
77
        VSTOR_OPERATION_REMOVE_DEVICE           = 2,
 
78
        VSTOR_OPERATION_EXECUTE_SRB             = 3,
 
79
        VSTOR_OPERATION_RESET_LUN               = 4,
 
80
        VSTOR_OPERATION_RESET_ADAPTER           = 5,
 
81
        VSTOR_OPERATION_RESET_BUS               = 6,
 
82
        VSTOR_OPERATION_BEGIN_INITIALIZATION    = 7,
 
83
        VSTOR_OPERATION_END_INITIALIZATION      = 8,
 
84
        VSTOR_OPERATION_QUERY_PROTOCOL_VERSION  = 9,
 
85
        VSTOR_OPERATION_QUERY_PROPERTIES        = 10,
 
86
        VSTOR_OPERATION_MAXIMUM                 = 10
 
87
};
 
88
 
 
89
/*
 
90
 * Platform neutral description of a scsi request -
 
91
 * this remains the same across the write regardless of 32/64 bit
 
92
 * note: it's patterned off the SCSI_PASS_THROUGH structure
 
93
 */
 
94
#define CDB16GENERIC_LENGTH                     0x10
 
95
 
 
96
#ifndef SENSE_BUFFER_SIZE
 
97
#define SENSE_BUFFER_SIZE                       0x12
 
98
#endif
 
99
 
 
100
#define MAX_DATA_BUF_LEN_WITH_PADDING           0x14
 
101
 
 
102
struct vmscsi_request {
 
103
        unsigned short length;
 
104
        unsigned char srb_status;
 
105
        unsigned char scsi_status;
 
106
 
 
107
        unsigned char port_number;
 
108
        unsigned char path_id;
 
109
        unsigned char target_id;
 
110
        unsigned char lun;
 
111
 
 
112
        unsigned char cdb_length;
 
113
        unsigned char sense_info_length;
 
114
        unsigned char data_in;
 
115
        unsigned char reserved;
 
116
 
 
117
        unsigned int data_transfer_length;
 
118
 
 
119
        union {
 
120
                unsigned char cdb[CDB16GENERIC_LENGTH];
 
121
                unsigned char sense_data[SENSE_BUFFER_SIZE];
 
122
                unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING];
 
123
        };
 
124
} __attribute((packed));
 
125
 
 
126
 
 
127
/*
 
128
 * This structure is sent during the intialization phase to get the different
 
129
 * properties of the channel.
 
130
 */
 
131
struct vmstorage_channel_properties {
 
132
        unsigned short protocol_version;
 
133
        unsigned char path_id;
 
134
        unsigned char target_id;
 
135
 
 
136
        /* Note: port number is only really known on the client side */
 
137
        unsigned int port_number;
 
138
        unsigned int flags;
 
139
        unsigned int max_transfer_bytes;
 
140
 
 
141
        /*  This id is unique for each channel and will correspond with */
 
142
        /*  vendor specific data in the inquirydata */
 
143
        unsigned long long unique_id;
 
144
} __packed;
 
145
 
 
146
/*  This structure is sent during the storage protocol negotiations. */
 
147
struct vmstorage_protocol_version {
 
148
        /* Major (MSW) and minor (LSW) version numbers. */
 
149
        unsigned short major_minor;
 
150
 
 
151
        /*
 
152
         * Revision number is auto-incremented whenever this file is changed
 
153
         * (See FILL_VMSTOR_REVISION macro above).  Mismatch does not
 
154
         * definitely indicate incompatibility--but it does indicate mismatched
 
155
         * builds.
 
156
         */
 
157
        unsigned short revision;
 
158
} __packed;
 
159
 
 
160
/* Channel Property Flags */
 
161
#define STORAGE_CHANNEL_REMOVABLE_FLAG          0x1
 
162
#define STORAGE_CHANNEL_EMULATED_IDE_FLAG       0x2
 
163
 
 
164
struct vstor_packet {
 
165
        /* Requested operation type */
 
166
        enum vstor_packet_operation operation;
 
167
 
 
168
        /*  Flags - see below for values */
 
169
        unsigned int flags;
 
170
 
 
171
        /* Status of the request returned from the server side. */
 
172
        unsigned int status;
 
173
 
 
174
        /* Data payload area */
 
175
        union {
 
176
                /*
 
177
                 * Structure used to forward SCSI commands from the
 
178
                 * client to the server.
 
179
                 */
 
180
                struct vmscsi_request vm_srb;
 
181
 
 
182
                /* Structure used to query channel properties. */
 
183
                struct vmstorage_channel_properties storage_channel_properties;
 
184
 
 
185
                /* Used during version negotiations. */
 
186
                struct vmstorage_protocol_version version;
 
187
        };
 
188
} __packed;
 
189
 
 
190
/* Packet flags */
 
191
/*
 
192
 * This flag indicates that the server should send back a completion for this
 
193
 * packet.
 
194
 */
 
195
#define REQUEST_COMPLETION_FLAG 0x1
 
196
 
 
197
/*  This is the set of flags that the vsc can set in any packets it sends */
 
198
#define VSC_LEGAL_FLAGS         (REQUEST_COMPLETION_FLAG)
 
199
 
 
200
 
 
201
#include <linux/kernel.h>
 
202
#include <linux/wait.h>
 
203
#include "hyperv_storage.h"
 
204
#include "hyperv.h"
 
205
 
 
206
/* Defines */
 
207
#define STORVSC_RING_BUFFER_SIZE                        (20*PAGE_SIZE)
 
208
#define BLKVSC_RING_BUFFER_SIZE                         (20*PAGE_SIZE)
 
209
 
 
210
#define STORVSC_MAX_IO_REQUESTS                         128
 
211
 
 
212
/*
 
213
 * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
 
214
 * reality, the path/target is not used (ie always set to 0) so our
 
215
 * scsi host adapter essentially has 1 bus with 1 target that contains
 
216
 * up to 256 luns.
 
217
 */
 
218
#define STORVSC_MAX_LUNS_PER_TARGET                     64
 
219
#define STORVSC_MAX_TARGETS                             1
 
220
#define STORVSC_MAX_CHANNELS                            1
 
221
 
 
222
struct hv_storvsc_request;
 
223
 
 
224
/* Matches Windows-end */
 
225
enum storvsc_request_type {
 
226
        WRITE_TYPE,
 
227
        READ_TYPE,
 
228
        UNKNOWN_TYPE,
 
229
};
 
230
 
 
231
 
 
232
struct hv_storvsc_request {
 
233
        struct hv_storvsc_request *request;
 
234
        struct hv_device *device;
 
235
 
 
236
        /* Synchronize the request/response if needed */
 
237
        struct completion wait_event;
 
238
 
 
239
        unsigned char *sense_buffer;
 
240
        void *context;
 
241
        void (*on_io_completion)(struct hv_storvsc_request *request);
 
242
        struct hv_multipage_buffer data_buffer;
 
243
 
 
244
        struct vstor_packet vstor_packet;
 
245
};
 
246
 
 
247
 
 
248
struct storvsc_device_info {
 
249
        u32 ring_buffer_size;
 
250
        unsigned int port_number;
 
251
        unsigned char path_id;
 
252
        unsigned char target_id;
 
253
};
 
254
 
 
255
struct storvsc_major_info {
 
256
        int major;
 
257
        int index;
 
258
        bool do_register;
 
259
        char *devname;
 
260
        char *diskname;
 
261
};
 
262
 
 
263
/* A storvsc device is a device object that contains a vmbus channel */
 
264
struct storvsc_device {
 
265
        struct hv_device *device;
 
266
 
 
267
        /* 0 indicates the device is being destroyed */
 
268
        atomic_t ref_count;
 
269
 
 
270
        bool     drain_notify;
 
271
        atomic_t num_outstanding_req;
 
272
 
 
273
        wait_queue_head_t waiting_to_drain;
 
274
 
 
275
        /*
 
276
         * Each unique Port/Path/Target represents 1 channel ie scsi
 
277
         * controller. In reality, the pathid, targetid is always 0
 
278
         * and the port is set by us
 
279
         */
 
280
        unsigned int port_number;
 
281
        unsigned char path_id;
 
282
        unsigned char target_id;
 
283
 
 
284
        /* Used for vsc/vsp channel reset process */
 
285
        struct hv_storvsc_request init_request;
 
286
        struct hv_storvsc_request reset_request;
 
287
};
 
288
 
 
289
 
 
290
/* Get the stordevice object iff exists and its refcount > 1 */
 
291
static inline struct storvsc_device *get_stor_device(struct hv_device *device)
 
292
{
 
293
        struct storvsc_device *stor_device;
 
294
 
 
295
        stor_device = (struct storvsc_device *)device->ext;
 
296
        if (stor_device && atomic_read(&stor_device->ref_count) > 1)
 
297
                atomic_inc(&stor_device->ref_count);
 
298
        else
 
299
                stor_device = NULL;
 
300
 
 
301
        return stor_device;
 
302
}
 
303
 
 
304
 
 
305
static inline void put_stor_device(struct hv_device *device)
 
306
{
 
307
        struct storvsc_device *stor_device;
 
308
 
 
309
        stor_device = (struct storvsc_device *)device->ext;
 
310
 
 
311
        atomic_dec(&stor_device->ref_count);
 
312
}
 
313
 
 
314
static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
 
315
{
 
316
        dev->drain_notify = true;
 
317
        wait_event(dev->waiting_to_drain,
 
318
                   atomic_read(&dev->num_outstanding_req) == 0);
 
319
        dev->drain_notify = false;
 
320
}
 
321
 
 
322
/* Interface */
 
323
 
 
324
int storvsc_dev_add(struct hv_device *device,
 
325
                                void *additional_info);
 
326
int storvsc_dev_remove(struct hv_device *device);
 
327
 
 
328
int storvsc_do_io(struct hv_device *device,
 
329
                                struct hv_storvsc_request *request);
 
330
 
 
331
int storvsc_get_major_info(struct storvsc_device_info *device_info,
 
332
                                struct storvsc_major_info *major_info);
 
333
 
 
334
#endif /* _HYPERV_STORAGE_H */