static int IVmbusChannelSendPacket(struct hv_device *device, const void *Buffer, u32 BufferLen, u64 RequestId, u32 Type, u32 Flags) { return VmbusChannelSendPacket(device->context, Buffer, BufferLen, RequestId, Type, Flags); }
/* * Heartbeat functionality. * Every two seconds, Hyper-V send us a heartbeat request message. * we respond to this message, and Hyper-V knows we are alive. */ static void heartbeat_onchannelcallback(void *context) { struct vmbus_channel *channel = context; u8 *buf; u32 buflen, recvlen; u64 requestid; struct icmsg_hdr *icmsghdrp; struct heartbeat_msg_data *heartbeat_msg; DPRINT_ENTER(VMBUS); buflen = PAGE_SIZE; buf = kmalloc(buflen, GFP_ATOMIC); VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); if (recvlen > 0) { DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", recvlen, requestid); icmsghdrp = (struct icmsg_hdr *)&buf[ sizeof(struct vmbuspipe_hdr)]; icmsghdrp = (struct icmsg_hdr *)&buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { prep_negotiate_resp(icmsghdrp, NULL, buf); } else { heartbeat_msg = (struct heartbeat_msg_data *)&buf[ sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; DPRINT_DBG(VMBUS, "heartbeat seq = %lld", heartbeat_msg->seq_num); heartbeat_msg->seq_num += 1; } icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; VmbusChannelSendPacket(channel, buf, recvlen, requestid, VmbusPacketTypeDataInBand, 0); } kfree(buf); DPRINT_EXIT(VMBUS); }
/* * Time Sync Channel message handler. */ static void timesync_onchannelcallback(void *context) { struct vmbus_channel *channel = context; u8 *buf; u32 buflen, recvlen; u64 requestid; struct icmsg_hdr *icmsghdrp; struct ictimesync_data *timedatap; DPRINT_ENTER(VMBUS); buflen = PAGE_SIZE; buf = kmalloc(buflen, GFP_ATOMIC); VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); if (recvlen > 0) { DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", recvlen, requestid); icmsghdrp = (struct icmsg_hdr *)&buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { prep_negotiate_resp(icmsghdrp, NULL, buf); } else { timedatap = (struct ictimesync_data *)&buf[ sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; adj_guesttime(timedatap->parenttime, timedatap->flags); } icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; VmbusChannelSendPacket(channel, buf, recvlen, requestid, VmbusPacketTypeDataInBand, 0); } kfree(buf); DPRINT_EXIT(VMBUS); }
static void shutdown_onchannelcallback(void *context) { struct vmbus_channel *channel = context; u8 *buf; u32 buflen, recvlen; u64 requestid; u8 execute_shutdown = false; struct shutdown_msg_data *shutdown_msg; struct icmsg_hdr *icmsghdrp; struct icmsg_negotiate *negop = NULL; DPRINT_ENTER(VMBUS); buflen = PAGE_SIZE; buf = kmalloc(buflen, GFP_ATOMIC); VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); if (recvlen > 0) { DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", recvlen, requestid); icmsghdrp = (struct icmsg_hdr *)&buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { prep_negotiate_resp(icmsghdrp, negop, buf); } else { shutdown_msg = (struct shutdown_msg_data *)&buf[ sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; switch (shutdown_msg->flags) { case 0: case 1: icmsghdrp->status = HV_S_OK; execute_shutdown = true; DPRINT_INFO(VMBUS, "Shutdown request received -" " gracefull shutdown initiated"); break; default: icmsghdrp->status = HV_E_FAIL; execute_shutdown = false; DPRINT_INFO(VMBUS, "Shutdown request received -" " Invalid request"); break; }; } icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; VmbusChannelSendPacket(channel, buf, recvlen, requestid, VmbusPacketTypeDataInBand, 0); } kfree(buf); DPRINT_EXIT(VMBUS); if (execute_shutdown == true) orderly_poweroff(false); }