~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to ubuntu/rtl8192se/rtllib/scatterwalk.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

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