]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/hv/Channel.c
Staging: hv: Remove C99 comments
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / hv / Channel.c
CommitLineData
3e7ee490
HJ
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
5654e932 24#include <linux/kernel.h>
09d50ff8
GKH
25#include "include/osd.h"
26#include "include/logging.h"
3e7ee490
HJ
27
28#include "VmbusPrivate.h"
29
454f18a9 30/* Internal routines */
3e7ee490
HJ
31static int
32VmbusChannelCreateGpadlHeader(
454f18a9
BP
33 void * Kbuffer, /* must be phys and virt contiguous */
34 u32 Size, /* page-size multiple */
3e7ee490 35 VMBUS_CHANNEL_MSGINFO **msgInfo,
4d643114 36 u32 *MessageCount
3e7ee490
HJ
37 );
38
39static void
40DumpVmbusChannel(
41 VMBUS_CHANNEL *Channel
42 );
43
44
45static void
46VmbusChannelSetEvent(
47 VMBUS_CHANNEL *Channel
48 );
49
50
51#if 0
52static void
53DumpMonitorPage(
54 HV_MONITOR_PAGE *MonitorPage
55 )
56{
57 int i=0;
58 int j=0;
59
60 DPRINT_DBG(VMBUS, "monitorPage - %p, trigger state - %d", MonitorPage, MonitorPage->TriggerState);
61
62 for (i=0; i<4; i++)
63 {
64 DPRINT_DBG(VMBUS, "trigger group (%d) - %llx", i, MonitorPage->TriggerGroup[i].AsUINT64);
65 }
66
67 for (i=0; i<4; i++)
68 {
69 for (j=0; j<32; j++)
70 {
71 DPRINT_DBG(VMBUS, "latency (%d)(%d) - %llx", i, j, MonitorPage->Latency[i][j]);
72 }
73 }
74 for (i=0; i<4; i++)
75 {
76 for (j=0; j<32; j++)
77 {
4d643114 78 DPRINT_DBG(VMBUS, "param-conn id (%d)(%d) - %d", i, j, MonitorPage->Parameter[i][j].ConnectionId.Asu32);
3e7ee490
HJ
79 DPRINT_DBG(VMBUS, "param-flag (%d)(%d) - %d", i, j, MonitorPage->Parameter[i][j].FlagNumber);
80
81 }
82 }
83}
84#endif
85
86/*++
87
88Name:
89 VmbusChannelSetEvent()
90
91Description:
92 Trigger an event notification on the specified channel.
93
94--*/
95static void
96VmbusChannelSetEvent(
97 VMBUS_CHANNEL *Channel
98 )
99{
100 HV_MONITOR_PAGE *monitorPage;
101
102 DPRINT_ENTER(VMBUS);
103
104 if (Channel->OfferMsg.MonitorAllocated)
105 {
454f18a9 106 /* Each u32 represents 32 channels */
4d643114 107 BitSet((u32*)gVmbusConnection.SendInterruptPage + (Channel->OfferMsg.ChildRelId >> 5), Channel->OfferMsg.ChildRelId & 31);
3e7ee490
HJ
108
109 monitorPage = (HV_MONITOR_PAGE*)gVmbusConnection.MonitorPages;
454f18a9 110 monitorPage++; /* Get the child to parent monitor page */
3e7ee490 111
4d643114 112 BitSet((u32*) &monitorPage->TriggerGroup[Channel->MonitorGroup].Pending, Channel->MonitorBit);
3e7ee490
HJ
113 }
114 else
115 {
116 VmbusSetEvent(Channel->OfferMsg.ChildRelId);
117 }
118
119 DPRINT_EXIT(VMBUS);
120}
121
122#if 0
123static void
124VmbusChannelClearEvent(
125 VMBUS_CHANNEL *Channel
126 )
127{
128 HV_MONITOR_PAGE *monitorPage;
129
130 DPRINT_ENTER(VMBUS);
131
132 if (Channel->OfferMsg.MonitorAllocated)
133 {
454f18a9 134 /* Each u32 represents 32 channels */
4d643114 135 BitClear((u32*)gVmbusConnection.SendInterruptPage + (Channel->OfferMsg.ChildRelId >> 5), Channel->OfferMsg.ChildRelId & 31);
3e7ee490
HJ
136
137 monitorPage = (HV_MONITOR_PAGE*)gVmbusConnection.MonitorPages;
454f18a9 138 monitorPage++; /* Get the child to parent monitor page */
3e7ee490 139
4d643114 140 BitClear((u32*) &monitorPage->TriggerGroup[Channel->MonitorGroup].Pending, Channel->MonitorBit);
3e7ee490
HJ
141 }
142
143 DPRINT_EXIT(VMBUS);
144}
145
146#endif
147/*++;
148
149Name:
150 VmbusChannelGetDebugInfo()
151
152Description:
153 Retrieve various channel debug info
154
155--*/
156void
157VmbusChannelGetDebugInfo(
158 VMBUS_CHANNEL *Channel,
159 VMBUS_CHANNEL_DEBUG_INFO *DebugInfo
160 )
161{
162 HV_MONITOR_PAGE *monitorPage;
5654e932
GKH
163 u8 monitorGroup = (u8)Channel->OfferMsg.MonitorId / 32;
164 u8 monitorOffset = (u8)Channel->OfferMsg.MonitorId % 32;
454f18a9 165 /* u32 monitorBit = 1 << monitorOffset; */
3e7ee490
HJ
166
167 DebugInfo->RelId = Channel->OfferMsg.ChildRelId;
168 DebugInfo->State = Channel->State;
169 memcpy(&DebugInfo->InterfaceType, &Channel->OfferMsg.Offer.InterfaceType, sizeof(GUID));
170 memcpy(&DebugInfo->InterfaceInstance, &Channel->OfferMsg.Offer.InterfaceInstance, sizeof(GUID));
171
172 monitorPage = (HV_MONITOR_PAGE*)gVmbusConnection.MonitorPages;
173
174 DebugInfo->MonitorId = Channel->OfferMsg.MonitorId;
175
176 DebugInfo->ServerMonitorPending = monitorPage->TriggerGroup[monitorGroup].Pending;
177 DebugInfo->ServerMonitorLatency = monitorPage->Latency[monitorGroup][ monitorOffset];
178 DebugInfo->ServerMonitorConnectionId = monitorPage->Parameter[monitorGroup][ monitorOffset].ConnectionId.u.Id;
179
180 monitorPage++;
181
182 DebugInfo->ClientMonitorPending = monitorPage->TriggerGroup[monitorGroup].Pending;
183 DebugInfo->ClientMonitorLatency = monitorPage->Latency[monitorGroup][ monitorOffset];
184 DebugInfo->ClientMonitorConnectionId = monitorPage->Parameter[monitorGroup][ monitorOffset].ConnectionId.u.Id;
185
186 RingBufferGetDebugInfo(&Channel->Inbound, &DebugInfo->Inbound);
187 RingBufferGetDebugInfo(&Channel->Outbound, &DebugInfo->Outbound);
188}
189
190
191/*++;
192
193Name:
194 VmbusChannelOpen()
195
196Description:
197 Open the specified channel.
198
199--*/
200int
201VmbusChannelOpen(
202 VMBUS_CHANNEL *NewChannel,
4d643114
GKH
203 u32 SendRingBufferSize,
204 u32 RecvRingBufferSize,
8282c400 205 void * UserData,
4d643114 206 u32 UserDataLen,
3e7ee490 207 PFN_CHANNEL_CALLBACK pfnOnChannelCallback,
8282c400 208 void * Context
3e7ee490
HJ
209 )
210{
211 int ret=0;
212 VMBUS_CHANNEL_OPEN_CHANNEL* openMsg;
213 VMBUS_CHANNEL_MSGINFO* openInfo;
214 void *in, *out;
dd0813b6 215 unsigned long flags;
3e7ee490
HJ
216
217 DPRINT_ENTER(VMBUS);
218
454f18a9 219 /* Aligned to page size */
3e7ee490
HJ
220 ASSERT(!(SendRingBufferSize & (PAGE_SIZE -1)));
221 ASSERT(!(RecvRingBufferSize & (PAGE_SIZE -1)));
222
223 NewChannel->OnChannelCallback = pfnOnChannelCallback;
224 NewChannel->ChannelCallbackContext = Context;
225
454f18a9 226 /* Allocate the ring buffer */
3e7ee490 227 out = PageAlloc((SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT);
454f18a9 228 /* out = kzalloc(sendRingBufferSize + recvRingBufferSize, GFP_KERNEL); */
3e7ee490 229 ASSERT(out);
c4b0bc94 230 ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0);
3e7ee490 231
c4b0bc94 232 in = (void*)((unsigned long)out + SendRingBufferSize);
3e7ee490
HJ
233
234 NewChannel->RingBufferPages = out;
235 NewChannel->RingBufferPageCount = (SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT;
236
237 RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize);
238
239 RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize);
240
454f18a9 241 /* Establish the gpadl for the ring buffer */
3e7ee490
HJ
242 DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...", NewChannel);
243
244 NewChannel->RingBufferGpadlHandle = 0;
245
246 ret = VmbusChannelEstablishGpadl(NewChannel,
247 NewChannel->Outbound.RingBuffer,
248 SendRingBufferSize + RecvRingBufferSize,
249 &NewChannel->RingBufferGpadlHandle);
250
251 DPRINT_DBG(VMBUS, "channel %p <relid %d gpadl 0x%x send ring %p size %d recv ring %p size %d, downstreamoffset %d>",
252 NewChannel,
253 NewChannel->OfferMsg.ChildRelId,
254 NewChannel->RingBufferGpadlHandle,
255 NewChannel->Outbound.RingBuffer,
256 NewChannel->Outbound.RingSize,
257 NewChannel->Inbound.RingBuffer,
258 NewChannel->Inbound.RingSize,
259 SendRingBufferSize);
260
454f18a9 261 /* Create and init the channel open message */
e40d37cc 262 openInfo = kmalloc(sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_OPEN_CHANNEL), GFP_KERNEL);
3e7ee490
HJ
263 ASSERT(openInfo != NULL);
264
265 openInfo->WaitEvent = WaitEventCreate();
266
267 openMsg = (VMBUS_CHANNEL_OPEN_CHANNEL*)openInfo->Msg;
268 openMsg->Header.MessageType = ChannelMessageOpenChannel;
454f18a9 269 openMsg->OpenId = NewChannel->OfferMsg.ChildRelId; /* FIXME */
3e7ee490
HJ
270 openMsg->ChildRelId = NewChannel->OfferMsg.ChildRelId;
271 openMsg->RingBufferGpadlHandle = NewChannel->RingBufferGpadlHandle;
272 ASSERT(openMsg->RingBufferGpadlHandle);
273 openMsg->DownstreamRingBufferPageOffset = SendRingBufferSize >> PAGE_SHIFT;
454f18a9 274 openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */
3e7ee490
HJ
275
276 ASSERT(UserDataLen <= MAX_USER_DEFINED_BYTES);
277 if (UserDataLen)
278 {
279 memcpy(openMsg->UserData, UserData, UserDataLen);
280 }
281
dd0813b6 282 spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490 283 INSERT_TAIL_LIST(&gVmbusConnection.ChannelMsgList, &openInfo->MsgListEntry);
dd0813b6 284 spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490
HJ
285
286 DPRINT_DBG(VMBUS, "Sending channel open msg...");
287
288 ret = VmbusPostMessage(openMsg, sizeof(VMBUS_CHANNEL_OPEN_CHANNEL));
289 if (ret != 0)
290 {
291 DPRINT_ERR(VMBUS, "unable to open channel - %d", ret);
292 goto Cleanup;
293 }
294
454f18a9 295 /* FIXME: Need to time-out here */
3e7ee490
HJ
296 WaitEventWait(openInfo->WaitEvent);
297
298 if (openInfo->Response.OpenResult.Status == 0)
299 {
300 DPRINT_INFO(VMBUS, "channel <%p> open success!!", NewChannel);
301 }
302 else
303 {
304 DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!", NewChannel, openInfo->Response.OpenResult.Status);
305 }
306
307Cleanup:
dd0813b6 308 spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490 309 REMOVE_ENTRY_LIST(&openInfo->MsgListEntry);
dd0813b6 310 spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490
HJ
311
312 WaitEventClose(openInfo->WaitEvent);
8c69f52a 313 kfree(openInfo);
3e7ee490
HJ
314
315 DPRINT_EXIT(VMBUS);
316
317 return 0;
318}
319
320/*++;
321
322Name:
323 DumpGpadlBody()
324
325Description:
326 Dump the gpadl body message to the console for debugging purposes.
327
328--*/
329static void DumpGpadlBody(
330 VMBUS_CHANNEL_GPADL_BODY *Gpadl,
4d643114 331 u32 Len)
3e7ee490
HJ
332{
333 int i=0;
334 int pfnCount=0;
335
59471438 336 pfnCount = (Len - sizeof(VMBUS_CHANNEL_GPADL_BODY))/ sizeof(u64);
3e7ee490
HJ
337 DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", Len, pfnCount);
338
339 for (i=0; i< pfnCount; i++)
340 {
341 DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu", i, Gpadl->Pfn[i]);
342 }
343}
344
345
346/*++;
347
348Name:
349 DumpGpadlHeader()
350
351Description:
352 Dump the gpadl header message to the console for debugging purposes.
353
354--*/
355static void DumpGpadlHeader(
356 VMBUS_CHANNEL_GPADL_HEADER *Gpadl
357 )
358{
359 int i=0,j=0;
360 int pageCount=0;
361
362
363 DPRINT_DBG(VMBUS, "gpadl header - relid %d, range count %d, range buflen %d",
364 Gpadl->ChildRelId,
365 Gpadl->RangeCount,
366 Gpadl->RangeBufLen);
367 for (i=0; i< Gpadl->RangeCount; i++)
368 {
369 pageCount = Gpadl->Range[i].ByteCount >> PAGE_SHIFT;
370 pageCount = (pageCount > 26)? 26 : pageCount;
371
372 DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d page count %d",
373 i, Gpadl->Range[i].ByteCount, Gpadl->Range[i].ByteOffset, pageCount);
374
375 for (j=0; j< pageCount; j++)
376 {
377 DPRINT_DBG(VMBUS, "%d) pfn %llu", j, Gpadl->Range[i].PfnArray[j]);
378 }
379 }
380}
381
382/*++;
383
384Name:
385 VmbusChannelCreateGpadlHeader()
386
387Description:
388 Creates a gpadl for the specified buffer
389
390--*/
391static int
392VmbusChannelCreateGpadlHeader(
454f18a9
BP
393 void * Kbuffer, /* from kmalloc() */
394 u32 Size, /* page-size multiple */
3e7ee490 395 VMBUS_CHANNEL_MSGINFO **MsgInfo,
4d643114 396 u32 *MessageCount)
3e7ee490
HJ
397{
398 int i;
399 int pageCount;
400 unsigned long long pfn;
401 VMBUS_CHANNEL_GPADL_HEADER* gpaHeader;
402 VMBUS_CHANNEL_GPADL_BODY* gpadlBody;
403 VMBUS_CHANNEL_MSGINFO* msgHeader;
404 VMBUS_CHANNEL_MSGINFO* msgBody;
4d643114 405 u32 msgSize;
3e7ee490
HJ
406
407 int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize;
408
454f18a9 409 /* ASSERT( (kbuffer & (PAGE_SIZE-1)) == 0); */
3e7ee490
HJ
410 ASSERT( (Size & (PAGE_SIZE-1)) == 0);
411
412 pageCount = Size >> PAGE_SHIFT;
413 pfn = GetPhysicalAddress(Kbuffer) >> PAGE_SHIFT;
414
454f18a9 415 /* do we need a gpadl body msg */
3e7ee490 416 pfnSize = MAX_SIZE_CHANNEL_MESSAGE - sizeof(VMBUS_CHANNEL_GPADL_HEADER) - sizeof(GPA_RANGE);
59471438 417 pfnCount = pfnSize / sizeof(u64);
3e7ee490 418
454f18a9 419 if (pageCount > pfnCount) /* we need a gpadl body */
3e7ee490 420 {
454f18a9 421 /* fill in the header */
59471438 422 msgSize = sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_GPADL_HEADER) + sizeof(GPA_RANGE) + pfnCount*sizeof(u64);
e276a3a5 423 msgHeader = kzalloc(msgSize, GFP_KERNEL);
3e7ee490
HJ
424
425 INITIALIZE_LIST_HEAD(&msgHeader->SubMsgList);
426 msgHeader->MessageSize=msgSize;
427
428 gpaHeader = (VMBUS_CHANNEL_GPADL_HEADER*)msgHeader->Msg;
429 gpaHeader->RangeCount = 1;
59471438 430 gpaHeader->RangeBufLen = sizeof(GPA_RANGE) + pageCount*sizeof(u64);
3e7ee490
HJ
431 gpaHeader->Range[0].ByteOffset = 0;
432 gpaHeader->Range[0].ByteCount = Size;
433 for (i=0; i<pfnCount; i++)
434 {
435 gpaHeader->Range[0].PfnArray[i] = pfn+i;
436 }
437 *MsgInfo = msgHeader;
438 *MessageCount = 1;
439
440 pfnSum = pfnCount;
441 pfnLeft = pageCount - pfnCount;
442
454f18a9 443 /* how many pfns can we fit */
3e7ee490 444 pfnSize = MAX_SIZE_CHANNEL_MESSAGE - sizeof(VMBUS_CHANNEL_GPADL_BODY);
59471438 445 pfnCount = pfnSize / sizeof(u64);
3e7ee490 446
454f18a9 447 /* fill in the body */
3e7ee490
HJ
448 while (pfnLeft)
449 {
450 if (pfnLeft > pfnCount)
451 {
452 pfnCurr = pfnCount;
453 }
454 else
455 {
456 pfnCurr = pfnLeft;
457 }
458
59471438 459 msgSize = sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_GPADL_BODY) + pfnCurr*sizeof(u64);
e276a3a5 460 msgBody = kzalloc(msgSize, GFP_KERNEL);
3e7ee490
HJ
461 ASSERT(msgBody);
462 msgBody->MessageSize = msgSize;
463 (*MessageCount)++;
464 gpadlBody = (VMBUS_CHANNEL_GPADL_BODY*)msgBody->Msg;
465
454f18a9
BP
466 /* FIXME: Gpadl is u32 and we are using a pointer which could be 64-bit */
467 /* gpadlBody->Gpadl = kbuffer; */
3e7ee490
HJ
468 for (i=0; i<pfnCurr; i++)
469 {
470 gpadlBody->Pfn[i] = pfn + pfnSum + i;
471 }
472
454f18a9 473 /* add to msg header */
3e7ee490
HJ
474 INSERT_TAIL_LIST(&msgHeader->SubMsgList, &msgBody->MsgListEntry);
475 pfnSum += pfnCurr;
476 pfnLeft -= pfnCurr;
477 }
478 }
479 else
480 {
454f18a9 481 /* everything fits in a header */
59471438 482 msgSize = sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_GPADL_HEADER) + sizeof(GPA_RANGE) + pageCount*sizeof(u64);
e276a3a5 483 msgHeader = kzalloc(msgSize, GFP_KERNEL);
3e7ee490
HJ
484 msgHeader->MessageSize=msgSize;
485
486 gpaHeader = (VMBUS_CHANNEL_GPADL_HEADER*)msgHeader->Msg;
487 gpaHeader->RangeCount = 1;
59471438 488 gpaHeader->RangeBufLen = sizeof(GPA_RANGE) + pageCount*sizeof(u64);
3e7ee490
HJ
489 gpaHeader->Range[0].ByteOffset = 0;
490 gpaHeader->Range[0].ByteCount = Size;
491 for (i=0; i<pageCount; i++)
492 {
493 gpaHeader->Range[0].PfnArray[i] = pfn+i;
494 }
495
496 *MsgInfo = msgHeader;
497 *MessageCount = 1;
498 }
499
500 return 0;
501}
502
503
504/*++;
505
506Name:
507 VmbusChannelEstablishGpadl()
508
509Description:
510 Estabish a GPADL for the specified buffer
511
512--*/
513int
514VmbusChannelEstablishGpadl(
515 VMBUS_CHANNEL *Channel,
454f18a9
BP
516 void * Kbuffer, /* from kmalloc() */
517 u32 Size, /* page-size multiple */
4d643114 518 u32 *GpadlHandle
3e7ee490
HJ
519 )
520{
521 int ret=0;
522 VMBUS_CHANNEL_GPADL_HEADER* gpadlMsg;
523 VMBUS_CHANNEL_GPADL_BODY* gpadlBody;
454f18a9 524 /* VMBUS_CHANNEL_GPADL_CREATED* gpadlCreated; */
3e7ee490
HJ
525
526 VMBUS_CHANNEL_MSGINFO *msgInfo;
527 VMBUS_CHANNEL_MSGINFO *subMsgInfo;
528
4d643114 529 u32 msgCount;
3e7ee490
HJ
530 LIST_ENTRY* anchor;
531 LIST_ENTRY* curr;
4d643114 532 u32 nextGpadlHandle;
dd0813b6 533 unsigned long flags;
3e7ee490
HJ
534
535 DPRINT_ENTER(VMBUS);
536
537 nextGpadlHandle = gVmbusConnection.NextGpadlHandle;
538 InterlockedIncrement((int*)&gVmbusConnection.NextGpadlHandle);
539
540 VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount);
541 ASSERT(msgInfo != NULL);
542 ASSERT(msgCount >0);
543
544 msgInfo->WaitEvent = WaitEventCreate();
545 gpadlMsg = (VMBUS_CHANNEL_GPADL_HEADER*)msgInfo->Msg;
546 gpadlMsg->Header.MessageType = ChannelMessageGpadlHeader;
547 gpadlMsg->ChildRelId = Channel->OfferMsg.ChildRelId;
548 gpadlMsg->Gpadl = nextGpadlHandle;
549
550 DumpGpadlHeader(gpadlMsg);
551
dd0813b6 552 spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490 553 INSERT_TAIL_LIST(&gVmbusConnection.ChannelMsgList, &msgInfo->MsgListEntry);
dd0813b6 554 spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490
HJ
555
556 DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d", Kbuffer, Size, msgCount);
557
226408a4 558 DPRINT_DBG(VMBUS, "Sending GPADL Header - len %ld", msgInfo->MessageSize - sizeof(VMBUS_CHANNEL_MSGINFO));
3e7ee490
HJ
559
560 ret = VmbusPostMessage(gpadlMsg, msgInfo->MessageSize - sizeof(VMBUS_CHANNEL_MSGINFO));
561 if (ret != 0)
562 {
563 DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret);
564 goto Cleanup;
565 }
566
567 if (msgCount>1)
568 {
569 ITERATE_LIST_ENTRIES(anchor, curr, &msgInfo->SubMsgList)
570 {
571 subMsgInfo = (VMBUS_CHANNEL_MSGINFO*) curr;
572 gpadlBody = (VMBUS_CHANNEL_GPADL_BODY*)subMsgInfo->Msg;
573
574 gpadlBody->Header.MessageType = ChannelMessageGpadlBody;
575 gpadlBody->Gpadl = nextGpadlHandle;
576
226408a4 577 DPRINT_DBG(VMBUS, "Sending GPADL Body - len %ld", subMsgInfo->MessageSize - sizeof(VMBUS_CHANNEL_MSGINFO));
3e7ee490
HJ
578
579 DumpGpadlBody(gpadlBody, subMsgInfo->MessageSize - sizeof(VMBUS_CHANNEL_MSGINFO));
580 ret = VmbusPostMessage(gpadlBody, subMsgInfo->MessageSize - sizeof(VMBUS_CHANNEL_MSGINFO));
581 ASSERT(ret == 0);
582 }
583 }
584 WaitEventWait(msgInfo->WaitEvent);
585
454f18a9 586 /* At this point, we received the gpadl created msg */
3e7ee490
HJ
587 DPRINT_DBG(VMBUS, "Received GPADL created (relid %d, status %d handle %x)",
588 Channel->OfferMsg.ChildRelId,
589 msgInfo->Response.GpadlCreated.CreationStatus,
590 gpadlMsg->Gpadl);
591
592 *GpadlHandle = gpadlMsg->Gpadl;
593
594Cleanup:
dd0813b6 595 spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490 596 REMOVE_ENTRY_LIST(&msgInfo->MsgListEntry);
dd0813b6 597 spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490
HJ
598
599 WaitEventClose(msgInfo->WaitEvent);
8c69f52a 600 kfree(msgInfo);
3e7ee490
HJ
601
602 DPRINT_EXIT(VMBUS);
603
604 return ret;
605}
606
607
608
609/*++;
610
611Name:
612 VmbusChannelTeardownGpadl()
613
614Description:
615 Teardown the specified GPADL handle
616
617--*/
618int
619VmbusChannelTeardownGpadl(
620 VMBUS_CHANNEL *Channel,
4d643114 621 u32 GpadlHandle
3e7ee490
HJ
622 )
623{
624 int ret=0;
625 VMBUS_CHANNEL_GPADL_TEARDOWN *msg;
626 VMBUS_CHANNEL_MSGINFO* info;
dd0813b6 627 unsigned long flags;
3e7ee490
HJ
628
629 DPRINT_ENTER(VMBUS);
630
631 ASSERT(GpadlHandle != 0);
632
e40d37cc 633 info = kmalloc(sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_GPADL_TEARDOWN), GFP_KERNEL);
3e7ee490
HJ
634 ASSERT(info != NULL);
635
636 info->WaitEvent = WaitEventCreate();
637
638 msg = (VMBUS_CHANNEL_GPADL_TEARDOWN*)info->Msg;
639
640 msg->Header.MessageType = ChannelMessageGpadlTeardown;
641 msg->ChildRelId = Channel->OfferMsg.ChildRelId;
642 msg->Gpadl = GpadlHandle;
643
dd0813b6 644 spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490 645 INSERT_TAIL_LIST(&gVmbusConnection.ChannelMsgList, &info->MsgListEntry);
dd0813b6 646 spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490
HJ
647
648 ret = VmbusPostMessage(msg, sizeof(VMBUS_CHANNEL_GPADL_TEARDOWN));
649 if (ret != 0)
650 {
454f18a9 651 /* TODO: */
3e7ee490
HJ
652 }
653
654 WaitEventWait(info->WaitEvent);
655
454f18a9 656 /* Received a torndown response */
dd0813b6 657 spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490 658 REMOVE_ENTRY_LIST(&info->MsgListEntry);
dd0813b6 659 spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
3e7ee490
HJ
660
661 WaitEventClose(info->WaitEvent);
8c69f52a 662 kfree(info);
3e7ee490
HJ
663
664 DPRINT_EXIT(VMBUS);
665
666 return ret;
667}
668
669
670/*++
671
672Name:
673 VmbusChannelClose()
674
675Description:
676 Close the specified channel
677
678--*/
e20f683b 679void
3e7ee490
HJ
680VmbusChannelClose(
681 VMBUS_CHANNEL *Channel
682 )
683{
684 int ret=0;
685 VMBUS_CHANNEL_CLOSE_CHANNEL* msg;
686 VMBUS_CHANNEL_MSGINFO* info;
0f5e44ca 687 unsigned long flags;
3e7ee490
HJ
688
689 DPRINT_ENTER(VMBUS);
690
454f18a9 691 /* Stop callback and cancel the timer asap */
3e7ee490
HJ
692 Channel->OnChannelCallback = NULL;
693 TimerStop(Channel->PollTimer);
694
454f18a9 695 /* Send a closing message */
e40d37cc 696 info = kmalloc(sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_CLOSE_CHANNEL), GFP_KERNEL);
3e7ee490
HJ
697 ASSERT(info != NULL);
698
454f18a9 699 /* info->waitEvent = WaitEventCreate(); */
3e7ee490
HJ
700
701 msg = (VMBUS_CHANNEL_CLOSE_CHANNEL*)info->Msg;
702 msg->Header.MessageType = ChannelMessageCloseChannel;
703 msg->ChildRelId = Channel->OfferMsg.ChildRelId;
704
705 ret = VmbusPostMessage(msg, sizeof(VMBUS_CHANNEL_CLOSE_CHANNEL));
706 if (ret != 0)
707 {
454f18a9 708 /* TODO: */
3e7ee490
HJ
709 }
710
454f18a9 711 /* Tear down the gpadl for the channel's ring buffer */
3e7ee490
HJ
712 if (Channel->RingBufferGpadlHandle)
713 {
714 VmbusChannelTeardownGpadl(Channel, Channel->RingBufferGpadlHandle);
715 }
716
454f18a9 717 /* TODO: Send a msg to release the childRelId */
3e7ee490 718
454f18a9 719 /* Cleanup the ring buffers for this channel */
3e7ee490
HJ
720 RingBufferCleanup(&Channel->Outbound);
721 RingBufferCleanup(&Channel->Inbound);
722
723 PageFree(Channel->RingBufferPages, Channel->RingBufferPageCount);
724
8c69f52a 725 kfree(info);
3e7ee490 726
454f18a9
BP
727
728 /*
729 * If we are closing the channel during an error path in
730 * opening the channel, don't free the channel since the
731 * caller will free the channel
732 */
733
3e7ee490
HJ
734 if (Channel->State == CHANNEL_OPEN_STATE)
735 {
0f5e44ca 736 spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
3e7ee490 737 REMOVE_ENTRY_LIST(&Channel->ListEntry);
0f5e44ca 738 spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
3e7ee490
HJ
739
740 FreeVmbusChannel(Channel);
741 }
742
743 DPRINT_EXIT(VMBUS);
744}
745
746
747/*++
748
749Name:
750 VmbusChannelSendPacket()
751
752Description:
753 Send the specified buffer on the given channel
754
755--*/
756int
757VmbusChannelSendPacket(
758 VMBUS_CHANNEL *Channel,
8282c400 759 const void * Buffer,
4d643114 760 u32 BufferLen,
59471438 761 u64 RequestId,
3e7ee490 762 VMBUS_PACKET_TYPE Type,
4d643114 763 u32 Flags
3e7ee490
HJ
764)
765{
766 int ret=0;
767 VMPACKET_DESCRIPTOR desc;
4d643114 768 u32 packetLen = sizeof(VMPACKET_DESCRIPTOR) + BufferLen;
59471438 769 u32 packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));
3e7ee490 770 SG_BUFFER_LIST bufferList[3];
59471438 771 u64 alignedData=0;
3e7ee490
HJ
772
773 DPRINT_ENTER(VMBUS);
774 DPRINT_DBG(VMBUS, "channel %p buffer %p len %d", Channel, Buffer, BufferLen);
775
776 DumpVmbusChannel(Channel);
777
59471438 778 ASSERT((packetLenAligned - packetLen) < sizeof(u64));
3e7ee490 779
454f18a9
BP
780 /* Setup the descriptor */
781 desc.Type = Type; /* VmbusPacketTypeDataInBand; */
782 desc.Flags = Flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
783 desc.DataOffset8 = sizeof(VMPACKET_DESCRIPTOR) >> 3; /* in 8-bytes granularity */
784 desc.Length8 = (u16)(packetLenAligned >> 3);
785 desc.TransactionId = RequestId;
3e7ee490
HJ
786
787 bufferList[0].Data = &desc;
788 bufferList[0].Length = sizeof(VMPACKET_DESCRIPTOR);
789
790 bufferList[1].Data = Buffer;
791 bufferList[1].Length = BufferLen;
792
793 bufferList[2].Data = &alignedData;
794 bufferList[2].Length = packetLenAligned - packetLen;
795
796 ret = RingBufferWrite(
797 &Channel->Outbound,
798 bufferList,
799 3);
800
454f18a9 801 /* TODO: We should determine if this is optional */
3e7ee490
HJ
802 if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
803 {
804 VmbusChannelSetEvent(Channel);
805 }
806
807 DPRINT_EXIT(VMBUS);
808
809 return ret;
810}
811
812
813/*++
814
815Name:
816 VmbusChannelSendPacketPageBuffer()
817
818Description:
819 Send a range of single-page buffer packets using a GPADL Direct packet type.
820
821--*/
822int
823VmbusChannelSendPacketPageBuffer(
824 VMBUS_CHANNEL *Channel,
825 PAGE_BUFFER PageBuffers[],
4d643114 826 u32 PageCount,
8282c400 827 void * Buffer,
4d643114 828 u32 BufferLen,
59471438 829 u64 RequestId
3e7ee490
HJ
830)
831{
832 int ret=0;
833 int i=0;
834 VMBUS_CHANNEL_PACKET_PAGE_BUFFER desc;
4d643114
GKH
835 u32 descSize;
836 u32 packetLen;
837 u32 packetLenAligned;
3e7ee490 838 SG_BUFFER_LIST bufferList[3];
59471438 839 u64 alignedData=0;
3e7ee490
HJ
840
841 DPRINT_ENTER(VMBUS);
842
843 ASSERT(PageCount <= MAX_PAGE_BUFFER_COUNT);
844
845 DumpVmbusChannel(Channel);
846
454f18a9 847 /* Adjust the size down since VMBUS_CHANNEL_PACKET_PAGE_BUFFER is the largest size we support */
3e7ee490
HJ
848 descSize = sizeof(VMBUS_CHANNEL_PACKET_PAGE_BUFFER) - ((MAX_PAGE_BUFFER_COUNT - PageCount)*sizeof(PAGE_BUFFER));
849 packetLen = descSize + BufferLen;
59471438 850 packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));
3e7ee490 851
59471438 852 ASSERT((packetLenAligned - packetLen) < sizeof(u64));
3e7ee490 853
454f18a9 854 /* Setup the descriptor */
3e7ee490
HJ
855 desc.Type = VmbusPacketTypeDataUsingGpaDirect;
856 desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
454f18a9
BP
857 desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */
858 desc.Length8 = (u16)(packetLenAligned >> 3);
859 desc.TransactionId = RequestId;
3e7ee490
HJ
860 desc.RangeCount = PageCount;
861
862 for (i=0; i<PageCount; i++)
863 {
864 desc.Range[i].Length = PageBuffers[i].Length;
865 desc.Range[i].Offset = PageBuffers[i].Offset;
866 desc.Range[i].Pfn = PageBuffers[i].Pfn;
867 }
868
869 bufferList[0].Data = &desc;
870 bufferList[0].Length = descSize;
871
872 bufferList[1].Data = Buffer;
873 bufferList[1].Length = BufferLen;
874
875 bufferList[2].Data = &alignedData;
876 bufferList[2].Length = packetLenAligned - packetLen;
877
878 ret = RingBufferWrite(
879 &Channel->Outbound,
880 bufferList,
881 3);
882
454f18a9 883 /* TODO: We should determine if this is optional */
3e7ee490
HJ
884 if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
885 {
886 VmbusChannelSetEvent(Channel);
887 }
888
889 DPRINT_EXIT(VMBUS);
890
891 return ret;
892}
893
894
895
896/*++
897
898Name:
899 VmbusChannelSendPacketMultiPageBuffer()
900
901Description:
902 Send a multi-page buffer packet using a GPADL Direct packet type.
903
904--*/
905int
906VmbusChannelSendPacketMultiPageBuffer(
907 VMBUS_CHANNEL *Channel,
908 MULTIPAGE_BUFFER *MultiPageBuffer,
8282c400 909 void * Buffer,
4d643114 910 u32 BufferLen,
59471438 911 u64 RequestId
3e7ee490
HJ
912)
913{
914 int ret=0;
915 VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER desc;
4d643114
GKH
916 u32 descSize;
917 u32 packetLen;
918 u32 packetLenAligned;
3e7ee490 919 SG_BUFFER_LIST bufferList[3];
59471438 920 u64 alignedData=0;
4d643114 921 u32 PfnCount = NUM_PAGES_SPANNED(MultiPageBuffer->Offset, MultiPageBuffer->Length);
3e7ee490
HJ
922
923 DPRINT_ENTER(VMBUS);
924
925 DumpVmbusChannel(Channel);
926
927 DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u", MultiPageBuffer->Offset, MultiPageBuffer->Length, PfnCount);
928
929 ASSERT(PfnCount > 0);
930 ASSERT(PfnCount <= MAX_MULTIPAGE_BUFFER_COUNT);
931
454f18a9 932 /* Adjust the size down since VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER is the largest size we support */
59471438 933 descSize = sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER) - ((MAX_MULTIPAGE_BUFFER_COUNT - PfnCount)*sizeof(u64));
3e7ee490 934 packetLen = descSize + BufferLen;
59471438 935 packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));
3e7ee490 936
59471438 937 ASSERT((packetLenAligned - packetLen) < sizeof(u64));
3e7ee490 938
454f18a9 939 /* Setup the descriptor */
3e7ee490
HJ
940 desc.Type = VmbusPacketTypeDataUsingGpaDirect;
941 desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
454f18a9
BP
942 desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */
943 desc.Length8 = (u16)(packetLenAligned >> 3);
944 desc.TransactionId = RequestId;
3e7ee490
HJ
945 desc.RangeCount = 1;
946
947 desc.Range.Length = MultiPageBuffer->Length;
948 desc.Range.Offset = MultiPageBuffer->Offset;
949
59471438 950 memcpy(desc.Range.PfnArray, MultiPageBuffer->PfnArray, PfnCount*sizeof(u64));
3e7ee490
HJ
951
952 bufferList[0].Data = &desc;
953 bufferList[0].Length = descSize;
954
955 bufferList[1].Data = Buffer;
956 bufferList[1].Length = BufferLen;
957
958 bufferList[2].Data = &alignedData;
959 bufferList[2].Length = packetLenAligned - packetLen;
960
961 ret = RingBufferWrite(
962 &Channel->Outbound,
963 bufferList,
964 3);
965
454f18a9 966 /* TODO: We should determine if this is optional */
3e7ee490
HJ
967 if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
968 {
969 VmbusChannelSetEvent(Channel);
970 }
971
972 DPRINT_EXIT(VMBUS);
973
974 return ret;
975}
976
977
978/*++
979
980Name:
981 VmbusChannelRecvPacket()
982
983Description:
984 Retrieve the user packet on the specified channel
985
986--*/
454f18a9 987/* TODO: Do we ever receive a gpa direct packet other than the ones we send ? */
3e7ee490
HJ
988int
989VmbusChannelRecvPacket(
990 VMBUS_CHANNEL *Channel,
8282c400 991 void * Buffer,
4d643114
GKH
992 u32 BufferLen,
993 u32* BufferActualLen,
59471438 994 u64* RequestId
3e7ee490
HJ
995 )
996{
997 VMPACKET_DESCRIPTOR desc;
4d643114
GKH
998 u32 packetLen;
999 u32 userLen;
3e7ee490 1000 int ret;
54411c42 1001 unsigned long flags;
3e7ee490
HJ
1002
1003 DPRINT_ENTER(VMBUS);
1004
1005 *BufferActualLen = 0;
1006 *RequestId = 0;
1007
54411c42 1008 spin_lock_irqsave(&Channel->inbound_lock, flags);
3e7ee490
HJ
1009
1010 ret = RingBufferPeek(&Channel->Inbound, &desc, sizeof(VMPACKET_DESCRIPTOR));
1011 if (ret != 0)
1012 {
54411c42 1013 spin_unlock_irqrestore(&Channel->inbound_lock, flags);
3e7ee490 1014
454f18a9 1015 /* DPRINT_DBG(VMBUS, "nothing to read!!"); */
3e7ee490
HJ
1016 DPRINT_EXIT(VMBUS);
1017 return 0;
1018 }
1019
454f18a9 1020 /* VmbusChannelClearEvent(Channel); */
3e7ee490
HJ
1021
1022 packetLen = desc.Length8 << 3;
1023 userLen = packetLen - (desc.DataOffset8 << 3);
454f18a9 1024 /* ASSERT(userLen > 0); */
3e7ee490
HJ
1025
1026 DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d flag %d tid %llx pktlen %d datalen %d> ",
1027 Channel,
1028 Channel->OfferMsg.ChildRelId,
1029 desc.Type,
1030 desc.Flags,
1031 desc.TransactionId, packetLen, userLen);
1032
1033 *BufferActualLen = userLen;
1034
1035 if (userLen > BufferLen)
1036 {
54411c42 1037 spin_unlock_irqrestore(&Channel->inbound_lock, flags);
3e7ee490
HJ
1038
1039 DPRINT_ERR(VMBUS, "buffer too small - got %d needs %d", BufferLen, userLen);
1040 DPRINT_EXIT(VMBUS);
1041
1042 return -1;
1043 }
1044
1045 *RequestId = desc.TransactionId;
1046
454f18a9 1047 /* Copy over the packet to the user buffer */
3e7ee490
HJ
1048 ret = RingBufferRead(&Channel->Inbound, Buffer, userLen, (desc.DataOffset8 << 3));
1049
54411c42 1050 spin_unlock_irqrestore(&Channel->inbound_lock, flags);
3e7ee490
HJ
1051
1052 DPRINT_EXIT(VMBUS);
1053
1054 return 0;
1055}
1056
1057/*++
1058
1059Name:
1060 VmbusChannelRecvPacketRaw()
1061
1062Description:
1063 Retrieve the raw packet on the specified channel
1064
1065--*/
1066int
1067VmbusChannelRecvPacketRaw(
1068 VMBUS_CHANNEL *Channel,
8282c400 1069 void * Buffer,
4d643114
GKH
1070 u32 BufferLen,
1071 u32* BufferActualLen,
59471438 1072 u64* RequestId
3e7ee490
HJ
1073 )
1074{
1075 VMPACKET_DESCRIPTOR desc;
4d643114
GKH
1076 u32 packetLen;
1077 u32 userLen;
3e7ee490 1078 int ret;
54411c42 1079 unsigned long flags;
3e7ee490
HJ
1080
1081 DPRINT_ENTER(VMBUS);
1082
1083 *BufferActualLen = 0;
1084 *RequestId = 0;
1085
54411c42 1086 spin_lock_irqsave(&Channel->inbound_lock, flags);
3e7ee490
HJ
1087
1088 ret = RingBufferPeek(&Channel->Inbound, &desc, sizeof(VMPACKET_DESCRIPTOR));
1089 if (ret != 0)
1090 {
54411c42 1091 spin_unlock_irqrestore(&Channel->inbound_lock, flags);
3e7ee490 1092
454f18a9 1093 /* DPRINT_DBG(VMBUS, "nothing to read!!"); */
3e7ee490
HJ
1094 DPRINT_EXIT(VMBUS);
1095 return 0;
1096 }
1097
454f18a9 1098 /* VmbusChannelClearEvent(Channel); */
3e7ee490
HJ
1099
1100 packetLen = desc.Length8 << 3;
1101 userLen = packetLen - (desc.DataOffset8 << 3);
1102
1103 DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d flag %d tid %llx pktlen %d datalen %d> ",
1104 Channel,
1105 Channel->OfferMsg.ChildRelId,
1106 desc.Type,
1107 desc.Flags,
1108 desc.TransactionId, packetLen, userLen);
1109
1110 *BufferActualLen = packetLen;
1111
1112 if (packetLen > BufferLen)
1113 {
54411c42 1114 spin_unlock_irqrestore(&Channel->inbound_lock, flags);
3e7ee490
HJ
1115
1116 DPRINT_ERR(VMBUS, "buffer too small - needed %d bytes but got space for only %d bytes", packetLen, BufferLen);
1117 DPRINT_EXIT(VMBUS);
1118 return -2;
1119 }
1120
1121 *RequestId = desc.TransactionId;
1122
454f18a9 1123 /* Copy over the entire packet to the user buffer */
3e7ee490
HJ
1124 ret = RingBufferRead(&Channel->Inbound, Buffer, packetLen, 0);
1125
54411c42 1126 spin_unlock_irqrestore(&Channel->inbound_lock, flags);
3e7ee490
HJ
1127
1128 DPRINT_EXIT(VMBUS);
1129
1130 return 0;
1131}
1132
1133
1134/*++
1135
1136Name:
1137 VmbusChannelOnChannelEvent()
1138
1139Description:
1140 Channel event callback
1141
1142--*/
1143void
1144VmbusChannelOnChannelEvent(
1145 VMBUS_CHANNEL *Channel
1146 )
1147{
1148 DumpVmbusChannel(Channel);
1149 ASSERT(Channel->OnChannelCallback);
1150#ifdef ENABLE_POLLING
1151 TimerStop(Channel->PollTimer);
1152 Channel->OnChannelCallback(Channel->ChannelCallbackContext);
1153 TimerStart(Channel->PollTimer, 100 /* 100us */);
1154#else
1155 Channel->OnChannelCallback(Channel->ChannelCallbackContext);
1156#endif
1157}
1158
1159/*++
1160
1161Name:
1162 VmbusChannelOnTimer()
1163
1164Description:
1165 Timer event callback
1166
1167--*/
1168void
1169VmbusChannelOnTimer(
1170 void *Context
1171 )
1172{
1173 VMBUS_CHANNEL *channel = (VMBUS_CHANNEL*)Context;
1174
1175 if (channel->OnChannelCallback)
1176 {
1177 channel->OnChannelCallback(channel->ChannelCallbackContext);
1178#ifdef ENABLE_POLLING
1179 TimerStart(channel->PollTimer, 100 /* 100us */);
1180#endif
1181 }
1182}
1183
1184
1185/*++
1186
1187Name:
1188 DumpVmbusChannel()
1189
1190Description:
1191 Dump vmbus channel info to the console
1192
1193--*/
1194static void
1195DumpVmbusChannel(
1196 VMBUS_CHANNEL *Channel
1197 )
1198{
1199 DPRINT_DBG(VMBUS, "Channel (%d)", Channel->OfferMsg.ChildRelId);
1200 DumpRingInfo(&Channel->Outbound, "Outbound ");
1201 DumpRingInfo(&Channel->Inbound, "Inbound ");
1202}
1203
1204
454f18a9 1205/* eof */