These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / interface / hyperv / vmbus.c
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 /** @file
27  *
28  * Hyper-V virtual machine bus
29  *
30  */
31
32 #include <stdint.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <assert.h>
38 #include <byteswap.h>
39 #include <ipxe/nap.h>
40 #include <ipxe/malloc.h>
41 #include <ipxe/iobuf.h>
42 #include <ipxe/hyperv.h>
43 #include <ipxe/vmbus.h>
44
45 /** VMBus initial GPADL ID
46  *
47  * This is an opaque value with no meaning.  The Linux kernel uses
48  * 0xe1e10.
49  */
50 #define VMBUS_GPADL_MAGIC 0x18ae0000
51
52 /**
53  * Post message
54  *
55  * @v hv                Hyper-V hypervisor
56  * @v header            Message header
57  * @v len               Length of message (including header)
58  * @ret rc              Return status code
59  */
60 static int vmbus_post_message ( struct hv_hypervisor *hv,
61                                 const struct vmbus_message_header *header,
62                                 size_t len ) {
63         struct vmbus *vmbus = hv->vmbus;
64         int rc;
65
66         /* Post message */
67         if ( ( rc = hv_post_message ( hv, VMBUS_MESSAGE_ID, VMBUS_MESSAGE_TYPE,
68                                       header, len ) ) != 0 ) {
69                 DBGC ( vmbus, "VMBUS %p could not post message: %s\n",
70                        vmbus, strerror ( rc ) );
71                 return rc;
72         }
73
74         return 0;
75 }
76
77 /**
78  * Post empty message
79  *
80  * @v hv                Hyper-V hypervisor
81  * @v type              Message type
82  * @ret rc              Return status code
83  */
84 static int vmbus_post_empty_message ( struct hv_hypervisor *hv,
85                                       unsigned int type ) {
86         struct vmbus_message_header header = { .type = cpu_to_le32 ( type ) };
87
88         return vmbus_post_message ( hv, &header, sizeof ( header ) );
89 }
90
91 /**
92  * Wait for received message
93  *
94  * @v hv                Hyper-V hypervisor
95  * @ret rc              Return status code
96  */
97 static int vmbus_wait_for_message ( struct hv_hypervisor *hv ) {
98         struct vmbus *vmbus = hv->vmbus;
99         int rc;
100
101         /* Wait for message */
102         if ( ( rc = hv_wait_for_message ( hv, VMBUS_MESSAGE_SINT ) ) != 0 ) {
103                 DBGC ( vmbus, "VMBUS %p failed waiting for message: %s\n",
104                        vmbus, strerror ( rc ) );
105                 return rc;
106         }
107
108         /* Sanity check */
109         if ( hv->message->received.type != cpu_to_le32 ( VMBUS_MESSAGE_TYPE ) ){
110                 DBGC ( vmbus, "VMBUS %p invalid message type %d\n",
111                        vmbus, le32_to_cpu ( hv->message->received.type ) );
112                 return -EINVAL;
113         }
114
115         return 0;
116 }
117
118 /**
119  * Initiate contact
120  *
121  * @v hv                Hyper-V hypervisor
122  * @v raw               VMBus protocol (raw) version
123  * @ret rc              Return status code
124  */
125 static int vmbus_initiate_contact ( struct hv_hypervisor *hv,
126                                     unsigned int raw ) {
127         struct vmbus *vmbus = hv->vmbus;
128         const struct vmbus_version_response *version = &vmbus->message->version;
129         struct vmbus_initiate_contact initiate;
130         int rc;
131
132         /* Construct message */
133         memset ( &initiate, 0, sizeof ( initiate ) );
134         initiate.header.type = cpu_to_le32 ( VMBUS_INITIATE_CONTACT );
135         initiate.version.raw = cpu_to_le32 ( raw );
136         initiate.intr = virt_to_phys ( vmbus->intr );
137         initiate.monitor_in = virt_to_phys ( vmbus->monitor_in );
138         initiate.monitor_out = virt_to_phys ( vmbus->monitor_out );
139
140         /* Post message */
141         if ( ( rc = vmbus_post_message ( hv, &initiate.header,
142                                          sizeof ( initiate ) ) ) != 0 )
143                 return rc;
144
145         /* Wait for response */
146         if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
147                 return rc;
148
149         /* Check response */
150         if ( version->header.type != cpu_to_le32 ( VMBUS_VERSION_RESPONSE ) ) {
151                 DBGC ( vmbus, "VMBUS %p unexpected version response type %d\n",
152                        vmbus, le32_to_cpu ( version->header.type ) );
153                 return -EPROTO;
154         }
155         if ( ! version->supported ) {
156                 DBGC ( vmbus, "VMBUS %p requested version not supported\n",
157                        vmbus );
158                 return -ENOTSUP;
159         }
160         if ( version->version.raw != cpu_to_le32 ( raw ) ) {
161                 DBGC ( vmbus, "VMBUS %p unexpected version %d.%d\n",
162                        vmbus, le16_to_cpu ( version->version.major ),
163                        le16_to_cpu ( version->version.minor ) );
164                 return -EPROTO;
165         }
166
167         DBGC ( vmbus, "VMBUS %p initiated contact using version %d.%d\n",
168                vmbus, le16_to_cpu ( version->version.major ),
169                le16_to_cpu ( version->version.minor ) );
170         return 0;
171 }
172
173 /**
174  * Terminate contact
175  *
176  * @v hv                Hyper-V hypervisor
177  * @ret rc              Return status code
178  */
179 static int vmbus_unload ( struct hv_hypervisor *hv ) {
180         struct vmbus *vmbus = hv->vmbus;
181         const struct vmbus_message_header *header = &vmbus->message->header;
182         int rc;
183
184         /* Post message */
185         if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_UNLOAD ) ) != 0 )
186                 return rc;
187
188         /* Wait for response */
189         if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
190                 return rc;
191
192         /* Check response */
193         if ( header->type != cpu_to_le32 ( VMBUS_UNLOAD_RESPONSE ) ) {
194                 DBGC ( vmbus, "VMBUS %p unexpected unload response type %d\n",
195                        vmbus, le32_to_cpu ( header->type ) );
196                 return -EPROTO;
197         }
198
199         return 0;
200 }
201
202 /**
203  * Negotiate protocol version
204  *
205  * @v hv                Hyper-V hypervisor
206  * @ret rc              Return status code
207  */
208 static int vmbus_negotiate_version ( struct hv_hypervisor *hv ) {
209         int rc;
210
211         /* We require the ability to disconnect from and reconnect to
212          * VMBus; if we don't have this then there is no (viable) way
213          * for a loaded operating system to continue to use any VMBus
214          * devices.  (There is also a small but non-zero risk that the
215          * host will continue to write to our interrupt and monitor
216          * pages, since the VMBUS_UNLOAD message in earlier versions
217          * is essentially a no-op.)
218          *
219          * This requires us to ensure that the host supports protocol
220          * version 3.0 (VMBUS_VERSION_WIN8_1).  However, we can't
221          * actually _use_ protocol version 3.0, since doing so causes
222          * an iSCSI-booted Windows Server 2012 R2 VM to crash due to a
223          * NULL pointer dereference in vmbus.sys.
224          *
225          * To work around this problem, we first ensure that we can
226          * connect using protocol v3.0, then disconnect and reconnect
227          * using the oldest known protocol.
228          */
229
230         /* Initiate contact to check for required protocol support */
231         if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WIN8_1 ) ) != 0 )
232                 return rc;
233
234         /* Terminate contact */
235         if ( ( rc = vmbus_unload ( hv ) ) != 0 )
236                 return rc;
237
238         /* Reinitiate contact using the oldest known protocol version */
239         if ( ( rc = vmbus_initiate_contact ( hv, VMBUS_VERSION_WS2008 ) ) != 0 )
240                 return rc;
241
242         return 0;
243 }
244
245 /**
246  * Establish GPA descriptor list
247  *
248  * @v vmdev             VMBus device
249  * @v data              Data buffer
250  * @v len               Length of data buffer
251  * @ret gpadl           GPADL ID, or negative error
252  */
253 int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data,
254                             size_t len ) {
255         struct hv_hypervisor *hv = vmdev->hv;
256         struct vmbus *vmbus = hv->vmbus;
257         physaddr_t addr = user_to_phys ( data, 0 );
258         unsigned int pfn_count = hv_pfn_count ( addr, len );
259         struct {
260                 struct vmbus_gpadl_header gpadlhdr;
261                 struct vmbus_gpa_range range;
262                 uint64_t pfn[pfn_count];
263         } __attribute__ (( packed )) gpadlhdr;
264         const struct vmbus_gpadl_created *created = &vmbus->message->created;
265         static unsigned int gpadl = VMBUS_GPADL_MAGIC;
266         unsigned int i;
267         int rc;
268
269         /* Allocate GPADL ID */
270         gpadl++;
271
272         /* Construct message */
273         memset ( &gpadlhdr, 0, sizeof ( gpadlhdr ) );
274         gpadlhdr.gpadlhdr.header.type = cpu_to_le32 ( VMBUS_GPADL_HEADER );
275         gpadlhdr.gpadlhdr.channel = cpu_to_le32 ( vmdev->channel );
276         gpadlhdr.gpadlhdr.gpadl = cpu_to_le32 ( gpadl );
277         gpadlhdr.gpadlhdr.range_len =
278                 cpu_to_le16 ( ( sizeof ( gpadlhdr.range ) +
279                                 sizeof ( gpadlhdr.pfn ) ) );
280         gpadlhdr.gpadlhdr.range_count = cpu_to_le16 ( 1 );
281         gpadlhdr.range.len = cpu_to_le32 ( len );
282         gpadlhdr.range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
283         for ( i = 0 ; i < pfn_count ; i++ )
284                 gpadlhdr.pfn[i] = ( ( addr / PAGE_SIZE ) + i );
285
286         /* Post message */
287         if ( ( rc = vmbus_post_message ( hv, &gpadlhdr.gpadlhdr.header,
288                                          sizeof ( gpadlhdr ) ) ) != 0 )
289                 return rc;
290
291         /* Wait for response */
292         if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
293                 return rc;
294
295         /* Check response */
296         if ( created->header.type != cpu_to_le32 ( VMBUS_GPADL_CREATED ) ) {
297                 DBGC ( vmdev, "VMBUS %s unexpected GPADL response type %d\n",
298                        vmdev->dev.name, le32_to_cpu ( created->header.type ) );
299                 return -EPROTO;
300         }
301         if ( created->channel != cpu_to_le32 ( vmdev->channel ) ) {
302                 DBGC ( vmdev, "VMBUS %s unexpected GPADL channel %d\n",
303                        vmdev->dev.name, le32_to_cpu ( created->channel ) );
304                 return -EPROTO;
305         }
306         if ( created->gpadl != cpu_to_le32 ( gpadl ) ) {
307                 DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
308                        vmdev->dev.name, le32_to_cpu ( created->gpadl ) );
309                 return -EPROTO;
310         }
311         if ( created->status != 0 ) {
312                 DBGC ( vmdev, "VMBUS %s GPADL creation failed: %#08x\n",
313                        vmdev->dev.name, le32_to_cpu ( created->status ) );
314                 return -EPROTO;
315         }
316
317         DBGC ( vmdev, "VMBUS %s GPADL %#08x is [%08lx,%08lx)\n",
318                vmdev->dev.name, gpadl, addr, ( addr + len ) );
319         return gpadl;
320 }
321
322 /**
323  * Tear down GPA descriptor list
324  *
325  * @v vmdev             VMBus device
326  * @v gpadl             GPADL ID
327  * @ret rc              Return status code
328  */
329 int vmbus_gpadl_teardown ( struct vmbus_device *vmdev, unsigned int gpadl ) {
330         struct hv_hypervisor *hv = vmdev->hv;
331         struct vmbus *vmbus = hv->vmbus;
332         struct vmbus_gpadl_teardown teardown;
333         const struct vmbus_gpadl_torndown *torndown = &vmbus->message->torndown;
334         int rc;
335
336         /* Construct message */
337         memset ( &teardown, 0, sizeof ( teardown ) );
338         teardown.header.type = cpu_to_le32 ( VMBUS_GPADL_TEARDOWN );
339         teardown.channel = cpu_to_le32 ( vmdev->channel );
340         teardown.gpadl = cpu_to_le32 ( gpadl );
341
342         /* Post message */
343         if ( ( rc = vmbus_post_message ( hv, &teardown.header,
344                                          sizeof ( teardown ) ) ) != 0 )
345                 return rc;
346
347         /* Wait for response */
348         if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
349                 return rc;
350
351         /* Check response */
352         if ( torndown->header.type != cpu_to_le32 ( VMBUS_GPADL_TORNDOWN ) ) {
353                 DBGC ( vmdev, "VMBUS %s unexpected GPADL response type %d\n",
354                        vmdev->dev.name, le32_to_cpu ( torndown->header.type ) );
355                 return -EPROTO;
356         }
357         if ( torndown->gpadl != cpu_to_le32 ( gpadl ) ) {
358                 DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
359                        vmdev->dev.name, le32_to_cpu ( torndown->gpadl ) );
360                 return -EPROTO;
361         }
362
363         return 0;
364 }
365
366 /**
367  * Open VMBus channel
368  *
369  * @v vmdev             VMBus device
370  * @v op                Channel operations
371  * @v out_len           Outbound ring buffer length
372  * @v in_len            Inbound ring buffer length
373  * @v mtu               Maximum expected data packet length (including headers)
374  * @ret rc              Return status code
375  *
376  * Both outbound and inbound ring buffer lengths must be a power of
377  * two and a multiple of PAGE_SIZE.  The requirement to be a power of
378  * two is a policy decision taken to simplify the ring buffer indexing
379  * logic.
380  */
381 int vmbus_open ( struct vmbus_device *vmdev,
382                  struct vmbus_channel_operations *op,
383                  size_t out_len, size_t in_len, size_t mtu ) {
384         struct hv_hypervisor *hv = vmdev->hv;
385         struct vmbus *vmbus = hv->vmbus;
386         struct vmbus_open_channel open;
387         const struct vmbus_open_channel_result *opened =
388                 &vmbus->message->opened;
389         size_t len;
390         void *ring;
391         void *packet;
392         int gpadl;
393         uint32_t open_id;
394         int rc;
395
396         /* Sanity checks */
397         assert ( ( out_len % PAGE_SIZE ) == 0 );
398         assert ( ( out_len & ( out_len - 1 ) ) == 0 );
399         assert ( ( in_len % PAGE_SIZE ) == 0 );
400         assert ( ( in_len & ( in_len - 1 ) ) == 0 );
401         assert ( mtu >= ( sizeof ( struct vmbus_packet_header ) +
402                           sizeof ( struct vmbus_packet_footer ) ) );
403
404         /* Allocate packet buffer */
405         packet = malloc ( mtu );
406         if ( ! packet ) {
407                 rc = -ENOMEM;
408                 goto err_alloc_packet;
409         }
410
411         /* Allocate ring buffer */
412         len = ( sizeof ( *vmdev->out ) + out_len +
413                 sizeof ( *vmdev->in ) + in_len );
414         assert ( ( len % PAGE_SIZE ) == 0 );
415         ring = malloc_dma ( len, PAGE_SIZE );
416         if ( ! ring ) {
417                 rc = -ENOMEM;
418                 goto err_alloc_ring;
419         }
420         memset ( ring, 0, len );
421
422         /* Establish GPADL for ring buffer */
423         gpadl = vmbus_establish_gpadl ( vmdev, virt_to_user ( ring ), len );
424         if ( gpadl < 0 ) {
425                 rc = gpadl;
426                 goto err_establish;
427         }
428
429         /* Construct message */
430         memset ( &open, 0, sizeof ( open ) );
431         open.header.type = cpu_to_le32 ( VMBUS_OPEN_CHANNEL );
432         open.channel = cpu_to_le32 ( vmdev->channel );
433         open_id = random();
434         open.id = open_id; /* Opaque random value: endianness irrelevant */
435         open.gpadl = cpu_to_le32 ( gpadl );
436         open.out_pages = ( ( sizeof ( *vmdev->out ) / PAGE_SIZE ) +
437                            ( out_len / PAGE_SIZE ) );
438
439         /* Post message */
440         if ( ( rc = vmbus_post_message ( hv, &open.header,
441                                          sizeof ( open ) ) ) != 0 )
442                 return rc;
443
444         /* Wait for response */
445         if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
446                 return rc;
447
448         /* Check response */
449         if ( opened->header.type != cpu_to_le32 ( VMBUS_OPEN_CHANNEL_RESULT ) ){
450                 DBGC ( vmdev, "VMBUS %s unexpected open response type %d\n",
451                        vmdev->dev.name, le32_to_cpu ( opened->header.type ) );
452                 return -EPROTO;
453         }
454         if ( opened->channel != cpu_to_le32 ( vmdev->channel ) ) {
455                 DBGC ( vmdev, "VMBUS %s unexpected opened channel %#08x\n",
456                        vmdev->dev.name, le32_to_cpu ( opened->channel ) );
457                 return -EPROTO;
458         }
459         if ( opened->id != open_id /* Non-endian */ ) {
460                 DBGC ( vmdev, "VMBUS %s unexpected open ID %#08x\n",
461                        vmdev->dev.name, le32_to_cpu ( opened->id ) );
462                 return -EPROTO;
463         }
464         if ( opened->status != 0 ) {
465                 DBGC ( vmdev, "VMBUS %s open failed: %#08x\n",
466                        vmdev->dev.name, le32_to_cpu ( opened->status ) );
467                 return -EPROTO;
468         }
469
470         /* Store channel parameters */
471         vmdev->out_len = out_len;
472         vmdev->in_len = in_len;
473         vmdev->out = ring;
474         vmdev->in = ( ring + sizeof ( *vmdev->out ) + out_len );
475         vmdev->gpadl = gpadl;
476         vmdev->op = op;
477         vmdev->mtu = mtu;
478         vmdev->packet = packet;
479
480         DBGC ( vmdev, "VMBUS %s channel GPADL %#08x ring "
481                 "[%#08lx,%#08lx,%#08lx)\n", vmdev->dev.name, vmdev->gpadl,
482                 virt_to_phys ( vmdev->out ), virt_to_phys ( vmdev->in ),
483                 ( virt_to_phys ( vmdev->out ) + len ) );
484         return 0;
485
486         vmbus_gpadl_teardown ( vmdev, vmdev->gpadl );
487  err_establish:
488         free_dma ( ring, len );
489  err_alloc_ring:
490         free ( packet );
491  err_alloc_packet:
492         return rc;
493 }
494
495 /**
496  * Close VMBus channel
497  *
498  * @v vmdev             VMBus device
499  */
500 void vmbus_close ( struct vmbus_device *vmdev ) {
501         struct hv_hypervisor *hv = vmdev->hv;
502         struct vmbus_close_channel close;
503         size_t len;
504         int rc;
505
506         /* Construct message */
507         memset ( &close, 0, sizeof ( close ) );
508         close.header.type = cpu_to_le32 ( VMBUS_CLOSE_CHANNEL );
509         close.channel = cpu_to_le32 ( vmdev->channel );
510
511         /* Post message */
512         if ( ( rc = vmbus_post_message ( hv, &close.header,
513                                          sizeof ( close ) ) ) != 0 ) {
514                 DBGC ( vmdev, "VMBUS %s failed to close: %s\n",
515                        vmdev->dev.name, strerror ( rc ) );
516                 /* Continue to attempt to tear down GPADL, so that our
517                  * memory is no longer accessible by the remote VM.
518                  */
519         }
520
521         /* Tear down GPADL */
522         if ( ( rc = vmbus_gpadl_teardown ( vmdev,
523                                            vmdev->gpadl ) ) != 0 ) {
524                 DBGC ( vmdev, "VMBUS %s failed to tear down channel GPADL: "
525                        "%s\n", vmdev->dev.name, strerror ( rc ) );
526                 /* We can't prevent the remote VM from continuing to
527                  * access this memory, so leak it.
528                  */
529                 return;
530         }
531
532         /* Free ring buffer */
533         len = ( sizeof ( *vmdev->out ) + vmdev->out_len +
534                 sizeof ( *vmdev->in ) + vmdev->in_len );
535         free_dma ( vmdev->out, len );
536         vmdev->out = NULL;
537         vmdev->in = NULL;
538
539         /* Free packet buffer */
540         free ( vmdev->packet );
541         vmdev->packet = NULL;
542
543         DBGC ( vmdev, "VMBUS %s closed\n", vmdev->dev.name );
544 }
545
546 /**
547  * Signal channel via monitor page
548  *
549  * @v vmdev             VMBus device
550  */
551 static void vmbus_signal_monitor ( struct vmbus_device *vmdev ) {
552         struct hv_hypervisor *hv = vmdev->hv;
553         struct vmbus *vmbus = hv->vmbus;
554         struct hv_monitor_trigger *trigger;
555         unsigned int group;
556         unsigned int bit;
557
558         /* Set bit in monitor trigger group */
559         group = ( vmdev->monitor / ( 8 * sizeof ( trigger->pending ) ));
560         bit = ( vmdev->monitor % ( 8 * sizeof ( trigger->pending ) ) );
561         trigger = &vmbus->monitor_out->trigger[group];
562         hv_set_bit ( trigger, bit );
563 }
564
565 /**
566  * Signal channel via hypervisor event
567  *
568  * @v vmdev             VMBus device
569  */
570 static void vmbus_signal_event ( struct vmbus_device *vmdev ) {
571         struct hv_hypervisor *hv = vmdev->hv;
572         int rc;
573
574         /* Signal hypervisor event */
575         if ( ( rc = hv_signal_event ( hv, VMBUS_EVENT_ID, 0 ) ) != 0 ) {
576                 DBGC ( vmdev, "VMBUS %s could not signal event: %s\n",
577                        vmdev->dev.name, strerror ( rc ) );
578                 return;
579         }
580 }
581
582 /**
583  * Fill outbound ring buffer
584  *
585  * @v vmdev             VMBus device
586  * @v prod              Producer index
587  * @v data              Data
588  * @v len               Length
589  * @ret prod            New producer index
590  *
591  * The caller must ensure that there is sufficient space in the ring
592  * buffer.
593  */
594 static size_t vmbus_produce ( struct vmbus_device *vmdev, size_t prod,
595                               const void *data, size_t len ) {
596         size_t first;
597         size_t second;
598
599         /* Determine fragment lengths */
600         first = ( vmdev->out_len - prod );
601         if ( first > len )
602                 first = len;
603         second = ( len - first );
604
605         /* Copy fragment(s) */
606         memcpy ( &vmdev->out->data[prod], data, first );
607         if ( second )
608                 memcpy ( &vmdev->out->data[0], ( data + first ), second );
609
610         return ( ( prod + len ) & ( vmdev->out_len - 1 ) );
611 }
612
613 /**
614  * Consume inbound ring buffer
615  *
616  * @v vmdev             VMBus device
617  * @v cons              Consumer index
618  * @v data              Data buffer, or NULL
619  * @v len               Length to consume
620  * @ret cons            New consumer index
621  */
622 static size_t vmbus_consume ( struct vmbus_device *vmdev, size_t cons,
623                               void *data, size_t len ) {
624         size_t first;
625         size_t second;
626
627         /* Determine fragment lengths */
628         first = ( vmdev->in_len - cons );
629         if ( first > len )
630                 first = len;
631         second = ( len - first );
632
633         /* Copy fragment(s) */
634         memcpy ( data, &vmdev->in->data[cons], first );
635         if ( second )
636                 memcpy ( ( data + first ), &vmdev->in->data[0], second );
637
638         return ( ( cons + len ) & ( vmdev->in_len - 1 ) );
639 }
640
641 /**
642  * Send packet via ring buffer
643  *
644  * @v vmdev             VMBus device
645  * @v header            Packet header
646  * @v data              Data
647  * @v len               Length of data
648  * @ret rc              Return status code
649  *
650  * Send a packet via the outbound ring buffer.  All fields in the
651  * packet header must be filled in, with the exception of the total
652  * packet length.
653  */
654 static int vmbus_send ( struct vmbus_device *vmdev,
655                         struct vmbus_packet_header *header,
656                         const void *data, size_t len ) {
657         struct hv_hypervisor *hv = vmdev->hv;
658         struct vmbus *vmbus = hv->vmbus;
659         static uint8_t padding[ 8 - 1 ];
660         struct vmbus_packet_footer footer;
661         size_t header_len;
662         size_t pad_len;
663         size_t footer_len;
664         size_t ring_len;
665         size_t cons;
666         size_t prod;
667         size_t old_prod;
668         size_t fill;
669
670         /* Sanity check */
671         assert ( vmdev->out != NULL );
672
673         /* Calculate lengths */
674         header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
675         pad_len = ( ( -len ) & ( 8 - 1 ) );
676         footer_len = sizeof ( footer );
677         ring_len = ( header_len + len + pad_len + footer_len );
678
679         /* Check that we have enough room in the outbound ring buffer */
680         cons = le32_to_cpu ( vmdev->out->cons );
681         prod = le32_to_cpu ( vmdev->out->prod );
682         old_prod = prod;
683         fill = ( ( prod - cons ) & ( vmdev->out_len - 1 ) );
684         if ( ( fill + ring_len ) >= vmdev->out_len ) {
685                 DBGC ( vmdev, "VMBUS %s ring buffer full\n", vmdev->dev.name );
686                 return -ENOBUFS;
687         }
688
689         /* Complete header */
690         header->qlen = cpu_to_le16 ( ( ring_len - footer_len ) / 8 );
691
692         /* Construct footer */
693         footer.reserved = 0;
694         footer.prod = vmdev->out->prod;
695
696         /* Copy packet to buffer */
697         DBGC2 ( vmdev, "VMBUS %s sending:\n", vmdev->dev.name );
698         DBGC2_HDA ( vmdev, prod, header, header_len );
699         prod = vmbus_produce ( vmdev, prod, header, header_len );
700         DBGC2_HDA ( vmdev, prod, data, len );
701         prod = vmbus_produce ( vmdev, prod, data, len );
702         prod = vmbus_produce ( vmdev, prod, padding, pad_len );
703         DBGC2_HDA ( vmdev, prod, &footer, sizeof ( footer ) );
704         prod = vmbus_produce ( vmdev, prod, &footer, sizeof ( footer ) );
705         assert ( ( ( prod - old_prod ) & ( vmdev->out_len - 1 ) ) == ring_len );
706
707         /* Update producer index */
708         wmb();
709         vmdev->out->prod = cpu_to_le32 ( prod );
710
711         /* Return if we do not need to signal the host.  This follows
712          * the logic of hv_need_to_signal() in the Linux driver.
713          */
714         mb();
715         if ( vmdev->out->intr_mask )
716                 return 0;
717         rmb();
718         cons = le32_to_cpu ( vmdev->out->cons );
719         if ( cons != old_prod )
720                 return 0;
721
722         /* Set channel bit in interrupt page */
723         hv_set_bit ( vmbus->intr->out, vmdev->channel );
724
725         /* Signal the host */
726         vmdev->signal ( vmdev );
727
728         return 0;
729 }
730
731 /**
732  * Send control packet via ring buffer
733  *
734  * @v vmdev             VMBus device
735  * @v xid               Transaction ID (or zero to not request completion)
736  * @v data              Data
737  * @v len               Length of data
738  * @ret rc              Return status code
739  *
740  * Send data using a VMBUS_DATA_INBAND packet.
741  */
742 int vmbus_send_control ( struct vmbus_device *vmdev, uint64_t xid,
743                          const void *data, size_t len ) {
744         struct vmbus_packet_header *header = vmdev->packet;
745
746         /* Construct header in packet buffer */
747         assert ( header != NULL );
748         header->type = cpu_to_le16 ( VMBUS_DATA_INBAND );
749         header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
750         header->flags = ( xid ?
751                           cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED ) : 0 );
752         header->xid = xid; /* Non-endian */
753
754         return vmbus_send ( vmdev, header, data, len );
755 }
756
757 /**
758  * Send data packet via ring buffer
759  *
760  * @v vmdev             VMBus device
761  * @v xid               Transaction ID
762  * @v data              Data
763  * @v len               Length of data
764  * @v iobuf             I/O buffer
765  * @ret rc              Return status code
766  *
767  * Send data using a VMBUS_DATA_GPA_DIRECT packet.  The caller is
768  * responsible for ensuring that the I/O buffer remains untouched
769  * until the corresponding completion has been received.
770  */
771 int vmbus_send_data ( struct vmbus_device *vmdev, uint64_t xid,
772                       const void *data, size_t len, struct io_buffer *iobuf ) {
773         physaddr_t addr = virt_to_phys ( iobuf->data );
774         unsigned int pfn_count = hv_pfn_count ( addr, iob_len ( iobuf ) );
775         struct {
776                 struct vmbus_gpa_direct_header gpa;
777                 struct vmbus_gpa_range range;
778                 uint64_t pfn[pfn_count];
779         } __attribute__ (( packed )) *header = vmdev->packet;
780         unsigned int i;
781
782         /* Sanity check */
783         assert ( header != NULL );
784         assert ( sizeof ( *header ) <= vmdev->mtu );
785
786         /* Construct header in packet buffer */
787         header->gpa.header.type = cpu_to_le16 ( VMBUS_DATA_GPA_DIRECT );
788         header->gpa.header.hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
789         header->gpa.header.flags = cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED );
790         header->gpa.header.xid = xid; /* Non-endian */
791         header->gpa.range_count = 1;
792         header->range.len = cpu_to_le32 ( iob_len ( iobuf ) );
793         header->range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
794         for ( i = 0 ; i < pfn_count ; i++ )
795                 header->pfn[i] = ( ( addr / PAGE_SIZE ) + i );
796
797         return vmbus_send ( vmdev, &header->gpa.header, data, len );
798 }
799
800 /**
801  * Send completion packet via ring buffer
802  *
803  * @v vmdev             VMBus device
804  * @v xid               Transaction ID
805  * @v data              Data
806  * @v len               Length of data
807  * @ret rc              Return status code
808  *
809  * Send data using a VMBUS_COMPLETION packet.
810  */
811 int vmbus_send_completion ( struct vmbus_device *vmdev, uint64_t xid,
812                             const void *data, size_t len ) {
813         struct vmbus_packet_header *header = vmdev->packet;
814
815         /* Construct header in packet buffer */
816         assert ( header != NULL );
817         header->type = cpu_to_le16 ( VMBUS_COMPLETION );
818         header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
819         header->flags = 0;
820         header->xid = xid; /* Non-endian */
821
822         return vmbus_send ( vmdev, header, data, len );
823 }
824
825 /**
826  * Send cancellation packet via ring buffer
827  *
828  * @v vmdev             VMBus device
829  * @v xid               Transaction ID
830  * @ret rc              Return status code
831  *
832  * Send data using a VMBUS_CANCELLATION packet.
833  */
834 int vmbus_send_cancellation ( struct vmbus_device *vmdev, uint64_t xid ) {
835         struct vmbus_packet_header *header = vmdev->packet;
836
837         /* Construct header in packet buffer */
838         assert ( header != NULL );
839         header->type = cpu_to_le16 ( VMBUS_CANCELLATION );
840         header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
841         header->flags = 0;
842         header->xid = xid; /* Non-endian */
843
844         return vmbus_send ( vmdev, header, NULL, 0 );
845 }
846
847 /**
848  * Get transfer page set from pageset ID
849  *
850  * @v vmdev             VMBus device
851  * @v pageset           Page set ID (in protocol byte order)
852  * @ret pages           Page set, or NULL if not found
853  */
854 static struct vmbus_xfer_pages * vmbus_xfer_pages ( struct vmbus_device *vmdev,
855                                                     uint16_t pageset ) {
856         struct vmbus_xfer_pages *pages;
857
858         /* Locate page set */
859         list_for_each_entry ( pages, &vmdev->pages, list ) {
860                 if ( pages->pageset == pageset )
861                         return pages;
862         }
863
864         DBGC ( vmdev, "VMBUS %s unrecognised page set ID %#04x\n",
865                vmdev->dev.name, le16_to_cpu ( pageset ) );
866         return NULL;
867 }
868
869 /**
870  * Construct I/O buffer list from transfer pages
871  *
872  * @v vmdev             VMBus device
873  * @v header            Transfer page header
874  * @v list              I/O buffer list to populate
875  * @ret rc              Return status code
876  */
877 static int vmbus_xfer_page_iobufs ( struct vmbus_device *vmdev,
878                                     struct vmbus_packet_header *header,
879                                     struct list_head *list ) {
880         struct vmbus_xfer_page_header *page_header =
881                 container_of ( header, struct vmbus_xfer_page_header, header );
882         struct vmbus_xfer_pages *pages;
883         struct io_buffer *iobuf;
884         struct io_buffer *tmp;
885         size_t len;
886         size_t offset;
887         unsigned int range_count;
888         unsigned int i;
889         int rc;
890
891         /* Sanity check */
892         assert ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) );
893
894         /* Locate page set */
895         pages = vmbus_xfer_pages ( vmdev, page_header->pageset );
896         if ( ! pages ) {
897                 rc = -ENOENT;
898                 goto err_pages;
899         }
900
901         /* Allocate and populate I/O buffers */
902         range_count = le32_to_cpu ( page_header->range_count );
903         for ( i = 0 ; i < range_count ; i++ ) {
904
905                 /* Parse header */
906                 len = le32_to_cpu ( page_header->range[i].len );
907                 offset = le32_to_cpu ( page_header->range[i].offset );
908
909                 /* Allocate I/O buffer */
910                 iobuf = alloc_iob ( len );
911                 if ( ! iobuf ) {
912                         DBGC ( vmdev, "VMBUS %s could not allocate %zd-byte "
913                                "I/O buffer\n", vmdev->dev.name, len );
914                         rc = -ENOMEM;
915                         goto err_alloc;
916                 }
917
918                 /* Add I/O buffer to list */
919                 list_add ( &iobuf->list, list );
920
921                 /* Populate I/O buffer */
922                 if ( ( rc = pages->op->copy ( pages, iob_put ( iobuf, len ),
923                                               offset, len ) ) != 0 ) {
924                         DBGC ( vmdev, "VMBUS %s could not populate I/O buffer "
925                                "range [%zd,%zd): %s\n",
926                                vmdev->dev.name, offset, len, strerror ( rc ) );
927                         goto err_copy;
928                 }
929         }
930
931         return 0;
932
933  err_copy:
934  err_alloc:
935         list_for_each_entry_safe ( iobuf, tmp, list, list ) {
936                 list_del ( &iobuf->list );
937                 free_iob ( iobuf );
938         }
939  err_pages:
940         return rc;
941 }
942
943 /**
944  * Poll ring buffer
945  *
946  * @v vmdev             VMBus device
947  * @ret rc              Return status code
948  */
949 int vmbus_poll ( struct vmbus_device *vmdev ) {
950         struct vmbus_packet_header *header = vmdev->packet;
951         struct list_head list;
952         void *data;
953         size_t header_len;
954         size_t len;
955         size_t footer_len;
956         size_t ring_len;
957         size_t cons;
958         size_t old_cons;
959         uint64_t xid;
960         int rc;
961
962         /* Sanity checks */
963         assert ( vmdev->packet != NULL );
964         assert ( vmdev->in != NULL );
965
966         /* Return immediately if buffer is empty */
967         if ( ! vmbus_has_data ( vmdev ) )
968                 return 0;
969         cons = le32_to_cpu ( vmdev->in->cons );
970         old_cons = cons;
971
972         /* Consume (start of) header */
973         cons = vmbus_consume ( vmdev, cons, header, sizeof ( *header ) );
974
975         /* Parse and sanity check header */
976         header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
977         if ( header_len < sizeof ( *header ) ) {
978                 DBGC ( vmdev, "VMBUS %s received underlength header (%zd "
979                        "bytes)\n", vmdev->dev.name, header_len );
980                 return -EINVAL;
981         }
982         len = ( ( le16_to_cpu ( header->qlen ) * 8 ) - header_len );
983         footer_len = sizeof ( struct vmbus_packet_footer );
984         ring_len = ( header_len + len + footer_len );
985         if ( ring_len > vmdev->mtu ) {
986                 DBGC ( vmdev, "VMBUS %s received overlength packet (%zd "
987                        "bytes)\n", vmdev->dev.name, ring_len );
988                 return -ERANGE;
989         }
990         xid = le64_to_cpu ( header->xid );
991
992         /* Consume remainder of packet */
993         cons = vmbus_consume ( vmdev, cons,
994                                ( ( ( void * ) header ) + sizeof ( *header ) ),
995                                ( ring_len - sizeof ( *header ) ) );
996         DBGC2 ( vmdev, "VMBUS %s received:\n", vmdev->dev.name );
997         DBGC2_HDA ( vmdev, old_cons, header, ring_len );
998         assert ( ( ( cons - old_cons ) & ( vmdev->in_len - 1 ) ) == ring_len );
999
1000         /* Allocate I/O buffers, if applicable */
1001         INIT_LIST_HEAD ( &list );
1002         if ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) ) {
1003                 if ( ( rc = vmbus_xfer_page_iobufs ( vmdev, header,
1004                                                      &list ) ) != 0 )
1005                         return rc;
1006         }
1007
1008         /* Update producer index */
1009         rmb();
1010         vmdev->in->cons = cpu_to_le32 ( cons );
1011
1012         /* Handle packet */
1013         data = ( ( ( void * ) header ) + header_len );
1014         switch ( header->type ) {
1015
1016         case cpu_to_le16 ( VMBUS_DATA_INBAND ) :
1017                 if ( ( rc = vmdev->op->recv_control ( vmdev, xid, data,
1018                                                       len ) ) != 0 ) {
1019                         DBGC ( vmdev, "VMBUS %s could not handle control "
1020                                "packet: %s\n",
1021                                vmdev->dev.name, strerror ( rc ) );
1022                         return rc;
1023                 }
1024                 break;
1025
1026         case cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) :
1027                 if ( ( rc = vmdev->op->recv_data ( vmdev, xid, data, len,
1028                                                    &list ) ) != 0 ) {
1029                         DBGC ( vmdev, "VMBUS %s could not handle data packet: "
1030                                "%s\n", vmdev->dev.name, strerror ( rc ) );
1031                         return rc;
1032                 }
1033                 break;
1034
1035         case cpu_to_le16 ( VMBUS_COMPLETION ) :
1036                 if ( ( rc = vmdev->op->recv_completion ( vmdev, xid, data,
1037                                                          len ) ) != 0 ) {
1038                         DBGC ( vmdev, "VMBUS %s could not handle completion: "
1039                                "%s\n", vmdev->dev.name, strerror ( rc ) );
1040                         return rc;
1041                 }
1042                 break;
1043
1044         case cpu_to_le16 ( VMBUS_CANCELLATION ) :
1045                 if ( ( rc = vmdev->op->recv_cancellation ( vmdev, xid ) ) != 0){
1046                         DBGC ( vmdev, "VMBUS %s could not handle cancellation: "
1047                                "%s\n", vmdev->dev.name, strerror ( rc ) );
1048                         return rc;
1049                 }
1050                 break;
1051
1052         default:
1053                 DBGC ( vmdev, "VMBUS %s unknown packet type %d\n",
1054                        vmdev->dev.name, le16_to_cpu ( header->type ) );
1055                 return -ENOTSUP;
1056         }
1057
1058         return 0;
1059 }
1060
1061 /**
1062  * Dump channel status (for debugging)
1063  *
1064  * @v vmdev             VMBus device
1065  */
1066 void vmbus_dump_channel ( struct vmbus_device *vmdev ) {
1067         size_t out_prod = le32_to_cpu ( vmdev->out->prod );
1068         size_t out_cons = le32_to_cpu ( vmdev->out->cons );
1069         size_t in_prod = le32_to_cpu ( vmdev->in->prod );
1070         size_t in_cons = le32_to_cpu ( vmdev->in->cons );
1071         size_t in_len;
1072         size_t first;
1073         size_t second;
1074
1075         /* Dump ring status */
1076         DBGC ( vmdev, "VMBUS %s out %03zx:%03zx%s in %03zx:%03zx%s\n",
1077                vmdev->dev.name, out_prod, out_cons,
1078                ( vmdev->out->intr_mask ? "(m)" : "" ), in_prod, in_cons,
1079                ( vmdev->in->intr_mask ? "(m)" : "" ) );
1080
1081         /* Dump inbound ring contents, if any */
1082         if ( in_prod != in_cons ) {
1083                 in_len = ( ( in_prod - in_cons ) &
1084                            ( vmdev->in_len - 1 ) );
1085                 first = ( vmdev->in_len - in_cons );
1086                 if ( first > in_len )
1087                         first = in_len;
1088                 second = ( in_len - first );
1089                 DBGC_HDA ( vmdev, in_cons, &vmdev->in->data[in_cons], first );
1090                 DBGC_HDA ( vmdev, 0, &vmdev->in->data[0], second );
1091         }
1092 }
1093
1094 /**
1095  * Find driver for VMBus device
1096  *
1097  * @v vmdev             VMBus device
1098  * @ret driver          Driver, or NULL
1099  */
1100 static struct vmbus_driver * vmbus_find_driver ( const union uuid *type ) {
1101         struct vmbus_driver *vmdrv;
1102
1103         for_each_table_entry ( vmdrv, VMBUS_DRIVERS ) {
1104                 if ( memcmp ( &vmdrv->type, type, sizeof ( *type ) ) == 0 )
1105                         return vmdrv;
1106         }
1107         return NULL;
1108 }
1109
1110 /**
1111  * Probe channels
1112  *
1113  * @v hv                Hyper-V hypervisor
1114  * @v parent            Parent device
1115  * @ret rc              Return status code
1116  */
1117 static int vmbus_probe_channels ( struct hv_hypervisor *hv,
1118                                   struct device *parent ) {
1119         struct vmbus *vmbus = hv->vmbus;
1120         const struct vmbus_message_header *header = &vmbus->message->header;
1121         const struct vmbus_offer_channel *offer = &vmbus->message->offer;
1122         const union uuid *type;
1123         struct vmbus_driver *driver;
1124         struct vmbus_device *vmdev;
1125         struct vmbus_device *tmp;
1126         unsigned int channel;
1127         int rc;
1128
1129         /* Post message */
1130         if ( ( rc = vmbus_post_empty_message ( hv, VMBUS_REQUEST_OFFERS ) ) !=0)
1131                 goto err_post_message;
1132
1133         /* Collect responses */
1134         while ( 1 ) {
1135
1136                 /* Wait for response */
1137                 if ( ( rc = vmbus_wait_for_message ( hv ) ) != 0 )
1138                         goto err_wait_for_message;
1139
1140                 /* Handle response */
1141                 if ( header->type == cpu_to_le32 ( VMBUS_OFFER_CHANNEL ) ) {
1142
1143                         /* Parse offer */
1144                         type = &offer->type;
1145                         channel = le32_to_cpu ( offer->channel );
1146                         DBGC2 ( vmbus, "VMBUS %p offer %d type %s",
1147                                 vmbus, channel, uuid_ntoa ( type ) );
1148                         if ( offer->monitored )
1149                                 DBGC2 ( vmbus, " monitor %d", offer->monitor );
1150                         DBGC2 ( vmbus, "\n" );
1151
1152                         /* Look for a driver */
1153                         driver = vmbus_find_driver ( type );
1154                         if ( ! driver ) {
1155                                 DBGC2 ( vmbus, "VMBUS %p has no driver for "
1156                                         "type %s\n", vmbus, uuid_ntoa ( type ));
1157                                 /* Not a fatal error */
1158                                 continue;
1159                         }
1160
1161                         /* Allocate and initialise device */
1162                         vmdev = zalloc ( sizeof ( *vmdev ) );
1163                         if ( ! vmdev ) {
1164                                 rc = -ENOMEM;
1165                                 goto err_alloc_vmdev;
1166                         }
1167                         snprintf ( vmdev->dev.name, sizeof ( vmdev->dev.name ),
1168                                    "vmbus:%02x", channel );
1169                         vmdev->dev.desc.bus_type = BUS_TYPE_HV;
1170                         INIT_LIST_HEAD ( &vmdev->dev.children );
1171                         list_add_tail ( &vmdev->dev.siblings,
1172                                         &parent->children );
1173                         vmdev->dev.parent = parent;
1174                         vmdev->hv = hv;
1175                         vmdev->channel = channel;
1176                         vmdev->monitor = offer->monitor;
1177                         vmdev->signal = ( offer->monitored ?
1178                                           vmbus_signal_monitor :
1179                                           vmbus_signal_event );
1180                         INIT_LIST_HEAD ( &vmdev->pages );
1181                         vmdev->driver = driver;
1182                         vmdev->dev.driver_name = driver->name;
1183                         DBGC ( vmdev, "VMBUS %s has driver \"%s\"\n",
1184                                vmdev->dev.name, vmdev->driver->name );
1185
1186                 } else if ( header->type ==
1187                             cpu_to_le32 ( VMBUS_ALL_OFFERS_DELIVERED ) ) {
1188
1189                         break;
1190
1191                 } else {
1192                         DBGC ( vmbus, "VMBUS %p unexpected offer response type "
1193                                "%d\n", vmbus, le32_to_cpu ( header->type ) );
1194                         rc = -EPROTO;
1195                         goto err_unexpected_offer;
1196                 }
1197         }
1198
1199         /* Probe all devices.  We do this only after completing
1200          * enumeration since devices will need to send and receive
1201          * VMBus messages.
1202          */
1203         list_for_each_entry ( vmdev, &parent->children, dev.siblings ) {
1204                 if ( ( rc = vmdev->driver->probe ( vmdev ) ) != 0 ) {
1205                         DBGC ( vmdev, "VMBUS %s could not probe: %s\n",
1206                                vmdev->dev.name, strerror ( rc ) );
1207                         goto err_probe;
1208                 }
1209         }
1210
1211         return 0;
1212
1213  err_probe:
1214         /* Remove driver from each device that was already probed */
1215         list_for_each_entry_continue_reverse ( vmdev, &parent->children,
1216                                                dev.siblings ) {
1217                 vmdev->driver->remove ( vmdev );
1218         }
1219  err_unexpected_offer:
1220  err_alloc_vmdev:
1221  err_wait_for_message:
1222         /* Free any devices allocated (but potentially not yet probed) */
1223         list_for_each_entry_safe ( vmdev, tmp, &parent->children,
1224                                    dev.siblings ) {
1225                 list_del ( &vmdev->dev.siblings );
1226                 free ( vmdev );
1227         }
1228  err_post_message:
1229         return rc;
1230 }
1231
1232 /**
1233  * Remove channels
1234  *
1235  * @v hv                Hyper-V hypervisor
1236  * @v parent            Parent device
1237  */
1238 static void vmbus_remove_channels ( struct hv_hypervisor *hv __unused,
1239                                     struct device *parent ) {
1240         struct vmbus_device *vmdev;
1241         struct vmbus_device *tmp;
1242
1243         /* Remove devices */
1244         list_for_each_entry_safe ( vmdev, tmp, &parent->children,
1245                                    dev.siblings ) {
1246                 vmdev->driver->remove ( vmdev );
1247                 assert ( list_empty ( &vmdev->dev.children ) );
1248                 assert ( vmdev->out == NULL );
1249                 assert ( vmdev->in == NULL );
1250                 assert ( vmdev->packet == NULL );
1251                 assert ( list_empty ( &vmdev->pages ) );
1252                 list_del ( &vmdev->dev.siblings );
1253                 free ( vmdev );
1254         }
1255 }
1256
1257 /**
1258  * Probe Hyper-V virtual machine bus
1259  *
1260  * @v hv                Hyper-V hypervisor
1261  * @v parent            Parent device
1262  * @ret rc              Return status code
1263  */
1264 int vmbus_probe ( struct hv_hypervisor *hv, struct device *parent ) {
1265         struct vmbus *vmbus;
1266         int rc;
1267
1268         /* Allocate and initialise structure */
1269         vmbus = zalloc ( sizeof ( *vmbus ) );
1270         if ( ! vmbus ) {
1271                 rc = -ENOMEM;
1272                 goto err_alloc;
1273         }
1274         hv->vmbus = vmbus;
1275
1276         /* Initialise message buffer pointer
1277          *
1278          * We use a pointer to the fixed-size Hyper-V received message
1279          * buffer.  This allows us to access fields within received
1280          * messages without first checking the message size: any
1281          * fields beyond the end of the message will read as zero.
1282          */
1283         vmbus->message = ( ( void * ) hv->message->received.data );
1284         assert ( sizeof ( *vmbus->message ) <=
1285                  sizeof ( hv->message->received.data ) );
1286
1287         /* Allocate interrupt and monitor pages */
1288         if ( ( rc = hv_alloc_pages ( hv, &vmbus->intr, &vmbus->monitor_in,
1289                                      &vmbus->monitor_out, NULL ) ) != 0 )
1290                 goto err_alloc_pages;
1291
1292         /* Enable message interrupt */
1293         hv_enable_sint ( hv, VMBUS_MESSAGE_SINT );
1294
1295         /* Negotiate protocol version */
1296         if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
1297                 goto err_negotiate_version;
1298
1299         /* Enumerate channels */
1300         if ( ( rc = vmbus_probe_channels ( hv, parent ) ) != 0 )
1301                 goto err_probe_channels;
1302
1303         return 0;
1304
1305         vmbus_remove_channels ( hv, parent );
1306  err_probe_channels:
1307         vmbus_unload ( hv );
1308  err_negotiate_version:
1309         hv_disable_sint ( hv, VMBUS_MESSAGE_SINT );
1310         hv_free_pages ( hv, vmbus->intr, vmbus->monitor_in, vmbus->monitor_out,
1311                         NULL );
1312  err_alloc_pages:
1313         free ( vmbus );
1314  err_alloc:
1315         return rc;
1316 }
1317
1318 /**
1319  * Remove Hyper-V virtual machine bus
1320  *
1321  * @v hv                Hyper-V hypervisor
1322  * @v parent            Parent device
1323  */
1324 void vmbus_remove ( struct hv_hypervisor *hv, struct device *parent ) {
1325         struct vmbus *vmbus = hv->vmbus;
1326
1327         vmbus_remove_channels ( hv, parent );
1328         vmbus_unload ( hv );
1329         hv_disable_sint ( hv, VMBUS_MESSAGE_SINT );
1330         hv_free_pages ( hv, vmbus->intr, vmbus->monitor_in, vmbus->monitor_out,
1331                         NULL );
1332         free ( vmbus );
1333 }