diff options
| author | wdenk <wdenk> | 2003-03-14 20:47:52 +0000 | 
|---|---|---|
| committer | wdenk <wdenk> | 2003-03-14 20:47:52 +0000 | 
| commit | 06d01dbe000057e5df4af0f113242f0eba716340 (patch) | |
| tree | 9188617ad1907e44f41910b99af9bde7258338f9 | |
| parent | 09127c60964c47621937ada7b0ccbf0c26329376 (diff) | |
| download | olio-uboot-2014.01-06d01dbe000057e5df4af0f113242f0eba716340.tar.xz olio-uboot-2014.01-06d01dbe000057e5df4af0f113242f0eba716340.zip | |
* Avoid flicker on the TRAB's VFD by synchronizing the enable with
  the HSYNC/VSYNC. Requires new CPLD code (Version 101 for Rev. 100
  boards, version 153 for Rev. 200 boards).
* Patch by Vladimir Gurevich, 12 Mar 2003:
  Fix relocation problem of statically initialized string pointers
  in common/cmd_pci.c
* Patch by Kai-Uwe Blöm, 12 Mar 2003:
  Cleanup & bug fixes for JFFS2 code:
  - the memory mangement was broken. It caused havoc on malloc by
    writing beyond the block boundaries.
  - the length calculation for files was wrong, sometimes resulting
    in short file reads.
  - data copying now optionally takes fragment version numbers into
    account, to avoid copying from older data.
  See doc/README.JFFS2 for details.
| -rw-r--r-- | CHANGELOG | 18 | ||||
| -rw-r--r-- | board/csb226/csb226.c | 2 | ||||
| -rw-r--r-- | board/emk/top860/config.mk | 4 | ||||
| -rw-r--r-- | board/innokom/innokom.c | 4 | ||||
| -rw-r--r-- | board/lubbock/flash.c | 331 | ||||
| -rw-r--r-- | board/mpl/common/common_util.c | 2 | ||||
| -rw-r--r-- | board/mpl/vcma9/cmd_vcma9.c | 2 | ||||
| -rw-r--r-- | board/mpl/vcma9/vcma9.c | 1 | ||||
| -rw-r--r-- | board/trab/vfd.c | 172 | ||||
| -rw-r--r-- | common/cmd_pci.c | 79 | ||||
| -rw-r--r-- | cpu/arm920t/interrupts.c | 8 | ||||
| -rw-r--r-- | cpu/arm920t/start.S | 3 | ||||
| -rw-r--r-- | doc/README.JFFS2 | 8 | ||||
| -rw-r--r-- | drivers/cs8900.c | 4 | ||||
| -rw-r--r-- | drivers/cs8900.h | 2 | ||||
| -rw-r--r-- | drivers/s3c24x0_i2c.c | 2 | ||||
| -rw-r--r-- | fs/jffs2/jffs2_1pass.c | 630 | ||||
| -rw-r--r-- | fs/jffs2/jffs2_private.h | 33 | ||||
| -rw-r--r-- | include/asm-arm/global_data.h | 1 | ||||
| -rw-r--r-- | include/asm-arm/io.h | 65 | ||||
| -rw-r--r-- | include/configs/innokom.h | 68 | ||||
| -rw-r--r-- | include/i2c.h | 3 | 
22 files changed, 835 insertions, 607 deletions
| @@ -2,6 +2,24 @@  Changes since U-Boot 0.2.2:  ====================================================================== +* Avoid flicker on the TRAB's VFD by synchronizing the enable with +  the HSYNC/VSYNC. Requires new CPLD code (Version 101 for Rev. 100 +  boards, version 153 for Rev. 200 boards). + +* Patch by Vladimir Gurevich, 12 Mar 2003: +  Fix relocation problem of statically initialized string pointers +  in common/cmd_pci.c + +* Patch by Kai-Uwe Blöm, 12 Mar 2003: +  Cleanup & bug fixes for JFFS2 code: +  - the memory mangement was broken. It caused havoc on malloc by +    writing beyond the block boundaries. +  - the length calculation for files was wrong, sometimes resulting +    in short file reads. +  - data copying now optionally takes fragment version numbers into +    account, to avoid copying from older data. +  See doc/README.JFFS2 for details. +  * Patch by Josef Wagner, 12 Mar 2003:    - 16/32 MB and 50/80 MHz support with auto-detection for IP860    - ETH05 and BEDBUG support for CU824 diff --git a/board/csb226/csb226.c b/board/csb226/csb226.c index 11cab005c..a79d168e0 100644 --- a/board/csb226/csb226.c +++ b/board/csb226/csb226.c @@ -38,10 +38,10 @@  int misc_init_r(void)  { +#if 0	  	uchar *str;  	/* determine if the software update key is pressed during startup */ -#if 0	  	/* not ported yet... */  	if (GPLR0 & 0x00000800) {  		printf("using bootcmd_normal (sw-update button not pressed)\n"); diff --git a/board/emk/top860/config.mk b/board/emk/top860/config.mk index 95917a18b..7b940cb81 100644 --- a/board/emk/top860/config.mk +++ b/board/emk/top860/config.mk @@ -21,4 +21,8 @@  # MA 02111-1307 USA  # +# +# TOP860 board +# +  TEXT_BASE = 0x80000000 diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c index 17f6353d2..0176d9c2c 100644 --- a/board/innokom/innokom.c +++ b/board/innokom/innokom.c @@ -39,7 +39,7 @@   * The Innokom board has GPIO70 connected to SCLK which can be toggled   * until all chips think that their current cycles are finished.   */ -int i2c_init_board(void) +void i2c_init_board(void)  {  	int i; @@ -53,8 +53,6 @@ int i2c_init_board(void)  	}          /* set gpio pin to input */          GPDR(70) &= ~GPIO_bit(70); - -	return 0;  } diff --git a/board/lubbock/flash.c b/board/lubbock/flash.c index a93875083..dcf829b2c 100644 --- a/board/lubbock/flash.c +++ b/board/lubbock/flash.c @@ -28,7 +28,7 @@  #include <linux/byteorder/swab.h> -flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/ +flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips    */  /* Board support for 1 or 2 flash devices */  #define FLASH_PORT_WIDTH32 @@ -53,50 +53,47 @@ flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/   * Functions   */  static ulong flash_get_size (FPW *addr, flash_info_t *info); -static int   write_data (flash_info_t *info, ulong dest, FPW data); -static void  flash_get_offsets (ulong base, flash_info_t *info); -void inline  spin_wheel(void); +static int write_data (flash_info_t *info, ulong dest, FPW data); +static void flash_get_offsets (ulong base, flash_info_t *info); +void inline spin_wheel (void);  /*-----------------------------------------------------------------------   */  unsigned long flash_init (void)  { -   int i; -    ulong size = 0; +	int i; +	ulong size = 0; -    for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) -    { -        switch (i) -        { -           case 0: -            flash_get_size((FPW *)PHYS_FLASH_1, &flash_info[i]); -	         flash_get_offsets(PHYS_FLASH_1, &flash_info[i]); -                break; -           case 1: -            flash_get_size((FPW *)PHYS_FLASH_2, &flash_info[i]); -	         flash_get_offsets(PHYS_FLASH_2, &flash_info[i]); -                break; -           default: -	        panic("configured to many flash banks!\n"); -                break; -        } -	size += flash_info[i].size; -    } +	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { +		switch (i) { +		case 0: +			flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]); +			flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); +			break; +		case 1: +			flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]); +			flash_get_offsets (PHYS_FLASH_2, &flash_info[i]); +			break; +		default: +			panic ("configured to many flash banks!\n"); +			break; +		} +		size += flash_info[i].size; +	} -    /* Protect monitor and environment sectors -     */ -    flash_protect(FLAG_PROTECT_SET, -		  CFG_FLASH_BASE, -		  CFG_FLASH_BASE + _armboot_end_data - _armboot_start, -		  &flash_info[0]); +	/* Protect monitor and environment sectors +	 */ +	flash_protect ( FLAG_PROTECT_SET, +			CFG_FLASH_BASE, +			CFG_FLASH_BASE + _armboot_end_data - _armboot_start, +			&flash_info[0] ); -    flash_protect(FLAG_PROTECT_SET, -		  CFG_ENV_ADDR, -		  CFG_ENV_ADDR + CFG_ENV_SIZE - 1, -		  &flash_info[0]); +	flash_protect ( FLAG_PROTECT_SET, +			CFG_ENV_ADDR, +			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] ); -    return size; +	return size;  }  /*----------------------------------------------------------------------- @@ -119,39 +116,45 @@ static void flash_get_offsets (ulong base, flash_info_t *info)  /*-----------------------------------------------------------------------   */ -void flash_print_info  (flash_info_t *info) +void flash_print_info (flash_info_t *info)  {  	int i;  	if (info->flash_id == FLASH_UNKNOWN) {  		printf ("missing or unknown FLASH type\n");  		return; -        } +	}  	switch (info->flash_id & FLASH_VENDMASK) { -		case FLASH_MAN_INTEL:	printf ("INTEL ");		break; -		default:		printf ("Unknown Vendor ");	break; +	case FLASH_MAN_INTEL: +		printf ("INTEL "); +		break; +	default: +		printf ("Unknown Vendor "); +		break;  	}  	switch (info->flash_id & FLASH_TYPEMASK) { -   case FLASH_28F128J3A: -				printf ("28F128J3A\n"); break; -	default:		printf ("Unknown Chip Type\n"); break; -        } +	case FLASH_28F128J3A: +		printf ("28F128J3A\n"); +		break; +	default: +		printf ("Unknown Chip Type\n"); +		break; +	}  	printf ("  Size: %ld MB in %d Sectors\n", -	        info->size >> 20, info->sector_count); +			info->size >> 20, info->sector_count);  	printf ("  Sector Start Addresses:"); -	for (i=0; i<info->sector_count; ++i) { -	        if ((i % 5) == 0) -	        printf ("\n   "); +	for (i = 0; i < info->sector_count; ++i) { +		if ((i % 5) == 0) +			printf ("\n   ");  		printf (" %08lX%s",  			info->start[i], -			info->protect[i] ? " (RO)" : "     " -		); -        } -        printf ("\n"); +			info->protect[i] ? " (RO)" : "     "); +	} +	printf ("\n");  	return;  } @@ -163,37 +166,37 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)  	volatile FPW value;  	/* Write auto select command: read Manufacturer ID */ -	addr[0x5555] = (FPW)0x00AA00AA; -	addr[0x2AAA] = (FPW)0x00550055; -	addr[0x5555] = (FPW)0x00900090; +	addr[0x5555] = (FPW) 0x00AA00AA; +	addr[0x2AAA] = (FPW) 0x00550055; +	addr[0x5555] = (FPW) 0x00900090; -   mb(); +	mb ();  	value = addr[0]; -   switch (value) { +	switch (value) { -   case (FPW)INTEL_MANUFACT: -      info->flash_id = FLASH_MAN_INTEL; -      break; +	case (FPW) INTEL_MANUFACT: +		info->flash_id = FLASH_MAN_INTEL; +		break;  	default:  		info->flash_id = FLASH_UNKNOWN;  		info->sector_count = 0;  		info->size = 0; -		addr[0] = (FPW)0x00FF00FF;      /* restore read mode */ -		return (0);			/* no or unknown flash	*/ +		addr[0] = (FPW) 0x00FF00FF;	/* restore read mode */ +		return (0);			/* no or unknown flash  */  	} -   mb(); -	value = addr[1];			/* device ID		*/ +	mb (); +	value = addr[1];			/* device ID        */ -   switch (value) { +	switch (value) { -   case (FPW)INTEL_ID_28F128J3A: -      info->flash_id += FLASH_28F128J3A; -      info->sector_count = 128; -      info->size = 0x02000000; -      break;            /* => 16 MB     */ +	case (FPW) INTEL_ID_28F128J3A: +		info->flash_id += FLASH_28F128J3A; +		info->sector_count = 128; +		info->size = 0x02000000; +		break;				/* => 16 MB     */  	default:  		info->flash_id = FLASH_UNKNOWN; @@ -204,9 +207,9 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)  		printf ("** ERROR: sector count %d > max (%d) **\n",  			info->sector_count, CFG_MAX_FLASH_SECT);  		info->sector_count = CFG_MAX_FLASH_SECT; -    } +	} -	addr[0] = (FPW)0x00FF00FF;      /* restore read mode */ +	addr[0] = (FPW) 0x00FF00FF;		/* restore read mode */  	return (info->size);  } @@ -215,34 +218,34 @@ static ulong flash_get_size (FPW *addr, flash_info_t *info)  /*-----------------------------------------------------------------------   */ -int	flash_erase (flash_info_t *info, int s_first, int s_last) +int flash_erase (flash_info_t *info, int s_first, int s_last)  { -    int flag, prot, sect; -	ulong type, start, now, last; +	int flag, prot, sect; +	ulong type, start, last;  	int rcode = 0; -    if ((s_first < 0) || (s_first > s_last)) { +	if ((s_first < 0) || (s_first > s_last)) {  		if (info->flash_id == FLASH_UNKNOWN) {  			printf ("- missing\n");  		} else {  			printf ("- no sectors to erase\n");  		}  		return 1; -    } +	}  	type = (info->flash_id & FLASH_VENDMASK);  	if ((type != FLASH_MAN_INTEL)) {  		printf ("Can't erase unknown flash type %08lx - aborted\n",  			info->flash_id);  		return 1; -    } +	} -    prot = 0; -    for (sect=s_first; sect<=s_last; ++sect) { -	if (info->protect[sect]) { -	    prot++; +	prot = 0; +	for (sect = s_first; sect <= s_last; ++sect) { +		if (info->protect[sect]) { +			prot++; +		}  	} -    }  	if (prot) {  		printf ("- Warning: %d protected sectors will not be erased!\n", @@ -252,42 +255,42 @@ int	flash_erase (flash_info_t *info, int s_first, int s_last)  	}  	start = get_timer (0); -	last  = start; +	last = start; -   /* Disable interrupts which might cause a timeout here */ -    flag = disable_interrupts(); +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts (); -    /* Start erase on unprotected sectors */ -	for (sect = s_first; sect<=s_last; sect++) { +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect <= s_last; sect++) {  		if (info->protect[sect] == 0) {	/* not protected */ -			FPWV *addr = (FPWV *)(info->start[sect]); +			FPWV *addr = (FPWV *) (info->start[sect]);  			FPW status; -	printf("Erasing sector %2d ... ", sect); +			printf ("Erasing sector %2d ... ", sect); -	/* arm simple, non interrupt dependent timer */ -	reset_timer_masked(); +			/* arm simple, non interrupt dependent timer */ +			reset_timer_masked (); -			*addr = (FPW)0x00500050;	/* clear status register */ -			*addr = (FPW)0x00200020;	/* erase setup */ -			*addr = (FPW)0x00D000D0;	/* erase confirm */ +			*addr = (FPW) 0x00500050;	/* clear status register */ +			*addr = (FPW) 0x00200020;	/* erase setup */ +			*addr = (FPW) 0x00D000D0;	/* erase confirm */ -			while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) { -		if (get_timer_masked() > CFG_FLASH_ERASE_TOUT) { +			while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { +				if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {  					printf ("Timeout\n"); -					*addr = (FPW)0x00B000B0; /* suspend erase	  */ -					*addr = (FPW)0x00FF00FF; /* reset to read mode */ +					*addr = (FPW) 0x00B000B0;	/* suspend erase     */ +					*addr = (FPW) 0x00FF00FF;	/* reset to read mode */  					rcode = 1;  					break; -	} -    } +				} +			} -			*addr = 0x00500050; /* clear status register cmd.   */ -			*addr = 0x00FF00FF; /* resest to read mode          */ +			*addr = 0x00500050;	/* clear status register cmd.   */ +			*addr = 0x00FF00FF;	/* resest to read mode          */  			printf (" done\n"); -        } -        } +		} +	}  	return rcode;  } @@ -301,7 +304,7 @@ int	flash_erase (flash_info_t *info, int s_first, int s_last)  int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  { -    ulong cp, wp; +	ulong cp, wp;  	FPW data;  	int count, i, l, rc, port_width; @@ -317,67 +320,66 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  	port_width = 4;  #endif -    /* -     * handle unaligned start bytes -     */ -    if ((l = addr - wp) != 0) { -	data = 0; -	for (i=0, cp=wp; i<l; ++i, ++cp) { -			data = (data << 8) | (*(uchar *)cp); -	} -		for (; i<port_width && cnt>0; ++i) { +	/* +	 * handle unaligned start bytes +	 */ +	if ((l = addr - wp) != 0) { +		data = 0; +		for (i = 0, cp = wp; i < l; ++i, ++cp) { +			data = (data << 8) | (*(uchar *) cp); +		} +		for (; i < port_width && cnt > 0; ++i) {  			data = (data << 8) | *src++; -	    --cnt; -	    ++cp; -	} -		for (; cnt==0 && i<port_width; ++i, ++cp) { -			data = (data << 8) | (*(uchar *)cp); -	} +			--cnt; +			++cp; +		} +		for (; cnt == 0 && i < port_width; ++i, ++cp) { +			data = (data << 8) | (*(uchar *) cp); +		} -		if ((rc = write_data(info, wp, SWAP(data))) != 0) { -	    return (rc); -	} +		if ((rc = write_data (info, wp, SWAP (data))) != 0) { +			return (rc); +		}  		wp += port_width; -    } +	} -    /* -     * handle word aligned part -     */ +	/* +	 * handle word aligned part +	 */  	count = 0;  	while (cnt >= port_width) {  		data = 0; -		for (i=0; i<port_width; ++i) { +		for (i = 0; i < port_width; ++i) {  			data = (data << 8) | *src++;  		} -		if ((rc = write_data(info, wp, SWAP(data))) != 0) { -	    return (rc); -	} -		wp  += port_width; +		if ((rc = write_data (info, wp, SWAP (data))) != 0) { +			return (rc); +		} +		wp += port_width;  		cnt -= port_width; -		if (count++ > 0x800) -		{ -         spin_wheel(); +		if (count++ > 0x800) { +			spin_wheel ();  			count = 0;  		} -    } +	} -    if (cnt == 0) { +	if (cnt == 0) {  		return (0); -    } +	} -    /* -     * handle unaligned tail bytes -     */ -    data = 0; -	for (i=0, cp=wp; i<port_width && cnt>0; ++i, ++cp) { +	/* +	 * handle unaligned tail bytes +	 */ +	data = 0; +	for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {  		data = (data << 8) | *src++; -	--cnt; -    } -	for (; i<port_width; ++i, ++cp) { -		data = (data << 8) | (*(uchar *)cp); +		--cnt; +	} +	for (; i < port_width; ++i, ++cp) { +		data = (data << 8) | (*(uchar *) cp);  	} -	return (write_data(info, wp, SWAP(data))); +	return (write_data (info, wp, SWAP (data)));  }  /*----------------------------------------------------------------------- @@ -388,45 +390,42 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)   */  static int write_data (flash_info_t *info, ulong dest, FPW data)  { -	FPWV *addr = (FPWV *)dest; +	FPWV *addr = (FPWV *) dest;  	ulong status; -	ulong start;  	int flag;  	/* Check if Flash is (sufficiently) erased */  	if ((*addr & data) != data) { -		printf("not erased at %08lx (%x)\n",(ulong)addr,*addr); +		printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);  		return (2);  	}  	/* Disable interrupts which might cause a timeout here */ -	flag = disable_interrupts(); +	flag = disable_interrupts (); -	*addr = (FPW)0x00400040;		/* write setup */ +	*addr = (FPW) 0x00400040;	/* write setup */  	*addr = data;  	/* arm simple, non interrupt dependent timer */ -	reset_timer_masked(); +	reset_timer_masked ();  	/* wait while polling the status register */ -	while (((status = *addr) & (FPW)0x00800080) != (FPW)0x00800080) { -		if (get_timer_masked() > CFG_FLASH_WRITE_TOUT) { -			*addr = (FPW)0x00FF00FF;	/* restore read mode */ +	while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { +		if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { +			*addr = (FPW) 0x00FF00FF;	/* restore read mode */  			return (1);  		} -    } +	} -	*addr = (FPW)0x00FF00FF;	/* restore read mode */ +	*addr = (FPW) 0x00FF00FF;	/* restore read mode */  	return (0);  } -void inline -spin_wheel(void) +void inline spin_wheel (void)  { -   static int r=0,p=0; -   static char w[] = "\\/-"; +	static int p = 0; +	static char w[] = "\\/-"; -   printf("\010%c", w[p]); -   (++p == 3) ? (p = 0) : 0; +	printf ("\010%c", w[p]); +	(++p == 3) ? (p = 0) : 0;  } - diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index 0a67090fe..19ead331b 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -49,7 +49,9 @@ int mpl_prg(unsigned long src,unsigned long size)  	unsigned long start;  	flash_info_t *info;  	int i,rc; +#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)  	unsigned long *magic = (unsigned long *)src; +#endif  	info = &flash_info[0]; diff --git a/board/mpl/vcma9/cmd_vcma9.c b/board/mpl/vcma9/cmd_vcma9.c index cdafc50d6..80bb61b2b 100644 --- a/board/mpl/vcma9/cmd_vcma9.c +++ b/board/mpl/vcma9/cmd_vcma9.c @@ -102,7 +102,7 @@ int do_vcma9(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  				printf("\nplease defined 'ethaddr'\n");  			}  		} else if (strcmp(argv[2], "dump") == 0) { -			uchar addr, endaddr, csum; ushort data; +			uchar addr = 0, endaddr, csum; ushort data;  			printf("Dump of CS8900 config device: ");  			cs8900_e2prom_read(addr, &data); diff --git a/board/mpl/vcma9/vcma9.c b/board/mpl/vcma9/vcma9.c index 8e3552e2b..e452a7b28 100644 --- a/board/mpl/vcma9/vcma9.c +++ b/board/mpl/vcma9/vcma9.c @@ -183,7 +183,6 @@ static uchar Get_Board_PCB(void)  int checkboard(void)  {  	unsigned char s[50]; -	unsigned char bc, var, rc;  	int i;  	backup_t *b = (backup_t *) s; diff --git a/board/trab/vfd.c b/board/trab/vfd.c index 894e3157d..9b61f6eb6 100644 --- a/board/trab/vfd.c +++ b/board/trab/vfd.c @@ -59,10 +59,24 @@  #define	FRAME_BUF_SIZE	((256*4*56)/8)  #define frame_buf_offs 4 +/* defines for starting Timer3 as CPLD-Clk */ +#define START3			(1 << 16) +#define UPDATE3			(1 << 17) +#define INVERT3			(1 << 18) +#define RELOAD3			(1 << 19) + +/* CPLD-Register for controlling vfd-blank-signal */ +#define VFD_DISABLE	(*(volatile uchar *)0x04038000=0x0000) +#define VFD_ENABLE	(*(volatile uchar *)0x04038000=0x0001) +  /* Supported VFD Types */  #define	VFD_TYPE_T119C		1	/* Noritake T119C VFD */  #define	VFD_TYPE_MN11236	2 +/*#define NEW_CPLD_CLK*/ + +int vfd_board_id; +  /* taken from armboot/common/vfd.c */  unsigned long adr_vfd_table[112][18][2][4][2];  unsigned char bit_vfd_table[112][18][2][4][2]; @@ -80,9 +94,7 @@ void init_grid_ctrl(void)  	/*  	 * clear frame buffer (logical clear => set to "black")  	 */ -	memset ((void *)(gd->fb_base), -		gd->vfd_inv_data ? 0xFF : 0, -		FRAME_BUF_SIZE); +	memset ((void *)(gd->fb_base), 0, FRAME_BUF_SIZE);  	switch (gd->vfd_type) {  	case VFD_TYPE_T119C: @@ -98,10 +110,7 @@ void init_grid_ctrl(void)  			bit_nr = bit % 8;  			bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;  			temp=(*(volatile unsigned char*)(adr)); -			if (gd->vfd_inv_data) -				temp &= ~(1<<bit_nr); -			else -				temp |=  (1<<bit_nr); +			temp |=  (1<<bit_nr);  			(*(volatile unsigned char*)(adr))=temp;  			if(grid_cycle<55) @@ -115,10 +124,7 @@ void init_grid_ctrl(void)  			bit_nr = bit%8;  			bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;  			temp=(*(volatile unsigned char*)(adr)); -			if (gd->vfd_inv_data) -				temp &= ~(1<<bit_nr); -			else -				temp |=  (1<<bit_nr); +			temp |=  (1<<bit_nr);  			(*(volatile unsigned char*)(adr))=temp;  		}  	    } @@ -136,10 +142,7 @@ void init_grid_ctrl(void)  			bit_nr = bit % 8;  			bit_nr = (bit_nr > 3) ? bit_nr-4 : bit_nr+4;  			temp=(*(volatile unsigned char*)(adr)); -			if (gd->vfd_inv_data) -				temp &= ~(1<<bit_nr); -			else -				temp |=  (1<<bit_nr); +			temp |=  (1<<bit_nr);  			(*(volatile unsigned char*)(adr))=temp;  			if(grid_cycle<37) @@ -152,10 +155,7 @@ void init_grid_ctrl(void)  			bit_nr = bit%8;  			bit_nr = (bit_nr>3)?bit_nr-4:bit_nr+4;  			temp=(*(volatile unsigned char*)(adr)); -			if (gd->vfd_inv_data) -				temp &= ~(1<<bit_nr); -			else -				temp |=  (1<<bit_nr); +			temp |=  (1<<bit_nr);  			(*(volatile unsigned char*)(adr))=temp;  		}  	    } @@ -250,7 +250,7 @@ void create_vfd_table(void)  			for(entry=0;entry<2;entry++) {  			    unsigned long adr  = gd->fb_base;  			    unsigned int bit_nr = 0; -			     +  			    if (vfd_table[x][y][color][display][entry]) {  				pixel  = vfd_table[x][y][color][display][entry] + frame_buf_offs; @@ -295,18 +295,11 @@ void set_vfd_pixel(unsigned char x, unsigned char y,  	bit_nr = bit_vfd_table[x][y][color][display][0];  	temp=(*(volatile unsigned char*)(adr)); -	if (gd->vfd_inv_data) { -		if (value) -			temp &= ~(1<<bit_nr); -		else -			temp |=  (1<<bit_nr); -	} else { -		if (value) -			temp |=  (1<<bit_nr); -		else -			temp &= ~(1<<bit_nr); -	} -	 +	if (value) +		temp |=  (1<<bit_nr); +	else +		temp &= ~(1<<bit_nr); +  	(*(volatile unsigned char*)(adr))=temp;  } @@ -363,22 +356,59 @@ void transfer_pic(int display, unsigned char *adr, int height, int width)   * This function initializes VFD clock that is needed for the CPLD that   * manages the keyboard.   */ -int vfd_init_clocks(void) +int vfd_init_clocks (void)  { -	/* Port-Pins als LCD-Ausgang */ -	rPCCON =   (rPCCON & 0xFFFFFF00)| 0x000000AA; -	/* Port-Pins als LCD-Ausgang */ -	rPDCON =   (rPDCON & 0xFFFFFF03)| 0x000000A8; -#ifdef CFG_WITH_VFRAME -	/* mit VFRAME zum Messen */ -	rPDCON =   (rPDCON & 0xFFFFFF00)| 0x000000AA; -#endif -	rLCDCON2 = 0x000DC000; -	rLCDCON3 = 0x0051000A; -	rLCDCON4 = 0x00000001; -	rLCDCON5 = 0x00000440; +	/* try to determine display type from the value +	 * defined by pull-ups +	 */ +	rPCUP = (rPCUP & 0xFFF0);	/* activate  GPC0...GPC3 pullups */ +	rPCCON = (rPCCON & 0xFFFFFF00);	/* configure GPC0...GPC3 as inputs */ +	udelay (10);				/* allow signals to settle */ +	vfd_board_id = (~rPCDAT) & 0x000F;	/* read GPC0...GPC3 port pins */ + +	VFD_DISABLE;				/* activate blank for the vfd */ + +#define	NEW_CPLD_CLK + +#ifdef NEW_CPLD_CLK +	if (vfd_board_id) { +		/* If new board revision, then use PWM 3 as cpld-clock */ +		/* Enable 500 Hz timer for fill level sensor to operate properly */ +		/* Configure TOUT3 as functional pin, disable pull-up */ +		rPDCON &= ~0x30000; +		rPDCON |= 0x20000; +		rPDUP |= (1 << 8); + +		/* Configure the prescaler */ +		rTCFG0 &= ~0xff00; +		rTCFG0 |= 0x0f00; + +		/* Select MUX input (divider) for timer3 (1/16) */ +		rTCFG1 &= ~0xf000; +		rTCFG1 |= 0x3000; + +		/* Enable autoreload and set the counter and compare +		 * registers to values for the 500 Hz clock +		 * (for a given  prescaler (15) and divider (16)): +		 * counter = (66000000 / 500) >> 9; +		 */ +		rTCNTB3 = 0x101; +		rTCMPB3 = 0x101 / 2; + +		/* Start timer */ +		rTCON = (rTCON | UPDATE3 | RELOAD3) & ~INVERT3; +		rTCON = (rTCON | START3) & ~UPDATE3; +	} +#endif +	/* If old board revision, then use vm-signal as cpld-clock */ +	rLCDCON2 = 0x00FFC000; +	rLCDCON3 = 0x0007FF00; +	rLCDCON4 = 0x00000000; +	rLCDCON5 = 0x00000400;  	rLCDCON1 = 0x00000B75; +	/* VM (GPD1) is used as clock for the CPLD */ +	rPDCON = (rPDCON & 0xFFFFFFF3) | 0x00000008;  	return 0;  } @@ -397,7 +427,7 @@ int drv_vfd_init(void)  	char *tmp;  	ulong palette;  	static int vfd_init_done = 0; -	int vfd_id; +	int vfd_inv_data = 0;  	DECLARE_GLOBAL_DATA_PTR; @@ -405,17 +435,9 @@ int drv_vfd_init(void)  		return (0);  	vfd_init_done = 1; -	/* try to determine display type from the value -	 * defined by pull-ups -	 */ -	rPCUP  = (rPCUP & 0xFFF0);	/* activate  GPC0...GPC3 pullups */ -	rPCCON = (rPCCON & 0xFFFFFF00);	/* configure GPC0...GPC3 as inputs */ -	udelay(10);			/* allow signals to settle */ +	debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_board_id); -	vfd_id = (~rPCDAT) & 0x000F;	/* read GPC0...GPC3 port pins */ -	debug("Detecting Revison of WA4-VFD: ID=0x%X\n", vfd_id); - -	switch (vfd_id) { +	switch (vfd_board_id) {  	case 0:			/* board revision < Rev.200 */  		if ((tmp = getenv ("vfd_type")) == NULL) {  			break; @@ -428,19 +450,18 @@ int drv_vfd_init(void)  			/* cannot use printf for a warning here */  			gd->vfd_type = 0;	/* unknown */  		} -		gd->vfd_inv_data = 0;  		break;  	default:		/* default to MN11236, data inverted */  		gd->vfd_type = VFD_TYPE_MN11236; -		gd->vfd_inv_data = 1; +		vfd_inv_data = 1;  		setenv ("vfd_type", "MN11236");  	}  	debug ("VFD type: %s%s\n",  		(gd->vfd_type == VFD_TYPE_T119C)   ? "T119C" :  		(gd->vfd_type == VFD_TYPE_MN11236) ? "MN11236" :  		"unknown", -		gd->vfd_inv_data ? ", inverted data" : ""); +		vfd_inv_data ? ", inverted data" : "");  	gd->fb_base = gd->fb_base;  	create_vfd_table(); @@ -458,11 +479,33 @@ int drv_vfd_init(void)  	 * (wrap around)  	 * see manual S3C2400  	 */ +	/* Stopp LCD-Controller */ +	rLCDCON1 = 0x00000000;  	/* frame buffer startadr */  	rLCDSADDR1 = gd->fb_base >> 1;   	/* frame buffer endadr */  	rLCDSADDR2 = (gd->fb_base + FRAME_BUF_SIZE) >> 1;  	rLCDSADDR3 = ((256/4)); +	rLCDCON2 = 0x000DC000; +	rLCDCON3 = 0x0051000A; +	rLCDCON4 = 0x00000001; +	if (gd->vfd_type && vfd_inv_data) +		rLCDCON5 = 0x000004C0; +	else +		rLCDCON5 = 0x00000440; + +	/* Port pins as LCD output */ +	rPCCON =   (rPCCON & 0xFFFFFF00)| 0x000000AA; +	rPDCON =   (rPDCON & 0xFFFFFF03)| 0x000000A8; + +	/* Synchronize VFD enable with LCD controller to avoid flicker	*/ +	rLCDCON1 = 0x00000B75;			/* Start LCD-Controller	*/ +	while((rLCDCON5 & 0x180000)!=0x100000);	/* Wait for end of VSYNC */ +	while((rLCDCON5 & 0x060000)!=0x040000);	/* Wait for next HSYNC	*/ +	while((rLCDCON5 & 0x060000)==0x040000); +	while((rLCDCON5 & 0x060000)!=0x000000); +	if(gd->vfd_type) +		VFD_ENABLE;  	debug ("LCDSADDR1: %lX\n", rLCDSADDR1);  	debug ("LCDSADDR2: %lX\n", rLCDSADDR2); @@ -471,6 +514,17 @@ int drv_vfd_init(void)  	return 0;  } +/* + * Disable VFD: should be run before resetting the system: + * disable VM, enable pull-up + */ +void disable_vfd (void) +{ +	VFD_DISABLE; +	rPDCON &= ~0xC; +	rPDUP  &= ~0x2; +} +  /************************************************************************/  /* ** ROM capable initialization part - needed to reserve FB memory	*/  /************************************************************************/ diff --git a/common/cmd_pci.c b/common/cmd_pci.c index 5a3b5574e..a26deddcd 100644 --- a/common/cmd_pci.c +++ b/common/cmd_pci.c @@ -115,28 +115,65 @@ void pciinfo(int BusNum, int ShortPCIListing)  char* pci_classes_str(u8 class)  { -	static char *pci_classes[] = { -		"Build before PCI Rev2.0", -		"Mass storage controller", -		"Network controller     ", -		"Display controller     ", -		"Multimedia device      ", -		"Memory controller      ", -		"Bridge device          ", -		"Simple comm. controller", -		"Base system peripheral ", -		"Input device           ", -		"Docking station        ", -		"Processor              ", -		"Serial bus controller  ", -		"Reserved entry         ", -		"Does not fit any class " -	}; - -	if (class < (sizeof pci_classes / sizeof *pci_classes)) -		return pci_classes[(int) class]; - +	switch (class) { +        case PCI_CLASS_NOT_DEFINED: +                return "Build before PCI Rev2.0"; +                break; +        case PCI_BASE_CLASS_STORAGE: +                return "Mass storage controller"; +                break; +        case PCI_BASE_CLASS_NETWORK: +                return "Network controller     "; +                break; +        case PCI_BASE_CLASS_DISPLAY: +                return "Display controller     "; +                break; +        case PCI_BASE_CLASS_MULTIMEDIA: +                return "Multimedia device      "; +                break; +        case PCI_BASE_CLASS_MEMORY: +                return "Memory controller      "; +                break; +        case PCI_BASE_CLASS_BRIDGE: +                return "Bridge device          "; +                break; +        case PCI_BASE_CLASS_COMMUNICATION: +                return "Simple comm. controller"; +                break; +        case PCI_BASE_CLASS_SYSTEM: +                return "Base system peripheral "; +                break; +        case PCI_BASE_CLASS_INPUT: +                return "Input device           "; +                break; +        case PCI_BASE_CLASS_DOCKING: +                return "Docking station        "; +                break; +        case PCI_BASE_CLASS_PROCESSOR: +                return "Processor              "; +                break; +        case PCI_BASE_CLASS_SERIAL: +                return "Serial bus controller  "; +                break; +        case PCI_BASE_CLASS_INTELLIGENT: +                return "Intelligent controller "; +                break; +        case PCI_BASE_CLASS_SATELLITE: +                return "Satellite controller   "; +                break; +        case PCI_BASE_CLASS_CRYPT: +                return "Cryptographic device   "; +                break; +        case PCI_BASE_CLASS_SIGNAL_PROCESSING: +                return "DSP                    "; +                break; +        case PCI_CLASS_OTHERS: +                return "Does not fit any class "; +                break; +        default:  	return  "???                    "; +                break; +	};  }  /* diff --git a/cpu/arm920t/interrupts.c b/cpu/arm920t/interrupts.c index 963ccbd2a..195fb0147 100644 --- a/cpu/arm920t/interrupts.c +++ b/cpu/arm920t/interrupts.c @@ -199,9 +199,9 @@ int interrupt_init (void)  	/* load value for 10 ms timeout */  	lastdec = rTCNTB4 = timer_load_val;  	/* auto load, manual update of Timer 4 */ -	rTCON = 0x600000; +	rTCON = (rTCON & ~0x0700000) | 0x600000;  	/* auto load, start Timer 4 */ -	rTCON = 0x500000; +	rTCON = (rTCON & ~0x0700000) | 0x500000;  	timestamp = 0;  	return (0); @@ -296,8 +296,10 @@ ulong get_tbclk (void)  #if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)  	tbclk = timer_load_val * 100; -#elif defined(CONFIG_SMDK2410) +#elif defined(CONFIG_SMDK2410) || defined(CONFIG_VCMA9)  	tbclk = CFG_HZ; +#else +#	error "tbclk not configured"  #endif  	return tbclk; diff --git a/cpu/arm920t/start.S b/cpu/arm920t/start.S index a858dfa05..4a4825ab3 100644 --- a/cpu/arm920t/start.S +++ b/cpu/arm920t/start.S @@ -446,6 +446,9 @@ fiq:  reset_cpu:  #ifdef CONFIG_S3C2400  	bl	disable_interrupts +# ifdef CONFIG_TRAB +	bl	disable_vfd +# endif  	ldr	r1, _rWTCON  	ldr	r2, _rWTCNT  	/* Disable watchdog */ diff --git a/doc/README.JFFS2 b/doc/README.JFFS2 index 0d39c4645..324389515 100644 --- a/doc/README.JFFS2 +++ b/doc/README.JFFS2 @@ -9,6 +9,14 @@ fsload  - load binary file from a file system image  fsinfo  - print information about file systems  ls      - list files in a directory +If you boot from a partition which is mounted writable, and you +update your boot environment by replacing single files on that +partition, you should also define CFG_JFFS2_SORT_FRAGMENTS. Scanning +the JFFS2 filesystem takes *much* longer with this feature, though. +Sorting is done while inserting into the fragment list, which is +more or less a bubble sort. That algorithm is known to be O(n^2), +thus you should really consider if you can avoid it! +  There is two ways for JFFS2 to find the disk. The default way uses  the flash_info structure to find the start of a JFFS2 disk (called diff --git a/drivers/cs8900.c b/drivers/cs8900.c index b9fac8c54..d35332c83 100644 --- a/drivers/cs8900.c +++ b/drivers/cs8900.c @@ -296,7 +296,7 @@ int cs8900_e2prom_read(unsigned char addr, unsigned short *value)  /* write a 16-bit word into the EEPROM                     */  /***********************************************************/ -void cs8900_e2prom_write(unsigned char addr, unsigned short value) +int cs8900_e2prom_write(unsigned char addr, unsigned short value)  {  	cs8900_e2prom_ready();  	put_reg(PP_EECMD, EEPROM_WRITE_EN); @@ -307,7 +307,7 @@ void cs8900_e2prom_write(unsigned char addr, unsigned short value)  	put_reg(PP_EECMD, EEPROM_WRITE_DIS);  	cs8900_e2prom_ready(); -	return; +	return 0;  }  #endif	/* COMMANDS & CFG_NET */ diff --git a/drivers/cs8900.h b/drivers/cs8900.h index dbfda3c15..d772cad66 100644 --- a/drivers/cs8900.h +++ b/drivers/cs8900.h @@ -253,6 +253,6 @@  #define EEPROM_ERASE_CMD	0x0300  extern int cs8900_e2prom_read(uchar, ushort *); -extern void cs8900_e2prom_write(uchar, ushort); +extern int cs8900_e2prom_write(uchar, ushort);  #endif /* CONFIG_DRIVER_CS8900 */ diff --git a/drivers/s3c24x0_i2c.c b/drivers/s3c24x0_i2c.c index bf435c983..b50176118 100644 --- a/drivers/s3c24x0_i2c.c +++ b/drivers/s3c24x0_i2c.c @@ -64,10 +64,12 @@ static int GetIICSDA(void)  	return (rGPEDAT & 0x8000) >> 15;  } +#if 0  static void SetIICSDA(int x)  {  	rGPEDAT = (rGPEDAT & ~0x8000) | (x&1) << 15;  } +#endif  static void SetIICSCL(int x)  { diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index bacec8e30..a5d958359 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -1,3 +1,4 @@ +/* vi: set sw=4 ts=4: */  /*  -------------------------------------------------------------------------   * Filename:      jffs2.c @@ -75,6 +76,42 @@   *   */ +/* + * Bugfixing by Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>, (C) Mar/2003 + * + * - overhaul of the memory management. Removed much of the "paper-bagging" + *   in that part of the code, fixed several bugs, now frees memory when + *   partition is changed. + *   It's still ugly :-( + * - fixed a bug in jffs2_1pass_read_inode where the file length calculation + *   was incorrect. Removed a bit of the paper-bagging as well. + * - removed double crc calculation for fragment headers in jffs2_private.h + *   for speedup. + * - scan_empty rewritten in a more "standard" manner (non-paperbag, that is). + * - spinning wheel now spins depending on how much memory has been scanned + * - lots of small changes all over the place to "improve" readability. + * - implemented fragment sorting to ensure that the newest data is copied + *   if there are multiple copies of fragments for a certain file offset. + * + * The fragment sorting feature must be enabled by CFG_JFFS2_SORT_FRAGMENTS. + * Sorting is done while adding fragments to the lists, which is more or less a + * bubble sort. This takes a lot of time, and is most probably not an issue if + * the boot filesystem is always mounted readonly. + * + * You should define it if the boot filesystem is mounted writable, and updates + * to the boot files are done by copying files to that filesystem. + * + * + * There's a big issue left: endianess is completely ignored in this code. Duh! + * + * + * You still should have paper bags at hand :-(. The code lacks more or less + * any comment, and is still arcane and difficult to read in places. As this + * is incompatible with any new code from the jffs2 maintainers anyway, it + * should probably be dumped and replaced by something like jffs2reader! + */ + +  #include <common.h>  #include <config.h>  #include <malloc.h> @@ -88,124 +125,197 @@  #include "jffs2_private.h" -/* Compression names */ -static char *compr_names[] = { -        "NONE", -        "ZERO", -        "RTIME", -        "RUBINMIPS", -        "COPY", -        "DYNRUBIN", -        "ZLIB" }; -static char spinner[] = { '|', '\\', '-', '/' }; +#define	NODE_CHUNK  	1024	/* size of memory allocation chunk in b_nodes */ +#define	SPIN_BLKSIZE	18  	/* spin after having scanned 1<<BLKSIZE bytes */ + +/* Debugging switches */ +#undef	DEBUG_DIRENTS		/* print directory entry list after scan */ +#undef	DEBUG_FRAGMENTS		/* print fragment list after scan */ +#undef	DEBUG   			/* enable debugging messages */ + -#define DEBUG  #ifdef  DEBUG  # define DEBUGF(fmt,args...)	printf(fmt ,##args)  #else  # define DEBUGF(fmt,args...)  #endif -#define MALLOC_CHUNK (10*1024) +/* Compression names */ +static char *compr_names[] = { +	"NONE", +	"ZERO", +	"RTIME", +	"RUBINMIPS", +	"COPY", +	"DYNRUBIN", +	"ZLIB" +}; + +/* Spinning wheel */ +static char spinner[] = { '|', '/', '-', '\\' }; + +/* Memory management */ +struct mem_block { +	u32	index; +	struct mem_block *next; +	struct b_node nodes[NODE_CHUNK]; +}; + + +static void +free_nodes(struct b_list *list) +{ +	while (list->listMemBase != NULL) { +		struct mem_block *next = list->listMemBase->next; +		free( list->listMemBase ); +		list->listMemBase = next; +	} +}  static struct b_node * -add_node(struct b_node *tail, u32 * count, u32 * memBase) +add_node(struct b_list *list)  { -	u32 index; -	u32 memLimit; +	u32 index = 0; +	struct mem_block *memBase;  	struct b_node *b; -	index = (*count) * sizeof(struct b_node) % MALLOC_CHUNK; -	memLimit = MALLOC_CHUNK; - +	memBase = list->listMemBase; +	if (memBase != NULL) +		index = memBase->index;  #if 0  	putLabeledWord("add_node: index = ", index); -	putLabeledWord("add_node: memLimit = ", memLimit); -	putLabeledWord("add_node: memBase = ", *memBase); +	putLabeledWord("add_node: memBase = ", list->listMemBase);  #endif -	/* we need not keep a list of bases since we'll never free the */ -	/* memory, just jump the the kernel */ -	if ((index == 0) || (index > memLimit)) {	/* we need mode space before we continue */ -		if ((*memBase = (u32) mmalloc(MALLOC_CHUNK)) == (u32) NULL) { +	if (memBase == NULL || index >= NODE_CHUNK) { +		/* we need more space before we continue */ +		memBase = mmalloc(sizeof(struct mem_block)); +		if (memBase == NULL) {  			putstr("add_node: malloc failed\n");  			return NULL;  		} +		memBase->next = list->listMemBase; +		index = 0;  #if 0  		putLabeledWord("add_node: alloced a new membase at ", *memBase);  #endif  	}  	/* now we have room to add it. */ -	b = (struct b_node *) (*memBase + index); - -	/* null on first call */ -	if (tail) -		tail->next = b; +	b = &memBase->nodes[index]; +	index ++; -#if 0 -	putLabeledWord("add_node: tail = ", (u32) tail); -	if (tail) -		putLabeledWord("add_node: tail->next = ", (u32) tail->next); +	memBase->index = index; +	list->listMemBase = memBase; +	list->listCount++; +	return b; +} +static struct b_node * +insert_node(struct b_list *list, u32 offset) +{ +	struct b_node *new; +#ifdef CFG_JFFS2_SORT_FRAGMENTS +	struct b_node *b, *prev;  #endif -#if 0 -	putLabeledWord("add_node: mb+i = ", (u32) (*memBase + index)); -	putLabeledWord("add_node: b = ", (u32) b); +	if (!(new = add_node(list))) { +		putstr("add_node failed!\r\n"); +		return NULL; +	} +	new->offset = offset; + +#ifdef CFG_JFFS2_SORT_FRAGMENTS +	if (list->listTail != NULL && list->listCompare(new, list->listTail)) +		prev = list->listTail; +	else if (list->listLast != NULL && list->listCompare(new, list->listLast)) +		prev = list->listLast; +	else +		prev = NULL; + +	for (b = (prev ? prev->next : list->listHead); +	     b != NULL && list->listCompare(new, b); +	     prev = b, b = b->next) { +		list->listLoops++; +	} +	if (b != NULL) +		list->listLast = prev; + +	if (b != NULL) { +		new->next = b; +		if (prev != NULL) +			prev->next = new; +		else +			list->listHead = new; +	} else  #endif -	(*count)++; -	b->next = (struct b_node *) NULL; -	return b; +	{ +		new->next = (struct b_node *) NULL; +		if (list->listTail != NULL) { +			list->listTail->next = new; +			list->listTail = new; +		} else { +			list->listTail = list->listHead = new; +		} +	} +	return new;  } -/* we know we have empties at the start offset so we will hop */ -/* t points that would be non F if there were a node here to speed this up. */ -struct jffs2_empty_node { -	u32 first; -	u32 second; -}; +#ifdef CFG_JFFS2_SORT_FRAGMENTS +static int compare_inodes(struct b_node *new, struct b_node *old) +{ +	struct jffs2_raw_inode *jNew = (struct jffs2_raw_inode *)new->offset; +	struct jffs2_raw_inode *jOld = (struct jffs2_raw_inode *)old->offset; + +	return jNew->version < jOld->version; +} + +static int compare_dirents(struct b_node *new, struct b_node *old) +{ +	struct jffs2_raw_dirent *jNew = (struct jffs2_raw_dirent *)new->offset; +	struct jffs2_raw_dirent *jOld = (struct jffs2_raw_dirent *)old->offset; + +	return jNew->version > jOld->version; +} +#endif  static u32  jffs2_scan_empty(u32 start_offset, struct part_info *part)  { -	u32 max = part->size - sizeof(struct jffs2_raw_inode); - -	/* this would be either dir node_crc or frag isize */ -	u32 offset = start_offset + 32; -	struct jffs2_empty_node *node; +	char *max = part->offset + part->size - sizeof(struct jffs2_raw_inode); +	char *offset = part->offset + start_offset; -	start_offset += 4; -	while (offset < max) { -		node = (struct jffs2_empty_node *) (part->offset + offset); -		if ((node->first == 0xFFFFFFFF) && (node->second == 0xFFFFFFFF)) { -			/* we presume that there were no nodes in between and advance in a hop */ -			/* putLabeledWord("\t\tjffs2_scan_empty: empty at offset=",offset); */ -			start_offset = offset + 4; -			offset = start_offset + 32;	/* orig 32 + 4 bytes for the second==0xfffff */ -		} else { -			return start_offset; -		} +	while (offset < max && *(u32 *)offset == 0xFFFFFFFF) { +		offset += sizeof(u32); +		/* return if spinning is due */ +		if (((u32)offset & ((1 << SPIN_BLKSIZE)-1)) == 0) break;  	} -	return start_offset; + +	return offset - part->offset;  }  static u32  jffs_init_1pass_list(struct part_info *part)  { -	if ( 0 != ( part->jffs2_priv=malloc(sizeof(struct b_lists)))){ -		struct b_lists *pL =(struct b_lists *)part->jffs2_priv; +	struct b_lists *pL; + +	if (part->jffs2_priv != NULL) { +		pL = (struct b_lists *)part->jffs2_priv; +		free_nodes(&pL->frag); +		free_nodes(&pL->dir); +		free(pL); +	} +	if (NULL != (part->jffs2_priv = malloc(sizeof(struct b_lists)))) { +		pL = (struct b_lists *)part->jffs2_priv; -		pL->dirListHead = pL->dirListTail = NULL; -		pL->fragListHead = pL->fragListTail = NULL; -		pL->dirListCount = 0; -		pL->dirListMemBase = 0; -		pL->fragListCount = 0; -		pL->fragListMemBase = 0; -		pL->partOffset = 0x0; +		memset(pL, 0, sizeof(*pL)); +#ifdef CFG_JFFS2_SORT_FRAGMENTS +		pL->dir.listCompare = compare_dirents; +		pL->frag.listCompare = compare_inodes; +#endif  	}  	return 0;  } @@ -216,21 +326,18 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)  {  	struct b_node *b;  	struct jffs2_raw_inode *jNode; -	u32 totalSize = 1; -	u32 oldTotalSize = 0; -	u32 size = 0; -	char *lDest = (char *) dest; +	u32 totalSize = 0; +	u16 latestVersion = 0; +	char *lDest;  	char *src;  	long ret;  	int i;  	u32 counter = 0; -	char totalSizeSet = 0; -#if 0 -	b = pL->fragListHead; -	while (b) { +	for (b = pL->frag.listHead; b != NULL; b = b->next) {  		jNode = (struct jffs2_raw_inode *) (b->offset);  		if ((inode == jNode->ino)) { +#if 0  			putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen);  			putLabeledWord("read_inode: inode = ", jNode->ino);  			putLabeledWord("read_inode: version = ", jNode->version); @@ -241,58 +348,26 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)  			putLabeledWord("read_inode: compr = ", jNode->compr);  			putLabeledWord("read_inode: usercompr = ", jNode->usercompr);  			putLabeledWord("read_inode: flags = ", jNode->flags); -		} - -		b = b->next; -	} -  #endif - -#if 1 -	b = pL->fragListHead; -	while (b && (size < totalSize)) { -		jNode = (struct jffs2_raw_inode *) (b->offset); -		if ((inode == jNode->ino)) { -			if ((jNode->isize == oldTotalSize) && (jNode->isize > totalSize)) { -				/* 2 consecutive isizes indicate file length */ +			/* get actual file length from the newest node */ +			if (jNode->version >= latestVersion) {  				totalSize = jNode->isize; -				totalSizeSet = 1; -			} else if (!totalSizeSet) { -				totalSize = size + jNode->dsize + 1; +				latestVersion = jNode->version;  			} -			oldTotalSize = jNode->isize;  			if(dest) {  				src = ((char *) jNode) + sizeof(struct jffs2_raw_inode); -				/* lDest = (char *) (dest + (jNode->offset & ~3)); */ +				/* ignore data behind latest known EOF */ +				if (jNode->offset > totalSize) +					continue; +  				lDest = (char *) (dest + jNode->offset);  #if 0 -				putLabeledWord("\r\n\r\nread_inode: src = ", src); +				putLabeledWord("read_inode: src = ", src);  				putLabeledWord("read_inode: dest = ", lDest); -				putLabeledWord("read_inode: dsize = ", jNode->dsize); -				putLabeledWord("read_inode: csize = ", jNode->csize); -				putLabeledWord("read_inode: version = ", jNode->version); -				putLabeledWord("read_inode: isize = ", jNode->isize); -				putLabeledWord("read_inode: offset = ", jNode->offset); -				putLabeledWord("read_inode: compr = ", jNode->compr); -				putLabeledWord("read_inode: flags = ", jNode->flags);  #endif  				switch (jNode->compr) {  				case JFFS2_COMPR_NONE: -#if 0 -					{ -						int i; - -						if ((dest > 0xc0092ff0) && (dest < 0xc0093000)) -							for (i = 0; i < first->length; i++) { -								putLabeledWord("\tCOMPR_NONE: src =", src + i); -								putLabeledWord("\tCOMPR_NONE: length =", first->length); -								putLabeledWord("\tCOMPR_NONE: dest =", dest + i); -								putLabeledWord("\tCOMPR_NONE: data =", (unsigned char) *(src + i)); -							} -					} -#endif -  					ret = (unsigned long) ldr_memcpy(lDest, src, jNode->dsize);  					break;  				case JFFS2_COMPR_ZERO: @@ -320,22 +395,18 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)  				}  			} -			size += jNode->dsize;  #if 0 -			putLabeledWord("read_inode: size = ", size);  			putLabeledWord("read_inode: totalSize = ", totalSize);  			putLabeledWord("read_inode: compr ret = ", ret);  #endif  		} -		b = b->next;  		counter++;  	} -#endif  #if 0 -	putLabeledWord("read_inode: returning = ", size); +	putLabeledWord("read_inode: returning = ", totalSize);  #endif -	return size; +	return totalSize;  }  /* find the inode from the slashless name given a parent */ @@ -354,18 +425,19 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)  	counter = 0;  	/* we need to search all and return the inode with the highest version */ -	for(b = pL->dirListHead;b;b=b->next,counter++) { +	for(b = pL->dir.listHead; b; b = b->next, counter++) {  		jDir = (struct jffs2_raw_dirent *) (b->offset); -		if ((pino == jDir->pino) && (len == jDir->nsize) && (jDir->ino) &&	/* 0 for unlink */ +		if ((pino == jDir->pino) && (len == jDir->nsize) && +		    (jDir->ino) &&	/* 0 for unlink */  		    (!strncmp(jDir->name, name, len))) {	/* a match */  			if (jDir->version < version) continue; -		        if(jDir->version==0) { +		        if(jDir->version == 0) {  			    	/* Is this legal? */  				putstr(" ** WARNING ** ");  				putnstr(jDir->name, jDir->nsize);  				putstr(" is version 0 (in find, ignoring)\r\n"); -			} else if(jDir->version==version) { +			} else if(jDir->version == version) {  			    	/* Im pretty sure this isn't ... */  				putstr(" ** ERROR ** ");  				putnstr(jDir->name, jDir->nsize); @@ -389,53 +461,53 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)  static char *mkmodestr(unsigned long mode, char *str)  { -    static const char *l="xwr"; -    int mask=1, i; -    char c; +	static const char *l = "xwr"; +	int mask = 1, i; +	char c; -    switch (mode & S_IFMT) { -        case S_IFDIR:    str[0]='d'; break; -        case S_IFBLK:    str[0]='b'; break; -        case S_IFCHR:    str[0]='c'; break; -        case S_IFIFO:    str[0]='f'; break; -        case S_IFLNK:    str[0]='l'; break; -        case S_IFSOCK:   str[0]='s'; break; -        case S_IFREG:    str[0]='-'; break; -        default:        str[0]='?'; -    } +	switch (mode & S_IFMT) { +		case S_IFDIR:    str[0] = 'd'; break; +		case S_IFBLK:    str[0] = 'b'; break; +		case S_IFCHR:    str[0] = 'c'; break; +		case S_IFIFO:    str[0] = 'f'; break; +		case S_IFLNK:    str[0] = 'l'; break; +		case S_IFSOCK:   str[0] = 's'; break; +		case S_IFREG:    str[0] = '-'; break; +		default:         str[0] = '?'; +	} -    for(i=0;i<9;i++) { -        c=l[i%3]; -        str[9-i]=(mode & mask)?c:'-'; -        mask=mask<<1; -    } +	for(i = 0; i < 9; i++) { +		c = l[i%3]; +		str[9-i] = (mode & mask)?c:'-'; +		mask = mask<<1; +	} -    if(mode & S_ISUID) str[3]=(mode & S_IXUSR)?'s':'S'; -    if(mode & S_ISGID) str[6]=(mode & S_IXGRP)?'s':'S'; -    if(mode & S_ISVTX) str[9]=(mode & S_IXOTH)?'t':'T'; -    str[10]='\0'; -    return str; +	if(mode & S_ISUID) str[3] = (mode & S_IXUSR)?'s':'S'; +	if(mode & S_ISGID) str[6] = (mode & S_IXGRP)?'s':'S'; +	if(mode & S_ISVTX) str[9] = (mode & S_IXOTH)?'t':'T'; +	str[10] = '\0'; +	return str;  }  static inline void dump_stat(struct stat *st, const char *name)  { -    char str[20]; -    char s[64], *p; +	char str[20]; +	char s[64], *p; -    if (st->st_mtime == (time_t)(-1))	/* some ctimes really hate -1 */ -        st->st_mtime = 1; +	if (st->st_mtime == (time_t)(-1)) /* some ctimes really hate -1 */ +		st->st_mtime = 1; -    ctime_r(&st->st_mtime, s/*, 64*/);   /* newlib ctime doesn't have buflen */ +	ctime_r(&st->st_mtime, s/*,64*/); /* newlib ctime doesn't have buflen */ -    if((p=strchr(s,'\n'))!=NULL) *p='\0'; -    if((p=strchr(s,'\r'))!=NULL) *p='\0'; +	if ((p = strchr(s,'\n')) != NULL) *p = '\0'; +	if ((p = strchr(s,'\r')) != NULL) *p = '\0';  /* -    printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str), -        st->st_size, s, name); +	printf("%6lo %s %8ld %s %s\n", st->st_mode, mkmodestr(st->st_mode, str), +		st->st_size, s, name);  */ -    printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name); +	printf(" %s %8ld %s %s", mkmodestr(st->st_mode,str), st->st_size, s, name);  }  static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, struct jffs2_raw_inode *i) @@ -446,16 +518,16 @@ static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, st  	if(!d || !i) return -1;  	strncpy(fname, d->name, d->nsize); -	fname[d->nsize]='\0'; +	fname[d->nsize] = '\0';  	memset(&st,0,sizeof(st)); -	st.st_mtime=i->mtime; -	st.st_mode=i->mode; -	st.st_ino=i->ino; +	st.st_mtime = i->mtime; +	st.st_mode = i->mode; +	st.st_ino = i->ino;  	/* neither dsize nor isize help us.. do it the long way */ -	st.st_size=jffs2_1pass_read_inode(pL, i->ino, NULL); +	st.st_size = jffs2_1pass_read_inode(pL, i->ino, NULL);  	dump_stat(&st, fname); @@ -477,18 +549,18 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino)  	struct b_node *b;  	struct jffs2_raw_dirent *jDir; -	for(b = pL->dirListHead;b;b=b->next) { +	for (b = pL->dir.listHead; b; b = b->next) {  		jDir = (struct jffs2_raw_dirent *) (b->offset); -		if ((pino == jDir->pino) && (jDir->ino)) {	/* 0 inode for unlink */ -			u32 i_version=0; -			struct jffs2_raw_inode *jNode, *i=NULL; -			struct b_node *b2 = pL->fragListHead; +		if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */ +			u32 i_version = 0; +			struct jffs2_raw_inode *jNode, *i = NULL; +			struct b_node *b2 = pL->frag.listHead;  			while (b2) {  				jNode = (struct jffs2_raw_inode *) (b2->offset);  				if (jNode->ino == jDir->ino -				    && jNode->version>=i_version) -					i=jNode; +				    && jNode->version >= i_version) +					i = jNode;  				b2 = b2->next;  			} @@ -568,7 +640,7 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)  	unsigned char *src;  	/* we need to search all and return the inode with the highest version */ -	for(b = pL->dirListHead; b; b=b->next) { +	for(b = pL->dir.listHead; b; b = b->next) {  		jDir = (struct jffs2_raw_dirent *) (b->offset);  		if (ino == jDir->ino) {  		    	if(jDir->version < version) continue; @@ -593,8 +665,9 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)  	/* now we found the right entry again. (shoulda returned inode*) */  	if (jDirFound->type != DT_LNK)  		return jDirFound->ino; -	/* so its a soft link so we follow it again. */ -	b2 = pL->fragListHead; + +	/* it's a soft link so we follow it again. */ +	b2 = pL->frag.listHead;  	while (b2) {  		jNode = (struct jffs2_raw_inode *) (b2->offset);  		if (jNode->ino == jDirFound->ino) { @@ -644,7 +717,8 @@ jffs2_1pass_search_list_inodes(struct b_lists * pL, const char *fname, u32 pino)  			tmp[i] = c[i + 1];  		tmp[i] = '\0';  		/* only a failure if we arent looking at top level */ -		if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && (working_tmp[0])) { +		if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) && +		    (working_tmp[0])) {  			putstr("find_inode failed for name=");  			putstr(working_tmp);  			putstr("\r\n"); @@ -674,29 +748,30 @@ jffs2_1pass_rescan_needed(struct part_info *part)  {  	struct b_node *b;  	struct jffs2_unknown_node *node; -	struct b_lists *pL=(struct b_lists *)part->jffs2_priv; +	struct b_lists *pL = (struct b_lists *)part->jffs2_priv;  	if (part->jffs2_priv == 0){  		DEBUGF ("rescan: First time in use\n");  		return 1;  	}  	/* if we have no list, we need to rescan */ -	if (pL->fragListCount == 0) { +	if (pL->frag.listCount == 0) {  		DEBUGF ("rescan: fraglist zero\n");  		return 1;  	} -	/* or if we are scanninga new partition */ +	/* or if we are scanning a new partition */  	if (pL->partOffset != part->offset) {  		DEBUGF ("rescan: different partition\n");  		return 1;  	} -	/* but suppose someone reflashed the root partition at the same offset... */ -	b = pL->dirListHead; +	/* but suppose someone reflashed a partition at the same offset... */ +	b = pL->dir.listHead;  	while (b) {  		node = (struct jffs2_unknown_node *) (b->offset);  		if (node->nodetype != JFFS2_NODETYPE_DIRENT) { -			DEBUGF ("rescan: fs changed beneath me? (%lx)\n", (unsigned long) b->offset); +			DEBUGF ("rescan: fs changed beneath me? (%lx)\n", +					(unsigned long) b->offset);  			return 1;  		}  		b = b->next; @@ -704,12 +779,71 @@ jffs2_1pass_rescan_needed(struct part_info *part)  	return 0;  } +#ifdef DEBUG_FRAGMENTS +static void +dump_fragments(struct b_lists *pL) +{ +	struct b_node *b; +	struct jffs2_raw_inode *jNode; + +	putstr("\r\n\r\n******The fragment Entries******\r\n"); +	b = pL->frag.listHead; +	while (b) { +		jNode = (struct jffs2_raw_inode *) (b->offset); +		putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset); +		putLabeledWord("\tbuild_list: totlen = ", jNode->totlen); +		putLabeledWord("\tbuild_list: inode = ", jNode->ino); +		putLabeledWord("\tbuild_list: version = ", jNode->version); +		putLabeledWord("\tbuild_list: isize = ", jNode->isize); +		putLabeledWord("\tbuild_list: atime = ", jNode->atime); +		putLabeledWord("\tbuild_list: offset = ", jNode->offset); +		putLabeledWord("\tbuild_list: csize = ", jNode->csize); +		putLabeledWord("\tbuild_list: dsize = ", jNode->dsize); +		putLabeledWord("\tbuild_list: compr = ", jNode->compr); +		putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr); +		putLabeledWord("\tbuild_list: flags = ", jNode->flags); +		putLabeledWord("\tbuild_list: offset = ", b->offset);	// FIXME: ? [RS] +		b = b->next; +	} +} +#endif + +#ifdef DEBUG_DIRENTS +static void +dump_dirents(struct b_lists *pL) +{ +	struct b_node *b; +	struct jffs2_raw_dirent *jDir; + +	putstr("\r\n\r\n******The directory Entries******\r\n"); +	b = pL->dir.listHead; +	while (b) { +		jDir = (struct jffs2_raw_dirent *) (b->offset); +		putstr("\r\n"); +		putnstr(jDir->name, jDir->nsize); +		putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); +		putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype); +		putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc); +		putLabeledWord("\tbuild_list: pino = ", jDir->pino); +		putLabeledWord("\tbuild_list: version = ", jDir->version); +		putLabeledWord("\tbuild_list: ino = ", jDir->ino); +		putLabeledWord("\tbuild_list: mctime = ", jDir->mctime); +		putLabeledWord("\tbuild_list: nsize = ", jDir->nsize); +		putLabeledWord("\tbuild_list: type = ", jDir->type); +		putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc); +		putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); +		putLabeledWord("\tbuild_list: offset = ", b->offset); 	// FIXME: ? [RS] +		b = b->next; +	} +} +#endif +  static u32  jffs2_1pass_build_lists(struct part_info * part)  {  	struct b_lists *pL;  	struct jffs2_unknown_node *node; -	u32 offset; +	u32 offset, oldoffset = 0;  	u32 max = part->size - sizeof(struct jffs2_raw_inode);  	u32 counter = 0;  	u32 counter4 = 0; @@ -722,71 +856,52 @@ jffs2_1pass_build_lists(struct part_info * part)  	/* lcd_off(); */  	/* if we are building a list we need to refresh the cache. */ -	/* note that since we don't free our memory, eventually this will be bad. */ -	/* but we're a bootldr so what the hell. */  	jffs_init_1pass_list(part); -	pL=(struct b_lists *)part->jffs2_priv; +	pL = (struct b_lists *)part->jffs2_priv;  	pL->partOffset = part->offset;  	offset = 0;  	printf("Scanning JFFS2 FS:   ");  	/* start at the beginning of the partition */  	while (offset < max) { -	    	if (! (++counter%10000)) -			printf("\b\b%c ", spinner[(counter / 10000) % 4]); +	    	if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) { +			printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]); +			oldoffset = offset; +		}  		node = (struct jffs2_unknown_node *) (part->offset + offset);  		if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) {  			/* if its a fragment add it */ -			if (node->nodetype == JFFS2_NODETYPE_INODE && inode_crc((struct jffs2_raw_inode *) node)) { -				if (!(pL->fragListTail = add_node(pL->fragListTail, &(pL->fragListCount), -								  &(pL->fragListMemBase)))) { -					putstr("add_node failed!\r\n"); +			if (node->nodetype == JFFS2_NODETYPE_INODE && +				    inode_crc((struct jffs2_raw_inode *) node)) { +				if (insert_node(&pL->frag, (u32) part->offset + +								offset) == NULL)  					return 0; -				} -				pL->fragListTail->offset = (u32) (part->offset + offset); -				if (!pL->fragListHead) -					pL->fragListHead = pL->fragListTail;  			} else if (node->nodetype == JFFS2_NODETYPE_DIRENT &&  				   dirent_crc((struct jffs2_raw_dirent *) node)  &&  				   dirent_name_crc((struct jffs2_raw_dirent *) node)) {  				if (! (counterN%100))  					printf("\b\b.  "); -#if 0 -				printf("Found DIRENT @ 0x%lx\n", offset); -				putstr("\r\nbuild_lists:p&l ->"); -				putnstr(((struct jffs2_raw_dirent *) node)->name, ((struct jffs2_raw_dirent *) node)->nsize); -				putstr("\r\n"); -				putLabeledWord("\tpino = ", ((struct jffs2_raw_dirent *) node)->pino); -				putLabeledWord("\tnsize = ", ((struct jffs2_raw_dirent *) node)->nsize); -#endif - -				if (!(pL->dirListTail = add_node(pL->dirListTail, &(pL->dirListCount), &(pL->dirListMemBase)))) { -					putstr("add_node failed!\r\n"); +				if (insert_node(&pL->dir, (u32) part->offset + +								offset) == NULL)  					return 0; -				} -				pL->dirListTail->offset = (u32) (part->offset + offset); -#if 0 -				putLabeledWord("\ttail = ", (u32) pL->dirListTail); -				putstr("\ttailName ->"); -				putnstr(((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->name, -					((struct jffs2_raw_dirent *) (pL->dirListTail->offset))->nsize); -				putstr("\r\n"); -#endif -				if (!pL->dirListHead) -					pL->dirListHead = pL->dirListTail;  				counterN++;  			} else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) {  				if (node->totlen != sizeof(struct jffs2_unknown_node)) -					printf("OOPS Cleanmarker has bad size %d != %d\n", node->totlen, sizeof(struct jffs2_unknown_node)); +					printf("OOPS Cleanmarker has bad size " +						"%d != %d\n", node->totlen, +						sizeof(struct jffs2_unknown_node));  			} else { -				printf("Unknown node type: %x len %d offset 0x%x\n", node->nodetype, node->totlen, offset); +				printf("Unknown node type: %x len %d " +					"offset 0x%x\n", node->nodetype, +					node->totlen, offset);  			}  			offset += ((node->totlen + 3) & ~3);  			counterF++; -		} else if (node->magic == JFFS2_EMPTY_BITMASK && node->nodetype == JFFS2_EMPTY_BITMASK) { +		} else if (node->magic == JFFS2_EMPTY_BITMASK && +			   node->nodetype == JFFS2_EMPTY_BITMASK) {  			offset = jffs2_scan_empty(offset, part); -		} else {	/* if we know nothing of the filesystem, we just step and look. */ +		} else {	/* if we know nothing, we just step and look. */  			offset += 4;  			counter4++;  		} @@ -799,66 +914,21 @@ jffs2_1pass_build_lists(struct part_info * part)  	/* splash(); */  #if 0 -	putLabeledWord("dir entries = ", pL->dirListCount); -	putLabeledWord("frag entries = ", pL->fragListCount); +	putLabeledWord("dir entries = ", pL->dir.listCount); +	putLabeledWord("frag entries = ", pL->frag.listCount);  	putLabeledWord("+4 increments = ", counter4);  	putLabeledWord("+file_offset increments = ", counterF);  #endif -#undef SHOW_ALL -#undef SHOW_ALL_FRAGMENTS - -#ifdef SHOW_ALL -	{ -		struct b_node *b; -		struct b_node *b2; -		struct jffs2_raw_dirent *jDir; -		struct jffs2_raw_inode *jNode; - -		putstr("\r\n\r\n******The directory Entries******\r\n"); -		b = pL->dirListHead; -		while (b) { -			jDir = (struct jffs2_raw_dirent *) (b->offset); -			putstr("\r\n"); -			putnstr(jDir->name, jDir->nsize); -			putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); -			putLabeledWord("\tbuild_list: nodetype = ", jDir->nodetype); -			putLabeledWord("\tbuild_list: hdr_crc = ", jDir->hdr_crc); -			putLabeledWord("\tbuild_list: pino = ", jDir->pino); -			putLabeledWord("\tbuild_list: version = ", jDir->version); -			putLabeledWord("\tbuild_list: ino = ", jDir->ino); -			putLabeledWord("\tbuild_list: mctime = ", jDir->mctime); -			putLabeledWord("\tbuild_list: nsize = ", jDir->nsize); -			putLabeledWord("\tbuild_list: type = ", jDir->type); -			putLabeledWord("\tbuild_list: node_crc = ", jDir->node_crc); -			putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); -			b = b->next; -		} +#ifdef DEBUG_DIRENTS +	dump_dirents(pL); +#endif -#ifdef SHOW_ALL_FRAGMENTS -		putstr("\r\n\r\n******The fragment Entries******\r\n"); -		b = pL->fragListHead; -		while (b) { -			jNode = (struct jffs2_raw_inode *) (b->offset); -			putLabeledWord("\r\n\tbuild_list: FLASH_OFFSET = ", b->offset); -			putLabeledWord("\tbuild_list: totlen = ", jNode->totlen); -			putLabeledWord("\tbuild_list: inode = ", jNode->ino); -			putLabeledWord("\tbuild_list: version = ", jNode->version); -			putLabeledWord("\tbuild_list: isize = ", jNode->isize); -			putLabeledWord("\tbuild_list: atime = ", jNode->atime); -			putLabeledWord("\tbuild_list: offset = ", jNode->offset); -			putLabeledWord("\tbuild_list: csize = ", jNode->csize); -			putLabeledWord("\tbuild_list: dsize = ", jNode->dsize); -			putLabeledWord("\tbuild_list: compr = ", jNode->compr); -			putLabeledWord("\tbuild_list: usercompr = ", jNode->usercompr); -			putLabeledWord("\tbuild_list: flags = ", jNode->flags); -			b = b->next; -		} -#endif /* SHOW_ALL_FRAGMENTS */ -	} +#ifdef DEBUG_FRAGMENTS +	dump_fragments(pL); +#endif -#endif	/* SHOW_ALL */  	/* give visual feedback that we are done scanning the flash */  	led_blink(0x0, 0x0, 0x1, 0x1);	/* off, forever, on 100ms, off 100ms */  	return 1; @@ -875,13 +945,13 @@ jffs2_1pass_fill_info(struct b_lists * pL, struct b_jffs2_info * piL)  	struct jffs2_raw_inode *jNode;  	int i; -	b = pL->fragListHead;  	for (i = 0; i < JFFS2_NUM_COMPR; i++) {  		piL->compr_info[i].num_frags = 0;  		piL->compr_info[i].compr_sum = 0;  		piL->compr_info[i].decompr_sum = 0;  	} +	b = pL->frag.listHead;  	while (b) {  		jNode = (struct jffs2_raw_inode *) (b->offset);  		if (jNode->compr < JFFS2_NUM_COMPR) { @@ -917,7 +987,7 @@ jffs2_1pass_ls(struct part_info * part, const char *fname)  	long ret = 0;  	u32 inode; -	if (! (pl  = jffs2_get_list(part, "ls"))) +	if (! (pl = jffs2_get_list(part, "ls")))  		return 0;  	if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) { @@ -983,7 +1053,7 @@ jffs2_1pass_info(struct part_info * part)  		return 0;  	jffs2_1pass_fill_info(pl, &info); -	for (i=0; i < JFFS2_NUM_COMPR; i++) { +	for (i = 0; i < JFFS2_NUM_COMPR; i++) {  		printf("Compression: %s\n", compr_names[i]);  		printf("\tfrag count: %d\n", info.compr_info[i].num_frags);  		printf("\tcompressed sum: %d\n", info.compr_info[i].compr_sum); diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index ca0af1f9a..c6d5fe360 100644 --- a/fs/jffs2/jffs2_private.h +++ b/fs/jffs2/jffs2_private.h @@ -3,23 +3,31 @@  #include <jffs2/jffs2.h> +  struct b_node {  	u32 offset;  	struct b_node *next;  }; +struct b_list { +	struct b_node *listTail; +	struct b_node *listHead; +#ifdef CFG_JFFS2_SORT_FRAGMENTS +	struct b_node *listLast; +	int (*listCompare)(struct b_node *new, struct b_node *node); +	u32 listLoops; +#endif +	u32 listCount; +	struct mem_block *listMemBase; +}; +  struct b_lists {  	char *partOffset; -	struct b_node *dirListTail; -	struct b_node *dirListHead; -	u32 dirListCount; -	u32 dirListMemBase; -	struct b_node *fragListTail; -	struct b_node *fragListHead; -	u32 fragListCount; -	u32 fragListMemBase; +	struct b_list dir; +	struct b_list frag;  }; +  struct b_compr_info {  	u32 num_frags;  	u32 compr_sum; @@ -33,11 +41,14 @@ struct b_jffs2_info {  static inline int  hdr_crc(struct jffs2_unknown_node *node)  { +#if 1          u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); -        u32 crc_blah = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); - -        crc_blah ^= ~0; +#else +	/* what's the semantics of this? why is this here? */ +        u32 crc = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); +        crc ^= ~0; +#endif          if (node->hdr_crc != crc) {                  return 0;          } else { diff --git a/include/asm-arm/global_data.h b/include/asm-arm/global_data.h index e0a95e081..892710df4 100644 --- a/include/asm-arm/global_data.h +++ b/include/asm-arm/global_data.h @@ -44,7 +44,6 @@ typedef	struct	global_data {  #ifdef CONFIG_VFD  	unsigned long	fb_base;	/* base address of frame buffer */  	unsigned char	vfd_type;	/* display type */ -	unsigned char	vfd_inv_data;	/* inverted data lines ? */  #endif  #if 0  	unsigned long	cpu_clk;	/* CPU clock in Hz!		*/ diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index 0d55ca25b..122419f1e 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -71,22 +71,37 @@ extern void __raw_readsl(unsigned int addr, void *data, int longlen);  #include <asm/arch/io.h>  /* - * IO definitions.  We define {out,in,outs,ins}[bwl] if __io is defined - * by the machine.  Otherwise, these definitions are left for the machine - * specific header files to pick up. + *  IO port access primitives + *  ------------------------- + * + * The ARM doesn't have special IO access instructions; all IO is memory + * mapped.  Note that these are defined to perform little endian accesses + * only.  Their primary purpose is to access PCI and ISA peripherals. + * + * Note that for a big endian machine, this implies that the following + * big endian mode connectivity is in place, as described by numerious + * ARM documents: + * + *    PCI:  D0-D7   D8-D15 D16-D23 D24-D31 + *    ARM: D24-D31 D16-D23  D8-D15  D0-D7 + * + * The machine specific io.h include defines __io to translate an "IO" + * address to a memory address.   *   * Note that we prevent GCC re-ordering or caching values in expressions   * by introducing sequence points into the in*() definitions.  Note that   * __raw_* do not guarantee this behaviour. + * + * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.   */  #ifdef __io  #define outb(v,p)			__raw_writeb(v,__io(p)) -#define outw(v,p)			__raw_writew(v,__io(p)) -#define outl(v,p)			__raw_writel(v,__io(p)) +#define outw(v,p)			__raw_writew(cpu_to_le16(v),__io(p)) +#define outl(v,p)			__raw_writel(cpu_to_le32(v),__io(p)) -#define inb(p)		({ unsigned int __v = __raw_readb(__io(p)); __v; }) -#define inw(p)		({ unsigned int __v = __raw_readw(__io(p)); __v; }) -#define inl(p)		({ unsigned int __v = __raw_readl(__io(p)); __v; }) +#define inb(p)	({ unsigned int __v = __raw_readb(__io(p)); __v; }) +#define inw(p)	({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; }) +#define inl(p)	({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; })  #define outsb(p,d,l)			__raw_writesb(__io(p),d,l)  #define outsw(p,d,l)			__raw_writesw(__io(p),d,l) @@ -171,20 +186,20 @@ extern void __readwrite_bug(const char *fn);   */  #ifdef __mem_pci -#define readb(addr) ({ unsigned int __v = __raw_readb(__mem_pci(addr)); __v; }) -#define readw(addr) ({ unsigned int __v = __raw_readw(__mem_pci(addr)); __v; }) -#define readl(addr) ({ unsigned int __v = __raw_readl(__mem_pci(addr)); __v; }) +#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; }) +#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) +#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) -#define writeb(val,addr)		__raw_writeb(val,__mem_pci(addr)) -#define writew(val,addr)		__raw_writew(val,__mem_pci(addr)) -#define writel(val,addr)		__raw_writel(val,__mem_pci(addr)) +#define writeb(v,c)		__raw_writeb(v,__mem_pci(c)) +#define writew(v,c)		__raw_writew(cpu_to_le16(v),__mem_pci(c)) +#define writel(v,c)		__raw_writel(cpu_to_le32(v),__mem_pci(c)) -#define memset_io(a,b,c)		_memset_io(__mem_pci(a),(b),(c)) -#define memcpy_fromio(a,b,c)		_memcpy_fromio((a),__mem_pci(b),(c)) -#define memcpy_toio(a,b,c)		_memcpy_toio(__mem_pci(a),(b),(c)) +#define memset_io(c,v,l)		_memset_io(__mem_pci(c),(v),(l)) +#define memcpy_fromio(a,c,l)		_memcpy_fromio((a),__mem_pci(c),(l)) +#define memcpy_toio(c,a,l)		_memcpy_toio(__mem_pci(c),(a),(l)) -#define eth_io_copy_and_sum(a,b,c,d) \ -				eth_copy_and_sum((a),__mem_pci(b),(c),(d)) +#define eth_io_copy_and_sum(s,c,l,b) \ +				eth_copy_and_sum((s),__mem_pci(c),(l),(b))  static inline int  check_signature(unsigned long io_addr, const unsigned char *signature, @@ -219,14 +234,6 @@ out:  #endif	/* __mem_pci */  /* - * remap a physical address `phys' of size `size' with page protection `prot' - * into virtual address `from' - */ -#define io_remap_page_range(from,phys,size,prot) \ -		remap_page_range(from,phys,size,prot) - - -/*   * If this architecture has ISA IO, then define the isa_read/isa_write   * macros.   */ @@ -245,6 +252,10 @@ out:  #define isa_eth_io_copy_and_sum(a,b,c,d) \  				eth_copy_and_sum((a),__mem_isa(b),(c),(d)) +#ifndef PCI_MEMORY_VADDR	/* XXX problem not understood -- wd */ +#define	PCI_MEMORY_VADDR	0 +#endif	/* XXX */ +  static inline int  isa_check_signature(unsigned long io_addr, const unsigned char *signature,  		    int length) diff --git a/include/configs/innokom.h b/include/configs/innokom.h index a8ee99ae0..c2267bd86 100644 --- a/include/configs/innokom.h +++ b/include/configs/innokom.h @@ -60,9 +60,9 @@  #define CONFIG_ENV_OVERWRITE  #define CONFIG_BAUDRATE		19200 +#define CONFIG_MISC_INIT_R	1	/* we have a misc_init_r() function */ -#define CONFIG_COMMANDS		((CONFIG_CMD_DFL | CFG_CMD_I2C | CFG_CMD_EEPROM) & ~CFG_CMD_NET) - +#define CONFIG_COMMANDS (CONFIG_CMD_DFL|CFG_CMD_I2C|CFG_CMD_EEPROM|CFG_CMD_NET|CFG_CMD_JFFS2|CFG_CMD_DHCP)  /* this must be included AFTER the definition of CONFIG_COMMANDS (if any)   */  #include <cmd_confdefs.h> @@ -90,13 +90,13 @@  /*   * Size of malloc() pool; this lives below the uppermost 128 KiB which are   * used for the RAM copy of the uboot code + *   */ -/* #define CFG_MALLOC_LEN	(CFG_ENV_SIZE + 128*1024) */ -#define CFG_MALLOC_LEN		(128*1024) +#define CFG_MALLOC_LEN		(256*1024)  #define CFG_LONGHELP				/* undef to save memory         */  #define CFG_PROMPT		"uboot> "	/* Monitor Command Prompt       */ -#define CFG_CBSIZE		128		/* Console I/O Buffer Size      */ +#define CFG_CBSIZE		256		/* Console I/O Buffer Size      */  #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */  #define CFG_MAXARGS		16		/* max number of command args   */  #define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size    */ @@ -106,10 +106,7 @@  #undef  CFG_CLKS_IN_HZ          /* everything, incl board info, in Hz */ -#define CFG_LOAD_ADDR           0xa7fe0000      /* default load address */ -						/* RS: where is this documented? */ -						/* RS: is this where U-Boot is  */ -						/* RS: relocated to in RAM?      */ +#define CFG_LOAD_ADDR           0xa3000000      /* load kernel to this address   */  #define CFG_HZ                  3686400         /* incrementer freq: 3.6864 MHz */  						/* RS: the oscillator is actually 3680130?? */ @@ -128,9 +125,9 @@  /*   * I2C bus   */ -#define CONFIG_HARD_I2C 1 -#define CFG_I2C_SPEED 50000 -#define CFG_I2C_SLAVE 0xfe +#define CONFIG_HARD_I2C 		1 +#define CFG_I2C_SPEED 			50000 +#define CFG_I2C_SLAVE 			0xfe  #define CFG_ENV_IS_IN_EEPROM 		1 @@ -138,9 +135,20 @@  #define CFG_ENV_SIZE			1024	/* 1 KiB                    */  #define CFG_I2C_EEPROM_ADDR		0x50	/* A0 = 0 (hardwired)       */  #define CFG_EEPROM_PAGE_WRITE_BITS	5	/* 5 bits = 32 octets       */ -#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	10	/* between stop and start   */ +#define CFG_EEPROM_PAGE_WRITE_DELAY_MS	15	/* between stop and start   */  #define CFG_I2C_EEPROM_ADDR_LEN		2	/* length of address        */  #define CFG_EEPROM_SIZE			4096	/* size in bytes            */ +#define CFG_I2C_INIT_BOARD		1	/* board has it's own init  */ + +/* + * SMSC91C111 Network Card + */ +#define CONFIG_DRIVER_SMC91111		1 +#define CONFIG_SMC91111_BASE		0x14000000 /* chip select 5         */ +#undef  CONFIG_SMC_USE_32_BIT		           /* 16 bit bus access     */ +#undef  CONFIG_SMC_91111_EXT_PHY		   /* we use internal phy   */ +#undef  CONFIG_SHOW_ACTIVITY +#define CONFIG_NET_RETRY_COUNT		10	   /* # of retries          */  /*   * Stack sizes @@ -168,11 +176,19 @@  #define CFG_FLASH_BASE          PHYS_FLASH_1 +  /* - * GPIO settings; + * JFFS2 Partitions   */ +#define CFG_JFFS_CUSTOM_PART	1		/* see board/innokom/flash.c */ +#define CONFIG_MTD_INNOKOM_16MB 1		/* development flash         */	 +#undef  CONFIG_MTD_INNOKOM_64MB			/* production flash          */ -/* GP15 == nCS1      is 1 + +/* + * GPIO settings; see BDI2000 config file for details + * + * GP15 == nCS1      is 1   * GP24 == SFRM      is 1   * GP25 == TXD       is 1   * GP33 == nCS5      is 1 @@ -273,6 +289,7 @@  #define CFG_GAFR2_L_VAL     0xA0000000  #define CFG_GAFR2_U_VAL     0x00000002 +  /* FIXME: set GPIO_RER/FER */  /* RDH = 1 @@ -285,9 +302,8 @@  /*   * Memory settings - */ - -/* This is the configuration for nCS0/1 -> flash banks + * + * This is the configuration for nCS0/1 -> flash banks   * configuration for nCS1:   * [31]    0    - Slower Device   * [30:28] 010  - CS deselect to CS time: 2*(2*MemClk) = 40 ns @@ -321,7 +337,7 @@   * [03]    1    - 16 Bit bus width   * [02:00] 100  - variable latency I/O   */ -#define CFG_MSC1_VAL		0x132C593C /* TDM switch, DSP               */ +#define CFG_MSC1_VAL		0x123C593C /* TDM switch, DSP               */  /* This is the configuration for nCS4/5 -> ExtBus, LAN Controller   * @@ -340,7 +356,7 @@   * [03]    1    - 16 Bit bus width   * [02:00] 100  - variable latency I/O   */ -#define CFG_MSC2_VAL		0x132C6CDC /* extra bus, LAN controller     */ +#define CFG_MSC2_VAL		0x123C6CDC /* extra bus, LAN controller     */  /* MDCNFG: SDRAM Configuration Register   * @@ -359,16 +375,15 @@   * [12]      1	 - SA1111 compatiblity mode   * [11]      1   - latch return data with return clock   * [10]      0   - no alternate addressing for pair 0/1 - * [09:08]   01  - tRP=2*MemClk; CL=2; tRCD=2*MemClk; tRAS=5*MemClk; tRC=8*MemClk + * [09:08]   01  - tRP=2*MemClk CL=2 tRCD=2*MemClk tRAS=5*MemClk tRC=8*MemClk   * [7]       1   - 4 internal banks in lower partition pair   * [06:05]   10  - 13 row address bits for partition 0/1   * [04:03]   01  - 9 column address bits for partition 0/1   * [02]      0   - SDRAM partition 0/1 width is 32 bit   * [01]      0   - disable SDRAM partition 1   * [00]      1   - enable  SDRAM partition 0 - * - * use the configuration above but disable partition 0   */ +/* use the configuration above but disable partition 0 */  #define CFG_MDCNFG_VAL		0x000019c8  /* MDREFR: SDRAM Refresh Control Register @@ -434,11 +449,4 @@  #define CFG_FLASH_ERASE_TOUT    (2*CFG_HZ) /* Timeout for Flash Erase       */  #define CFG_FLASH_WRITE_TOUT    (2*CFG_HZ) /* Timeout for Flash Write       */ -#if 0 -#define CFG_ENV_IS_IN_FLASH	1 -#define CFG_ENV_ADDR            (PHYS_FLASH_1 + 0x1C000) -                                        /* Addr of Environment Sector       */ -#define CFG_ENV_SIZE            0x4000  /* Total Size of Environment Sector */ -#endif -  #endif  /* __CONFIG_H */ diff --git a/include/i2c.h b/include/i2c.h index 43d76fd81..6d39080d8 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -51,6 +51,9 @@   * repeatedly to change the speed and slave addresses.   */  void i2c_init(int speed, int slaveaddr); +#ifdef CFG_I2C_INIT_BOARD +void i2c_init_board(void); +#endif  /*   * Probe the given I2C chip address.  Returns 0 if a chip responded, |