LCOV - code coverage report
Current view: top level - crypto - scatterwalk.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 47 0.0 %
Date: 2014-02-18 Functions: 0 7 0.0 %
Branches: 0 36 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Cryptographic API.
       3                 :            :  *
       4                 :            :  * Cipher operations.
       5                 :            :  *
       6                 :            :  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
       7                 :            :  *               2002 Adam J. Richter <adam@yggdrasil.com>
       8                 :            :  *               2004 Jean-Luc Cooke <jlcooke@certainkey.com>
       9                 :            :  *
      10                 :            :  * This program is free software; you can redistribute it and/or modify it
      11                 :            :  * under the terms of the GNU General Public License as published by the Free
      12                 :            :  * Software Foundation; either version 2 of the License, or (at your option)
      13                 :            :  * any later version.
      14                 :            :  *
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <crypto/scatterwalk.h>
      18                 :            : #include <linux/kernel.h>
      19                 :            : #include <linux/mm.h>
      20                 :            : #include <linux/module.h>
      21                 :            : #include <linux/pagemap.h>
      22                 :            : #include <linux/highmem.h>
      23                 :            : #include <linux/scatterlist.h>
      24                 :            : 
      25                 :            : static inline void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
      26                 :            : {
      27         [ #  # ]:          0 :         void *src = out ? buf : sgdata;
      28         [ #  # ]:          0 :         void *dst = out ? sgdata : buf;
      29                 :            : 
      30                 :          0 :         memcpy(dst, src, nbytes);
      31                 :            : }
      32                 :            : 
      33                 :          0 : void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
      34                 :            : {
      35                 :          0 :         walk->sg = sg;
      36                 :            : 
      37 [ #  # ][ #  # ]:          0 :         BUG_ON(!sg->length);
                 [ #  # ]
      38                 :            : 
      39                 :          0 :         walk->offset = sg->offset;
      40                 :          0 : }
      41                 :            : EXPORT_SYMBOL_GPL(scatterwalk_start);
      42                 :            : 
      43                 :          0 : void *scatterwalk_map(struct scatter_walk *walk)
      44                 :            : {
      45                 :          0 :         return kmap_atomic(scatterwalk_page(walk)) +
      46                 :          0 :                offset_in_page(walk->offset);
      47                 :            : }
      48                 :            : EXPORT_SYMBOL_GPL(scatterwalk_map);
      49                 :            : 
      50                 :          0 : static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
      51                 :            :                                  unsigned int more)
      52                 :            : {
      53         [ #  # ]:          0 :         if (out) {
      54                 :            :                 struct page *page;
      55                 :            : 
      56                 :          0 :                 page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
      57         [ #  # ]:          0 :                 if (!PageSlab(page))
      58                 :          0 :                         flush_dcache_page(page);
      59                 :            :         }
      60                 :            : 
      61         [ #  # ]:          0 :         if (more) {
      62                 :          0 :                 walk->offset += PAGE_SIZE - 1;
      63                 :          0 :                 walk->offset &= PAGE_MASK;
      64         [ #  # ]:          0 :                 if (walk->offset >= walk->sg->offset + walk->sg->length)
      65                 :            :                         scatterwalk_start(walk, scatterwalk_sg_next(walk->sg));
      66                 :            :         }
      67                 :          0 : }
      68                 :            : 
      69                 :          0 : void scatterwalk_done(struct scatter_walk *walk, int out, int more)
      70                 :            : {
      71 [ #  # ][ #  # ]:          0 :         if (!(scatterwalk_pagelen(walk) & (PAGE_SIZE - 1)) || !more)
      72                 :          0 :                 scatterwalk_pagedone(walk, out, more);
      73                 :          0 : }
      74                 :            : EXPORT_SYMBOL_GPL(scatterwalk_done);
      75                 :            : 
      76                 :          0 : void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
      77                 :            :                             size_t nbytes, int out)
      78                 :            : {
      79                 :            :         for (;;) {
      80                 :            :                 unsigned int len_this_page = scatterwalk_pagelen(walk);
      81                 :            :                 u8 *vaddr;
      82                 :            : 
      83         [ #  # ]:          0 :                 if (len_this_page > nbytes)
      84                 :            :                         len_this_page = nbytes;
      85                 :            : 
      86                 :          0 :                 vaddr = scatterwalk_map(walk);
      87                 :            :                 memcpy_dir(buf, vaddr, len_this_page, out);
      88                 :            :                 scatterwalk_unmap(vaddr);
      89                 :            : 
      90                 :            :                 scatterwalk_advance(walk, len_this_page);
      91                 :            : 
      92         [ #  # ]:          0 :                 if (nbytes == len_this_page)
      93                 :            :                         break;
      94                 :            : 
      95                 :          0 :                 buf += len_this_page;
      96                 :          0 :                 nbytes -= len_this_page;
      97                 :            : 
      98                 :          0 :                 scatterwalk_pagedone(walk, out, 1);
      99                 :          0 :         }
     100                 :          0 : }
     101                 :            : EXPORT_SYMBOL_GPL(scatterwalk_copychunks);
     102                 :            : 
     103                 :          0 : void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
     104                 :            :                               unsigned int start, unsigned int nbytes, int out)
     105                 :            : {
     106                 :            :         struct scatter_walk walk;
     107                 :            :         unsigned int offset = 0;
     108                 :            : 
     109         [ #  # ]:          0 :         if (!nbytes)
     110                 :          0 :                 return;
     111                 :            : 
     112                 :            :         for (;;) {
     113                 :            :                 scatterwalk_start(&walk, sg);
     114                 :            : 
     115         [ #  # ]:          0 :                 if (start < offset + sg->length)
     116                 :            :                         break;
     117                 :            : 
     118                 :            :                 offset += sg->length;
     119                 :            :                 sg = scatterwalk_sg_next(sg);
     120                 :            :         }
     121                 :            : 
     122                 :          0 :         scatterwalk_advance(&walk, start - offset);
     123                 :          0 :         scatterwalk_copychunks(buf, &walk, nbytes, out);
     124                 :          0 :         scatterwalk_done(&walk, out, 0);
     125                 :            : }
     126                 :            : EXPORT_SYMBOL_GPL(scatterwalk_map_and_copy);
     127                 :            : 
     128                 :          0 : int scatterwalk_bytes_sglen(struct scatterlist *sg, int num_bytes)
     129                 :            : {
     130                 :            :         int offset = 0, n = 0;
     131                 :            : 
     132                 :            :         /* num_bytes is too small */
     133         [ #  # ]:          0 :         if (num_bytes < sg->length)
     134                 :            :                 return -1;
     135                 :            : 
     136                 :            :         do {
     137                 :          0 :                 offset += sg->length;
     138                 :          0 :                 n++;
     139                 :            :                 sg = scatterwalk_sg_next(sg);
     140                 :            : 
     141                 :            :                 /* num_bytes is too large */
     142         [ #  # ]:          0 :                 if (unlikely(!sg && (num_bytes < offset)))
     143                 :            :                         return -1;
     144         [ #  # ]:          0 :         } while (sg && (num_bytes > offset));
     145                 :            : 
     146                 :            :         return n;
     147                 :            : }
     148                 :            : EXPORT_SYMBOL_GPL(scatterwalk_bytes_sglen);

Generated by: LCOV version 1.9