aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/hv
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/hv
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/staging/hv')
-rw-r--r--drivers/staging/hv/Kconfig46
-rw-r--r--drivers/staging/hv/Makefile14
-rw-r--r--drivers/staging/hv/TODO14
-rw-r--r--drivers/staging/hv/blkvsc_drv.c1026
-rw-r--r--drivers/staging/hv/channel.c877
-rw-r--r--drivers/staging/hv/channel_mgmt.c784
-rw-r--r--drivers/staging/hv/connection.c290
-rw-r--r--drivers/staging/hv/hv.c438
-rw-r--r--drivers/staging/hv/hv_kvp.c334
-rw-r--r--drivers/staging/hv/hv_kvp.h184
-rw-r--r--drivers/staging/hv/hv_mouse.c974
-rw-r--r--drivers/staging/hv/hv_timesource.c101
-rw-r--r--drivers/staging/hv/hv_util.c306
-rw-r--r--drivers/staging/hv/hyperv.h948
-rw-r--r--drivers/staging/hv/hyperv_net.h1057
-rw-r--r--drivers/staging/hv/hyperv_storage.h335
-rw-r--r--drivers/staging/hv/hyperv_vmbus.h629
-rw-r--r--drivers/staging/hv/netvsc.c1015
-rw-r--r--drivers/staging/hv/netvsc_drv.c476
-rw-r--r--drivers/staging/hv/ring_buffer.c526
-rw-r--r--drivers/staging/hv/rndis_filter.c831
-rw-r--r--drivers/staging/hv/storvsc.c564
-rw-r--r--drivers/staging/hv/storvsc_drv.c794
-rw-r--r--drivers/staging/hv/tools/hv_kvp_daemon.c493
-rw-r--r--drivers/staging/hv/vmbus_drv.c802
25 files changed, 13858 insertions, 0 deletions
diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig
new file mode 100644
index 00000000000..5e0c9f6c745
--- /dev/null
+++ b/drivers/staging/hv/Kconfig
@@ -0,0 +1,46 @@
1config HYPERV
2 tristate "Microsoft Hyper-V client drivers"
3 depends on X86 && ACPI && PCI && m
4 default n
5 help
6 Select this option to run Linux as a Hyper-V client operating
7 system.
8
9if HYPERV
10
11config HYPERV_STORAGE
12 tristate "Microsoft Hyper-V virtual storage driver"
13 depends on SCSI
14 default HYPERV
15 help
16 Select this option to enable the Hyper-V virtual storage driver.
17
18config HYPERV_BLOCK
19 tristate "Microsoft Hyper-V virtual block driver"
20 depends on BLOCK && SCSI && (LBDAF || 64BIT)
21 default HYPERV
22 help
23 Select this option to enable the Hyper-V virtual block driver.
24
25config HYPERV_NET
26 tristate "Microsoft Hyper-V virtual network driver"
27 depends on NET
28 default HYPERV
29 help
30 Select this option to enable the Hyper-V virtual network driver.
31
32config HYPERV_UTILS
33 tristate "Microsoft Hyper-V Utilities driver"
34 depends on CONNECTOR && NLS
35 default HYPERV
36 help
37 Select this option to enable the Hyper-V Utilities.
38
39config HYPERV_MOUSE
40 tristate "Microsoft Hyper-V mouse driver"
41 depends on HID
42 default HYPERV
43 help
44 Select this option to enable the Hyper-V mouse driver.
45
46endif
diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile
new file mode 100644
index 00000000000..30046743a0b
--- /dev/null
+++ b/drivers/staging/hv/Makefile
@@ -0,0 +1,14 @@
1obj-$(CONFIG_HYPERV) += hv_vmbus.o hv_timesource.o
2obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o
3obj-$(CONFIG_HYPERV_BLOCK) += hv_blkvsc.o
4obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o
5obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
6obj-$(CONFIG_HYPERV_MOUSE) += hv_mouse.o
7
8hv_vmbus-y := vmbus_drv.o \
9 hv.o connection.o channel.o \
10 channel_mgmt.o ring_buffer.o
11hv_storvsc-y := storvsc_drv.o storvsc.o
12hv_blkvsc-y := blkvsc_drv.o storvsc.o
13hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o
14hv_utils-y := hv_util.o hv_kvp.o
diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
new file mode 100644
index 00000000000..582fd4ab3f1
--- /dev/null
+++ b/drivers/staging/hv/TODO
@@ -0,0 +1,14 @@
1TODO:
2 - fix remaining checkpatch warnings and errors
3 - audit the vmbus to verify it is working properly with the
4 driver model
5 - see if the vmbus can be merged with the other virtual busses
6 in the kernel
7 - audit the network driver
8 - checking for carrier inside open is wrong, network device API
9 confusion??
10 - audit the block driver
11 - audit the scsi driver
12
13Please send patches for this code to Greg Kroah-Hartman <gregkh@suse.de>,
14Hank Janssen <hjanssen@microsoft.com>, and Haiyang Zhang <haiyangz@microsoft.com>.
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
new file mode 100644
index 00000000000..d286b222318
--- /dev/null
+++ b/drivers/staging/hv/blkvsc_drv.c
@@ -0,0 +1,1026 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 * K. Y. Srinivasan <kys@microsoft.com>
21 */
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/device.h>
25#include <linux/blkdev.h>
26#include <linux/major.h>
27#include <linux/delay.h>
28#include <linux/hdreg.h>
29#include <linux/slab.h>
30#include <scsi/scsi.h>
31#include <scsi/scsi_cmnd.h>
32#include <scsi/scsi_eh.h>
33#include <scsi/scsi_dbg.h>
34
35#include "hyperv.h"
36#include "hyperv_storage.h"
37
38
39#define BLKVSC_MINORS 64
40
41enum blkvsc_device_type {
42 UNKNOWN_DEV_TYPE,
43 HARDDISK_TYPE,
44 DVD_TYPE,
45};
46
47enum blkvsc_op_type {
48 DO_INQUIRY,
49 DO_CAPACITY,
50 DO_FLUSH,
51};
52
53/*
54 * This request ties the struct request and struct
55 * blkvsc_request/hv_storvsc_request together A struct request may be
56 * represented by 1 or more struct blkvsc_request
57 */
58struct blkvsc_request_group {
59 int outstanding;
60 int status;
61 struct list_head blkvsc_req_list; /* list of blkvsc_requests */
62};
63
64struct blkvsc_request {
65 /* blkvsc_request_group.blkvsc_req_list */
66 struct list_head req_entry;
67
68 /* block_device_context.pending_list */
69 struct list_head pend_entry;
70
71 /* This may be null if we generate a request internally */
72 struct request *req;
73
74 struct block_device_context *dev;
75
76 /* The group this request is part of. Maybe null */
77 struct blkvsc_request_group *group;
78
79 int write;
80 sector_t sector_start;
81 unsigned long sector_count;
82
83 unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
84 unsigned char cmd_len;
85 unsigned char cmnd[MAX_COMMAND_SIZE];
86
87 struct hv_storvsc_request request;
88};
89
90/* Per device structure */
91struct block_device_context {
92 /* point back to our device context */
93 struct hv_device *device_ctx;
94 struct kmem_cache *request_pool;
95 spinlock_t lock;
96 struct gendisk *gd;
97 enum blkvsc_device_type device_type;
98 struct list_head pending_list;
99
100 unsigned char device_id[64];
101 unsigned int device_id_len;
102 int num_outstanding_reqs;
103 int shutting_down;
104 unsigned int sector_size;
105 sector_t capacity;
106 unsigned int port;
107 unsigned char path;
108 unsigned char target;
109 int users;
110};
111
112static const char *drv_name = "blkvsc";
113
114/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
115static const struct hv_guid dev_type = {
116 .data = {
117 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
118 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
119 }
120};
121
122/*
123 * There is a circular dependency involving blkvsc_request_completion()
124 * and blkvsc_do_request().
125 */
126static void blkvsc_request_completion(struct hv_storvsc_request *request);
127
128static int blkvsc_ringbuffer_size = BLKVSC_RING_BUFFER_SIZE;
129
130module_param(blkvsc_ringbuffer_size, int, S_IRUGO);
131MODULE_PARM_DESC(ring_size, "Ring buffer size (in bytes)");
132
133/*
134 * There is a circular dependency involving blkvsc_probe()
135 * and block_ops.
136 */
137static int blkvsc_probe(struct hv_device *dev);
138
139static int blkvsc_device_add(struct hv_device *device,
140 void *additional_info)
141{
142 struct storvsc_device_info *device_info;
143 int ret = 0;
144
145 device_info = (struct storvsc_device_info *)additional_info;
146
147 device_info->ring_buffer_size = blkvsc_ringbuffer_size;
148
149 ret = storvsc_dev_add(device, additional_info);
150 if (ret != 0)
151 return ret;
152
153 /*
154 * We need to use the device instance guid to set the path and target
155 * id. For IDE devices, the device instance id is formatted as
156 * <bus id> * - <device id> - 8899 - 000000000000.
157 */
158 device_info->path_id = device->dev_instance.data[3] << 24 |
159 device->dev_instance.data[2] << 16 |
160 device->dev_instance.data[1] << 8 |
161 device->dev_instance.data[0];
162
163 device_info->target_id = device->dev_instance.data[5] << 8 |
164 device->dev_instance.data[4];
165
166 return ret;
167}
168
169static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
170 void (*request_completion)(struct hv_storvsc_request *))
171{
172 struct block_device_context *blkdev = blkvsc_req->dev;
173 struct hv_storvsc_request *storvsc_req;
174 struct vmscsi_request *vm_srb;
175 int ret;
176
177
178 storvsc_req = &blkvsc_req->request;
179 vm_srb = &storvsc_req->vstor_packet.vm_srb;
180
181 vm_srb->data_in = blkvsc_req->write ? WRITE_TYPE : READ_TYPE;
182
183 storvsc_req->on_io_completion = request_completion;
184 storvsc_req->context = blkvsc_req;
185
186 vm_srb->port_number = blkdev->port;
187 vm_srb->path_id = blkdev->path;
188 vm_srb->target_id = blkdev->target;
189 vm_srb->lun = 0; /* this is not really used at all */
190
191 vm_srb->cdb_length = blkvsc_req->cmd_len;
192
193 memcpy(vm_srb->cdb, blkvsc_req->cmnd, vm_srb->cdb_length);
194
195 storvsc_req->sense_buffer = blkvsc_req->sense_buffer;
196
197 ret = storvsc_do_io(blkdev->device_ctx,
198 &blkvsc_req->request);
199 if (ret == 0)
200 blkdev->num_outstanding_reqs++;
201
202 return ret;
203}
204
205
206static int blkvsc_open(struct block_device *bdev, fmode_t mode)
207{
208 struct block_device_context *blkdev = bdev->bd_disk->private_data;
209 unsigned long flags;
210
211 spin_lock_irqsave(&blkdev->lock, flags);
212
213 blkdev->users++;
214
215 spin_unlock_irqrestore(&blkdev->lock, flags);
216
217 return 0;
218}
219
220
221static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg)
222{
223 sector_t nsect = get_capacity(bd->bd_disk);
224 sector_t cylinders = nsect;
225
226 /*
227 * We are making up these values; let us keep it simple.
228 */
229 hg->heads = 0xff;
230 hg->sectors = 0x3f;
231 sector_div(cylinders, hg->heads * hg->sectors);
232 hg->cylinders = cylinders;
233 if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
234 hg->cylinders = 0xffff;
235 return 0;
236
237}
238
239
240static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req)
241{
242
243 blkvsc_req->cmd_len = 16;
244
245 if (rq_data_dir(blkvsc_req->req)) {
246 blkvsc_req->write = 1;
247 blkvsc_req->cmnd[0] = WRITE_16;
248 } else {
249 blkvsc_req->write = 0;
250 blkvsc_req->cmnd[0] = READ_16;
251 }
252
253 blkvsc_req->cmnd[1] |=
254 (blkvsc_req->req->cmd_flags & REQ_FUA) ? 0x8 : 0;
255
256 *(unsigned long long *)&blkvsc_req->cmnd[2] =
257 cpu_to_be64(blkvsc_req->sector_start);
258 *(unsigned int *)&blkvsc_req->cmnd[10] =
259 cpu_to_be32(blkvsc_req->sector_count);
260}
261
262
263static int blkvsc_ioctl(struct block_device *bd, fmode_t mode,
264 unsigned cmd, unsigned long arg)
265{
266 struct block_device_context *blkdev = bd->bd_disk->private_data;
267 int ret = 0;
268
269 switch (cmd) {
270 case HDIO_GET_IDENTITY:
271 if (copy_to_user((void __user *)arg, blkdev->device_id,
272 blkdev->device_id_len))
273 ret = -EFAULT;
274 break;
275 default:
276 ret = -EINVAL;
277 break;
278 }
279
280 return ret;
281}
282
283static void blkvsc_cmd_completion(struct hv_storvsc_request *request)
284{
285 struct blkvsc_request *blkvsc_req =
286 (struct blkvsc_request *)request->context;
287 struct block_device_context *blkdev =
288 (struct block_device_context *)blkvsc_req->dev;
289 struct scsi_sense_hdr sense_hdr;
290 struct vmscsi_request *vm_srb;
291 unsigned long flags;
292
293
294 vm_srb = &blkvsc_req->request.vstor_packet.vm_srb;
295
296 spin_lock_irqsave(&blkdev->lock, flags);
297 blkdev->num_outstanding_reqs--;
298 spin_unlock_irqrestore(&blkdev->lock, flags);
299
300 if (vm_srb->scsi_status)
301 if (scsi_normalize_sense(blkvsc_req->sense_buffer,
302 SCSI_SENSE_BUFFERSIZE, &sense_hdr))
303 scsi_print_sense_hdr("blkvsc", &sense_hdr);
304
305 complete(&blkvsc_req->request.wait_event);
306}
307
308
309static int blkvsc_do_operation(struct block_device_context *blkdev,
310 enum blkvsc_op_type op)
311{
312 struct blkvsc_request *blkvsc_req;
313 struct page *page_buf;
314 unsigned char *buf;
315 unsigned char device_type;
316 struct scsi_sense_hdr sense_hdr;
317 struct vmscsi_request *vm_srb;
318 unsigned long flags;
319
320 int ret = 0;
321
322 blkvsc_req = kmem_cache_zalloc(blkdev->request_pool, GFP_KERNEL);
323 if (!blkvsc_req)
324 return -ENOMEM;
325
326 page_buf = alloc_page(GFP_KERNEL);
327 if (!page_buf) {
328 kmem_cache_free(blkdev->request_pool, blkvsc_req);
329 return -ENOMEM;
330 }
331
332 vm_srb = &blkvsc_req->request.vstor_packet.vm_srb;
333 init_completion(&blkvsc_req->request.wait_event);
334 blkvsc_req->dev = blkdev;
335 blkvsc_req->req = NULL;
336 blkvsc_req->write = 0;
337
338 blkvsc_req->request.data_buffer.pfn_array[0] =
339 page_to_pfn(page_buf);
340 blkvsc_req->request.data_buffer.offset = 0;
341
342 switch (op) {
343 case DO_INQUIRY:
344 blkvsc_req->cmnd[0] = INQUIRY;
345 blkvsc_req->cmnd[1] = 0x1; /* Get product data */
346 blkvsc_req->cmnd[2] = 0x83; /* mode page 83 */
347 blkvsc_req->cmnd[4] = 64;
348 blkvsc_req->cmd_len = 6;
349 blkvsc_req->request.data_buffer.len = 64;
350 break;
351
352 case DO_CAPACITY:
353 blkdev->sector_size = 0;
354 blkdev->capacity = 0;
355
356 blkvsc_req->cmnd[0] = READ_CAPACITY;
357 blkvsc_req->cmd_len = 16;
358 blkvsc_req->request.data_buffer.len = 8;
359 break;
360
361 case DO_FLUSH:
362 blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE;
363 blkvsc_req->cmd_len = 10;
364 blkvsc_req->request.data_buffer.pfn_array[0] = 0;
365 blkvsc_req->request.data_buffer.len = 0;
366 break;
367 default:
368 ret = -EINVAL;
369 goto cleanup;
370 }
371
372 spin_lock_irqsave(&blkdev->lock, flags);
373 blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
374 spin_unlock_irqrestore(&blkdev->lock, flags);
375
376 wait_for_completion_interruptible(&blkvsc_req->request.wait_event);
377
378 /* check error */
379 if (vm_srb->scsi_status) {
380 scsi_normalize_sense(blkvsc_req->sense_buffer,
381 SCSI_SENSE_BUFFERSIZE, &sense_hdr);
382
383 return 0;
384 }
385
386 buf = kmap(page_buf);
387
388 switch (op) {
389 case DO_INQUIRY:
390 device_type = buf[0] & 0x1F;
391
392 if (device_type == 0x0)
393 blkdev->device_type = HARDDISK_TYPE;
394 else
395 blkdev->device_type = UNKNOWN_DEV_TYPE;
396
397 blkdev->device_id_len = buf[7];
398 if (blkdev->device_id_len > 64)
399 blkdev->device_id_len = 64;
400
401 memcpy(blkdev->device_id, &buf[8], blkdev->device_id_len);
402 break;
403
404 case DO_CAPACITY:
405 /* be to le */
406 blkdev->capacity =
407 ((buf[0] << 24) | (buf[1] << 16) |
408 (buf[2] << 8) | buf[3]) + 1;
409
410 blkdev->sector_size =
411 (buf[4] << 24) | (buf[5] << 16) |
412 (buf[6] << 8) | buf[7];
413 break;
414 default:
415 break;
416
417 }
418
419cleanup:
420
421 kunmap(page_buf);
422
423 __free_page(page_buf);
424
425 kmem_cache_free(blkdev->request_pool, blkvsc_req);
426
427 return ret;
428}
429
430
431static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev)
432{
433 struct blkvsc_request *pend_req, *tmp;
434 struct blkvsc_request *comp_req, *tmp2;
435 struct vmscsi_request *vm_srb;
436
437 int ret = 0;
438
439
440 /* Flush the pending list first */
441 list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
442 pend_entry) {
443 /*
444 * The pend_req could be part of a partially completed
445 * request. If so, complete those req first until we
446 * hit the pend_req
447 */
448 list_for_each_entry_safe(comp_req, tmp2,
449 &pend_req->group->blkvsc_req_list,
450 req_entry) {
451
452 if (comp_req == pend_req)
453 break;
454
455 list_del(&comp_req->req_entry);
456
457 if (comp_req->req) {
458 vm_srb =
459 &comp_req->request.vstor_packet.
460 vm_srb;
461 ret = __blk_end_request(comp_req->req,
462 (!vm_srb->scsi_status ? 0 : -EIO),
463 comp_req->sector_count *
464 blkdev->sector_size);
465
466 /* FIXME: shouldn't this do more than return? */
467 if (ret)
468 goto out;
469 }
470
471 kmem_cache_free(blkdev->request_pool, comp_req);
472 }
473
474 list_del(&pend_req->pend_entry);
475
476 list_del(&pend_req->req_entry);
477
478 if (comp_req->req) {
479 if (!__blk_end_request(pend_req->req, -EIO,
480 pend_req->sector_count *
481 blkdev->sector_size)) {
482 /*
483 * All the sectors have been xferred ie the
484 * request is done
485 */
486 kmem_cache_free(blkdev->request_pool,
487 pend_req->group);
488 }
489 }
490
491 kmem_cache_free(blkdev->request_pool, pend_req);
492 }
493
494out:
495 return ret;
496}
497
498
499/*
500 * blkvsc_remove() - Callback when our device is removed
501 */
502static int blkvsc_remove(struct hv_device *dev)
503{
504 struct block_device_context *blkdev = dev_get_drvdata(&dev->device);
505 unsigned long flags;
506
507
508 /* Get to a known state */
509 spin_lock_irqsave(&blkdev->lock, flags);
510
511 blkdev->shutting_down = 1;
512
513 blk_stop_queue(blkdev->gd->queue);
514
515 blkvsc_cancel_pending_reqs(blkdev);
516
517 spin_unlock_irqrestore(&blkdev->lock, flags);
518
519 blkvsc_do_operation(blkdev, DO_FLUSH);
520
521 if (blkdev->users == 0) {
522 del_gendisk(blkdev->gd);
523 put_disk(blkdev->gd);
524 blk_cleanup_queue(blkdev->gd->queue);
525
526 storvsc_dev_remove(blkdev->device_ctx);
527
528 kmem_cache_destroy(blkdev->request_pool);
529 kfree(blkdev);
530 }
531
532 return 0;
533}
534
535static void blkvsc_shutdown(struct hv_device *dev)
536{
537 struct block_device_context *blkdev = dev_get_drvdata(&dev->device);
538 unsigned long flags;
539
540 if (!blkdev)
541 return;
542
543 spin_lock_irqsave(&blkdev->lock, flags);
544
545 blkdev->shutting_down = 1;
546
547 blk_stop_queue(blkdev->gd->queue);
548
549 blkvsc_cancel_pending_reqs(blkdev);
550
551 spin_unlock_irqrestore(&blkdev->lock, flags);
552
553 blkvsc_do_operation(blkdev, DO_FLUSH);
554
555 /*
556 * Now wait for all outgoing I/O to be drained.
557 */
558 storvsc_wait_to_drain((struct storvsc_device *)dev->ext);
559
560}
561
562static int blkvsc_release(struct gendisk *disk, fmode_t mode)
563{
564 struct block_device_context *blkdev = disk->private_data;
565 unsigned long flags;
566
567 spin_lock_irqsave(&blkdev->lock, flags);
568
569 if ((--blkdev->users == 0) && (blkdev->shutting_down)) {
570 blk_stop_queue(blkdev->gd->queue);
571 spin_unlock_irqrestore(&blkdev->lock, flags);
572
573 blkvsc_do_operation(blkdev, DO_FLUSH);
574 del_gendisk(blkdev->gd);
575 put_disk(blkdev->gd);
576 blk_cleanup_queue(blkdev->gd->queue);
577
578 storvsc_dev_remove(blkdev->device_ctx);
579
580 kmem_cache_destroy(blkdev->request_pool);
581 kfree(blkdev);
582 } else
583 spin_unlock_irqrestore(&blkdev->lock, flags);
584
585 return 0;
586}
587
588
589/*
590 * We break the request into 1 or more blkvsc_requests and submit
591 * them. If we cant submit them all, we put them on the
592 * pending_list. The blkvsc_request() will work on the pending_list.
593 */
594static int blkvsc_do_request(struct block_device_context *blkdev,
595 struct request *req)
596{
597 struct bio *bio = NULL;
598 struct bio_vec *bvec = NULL;
599 struct bio_vec *prev_bvec = NULL;
600 struct blkvsc_request *blkvsc_req = NULL;
601 struct blkvsc_request *tmp;
602 int databuf_idx = 0;
603 int seg_idx = 0;
604 sector_t start_sector;
605 unsigned long num_sectors = 0;
606 int ret = 0;
607 int pending = 0;
608 struct blkvsc_request_group *group = NULL;
609
610 /* Create a group to tie req to list of blkvsc_reqs */
611 group = kmem_cache_zalloc(blkdev->request_pool, GFP_ATOMIC);
612 if (!group)
613 return -ENOMEM;
614
615 INIT_LIST_HEAD(&group->blkvsc_req_list);
616 group->outstanding = group->status = 0;
617
618 start_sector = blk_rq_pos(req);
619
620 /* foreach bio in the request */
621 if (req->bio) {
622 for (bio = req->bio; bio; bio = bio->bi_next) {
623 /*
624 * Map this bio into an existing or new storvsc request
625 */
626 bio_for_each_segment(bvec, bio, seg_idx) {
627 /* Get a new storvsc request */
628 /* 1st-time */
629 if ((!blkvsc_req) ||
630 (databuf_idx >= MAX_MULTIPAGE_BUFFER_COUNT)
631 /* hole at the begin of page */
632 || (bvec->bv_offset != 0) ||
633 /* hold at the end of page */
634 (prev_bvec &&
635 (prev_bvec->bv_len != PAGE_SIZE))) {
636 /* submit the prev one */
637 if (blkvsc_req) {
638 blkvsc_req->sector_start =
639 start_sector;
640 sector_div(
641 blkvsc_req->sector_start,
642 (blkdev->sector_size >> 9));
643
644 blkvsc_req->sector_count =
645 num_sectors /
646 (blkdev->sector_size >> 9);
647 blkvsc_init_rw(blkvsc_req);
648 }
649
650 /*
651 * Create new blkvsc_req to represent
652 * the current bvec
653 */
654 blkvsc_req =
655 kmem_cache_zalloc(
656 blkdev->request_pool, GFP_ATOMIC);
657 if (!blkvsc_req) {
658 /* free up everything */
659 list_for_each_entry_safe(
660 blkvsc_req, tmp,
661 &group->blkvsc_req_list,
662 req_entry) {
663 list_del(
664 &blkvsc_req->req_entry);
665 kmem_cache_free(
666 blkdev->request_pool,
667 blkvsc_req);
668 }
669
670 kmem_cache_free(
671 blkdev->request_pool, group);
672 return -ENOMEM;
673 }
674
675 memset(blkvsc_req, 0,
676 sizeof(struct blkvsc_request));
677
678 blkvsc_req->dev = blkdev;
679 blkvsc_req->req = req;
680 blkvsc_req->request.
681 data_buffer.offset
682 = bvec->bv_offset;
683 blkvsc_req->request.
684 data_buffer.len = 0;
685
686 /* Add to the group */
687 blkvsc_req->group = group;
688 blkvsc_req->group->outstanding++;
689 list_add_tail(&blkvsc_req->req_entry,
690 &blkvsc_req->group->blkvsc_req_list);
691
692 start_sector += num_sectors;
693 num_sectors = 0;
694 databuf_idx = 0;
695 }
696
697 /*
698 * Add the curr bvec/segment to the curr
699 * blkvsc_req
700 */
701 blkvsc_req->request.data_buffer.
702 pfn_array[databuf_idx]
703 = page_to_pfn(bvec->bv_page);
704 blkvsc_req->request.data_buffer.len
705 += bvec->bv_len;
706
707 prev_bvec = bvec;
708
709 databuf_idx++;
710 num_sectors += bvec->bv_len >> 9;
711
712 } /* bio_for_each_segment */
713
714 } /* rq_for_each_bio */
715 }
716
717 /* Handle the last one */
718 if (blkvsc_req) {
719 blkvsc_req->sector_start = start_sector;
720 sector_div(blkvsc_req->sector_start,
721 (blkdev->sector_size >> 9));
722
723 blkvsc_req->sector_count = num_sectors /
724 (blkdev->sector_size >> 9);
725
726 blkvsc_init_rw(blkvsc_req);
727 }
728
729 list_for_each_entry(blkvsc_req, &group->blkvsc_req_list, req_entry) {
730 if (pending) {
731
732 list_add_tail(&blkvsc_req->pend_entry,
733 &blkdev->pending_list);
734 } else {
735 ret = blkvsc_submit_request(blkvsc_req,
736 blkvsc_request_completion);
737 if (ret == -1) {
738 pending = 1;
739 list_add_tail(&blkvsc_req->pend_entry,
740 &blkdev->pending_list);
741 }
742
743 }
744 }
745
746 return pending;
747}
748
749static int blkvsc_do_pending_reqs(struct block_device_context *blkdev)
750{
751 struct blkvsc_request *pend_req, *tmp;
752 int ret = 0;
753
754 /* Flush the pending list first */
755 list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
756 pend_entry) {
757
758 ret = blkvsc_submit_request(pend_req,
759 blkvsc_request_completion);
760 if (ret != 0)
761 break;
762 else
763 list_del(&pend_req->pend_entry);
764 }
765
766 return ret;
767}
768
769
770static void blkvsc_request(struct request_queue *queue)
771{
772 struct block_device_context *blkdev = NULL;
773 struct request *req;
774 int ret = 0;
775
776 while ((req = blk_peek_request(queue)) != NULL) {
777
778 blkdev = req->rq_disk->private_data;
779 if (blkdev->shutting_down || req->cmd_type != REQ_TYPE_FS) {
780 __blk_end_request_cur(req, 0);
781 continue;
782 }
783
784 ret = blkvsc_do_pending_reqs(blkdev);
785
786 if (ret != 0) {
787 blk_stop_queue(queue);
788 break;
789 }
790
791 blk_start_request(req);
792
793 ret = blkvsc_do_request(blkdev, req);
794 if (ret > 0) {
795 blk_stop_queue(queue);
796 break;
797 } else if (ret < 0) {
798 blk_requeue_request(queue, req);
799 blk_stop_queue(queue);
800 break;
801 }
802 }
803}
804
805
806
807/* The one and only one */
808static struct hv_driver blkvsc_drv = {
809 .probe = blkvsc_probe,
810 .remove = blkvsc_remove,
811 .shutdown = blkvsc_shutdown,
812};
813
814static const struct block_device_operations block_ops = {
815 .owner = THIS_MODULE,
816 .open = blkvsc_open,
817 .release = blkvsc_release,
818 .getgeo = blkvsc_getgeo,
819 .ioctl = blkvsc_ioctl,
820};
821
822/*
823 * blkvsc_drv_init - BlkVsc driver initialization.
824 */
825static int blkvsc_drv_init(void)
826{
827 struct hv_driver *drv = &blkvsc_drv;
828 int ret;
829
830 BUILD_BUG_ON(sizeof(sector_t) != 8);
831
832 memcpy(&drv->dev_type, &dev_type, sizeof(struct hv_guid));
833 drv->driver.name = drv_name;
834
835 /* The driver belongs to vmbus */
836 ret = vmbus_child_driver_register(&drv->driver);
837
838 return ret;
839}
840
841
842static void blkvsc_drv_exit(void)
843{
844
845 vmbus_child_driver_unregister(&blkvsc_drv.driver);
846}
847
848/*
849 * blkvsc_probe - Add a new device for this driver
850 */
851static int blkvsc_probe(struct hv_device *dev)
852{
853 struct block_device_context *blkdev = NULL;
854 struct storvsc_device_info device_info;
855 struct storvsc_major_info major_info;
856 int ret = 0;
857
858 blkdev = kzalloc(sizeof(struct block_device_context), GFP_KERNEL);
859 if (!blkdev) {
860 ret = -ENOMEM;
861 goto cleanup;
862 }
863
864 INIT_LIST_HEAD(&blkdev->pending_list);
865
866 /* Initialize what we can here */
867 spin_lock_init(&blkdev->lock);
868
869
870 blkdev->request_pool = kmem_cache_create(dev_name(&dev->device),
871 sizeof(struct blkvsc_request), 0,
872 SLAB_HWCACHE_ALIGN, NULL);
873 if (!blkdev->request_pool) {
874 ret = -ENOMEM;
875 goto cleanup;
876 }
877
878
879 ret = blkvsc_device_add(dev, &device_info);
880 if (ret != 0)
881 goto cleanup;
882
883 blkdev->device_ctx = dev;
884 /* this identified the device 0 or 1 */
885 blkdev->target = device_info.target_id;
886 /* this identified the ide ctrl 0 or 1 */
887 blkdev->path = device_info.path_id;
888
889 dev_set_drvdata(&dev->device, blkdev);
890
891 ret = storvsc_get_major_info(&device_info, &major_info);
892
893 if (ret)
894 goto cleanup;
895
896 if (major_info.do_register) {
897 ret = register_blkdev(major_info.major, major_info.devname);
898
899 if (ret != 0) {
900 DPRINT_ERR(BLKVSC_DRV,
901 "register_blkdev() failed! ret %d", ret);
902 goto remove;
903 }
904 }
905
906 DPRINT_INFO(BLKVSC_DRV, "blkvsc registered for major %d!!",
907 major_info.major);
908
909 blkdev->gd = alloc_disk(BLKVSC_MINORS);
910 if (!blkdev->gd) {
911 ret = -1;
912 goto cleanup;
913 }
914
915 blkdev->gd->queue = blk_init_queue(blkvsc_request, &blkdev->lock);
916
917 blk_queue_max_segment_size(blkdev->gd->queue, PAGE_SIZE);
918 blk_queue_max_segments(blkdev->gd->queue, MAX_MULTIPAGE_BUFFER_COUNT);
919 blk_queue_segment_boundary(blkdev->gd->queue, PAGE_SIZE-1);
920 blk_queue_bounce_limit(blkdev->gd->queue, BLK_BOUNCE_ANY);
921 blk_queue_dma_alignment(blkdev->gd->queue, 511);
922
923 blkdev->gd->major = major_info.major;
924 if (major_info.index == 1 || major_info.index == 3)
925 blkdev->gd->first_minor = BLKVSC_MINORS;
926 else
927 blkdev->gd->first_minor = 0;
928 blkdev->gd->fops = &block_ops;
929 blkdev->gd->private_data = blkdev;
930 blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device);
931 sprintf(blkdev->gd->disk_name, "hd%c", 'a' + major_info.index);
932
933 blkvsc_do_operation(blkdev, DO_INQUIRY);
934 blkvsc_do_operation(blkdev, DO_CAPACITY);
935
936 set_capacity(blkdev->gd, blkdev->capacity * (blkdev->sector_size/512));
937 blk_queue_logical_block_size(blkdev->gd->queue, blkdev->sector_size);
938 /* go! */
939 add_disk(blkdev->gd);
940
941 DPRINT_INFO(BLKVSC_DRV, "%s added!! capacity %lu sector_size %d",
942 blkdev->gd->disk_name, (unsigned long)blkdev->capacity,
943 blkdev->sector_size);
944
945 return ret;
946
947remove:
948 storvsc_dev_remove(dev);
949
950cleanup:
951 if (blkdev) {
952 if (blkdev->request_pool) {
953 kmem_cache_destroy(blkdev->request_pool);
954 blkdev->request_pool = NULL;
955 }
956 kfree(blkdev);
957 blkdev = NULL;
958 }
959
960 return ret;
961}
962
963static void blkvsc_request_completion(struct hv_storvsc_request *request)
964{
965 struct blkvsc_request *blkvsc_req =
966 (struct blkvsc_request *)request->context;
967 struct block_device_context *blkdev =
968 (struct block_device_context *)blkvsc_req->dev;
969 unsigned long flags;
970 struct blkvsc_request *comp_req, *tmp;
971 struct vmscsi_request *vm_srb;
972
973
974 spin_lock_irqsave(&blkdev->lock, flags);
975
976 blkdev->num_outstanding_reqs--;
977 blkvsc_req->group->outstanding--;
978
979 /*
980 * Only start processing when all the blkvsc_reqs are
981 * completed. This guarantees no out-of-order blkvsc_req
982 * completion when calling end_that_request_first()
983 */
984 if (blkvsc_req->group->outstanding == 0) {
985 list_for_each_entry_safe(comp_req, tmp,
986 &blkvsc_req->group->blkvsc_req_list,
987 req_entry) {
988
989 list_del(&comp_req->req_entry);
990
991 vm_srb =
992 &comp_req->request.vstor_packet.vm_srb;
993 if (!__blk_end_request(comp_req->req,
994 (!vm_srb->scsi_status ? 0 : -EIO),
995 comp_req->sector_count * blkdev->sector_size)) {
996 /*
997 * All the sectors have been xferred ie the
998 * request is done
999 */
1000 kmem_cache_free(blkdev->request_pool,
1001 comp_req->group);
1002 }
1003
1004 kmem_cache_free(blkdev->request_pool, comp_req);
1005 }
1006
1007 if (!blkdev->shutting_down) {
1008 blkvsc_do_pending_reqs(blkdev);
1009 blk_start_queue(blkdev->gd->queue);
1010 blkvsc_request(blkdev->gd->queue);
1011 }
1012 }
1013
1014 spin_unlock_irqrestore(&blkdev->lock, flags);
1015}
1016
1017static void __exit blkvsc_exit(void)
1018{
1019 blkvsc_drv_exit();
1020}
1021
1022MODULE_LICENSE("GPL");
1023MODULE_VERSION(HV_DRV_VERSION);
1024MODULE_DESCRIPTION("Microsoft Hyper-V virtual block driver");
1025module_init(blkvsc_drv_init);
1026module_exit(blkvsc_exit);
diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c
new file mode 100644
index 00000000000..455f47a891f
--- /dev/null
+++ b/drivers/staging/hv/channel.c
@@ -0,0 +1,877 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 */
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/wait.h>
26#include <linux/mm.h>
27#include <linux/slab.h>
28#include <linux/module.h>
29
30#include "hyperv.h"
31#include "hyperv_vmbus.h"
32
33#define NUM_PAGES_SPANNED(addr, len) \
34((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT))
35
36/* Internal routines */
37static int create_gpadl_header(
38 void *kbuffer, /* must be phys and virt contiguous */
39 u32 size, /* page-size multiple */
40 struct vmbus_channel_msginfo **msginfo,
41 u32 *messagecount);
42static void vmbus_setevent(struct vmbus_channel *channel);
43
44/*
45 * vmbus_setevent- Trigger an event notification on the specified
46 * channel.
47 */
48static void vmbus_setevent(struct vmbus_channel *channel)
49{
50 struct hv_monitor_page *monitorpage;
51
52 if (channel->offermsg.monitor_allocated) {
53 /* Each u32 represents 32 channels */
54 sync_set_bit(channel->offermsg.child_relid & 31,
55 (unsigned long *) vmbus_connection.send_int_page +
56 (channel->offermsg.child_relid >> 5));
57
58 monitorpage = vmbus_connection.monitor_pages;
59 monitorpage++; /* Get the child to parent monitor page */
60
61 sync_set_bit(channel->monitor_bit,
62 (unsigned long *)&monitorpage->trigger_group
63 [channel->monitor_grp].pending);
64
65 } else {
66 vmbus_set_event(channel->offermsg.child_relid);
67 }
68}
69
70/*
71 * vmbus_get_debug_info -Retrieve various channel debug info
72 */
73void vmbus_get_debug_info(struct vmbus_channel *channel,
74 struct vmbus_channel_debug_info *debuginfo)
75{
76 struct hv_monitor_page *monitorpage;
77 u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
78 u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
79 /* u32 monitorBit = 1 << monitorOffset; */
80
81 debuginfo->relid = channel->offermsg.child_relid;
82 debuginfo->state = channel->state;
83 memcpy(&debuginfo->interfacetype,
84 &channel->offermsg.offer.if_type, sizeof(struct hv_guid));
85 memcpy(&debuginfo->interface_instance,
86 &channel->offermsg.offer.if_instance,
87 sizeof(struct hv_guid));
88
89 monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
90
91 debuginfo->monitorid = channel->offermsg.monitorid;
92
93 debuginfo->servermonitor_pending =
94 monitorpage->trigger_group[monitor_group].pending;
95 debuginfo->servermonitor_latency =
96 monitorpage->latency[monitor_group][monitor_offset];
97 debuginfo->servermonitor_connectionid =
98 monitorpage->parameter[monitor_group]
99 [monitor_offset].connectionid.u.id;
100
101 monitorpage++;
102
103 debuginfo->clientmonitor_pending =
104 monitorpage->trigger_group[monitor_group].pending;
105 debuginfo->clientmonitor_latency =
106 monitorpage->latency[monitor_group][monitor_offset];
107 debuginfo->clientmonitor_connectionid =
108 monitorpage->parameter[monitor_group]
109 [monitor_offset].connectionid.u.id;
110
111 hv_ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
112 hv_ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
113}
114
115/*
116 * vmbus_open - Open the specified channel.
117 */
118int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
119 u32 recv_ringbuffer_size, void *userdata, u32 userdatalen,
120 void (*onchannelcallback)(void *context), void *context)
121{
122 struct vmbus_channel_open_channel *openMsg;
123 struct vmbus_channel_msginfo *openInfo = NULL;
124 void *in, *out;
125 unsigned long flags;
126 int ret, t, err = 0;
127
128 newchannel->onchannel_callback = onchannelcallback;
129 newchannel->channel_callback_context = context;
130
131 /* Allocate the ring buffer */
132 out = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
133 get_order(send_ringbuffer_size + recv_ringbuffer_size));
134
135 if (!out)
136 return -ENOMEM;
137
138
139 in = (void *)((unsigned long)out + send_ringbuffer_size);
140
141 newchannel->ringbuffer_pages = out;
142 newchannel->ringbuffer_pagecount = (send_ringbuffer_size +
143 recv_ringbuffer_size) >> PAGE_SHIFT;
144
145 ret = hv_ringbuffer_init(
146 &newchannel->outbound, out, send_ringbuffer_size);
147
148 if (ret != 0) {
149 err = ret;
150 goto errorout;
151 }
152
153 ret = hv_ringbuffer_init(
154 &newchannel->inbound, in, recv_ringbuffer_size);
155 if (ret != 0) {
156 err = ret;
157 goto errorout;
158 }
159
160
161 /* Establish the gpadl for the ring buffer */
162 newchannel->ringbuffer_gpadlhandle = 0;
163
164 ret = vmbus_establish_gpadl(newchannel,
165 newchannel->outbound.ring_buffer,
166 send_ringbuffer_size +
167 recv_ringbuffer_size,
168 &newchannel->ringbuffer_gpadlhandle);
169
170 if (ret != 0) {
171 err = ret;
172 goto errorout;
173 }
174
175 /* Create and init the channel open message */
176 openInfo = kmalloc(sizeof(*openInfo) +
177 sizeof(struct vmbus_channel_open_channel),
178 GFP_KERNEL);
179 if (!openInfo) {
180 err = -ENOMEM;
181 goto errorout;
182 }
183
184 init_completion(&openInfo->waitevent);
185
186 openMsg = (struct vmbus_channel_open_channel *)openInfo->msg;
187 openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL;
188 openMsg->openid = newchannel->offermsg.child_relid;
189 openMsg->child_relid = newchannel->offermsg.child_relid;
190 openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
191 openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
192 PAGE_SHIFT;
193 openMsg->server_contextarea_gpadlhandle = 0;
194
195 if (userdatalen > MAX_USER_DEFINED_BYTES) {
196 err = -EINVAL;
197 goto errorout;
198 }
199
200 if (userdatalen)
201 memcpy(openMsg->userdata, userdata, userdatalen);
202
203 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
204 list_add_tail(&openInfo->msglistentry,
205 &vmbus_connection.chn_msg_list);
206 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
207
208 ret = vmbus_post_msg(openMsg,
209 sizeof(struct vmbus_channel_open_channel));
210
211 if (ret != 0)
212 goto cleanup;
213
214 t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ);
215 if (t == 0) {
216 err = -ETIMEDOUT;
217 goto errorout;
218 }
219
220
221 if (openInfo->response.open_result.status)
222 err = openInfo->response.open_result.status;
223
224cleanup:
225 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
226 list_del(&openInfo->msglistentry);
227 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
228
229 kfree(openInfo);
230 return err;
231
232errorout:
233 hv_ringbuffer_cleanup(&newchannel->outbound);
234 hv_ringbuffer_cleanup(&newchannel->inbound);
235 free_pages((unsigned long)out,
236 get_order(send_ringbuffer_size + recv_ringbuffer_size));
237 kfree(openInfo);
238 return err;
239}
240EXPORT_SYMBOL_GPL(vmbus_open);
241
242/*
243 * dump_gpadl_body - Dump the gpadl body message to the console for
244 * debugging purposes.
245 */
246static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len)
247{
248 int i;
249 int pfncount;
250
251 pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) /
252 sizeof(u64);
253
254 DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount);
255
256 for (i = 0; i < pfncount; i++)
257 DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu",
258 i, gpadl->pfn[i]);
259}
260
261/*
262 * dump_gpadl_header - Dump the gpadl header message to the console for
263 * debugging purposes.
264 */
265static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl)
266{
267 int i, j;
268 int pagecount;
269
270 DPRINT_DBG(VMBUS,
271 "gpadl header - relid %d, range count %d, range buflen %d",
272 gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen);
273 for (i = 0; i < gpadl->rangecount; i++) {
274 pagecount = gpadl->range[i].byte_count >> PAGE_SHIFT;
275 pagecount = (pagecount > 26) ? 26 : pagecount;
276
277 DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d "
278 "page count %d", i, gpadl->range[i].byte_count,
279 gpadl->range[i].byte_offset, pagecount);
280
281 for (j = 0; j < pagecount; j++)
282 DPRINT_DBG(VMBUS, "%d) pfn %llu", j,
283 gpadl->range[i].pfn_array[j]);
284 }
285}
286
287/*
288 * create_gpadl_header - Creates a gpadl for the specified buffer
289 */
290static int create_gpadl_header(void *kbuffer, u32 size,
291 struct vmbus_channel_msginfo **msginfo,
292 u32 *messagecount)
293{
294 int i;
295 int pagecount;
296 unsigned long long pfn;
297 struct vmbus_channel_gpadl_header *gpadl_header;
298 struct vmbus_channel_gpadl_body *gpadl_body;
299 struct vmbus_channel_msginfo *msgheader;
300 struct vmbus_channel_msginfo *msgbody = NULL;
301 u32 msgsize;
302
303 int pfnsum, pfncount, pfnleft, pfncurr, pfnsize;
304
305 pagecount = size >> PAGE_SHIFT;
306 pfn = virt_to_phys(kbuffer) >> PAGE_SHIFT;
307
308 /* do we need a gpadl body msg */
309 pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
310 sizeof(struct vmbus_channel_gpadl_header) -
311 sizeof(struct gpa_range);
312 pfncount = pfnsize / sizeof(u64);
313
314 if (pagecount > pfncount) {
315 /* we need a gpadl body */
316 /* fill in the header */
317 msgsize = sizeof(struct vmbus_channel_msginfo) +
318 sizeof(struct vmbus_channel_gpadl_header) +
319 sizeof(struct gpa_range) + pfncount * sizeof(u64);
320 msgheader = kzalloc(msgsize, GFP_KERNEL);
321 if (!msgheader)
322 goto nomem;
323
324 INIT_LIST_HEAD(&msgheader->submsglist);
325 msgheader->msgsize = msgsize;
326
327 gpadl_header = (struct vmbus_channel_gpadl_header *)
328 msgheader->msg;
329 gpadl_header->rangecount = 1;
330 gpadl_header->range_buflen = sizeof(struct gpa_range) +
331 pagecount * sizeof(u64);
332 gpadl_header->range[0].byte_offset = 0;
333 gpadl_header->range[0].byte_count = size;
334 for (i = 0; i < pfncount; i++)
335 gpadl_header->range[0].pfn_array[i] = pfn+i;
336 *msginfo = msgheader;
337 *messagecount = 1;
338
339 pfnsum = pfncount;
340 pfnleft = pagecount - pfncount;
341
342 /* how many pfns can we fit */
343 pfnsize = MAX_SIZE_CHANNEL_MESSAGE -
344 sizeof(struct vmbus_channel_gpadl_body);
345 pfncount = pfnsize / sizeof(u64);
346
347 /* fill in the body */
348 while (pfnleft) {
349 if (pfnleft > pfncount)
350 pfncurr = pfncount;
351 else
352 pfncurr = pfnleft;
353
354 msgsize = sizeof(struct vmbus_channel_msginfo) +
355 sizeof(struct vmbus_channel_gpadl_body) +
356 pfncurr * sizeof(u64);
357 msgbody = kzalloc(msgsize, GFP_KERNEL);
358
359 if (!msgbody) {
360 struct vmbus_channel_msginfo *pos = NULL;
361 struct vmbus_channel_msginfo *tmp = NULL;
362 /*
363 * Free up all the allocated messages.
364 */
365 list_for_each_entry_safe(pos, tmp,
366 &msgheader->submsglist,
367 msglistentry) {
368
369 list_del(&pos->msglistentry);
370 kfree(pos);
371 }
372
373 goto nomem;
374 }
375
376 msgbody->msgsize = msgsize;
377 (*messagecount)++;
378 gpadl_body =
379 (struct vmbus_channel_gpadl_body *)msgbody->msg;
380
381 /*
382 * Gpadl is u32 and we are using a pointer which could
383 * be 64-bit
384 * This is governed by the guest/host protocol and
385 * so the hypervisor gurantees that this is ok.
386 */
387 for (i = 0; i < pfncurr; i++)
388 gpadl_body->pfn[i] = pfn + pfnsum + i;
389
390 /* add to msg header */
391 list_add_tail(&msgbody->msglistentry,
392 &msgheader->submsglist);
393 pfnsum += pfncurr;
394 pfnleft -= pfncurr;
395 }
396 } else {
397 /* everything fits in a header */
398 msgsize = sizeof(struct vmbus_channel_msginfo) +
399 sizeof(struct vmbus_channel_gpadl_header) +
400 sizeof(struct gpa_range) + pagecount * sizeof(u64);
401 msgheader = kzalloc(msgsize, GFP_KERNEL);
402 if (msgheader == NULL)
403 goto nomem;
404 msgheader->msgsize = msgsize;
405
406 gpadl_header = (struct vmbus_channel_gpadl_header *)
407 msgheader->msg;
408 gpadl_header->rangecount = 1;
409 gpadl_header->range_buflen = sizeof(struct gpa_range) +
410 pagecount * sizeof(u64);
411 gpadl_header->range[0].byte_offset = 0;
412 gpadl_header->range[0].byte_count = size;
413 for (i = 0; i < pagecount; i++)
414 gpadl_header->range[0].pfn_array[i] = pfn+i;
415
416 *msginfo = msgheader;
417 *messagecount = 1;
418 }
419
420 return 0;
421nomem:
422 kfree(msgheader);
423 kfree(msgbody);
424 return -ENOMEM;
425}
426
427/*
428 * vmbus_establish_gpadl - Estabish a GPADL for the specified buffer
429 *
430 * @channel: a channel
431 * @kbuffer: from kmalloc
432 * @size: page-size multiple
433 * @gpadl_handle: some funky thing
434 */
435int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
436 u32 size, u32 *gpadl_handle)
437{
438 struct vmbus_channel_gpadl_header *gpadlmsg;
439 struct vmbus_channel_gpadl_body *gpadl_body;
440 /* struct vmbus_channel_gpadl_created *gpadlCreated; */
441 struct vmbus_channel_msginfo *msginfo = NULL;
442 struct vmbus_channel_msginfo *submsginfo;
443 u32 msgcount;
444 struct list_head *curr;
445 u32 next_gpadl_handle;
446 unsigned long flags;
447 int ret = 0;
448 int t;
449
450 next_gpadl_handle = atomic_read(&vmbus_connection.next_gpadl_handle);
451 atomic_inc(&vmbus_connection.next_gpadl_handle);
452
453 ret = create_gpadl_header(kbuffer, size, &msginfo, &msgcount);
454 if (ret)
455 return ret;
456
457 init_completion(&msginfo->waitevent);
458
459 gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg;
460 gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER;
461 gpadlmsg->child_relid = channel->offermsg.child_relid;
462 gpadlmsg->gpadl = next_gpadl_handle;
463
464 dump_gpadl_header(gpadlmsg);
465
466 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
467 list_add_tail(&msginfo->msglistentry,
468 &vmbus_connection.chn_msg_list);
469
470 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
471
472 ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
473 sizeof(*msginfo));
474 if (ret != 0)
475 goto cleanup;
476
477 if (msgcount > 1) {
478 list_for_each(curr, &msginfo->submsglist) {
479
480 submsginfo = (struct vmbus_channel_msginfo *)curr;
481 gpadl_body =
482 (struct vmbus_channel_gpadl_body *)submsginfo->msg;
483
484 gpadl_body->header.msgtype =
485 CHANNELMSG_GPADL_BODY;
486 gpadl_body->gpadl = next_gpadl_handle;
487
488 dump_gpadl_body(gpadl_body, submsginfo->msgsize -
489 sizeof(*submsginfo));
490 ret = vmbus_post_msg(gpadl_body,
491 submsginfo->msgsize -
492 sizeof(*submsginfo));
493 if (ret != 0)
494 goto cleanup;
495
496 }
497 }
498 t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
499 BUG_ON(t == 0);
500
501
502 /* At this point, we received the gpadl created msg */
503 *gpadl_handle = gpadlmsg->gpadl;
504
505cleanup:
506 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
507 list_del(&msginfo->msglistentry);
508 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
509
510 kfree(msginfo);
511 return ret;
512}
513EXPORT_SYMBOL_GPL(vmbus_establish_gpadl);
514
515/*
516 * vmbus_teardown_gpadl -Teardown the specified GPADL handle
517 */
518int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
519{
520 struct vmbus_channel_gpadl_teardown *msg;
521 struct vmbus_channel_msginfo *info;
522 unsigned long flags;
523 int ret, t;
524
525 /* ASSERT(gpadl_handle != 0); */
526
527 info = kmalloc(sizeof(*info) +
528 sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
529 if (!info)
530 return -ENOMEM;
531
532 init_completion(&info->waitevent);
533
534 msg = (struct vmbus_channel_gpadl_teardown *)info->msg;
535
536 msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN;
537 msg->child_relid = channel->offermsg.child_relid;
538 msg->gpadl = gpadl_handle;
539
540 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
541 list_add_tail(&info->msglistentry,
542 &vmbus_connection.chn_msg_list);
543 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
544 ret = vmbus_post_msg(msg,
545 sizeof(struct vmbus_channel_gpadl_teardown));
546
547 BUG_ON(ret != 0);
548 t = wait_for_completion_timeout(&info->waitevent, 5*HZ);
549 BUG_ON(t == 0);
550
551 /* Received a torndown response */
552 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
553 list_del(&info->msglistentry);
554 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
555
556 kfree(info);
557 return ret;
558}
559EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
560
561/*
562 * vmbus_close - Close the specified channel
563 */
564void vmbus_close(struct vmbus_channel *channel)
565{
566 struct vmbus_channel_close_channel *msg;
567 int ret;
568
569 /* Stop callback and cancel the timer asap */
570 channel->onchannel_callback = NULL;
571
572 /* Send a closing message */
573
574 msg = &channel->close_msg.msg;
575
576 msg->header.msgtype = CHANNELMSG_CLOSECHANNEL;
577 msg->child_relid = channel->offermsg.child_relid;
578
579 ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel));
580
581 BUG_ON(ret != 0);
582 /* Tear down the gpadl for the channel's ring buffer */
583 if (channel->ringbuffer_gpadlhandle)
584 vmbus_teardown_gpadl(channel,
585 channel->ringbuffer_gpadlhandle);
586
587 /* Cleanup the ring buffers for this channel */
588 hv_ringbuffer_cleanup(&channel->outbound);
589 hv_ringbuffer_cleanup(&channel->inbound);
590
591 free_pages((unsigned long)channel->ringbuffer_pages,
592 get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
593
594
595}
596EXPORT_SYMBOL_GPL(vmbus_close);
597
598/**
599 * vmbus_sendpacket() - Send the specified buffer on the given channel
600 * @channel: Pointer to vmbus_channel structure.
601 * @buffer: Pointer to the buffer you want to receive the data into.
602 * @bufferlen: Maximum size of what the the buffer will hold
603 * @requestid: Identifier of the request
604 * @type: Type of packet that is being send e.g. negotiate, time
605 * packet etc.
606 *
607 * Sends data in @buffer directly to hyper-v via the vmbus
608 * This will send the data unparsed to hyper-v.
609 *
610 * Mainly used by Hyper-V drivers.
611 */
612int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer,
613 u32 bufferlen, u64 requestid,
614 enum vmbus_packet_type type, u32 flags)
615{
616 struct vmpacket_descriptor desc;
617 u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
618 u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
619 struct scatterlist bufferlist[3];
620 u64 aligned_data = 0;
621 int ret;
622
623
624 /* Setup the descriptor */
625 desc.type = type; /* VmbusPacketTypeDataInBand; */
626 desc.flags = flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
627 /* in 8-bytes granularity */
628 desc.offset8 = sizeof(struct vmpacket_descriptor) >> 3;
629 desc.len8 = (u16)(packetlen_aligned >> 3);
630 desc.trans_id = requestid;
631
632 sg_init_table(bufferlist, 3);
633 sg_set_buf(&bufferlist[0], &desc, sizeof(struct vmpacket_descriptor));
634 sg_set_buf(&bufferlist[1], buffer, bufferlen);
635 sg_set_buf(&bufferlist[2], &aligned_data,
636 packetlen_aligned - packetlen);
637
638 ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
639
640 if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
641 vmbus_setevent(channel);
642
643 return ret;
644}
645EXPORT_SYMBOL(vmbus_sendpacket);
646
647/*
648 * vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
649 * packets using a GPADL Direct packet type.
650 */
651int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
652 struct hv_page_buffer pagebuffers[],
653 u32 pagecount, void *buffer, u32 bufferlen,
654 u64 requestid)
655{
656 int ret;
657 int i;
658 struct vmbus_channel_packet_page_buffer desc;
659 u32 descsize;
660 u32 packetlen;
661 u32 packetlen_aligned;
662 struct scatterlist bufferlist[3];
663 u64 aligned_data = 0;
664
665 if (pagecount > MAX_PAGE_BUFFER_COUNT)
666 return -EINVAL;
667
668
669 /*
670 * Adjust the size down since vmbus_channel_packet_page_buffer is the
671 * largest size we support
672 */
673 descsize = sizeof(struct vmbus_channel_packet_page_buffer) -
674 ((MAX_PAGE_BUFFER_COUNT - pagecount) *
675 sizeof(struct hv_page_buffer));
676 packetlen = descsize + bufferlen;
677 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
678
679 /* Setup the descriptor */
680 desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
681 desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
682 desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
683 desc.length8 = (u16)(packetlen_aligned >> 3);
684 desc.transactionid = requestid;
685 desc.rangecount = pagecount;
686
687 for (i = 0; i < pagecount; i++) {
688 desc.range[i].len = pagebuffers[i].len;
689 desc.range[i].offset = pagebuffers[i].offset;
690 desc.range[i].pfn = pagebuffers[i].pfn;
691 }
692
693 sg_init_table(bufferlist, 3);
694 sg_set_buf(&bufferlist[0], &desc, descsize);
695 sg_set_buf(&bufferlist[1], buffer, bufferlen);
696 sg_set_buf(&bufferlist[2], &aligned_data,
697 packetlen_aligned - packetlen);
698
699 ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
700
701 if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
702 vmbus_setevent(channel);
703
704 return ret;
705}
706EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
707
708/*
709 * vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
710 * using a GPADL Direct packet type.
711 */
712int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
713 struct hv_multipage_buffer *multi_pagebuffer,
714 void *buffer, u32 bufferlen, u64 requestid)
715{
716 int ret;
717 struct vmbus_channel_packet_multipage_buffer desc;
718 u32 descsize;
719 u32 packetlen;
720 u32 packetlen_aligned;
721 struct scatterlist bufferlist[3];
722 u64 aligned_data = 0;
723 u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
724 multi_pagebuffer->len);
725
726
727 if ((pfncount < 0) || (pfncount > MAX_MULTIPAGE_BUFFER_COUNT))
728 return -EINVAL;
729
730 /*
731 * Adjust the size down since vmbus_channel_packet_multipage_buffer is
732 * the largest size we support
733 */
734 descsize = sizeof(struct vmbus_channel_packet_multipage_buffer) -
735 ((MAX_MULTIPAGE_BUFFER_COUNT - pfncount) *
736 sizeof(u64));
737 packetlen = descsize + bufferlen;
738 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
739
740
741 /* Setup the descriptor */
742 desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
743 desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
744 desc.dataoffset8 = descsize >> 3; /* in 8-bytes grandularity */
745 desc.length8 = (u16)(packetlen_aligned >> 3);
746 desc.transactionid = requestid;
747 desc.rangecount = 1;
748
749 desc.range.len = multi_pagebuffer->len;
750 desc.range.offset = multi_pagebuffer->offset;
751
752 memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array,
753 pfncount * sizeof(u64));
754
755 sg_init_table(bufferlist, 3);
756 sg_set_buf(&bufferlist[0], &desc, descsize);
757 sg_set_buf(&bufferlist[1], buffer, bufferlen);
758 sg_set_buf(&bufferlist[2], &aligned_data,
759 packetlen_aligned - packetlen);
760
761 ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
762
763 if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
764 vmbus_setevent(channel);
765
766 return ret;
767}
768EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
769
770/**
771 * vmbus_recvpacket() - Retrieve the user packet on the specified channel
772 * @channel: Pointer to vmbus_channel structure.
773 * @buffer: Pointer to the buffer you want to receive the data into.
774 * @bufferlen: Maximum size of what the the buffer will hold
775 * @buffer_actual_len: The actual size of the data after it was received
776 * @requestid: Identifier of the request
777 *
778 * Receives directly from the hyper-v vmbus and puts the data it received
779 * into Buffer. This will receive the data unparsed from hyper-v.
780 *
781 * Mainly used by Hyper-V drivers.
782 */
783int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
784 u32 bufferlen, u32 *buffer_actual_len, u64 *requestid)
785{
786 struct vmpacket_descriptor desc;
787 u32 packetlen;
788 u32 userlen;
789 int ret;
790 unsigned long flags;
791
792 *buffer_actual_len = 0;
793 *requestid = 0;
794
795 spin_lock_irqsave(&channel->inbound_lock, flags);
796
797 ret = hv_ringbuffer_peek(&channel->inbound, &desc,
798 sizeof(struct vmpacket_descriptor));
799 if (ret != 0) {
800 spin_unlock_irqrestore(&channel->inbound_lock, flags);
801 return 0;
802 }
803
804 packetlen = desc.len8 << 3;
805 userlen = packetlen - (desc.offset8 << 3);
806
807 *buffer_actual_len = userlen;
808
809 if (userlen > bufferlen) {
810 spin_unlock_irqrestore(&channel->inbound_lock, flags);
811
812 pr_err("Buffer too small - got %d needs %d\n",
813 bufferlen, userlen);
814 return -ETOOSMALL;
815 }
816
817 *requestid = desc.trans_id;
818
819 /* Copy over the packet to the user buffer */
820 ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
821 (desc.offset8 << 3));
822
823 spin_unlock_irqrestore(&channel->inbound_lock, flags);
824
825 return 0;
826}
827EXPORT_SYMBOL(vmbus_recvpacket);
828
829/*
830 * vmbus_recvpacket_raw - Retrieve the raw packet on the specified channel
831 */
832int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
833 u32 bufferlen, u32 *buffer_actual_len,
834 u64 *requestid)
835{
836 struct vmpacket_descriptor desc;
837 u32 packetlen;
838 u32 userlen;
839 int ret;
840 unsigned long flags;
841
842 *buffer_actual_len = 0;
843 *requestid = 0;
844
845 spin_lock_irqsave(&channel->inbound_lock, flags);
846
847 ret = hv_ringbuffer_peek(&channel->inbound, &desc,
848 sizeof(struct vmpacket_descriptor));
849 if (ret != 0) {
850 spin_unlock_irqrestore(&channel->inbound_lock, flags);
851 return 0;
852 }
853
854
855 packetlen = desc.len8 << 3;
856 userlen = packetlen - (desc.offset8 << 3);
857
858 *buffer_actual_len = packetlen;
859
860 if (packetlen > bufferlen) {
861 spin_unlock_irqrestore(&channel->inbound_lock, flags);
862
863 pr_err("Buffer too small - needed %d bytes but "
864 "got space for only %d bytes\n",
865 packetlen, bufferlen);
866 return -2;
867 }
868
869 *requestid = desc.trans_id;
870
871 /* Copy over the entire packet to the user buffer */
872 ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
873
874 spin_unlock_irqrestore(&channel->inbound_lock, flags);
875 return 0;
876}
877EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
new file mode 100644
index 00000000000..bf011f3fb85
--- /dev/null
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -0,0 +1,784 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 */
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/wait.h>
26#include <linux/mm.h>
27#include <linux/slab.h>
28#include <linux/list.h>
29#include <linux/module.h>
30#include <linux/completion.h>
31
32#include "hyperv.h"
33#include "hyperv_vmbus.h"
34
35struct vmbus_channel_message_table_entry {
36 enum vmbus_channel_message_type message_type;
37 void (*message_handler)(struct vmbus_channel_message_header *msg);
38};
39
40#define MAX_MSG_TYPES 4
41#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8
42
43static const struct hv_guid
44 supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
45 /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
46 /* Storage - SCSI */
47 {
48 .data = {
49 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
50 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
51 }
52 },
53
54 /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
55 /* Network */
56 {
57 .data = {
58 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
59 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
60 }
61 },
62
63 /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
64 /* Input */
65 {
66 .data = {
67 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
68 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
69 }
70 },
71
72 /* {32412632-86cb-44a2-9b5c-50d1417354f5} */
73 /* IDE */
74 {
75 .data = {
76 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
77 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
78 }
79 },
80 /* 0E0B6031-5213-4934-818B-38D90CED39DB */
81 /* Shutdown */
82 {
83 .data = {
84 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
85 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
86 }
87 },
88 /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
89 /* TimeSync */
90 {
91 .data = {
92 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
93 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
94 }
95 },
96 /* {57164f39-9115-4e78-ab55-382f3bd5422d} */
97 /* Heartbeat */
98 {
99 .data = {
100 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
101 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
102 }
103 },
104 /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
105 /* KVP */
106 {
107 .data = {
108 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
109 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
110 }
111 },
112
113};
114
115
116/**
117 * prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
118 * @icmsghdrp: Pointer to msg header structure
119 * @icmsg_negotiate: Pointer to negotiate message structure
120 * @buf: Raw buffer channel data
121 *
122 * @icmsghdrp is of type &struct icmsg_hdr.
123 * @negop is of type &struct icmsg_negotiate.
124 * Set up and fill in default negotiate response message. This response can
125 * come from both the vmbus driver and the hv_utils driver. The current api
126 * will respond properly to both Windows 2008 and Windows 2008-R2 operating
127 * systems.
128 *
129 * Mainly used by Hyper-V drivers.
130 */
131void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
132 struct icmsg_negotiate *negop,
133 u8 *buf)
134{
135 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
136 icmsghdrp->icmsgsize = 0x10;
137
138 negop = (struct icmsg_negotiate *)&buf[
139 sizeof(struct vmbuspipe_hdr) +
140 sizeof(struct icmsg_hdr)];
141
142 if (negop->icframe_vercnt == 2 &&
143 negop->icversion_data[1].major == 3) {
144 negop->icversion_data[0].major = 3;
145 negop->icversion_data[0].minor = 0;
146 negop->icversion_data[1].major = 3;
147 negop->icversion_data[1].minor = 0;
148 } else {
149 negop->icversion_data[0].major = 1;
150 negop->icversion_data[0].minor = 0;
151 negop->icversion_data[1].major = 1;
152 negop->icversion_data[1].minor = 0;
153 }
154
155 negop->icframe_vercnt = 1;
156 negop->icmsg_vercnt = 1;
157 }
158}
159EXPORT_SYMBOL(prep_negotiate_resp);
160
161/**
162 * chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK
163 * Hyper-V requests
164 * @context: Pointer to argument structure.
165 *
166 * Set up the default handler for non device driver specific requests
167 * from Hyper-V. This stub responds to the default negotiate messages
168 * that come in for every non IDE/SCSI/Network request.
169 * This behavior is normally overwritten in the hv_utils driver. That
170 * driver handles requests like graceful shutdown, heartbeats etc.
171 *
172 * Mainly used by Hyper-V drivers.
173 */
174void chn_cb_negotiate(void *context)
175{
176 struct vmbus_channel *channel = context;
177 u8 *buf;
178 u32 buflen, recvlen;
179 u64 requestid;
180
181 struct icmsg_hdr *icmsghdrp;
182 struct icmsg_negotiate *negop = NULL;
183
184 if (channel->util_index >= 0) {
185 /*
186 * This is a properly initialized util channel.
187 * Route this callback appropriately and setup state
188 * so that we don't need to reroute again.
189 */
190 if (hv_cb_utils[channel->util_index].callback != NULL) {
191 /*
192 * The util driver has established a handler for
193 * this service; do the magic.
194 */
195 channel->onchannel_callback =
196 hv_cb_utils[channel->util_index].callback;
197 (hv_cb_utils[channel->util_index].callback)(channel);
198 return;
199 }
200 }
201
202 buflen = PAGE_SIZE;
203 buf = kmalloc(buflen, GFP_ATOMIC);
204
205 vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid);
206
207 if (recvlen > 0) {
208 icmsghdrp = (struct icmsg_hdr *)&buf[
209 sizeof(struct vmbuspipe_hdr)];
210
211 prep_negotiate_resp(icmsghdrp, negop, buf);
212
213 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
214 | ICMSGHDRFLAG_RESPONSE;
215
216 vmbus_sendpacket(channel, buf,
217 recvlen, requestid,
218 VM_PKT_DATA_INBAND, 0);
219 }
220
221 kfree(buf);
222}
223EXPORT_SYMBOL(chn_cb_negotiate);
224
225/*
226 * Function table used for message responses for non IDE/SCSI/Network type
227 * messages. (Such as KVP/Shutdown etc)
228 */
229struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
230 /* 0E0B6031-5213-4934-818B-38D90CED39DB */
231 /* Shutdown */
232 {
233 .msg_type = HV_SHUTDOWN_MSG,
234 .data = {
235 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
236 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
237 },
238 .log_msg = "Shutdown channel functionality initialized"
239 },
240
241 /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
242 /* TimeSync */
243 {
244 .msg_type = HV_TIMESYNC_MSG,
245 .data = {
246 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
247 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
248 },
249 .log_msg = "Timesync channel functionality initialized"
250 },
251 /* {57164f39-9115-4e78-ab55-382f3bd5422d} */
252 /* Heartbeat */
253 {
254 .msg_type = HV_HEARTBEAT_MSG,
255 .data = {
256 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
257 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
258 },
259 .log_msg = "Heartbeat channel functionality initialized"
260 },
261 /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
262 /* KVP */
263 {
264 .data = {
265 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
266 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
267 },
268 .log_msg = "KVP channel functionality initialized"
269 },
270};
271EXPORT_SYMBOL(hv_cb_utils);
272
273/*
274 * alloc_channel - Allocate and initialize a vmbus channel object
275 */
276static struct vmbus_channel *alloc_channel(void)
277{
278 struct vmbus_channel *channel;
279
280 channel = kzalloc(sizeof(*channel), GFP_ATOMIC);
281 if (!channel)
282 return NULL;
283
284 spin_lock_init(&channel->inbound_lock);
285
286 channel->controlwq = create_workqueue("hv_vmbus_ctl");
287 if (!channel->controlwq) {
288 kfree(channel);
289 return NULL;
290 }
291
292 return channel;
293}
294
295/*
296 * release_hannel - Release the vmbus channel object itself
297 */
298static void release_channel(struct work_struct *work)
299{
300 struct vmbus_channel *channel = container_of(work,
301 struct vmbus_channel,
302 work);
303
304 destroy_workqueue(channel->controlwq);
305
306 kfree(channel);
307}
308
309/*
310 * free_channel - Release the resources used by the vmbus channel object
311 */
312void free_channel(struct vmbus_channel *channel)
313{
314
315 /*
316 * We have to release the channel's workqueue/thread in the vmbus's
317 * workqueue/thread context
318 * ie we can't destroy ourselves.
319 */
320 INIT_WORK(&channel->work, release_channel);
321 queue_work(vmbus_connection.work_queue, &channel->work);
322}
323
324
325
326/*
327 * vmbus_process_rescind_offer -
328 * Rescind the offer by initiating a device removal
329 */
330static void vmbus_process_rescind_offer(struct work_struct *work)
331{
332 struct vmbus_channel *channel = container_of(work,
333 struct vmbus_channel,
334 work);
335
336 vmbus_child_device_unregister(channel->device_obj);
337}
338
339/*
340 * vmbus_process_offer - Process the offer by creating a channel/device
341 * associated with this offer
342 */
343static void vmbus_process_offer(struct work_struct *work)
344{
345 struct vmbus_channel *newchannel = container_of(work,
346 struct vmbus_channel,
347 work);
348 struct vmbus_channel *channel;
349 bool fnew = true;
350 int ret;
351 int cnt;
352 unsigned long flags;
353
354 /* The next possible work is rescind handling */
355 INIT_WORK(&newchannel->work, vmbus_process_rescind_offer);
356
357 /* Make sure this is a new offer */
358 spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
359
360 list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
361 if (!memcmp(&channel->offermsg.offer.if_type,
362 &newchannel->offermsg.offer.if_type,
363 sizeof(struct hv_guid)) &&
364 !memcmp(&channel->offermsg.offer.if_instance,
365 &newchannel->offermsg.offer.if_instance,
366 sizeof(struct hv_guid))) {
367 fnew = false;
368 break;
369 }
370 }
371
372 if (fnew)
373 list_add_tail(&newchannel->listentry,
374 &vmbus_connection.chn_list);
375
376 spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
377
378 if (!fnew) {
379 free_channel(newchannel);
380 return;
381 }
382
383 /*
384 * Start the process of binding this offer to the driver
385 * We need to set the DeviceObject field before calling
386 * vmbus_child_dev_add()
387 */
388 newchannel->device_obj = vmbus_child_device_create(
389 &newchannel->offermsg.offer.if_type,
390 &newchannel->offermsg.offer.if_instance,
391 newchannel);
392
393 /*
394 * Add the new device to the bus. This will kick off device-driver
395 * binding which eventually invokes the device driver's AddDevice()
396 * method.
397 */
398 ret = vmbus_child_device_register(newchannel->device_obj);
399 if (ret != 0) {
400 pr_err("unable to add child device object (relid %d)\n",
401 newchannel->offermsg.child_relid);
402
403 spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
404 list_del(&newchannel->listentry);
405 spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
406
407 free_channel(newchannel);
408 } else {
409 /*
410 * This state is used to indicate a successful open
411 * so that when we do close the channel normally, we
412 * can cleanup properly
413 */
414 newchannel->state = CHANNEL_OPEN_STATE;
415 newchannel->util_index = -1; /* Invalid index */
416
417 /* Open IC channels */
418 for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
419 if (memcmp(&newchannel->offermsg.offer.if_type,
420 &hv_cb_utils[cnt].data,
421 sizeof(struct hv_guid)) == 0 &&
422 vmbus_open(newchannel, 2 * PAGE_SIZE,
423 2 * PAGE_SIZE, NULL, 0,
424 chn_cb_negotiate,
425 newchannel) == 0) {
426 hv_cb_utils[cnt].channel = newchannel;
427 newchannel->util_index = cnt;
428
429 pr_info("%s\n", hv_cb_utils[cnt].log_msg);
430
431 }
432 }
433 }
434}
435
436/*
437 * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
438 *
439 * We ignore all offers except network and storage offers. For each network and
440 * storage offers, we create a channel object and queue a work item to the
441 * channel object to process the offer synchronously
442 */
443static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
444{
445 struct vmbus_channel_offer_channel *offer;
446 struct vmbus_channel *newchannel;
447 struct hv_guid *guidtype;
448 struct hv_guid *guidinstance;
449 int i;
450 int fsupported = 0;
451
452 offer = (struct vmbus_channel_offer_channel *)hdr;
453 for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
454 if (memcmp(&offer->offer.if_type,
455 &supported_device_classes[i],
456 sizeof(struct hv_guid)) == 0) {
457 fsupported = 1;
458 break;
459 }
460 }
461
462 if (!fsupported)
463 return;
464
465 guidtype = &offer->offer.if_type;
466 guidinstance = &offer->offer.if_instance;
467
468 /* Allocate the channel object and save this offer. */
469 newchannel = alloc_channel();
470 if (!newchannel) {
471 pr_err("Unable to allocate channel object\n");
472 return;
473 }
474
475 memcpy(&newchannel->offermsg, offer,
476 sizeof(struct vmbus_channel_offer_channel));
477 newchannel->monitor_grp = (u8)offer->monitorid / 32;
478 newchannel->monitor_bit = (u8)offer->monitorid % 32;
479
480 INIT_WORK(&newchannel->work, vmbus_process_offer);
481 queue_work(newchannel->controlwq, &newchannel->work);
482}
483
484/*
485 * vmbus_onoffer_rescind - Rescind offer handler.
486 *
487 * We queue a work item to process this offer synchronously
488 */
489static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
490{
491 struct vmbus_channel_rescind_offer *rescind;
492 struct vmbus_channel *channel;
493
494 rescind = (struct vmbus_channel_rescind_offer *)hdr;
495 channel = relid2channel(rescind->child_relid);
496
497 if (channel == NULL)
498 /* Just return here, no channel found */
499 return;
500
501 /* work is initialized for vmbus_process_rescind_offer() from
502 * vmbus_process_offer() where the channel got created */
503 queue_work(channel->controlwq, &channel->work);
504}
505
506/*
507 * vmbus_onoffers_delivered -
508 * This is invoked when all offers have been delivered.
509 *
510 * Nothing to do here.
511 */
512static void vmbus_onoffers_delivered(
513 struct vmbus_channel_message_header *hdr)
514{
515}
516
517/*
518 * vmbus_onopen_result - Open result handler.
519 *
520 * This is invoked when we received a response to our channel open request.
521 * Find the matching request, copy the response and signal the requesting
522 * thread.
523 */
524static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr)
525{
526 struct vmbus_channel_open_result *result;
527 struct vmbus_channel_msginfo *msginfo;
528 struct vmbus_channel_message_header *requestheader;
529 struct vmbus_channel_open_channel *openmsg;
530 unsigned long flags;
531
532 result = (struct vmbus_channel_open_result *)hdr;
533
534 /*
535 * Find the open msg, copy the result and signal/unblock the wait event
536 */
537 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
538
539 list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
540 msglistentry) {
541 requestheader =
542 (struct vmbus_channel_message_header *)msginfo->msg;
543
544 if (requestheader->msgtype == CHANNELMSG_OPENCHANNEL) {
545 openmsg =
546 (struct vmbus_channel_open_channel *)msginfo->msg;
547 if (openmsg->child_relid == result->child_relid &&
548 openmsg->openid == result->openid) {
549 memcpy(&msginfo->response.open_result,
550 result,
551 sizeof(
552 struct vmbus_channel_open_result));
553 complete(&msginfo->waitevent);
554 break;
555 }
556 }
557 }
558 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
559}
560
561/*
562 * vmbus_ongpadl_created - GPADL created handler.
563 *
564 * This is invoked when we received a response to our gpadl create request.
565 * Find the matching request, copy the response and signal the requesting
566 * thread.
567 */
568static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr)
569{
570 struct vmbus_channel_gpadl_created *gpadlcreated;
571 struct vmbus_channel_msginfo *msginfo;
572 struct vmbus_channel_message_header *requestheader;
573 struct vmbus_channel_gpadl_header *gpadlheader;
574 unsigned long flags;
575
576 gpadlcreated = (struct vmbus_channel_gpadl_created *)hdr;
577
578 /*
579 * Find the establish msg, copy the result and signal/unblock the wait
580 * event
581 */
582 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
583
584 list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
585 msglistentry) {
586 requestheader =
587 (struct vmbus_channel_message_header *)msginfo->msg;
588
589 if (requestheader->msgtype == CHANNELMSG_GPADL_HEADER) {
590 gpadlheader =
591 (struct vmbus_channel_gpadl_header *)requestheader;
592
593 if ((gpadlcreated->child_relid ==
594 gpadlheader->child_relid) &&
595 (gpadlcreated->gpadl == gpadlheader->gpadl)) {
596 memcpy(&msginfo->response.gpadl_created,
597 gpadlcreated,
598 sizeof(
599 struct vmbus_channel_gpadl_created));
600 complete(&msginfo->waitevent);
601 break;
602 }
603 }
604 }
605 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
606}
607
608/*
609 * vmbus_ongpadl_torndown - GPADL torndown handler.
610 *
611 * This is invoked when we received a response to our gpadl teardown request.
612 * Find the matching request, copy the response and signal the requesting
613 * thread.
614 */
615static void vmbus_ongpadl_torndown(
616 struct vmbus_channel_message_header *hdr)
617{
618 struct vmbus_channel_gpadl_torndown *gpadl_torndown;
619 struct vmbus_channel_msginfo *msginfo;
620 struct vmbus_channel_message_header *requestheader;
621 struct vmbus_channel_gpadl_teardown *gpadl_teardown;
622 unsigned long flags;
623
624 gpadl_torndown = (struct vmbus_channel_gpadl_torndown *)hdr;
625
626 /*
627 * Find the open msg, copy the result and signal/unblock the wait event
628 */
629 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
630
631 list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
632 msglistentry) {
633 requestheader =
634 (struct vmbus_channel_message_header *)msginfo->msg;
635
636 if (requestheader->msgtype == CHANNELMSG_GPADL_TEARDOWN) {
637 gpadl_teardown =
638 (struct vmbus_channel_gpadl_teardown *)requestheader;
639
640 if (gpadl_torndown->gpadl == gpadl_teardown->gpadl) {
641 memcpy(&msginfo->response.gpadl_torndown,
642 gpadl_torndown,
643 sizeof(
644 struct vmbus_channel_gpadl_torndown));
645 complete(&msginfo->waitevent);
646 break;
647 }
648 }
649 }
650 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
651}
652
653/*
654 * vmbus_onversion_response - Version response handler
655 *
656 * This is invoked when we received a response to our initiate contact request.
657 * Find the matching request, copy the response and signal the requesting
658 * thread.
659 */
660static void vmbus_onversion_response(
661 struct vmbus_channel_message_header *hdr)
662{
663 struct vmbus_channel_msginfo *msginfo;
664 struct vmbus_channel_message_header *requestheader;
665 struct vmbus_channel_initiate_contact *initiate;
666 struct vmbus_channel_version_response *version_response;
667 unsigned long flags;
668
669 version_response = (struct vmbus_channel_version_response *)hdr;
670 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
671
672 list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
673 msglistentry) {
674 requestheader =
675 (struct vmbus_channel_message_header *)msginfo->msg;
676
677 if (requestheader->msgtype ==
678 CHANNELMSG_INITIATE_CONTACT) {
679 initiate =
680 (struct vmbus_channel_initiate_contact *)requestheader;
681 memcpy(&msginfo->response.version_response,
682 version_response,
683 sizeof(struct vmbus_channel_version_response));
684 complete(&msginfo->waitevent);
685 }
686 }
687 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
688}
689
690/* Channel message dispatch table */
691static struct vmbus_channel_message_table_entry
692 channel_message_table[CHANNELMSG_COUNT] = {
693 {CHANNELMSG_INVALID, NULL},
694 {CHANNELMSG_OFFERCHANNEL, vmbus_onoffer},
695 {CHANNELMSG_RESCIND_CHANNELOFFER, vmbus_onoffer_rescind},
696 {CHANNELMSG_REQUESTOFFERS, NULL},
697 {CHANNELMSG_ALLOFFERS_DELIVERED, vmbus_onoffers_delivered},
698 {CHANNELMSG_OPENCHANNEL, NULL},
699 {CHANNELMSG_OPENCHANNEL_RESULT, vmbus_onopen_result},
700 {CHANNELMSG_CLOSECHANNEL, NULL},
701 {CHANNELMSG_GPADL_HEADER, NULL},
702 {CHANNELMSG_GPADL_BODY, NULL},
703 {CHANNELMSG_GPADL_CREATED, vmbus_ongpadl_created},
704 {CHANNELMSG_GPADL_TEARDOWN, NULL},
705 {CHANNELMSG_GPADL_TORNDOWN, vmbus_ongpadl_torndown},
706 {CHANNELMSG_RELID_RELEASED, NULL},
707 {CHANNELMSG_INITIATE_CONTACT, NULL},
708 {CHANNELMSG_VERSION_RESPONSE, vmbus_onversion_response},
709 {CHANNELMSG_UNLOAD, NULL},
710};
711
712/*
713 * vmbus_onmessage - Handler for channel protocol messages.
714 *
715 * This is invoked in the vmbus worker thread context.
716 */
717void vmbus_onmessage(void *context)
718{
719 struct hv_message *msg = context;
720 struct vmbus_channel_message_header *hdr;
721 int size;
722
723 hdr = (struct vmbus_channel_message_header *)msg->u.payload;
724 size = msg->header.payload_size;
725
726 if (hdr->msgtype >= CHANNELMSG_COUNT) {
727 pr_err("Received invalid channel message type %d size %d\n",
728 hdr->msgtype, size);
729 print_hex_dump_bytes("", DUMP_PREFIX_NONE,
730 (unsigned char *)msg->u.payload, size);
731 return;
732 }
733
734 if (channel_message_table[hdr->msgtype].message_handler)
735 channel_message_table[hdr->msgtype].message_handler(hdr);
736 else
737 pr_err("Unhandled channel message type %d\n", hdr->msgtype);
738}
739
740/*
741 * vmbus_request_offers - Send a request to get all our pending offers.
742 */
743int vmbus_request_offers(void)
744{
745 struct vmbus_channel_message_header *msg;
746 struct vmbus_channel_msginfo *msginfo;
747 int ret, t;
748
749 msginfo = kmalloc(sizeof(*msginfo) +
750 sizeof(struct vmbus_channel_message_header),
751 GFP_KERNEL);
752 if (!msginfo)
753 return -ENOMEM;
754
755 init_completion(&msginfo->waitevent);
756
757 msg = (struct vmbus_channel_message_header *)msginfo->msg;
758
759 msg->msgtype = CHANNELMSG_REQUESTOFFERS;
760
761
762 ret = vmbus_post_msg(msg,
763 sizeof(struct vmbus_channel_message_header));
764 if (ret != 0) {
765 pr_err("Unable to request offers - %d\n", ret);
766
767 goto cleanup;
768 }
769
770 t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
771 if (t == 0) {
772 ret = -ETIMEDOUT;
773 goto cleanup;
774 }
775
776
777
778cleanup:
779 kfree(msginfo);
780
781 return ret;
782}
783
784/* eof */
diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
new file mode 100644
index 00000000000..e6b40392e08
--- /dev/null
+++ b/drivers/staging/hv/connection.c
@@ -0,0 +1,290 @@
1/*
2 *
3 * Copyright (c) 2009, 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 *
22 */
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/kernel.h>
26#include <linux/sched.h>
27#include <linux/wait.h>
28#include <linux/mm.h>
29#include <linux/slab.h>
30#include <linux/vmalloc.h>
31
32#include "hyperv.h"
33#include "hyperv_vmbus.h"
34
35
36struct vmbus_connection vmbus_connection = {
37 .conn_state = DISCONNECTED,
38 .next_gpadl_handle = ATOMIC_INIT(0xE1E10),
39};
40
41/*
42 * vmbus_connect - Sends a connect request on the partition service connection
43 */
44int vmbus_connect(void)
45{
46 int ret = 0;
47 int t;
48 struct vmbus_channel_msginfo *msginfo = NULL;
49 struct vmbus_channel_initiate_contact *msg;
50 unsigned long flags;
51
52 /* Make sure we are not connecting or connected */
53 if (vmbus_connection.conn_state != DISCONNECTED)
54 return -EISCONN;
55
56 /* Initialize the vmbus connection */
57 vmbus_connection.conn_state = CONNECTING;
58 vmbus_connection.work_queue = create_workqueue("hv_vmbus_con");
59 if (!vmbus_connection.work_queue) {
60 ret = -ENOMEM;
61 goto cleanup;
62 }
63
64 INIT_LIST_HEAD(&vmbus_connection.chn_msg_list);
65 spin_lock_init(&vmbus_connection.channelmsg_lock);
66
67 INIT_LIST_HEAD(&vmbus_connection.chn_list);
68 spin_lock_init(&vmbus_connection.channel_lock);
69
70 /*
71 * Setup the vmbus event connection for channel interrupt
72 * abstraction stuff
73 */
74 vmbus_connection.int_page =
75 (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0);
76 if (vmbus_connection.int_page == NULL) {
77 ret = -ENOMEM;
78 goto cleanup;
79 }
80
81 vmbus_connection.recv_int_page = vmbus_connection.int_page;
82 vmbus_connection.send_int_page =
83 (void *)((unsigned long)vmbus_connection.int_page +
84 (PAGE_SIZE >> 1));
85
86 /*
87 * Setup the monitor notification facility. The 1st page for
88 * parent->child and the 2nd page for child->parent
89 */
90 vmbus_connection.monitor_pages =
91 (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1);
92 if (vmbus_connection.monitor_pages == NULL) {
93 ret = -ENOMEM;
94 goto cleanup;
95 }
96
97 msginfo = kzalloc(sizeof(*msginfo) +
98 sizeof(struct vmbus_channel_initiate_contact),
99 GFP_KERNEL);
100 if (msginfo == NULL) {
101 ret = -ENOMEM;
102 goto cleanup;
103 }
104
105 init_completion(&msginfo->waitevent);
106
107 msg = (struct vmbus_channel_initiate_contact *)msginfo->msg;
108
109 msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT;
110 msg->vmbus_version_requested = VMBUS_REVISION_NUMBER;
111 msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
112 msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages);
113 msg->monitor_page2 = virt_to_phys(
114 (void *)((unsigned long)vmbus_connection.monitor_pages +
115 PAGE_SIZE));
116
117 /*
118 * Add to list before we send the request since we may
119 * receive the response before returning from this routine
120 */
121 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
122 list_add_tail(&msginfo->msglistentry,
123 &vmbus_connection.chn_msg_list);
124
125 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
126
127 ret = vmbus_post_msg(msg,
128 sizeof(struct vmbus_channel_initiate_contact));
129 if (ret != 0) {
130 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
131 list_del(&msginfo->msglistentry);
132 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock,
133 flags);
134 goto cleanup;
135 }
136
137 /* Wait for the connection response */
138 t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
139 if (t == 0) {
140 spin_lock_irqsave(&vmbus_connection.channelmsg_lock,
141 flags);
142 list_del(&msginfo->msglistentry);
143 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock,
144 flags);
145 ret = -ETIMEDOUT;
146 goto cleanup;
147 }
148
149 spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
150 list_del(&msginfo->msglistentry);
151 spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
152
153 /* Check if successful */
154 if (msginfo->response.version_response.version_supported) {
155 vmbus_connection.conn_state = CONNECTED;
156 } else {
157 pr_err("Unable to connect, "
158 "Version %d not supported by Hyper-V\n",
159 VMBUS_REVISION_NUMBER);
160 ret = -ECONNREFUSED;
161 goto cleanup;
162 }
163
164 kfree(msginfo);
165 return 0;
166
167cleanup:
168 vmbus_connection.conn_state = DISCONNECTED;
169
170 if (vmbus_connection.work_queue)
171 destroy_workqueue(vmbus_connection.work_queue);
172
173 if (vmbus_connection.int_page) {
174 free_pages((unsigned long)vmbus_connection.int_page, 0);
175 vmbus_connection.int_page = NULL;
176 }
177
178 if (vmbus_connection.monitor_pages) {
179 free_pages((unsigned long)vmbus_connection.monitor_pages, 1);
180 vmbus_connection.monitor_pages = NULL;
181 }
182
183 kfree(msginfo);
184
185 return ret;
186}
187
188
189/*
190 * relid2channel - Get the channel object given its
191 * child relative id (ie channel id)
192 */
193struct vmbus_channel *relid2channel(u32 relid)
194{
195 struct vmbus_channel *channel;
196 struct vmbus_channel *found_channel = NULL;
197 unsigned long flags;
198
199 spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
200 list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
201 if (channel->offermsg.child_relid == relid) {
202 found_channel = channel;
203 break;
204 }
205 }
206 spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
207
208 return found_channel;
209}
210
211/*
212 * process_chn_event - Process a channel event notification
213 */
214static void process_chn_event(u32 relid)
215{
216 struct vmbus_channel *channel;
217
218 /* ASSERT(relId > 0); */
219
220 /*
221 * Find the channel based on this relid and invokes the
222 * channel callback to process the event
223 */
224 channel = relid2channel(relid);
225
226 if (channel) {
227 channel->onchannel_callback(channel->channel_callback_context);
228 } else {
229 pr_err("channel not found for relid - %u\n", relid);
230 }
231}
232
233/*
234 * vmbus_on_event - Handler for events
235 */
236void vmbus_on_event(unsigned long data)
237{
238 u32 dword;
239 u32 maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
240 int bit;
241 u32 relid;
242 u32 *recv_int_page = vmbus_connection.recv_int_page;
243
244 /* Check events */
245 if (!recv_int_page)
246 return;
247 for (dword = 0; dword < maxdword; dword++) {
248 if (!recv_int_page[dword])
249 continue;
250 for (bit = 0; bit < 32; bit++) {
251 if (sync_test_and_clear_bit(bit, (unsigned long *)&recv_int_page[dword])) {
252 relid = (dword << 5) + bit;
253
254 if (relid == 0) {
255 /*
256 * Special case - vmbus
257 * channel protocol msg
258 */
259 continue;
260 }
261 process_chn_event(relid);
262 }
263 }
264 }
265}
266
267/*
268 * vmbus_post_msg - Send a msg on the vmbus's message connection
269 */
270int vmbus_post_msg(void *buffer, size_t buflen)
271{
272 union hv_connection_id conn_id;
273
274 conn_id.asu32 = 0;
275 conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
276 return hv_post_message(conn_id, 1, buffer, buflen);
277}
278
279/*
280 * vmbus_set_event - Send an event notification to the parent
281 */
282int vmbus_set_event(u32 child_relid)
283{
284 /* Each u32 represents 32 channels */
285 sync_set_bit(child_relid & 31,
286 (unsigned long *)vmbus_connection.send_int_page +
287 (child_relid >> 5));
288
289 return hv_signal_event();
290}
diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c
new file mode 100644
index 00000000000..824f81679ae
--- /dev/null
+++ b/drivers/staging/hv/hv.c
@@ -0,0 +1,438 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 *
21 */
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24#include <linux/kernel.h>
25#include <linux/mm.h>
26#include <linux/slab.h>
27#include <linux/vmalloc.h>
28
29#include "hyperv.h"
30#include "hyperv_vmbus.h"
31
32/* The one and only */
33struct hv_context hv_context = {
34 .synic_initialized = false,
35 .hypercall_page = NULL,
36 .signal_event_param = NULL,
37 .signal_event_buffer = NULL,
38};
39
40/*
41 * query_hypervisor_presence
42 * - Query the cpuid for presence of windows hypervisor
43 */
44static int query_hypervisor_presence(void)
45{
46 unsigned int eax;
47 unsigned int ebx;
48 unsigned int ecx;
49 unsigned int edx;
50 unsigned int op;
51
52 eax = 0;
53 ebx = 0;
54 ecx = 0;
55 edx = 0;
56 op = HVCPUID_VERSION_FEATURES;
57 cpuid(op, &eax, &ebx, &ecx, &edx);
58
59 return ecx & HV_PRESENT_BIT;
60}
61
62/*
63 * query_hypervisor_info - Get version info of the windows hypervisor
64 */
65static int query_hypervisor_info(void)
66{
67 unsigned int eax;
68 unsigned int ebx;
69 unsigned int ecx;
70 unsigned int edx;
71 unsigned int max_leaf;
72 unsigned int op;
73
74 /*
75 * Its assumed that this is called after confirming that Viridian
76 * is present. Query id and revision.
77 */
78 eax = 0;
79 ebx = 0;
80 ecx = 0;
81 edx = 0;
82 op = HVCPUID_VENDOR_MAXFUNCTION;
83 cpuid(op, &eax, &ebx, &ecx, &edx);
84
85 max_leaf = eax;
86
87 if (max_leaf >= HVCPUID_VERSION) {
88 eax = 0;
89 ebx = 0;
90 ecx = 0;
91 edx = 0;
92 op = HVCPUID_VERSION;
93 cpuid(op, &eax, &ebx, &ecx, &edx);
94 pr_info("Hyper-V Host OS Build:%d-%d.%d-%d-%d.%d\n",
95 eax,
96 ebx >> 16,
97 ebx & 0xFFFF,
98 ecx,
99 edx >> 24,
100 edx & 0xFFFFFF);
101 }
102 return max_leaf;
103}
104
105/*
106 * do_hypercall- Invoke the specified hypercall
107 */
108static u64 do_hypercall(u64 control, void *input, void *output)
109{
110#ifdef CONFIG_X86_64
111 u64 hv_status = 0;
112 u64 input_address = (input) ? virt_to_phys(input) : 0;
113 u64 output_address = (output) ? virt_to_phys(output) : 0;
114 volatile void *hypercall_page = hv_context.hypercall_page;
115
116 __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
117 __asm__ __volatile__("call *%3" : "=a" (hv_status) :
118 "c" (control), "d" (input_address),
119 "m" (hypercall_page));
120
121 return hv_status;
122
123#else
124
125 u32 control_hi = control >> 32;
126 u32 control_lo = control & 0xFFFFFFFF;
127 u32 hv_status_hi = 1;
128 u32 hv_status_lo = 1;
129 u64 input_address = (input) ? virt_to_phys(input) : 0;
130 u32 input_address_hi = input_address >> 32;
131 u32 input_address_lo = input_address & 0xFFFFFFFF;
132 u64 output_address = (output) ? virt_to_phys(output) : 0;
133 u32 output_address_hi = output_address >> 32;
134 u32 output_address_lo = output_address & 0xFFFFFFFF;
135 volatile void *hypercall_page = hv_context.hypercall_page;
136
137 __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
138 "=a"(hv_status_lo) : "d" (control_hi),
139 "a" (control_lo), "b" (input_address_hi),
140 "c" (input_address_lo), "D"(output_address_hi),
141 "S"(output_address_lo), "m" (hypercall_page));
142
143 return hv_status_lo | ((u64)hv_status_hi << 32);
144#endif /* !x86_64 */
145}
146
147/*
148 * hv_init - Main initialization routine.
149 *
150 * This routine must be called before any other routines in here are called
151 */
152int hv_init(void)
153{
154 int ret = 0;
155 int max_leaf;
156 union hv_x64_msr_hypercall_contents hypercall_msr;
157 void *virtaddr = NULL;
158
159 memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS);
160 memset(hv_context.synic_message_page, 0,
161 sizeof(void *) * MAX_NUM_CPUS);
162
163 if (!query_hypervisor_presence())
164 goto cleanup;
165
166 max_leaf = query_hypervisor_info();
167 /* HvQueryHypervisorFeatures(maxLeaf); */
168
169 /*
170 * We only support running on top of Hyper-V
171 */
172 rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);
173
174 if (hv_context.guestid != 0)
175 goto cleanup;
176
177 /* Write our OS info */
178 wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
179 hv_context.guestid = HV_LINUX_GUEST_ID;
180
181 /* See if the hypercall page is already set */
182 rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
183
184 /*
185 * Allocate the hypercall page memory
186 * virtaddr = osd_page_alloc(1);
187 */
188 virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC);
189
190 if (!virtaddr)
191 goto cleanup;
192
193 hypercall_msr.enable = 1;
194
195 hypercall_msr.guest_physical_address = vmalloc_to_pfn(virtaddr);
196 wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
197
198 /* Confirm that hypercall page did get setup. */
199 hypercall_msr.as_uint64 = 0;
200 rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
201
202 if (!hypercall_msr.enable)
203 goto cleanup;
204
205 hv_context.hypercall_page = virtaddr;
206
207 /* Setup the global signal event param for the signal event hypercall */
208 hv_context.signal_event_buffer =
209 kmalloc(sizeof(struct hv_input_signal_event_buffer),
210 GFP_KERNEL);
211 if (!hv_context.signal_event_buffer)
212 goto cleanup;
213
214 hv_context.signal_event_param =
215 (struct hv_input_signal_event *)
216 (ALIGN((unsigned long)
217 hv_context.signal_event_buffer,
218 HV_HYPERCALL_PARAM_ALIGN));
219 hv_context.signal_event_param->connectionid.asu32 = 0;
220 hv_context.signal_event_param->connectionid.u.id =
221 VMBUS_EVENT_CONNECTION_ID;
222 hv_context.signal_event_param->flag_number = 0;
223 hv_context.signal_event_param->rsvdz = 0;
224
225 return ret;
226
227cleanup:
228 if (virtaddr) {
229 if (hypercall_msr.enable) {
230 hypercall_msr.as_uint64 = 0;
231 wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
232 }
233
234 vfree(virtaddr);
235 }
236 ret = -1;
237 return ret;
238}
239
240/*
241 * hv_cleanup - Cleanup routine.
242 *
243 * This routine is called normally during driver unloading or exiting.
244 */
245void hv_cleanup(void)
246{
247 union hv_x64_msr_hypercall_contents hypercall_msr;
248
249 kfree(hv_context.signal_event_buffer);
250 hv_context.signal_event_buffer = NULL;
251 hv_context.signal_event_param = NULL;
252
253 if (hv_context.hypercall_page) {
254 hypercall_msr.as_uint64 = 0;
255 wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
256 vfree(hv_context.hypercall_page);
257 hv_context.hypercall_page = NULL;
258 }
259}
260
261/*
262 * hv_post_message - Post a message using the hypervisor message IPC.
263 *
264 * This involves a hypercall.
265 */
266u16 hv_post_message(union hv_connection_id connection_id,
267 enum hv_message_type message_type,
268 void *payload, size_t payload_size)
269{
270 struct aligned_input {
271 u64 alignment8;
272 struct hv_input_post_message msg;
273 };
274
275 struct hv_input_post_message *aligned_msg;
276 u16 status;
277 unsigned long addr;
278
279 if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
280 return -EMSGSIZE;
281
282 addr = (unsigned long)kmalloc(sizeof(struct aligned_input), GFP_ATOMIC);
283 if (!addr)
284 return -ENOMEM;
285
286 aligned_msg = (struct hv_input_post_message *)
287 (ALIGN(addr, HV_HYPERCALL_PARAM_ALIGN));
288
289 aligned_msg->connectionid = connection_id;
290 aligned_msg->message_type = message_type;
291 aligned_msg->payload_size = payload_size;
292 memcpy((void *)aligned_msg->payload, payload, payload_size);
293
294 status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
295 & 0xFFFF;
296
297 kfree((void *)addr);
298
299 return status;
300}
301
302
303/*
304 * hv_signal_event -
305 * Signal an event on the specified connection using the hypervisor event IPC.
306 *
307 * This involves a hypercall.
308 */
309u16 hv_signal_event(void)
310{
311 u16 status;
312
313 status = do_hypercall(HVCALL_SIGNAL_EVENT,
314 hv_context.signal_event_param,
315 NULL) & 0xFFFF;
316 return status;
317}
318
319/*
320 * hv_synic_init - Initialize the Synthethic Interrupt Controller.
321 *
322 * If it is already initialized by another entity (ie x2v shim), we need to
323 * retrieve the initialized message and event pages. Otherwise, we create and
324 * initialize the message and event pages.
325 */
326void hv_synic_init(void *irqarg)
327{
328 u64 version;
329 union hv_synic_simp simp;
330 union hv_synic_siefp siefp;
331 union hv_synic_sint shared_sint;
332 union hv_synic_scontrol sctrl;
333
334 u32 irq_vector = *((u32 *)(irqarg));
335 int cpu = smp_processor_id();
336
337 if (!hv_context.hypercall_page)
338 return;
339
340 /* Check the version */
341 rdmsrl(HV_X64_MSR_SVERSION, version);
342
343 hv_context.synic_message_page[cpu] =
344 (void *)get_zeroed_page(GFP_ATOMIC);
345
346 if (hv_context.synic_message_page[cpu] == NULL) {
347 pr_err("Unable to allocate SYNIC message page\n");
348 goto cleanup;
349 }
350
351 hv_context.synic_event_page[cpu] =
352 (void *)get_zeroed_page(GFP_ATOMIC);
353
354 if (hv_context.synic_event_page[cpu] == NULL) {
355 pr_err("Unable to allocate SYNIC event page\n");
356 goto cleanup;
357 }
358
359 /* Setup the Synic's message page */
360 rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
361 simp.simp_enabled = 1;
362 simp.base_simp_gpa = virt_to_phys(hv_context.synic_message_page[cpu])
363 >> PAGE_SHIFT;
364
365 wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
366
367 /* Setup the Synic's event page */
368 rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
369 siefp.siefp_enabled = 1;
370 siefp.base_siefp_gpa = virt_to_phys(hv_context.synic_event_page[cpu])
371 >> PAGE_SHIFT;
372
373 wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
374
375 /* Setup the shared SINT. */
376 rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
377
378 shared_sint.as_uint64 = 0;
379 shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
380 shared_sint.masked = false;
381 shared_sint.auto_eoi = true;
382
383 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
384
385 /* Enable the global synic bit */
386 rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
387 sctrl.enable = 1;
388
389 wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
390
391 hv_context.synic_initialized = true;
392 return;
393
394cleanup:
395 if (hv_context.synic_event_page[cpu])
396 free_page((unsigned long)hv_context.synic_event_page[cpu]);
397
398 if (hv_context.synic_message_page[cpu])
399 free_page((unsigned long)hv_context.synic_message_page[cpu]);
400 return;
401}
402
403/*
404 * hv_synic_cleanup - Cleanup routine for hv_synic_init().
405 */
406void hv_synic_cleanup(void *arg)
407{
408 union hv_synic_sint shared_sint;
409 union hv_synic_simp simp;
410 union hv_synic_siefp siefp;
411 int cpu = smp_processor_id();
412
413 if (!hv_context.synic_initialized)
414 return;
415
416 rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
417
418 shared_sint.masked = 1;
419
420 /* Need to correctly cleanup in the case of SMP!!! */
421 /* Disable the interrupt */
422 wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
423
424 rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
425 simp.simp_enabled = 0;
426 simp.base_simp_gpa = 0;
427
428 wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
429
430 rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
431 siefp.siefp_enabled = 0;
432 siefp.base_siefp_gpa = 0;
433
434 wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
435
436 free_page((unsigned long)hv_context.synic_message_page[cpu]);
437 free_page((unsigned long)hv_context.synic_event_page[cpu]);
438}
diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/staging/hv/hv_kvp.c
new file mode 100644
index 00000000000..13b0ecf7d5d
--- /dev/null
+++ b/drivers/staging/hv/hv_kvp.c
@@ -0,0 +1,334 @@
1/*
2 * An implementation of key value pair (KVP) functionality for Linux.
3 *
4 *
5 * Copyright (C) 2010, Novell, Inc.
6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/net.h>
26#include <linux/nls.h>
27#include <linux/connector.h>
28#include <linux/workqueue.h>
29
30#include "hyperv.h"
31#include "hv_kvp.h"
32
33
34
35/*
36 * Global state maintained for transaction that is being processed.
37 * Note that only one transaction can be active at any point in time.
38 *
39 * This state is set when we receive a request from the host; we
40 * cleanup this state when the transaction is completed - when we respond
41 * to the host with the key value.
42 */
43
44static struct {
45 bool active; /* transaction status - active or not */
46 int recv_len; /* number of bytes received. */
47 struct vmbus_channel *recv_channel; /* chn we got the request */
48 u64 recv_req_id; /* request ID. */
49} kvp_transaction;
50
51static int kvp_send_key(int index);
52
53static void kvp_respond_to_host(char *key, char *value, int error);
54static void kvp_work_func(struct work_struct *dummy);
55static void kvp_register(void);
56
57static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func);
58
59static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL };
60static const char kvp_name[] = "kvp_kernel_module";
61static int timeout_fired;
62static u8 *recv_buffer;
63/*
64 * Register the kernel component with the user-level daemon.
65 * As part of this registration, pass the LIC version number.
66 */
67
68static void
69kvp_register(void)
70{
71
72 struct cn_msg *msg;
73
74 msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC);
75
76 if (msg) {
77 msg->id.idx = CN_KVP_IDX;
78 msg->id.val = CN_KVP_VAL;
79 msg->seq = KVP_REGISTER;
80 strcpy(msg->data, HV_DRV_VERSION);
81 msg->len = strlen(HV_DRV_VERSION) + 1;
82 cn_netlink_send(msg, 0, GFP_ATOMIC);
83 kfree(msg);
84 }
85}
86static void
87kvp_work_func(struct work_struct *dummy)
88{
89 /*
90 * If the timer fires, the user-mode component has not responded;
91 * process the pending transaction.
92 */
93 kvp_respond_to_host("Unknown key", "Guest timed out", timeout_fired);
94 timeout_fired = 1;
95}
96
97/*
98 * Callback when data is received from user mode.
99 */
100
101static void
102kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
103{
104 struct hv_ku_msg *message;
105
106 message = (struct hv_ku_msg *)msg->data;
107 if (msg->seq == KVP_REGISTER) {
108 pr_info("KVP: user-mode registering done.\n");
109 kvp_register();
110 }
111
112 if (msg->seq == KVP_USER_SET) {
113 /*
114 * Complete the transaction by forwarding the key value
115 * to the host. But first, cancel the timeout.
116 */
117 if (cancel_delayed_work_sync(&kvp_work))
118 kvp_respond_to_host(message->kvp_key,
119 message->kvp_value,
120 !strlen(message->kvp_key));
121 }
122}
123
124static int
125kvp_send_key(int index)
126{
127 struct cn_msg *msg;
128
129 msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
130
131 if (msg) {
132 msg->id.idx = CN_KVP_IDX;
133 msg->id.val = CN_KVP_VAL;
134 msg->seq = KVP_KERNEL_GET;
135 ((struct hv_ku_msg *)msg->data)->kvp_index = index;
136 msg->len = sizeof(struct hv_ku_msg);
137 cn_netlink_send(msg, 0, GFP_ATOMIC);
138 kfree(msg);
139 return 0;
140 }
141 return 1;
142}
143
144/*
145 * Send a response back to the host.
146 */
147
148static void
149kvp_respond_to_host(char *key, char *value, int error)
150{
151 struct hv_kvp_msg *kvp_msg;
152 struct hv_kvp_msg_enumerate *kvp_data;
153 char *key_name;
154 struct icmsg_hdr *icmsghdrp;
155 int keylen, valuelen;
156 u32 buf_len;
157 struct vmbus_channel *channel;
158 u64 req_id;
159
160 /*
161 * If a transaction is not active; log and return.
162 */
163
164 if (!kvp_transaction.active) {
165 /*
166 * This is a spurious call!
167 */
168 pr_warn("KVP: Transaction not active\n");
169 return;
170 }
171 /*
172 * Copy the global state for completing the transaction. Note that
173 * only one transaction can be active at a time.
174 */
175
176 buf_len = kvp_transaction.recv_len;
177 channel = kvp_transaction.recv_channel;
178 req_id = kvp_transaction.recv_req_id;
179
180 icmsghdrp = (struct icmsg_hdr *)
181 &recv_buffer[sizeof(struct vmbuspipe_hdr)];
182 kvp_msg = (struct hv_kvp_msg *)
183 &recv_buffer[sizeof(struct vmbuspipe_hdr) +
184 sizeof(struct icmsg_hdr)];
185 kvp_data = &kvp_msg->kvp_data;
186 key_name = key;
187
188 /*
189 * If the error parameter is set, terminate the host's enumeration.
190 */
191 if (error) {
192 /*
193 * We don't support this index or the we have timedout;
194 * terminate the host-side iteration by returning an error.
195 */
196 icmsghdrp->status = HV_E_FAIL;
197 goto response_done;
198 }
199
200 /*
201 * The windows host expects the key/value pair to be encoded
202 * in utf16.
203 */
204 keylen = utf8s_to_utf16s(key_name, strlen(key_name),
205 (wchar_t *)kvp_data->data.key);
206 kvp_data->data.key_size = 2*(keylen + 1); /* utf16 encoding */
207 valuelen = utf8s_to_utf16s(value, strlen(value),
208 (wchar_t *)kvp_data->data.value);
209 kvp_data->data.value_size = 2*(valuelen + 1); /* utf16 encoding */
210
211 kvp_data->data.value_type = REG_SZ; /* all our values are strings */
212 icmsghdrp->status = HV_S_OK;
213
214response_done:
215 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
216
217 vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
218 VM_PKT_DATA_INBAND, 0);
219
220 kvp_transaction.active = false;
221}
222
223/*
224 * This callback is invoked when we get a KVP message from the host.
225 * The host ensures that only one KVP transaction can be active at a time.
226 * KVP implementation in Linux needs to forward the key to a user-mde
227 * component to retrive the corresponding value. Consequently, we cannot
228 * respond to the host in the conext of this callback. Since the host
229 * guarantees that at most only one transaction can be active at a time,
230 * we stash away the transaction state in a set of global variables.
231 */
232
233void hv_kvp_onchannelcallback(void *context)
234{
235 struct vmbus_channel *channel = context;
236 u32 recvlen;
237 u64 requestid;
238
239 struct hv_kvp_msg *kvp_msg;
240 struct hv_kvp_msg_enumerate *kvp_data;
241
242 struct icmsg_hdr *icmsghdrp;
243 struct icmsg_negotiate *negop = NULL;
244
245
246 if (kvp_transaction.active)
247 return;
248
249
250 vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid);
251
252 if (recvlen > 0) {
253 icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
254 sizeof(struct vmbuspipe_hdr)];
255
256 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
257 prep_negotiate_resp(icmsghdrp, negop, recv_buffer);
258 } else {
259 kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
260 sizeof(struct vmbuspipe_hdr) +
261 sizeof(struct icmsg_hdr)];
262
263 kvp_data = &kvp_msg->kvp_data;
264
265 /*
266 * We only support the "get" operation on
267 * "KVP_POOL_AUTO" pool.
268 */
269
270 if ((kvp_msg->kvp_hdr.pool != KVP_POOL_AUTO) ||
271 (kvp_msg->kvp_hdr.operation !=
272 KVP_OP_ENUMERATE)) {
273 icmsghdrp->status = HV_E_FAIL;
274 goto callback_done;
275 }
276
277 /*
278 * Stash away this global state for completing the
279 * transaction; note transactions are serialized.
280 */
281 kvp_transaction.recv_len = recvlen;
282 kvp_transaction.recv_channel = channel;
283 kvp_transaction.recv_req_id = requestid;
284 kvp_transaction.active = true;
285
286 /*
287 * Get the information from the
288 * user-mode component.
289 * component. This transaction will be
290 * completed when we get the value from
291 * the user-mode component.
292 * Set a timeout to deal with
293 * user-mode not responding.
294 */
295 kvp_send_key(kvp_data->index);
296 schedule_delayed_work(&kvp_work, 100);
297
298 return;
299
300 }
301
302callback_done:
303
304 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
305 | ICMSGHDRFLAG_RESPONSE;
306
307 vmbus_sendpacket(channel, recv_buffer,
308 recvlen, requestid,
309 VM_PKT_DATA_INBAND, 0);
310 }
311
312}
313
314int
315hv_kvp_init(void)
316{
317 int err;
318
319 err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback);
320 if (err)
321 return err;
322 recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
323 if (!recv_buffer)
324 return -ENOMEM;
325
326 return 0;
327}
328
329void hv_kvp_deinit(void)
330{
331 cn_del_callback(&kvp_id);
332 cancel_delayed_work_sync(&kvp_work);
333 kfree(recv_buffer);
334}
diff --git a/drivers/staging/hv/hv_kvp.h b/drivers/staging/hv/hv_kvp.h
new file mode 100644
index 00000000000..8c402f357d3
--- /dev/null
+++ b/drivers/staging/hv/hv_kvp.h
@@ -0,0 +1,184 @@
1/*
2 * An implementation of HyperV key value pair (KVP) functionality for Linux.
3 *
4 *
5 * Copyright (C) 2010, Novell, Inc.
6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23#ifndef _KVP_H
24#define _KVP_H_
25
26/*
27 * Maximum value size - used for both key names and value data, and includes
28 * any applicable NULL terminators.
29 *
30 * Note: This limit is somewhat arbitrary, but falls easily within what is
31 * supported for all native guests (back to Win 2000) and what is reasonable
32 * for the IC KVP exchange functionality. Note that Windows Me/98/95 are
33 * limited to 255 character key names.
34 *
35 * MSDN recommends not storing data values larger than 2048 bytes in the
36 * registry.
37 *
38 * Note: This value is used in defining the KVP exchange message - this value
39 * cannot be modified without affecting the message size and compatibility.
40 */
41
42/*
43 * bytes, including any null terminators
44 */
45#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048)
46
47
48/*
49 * Maximum key size - the registry limit for the length of an entry name
50 * is 256 characters, including the null terminator
51 */
52
53#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512)
54
55/*
56 * In Linux, we implement the KVP functionality in two components:
57 * 1) The kernel component which is packaged as part of the hv_utils driver
58 * is responsible for communicating with the host and responsible for
59 * implementing the host/guest protocol. 2) A user level daemon that is
60 * responsible for data gathering.
61 *
62 * Host/Guest Protocol: The host iterates over an index and expects the guest
63 * to assign a key name to the index and also return the value corresponding to
64 * the key. The host will have atmost one KVP transaction outstanding at any
65 * given point in time. The host side iteration stops when the guest returns
66 * an error. Microsoft has specified the following mapping of key names to
67 * host specified index:
68 *
69 * Index Key Name
70 * 0 FullyQualifiedDomainName
71 * 1 IntegrationServicesVersion
72 * 2 NetworkAddressIPv4
73 * 3 NetworkAddressIPv6
74 * 4 OSBuildNumber
75 * 5 OSName
76 * 6 OSMajorVersion
77 * 7 OSMinorVersion
78 * 8 OSVersion
79 * 9 ProcessorArchitecture
80 *
81 * The Windows host expects the Key Name and Key Value to be encoded in utf16.
82 *
83 * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the
84 * data gathering functionality in a user mode daemon. The user level daemon
85 * is also responsible for binding the key name to the index as well. The
86 * kernel and user-level daemon communicate using a connector channel.
87 *
88 * The user mode component first registers with the
89 * the kernel component. Subsequently, the kernel component requests, data
90 * for the specified keys. In response to this message the user mode component
91 * fills in the value corresponding to the specified key. We overload the
92 * sequence field in the cn_msg header to define our KVP message types.
93 *
94 *
95 * The kernel component simply acts as a conduit for communication between the
96 * Windows host and the user-level daemon. The kernel component passes up the
97 * index received from the Host to the user-level daemon. If the index is
98 * valid (supported), the corresponding key as well as its
99 * value (both are strings) is returned. If the index is invalid
100 * (not supported), a NULL key string is returned.
101 */
102
103/*
104 *
105 * The following definitions are shared with the user-mode component; do not
106 * change any of this without making the corresponding changes in
107 * the KVP user-mode component.
108 */
109
110#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */
111#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */
112
113enum hv_ku_op {
114 KVP_REGISTER = 0, /* Register the user mode component */
115 KVP_KERNEL_GET, /* Kernel is requesting the value */
116 KVP_KERNEL_SET, /* Kernel is providing the value */
117 KVP_USER_GET, /* User is requesting the value */
118 KVP_USER_SET /* User is providing the value */
119};
120
121struct hv_ku_msg {
122 __u32 kvp_index; /* Key index */
123 __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */
124 __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */
125};
126
127
128
129
130#ifdef __KERNEL__
131
132/*
133 * Registry value types.
134 */
135
136#define REG_SZ 1
137
138enum hv_kvp_exchg_op {
139 KVP_OP_GET = 0,
140 KVP_OP_SET,
141 KVP_OP_DELETE,
142 KVP_OP_ENUMERATE,
143 KVP_OP_COUNT /* Number of operations, must be last. */
144};
145
146enum hv_kvp_exchg_pool {
147 KVP_POOL_EXTERNAL = 0,
148 KVP_POOL_GUEST,
149 KVP_POOL_AUTO,
150 KVP_POOL_AUTO_EXTERNAL,
151 KVP_POOL_AUTO_INTERNAL,
152 KVP_POOL_COUNT /* Number of pools, must be last. */
153};
154
155struct hv_kvp_hdr {
156 u8 operation;
157 u8 pool;
158};
159
160struct hv_kvp_exchg_msg_value {
161 u32 value_type;
162 u32 key_size;
163 u32 value_size;
164 u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
165 u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
166};
167
168struct hv_kvp_msg_enumerate {
169 u32 index;
170 struct hv_kvp_exchg_msg_value data;
171};
172
173struct hv_kvp_msg {
174 struct hv_kvp_hdr kvp_hdr;
175 struct hv_kvp_msg_enumerate kvp_data;
176};
177
178int hv_kvp_init(void);
179void hv_kvp_deinit(void);
180void hv_kvp_onchannelcallback(void *);
181
182#endif /* __KERNEL__ */
183#endif /* _KVP_H */
184
diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c
new file mode 100644
index 00000000000..d957fc22801
--- /dev/null
+++ b/drivers/staging/hv/hv_mouse.c
@@ -0,0 +1,974 @@
1/*
2 * Copyright (c) 2009, Citrix Systems, Inc.
3 * Copyright (c) 2010, Microsoft Corporation.
4 * Copyright (c) 2011, Novell Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 */
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/workqueue.h>
20#include <linux/sched.h>
21#include <linux/wait.h>
22#include <linux/input.h>
23#include <linux/hid.h>
24#include <linux/hiddev.h>
25#include <linux/pci.h>
26#include <linux/dmi.h>
27
28#include "hyperv.h"
29
30
31/*
32 * Data types
33 */
34struct hv_input_dev_info {
35 unsigned short vendor;
36 unsigned short product;
37 unsigned short version;
38 char name[128];
39};
40
41/* The maximum size of a synthetic input message. */
42#define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
43
44/*
45 * Current version
46 *
47 * History:
48 * Beta, RC < 2008/1/22 1,0
49 * RC > 2008/1/22 2,0
50 */
51#define SYNTHHID_INPUT_VERSION_MAJOR 2
52#define SYNTHHID_INPUT_VERSION_MINOR 0
53#define SYNTHHID_INPUT_VERSION (SYNTHHID_INPUT_VERSION_MINOR | \
54 (SYNTHHID_INPUT_VERSION_MAJOR << 16))
55
56
57#pragma pack(push,1)
58/*
59 * Message types in the synthetic input protocol
60 */
61enum synthhid_msg_type {
62 SynthHidProtocolRequest,
63 SynthHidProtocolResponse,
64 SynthHidInitialDeviceInfo,
65 SynthHidInitialDeviceInfoAck,
66 SynthHidInputReport,
67 SynthHidMax
68};
69
70/*
71 * Basic message structures.
72 */
73struct synthhid_msg_hdr {
74 enum synthhid_msg_type type;
75 u32 size;
76};
77
78struct synthhid_msg {
79 struct synthhid_msg_hdr header;
80 char data[1]; /* Enclosed message */
81};
82
83union synthhid_version {
84 struct {
85 u16 minor_version;
86 u16 major_version;
87 };
88 u32 version;
89};
90
91/*
92 * Protocol messages
93 */
94struct synthhid_protocol_request {
95 struct synthhid_msg_hdr header;
96 union synthhid_version version_requested;
97};
98
99struct synthhid_protocol_response {
100 struct synthhid_msg_hdr header;
101 union synthhid_version version_requested;
102 unsigned char approved;
103};
104
105struct synthhid_device_info {
106 struct synthhid_msg_hdr header;
107 struct hv_input_dev_info hid_dev_info;
108 struct hid_descriptor hid_descriptor;
109};
110
111struct synthhid_device_info_ack {
112 struct synthhid_msg_hdr header;
113 unsigned char reserved;
114};
115
116struct synthhid_input_report {
117 struct synthhid_msg_hdr header;
118 char buffer[1];
119};
120
121#pragma pack(pop)
122
123#define INPUTVSC_SEND_RING_BUFFER_SIZE 10*PAGE_SIZE
124#define INPUTVSC_RECV_RING_BUFFER_SIZE 10*PAGE_SIZE
125
126#define NBITS(x) (((x)/BITS_PER_LONG)+1)
127
128enum pipe_prot_msg_type {
129 PipeMessageInvalid = 0,
130 PipeMessageData,
131 PipeMessageMaximum
132};
133
134
135struct pipe_prt_msg {
136 enum pipe_prot_msg_type type;
137 u32 size;
138 char data[1];
139};
140
141/*
142 * Data types
143 */
144struct mousevsc_prt_msg {
145 enum pipe_prot_msg_type type;
146 u32 size;
147 union {
148 struct synthhid_protocol_request request;
149 struct synthhid_protocol_response response;
150 struct synthhid_device_info_ack ack;
151 };
152};
153
154/*
155 * Represents an mousevsc device
156 */
157struct mousevsc_dev {
158 struct hv_device *device;
159 /* 0 indicates the device is being destroyed */
160 atomic_t ref_count;
161 int num_outstanding_req;
162 unsigned char init_complete;
163 struct mousevsc_prt_msg protocol_req;
164 struct mousevsc_prt_msg protocol_resp;
165 /* Synchronize the request/response if needed */
166 wait_queue_head_t protocol_wait_event;
167 wait_queue_head_t dev_info_wait_event;
168 int protocol_wait_condition;
169 int device_wait_condition;
170 int dev_info_status;
171
172 struct hid_descriptor *hid_desc;
173 unsigned char *report_desc;
174 u32 report_desc_size;
175 struct hv_input_dev_info hid_dev_info;
176};
177
178
179static const char *driver_name = "mousevsc";
180
181/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
182static const struct hv_guid mouse_guid = {
183 .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
184 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A}
185};
186
187static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info);
188static void inputreport_callback(struct hv_device *dev, void *packet, u32 len);
189static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len);
190
191static struct mousevsc_dev *alloc_input_device(struct hv_device *device)
192{
193 struct mousevsc_dev *input_dev;
194
195 input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
196
197 if (!input_dev)
198 return NULL;
199
200 /*
201 * Set to 2 to allow both inbound and outbound traffics
202 * (ie get_input_device() and must_get_input_device()) to proceed.
203 */
204 atomic_cmpxchg(&input_dev->ref_count, 0, 2);
205
206 input_dev->device = device;
207 device->ext = input_dev;
208
209 return input_dev;
210}
211
212static void free_input_device(struct mousevsc_dev *device)
213{
214 WARN_ON(atomic_read(&device->ref_count) == 0);
215 kfree(device);
216}
217
218/*
219 * Get the inputdevice object if exists and its refcount > 1
220 */
221static struct mousevsc_dev *get_input_device(struct hv_device *device)
222{
223 struct mousevsc_dev *input_dev;
224
225 input_dev = (struct mousevsc_dev *)device->ext;
226
227/*
228 * FIXME
229 * This sure isn't a valid thing to print for debugging, no matter
230 * what the intention is...
231 *
232 * printk(KERN_ERR "-------------------------> REFCOUNT = %d",
233 * input_dev->ref_count);
234 */
235
236 if (input_dev && atomic_read(&input_dev->ref_count) > 1)
237 atomic_inc(&input_dev->ref_count);
238 else
239 input_dev = NULL;
240
241 return input_dev;
242}
243
244/*
245 * Get the inputdevice object iff exists and its refcount > 0
246 */
247static struct mousevsc_dev *must_get_input_device(struct hv_device *device)
248{
249 struct mousevsc_dev *input_dev;
250
251 input_dev = (struct mousevsc_dev *)device->ext;
252
253 if (input_dev && atomic_read(&input_dev->ref_count))
254 atomic_inc(&input_dev->ref_count);
255 else
256 input_dev = NULL;
257
258 return input_dev;
259}
260
261static void put_input_device(struct hv_device *device)
262{
263 struct mousevsc_dev *input_dev;
264
265 input_dev = (struct mousevsc_dev *)device->ext;
266
267 atomic_dec(&input_dev->ref_count);
268}
269
270/*
271 * Drop ref count to 1 to effectively disable get_input_device()
272 */
273static struct mousevsc_dev *release_input_device(struct hv_device *device)
274{
275 struct mousevsc_dev *input_dev;
276
277 input_dev = (struct mousevsc_dev *)device->ext;
278
279 /* Busy wait until the ref drop to 2, then set it to 1 */
280 while (atomic_cmpxchg(&input_dev->ref_count, 2, 1) != 2)
281 udelay(100);
282
283 return input_dev;
284}
285
286/*
287 * Drop ref count to 0. No one can use input_device object.
288 */
289static struct mousevsc_dev *final_release_input_device(struct hv_device *device)
290{
291 struct mousevsc_dev *input_dev;
292
293 input_dev = (struct mousevsc_dev *)device->ext;
294
295 /* Busy wait until the ref drop to 1, then set it to 0 */
296 while (atomic_cmpxchg(&input_dev->ref_count, 1, 0) != 1)
297 udelay(100);
298
299 device->ext = NULL;
300 return input_dev;
301}
302
303static void mousevsc_on_send_completion(struct hv_device *device,
304 struct vmpacket_descriptor *packet)
305{
306 struct mousevsc_dev *input_dev;
307 void *request;
308
309 input_dev = must_get_input_device(device);
310 if (!input_dev) {
311 pr_err("unable to get input device...device being destroyed?");
312 return;
313 }
314
315 request = (void *)(unsigned long)packet->trans_id;
316
317 if (request == &input_dev->protocol_req) {
318 /* FIXME */
319 /* Shouldn't we be doing something here? */
320 }
321
322 put_input_device(device);
323}
324
325static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
326 struct synthhid_device_info *device_info)
327{
328 int ret = 0;
329 struct hid_descriptor *desc;
330 struct mousevsc_prt_msg ack;
331
332 /* Assume success for now */
333 input_device->dev_info_status = 0;
334
335 /* Save the device attr */
336 memcpy(&input_device->hid_dev_info, &device_info->hid_dev_info,
337 sizeof(struct hv_input_dev_info));
338
339 /* Save the hid desc */
340 desc = &device_info->hid_descriptor;
341 WARN_ON(desc->bLength > 0);
342
343 input_device->hid_desc = kzalloc(desc->bLength, GFP_KERNEL);
344
345 if (!input_device->hid_desc) {
346 pr_err("unable to allocate hid descriptor - size %d", desc->bLength);
347 goto Cleanup;
348 }
349
350 memcpy(input_device->hid_desc, desc, desc->bLength);
351
352 /* Save the report desc */
353 input_device->report_desc_size = desc->desc[0].wDescriptorLength;
354 input_device->report_desc = kzalloc(input_device->report_desc_size,
355 GFP_KERNEL);
356
357 if (!input_device->report_desc) {
358 pr_err("unable to allocate report descriptor - size %d",
359 input_device->report_desc_size);
360 goto Cleanup;
361 }
362
363 memcpy(input_device->report_desc,
364 ((unsigned char *)desc) + desc->bLength,
365 desc->desc[0].wDescriptorLength);
366
367 /* Send the ack */
368 memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
369
370 ack.type = PipeMessageData;
371 ack.size = sizeof(struct synthhid_device_info_ack);
372
373 ack.ack.header.type = SynthHidInitialDeviceInfoAck;
374 ack.ack.header.size = 1;
375 ack.ack.reserved = 0;
376
377 ret = vmbus_sendpacket(input_device->device->channel,
378 &ack,
379 sizeof(struct pipe_prt_msg) - sizeof(unsigned char) +
380 sizeof(struct synthhid_device_info_ack),
381 (unsigned long)&ack,
382 VM_PKT_DATA_INBAND,
383 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
384 if (ret != 0) {
385 pr_err("unable to send synthhid device info ack - ret %d",
386 ret);
387 goto Cleanup;
388 }
389
390 input_device->device_wait_condition = 1;
391 wake_up(&input_device->dev_info_wait_event);
392
393 return;
394
395Cleanup:
396 kfree(input_device->hid_desc);
397 input_device->hid_desc = NULL;
398
399 kfree(input_device->report_desc);
400 input_device->report_desc = NULL;
401
402 input_device->dev_info_status = -1;
403 input_device->device_wait_condition = 1;
404 wake_up(&input_device->dev_info_wait_event);
405}
406
407static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device,
408 struct synthhid_input_report *input_report)
409{
410 struct hv_driver *input_drv;
411
412 if (!input_device->init_complete) {
413 pr_info("Initialization incomplete...ignoring input_report msg");
414 return;
415 }
416
417 input_drv = drv_to_hv_drv(input_device->device->device.driver);
418
419 inputreport_callback(input_device->device,
420 input_report->buffer,
421 input_report->header.size);
422}
423
424static void mousevsc_on_receive(struct hv_device *device,
425 struct vmpacket_descriptor *packet)
426{
427 struct pipe_prt_msg *pipe_msg;
428 struct synthhid_msg *hid_msg;
429 struct mousevsc_dev *input_dev;
430
431 input_dev = must_get_input_device(device);
432 if (!input_dev) {
433 pr_err("unable to get input device...device being destroyed?");
434 return;
435 }
436
437 pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
438 (packet->offset8 << 3));
439
440 if (pipe_msg->type != PipeMessageData) {
441 pr_err("unknown pipe msg type - type %d len %d",
442 pipe_msg->type, pipe_msg->size);
443 put_input_device(device);
444 return ;
445 }
446
447 hid_msg = (struct synthhid_msg *)&pipe_msg->data[0];
448
449 switch (hid_msg->header.type) {
450 case SynthHidProtocolResponse:
451 memcpy(&input_dev->protocol_resp, pipe_msg,
452 pipe_msg->size + sizeof(struct pipe_prt_msg) -
453 sizeof(unsigned char));
454 input_dev->protocol_wait_condition = 1;
455 wake_up(&input_dev->protocol_wait_event);
456 break;
457
458 case SynthHidInitialDeviceInfo:
459 WARN_ON(pipe_msg->size >= sizeof(struct hv_input_dev_info));
460
461 /*
462 * Parse out the device info into device attr,
463 * hid desc and report desc
464 */
465 mousevsc_on_receive_device_info(input_dev,
466 (struct synthhid_device_info *)&pipe_msg->data[0]);
467 break;
468 case SynthHidInputReport:
469 mousevsc_on_receive_input_report(input_dev,
470 (struct synthhid_input_report *)&pipe_msg->data[0]);
471
472 break;
473 default:
474 pr_err("unsupported hid msg type - type %d len %d",
475 hid_msg->header.type, hid_msg->header.size);
476 break;
477 }
478
479 put_input_device(device);
480}
481
482static void mousevsc_on_channel_callback(void *context)
483{
484 const int packetSize = 0x100;
485 int ret = 0;
486 struct hv_device *device = (struct hv_device *)context;
487 struct mousevsc_dev *input_dev;
488
489 u32 bytes_recvd;
490 u64 req_id;
491 unsigned char packet[0x100];
492 struct vmpacket_descriptor *desc;
493 unsigned char *buffer = packet;
494 int bufferlen = packetSize;
495
496 input_dev = must_get_input_device(device);
497
498 if (!input_dev) {
499 pr_err("unable to get input device...device being destroyed?");
500 return;
501 }
502
503 do {
504 ret = vmbus_recvpacket_raw(device->channel, buffer,
505 bufferlen, &bytes_recvd, &req_id);
506
507 if (ret == 0) {
508 if (bytes_recvd > 0) {
509 desc = (struct vmpacket_descriptor *)buffer;
510
511 switch (desc->type) {
512 case VM_PKT_COMP:
513 mousevsc_on_send_completion(
514 device, desc);
515 break;
516
517 case VM_PKT_DATA_INBAND:
518 mousevsc_on_receive(
519 device, desc);
520 break;
521
522 default:
523 pr_err("unhandled packet type %d, tid %llx len %d\n",
524 desc->type,
525 req_id,
526 bytes_recvd);
527 break;
528 }
529
530 /* reset */
531 if (bufferlen > packetSize) {
532 kfree(buffer);
533
534 buffer = packet;
535 bufferlen = packetSize;
536 }
537 } else {
538 /*
539 * pr_debug("nothing else to read...");
540 * reset
541 */
542 if (bufferlen > packetSize) {
543 kfree(buffer);
544
545 buffer = packet;
546 bufferlen = packetSize;
547 }
548 break;
549 }
550 } else if (ret == -2) {
551 /* Handle large packet */
552 bufferlen = bytes_recvd;
553 buffer = kzalloc(bytes_recvd, GFP_KERNEL);
554
555 if (buffer == NULL) {
556 buffer = packet;
557 bufferlen = packetSize;
558
559 /* Try again next time around */
560 pr_err("unable to allocate buffer of size %d!",
561 bytes_recvd);
562 break;
563 }
564 }
565 } while (1);
566
567 put_input_device(device);
568
569 return;
570}
571
572static int mousevsc_connect_to_vsp(struct hv_device *device)
573{
574 int ret = 0;
575 struct mousevsc_dev *input_dev;
576 struct mousevsc_prt_msg *request;
577 struct mousevsc_prt_msg *response;
578
579 input_dev = get_input_device(device);
580
581 if (!input_dev) {
582 pr_err("unable to get input device...device being destroyed?");
583 return -1;
584 }
585
586 init_waitqueue_head(&input_dev->protocol_wait_event);
587 init_waitqueue_head(&input_dev->dev_info_wait_event);
588
589 request = &input_dev->protocol_req;
590
591 /*
592 * Now, initiate the vsc/vsp initialization protocol on the open channel
593 */
594 memset(request, 0, sizeof(struct mousevsc_prt_msg));
595
596 request->type = PipeMessageData;
597 request->size = sizeof(struct synthhid_protocol_request);
598
599 request->request.header.type = SynthHidProtocolRequest;
600 request->request.header.size = sizeof(unsigned long);
601 request->request.version_requested.version = SYNTHHID_INPUT_VERSION;
602
603 pr_info("synthhid protocol request...");
604
605 ret = vmbus_sendpacket(device->channel, request,
606 sizeof(struct pipe_prt_msg) -
607 sizeof(unsigned char) +
608 sizeof(struct synthhid_protocol_request),
609 (unsigned long)request,
610 VM_PKT_DATA_INBAND,
611 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
612 if (ret != 0) {
613 pr_err("unable to send synthhid protocol request.");
614 goto Cleanup;
615 }
616
617 input_dev->protocol_wait_condition = 0;
618 wait_event_timeout(input_dev->protocol_wait_event,
619 input_dev->protocol_wait_condition, msecs_to_jiffies(1000));
620 if (input_dev->protocol_wait_condition == 0) {
621 ret = -ETIMEDOUT;
622 goto Cleanup;
623 }
624
625 response = &input_dev->protocol_resp;
626
627 if (!response->response.approved) {
628 pr_err("synthhid protocol request failed (version %d)",
629 SYNTHHID_INPUT_VERSION);
630 ret = -1;
631 goto Cleanup;
632 }
633
634 input_dev->device_wait_condition = 0;
635 wait_event_timeout(input_dev->dev_info_wait_event,
636 input_dev->device_wait_condition, msecs_to_jiffies(1000));
637 if (input_dev->device_wait_condition == 0) {
638 ret = -ETIMEDOUT;
639 goto Cleanup;
640 }
641
642 /*
643 * We should have gotten the device attr, hid desc and report
644 * desc at this point
645 */
646 if (!input_dev->dev_info_status)
647 pr_info("**** input channel up and running!! ****");
648 else
649 ret = -1;
650
651Cleanup:
652 put_input_device(device);
653
654 return ret;
655}
656
657static int mousevsc_on_device_add(struct hv_device *device,
658 void *additional_info)
659{
660 int ret = 0;
661 struct mousevsc_dev *input_dev;
662 struct hv_driver *input_drv;
663 struct hv_input_dev_info dev_info;
664
665 input_dev = alloc_input_device(device);
666
667 if (!input_dev) {
668 ret = -1;
669 goto Cleanup;
670 }
671
672 input_dev->init_complete = false;
673
674 /* Open the channel */
675 ret = vmbus_open(device->channel,
676 INPUTVSC_SEND_RING_BUFFER_SIZE,
677 INPUTVSC_RECV_RING_BUFFER_SIZE,
678 NULL,
679 0,
680 mousevsc_on_channel_callback,
681 device
682 );
683
684 if (ret != 0) {
685 pr_err("unable to open channel: %d", ret);
686 free_input_device(input_dev);
687 return -1;
688 }
689
690 pr_info("InputVsc channel open: %d", ret);
691
692 ret = mousevsc_connect_to_vsp(device);
693
694 if (ret != 0) {
695 pr_err("unable to connect channel: %d", ret);
696
697 vmbus_close(device->channel);
698 free_input_device(input_dev);
699 return ret;
700 }
701
702 input_drv = drv_to_hv_drv(input_dev->device->device.driver);
703
704 dev_info.vendor = input_dev->hid_dev_info.vendor;
705 dev_info.product = input_dev->hid_dev_info.product;
706 dev_info.version = input_dev->hid_dev_info.version;
707 strcpy(dev_info.name, "Microsoft Vmbus HID-compliant Mouse");
708
709 /* Send the device info back up */
710 deviceinfo_callback(device, &dev_info);
711
712 /* Send the report desc back up */
713 /* workaround SA-167 */
714 if (input_dev->report_desc[14] == 0x25)
715 input_dev->report_desc[14] = 0x29;
716
717 reportdesc_callback(device, input_dev->report_desc,
718 input_dev->report_desc_size);
719
720 input_dev->init_complete = true;
721
722Cleanup:
723 return ret;
724}
725
726static int mousevsc_on_device_remove(struct hv_device *device)
727{
728 struct mousevsc_dev *input_dev;
729 int ret = 0;
730
731 pr_info("disabling input device (%p)...",
732 device->ext);
733
734 input_dev = release_input_device(device);
735
736
737 /*
738 * At this point, all outbound traffic should be disable. We only
739 * allow inbound traffic (responses) to proceed
740 *
741 * so that outstanding requests can be completed.
742 */
743 while (input_dev->num_outstanding_req) {
744 pr_info("waiting for %d requests to complete...",
745 input_dev->num_outstanding_req);
746
747 udelay(100);
748 }
749
750 pr_info("removing input device (%p)...", device->ext);
751
752 input_dev = final_release_input_device(device);
753
754 pr_info("input device (%p) safe to remove", input_dev);
755
756 /* Close the channel */
757 vmbus_close(device->channel);
758
759 free_input_device(input_dev);
760
761 return ret;
762}
763
764
765/*
766 * Data types
767 */
768struct input_device_context {
769 struct hv_device *device_ctx;
770 struct hid_device *hid_device;
771 struct hv_input_dev_info device_info;
772 int connected;
773};
774
775
776static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info)
777{
778 struct input_device_context *input_device_ctx =
779 dev_get_drvdata(&dev->device);
780
781 memcpy(&input_device_ctx->device_info, info,
782 sizeof(struct hv_input_dev_info));
783
784 DPRINT_INFO(INPUTVSC_DRV, "%s", __func__);
785}
786
787static void inputreport_callback(struct hv_device *dev, void *packet, u32 len)
788{
789 int ret = 0;
790
791 struct input_device_context *input_dev_ctx =
792 dev_get_drvdata(&dev->device);
793
794 ret = hid_input_report(input_dev_ctx->hid_device,
795 HID_INPUT_REPORT, packet, len, 1);
796
797 DPRINT_DBG(INPUTVSC_DRV, "hid_input_report (ret %d)", ret);
798}
799
800static int mousevsc_hid_open(struct hid_device *hid)
801{
802 return 0;
803}
804
805static void mousevsc_hid_close(struct hid_device *hid)
806{
807}
808
809static int mousevsc_probe(struct hv_device *dev)
810{
811 int ret = 0;
812
813 struct input_device_context *input_dev_ctx;
814
815 input_dev_ctx = kmalloc(sizeof(struct input_device_context),
816 GFP_KERNEL);
817
818 dev_set_drvdata(&dev->device, input_dev_ctx);
819
820 /* Call to the vsc driver to add the device */
821 ret = mousevsc_on_device_add(dev, NULL);
822
823 if (ret != 0) {
824 DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device");
825
826 return -1;
827 }
828
829 return 0;
830}
831
832static int mousevsc_remove(struct hv_device *dev)
833{
834 int ret = 0;
835
836 struct input_device_context *input_dev_ctx;
837
838 input_dev_ctx = kmalloc(sizeof(struct input_device_context),
839 GFP_KERNEL);
840
841 dev_set_drvdata(&dev->device, input_dev_ctx);
842
843 if (input_dev_ctx->connected) {
844 hidinput_disconnect(input_dev_ctx->hid_device);
845 input_dev_ctx->connected = 0;
846 }
847
848 /*
849 * Call to the vsc driver to let it know that the device
850 * is being removed
851 */
852 ret = mousevsc_on_device_remove(dev);
853
854 if (ret != 0) {
855 DPRINT_ERR(INPUTVSC_DRV,
856 "unable to remove vsc device (ret %d)", ret);
857 }
858
859 kfree(input_dev_ctx);
860
861 return ret;
862}
863
864static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len)
865{
866 struct input_device_context *input_device_ctx =
867 dev_get_drvdata(&dev->device);
868 struct hid_device *hid_dev;
869
870 /* hid_debug = -1; */
871 hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL);
872
873 if (hid_parse_report(hid_dev, packet, len)) {
874 DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report");
875 return;
876 }
877
878 if (hid_dev) {
879 DPRINT_INFO(INPUTVSC_DRV, "hid_device created");
880
881 hid_dev->ll_driver->open = mousevsc_hid_open;
882 hid_dev->ll_driver->close = mousevsc_hid_close;
883
884 hid_dev->bus = BUS_VIRTUAL;
885 hid_dev->vendor = input_device_ctx->device_info.vendor;
886 hid_dev->product = input_device_ctx->device_info.product;
887 hid_dev->version = input_device_ctx->device_info.version;
888 hid_dev->dev = dev->device;
889
890 sprintf(hid_dev->name, "%s",
891 input_device_ctx->device_info.name);
892
893 /*
894 * HJ Do we want to call it with a 0
895 */
896 if (!hidinput_connect(hid_dev, 0)) {
897 hid_dev->claimed |= HID_CLAIMED_INPUT;
898
899 input_device_ctx->connected = 1;
900
901 DPRINT_INFO(INPUTVSC_DRV,
902 "HID device claimed by input\n");
903 }
904
905 if (!hid_dev->claimed) {
906 DPRINT_ERR(INPUTVSC_DRV,
907 "HID device not claimed by "
908 "input or hiddev\n");
909 }
910
911 input_device_ctx->hid_device = hid_dev;
912 }
913
914 kfree(hid_dev);
915}
916
917
918static struct hv_driver mousevsc_drv = {
919 .probe = mousevsc_probe,
920 .remove = mousevsc_remove,
921};
922
923static void mousevsc_drv_exit(void)
924{
925 vmbus_child_driver_unregister(&mousevsc_drv.driver);
926}
927
928static int __init mousevsc_init(void)
929{
930 struct hv_driver *drv = &mousevsc_drv;
931
932 DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing.");
933
934 memcpy(&drv->dev_type, &mouse_guid,
935 sizeof(struct hv_guid));
936
937 drv->driver.name = driver_name;
938
939 /* The driver belongs to vmbus */
940 vmbus_child_driver_register(&drv->driver);
941
942 return 0;
943}
944
945static void __exit mousevsc_exit(void)
946{
947 mousevsc_drv_exit();
948}
949
950/*
951 * We don't want to automatically load this driver just yet, it's quite
952 * broken. It's safe if you want to load it yourself manually, but
953 * don't inflict it on unsuspecting users, that's just mean.
954 */
955#if 0
956
957/*
958 * We use a PCI table to determine if we should autoload this driver This is
959 * needed by distro tools to determine if the hyperv drivers should be
960 * installed and/or configured. We don't do anything else with the table, but
961 * it needs to be present.
962 */
963const static struct pci_device_id microsoft_hv_pci_table[] = {
964 { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
965 { 0 }
966};
967MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
968#endif
969
970MODULE_LICENSE("GPL");
971MODULE_VERSION(HV_DRV_VERSION);
972module_init(mousevsc_init);
973module_exit(mousevsc_exit);
974
diff --git a/drivers/staging/hv/hv_timesource.c b/drivers/staging/hv/hv_timesource.c
new file mode 100644
index 00000000000..2b0f9aaf912
--- /dev/null
+++ b/drivers/staging/hv/hv_timesource.c
@@ -0,0 +1,101 @@
1/*
2 * A clocksource for Linux running on HyperV.
3 *
4 *
5 * Copyright (C) 2010, Novell, Inc.
6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/clocksource.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/dmi.h>
30#include <asm/hyperv.h>
31#include <asm/mshyperv.h>
32#include <asm/hypervisor.h>
33
34#define HV_CLOCK_SHIFT 22
35
36static cycle_t read_hv_clock(struct clocksource *arg)
37{
38 cycle_t current_tick;
39 /*
40 * Read the partition counter to get the current tick count. This count
41 * is set to 0 when the partition is created and is incremented in
42 * 100 nanosecond units.
43 */
44 rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick);
45 return current_tick;
46}
47
48static struct clocksource hyperv_cs = {
49 .name = "hyperv_clocksource",
50 .rating = 400, /* use this when running on Hyperv*/
51 .read = read_hv_clock,
52 .mask = CLOCKSOURCE_MASK(64),
53 /*
54 * The time ref counter in HyperV is in 100ns units.
55 * The definition of mult is:
56 * mult/2^shift = ns/cyc = 100
57 * mult = (100 << shift)
58 */
59 .mult = (100 << HV_CLOCK_SHIFT),
60 .shift = HV_CLOCK_SHIFT,
61};
62
63static const struct dmi_system_id __initconst
64hv_timesource_dmi_table[] __maybe_unused = {
65 {
66 .ident = "Hyper-V",
67 .matches = {
68 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
69 DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
70 DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
71 },
72 },
73 { },
74};
75MODULE_DEVICE_TABLE(dmi, hv_timesource_dmi_table);
76
77static const struct pci_device_id __initconst
78hv_timesource_pci_table[] __maybe_unused = {
79 { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
80 { 0 }
81};
82MODULE_DEVICE_TABLE(pci, hv_timesource_pci_table);
83
84
85static int __init init_hv_clocksource(void)
86{
87 if ((x86_hyper != &x86_hyper_ms_hyperv) ||
88 !(ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE))
89 return -ENODEV;
90
91 if (!dmi_check_system(hv_timesource_dmi_table))
92 return -ENODEV;
93
94 pr_info("Registering HyperV clock source\n");
95 return clocksource_register(&hyperv_cs);
96}
97
98module_init(init_hv_clocksource);
99MODULE_DESCRIPTION("HyperV based clocksource");
100MODULE_AUTHOR("K. Y. Srinivasan <ksrinivasan@novell.com>");
101MODULE_LICENSE("GPL");
diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
new file mode 100644
index 00000000000..c164b54b4cd
--- /dev/null
+++ b/drivers/staging/hv/hv_util.c
@@ -0,0 +1,306 @@
1/*
2 * Copyright (c) 2010, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 */
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/sysctl.h>
28#include <linux/reboot.h>
29#include <linux/dmi.h>
30#include <linux/pci.h>
31
32#include "hyperv.h"
33#include "hv_kvp.h"
34
35static u8 *shut_txf_buf;
36static u8 *time_txf_buf;
37static u8 *hbeat_txf_buf;
38
39static void shutdown_onchannelcallback(void *context)
40{
41 struct vmbus_channel *channel = context;
42 u32 recvlen;
43 u64 requestid;
44 u8 execute_shutdown = false;
45
46 struct shutdown_msg_data *shutdown_msg;
47
48 struct icmsg_hdr *icmsghdrp;
49 struct icmsg_negotiate *negop = NULL;
50
51 vmbus_recvpacket(channel, shut_txf_buf,
52 PAGE_SIZE, &recvlen, &requestid);
53
54 if (recvlen > 0) {
55 icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[
56 sizeof(struct vmbuspipe_hdr)];
57
58 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
59 prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf);
60 } else {
61 shutdown_msg =
62 (struct shutdown_msg_data *)&shut_txf_buf[
63 sizeof(struct vmbuspipe_hdr) +
64 sizeof(struct icmsg_hdr)];
65
66 switch (shutdown_msg->flags) {
67 case 0:
68 case 1:
69 icmsghdrp->status = HV_S_OK;
70 execute_shutdown = true;
71
72 pr_info("Shutdown request received -"
73 " graceful shutdown initiated\n");
74 break;
75 default:
76 icmsghdrp->status = HV_E_FAIL;
77 execute_shutdown = false;
78
79 pr_info("Shutdown request received -"
80 " Invalid request\n");
81 break;
82 }
83 }
84
85 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
86 | ICMSGHDRFLAG_RESPONSE;
87
88 vmbus_sendpacket(channel, shut_txf_buf,
89 recvlen, requestid,
90 VM_PKT_DATA_INBAND, 0);
91 }
92
93 if (execute_shutdown == true)
94 orderly_poweroff(false);
95}
96
97/*
98 * Set guest time to host UTC time.
99 */
100static inline void do_adj_guesttime(u64 hosttime)
101{
102 s64 host_tns;
103 struct timespec host_ts;
104
105 host_tns = (hosttime - WLTIMEDELTA) * 100;
106 host_ts = ns_to_timespec(host_tns);
107
108 do_settimeofday(&host_ts);
109}
110
111/*
112 * Synchronize time with host after reboot, restore, etc.
113 *
114 * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM.
115 * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time
116 * message after the timesync channel is opened. Since the hv_utils module is
117 * loaded after hv_vmbus, the first message is usually missed. The other
118 * thing is, systime is automatically set to emulated hardware clock which may
119 * not be UTC time or in the same time zone. So, to override these effects, we
120 * use the first 50 time samples for initial system time setting.
121 */
122static inline void adj_guesttime(u64 hosttime, u8 flags)
123{
124 static s32 scnt = 50;
125
126 if ((flags & ICTIMESYNCFLAG_SYNC) != 0) {
127 do_adj_guesttime(hosttime);
128 return;
129 }
130
131 if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) {
132 scnt--;
133 do_adj_guesttime(hosttime);
134 }
135}
136
137/*
138 * Time Sync Channel message handler.
139 */
140static void timesync_onchannelcallback(void *context)
141{
142 struct vmbus_channel *channel = context;
143 u32 recvlen;
144 u64 requestid;
145 struct icmsg_hdr *icmsghdrp;
146 struct ictimesync_data *timedatap;
147
148 vmbus_recvpacket(channel, time_txf_buf,
149 PAGE_SIZE, &recvlen, &requestid);
150
151 if (recvlen > 0) {
152 icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
153 sizeof(struct vmbuspipe_hdr)];
154
155 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
156 prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf);
157 } else {
158 timedatap = (struct ictimesync_data *)&time_txf_buf[
159 sizeof(struct vmbuspipe_hdr) +
160 sizeof(struct icmsg_hdr)];
161 adj_guesttime(timedatap->parenttime, timedatap->flags);
162 }
163
164 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
165 | ICMSGHDRFLAG_RESPONSE;
166
167 vmbus_sendpacket(channel, time_txf_buf,
168 recvlen, requestid,
169 VM_PKT_DATA_INBAND, 0);
170 }
171}
172
173/*
174 * Heartbeat functionality.
175 * Every two seconds, Hyper-V send us a heartbeat request message.
176 * we respond to this message, and Hyper-V knows we are alive.
177 */
178static void heartbeat_onchannelcallback(void *context)
179{
180 struct vmbus_channel *channel = context;
181 u32 recvlen;
182 u64 requestid;
183 struct icmsg_hdr *icmsghdrp;
184 struct heartbeat_msg_data *heartbeat_msg;
185
186 vmbus_recvpacket(channel, hbeat_txf_buf,
187 PAGE_SIZE, &recvlen, &requestid);
188
189 if (recvlen > 0) {
190 icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[
191 sizeof(struct vmbuspipe_hdr)];
192
193 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
194 prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf);
195 } else {
196 heartbeat_msg =
197 (struct heartbeat_msg_data *)&hbeat_txf_buf[
198 sizeof(struct vmbuspipe_hdr) +
199 sizeof(struct icmsg_hdr)];
200
201 heartbeat_msg->seq_num += 1;
202 }
203
204 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
205 | ICMSGHDRFLAG_RESPONSE;
206
207 vmbus_sendpacket(channel, hbeat_txf_buf,
208 recvlen, requestid,
209 VM_PKT_DATA_INBAND, 0);
210 }
211}
212
213static const struct pci_device_id __initconst
214hv_utils_pci_table[] __maybe_unused = {
215 { PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */
216 { 0 }
217};
218MODULE_DEVICE_TABLE(pci, hv_utils_pci_table);
219
220
221static const struct dmi_system_id __initconst
222hv_utils_dmi_table[] __maybe_unused = {
223 {
224 .ident = "Hyper-V",
225 .matches = {
226 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
227 DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
228 DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
229 },
230 },
231 { },
232};
233MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table);
234
235
236static int __init init_hyperv_utils(void)
237{
238 pr_info("Registering HyperV Utility Driver\n");
239
240 if (hv_kvp_init())
241 return -ENODEV;
242
243
244 if (!dmi_check_system(hv_utils_dmi_table))
245 return -ENODEV;
246
247 shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
248 time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
249 hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
250
251 if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) {
252 pr_info("Unable to allocate memory for receive buffer\n");
253 kfree(shut_txf_buf);
254 kfree(time_txf_buf);
255 kfree(hbeat_txf_buf);
256 return -ENOMEM;
257 }
258
259 hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
260
261 hv_cb_utils[HV_TIMESYNC_MSG].callback = &timesync_onchannelcallback;
262
263 hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback;
264
265 hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback;
266
267 return 0;
268}
269
270static void exit_hyperv_utils(void)
271{
272 pr_info("De-Registered HyperV Utility Driver\n");
273
274 if (hv_cb_utils[HV_SHUTDOWN_MSG].channel != NULL)
275 hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
276 &chn_cb_negotiate;
277 hv_cb_utils[HV_SHUTDOWN_MSG].callback = NULL;
278
279 if (hv_cb_utils[HV_TIMESYNC_MSG].channel != NULL)
280 hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
281 &chn_cb_negotiate;
282 hv_cb_utils[HV_TIMESYNC_MSG].callback = NULL;
283
284 if (hv_cb_utils[HV_HEARTBEAT_MSG].channel != NULL)
285 hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
286 &chn_cb_negotiate;
287 hv_cb_utils[HV_HEARTBEAT_MSG].callback = NULL;
288
289 if (hv_cb_utils[HV_KVP_MSG].channel != NULL)
290 hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback =
291 &chn_cb_negotiate;
292 hv_cb_utils[HV_KVP_MSG].callback = NULL;
293
294 hv_kvp_deinit();
295
296 kfree(shut_txf_buf);
297 kfree(time_txf_buf);
298 kfree(hbeat_txf_buf);
299}
300
301module_init(init_hyperv_utils);
302module_exit(exit_hyperv_utils);
303
304MODULE_DESCRIPTION("Hyper-V Utilities");
305MODULE_VERSION(HV_DRV_VERSION);
306MODULE_LICENSE("GPL");
diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h
new file mode 100644
index 00000000000..1747a2404f6
--- /dev/null
+++ b/drivers/staging/hv/hyperv.h
@@ -0,0 +1,948 @@
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_H
26#define _HYPERV_H
27
28#include <linux/scatterlist.h>
29#include <linux/list.h>
30#include <linux/timer.h>
31#include <linux/workqueue.h>
32#include <linux/completion.h>
33#include <linux/device.h>
34
35
36#include <asm/hyperv.h>
37
38struct hv_guid {
39 unsigned char data[16];
40};
41
42#define MAX_PAGE_BUFFER_COUNT 16
43#define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */
44
45#pragma pack(push, 1)
46
47/* Single-page buffer */
48struct hv_page_buffer {
49 u32 len;
50 u32 offset;
51 u64 pfn;
52};
53
54/* Multiple-page buffer */
55struct hv_multipage_buffer {
56 /* Length and Offset determines the # of pfns in the array */
57 u32 len;
58 u32 offset;
59 u64 pfn_array[MAX_MULTIPAGE_BUFFER_COUNT];
60};
61
62/* 0x18 includes the proprietary packet header */
63#define MAX_PAGE_BUFFER_PACKET (0x18 + \
64 (sizeof(struct hv_page_buffer) * \
65 MAX_PAGE_BUFFER_COUNT))
66#define MAX_MULTIPAGE_BUFFER_PACKET (0x18 + \
67 sizeof(struct hv_multipage_buffer))
68
69
70#pragma pack(pop)
71
72struct hv_ring_buffer {
73 /* Offset in bytes from the start of ring data below */
74 u32 write_index;
75
76 /* Offset in bytes from the start of ring data below */
77 u32 read_index;
78
79 u32 interrupt_mask;
80
81 /* Pad it to PAGE_SIZE so that data starts on page boundary */
82 u8 reserved[4084];
83
84 /* NOTE:
85 * The interrupt_mask field is used only for channels but since our
86 * vmbus connection also uses this data structure and its data starts
87 * here, we commented out this field.
88 */
89
90 /*
91 * Ring data starts here + RingDataStartOffset
92 * !!! DO NOT place any fields below this !!!
93 */
94 u8 buffer[0];
95} __packed;
96
97struct hv_ring_buffer_info {
98 struct hv_ring_buffer *ring_buffer;
99 u32 ring_size; /* Include the shared header */
100 spinlock_t ring_lock;
101
102 u32 ring_datasize; /* < ring_size */
103 u32 ring_data_startoffset;
104};
105
106struct hv_ring_buffer_debug_info {
107 u32 current_interrupt_mask;
108 u32 current_read_index;
109 u32 current_write_index;
110 u32 bytes_avail_toread;
111 u32 bytes_avail_towrite;
112};
113
114/*
115 * We use the same version numbering for all Hyper-V modules.
116 *
117 * Definition of versioning is as follows;
118 *
119 * Major Number Changes for these scenarios;
120 * 1. When a new version of Windows Hyper-V
121 * is released.
122 * 2. A Major change has occurred in the
123 * Linux IC's.
124 * (For example the merge for the first time
125 * into the kernel) Every time the Major Number
126 * changes, the Revision number is reset to 0.
127 * Minor Number Changes when new functionality is added
128 * to the Linux IC's that is not a bug fix.
129 *
130 * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync
131 */
132#define HV_DRV_VERSION "3.1"
133
134
135/*
136 * A revision number of vmbus that is used for ensuring both ends on a
137 * partition are using compatible versions.
138 */
139#define VMBUS_REVISION_NUMBER 13
140
141/* Make maximum size of pipe payload of 16K */
142#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384)
143
144/* Define PipeMode values. */
145#define VMBUS_PIPE_TYPE_BYTE 0x00000000
146#define VMBUS_PIPE_TYPE_MESSAGE 0x00000004
147
148/* The size of the user defined data buffer for non-pipe offers. */
149#define MAX_USER_DEFINED_BYTES 120
150
151/* The size of the user defined data buffer for pipe offers. */
152#define MAX_PIPE_USER_DEFINED_BYTES 116
153
154/*
155 * At the center of the Channel Management library is the Channel Offer. This
156 * struct contains the fundamental information about an offer.
157 */
158struct vmbus_channel_offer {
159 struct hv_guid if_type;
160 struct hv_guid if_instance;
161 u64 int_latency; /* in 100ns units */
162 u32 if_revision;
163 u32 server_ctx_size; /* in bytes */
164 u16 chn_flags;
165 u16 mmio_megabytes; /* in bytes * 1024 * 1024 */
166
167 union {
168 /* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */
169 struct {
170 unsigned char user_def[MAX_USER_DEFINED_BYTES];
171 } std;
172
173 /*
174 * Pipes:
175 * The following sructure is an integrated pipe protocol, which
176 * is implemented on top of standard user-defined data. Pipe
177 * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own
178 * use.
179 */
180 struct {
181 u32 pipe_mode;
182 unsigned char user_def[MAX_PIPE_USER_DEFINED_BYTES];
183 } pipe;
184 } u;
185 u32 padding;
186} __packed;
187
188/* Server Flags */
189#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1
190#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES 2
191#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS 4
192#define VMBUS_CHANNEL_NAMED_PIPE_MODE 0x10
193#define VMBUS_CHANNEL_LOOPBACK_OFFER 0x100
194#define VMBUS_CHANNEL_PARENT_OFFER 0x200
195#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400
196
197struct vmpacket_descriptor {
198 u16 type;
199 u16 offset8;
200 u16 len8;
201 u16 flags;
202 u64 trans_id;
203} __packed;
204
205struct vmpacket_header {
206 u32 prev_pkt_start_offset;
207 struct vmpacket_descriptor descriptor;
208} __packed;
209
210struct vmtransfer_page_range {
211 u32 byte_count;
212 u32 byte_offset;
213} __packed;
214
215struct vmtransfer_page_packet_header {
216 struct vmpacket_descriptor d;
217 u16 xfer_pageset_id;
218 bool sender_owns_set;
219 u8 reserved;
220 u32 range_cnt;
221 struct vmtransfer_page_range ranges[1];
222} __packed;
223
224struct vmgpadl_packet_header {
225 struct vmpacket_descriptor d;
226 u32 gpadl;
227 u32 reserved;
228} __packed;
229
230struct vmadd_remove_transfer_page_set {
231 struct vmpacket_descriptor d;
232 u32 gpadl;
233 u16 xfer_pageset_id;
234 u16 reserved;
235} __packed;
236
237/*
238 * This structure defines a range in guest physical space that can be made to
239 * look virtually contiguous.
240 */
241struct gpa_range {
242 u32 byte_count;
243 u32 byte_offset;
244 u64 pfn_array[0];
245};
246
247/*
248 * This is the format for an Establish Gpadl packet, which contains a handle by
249 * which this GPADL will be known and a set of GPA ranges associated with it.
250 * This can be converted to a MDL by the guest OS. If there are multiple GPA
251 * ranges, then the resulting MDL will be "chained," representing multiple VA
252 * ranges.
253 */
254struct vmestablish_gpadl {
255 struct vmpacket_descriptor d;
256 u32 gpadl;
257 u32 range_cnt;
258 struct gpa_range range[1];
259} __packed;
260
261/*
262 * This is the format for a Teardown Gpadl packet, which indicates that the
263 * GPADL handle in the Establish Gpadl packet will never be referenced again.
264 */
265struct vmteardown_gpadl {
266 struct vmpacket_descriptor d;
267 u32 gpadl;
268 u32 reserved; /* for alignment to a 8-byte boundary */
269} __packed;
270
271/*
272 * This is the format for a GPA-Direct packet, which contains a set of GPA
273 * ranges, in addition to commands and/or data.
274 */
275struct vmdata_gpa_direct {
276 struct vmpacket_descriptor d;
277 u32 reserved;
278 u32 range_cnt;
279 struct gpa_range range[1];
280} __packed;
281
282/* This is the format for a Additional Data Packet. */
283struct vmadditional_data {
284 struct vmpacket_descriptor d;
285 u64 total_bytes;
286 u32 offset;
287 u32 byte_cnt;
288 unsigned char data[1];
289} __packed;
290
291union vmpacket_largest_possible_header {
292 struct vmpacket_descriptor simple_hdr;
293 struct vmtransfer_page_packet_header xfer_page_hdr;
294 struct vmgpadl_packet_header gpadl_hdr;
295 struct vmadd_remove_transfer_page_set add_rm_xfer_page_hdr;
296 struct vmestablish_gpadl establish_gpadl_hdr;
297 struct vmteardown_gpadl teardown_gpadl_hdr;
298 struct vmdata_gpa_direct data_gpa_direct_hdr;
299};
300
301#define VMPACKET_DATA_START_ADDRESS(__packet) \
302 (void *)(((unsigned char *)__packet) + \
303 ((struct vmpacket_descriptor)__packet)->offset8 * 8)
304
305#define VMPACKET_DATA_LENGTH(__packet) \
306 ((((struct vmpacket_descriptor)__packet)->len8 - \
307 ((struct vmpacket_descriptor)__packet)->offset8) * 8)
308
309#define VMPACKET_TRANSFER_MODE(__packet) \
310 (((struct IMPACT)__packet)->type)
311
312enum vmbus_packet_type {
313 VM_PKT_INVALID = 0x0,
314 VM_PKT_SYNCH = 0x1,
315 VM_PKT_ADD_XFER_PAGESET = 0x2,
316 VM_PKT_RM_XFER_PAGESET = 0x3,
317 VM_PKT_ESTABLISH_GPADL = 0x4,
318 VM_PKT_TEARDOWN_GPADL = 0x5,
319 VM_PKT_DATA_INBAND = 0x6,
320 VM_PKT_DATA_USING_XFER_PAGES = 0x7,
321 VM_PKT_DATA_USING_GPADL = 0x8,
322 VM_PKT_DATA_USING_GPA_DIRECT = 0x9,
323 VM_PKT_CANCEL_REQUEST = 0xa,
324 VM_PKT_COMP = 0xb,
325 VM_PKT_DATA_USING_ADDITIONAL_PKT = 0xc,
326 VM_PKT_ADDITIONAL_DATA = 0xd
327};
328
329#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1
330
331
332/* Version 1 messages */
333enum vmbus_channel_message_type {
334 CHANNELMSG_INVALID = 0,
335 CHANNELMSG_OFFERCHANNEL = 1,
336 CHANNELMSG_RESCIND_CHANNELOFFER = 2,
337 CHANNELMSG_REQUESTOFFERS = 3,
338 CHANNELMSG_ALLOFFERS_DELIVERED = 4,
339 CHANNELMSG_OPENCHANNEL = 5,
340 CHANNELMSG_OPENCHANNEL_RESULT = 6,
341 CHANNELMSG_CLOSECHANNEL = 7,
342 CHANNELMSG_GPADL_HEADER = 8,
343 CHANNELMSG_GPADL_BODY = 9,
344 CHANNELMSG_GPADL_CREATED = 10,
345 CHANNELMSG_GPADL_TEARDOWN = 11,
346 CHANNELMSG_GPADL_TORNDOWN = 12,
347 CHANNELMSG_RELID_RELEASED = 13,
348 CHANNELMSG_INITIATE_CONTACT = 14,
349 CHANNELMSG_VERSION_RESPONSE = 15,
350 CHANNELMSG_UNLOAD = 16,
351#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
352 CHANNELMSG_VIEWRANGE_ADD = 17,
353 CHANNELMSG_VIEWRANGE_REMOVE = 18,
354#endif
355 CHANNELMSG_COUNT
356};
357
358struct vmbus_channel_message_header {
359 enum vmbus_channel_message_type msgtype;
360 u32 padding;
361} __packed;
362
363/* Query VMBus Version parameters */
364struct vmbus_channel_query_vmbus_version {
365 struct vmbus_channel_message_header header;
366 u32 version;
367} __packed;
368
369/* VMBus Version Supported parameters */
370struct vmbus_channel_version_supported {
371 struct vmbus_channel_message_header header;
372 bool version_supported;
373} __packed;
374
375/* Offer Channel parameters */
376struct vmbus_channel_offer_channel {
377 struct vmbus_channel_message_header header;
378 struct vmbus_channel_offer offer;
379 u32 child_relid;
380 u8 monitorid;
381 bool monitor_allocated;
382} __packed;
383
384/* Rescind Offer parameters */
385struct vmbus_channel_rescind_offer {
386 struct vmbus_channel_message_header header;
387 u32 child_relid;
388} __packed;
389
390/*
391 * Request Offer -- no parameters, SynIC message contains the partition ID
392 * Set Snoop -- no parameters, SynIC message contains the partition ID
393 * Clear Snoop -- no parameters, SynIC message contains the partition ID
394 * All Offers Delivered -- no parameters, SynIC message contains the partition
395 * ID
396 * Flush Client -- no parameters, SynIC message contains the partition ID
397 */
398
399/* Open Channel parameters */
400struct vmbus_channel_open_channel {
401 struct vmbus_channel_message_header header;
402
403 /* Identifies the specific VMBus channel that is being opened. */
404 u32 child_relid;
405
406 /* ID making a particular open request at a channel offer unique. */
407 u32 openid;
408
409 /* GPADL for the channel's ring buffer. */
410 u32 ringbuffer_gpadlhandle;
411
412 /* GPADL for the channel's server context save area. */
413 u32 server_contextarea_gpadlhandle;
414
415 /*
416 * The upstream ring buffer begins at offset zero in the memory
417 * described by RingBufferGpadlHandle. The downstream ring buffer
418 * follows it at this offset (in pages).
419 */
420 u32 downstream_ringbuffer_pageoffset;
421
422 /* User-specific data to be passed along to the server endpoint. */
423 unsigned char userdata[MAX_USER_DEFINED_BYTES];
424} __packed;
425
426/* Open Channel Result parameters */
427struct vmbus_channel_open_result {
428 struct vmbus_channel_message_header header;
429 u32 child_relid;
430 u32 openid;
431 u32 status;
432} __packed;
433
434/* Close channel parameters; */
435struct vmbus_channel_close_channel {
436 struct vmbus_channel_message_header header;
437 u32 child_relid;
438} __packed;
439
440/* Channel Message GPADL */
441#define GPADL_TYPE_RING_BUFFER 1
442#define GPADL_TYPE_SERVER_SAVE_AREA 2
443#define GPADL_TYPE_TRANSACTION 8
444
445/*
446 * The number of PFNs in a GPADL message is defined by the number of
447 * pages that would be spanned by ByteCount and ByteOffset. If the
448 * implied number of PFNs won't fit in this packet, there will be a
449 * follow-up packet that contains more.
450 */
451struct vmbus_channel_gpadl_header {
452 struct vmbus_channel_message_header header;
453 u32 child_relid;
454 u32 gpadl;
455 u16 range_buflen;
456 u16 rangecount;
457 struct gpa_range range[0];
458} __packed;
459
460/* This is the followup packet that contains more PFNs. */
461struct vmbus_channel_gpadl_body {
462 struct vmbus_channel_message_header header;
463 u32 msgnumber;
464 u32 gpadl;
465 u64 pfn[0];
466} __packed;
467
468struct vmbus_channel_gpadl_created {
469 struct vmbus_channel_message_header header;
470 u32 child_relid;
471 u32 gpadl;
472 u32 creation_status;
473} __packed;
474
475struct vmbus_channel_gpadl_teardown {
476 struct vmbus_channel_message_header header;
477 u32 child_relid;
478 u32 gpadl;
479} __packed;
480
481struct vmbus_channel_gpadl_torndown {
482 struct vmbus_channel_message_header header;
483 u32 gpadl;
484} __packed;
485
486#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
487struct vmbus_channel_view_range_add {
488 struct vmbus_channel_message_header header;
489 PHYSICAL_ADDRESS viewrange_base;
490 u64 viewrange_length;
491 u32 child_relid;
492} __packed;
493
494struct vmbus_channel_view_range_remove {
495 struct vmbus_channel_message_header header;
496 PHYSICAL_ADDRESS viewrange_base;
497 u32 child_relid;
498} __packed;
499#endif
500
501struct vmbus_channel_relid_released {
502 struct vmbus_channel_message_header header;
503 u32 child_relid;
504} __packed;
505
506struct vmbus_channel_initiate_contact {
507 struct vmbus_channel_message_header header;
508 u32 vmbus_version_requested;
509 u32 padding2;
510 u64 interrupt_page;
511 u64 monitor_page1;
512 u64 monitor_page2;
513} __packed;
514
515struct vmbus_channel_version_response {
516 struct vmbus_channel_message_header header;
517 bool version_supported;
518} __packed;
519
520enum vmbus_channel_state {
521 CHANNEL_OFFER_STATE,
522 CHANNEL_OPENING_STATE,
523 CHANNEL_OPEN_STATE,
524};
525
526struct vmbus_channel_debug_info {
527 u32 relid;
528 enum vmbus_channel_state state;
529 struct hv_guid interfacetype;
530 struct hv_guid interface_instance;
531 u32 monitorid;
532 u32 servermonitor_pending;
533 u32 servermonitor_latency;
534 u32 servermonitor_connectionid;
535 u32 clientmonitor_pending;
536 u32 clientmonitor_latency;
537 u32 clientmonitor_connectionid;
538
539 struct hv_ring_buffer_debug_info inbound;
540 struct hv_ring_buffer_debug_info outbound;
541};
542
543/*
544 * Represents each channel msg on the vmbus connection This is a
545 * variable-size data structure depending on the msg type itself
546 */
547struct vmbus_channel_msginfo {
548 /* Bookkeeping stuff */
549 struct list_head msglistentry;
550
551 /* So far, this is only used to handle gpadl body message */
552 struct list_head submsglist;
553
554 /* Synchronize the request/response if needed */
555 struct completion waitevent;
556 union {
557 struct vmbus_channel_version_supported version_supported;
558 struct vmbus_channel_open_result open_result;
559 struct vmbus_channel_gpadl_torndown gpadl_torndown;
560 struct vmbus_channel_gpadl_created gpadl_created;
561 struct vmbus_channel_version_response version_response;
562 } response;
563
564 u32 msgsize;
565 /*
566 * The channel message that goes out on the "wire".
567 * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header
568 */
569 unsigned char msg[0];
570};
571
572struct vmbus_close_msg {
573 struct vmbus_channel_msginfo info;
574 struct vmbus_channel_close_channel msg;
575};
576
577struct vmbus_channel {
578 struct list_head listentry;
579
580 struct hv_device *device_obj;
581
582 struct work_struct work;
583
584 enum vmbus_channel_state state;
585 /*
586 * For util channels, stash the
587 * the service index for easy access.
588 */
589 s8 util_index;
590
591 struct vmbus_channel_offer_channel offermsg;
592 /*
593 * These are based on the OfferMsg.MonitorId.
594 * Save it here for easy access.
595 */
596 u8 monitor_grp;
597 u8 monitor_bit;
598
599 u32 ringbuffer_gpadlhandle;
600
601 /* Allocated memory for ring buffer */
602 void *ringbuffer_pages;
603 u32 ringbuffer_pagecount;
604 struct hv_ring_buffer_info outbound; /* send to parent */
605 struct hv_ring_buffer_info inbound; /* receive from parent */
606 spinlock_t inbound_lock;
607 struct workqueue_struct *controlwq;
608
609 struct vmbus_close_msg close_msg;
610
611 /* Channel callback are invoked in this workqueue context */
612 /* HANDLE dataWorkQueue; */
613
614 void (*onchannel_callback)(void *context);
615 void *channel_callback_context;
616};
617
618void free_channel(struct vmbus_channel *channel);
619
620void vmbus_onmessage(void *context);
621
622int vmbus_request_offers(void);
623
624/* The format must be the same as struct vmdata_gpa_direct */
625struct vmbus_channel_packet_page_buffer {
626 u16 type;
627 u16 dataoffset8;
628 u16 length8;
629 u16 flags;
630 u64 transactionid;
631 u32 reserved;
632 u32 rangecount;
633 struct hv_page_buffer range[MAX_PAGE_BUFFER_COUNT];
634} __packed;
635
636/* The format must be the same as struct vmdata_gpa_direct */
637struct vmbus_channel_packet_multipage_buffer {
638 u16 type;
639 u16 dataoffset8;
640 u16 length8;
641 u16 flags;
642 u64 transactionid;
643 u32 reserved;
644 u32 rangecount; /* Always 1 in this case */
645 struct hv_multipage_buffer range;
646} __packed;
647
648
649extern int vmbus_open(struct vmbus_channel *channel,
650 u32 send_ringbuffersize,
651 u32 recv_ringbuffersize,
652 void *userdata,
653 u32 userdatalen,
654 void(*onchannel_callback)(void *context),
655 void *context);
656
657extern void vmbus_close(struct vmbus_channel *channel);
658
659extern int vmbus_sendpacket(struct vmbus_channel *channel,
660 const void *buffer,
661 u32 bufferLen,
662 u64 requestid,
663 enum vmbus_packet_type type,
664 u32 flags);
665
666extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
667 struct hv_page_buffer pagebuffers[],
668 u32 pagecount,
669 void *buffer,
670 u32 bufferlen,
671 u64 requestid);
672
673extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
674 struct hv_multipage_buffer *mpb,
675 void *buffer,
676 u32 bufferlen,
677 u64 requestid);
678
679extern int vmbus_establish_gpadl(struct vmbus_channel *channel,
680 void *kbuffer,
681 u32 size,
682 u32 *gpadl_handle);
683
684extern int vmbus_teardown_gpadl(struct vmbus_channel *channel,
685 u32 gpadl_handle);
686
687extern int vmbus_recvpacket(struct vmbus_channel *channel,
688 void *buffer,
689 u32 bufferlen,
690 u32 *buffer_actual_len,
691 u64 *requestid);
692
693extern int vmbus_recvpacket_raw(struct vmbus_channel *channel,
694 void *buffer,
695 u32 bufferlen,
696 u32 *buffer_actual_len,
697 u64 *requestid);
698
699
700extern void vmbus_get_debug_info(struct vmbus_channel *channel,
701 struct vmbus_channel_debug_info *debug);
702
703extern void vmbus_ontimer(unsigned long data);
704
705
706#define LOWORD(dw) ((unsigned short)(dw))
707#define HIWORD(dw) ((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF))
708
709
710#define VMBUS 0x0001
711#define STORVSC 0x0002
712#define NETVSC 0x0004
713#define INPUTVSC 0x0008
714#define BLKVSC 0x0010
715#define VMBUS_DRV 0x0100
716#define STORVSC_DRV 0x0200
717#define NETVSC_DRV 0x0400
718#define INPUTVSC_DRV 0x0800
719#define BLKVSC_DRV 0x1000
720
721#define ALL_MODULES (VMBUS |\
722 STORVSC |\
723 NETVSC |\
724 INPUTVSC |\
725 BLKVSC |\
726 VMBUS_DRV |\
727 STORVSC_DRV |\
728 NETVSC_DRV |\
729 INPUTVSC_DRV|\
730 BLKVSC_DRV)
731
732/* Logging Level */
733#define ERROR_LVL 3
734#define WARNING_LVL 4
735#define INFO_LVL 6
736#define DEBUG_LVL 7
737#define DEBUG_LVL_ENTEREXIT 8
738#define DEBUG_RING_LVL 9
739
740extern unsigned int vmbus_loglevel;
741
742#define DPRINT(mod, lvl, fmt, args...) do {\
743 if ((mod & (HIWORD(vmbus_loglevel))) && \
744 (lvl <= LOWORD(vmbus_loglevel))) \
745 printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
746 } while (0)
747
748#define DPRINT_DBG(mod, fmt, args...) do {\
749 if ((mod & (HIWORD(vmbus_loglevel))) && \
750 (DEBUG_LVL <= LOWORD(vmbus_loglevel))) \
751 printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
752 } while (0)
753
754#define DPRINT_INFO(mod, fmt, args...) do {\
755 if ((mod & (HIWORD(vmbus_loglevel))) && \
756 (INFO_LVL <= LOWORD(vmbus_loglevel))) \
757 printk(KERN_INFO #mod": " fmt "\n", ## args);\
758 } while (0)
759
760#define DPRINT_WARN(mod, fmt, args...) do {\
761 if ((mod & (HIWORD(vmbus_loglevel))) && \
762 (WARNING_LVL <= LOWORD(vmbus_loglevel))) \
763 printk(KERN_WARNING #mod": WARNING! " fmt "\n", ## args);\
764 } while (0)
765
766#define DPRINT_ERR(mod, fmt, args...) do {\
767 if ((mod & (HIWORD(vmbus_loglevel))) && \
768 (ERROR_LVL <= LOWORD(vmbus_loglevel))) \
769 printk(KERN_ERR #mod": %s() ERROR!! " fmt "\n", \
770 __func__, ## args);\
771 } while (0)
772
773
774
775struct hv_driver;
776struct hv_device;
777
778struct hv_dev_port_info {
779 u32 int_mask;
780 u32 read_idx;
781 u32 write_idx;
782 u32 bytes_avail_toread;
783 u32 bytes_avail_towrite;
784};
785
786struct hv_device_info {
787 u32 chn_id;
788 u32 chn_state;
789 struct hv_guid chn_type;
790 struct hv_guid chn_instance;
791
792 u32 monitor_id;
793 u32 server_monitor_pending;
794 u32 server_monitor_latency;
795 u32 server_monitor_conn_id;
796 u32 client_monitor_pending;
797 u32 client_monitor_latency;
798 u32 client_monitor_conn_id;
799
800 struct hv_dev_port_info inbound;
801 struct hv_dev_port_info outbound;
802};
803
804/* Base driver object */
805struct hv_driver {
806 const char *name;
807
808 /* the device type supported by this driver */
809 struct hv_guid dev_type;
810
811 struct device_driver driver;
812
813 int (*probe)(struct hv_device *);
814 int (*remove)(struct hv_device *);
815 void (*shutdown)(struct hv_device *);
816
817};
818
819/* Base device object */
820struct hv_device {
821 /* the device type id of this device */
822 struct hv_guid dev_type;
823
824 /* the device instance id of this device */
825 struct hv_guid dev_instance;
826
827 struct device device;
828
829 struct vmbus_channel *channel;
830
831 /* Device extension; */
832 void *ext;
833};
834
835
836static inline struct hv_device *device_to_hv_device(struct device *d)
837{
838 return container_of(d, struct hv_device, device);
839}
840
841static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d)
842{
843 return container_of(d, struct hv_driver, driver);
844}
845
846
847/* Vmbus interface */
848int vmbus_child_driver_register(struct device_driver *drv);
849void vmbus_child_driver_unregister(struct device_driver *drv);
850
851/*
852 * Common header for Hyper-V ICs
853 */
854
855#define ICMSGTYPE_NEGOTIATE 0
856#define ICMSGTYPE_HEARTBEAT 1
857#define ICMSGTYPE_KVPEXCHANGE 2
858#define ICMSGTYPE_SHUTDOWN 3
859#define ICMSGTYPE_TIMESYNC 4
860#define ICMSGTYPE_VSS 5
861
862#define ICMSGHDRFLAG_TRANSACTION 1
863#define ICMSGHDRFLAG_REQUEST 2
864#define ICMSGHDRFLAG_RESPONSE 4
865
866#define HV_S_OK 0x00000000
867#define HV_E_FAIL 0x80004005
868#define HV_ERROR_NOT_SUPPORTED 0x80070032
869#define HV_ERROR_MACHINE_LOCKED 0x800704F7
870
871struct vmbuspipe_hdr {
872 u32 flags;
873 u32 msgsize;
874} __packed;
875
876struct ic_version {
877 u16 major;
878 u16 minor;
879} __packed;
880
881struct icmsg_hdr {
882 struct ic_version icverframe;
883 u16 icmsgtype;
884 struct ic_version icvermsg;
885 u16 icmsgsize;
886 u32 status;
887 u8 ictransaction_id;
888 u8 icflags;
889 u8 reserved[2];
890} __packed;
891
892struct icmsg_negotiate {
893 u16 icframe_vercnt;
894 u16 icmsg_vercnt;
895 u32 reserved;
896 struct ic_version icversion_data[1]; /* any size array */
897} __packed;
898
899struct shutdown_msg_data {
900 u32 reason_code;
901 u32 timeout_seconds;
902 u32 flags;
903 u8 display_message[2048];
904} __packed;
905
906struct heartbeat_msg_data {
907 u64 seq_num;
908 u32 reserved[8];
909} __packed;
910
911/* Time Sync IC defs */
912#define ICTIMESYNCFLAG_PROBE 0
913#define ICTIMESYNCFLAG_SYNC 1
914#define ICTIMESYNCFLAG_SAMPLE 2
915
916#ifdef __x86_64__
917#define WLTIMEDELTA 116444736000000000L /* in 100ns unit */
918#else
919#define WLTIMEDELTA 116444736000000000LL
920#endif
921
922struct ictimesync_data {
923 u64 parenttime;
924 u64 childtime;
925 u64 roundtriptime;
926 u8 flags;
927} __packed;
928
929/* Index for each IC struct in array hv_cb_utils[] */
930#define HV_SHUTDOWN_MSG 0
931#define HV_TIMESYNC_MSG 1
932#define HV_HEARTBEAT_MSG 2
933#define HV_KVP_MSG 3
934
935struct hyperv_service_callback {
936 u8 msg_type;
937 char *log_msg;
938 unsigned char data[16];
939 struct vmbus_channel *channel;
940 void (*callback) (void *context);
941};
942
943extern void prep_negotiate_resp(struct icmsg_hdr *,
944 struct icmsg_negotiate *, u8 *);
945extern void chn_cb_negotiate(void *);
946extern struct hyperv_service_callback hv_cb_utils[];
947
948#endif /* _HYPERV_H */
diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h
new file mode 100644
index 00000000000..27f987b48df
--- /dev/null
+++ b/drivers/staging/hv/hyperv_net.h
@@ -0,0 +1,1057 @@
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_NET_H
26#define _HYPERV_NET_H
27
28#include <linux/list.h>
29#include "hyperv.h"
30
31/* Fwd declaration */
32struct hv_netvsc_packet;
33
34/* Represent the xfer page packet which contains 1 or more netvsc packet */
35struct xferpage_packet {
36 struct list_head list_ent;
37
38 /* # of netvsc packets this xfer packet contains */
39 u32 count;
40};
41
42/* The number of pages which are enough to cover jumbo frame buffer. */
43#define NETVSC_PACKET_MAXPAGE 4
44
45/*
46 * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
47 * within the RNDIS
48 */
49struct hv_netvsc_packet {
50 /* Bookkeeping stuff */
51 struct list_head list_ent;
52
53 struct hv_device *device;
54 bool is_data_pkt;
55
56 /*
57 * Valid only for receives when we break a xfer page packet
58 * into multiple netvsc packets
59 */
60 struct xferpage_packet *xfer_page_pkt;
61
62 union {
63 struct {
64 u64 recv_completion_tid;
65 void *recv_completion_ctx;
66 void (*recv_completion)(void *context);
67 } recv;
68 struct {
69 u64 send_completion_tid;
70 void *send_completion_ctx;
71 void (*send_completion)(void *context);
72 } send;
73 } completion;
74
75 /* This points to the memory after page_buf */
76 void *extension;
77
78 u32 total_data_buflen;
79 /* Points to the send/receive buffer where the ethernet frame is */
80 u32 page_buf_cnt;
81 struct hv_page_buffer page_buf[NETVSC_PACKET_MAXPAGE];
82};
83
84struct netvsc_device_info {
85 unsigned char mac_adr[6];
86 bool link_state; /* 0 - link up, 1 - link down */
87 int ring_size;
88};
89
90/* Interface */
91int netvsc_device_add(struct hv_device *device, void *additional_info);
92int netvsc_device_remove(struct hv_device *device);
93int netvsc_send(struct hv_device *device,
94 struct hv_netvsc_packet *packet);
95void netvsc_linkstatus_callback(struct hv_device *device_obj,
96 unsigned int status);
97int netvsc_recv_callback(struct hv_device *device_obj,
98 struct hv_netvsc_packet *packet);
99int netvsc_initialize(struct hv_driver *drv);
100int rndis_filter_open(struct hv_device *dev);
101int rndis_filter_close(struct hv_device *dev);
102int rndis_filter_device_add(struct hv_device *dev,
103 void *additional_info);
104void rndis_filter_device_remove(struct hv_device *dev);
105int rndis_filter_receive(struct hv_device *dev,
106 struct hv_netvsc_packet *pkt);
107
108
109
110int rndis_filter_send(struct hv_device *dev,
111 struct hv_netvsc_packet *pkt);
112
113#define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF)
114
115#define NVSP_PROTOCOL_VERSION_1 2
116#define NVSP_MIN_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1
117#define NVSP_MAX_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1
118
119enum {
120 NVSP_MSG_TYPE_NONE = 0,
121
122 /* Init Messages */
123 NVSP_MSG_TYPE_INIT = 1,
124 NVSP_MSG_TYPE_INIT_COMPLETE = 2,
125
126 NVSP_VERSION_MSG_START = 100,
127
128 /* Version 1 Messages */
129 NVSP_MSG1_TYPE_SEND_NDIS_VER = NVSP_VERSION_MSG_START,
130
131 NVSP_MSG1_TYPE_SEND_RECV_BUF,
132 NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE,
133 NVSP_MSG1_TYPE_REVOKE_RECV_BUF,
134
135 NVSP_MSG1_TYPE_SEND_SEND_BUF,
136 NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE,
137 NVSP_MSG1_TYPE_REVOKE_SEND_BUF,
138
139 NVSP_MSG1_TYPE_SEND_RNDIS_PKT,
140 NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE,
141
142 /*
143 * This should be set to the number of messages for the version with
144 * the maximum number of messages.
145 */
146 NVSP_NUM_MSG_PER_VERSION = 9,
147};
148
149enum {
150 NVSP_STAT_NONE = 0,
151 NVSP_STAT_SUCCESS,
152 NVSP_STAT_FAIL,
153 NVSP_STAT_PROTOCOL_TOO_NEW,
154 NVSP_STAT_PROTOCOL_TOO_OLD,
155 NVSP_STAT_INVALID_RNDIS_PKT,
156 NVSP_STAT_BUSY,
157 NVSP_STAT_MAX,
158};
159
160struct nvsp_message_header {
161 u32 msg_type;
162};
163
164/* Init Messages */
165
166/*
167 * This message is used by the VSC to initialize the channel after the channels
168 * has been opened. This message should never include anything other then
169 * versioning (i.e. this message will be the same for ever).
170 */
171struct nvsp_message_init {
172 u32 min_protocol_ver;
173 u32 max_protocol_ver;
174} __packed;
175
176/*
177 * This message is used by the VSP to complete the initialization of the
178 * channel. This message should never include anything other then versioning
179 * (i.e. this message will be the same for ever).
180 */
181struct nvsp_message_init_complete {
182 u32 negotiated_protocol_ver;
183 u32 max_mdl_chain_len;
184 u32 status;
185} __packed;
186
187union nvsp_message_init_uber {
188 struct nvsp_message_init init;
189 struct nvsp_message_init_complete init_complete;
190} __packed;
191
192/* Version 1 Messages */
193
194/*
195 * This message is used by the VSC to send the NDIS version to the VSP. The VSP
196 * can use this information when handling OIDs sent by the VSC.
197 */
198struct nvsp_1_message_send_ndis_version {
199 u32 ndis_major_ver;
200 u32 ndis_minor_ver;
201} __packed;
202
203/*
204 * This message is used by the VSC to send a receive buffer to the VSP. The VSP
205 * can then use the receive buffer to send data to the VSC.
206 */
207struct nvsp_1_message_send_receive_buffer {
208 u32 gpadl_handle;
209 u16 id;
210} __packed;
211
212struct nvsp_1_receive_buffer_section {
213 u32 offset;
214 u32 sub_alloc_size;
215 u32 num_sub_allocs;
216 u32 end_offset;
217} __packed;
218
219/*
220 * This message is used by the VSP to acknowledge a receive buffer send by the
221 * VSC. This message must be sent by the VSP before the VSP uses the receive
222 * buffer.
223 */
224struct nvsp_1_message_send_receive_buffer_complete {
225 u32 status;
226 u32 num_sections;
227
228 /*
229 * The receive buffer is split into two parts, a large suballocation
230 * section and a small suballocation section. These sections are then
231 * suballocated by a certain size.
232 */
233
234 /*
235 * For example, the following break up of the receive buffer has 6
236 * large suballocations and 10 small suballocations.
237 */
238
239 /*
240 * | Large Section | | Small Section |
241 * ------------------------------------------------------------
242 * | | | | | | | | | | | | | | | | | |
243 * | |
244 * LargeOffset SmallOffset
245 */
246
247 struct nvsp_1_receive_buffer_section sections[1];
248} __packed;
249
250/*
251 * This message is sent by the VSC to revoke the receive buffer. After the VSP
252 * completes this transaction, the vsp should never use the receive buffer
253 * again.
254 */
255struct nvsp_1_message_revoke_receive_buffer {
256 u16 id;
257};
258
259/*
260 * This message is used by the VSC to send a send buffer to the VSP. The VSC
261 * can then use the send buffer to send data to the VSP.
262 */
263struct nvsp_1_message_send_send_buffer {
264 u32 gpadl_handle;
265 u16 id;
266} __packed;
267
268/*
269 * This message is used by the VSP to acknowledge a send buffer sent by the
270 * VSC. This message must be sent by the VSP before the VSP uses the sent
271 * buffer.
272 */
273struct nvsp_1_message_send_send_buffer_complete {
274 u32 status;
275
276 /*
277 * The VSC gets to choose the size of the send buffer and the VSP gets
278 * to choose the sections size of the buffer. This was done to enable
279 * dynamic reconfigurations when the cost of GPA-direct buffers
280 * decreases.
281 */
282 u32 section_size;
283} __packed;
284
285/*
286 * This message is sent by the VSC to revoke the send buffer. After the VSP
287 * completes this transaction, the vsp should never use the send buffer again.
288 */
289struct nvsp_1_message_revoke_send_buffer {
290 u16 id;
291};
292
293/*
294 * This message is used by both the VSP and the VSC to send a RNDIS message to
295 * the opposite channel endpoint.
296 */
297struct nvsp_1_message_send_rndis_packet {
298 /*
299 * This field is specified by RNIDS. They assume there's two different
300 * channels of communication. However, the Network VSP only has one.
301 * Therefore, the channel travels with the RNDIS packet.
302 */
303 u32 channel_type;
304
305 /*
306 * This field is used to send part or all of the data through a send
307 * buffer. This values specifies an index into the send buffer. If the
308 * index is 0xFFFFFFFF, then the send buffer is not being used and all
309 * of the data was sent through other VMBus mechanisms.
310 */
311 u32 send_buf_section_index;
312 u32 send_buf_section_size;
313} __packed;
314
315/*
316 * This message is used by both the VSP and the VSC to complete a RNDIS message
317 * to the opposite channel endpoint. At this point, the initiator of this
318 * message cannot use any resources associated with the original RNDIS packet.
319 */
320struct nvsp_1_message_send_rndis_packet_complete {
321 u32 status;
322};
323
324union nvsp_1_message_uber {
325 struct nvsp_1_message_send_ndis_version send_ndis_ver;
326
327 struct nvsp_1_message_send_receive_buffer send_recv_buf;
328 struct nvsp_1_message_send_receive_buffer_complete
329 send_recv_buf_complete;
330 struct nvsp_1_message_revoke_receive_buffer revoke_recv_buf;
331
332 struct nvsp_1_message_send_send_buffer send_send_buf;
333 struct nvsp_1_message_send_send_buffer_complete send_send_buf_complete;
334 struct nvsp_1_message_revoke_send_buffer revoke_send_buf;
335
336 struct nvsp_1_message_send_rndis_packet send_rndis_pkt;
337 struct nvsp_1_message_send_rndis_packet_complete
338 send_rndis_pkt_complete;
339} __packed;
340
341union nvsp_all_messages {
342 union nvsp_message_init_uber init_msg;
343 union nvsp_1_message_uber v1_msg;
344} __packed;
345
346/* ALL Messages */
347struct nvsp_message {
348 struct nvsp_message_header hdr;
349 union nvsp_all_messages msg;
350} __packed;
351
352
353
354
355/* #define NVSC_MIN_PROTOCOL_VERSION 1 */
356/* #define NVSC_MAX_PROTOCOL_VERSION 1 */
357
358#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024) /* 1MB */
359
360#define NETVSC_RECEIVE_BUFFER_ID 0xcafe
361
362#define NETVSC_RECEIVE_SG_COUNT 1
363
364/* Preallocated receive packets */
365#define NETVSC_RECEIVE_PACKETLIST_COUNT 256
366
367#define NETVSC_PACKET_SIZE 2048
368
369/* Per netvsc channel-specific */
370struct netvsc_device {
371 struct hv_device *dev;
372
373 atomic_t refcnt;
374 atomic_t num_outstanding_sends;
375 /*
376 * List of free preallocated hv_netvsc_packet to represent receive
377 * packet
378 */
379 struct list_head recv_pkt_list;
380 spinlock_t recv_pkt_list_lock;
381
382 /* Receive buffer allocated by us but manages by NetVSP */
383 void *recv_buf;
384 u32 recv_buf_size;
385 u32 recv_buf_gpadl_handle;
386 u32 recv_section_cnt;
387 struct nvsp_1_receive_buffer_section *recv_section;
388
389 /* Used for NetVSP initialization protocol */
390 struct completion channel_init_wait;
391 struct nvsp_message channel_init_pkt;
392
393 struct nvsp_message revoke_packet;
394 /* unsigned char HwMacAddr[HW_MACADDR_LEN]; */
395
396 /* Holds rndis device info */
397 void *extension;
398};
399
400
401/* Status codes */
402
403
404#ifndef STATUS_SUCCESS
405#define STATUS_SUCCESS (0x00000000L)
406#endif
407
408#ifndef STATUS_UNSUCCESSFUL
409#define STATUS_UNSUCCESSFUL (0xC0000001L)
410#endif
411
412#ifndef STATUS_PENDING
413#define STATUS_PENDING (0x00000103L)
414#endif
415
416#ifndef STATUS_INSUFFICIENT_RESOURCES
417#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL)
418#endif
419
420#ifndef STATUS_BUFFER_OVERFLOW
421#define STATUS_BUFFER_OVERFLOW (0x80000005L)
422#endif
423
424#ifndef STATUS_NOT_SUPPORTED
425#define STATUS_NOT_SUPPORTED (0xC00000BBL)
426#endif
427
428#define RNDIS_STATUS_SUCCESS (STATUS_SUCCESS)
429#define RNDIS_STATUS_PENDING (STATUS_PENDING)
430#define RNDIS_STATUS_NOT_RECOGNIZED (0x00010001L)
431#define RNDIS_STATUS_NOT_COPIED (0x00010002L)
432#define RNDIS_STATUS_NOT_ACCEPTED (0x00010003L)
433#define RNDIS_STATUS_CALL_ACTIVE (0x00010007L)
434
435#define RNDIS_STATUS_ONLINE (0x40010003L)
436#define RNDIS_STATUS_RESET_START (0x40010004L)
437#define RNDIS_STATUS_RESET_END (0x40010005L)
438#define RNDIS_STATUS_RING_STATUS (0x40010006L)
439#define RNDIS_STATUS_CLOSED (0x40010007L)
440#define RNDIS_STATUS_WAN_LINE_UP (0x40010008L)
441#define RNDIS_STATUS_WAN_LINE_DOWN (0x40010009L)
442#define RNDIS_STATUS_WAN_FRAGMENT (0x4001000AL)
443#define RNDIS_STATUS_MEDIA_CONNECT (0x4001000BL)
444#define RNDIS_STATUS_MEDIA_DISCONNECT (0x4001000CL)
445#define RNDIS_STATUS_HARDWARE_LINE_UP (0x4001000DL)
446#define RNDIS_STATUS_HARDWARE_LINE_DOWN (0x4001000EL)
447#define RNDIS_STATUS_INTERFACE_UP (0x4001000FL)
448#define RNDIS_STATUS_INTERFACE_DOWN (0x40010010L)
449#define RNDIS_STATUS_MEDIA_BUSY (0x40010011L)
450#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION (0x40010012L)
451#define RNDIS_STATUS_WW_INDICATION RDIA_SPECIFIC_INDICATION
452#define RNDIS_STATUS_LINK_SPEED_CHANGE (0x40010013L)
453
454#define RNDIS_STATUS_NOT_RESETTABLE (0x80010001L)
455#define RNDIS_STATUS_SOFT_ERRORS (0x80010003L)
456#define RNDIS_STATUS_HARD_ERRORS (0x80010004L)
457#define RNDIS_STATUS_BUFFER_OVERFLOW (STATUS_BUFFER_OVERFLOW)
458
459#define RNDIS_STATUS_FAILURE (STATUS_UNSUCCESSFUL)
460#define RNDIS_STATUS_RESOURCES (STATUS_INSUFFICIENT_RESOURCES)
461#define RNDIS_STATUS_CLOSING (0xC0010002L)
462#define RNDIS_STATUS_BAD_VERSION (0xC0010004L)
463#define RNDIS_STATUS_BAD_CHARACTERISTICS (0xC0010005L)
464#define RNDIS_STATUS_ADAPTER_NOT_FOUND (0xC0010006L)
465#define RNDIS_STATUS_OPEN_FAILED (0xC0010007L)
466#define RNDIS_STATUS_DEVICE_FAILED (0xC0010008L)
467#define RNDIS_STATUS_MULTICAST_FULL (0xC0010009L)
468#define RNDIS_STATUS_MULTICAST_EXISTS (0xC001000AL)
469#define RNDIS_STATUS_MULTICAST_NOT_FOUND (0xC001000BL)
470#define RNDIS_STATUS_REQUEST_ABORTED (0xC001000CL)
471#define RNDIS_STATUS_RESET_IN_PROGRESS (0xC001000DL)
472#define RNDIS_STATUS_CLOSING_INDICATING (0xC001000EL)
473#define RNDIS_STATUS_NOT_SUPPORTED (STATUS_NOT_SUPPORTED)
474#define RNDIS_STATUS_INVALID_PACKET (0xC001000FL)
475#define RNDIS_STATUS_OPEN_LIST_FULL (0xC0010010L)
476#define RNDIS_STATUS_ADAPTER_NOT_READY (0xC0010011L)
477#define RNDIS_STATUS_ADAPTER_NOT_OPEN (0xC0010012L)
478#define RNDIS_STATUS_NOT_INDICATING (0xC0010013L)
479#define RNDIS_STATUS_INVALID_LENGTH (0xC0010014L)
480#define RNDIS_STATUS_INVALID_DATA (0xC0010015L)
481#define RNDIS_STATUS_BUFFER_TOO_SHORT (0xC0010016L)
482#define RNDIS_STATUS_INVALID_OID (0xC0010017L)
483#define RNDIS_STATUS_ADAPTER_REMOVED (0xC0010018L)
484#define RNDIS_STATUS_UNSUPPORTED_MEDIA (0xC0010019L)
485#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE (0xC001001AL)
486#define RNDIS_STATUS_FILE_NOT_FOUND (0xC001001BL)
487#define RNDIS_STATUS_ERROR_READING_FILE (0xC001001CL)
488#define RNDIS_STATUS_ALREADY_MAPPED (0xC001001DL)
489#define RNDIS_STATUS_RESOURCE_CONFLICT (0xC001001EL)
490#define RNDIS_STATUS_NO_CABLE (0xC001001FL)
491
492#define RNDIS_STATUS_INVALID_SAP (0xC0010020L)
493#define RNDIS_STATUS_SAP_IN_USE (0xC0010021L)
494#define RNDIS_STATUS_INVALID_ADDRESS (0xC0010022L)
495#define RNDIS_STATUS_VC_NOT_ACTIVATED (0xC0010023L)
496#define RNDIS_STATUS_DEST_OUT_OF_ORDER (0xC0010024L)
497#define RNDIS_STATUS_VC_NOT_AVAILABLE (0xC0010025L)
498#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE (0xC0010026L)
499#define RNDIS_STATUS_INCOMPATABLE_QOS (0xC0010027L)
500#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED (0xC0010028L)
501#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION (0xC0010029L)
502
503#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR (0xC0011000L)
504
505/* Object Identifiers used by NdisRequest Query/Set Information */
506/* General Objects */
507#define RNDIS_OID_GEN_SUPPORTED_LIST 0x00010101
508#define RNDIS_OID_GEN_HARDWARE_STATUS 0x00010102
509#define RNDIS_OID_GEN_MEDIA_SUPPORTED 0x00010103
510#define RNDIS_OID_GEN_MEDIA_IN_USE 0x00010104
511#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105
512#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106
513#define RNDIS_OID_GEN_LINK_SPEED 0x00010107
514#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108
515#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109
516#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A
517#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B
518#define RNDIS_OID_GEN_VENDOR_ID 0x0001010C
519#define RNDIS_OID_GEN_VENDOR_DESCRIPTION 0x0001010D
520#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
521#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD 0x0001010F
522#define RNDIS_OID_GEN_DRIVER_VERSION 0x00010110
523#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111
524#define RNDIS_OID_GEN_PROTOCOL_OPTIONS 0x00010112
525#define RNDIS_OID_GEN_MAC_OPTIONS 0x00010113
526#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
527#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115
528#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION 0x00010116
529#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
530#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
531#define RNDIS_OID_GEN_MACHINE_NAME 0x0001021A
532#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B
533
534#define RNDIS_OID_GEN_XMIT_OK 0x00020101
535#define RNDIS_OID_GEN_RCV_OK 0x00020102
536#define RNDIS_OID_GEN_XMIT_ERROR 0x00020103
537#define RNDIS_OID_GEN_RCV_ERROR 0x00020104
538#define RNDIS_OID_GEN_RCV_NO_BUFFER 0x00020105
539
540#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT 0x00020201
541#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
542#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT 0x00020203
543#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
544#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT 0x00020205
545#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
546#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV 0x00020207
547#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
548#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV 0x00020209
549#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
550#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV 0x0002020B
551#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
552
553#define RNDIS_OID_GEN_RCV_CRC_ERROR 0x0002020D
554#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
555
556#define RNDIS_OID_GEN_GET_TIME_CAPS 0x0002020F
557#define RNDIS_OID_GEN_GET_NETCARD_TIME 0x00020210
558
559/* These are connection-oriented general OIDs. */
560/* These replace the above OIDs for connection-oriented media. */
561#define RNDIS_OID_GEN_CO_SUPPORTED_LIST 0x00010101
562#define RNDIS_OID_GEN_CO_HARDWARE_STATUS 0x00010102
563#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED 0x00010103
564#define RNDIS_OID_GEN_CO_MEDIA_IN_USE 0x00010104
565#define RNDIS_OID_GEN_CO_LINK_SPEED 0x00010105
566#define RNDIS_OID_GEN_CO_VENDOR_ID 0x00010106
567#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107
568#define RNDIS_OID_GEN_CO_DRIVER_VERSION 0x00010108
569#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109
570#define RNDIS_OID_GEN_CO_MAC_OPTIONS 0x0001010A
571#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B
572#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C
573#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D
574
575#define RNDIS_OID_GEN_CO_GET_TIME_CAPS 0x00010201
576#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME 0x00010202
577
578/* These are connection-oriented statistics OIDs. */
579#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK 0x00020101
580#define RNDIS_OID_GEN_CO_RCV_PDUS_OK 0x00020102
581#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103
582#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR 0x00020104
583#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105
584
585
586#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR 0x00020201
587#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202
588#define RNDIS_OID_GEN_CO_BYTES_XMIT 0x00020203
589#define RNDIS_OID_GEN_CO_BYTES_RCV 0x00020204
590#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205
591#define RNDIS_OID_GEN_CO_NETCARD_LOAD 0x00020206
592
593/* These are objects for Connection-oriented media call-managers. */
594#define RNDIS_OID_CO_ADD_PVC 0xFF000001
595#define RNDIS_OID_CO_DELETE_PVC 0xFF000002
596#define RNDIS_OID_CO_GET_CALL_INFORMATION 0xFF000003
597#define RNDIS_OID_CO_ADD_ADDRESS 0xFF000004
598#define RNDIS_OID_CO_DELETE_ADDRESS 0xFF000005
599#define RNDIS_OID_CO_GET_ADDRESSES 0xFF000006
600#define RNDIS_OID_CO_ADDRESS_CHANGE 0xFF000007
601#define RNDIS_OID_CO_SIGNALING_ENABLED 0xFF000008
602#define RNDIS_OID_CO_SIGNALING_DISABLED 0xFF000009
603
604/* 802.3 Objects (Ethernet) */
605#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101
606#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102
607#define RNDIS_OID_802_3_MULTICAST_LIST 0x01010103
608#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
609#define RNDIS_OID_802_3_MAC_OPTIONS 0x01010105
610
611#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
612
613#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
614#define RNDIS_OID_802_3_XMIT_ONE_COLLISION 0x01020102
615#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
616
617#define RNDIS_OID_802_3_XMIT_DEFERRED 0x01020201
618#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
619#define RNDIS_OID_802_3_RCV_OVERRUN 0x01020203
620#define RNDIS_OID_802_3_XMIT_UNDERRUN 0x01020204
621#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205
622#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
623#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
624
625/* Remote NDIS message types */
626#define REMOTE_NDIS_PACKET_MSG 0x00000001
627#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002
628#define REMOTE_NDIS_HALT_MSG 0x00000003
629#define REMOTE_NDIS_QUERY_MSG 0x00000004
630#define REMOTE_NDIS_SET_MSG 0x00000005
631#define REMOTE_NDIS_RESET_MSG 0x00000006
632#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007
633#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008
634
635#define REMOTE_CONDIS_MP_CREATE_VC_MSG 0x00008001
636#define REMOTE_CONDIS_MP_DELETE_VC_MSG 0x00008002
637#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG 0x00008005
638#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG 0x00008006
639#define REMOTE_CONDIS_INDICATE_STATUS_MSG 0x00008007
640
641/* Remote NDIS message completion types */
642#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002
643#define REMOTE_NDIS_QUERY_CMPLT 0x80000004
644#define REMOTE_NDIS_SET_CMPLT 0x80000005
645#define REMOTE_NDIS_RESET_CMPLT 0x80000006
646#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008
647
648#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT 0x80008001
649#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT 0x80008002
650#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT 0x80008005
651#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT 0x80008006
652
653/*
654 * Reserved message type for private communication between lower-layer host
655 * driver and remote device, if necessary.
656 */
657#define REMOTE_NDIS_BUS_MSG 0xff000001
658
659/* Defines for DeviceFlags in struct rndis_initialize_complete */
660#define RNDIS_DF_CONNECTIONLESS 0x00000001
661#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002
662#define RNDIS_DF_RAW_DATA 0x00000004
663
664/* Remote NDIS medium types. */
665#define RNDIS_MEDIUM_802_3 0x00000000
666#define RNDIS_MEDIUM_802_5 0x00000001
667#define RNDIS_MEDIUM_FDDI 0x00000002
668#define RNDIS_MEDIUM_WAN 0x00000003
669#define RNDIS_MEDIUM_LOCAL_TALK 0x00000004
670#define RNDIS_MEDIUM_ARCNET_RAW 0x00000006
671#define RNDIS_MEDIUM_ARCNET_878_2 0x00000007
672#define RNDIS_MEDIUM_ATM 0x00000008
673#define RNDIS_MEDIUM_WIRELESS_WAN 0x00000009
674#define RNDIS_MEDIUM_IRDA 0x0000000a
675#define RNDIS_MEDIUM_CO_WAN 0x0000000b
676/* Not a real medium, defined as an upper-bound */
677#define RNDIS_MEDIUM_MAX 0x0000000d
678
679
680/* Remote NDIS medium connection states. */
681#define RNDIS_MEDIA_STATE_CONNECTED 0x00000000
682#define RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001
683
684/* Remote NDIS version numbers */
685#define RNDIS_MAJOR_VERSION 0x00000001
686#define RNDIS_MINOR_VERSION 0x00000000
687
688
689/* NdisInitialize message */
690struct rndis_initialize_request {
691 u32 req_id;
692 u32 major_ver;
693 u32 minor_ver;
694 u32 max_xfer_size;
695};
696
697/* Response to NdisInitialize */
698struct rndis_initialize_complete {
699 u32 req_id;
700 u32 status;
701 u32 major_ver;
702 u32 minor_ver;
703 u32 dev_flags;
704 u32 medium;
705 u32 max_pkt_per_msg;
706 u32 max_xfer_size;
707 u32 pkt_alignment_factor;
708 u32 af_list_offset;
709 u32 af_list_size;
710};
711
712/* Call manager devices only: Information about an address family */
713/* supported by the device is appended to the response to NdisInitialize. */
714struct rndis_co_address_family {
715 u32 address_family;
716 u32 major_ver;
717 u32 minor_ver;
718};
719
720/* NdisHalt message */
721struct rndis_halt_request {
722 u32 req_id;
723};
724
725/* NdisQueryRequest message */
726struct rndis_query_request {
727 u32 req_id;
728 u32 oid;
729 u32 info_buflen;
730 u32 info_buf_offset;
731 u32 dev_vc_handle;
732};
733
734/* Response to NdisQueryRequest */
735struct rndis_query_complete {
736 u32 req_id;
737 u32 status;
738 u32 info_buflen;
739 u32 info_buf_offset;
740};
741
742/* NdisSetRequest message */
743struct rndis_set_request {
744 u32 req_id;
745 u32 oid;
746 u32 info_buflen;
747 u32 info_buf_offset;
748 u32 dev_vc_handle;
749};
750
751/* Response to NdisSetRequest */
752struct rndis_set_complete {
753 u32 req_id;
754 u32 status;
755};
756
757/* NdisReset message */
758struct rndis_reset_request {
759 u32 reserved;
760};
761
762/* Response to NdisReset */
763struct rndis_reset_complete {
764 u32 status;
765 u32 addressing_reset;
766};
767
768/* NdisMIndicateStatus message */
769struct rndis_indicate_status {
770 u32 status;
771 u32 status_buflen;
772 u32 status_buf_offset;
773};
774
775/* Diagnostic information passed as the status buffer in */
776/* struct rndis_indicate_status messages signifying error conditions. */
777struct rndis_diagnostic_info {
778 u32 diag_status;
779 u32 error_offset;
780};
781
782/* NdisKeepAlive message */
783struct rndis_keepalive_request {
784 u32 req_id;
785};
786
787/* Response to NdisKeepAlive */
788struct rndis_keepalive_complete {
789 u32 req_id;
790 u32 status;
791};
792
793/*
794 * Data message. All Offset fields contain byte offsets from the beginning of
795 * struct rndis_packet. All Length fields are in bytes. VcHandle is set
796 * to 0 for connectionless data, otherwise it contains the VC handle.
797 */
798struct rndis_packet {
799 u32 data_offset;
800 u32 data_len;
801 u32 oob_data_offset;
802 u32 oob_data_len;
803 u32 num_oob_data_elements;
804 u32 per_pkt_info_offset;
805 u32 per_pkt_info_len;
806 u32 vc_handle;
807 u32 reserved;
808};
809
810/* Optional Out of Band data associated with a Data message. */
811struct rndis_oobd {
812 u32 size;
813 u32 type;
814 u32 class_info_offset;
815};
816
817/* Packet extension field contents associated with a Data message. */
818struct rndis_per_packet_info {
819 u32 size;
820 u32 type;
821 u32 per_pkt_info_offset;
822};
823
824/* Format of Information buffer passed in a SetRequest for the OID */
825/* OID_GEN_RNDIS_CONFIG_PARAMETER. */
826struct rndis_config_parameter_info {
827 u32 parameter_name_offset;
828 u32 parameter_name_length;
829 u32 parameter_type;
830 u32 parameter_value_offset;
831 u32 parameter_value_length;
832};
833
834/* Values for ParameterType in struct rndis_config_parameter_info */
835#define RNDIS_CONFIG_PARAM_TYPE_INTEGER 0
836#define RNDIS_CONFIG_PARAM_TYPE_STRING 2
837
838/* CONDIS Miniport messages for connection oriented devices */
839/* that do not implement a call manager. */
840
841/* CoNdisMiniportCreateVc message */
842struct rcondis_mp_create_vc {
843 u32 req_id;
844 u32 ndis_vc_handle;
845};
846
847/* Response to CoNdisMiniportCreateVc */
848struct rcondis_mp_create_vc_complete {
849 u32 req_id;
850 u32 dev_vc_handle;
851 u32 status;
852};
853
854/* CoNdisMiniportDeleteVc message */
855struct rcondis_mp_delete_vc {
856 u32 req_id;
857 u32 dev_vc_handle;
858};
859
860/* Response to CoNdisMiniportDeleteVc */
861struct rcondis_mp_delete_vc_complete {
862 u32 req_id;
863 u32 status;
864};
865
866/* CoNdisMiniportQueryRequest message */
867struct rcondis_mp_query_request {
868 u32 req_id;
869 u32 request_type;
870 u32 oid;
871 u32 dev_vc_handle;
872 u32 info_buflen;
873 u32 info_buf_offset;
874};
875
876/* CoNdisMiniportSetRequest message */
877struct rcondis_mp_set_request {
878 u32 req_id;
879 u32 request_type;
880 u32 oid;
881 u32 dev_vc_handle;
882 u32 info_buflen;
883 u32 info_buf_offset;
884};
885
886/* CoNdisIndicateStatus message */
887struct rcondis_indicate_status {
888 u32 ndis_vc_handle;
889 u32 status;
890 u32 status_buflen;
891 u32 status_buf_offset;
892};
893
894/* CONDIS Call/VC parameters */
895struct rcondis_specific_parameters {
896 u32 parameter_type;
897 u32 parameter_length;
898 u32 parameter_lffset;
899};
900
901struct rcondis_media_parameters {
902 u32 flags;
903 u32 reserved1;
904 u32 reserved2;
905 struct rcondis_specific_parameters media_specific;
906};
907
908struct rndis_flowspec {
909 u32 token_rate;
910 u32 token_bucket_size;
911 u32 peak_bandwidth;
912 u32 latency;
913 u32 delay_variation;
914 u32 service_type;
915 u32 max_sdu_size;
916 u32 minimum_policed_size;
917};
918
919struct rcondis_call_manager_parameters {
920 struct rndis_flowspec transmit;
921 struct rndis_flowspec receive;
922 struct rcondis_specific_parameters call_mgr_specific;
923};
924
925/* CoNdisMiniportActivateVc message */
926struct rcondis_mp_activate_vc_request {
927 u32 req_id;
928 u32 flags;
929 u32 dev_vc_handle;
930 u32 media_params_offset;
931 u32 media_params_length;
932 u32 call_mgr_params_offset;
933 u32 call_mgr_params_length;
934};
935
936/* Response to CoNdisMiniportActivateVc */
937struct rcondis_mp_activate_vc_complete {
938 u32 req_id;
939 u32 status;
940};
941
942/* CoNdisMiniportDeactivateVc message */
943struct rcondis_mp_deactivate_vc_request {
944 u32 req_id;
945 u32 flags;
946 u32 dev_vc_handle;
947};
948
949/* Response to CoNdisMiniportDeactivateVc */
950struct rcondis_mp_deactivate_vc_complete {
951 u32 req_id;
952 u32 status;
953};
954
955
956/* union with all of the RNDIS messages */
957union rndis_message_container {
958 struct rndis_packet pkt;
959 struct rndis_initialize_request init_req;
960 struct rndis_halt_request halt_req;
961 struct rndis_query_request query_req;
962 struct rndis_set_request set_req;
963 struct rndis_reset_request reset_req;
964 struct rndis_keepalive_request keep_alive_req;
965 struct rndis_indicate_status indicate_status;
966 struct rndis_initialize_complete init_complete;
967 struct rndis_query_complete query_complete;
968 struct rndis_set_complete set_complete;
969 struct rndis_reset_complete reset_complete;
970 struct rndis_keepalive_complete keep_alive_complete;
971 struct rcondis_mp_create_vc co_miniport_create_vc;
972 struct rcondis_mp_delete_vc co_miniport_delete_vc;
973 struct rcondis_indicate_status co_indicate_status;
974 struct rcondis_mp_activate_vc_request co_miniport_activate_vc;
975 struct rcondis_mp_deactivate_vc_request co_miniport_deactivate_vc;
976 struct rcondis_mp_create_vc_complete co_miniport_create_vc_complete;
977 struct rcondis_mp_delete_vc_complete co_miniport_delete_vc_complete;
978 struct rcondis_mp_activate_vc_complete co_miniport_activate_vc_complete;
979 struct rcondis_mp_deactivate_vc_complete
980 co_miniport_deactivate_vc_complete;
981};
982
983/* Remote NDIS message format */
984struct rndis_message {
985 u32 ndis_msg_type;
986
987 /* Total length of this message, from the beginning */
988 /* of the sruct rndis_message, in bytes. */
989 u32 msg_len;
990
991 /* Actual message */
992 union rndis_message_container msg;
993};
994
995
996struct rndis_filter_packet {
997 void *completion_ctx;
998 void (*completion)(void *context);
999 struct rndis_message msg;
1000};
1001
1002/* Handy macros */
1003
1004/* get the size of an RNDIS message. Pass in the message type, */
1005/* struct rndis_set_request, struct rndis_packet for example */
1006#define RNDIS_MESSAGE_SIZE(msg) \
1007 (sizeof(msg) + (sizeof(struct rndis_message) - \
1008 sizeof(union rndis_message_container)))
1009
1010/* get pointer to info buffer with message pointer */
1011#define MESSAGE_TO_INFO_BUFFER(msg) \
1012 (((unsigned char *)(msg)) + msg->info_buf_offset)
1013
1014/* get pointer to status buffer with message pointer */
1015#define MESSAGE_TO_STATUS_BUFFER(msg) \
1016 (((unsigned char *)(msg)) + msg->status_buf_offset)
1017
1018/* get pointer to OOBD buffer with message pointer */
1019#define MESSAGE_TO_OOBD_BUFFER(msg) \
1020 (((unsigned char *)(msg)) + msg->oob_data_offset)
1021
1022/* get pointer to data buffer with message pointer */
1023#define MESSAGE_TO_DATA_BUFFER(msg) \
1024 (((unsigned char *)(msg)) + msg->per_pkt_info_offset)
1025
1026/* get pointer to contained message from NDIS_MESSAGE pointer */
1027#define RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(rndis_msg) \
1028 ((void *) &rndis_msg->msg)
1029
1030/* get pointer to contained message from NDIS_MESSAGE pointer */
1031#define RNDIS_MESSAGE_RAW_PTR_TO_MESSAGE_PTR(rndis_msg) \
1032 ((void *) rndis_msg)
1033
1034
1035#define __struct_bcount(x)
1036
1037
1038
1039#define RNDIS_HEADER_SIZE (sizeof(struct rndis_message) - \
1040 sizeof(union rndis_message_container))
1041
1042#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
1043#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
1044#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
1045#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
1046#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
1047#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
1048#define NDIS_PACKET_TYPE_SMT 0x00000040
1049#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
1050#define NDIS_PACKET_TYPE_GROUP 0x00000100
1051#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200
1052#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400
1053#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800
1054
1055
1056
1057#endif /* _HYPERV_NET_H */
diff --git a/drivers/staging/hv/hyperv_storage.h b/drivers/staging/hv/hyperv_storage.h
new file mode 100644
index 00000000000..5af82f4235b
--- /dev/null
+++ b/drivers/staging/hv/hyperv_storage.h
@@ -0,0 +1,335 @@
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. */
75enum 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
102struct 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 */
131struct 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. */
147struct 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
164struct 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#define STORVSC_MAX_CMD_LEN 16
222
223struct hv_storvsc_request;
224
225/* Matches Windows-end */
226enum storvsc_request_type {
227 WRITE_TYPE,
228 READ_TYPE,
229 UNKNOWN_TYPE,
230};
231
232
233struct hv_storvsc_request {
234 struct hv_storvsc_request *request;
235 struct hv_device *device;
236
237 /* Synchronize the request/response if needed */
238 struct completion wait_event;
239
240 unsigned char *sense_buffer;
241 void *context;
242 void (*on_io_completion)(struct hv_storvsc_request *request);
243 struct hv_multipage_buffer data_buffer;
244
245 struct vstor_packet vstor_packet;
246};
247
248
249struct storvsc_device_info {
250 u32 ring_buffer_size;
251 unsigned int port_number;
252 unsigned char path_id;
253 unsigned char target_id;
254};
255
256struct storvsc_major_info {
257 int major;
258 int index;
259 bool do_register;
260 char *devname;
261 char *diskname;
262};
263
264/* A storvsc device is a device object that contains a vmbus channel */
265struct storvsc_device {
266 struct hv_device *device;
267
268 /* 0 indicates the device is being destroyed */
269 atomic_t ref_count;
270
271 bool drain_notify;
272 atomic_t num_outstanding_req;
273
274 wait_queue_head_t waiting_to_drain;
275
276 /*
277 * Each unique Port/Path/Target represents 1 channel ie scsi
278 * controller. In reality, the pathid, targetid is always 0
279 * and the port is set by us
280 */
281 unsigned int port_number;
282 unsigned char path_id;
283 unsigned char target_id;
284
285 /* Used for vsc/vsp channel reset process */
286 struct hv_storvsc_request init_request;
287 struct hv_storvsc_request reset_request;
288};
289
290
291/* Get the stordevice object iff exists and its refcount > 1 */
292static inline struct storvsc_device *get_stor_device(struct hv_device *device)
293{
294 struct storvsc_device *stor_device;
295
296 stor_device = (struct storvsc_device *)device->ext;
297 if (stor_device && atomic_read(&stor_device->ref_count) > 1)
298 atomic_inc(&stor_device->ref_count);
299 else
300 stor_device = NULL;
301
302 return stor_device;
303}
304
305
306static inline void put_stor_device(struct hv_device *device)
307{
308 struct storvsc_device *stor_device;
309
310 stor_device = (struct storvsc_device *)device->ext;
311
312 atomic_dec(&stor_device->ref_count);
313}
314
315static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
316{
317 dev->drain_notify = true;
318 wait_event(dev->waiting_to_drain,
319 atomic_read(&dev->num_outstanding_req) == 0);
320 dev->drain_notify = false;
321}
322
323/* Interface */
324
325int storvsc_dev_add(struct hv_device *device,
326 void *additional_info);
327int storvsc_dev_remove(struct hv_device *device);
328
329int storvsc_do_io(struct hv_device *device,
330 struct hv_storvsc_request *request);
331
332int storvsc_get_major_info(struct storvsc_device_info *device_info,
333 struct storvsc_major_info *major_info);
334
335#endif /* _HYPERV_STORAGE_H */
diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/staging/hv/hyperv_vmbus.h
new file mode 100644
index 00000000000..349ad80ce32
--- /dev/null
+++ b/drivers/staging/hv/hyperv_vmbus.h
@@ -0,0 +1,629 @@
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_VMBUS_H
26#define _HYPERV_VMBUS_H
27
28#include <linux/list.h>
29#include <asm/sync_bitops.h>
30#include <linux/atomic.h>
31
32#include "hyperv.h"
33
34/*
35 * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
36 * is set by CPUID(HVCPUID_VERSION_FEATURES).
37 */
38enum hv_cpuid_function {
39 HVCPUID_VERSION_FEATURES = 0x00000001,
40 HVCPUID_VENDOR_MAXFUNCTION = 0x40000000,
41 HVCPUID_INTERFACE = 0x40000001,
42
43 /*
44 * The remaining functions depend on the value of
45 * HVCPUID_INTERFACE
46 */
47 HVCPUID_VERSION = 0x40000002,
48 HVCPUID_FEATURES = 0x40000003,
49 HVCPUID_ENLIGHTENMENT_INFO = 0x40000004,
50 HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005,
51};
52
53/* Define version of the synthetic interrupt controller. */
54#define HV_SYNIC_VERSION (1)
55
56/* Define the expected SynIC version. */
57#define HV_SYNIC_VERSION_1 (0x1)
58
59/* Define synthetic interrupt controller message constants. */
60#define HV_MESSAGE_SIZE (256)
61#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
62#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
63#define HV_ANY_VP (0xFFFFFFFF)
64
65/* Define synthetic interrupt controller flag constants. */
66#define HV_EVENT_FLAGS_COUNT (256 * 8)
67#define HV_EVENT_FLAGS_BYTE_COUNT (256)
68#define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(u32))
69
70/* Define hypervisor message types. */
71enum hv_message_type {
72 HVMSG_NONE = 0x00000000,
73
74 /* Memory access messages. */
75 HVMSG_UNMAPPED_GPA = 0x80000000,
76 HVMSG_GPA_INTERCEPT = 0x80000001,
77
78 /* Timer notification messages. */
79 HVMSG_TIMER_EXPIRED = 0x80000010,
80
81 /* Error messages. */
82 HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020,
83 HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021,
84 HVMSG_UNSUPPORTED_FEATURE = 0x80000022,
85
86 /* Trace buffer complete messages. */
87 HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040,
88
89 /* Platform-specific processor intercept messages. */
90 HVMSG_X64_IOPORT_INTERCEPT = 0x80010000,
91 HVMSG_X64_MSR_INTERCEPT = 0x80010001,
92 HVMSG_X64_CPUID_INTERCEPT = 0x80010002,
93 HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003,
94 HVMSG_X64_APIC_EOI = 0x80010004,
95 HVMSG_X64_LEGACY_FP_ERROR = 0x80010005
96};
97
98/* Define the number of synthetic interrupt sources. */
99#define HV_SYNIC_SINT_COUNT (16)
100#define HV_SYNIC_STIMER_COUNT (4)
101
102/* Define invalid partition identifier. */
103#define HV_PARTITION_ID_INVALID ((u64)0x0)
104
105/* Define connection identifier type. */
106union hv_connection_id {
107 u32 asu32;
108 struct {
109 u32 id:24;
110 u32 reserved:8;
111 } u;
112};
113
114/* Define port identifier type. */
115union hv_port_id {
116 u32 asu32;
117 struct {
118 u32 id:24;
119 u32 reserved:8;
120 } u ;
121};
122
123/* Define port type. */
124enum hv_port_type {
125 HVPORT_MSG = 1,
126 HVPORT_EVENT = 2,
127 HVPORT_MONITOR = 3
128};
129
130/* Define port information structure. */
131struct hv_port_info {
132 enum hv_port_type port_type;
133 u32 padding;
134 union {
135 struct {
136 u32 target_sint;
137 u32 target_vp;
138 u64 rsvdz;
139 } message_port_info;
140 struct {
141 u32 target_sint;
142 u32 target_vp;
143 u16 base_flag_bumber;
144 u16 flag_count;
145 u32 rsvdz;
146 } event_port_info;
147 struct {
148 u64 monitor_address;
149 u64 rsvdz;
150 } monitor_port_info;
151 };
152};
153
154struct hv_connection_info {
155 enum hv_port_type port_type;
156 u32 padding;
157 union {
158 struct {
159 u64 rsvdz;
160 } message_connection_info;
161 struct {
162 u64 rsvdz;
163 } event_connection_info;
164 struct {
165 u64 monitor_address;
166 } monitor_connection_info;
167 };
168};
169
170/* Define synthetic interrupt controller message flags. */
171union hv_message_flags {
172 u8 asu8;
173 struct {
174 u8 msg_pending:1;
175 u8 reserved:7;
176 };
177};
178
179/* Define synthetic interrupt controller message header. */
180struct hv_message_header {
181 enum hv_message_type message_type;
182 u8 payload_size;
183 union hv_message_flags message_flags;
184 u8 reserved[2];
185 union {
186 u64 sender;
187 union hv_port_id port;
188 };
189};
190
191/* Define timer message payload structure. */
192struct hv_timer_message_payload {
193 u32 timer_index;
194 u32 reserved;
195 u64 expiration_time; /* When the timer expired */
196 u64 delivery_time; /* When the message was delivered */
197};
198
199/* Define synthetic interrupt controller message format. */
200struct hv_message {
201 struct hv_message_header header;
202 union {
203 u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
204 } u ;
205};
206
207/* Define the number of message buffers associated with each port. */
208#define HV_PORT_MESSAGE_BUFFER_COUNT (16)
209
210/* Define the synthetic interrupt message page layout. */
211struct hv_message_page {
212 struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
213};
214
215/* Define the synthetic interrupt controller event flags format. */
216union hv_synic_event_flags {
217 u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
218 u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT];
219};
220
221/* Define the synthetic interrupt flags page layout. */
222struct hv_synic_event_flags_page {
223 union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT];
224};
225
226/* Define SynIC control register. */
227union hv_synic_scontrol {
228 u64 as_uint64;
229 struct {
230 u64 enable:1;
231 u64 reserved:63;
232 };
233};
234
235/* Define synthetic interrupt source. */
236union hv_synic_sint {
237 u64 as_uint64;
238 struct {
239 u64 vector:8;
240 u64 reserved1:8;
241 u64 masked:1;
242 u64 auto_eoi:1;
243 u64 reserved2:46;
244 };
245};
246
247/* Define the format of the SIMP register */
248union hv_synic_simp {
249 u64 as_uint64;
250 struct {
251 u64 simp_enabled:1;
252 u64 preserved:11;
253 u64 base_simp_gpa:52;
254 };
255};
256
257/* Define the format of the SIEFP register */
258union hv_synic_siefp {
259 u64 as_uint64;
260 struct {
261 u64 siefp_enabled:1;
262 u64 preserved:11;
263 u64 base_siefp_gpa:52;
264 };
265};
266
267/* Definitions for the monitored notification facility */
268union hv_monitor_trigger_group {
269 u64 as_uint64;
270 struct {
271 u32 pending;
272 u32 armed;
273 };
274};
275
276struct hv_monitor_parameter {
277 union hv_connection_id connectionid;
278 u16 flagnumber;
279 u16 rsvdz;
280};
281
282union hv_monitor_trigger_state {
283 u32 asu32;
284
285 struct {
286 u32 group_enable:4;
287 u32 rsvdz:28;
288 };
289};
290
291/* struct hv_monitor_page Layout */
292/* ------------------------------------------------------ */
293/* | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) | */
294/* | 8 | TriggerGroup[0] | */
295/* | 10 | TriggerGroup[1] | */
296/* | 18 | TriggerGroup[2] | */
297/* | 20 | TriggerGroup[3] | */
298/* | 28 | Rsvd2[0] | */
299/* | 30 | Rsvd2[1] | */
300/* | 38 | Rsvd2[2] | */
301/* | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] | */
302/* | ... | */
303/* | 240 | Latency[0][0..3] | */
304/* | 340 | Rsvz3[0] | */
305/* | 440 | Parameter[0][0] | */
306/* | 448 | Parameter[0][1] | */
307/* | ... | */
308/* | 840 | Rsvd4[0] | */
309/* ------------------------------------------------------ */
310struct hv_monitor_page {
311 union hv_monitor_trigger_state trigger_state;
312 u32 rsvdz1;
313
314 union hv_monitor_trigger_group trigger_group[4];
315 u64 rsvdz2[3];
316
317 s32 next_checktime[4][32];
318
319 u16 latency[4][32];
320 u64 rsvdz3[32];
321
322 struct hv_monitor_parameter parameter[4][32];
323
324 u8 rsvdz4[1984];
325};
326
327/* Declare the various hypercall operations. */
328enum hv_call_code {
329 HVCALL_POST_MESSAGE = 0x005c,
330 HVCALL_SIGNAL_EVENT = 0x005d,
331};
332
333/* Definition of the hv_post_message hypercall input structure. */
334struct hv_input_post_message {
335 union hv_connection_id connectionid;
336 u32 reserved;
337 enum hv_message_type message_type;
338 u32 payload_size;
339 u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
340};
341
342/* Definition of the hv_signal_event hypercall input structure. */
343struct hv_input_signal_event {
344 union hv_connection_id connectionid;
345 u16 flag_number;
346 u16 rsvdz;
347};
348
349/*
350 * Versioning definitions used for guests reporting themselves to the
351 * hypervisor, and visa versa.
352 */
353
354/* Version info reported by guest OS's */
355enum hv_guest_os_vendor {
356 HVGUESTOS_VENDOR_MICROSOFT = 0x0001
357};
358
359enum hv_guest_os_microsoft_ids {
360 HVGUESTOS_MICROSOFT_UNDEFINED = 0x00,
361 HVGUESTOS_MICROSOFT_MSDOS = 0x01,
362 HVGUESTOS_MICROSOFT_WINDOWS3X = 0x02,
363 HVGUESTOS_MICROSOFT_WINDOWS9X = 0x03,
364 HVGUESTOS_MICROSOFT_WINDOWSNT = 0x04,
365 HVGUESTOS_MICROSOFT_WINDOWSCE = 0x05
366};
367
368/*
369 * Declare the MSR used to identify the guest OS.
370 */
371#define HV_X64_MSR_GUEST_OS_ID 0x40000000
372
373union hv_x64_msr_guest_os_id_contents {
374 u64 as_uint64;
375 struct {
376 u64 build_number:16;
377 u64 service_version:8; /* Service Pack, etc. */
378 u64 minor_version:8;
379 u64 major_version:8;
380 u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
381 u64 vendor_id:16; /* enum hv_guest_os_vendor */
382 };
383};
384
385/*
386 * Declare the MSR used to setup pages used to communicate with the hypervisor.
387 */
388#define HV_X64_MSR_HYPERCALL 0x40000001
389
390union hv_x64_msr_hypercall_contents {
391 u64 as_uint64;
392 struct {
393 u64 enable:1;
394 u64 reserved:11;
395 u64 guest_physical_address:52;
396 };
397};
398
399
400enum {
401 VMBUS_MESSAGE_CONNECTION_ID = 1,
402 VMBUS_MESSAGE_PORT_ID = 1,
403 VMBUS_EVENT_CONNECTION_ID = 2,
404 VMBUS_EVENT_PORT_ID = 2,
405 VMBUS_MONITOR_CONNECTION_ID = 3,
406 VMBUS_MONITOR_PORT_ID = 3,
407 VMBUS_MESSAGE_SINT = 2,
408};
409
410/* #defines */
411
412#define HV_PRESENT_BIT 0x80000000
413
414#define HV_LINUX_GUEST_ID_LO 0x00000000
415#define HV_LINUX_GUEST_ID_HI 0xB16B00B5
416#define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \
417 HV_LINUX_GUEST_ID_LO)
418
419#define HV_CPU_POWER_MANAGEMENT (1 << 0)
420#define HV_RECOMMENDATIONS_MAX 4
421
422#define HV_X64_MAX 5
423#define HV_CAPS_MAX 8
424
425
426#define HV_HYPERCALL_PARAM_ALIGN sizeof(u64)
427
428
429/* Service definitions */
430
431#define HV_SERVICE_PARENT_PORT (0)
432#define HV_SERVICE_PARENT_CONNECTION (0)
433
434#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS (0)
435#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER (1)
436#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE (2)
437#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED (3)
438
439#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID (1)
440#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID (2)
441#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID (3)
442#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID (4)
443#define HV_SERVICE_MAX_MESSAGE_ID (4)
444
445#define HV_SERVICE_PROTOCOL_VERSION (0x0010)
446#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64
447
448/* #define VMBUS_REVISION_NUMBER 6 */
449
450/* Our local vmbus's port and connection id. Anything >0 is fine */
451/* #define VMBUS_PORT_ID 11 */
452
453/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
454static const struct hv_guid VMBUS_SERVICE_ID = {
455 .data = {
456 0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
457 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
458 },
459};
460
461#define MAX_NUM_CPUS 32
462
463
464struct hv_input_signal_event_buffer {
465 u64 align8;
466 struct hv_input_signal_event event;
467};
468
469struct hv_context {
470 /* We only support running on top of Hyper-V
471 * So at this point this really can only contain the Hyper-V ID
472 */
473 u64 guestid;
474
475 void *hypercall_page;
476
477 bool synic_initialized;
478
479 /*
480 * This is used as an input param to HvCallSignalEvent hypercall. The
481 * input param is immutable in our usage and must be dynamic mem (vs
482 * stack or global). */
483 struct hv_input_signal_event_buffer *signal_event_buffer;
484 /* 8-bytes aligned of the buffer above */
485 struct hv_input_signal_event *signal_event_param;
486
487 void *synic_message_page[MAX_NUM_CPUS];
488 void *synic_event_page[MAX_NUM_CPUS];
489};
490
491extern struct hv_context hv_context;
492
493
494/* Hv Interface */
495
496extern int hv_init(void);
497
498extern void hv_cleanup(void);
499
500extern u16 hv_post_message(union hv_connection_id connection_id,
501 enum hv_message_type message_type,
502 void *payload, size_t payload_size);
503
504extern u16 hv_signal_event(void);
505
506extern void hv_synic_init(void *irqarg);
507
508extern void hv_synic_cleanup(void *arg);
509
510
511/* Interface */
512
513
514int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer,
515 u32 buflen);
516
517void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
518
519int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info,
520 struct scatterlist *sglist,
521 u32 sgcount);
522
523int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer,
524 u32 buflen);
525
526int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info,
527 void *buffer,
528 u32 buflen,
529 u32 offset);
530
531u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
532
533void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix);
534
535void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
536 struct hv_ring_buffer_debug_info *debug_info);
537
538/*
539 * Maximum channels is determined by the size of the interrupt page
540 * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
541 * and the other is receive endpoint interrupt
542 */
543#define MAX_NUM_CHANNELS ((PAGE_SIZE >> 1) << 3) /* 16348 channels */
544
545/* The value here must be in multiple of 32 */
546/* TODO: Need to make this configurable */
547#define MAX_NUM_CHANNELS_SUPPORTED 256
548
549
550enum vmbus_connect_state {
551 DISCONNECTED,
552 CONNECTING,
553 CONNECTED,
554 DISCONNECTING
555};
556
557#define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT
558
559struct vmbus_connection {
560 enum vmbus_connect_state conn_state;
561
562 atomic_t next_gpadl_handle;
563
564 /*
565 * Represents channel interrupts. Each bit position represents a
566 * channel. When a channel sends an interrupt via VMBUS, it finds its
567 * bit in the sendInterruptPage, set it and calls Hv to generate a port
568 * event. The other end receives the port event and parse the
569 * recvInterruptPage to see which bit is set
570 */
571 void *int_page;
572 void *send_int_page;
573 void *recv_int_page;
574
575 /*
576 * 2 pages - 1st page for parent->child notification and 2nd
577 * is child->parent notification
578 */
579 void *monitor_pages;
580 struct list_head chn_msg_list;
581 spinlock_t channelmsg_lock;
582
583 /* List of channels */
584 struct list_head chn_list;
585 spinlock_t channel_lock;
586
587 struct workqueue_struct *work_queue;
588};
589
590
591struct vmbus_msginfo {
592 /* Bookkeeping stuff */
593 struct list_head msglist_entry;
594
595 /* The message itself */
596 unsigned char msg[0];
597};
598
599
600extern struct vmbus_connection vmbus_connection;
601
602/* General vmbus interface */
603
604struct hv_device *vmbus_child_device_create(struct hv_guid *type,
605 struct hv_guid *instance,
606 struct vmbus_channel *channel);
607
608int vmbus_child_device_register(struct hv_device *child_device_obj);
609void vmbus_child_device_unregister(struct hv_device *device_obj);
610
611/* static void */
612/* VmbusChildDeviceDestroy( */
613/* struct hv_device *); */
614
615struct vmbus_channel *relid2channel(u32 relid);
616
617
618/* Connection interface */
619
620int vmbus_connect(void);
621
622int vmbus_post_msg(void *buffer, size_t buflen);
623
624int vmbus_set_event(u32 child_relid);
625
626void vmbus_on_event(unsigned long data);
627
628
629#endif /* _HYPERV_VMBUS_H */
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
new file mode 100644
index 00000000000..dc5e5c488e3
--- /dev/null
+++ b/drivers/staging/hv/netvsc.c
@@ -0,0 +1,1015 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 */
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/wait.h>
26#include <linux/mm.h>
27#include <linux/delay.h>
28#include <linux/io.h>
29#include <linux/slab.h>
30
31#include "hyperv.h"
32#include "hyperv_net.h"
33
34
35/* Globals */
36static const char *driver_name = "netvsc";
37
38/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
39static const struct hv_guid netvsc_device_type = {
40 .data = {
41 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
42 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
43 }
44};
45
46
47static struct netvsc_device *alloc_net_device(struct hv_device *device)
48{
49 struct netvsc_device *net_device;
50
51 net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
52 if (!net_device)
53 return NULL;
54
55 /* Set to 2 to allow both inbound and outbound traffic */
56 atomic_cmpxchg(&net_device->refcnt, 0, 2);
57
58 net_device->dev = device;
59 device->ext = net_device;
60
61 return net_device;
62}
63
64static void free_net_device(struct netvsc_device *device)
65{
66 WARN_ON(atomic_read(&device->refcnt) != 0);
67 device->dev->ext = NULL;
68 kfree(device);
69}
70
71
72/* Get the net device object iff exists and its refcount > 1 */
73static struct netvsc_device *get_outbound_net_device(struct hv_device *device)
74{
75 struct netvsc_device *net_device;
76
77 net_device = device->ext;
78 if (net_device && atomic_read(&net_device->refcnt) > 1)
79 atomic_inc(&net_device->refcnt);
80 else
81 net_device = NULL;
82
83 return net_device;
84}
85
86/* Get the net device object iff exists and its refcount > 0 */
87static struct netvsc_device *get_inbound_net_device(struct hv_device *device)
88{
89 struct netvsc_device *net_device;
90
91 net_device = device->ext;
92 if (net_device && atomic_read(&net_device->refcnt))
93 atomic_inc(&net_device->refcnt);
94 else
95 net_device = NULL;
96
97 return net_device;
98}
99
100static void put_net_device(struct hv_device *device)
101{
102 struct netvsc_device *net_device;
103
104 net_device = device->ext;
105
106 atomic_dec(&net_device->refcnt);
107}
108
109static struct netvsc_device *release_outbound_net_device(
110 struct hv_device *device)
111{
112 struct netvsc_device *net_device;
113
114 net_device = device->ext;
115 if (net_device == NULL)
116 return NULL;
117
118 /* Busy wait until the ref drop to 2, then set it to 1 */
119 while (atomic_cmpxchg(&net_device->refcnt, 2, 1) != 2)
120 udelay(100);
121
122 return net_device;
123}
124
125static struct netvsc_device *release_inbound_net_device(
126 struct hv_device *device)
127{
128 struct netvsc_device *net_device;
129
130 net_device = device->ext;
131 if (net_device == NULL)
132 return NULL;
133
134 /* Busy wait until the ref drop to 1, then set it to 0 */
135 while (atomic_cmpxchg(&net_device->refcnt, 1, 0) != 1)
136 udelay(100);
137
138 device->ext = NULL;
139 return net_device;
140}
141
142static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
143{
144 struct nvsp_message *revoke_packet;
145 int ret = 0;
146
147 /*
148 * If we got a section count, it means we received a
149 * SendReceiveBufferComplete msg (ie sent
150 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
151 * to send a revoke msg here
152 */
153 if (net_device->recv_section_cnt) {
154 /* Send the revoke receive buffer */
155 revoke_packet = &net_device->revoke_packet;
156 memset(revoke_packet, 0, sizeof(struct nvsp_message));
157
158 revoke_packet->hdr.msg_type =
159 NVSP_MSG1_TYPE_REVOKE_RECV_BUF;
160 revoke_packet->msg.v1_msg.
161 revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
162
163 ret = vmbus_sendpacket(net_device->dev->channel,
164 revoke_packet,
165 sizeof(struct nvsp_message),
166 (unsigned long)revoke_packet,
167 VM_PKT_DATA_INBAND, 0);
168 /*
169 * If we failed here, we might as well return and
170 * have a leak rather than continue and a bugchk
171 */
172 if (ret != 0) {
173 dev_err(&net_device->dev->device, "unable to send "
174 "revoke receive buffer to netvsp");
175 return -1;
176 }
177 }
178
179 /* Teardown the gpadl on the vsp end */
180 if (net_device->recv_buf_gpadl_handle) {
181 ret = vmbus_teardown_gpadl(net_device->dev->channel,
182 net_device->recv_buf_gpadl_handle);
183
184 /* If we failed here, we might as well return and have a leak
185 * rather than continue and a bugchk
186 */
187 if (ret != 0) {
188 dev_err(&net_device->dev->device,
189 "unable to teardown receive buffer's gpadl");
190 return -1;
191 }
192 net_device->recv_buf_gpadl_handle = 0;
193 }
194
195 if (net_device->recv_buf) {
196 /* Free up the receive buffer */
197 free_pages((unsigned long)net_device->recv_buf,
198 get_order(net_device->recv_buf_size));
199 net_device->recv_buf = NULL;
200 }
201
202 if (net_device->recv_section) {
203 net_device->recv_section_cnt = 0;
204 kfree(net_device->recv_section);
205 net_device->recv_section = NULL;
206 }
207
208 return ret;
209}
210
211static int netvsc_init_recv_buf(struct hv_device *device)
212{
213 int ret = 0;
214 int t;
215 struct netvsc_device *net_device;
216 struct nvsp_message *init_packet;
217
218 net_device = get_outbound_net_device(device);
219 if (!net_device) {
220 dev_err(&device->device, "unable to get net device..."
221 "device being destroyed?");
222 return -1;
223 }
224
225 net_device->recv_buf =
226 (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
227 get_order(net_device->recv_buf_size));
228 if (!net_device->recv_buf) {
229 dev_err(&device->device, "unable to allocate receive "
230 "buffer of size %d", net_device->recv_buf_size);
231 ret = -1;
232 goto cleanup;
233 }
234
235 /*
236 * Establish the gpadl handle for this buffer on this
237 * channel. Note: This call uses the vmbus connection rather
238 * than the channel to establish the gpadl handle.
239 */
240 ret = vmbus_establish_gpadl(device->channel, net_device->recv_buf,
241 net_device->recv_buf_size,
242 &net_device->recv_buf_gpadl_handle);
243 if (ret != 0) {
244 dev_err(&device->device,
245 "unable to establish receive buffer's gpadl");
246 goto cleanup;
247 }
248
249
250 /* Notify the NetVsp of the gpadl handle */
251 init_packet = &net_device->channel_init_pkt;
252
253 memset(init_packet, 0, sizeof(struct nvsp_message));
254
255 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_RECV_BUF;
256 init_packet->msg.v1_msg.send_recv_buf.
257 gpadl_handle = net_device->recv_buf_gpadl_handle;
258 init_packet->msg.v1_msg.
259 send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
260
261 /* Send the gpadl notification request */
262 ret = vmbus_sendpacket(device->channel, init_packet,
263 sizeof(struct nvsp_message),
264 (unsigned long)init_packet,
265 VM_PKT_DATA_INBAND,
266 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
267 if (ret != 0) {
268 dev_err(&device->device,
269 "unable to send receive buffer's gpadl to netvsp");
270 goto cleanup;
271 }
272
273 t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
274 BUG_ON(t == 0);
275
276
277 /* Check the response */
278 if (init_packet->msg.v1_msg.
279 send_recv_buf_complete.status != NVSP_STAT_SUCCESS) {
280 dev_err(&device->device, "Unable to complete receive buffer "
281 "initialzation with NetVsp - status %d",
282 init_packet->msg.v1_msg.
283 send_recv_buf_complete.status);
284 ret = -1;
285 goto cleanup;
286 }
287
288 /* Parse the response */
289
290 net_device->recv_section_cnt = init_packet->msg.
291 v1_msg.send_recv_buf_complete.num_sections;
292
293 net_device->recv_section = kmalloc(net_device->recv_section_cnt
294 * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL);
295 if (net_device->recv_section == NULL) {
296 ret = -1;
297 goto cleanup;
298 }
299
300 memcpy(net_device->recv_section,
301 init_packet->msg.v1_msg.
302 send_recv_buf_complete.sections,
303 net_device->recv_section_cnt *
304 sizeof(struct nvsp_1_receive_buffer_section));
305
306 /*
307 * For 1st release, there should only be 1 section that represents the
308 * entire receive buffer
309 */
310 if (net_device->recv_section_cnt != 1 ||
311 net_device->recv_section->offset != 0) {
312 ret = -1;
313 goto cleanup;
314 }
315
316 goto exit;
317
318cleanup:
319 netvsc_destroy_recv_buf(net_device);
320
321exit:
322 put_net_device(device);
323 return ret;
324}
325
326
327static int netvsc_connect_vsp(struct hv_device *device)
328{
329 int ret, t;
330 struct netvsc_device *net_device;
331 struct nvsp_message *init_packet;
332 int ndis_version;
333
334 net_device = get_outbound_net_device(device);
335 if (!net_device) {
336 dev_err(&device->device, "unable to get net device..."
337 "device being destroyed?");
338 return -1;
339 }
340
341 init_packet = &net_device->channel_init_pkt;
342
343 memset(init_packet, 0, sizeof(struct nvsp_message));
344 init_packet->hdr.msg_type = NVSP_MSG_TYPE_INIT;
345 init_packet->msg.init_msg.init.min_protocol_ver =
346 NVSP_MIN_PROTOCOL_VERSION;
347 init_packet->msg.init_msg.init.max_protocol_ver =
348 NVSP_MAX_PROTOCOL_VERSION;
349
350 /* Send the init request */
351 ret = vmbus_sendpacket(device->channel, init_packet,
352 sizeof(struct nvsp_message),
353 (unsigned long)init_packet,
354 VM_PKT_DATA_INBAND,
355 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
356
357 if (ret != 0)
358 goto cleanup;
359
360 t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
361
362 if (t == 0) {
363 ret = -ETIMEDOUT;
364 goto cleanup;
365 }
366
367 if (init_packet->msg.init_msg.init_complete.status !=
368 NVSP_STAT_SUCCESS) {
369 ret = -1;
370 goto cleanup;
371 }
372
373 if (init_packet->msg.init_msg.init_complete.
374 negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) {
375 ret = -1;
376 goto cleanup;
377 }
378 /* Send the ndis version */
379 memset(init_packet, 0, sizeof(struct nvsp_message));
380
381 ndis_version = 0x00050000;
382
383 init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_NDIS_VER;
384 init_packet->msg.v1_msg.
385 send_ndis_ver.ndis_major_ver =
386 (ndis_version & 0xFFFF0000) >> 16;
387 init_packet->msg.v1_msg.
388 send_ndis_ver.ndis_minor_ver =
389 ndis_version & 0xFFFF;
390
391 /* Send the init request */
392 ret = vmbus_sendpacket(device->channel, init_packet,
393 sizeof(struct nvsp_message),
394 (unsigned long)init_packet,
395 VM_PKT_DATA_INBAND, 0);
396 if (ret != 0) {
397 ret = -1;
398 goto cleanup;
399 }
400
401 /* Post the big receive buffer to NetVSP */
402 ret = netvsc_init_recv_buf(device);
403
404cleanup:
405 put_net_device(device);
406 return ret;
407}
408
409static void netvsc_disconnect_vsp(struct netvsc_device *net_device)
410{
411 netvsc_destroy_recv_buf(net_device);
412}
413
414/*
415 * netvsc_device_remove - Callback when the root bus device is removed
416 */
417int netvsc_device_remove(struct hv_device *device)
418{
419 struct netvsc_device *net_device;
420 struct hv_netvsc_packet *netvsc_packet, *pos;
421
422 /* Stop outbound traffic ie sends and receives completions */
423 net_device = release_outbound_net_device(device);
424 if (!net_device) {
425 dev_err(&device->device, "No net device present!!");
426 return -1;
427 }
428
429 /* Wait for all send completions */
430 while (atomic_read(&net_device->num_outstanding_sends)) {
431 dev_err(&device->device,
432 "waiting for %d requests to complete...",
433 atomic_read(&net_device->num_outstanding_sends));
434 udelay(100);
435 }
436
437 netvsc_disconnect_vsp(net_device);
438
439 /* Stop inbound traffic ie receives and sends completions */
440 net_device = release_inbound_net_device(device);
441
442 /* At this point, no one should be accessing netDevice except in here */
443 dev_notice(&device->device, "net device safe to remove");
444
445 /* Now, we can close the channel safely */
446 vmbus_close(device->channel);
447
448 /* Release all resources */
449 list_for_each_entry_safe(netvsc_packet, pos,
450 &net_device->recv_pkt_list, list_ent) {
451 list_del(&netvsc_packet->list_ent);
452 kfree(netvsc_packet);
453 }
454
455 free_net_device(net_device);
456 return 0;
457}
458
459static void netvsc_send_completion(struct hv_device *device,
460 struct vmpacket_descriptor *packet)
461{
462 struct netvsc_device *net_device;
463 struct nvsp_message *nvsp_packet;
464 struct hv_netvsc_packet *nvsc_packet;
465
466 net_device = get_inbound_net_device(device);
467 if (!net_device) {
468 dev_err(&device->device, "unable to get net device..."
469 "device being destroyed?");
470 return;
471 }
472
473 nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
474 (packet->offset8 << 3));
475
476 if ((nvsp_packet->hdr.msg_type == NVSP_MSG_TYPE_INIT_COMPLETE) ||
477 (nvsp_packet->hdr.msg_type ==
478 NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) ||
479 (nvsp_packet->hdr.msg_type ==
480 NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE)) {
481 /* Copy the response back */
482 memcpy(&net_device->channel_init_pkt, nvsp_packet,
483 sizeof(struct nvsp_message));
484 complete(&net_device->channel_init_wait);
485 } else if (nvsp_packet->hdr.msg_type ==
486 NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) {
487 /* Get the send context */
488 nvsc_packet = (struct hv_netvsc_packet *)(unsigned long)
489 packet->trans_id;
490
491 /* Notify the layer above us */
492 nvsc_packet->completion.send.send_completion(
493 nvsc_packet->completion.send.send_completion_ctx);
494
495 atomic_dec(&net_device->num_outstanding_sends);
496 } else {
497 dev_err(&device->device, "Unknown send completion packet type- "
498 "%d received!!", nvsp_packet->hdr.msg_type);
499 }
500
501 put_net_device(device);
502}
503
504int netvsc_send(struct hv_device *device,
505 struct hv_netvsc_packet *packet)
506{
507 struct netvsc_device *net_device;
508 int ret = 0;
509
510 struct nvsp_message sendMessage;
511
512 net_device = get_outbound_net_device(device);
513 if (!net_device) {
514 dev_err(&device->device, "net device (%p) shutting down..."
515 "ignoring outbound packets", net_device);
516 return -2;
517 }
518
519 sendMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
520 if (packet->is_data_pkt) {
521 /* 0 is RMC_DATA; */
522 sendMessage.msg.v1_msg.send_rndis_pkt.channel_type = 0;
523 } else {
524 /* 1 is RMC_CONTROL; */
525 sendMessage.msg.v1_msg.send_rndis_pkt.channel_type = 1;
526 }
527
528 /* Not using send buffer section */
529 sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_index =
530 0xFFFFFFFF;
531 sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0;
532
533 if (packet->page_buf_cnt) {
534 ret = vmbus_sendpacket_pagebuffer(device->channel,
535 packet->page_buf,
536 packet->page_buf_cnt,
537 &sendMessage,
538 sizeof(struct nvsp_message),
539 (unsigned long)packet);
540 } else {
541 ret = vmbus_sendpacket(device->channel, &sendMessage,
542 sizeof(struct nvsp_message),
543 (unsigned long)packet,
544 VM_PKT_DATA_INBAND,
545 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
546
547 }
548
549 if (ret != 0)
550 dev_err(&device->device, "Unable to send packet %p ret %d",
551 packet, ret);
552
553 atomic_inc(&net_device->num_outstanding_sends);
554 put_net_device(device);
555 return ret;
556}
557
558static void netvsc_send_recv_completion(struct hv_device *device,
559 u64 transaction_id)
560{
561 struct nvsp_message recvcompMessage;
562 int retries = 0;
563 int ret;
564
565 recvcompMessage.hdr.msg_type =
566 NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
567
568 /* FIXME: Pass in the status */
569 recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status =
570 NVSP_STAT_SUCCESS;
571
572retry_send_cmplt:
573 /* Send the completion */
574 ret = vmbus_sendpacket(device->channel, &recvcompMessage,
575 sizeof(struct nvsp_message), transaction_id,
576 VM_PKT_COMP, 0);
577 if (ret == 0) {
578 /* success */
579 /* no-op */
580 } else if (ret == -1) {
581 /* no more room...wait a bit and attempt to retry 3 times */
582 retries++;
583 dev_err(&device->device, "unable to send receive completion pkt"
584 " (tid %llx)...retrying %d", transaction_id, retries);
585
586 if (retries < 4) {
587 udelay(100);
588 goto retry_send_cmplt;
589 } else {
590 dev_err(&device->device, "unable to send receive "
591 "completion pkt (tid %llx)...give up retrying",
592 transaction_id);
593 }
594 } else {
595 dev_err(&device->device, "unable to send receive "
596 "completion pkt - %llx", transaction_id);
597 }
598}
599
600/* Send a receive completion packet to RNDIS device (ie NetVsp) */
601static void netvsc_receive_completion(void *context)
602{
603 struct hv_netvsc_packet *packet = context;
604 struct hv_device *device = (struct hv_device *)packet->device;
605 struct netvsc_device *net_device;
606 u64 transaction_id = 0;
607 bool fsend_receive_comp = false;
608 unsigned long flags;
609
610 /*
611 * Even though it seems logical to do a GetOutboundNetDevice() here to
612 * send out receive completion, we are using GetInboundNetDevice()
613 * since we may have disable outbound traffic already.
614 */
615 net_device = get_inbound_net_device(device);
616 if (!net_device) {
617 dev_err(&device->device, "unable to get net device..."
618 "device being destroyed?");
619 return;
620 }
621
622 /* Overloading use of the lock. */
623 spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
624
625 packet->xfer_page_pkt->count--;
626
627 /*
628 * Last one in the line that represent 1 xfer page packet.
629 * Return the xfer page packet itself to the freelist
630 */
631 if (packet->xfer_page_pkt->count == 0) {
632 fsend_receive_comp = true;
633 transaction_id = packet->completion.recv.recv_completion_tid;
634 list_add_tail(&packet->xfer_page_pkt->list_ent,
635 &net_device->recv_pkt_list);
636
637 }
638
639 /* Put the packet back */
640 list_add_tail(&packet->list_ent, &net_device->recv_pkt_list);
641 spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
642
643 /* Send a receive completion for the xfer page packet */
644 if (fsend_receive_comp)
645 netvsc_send_recv_completion(device, transaction_id);
646
647 put_net_device(device);
648}
649
650static void netvsc_receive(struct hv_device *device,
651 struct vmpacket_descriptor *packet)
652{
653 struct netvsc_device *net_device;
654 struct vmtransfer_page_packet_header *vmxferpage_packet;
655 struct nvsp_message *nvsp_packet;
656 struct hv_netvsc_packet *netvsc_packet = NULL;
657 unsigned long start;
658 unsigned long end, end_virtual;
659 /* struct netvsc_driver *netvscDriver; */
660 struct xferpage_packet *xferpage_packet = NULL;
661 int i, j;
662 int count = 0, bytes_remain = 0;
663 unsigned long flags;
664
665 LIST_HEAD(listHead);
666
667 net_device = get_inbound_net_device(device);
668 if (!net_device) {
669 dev_err(&device->device, "unable to get net device..."
670 "device being destroyed?");
671 return;
672 }
673
674 /*
675 * All inbound packets other than send completion should be xfer page
676 * packet
677 */
678 if (packet->type != VM_PKT_DATA_USING_XFER_PAGES) {
679 dev_err(&device->device, "Unknown packet type received - %d",
680 packet->type);
681 put_net_device(device);
682 return;
683 }
684
685 nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
686 (packet->offset8 << 3));
687
688 /* Make sure this is a valid nvsp packet */
689 if (nvsp_packet->hdr.msg_type !=
690 NVSP_MSG1_TYPE_SEND_RNDIS_PKT) {
691 dev_err(&device->device, "Unknown nvsp packet type received-"
692 " %d", nvsp_packet->hdr.msg_type);
693 put_net_device(device);
694 return;
695 }
696
697 vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet;
698
699 if (vmxferpage_packet->xfer_pageset_id != NETVSC_RECEIVE_BUFFER_ID) {
700 dev_err(&device->device, "Invalid xfer page set id - "
701 "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
702 vmxferpage_packet->xfer_pageset_id);
703 put_net_device(device);
704 return;
705 }
706
707 /*
708 * Grab free packets (range count + 1) to represent this xfer
709 * page packet. +1 to represent the xfer page packet itself.
710 * We grab it here so that we know exactly how many we can
711 * fulfil
712 */
713 spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
714 while (!list_empty(&net_device->recv_pkt_list)) {
715 list_move_tail(net_device->recv_pkt_list.next, &listHead);
716 if (++count == vmxferpage_packet->range_cnt + 1)
717 break;
718 }
719 spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
720
721 /*
722 * We need at least 2 netvsc pkts (1 to represent the xfer
723 * page and at least 1 for the range) i.e. we can handled
724 * some of the xfer page packet ranges...
725 */
726 if (count < 2) {
727 dev_err(&device->device, "Got only %d netvsc pkt...needed "
728 "%d pkts. Dropping this xfer page packet completely!",
729 count, vmxferpage_packet->range_cnt + 1);
730
731 /* Return it to the freelist */
732 spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
733 for (i = count; i != 0; i--) {
734 list_move_tail(listHead.next,
735 &net_device->recv_pkt_list);
736 }
737 spin_unlock_irqrestore(&net_device->recv_pkt_list_lock,
738 flags);
739
740 netvsc_send_recv_completion(device,
741 vmxferpage_packet->d.trans_id);
742
743 put_net_device(device);
744 return;
745 }
746
747 /* Remove the 1st packet to represent the xfer page packet itself */
748 xferpage_packet = (struct xferpage_packet *)listHead.next;
749 list_del(&xferpage_packet->list_ent);
750
751 /* This is how much we can satisfy */
752 xferpage_packet->count = count - 1;
753
754 if (xferpage_packet->count != vmxferpage_packet->range_cnt) {
755 dev_err(&device->device, "Needed %d netvsc pkts to satisy "
756 "this xfer page...got %d",
757 vmxferpage_packet->range_cnt, xferpage_packet->count);
758 }
759
760 /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
761 for (i = 0; i < (count - 1); i++) {
762 netvsc_packet = (struct hv_netvsc_packet *)listHead.next;
763 list_del(&netvsc_packet->list_ent);
764
765 /* Initialize the netvsc packet */
766 netvsc_packet->xfer_page_pkt = xferpage_packet;
767 netvsc_packet->completion.recv.recv_completion =
768 netvsc_receive_completion;
769 netvsc_packet->completion.recv.recv_completion_ctx =
770 netvsc_packet;
771 netvsc_packet->device = device;
772 /* Save this so that we can send it back */
773 netvsc_packet->completion.recv.recv_completion_tid =
774 vmxferpage_packet->d.trans_id;
775
776 netvsc_packet->total_data_buflen =
777 vmxferpage_packet->ranges[i].byte_count;
778 netvsc_packet->page_buf_cnt = 1;
779
780 netvsc_packet->page_buf[0].len =
781 vmxferpage_packet->ranges[i].byte_count;
782
783 start = virt_to_phys((void *)((unsigned long)net_device->
784 recv_buf + vmxferpage_packet->ranges[i].byte_offset));
785
786 netvsc_packet->page_buf[0].pfn = start >> PAGE_SHIFT;
787 end_virtual = (unsigned long)net_device->recv_buf
788 + vmxferpage_packet->ranges[i].byte_offset
789 + vmxferpage_packet->ranges[i].byte_count - 1;
790 end = virt_to_phys((void *)end_virtual);
791
792 /* Calculate the page relative offset */
793 netvsc_packet->page_buf[0].offset =
794 vmxferpage_packet->ranges[i].byte_offset &
795 (PAGE_SIZE - 1);
796 if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) {
797 /* Handle frame across multiple pages: */
798 netvsc_packet->page_buf[0].len =
799 (netvsc_packet->page_buf[0].pfn <<
800 PAGE_SHIFT)
801 + PAGE_SIZE - start;
802 bytes_remain = netvsc_packet->total_data_buflen -
803 netvsc_packet->page_buf[0].len;
804 for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) {
805 netvsc_packet->page_buf[j].offset = 0;
806 if (bytes_remain <= PAGE_SIZE) {
807 netvsc_packet->page_buf[j].len =
808 bytes_remain;
809 bytes_remain = 0;
810 } else {
811 netvsc_packet->page_buf[j].len =
812 PAGE_SIZE;
813 bytes_remain -= PAGE_SIZE;
814 }
815 netvsc_packet->page_buf[j].pfn =
816 virt_to_phys((void *)(end_virtual -
817 bytes_remain)) >> PAGE_SHIFT;
818 netvsc_packet->page_buf_cnt++;
819 if (bytes_remain == 0)
820 break;
821 }
822 }
823
824 /* Pass it to the upper layer */
825 rndis_filter_receive(device, netvsc_packet);
826
827 netvsc_receive_completion(netvsc_packet->
828 completion.recv.recv_completion_ctx);
829 }
830
831 put_net_device(device);
832}
833
834static void netvsc_channel_cb(void *context)
835{
836 int ret;
837 struct hv_device *device = context;
838 struct netvsc_device *net_device;
839 u32 bytes_recvd;
840 u64 request_id;
841 unsigned char *packet;
842 struct vmpacket_descriptor *desc;
843 unsigned char *buffer;
844 int bufferlen = NETVSC_PACKET_SIZE;
845
846 packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char),
847 GFP_ATOMIC);
848 if (!packet)
849 return;
850 buffer = packet;
851
852 net_device = get_inbound_net_device(device);
853 if (!net_device) {
854 dev_err(&device->device, "net device (%p) shutting down..."
855 "ignoring inbound packets", net_device);
856 goto out;
857 }
858
859 do {
860 ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen,
861 &bytes_recvd, &request_id);
862 if (ret == 0) {
863 if (bytes_recvd > 0) {
864 desc = (struct vmpacket_descriptor *)buffer;
865 switch (desc->type) {
866 case VM_PKT_COMP:
867 netvsc_send_completion(device, desc);
868 break;
869
870 case VM_PKT_DATA_USING_XFER_PAGES:
871 netvsc_receive(device, desc);
872 break;
873
874 default:
875 dev_err(&device->device,
876 "unhandled packet type %d, "
877 "tid %llx len %d\n",
878 desc->type, request_id,
879 bytes_recvd);
880 break;
881 }
882
883 /* reset */
884 if (bufferlen > NETVSC_PACKET_SIZE) {
885 kfree(buffer);
886 buffer = packet;
887 bufferlen = NETVSC_PACKET_SIZE;
888 }
889 } else {
890 /* reset */
891 if (bufferlen > NETVSC_PACKET_SIZE) {
892 kfree(buffer);
893 buffer = packet;
894 bufferlen = NETVSC_PACKET_SIZE;
895 }
896
897 break;
898 }
899 } else if (ret == -2) {
900 /* Handle large packet */
901 buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
902 if (buffer == NULL) {
903 /* Try again next time around */
904 dev_err(&device->device,
905 "unable to allocate buffer of size "
906 "(%d)!!", bytes_recvd);
907 break;
908 }
909
910 bufferlen = bytes_recvd;
911 }
912 } while (1);
913
914 put_net_device(device);
915out:
916 kfree(buffer);
917 return;
918}
919
920/*
921 * netvsc_device_add - Callback when the device belonging to this
922 * driver is added
923 */
924int netvsc_device_add(struct hv_device *device, void *additional_info)
925{
926 int ret = 0;
927 int i;
928 int ring_size =
929 ((struct netvsc_device_info *)additional_info)->ring_size;
930 struct netvsc_device *net_device;
931 struct hv_netvsc_packet *packet, *pos;
932
933 net_device = alloc_net_device(device);
934 if (!net_device) {
935 ret = -1;
936 goto cleanup;
937 }
938
939 /* Initialize the NetVSC channel extension */
940 net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
941 spin_lock_init(&net_device->recv_pkt_list_lock);
942
943 INIT_LIST_HEAD(&net_device->recv_pkt_list);
944
945 for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
946 packet = kzalloc(sizeof(struct hv_netvsc_packet) +
947 (NETVSC_RECEIVE_SG_COUNT *
948 sizeof(struct hv_page_buffer)), GFP_KERNEL);
949 if (!packet)
950 break;
951
952 list_add_tail(&packet->list_ent,
953 &net_device->recv_pkt_list);
954 }
955 init_completion(&net_device->channel_init_wait);
956
957 /* Open the channel */
958 ret = vmbus_open(device->channel, ring_size * PAGE_SIZE,
959 ring_size * PAGE_SIZE, NULL, 0,
960 netvsc_channel_cb, device);
961
962 if (ret != 0) {
963 dev_err(&device->device, "unable to open channel: %d", ret);
964 ret = -1;
965 goto cleanup;
966 }
967
968 /* Channel is opened */
969 pr_info("hv_netvsc channel opened successfully");
970
971 /* Connect with the NetVsp */
972 ret = netvsc_connect_vsp(device);
973 if (ret != 0) {
974 dev_err(&device->device,
975 "unable to connect to NetVSP - %d", ret);
976 ret = -1;
977 goto close;
978 }
979
980 return ret;
981
982close:
983 /* Now, we can close the channel safely */
984 vmbus_close(device->channel);
985
986cleanup:
987
988 if (net_device) {
989 list_for_each_entry_safe(packet, pos,
990 &net_device->recv_pkt_list,
991 list_ent) {
992 list_del(&packet->list_ent);
993 kfree(packet);
994 }
995
996 release_outbound_net_device(device);
997 release_inbound_net_device(device);
998
999 free_net_device(net_device);
1000 }
1001
1002 return ret;
1003}
1004
1005/*
1006 * netvsc_initialize - Main entry point
1007 */
1008int netvsc_initialize(struct hv_driver *drv)
1009{
1010
1011 drv->name = driver_name;
1012 memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid));
1013
1014 return 0;
1015}
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
new file mode 100644
index 00000000000..88d519359e6
--- /dev/null
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -0,0 +1,476 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 */
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/init.h>
24#include <linux/atomic.h>
25#include <linux/module.h>
26#include <linux/highmem.h>
27#include <linux/device.h>
28#include <linux/io.h>
29#include <linux/delay.h>
30#include <linux/netdevice.h>
31#include <linux/inetdevice.h>
32#include <linux/etherdevice.h>
33#include <linux/skbuff.h>
34#include <linux/in.h>
35#include <linux/slab.h>
36#include <linux/dmi.h>
37#include <linux/pci.h>
38#include <net/arp.h>
39#include <net/route.h>
40#include <net/sock.h>
41#include <net/pkt_sched.h>
42
43#include "hyperv.h"
44#include "hyperv_net.h"
45
46struct net_device_context {
47 /* point back to our device context */
48 struct hv_device *device_ctx;
49 atomic_t avail;
50 struct delayed_work dwork;
51};
52
53
54#define PACKET_PAGES_LOWATER 8
55/* Need this many pages to handle worst case fragmented packet */
56#define PACKET_PAGES_HIWATER (MAX_SKB_FRAGS + 2)
57
58static int ring_size = 128;
59module_param(ring_size, int, S_IRUGO);
60MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
61
62/* no-op so the netdev core doesn't return -EINVAL when modifying the the
63 * multicast address list in SIOCADDMULTI. hv is setup to get all multicast
64 * when it calls RndisFilterOnOpen() */
65static void netvsc_set_multicast_list(struct net_device *net)
66{
67}
68
69static int netvsc_open(struct net_device *net)
70{
71 struct net_device_context *net_device_ctx = netdev_priv(net);
72 struct hv_device *device_obj = net_device_ctx->device_ctx;
73 int ret = 0;
74
75 if (netif_carrier_ok(net)) {
76 /* Open up the device */
77 ret = rndis_filter_open(device_obj);
78 if (ret != 0) {
79 netdev_err(net, "unable to open device (ret %d).\n",
80 ret);
81 return ret;
82 }
83
84 netif_start_queue(net);
85 } else {
86 netdev_err(net, "unable to open device...link is down.\n");
87 }
88
89 return ret;
90}
91
92static int netvsc_close(struct net_device *net)
93{
94 struct net_device_context *net_device_ctx = netdev_priv(net);
95 struct hv_device *device_obj = net_device_ctx->device_ctx;
96 int ret;
97
98 netif_stop_queue(net);
99
100 ret = rndis_filter_close(device_obj);
101 if (ret != 0)
102 netdev_err(net, "unable to close device (ret %d).\n", ret);
103
104 return ret;
105}
106
107static void netvsc_xmit_completion(void *context)
108{
109 struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
110 struct sk_buff *skb = (struct sk_buff *)
111 (unsigned long)packet->completion.send.send_completion_tid;
112
113 kfree(packet);
114
115 if (skb) {
116 struct net_device *net = skb->dev;
117 struct net_device_context *net_device_ctx = netdev_priv(net);
118 unsigned int num_pages = skb_shinfo(skb)->nr_frags + 2;
119
120 dev_kfree_skb_any(skb);
121
122 atomic_add(num_pages, &net_device_ctx->avail);
123 if (atomic_read(&net_device_ctx->avail) >=
124 PACKET_PAGES_HIWATER)
125 netif_wake_queue(net);
126 }
127}
128
129static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
130{
131 struct net_device_context *net_device_ctx = netdev_priv(net);
132 struct hv_netvsc_packet *packet;
133 int ret;
134 unsigned int i, num_pages;
135
136 /* Add 1 for skb->data and additional one for RNDIS */
137 num_pages = skb_shinfo(skb)->nr_frags + 1 + 1;
138 if (num_pages > atomic_read(&net_device_ctx->avail))
139 return NETDEV_TX_BUSY;
140
141 /* Allocate a netvsc packet based on # of frags. */
142 packet = kzalloc(sizeof(struct hv_netvsc_packet) +
143 (num_pages * sizeof(struct hv_page_buffer)) +
144 sizeof(struct rndis_filter_packet), GFP_ATOMIC);
145 if (!packet) {
146 /* out of memory, silently drop packet */
147 netdev_err(net, "unable to allocate hv_netvsc_packet\n");
148
149 dev_kfree_skb(skb);
150 net->stats.tx_dropped++;
151 return NETDEV_TX_OK;
152 }
153
154 packet->extension = (void *)(unsigned long)packet +
155 sizeof(struct hv_netvsc_packet) +
156 (num_pages * sizeof(struct hv_page_buffer));
157
158 /* Setup the rndis header */
159 packet->page_buf_cnt = num_pages;
160
161 /* Initialize it from the skb */
162 packet->total_data_buflen = skb->len;
163
164 /* Start filling in the page buffers starting after RNDIS buffer. */
165 packet->page_buf[1].pfn = virt_to_phys(skb->data) >> PAGE_SHIFT;
166 packet->page_buf[1].offset
167 = (unsigned long)skb->data & (PAGE_SIZE - 1);
168 packet->page_buf[1].len = skb_headlen(skb);
169
170 /* Additional fragments are after SKB data */
171 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
172 skb_frag_t *f = &skb_shinfo(skb)->frags[i];
173
174 packet->page_buf[i+2].pfn = page_to_pfn(f->page);
175 packet->page_buf[i+2].offset = f->page_offset;
176 packet->page_buf[i+2].len = f->size;
177 }
178
179 /* Set the completion routine */
180 packet->completion.send.send_completion = netvsc_xmit_completion;
181 packet->completion.send.send_completion_ctx = packet;
182 packet->completion.send.send_completion_tid = (unsigned long)skb;
183
184 ret = rndis_filter_send(net_device_ctx->device_ctx,
185 packet);
186 if (ret == 0) {
187 net->stats.tx_bytes += skb->len;
188 net->stats.tx_packets++;
189
190 atomic_sub(num_pages, &net_device_ctx->avail);
191 if (atomic_read(&net_device_ctx->avail) < PACKET_PAGES_LOWATER)
192 netif_stop_queue(net);
193 } else {
194 /* we are shutting down or bus overloaded, just drop packet */
195 net->stats.tx_dropped++;
196 netvsc_xmit_completion(packet);
197 }
198
199 return NETDEV_TX_OK;
200}
201
202/*
203 * netvsc_linkstatus_callback - Link up/down notification
204 */
205void netvsc_linkstatus_callback(struct hv_device *device_obj,
206 unsigned int status)
207{
208 struct net_device *net = dev_get_drvdata(&device_obj->device);
209 struct net_device_context *ndev_ctx;
210
211 if (!net) {
212 netdev_err(net, "got link status but net device "
213 "not initialized yet\n");
214 return;
215 }
216
217 if (status == 1) {
218 netif_carrier_on(net);
219 netif_wake_queue(net);
220 ndev_ctx = netdev_priv(net);
221 schedule_delayed_work(&ndev_ctx->dwork, 0);
222 schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
223 } else {
224 netif_carrier_off(net);
225 netif_stop_queue(net);
226 }
227}
228
229/*
230 * netvsc_recv_callback - Callback when we receive a packet from the
231 * "wire" on the specified device.
232 */
233int netvsc_recv_callback(struct hv_device *device_obj,
234 struct hv_netvsc_packet *packet)
235{
236 struct net_device *net = dev_get_drvdata(&device_obj->device);
237 struct sk_buff *skb;
238 void *data;
239 int i;
240 unsigned long flags;
241
242 if (!net) {
243 netdev_err(net, "got receive callback but net device"
244 " not initialized yet\n");
245 return 0;
246 }
247
248 /* Allocate a skb - TODO direct I/O to pages? */
249 skb = netdev_alloc_skb_ip_align(net, packet->total_data_buflen);
250 if (unlikely(!skb)) {
251 ++net->stats.rx_dropped;
252 return 0;
253 }
254
255 /* for kmap_atomic */
256 local_irq_save(flags);
257
258 /*
259 * Copy to skb. This copy is needed here since the memory pointed by
260 * hv_netvsc_packet cannot be deallocated
261 */
262 for (i = 0; i < packet->page_buf_cnt; i++) {
263 data = kmap_atomic(pfn_to_page(packet->page_buf[i].pfn),
264 KM_IRQ1);
265 data = (void *)(unsigned long)data +
266 packet->page_buf[i].offset;
267
268 memcpy(skb_put(skb, packet->page_buf[i].len), data,
269 packet->page_buf[i].len);
270
271 kunmap_atomic((void *)((unsigned long)data -
272 packet->page_buf[i].offset), KM_IRQ1);
273 }
274
275 local_irq_restore(flags);
276
277 skb->protocol = eth_type_trans(skb, net);
278 skb->ip_summed = CHECKSUM_NONE;
279
280 net->stats.rx_packets++;
281 net->stats.rx_bytes += skb->len;
282
283 /*
284 * Pass the skb back up. Network stack will deallocate the skb when it
285 * is done.
286 * TODO - use NAPI?
287 */
288 netif_rx(skb);
289
290 return 0;
291}
292
293static void netvsc_get_drvinfo(struct net_device *net,
294 struct ethtool_drvinfo *info)
295{
296 strcpy(info->driver, "hv_netvsc");
297 strcpy(info->version, HV_DRV_VERSION);
298 strcpy(info->fw_version, "N/A");
299}
300
301static const struct ethtool_ops ethtool_ops = {
302 .get_drvinfo = netvsc_get_drvinfo,
303 .get_link = ethtool_op_get_link,
304};
305
306static const struct net_device_ops device_ops = {
307 .ndo_open = netvsc_open,
308 .ndo_stop = netvsc_close,
309 .ndo_start_xmit = netvsc_start_xmit,
310 .ndo_set_multicast_list = netvsc_set_multicast_list,
311 .ndo_change_mtu = eth_change_mtu,
312 .ndo_validate_addr = eth_validate_addr,
313 .ndo_set_mac_address = eth_mac_addr,
314};
315
316/*
317 * Send GARP packet to network peers after migrations.
318 * After Quick Migration, the network is not immediately operational in the
319 * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add
320 * another netif_notify_peers() into a delayed work, otherwise GARP packet
321 * will not be sent after quick migration, and cause network disconnection.
322 */
323static void netvsc_send_garp(struct work_struct *w)
324{
325 struct net_device_context *ndev_ctx;
326 struct net_device *net;
327
328 ndev_ctx = container_of(w, struct net_device_context, dwork.work);
329 net = dev_get_drvdata(&ndev_ctx->device_ctx->device);
330 netif_notify_peers(net);
331}
332
333
334static int netvsc_probe(struct hv_device *dev)
335{
336 struct net_device *net = NULL;
337 struct net_device_context *net_device_ctx;
338 struct netvsc_device_info device_info;
339 int ret;
340
341 net = alloc_etherdev(sizeof(struct net_device_context));
342 if (!net)
343 return -1;
344
345 /* Set initial state */
346 netif_carrier_off(net);
347
348 net_device_ctx = netdev_priv(net);
349 net_device_ctx->device_ctx = dev;
350 atomic_set(&net_device_ctx->avail, ring_size);
351 dev_set_drvdata(&dev->device, net);
352 INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp);
353
354 /* Notify the netvsc driver of the new device */
355 device_info.ring_size = ring_size;
356 ret = rndis_filter_device_add(dev, &device_info);
357 if (ret != 0) {
358 free_netdev(net);
359 dev_set_drvdata(&dev->device, NULL);
360
361 netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
362 return ret;
363 }
364
365 netif_carrier_on(net);
366
367 memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
368
369 net->netdev_ops = &device_ops;
370
371 /* TODO: Add GSO and Checksum offload */
372 net->hw_features = NETIF_F_SG;
373 net->features = NETIF_F_SG;
374
375 SET_ETHTOOL_OPS(net, &ethtool_ops);
376 SET_NETDEV_DEV(net, &dev->device);
377
378 ret = register_netdev(net);
379 if (ret != 0) {
380 /* Remove the device and release the resource */
381 rndis_filter_device_remove(dev);
382 free_netdev(net);
383 }
384
385 return ret;
386}
387
388static int netvsc_remove(struct hv_device *dev)
389{
390 struct net_device *net = dev_get_drvdata(&dev->device);
391 struct net_device_context *ndev_ctx;
392
393 if (net == NULL) {
394 dev_err(&dev->device, "No net device to remove\n");
395 return 0;
396 }
397
398 ndev_ctx = netdev_priv(net);
399 cancel_delayed_work_sync(&ndev_ctx->dwork);
400
401 /* Stop outbound asap */
402 netif_stop_queue(net);
403
404 unregister_netdev(net);
405
406 /*
407 * Call to the vsc driver to let it know that the device is being
408 * removed
409 */
410 rndis_filter_device_remove(dev);
411
412 free_netdev(net);
413 return 0;
414}
415
416/* The one and only one */
417static struct hv_driver netvsc_drv = {
418 .probe = netvsc_probe,
419 .remove = netvsc_remove,
420};
421
422static void __exit netvsc_drv_exit(void)
423{
424 vmbus_child_driver_unregister(&netvsc_drv.driver);
425}
426
427
428static const struct dmi_system_id __initconst
429hv_netvsc_dmi_table[] __maybe_unused = {
430 {
431 .ident = "Hyper-V",
432 .matches = {
433 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
434 DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
435 DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
436 },
437 },
438 { },
439};
440MODULE_DEVICE_TABLE(dmi, hv_netvsc_dmi_table);
441
442static int __init netvsc_drv_init(void)
443{
444 struct hv_driver *drv = &netvsc_drv;
445 int ret;
446
447 pr_info("initializing....");
448
449 if (!dmi_check_system(hv_netvsc_dmi_table))
450 return -ENODEV;
451
452
453 /* Callback to client driver to complete the initialization */
454 netvsc_initialize(drv);
455
456 drv->driver.name = drv->name;
457
458 /* The driver belongs to vmbus */
459 ret = vmbus_child_driver_register(&drv->driver);
460
461 return ret;
462}
463
464static const struct pci_device_id __initconst
465hv_netvsc_pci_table[] __maybe_unused = {
466 { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
467 { 0 }
468};
469MODULE_DEVICE_TABLE(pci, hv_netvsc_pci_table);
470
471MODULE_LICENSE("GPL");
472MODULE_VERSION(HV_DRV_VERSION);
473MODULE_DESCRIPTION("Microsoft Hyper-V network driver");
474
475module_init(netvsc_drv_init);
476module_exit(netvsc_drv_exit);
diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c
new file mode 100644
index 00000000000..42f76728429
--- /dev/null
+++ b/drivers/staging/hv/ring_buffer.c
@@ -0,0 +1,526 @@
1/*
2 *
3 * Copyright (c) 2009, 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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26#include <linux/kernel.h>
27#include <linux/mm.h>
28
29#include "hyperv.h"
30#include "hyperv_vmbus.h"
31
32
33/* #defines */
34
35
36/* Amount of space to write to */
37#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
38
39
40/*
41 *
42 * hv_get_ringbuffer_availbytes()
43 *
44 * Get number of bytes available to read and to write to
45 * for the specified ring buffer
46 */
47static inline void
48hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
49 u32 *read, u32 *write)
50{
51 u32 read_loc, write_loc;
52
53 smp_read_barrier_depends();
54
55 /* Capture the read/write indices before they changed */
56 read_loc = rbi->ring_buffer->read_index;
57 write_loc = rbi->ring_buffer->write_index;
58
59 *write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->ring_datasize);
60 *read = rbi->ring_datasize - *write;
61}
62
63/*
64 * hv_get_next_write_location()
65 *
66 * Get the next write location for the specified ring buffer
67 *
68 */
69static inline u32
70hv_get_next_write_location(struct hv_ring_buffer_info *ring_info)
71{
72 u32 next = ring_info->ring_buffer->write_index;
73
74 return next;
75}
76
77/*
78 * hv_set_next_write_location()
79 *
80 * Set the next write location for the specified ring buffer
81 *
82 */
83static inline void
84hv_set_next_write_location(struct hv_ring_buffer_info *ring_info,
85 u32 next_write_location)
86{
87 ring_info->ring_buffer->write_index = next_write_location;
88}
89
90/*
91 * hv_get_next_read_location()
92 *
93 * Get the next read location for the specified ring buffer
94 */
95static inline u32
96hv_get_next_read_location(struct hv_ring_buffer_info *ring_info)
97{
98 u32 next = ring_info->ring_buffer->read_index;
99
100 return next;
101}
102
103/*
104 * hv_get_next_readlocation_withoffset()
105 *
106 * Get the next read location + offset for the specified ring buffer.
107 * This allows the caller to skip
108 */
109static inline u32
110hv_get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
111 u32 offset)
112{
113 u32 next = ring_info->ring_buffer->read_index;
114
115 next += offset;
116 next %= ring_info->ring_datasize;
117
118 return next;
119}
120
121/*
122 *
123 * hv_set_next_read_location()
124 *
125 * Set the next read location for the specified ring buffer
126 *
127 */
128static inline void
129hv_set_next_read_location(struct hv_ring_buffer_info *ring_info,
130 u32 next_read_location)
131{
132 ring_info->ring_buffer->read_index = next_read_location;
133}
134
135
136/*
137 *
138 * hv_get_ring_buffer()
139 *
140 * Get the start of the ring buffer
141 */
142static inline void *
143hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
144{
145 return (void *)ring_info->ring_buffer->buffer;
146}
147
148
149/*
150 *
151 * hv_get_ring_buffersize()
152 *
153 * Get the size of the ring buffer
154 */
155static inline u32
156hv_get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
157{
158 return ring_info->ring_datasize;
159}
160
161/*
162 *
163 * hv_get_ring_bufferindices()
164 *
165 * Get the read and write indices as u64 of the specified ring buffer
166 *
167 */
168static inline u64
169hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
170{
171 return (u64)ring_info->ring_buffer->write_index << 32;
172}
173
174
175/*
176 *
177 * hv_dump_ring_info()
178 *
179 * Dump out to console the ring buffer info
180 *
181 */
182void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
183{
184 u32 bytes_avail_towrite;
185 u32 bytes_avail_toread;
186
187 hv_get_ringbuffer_availbytes(ring_info,
188 &bytes_avail_toread,
189 &bytes_avail_towrite);
190
191 DPRINT(VMBUS,
192 DEBUG_RING_LVL,
193 "%s <<ringinfo %p buffer %p avail write %u "
194 "avail read %u read idx %u write idx %u>>",
195 prefix,
196 ring_info,
197 ring_info->ring_buffer->buffer,
198 bytes_avail_towrite,
199 bytes_avail_toread,
200 ring_info->ring_buffer->read_index,
201 ring_info->ring_buffer->write_index);
202}
203
204
205/*
206 *
207 * hv_copyfrom_ringbuffer()
208 *
209 * Helper routine to copy to source from ring buffer.
210 * Assume there is enough room. Handles wrap-around in src case only!!
211 *
212 */
213static u32 hv_copyfrom_ringbuffer(
214 struct hv_ring_buffer_info *ring_info,
215 void *dest,
216 u32 destlen,
217 u32 start_read_offset)
218{
219 void *ring_buffer = hv_get_ring_buffer(ring_info);
220 u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
221
222 u32 frag_len;
223
224 /* wrap-around detected at the src */
225 if (destlen > ring_buffer_size - start_read_offset) {
226 frag_len = ring_buffer_size - start_read_offset;
227
228 memcpy(dest, ring_buffer + start_read_offset, frag_len);
229 memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
230 } else
231
232 memcpy(dest, ring_buffer + start_read_offset, destlen);
233
234
235 start_read_offset += destlen;
236 start_read_offset %= ring_buffer_size;
237
238 return start_read_offset;
239}
240
241
242/*
243 *
244 * hv_copyto_ringbuffer()
245 *
246 * Helper routine to copy from source to ring buffer.
247 * Assume there is enough room. Handles wrap-around in dest case only!!
248 *
249 */
250static u32 hv_copyto_ringbuffer(
251 struct hv_ring_buffer_info *ring_info,
252 u32 start_write_offset,
253 void *src,
254 u32 srclen)
255{
256 void *ring_buffer = hv_get_ring_buffer(ring_info);
257 u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
258 u32 frag_len;
259
260 /* wrap-around detected! */
261 if (srclen > ring_buffer_size - start_write_offset) {
262 frag_len = ring_buffer_size - start_write_offset;
263 memcpy(ring_buffer + start_write_offset, src, frag_len);
264 memcpy(ring_buffer, src + frag_len, srclen - frag_len);
265 } else
266 memcpy(ring_buffer + start_write_offset, src, srclen);
267
268 start_write_offset += srclen;
269 start_write_offset %= ring_buffer_size;
270
271 return start_write_offset;
272}
273
274/*
275 *
276 * hv_ringbuffer_get_debuginfo()
277 *
278 * Get various debug metrics for the specified ring buffer
279 *
280 */
281void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
282 struct hv_ring_buffer_debug_info *debug_info)
283{
284 u32 bytes_avail_towrite;
285 u32 bytes_avail_toread;
286
287 if (ring_info->ring_buffer) {
288 hv_get_ringbuffer_availbytes(ring_info,
289 &bytes_avail_toread,
290 &bytes_avail_towrite);
291
292 debug_info->bytes_avail_toread = bytes_avail_toread;
293 debug_info->bytes_avail_towrite = bytes_avail_towrite;
294 debug_info->current_read_index =
295 ring_info->ring_buffer->read_index;
296 debug_info->current_write_index =
297 ring_info->ring_buffer->write_index;
298 debug_info->current_interrupt_mask =
299 ring_info->ring_buffer->interrupt_mask;
300 }
301}
302
303
304/*
305 *
306 * hv_get_ringbuffer_interrupt_mask()
307 *
308 * Get the interrupt mask for the specified ring buffer
309 *
310 */
311u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
312{
313 return rbi->ring_buffer->interrupt_mask;
314}
315
316/*
317 *
318 * hv_ringbuffer_init()
319 *
320 *Initialize the ring buffer
321 *
322 */
323int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
324 void *buffer, u32 buflen)
325{
326 if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
327 return -EINVAL;
328
329 memset(ring_info, 0, sizeof(struct hv_ring_buffer_info));
330
331 ring_info->ring_buffer = (struct hv_ring_buffer *)buffer;
332 ring_info->ring_buffer->read_index =
333 ring_info->ring_buffer->write_index = 0;
334
335 ring_info->ring_size = buflen;
336 ring_info->ring_datasize = buflen - sizeof(struct hv_ring_buffer);
337
338 spin_lock_init(&ring_info->ring_lock);
339
340 return 0;
341}
342
343/*
344 *
345 * hv_ringbuffer_cleanup()
346 *
347 * Cleanup the ring buffer
348 *
349 */
350void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
351{
352}
353
354/*
355 *
356 * hv_ringbuffer_write()
357 *
358 * Write to the ring buffer
359 *
360 */
361int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
362 struct scatterlist *sglist, u32 sgcount)
363{
364 int i = 0;
365 u32 bytes_avail_towrite;
366 u32 bytes_avail_toread;
367 u32 totalbytes_towrite = 0;
368
369 struct scatterlist *sg;
370 u32 next_write_location;
371 u64 prev_indices = 0;
372 unsigned long flags;
373
374 for_each_sg(sglist, sg, sgcount, i)
375 {
376 totalbytes_towrite += sg->length;
377 }
378
379 totalbytes_towrite += sizeof(u64);
380
381 spin_lock_irqsave(&outring_info->ring_lock, flags);
382
383 hv_get_ringbuffer_availbytes(outring_info,
384 &bytes_avail_toread,
385 &bytes_avail_towrite);
386
387
388 /* If there is only room for the packet, assume it is full. */
389 /* Otherwise, the next time around, we think the ring buffer */
390 /* is empty since the read index == write index */
391 if (bytes_avail_towrite <= totalbytes_towrite) {
392 spin_unlock_irqrestore(&outring_info->ring_lock, flags);
393 return -1;
394 }
395
396 /* Write to the ring buffer */
397 next_write_location = hv_get_next_write_location(outring_info);
398
399 for_each_sg(sglist, sg, sgcount, i)
400 {
401 next_write_location = hv_copyto_ringbuffer(outring_info,
402 next_write_location,
403 sg_virt(sg),
404 sg->length);
405 }
406
407 /* Set previous packet start */
408 prev_indices = hv_get_ring_bufferindices(outring_info);
409
410 next_write_location = hv_copyto_ringbuffer(outring_info,
411 next_write_location,
412 &prev_indices,
413 sizeof(u64));
414
415 /* Make sure we flush all writes before updating the writeIndex */
416 smp_wmb();
417
418 /* Now, update the write location */
419 hv_set_next_write_location(outring_info, next_write_location);
420
421
422 spin_unlock_irqrestore(&outring_info->ring_lock, flags);
423 return 0;
424}
425
426
427/*
428 *
429 * hv_ringbuffer_peek()
430 *
431 * Read without advancing the read index
432 *
433 */
434int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
435 void *Buffer, u32 buflen)
436{
437 u32 bytes_avail_towrite;
438 u32 bytes_avail_toread;
439 u32 next_read_location = 0;
440 unsigned long flags;
441
442 spin_lock_irqsave(&Inring_info->ring_lock, flags);
443
444 hv_get_ringbuffer_availbytes(Inring_info,
445 &bytes_avail_toread,
446 &bytes_avail_towrite);
447
448 /* Make sure there is something to read */
449 if (bytes_avail_toread < buflen) {
450
451 spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
452
453 return -1;
454 }
455
456 /* Convert to byte offset */
457 next_read_location = hv_get_next_read_location(Inring_info);
458
459 next_read_location = hv_copyfrom_ringbuffer(Inring_info,
460 Buffer,
461 buflen,
462 next_read_location);
463
464 spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
465
466 return 0;
467}
468
469
470/*
471 *
472 * hv_ringbuffer_read()
473 *
474 * Read and advance the read index
475 *
476 */
477int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
478 u32 buflen, u32 offset)
479{
480 u32 bytes_avail_towrite;
481 u32 bytes_avail_toread;
482 u32 next_read_location = 0;
483 u64 prev_indices = 0;
484 unsigned long flags;
485
486 if (buflen <= 0)
487 return -EINVAL;
488
489 spin_lock_irqsave(&inring_info->ring_lock, flags);
490
491 hv_get_ringbuffer_availbytes(inring_info,
492 &bytes_avail_toread,
493 &bytes_avail_towrite);
494
495 /* Make sure there is something to read */
496 if (bytes_avail_toread < buflen) {
497 spin_unlock_irqrestore(&inring_info->ring_lock, flags);
498
499 return -1;
500 }
501
502 next_read_location =
503 hv_get_next_readlocation_withoffset(inring_info, offset);
504
505 next_read_location = hv_copyfrom_ringbuffer(inring_info,
506 buffer,
507 buflen,
508 next_read_location);
509
510 next_read_location = hv_copyfrom_ringbuffer(inring_info,
511 &prev_indices,
512 sizeof(u64),
513 next_read_location);
514
515 /* Make sure all reads are done before we update the read index since */
516 /* the writer may start writing to the read area once the read index */
517 /*is updated */
518 smp_mb();
519
520 /* Update the read index */
521 hv_set_next_read_location(inring_info, next_read_location);
522
523 spin_unlock_irqrestore(&inring_info->ring_lock, flags);
524
525 return 0;
526}
diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c
new file mode 100644
index 00000000000..dbb52019975
--- /dev/null
+++ b/drivers/staging/hv/rndis_filter.c
@@ -0,0 +1,831 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 */
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/wait.h>
24#include <linux/highmem.h>
25#include <linux/slab.h>
26#include <linux/io.h>
27#include <linux/if_ether.h>
28#include <linux/netdevice.h>
29
30#include "hyperv.h"
31#include "hyperv_net.h"
32
33
34enum rndis_device_state {
35 RNDIS_DEV_UNINITIALIZED = 0,
36 RNDIS_DEV_INITIALIZING,
37 RNDIS_DEV_INITIALIZED,
38 RNDIS_DEV_DATAINITIALIZED,
39};
40
41struct rndis_device {
42 struct netvsc_device *net_dev;
43
44 enum rndis_device_state state;
45 u32 link_stat;
46 atomic_t new_req_id;
47
48 spinlock_t request_lock;
49 struct list_head req_list;
50
51 unsigned char hw_mac_adr[ETH_ALEN];
52};
53
54struct rndis_request {
55 struct list_head list_ent;
56 struct completion wait_event;
57
58 /*
59 * FIXME: We assumed a fixed size response here. If we do ever need to
60 * handle a bigger response, we can either define a max response
61 * message or add a response buffer variable above this field
62 */
63 struct rndis_message response_msg;
64
65 /* Simplify allocation by having a netvsc packet inline */
66 struct hv_netvsc_packet pkt;
67 struct hv_page_buffer buf;
68 /* FIXME: We assumed a fixed size request here. */
69 struct rndis_message request_msg;
70};
71
72static void rndis_filter_send_completion(void *ctx);
73
74static void rndis_filter_send_request_completion(void *ctx);
75
76
77
78static struct rndis_device *get_rndis_device(void)
79{
80 struct rndis_device *device;
81
82 device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
83 if (!device)
84 return NULL;
85
86 spin_lock_init(&device->request_lock);
87
88 INIT_LIST_HEAD(&device->req_list);
89
90 device->state = RNDIS_DEV_UNINITIALIZED;
91
92 return device;
93}
94
95static struct rndis_request *get_rndis_request(struct rndis_device *dev,
96 u32 msg_type,
97 u32 msg_len)
98{
99 struct rndis_request *request;
100 struct rndis_message *rndis_msg;
101 struct rndis_set_request *set;
102 unsigned long flags;
103
104 request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
105 if (!request)
106 return NULL;
107
108 init_completion(&request->wait_event);
109
110 rndis_msg = &request->request_msg;
111 rndis_msg->ndis_msg_type = msg_type;
112 rndis_msg->msg_len = msg_len;
113
114 /*
115 * Set the request id. This field is always after the rndis header for
116 * request/response packet types so we just used the SetRequest as a
117 * template
118 */
119 set = &rndis_msg->msg.set_req;
120 set->req_id = atomic_inc_return(&dev->new_req_id);
121
122 /* Add to the request list */
123 spin_lock_irqsave(&dev->request_lock, flags);
124 list_add_tail(&request->list_ent, &dev->req_list);
125 spin_unlock_irqrestore(&dev->request_lock, flags);
126
127 return request;
128}
129
130static void put_rndis_request(struct rndis_device *dev,
131 struct rndis_request *req)
132{
133 unsigned long flags;
134
135 spin_lock_irqsave(&dev->request_lock, flags);
136 list_del(&req->list_ent);
137 spin_unlock_irqrestore(&dev->request_lock, flags);
138
139 kfree(req);
140}
141
142static void dump_rndis_message(struct hv_device *hv_dev,
143 struct rndis_message *rndis_msg)
144{
145 struct net_device *netdev = dev_get_drvdata(&hv_dev->device);
146
147 switch (rndis_msg->ndis_msg_type) {
148 case REMOTE_NDIS_PACKET_MSG:
149 netdev_dbg(netdev, "REMOTE_NDIS_PACKET_MSG (len %u, "
150 "data offset %u data len %u, # oob %u, "
151 "oob offset %u, oob len %u, pkt offset %u, "
152 "pkt len %u\n",
153 rndis_msg->msg_len,
154 rndis_msg->msg.pkt.data_offset,
155 rndis_msg->msg.pkt.data_len,
156 rndis_msg->msg.pkt.num_oob_data_elements,
157 rndis_msg->msg.pkt.oob_data_offset,
158 rndis_msg->msg.pkt.oob_data_len,
159 rndis_msg->msg.pkt.per_pkt_info_offset,
160 rndis_msg->msg.pkt.per_pkt_info_len);
161 break;
162
163 case REMOTE_NDIS_INITIALIZE_CMPLT:
164 netdev_dbg(netdev, "REMOTE_NDIS_INITIALIZE_CMPLT "
165 "(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
166 "device flags %d, max xfer size 0x%x, max pkts %u, "
167 "pkt aligned %u)\n",
168 rndis_msg->msg_len,
169 rndis_msg->msg.init_complete.req_id,
170 rndis_msg->msg.init_complete.status,
171 rndis_msg->msg.init_complete.major_ver,
172 rndis_msg->msg.init_complete.minor_ver,
173 rndis_msg->msg.init_complete.dev_flags,
174 rndis_msg->msg.init_complete.max_xfer_size,
175 rndis_msg->msg.init_complete.
176 max_pkt_per_msg,
177 rndis_msg->msg.init_complete.
178 pkt_alignment_factor);
179 break;
180
181 case REMOTE_NDIS_QUERY_CMPLT:
182 netdev_dbg(netdev, "REMOTE_NDIS_QUERY_CMPLT "
183 "(len %u, id 0x%x, status 0x%x, buf len %u, "
184 "buf offset %u)\n",
185 rndis_msg->msg_len,
186 rndis_msg->msg.query_complete.req_id,
187 rndis_msg->msg.query_complete.status,
188 rndis_msg->msg.query_complete.
189 info_buflen,
190 rndis_msg->msg.query_complete.
191 info_buf_offset);
192 break;
193
194 case REMOTE_NDIS_SET_CMPLT:
195 netdev_dbg(netdev,
196 "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)\n",
197 rndis_msg->msg_len,
198 rndis_msg->msg.set_complete.req_id,
199 rndis_msg->msg.set_complete.status);
200 break;
201
202 case REMOTE_NDIS_INDICATE_STATUS_MSG:
203 netdev_dbg(netdev, "REMOTE_NDIS_INDICATE_STATUS_MSG "
204 "(len %u, status 0x%x, buf len %u, buf offset %u)\n",
205 rndis_msg->msg_len,
206 rndis_msg->msg.indicate_status.status,
207 rndis_msg->msg.indicate_status.status_buflen,
208 rndis_msg->msg.indicate_status.status_buf_offset);
209 break;
210
211 default:
212 netdev_dbg(netdev, "0x%x (len %u)\n",
213 rndis_msg->ndis_msg_type,
214 rndis_msg->msg_len);
215 break;
216 }
217}
218
219static int rndis_filter_send_request(struct rndis_device *dev,
220 struct rndis_request *req)
221{
222 int ret;
223 struct hv_netvsc_packet *packet;
224
225 /* Setup the packet to send it */
226 packet = &req->pkt;
227
228 packet->is_data_pkt = false;
229 packet->total_data_buflen = req->request_msg.msg_len;
230 packet->page_buf_cnt = 1;
231
232 packet->page_buf[0].pfn = virt_to_phys(&req->request_msg) >>
233 PAGE_SHIFT;
234 packet->page_buf[0].len = req->request_msg.msg_len;
235 packet->page_buf[0].offset =
236 (unsigned long)&req->request_msg & (PAGE_SIZE - 1);
237
238 packet->completion.send.send_completion_ctx = req;/* packet; */
239 packet->completion.send.send_completion =
240 rndis_filter_send_request_completion;
241 packet->completion.send.send_completion_tid = (unsigned long)dev;
242
243 ret = netvsc_send(dev->net_dev->dev, packet);
244 return ret;
245}
246
247static void rndis_filter_receive_response(struct rndis_device *dev,
248 struct rndis_message *resp)
249{
250 struct rndis_request *request = NULL;
251 bool found = false;
252 unsigned long flags;
253
254 spin_lock_irqsave(&dev->request_lock, flags);
255 list_for_each_entry(request, &dev->req_list, list_ent) {
256 /*
257 * All request/response message contains RequestId as the 1st
258 * field
259 */
260 if (request->request_msg.msg.init_req.req_id
261 == resp->msg.init_complete.req_id) {
262 found = true;
263 break;
264 }
265 }
266 spin_unlock_irqrestore(&dev->request_lock, flags);
267
268 if (found) {
269 if (resp->msg_len <= sizeof(struct rndis_message)) {
270 memcpy(&request->response_msg, resp,
271 resp->msg_len);
272 } else {
273 dev_err(&dev->net_dev->dev->device,
274 "rndis response buffer overflow "
275 "detected (size %u max %zu)\n",
276 resp->msg_len,
277 sizeof(struct rndis_filter_packet));
278
279 if (resp->ndis_msg_type ==
280 REMOTE_NDIS_RESET_CMPLT) {
281 /* does not have a request id field */
282 request->response_msg.msg.reset_complete.
283 status = STATUS_BUFFER_OVERFLOW;
284 } else {
285 request->response_msg.msg.
286 init_complete.status =
287 STATUS_BUFFER_OVERFLOW;
288 }
289 }
290
291 complete(&request->wait_event);
292 } else {
293 dev_err(&dev->net_dev->dev->device,
294 "no rndis request found for this response "
295 "(id 0x%x res type 0x%x)\n",
296 resp->msg.init_complete.req_id,
297 resp->ndis_msg_type);
298 }
299}
300
301static void rndis_filter_receive_indicate_status(struct rndis_device *dev,
302 struct rndis_message *resp)
303{
304 struct rndis_indicate_status *indicate =
305 &resp->msg.indicate_status;
306
307 if (indicate->status == RNDIS_STATUS_MEDIA_CONNECT) {
308 netvsc_linkstatus_callback(
309 dev->net_dev->dev, 1);
310 } else if (indicate->status == RNDIS_STATUS_MEDIA_DISCONNECT) {
311 netvsc_linkstatus_callback(
312 dev->net_dev->dev, 0);
313 } else {
314 /*
315 * TODO:
316 */
317 }
318}
319
320static void rndis_filter_receive_data(struct rndis_device *dev,
321 struct rndis_message *msg,
322 struct hv_netvsc_packet *pkt)
323{
324 struct rndis_packet *rndis_pkt;
325 u32 data_offset;
326
327 rndis_pkt = &msg->msg.pkt;
328
329 /*
330 * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
331 * netvsc packet (ie TotalDataBufferLength != MessageLength)
332 */
333
334 /* Remove the rndis header and pass it back up the stack */
335 data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
336
337 pkt->total_data_buflen -= data_offset;
338 pkt->page_buf[0].offset += data_offset;
339 pkt->page_buf[0].len -= data_offset;
340
341 pkt->is_data_pkt = true;
342
343 netvsc_recv_callback(dev->net_dev->dev, pkt);
344}
345
346int rndis_filter_receive(struct hv_device *dev,
347 struct hv_netvsc_packet *pkt)
348{
349 struct netvsc_device *net_dev = dev->ext;
350 struct rndis_device *rndis_dev;
351 struct rndis_message rndis_msg;
352 struct rndis_message *rndis_hdr;
353
354 if (!net_dev)
355 return -EINVAL;
356
357 /* Make sure the rndis device state is initialized */
358 if (!net_dev->extension) {
359 dev_err(&dev->device, "got rndis message but no rndis device - "
360 "dropping this message!\n");
361 return -1;
362 }
363
364 rndis_dev = (struct rndis_device *)net_dev->extension;
365 if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
366 dev_err(&dev->device, "got rndis message but rndis device "
367 "uninitialized...dropping this message!\n");
368 return -1;
369 }
370
371 rndis_hdr = (struct rndis_message *)kmap_atomic(
372 pfn_to_page(pkt->page_buf[0].pfn), KM_IRQ0);
373
374 rndis_hdr = (void *)((unsigned long)rndis_hdr +
375 pkt->page_buf[0].offset);
376
377 /* Make sure we got a valid rndis message */
378 if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) &&
379 (rndis_hdr->msg_len > sizeof(struct rndis_message))) {
380 dev_err(&dev->device, "incoming rndis message buffer overflow "
381 "detected (got %u, max %zu)..marking it an error!\n",
382 rndis_hdr->msg_len,
383 sizeof(struct rndis_message));
384 }
385
386 memcpy(&rndis_msg, rndis_hdr,
387 (rndis_hdr->msg_len > sizeof(struct rndis_message)) ?
388 sizeof(struct rndis_message) :
389 rndis_hdr->msg_len);
390
391 kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, KM_IRQ0);
392
393 dump_rndis_message(dev, &rndis_msg);
394
395 switch (rndis_msg.ndis_msg_type) {
396 case REMOTE_NDIS_PACKET_MSG:
397 /* data msg */
398 rndis_filter_receive_data(rndis_dev, &rndis_msg, pkt);
399 break;
400
401 case REMOTE_NDIS_INITIALIZE_CMPLT:
402 case REMOTE_NDIS_QUERY_CMPLT:
403 case REMOTE_NDIS_SET_CMPLT:
404 /* completion msgs */
405 rndis_filter_receive_response(rndis_dev, &rndis_msg);
406 break;
407
408 case REMOTE_NDIS_INDICATE_STATUS_MSG:
409 /* notification msgs */
410 rndis_filter_receive_indicate_status(rndis_dev, &rndis_msg);
411 break;
412 default:
413 dev_err(&dev->device,
414 "unhandled rndis message (type %u len %u)\n",
415 rndis_msg.ndis_msg_type,
416 rndis_msg.msg_len);
417 break;
418 }
419
420 return 0;
421}
422
423static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
424 void *result, u32 *result_size)
425{
426 struct rndis_request *request;
427 u32 inresult_size = *result_size;
428 struct rndis_query_request *query;
429 struct rndis_query_complete *query_complete;
430 int ret = 0;
431 int t;
432
433 if (!result)
434 return -EINVAL;
435
436 *result_size = 0;
437 request = get_rndis_request(dev, REMOTE_NDIS_QUERY_MSG,
438 RNDIS_MESSAGE_SIZE(struct rndis_query_request));
439 if (!request) {
440 ret = -1;
441 goto Cleanup;
442 }
443
444 /* Setup the rndis query */
445 query = &request->request_msg.msg.query_req;
446 query->oid = oid;
447 query->info_buf_offset = sizeof(struct rndis_query_request);
448 query->info_buflen = 0;
449 query->dev_vc_handle = 0;
450
451 ret = rndis_filter_send_request(dev, request);
452 if (ret != 0)
453 goto Cleanup;
454
455 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
456 if (t == 0) {
457 ret = -ETIMEDOUT;
458 goto Cleanup;
459 }
460
461 /* Copy the response back */
462 query_complete = &request->response_msg.msg.query_complete;
463
464 if (query_complete->info_buflen > inresult_size) {
465 ret = -1;
466 goto Cleanup;
467 }
468
469 memcpy(result,
470 (void *)((unsigned long)query_complete +
471 query_complete->info_buf_offset),
472 query_complete->info_buflen);
473
474 *result_size = query_complete->info_buflen;
475
476Cleanup:
477 if (request)
478 put_rndis_request(dev, request);
479
480 return ret;
481}
482
483static int rndis_filter_query_device_mac(struct rndis_device *dev)
484{
485 u32 size = ETH_ALEN;
486
487 return rndis_filter_query_device(dev,
488 RNDIS_OID_802_3_PERMANENT_ADDRESS,
489 dev->hw_mac_adr, &size);
490}
491
492static int rndis_filter_query_device_link_status(struct rndis_device *dev)
493{
494 u32 size = sizeof(u32);
495
496 return rndis_filter_query_device(dev,
497 RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
498 &dev->link_stat, &size);
499}
500
501static int rndis_filter_set_packet_filter(struct rndis_device *dev,
502 u32 new_filter)
503{
504 struct rndis_request *request;
505 struct rndis_set_request *set;
506 struct rndis_set_complete *set_complete;
507 u32 status;
508 int ret, t;
509
510 request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG,
511 RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
512 sizeof(u32));
513 if (!request) {
514 ret = -1;
515 goto Cleanup;
516 }
517
518 /* Setup the rndis set */
519 set = &request->request_msg.msg.set_req;
520 set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
521 set->info_buflen = sizeof(u32);
522 set->info_buf_offset = sizeof(struct rndis_set_request);
523
524 memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
525 &new_filter, sizeof(u32));
526
527 ret = rndis_filter_send_request(dev, request);
528 if (ret != 0)
529 goto Cleanup;
530
531 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
532
533 if (t == 0) {
534 ret = -1;
535 dev_err(&dev->net_dev->dev->device,
536 "timeout before we got a set response...\n");
537 /*
538 * We can't deallocate the request since we may still receive a
539 * send completion for it.
540 */
541 goto Exit;
542 } else {
543 if (ret > 0)
544 ret = 0;
545 set_complete = &request->response_msg.msg.set_complete;
546 status = set_complete->status;
547 }
548
549Cleanup:
550 if (request)
551 put_rndis_request(dev, request);
552Exit:
553 return ret;
554}
555
556
557static int rndis_filter_init_device(struct rndis_device *dev)
558{
559 struct rndis_request *request;
560 struct rndis_initialize_request *init;
561 struct rndis_initialize_complete *init_complete;
562 u32 status;
563 int ret, t;
564
565 request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG,
566 RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
567 if (!request) {
568 ret = -1;
569 goto Cleanup;
570 }
571
572 /* Setup the rndis set */
573 init = &request->request_msg.msg.init_req;
574 init->major_ver = RNDIS_MAJOR_VERSION;
575 init->minor_ver = RNDIS_MINOR_VERSION;
576 /* FIXME: Use 1536 - rounded ethernet frame size */
577 init->max_xfer_size = 2048;
578
579 dev->state = RNDIS_DEV_INITIALIZING;
580
581 ret = rndis_filter_send_request(dev, request);
582 if (ret != 0) {
583 dev->state = RNDIS_DEV_UNINITIALIZED;
584 goto Cleanup;
585 }
586
587
588 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
589
590 if (t == 0) {
591 ret = -ETIMEDOUT;
592 goto Cleanup;
593 }
594
595 init_complete = &request->response_msg.msg.init_complete;
596 status = init_complete->status;
597 if (status == RNDIS_STATUS_SUCCESS) {
598 dev->state = RNDIS_DEV_INITIALIZED;
599 ret = 0;
600 } else {
601 dev->state = RNDIS_DEV_UNINITIALIZED;
602 ret = -1;
603 }
604
605Cleanup:
606 if (request)
607 put_rndis_request(dev, request);
608
609 return ret;
610}
611
612static void rndis_filter_halt_device(struct rndis_device *dev)
613{
614 struct rndis_request *request;
615 struct rndis_halt_request *halt;
616
617 /* Attempt to do a rndis device halt */
618 request = get_rndis_request(dev, REMOTE_NDIS_HALT_MSG,
619 RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
620 if (!request)
621 goto Cleanup;
622
623 /* Setup the rndis set */
624 halt = &request->request_msg.msg.halt_req;
625 halt->req_id = atomic_inc_return(&dev->new_req_id);
626
627 /* Ignore return since this msg is optional. */
628 rndis_filter_send_request(dev, request);
629
630 dev->state = RNDIS_DEV_UNINITIALIZED;
631
632Cleanup:
633 if (request)
634 put_rndis_request(dev, request);
635 return;
636}
637
638static int rndis_filter_open_device(struct rndis_device *dev)
639{
640 int ret;
641
642 if (dev->state != RNDIS_DEV_INITIALIZED)
643 return 0;
644
645 ret = rndis_filter_set_packet_filter(dev,
646 NDIS_PACKET_TYPE_BROADCAST |
647 NDIS_PACKET_TYPE_ALL_MULTICAST |
648 NDIS_PACKET_TYPE_DIRECTED);
649 if (ret == 0)
650 dev->state = RNDIS_DEV_DATAINITIALIZED;
651
652 return ret;
653}
654
655static int rndis_filter_close_device(struct rndis_device *dev)
656{
657 int ret;
658
659 if (dev->state != RNDIS_DEV_DATAINITIALIZED)
660 return 0;
661
662 ret = rndis_filter_set_packet_filter(dev, 0);
663 if (ret == 0)
664 dev->state = RNDIS_DEV_INITIALIZED;
665
666 return ret;
667}
668
669int rndis_filter_device_add(struct hv_device *dev,
670 void *additional_info)
671{
672 int ret;
673 struct netvsc_device *netDevice;
674 struct rndis_device *rndisDevice;
675 struct netvsc_device_info *deviceInfo = additional_info;
676
677 rndisDevice = get_rndis_device();
678 if (!rndisDevice)
679 return -1;
680
681 /*
682 * Let the inner driver handle this first to create the netvsc channel
683 * NOTE! Once the channel is created, we may get a receive callback
684 * (RndisFilterOnReceive()) before this call is completed
685 */
686 ret = netvsc_device_add(dev, additional_info);
687 if (ret != 0) {
688 kfree(rndisDevice);
689 return ret;
690 }
691
692
693 /* Initialize the rndis device */
694 netDevice = dev->ext;
695
696 netDevice->extension = rndisDevice;
697 rndisDevice->net_dev = netDevice;
698
699 /* Send the rndis initialization message */
700 ret = rndis_filter_init_device(rndisDevice);
701 if (ret != 0) {
702 /*
703 * TODO: If rndis init failed, we will need to shut down the
704 * channel
705 */
706 }
707
708 /* Get the mac address */
709 ret = rndis_filter_query_device_mac(rndisDevice);
710 if (ret != 0) {
711 /*
712 * TODO: shutdown rndis device and the channel
713 */
714 }
715
716 memcpy(deviceInfo->mac_adr, rndisDevice->hw_mac_adr, ETH_ALEN);
717
718 rndis_filter_query_device_link_status(rndisDevice);
719
720 deviceInfo->link_state = rndisDevice->link_stat;
721
722 dev_info(&dev->device, "Device MAC %pM link state %s",
723 rndisDevice->hw_mac_adr,
724 ((deviceInfo->link_state) ? ("down\n") : ("up\n")));
725
726 return ret;
727}
728
729void rndis_filter_device_remove(struct hv_device *dev)
730{
731 struct netvsc_device *net_dev = dev->ext;
732 struct rndis_device *rndis_dev = net_dev->extension;
733
734 /* Halt and release the rndis device */
735 rndis_filter_halt_device(rndis_dev);
736
737 kfree(rndis_dev);
738 net_dev->extension = NULL;
739
740 netvsc_device_remove(dev);
741}
742
743
744int rndis_filter_open(struct hv_device *dev)
745{
746 struct netvsc_device *netDevice = dev->ext;
747
748 if (!netDevice)
749 return -EINVAL;
750
751 return rndis_filter_open_device(netDevice->extension);
752}
753
754int rndis_filter_close(struct hv_device *dev)
755{
756 struct netvsc_device *netDevice = dev->ext;
757
758 if (!netDevice)
759 return -EINVAL;
760
761 return rndis_filter_close_device(netDevice->extension);
762}
763
764int rndis_filter_send(struct hv_device *dev,
765 struct hv_netvsc_packet *pkt)
766{
767 int ret;
768 struct rndis_filter_packet *filterPacket;
769 struct rndis_message *rndisMessage;
770 struct rndis_packet *rndisPacket;
771 u32 rndisMessageSize;
772
773 /* Add the rndis header */
774 filterPacket = (struct rndis_filter_packet *)pkt->extension;
775
776 memset(filterPacket, 0, sizeof(struct rndis_filter_packet));
777
778 rndisMessage = &filterPacket->msg;
779 rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet);
780
781 rndisMessage->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
782 rndisMessage->msg_len = pkt->total_data_buflen +
783 rndisMessageSize;
784
785 rndisPacket = &rndisMessage->msg.pkt;
786 rndisPacket->data_offset = sizeof(struct rndis_packet);
787 rndisPacket->data_len = pkt->total_data_buflen;
788
789 pkt->is_data_pkt = true;
790 pkt->page_buf[0].pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT;
791 pkt->page_buf[0].offset =
792 (unsigned long)rndisMessage & (PAGE_SIZE-1);
793 pkt->page_buf[0].len = rndisMessageSize;
794
795 /* Save the packet send completion and context */
796 filterPacket->completion = pkt->completion.send.send_completion;
797 filterPacket->completion_ctx =
798 pkt->completion.send.send_completion_ctx;
799
800 /* Use ours */
801 pkt->completion.send.send_completion = rndis_filter_send_completion;
802 pkt->completion.send.send_completion_ctx = filterPacket;
803
804 ret = netvsc_send(dev, pkt);
805 if (ret != 0) {
806 /*
807 * Reset the completion to originals to allow retries from
808 * above
809 */
810 pkt->completion.send.send_completion =
811 filterPacket->completion;
812 pkt->completion.send.send_completion_ctx =
813 filterPacket->completion_ctx;
814 }
815
816 return ret;
817}
818
819static void rndis_filter_send_completion(void *ctx)
820{
821 struct rndis_filter_packet *filterPacket = ctx;
822
823 /* Pass it back to the original handler */
824 filterPacket->completion(filterPacket->completion_ctx);
825}
826
827
828static void rndis_filter_send_request_completion(void *ctx)
829{
830 /* Noop */
831}
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
new file mode 100644
index 00000000000..30297861194
--- /dev/null
+++ b/drivers/staging/hv/storvsc.c
@@ -0,0 +1,564 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 * K. Y. Srinivasan <kys@microsoft.com>
21 *
22 */
23#include <linux/kernel.h>
24#include <linux/sched.h>
25#include <linux/completion.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/delay.h>
30
31#include "hyperv.h"
32#include "hyperv_storage.h"
33
34
35static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
36{
37 struct storvsc_device *stor_device;
38
39 stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL);
40 if (!stor_device)
41 return NULL;
42
43 /* Set to 2 to allow both inbound and outbound traffics */
44 /* (ie get_stor_device() and must_get_stor_device()) to proceed. */
45 atomic_cmpxchg(&stor_device->ref_count, 0, 2);
46
47 init_waitqueue_head(&stor_device->waiting_to_drain);
48 stor_device->device = device;
49 device->ext = stor_device;
50
51 return stor_device;
52}
53
54static inline void free_stor_device(struct storvsc_device *device)
55{
56 kfree(device);
57}
58
59/* Get the stordevice object iff exists and its refcount > 0 */
60static inline struct storvsc_device *must_get_stor_device(
61 struct hv_device *device)
62{
63 struct storvsc_device *stor_device;
64
65 stor_device = (struct storvsc_device *)device->ext;
66 if (stor_device && atomic_read(&stor_device->ref_count))
67 atomic_inc(&stor_device->ref_count);
68 else
69 stor_device = NULL;
70
71 return stor_device;
72}
73
74/* Drop ref count to 1 to effectively disable get_stor_device() */
75static inline struct storvsc_device *release_stor_device(
76 struct hv_device *device)
77{
78 struct storvsc_device *stor_device;
79
80 stor_device = (struct storvsc_device *)device->ext;
81
82 /* Busy wait until the ref drop to 2, then set it to 1 */
83 while (atomic_cmpxchg(&stor_device->ref_count, 2, 1) != 2)
84 udelay(100);
85
86 return stor_device;
87}
88
89/* Drop ref count to 0. No one can use stor_device object. */
90static inline struct storvsc_device *final_release_stor_device(
91 struct hv_device *device)
92{
93 struct storvsc_device *stor_device;
94
95 stor_device = (struct storvsc_device *)device->ext;
96
97 /* Busy wait until the ref drop to 1, then set it to 0 */
98 while (atomic_cmpxchg(&stor_device->ref_count, 1, 0) != 1)
99 udelay(100);
100
101 device->ext = NULL;
102 return stor_device;
103}
104
105static int storvsc_channel_init(struct hv_device *device)
106{
107 struct storvsc_device *stor_device;
108 struct hv_storvsc_request *request;
109 struct vstor_packet *vstor_packet;
110 int ret, t;
111
112 stor_device = get_stor_device(device);
113 if (!stor_device)
114 return -1;
115
116 request = &stor_device->init_request;
117 vstor_packet = &request->vstor_packet;
118
119 /*
120 * Now, initiate the vsc/vsp initialization protocol on the open
121 * channel
122 */
123 memset(request, 0, sizeof(struct hv_storvsc_request));
124 init_completion(&request->wait_event);
125 vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
126 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
127
128 DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION...");
129
130 ret = vmbus_sendpacket(device->channel, vstor_packet,
131 sizeof(struct vstor_packet),
132 (unsigned long)request,
133 VM_PKT_DATA_INBAND,
134 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
135 if (ret != 0)
136 goto cleanup;
137
138 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
139 if (t == 0) {
140 ret = -ETIMEDOUT;
141 goto cleanup;
142 }
143
144 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
145 vstor_packet->status != 0)
146 goto cleanup;
147
148 DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION...");
149
150 /* reuse the packet for version range supported */
151 memset(vstor_packet, 0, sizeof(struct vstor_packet));
152 vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
153 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
154
155 vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT;
156 FILL_VMSTOR_REVISION(vstor_packet->version.revision);
157
158 ret = vmbus_sendpacket(device->channel, vstor_packet,
159 sizeof(struct vstor_packet),
160 (unsigned long)request,
161 VM_PKT_DATA_INBAND,
162 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
163 if (ret != 0)
164 goto cleanup;
165
166 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
167 if (t == 0) {
168 ret = -ETIMEDOUT;
169 goto cleanup;
170 }
171
172 /* TODO: Check returned version */
173 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
174 vstor_packet->status != 0)
175 goto cleanup;
176
177 /* Query channel properties */
178 DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION...");
179
180 memset(vstor_packet, 0, sizeof(struct vstor_packet));
181 vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
182 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
183 vstor_packet->storage_channel_properties.port_number =
184 stor_device->port_number;
185
186 ret = vmbus_sendpacket(device->channel, vstor_packet,
187 sizeof(struct vstor_packet),
188 (unsigned long)request,
189 VM_PKT_DATA_INBAND,
190 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
191
192 if (ret != 0)
193 goto cleanup;
194
195 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
196 if (t == 0) {
197 ret = -ETIMEDOUT;
198 goto cleanup;
199 }
200
201 /* TODO: Check returned version */
202 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
203 vstor_packet->status != 0)
204 goto cleanup;
205
206 stor_device->path_id = vstor_packet->storage_channel_properties.path_id;
207 stor_device->target_id
208 = vstor_packet->storage_channel_properties.target_id;
209
210 DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION...");
211
212 memset(vstor_packet, 0, sizeof(struct vstor_packet));
213 vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
214 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
215
216 ret = vmbus_sendpacket(device->channel, vstor_packet,
217 sizeof(struct vstor_packet),
218 (unsigned long)request,
219 VM_PKT_DATA_INBAND,
220 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
221
222 if (ret != 0)
223 goto cleanup;
224
225 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
226 if (t == 0) {
227 ret = -ETIMEDOUT;
228 goto cleanup;
229 }
230
231 if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
232 vstor_packet->status != 0)
233 goto cleanup;
234
235 DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****");
236
237cleanup:
238 put_stor_device(device);
239 return ret;
240}
241
242static void storvsc_on_io_completion(struct hv_device *device,
243 struct vstor_packet *vstor_packet,
244 struct hv_storvsc_request *request)
245{
246 struct storvsc_device *stor_device;
247 struct vstor_packet *stor_pkt;
248
249 stor_device = must_get_stor_device(device);
250 if (!stor_device)
251 return;
252
253 stor_pkt = &request->vstor_packet;
254
255
256 /* Copy over the status...etc */
257 stor_pkt->vm_srb.scsi_status = vstor_packet->vm_srb.scsi_status;
258 stor_pkt->vm_srb.srb_status = vstor_packet->vm_srb.srb_status;
259 stor_pkt->vm_srb.sense_info_length =
260 vstor_packet->vm_srb.sense_info_length;
261
262 if (vstor_packet->vm_srb.scsi_status != 0 ||
263 vstor_packet->vm_srb.srb_status != 1){
264 DPRINT_WARN(STORVSC,
265 "cmd 0x%x scsi status 0x%x srb status 0x%x\n",
266 stor_pkt->vm_srb.cdb[0],
267 vstor_packet->vm_srb.scsi_status,
268 vstor_packet->vm_srb.srb_status);
269 }
270
271 if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) {
272 /* CHECK_CONDITION */
273 if (vstor_packet->vm_srb.srb_status & 0x80) {
274 /* autosense data available */
275 DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data "
276 "valid - len %d\n", request,
277 vstor_packet->vm_srb.sense_info_length);
278
279 memcpy(request->sense_buffer,
280 vstor_packet->vm_srb.sense_data,
281 vstor_packet->vm_srb.sense_info_length);
282
283 }
284 }
285
286 stor_pkt->vm_srb.data_transfer_length =
287 vstor_packet->vm_srb.data_transfer_length;
288
289 request->on_io_completion(request);
290
291 if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
292 stor_device->drain_notify)
293 wake_up(&stor_device->waiting_to_drain);
294
295
296 put_stor_device(device);
297}
298
299static void storvsc_on_receive(struct hv_device *device,
300 struct vstor_packet *vstor_packet,
301 struct hv_storvsc_request *request)
302{
303 switch (vstor_packet->operation) {
304 case VSTOR_OPERATION_COMPLETE_IO:
305 storvsc_on_io_completion(device, vstor_packet, request);
306 break;
307 case VSTOR_OPERATION_REMOVE_DEVICE:
308 DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION");
309 /* TODO: */
310 break;
311
312 default:
313 DPRINT_INFO(STORVSC, "Unknown operation received - %d",
314 vstor_packet->operation);
315 break;
316 }
317}
318
319static void storvsc_on_channel_callback(void *context)
320{
321 struct hv_device *device = (struct hv_device *)context;
322 struct storvsc_device *stor_device;
323 u32 bytes_recvd;
324 u64 request_id;
325 unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)];
326 struct hv_storvsc_request *request;
327 int ret;
328
329
330 stor_device = must_get_stor_device(device);
331 if (!stor_device)
332 return;
333
334 do {
335 ret = vmbus_recvpacket(device->channel, packet,
336 ALIGN(sizeof(struct vstor_packet), 8),
337 &bytes_recvd, &request_id);
338 if (ret == 0 && bytes_recvd > 0) {
339
340 request = (struct hv_storvsc_request *)
341 (unsigned long)request_id;
342
343 if ((request == &stor_device->init_request) ||
344 (request == &stor_device->reset_request)) {
345
346 memcpy(&request->vstor_packet, packet,
347 sizeof(struct vstor_packet));
348 complete(&request->wait_event);
349 } else {
350 storvsc_on_receive(device,
351 (struct vstor_packet *)packet,
352 request);
353 }
354 } else {
355 break;
356 }
357 } while (1);
358
359 put_stor_device(device);
360 return;
361}
362
363static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
364{
365 struct vmstorage_channel_properties props;
366 int ret;
367
368 memset(&props, 0, sizeof(struct vmstorage_channel_properties));
369
370 /* Open the channel */
371 ret = vmbus_open(device->channel,
372 ring_size,
373 ring_size,
374 (void *)&props,
375 sizeof(struct vmstorage_channel_properties),
376 storvsc_on_channel_callback, device);
377
378 if (ret != 0)
379 return -1;
380
381 ret = storvsc_channel_init(device);
382
383 return ret;
384}
385
386int storvsc_dev_add(struct hv_device *device,
387 void *additional_info)
388{
389 struct storvsc_device *stor_device;
390 struct storvsc_device_info *device_info;
391 int ret = 0;
392
393 device_info = (struct storvsc_device_info *)additional_info;
394 stor_device = alloc_stor_device(device);
395 if (!stor_device) {
396 ret = -1;
397 goto cleanup;
398 }
399
400 /* Save the channel properties to our storvsc channel */
401
402 /* FIXME: */
403 /*
404 * If we support more than 1 scsi channel, we need to set the
405 * port number here to the scsi channel but how do we get the
406 * scsi channel prior to the bus scan
407 */
408
409 stor_device->port_number = device_info->port_number;
410 /* Send it back up */
411 ret = storvsc_connect_to_vsp(device, device_info->ring_buffer_size);
412
413 device_info->path_id = stor_device->path_id;
414 device_info->target_id = stor_device->target_id;
415
416cleanup:
417 return ret;
418}
419
420int storvsc_dev_remove(struct hv_device *device)
421{
422 struct storvsc_device *stor_device;
423
424 DPRINT_INFO(STORVSC, "disabling storage device (%p)...",
425 device->ext);
426
427 stor_device = release_stor_device(device);
428
429 /*
430 * At this point, all outbound traffic should be disable. We
431 * only allow inbound traffic (responses) to proceed so that
432 * outstanding requests can be completed.
433 */
434
435 storvsc_wait_to_drain(stor_device);
436
437 stor_device = final_release_stor_device(device);
438
439 /* Close the channel */
440 vmbus_close(device->channel);
441
442 free_stor_device(stor_device);
443 return 0;
444}
445
446int storvsc_do_io(struct hv_device *device,
447 struct hv_storvsc_request *request)
448{
449 struct storvsc_device *stor_device;
450 struct vstor_packet *vstor_packet;
451 int ret = 0;
452
453 vstor_packet = &request->vstor_packet;
454 stor_device = get_stor_device(device);
455
456 if (!stor_device)
457 return -2;
458
459
460 request->device = device;
461
462
463 vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
464
465 vstor_packet->vm_srb.length = sizeof(struct vmscsi_request);
466
467
468 vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE;
469
470
471 vstor_packet->vm_srb.data_transfer_length =
472 request->data_buffer.len;
473
474 vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
475
476 if (request->data_buffer.len) {
477 ret = vmbus_sendpacket_multipagebuffer(device->channel,
478 &request->data_buffer,
479 vstor_packet,
480 sizeof(struct vstor_packet),
481 (unsigned long)request);
482 } else {
483 ret = vmbus_sendpacket(device->channel, vstor_packet,
484 sizeof(struct vstor_packet),
485 (unsigned long)request,
486 VM_PKT_DATA_INBAND,
487 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
488 }
489
490 if (ret != 0)
491 return ret;
492
493 atomic_inc(&stor_device->num_outstanding_req);
494
495 put_stor_device(device);
496 return ret;
497}
498
499/*
500 * The channel properties uniquely specify how the device is to be
501 * presented to the guest. Map this information for use by the block
502 * driver. For Linux guests on Hyper-V, we emulate a scsi HBA in the guest
503 * (storvsc_drv) and so scsi devices in the guest are handled by
504 * native upper level Linux drivers. Consequently, Hyper-V
505 * block driver, while being a generic block driver, presently does not
506 * deal with anything other than devices that would need to be presented
507 * to the guest as an IDE disk.
508 *
509 * This function maps the channel properties as embedded in the input
510 * parameter device_info onto information necessary to register the
511 * corresponding block device.
512 *
513 * Currently, there is no way to stop the emulation of the block device
514 * on the host side. And so, to prevent the native IDE drivers in Linux
515 * from taking over these devices (to be managedby Hyper-V block
516 * driver), we will take over if need be the major of the IDE controllers.
517 *
518 */
519
520int storvsc_get_major_info(struct storvsc_device_info *device_info,
521 struct storvsc_major_info *major_info)
522{
523 static bool ide0_registered;
524 static bool ide1_registered;
525
526 /*
527 * For now we only support IDE disks.
528 */
529 major_info->devname = "ide";
530 major_info->diskname = "hd";
531
532 if (device_info->path_id) {
533 major_info->major = 22;
534 if (!ide1_registered) {
535 major_info->do_register = true;
536 ide1_registered = true;
537 } else
538 major_info->do_register = false;
539
540 if (device_info->target_id)
541 major_info->index = 3;
542 else
543 major_info->index = 2;
544
545 return 0;
546 } else {
547 major_info->major = 3;
548 if (!ide0_registered) {
549 major_info->do_register = true;
550 ide0_registered = true;
551 } else
552 major_info->do_register = false;
553
554 if (device_info->target_id)
555 major_info->index = 1;
556 else
557 major_info->index = 0;
558
559 return 0;
560 }
561
562 return -ENODEV;
563}
564
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
new file mode 100644
index 00000000000..26983ac1ae4
--- /dev/null
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -0,0 +1,794 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 * K. Y. Srinivasan <kys@microsoft.com>
21 */
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/device.h>
26#include <linux/blkdev.h>
27#include <linux/dmi.h>
28#include <scsi/scsi.h>
29#include <scsi/scsi_cmnd.h>
30#include <scsi/scsi_host.h>
31#include <scsi/scsi_device.h>
32#include <scsi/scsi_tcq.h>
33#include <scsi/scsi_eh.h>
34#include <scsi/scsi_devinfo.h>
35#include <scsi/scsi_dbg.h>
36
37#include "hyperv.h"
38#include "hyperv_storage.h"
39
40static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
41
42module_param(storvsc_ringbuffer_size, int, S_IRUGO);
43MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
44
45static const char *driver_name = "storvsc";
46
47/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
48static const struct hv_guid stor_vsci_device_type = {
49 .data = {
50 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
51 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
52 }
53};
54
55struct hv_host_device {
56 struct hv_device *dev;
57 struct kmem_cache *request_pool;
58 unsigned int port;
59 unsigned char path;
60 unsigned char target;
61};
62
63struct storvsc_cmd_request {
64 struct list_head entry;
65 struct scsi_cmnd *cmd;
66
67 unsigned int bounce_sgl_count;
68 struct scatterlist *bounce_sgl;
69
70 struct hv_storvsc_request request;
71};
72
73
74static int storvsc_device_alloc(struct scsi_device *sdevice)
75{
76 /*
77 * This enables luns to be located sparsely. Otherwise, we may not
78 * discovered them.
79 */
80 sdevice->sdev_bflags |= BLIST_SPARSELUN | BLIST_LARGELUN;
81 return 0;
82}
83
84static int storvsc_merge_bvec(struct request_queue *q,
85 struct bvec_merge_data *bmd, struct bio_vec *bvec)
86{
87 /* checking done by caller. */
88 return bvec->bv_len;
89}
90
91static int storvsc_device_configure(struct scsi_device *sdevice)
92{
93 scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG,
94 STORVSC_MAX_IO_REQUESTS);
95
96 blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
97
98 blk_queue_merge_bvec(sdevice->request_queue, storvsc_merge_bvec);
99
100 blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
101
102 return 0;
103}
104
105static void destroy_bounce_buffer(struct scatterlist *sgl,
106 unsigned int sg_count)
107{
108 int i;
109 struct page *page_buf;
110
111 for (i = 0; i < sg_count; i++) {
112 page_buf = sg_page((&sgl[i]));
113 if (page_buf != NULL)
114 __free_page(page_buf);
115 }
116
117 kfree(sgl);
118}
119
120static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
121{
122 int i;
123
124 /* No need to check */
125 if (sg_count < 2)
126 return -1;
127
128 /* We have at least 2 sg entries */
129 for (i = 0; i < sg_count; i++) {
130 if (i == 0) {
131 /* make sure 1st one does not have hole */
132 if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
133 return i;
134 } else if (i == sg_count - 1) {
135 /* make sure last one does not have hole */
136 if (sgl[i].offset != 0)
137 return i;
138 } else {
139 /* make sure no hole in the middle */
140 if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
141 return i;
142 }
143 }
144 return -1;
145}
146
147static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
148 unsigned int sg_count,
149 unsigned int len)
150{
151 int i;
152 int num_pages;
153 struct scatterlist *bounce_sgl;
154 struct page *page_buf;
155
156 num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT;
157
158 bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC);
159 if (!bounce_sgl)
160 return NULL;
161
162 for (i = 0; i < num_pages; i++) {
163 page_buf = alloc_page(GFP_ATOMIC);
164 if (!page_buf)
165 goto cleanup;
166 sg_set_page(&bounce_sgl[i], page_buf, 0, 0);
167 }
168
169 return bounce_sgl;
170
171cleanup:
172 destroy_bounce_buffer(bounce_sgl, num_pages);
173 return NULL;
174}
175
176
177/* Assume the original sgl has enough room */
178static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
179 struct scatterlist *bounce_sgl,
180 unsigned int orig_sgl_count)
181{
182 int i;
183 int j = 0;
184 unsigned long src, dest;
185 unsigned int srclen, destlen, copylen;
186 unsigned int total_copied = 0;
187 unsigned long bounce_addr = 0;
188 unsigned long dest_addr = 0;
189 unsigned long flags;
190
191 local_irq_save(flags);
192
193 for (i = 0; i < orig_sgl_count; i++) {
194 dest_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])),
195 KM_IRQ0) + orig_sgl[i].offset;
196 dest = dest_addr;
197 destlen = orig_sgl[i].length;
198
199 if (bounce_addr == 0)
200 bounce_addr =
201 (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])),
202 KM_IRQ0);
203
204 while (destlen) {
205 src = bounce_addr + bounce_sgl[j].offset;
206 srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
207
208 copylen = min(srclen, destlen);
209 memcpy((void *)dest, (void *)src, copylen);
210
211 total_copied += copylen;
212 bounce_sgl[j].offset += copylen;
213 destlen -= copylen;
214 dest += copylen;
215
216 if (bounce_sgl[j].offset == bounce_sgl[j].length) {
217 /* full */
218 kunmap_atomic((void *)bounce_addr, KM_IRQ0);
219 j++;
220
221 /* if we need to use another bounce buffer */
222 if (destlen || i != orig_sgl_count - 1)
223 bounce_addr =
224 (unsigned long)kmap_atomic(
225 sg_page((&bounce_sgl[j])), KM_IRQ0);
226 } else if (destlen == 0 && i == orig_sgl_count - 1) {
227 /* unmap the last bounce that is < PAGE_SIZE */
228 kunmap_atomic((void *)bounce_addr, KM_IRQ0);
229 }
230 }
231
232 kunmap_atomic((void *)(dest_addr - orig_sgl[i].offset),
233 KM_IRQ0);
234 }
235
236 local_irq_restore(flags);
237
238 return total_copied;
239}
240
241
242/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */
243static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
244 struct scatterlist *bounce_sgl,
245 unsigned int orig_sgl_count)
246{
247 int i;
248 int j = 0;
249 unsigned long src, dest;
250 unsigned int srclen, destlen, copylen;
251 unsigned int total_copied = 0;
252 unsigned long bounce_addr = 0;
253 unsigned long src_addr = 0;
254 unsigned long flags;
255
256 local_irq_save(flags);
257
258 for (i = 0; i < orig_sgl_count; i++) {
259 src_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])),
260 KM_IRQ0) + orig_sgl[i].offset;
261 src = src_addr;
262 srclen = orig_sgl[i].length;
263
264 if (bounce_addr == 0)
265 bounce_addr =
266 (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])),
267 KM_IRQ0);
268
269 while (srclen) {
270 /* assume bounce offset always == 0 */
271 dest = bounce_addr + bounce_sgl[j].length;
272 destlen = PAGE_SIZE - bounce_sgl[j].length;
273
274 copylen = min(srclen, destlen);
275 memcpy((void *)dest, (void *)src, copylen);
276
277 total_copied += copylen;
278 bounce_sgl[j].length += copylen;
279 srclen -= copylen;
280 src += copylen;
281
282 if (bounce_sgl[j].length == PAGE_SIZE) {
283 /* full..move to next entry */
284 kunmap_atomic((void *)bounce_addr, KM_IRQ0);
285 j++;
286
287 /* if we need to use another bounce buffer */
288 if (srclen || i != orig_sgl_count - 1)
289 bounce_addr =
290 (unsigned long)kmap_atomic(
291 sg_page((&bounce_sgl[j])), KM_IRQ0);
292
293 } else if (srclen == 0 && i == orig_sgl_count - 1) {
294 /* unmap the last bounce that is < PAGE_SIZE */
295 kunmap_atomic((void *)bounce_addr, KM_IRQ0);
296 }
297 }
298
299 kunmap_atomic((void *)(src_addr - orig_sgl[i].offset), KM_IRQ0);
300 }
301
302 local_irq_restore(flags);
303
304 return total_copied;
305}
306
307
308static int storvsc_remove(struct hv_device *dev)
309{
310 struct Scsi_Host *host = dev_get_drvdata(&dev->device);
311 struct hv_host_device *host_dev =
312 (struct hv_host_device *)host->hostdata;
313
314 scsi_remove_host(host);
315
316 scsi_host_put(host);
317
318 storvsc_dev_remove(dev);
319 if (host_dev->request_pool) {
320 kmem_cache_destroy(host_dev->request_pool);
321 host_dev->request_pool = NULL;
322 }
323 return 0;
324}
325
326
327static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
328 sector_t capacity, int *info)
329{
330 sector_t nsect = capacity;
331 sector_t cylinders = nsect;
332 int heads, sectors_pt;
333
334 /*
335 * We are making up these values; let us keep it simple.
336 */
337 heads = 0xff;
338 sectors_pt = 0x3f; /* Sectors per track */
339 sector_div(cylinders, heads * sectors_pt);
340 if ((sector_t)(cylinders + 1) * heads * sectors_pt < nsect)
341 cylinders = 0xffff;
342
343 info[0] = heads;
344 info[1] = sectors_pt;
345 info[2] = (int)cylinders;
346
347 return 0;
348}
349
350static int storvsc_host_reset(struct hv_device *device)
351{
352 struct storvsc_device *stor_device;
353 struct hv_storvsc_request *request;
354 struct vstor_packet *vstor_packet;
355 int ret, t;
356
357
358 stor_device = get_stor_device(device);
359 if (!stor_device)
360 return -1;
361
362 request = &stor_device->reset_request;
363 vstor_packet = &request->vstor_packet;
364
365 init_completion(&request->wait_event);
366
367 vstor_packet->operation = VSTOR_OPERATION_RESET_BUS;
368 vstor_packet->flags = REQUEST_COMPLETION_FLAG;
369 vstor_packet->vm_srb.path_id = stor_device->path_id;
370
371 ret = vmbus_sendpacket(device->channel, vstor_packet,
372 sizeof(struct vstor_packet),
373 (unsigned long)&stor_device->reset_request,
374 VM_PKT_DATA_INBAND,
375 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
376 if (ret != 0)
377 goto cleanup;
378
379 t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
380 if (t == 0) {
381 ret = -ETIMEDOUT;
382 goto cleanup;
383 }
384
385
386 /*
387 * At this point, all outstanding requests in the adapter
388 * should have been flushed out and return to us
389 */
390
391cleanup:
392 put_stor_device(device);
393 return ret;
394}
395
396
397/*
398 * storvsc_host_reset_handler - Reset the scsi HBA
399 */
400static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
401{
402 int ret;
403 struct hv_host_device *host_dev =
404 (struct hv_host_device *)scmnd->device->host->hostdata;
405 struct hv_device *dev = host_dev->dev;
406
407 ret = storvsc_host_reset(dev);
408 if (ret != 0)
409 return ret;
410
411 return ret;
412}
413
414
415/*
416 * storvsc_commmand_completion - Command completion processing
417 */
418static void storvsc_commmand_completion(struct hv_storvsc_request *request)
419{
420 struct storvsc_cmd_request *cmd_request =
421 (struct storvsc_cmd_request *)request->context;
422 struct scsi_cmnd *scmnd = cmd_request->cmd;
423 struct hv_host_device *host_dev =
424 (struct hv_host_device *)scmnd->device->host->hostdata;
425 void (*scsi_done_fn)(struct scsi_cmnd *);
426 struct scsi_sense_hdr sense_hdr;
427 struct vmscsi_request *vm_srb;
428
429 if (cmd_request->bounce_sgl_count) {
430
431 /* FIXME: We can optimize on writes by just skipping this */
432 copy_from_bounce_buffer(scsi_sglist(scmnd),
433 cmd_request->bounce_sgl,
434 scsi_sg_count(scmnd));
435 destroy_bounce_buffer(cmd_request->bounce_sgl,
436 cmd_request->bounce_sgl_count);
437 }
438
439 vm_srb = &request->vstor_packet.vm_srb;
440 scmnd->result = vm_srb->scsi_status;
441
442 if (scmnd->result) {
443 if (scsi_normalize_sense(scmnd->sense_buffer,
444 SCSI_SENSE_BUFFERSIZE, &sense_hdr))
445 scsi_print_sense_hdr("storvsc", &sense_hdr);
446 }
447
448 scsi_set_resid(scmnd,
449 request->data_buffer.len -
450 vm_srb->data_transfer_length);
451
452 scsi_done_fn = scmnd->scsi_done;
453
454 scmnd->host_scribble = NULL;
455 scmnd->scsi_done = NULL;
456
457 scsi_done_fn(scmnd);
458
459 kmem_cache_free(host_dev->request_pool, cmd_request);
460}
461
462
463/*
464 * storvsc_queuecommand - Initiate command processing
465 */
466static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd,
467 void (*done)(struct scsi_cmnd *))
468{
469 int ret;
470 struct hv_host_device *host_dev =
471 (struct hv_host_device *)scmnd->device->host->hostdata;
472 struct hv_device *dev = host_dev->dev;
473 struct hv_storvsc_request *request;
474 struct storvsc_cmd_request *cmd_request;
475 unsigned int request_size = 0;
476 int i;
477 struct scatterlist *sgl;
478 unsigned int sg_count = 0;
479 struct vmscsi_request *vm_srb;
480
481
482 /* If retrying, no need to prep the cmd */
483 if (scmnd->host_scribble) {
484
485 cmd_request =
486 (struct storvsc_cmd_request *)scmnd->host_scribble;
487
488 goto retry_request;
489 }
490
491 scmnd->scsi_done = done;
492
493 request_size = sizeof(struct storvsc_cmd_request);
494
495 cmd_request = kmem_cache_zalloc(host_dev->request_pool,
496 GFP_ATOMIC);
497 if (!cmd_request) {
498 scmnd->scsi_done = NULL;
499 return SCSI_MLQUEUE_DEVICE_BUSY;
500 }
501
502 /* Setup the cmd request */
503 cmd_request->bounce_sgl_count = 0;
504 cmd_request->bounce_sgl = NULL;
505 cmd_request->cmd = scmnd;
506
507 scmnd->host_scribble = (unsigned char *)cmd_request;
508
509 request = &cmd_request->request;
510 vm_srb = &request->vstor_packet.vm_srb;
511
512
513 /* Build the SRB */
514 switch (scmnd->sc_data_direction) {
515 case DMA_TO_DEVICE:
516 vm_srb->data_in = WRITE_TYPE;
517 break;
518 case DMA_FROM_DEVICE:
519 vm_srb->data_in = READ_TYPE;
520 break;
521 default:
522 vm_srb->data_in = UNKNOWN_TYPE;
523 break;
524 }
525
526 request->on_io_completion = storvsc_commmand_completion;
527 request->context = cmd_request;/* scmnd; */
528
529 vm_srb->port_number = host_dev->port;
530 vm_srb->path_id = scmnd->device->channel;
531 vm_srb->target_id = scmnd->device->id;
532 vm_srb->lun = scmnd->device->lun;
533
534 vm_srb->cdb_length = scmnd->cmd_len;
535
536 memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length);
537
538 request->sense_buffer = scmnd->sense_buffer;
539
540
541 request->data_buffer.len = scsi_bufflen(scmnd);
542 if (scsi_sg_count(scmnd)) {
543 sgl = (struct scatterlist *)scsi_sglist(scmnd);
544 sg_count = scsi_sg_count(scmnd);
545
546 /* check if we need to bounce the sgl */
547 if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
548 cmd_request->bounce_sgl =
549 create_bounce_buffer(sgl, scsi_sg_count(scmnd),
550 scsi_bufflen(scmnd));
551 if (!cmd_request->bounce_sgl) {
552 scmnd->scsi_done = NULL;
553 scmnd->host_scribble = NULL;
554 kmem_cache_free(host_dev->request_pool,
555 cmd_request);
556
557 return SCSI_MLQUEUE_HOST_BUSY;
558 }
559
560 cmd_request->bounce_sgl_count =
561 ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >>
562 PAGE_SHIFT;
563
564 /*
565 * FIXME: We can optimize on reads by just skipping
566 * this
567 */
568 copy_to_bounce_buffer(sgl, cmd_request->bounce_sgl,
569 scsi_sg_count(scmnd));
570
571 sgl = cmd_request->bounce_sgl;
572 sg_count = cmd_request->bounce_sgl_count;
573 }
574
575 request->data_buffer.offset = sgl[0].offset;
576
577 for (i = 0; i < sg_count; i++)
578 request->data_buffer.pfn_array[i] =
579 page_to_pfn(sg_page((&sgl[i])));
580
581 } else if (scsi_sglist(scmnd)) {
582 request->data_buffer.offset =
583 virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
584 request->data_buffer.pfn_array[0] =
585 virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT;
586 }
587
588retry_request:
589 /* Invokes the vsc to start an IO */
590 ret = storvsc_do_io(dev, &cmd_request->request);
591
592 if (ret == -1) {
593 /* no more space */
594
595 if (cmd_request->bounce_sgl_count) {
596 /*
597 * FIXME: We can optimize on writes by just skipping
598 * this
599 */
600 copy_from_bounce_buffer(scsi_sglist(scmnd),
601 cmd_request->bounce_sgl,
602 scsi_sg_count(scmnd));
603 destroy_bounce_buffer(cmd_request->bounce_sgl,
604 cmd_request->bounce_sgl_count);
605 }
606
607 kmem_cache_free(host_dev->request_pool, cmd_request);
608
609 scmnd->scsi_done = NULL;
610 scmnd->host_scribble = NULL;
611
612 ret = SCSI_MLQUEUE_DEVICE_BUSY;
613 }
614
615 return ret;
616}
617
618static DEF_SCSI_QCMD(storvsc_queuecommand)
619
620
621/* Scsi driver */
622static struct scsi_host_template scsi_driver = {
623 .module = THIS_MODULE,
624 .name = "storvsc_host_t",
625 .bios_param = storvsc_get_chs,
626 .queuecommand = storvsc_queuecommand,
627 .eh_host_reset_handler = storvsc_host_reset_handler,
628 .slave_alloc = storvsc_device_alloc,
629 .slave_configure = storvsc_device_configure,
630 .cmd_per_lun = 1,
631 /* 64 max_queue * 1 target */
632 .can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
633 .this_id = -1,
634 /* no use setting to 0 since ll_blk_rw reset it to 1 */
635 /* currently 32 */
636 .sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT,
637 /*
638 * ENABLE_CLUSTERING allows mutiple physically contig bio_vecs to merge
639 * into 1 sg element. If set, we must limit the max_segment_size to
640 * PAGE_SIZE, otherwise we may get 1 sg element that represents
641 * multiple
642 */
643 /* physically contig pfns (ie sg[x].length > PAGE_SIZE). */
644 .use_clustering = ENABLE_CLUSTERING,
645 /* Make sure we dont get a sg segment crosses a page boundary */
646 .dma_boundary = PAGE_SIZE-1,
647};
648
649
650/*
651 * storvsc_probe - Add a new device for this driver
652 */
653
654static int storvsc_probe(struct hv_device *device)
655{
656 int ret;
657 struct Scsi_Host *host;
658 struct hv_host_device *host_dev;
659 struct storvsc_device_info device_info;
660
661 host = scsi_host_alloc(&scsi_driver,
662 sizeof(struct hv_host_device));
663 if (!host)
664 return -ENOMEM;
665
666 dev_set_drvdata(&device->device, host);
667
668 host_dev = (struct hv_host_device *)host->hostdata;
669 memset(host_dev, 0, sizeof(struct hv_host_device));
670
671 host_dev->port = host->host_no;
672 host_dev->dev = device;
673
674 host_dev->request_pool =
675 kmem_cache_create(dev_name(&device->device),
676 sizeof(struct storvsc_cmd_request), 0,
677 SLAB_HWCACHE_ALIGN, NULL);
678
679 if (!host_dev->request_pool) {
680 scsi_host_put(host);
681 return -ENOMEM;
682 }
683
684 device_info.port_number = host->host_no;
685 device_info.ring_buffer_size = storvsc_ringbuffer_size;
686 /* Call to the vsc driver to add the device */
687 ret = storvsc_dev_add(device, (void *)&device_info);
688
689 if (ret != 0) {
690 kmem_cache_destroy(host_dev->request_pool);
691 scsi_host_put(host);
692 return -1;
693 }
694
695 host_dev->path = device_info.path_id;
696 host_dev->target = device_info.target_id;
697
698 /* max # of devices per target */
699 host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
700 /* max # of targets per channel */
701 host->max_id = STORVSC_MAX_TARGETS;
702 /* max # of channels */
703 host->max_channel = STORVSC_MAX_CHANNELS - 1;
704 /* max cmd length */
705 host->max_cmd_len = STORVSC_MAX_CMD_LEN;
706
707 /* Register the HBA and start the scsi bus scan */
708 ret = scsi_add_host(host, &device->device);
709 if (ret != 0) {
710
711 storvsc_dev_remove(device);
712
713 kmem_cache_destroy(host_dev->request_pool);
714 scsi_host_put(host);
715 return -1;
716 }
717
718 scsi_scan_host(host);
719 return ret;
720}
721
722/* The one and only one */
723
724static struct hv_driver storvsc_drv = {
725 .probe = storvsc_probe,
726 .remove = storvsc_remove,
727};
728
729/*
730 * We use a DMI table to determine if we should autoload this driver This is
731 * needed by distro tools to determine if the hyperv drivers should be
732 * installed and/or configured. We don't do anything else with the table, but
733 * it needs to be present.
734 */
735
736static const struct dmi_system_id __initconst
737hv_stor_dmi_table[] __maybe_unused = {
738 {
739 .ident = "Hyper-V",
740 .matches = {
741 DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
742 DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
743 DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
744 },
745 },
746 { },
747};
748MODULE_DEVICE_TABLE(dmi, hv_stor_dmi_table);
749
750static int __init storvsc_drv_init(void)
751{
752 int ret;
753 struct hv_driver *drv = &storvsc_drv;
754 u32 max_outstanding_req_per_channel;
755
756 /*
757 * Divide the ring buffer data size (which is 1 page less
758 * than the ring buffer size since that page is reserved for
759 * the ring buffer indices) by the max request size (which is
760 * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64)
761 */
762
763 max_outstanding_req_per_channel =
764 ((storvsc_ringbuffer_size - PAGE_SIZE) /
765 ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
766 sizeof(struct vstor_packet) + sizeof(u64),
767 sizeof(u64)));
768
769 memcpy(&drv->dev_type, &stor_vsci_device_type,
770 sizeof(struct hv_guid));
771
772 if (max_outstanding_req_per_channel <
773 STORVSC_MAX_IO_REQUESTS)
774 return -1;
775
776 drv->driver.name = driver_name;
777
778
779 /* The driver belongs to vmbus */
780 ret = vmbus_child_driver_register(&drv->driver);
781
782 return ret;
783}
784
785static void __exit storvsc_drv_exit(void)
786{
787 vmbus_child_driver_unregister(&storvsc_drv.driver);
788}
789
790MODULE_LICENSE("GPL");
791MODULE_VERSION(HV_DRV_VERSION);
792MODULE_DESCRIPTION("Microsoft Hyper-V virtual storage driver");
793module_init(storvsc_drv_init);
794module_exit(storvsc_drv_exit);
diff --git a/drivers/staging/hv/tools/hv_kvp_daemon.c b/drivers/staging/hv/tools/hv_kvp_daemon.c
new file mode 100644
index 00000000000..a4a407f7052
--- /dev/null
+++ b/drivers/staging/hv/tools/hv_kvp_daemon.c
@@ -0,0 +1,493 @@
1/*
2 * An implementation of key value pair (KVP) functionality for Linux.
3 *
4 *
5 * Copyright (C) 2010, Novell, Inc.
6 * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
15 * NON INFRINGEMENT. See the GNU General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24
25#include <sys/types.h>
26#include <sys/socket.h>
27#include <sys/poll.h>
28#include <sys/utsname.h>
29#include <linux/types.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <unistd.h>
33#include <string.h>
34#include <errno.h>
35#include <arpa/inet.h>
36#include <linux/connector.h>
37#include <linux/netlink.h>
38#include <ifaddrs.h>
39#include <netdb.h>
40#include <syslog.h>
41
42/*
43 * KYS: TODO. Need to register these in the kernel.
44 *
45 * The following definitions are shared with the in-kernel component; do not
46 * change any of this without making the corresponding changes in
47 * the KVP kernel component.
48 */
49#define CN_KVP_IDX 0x9 /* MSFT KVP functionality */
50#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */
51#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */
52
53/*
54 * KVP protocol: The user mode component first registers with the
55 * the kernel component. Subsequently, the kernel component requests, data
56 * for the specified keys. In response to this message the user mode component
57 * fills in the value corresponding to the specified key. We overload the
58 * sequence field in the cn_msg header to define our KVP message types.
59 *
60 * We use this infrastructure for also supporting queries from user mode
61 * application for state that may be maintained in the KVP kernel component.
62 *
63 * XXXKYS: Have a shared header file between the user and kernel (TODO)
64 */
65
66enum kvp_op {
67 KVP_REGISTER = 0, /* Register the user mode component*/
68 KVP_KERNEL_GET, /*Kernel is requesting the value for the specified key*/
69 KVP_KERNEL_SET, /*Kernel is providing the value for the specified key*/
70 KVP_USER_GET, /*User is requesting the value for the specified key*/
71 KVP_USER_SET /*User is providing the value for the specified key*/
72};
73
74#define HV_KVP_EXCHANGE_MAX_KEY_SIZE 512
75#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE 2048
76
77struct hv_ku_msg {
78 __u32 kvp_index;
79 __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */
80 __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */
81};
82
83enum key_index {
84 FullyQualifiedDomainName = 0,
85 IntegrationServicesVersion, /*This key is serviced in the kernel*/
86 NetworkAddressIPv4,
87 NetworkAddressIPv6,
88 OSBuildNumber,
89 OSName,
90 OSMajorVersion,
91 OSMinorVersion,
92 OSVersion,
93 ProcessorArchitecture
94};
95
96/*
97 * End of shared definitions.
98 */
99
100static char kvp_send_buffer[4096];
101static char kvp_recv_buffer[4096];
102static struct sockaddr_nl addr;
103
104static char *os_name = "";
105static char *os_major = "";
106static char *os_minor = "";
107static char *processor_arch;
108static char *os_build;
109static char *lic_version;
110static struct utsname uts_buf;
111
112void kvp_get_os_info(void)
113{
114 FILE *file;
115 char *p, buf[512];
116
117 uname(&uts_buf);
118 os_build = uts_buf.release;
119 processor_arch= uts_buf.machine;
120
121 file = fopen("/etc/SuSE-release", "r");
122 if (file != NULL)
123 goto kvp_osinfo_found;
124 file = fopen("/etc/redhat-release", "r");
125 if (file != NULL)
126 goto kvp_osinfo_found;
127 /*
128 * Add code for other supported platforms.
129 */
130
131 /*
132 * We don't have information about the os.
133 */
134 os_name = uts_buf.sysname;
135 return;
136
137kvp_osinfo_found:
138 /* up to three lines */
139 p = fgets(buf, sizeof(buf), file);
140 if (p) {
141 p = strchr(buf, '\n');
142 if (p)
143 *p = '\0';
144 p = strdup(buf);
145 if (!p)
146 goto done;
147 os_name = p;
148
149 /* second line */
150 p = fgets(buf, sizeof(buf), file);
151 if (p) {
152 p = strchr(buf, '\n');
153 if (p)
154 *p = '\0';
155 p = strdup(buf);
156 if (!p)
157 goto done;
158 os_major = p;
159
160 /* third line */
161 p = fgets(buf, sizeof(buf), file);
162 if (p) {
163 p = strchr(buf, '\n');
164 if (p)
165 *p = '\0';
166 p = strdup(buf);
167 if (p)
168 os_minor = p;
169 }
170 }
171 }
172
173done:
174 fclose(file);
175 return;
176}
177
178static int
179kvp_get_ip_address(int family, char *buffer, int length)
180{
181 struct ifaddrs *ifap;
182 struct ifaddrs *curp;
183 int ipv4_len = strlen("255.255.255.255") + 1;
184 int ipv6_len = strlen("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")+1;
185 int offset = 0;
186 const char *str;
187 char tmp[50];
188 int error = 0;
189
190 /*
191 * On entry into this function, the buffer is capable of holding the
192 * maximum key value (2048 bytes).
193 */
194
195 if (getifaddrs(&ifap)) {
196 strcpy(buffer, "getifaddrs failed\n");
197 return 1;
198 }
199
200 curp = ifap;
201 while (curp != NULL) {
202 if ((curp->ifa_addr != NULL) &&
203 (curp->ifa_addr->sa_family == family)) {
204 if (family == AF_INET) {
205 struct sockaddr_in *addr =
206 (struct sockaddr_in *) curp->ifa_addr;
207
208 str = inet_ntop(family, &addr->sin_addr,
209 tmp, 50);
210 if (str == NULL) {
211 strcpy(buffer, "inet_ntop failed\n");
212 error = 1;
213 goto getaddr_done;
214 }
215 if (offset == 0)
216 strcpy(buffer, tmp);
217 else
218 strcat(buffer, tmp);
219 strcat(buffer, ";");
220
221 offset += strlen(str) + 1;
222 if ((length - offset) < (ipv4_len + 1))
223 goto getaddr_done;
224
225 } else {
226
227 /*
228 * We only support AF_INET and AF_INET6
229 * and the list of addresses is separated by a ";".
230 */
231 struct sockaddr_in6 *addr =
232 (struct sockaddr_in6 *) curp->ifa_addr;
233
234 str = inet_ntop(family,
235 &addr->sin6_addr.s6_addr,
236 tmp, 50);
237 if (str == NULL) {
238 strcpy(buffer, "inet_ntop failed\n");
239 error = 1;
240 goto getaddr_done;
241 }
242 if (offset == 0)
243 strcpy(buffer, tmp);
244 else
245 strcat(buffer, tmp);
246 strcat(buffer, ";");
247 offset += strlen(str) + 1;
248 if ((length - offset) < (ipv6_len + 1))
249 goto getaddr_done;
250
251 }
252
253 }
254 curp = curp->ifa_next;
255 }
256
257getaddr_done:
258 freeifaddrs(ifap);
259 return error;
260}
261
262
263static int
264kvp_get_domain_name(char *buffer, int length)
265{
266 struct addrinfo hints, *info ;
267 gethostname(buffer, length);
268 int error = 0;
269
270 memset(&hints, 0, sizeof(hints));
271 hints.ai_family = AF_INET; /*Get only ipv4 addrinfo. */
272 hints.ai_socktype = SOCK_STREAM;
273 hints.ai_flags = AI_CANONNAME;
274
275 error = getaddrinfo(buffer, "http", &hints, &info);
276 if (error != 0) {
277 strcpy(buffer, "getaddrinfo failed\n");
278 error = 1;
279 goto get_domain_done;
280 }
281 strcpy(buffer, info->ai_canonname);
282get_domain_done:
283 freeaddrinfo(info);
284 return error;
285}
286
287static int
288netlink_send(int fd, struct cn_msg *msg)
289{
290 struct nlmsghdr *nlh;
291 unsigned int size;
292 struct msghdr message;
293 char buffer[64];
294 struct iovec iov[2];
295
296 size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
297
298 nlh = (struct nlmsghdr *)buffer;
299 nlh->nlmsg_seq = 0;
300 nlh->nlmsg_pid = getpid();
301 nlh->nlmsg_type = NLMSG_DONE;
302 nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
303 nlh->nlmsg_flags = 0;
304
305 iov[0].iov_base = nlh;
306 iov[0].iov_len = sizeof(*nlh);
307
308 iov[1].iov_base = msg;
309 iov[1].iov_len = size;
310
311 memset(&message, 0, sizeof(message));
312 message.msg_name = &addr;
313 message.msg_namelen = sizeof(addr);
314 message.msg_iov = iov;
315 message.msg_iovlen = 2;
316
317 return sendmsg(fd, &message, 0);
318}
319
320int main(void)
321{
322 int fd, len, sock_opt;
323 int error;
324 struct cn_msg *message;
325 struct pollfd pfd;
326 struct nlmsghdr *incoming_msg;
327 struct cn_msg *incoming_cn_msg;
328 struct hv_ku_msg *hv_msg;
329 char *p;
330 char *key_value;
331 char *key_name;
332
333 daemon(1, 0);
334 openlog("KVP", 0, LOG_USER);
335 syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
336 /*
337 * Retrieve OS release information.
338 */
339 kvp_get_os_info();
340
341 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
342 if (fd < 0) {
343 syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd);
344 exit(-1);
345 }
346 addr.nl_family = AF_NETLINK;
347 addr.nl_pad = 0;
348 addr.nl_pid = 0;
349 addr.nl_groups = CN_KVP_IDX;
350
351
352 error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
353 if (error < 0) {
354 syslog(LOG_ERR, "bind failed; error:%d", error);
355 close(fd);
356 exit(-1);
357 }
358 sock_opt = addr.nl_groups;
359 setsockopt(fd, 270, 1, &sock_opt, sizeof(sock_opt));
360 /*
361 * Register ourselves with the kernel.
362 */
363 message = (struct cn_msg *)kvp_send_buffer;
364 message->id.idx = CN_KVP_IDX;
365 message->id.val = CN_KVP_VAL;
366 message->seq = KVP_REGISTER;
367 message->ack = 0;
368 message->len = 0;
369
370 len = netlink_send(fd, message);
371 if (len < 0) {
372 syslog(LOG_ERR, "netlink_send failed; error:%d", len);
373 close(fd);
374 exit(-1);
375 }
376
377 pfd.fd = fd;
378
379 while (1) {
380 pfd.events = POLLIN;
381 pfd.revents = 0;
382 poll(&pfd, 1, -1);
383
384 len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0);
385
386 if (len < 0) {
387 syslog(LOG_ERR, "recv failed; error:%d", len);
388 close(fd);
389 return -1;
390 }
391
392 incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
393 incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
394
395 switch (incoming_cn_msg->seq) {
396 case KVP_REGISTER:
397 /*
398 * Driver is registering with us; stash away the version
399 * information.
400 */
401 p = (char *)incoming_cn_msg->data;
402 lic_version = malloc(strlen(p) + 1);
403 if (lic_version) {
404 strcpy(lic_version, p);
405 syslog(LOG_INFO, "KVP LIC Version: %s",
406 lic_version);
407 } else {
408 syslog(LOG_ERR, "malloc failed");
409 }
410 continue;
411
412 case KVP_KERNEL_GET:
413 break;
414 default:
415 continue;
416 }
417
418 hv_msg = (struct hv_ku_msg *)incoming_cn_msg->data;
419 key_name = (char *)hv_msg->kvp_key;
420 key_value = (char *)hv_msg->kvp_value;
421
422 switch (hv_msg->kvp_index) {
423 case FullyQualifiedDomainName:
424 kvp_get_domain_name(key_value,
425 HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
426 strcpy(key_name, "FullyQualifiedDomainName");
427 break;
428 case IntegrationServicesVersion:
429 strcpy(key_name, "IntegrationServicesVersion");
430 strcpy(key_value, lic_version);
431 break;
432 case NetworkAddressIPv4:
433 kvp_get_ip_address(AF_INET, key_value,
434 HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
435 strcpy(key_name, "NetworkAddressIPv4");
436 break;
437 case NetworkAddressIPv6:
438 kvp_get_ip_address(AF_INET6, key_value,
439 HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
440 strcpy(key_name, "NetworkAddressIPv6");
441 break;
442 case OSBuildNumber:
443 strcpy(key_value, os_build);
444 strcpy(key_name, "OSBuildNumber");
445 break;
446 case OSName:
447 strcpy(key_value, os_name);
448 strcpy(key_name, "OSName");
449 break;
450 case OSMajorVersion:
451 strcpy(key_value, os_major);
452 strcpy(key_name, "OSMajorVersion");
453 break;
454 case OSMinorVersion:
455 strcpy(key_value, os_minor);
456 strcpy(key_name, "OSMinorVersion");
457 break;
458 case OSVersion:
459 strcpy(key_value, os_build);
460 strcpy(key_name, "OSVersion");
461 break;
462 case ProcessorArchitecture:
463 strcpy(key_value, processor_arch);
464 strcpy(key_name, "ProcessorArchitecture");
465 break;
466 default:
467 strcpy(key_value, "Unknown Key");
468 /*
469 * We use a null key name to terminate enumeration.
470 */
471 strcpy(key_name, "");
472 break;
473 }
474 /*
475 * Send the value back to the kernel. The response is
476 * already in the receive buffer. Update the cn_msg header to
477 * reflect the key value that has been added to the message
478 */
479
480 incoming_cn_msg->id.idx = CN_KVP_IDX;
481 incoming_cn_msg->id.val = CN_KVP_VAL;
482 incoming_cn_msg->seq = KVP_USER_SET;
483 incoming_cn_msg->ack = 0;
484 incoming_cn_msg->len = sizeof(struct hv_ku_msg);
485
486 len = netlink_send(fd, incoming_cn_msg);
487 if (len < 0) {
488 syslog(LOG_ERR, "net_link send failed; error:%d", len);
489 exit(-1);
490 }
491 }
492
493}
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
new file mode 100644
index 00000000000..1c949f5fb71
--- /dev/null
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -0,0 +1,802 @@
1/*
2 * Copyright (c) 2009, Microsoft Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Authors:
18 * Haiyang Zhang <haiyangz@microsoft.com>
19 * Hank Janssen <hjanssen@microsoft.com>
20 * K. Y. Srinivasan <kys@microsoft.com>
21 *
22 */
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/device.h>
28#include <linux/irq.h>
29#include <linux/interrupt.h>
30#include <linux/sysctl.h>
31#include <linux/pci.h>
32#include <linux/dmi.h>
33#include <linux/slab.h>
34#include <linux/acpi.h>
35#include <acpi/acpi_bus.h>
36#include <linux/completion.h>
37
38#include "hyperv.h"
39#include "hyperv_vmbus.h"
40
41
42static struct acpi_device *hv_acpi_dev;
43
44static struct tasklet_struct msg_dpc;
45static struct tasklet_struct event_dpc;
46
47unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL);
48EXPORT_SYMBOL(vmbus_loglevel);
49 /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
50 /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
51
52static struct completion probe_event;
53static int irq;
54
55static void get_channel_info(struct hv_device *device,
56 struct hv_device_info *info)
57{
58 struct vmbus_channel_debug_info debug_info;
59
60 if (!device->channel)
61 return;
62
63 vmbus_get_debug_info(device->channel, &debug_info);
64
65 info->chn_id = debug_info.relid;
66 info->chn_state = debug_info.state;
67 memcpy(&info->chn_type, &debug_info.interfacetype,
68 sizeof(struct hv_guid));
69 memcpy(&info->chn_instance, &debug_info.interface_instance,
70 sizeof(struct hv_guid));
71
72 info->monitor_id = debug_info.monitorid;
73
74 info->server_monitor_pending = debug_info.servermonitor_pending;
75 info->server_monitor_latency = debug_info.servermonitor_latency;
76 info->server_monitor_conn_id = debug_info.servermonitor_connectionid;
77
78 info->client_monitor_pending = debug_info.clientmonitor_pending;
79 info->client_monitor_latency = debug_info.clientmonitor_latency;
80 info->client_monitor_conn_id = debug_info.clientmonitor_connectionid;
81
82 info->inbound.int_mask = debug_info.inbound.current_interrupt_mask;
83 info->inbound.read_idx = debug_info.inbound.current_read_index;
84 info->inbound.write_idx = debug_info.inbound.current_write_index;
85 info->inbound.bytes_avail_toread =
86 debug_info.inbound.bytes_avail_toread;
87 info->inbound.bytes_avail_towrite =
88 debug_info.inbound.bytes_avail_towrite;
89
90 info->outbound.int_mask =
91 debug_info.outbound.current_interrupt_mask;
92 info->outbound.read_idx = debug_info.outbound.current_read_index;
93 info->outbound.write_idx = debug_info.outbound.current_write_index;
94 info->outbound.bytes_avail_toread =
95 debug_info.outbound.bytes_avail_toread;
96 info->outbound.bytes_avail_towrite =
97 debug_info.outbound.bytes_avail_towrite;
98}
99
100/*
101 * vmbus_show_device_attr - Show the device attribute in sysfs.
102 *
103 * This is invoked when user does a
104 * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
105 */
106static ssize_t vmbus_show_device_attr(struct device *dev,
107 struct device_attribute *dev_attr,
108 char *buf)
109{
110 struct hv_device *hv_dev = device_to_hv_device(dev);
111 struct hv_device_info device_info;
112
113 memset(&device_info, 0, sizeof(struct hv_device_info));
114
115 get_channel_info(hv_dev, &device_info);
116
117 if (!strcmp(dev_attr->attr.name, "class_id")) {
118 return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
119 "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
120 device_info.chn_type.data[3],
121 device_info.chn_type.data[2],
122 device_info.chn_type.data[1],
123 device_info.chn_type.data[0],
124 device_info.chn_type.data[5],
125 device_info.chn_type.data[4],
126 device_info.chn_type.data[7],
127 device_info.chn_type.data[6],
128 device_info.chn_type.data[8],
129 device_info.chn_type.data[9],
130 device_info.chn_type.data[10],
131 device_info.chn_type.data[11],
132 device_info.chn_type.data[12],
133 device_info.chn_type.data[13],
134 device_info.chn_type.data[14],
135 device_info.chn_type.data[15]);
136 } else if (!strcmp(dev_attr->attr.name, "device_id")) {
137 return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
138 "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
139 device_info.chn_instance.data[3],
140 device_info.chn_instance.data[2],
141 device_info.chn_instance.data[1],
142 device_info.chn_instance.data[0],
143 device_info.chn_instance.data[5],
144 device_info.chn_instance.data[4],
145 device_info.chn_instance.data[7],
146 device_info.chn_instance.data[6],
147 device_info.chn_instance.data[8],
148 device_info.chn_instance.data[9],
149 device_info.chn_instance.data[10],
150 device_info.chn_instance.data[11],
151 device_info.chn_instance.data[12],
152 device_info.chn_instance.data[13],
153 device_info.chn_instance.data[14],
154 device_info.chn_instance.data[15]);
155 } else if (!strcmp(dev_attr->attr.name, "state")) {
156 return sprintf(buf, "%d\n", device_info.chn_state);
157 } else if (!strcmp(dev_attr->attr.name, "id")) {
158 return sprintf(buf, "%d\n", device_info.chn_id);
159 } else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
160 return sprintf(buf, "%d\n", device_info.outbound.int_mask);
161 } else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
162 return sprintf(buf, "%d\n", device_info.outbound.read_idx);
163 } else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
164 return sprintf(buf, "%d\n", device_info.outbound.write_idx);
165 } else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
166 return sprintf(buf, "%d\n",
167 device_info.outbound.bytes_avail_toread);
168 } else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
169 return sprintf(buf, "%d\n",
170 device_info.outbound.bytes_avail_towrite);
171 } else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
172 return sprintf(buf, "%d\n", device_info.inbound.int_mask);
173 } else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
174 return sprintf(buf, "%d\n", device_info.inbound.read_idx);
175 } else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
176 return sprintf(buf, "%d\n", device_info.inbound.write_idx);
177 } else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
178 return sprintf(buf, "%d\n",
179 device_info.inbound.bytes_avail_toread);
180 } else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
181 return sprintf(buf, "%d\n",
182 device_info.inbound.bytes_avail_towrite);
183 } else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
184 return sprintf(buf, "%d\n", device_info.monitor_id);
185 } else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
186 return sprintf(buf, "%d\n", device_info.server_monitor_pending);
187 } else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
188 return sprintf(buf, "%d\n", device_info.server_monitor_latency);
189 } else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
190 return sprintf(buf, "%d\n",
191 device_info.server_monitor_conn_id);
192 } else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
193 return sprintf(buf, "%d\n", device_info.client_monitor_pending);
194 } else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
195 return sprintf(buf, "%d\n", device_info.client_monitor_latency);
196 } else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
197 return sprintf(buf, "%d\n",
198 device_info.client_monitor_conn_id);
199 } else {
200 return 0;
201 }
202}
203
204/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
205static struct device_attribute vmbus_device_attrs[] = {
206 __ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
207 __ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
208 __ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
209 __ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
210 __ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
211
212 __ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
213 __ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
214 __ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
215
216 __ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
217 __ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
218 __ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
219
220 __ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
221 __ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
222 __ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
223 __ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
224 __ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
225
226 __ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
227 __ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
228 __ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
229 __ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
230 __ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
231 __ATTR_NULL
232};
233
234
235/*
236 * vmbus_uevent - add uevent for our device
237 *
238 * This routine is invoked when a device is added or removed on the vmbus to
239 * generate a uevent to udev in the userspace. The udev will then look at its
240 * rule and the uevent generated here to load the appropriate driver
241 */
242static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
243{
244 struct hv_device *dev = device_to_hv_device(device);
245 int ret;
246
247 ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
248 "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
249 "%02x%02x%02x%02x%02x%02x%02x%02x}",
250 dev->dev_type.data[3],
251 dev->dev_type.data[2],
252 dev->dev_type.data[1],
253 dev->dev_type.data[0],
254 dev->dev_type.data[5],
255 dev->dev_type.data[4],
256 dev->dev_type.data[7],
257 dev->dev_type.data[6],
258 dev->dev_type.data[8],
259 dev->dev_type.data[9],
260 dev->dev_type.data[10],
261 dev->dev_type.data[11],
262 dev->dev_type.data[12],
263 dev->dev_type.data[13],
264 dev->dev_type.data[14],
265 dev->dev_type.data[15]);
266
267 if (ret)
268 return ret;
269
270 ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={"
271 "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
272 "%02x%02x%02x%02x%02x%02x%02x%02x}",
273 dev->dev_instance.data[3],
274 dev->dev_instance.data[2],
275 dev->dev_instance.data[1],
276 dev->dev_instance.data[0],
277 dev->dev_instance.data[5],
278 dev->dev_instance.data[4],
279 dev->dev_instance.data[7],
280 dev->dev_instance.data[6],
281 dev->dev_instance.data[8],
282 dev->dev_instance.data[9],
283 dev->dev_instance.data[10],
284 dev->dev_instance.data[11],
285 dev->dev_instance.data[12],
286 dev->dev_instance.data[13],
287 dev->dev_instance.data[14],
288 dev->dev_instance.data[15]);
289 if (ret)
290 return ret;
291
292 return 0;
293}
294
295
296/*
297 * vmbus_match - Attempt to match the specified device to the specified driver
298 */
299static int vmbus_match(struct device *device, struct device_driver *driver)
300{
301 int match = 0;
302 struct hv_driver *drv = drv_to_hv_drv(driver);
303 struct hv_device *hv_dev = device_to_hv_device(device);
304
305 /* We found our driver ? */
306 if (memcmp(&hv_dev->dev_type, &drv->dev_type,
307 sizeof(struct hv_guid)) == 0)
308 match = 1;
309
310 return match;
311}
312
313/*
314 * vmbus_probe - Add the new vmbus's child device
315 */
316static int vmbus_probe(struct device *child_device)
317{
318 int ret = 0;
319 struct hv_driver *drv =
320 drv_to_hv_drv(child_device->driver);
321 struct hv_device *dev = device_to_hv_device(child_device);
322
323 if (drv->probe) {
324 ret = drv->probe(dev);
325 if (ret != 0)
326 pr_err("probe failed for device %s (%d)\n",
327 dev_name(child_device), ret);
328
329 } else {
330 pr_err("probe not set for driver %s\n",
331 dev_name(child_device));
332 ret = -ENODEV;
333 }
334 return ret;
335}
336
337/*
338 * vmbus_remove - Remove a vmbus device
339 */
340static int vmbus_remove(struct device *child_device)
341{
342 int ret;
343 struct hv_driver *drv;
344
345 struct hv_device *dev = device_to_hv_device(child_device);
346
347 if (child_device->driver) {
348 drv = drv_to_hv_drv(child_device->driver);
349
350 if (drv->remove) {
351 ret = drv->remove(dev);
352 } else {
353 pr_err("remove not set for driver %s\n",
354 dev_name(child_device));
355 ret = -ENODEV;
356 }
357 }
358
359 return 0;
360}
361
362
363/*
364 * vmbus_shutdown - Shutdown a vmbus device
365 */
366static void vmbus_shutdown(struct device *child_device)
367{
368 struct hv_driver *drv;
369 struct hv_device *dev = device_to_hv_device(child_device);
370
371
372 /* The device may not be attached yet */
373 if (!child_device->driver)
374 return;
375
376 drv = drv_to_hv_drv(child_device->driver);
377
378 if (drv->shutdown)
379 drv->shutdown(dev);
380
381 return;
382}
383
384
385/*
386 * vmbus_device_release - Final callback release of the vmbus child device
387 */
388static void vmbus_device_release(struct device *device)
389{
390 struct hv_device *hv_dev = device_to_hv_device(device);
391
392 kfree(hv_dev);
393
394}
395
396/* The one and only one */
397static struct bus_type hv_bus = {
398 .name = "vmbus",
399 .match = vmbus_match,
400 .shutdown = vmbus_shutdown,
401 .remove = vmbus_remove,
402 .probe = vmbus_probe,
403 .uevent = vmbus_uevent,
404 .dev_attrs = vmbus_device_attrs,
405};
406
407static const char *driver_name = "hyperv";
408
409
410struct onmessage_work_context {
411 struct work_struct work;
412 struct hv_message msg;
413};
414
415static void vmbus_onmessage_work(struct work_struct *work)
416{
417 struct onmessage_work_context *ctx;
418
419 ctx = container_of(work, struct onmessage_work_context,
420 work);
421 vmbus_onmessage(&ctx->msg);
422 kfree(ctx);
423}
424
425/*
426 * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior
427 */
428static void vmbus_on_msg_dpc(unsigned long data)
429{
430 int cpu = smp_processor_id();
431 void *page_addr = hv_context.synic_message_page[cpu];
432 struct hv_message *msg = (struct hv_message *)page_addr +
433 VMBUS_MESSAGE_SINT;
434 struct onmessage_work_context *ctx;
435
436 while (1) {
437 if (msg->header.message_type == HVMSG_NONE) {
438 /* no msg */
439 break;
440 } else {
441 ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
442 if (ctx == NULL)
443 continue;
444 INIT_WORK(&ctx->work, vmbus_onmessage_work);
445 memcpy(&ctx->msg, msg, sizeof(*msg));
446 queue_work(vmbus_connection.work_queue, &ctx->work);
447 }
448
449 msg->header.message_type = HVMSG_NONE;
450
451 /*
452 * Make sure the write to MessageType (ie set to
453 * HVMSG_NONE) happens before we read the
454 * MessagePending and EOMing. Otherwise, the EOMing
455 * will not deliver any more messages since there is
456 * no empty slot
457 */
458 smp_mb();
459
460 if (msg->header.message_flags.msg_pending) {
461 /*
462 * This will cause message queue rescan to
463 * possibly deliver another msg from the
464 * hypervisor
465 */
466 wrmsrl(HV_X64_MSR_EOM, 0);
467 }
468 }
469}
470
471/*
472 * vmbus_on_isr - ISR routine
473 */
474static int vmbus_on_isr(void)
475{
476 int ret = 0;
477 int cpu = smp_processor_id();
478 void *page_addr;
479 struct hv_message *msg;
480 union hv_synic_event_flags *event;
481
482 page_addr = hv_context.synic_message_page[cpu];
483 msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
484
485 /* Check if there are actual msgs to be process */
486 if (msg->header.message_type != HVMSG_NONE)
487 ret |= 0x1;
488
489 page_addr = hv_context.synic_event_page[cpu];
490 event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
491
492 /* Since we are a child, we only need to check bit 0 */
493 if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0]))
494 ret |= 0x2;
495
496 return ret;
497}
498
499
500static irqreturn_t vmbus_isr(int irq, void *dev_id)
501{
502 int ret;
503
504 ret = vmbus_on_isr();
505
506 /* Schedules a dpc if necessary */
507 if (ret > 0) {
508 if (test_bit(0, (unsigned long *)&ret))
509 tasklet_schedule(&msg_dpc);
510
511 if (test_bit(1, (unsigned long *)&ret))
512 tasklet_schedule(&event_dpc);
513
514 return IRQ_HANDLED;
515 } else {
516 return IRQ_NONE;
517 }
518}
519
520/*
521 * vmbus_bus_init -Main vmbus driver initialization routine.
522 *
523 * Here, we
524 * - initialize the vmbus driver context
525 * - invoke the vmbus hv main init routine
526 * - get the irq resource
527 * - retrieve the channel offers
528 */
529static int vmbus_bus_init(int irq)
530{
531 int ret;
532 unsigned int vector;
533
534 /* Hypervisor initialization...setup hypercall page..etc */
535 ret = hv_init();
536 if (ret != 0) {
537 pr_err("Unable to initialize the hypervisor - 0x%x\n", ret);
538 return ret;
539 }
540
541 /* Initialize the bus context */
542 tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
543 tasklet_init(&event_dpc, vmbus_on_event, 0);
544
545 /* Now, register the bus with LDM */
546 ret = bus_register(&hv_bus);
547 if (ret)
548 return ret;
549
550 /* Get the interrupt resource */
551 ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
552 driver_name, hv_acpi_dev);
553
554 if (ret != 0) {
555 pr_err("Unable to request IRQ %d\n",
556 irq);
557
558 bus_unregister(&hv_bus);
559
560 return ret;
561 }
562
563 vector = IRQ0_VECTOR + irq;
564
565 /*
566 * Notify the hypervisor of our irq and
567 * connect to the host.
568 */
569 on_each_cpu(hv_synic_init, (void *)&vector, 1);
570 ret = vmbus_connect();
571 if (ret) {
572 free_irq(irq, hv_acpi_dev);
573 bus_unregister(&hv_bus);
574 return ret;
575 }
576
577
578 vmbus_request_offers();
579
580 return 0;
581}
582
583/**
584 * vmbus_child_driver_register() - Register a vmbus's child driver
585 * @drv: Pointer to driver structure you want to register
586 *
587 *
588 * Registers the given driver with Linux through the 'driver_register()' call
589 * And sets up the hyper-v vmbus handling for this driver.
590 * It will return the state of the 'driver_register()' call.
591 *
592 * Mainly used by Hyper-V drivers.
593 */
594int vmbus_child_driver_register(struct device_driver *drv)
595{
596 int ret;
597
598 pr_info("child driver registering - name %s\n", drv->name);
599
600 /* The child driver on this vmbus */
601 drv->bus = &hv_bus;
602
603 ret = driver_register(drv);
604
605 vmbus_request_offers();
606
607 return ret;
608}
609EXPORT_SYMBOL(vmbus_child_driver_register);
610
611/**
612 * vmbus_child_driver_unregister() - Unregister a vmbus's child driver
613 * @drv: Pointer to driver structure you want to un-register
614 *
615 *
616 * Un-register the given driver with Linux through the 'driver_unregister()'
617 * call. And ungegisters the driver from the Hyper-V vmbus handler.
618 *
619 * Mainly used by Hyper-V drivers.
620 */
621void vmbus_child_driver_unregister(struct device_driver *drv)
622{
623 pr_info("child driver unregistering - name %s\n", drv->name);
624
625 driver_unregister(drv);
626
627}
628EXPORT_SYMBOL(vmbus_child_driver_unregister);
629
630/*
631 * vmbus_child_device_create - Creates and registers a new child device
632 * on the vmbus.
633 */
634struct hv_device *vmbus_child_device_create(struct hv_guid *type,
635 struct hv_guid *instance,
636 struct vmbus_channel *channel)
637{
638 struct hv_device *child_device_obj;
639
640 /* Allocate the new child device */
641 child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL);
642 if (!child_device_obj) {
643 pr_err("Unable to allocate device object for child device\n");
644 return NULL;
645 }
646
647 child_device_obj->channel = channel;
648 memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid));
649 memcpy(&child_device_obj->dev_instance, instance,
650 sizeof(struct hv_guid));
651
652
653 return child_device_obj;
654}
655
656/*
657 * vmbus_child_device_register - Register the child device
658 */
659int vmbus_child_device_register(struct hv_device *child_device_obj)
660{
661 int ret = 0;
662
663 static atomic_t device_num = ATOMIC_INIT(0);
664
665 /* Set the device name. Otherwise, device_register() will fail. */
666 dev_set_name(&child_device_obj->device, "vmbus_0_%d",
667 atomic_inc_return(&device_num));
668
669 /* The new device belongs to this bus */
670 child_device_obj->device.bus = &hv_bus; /* device->dev.bus; */
671 child_device_obj->device.parent = &hv_acpi_dev->dev;
672 child_device_obj->device.release = vmbus_device_release;
673
674 /*
675 * Register with the LDM. This will kick off the driver/device
676 * binding...which will eventually call vmbus_match() and vmbus_probe()
677 */
678 ret = device_register(&child_device_obj->device);
679
680 if (ret)
681 pr_err("Unable to register child device\n");
682 else
683 pr_info("child device %s registered\n",
684 dev_name(&child_device_obj->device));
685
686 return ret;
687}
688
689/*
690 * vmbus_child_device_unregister - Remove the specified child device
691 * from the vmbus.
692 */
693void vmbus_child_device_unregister(struct hv_device *device_obj)
694{
695 /*
696 * Kick off the process of unregistering the device.
697 * This will call vmbus_remove() and eventually vmbus_device_release()
698 */
699 device_unregister(&device_obj->device);
700
701 pr_info("child device %s unregistered\n",
702 dev_name(&device_obj->device));
703}
704
705
706/*
707 * VMBUS is an acpi enumerated device. Get the the IRQ information
708 * from DSDT.
709 */
710
711static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *irq)
712{
713
714 if (res->type == ACPI_RESOURCE_TYPE_IRQ) {
715 struct acpi_resource_irq *irqp;
716 irqp = &res->data.irq;
717
718 *((unsigned int *)irq) = irqp->interrupts[0];
719 }
720
721 return AE_OK;
722}
723
724static int vmbus_acpi_add(struct acpi_device *device)
725{
726 acpi_status result;
727
728 hv_acpi_dev = device;
729
730 result =
731 acpi_walk_resources(device->handle, METHOD_NAME__CRS,
732 vmbus_walk_resources, &irq);
733
734 if (ACPI_FAILURE(result)) {
735 complete(&probe_event);
736 return -ENODEV;
737 }
738 complete(&probe_event);
739 return 0;
740}
741
742static const struct acpi_device_id vmbus_acpi_device_ids[] = {
743 {"VMBUS", 0},
744 {"VMBus", 0},
745 {"", 0},
746};
747MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
748
749static struct acpi_driver vmbus_acpi_driver = {
750 .name = "vmbus",
751 .ids = vmbus_acpi_device_ids,
752 .ops = {
753 .add = vmbus_acpi_add,
754 },
755};
756
757/*
758 * We use a PCI table to determine if we should autoload this driver This is
759 * needed by distro tools to determine if the hyperv drivers should be
760 * installed and/or configured. We don't do anything else with the table, but
761 * it needs to be present.
762 */
763static const struct pci_device_id microsoft_hv_pci_table[] = {
764 { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
765 { 0 }
766};
767MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
768
769static int __init hv_acpi_init(void)
770{
771 int ret;
772
773 init_completion(&probe_event);
774
775 /*
776 * Get irq resources first.
777 */
778
779 ret = acpi_bus_register_driver(&vmbus_acpi_driver);
780
781 if (ret)
782 return ret;
783
784 wait_for_completion(&probe_event);
785
786 if (irq <= 0) {
787 acpi_bus_unregister_driver(&vmbus_acpi_driver);
788 return -ENODEV;
789 }
790
791 ret = vmbus_bus_init(irq);
792 if (ret)
793 acpi_bus_unregister_driver(&vmbus_acpi_driver);
794 return ret;
795}
796
797
798MODULE_LICENSE("GPL");
799MODULE_VERSION(HV_DRV_VERSION);
800module_param(vmbus_loglevel, int, S_IRUGO|S_IWUSR);
801
802module_init(hv_acpi_init);