diff options
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/hifn_795x.c | 75 |
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 | ||
1457 | static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist *src, | 1465 | static 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 | |||
1492 | static int ablkcipher_walk(struct ablkcipher_request *req, | 1494 | static 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 | |||
1584 | err_out_unmap: | ||
1585 | kunmap_atomic(daddr, KM_SOFTIRQ0); | ||
1586 | return err; | ||
1587 | } | 1578 | } |
1588 | 1579 | ||
1589 | static int hifn_setup_session(struct ablkcipher_request *req) | 1580 | static int hifn_setup_session(struct ablkcipher_request *req) |