[klibc] Remove in-kernel root-mounting code

This removes the root mounting code from the kernel proper.  This
includes ip autoconfiguration, nfsroot, and name_to_dev_t().

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 08c00d2..cc79fa7 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -149,7 +149,6 @@
 
 extern void early_cpu_init(void);
 extern void generic_apic_probe(char *);
-extern int root_mountflags;
 
 unsigned long saved_videomode;
 
@@ -1469,11 +1468,6 @@
 	}
 	bootloader_type = LOADER_TYPE;
 
-#ifdef CONFIG_BLK_DEV_RAM
-	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
-	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
 	ARCH_SETUP
 	if (efi_enabled)
 		efi_init();
@@ -1484,8 +1478,6 @@
 
 	copy_edd();
 
-	if (!MOUNT_ROOT_RDONLY)
-		root_mountflags &= ~MS_RDONLY;
 	init_mm.start_code = (unsigned long) _text;
 	init_mm.end_code = (unsigned long) _etext;
 	init_mm.end_data = (unsigned long) _edata;
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 0925518..788735e 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -529,16 +529,9 @@
 	saved_video_mode = SAVED_VIDEO_MODE;
 	bootloader_type = LOADER_TYPE;
 
-#ifdef CONFIG_BLK_DEV_RAM
-	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
-	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
 	setup_memory_region();
 	copy_edd();
 
-	if (!MOUNT_ROOT_RDONLY)
-		root_mountflags &= ~MS_RDONLY;
 	init_mm.start_code = (unsigned long) &_text;
 	init_mm.end_code = (unsigned long) &_etext;
 	init_mm.end_data = (unsigned long) &_edata;
diff --git a/fs/Kconfig b/fs/Kconfig
index 53f5c6d..01f084e 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1567,20 +1567,6 @@
 	  TCP connections usually perform better than the default UDP when
 	  the network is lossy or congested.  If unsure, say Y.
 
-config ROOT_NFS
-	bool "Root file system on NFS"
-	depends on NFS_FS=y && IP_PNP
-	help
-	  If you want your Linux box to mount its whole root file system (the
-	  one containing the directory /) from some other computer over the
-	  net via NFS (presumably because your box doesn't have a hard disk),
-	  say Y. Read <file:Documentation/nfsroot.txt> for details. It is
-	  likely that in this case, you also want to say Y to "Kernel level IP
-	  autoconfiguration" so that your box can discover its network address
-	  at boot time.
-
-	  Most people say N here.
-
 config LOCKD
 	tristate
 
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 0b572a0..c7d6392 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -7,7 +7,6 @@
 nfs-y 			:= dir.o file.o inode.o super.o nfs2xdr.o pagelist.o \
 			   proc.o read.o symlink.o unlink.o write.o \
 			   namespace.o
-nfs-$(CONFIG_ROOT_NFS)	+= nfsroot.o mount_clnt.o      
 nfs-$(CONFIG_NFS_V3)	+= nfs3proc.o nfs3xdr.o
 nfs-$(CONFIG_NFS_V3_ACL)	+= nfs3acl.o
 nfs-$(CONFIG_NFS_V4)	+= nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
deleted file mode 100644
index 445abb4..0000000
--- a/fs/nfs/mount_clnt.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * linux/fs/nfs/mount_clnt.c
- *
- * MOUNT client to support NFSroot.
- *
- * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
- */
-
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/uio.h>
-#include <linux/net.h>
-#include <linux/in.h>
-#include <linux/sunrpc/clnt.h>
-#include <linux/sunrpc/xprt.h>
-#include <linux/sunrpc/sched.h>
-#include <linux/nfs_fs.h>
-
-#ifdef RPC_DEBUG
-# define NFSDBG_FACILITY	NFSDBG_ROOT
-#endif
-
-/*
-#define MOUNT_PROGRAM		100005
-#define MOUNT_VERSION		1
-#define MOUNT_MNT		1
-#define MOUNT_UMNT		3
- */
-
-static struct rpc_clnt *	mnt_create(char *, struct sockaddr_in *,
-								int, int);
-static struct rpc_program	mnt_program;
-
-struct mnt_fhstatus {
-	unsigned int		status;
-	struct nfs_fh *		fh;
-};
-
-/*
- * Obtain an NFS file handle for the given host and path
- */
-int
-nfsroot_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh,
-		int version, int protocol)
-{
-	struct rpc_clnt		*mnt_clnt;
-	struct mnt_fhstatus	result = {
-		.fh		= fh
-	};
-	struct rpc_message msg	= {
-		.rpc_argp	= path,
-		.rpc_resp	= &result,
-	};
-	char			hostname[32];
-	int			status;
-
-	dprintk("NFS:      nfs_mount(%08x:%s)\n",
-			(unsigned)ntohl(addr->sin_addr.s_addr), path);
-
-	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr));
-	mnt_clnt = mnt_create(hostname, addr, version, protocol);
-	if (IS_ERR(mnt_clnt))
-		return PTR_ERR(mnt_clnt);
-
-	if (version == NFS_MNT3_VERSION)
-		msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT];
-	else
-		msg.rpc_proc = &mnt_clnt->cl_procinfo[MNTPROC_MNT];
-
-	status = rpc_call_sync(mnt_clnt, &msg, 0);
-	return status < 0? status : (result.status? -EACCES : 0);
-}
-
-static struct rpc_clnt *
-mnt_create(char *hostname, struct sockaddr_in *srvaddr, int version,
-		int protocol)
-{
-	struct rpc_xprt	*xprt;
-	struct rpc_clnt	*clnt;
-
-	xprt = xprt_create_proto(protocol, srvaddr, NULL);
-	if (IS_ERR(xprt))
-		return (struct rpc_clnt *)xprt;
-
-	clnt = rpc_create_client(xprt, hostname,
-				&mnt_program, version,
-				RPC_AUTH_UNIX);
-	if (!IS_ERR(clnt)) {
-		clnt->cl_softrtry = 1;
-		clnt->cl_oneshot  = 1;
-		clnt->cl_intr = 1;
-	}
-	return clnt;
-}
-
-/*
- * XDR encode/decode functions for MOUNT
- */
-static int
-xdr_encode_dirpath(struct rpc_rqst *req, u32 *p, const char *path)
-{
-	p = xdr_encode_string(p, path);
-
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-	return 0;
-}
-
-static int
-xdr_decode_fhstatus(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
-{
-	struct nfs_fh *fh = res->fh;
-
-	if ((res->status = ntohl(*p++)) == 0) {
-		fh->size = NFS2_FHSIZE;
-		memcpy(fh->data, p, NFS2_FHSIZE);
-	}
-	return 0;
-}
-
-static int
-xdr_decode_fhstatus3(struct rpc_rqst *req, u32 *p, struct mnt_fhstatus *res)
-{
-	struct nfs_fh *fh = res->fh;
-
-	if ((res->status = ntohl(*p++)) == 0) {
-		int size = ntohl(*p++);
-		if (size <= NFS3_FHSIZE) {
-			fh->size = size;
-			memcpy(fh->data, p, size);
-		} else
-			res->status = -EBADHANDLE;
-	}
-	return 0;
-}
-
-#define MNT_dirpath_sz		(1 + 256)
-#define MNT_fhstatus_sz		(1 + 8)
-
-static struct rpc_procinfo	mnt_procedures[] = {
-[MNTPROC_MNT] = {
-	  .p_proc		= MNTPROC_MNT,
-	  .p_encode		= (kxdrproc_t) xdr_encode_dirpath,	
-	  .p_decode		= (kxdrproc_t) xdr_decode_fhstatus,
-	  .p_bufsiz		= MNT_dirpath_sz << 2,
-	  .p_statidx		= MNTPROC_MNT,
-	  .p_name		= "MOUNT",
-	},
-};
-
-static struct rpc_procinfo mnt3_procedures[] = {
-[MOUNTPROC3_MNT] = {
-	  .p_proc		= MOUNTPROC3_MNT,
-	  .p_encode		= (kxdrproc_t) xdr_encode_dirpath,
-	  .p_decode		= (kxdrproc_t) xdr_decode_fhstatus3,
-	  .p_bufsiz		= MNT_dirpath_sz << 2,
-	  .p_statidx		= MOUNTPROC3_MNT,
-	  .p_name		= "MOUNT",
-	},
-};
-
-
-static struct rpc_version	mnt_version1 = {
-		.number		= 1,
-		.nrprocs 	= 2,
-		.procs 		= mnt_procedures
-};
-
-static struct rpc_version       mnt_version3 = {
-		.number		= 3,
-		.nrprocs	= 2,
-		.procs		= mnt3_procedures
-};
-
-static struct rpc_version *	mnt_version[] = {
-	NULL,
-	&mnt_version1,
-	NULL,
-	&mnt_version3,
-};
-
-static struct rpc_stat		mnt_stats;
-
-static struct rpc_program	mnt_program = {
-	.name		= "mount",
-	.number		= NFS_MNT_PROGRAM,
-	.nrvers		= ARRAY_SIZE(mnt_version),
-	.version	= mnt_version,
-	.stats		= &mnt_stats,
-};
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
deleted file mode 100644
index c0a754e..0000000
--- a/fs/nfs/nfsroot.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- *  $Id: nfsroot.c,v 1.45 1998/03/07 10:44:46 mj Exp $
- *
- *  Copyright (C) 1995, 1996  Gero Kuhlmann <gero@gkminix.han.de>
- *
- *  Allow an NFS filesystem to be mounted as root. The way this works is:
- *     (1) Use the IP autoconfig mechanism to set local IP addresses and routes.
- *     (2) Handle RPC negotiation with the system which replied to RARP or
- *         was reported as a boot server by BOOTP or manually.
- *     (3) The actual mounting is done later, when init() is running.
- *
- *
- *	Changes:
- *
- *	Alan Cox	:	Removed get_address name clash with FPU.
- *	Alan Cox	:	Reformatted a bit.
- *	Gero Kuhlmann	:	Code cleanup
- *	Michael Rausch  :	Fixed recognition of an incoming RARP answer.
- *	Martin Mares	: (2.0)	Auto-configuration via BOOTP supported.
- *	Martin Mares	:	Manual selection of interface & BOOTP/RARP.
- *	Martin Mares	:	Using network routes instead of host routes,
- *				allowing the default configuration to be used
- *				for normal operation of the host.
- *	Martin Mares	:	Randomized timer with exponential backoff
- *				installed to minimize network congestion.
- *	Martin Mares	:	Code cleanup.
- *	Martin Mares	: (2.1)	BOOTP and RARP made configuration options.
- *	Martin Mares	:	Server hostname generation fixed.
- *	Gerd Knorr	:	Fixed wired inode handling
- *	Martin Mares	: (2.2)	"0.0.0.0" addresses from command line ignored.
- *	Martin Mares	:	RARP replies not tested for server address.
- *	Gero Kuhlmann	: (2.3) Some bug fixes and code cleanup again (please
- *				send me your new patches _before_ bothering
- *				Linus so that I don' always have to cleanup
- *				_afterwards_ - thanks)
- *	Gero Kuhlmann	:	Last changes of Martin Mares undone.
- *	Gero Kuhlmann	: 	RARP replies are tested for specified server
- *				again. However, it's now possible to have
- *				different RARP and NFS servers.
- *	Gero Kuhlmann	:	"0.0.0.0" addresses from command line are
- *				now mapped to INADDR_NONE.
- *	Gero Kuhlmann	:	Fixed a bug which prevented BOOTP path name
- *				from being used (thanks to Leo Spiekman)
- *	Andy Walker	:	Allow to specify the NFS server in nfs_root
- *				without giving a path name
- *	Swen Thümmler	:	Allow to specify the NFS options in nfs_root
- *				without giving a path name. Fix BOOTP request
- *				for domainname (domainname is NIS domain, not
- *				DNS domain!). Skip dummy devices for BOOTP.
- *	Jacek Zapala	:	Fixed a bug which prevented server-ip address
- *				from nfsroot parameter from being used.
- *	Olaf Kirch	:	Adapted to new NFS code.
- *	Jakub Jelinek	:	Free used code segment.
- *	Marko Kohtala	:	Fixed some bugs.
- *	Martin Mares	:	Debug message cleanup
- *	Martin Mares	:	Changed to use the new generic IP layer autoconfig
- *				code. BOOTP and RARP moved there.
- *	Martin Mares	:	Default path now contains host name instead of
- *				host IP address (but host name defaults to IP
- *				address anyway).
- *	Martin Mares	:	Use root_server_addr appropriately during setup.
- *	Martin Mares	:	Rewrote parameter parsing, now hopefully giving
- *				correct overriding.
- *	Trond Myklebust :	Add in preliminary support for NFSv3 and TCP.
- *				Fix bug in root_nfs_addr(). nfs_data.namlen
- *				is NOT for the length of the hostname.
- *	Hua Qin		:	Support for mounting root file system via
- *				NFS over TCP.
- *	Fabian Frederick:	Option parser rebuilt (using parser lib)
-*/
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/sunrpc/clnt.h>
-#include <linux/nfs.h>
-#include <linux/nfs_fs.h>
-#include <linux/nfs_mount.h>
-#include <linux/in.h>
-#include <linux/major.h>
-#include <linux/utsname.h>
-#include <linux/inet.h>
-#include <linux/root_dev.h>
-#include <net/ipconfig.h>
-#include <linux/parser.h>
-
-/* Define this to allow debugging output */
-#undef NFSROOT_DEBUG
-#define NFSDBG_FACILITY NFSDBG_ROOT
-
-/* Default path we try to mount. "%s" gets replaced by our IP address */
-#define NFS_ROOT		"/tftpboot/%s"
-
-/* Parameters passed from the kernel command line */
-static char nfs_root_name[256] __initdata = "";
-
-/* Address of NFS server */
-static __u32 servaddr __initdata = 0;
-
-/* Name of directory to mount */
-static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, };
-
-/* NFS-related data */
-static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */
-static int nfs_port __initdata = 0;		/* Port to connect to for NFS */
-static int mount_port __initdata = 0;		/* Mount daemon port number */
-
-
-/***************************************************************************
-
-			     Parsing of options
-
- ***************************************************************************/
-
-enum {
-	/* Options that take integer arguments */
-	Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
-	Opt_acregmax, Opt_acdirmin, Opt_acdirmax,
-	/* Options that take no arguments */
-	Opt_soft, Opt_hard, Opt_intr,
-	Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, 
-	Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
-	Opt_acl, Opt_noacl,
-	/* Error token */
-	Opt_err
-};
-
-static match_table_t __initdata tokens = {
-	{Opt_port, "port=%u"},
-	{Opt_rsize, "rsize=%u"},
-	{Opt_wsize, "wsize=%u"},
-	{Opt_timeo, "timeo=%u"},
-	{Opt_retrans, "retrans=%u"},
-	{Opt_acregmin, "acregmin=%u"},
-	{Opt_acregmax, "acregmax=%u"},
-	{Opt_acdirmin, "acdirmin=%u"},
-	{Opt_acdirmax, "acdirmax=%u"},
-	{Opt_soft, "soft"},
-	{Opt_hard, "hard"},
-	{Opt_intr, "intr"},
-	{Opt_nointr, "nointr"},
-	{Opt_posix, "posix"},
-	{Opt_noposix, "noposix"},
-	{Opt_cto, "cto"},
-	{Opt_nocto, "nocto"},
-	{Opt_ac, "ac"},
-	{Opt_noac, "noac"},
-	{Opt_lock, "lock"},
-	{Opt_nolock, "nolock"},
-	{Opt_v2, "nfsvers=2"},
-	{Opt_v2, "v2"},
-	{Opt_v3, "nfsvers=3"},
-	{Opt_v3, "v3"},
-	{Opt_udp, "proto=udp"},
-	{Opt_udp, "udp"},
-	{Opt_tcp, "proto=tcp"},
-	{Opt_tcp, "tcp"},
-	{Opt_acl, "acl"},
-	{Opt_noacl, "noacl"},
-	{Opt_err, NULL}
-	
-};
-
-/*
- *  Parse option string.
- */
-
-static int __init root_nfs_parse(char *name, char *buf)
-{
-
-	char *p;
-	substring_t args[MAX_OPT_ARGS];
-	int option;
-
-	if (!name)
-		return 1;
-
-	/* Set the NFS remote path */
-	p = strsep(&name, ",");
-	if (p[0] != '\0' && strcmp(p, "default") != 0)
-		strlcpy(buf, p, NFS_MAXPATHLEN);
-
-	while ((p = strsep (&name, ",")) != NULL) {
-		int token; 
-		if (!*p)
-			continue;
-		token = match_token(p, tokens, args);
-
-		/* %u tokens only. Beware if you add new tokens! */
-		if (token < Opt_soft && match_int(&args[0], &option))
-			return 0;
-		switch (token) {
-			case Opt_port:
-				nfs_port = option;
-				break;
-			case Opt_rsize:
-				nfs_data.rsize = option;
-				break;
-			case Opt_wsize:
-				nfs_data.wsize = option;
-				break;
-			case Opt_timeo:
-				nfs_data.timeo = option;
-				break;
-			case Opt_retrans:
-				nfs_data.retrans = option;
-				break;
-			case Opt_acregmin:
-				nfs_data.acregmin = option;
-				break;
-			case Opt_acregmax:
-				nfs_data.acregmax = option;
-				break;
-			case Opt_acdirmin:
-				nfs_data.acdirmin = option;
-				break;
-			case Opt_acdirmax:
-				nfs_data.acdirmax = option;
-				break;
-			case Opt_soft:
-				nfs_data.flags |= NFS_MOUNT_SOFT;
-				break;
-			case Opt_hard:
-				nfs_data.flags &= ~NFS_MOUNT_SOFT;
-				break;
-			case Opt_intr:
-				nfs_data.flags |= NFS_MOUNT_INTR;
-				break;
-			case Opt_nointr:
-				nfs_data.flags &= ~NFS_MOUNT_INTR;
-				break;
-			case Opt_posix:
-				nfs_data.flags |= NFS_MOUNT_POSIX;
-				break;
-			case Opt_noposix:
-				nfs_data.flags &= ~NFS_MOUNT_POSIX;
-				break;
-			case Opt_cto:
-				nfs_data.flags &= ~NFS_MOUNT_NOCTO;
-				break;
-			case Opt_nocto:
-				nfs_data.flags |= NFS_MOUNT_NOCTO;
-				break;
-			case Opt_ac:
-				nfs_data.flags &= ~NFS_MOUNT_NOAC;
-				break;
-			case Opt_noac:
-				nfs_data.flags |= NFS_MOUNT_NOAC;
-				break;
-			case Opt_lock:
-				nfs_data.flags &= ~NFS_MOUNT_NONLM;
-				break;
-			case Opt_nolock:
-				nfs_data.flags |= NFS_MOUNT_NONLM;
-				break;
-			case Opt_v2:
-				nfs_data.flags &= ~NFS_MOUNT_VER3;
-				break;
-			case Opt_v3:
-				nfs_data.flags |= NFS_MOUNT_VER3;
-				break;
-			case Opt_udp:
-				nfs_data.flags &= ~NFS_MOUNT_TCP;
-				break;
-			case Opt_tcp:
-				nfs_data.flags |= NFS_MOUNT_TCP;
-				break;
-			case Opt_acl:
-				nfs_data.flags &= ~NFS_MOUNT_NOACL;
-				break;
-			case Opt_noacl:
-				nfs_data.flags |= NFS_MOUNT_NOACL;
-				break;
-			default:
-				printk(KERN_WARNING "Root-NFS: unknown "
-					"option: %s\n", p);
-				return 0;
-		}
-	}
-
-	return 1;
-}
-
-/*
- *  Prepare the NFS data structure and parse all options.
- */
-static int __init root_nfs_name(char *name)
-{
-	static char buf[NFS_MAXPATHLEN] __initdata;
-	char *cp;
-
-	/* Set some default values */
-	memset(&nfs_data, 0, sizeof(nfs_data));
-	nfs_port          = -1;
-	nfs_data.version  = NFS_MOUNT_VERSION;
-	nfs_data.flags    = NFS_MOUNT_NONLM;	/* No lockd in nfs root yet */
-	nfs_data.rsize    = NFS_DEF_FILE_IO_SIZE;
-	nfs_data.wsize    = NFS_DEF_FILE_IO_SIZE;
-	nfs_data.acregmin = 3;
-	nfs_data.acregmax = 60;
-	nfs_data.acdirmin = 30;
-	nfs_data.acdirmax = 60;
-	strcpy(buf, NFS_ROOT);
-
-	/* Process options received from the remote server */
-	root_nfs_parse(root_server_path, buf);
-
-	/* Override them by options set on kernel command-line */
-	root_nfs_parse(name, buf);
-
-	cp = system_utsname.nodename;
-	if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
-		printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
-		return -1;
-	}
-	sprintf(nfs_path, buf, cp);
-
-	return 1;
-}
-
-
-/*
- *  Get NFS server address.
- */
-static int __init root_nfs_addr(void)
-{
-	if ((servaddr = root_server_addr) == INADDR_NONE) {
-		printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n");
-		return -1;
-	}
-
-	snprintf(nfs_data.hostname, sizeof(nfs_data.hostname),
-		 "%u.%u.%u.%u", NIPQUAD(servaddr));
-	return 0;
-}
-
-/*
- *  Tell the user what's going on.
- */
-#ifdef NFSROOT_DEBUG
-static void __init root_nfs_print(void)
-{
-	printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n",
-		nfs_path, nfs_data.hostname);
-	printk(KERN_NOTICE "Root-NFS:     rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
-		nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
-	printk(KERN_NOTICE "Root-NFS:     acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
-		nfs_data.acregmin, nfs_data.acregmax,
-		nfs_data.acdirmin, nfs_data.acdirmax);
-	printk(KERN_NOTICE "Root-NFS:     nfsd port = %d, mountd port = %d, flags = %08x\n",
-		nfs_port, mount_port, nfs_data.flags);
-}
-#endif
-
-
-static int __init root_nfs_init(void)
-{
-#ifdef NFSROOT_DEBUG
-	nfs_debug |= NFSDBG_ROOT;
-#endif
-
-	/*
-	 * Decode the root directory path name and NFS options from
-	 * the kernel command line. This has to go here in order to
-	 * be able to use the client IP address for the remote root
-	 * directory (necessary for pure RARP booting).
-	 */
-	if (root_nfs_name(nfs_root_name) < 0 ||
-	    root_nfs_addr() < 0)
-		return -1;
-
-#ifdef NFSROOT_DEBUG
-	root_nfs_print();
-#endif
-
-	return 0;
-}
-
-
-/*
- *  Parse NFS server and directory information passed on the kernel
- *  command line.
- */
-static int __init nfs_root_setup(char *line)
-{
-	ROOT_DEV = Root_NFS;
-	if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
-		strlcpy(nfs_root_name, line, sizeof(nfs_root_name));
-	} else {
-		int n = strlen(line) + sizeof(NFS_ROOT) - 1;
-		if (n >= sizeof(nfs_root_name))
-			line[sizeof(nfs_root_name) - sizeof(NFS_ROOT) - 2] = '\0';
-		sprintf(nfs_root_name, NFS_ROOT, line);
-	}
-	root_server_addr = root_nfs_parse_addr(nfs_root_name);
-	return 1;
-}
-
-__setup("nfsroot=", nfs_root_setup);
-
-/***************************************************************************
-
-	       Routines to actually mount the root directory
-
- ***************************************************************************/
-
-/*
- *  Construct sockaddr_in from address and port number.
- */
-static inline void
-set_sockaddr(struct sockaddr_in *sin, __u32 addr, __u16 port)
-{
-	sin->sin_family = AF_INET;
-	sin->sin_addr.s_addr = addr;
-	sin->sin_port = port;
-}
-
-/*
- *  Query server portmapper for the port of a daemon program.
- */
-static int __init root_nfs_getport(int program, int version, int proto)
-{
-	struct sockaddr_in sin;
-
-	printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n",
-		program, version, NIPQUAD(servaddr));
-	set_sockaddr(&sin, servaddr, 0);
-	return rpc_getport_external(&sin, program, version, proto);
-}
-
-
-/*
- *  Use portmapper to find mountd and nfsd port numbers if not overriden
- *  by the user. Use defaults if portmapper is not available.
- *  XXX: Is there any nfs server with no portmapper?
- */
-static int __init root_nfs_ports(void)
-{
-	int port;
-	int nfsd_ver, mountd_ver;
-	int nfsd_port, mountd_port;
-	int proto;
-
-	if (nfs_data.flags & NFS_MOUNT_VER3) {
-		nfsd_ver = NFS3_VERSION;
-		mountd_ver = NFS_MNT3_VERSION;
-		nfsd_port = NFS_PORT;
-		mountd_port = NFS_MNT_PORT;
-	} else {
-		nfsd_ver = NFS2_VERSION;
-		mountd_ver = NFS_MNT_VERSION;
-		nfsd_port = NFS_PORT;
-		mountd_port = NFS_MNT_PORT;
-	}
-
-	proto = (nfs_data.flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
-
-	if (nfs_port < 0) {
-		if ((port = root_nfs_getport(NFS_PROGRAM, nfsd_ver, proto)) < 0) {
-			printk(KERN_ERR "Root-NFS: Unable to get nfsd port "
-					"number from server, using default\n");
-			port = nfsd_port;
-		}
-		nfs_port = port;
-		dprintk("Root-NFS: Portmapper on server returned %d "
-			"as nfsd port\n", port);
-	}
-	nfs_port = htons(nfs_port);
-
-	if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) {
-		printk(KERN_ERR "Root-NFS: Unable to get mountd port "
-				"number from server, using default\n");
-		port = mountd_port;
-	}
-	mount_port = htons(port);
-	dprintk("Root-NFS: mountd port is %d\n", port);
-
-	return 0;
-}
-
-
-/*
- *  Get a file handle from the server for the directory which is to be
- *  mounted.
- */
-static int __init root_nfs_get_handle(void)
-{
-	struct nfs_fh fh;
-	struct sockaddr_in sin;
-	int status;
-	int protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
-					IPPROTO_TCP : IPPROTO_UDP;
-	int version = (nfs_data.flags & NFS_MOUNT_VER3) ?
-					NFS_MNT3_VERSION : NFS_MNT_VERSION;
-
-	set_sockaddr(&sin, servaddr, mount_port);
-	status = nfsroot_mount(&sin, nfs_path, &fh, version, protocol);
-	if (status < 0)
-		printk(KERN_ERR "Root-NFS: Server returned error %d "
-				"while mounting %s\n", status, nfs_path);
-	else {
-		nfs_data.root.size = fh.size;
-		memcpy(nfs_data.root.data, fh.data, fh.size);
-	}
-
-	return status;
-}
-
-/*
- *  Get the NFS port numbers and file handle, and return the prepared 'data'
- *  argument for mount() if everything went OK. Return NULL otherwise.
- */
-void * __init nfs_root_data(void)
-{
-	if (root_nfs_init() < 0
-	 || root_nfs_ports() < 0
-	 || root_nfs_get_handle() < 0)
-		return NULL;
-	set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port);
-	return (void*)&nfs_data;
-}
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 403d1a9..ef5908e 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -94,7 +94,6 @@
 extern void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts);
 
 extern spinlock_t vfsmount_lock;
-extern dev_t name_to_dev_t(char *name);
 
 #endif
 #endif /* _LINUX_MOUNT_H */
diff --git a/init/Makefile b/init/Makefile
index 633a268..acfdb2c 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -2,14 +2,9 @@
 # Makefile for the linux kernel.
 #
 
-obj-y				:= main.o version.o mounts.o initramfs.o
+obj-y				:= main.o version.o initramfs.o
 obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
 
-mounts-y			:= do_mounts.o
-mounts-$(CONFIG_BLK_DEV_RAM)	+= do_mounts_rd.o
-mounts-$(CONFIG_BLK_DEV_INITRD)	+= do_mounts_initrd.o
-mounts-$(CONFIG_BLK_DEV_MD)	+= do_mounts_md.o
-
 # files to be removed upon make clean
 clean-files := ../include/linux/compile.h
 
diff --git a/init/do_mounts.c b/init/do_mounts.c
deleted file mode 100644
index 94aeec7..0000000
--- a/init/do_mounts.c
+++ /dev/null
@@ -1,433 +0,0 @@
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/ctype.h>
-#include <linux/fd.h>
-#include <linux/tty.h>
-#include <linux/suspend.h>
-#include <linux/root_dev.h>
-#include <linux/security.h>
-#include <linux/delay.h>
-#include <linux/mount.h>
-
-#include <linux/nfs_fs.h>
-#include <linux/nfs_fs_sb.h>
-#include <linux/nfs_mount.h>
-
-#include "do_mounts.h"
-
-extern int get_filesystem_list(char * buf);
-
-int __initdata rd_doload;	/* 1 = load RAM disk, 0 = don't load */
-
-int root_mountflags = MS_RDONLY | MS_SILENT;
-char * __initdata root_device_name;
-static char __initdata saved_root_name[64];
-
-dev_t ROOT_DEV;
-
-static int __init load_ramdisk(char *str)
-{
-	rd_doload = simple_strtol(str,NULL,0) & 3;
-	return 1;
-}
-__setup("load_ramdisk=", load_ramdisk);
-
-static int __init readonly(char *str)
-{
-	if (*str)
-		return 0;
-	root_mountflags |= MS_RDONLY;
-	return 1;
-}
-
-static int __init readwrite(char *str)
-{
-	if (*str)
-		return 0;
-	root_mountflags &= ~MS_RDONLY;
-	return 1;
-}
-
-__setup("ro", readonly);
-__setup("rw", readwrite);
-
-static dev_t try_name(char *name, int part)
-{
-	char path[64];
-	char buf[32];
-	int range;
-	dev_t res;
-	char *s;
-	int len;
-	int fd;
-	unsigned int maj, min;
-
-	/* read device number from .../dev */
-
-	sprintf(path, "/sys/block/%s/dev", name);
-	fd = sys_open(path, 0, 0);
-	if (fd < 0)
-		goto fail;
-	len = sys_read(fd, buf, 32);
-	sys_close(fd);
-	if (len <= 0 || len == 32 || buf[len - 1] != '\n')
-		goto fail;
-	buf[len - 1] = '\0';
-	if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
-		/*
-		 * Try the %u:%u format -- see print_dev_t()
-		 */
-		res = MKDEV(maj, min);
-		if (maj != MAJOR(res) || min != MINOR(res))
-			goto fail;
-	} else {
-		/*
-		 * Nope.  Try old-style "0321"
-		 */
-		res = new_decode_dev(simple_strtoul(buf, &s, 16));
-		if (*s)
-			goto fail;
-	}
-
-	/* if it's there and we are not looking for a partition - that's it */
-	if (!part)
-		return res;
-
-	/* otherwise read range from .../range */
-	sprintf(path, "/sys/block/%s/range", name);
-	fd = sys_open(path, 0, 0);
-	if (fd < 0)
-		goto fail;
-	len = sys_read(fd, buf, 32);
-	sys_close(fd);
-	if (len <= 0 || len == 32 || buf[len - 1] != '\n')
-		goto fail;
-	buf[len - 1] = '\0';
-	range = simple_strtoul(buf, &s, 10);
-	if (*s)
-		goto fail;
-
-	/* if partition is within range - we got it */
-	if (part < range)
-		return res + part;
-fail:
-	return 0;
-}
-
-/*
- *	Convert a name into device number.  We accept the following variants:
- *
- *	1) device number in hexadecimal	represents itself
- *	2) /dev/nfs represents Root_NFS (0xff)
- *	3) /dev/<disk_name> represents the device number of disk
- *	4) /dev/<disk_name><decimal> represents the device number
- *         of partition - device number of disk plus the partition number
- *	5) /dev/<disk_name>p<decimal> - same as the above, that form is
- *	   used when disk name of partitioned disk ends on a digit.
- *
- *	If name doesn't have fall into the categories above, we return 0.
- *	Sysfs is used to check if something is a disk name - it has
- *	all known disks under bus/block/devices.  If the disk name
- *	contains slashes, name of sysfs node has them replaced with
- *	bangs.  try_name() does the actual checks, assuming that sysfs
- *	is mounted on rootfs /sys.
- */
-
-dev_t name_to_dev_t(char *name)
-{
-	char s[32];
-	char *p;
-	dev_t res = 0;
-	int part;
-
-#ifdef CONFIG_SYSFS
-	int mkdir_err = sys_mkdir("/sys", 0700);
-	if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
-		goto out;
-#endif
-
-	if (strncmp(name, "/dev/", 5) != 0) {
-		unsigned maj, min;
-
-		if (sscanf(name, "%u:%u", &maj, &min) == 2) {
-			res = MKDEV(maj, min);
-			if (maj != MAJOR(res) || min != MINOR(res))
-				goto fail;
-		} else {
-			res = new_decode_dev(simple_strtoul(name, &p, 16));
-			if (*p)
-				goto fail;
-		}
-		goto done;
-	}
-	name += 5;
-	res = Root_NFS;
-	if (strcmp(name, "nfs") == 0)
-		goto done;
-	res = Root_RAM0;
-	if (strcmp(name, "ram") == 0)
-		goto done;
-
-	if (strlen(name) > 31)
-		goto fail;
-	strcpy(s, name);
-	for (p = s; *p; p++)
-		if (*p == '/')
-			*p = '!';
-	res = try_name(s, 0);
-	if (res)
-		goto done;
-
-	while (p > s && isdigit(p[-1]))
-		p--;
-	if (p == s || !*p || *p == '0')
-		goto fail;
-	part = simple_strtoul(p, NULL, 10);
-	*p = '\0';
-	res = try_name(s, part);
-	if (res)
-		goto done;
-
-	if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
-		goto fail;
-	p[-1] = '\0';
-	res = try_name(s, part);
-done:
-#ifdef CONFIG_SYSFS
-	sys_umount("/sys", 0);
-out:
-	if (!mkdir_err)
-		sys_rmdir("/sys");
-#endif
-	return res;
-fail:
-	res = 0;
-	goto done;
-}
-
-static int __init root_dev_setup(char *line)
-{
-	strlcpy(saved_root_name, line, sizeof(saved_root_name));
-	return 1;
-}
-
-__setup("root=", root_dev_setup);
-
-static char * __initdata root_mount_data;
-static int __init root_data_setup(char *str)
-{
-	root_mount_data = str;
-	return 1;
-}
-
-static char * __initdata root_fs_names;
-static int __init fs_names_setup(char *str)
-{
-	root_fs_names = str;
-	return 1;
-}
-
-static unsigned int __initdata root_delay;
-static int __init root_delay_setup(char *str)
-{
-	root_delay = simple_strtoul(str, NULL, 0);
-	return 1;
-}
-
-__setup("rootflags=", root_data_setup);
-__setup("rootfstype=", fs_names_setup);
-__setup("rootdelay=", root_delay_setup);
-
-static void __init get_fs_names(char *page)
-{
-	char *s = page;
-
-	if (root_fs_names) {
-		strcpy(page, root_fs_names);
-		while (*s++) {
-			if (s[-1] == ',')
-				s[-1] = '\0';
-		}
-	} else {
-		int len = get_filesystem_list(page);
-		char *p, *next;
-
-		page[len] = '\0';
-		for (p = page-1; p; p = next) {
-			next = strchr(++p, '\n');
-			if (*p++ != '\t')
-				continue;
-			while ((*s++ = *p++) != '\n')
-				;
-			s[-1] = '\0';
-		}
-	}
-	*s = '\0';
-}
-
-static int __init do_mount_root(char *name, char *fs, int flags, void *data)
-{
-	int err = sys_mount(name, "/root", fs, flags, data);
-	if (err)
-		return err;
-
-	sys_chdir("/root");
-	ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
-	printk("VFS: Mounted root (%s filesystem)%s.\n",
-	       current->fs->pwdmnt->mnt_sb->s_type->name,
-	       current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? 
-	       " readonly" : "");
-	return 0;
-}
-
-void __init mount_block_root(char *name, int flags)
-{
-	char *fs_names = __getname();
-	char *p;
-	char b[BDEVNAME_SIZE];
-
-	get_fs_names(fs_names);
-retry:
-	for (p = fs_names; *p; p += strlen(p)+1) {
-		int err = do_mount_root(name, p, flags, root_mount_data);
-		switch (err) {
-			case 0:
-				goto out;
-			case -EACCES:
-				flags |= MS_RDONLY;
-				goto retry;
-			case -EINVAL:
-				continue;
-		}
-	        /*
-		 * Allow the user to distinguish between failed sys_open
-		 * and bad superblock on root device.
-		 */
-		__bdevname(ROOT_DEV, b);
-		printk("VFS: Cannot open root device \"%s\" or %s\n",
-				root_device_name, b);
-		printk("Please append a correct \"root=\" boot option\n");
-
-		panic("VFS: Unable to mount root fs on %s", b);
-	}
-
-	printk("No filesystem could mount root, tried: ");
-	for (p = fs_names; *p; p += strlen(p)+1)
-		printk(" %s", p);
-	printk("\n");
-	panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b));
-out:
-	putname(fs_names);
-}
- 
-#ifdef CONFIG_ROOT_NFS
-static int __init mount_nfs_root(void)
-{
-	void *data = nfs_root_data();
-
-	create_dev("/dev/root", ROOT_DEV);
-	if (data &&
-	    do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
-		return 1;
-	return 0;
-}
-#endif
-
-#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
-void __init change_floppy(char *fmt, ...)
-{
-	struct termios termios;
-	char buf[80];
-	char c;
-	int fd;
-	va_list args;
-	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
-	va_end(args);
-	fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
-	if (fd >= 0) {
-		sys_ioctl(fd, FDEJECT, 0);
-		sys_close(fd);
-	}
-	printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
-	fd = sys_open("/dev/console", O_RDWR, 0);
-	if (fd >= 0) {
-		sys_ioctl(fd, TCGETS, (long)&termios);
-		termios.c_lflag &= ~ICANON;
-		sys_ioctl(fd, TCSETSF, (long)&termios);
-		sys_read(fd, &c, 1);
-		termios.c_lflag |= ICANON;
-		sys_ioctl(fd, TCSETSF, (long)&termios);
-		sys_close(fd);
-	}
-}
-#endif
-
-void __init mount_root(void)
-{
-#ifdef CONFIG_ROOT_NFS
-	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
-		if (mount_nfs_root())
-			return;
-
-		printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
-		ROOT_DEV = Root_FD0;
-	}
-#endif
-#ifdef CONFIG_BLK_DEV_FD
-	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
-		/* rd_doload is 2 for a dual initrd/ramload setup */
-		if (rd_doload==2) {
-			if (rd_load_disk(1)) {
-				ROOT_DEV = Root_RAM1;
-				root_device_name = NULL;
-			}
-		} else
-			change_floppy("root floppy");
-	}
-#endif
-	create_dev("/dev/root", ROOT_DEV);
-	mount_block_root("/dev/root", root_mountflags);
-}
-
-/*
- * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
- */
-void __init prepare_namespace(void)
-{
-	int is_floppy;
-
-	if (root_delay) {
-		printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
-		       root_delay);
-		ssleep(root_delay);
-	}
-
-	md_run_setup();
-
-	if (saved_root_name[0]) {
-		root_device_name = saved_root_name;
-		if (!strncmp(root_device_name, "mtd", 3)) {
-			mount_block_root(root_device_name, root_mountflags);
-			goto out;
-		}
-		ROOT_DEV = name_to_dev_t(root_device_name);
-		if (strncmp(root_device_name, "/dev/", 5) == 0)
-			root_device_name += 5;
-	}
-
-	is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
-
-	if (initrd_load())
-		goto out;
-
-	if (is_floppy && rd_doload && rd_load_disk(0))
-		ROOT_DEV = Root_RAM0;
-
-	mount_root();
-out:
-	sys_mount(".", "/", NULL, MS_MOVE, NULL);
-	sys_chroot(".");
-	security_sb_post_mountroot();
-}
-
diff --git a/init/do_mounts.h b/init/do_mounts.h
deleted file mode 100644
index e7f2e7f..0000000
--- a/init/do_mounts.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/syscalls.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/mount.h>
-#include <linux/major.h>
-#include <linux/root_dev.h>
-
-void  change_floppy(char *fmt, ...);
-void  mount_block_root(char *name, int flags);
-void  mount_root(void);
-extern int root_mountflags;
-extern char *root_device_name;
-
-static inline int create_dev(char *name, dev_t dev)
-{
-	sys_unlink(name);
-	return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
-}
-
-#if BITS_PER_LONG == 32
-static inline u32 bstat(char *name)
-{
-	struct stat64 stat;
-	if (sys_stat64(name, &stat) != 0)
-		return 0;
-	if (!S_ISBLK(stat.st_mode))
-		return 0;
-	if (stat.st_rdev != (u32)stat.st_rdev)
-		return 0;
-	return stat.st_rdev;
-}
-#else
-static inline u32 bstat(char *name)
-{
-	struct stat stat;
-	if (sys_newstat(name, &stat) != 0)
-		return 0;
-	if (!S_ISBLK(stat.st_mode))
-		return 0;
-	return stat.st_rdev;
-}
-#endif
-
-#ifdef CONFIG_BLK_DEV_RAM
-
-int __init rd_load_disk(int n);
-int __init rd_load_image(char *from);
-
-#else
-
-static inline int rd_load_disk(int n) { return 0; }
-static inline int rd_load_image(char *from) { return 0; }
-
-#endif
-
-#ifdef CONFIG_BLK_DEV_INITRD
-
-int __init initrd_load(void);
-
-#else
-
-static inline int initrd_load(void) { return 0; }
-
-#endif
-
-#ifdef CONFIG_BLK_DEV_MD
-
-void md_run_setup(void);
-
-#else
-
-static inline void md_run_setup(void) {}
-
-#endif
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
deleted file mode 100644
index a06f037..0000000
--- a/init/do_mounts_initrd.c
+++ /dev/null
@@ -1,123 +0,0 @@
-#define __KERNEL_SYSCALLS__
-#include <linux/unistd.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/romfs_fs.h>
-#include <linux/initrd.h>
-#include <linux/sched.h>
-
-#include "do_mounts.h"
-
-unsigned long initrd_start, initrd_end;
-int initrd_below_start_ok;
-unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
-static int __initdata old_fd, root_fd;
-static int __initdata mount_initrd = 1;
-
-static int __init no_initrd(char *str)
-{
-	mount_initrd = 0;
-	return 1;
-}
-
-__setup("noinitrd", no_initrd);
-
-static int __init do_linuxrc(void * shell)
-{
-	static char *argv[] = { "linuxrc", NULL, };
-	extern char * envp_init[];
-
-	sys_close(old_fd);sys_close(root_fd);
-	sys_close(0);sys_close(1);sys_close(2);
-	sys_setsid();
-	(void) sys_open("/dev/console",O_RDWR,0);
-	(void) sys_dup(0);
-	(void) sys_dup(0);
-	return execve(shell, argv, envp_init);
-}
-
-static void __init handle_initrd(void)
-{
-	int error;
-	int pid;
-
-	real_root_dev = new_encode_dev(ROOT_DEV);
-	create_dev("/dev/root.old", Root_RAM0);
-	/* mount initrd on rootfs' /root */
-	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
-	sys_mkdir("/old", 0700);
-	root_fd = sys_open("/", 0, 0);
-	old_fd = sys_open("/old", 0, 0);
-	/* move initrd over / and chdir/chroot in initrd root */
-	sys_chdir("/root");
-	sys_mount(".", "/", NULL, MS_MOVE, NULL);
-	sys_chroot(".");
-
-	current->flags |= PF_NOFREEZE;
-	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
-	if (pid > 0) {
-		while (pid != sys_wait4(-1, NULL, 0, NULL))
-			yield();
-	}
-
-	/* move initrd to rootfs' /old */
-	sys_fchdir(old_fd);
-	sys_mount("/", ".", NULL, MS_MOVE, NULL);
-	/* switch root and cwd back to / of rootfs */
-	sys_fchdir(root_fd);
-	sys_chroot(".");
-	sys_close(old_fd);
-	sys_close(root_fd);
-
-	if (new_decode_dev(real_root_dev) == Root_RAM0) {
-		sys_chdir("/old");
-		return;
-	}
-
-	ROOT_DEV = new_decode_dev(real_root_dev);
-	mount_root();
-
-	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
-	error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
-	if (!error)
-		printk("okay\n");
-	else {
-		int fd = sys_open("/dev/root.old", O_RDWR, 0);
-		if (error == -ENOENT)
-			printk("/initrd does not exist. Ignored.\n");
-		else
-			printk("failed\n");
-		printk(KERN_NOTICE "Unmounting old root\n");
-		sys_umount("/old", MNT_DETACH);
-		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
-		if (fd < 0) {
-			error = fd;
-		} else {
-			error = sys_ioctl(fd, BLKFLSBUF, 0);
-			sys_close(fd);
-		}
-		printk(!error ? "okay\n" : "failed\n");
-	}
-}
-
-int __init initrd_load(void)
-{
-	if (mount_initrd) {
-		create_dev("/dev/ram", Root_RAM0);
-		/*
-		 * Load the initrd data into /dev/ram0. Execute it as initrd
-		 * unless /dev/ram0 is supposed to be our actual root device,
-		 * in that case the ram disk is just set up here, and gets
-		 * mounted in the normal path.
-		 */
-		if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
-			sys_unlink("/initrd.image");
-			handle_initrd();
-			return 1;
-		}
-	}
-	sys_unlink("/initrd.image");
-	return 0;
-}
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
deleted file mode 100644
index 2429e1b..0000000
--- a/init/do_mounts_md.c
+++ /dev/null
@@ -1,285 +0,0 @@
-
-#include <linux/raid/md.h>
-
-#include "do_mounts.h"
-
-/*
- * When md (and any require personalities) are compiled into the kernel
- * (not a module), arrays can be assembles are boot time using with AUTODETECT
- * where specially marked partitions are registered with md_autodetect_dev(),
- * and with MD_BOOT where devices to be collected are given on the boot line
- * with md=.....
- * The code for that is here.
- */
-
-static int __initdata raid_noautodetect, raid_autopart;
-
-static struct {
-	int minor;
-	int partitioned;
-	int level;
-	int chunk;
-	char *device_names;
-} md_setup_args[MAX_MD_DEVS] __initdata;
-
-static int md_setup_ents __initdata;
-
-extern int mdp_major;
-/*
- * Parse the command-line parameters given our kernel, but do not
- * actually try to invoke the MD device now; that is handled by
- * md_setup_drive after the low-level disk drivers have initialised.
- *
- * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
- *             assigns the task of parsing integer arguments to the
- *             invoked program now).  Added ability to initialise all
- *             the MD devices (by specifying multiple "md=" lines)
- *             instead of just one.  -- KTK
- * 18May2000: Added support for persistent-superblock arrays:
- *             md=n,0,factor,fault,device-list   uses RAID0 for device n
- *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
- *             md=n,device-list      reads a RAID superblock from the devices
- *             elements in device-list are read by name_to_kdev_t so can be
- *             a hex number or something like /dev/hda1 /dev/sdb
- * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
- *		Shifted name_to_kdev_t() and related operations to md_set_drive()
- *		for later execution. Rewrote section to make devfs compatible.
- */
-static int __init md_setup(char *str)
-{
-	int minor, level, factor, fault, partitioned = 0;
-	char *pername = "";
-	char *str1;
-	int ent;
-
-	if (*str == 'd') {
-		partitioned = 1;
-		str++;
-	}
-	if (get_option(&str, &minor) != 2) {	/* MD Number */
-		printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
-		return 0;
-	}
-	str1 = str;
-	if (minor >= MAX_MD_DEVS) {
-		printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
-		return 0;
-	}
-	for (ent=0 ; ent< md_setup_ents ; ent++)
-		if (md_setup_args[ent].minor == minor &&
-		    md_setup_args[ent].partitioned == partitioned) {
-			printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
-			       "Replacing previous definition.\n", partitioned?"d":"", minor);
-			break;
-		}
-	if (ent >= MAX_MD_DEVS) {
-		printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
-		return 0;
-	}
-	if (ent >= md_setup_ents)
-		md_setup_ents++;
-	switch (get_option(&str, &level)) {	/* RAID level */
-	case 2: /* could be 0 or -1.. */
-		if (level == 0 || level == LEVEL_LINEAR) {
-			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
-					get_option(&str, &fault) != 2) {
-				printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
-				return 0;
-			}
-			md_setup_args[ent].level = level;
-			md_setup_args[ent].chunk = 1 << (factor+12);
-			if (level ==  LEVEL_LINEAR)
-				pername = "linear";
-			else
-				pername = "raid0";
-			break;
-		}
-		/* FALL THROUGH */
-	case 1: /* the first device is numeric */
-		str = str1;
-		/* FALL THROUGH */
-	case 0:
-		md_setup_args[ent].level = LEVEL_NONE;
-		pername="super-block";
-	}
-
-	printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
-		minor, pername, str);
-	md_setup_args[ent].device_names = str;
-	md_setup_args[ent].partitioned = partitioned;
-	md_setup_args[ent].minor = minor;
-
-	return 1;
-}
-
-#define MdpMinorShift 6
-
-static void __init md_setup_drive(void)
-{
-	int minor, i, ent, partitioned;
-	dev_t dev;
-	dev_t devices[MD_SB_DISKS+1];
-
-	for (ent = 0; ent < md_setup_ents ; ent++) {
-		int fd;
-		int err = 0;
-		char *devname;
-		mdu_disk_info_t dinfo;
-		char name[16];
-
-		minor = md_setup_args[ent].minor;
-		partitioned = md_setup_args[ent].partitioned;
-		devname = md_setup_args[ent].device_names;
-
-		sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
-		if (partitioned)
-			dev = MKDEV(mdp_major, minor << MdpMinorShift);
-		else
-			dev = MKDEV(MD_MAJOR, minor);
-		create_dev(name, dev);
-		for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
-			char *p;
-			char comp_name[64];
-			u32 rdev;
-
-			p = strchr(devname, ',');
-			if (p)
-				*p++ = 0;
-
-			dev = name_to_dev_t(devname);
-			if (strncmp(devname, "/dev/", 5) == 0)
-				devname += 5;
-			snprintf(comp_name, 63, "/dev/%s", devname);
-			rdev = bstat(comp_name);
-			if (rdev)
-				dev = new_decode_dev(rdev);
-			if (!dev) {
-				printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
-				break;
-			}
-
-			devices[i] = dev;
-
-			devname = p;
-		}
-		devices[i] = 0;
-
-		if (!i)
-			continue;
-
-		printk(KERN_INFO "md: Loading md%s%d: %s\n",
-			partitioned ? "_d" : "", minor,
-			md_setup_args[ent].device_names);
-
-		fd = sys_open(name, 0, 0);
-		if (fd < 0) {
-			printk(KERN_ERR "md: open failed - cannot start "
-					"array %s\n", name);
-			continue;
-		}
-		if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
-			printk(KERN_WARNING
-			       "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
-			       minor);
-			sys_close(fd);
-			continue;
-		}
-
-		if (md_setup_args[ent].level != LEVEL_NONE) {
-			/* non-persistent */
-			mdu_array_info_t ainfo;
-			ainfo.level = md_setup_args[ent].level;
-			ainfo.size = 0;
-			ainfo.nr_disks =0;
-			ainfo.raid_disks =0;
-			while (devices[ainfo.raid_disks])
-				ainfo.raid_disks++;
-			ainfo.md_minor =minor;
-			ainfo.not_persistent = 1;
-
-			ainfo.state = (1 << MD_SB_CLEAN);
-			ainfo.layout = 0;
-			ainfo.chunk_size = md_setup_args[ent].chunk;
-			err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
-			for (i = 0; !err && i <= MD_SB_DISKS; i++) {
-				dev = devices[i];
-				if (!dev)
-					break;
-				dinfo.number = i;
-				dinfo.raid_disk = i;
-				dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
-				dinfo.major = MAJOR(dev);
-				dinfo.minor = MINOR(dev);
-				err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
-			}
-		} else {
-			/* persistent */
-			for (i = 0; i <= MD_SB_DISKS; i++) {
-				dev = devices[i];
-				if (!dev)
-					break;
-				dinfo.major = MAJOR(dev);
-				dinfo.minor = MINOR(dev);
-				sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
-			}
-		}
-		if (!err)
-			err = sys_ioctl(fd, RUN_ARRAY, 0);
-		if (err)
-			printk(KERN_WARNING "md: starting md%d failed\n", minor);
-		else {
-			/* reread the partition table.
-			 * I (neilb) and not sure why this is needed, but I cannot
-			 * boot a kernel with devfs compiled in from partitioned md
-			 * array without it
-			 */
-			sys_close(fd);
-			fd = sys_open(name, 0, 0);
-			sys_ioctl(fd, BLKRRPART, 0);
-		}
-		sys_close(fd);
-	}
-}
-
-static int __init raid_setup(char *str)
-{
-	int len, pos;
-
-	len = strlen(str) + 1;
-	pos = 0;
-
-	while (pos < len) {
-		char *comma = strchr(str+pos, ',');
-		int wlen;
-		if (comma)
-			wlen = (comma-str)-pos;
-		else	wlen = (len-1)-pos;
-
-		if (!strncmp(str, "noautodetect", wlen))
-			raid_noautodetect = 1;
-		if (strncmp(str, "partitionable", wlen)==0)
-			raid_autopart = 1;
-		if (strncmp(str, "part", wlen)==0)
-			raid_autopart = 1;
-		pos += wlen+1;
-	}
-	return 1;
-}
-
-__setup("raid=", raid_setup);
-__setup("md=", md_setup);
-
-void __init md_run_setup(void)
-{
-	create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
-	if (raid_noautodetect)
-		printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
-	else {
-		int fd = sys_open("/dev/md0", 0, 0);
-		if (fd >= 0) {
-			sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
-			sys_close(fd);
-		}
-	}
-	md_setup_drive();
-}
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
deleted file mode 100644
index ed652f4..0000000
--- a/init/do_mounts_rd.c
+++ /dev/null
@@ -1,429 +0,0 @@
-
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/romfs_fs.h>
-#include <linux/cramfs_fs.h>
-#include <linux/initrd.h>
-#include <linux/string.h>
-
-#include "do_mounts.h"
-
-#define BUILD_CRAMDISK
-
-int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
-
-static int __init prompt_ramdisk(char *str)
-{
-	rd_prompt = simple_strtol(str,NULL,0) & 1;
-	return 1;
-}
-__setup("prompt_ramdisk=", prompt_ramdisk);
-
-int __initdata rd_image_start;		/* starting block # of image */
-
-static int __init ramdisk_start_setup(char *str)
-{
-	rd_image_start = simple_strtol(str,NULL,0);
-	return 1;
-}
-__setup("ramdisk_start=", ramdisk_start_setup);
-
-static int __init crd_load(int in_fd, int out_fd);
-
-/*
- * This routine tries to find a RAM disk image to load, and returns the
- * number of blocks to read for a non-compressed image, 0 if the image
- * is a compressed image, and -1 if an image with the right magic
- * numbers could not be found.
- *
- * We currently check for the following magic numbers:
- * 	minix
- * 	ext2
- *	romfs
- *	cramfs
- * 	gzip
- */
-static int __init 
-identify_ramdisk_image(int fd, int start_block)
-{
-	const int size = 512;
-	struct minix_super_block *minixsb;
-	struct ext2_super_block *ext2sb;
-	struct romfs_super_block *romfsb;
-	struct cramfs_super *cramfsb;
-	int nblocks = -1;
-	unsigned char *buf;
-
-	buf = kmalloc(size, GFP_KERNEL);
-	if (buf == 0)
-		return -1;
-
-	minixsb = (struct minix_super_block *) buf;
-	ext2sb = (struct ext2_super_block *) buf;
-	romfsb = (struct romfs_super_block *) buf;
-	cramfsb = (struct cramfs_super *) buf;
-	memset(buf, 0xe5, size);
-
-	/*
-	 * Read block 0 to test for gzipped kernel
-	 */
-	sys_lseek(fd, start_block * BLOCK_SIZE, 0);
-	sys_read(fd, buf, size);
-
-	/*
-	 * If it matches the gzip magic numbers, return -1
-	 */
-	if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
-		printk(KERN_NOTICE
-		       "RAMDISK: Compressed image found at block %d\n",
-		       start_block);
-		nblocks = 0;
-		goto done;
-	}
-
-	/* romfs is at block zero too */
-	if (romfsb->word0 == ROMSB_WORD0 &&
-	    romfsb->word1 == ROMSB_WORD1) {
-		printk(KERN_NOTICE
-		       "RAMDISK: romfs filesystem found at block %d\n",
-		       start_block);
-		nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
-		goto done;
-	}
-
-	if (cramfsb->magic == CRAMFS_MAGIC) {
-		printk(KERN_NOTICE
-		       "RAMDISK: cramfs filesystem found at block %d\n",
-		       start_block);
-		nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
-		goto done;
-	}
-
-	/*
-	 * Read block 1 to test for minix and ext2 superblock
-	 */
-	sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
-	sys_read(fd, buf, size);
-
-	/* Try minix */
-	if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
-	    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
-		printk(KERN_NOTICE
-		       "RAMDISK: Minix filesystem found at block %d\n",
-		       start_block);
-		nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
-		goto done;
-	}
-
-	/* Try ext2 */
-	if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
-		printk(KERN_NOTICE
-		       "RAMDISK: ext2 filesystem found at block %d\n",
-		       start_block);
-		nblocks = le32_to_cpu(ext2sb->s_blocks_count) <<
-			le32_to_cpu(ext2sb->s_log_block_size);
-		goto done;
-	}
-
-	printk(KERN_NOTICE
-	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
-	       start_block);
-	
-done:
-	sys_lseek(fd, start_block * BLOCK_SIZE, 0);
-	kfree(buf);
-	return nblocks;
-}
-
-int __init rd_load_image(char *from)
-{
-	int res = 0;
-	int in_fd, out_fd;
-	unsigned long rd_blocks, devblocks;
-	int nblocks, i, disk;
-	char *buf = NULL;
-	unsigned short rotate = 0;
-#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
-	char rotator[4] = { '|' , '/' , '-' , '\\' };
-#endif
-
-	out_fd = sys_open("/dev/ram", O_RDWR, 0);
-	if (out_fd < 0)
-		goto out;
-
-	in_fd = sys_open(from, O_RDONLY, 0);
-	if (in_fd < 0)
-		goto noclose_input;
-
-	nblocks = identify_ramdisk_image(in_fd, rd_image_start);
-	if (nblocks < 0)
-		goto done;
-
-	if (nblocks == 0) {
-#ifdef BUILD_CRAMDISK
-		if (crd_load(in_fd, out_fd) == 0)
-			goto successful_load;
-#else
-		printk(KERN_NOTICE
-		       "RAMDISK: Kernel does not support compressed "
-		       "RAM disk images\n");
-#endif
-		goto done;
-	}
-
-	/*
-	 * NOTE NOTE: nblocks is not actually blocks but
-	 * the number of kibibytes of data to load into a ramdisk.
-	 * So any ramdisk block size that is a multiple of 1KiB should
-	 * work when the appropriate ramdisk_blocksize is specified
-	 * on the command line.
-	 *
-	 * The default ramdisk_blocksize is 1KiB and it is generally
-	 * silly to use anything else, so make sure to use 1KiB
-	 * blocksize while generating ext2fs ramdisk-images.
-	 */
-	if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
-		rd_blocks = 0;
-	else
-		rd_blocks >>= 1;
-
-	if (nblocks > rd_blocks) {
-		printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
-		       nblocks, rd_blocks);
-		goto done;
-	}
-		
-	/*
-	 * OK, time to copy in the data
-	 */
-	if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
-		devblocks = 0;
-	else
-		devblocks >>= 1;
-
-	if (strcmp(from, "/initrd.image") == 0)
-		devblocks = nblocks;
-
-	if (devblocks == 0) {
-		printk(KERN_ERR "RAMDISK: could not determine device size\n");
-		goto done;
-	}
-
-	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
-	if (buf == 0) {
-		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
-		goto done;
-	}
-
-	printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
-		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
-	for (i = 0, disk = 1; i < nblocks; i++) {
-		if (i && (i % devblocks == 0)) {
-			printk("done disk #%d.\n", disk++);
-			rotate = 0;
-			if (sys_close(in_fd)) {
-				printk("Error closing the disk.\n");
-				goto noclose_input;
-			}
-			change_floppy("disk #%d", disk);
-			in_fd = sys_open(from, O_RDONLY, 0);
-			if (in_fd < 0)  {
-				printk("Error opening disk.\n");
-				goto noclose_input;
-			}
-			printk("Loading disk #%d... ", disk);
-		}
-		sys_read(in_fd, buf, BLOCK_SIZE);
-		sys_write(out_fd, buf, BLOCK_SIZE);
-#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
-		if (!(i % 16)) {
-			printk("%c\b", rotator[rotate & 0x3]);
-			rotate++;
-		}
-#endif
-	}
-	printk("done.\n");
-
-successful_load:
-	res = 1;
-done:
-	sys_close(in_fd);
-noclose_input:
-	sys_close(out_fd);
-out:
-	kfree(buf);
-	sys_unlink("/dev/ram");
-	return res;
-}
-
-int __init rd_load_disk(int n)
-{
-	if (rd_prompt)
-		change_floppy("root floppy disk to be loaded into RAM disk");
-	create_dev("/dev/root", ROOT_DEV);
-	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
-	return rd_load_image("/dev/root");
-}
-
-#ifdef BUILD_CRAMDISK
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-
-#ifndef memzero
-#define memzero(s, n)     memset ((s), 0, (n))
-#endif
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define INBUFSIZ 4096
-#define WSIZE 0x8000    /* window size--must be a power of two, and */
-			/*  at least 32K for zip's deflate method */
-
-static uch *inbuf;
-static uch *window;
-
-static unsigned insize;  /* valid bytes in inbuf */
-static unsigned inptr;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt;  /* bytes in output buffer */
-static int exit_code;
-static int unzip_error;
-static long bytes_out;
-static int crd_infd, crd_outfd;
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-		
-/* Diagnostic functions (stubbed out) */
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define STATIC static
-#define INIT __init
-
-static int  __init fill_inbuf(void);
-static void __init flush_window(void);
-static void __init *malloc(size_t size);
-static void __init free(void *where);
-static void __init error(char *m);
-static void __init gzip_mark(void **);
-static void __init gzip_release(void **);
-
-#include "../lib/inflate.c"
-
-static void __init *malloc(size_t size)
-{
-	return kmalloc(size, GFP_KERNEL);
-}
-
-static void __init free(void *where)
-{
-	kfree(where);
-}
-
-static void __init gzip_mark(void **ptr)
-{
-}
-
-static void __init gzip_release(void **ptr)
-{
-}
-
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- * Returning -1 does not guarantee that gunzip() will ever return.
- */
-static int __init fill_inbuf(void)
-{
-	if (exit_code) return -1;
-	
-	insize = sys_read(crd_infd, inbuf, INBUFSIZ);
-	if (insize == 0) {
-		error("RAMDISK: ran out of compressed data");
-		return -1;
-	}
-
-	inptr = 1;
-
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n, written;
-    uch *in, ch;
-    
-    written = sys_write(crd_outfd, window, outcnt);
-    if (written != outcnt && unzip_error == 0) {
-	printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
-	       written, outcnt, bytes_out);
-	unzip_error = 1;
-    }
-    in = window;
-    for (n = 0; n < outcnt; n++) {
-	    ch = *in++;
-	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    outcnt = 0;
-}
-
-static void __init error(char *x)
-{
-	printk(KERN_ERR "%s\n", x);
-	exit_code = 1;
-	unzip_error = 1;
-}
-
-static int __init crd_load(int in_fd, int out_fd)
-{
-	int result;
-
-	insize = 0;		/* valid bytes in inbuf */
-	inptr = 0;		/* index of next byte to be processed in inbuf */
-	outcnt = 0;		/* bytes in output buffer */
-	exit_code = 0;
-	bytes_out = 0;
-	crc = (ulg)0xffffffffL; /* shift register contents */
-
-	crd_infd = in_fd;
-	crd_outfd = out_fd;
-	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
-	if (inbuf == 0) {
-		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
-		return -1;
-	}
-	window = kmalloc(WSIZE, GFP_KERNEL);
-	if (window == 0) {
-		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
-		kfree(inbuf);
-		return -1;
-	}
-	makecrc();
-	result = gunzip();
-	if (unzip_error)
-		result = 1;
-	kfree(inbuf);
-	kfree(window);
-	return result;
-}
-
-#endif  /* BUILD_CRAMDISK */
diff --git a/init/initramfs.c b/init/initramfs.c
index d28c109..57109d4 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -7,6 +7,9 @@
 #include <linux/string.h>
 #include <linux/syscalls.h>
 
+unsigned long __initdata initrd_start, initrd_end;
+int __initdata initrd_below_start_ok;
+
 static __initdata char *message;
 static void __init error(char *x)
 {
diff --git a/init/main.c b/init/main.c
index b2f3b56..e94e3ef 100644
--- a/init/main.c
+++ b/init/main.c
@@ -7,6 +7,8 @@
  *  Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
  *  Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
  *  Simplified starting of init:  Michael A. Griffith <grif@acm.org> 
+ *
+ *  2006-02-12 H. Peter Anvin: Eliminated in-kernel root mounting.
  */
 
 #define __KERNEL_SYSCALLS__
@@ -45,6 +47,7 @@
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
 #include <linux/key.h>
+#include <linux/root_dev.h>
 #include <linux/unwind.h>
 #include <linux/buffer_head.h>
 
@@ -123,6 +126,11 @@
 /* Setup configured maximum number of CPUs to activate */
 static unsigned int max_cpus = NR_CPUS;
 
+/* ROOT_DEV contains any architecture-specific default root device. */
+/* real_root_dev is used (via sysctl) to communicate ROOT_DEV to kinit. */
+dev_t ROOT_DEV;
+unsigned int real_root_dev;
+
 /*
  * Setup routine for controlling SMP activation
  *
@@ -688,6 +696,12 @@
 	do_basic_setup();
 
 	/*
+	 * If we have a root device set by architecture-specific means,
+	 * let kinit know about it.
+	 */
+	real_root_dev = new_encode_dev(ROOT_DEV);
+
+	/*
 	 * check if there is an early userspace init.  If yes, let it do all
 	 * the work
 	 */
@@ -695,11 +709,6 @@
 	if (!ramdisk_execute_command)
 		ramdisk_execute_command = "/init";
 
-	if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
-		ramdisk_execute_command = NULL;
-		prepare_namespace();
-	}
-
 	/*
 	 * Ok, we have completed the initial bootup, and
 	 * we're essentially up and running. Get rid of the
@@ -711,33 +720,13 @@
 	system_state = SYSTEM_RUNNING;
 	numa_default_policy();
 
+	/* This could be done by (k)init as well... */
 	if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
 		printk(KERN_WARNING "Warning: unable to open an initial console.\n");
 
 	(void) sys_dup(0);
 	(void) sys_dup(0);
 
-	if (ramdisk_execute_command) {
-		run_init_process(ramdisk_execute_command);
-		printk(KERN_WARNING "Failed to execute %s\n",
-				ramdisk_execute_command);
-	}
-
-	/*
-	 * We try each of these until one succeeds.
-	 *
-	 * The Bourne shell can be used instead of init if we are 
-	 * trying to recover a really broken machine.
-	 */
-	if (execute_command) {
-		run_init_process(execute_command);
-		printk(KERN_WARNING "Failed to execute %s.  Attempting "
-					"defaults...\n", execute_command);
-	}
-	run_init_process("/sbin/init");
-	run_init_process("/etc/init");
-	run_init_process("/bin/init");
-	run_init_process("/bin/sh");
-
-	panic("No init found.  Try passing init= option to kernel.");
+	run_init_process(ramdisk_execute_command);
+	panic("Failed to execute %s", ramdisk_execute_command);
 }
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 38b8039..964403f 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -26,7 +26,6 @@
 obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
 obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
 obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
-obj-$(CONFIG_IP_PNP) += ipconfig.o
 obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o
 obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
 obj-$(CONFIG_IP_ROUTE_MULTIPATH_WRANDOM) += multipath_wrandom.o
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
deleted file mode 100644
index cb8a92f..0000000
--- a/net/ipv4/ipconfig.c
+++ /dev/null
@@ -1,1510 +0,0 @@
-/*
- *  $Id: ipconfig.c,v 1.46 2002/02/01 22:01:04 davem Exp $
- *
- *  Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
- *  user-supplied information to configure own IP address and routes.
- *
- *  Copyright (C) 1996-1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- *
- *  Derived from network configuration code in fs/nfs/nfsroot.c,
- *  originally Copyright (C) 1995, 1996 Gero Kuhlmann and me.
- *
- *  BOOTP rewritten to construct and analyse packets itself instead
- *  of misusing the IP layer. num_bugs_causing_wrong_arp_replies--;
- *					     -- MJ, December 1998
- *  
- *  Fixed ip_auto_config_setup calling at startup in the new "Linker Magic"
- *  initialization scheme.
- *	- Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 08/11/1999
- *
- *  DHCP support added.  To users this looks like a whole separate
- *  protocol, but we know it's just a bag on the side of BOOTP.
- *		-- Chip Salzenberg <chip@valinux.com>, May 2000
- *
- *  Ported DHCP support from 2.2.16 to 2.4.0-test4
- *              -- Eric Biederman <ebiederman@lnxi.com>, 30 Aug 2000
- *
- *  Merged changes from 2.2.19 into 2.4.3
- *              -- Eric Biederman <ebiederman@lnxi.com>, 22 April Aug 2001
- *
- *  Multiple Nameservers in /proc/net/pnp
- *              --  Josef Siemes <jsiemes@web.de>, Aug 2002
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/jiffies.h>
-#include <linux/random.h>
-#include <linux/init.h>
-#include <linux/utsname.h>
-#include <linux/in.h>
-#include <linux/if.h>
-#include <linux/inet.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/ip.h>
-#include <linux/socket.h>
-#include <linux/route.h>
-#include <linux/udp.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/major.h>
-#include <linux/root_dev.h>
-#include <linux/delay.h>
-#include <linux/nfs_fs.h>
-#include <net/arp.h>
-#include <net/ip.h>
-#include <net/ipconfig.h>
-#include <net/route.h>
-
-#include <asm/uaccess.h>
-#include <net/checksum.h>
-#include <asm/processor.h>
-
-/* Define this to allow debugging output */
-#undef IPCONFIG_DEBUG
-
-#ifdef IPCONFIG_DEBUG
-#define DBG(x) printk x
-#else
-#define DBG(x) do { } while(0)
-#endif
-
-#if defined(CONFIG_IP_PNP_DHCP)
-#define IPCONFIG_DHCP
-#endif
-#if defined(CONFIG_IP_PNP_BOOTP) || defined(CONFIG_IP_PNP_DHCP)
-#define IPCONFIG_BOOTP
-#endif
-#if defined(CONFIG_IP_PNP_RARP)
-#define IPCONFIG_RARP
-#endif
-#if defined(IPCONFIG_BOOTP) || defined(IPCONFIG_RARP)
-#define IPCONFIG_DYNAMIC
-#endif
-
-/* Define the friendly delay before and after opening net devices */
-#define CONF_PRE_OPEN		500	/* Before opening: 1/2 second */
-#define CONF_POST_OPEN		1	/* After opening: 1 second */
-
-/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
-#define CONF_OPEN_RETRIES 	2	/* (Re)open devices twice */
-#define CONF_SEND_RETRIES 	6	/* Send six requests per open */
-#define CONF_INTER_TIMEOUT	(HZ/2)	/* Inter-device timeout: 1/2 second */
-#define CONF_BASE_TIMEOUT	(HZ*2)	/* Initial timeout: 2 seconds */
-#define CONF_TIMEOUT_RANDOM	(HZ)	/* Maximum amount of randomization */
-#define CONF_TIMEOUT_MULT	*7/4	/* Rate of timeout growth */
-#define CONF_TIMEOUT_MAX	(HZ*30)	/* Maximum allowed timeout */
-#define CONF_NAMESERVERS_MAX   3       /* Maximum number of nameservers  
-                                           - '3' from resolv.h */
-
-
-/*
- * Public IP configuration
- */
-
-/* This is used by platforms which might be able to set the ipconfig
- * variables using firmware environment vars.  If this is set, it will
- * ignore such firmware variables.
- */
-int ic_set_manually __initdata = 0;		/* IPconfig parameters set manually */
-
-static int ic_enable __initdata = 0;		/* IP config enabled? */
-
-/* Protocol choice */
-int ic_proto_enabled __initdata = 0
-#ifdef IPCONFIG_BOOTP
-			| IC_BOOTP
-#endif
-#ifdef CONFIG_IP_PNP_DHCP
-			| IC_USE_DHCP
-#endif
-#ifdef IPCONFIG_RARP
-			| IC_RARP
-#endif
-			;
-
-static int ic_host_name_set __initdata = 0;	/* Host name set by us? */
-
-u32 ic_myaddr = INADDR_NONE;		/* My IP address */
-static u32 ic_netmask = INADDR_NONE;	/* Netmask for local subnet */
-u32 ic_gateway = INADDR_NONE;	/* Gateway IP address */
-
-u32 ic_servaddr = INADDR_NONE;	/* Boot server IP address */
-
-u32 root_server_addr = INADDR_NONE;	/* Address of NFS server */
-u8 root_server_path[256] = { 0, };	/* Path to mount as root */
-
-/* Persistent data: */
-
-static int ic_proto_used;			/* Protocol used, if any */
-static u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
-static u8 ic_domain[64];		/* DNS (not NIS) domain name */
-
-/*
- * Private state.
- */
-
-/* Name of user-selected boot device */
-static char user_dev_name[IFNAMSIZ] __initdata = { 0, };
-
-/* Protocols supported by available interfaces */
-static int ic_proto_have_if __initdata = 0;
-
-#ifdef IPCONFIG_DYNAMIC
-static DEFINE_SPINLOCK(ic_recv_lock);
-static volatile int ic_got_reply __initdata = 0;    /* Proto(s) that replied */
-#endif
-#ifdef IPCONFIG_DHCP
-static int ic_dhcp_msgtype __initdata = 0;	/* DHCP msg type received */
-#endif
-
-
-/*
- *	Network devices
- */
-
-struct ic_device {
-	struct ic_device *next;
-	struct net_device *dev;
-	unsigned short flags;
-	short able;
-	u32 xid;
-};
-
-static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
-static struct net_device *ic_dev __initdata = NULL;	/* Selected device */
-
-static int __init ic_open_devs(void)
-{
-	struct ic_device *d, **last;
-	struct net_device *dev;
-	unsigned short oflags;
-
-	last = &ic_first_dev;
-	rtnl_lock();
-
-	/* bring loopback device up first */
-	if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
-		printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name);
-
-	for (dev = dev_base; dev; dev = dev->next) {
-		if (dev == &loopback_dev)
-			continue;
-		if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
-		    (!(dev->flags & IFF_LOOPBACK) &&
-		     (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
-		     strncmp(dev->name, "dummy", 5))) {
-			int able = 0;
-			if (dev->mtu >= 364)
-				able |= IC_BOOTP;
-			else
-				printk(KERN_WARNING "DHCP/BOOTP: Ignoring device %s, MTU %d too small", dev->name, dev->mtu);
-			if (!(dev->flags & IFF_NOARP))
-				able |= IC_RARP;
-			able &= ic_proto_enabled;
-			if (ic_proto_enabled && !able)
-				continue;
-			oflags = dev->flags;
-			if (dev_change_flags(dev, oflags | IFF_UP) < 0) {
-				printk(KERN_ERR "IP-Config: Failed to open %s\n", dev->name);
-				continue;
-			}
-			if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
-				rtnl_unlock();
-				return -1;
-			}
-			d->dev = dev;
-			*last = d;
-			last = &d->next;
-			d->flags = oflags;
-			d->able = able;
-			if (able & IC_BOOTP)
-				get_random_bytes(&d->xid, sizeof(u32));
-			else
-				d->xid = 0;
-			ic_proto_have_if |= able;
-			DBG(("IP-Config: %s UP (able=%d, xid=%08x)\n",
-				dev->name, able, d->xid));
-		}
-	}
-	rtnl_unlock();
-
-	*last = NULL;
-
-	if (!ic_first_dev) {
-		if (user_dev_name[0])
-			printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
-		else
-			printk(KERN_ERR "IP-Config: No network devices available.\n");
-		return -1;
-	}
-	return 0;
-}
-
-static void __init ic_close_devs(void)
-{
-	struct ic_device *d, *next;
-	struct net_device *dev;
-
-	rtnl_lock();
-	next = ic_first_dev;
-	while ((d = next)) {
-		next = d->next;
-		dev = d->dev;
-		if (dev != ic_dev) {
-			DBG(("IP-Config: Downing %s\n", dev->name));
-			dev_change_flags(dev, d->flags);
-		}
-		kfree(d);
-	}
-	rtnl_unlock();
-}
-
-/*
- *	Interface to various network functions.
- */
-
-static inline void
-set_sockaddr(struct sockaddr_in *sin, u32 addr, u16 port)
-{
-	sin->sin_family = AF_INET;
-	sin->sin_addr.s_addr = addr;
-	sin->sin_port = port;
-}
-
-static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
-{
-	int res;
-
-	mm_segment_t oldfs = get_fs();
-	set_fs(get_ds());
-	res = devinet_ioctl(cmd, (struct ifreq __user *) arg);
-	set_fs(oldfs);
-	return res;
-}
-
-static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg)
-{
-	int res;
-
-	mm_segment_t oldfs = get_fs();
-	set_fs(get_ds());
-	res = ip_rt_ioctl(cmd, (void __user *) arg);
-	set_fs(oldfs);
-	return res;
-}
-
-/*
- *	Set up interface addresses and routes.
- */
-
-static int __init ic_setup_if(void)
-{
-	struct ifreq ir;
-	struct sockaddr_in *sin = (void *) &ir.ifr_ifru.ifru_addr;
-	int err;
-
-	memset(&ir, 0, sizeof(ir));
-	strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
-	set_sockaddr(sin, ic_myaddr, 0);
-	if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
-		printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err);
-		return -1;
-	}
-	set_sockaddr(sin, ic_netmask, 0);
-	if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
-		printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err);
-		return -1;
-	}
-	set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
-	if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
-		printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err);
-		return -1;
-	}
-	return 0;
-}
-
-static int __init ic_setup_routes(void)
-{
-	/* No need to setup device routes, only the default route... */
-
-	if (ic_gateway != INADDR_NONE) {
-		struct rtentry rm;
-		int err;
-
-		memset(&rm, 0, sizeof(rm));
-		if ((ic_gateway ^ ic_myaddr) & ic_netmask) {
-			printk(KERN_ERR "IP-Config: Gateway not on directly connected network.\n");
-			return -1;
-		}
-		set_sockaddr((struct sockaddr_in *) &rm.rt_dst, 0, 0);
-		set_sockaddr((struct sockaddr_in *) &rm.rt_genmask, 0, 0);
-		set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0);
-		rm.rt_flags = RTF_UP | RTF_GATEWAY;
-		if ((err = ic_route_ioctl(SIOCADDRT, &rm)) < 0) {
-			printk(KERN_ERR "IP-Config: Cannot add default route (%d).\n", err);
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-/*
- *	Fill in default values for all missing parameters.
- */
-
-static int __init ic_defaults(void)
-{
-	/*
-	 *	At this point we have no userspace running so need not
-	 *	claim locks on system_utsname
-	 */
-	 
-	if (!ic_host_name_set)
-		sprintf(system_utsname.nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
-
-	if (root_server_addr == INADDR_NONE)
-		root_server_addr = ic_servaddr;
-
-	if (ic_netmask == INADDR_NONE) {
-		if (IN_CLASSA(ntohl(ic_myaddr)))
-			ic_netmask = htonl(IN_CLASSA_NET);
-		else if (IN_CLASSB(ntohl(ic_myaddr)))
-			ic_netmask = htonl(IN_CLASSB_NET);
-		else if (IN_CLASSC(ntohl(ic_myaddr)))
-			ic_netmask = htonl(IN_CLASSC_NET);
-		else {
-			printk(KERN_ERR "IP-Config: Unable to guess netmask for address %u.%u.%u.%u\n",
-				NIPQUAD(ic_myaddr));
-			return -1;
-		}
-		printk("IP-Config: Guessing netmask %u.%u.%u.%u\n", NIPQUAD(ic_netmask));
-	}
-
-	return 0;
-}
-
-/*
- *	RARP support.
- */
-
-#ifdef IPCONFIG_RARP
-
-static int ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev);
-
-static struct packet_type rarp_packet_type __initdata = {
-	.type =	__constant_htons(ETH_P_RARP),
-	.func =	ic_rarp_recv,
-};
-
-static inline void ic_rarp_init(void)
-{
-	dev_add_pack(&rarp_packet_type);
-}
-
-static inline void ic_rarp_cleanup(void)
-{
-	dev_remove_pack(&rarp_packet_type);
-}
-
-/*
- *  Process received RARP packet.
- */
-static int __init
-ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
-{
-	struct arphdr *rarp;
-	unsigned char *rarp_ptr;
-	unsigned long sip, tip;
-	unsigned char *sha, *tha;		/* s for "source", t for "target" */
-	struct ic_device *d;
-
-	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-		return NET_RX_DROP;
-
-	if (!pskb_may_pull(skb, sizeof(struct arphdr)))
-		goto drop;
-
-	/* Basic sanity checks can be done without the lock.  */
-	rarp = (struct arphdr *)skb->h.raw;
-
-	/* If this test doesn't pass, it's not IP, or we should
-	 * ignore it anyway.
-	 */
-	if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd))
-		goto drop;
-
-	/* If it's not a RARP reply, delete it. */
-	if (rarp->ar_op != htons(ARPOP_RREPLY))
-		goto drop;
-
-	/* If it's not Ethernet, delete it. */
-	if (rarp->ar_pro != htons(ETH_P_IP))
-		goto drop;
-
-	if (!pskb_may_pull(skb,
-			   sizeof(struct arphdr) +
-			   (2 * dev->addr_len) +
-			   (2 * 4)))
-		goto drop;
-
-	/* OK, it is all there and looks valid, process... */
-	rarp = (struct arphdr *)skb->h.raw;
-	rarp_ptr = (unsigned char *) (rarp + 1);
-
-	/* One reply at a time, please. */
-	spin_lock(&ic_recv_lock);
-
-	/* If we already have a reply, just drop the packet */
-	if (ic_got_reply)
-		goto drop_unlock;
-
-	/* Find the ic_device that the packet arrived on */
-	d = ic_first_dev;
-	while (d && d->dev != dev)
-		d = d->next;
-	if (!d)
-		goto drop_unlock;	/* should never happen */
-
-	/* Extract variable-width fields */
-	sha = rarp_ptr;
-	rarp_ptr += dev->addr_len;
-	memcpy(&sip, rarp_ptr, 4);
-	rarp_ptr += 4;
-	tha = rarp_ptr;
-	rarp_ptr += dev->addr_len;
-	memcpy(&tip, rarp_ptr, 4);
-
-	/* Discard packets which are not meant for us. */
-	if (memcmp(tha, dev->dev_addr, dev->addr_len))
-		goto drop_unlock;
-
-	/* Discard packets which are not from specified server. */
-	if (ic_servaddr != INADDR_NONE && ic_servaddr != sip)
-		goto drop_unlock;
-
-	/* We have a winner! */
-	ic_dev = dev;
-	if (ic_myaddr == INADDR_NONE)
-		ic_myaddr = tip;
-	ic_servaddr = sip;
-	ic_got_reply = IC_RARP;
-
-drop_unlock:
-	/* Show's over.  Nothing to see here.  */
-	spin_unlock(&ic_recv_lock);
-
-drop:
-	/* Throw the packet out. */
-	kfree_skb(skb);
-	return 0;
-}
-
-
-/*
- *  Send RARP request packet over a single interface.
- */
-static void __init ic_rarp_send_if(struct ic_device *d)
-{
-	struct net_device *dev = d->dev;
-	arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
-		 dev->dev_addr, dev->dev_addr);
-}
-#endif
-
-/*
- *	DHCP/BOOTP support.
- */
-
-#ifdef IPCONFIG_BOOTP
-
-struct bootp_pkt {		/* BOOTP packet format */
-	struct iphdr iph;	/* IP header */
-	struct udphdr udph;	/* UDP header */
-	u8 op;			/* 1=request, 2=reply */
-	u8 htype;		/* HW address type */
-	u8 hlen;		/* HW address length */
-	u8 hops;		/* Used only by gateways */
-	u32 xid;		/* Transaction ID */
-	u16 secs;		/* Seconds since we started */
-	u16 flags;		/* Just what it says */
-	u32 client_ip;		/* Client's IP address if known */
-	u32 your_ip;		/* Assigned IP address */
-	u32 server_ip;		/* (Next, e.g. NFS) Server's IP address */
-	u32 relay_ip;		/* IP address of BOOTP relay */
-	u8 hw_addr[16];		/* Client's HW address */
-	u8 serv_name[64];	/* Server host name */
-	u8 boot_file[128];	/* Name of boot file */
-	u8 exten[312];		/* DHCP options / BOOTP vendor extensions */
-};
-
-/* packet ops */
-#define BOOTP_REQUEST	1
-#define BOOTP_REPLY	2
-
-/* DHCP message types */
-#define DHCPDISCOVER	1
-#define DHCPOFFER	2
-#define DHCPREQUEST	3
-#define DHCPDECLINE	4
-#define DHCPACK		5
-#define DHCPNAK		6
-#define DHCPRELEASE	7
-#define DHCPINFORM	8
-
-static int ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev);
-
-static struct packet_type bootp_packet_type __initdata = {
-	.type =	__constant_htons(ETH_P_IP),
-	.func =	ic_bootp_recv,
-};
-
-
-/*
- *  Initialize DHCP/BOOTP extension fields in the request.
- */
-
-static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
-
-#ifdef IPCONFIG_DHCP
-
-static void __init
-ic_dhcp_init_options(u8 *options)
-{
-	u8 mt = ((ic_servaddr == INADDR_NONE)
-		 ? DHCPDISCOVER : DHCPREQUEST);
-	u8 *e = options;
-
-#ifdef IPCONFIG_DEBUG
-	printk("DHCP: Sending message type %d\n", mt);
-#endif
-
-	memcpy(e, ic_bootp_cookie, 4);	/* RFC1048 Magic Cookie */
-	e += 4;
-
-	*e++ = 53;		/* DHCP message type */
-	*e++ = 1;
-	*e++ = mt;
-
-	if (mt == DHCPREQUEST) {
-		*e++ = 54;	/* Server ID (IP address) */
-		*e++ = 4;
-		memcpy(e, &ic_servaddr, 4);
-		e += 4;
-
-		*e++ = 50;	/* Requested IP address */
-		*e++ = 4;
-		memcpy(e, &ic_myaddr, 4);
-		e += 4;
-	}
-
-	/* always? */
-	{
-		static const u8 ic_req_params[] = {
-			1,	/* Subnet mask */
-			3,	/* Default gateway */
-			6,	/* DNS server */
-			12,	/* Host name */
-			15,	/* Domain name */
-			17,	/* Boot path */
-			40,	/* NIS domain name */
-		};
-
-		*e++ = 55;	/* Parameter request list */
-		*e++ = sizeof(ic_req_params);
-		memcpy(e, ic_req_params, sizeof(ic_req_params));
-		e += sizeof(ic_req_params);
-	}
-
-	*e++ = 255;	/* End of the list */
-}
-
-#endif /* IPCONFIG_DHCP */
-
-static void __init ic_bootp_init_ext(u8 *e)
-{
-	memcpy(e, ic_bootp_cookie, 4);	/* RFC1048 Magic Cookie */
-	e += 4;
-	*e++ = 1;		/* Subnet mask request */
-	*e++ = 4;
-	e += 4;
-	*e++ = 3;		/* Default gateway request */
-	*e++ = 4;
-	e += 4;
-	*e++ = 5;		/* Name server request */
-	*e++ = 8;
-	e += 8;
-	*e++ = 12;		/* Host name request */
-	*e++ = 32;
-	e += 32;
-	*e++ = 40;		/* NIS Domain name request */
-	*e++ = 32;
-	e += 32;
-	*e++ = 17;		/* Boot path */
-	*e++ = 40;
-	e += 40;
-
-	*e++ = 57;		/* set extension buffer size for reply */ 
-	*e++ = 2;
-	*e++ = 1;		/* 128+236+8+20+14, see dhcpd sources */ 
-	*e++ = 150;
-
-	*e++ = 255;		/* End of the list */
-}
-
-
-/*
- *  Initialize the DHCP/BOOTP mechanism.
- */
-static inline void ic_bootp_init(void)
-{
-	int i;
-
-	for (i = 0; i < CONF_NAMESERVERS_MAX; i++)
-		ic_nameservers[i] = INADDR_NONE;
-
-	dev_add_pack(&bootp_packet_type);
-}
-
-
-/*
- *  DHCP/BOOTP cleanup.
- */
-static inline void ic_bootp_cleanup(void)
-{
-	dev_remove_pack(&bootp_packet_type);
-}
-
-
-/*
- *  Send DHCP/BOOTP request to single interface.
- */
-static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_diff)
-{
-	struct net_device *dev = d->dev;
-	struct sk_buff *skb;
-	struct bootp_pkt *b;
-	int hh_len = LL_RESERVED_SPACE(dev);
-	struct iphdr *h;
-
-	/* Allocate packet */
-	skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
-	if (!skb)
-		return;
-	skb_reserve(skb, hh_len);
-	b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));
-	memset(b, 0, sizeof(struct bootp_pkt));
-
-	/* Construct IP header */
-	skb->nh.iph = h = &b->iph;
-	h->version = 4;
-	h->ihl = 5;
-	h->tot_len = htons(sizeof(struct bootp_pkt));
-	h->frag_off = htons(IP_DF);
-	h->ttl = 64;
-	h->protocol = IPPROTO_UDP;
-	h->daddr = INADDR_BROADCAST;
-	h->check = ip_fast_csum((unsigned char *) h, h->ihl);
-
-	/* Construct UDP header */
-	b->udph.source = htons(68);
-	b->udph.dest = htons(67);
-	b->udph.len = htons(sizeof(struct bootp_pkt) - sizeof(struct iphdr));
-	/* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */
-
-	/* Construct DHCP/BOOTP header */
-	b->op = BOOTP_REQUEST;
-	if (dev->type < 256) /* check for false types */
-		b->htype = dev->type;
-	else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */
-		b->htype = ARPHRD_IEEE802;
-	else if (dev->type == ARPHRD_FDDI)
-		b->htype = ARPHRD_ETHER;
-	else {
-		printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
-		b->htype = dev->type; /* can cause undefined behavior */
-	}
-	b->hlen = dev->addr_len;
-	b->your_ip = INADDR_NONE;
-	b->server_ip = INADDR_NONE;
-	memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
-	b->secs = htons(jiffies_diff / HZ);
-	b->xid = d->xid;
-
-	/* add DHCP options or BOOTP extensions */
-#ifdef IPCONFIG_DHCP
-	if (ic_proto_enabled & IC_USE_DHCP)
-		ic_dhcp_init_options(b->exten);
-	else
-#endif
-		ic_bootp_init_ext(b->exten);
-
-	/* Chain packet down the line... */
-	skb->dev = dev;
-	skb->protocol = htons(ETH_P_IP);
-	if ((dev->hard_header &&
-	     dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) ||
-	    dev_queue_xmit(skb) < 0)
-		printk("E");
-}
-
-
-/*
- *  Copy BOOTP-supplied string if not already set.
- */
-static int __init ic_bootp_string(char *dest, char *src, int len, int max)
-{
-	if (!len)
-		return 0;
-	if (len > max-1)
-		len = max-1;
-	memcpy(dest, src, len);
-	dest[len] = '\0';
-	return 1;
-}
-
-
-/*
- *  Process BOOTP extensions.
- */
-static void __init ic_do_bootp_ext(u8 *ext)
-{
-       u8 servers;
-       int i;
-
-#ifdef IPCONFIG_DEBUG
-	u8 *c;
-
-	printk("DHCP/BOOTP: Got extension %d:",*ext);
-	for(c=ext+2; c<ext+2+ext[1]; c++)
-		printk(" %02x", *c);
-	printk("\n");
-#endif
-
-	switch (*ext++) {
-		case 1:		/* Subnet mask */
-			if (ic_netmask == INADDR_NONE)
-				memcpy(&ic_netmask, ext+1, 4);
-			break;
-		case 3:		/* Default gateway */
-			if (ic_gateway == INADDR_NONE)
-				memcpy(&ic_gateway, ext+1, 4);
-			break;
-		case 6:		/* DNS server */
-			servers= *ext/4;
-			if (servers > CONF_NAMESERVERS_MAX)
-				servers = CONF_NAMESERVERS_MAX;
-			for (i = 0; i < servers; i++) {
-				if (ic_nameservers[i] == INADDR_NONE)
-					memcpy(&ic_nameservers[i], ext+1+4*i, 4);
-			}
-			break;
-		case 12:	/* Host name */
-			ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
-			ic_host_name_set = 1;
-			break;
-		case 15:	/* Domain name (DNS) */
-			ic_bootp_string(ic_domain, ext+1, *ext, sizeof(ic_domain));
-			break;
-		case 17:	/* Root path */
-			if (!root_server_path[0])
-				ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
-			break;
-		case 40:	/* NIS Domain name (_not_ DNS) */
-			ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
-			break;
-	}
-}
-
-
-/*
- *  Receive BOOTP reply.
- */
-static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
-{
-	struct bootp_pkt *b;
-	struct iphdr *h;
-	struct ic_device *d;
-	int len, ext_len;
-
-	/* Perform verifications before taking the lock.  */
-	if (skb->pkt_type == PACKET_OTHERHOST)
-		goto drop;
-
-	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-		return NET_RX_DROP;
-
-	if (!pskb_may_pull(skb,
-			   sizeof(struct iphdr) +
-			   sizeof(struct udphdr)))
-		goto drop;
-
-	b = (struct bootp_pkt *) skb->nh.iph;
-	h = &b->iph;
-
-	if (h->ihl != 5 || h->version != 4 || h->protocol != IPPROTO_UDP)
-		goto drop;
-
-	/* Fragments are not supported */
-	if (h->frag_off & htons(IP_OFFSET | IP_MF)) {
-		if (net_ratelimit())
-			printk(KERN_ERR "DHCP/BOOTP: Ignoring fragmented "
-			       "reply.\n");
-		goto drop;
-	}
-
-	if (skb->len < ntohs(h->tot_len))
-		goto drop;
-
-	if (ip_fast_csum((char *) h, h->ihl))
-		goto drop;
-
-	if (b->udph.source != htons(67) || b->udph.dest != htons(68))
-		goto drop;
-
-	if (ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))
-		goto drop;
-
-	len = ntohs(b->udph.len) - sizeof(struct udphdr);
-	ext_len = len - (sizeof(*b) -
-			 sizeof(struct iphdr) -
-			 sizeof(struct udphdr) -
-			 sizeof(b->exten));
-	if (ext_len < 0)
-		goto drop;
-
-	/* Ok the front looks good, make sure we can get at the rest.  */
-	if (!pskb_may_pull(skb, skb->len))
-		goto drop;
-
-	b = (struct bootp_pkt *) skb->nh.iph;
-	h = &b->iph;
-
-	/* One reply at a time, please. */
-	spin_lock(&ic_recv_lock);
-
-	/* If we already have a reply, just drop the packet */
-	if (ic_got_reply)
-		goto drop_unlock;
-
-	/* Find the ic_device that the packet arrived on */
-	d = ic_first_dev;
-	while (d && d->dev != dev)
-		d = d->next;
-	if (!d)
-		goto drop_unlock;  /* should never happen */
-
-	/* Is it a reply to our BOOTP request? */
-	if (b->op != BOOTP_REPLY ||
-	    b->xid != d->xid) {
-		if (net_ratelimit())
-			printk(KERN_ERR "DHCP/BOOTP: Reply not for us, "
-			       "op[%x] xid[%x]\n",
-			       b->op, b->xid);
-		goto drop_unlock;
-	}
-
-	/* Parse extensions */
-	if (ext_len >= 4 &&
-	    !memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
-                u8 *end = (u8 *) b + ntohs(b->iph.tot_len);
-		u8 *ext;
-
-#ifdef IPCONFIG_DHCP
-		if (ic_proto_enabled & IC_USE_DHCP) {
-			u32 server_id = INADDR_NONE;
-			int mt = 0;
-
-			ext = &b->exten[4];
-			while (ext < end && *ext != 0xff) {
-				u8 *opt = ext++;
-				if (*opt == 0)	/* Padding */
-					continue;
-				ext += *ext + 1;
-				if (ext >= end)
-					break;
-				switch (*opt) {
-				case 53:	/* Message type */
-					if (opt[1])
-						mt = opt[2];
-					break;
-				case 54:	/* Server ID (IP address) */
-					if (opt[1] >= 4)
-						memcpy(&server_id, opt + 2, 4);
-					break;
-				};
-			}
-
-#ifdef IPCONFIG_DEBUG
-			printk("DHCP: Got message type %d\n", mt);
-#endif
-
-			switch (mt) {
-			case DHCPOFFER:
-				/* While in the process of accepting one offer,
-				 * ignore all others.
-				 */
-				if (ic_myaddr != INADDR_NONE)
-					goto drop_unlock;
-
-				/* Let's accept that offer. */
-				ic_myaddr = b->your_ip;
-				ic_servaddr = server_id;
-#ifdef IPCONFIG_DEBUG
-				printk("DHCP: Offered address %u.%u.%u.%u",
-				       NIPQUAD(ic_myaddr));
-				printk(" by server %u.%u.%u.%u\n",
-				       NIPQUAD(ic_servaddr));
-#endif
-				/* The DHCP indicated server address takes
-				 * precedence over the bootp header one if
-				 * they are different.
-				 */
-				if ((server_id != INADDR_NONE) &&
-				    (b->server_ip != server_id))
-					b->server_ip = ic_servaddr;
-				break;
-
-			case DHCPACK:
-				if (memcmp(dev->dev_addr, b->hw_addr, dev->addr_len) != 0)
-					goto drop_unlock;
-
-				/* Yeah! */
-				break;
-
-			default:
-				/* Urque.  Forget it*/
-				ic_myaddr = INADDR_NONE;
-				ic_servaddr = INADDR_NONE;
-				goto drop_unlock;
-			};
-
-			ic_dhcp_msgtype = mt;
-
-		}
-#endif /* IPCONFIG_DHCP */
-
-		ext = &b->exten[4];
-		while (ext < end && *ext != 0xff) {
-			u8 *opt = ext++;
-			if (*opt == 0)	/* Padding */
-				continue;
-			ext += *ext + 1;
-			if (ext < end)
-				ic_do_bootp_ext(opt);
-		}
-	}
-
-	/* We have a winner! */
-	ic_dev = dev;
-	ic_myaddr = b->your_ip;
-	ic_servaddr = b->server_ip;
-	if (ic_gateway == INADDR_NONE && b->relay_ip)
-		ic_gateway = b->relay_ip;
-	if (ic_nameservers[0] == INADDR_NONE)
-		ic_nameservers[0] = ic_servaddr;
-	ic_got_reply = IC_BOOTP;
-
-drop_unlock:
-	/* Show's over.  Nothing to see here.  */
-	spin_unlock(&ic_recv_lock);
-
-drop:
-	/* Throw the packet out. */
-	kfree_skb(skb);
-
-	return 0;
-}	
-
-
-#endif
-
-
-/*
- *	Dynamic IP configuration -- DHCP, BOOTP, RARP.
- */
-
-#ifdef IPCONFIG_DYNAMIC
-
-static int __init ic_dynamic(void)
-{
-	int retries;
-	struct ic_device *d;
-	unsigned long start_jiffies, timeout, jiff;
-	int do_bootp = ic_proto_have_if & IC_BOOTP;
-	int do_rarp = ic_proto_have_if & IC_RARP;
-
-	/*
-	 * If none of DHCP/BOOTP/RARP was selected, return with an error.
-	 * This routine gets only called when some pieces of information
-	 * are missing, and without DHCP/BOOTP/RARP we are unable to get it.
-	 */
-	if (!ic_proto_enabled) {
-		printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
-		return -1;
-	}
-
-#ifdef IPCONFIG_BOOTP
-	if ((ic_proto_enabled ^ ic_proto_have_if) & IC_BOOTP)
-		printk(KERN_ERR "DHCP/BOOTP: No suitable device found.\n");
-#endif
-#ifdef IPCONFIG_RARP
-	if ((ic_proto_enabled ^ ic_proto_have_if) & IC_RARP)
-		printk(KERN_ERR "RARP: No suitable device found.\n");
-#endif
-
-	if (!ic_proto_have_if)
-		/* Error message already printed */
-		return -1;
-
-	/*
-	 * Setup protocols
-	 */
-#ifdef IPCONFIG_BOOTP
-	if (do_bootp)
-		ic_bootp_init();
-#endif
-#ifdef IPCONFIG_RARP
-	if (do_rarp)
-		ic_rarp_init();
-#endif
-
-	/*
-	 * Send requests and wait, until we get an answer. This loop
-	 * seems to be a terrible waste of CPU time, but actually there is
-	 * only one process running at all, so we don't need to use any
-	 * scheduler functions.
-	 * [Actually we could now, but the nothing else running note still 
-	 *  applies.. - AC]
-	 */
-	printk(KERN_NOTICE "Sending %s%s%s requests .",
-	       do_bootp
-		? ((ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP") : "",
-	       (do_bootp && do_rarp) ? " and " : "",
-	       do_rarp ? "RARP" : "");
-
-	start_jiffies = jiffies;
-	d = ic_first_dev;
-	retries = CONF_SEND_RETRIES;
-	get_random_bytes(&timeout, sizeof(timeout));
-	timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
-	for(;;) {
-#ifdef IPCONFIG_BOOTP
-		if (do_bootp && (d->able & IC_BOOTP))
-			ic_bootp_send_if(d, jiffies - start_jiffies);
-#endif
-#ifdef IPCONFIG_RARP
-		if (do_rarp && (d->able & IC_RARP))
-			ic_rarp_send_if(d);
-#endif
-
-		jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout);
-		while (time_before(jiffies, jiff) && !ic_got_reply)
-			schedule_timeout_uninterruptible(1);
-#ifdef IPCONFIG_DHCP
-		/* DHCP isn't done until we get a DHCPACK. */
-		if ((ic_got_reply & IC_BOOTP)
-		    && (ic_proto_enabled & IC_USE_DHCP)
-		    && ic_dhcp_msgtype != DHCPACK)
-		{
-			ic_got_reply = 0;
-			printk(",");
-			continue;
-		}
-#endif /* IPCONFIG_DHCP */
-
-		if (ic_got_reply) {
-			printk(" OK\n");
-			break;
-		}
-
-		if ((d = d->next))
-			continue;
-
-		if (! --retries) {
-			printk(" timed out!\n");
-			break;
-		}
-
-		d = ic_first_dev;
-
-		timeout = timeout CONF_TIMEOUT_MULT;
-		if (timeout > CONF_TIMEOUT_MAX)
-			timeout = CONF_TIMEOUT_MAX;
-
-		printk(".");
-	}
-
-#ifdef IPCONFIG_BOOTP
-	if (do_bootp)
-		ic_bootp_cleanup();
-#endif
-#ifdef IPCONFIG_RARP
-	if (do_rarp)
-		ic_rarp_cleanup();
-#endif
-
-	if (!ic_got_reply) {
-		ic_myaddr = INADDR_NONE;
-		return -1;
-	}
-
-	printk("IP-Config: Got %s answer from %u.%u.%u.%u, ",
-		((ic_got_reply & IC_RARP) ? "RARP" 
-		 : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
-		NIPQUAD(ic_servaddr));
-	printk("my address is %u.%u.%u.%u\n", NIPQUAD(ic_myaddr));
-
-	return 0;
-}
-
-#endif /* IPCONFIG_DYNAMIC */
-
-#ifdef CONFIG_PROC_FS
-
-static int pnp_seq_show(struct seq_file *seq, void *v)
-{
-	int i;
-
-	if (ic_proto_used & IC_PROTO)
-		seq_printf(seq, "#PROTO: %s\n",
-			   (ic_proto_used & IC_RARP) ? "RARP"
-			   : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP");
-	else
-		seq_puts(seq, "#MANUAL\n");
-
-	if (ic_domain[0])
-		seq_printf(seq,
-			   "domain %s\n", ic_domain);
-	for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
-		if (ic_nameservers[i] != INADDR_NONE)
-			seq_printf(seq,
-				   "nameserver %u.%u.%u.%u\n",
-				   NIPQUAD(ic_nameservers[i]));
-	}
-	if (ic_servaddr != INADDR_NONE)
-		seq_printf(seq,
-			   "bootserver %u.%u.%u.%u\n",
-			   NIPQUAD(ic_servaddr));
-	return 0;
-}
-
-static int pnp_seq_open(struct inode *indoe, struct file *file)
-{
-	return single_open(file, pnp_seq_show, NULL);
-}
-
-static struct file_operations pnp_seq_fops = {
-	.owner		= THIS_MODULE,
-	.open		= pnp_seq_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-#endif /* CONFIG_PROC_FS */
-
-/*
- *  Extract IP address from the parameter string if needed. Note that we
- *  need to have root_server_addr set _before_ IPConfig gets called as it
- *  can override it.
- */
-u32 __init root_nfs_parse_addr(char *name)
-{
-	u32 addr;
-	int octets = 0;
-	char *cp, *cq;
-
-	cp = cq = name;
-	while (octets < 4) {
-		while (*cp >= '0' && *cp <= '9')
-			cp++;
-		if (cp == cq || cp - cq > 3)
-			break;
-		if (*cp == '.' || octets == 3)
-			octets++;
-		if (octets < 4)
-			cp++;
-		cq = cp;
-	}
-	if (octets == 4 && (*cp == ':' || *cp == '\0')) {
-		if (*cp == ':')
-			*cp++ = '\0';
-		addr = in_aton(name);
-		memmove(name, cp, strlen(cp) + 1);
-	} else
-		addr = INADDR_NONE;
-
-	return addr;
-}
-
-/*
- *	IP Autoconfig dispatcher.
- */
-
-static int __init ip_auto_config(void)
-{
-	u32 addr;
-
-#ifdef CONFIG_PROC_FS
-	proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
-#endif /* CONFIG_PROC_FS */
-
-	if (!ic_enable)
-		return 0;
-
-	DBG(("IP-Config: Entered.\n"));
-#ifdef IPCONFIG_DYNAMIC
- try_try_again:
-#endif
-	/* Give hardware a chance to settle */
-	msleep(CONF_PRE_OPEN);
-
-	/* Setup all network devices */
-	if (ic_open_devs() < 0)
-		return -1;
-
-	/* Give drivers a chance to settle */
-	ssleep(CONF_POST_OPEN);
-
-	/*
-	 * If the config information is insufficient (e.g., our IP address or
-	 * IP address of the boot server is missing or we have multiple network
-	 * interfaces and no default was set), use BOOTP or RARP to get the
-	 * missing values.
-	 */
-	if (ic_myaddr == INADDR_NONE ||
-#ifdef CONFIG_ROOT_NFS
-	    (MAJOR(ROOT_DEV) == UNNAMED_MAJOR
-	     && root_server_addr == INADDR_NONE
-	     && ic_servaddr == INADDR_NONE) ||
-#endif
-	    ic_first_dev->next) {
-#ifdef IPCONFIG_DYNAMIC
-	
-		int retries = CONF_OPEN_RETRIES;
-
-		if (ic_dynamic() < 0) {
-			ic_close_devs();
-
-			/*
-			 * I don't know why, but sometimes the
-			 * eepro100 driver (at least) gets upset and
-			 * doesn't work the first time it's opened.
-			 * But then if you close it and reopen it, it
-			 * works just fine.  So we need to try that at
-			 * least once before giving up.
-			 *
-			 * Also, if the root will be NFS-mounted, we
-			 * have nowhere to go if DHCP fails.  So we
-			 * just have to keep trying forever.
-			 *
-			 * 				-- Chip
-			 */
-#ifdef CONFIG_ROOT_NFS
-			if (ROOT_DEV ==  Root_NFS) {
-				printk(KERN_ERR 
-					"IP-Config: Retrying forever (NFS root)...\n");
-				goto try_try_again;
-			}
-#endif
-
-			if (--retries) {
-				printk(KERN_ERR 
-				       "IP-Config: Reopening network devices...\n");
-				goto try_try_again;
-			}
-
-			/* Oh, well.  At least we tried. */
-			printk(KERN_ERR "IP-Config: Auto-configuration of network failed.\n");
-			return -1;
-		}
-#else /* !DYNAMIC */
-		printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
-		ic_close_devs();
-		return -1;
-#endif /* IPCONFIG_DYNAMIC */
-	} else {
-		/* Device selected manually or only one device -> use it */
-		ic_dev = ic_first_dev->dev;
-	}
-
-	addr = root_nfs_parse_addr(root_server_path);
-	if (root_server_addr == INADDR_NONE)
-		root_server_addr = addr;
-
-	/*
-	 * Use defaults whereever applicable.
-	 */
-	if (ic_defaults() < 0)
-		return -1;
-
-	/*
-	 * Close all network devices except the device we've
-	 * autoconfigured and set up routes.
-	 */
-	ic_close_devs();
-	if (ic_setup_if() < 0 || ic_setup_routes() < 0)
-		return -1;
-
-	/*
-	 * Record which protocol was actually used.
-	 */
-#ifdef IPCONFIG_DYNAMIC
-	ic_proto_used = ic_got_reply | (ic_proto_enabled & IC_USE_DHCP);
-#endif
-
-#ifndef IPCONFIG_SILENT
-	/*
-	 * Clue in the operator.
-	 */
-	printk("IP-Config: Complete:");
-	printk("\n      device=%s", ic_dev->name);
-	printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr));
-	printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask));
-	printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway));
-	printk(",\n     host=%s, domain=%s, nis-domain=%s",
-	       system_utsname.nodename, ic_domain, system_utsname.domainname);
-	printk(",\n     bootserver=%u.%u.%u.%u", NIPQUAD(ic_servaddr));
-	printk(", rootserver=%u.%u.%u.%u", NIPQUAD(root_server_addr));
-	printk(", rootpath=%s", root_server_path);
-	printk("\n");
-#endif /* !SILENT */
-
-	return 0;
-}
-
-late_initcall(ip_auto_config);
-
-
-/*
- *  Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
- *  command line parameter. It consists of option fields separated by colons in
- *  the following order:
- *
- *  <client-ip>:<server-ip>:<gw-ip>:<netmask>:<host name>:<device>:<PROTO>
- *
- *  Any of the fields can be empty which means to use a default value:
- *	<client-ip>	- address given by BOOTP or RARP
- *	<server-ip>	- address of host returning BOOTP or RARP packet
- *	<gw-ip>		- none, or the address returned by BOOTP
- *	<netmask>	- automatically determined from <client-ip>, or the
- *			  one returned by BOOTP
- *	<host name>	- <client-ip> in ASCII notation, or the name returned
- *			  by BOOTP
- *	<device>	- use all available devices
- *	<PROTO>:
- *	   off|none	    - don't do autoconfig at all (DEFAULT)
- *	   on|any           - use any configured protocol
- *	   dhcp|bootp|rarp  - use only the specified protocol
- *	   both             - use both BOOTP and RARP (not DHCP)
- */
-static int __init ic_proto_name(char *name)
-{
-	if (!strcmp(name, "on") || !strcmp(name, "any")) {
-		return 1;
-	}
-#ifdef CONFIG_IP_PNP_DHCP
-	else if (!strcmp(name, "dhcp")) {
-		ic_proto_enabled &= ~IC_RARP;
-		return 1;
-	}
-#endif
-#ifdef CONFIG_IP_PNP_BOOTP
-	else if (!strcmp(name, "bootp")) {
-		ic_proto_enabled &= ~(IC_RARP | IC_USE_DHCP);
-		return 1;
-	}
-#endif
-#ifdef CONFIG_IP_PNP_RARP
-	else if (!strcmp(name, "rarp")) {
-		ic_proto_enabled &= ~(IC_BOOTP | IC_USE_DHCP);
-		return 1;
-	}
-#endif
-#ifdef IPCONFIG_DYNAMIC
-	else if (!strcmp(name, "both")) {
-		ic_proto_enabled &= ~IC_USE_DHCP; /* backward compat :-( */
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-static int __init ip_auto_config_setup(char *addrs)
-{
-	char *cp, *ip, *dp;
-	int num = 0;
-
-	ic_set_manually = 1;
-
-	ic_enable = (*addrs && 
-		(strcmp(addrs, "off") != 0) && 
-		(strcmp(addrs, "none") != 0));
-	if (!ic_enable)
-		return 1;
-
-	if (ic_proto_name(addrs))
-		return 1;
-
-	/* Parse the whole string */
-	ip = addrs;
-	while (ip && *ip) {
-		if ((cp = strchr(ip, ':')))
-			*cp++ = '\0';
-		if (strlen(ip) > 0) {
-			DBG(("IP-Config: Parameter #%d: `%s'\n", num, ip));
-			switch (num) {
-			case 0:
-				if ((ic_myaddr = in_aton(ip)) == INADDR_ANY)
-					ic_myaddr = INADDR_NONE;
-				break;
-			case 1:
-				if ((ic_servaddr = in_aton(ip)) == INADDR_ANY)
-					ic_servaddr = INADDR_NONE;
-				break;
-			case 2:
-				if ((ic_gateway = in_aton(ip)) == INADDR_ANY)
-					ic_gateway = INADDR_NONE;
-				break;
-			case 3:
-				if ((ic_netmask = in_aton(ip)) == INADDR_ANY)
-					ic_netmask = INADDR_NONE;
-				break;
-			case 4:
-				if ((dp = strchr(ip, '.'))) {
-					*dp++ = '\0';
-					strlcpy(system_utsname.domainname, dp,
-						sizeof(system_utsname.domainname));
-				}
-				strlcpy(system_utsname.nodename, ip,
-					sizeof(system_utsname.nodename));
-				ic_host_name_set = 1;
-				break;
-			case 5:
-				strlcpy(user_dev_name, ip, sizeof(user_dev_name));
-				break;
-			case 6:
-				ic_proto_name(ip);
-				break;
-			}
-		}
-		ip = cp;
-		num++;
-	}
-
-	return 1;
-}
-
-static int __init nfsaddrs_config_setup(char *addrs)
-{
-	return ip_auto_config_setup(addrs);
-}
-
-__setup("ip=", ip_auto_config_setup);
-__setup("nfsaddrs=", nfsaddrs_config_setup);