patch-2.2.4 linux/arch/ppc/boot/misc.c

Next file: linux/arch/ppc/boot/of1275.c
Previous file: linux/arch/ppc/boot/mbxtty.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.3/linux/arch/ppc/boot/misc.c linux/arch/ppc/boot/misc.c
@@ -1,7 +1,7 @@
 /*
  * misc.c
  *
- * $Id: misc.c,v 1.53 1998/12/15 17:40:15 cort Exp $
+ * $Id: misc.c,v 1.61 1999/03/08 23:51:02 cort Exp $
  * 
  * Adapted for PowerPC by Gary Thomas
  *
@@ -17,13 +17,7 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/mmu.h>
-#ifdef CONFIG_MBX
-#include <asm/mbx.h>
-#endif
-#ifdef CONFIG_FADS
-#include <asm/fads.h>
-#endif
-#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX)
+#if defined(CONFIG_SERIAL_CONSOLE)
 #include "ns16550.h"
 struct NS16550 *com_port;
 #endif /* CONFIG_SERIAL_CONSOLE */
@@ -37,30 +31,16 @@
  */
 char *avail_ram;
 char *end_avail;
+extern char _end[];
 
-/* Because of the limited amount of memory on the MBX, it presents
- * loading problems.  The biggest is that we load this boot program
- * into a relatively low memory address, and the Linux kernel Bss often
- * extends into this space when it get loaded.  When the kernel starts
- * and zeros the BSS space, it also writes over the information we
- * save here and pass to the kernel (command line and board info).
- * On the MBX we grab some known memory holes to hold this information.
- */
-char cmd_preset[] = "console=tty0 console=ttyS0,9600n8";
+#if defined(CONFIG_SERIAL_CONSOLE)
+char cmd_preset[] = "console=ttyS0,9600n8";
+#else
+char cmd_preset[] = "";
+#endif
 char	cmd_buf[256];
 char	*cmd_line = cmd_buf;
 
-#if defined(CONFIG_MBX) || defined(CONFIG_FADS)
-char	*root_string = "root=/dev/nfs";
-char	*nfsaddrs_string = "nfsaddrs=";
-char	*nfsroot_string = "nfsroot=";
-char	*defroot_string = "/sys/mbxroot";
-int	do_ipaddrs(char **cmd_cp, int echo);
-void	do_nfsroot(char **cmd_cp, char *dp);
-int	strncmp(const char * cs,const char * ct,size_t count);
-char	*strrchr(const char * s, int c);
-#endif
-
 RESIDUAL hold_resid_buf;
 RESIDUAL *hold_residual = &hold_resid_buf;
 unsigned long initrd_start = 0, initrd_end = 0;
@@ -78,6 +58,7 @@
 void * memcpy(void * __dest, __const void * __src,
 			    int __n);
 void gunzip(void *, int, unsigned char *, int *);
+int _cvt(unsigned long val, char *buf, long radix, char *digits);
 
 void pause()
 {
@@ -90,7 +71,6 @@
 	while(1); 
 }
 
-#if !defined(CONFIG_MBX) && !defined(CONFIG_FADS)
 static void clear_screen()
 {
 	int i, j;
@@ -113,17 +93,17 @@
 
 tstc(void)
 {
-#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX)
-	return (CRT_tstc() || NS16550_tstc(com_port));
-#else
-	return (CRT_tstc() );
+	return (
+#if defined(CONFIG_SERIAL_CONSOLE)
+		NS16550_tstc(com_port) ||
 #endif /* CONFIG_SERIAL_CONSOLE */
+		CRT_tstc());
 }
 
 getc(void)
 {
 	while (1) {
-#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX)
+#if defined(CONFIG_SERIAL_CONSOLE)
 		if (NS16550_tstc(com_port)) return (NS16550_getc(com_port));
 #endif /* CONFIG_SERIAL_CONSOLE */
 		if (CRT_tstc()) return (CRT_getc());
@@ -135,7 +115,7 @@
 {
 	int x,y;
 
-#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX)
+#if defined(CONFIG_SERIAL_CONSOLE)
 	NS16550_putc(com_port, c);
 	if ( c == '\n' ) NS16550_putc(com_port, '\r');
 #endif /* CONFIG_SERIAL_CONSOLE */
@@ -149,6 +129,8 @@
 			scroll();
 			y--;
 		}
+	} else if (c == '\r') {
+		x = 0;
 	} else if (c == '\b') {
 		if (x > 0) {
 			x--;
@@ -179,7 +161,7 @@
 	y = orig_y;
 
 	while ( ( c = *s++ ) != '\0' ) {
-#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX)
+#if defined(CONFIG_SERIAL_CONSOLE)
 	        NS16550_putc(com_port, c);
 	        if ( c == '\n' ) NS16550_putc(com_port, '\r');
 #endif /* CONFIG_SERIAL_CONSOLE */
@@ -209,39 +191,6 @@
 	orig_x = x;
 	orig_y = y;
 }
-#else
-/* The MBX is just the serial port.
-*/
-tstc(void)
-{
-        return (serial_tstc());
-}
-
-getc(void)
-{
-        while (1) {
-                if (serial_tstc()) return (serial_getc());
-        }
-}
-
-void 
-putc(const char c)
-{
-        serial_putchar(c);
-}
-
-void puts(const char *s)
-{
-        char c;
-
-        while ( ( c = *s++ ) != '\0' ) {
-                serial_putchar(c);
-                if ( c == '\n' )
-                        serial_putchar('\r');
-        }
-}
-
-#endif /* CONFIG_MBX */
 
 void * memcpy(void * __dest, __const void * __src,
 			    int __n)
@@ -354,7 +303,8 @@
 unsigned char sanity[0x2000];
 
 unsigned long
-decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, RESIDUAL *residual)
+decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
+		  RESIDUAL *residual, void *OFW_interface)
 {
 	int timer;
 	extern unsigned long start;
@@ -362,9 +312,11 @@
 	unsigned long i;
 	BATU *u;
 	BATL *l;
-#if defined(CONFIG_MBX) || defined(CONFIG_KB)
-	char	*dp;
-#endif
+	unsigned long TotalMemory;
+	unsigned long orig_MSR;
+	int dev_handle;
+	int mem_info[2];
+	int res, size;
 
 	lines = 25;
 	cols = 80;
@@ -372,7 +324,6 @@
 	orig_y = 24;
 
 	
-#if !defined(CONFIG_MBX) && !defined(CONFIG_FADS)
 	/*
 	 * IBM's have the MMU on, so we have to disable it or
 	 * things get really unhappy in the kernel when
@@ -381,42 +332,62 @@
 	 */
 	flush_instruction_cache();
 	_put_HID0(_get_HID0() & ~0x0000C000);
-	_put_MSR(_get_MSR() & ~0x0030);
+	_put_MSR((orig_MSR = _get_MSR()) & ~0x0030);
 	vga_init(0xC0000000);
 
-#if defined(CONFIG_SERIAL_CONSOLE) && !defined(CONFIG_MBX)
-	com_port = (struct NS16550 *)NS16550_init(0);
+#if defined(CONFIG_SERIAL_CONSOLE)
+	com_port = (struct NS16550 *)NS16550_init(1);
 #endif /* CONFIG_SERIAL_CONSOLE */
 
 	if (residual)
+	{
 		memcpy(hold_residual,residual,sizeof(RESIDUAL));
-#else /* CONFIG_MBX */
-	
-	/* Grab some space for the command line and board info.  Since
-	 * we no longer use the ELF header, but it was loaded, grab
-	 * that space.
-	 */
-	cmd_line = (char *)(load_addr - 0x10000);
-	hold_residual = (RESIDUAL *)(cmd_line + sizeof(cmd_buf));
-	/* copy board data */
-	if (residual)
-		memcpy(hold_residual,residual,sizeof(bd_t));
-#endif /* CONFIG_MBX */
-
-	/* MBX/prep sometimes put the residual/board info at the end of mem 
-	 * assume 16M for now  -- Cort
-	 * To boot on standard MBX boards with 4M, we can't use initrd,
-	 * and we have to assume less memory.  -- Dan
-	 */
-	if ( INITRD_OFFSET )
-		end_avail = (char *)0x01000000;
-	else
-		end_avail = (char *)0x00400000;
+	} else {
+		/* Assume 32M in the absence of more info... */
+		TotalMemory = 0x02000000;
+		/*
+		 * This is a 'best guess' check.  We want to make sure
+		 * we don't try this on a PReP box without OF
+		 *     -- Cort
+		 */
+		while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) )
+		{
+			/* The MMU needs to be on when we call OFW */
+			_put_MSR(orig_MSR);
+			of_init(OFW_interface);
+
+			/* get handle to memory description */
+			res = of_finddevice("/memory@0", 
+					    &dev_handle);
+			// puthex(res);  puts("\n");
+			if (res) break;
+			
+			/* get the info */
+			// puts("get info = ");
+			res = of_getprop(dev_handle, 
+					 "reg", 
+					 mem_info, 
+					 sizeof(mem_info), 
+					 &size);
+			// puthex(res);  puts(", info = "); puthex(mem_info[0]);  
+			// puts(" ");  puthex(mem_info[1]);   puts("\n");
+			if (res) break;
+			
+			TotalMemory = mem_info[1];
+			break;
+		}
+		hold_residual->TotalMemory = TotalMemory;
+		residual = hold_residual;
+		/* Turn MMU back off */
+		_put_MSR(orig_MSR & ~0x0030);
+        }
 
-	/* let residual data tell us it's higher */
-	if ( (unsigned long)residual > 0x00800000 )
-		end_avail = (char *)PAGE_ALIGN((unsigned long)residual);
+	/* assume the chunk below 8M is free */
+	end_avail = (char *)0x00800000;
 
+	/* tell the user where we were loaded at and where we
+	 * were relocated to for debugging this process
+	 */
 	puts("loaded at:     "); puthex(load_addr);
 	puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
 	if ( (unsigned long)load_addr != (unsigned long)&start )
@@ -431,20 +402,12 @@
 	{
 		puts("board data at: "); puthex((unsigned long)residual);
 		puts(" ");
-#if defined(CONFIG_MBX) || defined(CONFIG_FADS)
-		puthex((unsigned long)((unsigned long)residual + sizeof(bd_t)));
-#else
 		puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL)));
-#endif	
 		puts("\n");
 		puts("relocated to:  ");
 		puthex((unsigned long)hold_residual);
 		puts(" ");
-#if defined(CONFIG_MBX) || defined(CONFIG_FADS)
-		puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t)));
-#else
 		puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL)));
-#endif	
 		puts("\n");
 	}
 
@@ -460,33 +423,16 @@
 	initrd_end = INITRD_SIZE + initrd_start;
 
 	/*
-	 * setup avail_ram - this is the first part of ram usable
-	 * by the uncompress code. -- Cort
+	 * Find a place to stick the zimage and initrd and 
+	 * relocate them if we have to. -- Cort
 	 */
-	avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size);
-	if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram)
-		&& (load_addr <= 0x01000000) )
-		avail_ram = (char *)(load_addr+(num_words*4));
-	if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram)
-		&& (load_addr <= 0x01000000) )
-		avail_ram = (char *)((unsigned long)&start+(num_words*4));
-	
-	/* relocate zimage */
+	avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
 	puts("zimage at:     "); puthex((unsigned long)zimage_start);
 	puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
-	/*
-	 * don't relocate the zimage if it was loaded above 16M since
-	 * things get weird if we try to relocate -- Cort
-	 * We don't relocate zimage on a base MBX board because of
-	 * insufficient memory.  In this case we don't have initrd either,
-	 * so use that as an indicator.  -- Dan
-	 */
-	if (( (unsigned long)zimage_start <= 0x01000000 ) && initrd_start)
+	if ( (unsigned long)zimage_start <= 0x008000000 )
 	{
-		memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-zimage_size),
-			(void *)zimage_start, zimage_size );	
-		zimage_start = (char *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-zimage_size);
-		end_avail = (char *)zimage_start;
+		memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size );
+		zimage_start = (char *)avail_ram;
 		puts("relocated to:  "); puthex((unsigned long)zimage_start);
 		puts(" ");
 		puthex((unsigned long)zimage_size+(unsigned long)zimage_start);
@@ -498,42 +444,21 @@
 	{
 		puts("initrd at:     "); puthex(initrd_start);
 		puts(" "); puthex(initrd_end); puts("\n");
-		/*
-		 * Memory is really tight on the MBX (we can assume 4M)
-		 * so put the initrd at the TOP of ram, and set end_avail
-		 * to right after that.
-		 *
-		 * I should do something like this for prep, too and keep
-		 * a variable end_of_DRAM to keep track of what we think the
-		 * max ram is.
-		 * -- Cort
-		 */
-#if 0		
-		memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE),
-			(void *)initrd_start,
-			INITRD_SIZE );
-		initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE);
+		avail_ram = (char *)PAGE_ALIGN(
+			(unsigned long)zimage_size+(unsigned long)zimage_start);
+		memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE );
+		initrd_start = (unsigned long)avail_ram;
 		initrd_end = initrd_start + INITRD_SIZE;
-		end_avail = (char *)initrd_start;
 		puts("relocated to:  "); puthex(initrd_start);
 		puts(" "); puthex(initrd_end); puts("\n");
-#endif		
 	}
 
-#ifndef CONFIG_MBX
-	/* this is safe, just use it */
-	/* I don't know why it didn't work for me on the MBX with 20 MB
-	 * memory.  I guess something was saved up there, but I can't
-	 * figure it out......we are running on luck.  -- Dan.
-	 */
 	avail_ram = (char *)0x00400000;
-	end_avail = (char *)0x00600000;
-#endif
+	end_avail = (char *)0x00800000;
 	puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
 	puthex((unsigned long)end_avail); puts("\n");
 
-	
-#if !defined(CONFIG_MBX) && !defined(CONFIG_FADS)
+#if !defined(CONFIG_SERIAL_CONSOLE)
 	CRT_tstc();  /* Forces keyboard to be initialized */
 #endif
 
@@ -550,13 +475,6 @@
 						cp--;
 						puts("\b \b");
 					}
-#ifdef CONFIG_MBX
-				  } else if (ch == '?') {
-					if (!do_ipaddrs(&cp, 1)) {
-						  *cp++ = ch;
-						  putc(ch);
-					}
-#endif
 				} else {
 					*cp++ = ch;
 					putc(ch);
@@ -567,32 +485,6 @@
 		udelay(1000);  /* 1 msec */
 	}
 	*cp = 0;
-#ifdef CONFIG_MBX
-	/* The MBX does not currently have any default boot strategy.
-	 * If the command line is not filled in, we will automatically
-	 * create the default network boot.
-	 */
-	if (cmd_line[0] == 0) {
-		dp = root_string;
-		while (*dp != 0)
-			*cp++ = *dp++;
-		*cp++ = ' ';
-
-		dp = nfsaddrs_string;
-		while (*dp != 0)
-			*cp++ = *dp++;
-		dp = cp;
-		do_ipaddrs(&cp, 0);
-		*cp++ = ' ';
-
-		/* Add the server address to the root file system path.
-		*/
-		dp = strrchr(dp, ':');
-		dp++;
-		do_nfsroot(&cp, dp);
-		*cp = 0;
-	}
-#endif
 	puts("\n");
 
 	/* mappings on early boot can only handle 16M */
@@ -611,150 +503,6 @@
 	return (unsigned long)hold_residual;
 }
 
-#ifdef CONFIG_MBX
-int
-do_ipaddrs(char **cmd_cp, int echo)
-{
-	char	*cp, *ip, ch;
-	unsigned char	ipd;
-	int	i, j, retval;
-
-	/* We need to create the string:
-	 *	<my_ip>:<serv_ip>
-	 */
-	cp = *cmd_cp;
-	retval = 0;
-
-	if ((cp - 9) >= cmd_line) {
-		if (strncmp(cp - 9, "nfsaddrs=", 9) == 0) {
-			ip = (char *)0xfa000060;
-			retval = 1;
-			for (j=0; j<2; j++) {
-				for (i=0; i<4; i++) {
-					ipd = *ip++;
-
-					ch = ipd/100;
-					if (ch) {
-						ch += '0';
-						if (echo)
-							putc(ch);
-						*cp++ = ch;
-						ipd -= 100 * (ch - '0');
-					}
-
-					ch = ipd/10;
-					if (ch) {
-						ch += '0';
-						if (echo)
-							putc(ch);
-						*cp++ = ch;
-						ipd -= 10 * (ch - '0');
-					}
-
-					ch = ipd + '0';
-					if (echo)
-						putc(ch);
-					*cp++ = ch;
-
-					ch = '.';
-					if (echo)
-						putc(ch);
-					*cp++ = ch;
-				}
-
-				/* At the end of the string, remove the
-				 * '.' and replace it with a ':'.
-				 */
-				*(cp - 1) = ':';
-				if (echo) {
-					putc('\b'); putc(':');
-				}
-			}
-
-			/* At the end of the second string, remove the
-			 * '.' from both the command line and the
-			 * screen.
-			 */
-			--cp;
-			putc('\b'); putc(' '); putc('\b');
-		}
-	}
-	*cmd_cp = cp;
-	return(retval);
-}
-
-void
-do_nfsroot(char **cmd_cp, char *dp)
-{
-	char	*cp, *rp, *ep;
-
-	/* The boot argument (i.e /sys/mbxroot/zImage) is stored
-	 * at offset 0x0078 in NVRAM.  We use this path name to
-	 * construct the root file system path.
-	 */
-	cp = *cmd_cp;
-
-	/* build command string.
-	*/
-	rp = nfsroot_string;
-	while (*rp != 0)
-		*cp++ = *rp++;
-
-	/* Add the server address to the path.
-	*/
-	while (*dp != ' ')
-		*cp++ = *dp++;
-	*cp++ = ':';
-
-	rp = (char *)0xfa000078;
-	ep = strrchr(rp, '/');
-
-	if (ep != 0) {
-		while (rp < ep)
-			*cp++ = *rp++;
-	}
-	else {
-		rp = defroot_string;
-		while (*rp != 0)
-			*cp++ = *rp++;
-	}
-
-	*cmd_cp = cp;
-}
-
-size_t strlen(const char * s)
-{
-	const char *sc;
-
-	for (sc = s; *sc != '\0'; ++sc)
-		/* nothing */;
-	return sc - s;
-}
-
-int strncmp(const char * cs,const char * ct,size_t count)
-{
-	register signed char __res = 0;
-
-	while (count) {
-		if ((__res = *cs - *ct++) != 0 || !*cs++)
-			break;
-		count--;
-	}
-
-	return __res;
-}
-
-char * strrchr(const char * s, int c)
-{
-       const char *p = s + strlen(s);
-       do {
-           if (*p == (char)c)
-               return (char *)p;
-       } while (--p >= s);
-       return NULL;
-}
-#endif
-
 void puthex(unsigned long val)
 {
 	unsigned char buf[10];
@@ -801,4 +549,244 @@
 _bcopy(char *src, char *dst, int len)
 {
 	while (len--) *dst++ = *src++;
+}
+
+
+#define FALSE 0
+#define TRUE  1
+#include <stdarg.h>
+
+int
+strlen(char *s)
+{
+	int len = 0;
+	while (*s++) len++;
+	return len;
+}
+
+_printk(char const *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	va_start(ap, fmt);
+	ret = _vprintk(putc, fmt, ap);
+	va_end(ap);
+	return (ret);
+}
+
+#define is_digit(c) ((c >= '0') && (c <= '9'))
+
+int
+_vprintk(putc, fmt0, ap)
+int (*putc)();
+const char *fmt0;
+va_list ap;
+{
+	char c, sign, *cp;
+	int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
+	char buf[32];
+	long val;
+	while (c = *fmt0++)
+	{
+		if (c == '%')
+		{
+			c = *fmt0++;
+			left_prec = right_prec = pad_on_right = 0;
+			if (c == '-')
+			{
+				c = *fmt0++;
+				pad_on_right++;
+			}
+			if (c == '0')
+			{
+				zero_fill = TRUE;
+				c = *fmt0++;
+			} else
+			{
+				zero_fill = FALSE;
+			}
+			while (is_digit(c))
+			{
+				left_prec = (left_prec * 10) + (c - '0');
+				c = *fmt0++;
+			}
+			if (c == '.')
+			{
+				c = *fmt0++;
+				zero_fill++;
+				while (is_digit(c))
+				{
+					right_prec = (right_prec * 10) + (c - '0');
+					c = *fmt0++;
+				}
+			} else
+			{
+				right_prec = left_prec;
+			}
+			sign = '\0';
+			switch (c)
+			{
+			case 'd':
+			case 'x':
+			case 'X':
+				val = va_arg(ap, long);
+				switch (c)
+				{
+				case 'd':
+					if (val < 0)
+					{
+						sign = '-';
+						val = -val;
+					}
+					length = _cvt(val, buf, 10, "0123456789");
+					break;
+				case 'x':
+					length = _cvt(val, buf, 16, "0123456789abcdef");
+					break;
+				case 'X':
+					length = _cvt(val, buf, 16, "0123456789ABCDEF");
+					break;
+				}
+				cp = buf;
+				break;
+			case 's':
+				cp = va_arg(ap, char *);
+				length = strlen(cp);
+				break;
+			case 'c':
+				c = va_arg(ap, long /*char*/);
+				(*putc)(c);
+				continue;
+			default:
+				(*putc)('?');
+			}
+			pad = left_prec - length;
+			if (sign != '\0')
+			{
+				pad--;
+			}
+			if (zero_fill)
+			{
+				c = '0';
+				if (sign != '\0')
+				{
+					(*putc)(sign);
+					sign = '\0';
+				}
+			} else
+			{
+				c = ' ';
+			}
+			if (!pad_on_right)
+			{
+				while (pad-- > 0)
+				{
+					(*putc)(c);
+				}
+			}
+			if (sign != '\0')
+			{
+				(*putc)(sign);
+			}
+			while (length-- > 0)
+			{
+				(*putc)(c = *cp++);
+				if (c == '\n')
+				{
+					(*putc)('\r');
+				}
+			}
+			if (pad_on_right)
+			{
+				while (pad-- > 0)
+				{
+					(*putc)(c);
+				}
+			}
+		} else
+		{
+			(*putc)(c);
+			if (c == '\n')
+			{
+				(*putc)('\r');
+			}
+		}
+	}
+}
+
+int _cvt(unsigned long val, char *buf, long radix, char *digits)
+{
+	char temp[80];
+	char *cp = temp;
+	int length = 0;
+	if (val == 0)
+	{ /* Special case */
+		*cp++ = '0';
+	} else
+		while (val)
+		{
+			*cp++ = digits[val % radix];
+			val /= radix;
+		}
+	while (cp != temp)
+	{
+		*buf++ = *--cp;
+		length++;
+	}
+	*buf = '\0';
+	return (length);
+}
+
+_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
+{
+	int i, c;
+	if ((unsigned int)s > (unsigned int)p)
+	{
+		s = (unsigned int)s - (unsigned int)p;
+	}
+	while (s > 0)
+	{
+		if (base)
+		{
+			_printk("%06X: ", (int)p - (int)base);
+		} else
+		{
+			_printk("%06X: ", p);
+		}
+		for (i = 0;  i < 16;  i++)
+		{
+			if (i < s)
+			{
+				_printk("%02X", p[i] & 0xFF);
+			} else
+			{
+				_printk("  ");
+			}
+			if ((i % 2) == 1) _printk(" ");
+			if ((i % 8) == 7) _printk(" ");
+		}
+		_printk(" |");
+		for (i = 0;  i < 16;  i++)
+		{
+			if (i < s)
+			{
+				c = p[i] & 0xFF;
+				if ((c < 0x20) || (c >= 0x7F)) c = '.';
+			} else
+			{
+				c = ' ';
+			}
+			_printk("%c", c);
+		}
+		_printk("|\n");
+		s -= 16;
+		p += 16;
+	}
+}
+
+_dump_buf(unsigned char *p, int s)
+{
+	_printk("\n");
+	_dump_buf_with_offset(p, s, 0);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)