From: Jean Guyader Date: Fri, 6 Nov 2009 14:09:04 +0000 (+0000) Subject: Merge branch 'master' of git://git.uk.xensource.com/xenclient/linux-2.6.27-pq X-Git-Url: http://xenbits.xen.org/gitweb?a=commitdiff_plain;h=35ad56964466cce975b3df16e9edbc951878109d;p=xenclient%2Flinux-2.6.27-pq.git Merge branch 'master' of git://git.uk.xensource.com/xenclient/linux-2.6.27-pq Conflicts: master/v2v-dev --- 35ad56964466cce975b3df16e9edbc951878109d diff --cc master/v2v-dev index 866d633,b630764..3104196 --- a/master/v2v-dev +++ b/master/v2v-dev @@@ -1,41 -1,40 +1,14 @@@ --diff --git a/drivers/xen/v2v/Kconfig b/drivers/xen/v2v/Kconfig - index dd48eaf..e56706d 100644 -index 5966234..b3b6ef4 100644 ----- a/drivers/xen/v2v/Kconfig --+++ b/drivers/xen/v2v/Kconfig --@@ -22,3 +22,10 @@ config XEN_V2V_DRV - default n - default n -- help -- Sample for Xen V2V interdomain communication services. --+ --+config XEN_V2V_DEV --+ tristate "Xen V2V device" --+ depends on XEN_V2V - + default m -+ default m --+ help --+ Xen V2V char device for userland v2v. --diff --git a/drivers/xen/v2v/Makefile b/drivers/xen/v2v/Makefile - index 8e35e62..c390314 100644 -index f3442d9..5230cd6 100644 ----- a/drivers/xen/v2v/Makefile --+++ b/drivers/xen/v2v/Makefile - @@ -5,4 +5,7 @@ obj-$(CONFIG_XEN_V2V_DRV) += v2vdrv.o - v2vdrv-objs = - v2vdrv-objs += v2vsamp.o v2vops.o -@@ -4,5 +4,6 @@ -- - v2vdrv-objs = - v2vdrv-objs += v2vsamp.o v2vops.o --+obj-$(CONFIG_XEN_V2V_DEV) += v2vdev.o - + - + - -- ccflags-$(CONFIG_XEN_V2V_DEBUG) += -DDEBUG diff --git a/drivers/xen/v2v/v2vdev.c b/drivers/xen/v2v/v2vdev.c new file mode 100644 - index 0000000..39d0a84 -index 0000000..c7afdf3 ++index 0000000..adfc6c8 --- /dev/null +++ b/drivers/xen/v2v/v2vdev.c -@@ -0,0 +1,400 @@ +@@ -0,0 +1,511 @@ +/****************************************************************************** + * drivers/xen/v2v/v2vdev.c + * + * V2V broker. --+ * +++ * + * Copyright (c) 2009 Jean Guyader + * Copyright (c) 2009 Citrix Systems, Inc. + * @@@ -290,7 -220,7 +263,7 @@@ + err = v2v_connect(path, &ctx->channel, 0); + if (err) + { - + DPRINTK("failure in connect() - err: %d\n", err); -+ printk(V2VDEV_LOG" failure in connect() - err: %d\n", err); +++ DPRINTK("failure in connect() - err: %d\n", err); + return err; + } + @@@ -307,66 -237,26 +280,66 @@@ + size_t count, loff_t *ppos) +{ + struct v2vdev_context *ctx = filp->private_data; -+ ssize_t n, size; -+ uint16_t tag; -+ -+ if (ctx->last_err) -+ return -ctx->last_err; ++ struct v2v_wait *wait_state; ++ size_t red=0; ++ size_t n; ++ int nonblock=filp->f_flags & O_NONBLOCK; ++ u8 reasons_mask = V2V_WAKE_REASON_CONTROL | V2V_WAKE_REASON_RECEIVE; ++ u8 reason; ++ enum v2v_endpoint_state state; + -+ size = MIN(count, ctx->buff_size); -+ n = copy_to_user(buf, ctx->buff, size); -+ ctx->buff_size -= size; -+ if (ctx->buff_size == 0) -+ { -+ kfree(ctx->buff); -+ ctx->buff = NULL; -+ } -+ else -+ ctx->buff += size; ++ DUMP_CTX(ctx); - + if (!ctx->connected) +++ if (!ctx->connected) ++ return -ENOTCONN; ++ ++ while (count) { ++ ++ if (!ctx->data_len) { ++ - + if (ctx->last_err) +++ if (ctx->last_err) ++ return ctx->last_err; ++ ++ if (nonblock && !v2v_receive_in_queue(ctx)) { ++ DPRINTK("v2vdev_read needed got %d/%d\n",red,count+red); ++ return red ? red:-EAGAIN; ++ } - + +++ ++ wait_state = v2v_get_wait_state(ctx->channel); ++ wait_event(wait_state->wait_event, ++ atomic_xchg(&wait_state->wait_condition, 0) == 1); ++ reason = v2v_get_wake_reason(ctx->channel, reasons_mask); ++ if (reason & V2V_WAKE_REASON_CONTROL) ++ { ++ if (v2v_get_remote_state(ctx->channel, &state) == 0 && ++ state != v2v_state_connected) ++ { ++ ctx->connected = 0; ++ v2v_disconnect(ctx->channel); ++ return 0; ++ } ++ } ++ v2vdev_message_get(ctx); ++ } ++ DUMP_CTX(ctx); ++ ++ n=MIN(count,ctx->data_len); ++ ++ if (n) { ++ if (copy_to_user(buf, ctx->data_ptr, n)) ++ return -EFAULT; ++ red+=n; ++ count-=n; ++ ctx->data_ptr+=n; ++ ctx->data_len-=n; ++ buf+=n; ++ ++ DUMP_CTX(ctx); ++ } ++ } - + +++ ++ DPRINTK("v2vdev_read needed got %d/%d\n",red,red); + -+ v2v_nc2_finish_message(ctx->channel); -+ v2v_set_wake_reason(ctx->channel, V2V_WAKE_REASON_RECEIVE); -+ return size - n; ++ return red; +} + +static ssize_t v2vdev_write(struct file *filp, const char __user *buf, @@@ -376,21 -266,20 +349,21 @@@ + volatile void *msg; + int err; + -+ err = v2v_nc2_prep_message(ctx->channel, count, ctx->type, 0, &msg); ++ DUMP_CTX(ctx); - + if (!ctx->connected) +++ if (!ctx->connected) ++ return -ENOTCONN; - + +++ ++ err = v2v_nc2_prep_message(ctx->channel, count, 1, 0, &msg); + if (err) + { -+ printk(V2VDEV_LOG" failure in v2v_nc2_prep_message() - error: %d\n", err); -+ return -EAGAIN; -+ } -+ -+ if (copy_from_user((void *)msg, buf, count) != 0) -+ { -+ printk(V2VDEV_LOG" failure in copy_from_user()\n"); -+ return 0; ++ DPRINTK("failure in v2v_nc2_prep_message() - error: %d\n", err); ++ return -EIO; + } + -+ hexdump(">", msg, count); ++ if (copy_from_user((void *)msg, buf, count)) ++ return -EFAULT; - + +++ ++ hexdump(">", (void *) msg, count); + v2v_nc2_send_messages(ctx->channel); + v2v_set_wake_reason(ctx->channel, V2V_WAKE_REASON_SEND); + return count; @@@ -398,11 -287,10 +371,11 @@@ + +static long v2vdev_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) --+{ -+ int rc; -+ struct v2vdev_context *ctx = filp->private_data; -+ +++{ ++ int rc; ++ void __user *p = (void __user *)arg; ++ struct v2vdev_context *ctx = filp->private_data; - + +++ + rc = -ENOSYS; + switch (cmd) { + default: @@@ -457,45 -372,18 +430,45 @@@ + wait_state = v2v_get_wait_state(ctx->channel); + poll_wait(filp, &wait_state->wait_event, wait); + -+ if (!ctx->connected && ctx->listenner) -+ if (v2v_accept(ctx->channel, 1) != EAGAIN) ++ if (ctx->connected) ++ reasons_mask |= V2V_WAKE_REASON_RECEIVE; ++ ++ reason = v2v_get_wake_reason(ctx->channel, reasons_mask); ++ if (reason & V2V_WAKE_REASON_CONTROL) ++ { ++ if (!ctx->connected) { ++ err = v2v_get_remote_state(ctx->channel, &state); ++ if (ctx->listenner && (err == 0 && state == v2v_state_connected) && ++ v2v_accept(ctx->channel, 1) == 0) ++ { ++ v2vdev_wait_connected(ctx); ++ v2v_set_wake_reason(ctx->channel, V2V_WAKE_REASON_SEND); ++ DPRINTK("connected !\n"); ++ return 0; ++ } ++ } ++ else + { -+ v2vdev_wait_connected(ctx); -+ printk(V2VDEV_LOG" connected !\n"); -+ return 0; ++ err = v2v_get_remote_state(ctx->channel, &state); ++ if (err == 0 && ctx->connected && state != v2v_state_connected) ++ { - + DPRINTK("Remote end %s, v2v_disconnect\n", v2v_endpoint_state_name(state)); +++ DPRINTK("Remote end %s, v2v_disconnect\n", v2v_endpoint_state_name(state)); ++ ctx->connected = 0; ++ v2v_disconnect(ctx->channel); ++ return POLLIN | POLLRDNORM; ++ } + } ++ } ++ else if (reason & V2V_WAKE_REASON_RECEIVE) ++ { ++ DUMP_CTX(ctx); ++ v2vdev_message_get(ctx); ++ } ++ ++ if (ctx->data_len) ++ mask = POLLIN | POLLRDNORM; ++ + -+ reason = v2v_get_wake_reason(ctx->channel, reasons_mask); -+ if (reason & V2V_WAKE_REASON_RECEIVE) -+ if (v2vdev_message_get(ctx) == 0) -+ mask = POLLIN | POLLRDNORM; + return mask; +} + @@@ -524,11 -412,11 +497,11 @@@ + + err = misc_register(&v2vdev_miscdev); + if (err != 0) { -+ printk(KERN_ALERT "Could not register /dev/v2v\n"); ++ DPRINTK(KERN_ALERT "Could not register /dev/v2v\n"); + return err; + } --+ -+ printk("Xen V2V device installed.\n"); +++ ++ DPRINTK("Xen V2V device installed.\n"); + + return 0; +}