aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/hw_random
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-11 00:31:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-11 00:31:04 -0400
commit801a71a858631109a64bf30b1c480b0a18386605 (patch)
tree2a57e96279c9c06bc4bc30ba192037263c071d5c /drivers/char/hw_random
parent155134fef2b6c7426c3f25ffe84fb3043167c860 (diff)
parenteeec626366ffe558fc3d5685bd2b49a962acf57d (diff)
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull virtio updates from Rusty Russell. * tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: Revert "hwrng: virtio - ensure reads happen after successful probe" virtio: rng: delay hwrng_register() till driver is ready virtio: rng: re-arrange struct elements for better packing virtio: rng: remove unused struct element virtio: Replace DEFINE_PCI_DEVICE_TABLE macro use virtio: console: remove unnecessary null test before debugfs_remove_recursive
Diffstat (limited to 'drivers/char/hw_random')
-rw-r--r--drivers/char/hw_random/core.c6
-rw-r--r--drivers/char/hw_random/virtio-rng.c39
2 files changed, 17 insertions, 28 deletions
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 6e02ec103cc7..aa30a25c8d49 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -81,12 +81,6 @@ static void add_early_randomness(struct hwrng *rng)
81 unsigned char bytes[16]; 81 unsigned char bytes[16];
82 int bytes_read; 82 int bytes_read;
83 83
84 /*
85 * Currently only virtio-rng cannot return data during device
86 * probe, and that's handled in virtio-rng.c itself. If there
87 * are more such devices, this call to rng_get_data can be
88 * made conditional here instead of doing it per-device.
89 */
90 bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1); 84 bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
91 if (bytes_read > 0) 85 if (bytes_read > 0)
92 add_device_randomness(bytes, bytes_read); 86 add_device_randomness(bytes, bytes_read);
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index e9b15bc18b4d..0027137daa56 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -28,17 +28,16 @@
28static DEFINE_IDA(rng_index_ida); 28static DEFINE_IDA(rng_index_ida);
29 29
30struct virtrng_info { 30struct virtrng_info {
31 struct virtio_device *vdev;
32 struct hwrng hwrng; 31 struct hwrng hwrng;
33 struct virtqueue *vq; 32 struct virtqueue *vq;
34 unsigned int data_avail;
35 struct completion have_data; 33 struct completion have_data;
36 bool busy;
37 char name[25]; 34 char name[25];
35 unsigned int data_avail;
38 int index; 36 int index;
37 bool busy;
38 bool hwrng_register_done;
39}; 39};
40 40
41static bool probe_done;
42 41
43static void random_recv_done(struct virtqueue *vq) 42static void random_recv_done(struct virtqueue *vq)
44{ 43{
@@ -69,13 +68,6 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
69 int ret; 68 int ret;
70 struct virtrng_info *vi = (struct virtrng_info *)rng->priv; 69 struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
71 70
72 /*
73 * Don't ask host for data till we're setup. This call can
74 * happen during hwrng_register(), after commit d9e7972619.
75 */
76 if (unlikely(!probe_done))
77 return 0;
78
79 if (!vi->busy) { 71 if (!vi->busy) {
80 vi->busy = true; 72 vi->busy = true;
81 init_completion(&vi->have_data); 73 init_completion(&vi->have_data);
@@ -137,25 +129,17 @@ static int probe_common(struct virtio_device *vdev)
137 return err; 129 return err;
138 } 130 }
139 131
140 err = hwrng_register(&vi->hwrng);
141 if (err) {
142 vdev->config->del_vqs(vdev);
143 vi->vq = NULL;
144 kfree(vi);
145 ida_simple_remove(&rng_index_ida, index);
146 return err;
147 }
148
149 probe_done = true;
150 return 0; 132 return 0;
151} 133}
152 134
153static void remove_common(struct virtio_device *vdev) 135static void remove_common(struct virtio_device *vdev)
154{ 136{
155 struct virtrng_info *vi = vdev->priv; 137 struct virtrng_info *vi = vdev->priv;
138
156 vdev->config->reset(vdev); 139 vdev->config->reset(vdev);
157 vi->busy = false; 140 vi->busy = false;
158 hwrng_unregister(&vi->hwrng); 141 if (vi->hwrng_register_done)
142 hwrng_unregister(&vi->hwrng);
159 vdev->config->del_vqs(vdev); 143 vdev->config->del_vqs(vdev);
160 ida_simple_remove(&rng_index_ida, vi->index); 144 ida_simple_remove(&rng_index_ida, vi->index);
161 kfree(vi); 145 kfree(vi);
@@ -171,6 +155,16 @@ static void virtrng_remove(struct virtio_device *vdev)
171 remove_common(vdev); 155 remove_common(vdev);
172} 156}
173 157
158static void virtrng_scan(struct virtio_device *vdev)
159{
160 struct virtrng_info *vi = vdev->priv;
161 int err;
162
163 err = hwrng_register(&vi->hwrng);
164 if (!err)
165 vi->hwrng_register_done = true;
166}
167
174#ifdef CONFIG_PM_SLEEP 168#ifdef CONFIG_PM_SLEEP
175static int virtrng_freeze(struct virtio_device *vdev) 169static int virtrng_freeze(struct virtio_device *vdev)
176{ 170{
@@ -195,6 +189,7 @@ static struct virtio_driver virtio_rng_driver = {
195 .id_table = id_table, 189 .id_table = id_table,
196 .probe = virtrng_probe, 190 .probe = virtrng_probe,
197 .remove = virtrng_remove, 191 .remove = virtrng_remove,
192 .scan = virtrng_scan,
198#ifdef CONFIG_PM_SLEEP 193#ifdef CONFIG_PM_SLEEP
199 .freeze = virtrng_freeze, 194 .freeze = virtrng_freeze,
200 .restore = virtrng_restore, 195 .restore = virtrng_restore,