Когда то давно писал относительно простенький драйвер char-устройства. В нем чтение блокировалось с помощью wait_event, если буфер был пуст, ну и, соответственно, пробуждалось с помощью wake_up из обработчика прерываний, когда данные поступали в буфер.
Теперь понадобилось сделать нечто похожее, но только читаемые/записываемые данные должны обрабатываться через Crypto API ядра. Глянул примерчики, как этим хозяйством пользоваться. Там, соответственно, вызывается crypto_ablkcipher_encrypt/decrypt, а затем wait_for_complition для ожидания завершения операции. crypto_ablkcipher_encrypt/decrypt стартует поток обработки, который по завершению делает калбэк, по которому надо вызвать complete.
И вроде бы в обеих случаях делается одно и то же. Но в чем тогда разница? И когда следует использовать механизм очередей, а когда complition?