@@ -112,6 +112,7 @@
#define FLAGS_DMA_READY 6
#define FLAGS_AUTO_XOR 7
#define FLAGS_BE32_SHA1 8
+#define FLAGS_FLUSH 9
/* context flags */
#define FLAGS_FINUP 16
#define FLAGS_SG 17
@@ -996,15 +997,16 @@ static void omap_sham_finish_req(struct ahash_request *req, int err)
ctx->flags |= BIT(FLAGS_ERROR);
}
- /* atomic operation is not needed here */
- dd->flags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) |
- BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY));
-
pm_runtime_mark_last_busy(dd->dev);
pm_runtime_put_autosuspend(dd->dev);
- if (req->base.complete)
+ if (!test_bit(FLAGS_FLUSH, &dd->flags) && req->base.complete)
req->base.complete(&req->base, err);
+
+ /* atomic operation is not needed here */
+ dd->flags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) |
+ BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY) |
+ BIT(FLAGS_FLUSH));
}
static int omap_sham_handle_queue(struct omap_sham_dev *dd,
@@ -1329,6 +1331,54 @@ static void omap_sham_cra_exit(struct crypto_tfm *tfm)
}
}
+static int omap_sham_flush(struct ahash_request *req)
+{
+ struct omap_sham_reqctx *rctx = ahash_request_ctx(req);
+ struct omap_sham_dev *dd = rctx->dd;
+ int ret, len, bs;
+ unsigned long flags;
+
+ bs = get_block_size(rctx);
+
+ len = rctx->bufcnt / bs * bs;
+
+ spin_lock_irqsave(&dd->lock, flags);
+
+ if (test_bit(FLAGS_BUSY, &dd->flags)) {
+ ret = -EINPROGRESS;
+ goto exit_unlock;
+ }
+
+ if (!len) {
+ ret = 0;
+ goto exit_unlock;
+ }
+
+ set_bit(FLAGS_BUSY, &dd->flags);
+
+ spin_unlock_irqrestore(&dd->lock, flags);
+
+ rctx->total = 0;
+
+ ret = omap_sham_hw_init(dd);
+ if (ret)
+ goto exit_unlock;
+
+ set_bit(FLAGS_FLUSH, &dd->flags);
+
+ ret = omap_sham_xmit_cpu(dd, rctx->buffer, len, 0);
+ if (ret == -EINPROGRESS) {
+ memcpy(rctx->buffer, rctx->buffer + len, rctx->bufcnt - len);
+ rctx->bufcnt -= len;
+ }
+
+ return ret;
+
+exit_unlock:
+ spin_unlock_irqrestore(&dd->lock, flags);
+ return ret;
+}
+
static struct ahash_alg algs_sha1_md5[] = {
{
.init = omap_sham_init,
This flushes any full blocks of data from the data buffer. Required for implementing the export/import APIs for the driver, as the flush allows saving a much smaller context; basically only one block of buffer is required. Signed-off-by: Tero Kristo <t-kristo@ti.com> --- drivers/crypto/omap-sham.c | 60 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-)