OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [crypto/] [scatterwalk.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
#include <linux/kernel.h>
17
#include <linux/mm.h>
18
#include <linux/pagemap.h>
19
#include <linux/highmem.h>
20
#include <asm/scatterlist.h>
21
#include "internal.h"
22
#include "scatterwalk.h"
23
 
24
enum km_type crypto_km_types[] = {
25
        KM_USER0,
26
        KM_USER1,
27
        KM_SOFTIRQ0,
28
        KM_SOFTIRQ1,
29
};
30
 
31
void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
32
{
33
        if (nbytes <= walk->len_this_page &&
34
            (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
35
            PAGE_CACHE_SIZE)
36
                return walk->data;
37
        else
38
                return scratch;
39
}
40
 
41
static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
42
{
43
        if (out)
44
                memcpy(sgdata, buf, nbytes);
45
        else
46
                memcpy(buf, sgdata, nbytes);
47
}
48
 
49
void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
50
{
51
        unsigned int rest_of_page;
52
 
53
        walk->sg = sg;
54
 
55
        walk->page = sg->page;
56
        walk->len_this_segment = sg->length;
57
 
58
        rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
59
        walk->len_this_page = min(sg->length, rest_of_page);
60
        walk->offset = sg->offset;
61
}
62
 
63
void scatterwalk_map(struct scatter_walk *walk, int out)
64
{
65
        walk->data = crypto_kmap(walk->page, out) + walk->offset;
66
}
67
 
68
static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
69
                                 unsigned int more)
70
{
71
        /* walk->data may be pointing the first byte of the next page;
72
           however, we know we transfered at least one byte.  So,
73
           walk->data - 1 will be a virutual address in the mapped page. */
74
 
75
        if (out)
76
                flush_dcache_page(walk->page);
77
 
78
        if (more) {
79
                walk->len_this_segment -= walk->len_this_page;
80
 
81
                if (walk->len_this_segment) {
82
                        walk->page++;
83
                        walk->len_this_page = min(walk->len_this_segment,
84
                                                  (unsigned)PAGE_CACHE_SIZE);
85
                        walk->offset = 0;
86
                }
87
                else
88
                        scatterwalk_start(walk, sg_next(walk->sg));
89
        }
90
}
91
 
92
void scatterwalk_done(struct scatter_walk *walk, int out, int more)
93
{
94
        crypto_kunmap(walk->data, out);
95
        if (walk->len_this_page == 0 || !more)
96
                scatterwalk_pagedone(walk, out, more);
97
}
98
 
99
/*
100
 * Do not call this unless the total length of all of the fragments
101
 * has been verified as multiple of the block size.
102
 */
103
int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
104
                           size_t nbytes, int out)
105
{
106
        if (buf != walk->data) {
107
                while (nbytes > walk->len_this_page) {
108
                        memcpy_dir(buf, walk->data, walk->len_this_page, out);
109
                        buf += walk->len_this_page;
110
                        nbytes -= walk->len_this_page;
111
 
112
                        crypto_kunmap(walk->data, out);
113
                        scatterwalk_pagedone(walk, out, 1);
114
                        scatterwalk_map(walk, out);
115
                }
116
 
117
                memcpy_dir(buf, walk->data, nbytes, out);
118
        }
119
 
120
        walk->offset += nbytes;
121
        walk->len_this_page -= nbytes;
122
        walk->len_this_segment -= nbytes;
123
        return 0;
124
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.