diff -uNr mtd-20000119/byteorder-patch mtd-20000131/byteorder-patch
--- mtd-20000119/byteorder-patch	Thu Jan  1 01:00:00 1970
+++ mtd-20000131/byteorder-patch	Mon Jan 31 11:12:14 2000
@@ -0,0 +1,78 @@
+Index: include/linux/byteorder/big_endian.h
+===================================================================
+RCS file: /cvs/linux/include/linux/byteorder/big_endian.h,v
+retrieving revision 1.1.1.1
+diff -u -w -r1.1.1.1 big_endian.h
+--- include/linux/byteorder/big_endian.h	1998/10/28 21:23:47	1.1.1.1
++++ include/linux/byteorder/big_endian.h	2000/01/31 11:11:32
+@@ -14,6 +14,18 @@
+ #define __constant_ntohl(x) ((__u32)(x))
+ #define __constant_htons(x) ((__u16)(x))
+ #define __constant_ntohs(x) ((__u16)(x))
++#define __constant_cpu_to_le64(x) ___swab64((x))
++#define __constant_le64_to_cpu(x) ___swab64((x))
++#define __constant_cpu_to_le32(x) ___swab32((x))
++#define __constant_le32_to_cpu(x) ___swab32((x))
++#define __constant_cpu_to_le16(x) ___swab16((x))
++#define __constant_le16_to_cpu(x) ___swab16((x))
++#define __constant_cpu_to_be64(x) ((__u64)(x))
++#define __constant_be64_to_cpu(x) ((__u64)(x))
++#define __constant_cpu_to_be32(x) ((__u32)(x))
++#define __constant_be32_to_cpu(x) ((__u32)(x))
++#define __constant_cpu_to_be16(x) ((__u16)(x))
++#define __constant_be16_to_cpu(x) ((__u16)(x))
+ #define __cpu_to_le64(x) __swab64((x))
+ #define __le64_to_cpu(x) __swab64((x))
+ #define __cpu_to_le32(x) __swab32((x))
+Index: include/linux/byteorder/little_endian.h
+===================================================================
+RCS file: /cvs/linux/include/linux/byteorder/little_endian.h,v
+retrieving revision 1.1.1.1
+diff -u -w -r1.1.1.1 little_endian.h
+--- include/linux/byteorder/little_endian.h	1998/10/28 21:23:47	1.1.1.1
++++ include/linux/byteorder/little_endian.h	2000/01/31 11:11:32
+@@ -14,6 +14,18 @@
+ #define __constant_ntohl(x) ___swab32((x))
+ #define __constant_htons(x) ___swab16((x))
+ #define __constant_ntohs(x) ___swab16((x))
++#define __constant_cpu_to_le64(x) ((__u64)(x))
++#define __constant_le64_to_cpu(x) ((__u64)(x))
++#define __constant_cpu_to_le32(x) ((__u32)(x))
++#define __constant_le32_to_cpu(x) ((__u32)(x))
++#define __constant_cpu_to_le16(x) ((__u16)(x))
++#define __constant_le16_to_cpu(x) ((__u16)(x))
++#define __constant_cpu_to_be64(x) ___swab64((x))
++#define __constant_be64_to_cpu(x) ___swab64((x))
++#define __constant_cpu_to_be32(x) ___swab32((x))
++#define __constant_be32_to_cpu(x) ___swab32((x))
++#define __constant_cpu_to_be16(x) ___swab16((x))
++#define __constant_be16_to_cpu(x) ___swab16((x))
+ #define __cpu_to_le64(x) ((__u64)(x))
+ #define __le64_to_cpu(x) ((__u64)(x))
+ #define __cpu_to_le32(x) ((__u32)(x))
+Index: include/linux/byteorder/pdp_endian.h
+===================================================================
+RCS file: /cvs/linux/include/linux/byteorder/pdp_endian.h,v
+retrieving revision 1.1.1.1
+diff -u -w -r1.1.1.1 pdp_endian.h
+--- include/linux/byteorder/pdp_endian.h	1998/10/28 21:23:47	1.1.1.1
++++ include/linux/byteorder/pdp_endian.h	2000/01/31 11:11:32
+@@ -34,6 +34,18 @@
+ #define __constant_ntohl(x) ___swahb32((x))
+ #define __constant_htons(x) ___swab16((x))
+ #define __constant_ntohs(x) ___swab16((x))
++#define __constant_cpu_to_le64(x) I DON'T KNOW
++#define __constant_le64_to_cpu(x) I DON'T KNOW
++#define __constant_cpu_to_le32(x) ___swahw32((x))
++#define __constant_le32_to_cpu(x) ___swahw32((x))
++#define __constant_cpu_to_le16(x) ((__u16)(x)
++#define __constant_le16_to_cpu(x) ((__u16)(x)
++#define __constant_cpu_to_be64(x) I DON'T KNOW
++#define __constant_be64_to_cpu(x) I DON'T KNOW
++#define __constant_cpu_to_be32(x) ___swahb32((x))
++#define __constant_be32_to_cpu(x) ___swahb32((x))
++#define __constant_cpu_to_be16(x) ___swab16((x))
++#define __constant_be16_to_cpu(x) ___swab16((x))
+ #define __cpu_to_le64(x) I DON'T KNOW
+ #define __le64_to_cpu(x) I DON'T KNOW
+ #define __cpu_to_le32(x) ___swahw32((x))
diff -uNr mtd-20000119/grub/Makefile mtd-20000131/grub/Makefile
--- mtd-20000119/grub/Makefile	Thu Jan  1 01:00:00 1970
+++ mtd-20000131/grub/Makefile	Fri Jan 28 13:32:12 2000
@@ -0,0 +1,24 @@
+# Default to using the new FSF grub
+STAGE2FILE := pre_stage2
+# Comment out the above, and uncomment the following two lines, if you
+# are using Erich Boleyn's old grub (<= 0.5)
+#STDEFINE := -DOLDGRUB
+#STAGE2FILE := stage2
+
+
+grub_firmware: doc_stage1 makecsum pre_stage2 Makefile
+	./makecsum doc_stage1 $(STAGE2FILE) grub_firmware
+
+doc_stage1: doc_stage1.exec Makefile
+	objcopy -O binary doc_stage1.exec doc_stage1
+
+doc_stage1.exec: doc_stage1.S doc_stage1.h stage2_size.h Makefile
+	$(CC) -O2 $(STDEFINE) -fno-builtin -nostdinc -nostdlib -Wl,-N,-Ttext,0 -o doc_stage1.exec doc_stage1.S
+
+stage2_size.h: $(STAGE2FILE)
+	-rm -f stage2_size.h
+	set dummy `ls -l $(STAGE2FILE)`; \
+	echo "#define STAGE2_SIZE $$6" > stage2_size.h
+
+clean:
+	rm -f doc_stage1 *~ grub_firmware doc_stage1.exec makecsum stage2_size.h
diff -uNr mtd-20000119/grub/README mtd-20000131/grub/README
--- mtd-20000119/grub/README	Thu Jan  1 01:00:00 1970
+++ mtd-20000131/grub/README	Fri Jan 28 13:53:26 2000
@@ -0,0 +1,63 @@
+	$Id: README,v 1.3 2000/01/28 13:53:26 dwmw2 Exp $
+
+HOW TO GET GRUB BOOTING FROM DiskOnChip
+---------------------------------------
+
+(0. You'll need the driver modules loaded and the utils built.)
+ 1. Build a recent GRUB (from the FSF, not the old grub-0.5)
+ 2. Copy the 'stage2/pre_stage2' file to this directory.
+ 3. make
+ 4. ../util/doc_loadbios /dev/mtd0 grub_firmware
+
+This assumes that the DiskOnChip is the only (or first) memory device
+for which the driver was loaded - and hence that it's /dev/mtd0
+
+
+HOW IT WORKS
+------------
+
+The DiskOnChip has a built-in ROM which is recognised as a BIOS extension
+by the system BIOS. This is called the 'IPL ROM', and it attempts to load 
+0x2000 bytes of the next stage, called the 'SPL, from the DiskOnChip.
+
+To make life complex, it doesn't just load the first 0x2000 bytes from the
+DiskOnChip - it loads half of the first 0x4000 bytes instead. Of each 512-byte
+block, it loads the first 256 bytes. 
+This is because of the way that NAND flash blocks are divided into two pages,
+and presumably it's done to save code space in the IPL ROM.
+
+As it loads the SPL, it performs a checksum. Iff the checksum of the SPL is
+equal to 0x55, then it will execute the SPL, which it has loaded to the 
+address 0x2000:0000.
+
+The SPL in turn is responsible for loading the rest of the firmware from the 
+DiskOnChip. Normally, this steals some memory for itself, and installs an
+INT 13h (Disk BIOS) handler to emulate disk access.
+
+We change this. Instead of installing an INT 13h handler, we install an
+INT 18h (bootstrap) handler. This is very small, and is held entirely
+within the first 256 bytes of the SPL with the code which installs it. 
+
+The INT 18h handler, when executed, loads GRUB Stage2 from the DiskOnChip
+to the place where GRUB Stage1 would normally load it, and then passes 
+control to it.
+
+Clear as mud? 
+
+
+NOTE: Grub 0.5, which was the latest version for some time before the FSF
+took over, expects stage2 to be loaded to 0x08000, and executed with CS:IP
+0000:8000.
+
+The versions currently in the FSF CVS repository are slightly different. The
+stage2 now has a 512-byte loader prepended to it, so now we need to load it
+as before but execute it starting as 0000:8200.
+
+I've changed the default behaviour of the DiskOnChip Stage1 over to the new 
+address, because I expect any development of DiskOnChip capability in Grub 
+itself to be added to the CVS version, not the old 0.5 version.
+
+If you are using this with the older grub, change the first few lines of the
+Makefile appropriately.
+
+DW 28/1/00
diff -uNr mtd-20000119/grub/doc_stage1.S mtd-20000131/grub/doc_stage1.S
--- mtd-20000119/grub/doc_stage1.S	Thu Jan  1 01:00:00 1970
+++ mtd-20000131/grub/doc_stage1.S	Mon Jan 31 09:49:31 2000
@@ -0,0 +1,359 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000 Machine Vision Holdings, Inc.
+ *
+ *  Author: David Woodhouse <dwmw2@infradead.org>
+ *
+ *  $Id: doc_stage1.S,v 1.6 2000/01/31 09:49:31 dwmw2 Exp $
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "doc_stage1.h"
+#include "stage2_size.h"
+
+/*
+ *  defines for the code go here
+ */
+
+#ifdef OLDGRUB /* Loading Erich's old grub */
+
+#define LOADLEN (((STAGE2_SIZE + 0xff) & ~0xff) >> 8)
+#define GRUBSTART 0x8000
+#define GRUBLOADSEG	0x7e0
+#define GRUBLOADOFS	0x200
+
+#else /* Loading FSF grub */
+
+#define LOADLEN (((((STAGE2_SIZE + 0xff) & ~0xff) + 0x200)) >> 8)
+#define GRUBSTART 0x8200
+#define GRUBLOADSEG	0x800
+#define GRUBLOADOFS	0x000
+
+#endif
+
+
+	
+			/* Some macros to make it obvious what we're accessing */
+#define BXREG 0x1004
+
+#define BX_ChipID		-4(%bx)
+#define BX_DOCControl		-2(%bx)
+#define BX_CSDNControl		(%bx)
+#define BX_SlowIO		9(%bx)
+
+#define SIREG 0x1800
+#define SI_CSDN_IO		(%si)
+	
+		/* Print message string */
+#define MSG(x)	movw $(x), %si; call message
+
+	.file	"stage1_doc.S"
+
+	.text
+
+	/* Tell GAS to generate 16-bit instructions so that this code works
+	   in real mode. */
+	.code16
+
+.globl _start; _start:
+	/*
+	 * _start is loaded at 0x20000 by the DiskOnChip IPL,
+	 *	and is jumped to with CS:IP 0x2000:0
+	 */
+
+	
+	/* What we need to do is:
+	   1. Check the current end-of-memory in the BIOS
+	   2. Reduce it by the amount of memory we need for our INT 18h 
+	   3. Return, and wait for our INT 18h to be called.
+	*/
+
+		/* Store the DiskOnChip segment */
+	movw	%ds, %cs:doc_seg
+		
+		/* Find top of memory */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	movw	0x0413, %ax
+
+		/* Set up our shiny net INT 18h handler */
+	movw	%es,0x0066
+	movw	$int18,0x0062
+
+
+		/* Steal 1K from the top */
+	decw	%ax
+	movw	%ax,0x0413
+
+		/* Generate segment address */
+	shlw	$6,%ax
+	movw	%ax,%es
+
+		/* Debug: print the address at which we're installing */
+	pushw	%cs
+	popw	%ds
+
+		/* Copy ourself into the new segment we've just reserved */
+	movw	$0x80, %cx
+	cld
+	xorw	%si,%si
+	xorw	%di,%di
+	rep
+	movsw
+
+#if 0
+		/* Copy the old INT 18h handler vector */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+
+	movw	0x0060, %ax
+	movw	%ax, %es:oldvec_ofs
+
+	movw	0x0062, %ax
+	movw	%ax, %es:oldvec_seg
+
+		/* Set up our shiny net INT 18h handler */
+	//sti
+	movw	%es,0x0062
+	movw	$int18,0x0060
+	//cli
+#endif
+	lret	
+	
+int18:
+#if 0
+	pushw	%ax
+	pushw	%bx
+	pushw	%cx
+	pushw	%dx
+	pushw	%ds
+	pushw	%es
+	pushw	%di
+	pushw	%si
+#endif	
+	pushw	%cs
+	popw	%ds
+
+		/* Say hello */
+	MSG(int18_execed_string)
+
+		/* Check where the DiskOnChip is */
+	movw	doc_seg, %ds
+
+		/* Set up our target address for writing stage2 */
+	movw	$GRUBLOADSEG, %ax
+	movw	%ax, %es
+#if	GRUBLOADOFS == 0
+	xorw	%di, %di
+#else
+	movw	$GRUBLOADOFS, %di
+#endif
+
+		/* Contents of DiskOnChip are loaded at 0000:8000 */
+		/* The first 0x200 bytes of this is in fact this bootloader,
+		 *   and it replaces the bootloader which CVS grub has now
+		 *   added to the beginning of stage2
+		 * Stage2 proper starts at 0x08200, which is convenient.
+		 */
+
+	cld
+
+		/* Copy it.... */
+
+		/* Reset DiskOnChip */
+	movw	$BXREG, %bx
+	movb	$DOC_MODE_CLR_ERR + DOC_MODE_MDWREN + DOC_MODE_NORMAL, BX_DOCControl
+	movb	$DOC_MODE_CLR_ERR + DOC_MODE_MDWREN + DOC_MODE_NORMAL, BX_DOCControl
+
+	movw	$SIREG, %si
+	
+		/* Flash command:	Reset */
+	movb	$NAND_CMD_RESET, %ah
+	call	doc_cmd
+
+		/* Load %CX with the number of 256-byte blocks to load */	
+	movw	$LOADLEN, %cx
+
+mainloop:
+		/* We're still reading a block */
+//	testw	$0xff, %di
+//	jnz	readbyte
+
+		/* Send new READ command - is it READ0 or READ1? */
+
+	movw	%di, %ax
+	andb	$1,%ah
+	call	doc_cmd
+
+		/* Start of new block. Set address */
+	movb	$CSDN_CTRL_FLASH_IO + CSDN_CTRL_WP + CSDN_CTRL_ALE + CSDN_CTRL_CE, BX_CSDNControl
+	incw	BX_ChipID
+
+		/* We sent bits 0-7, then 9-16, then 17-23 */
+		/* Yes bit 8 is missing. Read the NAND flash specs */		
+	movw	%di,%dx
+		/* Bits 0-7 are always zero */
+	movb	$0,BX_SlowIO
+	movb	$0,SI_CSDN_IO
+			/* Bits 9-16 */
+	shrw	$1,%dx
+	.byte	0x80, 0xce /* orb adrbit16, %dh */
+adrbit16:	
+	.byte	0	
+	movb	%dh,BX_SlowIO
+	movb	%dh,SI_CSDN_IO
+		/* Bits 17-23 are also zero */
+	.byte	0xb2 /* movb adrbytehi, %dl */
+adrbytehi:
+	.byte	0
+	movb	%dl,BX_SlowIO
+	movb	%dl,SI_CSDN_IO
+
+		/* Clear the ALE line to the flash chip */
+	movb	$CSDN_CTRL_FLASH_IO + CSDN_CTRL_WP + CSDN_CTRL_CE, BX_CSDNControl
+	call	doc_wait
+
+	pushw	%cx		/* Store the 'blocks remaining' count */
+	movw	$0x100, %cx	/* Set up to copy 0x100 bytes */
+readbyte:	
+	testb	BX_SlowIO,%al	/* dummy read */
+	movsb			/* movb SI_CSDN_IO ;  stosb would be more obvious, */
+	decw	%si		/*  but would take an extra byte. */
+	loop	readbyte
+
+
+	testw	$0xffff, %di	/* Check if we've done a whole 0x10000 bytes */
+	jnz	endloop		/* No - continue regardless */
+		/* Yes - increase %es */
+	movw	%es, %cx
+	addb	$0x10, %ch
+	movw	%cx, %es
+
+	addb	$0x80, %cs:adrbit16	/* Increase bit 16 */
+	jnc	endloop			/* Did it overflow? */
+	incb	%cs:adrbytehi		/* If so, increase the high byte too */
+
+endloop:	
+	popw	%cx		/* Restore the 'blocks remaining' count */
+	loop	mainloop	/* Loop till completely done */
+good:	
+		/* Run it:	 jmpf 0:2000 */
+
+	.byte	0xea
+	.word	GRUBSTART,0
+
+		/* doc_cmd:	 Send a command to the flash chip */
+doc_cmd:
+		/* Enable CLE line to flash */
+	movb	$CSDN_CTRL_FLASH_IO + CSDN_CTRL_WP + CSDN_CTRL_CLE + CSDN_CTRL_CE, BX_CSDNControl
+		/* Dummy */
+	incw	-4(%bx)
+		/* Write the actual command */
+	movb	%ah,BX_SlowIO
+	movb	%ah,(%si)
+
+		/* doc_wait:	 Wait for the DiskOnChip to be ready */
+doc_wait:
+	incw	BX_ChipID
+l38:	
+	testb	$0x80,BX_CSDNControl
+	jz	l38
+	test	BX_CSDNControl,%dx
+	ret
+		
+#if 0	
+bad:		/* Whinge and return*/
+	
+	popw	%si
+	popw	%di
+	popw	%es
+	popw	%ds
+	popw	%dx
+	popw	%cx
+	popw	%bx
+	popw	%ax
+	.byte 0xea		// jmpf
+oldvec_ofs:	.word 0
+oldvec_seg:	.word 0
+#endif
+
+doc_seg:	.word 0
+	
+int18_execed_string:	.string "Loading GRUB from DiskOnChip\n\r"
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+	/*
+	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+	 *	%ah = 0xe	%al = character
+	 *	%bh = page	%bl = foreground color (graphics modes)
+	 */
+1:
+	movw	$0x0001, %bx
+	movb	$0xe, %ah
+	int	$0x10		/* display a byte */
+
+message:
+	lodsb
+	cmpb	$0, %al
+	jne	1b	/* if not end of string, jmp to display */
+	ret
+
+	/* Hex output routines, used at one point in debugging */	
+#if 0
+phword:
+	pushw	%ax
+	xchgb	%al,%ah
+	call	phbyte
+	movb	%ah,%al
+	call	phbyte
+	popw	%ax
+	ret
+
+
+phbyte:
+	pushw	%ax
+	movb	%al, %ah
+	shrb	$4,%al
+	call	phnibble
+	movb	%ah, %al
+	call	phnibble
+	popw	%ax
+	ret
+
+phnibble:
+	pushw	%ax
+	andb	$0xf,%al
+	addb	$48,%al
+	cmpb	$57,%al
+	jna	ph1
+	add	$7,%al
+ph1:	mov	$0xe,%ah
+	int	$0x10
+	popw	%ax
+	ret
+#endif
+
+#if 0
+		/* Cause an error if this code was too large. */
+	.org 0xff
+	.byte 0 /* Placement of checksum byte */
+#endif	
diff -uNr mtd-20000119/grub/doc_stage1.h mtd-20000131/grub/doc_stage1.h
--- mtd-20000119/grub/doc_stage1.h	Thu Jan  1 01:00:00 1970
+++ mtd-20000131/grub/doc_stage1.h	Mon Jan 31 11:05:23 2000
@@ -0,0 +1,78 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000 Machine Vision Holdings, Inc.
+ *
+ *  Author: David Woodhouse <dwmw2@infradead.org>
+ *
+ *  $Id: doc_stage1.h,v 1.1 2000/01/31 11:05:23 dwmw2 Exp $
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#define DoC_M_CDSN_IO 0x800
+
+#define DoC_ChipID 0x1000
+#define DoC_DOCStatus 0x1001
+#define DoC_DOCControl 0x1002
+#define DoC_FloorSelect 0x1003
+#define DoC_CSDNControl 0x1004
+#define DoC_CSDNDeviceSelect 0x1005
+#define DoC_ECCConf 0x1006
+#define DoC_2k_ECCStatus 0x1007
+
+#define DoC_CSDNSlowIO 0x100d
+#define DoC_ECCSyndrome0 0x1010
+#define DoC_ECCSyndrome1 0x1011
+#define DoC_ECCSyndrome2 0x1012
+#define DoC_ECCSyndrome3 0x1013
+#define DoC_ECCSyndrome4 0x1014
+#define DoC_ECCSyndrome5 0x1015
+#define DoC_AliasResolution 0x101b
+#define DoC_ConfigInput 0x101c
+#define DoC_ReadPipeInit 0x101d
+#define DoC_WritePipeTerm 0x101e
+#define DoC_LastDataRead 0x101f
+#define DoC_NOP 0x1020
+
+#define DoC_2k_CSDN_IO 0x1800
+
+	
+	
+#define DOC_MODE_RESET 0
+#define DOC_MODE_NORMAL 1
+#define DOC_MODE_RESERVED1 2
+#define DOC_MODE_RESERVED2 3
+
+#define DOC_MODE_MDWREN 4
+#define DOC_MODE_CLR_ERR 0x80
+
+#define DOC_ChipID_Doc2k 0x20
+#define DOC_ChipID_DocMil 0x30
+
+#define CSDN_CTRL_FR_B 0x80
+#define CSDN_CTRL_ECC_IO 0x20
+#define CSDN_CTRL_FLASH_IO 0x10
+#define CSDN_CTRL_WP 8
+#define CSDN_CTRL_ALE 4
+#define CSDN_CTRL_CLE 2
+#define CSDN_CTRL_CE 1
+
+	
+#define NAND_CMD_READ0 0
+#define NAND_CMD_READ1 1
+#define NAND_CMD_RESET 0xff
+
diff -uNr mtd-20000119/grub/makecsum.c mtd-20000131/grub/makecsum.c
--- mtd-20000119/grub/makecsum.c	Thu Jan  1 01:00:00 1970
+++ mtd-20000131/grub/makecsum.c	Thu Jan 27 13:35:15 2000
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+unsigned char buf[16384];
+
+main(int argc, char **argv)
+{
+	int len,i, stubfd, st2fd, outfd, retval=0;
+	unsigned char checksum=0;
+
+	memset(buf, 0xff, 16384);
+
+	if (argc < 4) {
+		fprintf(stderr, "Usage: makecsum <stubfile> <stage2> <outfile>\n");
+		exit(1);
+	}
+	
+	stubfd = open(argv[1], O_RDONLY);
+	if (stubfd < 0) {
+		perror("open stub file");
+		exit(1);
+	}
+
+	st2fd = open(argv[2], O_RDONLY);
+	if (st2fd < 0) {
+		perror("open stage2 file");
+		close(stubfd);
+		exit(1);
+	}
+
+	outfd = open(argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0664);
+	if (outfd < 0) {
+		perror("open output file");
+		exit(1);
+	}
+
+	/* Read the stub loader (stage1) */
+
+	len =  read(stubfd,buf,513);
+	if (len < 0) {
+		perror("read from stub file");
+		close(outfd);
+		close(st2fd);
+		close(stubfd);
+		exit(1);
+	}
+
+	if (len > 512) {
+		fprintf(stderr, "stub file is too large (>512 bytes)\n");
+		close(outfd);
+		close(st2fd);
+		close(stubfd);
+		exit(1);
+	}
+
+	close(stubfd);
+
+	/* Read enough of the remainder to calculate the csum */
+	
+	len = read(st2fd, buf+512, 16384-512);
+	if (len < 0) {
+		perror("read from stage2 file\n");
+		close(outfd);
+		close(st2fd);
+		exit(1);
+	}
+
+
+	/* Calculate the csum */
+	buf[255] = 0;
+
+	i=0;
+	while (i<16384) {
+		checksum += buf[i];
+		i++;
+		if ((i >> 8)&1)
+			i += 256;
+	}
+
+	/* Set the slack byte to fix the csum */
+	buf[255] = 0x55 - checksum;
+
+	/* Write the original buffer */
+	len = write(outfd, buf, 16384);
+
+	if (len < 0) {
+		perror("write output file");
+		close(outfd);
+		close(st2fd);
+		exit(1);
+	}
+
+	if (len < 16384) {
+		fprintf(stderr, "short write of output file (%d bytes < 16384)\n",
+			len);
+		close(outfd);
+		close(st2fd);
+		exit(1);
+	}
+	
+	/* Now chuck out the rest of the stage2 */
+
+	while (1) {
+		len = read(st2fd, buf, 16384);
+		if (len < 0) {
+			perror("read stage2 file");
+			retval = 1;
+			break;
+		}
+		if (len == 0)
+			break;
+		
+		i = write(outfd, buf, len);
+		if (i < 0) {
+			perror("write output file");
+			retval = 1;
+			break;
+		}
+		if (i<len) {
+			fprintf(stderr, "short write of output file (%d bytes < %d)\n",
+				i,len);
+			retval = 1;
+			break;
+		}
+	}
+		
+	close(outfd);
+	close(st2fd);
+	return retval;
+}
diff -uNr mtd-20000119/include/linux/mtd/nftl.h mtd-20000131/include/linux/mtd/nftl.h
--- mtd-20000119/include/linux/mtd/nftl.h	Wed Jan 19 08:35:13 2000
+++ mtd-20000131/include/linux/mtd/nftl.h	Mon Jan 31 13:28:55 2000
@@ -2,7 +2,7 @@
 /* Defines for NAND Flash Translation Layer  */
 /* (c) 1999 Machine Vision Holdings, Inc.    */
 /* Author: David Woodhouse <dwmw2@mvhi.com>  */
-/* $Id: nftl.h,v 1.4 2000/01/19 08:35:13 dwmw2 Exp $ */
+/* $Id: nftl.h,v 1.5 2000/01/31 13:28:51 dwmw2 Exp $ */
 
 #ifndef __MTD_NFTL_H__
 #define __MTD_NFTL_H__
@@ -74,6 +74,7 @@
 
 struct NFTLrecord {
 	struct mtd_info *mtd;
+	spinlock_t mutex;
 	__u16 MediaUnit, SpareMediaUnit;
 	__u32 EraseSize;
 	struct NFTLMediaHeader MediaHdr;
diff -uNr mtd-20000119/kernel/Config.in mtd-20000131/kernel/Config.in
--- mtd-20000119/kernel/Config.in	Wed Jan 19 10:04:37 2000
+++ mtd-20000131/kernel/Config.in	Mon Jan 31 11:07:51 2000
@@ -1,5 +1,5 @@
 mainmenu_option next_comment
-comment 'Memory Technology Device (MTD)'
+comment 'Memory Technology Devices (MTD)'
 
 tristate 'Memory Technology Device (MTD) support' CONFIG_MTD
 
@@ -10,8 +10,8 @@
 	dep_tristate 'Octagon 5066 SBC onboard flash support' CONFIG_MTD_OCTAGON $CONFIG_MTD
 	dep_tristate 'Tempustech VMAX SBC301 onboard flash support' CONFIG_MTD_VMAX $CONFIG_MTD
 	dep_tristate 'Mixcom piggyback flash card support' CONFIG_MTD_MIXMEM $CONFIG_MTD
-
-	dep_tristate 'FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD
+# Leave out FTL till it's updated.
+#	dep_tristate 'FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD
 	dep_tristate 'NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD
 	dep_tristate 'Direct blockdevice access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD
 fi
diff -uNr mtd-20000119/kernel/Makefile mtd-20000131/kernel/Makefile
--- mtd-20000119/kernel/Makefile	Mon Oct 25 15:55:46 1999
+++ mtd-20000131/kernel/Makefile	Mon Jan 31 11:07:51 2000
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.8 1999/10/25 14:55:46 dwmw2 Exp $
+# $Id: Makefile,v 1.9 2000/01/31 11:04:39 dwmw2 Exp $
 
 
 ifndef CONFIG_MTD
@@ -21,7 +21,7 @@
 ifeq ($(CONFIG_MTD),y)
   OX_OBJS += mtd.o mapped.o
 else
-  ifeq ($(CONFIG_MTD_DOC1000),m)
+  ifeq ($(CONFIG_MTD),m)
     MX_OBJS += mtd.o mapped.o
   endif
 endif
diff -uNr mtd-20000119/kernel/doc2000.c mtd-20000131/kernel/doc2000.c
--- mtd-20000119/kernel/doc2000.c	Wed Jan 19 10:26:04 2000
+++ mtd-20000131/kernel/doc2000.c	Mon Jan 31 11:07:51 2000
@@ -2,7 +2,7 @@
 /* Linux driver for Disk-On-Chip 2000       */
 /* (c) 1999 Machine Vision Holdings, Inc.   */
 /* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: doc2000.c,v 1.9 2000/01/19 10:26:04 dwmw2 Exp $ */
+/* $Id: doc2000.c,v 1.10 2000/01/31 11:04:39 dwmw2 Exp $ */
 
 
 /* DOC_PASSIVE_PROBE:
@@ -895,7 +895,7 @@
 	
 	printk(KERN_NOTICE "M-Systems DiskOnChip driver. (C) 1999 Machine Vision Holdings, Inc.\n");
 #ifdef PRERELEASE
-	printk(KERN_INFO "$Id: doc2000.c,v 1.9 2000/01/19 10:26:04 dwmw2 Exp $\n");
+	printk(KERN_INFO "$Id: doc2000.c,v 1.10 2000/01/31 11:04:39 dwmw2 Exp $\n");
 #endif
 	
 	for (i=0; doc_locations[i]; i++) {
@@ -929,4 +929,11 @@
 		}
 	}
 }
+
+#if LINUX_VERSION_CODE > 0x20300
+module_init(init_doc2000);
+module_exit(cleanup_doc2000);
+#endif
+
+
 
diff -uNr mtd-20000119/kernel/mtd.c mtd-20000131/kernel/mtd.c
--- mtd-20000119/kernel/mtd.c	Wed Jan 19 10:26:04 2000
+++ mtd-20000131/kernel/mtd.c	Mon Jan 31 11:07:51 2000
@@ -1,6 +1,6 @@
 /*======================================================================
 
-  $Id: mtd.c,v 1.9 2000/01/19 10:26:04 dwmw2 Exp $
+  $Id: mtd.c,v 1.10 2000/01/31 11:04:39 dwmw2 Exp $
 
     A general driver for accessing Memory Technology Devices
 
@@ -552,4 +552,11 @@
 	  remove_proc_entry( "mtd", 0);
 #endif
 }
+
+      
+#if LINUX_VERSION_CODE > 0x20300
+module_init(init_mtd);
+module_exit(cleanup_mtd);
+#endif
+
 
diff -uNr mtd-20000119/kernel/mtdblock.c mtd-20000131/kernel/mtdblock.c
--- mtd-20000119/kernel/mtdblock.c	Wed Jan 19 10:26:04 2000
+++ mtd-20000131/kernel/mtdblock.c	Mon Jan 31 09:48:45 2000
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                          /*{{{*/
-// $Id: mtdblock.c,v 1.4 2000/01/19 10:26:04 dwmw2 Exp $
+// $Id: mtdblock.c,v 1.6 2000/01/30 14:53:58 dwmw2 Exp $
 /* ######################################################################
 
    Memory Technology Devices Manager
@@ -30,6 +30,11 @@
 #define DEVICE_NO_RANDOM
 #include <linux/blk.h>
 
+#if LINUX_VERSION_CODE < 0x20300
+#define RQFUNC_ARG void
+#else
+#define RQFUNC_ARG request_queue_t *q
+#endif
 static int mtd_blksizes[MAX_MTD_DEVICES];
 static int mtd_sizes[MAX_MTD_DEVICES];
 
@@ -103,7 +108,7 @@
 // ---------------------------------------------------------------------
 /* This is a simple request handler to verify the parameters and pass them
    on to the lower mtd layer */
-static void mtdblock_request(void)
+static void mtdblock_request(RQFUNC_ARG)
 {
    struct request *current_request;
    unsigned int res = 0;
@@ -199,7 +204,7 @@
    }
 }
 									/*}}}*/
-
+#if LINUX_VERSION_CODE < 0x20326
 static struct file_operations mtd_fops =
 {
 	NULL,	             /* lseek - default */
@@ -212,9 +217,15 @@
 	mtdblock_open,	     /* open */
 	NULL,		     /* flush */
 	mtdblock_release,    /* release */
-	block_fsync          /* fsync */  
+	NULL		     /* fsync */  
 };
-
+#else
+static struct block_device_operations mtd_fops = 
+{
+	open: mtdblock_open,
+	release: mtdblock_release
+};
+#endif
 
 
 
@@ -240,11 +251,13 @@
       return EAGAIN;
    }
 
-   printk("MAJOR_NR == %d, MTD_BLOCK_MAJOR %d\n",MAJOR_NR, MTD_BLOCK_MAJOR);
    blksize_size[MAJOR_NR] = mtd_blksizes;
    blk_size[MAJOR_NR] = mtd_sizes;
+#if LINUX_VERSION_CODE < 0x20320
    blk_dev[MAJOR_NR].request_fn = mtdblock_request;
-   
+#else
+   blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
+#endif
    return 0;
 }
 									/*}}}*/
diff -uNr mtd-20000119/kernel/nftl.c mtd-20000131/kernel/nftl.c
--- mtd-20000119/kernel/nftl.c	Wed Jan 19 10:26:04 2000
+++ mtd-20000131/kernel/nftl.c	Mon Jan 31 13:28:22 2000
@@ -2,7 +2,7 @@
 /* Linux driver for NAND Flash Translation Layer */
 /* (c) 1999 Machine Vision Holdings, Inc.   */
 /* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: nftl.c,v 1.12 2000/01/19 10:26:04 dwmw2 Exp $ */
+/* $Id: nftl.c,v 1.20 2000/01/31 13:28:14 dwmw2 Exp $ */
 
 #define PRERELEASE
 
@@ -28,6 +28,11 @@
 #include <linux/hdreg.h>
 
 
+#if LINUX_VERSION_CODE < 0x20300
+#define RQFUNC_ARG void
+#else
+#define RQFUNC_ARG request_queue_t *q
+#endif
 
 
 
@@ -39,23 +44,27 @@
 
 static int nftl_sizes[256]={0,};
 static int nftl_blocksizes[256] = {0,};
-
+#if LINUX_VERSION_CODE > 0x20328
+static int nftl_max_sectors[256] = {1,};
+#endif
 /* .. for the Linux partition table handling. */
 
 struct hd_struct part_table[256] = {{0,0},};
 
-
+#if LINUX_VERSION_CODE < 0x20328
 static void dummy_init (struct gendisk *crap)
 {}
-
+#endif
 
 static struct gendisk nftl_gendisk = {
         NFTL_MAJOR,     /* Major number */      
         "nftl",         /* Major name */
         4,              /* Bits to shift to get real from partition */
         15,             /* Number of partitions per real */
+#if LINUX_VERSION_CODE < 0x20328
         MAX_NFTLS,      /* maximum number of real */
         dummy_init,     /* init function */
+#endif
         part_table,     /* hd struct */
         nftl_sizes,     /* block sizes */
         0,              /* number */
@@ -101,7 +110,7 @@
 		printk(KERN_WARNING "Out of memory for NFTL data structures\n");
 		return;
 	}
-	
+	spin_lock_init(&thisNFTL->mutex);
 	thisNFTL->EraseSize = mtd->erasesize;
 	memcpy(&thisNFTL->MediaHdr, hdr, sizeof(*hdr));
 	thisNFTL->mtd = mtd;
@@ -254,9 +263,15 @@
 	/* Except that I haven't implemented that bit yet :) */
 
 	/* Finally, set up the block device sizes */
-	   
+	nftl_sizes[firstfree * 16]=thisNFTL->nr_sects;
+//	nftl_blocksizes[firstfree*16] = 512;
 	part_table[firstfree * 16].nr_sects = thisNFTL->nr_sects;
+#if LINUX_VERSION_CODE < 0x20328
 	resetup_one_dev(&nftl_gendisk, firstfree);
+#else
+	grok_partitions(&nftl_gendisk, firstfree, 1<<4, thisNFTL->nr_sects);
+#endif
+
 }
 
 
@@ -417,18 +432,18 @@
 			BlockLastState[block] = (unsigned char) oob.b.Status & 0xff;
 
 			switch(oob.b.Status) {
-			case cpu_to_le16(BLOCK_FREE):
+			case __constant_cpu_to_le16(BLOCK_FREE):
 				BlockFreeFound[block]=1;
 				break;
 
-			case cpu_to_le16(BLOCK_USED):
+			case __constant_cpu_to_le16(BLOCK_USED):
 				if (!BlockFreeFound[block])
 					BlockMap[block] = thisEUN;
 				else
 					printk(KERN_WARNING "BLOCK_USED found after BLOCK_FREE in Virtual Unit Chain %d for block %d\n", thisVUC, block);
 				break;
-			case cpu_to_le16(BLOCK_IGNORE):
-			case cpu_to_le16(BLOCK_DELETED):
+			case __constant_cpu_to_le16(BLOCK_IGNORE):
+			case __constant_cpu_to_le16(BLOCK_DELETED):
 				break;
 			default:
 				printk("Unknown status for block %d in EUN %d: %x\n",block,thisEUN, oob.b.Status);
@@ -710,14 +725,14 @@
 		MTD_READOOB(thisNFTL->mtd, (thisEUN * thisNFTL->EraseSize) + blockofs,8, &retlen, (char *)&bci);
 		
 		switch(bci.Status) {
-		case cpu_to_le16(BLOCK_FREE):
+		case __constant_cpu_to_le16(BLOCK_FREE):
 			thisEUN = 0;
 			break;
-		case cpu_to_le16(BLOCK_USED):
+		case __constant_cpu_to_le16(BLOCK_USED):
 			lastgoodEUN = thisEUN;
 			break;
-		case cpu_to_le16(BLOCK_IGNORE):
-		case cpu_to_le16(BLOCK_DELETED):
+		case __constant_cpu_to_le16(BLOCK_IGNORE):
+		case __constant_cpu_to_le16(BLOCK_DELETED):
 			break;
 		default:
 			printk("Unknown status for block %d in EUN %d: %x\n",block,thisEUN, bci.Status);
@@ -781,12 +796,12 @@
 				printk("Status of block %d in EUN %d is %x\n", block , writeEUN, le16_to_cpu(bci.Status));
 
 			switch(bci.Status) {
-			case cpu_to_le16(BLOCK_FREE):
+			case __constant_cpu_to_le16(BLOCK_FREE):
 				return writeEUN;
 
-			case cpu_to_le16(BLOCK_DELETED):
-			case cpu_to_le16(BLOCK_USED):
-			case cpu_to_le16(BLOCK_IGNORE):
+			case __constant_cpu_to_le16(BLOCK_DELETED):
+			case __constant_cpu_to_le16(BLOCK_USED):
+			case __constant_cpu_to_le16(BLOCK_IGNORE):
 				break;
 			default:
 				// Invalid block. Don't use it any more. Must implement.
@@ -916,7 +931,7 @@
 		/* If we _still_ haven't got a block to use, we're screwed */
 		return 1;
 	}
-	//	printk("Writing block %lx to EUN %x\n",block, writeEUN);
+//		printk("Writing block %lx to EUN %x\n",block, writeEUN);
 
 
 	thisNFTL->mtd->write_ecc(thisNFTL->mtd, 
@@ -971,7 +986,11 @@
 			//			printk("Use count %d\n", thisNFTL->usecount);
 			return -EBUSY;
 		}
+#if LINUX_VERSION_CODE < 0x20328
 		resetup_one_dev(&nftl_gendisk, MINOR(inode->i_dev) / 16);
+#else
+		grok_partitions(&nftl_gendisk, MINOR(inode->i_dev) / 16, 1<<4, thisNFTL->nr_sects);
+#endif
 		return 0;
 		
 		//        RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
@@ -981,13 +1000,13 @@
 }
 
 
-void nftl_request(void)
+void nftl_request(RQFUNC_ARG)
 {
 	unsigned int dev, block, nsect;
 	struct NFTLrecord *thisNFTL;
 	char *buffer;
  repeat:
-	cli();
+	//cli();
 	INIT_REQUEST;
 	dev = MINOR(CURRENT->rq_dev);
 	block = CURRENT->sector;
@@ -1002,10 +1021,12 @@
 	}
 	
 	thisNFTL = NFTLs[dev / 16];
+	spin_lock(&thisNFTL->mutex);
 	
 	if (block + nsect >= part_table[dev].nr_sects) {
 		printk("nftl%c%d: bad access: block=%d, count=%d\n",
 		       (MINOR(CURRENT->rq_dev)>>6)+'a', dev & 0xf, block, nsect);
+		spin_unlock(&thisNFTL->mutex);
 		end_request(0); /* fail */
 		goto repeat;
 	}
@@ -1014,32 +1035,39 @@
 	
 	if (CURRENT->cmd == READ) {
 		
-		
 		for ( ; nsect > 0; nsect-- , block++, buffer+= 512) {
 			/* Read a single sector to CURRENT->buffer + (512 * i) */
 	
 			if (NFTL_readblock(thisNFTL, block, buffer)) {
+				spin_unlock(&thisNFTL->mutex);
 				end_request(0);
 				goto repeat;
 			}
 		}
+		spin_unlock(&thisNFTL->mutex);
 		end_request(1);
 		goto repeat;
 	}
 	else if (CURRENT->cmd == WRITE) {
-		
+//		printk("NFTL write request of 0x%x sectors @ %lx\n",nsect, block);
 		for ( ; nsect > 0; nsect-- , block++, buffer+= 512) {
 			/* Read a single sector to CURRENT->buffer + (512 * i) */
 	
 			if (NFTL_writeblock(thisNFTL, block, buffer)) {
+			//	printk("NFTL write request failed\n");
+
+				spin_unlock(&thisNFTL->mutex);
 				end_request(0);
 				goto repeat;
 			}
 		}
+//		printk("NFTL write request completed OK\n");
+		spin_unlock(&thisNFTL->mutex);
 		end_request(1);
 		goto repeat;
 	}
 	else {
+		spin_unlock(&thisNFTL->mutex);
 		end_request(0); /* fail */
 		goto repeat;
 	}
@@ -1048,7 +1076,7 @@
 static int nftl_open(struct inode *ip, struct file *fp)
 {
 	struct NFTLrecord *thisNFTL;
-
+	printk("NFTL_open called\n");
 	thisNFTL = NFTLs[MINOR(ip->i_rdev) / 16];
 
 	if (!thisNFTL)
@@ -1084,7 +1112,7 @@
 
 	return 0;
 }
-
+#if LINUX_VERSION_CODE < 0x20326
 static struct file_operations nftl_fops = {
         NULL,           /* lseek - default */
         block_read,     /* read - block dev read */
@@ -1098,7 +1126,14 @@
         nftl_release,           /* no special release code... */
         block_fsync     /* fsync */
 };
-
+#else
+static struct block_device_operations nftl_fops = 
+{
+	open: nftl_open,
+	release: nftl_release,
+	ioctl: nftl_ioctl
+};
+#endif
 
 
 
@@ -1126,15 +1161,26 @@
 	
 	printk(KERN_NOTICE "M-Systems NAND Flash Translation Layer driver. (C) 1999 MVHI\n");
 #ifdef PRERELEASE 
-	printk(KERN_INFO"$Id: nftl.c,v 1.12 2000/01/19 10:26:04 dwmw2 Exp $\n");
+	printk(KERN_INFO"$Id: nftl.c,v 1.20 2000/01/31 13:28:14 dwmw2 Exp $\n");
 #endif
 
 	if (register_blkdev(NFTL_MAJOR, "nftl", &nftl_fops)){
 		printk("unable to register NFTL block device\n");
 	} else {
-		blk_dev[NFTL_MAJOR].request_fn = DEVICE_REQUEST;
-		for (i=0; i < 256 ; i++)
+#if LINUX_VERSION_CODE < 0x20320
+	  blk_dev[MAJOR_NR].request_fn = nftl_request;
+#else
+	  blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request);
+#endif
+		for (i=0; i < 256 ; i++) {
 			nftl_blocksizes[i] = 1024;
+#if LINUX_VERSION_CODE > 0x20328
+			nftl_max_sectors[i] = 1;
+#endif
+		}
+#if LINUX_VERSION_CODE > 0x20328
+		max_sectors[NFTL_MAJOR] = nftl_max_sectors;
+#endif
 		blksize_size[NFTL_MAJOR] = nftl_blocksizes;
 		nftl_gendisk.next = gendisk_head;
 		gendisk_head = &nftl_gendisk;
@@ -1165,7 +1211,11 @@
 
 
   unregister_blkdev(NFTL_MAJOR, "nftl");
-
+#if LINUX_VERSION_CODE < 0x20320
+  blk_dev[MAJOR_NR].request_fn = 0;
+#else
+  blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+#endif	
   for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
     if (*gdp == &nftl_gendisk) {
       gd = *gdp; *gdp = gd->next;
@@ -1178,15 +1228,3 @@
 module_init(init_nftl);
 module_exit(cleanup_nftl);
 #endif
-
-
-
-
-
-
-
-
-
-
-
-
diff -uNr mtd-20000119/util/doc_loadbios.c mtd-20000131/util/doc_loadbios.c
--- mtd-20000119/util/doc_loadbios.c	Fri Aug 20 16:31:01 1999
+++ mtd-20000131/util/doc_loadbios.c	Mon Jan 31 09:48:46 2000
@@ -7,6 +7,7 @@
 #include <sys/ioctl.h>
 #include <sys/mount.h>
 
+/* $Id: doc_loadbios.c,v 1.4 2000/01/31 09:48:08 dwmw2 Exp $ */
 #include <linux/mtd/mtd.h>
 
 unsigned char databuf[512];
@@ -43,13 +44,14 @@
 	   return 1;
    }
    
+#if 0
    if (statbuf.st_size > 65536) {
 	   printf("Firmware too large (%ld bytes)\n",statbuf.st_size);
 	   close(ifd);
 	   close(ofd);
 	   return 1;
    }
-   
+#endif   
      
    if (ioctl(ofd,MEMGETINFO,&meminfo) != 0) {
 	   perror("ioctl(MEMGETINFO)");
@@ -73,14 +75,11 @@
 	   }
    }
 
-   /* Set upper half of buffer to 0xff */
-   memset(databuf+256, 0xff, 256);
 
    do {
-	   retlen = read(ifd, databuf, 256);
-	   if (retlen != 256)
-		   memset(databuf+retlen, 0xff, 256 - retlen);
-
+	   retlen = read(ifd, databuf, 512);
+	   if (retlen < 512)
+	     memset(databuf+retlen, 0xff, 512-retlen);
 	   write(ofd, databuf, 512);
-   } while (retlen == 256);
+   } while (retlen == 512);
 }
