Esempio n. 1
0
static void mousevsc_on_channel_callback(void *context)
{
	const int packet_size = 0x100;
	int ret;
	struct hv_device *device = context;
	u32 bytes_recvd;
	u64 req_id;
	struct vmpacket_descriptor *desc;
	unsigned char	*buffer;
	int	bufferlen = packet_size;

	buffer = kmalloc(bufferlen, GFP_ATOMIC);
	if (!buffer)
		return;

	do {
		ret = vmbus_recvpacket_raw(device->channel, buffer,
					bufferlen, &bytes_recvd, &req_id);

		switch (ret) {
		case 0:
			if (bytes_recvd <= 0) {
				kfree(buffer);
				return;
			}
			desc = (struct vmpacket_descriptor *)buffer;

			switch (desc->type) {
			case VM_PKT_COMP:
				break;

			case VM_PKT_DATA_INBAND:
				mousevsc_on_receive(device, desc);
				break;

			default:
				pr_err("unhandled packet type %d, tid %llx len %d\n",
					desc->type, req_id, bytes_recvd);
				break;
			}

			break;

		case -ENOBUFS:
			kfree(buffer);
			/* Handle large packet */
			bufferlen = bytes_recvd;
			buffer = kmalloc(bytes_recvd, GFP_ATOMIC);

			if (!buffer)
				return;

			break;
		}
	} while (1);

}
Esempio n. 2
0
static void hv_kbd_on_channel_callback(void *context)
{
	struct hv_device *hv_dev = context;
	void *buffer;
	int bufferlen = 0x100; /* Start with sensible size */
	u32 bytes_recvd;
	u64 req_id;
	int error;

	buffer = kmalloc(bufferlen, GFP_ATOMIC);
	if (!buffer)
		return;

	while (1) {
		error = vmbus_recvpacket_raw(hv_dev->channel, buffer, bufferlen,
					     &bytes_recvd, &req_id);
		switch (error) {
		case 0:
			if (bytes_recvd == 0) {
				kfree(buffer);
				return;
			}

			hv_kbd_handle_received_packet(hv_dev, buffer,
						      bytes_recvd, req_id);
			break;

		case -ENOBUFS:
			kfree(buffer);
			/* Handle large packet */
			bufferlen = bytes_recvd;
			buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
			if (!buffer)
				return;
			break;
		}
	}
}
Esempio n. 3
0
void netvsc_channel_cb(void *context)
{
	int ret;
	struct vmbus_channel *channel = (struct vmbus_channel *)context;
	struct hv_device *device;
	struct netvsc_device *net_device;
	u32 bytes_recvd;
	u64 request_id;
	struct vmpacket_descriptor *desc;
	unsigned char *buffer;
	int bufferlen = NETVSC_PACKET_SIZE;
	struct net_device *ndev;
	struct nvsp_message *nvmsg;

	if (channel->primary_channel != NULL)
		device = channel->primary_channel->device_obj;
	else
		device = channel->device_obj;

	net_device = get_inbound_net_device(device);
	if (!net_device)
		return;
	ndev = net_device->ndev;
	buffer = get_per_channel_state(channel);

	do {
		ret = vmbus_recvpacket_raw(channel, buffer, bufferlen,
					   &bytes_recvd, &request_id);
		if (ret == 0) {
			if (bytes_recvd > 0) {
				desc = (struct vmpacket_descriptor *)buffer;
				nvmsg = (struct nvsp_message *)((unsigned long)
					 desc + (desc->offset8 << 3));
				switch (desc->type) {
				case VM_PKT_COMP:
					netvsc_send_completion(net_device,
								device, desc);
					break;

				case VM_PKT_DATA_USING_XFER_PAGES:
					netvsc_receive(net_device, channel,
						       device, desc);
					break;

				case VM_PKT_DATA_INBAND:
					netvsc_receive_inband(device,
							      net_device,
							      nvmsg);
					break;

				default:
					netdev_err(ndev,
						   "unhandled packet type %d, "
						   "tid %llx len %d\n",
						   desc->type, request_id,
						   bytes_recvd);
					break;
				}

			} else {
				/*
				 * We are done for this pass.
				 */
				break;
			}

		} else if (ret == -ENOBUFS) {
			if (bufferlen > NETVSC_PACKET_SIZE)
				kfree(buffer);
			/* Handle large packet */
			buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
			if (buffer == NULL) {
				/* Try again next time around */
				netdev_err(ndev,
					   "unable to allocate buffer of size "
					   "(%d)!!\n", bytes_recvd);
				break;
			}

			bufferlen = bytes_recvd;
		}
	} while (1);

	if (bufferlen > NETVSC_PACKET_SIZE)
		kfree(buffer);
	return;
}