From: charles Date: Fri, 27 Sep 2002 20:50:50 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs%2F.git;a=commitdiff_plain;h=4d9efb8e3f1bd240579632b4c1446d7384c3cc96;ds=sidebyside *** empty log message *** --- diff --git a/devextras.h b/devextras.h index 9615362..3150f96 100644 --- a/devextras.h +++ b/devextras.h @@ -1,269 +1,271 @@ -/* - * YAFFS: Yet another FFS. A NAND-flash specific file system. - * devextras.h - * - * Copyright (C) 2002 Aleph One Ltd. - * for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 as - * published by the Free Software Foundation. - * - * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. - * - * This file is just holds extra declarations used during development. - * Most of these are from kernel includes placed here so we can use them in - * applications. - * - */ - -#ifndef __EXTRAS_H__ -#define __EXTRAS_H__ - -#if defined WIN32 -#define __inline__ __inline -#define new newHack -#endif - -#if !(defined __KERNEL__) || (defined WIN32) - -// User space defines - -typedef unsigned char __u8; -typedef unsigned short __u16; -typedef unsigned __u32; - - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - - #define prefetch(x) 1 - - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __list_add(struct list_head * new, - struct list_head * prev, - struct list_head * next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static __inline__ void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static __inline__ void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __list_del(struct list_head * prev, - struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is in an undefined state. - */ -static __inline__ void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static __inline__ void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static __inline__ int list_empty(struct list_head *head) -{ - return head->next == head; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static __inline__ void list_splice(struct list_head *list, struct list_head *head) -{ - struct list_head *first = list->next; - - if (first != list) { - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next, prefetch(pos->next); pos != (head); \ - pos = pos->next, prefetch(pos->next)) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - - - - -/* - * File types - */ -#define DT_UNKNOWN 0 -#define DT_FIFO 1 -#define DT_CHR 2 -#define DT_DIR 4 -#define DT_BLK 6 -#define DT_REG 8 -#define DT_LNK 10 -#define DT_SOCK 12 -#define DT_WHT 14 - -#ifndef WIN32 -#include -#endif - -/* - * Attribute flags. These should be or-ed together to figure out what - * has been changed! - */ -#define ATTR_MODE 1 -#define ATTR_UID 2 -#define ATTR_GID 4 -#define ATTR_SIZE 8 -#define ATTR_ATIME 16 -#define ATTR_MTIME 32 -#define ATTR_CTIME 64 -#define ATTR_ATIME_SET 128 -#define ATTR_MTIME_SET 256 -#define ATTR_FORCE 512 /* Not a change, but a change it */ -#define ATTR_ATTR_FLAG 1024 - - -struct iattr { - unsigned int ia_valid; - unsigned ia_mode; - unsigned ia_uid; - unsigned ia_gid; - unsigned ia_size; - unsigned ia_atime; - unsigned ia_mtime; - unsigned ia_ctime; - unsigned int ia_attr_flags; -}; - -#define KERN_DEBUG - - -#else - -#ifndef WIN32 -#include -#include -#include -#include -#endif - -#endif - - - -#if defined WIN32 -#undef new -#endif - -#endif - +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * devextras.h + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + * This file is just holds extra declarations used during development. + * Most of these are from kernel includes placed here so we can use them in + * applications. + * + * $Id: devextras.h,v 1.5 2002-09-27 20:50:50 charles Exp $ + * + */ + +#ifndef __EXTRAS_H__ +#define __EXTRAS_H__ + +#if defined WIN32 +#define __inline__ __inline +#define new newHack +#endif + +#if !(defined __KERNEL__) || (defined WIN32) + +// User space defines + +typedef unsigned char __u8; +typedef unsigned short __u16; +typedef unsigned __u32; + + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + + #define prefetch(x) 1 + + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline__ void __list_add(struct list_head * new, + struct list_head * prev, + struct list_head * next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static __inline__ void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static __inline__ void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline__ void __list_del(struct list_head * prev, + struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + */ +static __inline__ void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static __inline__ void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static __inline__ int list_empty(struct list_head *head) +{ + return head->next == head; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static __inline__ void list_splice(struct list_head *list, struct list_head *head) +{ + struct list_head *first = list->next; + + if (first != list) { + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next, prefetch(pos->next); pos != (head); \ + pos = pos->next, prefetch(pos->next)) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + + + + +/* + * File types + */ +#define DT_UNKNOWN 0 +#define DT_FIFO 1 +#define DT_CHR 2 +#define DT_DIR 4 +#define DT_BLK 6 +#define DT_REG 8 +#define DT_LNK 10 +#define DT_SOCK 12 +#define DT_WHT 14 + +#ifndef WIN32 +#include +#endif + +/* + * Attribute flags. These should be or-ed together to figure out what + * has been changed! + */ +#define ATTR_MODE 1 +#define ATTR_UID 2 +#define ATTR_GID 4 +#define ATTR_SIZE 8 +#define ATTR_ATIME 16 +#define ATTR_MTIME 32 +#define ATTR_CTIME 64 +#define ATTR_ATIME_SET 128 +#define ATTR_MTIME_SET 256 +#define ATTR_FORCE 512 /* Not a change, but a change it */ +#define ATTR_ATTR_FLAG 1024 + + +struct iattr { + unsigned int ia_valid; + unsigned ia_mode; + unsigned ia_uid; + unsigned ia_gid; + unsigned ia_size; + unsigned ia_atime; + unsigned ia_mtime; + unsigned ia_ctime; + unsigned int ia_attr_flags; +}; + +#define KERN_DEBUG + + +#else + +#ifndef WIN32 +#include +#include +#include +#include +#endif + +#endif + + + +#if defined WIN32 +#undef new +#endif + +#endif + diff --git a/nand_ecc.c b/nand_ecc.c index 6e2b7cd..c22397b 100644 --- a/nand_ecc.c +++ b/nand_ecc.c @@ -4,7 +4,7 @@ * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) * Toshiba America Electronics Components, Inc. * - * $Id: nand_ecc.c,v 1.2 2002-09-17 04:45:48 charles Exp $ + * $Id: nand_ecc.c,v 1.3 2002-09-27 20:50:50 charles Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -16,6 +16,8 @@ // Minor tweak by Charles Manning to prevent exporting symbols // when compiled in with yaffs. +const char *nand_ecc_c_version = "$Id: nand_ecc.c,v 1.3 2002-09-27 20:50:50 charles Exp $"; + #if 0 #include #include diff --git a/snMakefile b/snMakefile index 5f52d0f..0b9fbb9 100644 --- a/snMakefile +++ b/snMakefile @@ -1,6 +1,6 @@ ######################################################### # Makefile auto generated by Cygnus Source Navigator. -# Target: yaffsdev_disk Date: Sep 18 2002 Time: 10:19:04 AM +# Target: yaffsdev_disk Date: Sep 27 2002 Time: 09:05:11 AM # diff --git a/utils/mkyaffs.c b/utils/mkyaffs.c index 3a0ed67..91a3c9d 100644 --- a/utils/mkyaffs.c +++ b/utils/mkyaffs.c @@ -34,6 +34,7 @@ #include #include +cost char *mkyaffs_c_version = "$Id: mkyaffs.c,v 1.3 2002-09-27 20:50:50 charles Exp $"; // countBits is a quick way of counting the number of bits in a byte. // ie. countBits[n] holds the number of 1 bits in a byte with the value n. diff --git a/utils/mkyaffsimage.c b/utils/mkyaffsimage.c index 797bc0f..bab5797 100644 --- a/utils/mkyaffsimage.c +++ b/utils/mkyaffsimage.c @@ -14,6 +14,9 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * + * + * Nick Bane modifications flagged NCB + * */ #include @@ -30,14 +33,13 @@ #define MAX_OBJECTS 10000 +const char * mkyaffsimage_c_version = "$Id: mkyaffsimage.c,v 1.3 2002-09-27 20:50:50 charles Exp $"; + // External functions for ECC on data void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); - - - typedef struct { dev_t dev; @@ -113,6 +115,22 @@ int find_obj_in_list(dev_t dev, ino_t ino) return -1; } +// NCB added 10/9/2002 +static __u16 yaffs_CalcNameSum(const char *name) +{ + __u16 sum = 0; + __u16 i = 1; + + __u8 *bname = (__u8 *)name; + + while (*bname) + { + sum += (*bname) * i; + i++; + bname++; + } + return sum; +} void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare) @@ -133,7 +151,8 @@ void yaffs_CalcTagsECC(yaffs_Tags *tags) for(i = 0; i < 8; i++) { - for(j = 1; j &0x7f; j<<=1) +// NCB modified 20-9-02 for(j = 1; j &0x7f; j<<=1) + for(j = 1; j &0xff; j<<=1) { bit++; if(b[i] & j) @@ -206,11 +225,15 @@ int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, int paren strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH); + // NCB added 10/9/2001 + oh->sum = yaffs_CalcNameSum(oh->name); + if(t != YAFFS_OBJECT_TYPE_HARDLINK) { oh->st_mode = s->st_mode; oh->st_uid = s->st_uid; - oh->st_gid = s->st_uid; +// NCB 12/9/02 oh->st_gid = s->st_uid; + oh->st_gid = s->st_gid; oh->st_atime = s->st_atime; oh->st_mtime = s->st_mtime; oh->st_ctime = s->st_ctime; @@ -364,7 +387,8 @@ int process_directory(int parent, const char *path) { printf("directory\n"); error = write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL); - process_directory(1,full_name); +// NCB modified 10/9/2001 process_directory(1,full_name); + process_directory(newObj,full_name); } } } diff --git a/yaffs_fs.c b/yaffs_fs.c index 8ef7da7..b693305 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -22,10 +22,13 @@ * Acknowledgements: * * Luc van OostenRyck for numerous patches. * * Nick Bane for numerous patches. + * * Andras Toth for mknod rdev issue. * * Some code bodily lifted from JFFS2. */ +const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.16 2002-09-27 20:50:50 charles Exp $"; + #include #include #include @@ -361,7 +364,7 @@ static int yaffs_readpage_nolock(struct file *f, struct page * pg) yaffs_Device *dev; T((KERN_DEBUG"yaffs_readpage at %08x, size %08x\n", - pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE)); + (unsigned)(pg->index << PAGE_CACHE_SHIFT), (unsigned)PAGE_CACHE_SIZE)); obj = yaffs_DentryToObject(f->f_dentry); @@ -431,7 +434,7 @@ static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, int nWritten; unsigned spos = pos; - unsigned saddr = addr; + unsigned saddr = (unsigned)addr; T((KERN_DEBUG"yaffs_commit_write addr %x pos %x nBytes %d\n",saddr,spos,nBytes)); @@ -613,7 +616,7 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_ inode->i_size = ipos; inode->i_blocks = (ipos + inode->i_blksize - 1)/ inode->i_blksize; - T((KERN_DEBUG"yaffs_file_write size updated to %d bytes, %d blocks\n",ipos,inode->i_blocks)); + T((KERN_DEBUG"yaffs_file_write size updated to %d bytes, %d blocks\n",ipos,(int)(inode->i_blocks))); } } @@ -704,7 +707,7 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) /* * File creation. Allocate an inode, and we're done.. */ -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) { struct inode *inode; @@ -727,7 +730,7 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d } T(("yaffs_mknod: making oject for %s, mode %x dev %x\n", - dentry->d_name.name, mode,dev)); + dentry->d_name.name, mode,rdev)); dev = parent->myDev; @@ -738,7 +741,7 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d default: // Special (socket, fifo, device...) T((KERN_DEBUG"yaffs_mknod: making special\n")); - obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,current->uid, current->gid,dev); + obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,current->uid, current->gid,rdev); break; case S_IFREG: // file T((KERN_DEBUG"yaffs_mknod: making file\n")); @@ -756,7 +759,7 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int d if(obj) { - inode = yaffs_get_inode(dir->i_sb, mode, dev, obj); + inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); d_instantiate(dentry, inode); T((KERN_DEBUG"yaffs_mknod created object %d count = %d\n",obj->objectId,atomic_read(&inode->i_count))); error = 0; @@ -802,13 +805,12 @@ static int yaffs_unlink(struct inode * dir, struct dentry *dentry) yaffs_Device *dev; - T((KERN_DEBUG"yaffs_unlink %d:%s\n",dir->i_ino,dentry->d_name.name)); + T((KERN_DEBUG"yaffs_unlink %d:%s\n",(int)(dir->i_ino),dentry->d_name.name)); dev = yaffs_InodeToObject(dir)->myDev; yaffs_GrossLock(dev); - nlinks = retVal = yaffs_Unlink(yaffs_InodeToObject(dir),dentry->d_name.name); @@ -930,6 +932,7 @@ static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struc yaffs_GrossLock(dev); + retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name, yaffs_InodeToObject(new_dir),new_dentry->d_name.name); yaffs_GrossUnlock(dev); @@ -1083,7 +1086,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; #endif - T(("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",sb->s_blocksize)); + T(("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",(int)(sb->s_blocksize))); #ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY T(("yaffs: Write verification disabled. All guarantees null and void\n"); @@ -1144,13 +1147,13 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl return NULL; } - printk(KERN_DEBUG" erase %x\n",mtd->erase); - printk(KERN_DEBUG" read %x\n",mtd->read); - printk(KERN_DEBUG" write %x\n",mtd->write); - printk(KERN_DEBUG" readoob %x\n",mtd->read_oob); - printk(KERN_DEBUG" writeoob %x\n",mtd->write_oob); - printk(KERN_DEBUG" oobblock %x\n",mtd->oobblock); - printk(KERN_DEBUG" oobsize %x\n",mtd->oobsize); + //printk(KERN_DEBUG" erase %x\n",mtd->erase); + //printk(KERN_DEBUG" read %x\n",mtd->read); + //printk(KERN_DEBUG" write %x\n",mtd->write); + //printk(KERN_DEBUG" readoob %x\n",mtd->read_oob); + //printk(KERN_DEBUG" writeoob %x\n",mtd->write_oob); + //printk(KERN_DEBUG" oobblock %x\n",mtd->oobblock); + //printk(KERN_DEBUG" oobsize %x\n",mtd->oobsize); if(!mtd->erase || @@ -1281,6 +1284,10 @@ static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name) buf +=sprintf(buf,"garbageCollections. %d\n",dev->garbageCollections); buf +=sprintf(buf,"nRetriedWrites..... %d\n",dev->nRetriedWrites); buf +=sprintf(buf,"nRetireBlocks...... %d\n",dev->nRetiredBlocks); + buf +=sprintf(buf,"eccFixed........... %d\n",dev->eccFixed); + buf +=sprintf(buf,"eccUnfixed......... %d\n",dev->eccUnfixed); + buf +=sprintf(buf,"tagsEccFixed....... %d\n",dev->tagsEccFixed); + buf +=sprintf(buf,"tagsEccUnfixed..... %d\n",dev->tagsEccUnfixed); buf +=sprintf(buf,"cacheHits.......... %d\n",dev->cacheHits); buf +=sprintf(buf,"nDeletedFiles...... %d\n",dev->nDeletedFiles); buf +=sprintf(buf,"nUnlinkedFiles..... %d\n",dev->nUnlinkedFiles); @@ -1357,7 +1364,7 @@ static int __init init_yaffs_fs(void) } #ifdef CONFIG_YAFFS_RAM_ENABLED - +#if 0 my_proc_ram_write_entry = create_proc_entry("yaffs_ram", S_IRUGO | S_IFREG, &proc_root); @@ -1370,6 +1377,8 @@ static int __init init_yaffs_fs(void) { my_proc_ram_write_entry->write_proc = yaffs_proc_ram_write; } +#endif + error = register_filesystem(&yaffs_ram_fs_type); if(error) { diff --git a/yaffs_guts.c b/yaffs_guts.c index eaa18fd..bfe10b7 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -14,6 +14,8 @@ */ //yaffs_guts.c +const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.10 2002-09-27 20:50:50 charles Exp $"; + #include "yportenv.h" #include "yaffsinterface.h" @@ -63,7 +65,7 @@ static int yaffs_CountBits(__u8 x) // Local prototypes static int yaffs_CheckObjectHashSanity(yaffs_Device *dev); static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr); -static void yaffs_GetTagsFromSpare(yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr); +static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr); static int yaffs_PutChunkIntoFile(yaffs_Object *in,int chunkInInode, int chunkInNAND, int inScan); static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectType type); @@ -178,19 +180,23 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 if(eccResult1>0) { T((TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND)); + dev->eccFixed++; } else if(eccResult1<0) { T((TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND)); + dev->eccUnfixed++; } if(eccResult2>0) { T((TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND)); + dev->eccFixed++; } else if(eccResult2<0) { T((TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND)); + dev->eccUnfixed++; } if(eccResult1 || eccResult2) @@ -488,7 +494,7 @@ void yaffs_CalcTagsECC(yaffs_Tags *tags) } -void yaffs_CheckECCOnTags(yaffs_Tags *tags) +int yaffs_CheckECCOnTags(yaffs_Tags *tags) { unsigned ecc = tags->ecc; @@ -496,9 +502,9 @@ void yaffs_CheckECCOnTags(yaffs_Tags *tags) ecc ^= tags->ecc; - if(ecc) + if(ecc && ecc <= 64) { - // Needs fixing + // TODO: Handle the failure better. Retire? unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes; ecc--; @@ -507,7 +513,17 @@ void yaffs_CheckECCOnTags(yaffs_Tags *tags) // Now recvalc the ecc yaffs_CalcTagsECC(tags); + + return 1; // recovered error + } + else if(ecc) + { + // Wierd ecc failure value + // TODO Need to do somethiong here + return -1; //unrecovered error } + + return 0; } @@ -1867,7 +1883,8 @@ int yaffs_GarbageCollectBlock(yaffs_Device *dev,int block) yaffs_ReadChunkFromNAND(dev,oldChunk,buffer, &spare,1); - yaffs_GetTagsFromSpare(&spare,&tags); + yaffs_GetTagsFromSpare(dev,&spare,&tags); + tags.serialNumber++; yaffs_LoadTagsIntoSpare(&spare,&tags); @@ -2020,9 +2037,10 @@ static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr) sparePtr->tagByte7 = tu->asBytes[7]; } -static void yaffs_GetTagsFromSpare(yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr) +static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr) { yaffs_TagsUnion *tu = (yaffs_TagsUnion *)tagsPtr; + int result; tu->asBytes[0]= sparePtr->tagByte0; tu->asBytes[1]= sparePtr->tagByte1; @@ -2033,7 +2051,15 @@ static void yaffs_GetTagsFromSpare(yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr) tu->asBytes[6]= sparePtr->tagByte6; tu->asBytes[7]= sparePtr->tagByte7; - yaffs_CheckECCOnTags(tagsPtr); + result = yaffs_CheckECCOnTags(tagsPtr); + if(result> 0) + { + dev->tagsEccFixed++; + } + else if(result <0) + { + dev->tagsEccUnfixed++; + } } static void yaffs_SpareInitialise(yaffs_Spare *spare) @@ -2049,7 +2075,7 @@ static int yaffs_ReadChunkTagsFromNAND(yaffs_Device *dev,int chunkInNAND, yaffs_ if(yaffs_ReadChunkFromNAND(dev,chunkInNAND,NULL,&spare,1) == YAFFS_OK) { *chunkDeleted = (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0; - yaffs_GetTagsFromSpare(&spare,tags); + yaffs_GetTagsFromSpare(dev,&spare,tags); return YAFFS_OK; } else @@ -2798,9 +2824,9 @@ int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 * buffer, __u32 offset, int nB #ifdef CONFIG_YAFFS_SHORT_OP_CACHE yaffs_ChunkCache *cache; -#else - __u8 localBuffer[YAFFS_BYTES_PER_CHUNK]; #endif + + __u8 localBuffer[YAFFS_BYTES_PER_CHUNK]; int chunk; int start; @@ -2849,8 +2875,15 @@ int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 * buffer, __u32 offset, int nB } else { +#ifdef WIN32 + // Under WinCE can't do direct transfer. Need to use a local buffer. + // This is because we otherwise screw up WinCE's memory mapper + yaffs_ReadChunkDataFromObject(in,chunk,localBuffer); + memcpy(buffer,localBuffer,YAFFS_BYTES_PER_CHUNK); +#else // A full chunk. Read directly into the supplied buffer. yaffs_ReadChunkDataFromObject(in,chunk,buffer); +#endif } n -= nToCopy; @@ -2914,8 +2947,16 @@ int yaffs_WriteDataToFile(yaffs_Object *in,const __u8 * buffer, __u32 offset, in } else { + +#ifdef WIN32 + // Under WinCE can't do direct transfer. Need to use a local buffer. + // This is because we otherwise screw up WinCE's memory mapper + memcpy(localBuffer,buffer,YAFFS_BYTES_PER_CHUNK); + chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,localBuffer,YAFFS_BYTES_PER_CHUNK,0); +#else // A full chunk. Write directly from the supplied buffer. chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,buffer,YAFFS_BYTES_PER_CHUNK,0); +#endif //T(("Write to chunk %d %d\n",chunk,chunkWritten)); } @@ -3432,7 +3473,7 @@ static int yaffs_Scan(yaffs_Device *dev) // This block looks ok, now what's in this chunk? - yaffs_GetTagsFromSpare(&spare,&tags); + yaffs_GetTagsFromSpare(dev,&spare,&tags); if(yaffs_CountBits(spare.pageStatus) < 6) { @@ -4038,6 +4079,10 @@ int yaffs_GutsInitialise(yaffs_Device *dev) dev->nDeletedFiles = 0; dev->nBackgroundDeletions=0; dev->nUnlinkedFiles = 0; + dev->eccFixed=0; + dev->eccUnfixed=0; + dev->tagsEccFixed=0; + dev->tagsEccUnfixed=0; yaffs_InitialiseBlocks(dev,nBlocks); diff --git a/yaffs_guts.h b/yaffs_guts.h index b42c7cb..4a63c99 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -13,6 +13,8 @@ * * * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + * $Id: yaffs_guts.h,v 1.10 2002-09-27 20:50:50 charles Exp $ */ #ifndef __YAFFS_GUTS_H__ @@ -423,6 +425,10 @@ struct yaffs_DeviceStruct int garbageCollections; int nRetriedWrites; int nRetiredBlocks; + int eccFixed; + int eccUnfixed; + int tagsEccFixed; + int tagsEccUnfixed; yaffs_Object *rootDir; yaffs_Object *lostNFoundDir; diff --git a/yaffs_mtdif.c b/yaffs_mtdif.c index 7f74b6f..923de91 100644 --- a/yaffs_mtdif.c +++ b/yaffs_mtdif.c @@ -12,6 +12,9 @@ * published by the Free Software Foundation. * */ + +const char *yaffs_mtdif_c_version = "$Id: yaffs_mtdif.c,v 1.3 2002-09-27 20:50:50 charles Exp $"; + #ifdef CONFIG_YAFFS_MTD_ENABLED #include "yportenv.h" diff --git a/yaffs_mtdif.h b/yaffs_mtdif.h index dd908ec..7431299 100644 --- a/yaffs_mtdif.h +++ b/yaffs_mtdif.h @@ -14,6 +14,7 @@ * * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. * + * $Id: yaffs_mtdif.h,v 1.4 2002-09-27 20:50:50 charles Exp $ */ #ifndef __YAFFS_MTDIF_H__ diff --git a/yaffs_nandemul.h b/yaffs_nandemul.h index bd51465..2faeb65 100644 --- a/yaffs_nandemul.h +++ b/yaffs_nandemul.h @@ -15,6 +15,7 @@ * * yaffs_nandemul.h: Interface to emulated NAND functions * + * $Id: yaffs_nandemul.h,v 1.4 2002-09-27 20:50:50 charles Exp $ */ #ifndef __YAFFS_NANDEMUL_H__ diff --git a/yaffs_ramem.c b/yaffs_ramem.c index 09e49c3..28ce406 100644 --- a/yaffs_ramem.c +++ b/yaffs_ramem.c @@ -15,6 +15,8 @@ //yaffs_ramem.c // Since this creates the RAM block at start up it is pretty useless for testing the scanner. +const char *yaffs_ramem_c_version = "$Id: yaffs_ramem.c,v 1.5 2002-09-27 20:50:50 charles Exp $"; + #ifndef __KERNEL__ #define CONFIG_YAFFS_RAM_ENABLED #endif diff --git a/yaffsdev b/yaffsdev deleted file mode 100755 index e103329..0000000 Binary files a/yaffsdev and /dev/null differ diff --git a/yaffsdev.proj b/yaffsdev.proj index 2ead24f..5a97bb6 100644 Binary files a/yaffsdev.proj and b/yaffsdev.proj differ diff --git a/yportenv.h b/yportenv.h index 6f42e10..6393174 100644 --- a/yportenv.h +++ b/yportenv.h @@ -1,143 +1,145 @@ -/* - * YAFFS: Yet another FFS. A NAND-flash specific file system. - * yportenv.h: Portable services used by yaffs. This is done to allow - * simple migration from kernel space into app space for testing. - * - * Copyright (C) 2002 Aleph One Ltd. - * for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 as - * published by the Free Software Foundation. - * - * - * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. - * - */ - -#ifndef __PORTENV_H__ -#define __PORTENV_H__ - - -#if defined WIN32 - -// Win32 -#include "stdlib.h" -#include "stdio.h" -#include "string.h" - -#define YMALLOC(x) malloc(x) -#define YFREE(x) free(x) - - -#define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s)) -#define YALERT(s) YINFO(s) - -#include - -#define YAFFS_LOSTNFOUND_NAME "LOST_CLUSTERS" -#define YAFFS_LOSTNFOUND_PREFIX "OBJ" - -#define YPRINTF(x) - -// Always pass the sum compare to overcome the case insensitivity issue -#define yaffs_SumCompare(x,y) 1 -#define yaffs_strcmp(a,b) _stricmp(a,b) - - -#define u_char unsigned char -#define loff_t int -#define S_IFDIR 04000 - -#define S_ISFIFO(x) 0 -#define S_ISCHR(x) 0 -#define S_ISBLK(x) 0 -#define S_ISSOCK(x) 0 - -extern unsigned yfsd_U32FileTimeNow(void); - -#define CURRENT_TIME yfsd_U32FileTimeNow() -#define YAFFS_ROOT_MODE FILE_ATTRIBUTE_ARCHIVE -#define YAFFS_LOSTNFOUND_MODE (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN) - - -#define TENDSTR "\r\n" -#define TSTR(x) TEXT(x) -#define T(x) RETAILMSG(1, x) - - -#elif defined __KERNEL__ - - - -// Linux kernel -#include "linux/kernel.h" -#include "linux/mm.h" -#include "linux/string.h" -#include "linux/slab.h" -#define YAFFS_LOSTNFOUND_NAME "lost+found" -#define YAFFS_LOSTNFOUND_PREFIX "obj" - -#define YPRINTF(x) printk x -#define YMALLOC(x) kmalloc(x,GFP_KERNEL) -#define YFREE(x) kfree(x) - -#define YAFFS_ROOT_MODE 0666 -#define YAFFS_LOSTNFOUND_MODE 0666 - - -#define yaffs_SumCompare(x,y) ((x) == (y)) -#define yaffs_strcmp(a,b) strcmp(a,b) - -#define TENDSTR "\n" -#define TSTR(x) KERN_DEBUG x -#define T(x) printk x - - -#else - -// Linux application -#include "stdlib.h" -#include "stdio.h" -#include "string.h" - -#define YMALLOC(x) malloc(x) -#define YFREE(x) free(x) - - -#define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s)) -#define YALERT(s) YINFO(s) - - -#define TENDSTR "\n" -#define TSTR(x) x -#define T(x) printf x - - -#define YAFFS_LOSTNFOUND_NAME "lost+found" -#define YAFFS_LOSTNFOUND_PREFIX "obj" -#define YPRINTF(x) printf x - -#define CURRENT_TIME 0 -#define YAFFS_ROOT_MODE 0666 -#define YAFFS_LOSTNFOUND_MODE 0666 - -#define yaffs_SumCompare(x,y) ((x) == (y)) -#define yaffs_strcmp(a,b) strcmp(a,b) - -#endif - - - -#undef YINFO - - -#define YINFO(s) YPRINTF((KERN_DEBUG __FILE__ " %d %s\n",__LINE__,s)) -#define YALERT(s) YINFO(s) - -#define YBUG() do{YINFO("bug");} while(0) - - -#endif +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yportenv.h: Portable services used by yaffs. This is done to allow + * simple migration from kernel space into app space for testing. + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + * $Id: yportenv.h,v 1.5 2002-09-27 20:50:50 charles Exp $ + * + */ + +#ifndef __PORTENV_H__ +#define __PORTENV_H__ + + +#if defined WIN32 + +// Win32 +#include "stdlib.h" +#include "stdio.h" +#include "string.h" + +#define YMALLOC(x) malloc(x) +#define YFREE(x) free(x) + + +#define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s)) +#define YALERT(s) YINFO(s) + +#include + +#define YAFFS_LOSTNFOUND_NAME "LOST_CLUSTERS" +#define YAFFS_LOSTNFOUND_PREFIX "OBJ" + +#define YPRINTF(x) + +// Always pass the sum compare to overcome the case insensitivity issue +#define yaffs_SumCompare(x,y) 1 +#define yaffs_strcmp(a,b) _stricmp(a,b) + + +#define u_char unsigned char +#define loff_t int +#define S_IFDIR 04000 + +#define S_ISFIFO(x) 0 +#define S_ISCHR(x) 0 +#define S_ISBLK(x) 0 +#define S_ISSOCK(x) 0 + +extern unsigned yfsd_U32FileTimeNow(void); + +#define CURRENT_TIME yfsd_U32FileTimeNow() +#define YAFFS_ROOT_MODE FILE_ATTRIBUTE_ARCHIVE +#define YAFFS_LOSTNFOUND_MODE (FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN) + + +#define TENDSTR "\r\n" +#define TSTR(x) TEXT(x) +#define T(x) RETAILMSG(1, x) + + +#elif defined __KERNEL__ + + + +// Linux kernel +#include "linux/kernel.h" +#include "linux/mm.h" +#include "linux/string.h" +#include "linux/slab.h" +#define YAFFS_LOSTNFOUND_NAME "lost+found" +#define YAFFS_LOSTNFOUND_PREFIX "obj" + +#define YPRINTF(x) printk x +#define YMALLOC(x) kmalloc(x,GFP_KERNEL) +#define YFREE(x) kfree(x) + +#define YAFFS_ROOT_MODE 0666 +#define YAFFS_LOSTNFOUND_MODE 0666 + + +#define yaffs_SumCompare(x,y) ((x) == (y)) +#define yaffs_strcmp(a,b) strcmp(a,b) + +#define TENDSTR "\n" +#define TSTR(x) KERN_DEBUG x +#define T(x) printk x + + +#else + +// Linux application +#include "stdlib.h" +#include "stdio.h" +#include "string.h" + +#define YMALLOC(x) malloc(x) +#define YFREE(x) free(x) + + +#define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s)) +#define YALERT(s) YINFO(s) + + +#define TENDSTR "\n" +#define TSTR(x) x +#define T(x) printf x + + +#define YAFFS_LOSTNFOUND_NAME "lost+found" +#define YAFFS_LOSTNFOUND_PREFIX "obj" +#define YPRINTF(x) printf x + +#define CURRENT_TIME 0 +#define YAFFS_ROOT_MODE 0666 +#define YAFFS_LOSTNFOUND_MODE 0666 + +#define yaffs_SumCompare(x,y) ((x) == (y)) +#define yaffs_strcmp(a,b) strcmp(a,b) + +#endif + + + +#undef YINFO + + +#define YINFO(s) YPRINTF((KERN_DEBUG __FILE__ " %d %s\n",__LINE__,s)) +#define YALERT(s) YINFO(s) + +#define YBUG() do{YINFO("bug");} while(0) + + +#endif