#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/rtnetlink.h>
+#include <linux/sched.h>
#include <linux/string.h>
#include <linux/workqueue.h>
} alg;
struct {
+ u32 type;
+ u32 mask;
char name[CRYPTO_MAX_ALG_NAME];
} larval;
char template[CRYPTO_MAX_ALG_NAME];
};
-static void cryptomgr_probe(void *data)
+static void cryptomgr_probe(struct work_struct *work)
{
- struct cryptomgr_param *param = data;
+ struct cryptomgr_param *param =
+ container_of(work, struct cryptomgr_param, work);
struct crypto_template *tmpl;
struct crypto_instance *inst;
+ int err;
tmpl = crypto_lookup_template(param->template);
if (!tmpl)
goto err;
- inst = tmpl->alloc(¶m->alg, sizeof(param->alg));
- if (IS_ERR(inst))
- goto err;
- else if ((err = crypto_register_instance(tmpl, inst))) {
- tmpl->free(inst);
- goto err;
- }
+ do {
+ inst = tmpl->alloc(¶m->alg, sizeof(param->alg));
+ if (IS_ERR(inst))
+ err = PTR_ERR(inst);
+ else if ((err = crypto_register_instance(tmpl, inst)))
+ tmpl->free(inst);
+ } while (err == -EAGAIN && !signal_pending(current));
crypto_tmpl_put(tmpl);
+ if (err)
+ goto err;
+
out:
kfree(param);
return;
err:
- crypto_larval_error(param->larval.name);
+ crypto_larval_error(param->larval.name, param->larval.type,
+ param->larval.mask);
goto out;
}
param->alg.data.name[len] = 0;
memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
+ param->larval.type = larval->alg.cra_flags;
+ param->larval.mask = larval->mask;
- INIT_WORK(¶m->work, cryptomgr_probe, param);
+ INIT_WORK(¶m->work, cryptomgr_probe);
schedule_work(¶m->work);
return NOTIFY_STOP;