From cc8744e12936680478ce82b0f21dbaa272df1447 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 28 May 2012 12:18:40 +0530 Subject: virtio: rng: allow tasks to be killed that are waiting for rng input Use wait_for_completion_killable() instead of wait_for_completion() when waiting for the host to send us entropy. Without this, # cat /dev/hwrng ^C just hangs. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/hw_random/virtio-rng.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/char/hw_random') diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 723725bbb96b..c8a935034218 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -55,6 +55,7 @@ static void register_buffer(u8 *buf, size_t size) static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) { + int ret; if (!busy) { busy = true; @@ -65,7 +66,9 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) if (!wait) return 0; - wait_for_completion(&have_data); + ret = wait_for_completion_killable(&have_data); + if (ret < 0) + return ret; busy = false; -- cgit v1.2.3 From 4476987a9a4525db3ebe29538cc357ca589db4ac Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 28 May 2012 12:18:41 +0530 Subject: virtio: rng: don't wait on host when module is going away No use waiting for input from host when the module is being removed. We're going to remove the vq in the next step anyway, so just perform any other steps for cleanup (currently none). Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/hw_random/virtio-rng.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/char/hw_random') diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index c8a935034218..2dc9ce183cc6 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -109,6 +109,7 @@ static int virtrng_probe(struct virtio_device *vdev) static void __devexit virtrng_remove(struct virtio_device *vdev) { vdev->config->reset(vdev); + busy = false; hwrng_unregister(&virtio_hwrng); vdev->config->del_vqs(vdev); } -- cgit v1.2.3 From 178d855e7810deecb7fa96afdf82ec45b0284233 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 28 May 2012 12:18:42 +0530 Subject: virtio: rng: split out common code in probe / remove for s3/s4 ops The freeze/restore s3/s4 operations will use code that's common to the probe and remove routines. Put the common code in separate funcitons. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/hw_random/virtio-rng.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/char/hw_random') diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 2dc9ce183cc6..a9673a757009 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -88,7 +88,7 @@ static struct hwrng virtio_hwrng = { .read = virtio_read, }; -static int virtrng_probe(struct virtio_device *vdev) +static int probe_common(struct virtio_device *vdev) { int err; @@ -106,7 +106,7 @@ static int virtrng_probe(struct virtio_device *vdev) return 0; } -static void __devexit virtrng_remove(struct virtio_device *vdev) +static void remove_common(struct virtio_device *vdev) { vdev->config->reset(vdev); busy = false; @@ -114,6 +114,16 @@ static void __devexit virtrng_remove(struct virtio_device *vdev) vdev->config->del_vqs(vdev); } +static int virtrng_probe(struct virtio_device *vdev) +{ + return probe_common(vdev); +} + +static void __devexit virtrng_remove(struct virtio_device *vdev) +{ + remove_common(vdev); +} + static struct virtio_device_id id_table[] = { { VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID }, { 0 }, -- cgit v1.2.3 From 0bc1a2ef19b45bb23617b203bc631b44609f17ba Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 28 May 2012 12:18:43 +0530 Subject: virtio: rng: s3/s4 support Unregister from the hwrng interface and remove the vq before entering the S3 or S4 states. Add the vq and re-register with hwrng on restore. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/hw_random/virtio-rng.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/char/hw_random') diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index a9673a757009..5708299507d0 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -124,6 +124,19 @@ static void __devexit virtrng_remove(struct virtio_device *vdev) remove_common(vdev); } +#ifdef CONFIG_PM +static int virtrng_freeze(struct virtio_device *vdev) +{ + remove_common(vdev); + return 0; +} + +static int virtrng_restore(struct virtio_device *vdev) +{ + return probe_common(vdev); +} +#endif + static struct virtio_device_id id_table[] = { { VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID }, { 0 }, @@ -135,6 +148,10 @@ static struct virtio_driver virtio_rng_driver = { .id_table = id_table, .probe = virtrng_probe, .remove = __devexit_p(virtrng_remove), +#ifdef CONFIG_PM + .freeze = virtrng_freeze, + .restore = virtrng_restore, +#endif }; static int __init init(void) -- cgit v1.2.3