Mercurial > nand-ecoscentric
annotate packages/fs/jffs2/current/src/flashio.c @ 3403:8c8767bb9a62 default tip
devs/nand/micron_mt29: Remove defunct references (in comments) to mt29f2g08_oob_ecc.
| author | Ross Younger <wry@ecoscentric.com> |
|---|---|
| date | Sun, 18 Jan 2015 17:59:01 +1300 |
| parents | 13376f3cfc60 |
| children |
| rev | line source |
|---|---|
| 1443 | 1 /* |
| 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, | |
| 2042 | 24 size_t * return_size, unsigned char *write_buffer) |
| 1443 | 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, | |
| 2042 | 42 size_t * return_size, unsigned char *read_buffer) |
| 1443 | 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; | |
|
2631
13376f3cfc60
Merge flashv2 branch to trunk, with eCosCentric additions
jlarmour
parents:
2042
diff
changeset
|
147 cyg_flashaddr_t err_addr; |
| 1443 | 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 |
