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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [fs/] [jffs2/] [current/] [src/] [flashio.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*
2
 * JFFS2 -- Journalling Flash File System, Version 2.
3
 *
4
 * Copyright (C) 2001-2003 Red Hat, Inc.
5
 *
6
 * Created by Dominic Ostrowski <dominic.ostrowski@3glab.com>
7
 * Contributors: David Woodhouse, Nick Garnett, Richard Panton.
8
 *
9
 * For licensing information, see the file 'LICENCE' in this directory.
10
 *
11
 * $Id: flashio.c,v 1.1 2003/11/26 14:09:29 dwmw2 Exp $
12
 *
13
 */
14
 
15
#include <linux/kernel.h>
16
#include "nodelist.h"
17
 
18
#include <cyg/io/io.h>
19
#include <cyg/io/config_keys.h>
20
#include <cyg/io/flash.h>
21
 
22
cyg_bool jffs2_flash_read(struct jffs2_sb_info * c,
23
                          cyg_uint32 read_buffer_offset, const size_t size,
24
                          size_t * return_size, unsigned char *write_buffer)
25
{
26
        Cyg_ErrNo err;
27
        cyg_uint32 len = size;
28
        struct super_block *sb = OFNI_BS_2SFFJ(c);
29
 
30
        //D2(printf("FLASH READ\n"));
31
        //D2(printf("read address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + read_buffer_offset));
32
        //D2(printf("write address = %x\n", write_buffer));
33
        //D2(printf("size = %x\n", size));
34
        err = cyg_io_bread(sb->s_dev, write_buffer, &len, read_buffer_offset);
35
 
36
        *return_size = (size_t) len;
37
        return ((err == ENOERR) ? ENOERR : -EIO);
38
}
39
 
40
cyg_bool jffs2_flash_write(struct jffs2_sb_info * c,
41
                           cyg_uint32 write_buffer_offset, const size_t size,
42
                           size_t * return_size, unsigned char *read_buffer)
43
{
44
 
45
        Cyg_ErrNo err;
46
        cyg_uint32 len = size;
47
        struct super_block *sb = OFNI_BS_2SFFJ(c);
48
 
49
        //    D2(printf("FLASH WRITE ENABLED!!!\n"));
50
        //    D2(printf("write address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + write_buffer_offset));
51
        //    D2(printf("read address = %x\n", read_buffer));
52
        //    D2(printf("size = %x\n", size));
53
 
54
        err = cyg_io_bwrite(sb->s_dev, read_buffer, &len, write_buffer_offset);
55
        *return_size = (size_t) len;
56
 
57
        return ((err == ENOERR) ? ENOERR : -EIO);
58
}
59
 
60
int
61
jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
62
                   unsigned long count, loff_t to, size_t * retlen)
63
{
64
        unsigned long i;
65
        size_t totlen = 0, thislen;
66
        int ret = 0;
67
 
68
        for (i = 0; i < count; i++) {
69
                // writes need to be aligned but the data we're passed may not be
70
                // Observation suggests most unaligned writes are small, so we
71
                // optimize for that case.
72
 
73
                if (((vecs[i].iov_len & (sizeof (int) - 1))) ||
74
                    (((unsigned long) vecs[i].
75
                      iov_base & (sizeof (unsigned long) - 1)))) {
76
                        // are there iov's after this one? Or is it so much we'd need
77
                        // to do multiple writes anyway?
78
                        if ((i + 1) < count || vecs[i].iov_len > 256) {
79
                                // cop out and malloc
80
                                unsigned long j;
81
                                ssize_t sizetomalloc = 0, totvecsize = 0;
82
                                char *cbuf, *cbufptr;
83
 
84
                                for (j = i; j < count; j++)
85
                                        totvecsize += vecs[j].iov_len;
86
 
87
                                // pad up in case unaligned
88
                                sizetomalloc = totvecsize + sizeof (int) - 1;
89
                                sizetomalloc &= ~(sizeof (int) - 1);
90
                                cbuf = (char *) malloc(sizetomalloc);
91
                                // malloc returns aligned memory
92
                                if (!cbuf) {
93
                                        ret = -ENOMEM;
94
                                        goto writev_out;
95
                                }
96
                                cbufptr = cbuf;
97
                                for (j = i; j < count; j++) {
98
                                        memcpy(cbufptr, vecs[j].iov_base,
99
                                               vecs[j].iov_len);
100
                                        cbufptr += vecs[j].iov_len;
101
                                }
102
                                ret =
103
                                    jffs2_flash_write(c, to, sizetomalloc,
104
                                                      &thislen, cbuf);
105
                                if (thislen > totvecsize)       // in case it was aligned up
106
                                        thislen = totvecsize;
107
                                totlen += thislen;
108
                                free(cbuf);
109
                                goto writev_out;
110
                        } else {
111
                                // otherwise optimize for the common case
112
                                int buf[256 / sizeof (int)];    // int, so int aligned
113
                                size_t lentowrite;
114
 
115
                                lentowrite = vecs[i].iov_len;
116
                                // pad up in case its unaligned
117
                                lentowrite += sizeof (int) - 1;
118
                                lentowrite &= ~(sizeof (int) - 1);
119
                                memcpy(buf, vecs[i].iov_base, lentowrite);
120
 
121
                                ret =
122
                                    jffs2_flash_write(c, to, lentowrite,
123
                                                      &thislen, (char *) &buf);
124
                                if (thislen > vecs[i].iov_len)
125
                                        thislen = vecs[i].iov_len;
126
                        }       // else
127
                } else
128
                        ret =
129
                            jffs2_flash_write(c, to, vecs[i].iov_len, &thislen,
130
                                              vecs[i].iov_base);
131
                totlen += thislen;
132
                if (ret || thislen != vecs[i].iov_len)
133
                        break;
134
                to += vecs[i].iov_len;
135
        }
136
      writev_out:
137
        if (retlen)
138
                *retlen = totlen;
139
 
140
        return ret;
141
}
142
 
143
cyg_bool jffs2_flash_erase(struct jffs2_sb_info * c,
144
                           struct jffs2_eraseblock * jeb)
145
{
146
        cyg_io_flash_getconfig_erase_t e;
147
        cyg_flashaddr_t err_addr;
148
        Cyg_ErrNo err;
149
        cyg_uint32 len = sizeof (e);
150
        struct super_block *sb = OFNI_BS_2SFFJ(c);
151
 
152
        e.offset = jeb->offset;
153
        e.len = c->sector_size;
154
        e.err_address = &err_addr;
155
 
156
        //        D2(printf("FLASH ERASE ENABLED!!!\n"));
157
        //        D2(printf("erase address = %x\n", CYGNUM_FS_JFFS2_BASE_ADDRESS + jeb->offset));
158
        //        D2(printf("size = %x\n", c->sector_size));
159
 
160
        err = cyg_io_get_config(sb->s_dev, CYG_IO_GET_CONFIG_FLASH_ERASE,
161
                                &e, &len);
162
 
163
        return (err != ENOERR || e.flasherr != 0);
164
}
165
 

powered by: WebSVN 2.1.0

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