[PATCH 2/3] virtio: rng: delay hwrng_register() till driver is ready

From: Amit Shah
Date: Mon Jul 21 2014 - 05:33:01 EST


Instead of calling hwrng_register() in the probe routing, call it in the
scan routine. This ensures that when hwrng_register() is successful,
and it requests a few random bytes to seed the kernel's pool at init,
we're ready to service that request.

This will also enable us to remove the workaround added previously to
check whether probe was completed, and only then ask for data from the
host. The revert follows in the next commit.

Signed-off-by: Amit Shah <amit.shah@xxxxxxxxxx>
---
drivers/char/hw_random/virtio-rng.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index d8ffebd..32e6373 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -38,6 +38,7 @@ struct virtrng_info {
};

static bool probe_done;
+static bool hwrng_register_done;

static void random_recv_done(struct virtqueue *vq)
{
@@ -136,15 +137,6 @@ static int probe_common(struct virtio_device *vdev)
return err;
}

- err = hwrng_register(&vi->hwrng);
- if (err) {
- vdev->config->del_vqs(vdev);
- vi->vq = NULL;
- kfree(vi);
- ida_simple_remove(&rng_index_ida, index);
- return err;
- }
-
probe_done = true;
return 0;
}
@@ -152,9 +144,11 @@ static int probe_common(struct virtio_device *vdev)
static void remove_common(struct virtio_device *vdev)
{
struct virtrng_info *vi = vdev->priv;
+
vdev->config->reset(vdev);
vi->busy = false;
- hwrng_unregister(&vi->hwrng);
+ if (hwrng_register_done)
+ hwrng_unregister(&vi->hwrng);
vdev->config->del_vqs(vdev);
ida_simple_remove(&rng_index_ida, vi->index);
kfree(vi);
@@ -170,6 +164,16 @@ static void virtrng_remove(struct virtio_device *vdev)
remove_common(vdev);
}

+static void virtrng_scan(struct virtio_device *vdev)
+{
+ struct virtrng_info *vi = vdev->priv;
+ int err;
+
+ err = hwrng_register(&vi->hwrng);
+ if (!err)
+ hwrng_register_done = true;
+}
+
#ifdef CONFIG_PM_SLEEP
static int virtrng_freeze(struct virtio_device *vdev)
{
@@ -194,6 +198,7 @@ static struct virtio_driver virtio_rng_driver = {
.id_table = id_table,
.probe = virtrng_probe,
.remove = virtrng_remove,
+ .scan = virtrng_scan,
#ifdef CONFIG_PM_SLEEP
.freeze = virtrng_freeze,
.restore = virtrng_restore,
--
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/