1 /* 2 * JFFS2 -- Journalling Flash File System, Version 2. 3 * 4 * Copyright (C) 2001-2003 Red Hat, Inc. 5 * 6 * Created by Dominic Ostrowski <[email protected]> 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 #include <rtdevice.h> 18 19 int jffs2_flash_read(struct jffs2_sb_info * c, cyg_uint32 offset, 20 const size_t size, 21 size_t * return_size, 22 unsigned char *buffer) 23 { 24 uint32_t len; 25 struct super_block *sb = OFNI_BS_2SFFJ(c); 26 27 len = rt_mtd_nor_read(RT_MTD_NOR_DEVICE(sb->s_dev), offset, buffer, size); 28 if (len != size) 29 return -EIO; 30 31 * return_size = len; 32 return ENOERR; 33 } 34 35 int jffs2_flash_write(struct jffs2_sb_info * c, 36 cyg_uint32 offset, const size_t size, 37 size_t * return_size, unsigned char *buffer) 38 { 39 uint32_t len; 40 struct super_block *sb = OFNI_BS_2SFFJ(c); 41 42 len = rt_mtd_nor_write(RT_MTD_NOR_DEVICE(sb->s_dev), offset, buffer, size); 43 if (len != size) 44 return -EIO; 45 46 * return_size = len; 47 return ENOERR; 48 } 49 50 int jffs2_flash_erase(struct jffs2_sb_info * c, 51 struct jffs2_eraseblock * jeb) 52 { 53 rt_err_t result; 54 struct super_block *sb = OFNI_BS_2SFFJ(c); 55 56 result = rt_mtd_nor_erase_block(RT_MTD_NOR_DEVICE(sb->s_dev), jeb->offset, c->sector_size); 57 if (result != RT_EOK) 58 return -EIO; 59 60 return ENOERR; 61 } 62 63 int jffs2_flash_direct_writev(struct jffs2_sb_info *c, 64 const struct iovec *vecs, unsigned long count, loff_t to, 65 size_t * retlen) 66 { 67 unsigned long i; 68 size_t totlen = 0, thislen; 69 int ret = 0; 70 71 for (i = 0; i < count; i++) 72 { 73 // writes need to be aligned but the data we're passed may not be 74 // Observation suggests most unaligned writes are small, so we 75 // optimize for that case. 76 77 if (((vecs[i].iov_len & (sizeof(int) - 1))) || 78 (((unsigned long) vecs[i].iov_base & (sizeof(unsigned long) - 1)))) 79 { 80 // are there iov's after this one? Or is it so much we'd need 81 // to do multiple writes anyway? 82 if ((i + 1) < count || vecs[i].iov_len > 256) 83 { 84 // cop out and malloc 85 unsigned long j; 86 ssize_t sizetomalloc = 0, totvecsize = 0; 87 char *cbuf, *cbufptr; 88 89 for (j = i; j < count; j++) 90 totvecsize += vecs[j].iov_len; 91 92 // pad up in case unaligned 93 sizetomalloc = totvecsize + sizeof(int) - 1; 94 sizetomalloc &= ~(sizeof(int) - 1); 95 cbuf = (char *) rt_malloc(sizetomalloc); 96 // malloc returns aligned memory 97 if (!cbuf) 98 { 99 ret = -ENOMEM; 100 goto writev_out; 101 } 102 cbufptr = cbuf; 103 for (j = i; j < count; j++) 104 { 105 memcpy(cbufptr, vecs[j].iov_base, vecs[j].iov_len); 106 cbufptr += vecs[j].iov_len; 107 } 108 //rt_kprintf("direct_write: offset %d, size %d\n", to, sizetomalloc); 109 ret = jffs2_flash_write(c, to, sizetomalloc, &thislen, 110 (unsigned char *) cbuf); 111 if (thislen > totvecsize) // in case it was aligned up 112 thislen = totvecsize; 113 totlen += thislen; 114 rt_free(cbuf); 115 goto writev_out; 116 } 117 else 118 { 119 // otherwise optimize for the common case 120 int buf[256/sizeof(int)]; // int, so int aligned 121 size_t lentowrite; 122 123 lentowrite = vecs[i].iov_len; 124 // pad up in case its unaligned 125 lentowrite += sizeof(int) - 1; 126 lentowrite &= ~(sizeof(int) - 1); 127 memcpy(buf, vecs[i].iov_base, lentowrite); 128 129 //rt_kprintf("direct_write: offset %d, size %d\n", to, lentowrite); 130 ret = jffs2_flash_write(c, to, lentowrite, &thislen, 131 (unsigned char *) &buf); 132 if (thislen > vecs[i].iov_len) 133 thislen = vecs[i].iov_len; 134 } 135 } 136 else 137 { 138 //rt_kprintf("direct_writev: offset %d, size %d\n", to, vecs[i].iov_len); 139 ret = jffs2_flash_write(c, to, vecs[i].iov_len, &thislen, 140 vecs[i].iov_base); 141 } 142 totlen += thislen; 143 if (ret || thislen != vecs[i].iov_len) break; 144 to += vecs[i].iov_len; 145 } 146 147 writev_out: 148 if (retlen) *retlen = totlen; 149 150 return ret; 151 } 152