deleted old lines after nick's correction of unregistering the correct flavour of
[yaffs/.git] / utils / mkyaffs.c
1 /*
2  * YAFFS: Yet another FFS. A NAND-flash specific file system. 
3  * mkyaffs.c Format a chunk of NAND for YAFFS.
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  *  Acknowledgement:
15  *  This file is crafted from nandtest.c by  Miguel Freitas (miguel@cetuc.puc-rio.br)
16  *  and Steven J. Hill (sjhill@cotw.com)
17  *
18  * Overview:
19  * Formatting a YAFFS device is very simple. Just erase all undamaged blocks. 
20  * NB Don't erase blocks maked as damaged.
21  */
22
23 #define _GNU_SOURCE
24 #include <ctype.h>
25 #include <fcntl.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <time.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <sys/ioctl.h>
32 #include <sys/types.h>
33 #include <asm/types.h>
34 #include <linux/config.h>
35 #include <linux/mtd/mtd.h>
36
37
38 // countBits is a quick way of counting the number of bits in a byte.
39 // ie. countBits[n] holds the number of 1 bits in a byte with the value n.
40
41 static const char countBits[256] =
42 {
43 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
44 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
45 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
46 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
47 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
48 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
49 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
50 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
51 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
52 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
53 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
54 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
55 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
56 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
57 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
58 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
59 };
60
61 /*
62  * Buffer arrays used for running tests
63  */
64
65 unsigned char oobbuf[16];
66
67
68 /*
69  * Main program
70  */
71 int main(int argc, char **argv)
72 {
73         unsigned long addr;
74         int bs, fd, i;
75         struct mtd_oob_buf oob = {0, 16, (unsigned char *) &oobbuf};
76         mtd_info_t meminfo;
77         erase_info_t erase;
78
79         /* Make sure a device was specified */
80         if(argc < 2) {
81                 printf("usage: %s <mtdname>\n", argv[0]);
82                 exit(1);
83         }
84
85         /* Open the device */
86         if((fd = open(argv[1], O_RDWR)) == -1) {
87                 perror("open flash");
88                 exit(1);
89         }
90
91         /* Fill in MTD device capability structure */
92         if(ioctl(fd, MEMGETINFO, &meminfo) != 0) {
93                 perror("MEMGETINFO");
94                 close(fd);
95                 exit(1);
96         }
97
98         /* Make sure device page sizes are valid */
99         if( !(meminfo.oobsize == 16 && meminfo.oobblock == 512)) 
100         {
101                 printf("Unknown flash (not normal NAND)\n");
102                 close(fd);
103                 exit(1);
104         }
105         
106         
107         for(addr = 0; addr < meminfo.size; addr += meminfo.erasesize)
108         {
109                 /* Read the OOB data to determine if the block is valid.
110                  * If the block is damaged, then byte 5 of the OOB data will
111                  * have at least 2 zero bits.
112                  */
113                 oob.start = addr;
114                 oob.length = 16;
115                 oob.ptr = oobbuf;
116                 if (ioctl(fd, MEMREADOOB, &oob) != 0) 
117                 {
118                         perror("ioctl(MEMREADOOB)");
119                         close(fd);
120                         exit(1);
121                 }
122                 
123                 if(countBits[oobbuf[5]] < 7)
124                 {
125                         printf("Block at 0x08%lx is damaged and is not being formatted\n",addr);
126                 }
127                 else
128                 {
129                         /* Erase this block */
130                         erase.start = addr;
131                         erase.length = meminfo.erasesize;
132                         printf("Erasing block at 0x08%lx\n",addr);
133                         if(ioctl(fd, MEMERASE, &erase) != 0) 
134                         {
135                                 perror("\nMTD Erase failure\n");
136                                 close(fd);
137                                 exit(1);
138                         }
139                         
140                 }
141
142         }
143
144
145         /* All the tests succeeded */
146         printf("OK\n");
147         close(fd);
148         return 0;
149 }
150