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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [crypto/] [scatterwalk.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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/module.h>
19
#include <linux/pagemap.h>
20
#include <linux/highmem.h>
21
#include <linux/scatterlist.h>
22
 
23
#include "internal.h"
24
#include "scatterwalk.h"
25
 
26
static inline void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
27
{
28
        void *src = out ? buf : sgdata;
29
        void *dst = out ? sgdata : buf;
30
 
31
        memcpy(dst, src, nbytes);
32
}
33
 
34
void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
35
{
36
        walk->sg = sg;
37
 
38
        BUG_ON(!sg->length);
39
 
40
        walk->offset = sg->offset;
41
}
42
EXPORT_SYMBOL_GPL(scatterwalk_start);
43
 
44
void *scatterwalk_map(struct scatter_walk *walk, int out)
45
{
46
        return crypto_kmap(scatterwalk_page(walk), out) +
47
               offset_in_page(walk->offset);
48
}
49
EXPORT_SYMBOL_GPL(scatterwalk_map);
50
 
51
static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
52
                                 unsigned int more)
53
{
54
        if (out) {
55
                struct page *page;
56
 
57
                page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
58
                flush_dcache_page(page);
59
        }
60
 
61
        if (more) {
62
                walk->offset += PAGE_SIZE - 1;
63
                walk->offset &= PAGE_MASK;
64
                if (walk->offset >= walk->sg->offset + walk->sg->length)
65
                        scatterwalk_start(walk, scatterwalk_sg_next(walk->sg));
66
        }
67
}
68
 
69
void scatterwalk_done(struct scatter_walk *walk, int out, int more)
70
{
71
        if (!offset_in_page(walk->offset) || !more)
72
                scatterwalk_pagedone(walk, out, more);
73
}
74
EXPORT_SYMBOL_GPL(scatterwalk_done);
75
 
76
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
                if (len_this_page > nbytes)
84
                        len_this_page = nbytes;
85
 
86
                vaddr = scatterwalk_map(walk, out);
87
                memcpy_dir(buf, vaddr, len_this_page, out);
88
                scatterwalk_unmap(vaddr, out);
89
 
90
                scatterwalk_advance(walk, len_this_page);
91
 
92
                if (nbytes == len_this_page)
93
                        break;
94
 
95
                buf += len_this_page;
96
                nbytes -= len_this_page;
97
 
98
                scatterwalk_pagedone(walk, out, 1);
99
        }
100
}
101
EXPORT_SYMBOL_GPL(scatterwalk_copychunks);
102
 
103
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
        for (;;) {
110
                scatterwalk_start(&walk, sg);
111
 
112
                if (start < offset + sg->length)
113
                        break;
114
 
115
                offset += sg->length;
116
                sg = sg_next(sg);
117
        }
118
 
119
        scatterwalk_advance(&walk, start - offset);
120
        scatterwalk_copychunks(buf, &walk, nbytes, out);
121
        scatterwalk_done(&walk, out, 0);
122
}
123
EXPORT_SYMBOL_GPL(scatterwalk_map_and_copy);

powered by: WebSVN 2.1.0

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