aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-06-16 01:54:22 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-06-17 03:35:08 -0400
commit6c94711cbdf595766bc3295e437c3579943cd846 (patch)
treeb718b155bf880275c71ee5a2d4525f7468f3a566 /drivers/crypto
parent201f28f055917300c3301b19d0e0e674b9cf8cb7 (diff)
crypto: caam - Handle errors in dma_map_sg_chained
Currently dma_map_sg_chained does not handle errors from the underlying dma_map_sg calls. This patch adds rollback in case of an error by simply calling dma_unmap_sg_chained for the ones that we've already mapped. All current callers ignore the return value so this should have no impact on them. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/sg_sw_sec4.h35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h
index efbc1db8da53..b68b74cc7b77 100644
--- a/drivers/crypto/caam/sg_sw_sec4.h
+++ b/drivers/crypto/caam/sg_sw_sec4.h
@@ -100,34 +100,41 @@ static inline int sg_count(struct scatterlist *sg_list, int nbytes,
100 return sg_nents; 100 return sg_nents;
101} 101}
102 102
103static int dma_map_sg_chained(struct device *dev, struct scatterlist *sg, 103static inline void dma_unmap_sg_chained(
104 unsigned int nents, enum dma_data_direction dir, 104 struct device *dev, struct scatterlist *sg, unsigned int nents,
105 bool chained) 105 enum dma_data_direction dir, bool chained)
106{ 106{
107 if (unlikely(chained)) { 107 if (unlikely(chained)) {
108 int i; 108 int i;
109 for (i = 0; i < nents; i++) { 109 for (i = 0; i < nents; i++) {
110 dma_map_sg(dev, sg, 1, dir); 110 dma_unmap_sg(dev, sg, 1, dir);
111 sg = sg_next(sg); 111 sg = sg_next(sg);
112 } 112 }
113 } else { 113 } else if (nents) {
114 dma_map_sg(dev, sg, nents, dir); 114 dma_unmap_sg(dev, sg, nents, dir);
115 } 115 }
116 return nents;
117} 116}
118 117
119static int dma_unmap_sg_chained(struct device *dev, struct scatterlist *sg, 118static inline int dma_map_sg_chained(
120 unsigned int nents, enum dma_data_direction dir, 119 struct device *dev, struct scatterlist *sg, unsigned int nents,
121 bool chained) 120 enum dma_data_direction dir, bool chained)
122{ 121{
122 struct scatterlist *first = sg;
123
123 if (unlikely(chained)) { 124 if (unlikely(chained)) {
124 int i; 125 int i;
125 for (i = 0; i < nents; i++) { 126 for (i = 0; i < nents; i++) {
126 dma_unmap_sg(dev, sg, 1, dir); 127 if (!dma_map_sg(dev, sg, 1, dir)) {
128 dma_unmap_sg_chained(dev, first, i, dir,
129 chained);
130 nents = 0;
131 break;
132 }
133
127 sg = sg_next(sg); 134 sg = sg_next(sg);
128 } 135 }
129 } else { 136 } else
130 dma_unmap_sg(dev, sg, nents, dir); 137 nents = dma_map_sg(dev, sg, nents, dir);
131 } 138
132 return nents; 139 return nents;
133} 140}