Blame view
fs/yaffs2/yaffs_mtdif.c
4.1 KB
0e8cc8bd9 YAFFS2 import |
1 2 3 4 5 6 7 8 9 10 11 12 |
/* * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. * * Copyright (C) 2002-2007 Aleph One Ltd. * for Toby Churchill Ltd and Brightstar Engineering * * Created by Charles Manning <charles@aleph1.co.uk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ |
90ef117b6 Incorporate yaffs... |
13 14 |
/* XXX U-BOOT XXX */ #include <common.h> |
0e8cc8bd9 YAFFS2 import |
15 16 17 18 |
#include "yportenv.h" #include "yaffs_mtdif.h" |
b5bf5cb3b treewide: use #in... |
19 20 21 |
#include <linux/mtd/mtd.h> #include <linux/types.h> #include <linux/time.h> |
6ae3900a8 mtd: nand: Rename... |
22 |
#include <linux/mtd/rawnand.h> |
0e8cc8bd9 YAFFS2 import |
23 |
|
0e8cc8bd9 YAFFS2 import |
24 |
|
753ac6108 u-boot: Update ya... |
25 |
static inline void translate_spare2oob(const struct yaffs_spare *spare, u8 *oob) |
0e8cc8bd9 YAFFS2 import |
26 |
{ |
753ac6108 u-boot: Update ya... |
27 28 29 30 31 32 33 34 35 36 |
oob[0] = spare->tb0; oob[1] = spare->tb1; oob[2] = spare->tb2; oob[3] = spare->tb3; oob[4] = spare->tb4; oob[5] = spare->tb5 & 0x3f; oob[5] |= spare->block_status == 'Y' ? 0 : 0x80; oob[5] |= spare->page_status == 0 ? 0 : 0x40; oob[6] = spare->tb6; oob[7] = spare->tb7; |
0e8cc8bd9 YAFFS2 import |
37 |
} |
753ac6108 u-boot: Update ya... |
38 |
static inline void translate_oob2spare(struct yaffs_spare *spare, u8 *oob) |
0e8cc8bd9 YAFFS2 import |
39 |
{ |
753ac6108 u-boot: Update ya... |
40 41 42 43 44 45 46 47 48 |
struct yaffs_nand_spare *nspare = (struct yaffs_nand_spare *)spare; spare->tb0 = oob[0]; spare->tb1 = oob[1]; spare->tb2 = oob[2]; spare->tb3 = oob[3]; spare->tb4 = oob[4]; spare->tb5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f; spare->block_status = oob[5] & 0x80 ? 0xff : 'Y'; spare->page_status = oob[5] & 0x40 ? 0xff : 0; |
0e8cc8bd9 YAFFS2 import |
49 |
spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff; |
753ac6108 u-boot: Update ya... |
50 51 |
spare->tb6 = oob[6]; spare->tb7 = oob[7]; |
0e8cc8bd9 YAFFS2 import |
52 53 54 55 |
spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff; nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */ } |
0e8cc8bd9 YAFFS2 import |
56 |
|
753ac6108 u-boot: Update ya... |
57 58 59 |
int nandmtd_WriteChunkToNAND(struct yaffs_dev *dev, int chunkInNAND, const u8 *data, const struct yaffs_spare *spare) |
0e8cc8bd9 YAFFS2 import |
60 |
{ |
753ac6108 u-boot: Update ya... |
61 |
struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context); |
0e8cc8bd9 YAFFS2 import |
62 |
struct mtd_oob_ops ops; |
0e8cc8bd9 YAFFS2 import |
63 64 |
size_t dummy; int retval = 0; |
753ac6108 u-boot: Update ya... |
65 66 |
loff_t addr = ((loff_t) chunkInNAND) * dev->data_bytes_per_chunk; u8 spareAsBytes[8]; /* OOB */ |
0e8cc8bd9 YAFFS2 import |
67 68 |
if (data && !spare) |
dfe64e2c8 mtd: resync with ... |
69 |
retval = mtd_write(mtd, addr, dev->data_bytes_per_chunk, |
0e8cc8bd9 YAFFS2 import |
70 71 |
&dummy, data); else if (spare) { |
753ac6108 u-boot: Update ya... |
72 |
if (dev->param.use_nand_ecc) { |
0e8cc8bd9 YAFFS2 import |
73 |
translate_spare2oob(spare, spareAsBytes); |
dfe64e2c8 mtd: resync with ... |
74 |
ops.mode = MTD_OPS_AUTO_OOB; |
0e8cc8bd9 YAFFS2 import |
75 76 |
ops.ooblen = 8; /* temp hack */ } else { |
dfe64e2c8 mtd: resync with ... |
77 |
ops.mode = MTD_OPS_RAW; |
0e8cc8bd9 YAFFS2 import |
78 79 |
ops.ooblen = YAFFS_BYTES_PER_SPARE; } |
753ac6108 u-boot: Update ya... |
80 |
ops.len = data ? dev->data_bytes_per_chunk : ops.ooblen; |
0e8cc8bd9 YAFFS2 import |
81 82 83 |
ops.datbuf = (u8 *)data; ops.ooboffs = 0; ops.oobbuf = spareAsBytes; |
dfe64e2c8 mtd: resync with ... |
84 |
retval = mtd_write_oob(mtd, addr, &ops); |
0e8cc8bd9 YAFFS2 import |
85 |
} |
0e8cc8bd9 YAFFS2 import |
86 87 88 89 90 91 |
if (retval == 0) return YAFFS_OK; else return YAFFS_FAIL; } |
753ac6108 u-boot: Update ya... |
92 93 |
int nandmtd_ReadChunkFromNAND(struct yaffs_dev *dev, int chunkInNAND, u8 *data, struct yaffs_spare *spare) |
0e8cc8bd9 YAFFS2 import |
94 |
{ |
753ac6108 u-boot: Update ya... |
95 |
struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context); |
0e8cc8bd9 YAFFS2 import |
96 |
struct mtd_oob_ops ops; |
0e8cc8bd9 YAFFS2 import |
97 98 |
size_t dummy; int retval = 0; |
753ac6108 u-boot: Update ya... |
99 100 |
loff_t addr = ((loff_t) chunkInNAND) * dev->data_bytes_per_chunk; u8 spareAsBytes[8]; /* OOB */ |
0e8cc8bd9 YAFFS2 import |
101 102 |
if (data && !spare) |
dfe64e2c8 mtd: resync with ... |
103 |
retval = mtd_read(mtd, addr, dev->data_bytes_per_chunk, |
0e8cc8bd9 YAFFS2 import |
104 105 |
&dummy, data); else if (spare) { |
753ac6108 u-boot: Update ya... |
106 |
if (dev->param.use_nand_ecc) { |
dfe64e2c8 mtd: resync with ... |
107 |
ops.mode = MTD_OPS_AUTO_OOB; |
0e8cc8bd9 YAFFS2 import |
108 109 |
ops.ooblen = 8; /* temp hack */ } else { |
dfe64e2c8 mtd: resync with ... |
110 |
ops.mode = MTD_OPS_RAW; |
0e8cc8bd9 YAFFS2 import |
111 112 |
ops.ooblen = YAFFS_BYTES_PER_SPARE; } |
753ac6108 u-boot: Update ya... |
113 |
ops.len = data ? dev->data_bytes_per_chunk : ops.ooblen; |
0e8cc8bd9 YAFFS2 import |
114 115 116 |
ops.datbuf = data; ops.ooboffs = 0; ops.oobbuf = spareAsBytes; |
dfe64e2c8 mtd: resync with ... |
117 |
retval = mtd_read_oob(mtd, addr, &ops); |
753ac6108 u-boot: Update ya... |
118 |
if (dev->param.use_nand_ecc) |
0e8cc8bd9 YAFFS2 import |
119 120 |
translate_oob2spare(spare, spareAsBytes); } |
0e8cc8bd9 YAFFS2 import |
121 122 123 124 125 126 |
if (retval == 0) return YAFFS_OK; else return YAFFS_FAIL; } |
753ac6108 u-boot: Update ya... |
127 |
int nandmtd_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber) |
0e8cc8bd9 YAFFS2 import |
128 |
{ |
753ac6108 u-boot: Update ya... |
129 |
struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context); |
0e8cc8bd9 YAFFS2 import |
130 |
__u32 addr = |
753ac6108 u-boot: Update ya... |
131 132 |
((loff_t) blockNumber) * dev->data_bytes_per_chunk * dev->param.chunks_per_block; |
0e8cc8bd9 YAFFS2 import |
133 134 135 136 137 |
struct erase_info ei; int retval = 0; ei.mtd = mtd; ei.addr = addr; |
753ac6108 u-boot: Update ya... |
138 |
ei.len = dev->data_bytes_per_chunk * dev->param.chunks_per_block; |
0e8cc8bd9 YAFFS2 import |
139 140 141 142 143 144 |
ei.time = 1000; ei.retries = 2; ei.callback = NULL; ei.priv = (u_long) dev; /* Todo finish off the ei if required */ |
0e8cc8bd9 YAFFS2 import |
145 |
|
dfe64e2c8 mtd: resync with ... |
146 |
retval = mtd_erase(mtd, &ei); |
0e8cc8bd9 YAFFS2 import |
147 148 149 150 151 152 |
if (retval == 0) return YAFFS_OK; else return YAFFS_FAIL; } |
753ac6108 u-boot: Update ya... |
153 |
int nandmtd_InitialiseNAND(struct yaffs_dev *dev) |
0e8cc8bd9 YAFFS2 import |
154 155 156 |
{ return YAFFS_OK; } |