.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Cryptographic API. |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * Copyright (c) 2010 Nokia Corporation |
---|
7 | 8 | * Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com> |
---|
8 | 9 | * Copyright (c) 2011 Texas Instruments Incorporated |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of the GNU General Public License version 2 as published |
---|
12 | | - * by the Free Software Foundation. |
---|
13 | 10 | * |
---|
14 | 11 | * Some ideas are from old omap-sha1-md5.c driver. |
---|
15 | 12 | */ |
---|
.. | .. |
---|
36 | 33 | #include <linux/of_irq.h> |
---|
37 | 34 | #include <linux/delay.h> |
---|
38 | 35 | #include <linux/crypto.h> |
---|
39 | | -#include <linux/cryptohash.h> |
---|
40 | 36 | #include <crypto/scatterwalk.h> |
---|
41 | 37 | #include <crypto/algapi.h> |
---|
42 | 38 | #include <crypto/sha.h> |
---|
43 | 39 | #include <crypto/hash.h> |
---|
44 | 40 | #include <crypto/hmac.h> |
---|
45 | 41 | #include <crypto/internal/hash.h> |
---|
| 42 | +#include <crypto/engine.h> |
---|
46 | 43 | |
---|
47 | 44 | #define MD5_DIGEST_SIZE 16 |
---|
48 | 45 | |
---|
.. | .. |
---|
104 | 101 | #define DEFAULT_AUTOSUSPEND_DELAY 1000 |
---|
105 | 102 | |
---|
106 | 103 | /* mostly device flags */ |
---|
107 | | -#define FLAGS_BUSY 0 |
---|
108 | 104 | #define FLAGS_FINAL 1 |
---|
109 | 105 | #define FLAGS_DMA_ACTIVE 2 |
---|
110 | 106 | #define FLAGS_OUTPUT_READY 3 |
---|
.. | .. |
---|
115 | 111 | #define FLAGS_BE32_SHA1 8 |
---|
116 | 112 | #define FLAGS_SGS_COPIED 9 |
---|
117 | 113 | #define FLAGS_SGS_ALLOCED 10 |
---|
| 114 | +#define FLAGS_HUGE 11 |
---|
| 115 | + |
---|
118 | 116 | /* context flags */ |
---|
119 | 117 | #define FLAGS_FINUP 16 |
---|
120 | 118 | |
---|
.. | .. |
---|
139 | 137 | #define BUFLEN SHA512_BLOCK_SIZE |
---|
140 | 138 | #define OMAP_SHA_DMA_THRESHOLD 256 |
---|
141 | 139 | |
---|
| 140 | +#define OMAP_SHA_MAX_DMA_LEN (1024 * 2048) |
---|
| 141 | + |
---|
142 | 142 | struct omap_sham_dev; |
---|
143 | 143 | |
---|
144 | 144 | struct omap_sham_reqctx { |
---|
145 | 145 | struct omap_sham_dev *dd; |
---|
146 | 146 | unsigned long flags; |
---|
147 | | - unsigned long op; |
---|
| 147 | + u8 op; |
---|
148 | 148 | |
---|
149 | 149 | u8 digest[SHA512_DIGEST_SIZE] OMAP_ALIGNED; |
---|
150 | 150 | size_t digcnt; |
---|
.. | .. |
---|
158 | 158 | int sg_len; |
---|
159 | 159 | unsigned int total; /* total request */ |
---|
160 | 160 | |
---|
161 | | - u8 buffer[0] OMAP_ALIGNED; |
---|
| 161 | + u8 buffer[] OMAP_ALIGNED; |
---|
162 | 162 | }; |
---|
163 | 163 | |
---|
164 | 164 | struct omap_sham_hmac_ctx { |
---|
.. | .. |
---|
168 | 168 | }; |
---|
169 | 169 | |
---|
170 | 170 | struct omap_sham_ctx { |
---|
| 171 | + struct crypto_engine_ctx enginectx; |
---|
171 | 172 | unsigned long flags; |
---|
172 | 173 | |
---|
173 | 174 | /* fallback stuff */ |
---|
174 | 175 | struct crypto_shash *fallback; |
---|
175 | 176 | |
---|
176 | | - struct omap_sham_hmac_ctx base[0]; |
---|
| 177 | + struct omap_sham_hmac_ctx base[]; |
---|
177 | 178 | }; |
---|
178 | 179 | |
---|
179 | 180 | #define OMAP_SHAM_QUEUE_LENGTH 10 |
---|
.. | .. |
---|
219 | 220 | struct device *dev; |
---|
220 | 221 | void __iomem *io_base; |
---|
221 | 222 | int irq; |
---|
222 | | - spinlock_t lock; |
---|
223 | 223 | int err; |
---|
224 | 224 | struct dma_chan *dma_lch; |
---|
225 | 225 | struct tasklet_struct done_task; |
---|
.. | .. |
---|
230 | 230 | int fallback_sz; |
---|
231 | 231 | struct crypto_queue queue; |
---|
232 | 232 | struct ahash_request *req; |
---|
| 233 | + struct crypto_engine *engine; |
---|
233 | 234 | |
---|
234 | 235 | const struct omap_sham_pdata *pdata; |
---|
235 | 236 | }; |
---|
.. | .. |
---|
244 | 245 | .dev_list = LIST_HEAD_INIT(sham.dev_list), |
---|
245 | 246 | .lock = __SPIN_LOCK_UNLOCKED(sham.lock), |
---|
246 | 247 | }; |
---|
| 248 | + |
---|
| 249 | +static int omap_sham_enqueue(struct ahash_request *req, unsigned int op); |
---|
| 250 | +static void omap_sham_finish_req(struct ahash_request *req, int err); |
---|
247 | 251 | |
---|
248 | 252 | static inline u32 omap_sham_read(struct omap_sham_dev *dd, u32 offset) |
---|
249 | 253 | { |
---|
.. | .. |
---|
357 | 361 | |
---|
358 | 362 | if (big_endian) |
---|
359 | 363 | for (i = 0; i < d; i++) |
---|
360 | | - hash[i] = be32_to_cpu(in[i]); |
---|
| 364 | + hash[i] = be32_to_cpup((__be32 *)in + i); |
---|
361 | 365 | else |
---|
362 | 366 | for (i = 0; i < d; i++) |
---|
363 | | - hash[i] = le32_to_cpu(in[i]); |
---|
| 367 | + hash[i] = le32_to_cpup((__le32 *)in + i); |
---|
364 | 368 | } |
---|
365 | 369 | |
---|
366 | 370 | static int omap_sham_hw_init(struct omap_sham_dev *dd) |
---|
367 | 371 | { |
---|
368 | 372 | int err; |
---|
369 | 373 | |
---|
370 | | - err = pm_runtime_get_sync(dd->dev); |
---|
| 374 | + err = pm_runtime_resume_and_get(dd->dev); |
---|
371 | 375 | if (err < 0) { |
---|
372 | 376 | dev_err(dd->dev, "failed to get sync: %d\n", err); |
---|
373 | 377 | return err; |
---|
.. | .. |
---|
525 | 529 | int mlen; |
---|
526 | 530 | struct sg_mapping_iter mi; |
---|
527 | 531 | |
---|
528 | | - dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n", |
---|
| 532 | + dev_dbg(dd->dev, "xmit_cpu: digcnt: %zd, length: %zd, final: %d\n", |
---|
529 | 533 | ctx->digcnt, length, final); |
---|
530 | 534 | |
---|
531 | 535 | dd->pdata->write_ctrl(dd, length, final, 0); |
---|
.. | .. |
---|
591 | 595 | struct dma_slave_config cfg; |
---|
592 | 596 | int ret; |
---|
593 | 597 | |
---|
594 | | - dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n", |
---|
| 598 | + dev_dbg(dd->dev, "xmit_dma: digcnt: %zd, length: %zd, final: %d\n", |
---|
595 | 599 | ctx->digcnt, length, final); |
---|
596 | 600 | |
---|
597 | 601 | if (!dma_map_sg(dd->dev, ctx->sg, ctx->sg_len, DMA_TO_DEVICE)) { |
---|
.. | .. |
---|
648 | 652 | struct scatterlist *tmp; |
---|
649 | 653 | int offset = ctx->offset; |
---|
650 | 654 | |
---|
| 655 | + ctx->total = new_len; |
---|
| 656 | + |
---|
651 | 657 | if (ctx->bufcnt) |
---|
652 | 658 | n++; |
---|
653 | 659 | |
---|
.. | .. |
---|
665 | 671 | sg_set_buf(tmp, ctx->dd->xmit_buf, ctx->bufcnt); |
---|
666 | 672 | tmp = sg_next(tmp); |
---|
667 | 673 | ctx->sg_len++; |
---|
| 674 | + new_len -= ctx->bufcnt; |
---|
668 | 675 | } |
---|
669 | 676 | |
---|
670 | 677 | while (sg && new_len) { |
---|
671 | 678 | int len = sg->length - offset; |
---|
672 | 679 | |
---|
673 | | - if (offset) { |
---|
| 680 | + if (len <= 0) { |
---|
674 | 681 | offset -= sg->length; |
---|
675 | | - if (offset < 0) |
---|
676 | | - offset = 0; |
---|
| 682 | + sg = sg_next(sg); |
---|
| 683 | + continue; |
---|
677 | 684 | } |
---|
678 | 685 | |
---|
679 | 686 | if (new_len < len) |
---|
.. | .. |
---|
681 | 688 | |
---|
682 | 689 | if (len > 0) { |
---|
683 | 690 | new_len -= len; |
---|
684 | | - sg_set_page(tmp, sg_page(sg), len, sg->offset); |
---|
685 | | - if (new_len <= 0) |
---|
686 | | - sg_mark_end(tmp); |
---|
687 | | - tmp = sg_next(tmp); |
---|
| 691 | + sg_set_page(tmp, sg_page(sg), len, sg->offset + offset); |
---|
| 692 | + offset = 0; |
---|
| 693 | + ctx->offset = 0; |
---|
688 | 694 | ctx->sg_len++; |
---|
| 695 | + if (new_len <= 0) |
---|
| 696 | + break; |
---|
| 697 | + tmp = sg_next(tmp); |
---|
689 | 698 | } |
---|
690 | 699 | |
---|
691 | 700 | sg = sg_next(sg); |
---|
692 | 701 | } |
---|
693 | 702 | |
---|
| 703 | + if (tmp) |
---|
| 704 | + sg_mark_end(tmp); |
---|
| 705 | + |
---|
694 | 706 | set_bit(FLAGS_SGS_ALLOCED, &ctx->dd->flags); |
---|
695 | 707 | |
---|
| 708 | + ctx->offset += new_len - ctx->bufcnt; |
---|
696 | 709 | ctx->bufcnt = 0; |
---|
697 | 710 | |
---|
698 | 711 | return 0; |
---|
699 | 712 | } |
---|
700 | 713 | |
---|
701 | 714 | static int omap_sham_copy_sgs(struct omap_sham_reqctx *ctx, |
---|
702 | | - struct scatterlist *sg, int bs, int new_len) |
---|
| 715 | + struct scatterlist *sg, int bs, |
---|
| 716 | + unsigned int new_len) |
---|
703 | 717 | { |
---|
704 | 718 | int pages; |
---|
705 | 719 | void *buf; |
---|
706 | | - int len; |
---|
707 | 720 | |
---|
708 | | - len = new_len + ctx->bufcnt; |
---|
709 | | - |
---|
710 | | - pages = get_order(ctx->total); |
---|
| 721 | + pages = get_order(new_len); |
---|
711 | 722 | |
---|
712 | 723 | buf = (void *)__get_free_pages(GFP_ATOMIC, pages); |
---|
713 | 724 | if (!buf) { |
---|
.. | .. |
---|
719 | 730 | memcpy(buf, ctx->dd->xmit_buf, ctx->bufcnt); |
---|
720 | 731 | |
---|
721 | 732 | scatterwalk_map_and_copy(buf + ctx->bufcnt, sg, ctx->offset, |
---|
722 | | - ctx->total - ctx->bufcnt, 0); |
---|
| 733 | + min(new_len, ctx->total) - ctx->bufcnt, 0); |
---|
723 | 734 | sg_init_table(ctx->sgl, 1); |
---|
724 | | - sg_set_buf(ctx->sgl, buf, len); |
---|
| 735 | + sg_set_buf(ctx->sgl, buf, new_len); |
---|
725 | 736 | ctx->sg = ctx->sgl; |
---|
726 | 737 | set_bit(FLAGS_SGS_COPIED, &ctx->dd->flags); |
---|
727 | 738 | ctx->sg_len = 1; |
---|
| 739 | + ctx->offset += new_len - ctx->bufcnt; |
---|
728 | 740 | ctx->bufcnt = 0; |
---|
729 | | - ctx->offset = 0; |
---|
| 741 | + ctx->total = new_len; |
---|
730 | 742 | |
---|
731 | 743 | return 0; |
---|
732 | 744 | } |
---|
.. | .. |
---|
741 | 753 | struct scatterlist *sg_tmp = sg; |
---|
742 | 754 | int new_len; |
---|
743 | 755 | int offset = rctx->offset; |
---|
| 756 | + int bufcnt = rctx->bufcnt; |
---|
744 | 757 | |
---|
745 | | - if (!sg || !sg->length || !nbytes) |
---|
| 758 | + if (!sg || !sg->length || !nbytes) { |
---|
| 759 | + if (bufcnt) { |
---|
| 760 | + bufcnt = DIV_ROUND_UP(bufcnt, bs) * bs; |
---|
| 761 | + sg_init_table(rctx->sgl, 1); |
---|
| 762 | + sg_set_buf(rctx->sgl, rctx->dd->xmit_buf, bufcnt); |
---|
| 763 | + rctx->sg = rctx->sgl; |
---|
| 764 | + rctx->sg_len = 1; |
---|
| 765 | + } |
---|
| 766 | + |
---|
746 | 767 | return 0; |
---|
| 768 | + } |
---|
747 | 769 | |
---|
748 | 770 | new_len = nbytes; |
---|
749 | 771 | |
---|
.. | .. |
---|
755 | 777 | else |
---|
756 | 778 | new_len = (new_len - 1) / bs * bs; |
---|
757 | 779 | |
---|
| 780 | + if (!new_len) |
---|
| 781 | + return 0; |
---|
| 782 | + |
---|
758 | 783 | if (nbytes != new_len) |
---|
759 | 784 | list_ok = false; |
---|
760 | 785 | |
---|
761 | 786 | while (nbytes > 0 && sg_tmp) { |
---|
762 | 787 | n++; |
---|
| 788 | + |
---|
| 789 | + if (bufcnt) { |
---|
| 790 | + if (!IS_ALIGNED(bufcnt, bs)) { |
---|
| 791 | + aligned = false; |
---|
| 792 | + break; |
---|
| 793 | + } |
---|
| 794 | + nbytes -= bufcnt; |
---|
| 795 | + bufcnt = 0; |
---|
| 796 | + if (!nbytes) |
---|
| 797 | + list_ok = false; |
---|
| 798 | + |
---|
| 799 | + continue; |
---|
| 800 | + } |
---|
763 | 801 | |
---|
764 | 802 | #ifdef CONFIG_ZONE_DMA |
---|
765 | 803 | if (page_zonenum(sg_page(sg_tmp)) != ZONE_DMA) { |
---|
.. | .. |
---|
798 | 836 | } |
---|
799 | 837 | } |
---|
800 | 838 | |
---|
| 839 | + if (new_len > OMAP_SHA_MAX_DMA_LEN) { |
---|
| 840 | + new_len = OMAP_SHA_MAX_DMA_LEN; |
---|
| 841 | + aligned = false; |
---|
| 842 | + } |
---|
| 843 | + |
---|
801 | 844 | if (!aligned) |
---|
802 | 845 | return omap_sham_copy_sgs(rctx, sg, bs, new_len); |
---|
803 | 846 | else if (!list_ok) |
---|
804 | 847 | return omap_sham_copy_sg_lists(rctx, sg, bs, new_len); |
---|
805 | 848 | |
---|
| 849 | + rctx->total = new_len; |
---|
| 850 | + rctx->offset += new_len; |
---|
806 | 851 | rctx->sg_len = n; |
---|
807 | | - rctx->sg = sg; |
---|
| 852 | + if (rctx->bufcnt) { |
---|
| 853 | + sg_init_table(rctx->sgl, 2); |
---|
| 854 | + sg_set_buf(rctx->sgl, rctx->dd->xmit_buf, rctx->bufcnt); |
---|
| 855 | + sg_chain(rctx->sgl, 2, sg); |
---|
| 856 | + rctx->sg = rctx->sgl; |
---|
| 857 | + } else { |
---|
| 858 | + rctx->sg = sg; |
---|
| 859 | + } |
---|
808 | 860 | |
---|
809 | 861 | return 0; |
---|
810 | 862 | } |
---|
811 | 863 | |
---|
812 | | -static int omap_sham_prepare_request(struct ahash_request *req, bool update) |
---|
| 864 | +static int omap_sham_prepare_request(struct crypto_engine *engine, void *areq) |
---|
813 | 865 | { |
---|
| 866 | + struct ahash_request *req = container_of(areq, struct ahash_request, |
---|
| 867 | + base); |
---|
814 | 868 | struct omap_sham_reqctx *rctx = ahash_request_ctx(req); |
---|
815 | 869 | int bs; |
---|
816 | 870 | int ret; |
---|
817 | | - int nbytes; |
---|
| 871 | + unsigned int nbytes; |
---|
818 | 872 | bool final = rctx->flags & BIT(FLAGS_FINUP); |
---|
819 | | - int xmit_len, hash_later; |
---|
| 873 | + bool update = rctx->op == OP_UPDATE; |
---|
| 874 | + int hash_later; |
---|
820 | 875 | |
---|
821 | 876 | bs = get_block_size(rctx); |
---|
822 | 877 | |
---|
| 878 | + nbytes = rctx->bufcnt; |
---|
| 879 | + |
---|
823 | 880 | if (update) |
---|
824 | | - nbytes = req->nbytes; |
---|
825 | | - else |
---|
826 | | - nbytes = 0; |
---|
| 881 | + nbytes += req->nbytes - rctx->offset; |
---|
827 | 882 | |
---|
828 | | - rctx->total = nbytes + rctx->bufcnt; |
---|
| 883 | + dev_dbg(rctx->dd->dev, |
---|
| 884 | + "%s: nbytes=%d, bs=%d, total=%d, offset=%d, bufcnt=%zd\n", |
---|
| 885 | + __func__, nbytes, bs, rctx->total, rctx->offset, |
---|
| 886 | + rctx->bufcnt); |
---|
829 | 887 | |
---|
830 | | - if (!rctx->total) |
---|
| 888 | + if (!nbytes) |
---|
831 | 889 | return 0; |
---|
832 | 890 | |
---|
833 | | - if (nbytes && (!IS_ALIGNED(rctx->bufcnt, bs))) { |
---|
| 891 | + rctx->total = nbytes; |
---|
| 892 | + |
---|
| 893 | + if (update && req->nbytes && (!IS_ALIGNED(rctx->bufcnt, bs))) { |
---|
834 | 894 | int len = bs - rctx->bufcnt % bs; |
---|
835 | 895 | |
---|
836 | | - if (len > nbytes) |
---|
837 | | - len = nbytes; |
---|
| 896 | + if (len > req->nbytes) |
---|
| 897 | + len = req->nbytes; |
---|
838 | 898 | scatterwalk_map_and_copy(rctx->buffer + rctx->bufcnt, req->src, |
---|
839 | 899 | 0, len, 0); |
---|
840 | 900 | rctx->bufcnt += len; |
---|
841 | | - nbytes -= len; |
---|
842 | 901 | rctx->offset = len; |
---|
843 | 902 | } |
---|
844 | 903 | |
---|
.. | .. |
---|
849 | 908 | if (ret) |
---|
850 | 909 | return ret; |
---|
851 | 910 | |
---|
852 | | - xmit_len = rctx->total; |
---|
853 | | - |
---|
854 | | - if (!IS_ALIGNED(xmit_len, bs)) { |
---|
855 | | - if (final) |
---|
856 | | - xmit_len = DIV_ROUND_UP(xmit_len, bs) * bs; |
---|
857 | | - else |
---|
858 | | - xmit_len = xmit_len / bs * bs; |
---|
859 | | - } else if (!final) { |
---|
860 | | - xmit_len -= bs; |
---|
861 | | - } |
---|
862 | | - |
---|
863 | | - hash_later = rctx->total - xmit_len; |
---|
| 911 | + hash_later = nbytes - rctx->total; |
---|
864 | 912 | if (hash_later < 0) |
---|
865 | 913 | hash_later = 0; |
---|
866 | 914 | |
---|
867 | | - if (rctx->bufcnt && nbytes) { |
---|
868 | | - /* have data from previous operation and current */ |
---|
869 | | - sg_init_table(rctx->sgl, 2); |
---|
870 | | - sg_set_buf(rctx->sgl, rctx->dd->xmit_buf, rctx->bufcnt); |
---|
871 | | - |
---|
872 | | - sg_chain(rctx->sgl, 2, req->src); |
---|
873 | | - |
---|
874 | | - rctx->sg = rctx->sgl; |
---|
875 | | - |
---|
876 | | - rctx->sg_len++; |
---|
877 | | - } else if (rctx->bufcnt) { |
---|
878 | | - /* have buffered data only */ |
---|
879 | | - sg_init_table(rctx->sgl, 1); |
---|
880 | | - sg_set_buf(rctx->sgl, rctx->dd->xmit_buf, xmit_len); |
---|
881 | | - |
---|
882 | | - rctx->sg = rctx->sgl; |
---|
883 | | - |
---|
884 | | - rctx->sg_len = 1; |
---|
885 | | - } |
---|
886 | | - |
---|
887 | | - if (hash_later) { |
---|
888 | | - int offset = 0; |
---|
889 | | - |
---|
890 | | - if (hash_later > req->nbytes) { |
---|
891 | | - memcpy(rctx->buffer, rctx->buffer + xmit_len, |
---|
892 | | - hash_later - req->nbytes); |
---|
893 | | - offset = hash_later - req->nbytes; |
---|
894 | | - } |
---|
895 | | - |
---|
896 | | - if (req->nbytes) { |
---|
897 | | - scatterwalk_map_and_copy(rctx->buffer + offset, |
---|
898 | | - req->src, |
---|
899 | | - offset + req->nbytes - |
---|
900 | | - hash_later, hash_later, 0); |
---|
901 | | - } |
---|
| 915 | + if (hash_later && hash_later <= rctx->buflen) { |
---|
| 916 | + scatterwalk_map_and_copy(rctx->buffer, |
---|
| 917 | + req->src, |
---|
| 918 | + req->nbytes - hash_later, |
---|
| 919 | + hash_later, 0); |
---|
902 | 920 | |
---|
903 | 921 | rctx->bufcnt = hash_later; |
---|
904 | 922 | } else { |
---|
905 | 923 | rctx->bufcnt = 0; |
---|
906 | 924 | } |
---|
907 | 925 | |
---|
908 | | - if (!final) |
---|
909 | | - rctx->total = xmit_len; |
---|
| 926 | + if (hash_later > rctx->buflen) |
---|
| 927 | + set_bit(FLAGS_HUGE, &rctx->dd->flags); |
---|
| 928 | + |
---|
| 929 | + rctx->total = min(nbytes, rctx->total); |
---|
910 | 930 | |
---|
911 | 931 | return 0; |
---|
912 | 932 | } |
---|
.. | .. |
---|
922 | 942 | return 0; |
---|
923 | 943 | } |
---|
924 | 944 | |
---|
925 | | -struct omap_sham_dev *omap_sham_find_dev(struct omap_sham_reqctx *ctx) |
---|
| 945 | +static struct omap_sham_dev *omap_sham_find_dev(struct omap_sham_reqctx *ctx) |
---|
926 | 946 | { |
---|
927 | 947 | struct omap_sham_dev *dd; |
---|
928 | 948 | |
---|
.. | .. |
---|
1010 | 1030 | struct ahash_request *req = dd->req; |
---|
1011 | 1031 | struct omap_sham_reqctx *ctx = ahash_request_ctx(req); |
---|
1012 | 1032 | int err; |
---|
1013 | | - bool final = ctx->flags & BIT(FLAGS_FINUP); |
---|
| 1033 | + bool final = (ctx->flags & BIT(FLAGS_FINUP)) && |
---|
| 1034 | + !(dd->flags & BIT(FLAGS_HUGE)); |
---|
1014 | 1035 | |
---|
1015 | | - dev_dbg(dd->dev, "update_req: total: %u, digcnt: %d, finup: %d\n", |
---|
1016 | | - ctx->total, ctx->digcnt, (ctx->flags & BIT(FLAGS_FINUP)) != 0); |
---|
| 1036 | + dev_dbg(dd->dev, "update_req: total: %u, digcnt: %zd, final: %d", |
---|
| 1037 | + ctx->total, ctx->digcnt, final); |
---|
1017 | 1038 | |
---|
1018 | 1039 | if (ctx->total < get_block_size(ctx) || |
---|
1019 | 1040 | ctx->total < dd->fallback_sz) |
---|
.. | .. |
---|
1025 | 1046 | err = omap_sham_xmit_dma(dd, ctx->total, final); |
---|
1026 | 1047 | |
---|
1027 | 1048 | /* wait for dma completion before can take more data */ |
---|
1028 | | - dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt); |
---|
| 1049 | + dev_dbg(dd->dev, "update: err: %d, digcnt: %zd\n", err, ctx->digcnt); |
---|
1029 | 1050 | |
---|
1030 | 1051 | return err; |
---|
1031 | 1052 | } |
---|
.. | .. |
---|
1035 | 1056 | struct ahash_request *req = dd->req; |
---|
1036 | 1057 | struct omap_sham_reqctx *ctx = ahash_request_ctx(req); |
---|
1037 | 1058 | int err = 0, use_dma = 1; |
---|
| 1059 | + |
---|
| 1060 | + if (dd->flags & BIT(FLAGS_HUGE)) |
---|
| 1061 | + return 0; |
---|
1038 | 1062 | |
---|
1039 | 1063 | if ((ctx->total <= get_block_size(ctx)) || dd->polling_mode) |
---|
1040 | 1064 | /* |
---|
.. | .. |
---|
1055 | 1079 | return err; |
---|
1056 | 1080 | } |
---|
1057 | 1081 | |
---|
| 1082 | +static int omap_sham_hash_one_req(struct crypto_engine *engine, void *areq) |
---|
| 1083 | +{ |
---|
| 1084 | + struct ahash_request *req = container_of(areq, struct ahash_request, |
---|
| 1085 | + base); |
---|
| 1086 | + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); |
---|
| 1087 | + struct omap_sham_dev *dd = ctx->dd; |
---|
| 1088 | + int err; |
---|
| 1089 | + bool final = (ctx->flags & BIT(FLAGS_FINUP)) && |
---|
| 1090 | + !(dd->flags & BIT(FLAGS_HUGE)); |
---|
| 1091 | + |
---|
| 1092 | + dev_dbg(dd->dev, "hash-one: op: %u, total: %u, digcnt: %zd, final: %d", |
---|
| 1093 | + ctx->op, ctx->total, ctx->digcnt, final); |
---|
| 1094 | + |
---|
| 1095 | + dd->req = req; |
---|
| 1096 | + |
---|
| 1097 | + err = omap_sham_hw_init(dd); |
---|
| 1098 | + if (err) |
---|
| 1099 | + return err; |
---|
| 1100 | + |
---|
| 1101 | + if (ctx->digcnt) |
---|
| 1102 | + dd->pdata->copy_hash(req, 0); |
---|
| 1103 | + |
---|
| 1104 | + if (ctx->op == OP_UPDATE) |
---|
| 1105 | + err = omap_sham_update_req(dd); |
---|
| 1106 | + else if (ctx->op == OP_FINAL) |
---|
| 1107 | + err = omap_sham_final_req(dd); |
---|
| 1108 | + |
---|
| 1109 | + if (err != -EINPROGRESS) |
---|
| 1110 | + omap_sham_finish_req(req, err); |
---|
| 1111 | + |
---|
| 1112 | + return 0; |
---|
| 1113 | +} |
---|
| 1114 | + |
---|
1058 | 1115 | static int omap_sham_finish_hmac(struct ahash_request *req) |
---|
1059 | 1116 | { |
---|
1060 | 1117 | struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); |
---|
.. | .. |
---|
1064 | 1121 | SHASH_DESC_ON_STACK(shash, bctx->shash); |
---|
1065 | 1122 | |
---|
1066 | 1123 | shash->tfm = bctx->shash; |
---|
1067 | | - shash->flags = 0; /* not CRYPTO_TFM_REQ_MAY_SLEEP */ |
---|
1068 | 1124 | |
---|
1069 | 1125 | return crypto_shash_init(shash) ?: |
---|
1070 | 1126 | crypto_shash_update(shash, bctx->opad, bs) ?: |
---|
.. | .. |
---|
1084 | 1140 | err = omap_sham_finish_hmac(req); |
---|
1085 | 1141 | } |
---|
1086 | 1142 | |
---|
1087 | | - dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt); |
---|
| 1143 | + dev_dbg(dd->dev, "digcnt: %zd, bufcnt: %zd\n", ctx->digcnt, ctx->bufcnt); |
---|
1088 | 1144 | |
---|
1089 | 1145 | return err; |
---|
1090 | 1146 | } |
---|
.. | .. |
---|
1096 | 1152 | |
---|
1097 | 1153 | if (test_bit(FLAGS_SGS_COPIED, &dd->flags)) |
---|
1098 | 1154 | free_pages((unsigned long)sg_virt(ctx->sg), |
---|
1099 | | - get_order(ctx->sg->length + ctx->bufcnt)); |
---|
| 1155 | + get_order(ctx->sg->length)); |
---|
1100 | 1156 | |
---|
1101 | 1157 | if (test_bit(FLAGS_SGS_ALLOCED, &dd->flags)) |
---|
1102 | 1158 | kfree(ctx->sg); |
---|
1103 | 1159 | |
---|
1104 | 1160 | ctx->sg = NULL; |
---|
1105 | 1161 | |
---|
1106 | | - dd->flags &= ~(BIT(FLAGS_SGS_ALLOCED) | BIT(FLAGS_SGS_COPIED)); |
---|
| 1162 | + dd->flags &= ~(BIT(FLAGS_SGS_ALLOCED) | BIT(FLAGS_SGS_COPIED) | |
---|
| 1163 | + BIT(FLAGS_CPU) | BIT(FLAGS_DMA_READY) | |
---|
| 1164 | + BIT(FLAGS_OUTPUT_READY)); |
---|
| 1165 | + |
---|
| 1166 | + if (!err) |
---|
| 1167 | + dd->pdata->copy_hash(req, 1); |
---|
| 1168 | + |
---|
| 1169 | + if (dd->flags & BIT(FLAGS_HUGE)) { |
---|
| 1170 | + /* Re-enqueue the request */ |
---|
| 1171 | + omap_sham_enqueue(req, ctx->op); |
---|
| 1172 | + return; |
---|
| 1173 | + } |
---|
1107 | 1174 | |
---|
1108 | 1175 | if (!err) { |
---|
1109 | | - dd->pdata->copy_hash(req, 1); |
---|
1110 | 1176 | if (test_bit(FLAGS_FINAL, &dd->flags)) |
---|
1111 | 1177 | err = omap_sham_finish(req); |
---|
1112 | 1178 | } else { |
---|
.. | .. |
---|
1114 | 1180 | } |
---|
1115 | 1181 | |
---|
1116 | 1182 | /* atomic operation is not needed here */ |
---|
1117 | | - dd->flags &= ~(BIT(FLAGS_BUSY) | BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) | |
---|
| 1183 | + dd->flags &= ~(BIT(FLAGS_FINAL) | BIT(FLAGS_CPU) | |
---|
1118 | 1184 | BIT(FLAGS_DMA_READY) | BIT(FLAGS_OUTPUT_READY)); |
---|
1119 | 1185 | |
---|
1120 | 1186 | pm_runtime_mark_last_busy(dd->dev); |
---|
1121 | 1187 | pm_runtime_put_autosuspend(dd->dev); |
---|
1122 | 1188 | |
---|
1123 | | - if (req->base.complete) |
---|
1124 | | - req->base.complete(&req->base, err); |
---|
| 1189 | + ctx->offset = 0; |
---|
| 1190 | + |
---|
| 1191 | + crypto_finalize_hash_request(dd->engine, req, err); |
---|
1125 | 1192 | } |
---|
1126 | 1193 | |
---|
1127 | 1194 | static int omap_sham_handle_queue(struct omap_sham_dev *dd, |
---|
1128 | 1195 | struct ahash_request *req) |
---|
1129 | 1196 | { |
---|
1130 | | - struct crypto_async_request *async_req, *backlog; |
---|
1131 | | - struct omap_sham_reqctx *ctx; |
---|
1132 | | - unsigned long flags; |
---|
1133 | | - int err = 0, ret = 0; |
---|
1134 | | - |
---|
1135 | | -retry: |
---|
1136 | | - spin_lock_irqsave(&dd->lock, flags); |
---|
1137 | | - if (req) |
---|
1138 | | - ret = ahash_enqueue_request(&dd->queue, req); |
---|
1139 | | - if (test_bit(FLAGS_BUSY, &dd->flags)) { |
---|
1140 | | - spin_unlock_irqrestore(&dd->lock, flags); |
---|
1141 | | - return ret; |
---|
1142 | | - } |
---|
1143 | | - backlog = crypto_get_backlog(&dd->queue); |
---|
1144 | | - async_req = crypto_dequeue_request(&dd->queue); |
---|
1145 | | - if (async_req) |
---|
1146 | | - set_bit(FLAGS_BUSY, &dd->flags); |
---|
1147 | | - spin_unlock_irqrestore(&dd->lock, flags); |
---|
1148 | | - |
---|
1149 | | - if (!async_req) |
---|
1150 | | - return ret; |
---|
1151 | | - |
---|
1152 | | - if (backlog) |
---|
1153 | | - backlog->complete(backlog, -EINPROGRESS); |
---|
1154 | | - |
---|
1155 | | - req = ahash_request_cast(async_req); |
---|
1156 | | - dd->req = req; |
---|
1157 | | - ctx = ahash_request_ctx(req); |
---|
1158 | | - |
---|
1159 | | - err = omap_sham_prepare_request(req, ctx->op == OP_UPDATE); |
---|
1160 | | - if (err || !ctx->total) |
---|
1161 | | - goto err1; |
---|
1162 | | - |
---|
1163 | | - dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n", |
---|
1164 | | - ctx->op, req->nbytes); |
---|
1165 | | - |
---|
1166 | | - err = omap_sham_hw_init(dd); |
---|
1167 | | - if (err) |
---|
1168 | | - goto err1; |
---|
1169 | | - |
---|
1170 | | - if (ctx->digcnt) |
---|
1171 | | - /* request has changed - restore hash */ |
---|
1172 | | - dd->pdata->copy_hash(req, 0); |
---|
1173 | | - |
---|
1174 | | - if (ctx->op == OP_UPDATE) { |
---|
1175 | | - err = omap_sham_update_req(dd); |
---|
1176 | | - if (err != -EINPROGRESS && (ctx->flags & BIT(FLAGS_FINUP))) |
---|
1177 | | - /* no final() after finup() */ |
---|
1178 | | - err = omap_sham_final_req(dd); |
---|
1179 | | - } else if (ctx->op == OP_FINAL) { |
---|
1180 | | - err = omap_sham_final_req(dd); |
---|
1181 | | - } |
---|
1182 | | -err1: |
---|
1183 | | - dev_dbg(dd->dev, "exit, err: %d\n", err); |
---|
1184 | | - |
---|
1185 | | - if (err != -EINPROGRESS) { |
---|
1186 | | - /* done_task will not finish it, so do it here */ |
---|
1187 | | - omap_sham_finish_req(req, err); |
---|
1188 | | - req = NULL; |
---|
1189 | | - |
---|
1190 | | - /* |
---|
1191 | | - * Execute next request immediately if there is anything |
---|
1192 | | - * in queue. |
---|
1193 | | - */ |
---|
1194 | | - goto retry; |
---|
1195 | | - } |
---|
1196 | | - |
---|
1197 | | - return ret; |
---|
| 1197 | + return crypto_transfer_hash_request_to_engine(dd->engine, req); |
---|
1198 | 1198 | } |
---|
1199 | 1199 | |
---|
1200 | 1200 | static int omap_sham_enqueue(struct ahash_request *req, unsigned int op) |
---|
.. | .. |
---|
1228 | 1228 | return omap_sham_enqueue(req, OP_UPDATE); |
---|
1229 | 1229 | } |
---|
1230 | 1230 | |
---|
1231 | | -static int omap_sham_shash_digest(struct crypto_shash *tfm, u32 flags, |
---|
1232 | | - const u8 *data, unsigned int len, u8 *out) |
---|
1233 | | -{ |
---|
1234 | | - SHASH_DESC_ON_STACK(shash, tfm); |
---|
1235 | | - |
---|
1236 | | - shash->tfm = tfm; |
---|
1237 | | - shash->flags = flags & CRYPTO_TFM_REQ_MAY_SLEEP; |
---|
1238 | | - |
---|
1239 | | - return crypto_shash_digest(shash, data, len, out); |
---|
1240 | | -} |
---|
1241 | | - |
---|
1242 | 1231 | static int omap_sham_final_shash(struct ahash_request *req) |
---|
1243 | 1232 | { |
---|
1244 | 1233 | struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); |
---|
.. | .. |
---|
1254 | 1243 | !test_bit(FLAGS_AUTO_XOR, &ctx->dd->flags)) |
---|
1255 | 1244 | offset = get_block_size(ctx); |
---|
1256 | 1245 | |
---|
1257 | | - return omap_sham_shash_digest(tctx->fallback, req->base.flags, |
---|
1258 | | - ctx->buffer + offset, |
---|
1259 | | - ctx->bufcnt - offset, req->result); |
---|
| 1246 | + return crypto_shash_tfm_digest(tctx->fallback, ctx->buffer + offset, |
---|
| 1247 | + ctx->bufcnt - offset, req->result); |
---|
1260 | 1248 | } |
---|
1261 | 1249 | |
---|
1262 | 1250 | static int omap_sham_final(struct ahash_request *req) |
---|
.. | .. |
---|
1322 | 1310 | return err; |
---|
1323 | 1311 | |
---|
1324 | 1312 | if (keylen > bs) { |
---|
1325 | | - err = omap_sham_shash_digest(bctx->shash, |
---|
1326 | | - crypto_shash_get_flags(bctx->shash), |
---|
1327 | | - key, keylen, bctx->ipad); |
---|
| 1313 | + err = crypto_shash_tfm_digest(bctx->shash, key, keylen, |
---|
| 1314 | + bctx->ipad); |
---|
1328 | 1315 | if (err) |
---|
1329 | 1316 | return err; |
---|
1330 | 1317 | keylen = ds; |
---|
.. | .. |
---|
1376 | 1363 | } |
---|
1377 | 1364 | |
---|
1378 | 1365 | } |
---|
| 1366 | + |
---|
| 1367 | + tctx->enginectx.op.do_one_request = omap_sham_hash_one_req; |
---|
| 1368 | + tctx->enginectx.op.prepare_request = omap_sham_prepare_request; |
---|
| 1369 | + tctx->enginectx.op.unprepare_request = NULL; |
---|
1379 | 1370 | |
---|
1380 | 1371 | return 0; |
---|
1381 | 1372 | } |
---|
.. | .. |
---|
1555 | 1546 | .cra_name = "sha224", |
---|
1556 | 1547 | .cra_driver_name = "omap-sha224", |
---|
1557 | 1548 | .cra_priority = 400, |
---|
1558 | | - .cra_flags = CRYPTO_ALG_ASYNC | |
---|
| 1549 | + .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | |
---|
| 1550 | + CRYPTO_ALG_ASYNC | |
---|
1559 | 1551 | CRYPTO_ALG_NEED_FALLBACK, |
---|
1560 | 1552 | .cra_blocksize = SHA224_BLOCK_SIZE, |
---|
1561 | 1553 | .cra_ctxsize = sizeof(struct omap_sham_ctx), |
---|
.. | .. |
---|
1576 | 1568 | .cra_name = "sha256", |
---|
1577 | 1569 | .cra_driver_name = "omap-sha256", |
---|
1578 | 1570 | .cra_priority = 400, |
---|
1579 | | - .cra_flags = CRYPTO_ALG_ASYNC | |
---|
| 1571 | + .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | |
---|
| 1572 | + CRYPTO_ALG_ASYNC | |
---|
1580 | 1573 | CRYPTO_ALG_NEED_FALLBACK, |
---|
1581 | 1574 | .cra_blocksize = SHA256_BLOCK_SIZE, |
---|
1582 | 1575 | .cra_ctxsize = sizeof(struct omap_sham_ctx), |
---|
.. | .. |
---|
1598 | 1591 | .cra_name = "hmac(sha224)", |
---|
1599 | 1592 | .cra_driver_name = "omap-hmac-sha224", |
---|
1600 | 1593 | .cra_priority = 400, |
---|
1601 | | - .cra_flags = CRYPTO_ALG_ASYNC | |
---|
| 1594 | + .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | |
---|
| 1595 | + CRYPTO_ALG_ASYNC | |
---|
1602 | 1596 | CRYPTO_ALG_NEED_FALLBACK, |
---|
1603 | 1597 | .cra_blocksize = SHA224_BLOCK_SIZE, |
---|
1604 | 1598 | .cra_ctxsize = sizeof(struct omap_sham_ctx) + |
---|
.. | .. |
---|
1621 | 1615 | .cra_name = "hmac(sha256)", |
---|
1622 | 1616 | .cra_driver_name = "omap-hmac-sha256", |
---|
1623 | 1617 | .cra_priority = 400, |
---|
1624 | | - .cra_flags = CRYPTO_ALG_ASYNC | |
---|
| 1618 | + .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | |
---|
| 1619 | + CRYPTO_ALG_ASYNC | |
---|
1625 | 1620 | CRYPTO_ALG_NEED_FALLBACK, |
---|
1626 | 1621 | .cra_blocksize = SHA256_BLOCK_SIZE, |
---|
1627 | 1622 | .cra_ctxsize = sizeof(struct omap_sham_ctx) + |
---|
.. | .. |
---|
1646 | 1641 | .cra_name = "sha384", |
---|
1647 | 1642 | .cra_driver_name = "omap-sha384", |
---|
1648 | 1643 | .cra_priority = 400, |
---|
1649 | | - .cra_flags = CRYPTO_ALG_ASYNC | |
---|
| 1644 | + .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | |
---|
| 1645 | + CRYPTO_ALG_ASYNC | |
---|
1650 | 1646 | CRYPTO_ALG_NEED_FALLBACK, |
---|
1651 | 1647 | .cra_blocksize = SHA384_BLOCK_SIZE, |
---|
1652 | 1648 | .cra_ctxsize = sizeof(struct omap_sham_ctx), |
---|
.. | .. |
---|
1667 | 1663 | .cra_name = "sha512", |
---|
1668 | 1664 | .cra_driver_name = "omap-sha512", |
---|
1669 | 1665 | .cra_priority = 400, |
---|
1670 | | - .cra_flags = CRYPTO_ALG_ASYNC | |
---|
| 1666 | + .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | |
---|
| 1667 | + CRYPTO_ALG_ASYNC | |
---|
1671 | 1668 | CRYPTO_ALG_NEED_FALLBACK, |
---|
1672 | 1669 | .cra_blocksize = SHA512_BLOCK_SIZE, |
---|
1673 | 1670 | .cra_ctxsize = sizeof(struct omap_sham_ctx), |
---|
.. | .. |
---|
1689 | 1686 | .cra_name = "hmac(sha384)", |
---|
1690 | 1687 | .cra_driver_name = "omap-hmac-sha384", |
---|
1691 | 1688 | .cra_priority = 400, |
---|
1692 | | - .cra_flags = CRYPTO_ALG_ASYNC | |
---|
| 1689 | + .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | |
---|
| 1690 | + CRYPTO_ALG_ASYNC | |
---|
1693 | 1691 | CRYPTO_ALG_NEED_FALLBACK, |
---|
1694 | 1692 | .cra_blocksize = SHA384_BLOCK_SIZE, |
---|
1695 | 1693 | .cra_ctxsize = sizeof(struct omap_sham_ctx) + |
---|
.. | .. |
---|
1712 | 1710 | .cra_name = "hmac(sha512)", |
---|
1713 | 1711 | .cra_driver_name = "omap-hmac-sha512", |
---|
1714 | 1712 | .cra_priority = 400, |
---|
1715 | | - .cra_flags = CRYPTO_ALG_ASYNC | |
---|
| 1713 | + .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | |
---|
| 1714 | + CRYPTO_ALG_ASYNC | |
---|
1716 | 1715 | CRYPTO_ALG_NEED_FALLBACK, |
---|
1717 | 1716 | .cra_blocksize = SHA512_BLOCK_SIZE, |
---|
1718 | 1717 | .cra_ctxsize = sizeof(struct omap_sham_ctx) + |
---|
.. | .. |
---|
1730 | 1729 | struct omap_sham_dev *dd = (struct omap_sham_dev *)data; |
---|
1731 | 1730 | int err = 0; |
---|
1732 | 1731 | |
---|
1733 | | - if (!test_bit(FLAGS_BUSY, &dd->flags)) { |
---|
1734 | | - omap_sham_handle_queue(dd, NULL); |
---|
1735 | | - return; |
---|
1736 | | - } |
---|
| 1732 | + dev_dbg(dd->dev, "%s: flags=%lx\n", __func__, dd->flags); |
---|
1737 | 1733 | |
---|
1738 | 1734 | if (test_bit(FLAGS_CPU, &dd->flags)) { |
---|
1739 | 1735 | if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) |
---|
.. | .. |
---|
1759 | 1755 | dev_dbg(dd->dev, "update done: err: %d\n", err); |
---|
1760 | 1756 | /* finish curent request */ |
---|
1761 | 1757 | omap_sham_finish_req(dd->req, err); |
---|
1762 | | - |
---|
1763 | | - /* If we are not busy, process next req */ |
---|
1764 | | - if (!test_bit(FLAGS_BUSY, &dd->flags)) |
---|
1765 | | - omap_sham_handle_queue(dd, NULL); |
---|
1766 | 1758 | } |
---|
1767 | 1759 | |
---|
1768 | 1760 | static irqreturn_t omap_sham_irq_common(struct omap_sham_dev *dd) |
---|
1769 | 1761 | { |
---|
1770 | | - if (!test_bit(FLAGS_BUSY, &dd->flags)) { |
---|
1771 | | - dev_warn(dd->dev, "Interrupt when no active requests.\n"); |
---|
1772 | | - } else { |
---|
1773 | | - set_bit(FLAGS_OUTPUT_READY, &dd->flags); |
---|
1774 | | - tasklet_schedule(&dd->done_task); |
---|
1775 | | - } |
---|
| 1762 | + set_bit(FLAGS_OUTPUT_READY, &dd->flags); |
---|
| 1763 | + tasklet_schedule(&dd->done_task); |
---|
1776 | 1764 | |
---|
1777 | 1765 | return IRQ_HANDLED; |
---|
1778 | 1766 | } |
---|
.. | .. |
---|
1989 | 1977 | /* Get the IRQ */ |
---|
1990 | 1978 | dd->irq = platform_get_irq(pdev, 0); |
---|
1991 | 1979 | if (dd->irq < 0) { |
---|
1992 | | - dev_err(dev, "no IRQ resource info\n"); |
---|
1993 | 1980 | err = dd->irq; |
---|
1994 | 1981 | goto err; |
---|
1995 | 1982 | } |
---|
.. | .. |
---|
2046 | 2033 | struct omap_sham_dev *dd = dev_get_drvdata(dev); |
---|
2047 | 2034 | ssize_t status; |
---|
2048 | 2035 | long value; |
---|
2049 | | - unsigned long flags; |
---|
2050 | 2036 | |
---|
2051 | 2037 | status = kstrtol(buf, 0, &value); |
---|
2052 | 2038 | if (status) |
---|
.. | .. |
---|
2060 | 2046 | * than current size, it will just not accept new entries until |
---|
2061 | 2047 | * it has shrank enough. |
---|
2062 | 2048 | */ |
---|
2063 | | - spin_lock_irqsave(&dd->lock, flags); |
---|
2064 | 2049 | dd->queue.max_qlen = value; |
---|
2065 | | - spin_unlock_irqrestore(&dd->lock, flags); |
---|
2066 | 2050 | |
---|
2067 | 2051 | return size; |
---|
2068 | 2052 | } |
---|
.. | .. |
---|
2099 | 2083 | platform_set_drvdata(pdev, dd); |
---|
2100 | 2084 | |
---|
2101 | 2085 | INIT_LIST_HEAD(&dd->list); |
---|
2102 | | - spin_lock_init(&dd->lock); |
---|
2103 | 2086 | tasklet_init(&dd->done_task, omap_sham_done_task, (unsigned long)dd); |
---|
2104 | 2087 | crypto_init_queue(&dd->queue, OMAP_SHAM_QUEUE_LENGTH); |
---|
2105 | 2088 | |
---|
.. | .. |
---|
2147 | 2130 | pm_runtime_enable(dev); |
---|
2148 | 2131 | pm_runtime_irq_safe(dev); |
---|
2149 | 2132 | |
---|
2150 | | - err = pm_runtime_get_sync(dev); |
---|
| 2133 | + err = pm_runtime_resume_and_get(dev); |
---|
2151 | 2134 | if (err < 0) { |
---|
2152 | 2135 | dev_err(dev, "failed to get sync: %d\n", err); |
---|
2153 | 2136 | goto err_pm; |
---|
.. | .. |
---|
2160 | 2143 | (rev & dd->pdata->major_mask) >> dd->pdata->major_shift, |
---|
2161 | 2144 | (rev & dd->pdata->minor_mask) >> dd->pdata->minor_shift); |
---|
2162 | 2145 | |
---|
2163 | | - spin_lock(&sham.lock); |
---|
| 2146 | + spin_lock_bh(&sham.lock); |
---|
2164 | 2147 | list_add_tail(&dd->list, &sham.dev_list); |
---|
2165 | | - spin_unlock(&sham.lock); |
---|
| 2148 | + spin_unlock_bh(&sham.lock); |
---|
| 2149 | + |
---|
| 2150 | + dd->engine = crypto_engine_alloc_init(dev, 1); |
---|
| 2151 | + if (!dd->engine) { |
---|
| 2152 | + err = -ENOMEM; |
---|
| 2153 | + goto err_engine; |
---|
| 2154 | + } |
---|
| 2155 | + |
---|
| 2156 | + err = crypto_engine_start(dd->engine); |
---|
| 2157 | + if (err) |
---|
| 2158 | + goto err_engine_start; |
---|
2166 | 2159 | |
---|
2167 | 2160 | for (i = 0; i < dd->pdata->algs_info_size; i++) { |
---|
2168 | 2161 | if (dd->pdata->algs_info[i].registered) |
---|
.. | .. |
---|
2197 | 2190 | for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) |
---|
2198 | 2191 | crypto_unregister_ahash( |
---|
2199 | 2192 | &dd->pdata->algs_info[i].algs_list[j]); |
---|
| 2193 | +err_engine_start: |
---|
| 2194 | + crypto_engine_exit(dd->engine); |
---|
| 2195 | +err_engine: |
---|
| 2196 | + spin_lock_bh(&sham.lock); |
---|
| 2197 | + list_del(&dd->list); |
---|
| 2198 | + spin_unlock_bh(&sham.lock); |
---|
2200 | 2199 | err_pm: |
---|
2201 | 2200 | pm_runtime_disable(dev); |
---|
2202 | 2201 | if (!dd->polling_mode) |
---|
.. | .. |
---|
2215 | 2214 | dd = platform_get_drvdata(pdev); |
---|
2216 | 2215 | if (!dd) |
---|
2217 | 2216 | return -ENODEV; |
---|
2218 | | - spin_lock(&sham.lock); |
---|
| 2217 | + spin_lock_bh(&sham.lock); |
---|
2219 | 2218 | list_del(&dd->list); |
---|
2220 | | - spin_unlock(&sham.lock); |
---|
| 2219 | + spin_unlock_bh(&sham.lock); |
---|
2221 | 2220 | for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) |
---|
2222 | 2221 | for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) { |
---|
2223 | 2222 | crypto_unregister_ahash( |
---|
.. | .. |
---|
2229 | 2228 | |
---|
2230 | 2229 | if (!dd->polling_mode) |
---|
2231 | 2230 | dma_release_channel(dd->dma_lch); |
---|
| 2231 | + |
---|
| 2232 | + sysfs_remove_group(&dd->dev->kobj, &omap_sham_attr_group); |
---|
2232 | 2233 | |
---|
2233 | 2234 | return 0; |
---|
2234 | 2235 | } |
---|
.. | .. |
---|
2242 | 2243 | |
---|
2243 | 2244 | static int omap_sham_resume(struct device *dev) |
---|
2244 | 2245 | { |
---|
2245 | | - int err = pm_runtime_get_sync(dev); |
---|
| 2246 | + int err = pm_runtime_resume_and_get(dev); |
---|
2246 | 2247 | if (err < 0) { |
---|
2247 | 2248 | dev_err(dev, "failed to get sync: %d\n", err); |
---|
2248 | 2249 | return err; |
---|