/* Callback when data is received from userspace */ static int fcopy_on_msg(void *msg, int len) { int *val = (int *)msg; if (len != sizeof(int)) return -EINVAL; if (fcopy_transaction.state == HVUTIL_DEVICE_INIT) return fcopy_handle_handshake(*val); if (fcopy_transaction.state != HVUTIL_USERSPACE_REQ) return -EINVAL; /* * Complete the transaction by forwarding the result * to the host. But first, cancel the timeout. */ if (cancel_delayed_work_sync(&fcopy_timeout_work)) { fcopy_transaction.state = HVUTIL_USERSPACE_RECV; fcopy_respond_to_host(*val); hv_poll_channel(fcopy_transaction.recv_channel, fcopy_poll_wrapper); } return 0; }
static ssize_t fcopy_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { int response = 0; if (count != sizeof(int)) return -EINVAL; if (copy_from_user(&response, buf, sizeof(int))) return -EFAULT; if (in_hand_shake) { if (fcopy_handle_handshake(response)) return -EINVAL; return sizeof(int); } /* * Complete the transaction by forwarding the result * to the host. But first, cancel the timeout. */ if (cancel_delayed_work_sync(&fcopy_work)) fcopy_respond_to_host(response); return sizeof(int); }