aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/atmel-sha.c
diff options
context:
space:
mode:
authorCyrille Pitchen <cyrille.pitchen@atmel.com>2017-02-09 11:51:21 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2017-02-15 00:23:33 -0500
commit19998acb0ff67cb8843668f3b94bdbe6018fa7d8 (patch)
tree30c4a789fee823f608a4496661d05e3094dd955e /drivers/crypto/atmel-sha.c
parentdd3f9f40b58168f91f27ab686c7bae1f35edd3d4 (diff)
crypto: atmel-sha - fix error management in atmel_sha_start()
This patch clarifies and fixes how errors should be handled by atmel_sha_start(). For update operations, the previous code wrongly assumed that (err != -EINPROGRESS) implies (err == 0). It's wrong because that doesn't take the error cases (err < 0) into account. This patch also adds many comments to detail all the possible returned values and what should be done in each case. Especially, when an error occurs, since atmel_sha_complete() has already been called, hence releasing the hardware, atmel_sha_start() must not call atmel_sha_finish_req() later otherwise atmel_sha_complete() would be called a second time. Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/atmel-sha.c')
-rw-r--r--drivers/crypto/atmel-sha.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index bc033178d0e7..a9482023d7d3 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -1106,22 +1106,39 @@ static int atmel_sha_start(struct atmel_sha_dev *dd)
1106 ctx->op, req->nbytes); 1106 ctx->op, req->nbytes);
1107 1107
1108 err = atmel_sha_hw_init(dd); 1108 err = atmel_sha_hw_init(dd);
1109
1110 if (err) 1109 if (err)
1111 goto err1; 1110 return atmel_sha_complete(dd, err);
1111
1112 /*
1113 * atmel_sha_update_req() and atmel_sha_final_req() can return either:
1114 * -EINPROGRESS: the hardware is busy and the SHA driver will resume
1115 * its job later in the done_task.
1116 * This is the main path.
1117 *
1118 * 0: the SHA driver can continue its job then release the hardware
1119 * later, if needed, with atmel_sha_finish_req().
1120 * This is the alternate path.
1121 *
1122 * < 0: an error has occurred so atmel_sha_complete(dd, err) has already
1123 * been called, hence the hardware has been released.
1124 * The SHA driver must stop its job without calling
1125 * atmel_sha_finish_req(), otherwise atmel_sha_complete() would be
1126 * called a second time.
1127 *
1128 * Please note that currently, atmel_sha_final_req() never returns 0.
1129 */
1112 1130
1113 dd->resume = atmel_sha_done; 1131 dd->resume = atmel_sha_done;
1114 if (ctx->op == SHA_OP_UPDATE) { 1132 if (ctx->op == SHA_OP_UPDATE) {
1115 err = atmel_sha_update_req(dd); 1133 err = atmel_sha_update_req(dd);
1116 if (err != -EINPROGRESS && (ctx->flags & SHA_FLAGS_FINUP)) 1134 if (!err && (ctx->flags & SHA_FLAGS_FINUP))
1117 /* no final() after finup() */ 1135 /* no final() after finup() */
1118 err = atmel_sha_final_req(dd); 1136 err = atmel_sha_final_req(dd);
1119 } else if (ctx->op == SHA_OP_FINAL) { 1137 } else if (ctx->op == SHA_OP_FINAL) {
1120 err = atmel_sha_final_req(dd); 1138 err = atmel_sha_final_req(dd);
1121 } 1139 }
1122 1140
1123err1: 1141 if (!err)
1124 if (err != -EINPROGRESS)
1125 /* done_task will not finish it, so do it here */ 1142 /* done_task will not finish it, so do it here */
1126 atmel_sha_finish_req(req, err); 1143 atmel_sha_finish_req(req, err);
1127 1144