Exemplo n.º 1
0
/**
 * Shutdown
 */
static void
hv_shutdown_cb(void *context)
{
	uint8_t*			buf;
	hv_vmbus_channel*		channel = context;
	uint8_t			execute_shutdown = 0;
	hv_vmbus_icmsg_hdr*		icmsghdrp;
	uint32_t			recv_len;
	uint64_t			request_id;
	int				ret;
	hv_vmbus_shutdown_msg_data*	shutdown_msg;

	buf = receive_buffer[HV_SHUT_DOWN];

	ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE,
					    &recv_len, &request_id);

	if ((ret == 0) && recv_len > 0) {

	    icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
		&buf[sizeof(struct hv_vmbus_pipe_hdr)];

	    if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
		hv_negotiate_version(icmsghdrp, NULL, buf);

	    } else {
		shutdown_msg =
		    (struct hv_vmbus_shutdown_msg_data *)
		    &buf[sizeof(struct hv_vmbus_pipe_hdr) +
			sizeof(struct hv_vmbus_icmsg_hdr)];

		switch (shutdown_msg->flags) {
		    case 0:
		    case 1:
			icmsghdrp->status = HV_S_OK;
			execute_shutdown = 1;
			if(bootverbose)
			    printf("Shutdown request received -"
				    " graceful shutdown initiated\n");
			break;
		    default:
			icmsghdrp->status = HV_E_FAIL;
			execute_shutdown = 0;
			printf("Shutdown request received -"
			    " Invalid request\n");
			break;
		    }
	    }

	    icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
				 HV_ICMSGHDRFLAG_RESPONSE;

	    hv_vmbus_channel_send_packet(channel, buf,
					recv_len, request_id,
					HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
	}

	if (execute_shutdown)
	    shutdown_nice(RB_POWEROFF);
}
Exemplo n.º 2
0
/**
 * Process heartbeat message
 */
static void
hv_heartbeat_cb(void *context)
{
	uint8_t*		buf;
	hv_vmbus_channel*	channel = context;
	uint32_t		recvlen;
	uint64_t		requestid;
	int			ret;

	struct hv_vmbus_heartbeat_msg_data*	heartbeat_msg;
	struct hv_vmbus_icmsg_hdr*		icmsghdrp;

	buf = receive_buffer[HV_HEART_BEAT];

	ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE, &recvlen,
					    &requestid);

	if ((ret == 0) && recvlen > 0) {

	    icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
		&buf[sizeof(struct hv_vmbus_pipe_hdr)];

	    if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
		hv_negotiate_version(icmsghdrp, NULL, buf);

	    } else {
		heartbeat_msg =
		    (struct hv_vmbus_heartbeat_msg_data *)
			&buf[sizeof(struct hv_vmbus_pipe_hdr) +
			     sizeof(struct hv_vmbus_icmsg_hdr)];

		heartbeat_msg->seq_num += 1;
	    }

	    icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
				 HV_ICMSGHDRFLAG_RESPONSE;

	    hv_vmbus_channel_send_packet(channel, buf, recvlen, requestid,
		HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
	}
}
Exemplo n.º 3
0
/**
 * Time Sync Channel message handler
 */
static void
hv_timesync_cb(void *context)
{
	hv_vmbus_channel*	channel;
	hv_vmbus_icmsg_hdr*	icmsghdrp;
	uint32_t		recvlen;
	uint64_t		requestId;
	int			ret;
	uint8_t*		time_buf;
	struct hv_ictimesync_data* timedatap;
	hv_timesync_sc		*softc;

	softc = (hv_timesync_sc*)context;
	channel = softc->util_sc.hv_dev->channel;
	time_buf = softc->util_sc.receive_buffer;

	ret = hv_vmbus_channel_recv_packet(channel, time_buf,
		PAGE_SIZE, &recvlen, &requestId);

	if ((ret == 0) && recvlen > 0) {
	    icmsghdrp = (struct hv_vmbus_icmsg_hdr *) &time_buf[
		sizeof(struct hv_vmbus_pipe_hdr)];

	    if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
		hv_negotiate_version(icmsghdrp, NULL, time_buf);
	    } else {
		timedatap = (struct hv_ictimesync_data *) &time_buf[
		    sizeof(struct hv_vmbus_pipe_hdr) +
			sizeof(struct hv_vmbus_icmsg_hdr)];
		hv_adj_guesttime(softc, timedatap->parenttime, timedatap->flags);
	    }

	    icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION
		| HV_ICMSGHDRFLAG_RESPONSE;

	    hv_vmbus_channel_send_packet(channel, time_buf,
		recvlen, requestId,
		HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
	}
}
Exemplo n.º 4
0
/**
 * Time Sync Channel message handler
 */
static void
hv_timesync_cb(struct vmbus_channel *channel, void *context)
{
	hv_vmbus_icmsg_hdr*	icmsghdrp;
	uint32_t		recvlen;
	uint64_t		requestId;
	int			ret;
	uint8_t*		time_buf;
	struct hv_ictimesync_data* timedatap;
	hv_timesync_sc		*softc;

	softc = (hv_timesync_sc*)context;
	time_buf = softc->util_sc.receive_buffer;

	recvlen = PAGE_SIZE;
	ret = vmbus_chan_recv(channel, time_buf, &recvlen, &requestId);
	KASSERT(ret != ENOBUFS, ("hvtimesync recvbuf is not large enough"));
	/* XXX check recvlen to make sure that it contains enough data */

	if ((ret == 0) && recvlen > 0) {
	    icmsghdrp = (struct hv_vmbus_icmsg_hdr *) &time_buf[
		sizeof(struct hv_vmbus_pipe_hdr)];

	    if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
		hv_negotiate_version(icmsghdrp, NULL, time_buf);
	    } else {
		timedatap = (struct hv_ictimesync_data *) &time_buf[
		    sizeof(struct hv_vmbus_pipe_hdr) +
			sizeof(struct hv_vmbus_icmsg_hdr)];
		hv_adj_guesttime(softc, timedatap->parenttime, timedatap->flags);
	    }

	    icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION
		| HV_ICMSGHDRFLAG_RESPONSE;

	    vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0,
	        time_buf, recvlen, requestId);
	}
}
Exemplo n.º 5
0
/* 
 * Callback routine that gets called whenever there is a message from host
 */
static 
void hv_kvp_callback(void *context)
{
	uint8_t*		buf;
	hv_vmbus_channel*	channel = context;
	uint32_t		recvlen;
	uint64_t		requestid;
	int			ret;

	struct hv_vmbus_icmsg_hdr*		icmsghdrp;
	buf = receive_buffer[0];

#if 0
	/* If driver unloaded abruptly, return */
	if (vmbus_kvp_channel == NULL) 
	{
#ifdef DEBUG
		printf("hv_kvp_cb: kvp unloaded abruptly\n");
#endif
		return;
	}
#endif

	/* Check if kvp is ready to process */
	if (!hv_kvp_ready()) {
#ifdef DEBUG
		printf("hv_kvp_cb: kvp is not ready..initing\n");
#endif
		hv_queue_work_item(kvp_work_queue, hv_kvp_conn_register, NULL);
	}

	/* Check if already one transaction is under process */
	if (hv_kvp_transaction_active()) {
#ifdef DEBUG
		printf("hv_kvp_cb: Already one transaction is active\n");
#endif
		return;
	}
	ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE * 2, 
		&recvlen, &requestid);

#ifdef DEBUG
	printf("hv_kvp_cb: vmbus_recv ret:%d rLen:%d rId:%d\n", 
		ret, recvlen, (int)requestid);
#endif
	if ((ret == 0) && (recvlen > 0)) {

		icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
			&buf[sizeof(struct hv_vmbus_pipe_hdr)];

		if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
#ifdef DEBUG
			printf("hv_kvp_cb: Negotiate message received\n");
#endif
			hv_negotiate_version(icmsghdrp, NULL, buf);
		} else {
#ifdef DEBUG
			printf("hv_kvp_cb: New host message received\n");
#endif
			hv_kvp_transaction_init(recvlen,channel,requestid, buf);
			hv_queue_work_item(kvp_work_queue,
						hv_kvp_process_msg, NULL);
			return; /* deferred response by KVP process */
		}

		icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
			HV_ICMSGHDRFLAG_RESPONSE;

		hv_vmbus_channel_send_packet(channel, buf, recvlen, requestid,
			HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0);
	}
}
Exemplo n.º 6
0
/**
 * Shutdown
 */
static void
hv_shutdown_cb(struct vmbus_channel *channel, void *context)
{
	uint8_t*			buf;
	uint8_t				execute_shutdown = 0;
	hv_vmbus_icmsg_hdr*		icmsghdrp;
	uint32_t			recv_len;
	uint64_t			request_id;
	int				ret;
	hv_vmbus_shutdown_msg_data*	shutdown_msg;
	hv_util_sc			*softc;

	softc = (hv_util_sc*)context;
	buf = softc->receive_buffer;

	recv_len = softc->ic_buflen;
	ret = vmbus_chan_recv(channel, buf, &recv_len, &request_id);
	KASSERT(ret != ENOBUFS, ("hvshutdown recvbuf is not large enough"));
	/* XXX check recv_len to make sure that it contains enough data */

	if ((ret == 0) && recv_len > 0) {

	    icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
		&buf[sizeof(struct hv_vmbus_pipe_hdr)];

	    if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
		hv_negotiate_version(icmsghdrp, buf);
	    } else {
		shutdown_msg =
		    (struct hv_vmbus_shutdown_msg_data *)
		    &buf[sizeof(struct hv_vmbus_pipe_hdr) +
			sizeof(struct hv_vmbus_icmsg_hdr)];

		switch (shutdown_msg->flags) {
		    case 0:
		    case 1:
			icmsghdrp->status = HV_S_OK;
			execute_shutdown = 1;
			if(bootverbose)
			    printf("Shutdown request received -"
				    " graceful shutdown initiated\n");
			break;
		    default:
			icmsghdrp->status = HV_E_FAIL;
			execute_shutdown = 0;
			printf("Shutdown request received -"
			    " Invalid request\n");
			break;
		    }
	    }

	icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
				 HV_ICMSGHDRFLAG_RESPONSE;

	    vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0,
	        buf, recv_len, request_id);
	}

	if (execute_shutdown)
	    shutdown_nice(RB_POWEROFF);
}