diff options
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/manage.c | 10 | ||||
-rw-r--r-- | drivers/xen/xenfs/xenbus.c | 31 |
2 files changed, 23 insertions, 18 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index db8c4c4ac880..24177272bcb8 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -37,11 +37,19 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; | |||
37 | #ifdef CONFIG_PM_SLEEP | 37 | #ifdef CONFIG_PM_SLEEP |
38 | static int xen_hvm_suspend(void *data) | 38 | static int xen_hvm_suspend(void *data) |
39 | { | 39 | { |
40 | int err; | ||
40 | struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; | 41 | struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; |
41 | int *cancelled = data; | 42 | int *cancelled = data; |
42 | 43 | ||
43 | BUG_ON(!irqs_disabled()); | 44 | BUG_ON(!irqs_disabled()); |
44 | 45 | ||
46 | err = sysdev_suspend(PMSG_SUSPEND); | ||
47 | if (err) { | ||
48 | printk(KERN_ERR "xen_hvm_suspend: sysdev_suspend failed: %d\n", | ||
49 | err); | ||
50 | return err; | ||
51 | } | ||
52 | |||
45 | *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r); | 53 | *cancelled = HYPERVISOR_sched_op(SCHEDOP_shutdown, &r); |
46 | 54 | ||
47 | xen_hvm_post_suspend(*cancelled); | 55 | xen_hvm_post_suspend(*cancelled); |
@@ -53,6 +61,8 @@ static int xen_hvm_suspend(void *data) | |||
53 | xen_timer_resume(); | 61 | xen_timer_resume(); |
54 | } | 62 | } |
55 | 63 | ||
64 | sysdev_resume(); | ||
65 | |||
56 | return 0; | 66 | return 0; |
57 | } | 67 | } |
58 | 68 | ||
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index 1c1236087f78..bbd000f88af7 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c | |||
@@ -122,6 +122,7 @@ static ssize_t xenbus_file_read(struct file *filp, | |||
122 | int ret; | 122 | int ret; |
123 | 123 | ||
124 | mutex_lock(&u->reply_mutex); | 124 | mutex_lock(&u->reply_mutex); |
125 | again: | ||
125 | while (list_empty(&u->read_buffers)) { | 126 | while (list_empty(&u->read_buffers)) { |
126 | mutex_unlock(&u->reply_mutex); | 127 | mutex_unlock(&u->reply_mutex); |
127 | if (filp->f_flags & O_NONBLOCK) | 128 | if (filp->f_flags & O_NONBLOCK) |
@@ -144,7 +145,7 @@ static ssize_t xenbus_file_read(struct file *filp, | |||
144 | i += sz - ret; | 145 | i += sz - ret; |
145 | rb->cons += sz - ret; | 146 | rb->cons += sz - ret; |
146 | 147 | ||
147 | if (ret != sz) { | 148 | if (ret != 0) { |
148 | if (i == 0) | 149 | if (i == 0) |
149 | i = -EFAULT; | 150 | i = -EFAULT; |
150 | goto out; | 151 | goto out; |
@@ -160,6 +161,8 @@ static ssize_t xenbus_file_read(struct file *filp, | |||
160 | struct read_buffer, list); | 161 | struct read_buffer, list); |
161 | } | 162 | } |
162 | } | 163 | } |
164 | if (i == 0) | ||
165 | goto again; | ||
163 | 166 | ||
164 | out: | 167 | out: |
165 | mutex_unlock(&u->reply_mutex); | 168 | mutex_unlock(&u->reply_mutex); |
@@ -407,6 +410,7 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u) | |||
407 | 410 | ||
408 | mutex_lock(&u->reply_mutex); | 411 | mutex_lock(&u->reply_mutex); |
409 | rc = queue_reply(&u->read_buffers, &reply, sizeof(reply)); | 412 | rc = queue_reply(&u->read_buffers, &reply, sizeof(reply)); |
413 | wake_up(&u->read_waitq); | ||
410 | mutex_unlock(&u->reply_mutex); | 414 | mutex_unlock(&u->reply_mutex); |
411 | } | 415 | } |
412 | 416 | ||
@@ -455,7 +459,7 @@ static ssize_t xenbus_file_write(struct file *filp, | |||
455 | 459 | ||
456 | ret = copy_from_user(u->u.buffer + u->len, ubuf, len); | 460 | ret = copy_from_user(u->u.buffer + u->len, ubuf, len); |
457 | 461 | ||
458 | if (ret == len) { | 462 | if (ret != 0) { |
459 | rc = -EFAULT; | 463 | rc = -EFAULT; |
460 | goto out; | 464 | goto out; |
461 | } | 465 | } |
@@ -488,21 +492,6 @@ static ssize_t xenbus_file_write(struct file *filp, | |||
488 | msg_type = u->u.msg.type; | 492 | msg_type = u->u.msg.type; |
489 | 493 | ||
490 | switch (msg_type) { | 494 | switch (msg_type) { |
491 | case XS_TRANSACTION_START: | ||
492 | case XS_TRANSACTION_END: | ||
493 | case XS_DIRECTORY: | ||
494 | case XS_READ: | ||
495 | case XS_GET_PERMS: | ||
496 | case XS_RELEASE: | ||
497 | case XS_GET_DOMAIN_PATH: | ||
498 | case XS_WRITE: | ||
499 | case XS_MKDIR: | ||
500 | case XS_RM: | ||
501 | case XS_SET_PERMS: | ||
502 | /* Send out a transaction */ | ||
503 | ret = xenbus_write_transaction(msg_type, u); | ||
504 | break; | ||
505 | |||
506 | case XS_WATCH: | 495 | case XS_WATCH: |
507 | case XS_UNWATCH: | 496 | case XS_UNWATCH: |
508 | /* (Un)Ask for some path to be watched for changes */ | 497 | /* (Un)Ask for some path to be watched for changes */ |
@@ -510,7 +499,8 @@ static ssize_t xenbus_file_write(struct file *filp, | |||
510 | break; | 499 | break; |
511 | 500 | ||
512 | default: | 501 | default: |
513 | ret = -EINVAL; | 502 | /* Send out a transaction */ |
503 | ret = xenbus_write_transaction(msg_type, u); | ||
514 | break; | 504 | break; |
515 | } | 505 | } |
516 | if (ret != 0) | 506 | if (ret != 0) |
@@ -555,6 +545,7 @@ static int xenbus_file_release(struct inode *inode, struct file *filp) | |||
555 | struct xenbus_file_priv *u = filp->private_data; | 545 | struct xenbus_file_priv *u = filp->private_data; |
556 | struct xenbus_transaction_holder *trans, *tmp; | 546 | struct xenbus_transaction_holder *trans, *tmp; |
557 | struct watch_adapter *watch, *tmp_watch; | 547 | struct watch_adapter *watch, *tmp_watch; |
548 | struct read_buffer *rb, *tmp_rb; | ||
558 | 549 | ||
559 | /* | 550 | /* |
560 | * No need for locking here because there are no other users, | 551 | * No need for locking here because there are no other users, |
@@ -573,6 +564,10 @@ static int xenbus_file_release(struct inode *inode, struct file *filp) | |||
573 | free_watch_adapter(watch); | 564 | free_watch_adapter(watch); |
574 | } | 565 | } |
575 | 566 | ||
567 | list_for_each_entry_safe(rb, tmp_rb, &u->read_buffers, list) { | ||
568 | list_del(&rb->list); | ||
569 | kfree(rb); | ||
570 | } | ||
576 | kfree(u); | 571 | kfree(u); |
577 | 572 | ||
578 | return 0; | 573 | return 0; |