aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-11-24 09:00:49 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2008-12-24 19:01:52 -0500
commit3416158680d5ba6fdb939e5bb52a8eba1ad5c027 (patch)
treed0da1237d5672f6cf2f403d43c57082d4c523a11 /drivers/crypto
parent75741a034024f146ba5431602f3ad33a5df8363c (diff)
crypto: hifn_795x - Don't copy src sg list
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/hifn_795x.c75
1 files changed, 33 insertions, 42 deletions
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 27b8af983aae..2b4940bc8356 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1378,32 +1378,40 @@ static int hifn_setup_dma(struct hifn_device *dev, struct hifn_context *ctx,
1378 unsigned int soff, doff; 1378 unsigned int soff, doff;
1379 unsigned int n, len; 1379 unsigned int n, len;
1380 1380
1381 n = nbytes;
1382 while (n) {
1383 spage = sg_page(src);
1384 soff = src->offset;
1385 len = min(src->length, n);
1386
1387 dprintk("%s: spage: %p, soffset: %u, nbytes: %u, "
1388 "priv: %p, ctx: %p.\n",
1389 dev->name, spage, soff, nbytes, priv, ctx);
1390 hifn_setup_src_desc(dev, spage, soff, len, n - len == 0);
1391
1392 src++;
1393 n -= len;
1394 }
1395
1381 t = &ctx->walk.cache[0]; 1396 t = &ctx->walk.cache[0];
1382 n = nbytes; 1397 n = nbytes;
1383 while (n) { 1398 while (n) {
1384 if (t->length) { 1399 if (t->length) {
1385 spage = dpage = sg_page(t); 1400 dpage = sg_page(t);
1386 soff = doff = 0; 1401 doff = 0;
1387 len = t->length; 1402 len = t->length;
1388 } else { 1403 } else {
1389 spage = sg_page(src);
1390 soff = src->offset;
1391
1392 dpage = sg_page(dst); 1404 dpage = sg_page(dst);
1393 doff = dst->offset; 1405 doff = dst->offset;
1394
1395 len = dst->length; 1406 len = dst->length;
1396 } 1407 }
1397 len = min(len, n); 1408 len = min(len, n);
1398 1409
1399 dprintk("%s: spage: %p, soffset: %u, dpage: %p, doffset: %u, " 1410 dprintk("%s: dpage: %p, doffset: %u, nbytes: %u, "
1400 "nbytes: %u, priv: %p, ctx: %p.\n", 1411 "priv: %p, ctx: %p.\n",
1401 dev->name, spage, soff, dpage, doff, nbytes, priv, ctx); 1412 dev->name, dpage, doff, nbytes, priv, ctx);
1402
1403 hifn_setup_src_desc(dev, spage, soff, len, n - len == 0);
1404 hifn_setup_dst_desc(dev, dpage, doff, len, n - len == 0); 1413 hifn_setup_dst_desc(dev, dpage, doff, len, n - len == 0);
1405 1414
1406 src++;
1407 dst++; 1415 dst++;
1408 t++; 1416 t++;
1409 n -= len; 1417 n -= len;
@@ -1454,32 +1462,26 @@ static void ablkcipher_walk_exit(struct ablkcipher_walk *w)
1454 w->num = 0; 1462 w->num = 0;
1455} 1463}
1456 1464
1457static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist *src, 1465static int ablkcipher_add(unsigned int *drestp, struct scatterlist *dst,
1458 unsigned int size, unsigned int *nbytesp) 1466 unsigned int size, unsigned int *nbytesp)
1459{ 1467{
1460 unsigned int copy, drest = *drestp, nbytes = *nbytesp; 1468 unsigned int copy, drest = *drestp, nbytes = *nbytesp;
1461 int idx = 0; 1469 int idx = 0;
1462 void *saddr;
1463 1470
1464 if (drest < size || size > nbytes) 1471 if (drest < size || size > nbytes)
1465 return -EINVAL; 1472 return -EINVAL;
1466 1473
1467 while (size) { 1474 while (size) {
1468 copy = min(drest, min(size, src->length)); 1475 copy = min(drest, min(size, dst->length));
1469
1470 saddr = kmap_atomic(sg_page(src), KM_SOFTIRQ1);
1471 memcpy(daddr, saddr + src->offset, copy);
1472 kunmap_atomic(saddr, KM_SOFTIRQ1);
1473 1476
1474 size -= copy; 1477 size -= copy;
1475 drest -= copy; 1478 drest -= copy;
1476 nbytes -= copy; 1479 nbytes -= copy;
1477 daddr += copy;
1478 1480
1479 dprintk("%s: copy: %u, size: %u, drest: %u, nbytes: %u.\n", 1481 dprintk("%s: copy: %u, size: %u, drest: %u, nbytes: %u.\n",
1480 __func__, copy, size, drest, nbytes); 1482 __func__, copy, size, drest, nbytes);
1481 1483
1482 src++; 1484 dst++;
1483 idx++; 1485 idx++;
1484 } 1486 }
1485 1487
@@ -1492,8 +1494,7 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist
1492static int ablkcipher_walk(struct ablkcipher_request *req, 1494static int ablkcipher_walk(struct ablkcipher_request *req,
1493 struct ablkcipher_walk *w) 1495 struct ablkcipher_walk *w)
1494{ 1496{
1495 struct scatterlist *src, *dst, *t; 1497 struct scatterlist *dst, *t;
1496 void *daddr;
1497 unsigned int nbytes = req->nbytes, offset, copy, diff; 1498 unsigned int nbytes = req->nbytes, offset, copy, diff;
1498 int idx, tidx, err; 1499 int idx, tidx, err;
1499 1500
@@ -1503,26 +1504,22 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1503 if (idx >= w->num && (w->flags & ASYNC_FLAGS_MISALIGNED)) 1504 if (idx >= w->num && (w->flags & ASYNC_FLAGS_MISALIGNED))
1504 return -EINVAL; 1505 return -EINVAL;
1505 1506
1506 src = &req->src[idx];
1507 dst = &req->dst[idx]; 1507 dst = &req->dst[idx];
1508 1508
1509 dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, " 1509 dprintk("\n%s: dlen: %u, doff: %u, offset: %u, nbytes: %u.\n",
1510 "nbytes: %u.\n", 1510 __func__, dst->length, dst->offset, offset, nbytes);
1511 __func__, src->length, dst->length, src->offset,
1512 dst->offset, offset, nbytes);
1513 1511
1514 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || 1512 if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
1515 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) || 1513 !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
1516 offset) { 1514 offset) {
1517 unsigned slen = min(src->length - offset, nbytes); 1515 unsigned slen = min(dst->length - offset, nbytes);
1518 unsigned dlen = PAGE_SIZE; 1516 unsigned dlen = PAGE_SIZE;
1519 1517
1520 t = &w->cache[idx]; 1518 t = &w->cache[idx];
1521 1519
1522 daddr = kmap_atomic(sg_page(t), KM_SOFTIRQ0); 1520 err = ablkcipher_add(&dlen, dst, slen, &nbytes);
1523 err = ablkcipher_add(daddr, &dlen, src, slen, &nbytes);
1524 if (err < 0) 1521 if (err < 0)
1525 goto err_out_unmap; 1522 return err;
1526 1523
1527 idx += err; 1524 idx += err;
1528 1525
@@ -1558,21 +1555,19 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1558 } else { 1555 } else {
1559 copy += diff + nbytes; 1556 copy += diff + nbytes;
1560 1557
1561 src = &req->src[idx]; 1558 dst = &req->dst[idx];
1562 1559
1563 err = ablkcipher_add(daddr + slen, &dlen, src, nbytes, &nbytes); 1560 err = ablkcipher_add(&dlen, dst, nbytes, &nbytes);
1564 if (err < 0) 1561 if (err < 0)
1565 goto err_out_unmap; 1562 return err;
1566 1563
1567 idx += err; 1564 idx += err;
1568 } 1565 }
1569 1566
1570 t->length = copy; 1567 t->length = copy;
1571 t->offset = offset; 1568 t->offset = offset;
1572
1573 kunmap_atomic(daddr, KM_SOFTIRQ0);
1574 } else { 1569 } else {
1575 nbytes -= min(src->length, nbytes); 1570 nbytes -= min(dst->length, nbytes);
1576 idx++; 1571 idx++;
1577 } 1572 }
1578 1573
@@ -1580,10 +1575,6 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
1580 } 1575 }
1581 1576
1582 return tidx; 1577 return tidx;
1583
1584err_out_unmap:
1585 kunmap_atomic(daddr, KM_SOFTIRQ0);
1586 return err;
1587} 1578}
1588 1579
1589static int hifn_setup_session(struct ablkcipher_request *req) 1580static int hifn_setup_session(struct ablkcipher_request *req)