From e9e1115af8d1609165b3e5baf0aef838f29e91a1 Mon Sep 17 00:00:00 2001
From: hackbard <hackbard@staubsauger.localdomain>
Date: Sun, 9 Sep 2007 16:47:46 +0200
Subject: [PATCH] safety checkin: more pffs

---
 betty/flash.c |  5 +--
 betty/pffs.c  | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 betty/pffs.h  |  7 ++--
 3 files changed, 98 insertions(+), 6 deletions(-)

diff --git a/betty/flash.c b/betty/flash.c
index 64488e2..f4be416 100644
--- a/betty/flash.c
+++ b/betty/flash.c
@@ -11,7 +11,7 @@
  * sector addresses
  */
 
-unsigned long sector_address[19]={
+unsigned long sector_address[20]={
 	0x00000,0x02000,0x03000,0x04000,0x08000,
 	0x10000,0x18000,
 	0x20000,0x28000,
@@ -19,7 +19,8 @@ unsigned long sector_address[19]={
 	0x40000,0x48000,
 	0x50000,0x58000,
 	0x60000,0x68000,
-	0x70000,0x78000
+	0x70000,0x78000,
+	0x80000			// not a sector, end of flash!
 };
 
 /*
diff --git a/betty/pffs.c b/betty/pffs.c
index 995e108..7b3b5e8 100644
--- a/betty/pffs.c
+++ b/betty/pffs.c
@@ -11,19 +11,109 @@
  * functions
  */
 
+u32 pffs_get_ptr(t_pffs *pffs,u8 sector) {
+
+	u16 data[3];
+	u32 iaddr;
+	u32 daddr;
+	u8 fnlen;
+	u8 found;
+
+	iaddr=0;
+	daddr=0;
+	found=0;
+
+	while(1) {
+		pffs->fr(pffs->base_addr+pffs->sec_addr[sector]+iaddr,data,6);
+		if(!((data[0]&0xff00)==PFFS_INDEX_MAGIC))
+			break;
+		found=1;
+		fnlen=(data[0]&0x00f0)>>4;
+		iaddr+=(6+fnlen+fnlen);
+		daddr=((data[0]&0x000f)<<16)|data[1];
+	}
+
+	pffs->data_ptr=daddr;
+
+	if(found) {
+		pffs->index_ptr=pffs->sec_addr[sector]+iaddr;
+		return 0;
+	}
+	else
+		return -1;
+}
+
+int pffs_sec_empty(t_pffs *pffs,u8 sec) {
+
+	u32 addr;
+	u16 data;
+
+	addr=pffs->base_addr|pffs->sec_addr[sec];
+
+	while(addr<(pffs->base_addr|pffs->sec_addr[sec+1])) {
+		data=*((u16 *)(addr));
+		if(data!=0xffff)
+			return 0;
+		addr+=2;
+	}
+
+	return 1;
+}
+
+#define pffs_sec_erase(pffs,sec) pffs->fe(pffs->base_addr|pffs->sec_addr[sec])
+
+int pffs_reorientate(t_pffs *pffs) {
+
+	u8 sec,sec0,sec1;
+
+	/* check index sectors */
+	sec0=pffs->sec_num_index[0];
+	sec1=pffs->sec_num_index[1];
+	if(!(pffs_get_ptr(pffs,sec0)&pffs_get_ptr(pffs,sec1)))
+		return 0;
+
+	/* initial run => no data + no index assumed => check whether erased! */
+	// erase index sectors
+	if(!pffs_sec_empty(pffs,sec0))
+		pffs_sec_erase(pffs,sec0);
+	if(!pffs_sec_empty(pffs,sec1))
+		pffs_sec_erase(pffs,sec1);
+	// erase data sectors
+	sec0=pffs->sec_num_data[0];
+	sec1=pffs->sec_num_data[1];
+	for(sec=sec0;sec<=sec1;sec++)
+		if(!pffs_sec_empty(pffs,sec))
+			pffs_sec_erase(pffs,sec);
+
+	return 0;
+}
+
 int pffs_flash_register(t_pffs *pffs,u32 base_addr,u8 sec_num,u32 *sec_addr,
-                        u8 dmin,u8 dmax,u8 index1,u8 index2,
+                        u8 sec_num_data_min,u8 sec_num_data_max,
+			u8 sec_num_index0,u8 sec_num_index1,
                         int (*fw)(u32 addr,u16 *buf,int len),
 			int (*fr)(u32 addr,u16 *buf,int len),
 			int (*fe)(u32 addr)) {
 
+	/* assign physical flash specs */
 	pffs->base_addr=base_addr;
 	pffs->sec_num=sec_num;
 	pffs->sec_addr=sec_addr;
+
+	/* specified index and data sectors */
+	pffs->sec_num_data[0]=sec_num_data_min;
+	pffs->sec_num_data[1]=sec_num_data_max;
+	pffs->sec_num_index[0]=sec_num_index0;
+	pffs->sec_num_index[1]=sec_num_index1;
+
+	/* flash acccess function pointers */
 	pffs->fw=fw;
 	pffs->fr=fr;
 	pffs->fe=fe;
 
+	/* orientate */
+	pffs_reorientate(pffs);
+
 	pffs->state|=PFFS_REGISTERED;
 
 	return 0;
diff --git a/betty/pffs.h b/betty/pffs.h
index 92b4821..72ec880 100644
--- a/betty/pffs.h
+++ b/betty/pffs.h
@@ -15,6 +15,8 @@
 
 #define PFFS_REGISTERED		(1<<0)
 
+#define PFFS_INDEX_MAGIC	0x7000
+
 /* type definitions */
 
 typedef struct s_pffs {
@@ -28,11 +30,10 @@ typedef struct s_pffs {
 	int (*fe)(u32 addr);
 	/* pffs internal variables */
 	u8 state;
-	u8 sec_num_data_min;
-	u8 sec_num_data_max;
-	u8 sec_num_index[2];
 	u32 data_ptr;
 	u32 index_ptr;
+	u8 sec_num_data[2];
+	u8 sec_num_index[2];
 } t_pffs;
 
 /* function prototypes */
-- 
2.39.5