Add first-cut Linux kernel patch-in mechanism
[yaffs/.git] / wince / ynandif.c
1 /*\r
2  * YAFFS: Yet another FFS. A NAND-flash specific file system.\r
3  * ynandif.c: NAND interface functions for the WinCE port of YAFFS.\r
4  *\r
5  * Copyright (C) 2002-2003 Trimble Navigation Ltd.\r
6  *\r
7  * Created by Brad Beveridge <brad.beveridge@trimble.co.nz>\r
8  * Modified for CE 4.x by Steve Fogle <stevef@atworkcom.com>\r
9  *\r
10  * This program is free software; you can redistribute it and/or modify\r
11  * it under the terms of the GNU General Public License version 2 as\r
12  * published by the Free Software Foundation.\r
13  *\r
14  * This program is distributed in the hope that it will be useful, \r
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of \r
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU \r
17  * General Public License for more details. You should have received a \r
18  * copy of the GNU General Public License along with this program; \r
19  * if not, write to the Free Software Foundation, Inc., \r
20  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. \r
21  *\r
22  * $Id: ynandif.c,v 1.2 2003-01-31 00:52:53 charles Exp $\r
23  */\r
24 #include <windows.h>\r
25 #include <fsdmgr.h>\r
26 #include "ynandif.h"\r
27 \r
28 //slf021220a Begin Cleanup block driver interface\r
29 #if _WINCEOSVER < 400\r
30 // For Win'CE 4.0 FSDMGR instead of direct access.\r
31 HANDLE devHandle = 0;\r
32 #endif\r
33 //slf021220a end Cleanup block driver interface\r
34 \r
35 /*\r
36 *       Functions that need to be provided for YAFFS\r
37 */\r
38 int ynandif_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,const __u8 *data, yaffs_Spare *spare)\r
39 {\r
40 //slf021220a Begin Cleanup block driver interface\r
41 #if _WINCEOSVER >= 400\r
42         if (dev)\r
43 #else\r
44         if (devHandle)\r
45 #endif\r
46 //slf021220a end Cleanup block driver interface\r
47         {\r
48                 ynandif_data writeData;\r
49                 int result;\r
50 \r
51                 writeData.chunk = chunkInNAND;\r
52                 writeData.data = (__u8 *)data;\r
53                 writeData.spare = (char *)spare;\r
54                 \r
55 //slf021220a Begin Cleanup block driver interface\r
56 #if _WINCEOSVER >= 400\r
57                 if (!FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
58 #else\r
59                 if (!DeviceIoControl(devHandle,\r
60 #endif\r
61 //slf021220a end Cleanup block driver interface\r
62                                                      YNANDIF_WRITE,\r
63                                                      &writeData,\r
64                                                      sizeof(ynandif_data),\r
65                                                      &result,\r
66                                                      sizeof(result),\r
67                                                      NULL,\r
68                                                          NULL))\r
69                         return YAFFS_FAIL;\r
70 \r
71                 return result;\r
72         }\r
73 \r
74         return YAFFS_FAIL;\r
75 }\r
76 \r
77 int ynandif_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)\r
78 {\r
79 //slf021220a Begin Cleanup block driver interface\r
80 #if _WINCEOSVER >= 400\r
81         if (dev)\r
82 #else\r
83         if (devHandle)\r
84 #endif\r
85 //slf021220a end Cleanup block driver interface\r
86         {\r
87                 ynandif_data readData;\r
88                 int result;\r
89 \r
90                 readData.chunk = chunkInNAND;\r
91                 readData.data = data;\r
92                 readData.spare = (char *)spare;\r
93                 \r
94 //slf021220a Begin Cleanup block driver interface\r
95 #if _WINCEOSVER >= 400\r
96                 if (!FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
97 #else\r
98                 if (!DeviceIoControl(devHandle,\r
99 #endif\r
100 //slf021220a end Cleanup block driver interface\r
101                                                      YNANDIF_READ,\r
102                                                      &readData,\r
103                                                      sizeof(ynandif_data),\r
104                                                      &result,\r
105                                                      sizeof(result),\r
106                                                      NULL,\r
107                                                          NULL))\r
108                         return YAFFS_FAIL;\r
109 \r
110                 return result;\r
111         }\r
112 \r
113         return YAFFS_FAIL;\r
114 }\r
115 \r
116 int ynandif_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)\r
117 {\r
118 //slf021220a Begin Cleanup block driver interface\r
119 #if _WINCEOSVER >= 400\r
120         if (dev)\r
121 #else\r
122         if (devHandle)\r
123 #endif\r
124 //slf021220a end Cleanup block driver interface\r
125         {\r
126                 int result;\r
127                 \r
128 //slf021220a Begin Cleanup block driver interface\r
129 #if _WINCEOSVER >= 400\r
130                 if (!FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
131 #else\r
132         if (!DeviceIoControl(devHandle,\r
133 #endif\r
134 //slf021220a end Cleanup block driver interface\r
135                                                      YNANDIF_ERASE,\r
136                                                      &blockNumber,\r
137                                                      sizeof(int),\r
138                                                      &result,\r
139                                                      sizeof(result),\r
140                                                      NULL,\r
141                                                          NULL))\r
142                         return YAFFS_FAIL;\r
143 \r
144                 return result;\r
145         }\r
146 \r
147 // if we return YAFFS_FAIL, then yaffs will retire this block & mark it bad, not exactly\r
148 // what we want to do by default.\r
149         return YAFFS_OK;\r
150 }\r
151 \r
152 int ynandif_InitialiseNAND(yaffs_Device *dev)\r
153 {\r
154 \r
155 //slf021220a Begin Cleanup block driver interface\r
156 #if _WINCEOSVER < 400\r
157 // For Win'CE 4.0 FSDMGR instead of direct access.\r
158         RETAILMSG(1, (L"ynandif_InitialiseNAND\r\n"));\r
159         devHandle = CreateFile(L"YND1:",\r
160                                                    GENERIC_READ|GENERIC_WRITE,\r
161                                                    0,\r
162                                                    NULL,\r
163                                                    OPEN_EXISTING,\r
164                                                    0,\r
165                                                    0);\r
166 \r
167 //slf021220d Begin CreateFile returns INVALID_HANDLE_VALUE not null fix.\r
168         if (INVALID_HANDLE_VALUE == devHandle)\r
169         {\r
170                 devHandle = NULL;\r
171                 return 0;\r
172         }\r
173 //      if (!devHandle)\r
174 //              return 0;\r
175 //slf021220d end CreateFile returns INVALID_HANDLE_VALUE not null fix.\r
176 \r
177         RETAILMSG(1, (L"devhandle open\r\n"));\r
178 #endif\r
179 //slf021220a Begin Cleanup block driver interface\r
180 \r
181         RETAILMSG(1, (L"DeviceIo INIT\r\n"));\r
182 //slf021220a Begin Cleanup block driver interface\r
183         if (dev)\r
184         {\r
185 #if _WINCEOSVER >= 400\r
186                 if (!FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
187 #else\r
188                 if (!DeviceIoControl(devHandle,\r
189 #endif\r
190 //slf021220a end Cleanup block driver interface\r
191                                                  YNANDIF_INIT,\r
192                                                  NULL,\r
193                                                  0,\r
194                                                  NULL,\r
195                                                  0,\r
196                                                  NULL,\r
197                                                  NULL))\r
198                         return 0;\r
199 //slf021220a Begin Cleanup block driver interface\r
200         }\r
201 //slf021220a end Cleanup block driver interface\r
202 \r
203         if (dev)\r
204         {\r
205 //slf021220a Begin Cleanup block driver interface\r
206 //              int nBlocks = ynandif_GetChipSize(0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
207                 int nBlocks = ynandif_GetChipSize(dev,0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
208 //slf021220a end Cleanup block driver interface\r
209                 dev->startBlock = 1;  // Don't use block 0\r
210                 dev->endBlock = nBlocks - 1;\r
211         }\r
212 \r
213         return 1;\r
214 }\r
215 \r
216 //slf021220a Begin Cleanup block driver interface\r
217 void ynandif_DeinitialiseNAND(yaffs_Device *dev)\r
218 {\r
219         RETAILMSG(1, (L"ynandif_DeinitialiseNAND\r\n"));\r
220 #if _WINCEOSVER < 400\r
221         if (devHandle)\r
222         {\r
223                 CloseHandle(devHandle);\r
224                 devHandle = NULL;\r
225         }\r
226 #endif\r
227 }\r
228 //slf021220a end Cleanup block driver interface\r
229 \r
230 int ynandif_EraseAllBlocks(yaffs_Device *dev)\r
231 {\r
232         int numBlocks, counter;\r
233 //slf021220a Begin Cleanup block driver interface\r
234 //      numBlocks = ynandif_GetChipSize(0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
235         numBlocks = ynandif_GetChipSize(dev,0xFF) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);\r
236 //slf021220a end Cleanup block driver interface\r
237         for (counter = 0; counter < numBlocks; counter++)\r
238         {\r
239                 ynandif_EraseBlockInNAND(dev, counter);\r
240         }\r
241         return YAFFS_OK;\r
242 }\r
243 \r
244 //slf021220a Begin Cleanup block driver interface\r
245 //int ynandif_GetChipSize(unsigned char chipNumber)\r
246 int ynandif_GetChipSize(yaffs_Device *dev, unsigned char chipNumber)\r
247 //slf021220a end Cleanup block driver interface\r
248 {\r
249         int ret = 0;\r
250         RETAILMSG(1, (L"DeviceIo GETSIZE\r\n"));\r
251 //slf021220a Begin Cleanup block driver interface\r
252 #if _WINCEOSVER >= 400\r
253         if (dev)\r
254 #else\r
255         if (devHandle)\r
256 #endif\r
257 //slf021220a end Cleanup block driver interface\r
258         {\r
259                 RETAILMSG(1, (L"DeviceIo GETSIZE - getting ret\r\n"));\r
260 //slf021220a Begin Cleanup block driver interface\r
261 #if _WINCEOSVER >= 400\r
262                 FSDMGR_DiskIoControl((HDSK)dev->genericDevice,\r
263 #else\r
264                 DeviceIoControl(devHandle,\r
265 #endif\r
266 //slf021220a end Cleanup block driver interface\r
267                                         YNANDIF_GETSIZE,\r
268                                         NULL,\r
269                                         0,\r
270                                         &ret,\r
271                                         sizeof(ret),\r
272                                         NULL,\r
273                                         NULL);\r
274         }\r
275         RETAILMSG(1, (L"DeviceIo GETSIZE ret %X\r\n", ret));\r
276 \r
277 \r
278 \r
279         return ret;\r
280 }\r