*** empty log message ***
[yaffs/.git] / yaffs_mtdif.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system. 
3  * yaffs_mtdif.c  NAND mtd wrapper functions.
4  *
5  * Copyright (C) 2002 Aleph One Ltd.
6  *   for Toby Churchill Ltd and Brightstar Engineering
7  *
8  * Created by Charles Manning <charles@aleph1.co.uk>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  */
15
16 const char *yaffs_mtdif_c_version = "$Id: yaffs_mtdif.c,v 1.6 2003-01-14 23:15:32 charles Exp $";
17
18 #ifdef CONFIG_YAFFS_MTD_ENABLED
19  
20 #include "yportenv.h"
21
22 #include "yaffs_mtdif.h"
23
24 #include "linux/mtd/mtd.h"
25 #include "linux/types.h"
26 #include "linux/time.h"
27
28 #ifndef CONFIG_YAFFS_USE_OLD_MTD
29 #include "linux/mtd/nand.h"
30 #endif
31
32 int nandmtd_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare)
33 {
34         struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
35         size_t dummy;
36     int retval = 0;
37         
38         loff_t addr = ((loff_t)chunkInNAND) * YAFFS_BYTES_PER_CHUNK;
39         
40         __u8 *spareAsBytes = (__u8 *)spare;
41
42 #ifndef CONFIG_YAFFS_USE_OLD_MTD
43         if(data && spare)
44         {
45                 if(dev->useNANDECC)
46                         mtd->write_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,spareAsBytes,NAND_YAFFS_OOB);
47                 else
48                         mtd->write_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,spareAsBytes,NAND_NONE_OOB);
49         }
50         else
51         {
52 #endif
53         if(data)
54                 retval = mtd->write(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data);
55         if(spare)
56                 retval = mtd->write_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes);
57 #ifndef CONFIG_YAFFS_USE_OLD_MTD
58         }
59 #endif
60
61     if (retval == 0)
62         return YAFFS_OK;
63     else
64         return YAFFS_FAIL;
65 }
66
67 int nandmtd_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)
68 {
69         struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
70         size_t dummy;
71     int retval = 0;
72         
73         loff_t addr = ((loff_t)chunkInNAND) * YAFFS_BYTES_PER_CHUNK;
74         
75         __u8 *spareAsBytes = (__u8 *)spare;
76         
77 #ifndef CONFIG_YAFFS_USE_OLD_MTD
78         if(data && spare)
79         {
80                 if(dev->useNANDECC)
81                 {
82                         u8 tmpSpare[ YAFFS_BYTES_PER_SPARE + (2*sizeof(int)) ];
83                         retval = mtd->read_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,tmpSpare,NAND_YAFFS_OOB);
84                         memcpy(spareAsBytes, tmpSpare, YAFFS_BYTES_PER_SPARE);
85                 }
86                 else
87                 {
88                         retval = mtd->read_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,spareAsBytes,NAND_NONE_OOB);
89                 }
90         }
91         else
92         {
93 #endif
94         if(data)
95                 retval = mtd->read(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data);
96         if(spare)
97                 retval = mtd->read_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes);
98 #ifndef CONFIG_YAFFS_USE_OLD_MTD
99         }
100 #endif
101
102     if (retval == 0)
103         return YAFFS_OK;
104     else
105         return YAFFS_FAIL;
106 }
107
108
109 static void nandmtd_EraseCallback(struct erase_info *ei)
110 {
111         yaffs_Device *dev = (yaffs_Device *)ei->priv;   
112         up(&dev->sem);
113 }
114
115
116 int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
117 {
118         struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
119         __u32 addr = ((loff_t) blockNumber) * YAFFS_BYTES_PER_BLOCK;
120         struct erase_info ei;
121     int retval = 0;
122         
123         ei.mtd = mtd;
124         ei.addr = addr;
125         ei.len = YAFFS_BYTES_PER_BLOCK;
126         ei.time = 1000;
127         ei.retries = 2;
128         ei.callback = nandmtd_EraseCallback;
129         ei.priv = (u_long)dev;
130         
131         // Todo finish off the ei if required
132         
133         sema_init(&dev->sem,0);
134
135         retval = mtd->erase(mtd,&ei);   
136         
137         down(&dev->sem); // Wait for the erasure to complete
138
139     if (retval == 0)    
140         return YAFFS_OK;
141     else
142         return YAFFS_FAIL;
143 }
144
145 int nandmtd_InitialiseNAND(yaffs_Device *dev)
146 {
147         return YAFFS_OK;
148 }
149
150 #endif // CONFIG_YAFFS_MTD_ENABLED
151